Read a few indices of CIFTI matrix dimension 0 (the rows of the
data matrix) from a large file, without ever holding the values of the rows
that are not requested in memory. read.cifti supports the same
selection, but it reads the whole matrix first and then drops the unrequested
rows, which is impossible for a file that does not fit into memory: the
matrix of an HCP subject (91,282 grayordinates in both dimensions) is 33 GB.
This function streams through the file in chunks and keeps only the requested
rows, so its memory usage is the size of the result plus one chunk (32 MB by
default), regardless of the size of the file.
Note which direction of a CIFTI-2 file is the cheap one: the values of a
cell of a row are stored with a stride (dim[5] values lie between the
values of one row), while the values of a column are contiguous. Reading
rows therefore has to touch every value of the file once (it is a
single sequential pass, not a seek per value, but the I/O is the size of the
file), while selecting columns reads only what was asked for. Use
read.cifti with the columns parameter if the rows you need are
the ones that a column selection can give you, e.g. because the matrix is
symmetric (which a .dconn is), and use this function for the cases that
need rows: for a .dtseries, one row is one time point of all grayordinates,
so reading the first few time points of a 1.7 GB file with this function
needs a few KB instead of the whole file.
read.cifti.rows(filepath, rows, columns = NULL, chunk_values = 4000000L)a named list with the entries 'header' and 'data', see
read.cifti. The 'data' entry holds the requested rows, with the
requested columns if columns was given.
character string, the path to a CIFTI-2 file. Note that a CIFTI-2 file is a NIFTI-2 file, but its data are not a 3D volume; gzipped CIFTI files do not exist (the format forbids compression so that random access remains possible).
integer vector, the indices of matrix dimension 0 to read. At least
one index has to be given; the indices are 1-based, see read.cifti.
integer vector or NULL, the indices of matrix dimension 1 to
read, i.e. the columns of the returned array. This is the matrix dimension
that holds the brainordinates of a dense file (the grayordinates of a
.dscalar, .dtseries or .dlabel), and it is also one of the two
dimensions that hold them in a connectome file like a .dconn. Selecting
columns avoids reading the rest of the file, which is the only practical way
to read a small part of a huge file like a .dconn (9 to 38 GB): for a
2-dimensional matrix, one contiguous block of the file holds all values of
one column. Note that rows does not have this property, selecting rows
still reads all values of the file.
integer, the number of data values that are read from the file per chunk. This does not change the result, only the peak memory usage and the I/O granularity, so it is rarely needed: the default of 4 millions values corresponds to about 16 MB. The chunk size is rounded up to a whole number of matrix columns, and the result is the same for every chunk size.
Other cifti functions:
cifti.axis.brain.models(),
cifti.axis.from.template(),
cifti.axis.labels(),
cifti.axis.parcels(),
cifti.axis.parcels.from.annot(),
cifti.axis.scalars(),
cifti.axis.series(),
cifti.brain.model.surface(),
cifti.brain.model.volume(),
cifti.dim.labels(),
cifti.file.type.for.axes(),
cifti.grayordinates(),
cifti.header.from.axes(),
cifti.label.table(),
cifti.parcel(),
cifti.parcels(),
cifti.series.info(),
cifti.structure.data(),
cifti.structures(),
cifti.volume(),
print.fs.cifti(),
print.fs.cifti.data(),
print.fs.connectome(),
read.cifti(),
read.cifti.header(),
read.fs.connectome.cifti(),
write.cifti(),
write.fs.connectome.cifti(),
write.fs.morph.cifti(),
write.fs.parcellated.cifti(),
write.fs.parcellation.cifti(),
write.fs.series.cifti()
cifti_file <- system.file("extdata", "cifti", "tiny.dtseries.nii", package = "freesurferformats")
# The first two time points of all grayordinates:
first_frames <- read.cifti.rows(cifti_file, rows = 1:2)
dim(first_frames$data)
# A few time points and a few grayordinates:
subset <- read.cifti.rows(cifti_file, rows = 2, columns = 1:3)
subset$data
Run the code above in your browser using DataLab