def _load(self, fname, name, is_roi=False): try: extension = "" parts = fname.split(".", 1) if len(parts) > 1: extension = parts[1] self.debug("Loading: %s (%s)", fname, extension) if extension == 'mat': mat, _rows, _cols = load_matrix(fname) extra = MatrixExtra(name, mat) self.ivm.add_extra(name, extra) elif extension == 'csv': df = pd.read_csv(fname) extra = DataFrameExtra(name, df) self.ivm.add_extra(name, extra) elif extension in ('nii', 'nii.gz'): self.debug("Nifti data") qpdata = load(fname) # Remember this is from a temporary file so need to copy the actual data qpdata = NumpyData(qpdata.raw(), grid=qpdata.grid, name=self._output_prefix + name, roi=is_roi) self._output_data_items.append(name) self.ivm.add(qpdata) except: self.warn("Failed to load: %s", fname) traceback.print_exc()
def load_data(self, fname): """ Load data non-interactively. The data will not be flagged as an ROI but the user can change that later if they want. Any finer control and you need to use interactive loading. """ qpdata = load(fname) name = self.ivm.suggest_name(os.path.split(fname)[1].split(".", 1)[0]) qpdata.name = name self.ivm.add(qpdata)
def _reload(self): if self.data_list.selected is not None: name = self.data_list.selected.name data = self.ivm.data[name] if hasattr(data, "fname") and data.fname: new_data = load(data.fname) new_data.roi = data.roi self.ivm.add(new_data, name=data.name) new_data.metadata.update(data.metadata) new_data.view.update(data.view)
def _load_file(self, fname, name): filepath = self._get_filepath(fname) if name is None: name = self.ivm.suggest_name(os.path.split(fname)[1].split(".", 1)[0]) self.debug(" - Loading data '%s' from %s" % (name, filepath)) try: data = load(filepath) data.name = name return data except QpException as exc: self.warn("Failed to load data: %s (%s)" % (filepath, str(exc)))
def finished(self, worker_output): """ Add data to IVM and set log Note that we need to call ``qpdata.raw()`` to make sure data is all loaded into memory as the files may be temporary """ if self.status == Process.SUCCEEDED: log, data_files = worker_output[0] self.log(log) self.debug("Loading data: %s", data_files) for data_file in data_files: qpdata = load(os.path.join(self.workdir, data_file)) qpdata.name = self.ivm.suggest_name(data_file.split(".", 1)[0], ensure_unique=False) qpdata.raw() self.ivm.add(qpdata, make_current=(data_file == self._current_data))
def load_data_interactive(self, fname=None, name=None): """ Load data into the IVM from a file (which may already be known) """ if fname is None: fname, _ = QtGui.QFileDialog.getOpenFileName( self, 'Open file', default_save_dir()) if not fname: return set_default_save_dir(os.path.dirname(fname)) # Data is not loaded at this point, however basic metadata is so we can tailor the # options we offer data = load(fname) # If we have apparently 3d data then we have the 'advanced' option of treating the # third dimension as time - some broken NIFTI files require this. force_t_option = (data.nvols == 1 and data.grid.shape[2] > 1) force_t = False options = DragOptions(self, fname, self.ivm, force_t_option=force_t_option, default_main=self.ivm.main is None, possible_roi=(data.nvols == 1)) if not options.exec_(): return data.name = options.name data.roi = options.type == "roi" if force_t_option: force_t = options.force_t # If we had to do anything evil to make data fit, warn and give user the chance to back out if force_t: msg_box = QtGui.QMessageBox(self) msg_box.setText("3D data was interpreted as multiple 2D volumes") msg_box.setStandardButtons(QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel) msg_box.setDefaultButton(QtGui.QMessageBox.Ok) if msg_box.exec_() != QtGui.QMessageBox.Ok: return data.set_2dt() self.ivm.add(data, make_main=options.make_main, make_current=not options.make_main)
def get_images(self): """ :return: Tuple of (sequence of data names, sequence of flip angles in data) """ vols = [] vals = [] for i in range(self.table.rowCount()): filename = self.table.item(i, 0).text() file_vals = [ float(v) for v in self.table.item(i, 1).text().split(",") ] # NB need to pass main volume affine to ensure consistant orientation vol = load(filename) vol.name = "fa%i" % file_vals[0] self.ivm.add(vol) # FIXME need to check dimensions against volume? vols.append(vol.name) vals.append(file_vals) return vols, vals
def _check_file(self, filename): """ Check that filename is a valid FA image. It must be 3D (currently - 4D may be possible but must be handled differently) and must have shape consistent with the main volume """ try: f = load(filename) if len(f.grid.shape) not in (3, 4): QtGui.QMessageBox.warning(None, "Invalid file", "File must be 3D or 4D volumes", QtGui.QMessageBox.Close) return 0 except QpException: QtGui.QMessageBox.warning(None, "Invalid file", "Files must be NIFTI volumes", QtGui.QMessageBox.Close) return 0 return f.nvols
def _load(self): if self._selected: qpdata = load(self._selected) roi = "_mask_" in self._selected or "_mask." in self._selected qpdata.roi = roi self.ivm.add(qpdata, name=self._load_name.text())
def run(self, options): # TR specified in ms but pass in s tr = float(options.pop("tr")) / 1000 fa_vols, fas = [], [] grid = None for fname, fa in options.pop("vfa").items(): self.debug("FA=%f: %s", fa, fname) if fname in self.ivm.data: data = self.ivm.data[fname] else: data = load(_get_filepath(fname, self.indir)) if grid is None: grid = data.grid else: data = data.resample(grid) arr = data.raw() if isinstance(fa, list): if len(fa) > 1: for i, a in enumerate(fa): fas.append(a) fa_vols.append(arr[:, :, :, i]) else: fas.append(fa[0]) fa_vols.append(arr) else: fas.append(fa) fa_vols.append(arr) if "afi" in options: # We are doing a B0 correction (preclinical) afi_vols, trs = [], [] for fname, t in options.pop("afi").items(): if fname in self.ivm.data: data = self.ivm.data[fname] else: data = load(_get_filepath(fname, self.indir)) if grid is None: grid = data.grid else: data = data.resample(grid) arr = data.raw() if isinstance(t, list): for i, a in enumerate(t): trs.append(float(a) / 1000) afi_vols.append(arr[:, :, :, i]) else: trs.append(t) afi_vols.append(arr) fa_afi = options.pop("fa-afi") T10 = t10_map(fa_vols, fas, TR=tr, afi_vols=afi_vols, fa_afi=fa_afi, TR_afi=trs) smooth = options.pop("smooth", None) if smooth is not None: T10 = gaussian_filter(T10, sigma=smooth.get("sigma", 0.5), truncate=smooth.get("truncate", 3)) else: T10 = t10_map(fa_vols, fas, tr) clamp = options.pop("clamp", None) if clamp is not None: np.clip(T10, clamp["min"], clamp["max"], out=T10) self.ivm.add(T10, grid=grid, name="T10", make_current=True)