Skip to content

Commit 5120c4f

Browse files
committed
MRISurfOverlay/gifti.cpp/mris_convert
1. MRISurfOverlay class - add '__datatype' to struct OverlayInfoStruct for the value of gifti NIFTI_INTENT_SHAPE metadata ShapeDataType - the class can't handle multiple overlays in same input file 2. gifti.cpp change functions to take NIFTI_INTENT_SHAPE metadata ShapeDataType value as input parameter 3. mris_convert function rename and add error handling
1 parent 2dfd558 commit 5120c4f

File tree

5 files changed

+121
-52
lines changed

5 files changed

+121
-52
lines changed

include/MRISurfOverlay.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,12 @@ struct OverlayInfoStruct
4444
{
4545
//char __foverlay[1024]; // full path to overlay file
4646
const char *__foverlay;
47-
int __type; // not assigned yet, FS_MRISURFOVERLAY*
48-
int __format; // MRI_CURV_FILE, MRI_MGH_FILE, GIFTI_FILE
47+
int __type; // FS_MRISURFOVERLAY*
48+
const char *__datatype;// CurvatureRadial, SulcalDepth, Thickness, Area, (Volume, Jacobian)
49+
int __format; // MRI_CURV_FILE, MRI_MGH_FILE, GIFTI_FILE, ASCII_FILE, VTK_FILE
4950
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+
int __numframe; // for functions time series*, nframes can be > 1
5152

52-
//int __nVertices;
53-
//int __nFaces; // # of triangles, we need this for MRI_CURV_FILE output
5453
int __nValsPerVertex = 1; // number of values at each vertex, should be 1
5554
};
5655

@@ -73,7 +72,6 @@ class MRISurfOverlay
7372
~MRISurfOverlay();
7473

7574
int read(int read_volume, MRIS *mris);
76-
int readOneOverlay(int nthOverlay, int read_volume, MRIS *mris); // MRISreadCurvatureFile()
7775
int write(const char *fout, MRIS *inmris=NULL, bool mergegifti=false); // MRISwriteCurvature()
7876

7977
int getNumOverlay() { return __noverlay; }
@@ -82,13 +80,15 @@ class MRISurfOverlay
8280
int getGIFTIIntent(int nthOverlay);
8381
int getFirstFrameNo(int nthOverlay) { return __overlayInfo[nthOverlay].__stframe; }
8482
int getNumFrames(int nthOverlay) { return __overlayInfo[nthOverlay].__stframe + __overlayInfo[nthOverlay].__numframe; }
83+
const char *getDataType(int nthOverlay) { return __overlayInfo[nthOverlay].__datatype; }
8584

8685
// return overlay data in multi-frame MRI
8786
MRI *getOverlayMRI() { return __overlaymri; }
8887

8988
static int getFileFormat(const char *foverlay);
9089

9190
private:
91+
int __readOneOverlay(int nthOverlay, int read_volume, MRIS *mris); // MRISreadCurvatureFile()
9292
int __copyOverlay2MRIS(MRIS *outmris);
9393
int __readCurvatureAsMRI(const char *curvfile, int read_volume);
9494
int __readOldCurvature(const char *fname);

include/gifti.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ int MRISwriteGIFTISurface(MRIS *mris, gifti_image *image, const char *out_fname)
4343
// function to output multiple overlays
4444
int MRISwriteGIFTICombined(MRIS *mris, MRISurfOverlay *poverlays, const char *out_fname);
4545
// overloaded functions to handle combined GIFTI with multiple intents
46-
int MRISwriteGIFTIIntent(MRIS *mris, const MRI *mri, int stframe, int endframe, gifti_image *image, int intent_code, const char *out_fname, const char *curv_fname);
47-
int MRISwriteGIFTIShape(MRIS *mris, const MRI *mri, int stframe, int endframe, gifti_image *image, int intent_code, const char *curv_fname);
48-
int MRISwriteGIFTIStats(MRIS *mris, const MRI *mri, int stframe, int endframe, gifti_image *image, int intent_code);
46+
int MRISwriteGIFTIIntent(MRIS *mris, const MRI *mri, int stframe, int endframe, gifti_image *image, int intent_code, const char *out_fname, const char *curv_fname, const char *datatype);
47+
int MRISwriteGIFTIShape(MRIS *mris, const MRI *mri, int stframe, int endframe, gifti_image *image, int intent_code, const char *curv_fname, const char *datatype);
48+
int MRISwriteGIFTIStats(MRIS *mris, const MRI *mri, int stframe, int endframe, gifti_image *image, int intent_code, const char *curv_fname, const char *datatype);
4949

5050

5151

mris_convert/mris_convert.cpp

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,11 @@ static const COLOR_TABLE miniColorTable =
8080
int main(int argc, char *argv[]) ;
8181

8282
static void __convertCurvatureFile(MRIS *mris, int noverlay, const char **foverlays, char *out_fname);
83-
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, char *out_fname);
85-
static void __writeFuncFile(const char *ffunc, char *out_fname);
86-
static void __writeNormals(MRIS *mris, char *out_fname);
87-
static void __writeMRISPatch(MRIS *mris, char *out_fname);
83+
static void __convertLabelFile(MRIS *mris, const char *flabel, const char *label, const char *labelstats, char *out_fname);
84+
static void __convertAnnotFile(MRIS *mris, const char *fannot, int giftiDaNum, const char *parcstats, char *out_fname);
85+
static void __convertFuncFile(const char *ffunc, char *out_fname);
86+
static void __convertNormals(MRIS *mris, char *out_fname);
87+
static void __convertMRISPatch(MRIS *mris, char *out_fname);
8888

8989
static int get_option(int argc, char *argv[]) ;
9090
static void check_options(void);
@@ -414,18 +414,18 @@ main(int argc, char *argv[])
414414
if (curv_file_flag)
415415
__convertCurvatureFile(mris, nfcurv, arr_fcurv, out_fname);
416416
else if (annot_file_flag)
417-
__writeAnnotFile(mris, annot_fname, gifti_da_num, parcstats_fname, out_fname);
417+
__convertAnnotFile(mris, annot_fname, gifti_da_num, parcstats_fname, out_fname);
418418
else if (label_file_flag)
419-
__writeLabelFile(mris, label_fname, label_name, labelstats_fname, out_fname);
419+
__convertLabelFile(mris, label_fname, label_name, labelstats_fname, out_fname);
420420
else if (func_file_flag)
421421
{
422-
__writeFuncFile(func_fname, out_fname);
422+
__convertFuncFile(func_fname, out_fname);
423423
exit(0);
424424
}
425425
else if (mris->patch)
426-
__writeMRISPatch(mris, out_fname);
426+
__convertMRISPatch(mris, out_fname);
427427
else if (output_normals)
428-
__writeNormals(mris, out_fname);
428+
__convertNormals(mris, out_fname);
429429
else if (write_vertex_neighbors)
430430
MRISwriteVertexNeighborsAscii(mris, out_fname) ;
431431
else if(PrintXYZOnly)
@@ -464,6 +464,8 @@ main(int argc, char *argv[])
464464
printf("Removing Vol Geom\n");
465465
mris->vg.valid = 0;
466466
}
467+
468+
// ??? should we call MRIcopyMRIS() instead ???
467469
if(MRISfileNameType(out_fname) == MRIS_VOLUME_FILE) {
468470
printf("Saving surface xyz %s as a volume format\n",out_fname);
469471
MRI *vol = MRIallocSequence(mris->nvertices, 1, 1, MRI_FLOAT, 3);
@@ -506,12 +508,15 @@ static void __convertCurvatureFile(MRIS *mris, int noverlay, const char **foverl
506508
}
507509

508510
MRISurfOverlay *fsOverlay = new MRISurfOverlay(mris, noverlay, &poverlayStruct[0]);
509-
fsOverlay->read(TRUE, mris);
511+
int error = fsOverlay->read(TRUE, mris);
512+
if (error != NO_ERROR)
513+
return;
514+
510515
fsOverlay->write(out_fname, mris, (mergegifti_flag) ? true : false);
511516
}
512517

513518

514-
static void __writeLabelFile(MRIS *mris, const char *flabel, const char *labelname, const char *labelstats, char *out_fname)
519+
static void __convertLabelFile(MRIS *mris, const char *flabel, const char *labelname, const char *labelstats, char *out_fname)
515520
{
516521
#if 0 // for some reasons, defining the variables here doesn't work
517522
const COLOR_TABLE_ENTRY unknown = {"unknown", 0,0,0,0, 0,0,0,0};
@@ -611,7 +616,7 @@ static void __writeLabelFile(MRIS *mris, const char *flabel, const char *labelna
611616
}
612617

613618

614-
static void __writeAnnotFile(MRIS *mris, const char *fannot, int giftiDaNum, const char *parcstats, char *out_fname)
619+
static void __convertAnnotFile(MRIS *mris, const char *fannot, int giftiDaNum, const char *parcstats, char *out_fname)
615620
{
616621
// first read the annotation/gifti label data...
617622
int type = MRISfileNameType(fannot);
@@ -711,7 +716,7 @@ static void __writeAnnotFile(MRIS *mris, const char *fannot, int giftiDaNum, con
711716
}
712717

713718

714-
static void __writeFuncFile(const char *ffunc, char *out_fname)
719+
static void __convertFuncFile(const char *ffunc, char *out_fname)
715720
{
716721
MRI* mri = MRIread( ffunc );
717722
if (NULL == mri)
@@ -723,7 +728,7 @@ static void __writeFuncFile(const char *ffunc, char *out_fname)
723728
}
724729

725730

726-
static void __writeNormals(MRIS *mris, char *out_fname)
731+
static void __convertNormals(MRIS *mris, char *out_fname)
727732
{
728733
if (MRISfileNameType(out_fname) == MRIS_ASCII_TRIANGLE_FILE)
729734
MRISwriteNormalsAscii(mris, out_fname) ;
@@ -732,7 +737,7 @@ static void __writeNormals(MRIS *mris, char *out_fname)
732737
}
733738

734739

735-
static void __writeMRISPatch(MRIS *mris, char *out_fname)
740+
static void __convertMRISPatch(MRIS *mris, char *out_fname)
736741
{
737742
int type = MRISfileNameType(out_fname) ;
738743
if (type == MRIS_GIFTI_FILE)

utils/MRISurfOverlay.cpp

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,26 @@ MRISurfOverlay::MRISurfOverlay(MRIS *mris, int noverlay, OverlayInfoStruct *pove
1515
for (int n = 0; n < __noverlay; n++)
1616
{
1717
__overlayInfo[n] = poverlayInfo[n];
18+
19+
__overlayInfo[n].__stframe = n; // assume one frame for each overlay
20+
21+
const char *curv_fname = __overlayInfo[n].__foverlay;
22+
__overlayInfo[n].__datatype = NULL;
23+
if (strstr(curv_fname, ".thickness"))
24+
__overlayInfo[n].__datatype = "Thickness";
25+
else if (strstr(curv_fname, ".curv"))
26+
__overlayInfo[n].__datatype = "CurvatureRadial";
27+
else if (strstr(curv_fname, ".sulc"))
28+
__overlayInfo[n].__datatype = "SulcalDepth";
29+
else if (strstr(curv_fname, ".area"))
30+
__overlayInfo[n].__datatype = "Area";
31+
else if (strstr(curv_fname, ".volume"))
32+
__overlayInfo[n].__datatype = "Volume";
33+
else if (strstr(curv_fname, ".jacobian"))
34+
__overlayInfo[n].__datatype = "Jacobian";
35+
else
36+
__overlayInfo[n].__datatype = NULL;
37+
1838
#if 0
1939
memcpy(__overlayInfo[n], poverlayInfo[n], sizeof(__overlayInfo[n]));
2040
__overlayInfo[n].__type = poverlayInfo[n]__type;
@@ -26,6 +46,7 @@ MRISurfOverlay::MRISurfOverlay(MRIS *mris, int noverlay, OverlayInfoStruct *pove
2646
#endif
2747
}
2848

49+
// Can't handle multi overlay in one input file
2950
std::vector<int> shape{__nVertices, 1, 1, __noverlay};
3051
__overlaymri = new MRI(shape, MRI_FLOAT);
3152
__currFrame = 0;
@@ -43,7 +64,7 @@ MRISurfOverlay::~MRISurfOverlay()
4364
/* static member method to return file type for the given file
4465
*
4566
* The following file types are considered valid overlay files:
46-
* MRI_CURV_FILE, MRI_MGH_FILE, GIFTI_FILE, MRIS_ASCII_FILE, MRIS_VTK_FILE
67+
* MRI_CURV_FILE, MRI_MGH_FILE, GIFTI_FILE, ASCII_FILE, VTK_FILE
4768
* For file types other than those, return MRI_VOLUME_TYPE_UNKNOWN to callers.
4869
*
4970
* Notes: This class only handles MRI_CURV_FILE, MRI_MGH_FILE, GIFTI_FILE now.
@@ -75,7 +96,7 @@ int MRISurfOverlay::read(int read_volume, MRIS *mris)
7596
__currFrame = n;
7697
__overlayInfo[n].__stframe = __currFrame;
7798

78-
int error = readOneOverlay(n, read_volume, mris);
99+
int error = __readOneOverlay(n, read_volume, mris);
79100
if (error != NO_ERROR)
80101
return error;
81102
}
@@ -90,12 +111,12 @@ int MRISurfOverlay::read(int read_volume, MRIS *mris)
90111
* (MRI_CURV_FILE, MRI_MGH_FILE, GIFTI_FILE).
91112
* MRI_CURV_FILE is the new CURV format with MAGICNO. = 16777215.
92113
*
93-
* Overlay files can also be in MRIS_ASCII_FILE, MRIS_VTK_FILE, and old CURV formats (read).
114+
* Overlay files can also be in ASCII_FILE, VTK_FILE, and old CURV formats (read).
94115
*
95116
* The overlay data has 1D morphometry data (vertex-wise measures) or other per-vertex information.
96117
* The data is read into MRI representation in this class for MRI_CURV_FILE, MRI_MGH_FILE, GIFTI_FILE.
97118
*/
98-
int MRISurfOverlay::readOneOverlay(int nthOverlay, int read_volume, MRIS *mris)
119+
int MRISurfOverlay::__readOneOverlay(int nthOverlay, int read_volume, MRIS *mris)
99120
{
100121
if (mris == NULL)
101122
{
@@ -125,12 +146,25 @@ int MRISurfOverlay::readOneOverlay(int nthOverlay, int read_volume, MRIS *mris)
125146
else if (overlayFormat == MRI_MGH_FILE)
126147
{
127148
MRI *tempMRI = mghRead(__overlayInfo[__currFrame].__foverlay, read_volume, -1);
128-
if (tempMRI->width != __nVertices || tempMRI->height != 1 || tempMRI->depth != 1 || tempMRI->nframes != 1)
149+
if (tempMRI->width != __nVertices || tempMRI->height != 1 || tempMRI->depth != 1)
129150
{
130-
printf("ERROR MRISurfOverlay::readOneOverlay() - wrong MRI_MGH_FILE dimension (%s)\n", __overlayInfo[nthOverlay].__foverlay);
151+
printf("[ERROR] MRISurfOverlay::readOneOverlay() - %s dimensions (%d x %d x %d) doesn't match number of surface vertices (%d)\n",
152+
__overlayInfo[nthOverlay].__foverlay, tempMRI->width, tempMRI->height, tempMRI->depth, __nVertices);
131153
return ERROR_BADFILE;
132154
}
133155

156+
if (tempMRI->nframes > 1)
157+
{
158+
printf("[ERROR] MRISurfOverlay::readOneOverlay() - %s has multiple frames = %d.\n", __overlayInfo[nthOverlay].__foverlay, tempMRI->nframes);
159+
return ERROR_BADFILE;
160+
// Can't handle it now, just return error
161+
//__overlayInfo[__currOverlay].__numframe = tempMRI->nframes;
162+
//printf("[INFO] MRISurfOverlay::readOneOverlay() - Each frame will be treated as one overlay.\n");
163+
//__noverlay = tempMRI->nframes;
164+
}
165+
166+
__overlayInfo[__currOverlay].__numframe = 1;
167+
134168
// copy the data to __currFrame
135169
for (int f = 0; f < __overlaymri->nframes; f++) {
136170
for (int s = 0; s < __overlaymri->depth; s++) {
@@ -144,18 +178,18 @@ int MRISurfOverlay::readOneOverlay(int nthOverlay, int read_volume, MRIS *mris)
144178
}
145179
MRIfree(&tempMRI);
146180

147-
__overlayInfo[__currOverlay].__numframe = __overlaymri->nframes;
148181
__copyOverlay2MRIS(mris);
149182
}
150183
else if (overlayFormat == GIFTI_FILE)
151184
{
152-
// ??? only one SHAPE and <STATS> is handled ???
185+
// after read,
186+
// first SHAPE is saved in mris->curv;
187+
// first <STATS> is saved in mris->val and mris->stat;
188+
// all SHAPE and <STATS> data arrays are saved as multi-frame MRI
189+
int currFrame_saved = __currFrame;
153190
mrisReadGIFTIfile(__overlayInfo[__currFrame].__foverlay, mris, __overlaymri, &__currFrame);
154191

155-
// ??? multiple frames ???
156-
__overlayInfo[__currOverlay].__numframe = 1;
157-
//else
158-
// __overlaymri = MRISreadGiftiAsMRI(__foverlay, read_volume);
192+
__overlayInfo[__currOverlay].__numframe = (__currFrame - currFrame_saved);
159193
}
160194
else if (overlayFormat == ASCII_FILE)
161195
{
@@ -424,13 +458,10 @@ int MRISurfOverlay::write(const char *fout, MRIS *mris, bool mergegifti)
424458
}
425459
else if (outtype == GIFTI_FILE)
426460
{
427-
//MRISwriteGIFTICombined(mris, fout, __overlaymri, __noverlay, __overlayInfo);
428461
if (mergegifti)
429462
MRISwriteGIFTICombined(mris, this, fout);
430463
else
431464
{
432-
int giftiintent = getGIFTIIntent(0);
433-
434465
/* ???__foverlay will be read again in MRISwriteGIFTI() why???
435466
* ...
436467
* if (intent_code == NIFTI_INTENT_SHAPE) {
@@ -442,6 +473,7 @@ int MRISurfOverlay::write(const char *fout, MRIS *mris, bool mergegifti)
442473
* ...
443474
* }
444475
*/
476+
int giftiintent = getGIFTIIntent(0);
445477
error = MRISwriteGIFTI(mris, giftiintent, fout, __overlayInfo[0].__foverlay);
446478
}
447479
}

0 commit comments

Comments
 (0)