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