Example #1
0
def test_calc_noise():

    # Inputs for functions
    onsets = [10, 30, 50, 70, 90]
    event_durations = [6]
    tr_duration = 2
    duration = 200
    tr_number = int(np.floor(duration / tr_duration))
    dimensions_tr = np.array([10, 10, 10, tr_number])

    # Preset the noise dict
    nd_orig = {
        'auto_reg_sigma': 0.6,
        'drift_sigma': 0.4,
        'snr': 30,
        'sfnr': 30,
        'max_activity': 1000,
        'fwhm': 4,
    }

    # Create the time course for the signal to be generated
    stimfunction = sim.generate_stimfunction(
        onsets=onsets,
        event_durations=event_durations,
        total_time=duration,
    )

    # Mask the volume to be the same shape as a brain
    mask, template = sim.mask_brain(dimensions_tr, mask_threshold=0.2)
    stimfunction_tr = stimfunction[::int(tr_duration * 100)]
    noise = sim.generate_noise(
        dimensions=dimensions_tr[0:3],
        stimfunction_tr=stimfunction_tr,
        tr_duration=tr_duration,
        template=template,
        mask=mask,
        noise_dict=nd_orig,
    )

    # Check that noise_system is being calculated correctly
    spatial_sd = 5
    temporal_sd = 5
    noise_system = sim._generate_noise_system(dimensions_tr, spatial_sd,
                                              temporal_sd)

    precision = abs(noise_system[0, 0, 0, :].std() - spatial_sd)
    assert precision < spatial_sd, 'noise_system calculated incorrectly'

    precision = abs(noise_system[:, :, :, 0].std() - temporal_sd)
    assert precision < spatial_sd, 'noise_system calculated incorrectly'

    # Calculate the noise
    nd_calc = sim.calc_noise(volume=noise, mask=mask)

    # How precise are these estimates
    precision = abs(nd_calc['snr'] - nd_orig['snr'])
    assert precision < nd_orig['snr'], 'snr calculated incorrectly'

    precision = abs(nd_calc['sfnr'] - nd_orig['sfnr'])
    assert precision < nd_orig['sfnr'], 'sfnr calculated incorrectly'
Example #2
0
def test_calc_noise():

    # Inputs for functions
    onsets = [10, 30, 50, 70, 90]
    event_durations = [6]
    tr_duration = 2
    duration = 200
    tr_number = int(np.floor(duration / tr_duration))
    dimensions_tr = np.array([10, 10, 10, tr_number])

    # Preset the noise dict
    nd_orig = {'auto_reg_sigma': 0.6,
               'drift_sigma': 0.4,
               'snr': 30,
               'sfnr': 30,
               'max_activity': 1000,
               'fwhm': 4,
               }

    # Create the time course for the signal to be generated
    stimfunction = sim.generate_stimfunction(onsets=onsets,
                                             event_durations=event_durations,
                                             total_time=duration,
                                             )

    # Mask the volume to be the same shape as a brain
    mask, template = sim.mask_brain(dimensions_tr, mask_threshold=0.2)
    stimfunction_tr = stimfunction[::int(tr_duration * 100)]
    noise = sim.generate_noise(dimensions=dimensions_tr[0:3],
                               stimfunction_tr=stimfunction_tr,
                               tr_duration=tr_duration,
                               template=template,
                               mask=mask,
                               noise_dict=nd_orig,
                               )

    # Check that noise_system is being calculated correctly
    spatial_sd = 5
    temporal_sd = 5
    noise_system = sim._generate_noise_system(dimensions_tr,
                                              spatial_sd,
                                              temporal_sd)

    precision = abs(noise_system[0, 0, 0, :].std() - spatial_sd)
    assert precision < spatial_sd, 'noise_system calculated incorrectly'

    precision = abs(noise_system[:, :, :, 0].std() - temporal_sd)
    assert precision < spatial_sd, 'noise_system calculated incorrectly'

    # Calculate the noise
    nd_calc = sim.calc_noise(volume=noise,
                             mask=mask)

    # How precise are these estimates
    precision = abs(nd_calc['snr'] - nd_orig['snr'])
    assert precision < nd_orig['snr'], 'snr calculated incorrectly'

    precision = abs(nd_calc['sfnr'] - nd_orig['sfnr'])
    assert precision < nd_orig['sfnr'], 'sfnr calculated incorrectly'
Example #3
0
def test_generate_stimfunction():

    # Inputs for generate_stimfunction
    onsets = [10, 30, 50, 70, 90]
    event_durations = [6]
    tr_duration = 2
    duration = 100

    # Create the time course for the signal to be generated
    stimfunction = sim.generate_stimfunction(
        onsets=onsets,
        event_durations=event_durations,
        total_time=duration,
    )

    assert stimfunction.shape[0] == duration * 100, "stimfunc incorrect length"
    eventNumber = np.sum(event_durations * len(onsets)) * 100
    assert np.sum(stimfunction) == eventNumber, "Event number"

    # Create the signal function
    signal_function = sim.convolve_hrf(
        stimfunction=stimfunction,
        tr_duration=tr_duration,
    )

    stim_dur = stimfunction.shape[0] / (tr_duration * 100)
    assert signal_function.shape[0] == stim_dur, "The length did not change"

    # Test
    onsets = [0]
    tr_duration = 1
    event_durations = [1]
    stimfunction = sim.generate_stimfunction(
        onsets=onsets,
        event_durations=event_durations,
        total_time=duration,
    )

    signal_function = sim.convolve_hrf(
        stimfunction=stimfunction,
        tr_duration=tr_duration,
    )

    max_response = np.where(signal_function != 0)[0].max()
    assert 25 < max_response <= 30, "HRF has the incorrect length"
    assert np.sum(signal_function < 0) > 0, "No values below zero"
Example #4
0
def test_generate_stimfunction():

    # Inputs for generate_stimfunction
    onsets = [10, 30, 50, 70, 90]
    event_durations = [6]
    tr_duration = 2
    duration = 100

    # Create the time course for the signal to be generated
    stimfunction = sim.generate_stimfunction(onsets=onsets,
                                             event_durations=event_durations,
                                             total_time=duration,
                                             )

    assert stimfunction.shape[0] == duration * 100, "stimfunc incorrect length"
    eventNumber = np.sum(event_durations * len(onsets)) * 100
    assert np.sum(stimfunction) == eventNumber, "Event number"

    # Create the signal function
    signal_function = sim.convolve_hrf(stimfunction=stimfunction,
                                       tr_duration=tr_duration,
                                       )

    stim_dur = stimfunction.shape[0] / (tr_duration * 100)
    assert signal_function.shape[0] == stim_dur, "The length did not change"

    # Test
    onsets = [0]
    tr_duration = 1
    event_durations = [1]
    stimfunction = sim.generate_stimfunction(onsets=onsets,
                                             event_durations=event_durations,
                                             total_time=duration,
                                             )

    signal_function = sim.convolve_hrf(stimfunction=stimfunction,
                                       tr_duration=tr_duration,
                                       )

    max_response = np.where(signal_function != 0)[0].max()
    assert 25 < max_response <= 30, "HRF has the incorrect length"
    assert np.sum(signal_function < 0) > 0, "No values below zero"
Example #5
0
def test_generate_stimfunction():

    # Inputs for generate_stimfunction
    onsets = [10, 30, 50, 70, 90]
    event_durations = [6]
    tr_duration = 2
    duration = 100

    # Create the time course for the signal to be generated
    stimfunction = sim.generate_stimfunction(
        onsets=onsets,
        event_durations=event_durations,
        total_time=duration,
    )

    assert len(stimfunction) == duration * 1000, "stimfunction incorrect " \
                                                 "length"
    eventNumber = np.sum(event_durations * len(onsets)) * 1000
    assert np.sum(stimfunction) == eventNumber, "Event number"

    # Create the signal function
    signal_function = sim.double_gamma_hrf(
        stimfunction=stimfunction,
        tr_duration=tr_duration,
    )
    assert len(signal_function) == len(stimfunction) / (tr_duration * 1000), \
        "The length did not change"

    onsets = [10]
    stimfunction = sim.generate_stimfunction(
        onsets=onsets,
        event_durations=event_durations,
        total_time=duration,
    )

    signal_function = sim.double_gamma_hrf(
        stimfunction=stimfunction,
        tr_duration=tr_duration,
    )
    assert np.sum(signal_function < 0) > 0, "No values below zero"
Example #6
0
def test_apply_signal():

    dimensions = np.array([10, 10, 10])  # What is the size of the brain
    feature_size = [2]
    feature_type = ['cube']
    feature_coordinates = np.array([[5, 5, 5]])
    signal_magnitude = [30]

    # Generate a volume representing the location and quality of the signal
    volume = sim.generate_signal(
        dimensions=dimensions,
        feature_coordinates=feature_coordinates,
        feature_type=feature_type,
        feature_size=feature_size,
        signal_magnitude=signal_magnitude,
    )

    # Inputs for generate_stimfunction
    onsets = [10, 30, 50, 70, 90]
    event_durations = [6]
    tr_duration = 2
    duration = 100

    # Create the time course for the signal to be generated
    stimfunction = sim.generate_stimfunction(
        onsets=onsets,
        event_durations=event_durations,
        total_time=duration,
    )

    signal_function = sim.double_gamma_hrf(
        stimfunction=stimfunction,
        tr_duration=tr_duration,
    )

    # Convolve the HRF with the stimulus sequence
    signal = sim.apply_signal(
        signal_function=signal_function,
        volume_static=volume,
    )

    assert signal.shape == (dimensions[0], dimensions[1], dimensions[2],
                            duration / tr_duration), "The output is the " \
                                                     "wrong size"

    signal = sim.apply_signal(
        signal_function=stimfunction,
        volume_static=volume,
    )

    assert np.any(signal == signal_magnitude), "The stimfunction is not binary"
Example #7
0
def test_calc_noise():

    # Inputs for functions
    onsets = [10, 30, 50, 70, 90]
    event_durations = [6]
    tr_duration = 2
    duration = 100
    tr_number = int(np.floor(duration / tr_duration))
    dimensions_tr = np.array([10, 10, 10, tr_number])

    # Preset the noise dict
    nd_orig = {
        'auto_reg_sigma': 1,
        'drift_sigma': 0.5,
        'overall': 0.1,
        'snr': 30,
        'spatial_sigma': 0.15,
        'system_sigma': 1,
    }

    # Create the time course for the signal to be generated
    stimfunction = sim.generate_stimfunction(
        onsets=onsets,
        event_durations=event_durations,
        total_time=duration,
    )

    # Mask the volume to be the same shape as a brain
    mask = sim.mask_brain(dimensions_tr)
    noise = sim.generate_noise(
        dimensions=dimensions_tr[0:3],
        stimfunction=stimfunction,
        tr_duration=tr_duration,
        mask=mask,
        noise_dict=nd_orig,
    )

    # Calculate the noise
    nd_calc = sim.calc_noise(noise, mask)

    assert abs(nd_calc['overall'] - nd_orig['overall']) < 0.1, 'overall ' \
                                                               'calculated ' \
                                                               'incorrectly'

    assert abs(nd_calc['snr'] - nd_orig['snr']) < 10, 'snr calculated ' \
                                                      'incorrectly'

    assert abs(nd_calc['system_sigma'] - nd_orig['system_sigma']) < 1, \
        'snr calculated incorrectly'
Example #8
0
def test_generate_stimfunction():

    # Inputs for generate_stimfunction
    onsets = [10, 30, 50, 70, 90]
    event_durations = [6]
    tr_duration = 2
    duration = 100

    # Create the time course for the signal to be generated
    stimfunction = sim.generate_stimfunction(onsets=onsets,
                                             event_durations=event_durations,
                                             total_time=duration,
                                             tr_duration=tr_duration,
                                             )

    assert len(stimfunction) == duration / tr_duration, "stimfunction incorrect " \
                                                        "length"
    assert np.sum(stimfunction) == np.sum(event_durations * len(onsets)) / \
                                   tr_duration, "Event number"


    # Create the signal function
    signal_function = sim.double_gamma_hrf(stimfunction=stimfunction,
                                           )
    assert len(signal_function) == len(stimfunction), "The length did not change"

    onsets = [10]
    stimfunction = sim.generate_stimfunction(onsets=onsets,
                                             event_durations=event_durations,
                                             total_time=duration,
                                             tr_duration=tr_duration,
                                             )

    signal_function = sim.double_gamma_hrf(stimfunction=stimfunction,
                                           )
    assert np.sum(signal_function < 0) > 0, "No values below zero"
Example #9
0
def univ_neural_signal(spec, tr, nvolumes):
    """
    For each event/condition in the input spec,
    generate a neural signal function (e.g. boxcar)
    and append it to the spec
    """

    for event in spec:
        # TODO: add option for lag
        if event['signal_type'] == 'boxcar':
            event['neural_signal'] = generate_stimfunction(
                event['onsets'],
                event['durations'], (nvolumes * tr),
                weights=event['amplitudes'])

    return spec
Example #10
0
def test_calc_noise():

    # Inputs for functions
    onsets = [10, 30, 50, 70, 90]
    event_durations = [6]
    tr_duration = 2
    duration = 100
    tr_number = int(np.floor(duration / tr_duration))
    dimensions_tr = np.array([10, 10, 10, tr_number])

    # Preset the noise dict
    nd_orig = {
        'auto_reg_sigma': 0.6,
        'drift_sigma': 0.4,
        'temporal_noise': 5,
        'sfnr': 30,
        'max_activity': 1000,
        'fwhm': 4,
    }

    # Create the time course for the signal to be generated
    stimfunction = sim.generate_stimfunction(
        onsets=onsets,
        event_durations=event_durations,
        total_time=duration,
    )

    # Mask the volume to be the same shape as a brain
    mask = sim.mask_brain(dimensions_tr)
    stimfunction_tr = stimfunction[::int(tr_duration * 1000)]
    noise = sim.generate_noise(
        dimensions=dimensions_tr[0:3],
        stimfunction_tr=stimfunction_tr,
        tr_duration=tr_duration,
        mask=mask,
        noise_dict=nd_orig,
    )

    # Calculate the noise
    nd_calc = sim.calc_noise(noise, mask)

    # How precise are these estimates
    precision = abs(nd_calc['temporal_noise'] - nd_orig['temporal_noise'])
    assert precision < 1, 'temporal_noise calculated incorrectly'

    precision = abs(nd_calc['sfnr'] - nd_orig['sfnr'])
    assert precision < 5, 'sfnr calculated incorrectly'
Example #11
0
def test_apply_signal():

    dimensions = np.array([10, 10, 10])  # What is the size of the brain
    feature_size = [2]
    feature_type = ['cube']
    feature_coordinates = np.array(
        [[5, 5, 5]])
    signal_magnitude = [30]

    # Generate a volume representing the location and quality of the signal
    volume = sim.generate_signal(dimensions=dimensions,
                                 feature_coordinates=feature_coordinates,
                                 feature_type=feature_type,
                                 feature_size=feature_size,
                                 signal_magnitude=signal_magnitude,
                                 )

    # Inputs for generate_stimfunction
    onsets = [10, 30, 50, 70, 90]
    event_durations = [6]
    tr_duration = 2
    duration = 100

    # Create the time course for the signal to be generated
    stimfunction = sim.generate_stimfunction(onsets=onsets,
                                             event_durations=event_durations,
                                             total_time=duration,
                                             )

    signal_function = sim.convolve_hrf(stimfunction=stimfunction,
                                       tr_duration=tr_duration,
                                       )

    # Convolve the HRF with the stimulus sequence
    signal = sim.apply_signal(signal_function=signal_function,
                              volume_signal=volume,
                              )

    assert signal.shape == (dimensions[0], dimensions[1], dimensions[2],
                            duration / tr_duration), "The output is the " \
                                                     "wrong size"

    signal = sim.apply_signal(signal_function=stimfunction,
                              volume_signal=volume,
                              )

    assert np.any(signal == signal_magnitude), "The stimfunction is not binary"
Example #12
0
def test_calc_noise():

    # Inputs for functions
    onsets = [10, 30, 50, 70, 90]
    event_durations = [6]
    tr_duration = 2
    duration = 100
    tr_number = int(np.floor(duration / tr_duration))
    dimensions_tr = np.array([10, 10, 10, tr_number])

    # Preset the noise dict
    nd_orig = {'auto_reg_sigma': 1,
               'drift_sigma': 0.5,
               'overall': 0.1,
               'snr': 30,
               'spatial_sigma': 0.15,
               'system_sigma': 1,
               }

    # Create the time course for the signal to be generated
    stimfunction = sim.generate_stimfunction(onsets=onsets,
                                             event_durations=event_durations,
                                             total_time=duration,
                                             )

    # Mask the volume to be the same shape as a brain
    mask = sim.mask_brain(dimensions_tr)
    noise = sim.generate_noise(dimensions=dimensions_tr[0:3],
                               stimfunction=stimfunction,
                               tr_duration=tr_duration,
                               mask=mask,
                               noise_dict=nd_orig,
                               )

    # Calculate the noise
    nd_calc = sim.calc_noise(noise, mask)

    assert abs(nd_calc['overall'] - nd_orig['overall']) < 0.1, 'overall ' \
                                                               'calculated ' \
                                                               'incorrectly'

    assert abs(nd_calc['snr'] - nd_orig['snr']) < 10, 'snr calculated ' \
                                                      'incorrectly'

    assert abs(nd_calc['system_sigma'] - nd_orig['system_sigma']) < 1, \
        'snr calculated incorrectly'
Example #13
0
def test_generate_noise():

    dimensions = np.array([10, 10, 10])  # What is the size of the brain
    feature_size = [2]
    feature_type = ['cube']
    feature_coordinates = np.array([[5, 5, 5]])
    signal_magnitude = [1]

    # Generate a volume representing the location and quality of the signal
    volume = sim.generate_signal(
        dimensions=dimensions,
        feature_coordinates=feature_coordinates,
        feature_type=feature_type,
        feature_size=feature_size,
        signal_magnitude=signal_magnitude,
    )

    # Inputs for generate_stimfunction
    onsets = [10, 30, 50, 70, 90]
    event_durations = [6]
    tr_duration = 2
    duration = 100

    # Create the time course for the signal to be generated
    stimfunction = sim.generate_stimfunction(
        onsets=onsets,
        event_durations=event_durations,
        total_time=duration,
    )

    signal_function = sim.double_gamma_hrf(
        stimfunction=stimfunction,
        tr_duration=tr_duration,
    )

    # Convolve the HRF with the stimulus sequence
    signal = sim.apply_signal(
        signal_function=signal_function,
        volume_static=volume,
    )

    # Generate the mask of the signal
    mask = sim.mask_brain(signal, mask_threshold=0.1)

    assert min(mask[mask > 0]) > 0.1, "Mask thresholding did not work"

    stimfunction_tr = stimfunction[::int(tr_duration * 1000)]
    # Create the noise volumes (using the default parameters)
    noise = sim.generate_noise(
        dimensions=dimensions,
        stimfunction_tr=stimfunction_tr,
        tr_duration=tr_duration,
        mask=mask,
    )

    assert signal.shape == noise.shape, "The dimensions of signal and noise " \
                                        "the same"

    assert np.std(signal) < np.std(noise), "Noise was not created"

    noise = sim.generate_noise(
        dimensions=dimensions,
        stimfunction_tr=stimfunction_tr,
        tr_duration=tr_duration,
        mask=mask,
        noise_dict={
            'temporal_noise': 0,
            'sfnr': 10000
        },
    )

    temporal_noise = np.std(noise[mask[:, :, :, 0] > 0], 1).mean()

    assert temporal_noise <= 0.1, "Noise strength could not be manipulated"
Example #14
0
    dimensions=dimensions,
    feature_coordinates=feature_coordinates_B,
    feature_type=feature_type,
    feature_size=feature_size,
    signal_magnitude=signal_magnitude,
)


# Visualize the signal that was generated for condition A
fig = plt.figure()
sim.plot_brain(fig, volume_static_A)
plt.show()

# Create the time course for the signal to be generated
stimfunction_A = sim.generate_stimfunction(
    onsets=onsets_A, event_durations=event_durations, total_time=duration, tr_duration=tr_duration
)

stimfunction_B = sim.generate_stimfunction(
    onsets=onsets_B, event_durations=event_durations, total_time=duration, tr_duration=tr_duration
)

# Convolve the HRF with the stimulus sequence
signal_function_A = sim.double_gamma_hrf(stimfunction=stimfunction_A)

signal_function_B = sim.double_gamma_hrf(stimfunction=stimfunction_B)

# Multiply the HRF timecourse with the signal
signal_A = sim.apply_signal(signal_function=signal_function_A, volume_static=volume_static_A)

signal_B = sim.apply_signal(signal_function=signal_function_B, volume_static=volume_static_B)
Example #15
0
def test_generate_noise():

    dimensions = np.array([10, 10, 10])  # What is the size of the brain
    feature_size = [2]
    feature_type = ['cube']
    feature_coordinates = np.array(
        [[5, 5, 5]])
    signal_magnitude = [1]

    # Generate a volume representing the location and quality of the signal
    volume = sim.generate_signal(dimensions=dimensions,
                                 feature_coordinates=feature_coordinates,
                                 feature_type=feature_type,
                                 feature_size=feature_size,
                                 signal_magnitude=signal_magnitude,
                                 )

    # Inputs for generate_stimfunction
    onsets = [10, 30, 50, 70, 90]
    event_durations = [6]
    tr_duration = 2
    duration = 100

    # Create the time course for the signal to be generated
    stimfunction = sim.generate_stimfunction(onsets=onsets,
                                             event_durations=event_durations,
                                             total_time=duration,
                                             )

    signal_function = sim.double_gamma_hrf(stimfunction=stimfunction,
                                           tr_duration=tr_duration,
                                           )

    # Convolve the HRF with the stimulus sequence
    signal = sim.apply_signal(signal_function=signal_function,
                              volume_static=volume,
                              )

    # Generate the mask of the signal
    mask = sim.mask_brain(signal, mask_threshold=0.1)

    assert min(mask[mask > 0]) > 0.1, "Mask thresholding did not work"

    # Create the noise volumes (using the default parameters)
    noise = sim.generate_noise(dimensions=dimensions,
                               stimfunction=stimfunction,
                               tr_duration=tr_duration,
                               mask=mask,
                               )

    assert signal.shape == noise.shape, "The dimensions of signal and noise " \
                                        "the same"

    assert np.std(signal) < np.std(noise), "Noise was not created"

    noise = sim.generate_noise(dimensions=dimensions,
                               stimfunction=stimfunction,
                               tr_duration=tr_duration,
                               mask=mask,
                               noise_dict={'overall': 0},
                               )

    assert np.sum(noise) == 0, "Noise strength could not be manipulated"
    assert np.std(noise) == 0, "Noise strength could not be manipulated"
Example #16
0
    randoized_label = np.repeat([1, 2], int(events / 2)).tolist()
    random.shuffle(randoized_label)
    for event_counter, cond in enumerate(randoized_label):

        # Flip a coin for each epoch to determine whether it is A or B
        if cond == 1:
            onsets_A.append(event_counter * (event_duration + isi))
        elif cond == 2:
            onsets_B.append(event_counter * (event_duration + isi))

    temporal_res = 1  # How many timepoints per second of the stim function are to be generated?

    # Create a time course of events
    stimfunc_A = sim.generate_stimfunction(
        onsets=onsets_A,
        event_durations=[event_duration],
        total_time=total_time,
        temporal_resolution=temporal_res,
    )

    stimfunc_B = sim.generate_stimfunction(
        onsets=onsets_B,
        event_durations=[event_duration],
        total_time=total_time,
        temporal_resolution=temporal_res,
    )
    # stimfunc per subject
    stimfunc_ppt = np.concatenate((stimfunc_A, stimfunc_B), axis=1)

    stimfunc_all.append(stimfunc_ppt)

    print('Load ROIs')
Example #17
0
def test_generate_noise():


    dimensions = np.array([64, 64, 36]) # What is the size of the brain
    feature_size = [2]
    feature_type = ['cube']
    feature_coordinates = np.array(
        [[32, 32, 18]])
    signal_magnitude = [30]

    # Generate a volume representing the location and quality of the signal
    volume_static = sim.generate_signal(dimensions=dimensions,
                                        feature_coordinates=feature_coordinates,
                                        feature_type=feature_type,
                                        feature_size=feature_size,
                                        signal_magnitude=signal_magnitude,
                                        )

    # Inputs for generate_stimfunction
    onsets = [10, 30, 50, 70, 90]
    event_durations = [6]
    tr_duration = 2
    duration = 100

    # Create the time course for the signal to be generated
    stimfunction = sim.generate_stimfunction(onsets=onsets,
                                             event_durations=event_durations,
                                             total_time=duration,
                                             tr_duration=tr_duration,
                                             )

    signal_function = sim.double_gamma_hrf(stimfunction=stimfunction,
                                           )

    # Convolve the HRF with the stimulus sequence
    signal = sim.apply_signal(signal_function=signal_function,
                              volume_static=volume_static,
                              )

    # Create the noise volumes (using the default parameters)

    noise = sim.generate_noise(dimensions=dimensions,
                               stimfunction=stimfunction,
                               tr_duration=tr_duration,
                               )

    assert signal.shape == noise.shape, "The dimensions of signal " \
                                                  "and noise the same"

    Z_noise = sim._generate_noise_temporal(stimfunction, tr_duration, 1)
    noise = sim._generate_noise_temporal(stimfunction, tr_duration, 0)

    assert np.std(Z_noise) < np.std(noise), "Z scoring is not working"

    # Combine the signal and the noise
    volume = signal + noise

    assert np.std(signal) < np.std(noise), "Noise was not created"

    noise = sim.generate_noise(dimensions=dimensions,
                               stimfunction=stimfunction,
                               tr_duration=tr_duration,
                               noise_strength=[0, 0, 0]
                               )

    assert np.sum(noise) == 0, "Noise strength could not be manipulated"
    assert np.std(noise) == 0, "Noise strength could not be manipulated"
Example #18
0
def test_generate_stimfunction():

    # Inputs for generate_stimfunction
    onsets = [10, 30, 50, 70, 90]
    event_durations = [6]
    tr_duration = 2
    duration = 100

    # Create the time course for the signal to be generated
    stimfunction = sim.generate_stimfunction(onsets=onsets,
                                             event_durations=event_durations,
                                             total_time=duration,
                                             )

    assert stimfunction.shape[0] == duration * 100, "stimfunc incorrect length"
    eventNumber = np.sum(event_durations * len(onsets)) * 100
    assert np.sum(stimfunction) == eventNumber, "Event number"

    # Create the signal function
    signal_function = sim.convolve_hrf(stimfunction=stimfunction,
                                       tr_duration=tr_duration,
                                       )

    stim_dur = stimfunction.shape[0] / (tr_duration * 100)
    assert signal_function.shape[0] == stim_dur, "The length did not change"

    # Test
    onsets = [0]
    tr_duration = 1
    event_durations = [1]
    stimfunction = sim.generate_stimfunction(onsets=onsets,
                                             event_durations=event_durations,
                                             total_time=duration,
                                             )

    signal_function = sim.convolve_hrf(stimfunction=stimfunction,
                                       tr_duration=tr_duration,
                                       )

    max_response = np.where(signal_function != 0)[0].max()
    assert 25 < max_response <= 30, "HRF has the incorrect length"
    assert np.sum(signal_function < 0) > 0, "No values below zero"

    # Export a stimfunction
    sim.export_3_column(stimfunction,
                        'temp.txt',
                        )

    # Load in the stimfunction
    stimfunc_new = sim.generate_stimfunction(onsets=None,
                                             event_durations=None,
                                             total_time=duration,
                                             timing_file='temp.txt',
                                             )

    assert np.all(stimfunc_new == stimfunction), "Export/import failed"

    # Break the timing precision of the generation
    stimfunc_new = sim.generate_stimfunction(onsets=None,
                                             event_durations=None,
                                             total_time=duration,
                                             timing_file='temp.txt',
                                             temporal_resolution=0.5,
                                             )

    assert stimfunc_new.sum() == 0, "Temporal resolution not working right"

    # Set the duration to be too short so you should get an error
    onsets = [10, 30, 50, 70, 90]
    event_durations = [5]
    with pytest.raises(ValueError):
        sim.generate_stimfunction(onsets=onsets,
                                  event_durations=event_durations,
                                  total_time=89,
                                  )

    # Clip the event offset
    stimfunc_new = sim.generate_stimfunction(onsets=onsets,
                                             event_durations=event_durations,
                                             total_time=95,
                                             )
    assert stimfunc_new[-1] == 1, 'Event offset was not clipped'

    # Test exporting a group of participants to an epoch file
    cond_a = sim.generate_stimfunction(onsets=onsets,
                                       event_durations=event_durations,
                                       total_time=110,
                                       )

    cond_b = sim.generate_stimfunction(onsets=[x + 5 for x in onsets],
                                       event_durations=event_durations,
                                       total_time=110,
                                       )

    stimfunction_group = [np.hstack((cond_a, cond_b))] * 2
    sim.export_epoch_file(stimfunction_group,
                          'temp.txt',
                          tr_duration,
                          )

    # Check that convolve throws a warning when the shape is wrong
    sim.convolve_hrf(stimfunction=np.hstack((cond_a, cond_b)).T,
                     tr_duration=tr_duration,
                     temporal_resolution=1,
                     )
Example #19
0
def test_calc_noise():

    # Inputs for functions
    onsets = [10, 30, 50, 70, 90]
    event_durations = [6]
    tr_duration = 2
    duration = 200
    temporal_res = 100
    tr_number = int(np.floor(duration / tr_duration))
    dimensions_tr = np.array([10, 10, 10, tr_number])

    # Preset the noise dict
    nd_orig = sim._noise_dict_update({})

    # Create the time course for the signal to be generated
    stimfunction = sim.generate_stimfunction(onsets=onsets,
                                             event_durations=event_durations,
                                             total_time=duration,
                                             temporal_resolution=temporal_res,
                                             )

    # Mask the volume to be the same shape as a brain
    mask, template = sim.mask_brain(dimensions_tr, mask_self=None)
    stimfunction_tr = stimfunction[::int(tr_duration * temporal_res)]

    nd_orig['matched'] = 0
    noise = sim.generate_noise(dimensions=dimensions_tr[0:3],
                               stimfunction_tr=stimfunction_tr,
                               tr_duration=tr_duration,
                               template=template,
                               mask=mask,
                               noise_dict=nd_orig,
                               )

    # Check the spatial noise match
    nd_orig['matched'] = 1
    noise_matched = sim.generate_noise(dimensions=dimensions_tr[0:3],
                                       stimfunction_tr=stimfunction_tr,
                                       tr_duration=tr_duration,
                                       template=template,
                                       mask=mask,
                                       noise_dict=nd_orig,
                                       iterations=[50, 0]
                                       )

    # Calculate the noise parameters from this newly generated volume
    nd_new = sim.calc_noise(noise, mask, template)
    nd_matched = sim.calc_noise(noise_matched, mask, template)

    # Check the values are reasonable"
    assert nd_new['snr'] > 0, 'snr out of range'
    assert nd_new['sfnr'] > 0, 'sfnr out of range'
    assert nd_new['auto_reg_rho'][0] > 0, 'ar out of range'

    # Check that the dilation increases SNR
    no_dilation_snr = sim._calc_snr(noise_matched,
                                    mask,
                                    dilation=0,
                                    reference_tr=tr_duration,
                                    )

    assert nd_new['snr'] > no_dilation_snr, "Dilation did not increase SNR"

    # Check that template size is in bounds
    with pytest.raises(ValueError):
        sim.calc_noise(noise, mask, template * 2)

    # Check that Mask is set is checked
    with pytest.raises(ValueError):
        sim.calc_noise(noise, None, template)

    # Check that it can deal with missing noise parameters
    temp_nd = sim.calc_noise(noise, mask, template, noise_dict={})
    assert temp_nd['voxel_size'][0] == 1, 'Default voxel size not set'

    temp_nd = sim.calc_noise(noise, mask, template, noise_dict=None)
    assert temp_nd['voxel_size'][0] == 1, 'Default voxel size not set'

    # Check that the fitting worked
    snr_diff = abs(nd_orig['snr'] - nd_new['snr'])
    snr_diff_match = abs(nd_orig['snr'] - nd_matched['snr'])
    assert snr_diff > snr_diff_match, 'snr fit incorrectly'

    # Test that you can generate rician and exponential noise
    sim._generate_noise_system(dimensions_tr,
                               1,
                               1,
                               spatial_noise_type='exponential',
                               temporal_noise_type='rician',
                               )

    # Check the temporal noise match
    nd_orig['matched'] = 1
    noise_matched = sim.generate_noise(dimensions=dimensions_tr[0:3],
                                       stimfunction_tr=stimfunction_tr,
                                       tr_duration=tr_duration,
                                       template=template,
                                       mask=mask,
                                       noise_dict=nd_orig,
                                       iterations=[0, 50]
                                       )

    nd_matched = sim.calc_noise(noise_matched, mask, template)

    sfnr_diff = abs(nd_orig['sfnr'] - nd_new['sfnr'])
    sfnr_diff_match = abs(nd_orig['sfnr'] - nd_matched['sfnr'])
    assert sfnr_diff > sfnr_diff_match, 'sfnr fit incorrectly'

    ar1_diff = abs(nd_orig['auto_reg_rho'][0] - nd_new['auto_reg_rho'][0])
    ar1_diff_match = abs(nd_orig['auto_reg_rho'][0] - nd_matched[
        'auto_reg_rho'][0])
    assert ar1_diff > ar1_diff_match, 'AR1 fit incorrectly'

    # Check that you can calculate ARMA for a single voxel
    vox = noise[5, 5, 5, :]
    arma = sim._calc_ARMA_noise(vox,
                                None,
                                sample_num=2,
                                )
    assert len(arma) == 2, "Two outputs not given by ARMA"
Example #20
0
def test_generate_noise():

    dimensions = np.array([10, 10, 10])  # What is the size of the brain
    feature_size = [2]
    feature_type = ['cube']
    feature_coordinates = np.array(
        [[5, 5, 5]])
    signal_magnitude = [1]

    # Generate a volume representing the location and quality of the signal
    volume = sim.generate_signal(dimensions=dimensions,
                                 feature_coordinates=feature_coordinates,
                                 feature_type=feature_type,
                                 feature_size=feature_size,
                                 signal_magnitude=signal_magnitude,
                                 )

    # Inputs for generate_stimfunction
    onsets = [10, 30, 50, 70, 90]
    event_durations = [6]
    tr_duration = 2
    duration = 200

    # Create the time course for the signal to be generated
    stimfunction = sim.generate_stimfunction(onsets=onsets,
                                             event_durations=event_durations,
                                             total_time=duration,
                                             )

    signal_function = sim.convolve_hrf(stimfunction=stimfunction,
                                       tr_duration=tr_duration,
                                       )

    # Convolve the HRF with the stimulus sequence
    signal = sim.apply_signal(signal_function=signal_function,
                              volume_signal=volume,
                              )

    # Generate the mask of the signal
    mask, template = sim.mask_brain(signal,
                                    mask_self=None)

    assert min(mask[mask > 0]) > 0.1, "Mask thresholding did not work"
    assert len(np.unique(template) > 2), "Template creation did not work"

    stimfunction_tr = stimfunction[::int(tr_duration * 100)]

    # Create the noise volumes (using the default parameters)
    noise = sim.generate_noise(dimensions=dimensions,
                               stimfunction_tr=stimfunction_tr,
                               tr_duration=tr_duration,
                               template=template,
                               mask=mask,
                               iterations=[1, 0],
                               )

    assert signal.shape == noise.shape, "The dimensions of signal and noise " \
                                        "the same"

    noise_high = sim.generate_noise(dimensions=dimensions,
                                    stimfunction_tr=stimfunction_tr,
                                    tr_duration=tr_duration,
                                    template=template,
                                    mask=mask,
                                    noise_dict={'sfnr': 50, 'snr': 25},
                                    iterations=[1, 0],
                                    )

    noise_low = sim.generate_noise(dimensions=dimensions,
                                   stimfunction_tr=stimfunction_tr,
                                   tr_duration=tr_duration,
                                   template=template,
                                   mask=mask,
                                   noise_dict={'sfnr': 100, 'snr': 25},
                                   iterations=[1, 0],
                                   )

    system_high = np.std(noise_high[mask > 0], 1).mean()
    system_low = np.std(noise_low[mask > 0], 1).mean()

    assert system_low < system_high, "SFNR noise could not be manipulated"

    # Check that you check for the appropriate template values
    with pytest.raises(ValueError):
        sim.generate_noise(dimensions=dimensions,
                           stimfunction_tr=stimfunction_tr,
                           tr_duration=tr_duration,
                           template=template * 2,
                           mask=mask,
                           noise_dict={},
                           )

    # Check that iterations does what it should
    sim.generate_noise(dimensions=dimensions,
                       stimfunction_tr=stimfunction_tr,
                       tr_duration=tr_duration,
                       template=template,
                       mask=mask,
                       noise_dict={},
                       iterations=[0, 0],
                       )

    sim.generate_noise(dimensions=dimensions,
                       stimfunction_tr=stimfunction_tr,
                       tr_duration=tr_duration,
                       template=template,
                       mask=mask,
                       noise_dict={},
                       iterations=None,
                       )

    # Test drift noise
    trs = 1000
    period = 100
    drift = sim._generate_noise_temporal_drift(trs,
                                               tr_duration,
                                               'sine',
                                               period,
                                               )

    # Check that the max frequency is the appropriate frequency
    power = abs(np.fft.fft(drift))[1:trs // 2]
    freq = np.linspace(1, trs // 2 - 1, trs // 2 - 1) / trs
    period_freq = np.where(freq == 1 / (period // tr_duration))
    max_freq = np.argmax(power)

    assert period_freq == max_freq, 'Max frequency is not where it should be'

    # Do the same but now with cosine basis functions, answer should be close
    drift = sim._generate_noise_temporal_drift(trs,
                                               tr_duration,
                                               'discrete_cos',
                                               period,
                                               )

    # Check that the appropriate frequency is peaky (may not be the max)
    power = abs(np.fft.fft(drift))[1:trs // 2]
    freq = np.linspace(1, trs // 2 - 1, trs // 2 - 1) / trs
    period_freq = np.where(freq == 1 / (period // tr_duration))[0][0]

    assert power[period_freq] > power[period_freq + 1], 'Power is low'
    assert power[period_freq] > power[period_freq - 1], 'Power is low'

    # Check it gives a warning if the duration is too short
    drift = sim._generate_noise_temporal_drift(50,
                                               tr_duration,
                                               'discrete_cos',
                                               period,
                                               )

    # Test physiological noise (using unrealistic parameters so that it's easy)
    timepoints = list(np.linspace(0, (trs - 1) * tr_duration, trs))
    resp_freq = 0.2
    heart_freq = 1.17
    phys = sim._generate_noise_temporal_phys(timepoints,
                                             resp_freq,
                                             heart_freq,
                                             )

    # Check that the max frequency is the appropriate frequency
    power = abs(np.fft.fft(phys))[1:trs // 2]
    freq = np.linspace(1, trs // 2 - 1, trs // 2 - 1) / (trs * tr_duration)
    peaks = (power > (power.mean() + power.std()))  # Where are the peaks
    peak_freqs = freq[peaks]

    assert np.any(resp_freq == peak_freqs), 'Resp frequency not found'
    assert len(peak_freqs) == 2, 'Two peaks not found'

    # Test task noise
    sim._generate_noise_temporal_task(stimfunction_tr,
                                      motion_noise='gaussian',
                                      )
    sim._generate_noise_temporal_task(stimfunction_tr,
                                      motion_noise='rician',
                                      )

    # Test ARMA noise
    with pytest.raises(ValueError):
        noise_dict = {'fwhm': 4, 'auto_reg_rho': [1], 'ma_rho': [1, 1]}
        sim._generate_noise_temporal_autoregression(stimfunction_tr,
                                                    noise_dict,
                                                    dimensions,
                                                    mask,
                                                    )

    # Generate spatial noise
    vol = sim._generate_noise_spatial(np.array([10, 10, 10, trs]))
    assert len(vol.shape) == 3, 'Volume was not reshaped to ignore TRs'

    # Switch some of the noise types on
    noise_dict = dict(physiological_sigma=1, drift_sigma=1, task_sigma=1,
                      auto_reg_sigma=0)
    sim.generate_noise(dimensions=dimensions,
                       stimfunction_tr=stimfunction_tr,
                       tr_duration=tr_duration,
                       template=template,
                       mask=mask,
                       noise_dict=noise_dict,
                       iterations=[0, 0],
                       )
Example #21
0
def test_apply_signal():

    dimensions = np.array([10, 10, 10])  # What is the size of the brain
    feature_size = [2]
    feature_type = ['cube']
    feature_coordinates = np.array(
        [[5, 5, 5]])
    signal_magnitude = [30]

    # Generate a volume representing the location and quality of the signal
    volume = sim.generate_signal(dimensions=dimensions,
                                 feature_coordinates=feature_coordinates,
                                 feature_type=feature_type,
                                 feature_size=feature_size,
                                 signal_magnitude=signal_magnitude,
                                 )

    # Inputs for generate_stimfunction
    onsets = [10, 30, 50, 70, 90]
    event_durations = [6]
    tr_duration = 2
    duration = 100

    # Create the time course for the signal to be generated
    stimfunction = sim.generate_stimfunction(onsets=onsets,
                                             event_durations=event_durations,
                                             total_time=duration,
                                             )

    signal_function = sim.convolve_hrf(stimfunction=stimfunction,
                                       tr_duration=tr_duration,
                                       )

    # Check that you can compute signal change appropriately
    # Preset a bunch of things
    stimfunction_tr = stimfunction[::int(tr_duration * 100)]
    mask, template = sim.mask_brain(dimensions, mask_self=False)
    noise_dict = sim._noise_dict_update({})
    noise = sim.generate_noise(dimensions=dimensions,
                               stimfunction_tr=stimfunction_tr,
                               tr_duration=tr_duration,
                               template=template,
                               mask=mask,
                               noise_dict=noise_dict,
                               iterations=[0, 0]
                               )
    coords = feature_coordinates[0]
    noise_function_a = noise[coords[0], coords[1], coords[2], :]
    noise_function_a = noise_function_a.reshape(duration // tr_duration, 1)

    noise_function_b = noise[coords[0] + 1, coords[1], coords[2], :]
    noise_function_b = noise_function_b.reshape(duration // tr_duration, 1)

    # Create the calibrated signal with PSC
    method = 'PSC'
    sig_a = sim.compute_signal_change(signal_function,
                                      noise_function_a,
                                      noise_dict,
                                      [0.5],
                                      method,
                                      )
    sig_b = sim.compute_signal_change(signal_function,
                                      noise_function_a,
                                      noise_dict,
                                      [1.0],
                                      method,
                                      )

    assert sig_b.max() / sig_a.max() == 2, 'PSC modulation failed'

    # Create the calibrated signal with SFNR
    method = 'SFNR'
    sig_a = sim.compute_signal_change(signal_function,
                                      noise_function_a,
                                      noise_dict,
                                      [0.5],
                                      method,
                                      )
    scaled_a = sig_a / (noise_function_a.mean() / noise_dict['sfnr'])
    sig_b = sim.compute_signal_change(signal_function,
                                      noise_function_b,
                                      noise_dict,
                                      [1.0],
                                      method,
                                      )
    scaled_b = sig_b / (noise_function_b.mean() / noise_dict['sfnr'])

    assert scaled_b.max() / scaled_a.max() == 2, 'SFNR modulation failed'

    # Create the calibrated signal with CNR_Amp/Noise-SD
    method = 'CNR_Amp/Noise-SD'
    sig_a = sim.compute_signal_change(signal_function,
                                      noise_function_a,
                                      noise_dict,
                                      [0.5],
                                      method,
                                      )
    scaled_a = sig_a / noise_function_a.std()
    sig_b = sim.compute_signal_change(signal_function,
                                      noise_function_b,
                                      noise_dict,
                                      [1.0],
                                      method,
                                      )
    scaled_b = sig_b / noise_function_b.std()

    assert scaled_b.max() / scaled_a.max() == 2, 'CNR_Amp modulation failed'

    # Create the calibrated signal with CNR_Amp/Noise-Var_dB
    method = 'CNR_Amp2/Noise-Var_dB'
    sig_a = sim.compute_signal_change(signal_function,
                                      noise_function_a,
                                      noise_dict,
                                      [0.5],
                                      method,
                                      )
    scaled_a = np.log(sig_a.max() / noise_function_a.std())
    sig_b = sim.compute_signal_change(signal_function,
                                      noise_function_b,
                                      noise_dict,
                                      [1.0],
                                      method,
                                      )
    scaled_b = np.log(sig_b.max() / noise_function_b.std())

    assert np.round(scaled_b / scaled_a) == 2, 'CNR_Amp dB modulation failed'

    # Create the calibrated signal with CNR_Signal-SD/Noise-SD
    method = 'CNR_Signal-SD/Noise-SD'
    sig_a = sim.compute_signal_change(signal_function,
                                      noise_function_a,
                                      noise_dict,
                                      [0.5],
                                      method,
                                      )
    scaled_a = sig_a.std() / noise_function_a.std()
    sig_b = sim.compute_signal_change(signal_function,
                                      noise_function_a,
                                      noise_dict,
                                      [1.0],
                                      method,
                                      )
    scaled_b = sig_b.std() / noise_function_a.std()

    assert (scaled_b / scaled_a) == 2, 'CNR signal modulation failed'

    # Create the calibrated signal with CNR_Amp/Noise-Var_dB
    method = 'CNR_Signal-Var/Noise-Var_dB'
    sig_a = sim.compute_signal_change(signal_function,
                                      noise_function_a,
                                      noise_dict,
                                      [0.5],
                                      method,
                                      )

    scaled_a = np.log(sig_a.std() / noise_function_a.std())
    sig_b = sim.compute_signal_change(signal_function,
                                      noise_function_b,
                                      noise_dict,
                                      [1.0],
                                      method,
                                      )
    scaled_b = np.log(sig_b.std() / noise_function_b.std())

    assert np.round(scaled_b / scaled_a) == 2, 'CNR signal dB modulation ' \
                                               'failed'

    # Convolve the HRF with the stimulus sequence
    signal = sim.apply_signal(signal_function=signal_function,
                              volume_signal=volume,
                              )

    assert signal.shape == (dimensions[0], dimensions[1], dimensions[2],
                            duration / tr_duration), "The output is the " \
                                                     "wrong size"

    signal = sim.apply_signal(signal_function=stimfunction,
                              volume_signal=volume,
                              )

    assert np.any(signal == signal_magnitude), "The stimfunction is not binary"

    # Check that there is an error if the number of signal voxels doesn't
    # match the number of non zero brain voxels
    with pytest.raises(IndexError):
        sig_vox = (volume > 0).sum()
        vox_pattern = np.tile(stimfunction, (1, sig_vox - 1))
        sim.apply_signal(signal_function=vox_pattern,
                         volume_signal=volume,
                         )
Example #22
0
def generate_data(outputDir, user_settings):
    """Generate simulated fMRI data
    Use a few parameters that might be relevant for real time analysis

    Parameters
    ----------

    outputDir : str
        Specify output data dir where the data should be saved

    user_settings : dict
        A dictionary to specify the parameters used for making data,
        specifying the following keys
        numTRs - int - Specify the number of time points
        multivariate_patterns - bool - Is the difference between conditions
        univariate (0) or multivariate (1)
        different_ROIs - bool - Are there different ROIs for each condition (
        1) or is it in the same ROI (0). If it is the same ROI and you are
        using univariate differences, the second condition will have a
        smaller evoked response than the other.
        event_duration - int - How long, in seconds, is each event
        scale_percentage - float - What is the percent signal change
        trDuration - float - How many seconds per volume
        save_dicom - bool - Save to data as a dicom (1) or numpy (0)
        save_realtime - bool - Do you want to save the data in real time (1)
        or as fast as possible (0)?
        isi - float - What is the time between each event (in seconds)
        burn_in - int - How long before the first event (in seconds)

    """
    data_dict = default_settings.copy()
    data_dict.update(user_settings)

    # If the folder doesn't exist then make it
    os.system('mkdir -p %s' % outputDir)

    logger.info('Load template of average voxel value')

    # Get the file names needed for loading in the data
    ROI_A_file, ROI_B_file, template_path, noise_dict_file = \
        _get_input_names(data_dict)

    # Load in the template data (it may already be loaded if doing a test)
    if isinstance(template_path, str):
        template_nii = nibabel.load(template_path)
        template = template_nii.get_data()
    else:
        template = template_path

    dimensions = np.array(template.shape[0:3])

    logger.info('Create binary mask and normalize the template range')
    mask, template = sim.mask_brain(
        volume=template,
        mask_self=True,
    )

    # Write out the mask as a numpy file
    outFile = os.path.join(outputDir, 'mask.npy')
    np.save(outFile, mask.astype(np.uint8))

    # Load the noise dictionary
    logger.info('Loading noise parameters')

    # If this isn't a string, assume it is a resource stream file
    if type(noise_dict_file) is str:
        with open(noise_dict_file, 'r') as f:
            noise_dict = f.read()
    else:
        # Read the resource stream object
        noise_dict = noise_dict_file.decode()

    noise_dict = eval(noise_dict)
    noise_dict['matched'] = 0  # Increases processing time

    # Add it here for easy access
    data_dict['noise_dict'] = noise_dict

    logger.info('Generating noise')
    temp_stimfunction = np.zeros((data_dict['numTRs'], 1))
    noise = sim.generate_noise(
        dimensions=dimensions,
        stimfunction_tr=temp_stimfunction,
        tr_duration=int(data_dict['trDuration']),
        template=template,
        mask=mask,
        noise_dict=noise_dict,
    )

    # Create the stimulus time course of the conditions
    total_time = int(data_dict['numTRs'] * data_dict['trDuration'])
    onsets_A = []
    onsets_B = []
    curr_time = data_dict['burn_in']
    while curr_time < (total_time - data_dict['event_duration']):

        # Flip a coin for each epoch to determine whether it is A or B
        if np.random.randint(0, 2) == 1:
            onsets_A.append(curr_time)
        else:
            onsets_B.append(curr_time)

        # Increment the current time
        curr_time += data_dict['event_duration'] + data_dict['isi']

    # How many timepoints per second of the stim function are to be generated?
    temporal_res = 1 / data_dict['trDuration']

    # Create a time course of events
    event_durations = [data_dict['event_duration']]
    stimfunc_A = sim.generate_stimfunction(
        onsets=onsets_A,
        event_durations=event_durations,
        total_time=total_time,
        temporal_resolution=temporal_res,
    )

    stimfunc_B = sim.generate_stimfunction(
        onsets=onsets_B,
        event_durations=event_durations,
        total_time=total_time,
        temporal_resolution=temporal_res,
    )

    # Create a labels timecourse
    outFile = os.path.join(outputDir, 'labels.npy')
    np.save(outFile, (stimfunc_A + (stimfunc_B * 2)))

    # How is the signal implemented in the different ROIs
    signal_A = _generate_ROIs(ROI_A_file, stimfunc_A, noise,
                              data_dict['scale_percentage'], data_dict)
    if data_dict['different_ROIs'] is True:

        signal_B = _generate_ROIs(ROI_B_file, stimfunc_B, noise,
                                  data_dict['scale_percentage'], data_dict)

    else:

        # Halve the evoked response if these effects are both expected in the
        #  same ROI
        if data_dict['multivariate_pattern'] is False:
            signal_B = _generate_ROIs(ROI_A_file, stimfunc_B, noise,
                                      data_dict['scale_percentage'] * 0.5,
                                      data_dict)
        else:
            signal_B = _generate_ROIs(ROI_A_file, stimfunc_B, noise,
                                      data_dict['scale_percentage'], data_dict)

    # Combine the two signal timecourses
    signal = signal_A + signal_B

    logger.info('Generating TRs in real time')
    for idx in range(data_dict['numTRs']):

        #  Create the brain volume on this TR
        brain = noise[:, :, :, idx] + signal[:, :, :, idx]

        # Convert file to integers to mimic what you get from MR
        brain_int32 = brain.astype(np.int32)

        # Store as dicom or nifti?
        if data_dict['save_dicom'] is True:
            # Save the volume as a DICOM file, with each TR as its own file
            output_file = os.path.join(outputDir,
                                       'rt_' + format(idx, '03d') + '.dcm')
            _write_dicom(output_file, brain_int32, idx + 1)
        else:
            # Save the volume as a numpy file, with each TR as its own file
            output_file = os.path.join(outputDir,
                                       'rt_' + format(idx, '03d') + '.npy')
            np.save(output_file, brain_int32)

        logger.info("Generate {}".format(output_file))

        # Sleep until next TR
        if data_dict['save_realtime'] == 1:
            time.sleep(data_dict['trDuration'])
Example #23
0
    dimensions=dimensions,
    feature_coordinates=coordinates_B,
    feature_type=feature_type,
    feature_size=feature_size,
    signal_magnitude=signal_magnitude,
)

# Visualize the signal that was generated for condition A
fig = plt.figure()
sim.plot_brain(fig, volume_static_A)
plt.show()

# Create the time course for the signal to be generated
stimfunction_A = sim.generate_stimfunction(
    onsets=onsets_A,
    event_durations=event_durations,
    total_time=duration,
    temporal_resolution=temporal_res,
)

stimfunction_B = sim.generate_stimfunction(
    onsets=onsets_B,
    event_durations=event_durations,
    total_time=duration,
    temporal_resolution=temporal_res,
)

# Convolve the HRF with the stimulus sequence
signal_function_A = sim.double_gamma_hrf(
    stimfunction=stimfunction_A,
    tr_duration=tr_duration,
    temporal_resolution=temporal_res,
Example #24
0
                                      feature_coordinates=coordinates_B,
                                      feature_type=feature_type,
                                      feature_size=feature_size,
                                      signal_magnitude=signal_magnitude,
                                      )


# Visualize the signal that was generated for condition A
fig = plt.figure()
sim.plot_brain(fig,
               volume_static_A)
plt.show()

# Create the time course for the signal to be generated
stimfunction_A = sim.generate_stimfunction(onsets=onsets_A,
                                           event_durations=event_durations,
                                           total_time=duration,
                                           )

stimfunction_B = sim.generate_stimfunction(onsets=onsets_B,
                                           event_durations=event_durations,
                                           total_time=duration,
                                           )

# Convolve the HRF with the stimulus sequence
signal_function_A = sim.double_gamma_hrf(stimfunction=stimfunction_A,
                                         tr_duration=tr_duration,
                                         )

signal_function_B = sim.double_gamma_hrf(stimfunction=stimfunction_B,
                                         tr_duration=tr_duration,
                                         )
        print('Node ' + str(node_counter))

        # Preset value
        volume = np.zeros(dimensions[0:3])

        # Preset the signal
        signal_pattern = signal_coords[node_counter, :]
        onsets_node = onsets[node_counter]

        # Only do it if there are onsets
        if len(onsets_node) > 0:
     
            # Create the time course for the signal to be generated
            stimfunc = sim.generate_stimfunction(onsets=onsets_node,
                                                 event_durations=event_durations,
                                                 total_time=duration,
                                                 temporal_resolution=temporal_res,
                                                 )

            # Aggregate the timecourse
            if len(stimfunc_all) == 0:
                stimfunc_all = np.zeros((len(stimfunc), vector_size))
                for voxel_counter in list(range(0, vector_size)):
                    stimfunc_all[:, voxel_counter] = np.asarray(
                        stimfunc).transpose() * signal_pattern[voxel_counter]
            else:

                # Add these elements together
                temp = np.zeros((len(stimfunc), vector_size))
                for voxel_counter in list(range(0, vector_size)):
                    temp[:, voxel_counter] = np.asarray(stimfunc).transpose() * \
def generate_data(inputDir, outputDir, data_dict):
    # Generate simulated fMRI data with a few parameters that might be
    # relevant for real time analysis
    # inputDir - Specify input data dir where the parameters for fmrisim are
    # outputDir - Specify output data dir where the data should be saved
    # data_dict contains:
    #     numTRs - Specify the number of time points
    #     multivariate_patterns - Is the difference between conditions
    # univariate (0) or multivariate (1)
    #     different_ROIs - Are there different ROIs for each condition (1) or
    #  is it in the same ROI (0). If it is the same ROI and you are using
    # univariate differences, the second condition will have a smaller evoked
    #  response than the other.
    #     event_duration - How long, in seconds, is each event
    #     scale_percentage - What is the percent signal change
    #     trDuration - How many seconds per volume
    #     save_dicom - Do you want to save data as a dicom (1) or numpy (0)
    #     save_realtime - Do you want to save the data in real time (1) or as
    #  fast as possible (0)?
    #     isi - What is the time between each event (in seconds)
    #     burn_in - How long before the first event (in seconds)

    # If the folder doesn't exist then make it
    if os.path.isdir(outputDir) is False:
        os.makedirs(outputDir, exist_ok=True)

    print('Load template of average voxel value')
    templateFile = os.path.join(inputDir, 'sub_template.nii.gz')
    template_nii = nibabel.load(templateFile)
    template = template_nii.get_data()

    dimensions = np.array(template.shape[0:3])

    print('Create binary mask and normalize the template range')
    mask, template = sim.mask_brain(
        volume=template,
        mask_self=True,
    )

    # Write out the mask as a numpy file
    outFile = os.path.join(outputDir, 'mask.npy')
    np.save(outFile, mask.astype(np.uint8))

    # Load the noise dictionary
    print('Loading noise parameters')
    noiseFile = os.path.join(inputDir, 'sub_noise_dict.txt')
    with open(noiseFile, 'r') as f:
        noise_dict = f.read()
    noise_dict = eval(noise_dict)
    noise_dict['matched'] = 0  # Increases processing time

    # Add it here for easy access
    data_dict['noise_dict'] = data_dict

    print('Generating noise')
    temp_stimfunction = np.zeros((data_dict['numTRs'], 1))
    noise = sim.generate_noise(
        dimensions=dimensions,
        stimfunction_tr=temp_stimfunction,
        tr_duration=int(data_dict['trDuration']),
        template=template,
        mask=mask,
        noise_dict=noise_dict,
    )

    # Create the stimulus time course of the conditions
    total_time = int(data_dict['numTRs'] * data_dict['trDuration'])
    onsets_A = []
    onsets_B = []
    curr_time = data_dict['burn_in']
    while curr_time < (total_time - data_dict['event_duration']):

        # Flip a coin for each epoch to determine whether it is A or B
        if np.random.randint(0, 2) == 1:
            onsets_A.append(curr_time)
        else:
            onsets_B.append(curr_time)

        # Increment the current time
        curr_time += data_dict['event_duration'] + data_dict['isi']

    # How many timepoints per second of the stim function are to be generated?
    temporal_res = 1 / data_dict['trDuration']

    # Create a time course of events
    event_durations = [data_dict['event_duration']]
    stimfunc_A = sim.generate_stimfunction(
        onsets=onsets_A,
        event_durations=event_durations,
        total_time=total_time,
        temporal_resolution=temporal_res,
    )

    stimfunc_B = sim.generate_stimfunction(
        onsets=onsets_B,
        event_durations=event_durations,
        total_time=total_time,
        temporal_resolution=temporal_res,
    )

    # Create a labels timecourse
    outFile = os.path.join(outputDir, 'labels.npy')
    np.save(outFile, (stimfunc_A + (stimfunc_B * 2)))

    roiA_file = os.path.join(inputDir, 'ROI_A.nii.gz')
    roiB_file = os.path.join(inputDir, 'ROI_B.nii.gz')

    # How is the signal implemented in the different ROIs
    signal_A = generate_ROIs(roiA_file, stimfunc_A, noise,
                             data_dict['scale_percentage'], data_dict)
    if data_dict['different_ROIs'] is True:

        signal_B = generate_ROIs(roiB_file, stimfunc_B, noise,
                                 data_dict['scale_percentage'], data_dict)

    else:

        # Halve the evoked response if these effects are both expected in the same ROI
        if data_dict['multivariate_pattern'] is False:
            signal_B = generate_ROIs(roiA_file, stimfunc_B, noise,
                                     data_dict['scale_percentage'] * 0.5,
                                     data_dict)
        else:
            signal_B = generate_ROIs(roiA_file, stimfunc_B, noise,
                                     data_dict['scale_percentage'], data_dict)

    # Combine the two signal timecourses
    signal = signal_A + signal_B

    print('Generating TRs in real time')
    for idx in range(data_dict['numTRs']):

        #  Create the brain volume on this TR
        brain = noise[:, :, :, idx] + signal[:, :, :, idx]

        # Convert file to integers to mimic what you get from MR
        brain_int32 = brain.astype(np.int32)

        # Store as dicom or nifti?
        if data_dict['save_dicom'] is True:
            # Save the volume as a DICOM file, with each TR as its own file
            output_file = os.path.join(outputDir,
                                       'rt_' + format(idx, '03d') + '.dcm')
            write_dicom(output_file, brain_int32, idx + 1)
        else:
            # Save the volume as a numpy file, with each TR as its own file
            output_file = os.path.join(outputDir,
                                       'rt_' + format(idx, '03d') + '.npy')
            np.save(output_file, brain_int32)

        print("Generate {}".format(output_file))

        # Sleep until next TR
        if data_dict['save_realtime'] == 1:
            time.sleep(data_dict['trDuration'])
Example #27
0
def toy_simulation(community_density=1,
                   added_isi=0,
                   rand=0,
                   signal_magnitude=1,
                   noise_type='coordinates',
                   noise_parameter=0,
                   restrict_overall_duration=0,
                   ):

    # Default these values
    nodes = 15
    runs = 5
    vector_size = 2  # How many voxels did you make
    all_pos = 1
    ppt = '1'  # What participant would you like to simulate
    tr_duration = 2
    event_durations = [1]
    hrf_lag = 2
    temporal_res = 100  # How many samples per second are there for timing files

    # Select what the noise is applied to
    noise_coordinates = 0  # How much noise are you adding to the coordinates
    noise_timecourse = 0  # How many random noise are you adding to the timecourse
    if noise_type == 'coordinates':
        noise_coordinates = noise_parameter
    elif noise_type == 'timecourse':
        noise_timecourse = noise_parameter

    # Load the timing information
    timing_path = '../../community_structure/simulator_parameters/timing/'
    #timing_path = '/Volumes/pniintel/ntb/TDA/Validation/code/community_structure/simulator_parameters/timing/'
    onsets_runs = np.load(timing_path + 'sub-' + ppt + '.npy')
    
    # Generate the graph structure (based on the ratio)
    signal_coords = community_structure(1 - community_density,
                                        )

    # Add noise to these coordinates
    noise = np.random.randn(np.prod(signal_coords.shape)).reshape(
        signal_coords.shape) * noise_coordinates

    signal_coords += noise

    # Perform an orthonormal transformation of the data
    if vector_size > signal_coords.shape[1]:
        signal_coords = orthonormal_transform(vector_size,
                                              signal_coords,
                                              )

    # Do you want these coordinates to be all positive? This means that
    # these coordinates are represented as different magnitudes of
    # activation
    if all_pos == 1:
        mins = np.abs(np.min(signal_coords, 0))
        for voxel_counter in list(range(0, len(mins))):
            signal_coords[:, voxel_counter] += mins[voxel_counter]

    # Bound the value to have a max of 1 so that the signal magnitude is more interpretable
    signal_coords /= np.max(signal_coords)

    # Determine the size of the signal
    signal_coords *= signal_magnitude

    # Cycle through the runs and generate the data

    node_brain = np.zeros([vector_size, nodes, runs], dtype='double')  # Preset
    for run_counter in list(range(1, runs + 1)):

        # Pull out the onsets for this participant (reload it each time to deal with copying issues)
        onsets_runs = np.load(timing_path + 'sub-' + ppt + '.npy')
        onsets_run = onsets_runs[run_counter - 1]

        # What is the original max duration of the onsets
        max_duration_orig = np.max([np.max(onsets_run[x]) for x in range(onsets_run.size)])
        max_duration_orig += 10 # Add some wiggle room

        # Do you want to randomise the onsets (so that the events do not have a
        # fixed order)
        if rand == 1:
            onsets_run = randomise_timing(onsets_runs[run_counter - 1],
                                      )

        # If you want to use different timing then take the order of the data
        # and then create a new timecourse
        onsets_run = extra_isi(onsets_run,
                           added_isi,
                           )
        
        # If necessary, remove all the values greater than the max
        if restrict_overall_duration == 1:
            onsets_run = [onsets_run[x][onsets_run[x] < max_duration_orig] for x in range(
                onsets_run.size)]
            onsets_run = np.asarray(onsets_run)

        # Determine how long the simulated time course is by finding the max of maxs
        last_event = 0
        for node_counter in range(len(onsets_run)):
            if len(onsets_run[node_counter]) > 0 and onsets_run[node_counter].max() > last_event:
                last_event = onsets_run[node_counter].max()    
                
        # How long should you model
        duration = int(last_event + 10)  # Add a decay buffer

        # Preset brain size
        brain_signal = np.zeros([2, int(duration / tr_duration)], dtype='double')
        stimfunc_all = []
        for node_counter in list(range(0, nodes)):

            # Preset the signal
            signal_pattern = np.ones(vector_size)

            # Take the coordinates from the signal template
            for coord_counter in list(range(0, signal_coords.shape[1])):
                signal_pattern[coord_counter] = signal_coords[node_counter,
                                                              coord_counter]

            onsets_node = onsets_run[node_counter]
            
            # Only do it if there are onsets
            if len(onsets_node) > 0:

                # Create the time course for the signal to be generated
                stimfunc = sim.generate_stimfunction(onsets=onsets_node,
                                                     event_durations=event_durations,
                                                     total_time=duration,
                                                     temporal_resolution=temporal_res,
                                                     )

                # Aggregate the timecourse
                if len(stimfunc_all) == 0:
                    stimfunc_all = np.zeros((len(stimfunc), vector_size))
                    for voxel_counter in list(range(0, vector_size)):
                        stimfunc_all[:, voxel_counter] = np.asarray(
                            stimfunc).transpose() * signal_coords[node_counter, voxel_counter]
                else:

                    # Add these elements together
                    temp = np.zeros((len(stimfunc), vector_size))
                    for voxel_counter in list(range(0, vector_size)):
                        temp[:, voxel_counter] = np.asarray(stimfunc).transpose() * \
                                                 signal_coords[node_counter,
                                                               voxel_counter]

                    stimfunc_all += temp

        # After you have gone through all the nodes, convolve the HRF and
        # stimulation for each voxel
        signal_func = sim.convolve_hrf(stimfunction=stimfunc_all,
                                       tr_duration=tr_duration,
                                       temporal_resolution=temporal_res,
                                       )

        # Multiply the convolved responses with their magnitudes (after being
        # scaled)
        for voxel_counter in list(range(0, vector_size)):
            # Reset the range of the function to be appropriate for the
            # stimfunc
            signal_func[:, voxel_counter] *= stimfunc_all[:,
                                             voxel_counter].max()

        # Create the noise
        noise = np.random.randn(np.prod(signal_func.shape)).reshape(
            signal_func.shape) * noise_timecourse

        # Combine the signal and the noise
        brain = signal_func + noise
        # Z score the data
        #brain = zscore(brain.astype('float'), 0)

        # Loop through the nodes
        for node in list(range(0, nodes)):

            node_trs = onsets_run[node]
            if len(node_trs) > 0:
                temp = np.zeros((vector_size, len(node_trs) - 1))
                for tr_counter in list(range(1, len(node_trs))):

                    # When does it onset (first TR is zero so minus 1)
                    onset = int(np.round(node_trs[tr_counter] / tr_duration) +
                                hrf_lag)

                    # Add the TR if it is included when considering the hrf lag
                    if onset < brain.shape[0]:
                        temp[:, tr_counter - 1] = brain[onset, :]

                # Average the TRs
                node_brain[:, node, run_counter - 1] = np.mean(temp, 1)

    # average the brains across runs
    node_brain = np.mean(node_brain, 2)

    return node_brain
Example #28
0
# Iterate through the conditions to make the necessary functions
for cond in list(range(conds)):

    # Generate a volume representing the location and quality of the signal
    volume_static = sim.generate_signal(dimensions=dimensions,
                                        feature_coordinates=coordinates[cond],
                                        feature_type=feature_type,
                                        feature_size=feature_size,
                                        signal_magnitude=signal_magnitude,
                                        )

    # Create the time course for the signal to be generated
    stimfunction_cond = sim.generate_stimfunction(onsets=onsets[cond],
                                                  event_durations=
                                                  event_durations,
                                                  total_time=duration,
                                                  weights=weights[cond],
                                                  )

    # Convolve the HRF with the stimulus sequence
    signal_function = sim.double_gamma_hrf(stimfunction=stimfunction_cond,
                                           tr_duration=tr_duration,
                                           )

    # Multiply the HRF timecourse with the signal
    signal_cond = sim.apply_signal(signal_function=signal_function,
                                   volume_static=volume_static,
                                   )

    # Concatenate all the signal and function files
    if cond == 0:
Example #29
0
def test_generate_stimfunction():

    # Inputs for generate_stimfunction
    onsets = [10, 30, 50, 70, 90]
    event_durations = [6]
    tr_duration = 2
    duration = 100

    # Create the time course for the signal to be generated
    stimfunction = sim.generate_stimfunction(
        onsets=onsets,
        event_durations=event_durations,
        total_time=duration,
    )

    assert stimfunction.shape[0] == duration * 100, "stimfunc incorrect length"
    eventNumber = np.sum(event_durations * len(onsets)) * 100
    assert np.sum(stimfunction) == eventNumber, "Event number"

    # Create the signal function
    signal_function = sim.convolve_hrf(
        stimfunction=stimfunction,
        tr_duration=tr_duration,
    )

    stim_dur = stimfunction.shape[0] / (tr_duration * 100)
    assert signal_function.shape[0] == stim_dur, "The length did not change"

    # Test
    onsets = [0]
    tr_duration = 1
    event_durations = [1]
    stimfunction = sim.generate_stimfunction(
        onsets=onsets,
        event_durations=event_durations,
        total_time=duration,
    )

    signal_function = sim.convolve_hrf(
        stimfunction=stimfunction,
        tr_duration=tr_duration,
    )

    max_response = np.where(signal_function != 0)[0].max()
    assert 25 < max_response <= 30, "HRF has the incorrect length"
    assert np.sum(signal_function < 0) > 0, "No values below zero"

    # Export a stimfunction
    sim.export_3_column(
        stimfunction,
        'temp.txt',
    )

    # Load in the stimfunction
    stimfunc_new = sim.generate_stimfunction(
        onsets=None,
        event_durations=None,
        total_time=duration,
        timing_file='temp.txt',
    )

    assert np.all(stimfunc_new == stimfunction), "Export/import failed"

    # Break the timing precision of the generation
    stimfunc_new = sim.generate_stimfunction(
        onsets=None,
        event_durations=None,
        total_time=duration,
        timing_file='temp.txt',
        temporal_resolution=0.5,
    )

    assert stimfunc_new.sum() == 0, "Temporal resolution not working right"

    # Set the duration to be too short so you should get an error
    onsets = [10, 30, 50, 70, 90]
    event_durations = [5]
    with pytest.raises(ValueError):
        sim.generate_stimfunction(
            onsets=onsets,
            event_durations=event_durations,
            total_time=89,
        )

    # Clip the event offset
    stimfunc_new = sim.generate_stimfunction(
        onsets=onsets,
        event_durations=event_durations,
        total_time=95,
    )
    assert stimfunc_new[-1] == 1, 'Event offset was not clipped'

    # Test exporting a group of participants to an epoch file
    cond_a = sim.generate_stimfunction(
        onsets=onsets,
        event_durations=event_durations,
        total_time=110,
    )

    cond_b = sim.generate_stimfunction(
        onsets=[x + 5 for x in onsets],
        event_durations=event_durations,
        total_time=110,
    )

    stimfunction_group = [np.hstack((cond_a, cond_b))] * 2
    sim.export_epoch_file(
        stimfunction_group,
        'temp.txt',
        tr_duration,
    )

    # Check that convolve throws a warning when the shape is wrong
    sim.convolve_hrf(
        stimfunction=np.hstack((cond_a, cond_b)).T,
        tr_duration=tr_duration,
        temporal_resolution=1,
    )
Example #30
0
def test_generate_noise():

    dimensions = np.array([10, 10, 10])  # What is the size of the brain
    feature_size = [2]
    feature_type = ['cube']
    feature_coordinates = np.array(
        [[5, 5, 5]])
    signal_magnitude = [1]

    # Generate a volume representing the location and quality of the signal
    volume = sim.generate_signal(dimensions=dimensions,
                                 feature_coordinates=feature_coordinates,
                                 feature_type=feature_type,
                                 feature_size=feature_size,
                                 signal_magnitude=signal_magnitude,
                                 )

    # Inputs for generate_stimfunction
    onsets = [10, 30, 50, 70, 90]
    event_durations = [6]
    tr_duration = 2
    duration = 200

    # Create the time course for the signal to be generated
    stimfunction = sim.generate_stimfunction(onsets=onsets,
                                             event_durations=event_durations,
                                             total_time=duration,
                                             )

    signal_function = sim.convolve_hrf(stimfunction=stimfunction,
                                       tr_duration=tr_duration,
                                       )

    # Convolve the HRF with the stimulus sequence
    signal = sim.apply_signal(signal_function=signal_function,
                              volume_signal=volume,
                              )

    # Generate the mask of the signal
    mask, template = sim.mask_brain(signal, mask_threshold=0.1)

    assert min(mask[mask > 0]) > 0.1, "Mask thresholding did not work"
    assert len(np.unique(template) > 2), "Template creation did not work"

    stimfunction_tr = stimfunction[::int(tr_duration * 100)]
    # Create the noise volumes (using the default parameters)
    noise = sim.generate_noise(dimensions=dimensions,
                               stimfunction_tr=stimfunction_tr,
                               tr_duration=tr_duration,
                               template=template,
                               mask=mask,
                               )

    assert signal.shape == noise.shape, "The dimensions of signal and noise " \
                                        "the same"

    assert np.std(signal) < np.std(noise), "Noise was not created"

    noise = sim.generate_noise(dimensions=dimensions,
                               stimfunction_tr=stimfunction_tr,
                               tr_duration=tr_duration,
                               template=template,
                               mask=mask,
                               noise_dict={'sfnr': 10000, 'snr': 10000},
                               )

    system_noise = np.std(noise[mask > 0], 1).mean()

    assert system_noise <= 0.1, "Noise strength could not be manipulated"
Example #31
0
    dimensions=dimensions,
    feature_coordinates=coordinates_B,
    feature_type=feature_type,
    feature_size=feature_size,
    signal_magnitude=signal_magnitude,
)

# Visualize the signal that was generated for condition A
fig = plt.figure()
sim.plot_brain(fig, volume_static_A)
plt.show()

# Create the time course for the signal to be generated
stimfunction_A = sim.generate_stimfunction(
    onsets=onsets_A,
    event_durations=event_durations,
    total_time=duration,
)

stimfunction_B = sim.generate_stimfunction(
    onsets=onsets_B,
    event_durations=event_durations,
    total_time=duration,
)

# Convolve the HRF with the stimulus sequence
signal_function_A = sim.double_gamma_hrf(
    stimfunction=stimfunction_A,
    tr_duration=tr_duration,
)
Example #32
0
def test_apply_signal():

    dimensions = np.array([10, 10, 10])  # What is the size of the brain
    feature_size = [2]
    feature_type = ['cube']
    feature_coordinates = np.array([[5, 5, 5]])
    signal_magnitude = [30]

    # Generate a volume representing the location and quality of the signal
    volume = sim.generate_signal(
        dimensions=dimensions,
        feature_coordinates=feature_coordinates,
        feature_type=feature_type,
        feature_size=feature_size,
        signal_magnitude=signal_magnitude,
    )

    # Inputs for generate_stimfunction
    onsets = [10, 30, 50, 70, 90]
    event_durations = [6]
    tr_duration = 2
    duration = 100

    # Create the time course for the signal to be generated
    stimfunction = sim.generate_stimfunction(
        onsets=onsets,
        event_durations=event_durations,
        total_time=duration,
    )

    signal_function = sim.convolve_hrf(
        stimfunction=stimfunction,
        tr_duration=tr_duration,
    )

    # Check that you can compute signal change appropriately
    # Preset a bunch of things
    stimfunction_tr = stimfunction[::int(tr_duration * 100)]
    mask, template = sim.mask_brain(dimensions, mask_self=False)
    noise_dict = sim._noise_dict_update({})
    noise = sim.generate_noise(dimensions=dimensions,
                               stimfunction_tr=stimfunction_tr,
                               tr_duration=tr_duration,
                               template=template,
                               mask=mask,
                               noise_dict=noise_dict,
                               iterations=[0, 0])
    coords = feature_coordinates[0]
    noise_function_a = noise[coords[0], coords[1], coords[2], :]
    noise_function_a = noise_function_a.reshape(duration // tr_duration, 1)

    noise_function_b = noise[coords[0] + 1, coords[1], coords[2], :]
    noise_function_b = noise_function_b.reshape(duration // tr_duration, 1)

    # Create the calibrated signal with PSC
    method = 'PSC'
    sig_a = sim.compute_signal_change(
        signal_function,
        noise_function_a,
        noise_dict,
        [0.5],
        method,
    )
    sig_b = sim.compute_signal_change(
        signal_function,
        noise_function_a,
        noise_dict,
        [1.0],
        method,
    )

    assert sig_b.max() / sig_a.max() == 2, 'PSC modulation failed'

    # Create the calibrated signal with SFNR
    method = 'SFNR'
    sig_a = sim.compute_signal_change(
        signal_function,
        noise_function_a,
        noise_dict,
        [0.5],
        method,
    )
    scaled_a = sig_a / (noise_function_a.mean() / noise_dict['sfnr'])
    sig_b = sim.compute_signal_change(
        signal_function,
        noise_function_b,
        noise_dict,
        [1.0],
        method,
    )
    scaled_b = sig_b / (noise_function_b.mean() / noise_dict['sfnr'])

    assert scaled_b.max() / scaled_a.max() == 2, 'SFNR modulation failed'

    # Create the calibrated signal with CNR_Amp/Noise-SD
    method = 'CNR_Amp/Noise-SD'
    sig_a = sim.compute_signal_change(
        signal_function,
        noise_function_a,
        noise_dict,
        [0.5],
        method,
    )
    scaled_a = sig_a / noise_function_a.std()
    sig_b = sim.compute_signal_change(
        signal_function,
        noise_function_b,
        noise_dict,
        [1.0],
        method,
    )
    scaled_b = sig_b / noise_function_b.std()

    assert scaled_b.max() / scaled_a.max() == 2, 'CNR_Amp modulation failed'

    # Create the calibrated signal with CNR_Amp/Noise-Var_dB
    method = 'CNR_Amp2/Noise-Var_dB'
    sig_a = sim.compute_signal_change(
        signal_function,
        noise_function_a,
        noise_dict,
        [0.5],
        method,
    )
    scaled_a = np.log(sig_a.max() / noise_function_a.std())
    sig_b = sim.compute_signal_change(
        signal_function,
        noise_function_b,
        noise_dict,
        [1.0],
        method,
    )
    scaled_b = np.log(sig_b.max() / noise_function_b.std())

    assert np.round(scaled_b / scaled_a) == 2, 'CNR_Amp dB modulation failed'

    # Create the calibrated signal with CNR_Signal-SD/Noise-SD
    method = 'CNR_Signal-SD/Noise-SD'
    sig_a = sim.compute_signal_change(
        signal_function,
        noise_function_a,
        noise_dict,
        [0.5],
        method,
    )
    scaled_a = sig_a.std() / noise_function_a.std()
    sig_b = sim.compute_signal_change(
        signal_function,
        noise_function_a,
        noise_dict,
        [1.0],
        method,
    )
    scaled_b = sig_b.std() / noise_function_a.std()

    assert (scaled_b / scaled_a) == 2, 'CNR signal modulation failed'

    # Create the calibrated signal with CNR_Amp/Noise-Var_dB
    method = 'CNR_Signal-Var/Noise-Var_dB'
    sig_a = sim.compute_signal_change(
        signal_function,
        noise_function_a,
        noise_dict,
        [0.5],
        method,
    )

    scaled_a = np.log(sig_a.std() / noise_function_a.std())
    sig_b = sim.compute_signal_change(
        signal_function,
        noise_function_b,
        noise_dict,
        [1.0],
        method,
    )
    scaled_b = np.log(sig_b.std() / noise_function_b.std())

    assert np.round(scaled_b / scaled_a) == 2, 'CNR signal dB modulation ' \
                                               'failed'

    # Convolve the HRF with the stimulus sequence
    signal = sim.apply_signal(
        signal_function=signal_function,
        volume_signal=volume,
    )

    assert signal.shape == (dimensions[0], dimensions[1], dimensions[2],
                            duration / tr_duration), "The output is the " \
                                                     "wrong size"

    signal = sim.apply_signal(
        signal_function=stimfunction,
        volume_signal=volume,
    )

    assert np.any(signal == signal_magnitude), "The stimfunction is not binary"

    # Check that there is an error if the number of signal voxels doesn't
    # match the number of non zero brain voxels
    with pytest.raises(IndexError):
        sig_vox = (volume > 0).sum()
        vox_pattern = np.tile(stimfunction, (1, sig_vox - 1))
        sim.apply_signal(
            signal_function=vox_pattern,
            volume_signal=volume,
        )
Example #33
0
    dimensions=dimensions,
    feature_coordinates=feature_coordinates_B,
    feature_type=feature_type,
    feature_size=feature_size,
    signal_magnitude=signal_magnitude,
)

# Visualize the signal that was generated for condition A
fig = plt.figure()
sim.plot_brain(fig, volume_static_A)
plt.show()

# Create the time course for the signal to be generated
stimfunction_A = sim.generate_stimfunction(
    onsets=onsets_A,
    event_durations=event_durations,
    total_time=duration,
    tr_duration=tr_duration,
)

stimfunction_B = sim.generate_stimfunction(
    onsets=onsets_B,
    event_durations=event_durations,
    total_time=duration,
    tr_duration=tr_duration,
)

# Convolve the HRF with the stimulus sequence
signal_function_A = sim.double_gamma_hrf(stimfunction=stimfunction_A, )

signal_function_B = sim.double_gamma_hrf(stimfunction=stimfunction_B, )
Example #34
0
                                      feature_coordinates=coordinates_B,
                                      feature_type=feature_type,
                                      feature_size=feature_size,
                                      signal_magnitude=signal_magnitude,
                                      )

# Visualize the signal that was generated for condition A
fig = plt.figure()
sim.plot_brain(fig,
               volume_signal_A)
plt.show()

# Create the time course for the signal to be generated
stimfunction_A = sim.generate_stimfunction(onsets=onsets_A,
                                           event_durations=event_durations,
                                           total_time=duration,
                                           temporal_resolution=temporal_res,
                                           )

stimfunction_B = sim.generate_stimfunction(onsets=onsets_B,
                                           event_durations=event_durations,
                                           total_time=duration,
                                           temporal_resolution=temporal_res,
                                           )

# Convolve the HRF with the stimulus sequence
signal_function_A = sim.convolve_hrf(stimfunction=stimfunction_A,
                                     tr_duration=tr_duration,
                                     temporal_resolution=temporal_res,
                                     )
Example #35
0
def test_generate_noise():

    dimensions = np.array([10, 10, 10])  # What is the size of the brain
    feature_size = [2]
    feature_type = ['cube']
    feature_coordinates = np.array([[5, 5, 5]])
    signal_magnitude = [1]

    # Generate a volume representing the location and quality of the signal
    volume = sim.generate_signal(
        dimensions=dimensions,
        feature_coordinates=feature_coordinates,
        feature_type=feature_type,
        feature_size=feature_size,
        signal_magnitude=signal_magnitude,
    )

    # Inputs for generate_stimfunction
    onsets = [10, 30, 50, 70, 90]
    event_durations = [6]
    tr_duration = 2
    duration = 200

    # Create the time course for the signal to be generated
    stimfunction = sim.generate_stimfunction(
        onsets=onsets,
        event_durations=event_durations,
        total_time=duration,
    )

    signal_function = sim.convolve_hrf(
        stimfunction=stimfunction,
        tr_duration=tr_duration,
    )

    # Convolve the HRF with the stimulus sequence
    signal = sim.apply_signal(
        signal_function=signal_function,
        volume_signal=volume,
    )

    # Generate the mask of the signal
    mask, template = sim.mask_brain(signal, mask_self=None)

    assert min(mask[mask > 0]) > 0.1, "Mask thresholding did not work"
    assert len(np.unique(template) > 2), "Template creation did not work"

    stimfunction_tr = stimfunction[::int(tr_duration * 100)]

    # Create the noise volumes (using the default parameters)
    noise = sim.generate_noise(
        dimensions=dimensions,
        stimfunction_tr=stimfunction_tr,
        tr_duration=tr_duration,
        template=template,
        mask=mask,
        iterations=[1, 0],
    )

    assert signal.shape == noise.shape, "The dimensions of signal and noise " \
                                        "the same"

    noise_high = sim.generate_noise(
        dimensions=dimensions,
        stimfunction_tr=stimfunction_tr,
        tr_duration=tr_duration,
        template=template,
        mask=mask,
        noise_dict={
            'sfnr': 50,
            'snr': 25
        },
        iterations=[1, 0],
    )

    noise_low = sim.generate_noise(
        dimensions=dimensions,
        stimfunction_tr=stimfunction_tr,
        tr_duration=tr_duration,
        template=template,
        mask=mask,
        noise_dict={
            'sfnr': 100,
            'snr': 25
        },
        iterations=[1, 0],
    )

    system_high = np.std(noise_high[mask > 0], 1).mean()
    system_low = np.std(noise_low[mask > 0], 1).mean()

    assert system_low < system_high, "SFNR noise could not be manipulated"

    # Check that you check for the appropriate template values
    with pytest.raises(ValueError):
        sim.generate_noise(
            dimensions=dimensions,
            stimfunction_tr=stimfunction_tr,
            tr_duration=tr_duration,
            template=template * 2,
            mask=mask,
            noise_dict={},
        )

    # Check that iterations does what it should
    sim.generate_noise(
        dimensions=dimensions,
        stimfunction_tr=stimfunction_tr,
        tr_duration=tr_duration,
        template=template,
        mask=mask,
        noise_dict={},
        iterations=[0, 0],
    )

    sim.generate_noise(
        dimensions=dimensions,
        stimfunction_tr=stimfunction_tr,
        tr_duration=tr_duration,
        template=template,
        mask=mask,
        noise_dict={},
        iterations=None,
    )

    # Test drift noise
    trs = 1000
    period = 100
    drift = sim._generate_noise_temporal_drift(
        trs,
        tr_duration,
        'sine',
        period,
    )

    # Check that the max frequency is the appropriate frequency
    power = abs(np.fft.fft(drift))[1:trs // 2]
    freq = np.linspace(1, trs // 2 - 1, trs // 2 - 1) / trs
    period_freq = np.where(freq == 1 / (period // tr_duration))
    max_freq = np.argmax(power)

    assert period_freq == max_freq, 'Max frequency is not where it should be'

    # Do the same but now with cosine basis functions, answer should be close
    drift = sim._generate_noise_temporal_drift(
        trs,
        tr_duration,
        'discrete_cos',
        period,
    )

    # Check that the appropriate frequency is peaky (may not be the max)
    power = abs(np.fft.fft(drift))[1:trs // 2]
    freq = np.linspace(1, trs // 2 - 1, trs // 2 - 1) / trs
    period_freq = np.where(freq == 1 / (period // tr_duration))[0][0]

    assert power[period_freq] > power[period_freq + 1], 'Power is low'
    assert power[period_freq] > power[period_freq - 1], 'Power is low'

    # Check it runs fine
    drift = sim._generate_noise_temporal_drift(
        50,
        tr_duration,
        'discrete_cos',
        period,
    )

    # Check it runs fine
    drift = sim._generate_noise_temporal_drift(
        300,
        tr_duration,
        'cos_power_drop',
        period,
    )

    # Check that when the TR is greater than the period it errors
    with pytest.raises(ValueError):
        sim._generate_noise_temporal_drift(30, 10, 'cos_power_drop', 5)

    # Test physiological noise (using unrealistic parameters so that it's easy)
    timepoints = list(np.linspace(0, (trs - 1) * tr_duration, trs))
    resp_freq = 0.2
    heart_freq = 1.17
    phys = sim._generate_noise_temporal_phys(
        timepoints,
        resp_freq,
        heart_freq,
    )

    # Check that the max frequency is the appropriate frequency
    power = abs(np.fft.fft(phys))[1:trs // 2]
    freq = np.linspace(1, trs // 2 - 1, trs // 2 - 1) / (trs * tr_duration)
    peaks = (power > (power.mean() + power.std()))  # Where are the peaks
    peak_freqs = freq[peaks]

    assert np.any(resp_freq == peak_freqs), 'Resp frequency not found'
    assert len(peak_freqs) == 2, 'Two peaks not found'

    # Test task noise
    sim._generate_noise_temporal_task(
        stimfunction_tr,
        motion_noise='gaussian',
    )
    sim._generate_noise_temporal_task(
        stimfunction_tr,
        motion_noise='rician',
    )

    # Test ARMA noise
    with pytest.raises(ValueError):
        noise_dict = {'fwhm': 4, 'auto_reg_rho': [1], 'ma_rho': [1, 1]}
        sim._generate_noise_temporal_autoregression(
            stimfunction_tr,
            noise_dict,
            dimensions,
            mask,
        )

    # Generate spatial noise
    vol = sim._generate_noise_spatial(np.array([10, 10, 10, trs]))
    assert len(vol.shape) == 3, 'Volume was not reshaped to ignore TRs'

    # Switch some of the noise types on
    noise_dict = dict(physiological_sigma=1,
                      drift_sigma=1,
                      task_sigma=1,
                      auto_reg_sigma=0)
    sim.generate_noise(
        dimensions=dimensions,
        stimfunction_tr=stimfunction_tr,
        tr_duration=tr_duration,
        template=template,
        mask=mask,
        noise_dict=noise_dict,
        iterations=[0, 0],
    )
Example #36
0
def test_generate_noise():

    dimensions = np.array([64, 64, 36])  # What is the size of the brain
    feature_size = [2]
    feature_type = ['cube']
    feature_coordinates = np.array([[32, 32, 18]])
    signal_magnitude = [30]

    # Generate a volume representing the location and quality of the signal
    volume_static = sim.generate_signal(
        dimensions=dimensions,
        feature_coordinates=feature_coordinates,
        feature_type=feature_type,
        feature_size=feature_size,
        signal_magnitude=signal_magnitude,
    )

    # Inputs for generate_stimfunction
    onsets = [10, 30, 50, 70, 90]
    event_durations = [6]
    tr_duration = 2
    duration = 100

    # Create the time course for the signal to be generated
    stimfunction = sim.generate_stimfunction(
        onsets=onsets,
        event_durations=event_durations,
        total_time=duration,
        tr_duration=tr_duration,
    )

    signal_function = sim.double_gamma_hrf(stimfunction=stimfunction, )

    # Convolve the HRF with the stimulus sequence
    signal = sim.apply_signal(
        signal_function=signal_function,
        volume_static=volume_static,
    )

    # Create the noise volumes (using the default parameters)

    noise = sim.generate_noise(
        dimensions=dimensions,
        stimfunction=stimfunction,
        tr_duration=tr_duration,
    )

    assert signal.shape == noise.shape, "The dimensions of signal " \
                                                  "and noise the same"

    Z_noise = sim._generate_noise_temporal(stimfunction, tr_duration, 1)
    noise = sim._generate_noise_temporal(stimfunction, tr_duration, 0)

    assert np.std(Z_noise) < np.std(noise), "Z scoring is not working"

    # Combine the signal and the noise
    volume = signal + noise

    assert np.std(signal) < np.std(noise), "Noise was not created"

    noise = sim.generate_noise(dimensions=dimensions,
                               stimfunction=stimfunction,
                               tr_duration=tr_duration,
                               noise_strength=[0, 0, 0])

    assert np.sum(noise) == 0, "Noise strength could not be manipulated"
    assert np.std(noise) == 0, "Noise strength could not be manipulated"
Example #37
0
def test_calc_noise():

    # Inputs for functions
    onsets = [10, 30, 50, 70, 90]
    event_durations = [6]
    tr_duration = 2
    duration = 200
    temporal_res = 100
    tr_number = int(np.floor(duration / tr_duration))
    dimensions_tr = np.array([10, 10, 10, tr_number])

    # Preset the noise dict
    nd_orig = sim._noise_dict_update({})

    # Create the time course for the signal to be generated
    stimfunction = sim.generate_stimfunction(
        onsets=onsets,
        event_durations=event_durations,
        total_time=duration,
        temporal_resolution=temporal_res,
    )

    # Mask the volume to be the same shape as a brain
    mask, template = sim.mask_brain(dimensions_tr, mask_self=None)
    stimfunction_tr = stimfunction[::int(tr_duration * temporal_res)]

    nd_orig['matched'] = 0
    noise = sim.generate_noise(
        dimensions=dimensions_tr[0:3],
        stimfunction_tr=stimfunction_tr,
        tr_duration=tr_duration,
        template=template,
        mask=mask,
        noise_dict=nd_orig,
    )

    # Check the spatial noise match
    nd_orig['matched'] = 1
    noise_matched = sim.generate_noise(dimensions=dimensions_tr[0:3],
                                       stimfunction_tr=stimfunction_tr,
                                       tr_duration=tr_duration,
                                       template=template,
                                       mask=mask,
                                       noise_dict=nd_orig,
                                       iterations=[50, 0])

    # Calculate the noise parameters from this newly generated volume
    nd_new = sim.calc_noise(noise, mask, template)
    nd_matched = sim.calc_noise(noise_matched, mask, template)

    # Check the values are reasonable"
    assert nd_new['snr'] > 0, 'snr out of range'
    assert nd_new['sfnr'] > 0, 'sfnr out of range'
    assert nd_new['auto_reg_rho'][0] > 0, 'ar out of range'

    # Check that the dilation increases SNR
    no_dilation_snr = sim._calc_snr(
        noise_matched,
        mask,
        dilation=0,
        reference_tr=tr_duration,
    )

    assert nd_new['snr'] > no_dilation_snr, "Dilation did not increase SNR"

    # Check that template size is in bounds
    with pytest.raises(ValueError):
        sim.calc_noise(noise, mask, template * 2)

    # Check that Mask is set is checked
    with pytest.raises(ValueError):
        sim.calc_noise(noise, None, template)

    # Check that it can deal with missing noise parameters
    temp_nd = sim.calc_noise(noise, mask, template, noise_dict={})
    assert temp_nd['voxel_size'][0] == 1, 'Default voxel size not set'

    temp_nd = sim.calc_noise(noise, mask, template, noise_dict=None)
    assert temp_nd['voxel_size'][0] == 1, 'Default voxel size not set'

    # Check that the fitting worked
    snr_diff = abs(nd_orig['snr'] - nd_new['snr'])
    snr_diff_match = abs(nd_orig['snr'] - nd_matched['snr'])
    assert snr_diff > snr_diff_match, 'snr fit incorrectly'

    # Test that you can generate rician and exponential noise
    sim._generate_noise_system(
        dimensions_tr,
        1,
        1,
        spatial_noise_type='exponential',
        temporal_noise_type='rician',
    )

    # Check the temporal noise match
    nd_orig['matched'] = 1
    noise_matched = sim.generate_noise(dimensions=dimensions_tr[0:3],
                                       stimfunction_tr=stimfunction_tr,
                                       tr_duration=tr_duration,
                                       template=template,
                                       mask=mask,
                                       noise_dict=nd_orig,
                                       iterations=[0, 50])

    nd_matched = sim.calc_noise(noise_matched, mask, template)

    sfnr_diff = abs(nd_orig['sfnr'] - nd_new['sfnr'])
    sfnr_diff_match = abs(nd_orig['sfnr'] - nd_matched['sfnr'])
    assert sfnr_diff > sfnr_diff_match, 'sfnr fit incorrectly'

    ar1_diff = abs(nd_orig['auto_reg_rho'][0] - nd_new['auto_reg_rho'][0])
    ar1_diff_match = abs(nd_orig['auto_reg_rho'][0] -
                         nd_matched['auto_reg_rho'][0])
    assert ar1_diff > ar1_diff_match, 'AR1 fit incorrectly'

    # Check that you can calculate ARMA for a single voxel
    vox = noise[5, 5, 5, :]
    arma = sim._calc_ARMA_noise(
        vox,
        None,
        sample_num=2,
    )
    assert len(arma) == 2, "Two outputs not given by ARMA"