tools
[iramuteq] / analysetxt.py
1 # -*- coding: utf-8 -*-
2 #Author: Pierre Ratinaud
3 #from corpusNG import Corpus
4 import logging
5 from chemins import PathOut, ChdTxtPathOut
6 from functions import exec_rcode, check_Rresult, DoConf, print_liste
7 from time import time, sleep
8 from uuid import uuid4
9 import os
10 #ALCESTE
11 from PrintRScript import RchdTxt, AlcesteTxtProf
12 from OptionAlceste import OptionAlc 
13 from layout import PrintRapport
14 from openanalyse import OpenAnalyse
15 from time import time
16 ######################################
17 print '#######LOGGING TEST###########'
18 log = logging.getLogger('iramuteq.analyse')
19 #formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
20 #ch = logging.StreamHandler()
21 #ch.setFormatter(formatter)
22 #log.addHandler(ch)
23 #log.setLevel(logging.INFO)
24 #######################################
25
26 #def make_ucecl_from_R(filein) :
27 #    with open(filein, 'rU') as f :
28 #        c = f.readlines()
29 #    c.pop(0)
30 #    ucecl = []
31 #    for line in c :
32 #        line = line.replace('\n', '').replace('"', '').split(';')
33 #        ucecl.append([int(line[0]) - 1, int(line[1])])
34 #    classesl = [val[1] for val in ucecl]
35 #    clnb = max(classesl)
36 #    ucecl = sorted(ucecl, key=itemgetter(1))
37 #    ucecl = [[uce[0] for uce in ucecl if uce[1] == i] for i in range(clnb+1)]
38 #    return ucecl
39 #
40 #def make_lc(self, uces, classes, clnb) :    
41 #    self.lc = [[] for classe in range(0,clnb)]
42 #    for i in range(0,clnb):
43 #        self.lc[i] = [uce for j, uce in enumerate(uces) if i+1 == classes[j]]
44 #    self.lc0 = [uce for j, uce in enumerate(uces) if 0 == classes[j]]
45
46
47 class AnalyseText :
48     def __init__(self, ira, corpus, parametres = None, dlg = False) :
49         self.corpus = corpus
50         self.ira = ira
51         self.parent = ira
52         self.dlg = dlg
53         self.dialok = True
54         self.parametres = parametres
55         self.val = False
56         if not 'pathout' in self.parametres :
57             self.pathout = PathOut(corpus.parametres['originalpath'], analyse_type = parametres['type'], dirout = corpus.parametres['pathout'])
58         else :
59             self.pathout = PathOut(filename = corpus.parametres['originalpath'], dirout = self.parametres['pathout'], analyse_type = self.parametres['name'])
60         self.parametres = self.make_config(parametres)
61         log.info(self.pathout.dirout)
62         if self.parametres is not None :
63             self.keys = DoConf(self.ira.ConfigPath['key']).getoptions()
64             gramact = [k for k in keys if keys[k] == 1]
65             gramsup = [k for k in keys if keys[k] == 2]
66             #FIXME
67             if not 'lem' in self.parametres :
68                 self.parametres['lem'] = 1
69             self.parametres['pathout'] = self.pathout.mkdirout()
70             self.pathout = PathOut(dirout = self.parametres['pathout'])
71             self.pathout.createdir(self.parametres['pathout'])
72             self.parametres['corpus'] = self.corpus.parametres['uuid']
73             self.parametres['uuid'] = str(uuid4())
74             self.parametres['name'] = os.path.split(self.parametres['pathout'])[1]
75             self.parametres['type'] = parametres['type']
76             self.parametres['encoding'] = self.ira.syscoding
77             self.t1 = time()
78             #if self.corpus.lems is None :
79             self.corpus.make_lems(lem = self.parametres['lem'])
80             corpus.parse_active(gramact, gramsup)
81             result_analyse = self.doanalyse()
82             if result_analyse is None :
83                  self.time = time() - self.t1
84                  minutes, seconds = divmod(self.time, 60)
85                  hours, minutes = divmod(minutes, 60)            
86                  self.parametres['time'] = '%.0fh %.0fm %.0fs' % (hours, minutes, seconds)
87                  self.parametres['ira'] = self.pathout['Analyse.ira']
88                  DoConf().makeoptions([self.parametres['type']], [self.parametres], self.pathout['Analyse.ira'])
89                  self.ira.history.add(self.parametres)
90                  if dlg :
91                      dlg.Destroy()
92                      OpenAnalyse(self.parent, self.parametres['ira'])
93                      self.ira.tree.AddAnalyse(self.parametres)
94                      self.val = 5100
95             else :
96                  self.val = False
97                  if dlg :
98                      dlg.Destroy()
99         else :
100             if dlg :
101                 dlg.Destroy()
102             self.val = False
103
104     def doanalyse(self) :
105         pass
106
107     def make_config(self, config) :
108         if config is not None :
109             if not self.dlg : 
110                 return config
111             else :
112                 return self.preferences()
113
114     def readconfig(self, config) :
115         return config
116
117     def preferences(self) :
118         return {}
119
120     def printRscript(self) :
121         pass
122
123     def doR(self, Rscript, wait = False, dlg = None, message = '') :
124         log.info('R code...')
125         pid = exec_rcode(self.ira.RPath, Rscript, wait = wait)
126         while pid.poll() is None :
127             if dlg is not None :
128                 self.dlg.Pulse(message)
129                 sleep(0.2)
130             else :
131                 sleep(0.2)
132         return check_Rresult(self.ira, pid)
133
134
135
136 class Alceste(AnalyseText) :
137     def doanalyse(self) :
138         #self.pathout = PathOut(self.corpus.parametres['filename'], 'alceste')
139         self.parametres['type'] = 'alceste'
140         self.pathout.basefiles(ChdTxtPathOut)
141         self.actives, lim = self.corpus.make_actives_nb(self.parametres['max_actives'], 1)
142         self.parametres['eff_min_forme'] = lim
143         self.parametres['nbactives'] = len(self.actives)
144         if self.parametres['classif_mode'] == 0 :
145             lenuc1, lenuc2 = self.corpus.make_and_write_sparse_matrix_from_uc(self.actives, self.parametres['tailleuc1'], self.parametres['tailleuc2'], self.pathout['TableUc1'], self.pathout['TableUc2'], self.pathout['listeuce1'], self.pathout['listeuce2'])
146             self.parametres['lenuc1'] = lenuc1
147             self.parametres['lenuc2'] = lenuc2
148         elif self.parametres['classif_mode'] == 1 :
149             self.corpus.make_and_write_sparse_matrix_from_uces(self.actives, self.pathout['TableUc1'], self.pathout['listeuce1'])
150         elif self.parametres['classif_mode'] == 2 :
151             self.corpus.make_and_write_sparse_matrix_from_uci(self.actives, self.pathout['TableUc1'], self.pathout['listeuce1'])
152         Rscript = self.printRscript()
153         self.doR(Rscript, dlg = self.dlg, message = 'CHD...')
154         #self.lc = make_ucecl_from_R(self.pathout['uce'])
155         #self.lc0 = self.lc.pop(0)
156         self.corpus.make_ucecl_from_R(self.pathout['uce'])
157         self.corpus.make_and_write_profile(self.actives, self.corpus.lc, self.pathout['Contout'])
158         self.sup, lim = self.corpus.make_actives_nb(self.parametres['max_actives'], 2)
159         self.corpus.make_and_write_profile(self.sup, self.corpus.lc, self.pathout['ContSupOut'])
160         self.corpus.make_and_write_profile_et(self.corpus.lc, self.pathout['ContEtOut'])
161         self.clnb = len(self.corpus.lc)
162         self.parametres['clnb'] = self.clnb
163         Rscript = self.printRscript2()
164         self.doR(Rscript, dlg = self.dlg, message = 'profils et A.F.C. ...')
165         self.time = time() - self.t1
166         minutes, seconds = divmod(self.time, 60)
167         hours, minutes = divmod(minutes, 60)            
168         self.parametres['time'] = '%.0fh %.0fm %.0fs' % (hours, minutes, seconds)
169         self.print_graph_files()
170
171     def preferences(self) :
172         parametres = DoConf(self.parent.ConfigPath['alceste']).getoptions('ALCESTE')
173         parametres['corpus'] = self.corpus
174         parametres['pathout'] = self.pathout
175         self.dial = OptionAlc(self.parent, parametres)
176         self.dial.CenterOnParent()
177         self.dialok = self.dial.ShowModal()
178         if self.dialok == 5100 :
179             if self.dial.radio_1.GetSelection() == 0 :
180                 lem = 1
181             else :
182                 lem = 0
183             parametres['lem'] = lem
184             parametres['classif_mode'] = self.dial.radio_box_2.GetSelection()
185             parametres['tailleuc1'] = self.dial.spin_ctrl_1.GetValue()
186             parametres['tailleuc2'] = self.dial.spin_ctrl_2.GetValue()
187             parametres['mincl'] = self.dial.spin_ctrl_4.GetValue()
188             parametres['minforme'] = self.dial.spin_ctrl_5.GetValue()
189             parametres['nbcl_p1'] = self.dial.spin_nbcl.GetValue()
190             parametres['max_actives'] = self.dial.spin_max_actives.GetValue()
191             parametres['corpus'] = ''
192             parametres['pathout'] = self.pathout.dirout
193             for val in parametres :
194                 print val, parametres[val]
195             DoConf(self.parent.ConfigPath['alceste']).makeoptions(['ALCESTE'], [parametres])
196             self.dial.Destroy()
197             return parametres
198         else :
199             self.dial.Destroy()
200             return None
201
202     def printRscript(self) :
203         RchdTxt(self.pathout, self.parent.RscriptsPath, self.parametres['mincl'], self.parametres['classif_mode'], nbt = self.parametres['nbcl_p1'] - 1, libsvdc = self.parent.pref.getboolean('iramuteq','libsvdc'), libsvdc_path = self.parent.pref.get('iramuteq','libsvdc_path'), R_max_mem = False)
204         return self.pathout['Rchdtxt']
205
206     def printRscript2(self) :
207         AlcesteTxtProf(self.pathout, self.parent.RscriptsPath, self.clnb, 0.9)
208         return self.pathout['RTxtProfGraph']
209
210     def print_graph_files(self) :
211         mess_afc = u"La position des points n'est peut être pas exacte"
212         afc_graph_list = [[os.path.basename(self.pathout['AFC2DL_OUT']), u'Variables actives - coordonnées - 30 points par classes - facteurs 1 / 2 - %s' % mess_afc],
213                       [os.path.basename(self.pathout['AFC2DSL_OUT']), u'variables supplémentaires - coordonnées - 30 points par classes - facteurs 1 / 2 - %s' % mess_afc],
214                       [os.path.basename(self.pathout['AFC2DEL_OUT']), u'Variables illustratives - Coordonnées - 30 points par classes - facteur 1 / 2 - %s' % mess_afc],
215                       [os.path.basename(self.pathout['AFC2DCL_OUT']), u'Classes - Coordonnées - facteur 1 / 2']]
216                       #[os.path.basename(self.pathout['AFC2DCoul']), u'Variables actives - Corrélation - facteur 1 / 2'],
217                       #[os.path.basename(self.pathout['AFC2DCoulSup']), u'Variables supplémentaires - Corrélation - facteur 1 / 2'],
218                       #[os.path.basename(self.pathout['AFC2DCoulEt']), u'Variables illustratives - Corrélations - facteur 1 / 2'],
219                       #[os.path.basename(self.pathout['AFC2DCoulCl']), u'Classes - Corrélations - facteurs 1 / 2'],]
220         chd_graph_list = [[os.path.basename(self.pathout['dendro1']), u'dendrogramme à partir de chd1']]
221         if self.parametres['classif_mode'] == 0 :
222             chd_graph_list.append([os.path.basename(self.pathout['dendro2']), u'dendrogramme à partir de chd2'])
223         chd_graph_list.append([os.path.basename(self.pathout['arbre1']), u'chd1'])
224         if self.parametres['classif_mode'] == 0 :
225             chd_graph_list.append([os.path.basename(self.pathout['arbre2']), u'chd2'])       
226         print_liste(self.pathout['liste_graph_afc'],afc_graph_list)
227         print_liste(self.pathout['liste_graph_chd'],chd_graph_list)
228         PrintRapport(self, self.corpus, self.parametres)
229
230
231 keys = {'art_def' : 2,
232         'pre' : 2,
233         'adj_dem' : 2,
234         'ono' : 2,
235         'pro_per' : 2,
236         'ver_sup' : 2,
237         'adv' : 1,
238         'ver' : 1,
239         'adj_ind' : 2,
240         'adj_pos' : 2,
241         'aux' : 2,
242         'adj_int' : 2,
243         'pro_ind' : 2,
244         'adj' : 1,
245         'pro_dem' : 2,
246         'nom' : 1,
247         'art_ind' : 2,
248         'pro_pos' : 2,
249         'nom_sup' : 2,
250         'adv_sup' : 2,
251         'adj_sup' : 2,
252         'adj_num' : 2,
253         'pro_rel' : 2,
254         'con' : 2,
255         'num' : 2,
256         'nr' : 1,
257         'sw' : 2,
258 }
259
260 gramact = [k for k in keys if keys[k] == 1]
261 gramsup = [k for k in keys if keys[k] == 2]
262
263 #corpus = Corpus('', {'filename': '/home/pierre/workspace/iramuteq/dev/testcorpus.txt','formesdb':'formes.db', 'ucesdb': 'uces.db', 'corpusdb' : 'corpus.db', 'syscoding' : 'utf-8'})
264 #corpus.read_corpus()
265 #corpus.parse_active(gramact, gramsup)
266 #Alceste(corpus).doanalyse()