示例#1
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
示例#2
0
def combine_FIDs_report(inFIDs,
                        outFID,
                        hdr,
                        ncha=2,
                        ppmlim=(0.0, 6.0),
                        method='not specified',
                        html=None):
    """ Take list of FIDs that are passed to combine and output

    If uncombined data it will display ncha channels (default 2).
    """
    from fsl_mrs.core import MRS
    import plotly.graph_objects as go
    from fsl_mrs.utils.preproc.reporting import plotStyles, plotAxesStyle
    from matplotlib.pyplot import cm
    toMRSobj = lambda fid: MRS(FID=fid, header=hdr)

    # Assemble data to plot
    toPlotIn = []
    colourVecIn = []
    legendIn = []
    if isinstance(inFIDs, list):
        for idx, fid in enumerate(inFIDs):
            if inFIDs[0].ndim > 1:
                toPlotIn.extend([toMRSobj(f) for f in fid[:, :ncha].T])
                colourVecIn.extend([idx / len(inFIDs)] * ncha)
                legendIn.extend(
                    [f'FID #{idx}: CHA #{jdx}' for jdx in range(ncha)])
            else:
                toPlotIn.append(toMRSobj(fid))
                colourVecIn.append(idx / len(inFIDs))
                legendIn.append(f'FID #{idx}')

    elif inFIDs.ndim > 1:
        toPlotIn.extend([toMRSobj(f) for f in inFIDs[:, :ncha].T])
        colourVecIn.extend([float(jdx) / ncha for jdx in range(ncha)])
        legendIn.extend([f'FID #0: CHA #{jdx}' for jdx in range(ncha)])

    toPlotOut = []
    legendOut = []
    if outFID.ndim > 1:
        toPlotOut.extend([toMRSobj(f) for f in outFID[:, :ncha].T])
        legendOut.extend([f'Combined: CHA #{jdx}' for jdx in range(ncha)])
    else:
        toPlotOut.append(toMRSobj(outFID))
        legendOut.append('Combined')

    def addline(fig, mrs, lim, name, linestyle):
        trace = go.Scatter(x=mrs.getAxes(ppmlim=lim),
                           y=np.real(mrs.getSpectrum(ppmlim=lim)),
                           mode='lines',
                           name=name,
                           line=linestyle)
        return fig.add_trace(trace)

    lines, colors, _ = plotStyles()
    colors = cm.Spectral(np.array(colourVecIn).ravel())

    fig = go.Figure()
    for idx, fid in enumerate(toPlotIn):
        cval = np.round(255 * colors[idx, :])
        linetmp = {'color': f'rgb({cval[0]},{cval[1]},{cval[2]})', 'width': 1}
        fig = addline(fig, fid, ppmlim, legendIn[idx], linetmp)

    for idx, fid in enumerate(toPlotOut):
        fig = addline(fig, fid, ppmlim, legendOut[idx], lines['blk'])
    plotAxesStyle(fig, ppmlim, 'Combined')

    # Generate report
    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. ')

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

        singleReport(htmlfile, opName, headerinfo, figurelist)
        return fig
    else:
        return fig
示例#3
0
def hlsvd_report(inFID,
                 outFID,
                 hdr,
                 limits,
                 limitUnits='ppm',
                 plotlim=(0.2, 6),
                 html=None):
    """
    Generate hlsvd report
    """
    # from matplotlib import pyplot as plt
    from fsl_mrs.core import MRS
    import plotly.graph_objects as go
    from fsl_mrs.utils.preproc.reporting import plotStyles, plotAxesStyle

    # Turn input FIDs into mrs objects
    def toMRSobj(fid):
        return MRS(FID=fid, header=hdr)

    plotIn = toMRSobj(inFID)
    plotOut = toMRSobj(outFID)
    plotDiff = toMRSobj(outFID - inFID)

    if limitUnits.lower() == 'ppm':
        limits = np.array(limits) + H2O_PPM_TO_TMS
    elif limitUnits.lower() == 'ppm+shift':
        pass
    elif limitUnits.lower() == 'hz':
        limits = (np.array(limits)/(plotIn.centralFrequency/1E6)) + \
                 H2O_PPM_TO_TMS
    else:
        raise ValueError('limitUnits should be one of: ppm, ppm+shift or hz.')

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

    # Make a new figure
    fig = go.Figure()

    # Add lines to figure
    def addline(fig, mrs, lim, name, linestyle):
        trace = go.Scatter(x=mrs.getAxes(ppmlim=lim),
                           y=np.real(mrs.getSpectrum(ppmlim=lim)),
                           mode='lines',
                           name=name,
                           line=linestyle)
        return fig.add_trace(trace)

    fig = addline(fig, plotIn, plotlim, 'Uncorrected', lines['in'])
    fig = addline(fig, plotIn, limits, 'Limits', lines['emph'])
    fig = addline(fig, plotOut, plotlim, 'Corrected', lines['out'])
    fig = addline(fig, plotDiff, plotlim, 'Difference', lines['diff'])

    # Axes layout
    plotAxesStyle(fig, plotlim, title='HLSVD summary')

    # Axes
    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. ')

        opName = 'HLSVD'
        timestr = datetime.now().strftime("%H:%M:%S")
        datestr = datetime.now().strftime("%d/%m/%Y")
        headerinfo = 'Report for fsl_mrs.utils.preproc.remove.HLSVD.\n' + \
                     f'Generated at {timestr} on {datestr}.'

        # Figures
        div = plot(fig, output_type='div', include_plotlyjs='cdn')
        figurelist = [
            figgroup(fig=div,
                     name='',
                     foretext='HLSVD removal of peaks in the range'
                     f' {limits[0]:0.1f} to'
                     f' {limits[1]:0.1f} ppm.',
                     afttext='')
        ]

        singleReport(htmlfile, opName, headerinfo, figurelist)
        return fig
    else:
        return fig
示例#4
0
def apodize_report(inFID, outFID, hdr, plotlim=(0.2, 6), html=None):
    """
    Generate report
    """
    # from matplotlib import pyplot as plt
    from fsl_mrs.core import MRS
    import plotly.graph_objects as go
    from fsl_mrs.utils.preproc.reporting import plotStyles, plotAxesStyle

    # Turn input FIDs into mrs objects
    toMRSobj = lambda fid: MRS(FID=fid, header=hdr)
    plotIn = toMRSobj(inFID)
    plotOut = toMRSobj(outFID)

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

    # Make a new figure
    fig = go.Figure()

    # Add lines to figure
    def addline(fig, mrs, lim, name, linestyle):
        trace = go.Scatter(x=mrs.getAxes(ppmlim=lim),
                           y=np.real(mrs.getSpectrum(ppmlim=lim)),
                           mode='lines',
                           name=name,
                           line=linestyle)
        return fig.add_trace(trace)

    fig = addline(fig, plotIn, plotlim, 'Uncorrected', lines['in'])
    fig = addline(fig, plotOut, plotlim, 'Corrected', lines['out'])

    # Axes layout
    plotAxesStyle(fig, plotlim, title='Apodization summary')

    # Generate report
    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. ')

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

        singleReport(htmlfile, opName, headerinfo, figurelist)
        return fig
    else:
        return fig
示例#5
0
def phase_freq_align_diff_report(inFIDs0,
                                 inFIDs1,
                                 outFIDs0,
                                 outFIDs1,
                                 hdr,
                                 eps,
                                 phi,
                                 ppmlim=None,
                                 diffType='add',
                                 shift=True,
                                 html=None):
    from fsl_mrs.utils.preproc.combine import combine_FIDs
    import plotly.graph_objects as go
    from fsl_mrs.utils.preproc.reporting import plotStyles, plotAxesStyle
    from plotly.subplots import make_subplots

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

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

    trace1 = go.Scatter(x=np.arange(1,
                                    len(phi) + 1),
                        y=np.array(phi) * (180.0 / np.pi),
                        mode='lines',
                        name='Phase',
                        line=lines['out'])
    fig.add_trace(trace1, row=1, col=1)
    fig.layout.xaxis.update(title_text='Transient #')
    fig.layout.yaxis.update(title_text=r'$\phi$ (degrees)')

    trace2 = go.Scatter(x=np.arange(1,
                                    len(eps) + 1),
                        y=eps,
                        mode='lines',
                        name='Shift',
                        line=lines['diff'])
    fig.add_trace(trace2, row=1, col=2)
    fig.layout.yaxis2.update(title_text='Shift (Hz)')
    fig.layout.xaxis2.update(title_text='Transient #')

    diffFIDListIn = []
    diffFIDListOut = []
    for fid0i, fid1i, fid0o, fid1o in zip(inFIDs0, inFIDs1, outFIDs0,
                                          outFIDs1):
        if diffType.lower() == 'add':
            diffFIDListIn.append(add(fid1i, fid0i))
            diffFIDListOut.append(add(fid1o, fid0o))
        elif diffType.lower() == 'sub':
            diffFIDListIn.append(subtract(fid1i, fid0i))
            diffFIDListOut.append(subtract(fid1o, fid0o))
        else:
            raise ValueError('diffType must be add or sub.')

    meanIn = combine_FIDs(diffFIDListIn, 'mean')
    meanOut = combine_FIDs(diffFIDListOut, 'mean')
    toMRSobj = lambda fid: MRS(FID=fid, header=hdr)
    meanIn = toMRSobj(meanIn)
    meanOut = toMRSobj(meanOut)

    if shift:
        axis = 'ppmshift'
    else:
        axis = 'ppm'

    toPlotIn, toPlotOut = [], []
    for fid in diffFIDListIn:
        toPlotIn.append(toMRSobj(fid))
    for fid in diffFIDListOut:
        toPlotOut.append(toMRSobj(fid))

    def addline(fig, mrs, lim, name, linestyle):
        trace = go.Scatter(x=mrs.getAxes(ppmlim=lim, axis=axis),
                           y=np.real(mrs.getSpectrum(ppmlim=lim, shift=shift)),
                           mode='lines',
                           name=name,
                           line=linestyle)
        return fig.add_trace(trace)

    fig2 = go.Figure()
    for idx, fid in enumerate(toPlotIn):
        cval = np.round(255 * idx / len(toPlotIn))
        linetmp = {'color': f'rgb(0,{cval},{cval})', 'width': 1}
        fig2 = addline(fig2, fid, ppmlim, f'#{idx}', linetmp)
    fig2 = addline(fig2, meanIn, ppmlim, f'Mean - Unligned', lines['blk'])
    plotAxesStyle(fig2, ppmlim, 'Unaligned')

    fig3 = go.Figure()
    for idx, fid in enumerate(toPlotOut):
        cval = np.round(255 * idx / len(toPlotIn))
        linetmp = {'color': f'rgb(0,{cval},{cval})', 'width': 1}
        fig3 = addline(fig3, fid, ppmlim, f'#{idx}', linetmp)
    fig3 = addline(fig3, meanIn, ppmlim, f'Mean - Unligned', lines['out'])
    fig3 = addline(fig3, meanOut, ppmlim, f'Mean - Aligned', lines['blk'])
    plotAxesStyle(fig3, ppmlim, 'Aligned')

    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. ')

        opName = 'AlignDiff'
        timestr = datetime.now().strftime("%H:%M:%S")
        datestr = datetime.now().strftime("%d/%m/%Y")
        headerinfo = 'Report for fsl_mrs.utils.align.phase_freq_align_diff.\n'\
                    + f'Generated at {timestr} on {datestr}.'
        # Figures
        div = plot(fig, output_type='div', include_plotlyjs='cdn')
        figurelist = [
            figgroup(fig=div,
                     name='',
                     foretext=f'Alignment parameters.',
                     afttext=f'')
        ]
        div2 = plot(fig2, output_type='div', include_plotlyjs='cdn')
        figurelist.append(
            figgroup(fig=div2,
                     name='',
                     foretext=f'Transients before alignment.',
                     afttext=f''))
        div3 = plot(fig3, output_type='div', include_plotlyjs='cdn')
        figurelist.append(
            figgroup(fig=div3,
                     name='',
                     foretext=f'Transients after alignment.',
                     afttext=f''))

        singleReport(htmlfile, opName, headerinfo, figurelist)
        return fig, fig2, fig3
    else:
        return fig, fig2, fig3
示例#6
0
def identifyUnlikeFIDs_report(goodFIDs,badFIDs,hdr,keepIndicies,rmIndicies,metric,ppmlim=(0.2,4.2),sdlimit = 1.96,html=None):
    from fsl_mrs.utils.preproc.combine import combine_FIDs
    import plotly.graph_objects as go    
    from fsl_mrs.utils.preproc.reporting import plotStyles,plotAxesStyle

    metricGd = np.array(metric)[keepIndicies]
    metricBd = np.array(metric)[rmIndicies]    
    metric_avg = np.mean(metric)
    metric_std = np.std(metric)

    metricGd_SD = np.abs(metricGd-metric_avg)/metric_std
    metricBd_SD = np.abs(metricBd-metric_avg)/metric_std

    gdIndex = np.argsort(metricGd_SD)
    bdIndex = np.argsort(metricBd_SD)



    plotGood,plotBad = [],[]
    gdLegend,bdLegend = [],[]
    toMRSobj = lambda fid : MRS(FID=fid,header=hdr)    

    for idx in gdIndex:
        fid = goodFIDs[idx]
        plotGood.append(toMRSobj(fid))
        gdLegend.append(f'Kept (SD={metricGd_SD[idx]:0.2f})')
    for idx in bdIndex:
        fid = badFIDs[idx]
        plotBad.append(toMRSobj(fid))
        bdLegend.append(f'Removed (SD={metricBd_SD[idx]:0.2f})')
        
    target = get_target_FID(goodFIDs,target='median')
    tgtmrs = toMRSobj(target)

    # Fetch line styles
    lines,colors,_ = plotStyles()
    # Make a new figure
    fig = go.Figure()

    # Add lines to figure
    def addline(fig,mrs,lim,name,linestyle):
        trace = go.Scatter(x=mrs.getAxes(ppmlim=lim),
                        y=np.real(mrs.getSpectrum(ppmlim=lim)),
                        mode='lines',
                        name=name,
                        line=linestyle)
        return fig.add_trace(trace)    
    for fid,leg in zip(plotGood,gdLegend):        
        fig = addline(fig,fid,ppmlim,leg,lines['out'])
    for fid,leg in zip(plotBad,bdLegend):        
        fig = addline(fig,fid,ppmlim,leg,lines['emph'])    
    fig = addline(fig,tgtmrs,ppmlim,'Target',lines['blk']) 
    
    plotAxesStyle(fig,ppmlim,title = 'Bad average removal summary')

    # Generate report 
    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. ')
        
        opName = 'BadAverageRemoval'
        timestr = datetime.now().strftime("%H:%M:%S")
        datestr = datetime.now().strftime("%d/%m/%Y")
        headerinfo = 'Report for fsl_mrs.utils.preproc.unlike.identifyUnlikeFIDs.\n'\
                    + f'Generated at {timestr} on {datestr}.'        
        # Figures
        div = plot(fig, output_type='div',include_plotlyjs='cdn')
        figurelist = [figgroup(fig = div,
                            name= '',
                            foretext= f'Identification of FIDs unlike others. SD limit = {sdlimit:0.2f}',
                            afttext= f'')]

        singleReport(htmlfile,opName,headerinfo,figurelist)
        return fig
    else:
        return fig
示例#7
0
def phaseCorrect_report(inFID,
                        outFID,
                        hdr,
                        position,
                        ppmlim=(2.8, 3.2),
                        html=None):
    """
    Generate report for phaseCorrect
    """
    # from matplotlib import pyplot as plt
    from fsl_mrs.core import MRS
    import plotly.graph_objects as go
    from fsl_mrs.utils.preproc.reporting import plotStyles, plotAxesStyle

    # Turn input FIDs into mrs objects
    toMRSobj = lambda fid: MRS(FID=fid, header=hdr)
    plotIn = toMRSobj(inFID)
    plotOut = toMRSobj(outFID)

    widelimit = (0, 6)

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

    # Make a new figure
    fig = go.Figure()

    # Add lines to figure
    def addline(fig, mrs, lim, name, linestyle):
        trace = go.Scatter(x=mrs.getAxes(ppmlim=lim),
                           y=np.real(mrs.getSpectrum(ppmlim=lim)),
                           mode='lines',
                           name=name,
                           line=linestyle)
        return fig.add_trace(trace)

    fig = addline(fig, plotIn, widelimit, 'Unphased', lines['in'])
    fig = addline(fig, plotIn, ppmlim, 'Search region', lines['emph'])

    if position is None:
        # re-estimate here.
        position = np.argmax(np.abs(plotIn.getSpectrum(ppmlim=ppmlim)))

    axis = [plotIn.getAxes(ppmlim=ppmlim)[position]]
    y_data = [np.real(plotIn.getSpectrum(ppmlim=ppmlim))[position]]
    trace = go.Scatter(x=axis,
                       y=y_data,
                       mode='markers',
                       name='max point',
                       marker=dict(color=colors['emph'], symbol='x', size=8))
    fig.add_trace(trace)

    fig = addline(fig, plotOut, widelimit, 'Phased', lines['out'])

    # Axes layout
    plotAxesStyle(fig, widelimit, title='Phase correction summary')

    # Axes
    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. ')

        opName = 'Phase correction'
        timestr = datetime.now().strftime("%H:%M:%S")
        datestr = datetime.now().strftime("%d/%m/%Y")
        headerinfo = 'Report for fsl_mrs.utils.preproc.phasing.phaseCorrect.\n'\
                    + f'Generated at {timestr} on {datestr}.'
        # Figures
        div = plot(fig, output_type='div', include_plotlyjs='cdn')
        figurelist = [
            figgroup(
                fig=div,
                name='',
                foretext=
                f'Phase correction of spectra based on maximum in the range {ppmlim[0]} to {ppmlim[1]} ppm.',
                afttext=f'')
        ]

        singleReport(htmlfile, opName, headerinfo, figurelist)
        return fig
    else:
        return fig