def test_nocalib(): """ Check we get an error if there is no calibration data """ d = np.random.rand(5, 5, 5, 6) perf_img = Image(name="perfusion", image=d) wsp = Workspace(calib_method="voxelwise") with pytest.raises(ValueError): calib.calibrate(wsp, perf_img)
def test_bad_method(): """ Check we get an error on an invalid method """ d = np.random.rand(5, 5, 5, 6) perf_img = Image(name="perfusion", image=d) d = np.random.rand(5, 5, 5, 6) calib_img = Image(name="calib", image=d) wsp = Workspace(calib=calib_img, calib_method="random") with pytest.raises(ValueError): calib.calibrate(wsp, perf_img)
def test_refregion_gain(): """ Modify calibration gain """ GAIN = 3.4 perf_img, calib_img = _get_imgs() ref_d = np.ones((5, 5, 5)) ref_img = Image(name="refmask", image=ref_d) wsp = Workspace(calib=calib_img, calib_method="refregion", refmask=ref_img, calib_aslreg=True, tissref="wm", calib_gain=GAIN) perf_calib = calib.calibrate(wsp, perf_img) calibrated_d = perf_calib.data m0_expected = _expected_m0(np.mean(calib_img.data), 1.0, 50, 0.82, gain=GAIN) np.testing.assert_allclose(calibrated_d, perf_img.data / m0_expected)
def test_refregion_unknown(): """ Reference region unknown type """ perf_img, calib_img = _get_imgs() ref_d = np.ones((5, 5, 5)) ref_img = Image(name="refmask", image=ref_d) wsp = Workspace(calib=calib_img, calib_method="refregion", refmask=ref_img, calib_aslreg=True, tissref="kryptonite") with pytest.raises(ValueError): calib.calibrate(wsp, perf_img)
def test_defaults(): """ Check default calibration works """ perf_d = np.random.rand(5, 5, 5) perf_img = Image(name="perfusion", image=perf_d) calib_d = np.random.rand(5, 5, 5) calib_img = Image(name="calib", image=calib_d) wsp = Workspace(calib=calib_img, calib_method="voxelwise") perf_calib = calib.calibrate(wsp, perf_img) calibrated_d = perf_calib.data assert (perf_calib.name == "perfusion_calib") assert (perf_calib.shape == perf_img.shape) # Default partition coefficient is 0.9 np.testing.assert_allclose(calibrated_d, 0.9 * perf_d / calib_d)
def test_partition_coeff(): """ Check tissue/blood partition coefficient """ PC = 0.67 perf_d = np.random.rand(5, 5, 5) perf_img = Image(name="perfusion", image=perf_d) calib_d = np.random.rand(5, 5, 5) calib_img = Image(name="calib", image=calib_d) wsp = Workspace(calib=calib_img, calib_method="voxelwise", pct=PC) perf_calib = calib.calibrate(wsp, perf_img) calibrated_d = perf_calib.data assert (perf_calib.name == "perfusion_calib") assert (perf_calib.shape == perf_img.shape) # Default partition coefficient is 0.9 np.testing.assert_allclose(calibrated_d, PC * perf_d / calib_d)
def test_alpha(): """ Check inversion efficiency """ ALPHA = 0.74 perf_d = np.random.rand(5, 5, 5) perf_img = Image(name="perfusion", image=perf_d) calib_d = np.random.rand(5, 5, 5) calib_img = Image(name="calib", image=calib_d) wsp = Workspace(calib=calib_img, calib_method="voxelwise") perf_calib = calib.calibrate(wsp, perf_img, alpha=ALPHA) calibrated_d = perf_calib.data assert (perf_calib.name == "perfusion_calib") assert (perf_calib.shape == perf_img.shape) # Default partition coefficient is 0.9 np.testing.assert_allclose(calibrated_d, 0.9 / ALPHA * perf_d / calib_d)
def test_refregion_gm_all(): """ Reference region mask is whole image """ perf_img, calib_img = _get_imgs() ref_d = np.ones((5, 5, 5)) ref_img = Image(name="refmask", image=ref_d) wsp = Workspace(calib=calib_img, calib_method="refregion", refmask=ref_img, calib_aslreg=True, tissref="gm") perf_calib = calib.calibrate(wsp, perf_img) calibrated_d = perf_calib.data # GM defaults m0_expected = _expected_m0(np.mean(calib_img.data), 1.3, 100, 0.98) np.testing.assert_allclose(calibrated_d, perf_img.data / m0_expected)
def test_refregion_csf_t2star(): """ Using T2* instead of T2 for CSF """ perf_img, calib_img = _get_imgs() ref_d = np.ones((5, 5, 5)) ref_img = Image(name="refmask", image=ref_d) wsp = Workspace(calib=calib_img, calib_method="refregion", refmask=ref_img, calib_aslreg=True, tissref="csf", t2star=True) perf_calib = calib.calibrate(wsp, perf_img) calibrated_d = perf_calib.data m0_expected = _expected_m0(np.mean(calib_img.data), 4.3, 400, 1.15) np.testing.assert_allclose(calibrated_d, perf_img.data / m0_expected)
def test_shorttr_corr(): """ Check correction for short TR """ TR, T1 = 3.0, 1.1 perf_d = np.random.rand(5, 5, 5) perf_img = Image(name="perfusion", image=perf_d) calib_d = np.random.rand(5, 5, 5) calib_img = Image(name="calib", image=calib_d) wsp = Workspace(calib=calib_img, calib_method="voxelwise", tr=TR, t1=T1) perf_calib = calib.calibrate(wsp, perf_img) calibrated_d = perf_calib.data assert (perf_calib.name == "perfusion_calib") assert (perf_calib.shape == perf_img.shape) factor = 1 - math.exp(-TR / T1) # Default partition coefficient is 0.9 np.testing.assert_allclose(calibrated_d, 0.9 * factor * perf_d / calib_d)
def test_cgain_var(): """ Check calibration gain on variances """ GAIN = 1.23 perf_d = np.random.rand(5, 5, 5) perf_img = Image(name="perfusion", image=perf_d) calib_d = np.random.rand(5, 5, 5) calib_img = Image(name="calib", image=calib_d) wsp = Workspace(calib=calib_img, calib_method="voxelwise", calib_gain=GAIN) perf_calib = calib.calibrate(wsp, perf_img, var=True) calibrated_d = perf_calib.data assert (perf_calib.name == "perfusion_calib") assert (perf_calib.shape == perf_img.shape) # Default partition coefficient is 0.9 np.testing.assert_allclose( calibrated_d, 0.9 * 0.9 / GAIN / GAIN * perf_d / calib_d / calib_d)
def test_multiplier(): """ Check end multiplier for physical units """ MULTIPLIER = 7654 perf_d = np.random.rand(5, 5, 5) perf_img = Image(name="perfusion", image=perf_d) calib_d = np.random.rand(5, 5, 5) calib_img = Image(name="calib", image=calib_d) wsp = Workspace(calib=calib_img, calib_method="voxelwise") perf_calib = calib.calibrate(wsp, perf_img, multiplier=MULTIPLIER) calibrated_d = perf_calib.data assert (perf_calib.name == "perfusion_calib") assert (perf_calib.shape == perf_img.shape) # Default partition coefficient is 0.9 np.testing.assert_allclose(calibrated_d, 0.9 * MULTIPLIER * perf_d / calib_d)
def run(self, options): """ Run the process """ from oxasl import Workspace, calib from fsl.data.image import Image data = self.get_data(options) img = Image(data.raw(), name=data.name) roi = self.get_roi(options, data.grid) options["mask"] = Image(roi.raw(), name=roi.name) calib_name = options.pop("calib-data") if calib_name not in self.ivm.data: raise QpException("Calibration data not found: %s" % calib_name) else: calib_img = Image(self.ivm.data[calib_name].resample( data.grid).raw(), name=calib_name) ref_roi_name = options.pop("ref-roi", None) if ref_roi_name is not None: if ref_roi_name not in self.ivm.rois: raise QpException("Reference ROI not found: %s" % calib_name) else: options["ref_mask"] = Image( self.ivm.rois[ref_roi_name].resample(data.grid).raw(), name=ref_roi_name) options["calib_method"] = options.pop("method", None) output_name = options.pop("output-name", data.name + "_calib") logbuf = six.StringIO() wsp = Workspace(log=logbuf, **options) wsp.calib = calib_img ## FIXME variance mode calibrated = calib.calibrate(wsp, img) self.log(logbuf.getvalue()) self.ivm.add(name=output_name, data=calibrated.data, grid=data.grid, make_current=True)
def test_shorttr_corr_not1(): """ Check correction for short TR is not done (and generates warning) if T1 not given """ TR = 3.0 perf_d = np.random.rand(5, 5, 5) perf_img = Image(name="perfusion", image=perf_d) calib_d = np.random.rand(5, 5, 5) calib_img = Image(name="calib", image=calib_d) log = StringIO() wsp = Workspace(calib=calib_img, calib_method="voxelwise", tr=TR, log=log) perf_calib = calib.calibrate(wsp, perf_img) calibrated_d = perf_calib.data assert (perf_calib.name == "perfusion_calib") assert (perf_calib.shape == perf_img.shape) assert ("WARNING" in log.getvalue()) # Default partition coefficient is 0.9 np.testing.assert_allclose(calibrated_d, 0.9 * perf_d / calib_d)
def test_refregion_pc(): """ Reference region override partition coeff of ref tissue """ PC = 0.67 perf_img, calib_img = _get_imgs() ref_d = np.ones((5, 5, 5)) ref_img = Image(name="refmask", image=ref_d) wsp = Workspace(calib=calib_img, calib_method="refregion", refmask=ref_img, calib_aslreg=True, tissref="wm", pcr=PC) perf_calib = calib.calibrate(wsp, perf_img) calibrated_d = perf_calib.data m0_expected = _expected_m0(np.mean(calib_img.data), 1.0, 50, PC) np.testing.assert_allclose(calibrated_d, perf_img.data / m0_expected)
def test_refregion_t2r(): """ Reference region override T2 of ref tissue """ T2 = 635 perf_img, calib_img = _get_imgs() ref_d = np.ones((5, 5, 5)) ref_img = Image(name="refmask", image=ref_d) wsp = Workspace(calib=calib_img, calib_method="refregion", refmask=ref_img, calib_aslreg=True, tissref="wm", t2r=T2) perf_calib = calib.calibrate(wsp, perf_img) calibrated_d = perf_calib.data m0_expected = _expected_m0(np.mean(calib_img.data), 1.0, T2, 0.82) np.testing.assert_allclose(calibrated_d, perf_img.data / m0_expected)
def test_refregion_defaults(): """ Reference region defaults to CSF """ perf_img, calib_img = _get_imgs() ref_d = np.ones((5, 5, 5)) ref_img = Image(name="refmask", image=ref_d) wsp = Workspace(calib=calib_img, calib_method="refregion", refmask=ref_img, calib_aslreg=True) perf_calib = calib.calibrate(wsp, perf_img) calibrated_d = perf_calib.data assert (perf_calib.name == "perfusion_calib") assert (perf_calib.shape == perf_img.shape) # CSF defaults m0_expected = _expected_m0(np.mean(calib_img.data), 4.3, 750, 1.15) np.testing.assert_allclose(calibrated_d, perf_img.data / m0_expected)
def test_refregion_tr(): """ Reference region override TR """ TR = 7.1 perf_img, calib_img = _get_imgs() ref_d = np.ones((5, 5, 5)) ref_img = Image(name="refmask", image=ref_d) wsp = Workspace(calib=calib_img, calib_method="refregion", refmask=ref_img, calib_aslreg=True, tissref="wm", tr=TR) perf_calib = calib.calibrate(wsp, perf_img) calibrated_d = perf_calib.data # WM defaults m0_expected = _expected_m0(np.mean(calib_img.data), 1.0, 50, 0.82, tr=TR) np.testing.assert_allclose(calibrated_d, perf_img.data / m0_expected)
def output_native(wsp, basil_wsp, report=None): """ Create native space output images :param wsp: Workspace object. Output will be placed in a sub workspace named ``native`` :param basil_wsp: Workspace in which Basil modelling has been run. The ``finalstep`` attribute is expected to point to the final output workspace """ if not wsp.output_native: return wsp.sub("native") # Output the differenced data averaged across repeats for kinetic curve comparison # with the model if wsp.asldata.iaf in ("tc", "ct", "diff"): wsp.native.diffdata_mean = wsp.asldata.diff().mean_across_repeats() # Output model fitting results prefixes = ["", "mean"] if wsp.output_stddev: prefixes.append("std") if wsp.output_var: prefixes.append("var") for fabber_name, oxasl_output in OUTPUT_ITEMS.items(): for prefix in prefixes: is_variance = prefix == "var" if is_variance: # Variance is not output by Fabber natively so we get it by # squaring the standard deviation. We also pass the flag # to the calibration routine so it can square the correction # factors fabber_output = "std_%s" % fabber_name elif prefix: fabber_output = "%s_%s" % (prefix, fabber_name) else: fabber_output = fabber_name img = basil_wsp.finalstep.ifnone(fabber_output, None) if img is not None: # Make negative/nan values = 0 and ensure masked value zeroed data = np.copy(img.data) data[~np.isfinite(data)] = 0 data[img.data < 0] = 0 data[wsp.rois.mask.data == 0] = 0 img = Image(data, header=img.header) name, multiplier, calibrate, _, _, _ = oxasl_output if prefix and prefix != "mean": name = "%s_%s" % (name, prefix) if calibrate: # Anything that needs calibration also requires sensitivity correction img, = corrections.apply_sensitivity_correction(wsp, img) if is_variance: img = Image(np.square(img.data), header=img.header) setattr(wsp.native, name, img) if calibrate and wsp.calib is not None: alpha = wsp.ifnone( "calib_alpha", 1.0 if wsp.asldata.iaf in ("ve", "vediff") else 0.85 if wsp.asldata.casl else 0.98) img = calib.calibrate(wsp, img, multiplier=multiplier, alpha=alpha, var=is_variance) name = "%s_calib" % name setattr(wsp.native, name, img) if wsp.save_mask: wsp.native.mask = wsp.rois.mask output_report(wsp.native, report=report)