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