コード例 #1
0
    def make_se_epi(self):
        kwargs_for_opts = {"max_grad": self.max_grad, "grad_unit": "mT/m", "max_slew": self.max_slew,
                           "slew_unit": "T/m/s", "rf_dead_time": 10e-6, "adc_dead_time": 10e-6}
        system = Opts(kwargs_for_opts)
        seq = Sequence(system)

        slice_thickness = 3e-3

        flip = 90 * pi / 180
        kwargs_for_sinc = {"flip_angle": flip, "system": system, "duration": 3e-3, "slice_thickness": slice_thickness,
                           "apodization": 0.5, "time_bw_product": 4}
        rf, gz = makesincpulse(kwargs_for_sinc, 2)
        # plt.plot(rf.t[0], rf.signal[0])
        # plt.show()

        delta_k = 1 / self.fov
        k_width = self.Nx * delta_k
        readout_time = 3.2e-4
        kwargs_for_gx = {"channel": 'x', "system": system, "flat_area": k_width, "flat_time": readout_time}
        gx = maketrapezoid(kwargs_for_gx)
        kwargs_for_adc = {"num_samples": self.Nx, "system": system, "duration": gx.flat_time, "delay": gx.rise_time}
        adc = makeadc(kwargs_for_adc)

        pre_time = 8e-4
        kwargs_for_gxpre = {"channel": 'x', "system": system, "area": -gx.area / 2, "duration": pre_time}
        gx_pre = maketrapezoid(kwargs_for_gxpre)
        kwargs_for_gz_reph = {"channel": 'z', "system": system, "area": -gz.area / 2, "duration": pre_time}
        gz_reph = maketrapezoid(kwargs_for_gz_reph)
        kwargs_for_gy_pre = {"channel": 'y', "system": system, "area": -self.Ny / 2 * delta_k, "duration": pre_time}
        gy_pre = maketrapezoid(kwargs_for_gy_pre)

        dur = ceil(2 * sqrt(delta_k / system.max_slew) / 10e-6) * 10e-6
        kwargs_for_gy = {"channel": 'y', "system": system, "area": delta_k, "duration": dur}
        gy = maketrapezoid(kwargs_for_gy)

        flip = 180 * pi / 180
        kwargs_for_sinc = {"flip_angle": flip, "system": system, "duration": 500e-6}
        rf180 = makeblockpulse(kwargs_for_sinc)
        kwargs_for_gz_spoil = {"channel": 'z', "system": system, "area": gz.area * 2, "duration": 3 * pre_time}
        gz_spoil = maketrapezoid(kwargs_for_gz_spoil)

        TE = self.te
        duration_to_center = (self.Nx / 2 + 0.5) * calcduration(gx) + self.Ny / 2 * calcduration(gy)
        delayTE1 = TE / 2 - calcduration(gz) / 2 - pre_time - calcduration(gz_spoil) - calcduration(rf180) / 2
        delayTE2 = TE / 2 - calcduration(rf180) / 2 - calcduration(gz_spoil) - duration_to_center
        delay1 = makedelay(delayTE1)
        delay2 = makedelay(delayTE2)

        seq.add_block(rf, gz)
        seq.add_block(gx_pre, gy_pre, gz_reph)
        seq.add_block(delay1)
        seq.add_block(gz_spoil)
        seq.add_block(rf180)
        seq.add_block(gz_spoil)
        seq.add_block(delay2)
        for i in range(self.Ny):
            seq.add_block(gx, adc)
            seq.add_block(gy)
            gx.amplitude = -gx.amplitude
        seq.add_block(makedelay(1))

        return seq
コード例 #2
0
    "time_bw_product": 4
}
rf, gz = makesincpulse(kwargs_for_sinc, 2)
# plt.plot(rf.t[0], rf.signal[0])
# plt.show()

delta_k = 1 / fov
kWidth = Nx * delta_k
readoutTime = Nx * dt_GE
kwargs_for_gx = {
    "channel": 'x',
    "system": system,
    "flat_area": kWidth,
    "flat_time": readoutTime
}
gx = maketrapezoid(kwargs_for_gx)
kwargs_for_adc = {
    "num_samples": Nx,
    "system": system,
    "duration": gx.flat_time,
    "delay": gx.rise_time
}
adc = makeadc(kwargs_for_adc)

pre_time = 8e-4
kwargs_for_gxpre = {
    "channel": 'x',
    "system": system,
    "area": -gx.area / 2 - delta_k / 2,
    "duration": pre_time
}
コード例 #3
0
Ny = 256
slice_thickness = 3e-3
dt_GE = 4e-6

flip = 90 * pi / 180
kwargs_for_sinc = {"flip_angle": flip, "system": system, "duration": 2.5e-3, "slice_thickness": slice_thickness,
                   "apodization": 0.5, "time_bw_product": 4}
rf, gz = makesincpulse(kwargs_for_sinc, 2)
# plt.plot(rf.t[0], rf.signal[0])
# plt.show()

delta_k = 1 / fov
kWidth = Nx * delta_k
readoutTime = Nx * dt_GE
kwargs_for_gx = {"channel": 'x', "system": system, "flat_area": kWidth, "flat_time": readoutTime}
gx = maketrapezoid(kwargs_for_gx)
kwargs_for_adc = {"num_samples": Nx, "system": system, "duration": gx.flat_time, "delay": gx.rise_time}
adc = makeadc(kwargs_for_adc)

kwargs_for_gxpre = {"channel": 'x', "system": system, "area": -gx.area / 2, "duration": 2.5e-3}
gx_pre = maketrapezoid(kwargs_for_gxpre)
kwargs_for_gz_reph = {"channel": 'z', "system": system, "area": -gz.area / 2, "duration": 2.5e-3}
gz_reph = maketrapezoid(kwargs_for_gz_reph)

flip = 180 * pi / 180
kwargs_for_sinc = {"flip_angle": flip, "system": system, "duration": 2.5e-3, "slice_thickness": slice_thickness,
                   "apodization": 0.5, "time_bw_product": 4}
rf180, gz180 = makesincpulse(kwargs_for_sinc, 2)


delayTE1 = TE / 2 - calcduration(gz_reph) - calcduration(rf) - calcduration(rf180) / 2
コード例 #4
0
ファイル: makeblock.py プロジェクト: Vajuvalli/IMRI-MIRC
def makeblockpulse(kwargs, nargout=1):
    """
    Makes a Holder object for an RF pulse Event.

    Parameters
    ----------
    kwargs : dict
        Key value mappings of RF Event parameters_params and values.
    nargout: int
        Number of output arguments to be returned. Default is 1, only RF Event is returned. Passing any number greater
        than 1 will return the Gz Event along with the RF Event.

    Returns
    -------
    Tuple consisting of:
    rf : Holder
        RF Event configured based on supplied kwargs.
    gz : Holder
        Slice select trapezoidal gradient Event.
    """

    flip_angle = kwargs.get("flip_angle")
    system = kwargs.get("system", Opts())
    duration = kwargs.get("duration", 0)
    freq_offset = kwargs.get("freq_offset", 0)
    phase_offset = kwargs.get("phase_offset", 0)
    time_bw_product = kwargs.get("time_bw_product", 4)
    bandwidth = kwargs.get("bandwidth", 0)
    max_grad = kwargs.get("max_grad", 0)
    max_slew = kwargs.get("max_slew", 0)
    slice_thickness = kwargs.get("slice_thickness", 0)

    if duration == 0:
        if time_bw_product > 0:
            duration = time_bw_product / bandwidth
        elif bandwidth > 0:
            duration = 1 / (4 * bandwidth)
        else:
            raise ValueError('Either bandwidth or duration must be defined')

    BW = 1 / (4 * duration)
    N = round(duration / 1e-6)
    t = [x * system.rf_raster_time for x in range(N)]
    signal = flip_angle / (2 * np.pi) / duration * np.ones(len(t))

    rf = Holder()
    rf.type = 'rf'
    rf.signal = signal
    rf.t = t
    rf.freq_offset = freq_offset
    rf.phase_offset = phase_offset
    rf.dead_time = system.rf_dead_time

    fill_time = 0
    if nargout > 1:
        if slice_thickness < 0:
            raise ValueError('Slice thickness must be provided')

        if max_grad > 0:
            system.max_grad = max_grad
        if max_slew > 0:
            system.max_slew = max_slew

        amplitude = BW / slice_thickness
        area = amplitude * duration
        kwargs_for_trap = {'channel': 'z', 'system': system, 'flat_time': duration, 'flat_area': area}
        gz = maketrapezoid(kwargs_for_trap)

        fill_time = gz.rise_time
        t_fill = np.array([x * 1e-6 for x in range(int(round(fill_time / 1e-6)))])
        rf.t = np.array([t_fill, rf.t + t_fill[-1], t_fill + rf.t[-1] + t_fill[-1]])
        rf.signal = np.array([np.zeros(t_fill.size), rf.signal, np.zeros(t_fill.size)])

    if fill_time < rf.dead_time:
        fill_time = rf.dead_time - fill_time
        t_fill = np.array([x * 1e-6 for x in range(int(round(fill_time / 1e-6)))])
        rf.t = np.insert(rf.t, 0, t_fill) + t_fill[-1]
        rf.t = np.reshape(rf.t, (1, len(rf.t)))
        rf.signal = np.insert(rf.signal, 0, np.zeros(t_fill.size))
        rf.signal = np.reshape(rf.signal, (1, len(rf.signal)))

    if nargout > 1:
        return rf, gz
    else:
        return rf
コード例 #5
0
def makearbitraryrf(kwargs, nargout=1):
    """
    Makes a Holder object for an arbitrary RF pulse Event.

    Parameters
    ----------
    kwargs : dict
        Key value mappings of RF Event parameters_params and values.
    nargout: int
        Number of output arguments to be returned. Default is 1, only RF Event is returned. Passing any number greater
        than 1 will return the Gz Event along with the RF Event.

    Returns
    -------
    rf : Holder
        RF Event configured based on supplied kwargs.
    gz : Holder
        Slice select trapezoidal gradient Event.
    """

    flip_angle = kwargs.get("flip_angle")
    system = kwargs.get("system", Opts())
    signal = kwargs.get("signal", 0)
    freq_offset = kwargs.get("freq_offset", 0)
    phase_offset = kwargs.get("phase_offset", 0)
    time_bw_product = kwargs.get("time_bw_product", 0)
    bandwidth = kwargs.get("bandwidth", 0)
    max_grad = kwargs.get("max_grad", 0)
    max_slew = kwargs.get("max_slew", 0)
    slice_thickness = kwargs.get("slice_thickness", 0)

    signal = signal / sum(
        signal * system.rf_raster_time) * flip_angle / (2 * pi)
    N = len(signal)
    duration = N * system.rf_raster_time
    t = [x * system.rfRasterTime for x in range(0, N)]

    rf = Holder()
    rf.type = 'rf'
    rf.signal = signal
    rf.t = t
    rf.freq_offset = freq_offset
    rf.phase_offset = phase_offset
    rf.rf_dead_time = system.rf_dead_time

    if nargout > 1:
        if slice_thickness <= 0:
            raise ValueError('Slice thickness must be provided')
        if bandwidth <= 0:
            raise ValueError('Bandwdith of pulse must be provided')

        system.maxgrad = max_grad if max_grad > 0 else system.maxgrad
        system.max_slew = max_slew if max_slew > 0 else system.max_slew

        BW = bandwidth
        if time_bw_product > 0:
            BW = time_bw_product / duration

        amplitude = BW / slice_thickness
        area = amplitude * duration
        kwargs_for_trap = {
            "channel": 'z',
            "system": system,
            "flat_time": duration,
            "flat_area": area
        }
        gz = maketrapezoid(**kwargs_for_trap)

        t_fill = [x * 1e-6 for x in range(1, round(gz.riseTime / 1e-6))]
        rf.t = [t_fill, rf.t + t_fill[-1], t_fill + rf.t[-1] + t_fill[-1]]
        rf.signal = [np.zeros(len(t_fill)), rf.signal, np.zeros(len(t_fill))]

    return rf, gz
コード例 #6
0
ファイル: makesinc.py プロジェクト: Vajuvalli/IMRI-MIRC
def makesincpulse(kwargs, nargout=1):
    """
    Makes a Holder object for an RF pulse Event.

    Parameters
    ----------
    kwargs : dict
        Key value mappings of RF Event parameters_params and values.
    nargout: int
        Number of output arguments to be returned. Default is 1, only RF Event is returned. Passing any number greater
        than 1 will return the Gz Event along with the RF Event.

    Returns
    -------
    Tuple consisting of:
    rf : Holder
        RF Event configured based on supplied kwargs.
    gz : Holder
        Slice select trapezoidal gradient Event.
    """

    flip_angle = kwargs.get("flip_angle")
    system = kwargs.get("system", Opts())
    duration = kwargs.get("duration", 0)
    freq_offset = kwargs.get("freq_offset", 0)
    phase_offset = kwargs.get("phase_offset", 0)
    time_bw_product = kwargs.get("time_bw_product", 4)
    apodization = kwargs.get("apodization", 0)
    max_grad = kwargs.get("max_grad", 0)
    max_slew = kwargs.get("max_slew", 0)
    slice_thickness = kwargs.get("slice_thickness", 0)

    BW = time_bw_product / duration
    alpha = apodization
    N = int(round(duration / 1e-6))
    t = np.zeros((1, N))
    for x in range(1, N + 1):
        t[0][x - 1] = x * system.rf_raster_time
    tt = t - (duration / 2)
    window = np.zeros((1, tt.shape[1]))
    for x in range(0, tt.shape[1]):
        window[0][x] = 1.0 - alpha + alpha * np.cos(
            2 * np.pi * tt[0][x] / duration)
    signal = np.multiply(window, np.sinc(BW * tt))
    flip = np.sum(signal) * system.rf_raster_time * 2 * np.pi
    signal = signal * flip_angle / flip

    rf = Holder()
    rf.type = 'rf'
    rf.signal = signal
    rf.t = t
    rf.freq_offset = freq_offset
    rf.phase_offset = phase_offset
    rf.dead_time = system.rf_dead_time

    fill_time = 0
    if nargout > 1:
        if slice_thickness == 0:
            raise ValueError('Slice thickness must be provided')

        system.max_grad = max_grad if max_grad > 0 else system.max_grad
        system.max_slew = max_slew if max_slew > 0 else system.max_slew

        amplitude = BW / slice_thickness
        area = amplitude * duration
        kwargs_for_trap = {
            "channel": 'z',
            "system": system,
            "flat_time": duration,
            "flat_area": area
        }
        gz = maketrapezoid(kwargs_for_trap)

        fill_time = gz.rise_time
        nfill_time = int(round(fill_time / 1e-6))
        t_fill = np.zeros((1, nfill_time))
        for x in range(1, nfill_time + 1):
            t_fill[0][x - 1] = x * 1e-6
        temp = np.concatenate((t_fill[0], rf.t[0] + t_fill[0][-1]))
        temp = temp.reshape((1, len(temp)))
        rf.t = np.resize(rf.t, temp.shape)
        rf.t[0] = temp
        z = np.zeros((1, t_fill.shape[1]))
        temp2 = np.concatenate((z[0], rf.signal[0]))
        temp2 = temp2.reshape((1, len(temp2)))
        rf.signal = np.resize(rf.signal, temp2.shape)
        rf.signal[0] = temp2

    if fill_time < rf.dead_time:
        fill_time = rf.dead_time - fill_time
        t_fill = np.array(
            [x * 1e-6 for x in range(int(round(fill_time / 1e-6)))])
        rf.t = np.insert(rf.t, 0, t_fill) + t_fill[-1]
        rf.t = np.reshape(rf.t, (1, len(rf.t)))
        rf.signal = np.insert(rf.signal, 0, (np.zeros(t_fill.size)))
        rf.signal = np.reshape(rf.signal, (1, len(rf.signal)))

    # Following 2 lines of code are workarounds for numpy returning 3.14... for np.angle(-0.00...)
    negative_zero_indices = np.where(rf.signal == -0.0)
    rf.signal[negative_zero_indices] = 0

    if nargout > 1:
        return rf, gz
    else:
        return rf
コード例 #7
0
ファイル: GenSeq_GPI.py プロジェクト: Vajuvalli/IMRI-MIRC
    def make_event_holders(self):
        """Make appropriate Holder objects depending on the Event type."""

        self.system = self.in_dict['system']
        # arbgrad_file_path is only for arbitrary gradients
        arbgrad_file_path = self.all_event_def[
            'file_path'] if 'file_path' in self.all_event_def else None
        self.all_event_holders = {}

        for event in self.all_event_def:
            event_unique_name = event['event_unique_name']
            event_name = event['event_name']
            event_values = list(event['event_values'].values())
            include_in_loop = event['include_in_loop']

            if event_name == 'Delay':
                params = self.parse_config_params(event_values)
                delay = makedelay(params[0])
                self.all_event_holders[
                    event_unique_name] = delay, include_in_loop
            elif event_name == 'SincRF':
                include_gz = event['include_gz']
                max_grad, max_slew, flip_angle, duration, freq_offset, phase_offset, time_bw_product, apodization, slice_thickness = self.parse_config_params(
                    event_values)
                flip_angle = math.radians(flip_angle)
                max_grad = convert.convert_from_to(max_grad, 'mT/m')
                max_slew = convert.convert_from_to(max_slew, 'mT/m/ms')
                max_grad = self.system.max_grad if max_grad == 0 else max_grad
                max_slew = self.system.max_slew if max_slew == 0 else max_slew
                kwargs_for_sinc = {
                    "flip_angle": flip_angle,
                    "system": self.system,
                    "duration": duration,
                    "freq_offset": freq_offset,
                    "phase_offset": phase_offset,
                    "time_bw_product": time_bw_product,
                    "apodization": apodization,
                    "max_grad": max_grad,
                    "max_slew": max_slew,
                    "slice_thickness": slice_thickness
                }
                if include_gz:
                    rf, gz = makesincpulse(kwargs_for_sinc, 2)
                    self.all_event_holders[
                        event_unique_name] = rf, include_in_loop
                    self.all_event_holders[
                        'gz_' + event_unique_name] = gz, include_in_loop
                else:
                    rf = makesincpulse(kwargs_for_sinc)
                    self.all_event_holders[
                        event_unique_name] = rf, include_in_loop
            elif event_name == 'BlockRF':
                include_gz = event['include_gz']
                max_grad, max_slew, flip_angle, duration, freq_offset, phase_offset, time_bw_product, bandwidth, slice_thickness = self.parse_config_params(
                    event_values)
                flip_angle = math.radians(flip_angle)
                max_grad = convert.convert_from_to(max_grad, 'mT/m')
                max_slew = convert.convert_from_to(max_slew, 'mT/m/ms')
                max_grad = self.system.max_grad if max_grad == 0 else max_grad
                max_slew = self.system.max_slew if max_slew == 0 else max_slew
                kwargs_for_block = {
                    "flip_angle": flip_angle,
                    "system": self.system,
                    "duration": duration,
                    "freq_offset": freq_offset,
                    "phase_offset": phase_offset,
                    "time_bw_product": time_bw_product,
                    "bandwidth": bandwidth,
                    "max_grad": max_grad,
                    "max_slew": max_slew,
                    "slice_thickness": slice_thickness
                }
                if include_gz:
                    rf, gz = makeblockpulse(kwargs_for_block, 2)
                    self.all_event_holders[
                        event_unique_name] = rf, include_in_loop
                    self.all_event_holders[
                        'gz_' + event_unique_name] = gz, include_in_loop
                else:
                    rf = makeblockpulse(kwargs_for_block)
                    self.all_event_holders[
                        event_unique_name] = rf, include_in_loop
            elif event_name == 'G':
                channel = event_values.pop(0)
                max_grad, max_slew, duration, area, flat_time, flat_area, amplitude, rise_time = self.parse_config_params(
                    event_values)

                # area, flat_area and amplitude should be reset to -1 if user does not input any values. This is
                # because the default values are -1 in maketrap method.
                area = area if area != 0 else -1
                flat_area = flat_area if flat_area != 0 else -1
                amplitude = amplitude if amplitude != 0 else -1

                max_grad = convert.convert_from_to(max_grad, 'mT/m')
                max_slew = convert.convert_from_to(max_slew, 'mT/m/ms')
                max_grad = self.system.max_grad if max_grad == 0 else max_grad
                max_slew = self.system.max_slew if max_slew == 0 else max_slew
                kwargs_for_trap = {
                    "channel": channel,
                    "system": self.system,
                    "duration": duration,
                    "area": area,
                    "flat_time": flat_time,
                    "flat_area": flat_area,
                    "amplitude": amplitude,
                    "max_grad": max_grad,
                    "max_slew": max_slew,
                    "rise_time": rise_time
                }
                trap = maketrapezoid(kwargs_for_trap)
                self.all_event_holders[
                    event_unique_name] = trap, include_in_loop
            elif event_name == 'GyPre':
                duration, area = self.parse_config_params(event_values)
                Ny = self.system.Ny
                delta_k = 1 / self.system.fov
                gy_pre_list = []

                for i in range(int(Ny)):
                    kwargs_for_gy_pre = {
                        "channel": 'y',
                        "system": self.system,
                        "area": (i - Ny / 2) * delta_k,
                        "duration": duration
                    }
                    if area != 0:
                        kwargs_for_gy_pre['area'] = area
                    gy_pre = maketrapezoid(kwargs_for_gy_pre)
                    gy_pre_list.append(gy_pre)

                self.all_event_holders[event_unique_name] = gy_pre_list, True
            elif event_name == 'ArbGrad':
                channel = event_values.pop(0)
                max_grad, max_slew = self.parse_config_params(event_values)
                file = h5py.File(gpi.TranslateFileURI(arbgrad_file_path), "r")
                self.dataset = str()

                def append_if_dataset(name, obj):
                    if isinstance(obj, h5py.Dataset):
                        self.dataset = name
                        return True

                file.visititems(append_if_dataset)

                waveform = file[self.dataset].value
                kwargs_for_arb_grad = {
                    "channel": channel,
                    "waveform": waveform,
                    "max_grad": max_grad,
                    "max_slew": max_slew,
                    "system": self.system
                }
                arb_grad = makearbitrarygrad(kwargs_for_arb_grad)
                self.all_event_holders[
                    event_unique_name] = arb_grad, include_in_loop
            elif event_name == 'ADC':
                num_samples, dwell, duration, delay, freq_offset, phase_offset = self.parse_config_params(
                    event_values)
                kwargs_for_adc = {
                    "num_samples": num_samples,
                    "system": self.system,
                    "dwell": dwell,
                    "duration": duration,
                    "delay": delay,
                    "freq_offset": freq_offset,
                    "phase_offset": phase_offset
                }
                adc = makeadc(kwargs_for_adc)
                self.all_event_holders[
                    event_unique_name] = adc, include_in_loop