MICA-MNI / BrainStat

A statistics and context decoding toolbox for neuroimaging.
https://brainstat.readthedocs.io
Other
95 stars 22 forks source link

surface_genetic_expression is broken with current versions of #351

Open araikes opened 5 months ago

araikes commented 5 months ago
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 commented 4 months ago

I encountered the same issue.

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 commented 2 months ago

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

zihuaihuai commented 1 month ago

this bug is because the new check atlas function in abagen has a little bug https://github.com/rmarkello/abagen/issues/235