Ejemplo n.º 1
0
    def test_phantom_cylinder(self):
        # Compare to pre-made phantom (check size and values)
        phantom = pht.makeCylindricalPhantom()

        test_data_path = constants.SERVER_SIM_BLOCH_PATH / 'test_data' / 'test_cylindrical_phantom_maps.npy'
        maps = np.load(test_data_path)


        self.assertIsInstance(phantom, pht.DTTPhantom)
        np.testing.assert_allclose(phantom.PDmap, maps[:,:,:,0])
        np.testing.assert_allclose(phantom.T1map, maps[:,:,:,1])
        np.testing.assert_allclose(phantom.T2map, maps[:,:,:,2])
Ejemplo n.º 2
0
def sim_sequence(seq):
    nn = 15
    phantom = pht.makeCylindricalPhantom(dim=2, dir='z', loc=0, n=nn)
    # Time the code: Tic
    start_time = time.time()
    # Store seq info
    seq_info = blcsim.store_pulseq_commands(seq)
    # Get list of locations from phantom
    loc_ind_list = phantom.get_list_inds()
    # Initiate multiprocessing pool
    pool = mp.Pool(mp.cpu_count())
    # Parallel simulation
    df = 0
    results = pool.starmap_async(blcsim.sim_single_spingroup,
                                 [(loc_ind, df, phantom, seq_info)
                                  for loc_ind in loc_ind_list]).get()
    pool.close()
    # Add up signal across all SpinGroups
    signal = np.sum(results, axis=0)

    # Time the code: Toc
    print("Time used: %s seconds" % (time.time() - start_time))

    return signal
Ejemplo n.º 3
0
import time

import matplotlib as mpl

mpl.use('TkAgg')
import matplotlib.pyplot as plt
import numpy as np

import virtualscanner.server.simulation.bloch.phantom as pht
import virtualscanner.server.simulation.bloch.pulseq_blochsim_methods as blcsim
import virtualscanner.server.simulation.bloch.pulseq_library as psl

if __name__ == '__main__':
    # Make a phantom
    nn = 49
    myphantom = pht.makeCylindricalPhantom(dim=2, dir='z', loc=0, n=nn)
    df = 0

    # Define sequence parameters
    # FOV = [0.24,0.24]
    FOV = 0.24
    # N = [21,21]
    N = 49
    FA = 90
    TR = 2
    TE = 0.5
    slice_locs = [0]
    thk = 0.24 / 49

    # Defining oblique encoding directions
    # Mrot = np.array([[1,            0,            0],
            loc_vec_dict = {'x': (1, 0, 0), 'y': (0, 1, 0), 'z': (0, 0, 1)}
            myphantom = pht.makePlanarPhantom(
                n=args.n_ph,
                fov=args.fov_ph,
                T1s=args.T1s,
                T2s=args.T2s,
                PDs=args.PDs,
                radii=Rs,
                dir=args.dir_ph,
                loc=0)  # now, 2D phantom is not moved around
            # args.slice_loc*np.array(loc_vec_dict[args.enc[2]]))

    elif args.pht_type == 'cylindrical':
        print("Making cylindrical phantom")
        myphantom = pht.makeCylindricalPhantom(dim=args.pht_dim,
                                               n=args.n_ph,
                                               dir=args.dir_ph,
                                               loc=0)

    elif args.pht_type == 'NIST':
        myphantom = []
        # myphantom = pht.get_NIST_Phantom()

    else:
        raise ValueError("Phantom type non-existent!")

    # Slice locations
    Ns = args.num_slices
    g = args.slice_gap
    t = args.thk
    slice_locs = np.arange(-(Ns - 1) * (g + t) / 2, Ns * (g + t) / 2, g + t)
    print('Slice locations:', slice_locs)
Ejemplo n.º 5
0
def create_and_save_phantom(phantom_info, out_folder):
    """Generates a phantom and saves it into desired folder as .h5 file for JEMRIS purposes

    Inputs
    ------
    phantom_info : dict
        Info of phantom to be constructed

        REQUIRED
        'fov' : float, field-of-view [meters]
        'N' : int, phantom matrix size (isotropic)
        'type' : str, 'spherical', 'cylindrical' or 'custom'
        'dim' : int, either 3 or 2; 3D or 2D phantom options
        'dir' : str, {'x', 'y', 'z'}; orientation of 2D phantom

        OPTIONAL (only required for 'custom' phantom type)
        'T1' : np.ndarray, T1 map matrix
        'T2' : np.ndarray, T2 map matrix
        'PD' : np.ndarray, PD map matrix
        'dr' : float, voxel size [meters] (isotropic)
        'dBmap' : optional even for 'custom' type. If not provided, dB is set to 0 everywhere.


    out_folder : str or pathlib Path object
        Path to directory where phantom will be saved

    Returns
    -------
    pht_type : str
        phantom_info['pht_type'] (returned for naming purposes)


    """
    out_folder = str(out_folder)

    FOV = phantom_info['fov']
    N = phantom_info['N']
    pht_type = phantom_info['type']
    pht_dim = phantom_info['dim']
    pht_dir = phantom_info['dir']

    sim_phantom = 0

    if pht_type == 'spherical':
        print('Making spherical phantom')
        T1s = [1000]
        T2s = [100]
        PDs = [1]
        R = 0.8 * FOV / 2
        Rs = [R]
        if pht_dim == 3:
            sim_phantom = pht.makeSphericalPhantom(n=N,
                                                   fov=FOV,
                                                   T1s=T1s,
                                                   T2s=T2s,
                                                   PDs=PDs,
                                                   radii=Rs)

        elif pht_dim == 2:
            sim_phantom = pht.makePlanarPhantom(n=N,
                                                fov=FOV,
                                                T1s=T1s,
                                                T2s=T2s,
                                                PDs=PDs,
                                                radii=Rs,
                                                dir=pht_dir,
                                                loc=0)
    elif pht_type == 'cylindrical':
        print("Making cylindrical phantom")
        sim_phantom = pht.makeCylindricalPhantom(dim=pht_dim,
                                                 n=N,
                                                 dir=pht_dir,
                                                 loc=0)

    elif pht_type == 'custom':
        # Use a custom file!
        T1 = phantom_info['T1']
        T2 = phantom_info['T2']
        PD = phantom_info['PD']
        dr = phantom_info['dr']
        if 'dBmap' in phantom_info.keys():
            dBmap = phantom_info['dBmap']
        else:
            dBmap = 0

        sim_phantom = pht.Phantom(T1map=T1,
                                  T2map=T2,
                                  PDmap=PD,
                                  vsize=dr,
                                  dBmap=dBmap,
                                  loc=(0, 0, 0))

    else:
        raise ValueError("Phantom type non-existent!")

    # Save as h5
    sim_phantom.output_h5(out_folder, pht_type)

    return pht_type
Ejemplo n.º 6
0
import virtualscanner.server.simulation.bloch.phantom as pht
from pypulseq.Sequence.sequence import Sequence
import time
import multiprocessing as mp
import virtualscanner.server.simulation.bloch.pulseq_blochsim_methods as blcsim

if __name__ == '__main__':
    # Make phantom

    dfmap = np.zeros((32, 32, 1))
    txmap = np.ones((32, 32, 1))
    rxmap = np.ones((32, 32, 1))

    myphantom = pht.makeCylindricalPhantom(dim=2,
                                           n=32,
                                           dir='z',
                                           loc=0,
                                           fov=0.25)

    # Load the sequence : choose your own
    myseq = Sequence()
    myseq.read(
        'sim/amri_debug/b0demo/tse_ms_FOV250mm_N32_Ns1_TR2000ms_TE12ms_4echoes_dwell200.0us.seq'
    )

    # Time the code: Tic
    start_time = time.time()
    # Store seq info
    seq_info = blcsim.store_pulseq_commands(myseq)
    # Get list of locations from phantom
    loc_ind_list = myphantom.get_list_inds()