Пример #1
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)
Пример #2
0
def shift_report(inFID,
                 outFID,
                 inHdr,
                 outHdr,
                 ppmlim=(0.2, 4.2),
                 html=None,
                 function='shift'):
    """
    Generate report
    """
    import plotly.graph_objects as go
    from plotly.subplots import make_subplots
    from fsl_mrs.utils.preproc.reporting import plotStyles, plotAxesStyle

    plotIn = MRS(FID=inFID, header=inHdr)
    plotOut = MRS(FID=outFID, header=outHdr)

    # Fetch line styles
    lines, colors, _ = plotStyles()

    # Make a new figure
    fig = make_subplots(rows=1, cols=2, subplot_titles=['Spectra', 'FID'])

    # Add lines to figure
    trace1 = go.Scatter(x=plotIn.getAxes(ppmlim=ppmlim),
                        y=np.real(plotIn.getSpectrum(ppmlim=ppmlim)),
                        mode='lines',
                        name='Original',
                        line=lines['in'])
    trace2 = go.Scatter(x=plotOut.getAxes(ppmlim=ppmlim),
                        y=np.real(plotOut.getSpectrum(ppmlim=ppmlim)),
                        mode='lines',
                        name='Shifted',
                        line=lines['out'])
    fig.add_trace(trace1, row=1, col=1)
    fig.add_trace(trace2, row=1, col=1)

    # Add lines to figure
    trace3 = go.Scatter(x=plotIn.getAxes(axis='time'),
                        y=np.real(plotIn.FID),
                        mode='lines',
                        name='Original',
                        line=lines['emph'])
    trace4 = go.Scatter(x=plotOut.getAxes(axis='time'),
                        y=np.real(plotOut.FID),
                        mode='lines',
                        name='Shifted',
                        line=lines['diff'])
    fig.add_trace(trace3, row=1, col=2)
    fig.add_trace(trace4, row=1, col=2)

    # Axes layout
    plotAxesStyle(fig, ppmlim, title='Shift summary')
    fig.layout.xaxis2.update(title_text='Time (s)')
    fig.layout.yaxis2.update(zeroline=True,
                             zerolinewidth=1,
                             zerolinecolor='Gray',
                             showgrid=False,
                             showticklabels=False)

    if html is not None:
        from plotly.offline import plot
        from fsl_mrs.utils.preproc.reporting import figgroup, singleReport
        from datetime import datetime
        import os.path as op

        if op.isdir(html):
            filename = 'report_' + datetime.now().strftime(
                "%Y%m%d_%H%M%S%f")[:-3] + '.html'
            htmlfile = op.join(html, filename)
        elif op.isdir(op.dirname(html)) and op.splitext(html)[1] == '.html':
            htmlfile = html
        else:
            raise ValueError('Report html path must be file or directory. ')

        operation, function, description = reportStrings(function)

        opName = operation
        timestr = datetime.now().strftime("%H:%M:%S")
        datestr = datetime.now().strftime("%d/%m/%Y")
        headerinfo = f'Report for fsl_mrs.utils.preproc.shifting.{function}.\n'\
                    + f'Generated at {timestr} on {datestr}.'
        # Figures
        div = plot(fig, output_type='div', include_plotlyjs='cdn')
        figurelist = [
            figgroup(fig=div, name='', foretext=f'{description}', afttext=f'')
        ]

        singleReport(htmlfile, opName, headerinfo, figurelist)
        return fig
    else:
        return fig
Пример #3
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)