gemprf 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. gemprf-0.1.1/LICENSE +28 -0
  2. gemprf-0.1.1/MANIFEST.in +22 -0
  3. gemprf-0.1.1/PKG-INFO +98 -0
  4. gemprf-0.1.1/README.md +74 -0
  5. gemprf-0.1.1/gem/__init__.py +10 -0
  6. gemprf-0.1.1/gem/analysis/__init__.py +6 -0
  7. gemprf-0.1.1/gem/analysis/prf_analysis.py +72 -0
  8. gemprf-0.1.1/gem/analysis/prf_r2_variance_explain.py +101 -0
  9. gemprf-0.1.1/gem/configs/__init__.py +6 -0
  10. gemprf-0.1.1/gem/configs/analysis_configs/analysis_additional_params.h5 +0 -0
  11. gemprf-0.1.1/gem/configs/analysis_configs/analysis_config.xml +124 -0
  12. gemprf-0.1.1/gem/configs/config_manager.py +174 -0
  13. gemprf-0.1.1/gem/configs/default_config/default_config - old before concatenation.xml +141 -0
  14. gemprf-0.1.1/gem/configs/default_config/default_config.xml +171 -0
  15. gemprf-0.1.1/gem/configs/default_config/new_concatenationDummyTest_config.xml +180 -0
  16. gemprf-0.1.1/gem/configs/default_config/new_concatenation_config.xml +180 -0
  17. gemprf-0.1.1/gem/configs/gem_xml_utils.py +30 -0
  18. gemprf-0.1.1/gem/configs/multiproc_prfspace_config/asus_analysis_config.xml +165 -0
  19. gemprf-0.1.1/gem/configs/multiproc_prfspace_config/dgx_analysis_config.xml +165 -0
  20. gemprf-0.1.1/gem/data/__init__.py +6 -0
  21. gemprf-0.1.1/gem/data/bids_handler.py +208 -0
  22. gemprf-0.1.1/gem/data/gem_bids_concatenation_data_info.py +42 -0
  23. gemprf-0.1.1/gem/data/gem_bids_individual_run_data_info.py +35 -0
  24. gemprf-0.1.1/gem/data/gem_stimulus_file_info.py +16 -0
  25. gemprf-0.1.1/gem/data/observed_data.py +42 -0
  26. gemprf-0.1.1/gem/fitting/__init__.py +6 -0
  27. gemprf-0.1.1/gem/fitting/hpc_coefficient_matrix.py +188 -0
  28. gemprf-0.1.1/gem/fitting/hpc_grid_fit.py +184 -0
  29. gemprf-0.1.1/gem/fitting/hpc_refine_fit.py +632 -0
  30. gemprf-0.1.1/gem/init_setup.py +136 -0
  31. gemprf-0.1.1/gem/kernels/gaussian_kernel.cu +208 -0
  32. gemprf-0.1.1/gem/kernels/gaussian_kernel.ptx +1408 -0
  33. gemprf-0.1.1/gem/model/__init__.py +6 -0
  34. gemprf-0.1.1/gem/model/prf_DoG_model.py +32 -0
  35. gemprf-0.1.1/gem/model/prf_gaussian_model.py +121 -0
  36. gemprf-0.1.1/gem/model/prf_model.py +130 -0
  37. gemprf-0.1.1/gem/model/prf_stimulus.py +146 -0
  38. gemprf-0.1.1/gem/model/selected_prf_model.py +17 -0
  39. gemprf-0.1.1/gem/run/__init__.py +0 -0
  40. gemprf-0.1.1/gem/run/run_gem_prf_analysis.py +728 -0
  41. gemprf-0.1.1/gem/run_gem.py +42 -0
  42. gemprf-0.1.1/gem/signals/__init__.py +6 -0
  43. gemprf-0.1.1/gem/signals/hrf_generator.py +64 -0
  44. gemprf-0.1.1/gem/signals/orthogonalization_matrix.py +40 -0
  45. gemprf-0.1.1/gem/signals/signal_synthesizer.py +281 -0
  46. gemprf-0.1.1/gem/space/PRFNeighbours.py +4 -0
  47. gemprf-0.1.1/gem/space/PRFSpace.py +569 -0
  48. gemprf-0.1.1/gem/space/__init__.py +6 -0
  49. gemprf-0.1.1/gem/space/coefficient_matrix.py +43 -0
  50. gemprf-0.1.1/gem/tools/__init__.py +6 -0
  51. gemprf-0.1.1/gem/tools/json_file_operations.py +43 -0
  52. gemprf-0.1.1/gem/utils/__init__.py +6 -0
  53. gemprf-0.1.1/gem/utils/gem_gpu_manager.py +107 -0
  54. gemprf-0.1.1/gem/utils/gem_h5_file_handler.py +24 -0
  55. gemprf-0.1.1/gem/utils/gem_load_estimations.py +89 -0
  56. gemprf-0.1.1/gem/utils/gem_write_to_file.py +121 -0
  57. gemprf-0.1.1/gem/utils/hpc_cupy_utils.py +149 -0
  58. gemprf-0.1.1/gem/utils/logger.py +52 -0
  59. gemprf-0.1.1/gemprf.egg-info/PKG-INFO +98 -0
  60. gemprf-0.1.1/gemprf.egg-info/SOURCES.txt +63 -0
  61. gemprf-0.1.1/gemprf.egg-info/dependency_links.txt +1 -0
  62. gemprf-0.1.1/gemprf.egg-info/requires.txt +12 -0
  63. gemprf-0.1.1/gemprf.egg-info/top_level.txt +2 -0
  64. gemprf-0.1.1/pyproject.toml +40 -0
  65. gemprf-0.1.1/setup.cfg +4 -0
gemprf-0.1.1/LICENSE ADDED
@@ -0,0 +1,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2023-2025, Siddharth Mittal, Medical University of Vienna
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,22 @@
1
+ # Include package data (ONLY specify the non-python files that need to be included)
2
+ # Include config files
3
+ recursive-include gem/configs *.xml *.h5
4
+
5
+ # Include CUDA kernels
6
+ recursive-include gem/kernels *.cu *.ptx
7
+
8
+ # Exclude tests and test data
9
+ recursive-exclude gem/tests *
10
+ recursive-exclude gem/tests/temp *
11
+ recursive-exclude gem/tests/testdata *
12
+
13
+ # Exclude cache and compiled artifacts
14
+ recursive-exclude gem/__pycache__ *
15
+ recursive-exclude __pycache__ *
16
+ recursive-exclude gem/**/*.pyc
17
+ recursive-exclude gem/**/*.pyo
18
+ recursive-exclude gem/**/*.nbc
19
+ recursive-exclude gem/**/*.nbi
20
+
21
+ # Misc OS garbage
22
+ exclude .DS_Store
gemprf-0.1.1/PKG-INFO ADDED
@@ -0,0 +1,98 @@
1
+ Metadata-Version: 2.4
2
+ Name: gemprf
3
+ Version: 0.1.1
4
+ Summary: A Python library for population receptive field (pRF) analysis
5
+ Author-email: Siddharth Mittal <siddharth.mittal@meduniwien.ac.at>
6
+ License: BSD 3-Clause License
7
+ Project-URL: Homepage, https://gemprf.github.io/
8
+ Requires-Python: >=3.8
9
+ Description-Content-Type: text/markdown
10
+ License-File: LICENSE
11
+ Requires-Dist: h5py==3.13.0
12
+ Requires-Dist: joblib==1.4.2
13
+ Requires-Dist: matplotlib==3.10.1
14
+ Requires-Dist: nibabel==5.3.2
15
+ Requires-Dist: numba==0.61.0
16
+ Requires-Dist: numba_kdtree==0.6.0
17
+ Requires-Dist: numpy==2.1.3
18
+ Requires-Dist: nvidia_ml_py==12.570.86
19
+ Requires-Dist: pandas==2.2.3
20
+ Requires-Dist: pynvml==12.0.0
21
+ Requires-Dist: scipy==1.15.2
22
+ Requires-Dist: xmltodict==0.14.2
23
+ Dynamic: license-file
24
+
25
+ Welcome to **GEM-pRF** - a standalone, plug-and-play software for population receptive field (pRF) mapping, designed for **large-scale data analysis with high accuracy**.
26
+
27
+
28
+ To understand the theoretical foundations and details of how the software works, please refer to our paper: 👉[Mittal et al (2025), ](https://www.biorxiv.org/content/10.1101/2025.05.16.654560v1)*[GEM-pRF: GPU-Empowered Mapping of Population Receptive Fields for Large-Scale fMRI Analysis](https://www.biorxiv.org/content/10.1101/2025.05.16.654560v1)*
29
+
30
+
31
+ ## Documentation
32
+
33
+ An official documentation is coming soon ([GEM-pRF documentation link](https://gemprf.github.io/))! Meanwhile, to get the mathematical foundation of the software, you may refer to the [GEM-pRF paper](https://www.biorxiv.org/content/10.1101/2025.05.16.654560v1).
34
+
35
+
36
+ ## Installation
37
+
38
+ GEM-pRF requires the GPU access for the data processing. At the moment, GEM uses CUDA libraries to acess/process data on NVIDIA GPUs.
39
+
40
+ > \[!WARNING\]
41
+ >
42
+ > Please check your system has compatible NVIDIA GPU available.
43
+
44
+ ### Step-by-Step Guide
45
+
46
+ **Step 1. Install dependencies**
47
+
48
+ * Create or activate your preferred Python/Conda environment.
49
+ * Install all required dependencies listed in `requirements.txt`:
50
+
51
+ ```bash
52
+ pip install -r requirements.txt
53
+ ```
54
+
55
+
56
+ **Step 2. Download GEM-pRF code**
57
+
58
+ * Clone the repository:
59
+
60
+ ```bash
61
+ git clone https://github.com/siddmittal/GEMpRF.git
62
+ cd GEMpRF
63
+ ```
64
+
65
+
66
+ ## Running GEM-pRF
67
+
68
+
69
+ > \[!CAUTION\]
70
+ > Before proceeding, make sure to install the required python dependencies as specified in the `requirements.txt` file
71
+
72
+ GEM-pRF is written as a **standalone software**. It comes with an XML configuration file. Once you configure your XML file (see [sample config](https://github.com/siddmittal/GEMpRF/blob/main/gem/configs/analysis_configs/analysis_config.xml)), you can directly run the software.
73
+
74
+ ### 🔹 **Option A: Run from terminal**
75
+
76
+
77
+
78
+
79
+ 1. Open a terminal (e.g. Anaconda Prompt).
80
+ 2. Activate the environment with the dependencies installed.
81
+ 3. Navigate to the GEM-pRF folder.
82
+ 4. Run:
83
+
84
+ ```bash
85
+ python run_gem.py PATH_TO_YOUR_XML_CONFIG_FILE
86
+ ```
87
+
88
+
89
+ ### 🔹 **Option B: Run from IDE (e.g. VS Code)**
90
+
91
+
92
+
93
+
94
+ 1. Open the downloaded GEM-pRF folder in VS Code.
95
+ 2. Edit the `run_gem.py` script to specify the path to your XML config file.
96
+ 3. Run the script directly from the IDE.
97
+
98
+
gemprf-0.1.1/README.md ADDED
@@ -0,0 +1,74 @@
1
+ Welcome to **GEM-pRF** - a standalone, plug-and-play software for population receptive field (pRF) mapping, designed for **large-scale data analysis with high accuracy**.
2
+
3
+
4
+ To understand the theoretical foundations and details of how the software works, please refer to our paper: 👉[Mittal et al (2025), ](https://www.biorxiv.org/content/10.1101/2025.05.16.654560v1)*[GEM-pRF: GPU-Empowered Mapping of Population Receptive Fields for Large-Scale fMRI Analysis](https://www.biorxiv.org/content/10.1101/2025.05.16.654560v1)*
5
+
6
+
7
+ ## Documentation
8
+
9
+ An official documentation is coming soon ([GEM-pRF documentation link](https://gemprf.github.io/))! Meanwhile, to get the mathematical foundation of the software, you may refer to the [GEM-pRF paper](https://www.biorxiv.org/content/10.1101/2025.05.16.654560v1).
10
+
11
+
12
+ ## Installation
13
+
14
+ GEM-pRF requires the GPU access for the data processing. At the moment, GEM uses CUDA libraries to acess/process data on NVIDIA GPUs.
15
+
16
+ > \[!WARNING\]
17
+ >
18
+ > Please check your system has compatible NVIDIA GPU available.
19
+
20
+ ### Step-by-Step Guide
21
+
22
+ **Step 1. Install dependencies**
23
+
24
+ * Create or activate your preferred Python/Conda environment.
25
+ * Install all required dependencies listed in `requirements.txt`:
26
+
27
+ ```bash
28
+ pip install -r requirements.txt
29
+ ```
30
+
31
+
32
+ **Step 2. Download GEM-pRF code**
33
+
34
+ * Clone the repository:
35
+
36
+ ```bash
37
+ git clone https://github.com/siddmittal/GEMpRF.git
38
+ cd GEMpRF
39
+ ```
40
+
41
+
42
+ ## Running GEM-pRF
43
+
44
+
45
+ > \[!CAUTION\]
46
+ > Before proceeding, make sure to install the required python dependencies as specified in the `requirements.txt` file
47
+
48
+ GEM-pRF is written as a **standalone software**. It comes with an XML configuration file. Once you configure your XML file (see [sample config](https://github.com/siddmittal/GEMpRF/blob/main/gem/configs/analysis_configs/analysis_config.xml)), you can directly run the software.
49
+
50
+ ### 🔹 **Option A: Run from terminal**
51
+
52
+
53
+
54
+
55
+ 1. Open a terminal (e.g. Anaconda Prompt).
56
+ 2. Activate the environment with the dependencies installed.
57
+ 3. Navigate to the GEM-pRF folder.
58
+ 4. Run:
59
+
60
+ ```bash
61
+ python run_gem.py PATH_TO_YOUR_XML_CONFIG_FILE
62
+ ```
63
+
64
+
65
+ ### 🔹 **Option B: Run from IDE (e.g. VS Code)**
66
+
67
+
68
+
69
+
70
+ 1. Open the downloaded GEM-pRF folder in VS Code.
71
+ 2. Edit the `run_gem.py` script to specify the path to your XML config file.
72
+ 3. Run the script directly from the IDE.
73
+
74
+
@@ -0,0 +1,10 @@
1
+ from . import model
2
+ from .model import *
3
+
4
+ from . import tools
5
+ from .tools import *
6
+
7
+ from . import space
8
+ from .space import *
9
+
10
+ from .run_gem import run
@@ -0,0 +1,6 @@
1
+ class my_class(object):
2
+ pass
3
+
4
+
5
+
6
+
@@ -0,0 +1,72 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+
4
+ "@Author : Siddharth Mittal",
5
+ "@Version : 1.0",
6
+ "@Contact : siddharth.mittal@meduniwien.ac.at",
7
+ "@License : (C)Copyright 2024, Medical University of Vienna",
8
+ "@Desc : None",
9
+
10
+ """
11
+
12
+ import numpy as np
13
+ import cupy as cp
14
+ from typing import List
15
+
16
+ from gem.model.prf_model import PRFModel
17
+ from gem.model.selected_prf_model import SelectedPRFModel
18
+ from gem.model.prf_stimulus import Stimulus
19
+ from gem.space.PRFSpace import PRFSpace
20
+ from gem.utils.hpc_cupy_utils import HpcUtils as gpu_utils
21
+
22
+
23
+ class PRFAnalysis():
24
+ def __init__(self, prf_space : PRFSpace, stimulus : Stimulus) -> None:
25
+ self.__prf_points = prf_space
26
+ self.__stimulus = stimulus
27
+ self.__model_signals_batches = None
28
+ self.__dervatives_signals_batches_list = None
29
+ self.__error_e = None
30
+ self.__error_de_dtheta_list = None # contains a list of all derivative errors w.r.t each parameter
31
+
32
+ @property
33
+ def prf_points(self)-> PRFSpace:
34
+ return self.__prf_points
35
+
36
+ @property
37
+ def stimulus(self)-> Stimulus:
38
+ return self.__stimulus
39
+
40
+ @property
41
+ def orthonormalized_S_batches(self)-> List[cp.ndarray]:
42
+ return self.__model_signals_batches
43
+
44
+ @orthonormalized_S_batches.setter
45
+ def orthonormalized_S_batches(self, new_value)-> None:
46
+ self.__model_signals_batches = new_value
47
+
48
+ @property
49
+ def orthonormalized_dS_dtheta_batches_list(self)-> List[List[cp.ndarray]]:
50
+ return self.__dervatives_signals_batches_list
51
+
52
+ @orthonormalized_dS_dtheta_batches_list.setter
53
+ def orthonormalized_dS_dtheta_batches_list(self, new_value)-> None:
54
+ self.__dervatives_signals_batches_list = new_value
55
+
56
+ @property
57
+ def error_e(self)-> cp.ndarray:
58
+ return self.__error_e
59
+
60
+ @error_e.setter
61
+ def error_e(self, new_value)-> None:
62
+ self.__error_e = new_value
63
+
64
+ @property
65
+ def error_de_dtheta_list(self)-> List[cp.ndarray]:
66
+ return self.__error_de_dtheta_list
67
+
68
+ @error_de_dtheta_list.setter
69
+ def error_de_dtheta_list(self, new_value)-> None:
70
+ self.__error_de_dtheta_list = new_value
71
+
72
+
@@ -0,0 +1,101 @@
1
+ import numpy as np
2
+ import cupy as cp
3
+ from gem.tools.json_file_operations import JsonMgr
4
+ from gem.utils.hpc_cupy_utils import HpcUtils as Utils
5
+ from gem.model import prf_model
6
+ from gem.signals.signal_synthesizer import SignalSynthesizer
7
+ from gem.model.prf_model import GaussianModelParams
8
+ from gem.utils.gem_gpu_manager import GemGpuManager as ggm
9
+
10
+ class R2:
11
+ @classmethod
12
+ def get_r2_new_method_with_epsilon_as_Fx(cls, Y_signals_gpu, O_gpu, epsilon_results_cpu):
13
+ r2 = []
14
+ R_Rt_gpu = cp.eye(O_gpu.shape[0]) - O_gpu
15
+
16
+ num_y_signals = len(epsilon_results_cpu)
17
+ for yIdx in range (num_y_signals):
18
+ y = Y_signals_gpu[:, yIdx]
19
+ yty = y.T @ y
20
+ ystar = O_gpu @ y
21
+ ystarT_ystar_inv = (ystar.T @ ystar) ** (-1)
22
+ e = (float(epsilon_results_cpu[yIdx])) ** 2 #<----------------------------------
23
+ yt_RRt_y = (y.T @ R_Rt_gpu) @ y
24
+ r2_gpu = 1 - ((yty - e - yt_RRt_y) * ystarT_ystar_inv)
25
+ r2.append(float(r2_gpu))
26
+
27
+ return r2
28
+
29
+ @classmethod
30
+ def get_r2_num_den_method_with_epsilon_as_yTs(cls, Y_signals_gpu, O_gpu, refined_matching_results, refined_S_cpu):
31
+ with cp.cuda.Device(ggm.get_instance().default_gpu_id):
32
+ numerators_gpu , denominators_gpu = cls.get_r2_numerator_denominator_terms(Y_signals_gpu, O_gpu, refined_matching_results, refined_S_cpu)
33
+ r2_results_gpu = 1 - (numerators_gpu / denominators_gpu)
34
+
35
+ return cp.asnumpy(r2_results_gpu)
36
+
37
+ @classmethod # R2 numerator = (yty - e - yt_RRt_y)
38
+ def get_r2_numerator_denominator_terms(cls, Y_signals_gpu, O_gpu, refined_matching_results, refined_signals_cpu: np.ndarray):
39
+ with cp.cuda.Device(ggm.get_instance().default_gpu_id):
40
+ refined_signals_gpu = cp.asarray(refined_signals_cpu)
41
+ num_y_signals = Y_signals_gpu.shape[1]
42
+
43
+ R_Rt_gpu = cp.eye(O_gpu.shape[0]) - O_gpu
44
+
45
+ # Compute yty for each signal
46
+ yty = cp.sum(Y_signals_gpu ** 2, axis=0)
47
+
48
+ # Compute ystar and ystarT_ystar
49
+ ystar = O_gpu @ Y_signals_gpu
50
+ ystarT_ystar = cp.sum(ystar ** 2, axis=0)
51
+
52
+ # Check for NaN refined results
53
+ nan_mask = np.isnan(refined_matching_results).all(axis=1)
54
+ nan_mask = cp.asarray(nan_mask)
55
+
56
+ # Check for zero signals
57
+ s = refined_signals_gpu
58
+ zero_mask = np.all(refined_signals_cpu == 0, axis=1)
59
+ zero_mask = cp.asarray(zero_mask)
60
+
61
+ # Compute s_star
62
+ s_star = O_gpu @ s.T # shape: [timepoints, num_signals]
63
+
64
+ # Normalize s_star to get s_prime
65
+ s_prime = s_star * (cp.sum(s_star ** 2, axis=0) ** (-0.5))
66
+
67
+ # Compute error-term e = (y.T @ s_prime)^2
68
+ e = cp.sum(Y_signals_gpu * s_prime, axis=0) ** 2 #<----------------------------------
69
+
70
+ # Compute yt_RRt_y
71
+ # # yt_RRt_y = cp.sum(Y_signals_gpu * (R_Rt_gpu @ Y_signals_gpu), axis=0)
72
+ yt_R = Y_signals_gpu * (R_Rt_gpu @ Y_signals_gpu)
73
+ yt_RRt_y = cp.sum(yt_R, axis=0)
74
+
75
+ # Compute final numerator and denominator
76
+ num = yty - e - yt_RRt_y
77
+ den = ystarT_ystar
78
+
79
+ # Apply masks for nan/zero
80
+ num = cp.where(nan_mask, 2.0, num)
81
+ num = cp.where(zero_mask & ~nan_mask, 3.0, num)
82
+ den = cp.where(nan_mask | zero_mask, 1.0, den)
83
+
84
+ return num, den
85
+
86
+ @classmethod
87
+ def format_in_json_format(cls, r2_results, refined_matching_results, refined_signal_timecourses, refined_signals_present = True):
88
+ json_data_results_with_r2 = []
89
+
90
+ # default r2 value
91
+ for i in range((len(refined_matching_results))):
92
+ r2 = float(r2_results[i])
93
+ muX, muY, sigma = refined_matching_results[i]
94
+ if refined_signals_present:
95
+ refined_signal_timecourse = refined_signal_timecourses[i]
96
+ else:
97
+ refined_signal_timecourse = np.array([None])
98
+ json_entry = JsonMgr.args2jsonEntry(muX, muY, sigma, r2, refined_signal_timecourse)
99
+ json_data_results_with_r2.append(json_entry)
100
+
101
+ return json_data_results_with_r2
@@ -0,0 +1,6 @@
1
+ class my_class(object):
2
+ pass
3
+
4
+
5
+
6
+
@@ -0,0 +1,124 @@
1
+ <!-- XML representation of JSON data -->
2
+ <!--
3
+ "@Author : Siddharth Mittal",
4
+ "@Version : 1.0",
5
+ "@Contact : siddharth.mittal@meduniwien.ac.at",
6
+ "@License : (C)Copyright 2024, Medical University of Vienna"
7
+ -->
8
+
9
+ <!-- NOTE for Analysis: For DUMMY/Analsis, set correct Visual field at two positions, one for the <stimulus> and another for <search_space>-->
10
+
11
+
12
+ <root>
13
+ <!-- Path information -->
14
+ <path_to_append>.../</path_to_append>
15
+ <refine_fitting enable="True" refinefit_on_gpu="True"/> <!-- Execute refine fitting on GPU if sufficient GPU memory is available -->
16
+
17
+ <!-- Stimulus data -->
18
+ <stimulus>
19
+ <!-- File path for stimulus -->
20
+ <directory>/ceph/mri.meduniwien.ac.at/projects/physics/fmri/data/stimsim24/BIDS/derivatives/prfprepare/analysis-01/sub-001/stimuli</directory>
21
+ <visual_field>9</visual_field> <!-- Visual field Radius, NOTE: Use "10" for simulated data, else "9" -->
22
+ <width>101</width>
23
+ <height>101</height>
24
+ <binarization enable="False" threshold="0"/> <!-- stimulus will be binarized if enabled, all values above threshold will be set to 1 and below to 0 -->
25
+
26
+ <!-- Compute model signals with high-res stimulus then downsample: "num_frames_downsampled" = your fMRI timecourse length, "slice_time_ref" for details see https://www.alivelearn.net/?p=1037 -->
27
+ <high_temporal_resolution enable="false" num_frames_downsampled="240" slice_time_ref="0.5"/>
28
+ </stimulus>
29
+
30
+ <!-- Input Data -->
31
+ <input_datasrc>
32
+ <BIDS enable="True" run_type="individual"> <!-- Set to "True" if the input data is organized in BIDS format, select "individual" or "concatenated" run type -->
33
+ <basepath>/ceph/mri.meduniwien.ac.at/projects/physics/fmri/data/stimsim24/BIDS</basepath>
34
+ <append_to_basepath>derivatives, prfprepare</append_to_basepath> <!-- specify if the "analysis-xx" -->
35
+ <!-- <basepath>D:/results/fmri/generic/</basepath> -->
36
+
37
+ <!-- Directory name for results; backups created with timestamp if overwrite="True" -->
38
+ <results_anaylsis_id overwrite="False">GEMpRF</results_anaylsis_id>
39
+
40
+ <!--
41
+ NOTE: Case sensitive, provide the exact values!!!
42
+ For the analysis, sub, ses, task, run, hemi,
43
+ either provide comma separated values or specify "all" (to go through every available analysis)
44
+ Sample: <analysis>01, 02</analysis> or <analysis>all</analysis>
45
+ -->
46
+ <analysis>01</analysis>
47
+ <sub>001, 002</sub>
48
+ <hemi>all</hemi>
49
+
50
+ <!--INDIVIDUAL Task/stimulus Analysis-->
51
+ <individual>
52
+ <task>bar</task> <!--name of the stimulus, this will be used to find the file in the stimulus directory, ONLY one value is allowed-->
53
+ <ses>001nn</ses> <!-- comma separated values or specify "all" -->
54
+ <run>01, 02</run> <!-- comma separated values or specify "all" -->
55
+ </individual>
56
+
57
+ <!--CONCATENATED Analysis-->
58
+ <concatenated>
59
+ <concatenate_item>
60
+ <ses>001</ses> <!-- ONLY one value is allowed-->
61
+ <task>bar</task> <!-- ONLY one value is allowed-->
62
+ <run>02</run> <!-- ONLY one value is allowed-->
63
+ </concatenate_item>
64
+ <concatenate_item>
65
+ <ses>001</ses>
66
+ <task>bar</task>
67
+ <run>04</run>
68
+ </concatenate_item>
69
+ </concatenated>
70
+ </BIDS>
71
+
72
+ <!--OR, make Bids False and specify directly single/multiple filepaths -->
73
+ <fixed_paths>
74
+ <measured_data_filepath> <!-- Measured input data filepaths -->
75
+ <filepath>/ceph/mri.meduniwien.ac.at/projects/physics/fmri/data/tests/gem_generic_test/BIDS/sub-001/ses-3n2/func/sub-001_ses-3n2_task-prf_acq-normal_run-01_bold.nii.gz</filepath>
76
+ <filepath>dummy////sub-001/ses-3n2/func/sub-001_ses-3n2_task-prf_acq-normal_run-01_bold.nii.gz</filepath>
77
+ </measured_data_filepath>
78
+ <results> <!-- Results filepaths realted -->
79
+ <basepath>/ceph/mri.meduniwien.ac.at/projects/physics/fmri/data/tests/gem_generic_test/derivatives/prfanalyze-gem/analysis-01/sub-001/ses-3n2/</basepath> <!-- Base path for results -->
80
+ <custom_filename_postfix>_[gem-new_data-simulated_v1_151x151x8_refine-validation]</custom_filename_postfix> <!-- Custom filename postfix -->
81
+ <prepend_date>True</prepend_date> <!-- Flag to prepend date -->
82
+ </results>
83
+ </fixed_paths>
84
+ </input_datasrc>
85
+
86
+ <!-- Analysis Model -->
87
+ <pRF_model>
88
+ <model>2d_gaussian</model> <!-- 2d_gauss, (DoG, CSS not avaiable at the moment) -->
89
+ </pRF_model>
90
+
91
+ <!-- Measured data section -->
92
+ <measured_data>
93
+ <width>101</width>
94
+ <height>101</height>
95
+ <batches>200</batches>
96
+ </measured_data>
97
+
98
+ <!-- GPU configuration -->
99
+ <gpu>
100
+ <!-- Default GPU -->
101
+ <default_gpu>0</default_gpu>
102
+ <!-- Additional available GPUs -->
103
+ <additional_available_gpus>
104
+ <gpu>1</gpu>
105
+ <gpu>2</gpu>
106
+ <gpu>3</gpu>
107
+ </additional_available_gpus>
108
+ </gpu>
109
+
110
+ <!-- Search space information -->
111
+ <search_space write_debug_info="false">
112
+ <!-- if the user wants to use custom HRF, pRF sizes or Spatial grid, provide the filepath to the H5 file and the keys for each parameter -->
113
+ <optional_analysis_params enable="False" filepath="DIR_PATH/analysis_additional_params.h5">
114
+ <hrf use_from_file="True" key="analysis_params/hrf_values"/>
115
+ <sigmas use_from_file="True" key="analysis_params/sigmas"/>
116
+ <spatial_grid_xy use_from_file="True" key="analysis_params/spatial_grid_xy"/>
117
+ </optional_analysis_params>
118
+
119
+ <!-- if the user wants to generate a rectilinear grid within the GEM-pRF program, specify the default values below. Please NOTE that these values will ONLY be used if their corresponding optional_analysis_params = False -->
120
+ <default_hrf t="(0, 45)" TR="auto" peak_delay="6.16" under_shoot_delay="12.0" peak_disp="0.85" under_disp="0.82" peak_to_undershoot="2.15" normalize="true"/> <!-- SPM parameters, "t" is fed to np.arange(start, stop, step), "step" represents the TR value, set it to a lower value in case of high temporal stimulus. If TR = "auto" then, its value will be read from the stimulus file -->
121
+ <default_spatial_grid visual_field_radius="13.5" num_horizontal_prfs="151" num_vertical_prfs="151"/>
122
+ <default_sigmas num_sigmas="16" min_sigma="0.5" max_sigma="5"/>
123
+ </search_space>
124
+ </root>