def update_display(self, is_active): apc = AppPreferences() self._host_url = apc.url if self._connect(): can_submit = True try: self._submit_settings = self._clusterframe.get_special_settings( \ self._settings, self.imagecontainer.has_timelapse) except: self._submit_settings = self._clusterframe.get_special_settings(self._settings) self._label_hosturl.setText(self._host_url) self._label_status.setText(self._service.get_service_info()) mappable_paths = self._get_mappable_paths() self._table_info.clearContents() self._table_info.setRowCount(len(mappable_paths)) for i, info in enumerate(mappable_paths): value = self._settings.get(*info) mapped = apc.map2platform(value) self._submit_settings.set(info[0], info[1], mapped) if mapped is None: can_submit = False self._table_info.setItem(i, 0, QTableWidgetItem(value)) self._table_info.setItem(i, 1, QTableWidgetItem(mapped)) self.check_directories() self._table_info.resizeColumnsToContents() self._table_info.resizeRowsToContents() self._btn_submit.setEnabled(can_submit and is_active) else: self._btn_submit.setEnabled(False)
def update_display(self, is_active): apc = AppPreferences() self._host_url = apc.url if self._connect(): can_submit = True try: self._submit_settings = self._clusterframe.get_special_settings( \ self._settings, self.imagecontainer.has_timelapse) except: self._submit_settings = self._clusterframe.get_special_settings( self._settings) self._label_hosturl.setText(self._host_url) self._label_status.setText(self._service.get_service_info()) mappable_paths = self._get_mappable_paths() self._table_info.clearContents() self._table_info.setRowCount(len(mappable_paths)) for i, info in enumerate(mappable_paths): value = self._settings.get(*info) mapped = apc.map2platform(value) self._submit_settings.set(info[0], info[1], mapped) if mapped is None: can_submit = False self._table_info.setItem(i, 0, QTableWidgetItem(value)) self._table_info.setItem(i, 1, QTableWidgetItem(mapped)) self.check_directories() self._table_info.resizeColumnsToContents() self._table_info.resizeRowsToContents() self._btn_submit.setEnabled(can_submit and is_active) else: self._btn_submit.setEnabled(False)
def _on_browser_open(self): if self._imagecontainer is None: QMessageBox.warning( self, 'Data structure not loaded', 'The input directory structure file was not loaded.\n' 'Click "Scan input directory" in section "General" to proceed.' ) elif self._browser is None: try: browser = Browser(self._settings, self._imagecontainer, None) browser.show() browser.raise_() browser.setFocus() app = AppPreferences() f = QFile(":cecog_style") f.open(QFile.ReadOnly | QFile.Text) ts = QTextStream(f).readAll() browser.setStyleSheet(ts) self._browser = browser except Exception as e: traceback.print_exc() QMessageBox.critical(self, "Error", str(e)) else: self._browser.show() self._browser.raise_()
def _on_submit_job(self): self._submit_settings.set_section(SECTION_NAME_GENERAL) if not self._submit_settings.get2('constrain_positions'): positions = [] for plate_id in self.imagecontainer.plates: self.imagecontainer.set_plate(plate_id) meta_data = self.imagecontainer.get_meta_data() positions += [ '%s___%s' % (plate_id, p) for p in meta_data.positions ] self._submit_settings.set2('positions', ','.join(positions)) nr_items = len(positions) else: positions = self._submit_settings.get2('positions') nr_items = len(positions.split(',')) settings_dummy = self._clusterframe.get_special_settings( self._settings) apc = AppPreferences() batch_size = apc.batch_size pathout = self._submit_settings.get2('pathout') if not self._submit_settings('General', 'skip_finished'): self.clear_output_directory(self._settings("General", "pathout")) try: self.dlg = ProgressDialog("Submitting Jobs...", None, 0, 0, self) settings_str = self._submit_settings.to_string() func = lambda: self._service.submit_job( 'cecog_batch', settings_str, pathout, nr_items, batch_size, version) self.dlg.exec_(func) jobid = self.dlg.getTargetResult() except Exception as e: QMessageBox.critical(self, "Error", 'Job submission failed (%s)' % str(e)) else: # FIXME: no idea how DRMAA 1.0 compatible this is if type(jobid) == types.ListType: self._jobid = ','.join(jobid) main_jobid = jobid[0].split('.')[0] else: self._jobid = str(jobid) main_jobid = jobid self._txt_jobid.setText(self._jobid) self._update_job_status() QMessageBox.information(self, "Information", ("Job(s) successfully submitted\n" "Job ID: %s, #jobs: %d" % (main_jobid, nr_items)))
def _makedirs(self): odirs = (join(self._outdir, "cellh5"), ) if AppPreferences().write_logs: odirs += (join(self._outdir, "log"), ) for odir in odirs: try: makedirs(odir) except os.error: # no permissions self.logger.error("mkdir %s: failed" % odir) else: self.logger.info("mkdir %s: ok" % odir) setattr(self, "_%s_dir" % basename(odir.lower()).strip("_"), odir)
def __call__(self): # skip plate if exists if self.settings('General', 'skip_finished') and os.path.isfile( self.h5f): return layout = "%s/%s.txt" % (self.settings("General", "plate_layout"), self.plate) layout = Ch5File.layoutFromTxt(layout) for pos in self.positions: i = layout["File"].tolist().index(pos) well, site = layout["Well"][i], layout["Site"][i] wsstr = "%s_%02d" % (well, site) datafile = join(self._cellh5_dir, '%s.ch5' % wsstr) if self.settings('General', 'skip_finished') and os.path.isfile( datafile.replace(".ch5", ".tmp")): msg = 'Skipping already processed postion %s' % wsstr self.logger.info(msg) continue else: self.logger.info('Processing position: %s' % wsstr) analyzer = PositionAnalyzer(self.plate, pos, datafile, self.settings, self.frames, self.sample_reader, self.sample_positions, None, self._imagecontainer, layout, AppPreferences().write_logs) try: analyzer() fp = open(datafile.replace(".ch5", ".tmp"), "a") fp.close() except StopProcessing: if analyzer.isAborted(): os.remove(datafile) except Exception as e: os.remove(datafile) self.logger.error("Removed file %s" % datafile) traceback.print_exc() raise finally: analyzer.clear()
def _restore_geometry(self): settings = QtCore.QSettings(version.organisation, version.appname) settings.beginGroup('Gui') if settings.contains('geometry'): self.restoreGeometry(settings.value('geometry')) if settings.contains('state'): self.restoreState(settings.value('state')) if settings.contains('clusterjobs'): jobids = settings.value('clusterjobs') if AppPreferences().cluster_support and jobids: self._pages.widgetByType(ClusterFrame).restore_jobids(jobids) settings.endGroup()
def _on_browser_open(self): if self._imagecontainer is None: QMessageBox.warning( self, 'Data structure not loaded', 'The input directory structure file was not loaded.\n' 'Click "Scan input directory" in section "General" to proceed.' ) elif self._browser is None: try: browser = Browser(self._settings, self._imagecontainer, None) browser.show() browser.raise_() browser.setFocus() app = AppPreferences() browser.setStyleSheet(loadStyle(app.stylesheet)) self._browser = browser except Exception as e: traceback.print_exc() QMessageBox.critical(self, "Error", str(e)) else: self._browser.show() self._browser.raise_()
def _turn_off_cluster_support(self): pref = AppPreferences() pref.cluster_support = False pref.saveSettings()
def __init__(self, appname, version, redirect, settings=None, debug=False, *args, **kw): super(CecogAnalyzer, self).__init__(*args, **kw) self.setWindowTitle("%s-%s" % (appname, version) + '[*]') self.setAcceptDrops(True) self.setCentralWidget(QtWidgets.QFrame(self)) self.setObjectName(appname) self.version = version self.appname = appname self.debug = debug self.environ = CecogEnvironment(version=version, redirect=redirect, debug=debug) if debug: self.environ.pprint() self._is_initialized = False self._imagecontainer = None self._meta_data = None self._browser = None action_quit = self.create_action('&Quit', slot=self.close) action_pref = self.create_action('&Preferences', slot=self.open_preferences) action_load = self.create_action('&Load Settings...', shortcut=QtGui.QKeySequence.Open, slot=self._on_file_open) action_save = self.create_action('&Save Settings', shortcut=QtGui.QKeySequence.Save, slot=self._on_file_save) self.action_save = action_save action_save_as = self.create_action('&Save Settings As...', shortcut=QtGui.QKeySequence.SaveAs, slot=self._on_file_save_as) menu_file = self.menuBar().addMenu('&File') self.add_actions(menu_file, (action_pref, None, action_load, None, action_save, action_save_as, None, action_quit)) action_log = self.create_action('&Log window', shortcut=QtGui.QKeySequence(Qt.CTRL + Qt.Key_L), slot=self._on_show_log_window) action_open = self.create_action('&Browser', shortcut=QtGui.QKeySequence('CTRL+B'), slot=self._on_browser_open) menu_view = self.menuBar().addMenu('&View') self.add_actions(menu_view, (action_log, )) self.add_actions(menu_view, (action_open, )) action_assistant = self.create_action( '&Help', shortcut=QtGui.QKeySequence.HelpContents, slot=self.show_assistant) action_about = self.create_action('&About', slot=self.on_about) action_aboutQt = self.create_action('&About Qt', slot=self.about_qt) menu_help = self.menuBar().addMenu('&Help') self.add_actions(menu_help, (action_assistant, action_about, action_aboutQt)) self.setStatusBar(QtWidgets.QStatusBar(self)) self._selection = QtWidgets.QListWidget(self.centralWidget()) self._selection.setViewMode(QtWidgets.QListView.IconMode) self._selection.setIconSize(QtCore.QSize(35, 35)) self._selection.setGridSize(QtCore.QSize(140, 60)) self._selection.setMovement(QtWidgets.QListView.Static) self._selection.setMaximumWidth(self._selection.gridSize().width() + 5) self._selection.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self._selection.setSizePolicy( QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Expanding)) self._pages = FrameStack(self) self._settings_filename = None self._settings = GuiConfigSettings(self) self._tab_lookup = OrderedDict() self._tabs = [ GeneralFrame(self._settings, self._pages, SECTION_NAME_GENERAL), ObjectDetectionFrame(self._settings, self._pages, SECTION_NAME_OBJECTDETECTION), FeatureExtractionFrame(self._settings, self._pages, SECTION_NAME_FEATURE_EXTRACTION), ClassificationFrame(self._settings, self._pages, SECTION_NAME_CLASSIFICATION), TrackingFrame(self._settings, self._pages, SECTION_NAME_TRACKING), EventSelectionFrame(self._settings, self._pages, SECTION_NAME_EVENT_SELECTION), ErrorCorrectionFrame(self._settings, self._pages, SECTION_NAME_ERRORCORRECTION), OutputFrame(self._settings, self._pages, SECTION_NAME_OUTPUT), ProcessingFrame(self._settings, self._pages, SECTION_NAME_PROCESSING) ] # connections for the section frames self._tabs[3].connect_browser_btn(self._on_browser_open) for frame in self._tabs: frame.status_message.connect(self.statusBar().showMessage) app = AppPreferences() if app.cluster_support: clusterframe = ClusterFrame(self._settings, self._pages, SECTION_NAME_CLUSTER) clusterframe.set_imagecontainer(self._imagecontainer) self._tabs.append(clusterframe) try: self.updateStyleSheet(loadStyle(app.stylesheet)) except Exception as e: # proceed with no stylesheet traceback.print_exc() widths = [] for tab in self._tabs: size = self._add_page(tab) widths.append(size.width()) self.set_modules_active(state=False) self._pages.setMinimumWidth(max(widths) + 45) self._selection.currentItemChanged.connect(self._on_change_page) self._selection.setCurrentRow(0) w_logo = QtWidgets.QLabel(self.centralWidget()) w_logo.setPixmap(QtGui.QPixmap(':cecog_logo_w145')) layout = QtWidgets.QGridLayout(self.centralWidget()) layout.addWidget(self._selection, 0, 0) layout.addWidget(w_logo, 1, 0, Qt.AlignBottom | Qt.AlignHCenter) layout.addWidget(self._pages, 0, 1, 2, 1) layout.setContentsMargins(1, 1, 1, 1) self.setGeometry(0, 0, 1250, 800) self.setMinimumSize(QtCore.QSize(700, 600)) self._is_initialized = True self._restore_geometry() self.show() # finally load (demo) - settings if settings is None: self.load_settings(self.environ.demo_settings) elif os.path.isfile(settings): self.load_settings(settings) else: QMessageBox.warning(self, "Warning", "File (%s) does not exist" % settings)
def _analyze(self, cellanalyzer): thread = QThread.currentThread() stopwatch = StopWatch(start=True) crd = Coordinate(self.plate_id, self.position, self._frames, list(set(self.ch_mapping.values()))) for frame, channels in self._imagecontainer( \ crd, interrupt_channel=True, interrupt_zslice=True): self.interruptionPoint() txt = '%s, %s, T %d (%d/%d)' \ %(self.plate_id, self.position, frame, self._frames.index(frame)+1, len(self._frames)) self.statusUpdate(text=txt, interval=stopwatch.interim(), increment=True) stopwatch.reset(start=True) cellanalyzer.initTimepoint(frame) self.register_channels(cellanalyzer, channels) cellanalyzer.process() self.logger.debug(" - Frame %d, cellanalyzer.process (ms): %3d" \ %(frame, stopwatch.interval()*1000)) images = [] if self.settings('Processing', 'tracking'): apc = AppPreferences() region = self.settings('Tracking', 'region') samples = self.timeholder[frame][ PrimaryChannel.NAME].get_region(region) self._tracker.track_next_frame(frame, samples) if apc.display_tracks: size = cellanalyzer.getImageSize(PrimaryChannel.NAME) img_conn, img_split = self._tracker.render_tracks( frame, size, apc.track_length, apc.cradius) images += [(img_conn, '#FFFF00', 1.0), (img_split, '#00FFFF', 1.0)] self.logger.debug(" - Frame %d, Tracking (ms): %3d" \ %(frame, stopwatch.interval()*1000)) # can't cluster on a per frame basis if self.settings("EventSelection", "supervised_event_selection"): for channel, clf in self.classifiers.iteritems(): cellanalyzer.classify_objects(clf, channel) self.logger.debug(" - Frame %d, Classification (ms): %3d" \ % (frame, stopwatch.interval()*1000)) self.settings.set_section('General') # want emit all images at once imgs = {} imgs.update( self.render_classification_images(cellanalyzer, images, frame)) imgs.update(self.render_contour_images(cellanalyzer, images, frame)) msg = 'PL %s - P %s - T %05d' % (self.plate_id, self.position, frame) self.setImage(imgs, msg, 50) cellanalyzer.purge(features=self.export_features) self.logger.debug(" - Frame %d, duration (ms): %3d" \ %(frame, stopwatch.interim()*1000))