def __init__(self): super().__init__() # Docker Client # This client talks to your local docker self.docker = DockerClient('unix:///var/run/docker.sock', 'local') self.host_ref_dir = None self.host_seq_dir = None self.ref_dir_set = False self.seq_dir_set = False self.result_folder_name = "/Count" self.aligns_folder_name = "/Aligns" # TODO is this an issue if multiple containers write to the same place? # TODO add timestamp to directory name to differentiate runs # Jimmy, Mar/7/2017, I don't know what does "toHostDir" do. Since our DockerClient missed that code, I comment it temporary #self.host_counts_dir = counts_dir #self.docker.toHostDir(counts_dir) # GUI box = gui.widgetBox(self.controlArea, "Info") self.infoLabel = gui.widgetLabel( box, 'Connect to a Directory widget ' 'to specify location of reference ' 'and seq fastq files') self.infoLabel.setWordWrap(True) gui.checkBox(self.controlArea, self, 'auto_run', 'Run automatically when input set') self.btn_run = gui.button(self.controlArea, self, "Run", callback=self.btn_run_pushed) self.is_running = False
def __init__(self): super().__init__() # Docker Client # This client talks to your local docker self.docker = DockerClient('unix:///var/run/docker.sock', 'local') # GUI box = gui.widgetBox(self.controlArea, "Info") self.infoLabel = gui.widgetLabel( box, 'Connect to data or use a Directory widget' ' to specify location of UMI read data files') self.infoLabel.setWordWrap(True) # TODO let user specify results directory # self.btn_res = gui.button(None, self, "Open", callback=self.set_results_dir) # self.resultsEdit = QtGui.QLineEdit(self.host_results_dir) # self.buttonsArea.layout().addWidget(self.btn_res) # self.buttonsArea.layout().addWidget(self.resultsEdit) self.autoRun = True gui.checkBox(self.controlArea, self, 'autoRun', 'Run automatically when input set') self.btn_run = gui.button(self.controlArea, self, "Run", callback=self.start_analysis)
def __init__(self): super().__init__() # Docker Client # This client talks to your local docker self.docker = DockerClient('unix:///var/run/docker.sock', 'local') self.hostDirectories = {'refs': None, 'seqs': None, 'conf': None, 'counts': None, 'aligns': None, 'barcodes': None} self.labelText = {'refs': 'References: {0}', 'seqs': 'Sequences: {0}', 'conf': 'Configs: {0}', 'barcodes': 'Barcode file: {0}'} # folders that will created automatically self.result_folder_name = "Counts" self.aligns_folder_name = "Aligns" # GUI box = gui.widgetBox(self.controlArea, "Info") self.lblRefs = gui.widgetLabel(box, 'References: Not Set') self.lblSeqs = gui.widgetLabel(box, 'Sequences: Not Set') self.lblConfigs = gui.widgetLabel(box, 'Configs: Not Set') self.lblBarcodes = gui.widgetLabel(box, "Barcode file: Not Set") self.infoLabel = gui.widgetLabel(box, 'Waiting...') self.infoLabel.setWordWrap(True) gui.checkBox(self.controlArea, self, 'auto_run', 'Run automatically when input set') self.btn_run = gui.button(self.controlArea, self, "Run", callback=self.btn_run_pushed) self.is_running = False self.setMinimumSize(500, 200)
def __init__(self): super().__init__() # Docker Client # This client talks to your local docker self.docker = DockerClient('unix:///var/run/docker.sock', 'local') # The directory of the seq data needed to run # the container will be set by the user before the # container can be run self.host_ref_dir = None self.host_seq_dir = None self.ref_dir_set = False self.seq_dir_set = False # The default write location of all widgets should be # ~/BioDepot/WidgetName/ # TODO is this an issue if multiple containers write to the same place? # TODO add timestamp to directory name to differentiate runs counts_dir = '~/BioDepot/Dtoxs_Alignment/Counts' if not os.path.exists(counts_dir): os.makedirs(counts_dir) self.host_counts_dir = self.docker.toHostDir(counts_dir) # GUI box = gui.widgetBox(self.controlArea, "Info") self.infoLabel = gui.widgetLabel( box, 'Connect to a Directory widget ' 'to specify location of reference ' 'and seq fastq files') self.infoLabel.setWordWrap(True) gui.checkBox(self.controlArea, self, 'auto_run', 'Run automatically when input set') self.btn_run = gui.button(self.controlArea, self, "Run", callback=self.btn_run_pushed) self.is_running = False
class OWBwBWidget(widget.OWWidget): dockerClient = DockerClient('unix:///var/run/docker.sock', 'local') def __init__(self, image_name, image_tag): super().__init__() self._hostDirectories = {} self._dockerImageName = image_name self._dockerImageTag = image_tag self._dockerVolumes = None self._dockerCommands = None self._dockerEnvironments = None self._Flag_isRunning = False def Event_OnRunFinished(self): raise Exception('Event_OnRunFinished not implemented!') def Event_OnRunMessage(self, message): raise Exception('Event_OnRunMessage not implemented!') def Initialize_InputKeys(self, keys): for k in keys: self._hostDirectories[k] = None def setDirectories(self, key, path, ctrlLabel=None): labelTitle = ctrlLabel.text().split(':')[0] + ': {}' # When a user removes a connected Directory widget, # it sends a signal with path=None if path is None: self._hostDirectories[key] = None if ctrlLabel is not None: ctrlLabel.setText(labelTitle.format('Not Set')) elif not os.path.exists(path): self._hostDirectories[key] = None if ctrlLabel is not None: ctrlLabel.setText( labelTitle.format('None existent directory: {}'.format( str(path)))) else: self._hostDirectories[key] = path.strip() if ctrlLabel is not None: ctrlLabel.setText(labelTitle.format((str(path)))) def getDirectory(self, key): return self._hostDirectories[key] """ Pull image """ def __dockerPullImage__(self): self.Event_OnRunMessage('Pulling \'' + self._dockerImageName + ":" + self._dockerImageTag + '\' from Dockerhub...') self.setStatusMessage("Downloading...") self.progressBarInit() self._Flag_isRunning = True # Pull the image in a new thread self.pullImageThread = PullImageThread(self.dockerClient, self._dockerImageName, self._dockerImageTag) self.pullImageThread.pull_progress.connect(self.__dockerPullProgress__) self.pullImageThread.finished.connect(self.__dockerPullDone__) self.pullImageThread.start() def __dockerPullProgress__(self, val): self.progressBarSet(val) def __dockerPullDone__(self): self.Event_OnRunMessage('Finished pulling \'' + self._dockerImageName + ":" + self._dockerImageTag + '\'') self.progressBarFinished() self.__dockerRealRun__() """ Run container """ def dockerRun(self, volumes=None, commands=None, environments=None): if not self._Flag_isRunning: self._dockerVolumes = volumes self._dockerCommands = commands self._dockerEnvironments = environments # Make sure the docker image is downloaded if not self.dockerClient.has_image(self._dockerImageName, self._dockerImageTag): self.__dockerPullImage__() else: self.__dockerRealRun__() def __dockerRealRun__(self): self._Flag_isRunning = True self.setStatusMessage('Running...') self.Event_OnRunMessage('Running \'' + self._dockerImageName + '\'') # Run the container in a new thread self.containerThread = LocalContainerRunner( self.dockerClient, '{}:{}'.format(self._dockerImageName, self._dockerImageTag), self._dockerVolumes, self._dockerCommands, self._dockerEnvironments) self.containerThread.progress.connect(self.__dockerRunProgress__) self.containerThread.finished.connect(self.__dockerRunDone__) self.containerThread.start() def __dockerRunProgress__(self, val): self.progressBarSet(val) def __dockerRunDone__(self): self._Flag_isRunning = False self.setStatusMessage('Finished!') self.Event_OnRunMessage('Finished!') self.Event_OnRunFinished()
class OWDocker(widget.OWWidget): name = "Docker Info" description = "See the status of your docker engine" category = "Dev" icon = "icons/docker-info.svg" priority = 1 inputs = [] outputs = [] want_main_area = False # TODO finish supporting multiple Docker Clients for Containers, Images, Volumns tables # see Version table for an example docker_clients = [DockerClient('unix:///var/run/docker.sock', 'local')] font = QtGui.QFont() font.setFamily("Courier New") font.setPointSize(12) def __init__(self): super().__init__() self.context = 'none' # GUI self.btn_cli = gui.button(None, self, "Clients", callback=self.get_clients, autoDefault=False) self.btn_ver = gui.button(None, self, "Version", callback=self.get_version, autoDefault=False) self.btn_inf = gui.button(None, self, "Info", callback=self.get_info, autoDefault=False) self.btn_img = gui.button(None, self, "Images", callback=self.get_images, autoDefault=False) self.btn_con = gui.button(None, self, "Containers", callback=self.get_containers, autoDefault=False) self.btn_vol = gui.button(None, self, "Volumes", callback=self.get_volumes, autoDefault=False) self.btn_cli.setFixedWidth(100) self.btn_ver.setFixedWidth(100) self.btn_inf.setFixedWidth(100) self.btn_img.setFixedWidth(100) self.btn_con.setFixedWidth(100) self.btn_vol.setFixedWidth(100) self.hboxTop = QtWidgets.QHBoxLayout() self.hboxTop.setAlignment(QtCore.Qt.AlignLeft) self.hboxTop.addWidget(self.btn_con) self.hboxTop.addWidget(self.btn_img) self.hboxTop.addWidget(self.btn_vol) self.hboxTop.addStretch() self.hboxTop.addWidget(self.btn_cli) self.hboxTop.addWidget(self.btn_ver) self.hboxTop.addWidget(self.btn_inf) self.infoTable = QtWidgets.QTableWidget() self.infoTable.horizontalHeader().setStretchLastSection(True) self.infoTable.setFont(self.font) self.btn_rmv = gui.button(None, self, "Remove", callback=self.remove_selected, autoDefault=False) self.btn_stp = gui.button(None, self, "Stop", callback=self.stop_selected, autoDefault=False) self.btn_pau = gui.button(None, self, "Pause", callback=self.pause_selected, autoDefault=False) self.btn_unp = gui.button(None, self, "Unpause", callback=self.unpause_selected, autoDefault=False) self.btn_rmv.setHidden(True) self.btn_stp.setHidden(True) self.btn_pau.setHidden(True) self.btn_unp.setHidden(True) self.btn_rmv.setFixedWidth(100) self.btn_stp.setFixedWidth(100) self.btn_pau.setFixedWidth(100) self.btn_unp.setFixedWidth(100) self.rm_force = QtWidgets.QCheckBox("Force") self.rm_force.setHidden(True) self.hbox = QtWidgets.QHBoxLayout() self.hbox.addWidget(self.btn_rmv) self.hbox.addSpacing(5) self.hbox.addWidget(self.rm_force) self.hbox.addSpacing(20) self.hbox.addWidget(self.btn_stp) self.hbox.addWidget(self.btn_pau) self.hbox.addWidget(self.btn_unp) self.hbox.setAlignment(QtCore.Qt.AlignLeft) self.controlArea.layout().addLayout(self.hboxTop) self.controlArea.layout().addWidget(self.infoTable) self.controlArea.layout().addLayout(self.hbox) self.controlArea.setMinimumSize(900, 298) self.get_containers() """ Button Callbacks """ def get_clients(self): self.context = 'clients' self.btn_cli.setDefault(True) self.btn_rmv.setHidden(True) self.rm_force.setHidden(True) self.btn_stp.setHidden(True) self.btn_pau.setHidden(True) self.btn_unp.setHidden(True) self.draw_clients_table() def get_version(self): self.context = 'version' self.btn_ver.setDefault(True) self.btn_rmv.setHidden(True) self.rm_force.setHidden(True) self.btn_stp.setHidden(True) self.btn_pau.setHidden(True) self.btn_unp.setHidden(True) self.draw_version_table() def get_info(self): self.context = 'info' self.btn_inf.setDefault(True) self.btn_rmv.setHidden(True) self.rm_force.setHidden(True) self.btn_stp.setHidden(True) self.btn_pau.setHidden(True) self.btn_unp.setHidden(True) self.draw_info_table() def get_images(self): self.context = 'images' self.btn_img.setDefault(True) self.btn_rmv.setHidden(False) self.rm_force.setHidden(False) self.btn_stp.setHidden(True) self.btn_pau.setHidden(True) self.btn_unp.setHidden(True) self.draw_images_table() def get_containers(self): self.context = 'containers' self.btn_con.setDefault(True) self.btn_rmv.setHidden(False) self.rm_force.setHidden(False) self.btn_stp.setHidden(False) self.btn_pau.setHidden(False) self.btn_unp.setHidden(False) self.draw_containers_table() def get_volumes(self): self.context = 'volumes' self.btn_vol.setDefault(True) self.btn_rmv.setHidden(False) self.rm_force.setHidden(True) self.btn_stp.setHidden(True) self.btn_pau.setHidden(True) self.btn_unp.setHidden(True) self.draw_volumes_table() """ Draw Tables """ def draw_clients_table(self): self.infoTable.clearSpans() self.infoTable.setColumnCount(3) self.infoTable.setHorizontalHeaderLabels(['', 'NAME', 'URL']) self.infoTable.horizontalHeader().setSectionResizeMode( QtWidgets.QHeaderView.ResizeToContents) self.infoTable.horizontalHeader().setVisible(True) self.infoTable.setRowCount(len(self.docker_clients)) for i, client in enumerate(self.docker_clients): self.infoTable.setCellWidget(i, 0, QtWidgets.QCheckBox()) self.infoTable.setItem(i, 0, QtWidgets.QTableWidgetItem('')) self.infoTable.setItem( i, 1, QtWidgets.QTableWidgetItem(client.getName())) self.infoTable.setItem(i, 2, QtWidgets.QTableWidgetItem(client.getUrl())) def draw_version_table(self): self.infoTable.clearSpans() self.infoTable.setColumnCount(2) self.infoTable.setHorizontalHeaderLabels(['', '']) self.infoTable.horizontalHeader().setVisible(False) self.infoTable.verticalHeader().setVisible(False) totalRows = len(self.docker_clients) + sum( len(client.version().items()) for client in self.docker_clients) self.infoTable.setRowCount(totalRows) for i, client in enumerate(self.docker_clients): clientSep = QtWidgets.QTableWidgetItem(client.getName() + ": " + client.getUrl()) clientSep.setBackground(QtGui.QColor('lightGray')) self.infoTable.setItem(i, 0, clientSep) self.infoTable.setSpan(i, 0, 1, 2) self.infoTable.setCellWidget(i, 0, None) table = [(str(k), str(v)) for k, v in sorted(client.version().items())] for x, row in enumerate(table): self.infoTable.setItem(i + x + 1, 0, QtWidgets.QTableWidgetItem(row[0])) self.infoTable.setItem(i + x + 1, 1, QtWidgets.QTableWidgetItem(row[1])) self.infoTable.setCellWidget(i + x + 1, 0, None) self.infoTable.horizontalHeader().setSectionResizeMode( QtWidgets.QHeaderView.ResizeToContents) def draw_info_table(self): self.infoTable.clearSpans() table = [(str(k), str(v)) for k, v in sorted(self.docker_clients[0].info().items())] self.infoTable.setColumnCount(2) self.infoTable.setHorizontalHeaderLabels(['', '']) self.infoTable.setRowCount(len(table)) self.infoTable.horizontalHeader().setSectionResizeMode( QtWidgets.QHeaderView.Interactive) self.infoTable.horizontalHeader().resizeSection(0, 150) self.infoTable.horizontalHeader().setVisible(False) for i, row in enumerate(table): self.infoTable.setItem(i, 0, QtWidgets.QTableWidgetItem(row[0])) self.infoTable.setItem(i, 1, QtWidgets.QTableWidgetItem(row[1])) self.infoTable.setCellWidget(i, 0, None) def draw_images_table(self): self.infoTable.clearSpans() tableHeader = ['', 'REPOSITORY', 'TAG', 'ID', 'CREATED', 'SIZE'] self.infoTable.setColumnCount(len(tableHeader)) self.infoTable.setHorizontalHeaderLabels(tableHeader) self.infoTable.horizontalHeader().setSectionResizeMode( QtWidgets.QHeaderView.ResizeToContents) self.infoTable.horizontalHeader().setVisible(True) table = [] imgs = self.docker_clients[0].images() if not type(imgs) is list: self.infoTable.horizontalHeader().setSectionResizeMode( QtWidgets.QHeaderView.Stretch) self.infoTable.horizontalHeader().setSectionResizeMode( 0, QtWidgets.QHeaderView.ResizeToContents) else: for img in imgs: id = img['Id'].split(':')[1][:12] created = millis_to_datetime(img['Created']) size = sizeof_fmt(img['Size']) repo_info = [id, created, size] if not img['RepoTags']: continue for repo in img['RepoTags']: table.append(repo.split(':') + repo_info) self.infoTable.setRowCount(len(table)) for i, row in enumerate(table): self.infoTable.setCellWidget(i, 0, QtWidgets.QCheckBox()) self.infoTable.setItem(i, 0, QtWidgets.QTableWidgetItem('')) for x, cell in enumerate(row): self.infoTable.setItem(i, 1 + x, QtWidgets.QTableWidgetItem(cell)) def draw_containers_table(self): self.infoTable.clearSpans() tableHeader = [ '', 'CONTAINER ID', 'IMAGE', 'COMMAND', 'CREATED', 'STATUS', 'PORTS', 'NAMES' ] self.infoTable.setColumnCount(len(tableHeader)) self.infoTable.setHorizontalHeaderLabels(tableHeader) self.infoTable.horizontalHeader().setSectionResizeMode( QtWidgets.QHeaderView.ResizeToContents) self.infoTable.horizontalHeader().setVisible(True) self.infoTable.horizontalHeader().setSectionResizeMode( 3, QtWidgets.QHeaderView.Interactive) self.infoTable.horizontalHeader().resizeSection(3, 120) conts = self.docker_clients[0].containers() if not type(conts) is list: self.infoTable.setRowCount(0) self.infoTable.horizontalHeader().setSectionResizeMode( QtWidgets.QHeaderView.Stretch) self.infoTable.horizontalHeader().setSectionResizeMode( 0, QtWidgets.QHeaderView.ResizeToContents) else: self.infoTable.setRowCount(len(conts)) for i, cont in enumerate(conts): self.infoTable.setCellWidget(i, 0, QtWidgets.QCheckBox()) self.infoTable.setItem(i, 0, QtWidgets.QTableWidgetItem('')) self.infoTable.setItem( i, 1, QtWidgets.QTableWidgetItem(cont['Id'][:12])) img_split = cont['Image'].split(':') img_str = img_split[0] if len( img_split) < 2 else img_split[1][:12] self.infoTable.setItem(i, 2, QtWidgets.QTableWidgetItem(img_str)) self.infoTable.setItem( i, 3, QtWidgets.QTableWidgetItem(cont['Command'])) self.infoTable.setItem( i, 4, QtWidgets.QTableWidgetItem( millis_to_datetime(cont['Created']))) self.infoTable.setItem( i, 5, QtWidgets.QTableWidgetItem(cont['Status'])) self.infoTable.setItem( i, 6, QtWidgets.QTableWidgetItem('\n'.join([ str(_.get('PublicPort', ' ')) for _ in cont['Ports'] ]))) self.infoTable.setItem( i, 7, QtWidgets.QTableWidgetItem('\n'.join(cont['Names']))) def draw_volumes_table(self): self.infoTable.clearSpans() tableHeader = ['', 'DRIVER', 'VOLUME NAME', 'MOUNT POINT'] self.infoTable.setColumnCount(len(tableHeader)) self.infoTable.setHorizontalHeaderLabels(tableHeader) self.infoTable.horizontalHeader().setSectionResizeMode( QtWidgets.QHeaderView.ResizeToContents) self.infoTable.horizontalHeader().setVisible(True) vols = self.docker_clients[0].volumes() if not type(vols) is list: self.infoTable.setRowCount(0) self.infoTable.horizontalHeader().setSectionResizeMode( QtWidgets.QHeaderView.Stretch) self.infoTable.horizontalHeader().setSectionResizeMode( 0, QtWidgets.QHeaderView.ResizeToContents) else: self.infoTable.setRowCount(len(vols)) for i, vol in enumerate(vols): self.infoTable.setCellWidget(i, 0, QtWidgets.QCheckBox()) self.infoTable.setItem(i, 0, QtWidgets.QTableWidgetItem('')) self.infoTable.setItem( i, 1, QtWidgets.QTableWidgetItem(vol['Driver'])) self.infoTable.setItem(i, 2, QtWidgets.QTableWidgetItem(vol['Name'])) self.infoTable.setItem( i, 3, QtWidgets.QTableWidgetItem(vol['Mountpoint'])) """ Remove functions """ def remove_image(self, id, force): print('Removing image: ' + id) self.docker_clients[0].remove_image(id, force) def remove_container(self, id, force): print('Removing container: ' + id) self.docker_clients[0].remove_container(id, force) def remove_volume(self, id, force): print('Removing volume: ' + id) self.docker_clients[0].remove_volume(id) def remove_selected(self): remove_func = None draw_func = None id_column = 0 if (self.context == 'images'): remove_func = self.remove_image draw_func = self.draw_images_table id_column = 3 elif (self.context == 'containers'): remove_func = self.remove_container draw_func = self.draw_containers_table id_column = 1 elif (self.context == 'volumes'): remove_func = self.remove_volume draw_func = self.draw_volumes_table id_column = 2 for i in range(0, self.infoTable.rowCount()): if (self.infoTable.cellWidget(i, 0).isChecked()): remove_func( self.infoTable.item(i, id_column).text(), self.rm_force.isChecked()) draw_func() """ Stop, Pause, Unpause only apply to containers """ def stop_selected(self): for i in range(0, self.infoTable.rowCount()): if (self.infoTable.cellWidget(i, 0).isChecked()): status = self.infoTable.item(i, 5).text() if (status.startswith('Up') and not status.endswith('(Paused)')): self.docker_clients[0].stop_container( self.infoTable.item(i, 1).text()) self.draw_containers_table() def pause_selected(self): for i in range(0, self.infoTable.rowCount()): if (self.infoTable.cellWidget(i, 0).isChecked()): status = self.infoTable.item(i, 5).text() if (status.startswith('Up') and not status.endswith('(Paused)')): self.docker_clients[0].pause_container( self.infoTable.item(i, 1).text()) self.draw_containers_table() def unpause_selected(self): for i in range(0, self.infoTable.rowCount()): if (self.infoTable.cellWidget(i, 0).isChecked()): status = self.infoTable.item(i, 5).text() if (status.startswith('Up') and status.endswith('(Paused)')): self.docker_clients[0].unpause_container( self.infoTable.item(i, 1).text()) self.draw_containers_table()
class OWRSEMCalc(widget.OWWidget): name = "RSEM Calculation" description = "Step2: handles both the alignment of reads against reference transcript sequences and the calculation of relative abundances. It executes rsem-calculate-expression command" category = "RNASeq" icon = "icons/rsemcalc.svg" priority = 10 image_name = "genomicpariscentre/rsem" image_version = "latest" inputs = [(".fastq files + ref files from step1", str, "set_aligns")] outputs = [("Results", str)] want_main_area = False # The directory of the alignment data needed to run # the container will be set by the user before the # container can be run host_counts_dir = "" # The default write location of all widgets should be # ~/BioDepot/WidgetName/ # TODO is this an issue if multiple containers write to the same place? # host_results_dir = os.path.expanduser('~') + '/BioDepot/Kallisto' host_results_dir = os.path.expanduser('~') + '/BioDepot/RSEM_Calc/Results' def __init__(self): super().__init__() # Docker Client # This client talks to your local docker self.docker = DockerClient('unix:///var/run/docker.sock', 'local') # GUI box = gui.widgetBox(self.controlArea, "Info") self.infoLabel = gui.widgetLabel( box, 'Connect to data or use a Directory widget' ' to specify location of UMI read data files') self.infoLabel.setWordWrap(True) # TODO let user specify results directory # self.btn_res = gui.button(None, self, "Open", callback=self.set_results_dir) # self.resultsEdit = QtGui.QLineEdit(self.host_results_dir) # self.buttonsArea.layout().addWidget(self.btn_res) # self.buttonsArea.layout().addWidget(self.resultsEdit) self.autoRun = True gui.checkBox(self.controlArea, self, 'autoRun', 'Run automatically when input set') self.btn_run = gui.button(self.controlArea, self, "Run", callback=self.start_analysis) """ Set input """ def set_aligns(self, path): if not type(path) is str: # TODO create warning print('Tried to set input directory to None') elif not os.path.exists(path): # TODO create warning print('Tried to set input directory to none existent directory: ' + str(path)) else: self.host_counts_dir = path.strip() if self.autoRun: self.start_analysis() else: self.infoLabel.setText( 'Input directory set.\nWaiting to run...') """ Pull image """ def pull_image(self): self.infoLabel.setText('Pulling \'' + self.image_name + ":" + self.image_version + '\' from Dockerhub...') self.setStatusMessage("Downloading...") self.progressBarInit() self.btn_run.setEnabled(False) # Pull the image in a new thread self.pull_image_thread = PullImageThread(self.docker, self.image_name, self.image_version) self.pull_image_thread.pull_progress.connect(self.pull_image_progress) self.pull_image_thread.finished.connect(self.pull_image_done) self.pull_image_thread.start() def pull_image_progress(self, val): self.progressBarSet(val) def pull_image_done(self): self.infoLabel.setText('Finished pulling \'' + self.image_name + ":" + self.image_version + '\'') self.progressBarFinished() self.run_analysis() """ Analysis """ def start_analysis(self): # Make sure the docker image is downloaded if not self.docker.has_image(self.image_name, self.image_version): self.pull_image() # Make sure there is an alignment directory set elif self.host_counts_dir: self.run_analysis() else: self.infoLabel.setText('Set directory before running.') def run_analysis(self): self.btn_run.setEnabled(False) self.infoLabel.setText('Running analysis...') self.setStatusMessage('Running...') self.progressBarInit() # Run the container in a new thread self.run_analysis_thread = RunAnalysisThread(self.docker, self.image_name, self.host_counts_dir, self.host_results_dir) self.run_analysis_thread.analysis_progress.connect( self.run_analysis_progress) self.run_analysis_thread.finished.connect(self.run_analysis_done) self.run_analysis_thread.start() def run_analysis_progress(self, val): self.progressBarSet(val) def run_analysis_done(self): self.infoLabel.setText("Finished running analysis!") self.btn_run.setEnabled(True) self.btn_run.setText('Run again') self.setStatusMessage('Finished!') self.progressBarFinished() self.send("Results", self.host_results_dir) self.btn_run.setEnabled(True)
class OWDtoxsAlignment(widget.OWWidget): name = "Dtoxs Alignment" description = "Step 1 of the Dtoxs SOP. Uses a Burrows-Wheeler Aligner (BWA)." category = "RNASeq" icon = "icons/dtoxs-alignment2.svg" priority = 10 image_name = "biodepot/dtoxs_alignment" image_version = "latest" inputs = [("References", str, "set_refs"), ("Seqs", str, "set_seqs")] outputs = [("Counts", str)] auto_run = Setting(True) want_main_area = False def __init__(self): super().__init__() # Docker Client # This client talks to your local docker self.docker = DockerClient('unix:///var/run/docker.sock', 'local') self.host_ref_dir = None self.host_seq_dir = None self.ref_dir_set = False self.seq_dir_set = False self.result_folder_name = "/Count" self.aligns_folder_name = "/Aligns" # TODO is this an issue if multiple containers write to the same place? # TODO add timestamp to directory name to differentiate runs # Jimmy, Mar/7/2017, I don't know what does "toHostDir" do. Since our DockerClient missed that code, I comment it temporary #self.host_counts_dir = counts_dir #self.docker.toHostDir(counts_dir) # GUI box = gui.widgetBox(self.controlArea, "Info") self.infoLabel = gui.widgetLabel( box, 'Connect to a Directory widget ' 'to specify location of reference ' 'and seq fastq files') self.infoLabel.setWordWrap(True) gui.checkBox(self.controlArea, self, 'auto_run', 'Run automatically when input set') self.btn_run = gui.button(self.controlArea, self, "Run", callback=self.btn_run_pushed) self.is_running = False """ Called when the user pushes 'Run' """ def btn_run_pushed(self): self.start_container(run_btn_pushed=True) """ Set references """ def set_refs(self, path): # When a user removes a connected Directory widget, # it sends a signal with path=None if path is None: self.ref_dir_set = False else: self.host_ref_dir = path if self.host_ref_dir is None: # TODO emit error self.ref_dir_set = False print('References set to invalid directory') else: self.ref_dir_set = True self.start_container(run_btn_pushed=False) """ Set seqs """ def set_seqs(self, path): # When a user removes a connected Directory widget, # it sends a signal with path=None if path is None: self.seq_dir_set = False else: self.host_seq_dir = path # Jimmy March-28-2017, once the seq input was set, automatically create a result and aligns folder as a sibling of "Seqs" parent_path = os.path.abspath(os.path.join(self.host_seq_dir, '..')) self.host_counts_dir = os.path.join(parent_path + self.result_folder_name) self.host_aligns_dir = os.path.join(parent_path + self.aligns_folder_name) if not os.path.exists(self.host_counts_dir): os.makedirs(self.host_counts_dir) if not os.path.exists(self.host_aligns_dir): os.makedirs(self.host_aligns_dir) if self.host_seq_dir is None: # TODO emit error self.seq_dir_set = False print('Seq set to invalid directory') else: self.seq_dir_set = True self.start_container(run_btn_pushed=False) """ Pull image """ def pull_image(self): self.infoLabel.setText('Pulling \'' + self.image_name + ":" + self.image_version + '\' from Dockerhub...') self.setStatusMessage("Downloading...") self.progressBarInit() self.is_running = True self.btn_run.setEnabled(False) # Pull the image in a new thread self.pull_image_worker = PullImageThread(self.docker, self.image_name, self.image_version) self.pull_image_worker.pull_progress.connect(self.pull_image_progress) self.pull_image_worker.finished.connect(self.pull_image_finished) self.pull_image_worker.start() def pull_image_progress(self, val): self.progressBarSet(val) def pull_image_finished(self): self.infoLabel.setText('Finished pulling \'' + self.image_name + ":" + self.image_version + '\'') self.progressBarFinished() self.run_container() """ Alignment """ def start_container(self, run_btn_pushed=True): # Make sure both inputs are set if self.ref_dir_set and self.seq_dir_set: if not self.is_running and (self.auto_run or run_btn_pushed): # Make sure the docker image is downloaded if not self.docker.has_image(self.image_name, self.image_version): self.pull_image() else: self.run_container() else: self.infoLabel.setText( 'References and Seqs directories set.\nWaiting to run...') elif self.ref_dir_set: self.infoLabel.setText("Waiting for user to set Seqs directory.") elif self.seq_dir_set: self.infoLabel.setText( "Waiting for user to set References directory.") def run_container(self): self.is_running = True self.infoLabel.setText('Running alignment...') self.setStatusMessage('Running...') #self.progressBarInit() # Run the container in a new thread self.run_container_thread = RunAlignmentThread( self.docker, self.image_name, self.host_ref_dir, self.host_seq_dir, self.host_counts_dir, self.host_aligns_dir) self.run_container_thread.progress.connect(self.run_container_progress) self.run_container_thread.finished.connect(self.run_container_finished) self.run_container_thread.start() def run_container_progress(self, val): self.progressBarSet(val) def run_container_finished(self): self.infoLabel.setText("Finished running alignment!") self.btn_run.setEnabled(True) self.is_running = False self.btn_run.setText('Run again') self.setStatusMessage('Finished!') #self.progressBarFinished() self.send("Counts", self.host_counts_dir)
class OWSTARAlignment(widget.OWWidget): RunMode_GenerateGenome = 0 RunMode_STAR = 1 name = "Star Alignment" description = "Performs alignment of fastqs to bam via STAR" category = "RNASeq" icon = "icons/staralignment.svg" priority = 10 inputs = [("FastQ Files", str, "setFastqInput", widget.Default), ("Genome Dir", str, "setGenomeDir")] outputs = [("Directory", str)] want_main_area = False dockerClient = DockerClient('unix:///var/run/docker.sock', 'local') image_name = "biodepot/ubuntu-star" image_version = "latest" def __init__(self): super().__init__() self.bFastqDirSet = False self.bStarIndexDirSet = False self.result_folder_name = "/Aligned" # GUI box = gui.widgetBox(self.controlArea, "Info") self.info_fastq = gui.widgetLabel( box, 'Please specify a directory with fastq or fasta files.') self.info_starindex = gui.widgetLabel( box, 'Please specify a genome directory.') self.info_fastq.setWordWrap(True) self.info_starindex.setWordWrap(True) self.RunMode = OWSTARAlignment.RunMode_GenerateGenome self.cboRunMode = gui.comboBox(self.controlArea, self, 'RunMode', label='Running Mode:', items=('Generate Genome', 'STAR Alignment'), valueType=int) self.cboRunMode.setCurrentIndex(0) self.AutoStarAlignment = False gui.checkBox(self.controlArea, self, 'AutoStarAlignment', 'Run automatically when directory was set.') self.btnStarAlignment = gui.button(self.controlArea, self, "Star Alignment", callback=self.StartStarAlignment) self.btnStarAlignment.setEnabled(False) def setFastqInput(self, path): # When a user removes a connected Directory widget, # it sends a signal with path=None if path is None: self.bFastqDirSet = False else: if not os.path.exists(path): self.bFastqDirSet = False print('References set to invalid directory') else: self.fastqDirectory = path self.bFastqDirSet = True self.info_fastq.setText("Fasta/q files: {0}".format( self.fastqDirectory)) host_fastq_dir = path.strip() # Jimmy May-03-2017, once the fastq input was set, automatically create an output fold as a sibling of "fastq" parent_path = os.path.abspath(os.path.join(host_fastq_dir, '..')) self.host_results_dir = os.path.join(parent_path + self.result_folder_name) if not os.path.exists(self.host_results_dir): os.makedirs(self.host_results_dir) self.btnStarAlignment.setEnabled(self.bFastqDirSet and self.bStarIndexDirSet) if self.bFastqDirSet and self.bStarIndexDirSet and self.AutoStarAlignment: self.StartStarAlignment() def setGenomeDir(self, path): if path is None: self.bStarIndexDirSet = False else: if not os.path.exists(path): self.bStarIndexDirSet = False print('References set to invalid directory') else: self.starindexDirectory = path self.bStarIndexDirSet = True self.info_starindex.setText("Star index: {0}".format( self.starindexDirectory)) self.btnStarAlignment.setEnabled(self.bFastqDirSet and self.bStarIndexDirSet) if self.bFastqDirSet and self.bStarIndexDirSet and self.AutoStarAlignment: self.StartStarAlignment() def StartStarAlignment(self): if not self.bFastqDirSet or not self.bStarIndexDirSet: return if not self.dockerClient.has_image(self.image_name, self.image_version): self.pull_image() elif self.bFastqDirSet and self.bStarIndexDirSet: self.run_staralignment() """ Pull image """ def pull_image(self): self.info_fastq.setText('Pulling \'' + self.image_name + ":" + self.image_version) self.info_starindex.setText('') self.setStatusMessage("Downloading...") self.progressBarInit() self.btnStarAlignment.setEnabled(False) # Pull the image in a new thread self.pull_image_thread = PullImageThread(self.dockerClient, self.image_name, self.image_version) self.pull_image_thread.pull_progress.connect(self.pull_image_progress) self.pull_image_thread.finished.connect(self.pull_image_done) self.pull_image_thread.start() def pull_image_progress(self, val=0): self.progressBarSet(val) def pull_image_done(self): self.info_fastq.setText('Finished pulling \'' + self.image_name + ":" + self.image_version + '\'') self.progressBarFinished() self.run_staralignment() def run_staralignment(self): self.btnStarAlignment.setEnabled(False) self.info_fastq.setText('Running star alignment...') self.info_starindex.setText('') self.setStatusMessage('Running...') #self.progressBarInit() # Run the container in a new thread self.run_staralignment_thread = StarAlignmentThread( self.dockerClient, self.image_name, self.image_version, self.fastqDirectory, self.starindexDirectory, self.host_results_dir, self.RunMode) self.run_staralignment_thread.analysis_progress.connect( self.run_staralignment_progress) self.run_staralignment_thread.finished.connect( self.run_staralignment_done) self.run_staralignment_thread.analysis_message.connect( self.run_star_message) self.run_staralignment_thread.start() def run_staralignment_progress(self, val): self.progressBarSet(val) def run_staralignment_done(self): self.info_fastq.setText("Finished running analysis!") self.btnStarAlignment.setEnabled(True) self.btnStarAlignment.setText('Run again') self.setStatusMessage('Finished!') output_channel = self.host_results_dir if self.RunMode == OWSTARAlignment.RunMode_GenerateGenome: output_channel = self.starindexDirectory self.send("Directory", output_channel) self.btnStarAlignment.setEnabled(True) def run_star_message(self, msgType, message): if msgType == 'warning': self.warning(message) elif msgType == 'error': self.error(message)
def __init__(self): super().__init__() self.result_folder_name = "Results" self.host_counts_dir = None self.host_config_dir = None self.host_param_dir = None # This client talks to your local docker self.docker = DockerClient('unix:///var/run/docker.sock', 'local') # GUI self.setStyleSheet("QPushButton{\n" " background-color: #1588c5;\n" " color: white;\n" " height: 25px;\n" " border: 1px solid #1a8ac6;\n" "}") # creat controls self.vlayoutBase = QtWidgets.QVBoxLayout() self.vlayoutBase.setSizeConstraint( QtWidgets.QLayout.SetDefaultConstraint) self.vlayoutBase.setContentsMargins(0, 0, 0, 0) self.vlayoutBase.setSpacing(0) self.vlayoutBase.setObjectName("vlayoutBase") self.vlayoutBase = QtWidgets.QVBoxLayout() self.vlayoutBase.setContentsMargins(0, 0, 0, 0) self.vlayoutBase.setSpacing(0) self.vlayoutBase.setObjectName("vlayoutBase") self.verticalLayout = QtWidgets.QVBoxLayout() self.verticalLayout.setSizeConstraint( QtWidgets.QLayout.SetDefaultConstraint) self.verticalLayout.setSpacing(0) self.verticalLayout.setObjectName("verticalLayout") self.frameTitle = QtWidgets.QFrame(self.mainArea) self.frameTitle.setEnabled(True) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.frameTitle.sizePolicy().hasHeightForWidth()) self.frameTitle.setSizePolicy(sizePolicy) self.frameTitle.setMinimumSize(QtCore.QSize(0, 45)) self.frameTitle.setMaximumSize(QtCore.QSize(16777215, 65)) self.frameTitle.setStyleSheet("QFrame#frameTitle{\n" " background: #1588c5;\n" " color: #1588c5\n" "}") self.frameTitle.setFrameShape(QtWidgets.QFrame.Box) self.frameTitle.setFrameShadow(QtWidgets.QFrame.Plain) self.frameTitle.setObjectName("frameTitle") self.lblFormTitle = QtWidgets.QLabel(self.frameTitle) self.lblFormTitle.setGeometry(QtCore.QRect(10, 13, 221, 21)) font = QtGui.QFont() font.setPointSize(18) font.setBold(False) font.setWeight(50) self.lblFormTitle.setFont(font) self.lblFormTitle.setStyleSheet("\n" " color: white;\n" "") self.lblFormTitle.setObjectName("lblFormTitle") self.verticalLayout.addWidget(self.frameTitle) self.mainContent = QtWidgets.QWidget(self.mainArea) self.mainContent.setObjectName("mainContent") self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.mainContent) self.verticalLayout_4.setContentsMargins(15, 15, 15, 15) self.verticalLayout_4.setObjectName("verticalLayout_4") self.vlayout_content = QtWidgets.QVBoxLayout() self.vlayout_content.setSizeConstraint( QtWidgets.QLayout.SetDefaultConstraint) self.vlayout_content.setSpacing(2) self.vlayout_content.setObjectName("vlayout_content") self.lblExpFile = QtWidgets.QLabel(self.mainContent) self.lblExpFile.setMinimumSize(QtCore.QSize(0, 25)) self.lblExpFile.setMaximumSize(QtCore.QSize(16777215, 25)) self.lblExpFile.setObjectName("lblExpFile") self.vlayout_content.addWidget(self.lblExpFile) self.horizontalLayout = QtWidgets.QHBoxLayout() self.horizontalLayout.setSizeConstraint( QtWidgets.QLayout.SetDefaultConstraint) self.horizontalLayout.setContentsMargins(0, -1, -1, -1) self.horizontalLayout.setSpacing(1) self.horizontalLayout.setObjectName("horizontalLayout") self.edtExpDesignFile = QtWidgets.QLineEdit(self.mainContent) self.edtExpDesignFile.setObjectName("edtExpDesignFile") self.horizontalLayout.addWidget(self.edtExpDesignFile) self.btnSelectExpFile = QtWidgets.QPushButton(self.mainContent) self.btnSelectExpFile.setMinimumSize(QtCore.QSize(24, 24)) self.btnSelectExpFile.setMaximumSize(QtCore.QSize(24, 24)) self.btnSelectExpFile.setObjectName("btnSelectExpFile") self.horizontalLayout.addWidget(self.btnSelectExpFile) self.vlayout_content.addLayout(self.horizontalLayout) self.line_2 = QtWidgets.QFrame(self.mainContent) self.line_2.setFrameShape(QtWidgets.QFrame.HLine) self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken) self.line_2.setObjectName("line_2") self.vlayout_content.addWidget(self.line_2) self.lblInfoTitle = QtWidgets.QLabel(self.mainContent) self.lblInfoTitle.setMinimumSize(QtCore.QSize(0, 25)) self.lblInfoTitle.setMaximumSize(QtCore.QSize(16777215, 25)) self.lblInfoTitle.setStyleSheet( "background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(235, 235, 235, 255), stop:1 rgba(217, 217, 217, 255));\n" "padding-left: 3px;") self.lblInfoTitle.setObjectName("lblInfoTitle") self.vlayout_content.addWidget(self.lblInfoTitle) self.line = QtWidgets.QFrame(self.mainContent) self.line.setFrameShape(QtWidgets.QFrame.HLine) self.line.setFrameShadow(QtWidgets.QFrame.Sunken) self.line.setObjectName("line") self.vlayout_content.addWidget(self.line) self.infoLabel = QtWidgets.QLabel(self.mainContent) self.infoLabel.setMinimumSize(QtCore.QSize(0, 45)) self.infoLabel.setStyleSheet("padding-left: 3px") self.infoLabel.setFrameShape(QtWidgets.QFrame.NoFrame) self.infoLabel.setAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop) self.infoLabel.setWordWrap(True) self.infoLabel.setObjectName("infoLabel") self.vlayout_content.addWidget(self.infoLabel) self.btn_run = QtWidgets.QPushButton(self.mainContent) self.btn_run.setMinimumSize(QtCore.QSize(90, 0)) self.btn_run.setMaximumSize(QtCore.QSize(90, 16777215)) self.btn_run.setObjectName("btn_run") self.vlayout_content.addWidget(self.btn_run, 0, QtCore.Qt.AlignRight) self.verticalLayout_4.addLayout(self.vlayout_content) self.verticalLayout.addWidget(self.mainContent) self.vlayoutBase.addLayout(self.verticalLayout) self.mainArea.layout().addLayout(self.vlayoutBase) self.mainArea.layout().setContentsMargins(0, 0, 0, 0) self.mainArea.setMinimumSize(568, 246) # events self.btnSelectExpFile.clicked.connect(self.OnChooseExpFile) self.btn_run.clicked.connect(self.start_analysis) self.retranslateUi(self.mainArea)
class FastQCAnalysis(widget.OWWidget): name = "FastQC Analysis" description = "Step 2 of Dtoxs SOP. Uses edgeR for differential expression analysis." category = "RNASeq" icon = "icons/dtoxs-analysis2.svg" priority = 10 image_name = "conradstoerker/fastqc" image_version = "latest" inputs = [("Counts", str, "set_aligns")] outputs = [("Results", str)] want_main_area = False # The directory of the alignment data needed to run # the container will be set by the user before the # container can be run host_counts_dir = "" def __init__(self): super().__init__() # Docker Client # This client talks to your local docker self.docker = DockerClient('unix:///var/run/docker.sock', 'local') # GUI box = gui.widgetBox(self.controlArea, "Info") self.infoLabel = gui.widgetLabel(box, 'Connect to Dtoxs Alignment or use a Directory widget' ' to specify location of UMI read counts data files') self.infoLabel.setWordWrap(True) # TODO let user specify results directory # self.btn_res = gui.button(None, self, "Open", callback=self.set_results_dir) # self.resultsEdit = QtGui.QLineEdit(self.host_results_dir) # self.buttonsArea.layout().addWidget(self.btn_res) # self.buttonsArea.layout().addWidget(self.resultsEdit) self.autoRun = True gui.checkBox(self.controlArea, self, 'autoRun', 'Run automatically when input set') self.btn_run = gui.button(self.controlArea, self, "Run", callback=self.start_analysis) """ Set input """ def set_aligns(self, path): if not type(path) is str: # TODO create warning print('Tried to set alignment directory to None') elif not os.path.exists(path): # TODO create warning print('Tried to set alignment directory to none existent directory: ' + str(path)) else: self.host_counts_dir = path.strip() if self.autoRun: self.start_analysis() else: self.infoLabel.setText('Alignment directory set.\nWaiting to run...') """ Pull image """ def pull_image(self): self.infoLabel.setText('Pulling \'' + self.image_name + ":" + self.image_version + '\' from Dockerhub...') self.setStatusMessage("Downloading...") self.progressBarInit() self.btn_run.setEnabled(False) # Pull the image in a new thread self.pull_image_thread = PullImageThread(self.docker, self.image_name, self.image_version) self.pull_image_thread.pull_progress.connect(self.pull_image_progress) self.pull_image_thread.finished.connect(self.pull_image_done) self.pull_image_thread.start() def pull_image_progress(self, val=0): self.progressBarSet(val) def pull_image_done(self): self.infoLabel.setText('Finished pulling \'' + self.image_name + ":" + self.image_version + '\'') self.progressBarFinished() self.run_analysis() """ Analysis """ def start_analysis(self): # Make sure the docker image is downloaded if not self.docker.has_image(self.image_name, self.image_version): self.pull_image() # Make sure there is an alignment directory set elif self.host_counts_dir: self.run_analysis() else: self.infoLabel.setText('Set alignment directory before running.') def run_analysis(self): self.infoLabel.setText('Running analysis...') self.setStatusMessage('Running...') self.progressBarInit() # Run the container in a new thread self.run_analysis_thread = RunAnalysisThread(self.docker, self.image_name, self.host_counts_dir, self.host_counts_dir) self.run_analysis_thread.analysis_progress.connect(self.run_analysis_progress) self.run_analysis_thread.finished.connect(self.run_analysis_done) self.run_analysis_thread.start() def run_analysis_progress(self, val): self.progressBarSet(val) def run_analysis_done(self): self.infoLabel.setText("Finished running analysis!") self.btn_run.setEnabled(True) self.btn_run.setText('Run again') self.setStatusMessage('Finished!') self.progressBarFinished() self.send("Results", self.host_counts_dir)
class OWSTARAlignment(widget.OWWidget): name = "Star Alignment" description = "Performs alignment of fastqs to bam via STAR" category = "RNASeq" icon = "icons/staralignment.svg" priority = 10 inputs = [("FastQ Files", str, "setFastqInput", widget.Default), ("Genome Dir", str, "setGenomeDir")] outputs = [("Directory", str)] want_main_area = False dockerClient = DockerClient('unix:///var/run/docker.sock', 'local') image_name = "biodepot/ubuntu-star" image_version = "latest" def __init__(self): super().__init__() self.bFastqDirSet = False self.bStarIndexDirSet = False # GUI box = gui.widgetBox(self.controlArea, "Info") self.info_fastq = gui.widgetLabel(box, 'Please specify a directory with fastq files.') self.info_starindex = gui.widgetLabel(box, 'Please specify a genome directory.') self.info_fastq.setWordWrap(True) self.info_starindex.setWordWrap(True) self.AutoStarAlignment = False gui.checkBox(self.controlArea, self, 'AutoStarAlignment', 'Run automatically when directory was set.') self.btnStarAlignment = gui.button(self.controlArea, self, "Star Alignment", callback=self.StartStarAlignment) self.btnStarAlignment.setEnabled(False) def setFastqInput(self, path): # When a user removes a connected Directory widget, # it sends a signal with path=None if path is None: self.bFastqDirSet = False else: if not os.path.exists(path): self.bFastqDirSet = False print('References set to invalid directory') else: self.fastqDirectory = path self.bFastqDirSet = True self.info_fastq.setText("Fastq files: {0}".format(self.fastqDirectory)) self.btnStarAlignment.setEnabled(self.bFastqDirSet and self.bStarIndexDirSet) if self.bFastqDirSet and self.bStarIndexDirSet and self.AutoStarAlignment: self.StartStarAlignment() def setGenomeDir(self, path): if path is None: self.bStarIndexDirSet = False else: if not os.path.exists(path): self.bStarIndexDirSet = False print('References set to invalid directory') else: self.starindexDirectory = path self.bStarIndexDirSet = True self.info_starindex.setText("Star index: {0}".format(self.starindexDirectory)) self.btnStarAlignment.setEnabled(self.bFastqDirSet and self.bStarIndexDirSet) if self.bFastqDirSet and self.bStarIndexDirSet and self.AutoStarAlignment: self.StartStarAlignment() def StartStarAlignment(self): if not self.bFastqDirSet or not self.bStarIndexDirSet: return if not self.dockerClient.has_image(self.image_name, self.image_version): self.pull_image() elif self.bFastqDirSet and self.bStarIndexDirSet: self.run_staralignment() """ Pull image """ def pull_image(self): self.info_fastq.setText('Pulling \'' + self.image_name + ":" + self.image_version) self.info_starindex.setText('') self.setStatusMessage("Downloading...") self.progressBarInit() self.btnStarAlignment.setEnabled(False) # Pull the image in a new thread self.pull_image_thread = PullImageThread(self.dockerClient, self.image_name, self.image_version) self.pull_image_thread.pull_progress.connect(self.pull_image_progress) self.pull_image_thread.finished.connect(self.pull_image_done) self.pull_image_thread.start() def pull_image_progress(self, val=0): self.progressBarSet(val) def pull_image_done(self): self.info_fastq.setText('Finished pulling \'' + self.image_name + ":" + self.image_version + '\'') self.progressBarFinished() self.run_staralignment() def run_staralignment(self): self.btnStarAlignment.setEnabled(False) self.info_fastq.setText('Running star alignment...') self.info_starindex.setText('') self.setStatusMessage('Running...') #self.progressBarInit() # Run the container in a new thread self.run_staralignment_thread = StarAlignmentThread(self.dockerClient, self.image_name, self.image_version, self.fastqDirectory, self.starindexDirectory, self.fastqDirectory) self.run_staralignment_thread.analysis_progress.connect(self.run_staralignment_progress) self.run_staralignment_thread.finished.connect(self.run_staralignment_done) self.run_staralignment_thread.start() def run_staralignment_progress(self, val): self.progressBarSet(val) def run_staralignment_done(self): self.info_fastq.setText("Finished running analysis!") self.btnStarAlignment.setEnabled(True) self.btnStarAlignment.setText('Run again') self.setStatusMessage('Finished!') #self.progressBarFinished() self.send("Directory", self.fastqDirectory) self.btnStarAlignment.setEnabled(True)
class OWUnpack(widget.OWWidget): name = "UnPack" description = "Unpack compressed fastqc files" icon = "icons/unpack.svg" priority = 10 inputs = [("Unpack", str, "setDirectory", widget.Default)] outputs = [("Directory", str)] want_main_area = False dockerClient = DockerClient('unix:///var/run/docker.sock', 'local') def __init__(self): super().__init__() self.inputDirectory = None self.bDirectorySet = False; # GUI box = gui.widgetBox(self.controlArea, "Info") self.infoa = gui.widgetLabel(box, 'Please specify a directory.') self.infob = gui.widgetLabel(box, '') self.infoa.setWordWrap(True) self.infob.setWordWrap(True) self.AutoUnpack = False gui.checkBox(self.controlArea, self, 'AutoUnpack', 'Run automatically when directory was set.') self.mergeFile = True gui.checkBox(self.controlArea, self, "mergeFile", "Merge files into R1.fastq and R2.fastq") self.btnUnpack = gui.button(self.controlArea, self, "Unpack", callback=self.StartUnpack) self.btnUnpack.setEnabled(False) """ Set Unpack Directory """ def setDirectory(self, path): # When a user removes a connected Directory widget, # it sends a signal with path=None if path is None: self.bDirectorySet = False else: if not os.path.exists(path): self.bDirectorySet = False print('References set to invalid directory') else: self.inputDirectory = path self.bDirectorySet = True self.infoa.setText("Directory: {0}".format(self.inputDirectory)) self.btnUnpack.setEnabled(self.bDirectorySet) if self.bDirectorySet and self.AutoUnpack: self.StartUnpack() """ Do Unpack tar file:///path/to/sample.tar # fq paired file:///path/to/R1.fq.gz,file:///path/to/R2.fq.gz # tar single http://sample-depot.com/single-end-sample.tar # tar paired s3://my-bucket-name/directory/paired-sample.tar.gz # fq single s3://my-bucket-name/directory/single-end-file.fq now, only consider [fq paired] """ def StartUnpack(self): if not self.bDirectorySet: return self.progressBarInit() command = ['tar', '-zxf'] if platform.system() == "Darwin": #command = ['gunzip', '-k'] command = ['gunzip'] fastq_files = [] for root, subdir, files in os.walk(self.inputDirectory): fastq_files.extend([os.path.join(root, x) for x in files]) if self.mergeFile: r1, r2 = [], [] # Pattern convention: Look for "R1" / "R2" in the filename, or "_1" / "_2" before the extension pattern = re.compile('(?:^|[._-])(R[12]|[12]\.f)') for fastq in sorted(fastq_files): match = pattern.search(os.path.basename(fastq)) if not match: print ('Invalid FASTQ file: {0}, ignore it.'.format(fastq)) continue elif '1' in match.group(): r1.append(fastq) elif '2' in match.group(): r2.append(fastq) if len(r1) != len(r2): self.error('Check fastq names, uneven number of pairs found.') print ('Check fastq names, uneven number of pairs found.\nr1: {}\nr2: {}'.format(r1, r2)) return if len(r1) == 0: return if platform.system() == "Darwin": command = ['gunzip', '-c'] if r1[0].endswith('.gz') and r2[0].endswith('.gz') else ['cat'] else: command = ['zcat'] if r1[0].endswith('.gz') and r2[0].endswith('.gz') else ['cat'] R1_file = open(os.path.join(self.inputDirectory, 'R1.fastq'), 'a') R2_file = open(os.path.join(self.inputDirectory, 'R2.fastq'), 'a') for i in range(len(r1)): p1 = subprocess.Popen(command + [str(r1[i])], stdout = R1_file) p2 = subprocess.Popen(command + [str(r2[i])], stdout = R2_file) p1.wait() p2.wait() self.progressBarSet((i + 1) / len(r1) * 100) R1_file.flush() R2_file.flush() else: for index, fastq in enumerate(sorted(fastq_files)): print("Unpacking....{0}".format(fastq)) if not fastq.endswith('.gz'): print ("Not supported file format {0}".format(fastq)) else: runcommand = command + [fastq] #print (runcommand) processor = subprocess.Popen(runcommand) processor.wait() self.progressBarSet((index+1)/len(fastq_files)*100) #time.sleep(0.1) self.progressBarFinished() self.send("Directory", self.inputDirectory)
class OWDtoxsAlignment(widget.OWWidget): name = "Dtoxs Alignment" description = "Step 1 of the Dtoxs SOP. Uses a Burrows-Wheeler Aligner (BWA)." category = "RNASeq" icon = "icons/dtoxs-alignment2.svg" priority = 10 image_name = "biodepot/dtoxs_alignment" image_version = "latest" inputs = [("References", str, "set_refs"), ("Seqs", str, "set_seqs")] outputs = [("Counts", str)] auto_run = Setting(True) want_main_area = False def __init__(self): super().__init__() # Docker Client # This client talks to your local docker self.docker = DockerClient('unix:///var/run/docker.sock', 'local') # The directory of the seq data needed to run # the container will be set by the user before the # container can be run self.host_ref_dir = None self.host_seq_dir = None self.ref_dir_set = False self.seq_dir_set = False # The default write location of all widgets should be # ~/BioDepot/WidgetName/ # TODO is this an issue if multiple containers write to the same place? # TODO add timestamp to directory name to differentiate runs counts_dir = '~/BioDepot/Dtoxs_Alignment/Counts' if not os.path.exists(counts_dir): os.makedirs(counts_dir) self.host_counts_dir = self.docker.toHostDir(counts_dir) # GUI box = gui.widgetBox(self.controlArea, "Info") self.infoLabel = gui.widgetLabel( box, 'Connect to a Directory widget ' 'to specify location of reference ' 'and seq fastq files') self.infoLabel.setWordWrap(True) gui.checkBox(self.controlArea, self, 'auto_run', 'Run automatically when input set') self.btn_run = gui.button(self.controlArea, self, "Run", callback=self.btn_run_pushed) self.is_running = False """ Called when the user pushes 'Run' """ def btn_run_pushed(self): self.start_container(run_btn_pushed=True) """ Set references """ def set_refs(self, path): # When a user removes a connected Directory widget, # it sends a signal with path=None if path is None: self.ref_dir_set = False else: self.host_ref_dir = self.docker.toHostDir(path) if self.host_ref_dir is None: # TODO emit error self.ref_dir_set = False print('References set to invalid directory') else: self.ref_dir_set = True self.start_container(run_btn_pushed=False) """ Set seqs """ def set_seqs(self, path): # When a user removes a connected Directory widget, # it sends a signal with path=None if path is None: self.seq_dir_set = False else: self.host_seq_dir = self.docker.toHostDir(path) if self.host_seq_dir is None: # TODO emit error self.seq_dir_set = False print('Seq set to invalid directory') else: self.seq_dir_set = True self.start_container(run_btn_pushed=False) """ Pull image """ def pull_image(self): self.infoLabel.setText('Pulling \'' + self.image_name + ":" + self.image_version + '\' from Dockerhub...') self.setStatusMessage("Downloading...") self.progressBarInit() self.is_running = True self.btn_run.setEnabled(False) # Pull the image in a new thread self.pull_image_thread = QThread() self.pull_image_worker = PullImageWorker(self.docker, self.image_name, self.image_version) self.pull_image_worker.progress[int].connect(self.pull_image_progress) self.pull_image_worker.finished.connect(self.pull_image_finished) self.pull_image_worker.moveToThread(self.pull_image_thread) self.pull_image_thread.started.connect(self.pull_image_worker.work) self.pull_image_thread.start() @pyqtSlot(int, name="pullImageProgress") def pull_image_progress(self, val): self.progressBarSet(val) @pyqtSlot(name="pullImageFinished") def pull_image_finished(self): self.pull_image_thread.terminate() self.pull_image_thread.wait() self.infoLabel.setText('Finished pulling \'' + self.image_name + ":" + self.image_version + '\'') self.progressBarFinished() self.start_container() """ Alignment """ def start_container(self, run_btn_pushed=True): # Make sure both inputs are set if self.ref_dir_set and self.seq_dir_set: if not self.is_running and (self.auto_run or run_btn_pushed): # Make sure the docker image is downloaded if not self.docker.has_image(self.image_name, self.image_version): self.pull_image() else: self.run_container() else: self.infoLabel.setText( 'References and Seqs directories set.\nWaiting to run...') elif self.ref_dir_set: self.infoLabel.setText("Waiting for user to set Seqs directory.") elif self.seq_dir_set: self.infoLabel.setText( "Waiting for user to set References directory.") def run_container(self): self.is_running = True self.infoLabel.setText('Running alignment...') self.setStatusMessage('Running...') self.progressBarInit() # Run the container in a new thread self.run_container_thread = QThread() self.run_container_worker = RunAlignmentWorker(self.docker, self.image_name, self.host_ref_dir, self.host_seq_dir, self.host_counts_dir) self.run_container_worker.progress[int].connect( self.run_container_progress) self.run_container_worker.finished.connect(self.run_container_finished) self.run_container_worker.moveToThread(self.run_container_thread) self.run_container_thread.started.connect( self.run_container_worker.work) self.run_container_thread.start() @pyqtSlot(int, name="runContainerProgress") def run_container_progress(self, val): self.progressBarSet(val) @pyqtSlot(name="runContainerFinished") def run_container_finished(self): self.run_container_thread.terminate() self.run_container_thread.wait() self.infoLabel.setText("Finished running alignment!") self.btn_run.setEnabled(True) self.is_running = False self.btn_run.setText('Run again') self.setStatusMessage('Finished!') self.progressBarFinished() self.send("Counts", self.docker.toContainerDir(self.host_counts_dir))
class OWSBowtie2(widget.OWWidget): RunMode_GenerateGenome = 0 RunMode_STAR = 1 name = "Bowtie2" description = "An ultrafast memory-efficient short read aligner" category = "RNASeq" icon = "icons/bowtie.png" priority = 10 inputs = [("FQ Files", str, "setFastqInput", widget.Default), ("Bt2 Index", str, "setStarIndexDir")] outputs = [("SAM Files", str)] want_main_area = False dockerClient = DockerClient('unix:///var/run/docker.sock', 'local') image_name = "biocontainers/bowtie2" image_version = "latest" def __init__(self): super().__init__() self.bFastqDirSet = False self.bStarIndexDirSet = False # GUI box = gui.widgetBox(self.controlArea, "Info") self.info_fastq = gui.widgetLabel( box, 'Please specify a directory with FQ files.') self.info_fastq.setWordWrap(True) self.AutoBowtie2 = False self.info_starindex = gui.widgetLabel( box, 'Please specify a directory with bt2 index.') self.info_starindex.setWordWrap(True) gui.checkBox(self.controlArea, self, 'AutoBowtie2', 'Run automatically when directory was set.') self.btnStartBowtie2 = gui.button(self.controlArea, self, "Star Bowtie2", callback=self.StartBowtie2) self.btnStartBowtie2.setEnabled(False) def setFastqInput(self, path): # When a user removes a connected Directory widget, # it sends a signal with path=None if path is None: self.bFastqDirSet = False else: if not os.path.exists(path): self.bFastqDirSet = False print('References set to invalid directory') else: self.fastqDirectory = path self.bFastqDirSet = True self.info_fastq.setText("FQ files: {0}".format( self.fastqDirectory)) self.btnStartBowtie2.setEnabled(self.bFastqDirSet) if self.bFastqDirSet and self.AutoBowtie2 and self.bStarIndexDirSet: self.StartBowtie2() def setStarIndexDir(self, path): if path is None: self.bStarIndexDirSet = False else: if not os.path.exists(path): self.bStarIndexDirSet = False print('References set to invalid directory') else: self.starindexDirectory = path self.bStarIndexDirSet = True self.info_starindex.setText("Bt2 index: {0}".format( self.starindexDirectory)) self.btnStartBowtie2.setEnabled(self.bFastqDirSet and self.bStarIndexDirSet) if self.bFastqDirSet and self.bStarIndexDirSet and self.AutoBowtie2: self.StartBowtie2() def StartBowtie2(self): if not self.bFastqDirSet or not self.bStarIndexDirSet: return if not self.dockerClient.has_image(self.image_name, self.image_version): self.pull_image() elif self.bFastqDirSet: self.run_startbowtie2() """ Pull image """ def pull_image(self): self.info_fastq.setText('Pulling \'' + self.image_name + ":" + self.image_version) self.info_starindex.setText('') self.setStatusMessage("Downloading...") self.progressBarInit() self.btnStartBowtie2.setEnabled(False) # Pull the image in a new thread self.pull_image_thread = PullImageThread(self.dockerClient, self.image_name, self.image_version) self.pull_image_thread.pull_progress.connect(self.pull_image_progress) self.pull_image_thread.finished.connect(self.pull_image_done) self.pull_image_thread.start() def pull_image_progress(self, val=0): self.progressBarSet(val) def pull_image_done(self): self.info_fastq.setText('Finished pulling \'' + self.image_name + ":" + self.image_version + '\'') self.progressBarFinished() self.run_startbowtie2() def run_startbowtie2(self): self.btnStartBowtie2.setEnabled(False) self.info_fastq.setText('Running bowtie alignment...') self.setStatusMessage('Running...') #self.progressBarInit() # Run the container in a new thread self.run_startbowtie2_thread = Bowtie2Thread(self.dockerClient, self.image_name, self.image_version, self.fastqDirectory, self.starindexDirectory) self.run_startbowtie2_thread.analysis_progress.connect( self.run_startbowtie2_progress) self.run_startbowtie2_thread.finished.connect( self.run_startbowtie2_done) self.run_startbowtie2_thread.start() def run_startbowtie2_progress(self, val): self.progressBarSet(val) def run_startbowtie2_done(self): self.info_fastq.setText("Finished run bowtie2") self.btnStartBowtie2.setEnabled(True) self.btnStartBowtie2.setText('Run again') self.setStatusMessage('Finished!') output_channel = self.fastqDirectory self.send("SAM Files", output_channel)
class OWDtoxsAnalysis(widget.OWWidget): name = "Dtoxs Analysis" description = "Step 2 of Dtoxs SOP. Uses edgeR for differential expression analysis." category = "RNASeq" icon = "icons/dtoxs-analysis2.svg" priority = 10 image_name = "biodepot/dtoxs_analysis" image_version = "latest" inputs = [("Counts", str, "set_aligns", widget.Default), ("Configs", str, "set_configs"), ("Params", str, "set_params")] outputs = [("Results", str), ("Top 40", Orange.data.Table)] want_main_area = True want_control_area = False Exp_Design_file = settings.Setting('', schema_only=True) def __init__(self): super().__init__() self.result_folder_name = "Results" self.host_counts_dir = None self.host_config_dir = None self.host_param_dir = None # This client talks to your local docker self.docker = DockerClient('unix:///var/run/docker.sock', 'local') # GUI self.setStyleSheet("QPushButton{\n" " background-color: #1588c5;\n" " color: white;\n" " height: 25px;\n" " border: 1px solid #1a8ac6;\n" "}") # creat controls self.vlayoutBase = QtWidgets.QVBoxLayout() self.vlayoutBase.setSizeConstraint( QtWidgets.QLayout.SetDefaultConstraint) self.vlayoutBase.setContentsMargins(0, 0, 0, 0) self.vlayoutBase.setSpacing(0) self.vlayoutBase.setObjectName("vlayoutBase") self.vlayoutBase = QtWidgets.QVBoxLayout() self.vlayoutBase.setContentsMargins(0, 0, 0, 0) self.vlayoutBase.setSpacing(0) self.vlayoutBase.setObjectName("vlayoutBase") self.verticalLayout = QtWidgets.QVBoxLayout() self.verticalLayout.setSizeConstraint( QtWidgets.QLayout.SetDefaultConstraint) self.verticalLayout.setSpacing(0) self.verticalLayout.setObjectName("verticalLayout") self.frameTitle = QtWidgets.QFrame(self.mainArea) self.frameTitle.setEnabled(True) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.frameTitle.sizePolicy().hasHeightForWidth()) self.frameTitle.setSizePolicy(sizePolicy) self.frameTitle.setMinimumSize(QtCore.QSize(0, 45)) self.frameTitle.setMaximumSize(QtCore.QSize(16777215, 65)) self.frameTitle.setStyleSheet("QFrame#frameTitle{\n" " background: #1588c5;\n" " color: #1588c5\n" "}") self.frameTitle.setFrameShape(QtWidgets.QFrame.Box) self.frameTitle.setFrameShadow(QtWidgets.QFrame.Plain) self.frameTitle.setObjectName("frameTitle") self.lblFormTitle = QtWidgets.QLabel(self.frameTitle) self.lblFormTitle.setGeometry(QtCore.QRect(10, 13, 221, 21)) font = QtGui.QFont() font.setPointSize(18) font.setBold(False) font.setWeight(50) self.lblFormTitle.setFont(font) self.lblFormTitle.setStyleSheet("\n" " color: white;\n" "") self.lblFormTitle.setObjectName("lblFormTitle") self.verticalLayout.addWidget(self.frameTitle) self.mainContent = QtWidgets.QWidget(self.mainArea) self.mainContent.setObjectName("mainContent") self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.mainContent) self.verticalLayout_4.setContentsMargins(15, 15, 15, 15) self.verticalLayout_4.setObjectName("verticalLayout_4") self.vlayout_content = QtWidgets.QVBoxLayout() self.vlayout_content.setSizeConstraint( QtWidgets.QLayout.SetDefaultConstraint) self.vlayout_content.setSpacing(2) self.vlayout_content.setObjectName("vlayout_content") self.lblExpFile = QtWidgets.QLabel(self.mainContent) self.lblExpFile.setMinimumSize(QtCore.QSize(0, 25)) self.lblExpFile.setMaximumSize(QtCore.QSize(16777215, 25)) self.lblExpFile.setObjectName("lblExpFile") self.vlayout_content.addWidget(self.lblExpFile) self.horizontalLayout = QtWidgets.QHBoxLayout() self.horizontalLayout.setSizeConstraint( QtWidgets.QLayout.SetDefaultConstraint) self.horizontalLayout.setContentsMargins(0, -1, -1, -1) self.horizontalLayout.setSpacing(1) self.horizontalLayout.setObjectName("horizontalLayout") self.edtExpDesignFile = QtWidgets.QLineEdit(self.mainContent) self.edtExpDesignFile.setObjectName("edtExpDesignFile") self.horizontalLayout.addWidget(self.edtExpDesignFile) self.btnSelectExpFile = QtWidgets.QPushButton(self.mainContent) self.btnSelectExpFile.setMinimumSize(QtCore.QSize(24, 24)) self.btnSelectExpFile.setMaximumSize(QtCore.QSize(24, 24)) self.btnSelectExpFile.setObjectName("btnSelectExpFile") self.horizontalLayout.addWidget(self.btnSelectExpFile) self.vlayout_content.addLayout(self.horizontalLayout) self.line_2 = QtWidgets.QFrame(self.mainContent) self.line_2.setFrameShape(QtWidgets.QFrame.HLine) self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken) self.line_2.setObjectName("line_2") self.vlayout_content.addWidget(self.line_2) self.lblInfoTitle = QtWidgets.QLabel(self.mainContent) self.lblInfoTitle.setMinimumSize(QtCore.QSize(0, 25)) self.lblInfoTitle.setMaximumSize(QtCore.QSize(16777215, 25)) self.lblInfoTitle.setStyleSheet( "background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(235, 235, 235, 255), stop:1 rgba(217, 217, 217, 255));\n" "padding-left: 3px;") self.lblInfoTitle.setObjectName("lblInfoTitle") self.vlayout_content.addWidget(self.lblInfoTitle) self.line = QtWidgets.QFrame(self.mainContent) self.line.setFrameShape(QtWidgets.QFrame.HLine) self.line.setFrameShadow(QtWidgets.QFrame.Sunken) self.line.setObjectName("line") self.vlayout_content.addWidget(self.line) self.infoLabel = QtWidgets.QLabel(self.mainContent) self.infoLabel.setMinimumSize(QtCore.QSize(0, 45)) self.infoLabel.setStyleSheet("padding-left: 3px") self.infoLabel.setFrameShape(QtWidgets.QFrame.NoFrame) self.infoLabel.setAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop) self.infoLabel.setWordWrap(True) self.infoLabel.setObjectName("infoLabel") self.vlayout_content.addWidget(self.infoLabel) self.btn_run = QtWidgets.QPushButton(self.mainContent) self.btn_run.setMinimumSize(QtCore.QSize(90, 0)) self.btn_run.setMaximumSize(QtCore.QSize(90, 16777215)) self.btn_run.setObjectName("btn_run") self.vlayout_content.addWidget(self.btn_run, 0, QtCore.Qt.AlignRight) self.verticalLayout_4.addLayout(self.vlayout_content) self.verticalLayout.addWidget(self.mainContent) self.vlayoutBase.addLayout(self.verticalLayout) self.mainArea.layout().addLayout(self.vlayoutBase) self.mainArea.layout().setContentsMargins(0, 0, 0, 0) self.mainArea.setMinimumSize(568, 246) # events self.btnSelectExpFile.clicked.connect(self.OnChooseExpFile) self.btn_run.clicked.connect(self.start_analysis) self.retranslateUi(self.mainArea) def retranslateUi(self, Form): _translate = QtCore.QCoreApplication.translate Form.setWindowTitle(_translate("Widget", "Form")) self.lblFormTitle.setText(_translate("Widget", "DTOXS Analysis")) self.lblExpFile.setText( _translate("Widget", "Select experiment design file:")) self.btnSelectExpFile.setText(_translate("Widget", " ☰ ")) self.lblInfoTitle.setText(_translate("Widget", "Information")) self.infoLabel.setText( _translate( "Widget", "Connect to Dtoxs Alignment or use a Directory widget to specify location of UMI read counts data files" )) self.btn_run.setText(_translate("Widget", "Run")) self.edtExpDesignFile.setText(self.Exp_Design_file) """ Set input """ def set_aligns(self, path): if not type(path) is str: # TODO create warning print('Tried to set alignment directory to None') elif not os.path.exists(path): # TODO create warning print( 'Tried to set alignment directory to none existent directory: ' + str(path)) else: self.host_counts_dir = path.strip() # Jimmy March-29-2017, once the counts input was set, automatically create an output fold as a sibling of "Seqs" parent_path = os.path.abspath( os.path.join(self.host_counts_dir, '..')) self.host_results_dir = os.path.join(parent_path, self.result_folder_name) if not os.path.exists(self.host_results_dir): os.makedirs(self.host_results_dir) if os.path.exists(self.Exp_Design_file): import shutil shutil.copy2(self.Exp_Design_file, self.host_counts_dir) if self.host_param_dir and self.host_config_dir and self.Exp_Design_file: self.infoLabel.setText('All set.\nWaiting to run...') def set_configs(self, path): if not type(path) is str: print('Tried to set configs directory to None') elif not os.path.exists(path): print( 'Tried to set configs directory to none existent directory: ' + str(path)) else: self.host_config_dir = path.strip() if self.host_counts_dir and self.host_param_dir and self.Exp_Design_file: self.infoLabel.setText('All set.\nWaiting to run...') def set_params(self, path): if not type(path) is str: print('Tried to set params directory to None') elif not os.path.exists(path): print( 'Tried to set params directory to none existent directory: ' + str(path)) else: self.host_param_dir = path.strip() if self.host_counts_dir and self.host_config_dir and self.Exp_Design_file: self.infoLabel.setText('All set.\nWaiting to run...') def OnChooseExpFile(self): start_file = os.path.expanduser("~/") filename, _ = QtWidgets.QFileDialog.getOpenFileName( self, 'Open Experiment Design File', start_file) if not filename: return self.edtExpDesignFile.setText(filename) self.Exp_Design_file = filename if self.host_counts_dir and self.host_config_dir and self.host_param_dir: import shutil shutil.copy2(self.Exp_Design_file, self.host_counts_dir) self.infoLabel.setText('All set.\nWaiting to run...') """ Pull image """ def pull_image(self): self.infoLabel.setText('Pulling \'' + self.image_name + ":" + self.image_version + '\' from Dockerhub...') self.setStatusMessage("Downloading...") self.progressBarInit() self.btn_run.setEnabled(False) # Pull the image in a new thread self.pull_image_thread = PullImageThread(self.docker, self.image_name, self.image_version) self.pull_image_thread.pull_progress.connect(self.pull_image_progress) self.pull_image_thread.finished.connect(self.pull_image_done) self.pull_image_thread.start() def pull_image_progress(self, val): self.progressBarSet(val) def pull_image_done(self): self.infoLabel.setText('Finished pulling \'' + self.image_name + ":" + self.image_version + '\'') self.progressBarFinished() self.run_analysis() """ Analysis """ def start_analysis(self): # Make sure the docker image is downloaded if not self.docker.has_image(self.image_name, self.image_version): self.pull_image() # Make sure there is an alignment directory set elif self.host_counts_dir and self.host_config_dir and self.host_param_dir: self.run_analysis() else: self.infoLabel.setText( 'Set counts, params and configs directories before running.') def run_analysis(self): self.infoLabel.setText('Running analysis...') self.setStatusMessage('Running...') #self.progressBarInit() # Run the container in a new thread self.run_analysis_thread = RunAnalysisThread( self.docker, self.image_name, self.host_counts_dir, self.host_results_dir, self.host_config_dir, self.host_param_dir) self.run_analysis_thread.analysis_progress.connect( self.run_analysis_progress) self.run_analysis_thread.finished.connect(self.run_analysis_done) self.run_analysis_thread.start() def run_analysis_progress(self, val): self.progressBarSet(val) def run_analysis_done(self): self.infoLabel.setText("Finished running analysis!") self.btn_run.setEnabled(True) self.btn_run.setText('Run again') self.setStatusMessage('Finished!') #self.progressBarFinished() self.send("Results", self.host_results_dir) # Jimmy March 29 2017 added, create a dataset for DataTable widget to show TOP-40.tsv tsvFile = os.path.join(self.host_results_dir, 'FDR-0.1/TOP-40.tsv') tsvReader = FileFormat.get_reader(tsvFile) data = None try: data = tsvReader.read() # TODO Jimmy March 29 2017, tried to define domain for DataTable, didn't work ''' domain = Orange.data.Domain(["Cell", "Plate", "Gene", "logFC", "logCPM", "PValue"], data.domain) domain = Orange.data.Domain(data.domain.attributes, data.domain.class_vars, [Orange.data.DiscreteVariable("Cell"), Orange.data.DiscreteVariable("Plate"), Orange.data.DiscreteVariable("Condition1"), Orange.data.DiscreteVariable("Condition2"), Orange.data.StringVariable("Gene"), Orange.data.ContinuousVariable("logFC"), Orange.data.ContinuousVariable("logCPM"), Orange.data.StringVariable("PValue")]) data = data.from_table(domain, data)''' except Exception as ex: print(ex) self.send("Top 40", data)
class OWDtoxsAlignment(widget.OWWidget): name = "Dtoxs Alignment" description = "Step 1 of the Dtoxs SOP. Uses a Burrows-Wheeler Aligner (BWA)." category = "RNASeq" icon = "icons/dtoxs-alignment2.svg" priority = 10 image_name = "biodepot/dtoxs_alignment" image_version = "latest" inputs = [("References", str, "set_refs"), ("Seqs", str, "set_seqs"), ("Configs", str, "set_configs"), ("Barcodes", str, "set_barcodes_file")] outputs = [("Counts", str)] auto_run = Setting(True) want_main_area = False def __init__(self): super().__init__() # Docker Client # This client talks to your local docker self.docker = DockerClient('unix:///var/run/docker.sock', 'local') self.hostDirectories = {'refs': None, 'seqs': None, 'conf': None, 'counts': None, 'aligns': None, 'barcodes': None} self.labelText = {'refs': 'References: {0}', 'seqs': 'Sequences: {0}', 'conf': 'Configs: {0}', 'barcodes': 'Barcode file: {0}'} # folders that will created automatically self.result_folder_name = "Counts" self.aligns_folder_name = "Aligns" # GUI box = gui.widgetBox(self.controlArea, "Info") self.lblRefs = gui.widgetLabel(box, 'References: Not Set') self.lblSeqs = gui.widgetLabel(box, 'Sequences: Not Set') self.lblConfigs = gui.widgetLabel(box, 'Configs: Not Set') self.lblBarcodes = gui.widgetLabel(box, "Barcode file: Not Set") self.infoLabel = gui.widgetLabel(box, 'Waiting...') self.infoLabel.setWordWrap(True) gui.checkBox(self.controlArea, self, 'auto_run', 'Run automatically when input set') self.btn_run = gui.button(self.controlArea, self, "Run", callback=self.btn_run_pushed) self.is_running = False self.setMinimumSize(500, 200) """ Called when the user pushes 'Run' """ def btn_run_pushed(self): self.start_container(run_btn_pushed=True) """ Set references """ def set_refs(self, path): self.__set_directory__('refs', self.lblRefs, path) """ Set seqs """ def set_seqs(self, path): self.__set_directory__('seqs', self.lblSeqs, path, startContainer=False) if self.hostDirectories['seqs'] is not None: # Jimmy March-28-2017, once the seq input was set, automatically create a result and aligns folder as a sibling of "Seqs" parent_path = os.path.abspath(os.path.join(self.hostDirectories['seqs'], '..')) self.hostDirectories['counts'] = os.path.join(parent_path, self.result_folder_name) self.hostDirectories['aligns'] = os.path.join(parent_path, self.aligns_folder_name) if not os.path.exists(self.hostDirectories['counts']): os.makedirs(self.hostDirectories['counts']) if not os.path.exists(self.hostDirectories['aligns']): os.makedirs(self.hostDirectories['aligns']) self.start_container(run_btn_pushed=False) def set_configs(self, path): self.__set_directory__('conf', self.lblConfigs, path) def __set_directory__(self, key, ctrlLabel, path, startContainer = True): # When a user removes a connected Directory widget, # it sends a signal with path=None if path is None: self.hostDirectories[key] = None ctrlLabel.setText(self.labelText[key].format('Not Set')) elif not os.path.exists(path): self.hostDirectories[key] = None ctrlLabel.setText(self.labelText[key].format('None existent directory: {}'.format(str(path)))) else: self.hostDirectories[key] = path.strip() if key == 'barcodes': path = os.path.basename(path) self.hostDirectories['barcodes_basename'] = path ctrlLabel.setText(self.labelText[key].format((str(path)))) if startContainer: self.start_container(run_btn_pushed=False) def set_barcodes_file(self, filename): self.__set_directory__('barcodes', self.lblBarcodes, filename) """ Pull image """ def pull_image(self): self.infoLabel.setText('Pulling \'' + self.image_name + ":" + self.image_version + '\' from Dockerhub...') self.setStatusMessage("Downloading...") self.progressBarInit() self.is_running = True self.btn_run.setEnabled(False) # Pull the image in a new thread self.pull_image_worker = PullImageThread(self.docker, self.image_name, self.image_version) self.pull_image_worker.pull_progress.connect(self.pull_image_progress) self.pull_image_worker.finished.connect(self.pull_image_finished) self.pull_image_worker.start() def pull_image_progress(self, val): self.progressBarSet(val) def pull_image_finished(self): self.infoLabel.setText('Finished pulling \'' + self.image_name + ":" + self.image_version + '\'') self.progressBarFinished() self.run_container() """ Alignment """ def start_container(self, run_btn_pushed=True): # Make sure both inputs are set all_set = all(value is not None for value in self.hostDirectories.values()) if all_set: if not self.is_running and (self.auto_run or run_btn_pushed): # Make sure the docker image is downloaded if not self.docker.has_image(self.image_name, self.image_version): self.pull_image() else: self.run_container() def run_container(self): self.is_running = True self.btn_run.setEnabled(False) self.infoLabel.setText('Running alignment...') self.setStatusMessage('Running...') #self.progressBarInit() # Run the container in a new thread self.run_container_thread = RunAlignmentThread(self.docker, self.image_name, self.hostDirectories) self.run_container_thread.progress.connect(self.run_container_progress) self.run_container_thread.finished.connect(self.run_container_finished) self.run_container_thread.start() def run_container_progress(self, val): self.progressBarSet(val) def run_container_finished(self): self.infoLabel.setText("Finished running alignment!") self.btn_run.setEnabled(True) self.is_running = False self.btn_run.setText('Run again') self.setStatusMessage('Finished!') #self.progressBarFinished() self.send("Counts", self.hostDirectories['counts'])
class OWCutAdapt(widget.OWWidget): name = "CutAdapt" description = "CutAdapt for RNA-seq" icon = "icons/cutadapt.svg" priority = 10 inputs = [("CutAdapt", str, "setDirectory")] outputs = [("Directory", str)] want_main_area = False dockerClient = DockerClient('unix:///var/run/docker.sock', 'local') image_name = "quay.io/ucsc_cgl/cutadapt" image_version = "1.9--6bd44edd2b8f8f17e25c5a268fedaab65fa851d2" def __init__(self): super().__init__() # GUI box = gui.widgetBox(self.controlArea, "Info") self.infoa = gui.widgetLabel(box, 'Please specify a directory.') self.infob = gui.widgetLabel(box, '') self.infoa.setWordWrap(True) self.infob.setWordWrap(True) self.AutoCutAdapt = False gui.checkBox(self.controlArea, self, 'AutoCutAdapt', 'Run automatically when directory was set.') self.btnCutAdapt = gui.button(self.controlArea, self, "CutAdapt", callback=self.StartCutAdapt) self.btnCutAdapt.setEnabled(False) def setDirectory(self, path): # When a user removes a connected Directory widget, # it sends a signal with path=None if path is None: self.bDirectorySet = False else: if not os.path.exists(path): self.bDirectorySet = False print('References set to invalid directory') else: self.inputDirectory = path self.bDirectorySet = True self.infoa.setText("Directory: {0}".format( self.inputDirectory)) self.btnCutAdapt.setEnabled(self.bDirectorySet) if self.bDirectorySet and self.AutoCutAdapt: self.StartCutAdapt() def StartCutAdapt(self): if not self.bDirectorySet: return if not self.dockerClient.has_image(self.image_name, self.image_version): self.pull_image() elif self.bDirectorySet: self.run_cutadpat() """ Pull image """ def pull_image(self): self.infoa.setText('Pulling \'' + self.image_name + ":" + self.image_version) self.setStatusMessage("Downloading...") self.progressBarInit() self.btnCutAdapt.setEnabled(False) # Pull the image in a new thread self.pull_image_thread = PullImageThread(self.dockerClient, self.image_name, self.image_version) self.pull_image_thread.pull_progress.connect(self.pull_image_progress) self.pull_image_thread.finished.connect(self.pull_image_done) self.pull_image_thread.start() def pull_image_progress(self, val=0): self.progressBarSet(val) def pull_image_done(self): self.infoa.setText('Finished pulling \'' + self.image_name + ":" + self.image_version + '\'') self.progressBarFinished() self.run_cutadpat() def run_cutadpat(self): self.btnCutAdapt.setEnabled(False) self.infoa.setText('Running cutadapt...') self.setStatusMessage('Running...') self.progressBarInit() # Run the container in a new thread self.run_cutadpat_thread = CutAdaptThread(self.dockerClient, self.image_name, self.image_version, self.inputDirectory, self.inputDirectory) self.run_cutadpat_thread.analysis_progress.connect( self.run_cutadpat_progress) self.run_cutadpat_thread.finished.connect(self.run_cutadpat_done) self.run_cutadpat_thread.start() def run_cutadpat_progress(self, val): self.progressBarSet(val) def run_cutadpat_done(self): self.infoa.setText("Finished running analysis!") self.btnCutAdapt.setEnabled(True) self.btnCutAdapt.setText('Run again') self.setStatusMessage('Finished!') self.progressBarFinished() self.send("Directory", self.inputDirectory) self.btnCutAdapt.setEnabled(True)