library(oro.nifti)
oro.nifti 0.11.4
<-readNIfTI("./Data-Use/mca_notpa.nii.gz", reorient = FALSE)
mca
range(mca)
[1] 0.000000000 0.001411765
R can handle a variety of different data format. Medical images are stored as DICOM files for handling and converted to nifti files for analysis. The workhorses are the oro.dicom and oro.nifti libraries. Nifti is an S4 class object with multiple slots for data type. These slots can be accessed by typing the @ after the handle of the file. The values in an image can be evaluated using range function. Alternately, use cal_max and cal_min to perform the same task. It appears that in the conversion from minc file to nifti file, a scaling factor has been applied and transformed the values.
library(oro.nifti)
oro.nifti 0.11.4
<-readNIfTI("./Data-Use/mca_notpa.nii.gz", reorient = FALSE)
mca
range(mca)
[1] 0.000000000 0.001411765
The slots also contain information on whether the data has been scaled. This can be checked by accessing the scl_slope and scl_inter slots. These data on slope and intercept provide a mean of returning an image to its correct value.
@scl_slope mca
[1] 1
To find available slots
#find available of slots
slotNames(mca)
[1] ".Data" "sizeof_hdr" "data_type" "db_name"
[5] "extents" "session_error" "regular" "dim_info"
[9] "dim_" "intent_p1" "intent_p2" "intent_p3"
[13] "intent_code" "datatype" "bitpix" "slice_start"
[17] "pixdim" "vox_offset" "scl_slope" "scl_inter"
[21] "slice_end" "slice_code" "xyzt_units" "cal_max"
[25] "cal_min" "slice_duration" "toffset" "glmax"
[29] "glmin" "descrip" "aux_file" "qform_code"
[33] "sform_code" "quatern_b" "quatern_c" "quatern_d"
[37] "qoffset_x" "qoffset_y" "qoffset_z" "srow_x"
[41] "srow_y" "srow_z" "intent_name" "magic"
[45] "extender" "reoriented"
In this example below we will simulated an image of dimensions 5 by 5 by 5. see [simulation using mand library][PCA with MRI].
library(oro.nifti)
set.seed(1234)
= rep(5, 3)
dims = array(rnorm(5*5*5), dim = dims)
SimArr = oro.nifti::nifti(SimArr)
SimIm print(SimIm)
NIfTI-1 format
Type : nifti
Data Type : 2 (UINT8)
Bits per Pixel : 8
Slice Code : 0 (Unknown)
Intent Code : 0 (None)
Qform Code : 0 (Unknown)
Sform Code : 0 (Unknown)
Dimension : 5 x 5 x 5
Pixel Dimension : 1 x 1 x 1
Voxel Units : Unknown
Time Units : Unknown
View the simulated image.
::ortho2(SimIm) neurobase
This section provides a brief introduction to viewing nifti files. Data are stored as rows, columns and slices. To view sagital image then assign a number to the row data.
#plot mca #sagittal
image(mca[50,,])
To see coronal image, assign a number to the column data.
#plot mca #coronal
image(mca[,70,])
To see axial image, assign a number to the slice data.
#plot mca #axial in third column
image(mca[,,35])
These arrays of medical images should be treated no differently from any other arrays. The imaging data are stored as arrays within the .Data slot in nifti.
Data can be subset using the square bracket. The image is referred to x (right to left), y (front to back), z (superior to inferior).
library(oro.nifti)
#extract data as array using @ function
<-readNIfTI("./Data-Use/mca_notpa.nii.gz", reorient = FALSE)
img<-img@.Data
k
#change x orientation to right to left 91*109*91
<-k[91:1,,]
k1#access slice 35 to verify that the image orientation has been switched.
image(k1[,,35])
With the image now flipped to the other side, we can create an image by returning the array into its data slot.
<-img
img2@.Data <- k1
img2 img2
NIfTI-1 format
Type : nifti
Data Type : 16 (FLOAT32)
Bits per Pixel : 32
Slice Code : 0 (Unknown)
Intent Code : 0 (None)
Qform Code : 0 (Unknown)
Sform Code : 1 (Scanner_Anat)
Dimension : 91 x 109 x 91
Pixel Dimension : 2 x 2 x 2
Voxel Units : mm
Time Units : sec
Arrays can be manipulated to split an image into 2 separate images. Below is a function to split B0 and B1000 images from diffusion series.
#split dwi file into b0 and b1000
#assume that b1000 is the second volume
#dwi<-readNIfTI("....nii.gz",reorient = F)
<-function(D) {
DWIsplit<-readNIfTI(D,reorient = F)
DWI<-dwi #dim (b1000) [1] 384 384 32 2
b1000<-dwi@.Data
k<-k[,,,2] #dim(b1000k) [1] 384 384 32
b1000kwriteNIfTI(b1000k,"b1000")
}
Measurement of volume requires information on the dimensions of voxel.
#measure volume
="./Ext-Data/3000F_mca_blur.nii"
A
<-function(A){
VoxelDimlibrary(oro.nifti)
<-readNIfTI(A,reorient = F)
img<-pixdim(img)
VoxDim<-sum(img>.5)*VoxDim[2]*VoxDim[3]*VoxDim[4]/1000
Volume
Volume
}
VoxelDim(A)
Malformed NIfTI - not reading NIfTI extension, use at own risk!
[1] 69
Find unsigned angle between 2 vectors k and k1
::angle.calc(k,k1) Morpho
[1] 1.570771
Determine centre of gravity of an object.
#centre of gravity
::cog(img) neurobase
dim1 dim2 dim3
65.74983 53.09204 46.67048
This is an illustration of combining array using cbind.
#stack arrays
<-cbind(k,k1)
k2dim(k2) ### [1] 902629 2
[1] 902629 2
The abind function produces a different array output. Later we will repeat the same exercise using list function.
#combine multi-dimensional arrays
<-abind::abind(k,k1)
abdim(ab) ### [1] 91 109 182
[1] 91 109 182
This example uses 25 files. Rather than open one file at a time create a list from pattern matching.
library(oro.nifti)
library(abind)
library(CHNOSZ) # for working with arrays
CHNOSZ version 2.0.0 (2023-03-13)
reset: creating "thermo" object
OBIGT: loading default database with 1904 aqueous, 3448 total species
Attaching package: 'CHNOSZ'
The following object is masked from 'package:oro.nifti':
slice
library(RNiftyReg)
Attaching package: 'RNiftyReg'
The following objects are masked from 'package:oro.nifti':
pixdim, pixdim<-
#create a list using pattern matching
<-list.files(path="./Ext-Data/",pattern = "*.nii", full.names = TRUE)
mca.list
#length of list
length(mca.list)
[1] 42
#read multiple files using lapply function
#use lappy to read in the nifti files
#note lapply returns a list
<- lapply(mca.list, readNIfTI) mca.list.nii
Malformed NIfTI - not reading NIfTI extension, use at own risk!
Malformed NIfTI - not reading NIfTI extension, use at own risk!
Malformed NIfTI - not reading NIfTI extension, use at own risk!
Malformed NIfTI - not reading NIfTI extension, use at own risk!
Malformed NIfTI - not reading NIfTI extension, use at own risk!
Malformed NIfTI - not reading NIfTI extension, use at own risk!
Malformed NIfTI - not reading NIfTI extension, use at own risk!
Malformed NIfTI - not reading NIfTI extension, use at own risk!
Malformed NIfTI - not reading NIfTI extension, use at own risk!
Malformed NIfTI - not reading NIfTI extension, use at own risk!
Malformed NIfTI - not reading NIfTI extension, use at own risk!
Malformed NIfTI - not reading NIfTI extension, use at own risk!
Malformed NIfTI - not reading NIfTI extension, use at own risk!
Malformed NIfTI - not reading NIfTI extension, use at own risk!
Malformed NIfTI - not reading NIfTI extension, use at own risk!
Malformed NIfTI - not reading NIfTI extension, use at own risk!
Malformed NIfTI - not reading NIfTI extension, use at own risk!
Malformed NIfTI - not reading NIfTI extension, use at own risk!
Malformed NIfTI - not reading NIfTI extension, use at own risk!
Malformed NIfTI - not reading NIfTI extension, use at own risk!
Malformed NIfTI - not reading NIfTI extension, use at own risk!
Malformed NIfTI - not reading NIfTI extension, use at own risk!
Malformed NIfTI - not reading NIfTI extension, use at own risk!
Malformed NIfTI - not reading NIfTI extension, use at own risk!
Malformed NIfTI - not reading NIfTI extension, use at own risk!
class(mca.list.nii)
[1] "list"
This example illustrates how to view the first image in the list.
#view each image in the list
::ortho2(mca.list.nii[[1]]) neurobase
In this example, the first 3 segmented images from the list are averaged and viewed.
#view average image
<-(mca.list.nii[[5]]+mca.list.nii[[6]]+mca.list.nii[[7]])/3
mca_ave3::ortho2(mca_ave3) neurobase
The output below is the same as above but is performed on arrays. The image_data function from oro.nifti library extracts the image attribute from the slot .Data.
#extract multiple arrays using lapply
<-lapply(mca.list.nii, img_data)
mca.list.array
<-(mca.list.array[[5]]+mca.list.array[[6]]+mca.list.array[[7]])/3
m3
#compare this with the output from above
::double_ortho(m3, mca_ave3) neurobase
Arrays can be extracted from list using list2array function.
class(mca.list.array)
[1] "list"
#convert list to array
#CHNOSZ function
<-CHNOSZ::list2array(mca.list.array)#91 109 91 25
m.listarray
class(m.listarray)
[1] "array"
Before illustrating more complex operations on ultidimensional array or tensor, let’s consider the basics of multidimensional array. The rank of a tensor represents the dimension of an array. Rank 0 represents 1 dimension and so on.
Here we use apply function to average over every element of the multidimensional array. The first argument of apply is the array, the second argument is the margin or the component for analysis and the last argument is the function. If the idea is to analyse the row then the margin argument is c(1), column then the margin argumen is c(2) and so on.
<-apply(m.listarray,c(1,2,3), mean)
ma::ortho2(ma) neurobase
Thresholding can be performed using mask_img function. This function can also be used to create a mask.
=neurobase::mask_img(ma, ma>0.1)
ma_mask
::double_ortho(ma_mask, ma) neurobase
In this example we us lapply to a function within a list. This is an example of a functional or a function which takes a function as an input and return a vector as an output. In this example, a functional operates on one element of the list at a time. This example of functional is the same as the function VoxelDim describes above.
=unlist(lapply(mca.list.nii,
voxfunction(A) sum(A>.5)*
#obtain voxel dimensions
::pixdim(A)[2]*
oro.nifti::pixdim(A)[3]*
oro.nifti::pixdim(A)[4]/1000
oro.nifti
))
vox
[1] 0.000 0.000 0.000 0.000 69.000 3.624 8.768 58.200 326.760
[10] 1.608 0.000 3.904 3.328 66.776 106.976 70.928 26.912 11.768
[19] 17.592 14.720 151.872 87.528 0.000 24.192 80.248 152.792 69.552
[28] 25.576 0.000 8.644 4.230 3.781 3.643 5.720 5.061 8.644
[37] 4.230 3.781 3.643 5.720 5.061 43.968
One way of handling imaging data for analysis is to flatten the image, then create an empty array of the same size to return the image.
#flatten 3D
= as.vector(img[,,]) #902629
niivector
#Create empty array of same size to fill up
= array(0, dim=dim(img))
niinew
#return to 3D
= array(niivector, dim=dim(img))
niinew
#confirm
::ortho2(niinew) neurobase
Another way of creating vector from the image is to use c function.
#vector can also be created using c
= c(img[,,]) #902629 niivector2
Image files can be large and are often stored as tar files. The tar (tgz file), untar, zip (gz file) and unzip function are from the utils library.
<-untar("./Data-Use/colin_1mm.tgz")
colin_1mm<-readNIfTI("colin_1mm") #1 x 1 x 1
colinImclass(colinIm)
[1] "nifti"
attr(,"package")
[1] "oro.nifti"
::ortho2(colinIm) neurobase
The readNIfTI call can open gz file without the need to call unzip function.
library(RNiftyReg)
<- readNIfTI(system.file("extdata", "epi_t2.nii.gz", package="RNiftyReg"))
epi_t2class(epi_t2)
[1] "nifti"
attr(,"package")
[1] "oro.nifti"
::ortho2(epi_t2) neurobase
There are many different libraries for performing registration.
library(RNiftyReg)
#example from data
<-readNifti("./Data-Use/mca10_pca10_border10.nii.gz")
sourcepixdim(source)
[1] 2 2 2
<-untar("./Data-Use/colin_1mm.tgz")
colin_1mm<-readNifti("colin_1mm")
targetpixdim(target)
[1] 1 1 1 1
target
Image array of mode "double" (54.2 Mb)
- 181 x 217 x 181 x 1 voxels
- 1 x 1 x 1 mm x 1 s per voxel
#register source to target
<- niftyreg(source, target)
result #affine transformation
$forwardTransforms result
[[1]]
NiftyReg affine matrix:
0.773388 0.569432 0.471194 4.534728
-0.595046 0.720880 -0.807965 -19.901979
-0.562192 -0.069332 0.552411 21.512533
0.000000 0.000000 0.000000 1.000000
#image in target space
$image result
Image array of mode "double" (54.2 Mb)
- 181 x 217 x 181 voxels
- 1 x 1 x 1 mm per voxel
::ortho2(result$image) neurobase
Output from RNiftyReg are niftiImage objects. They can be converted to oro.nifti objects using nii2oro function.
<-nii2oro(target)
otarget<-nii2oro(result$image)
oimage
overlay(otarget, y=oimage,z = 90, plot.type = "single" )
Perform affine registration and resampling of image using the transformation file.
#affine
<-readNifti("./Ext-Data/1000M_ica.nii")
ica1000 ica1000
Image array of mode "double" (6.9 Mb)
- 91 x 109 x 91 voxels
- 2 x 2 x 2 mm per voxel
<-buildAffine(source=ica1000, target=target)
colin_affine#apply transformation from above
#assume 1000M_ica.nii and source are in the same space
<-applyTransform(colin_affine,ica1000)
colin_like::ortho2(colin_like) neurobase
Resampling an image to different dimensions. This example is different from above in which rescaling is performed as part of registration to higher resolution image. Here the rescale function from RNiftyReg library is used to change the dimensions from 1x1x1 mm to 2x2x2 mm.
<-RNiftyReg::rescale(ica1000,c(.5,.5,.5))
ica1000.rescale
ica1000
Image array of mode "double" (6.9 Mb)
- 91 x 109 x 91 voxels
- 2 x 2 x 2 mm per voxel
#compare with rescale
ica1000.rescale
Image array of mode "double" (855.6 Kb)
- 45 x 54 x 45 voxels
- 4 x 4 x 4 mm per voxel
There are several different MRI templates. The well known one is the MNI 152 template (Mazziotta J 2001). This was developed from male right-handed medical students. The MNI 152 is also known as International Consortium for Brain Mapping (ICBM) 152.
The Colin high resolution template was obtained by scanning the same individual 27 times (Holmes CJ 1998). This template was registered to the MNI 305 template and has been used as target template by some investigators.
A list of available atlases for human and animals is available at https://loni.usc.edu/research/atlases.
The automated anatomical labeling (AAL) atlas of activation contains 45 volume of interest in each hemisphere (Tzourio-Mazoyer N 2002). The atlas is aligned to MNI 152 coordinates. The updated AAL has additional parcellation of orbitofrontal cortex. AAL3 update includes further parcellation of thalamus.
library(rgl)
library(misc3d)
library(MNITemplate)
#source("https://neuroconductor.org/neurocLite.R")
#neuro_install('aal')
library(aal)
library(neurobase)
library(magick)
Linking to ImageMagick 6.9.12.3
Enabled features: cairo, freetype, fftw, ghostscript, heic, lcms, pango, raw, rsvg, webp
Disabled features: fontconfig, x11
library(oro.nifti)
= aal_image()
img = readMNI(res = "2mm")
template <- 4500
cut <- dim(template)
dtemp
# All of the sections you can label
= aal_get_labels()
labs
# highlight - in this case the Cingulate_Post_L
= labs$index[grep("Cingulate_Post_R", labs$name)]
cingulate
#mask of object for rendering
= remake_img(vec = img %in% cingulate, img = img)
mask
#contour for MNI template
contour3d(template, x=1:dtemp[1], y=1:dtemp[2], z=1:dtemp[3], level = cut, alpha = 0.1, draw = TRUE)
#contour for mask
contour3d(mask, level = c(0.5), alpha = c(0.5), add = TRUE, color=c("red") )
### add text
text3d(x=dtemp[1]/2, y=dtemp[2]/2, z = dtemp[3]*0.98, text="Top")
text3d(x=-0.98, y=dtemp[2]/2, z = dtemp[3]/2, text="Right")
#create movie
#movie file is saved to temporary folder
#movie3d(spin3d(),duration=30)
#add digital map of mca territory
<-readNIfTI("./Data-Use/MCA_average28_MAP_100.nii") MCA
Malformed NIfTI - not reading NIfTI extension, use at own risk!
#mask2 = remake_img(vec = img %in% source, img = img)
contour3d(template, x=1:dtemp[1], y=1:dtemp[2], z=1:dtemp[3], level = cut, alpha = 0.1, draw = TRUE)
#contour for mask
contour3d(MCA, level = c(0.5), alpha = c(0.5), add = TRUE, color=c("Yellow"))
#add frontal
= labs$index[grep("Angular_R", labs$name)]
angular #mask of object for rendering
= remake_img(vec = img %in% angular, img = img)
mask2 contour3d(mask2, level = c(0.5), alpha = c(0.5), add = TRUE, color=c("red"))
#add cingulate
contour3d(mask, level = c(0.5), alpha = c(0.5), add = TRUE, color=c("blue"))
### add text
text3d(x=dtemp[1]/2, y=dtemp[2]/2, z = dtemp[3]*0.98, text="Top")
text3d(x=-0.98, y=dtemp[2]/2, z = dtemp[3]/2, text="Right")
The Eve template is from John Hopkins (“Atlas-Based Whole Brain White Matter Analysis Using Large Deformation Diffeomorphic Metric Mapping: Application to Normal Elderly and Alzheimer’s Disease Participants.” 2009). It is a single subject high resolution white matter atlas that has been morphed into MNI 152 coordinates. The atlas is parcellated into 176 regions based on ICBM-DTI-81 atlas.
#source("https://neuroconductor.org/neurocLite.R")
#neuro_install('EveTemplate', release = "stable", release_repo = "github")
library(EveTemplate)
= readEveMap(type = "II")
eve_labels eve_labels
NIfTI-1 format
Type : nifti
Data Type : 4 (INT16)
Bits per Pixel : 16
Slice Code : 0 (Unknown)
Intent Code : 0 (None)
Qform Code : 2 (Aligned_Anat)
Sform Code : 1 (Scanner_Anat)
Dimension : 181 x 217 x 181
Pixel Dimension : 1 x 1 x 1
Voxel Units : mm
Time Units : Unknown
::ortho2(eve_labels) neurobase
library(RColorBrewer)
library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr 1.1.2 ✔ readr 2.1.4
✔ forcats 1.0.0 ✔ stringr 1.5.0
✔ ggplot2 3.5.1 ✔ tibble 3.2.1
✔ lubridate 1.9.2 ✔ tidyr 1.3.0
✔ purrr 1.0.1
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag() masks stats::lag()
✖ dplyr::slice() masks CHNOSZ::slice(), oro.nifti::slice()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
= eve_labels %>%
unique_labs %>%
c %>%
unique
sort = unique_labs
breaks <- colorRampPalette(rev(brewer.pal(11,'Spectral')))
rf <- rf(length(unique_labs))
cols
::ortho2(eve_labels, col = cols, breaks = c(-1, breaks)) neurobase
Template for corticofugal tracts from primary motor cortex, dorsal premotor cortex, ventral premotor cortex, supplementary motor area (SMA), pre-supplementary motor area (preSMA), and primary somatosensory cortex is available from (Derek B Archer 2018). Below is an illustration of the M1 tract obtained from LRNLAB.
<-readNifti("./Ext-Data/Right-M1-S-MATT.nii")
RightM1
::ortho2(RightM1) neurobase
#to down weight the voxel from 1 mm to 2 mm
<-RNiftyReg::rescale(RightM1,c(.5,.5,.5))
RightM1.rescale
<-nii2oro(RightM1)
RightM1o
#dimensions of RightM1o (182 218 182) and eve_labels (181 217 181) are dissimilar
#overlay(eve_labels, y=RightM1o, z=90,plot.type="single")
The swc format is used for examining morphology of neurons (K. Mehta and Ascoli 2023) or arteries (Decroocq et al. 2023). The file represent neurons or arteries as connected components. Example is provided from the nat library.
library(nat)
Registered S3 method overwritten by 'nat':
method from
as.mesh3d.ashape3d rgl
Some nat functions depend on a CMTK installation. See ?cmtk and README.md for details.
Attaching package: 'nat'
The following objects are masked from 'package:lubridate':
intersect, setdiff, union
The following objects are masked from 'package:dplyr':
intersect, setdiff, union
The following object is masked from 'package:RNiftyReg':
xform
The following object is masked from 'package:oro.nifti':
origin
The following objects are masked from 'package:base':
intersect, setdiff, union
= Cell07PNs[[1]]
n # inspect its internal structure
str(n)
List of 24
$ CellType : chr "DA1"
$ NeuronName : chr "EBH11R"
$ InputFileName: 'AsIs' chr "/GD/projects/PN2/TransformedTraces/DA1/EBH11R.tasc"
$ CreatedAt : POSIXt[1:1], format: "2006-01-18 02:21:14"
$ NodeName : Named chr "jefferis.joh.cam.ac.uk"
..- attr(*, "names")= chr "nodename"
$ InputFileStat:'data.frame': 1 obs. of 10 variables:
..$ size : num 15379
..$ isdir : logi FALSE
..$ mode : 'octmode' int 644
..$ mtime : POSIXt[1:1], format: "2006-01-12 11:52:01"
..$ ctime : POSIXt[1:1], format: "2006-01-12 11:52:01"
..$ atime : POSIXt[1:1], format: "2006-01-18 02:21:14"
..$ uid : int 501
..$ gid : int 501
..$ uname : chr "jefferis"
..$ grname: chr "jefferis"
$ InputFileMD5 : Named chr "fcacee3f874cbe2c6ad96214e6fee337"
..- attr(*, "names")= 'AsIs' chr "/GD/projects/PN2/TransformedTraces/DA1/EBH11R.tasc"
$ NumPoints : int 180
$ StartPoint : num 1
$ BranchPoints : num [1:16] 34 48 51 75 78 95 98 99 108 109 ...
$ EndPoints : num [1:18] 1 42 59 62 80 85 96 100 102 112 ...
$ NumSegs : int 33
$ SegList :List of 33
..$ : int [1:34] 1 2 3 4 5 6 7 8 9 10 ...
..$ : int [1:9] 34 35 36 37 38 39 40 41 42
..$ : num [1:7] 34 43 44 45 46 47 48
..$ : int [1:4] 48 49 50 51
..$ : int [1:9] 51 52 53 54 55 56 57 58 59
..$ : num [1:4] 51 60 61 62
..$ : num [1:14] 48 63 64 65 66 67 68 69 70 71 ...
..$ : int [1:4] 75 76 77 78
..$ : int [1:3] 78 79 80
..$ : num [1:6] 78 81 82 83 84 85
..$ : num [1:11] 75 86 87 88 89 90 91 92 93 94 ...
..$ : int [1:2] 95 96
..$ : num [1:3] 95 97 98
..$ : int [1:2] 98 99
..$ : int [1:2] 99 100
..$ : num [1:3] 99 101 102
..$ : num [1:7] 98 103 104 105 106 107 108
..$ : int [1:2] 108 109
..$ : int [1:4] 109 110 111 112
..$ : num [1:4] 109 113 114 115
..$ : int [1:3] 115 116 117
..$ : num [1:3] 115 118 119
..$ : int [1:3] 119 120 121
..$ : num [1:14] 119 122 123 124 125 126 127 128 129 130 ...
..$ : num [1:2] 108 135
..$ : int [1:9] 135 136 137 138 139 140 141 142 143
..$ : int [1:6] 143 144 145 146 147 148
..$ : num [1:7] 143 149 150 151 152 153 154
..$ : num [1:7] 135 155 156 157 158 159 160
..$ : int [1:6] 160 161 162 163 164 165
..$ : num [1:5] 160 166 167 168 169
..$ : int [1:4] 169 170 171 172
..$ : num [1:9] 169 173 174 175 176 177 178 179 180
$ d :'data.frame': 180 obs. of 7 variables:
..$ PointNo: int [1:180] 1 2 3 4 5 6 7 8 9 10 ...
..$ Label : num [1:180] 2 2 2 2 2 2 2 2 2 2 ...
..$ X : num [1:180] 187 187 188 188 188 ...
..$ Y : num [1:180] 133 131 130 129 129 ...
..$ Z : num [1:180] 88.2 90.6 93.1 95 97.5 ...
..$ W : num [1:180] 1.01 1.27 1.14 1.27 1.27 1.27 1.27 1.27 1.27 1.27 ...
..$ Parent : num [1:180] -1 1 2 3 4 5 6 7 8 9 ...
$ OrientInfo :List of 5
..$ AxonOriented: logi TRUE
..$ AVMPoint : logi NA
..$ AVLPoint : logi NA
..$ Scl : num [1:3] 1 1 1
..$ NewAxes : num [1:3] 1 2 3
$ SegOrders : num [1:33] 1 2 2 3 4 4 3 4 5 5 ...
$ MBPoints : int [1:2] 34 48
$ LHBranchPoint: int 75
$ SegTypes : num [1:33] 1 3 1 3 3 3 1 2 2 2 ...
$ AxonSegNos :List of 3
..$ PreMBAxons : int 1
..$ MBAxons : int 3
..$ PostMBAxons: int 7
$ LHSegNos : num [1:26] 8 9 10 11 12 13 14 15 16 17 ...
$ MBSegNos :List of 2
..$ : int 2
..$ : num [1:3] 4 5 6
$ NumMBBranches: num 2
$ AxonLHEP : num 72
- attr(*, "class")= chr [1:2] "neuron" "list"
# summary of 3D points
summary(xyzmatrix(n))
X Y Z
Min. :186.9 Min. : 90.36 Min. : 88.2
1st Qu.:225.6 1st Qu.: 97.56 1st Qu.:103.4
Median :258.4 Median :102.70 Median :112.9
Mean :249.4 Mean :104.03 Mean :120.9
3rd Qu.:277.7 3rd Qu.:109.04 3rd Qu.:139.0
Max. :289.5 Max. :132.71 Max. :157.3
# identify 3d location of endpoints
xyzmatrix(n)[endpoints(n),]
X Y Z
1 186.8660 132.70932 88.20393
42 224.7067 109.86362 153.58749
59 229.6343 92.30637 157.29700
62 226.8855 90.36325 147.59602
80 249.8864 93.59079 136.77795
85 253.0099 90.94904 137.34921
96 264.0801 98.53390 121.89463
100 266.3223 98.73241 116.46558
102 267.5460 98.59859 112.85608
112 271.0762 102.67288 100.84955
117 274.6128 100.92061 103.28772
121 277.3920 102.19148 102.69473
134 287.1214 101.43365 103.30740
148 281.7958 96.63987 101.08075
154 276.6551 95.09809 99.22113
165 278.3287 113.75627 104.87700
172 282.3069 111.93213 105.65492
180 289.5364 111.96014 109.18281
Plotting a neuron
plot(n)
The read.ngraph.swc function provides a link to the igraph library.
library(nat)
<-read.ngraph.swc("./Ext-Data/swc_files/BG0002.CNG.swc")
aplot(a)