Ejemplo n.º 1
0
def data():
    noiseCov = 0.01
    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']

    basisFIDs = []
    for idx, _ in enumerate(amplitude):
        tmp, basisHdr = syntheticFID(noisecovariance=[[0.0]],
                                     chemicalshift=[chemshift[idx]],
                                     amplitude=[1.0],
                                     linewidth=[lw[idx] / 5],
                                     phase=[phases[idx]],
                                     g=[g[idx]])
        basisFIDs.append(tmp[0])
    basisFIDs = np.asarray(basisFIDs)

    synFID, synHdr = syntheticFID(noisecovariance=[[noiseCov]],
                                  chemicalshift=chemshift,
                                  amplitude=amplitude,
                                  linewidth=lw,
                                  phase=phases,
                                  g=g)

    synMRS = MRS(FID=synFID[0],
                 header=synHdr,
                 basis=basisFIDs,
                 basis_hdr=basisHdr,
                 names=basisNames)

    return synMRS, amplitude
Ejemplo n.º 2
0
def test_FIDToSpec_SpecToFID():
    testFID, hdr = synth.syntheticFID(amplitude=[10],
                                      chemicalshift=[0],
                                      phase=[0],
                                      damping=[20])

    # SVS case
    spec = misc.FIDToSpec(testFID[0])
    reformedFID = misc.SpecToFID(spec)
    assert np.allclose(reformedFID, testFID)

    testMRSI = np.tile(testFID, (4, 4, 4, 1)).T
    testspec = misc.FIDToSpec(testMRSI)
    assert np.argmax(np.abs(testspec[:, 2, 2, 2])) == 1024

    testspec = misc.FIDToSpec(testMRSI.T, axis=3)
    assert np.argmax(np.abs(testspec[2, 2, 2, :])) == 1024

    reformedFID = misc.SpecToFID(testspec, axis=3)
    assert np.allclose(reformedFID, testMRSI.T)

    reformedFID = misc.SpecToFID(testspec.T)
    assert np.allclose(reformedFID, testMRSI)

    # Odd number of points - guard against fftshift/ifftshift errors
    testFID, hdr = synth.syntheticFID(amplitude=[1],
                                      chemicalshift=[0],
                                      phase=[0],
                                      damping=[20],
                                      points=1025)
    assert np.allclose(misc.SpecToFID(misc.FIDToSpec(testFID[0])), testFID)
Ejemplo n.º 3
0
def mrsi_data_diff(tmp_path):
    reps = 2
    noiseconv = 0.1*np.eye(reps)
    coilamps = np.ones(reps)
    coilphs = np.zeros(reps)
    FID, hdr = syntheticFID(noisecovariance=noiseconv,
                            coilamps=coilamps,
                            coilphase=coilphs)

    coilamps = np.ones(reps)
    coilphs = np.random.randn(reps)
    FID2, hdr = syntheticFID(noisecovariance=noiseconv,
                             coilamps=coilamps,
                             coilphase=coilphs)

    testFile, testFile2 = [], []
    data, data2 = [], []
    for idx, f in enumerate(FID):
        testname = f'mrsidata_{idx}.nii'
        testFile.append(op.join(tmp_path, testname))

        affine = np.eye(4)
        data.append(np.tile(f, (3, 3, 3, 1)))
        fsl_io.saveNIFTI(testFile[idx], data[idx], hdr, affine=affine)

    for idx, f in enumerate(FID2):
        testname = f'mrsidata_{idx}.nii'
        testFile2.append(op.join(tmp_path, testname))

        affine = np.eye(4)
        data2.append(np.tile(f, (3, 3, 3, 1)))
        fsl_io.saveNIFTI(testFile2[idx], data2[idx], hdr, affine=affine)

    return testFile, testFile2, data, data2
Ejemplo n.º 4
0
def test_align_diff():
    shift0 = np.random.randn(10) * 0.15
    phs = np.random.randn(10) * 0.1 * np.pi
    shiftedFIDs0 = []
    shiftedFIDs1 = []
    for s0, p in zip(shift0, phs):
        testFIDs, testHdrs = syn.syntheticFID(amplitude=[1, 1],
                                              chemicalshift=[-2 + s0, 3 + s0],
                                              phase=[p + np.pi, p],
                                              damping=[100, 100],
                                              points=2048,
                                              noisecovariance=[[1E-6]])
        shiftedFIDs0.append(testFIDs[0])

        testFIDs, testHdrs = syn.syntheticFID(amplitude=[1, 1],
                                              chemicalshift=[-2, 3],
                                              phase=[0, 0],
                                              damping=[100, 100],
                                              points=2048,
                                              noisecovariance=[[1E-6]])
        shiftedFIDs1.append(testFIDs[0])

    testFIDs0, _ = syn.syntheticFID(amplitude=[2, 1],
                                    chemicalshift=[-2, 3],
                                    phase=[np.pi, 0],
                                    damping=[100, 100],
                                    points=2048,
                                    noisecovariance=[[1E-6]])
    testFIDs1, _ = syn.syntheticFID(amplitude=[2, 1],
                                    chemicalshift=[-2, 3],
                                    phase=[0, 0],
                                    damping=[100, 100],
                                    points=2048,
                                    noisecovariance=[[1E-6]])

    tgt = testFIDs0[0] + testFIDs1[0]
    mrs = MRS(FID=tgt, header=testHdrs)

    sub0_aa, sub1_aa, phi, eps = preproc.phase_freq_align_diff(
        shiftedFIDs0,
        shiftedFIDs1,
        testHdrs['bandwidth'],
        testHdrs['centralFrequency'],
        target=tgt,
        shift=False,
        ppmlim=(-5, 5))
    # align.phase_freq_align_diff_report(shiftedFIDs0,shiftedFIDs1,sub0_aa,sub1_aa,testHdrs,eps,phi,shift=False,ppmlim=(-5,5))

    shiftInHz = shift0 * testHdrs['centralFrequency']
    assert np.allclose(eps, shiftInHz, atol=1E-0)
    assert np.allclose(phi, phs, atol=1E-0)
Ejemplo n.º 5
0
def test_combine_FIDs():
    testFIDs, testHdrs = syn.syntheticFID(noisecovariance=np.zeros((2, 2)),
                                          coilamps=[1.0, 1.0],
                                          coilphase=[0.0, np.pi])

    combfids = preproc.combine_FIDs(testFIDs, 'mean')

    assert np.isclose(combfids, 0).all()

    testFIDs, testHdrs = syn.syntheticFID(noisecovariance=np.zeros((4, 4)),
                                          coilamps=[1.0, 1.0, 1.0, 1.0],
                                          coilphase=[0.0, 0.0, 0.0, 0.0])

    weigths = [
        np.exp(1j * 0),
        np.exp(1j * np.pi / 2),
        np.exp(1j * np.pi),
        np.exp(1j * 3 * np.pi / 2)
    ]
    combfids = preproc.combine_FIDs(testFIDs, 'weighted', weights=weigths)

    assert np.isclose(combfids, 0).all()

    #Generate high SNR data
    coilvar = 0.001
    noiseCov = [[coilvar, 0], [0, coilvar]]
    coilamps = 0.5 + np.random.rand(2) * 0.4
    coilphs = np.random.rand(2) * np.pi * 2

    testFIDs, testHdrs = syn.syntheticFID(noisecovariance=noiseCov,
                                          coilamps=coilamps,
                                          coilphase=coilphs,
                                          points=4096)

    invcovMat = coilvar * np.linalg.inv(noiseCov)
    analyticalRoemer = []
    testFIDs = np.asarray(testFIDs).T
    cmplxW = coilamps * np.exp(1j * coilphs)
    for f in testFIDs:
        tmp = (f @ invcovMat @ cmplxW.conj()) / np.sqrt(
            cmplxW.conj() @ invcovMat @ cmplxW)
        analyticalRoemer.append(tmp)
    analyticalRoemer = np.asarray(analyticalRoemer)

    combfid = preproc.combine_FIDs(testFIDs, 'svd', do_prewhiten=True)
    # Check only the first few points otherwise the relative tolarence has to be very high.
    assert np.isclose(np.abs(combfid[:200]),
                      np.abs(analyticalRoemer[:200]),
                      atol=1E-4,
                      rtol=1E-1).all()
Ejemplo n.º 6
0
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
Ejemplo n.º 7
0
def test_syntheticFID():
    testFID, hdr = syn.syntheticFID(noisecovariance=[[0.0]], points=16384)

    # Check FID is sum of lorentzian lineshapes
    # anlytical solution
    T2 = 1 / (hdr['inputopts']['damping'][0])
    M0 = hdr['inputopts']['amplitude'][0]
    f0 = hdr['inputopts']['centralfrequency'] * hdr['inputopts'][
        'chemicalshift'][0]
    f1 = hdr['inputopts']['centralfrequency'] * hdr['inputopts'][
        'chemicalshift'][1]
    f = hdr['faxis']
    spec = (M0 * T2) / (1 + 4 * np.pi**2 * (f0 - f)**2 * T2**2) + 1j * (
        2 * np.pi * M0 * (f0 - f) * T2**2) / (1 + 4 * np.pi**2 *
                                              (f0 - f)**2 * T2**2)
    spec += (M0 * T2) / (1 + 4 * np.pi**2 * (f1 - f)**2 * T2**2) + 1j * (
        2 * np.pi * M0 * (f1 - f) * T2**2) / (1 + 4 * np.pi**2 *
                                              (f1 - f)**2 * T2**2)

    # Can't quite get the scaling right here.
    testSpec = FIDToSpec(testFID[0])
    spec /= np.max(np.abs(spec))
    testSpec /= np.max(np.abs(testSpec))

    assert np.isclose(spec, FIDToSpec(testFID[0]), atol=1E-2, rtol=1E0).all()
Ejemplo n.º 8
0
def test_timeshift():
    # Create data with lots of points and some begin time delay
    testFID, testHdrs = syn.syntheticFID(begintime=-0.001,
                                         points=4096,
                                         noisecovariance=[[0.0]])
    testFID2, testHdrs2 = syn.syntheticFID(begintime=0.000,
                                           points=4096,
                                           noisecovariance=[[0.0]])

    # Reduce points and pad to remove first order phase
    shiftedFID, _ = preproc.timeshift(testFID[0],
                                      1 / testHdrs['inputopts']['bandwidth'],
                                      0.001,
                                      0.0,
                                      samples=4096)

    # assert shiftedFID.size == 2048
    assert np.allclose(shiftedFID, testFID2[0], atol=1E-1)
Ejemplo n.º 9
0
def test_phaseCorrect():
    testFIDs, testHdrs = syn.syntheticFID(amplitude=[1.0],
                                          chemicalshift=[0.0],
                                          phase=[np.pi / 2],
                                          noisecovariance=[[1E-5]])
    corrected, phs, pos = preproc.phaseCorrect(testFIDs[0],
                                               testHdrs['bandwidth'],
                                               testHdrs['centralFrequency'],
                                               ppmlim=(-0.5, 0.5),
                                               shift=False)
    assert np.isclose(phs, -np.pi / 2, atol=1E-2)
Ejemplo n.º 10
0
def test_freqshift():
    testFID, testHdrs = syn.syntheticFID(amplitude=[0.0, 1.0
                                                    ])  # Single peak at 3 ppm
    # Shift to 0 ppm
    dt = 1 / testHdrs['inputopts']['bandwidth']
    shift = testHdrs['inputopts']['centralfrequency'] * -3.0
    shiftedFID = preproc.freqshift(testFID[0], dt, shift)

    maxindex = np.argmax(np.abs(FIDToSpec(shiftedFID)))
    freqOfMax = testHdrs['faxis'][maxindex]

    assert freqOfMax < 5 and freqOfMax > -5
Ejemplo n.º 11
0
def test_noisecov():
    # Create positive semi-definite noise covariance
    inputnoisecov = np.random.random((2, 2))
    inputnoisecov = np.dot(inputnoisecov, inputnoisecov.T)

    testFID, hdr = syn.syntheticFID(coilamps=[1.0, 1.0],
                                    coilphase=[0.0, 0.0],
                                    noisecovariance=inputnoisecov,
                                    amplitude=[0.0, 0.0],
                                    points=32768)

    outcov = np.cov(np.asarray(testFID))

    # Noise cov is for both real and imag, so multiply by 2
    assert np.isclose(outcov, 2 * inputnoisecov, atol=1E-1).all()
Ejemplo n.º 12
0
def mrsi_data_uncomb(tmp_path):
    coils = 4
    noiseconv = 0.1*np.eye(coils)
    coilamps = np.random.randn(coils)
    coilphs = np.random.random(coils)*2*np.pi
    FID, hdr = syntheticFID(noisecovariance=noiseconv,
                            coilamps=coilamps,
                            coilphase=coilphs)

    testname = 'mrsidata_uncomb.nii'
    testFile = op.join(tmp_path, testname)

    affine = np.eye(4)
    data = np.tile(np.asarray(FID).T, (3, 3, 3, 1, 1))
    fsl_io.saveNIFTI(testFile, data, hdr, affine=affine)

    return testFile, data
Ejemplo n.º 13
0
def svs_data(tmp_path):
    reps = 3
    noiseconv = 0.1*np.eye(reps)
    coilamps = np.ones(reps)
    coilphs = np.zeros(reps)
    FID, hdr = syntheticFID(noisecovariance=noiseconv,
                            coilamps=coilamps,
                            coilphase=coilphs)

    testFile = []
    data = []
    for idx, f in enumerate(FID):
        testname = f'svsdata_{idx}.nii'
        testFile.append(op.join(tmp_path, testname))

        affine = np.eye(4)
        data.append(f)
        fsl_io.saveNIFTI(testFile[idx], data[idx], hdr, affine=affine)

    return testFile, data
Ejemplo n.º 14
0
def test_shiftToRef():
    testFIDs, testHdrs = syn.syntheticFID(amplitude=[1, 0],
                                          chemicalshift=[-2.1, 0],
                                          phase=[0, 0],
                                          points=1024,
                                          noisecovariance=[[1E-3]])

    shiftFID, _ = preproc.shiftToRef(testFIDs[0],
                                     -2.0,
                                     testHdrs['bandwidth'],
                                     testHdrs['centralFrequency'],
                                     ppmlim=(-2.2, -2.0),
                                     shift=False)

    mrs = MRS(FID=shiftFID, header=testHdrs)

    maxindex = np.argmax(mrs.getSpectrum(shift=False))
    position = mrs.getAxes(axis='ppm')[maxindex]

    assert np.isclose(position, -2.0, atol=1E-1)
Ejemplo n.º 15
0
def test_hlsvd():
    # low noise
    testFIDs, testHdrs = syn.syntheticFID(noisecovariance=[[1E-6]],
                                          amplitude=[1.0, 1.0],
                                          chemicalshift=[-2, 0])
    limits = [-2.5, -1.5]
    # (FID,dwelltime,centralFrequency,limits,limitUnits = 'ppm',numSingularValues=50)

    removedFID = preproc.hlsvd(testFIDs[0],
                               testHdrs['dwelltime'],
                               testHdrs['centralFrequency'],
                               limits,
                               limitUnits='ppm',
                               numSingularValues=20)

    onResFID = np.exp(-testHdrs['inputopts']['damping'][1] * testHdrs['taxis'])

    assert np.isclose(np.real(removedFID),
                      np.real(onResFID),
                      atol=1E-2,
                      rtol=1E-2).all()
Ejemplo n.º 16
0
def test_phase_freq_align():

    peak1Shift = np.random.rand(10) * 0.1
    peak1Phs = np.random.randn(10) * 2 * np.pi
    shiftedFIDs = []
    for s, p in zip(peak1Shift, peak1Phs):
        testFIDs, testHdrs = syn.syntheticFID(amplitude=[1, 1],
                                              chemicalshift=[-2 + s, 3],
                                              phase=[p, 0.0],
                                              points=2048,
                                              noisecovariance=[[1E-1]])
        shiftedFIDs.append(testFIDs[0])

    # Align across shifted peak
    alignedFIDs, _, _ = preproc.phase_freq_align(shiftedFIDs,
                                                 testHdrs['bandwidth'],
                                                 testHdrs['centralFrequency'] *
                                                 1E6,
                                                 niter=2,
                                                 verbose=False,
                                                 ppmlim=(-2.2, -1.7),
                                                 shift=False)

    meanFID = preproc.combine_FIDs(alignedFIDs, 'mean')
    assert np.max(np.abs(FIDToSpec(meanFID))) > 0.09

    # Align across fixed peak
    alignedFIDs, _, _ = preproc.phase_freq_align(shiftedFIDs,
                                                 testHdrs['bandwidth'],
                                                 testHdrs['centralFrequency'] *
                                                 1E6,
                                                 niter=2,
                                                 verbose=False,
                                                 ppmlim=(2, 4),
                                                 shift=False)

    meanFID = preproc.combine_FIDs(alignedFIDs, 'mean')
    assert np.max(np.abs(FIDToSpec(meanFID))) > 0.09
Ejemplo n.º 17
0
def test_pad():
    testFIDs, testHdrs = syn.syntheticFID()
    paddedFID1 = preproc.pad(testFIDs[0], 1, 'first')
    assert paddedFID1[0] == 0.0
    paddedFID1 = preproc.pad(testFIDs[0], 1, 'last')
    assert paddedFID1[-1] == 0.0
Ejemplo n.º 18
0
def test_truncate():
    testFIDs, testHdrs = syn.syntheticFID()
    truncatedFID1 = preproc.truncate(testFIDs[0], 1, 'first')
    assert (testFIDs[0][1:] == truncatedFID1).all()
    truncatedFID1 = preproc.truncate(testFIDs[0], 1, 'last')
    assert (testFIDs[0][:-1] == truncatedFID1).all()
Ejemplo n.º 19
0
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)