Example #1
0
# Combine the signals from the two conditions
signal = signal_A + signal_B

# Combine the stim functions
stimfunction = list(np.add(stimfunction_A, stimfunction_B))
stimfunction_tr = stimfunction[::int(tr_duration * temporal_res)]

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

# Mask the signal to the shape of a brain (attenuates signal according to grey
# matter likelihood)
signal *= mask.reshape(dimensions[0], dimensions[1], dimensions[2], 1)

# Generate original noise dict for comparison later
orig_noise_dict = sim._noise_dict_update({})

# Create the noise volumes (using the default parameters
noise = sim.generate_noise(dimensions=dimensions,
                           stimfunction_tr=stimfunction_tr,
                           tr_duration=tr_duration,
                           mask=mask,
                           template=template,
                           noise_dict=orig_noise_dict,
                           )

# Standardize the signal activity to make it percent signal change
mean_act = (mask * orig_noise_dict['max_activity']).sum() / (mask > 0).sum()
signal = signal * mean_act / 100

# Combine the signal and the noise
Example #2
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 #3
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 #4
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 #5
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 #6
0
# Combine the signals from the two conditions
signal = signal_A + signal_B

# Combine the stim functions
stimfunction = list(np.add(stimfunction_A, stimfunction_B))
stimfunction_tr = stimfunction[::int(tr_duration * temporal_res)]

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

# Mask the signal to the shape of a brain (attenuates signal according to grey
# matter likelihood)
signal *= mask

# Generate original noise dict for comparison later
orig_noise_dict = sim._noise_dict_update({})

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

# Standardize the signal activity to make it percent signal change
mean_act = (mask * orig_noise_dict['max_activity']).sum() / (mask > 0).sum()
signal = signal * mean_act / 100

# Combine the signal and the noise