You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have been running the fmrisim jupyter notebook using my own data. It went well until I hit this cell:
# Specify the parameters for signalsignal_method='CNR_Amp/Noise-SD'signal_magnitude= [0.5]
# Where in the brain are there stimulus evoked voxelssignal_idxs=np.where(signal_volume==1)
# Pull out the voxels corresponding to the noise volumenoise_func=noise[signal_idxs[0], signal_idxs[1], signal_idxs[2], :].T# Compute the signal appropriate scaledsignal_func_scaled=fmrisim.compute_signal_change(signal_func,
noise_func,
noise_dict,
magnitude=signal_magnitude,
method=signal_method)
That gave me this error:
ValueError Traceback (most recent call last)/scratch/marzwi/slurm_job_55885/ipykernel_2104266/2965812987.py in <module> 13 noise_dict, 14 magnitude=signal_magnitude,---> 15 method=signal_method)~/PycharmProjects/wp15/BIDScramble/bidscramble/fmrisim.py in compute_signal_change(signal_function, noise_function, noise_dict, magnitude, method) 2856 if signal_function.shape != noise_function.shape: 2857 msg = 'noise_function is not the same size as signal_function'-> 2858 raise ValueError(msg) 2859 2860 # Scale all signals that to have a range of -1 to 1. This is so that any values less than this will be scaled appropriatelyValueError: noise_function is not the same size as signal_function
If I compare it to this input signal size I see that signal_func is one element too long:
However, if I set burn_in = 0 in the brainiak fmrisim example notebook (in the In[19] cell), then the dimensions are correct. That seems like a bug / the root of the problem, right?
# Set up stimulus event time course parametersevent_duration=2# How long is each eventisi=7# What is the time between each eventburn_in=1# How long before the first event
Yes, I think this may be a bug (in the demo). I think this line total_time = int(dim[3] * tr) + burn_in should not include burn_in or it should be removed when feeding to total_time of generate_stimfunction`. For your own task, I suggest using the timing of your own design instead of strictly following the demo.
@CameronTEllis Would you mind taking a look at the Jupyter notebook demo and confirm whether simply replacing total_time = int(dim[3] * tr) + burn_in with total_time = int(dim[3] * tr) or making burn_in = 0 should be correct?
Hi @marcelzwiers and @lcnature, thanks for working on this, you are right: burn_in should be set to zero in this code. Previously, the compute_signal_change didn't have the shape size check, so we didn't have this issue previously.
I have made a new PR (#542) for the code with no burn_in. I could have changed the code so that there is an equivalent burn in for generating the noise; however, that is a step of complexity that is unnecessary.
When SNR is low, Rician noise is a good estimate of background noise data (Gudbjartsson, & Patz, 1995). However if you look at the distribution of non-brain voxel values averaged across time (i.e., the template) then you see that this is also rician, suggesting that most of the rician noise is a result of the structure in the background of the brain (e.g. the baseline MR of the head coil or skull). If you subtract this baseline then the noise becomes approximately gaussian, especially in the regions far from the brain (which is what the calc_noise algorithm considers when calculating SNR). Hence the machine noise here is Gaussian added to an inherently Rician baseline.
I cannot make any sense of this? Rician noise in MR is well understood, which is as you may well know just Gaussian noise during the acquisition of the (complex) k-space datapoints (the total signal being the vector sum of the MR signal vector + the random noise vector). After Fourier transformation of the k-space data to (magnitude) image space, the complex Gaussian noise emerges as Rician magnitude noise. The higher the SNR, the larger the distance between the reference point and the center of the bivariate Rice distribution in the image domain, and then the distribution looks more and more like a Gaussian one. There are excellent methods out there to estimate (and transform) the Rician noise level in MR (especially in the diffusion-weighted MR literature, which always suffers heavily from Rician noise in their brain signals). Is fmrisim still being developed?
This is a great point. I agree that we took a heuristic shortcut and that there are better methods to directly relate SNR to the noise distribution.
Yes, fmrisim is still in development, albeit slowly. There are a few additions that I intend to make in the near term. I welcome any suggestions you have, or better yet, any contributions you wish to make. If you would like to talk about it, I am happy to chat over zoom.
Activity
marcelzwiers commentedon Jul 4, 2024
I am using the latest code from github
lcnature commentedon Jul 4, 2024
Hi @marcelzwiers can you show how
signal_funcis produced before this part of code?marcelzwiers commentedon Jul 4, 2024
marcelzwiers commentedon Jul 4, 2024
See here:
https://github.com/brainiak/brainiak/blob/master/examples/utils/fmrisim_multivariate_example.ipynb
lcnature commentedon Jul 4, 2024
Thanks! What is the shape of
stimfunc_weighted, the values oftrandtemporal_res?marcelzwiers commentedon Jul 5, 2024
However, if I set
burn_in = 0in the brainiak fmrisim example notebook (in theIn[19]cell), then the dimensions are correct. That seems like a bug / the root of the problem, right?[-]fmrisim wrong dimensions[/-][+]fmrisim notebook example: wrong dimensions[/+]lcnature commentedon Jul 5, 2024
Yes, I think this may be a bug (in the demo). I think this line
total_time = int(dim[3] * tr) + burn_inshould not includeburn_inor it should be removed when feeding tototal_time ofgenerate_stimfunction`. For your own task, I suggest using the timing of your own design instead of strictly following the demo.@CameronTEllis Would you mind taking a look at the Jupyter notebook demo and confirm whether simply replacing
total_time = int(dim[3] * tr) + burn_inwithtotal_time = int(dim[3] * tr)or makingburn_in = 0should be correct?CameronTEllis commentedon Jul 5, 2024
Hi @marcelzwiers and @lcnature, thanks for working on this, you are right:
burn_inshould be set to zero in this code. Previously, thecompute_signal_changedidn't have the shape size check, so we didn't have this issue previously.I have made a new PR (#542) for the code with no
burn_in. I could have changed the code so that there is an equivalent burn in for generating the noise; however, that is a step of complexity that is unnecessary.marcelzwiers commentedon Jul 8, 2024
In the same notebook it is stated:
I cannot make any sense of this? Rician noise in MR is well understood, which is as you may well know just Gaussian noise during the acquisition of the (complex) k-space datapoints (the total signal being the vector sum of the MR signal vector + the random noise vector). After Fourier transformation of the k-space data to (magnitude) image space, the complex Gaussian noise emerges as Rician magnitude noise. The higher the SNR, the larger the distance between the reference point and the center of the bivariate Rice distribution in the image domain, and then the distribution looks more and more like a Gaussian one. There are excellent methods out there to estimate (and transform) the Rician noise level in MR (especially in the diffusion-weighted MR literature, which always suffers heavily from Rician noise in their brain signals). Is fmrisim still being developed?
CameronTEllis commentedon Jul 8, 2024
Hi Marcel,
This is a great point. I agree that we took a heuristic shortcut and that there are better methods to directly relate SNR to the noise distribution.
Yes, fmrisim is still in development, albeit slowly. There are a few additions that I intend to make in the near term. I welcome any suggestions you have, or better yet, any contributions you wish to make. If you would like to talk about it, I am happy to chat over zoom.