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