Esempio n. 1
0
def calcAndPlotWeighted(xres, yres, args):
    fs = np.linspace(0, 1, xres)
    ts = np.linspace(0, 2.3e-3, yres)

    NSA_weighted = np.zeros((yres, xres, 3), dtype=np.float32)

    for t1Idx, t1 in enumerate(ts):
        for fIdx, f in enumerate(fs):
            NSA_weighted[t1Idx, fIdx, :] = np.reciprocal(
                weightedCrbTwoEchoes(3, [0, t1], weightsFromFraction(f)))
    mapper1 = LinearColorMapper(palette='Spectral10', low=0, high=1)

    CDSimages = [
        ColumnDataSource({'imageData': [NSA_weighted[:, :, 0]]}),
        ColumnDataSource({'imageData': [NSA_weighted[:, :, 1]]}),
        ColumnDataSource({'imageData': [NSA_weighted[:, :, 2]]})
    ]

    p1 = figure(width=400,
                height=350,
                tools='hover',
                toolbar_location=None,
                title='NSA Water, 0% FF, weighted')
    p1.image(image='imageData',
             x=0,
             y=0,
             dw=xres,
             dh=yres,
             color_mapper=mapper1,
             source=CDSimages[2])
    colorBar = ColorBar(color_mapper=mapper1, location=(0, 0))
    p1.add_layout(colorBar, 'right')
    p1.x_range.range_padding = p1.y_range.range_padding = 0
    if args.svg is True:
        from bokeh.io import export_svgs
        p1.output_backend = 'svg'
        export_svgs(p1, filename=args.filename + '.svg')
    else:
        show(p1)
Esempio n. 2
0
import numpy as np
from supportFunctions import weightsFromFraction
from bokeh.plotting import figure, output_file, save

fs = np.linspace(0,1,100)
weights = np.zeros((100,2))
for fidx, f in enumerate(fs):
    weights[fidx,:] = np.array(weightsFromFraction(f))
print(weights)

p1 = figure(width=350, height=200, toolbar_location=None)
p1.line(fs, weights[:,0],line_color='navy')
p1.line(fs, weights[:,1],line_color='chocolate')
p1.xaxis.axis_label = 'f'
p1.yaxis.axis_label = 'weight'
output_file('weights.html')
save(p1, filename='weights.html', title='')
Esempio n. 3
0
def plot(numFrac, numPF, args):
    B0 = 3  # Tesla
    mapper = LinearColorMapper(palette='Spectral10', low=0, high=1)
    colorBar = ColorBar(color_mapper=mapper, location=(0, 0))
    acquistionTimes = np.arange(start=float(args.tmin),
                                stop=float(args.tmax),
                                step=float(args.dt))
    numTa = len(acquistionTimes)
    partialFourierFactors = np.linspace(start=0.5, stop=1, num=numPF)
    dephasingTimes = np.empty(shape=(numPF, numFrac, numTa, 2),
                              dtype=np.float32)
    firstEchoFractions = np.linspace(start=0, stop=1, num=numFrac)
    NSA = np.empty(shape=(numPF, numFrac, numTa, 2),
                   dtype=np.float32)  # NSA_ss [weighted, unweighted]

    for nt, ta in enumerate(acquistionTimes):
        for nPF, PF in enumerate(partialFourierFactors):
            for nf, f in enumerate(firstEchoFractions):
                dephasingTimes[nPF, nf,
                               nt, :] = getDephasingTimes(ta / 1.0e3, PF, f)
                weights = weightsFromFraction(f)
                NSA[nPF, nf, nt, 0] = np.reciprocal(
                    weightedCrbTwoEchoes(B0, dephasingTimes[nPF, nf, nt, :],
                                         weights)[2])  # Weighted NSA_ss
                NSA[nPF, nf, nt, 1] = np.reciprocal(
                    weightedCrbTwoEchoes(
                        B0, dephasingTimes[nPF, nf, nt, :],
                        weightsFromFraction(.5))[2])  # Unweighted NSA_ss
        print(100. * (nt + 1) / numTa)

    pWeighted = figure(height=350,
                       width=350,
                       toolbar_location=None,
                       title='Weighted NSA_ss (3T)')
    pUnWeighted = figure(height=350,
                         width=350,
                         toolbar_location=None,
                         title='Unweighted NSA_ss (3T)')
    pUnWeighted.add_layout(colorBar, 'right')
    CDSimages = [
        ColumnDataSource({'imageData': [NSA[:, :, -1, 0]]}),
        ColumnDataSource({'imageData': [NSA[:, :, -1, 1]]})
    ]
    pWeighted.image(image='imageData',
                    x=0,
                    y=0,
                    dw=numFrac,
                    dh=numPF,
                    color_mapper=mapper,
                    source=CDSimages[0])
    pUnWeighted.image(image='imageData',
                      x=0,
                      y=0,
                      dw=numFrac,
                      dh=numPF,
                      color_mapper=mapper,
                      source=CDSimages[1])

    for p in [pWeighted, pUnWeighted]:
        p.xaxis.ticker = [
            0, (numFrac - 1) / 4, (numFrac - 1) / 2, 3 * (numFrac - 1) / 4,
            numFrac - 1
        ]
        p.xaxis.major_label_overrides = {
            0: '0',
            (numFrac - 1) / 4: '.25',
            (numFrac - 1) / 2: '.5',
            3 * (numFrac - 1) / 4: '.75',
            numFrac - 1: '1'
        }
        p.yaxis.ticker = [0, (numPF - 1) / 2, numPF - 1]
        p.yaxis.major_label_overrides = {
            0: '0.5',
            (numPF - 1) / 2: '.75',
            numPF - 1: '1.0'
        }

    pWeighted.x_range.range_padding = pWeighted.y_range.range_padding = 0
    pUnWeighted.x_range.range_padding = pUnWeighted.y_range.range_padding = 0
    spans = [
        Span(location=-1,
             dimension='height',
             line_color='navy',
             line_dash='dashed'),
        Span(location=-1,
             dimension='height',
             line_color='chocolate',
             line_dash='dashed')
    ]
    pGrad = figure(height=350,
                   width=350,
                   toolbar_location=None,
                   title='Gradients')
    pGrad.add_layout(spans[0])
    pGrad.add_layout(spans[1])
    CDSFirst = ColumnDataSource({'t': [0, 0, .5, .5], 'amp': [0, 1, 1, 0]})
    CDSSecond = ColumnDataSource({'t': [.5, .5, 1, 1], 'amp': [0, -1, -1, 0]})
    pGrad.line(x='t', y='amp', color='navy', line_width=2, source=CDSFirst)
    pGrad.line(x='t',
               y='amp',
               color='chocolate',
               line_width=2,
               source=CDSSecond)

    pCompass = figure(height=350,
                      width=350,
                      toolbar_location=None,
                      title='Fat vectors',
                      x_range=(-1.1, 1.1),
                      y_range=(-1.1, 1.1))
    pCompass.circle(0, 0, radius=1, fill_color=None, line_color='black')
    CDSArrow = [
        ColumnDataSource({
            'x': [0, 0],
            'y': [0, 0]
        }),
        ColumnDataSource({
            'x': [0, 0],
            'y': [0, 0]
        })
    ]
    pCompass.line(x='x', y='y', color='navy', line_width=2, source=CDSArrow[0])
    pCompass.line(x='x',
                  y='y',
                  color='chocolate',
                  line_width=2,
                  source=CDSArrow[1])

    slider = Slider(start=np.min(acquistionTimes),
                    end=np.max(acquistionTimes),
                    value=np.max(acquistionTimes),
                    step=acquistionTimes[1] - acquistionTimes[0],
                    title="Available acquisition time [ms]")

    hoverCallback = CustomJS(args={
        'dephasingTimes': dephasingTimes,
        'firstEchoFractions': firstEchoFractions,
        'partialFourierFactors': partialFourierFactors,
        'spans': spans,
        'arrows': CDSArrow,
        'first': CDSFirst,
        'slider': slider,
        'second': CDSSecond
    },
                             code="""
                            if ( isFinite(cb_data['geometry']['x']) && isFinite(cb_data['geometry']['y']) ) {
                                let ta = slider.value / 1000.0
                                if (typeof window.taIdx == 'undefined') {
                                    window.taIdx = dephasingTimes[0][0].length - 1;
                                }
                                let fIdx = Math.floor(cb_data["geometry"]['x']) % firstEchoFractions.length;
                                let pfIdx = Math.floor(cb_data["geometry"]['y']);
                                first.data.t[2] = first.data.t[3] = ta*firstEchoFractions[fIdx];
                                second.data.t[0] = second.data.t[1] = ta*firstEchoFractions[fIdx];
                                second.data.t[2] = second.data.t[3] = ta;
                                first.data.amp[1] = first.data.amp[2] = partialFourierFactors[pfIdx] / firstEchoFractions[fIdx];
                                second.data.amp[1] = second.data.amp[2] = - partialFourierFactors[pfIdx] / (1 - firstEchoFractions[fIdx]);
                                spans[0].location = ta/2.0 + dephasingTimes[pfIdx][fIdx][window.taIdx][0];
                                spans[1].location = ta/2.0 + dephasingTimes[pfIdx][fIdx][window.taIdx][1];
                                
                                spans[0].change.emit();
                                spans[1].change.emit();
                                first.change.emit();
                                second.change.emit();
                                let omega = 2*Math.PI*42.58*3*3.4
                                
                                for (let i = 0; i < 2; i++) {
                                    arrows[i].data.x[1] = Math.cos(omega*dephasingTimes[pfIdx][fIdx][window.taIdx][i]);
                                    arrows[i].data.y[1] = Math.sin(omega*dephasingTimes[pfIdx][fIdx][window.taIdx][i]);
                                    arrows[i].change.emit();
                                }
                                
                                window.fIdx = fIdx;
                                window.pfIdx = pfIdx;
                            }
                            """)
    pWeighted.add_tools(
        HoverTool(tooltips=[('index', '$index'), ('x', '$x'), ('y', '$y')],
                  callback=hoverCallback,
                  mode='mouse'))
    pUnWeighted.add_tools(
        HoverTool(tooltips=[('index', '$index'), ('x', '$x'), ('y', '$y')],
                  callback=hoverCallback,
                  mode='mouse'))
    sliderCallback = CustomJS(args={
        'acquistionTimes': acquistionTimes,
        'images': CDSimages,
        'NSA': NSA
    },
                              code="""
        window.taIdx = Math.floor((cb_obj.value - cb_obj.start ) / cb_obj.step)
        console.log(window.taIdx)
        images[0].data.imageData = [NSA.map(PF => PF.map(f => f[window.taIdx][0])).flat()]
        images[1].data.imageData = [NSA.map(PF => PF.map(f => f[window.taIdx][1])).flat()]
        images[0].change.emit();
        images[1].change.emit();
        """)
    slider.js_on_change('value', sliderCallback)
    if args.svg is True:
        from bokeh.io import export_svgs
        fname = 'pweighted.svg'
        print('Saving ' + fname)
        pWeighted.output_backend = "svg"
        export_svgs(pWeighted, filename=fname)
        print('Done')
    else:
        output_file(args.filename)
        combinedPlot = column(row(pWeighted, pUnWeighted),
                              row(pGrad, pCompass), slider)
        save(combinedPlot, filename=args.filename, title=args.title)
B0 = 3
nFFs = 6
FFs = np.linspace(start=0, stop=1, num=nFFs, endpoint=True)

NSA_equalWeights = np.zeros((nt, nt, len(FFs), 2), dtype=np.float32)
NSA_weighted = np.zeros((nt, nFrac, len(FFs), 2), dtype=np.float32)

pbar1 = tqdm(total=nt, position=0, desc='Current fat fraction')
pbar2 = tqdm(total=nFFs, position=1, desc='Overall progress')
for FFidx, fatFraction in enumerate(FFs):
    pbar1.reset()
    for tIdx, t1 in enumerate(np.linspace(0, 2.3e-3, nt)):
        for t2Idx, t2 in enumerate(np.linspace(0, 2.3e-3, nt)):
            NSA_equalWeights[tIdx, t2Idx, FFidx, :] = fwNoiseSim(
                nSamples, [t1, t2], [1 - fatFraction, fatFraction],
                weightsFromFraction(.5), B0)
        for fIdx, f in enumerate(np.linspace(0, 1, nFrac)):
            pass  #NSA_weighted[tIdx, fIdx, FFidx, :] = fwNoiseSim(nSamples, [0., t1], [1-fatFraction, fatFraction], weightsFromFraction(f), B0)
        pbar1.update(1)
    pbar2.update(1)

CDSimages = {
    'weighted': [
        ColumnDataSource({'imageData': [NSA_weighted[:, :, 0, 0]]}),
        ColumnDataSource({'imageData': [NSA_weighted[:, :, 0, 1]]})
    ],
    'unweighted': [
        ColumnDataSource({'imageData': [NSA_equalWeights[:, :, 0, 0]]}),
        ColumnDataSource({'imageData': [NSA_equalWeights[:, :, 0, 1]]})
    ]
}