def check_running(config_path): pipe_parser = custom_config_parser() pipe_parser.load(f"{config_path}/PIPE") sh_parser = custom_config_parser() sh_parser.load(f"{config_path}/run_quandenser.sh") exit_code = int(pipe_parser.get("exit_code")) if pipe_parser.get("started") == "true": pipe_parser.write("started", "") # Reset pid = pipe_parser.get("pid") output_path = sh_parser.get("OUTPUT_PATH") output_label = sh_parser.get("OUTPUT_PATH_LABEL") output_path = output_path + output_label if pid == "": msg = QMessageBox() msg.setIcon(QMessageBox.Critical) msg.setWindowTitle("Critical fail") msg.setText(f"Unable to start nextflow. Check console output or stdout.txt at \n{output_path}\nfor more information") msg.exec_() else: now = datetime.datetime.now() with open(f"{config_path}/jobs.txt", 'a') as job_file: job_file.write(pid + '\t' + output_path + '\t' + now.strftime("%Y-%m-%d %H:%M") + ' ' + time.localtime().tm_zone + '\n') pipe_parser.write('pid', '', isString=False) # Reset pid msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setWindowTitle("Started") msg.setText("Quandenser started") msg.setDetailedText(f"PID of the process is: {pid}") msg.exec_()
def __init__(self, nf_settings_path): super(batch_file_viewer, self).__init__(parent=None) self.nf_settings_parser = custom_config_parser() self.nf_settings_parser.load(nf_settings_path) self.setRowCount(20) self.setColumnCount(2) # Fill all places so there are no "None" types in the table for row in range(self.rowCount()): for column in range(self.columnCount()): item = QTableWidgetItem() item.setText('') self.setItem(row, column, item) self.original_background = item.background() self.clipboard = QGuiApplication.clipboard() self.cellChanged.connect( self.check_cell) # Needs to be after "filling for loop" above self.header = self.horizontalHeader() self.header.setSectionResizeMode(0, QHeaderView.Stretch) self.setHorizontalHeaderLabels(["MS files", "Label"]) self.header.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.header.customContextMenuRequested.connect(self.right_click_menu) self.saved_text = '' self.store_re_text = ''
def __init__(self, nf_settings_path, id=0): super(resume_folder_viewer, self).__init__(parent=None) self.type = type self.id = id self.nf_settings_parser = custom_config_parser() self.nf_settings_parser.load(nf_settings_path) self.textChanged.connect(self.check_text)
def __init__(self, sh_path, id=0): super(label_writer, self).__init__(parent=None) self.type = type self.id = id self.sh_parser = custom_config_parser() self.sh_parser.load(sh_path) self.textChanged.connect(self.check_text)
def __init__(self, parameter, nf_settings_path): super(publish_checkbox, self).__init__(parent=None) self.nf_settings_path = nf_settings_path self.nf_settings_parser = custom_config_parser() self.nf_settings_parser.load(self.nf_settings_path) self.parameter = parameter self.default() self.stateChanged.connect(self.check_check)
def __init__(self, parameter, nf_settings_path): super(set_cpus, self).__init__(parent=None) self.nf_settings_path = nf_settings_path self.nf_settings_parser = custom_config_parser() self.nf_settings_parser.load(self.nf_settings_path) self.parameter = parameter self.valueChanged.connect(self.check_value) self.default()
def __init__(self, process, nf_settings_path): super(set_time, self).__init__(parent=None) self.nf_settings_path = nf_settings_path self.nf_settings_parser = custom_config_parser() self.nf_settings_parser.load(self.nf_settings_path) self.process = process self.default() self.textChanged.connect(self.check_text)
def __init__(self, argument, nf_settings_path): super(cluster_arguments,self).__init__(parent = None) self.nf_settings_path = nf_settings_path self.nf_settings_parser = custom_config_parser() self.nf_settings_parser.load(self.nf_settings_path) self.argument = argument self.default() self.textChanged.connect(self.check_text)
def __init__(self, parameter, settings_file): super(choose_option, self).__init__(parent=None) self.parameter = parameter self.addItems(["true", "false"]) self.parser = custom_config_parser() self.parser.load(settings_file) self.settings_file = settings_file self.default() self.currentIndexChanged.connect(self.selectionchange)
def check_corrupt(config_path): # Check for corrupt files/old/missing installed_parser = custom_config_parser() packed_parser = custom_config_parser() if not os.path.isdir(f"{config_path}"): WARNING(f"Missing config directory {config_path}. Initalizing directory") os.makedirs(config_path) files = ["ui.config", "nf.config", "PIPE", "jobs.txt", "run_quandenser.nf", "run_quandenser.sh", "nextflow"] for file in files: corrupted = False if not os.path.isfile(f"{config_path}/{file}"): WARNING(f"Missing file {file}. Installing file") shutil.copyfile(f"config/{file}", f"{config_path}/{file}") os.chmod(f"{config_path}/{file}", 0o700) # Only user will get access else: # check corrupt/old versions of config if (file.split('.')[-1] in ['config', 'sh'] or file == 'PIPE') and file != 'ui.config': installed_parser.load(f"{config_path}/{file}") installed_parameters = installed_parser.get_params() packed_parser.load(f"config/{file}") packed_parameters = packed_parser.get_params() if not installed_parameters == packed_parameters: corrupted = True elif file == "nf.config": # Check for old versions lines = open(f"{config_path}/{file}", 'r').readlines() if not any("slurm_cluster" in line for line in lines): # Very specific corrupted=True else: if not filecmp.cmp(f"{config_path}/{file}", f"config/{file}") and file not in ['ui.config', 'jobs.txt']: # check if files are the same corrupted = True if corrupted: WARNING(f"Detected old or corrupt version of {file}. Replacing file") os.remove(f"{config_path}/{file}") shutil.copyfile(f"config/{file}", f"{config_path}/{file}") os.chmod(f"{config_path}/{file}", 0o700) # Only user will get access
def __init__(self, argument, nf_settings_path): super(additional_arguments, self).__init__(parent=None) self.nf_settings_path = nf_settings_path self.nf_settings_parser = custom_config_parser() self.nf_settings_parser.load(self.nf_settings_path) self.argument = argument if "password" in self.argument: self.setEchoMode(QLineEdit.Password) # Hide password self.setText('') self.default() self.textChanged.connect(self.check_text)
def __init__(self, parameter, settings_file): super(choose_option, self).__init__(parent=None) self.parameter = parameter self.addItems(["true", "false"]) self.parser = custom_config_parser() self.parser.load(settings_file) self.settings_file = settings_file self.default() # Fix for long combo boxes delegate = QtWidgets.QStyledItemDelegate() self.setItemDelegate(delegate) self.currentIndexChanged.connect(self.selectionchange)
def __init__(self, parameter, nf_settings_path): super(parameter_setter_double, self).__init__(parent=None) self.nf_settings_path = nf_settings_path self.nf_settings_parser = custom_config_parser() self.nf_settings_parser.load(self.nf_settings_path) self.parameter = parameter if self.parameter == "params.precursor_window": # Crux self.setSuffix(" ppm") self.setMaximum(9999999) elif self.parameter == "params.fold_change_eval": # Triqler self.setSingleStep(0.05) self.default() self.valueChanged.connect(self.check_value)
def __init__(self, pipe_path, type='ms'): super(file_chooser, self).__init__(parent=None) self.setFixedWidth(200) self.type = type self.id = id self.pipe_parser = custom_config_parser() self.pipe_parser.load(pipe_path) if self.type == 'ms': self.setText('Choose MS files') elif self.type == 'fasta': self.setText('Choose fasta file') elif self.type == 'directory': self.setText('Choose output directory') self.clicked.connect(self.open_window)
def reset(self): files = ["ui.config", "nf.config", "run_quandenser.sh"] for file in files: print(Fore.YELLOW + f"Replaced {file}" + Fore.RESET) os.remove(f"{self.config_path}/{file}") shutil.copyfile(f"config/{file}", f"{self.config_path}/{file}") os.chmod(f"{self.config_path}/{file}", 0o700) # Only user will get access nf_parser = custom_config_parser() nf_parser.load(self.config_path + "/nf.config") # Read parent window = self.window() self.recurse_children(window)
def init_tab5(paths): tab5 = QWidget() tab5_layout = QVBoxLayout() tab5.setLayout(tab5_layout) pipe_parser = custom_config_parser() pipe_parser.load(paths['pipe']) if pipe_parser.get('disable-opengl') in ['false', '']: tab5_about = about() else: tab5_about = tooltip_label("OpenGL disabled", "OpenGL disabled", style=True) tab5_layout.addWidget(tab5_about) return tab5
def __init__(self, parameter, nf_settings_path): super(parameter_setter_single, self).__init__(parent=None) self.nf_settings_path = nf_settings_path self.nf_settings_parser = custom_config_parser() self.nf_settings_parser.load(self.nf_settings_path) self.parameter = parameter if self.parameter == "params.missed_cleavages": self.setMaximum(500) self.setSuffix(" cleavages") elif self.parameter == "params.max_missing": self.setMaximum(1000) self.setSuffix(" features") else: self.setMaximum(9999999) self.default() self.valueChanged.connect(self.check_value)
def __init__(self, parameter, settings_file): super(choose_option, self).__init__(parent=None) self.parameter = parameter self.parser = custom_config_parser() self.parser.load(settings_file) self.settings_file = settings_file if self.parameter == 'workflow': self.addItems(["Full", "MSconvert", "Quandenser"]) elif 'parallel' in self.parameter: self.addItems(["true", "false"]) elif self.parameter == 'profile': self.addItems(["local", "cluster"]) elif self.parameter == 'process.executor': self.addItems(["slurm"]) else: self.addItems(["true", "false"]) self.default() self.currentIndexChanged.connect(self.selectionchange)
def __init__(self): super().__init__() self.title = 'Quandenser-pipeline' self.setWindowIcon(QIcon('images/logo.png')) QFontDatabase.addApplicationFont("fonts/rockwell.ttf") self.resize(1000, 800) # Check file integrety check_corrupt(config_path) self.paths = {} self.paths['config'] = f"{config_path}" self.paths['ui'] = f"{config_path}/ui.config" self.paths['nf'] = f"{config_path}/nf.config" self.paths['sh'] = f"{config_path}/run_quandenser.sh" self.paths['pipe'] = f"{config_path}/PIPE" self.paths['jobs'] = f"{config_path}/jobs.txt" # Open pipe and read self.pipe_parser = custom_config_parser() self.pipe_parser.load(self.paths['pipe']) check_running(config_path) self.pipe_parser.write( 'exit_code', '2', isString=False ) # Add error code 2. If we manage to load, change to 1 # To restore settings of window self.settings_obj = QtCore.QSettings(self.paths['ui'], QtCore.QSettings.IniFormat) # Restore window's previous geometry from file self.setMinimumWidth(300) self.setMinimumHeight(200) self.initUI() if os.path.exists(self.paths['ui']): self.restoreGeometry(self.settings_obj.value("windowGeometry")) self.restoreState(self.settings_obj.value("State_main")) children = self.children() for child in children: self.recurse_children(child, save=False) self.show()
def __init__(self, parameter, settings_file): super(choose_option, self).__init__(parent=None) self.parameter = parameter self.parser = custom_config_parser() self.parser.load(settings_file) self.settings_file = settings_file # Fix for long combo boxes delegate = QtWidgets.QStyledItemDelegate() self.setItemDelegate(delegate) if self.parameter == 'workflow': self.addItems(["Full", "MSconvert", "Quandenser"]) elif 'parallel' in self.parameter: self.addItems(["true", "false"]) elif self.parameter == 'profile': self.addItems(["local", "cluster"]) elif self.parameter == 'process.executor': self.addItems([ "slurm", "pbs", "pbspro", "sge", "lsf", "moab", "nqsii", "condor", "ignite" ]) else: self.addItems(["true", "false"]) self.default() self.currentIndexChanged.connect(self.selectionchange)
def run(self): # Load settings self.pipe_parser = custom_config_parser() self.pipe_parser.load(self.pipe_path) self.nf_settings_parser = custom_config_parser() self.nf_settings_parser.load(self.nf_settings_path) self.sh_parser = custom_config_parser() self.sh_parser.load(self.sh_script_path) # Read parent parent = self.parentWidget() # OUTPUT_DIRECTORY # children = parent.findChildren(QLineEdit) for child in children: # This is so I can have whatever order in widgets I want if child.type == 'directory': break # Will keep child output_path = child.text() if not os.path.isdir(output_path): ERROR('Not a valid output path') return 1 # Change output parameters in both nf_settings and sh self.sh_parser.write("OUTPUT_PATH", output_path) # In sh self.nf_settings_parser.write("params.output_path", output_path) # In sh # OUTPUT_LABEL # label = self.sh_parser.get('OUTPUT_PATH_LABEL') if label != '': # Check if label has been set label = re.sub("_*", '', label) # Remove previous indexing index = 0 while True: if os.path.isdir(output_path + label + "_" + str(index)): index += 1 else: label = label + "_" + str(index) self.nf_settings_parser.write("params.output_label", label) self.sh_parser.write('OUTPUT_PATH_LABEL', label) break else: self.nf_settings_parser.write("params.output_label", '') # BATCH_FILE # child = parent.findChildren(QTableWidget)[0] full_table = [] for row in range(child.rowCount()): if not child.item(row, 0).text() == '': if not os.path.isfile(child.item(row, 0).text()): ERROR(f"File in row {row} does not exist") return 1 elif self.nf_settings_parser.get('params.workflow') in [ "MSconvert", "Quandenser" ] and child.item(row, 1).text() == '': label = 'A' # Add junk labeling elif child.item( row, 1).text() == '' and self.nf_settings_parser.get( 'params.workflow') == "Full": ERROR( f"File in row {row} is missing a label (Full workflow enabled)" ) return 1 elif child.item(row, 1).text() != '': label = child.item(row, 1).text() input_string = child.item(row, 0).text() + '\t' + label + '\n' full_table.append(input_string) if full_table == []: ERROR('No files choosen') return 1 with open(f"{output_path}/file_list.txt", 'w') as file: for line in full_table: file.write(line) batch_file_path = f"{output_path}/file_list.txt" self.nf_settings_parser.write("params.batch_file", batch_file_path) # DATABASE_FILE # children = parent.findChildren(QLineEdit) for child in children: # This is so I can have whatever order in widgets I want if child.type == 'file': break # Will keep child database_path = child.text() self.nf_settings_parser.write("params.db", database_path) workflow = self.nf_settings_parser.get("params.workflow") if workflow == "Full" and not os.path.isfile(database_path): ERROR( "You must choose an database if you are running the full pipeline" ) return 1 # EMAIL # email = self.nf_settings_parser.get("params.email") if email != '': # Need to add -N here, since without it, nextflow will display a warning self.sh_parser.write("EMAIL_NOTIFICATION", f"-N {email}") else: self.sh_parser.write("EMAIL_NOTIFICATION", f"") # CUSTOM MOUNTS # custom_mounts = self.pipe_parser.get('custom_mounts').replace( '\r', '').replace('\n', '') self.nf_settings_parser.write('params.custom_mounts', custom_mounts) # Generate random hash for nextflow random_hash = secrets.token_urlsafe(16) self.nf_settings_parser.write('params.random_hash', random_hash) # Set pipe to launch nextflow pipeline self.pipe_parser.write('exit_code', '0', isString=False) self.window().close()
def init_tab2(paths): tab2 = QWidget() tab2_layout = QHBoxLayout() tab2.setLayout(tab2_layout) filler = QLabel('') filler.setFixedWidth(1) # Left box tab2_leftbox = QWidget() tab2_leftbox_layout = QVBoxLayout() tab2_leftbox.setLayout(tab2_leftbox_layout) # Top tab2_leftbox_top = QWidget() tab2_leftbox_top_layout = QFormLayout() tab2_leftbox_top.setLayout(tab2_leftbox_top_layout) tab2_choose_option_workflow = choose_option('workflow', paths['nf']) tab2_choose_option_boxcar_convert = choose_option('boxcar_convert', paths['nf']) tab2_choose_option_profile = choose_option('profile', paths['sh']) tab2_choose_option_parallel_msconvert = choose_option( 'parallel_msconvert', paths['nf']) tab2_choose_option_parallel_quandenser = choose_option( 'parallel_quandenser', paths['nf']) # Always visible tab2_leftbox_top_layout.addRow(QLabel('Choose workflow'), tab2_choose_option_workflow) tab2_leftbox_top_layout.addRow(QLabel('Profile'), tab2_choose_option_profile) tab2_leftbox_top_layout.addRow(QLabel('Enable boxcar conversion'), tab2_choose_option_boxcar_convert) tab2_leftbox_top_layout.addRow(QLabel('Enable parallel MSconvert'), tab2_choose_option_parallel_msconvert) tab2_leftbox_top_layout.addRow(QLabel('Enable parallel quandenser'), tab2_choose_option_parallel_quandenser) tab2_leftbox_top_layout.addRow(filler, filler) # Empty space tab2_leftbox_layout.addWidget(tab2_leftbox_top) # Bottom, these will be hidden or shown depending on profile option tab2_hidden = QWidget() tab2_hidden.hidden_object = True tab2_hidden_layout = QStackedLayout() tab2_hidden.setLayout(tab2_hidden_layout) # Stack 1: Empty layout. Cluster disabled tab2_hidden_stack_1 = QWidget() tab2_hidden_stack_1_layout = QFormLayout() tab2_hidden_stack_1.setLayout(tab2_hidden_stack_1_layout) # Stack 2: Regular quandenser, cluster enabled tab2_hidden_stack_2 = QWidget() tab2_hidden_stack_2_layout = QFormLayout() tab2_hidden_stack_2_layout.setVerticalSpacing(0) tab2_hidden_stack_2.setLayout(tab2_hidden_stack_2_layout) stack_2_widgets = [] stack_2_widgets.append(get_tooltip('cluster-type')) stack_2_widgets.append(choose_option("process.executor", paths['nf'])) stack_2_widgets.append(filler) stack_2_widgets.append(get_tooltip('cluster-arguments')) stack_2_widgets.append( cluster_arguments("process.clusterOptions", paths['nf'])) stack_2_widgets.append(filler) stack_2_widgets.append(get_tooltip('cluster-queue')) stack_2_widgets.append(cluster_arguments("process.queue", paths['nf'])) stack_2_widgets.append(filler) stack_2_widgets.append(QLabel('MSconvert cpus + time')) stack_2_widgets.append(set_cpus("msconvert_cpus", paths['nf'])) stack_2_widgets.append(set_time("msconvert_time", paths['nf'])) stack_2_widgets.append(QLabel('Boxcar convert cpus + time')) stack_2_widgets.append(set_cpus("boxcar_convert_cpus", paths['nf'])) stack_2_widgets.append(set_time("boxcar_convert_time", paths['nf'])) stack_2_widgets.append(QLabel('Quandenser cpus + time')) stack_2_widgets.append(set_cpus("quandenser_cpus", paths['nf'])) stack_2_widgets.append(set_time("quandenser_time", paths['nf'])) stack_2_widgets.append(QLabel('Tide cpus + time')) stack_2_widgets.append(set_cpus("tide_search_cpus", paths['nf'])) stack_2_widgets.append(set_time("tide_search_time", paths['nf'])) stack_2_widgets.append(QLabel('Triqler cpus + time')) stack_2_widgets.append(set_cpus("triqler_cpus", paths['nf'])) stack_2_widgets.append(set_time("triqler_time", paths['nf'])) list_itr = iter(stack_2_widgets) for label in list_itr: combine_widget = QWidget() combine_widget_layout = QFormLayout() combine_widget.setLayout(combine_widget_layout) widget1, widget2 = next(list_itr), next(list_itr) combine_widget_layout.addRow(widget1, widget2) tab2_hidden_stack_2_layout.addRow(label, combine_widget) # Stack 3: Parallel quandenser, cluster enabled tab2_hidden_stack_3 = QWidget() tab2_hidden_stack_3_layout = QFormLayout() tab2_hidden_stack_3_layout.setVerticalSpacing(0) tab2_hidden_stack_3.setLayout(tab2_hidden_stack_3_layout) stack_3_widgets = [] stack_3_widgets.append(get_tooltip('cluster-type')) stack_3_widgets.append(choose_option("process.executor", paths['nf'])) stack_3_widgets.append(filler) stack_3_widgets.append(get_tooltip('cluster-arguments')) stack_3_widgets.append( cluster_arguments("process.clusterOptions", paths['nf'])) stack_3_widgets.append(filler) stack_3_widgets.append(get_tooltip('cluster-queue')) stack_3_widgets.append(cluster_arguments("process.queue", paths['nf'])) stack_3_widgets.append(filler) stack_3_widgets.append(QLabel('MSconvert cpus + time')) stack_3_widgets.append(set_cpus("msconvert_cpus", paths['nf'])) stack_3_widgets.append(set_time("msconvert_time", paths['nf'])) stack_3_widgets.append(QLabel('Boxcar convert cpus + time')) stack_3_widgets.append(set_cpus("boxcar_convert_cpus", paths['nf'])) stack_3_widgets.append(set_time("boxcar_convert_time", paths['nf'])) stack_3_widgets.append(QLabel('Quandenser p1 cpus + time')) stack_3_widgets.append(set_cpus("quandenser_parallel_1_cpus", paths['nf'])) stack_3_widgets.append(set_time("quandenser_parallel_1_time", paths['nf'])) stack_3_widgets.append(QLabel('Quandenser p2 cpus + time')) stack_3_widgets.append(set_cpus("quandenser_parallel_2_cpus", paths['nf'])) stack_3_widgets.append(set_time("quandenser_parallel_2_time", paths['nf'])) stack_3_widgets.append(QLabel('Quandenser p3 cpus + time')) stack_3_widgets.append(set_cpus("quandenser_parallel_3_cpus", paths['nf'])) stack_3_widgets.append(set_time("quandenser_parallel_3_time", paths['nf'])) stack_3_widgets.append(QLabel('Quandenser p4 cpus + time')) stack_3_widgets.append(set_cpus("quandenser_parallel_4_cpus", paths['nf'])) stack_3_widgets.append(set_time("quandenser_parallel_4_time", paths['nf'])) stack_3_widgets.append(QLabel('Tide cpus + time')) stack_3_widgets.append(set_cpus("tide_search_cpus", paths['nf'])) stack_3_widgets.append(set_time("tide_search_time", paths['nf'])) stack_3_widgets.append(QLabel('Triqler cpus + time')) stack_3_widgets.append(set_cpus("triqler_cpus", paths['nf'])) stack_3_widgets.append(set_time("triqler_time", paths['nf'])) stack_3_widgets.extend([filler, filler, filler]) # Empty space list_itr = iter(stack_3_widgets) for label in list_itr: combine_widget = QWidget() combine_widget_layout = QFormLayout() combine_widget.setLayout(combine_widget_layout) widget1, widget2 = next(list_itr), next(list_itr) combine_widget_layout.addRow(widget1, widget2) tab2_hidden_stack_3_layout.addRow(label, combine_widget) # Add stacks tab2_hidden_layout.addWidget(tab2_hidden_stack_1) tab2_hidden_layout.addWidget(tab2_hidden_stack_2) tab2_hidden_layout.addWidget(tab2_hidden_stack_3) # Add hidden stacked layout tab2_leftbox_layout.addWidget(tab2_hidden) # Right box tab2_rightbox = QWidget() tab2_rightbox_layout = QHBoxLayout() tab2_rightbox.setLayout(tab2_rightbox_layout) pipe_parser = custom_config_parser() pipe_parser.load(paths['pipe']) if pipe_parser.get('disable-opengl') in ['false', '']: tab2_workflow = workflow() tab2_rightbox_layout.addWidget(tab2_workflow) else: tab2_workflow = tooltip_label("OpenGL disabled", "OpenGL disabled", style=True) tab2_rightbox_layout.addWidget(tab2_workflow) tab2_layout.addWidget(tab2_rightbox) # Combine tab2_layout.addWidget(tab2_leftbox) tab2_layout.addWidget(tab2_rightbox) return tab2