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)
Exemple #3
0
    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)
Exemple #4
0
    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()
Exemple #6
0
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)
Exemple #9
0
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)
Exemple #10
0
    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)
Exemple #11
0
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)
Exemple #13
0
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)
Exemple #14
0
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))
Exemple #15
0
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)
Exemple #16
0
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)
Exemple #17
0
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'])
Exemple #18
0
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)