pcntoolkit.longitudinal.correlation_matrix#

Age-to-age z-score correlation matrices for longitudinal scores.

Classes#

CorrelationMatrix

How strongly a person's z-scores at two timepoints correlate.

Module Contents#

class CorrelationMatrix(matrix: xarray.DataArray, *, covariate: str = 'age', bandwidth: int | None = None, max_correlation: float = 0.99, n_subjects: int | None = None, estimated_range: tuple[int, int] | None = None)#

How strongly a person’s z-scores at two timepoints correlate.

Do not call CorrelationMatrix(...) directly. Use compute to estimate one from your data, or load to read saved CSV files.

Examples

Estimate a matrix from your own longitudinal controls:

>>> from pcntoolkit import CorrelationMatrix
>>> corr = CorrelationMatrix.compute(controls, bandwidth=5)
>>> corr.n_subjects
67

Save it as one CSV per region, and load the folder back later:

>>> corr.save("my_matrices")
>>> corr = CorrelationMatrix.load("my_matrices")

Or load a single region:

>>> corr = CorrelationMatrix.load("my_matrices/rh_G_front_middle_thickness.csv")

Either way, pass it to a velocity model:

>>> from pcntoolkit import VelocityModel
>>> velocity = VelocityModel(model, corr)
Parameters:
  • matrix (xr.DataArray) – The correlations, filled in by compute and load.

  • covariate (str, default "age") – Covariate the matrix is indexed by.

  • bandwidth (int, optional) – Widest age gap that has a correlation. Wider gaps are 0.

  • max_correlation (float, default 0.99) – Cap on correlations read with get_correlation, so the z-gain never divides by zero (as it divides by sqrt(1 - r²))

  • n_subjects (int, optional) – Number of subjects the matrix was estimated from.

  • estimated_range (tuple of int, optional) – (min, max) ages actually seen in those subjects. Values outside it are extrapolated. The matrix itself always starts at age 0.

matrix#

The correlations.

Type:

xr.DataArray

Raises:

ValueError – If max_correlation is not strictly between 0 and 1.

classmethod compute(data: pcntoolkit.dataio.norm_data.NormData, *, bandwidth: int = 5, covariate: str = 'age', max_correlation: float = 0.99) → CorrelationMatrix#

Estimate the correlation matrix from your own longitudinal data.

Warning

This method is still under development and might change in the future.

Parameters:
  • data (NormData) – Subjects with two or more visits and z-scores already predicted.

  • bandwidth (int, default 5) – Widest age gap, in years, to estimate correlations for. Correlations for wider gaps are set to 0.

  • covariate (str, default "age") – Covariate to compute correlations over.

  • max_correlation (float, default 0.99) – Cap on correlations read with get_correlation, so the z-gain never divides by zero (as it divides by sqrt(1 - r²))

Returns:

The matrix, plus the number of subjects and the age range it was estimated from.

Return type:

CorrelationMatrix

Raises:

ValueError – If data has no predictions, is not longitudinal, or if max_correlation is out of range.

get_correlation(response_var: str, timepoint_1: int, timepoint_2: int) → float#

Read the correlation between two timepoints for one response variable.

For example, corr.get_correlation("lh_thickness", 40, 41) is how strongly a z-score at age 40 predicts the z-score at age 41. Ages beyond the matrix are moved to its nearest edge.

Parameters:
  • response_var (str) – Response variable to read.

  • timepoint_1 (int) – The two timepoints to get the correlation for.

  • timepoint_2 (int) – The two timepoints to get the correlation for.

Returns:

The correlation, kept between -max_correlation and +max_correlation (default 0.99).

Return type:

float

Raises:

KeyError – If the matrix holds no correlations for the model’s response_var.

classmethod load(path: str, *, covariate: str = 'age', max_correlation: float = 0.99) → CorrelationMatrix#

Load correlation matrices from a folder of CSVs, or from one CSV.

Each CSV holds one response variable and is named after it, as written by save:

<path>/<response_var>.csv

A folder loads every .csv in it, so keep only correlation matrices there. A file loads that one response variable. The file name, without .csv, must match the response variable in the normative model the matrix is used with.

Only the correlations are stored, so bandwidth, n_subjects and estimated_range are None.

Parameters:
  • path (str) – Folder written by save, or one CSV inside it.

  • covariate (str, default "age") – Covariate the matrix is indexed by.

  • max_correlation (float, default 0.99) – Cap on correlations read with get_correlation, so the z-gain never divides by zero (as it divides by sqrt(1 - r²))

Returns:

The loaded matrix, with one entry along response_vars per CSV.

Return type:

CorrelationMatrix

Raises:
  • FileNotFoundError – If path does not exist, or is a folder without .csv files.

  • ValueError – If a CSV’s header row and first column are not the covariate values 0, 1, …, N-1, if the CSVs differ in size, or if a CSV has empty cells, correlations outside -1 to 1, or is not symmetric.

classmethod load_velocity_pickle(path: str) → CorrelationMatrix#

Load a correlation matrix from a pickled velocity model.

Note: this reads one specific layout: the velocity models produced by Johanna Bayer’s pipeline. It is not a general-purpose loader. Use it once to convert such a file, then save it with save and load the result with load.

Those files hold a dict whose A_sparse_predict entry is the correlations, stored lower-triangular with a zero diagonal. They are mirrored and given a unit diagonal here to match the layout produced by compute_correlation_matrix.

The region name is not inside the file. It appears only in the directory name, laid out as .../batch_<n>_<region>/Velocity/<file>.pkl, so it is read from there. The region must match the one the normative model was fitted on, since scoring selects the matrix by that label.

Parameters:

path (str) – Path to the .pkl file, inside a batch_<n>_<region> directory.

Returns:

The loaded matrix.

Return type:

CorrelationMatrix

Raises:
  • KeyError – If the file has no A_sparse_predict entry.

  • ValueError – If no batch_<n>_<region> directory is found in path.

save(path: str) → None#

Save the matrix as one CSV per response variable in a folder:

<path>/<response_var>.csv

Each CSV has the covariate values (0, 1, …, N-1) as both the header row and the first column, with an empty top-left cell.

Parameters:

path (str) – Folder to write to. Created if it does not exist.

Return type:

None

bandwidth = None#
covariate = 'age'#
estimated_range = None#
matrix#
max_correlation = 0.99#
n_subjects = None#