Skip to content

Commit 5039226

Browse files
Create CIFTItoFC_concat_ses.R
1 parent 0c77917 commit 5039226

File tree

1 file changed

+168
-0
lines changed

1 file changed

+168
-0
lines changed

R/CIFTItoFC_concat_ses.R

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
2+
########################################################################################################
3+
########################################################################################################
4+
5+
#' @title CIFTItoFC_concat_ses
6+
#'
7+
#' @description Extracting FC matrices from CIFTI files, concatenating runs within each session
8+
#'
9+
#' @details This function extracts FC matrices from CIFTI volumes postprocessed with XCP_d
10+
#'
11+
#' @param wb_path The filepath to the workbench folder that you have previously downloaded and unzipped. Set to `/home/junhong.yu/workbench/bin_rh_linux64` by default
12+
#' @param path The filepath to directory containing the subject folders. Set to `./.` by default.
13+
#' @param atlas The version (number of parcels) of the Schaefer atlas; it has to be in multiples of 100, from 100 to 1000. set to `200` by default. The specified atlas template will be automatically downloaded from here if it does not exist in the current directory.
14+
#' @param dtseries The filename extension of the fMRI volumes. Set to `_space-fsLR_den-91k_desc-denoised_bold.dtseries.nii` by default
15+
#' @param timeseries If set to `TRUE`, FC matrices will not be computed, instead the parcellated timeseries will be return in a list format, where each subject's parcellated timeseries data is contained within a list element. Set to `FALSE` by default.
16+
#' @param filename Filename of the concatenated FC vector file. Set to `FC.rds` by default
17+
#' @returns outputs N (number of subjects) x E (number of unique) matrices as a .rds file
18+
#'
19+
#' @examples
20+
#' \dontrun{
21+
#' CIFTItoFC_concatses(dtseries="_task-rest_run-00._space-fsLR_den-91k_desc-denoised_bold.dtseries.nii", atlas=200, filename="PREVENTAD_stage1_rsFC.rds")
22+
#' }
23+
#' @importFrom stringr str_detect
24+
#' @importFrom ciftiTools ciftiTools.setOption read_cifti read_xifti newdata_xifti move_from_mwall
25+
#' @importFrom psych fisherz
26+
#' @export
27+
28+
########################################################################################################
29+
########################################################################################################
30+
CIFTItoFC_concat_ses=function(path="./",wb_path="/home/junhong.yu/workbench/bin_rh_linux64", dtseries="_space-fsLR_den-91k_desc-denoised_bold.dtseries.nii", timeseries=F, atlas=200,filename="FC.rds")
31+
{
32+
filelist=list.files(path=path,pattern=dtseries,recursive = T)
33+
sublist=unique(gsub(pattern ="/ses-.*/func",replacement = "",dirname(filelist)))
34+
35+
##load and configure ciftitools
36+
ciftiTools::ciftiTools.setOption('wb_path', wb_path)
37+
38+
##atlas checks
39+
if(is.na(match(atlas,(1:10)*100))) {stop("\nAtlas should be a multiple of 100 from 100 to 1000")}
40+
#download atlas template if it is missing
41+
if(!file.exists(paste(system.file(package='FCtools'),"/data/Schaefer2018_",atlas,"Parcels_7Networks_order.dlabel.nii",sep="")))
42+
{
43+
cat(paste("\nThe",paste("Schaefer2018_",atlas,"Parcels_7Networks_order.dlabel.nii",sep=""),"template file does not exist and will be downloaded\n"),sep=" ")
44+
download.file(url=paste0("https://raw.githubusercontent.com/ThomasYeoLab/CBIG/master/stable_projects/brain_parcellation/Schaefer2018_LocalGlobal/Parcellations/HCP/fslr32k/cifti/Schaefer2018_",atlas,"Parcels_7Networks_order.dlabel.nii"),
45+
destfile =paste(system.file(package='FCtools'),"/data/Schaefer2018_",atlas,"Parcels_7Networks_order.dlabel.nii",sep=""),mode = "wb")
46+
47+
}
48+
parc=c(as.matrix(ciftiTools::read_cifti(paste(system.file(package='FCtools'),"/data/Schaefer2018_",atlas,"Parcels_7Networks_order.dlabel.nii",sep=""),brainstructures=c("left","right"))))
49+
50+
## defining subcortical parcel indices for reordering ROIs subsequently
51+
reorder.subcortical.idx=c(9,18,8,17,6,3,13,1,11,10,19,7,16,5,15,4,14,2,12)+atlas
52+
53+
if(timeseries==F)
54+
{
55+
all_FC=matrix(NA,nrow=length(sublist),ncol=(((atlas+19)^2)-(atlas+19))/2)
56+
} else if(timeseries==T)
57+
{
58+
all_TS=list()
59+
}
60+
61+
count=1
62+
63+
for (sub in 1:length(sublist))
64+
{
65+
66+
filelist.sub=filelist[stringr::str_detect(pattern=sublist[sub],string=filelist)]
67+
sessions=list.files(path=paste0(sublist[sub],"/"),pattern="ses")
68+
69+
for (session in 1: length(sessions))
70+
{
71+
72+
filelist.sub.session=filelist.sub[stringr::str_detect(pattern=sessions[session],string=filelist.sub)]
73+
if(length(filelist.sub.session)>0)
74+
{
75+
start=Sys.time()
76+
cat(paste0("processing ",sublist[sub],"_",sessions[session]," (",sub," / ",length(sublist),")..."))
77+
for (scan in 1:length(filelist.sub.session))
78+
{
79+
if(scan==1)
80+
{
81+
xii0=ciftiTools::read_xifti(paste0(path,"/",filelist.sub.session[scan]), brainstructures="all")
82+
xii=scale(as.matrix(xii0))
83+
if(sum(colSums(xii)==0)!=0)
84+
{
85+
cat(paste0("WARNING: ",filelist.sub.session[scan]," contains column(s) with entirely 0 values\n"))
86+
}
87+
}
88+
else
89+
{
90+
xii=cbind(scale(as.matrix(ciftiTools::read_xifti(paste0(path,"/",filelist.sub.session[scan]), brainstructures="all"))),xii)
91+
if(sum(colSums(xii)==0)!=0)
92+
{
93+
cat(paste0("WARNING: ",filelist.sub.session[scan]," contains column(s) with entirely 0 values\n"))
94+
}
95+
}
96+
97+
if(length(filelist.sub.session)==1)
98+
{
99+
xii.final=xii0
100+
timeseries.dat=as.matrix(ciftiTools::move_from_mwall(xii0, NA))
101+
} else
102+
{
103+
xii.final=ciftiTools::newdata_xifti(xii0, xii)
104+
timeseries.dat=as.matrix(ciftiTools::move_from_mwall(xii.final, NA))
105+
}
106+
}
107+
108+
##generate parcellated timeseries
109+
sub_keys=as.numeric(xii.final$meta$subcort$labels) - 2 +atlas
110+
brain_vec=c(parc, sub_keys)
111+
112+
xii_pmean=matrix(ncol=atlas+19,nrow=ncol(xii))
113+
114+
for (p in 1:(atlas+19))
115+
{
116+
xii_pmean[,p]=colMeans(timeseries.dat[which(brain_vec==p),],na.rm = T)
117+
}
118+
#reorder parcel indices for visualization purpose
119+
xii_pmean=xii_pmean[,c(1:atlas,reorder.subcortical.idx)]
120+
121+
if(count==1)
122+
{
123+
sub.sess=paste0(sublist[sub],"_",sessions[session])
124+
if(timeseries==F)
125+
{
126+
FCmat=cor(xii_pmean)
127+
all_FC=FCmat[upper.tri(FCmat,diag=F)]
128+
remove(FCmat)
129+
} else if(timeseries==T)
130+
{
131+
all_TS[[sub]]=xii_pmean
132+
}
133+
} else
134+
{
135+
sub.sess=c(sub.sess,paste0(sublist[sub],"_",sessions[session]))
136+
if(timeseries==F)
137+
{
138+
FCmat=cor(xii_pmean)
139+
all_FC=rbind(all_FC,FCmat[upper.tri(FCmat,diag=F)])
140+
remove(FCmat)
141+
} else if(timeseries==T)
142+
{
143+
all_TS[[sub]]=xii_pmean
144+
}
145+
}
146+
##clean temp dir
147+
files_to_remove=list.files(tempdir(), full.names = TRUE)
148+
removedfiles=file.remove(files_to_remove)
149+
count=count+1
150+
end=Sys.time()
151+
cat(paste0(" Completed in ", round(difftime(end,start, units="secs"),1),"s\n"))
152+
remove(xii, xii0, xii.final, xii_pmean, timeseries.dat,filelist.sub.session, start,end,removedfiles)
153+
}
154+
}
155+
remove(filelist.sub)
156+
}
157+
cat(paste0("Saving ", filename," ..."))
158+
159+
if(timeseries==F)
160+
{
161+
saveRDS(list(sublist,psych::fisherz(all_FC)),file=filename)
162+
} else if(timeseries==T)
163+
{
164+
saveRDS(list(sub.sess,all_TS),file=filename)
165+
}
166+
167+
}
168+

0 commit comments

Comments
 (0)