00001 #include "SUMA_suma.h"
00002
00003 SUMA_SurfaceViewer *SUMAg_cSV = NULL;
00004 SUMA_SurfaceViewer *SUMAg_SVv = NULL;
00005
00006 int SUMAg_N_SVv = 0;
00007 SUMA_DO *SUMAg_DOv = NULL;
00008 int SUMAg_N_DOv = 0;
00009 SUMA_CommonFields *SUMAg_CF = NULL;
00010
00011 void usage_3dBRAIN_VOYAGERtoAFNI (SUMA_GENERIC_ARGV_PARSE *ps)
00012 {
00013 static char FuncName[]={"usage_3dBRAIN_VOYAGERtoAFNI"};
00014 char * s = NULL, *sio=NULL, *st = NULL, *sts = NULL;
00015 int i;
00016 s = SUMA_help_basics();
00017 sio = SUMA_help_IO_Args(ps);
00018 printf ( "\n"
00019 "Usage: 3dBRAIN_VOYAGERtoAFNI -input BV_VOLUME.vmr\n"
00020 " Converts a BrainVoyager vmr dataset to AFNI's BRIK format\n"
00021 " The conversion is based on information from BrainVoyager's\n"
00022 " website: www.brainvoyager.com. Sample data and information\n"
00023 " provided by Adam Greenberg and Nikolaus Kriegeskorte.\n"
00024 "\n"
00025 "%s"
00026 "%s"
00027 "\n", sio, s);
00028 SUMA_free(s); s = NULL; SUMA_free(st); st = NULL; SUMA_free(sio); sio = NULL;
00029 s = SUMA_New_Additions(0, 1); printf("%s\n", s);SUMA_free(s); s = NULL;
00030 printf(" Ziad S. Saad SSCC/NIMH/NIH ziad@nih.gov \n");
00031 exit(0);
00032 }
00033
00034 SUMA_GENERIC_PROG_OPTIONS_STRUCT *SUMA_3dBRAIN_VOYAGERtoAFNI_ParseInput(char *argv[], int argc, SUMA_GENERIC_ARGV_PARSE *ps)
00035 {
00036 static char FuncName[]={"SUMA_BrainWrap_ParseInput"};
00037 SUMA_GENERIC_PROG_OPTIONS_STRUCT *Opt=NULL;
00038 int kar;
00039 SUMA_Boolean brk;
00040 SUMA_Boolean LocalHead = NOPE;
00041
00042 SUMA_ENTRY;
00043
00044 Opt = SUMA_Alloc_Generic_Prog_Options_Struct();
00045 kar = 1;
00046 brk = NOPE;
00047 while (kar < argc) {
00048
00049 if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0) {
00050 usage_3dBRAIN_VOYAGERtoAFNI(ps);
00051 exit (0);
00052 }
00053
00054 SUMA_SKIP_COMMON_OPTIONS(brk, kar);
00055
00056 if (!brk && (strcmp(argv[kar], "-input") == 0)) {
00057 kar ++;
00058 if (kar >= argc) {
00059 fprintf (SUMA_STDERR, "need argument after -input\n");
00060 exit (1);
00061 }
00062 Opt->in_name = argv[kar];
00063 brk = YUP;
00064 }
00065 if (!brk && (strcmp(argv[kar], "-debug") == 0)) {
00066 kar ++;
00067 if (kar >= argc) {
00068 fprintf (SUMA_STDERR, "need integer argument after -debug\n");
00069 exit (1);
00070 }
00071 Opt->debug = atoi(argv[kar]);
00072 brk = YUP;
00073 }
00074
00075 if (!brk && !ps->arg_checked[kar]) {
00076 fprintf (SUMA_STDERR,"Error %s:\nOption %s not understood. Try -help for usage\n", FuncName, argv[kar]);
00077 exit (1);
00078 } else {
00079 brk = NOPE;
00080 kar ++;
00081 }
00082 }
00083
00084 SUMA_RETURN(Opt);
00085 }
00086
00087 char * SUMA_BrainVoyager_Read_vmr(char *fnameorig, THD_3dim_dataset *dset, int LoadData)
00088 {
00089 static char FuncName[]={"SUMA_BrainVoyager_Read_vmr"};
00090 int i = 0, nf, iop, dchunk, End, bs, doff, ex,
00091 data_type=SUMA_notypeset, view, endian, dblock;
00092 THD_ivec3 iv3;
00093 unsigned long len;
00094 short nvox[3];
00095 THD_mat33 m33;
00096 THD_ivec3 orixyz , nxyz ;
00097 THD_fvec3 dxyz , orgxyz ;
00098 float ep[3], sp[3];
00099 char sview[10], *fname = NULL, *scom=NULL, form[10], swp[10], orstr[10], xfov[100], yfov[100], zfov[100], *prefix = NULL, *dsetheadname = NULL;
00100 FILE *fid = NULL;
00101 SUMA_Boolean LocalHead = NOPE;
00102
00103 SUMA_ENTRY;
00104
00105 if (!dset || !fnameorig) {
00106 SUMA_SL_Err("NULL fname || NULL dset!");
00107 SUMA_RETURN(NOPE);
00108 }
00109
00110 if (!SUMA_isExtension(fnameorig, ".vmr")) {
00111 SUMA_SL_Err("vmr dset is expected to have .vmr for an extension");
00112 SUMA_RETURN(NOPE);
00113 }
00114
00115 if (!SUMA_filexists(fnameorig)) {
00116 SUMA_SL_Err("file does not exist");
00117 SUMA_RETURN(NOPE);
00118 }
00119
00120
00121 fname = SUMA_Extension(fnameorig,".vmr", YUP);
00122
00123 prefix = SUMA_AfniPrefix(fname, NULL, NULL, NULL);
00124 if( !THD_filename_ok(prefix) ) {
00125 SUMA_SL_Err("Bad prefix");
00126 goto CLEAN_EXIT;
00127 }
00128
00129
00130 view = VIEW_ORIGINAL_TYPE;
00131 if (strstr(fname, "_tal")) { view = VIEW_TALAIRACH_TYPE; sprintf(sview,"+tlrc"); }
00132 else if (strstr(fname, "_acpc")) { view = VIEW_ACPCALIGNED_TYPE; sprintf(sview,"+acpc"); }
00133 else { view = VIEW_ORIGINAL_TYPE; sprintf(sview,"+orig"); }
00134 if (LocalHead) fprintf(SUMA_STDERR,"%s: View %s, %d\n", FuncName, sview, view);
00135
00136 dsetheadname = SUMA_append_replace_string(prefix,".HEAD", sview, 0);
00137 if (SUMA_filexists(dsetheadname)) {
00138 SUMA_SL_Err("Bad prefix, output dset exists");
00139 goto CLEAN_EXIT;
00140 }
00141 SUMA_free(dsetheadname); dsetheadname = NULL;
00142
00143 fid = fopen(fnameorig,"r");
00144 if (!fid) {
00145 SUMA_SL_Err("Could not open file for reading");
00146 goto CLEAN_EXIT;
00147 }
00148
00149 SUMA_LH("Reading dimensions, 1st 6 bytes and deciding on swap");
00150 doff = 3*sizeof(short);
00151 SUMA_WHAT_ENDIAN(endian);
00152 bs = 0;
00153 swp[0] = '\0';
00154 data_type = SUMA_byte;
00155 dchunk = sizeof(byte);
00156 sprintf(form,"3Db");
00157 SUMA_READ_NUM(&(nvox[2]), fid, ex, sizeof(short));
00158 SUMA_READ_NUM(&(nvox[1]), fid, ex, sizeof(short));
00159 SUMA_READ_NUM(&(nvox[0]), fid, ex, sizeof(short));
00160 if (nvox[0] < 0 || nvox[1] < 0 || nvox[2] < 0 ) {
00161 SUMA_LH("Byte swapping needed");
00162 bs = 1;
00163 }
00164
00165 if (bs) {
00166 SUMA_swap_2(&(nvox[0]));
00167 SUMA_swap_2(&(nvox[1]));
00168 SUMA_swap_2(&(nvox[2]));
00169 sprintf(swp,"-2swap");
00170 SUMA_OTHER_ENDIAN(endian);
00171 }
00172
00173
00174 if (nvox[0] == nvox[1] && nvox[1] == nvox[2] && nvox[2] == 1) {
00175 if (LocalHead) { fprintf(SUMA_STDERR,"Warning %s: Voxel nums all 1. Trying from file size\n", FuncName); }
00176 len = THD_filesize( fnameorig ) ;
00177 len -= doff;
00178 len /= dchunk;
00179 nvox[0] = (int)pow((double)len, 1.0/3.0);
00180 if (nvox[0] * nvox[0] * nvox[0] != len) {
00181 fprintf(SUMA_STDERR,"Error %s: Bad voxel numbers and could not infer number from filesize.\n"
00182 "Size of file: %ld, data offset: %d, datum size: %d, data number: %ld\n"
00183 "Inferred nvox:%d\n",
00184 FuncName,
00185 THD_filesize( fnameorig ), doff, dchunk, len,
00186 nvox[0]);
00187 goto CLEAN_EXIT;
00188 }
00189 nvox[2] = nvox[1] = nvox[0];
00190 if (LocalHead) { fprintf(SUMA_STDERR,"Warning %s: Using filesize inferred number of voxels: %d %d %d\n",
00191 FuncName, nvox[0], nvox[1], nvox[2]); }
00192 }
00193
00194 if (LocalHead) fprintf(SUMA_STDERR,"Number of voxels: %d %d %d\n", nvox[0], nvox[1], nvox[2]);
00195
00196
00197
00198
00199 len = THD_filesize( fnameorig ) ;
00200 dblock = nvox[0]*nvox[1]*nvox[2]*dchunk;
00201 if (len != (dblock + doff)) {
00202 if (LocalHead) {
00203 fprintf(SUMA_STDERR, "Mismatch between file size %ld\n"
00204 "and expected size %d = (%d*%d*%d*%d+%d) \n",
00205 len, (dblock + doff), nvox[0], nvox[1], nvox[2], dchunk, doff);
00206 }
00207 goto CLEAN_EXIT;
00208 }
00209 if (LocalHead) fprintf(SUMA_STDERR,"File size passes test\n");
00210
00211
00212
00213 orixyz.ijk[0] = ORI_A2P_TYPE;
00214 orixyz.ijk[1] = ORI_S2I_TYPE;
00215 orixyz.ijk[2] = ORI_R2L_TYPE;
00216
00217
00218 LOAD_IVEC3( nxyz , nvox[0] , nvox[1] , nvox[2] ) ;
00219
00220
00221 SUMA_LH("Forming command");
00222
00223 {
00224 float delta[3]={1.0, 1.0, 1.0};
00225 float origin[3]={0.0, 0.0, 0.0};
00226
00227 LOAD_FVEC3( dxyz , delta[0], delta[1], delta[2] ) ;
00228 SUMA_sizeto3d_2_deltaHEAD(orixyz, &dxyz);
00229
00230 LOAD_FVEC3( orgxyz , origin[0], origin[1], origin[2] ) ;
00231 SUMA_originto3d_2_originHEAD(orixyz, &orgxyz);
00232
00233 }
00234
00235
00236 sp[0] = orgxyz.xyz[0] + SUMA_ABS(dxyz.xyz[0]) / 2.0;
00237 sp[1] = orgxyz.xyz[1] + SUMA_ABS(dxyz.xyz[1]) / 2.0;
00238 sp[2] = orgxyz.xyz[2] + SUMA_ABS(dxyz.xyz[2]) / 2.0;
00239 ep[0] = orgxyz.xyz[0] + (nxyz.ijk[0] - 0.5) * SUMA_ABS(dxyz.xyz[0]);
00240 ep[1] = orgxyz.xyz[1] + (nxyz.ijk[1] - 0.5) * SUMA_ABS(dxyz.xyz[1]);
00241 ep[2] = orgxyz.xyz[2] + (nxyz.ijk[2] - 0.5) * SUMA_ABS(dxyz.xyz[2]);
00242 SUMA_orcode_to_orstring (orixyz.ijk[0], orixyz.ijk[1], orixyz.ijk[2], orstr);
00243 sprintf(xfov," -xFOV %.2f%c-%.2f%c", sp[0], orstr[0], ep[0], orstr[3]);
00244 sprintf(yfov," -yFOV %.2f%c-%.2f%c", sp[1], orstr[1], ep[1], orstr[4]);
00245 sprintf(zfov," -zFOV %.2f%c-%.2f%c", sp[2], orstr[2], ep[2], orstr[5]);
00246
00247 scom = (char *)SUMA_calloc((strlen(fnameorig)+500), sizeof(char));
00248 sprintf(scom,"to3d %s %s %s %s -prefix %s %s:%d:0:%d:%d:%d:%s ",
00249 swp, xfov, yfov, zfov, prefix, form, doff,
00250 nvox[0], nvox[1], nvox[0], fnameorig);
00251
00252
00253 if (dset) {
00254 int nvals_read = 0;
00255 SUMA_LH("Filling header");
00256 EDIT_dset_items( dset ,
00257 ADN_prefix , prefix ,
00258 ADN_datum_all , data_type ,
00259 ADN_nxyz , nxyz ,
00260 ADN_xyzdel , dxyz ,
00261 ADN_xyzorg , orgxyz ,
00262 ADN_xyzorient , orixyz ,
00263 ADN_malloc_type , DATABLOCK_MEM_MALLOC ,
00264 ADN_view_type , view ,
00265 ADN_type , HEAD_ANAT_TYPE ,
00266 ADN_func_type , ANAT_BUCK_TYPE ,
00267 ADN_none ) ;
00268
00269 if (LoadData) {
00270 void *vec=NULL;
00271 SUMA_LH("Loading data");
00272 if (!(vec = SUMA_BinarySuck(fnameorig, data_type, endian, 3*sizeof(short), -1, &nvals_read))) {
00273 SUMA_SL_Err("Failed to read data file"); goto CLEAN_EXIT;
00274 }
00275 if (nvals_read != nvox[0]*nvox[1]*nvox[2]) {
00276 SUMA_SL_Warn("Failed to read the appropriate number of voxels\n proceeding...");
00277
00278 }
00279 EDIT_substitute_brick( dset , 0 , data_type , vec) ;
00280 if (LocalHead) fprintf(SUMA_STDERR,"%s: Read %d values from file.\n", FuncName, nvals_read);
00281
00282 }
00283 }
00284
00285
00286
00287 CLEAN_EXIT:
00288 if (prefix) SUMA_free(prefix); prefix = NULL;
00289 if (fname) SUMA_free(fname); fname = NULL;
00290 if (fid) fclose(fid); fid = NULL;
00291 SUMA_RETURN(scom);
00292 }
00293
00294 int main (int argc,char *argv[])
00295 {
00296 static char FuncName[]={"3dBRAIN_VOYAGERtoAFNI"};
00297 SUMA_GENERIC_PROG_OPTIONS_STRUCT *Opt;
00298 SUMA_GENERIC_ARGV_PARSE *ps=NULL;
00299 SUMA_OPEN_DX_STRUCT **dx = NULL;
00300 THD_3dim_dataset *dset=NULL;
00301 char *sto3d = NULL;
00302 SUMA_Boolean LocalHead = NOPE;
00303
00304 SUMA_mainENTRY;
00305 SUMA_STANDALONE_INIT;
00306
00307
00308 SUMAg_DOv = SUMA_Alloc_DisplayObject_Struct (SUMA_MAX_DISPLAYABLE_OBJECTS);
00309 ps = SUMA_Parse_IO_Args(argc, argv, "");
00310
00311 if (argc < 2) {
00312 usage_3dBRAIN_VOYAGERtoAFNI(ps);
00313 exit (1);
00314 }
00315
00316 Opt = SUMA_3dBRAIN_VOYAGERtoAFNI_ParseInput (argv, argc, ps);
00317
00318 if (Opt->debug > 2) LocalHead = YUP;
00319
00320 dset = EDIT_empty_copy( NULL ) ;
00321 tross_Make_History( "3dBRAIN_VOYAGERtoAFNI" , argc,argv , dset) ;
00322 if (!(sto3d = SUMA_BrainVoyager_Read_vmr(Opt->in_name, dset, 1))) {
00323 if (Opt->debug) SUMA_SL_Err("Failed in SUMA_BrainVoyager_Read_vmr");
00324 exit(1);
00325 }
00326 if (dset) {
00327 SUMA_LH("Writing Dset");
00328 DSET_write(dset) ;
00329 if (LocalHead) {
00330 fprintf(SUMA_STDERR,"%s: Can use the following command to create dset with to3d:\n%s\n", FuncName,sto3d);
00331 }
00332 } else {
00333
00334 if (system(sto3d)) {
00335 fprintf(SUMA_STDERR, "Error %s: Failed while executing shell command:\n%s\n"
00336 "Check to3d's error messages, and disk writing permissions.\n", FuncName, sto3d);
00337 }
00338 }
00339
00340
00341
00342 if (sto3d) SUMA_free(sto3d); sto3d = NULL;
00343 if (dset) { DSET_delete(dset); dset = NULL; }
00344 if (Opt) Opt = SUMA_Free_Generic_Prog_Options_Struct(Opt);
00345 if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
00346 exit(0);
00347
00348 }