Skip to content

Commit 8ecf78a

Browse files
committed
MRISurfOverlay/mris_convert
1. MRISurfOverlay class add struct OverlayInfoStruct to keep overlay information overlay values are saved as multi-frame MRI 2. mris_convert allowing multiple input files for -c flag new option --mergegifti to combine GIFTI surface with multiple intents
1 parent 6bcc479 commit 8ecf78a

File tree

3 files changed

+466
-127
lines changed

3 files changed

+466
-127
lines changed

include/MRISurfOverlay.h

Lines changed: 66 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,55 @@
55
#include "mrisurf.h"
66

77
// list of Freesurfer surface overlays
8-
// the list for FS_MRISURFOVERLAY_STATS* is not complete
98
// the list should be mapped to INTENTS in GIFTI
109
#define FS_MRISURFOVERLAY_UNKNOWN -1
1110
#define FS_MRISURFOVERLAY_SHAPE 100
1211
#define FS_MRISURFOVERLAY_SHAPE_CURV 101
1312
#define FS_MRISURFOVERLAY_SHAPE_SULC 102
1413
#define FS_MRISURFOVERLAY_SHAPE_AREA 103
1514
#define FS_MRISURFOVERLAY_SHAPE_THICKNESS 104
15+
1616
#define FS_MRISURFOVERLAY_STATS 200
17-
#define FS_MRISURFOVERLAY_STATS_GAMMA 201
18-
#define FS_MRISURFOVERLAY_STATS_BETA 202
17+
#define FS_MRISURFOVERLAY_STATS_CORREL 201
18+
#define FS_MRISURFOVERLAY_STATS_TTEST 202
19+
#define FS_MRISURFOVERLAY_STATS_FTEST 203
20+
#define FS_MRISURFOVERLAY_STATS_ZSCORE 204
21+
#define FS_MRISURFOVERLAY_STATS_CHISQ 205
22+
#define FS_MRISURFOVERLAY_STATS_BETA 206
23+
#define FS_MRISURFOVERLAY_STATS_BINOM 207
24+
#define FS_MRISURFOVERLAY_STATS_GAMMA 208
25+
#define FS_MRISURFOVERLAY_STATS_POISSON 209
26+
#define FS_MRISURFOVERLAY_STATS_NORMAL 210
27+
#define FS_MRISURFOVERLAY_STATS_FTEST_NONC 211
28+
#define FS_MRISURFOVERLAY_STATS_CHISQ_NONC 212
29+
#define FS_MRISURFOVERLAY_STATS_LOGISTIC 213
30+
#define FS_MRISURFOVERLAY_STATS_LAPLACE 214
31+
#define FS_MRISURFOVERLAY_STATS_UNIFORM 215
32+
#define FS_MRISURFOVERLAY_STATS_TTEST_NONC 216
33+
#define FS_MRISURFOVERLAY_STATS_WEIBULL 217
34+
#define FS_MRISURFOVERLAY_STATS_CHI 218
35+
#define FS_MRISURFOVERLAY_STATS_INVGAUSS 219
36+
#define FS_MRISURFOVERLAY_STATS_EXTVAL 220
37+
#define FS_MRISURFOVERLAY_STATS_PVAL 221
38+
#define FS_MRISURFOVERLAY_STATS_LOGPVAL 222
39+
#define FS_MRISURFOVERLAY_STATS_LOG10PVAL 223
40+
#define FS_MRISURFOVERLAY_STATS_ESTIMATE 224
1941
// ...
2042

43+
struct OverlayInfoStruct
44+
{
45+
//char __foverlay[1024]; // full path to overlay file
46+
const char *__foverlay;
47+
int __type; // not assigned yet, FS_MRISURFOVERLAY*
48+
int __format; // MRI_CURV_FILE, MRI_MGH_FILE, GIFTI_FILE
49+
int __stframe; // starting frame, this can be used when we combine multiple overlays in one MRI
50+
int __numframe; // for functions time series*, nframes can be > 1
51+
52+
//int __nVertices;
53+
//int __nFaces; // # of triangles, we need this for MRI_CURV_FILE output
54+
int __nValsPerVertex = 1; // number of values at each vertex, should be 1
55+
};
56+
2157

2258
/* This class implements methods to read/write Freesurfer overlay files.
2359
* The following file formats are supported:
@@ -33,35 +69,47 @@
3369
class MRISurfOverlay
3470
{
3571
public:
36-
MRISurfOverlay();
72+
MRISurfOverlay(MRIS *mris, int noverlay, OverlayInfoStruct *poverlayInfo);
3773
~MRISurfOverlay();
3874

39-
MRI *read(const char *foverlay, int read_volume, MRIS *outmris=NULL); // MRISreadCurvatureFile()
40-
int write(const char *fout, MRIS *inmris=NULL); // MRISwriteCurvature()
75+
int read(int read_volume, MRIS *mris);
76+
int readOneOverlay(int nthOverlay, int read_volume, MRIS *mris); // MRISreadCurvatureFile()
77+
int write(const char *fout, MRIS *inmris=NULL, bool mergegifti=false); // MRISwriteCurvature()
4178

42-
MRI *readCurvatureAsMRI(const char *curvfile, int read_volume);
79+
int getNumOverlay() { return __noverlay; }
80+
const char *getOverlayFilename(int nthOverlay) { return __overlayInfo[nthOverlay].__foverlay; }
81+
int getOverlayType(int nthOverlay) { return __overlayInfo[nthOverlay].__type; }
82+
int getGIFTIIntent(int nthOverlay);
83+
int getFirstFrameNo(int nthOverlay) { return __overlayInfo[nthOverlay].__stframe; }
84+
int getNumFrames(int nthOverlay) { return __overlayInfo[nthOverlay].__stframe + __overlayInfo[nthOverlay].__numframe; }
4385

86+
// return overlay data in multi-frame MRI
87+
MRI *getOverlayMRI() { return __overlaymri; }
88+
4489
static int getFileFormat(const char *foverlay);
4590

4691
private:
4792
int __copyOverlay2MRIS(MRIS *outmris);
48-
int __readOldCurvature(MRIS *outmris, const char *fname);
93+
int __readCurvatureAsMRI(const char *curvfile, int read_volume);
94+
int __readOldCurvature(const char *fname);
4995

5096
int __writeCurvFromMRI(MRI *outmri, const char *fout);
5197
int __writeCurvFromMRIS(MRIS *outmris, const char *fout);
5298

53-
54-
char __foverlay[1024]; // full path to overlay file
55-
int __type; // not assigned yet, FS_MRISURFOVERLAY*
56-
int __format; // MRI_CURV_FILE, MRI_MGH_FILE, GIFTI_FILE
57-
int __stframe; // starting frame, this can be used when we combine multiple overlays in one MRI
58-
int __nframes; // for functions time series*, nframes can be > 1
59-
MRI *__overlaymri; // overlay data in MRI representation
99+
bool __isStatsData(int nthOverlay);
100+
bool __isShapeMeasurement(int nthOverlay);
60101

61102
int __nVertices;
62-
int __nFaces; // # of triangles, we need this for MRI_CURV_FILE output
63-
int __nValsPerVertex; // number of values at each vertex, should be 1
64-
};
103+
int __nFaces; // # of triangles, we need this for MRI_CURV_FILE output
104+
105+
int __noverlay;
106+
OverlayInfoStruct *__overlayInfo;
65107

108+
int __currOverlay;
109+
int __currFrame;
110+
111+
MRI *__overlaymri; // overlay data in MRI representation
112+
};
66113

67114
#endif
115+

mris_convert/mris_convert.cpp

Lines changed: 80 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -79,15 +79,17 @@ static const COLOR_TABLE miniColorTable =
7979

8080
int main(int argc, char *argv[]) ;
8181

82-
static void __convertOverlayFile(MRIS *mris, const char *curv, char *out_fname);
82+
static void __convertCurvatureFile(MRIS *mris, int noverlay, const char **foverlays, char *out_fname);
8383
static void __writeLabelFile(MRIS *mris, const char *flabel, const char *label, const char *labelstats, char *out_fname);
84-
static void __writeAnnotFile(MRIS *mris, const char *fannot, int giftiDaNum, const char *parcstats, const char *fcurv, char *out_fname);
84+
static void __writeAnnotFile(MRIS *mris, const char *fannot, int giftiDaNum, const char *parcstats, char *out_fname);
8585
static void __writeFuncFile(const char *ffunc, char *out_fname);
8686
static void __writeNormals(MRIS *mris, char *out_fname);
8787
static void __writeMRISPatch(MRIS *mris, char *out_fname);
8888

8989
static int get_option(int argc, char *argv[]) ;
9090
static void check_options(void);
91+
static int isflag(char *flag);
92+
static int nth_is_arg(int nargc, char **argv, int nth);
9193
static void usage_exit(void) ;
9294
static void print_usage(void) ;
9395
static void print_help(void) ;
@@ -112,6 +114,8 @@ static int w_file_dst_flag = 0 ;
112114
static int w_file_src_flag = 0 ;
113115
static int curv_file_flag = 0 ;
114116
static char *curv_fname = NULL;
117+
static const char **arr_fcurv = NULL;
118+
static int nfcurv = 0;
115119
static int func_file_flag = 0 ;
116120
static char *func_fname = NULL;
117121
static int annot_file_flag = 0 ;
@@ -132,6 +136,7 @@ static int PrintXYZOnly = 0;
132136
static MATRIX *XFM=NULL;
133137
static int write_vertex_neighbors = 0;
134138
static int combinesurfs_flag = 0;
139+
static int mergegifti_flag = 0;
135140
static int userealras_flag = 0;
136141
static int usesurfras_flag = 0;
137142
static MRI *VolGeomMRI=NULL;
@@ -407,9 +412,9 @@ main(int argc, char *argv[])
407412
}
408413

409414
if (curv_file_flag)
410-
__convertOverlayFile(mris, curv_fname, out_fname);
415+
__convertCurvatureFile(mris, nfcurv, arr_fcurv, out_fname);
411416
else if (annot_file_flag)
412-
__writeAnnotFile(mris, annot_fname, gifti_da_num, parcstats_fname, curv_fname, out_fname);
417+
__writeAnnotFile(mris, annot_fname, gifti_da_num, parcstats_fname, out_fname);
413418
else if (label_file_flag)
414419
__writeLabelFile(mris, label_fname, label_name, labelstats_fname, out_fname);
415420
else if (func_file_flag)
@@ -488,11 +493,21 @@ main(int argc, char *argv[])
488493
}
489494

490495

491-
static void __convertOverlayFile(MRIS *mris, const char *fcurv, char *out_fname)
496+
static void __convertCurvatureFile(MRIS *mris, int noverlay, const char **foverlays, char *out_fname)
492497
{
493-
MRISurfOverlay *fsOverlay = new MRISurfOverlay();
494-
fsOverlay->read(fcurv, TRUE, mris);
495-
fsOverlay->write(out_fname, mris);
498+
OverlayInfoStruct poverlayStruct[noverlay];
499+
for (int n = 0; n < noverlay; n++)
500+
{
501+
poverlayStruct[n].__foverlay = foverlays[n];
502+
poverlayStruct[n].__type = FS_MRISURFOVERLAY_SHAPE;
503+
poverlayStruct[n].__format = MRISurfOverlay::getFileFormat(foverlays[n]);
504+
poverlayStruct[n].__stframe = n; // assume one frame for each curvature
505+
poverlayStruct[n].__numframe = 1;
506+
}
507+
508+
MRISurfOverlay *fsOverlay = new MRISurfOverlay(mris, noverlay, &poverlayStruct[0]);
509+
fsOverlay->read(TRUE, mris);
510+
fsOverlay->write(out_fname, mris, (mergegifti_flag) ? true : false);
496511
}
497512

498513

@@ -596,7 +611,7 @@ static void __writeLabelFile(MRIS *mris, const char *flabel, const char *labelna
596611
}
597612

598613

599-
static void __writeAnnotFile(MRIS *mris, const char *fannot, int giftiDaNum, const char *parcstats, const char *fcurv, char *out_fname)
614+
static void __writeAnnotFile(MRIS *mris, const char *fannot, int giftiDaNum, const char *parcstats, char *out_fname)
600615
{
601616
// first read the annotation/gifti label data...
602617
int type = MRISfileNameType(fannot);
@@ -662,8 +677,7 @@ static void __writeAnnotFile(MRIS *mris, const char *fannot, int giftiDaNum, con
662677
}
663678
else if (type == MRIS_GIFTI_FILE)
664679
{
665-
// ??? is curv_fname set for this code path ???
666-
MRISwriteGIFTI(mris, NIFTI_INTENT_SHAPE, out_fname, fcurv);
680+
MRISwriteGIFTI(mris, NIFTI_INTENT_SHAPE, out_fname, NULL);
667681
}
668682
else
669683
{
@@ -842,6 +856,10 @@ get_option(int argc, char *argv[])
842856
nargs = 1 ;
843857
#endif
844858
}
859+
else if (!stricmp(option, "-mergegifti"))
860+
{
861+
mergegifti_flag = 1;
862+
}
845863
else if (!stricmp(option, "-delete-cmds"))
846864
{
847865
DeleteCommands = 1;
@@ -915,10 +933,30 @@ get_option(int argc, char *argv[])
915933
nargs = 1 ;
916934
break ;
917935
case 'C':
936+
{
918937
curv_file_flag = 1 ;
919938
curv_fname = argv[2] ;
920939
nargs = 1 ;
940+
941+
int argc0 = 2;
942+
int nth = 3;
943+
// get additional input curvature files
944+
// minus 2 positional arguments
945+
while (nth_is_arg(argc-nth-2, argv, nth))
946+
{
947+
nargs++; nth++;
948+
}
949+
950+
arr_fcurv = new const char*[nargs];
951+
for (int n = 0; n < nargs; n++)
952+
{
953+
arr_fcurv[n] = argv[argc0];
954+
argc0++;
955+
}
956+
957+
nfcurv = nargs;
921958
break ;
959+
}
922960
case 'N':
923961
output_normals = 1;
924962
break ;
@@ -964,6 +1002,12 @@ get_option(int argc, char *argv[])
9641002

9651003
static void check_options(void)
9661004
{
1005+
if (combinesurfs_flag && curv_file_flag)
1006+
{
1007+
printf("ERROR: --combinesurf and -c are mutually exclusive. \n");
1008+
exit(1);
1009+
}
1010+
9671011
// --to-scanner/--userealras and --to-tkr/--usesurfras are mutually exclusive
9681012
if ( (ToScanner || userealras_flag) &&
9691013
(ToTkr || usesurfras_flag) )
@@ -991,7 +1035,31 @@ static void check_options(void)
9911035
}
9921036
}
9931037

994-
static void
1038+
/*---------------------------------------------------------------*/
1039+
static int isflag(char *flag) {
1040+
int len;
1041+
len = strlen(flag);
1042+
if (len < 2) return(0);
1043+
1044+
if (flag[0] == '-' && flag[1] == '-') return(1);
1045+
return(0);
1046+
}
1047+
1048+
/*---------------------------------------------------------------*/
1049+
static int nth_is_arg(int nargc, char **argv, int nth) {
1050+
/* Checks that nth arg exists and is not a flag */
1051+
/* nth is 0-based */
1052+
1053+
/* check that there are enough args for nth to exist */
1054+
if (nargc <= 0) return(0);
1055+
1056+
/* check whether the nth arg is a flag */
1057+
if (isflag(argv[nth])) return(0);
1058+
1059+
return(1);
1060+
}
1061+
1062+
static void
9951063
usage_exit(void)
9961064
{
9971065
print_help() ;

0 commit comments

Comments
 (0)