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