def test_fit_FSLModel_on_invivo_sim(): FIDs, hdr, trueconcs = syntheticFromBasisFile(basis_path, noisecovariance=[[1E-3]], broadening=(9.0, 9.0), concentrations={'Mac': 2.0}) basis, names, header = mrs_io.read_basis(basis_path) mrs = MRS(FID=FIDs, header=hdr, basis=basis, basis_hdr=header[0], names=names) mrs.processForFitting() metab_groups = [0] * mrs.numBasis Fitargs = { 'ppmlim': [0.2, 4.2], 'method': 'MH', 'baseline_order': -1, 'metab_groups': metab_groups, 'MHSamples': 100 } res = fit_FSLModel(mrs, **Fitargs) fittedRelconcs = res.getConc(scaling='internal', metab=mrs.names) answers = np.asarray(trueconcs) answers /= (answers[names.index('Cr')] + trueconcs[names.index('PCr')]) assert np.allclose(fittedRelconcs, answers, atol=5E-2)
def test_quantifyWater(): basis, names, headerb = mrsio.read_basis(basisfile) crIndex = names.index('Cr') data, header = mrsio.read_FID(metabfile) dataw, headerw = mrsio.read_FID(h2ofile) mrs = MRS(FID=data, header=header, basis=basis[:, crIndex], names=['Cr'], basis_hdr=headerb[crIndex], H2O=dataw) mrs.check_FID(repair=True) mrs.check_Basis(repair=True) Fitargs = { 'ppmlim': [0.2, 5.2], 'method': 'MH', 'baseline_order': -1, 'metab_groups': [0] } res = fit_FSLModel(mrs, **Fitargs) tissueFractions = {'GM': 0.6, 'WM': 0.4, 'CSF': 0.0} TE = 0.03 T2dict = { 'H2O_GM': 0.110, 'H2O_WM': 0.080, 'H2O_CSF': 2.55, 'METAB': 0.160 } res.calculateConcScaling(mrs, referenceMetab=['Cr'], waterRefFID=mrs.H2O, tissueFractions=tissueFractions, TE=TE, T2=T2dict, waterReferenceMetab='Cr', wRefMetabProtons=5, reflimits=(2, 5), verbose=False) print(res.getConc(scaling='raw')) print(res.getConc(scaling='internal')) print(res.getConc(scaling='molality')) print(res.getConc(scaling='molarity')) assert np.allclose(res.getConc(scaling='internal'), 1.0) assert np.allclose(res.getConc(scaling='molarity'), 10.59, atol=1E-1)
def data(): noiseCov = 0.001 amplitude = np.asarray([0.5, 0.5, 1.0]) * 10 chemshift = np.asarray([3.0, 3.05, 2.0]) - 4.65 lw = [10, 10, 10] phases = [0, 0, 0] g = [0, 0, 0] basisNames = ['Cr', 'PCr', 'NAA'] begintime = 0.00005 basisFIDs = [] for idx, _ in enumerate(amplitude): tmp, basisHdr = syntheticFID(noisecovariance=[[0.0]], chemicalshift=[chemshift[idx] + 0.1], amplitude=[1.0], linewidth=[lw[idx] / 5], phase=[phases[idx]], g=[g[idx]], begintime=0) basisFIDs.append(tmp[0]) basisFIDs = np.asarray(basisFIDs) synFID, synHdr = syntheticFID(noisecovariance=[[noiseCov]], chemicalshift=chemshift, amplitude=amplitude, linewidth=lw, phase=phases, g=g, begintime=begintime) synMRS = MRS(FID=synFID[0], header=synHdr, basis=basisFIDs, basis_hdr=basisHdr, names=basisNames) metab_groups = [0] * synMRS.numBasis Fitargs = { 'ppmlim': [0.2, 4.2], 'method': 'MH', 'baseline_order': -1, 'metab_groups': metab_groups, 'MHSamples': 100, 'disable_mh_priors': True } res = fit_FSLModel(synMRS, **Fitargs) return res, amplitude
def test_fit_FSLModel_Newton(data): mrs = data[0] amplitudes = data[1] metab_groups = [0] * mrs.numBasis Fitargs = { 'ppmlim': [0.2, 4.2], 'method': 'Newton', 'baseline_order': -1, 'metab_groups': metab_groups } res = fit_FSLModel(mrs, **Fitargs) fittedconcs = res.getConc(metab=mrs.names) fittedRelconcs = res.getConc(scaling='internal', metab=mrs.names) assert np.allclose(fittedconcs, amplitudes, atol=1E-1) assert np.allclose(fittedRelconcs, amplitudes / (amplitudes[0] + amplitudes[1]), atol=1E-1)
def test_calcQC(): # Syntetic data synFID, synHdr = syntheticFID(noisecovariance=[[0.1]], points=2 * 2048, chemicalshift=[0], amplitude=[6.0], linewidth=[10]) synFIDNoise, synHdrNoise = syntheticFID(noisecovariance=[[0.1]], points=2 * 2048, chemicalshift=[0], amplitude=[0], linewidth=[10]) basisFID, basisHdr = syntheticFID(noisecovariance=[[0.0]], points=2 * 2048, chemicalshift=[0], amplitude=[0.1], linewidth=[2]) synMRS = MRS(FID=synFID[0], header=synHdr) synMRSNoise = MRS(FID=synFIDNoise[0], header=synHdrNoise) synMRSNoNoise = MRS(FID=synHdr['noiseless'], header=synHdr) synMRS_basis = MRS(FID=synFID[0], header=synHdr, basis=basisFID[0], basis_hdr=basisHdr, names=['Peak1']) truenoiseSD = np.sqrt(synHdrNoise['cov'][0, 0]) pureNoiseMeasured = np.std(synMRSNoise.getSpectrum()) realnoise = np.std(np.real(synMRSNoise.getSpectrum())) imagNoise = np.std(np.imag(synMRSNoise.getSpectrum())) print( f'True cmplx noise = {truenoiseSD:0.3f}, pure noise measured = {pureNoiseMeasured:0.3f} (real/imag = {realnoise:0.3f}/{imagNoise:0.3f})' ) # Calc SNR without apodisation from the no noise and pure noise spectra truePeakHeight = np.max(np.real(synMRSNoNoise.getSpectrum())) SNR_noApod = truePeakHeight / pureNoiseMeasured print( f'SNR no apod: {SNR_noApod:0.1f} ({truePeakHeight:0.2e}/{pureNoiseMeasured:0.2e})' ) # Calc SNR with apodisation from the no noise and pure noise spectra trueLW = synHdr['inputopts']['linewidth'][0] trueApodSpec_Noise = specApodise(synMRSNoise, trueLW) apodNoise = np.std(trueApodSpec_Noise) trueApodSpec_noNoise = specApodise(synMRSNoNoise, trueLW) peakHeigtApod = np.max(np.real(trueApodSpec_noNoise)) SNR = peakHeigtApod / apodNoise print(f'SNR w. apod: {SNR:0.1f} ({peakHeigtApod:0.2e}/{apodNoise:0.2e})') metab_groups = [0] Fitargs = { 'ppmlim': [2.65, 6.65], 'method': 'Newton', 'baseline_order': -1, 'metab_groups': [0] } res = fit_FSLModel(synMRS_basis, **Fitargs) fwhm_test, SNRObj = calcQC(synMRS_basis, res, ppmlim=[2.65, 6.65]) print(f'Measured FWHM: {fwhm_test.mean().to_numpy()[0]:0.1f}') print(f'Measured spec SNR: {SNRObj.spectrum:0.1f}') print(f'Measured peak SNR: {SNRObj.peaks.mean().to_numpy()[0]:0.1f}') assert np.isclose(fwhm_test.mean().to_numpy(), trueLW, atol=1E0) assert np.isclose(SNRObj.spectrum, SNR_noApod, atol=1E1) assert np.isclose(SNRObj.peaks.mean().to_numpy(), SNR, atol=2E1)