4ba60d1d4b51bb64d039cb4956eb83bebb8c6b86
[iramuteq] / corpus.py
1 # -*- coding: utf-8 -*-
2 #Author: Pierre Ratinaud
3
4 import codecs
5 import os
6 import gettext
7 _ = gettext.gettext
8 import locale
9 import sys
10 from time import time
11 from functions import decoupercharact, ReadDicoAsDico, DoConf, ReadLexique
12 import re
13 import sqlite3
14 import itertools
15 import logging
16 from operator import itemgetter
17 from uuid import uuid4
18 from chemins import PathOut
19 from dialog import CorpusPref, SubTextFromMetaDial
20 from copy import copy
21 from colors import colors
22 import datetime
23
24
25 log = logging.getLogger('iramuteq.corpus')
26
27
28 def copycorpus(corpus) :
29     log.info('copy corpus')
30     copy_corpus = Corpus(corpus.parent, parametres = corpus.parametres)
31     copy_corpus.ucis = corpus.ucis
32     copy_corpus.formes = corpus.formes
33     copy_corpus.pathout = corpus.pathout
34     copy_corpus.conn_all()
35     return copy_corpus
36
37 def CopyUce(uce) :
38     return Uce(uce.ident, uce.para, uce.uci)
39     
40
41 def CopyUci(uci):
42     nuci = Uci(uci.ident, '')
43     nuci.etoiles = copy(uci.etoiles)
44     nuci.uces = [CopyUce(uce) for uce in uci.uces]
45     return nuci
46     
47
48
49 class Corpus :
50     """Corpus class
51     list of text
52     """
53     def __init__(self, parent, parametres = {}, read = False) :
54         self.parent = parent
55         self.parametres = parametres
56         self.cformes = None         
57         self.connformes = None
58         self.connuces = None
59         self.conncorpus = None
60         self.islem = False
61         self.cuces = None
62         self.ucis = []
63         self.formes = {}
64         self.flems = {}
65         self.lems = None
66         self.idformesuces = {}
67         self.iduces = None
68         self.idformes = None
69         self.uceuci = None
70         if read :
71             self.pathout = PathOut(dirout = parametres['pathout'])
72             self.read_corpus()
73
74     def add_word(self, word) :
75         if word in self.formes :
76             self.formes[word].freq += 1
77             if self.formes[word].ident in self.idformesuces :
78                 if self.ucis[-1].uces[-1].ident in self.idformesuces[self.formes[word].ident] :
79                     self.idformesuces[self.formes[word].ident][self.ucis[-1].uces[-1].ident] += 1
80                 else :
81                     self.idformesuces[self.formes[word].ident][self.ucis[-1].uces[-1].ident] = 1
82             else :
83                 self.idformesuces[self.formes[word].ident] = {self.ucis[-1].uces[-1].ident: 1}
84         else :
85             if word in self.parent.lexique :
86                 gramtype = self.parent.lexique[word][1]
87                 lem = self.parent.lexique[word][0]
88             elif word.isdigit() :
89                 gramtype = u'num'
90                 lem = word
91             else :
92                 gramtype = u'nr'
93                 lem = word
94             self.formes[word] =  Word(word, gramtype, len(self.formes), lem)
95             self.idformesuces[self.formes[word].ident] = {self.ucis[-1].uces[-1].ident : 1}
96     
97     def add_word_from_forme(self, word, stident):
98         if word.forme in self.formes :
99             self.formes[word.forme].freq += 1
100             if self.formes[word.forme].ident in self.idformesuces :
101                 if stident in self.idformesuces[self.formes[word.forme].ident] :
102                     self.idformesuces[self.formes[word.forme].ident][stident] += 1
103                 else :
104                     self.idformesuces[self.formes[word.forme].ident][stident] = 1
105             else :
106                 self.idformesuces[self.formes[word.forme].ident] = {stident: 1}
107         else :
108             self.formes[word.forme] = Word(word.forme, word.gram, len(self.formes), word.lem)
109             self.idformesuces[self.formes[word.forme].ident] = {stident : 1}       
110
111     def conn_all(self): 
112         """connect corpus to db"""
113         if self.connformes is None :
114             log.info('connexion corpus')
115             self.connuces = sqlite3.connect(self.pathout['uces.db'])
116             self.cuces = self.connuces.cursor()
117             self.connformes = sqlite3.connect(self.pathout['formes.db'])
118             self.cformes = self.connformes.cursor()
119             self.conncorpus = sqlite3.connect(self.pathout['corpus.db'])
120             self.ccorpus = self.conncorpus.cursor()
121             self.cformes.execute('PRAGMA temp_store=MEMORY;')
122             self.cformes.execute('PRAGMA journal_mode=MEMORY;')
123             self.cformes.execute('PRAGMA  synchronous = OFF;')
124             self.cuces.execute('PRAGMA temp_store=MEMORY;')
125             self.cuces.execute('PRAGMA journal_mode=MEMORY;')
126             self.cuces.execute('PRAGMA  synchronous = OFF;')
127             self.ccorpus.execute('PRAGMA temp_store=MEMORY;')
128             self.ccorpus.execute('PRAGMA journal_mode=MEMORY;')
129             self.ccorpus.execute('PRAGMA  synchronous = OFF;')
130
131     def read_corpus(self) :
132         log.info('read corpus')
133         self.parametres['syscoding'] = sys.getdefaultencoding()
134         if self.conncorpus is None :
135             self.conn_all()
136         res = self.ccorpus.execute('SELECT * FROM etoiles;')
137         for row in res :
138             self.ucis.append(Uci(row[0], row[1], row[2]))
139             uces = self.conncorpus.cursor().execute('SELECT * FROM luces where uci=?;',(`self.ucis[-1].ident`,))
140             for uce in uces:
141                 self.ucis[-1].uces.append(Uce(uce[2], uce[1], uce[0]))
142         res = self.ccorpus.execute('SELECT * FROM formes;')
143         self.formes = dict([[forme[1], Word(forme[1], forme[3], forme[0], lem = forme[2], freq = forme[4])] for forme in res])
144         self.ccorpus.close()
145     
146     def getworduces(self, wordid) :
147         if isinstance(wordid, basestring) :
148             wordid = self.formes[wordid].ident
149         res = self.cformes.execute('SELECT uces FROM uces where id=? ORDER BY id;', (`wordid`,))
150         return list(itertools.chain(*[[int(val) for val in row[0].split()] if not isinstance(row[0], int) else [row[0]] for row in res]))
151     
152     def getworducis(self, wordid) :
153         res = self.getworduces(wordid)
154         return list(set([self.getucefromid(uce).uci for uce in res]))
155
156     def getformeuceseff(self, formeid) :
157         if isinstance(formeid, basestring) :
158             formeid = self.formes[formeid].ident
159         res = self.cformes.execute('SELECT uces FROM uces where id=? ORDER BY id;', (`formeid`,))
160         uces = list(itertools.chain(*[[int(val) for val in row[0].split()] if not isinstance(row[0], int) else [row[0]] for row in res]))
161         query = 'SELECT eff FROM eff where id=%i ORDER BY id' % formeid
162         res = self.cformes.execute(query)
163         eff = list(itertools.chain(*[[int(val) for val in row[0].split()] if not isinstance(row[0], int) else [row[0]] for row in res]))
164         formeuceeff = {}
165         for i, uce in enumerate(uces) :
166             formeuceeff[uce] = formeuceeff.get(uce, 0) + eff[i]
167         return formeuceeff    
168
169     def getlemuces(self, lem) :
170         formesid = ', '.join([`val` for val in self.lems[lem].formes])
171         query = 'SELECT uces FROM uces where id IN (%s) ORDER BY id' % formesid
172         res = self.cformes.execute(query)
173         return list(set(list(itertools.chain(*[[int(val) for val in row[0].split()] if not isinstance(row[0], int) else [row[0]] for row in res]))))
174
175     def gettgenst(self, tgen):
176         formesid = ', '.join([`val` for lem in tgen for val in self.lems[lem].formes if lem in self.lems])
177         query = 'SELECT uces FROM uces where id IN (%s) ORDER BY id' % formesid
178         res = self.cformes.execute(query)
179         return list(set(list(itertools.chain(*[[int(val) for val in row[0].split()] if not isinstance(row[0], int) else [row[0]] for row in res]))))
180
181     def getlemucis(self, lem) :
182         uces = self.getlemuces(lem)
183         return list(set([self.getucefromid(val).uci for val in uces]))
184
185     def getlemuceseff(self, lem, luces = None) :
186         formesid = ', '.join([`val` for val in self.lems[lem].formes])
187         query = 'SELECT uces FROM uces where id IN (%s) ORDER BY id' % formesid
188         res = self.cformes.execute(query)
189         uces = list(itertools.chain(*[[int(val) for val in row[0].split()] if not isinstance(row[0], int) else [row[0]] for row in res]))
190         query = 'SELECT eff FROM eff where id IN (%s) ORDER BY id' % formesid
191         res = self.cformes.execute(query)
192         eff = list(itertools.chain(*[[int(val) for val in row[0].split()] if not isinstance(row[0], int) else [row[0]] for row in res]))
193         lemuceeff = {}
194         for i, uce in enumerate(uces) :
195             lemuceeff[uce] = lemuceeff.get(uce, 0) + eff[i]
196         return lemuceeff
197
198     def getlemclustereff(self, lem, cluster) :
199         return len(list(set(self.lc[cluster]).intersection(self.getlemuces(lem))))
200
201     def getlemeff(self, lem) :
202         return self.lems[lem].freq
203
204     def getlems(self) :
205         return self.lems
206
207     def getforme(self, formeid) :
208         if self.idformes is None : self.make_idformes()
209         return self.idformes[formeid]
210
211     def gettotocc(self) :
212         return sum([self.formes[forme].freq for forme in self.formes])
213
214     def getucemean(self) :
215         return float(self.gettotocc())/self.getucenb()
216
217     def getucenb(self) :
218         return self.ucis[-1].uces[-1].ident + 1
219
220     def getucinb(self) :
221         return self.ucis[-1].ident + 1
222
223     def getucisize(self) :
224         ucesize = self.getucesize()
225         return [sum(ucesize[uci.uces[0].ident:(uci.uces[-1].ident + 1)]) for uci in self.ucis]
226     
227     def getucesize(self) :
228         res = self.getalluces()
229         return [len(uce[1].split()) for uce in res]
230
231     def getconcorde(self, uces) :
232         return self.cuces.execute('select * from uces where id IN (%s) ORDER BY id;' % ', '.join([`i` for i in uces])) 
233     
234     def getuciconcorde(self, ucis) :
235         uces = [[val,[uce.ident for uce in self.ucis[val].uces]] for val in ucis]
236         uces = [[val[0], '\n'.join([row[1] for row in self.getconcorde(val[1])])] for val in uces]
237         return uces
238
239     def getwordconcorde(self, word) :
240         return self.getconcorde(self.getworduces(word))
241
242     def getlemconcorde(self, lem) :
243         return self.getconcorde(self.getlemuces(lem))
244
245     def getalluces(self) :
246         return self.cuces.execute('SELECT * FROM uces')
247     
248     def getallucis(self):
249         uces = [row[1] for row in self.getalluces()]
250         return [[uci.ident, '\n'.join([uces[uce.ident] for uce in uci.uces])] for uci in self.ucis]
251         
252     def getucesfrometoile(self, etoile) :
253         return [uce.ident for uci in self.ucis for uce in uci.uces if etoile in uci.etoiles]
254
255     def getetoileuces(self) :
256         log.info('get uces etoiles')
257         etoileuces = {}
258         idpara = 0
259         for uci in self.ucis :
260             etoiles = uci.etoiles[1:]
261             for et in etoiles :
262                 if et in etoileuces :
263                     etoileuces[et] += [uce.ident for uce in uci.uces]
264                 else :
265                     etoileuces[et] = [uce.ident for uce in uci.uces]
266             if uci.paras != [] :
267                 for et in uci.paras :
268                     if et in etoileuces :
269                         etoileuces[et] += [uce.ident for uce in uci.uces if uce.para == idpara]
270                     else :
271                         etoileuces[et] = [uce.ident for uce in uci.uces if uce.para == idpara]
272                     idpara += 1
273             else :
274                 idpara += 1
275         return etoileuces
276     
277     def getetoileucis(self):
278         etoileuces = {}
279         for uci in self.ucis :
280             etoiles = uci.etoiles[1:]
281             for et in etoiles :
282                 if et in etoileuces :
283                     etoileuces[et] += [uci.ident]
284                 else :
285                     etoileuces[et] = [uci.ident]
286         return etoileuces
287
288     def getucefromid(self, uceid) :
289         if self.iduces is None : self.make_iduces()
290         return self.iduces[uceid]
291
292     def gethapaxnb(self) :
293         return len([None for forme in self.formes if self.formes[forme].freq == 1])
294
295     def getactivesnb(self, key) :
296         return len([lem for lem in self.lems if self.lems[lem].act == key])
297 #    def make_lems(self, lem = True) :
298 #        log.info('make lems')
299 #        self.lems = {}
300 #        for forme in self.formes :
301 #            if self.formes[forme].lem in self.lems :
302 #                if self.formes[forme].ident not in self.lems[self.formes[forme].lem] :
303 #                    self.lems[self.formes[forme].lem][self.formes[forme].ident] = 0
304 #            else :
305 #                    self.lems[self.formes[forme].lem] = {self.formes[forme].ident : 0}
306
307     def getetbyuceid(self, uceid) :
308         if self.uceuci is None : self.uceuci = dict([[uce.ident,uci.ident] for uci in self.ucis for uce in uci.uces])
309         return self.ucis[self.uceuci[uceid]].etoiles
310
311     def make_lems(self, lem = True) :
312         log.info('make lems')
313         self.lems = {}
314         if lem :
315             for forme in self.formes :
316                 if self.formes[forme].lem in self.lems :
317                     if self.formes[forme].ident not in self.lems[self.formes[forme].lem].formes :
318                         self.lems[self.formes[forme].lem].add_forme(self.formes[forme])
319                 else :
320                     self.lems[self.formes[forme].lem] = Lem(self, self.formes[forme])
321         else :
322             self.lems = dict([[forme, Lem(self, self.formes[forme])] for forme in self.formes])
323     
324     def make_lems_from_dict(self, dictionnaire, dolem = True) :
325         log.info('make lems from dict')
326         self.lems = {}
327         for forme in self.formes :
328             if self.formes[forme].forme in dictionnaire :
329                 lem = dictionnaire[forme][0]
330                 gram = dictionnaire[forme][1]
331             elif forme.isdigit() :
332                 gram = u'num'
333                 lem = forme
334             else :
335                 gram = u'nr'
336                 lem = forme
337             self.formes[forme].lem = lem
338             self.formes[forme].gram = gram
339             if dolem :
340                 if self.formes[forme].lem in self.lems :
341                     if self.formes[forme].ident not in self.lems[self.formes[forme].lem].formes :
342                         self.lems[self.formes[forme].lem].add_forme(self.formes[forme])
343                 else :
344                     self.lems[self.formes[forme].lem] = Lem(self, self.formes[forme])
345             else :
346                 self.lems[forme] = Lem(self, self.formes[forme])
347                 
348     def make_idformes(self) :
349         self.idformes = dict([[self.formes[forme].ident, self.formes[forme]] for forme in self.formes])
350
351     def make_iduces(self) :
352         if self.iduces is None :
353             self.iduces = dict([[uce.ident, uce] for uci in self.ucis for uce in uci.uces])
354
355     def make_lexitable(self, mineff, etoiles, gram = 0) :
356         if gram == 0 :
357             grams = {1:'', 2:''}
358         else :
359             grams = {gram :''}
360         tokeep = [lem for lem in self.lems if self.lems[lem].freq >= mineff and self.lems[lem].act in grams]
361         etuces = [[] for et in etoiles]
362         for uci in self.ucis :
363             get = list(set(uci.etoiles).intersection(etoiles))
364             if len(get) > 1 :
365                 log.info('2 variables sur une ligne')
366             if get != [] :
367                 etuces[etoiles.index(get[0])] += [uce.ident for uce in uci.uces]
368         etuces = [set(val) for val in etuces]
369         tab = []
370         for lem in tokeep :
371             deff = self.getlemuceseff(lem)
372             ucesk = deff.keys()
373             tab.append([lem] + [sum([deff[uce] for uce in et.intersection(ucesk)]) for et in etuces])
374         tab.insert(0, [''] + etoiles)
375         return tab
376     
377     def make_tgen_table(self, tgen, etoiles, tot = None):
378         lclasses = [self.getucesfrometoile(etoile) for etoile in etoiles]
379         sets = [set(cl) for cl in lclasses]
380         totoccurrences = dict([[val, 0] for val in etoiles])
381         if tot is None :
382             for forme in self.formes :
383                 formeuceeff = self.getformeuceseff(forme)
384                 for i, classe in enumerate(lclasses) :
385                     concern = sets[i].intersection(formeuceeff.keys())
386                     if len(concern) :
387                         totoccurrences[etoiles[i]] += sum([formeuceeff[uce] for uce in concern])
388         #tgenoccurrences = dict([[val, 0] for val in etoiles])
389         tgenoccurrences = {}
390         for t in tgen.tgen :
391             tgenoccurrences[t] = dict([[val, 0] for val in etoiles])
392             for lem in tgen[t] :
393                 lemuceeff = self.getlemuceseff(lem)
394                 for i, classe in enumerate(lclasses) :
395                     concern = sets[i].intersection(lemuceeff.keys())
396                     if len(concern) :
397                         tgenoccurrences[t][etoiles[i]] += sum([lemuceeff[uce] for uce in concern])
398         return tgenoccurrences, totoccurrences
399     
400     def make_efftype_from_etoiles(self, etoiles) :
401         dtype = {}
402         etuces = [[] for et in etoiles]
403         for uci in self.ucis :
404             get = list(set(uci.etoiles).intersection(etoiles))
405             if len(get) > 1 :
406                 return '2 variables sur la meme ligne'
407             elif get != [] :
408                 etuces[etoiles.index(get[0])] += [uce.ident for uce in uci.uces]
409         etuces = [set(val) for val in etuces]
410         for lem in self.lems :
411             deff = self.getlemuceseff(lem)
412             ucesk = deff.keys()
413             gram = self.lems[lem].gram
414             if gram in dtype :
415                 dtype[gram] = [i + j for i, j in zip(dtype[gram], [sum([deff[uce] for uce in et.intersection(ucesk)]) for et in etuces])]
416             else :
417                 dtype[gram] = [sum([deff[uce] for uce in et.intersection(ucesk)]) for et in etuces]
418         tabout = [[gram] + dtype[gram] for gram in dtype]
419         tabout.insert(0, [''] + etoiles)
420         return tabout
421
422     def make_uceactsize(self, actives) :
423         res = self.getalluces()
424         ucesize = {}
425         for lem in actives: 
426             deff = self.getlemuceseff(lem)
427             for uce in deff :
428                 ucesize[uce] = ucesize.get(uce, 0) + 1
429         return ucesize
430
431     def make_uc(self, actives, lim1, lim2) :
432         uceactsize = self.make_uceactsize(actives)
433         last1 = 0
434         last2 = 0
435         uc1 = [[]]
436         uc2 = [[]]
437         lastpara = 0
438         for uce in [uce for uci in self.ucis for uce in uci.uces] :
439             if uce.para == lastpara :
440                 if last1 <= lim1 :
441                     last1 += uceactsize.get(uce.ident,0)
442                     uc1[-1].append(uce.ident)
443                 else :
444                     uc1.append([uce.ident])
445                     last1 = 0
446                 if last2 <= lim2 :
447                     last2 += uceactsize.get(uce.ident, 0)
448                     uc2[-1].append(uce.ident)
449                 else :
450                     uc2.append([uce.ident])
451                     last2 = 0
452             else :
453                 last1 = uceactsize.get(uce.ident, 0)
454                 last2 = uceactsize.get(uce.ident, 0)
455                 lastpara = uce.para
456                 uc1.append([uce.ident])
457                 uc2.append([uce.ident])
458         return uc1, uc2
459
460     def make_and_write_sparse_matrix_from_uc(self, actives, sizeuc1, sizeuc2, uc1out, uc2out, listuce1out, listuce2out) :
461         uc1, uc2 = self.make_uc(actives, sizeuc1, sizeuc2)
462         log.info('taille uc1 : %i - taille uc2 : %i' % (len(uc1), len(uc2)))
463         self.write_ucmatrix(uc1, actives, uc1out)
464         self.write_ucmatrix(uc2, actives, uc2out)
465         listuce1 = [['uce', 'uc']] + [[`uce`, `i`] for i, ucl in enumerate(uc1) for uce in ucl]
466         listuce2 = [['uce', 'uc']] + [[`uce`, `i`] for i, ucl in enumerate(uc2) for uce in ucl]
467         with open(listuce1out, 'w') as f :
468             f.write('\n'.join([';'.join(line) for line in listuce1]))
469         with open(listuce2out, 'w') as f :
470             f.write('\n'.join([';'.join(line) for line in listuce2]))
471         return len(uc1), len(uc2)
472
473     def write_ucmatrix(self, uc, actives, fileout) :
474         log.info('write uc matrix %s' % fileout)
475         uces_uc = dict([[uce, i] for i, ucl in enumerate(uc) for uce in ucl])
476         deja_la = {}
477         nbl = 0
478         with open(fileout + '~', 'w+') as f :
479             for i, lem in enumerate(actives) :
480                 for uce in self.getlemuces(lem):
481                     if (uces_uc[uce], i) not in deja_la :
482                         nbl += 1
483                         f.write(''.join([' '.join([`uces_uc[uce]+1`,`i+1`,`1`]),'\n']))
484                         deja_la[(uces_uc[uce], i)] = 0
485             f.seek(0)
486             with open(fileout, 'w') as ffin :        
487                 ffin.write("%%%%MatrixMarket matrix coordinate integer general\n%i %i %i\n" % (len(uc), len(actives), nbl))
488                 for line in f :
489                     ffin.write(line)
490         os.remove(fileout + '~')
491         del(deja_la)
492
493     def export_corpus(self, outf) :
494         #outf = 'export_corpus.txt'
495         self.make_iduces()
496         res = self.getalluces()
497         self.make_iduces()
498         actuci = ''
499         actpara = False
500         with open(outf,'w') as f :
501             for uce in res :
502                 if self.iduces[uce[0]].uci == actuci and self.iduces[uce[0]].para == actpara :
503                     f.write(uce[1].encode(self.parametres['syscoding']) + '\n')
504                 elif self.iduces[uce[0]].uci != actuci :
505                     actuci = self.iduces[uce[0]].uci
506                     if self.ucis[self.iduces[uce[0]].uci].paras == [] :
507                         actpara = self.iduces[uce[0]].para
508                         f.write('\n' + ' '.join(self.ucis[self.iduces[uce[0]].uci].etoiles).encode(self.parametres['syscoding']) + '\n' + uce[1].encode(self.parametres['syscoding']) + '\n')
509                     else :
510                         ident = 0
511                         actpara = self.iduces[uce[0]].para
512                         f.write('\n'.join([' '.join(self.ucis[self.iduces[uce[0]].uci].etoiles).encode(self.parametres['syscoding']), self.ucis[self.iduces[uce[0]].uci].paras[ident].encode(self.parametres['syscoding']), uce[1].encode(self.parametres['syscoding'])]) + '\n')
513                 elif self.iduces[uce[0]].para != actpara :
514                     actpara = self.iduces[uce[0]].para
515                     ident += 1
516                     f.write('\n'.join([self.ucis[self.iduces[uce[0]].uci].paras[ident].encode(self.parametres['syscoding']), uce[1].encode(self.parametres['syscoding'])]) + '\n')
517     
518     def export_corpus_classes(self, outf, alc = True, lem = False, uci = False) :
519         ucecl = {}
520         for i, lc in enumerate(self.lc) :
521             for uce in lc : 
522                 ucecl[uce] = i + 1
523         for uce in self.lc0 :
524             ucecl[uce] = 0
525         if not uci :
526             res = self.getalluces()
527             self.make_iduces()
528         else :
529             res = self.getallucis()
530         with open(outf, 'w') as f :
531             for uce in res :
532                 guce = uce[1]
533                 if not uci :
534                     actuci = self.iduces[uce[0]].uci
535                 else :
536                     actuci = uce[0]
537                 if lem :
538                     guce = ' '.join([self.formes[forme].lem for forme in guce.split()])
539                 if alc :
540                     etline = ' '.join(self.ucis[actuci].etoiles + ['*classe_%i' % ucecl[uce[0]]])
541                 else :
542                     etline = ' '.join(['<' + '='.join(et.split('_')) + '>' for et in self.ucis[actuci].etoiles[1:]])
543                 f.write(etline.encode(self.parametres['syscoding']) + '\n')
544                 f.write(guce.encode(self.parametres['syscoding']) + '\n\n')
545
546     def export_classe(self, outf, classe, lem = False, uci = False) :
547         sts = self.lc[classe - 1] 
548         if not uci :
549             res = self.getconcorde(sts)
550             self.make_iduces()
551         else :
552             res = self.getuciconcorde(sts)
553         with open(outf, 'w') as f :
554             for uce in res :
555                 guce = uce[1]
556                 if not uci :
557                     f.write(' '.join(self.ucis[self.iduces[uce[0]].uci].etoiles).encode(self.parametres['syscoding']) + '\n')
558                 else :
559                     f.write(' '.join(self.ucis[uce[0]].etoiles).encode(self.parametres['syscoding']) + '\n')
560                 if lem :
561                     guce = ' '.join([self.formes[forme].lem for forme in guce.split()])
562                 f.write(guce.encode(self.parametres['syscoding']) + '\n\n')
563     
564     def export_owledge(self, rep, classe, lem = False, uci = False) :
565         sts = self.lc[classe - 1]
566         if not uci :
567             res = self.getconcorde(sts)
568             self.make_iduces()
569         else :
570             res = self.getuciconcorde(sts)
571         for uce in res :
572             ident = uce[0]
573             guce = uce[1]
574             outf = '.'.join([`ident`, 'txt'])
575             outf = os.path.join(rep, outf)
576             if lem :
577                 guce = ' '.join([self.formes[forme].lem for forme in guce.split()])
578             with open(outf, 'w') as f :
579                 f.write(guce.encode('cp1252', errors = 'replace'))
580
581     def export_tropes(self, fileout, classe, lem = False, uci = False) :
582         sts = self.lc[classe - 1]
583         if not uci :
584             res = self.getconcorde(sts)
585             self.make_iduces()
586         else :
587             res = self.getuciconcorde(sts)
588         with open(fileout, 'w') as f :
589             for uce in res :
590                 guce = uce[1]
591                 if lem :
592                     guce = ' '.join([self.formes[forme].lem for forme in guce.split()])
593                 f.write(guce.encode('cp1252', errors = 'replace'))
594                 f.write('\n')
595
596     def make_and_write_sparse_matrix_from_uces(self, actives, outfile, listuce = False) :
597         log.info('make_and_write_sparse_matrix_from_uces %s' % outfile)
598         nbl = 0
599         with open(outfile + '~', 'w+') as f :
600             for i, lem in enumerate(actives) :
601                 for uce in sorted(self.getlemuces(lem)) :
602                     nbl += 1
603                     f.write(''.join([' '.join([`uce+1`, `i+1`,`1`]),'\n']))
604             f.seek(0)
605             with open(outfile, 'w') as ffin :        
606                 ffin.write("%%%%MatrixMarket matrix coordinate integer general\n%i %i %i\n" % (self.getucenb(), len(actives), nbl))
607                 for line in f :
608                     ffin.write(line)
609         os.remove(outfile + '~')
610         if listuce :
611             with open(listuce, 'w') as f :
612                 f.write('\n'.join(['uce;uc'] + [';'.join([`i`,`i`]) for i in range(0, self.getucenb())]))
613
614     def make_and_write_sparse_matrix_from_uci(self, actives, outfile, listuci = False) :
615         log.info('make_and_write_sparse_matrix_from_ucis %s' % outfile)
616         nbl = 0
617         with open(outfile + '~', 'w+') as f :
618             for i, lem in enumerate(actives) :
619                 for uci in sorted(self.getlemucis(lem)) :
620                     nbl += 1
621                     f.write(''.join([' '.join([`uci+1`, `i+1`,`1`]),'\n']))
622             f.seek(0)
623             with open(outfile, 'w') as ffin :        
624                 ffin.write("%%%%MatrixMarket matrix coordinate integer general\n%i %i %i\n" % (self.getucinb(), len(actives), nbl))
625                 for line in f :
626                     ffin.write(line)
627         os.remove(outfile + '~')
628         if listuci :
629             with open(listuci, 'w') as f :
630                 f.write('\n'.join(['uci;uc'] + [';'.join([`i`,`i`]) for i in range(0, self.getucinb())]))
631                     
632     def make_and_write_sparse_matrix_from_classe(self, actives, uces, outfile) :
633         log.info('make_and_write_sparse_matrix_from_classe %s' % outfile)
634         nbl = 0
635         duces = dict([[uce, i] for i, uce in enumerate(uces)])
636         with open(outfile + '~', 'w+') as f :
637             for i, lem in enumerate(actives) :
638                 uces_ok = list(set(self.getlemuces(lem)).intersection(uces))
639                 for uce in uces_ok :
640                     f.write(''.join([' '.join([`duces[uce]+1`,`i+1`,`1`]),'\n']))
641             f.seek(0)
642             with open(outfile, 'w') as ffin :        
643                 ffin.write("%%%%MatrixMarket matrix coordinate integer general\n%i %i %i\n" % (self.getucenb(), len(actives), nbl))
644                 for line in f :
645                     ffin.write(line)
646         os.remove(outfile + '~')
647     
648     def make_table_with_classe(self, uces, list_act, uci = False) :
649         table_uce = [[0 for val in list_act] for line in range(0,len(uces))]
650         uces = dict([[uce, i] for i, uce in enumerate(uces)])
651         if uci :
652             getlem = self.getlemucis
653         else :
654             getlem = self.getlemuces
655         for i, lem in enumerate(list_act) :
656             lemuces = list(set(getlem(lem)).intersection(uces))
657             for uce in lemuces :
658                 table_uce[uces[uce]][i] = 1
659         table_uce.insert(0, list_act)
660         return table_uce      
661     
662     def make_pondtable_with_classe(self, uces, list_act) :
663         table_uce = [[0 for val in list_act] for line in range(0,len(uces))]
664         uces = dict([[uce, i] for i, uce in enumerate(uces)])
665         for i, lem in enumerate(list_act) :
666             uceseff = self.getlemuceseff(lem)
667             lemuces = list(set(uceseff.keys()).intersection(uces))
668             for uce in lemuces :
669                 table_uce[uces[uce]][i] = uceseff[uce]
670         table_uce.insert(0, list_act)
671         return table_uce 
672
673     def parse_active(self, gramact, gramsup = None) :
674         log.info('parse actives')
675         for lem in self.lems :
676             if lem.startswith('_') and lem.endswith('_') :
677                 self.lems[lem].act = 2
678             elif self.lems[lem].gram in gramact :
679                 self.lems[lem].act = 1
680             elif gramsup is not None and self.lems[lem].gram not in gramact:
681                 if self.lems[lem].gram in gramsup :
682                     self.lems[lem].act = 2
683                 else :
684                     self.lems[lem].act =  0
685             else :
686                 self.lems[lem].act = 2
687
688     def make_actives_limit(self, limit, key = 1) :
689         if self.idformes is None :
690             self.make_idformes()
691         return [lem for lem in self.lems if self.getlemeff(lem) >= limit and self.lems[lem].act == key]
692     
693     def make_actives_nb(self, nbmax, key) :
694         log.info('make_actives_nb : %i - %i' % (nbmax,key))
695         if self.idformes is None :
696             self.make_idformes()
697         allactives = [[self.lems[lem].freq, lem] for lem in self.lems if self.lems[lem].act == key and self.lems[lem].freq >= 3]
698         self.activenb = len(allactives)
699         allactives = sorted(allactives, reverse = True)
700         if self.activenb == 0 :
701             return [], 0
702         if len(allactives) <= nbmax :
703             log.info('nb = %i - eff min = %i ' % (len(allactives), allactives[-1][0]))
704             return [val[1] for val in allactives], allactives[-1][0]
705         else :
706             effs = [val[0] for val in allactives]
707             if effs.count(effs[nbmax - 1]) > 1 :
708                 lim = effs[nbmax - 1] + 1
709                 nok = True
710                 while nok :
711                     try :
712                         stop = effs.index(lim)
713                         nok = False
714                     except ValueError:
715                         lim -= 1
716             else :
717                 stop = nbmax - 1
718                 lim = effs[stop]
719         log.info('nb actives = %i - eff min = %i ' % (stop + 1, lim))
720         return [val[1] for val in allactives[0:stop + 1]], lim
721
722     def make_and_write_profile(self, actives, ucecl, fileout, uci = False) :
723         log.info('formes/classes')
724         if uci :
725             tab = [[lem] + [len(set(self.getlemucis(lem)).intersection(classe)) for classe in ucecl] for lem in actives]
726         else :
727             tab = [[lem] + [len(set(self.getlemuces(lem)).intersection(classe)) for classe in ucecl] for lem in actives]
728         tab = [[line[0]] + [`val` for val in line[1:]] for line in tab if sum(line[1:]) >= 3]
729         with open(fileout, 'w') as f :
730             f.write('\n'.join([';'.join(line) for line in tab]).encode(self.parametres['syscoding']))
731
732     def make_etoiles(self) :
733         etoiles = set([])
734         for uci in self.ucis :
735             etoiles.update(uci.etoiles[1:])
736         return list(etoiles)
737     
738     def make_themes(self):
739         themes = set([])
740         for uci in self.ucis :
741             themes.update(uci.paras)
742         return list(themes)
743
744     def make_etoiles_dict(self) :
745         etoiles = [et for uci in self.ucis for et in uci.etoiles[1:]]
746         det = {}
747         for etoile in etoiles :
748             et = etoile.split('_')
749             if et[0] in det :
750                 try :
751                     endet = '_'.join(et[1:])
752                     if etoile in det[et[0]] :
753                         det[et[0]][etoile] += 1
754                     else :
755                         det[et[0]][etoile] = 1
756                 except IndexError :
757                     det[et[0]] += 1
758             else :
759                 try :
760                     endet = '_'.join(et[1:])
761                     det[et[0]] = {etoile :1}
762                 except IndexError :
763                     det[et[0]] = 1
764         return det
765     
766     def make_theme_dict(self):
767         themes = [val for uci in self.ucis for val in uci.paras]
768         det = {}
769         for theme in themes :
770             th = theme.split('_')
771             if th[0] in det :
772                 try :
773                     endth = '_'.join(th[1:])
774                     if theme in det[th[0]] :
775                         det[th[0]][theme] += 1
776                     else :
777                         det[th[0]][theme] = 1
778                 except IndexError :
779                     det[th[0]] += 1
780             else :
781                 try :
782                     endth = '_'.join(th[1:])
783                     det[th[0]] = {theme:1}
784                 except IndexError :
785                     det[th[0]] = 1
786         return det
787
788     def make_etline(self, listet) :
789         etuces = [[] for et in listet]
790         for uci in self.ucis :
791             get = list(set(uci.etoiles).intersection(listet))
792             if len(get) > 1 :
793                 return '2 variables sur la meme ligne'
794             elif get != [] :
795                 etuces[listet.index(get[0])] += [uce.ident for uce in uci.uces]
796         return etuces
797
798     def make_and_write_profile_et(self, ucecl, fileout, uci = False) :
799         log.info('etoiles/classes')
800         if not uci :
801             etoileuces = self.getetoileuces()
802         else :
803             etoileuces = self.getetoileucis()
804         etoileuces = dict([[et, etoileuces[et]] for et in etoileuces if len(etoileuces[et]) > 1])
805         with open(fileout, 'w') as f :
806             f.write('\n'.join([';'.join([et] + [`len(set(etoileuces[et]).intersection(classe))` for classe in ucecl]) for et in etoileuces]).encode(self.parametres['syscoding']))
807         #etoiles = self.make_etoiles()
808         #with open(fileout, 'w') as f :
809         #    f.write('\n'.join([';'.join([etoile] + [`len(set(self.getucesfrometoile(etoile)).intersection(classe))` for classe in ucecl]) for etoile in etoiles]).encode(self.parametres['syscoding']))
810
811     def make_colored_corpus(self, uci = False) :
812         ucecl = {}
813         for i, lc in enumerate(self.lc) :
814             for uce in lc : 
815                 ucecl[uce] = i + 1
816         for uce in self.lc0 :
817             ucecl[uce] = 0
818         color = ['black'] + colors[len(self.lc) - 1]        
819         txt = '''<html>
820         <meta http-equiv="content-Type" content="text/html; charset=%s" />
821         <body>
822 ''' % sys.getdefaultencoding()
823         if not uci :
824             res = self.getalluces()
825             self.make_iduces()
826             actuci = ''
827             actpara = False
828             for uce in res :
829                 if self.iduces[uce[0]].uci != actuci :
830                     actuci = self.iduces[uce[0]].uci
831                     txt += '<br><hr>' + ' '.join(self.ucis[self.iduces[uce[0]].uci].etoiles) + '<br><br>'
832                     txt += '<font color="%s">' % (color[ucecl[uce[0]]]) + uce[1] + '</font><br><br>'
833                 else :
834                     txt += '<font color="%s">' % (color[ucecl[uce[0]]]) + uce[1] + '</font><br><br>'
835         else :
836             res = self.getallucis()
837             actuci = ''
838             for uce in res :
839                 if self.ucis[uce[0]].ident != actuci :
840                     actuci = self.ucis[uce[0]].ident
841                     txt += '<br><hr>' + ' '.join(self.ucis[self.ucis[uce[0]].ident].etoiles) + '<br><br>'
842                     txt += '<font color="%s">' % (color[ucecl[uce[0]]]) + uce[1] + '</font><br><br>'
843                 else :
844                     txt += '<font color="%s">' % (color[ucecl[uce[0]]]) + uce[1] + '</font><br><br>'
845         return txt + '\n</body></html>'
846
847     def count_from_list(self, l, d) :
848         for val in l :
849             if val in d :
850                 d[val] += 1
851             else :
852                 d[val] = 1
853         return d
854
855     def count_from_list_cl(self, l, d, a, clnb) :
856         for val in l :
857             if val in d :
858                 d[val][a] += 1
859             else :
860                 d[val] = [0] * clnb
861                 d[val][a] = 1
862         return d
863
864     def find_segments(self, taille_segment, taille_limite) :
865         d = {}
866         for uce in self.getalluces() :
867             uce = uce[1].split()
868             d = self.count_from_list([' '.join(uce[i:i+taille_segment]) for i in range(len(uce)-(taille_segment - 1))], d)
869         l = [[d[val], val] for val in d if d[val] >= 3]
870         del(d)
871         l.sort()
872         if len(l) > taille_limite :
873             l = l[-taille_limite:]
874         return l
875
876     def find_segments_in_classe(self, list_uce, taille_segment, taille_limite, uci = False):
877         d={}
878         if not uci : 
879             concorde = self.getconcorde
880         else :
881             concorde = self.getuciconcorde
882         for uce in concorde(list_uce) :
883             uce = uce[1].split()
884             d =self.count_from_list([' '.join(uce[i:i+taille_segment]) for i in range(len(uce)-(taille_segment - 1))], d)
885         l = [[d[val], val, taille_segment] for val in d if d[val] >= 3]
886         del(d)
887         l.sort()
888         if len(l) > taille_limite :
889             l = l[-taille_limite:]
890         return l
891             
892     def make_segments_profile(self, fileout, lenmin = 3, lenmax = 10, effmin = 50, lem = False) :
893         d = {}
894         for b, classe in enumerate(self.lc) :
895             for uce in self.getconcorde(classe) :
896                 uce = uce[1].split()
897                 if lem :
898                     uce = [self.formes[forme].lem for forme in uce]
899                 for taille_segment in range(lenmin,lenmax) :
900                     d =self.count_from_list_cl([' '.join(uce[i:i+taille_segment]) for i in range(len(uce)-(taille_segment - 1))], d, b, len(self.lc))
901         result = [[seg] + [str(val) for val in d[seg]] for seg in d if sum(d[seg]) >= effmin]
902         with open(fileout, 'w') as f :
903             f.write('\n'.join([';'.join(line) for line in result]))
904     
905     def make_proftype(self, outf) :
906         res = {}
907         for lem in self.lems :
908             gram = self.lems[lem].gram
909             if not gram in res :
910                 res[gram] = [0 for val in self.lc]
911             lemuceeff = self.getlemuceseff(lem)
912             for i, classe in enumerate(self.lc) :
913                 concern = set(classe).intersection(lemuceeff.keys())
914                 res[gram][i] += sum([lemuceeff[uce] for uce in concern])
915         res = [[gram] + [`val` for val in res[gram]] for gram in res]
916         res.sort()
917         with open(outf, 'w') as f :
918             f.write('\n'.join([';'.join(line) for line in res]).encode(self.parametres['syscoding']))
919
920
921     def make_ucecl_from_R(self, filein) :
922         with open(filein, 'rU') as f :
923             c = f.readlines()
924         c.pop(0)
925         self.lc = []
926         for line in c :
927             line = line.replace('\n', '').replace('"', '').split(';')
928             self.lc.append([int(line[0]) - 1, int(line[1])])
929         classesl = [val[1] for val in self.lc]
930         clnb = max(classesl)
931         self.lc = sorted(self.lc, key=itemgetter(1))
932         self.lc = [[uce[0] for uce in self.lc if uce[1] == i] for i in range(clnb+1)]
933         self.lc0 = self.lc.pop(0)
934         #return ucecl
935     
936     def get_stat_by_cluster(self, outf, lclasses = None) :
937         log.info('get_stat_by_cluster')
938         if lclasses is None :
939             lclasses = self.lc
940         t1 = time()
941         occurrences = dict([[i + 1, 0] for i in range(len(lclasses))])
942         formescl = dict([[i + 1, 0] for i in range(len(lclasses))])
943         hapaxcl = dict([[i + 1, 0] for i in range(len(lclasses))])
944         lenclasses = dict([[i+1,len(cl)] for i, cl in enumerate(lclasses)])
945         sets = [set(cl) for cl in lclasses]
946         for forme in self.formes :
947             formeuceeff = self.getformeuceseff(forme)
948             for i, classe in enumerate(lclasses) :
949                 concern = sets[i].intersection(formeuceeff.keys())
950                 if len(concern) :
951                     occurrences[i+1] += sum([formeuceeff[uce] for uce in concern])
952                     formescl[i+1] += 1
953                     if self.formes[forme].freq == 1 :
954                         hapaxcl[i+1] += 1
955         log.info('%f' % (time() - t1))        
956         if outf is not None :
957             toprint = '\n'.join([';'.join([`i`, `occurrences[i]`, `formescl[i]`, `hapaxcl[i]`, `lenclasses[i]`, `float(hapaxcl[i])/float(formescl[i])`]) for i in occurrences])
958             with open(outf, 'w') as f :
959                 f.write(toprint)
960         else :
961             return [[`occurrences[i]`, `formescl[i]`, `hapaxcl[i]`, `lenclasses[i]`, `float(hapaxcl[i])/float(formescl[i])`] for i in occurrences]
962
963     def get_stat_by_et(self, outf, etoiles) :
964         lclasses = [self.getucesfrometoile(etoile) for etoile in etoiles]
965         stats = self.get_stat_by_cluster(None, lclasses)
966         stats = [[etoiles[i]] + val for i, val in enumerate(stats)]
967
968     def gethapaxbyet(self, etoiles) :
969         hapaxuces = [self.getlemuces(forme)[0] for forme in self.lems if self.lems[forme].freq == 1]
970         hucesdict = {}
971         for uce in hapaxuces :
972             if uce in hucesdict :
973                 hucesdict[uce] += 1
974             else :
975                 hucesdict[uce] = 1
976         etuces = [[] for et in etoiles]
977         for uci in self.ucis :
978             get = list(set(uci.etoiles).intersection(etoiles))
979             if len(get) > 1 :
980                 return '2 variables sur la meme ligne'
981             elif get != [] :
982                 etuces[etoiles.index(get[0])] += [uce.ident for uce in uci.uces]
983         etuces = [set(val) for val in etuces]
984         return [sum([hucesdict[uce] for uce in list(etuce.intersection(hapaxuces))]) for etuce in etuces]
985
986     def gethapaxuces(self) :
987         hapaxuces = [self.getlemuces(forme)[0] for forme in self.lems if self.lems[forme].freq == 1]
988         hapax = [forme for forme in self.lems if self.lems[forme].freq == 1]
989         hucesdict = {}
990         for i,uce in enumerate(hapaxuces) :
991             if uce in hucesdict :
992                 hucesdict[uce][0] += 1
993                 hucesdict[uce][1].append(hapax[i])
994             else :
995                 hucesdict[uce] = [1,[hapax[i]]]
996         huces = {}
997         for uce in hucesdict :
998             if hucesdict[uce][0] in huces :
999                 huces[hucesdict[uce][0]].append(uce)
1000             else :
1001                 huces[hucesdict[uce][0]] = [uce]
1002         huces = zip(huces, huces.values())
1003         huces.sort(reverse=True)
1004         txt = """
1005         <html><body>
1006         """
1007         for nb in huces[0:4] :
1008             txt += "<p><h2>%i hapax par uce</h2><p>\n" % nb[0]
1009             for uce in nb[1] :
1010                 res = self.getconcorde([uce])
1011                 for row in res :
1012                     ucetxt = ' ' + row[1] + ' '
1013                     uceid = row[0]
1014                 for hap in hucesdict[uce][1] :
1015                     laforme = self.getforme([forme for forme in self.lems[hap].formes][0]).forme
1016                     ucetxt = ucetxt.replace(' '+laforme+' ', ' <font color=red>'+laforme+'</font> ')
1017                 txt += '<p><b>' + ' '.join(self.getetbyuceid(uceid)) + '</b></p>'
1018                 txt += '<p>'+ucetxt+'</p>\n'
1019         txt += """
1020         </body></html>
1021         """
1022         with open('/tmp/testhapxuce.html','w') as f :
1023             f.write(txt)
1024
1025     def export_dictionary(self, fileout, syscoding) :
1026         listformes = [[self.formes[forme].freq, forme, self.formes[forme].lem, self.formes[forme].gram] for forme in self.formes]
1027         listformes.sort(reverse = True)
1028         listformes = [forme[1:] + [`forme[0]`] for forme in listformes]
1029         with open(fileout, 'w') as f :
1030             f.write('\n'.join(['\t'.join(forme) for forme in listformes]).encode(syscoding))
1031
1032     def export_lems(self, fileout, syscoding) :
1033         self.make_idformes()
1034         listlem = [[lem, '\t'.join(['\t'.join([self.idformes[forme].forme, `self.lems[lem].formes[forme]`]) for forme in self.lems[lem].formes])] for lem in self.lems]
1035         listlem.sort()
1036         with open(fileout, 'w') as f :
1037             f.write('\n'.join(['\t'.join(lem) for lem in listlem]).encode(syscoding))
1038     
1039
1040
1041 class MakeUciStat :
1042     def __init__(self, corpus) :
1043         ucinb = corpus.getucinb()
1044         ucisize = corpus.getucisize()
1045         ucimean = float(sum(ucisize))/float(ucinb)
1046         detoile = corpus.make_etoiles_dict() 
1047
1048 class Uci :
1049     def __init__(self, iduci, line, paraset = None) :
1050         self.ident = iduci
1051         self.etoiles = line.split()
1052         self.uces = []
1053         if paraset is not None :
1054             self.paras = paraset.split()
1055         else :
1056             self.paras = []
1057
1058 class Uce :
1059     def __init__(self, iduce, idpara, iduci) :
1060         self.ident = iduce
1061         self.para = idpara
1062         self.uci = iduci
1063
1064 class Word :
1065     def __init__(self, word, gramtype, idword, lem = None, freq = None) :
1066         self.forme = word
1067         self.lem = lem
1068         self.gram = gramtype
1069         self.ident = idword
1070         self.act = 1
1071         if freq is not None :
1072             self.freq = freq
1073         else :
1074             self.freq = 1
1075
1076 class Lem :
1077     def __init__(self, parent, forme) :
1078         self.formes = {forme.ident : forme.freq}
1079         self.gram = forme.gram
1080         self.freq = forme.freq
1081         self.act = forme.act
1082
1083     def add_forme(self, forme) :
1084         self.formes[forme.ident] = forme.freq
1085         self.freq += forme.freq
1086
1087 def decouperlist(chaine, longueur, longueurOptimale) :
1088     """
1089         on part du dernier caractère, et on recule jusqu'au début de la chaîne.
1090         Si on trouve un '$', c'est fini.
1091         Sinon, on cherche le meilleur candidat. C'est-à-dire le rapport poids/distance le plus important.
1092     """
1093     separateurs = [[u'.', 6.0], [u'?', 6.0], [u'!', 6.0], [u'£$£', 6.0], [u':', 5.0], [u';', 4.0], [u',', 1.0], [u' ', 0.01]]
1094     dsep = dict([[val[0],val[1]] for val in separateurs])
1095     trouve = False                 # si on a trouvé un bon séparateur
1096     iDecoupe = 0                # indice du caractere ou il faut decouper
1097     
1098     longueur = min(longueur, len(chaine) - 1)
1099     chaineTravail = chaine[:longueur + 1]
1100     nbCar = longueur
1101     meilleur = ['', 0, 0]        # type, poids et position du meilleur separateur
1102     
1103     try :
1104         indice = chaineTravail.index(u'$')
1105         trouve = True
1106         iDecoupe = indice - 1
1107     except ValueError :
1108         pass
1109     if not trouve:
1110         while nbCar >= 0:
1111             caractere = chaineTravail[nbCar]
1112             distance = abs(longueurOptimale - nbCar) + 1
1113             meilleureDistance = abs(longueurOptimale - meilleur[2]) + 1
1114             if caractere in dsep :
1115                 if (float(dsep[caractere]) / distance) > (float(meilleur[1]) / meilleureDistance) :
1116                     meilleur[0] = caractere
1117                     meilleur[1] = dsep[caractere]
1118                     meilleur[2] = nbCar
1119                     trouve = True
1120                     iDecoupe = nbCar
1121             else :
1122                 if (float(dsep[' ']) / distance) > (float(meilleur[1]) / meilleureDistance) :
1123                     meilleur[0] = ' '
1124                     meilleur[1] = dsep[' ']
1125                     meilleur[2] = nbCar
1126                     trouve = True
1127                     iDecoupe = nbCar
1128             nbCar = nbCar - 1
1129     # si on a trouvé
1130     if trouve:
1131         #if meilleur[0] != ' ' :
1132         #    fin = chaine[iDecoupe + 1:]
1133         #    retour = chaineTravail[:iDecoupe]
1134         #else :
1135         fin = chaine[iDecoupe + 1:]
1136         retour = chaineTravail[:iDecoupe + 1]
1137         return len(retour) > 0, retour, fin
1138     # si on a rien trouvé
1139     return False, chaine, ''
1140
1141 def testetoile(line) :
1142     return line.startswith(u'****')
1143
1144 def testint(line) :
1145     return line[0:4].isdigit() and u'*' in line
1146
1147 def prep_txtlist(txt) :
1148     return txt.split() + [u'$']
1149
1150 def prep_txtcharact(txt) :
1151     return txt + u'$'
1152
1153 class BuildCorpus :
1154     """
1155     Class for building a corpus
1156     """
1157     def __init__(self, infile, parametres_corpus, lexique = None, expressions = None, dlg = None) :
1158         log.info('begin building corpus...')
1159         self.lexique = lexique
1160         self.expressions = expressions
1161         self.dlg = dlg
1162         self.corpus = Corpus(self, parametres_corpus)
1163         self.infile = infile
1164         self.last = 0
1165         self.lim = parametres_corpus.get('lim', 1000000)
1166         self.encoding = parametres_corpus['encoding']
1167         self.corpus.pathout = PathOut(filename = parametres_corpus['originalpath'], dirout = parametres_corpus['pathout'])
1168         self.corpus.pathout.createdir(parametres_corpus['pathout'])
1169         self.corpus.parametres['uuid'] = str(uuid4())
1170         self.corpus.parametres['corpus_name'] = parametres_corpus['corpus_name']#os.path.split(self.corpus.parametres['pathout'])[1]
1171         self.corpus.parametres['type'] = 'corpus'
1172         if self.corpus.parametres['keep_ponct'] :
1173             self.ponctuation_espace = [' ', '']
1174         else :
1175             self.ponctuation_espace =  [' ','.', u'£$£', ';', '?', '!', ',', ':','']
1176         self.cleans = []
1177         self.tolist = self.corpus.parametres.get('tolist', 0)
1178         self.buildcleans()
1179         self.prep_makeuce()
1180         #create database
1181         self.connect()
1182         self.dobuild()
1183
1184     def prep_makeuce(self) :
1185         method = self.corpus.parametres.get('ucemethod', 0)
1186         if method == 1 :
1187             self.decouper = decouperlist
1188             self.prep_txt = prep_txtlist
1189             self.ucesize = self.corpus.parametres.get('ucesize', 40)
1190         elif method == 0 :
1191             self.decouper = decoupercharact
1192             self.prep_txt = prep_txtcharact
1193             self.ucesize = self.corpus.parametres.get('ucesize', 240)
1194         log.info('method uce : %s' % method)
1195
1196     def dobuild(self) :    
1197         t1 = time()
1198         try :
1199             self.read_corpus(self.infile)
1200         except Warning, args :
1201             log.info('pas kool %s' % args)
1202             raise Warning
1203         else :    
1204             self.indexdb()
1205             self.corpus.parametres['ira'] = self.corpus.pathout['Corpus.cira']
1206             self.time = time() - t1
1207             self.dofinish()
1208             DoConf().makeoptions(['corpus'],[self.corpus.parametres], self.corpus.pathout['Corpus.cira'])
1209             log.info('time : %f' % (time() - t1))
1210
1211     def connect(self) :
1212         self.conn_f = sqlite3.connect(self.corpus.pathout['formes.db'])
1213         self.cf = self.conn_f.cursor()
1214         self.cf.execute('CREATE TABLE IF NOT EXISTS uces (id INTEGER, uces TEXT);')
1215         self.cf.execute('CREATE TABLE IF NOT EXISTS eff (id INTEGER, eff TEXT);')
1216         self.conn_f.commit()
1217         self.cf = self.conn_f.cursor()
1218         self.cf.execute('PRAGMA temp_store=MEMORY;')
1219         self.cf.execute('PRAGMA journal_mode=MEMORY;')
1220         self.cf.execute('PRAGMA  synchronous = OFF;')
1221         self.cf.execute('begin')
1222         self.conn = sqlite3.connect(self.corpus.pathout['uces.db'])
1223         self.c = self.conn.cursor()
1224         self.c.execute('CREATE TABLE IF NOT EXISTS uces (id INTEGER, uces TEXT);')
1225         self.conn.commit()
1226         self.c = self.conn.cursor()
1227         self.c.execute('PRAGMA temp_store=MEMORY;')
1228         self.c.execute('PRAGMA journal_mode=MEMORY;')
1229         self.c.execute('PRAGMA  synchronous = OFF;')
1230         self.c.execute('begin')
1231
1232     def indexdb(self) :
1233         #commit index and close db
1234         self.conn.commit()
1235         self.conn_f.commit()
1236         self.cf.execute('CREATE INDEX iduces ON uces (id);')
1237         self.cf.execute('CREATE INDEX ideff ON eff (id);')
1238         self.c.close()
1239         self.cf.close()
1240         #backup corpus
1241         self.conn_corpus = sqlite3.connect(self.corpus.pathout['corpus.db'])
1242         self.ccorpus = self.conn_corpus.cursor()
1243         self.ccorpus.execute('CREATE TABLE IF NOT EXISTS etoiles (uci INTEGER, et TEXT, paras TEXT);')
1244         self.ccorpus.execute('CREATE TABLE IF NOT EXISTS luces (uci INTEGER, para INTEGER, uce INTEGER);')
1245         self.ccorpus.execute('CREATE TABLE IF NOT EXISTS formes (ident INTEGER, forme TEXT, lem TEXT, gram TEXT, freq INTEGER);')
1246         self.conn_corpus.commit()
1247         self.ccorpus = self.conn_corpus.cursor()
1248         self.ccorpus.execute('PRAGMA temp_store=MEMORY;')
1249         self.ccorpus.execute('PRAGMA journal_mode=MEMORY;')
1250         self.ccorpus.execute('PRAGMA  synchronous = OFF;')
1251         self.ccorpus.execute('begin')
1252         self.backup_corpus()
1253         self.ccorpus.execute('CREATE INDEX iduci ON luces (uci);')
1254         self.conn_corpus.commit()
1255         self.conn_corpus.close()
1256         #self.corpus.parametres['corpus_ira'] = self.corpus.pathout['corpus.cira']
1257
1258     def buildcleans(self) :
1259         if self.corpus.parametres.get('lower', 1) :
1260             self.cleans.append(self.dolower)
1261         if self.corpus.parametres.get('firstclean', 1) :
1262             self.cleans.append(self.firstclean)
1263         if self.corpus.parametres['charact'] :
1264             self.rule = self.corpus.parametres.get('keep_caract', u"^a-zA-Z0-9àÀâÂäÄáÁéÉèÈêÊëËìÌîÎïÏòÒôÔöÖùÙûÛüÜçÇßœŒ’ñ.:,;!?*'_")
1265             self.cleans.append(self.docharact)
1266         if self.corpus.parametres.get('expressions', 1) :
1267             self.cleans.append(self.make_expression)
1268         if self.corpus.parametres.get('apos', 1) :
1269             self.cleans.append(self.doapos)
1270         if self.corpus.parametres.get('tiret', 1):
1271             self.cleans.append(self.dotiret)
1272
1273     def make_expression(self,txt) :
1274         for expression in self.expressions:
1275             if expression in txt :
1276                 txt = txt.replace(expression, self.expressions[expression][0])
1277         return txt
1278     
1279     def dolower(self, txt) :
1280         return txt.lower()
1281
1282     def docharact(self, txt) :
1283         #rule = u"^a-zA-Z0-9àÀâÂäÄáÁéÉèÈêÊëËìÌîÎïÏòÒôÔöÖùÙûÛüÜçÇßœŒ’ñ.:,;!?*'_-"
1284         list_keep = u"[" + self.rule + "]+"
1285         return re.sub(list_keep, ' ', txt)
1286     
1287     def doapos(self, txt) :
1288         return txt.replace(u'\'', u' ')
1289
1290     def dotiret(self, txt) :
1291         return txt.replace(u'-', u' ')
1292
1293     def firstclean(self, txt) :
1294         txt = txt.replace(u'’',"'")
1295         txt = txt.replace(u'œ', u'oe')
1296         return txt.replace('...',u' £$£ ').replace('?',' ? ').replace('.',' . ').replace('!', ' ! ').replace(',',' , ').replace(';', ' ; ').replace(':',' : ').replace(u'…', u' £$£ ')
1297
1298     def make_cleans(self, txt) :
1299         for clean in self.cleans :
1300             txt = clean(txt)
1301         return txt
1302
1303     def backup_uce(self) :
1304         if self.corpus.idformesuces != {} :
1305             log.info('backup %i' % len(self.corpus.idformesuces))
1306             touce = [(`forme`, ' '.join([`val` for val in  self.corpus.idformesuces[forme].keys()])) for forme in self.corpus.idformesuces]
1307             toeff = [(`forme`, ' '.join([`val` for val in  self.corpus.idformesuces[forme].values()])) for forme in self.corpus.idformesuces]
1308             self.cf.executemany('INSERT INTO uces VALUES (?,?);', touce)
1309             self.cf.executemany('INSERT INTO eff VALUES (?,?);', toeff)
1310         self.corpus.idformesuces = {}        
1311         self.count = 1
1312
1313     def backup_corpus(self) :
1314         log.info('start backup corpus')
1315         t = time()
1316         for uci in self.corpus.ucis :
1317             self.ccorpus.execute('INSERT INTO etoiles VALUES (?,?,?);' ,(uci.ident,' '.join(uci.etoiles), ' '.join(uci.paras,)))
1318             for uce in uci.uces : 
1319                 self.ccorpus.execute('INSERT INTO luces VALUES (?,?,?);',(`uci.ident`,`uce.para`,`uce.ident`,))
1320         for forme in self.corpus.formes :
1321             self.ccorpus.execute('INSERT INTO formes VALUES (?,?,?,?,?);', (`self.corpus.formes[forme].ident`, forme, self.corpus.formes[forme].lem, self.corpus.formes[forme].gram, `self.corpus.formes[forme].freq`,))
1322         log.info('%f' % (time() - t))
1323
1324     def dofinish(self) :
1325         self.corpus.parametres['date'] = datetime.datetime.now().ctime()
1326         minutes, seconds = divmod(self.time, 60)
1327         hours, minutes = divmod(minutes, 60)
1328         self.corpus.parametres['time'] = '%.0fh %.0fm %.0fs' % (hours, minutes, seconds)
1329         self.corpus.parametres['ucinb'] = self.corpus.getucinb()
1330         self.corpus.parametres['ucenb'] = self.corpus.getucenb()
1331         self.corpus.parametres['occurrences'] = self.corpus.gettotocc()
1332         self.corpus.parametres['formesnb'] = len(self.corpus.formes)
1333         hapaxnb = self.corpus.gethapaxnb()
1334         pourhapaxf = (float(hapaxnb) / len(self.corpus.formes)) * 100
1335         pourhapaxocc = (float(hapaxnb) / self.corpus.parametres['occurrences']) * 100
1336         self.corpus.parametres['hapax'] = '%i - %.2f %% des formes - %.2f %% des occurrences' % (hapaxnb, pourhapaxf, pourhapaxocc)
1337
1338 class BuildSubCorpus(BuildCorpus):
1339     def __init__(self, corpus, parametres, dlg = None) :
1340         log.info('begin subcorpus...')
1341         self.dlg = dlg
1342         self.ori = corpus
1343         self.infile = None
1344         self.corpus = Corpus(self, {'type' : 'corpus', 'originalpath' : corpus.parametres['originalpath'], 'encoding' : corpus.parametres['encoding']})
1345         self.last = 0
1346         self.parametres = parametres
1347         self.encoding = corpus.parametres['encoding']
1348         self.corpus.parametres['corpus_name'] = parametres['corpus_name']
1349         self.corpus.pathout = PathOut(filename = corpus.parametres['originalpath'], dirout = parametres['pathout'])
1350         self.corpus.pathout.createdir(parametres['pathout'])
1351         self.corpus.parametres['pathout'] = parametres['pathout']
1352         self.corpus.parametres['meta'] = parametres.get('meta', False)
1353         self.corpus.parametres['uuid'] = str(uuid4())
1354         if parametres.get('frommeta', False) :
1355             print 'make subtexts'
1356             self.corpus.ucis = [CopyUci(uci) for uci in self.ori.ucis if set(parametres['meta']).intersection(uci.etoiles) != set()]
1357         elif parametres.get('fromtheme', False) :
1358             print 'make subtexts from theme'
1359             idpara = 0
1360             for uci in self.ori.ucis :
1361                 if uci.paras != [] :
1362                     newuce = []
1363                     newpara = []
1364                     for et in uci.paras :
1365                         if et in parametres['meta'] :
1366                             newuce += [CopyUce(uce) for uce in uci.uces if uce.para == idpara]
1367                             newpara.append(et)
1368                         idpara += 1
1369                     if newuce != [] :
1370                         nuci = CopyUci(uci)
1371                         nuci.uces = newuce
1372                         nuci.paras = newpara
1373                         self.corpus.ucis.append(nuci)
1374                 else :
1375                     idpara += 1  
1376         elif parametres.get('fromclusters', False) :
1377             self.parametres['uceids'] = [st for i in self.parametres['meta'] for st in self.parametres['lc'][i]]
1378             self.fromuceids()
1379         elif parametres.get('fromuceids', False) :
1380             self.fromuceids()
1381         #create database
1382         self.connect()
1383         self.dobuild()
1384
1385     def fromuceids(self):
1386         print 'fromuceids'
1387         dictucekeep = dict(zip(self.parametres['uceids'], self.parametres['uceids']))
1388         idpara = 0
1389         for uci in self.ori.ucis :
1390             if uci.paras == [] :
1391                 keepuces = [CopyUce(uce) for uce in uci.uces if uce.ident in dictucekeep]
1392                 if keepuces != [] :
1393                     nuci = CopyUci(uci)
1394                     nuci.uces = keepuces
1395                     self.corpus.ucis.append(nuci)
1396                 idpara += 1
1397             else :
1398                 newuces = []
1399                 newpara = []
1400                 for et in uci.paras :
1401                     keepuces = [CopyUce(uce) for uce in uci.uces if uce.ident in dictucekeep]
1402                     idpara += 1
1403                     if keepuces != [] :
1404                         newuces += keepuces
1405                         newpara.append(et)
1406                 if newuces != [] :
1407                     nuci = CopyUci(uci)
1408                     nuci.uces = newuces
1409                     nuci.paras = newpara
1410                     self.corpus.ucis.append(nuci)       
1411     
1412     def read_corpus(self, infile = None):
1413         self.olduceid = [uce.ident for uci in self.corpus.ucis for uce in uci.uces]
1414         ident_uci = 0
1415         ident_uce = 0
1416         ident_para = -1
1417         lastpara = -1
1418         newuceident = {}
1419         print 'redo text, para and st ident'
1420         for uci in self.corpus.ucis :
1421             uci.ident = ident_uci
1422             ident_uci += 1
1423             for uce in uci.uces :
1424                 uce.uci = uci.ident
1425                 if uce.para != lastpara :
1426                     ident_para += 1
1427                     lastpara = uce.para
1428                     uce.para = ident_para
1429                 else :
1430                     uce.para = ident_para
1431                 newuceident[uce.ident] = ident_uce
1432                 uce.ident = ident_uce
1433                 ident_uce += 1
1434         print 'backup st text and forms'
1435         for row in self.ori.getconcorde(self.olduceid) :
1436             self.c.execute('INSERT INTO uces VALUES(?,?);', (`newuceident[row[0]]`, row[1]))
1437             for word in row[1].split() :
1438                 self.corpus.add_word_from_forme(self.ori.formes[word], newuceident[row[0]])
1439         self.backup_uce()
1440         print 'done'
1441
1442 class BuildFromAlceste(BuildCorpus) :
1443     def read_corpus(self, infile) :
1444         if self.dlg is not None :
1445             self.dlg.Pulse('textes : 0 - segments : 0')
1446         self.limitshow = 0
1447         self.count = 1
1448         if self.corpus.parametres['ucimark'] == 0 :
1449             self.testuci = testetoile
1450         elif  self.corpus.parametres['ucimark'] == 1 :
1451             self.testuci = testint
1452         txt = []
1453         iduci = -1
1454         idpara = -1
1455         iduce = -1
1456         try :
1457             with codecs.open(infile, 'r', self.encoding) as f :
1458                 for linenb, line in enumerate(f) :
1459                     line = line.rstrip('\n\r')#FIXME .lstrip(codecs.BOM).lstrip(codecs.BOM_UTF8)
1460                     if self.testuci(line) :
1461                         iduci += 1
1462                         if txt != [] :
1463                             iduce, idpara = self.treattxt(txt, iduce, idpara, iduci - 1)
1464                             txt = []
1465                             self.corpus.ucis.append(Uci(iduci, line))
1466                         else :
1467                             if iduci > 0 :
1468                                 if self.corpus.ucis[-1].uces == [] :
1469                                     log.info(u'Empty text : %i' % linenb)
1470                                     iduci -= 1
1471                                     self.corpus.ucis.pop()
1472                             self.corpus.ucis.append(Uci(iduci, line))
1473                         if self.dlg is not None :
1474                             if not (iduci + 1) % 10 :
1475                                 self.dlg.Pulse('textes : %i - segments : %i' % (iduci + 1, iduce +1))
1476                     elif line.startswith(u'-*') :
1477                         if iduci != -1 :
1478                             if txt != [] :
1479                                 iduce, idpara = self.treattxt(txt, iduce, idpara, iduci)
1480                                 txt = []
1481                             idpara += 1
1482                             self.corpus.ucis[-1].paras.append(line.split()[0])
1483                         else :
1484                             raise Exception('paragrapheOT %i' % linenb)
1485                     elif line.strip() != '' and iduci != -1 :
1486                         txt.append(line)
1487             if txt != [] and iduci != -1 :
1488                 iduce, idpara = self.treattxt(txt, iduce, idpara, iduci)
1489                 del(txt)
1490             else :
1491                 if iduci != -1 :
1492                     iduci -= 1
1493                     self.corpus.ucis.pop()
1494                     log.info(Exception("Empty text %i" % linenb))
1495                 else :
1496                     raise Exception('EmptyText %i' % linenb)
1497             if iduci != -1  and iduce != -1:
1498                 self.backup_uce()
1499             else : 
1500                 log.info(_(u"No Text in corpus. Are you sure of the formatting ?"))
1501                 raise Exception('TextBeforeTextMark %i' % linenb)
1502         except UnicodeDecodeError :
1503             raise Exception("CorpusEncoding")
1504
1505     def treattxt(self, txt, iduce, idpara, iduci) :
1506         if self.corpus.parametres.get('ucemethod', 0) == 2 and self.corpus.parametres['douce']:
1507             txt = 'laphrasepoursplitter'.join(txt)
1508             txt = self.make_cleans(txt)
1509             txt = ' '.join([val for val in txt.split() if val not in self.ponctuation_espace])
1510             ucetxt = txt.split('laphrasepoursplitter')
1511         else :
1512             txt = ' '.join(txt)
1513             txt = self.make_cleans(txt)
1514             ucetxt = self.make_uces(txt, self.corpus.parametres['douce'])
1515         if self.corpus.ucis[-1].paras == [] :
1516             idpara += 1
1517         for uce in ucetxt :
1518             iduce += 1
1519             self.corpus.ucis[-1].uces.append(Uce(iduce, idpara, iduci))
1520             self.c.execute('INSERT INTO uces VALUES(?,?);', (`iduce`,uce))
1521             if not self.tolist :
1522                 uce = uce.split()
1523             else :
1524                 uce = list(uce)
1525             for word in uce :
1526                 self.last += 1
1527                 self.corpus.add_word(word)
1528         log.debug(' '.join([`iduci`,`idpara`,`iduce`]))
1529         if self.last > self.lim :
1530             self.backup_uce()
1531             self.last = 0
1532         return iduce, idpara
1533
1534     def make_uces(self, txt, douce = True, keep_ponct = False) :
1535         txt = ' '.join(txt.split())
1536         if douce :
1537             out = []
1538             reste, texte_uce, suite = self.decouper(self.prep_txt(txt), self.ucesize + 15, self.ucesize)
1539             while reste :
1540                 uce = ' '.join([val for val in texte_uce if val not in self.ponctuation_espace])
1541                 if uce != '' :
1542                     out.append(uce)
1543                 reste, texte_uce, suite = self.decouper(suite, self.ucesize + 15, self.ucesize)
1544             uce = ' '.join([val for val in texte_uce if val not in self.ponctuation_espace])
1545             if uce != '' : 
1546                 out.append(uce)
1547             return out
1548         else :
1549             return [' '.join([val for val in txt.split() if val not in self.ponctuation_espace])]
1550
1551 #decouper (list_sep)
1552 #make_uces (decouper)
1553 #treat_txt (make_uces)
1554 #read (treat_txt)
1555
1556 class Builder :
1557     def __init__(self, parent, dlg = None) :
1558         self.parent = parent
1559         self.dlg = dlg
1560         parametres = DoConf(os.path.join(self.parent.UserConfigPath,'corpus.cfg')).getoptions('corpus')
1561         parametres['pathout'] = PathOut(parent.filename, 'corpus').mkdirout()
1562         parametres['corpus_name'] = os.path.split(parametres['pathout'])[1]
1563         dial = CorpusPref(parent, parametres)
1564         dial.CenterOnParent()
1565         dial.txtpath.SetLabel(parent.filename)
1566         #dial.repout_choices.SetValue(parametres['pathout'])
1567         self.res = dial.ShowModal()
1568         if self.res == 5100 :
1569             parametres = dial.doparametres()
1570             parametres['originalpath'] = parent.filename
1571             PathOut().createdir(parametres['pathout'])
1572             if parametres.get('dictionary', False) :
1573                 filein = parametres['dictionary']
1574             else :
1575                 filein = None
1576             dial.Destroy()
1577             ReadLexique(self.parent, lang = parametres['lang'], filein = filein)
1578             if parametres['lang'] != 'other' and  os.path.exists(self.parent.DictPath.get(parametres['lang']+'_exp', 'french_exp')):
1579                 self.parent.expressions = ReadDicoAsDico(self.parent.DictPath.get(parametres['lang']+'_exp', 'french_exp'))
1580             else :
1581                 self.parent.expressions = {}
1582             self.parametres = parametres
1583         else :
1584             dial.Destroy()
1585             if self.dlg is not None :
1586                 self.dlg.Destroy()
1587
1588     def doanalyse(self) :
1589         return BuildFromAlceste(self.parent.filename, self.parametres, self.parent.lexique, self.parent.expressions, dlg = self.dlg).corpus
1590
1591 class SubBuilder :
1592     def __init__(self, parent, corpus, parametres = None, dlg = None):
1593         self.parent = parent
1594         self.ori = corpus
1595         self.dlg = dlg
1596         corpus_name = 'Sub' + corpus.parametres['corpus_name']
1597         if dlg is not None :
1598             busy = wx.BusyInfo(_("Please wait...").decode('utf8'), self)
1599             wx.SafeYield()
1600         parametres['corpus_name'] = corpus_name
1601         if parametres.get('frommeta', False) :
1602             parametres['meta'] = corpus.make_etoiles()
1603         elif parametres.get('fromtheme', False) :
1604             parametres['meta'] = corpus.make_themes()
1605         elif parametres.get('fromclusters', False) :
1606             parametres['meta'] = [' '.join(['classe', `i`]) for i in range(1,parametres['clnb'] + 1)]
1607         else :
1608             parametres['meta'] = []
1609         if 'fromclusters' not in parametres :
1610             parametres['meta'].sort()
1611         if dlg is not None :
1612             del busy
1613         dial = SubTextFromMetaDial(parent, parametres)
1614         self.res = dial.ShowModal()
1615         if self.res == 5100 :
1616             if dial.subcorpusname.GetValue() != '' :
1617                 corpus_name = ''.join([l for l in dial.subcorpusname.GetValue() if l.isalnum() or l in ['_']])
1618             if corpus_name != '' :
1619                 parametres['corpus_name'] = corpus_name
1620             else :
1621                 parametres['corpus_name'] = 'Sub' + corpus.parametres['corpus_name']
1622             pathout = os.path.join(corpus.parametres['pathout'], parametres['corpus_name'])
1623             i = 1
1624             while os.path.exists(pathout + '_%i' % i) :
1625                 i += 1
1626             parametres['pathout'] = pathout + '_%i' % i
1627             meta = dial.m_listBox1.GetSelections()
1628             if not 'fromclusters' in parametres :
1629                 parametres['meta'] = [parametres['meta'][val] for val in meta]
1630             else :
1631                 parametres['meta'] = meta
1632             self.parametres = parametres
1633             dial.Destroy()
1634         else :
1635             dial.Destroy()
1636     
1637     def doanalyse(self):
1638         return BuildSubCorpus(self.ori, parametres = self.parametres, dlg = self.dlg).corpus