libfs
Header-only C++11 library for accessing FreeSurfer neuroimaging data
Classes | Macros | Functions | Variables
libfs.h File Reference
#include <iostream>
#include <climits>
#include <stdio.h>
#include <vector>
#include <fstream>
#include <cassert>
#include <sstream>
#include <stdexcept>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <cmath>
#include <algorithm>
#include <chrono>
#include <cstdint>
#include <cstring>
Include dependency graph for libfs.h:

Go to the source code of this file.

Classes

struct  fs::Mesh
 Models a triangular mesh, used for brain surface meshes. More...
 
struct  fs::Curv
 Models a FreeSurfer curv file that contains per-vertex float data. More...
 
struct  fs::Colortable
 The colortable from an Annot file, can be used for parcellations and integer labels. Typically each index (in all fields) describes a brain region. More...
 
struct  fs::Annot
 An annotation, also known as a brain surface parcellation. Assigns to each vertex a region, identified by the region_label. The region name and color for each region can be found in the Colortable. More...
 
struct  fs::MghHeader
 Models the header of an MGH file. More...
 
struct  fs::MghData
 Models the data of an MGH file. Currently these are 1D vectors, but one can compute the 4D array using the dimXlength fields of the respective MghHeader. More...
 
struct  fs::Mgh
 Models a whole MGH file. More...
 
struct  fs::Array4D< T >
 A simple 4D array datastructure, useful for representing volume data. More...
 
struct  fs::Nifti1Header
 NIfTI-1 header structure (348 bytes, packed). More...
 
struct  fs::Label
 

Macros

#define LIBFS_VERSION   "0.5.0"
 Full libfs version string, in semver format. More...
 
#define LIBFS_VERSION_MAJOR   0
 Major version number (incompatible API changes). More...
 
#define LIBFS_VERSION_MINOR   5
 Minor version number (backward-compatible feature additions). More...
 
#define LIBFS_VERSION_PATCH   0
 Patch version number (backward-compatible bug fixes). More...
 
#define LIBFS_MAX_ALLOC_BYTES_DEFAULT   (2ULL * 1024ULL * 1024ULL * 1024ULL)
 
#define LIBFS_MAX_ALLOC_BYTES   LIBFS_MAX_ALLOC_BYTES_DEFAULT
 Maximum memory allocation limit.
 
#define LIBFS_MAX_STRING_LENGTH   4096
 Maximum length for fixed-length strings read from binary headers (e.g., filenames in annot colortables).
 
#define LIBFS_MAX_COLORTABLE_ENTRIES   10000
 Maximum number of entries in an annotation colortable.
 
#define LIBFS_APPTAG   "[libfs] "
 Application tag prepended to every debug message from libfs. More...
 
#define LIBFS_DBG_WARNING
 Default debug level: emit warnings and everything more severe. More...
 
#define LIBFS_DBG_ERROR
 Debug level: emit errors and everything more severe. More...
 
#define LIBFS_DBG_CRITICAL
 Debug level: emit only critical errors. More...
 

Functions

std::string fs::util::time_tag (std::chrono::system_clock::time_point t)
 Get current time as string, e.g. for log messages. More...
 
void fs::util::log (std::string const &message, std::string const loglevel="INFO")
 Log a message, goes to stdout. More...
 
template<typename T >
std::vector< T > fs::util::vflatten (std::vector< std::vector< T >> values)
 Flatten 2D vector. More...
 
bool fs::util::starts_with (std::string const &value, std::initializer_list< std::string > prefixes)
 Check whether a string starts with one of the given prefixes. More...
 
bool fs::util::file_exists (const std::string &name)
 Check whether a file exists (can be read) at given path. More...
 
std::string fs::util::fullpath (std::initializer_list< std::string > path_components, std::string path_sep=std::string("/"))
 Construct a UNIX file system path from the given path_components. More...
 
void fs::util::str_to_file (const std::string &filename, const std::string rep)
 Write the given text representation (any string) to a file. More...
 
std::vector< uint8_t > fs::util::viridis (const std::vector< float > &data, float vmin=NAN, float vmax=NAN, uint8_t nan_r=255, uint8_t nan_g=255, uint8_t nan_b=255)
 Map per-vertex numeric data to RGB colors using the Viridis perceptually-uniform colormap. More...
 
void fs::read_nifti (Mgh *mgh, std::istream *is, bool force_standard)
 Read a NIfTI-1 file into an Mgh struct (stream overload). More...
 
void fs::read_nifti (Mgh *mgh, const std::string &filename, bool force_standard)
 Read a NIfTI-1 file into an Mgh struct (filename overload). More...
 
void fs::read_mgh_header (MghHeader *mgh_header, const std::string &filename)
 Read the header of a FreeSurfer volume file in MGH format into the given MghHeader struct. More...
 
void fs::read_mgh_header (MghHeader *mgh_header, std::istream *is)
 Read an MGH header from a stream. More...
 
void fs::read_mgh (Mgh *mgh, const std::string &filename)
 Read a FreeSurfer volume file in MGH format into the given Mgh struct. More...
 
std::vector< std::string > fs::read_subjectsfile (const std::string &filename)
 Read a vector of subject identifiers from a FreeSurfer subjects file. More...
 
void fs::write_subjectsfile (const std::string &filename, const std::vector< std::string > &subjects)
 Write a vector of subject identifiers to a FreeSurfer subjects file. More...
 
void fs::read_mgh (Mgh *mgh, std::istream *is)
 Read MGH data from a stream. More...
 
void fs::read_surf (Mesh *surface, const std::string &filename)
 Read a brain mesh from a file in binary FreeSurfer 'surf' format into the given Mesh instance. More...
 
void fs::read_mesh (Mesh *surface, const std::string &filename)
 Read a triangular mesh from a surf, obj, or ply file into the given Mesh instance. More...
 
void fs::read_curv (Curv *curv, std::istream *is, const std::string &source_filename="")
 Read per-vertex brain morphometry data from a FreeSurfer curv stream. More...
 
void fs::read_curv (Curv *curv, const std::string &filename)
 Read Curv instance from a FreeSurfer curv format file. More...
 
void fs::read_annot (Annot *annot, std::istream *is)
 Read a FreeSurfer annotation or brain surface parcellation from an annot stream. More...
 
void fs::read_annot (Annot *annot, const std::string &filename)
 Read a FreeSurfer annotation from a file. More...
 
std::vector< float > fs::read_curv_data (const std::string &filename)
 Read per-vertex brain morphometry data from a FreeSurfer curv format file. More...
 
std::vector< float > fs::read_desc_data (const std::string &filename)
 Read per-vertex brain morphometry data from a FreeSurfer curv, MGH, or NIfTI format file. More...
 
void fs::write_annot (const Annot &annot, std::ostream &os)
 Write a FreeSurfer annotation (brain surface parcellation) to a stream. More...
 
void fs::write_annot (const Annot &annot, const std::string &filename)
 Write a FreeSurfer annotation (brain surface parcellation) to a file. More...
 
void fs::write_curv (std::ostream &os, std::vector< float > curv_data, int32_t num_faces=100000)
 Write curv data to a stream. More...
 
void fs::write_curv (const std::string &filename, std::vector< float > curv_data, const int32_t num_faces=100000)
 Write curv data to a file. More...
 
void fs::write_mgh (const Mgh &mgh, std::ostream &os)
 Write MGH data to a stream. More...
 
void fs::write_mgh (const Mgh &mgh, const std::string &filename)
 Write MGH data to a file. More...
 
void fs::write_nifti (const Mgh &mgh, std::ostream &os)
 Write MGH data to a NIfTI-1 file (stream overload). More...
 
void fs::write_nifti (const Mgh &mgh, const std::string &filename)
 Write MGH data to a NIfTI-1 file (filename overload). More...
 
Mgh fs::nifti_to_mgh (const std::string &filename)
 Convert a NIfTI-1 file directly to MGH by reading it. More...
 
void fs::write_surf (std::vector< float > vertices, std::vector< int32_t > faces, std::ostream &os)
 Write a mesh to a stream in FreeSurfer surf format. More...
 
void fs::write_surf (std::vector< float > vertices, std::vector< int32_t > faces, const std::string &filename)
 Write a mesh to a binary file in FreeSurfer surf format. More...
 
void fs::write_surf (const Mesh &mesh, const std::string &filename)
 Write a mesh to a binary file in FreeSurfer surf format. More...
 
void fs::read_label (Label *label, std::istream *is)
 Read a FreeSurfer ASCII label from a stream. More...
 
void fs::read_label (Label *label, const std::string &filename)
 Read a FreeSurfer ASCII label from a file. More...
 
void fs::write_label (const Label &label, std::ostream &os)
 Write label data to a stream. More...
 
void fs::write_label (const Label &label, const std::string &filename)
 Write label data to a file. More...
 
void fs::write_mesh (const Mesh &mesh, const std::string &filename)
 Write a mesh to a file in different formats. More...
 
void fs::write_mesh (const Mesh &mesh, const std::string &filename, const std::vector< uint8_t > col)
 Write a mesh to a file in different formats, with vertex colors. More...
 

Variables

const std::string fs::util::LOGTAG_CRITICAL = "CRITICAL"
 Logging threshold for critical messages.
 
const std::string fs::util::LOGTAG_ERROR = "ERROR"
 Logging threshold for error messages.
 
const std::string fs::util::LOGTAG_WARNING = "WARNING"
 Logging threshold for warning messages.
 
const std::string fs::util::LOGTAG_INFO = "INFO"
 Logging threshold for warning messages.
 
const std::string fs::util::LOGTAG_VERBOSE = "VERBOSE"
 Logging threshold for warning messages.
 
const std::string fs::util::LOGTAG_EXCESSIVE = "EXCESSIVE"
 Logging threshold for warning messages.
 
const int fs::MRI_UCHAR = 0
 MRI data type representing an 8 bit unsigned integer.
 
const int fs::MRI_INT = 1
 MRI data type representing a 32 bit signed integer.
 
const int fs::MRI_FLOAT = 3
 MRI data type representing a 32 bit float.
 
const int fs::MRI_SHORT = 4
 MRI data type representing a 16 bit signed integer.
 
NIfTI-1 Data Type Constants

Pixel data type codes defined by the NIfTI-1 specification.

These constants correspond to the datatype field of the NIfTI-1 header. They encode both the underlying C type and the bit width. The numeric values are taken directly from the NIfTI-1 standard (see the nifti1.h reference implementation). When reading a file, the datatype field is compared against these constants to determine how to interpret the raw voxel bytes.

const int16_t fs::NIFTI_DT_NONE = 0
 No data / unknown type (value 0).
 
const int16_t fs::NIFTI_DT_BINARY = 1
 
const int16_t fs::NIFTI_DT_UINT8 = 2
 
const int16_t fs::NIFTI_DT_INT16 = 4
 
const int16_t fs::NIFTI_DT_INT32 = 8
 
const int16_t fs::NIFTI_DT_FLOAT32 = 16
 
const int16_t fs::NIFTI_DT_COMPLEX64 = 32
 
const int16_t fs::NIFTI_DT_FLOAT64 = 64
 
const int16_t fs::NIFTI_DT_RGB24 = 128
 
const int16_t fs::NIFTI_DT_INT8 = 256
 
const int16_t fs::NIFTI_DT_UINT16 = 512
 
const int16_t fs::NIFTI_DT_UINT32 = 768
 
const int16_t fs::NIFTI_DT_INT64 = 1024
 
const int16_t fs::NIFTI_DT_UINT64 = 1280
 
const int16_t fs::NIFTI_DT_FLOAT128 = 1536
 
const int16_t fs::NIFTI_DT_COMPLEX128 = 1792
 
const int16_t fs::NIFTI_DT_COMPLEX256 = 2048
 

Macro Definition Documentation

◆ LIBFS_APPTAG

#define LIBFS_APPTAG   "[libfs] "

Application tag prepended to every debug message from libfs.

Each line of output produced by the debug macros is prefixed with this string so users can identify which component emitted the message. Define LIBFS_APPTAG before including libfs.h to supply your own tag, e.g.:

#define LIBFS_APPTAG "[my-app] "
#include "libfs.h"

If left undefined, the default "[libfs] " is used.

◆ LIBFS_DBG_CRITICAL

#define LIBFS_DBG_CRITICAL

Debug level: emit only critical errors.

When defined, only the most severe messages are printed. Critical errors typically precede an exception that will terminate the application unless caught. Use this level in production to keep output minimal while still reporting fatal conditions.

◆ LIBFS_DBG_ERROR

#define LIBFS_DBG_ERROR

Debug level: emit errors and everything more severe.

When defined (directly by the user or through the cascading #ifdef chain), messages tagged as errors, as well as critical errors, are printed. Error-level messages indicate a problem that prevents the current operation from completing successfully (e.g., a file could not be parsed), but the application may still continue.

◆ LIBFS_DBG_WARNING

#define LIBFS_DBG_WARNING

Default debug level: emit warnings and everything more severe.

This is the built-in fallback when no LIBFS_DBG_* macro is defined by the user. Enabling LIBFS_DBG_WARNING also automatically activates LIBFS_DBG_ERROR and LIBFS_DBG_CRITICAL (see the cascading #ifdef chain below). Typical output includes recoverable problems such as unknown file metadata keys or deprecated API usage.

◆ LIBFS_MAX_ALLOC_BYTES_DEFAULT

#define LIBFS_MAX_ALLOC_BYTES_DEFAULT   (2ULL * 1024ULL * 1024ULL * 1024ULL)

Default maximum memory allocation limit in bytes (2 GiB). A header claiming to need more memory than this will be rejected.

◆ LIBFS_VERSION

#define LIBFS_VERSION   "0.5.0"

Full libfs version string, in semver format.

A "MAJOR.MINOR.PATCH" string, e.g. "0.4.2". Use this when displaying the library version to users or writing it into output file headers. For programmatic version checks, prefer the individual LIBFS_VERSION_MAJOR, LIBFS_VERSION_MINOR, and LIBFS_VERSION_PATCH integer macros.

◆ LIBFS_VERSION_MAJOR

#define LIBFS_VERSION_MAJOR   0

Major version number (incompatible API changes).

Incremented when the public API changes in a way that breaks source or binary compatibility. For example, bumping from 0 to 1 signals a stable first release. Combine with LIBFS_VERSION_MINOR and LIBFS_VERSION_PATCH to construct a complete semver identifier.

◆ LIBFS_VERSION_MINOR

#define LIBFS_VERSION_MINOR   5

Minor version number (backward-compatible feature additions).

Incremented when new functionality is added without breaking existing API contracts. Together with LIBFS_VERSION_MAJOR this forms the MAJOR.MINOR prefix used in release tags.

◆ LIBFS_VERSION_PATCH

#define LIBFS_VERSION_PATCH   0

Patch version number (backward-compatible bug fixes).

Incremented for bug-fix releases that do not add new features or change the public API. The full version string is LIBFS_VERSION_MAJOR.LIBFS_VERSION_MINOR.LIBFS_VERSION_PATCH.

Function Documentation

◆ file_exists()

bool fs::util::file_exists ( const std::string &  name)
inline

Check whether a file exists (can be read) at given path.

You should not rely on this as a pre-check when considering to open a file due to race conditions, just try-catch open in that case. This is intended to check whether a certain software run succeeded, by checking whether the key expected output files exist.

Parameters
namethe filename that should be checked.

Examples

bool exists = fs::util::file_exists("./study1/subject1/label/lh.aparc.annot");

◆ fullpath()

std::string fs::util::fullpath ( std::initializer_list< std::string >  path_components,
std::string  path_sep = std::string("/") 
)

Construct a UNIX file system path from the given path_components.

Any trailing or leading slash (path_sep) will be stripped from the individual components and replaced with a single one between two components. If the first path component started with a slash, that slash will be kept (absolute paths are left intact).

Parameters
path_componentsinit list of strings, the path components
path_seppath separator to use, typically / on Unix-based system.
Exceptions
std::invalid_argumenton empty
Returns
string representation of the path, using the path_sep.

Examples

std::string p = fs::util::fullpath({"path", "to", "file.txt"});
// Gives: "path/to/file.txt"
std::string p = fs::util::fullpath({"/path", "to", "file.txt"});
// Gives: "/path/to/file.txt"

◆ log()

void fs::util::log ( std::string const &  message,
std::string const  loglevel = "INFO" 
)
inline

Log a message, goes to stdout.

Parameters
messagethe message to be logged.
loglevelthe log level, one of fs::util::LOGTAG_*.

◆ nifti_to_mgh()

Mgh fs::nifti_to_mgh ( const std::string &  filename)
inline

Convert a NIfTI-1 file directly to MGH by reading it.

This is just a convenience wrapper: read_nifti already populates an Mgh struct, so this provides a more explicit name for the "convert" use case.

Parameters
filenamePath to the input .nii or .nii.gz file.
Returns
An Mgh instance containing the NIfTI data.
Exceptions
std::runtime_erroron read errors.

◆ read_annot() [1/2]

void fs::read_annot ( Annot annot,
std::istream *  is 
)

Read a FreeSurfer annotation or brain surface parcellation from an annot stream.

A brain parcellations contains a region table and assigns to each vertex of a surface a region.

Parameters
annotAn Annot instance to be filled.
isAn open istream from which to read the annot data.
Exceptions
domain_errorif the file format version is not supported or the file is missing the color table.

◆ read_annot() [2/2]

void fs::read_annot ( Annot annot,
const std::string &  filename 
)

Read a FreeSurfer annotation from a file.

Parameters
annotAn Annot instance that should be filled.
filenamePath to the label file that should be read.
See also
There exists an overload to read from a stream instead.
Exceptions
runtime_errorif the file cannot be opened, domain_error if the file format version is not supported or the file is missing the color table.

Examples

std::string annot_fname = "lh.aparc.annot";
fs::Annot annot;
fs::read_annot(&annot, annot_fname);

◆ read_curv() [1/2]

void fs::read_curv ( Curv curv,
std::istream *  is,
const std::string &  source_filename = "" 
)

Read per-vertex brain morphometry data from a FreeSurfer curv stream.

The curv format is a simple binary format that stores one floating point value per vertex of a related brain surface.

Parameters
curvA Curv instance to be filled.
isAn open istream from which to read the curv data.
source_filenameOptional human-readable name for the data source (e.g., "lh.thickness"). When supplied, it is included in exception messages to help identify which file caused the error. Leave empty (the default) to omit the filename from diagnostics.
Exceptions
domain_errorif the curv file magic mismatches or the curv file header claims that the file contains more than 1 value per vertex.

◆ read_curv() [2/2]

void fs::read_curv ( Curv curv,
const std::string &  filename 
)

Read Curv instance from a FreeSurfer curv format file.

The curv format is a simple binary format that stores one floating point value per vertex of a related brain surface.

Parameters
curvA Curv instance to be filled.
filenamePath to a file from which to read the curv data.
Exceptions
runtime_errorif the file cannot be opened, domain_error if the curv file magic mismatches or the curv file header claims that the file contains more than 1 value per vertex.

Examples

fs::Curv curv;
fs::read_curv(&curv, "examples/read_curv/lh.thickness");

◆ read_curv_data()

std::vector<float> fs::read_curv_data ( const std::string &  filename)

Read per-vertex brain morphometry data from a FreeSurfer curv format file.

The curv format is a simple binary format that stores one floating point value per vertex of a related brain surface.

Parameters
filenamePath to a file from which to read the curv data.
Returns
a vector of float values, one per vertex.
Exceptions
runtime_errorif the file cannot be opened, domain_error if the curv file magic mismatches or the curv file header claims that the file contains more than 1 value per vertex.

Examples

std::string curv_fname = "lh.thickness";
std::vector<float> data = fs::read_curv_data(curv_fname);

◆ read_desc_data()

std::vector<float> fs::read_desc_data ( const std::string &  filename)
inline

Read per-vertex brain morphometry data from a FreeSurfer curv, MGH, or NIfTI format file.

Parameters
filenamePath to a file from which to read the data. If the name ends with '.mgh' / '.MGH' it is read as MGH; if it ends with '.nii' / '.nii.gz' it is read as NIfTI; otherwise it is assumed to be a curv file. The data must be of type MRI_FLOAT, and only one spatial dimension may have size > 1.
Returns
a vector of float values, one per vertex.
Exceptions
runtime_errorif the file cannot be opened, domain_error if the curv file magic mismatches or the curv file header claims that the file contains more than 1 value per vertex.

Examples

std::string curv_fname = "lh.thickness";
std::vector<float> data1 = fs::read_desc_data(curv_fname);
std::string mgh_fname = "lh.thickness.mgh";
std::vector<float> data2 = fs::read_desc_data(mgh_fname);
std::string nii_fname = "lh.thickness.nii.gz";
std::vector<float> data3 = fs::read_desc_data(nii_fname);

◆ read_label() [1/2]

void fs::read_label ( Label label,
std::istream *  is 
)

Read a FreeSurfer ASCII label from a stream.

A label is a list of vertices (for a surface label, given by index) or voxels (for a volume label, given by the xyz coordinates) and one floating point value per vertex/voxel. Sometimes a label is only used to define a set of vertices/voxels (like a certain brain region), and the values are irrelevant (and typically left at 0.0).

Parameters
labelA Label instance that should be filled.
isAn open std::istream or derived class stream from which to read the data, e.g., std::ifstream or std::istringstream.
See also
There exists an overload to read from a file instead.
Exceptions
std::domain_errorif the label data format is incorrect

◆ read_label() [2/2]

void fs::read_label ( Label label,
const std::string &  filename 
)

Read a FreeSurfer ASCII label from a file.

A label is a list of vertices (for a surface label, given by index) or voxels (for a volume label, given by the xyz coordinates) and one floating point value per vertex/voxel. Sometimes a label is only used to define a set of vertices/voxels (like a certain brain region), and the values are irrelevant (and typically left at 0.0).

Parameters
labelA Label instance that should be filled.
filenamePath to the label file that should be read.
See also
There exists an overload to read from a stream instead.
Exceptions
std::domain_errorif the label data format is incorrect, std::runtime_error if the file cannot be opened.

Examples

fs::Label label;
fs::read_label(&label, "subject1/label/lh.cortex.label");

◆ read_mesh()

void fs::read_mesh ( Mesh surface,
const std::string &  filename 
)

Read a triangular mesh from a surf, obj, or ply file into the given Mesh instance.

Parameters
surfacea Mesh instance representing a vertex-indexed tri-mesh. This will be filled.
filenameThe path to the file from which to read the mesh. The format will be determined from the file extension as follows. File names ending with '.obj' are loaded as Wavefront OBJ files. File names ending with '.ply' are loaded as Stanford PLY files in format version 'ascii 1.0'. All other files are loaded as FreeSurfer binary surf files.
Exceptions
runtime_errorif the file cannot be opened, domain_error if the surf file magic mismatches.

Examples

fs::mesh surface;
fs::read_mesh(&surface, "subject1/surf/lh.thickness");

◆ read_mgh() [1/2]

void fs::read_mgh ( Mgh mgh,
const std::string &  filename 
)

Read a FreeSurfer volume file in MGH format into the given Mgh struct.

Parameters
mghAn Mgh instance that should be filled with the data from the filename.
filenamePath to the input MGH file.
See also
There exists an overloaded version that reads from a stream.
Exceptions
runtime_errorif the file uses an unsupported MRI data type.

Examples

fs::Mgh mgh;
fs::read_mgh(&mgh, "somebrain.mgh");

◆ read_mgh() [2/2]

void fs::read_mgh ( Mgh mgh,
std::istream *  is 
)

Read MGH data from a stream.

Parameters
mghAn Mgh instance that should be filled with the data from the stream.
isPointer to an open istream from which to read the MGH data.
See also
There exists an overloaded version that reads from a file.
Exceptions
runtime_errorif the file uses an unsupported MRI data type.

◆ read_mgh_header() [1/2]

void fs::read_mgh_header ( MghHeader mgh_header,
const std::string &  filename 
)

Read the header of a FreeSurfer volume file in MGH format into the given MghHeader struct.

Parameters
mgh_headerAn MghHeader instance that should be filled with the data from the file.
filenamePath to the file from which to read the MGH data.
See also
There exists an overloaded version that reads from a stream.
Exceptions
runtime_errorif the file cannot be opened

◆ read_mgh_header() [2/2]

void fs::read_mgh_header ( MghHeader mgh_header,
std::istream *  is 
)

Read an MGH header from a stream.

Parameters
mgh_headerAn MghHeader instance that should be filled with the data from the stream.
isPointer to an open istream from which to read the MGH data.
See also
There exists an overloaded version that reads from a file.
Exceptions
runtime_errorif the file uses an unsupported MRI file format version. Only version 1 is supported (the only existing version to my knowledge).

◆ read_nifti() [1/2]

void fs::read_nifti ( Mgh mgh,
std::istream *  is,
bool  force_standard 
)
inline

Read a NIfTI-1 file into an Mgh struct (stream overload).

Parameters
mghThe Mgh instance to fill with the NIfTI data.
isAn open input stream positioned at the start of the NIfTI file.
force_standardIf true, reject non-conformant headers including the FreeSurfer hack.
Exceptions
std::runtime_erroron unsupported data types, I/O errors, or dimension overflows.

◆ read_nifti() [2/2]

void fs::read_nifti ( Mgh mgh,
const std::string &  filename,
bool  force_standard 
)
inline

Read a NIfTI-1 file into an Mgh struct (filename overload).

Auto-detects .nii and .nii.gz by file extension.

Parameters
mghThe Mgh instance to fill with the NIfTI data.
filenamePath to the input file (.nii or .nii.gz).
force_standardIf true, reject non-conformant headers including the FreeSurfer hack.
Exceptions
std::runtime_erroron unsupported data types, I/O errors, or dimension overflows.

◆ read_subjectsfile()

std::vector<std::string> fs::read_subjectsfile ( const std::string &  filename)

Read a vector of subject identifiers from a FreeSurfer subjects file.

Parameters
filenamea text file that contains one subject identifier per line.
Exceptions
runtime_errorif the file cannot be read

Examples

std::vector<std::string> subjects = fs::read_subjectsfile("subjects.txt");

◆ read_surf()

void fs::read_surf ( Mesh surface,
const std::string &  filename 
)

Read a brain mesh from a file in binary FreeSurfer 'surf' format into the given Mesh instance.

Parameters
surfacea Mesh instance representing a vertex-indexed tri-mesh. This will be filled.
filenameThe path to the file from which to read the mesh. Must be in binary FreeSurfer surf format. An example file is surf/lh.white.
Exceptions
runtime_errorif the file cannot be opened, domain_error if the surf file magic mismatches.
See also
fs::read_mesh, a generalized version that supports other mesh file formats as well.

Examples

fs::Mesh surface;
fs::read_surf(&surface, "lh.white");

◆ starts_with()

bool fs::util::starts_with ( std::string const &  value,
std::initializer_list< std::string >  prefixes 
)
inline

Check whether a string starts with one of the given prefixes.

Parameters
valuethe string for which to check whether it starts with any of the prefixes
prefixesthe prefixes to consider
Returns
whether the string starts with one of the prefixes.

Examples

bool ev = fs::util::starts_with("freesurfer", {"free", "not"}); // true

◆ str_to_file()

void fs::util::str_to_file ( const std::string &  filename,
const std::string  rep 
)

Write the given text representation (any string) to a file.

Parameters
filenamethe file to which to write, will be overwritten if exists
repthe string to write to the file
Exceptions
std::runtime_errorif the file cannot be opened.

Examples

fs::util::str_to_file("thoughts.txt", "blah, blah, blah");

◆ time_tag()

std::string fs::util::time_tag ( std::chrono::system_clock::time_point  t)

Get current time as string, e.g. for log messages.

Parameters
tthe timepoint to format as a string, typically std::system_clock::now().
Returns
the formatted time string.

Examples

std::string time_rep = fs::util::time_tag(std::chrono::system_clock::now());

◆ vflatten()

template<typename T >
std::vector<T> fs::util::vflatten ( std::vector< std::vector< T >>  values)

Flatten 2D vector.

Parameters
valuesthe input 2D vector.
Returns
1D vector.

Examples

std::vector<float> input = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 };
std::vector<std::vector<float>> res = fs::util::v2d(input, 2);

◆ viridis()

std::vector<uint8_t> fs::util::viridis ( const std::vector< float > &  data,
float  vmin = NAN,
float  vmax = NAN,
uint8_t  nan_r = 255,
uint8_t  nan_g = 255,
uint8_t  nan_b = 255 
)

Map per-vertex numeric data to RGB colors using the Viridis perceptually-uniform colormap.

This converts the output of fs::read_curv_data (or any per-vertex float vector) into the RGB color vector expected by fs::Mesh::to_ply() / fs::Mesh::to_ply_file() (and the OFF variants). The returned vector contains 3 consecutive uint8_t values per vertex (red, green, blue), in the exact interleave order used by the mesh exporters (v0_red, v0_green, v0_blue, v1_red, ...). The input data is normalized to the [0, 1] range before sampling the colormap. By default the normalization range is computed from the finite (non-NaN) min and max of the input, and you can override either bound by passing a finite value for vmin and/or vmax (pass NAN for the bound(s) you want to be derived from the data). NaN input values are mapped to a configurable color, which defaults to white (255, 255, 255) following the standard convention in neuroimaging where missing data (e.g. the medial wall) is shown in white. Use the nan_r / nan_g / nan_b parameters to change this color. The Viridis colormap is implemented from its official 256-sample lookup table (the same data used by matplotlib), with linear interpolation between samples, so there are no external dependencies.

Parameters
datathe per-vertex scalar values to convert (one value per vertex).
vminthe value mapped to the bottom of the colormap. Pass NAN (the default) to auto-compute it as the finite minimum of data.
vmaxthe value mapped to the top of the colormap. Pass NAN (the default) to auto-compute it as the finite maximum of data.
nan_rthe red component (0..255) of the color used for NaN input values. Defaults to 255 (white).
nan_gthe green component (0..255) of the color used for NaN input values. Defaults to 255 (white).
nan_bthe blue component (0..255) of the color used for NaN input values. Defaults to 255 (white).
Returns
a vector of 3 * data.size() uint8_t RGB color values, interleaved by vertex, ready for fs::Mesh::to_ply().
Exceptions
std::invalid_argumentif vmin and vmax are both given but vmin is greater than vmax.

Examples

std::vector<float> data = fs::read_curv_data("lh.thickness");
// NaN values map to white by default, override the value range via vmin/vmax:
std::vector<uint8_t> col = fs::util::viridis(data);
surface.to_ply_file("lh.thickness.ply", col);
// Optionally clip the value range, e.g. to [0.5, 4.0]:
std::vector<uint8_t> col2 = fs::util::viridis(data, 0.5f, 4.0f);
surface.to_ply_file("lh.thickness_clipped.ply", col2);
// Optionally change the NaN color, e.g. to black:
std::vector<uint8_t> col3 = fs::util::viridis(data, NAN, NAN, 0, 0, 0);
surface.to_ply_file("lh.thickness_black_nan.ply", col3);

◆ write_annot() [1/2]

void fs::write_annot ( const Annot annot,
std::ostream &  os 
)

Write a FreeSurfer annotation (brain surface parcellation) to a stream.

Parameters
annotThe Annot instance to write.
osAn open output stream (binary mode).
See also
There exists an overload to write to a file.
Exceptions
std::domain_errorif the annot or colortable data is inconsistent.

◆ write_annot() [2/2]

void fs::write_annot ( const Annot annot,
const std::string &  filename 
)

Write a FreeSurfer annotation (brain surface parcellation) to a file.

Parameters
annotThe Annot instance to write.
filenamePath to the output file.
See also
There exists an overload to write to a stream.
Exceptions
std::runtime_errorif the file cannot be opened.

Examples

fs::Annot annot;
fs::read_annot(&annot, "lh.aparc.annot");
// modify annot here …
fs::write_annot(annot, "lh.aparc.modified.annot");

◆ write_curv() [1/2]

void fs::write_curv ( std::ostream &  os,
std::vector< float >  curv_data,
int32_t  num_faces = 100000 
)

Write curv data to a stream.

A curv file contains one floating point value per vertex (or a related mesh).

Parameters
osAn output stream to which to write the data. The stream must be open, and this function will not close it after writing to it.
curv_datathe data to write.
num_facesthe value for the header field num_faces. This is not needed afaik and typically ignored.

◆ write_curv() [2/2]

void fs::write_curv ( const std::string &  filename,
std::vector< float >  curv_data,
const int32_t  num_faces = 100000 
)

Write curv data to a file.

A curv file contains one floating point value per vertex (or a related mesh).

Parameters
filenameThe path to the output file.
curv_datathe data to write.
num_facesthe value for the header field num_faces. This is not needed afaik and typically ignored.
Exceptions
std::runtime_errorif the file cannot be opened.

Examples

std::vector<float> data = fs::read_curv_data("lh.thickness");
// Do something with 'data' here, maybe?
fs::write_curv("output.curv", data);

◆ write_label() [1/2]

void fs::write_label ( const Label label,
std::ostream &  os 
)

Write label data to a stream.

Parameters
labelThe label to write.
osAn open output stream.
See also
There exists an onverload of this function to write a label to a file.

◆ write_label() [2/2]

void fs::write_label ( const Label label,
const std::string &  filename 
)

Write label data to a file.

Parameters
labelan fs::Label instance
filenamePath to the label file that should be written.
See also
There exists an overload to write to a stream.
Exceptions
std::runtime_errorif the file cannot be opened.

Examples

fs::Label label;
fs::read_label(&label, "subject1/label/lh.cortex.label");
fs::write_label(label, "out.label");

◆ write_mesh() [1/2]

void fs::write_mesh ( const Mesh mesh,
const std::string &  filename 
)

Write a mesh to a file in different formats.

The output format will be auto-determined from the file extension.

Parameters
meshThe fs::Mesh instance to write.
filenameThe path to the output file.
Exceptions
std::runtime_errorif the file cannot be opened.

Examples

fs::write_mesh(surface, "cube.ply");
fs::write_mesh(surface, "cube.off");
fs::write_mesh(surface, "cube.obj");
fs::write_mesh(surface, "cube"); // writes FS surf format.

◆ write_mesh() [2/2]

void fs::write_mesh ( const Mesh mesh,
const std::string &  filename,
const std::vector< uint8_t >  col 
)

Write a mesh to a file in different formats, with vertex colors.

The output format will be auto-determined from the file extension. The colors are written for PLY, OFF, and OBJ formats; the surf format ignores them.

Parameters
meshThe fs::Mesh instance to write.
filenameThe path to the output file.
colu_char vector of RGB color values, 3 per vertex.
Exceptions
std::runtime_errorif the file cannot be opened.

Examples

fs::write_mesh(surface, "cube.ply", surface.vertex_colors);

◆ write_mgh() [1/2]

void fs::write_mgh ( const Mgh mgh,
std::ostream &  os 
)

Write MGH data to a stream.

The MGH format is a binary, big-endian FreeSurfer file format for storing 4D data. Several data types are supported, and one has to check the header to see which one is contained in a file.

Parameters
mghAn Mgh instance that should be written.
osAn output stream to which to write the data. The stream must be open, and this function will not close it after writing to it.
Exceptions
std::logic_errorif the mgh header and data are inconsistent, std::domain_error if the given MRI data type is unknown or unsupported.

◆ write_mgh() [2/2]

void fs::write_mgh ( const Mgh mgh,
const std::string &  filename 
)

Write MGH data to a file.

The MGH format is a binary, big-endian FreeSurfer file format for storing 4D data. Several data types are supported, and one has to check the header to see which one is contained in a file.

Parameters
mghAn Mgh instance that should be written.
filenamePath to an output file to which to write.
See also
There exists an overload to write to a stream.
Exceptions
std::runtime_errorif the file cannot be opened, std::logic_error if the mgh header and data are inconsistent, std::domain_error if the given MRI data type is unknown or unsupported.

Examples

fs::Mgh mgh;
fs::read_mgh(&mgh, "somebrain.mgh");
// Do something with 'mgh' here, maybe?
fs::write_mgh(mgh, "output.mgh");

◆ write_nifti() [1/2]

void fs::write_nifti ( const Mgh mgh,
std::ostream &  os 
)
inline

Write MGH data to a NIfTI-1 file (stream overload).

Writes a standard volumetric NIfTI-1 file in big-endian byte order (NIfTI-1 standard). The FreeSurfer hack is never produced.

Parameters
mghThe Mgh data to write.
osAn open output stream.
Exceptions
std::runtime_errorif any dimension exceeds 32767 or the data type is unsupported.

◆ write_nifti() [2/2]

void fs::write_nifti ( const Mgh mgh,
const std::string &  filename 
)
inline

Write MGH data to a NIfTI-1 file (filename overload).

Parameters
mghThe Mgh data to write.
filenamePath to the output file (.nii or .nii.gz).
Exceptions
std::runtime_errorif the file cannot be opened.

◆ write_subjectsfile()

void fs::write_subjectsfile ( const std::string &  filename,
const std::vector< std::string > &  subjects 
)

Write a vector of subject identifiers to a FreeSurfer subjects file.

Parameters
filenamePath to the output file (one subject ID per line).
subjectsThe subject identifiers to write.
Exceptions
std::runtime_errorif the file cannot be opened.

Examples

std::vector<std::string> subjects = {"subject1", "subject2"};
fs::write_subjectsfile("subjects.txt", subjects);

◆ write_surf() [1/3]

void fs::write_surf ( std::vector< float >  vertices,
std::vector< int32_t >  faces,
std::ostream &  os 
)

Write a mesh to a stream in FreeSurfer surf format.

A surf file contains a vertex index representation of a mesh, i.e., the vertices and faces vectors.

Parameters
verticesvector of float, length 3n for n vertices. The 3D coordinates of the vertices, typically from <Mesh_instance>.vertices.
facesvector of int, length 3n for n faces. The 3 vertex indices for each face, typically from <Mesh_instance>.faces.
osAn output stream to which to write the data. The stream must be open, and this function will not close it after writing to it.
Exceptions
std::runtime_errorif the file cannot be opened.

◆ write_surf() [2/3]

void fs::write_surf ( std::vector< float >  vertices,
std::vector< int32_t >  faces,
const std::string &  filename 
)

Write a mesh to a binary file in FreeSurfer surf format.

A surf file contains a vertex index representation of a mesh, i.e., the vertices and faces vectors.

Parameters
verticesvector of float, length 3n for n vertices. The 3D coordinates of the vertices, typically from <Mesh_instance>.vertices.
facesvector of int, length 3n for n faces. The 3 vertex indices for each face, typically from <Mesh_instance>.faces.
filenameThe path to the output file.
Exceptions
std::runtime_errorif the file cannot be opened.

Examples

fs::write_surf(surface.vertices, surface.faces, "lh.cube");

◆ write_surf() [3/3]

void fs::write_surf ( const Mesh mesh,
const std::string &  filename 
)

Write a mesh to a binary file in FreeSurfer surf format.

A surf file contains a vertex index representation of a mesh, i.e., the vertices and faces vectors.

Parameters
meshThe Mesh instance to write.
filenameThe path to the output file.
Exceptions
std::runtime_errorif the file cannot be opened.

Examples

fs::write_surf(surface, "lh.cube");

Variable Documentation

◆ NIFTI_DT_BINARY

const int16_t fs::NIFTI_DT_BINARY = 1

Binary mask: each voxel is a single bit packed into a byte (value 1). Useful for segmentation labels that are strictly 0 or 1.

◆ NIFTI_DT_COMPLEX128

const int16_t fs::NIFTI_DT_COMPLEX128 = 1792

Complex number stored as two consecutive 64-bit floats (real, imaginary), 128 bits total (value 1792).

◆ NIFTI_DT_COMPLEX256

const int16_t fs::NIFTI_DT_COMPLEX256 = 2048

Complex number stored as two consecutive 128-bit floats (real, imaginary), 256 bits total (value 2048). Highest precision complex storage; virtually never encountered in real-world datasets.

◆ NIFTI_DT_COMPLEX64

const int16_t fs::NIFTI_DT_COMPLEX64 = 32

Complex number stored as two consecutive 32-bit floats (real, imaginary), 64 bits total (value 32). Rarely used in practice; mainly for frequency-domain / phase data.

◆ NIFTI_DT_FLOAT128

const int16_t fs::NIFTI_DT_FLOAT128 = 1536

128-bit IEEE-754 quadruple-precision float (value 1536). Rarely supported in practice — most toolchains read it but fall back to double precision.

◆ NIFTI_DT_FLOAT32

const int16_t fs::NIFTI_DT_FLOAT32 = 16

32-bit IEEE-754 single-precision float (value 16). The most common floating-point format for processed neuroimaging data (e.g., z-statistics, correlation maps).

◆ NIFTI_DT_FLOAT64

const int16_t fs::NIFTI_DT_FLOAT64 = 64

64-bit IEEE-754 double-precision float (value 64). Preferred when numerical precision is critical, e.g., for deformation fields or when accumulating statistics.

◆ NIFTI_DT_INT16

const int16_t fs::NIFTI_DT_INT16 = 4

Signed 16-bit integer, range [-32768, 32767] (value 4). Widely used for structural MRI after scaling with scl_slope/ scl_inter.

◆ NIFTI_DT_INT32

const int16_t fs::NIFTI_DT_INT32 = 8

Signed 32-bit integer, range [-2^31, 2^31-1] (value 8). Used for high-dynamic-range label maps and processed statistical images.

◆ NIFTI_DT_INT64

const int16_t fs::NIFTI_DT_INT64 = 1024

Signed 64-bit integer, range [-2^63, 2^63-1] (value 1024). Suitable for high-precision integer processing and very large label spaces.

◆ NIFTI_DT_INT8

const int16_t fs::NIFTI_DT_INT8 = 256

Signed 8-bit integer, range [-128, 127] (value 256). Provides a compact representation when the dynamic range fits in a single signed byte.

◆ NIFTI_DT_RGB24

const int16_t fs::NIFTI_DT_RGB24 = 128

RGB triple: three consecutive uint8 values per voxel (R, G, B), 24 bits total (value 128). Used for 2-D colour images stored in NIfTI format (e.g., tissue-class overlays).

◆ NIFTI_DT_UINT16

const int16_t fs::NIFTI_DT_UINT16 = 512

Unsigned 16-bit integer, range [0, 65535] (value 512). Common in DICOM-derived data and some microscopy formats.

◆ NIFTI_DT_UINT32

const int16_t fs::NIFTI_DT_UINT32 = 768

Unsigned 32-bit integer, range [0, 2^32-1] (value 768). Useful for large label sets and extended-count voxel data.

◆ NIFTI_DT_UINT64

const int16_t fs::NIFTI_DT_UINT64 = 1280

Unsigned 64-bit integer, range [0, 2^64-1] (value 1280). The widest integral type available in the NIfTI-1 spec.

◆ NIFTI_DT_UINT8

const int16_t fs::NIFTI_DT_UINT8 = 2

Unsigned 8-bit integer, range [0, 255] (value 2). Common for RGB component planes, label masks, and CT data.