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