elliohow / fMRI_ROI_Analysis_Tool

An analysis tool that uses per-voxel statistical maps in conjunction with FSL atlases to create per-region statistical maps. Current usage includes the creation of regional maps of temporal signal to noise ratio.
Apache License 2.0
11 stars 4 forks source link

Add dimension check for pandas dataframe input #41

Closed ZeitgeberH closed 1 year ago

ZeitgeberH commented 1 year ago

The function compute_rsquare_regression may fail when the voxel_data do not have enough entries. This happens when fRAT calculate percentage change statistics during test analysis; It was OK till it reached for cingulate gyrus. See the traceback output at the end.

def compute_rsquare_regression(voxel_data, r_square_data, r_square_type, glm_formula_type):
    # GLM
    voxel_data = sm.add_constant(voxel_data)
    voxel_df = pd.DataFrame(columns=['Intercept', 'Voxels'], data=voxel_data)

Calculating Frontal Medial Cortex statistics (main effects).

All sessions below minimum voxel count. Skipping statistics for this ROI.

Calculating Cingulate Gyrus, posterior division statistics (main effects).

Main effect t-test results Variable contrast tstat pvalue df Mean difference (x1 - x2) Cohen's d 0 (Within-subjects) Multiband: 1 v 3 No participants remaining after balancing data... NaN NaN NaN NaN 1 (Within-subjects) Multiband: 3 v 4 Parameters not equal, analysis not ran NaN NaN NaN NaN 2 (Within-subjects) SENSE: 1.5 v 2.0 Parameters not equal, analysis not ran NaN NaN NaN NaN

/home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/scipy/stats/_axis_nan_policy.py:502: RuntimeWarning: Precision loss occurred in moment calculation due to catastrophic cancellation. This occurs when the data are nearly identical. Results may be unreliable. /home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/scipy/stats/_stats_py.py:1214: RuntimeWarning: divide by zero encountered in true_divide /home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/scipy/stats/_stats_py.py:1214: RuntimeWarning: invalid value encountered in double_scalars Simple effect t-test results Controlled variables Variable contrast tstat pvalue df Mean difference (x1 - x2) Cohen's d 0 {'sense': '1.5'} (Within-subjects) Multiband: 1 v 3 One participant not sufficient to run statisti... NaN 0 2.96457 NaN

Exception in Tkinter callback Traceback (most recent call last): File "/home/mlk/anaconda3/envs/frat310/lib/python3.10/tkinter/init.py", line 1921, in call return self.func(*args) File "/home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/fRAT/main.py", line 403, in self.setattr(name, ttk.Button(self.settings_frame, command=lambda: func(self))) File "/home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/fRAT/main.py", line 858, in run_tests fRAT('test_config.toml', path_to_example_data) File "/home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/fRAT/nogui.py", line 41, in fRAT statistics_main(config, config_path, config_filename) File "/home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/fRAT/utils/statistics.py", line 114, in main statistics(param_queries, critical_params) File "/home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/fRAT/utils/statistics.py", line 319, in statistics roi_statistics(critical_params, rois_below_max_r2_thresh, File "/home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/fRAT/utils/statistics.py", line 422, in roi_statistics compute_rsquare_regression(voxel_data, r_square_dict[rsquare_type], rsquare_type, glm_formula_type) File "/home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/fRAT/utils/statistics.py", line 445, in compute_rsquare_regression voxel_df = pd.DataFrame(columns=['Intercept', 'Voxels'], data=voxel_data) File "/home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/pandas/core/frame.py", line 722, in init mgr = ndarray_to_mgr( File "/home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/pandas/core/internals/construction.py", line 349, in ndarray_to_mgr _check_values_indices_shape_match(values, index, columns) File "/home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/pandas/core/internals/construction.py", line 420, in _check_values_indices_shape_match raise ValueError(f"Shape of passed values is {passed}, indices imply {implied}") ValueError: Shape of passed values is (1, 1), indices imply (1, 2)

elliohow commented 1 year ago

I'm not able to replicate this error, however as the model needs to converge in order to add the data to the voxel_data array, statsmodels won't add a constant to an array of shape (1, 1), and the shape of my voxel_data array was (2, 1) before adding the constant, it looks like the model successfully converged on my machine for one more ROI than yours. I've increased the number of ROIs that the linear mixed model is used on to lower the chance of only one ROI being passed to voxel_data, and added a dimension check to the function. Version 1.3.2 should now fix this issue: 75cd74c4d28a16e524987220c2e81cac72996a56

ZeitgeberH commented 1 year ago

OK. I upgraded fRAT to 1.3.2. Now it asks for location for output folder after creating the statistic map. I set the path to somewhere outside the data folder, then it gets an error. Should I put it inside the data folder?


--- Statistics ---

Select the directory output by the fRAT. Selected directory: /home/mlk/Documents Exception in Tkinter callback Traceback (most recent call last): File "/home/mlk/anaconda3/envs/frat310/lib/python3.10/tkinter/init.py", line 1921, in call return self.func(*args) File "/home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/fRAT/main.py", line 403, in self.setattr(name, ttk.Button(self.settings_frame, command=lambda: func(self))) File "/home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/fRAT/main.py", line 858, in run_tests fRAT('test_config.toml', path_to_example_data) File "/home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/fRAT/nogui.py", line 41, in fRAT statistics_main(config, config_path, config_filename) File "/home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/fRAT/utils/statistics.py", line 107, in main stats_setup(config_path, config_filename) File "/home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/fRAT/utils/statistics.py", line 131, in stats_setup shutil.copyfile(f"{os.getcwd()}/../statisticsOptions.csv", f"{STATISTICS_PATH}/copy_statisticsOptions.csv") File "/home/mlk/anaconda3/envs/frat310/lib/python3.10/shutil.py", line 254, in copyfile with open(src, 'rb') as fsrc: FileNotFoundError: [Errno 2] No such file or directory: '/home/mlk/Documents/../statisticsOptions.csv'

elliohow commented 1 year ago

Asking for the location of the output folder is normal behaviour if running the statistics or figures step without the analysis step (in case a user wants to run these steps separately), but shouldn't occur in the installation testing. When testing the error you encountered before, for testing purposes I modified the test config file so only the statistics step would run. I've set the test config back to its usual state in version 1.3.3.

ZeitgeberH commented 1 year ago

OK. 1.3.3 solved it! But how come the number of ROIs are different in your machine compared to mine? Do you think this would create a discrepancy for the analyses? I would expect you get the same ROIs independent the platform fRAT is run.

1.3.3 is able to move to the next step with another error (see below). From the error message, I thought it was nilearn's problem, so I tried installing nilearn, but the problem persists. Are you using a different version of nilearn? By the way, it seems nilearn has some functional overlap with fRAT. You probably could add a few comments on the difference between them in your JOSS paper.

Creating standardised and unstandardised coefficient brain maps

Skipping creation of standardised coefficient brain maps, all ROIs below p-value threshold. /home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/nilearn/plotting/img_plotting.py:348: FutureWarning: Default resolution of the MNI template will change from 2mm to 1mm in version 0.10.0 /home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/nilearn/_utils/niimg.py:61: UserWarning: Non-finite values detected. These values will be replaced with zeros. Exception in Tkinter callback Traceback (most recent call last): File "/home/mlk/anaconda3/envs/frat310/lib/python3.10/tkinter/init.py", line 1921, in call return self.func(*args) File "/home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/fRAT/main.py", line 403, in self.setattr(name, ttk.Button(self.settings_frame, command=lambda: func(self))) File "/home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/fRAT/main.py", line 858, in run_tests fRAT('test_config.toml', path_to_example_data) File "/home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/fRAT/nogui.py", line 41, in fRAT statistics_main(config, config_path, config_filename) File "/home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/fRAT/utils/statistics.py", line 114, in main statistics(param_queries, critical_params) File "/home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/fRAT/utils/statistics.py", line 319, in statistics roi_statistics(critical_params, rois_below_max_r2_thresh, File "/home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/fRAT/utils/statistics.py", line 438, in roi_statistics Coefficient_map.to_braingrid(unstandardised_coeffs_df, "unstandardised_coeffs", File "/home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/fRAT/utils/statistics.py", line 55, in to_braingrid cls.create_images(df, subfolder, standardise_cbar) File "/home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/fRAT/utils/statistics.py", line 97, in create_images cls.save_brain_imgs(variable, subfolder, vmax) File "/home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/fRAT/utils/statistics.py", line 65, in save_brain_imgs plot.savefig(f"{STATISTICS_PATH}/{subfolder}/images/{file_name}.png") ### File "/home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/nilearn/plotting/displays/_slicers.py", line 687, in savefig self.frame_axes.figure.savefig(filename, dpi=dpi, File "/home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/matplotlib/figure.py", line 3285, in savefig self.canvas.print_figure(fname, kwargs) File "/home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/matplotlib/backend_bases.py", line 2338, in print_figure result = print_method( File "/home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/matplotlib/backend_bases.py", line 2204, in print_method = functools.wraps(meth)(lambda *args, *kwargs: meth( File "/home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/matplotlib/_api/deprecation.py", line 410, in wrapper return func(inner_args, inner_kwargs) File "/home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/matplotlib/backends/backend_agg.py", line 517, in print_png self._print_pil(filename_or_obj, "png", pil_kwargs, metadata) File "/home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/matplotlib/backends/backend_agg.py", line 464, in _print_pil mpl.image.imsave( File "/home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/matplotlib/image.py", line 1667, in imsave image.save(fname, **pil_kwargs) File "/home/mlk/.local/pipx/venvs/frat-brain/lib/python3.10/site-packages/PIL/Image.py", line 2350, in save fp = builtins.open(filename, "w+b") FileNotFoundError: [Errno 2] No such file or directory: '/home/mlk/Documents/fRAT/example_data_v1.2.0/test_ROI_report/Statistics/stats//unstandardised_coeffs/main_effects/images/Intercept.png'

elliohow commented 1 year ago

From the error message, I thought it was nilearn's problem, so I tried installing nilearn, but the problem persists. Are you using a different version of nilearn?

The version of nilearn fRAT uses (0.9.0) is installed by pipx in the fRAT virtual environment upon installation.

I've resolved this issue with version 1.3.4. It was a small issue with the file path. Linux has a case-sensitive file system, whereas MacOS is case-insensitive, so it didn't flag up previously when testing on my Mac.

how come the number of ROIs are different in your machine compared to mine? Do you think this would create a discrepancy for the analyses? I would expect you get the same ROIs independent the platform fRAT is run.

There may be some slight differences in the result of the linear mixed model due to randomness or architectural differences between MacOS and Linux. This wouldn't normally be an issue with a full dataset that has an appropriate number of groups and observations, but with the restricted dataset provided in the example data, these small differences can lead to the scipy optimisers failing to converge in some cases. The original example data did not have any convergence issues, however it took around 90 minutes to run as opposed to ~13 minutes for the current dataset, and the file size was also around 5x larger. As this dataset is used for purpose of installation checking, as it will not cause issues later on in the application, I think having a much lighter dataset that may have some convergence issues is an appropriate tradeoff.

By the way, it seems nilearn has some functional overlap with fRAT. You probably could add a few comments on the difference between them in your JOSS paper.

I don't think there is much functional overlap between fRAT and nilearn. While both can be used with fMRI data to plot brain images (with fRAT using nilearn to do so) and for statistical analysis, the types of plotting and analysis they do is quite different, with the big difference being the tools provided by fRAT are centered around ROI analysis.

ZeitgeberH commented 1 year ago

1.3.4 passed the installation test with example_data_v1.3.4 in my WSL2 on Windows 10! Great work, @elliohow

--- End of installation testing, no errors found ---