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 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::Label
 

Macros

#define LIBFS_VERSION   "0.3.4"
 
#define LIBFS_VERISION_MAJOR   0
 
#define LIBFS_VERISION_MINOR   3
 
#define LIBFS_VERISION_PATCH   4
 
#define LIBFS_APPTAG   "[libfs] "
 
#define LIBFS_DBG_WARNING
 
#define LIBFS_DBG_ERROR
 
#define LIBFS_DBG_CRITICAL
 

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...
 
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::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 format or MGH format 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_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...
 

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.
 

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_*.

◆ 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.
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)

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

Parameters
filenamePath to a file from which to read the data. If the name ends with '.mgh' or '.MGH', this function assumes it is an MGH file. Otherwise it assumes it is a curv file. If it is an MGH file, it must contain data of type MRI_FLOAT, and it must only contain data for one subject, i.e., all dimensions with the exception of the first one should 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);

◆ 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_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);

◆ 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()

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_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_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");