def add_record(self): """ Fires up GUI for budget record creation. """ if len(self.categories) == 0: show_warning('You have to create categories first.') return manager = Manager(self.categories.values()) manager.createdRecord.connect(self.record_created) manager.exec()
def jobtree_menu(self, pos): selected = self.ui.treeWidget.selectedItems() # show menu menu = QtGui.QMenu() a1 = menu.addAction("Delete job(s)") # exec action = menu.exec_(self.ui.treeWidget.mapToGlobal(pos)) success = 1 if action == a1: warning = "Are you sure to delete all of the outputs of these job(s) ?\nNote: they cannot be restored after deletion.\n" for si in selected: warning = warning + str(si.text(0)) + '\n' re = utils.show_warning(warning) if re == 1: for si in selected: jid = self.mainwindow.JobCenter.run_view[str(si.text(0))] job_path = self.mainwindow.JobCenter.jobs[jid].savepath job_status = self.mainwindow.JobCenter.get_run_status_2(jid) if job_status is None or job_status == self.mainwindow.JobCenter.RUN or job_status == self.mainwindow.JobCenter.SUB: utils.show_message("The status of job %s is %s, cannot be deleted !" % (str(si.text()), str(job_status)) ) success = 0 continue else: try: shutil.rmtree(job_path) except: utils.show_message("Fail to remove job %s !\n(%s)" % (str(si.text(0)), job_path) ) success = 0 continue success = self.mainwindow.JobCenter.del_job_record(jid) if success: utils.show_message("All done!") self.load_jobs()
def delete_category(self): """ Tries to delete selected category from DB. On success reloads all categories in the GUI. """ index_list = self.categoriesView.selectedIndexes() if index_list and index_list[0].isValid(): index = index_list[0] category = index.data(Qt.UserRole) deletion = self.orm.delete_category(category) if not deletion: show_warning("Can't delete category") else: self.show_categories() if category.parent is None: self.show_available_parents()
def add_category(self): """ Gets the name of new category and creates category or subcategory in DB. On success reloads all categories in the GUI. """ name = self.caregoryName.text() if name == '': return parent = self.categoryParent.currentText() addition = self.orm.add_category(name, parent) if not addition: show_warning("Category already exists.") else: self.show_categories() if parent == '': self.show_available_parents()
def delete_account(self): """ Tries to delete the account from DB, if successful deletes it from GUI. """ model_indexes = self.selection.selectedIndexes() if not model_indexes: # the list of accounts is empty return None model_index = model_indexes[0] acc = model_index.data(role=Qt.UserRole) msgBox = QMessageBox() msgBox.setText("Delete the {} account?".format(acc.name)) msgBox.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel) msgBox.setDefaultButton(QMessageBox.Cancel) ret = msgBox.exec() if ret == QMessageBox.Ok: deletion = self.orm.delete_account(acc) if not deletion: show_warning("Can't delete account.") else: self.accounts.removeRow(model_index.row())
def OK(self): if self.datadir is None: utils.show_message("Please choose data directory !") return False if self.dirname is None: utils.show_message("Please choose work directory !") return False # check & set jss if str(self.ui.comboBox.currentText()).strip()[:2] == "NO": self.jss = None elif str(self.ui.comboBox.currentText()).strip()[:3] == "PBS": # check if PBS is working if not utils.check_PBS(): utils.show_message("NO PBS detected !") return False self.jss = "PBS" else: utils.show_message("I can not recognize the job submitting system") return False # check data format self.format_index = self.ui.comboBox_2.currentIndex() # check subDir if self.ui.checkBox.checkState() == QtCore.Qt.Checked: self.subDir = True # check data dir if not os.path.exists(os.path.join(self.datadir)): utils.show_message("Data directory is invalid !") return False else: stat = utils.check_datadir(self.datadir, self.format_index, self.namespace['data_format'], self.subDir) # checking results, interact with user if stat[0] == 0 and stat[1] == 0: re = utils.show_warning("I can not find any %s files in the data folder, still go on ?" \ % self.namespace['data_format'][self.format_index]) if re == 1: pass else: return False elif stat[0] == -1 and stat[1] == -1: utils.show_message("Some error occurred ! Please report it") return False elif stat[0] == 1: if stat[1] == 1: pass elif stat[1] == -1: subdre = '' if self.subDir: subdre = ' no' re = utils.show_warning( "It seems there are%s sub directories in data folder, still go on ?" % subdre) if re == 1: pass else: return False else: utils.show_message( "Some error occurred ! Please report it") return False elif type(stat[0]) == str: if stat[1] == 1: re = utils.show_warning("It seems the data format is '%s', still use '%s' ?" \ % (stat[0], self.namespace['data_format'][self.format_index]) ) if re == 1: pass else: return False elif stat[1] == -1: subdre = '' if self.subDir: subdre = ' no' re = utils.show_warning("It seems there are%s sub directories in data folder, \ and the data format is '%s', still go on and use '%s' ?" \ % (subdre, stat[0], self.namespace['data_format'][self.format_index]) ) if re == 1: pass else: return False else: utils.show_message( "Some error occurred ! Please report it") return False # make dir # if not os.path.exists(os.path.join(self.dirname, self.namespace['ini'])): self.makedirs() # copy darkcal to Process/config project_darkcal_path = os.path.join( self.dirname, self.namespace['project_structure'][0], "config/darkcal_default.ini") if not os.path.exists(project_darkcal_path): shutil.copyfile( os.path.join( os.path.split(os.path.realpath(__file__))[0], "darkcal.ini"), project_darkcal_path) subprocess.check_call( "ln -fs %s %s" % ( project_darkcal_path, \ os.path.join(self.dirname, self.namespace['project_structure'][0], "config/darkcal.ini") ), shell=True ) # write project.ini config_name = self.namespace['project_ini'][0] config_item = self.namespace['project_ini'][1].split(',') utils.write_config(os.path.join(self.dirname, self.namespace['ini']),\ {config_name:{config_item[0]:self.datadir, config_item[1]:self.jss, \ config_item[2]:self.format_index, config_item[3]:self.subDir, \ config_item[4]:self.job_control[0], config_item[5]:self.job_control[1]}}, 'w') utils.print2projectLog(self.dirname, "Select data dir %s" % self.datadir) utils.print2projectLog(self.dirname, "Choose work dir %s" % self.dirname) utils.print2projectLog(self.dirname, "Spipy GUI opened successfully") # close and open main gui self.mainapp.setup(self.dirname, self.datadir, self.jss, self.subDir, self.format_index) self.mainapp.show() self.close()
def SecurityCheck(command): for st in MaliciousStrings: if command.find(st) != -1: utils.show_warning(_('GnoMenu detected a malicious script in this theme.\nThe script was blocked!\nYou should uninstall the selected theme and contact the website where you got it.\n\nThe script that tried to run was:')+ ' ' + command.replace('&','')) return '' return command
def table_menu(self, position): """ entrance to submit jobs """ # selected cells selected_runs = [] selected_tag_remarks = {} selected_datafile = {} for pos in self.ui.tableWidget.selectionModel().selection().indexes(): row = pos.row() run_name = str(self.ui.tableWidget.item(row, 0).text()) if len(self.process_data[run_name][0]) == 0: utils.show_message("Run %s does not contain any data. Skip." % run_name) continue tag_remarks_name = str(self.ui.tableWidget.item(row, 1).text()) selected_runs.append(run_name) selected_tag_remarks[run_name] = self.split_tag_remarks(tag_remarks_name) selected_datafile[run_name] = self.process_data[run_name][0] # show menu if len(selected_runs) > 0: # get assignments assignments = str(self.ui.comboBox.currentText()) # show menu menu = QtGui.QMenu() a1 = menu.addAction("Run %s" % assignments) menu.addSeparator() # a2 = menu.addAction("Terminate all") menu_sub = menu.addMenu("Terminate") b = [] if len(selected_runs) > 1: for assign in self.namespace['process_assignments']: b.append(menu_sub.addAction(assign)) if selected_tag_remarks[selected_runs[0]][0] != "--": menu.addSeparator() a4 = menu.addAction("Open %s results in data viewer" % assignments) elif len(selected_runs) == 1: run_tag_remarks = self.get_existing_runtags(assignments, selected_runs[0]) for tr in run_tag_remarks: tr_status = self.JobCenter.get_run_status(selected_runs[0], self.namespace['project_structure'][0], assignments, tr[0], tr[1]) if tr_status == self.JobCenter.RUN: b.append( menu_sub.addAction("%s.%s.%s.%s" % (assignments, selected_runs[0], tr[0], tr[1])) ) menu.addSeparator() if selected_tag_remarks[selected_runs[0]][0] == "darkcal": a4 = menu.addAction("Set as current darkcal") elif selected_tag_remarks[selected_runs[0]][0] != "--": a4 = menu.addAction("Open %s results in data viewer" % assignments) else: a4 = 0 else: pass # exec action = menu.exec_(self.ui.tableWidget.mapToGlobal(position)) # parse selection job_type = self.namespace['project_structure'][0] + "/" + assignments if action == a1: utils.print2projectLog(self.dirname, "Choose %s on %s" % (assignments, str(selected_runs))) self.JobCenter.TableRun_showoff(job_type, selected_runs, selected_datafile, selected_tag_remarks) #elif action == a2: # print("Terminate all jobs of %s" % str(selected_runs)) elif len(selected_runs) == 1 and action == a4: if selected_tag_remarks[selected_runs[0]][0] == "darkcal": # re-link current-darkcal.h5 tmp_darkfile = utils.fmt_job_dir(selected_runs[0], \ selected_tag_remarks[selected_runs[0]][0], selected_tag_remarks[selected_runs[0]][1]) tmp_darkfile = os.path.join(self.dirname, self.namespace['project_structure'][0], self.namespace['process_HF'], tmp_darkfile) try: tmp_darkfile = glob.glob(os.path.join(tmp_darkfile, "*darkcal.h5"))[0] except: utils.show_message("I cannot find ?.darkcal.h5 in this run. Fail to set current darkcal.") return tmp_curr_darklink = os.path.join(self.dirname, self.namespace['project_structure'][0], self.namespace['process_HF'], self.namespace['darkcal']) prev_dark_run = None if os.path.exists(tmp_curr_darklink): prev_dark_run = subprocess.check_output("ls -l %s | awk -F'->' '{print $2}' | tr -d ' '" % tmp_curr_darklink, shell=True) prev_dark_run = os.path.split(prev_dark_run.strip("\n"))[-1].split('.')[0] subprocess.check_call("ln -fs %s %s" % (tmp_darkfile, tmp_curr_darklink), shell=True) # refresh table info if prev_dark_run is not None: self.process_data[prev_dark_run][6] = "--" self.process_data[selected_runs[0]][6] = "Current-Darkcal" utils.print2projectLog(self.dirname, "Set %s as current darkcal" % selected_runs[0]) # draw table self.draw_table() else: # open data viewer and add files tmp = utils.fmt_job_dir(selected_runs[0], \ selected_tag_remarks[selected_runs[0]][0], selected_tag_remarks[selected_runs[0]][1]) tmp = os.path.join(self.dirname, self.namespace['project_structure'][0], assignments, tmp, '*.h5') tmp = glob.glob(tmp) if not data_viewer.is_shown(): data_viewer.show_data_viewer(self) data_viewer.add_files(tmp) utils.print2projectLog(self.dirname, "Add %s results of %s to data viewer." % (assignments, selected_runs[0])) elif len(selected_runs) == 1 and action in b: tmp = str(action.text()).split('.') jid = self.JobCenter.get_jid(tmp[0], tmp[1], tmp[2], tmp[3]) re = utils.show_warning("Terminate job %d of %s ?" % (jid, str(selected_runs))) if re == 1: tmp = self.JobCenter.kill_job(jid) if tmp[0] == 1: utils.print2projectLog(self.dirname, "Terminate job %d of %s" % (jid, str(selected_runs))) utils.show_message("Job %s is successfully terminated" % str(action.text())) else: utils.print2projectLog(self.dirname, "Fail to terminate job %d of %s" % (jid, str(selected_runs))) utils.show_message("**FAIL** to terminate job !" % str(action.text())) # refresh self.update_table_runs() self.draw_table() elif len(selected_runs) > 1 and action in b: assign = str(action.text()) all_jid = [] for run_name in selected_runs: tag_remarks = self.get_existing_runtags(assign, run_name) for tr in tag_remarks: tr_status = self.JobCenter.get_run_status(run_name, self.namespace['project_structure'][0], assign, tr[0], tr[1]) if tr_status == self.JobCenter.RUN: tmp_jid = self.JobCenter.run_view[utils.fmt_runview_key(assign, run_name, tr[0], tr[1])] all_jid.append(tmp_jid) re = utils.show_warning("Terminate all these %d jobs ?" % len(all_jid)) if re == 1: killed = 0 for tmp_jid in all_jid: killed += self.JobCenter.kill_job(jid) utils.print2projectLog("Terminate %d %s jobs of %s" % (killed, assign, str(selected_runs))) utils.show_message("Successfully terminate %d jobs" % killed) # refresh self.update_table_runs() self.draw_table() elif len(selected_runs) > 1 and action == a4: if not data_viewer.is_shown(): data_viewer.show_data_viewer(self) for selected_run in selected_runs: tmp = utils.fmt_job_dir(selected_run, \ selected_tag_remarks[selected_run][0], selected_tag_remarks[selected_run][1]) tmp = os.path.join(self.dirname, self.namespace['project_structure'][0], assignments, tmp, '*.h5') tmp = glob.glob(tmp) data_viewer.add_files(tmp) utils.print2projectLog(self.dirname, "Add %s results of %s to data viewer." % (assignments, str(selected_runs))) else: pass else: menu = QtGui.QMenu() if self.ui.tableWidget.horizontalHeader().resizeMode(0) == QtGui.QHeaderView.Stretch: a1 = menu.addAction("Unfill table window") else: a1 = menu.addAction("Fill table window") menu.addSeparator() a2 = menu.addAction("Set 'force overwrite' to %s" % str(not self.JobCenter.force_overwrite)) action = menu.exec_(self.ui.tableWidget.mapToGlobal(position)) if action == a1: if self.ui.tableWidget.horizontalHeader().resizeMode(0) == QtGui.QHeaderView.Stretch: self.ui.tableWidget.horizontalHeader().setResizeMode(QtGui.QHeaderView.Interactive) else: self.ui.tableWidget.horizontalHeader().setResizeMode(QtGui.QHeaderView.Stretch) elif action == a2: self.JobCenter.reverseForceOverwrite() else: pass
def packSubmit(self, job_obj): def get_mpi_ranks(runtime_data, inh5, pat_per_job, max_jobs): pat_num = 0 try: for ind, f in enumerate(runtime_data): fp = h5py.File(f, 'r') if len(fp[inh5].shape) != 3: return None pat_num += fp[inh5].shape[0] fp.close() except: return None return min(pat_num / pat_per_job + 1, max_jobs) proj_conf = utils.read_config( os.path.join(self.rootdir, self.namespace['ini'])) pat_per_job = int( proj_conf.get(self.namespace['project_ini'][0], self.namespace['project_ini'][1].split(',')[4])) max_jobs = int( proj_conf.get(self.namespace['project_ini'][0], self.namespace['project_ini'][1].split(',')[5])) del proj_conf # runtime json runtime = {} # config file config_file = None # jss sub_jss = self.jss # queue sub_submit_queue = self.submit_queue # write run shell to workdir sub_prepare_sub_script = os.path.join( os.path.split(os.path.realpath(__file__))[0], "scripts/submission.sh") # python script sub_python_exec = None # number of process sub_nproc = 0 # workdir sub_workdir = None ############ These are irrelevent to assignments' type runtime['run_name'] = job_obj.run_name runtime['dataset'] = job_obj.datafile runtime['savepath'] = job_obj.savepath config_file = job_obj.config sub_workdir = job_obj.savepath # get inh5 try: inh5 = utils.read_config( config_file, [self.namespace['config_head'], 'data-path in cxi/h5']) except: inh5 = utils.read_config(config_file, ['darkcal', 'inh5']) inh5 = utils.compile_h5loc(inh5, job_obj.run_name) ############ ''' choose correct code blocks to run according to the given job type ''' if job_obj.assignments == self.namespace['process_HF']: # hit-finding if str(self.ui.lineEdit_2.text()).lower() == "none": runtime['darkcal'] = None else: runtime['darkcal'] = str(self.ui.lineEdit_2.text()) sub_python_exec = os.path.join( os.path.split(os.path.realpath(__file__))[0], "scripts", self.python_scripts["hf"]) # decide mpi rank size # actually I want to be free from inh5, but can not find any good ways if self.data_format.lower() in ["cxi", "h5"]: sub_nproc = get_mpi_ranks(runtime['dataset'], inh5, pat_per_job, max_jobs) if sub_nproc is None: utils.show_message( "The data file '%s' seem seem to have some problems. Check whether the 'Data-path in cxi/h5' is correct." % f) return None else: # TODO pass elif job_obj.assignments == self.namespace['process_AP']: # adu2photon sub_python_exec = os.path.join( os.path.split(os.path.realpath(__file__))[0], "scripts", self.python_scripts["ap"]) # get data source path this_datadir = utils.read_config( config_file, [self.namespace['config_head'], 'Data Dir']) # do not use raw dataset if not job_obj.datafile[0].startswith(this_datadir): assignments = os.path.split(this_datadir)[-1] try: tag_remarks = self.main_gui.tag_buffer[assignments][ runtime['run_name']] tag_remarks = self.main_gui.split_tag_remarks(tag_remarks) if len(tag_remarks) != 2: raise ValueError("boomb") except: utils.show_message( "%s:\nI cannot find the data source, please check the parameters agian." % runtime['run_name']) return None ''' tag_remarks = self.tag_remarks_buffer[runtime['run_name']] if len(tag_remarks) != 2: utils.show_message("%s:\nI cannot find the data source, please check the parameters agian." % runtime['run_name']) return None ''' datafile = os.path.join( this_datadir, utils.fmt_job_dir(runtime['run_name'], tag_remarks[0], tag_remarks[1]), '*.h5') datafile = glob.glob(datafile) if len(datafile) == 0: utils.show_message( "%s:\nI cannot find the data source, please check the parameters agian." % runtime['run_name']) return None runtime['dataset'] = datafile # decide mpi rank size sub_nproc = get_mpi_ranks(runtime['dataset'], inh5, pat_per_job, max_jobs) if sub_nproc is None: utils.show_message("The data files in '%s' seem to have some problems.\n" % this_datadir + \ "Check : data location, 'Data-path in cxi/h5' are correct;\n" + \ "Check : data files are multi-pattern HDf5 format.") return None else: return None ''' prepare and submit jobs : job_dir/status stores all status_xxx.txt of every process and there will be a status.txt if the job finished ''' try: # make workdir if not exists if not os.path.isdir(runtime['savepath']): os.mkdir(runtime['savepath']) os.mkdir(os.path.join(runtime['savepath'], 'status')) else: if not self.force_overwrite: re = utils.show_warning( "project %s already exists, overwrite it?" % runtime['savepath']) if re == 0: utils.show_message( "Don't overwrite project %s, EXIT." % runtime['savepath']) return None shutil.rmtree(runtime['savepath']) os.mkdir(runtime['savepath']) os.mkdir(os.path.join(runtime['savepath'], 'status')) # write runtimejson and config to workdir with open(os.path.join(runtime['savepath'], 'runtime.json'), 'w') as rjson: json.dump(runtime, rjson) shutil.copyfile(config_file, os.path.join(runtime['savepath'], 'config.ini')) # write submit script to workdir SUB_cmd = subprocess.check_output( "bash %s -s %s -t %d -p %s -q %s -y %s" % (sub_prepare_sub_script, sub_python_exec, sub_nproc, sub_workdir, sub_submit_queue, sub_jss), shell=True) SUB_cmd = SUB_cmd.strip("\n") if len(SUB_cmd) == 0: return None # submit pobj = utils.submit_job(sub_workdir, SUB_cmd, self.jss) # return if pobj is None: return None else: return pobj except: return None
def run(self): # update self.run_view # update run_tag, config, run_remarks, pid, savepath, stime, status in self.jobs # read tag, remarks and darkcal title = str(self.windowTitle()) module, assignments = title.split('.') config_file_name = str(self.ui.comboBox.currentText()) # 'xxx.ini' config_file = os.path.join(self.rootdir, module, "config", config_file_name) tag_name = self.extract_tag(config_file_name) self.submit_queue = str(self.ui.lineEdit_3.text()) if not os.path.isfile(config_file): utils.show_message("Choose a configuration file !") return remarks = utils.fmt_remarks(str(self.ui.lineEdit.text())) if len(remarks) == 0: remarks = "default" # hit-finding has darkcal if assignments == self.namespace['process_HF']: if config_file_name == "darkcal.ini": if len(str(self.ui.lineEdit_2.text())) == 0: utils.show_message( "Dark calibration needs data location in raw h5/cxi file." ) return if not str(self.ui.lineEdit_2.text()) == self.darkcal_inh5: self.darkcal_inh5 = str(self.ui.lineEdit_2.text()) utils.write_config( os.path.join(self.rootdir, self.namespace['project_structure'][0], 'config/darkcal.ini'), {'darkcal': { 'inh5': self.darkcal_inh5 }}, "a") else: if not os.path.isfile(str(self.ui.lineEdit_2.text())): re = utils.show_warning( "Dark calibration file is invalid, \ which may affect the hit-finding accuracy. Ignore and go on?") if re == 0: return else: self.ui.lineEdit_2.setText("None") while not self.job_queue['waiting'].empty(): wjid = self.job_queue['waiting'].get() jobdir = utils.fmt_job_dir(self.jobs[wjid].run_name, tag_name, remarks) self.jobs[wjid].run_tag = tag_name self.jobs[wjid].config = config_file self.jobs[wjid].run_remarks = remarks self.jobs[wjid].savepath = os.path.join(self.jobs[wjid].savepath, jobdir) # submit pobj = self.packSubmit(self.jobs[wjid]) if pobj is not None: self.jobs[wjid].jss = self.jss self.jobs[wjid].submit_time = time.time() self.jobs[wjid].process_obj = pobj # self.run_view run_view_key = utils.fmt_runview_key(self.jobs[wjid].assignments, \ self.jobs[wjid].run_name, tag_name, remarks) self.run_view[run_view_key] = wjid # write to project log utils.print2projectLog( self.rootdir, "Submit %s job on %s : pid is %s" % (self.jobs[wjid].assignments, self.jobs[wjid].run_name, str(pobj.pid))) # write job infomation into jobHub self.write_job_hub(wjid) # refresh self.main_gui.update_table_runs() self.main_gui.draw_table() else: utils.show_message("Fail to submit job %s" % jobdir) utils.print2projectLog( self.rootdir, "Fail to submit job : %s (%s.%s)" % (self.jobs[wjid].assignments, self.jobs[wjid].run_name, self.jobs[wjid].run_tag)) self.jobs.pop(wjid) self.close() pass