source: orange-bioinformatics/orangecontrib/bio/widgets/prototypes/OWDataFiles.py @ 1873:0810c5708cc5

Revision 1873:0810c5708cc5, 10.4 KB checked in by Ales Erjavec <ales.erjavec@…>, 6 months ago (diff)

Moved '_bioinformatics' into orangecontrib namespace.

RevLine 
[975]1"""
2<name>Data Files</name>
3<description>Reads data from designated directory.</description>
4<icon>icons/ChipDataFiles.png</icon>
5<priority>1050</priority>
6<contact>Peter Juvan (peter.juvan@fri.uni-lj.si)</contact>
[1643]7<prototype>1</prototype>
[975]8"""
9
[1633]10import os, os.path
11
12import orange
13from Orange.OrangeWidgets.OWWidget import *
14from Orange.OrangeWidgets import OWGUI
[975]15
16import warnings
17warnings.filterwarnings("ignore", "'strain'", orange.AttributeWarning)
18
[1731]19class DataFiles(orange.OrangeBase):
[975]20    """Structure for communicating multiple ExampleTables:
21    [(name1,[exampleTable1a,exampleTable1b,...]), (name2,[exampleTable2a,...]), ...]
22    """
23    pass
24
25
[1731]26class ExampleSelection(orange.OrangeBase):
[975]27    """Structure for selection of examples: (selectorName, [0,1,...])
28    """
29    pass
30
31
32class OWDataFiles(OWWidget):
33    settingsList  = ["recentDirs", "selectedDirName", "applyOnChange"]
34
35    def __init__(self, parent=None, signalManager = None, loaddata=1):
36        OWWidget.__init__(self, parent, signalManager, 'Data Files', wantMainArea = 0, resizingEnabled = 1)
37
38        self.callbackDeposit = []
39
40        self.inputs = []
41        self.outputs = [("Examples", ExampleTable), ("Structured Data", DataFiles)]
42
43        self.dataStructure = []
44        self.datasets = None
45        self.lastSentIds = []
46
47        # Settings
48        self.recentDirs=[] 
49        self.selectedDirName = "None"
50        self.applyOnChange = 0
51        self.loadSettings()
52
53        # CONTROLS
54        box = OWGUI.widgetBox(self.controlArea, "Directory", addSpace = True, orientation=0)
55        self.dircombo=QComboBox(box)
56        box.layout().addWidget(self.dircombo)
57        button = OWGUI.button(box, self, '...', callback = self.browseDirectory, disabled=0)
58        button.setMaximumWidth(25)
59        # connecting GUI to code
60        self.connect(self.dircombo,SIGNAL('activated(int)'),self.selectDir)
61
62        # info
63        box = OWGUI.widgetBox(self.controlArea, "Info", addSpace = True)
64        self.infoa = OWGUI.widgetLabel(box, 'No data loaded.')
65        self.infob = OWGUI.widgetLabel(box, '')
66        self.infoc = OWGUI.widgetLabel(box, '')
67           
68        # LIST VIEW
69        frmListView = OWGUI.widgetBox(self.controlArea, None, addSpace = True)
70        self.tree = QTreeWidget(frmListView)
71        self.tree.setSelectionMode(QAbstractItemView.MultiSelection)
72        self.tree.setHeaderLabel("Directory/Data File")
73        frmListView.layout().addWidget(self.tree)
74        self.connect(self.tree,SIGNAL('itemSelectionChanged()'),self.selectionChanged)
75
76        # Output
77        box = OWGUI.widgetBox(self.controlArea, "Output", addSpace = True)
78        OWGUI.checkBox(box, self, 'applyOnChange', 'Commit data on selection change')
79        self.commitBtn = OWGUI.button(box, self, "Commit", callback=self.sendData, disabled=1)
80        self.resize(300,600)
81
82        # initial settings           
83        self.recentDirs=filter(os.path.exists,self.recentDirs)
84        self.setDirlist()
85        self.dircombo.setCurrentIndex(0)
86        if self.recentDirs!=[] and loaddata:
87            self.loadData(self.recentDirs[0])
88           
89    def setFileTree(self):
90        self.disconnect(self.tree,SIGNAL('itemSelectionChanged()'),self.selectionChanged)
91        self.tree.clear()
92        self.listitems = []
93        for d in self.dataStructure:
94            (dirname, files) = d
95            diritem = QTreeWidgetItem(self.tree, [dirname], QTreeWidgetItem.UserType)
96            diritem.setSelected(1)
97            self.listitems.append(diritem)
98            diritem.setExpanded(1)
99            diritem.name = dirname
100            for f in files:
101                item = QTreeWidgetItem(diritem, [f.name], QTreeWidgetItem.UserType)
102                item.setSelected(1)
103                self.listitems.append(item)
104                item.data = f
105        self.connect(self.tree,SIGNAL('itemSelectionChanged()'),self.selectionChanged)
106               
107    def selectionChanged(self):
108        if self.applyOnChange:
109            self.sendData()
110
111    # checks which data has been selected, builds a data structure, and sends it out
112    def sendData(self):
113        data = []
114        # clear what has been previously sent
115        for id in self.lastSentIds:
116            self.send("Examples", None, id)
117        self.lastSentIds = []
118        # send new data
119        id = 0
120        for tIdx in range(self.tree.topLevelItemCount()):
121            dir = self.tree.topLevelItem(tIdx)
122            if dir in self.tree.selectedItems():
123                files = []
124                for cIdx in range(dir.childCount()):
125                    f = dir.child(cIdx)
126                    if f in self.tree.selectedItems():
127                        files.append(f.data)
128                        self.send("Examples", f.data, id)
129                        self.lastSentIds.append(id)
130                        id += 1
131                data.append((dir.name, files))
[1072]132        #print "DATAS", data
[975]133        self.send("Structured Data", data)
134
135    # Loads the data from a root directory, sends the data to the output channels
136    def loadData(self, root):
137        dataStructure = [] # structured [(dirname0, [d00, d01, ...]), ...]
138        datasets = []  # flat list containing all the data sets
139        dirs = os.listdir(root)
140        lenDirs = len(dirs)
141        if lenDirs:
142            self.progressBarInit()
143            pbStep = 100./lenDirs
144        for d in dirs:
[1072]145            dirname = os.path.join(root, d)
[975]146            if os.path.isdir(dirname):
147                dirdata = []   
148                files  = os.listdir(dirname)
149                for f in files:
150                    name, ext = os.path.splitext(f)
151                    if ext in ['.tab', '.txt', '.data']:
152                        try:
153                            data = None
[1072]154                            data = orange.ExampleTable(os.path.join(dirname,f))
[975]155                            data.name = name
156                            data.strain = os.path.basename(dirname)
157                            dirdata.append(data)
158                        except orange.KernelException:
159                            print 'Warning: file %s\\%s not in appropriate format' %(dirname, f)
160                if len(dirdata):
161                    dataStructure.append((os.path.split(dirname)[1], dirdata))
162                    datasets = datasets + dirdata
163            self.progressBarAdvance(pbStep)
164        if lenDirs:
165            self.progressBarFinished()
166
167        # enable commit, set file tree
168        self.commitBtn.setEnabled(len(dataStructure))
169        self.dataStructure = dataStructure
170        self.datasets = datasets
171        self.setFileTree()
172
173        # set infos (sumarize the data)
174        if len(dataStructure):
175            numSets = len(self.dataStructure)
176            numFiles = len(self.datasets)
177            self.infoa.setText("%d set%s, total of %d data file%s." % (numSets, ["", "s"][numSets!=1], numFiles, ["","s"][numFiles!=1]))
178            # construct lists that sumarize the data
179            numExamplesList = []
180            numAttrList = []
181            hasClass = []
182            attrNameList = []
183            for et in datasets:
184                numExamplesList.append(len(et))
185                numAttrList.append(len(et.domain.attributes))
186                hasClass.append(et.domain.classVar != None)
187                for attr in et.domain.attributes:
188                    if attr.name not in attrNameList:
189                        attrNameList.append(attr.name)
190            # report the number of attributes/class
191            if len(numAttrList):
192                minNumAttr = min(numAttrList)
193                maxNumAttr = max(numAttrList)
194                if minNumAttr != maxNumAttr:
195                    infob = "From %d to %d attribute%s (%d in total)" % (minNumAttr, maxNumAttr, ["","s"][maxNumAttr!=1], len(attrNameList))
196                else:
197                    infob = "%d attribute%s" % (maxNumAttr, ["","s"][maxNumAttr!=1])
198            else:
199                infob = "No attributes"
200            if sum(hasClass) == len(hasClass):
201                infob += ", all files contain class variable."
202            elif sum(hasClass) == 0:
203                infob += ", no class variable."
204            else:
205                infob += ", some files contain class variable."
206            self.infob.setText(infob)
207            # report the number of examples
208            if len(numExamplesList):
209                infoc = "Files contain "
210                minNumE = min(numExamplesList)
211                maxNumE = max(numExamplesList)
212                if minNumE == maxNumE:
213                    infoc += "%d example%s, " % (maxNumE, ["","s"][maxNumE!=1])
214                else:
215                    infoc += "from %d to %d example%s, " % (minNumE, maxNumE, ["","s"][maxNumE!=1])
216                infoc += "%d in total." % sum(numExamplesList)
217            else:
218                infoc = "Files contain no examples."
219            self.infoc.setText(infoc)
220
221            # Add a directory to the start of the file list.
222            # If it exists, move it to the start of the list
223            if root in self.recentDirs:
224                self.recentDirs.remove(root)
225            self.recentDirs.insert(0, root)
226            self.setDirlist()
227            self.selectedDirName = root
228               
229        else:
230            self.infoa.setText('No data on input.')
231            self.infob.setText('')
232            self.infoc.setText('')
233
234        # read data
235        if self.applyOnChange:
236            self.sendData()
237
238    # displays a file dialog and selects a directory
239    def browseDirectory(self):
240        if len(self.recentDirs):
241            startdir=self.recentDirs[0]
242        else:
243            startdir ="."
244        dirname=str(QFileDialog.getExistingDirectory(self, 'Data Directory', startdir, QFileDialog.ShowDirsOnly))
245        if len(dirname):
246            self.loadData(str(dirname))
247
248    def setDirlist(self):
249        self.dircombo.clear()
250        if len(self.recentDirs):
251            for dir in self.recentDirs:
252                (upperdir,dirname)=os.path.split(dir)
253                # leave out the path
254                self.dircombo.insertItem(self.dircombo.count(), dirname)
255        else:
256            self.dircombo.insertItem(0,"(none)")
257
258    # called when user makes a selection from the drop-down menu
259    def selectDir(self, n):
260        if self.recentDirs:
261            self.loadData(self.recentDirs[n])
262        else:
263            self.loadData("(none)")
264
265
266
267if __name__=="__main__":
268    a=QApplication(sys.argv)
269    ow=OWDataFiles()
270    ow.show()
[1072]271    ow.loadData("/home/marko/anova/smallchipdata")
[975]272    a.exec_()
273    ow.saveSettings()
Note: See TracBrowser for help on using the repository browser.