Source code for runtransit

#!/usr/bin/env python

# Copyright 2015.
#   Michael A. DeJesus, Chaitra Ambadipudi, and  Thomas R. Ioerger.
#
#
#    This file is part of TRANSIT.
#
#    TRANSIT is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License.
#
#
#    TRANSIT is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with TRANSIT.  If not, see <http://www.gnu.org/licenses/>.


#importing wx files

__version__ = "v2.0.0"



import sys
import wx
#Check if wx is the newest 3.0+ version:
try:
    from wx.lib.pubsub import pub
    pub.subscribe
    newWx = True
except AttributeError as e:
    from wx.lib.pubsub import Publisher as pub
    newWx = False

import os
import time
import datetime
import threading
import numpy
import matplotlib.pyplot as plt
import multiprocessing as mp
import math
import subprocess

from functools import partial

import traceback

# trash view stuff
import transit
import transit.analysis

import transit.trash as trash
import transit.transit_gui as transit_gui
import transit.transit_tools as transit_tools
import transit.tnseq_tools as tnseq_tools
import transit.norm_tools as norm_tools
import transit.fileDisplay as fileDisplay
import transit.qcDisplay as qcDisplay
import transit.images as images



method_wrap_width = 250
methods = transit.analysis.methods


wildcard = "Python source (*.py)|*.py|" \
            "All files (*.*)|*.*"
transit_prefix = "[TRANSIT]"

#inherit from the MainFrame created in wxFowmBuilder and create CalcFrame
[docs]class TnSeekFrame(transit_gui.MainFrame): #constructor def __init__(self,parent): #initialize parent class transit_gui.MainFrame.__init__(self,parent) self.SetIcon(images.transit_icon.GetIcon()) self.workdir = os.getcwd() self.annotation = "" self.transposons = ["himar1", "tn5"] #import pkgutil #print [x for x in pkgutil.iter_modules(['transit/analysis'])] #print gumbel.Gumbel.__bases__ self.logoImg.SetBitmap(images.transit_logo2.GetImage().ConvertToBitmap()) self.versionLabel.SetLabel(__version__) self.methodSizerText.Hide() self.index_ctrl = 0 self.list_ctrl.InsertColumn(0, 'File', width=210) self.list_ctrl.InsertColumn(1, 'Total Reads', width=85) self.list_ctrl.InsertColumn(2, 'Density', width=85) self.list_ctrl.InsertColumn(3, 'Mean Count', width=90) self.list_ctrl.InsertColumn(4, 'Max Count', width=85) self.list_ctrl.InsertColumn(5, 'Full Path', width=403) self.index_exp = 0 self.list_exp.InsertColumn(0, 'File', width=210) self.list_exp.InsertColumn(1, 'Total Reads', width=85) self.list_exp.InsertColumn(2, 'Density', width=85) self.list_exp.InsertColumn(3, 'Mean Count', width=90) self.list_exp.InsertColumn(4, 'Max Count', width=85) self.list_exp.InsertColumn(5, 'Full Path',width=403) self.index_file = 0 self.list_files.InsertColumn(0, 'Name', width=350) self.list_files.InsertColumn(1, 'Type', width=100) self.list_files.InsertColumn(2, 'Date', width=230) self.list_files.InsertColumn(3, 'Full Path',width=403) self.verbose = True self.statusBar.SetStatusText("Welcome to TRANSIT") self.progress_count = 0 pub.subscribe(self.setProgressRange, "progressrange") pub.subscribe(self.updateProgress, "progress") pub.subscribe(self.updateStatus, "status") pub.subscribe(self.addFile, "file") pub.subscribe(self.finishRun, "finish") pub.subscribe(self.saveHistogram, "histogram") #self.outputDirPicker.SetPath(os.path.dirname(os.path.realpath(__file__))) methodChoiceChoices = [ "[Choose Method]"] for name in methods: methods[name].gui.definePanel(self) #methods[name].gui.panel.BackgroundColour = (0, 200, 20) self.methodSizer.Add(methods[name].gui.panel, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) methods[name].gui.Hide() if "himar1" in methods[name].transposons: tempMenuItem = wx.MenuItem( self.himar1MenuItem, wx.ID_ANY, methods[name].fullname(), wx.EmptyString, wx.ITEM_NORMAL ) self.Bind( wx.EVT_MENU, partial(self.MethodSelectFunc, methods[name].fullname()), tempMenuItem ) self.himar1MenuItem.AppendItem( tempMenuItem ) if "tn5" in methods[name].transposons: tempMenuItem = wx.MenuItem( self.tn5MenuItem, wx.ID_ANY, methods[name].fullname(), wx.EmptyString, wx.ITEM_NORMAL ) self.Bind( wx.EVT_MENU, partial(self.MethodSelectFunc, methods[name].fullname()), tempMenuItem ) self.tn5MenuItem.AppendItem( tempMenuItem ) #progress self.progressPanel = wx.Panel( self.optionsWindow, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL ) progressSizer = wx.BoxSizer( wx.VERTICAL ) self.progressLabel = wx.StaticText( self.progressPanel, wx.ID_ANY, u"Progress", wx.DefaultPosition, wx.DefaultSize, 0 ) self.progressLabel.Wrap( -1 ) progressSizer.Add( self.progressLabel, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) self.progress = wx.Gauge( self.progressPanel, wx.ID_ANY, 20, wx.DefaultPosition, wx.DefaultSize, wx.GA_HORIZONTAL|wx.GA_SMOOTH ) progressSizer.Add( self.progress, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) #self.progressPanel.BackgroundColour = (0, 0, 250) self.progressPanel.SetSizer( progressSizer ) self.progressPanel.SetMaxSize(wx.Size(100, 100)) self.progressPanel.Layout() #progressSizer.Fit( self.progressPanel ) self.methodSizer.Add( self.progressPanel, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) #self.methodSizer.Add( self.globalLabel, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) #self.methodSizer.Hide() self.progress.SetRange(50) ######### self.optionsWindow.Fit() self.HideProgressSection() self.HideGlobalOptions()
[docs] def Exit(self, event): """Exit Menu Item""" if self.verbose: transit_tools.transit_message("Exiting Transit") self.Close()
[docs] def updateProgress(self, msg): """""" if newWx: method, count = msg else: method, count = msg.data self.progress_count = count try: self.progress.SetValue(self.progress_count) except: pass
[docs] def setProgressRange(self, msg): """""" if newWx: count = msg else: count = msg.data try: self.progress.SetRange(count) except: pass
[docs] def updateStatus(self, msg): """""" if newWx: method, text = msg else: method, text = msg.data self.statusBar.SetStatusText(text)
[docs] def saveHistogram(self, msg): if newWx: data, orf, path, delta = msg else: data, orf, path, delta = msg.data n, bins, patches = plt.hist(data, normed=1, facecolor='c', alpha=0.75, bins=100) plt.xlabel('Delta Sum') plt.ylabel('Probability') plt.title('%s - Histogram of Delta Sum' % orf) plt.axvline(delta, color='r', linestyle='dashed', linewidth=3) plt.grid(True) genePath = os.path.join(path, orf +".png") plt.savefig(genePath) plt.clf()
[docs] def addFile(self, data): if not newWx: data = data.data fullpath = data["path"] name = transit_tools.basename(fullpath) type = data["type"] date = data["date"] self.list_files.InsertStringItem(self.index_file, name) self.list_files.SetStringItem(self.index_file, 1, "%s" % type) self.list_files.SetStringItem(self.index_file, 2, "%s" % (date)) self.list_files.SetStringItem(self.index_file, 3, "%s" % (fullpath)) self.index_file+=1
[docs] def finishRun(self,msg): if not newWx: msg = msg.data try: #methods[msg].gui.Enable() pass except Exception as e: transit_tools.transit_message("Error: %s" % e) exc_type, exc_obj, exc_tb = sys.exc_info() fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] print(exc_type, fname, exc_tb.tb_lineno)
[docs] def ResetProgress(self): self.progress_count = 0
[docs] def HideAllOptions(self): self.HideGlobalOptions() self.HideProgressSection() for name in methods: methods[name].gui.Hide()
[docs] def HideGlobalOptions(self): self.globalLabel.Hide() self.globalNTerminusLabel.Hide() self.globalCTerminusLabel.Hide() self.globalNTerminusText.Hide() self.globalCTerminusText.Hide()
[docs] def ShowGlobalOptions(self): self.globalLabel.Show() self.globalNTerminusLabel.Show() self.globalCTerminusLabel.Show() self.globalNTerminusText.Show() self.globalCTerminusText.Show()
[docs] def HideProgressSection(self): self.progressLabel.Hide() self.progress.Hide()
[docs] def ShowProgressSection(self): self.progressLabel.Show() self.progress.Show()
[docs] def onHimar1Checked(self, event): if self.methodCheckBoxHimar1.GetValue(): self.transposons.append("himar1") else: self.transposons.remove("himar1") self.filterMethodsByTransposon()
[docs] def onTn5Checked(self, event): if self.methodCheckBoxTn5.GetValue(): self.transposons.append("tn5") else: self.transposons.remove("tn5") self.filterMethodsByTransposon()
[docs] def filterMethodsByTransposon(self): newmethods = {} fullmethods = transit.analysis.methods goodTn = False for method in fullmethods: goodTn = False for tn in self.transposons: if tn in fullmethods[method].transposons: goodTn = True if goodTn: newmethods[method] = fullmethods[method] methodChoiceChoices = [ "[Choose Method]"] for name in newmethods: methodChoiceChoices.append(methods[name].fullname()) self.methodChoice.SetItems(methodChoiceChoices) self.methodChoice.SetSelection( 0 )
[docs] def SaveFile(self, DIR=None, FILE="", WC=""): """ Create and show the Save FileDialog """ path = "" if not DIR: DIR = os.getcwd() dlg = wx.FileDialog( self, message="Save file as ...", defaultDir=DIR, defaultFile=FILE, wildcard=WC, style=wx.SAVE|wx.OVERWRITE_PROMPT ) if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() if self.verbose: transit_tools.transit_message("You chose the following output filename: %s" % path) dlg.Destroy() return path
[docs] def OpenFile(self, DIR=".", FILE="", WC=""): """ Create and show the Open FileDialog """ path = "" dlg = wx.FileDialog( self, message="Save file as ...", defaultDir=DIR, defaultFile=FILE, wildcard=WC, style=wx.OPEN ) if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() if self.verbose: transit_tools.transit_message("You chose the following file: %s" % path) dlg.Destroy() return path
[docs] def ctrlSelected(self, col=5): selected_ctrl = [] current = -1 while True: next = self.list_ctrl.GetNextSelected(current) if next == -1: break path = self.list_ctrl.GetItem(next, col).GetText() selected_ctrl.append(path) current = next return selected_ctrl
[docs] def expSelected(self, col=5): selected_exp = [] current = -1 while True: next = self.list_exp.GetNextSelected(current) if next == -1: break path = self.list_exp.GetItem(next, col).GetText() selected_exp.append(path) current = next return selected_exp
[docs] def allSelected(self, col=5): selected_all = self.ctrlSelected(col) + self.expSelected(col) return selected_all
[docs] def ctrlAll(self, col=5): all_ctrl = [] for i in range(self.list_ctrl.GetItemCount()): all_ctrl.append(self.list_ctrl.GetItem(i, col).GetText()) return all_ctrl
[docs] def expAll(self, col=5): all_exp = [] for i in range(self.list_exp.GetItemCount()): all_exp.append(self.list_exp.GetItem(i, col).GetText()) return all_exp
[docs] def loadCtrlFileFunc(self, event): self.statusBar.SetStatusText("Loading Control Dataset(s)...") try: dlg = wx.FileDialog( self, message="Choose a file", defaultDir=self.workdir, defaultFile="", wildcard=u"Read Files (*.wig)|*.wig;|\nRead Files (*.txt)|*.txt;|\nRead Files (*.dat)|*.dat;|\nAll files (*.*)|*.*", style=wx.OPEN | wx.MULTIPLE | wx.CHANGE_DIR ) if dlg.ShowModal() == wx.ID_OK: paths = dlg.GetPaths() print "You chose the following Control file(s):" for fullpath in paths: print "\t%s" % fullpath name = transit_tools.basename(fullpath) (density, meanrd, nzmeanrd, nzmedianrd, maxrd, totalrd, skew, kurtosis) = transit_tools.get_wig_stats(fullpath) self.list_ctrl.InsertStringItem(self.index_ctrl, name) self.list_ctrl.SetStringItem(self.index_ctrl, 1, "%1.1f" % (totalrd)) self.list_ctrl.SetStringItem(self.index_ctrl, 2, "%2.1f" % (density*100)) self.list_ctrl.SetStringItem(self.index_ctrl, 3, "%1.1f" % (meanrd)) self.list_ctrl.SetStringItem(self.index_ctrl, 4, "%d" % (maxrd)) self.list_ctrl.SetStringItem(self.index_ctrl, 5, "%s" % (fullpath)) self.index_ctrl+=1 dlg.Destroy() except Exception as e: transit_tools.transit_message("Error: %s" % e) print "PATH", fullpath exc_type, exc_obj, exc_tb = sys.exc_info() fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] print(exc_type, fname, exc_tb.tb_lineno) self.statusBar.SetStatusText("")
[docs] def loadExpFileFunc(self, event): self.statusBar.SetStatusText("Loading Experimental Dataset(s)...") try: dlg = wx.FileDialog( self, message="Choose a file", defaultDir=self.workdir, defaultFile="", wildcard=u"Read Files (*.wig)|*.wig;|\nRead Files (*.txt)|*.txt;|\nRead Files (*.dat)|*.dat;|\nAll files (*.*)|*.*", style=wx.OPEN | wx.MULTIPLE | wx.CHANGE_DIR ) if dlg.ShowModal() == wx.ID_OK: paths = dlg.GetPaths() print "You chose the following Experimental file(s):" for fullpath in paths: print "\t%s" % fullpath name = transit_tools.basename(fullpath) (density, meanrd, nzmeanrd, nzmedianrd, maxrd, totalrd, skew, kurtosis) = transit_tools.get_wig_stats(fullpath) self.list_exp.InsertStringItem(self.index_exp, name) self.list_exp.SetStringItem(self.index_exp, 1, "%1.1f" % (totalrd)) self.list_exp.SetStringItem(self.index_exp, 2, "%2.1f" % (density*100)) self.list_exp.SetStringItem(self.index_exp, 3, "%1.1f" % (meanrd)) self.list_exp.SetStringItem(self.index_exp, 4, "%d" % (maxrd)) self.list_exp.SetStringItem(self.index_exp, 5, "%s" % (fullpath)) self.index_exp+=1 dlg.Destroy() except Exception as e: transit_tools.transit_message("Error: %s" % e) print "PATH", fullpath exc_type, exc_obj, exc_tb = sys.exc_info() fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] print(exc_type, fname, exc_tb.tb_lineno) self.statusBar.SetStatusText("")
[docs] def ctrlRemoveFunc(self, event): next = self.list_ctrl.GetNextSelected(-1) while next != -1: if self.verbose: transit_tools.transit_message("Removing control item (%d): %s" % (next, self.list_ctrl.GetItem(next, 0).GetText())) self.list_ctrl.DeleteItem(next) next = self.list_ctrl.GetNextSelected(-1) self.index_ctrl-=1
[docs] def expRemoveFunc(self, event): next = self.list_exp.GetNextSelected(-1) while next != -1: if self.verbose: transit_tools.transit_message("Removing experimental item (%d): %s" % (next, self.list_exp.GetItem(next, 0).GetText())) self.list_exp.DeleteItem(next) next = self.list_exp.GetNextSelected(-1) self.index_exp-=1
[docs] def allViewFunc(self, event, gene=""): annotationpath = self.annotation datasets = self.ctrlSelected() + self.expSelected() if datasets and annotationpath: if self.verbose: transit_tools.transit_message("Visualizing counts for: %s" % ", ".join([transit_tools.fetch_name(d) for d in datasets])) viewWindow = trash.TrashFrame(self, datasets, annotationpath, gene) viewWindow.Show() elif not datasets: transit_tools.ShowError("Error: No datasets selected.") return else: transit_tools.ShowError("Error: No annotation file selected.") return
[docs] def ctrlViewFunc(self, event, gene=""): annotationpath = self.annotation datasets = self.ctrlSelected() if datasets and annotationpath: if self.verbose: transit_tools.transit_message("Visualizing counts for: %s" % ", ".join([transit_tools.fetch_name(d) for d in datasets])) viewWindow = trash.TrashFrame(self, datasets, annotationpath, gene) viewWindow.Show() elif not datasets: if self.verbose: transit_tools.transit_message("No datasets selected to visualize!") else: if self.verbose: transit_tools.transit_message("No annotation file selected")
[docs] def expViewFunc(self, event, gene=""): annotationpath = self.annotation datasets = self.expSelected() if datasets and annotationpath: if self.verbose: transit_tools.transit_message("Visualizing counts for: %s" % ", ".join([transit_tools.fetch_name(d) for d in datasets])) viewWindow = trash.TrashFrame(self, datasets, annotationpath, gene) viewWindow.Show() elif not datasets: if self.verbose: transit_tools.transit_message("No datasets selected to visualize!") else: if self.verbose: transit_tools.transit_message("No annotation file selected")
[docs] def scatterFunc(self, event): """ """ #annotationpath = self.annotation datasets = self.ctrlSelected() + self.expSelected() if len(datasets) == 2: if self.verbose: transit_tools.transit_message("Showing scatter plot for: %s" % ", ".join([transit_tools.fetch_name(d) for d in datasets])) (data, position) = transit_tools.get_data(datasets) X = data[0,:] Y = data[1,:] plt.plot(X,Y, "bo") plt.title('Scatter plot - Reads at TA sites') plt.xlabel(transit_tools.fetch_name(datasets[0])) plt.ylabel(transit_tools.fetch_name(datasets[1])) plt.show() else: transit_tools.ShowError(MSG="Please make sure only two datasets are selected (across control and experimental datasets).")
[docs] def qcFunc(self, event): datasets = self.allSelected() nfiles = len(datasets) if nfiles == 0: transit_tools.transit_message("You must select atleast one dataset control or experimental dataset.") transit_tools.ShowError(MSG="You must select atleast one dataset control or experimental dataset.") elif nfiles >= 1: transit_tools.transit_message("Displaying results: %s" % datasets[0]) try: qcWindow = qcDisplay.qcFrame(self, datasets) qcWindow.Show() except Exception as e: transit_tools.transit_message("Error occured displaying file: %s" % str(e)) traceback.print_exc()
[docs] def aboutFunc(self, event): description = """TRANSIT is a tool for analysing TnSeq data. It provides an easy to use graphical interface and access to several different analysis methods that allow the user to determine essentiality within a single condition as well as between two conditions. If you need to cite this tool, please use the following reference: DeJesus, M.A., Ambadipudi, C., Baker, R., Sassetti, C., and Ioerger, T.R. (2015). TRANSIT - a Software Tool for Himar1 TnSeq Analysis. PLOS Computational Biology, 11(10):e1004401 """ licence = """ TRANSIT is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License. TRANSIT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with TRANSIT. If not, see <http://www.gnu.org/licenses/>. """ info = wx.AboutDialogInfo() #info.SetIcon(wx.Icon('hunter.png', wx.BITMAP_TYPE_PNG)) info.SetName('TRANSIT') info.SetVersion(__version__) info.SetDescription(description) info.SetCopyright('(C) 2015 - 2016\n Michael A. DeJesus\nThomas R. Ioerger') info.SetWebSite('http://saclab.tamu.edu/essentiality/transit/') info.SetLicence(licence) info.AddDeveloper('Michael A. DeJesus') info.AddDeveloper('Thomas R. Ioerger') info.AddDeveloper('Chaitra Ambadipudi') info.AddDeveloper('Richard Baker') info.AddDeveloper('Christopher Sassetti') info.AddDeveloper('Eric Nelson') #info.AddDocWriter('Jan Bodnar') #info.AddArtist('The Tango crew') #info.AddTranslator('Jan Bodnar') wx.AboutBox(info)
[docs] def documentationFunc(self, event): filepath = "http://saclab.tamu.edu/essentiality/transit/transit.html" output = "" error = "" try: if sys.platform.startswith('darwin'): OS = "OSX" #subprocess.call(('open', filepath)) args = ["open", filepath] output,error = subprocess.Popen(args,stdout = subprocess.PIPE, stderr= subprocess.PIPE).communicate() elif os.name == 'nt': OS = "Windows" os.startfile(filepath) elif os.name == 'posix': OS = "Linux" args = ["xdg-open", filepath] output,error = subprocess.Popen(args,stdout = subprocess.PIPE, stderr= subprocess.PIPE).communicate() if "not found" in error: args = ["exo-open", filepath] output,error = subprocess.Popen(args,stdout = subprocess.PIPE, stderr= subprocess.PIPE).communicate() except Exception as e: error_text = """Error occurred opening documentation URL.\nYour browser or OS may not be configured correctly.""" transit_tools.ShowError(MSG=error_text) traceback.print_exc()
[docs] def annotationFileFunc(self, event): wc = u"Prot Table (*.prot_table)|*.prot_table;|\nProt Table (*.txt)|*.txt;|\nProt Table (*.dat)|*.dat;|\nAll files (*.*)|*.*" self.annotation = self.OpenFile(DIR=self.workdir, FILE="", WC=wc) if self.annotation: self.annotationFilePicker.SetLabel(transit_tools.basename(self.annotation)) if self.verbose: transit_tools.transit_message("Annotation File Selected: %s" % self.annotation) else: self.annotationFilePicker.SetLabel("[Click to add Annotation File (.prot_table)]")
[docs] def MethodSelectFunc(self, selected_name, test=""): #X = self.methodChoice.GetCurrentSelection() #selected_name = self.methodChoice.GetString(X) #If empty is selected if selected_name == "[Choose Method]": self.HideAllOptions() self.methodInfoText.SetLabel(u"Instructions") self.methodInstructions.Show() self.methodInstructions.SetLabel(self.instructions_text) self.methodInstructions.Wrap(method_wrap_width) self.methodShortText.Hide() self.methodLongText.Hide() self.methodTnText.Hide() self.methodDescText.Hide() self.method_choice = "" else: self.ShowGlobalOptions() self.methodSizerText.Show() #Show Selected Method and hide Others for name in methods: methods[name].gui.Hide() if methods[name].fullname() == selected_name: self.methodInfoText.SetLabel("%s" % methods[name].short_name) #self.methodShortText.SetLabel("[%s]" % methods[name].short_name) #self.methodShortText.Wrap(250) #self.methodLongText.SetLabel(methods[name].long_name) #self.methodLongText.Wrap(250) self.methodTnText.SetLabel(methods[name].getTransposonsText()) self.methodTnText.Wrap(250) self.methodTnText.Show() self.methodDescText.SetLabel(methods[name].getDescriptionText()) self.methodDescText.Wrap(250) self.methodDescText.Show() self.methodInstructions.SetLabel("") methods[name].gui.Show() self.statusBar.SetStatusText("[%s]" % methods[name].short_name) else: methods[name].gui.Hide() self.ShowProgressSection() self.method_choice = selected_name self.Layout() if self.verbose: transit_tools.transit_message("Selected Method: %s" % (selected_name))
[docs] def displayFileFunc(self, event): next = self.list_files.GetNextSelected(-1) if next > -1: dataset = self.list_files.GetItem(next, 3).GetText() if self.verbose: transit_tools.transit_message("Displaying results: %s" % self.list_files.GetItem(next, 0).GetText()) try: #fileWindow = fileDisplay.FileFrame(self, dataset, self.list_files.GetItem(next, 1).GetText()) fileWindow = fileDisplay.TransitGridFrame(self, dataset) fileWindow.Show() except Exception as e: transit_tools.transit_message("Error occurred displaying file: %s" % str(e)) traceback.print_exc() else: if self.verbose: transit_tools.transit_message("No results selected to display!")
[docs] def fileSelected(self,event): next = self.list_files.GetNextSelected(-1) if next > -1: dataset_path = self.list_files.GetItem(next, 3).GetText() dataset_name = self.list_files.GetItem(next, 0).GetText() dataset_type = self.list_files.GetItem(next, 1).GetText() self.updateGraphChoices(dataset_type) else: pass
[docs] def updateGraphChoices(self, dataset_type): empty_action = "[Choose Action]" if dataset_type == "Gumbel": choices = [empty_action, "Plot Ranked Probability of Essentiality"] elif dataset_type == "Binomial": choices = [empty_action, "Plot Ranked Probability of Essentiality"] elif dataset_type == "HMM - Sites": choices = [empty_action] elif dataset_type == "HMM - Genes": choices = [empty_action] elif dataset_type == "Resampling": choices = [empty_action, "Create a Volcano Plot", "Plot Histogram of logFC of Gene Counts"] elif dataset_type == "DE-HMM - Sites": choices = [empty_action, "Recreate Sites File"] elif dataset_type == "DE-HMM - Segments": choices = [empty_action] else: choices = [empty_action] self.fileActionChoice.SetItems(choices) self.fileActionChoice.SetSelection(0)
[docs] def fileActionFunc(self, event): # 0 - nothing # 1 - Volcano # 2 - Hist gene counts ratio plot_choice = self.fileActionChoice.GetCurrentSelection() plot_name = self.fileActionChoice.GetString(plot_choice) if plot_name == "[Choose Action]": return next = self.list_files.GetNextSelected(-1) if next > -1: dataset_path = self.list_files.GetItem(next, 3).GetText() dataset_name = self.list_files.GetItem(next, 0).GetText() dataset_type = self.list_files.GetItem(next, 1).GetText() if self.verbose: transit_tools.transit_message("Performing the '%s' action on dataset '%s'" % (plot_name, dataset_name)) if plot_name == "Create a Volcano Plot": self.graphVolcanoPlot(dataset_name, dataset_type, dataset_path) elif plot_name == "Plot Histogram of logFC of Gene Counts": self.graphGeneCounts(dataset_name, dataset_type, dataset_path) elif plot_name == "Plot Ranked Probability of Essentiality": self.graphRankedZbar(dataset_name, dataset_type, dataset_path) else: return self.fileActionChoice.SetSelection(0) else: transit_tools.ShowError(MSG="Please select a results file to plot!")
[docs] def graphGeneCounts(self, dataset_name, dataset_type, dataset_path): try: if dataset_type == "Resampling": X = [] for line in open(dataset_path): if line.startswith("#"): continue tmp = line.strip().split("\t") try: log2FC = float(tmp[7]) except: log2FC = 0 X.append(log2FC) n, bins, patches = plt.hist(X, normed=1, facecolor='c', alpha=0.75, bins=100) plt.xlabel('log2 FC - Total Gene Counts') plt.ylabel('Probability') plt.title('Histogram of log2 Fold Change for Total Normalized Counts within Genes') plt.axvline(0, color='r', linestyle='dashed', linewidth=3) plt.grid(True) plt.show() plt.close() else: transit_tools.ShowError(MSG="Need to select a 'Resampling' results file for this type of plot.") except Exception as e: transit_tools.transit_message("Error occurred creating plot: %s" % str(e)) traceback.print_exc()
[docs] def graphVolcanoPlot(self, dataset_name, dataset_type, dataset_path): try: if dataset_type == "Resampling": X = []; Y = []; for line in open(dataset_path): if line.startswith("#"): continue tmp = line.strip().split("\t") try: #log2FC = math.log(float(tmp[6])/float(tmp[5]),2) log2FC = float(tmp[7]) log10qval = -math.log(float(tmp[-1].strip()), 10) except: log2FC = 0 log10qval = 0 #log2FC = 1 #log10qval = 1 X.append(log2FC) Y.append(log10qval) plt.plot(X,Y, "bo") plt.xlabel("Log Fold Change (base 2)") plt.ylabel("-Log q-value (base 10)") plt.title("Resampling - Volcano plot") plt.show() plt.close() else: transit_tools.ShowError(MSG="Need to select a 'Resampling' results file for this type of plot.") except Exception as e: print "Error occurred creating plot:", str(e)
[docs] def graphRankedZbar(self, dataset_name, dataset_type, dataset_path): try: X = []; Y = []; for line in open(dataset_path): if line.startswith("#"): continue tmp = line.strip().split("\t") try: #log2FC = math.log(float(tmp[6])/float(tmp[5]),2) zbar = float(tmp[-2]) except: zbar = 0 Y.append(zbar) Y.sort() index=range(1,len(Y)+1) plt.plot(index,Y, "bo") plt.xlabel("Rank of Gene According to Probability of Essentiality") plt.ylabel("Probability of Essentiality") plt.title("Ranked Probability of Essentiality") plt.show() plt.close() except Exception as e: print "Error occurred creating plot:", str(e)
[docs] def LoessPrevFunc(self,event): datasets_selected = self.ctrlSelected() + self.expSelected() if not datasets_selected: transit_tools.ShowError(MSG="Need to select at least one control or experimental dataset.") return data, position = transit_tools.get_data(datasets_selected) (K,N) = data.shape window = 100 for j in range(K): size = len(position)/window + 1 x_w = numpy.zeros(size) y_w = numpy.zeros(size) for i in range(size): x_w[i] = window*i y_w[i] = sum(data[j][window*i:window*(i+1)]) y_smooth = transit_tools.loess(x_w, y_w, h=10000) plt.plot(x_w, y_w, "g+") plt.plot(x_w, y_smooth, "b-") plt.xlabel("Genomic Position") plt.ylabel("Reads per 100 insertion sites") plt.title("LOESS Fit - %s" % transit_tools.basename(datasets_selected[j]) ) plt.show() plt.close()
[docs] def addFileFunc(self, event): try: dlg = wx.FileDialog( self, message="Choose a file", defaultDir=self.workdir, defaultFile="", wildcard=u"Results Files (*.dat)|*.dat;|\nResults Files (*.txt)|*.txt;|\nAll files (*.*)|*.*", style=wx.OPEN | wx.MULTIPLE | wx.CHANGE_DIR ) if dlg.ShowModal() == wx.ID_OK: paths = dlg.GetPaths() print "You chose the following Results file(s):" for fullpath in paths: print "\t%s" % fullpath name = transit_tools.basename(fullpath) line = open(fullpath).readline() if line.startswith("#Gumbel"): type = "Gumbel" elif line.startswith("#Binomial"): type = "Binomial" elif line.startswith("#HMM - Sites"): type = "HMM - Sites" elif line.startswith("#HMM - Genes"): type = "HMM - Genes" elif line.startswith("#Resampling"): type = "Resampling" elif line.startswith("#DE-HMM - Sites"): type = "DE-HMM - Sites" elif line.startswith("#DE-HMM - Segments"): type = "DE-HMM - Segments" else: type = "Unknown" data = {"path":fullpath, "type":type, "date": datetime.datetime.today().strftime("%B %d, %Y %I:%M%p")} if newWx: wx.CallAfter(pub.sendMessage, "file", data=data) else: wx.CallAfter(pub.sendMessage, "file", data) dlg.Destroy() except Exception as e: transit_tools.transit_message("Error: %s" % e) print "PATH", fullpath exc_type, exc_obj, exc_tb = sys.exc_info() fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] print(exc_type, fname, exc_tb.tb_lineno)
[docs] def choseMethodsMenu(self, selected_name, event): if self.verbose: transit_tools.transit_message("Selected Method: %s" % (selected_name)) self.MethodSelectFunc(selected_name)
[docs] def convertToIGVGUI(self, datasets): annotationPath = self.annotation if datasets and annotationPath: defaultFile = "read_counts.igv" defaultDir = os.getcwd() outputPath = self.SaveFile(defaultDir, defaultFile) if not outputPath: return if self.verbose: transit_tools.transit_message("Converting the following datasets to IGV format: %s" % ", ".join([transit_tools.fetch_name(d) for d in datasets])) self.convertToIGV(datasets, annotationPath, outputPath) if self.verbose: transit_tools.transit_message("Finished conversion") elif not datasets: transit_tools.ShowError("Error: No datasets selected to convert!") elif not annotationPath: transit_tools.ShowError("Error: No annotation file selected.") else: pass
[docs] def convertToIGV(self, dataset_list, annotationPath, path): normchoice = self.chooseNormalization() if not normchoice: normchoice = "nonorm" (fulldata, position) = tnseq_tools.get_data(dataset_list) (fulldata, factors) = norm_tools.normalize_data(fulldata, normchoice, dataset_list, annotationPath) position = position.astype(int) output = open(path, "w") output.write("#Converted to IGV with TRANSIT.\n") if normchoice != "nonorm": output.write("#Reads normalized using '%s'\n" % normchoice) output.write("#Files:\n#%s\n" % "\n#".join(dataset_list)) output.write("#Chromosome\tStart\tEnd\tFeature\t%s\tTAs\n" % ("\t".join([transit_tools.fetch_name(D) for D in dataset_list]))) chrom = transit_tools.fetch_name(annotationPath) for i,pos in enumerate(position): output.write("%s\t%s\t%s\tTA%s\t%s\t1\n" % (chrom, position[i], position[i]+1, position[i], "\t".join(["%1.1f" % fulldata[j][i] for j in range(len(fulldata))]))) output.close()
[docs] def convertToCombinedWigGUI(self, datasets): annotationPath = self.annotation if datasets and annotationPath: defaultFile = "combined_read_counts.txt" defaultDir = os.getcwd() outputPath = self.SaveFile(defaultDir, defaultFile) if not outputPath: return if self.verbose: transit_tools.transit_message("Converting the following datasets to Combined Wig format: %s" % ", ".join([transit_tools.fetch_name(d) for d in datasets])) self.convertToCombinedWig(datasets, annotationPath, outputPath) if self.verbose: transit_tools.transit_message("Finished conversion") elif not datasets: transit_tools.ShowError("Error: No datasets selected to convert!") elif not annotationPath: transit_tools.ShowError("Error: No annotation file selected.") else: pass
[docs] def convertToCombinedWig(self, dataset_list, annotationPath, path): normchoice = self.chooseNormalization() if not normchoice: normchoice = "nonorm" (fulldata, position) = tnseq_tools.get_data(dataset_list) (fulldata, factors) = norm_tools.normalize_data(fulldata, normchoice, dataset_list, annotationPath) position = position.astype(int) hash = tnseq_tools.get_pos_hash(annotationPath) rv2info = tnseq_tools.get_gene_info(annotationPath) output = open(path, "w") output.write("#Converted to CombinedWig with TRANSIT.\n") if normchoice != "nonorm": output.write("#Reads normalized using '%s'\n" % normchoice) (K,N) = fulldata.shape output.write("#Files:\n") for f in dataset_list: output.write("#%s\n" % f) for i,pos in enumerate(position): #output.write("%s\t%s\t%s\n" % (position[i], "\t".join(["%1.1f" % fulldata[j][i] for j in range(K)]), ",".join(["%s (%s)" % (orf,rv2info.get(orf,["-"])[0]) for orf in hash.get(position[i], [])]) ) ) output.write("%-10d %s %s\n" % (position[i], "".join(["%7.1f" % c for c in fulldata[:,i]]),",".join(["%s (%s)" % (orf,rv2info.get(orf,["-"])[0]) for orf in hash.get(position[i], [])]) )) output.close()
[docs] def chooseNormalization(self): dlg = wx.SingleChoiceDialog( self, "Choose how to normalize read-counts accross datasets.", 'Normalization Choice', ["nonorm", "nzmean", "totreads", "TTR", "zinfnb", "quantile", "betageom", "aBGC", "emphist"], wx.CHOICEDLG_STYLE ) if dlg.ShowModal() == wx.ID_OK: transit_tools.transit_message("Selected the '%s' normalization method" % dlg.GetStringSelection()) dlg.Destroy() return dlg.GetStringSelection()
[docs] def selectedToIGV(self, event): datasets = self.ctrlSelected() + self.expSelected() self.convertToIGVGUI(datasets)
[docs] def selectedToCombinedWig(self, event): datasets = self.ctrlSelected() + self.expSelected() self.convertToCombinedWigGUI(datasets)
[docs] def annotationPT_to_GFF3(self, event): annotationpath = self.annotation defaultFile = transit_tools.fetch_name(annotationpath) + ".gff3" #defaultDir = os.path.dirname(os.path.realpath(__file__)) defaultDir = os.getcwd() outputPath = self.SaveFile(defaultDir, defaultFile) ORGANISM = transit_tools.fetch_name(annotationpath) if not annotationpath: transit_tools.ShowError("Error: No annotation file selected.") elif outputPath: if self.verbose: transit_tools.transit_message("Converting annotation file from prot_table format to GFF3 format") year = time.localtime().tm_year month = time.localtime().tm_mon day = time.localtime().tm_mday output = open(outputPath, "w") output.write("##gff-version 3\n") output.write("##converted to IGV with TRANSIT.\n") output.write("##date %d-%d-%d\n" % (year, month, day)) output.write("##Type DNA %s\n" % ORGANISM) for line in open(annotationpath): if line.startswith("#"): continue tmp = line.strip().split("\t") desc = tmp[0]; start = int(tmp[1]); end = int(tmp[2]); strand = tmp[3]; length = tmp[4]; name = tmp[7]; orf = tmp[8]; ID = name desc.replace("%", "%25").replace(";", "%3B").replace("=","%3D").replace(",","%2C") output.write("%s\tRefSeq\tgene\t%d\t%d\t.\t%s\t.\tID=%s;Name=%s;Alias=%s;locus_tag=%s;desc=%s\n" % (ORGANISM, start, end, strand, orf,ID, orf, orf,desc)) output.close() if self.verbose: transit_tools.transit_message("Finished conversion")
[docs] def annotationPT_to_PTT(self, event): annotationpath = self.annotation defaultFile = transit_tools.fetch_name(annotationpath) + ".ptt.table" #defaultDir = os.path.dirname(os.path.realpath(__file__)) defaultDir = os.getcwd() datasets = self.ctrlSelected() + self.expSelected() if not annotationpath: transit_tools.ShowError("Error: No annotation file selected.") elif not datasets: transit_tools.ShowError("Error: Please add a .wig dataset, to determine TA sites.") else: outputPath = self.SaveFile(defaultDir, defaultFile) if not outputPath: return if self.verbose: transit_tools.transit_message("Converting annotation file from prot_table format to PTT format") (data, position) = transit_tools.get_data(datasets) orf2info = transit_tools.get_gene_info(annotationpath) hash = transit_tools.get_pos_hash(annotationpath) (orf2reads, orf2pos) = transit_tools.get_gene_reads(hash, data, position, orf2info) output = open(outputPath, "w") output.write("geneID\tstart\tend\tstrand\tTA coordinates\n") for line in open(annotationpath): if line.startswith("#"): continue tmp = line.strip().split("\t") orf = tmp[8] name = tmp[7] desc = tmp[0] start = int(tmp[1]) end = int(tmp[2]) strand = tmp[3] ta_str = "no TAs" if orf in orf2pos: ta_str = "\t".join([str(int(ta)) for ta in orf2pos[orf]]) output.write("%s\t%s\t%s\t%s\t%s\n" % (orf, start, end, strand, ta_str)) output.close() if self.verbose: transit_tools.transit_message("Finished conversion")
[docs] def annotationPTT_to_PT(self, event): annotationpath = self.annotation defaultFile = transit_tools.fetch_name(annotationpath) + ".prot_table" #defaultDir = os.path.dirname(os.path.realpath(__file__)) defaultDir = os.getcwd() datasets = self.ctrlSelected() + self.expSelected() if not annotationpath: transit_tools.ShowError("Error: No annotation file selected.") #elif not datasets: # transit_tools.ShowError("Error: Please add a .wig dataset, to determine TA sites.") else: outputPath = self.SaveFile(defaultDir, defaultFile) if not outputPath: return if self.verbose: transit_tools.transit_message("Converting annotation file from PTT format to prot_table format") #(data, position) = transit_tools.get_data(datasets) #orf2info = transit_tools.get_gene_info(annotationpath) #hash = transit_tools.get_pos_hash(annotationpath) #(orf2reads, orf2pos) = transit_tools.get_gene_reads(hash, data, position, orf2info) output = open(outputPath, "w") #output.write("geneID\tstart\tend\tstrand\tTA coordinates\n") for line in open(annotationpath): if line.startswith("#"): continue if line.startswith("geneID"): continue tmp = line.strip().split("\t") orf = tmp[0] if orf == "intergenic": continue name = "-" desc = "-" start = int(tmp[1]) end = int(tmp[2]) length = ((end-start+1)/3)-1 strand = tmp[3] someID = "-" someID2 = "-" COG = "-" output.write("%s\t%d\t%d\t%s\t%d\t%s\t%s\t%s\t%s\t%s\n" % (desc, start, end, strand, length, someID, someID2, name, orf, COG)) output.close() if self.verbose: transit_tools.transit_message("Finished conversion")
#geneID start end strand TA coordinates
[docs] def annotationGFF3_to_PT(self, event): annotationpath = self.annotation defaultFile = transit_tools.fetch_name(annotationpath) + ".prot_table" #defaultDir = os.path.dirname(os.path.realpath(__file__)) defaultDir = os.getcwd() datasets = self.ctrlSelected() + self.expSelected() if not annotationpath: transit_tools.ShowError("Error: No annotation file selected.") else: outputPath = self.SaveFile(defaultDir, defaultFile) if not outputPath: return if self.verbose: transit_tools.transit_message("Converting annotation file from GFF3 format to prot_table format") output = open(outputPath, "w") for line in open(annotationpath): if line.startswith("#"): continue tmp = line.strip().split("\t") chr = tmp[0] type = tmp[2] start = int(tmp[3]) end = int(tmp[4]) length = ((end-start+1)/3)-1 strand = tmp[6] features = dict([tuple(f.split("=")) for f in tmp[8].split(";")]) if "ID" not in features: continue orf = features["ID"] name = features.get("Name", "-") if name == "-": name = features.get("name", "-") desc = features.get("Description", "-") if desc == "-": desc = features.get("description", "-") if desc == "-": desc = features.get("Desc", "-") if desc == "-": desc = features.get("desc", "-") someID = "-" someID2 = "-" COG = "-" output.write("%s\t%d\t%d\t%s\t%d\t%s\t%s\t%s\t%s\t%s\n" % (desc, start, end, strand, length, someID, someID2, name, orf, COG)) output.close() if self.verbose: transit_tools.transit_message("Finished conversion")
[docs] def RunMethod(self, event): #FLORF #X = self.methodChoice.GetCurrentSelection() #selected_name = self.methodChoice.GetString(X) selected_name = self.method_choice for name in methods: if methods[name].fullname() == selected_name: methodobj = methods[name].method try: M = methodobj.fromGUI(self) if M: thread = threading.Thread(target=M.Run()) thread.setDaemon(True) thread.start() except Exception as e: transit_tools.transit_message("Error: %s" % str(e)) traceback.print_exc()
[docs]def msg(): return """transit.py {gumbel, hmm, resampling} [-h/--help] Help: """
if __name__ == "__main__": #If no arguments, show GUI: if len(sys.argv) == 1: transit_tools.transit_message("Running in GUI Mode") app = wx.App(False) #create an object of CalcFrame frame = TnSeekFrame(None) #show the frame frame.Show(True) #start the applications app.MainLoop() else: method_name = sys.argv[1] if method_name not in methods: print "Error: The '%s' method is unknown." % method_name print "Please use one of the known methods (or see documentation to add a new one):" for m in methods: print "\t - %s" % m else: methodobj = methods[method_name].method.fromconsole() methodobj.Run()