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