44ea0ef07774f9a7855f1e98c14c857e87d966a5
[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
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
20 from functions import ReadLexique, ReadDicoAsDico
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
38
39 class Corpus :
40     """Corpus class
41     list of uci
42
43     """
44     def __init__(self, parent, parametres = {}, read = False) :
45         self.parent = parent
46         self.parametres = parametres
47         self.cformes = None         
48         self.connformes = None
49         self.connuces = None
50         self.conncorpus = None
51         self.islem = False
52         self.cuces = None
53         self.ucis = []
54         self.formes = {}
55         self.flems = {}
56         self.lems = None
57         self.idformesuces = {}
58         self.iduces = None
59         self.idformes = None
60         self.uceuci = None
61         if read :
62             self.pathout = PathOut(dirout = parametres['pathout'])
63             self.read_corpus()
64
65     def add_word(self, word) :
66         if word in self.formes :
67             self.formes[word].freq += 1
68             if self.formes[word].ident in self.idformesuces :
69                 if self.ucis[-1].uces[-1].ident in self.idformesuces[self.formes[word].ident] :
70                     self.idformesuces[self.formes[word].ident][self.ucis[-1].uces[-1].ident] += 1
71                 else :
72                     self.idformesuces[self.formes[word].ident][self.ucis[-1].uces[-1].ident] = 1
73             else :
74                 self.idformesuces[self.formes[word].ident] = {self.ucis[-1].uces[-1].ident: 1}
75         else :
76             if word in self.parent.lexique :
77                 gramtype = self.parent.lexique[word][1]
78                 lem = self.parent.lexique[word][0]
79             elif word.isdigit() :
80                 gramtype = 'num'
81                 lem = word
82             else :
83                 gramtype = 'nr'
84                 lem = word
85             self.formes[word] =  Word(word, gramtype, len(self.formes), lem)
86             self.idformesuces[self.formes[word].ident] = {self.ucis[-1].uces[-1].ident : 1}
87
88     def conn_all(self): 
89         """connect corpus to db"""
90         if self.connformes is None :
91             log.info('connexion corpus')
92             self.connuces = sqlite3.connect(self.pathout['uces.db'])
93             self.cuces = self.connuces.cursor()
94             self.connformes = sqlite3.connect(self.pathout['formes.db'])
95             self.cformes = self.connformes.cursor()
96             self.conncorpus = sqlite3.connect(self.pathout['corpus.db'])
97             self.ccorpus = self.conncorpus.cursor()
98             self.cformes.execute('PRAGMA temp_store=MEMORY;')
99             self.cformes.execute('PRAGMA journal_mode=MEMORY;')
100             self.cformes.execute('PRAGMA  synchronous = OFF;')
101             self.cuces.execute('PRAGMA temp_store=MEMORY;')
102             self.cuces.execute('PRAGMA journal_mode=MEMORY;')
103             self.cuces.execute('PRAGMA  synchronous = OFF;')
104             self.ccorpus.execute('PRAGMA temp_store=MEMORY;')
105             self.ccorpus.execute('PRAGMA journal_mode=MEMORY;')
106             self.ccorpus.execute('PRAGMA  synchronous = OFF;')
107
108     def read_corpus(self) :
109         log.info('read corpus')
110         self.parametres['syscoding'] = sys.getdefaultencoding()
111         if self.conncorpus is None :
112             self.conn_all()
113         res = self.ccorpus.execute('SELECT * FROM etoiles;')
114         for row in res :
115             self.ucis.append(Uci(row[0], row[1], row[2]))
116             uces = self.conncorpus.cursor().execute('SELECT * FROM luces where uci=?;',(`self.ucis[-1].ident`,))
117             for uce in uces:
118                 self.ucis[-1].uces.append(Uce(uce[2], uce[1], uce[0]))
119         res = self.ccorpus.execute('SELECT * FROM formes;')
120         self.formes = dict([[forme[1], Word(forme[1], forme[3], forme[0], lem = forme[2], freq = forme[4])] for forme in res])
121         self.ccorpus.close()
122     
123     def getworduces(self, wordid) :
124         if isinstance(wordid, basestring) :
125             wordid = self.formes[wordid].ident
126         res = self.cformes.execute('SELECT uces FROM uces where id=? ORDER BY id;', (`wordid`,))
127         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]))
128
129     def getformeuceseff(self, formeid) :
130         if isinstance(formeid, basestring) :
131             formeid = self.formes[formeid].ident
132         res = self.cformes.execute('SELECT uces FROM uces where id=? ORDER BY id;', (`formeid`,))
133         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]))
134         query = 'SELECT eff FROM eff where id=%i ORDER BY id' % formeid
135         res = self.cformes.execute(query)
136         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]))
137         formeuceeff = {}
138         for i, uce in enumerate(uces) :
139             formeuceeff[uce] = formeuceeff.get(uce, 0) + eff[i]
140         return formeuceeff    
141
142     def getlemuces(self, lem) :
143         formesid = ', '.join([`val` for val in self.lems[lem].formes])
144         query = 'SELECT uces FROM uces where id IN (%s) ORDER BY id' % formesid
145         res = self.cformes.execute(query)
146         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]))))
147
148     def getlemucis(self, lem) :
149         uces = self.getlemuces(lem)
150         return list(set([self.getucefromid(val).uci for val in uces]))
151
152     def getlemuceseff(self, lem, luces = None) :
153         formesid = ', '.join([`val` for val in self.lems[lem].formes])
154         query = 'SELECT uces FROM uces where id IN (%s) ORDER BY id' % formesid
155         res = self.cformes.execute(query)
156         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]))
157         query = 'SELECT eff FROM eff where id IN (%s) ORDER BY id' % formesid
158         res = self.cformes.execute(query)
159         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]))
160         lemuceeff = {}
161         for i, uce in enumerate(uces) :
162             lemuceeff[uce] = lemuceeff.get(uce, 0) + eff[i]
163         return lemuceeff    
164
165     def getlemclustereff(self, lem, cluster) :
166         return len(list(set(self.lc[cluster]).intersection(self.getlemuces(lem))))
167
168     def getlemeff(self, lem) :
169         return self.lems[lem].freq
170
171     def getlems(self) :
172         return self.lems
173
174     def getforme(self, formeid) :
175         if self.idformes is None : self.make_idformes()
176         return self.idformes[formeid]
177
178     def gettotocc(self) :
179         return sum([self.formes[forme].freq for forme in self.formes])
180
181     def getucemean(self) :
182         return float(self.gettotocc())/self.getucenb()
183
184     def getucenb(self) :
185         return self.ucis[-1].uces[-1].ident + 1
186
187     def getucinb(self) :
188         return self.ucis[-1].ident + 1
189
190     def getucisize(self) :
191         ucesize = self.getucesize()
192         return [sum(ucesize[uci.uces[0].ident:(uci.uces[-1].ident + 1)]) for uci in self.ucis]
193     
194     def getucesize(self) :
195         res = self.getalluces()
196         return [len(uce[1].split()) for uce in res]
197
198     def getconcorde(self, uces) :
199         return self.cuces.execute('select * from uces where id IN (%s);' % ', '.join([`i` for i in uces])) 
200
201     def getwordconcorde(self, word) :
202         return self.getconcorde(self.getworduces(word))
203
204     def getlemconcorde(self, lem) :
205         return self.getconcorde(self.getlemuces(lem))
206
207     def getalluces(self) :
208         return self.cuces.execute('SELECT * FROM uces')
209
210     def getucesfrometoile(self, etoile) :
211         return [uce.ident for uci in self.ucis for uce in uci.uces if etoile in uci.etoiles]
212
213     def getetoileuces(self) :
214         log.info('get uces etoiles')
215         etoileuces = {}
216         idpara = 0
217         for uci in self.ucis :
218             etoiles = uci.etoiles[1:]
219             for et in etoiles :
220                 if et in etoileuces :
221                     etoileuces[et] += [uce.ident for uce in uci.uces]
222                 else :
223                     etoileuces[et] = [uce.ident for uce in uci.uces]
224             if uci.paras != [] :
225                 for et in uci.paras :
226                     if et in etoileuces :
227                         etoileuces[et] += [uce.ident for uce in uci.uces if uce.para == idpara]
228                     else :
229                         etoileuces[et] = [uce.ident for uce in uci.uces if uce.para == idpara]
230                     idpara += 1
231             else :
232                 idpara += 1
233         return etoileuces
234
235     def getucefromid(self, uceid) :
236         if self.iduces is None : self.make_iduces()
237         return self.iduces[uceid]
238
239     def gethapaxnb(self) :
240         return len([None for forme in self.formes if self.formes[forme].freq == 1])
241
242     def getactivesnb(self, key) :
243         return len([lem for lem in self.lems if self.lems[lem].act == key])
244 #    def make_lems(self, lem = True) :
245 #        log.info('make lems')
246 #        self.lems = {}
247 #        for forme in self.formes :
248 #            if self.formes[forme].lem in self.lems :
249 #                if self.formes[forme].ident not in self.lems[self.formes[forme].lem] :
250 #                    self.lems[self.formes[forme].lem][self.formes[forme].ident] = 0
251 #            else :
252 #                    self.lems[self.formes[forme].lem] = {self.formes[forme].ident : 0}
253
254     def getetbyuceid(self, uceid) :
255         if self.uceuci is None : self.uceuci = dict([[uce.ident,uci.ident] for uci in self.ucis for uce in uci.uces])
256         return self.ucis[self.uceuci[uceid]].etoiles
257
258     def make_lems(self, lem = True) :
259         log.info('make lems')
260         self.lems = {}
261         if lem :
262             for forme in self.formes :
263                 if self.formes[forme].lem in self.lems :
264                     if self.formes[forme].ident not in self.lems[self.formes[forme].lem].formes :
265                         self.lems[self.formes[forme].lem].add_forme(self.formes[forme])
266                 else :
267                     self.lems[self.formes[forme].lem] = Lem(self, self.formes[forme])
268         else :
269             self.lems = dict([[forme, Lem(self, self.formes[forme])] for forme in self.formes])
270                 
271     def make_idformes(self) :
272         self.idformes = dict([[self.formes[forme].ident, self.formes[forme]] for forme in self.formes])
273
274     def make_iduces(self) :
275         if self.iduces is None :
276             self.iduces = dict([[uce.ident, uce] for uci in self.ucis for uce in uci.uces])
277
278     def make_lexitable(self, mineff, etoiles) :
279         tokeep = [lem for lem in self.lems if self.lems[lem].freq >= mineff]
280         etuces = [[] for et in etoiles]
281         for uci in self.ucis :
282             get = list(set(uci.etoiles).intersection(etoiles))
283             if len(get) > 1 :
284                 return '2 variables sur la meme ligne'
285             elif get != [] :
286                 etuces[etoiles.index(get[0])] += [uce.ident for uce in uci.uces]
287         etuces = [set(val) for val in etuces]
288         tab = []
289         for lem in tokeep :
290             deff = self.getlemuceseff(lem)
291             ucesk = deff.keys()
292             tab.append([lem] + [sum([deff[uce] for uce in et.intersection(ucesk)]) for et in etuces])
293         tab.insert(0, [''] + etoiles)
294         return tab
295     
296     def make_efftype_from_etoiles(self, etoiles) :
297         dtype = {}
298         etuces = [[] for et in etoiles]
299         for uci in self.ucis :
300             get = list(set(uci.etoiles).intersection(etoiles))
301             if len(get) > 1 :
302                 return '2 variables sur la meme ligne'
303             elif get != [] :
304                 etuces[etoiles.index(get[0])] += [uce.ident for uce in uci.uces]
305         etuces = [set(val) for val in etuces]
306         for lem in self.lems :
307             deff = self.getlemuceseff(lem)
308             ucesk = deff.keys()
309             gram = self.lems[lem].gram
310             if gram in dtype :
311                 dtype[gram] = [i + j for i, j in zip(dtype[gram], [sum([deff[uce] for uce in et.intersection(ucesk)]) for et in etuces])]
312             else :
313                 dtype[gram] = [sum([deff[uce] for uce in et.intersection(ucesk)]) for et in etuces]
314         tabout = [[gram] + dtype[gram] for gram in dtype]
315         tabout.insert(0, [''] + etoiles)
316         return tabout
317
318     def make_uceactsize(self, actives) :
319         res = self.getalluces()
320         ucesize = {}
321         for lem in actives: 
322             deff = self.getlemuceseff(lem)
323             for uce in deff :
324                 ucesize[uce] = ucesize.get(uce, 0) + 1
325         return ucesize
326
327     def make_uc(self, actives, lim1, lim2) :
328         uceactsize = self.make_uceactsize(actives)
329         last1 = 0
330         last2 = 0
331         uc1 = [[]]
332         uc2 = [[]]
333         lastpara = 0
334         for uce in [uce for uci in self.ucis for uce in uci.uces] :
335             if uce.para == lastpara :
336                 if last1 <= lim1 :
337                     last1 += uceactsize.get(uce.ident,0)
338                     uc1[-1].append(uce.ident)
339                 else :
340                     uc1.append([uce.ident])
341                     last1 = 0
342                 if last2 <= lim2 :
343                     last2 += uceactsize.get(uce.ident, 0)
344                     uc2[-1].append(uce.ident)
345                 else :
346                     uc2.append([uce.ident])
347                     last2 = 0
348             else :
349                 last1 = uceactsize.get(uce.ident, 0)
350                 last2 = uceactsize.get(uce.ident, 0)
351                 lastpara = uce.para
352                 uc1.append([uce.ident])
353                 uc2.append([uce.ident])
354         return uc1, uc2
355
356     def make_and_write_sparse_matrix_from_uc(self, actives, sizeuc1, sizeuc2, uc1out, uc2out, listuce1out, listuce2out) :
357         uc1, uc2 = self.make_uc(actives, sizeuc1, sizeuc2)
358         log.info('taille uc1 : %i - taille uc2 : %i' % (len(uc1), len(uc2)))
359         self.write_ucmatrix(uc1, actives, uc1out)
360         self.write_ucmatrix(uc2, actives, uc2out)
361         listuce1 = [['uce', 'uc']] + [[`uce`, `i`] for i, ucl in enumerate(uc1) for uce in ucl]
362         listuce2 = [['uce', 'uc']] + [[`uce`, `i`] for i, ucl in enumerate(uc2) for uce in ucl]
363         with open(listuce1out, 'w') as f :
364             f.write('\n'.join([';'.join(line) for line in listuce1]))
365         with open(listuce2out, 'w') as f :
366             f.write('\n'.join([';'.join(line) for line in listuce2]))
367         return len(uc1), len(uc2)
368
369     def write_ucmatrix(self, uc, actives, fileout) :
370         log.info('write uc matrix %s' % fileout)
371         uces_uc = dict([[uce, i] for i, ucl in enumerate(uc) for uce in ucl])
372         deja_la = {}
373         nbl = 0
374         with open(fileout + '~', 'w+') as f :
375             for i, lem in enumerate(actives) :
376                 for uce in self.getlemuces(lem):
377                     if (uces_uc[uce], i) not in deja_la :
378                         nbl += 1
379                         f.write(''.join([' '.join([`uces_uc[uce]+1`,`i+1`,`1`]),'\n']))
380                         deja_la[(uces_uc[uce], i)] = 0
381             f.seek(0)
382             with open(fileout, 'w') as ffin :        
383                 ffin.write("%%%%MatrixMarket matrix coordinate integer general\n%i %i %i\n" % (len(uc), len(actives), nbl))
384                 for line in f :
385                     ffin.write(line)
386         os.remove(fileout + '~')
387         del(deja_la)
388
389     def export_corpus(self, outf) :
390         #outf = 'export_corpus.txt'
391         self.make_iduces()
392         res = self.getalluces()
393         self.make_iduces()
394         actuci = ''
395         actpara = False
396         with open(outf,'w') as f :
397             for uce in res :
398                 if self.iduces[uce[0]].uci == actuci and self.iduces[uce[0]].para == actpara :
399                     f.write(uce[1].encode(self.parametres['syscoding']) + '\n')
400                 elif self.iduces[uce[0]].uci != actuci :
401                     actuci = self.iduces[uce[0]].uci
402                     if self.ucis[self.iduces[uce[0]].uci].paras == [] :
403                         actpara = self.iduces[uce[0]].para
404                         f.write('\n' + ' '.join(self.ucis[self.iduces[uce[0]].uci].etoiles).encode(self.parametres['syscoding']) + '\n' + uce[1].encode(self.parametres['syscoding']) + '\n')
405                     else :
406                         ident = 0
407                         actpara = self.iduces[uce[0]].para
408                         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')
409                 elif self.iduces[uce[0]].para != actpara :
410                     actpara = self.iduces[uce[0]].para
411                     ident += 1
412                     f.write('\n'.join([self.ucis[self.iduces[uce[0]].uci].paras[ident].encode(self.parametres['syscoding']), uce[1].encode(self.parametres['syscoding'])]) + '\n')
413     
414     def export_corpus_classes(self, outf, alc = True, lem = False) :
415         ucecl = {}
416         for i, lc in enumerate(self.lc) :
417             for uce in lc : 
418                 ucecl[uce] = i + 1
419         for uce in self.lc0 :
420             ucecl[uce] = 0
421         res = self.getalluces()
422         self.make_iduces()
423         with open(outf, 'w') as f :
424             for uce in res :
425                 guce = uce[1]
426                 actuci = self.iduces[uce[0]].uci
427                 if lem :
428                     guce = ' '.join([self.formes[forme].lem for forme in guce.split()])
429                 if alc :
430                     etline = ' '.join(self.ucis[self.iduces[uce[0]].uci].etoiles + ['*classe_%i' % ucecl[uce[0]]])
431                 else :
432                     etline = ' '.join(['<' + '='.join(et.split('_')) + '>' for et in self.ucis[self.iduces[uce[0]].uci].etoiles[1:]])
433                 f.write(etline.encode(self.parametres['syscoding']) + '\n')
434                 f.write(guce.encode(self.parametres['syscoding']) + '\n\n')
435
436     def make_and_write_sparse_matrix_from_uces(self, actives, outfile, listuce = False) :
437         log.info('make_and_write_sparse_matrix_from_uces %s' % outfile)
438         nbl = 0
439         with open(outfile + '~', 'w+') as f :
440             for i, lem in enumerate(actives) :
441                 for uce in sorted(self.getlemuces(lem)) :
442                     nbl += 1
443                     f.write(''.join([' '.join([`uce+1`, `i+1`,`1`]),'\n']))
444             f.seek(0)
445             with open(outfile, 'w') as ffin :        
446                 ffin.write("%%%%MatrixMarket matrix coordinate integer general\n%i %i %i\n" % (self.getucenb(), len(actives), nbl))
447                 for line in f :
448                     ffin.write(line)
449         os.remove(outfile + '~')
450         if listuce :
451             with open(listuce, 'w') as f :
452                 f.write('\n'.join(['uce;uc'] + [';'.join([`i`,`i`]) for i in range(0, self.getucenb())]))
453
454     def make_and_write_sparse_matrix_from_uci(self, actives, outfile, listuci = False) :
455         log.info('make_and_write_sparse_matrix_from_ucis %s' % outfile)
456         nbl = 0
457         with open(outfile + '~', 'w+') as f :
458             for i, lem in enumerate(actives) :
459                 for uci in sorted(self.getlemucis(lem)) :
460                     nbl += 1
461                     f.write(''.join([' '.join([`uci+1`, `i+1`,`1`]),'\n']))
462             f.seek(0)
463             with open(outfile, 'w') as ffin :        
464                 ffin.write("%%%%MatrixMarket matrix coordinate integer general\n%i %i %i\n" % (self.getucinb(), len(actives), nbl))
465                 for line in f :
466                     ffin.write(line)
467         os.remove(outfile + '~')
468         if listuci :
469             with open(listuci, 'w') as f :
470                 f.write('\n'.join(['uci;uc'] + [';'.join([`i`,`i`]) for i in range(0, self.getucinb())]))
471                     
472     def make_and_write_sparse_matrix_from_classe(self, actives, uces, outfile) :
473         log.info('make_and_write_sparse_matrix_from_classe %s' % outfile)
474         nbl = 0
475         duces = dict([[uce, i] for i, uce in enumerate(uces)])
476         with open(outfile + '~', 'w+') as f :
477             for i, lem in enumerate(actives) :
478                 uces_ok = list(set(self.getlemuces(lem)).intersection(uces))
479                 for uce in uces_ok :
480                     f.write(''.join([' '.join([`duces[uce]+1`,`i+1`,`1`]),'\n']))
481             f.seek(0)
482             with open(outfile, 'w') as ffin :        
483                 ffin.write("%%%%MatrixMarket matrix coordinate integer general\n%i %i %i\n" % (self.getucenb(), len(actives), nbl))
484                 for line in f :
485                     ffin.write(line)
486         os.remove(outfile + '~')
487     
488     def make_table_with_classe(self, uces, list_act) :
489         table_uce = [[0 for val in list_act] for line in range(0,len(uces))]
490         uces = dict([[uce, i] for i, uce in enumerate(uces)])
491         for i, lem in enumerate(list_act) :
492             lemuces = list(set(self.getlemuces(lem)).intersection(uces))
493             for uce in lemuces :
494                 table_uce[uces[uce]][i] = 1
495         table_uce.insert(0, list_act)
496         return table_uce      
497
498     def parse_active(self, gramact, gramsup = None) :
499         log.info('parse actives')
500         for lem in self.lems :
501             if lem.startswith('_') and lem.endswith('_') :
502                 self.lems[lem].act = 2
503             elif self.lems[lem].gram in gramact :
504                 self.lems[lem].act = 1
505             elif gramsup is not None :
506                 if self.lems[lem].gram in gramsup :
507                     self.lems[lem].act = 2
508                 else :
509                     self.lems[lem].act =  0
510             else :
511                 self.lems[lem].act = 2
512
513     def make_actives_limit(self, limit, key = 1) :
514         if self.idformes is None :
515             self.make_idformes()
516         return [lem for lem in self.lems if self.getlemeff(lem) >= limit and self.lems[lem].act == key]
517     
518     def make_actives_nb(self, nbmax, key) :
519         log.info('make_actives_nb : %i - %i' % (nbmax,key))
520         if self.idformes is None :
521             self.make_idformes()
522         allactives = [[self.lems[lem].freq, lem] for lem in self.lems if self.lems[lem].act == key and self.lems[lem].freq >= 3]
523         self.activenb = len(allactives)
524         allactives = sorted(allactives, reverse = True)
525         if len(allactives) <= nbmax :
526             log.info('nb = %i - eff min = %i ' % (len(allactives), allactives[-1][0]))
527             return [val[1] for val in allactives], allactives[-1][0]
528         else :
529             effs = [val[0] for val in allactives]
530             if effs.count(effs[nbmax - 1]) > 1 :
531                 lim = effs[nbmax - 1] + 1
532                 nok = True
533                 while nok :
534                     try :
535                         stop = effs.index(lim)
536                         nok = False
537                     except ValueError:
538                         lim -= 1
539             else :
540                 stop = nbmax - 1
541                 lim = effs[stop]
542         log.info('nb actives = %i - eff min = %i ' % (stop + 1, lim))
543         return [val[1] for val in allactives[0:stop + 1]], lim
544
545     def make_and_write_profile(self, actives, ucecl, fileout) :
546         log.info('formes/classes')
547         tab = [[lem] + [len(set(self.getlemuces(lem)).intersection(classe)) for classe in ucecl] for lem in actives]
548         tab = [[line[0]] + [`val` for val in line[1:]] for line in tab if sum(line[1:]) >= 3]
549         with open(fileout, 'w') as f :
550             f.write('\n'.join([';'.join(line) for line in tab]).encode(self.parametres['syscoding']))
551
552     def make_etoiles(self) :
553         etoiles = set([])
554         for uci in self.ucis :
555             etoiles.update(uci.etoiles[1:])
556         return list(etoiles)
557
558     def make_etoiles_dict(self) :
559         etoiles = [et for uci in self.ucis for et in uci.etoiles[1:]]
560         det = {}
561         for etoile in etoiles :
562             et = etoile.split('_')
563             if et[0] in det :
564                 try :
565                     endet = '_'.join(et[1:])
566                     if etoile in det[et[0]] :
567                         det[et[0]][etoile] += 1
568                     else :
569                         det[et[0]][etoile] = 1
570                 except IndexError :
571                     det[et[0]] += 1
572             else :
573                 try :
574                     endet = '_'.join(et[1:])
575                     det[et[0]] = {etoile :1}
576                 except IndexError :
577                     det[et[0]] = 1
578         return det
579
580     def make_etline(self, listet) :
581         etuces = [[] for et in listet]
582         for uci in self.ucis :
583             get = list(set(uci.etoiles).intersection(listet))
584             if len(get) > 1 :
585                 return '2 variables sur la meme ligne'
586             elif get != [] :
587                 etuces[listet.index(get[0])] += [uce.ident for uce in uci.uces]
588         return etuces
589
590     def make_and_write_profile_et(self, ucecl, fileout) :
591         log.info('etoiles/classes')
592         etoileuces = self.getetoileuces()
593         etoileuces = dict([[et, etoileuces[et]] for et in etoileuces if len(etoileuces[et]) > 1])
594         with open(fileout, 'w') as f :
595             f.write('\n'.join([';'.join([et] + [`len(set(etoileuces[et]).intersection(classe))` for classe in ucecl]) for et in etoileuces]).encode(self.parametres['syscoding']))
596         #etoiles = self.make_etoiles()
597         #with open(fileout, 'w') as f :
598         #    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']))
599
600     def make_colored_corpus(self) :
601         ucecl = {}
602         for i, lc in enumerate(self.lc) :
603             for uce in lc : 
604                 ucecl[uce] = i + 1
605         for uce in self.lc0 :
606             ucecl[uce] = 0
607         color = ['black'] + colors[len(self.lc) - 1]        
608         txt = '''<html>
609         <meta http-equiv="content-Type" content="text/html; charset=%s" />
610         <body>
611 ''' % sys.getdefaultencoding()
612         res = self.getalluces()
613         self.make_iduces()
614         actuci = ''
615         actpara = False
616         for uce in res :
617             if self.iduces[uce[0]].uci != actuci :
618                 actuci = self.iduces[uce[0]].uci
619                 txt += '<br><hr>' + ' '.join(self.ucis[self.iduces[uce[0]].uci].etoiles) + '<br><br>'
620                 txt += '<font color="%s">' % (color[ucecl[uce[0]]]) + uce[1] + '</font><br><br>'
621             else :
622                 txt += '<font color="%s">' % (color[ucecl[uce[0]]]) + uce[1] + '</font><br><br>'
623         return txt + '\n</body></html>'
624
625     def count_from_list(self, l, d) :
626         for val in l :
627             if val in d :
628                 d[val] += 1
629             else :
630                 d[val] = 1
631         return d
632
633     def count_from_list_cl(self, l, d, a, clnb) :
634         for val in l :
635             if val in d :
636                 d[val][a] += 1
637             else :
638                 d[val] = [0] * clnb
639                 d[val][a] = 1
640         return d
641
642     def find_segments(self, taille_segment, taille_limite) :
643         d = {}
644         for uce in self.getalluces() :
645             uce = uce[1].split()
646             d = self.count_from_list([' '.join(uce[i:i+taille_segment]) for i in range(len(uce)-(taille_segment - 1))], d)
647         l = [[d[val], val] for val in d if d[val] >= 3]
648         del(d)
649         l.sort()
650         if len(l) > taille_limite :
651             l = l[-taille_limite:]
652         return l
653
654     def find_segments_in_classe(self, list_uce, taille_segment, taille_limite):
655         d={}
656         for uce in self.getconcorde(list_uce) :
657             uce = uce[1].split()
658             d =self.count_from_list([' '.join(uce[i:i+taille_segment]) for i in range(len(uce)-(taille_segment - 1))], d)
659         l = [[d[val], val, taille_segment] for val in d if d[val] >= 3]
660         del(d)
661         l.sort()
662         if len(l) > taille_limite :
663             l = l[-taille_limite:]
664         return l
665             
666     def make_segments_profile(self, fileout, lenmin = 3, lenmax = 10, effmin = 50, lem = False) :
667         d = {}
668         for b, classe in enumerate(self.lc) :
669             for uce in self.getconcorde(classe) :
670                 uce = uce[1].split()
671                 if lem :
672                     uce = [self.formes[forme].lem for forme in uce]
673                 for taille_segment in range(lenmin,lenmax) :
674                     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))
675         result = [[seg] + [str(val) for val in d[seg]] for seg in d if sum(d[seg]) >= effmin]
676         with open(fileout, 'w') as f :
677             f.write('\n'.join([';'.join(line) for line in result]))
678     
679     def make_proftype(self, outf) :
680         res = {}
681         for lem in self.lems :
682             gram = self.lems[lem].gram
683             if not gram in res :
684                 res[gram] = [0 for val in self.lc]
685             lemuceeff = self.getlemuceseff(lem)
686             for i, classe in enumerate(self.lc) :
687                 concern = set(classe).intersection(lemuceeff.keys())
688                 res[gram][i] += sum([lemuceeff[uce] for uce in concern])
689         res = [[gram] + [`val` for val in res[gram]] for gram in res]
690         res.sort()
691         with open(outf, 'w') as f :
692             f.write('\n'.join([';'.join(line) for line in res]).encode(self.parametres['syscoding']))
693
694
695     def make_ucecl_from_R(self, filein) :
696         with open(filein, 'rU') as f :
697             c = f.readlines()
698         c.pop(0)
699         self.lc = []
700         for line in c :
701             line = line.replace('\n', '').replace('"', '').split(';')
702             self.lc.append([int(line[0]) - 1, int(line[1])])
703         classesl = [val[1] for val in self.lc]
704         clnb = max(classesl)
705         self.lc = sorted(self.lc, key=itemgetter(1))
706         self.lc = [[uce[0] for uce in self.lc if uce[1] == i] for i in range(clnb+1)]
707         self.lc0 = self.lc.pop(0)
708         #return ucecl
709     
710     def get_stat_by_cluster(self, outf) :
711         log.info('get_stat_by_cluster')
712         t1 = time()
713         occurrences = dict([[i + 1, 0] for i in range(len(self.lc))])
714         formescl = dict([[i + 1, 0] for i in range(len(self.lc))])
715         hapaxcl = dict([[i + 1, 0] for i in range(len(self.lc))])
716         lenclasses = dict([[i+1,len(cl)] for i, cl in enumerate(self.lc)])
717         sets = [set(cl) for cl in self.lc]
718         for forme in self.formes :
719             formeuceeff = self.getformeuceseff(forme)
720             for i, classe in enumerate(self.lc) :
721                 concern = sets[i].intersection(formeuceeff.keys())
722                 if len(concern) :
723                     occurrences[i+1] += sum([formeuceeff[uce] for uce in concern])
724                     formescl[i+1] += 1
725                     if self.formes[forme].freq == 1 :
726                         hapaxcl[i+1] += 1
727         toprint = '\n'.join([';'.join([`i`, `occurrences[i]`, `formescl[i]`, `hapaxcl[i]`, `lenclasses[i]`, `float(hapaxcl[i])/float(formescl[i])`]) for i in occurrences])
728         with open(outf, 'w') as f :
729             f.write(toprint)
730         log.info('%f' % (time() - t1))        
731
732     def gethapaxbyet(self, etoiles) :
733         hapaxuces = [self.getlemuces(forme)[0] for forme in self.lems if self.lems[forme].freq == 1]
734         hucesdict = {}
735         for uce in hapaxuces :
736             if uce in hucesdict :
737                 hucesdict[uce] += 1
738             else :
739                 hucesdict[uce] = 1
740         etuces = [[] for et in etoiles]
741         for uci in self.ucis :
742             get = list(set(uci.etoiles).intersection(etoiles))
743             if len(get) > 1 :
744                 return '2 variables sur la meme ligne'
745             elif get != [] :
746                 etuces[etoiles.index(get[0])] += [uce.ident for uce in uci.uces]
747         etuces = [set(val) for val in etuces]
748         return [sum([hucesdict[uce] for uce in list(etuce.intersection(hapaxuces))]) for etuce in etuces]
749
750     def gethapaxuces(self) :
751         hapaxuces = [self.getlemuces(forme)[0] for forme in self.lems if self.lems[forme].freq == 1]
752         hapax = [forme for forme in self.lems if self.lems[forme].freq == 1]
753         hucesdict = {}
754         for i,uce in enumerate(hapaxuces) :
755             if uce in hucesdict :
756                 hucesdict[uce][0] += 1
757                 hucesdict[uce][1].append(hapax[i])
758             else :
759                 hucesdict[uce] = [1,[hapax[i]]]
760         huces = {}
761         for uce in hucesdict :
762             if hucesdict[uce][0] in huces :
763                 huces[hucesdict[uce][0]].append(uce)
764             else :
765                 huces[hucesdict[uce][0]] = [uce]
766         huces = zip(huces, huces.values())
767         huces.sort(reverse=True)
768         txt = """
769         <html><body>
770         """
771         for nb in huces[0:4] :
772             txt += "<p><h2>%i hapax par uce</h2><p>\n" % nb[0]
773             for uce in nb[1] :
774                 res = self.getconcorde([uce])
775                 for row in res :
776                     ucetxt = ' ' + row[1] + ' '
777                     uceid = row[0]
778                 for hap in hucesdict[uce][1] :
779                     laforme = self.getforme([forme for forme in self.lems[hap].formes][0]).forme
780                     ucetxt = ucetxt.replace(' '+laforme+' ', ' <font color=red>'+laforme+'</font> ')
781                 txt += '<p><b>' + ' '.join(self.getetbyuceid(uceid)) + '</b></p>'
782                 txt += '<p>'+ucetxt+'</p>\n'
783         txt += """
784         </body></html>
785         """
786         with open('/tmp/testhapxuce.html','w') as f :
787             f.write(txt)
788
789
790 class MakeUciStat :
791     def __init__(self, corpus) :
792         ucinb = corpus.getucinb()
793         ucisize = corpus.getucisize()
794         ucimean = float(sum(ucisize))/float(ucinb)
795         detoile = corpus.make_etoiles_dict()
796         
797
798 class Uci :
799     def __init__(self, iduci, line, paraset = None) :
800         self.ident = iduci
801         self.etoiles = line.split()
802         self.uces = []
803         if paraset is not None :
804             self.paras = paraset.split()
805         else :
806             self.paras = []
807
808 class Uce :
809     def __init__(self, iduce, idpara, iduci) :
810         self.ident = iduce
811         self.para = idpara
812         self.uci = iduci
813
814 class Word :
815     def __init__(self, word, gramtype, idword, lem = None, freq = None) :
816         self.forme = word
817         self.lem = lem
818         self.gram = gramtype
819         self.ident = idword
820         self.act = 1
821         if freq is not None :
822             self.freq = freq
823         else :
824             self.freq = 1
825
826 class Lem :
827     def __init__(self, parent, forme) :
828         self.formes = {forme.ident : forme.freq}
829         self.gram = forme.gram
830         self.freq = forme.freq
831         self.act = forme.act
832
833     def add_forme(self, forme) :
834         self.formes[forme.ident] = forme.freq
835         self.freq += forme.freq
836
837 def decouperlist(chaine, longueur, longueurOptimale) :
838     """
839         on part du dernier caractère, et on recule jusqu'au début de la chaîne.
840         Si on trouve un '$', c'est fini.
841         Sinon, on cherche le meilleur candidat. C'est-à-dire le rapport poids/distance le plus important.
842     """
843     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]]
844     dsep = dict([[val[0],val[1]] for val in separateurs])
845     trouve = False                 # si on a trouvé un bon séparateur
846     iDecoupe = 0                # indice du caractere ou il faut decouper
847     
848     longueur = min(longueur, len(chaine) - 1)
849     chaineTravail = chaine[:longueur + 1]
850     nbCar = longueur
851     meilleur = ['', 0, 0]        # type, poids et position du meilleur separateur
852     
853     try :
854         indice = chaineTravail.index(u'$')
855         trouve = True
856         iDecoupe = indice - 1
857     except ValueError :
858         pass
859     if not trouve:
860         while nbCar >= 0:
861             caractere = chaineTravail[nbCar]
862             distance = abs(longueurOptimale - nbCar) + 1
863             meilleureDistance = abs(longueurOptimale - meilleur[2]) + 1
864             if caractere in dsep :
865                 if (float(dsep[caractere]) / distance) > (float(meilleur[1]) / meilleureDistance) :
866                     meilleur[0] = caractere
867                     meilleur[1] = dsep[caractere]
868                     meilleur[2] = nbCar
869                     trouve = True
870                     iDecoupe = nbCar
871             else :
872                 if (float(dsep[' ']) / distance) > (float(meilleur[1]) / meilleureDistance) :
873                     meilleur[0] = ' '
874                     meilleur[1] = dsep[' ']
875                     meilleur[2] = nbCar
876                     trouve = True
877                     iDecoupe = nbCar
878             nbCar = nbCar - 1
879     # si on a trouvé
880     if trouve:
881         #if meilleur[0] != ' ' :
882         #    fin = chaine[iDecoupe + 1:]
883         #    retour = chaineTravail[:iDecoupe]
884         #else :
885         fin = chaine[iDecoupe + 1:]
886         retour = chaineTravail[:iDecoupe + 1]
887         return len(retour) > 0, retour, fin
888     # si on a rien trouvé
889     return False, chaine, ''
890
891 def testetoile(line) :
892     return line.startswith(u'****')
893
894 def testint(line) :
895     return line[0:4].isdigit() and u'*' in line
896
897 def prep_txtlist(txt) :
898     return txt.split() + [u'$']
899
900 def prep_txtcharact(txt) :
901     return txt + u'$'
902
903 class BuildCorpus :
904     """
905     Class for building a corpus
906     """
907     def __init__(self, infile, parametres_corpus, lexique = None, expressions = None, dlg = None) :
908         log.info('begin building corpus...')
909         self.lexique = lexique
910         self.expressions = expressions
911         self.dlg = dlg
912         self.corpus = Corpus(self, parametres_corpus)
913         self.infile = infile
914         self.last = 0
915         self.lim = parametres_corpus.get('lim', 1000000)
916         self.encoding = parametres_corpus['encoding']
917         self.corpus.pathout = PathOut(filename = parametres_corpus['originalpath'], dirout = parametres_corpus['pathout'])
918         self.corpus.pathout.createdir(parametres_corpus['pathout'])
919         self.corpus.parametres['uuid'] = str(uuid4())
920         self.corpus.parametres['corpus_name'] = os.path.split(self.corpus.parametres['pathout'])[1]
921         self.corpus.parametres['type'] = 'corpus'
922         if self.corpus.parametres['keep_ponct'] :
923             self.ponctuation_espace = [' ', '']
924         else :
925             self.ponctuation_espace =  [' ','.', u'£$£', ';', '?', '!', ',', ':','']
926         self.cleans = []
927         self.tolist = self.corpus.parametres.get('tolist', 0)
928         self.buildcleans()
929         self.prep_makeuce()
930         #create database
931         self.connect()
932         self.dobuild()
933
934     def prep_makeuce(self) :
935         method = self.corpus.parametres.get('ucemethod', 0)
936         if method == 1 :
937             self.decouper = decouperlist
938             self.prep_txt = prep_txtlist
939             self.ucesize = self.corpus.parametres.get('ucesize', 40)
940         elif method == 0 :
941             self.decouper = decoupercharact
942             self.prep_txt = prep_txtcharact
943             self.ucesize = self.corpus.parametres.get('ucesize', 240)
944         log.info('method uce : %s' % method)
945
946     def dobuild(self) :    
947         t1 = time()
948         try :
949             self.read_corpus(self.infile)
950         except Warning, args :
951             log.info('pas kool %s' % args)
952             raise Warning
953         else :    
954             self.indexdb()
955             self.corpus.parametres['ira'] = self.corpus.pathout['Corpus.cira']
956             self.time = time() - t1
957             self.dofinish()
958             DoConf().makeoptions(['corpus'],[self.corpus.parametres], self.corpus.pathout['Corpus.cira'])
959             log.info('time : %f' % (time() - t1))
960
961     def connect(self) :
962         self.conn_f = sqlite3.connect(self.corpus.pathout['formes.db'])
963         self.cf = self.conn_f.cursor()
964         self.cf.execute('CREATE TABLE IF NOT EXISTS uces (id INTEGER, uces TEXT);')
965         self.cf.execute('CREATE TABLE IF NOT EXISTS eff (id INTEGER, eff TEXT);')
966         self.conn_f.commit()
967         self.cf = self.conn_f.cursor()
968         self.cf.execute('PRAGMA temp_store=MEMORY;')
969         self.cf.execute('PRAGMA journal_mode=MEMORY;')
970         self.cf.execute('PRAGMA  synchronous = OFF;')
971         self.cf.execute('begin')
972         self.conn = sqlite3.connect(self.corpus.pathout['uces.db'])
973         self.c = self.conn.cursor()
974         self.c.execute('CREATE TABLE IF NOT EXISTS uces (id INTEGER, uces TEXT);')
975         self.conn.commit()
976         self.c = self.conn.cursor()
977         self.c.execute('PRAGMA temp_store=MEMORY;')
978         self.c.execute('PRAGMA journal_mode=MEMORY;')
979         self.c.execute('PRAGMA  synchronous = OFF;')
980         self.c.execute('begin')
981
982     def indexdb(self) :
983         #commit index and close db
984         self.conn.commit()
985         self.conn_f.commit()
986         self.cf.execute('CREATE INDEX iduces ON uces (id);')
987         self.cf.execute('CREATE INDEX ideff ON eff (id);')
988         self.c.close()
989         self.cf.close()
990         #backup corpora
991         self.conn_corpus = sqlite3.connect(self.corpus.pathout['corpus.db'])
992         self.ccorpus = self.conn_corpus.cursor()
993         self.ccorpus.execute('CREATE TABLE IF NOT EXISTS etoiles (uci INTEGER, et TEXT, paras TEXT);')
994         self.ccorpus.execute('CREATE TABLE IF NOT EXISTS luces (uci INTEGER, para INTEGER, uce INTEGER);')
995         self.ccorpus.execute('CREATE TABLE IF NOT EXISTS formes (ident INTEGER, forme TEXT, lem TEXT, gram TEXT, freq INTEGER);')
996         self.conn_corpus.commit()
997         self.ccorpus = self.conn_corpus.cursor()
998         self.ccorpus.execute('PRAGMA temp_store=MEMORY;')
999         self.ccorpus.execute('PRAGMA journal_mode=MEMORY;')
1000         self.ccorpus.execute('PRAGMA  synchronous = OFF;')
1001         self.ccorpus.execute('begin')
1002         self.backup_corpus()
1003         self.ccorpus.execute('CREATE INDEX iduci ON luces (uci);')
1004         self.conn_corpus.commit()
1005         self.conn_corpus.close()
1006         #self.corpus.parametres['corpus_ira'] = self.corpus.pathout['corpus.cira']
1007
1008     def buildcleans(self) :
1009         if self.corpus.parametres.get('lower', 1) :
1010             self.cleans.append(self.dolower)
1011         if self.corpus.parametres.get('firstclean', 1) :
1012             self.cleans.append(self.firstclean)
1013         if self.corpus.parametres['charact'] :
1014             self.rule = self.corpus.parametres.get('keep_caract', u"^a-zA-Z0-9àÀâÂäÄáÁéÉèÈêÊëËìÌîÎïÏòÒôÔöÖùÙûÛüÜçÇßœŒ’ñ.:,;!?*'_")
1015             self.cleans.append(self.docharact)
1016         if self.corpus.parametres.get('expressions', 1) :
1017             self.cleans.append(self.make_expression)
1018         if self.corpus.parametres.get('apos', 1) :
1019             self.cleans.append(self.doapos)
1020         if self.corpus.parametres.get('tiret', 1):
1021             self.cleans.append(self.dotiret)
1022
1023     def make_expression(self,txt) :
1024          for expression in self.expressions:
1025             if expression in txt :
1026                 txt = txt.replace(expression, self.expressions[expression][0])
1027          return txt
1028     
1029     def dolower(self, txt) :
1030         return txt.lower()
1031
1032     def docharact(self, txt) :
1033         #rule = u"^a-zA-Z0-9àÀâÂäÄáÁéÉèÈêÊëËìÌîÎïÏòÒôÔöÖùÙûÛüÜçÇßœŒ’ñ.:,;!?*'_-"
1034         list_keep = u"[" + self.rule + "]+"
1035         return re.sub(list_keep, ' ', txt)
1036     
1037     def doapos(self, txt) :
1038         return txt.replace(u'\'', u' ')
1039
1040     def dotiret(self, txt) :
1041         return txt.replace(u'-', u' ')
1042
1043     def firstclean(self, txt) :
1044         txt = txt.replace(u'’',"'")
1045         txt = txt.replace(u'œ', u'oe')
1046         return txt.replace('...',u' £$£ ').replace('?',' ? ').replace('.',' . ').replace('!', ' ! ').replace(',',' , ').replace(';', ' ; ').replace(':',' : ').replace(u'…', ' £$£ ')
1047
1048     def make_cleans(self, txt) :
1049         for clean in self.cleans :
1050             txt = clean(txt)
1051         return txt
1052
1053     def backup_uce(self) :
1054         if self.corpus.idformesuces != {} :
1055             log.info('backup %i' % len(self.corpus.idformesuces))
1056             touce = [(`forme`, ' '.join([`val` for val in  self.corpus.idformesuces[forme].keys()])) for forme in self.corpus.idformesuces]
1057             toeff = [(`forme`, ' '.join([`val` for val in  self.corpus.idformesuces[forme].values()])) for forme in self.corpus.idformesuces]
1058             self.cf.executemany('INSERT INTO uces VALUES (?,?);', touce)
1059             self.cf.executemany('INSERT INTO eff VALUES (?,?);', toeff)
1060         self.corpus.idformesuces = {}        
1061         self.count = 1
1062
1063     def backup_corpus(self) :
1064         log.info('start backup corpus')
1065         t = time()
1066         for uci in self.corpus.ucis :
1067             self.ccorpus.execute('INSERT INTO etoiles VALUES (?,?,?);' ,(uci.ident,' '.join(uci.etoiles), ' '.join(uci.paras,)))
1068             for uce in uci.uces : 
1069                 self.ccorpus.execute('INSERT INTO luces VALUES (?,?,?);',(`uci.ident`,`uce.para`,`uce.ident`,))
1070         for forme in self.corpus.formes :
1071             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`,))
1072         log.info('%f' % (time() - t))
1073
1074     def dofinish(self) :
1075         self.corpus.parametres['date'] = datetime.datetime.now().ctime()
1076         minutes, seconds = divmod(self.time, 60)
1077         hours, minutes = divmod(minutes, 60)
1078         self.corpus.parametres['time'] = '%.0fh %.0fm %.0fs' % (hours, minutes, seconds)
1079         self.corpus.parametres['ucinb'] = self.corpus.getucinb()
1080         self.corpus.parametres['ucenb'] = self.corpus.getucenb()
1081         self.corpus.parametres['occurrences'] = self.corpus.gettotocc()
1082         self.corpus.parametres['formesnb'] = len(self.corpus.formes)
1083         hapaxnb = self.corpus.gethapaxnb()
1084         pourhapaxf = (float(hapaxnb) / len(self.corpus.formes)) * 100
1085         pourhapaxocc = (float(hapaxnb) / self.corpus.parametres['occurrences']) * 100
1086         self.corpus.parametres['hapax'] = '%i - %.2f %% des formes - %.2f %% des occurrences' % (hapaxnb, pourhapaxf, pourhapaxocc)
1087
1088
1089 class BuildFromAlceste(BuildCorpus) :
1090     def read_corpus(self, infile) :
1091         if self.dlg is not None :
1092             self.dlg.Pulse('textes : 0 - segments : 0')
1093         self.limitshow = 0
1094         self.count = 1
1095         if self.corpus.parametres['ucimark'] == 0 :
1096             self.testuci = testetoile
1097         elif  self.corpus.parametres['ucimark'] == 1 :
1098             self.testuci = testint
1099         txt = []
1100         iduci = -1
1101         idpara = -1
1102         iduce = -1
1103         try :
1104             with codecs.open(infile, 'r', self.encoding) as f :
1105                 for linenb, line in enumerate(f) :
1106                     line = line.rstrip('\n\r')
1107                     if self.testuci(line) :
1108                         iduci += 1
1109                         if txt != [] :
1110                             iduce, idpara = self.treattxt(txt, iduce, idpara, iduci - 1)
1111                             txt = []
1112                             self.corpus.ucis.append(Uci(iduci, line))
1113                         else :
1114                             if iduci > 0 :
1115                                 if self.corpus.ucis[-1].uces == [] :
1116                                     log.info(u'Empty text : %i' % linenb)
1117                                     iduci -= 1
1118                                     self.corpus.ucis.pop()
1119                                     #raise Exception("EmptyText %i" % linenb)
1120                             self.corpus.ucis.append(Uci(iduci, line))
1121                         if self.dlg is not None :
1122                             if not (iduci + 1) % 10 :
1123                                 self.dlg.Pulse('textes : %i - segments : %i' % (iduci + 1, iduce +1))
1124                     elif line.startswith(u'-*') :
1125                         if iduci != -1 :
1126                             if txt != [] :
1127                                 iduce, idpara = self.treattxt(txt, iduce, idpara, iduci)
1128                                 txt = []
1129                             idpara += 1
1130                             self.corpus.ucis[-1].paras.append(line.split()[0])
1131                         else :
1132                             raise Exception('paragrapheOT')
1133                     elif line.strip() != '' and iduci != -1 :
1134                         txt.append(line)
1135             if txt != [] and iduci != -1 :
1136                 iduce, idpara = self.treattxt(txt, iduce, idpara, iduci)
1137                 del(txt)
1138             else :
1139                 raise Exception("EmptyText")
1140             if iduci != -1  and iduce != -1:
1141                 self.backup_uce()
1142             else : 
1143                 log.info(_(u"No Text in corpora. Are you sure of the formatting ?"))
1144                 raise Exception('TextBeforeTextMark')
1145         except UnicodeDecodeError :
1146             raise Exception("CorpusEncoding")
1147
1148     def treattxt(self, txt, iduce, idpara, iduci) :
1149         if self.corpus.parametres.get('ucemethod', 0) == 2 and self.corpus.parametres['douce']:
1150             txt = 'laphrasepoursplitter'.join(txt)
1151             txt = self.make_cleans(txt)
1152             txt = ' '.join([val for val in txt.split() if val not in self.ponctuation_espace])
1153             ucetxt = txt.split('laphrasepoursplitter')
1154         else :
1155             txt = ' '.join(txt)
1156             txt = self.make_cleans(txt)
1157             ucetxt = self.make_uces(txt, self.corpus.parametres['douce'])
1158         if self.corpus.ucis[-1].paras == [] :
1159             idpara += 1
1160         for uce in ucetxt :
1161             iduce += 1
1162             self.corpus.ucis[-1].uces.append(Uce(iduce, idpara, iduci))
1163             self.c.execute('INSERT INTO uces VALUES(?,?);', (`iduce`,uce))
1164             if not self.tolist :
1165                 uce = uce.split()
1166             else :
1167                 uce = list(uce)
1168             for word in uce :
1169                 self.last += 1
1170                 self.corpus.add_word(word)
1171         log.debug(' '.join([`iduci`,`idpara`,`iduce`]))
1172         if self.last > self.lim :
1173             self.backup_uce()
1174             self.last = 0
1175         return iduce, idpara
1176
1177     def make_uces(self, txt, douce = True, keep_ponct = False) :
1178         txt = ' '.join(txt.split())
1179         if douce :
1180             out = []
1181             reste, texte_uce, suite = self.decouper(self.prep_txt(txt), self.ucesize + 15, self.ucesize)
1182             while reste :
1183                 uce = ' '.join([val for val in texte_uce if val not in self.ponctuation_espace])
1184                 if uce != '' :
1185                     out.append(uce)
1186                 reste, texte_uce, suite = self.decouper(suite, self.ucesize + 15, self.ucesize)
1187             uce = ' '.join([val for val in texte_uce if val not in self.ponctuation_espace])
1188             if uce != '' : 
1189                 out.append(uce)
1190             return out
1191         else :
1192             return [' '.join([val for val in txt.split() if val not in self.ponctuation_espace])]
1193
1194 #decouper (list_sep)
1195 #make_uces (decouper)
1196 #treat_txt (make_uces)
1197 #read (treat_txt)
1198
1199 class Builder :
1200     def __init__(self, parent, dlg = None) :
1201         self.parent = parent
1202         self.dlg = dlg
1203         parametres = DoConf(os.path.join(self.parent.UserConfigPath,'corpus.cfg')).getoptions('corpus')
1204         parametres['pathout'] = PathOut(parent.filename, 'corpus').mkdirout()
1205         dial = CorpusPref(parent, parametres)
1206         dial.CenterOnParent()
1207         dial.txtpath.SetLabel(parent.filename)
1208         #dial.repout_choices.SetValue(parametres['pathout'])
1209         self.res = dial.ShowModal()
1210         if self.res == 5100 :
1211             parametres = dial.doparametres()
1212             parametres['originalpath'] = parent.filename
1213             PathOut().createdir(parametres['pathout'])
1214             ReadLexique(self.parent, lang = parametres['lang'])
1215             self.parent.expressions = ReadDicoAsDico(self.parent.DictPath.get(parametres['lang']+'_exp', 'french_exp'))
1216             self.parametres = parametres
1217         else :
1218             if self.dlg is not None :
1219                 self.dlg.Destroy()
1220         dial.Destroy()
1221
1222     def doanalyse(self) :
1223         return BuildFromAlceste(self.parent.filename, self.parametres, self.parent.lexique, self.parent.expressions, dlg = self.dlg).corpus
1224
1225
1226 if __name__ == '__main__' :
1227     t1 = time()
1228     parametres = {'formesdb':'formes.db', 'ucesdb': 'uces.db', 'corpusdb' : 'corpus.db', 'syscoding' : 'utf-8', 'encoding' : encoding}
1229     intro = BuildCorpus(infile, parametres)#, tar_in, tar_infouce)#, tar_formes)
1230     print time() - t1