Authors
- Daniel Bullock ([email protected])
- Jasleen Jolly ([email protected])
Lab Directors
- Franco Pestilli ([email protected]) - The University of Texas at Austin
- Holly Bridge ([email protected]) - University of Oxford
(For MAIA readme, please proceed further down the document)
Before running this code (OCT)
Process OCT images from compatible systems with the Orion® software (Voxeleron, LLC, Pleasanton, CA, USA).
Label output csv files with a 3 components in the filename '000_OD_T.csv'
The first 3 digits are the patient identifier. Eye is signalled by OD for right and OS for left.
Create a file named 'Location.csv' to identify the foveal centre. This must contain the following data with the headings exactly as written:
Filename | Eye | slice | position | Size X pixel | Size x mm | Position on HEE |
---|
Size X pixels and X mm are determined by the OCT scan parameters and may be identical across all images. On the OCT software, such as Heidelberg, identify the foveal centre in the original image. Record the slice this is found in. The final column contains precise X location of the foveal centre. The pixel position (position) is then calculated by (SizeXpixel / SizeXmm) * Position on HEE.
If you have multiple groups in your dataset set up a group directory. For each group create a csv file containing a list of the 3 digit identifiers for the participants in that group.
Running this code (OCT)
This code is written in Matlab. It makes use of the imresize function and thus requires Matlab's image processing toolkit.
The primary wrapper function is OCTanalysisWrapper .m which goes from individual raw data all the way to group-level analysis. Thus, once the local github repository has been added to Matlab's path, running the contents of OCTanalysisWrapper.m (after setting paths appropriately) should be sufficient to perform the full analysis.
Ensure the correct pathways are set for (see below for further details):
rawSubjDataDir (input CSV files)
targetOutputDir (initial output)
analysisMeanDir (secondary output)
centroidCSVPath (Location file)
groupKeyDir (folder that specifies groups)
groupAnalysisDir (final output)
In addition, customise the following to your layers of interest:
layerIndexSequences={1:7,1:4,5,6,5:6};
analysesNames={'TT','IR','ONL','PROS','PC'};
This is based on the output from Orion:
The data is arranged as all_layers(width,slices,num_layers)
1: Reading layer: ILM to RNFL-posterior
2: Reading layer: RNFL-posterior to IPL-posterior
3: Reading layer: IPL-posterior to INL-posterior
4: Reading layer: INL-posterior to OPL-posterior
5: Reading layer: OPL-posterior to ONL-posterior
6: Reading layer: ONL-posterior to RPE
7: Reading layer: RPE to BRUCHS
Therefore, we read 8 layers when no additional layers are added.
Code details (OCT)
The wrapper,OCTanalysisWrapper_.m_ , directly calls the following functions:
Function name | Function description | Variable / Parameter inputs |
---|---|---|
parseCsvExport | Provided by Jonathan Oakley, Voxeleron. Allows reading in of segmented thickness measurements and sorting by layer | rawSubjDataDir |
createCSVsumOutputFiles | Iteratively takes data generated by Voxeleron's Orion for the accurate segmentation of OCT data, and computes subject-level amalgam csv outputs in accordance with requested layer sequences | rawSubjDataDir, targetOutputDir, layerIndexSequences, analysesNames, |
analyzeOCTDataWrapper | For each of the layer sequence amalgams generated by createCSVsumOutputFiles, performs an iterative, degree wise analysis and creates a subject-level output csv. | analysisMeanDir, centroidCSVPath, visFieldDiam, theshFloor, gaussKernel, meanShape, |
OCTGroupAnalysisWrapper | Creates group level analysis outputs based on a keyfile identifying group membership. | inputDir, groupKeyDir, outputDir |
Several of the variables are simply paths to files or directories containing necessary data/metadata
File/Path variable name | Contents | Structure/Naming convention |
---|---|---|
rawSubjDataDir | Directory containing subject-level data generated by Voxeleron's [deviceName] | Name(s): "[subjectNum]_[eyeLabel]_T.csv" Structure: TBD |
targetOutputDir | Directory containing (or to contain) the subject-level amalgam csv outputs generated by createCSVsumOutputFiles | Name(s): "[subjectNum]_[eyeLabel]_[layerLabel].csv" , Structure: TBD |
analysisMeanDir | Directory containing (or to contain) subject-level analyses (degree iterated means) | Name(s): "[subjectNum]_[eyeLabel]_meanTable.csv"&"[subjectNum]_[eyeLabel]_stdTable.csv" , Structure: TBD |
outputDir | Directory containing (or to contain) group-level analyses (degree-wise, cross-subject means) | Name(s): "[eyeLabel]_GroupMean_[groupLabel].csv"&"[eyeLabel]_StdMean_[groupLabel].csv" Structure: TBD |
centroidCSVPath | Path to a specific csv file which contains (among other information) the centroid location of each subject in the entire dataset | Name(s):"Location.csv"Structure: TBD |
groupKeyDir | A directory counting csv files (named after the group name) containing subject ID's corresponding to group membership | Name(s):"[groupLabel].xlsx Structure: TBD |
The rest of the variables are parameters which the user may modify in order to impact their analysis as desired.
Parameter variable name | Purpose | Specifications |
---|---|---|
layerIndexSequences | Indicates which layers are to be summed in createCSVsumOutputFiles to generate the layer amalgams that will be processed later. | Sequence[1] of sequence[2] of integers. Sequence[1] must be equal to the number of inputs in analysesNames. sequence[2] must be unique integers which do not exceed the total number of layers obtained from Voxeleron's [deviceName] |
analysesNames | Indicates the abbreviation for the layer amalgam, corresponds to [specify standard]. | Set of strings, equal in length to sequence[1] of layerIndexSequences |
visFieldDiam | Indicates the total diameter of the visual field measured by the experimenter. Assumed to be consistent across subjects. The user/experimenter should know this about their data.The code must be amended if this is not the case, e.g. retrospective analysis of clinical data. | Numerical value |
theshFloor | Specifies the desired threshold to be applied to input data obtained from createCSVsumOutputFiles. Applied across subjects (prior to computation of means). Values below this are set to NaN and are not featured in computation of mean. If no threshold is desired, enter a value of []. | Numerical value |
gaussKernel | Specifies the desired smoothing kernel to be applied to input data obtained from createCSVsumOutputFiles. Applied across subjects (prior to computation of means). Pixel values are thus the result of a gaussian smoothing process. If no threshold is desired, enter a value of [] or 1. | Odd integer value |
meanShape | Specifies the desired method for computing the mean. "rings" will generate averages for concentric, degree-specific rings (like a bullseye), while "full" will compute the mean for the entire visual field (to the specified current, iterated degree). | Either "rings" or "full" |
Before running this code (MAIA)
Running this code (MAIA)
This code is written in Matlab. It makes use of no specialized matlab toolkits
The primary wrapper function is MAIAwrapper .m which goes from individual raw data all the way to subject-level analysis. Thus, once the local github repository has been added to Matlab's path, running the contents of MAIAwrapper.m (after setting paths appropriately) should be sufficient to perform the full analysis.
Ensure the correct pathways are set for (see below for further details):
subjectDir (input txt files)
keyFile (folder that specifies groups)
outputDir (final output directory)
In addition, use the meanMethod variable to set whether you would like the iterative means computed as full shapes or as rings.
Code details (MAIA)
The wrapper, MAIAwrapper_.m_ , only calls a single function , computeGroupMAIAmeans.m, which creates output tables for both the index-based means, and the iterative, degree-based means.