Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

surface_genetic_expression is broken with current versions of #351

Open
araikes opened this issue Jun 4, 2024 · 3 comments
Open

surface_genetic_expression is broken with current versions of #351

araikes opened this issue Jun 4, 2024 · 3 comments
Assignees
Labels
bug Something isn't working

Comments

@araikes
Copy link

araikes commented Jun 4, 2024

  • What is the current behavior?
    Following the tutorial using BrainStat in a Jupyter Notebook running through Singularity. In the tutorial, you are supposed to be able to fetch gene expression using surface_genetic_expression. However, this is broken currently:
2024-06-04 10:34:06.077 (36615.547s) [        C8222740] vtkPythonAlgorithm.cxx:97     ERR| vtkPythonAlgorithm (0x56267e036dd0): Failure when calling method: "ProcessRequest":

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
File /opt/conda/lib/python3.11/site-packages/vtk-9.3.20230807rc0-py3.11-linux-x86_64.egg/vtkmodules/util/vtkAlgorithm.py:152, in VTKPythonAlgorithmBase.InternalAlgorithm.ProcessRequest(self, vtkself, request, inInfo, outInfo)
    151 def ProcessRequest(self, vtkself, request, inInfo, outInfo):
--> 152     return vtkself.ProcessRequest(request, inInfo, outInfo)

File /opt/conda/lib/python3.11/site-packages/vtk-9.3.20230807rc0-py3.11-linux-x86_64.egg/vtkmodules/util/vtkAlgorithm.py:198, in VTKPythonAlgorithmBase.ProcessRequest(self, request, inInfo, outInfo)
    196     return self.RequestUpdateExtent(request, inInfo, outInfo)
    197 elif request.Has(vtkDemandDrivenPipeline.REQUEST_DATA()):
--> 198     return self.RequestData(request, inInfo, outInfo)
    200 return 1

File /opt/conda/lib/python3.11/site-packages/brainspace-0.1.10-py3.11.egg/brainspace/vtk_interface/io_support/gifti_support.py:123, in vtkGIFTIWriter.RequestData(self, request, inInfo, outInfo)
    122 def RequestData(self, request, inInfo, outInfo):
--> 123     _write_gifti(vtkPolyData.GetData(inInfo[0], 0), self.__FileName)
    124     return 1

File /opt/conda/lib/python3.11/site-packages/brainspace-0.1.10-py3.11.egg/brainspace/vtk_interface/decorators.py:41, in wrap_input.<locals>._wrapper_decorator.<locals>._wrapper_wrap(*args, **kwds)
     38 @functools.wraps(func)
     39 def _wrapper_wrap(*args, **kwds):
     40     args, kwds = _wrap_input_data(args, kwds, *xargs, skip=skip)
---> 41     data = func(*args, **kwds)
     42     return data

File /opt/conda/lib/python3.11/site-packages/brainspace-0.1.10-py3.11.egg/brainspace/vtk_interface/io_support/gifti_support.py:61, in _write_gifti(pd, opth)
     58 if not pd.has_only_triangle:
     59     raise ValueError('GIFTI writer only accepts triangles.')
---> 61 points = GiftiDataArray(data=pd.Points, intent=INTENT_POINTS)
     62 cells = GiftiDataArray(data=pd.GetCells2D(), intent=INTENT_CELLS)
     63 # if data is not None:
     64 #     data_array = GiftiDataArray(data=data, intent=INTENT_POINTDATA)
     65 #     gii = nb.gifti.GiftiImage(darrays=[points, cells, data_array])
     66 # else:

File /opt/conda/lib/python3.11/site-packages/nibabel-5.2.1-py3.11.egg/nibabel/gifti/gifti.py:476, in GiftiDataArray.__init__(self, data, intent, datatype, encoding, endian, coordsys, ordering, meta, ext_fname, ext_offset)
    474         datatype = self.data.dtype
    475     else:
--> 476         raise ValueError(
    477             f'Data array has type {self.data.dtype}. '
    478             'The GIFTI standard only supports uint8, int32 and float32 arrays.\n'
    479             'Explicitly cast the data array to a supported dtype or pass an '
    480             'explicit "datatype" parameter to GiftiDataArray().'
    481         )
    482 self.datatype = data_type_codes.code[datatype]
    483 self.encoding = gifti_encoding_codes.code[encoding]

ValueError: Data array has type float64. The GIFTI standard only supports uint8, int32 and float32 arrays.
Explicitly cast the data array to a supported dtype or pass an explicit "datatype" parameter to GiftiDataArray().

2024-06-04 10:34:06.107 (36615.577s) [        C8222740]       vtkExecutive.cxx:729    ERR| vtkCompositeDataPipeline (0x56267e246d40): Algorithm vtkPythonAlgorithm (0x56267e036dd0) returned failure for request: vtkInformation (0x56266eec1ac0)
  Debug: Off
  Modified Time: 80451
  Reference Count: 2
  Registered Events: (none)
  Request: REQUEST_DATA
  FROM_OUTPUT_PORT: -1
  ALGORITHM_AFTER_FORWARD: 1
  FORWARD_DIRECTION: 0


---------------------------------------------------------------------------
ImageFileError                            Traceback (most recent call last)
Cell In[72], line 4
      2 schaefer_200_fs5 = fetch_parcellation("fsaverage5", "schaefer", 200)
      3 surfaces = fetch_template_surface("fsaverage5", join=False)
----> 4 expression = surface_genetic_expression(schaefer_200_fs5, surfaces, space="fsaverage5")

File /opt/conda/lib/python3.11/site-packages/brainstat/context/genetics.py:100, in surface_genetic_expression(labels, surfaces, space, atlas_info, ibf_threshold, probe_selection, donor_probes, lr_mirror, missing, tolerance, sample_norm, gene_norm, norm_matched, norm_structures, region_agg, agg_metric, corrected_mni, reannotated, return_counts, return_donors, return_report, donors, data_dir, verbose, n_proc)
     98         name = f.name
     99         write_surface(surface, name, otype="gii")
--> 100     surfaces_gii.append(nib.load(name))
    101 finally:
    102     Path(name).unlink()

File /opt/conda/lib/python3.11/site-packages/nibabel-5.2.1-py3.11.egg/nibabel/loadsave.py:104, in load(filename, **kwargs)
    102     raise FileNotFoundError(f"No such file or no access: '{filename}'")
    103 if stat_result.st_size <= 0:
--> 104     raise ImageFileError(f"Empty file: '{filename}'")
    106 sniff = None
    107 for image_klass in all_image_classes:

ImageFileError: Empty file: '/tmp/tmp6aalcznf.gii
@RicardoRyn
Copy link

I encountered the same issue.

  • python 3.11
  • brainstat 0.4.2
  • brainspace 0.1.10
  • abagen 0.1.3
  • nibabel 5.2.0
  • vtk 9.3.1

This is my code:

from brainstat.context.genetics import surface_genetic_expression
from nilearn import datasets
import numpy as np


destrieux = datasets.fetch_atlas_surf_destrieux()
labels = np.hstack((destrieux['map_left'], destrieux['map_right']))
fsaverage = datasets.fetch_surf_fsaverage()
surfaces = (fsaverage['pial_left'], fsaverage['pial_right'])
expression = surface_genetic_expression(labels, surfaces, space='fsaverage')

And this is error:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
File e:\jupyter_notebook\jupyter_notebook_env\RJX\Lib\site-packages\abagen\images.py:352, in check_atlas(atlas, atlas_info, geometry, space, donor, data_dir)
    351 try:
--> 352     atlas = check_img(atlas)
    353     coords = triangles = None

File e:\jupyter_notebook\jupyter_notebook_env\RJX\Lib\site-packages\abagen\images.py:218, in check_img(img)
    217 elif not isinstance(img, nib.spatialimages.SpatialImage):
--> 218     raise TypeError('Provided image must be an existing filepath or a '
    219                     'pre-loaded niimg-like object')
    221 # ensure 3D or squeezable to 3D

TypeError: Provided image must be an existing filepath or a pre-loaded niimg-like object

During handling of the above exception, another exception occurred:

TypeError                                 Traceback (most recent call last)
File e:\jupyter_notebook\jupyter_notebook_env\RJX\Lib\site-packages\abagen\images.py:419, in check_geometry(surface, space, donor, data_dir)
    418 try:
--> 419     coords, triangles = map(list, zip(*[
    420         load_gifti(img).agg_data() for img in surface
    421     ]))
    422 except TypeError:

File e:\jupyter_notebook\jupyter_notebook_env\RJX\Lib\site-packages\abagen\images.py:420, in <listcomp>(.0)
    418 try:
    419     coords, triangles = map(list, zip(*[
--> 420         load_gifti(img).agg_data() for img in surface
    421     ]))
    422 except TypeError:

File e:\jupyter_notebook\jupyter_notebook_env\RJX\Lib\site-packages\abagen\utils.py:220, in load_gifti(img)
    217     elif (isinstance(err, TypeError)
    218           and not str(err) == 'stat: path should be string, bytes, os.'
    219                               'PathLike or integer, not GiftiImage'):
--> 220         raise err
    222 return img

File e:\jupyter_notebook\jupyter_notebook_env\RJX\Lib\site-packages\abagen\utils.py:210, in load_gifti(img)
    209 try:
--> 210     img = nib.load(img)
    211 except (ImageFileError, TypeError) as err:
    212     # it's gzipped, so read the gzip and pipe it in

File e:\jupyter_notebook\jupyter_notebook_env\RJX\Lib\site-packages\nibabel\loadsave.py:96, in load(filename, **kwargs)
     82 r"""Load file given filename, guessing at file type
     83 
     84 Parameters
   (...)
     94    Image of guessed type
     95 """
---> 96 filename = _stringify_path(filename)
     98 # Check file exists and is not empty

File e:\jupyter_notebook\jupyter_notebook_env\RJX\Lib\site-packages\nibabel\filename_parser.py:41, in _stringify_path(filepath_or_buffer)
     26 """Attempt to convert a path-like object to a string.
     27 
     28 Parameters
   (...)
     39 https://github.com/pandas-dev/pandas/blob/325dd68/pandas/io/common.py#L131-L160
     40 """
---> 41 return pathlib.Path(filepath_or_buffer).expanduser().as_posix()

File e:\jupyter_notebook\jupyter_notebook_env\RJX\Lib\pathlib.py:871, in Path.__new__(cls, *args, **kwargs)
    870     cls = WindowsPath if os.name == 'nt' else PosixPath
--> 871 self = cls._from_parts(args)
    872 if not self._flavour.is_supported:

File e:\jupyter_notebook\jupyter_notebook_env\RJX\Lib\pathlib.py:509, in PurePath._from_parts(cls, args)
    508 self = object.__new__(cls)
--> 509 drv, root, parts = self._parse_args(args)
    510 self._drv = drv

File e:\jupyter_notebook\jupyter_notebook_env\RJX\Lib\pathlib.py:493, in PurePath._parse_args(cls, args)
    492 else:
--> 493     a = os.fspath(a)
    494     if isinstance(a, str):
    495         # Force-cast str subclasses to str (issue #21127)

TypeError: expected str, bytes or os.PathLike object, not GiftiImage

During handling of the above exception, another exception occurred:

TypeError                                 Traceback (most recent call last)
Cell In[8], line 10
      8 fsaverage = datasets.fetch_surf_fsaverage()
      9 surfaces = (fsaverage['pial_left'], fsaverage['pial_right'])
---> 10 expression = surface_genetic_expression(labels, surfaces, space='fsaverage')

File e:\jupyter_notebook\jupyter_notebook_env\RJX\Lib\site-packages\brainstat\context\genetics.py:110, in surface_genetic_expression(labels, surfaces, space, atlas_info, ibf_threshold, probe_selection, donor_probes, lr_mirror, missing, tolerance, sample_norm, gene_norm, norm_matched, norm_structures, region_agg, agg_metric, corrected_mni, reannotated, return_counts, return_donors, return_report, donors, data_dir, verbose, n_proc)
    106 # Use abagen to grab expression data.
    107 logger.info(
    108     "If you use BrainStat's genetics functionality, please cite abagen (https://abagen.readthedocs.io/en/stable/citing.html)."
    109 )
--> 110 atlas = check_atlas(labels, geometry=surfaces_gii, space=space)
    111 expression = get_expression_data(
    112     atlas,
    113     atlas_info=atlas_info,
   (...)
    134     n_proc=n_proc,
    135 )
    137 return expression

File e:\jupyter_notebook\jupyter_notebook_env\RJX\Lib\site-packages\abagen\images.py:366, in check_atlas(atlas, atlas_info, geometry, space, donor, data_dir)
    363 elif geometry is not None and space is None:
    364     raise ValueError('If providing geometry files space parameter '
    365                      'must be specified')
--> 366 coords, triangles = check_geometry(geometry, space, donor=donor,
    367                                    data_dir=data_dir)
    368 if atlas_info is None and info is not None:
    369     atlas_info = info

File e:\jupyter_notebook\jupyter_notebook_env\RJX\Lib\site-packages\abagen\images.py:423, in check_geometry(surface, space, donor, data_dir)
    419     coords, triangles = map(list, zip(*[
    420         load_gifti(img).agg_data() for img in surface
    421     ]))
    422 except TypeError:
--> 423     coords, triangles = map(list, zip(*[i for i in surface]))
    425 triangles[-1] += coords[0].shape[0]
    426 coords, triangles = np.row_stack(coords), np.row_stack(triangles)

File e:\jupyter_notebook\jupyter_notebook_env\RJX\Lib\site-packages\nibabel\filebasedimages.py:206, in FileBasedImage.__getitem__(self, key)
    204 def __getitem__(self, key) -> None:
    205     """No slicing or dictionary interface for images"""
--> 206     raise TypeError('Cannot slice image objects.')

TypeError: Cannot slice image objects.

@daisyxyfamily
Copy link

I got the same error of araikes's. Anybody solved this problem?

@zihuaihuai zihuaihuai added the bug Something isn't working label Sep 25, 2024
@zihuaihuai zihuaihuai self-assigned this Oct 22, 2024
@zihuaihuai
Copy link
Collaborator

this bug is because the new check atlas function in abagen has a little bug
rmarkello/abagen#235

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

When branches are created from issues, their pull requests are automatically linked.

4 participants