...
[iramuteq] / ProfList.py
1 # -*- coding: utf-8 -*-
2
3 #----------------------------------------------------------------------------
4 # Name:         ListCtrl.py
5 # Author:       Pierre Ratinaud
6
7
8 #comes from ListCtrl.py from the demo tool of wxPython:
9 # Author:       Robin Dunn & Gary Dumer
10 #
11 # Created:
12 # Copyright:    (c) 1998 by Total Control Software
13 # Licence:      wxWindows license
14 #----------------------------------------------------------------------------
15
16 import os
17 import sys
18 import  wx
19 import  wx.lib.mixins.listctrl  as  listmix
20 #from tabsimi import DoSimi
21 from listlex import ListForSpec
22 from chemins import ConstructPathOut, ffr
23 from dialog import PrefExport, PrefUCECarac, SearchDial, message, MessageImage, BarFrame
24 from tableau import Tableau, copymatrix
25 from search_tools import SearchFrame
26 import webbrowser
27 #import cStringIO
28 import tempfile
29 import codecs
30 from functions import exec_rcode, progressbar, treat_var_mod, doconcorde
31 from PrintRScript import barplot
32 from textclassechd import ClasseCHD
33 from shutil import copyfile
34 from operator import itemgetter
35 from copy import copy
36
37 #---------------------------------------------------------------------------
38 class ProfListctrlPanel(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin, listmix.ColumnSorterMixin):
39     def __init__(self, parent, gparent, profclasse, Alceste=False, cl=0):
40         wx.ListCtrl.__init__( self, parent, -1, style=wx.LC_REPORT|wx.LC_VIRTUAL|wx.LC_HRULES|wx.LC_VRULES)
41
42         self.parent = parent
43         self.Alceste = Alceste
44         self.Source = gparent
45         self.cl = cl
46         self.var_mod = {}
47         self.them_mod = {}
48
49         line1 = profclasse.pop(0)
50         classen = [line for line in profclasse if line[0] != '*' and line[0] != '*****']
51         try :
52             self.lenact = profclasse.index([u'*****', u'*', u'*', u'*', u'*', u'*', '', ''])
53             profclasse.pop(self.lenact)
54         except ValueError:
55             try :
56                 self.lenact = profclasse.index([u'*', u'*', u'*', u'*', u'*', u'*', '', ''])
57                 profclasse.pop(self.lenact)
58             except ValueError:
59                 self.lenact = len(profclasse)
60         try :
61             self.lensup = profclasse.index([u'*', u'*', u'*', u'*', u'*', u'*', '', ''])
62             self.lensup = self.lensup - self.lenact
63             profclasse.pop(self.lensup)
64         except ValueError: 
65             self.lensup = len(profclasse) - self.lenact
66         self.lenet = len(profclasse) - (self.lenact + self.lensup)
67 #        print self.lenact, self.lensup, self.lenet
68         for i,  line in enumerate(classen) :
69             line[0] = i
70         dictdata = dict(zip([i for i in range(0,len(classen))], classen))
71
72         if self.lenact != 0 :
73             self.la = [dictdata[i][6] for i in range(0, self.lenact)]
74             self.lchi = [dictdata[i][4] for i in range(0, self.lenact)]
75             self.lfreq = [dictdata[i][1] for i in range(0, self.lenact)]
76         else :
77             self.la = []
78             self.lchi = []
79             self.lfreq = []
80         self.tmpchi = None
81             
82         #adding some art
83         self.il = wx.ImageList(16, 16)
84         a={"sm_up":"GO_UP","sm_dn":"GO_DOWN","w_idx":"WARNING","e_idx":"ERROR","i_idx":"QUESTION"}
85         for k,v in a.items():
86             s="self.%s= self.il.Add(wx.ArtProvider_GetBitmap(wx.ART_%s,wx.ART_TOOLBAR,(16,16)))" % (k,v)
87             exec(s)
88         self.SetImageList(self.il, wx.IMAGE_LIST_SMALL)
89
90         #adding some attributes (colourful background for each item rows)
91         self.attr1 = wx.ListItemAttr()
92         self.attr1.SetBackgroundColour((220, 220, 220))
93         self.attrsg = wx.ListItemAttr()
94         self.attrsg.SetBackgroundColour((230, 230, 230))
95         self.attr2 = wx.ListItemAttr()
96         self.attr2.SetBackgroundColour((190, 249, 236))
97         self.attr2s = wx.ListItemAttr()
98         self.attr2s.SetBackgroundColour((211, 252, 244))        
99         self.attr3 = wx.ListItemAttr()
100         self.attr3.SetBackgroundColour((245, 180, 180))
101         self.attr3s = wx.ListItemAttr()
102         self.attr3s.SetBackgroundColour((245, 190, 190))
103
104
105         self.InsertColumn(0, "num", wx.LIST_FORMAT_RIGHT)
106         self.InsertColumn(1, "eff. s.t.", wx.LIST_FORMAT_RIGHT)
107         self.InsertColumn(2, "eff. total", wx.LIST_FORMAT_RIGHT)
108         self.InsertColumn(3, "pourcentage", wx.LIST_FORMAT_RIGHT)
109         self.InsertColumn(4, "chi2", wx.LIST_FORMAT_RIGHT)
110         self.InsertColumn(5, "Type", wx.LIST_FORMAT_RIGHT)
111         self.InsertColumn(6, "forme", wx.LIST_FORMAT_RIGHT)
112         self.InsertColumn(7, "p", wx.LIST_FORMAT_RIGHT)
113         
114
115         self.SetColumnWidth(0, 60)
116         self.SetColumnWidth(1, 70)
117         self.SetColumnWidth(2, 80)
118         self.SetColumnWidth(3, 100)
119         self.SetColumnWidth(4, 70)
120         self.SetColumnWidth(5, 60)
121         self.SetColumnWidth(6, 140)
122         self.SetColumnWidth(7, wx.LIST_AUTOSIZE)
123
124         #These two should probably be passed to init more cleanly
125         #setting the numbers of items = number of elements in the dictionary
126         self.itemDataMap = dictdata
127         self.itemIndexMap = dictdata.keys()
128         self.SetItemCount(len(dictdata))
129         
130         #mixins
131         listmix.ListCtrlAutoWidthMixin.__init__(self)
132         listmix.ColumnSorterMixin.__init__(self, len(classen[0]))
133
134         #sort by genre (column 2), A->Z ascending order (1)
135         self.SortListItems(0, 1)
136
137         #events
138         #self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected)
139         self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnPopupTwo, self)
140         #self.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.OnItemDeselected)
141         self.Bind(wx.EVT_LIST_COL_CLICK, self.OnColClick)
142
143         # for wxMSW
144         self.Bind(wx.EVT_COMMAND_RIGHT_CLICK, self.OnRightClick)
145
146         # for wxGTK
147         self.Bind(wx.EVT_RIGHT_UP, self.OnRightClick)
148
149         #for searching
150         search_id = wx.NewId()
151         searchall_id = wx.NewId()
152         concord_id = wx.NewId()
153         self.parent.Bind(wx.EVT_MENU, self.onsearch, id = search_id)
154         self.parent.Bind(wx.EVT_MENU, self.onsearchall, id = searchall_id)
155         self.accel_tbl = wx.AcceleratorTable([(wx.ACCEL_CTRL, ord('F'), search_id),
156                                               (wx.ACCEL_CTRL|wx.ACCEL_SHIFT, ord('F'), searchall_id)])
157         self.SetAcceleratorTable(self.accel_tbl)
158
159
160
161     def OnColClick(self,event):
162         event.Skip()
163
164     def OnItemSelected(self, event):
165         self.currentItem = event.m_itemIndex
166
167     def OnItemActivated(self, event):
168         self.currentItem = event.m_itemIndex
169
170     def getColumnText(self, index, col):
171         item = self.GetItem(index, col)
172         return item.GetText()
173
174     def OnItemDeselected(self, evt):
175         pass
176     #---------------------------------------------------
177     # These methods are callbacks for implementing the
178     # "virtualness" of the list...
179
180     def OnGetItemText(self, item, col):
181         index=self.itemIndexMap[item]
182         s = self.itemDataMap[index][col]
183         return s
184
185     def OnGetItemImage(self, item):
186         index=self.itemIndexMap[item]
187         genre=self.itemDataMap[index][2]
188
189         if genre=="Rock":
190             return self.w_idx
191         elif genre=="Jazz":
192             return self.e_idx
193         elif genre=="New Age":
194             return self.i_idx
195         else:
196             return -1
197
198     def OnGetItemAttr(self, item):
199         index=self.itemIndexMap[item]
200         if index < self.lenact :
201             if item % 2 :
202                 return self.attr1
203             else :
204                 return self.attrsg
205         elif index >= self.lenact and index < (self.lenact + self.lensup) :
206             if item % 2 :
207                 return self.attr2
208             else :
209                 return self.attr2s
210         elif index >= (self.lenact + self.lensup) :
211             if item % 2 :
212                 return self.attr3
213             else :
214                 return self.attr3s
215         else :
216             return None
217
218     #---------------------------------------------------
219     # Matt C, 2006/02/22
220     # Here's a better SortItems() method --
221     # the ColumnSorterMixin.__ColumnSorter() method already handles the ascending/descending,
222     # and it knows to sort on another column if the chosen columns have the same value.
223
224     def SortItems(self,sorter=cmp):
225         items = list(self.itemDataMap.keys())
226         items.sort(sorter)
227         self.itemIndexMap = items
228         
229         # redraw the list
230         self.Refresh()
231
232     # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py
233     def GetListCtrl(self):
234         return self
235
236     # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py
237     def GetSortImages(self):
238         return (self.sm_dn, self.sm_up)
239
240     def onsearch(self, evt) :
241         self.dial = SearchDial(self, self, 6, True)
242         self.dial.CenterOnParent()
243         self.dial.Show()
244         #self.dial.Destroy()
245
246     def onsearchall(self, evt) :
247         if 'FrameSearch' not in dir(self.Source) :
248             self.Source.FrameSearch = SearchFrame(self.parent, -1, u"Rechercher...", self.Source.corpus)
249         self.dial = SearchDial(self, self.Source.FrameSearch.liste, 1, False)
250         self.dial.CenterOnParent()
251         self.dial.Show()
252         #self.dial.Destroy()
253
254     def OnRightClick(self, event):
255
256         # only do this part the first time so the events are only bound once
257         if self.Alceste:
258             if not hasattr(self, "popupID1"):
259                 self.popupID1 = wx.NewId()
260                 self.popupID2 = wx.NewId()
261                 self.popupID3 = wx.NewId()
262                 self.popupID4 = wx.NewId()
263                 self.popupID5 = wx.NewId()
264                 self.popupID6 = wx.NewId()
265                 self.popupID7 = wx.NewId()
266                 self.popupID8 = wx.NewId()
267                 self.popupID9 = wx.NewId()
268                 #self.popupID10 = wx.NewId()
269                 self.popupIDgraph = wx.NewId()
270                 self.idseg = wx.NewId()
271                 self.iducecarac = wx.NewId()
272                 self.idtablex = wx.NewId()
273                 self.idchimod = wx.NewId()
274                 self.idwordgraph = wx.NewId()
275                 self.popup_proxe = wx.NewId()
276                 self.idlexdendro = wx.NewId()
277                 self.idcloud = wx.NewId()
278                 self.idexport = wx.NewId()
279                 self.idexporttropes = wx.NewId()
280                 self.idexportowledge = wx.NewId()
281                 self.onmaketgen = wx.NewId()
282             #    self.export_classes = wx.NewId()
283    
284                 self.Bind(wx.EVT_MENU, self.OnPopupOne, id=self.popupID1)
285                 self.Bind(wx.EVT_MENU, self.OnPopupTwo, id=self.popupID2)
286                 self.Bind(wx.EVT_MENU, self.OnPopupThree, id=self.popupID3)
287                 self.Bind(wx.EVT_MENU, self.OnPopupFour, id=self.popupID4)
288                 self.Bind(wx.EVT_MENU, self.OnPopupFive, id=self.popupID5)
289                 self.Bind(wx.EVT_MENU, self.OnPopupSix, id=self.popupID6)
290                 self.Bind(wx.EVT_MENU, self.OnPopupSeven, id=self.popupID7)
291                 self.Bind(wx.EVT_MENU, self.OnPopupHeight, id=self.popupID8)
292                 self.Bind(wx.EVT_MENU, self.OnPopupNine, id=self.popupID9)
293                 #self.Bind(wx.EVT_MENU, self.OnPopupSpec, id=self.popupID10)
294                 self.Bind(wx.EVT_MENU, self.on_graph, id=self.popupIDgraph)
295                 self.Bind(wx.EVT_MENU, self.on_segments, id=self.idseg)
296                 self.Bind(wx.EVT_MENU, self.on_uce_carac, id = self.iducecarac)
297                 self.Bind(wx.EVT_MENU, self.on_tablex, id = self.idtablex)
298                 self.Bind(wx.EVT_MENU, self.quest_var_mod, id = self.idchimod)
299                 self.Bind(wx.EVT_MENU, self.onwordgraph, id = self.idwordgraph)
300                 self.Bind(wx.EVT_MENU, self.onproxe, id = self.popup_proxe)
301                 self.Bind(wx.EVT_MENU, self.onlexdendro, id = self.idlexdendro)
302                 self.Bind(wx.EVT_MENU, self.oncloud, id = self.idcloud)
303                 self.Bind(wx.EVT_MENU, self.onexport, id = self.idexport)
304                 self.Bind(wx.EVT_MENU, self.onexporttropes, id = self.idexporttropes)
305                 self.Bind(wx.EVT_MENU, self.onexportowledge, id = self.idexportowledge)
306                 self.Bind(wx.EVT_MENU, self.OnMakeTgen, id=self.onmaketgen)
307              #  self.Bind(wx.EVT_MENU, self.on_export_classes, id = self.export_classes)
308    #            self.Bind(wx.EVT_MENU, self.OnPopupThree, id=self.popupID3)
309     
310             # make a menu
311             menu = wx.Menu()
312             menu.Append(self.popupID1, u"Formes associées")
313             menu.Append(self.idtablex, u"Chi2 par classe")
314             menu.Append(self.idlexdendro, u"Chi2 par classe + dendro")
315             menu.Append(self.idchimod, u"Chi2 modalités de la variable")
316             menu.Append(self.idwordgraph, u"Graphe du mot")
317             #menu.Append(self.export_classes, u"Exporter le corpus...") 
318             
319             #menu.Append(self.popupID10, u"Spécificités")
320
321             menu_conc = wx.Menu()
322             menu_conc.Append(self.popupID2, u"dans les segments de texte de la classe")
323             menu_conc.Append(self.popupID3, u"dans les segments de texte classés")
324             menu_conc.Append(self.popupID4, u"dans tous les segments de texte")
325             menu.AppendMenu(-1, u"Concordancier", menu_conc)
326             menu.Append(self.onmaketgen, _(u"Make Tgen").decode('utf8'))
327             menu_cnrtl = wx.Menu()      
328             menu_cnrtl.Append(self.popupID5, u"Définition")
329             menu_cnrtl.Append(self.popupID6, u"Etymologie")
330             menu_cnrtl.Append(self.popupID7, u"Synonymie")
331             menu_cnrtl.Append(self.popupID8, u"Antonymie")
332             menu_cnrtl.Append(self.popupID9, u"Morphologie")
333             menu_cnrtl.Append(self.popup_proxe, u"Proxémie")
334             menu.AppendMenu(-1, u"Outils du CNRTL", menu_cnrtl)
335             menu.AppendSeparator()
336             menu.Append(self.popupIDgraph, u"Graphe de la classe")
337             menu.Append(self.idseg, u"Segments répétés")
338             menu.Append(self.iducecarac, u"Segments de texte caractéristiques")
339             menu.Append(self.idcloud, u"Nuage de la classe")
340             menu.Append(self.idexport, u'Exporter...')
341             menu.Append(self.idexporttropes, 'Exporter pour Tropes')
342             menu.Append(self.idexportowledge, 'Exporter pour Owledge')
343             #menu.Append(self.popupID2, u"Concordancier")
344     #        menu.Append(self.popupID3, "recharger")
345     
346             self.PopupMenu(menu)
347             menu.Destroy()
348         elif 'tableau' in dir(self.Source) :
349             if not hasattr(self, "pop1"):
350                 self.pop1 = wx.NewId()
351                 self.pop2 = wx.NewId()
352                 self.pop3 = wx.NewId()
353                 self.Bind(wx.EVT_MENU, self.quest_simi, id=self.pop1)
354                 self.Bind(wx.EVT_MENU, self.on_tablex, id=self.pop2)
355                 self.Bind(wx.EVT_MENU, self.quest_var_mod, id=self.pop3)
356
357             menu = wx.Menu()
358             menu.Append(self.pop2, u"Chi2 par classe")
359             menu.Append(self.pop3, u"Chi2 modalités de la variable")
360             menu.AppendSeparator()
361             menu.Append(self.pop1, u"Graphe de la classe")
362             self.PopupMenu(menu)
363             menu.Destroy()
364
365     def oncloud(self, evt) :
366         if 'corpus' in dir(self.Source):
367             corpus = self.Source.corpus
368         prof = [[self.la[i], self.lchi[i], self.lfreq[i]] for i, val in enumerate(self.la)]
369         parametres = copy(self.Source.parametres)
370         parametres['clusterprof'] = prof
371         parametres['type'] = 'clustercloud'
372         parametres['prof'] = self.Source.pathout['actprof_classe_%i.csv' % self.cl]
373         del  parametres['uuid']
374         #if not os.path.exists(self.Source.pathout['actprof_classe_%i.csv' % self.lc]) :
375         #    with open(self.Source.pathout['actprof_classe_%i.csv' % self.lc], 'w') as f :
376         #        f.write('\n'.join(prof).encode(self.parent.syscoding))
377         self.parent.OnClusterCloud(self.Source.corpus, parametres = parametres)
378
379     def onexport(self, evt) :
380         if 'corpus' in dir(self.Source):
381             corpus = self.Source.corpus
382         if self.Source.parametres['classif_mode'] != 2 :
383             uci = False
384         else :
385             uci = True
386         corpus.export_classe(self.Source.pathout['classe_%i_export.txt' % self.cl], self.cl, uci = uci)
387         dial = wx.MessageDialog(self, self.Source.pathout['classe_%i_export.txt' % self.cl], u"Export", wx.OK|wx.ICON_INFORMATION)
388         dial.ShowModal()
389         dial.Destroy()
390         #if 'corpus' in dir(self.Source):
391         #    corpus = self.Source.corpus
392         #ClasseCHD(self.parent, corpus, self.cl)
393     
394     def onexporttropes(self, evt) :
395         if 'corpus' in dir(self.Source):
396             corpus = self.Source.corpus
397         if self.Source.parametres['classif_mode'] != 2 :
398             uci = False
399         else :
400             uci = True
401         fileout = self.Source.pathout['export_tropes_classe_%i.txt' % self.cl]
402         corpus.export_tropes(fileout, self.cl, uci = uci)
403     
404     def onexportowledge(self, evt):
405         if 'corpus' in dir(self.Source):
406             corpus = self.Source.corpus
407         if self.Source.parametres['classif_mode'] != 2 :
408             uci = False
409         else :
410             uci = True
411         repout = self.Source.pathout['export_owledge_classe_%i' % self.cl]
412         if not os.path.exists(repout) :
413             os.mkdir(repout)
414         corpus.export_owledge(repout, self.cl, uci = uci)        
415
416     def getselectedwords(self) :
417         words = [self.getColumnText(self.GetFirstSelected(), 6)]
418         last = self.GetFirstSelected()
419         while self.GetNextSelected(last) != -1:
420             last = self.GetNextSelected(last)
421             words.append(self.getColumnText(last, 6))
422         return words
423
424     def quest_var_mod(self, evt) :  
425         word = self.getselectedwords()[0]
426         if len(word.split('_')) <= 1 :
427             dial = wx.MessageDialog(self, u"Ce n'est pas une forme du type variable_modalité", u"Problème", wx.OK | wx.ICON_WARNING)
428             dial.CenterOnParent()
429             dial.ShowModal()
430             dial.Destroy()
431             return
432             
433         if 'corpus' in dir(self.Source):
434             corpus = self.Source.corpus
435             if word.startswith(u'-*') :
436                 if self.them_mod == {} :
437                     self.them_mod = self.Source.corpus.make_theme_dict()
438                 var_mod = self.them_mod
439             else :
440                 if self.var_mod == {} :
441                     self.var_mod = self.Source.corpus.make_etoiles_dict()
442                 var_mod = self.var_mod
443         else :
444             corpus = self.Source.tableau
445             if self.var_mod == {} :
446                 self.var_mod = treat_var_mod([val for val in corpus.actives] + [val for val in corpus.sups])
447             var_mod = self.var_mod
448         with codecs.open(self.Source.pathout['chisqtable'], 'r', corpus.parametres['syscoding']) as f :
449             chistable = [line.replace('\n','').replace('\r','').replace('"','').replace(',','.').split(';') for line in f]
450         title = chistable[0]
451         title.pop(0)
452         chistable.pop(0)
453         vchistable = [line[1:] for line in chistable]
454         fchistable = [line[0] for line in chistable]
455
456         var = word.split('_')
457         #words = ['_'.join([var[0],word]) for word in self.var_mod[var[0]]]
458         try :
459             words = [word for word in var_mod[var[0]]]
460         except KeyError:
461             dial = wx.MessageDialog(self, _(u"This is not a meta-data"), u"Problème", wx.OK | wx.ICON_WARNING)
462             dial.CenterOnParent()
463             dial.ShowModal()
464             dial.Destroy()
465             return            
466         words.sort()
467         tableout = []
468         kwords = []
469         for word in words :
470             if word in fchistable :
471                 tableout.append(vchistable[fchistable.index(word)])
472                 kwords.append(word)
473         BarFrame(self.Source.parent, tableout, title, kwords)
474
475     def quest_simi(self, evt) :
476         tableau = self.Source.tableau
477         tab = tableau.make_table_from_classe(self.cl, self.la)
478         pathout = ConstructPathOut(self.Source.pathout.dirout, 'simi_classe_%i' %self.cl)
479         if self.tmpchi is None :
480             self.tmpchi = os.path.join(pathout,'chi.csv')
481             with open(self.tmpchi, 'w') as f:
482                 f.write('\n'.join([str(val) for val in self.lchi]))
483         self.filename = os.path.join(pathout,'mat01.csv')
484         tableau.printtable(self.filename, tab)
485         del tab
486         paramsimi = {'coeff' : 0,
487                           'layout' : 2,
488                           'type_graph' : 1,
489                           'arbremax' : 1,
490                           'coeff_tv' : 1,
491                           'coeff_tv_nb' : 0,
492                           'tvprop' : 0,
493                           'tvmin' : 5,
494                           'tvmax' : 30,
495                           'coeff_te' : 1,
496                           'coeff_temin' : 1,
497                           'coeff_temax' : 10,
498                           'label_v': 1,
499                           'label_e': 1,
500                           'vcex' : 0,
501                           'vcexmin' : 10,
502                           'vcexmax' : 25,
503                           'cex' : 10,
504                           'cexfromchi' : True,
505                           'sfromchi': False,
506                           'seuil_ok' : 0,
507                           'seuil' : 1,
508                           'cols' : (255,0,0),
509                           'cola' : (200,200,200),
510                           'width' : 1000,
511                           'height' : 1000,
512                           'first' : True,
513                           'keep_coord' : True,
514                           'alpha' : 20,
515                           'film': False,
516                           'com' : 0,
517                           'communities' : 0,
518                           'halo' : 0,
519                           'tmpchi': self.tmpchi,
520                           'fromprof' : True,
521                           'edgecurved' : True,
522                           }
523         act = {}
524         tableau = copymatrix(tableau)
525         tableau.chi = {}
526         tableau.lchi = self.lchi
527         #tableau.parametres['fromprof'] = True
528         for i, val in enumerate(self.la) :
529             act[val] = [self.lfreq[i]]
530             tableau.chi[val] = [self.lchi[i]]
531         paramsimi['listactives'] = copy(self.la)
532         paramsimi['actives'] = copy(act)
533         paramsimi['pathout'] = pathout
534         self.parent.SimiCluster(parametres = paramsimi, fromprof = ffr(self.filename), tableau = tableau)
535
536     def onwordgraph(self, evt):
537         word = self.getColumnText(self.GetFirstSelected(), 6)
538         if self.tmpchi is None :
539             self.tmpchi = os.path.join(self.Source.parametres['pathout'],'chi_%i.csv' % self.cl)
540             with open(self.tmpchi, 'w') as f:
541                 f.write('\n'.join([str(val) for val in self.lchi]))
542         index = self.la.index(word)
543         parametres = {'type' : 'clustersimitxt', 
544                         'pathout' : self.Source.parametres['pathout'],
545                         'word' : index ,
546                         'lem' : self.Source.parametres['lem'],
547                         'tmpchi' : self.tmpchi}
548         #try :
549         self.parent.SimiFromCluster(self.parent, self.Source.corpus, self.la, self.lfreq, self.lchi, self.cl - 1, parametres = parametres, dlg = progressbar(self, 4))
550         #except :
551         #    print 'not acitve'
552
553     def on_graph(self, evt):
554         if self.tmpchi is None :
555             self.tmpchi = os.path.join(self.Source.parametres['pathout'],'chi_%i.csv' % self.cl)
556             with open(self.tmpchi, 'w') as f:
557                 f.write('\n'.join([str(val) for val in self.lchi]))
558         parametres = {'type' : 'clustersimitxt', 
559                         'pathout' : self.Source.parametres['pathout'],
560                         'lem' : self.Source.parametres['lem'],
561                         'tmpchi' : self.tmpchi}
562
563         self.parent.SimiFromCluster(self.parent, self.Source.corpus, self.la, self.lfreq, self.lchi, self.cl - 1, parametres = parametres, dlg = progressbar(self, 4))
564
565     def on_segments(self,evt) :
566         dlg = progressbar(self, 2)
567         corpus = self.Source.corpus
568         uces = corpus.lc[self.cl-1]
569         if self.Source.parametres['classif_mode'] != 2 :
570             uci = False
571         else :
572             uci = True
573         l = []
574         dlg.Update(1, u'Segments...')
575         for i in range(2,10) :
576             li = corpus.find_segments_in_classe(uces, i, 1000, uci = uci)
577             if li == [] :
578                 break
579             else :
580                 l += li
581         l.sort(reverse = True)
582         d = {}
583         dlg.Update(2, 'Tri...')
584         for i, line in enumerate(l) :
585             d[i] = [line[1],line[0], line[2]]
586         first = ['','','']
587         para={'dico': d,'fline':first}
588         dlg.Destroy()
589         win = wliste(self, -1, u"Segments répétés - Classe %i" % self.cl, d, first, size=(600, 500))
590         win.Show(True)
591
592     def on_uce_carac(self,evt) :
593         dial = PrefUCECarac(self, self.parent)
594         dial.CenterOnParent()
595         if dial.ShowModal() == wx.ID_OK :
596             limite = dial.spin_eff.GetValue()
597             atype = dial.radio_type.GetSelection()
598             dlg = progressbar(self,maxi = 4)
599             corpus = self.Source.corpus
600             uces = corpus.lc[self.cl-1]
601             if self.Source.parametres['classif_mode'] != 2 :
602                 uci = False
603             else :
604                 uci = True
605             tab = corpus.make_table_with_classe(uces, self.la, uci = uci)
606             tab.pop(0)
607             dlg.Update(2, u'score...')
608             if atype == 0 :
609                 ntab = [round(sum([self.lchi[i] for i, word in enumerate(line) if word == 1]),2) for line in tab]
610             else :
611                 ntab = [round(sum([self.lchi[i] for i, word in enumerate(line) if word == 1])/float(sum(line)),2) if sum(line)!=0 else 0 for line in tab]
612             ntab2 = [[ntab[i], uces[i]] for i, val in enumerate(ntab)]
613             del ntab
614             ntab2.sort(reverse = True)
615             ntab2 = ntab2[:limite]
616             nuces = [val[1] for val in ntab2]
617             dlg.Update(3, u'concordancier...')
618             ucis_txt, ucestxt = doconcorde(corpus, nuces, self.la, uci = uci)
619             items = dict([[i, '<br>'.join([ucis_txt[i], '<table bgcolor = #1BF0F7 border=0><tr><td><b>score : %.2f</b></td></tr></table><br>' % ntab2[i][0], ucestxt[i]])] for i, uce in enumerate(nuces)])
620             dlg.Destroy()
621             win = message(self, items, u"Segments de texte caractéristiques - Classe %i" % self.cl, (750, 600), uceids = nuces)
622             #win.html = '<html>\n' + '<br>'.join(['<br>'.join([ucis_txt[i], '<table bgcolor = #1BF0F7 border=0><tr><td><b>score : %.2f</b></td></tr></table>' % ntab2[i][0], ucestxt[i]]) for i in range(0,len(ucestxt))]) + '\n</html>'
623             #win.HtmlPage.SetPage(win.html)
624             win.Show(True)
625     
626     def on_tablex(self, evt):
627         if 'corpus' in dir(self.Source):
628             corpus = self.Source.corpus
629         else :
630             corpus = self.Source.tableau
631         with codecs.open(self.Source.pathout['chisqtable'], 'r', corpus.parametres['syscoding']) as f :
632             chistable = [line.replace('\n','').replace('\r','').replace('"','').replace(',','.').split(';') for line in f]
633         title = chistable[0]
634         title.pop(0)
635         chistable.pop(0)
636         vchistable = [line[1:] for line in chistable]
637         fchistable = [line[0] for line in chistable]
638         words = self.getselectedwords()
639         tableout = [vchistable[fchistable.index(word)] for word in words]
640         tmpgraph = tempfile.mktemp(dir=self.Source.parent.TEMPDIR)
641         nbcl = len(title)
642         nbwords = len(words)
643         BarFrame(self.Source.parent, tableout, title, words)
644
645     def onlexdendro(self, evt):
646         if 'corpus' in dir(self.Source):
647             corpus = self.Source.corpus
648         else :
649             corpus = self.Source.tableau
650         with codecs.open(self.Source.pathout['chisqtable'], 'r', corpus.parametres['syscoding']) as f :
651             chistable = [line.replace('\n','').replace('\r','').replace('"','').replace(',','.').split(';') for line in f]
652         title = chistable[0]
653         title.pop(0)
654         chistable.pop(0)
655         vchistable = [line[1:] for line in chistable]
656         fchistable = [line[0] for line in chistable]
657         words = self.getselectedwords()
658         tableout = [vchistable[fchistable.index(word)] for word in words]
659         BarFrame(self.Source.parent, tableout, title, words, tree = self.Source.pathout['Rdendro'])
660
661     def make_concord(self, uces, title, color = 'red') :
662         corpus = self.Source.corpus
663         ListWord = [self.getColumnText(self.GetFirstSelected(), 6)]
664         last = self.GetFirstSelected()
665         while self.GetNextSelected(last) != -1:
666             last = self.GetNextSelected(last)
667             ListWord.append(self.getColumnText(last, 6))
668         ucef = []
669         if self.Source.parametres['classif_mode'] != 2 :
670             for word in ListWord : 
671                 uci = False
672                 ucef += list(set(corpus.getlemuces(word)).intersection(uces))
673         else :
674             for word in ListWord : 
675                 ucef += list(set(corpus.getlemucis(word)).intersection(uces))            
676                 uci = True
677         ucis_txt, ucestxt = doconcorde(corpus, ucef, ListWord, uci = uci)
678         items = dict([[i, '<br><br>'.join([ucis_txt[i], ucestxt[i]])] for i in range(0,len(ucestxt))])
679         win = message(self, items, title, (800, 500), uceids = ucef)
680         return win
681
682     def OnPopupTwo(self, event):
683         if 'corpus' in dir(self.Source) :
684             corpus = self.Source.corpus
685             uces = corpus.lc[self.cl-1]
686             win = self.make_concord(uces, "Concordancier - Classe %i" % self.cl)
687             win.Show(True)
688     
689     def OnPopupThree(self, event):
690         corpus = self.Source.corpus
691         uces = [classe[i] for classe in corpus.lc for i in range(0,len(classe))]
692         win = self.make_concord(uces, "Concordancier - Segments de texte classés")
693         win.Show(True)
694         
695     def OnPopupFour(self, event):
696         corpus = self.Source.corpus
697         uces = [classe[i] for classe in corpus.lc for i in range(0,len(classe))] + corpus.lc0
698         win = self.make_concord(uces, "Concordancier - Tous les segments de texte")
699         win.Show(True)
700
701     def OnPopupFive(self, event):
702         word = self.getColumnText(self.GetFirstSelected(), 6)
703         lk = "http://www.cnrtl.fr/definition/" + word
704         webbrowser.open(lk)
705
706     def OnPopupSix(self, event):  
707         word = self.getColumnText(self.GetFirstSelected(), 6)
708         lk = "http://www.cnrtl.fr/etymologie/" + word
709         webbrowser.open(lk)
710         
711     def OnPopupSeven(self, event):        
712         word = self.getColumnText(self.GetFirstSelected(), 6)
713         lk = "http://www.cnrtl.fr/synonymie/" + word
714         webbrowser.open(lk)
715         
716     def OnPopupHeight(self, event):  
717         word = self.getColumnText(self.GetFirstSelected(), 6)
718         lk = "http://www.cnrtl.fr/antonymie/" + word
719         webbrowser.open(lk)
720         
721     def OnPopupNine(self, event):            
722         word = self.getColumnText(self.GetFirstSelected(), 6)
723         lk = "http://www.cnrtl.fr/morphologie/" + word
724         webbrowser.open(lk)
725
726     def onproxe(self, evt) :
727         word = self.getColumnText(self.GetFirstSelected(), 6)
728         lk = "http://www.cnrtl.fr/proxemie/" + word
729         webbrowser.open(lk)
730
731     def OnPopupOne(self, event):
732         corpus = self.Source.corpus
733         #print 'ATTENTION PRINT ET TABLE'
734         #corpus.make_et_table()
735         word = self.getColumnText(self.GetFirstSelected(), 6)
736         lems = corpus.getlems()
737         uces = corpus.lc[self.cl-1]
738         rep = []
739         #FIXME : donner aussi eff reel a la place de nb uce
740         for forme in lems[word].formes :
741             if self.Source.parametres['classif_mode'] != 2 :
742                 ucef = list(set(corpus.getworduces(forme)).intersection(uces))
743             else :
744                 ucef = list(set(corpus.getworducis(forme)).intersection(uces))
745             #ucef = [uce for uce in corpus.formes[forme][1] if uce in uces]
746             if ucef != [] :
747                 nb = len(ucef)
748                 rep.append([corpus.getforme(forme).forme, nb])
749         rep.sort(key = itemgetter(1), reverse = True)
750         #win = message(self, u"Formes associées", wx.Size(300, 200))
751         items = dict([[i, '\t:\t'.join([str(val) for val in forme])] for i, forme in enumerate(rep)])
752         win = message(self, items, u"Formes associées", (300, 200))
753         #win.html = '<html>\n' + '<br>'.join([' : '.join([str(val) for val in forme]) for forme in rep]) + '\n</html>'
754         #win.HtmlPage.SetPage(win.html)
755         win.Show(True)
756     
757     def OnMakeTgen(self, evt):
758         self.parent.tree.OnTgenEditor(self.getselectedwords())    
759
760
761 class wliste(wx.Frame):
762     def __init__(self, parent, id, title, d, fline, size=(600, 500)):
763         wx.Frame.__init__(self, parent, id)
764         self.liste = ListForSpec(self, parent, d, fline[1:], menu = False)
765         self.button_1 = wx.Button(self, -1, "Fermer")
766         self.Bind(wx.EVT_BUTTON, self.OnCloseMe, self.button_1)
767         self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
768         self.__do_layout()
769
770     def __do_layout(self):
771         sizer_1 = wx.BoxSizer(wx.VERTICAL)
772         sizer_2 = wx.BoxSizer(wx.VERTICAL)
773         sizer_2.Add(self.liste, 1, wx.EXPAND | wx.ADJUST_MINSIZE, 0)
774         sizer_2.Add(self.button_1, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ADJUST_MINSIZE, 0)
775         sizer_1.Add(sizer_2, 1, wx.EXPAND, 0)
776         self.SetAutoLayout(True)
777         self.SetSizer(sizer_1)
778         self.Layout()
779         
780     def OnCloseMe(self, event):
781         self.Close(True)
782
783     def OnCloseWindow(self, event):
784         self.Destroy()