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