def _worker_initialize(): """ Initializer function for multiprocessing workers. This makes sure plugins are loaded and paths to local files are set """ set_local_file_path() get_plugins()
def resamp(self, qpdata): """ Resample a map according to resampling options """ resamp_options = dict(self.options.get("resampling", {})) if resamp_options: resamp_processes = get_plugins("processes", "ResampleProcess") if len(resamp_processes) != 1: raise QpException("Can't identify Resampling process") ivm = ImageVolumeManagement() ivm.add(qpdata) process = resamp_processes[0](ivm) resamp_options.update({ "data": qpdata.name, "output-name": "output_res" }) process.execute(resamp_options) while process.status == Process.RUNNING: time.sleep(1) if process.status == Process.FAILED: raise process.exception # FIXME hack process._complete() return ivm.data["output_res"] else: return qpdata
def structure_maps(self): processes = get_plugins("processes", "FastProcess") if len(processes) != 1: raise QpException("Can't identify Fast process") struc = self.options.get("struc", None) if struc not in self._ivm.data: raise QpException("Structural image not loaded: %s" % struc) qpdata = self._ivm.data[struc] ivm = ImageVolumeManagement() ivm.add(qpdata) process = processes[0](ivm) fast_options = { "data": qpdata.name, "class": 3, "type": self.options["type"], "output-pve": True, "output-pveseg": False, } process.execute(fast_options) while process.status == Process.RUNNING: time.sleep(1) if process.status == Process.FAILED: raise process.exception # FIXME hack process._complete() return { "gm": ivm.data["%s_pve_1" % qpdata.name], "wm": ivm.data["%s_pve_2" % qpdata.name], "csf": ivm.data["%s_pve_0" % qpdata.name], }
def _smooth_pv(self, qpdata, sigma): """ Do Gaussian smoothing on a partial volume map Typically when the map is a discrete ROI and we want to smoothly blend it into the other tissue PV maps :param qpdata: PV map :param sigma: Gaussian kernel std.dev in mm :return: Smoothed PV map as Numpy array """ smooth_processes = get_plugins("processes", "SmoothingProcess") if len(smooth_processes) != 1: raise QpException("Can't identify smoothing process") ivm = ImageVolumeManagement() ivm.add(qpdata) process = smooth_processes[0](ivm) smooth_options = { "data": qpdata.name, "sigma": sigma, "output-name": "output_smooth", } process.execute(smooth_options) while process.status == Process.RUNNING: time.sleep(1) if process.status == Process.FAILED: raise process.exception # FIXME hack process._complete() return ivm.data["output_smooth"].raw()
def init_ui(self): vbox = QtGui.QVBoxLayout() self.setLayout(vbox) try: proc = get_plugins("processes", "FabberProcess")[0] except: proc = None if proc is None: vbox.addWidget( QtGui.QLabel( "Fabber core library not found.\n\n You must install Fabber to use this widget" )) return title = TitleWidget(self, help="fabber-dsc", subtitle="Bayesian modelling for DSC-MRI %s" % __version__) vbox.addWidget(title) cite = Citation(FAB_CITE_TITLE, FAB_CITE_AUTHOR, FAB_CITE_JOURNAL) vbox.addWidget(cite) tabs = QtGui.QTabWidget() vbox.addWidget(tabs) self.dsc_widget = DscOptionsWidget(self.ivm) tabs.addTab(self.dsc_widget, "DSC Options") self.aif_widget = AifWidget(self.ivm) tabs.addTab(self.aif_widget, "AIF") vbox.addWidget(tabs) vbox.addWidget(RunWidget(self, save_option=True)) vbox.addStretch(1)
def _run_reg(worker_id, queue, method_name, mode, reg_data, ref_data, options): """ Generic registration function for asynchronous process """ try: set_local_file_path() method = get_reg_method(method_name) if method is None: raise QpException("Unknown registration method: %s (known: %s)" % (method_name, str(get_plugins("reg-methods")))) if not reg_data: raise QpException("No registration data") elif mode == "moco": return _reg_moco(worker_id, method, reg_data, ref_data, options, queue) elif reg_data[0].ndim == 3: return _reg_3d(worker_id, method, reg_data, ref_data, options, queue) else: return _reg_4d(worker_id, method, reg_data, ref_data, options, queue) except: traceback.print_exc() return worker_id, False, sys.exc_info()[1]
def qp_oxasl(worker_id, queue, fsldir, fsldevdir, asldata, options): """ Worker function for asynchronous oxasl run Note that images are passed as QpData because it's pickleable but need to be converted to fsl.data.image.Image """ try: from oxasl import Workspace from oxasl.oxford_asl import oxasl options["fabber_dirs"] = get_plugins("fabber-dirs") if "FSLOUTPUTTYPE" not in os.environ: os.environ["FSLOUTPUTTYPE"] = "NIFTI_GZ" if fsldir: os.environ["FSLDIR"] = fsldir if fsldevdir: os.environ["FSLDEVDIR"] = fsldevdir for key, value in options.items(): if isinstance(value, QpData): options[key] = qpdata_to_fslimage(value) options["asldata"], _ = qpdata_to_aslimage(asldata) output_monitor = OutputStreamMonitor(queue) wsp = Workspace(log=output_monitor, **options) oxasl(wsp) return worker_id, True, {} except: traceback.print_exc() return worker_id, False, sys.exc_info()[1]
def api(model_group=None): """ Return a Fabber API object """ from fabber import Fabber search_dirs = get_plugins(key="fabber-dirs") return Fabber(*search_dirs)
def init_ui(self): vbox = QtGui.QVBoxLayout() self.setLayout(vbox) try: self.fabber_process = get_plugins("processes", "FabberProcess")[0] except: self.fabber_process = None if self.fabber_process is None: vbox.addWidget( QtGui.QLabel( "Fabber core library not found.\n\n You must install Fabber to use this widget" )) return title = TitleWidget( self, help="cest", subtitle= "Bayesian Modelling for Chemical Exchange Saturation Transfer MRI %s" % __version__) vbox.addWidget(title) cite = Citation(CEST_CITE_TITLE, CEST_CITE_AUTHOR, CEST_CITE_JOURNAL) vbox.addWidget(cite) self.tabs = QtGui.QTabWidget() self.seqtab = SequenceOptions(self.ivm) self.tabs.addTab(self.seqtab, "Sequence") self.pooltab = PoolOptions(self.ivm) self.tabs.addTab(self.pooltab, "Pools") self.analysistab = AnalysisOptions(self.ivm) self.tabs.addTab(self.analysistab, "Analysis") self.pooltab.sig_pools_changed.connect(self.analysistab.set_pools) self.seqtab.sig_b0_changed.connect(self.pooltab.set_b0) vbox.addWidget(self.tabs) run_tabs = QtGui.QTabWidget() run_box = RunBox(self._get_process_model, self._options, title="Run model-based analysis", save_option=True) run_tabs.addTab(run_box, "Model based analysis") run_box = RunBox(self._get_process_lda, self._options_lda, title="Run Lorentzian Difference analysis", save_option=True) run_tabs.addTab(run_box, "Lorentzian Difference analysis") vbox.addWidget(run_tabs) vbox.addStretch(1) self.analysistab.set_pools(self.pooltab.pools)
def setUp(self): self.qpe, self.error = False, False sys.excepthook = self._exc self.ivm = ImageVolumeManagement() self.ivl = Viewer(self.ivm) get_plugins() wclass = self.widget_class() if wclass is not None: self.w = wclass(ivm=self.ivm, ivl=self.ivl) self.w.init_ui() self.w.activate() self.w.show() else: raise unittest.SkipTest("Plugin not found") from . import create_test_data create_test_data(self)
def __init__(self, **kwargs): super(RegWidget, self).__init__(name="Registration", icon="reg", desc="Registration and Motion Correction", group="Registration", **kwargs) self.reg_methods = [] for method in get_plugins("reg-methods"): try: self.reg_methods.append(method(self.ivm)) except: traceback.print_exc() self.warn("Failed to create registration method: %s", method)
def get_reg_method(method_name): """ Get a named registration method (case insensitive) """ methods = get_plugins("reg-methods") LOG.debug("Known methods: %s", str(methods)) for method_class in methods: method = method_class(None) if method.name.lower() == method_name.lower(): return method return None
def __init__(self, **kwargs): super(ApplyTransform, self).__init__(name="Apply Transform", icon="reg", desc="Apply previously calculated transformations", group="Registration", **kwargs) self.reg_methods = [] for method in get_plugins("reg-methods"): try: self.reg_methods.append(method(self.ivm)) except: traceback.print_exc() self.warn("Failed to create registration method: %s", method)
def init_ui(self): vbox = QtGui.QVBoxLayout() self.setLayout(vbox) title = TitleWidget( self, help="asl", subtitle="Data processing for Arterial Spin Labelling MRI") vbox.addWidget(title) cite = Citation(FAB_CITE_TITLE, FAB_CITE_AUTHOR, FAB_CITE_JOURNAL) vbox.addWidget(cite) self.tabs = QtGui.QTabWidget() vbox.addWidget(self.tabs) self.asldata = AslImageWidget(self.ivm, parent=self) self.asldata.sig_changed.connect(self._data_changed) self.tabs.addTab(self.asldata, "ASL data") self.preproc = PreprocOptions(self.ivm) self.preproc.sig_enable_tab.connect(self._enable_tab) self.tabs.addTab(self.preproc, "Corrections") # Only add these if appropriate self._optional_tabs = { "veasl": VeaslOptions(self.ivm, self.asldata), "enable": EnableOptions(self.ivm), "deblur": DeblurOptions(), } self.structural = StructuralData(self.ivm) self.tabs.addTab(self.structural, "Structural data") self.calibration = CalibrationOptions(self.ivm) self.tabs.addTab(self.calibration, "Calibration") self.analysis = AnalysisOptions(self.ivm) self.analysis.optbox.option("wp").sig_changed.connect(self._wp_changed) self.tabs.addTab(self.analysis, "Analysis") self.output = OutputOptions() self.tabs.addTab(self.output, "Output") runbox = RunWidget(self, title="Run processing", save_option=True) runbox.sig_postrun.connect(self._postrun) vbox.addWidget(runbox) vbox.addStretch(1) fsldir_qwidgets = get_plugins("qwidgets", "FslDirWidget") if len(fsldir_qwidgets) > 0: fsldir = fsldir_qwidgets[0]() vbox.addWidget(fsldir)
def run_tests(test_filter=None): """ Run all unit tests defined by packages and plugins :param test_filter: Specifies name of test set to be run, None=run all """ suite = unittest.TestSuite() for test in class_tests: if test_filter is None or test.__name__.lower().startswith(test_filter.lower()): suite.addTests(unittest.defaultTestLoader.loadTestsFromTestCase(test)) tests = get_plugins("widget-tests") for test in tests: if test_filter is None or test.__name__.lower().startswith(test_filter.lower()): suite.addTests(unittest.defaultTestLoader.loadTestsFromTestCase(test)) tests = get_plugins("process-tests") for test in tests: if test_filter is None or test.__name__.lower().startswith(test_filter.lower()): suite.addTests(unittest.defaultTestLoader.loadTestsFromTestCase(test)) unittest.TextTestRunner(verbosity=2).run(suite)
def __init__(self, ivm, **kwargs): try: self.fabber = get_plugins("processes", class_name="FabberProcess")[0](ivm) self.fabber.sig_finished.connect(self._fabber_finished) self.fabber.sig_progress.connect(self._fabber_progress) except Exception as exc: self.warn(str(exc)) raise QpException( "Fabber core library not found.\n\n You must install Fabber to use this widget" ) self.steps = [] self.step_num = 0 super(BasilProcess, self).__init__(ivm, **kwargs)
def __init__(self, ivm): FabberDataModel.__init__(self, ivm, "Dynamic Contrast-Enhanced MRI") from fabber import Fabber search_dirs = get_plugins(key="fabber-dirs") self._fab = Fabber(*search_dirs) self.known_params = [ Parameter("sig0", "Signal offset", default=100.0), Parameter("fp", "Flow, Fp", default=0.5, units="min^-1"), Parameter("ps", "Permeability-surface area, PS", default=0.5, units="min^-1"), Parameter("ktrans", "Transfer coefficient, Ktrans", default=0.5, units="min^-1"), Parameter("ve", "Extracellular volume fraction Ve", default=0.2), Parameter("vp", "Vascular plasma volume fraction Vp", default=0.05), Parameter("t10", "T1", default=1.0, units="s"), ]
from PySide import QtGui, QtCore, QtGui as QtWidgets except ImportError: from PySide2 import QtGui, QtCore, QtWidgets from quantiphyse.gui.widgets import Citation from quantiphyse.gui.options import OptionBox, DataOption, ChoiceOption from quantiphyse.utils import get_plugins from quantiphyse.utils.exceptions import QpException from .process import qpdata_to_fslimage, fslimage_to_qpdata CITE_TITLE = "Non-linear registration, aka spatial normalisation" CITE_AUTHOR = "Andersson JLR, Jenkinson M, Smith S" CITE_JOURNAL = "FMRIB technical report TR07JA2, 2010" RegMethod = get_plugins("base-classes", class_name="RegMethod")[0] def _interp(order): return {0: "nn", 1: "trilinear", 2: "spline", 3: "spline"}[order] class FnirtRegMethod(RegMethod): """ FNIRT registration method """ def __init__(self, ivm): RegMethod.__init__(self, "fnirt", ivm, display_name="FNIRT") self.options_widget = None @classmethod
def get_data_models(): ret = {} for cls in get_plugins("datasim-data-models"): ret[cls.NAME] = cls return ret
def __init__(self, load_data=None, widgets=True): super(MainWindow, self).__init__() self.ivm = ImageVolumeManagement() self.view_options_dlg = ViewOptions(self, self.ivm) self.ivl = ImageView(self.ivm, self.view_options_dlg) # Load style sheet stylesheet = get_local_file("resources/darkorange.stylesheet") with open(stylesheet, "r") as stylesheet_file: self.setStyleSheet(stylesheet_file.read()) # Default dir to load files from is the user's home dir self.default_directory = os.path.expanduser("~") # Widgets self.widget_groups = {} self.current_widget = None # Main layout - image view to left, tabs to right main_widget = QtGui.QWidget() hbox = QtGui.QHBoxLayout() splitter = QtGui.QSplitter(QtCore.Qt.Horizontal) splitter.addWidget(self.ivl) splitter.setStretchFactor(0, 4) hbox.addWidget(splitter) main_widget.setLayout(hbox) self.setCentralWidget(main_widget) if widgets: default_size = (1000, 700) widgets = get_plugins("widgets") for wclass in widgets: w = wclass(ivm=self.ivm, ivl=self.ivl, opts=self.view_options_dlg) if w.group not in self.widget_groups: self.widget_groups[w.group] = [] self.widget_groups[w.group].append(w) for _, widgets in self.widget_groups.items(): widgets.sort(key=lambda x: x.position) self._init_tabs() splitter.addWidget(self.tab_widget) splitter.setStretchFactor(1, 1) else: default_size = (700, 700) self.init_menu() # General properties of main window self.setWindowTitle("Quantiphyse %s" % get_version()) self.setWindowIcon(QtGui.QIcon(get_icon("main_icon.png"))) self.resize(*default_size) self.setUnifiedTitleAndToolBarOnMac(True) self.setAcceptDrops(True) self.show() # Load any files from the command line if load_data: for fname in load_data: self.load_data(fname=fname)
def init_ui(self): vbox = QtGui.QVBoxLayout() self.setLayout(vbox) try: self.FabberProcess = get_plugins("processes", "FabberProcess")[0] except IndexError: self.FabberProcess = None if self.FabberProcess is None: vbox.addWidget( QtGui.QLabel( "Fabber core library not found.\n\n You must install Fabber to use this widget" )) return title = TitleWidget( self, help="fabber-dsc", subtitle="DSC modelling using the Fabber process %s" % __version__) vbox.addWidget(title) cite = Citation(FAB_CITE_TITLE, FAB_CITE_AUTHOR, FAB_CITE_JOURNAL) vbox.addWidget(cite) self.input = OptionBox("Input data") self.input.add("DCE data", DataOption(self.ivm, include_3d=False, include_4d=True), key="data") self.input.add("ROI", DataOption(self.ivm, data=False, rois=True), key="roi", checked=True) self.input.add("T1 map", DataOption(self.ivm, include_3d=True, include_4d=False), key="t1", checked=True) self.input.option("t1").sig_changed.connect(self._t1_map_changed) vbox.addWidget(self.input) self.acquisition = OptionBox("Acquisition") self.acquisition.add("Contrast agent R1 relaxivity (l/mmol s)", NumericOption(minval=0, maxval=10, default=3.7), key="r1") self.acquisition.add("Flip angle (\N{DEGREE SIGN})", NumericOption(minval=0, maxval=90, default=12), key="fa") self.acquisition.add("TR (ms)", NumericOption(minval=0, maxval=10, default=4.108), key="tr") self.acquisition.add("Time between volumes (s)", NumericOption(minval=0, maxval=30, default=12), key="delt") vbox.addWidget(self.acquisition) self.model = OptionBox("Model options") self.model.add( "Model", ChoiceOption([ "Standard Tofts model", "Extended Tofts model (ETM)", "2 Compartment exchange model", "Compartmental Tissue Update (CTU) model", "Adiabatic Approximation to Tissue Homogeneity (AATH) Model" ], ["dce_tofts", "dce_ETM", "dce_2CXM", "dce_CTU", "dce_AATH"]), key="model") self.model.add( "AIF", ChoiceOption([ "Population (Orton 2008)", "Population (Parker)", "Measured DCE signal", "Measured concentration curve" ], ["orton", "parker", "signal", "conc"]), key="aif") self.model.add("Bolus injection time (s)", NumericOption(minval=0, maxval=60, default=30), key="tinj") self.model.add("AIF data values", NumberListOption([ 0, ]), key="aif-data") self.model.add("T1 (s)", NumericOption(minval=0.0, maxval=5.0, default=1.0), key="t10") self.model.add("Allow T1 to vary", BoolOption(default=False), key="infer-t10") self.model.add("Bolus arrival time (s)", NumericOption(minval=0, maxval=2.0, default=0), key="delay") self.model.add("Allow bolus arrival time to vary", BoolOption(default=False), key="infer-delay") self.model.add("Infer kep rather than ve", BoolOption(default=False), key="infer-kep") self.model.add("Infer flow", BoolOption(default=True), key="infer-fp") self.model.add("Infer permeability-surface area", BoolOption(default=False), key="infer-ps") self.model.add("Spatial regularization", BoolOption(default=False), key="spatial") self.model.option("model").sig_changed.connect(self._model_changed) self.model.option("aif").sig_changed.connect(self._aif_changed) vbox.addWidget(self.model) # Run button and progress vbox.addWidget(RunWidget(self, title="Run modelling")) vbox.addStretch(1) self._aif_changed() self._model_changed()
def init_ui(self): vbox = QtGui.QVBoxLayout() self.setLayout(vbox) try: self.FabberProcess = get_plugins("processes", "FabberProcess")[0] except: self.FabberProcess = None if self.FabberProcess is None: vbox.addWidget( QtGui.QLabel( "Fabber core library not found.\n\n You must install Fabber to use this widget" )) return title = TitleWidget( self, help="fabber-t1", subtitle="T1 mapping from VFA images using the Fabber process %s" % __version__) vbox.addWidget(title) cite = Citation(FAB_CITE_TITLE, FAB_CITE_AUTHOR, FAB_CITE_JOURNAL) vbox.addWidget(cite) grid = QtGui.QGridLayout() self.multivol_choice = ChoiceOption( "VFA data in", grid, ypos=0, choices=["Single data set", "Multiple data sets"]) self.multivol_choice.combo.currentIndexChanged.connect(self.update_ui) self.multivol_label = QtGui.QLabel("VFA data set") grid.addWidget(self.multivol_label, 1, 0) self.multivol_combo = OverlayCombo(self.ivm) grid.addWidget(self.multivol_combo, 1, 1) self.multivol_fas_label = QtGui.QLabel("FAs (\N{DEGREE SIGN})") grid.addWidget(self.multivol_fas_label, 2, 0) self.multivol_fas = NumberList(initial=[ 1, ]) grid.addWidget(self.multivol_fas, 2, 1, 1, 2) self.singlevol_label = QtGui.QLabel("VFA data sets") grid.addWidget(self.singlevol_label, 3, 0) grid.setAlignment(self.singlevol_label, QtCore.Qt.AlignTop) self.singlevol_table = QtGui.QTableWidget() self.singlevol_table.setColumnCount(2) self.singlevol_table.setHorizontalHeaderLabels( ["Data set", "Flip angle"]) self.singlevol_table.setEditTriggers( QtGui.QAbstractItemView.NoEditTriggers) grid.addWidget(self.singlevol_table, 3, 1) hbox = QtGui.QHBoxLayout() self.singlevol_add = QtGui.QPushButton("Add") self.singlevol_add.clicked.connect(self.add_vol) hbox.addWidget(self.singlevol_add) self.singlevol_clear = QtGui.QPushButton("Clear") self.singlevol_clear.clicked.connect(self.clear_vols) hbox.addWidget(self.singlevol_clear) grid.addLayout(hbox, 4, 1) self.tr = NumericOption("TR (ms)", grid, ypos=5, default=4.108, minval=0, step=0.1, decimals=3) grid.setColumnStretch(3, 1) vbox.addLayout(grid) self.run = RunBox(self.get_process, self.get_rundata) vbox.addWidget(self.run) vbox.addStretch(1) self.update_ui()
def get_struc_models(): ret = {} for cls in get_plugins("datasim-struc-models"): ret[cls.NAME] = cls return ret
def __init__(self, ivm, title): DataModel.__init__(self, ivm, title) from fabber import Fabber search_dirs = get_plugins(key="fabber-dirs") self._fab = Fabber(*search_dirs)