00001 
00002 #include "SUMA_suma.h"
00003 
00004 extern SUMA_CommonFields *SUMAg_CF; 
00005 
00006 
00007 
00008 int SUMA_THD_handedness( THD_3dim_dataset * dset )
00009 {
00010    THD_dataxes * dax ;
00011    THD_mat33 q ;
00012    int col ;
00013    float val ;
00014 
00015 
00016    if( !ISVALID_DSET(dset) ) SUMA_RETURN(1) ;
00017 
00018    LOAD_ZERO_MAT(q) ;
00019    dax = dset->daxes ;
00020 
00021    col = 0 ;
00022    switch( dax->xxorient ){
00023       case 0: q.mat[0][col] =  1.0 ; break ;
00024       case 1: q.mat[0][col] = -1.0 ; break ;
00025       case 2: q.mat[1][col] = -1.0 ; break ;
00026       case 3: q.mat[1][col] =  1.0 ; break ;
00027       case 4: q.mat[2][col] =  1.0 ; break ;
00028       case 5: q.mat[2][col] = -1.0 ; break ;
00029    }
00030 
00031    col = 1 ;
00032    switch( dax->yyorient ){
00033       case 0: q.mat[0][col] =  1.0 ; break ;
00034       case 1: q.mat[0][col] = -1.0 ; break ;
00035       case 2: q.mat[1][col] = -1.0 ; break ;
00036       case 3: q.mat[1][col] =  1.0 ; break ;
00037       case 4: q.mat[2][col] =  1.0 ; break ;
00038       case 5: q.mat[2][col] = -1.0 ; break ;
00039    }
00040 
00041    col = 2 ;
00042    switch( dax->zzorient ){
00043       case 0: q.mat[0][col] =  1.0 ; break ;
00044       case 1: q.mat[0][col] = -1.0 ; break ;
00045       case 2: q.mat[1][col] = -1.0 ; break ;
00046       case 3: q.mat[1][col] =  1.0 ; break ;
00047       case 4: q.mat[2][col] =  1.0 ; break ;
00048       case 5: q.mat[2][col] = -1.0 ; break ;
00049    }
00050 
00051    val = MAT_DET(q) ;
00052    if( val > 0.0 ) SUMA_RETURN( 1) ;  
00053    else            SUMA_RETURN(-1) ;  
00054 }
00055 
00056 
00057 
00058 
00059 SUMA_Boolean SUMA_AfniExistsView(int exists, char *view)
00060 {
00061    static char FuncName[]={"SUMA_AfniExistsView"};
00062    SUMA_Boolean ans = NOPE;
00063    
00064    if (!exists) SUMA_RETURN(ans);
00065    
00066    if (strcmp(view,"+orig") == 0) {
00067       if (exists == 1 || exists == 3 || exists == 5 || exists == 7) ans = YUP; 
00068    } else if (strcmp(view,"+acpc") == 0) {
00069       if (exists == 2 || exists == 3 || exists == 6 || exists == 7) ans = YUP; 
00070    } else if (strcmp(view,"+tlrc") == 0) {
00071       if (exists == 4 || exists == 5 || exists == 6 || exists == 7) ans = YUP; 
00072    } 
00073    
00074    SUMA_RETURN(ans);
00075 
00076 }
00077 
00078 SUMA_Boolean SUMA_AfniView (char *nameorig, char *cview)
00079 {
00080    static char FuncName[]={"SUMA_AfniView"};
00081    char *tmp1 = NULL, *tmp2 = NULL;
00082    SUMA_Boolean LocalHead = NOPE;
00083    
00084    SUMA_ENTRY;
00085    
00086    if (!nameorig) SUMA_RETURN(NOPE);
00087    if (!cview) SUMA_RETURN(NOPE);
00088 
00089    tmp1 = SUMA_Extension(nameorig, ".HEAD", YUP);
00090    tmp2 = SUMA_Extension(tmp1, ".BRIK", YUP); SUMA_free(tmp1); tmp1 = NULL;
00091    
00092    if (tmp2[strlen(tmp2)-1] == '.') tmp2[strlen(tmp2)-1] = '\0';
00093    
00094    if (LocalHead) fprintf(SUMA_STDERR,"%s: Searching for view of %s\n", FuncName, tmp2);
00095    
00096    
00097    if (SUMA_isExtension(tmp2, "+orig")) { 
00098       sprintf(cview, "+orig"); 
00099    } else if (SUMA_isExtension(tmp2, "+acpc")) { 
00100       sprintf(cview, "+acpc"); 
00101    } else if (SUMA_isExtension(tmp2, "+tlrc")) { 
00102       sprintf(cview, "+tlrc"); 
00103    } else {
00104       cview[0]='\0';
00105    }
00106    SUMA_free(tmp2); tmp2 = NULL;
00107 
00108    SUMA_RETURN(YUP);
00109 }
00110 
00111 SUMA_Boolean SUMA_AfniExists(char *prefix, char *c2view) 
00112 {
00113    static char FuncName[]={"SUMA_AfniExists"};
00114    char *head=NULL;
00115    SUMA_Boolean ans = NOPE;
00116    SUMA_Boolean LocalHead = NOPE;
00117    
00118    ans = NOPE;
00119 
00120    head = SUMA_append_replace_string(prefix,".HEAD", c2view,0);
00121    if (LocalHead) fprintf(SUMA_STDERR,"%s: Checking existence of %s\n", FuncName, head);
00122    if (SUMA_filexists(head)) { ans = YUP; }
00123    SUMA_free(head); head = NULL; 
00124    
00125    SUMA_RETURN(ans);
00126 }
00127 
00128 
00129 
00130 
00131 
00132 
00133 
00134 
00135 
00136 
00137 
00138 
00139 
00140 
00141 
00142 
00143 
00144 
00145 
00146 
00147 char *SUMA_AfniPrefix(char *nameorig, char *view, char *path, int *exists) 
00148 {
00149    static char FuncName[]={"SUMA_AfniPrefix"};
00150    char *tmp1 = NULL, *tmp2 = NULL, *prfx = NULL, *name=NULL;
00151    char cview[10];
00152    int iview;
00153    SUMA_Boolean LocalHead = NOPE;
00154    
00155    SUMA_ENTRY;
00156    
00157    if (!nameorig) SUMA_RETURN(prfx);
00158    if (exists) *exists = 0;
00159    
00160    if (LocalHead) fprintf(SUMA_STDERR,"%s: Working with %s\n", FuncName, nameorig);
00161    
00162    if (!path) name = SUMA_copy_string(nameorig);
00163    else {
00164       if (path[strlen(path)-1] == '/') {
00165          name = SUMA_append_replace_string(path, nameorig, "", 0);
00166       } else {
00167          name = SUMA_append_replace_string(path, nameorig, "/", 0);
00168       }
00169    }
00170    
00171    if (LocalHead) fprintf(SUMA_STDERR,"%s: name now %s\n", FuncName, name);
00172    
00173    tmp1 = SUMA_Extension(name, ".HEAD", YUP);
00174    tmp2 = SUMA_Extension(tmp1, ".BRIK", YUP); SUMA_free(tmp1); tmp1 = NULL;
00175    
00176    if (tmp2[strlen(tmp2)-1] == '.') tmp2[strlen(tmp2)-1] = '\0';
00177    
00178    if (LocalHead) fprintf(SUMA_STDERR,"%s: Searching for view of %s\n", FuncName, tmp2);
00179    
00180    
00181    iview = -1;
00182    if (SUMA_isExtension(tmp2, "+orig")) { 
00183       iview = 0; sprintf(cview, "+orig"); 
00184       prfx = SUMA_Extension(tmp2, "+orig", YUP);
00185    } else if (SUMA_isExtension(tmp2, "+acpc")) { 
00186       iview = 1; sprintf(cview, "+acpc"); 
00187       prfx = SUMA_Extension(tmp2, "+acpc", YUP);
00188    } else if (SUMA_isExtension(tmp2, "+tlrc")) { 
00189       iview = 2; sprintf(cview, "+tlrc"); 
00190       prfx = SUMA_Extension(tmp2, "+tlrc", YUP);
00191    } else {
00192       prfx = SUMA_copy_string(tmp2);
00193       cview[0]='\0';
00194    }
00195    SUMA_free(tmp2); tmp2 = NULL;
00196    
00197    if (LocalHead) fprintf(SUMA_STDERR,"%s: Prefix %s\n", FuncName, prfx);
00198    
00199    
00200    {   
00201       
00202       char *bname=SUMA_append_string(prfx,"+orig");
00203       if (LocalHead) fprintf(SUMA_STDERR,"%s: Checking name validity using +orig for view %s\n", FuncName, bname);
00204       if( !THD_filename_ok(bname) ){
00205          SUMA_SL_Err("not a proper dset name!\n") ;
00206          SUMA_free(name); name = NULL;
00207          SUMA_free(prfx); prfx = NULL;
00208          SUMA_free(bname); bname = NULL;
00209          SUMA_RETURN(prfx);
00210       }
00211    }
00212    
00213    if (exists) {
00214       { 
00215          char *head=NULL, c2view[10];
00216          iview = 0; *exists = 0;
00217          while (iview < 3) {
00218             if (iview == 0) sprintf(c2view, "+orig"); 
00219             else if (iview == 1) sprintf(c2view, "+acpc"); 
00220             else if (iview == 2) sprintf(c2view, "+tlrc");
00221             head = SUMA_append_replace_string(prfx,".HEAD", c2view,0);
00222             if (LocalHead) fprintf(SUMA_STDERR,"%s: Checking existence of %s\n", FuncName, head);
00223             if (SUMA_filexists(head)) { *exists += (int)pow(2,iview); }
00224             SUMA_free(head); head = NULL; 
00225             ++iview;
00226          }
00227       }
00228       if (LocalHead) fprintf(SUMA_STDERR,"%s: exist number is %d\n", FuncName, *exists);
00229    }
00230    
00231    
00232    if (cview[0] != '\0') {
00233       if (LocalHead) {
00234          if (SUMA_AfniExistsView(*exists, cview)) {
00235             fprintf(SUMA_STDERR,"%s: dset with view %s does exist.\n", FuncName, cview); 
00236          } else {
00237             fprintf(SUMA_STDERR,"%s: dset with view %s does not exist.\n", FuncName, cview); 
00238          }
00239       }
00240    }
00241    
00242    if (view) {
00243       sprintf(view,"%s", cview);
00244    }
00245    if (name) SUMA_free(name); name = NULL;
00246    
00247    SUMA_RETURN(prfx);
00248 }
00249                         
00250 
00251 
00252 
00253 
00254 
00255 
00256 
00257 
00258 byte * SUMA_isSkin(THD_3dim_dataset *dset, double *dvec, double thresh, int *N_skin)
00259 {
00260    static char FuncName[]={"SUMA_isSkin"};
00261    byte *isskin=NULL;
00262    int x, y, z, nx, ny, nz, i1D,  nxy;
00263   
00264    SUMA_ENTRY;
00265    
00266    if (!dset || !dvec) {
00267       SUMA_SL_Err("NULL input dset or dvec");
00268       SUMA_RETURN(isskin);
00269    }
00270    
00271    nx = DSET_NX(dset);
00272    ny = DSET_NY(dset);
00273    nz = DSET_NZ(dset);
00274    nxy = nx * ny;
00275    
00276    isskin = (byte *) SUMA_calloc(nxy * nz, sizeof(byte));
00277    if (!isskin) {
00278       SUMA_SL_Crit("Failed to allocate");
00279       SUMA_RETURN(NULL);
00280    }
00281    
00282    *N_skin = 0;
00283    for (z=0; z<nz; ++z) {
00284       for (y=0; y<ny; ++y) {
00285          x = 0;
00286          do { 
00287             i1D = SUMA_3D_2_1D_index(x, y, z, nx, nxy);
00288             if (dvec[i1D] > thresh) { isskin[i1D] = 1; ++ *N_skin; }
00289             ++x; 
00290          } while (x < nx && !isskin[i1D]);
00291          x = nx - 1;
00292          do { 
00293             i1D = SUMA_3D_2_1D_index(x, y, z, nx, nxy);
00294             if (dvec[i1D] > thresh) { isskin[i1D] = 1; ++ *N_skin; }
00295             --x; 
00296          } while (x >=0 && !isskin[i1D]);
00297       } 
00298    } 
00299    
00300    for (z=0; z<nz; ++z) {
00301       for (x=0; x<nx; ++x) {
00302          y = 0;
00303          do { 
00304             i1D = SUMA_3D_2_1D_index(x, y, z, nx, nxy);
00305             if (dvec[i1D] > thresh) { isskin[i1D] = 1; ++ *N_skin; }
00306             ++y; 
00307          } while (y < ny && !isskin[i1D]);
00308          y = ny - 1;
00309          do { 
00310             i1D = SUMA_3D_2_1D_index(x, y, z, nx, nxy);
00311             if (dvec[i1D] > thresh) { isskin[i1D] = 1; ++ *N_skin; }
00312             --y; 
00313          } while (y >=0 && !isskin[i1D]);
00314       } 
00315    } 
00316    
00317    for (x=0; x<nx; ++x) {
00318       for (y=0; y<ny; ++y) {
00319          z = 0;
00320          do { 
00321             i1D = SUMA_3D_2_1D_index(x, y, z, nx, nxy);
00322             if (dvec[i1D] > thresh) { isskin[i1D] = 1; ++ *N_skin; }
00323             ++z; 
00324          } while (z < nz && !isskin[i1D]);
00325          z = nz - 1;
00326          do { 
00327             i1D = SUMA_3D_2_1D_index(x, y, z, nx, nxy);
00328             if (dvec[i1D] > thresh) { isskin[i1D] = 1; ++ *N_skin; }
00329             --z; 
00330          } while (z >=0 && !isskin[i1D]);
00331       } 
00332    } 
00333       
00334    SUMA_RETURN(isskin);
00335 }
00336 
00337 
00338 
00339 
00340 
00341 
00342 SUMA_VOLPAR *SUMA_Alloc_VolPar (void)
00343 {
00344    static char FuncName[]={"SUMA_Alloc_VolPar"};
00345    SUMA_VOLPAR *VP;
00346 
00347    SUMA_ENTRY;
00348 
00349    VP = (SUMA_VOLPAR *)SUMA_malloc(sizeof(SUMA_VOLPAR));
00350    if (VP == NULL) {
00351       fprintf(SUMA_STDERR,"Error SUMA_Alloc_VolPar: Failed to allocate for VolPar\n");
00352       SUMA_RETURN (NULL);
00353    }
00354    VP->idcode_str = NULL;
00355    VP->isanat = 1;
00356    VP->nx = VP->ny = VP->nz = 0; 
00357    VP->dx = VP->dy = VP->dz = 0.0; 
00358    VP->xorg = VP->yorg = VP->zorg = 0.0; 
00359    VP->prefix = NULL; 
00360    VP->filecode = NULL; 
00361    VP->dirname = NULL; 
00362    VP->vol_idcode_str = NULL; 
00363    VP->vol_idcode_date = NULL; 
00364    VP->xxorient = VP->yyorient = VP->zzorient = 0;  
00365    VP->VOLREG_CENTER_OLD = NULL; 
00366    VP->VOLREG_CENTER_BASE = NULL; 
00367    VP->VOLREG_MATVEC = NULL; 
00368    VP->TAGALIGN_MATVEC = NULL; 
00369    VP->ROTATE_MATVEC = NULL; 
00370    VP->ROTATE_CENTER_OLD = NULL;
00371    VP->ROTATE_CENTER_BASE = NULL;
00372    VP->Hand = 1; 
00373    
00374    SUMA_RETURN(VP);
00375 }
00376 SUMA_Boolean SUMA_Free_VolPar (SUMA_VOLPAR *VP)
00377 {
00378    static char FuncName[]={"SUMA_Free_VolPar"};
00379    
00380    SUMA_ENTRY;
00381 
00382    if (VP->prefix != NULL) SUMA_free(VP->prefix);
00383    if (VP->idcode_str != NULL) SUMA_free(VP->idcode_str);
00384    if (VP->filecode != NULL) SUMA_free(VP->filecode);
00385    if (VP->dirname != NULL) SUMA_free(VP->dirname);
00386    if (VP->vol_idcode_str != NULL) SUMA_free(VP->vol_idcode_str);
00387    if (VP->vol_idcode_date != NULL) SUMA_free(VP->vol_idcode_date);
00388    if (VP->VOLREG_CENTER_OLD != NULL) SUMA_free(VP->VOLREG_CENTER_OLD);
00389    if (VP->VOLREG_CENTER_BASE != NULL) SUMA_free(VP->VOLREG_CENTER_BASE);
00390    if (VP->VOLREG_MATVEC != NULL) SUMA_free(VP->VOLREG_MATVEC);
00391    if (VP->TAGALIGN_MATVEC != NULL) SUMA_free(VP->TAGALIGN_MATVEC);
00392    if (VP->ROTATE_MATVEC != NULL) SUMA_free(VP->ROTATE_MATVEC);
00393    if (VP->ROTATE_CENTER_OLD != NULL) SUMA_free(VP->ROTATE_CENTER_OLD);
00394    if (VP->ROTATE_CENTER_BASE != NULL) SUMA_free(VP->ROTATE_CENTER_BASE);
00395    if (VP != NULL) SUMA_free(VP);
00396    SUMA_RETURN (YUP);
00397 }
00398 
00399 SUMA_VOLPAR *SUMA_VolParFromDset (THD_3dim_dataset *dset)
00400 {
00401    ATR_float *atr;
00402    static char FuncName[]={"SUMA_VolParFromDset"};
00403    SUMA_VOLPAR *VP;
00404    int ii;
00405    MCW_idcode idcode;
00406    SUMA_Boolean LocalHead = NOPE;
00407       
00408    SUMA_ENTRY;
00409 
00410    
00411    if (dset == NULL) {
00412       fprintf (SUMA_STDERR,"Error %s:\nNULL dset\n", FuncName);
00413       SUMA_RETURN (NULL);
00414    }
00415    
00416    
00417    VP = SUMA_Alloc_VolPar();
00418    if (VP == NULL) {
00419       fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_Alloc_VolPar\n", FuncName);
00420       SUMA_RETURN (NULL);
00421    }
00422    
00423    
00424    VP->isanat = ISANAT(dset);
00425    VP->nx = DSET_NX(dset);
00426    VP->ny = DSET_NY(dset);
00427    VP->nz = DSET_NZ(dset);
00428    VP->dx = DSET_DX(dset);
00429    VP->dy = DSET_DY(dset);
00430    VP->dz = DSET_DZ(dset);
00431    VP->xorg = DSET_XORG(dset);
00432    VP->yorg = DSET_YORG(dset);
00433    VP->zorg = DSET_ZORG(dset);
00434    ii = strlen(DSET_PREFIX(dset));
00435    VP->prefix = (char *)SUMA_malloc(ii+1);
00436    ii = strlen(DSET_FILECODE(dset));
00437    VP->filecode = (char *)SUMA_malloc(ii+1);
00438    ii = strlen(DSET_DIRNAME(dset));
00439    VP->dirname = (char *)SUMA_malloc(ii+1);
00440    ii = strlen(dset->idcode.str);
00441    VP->vol_idcode_str = (char *)SUMA_malloc(ii+1);
00442    ii = strlen(dset->idcode.date);
00443    VP->vol_idcode_date = (char *)SUMA_malloc(ii+1);
00444    if (VP->prefix == NULL || VP->filecode == NULL || VP->vol_idcode_date == NULL || VP->dirname == NULL || VP->vol_idcode_str == NULL) {
00445       fprintf(SUMA_STDERR,"Error %s: Failed to allocate for strings. Kill me, please.\n", FuncName);
00446       SUMA_Free_VolPar(VP);
00447       SUMA_RETURN (NULL);
00448    }
00449    VP->prefix = strcpy(VP->prefix, DSET_PREFIX(dset));
00450    VP->filecode = strcpy(VP->filecode, DSET_FILECODE(dset));
00451    VP->dirname = strcpy(VP->dirname, DSET_DIRNAME(dset));
00452    VP->vol_idcode_str = strcpy(VP->vol_idcode_str, dset->idcode.str);
00453    VP->vol_idcode_date = strcpy(VP->vol_idcode_date, dset->idcode.date);
00454    VP->xxorient = dset->daxes->xxorient;
00455    VP->yyorient = dset->daxes->yyorient;
00456    VP->zzorient = dset->daxes->zzorient;
00457 
00458    if (LocalHead) {      
00459       fprintf (SUMA_STDERR,"%s: dset->idcode_str = %s\n", FuncName, dset->idcode.str);
00460       fprintf (SUMA_STDERR,"%s: VP->vol_idcode_str = %s\n", FuncName, VP->vol_idcode_str);
00461    }
00462    
00463    atr = THD_find_float_atr( dset->dblk , "ROTATE_MATVEC_000000" ) ;
00464    if (atr == NULL) {
00465       VP->ROTATE_MATVEC = NULL;
00466    }else {
00467       VP->ROTATE_MATVEC = (float *)SUMA_calloc(12, sizeof(float));
00468       if (VP->ROTATE_MATVEC != NULL) {
00469          if (atr->nfl == 12) {
00470             for (ii=0; ii<12; ++ii) VP->ROTATE_MATVEC[ii] = atr->fl[ii];
00471          } else {   
00472             fprintf(SUMA_STDERR,"Error %s: ROTATE_MATVEC does not have 12 elements.\n", FuncName);
00473          }
00474       } else {
00475          fprintf(SUMA_STDERR,"Error %s: Failed to allocate for VP->ROTATE_MATVEC\n", FuncName);
00476       }
00477    }
00478    
00479    
00480    atr = THD_find_float_atr( dset->dblk , "TAGALIGN_MATVEC" ) ;
00481    if (atr == NULL) {
00482       VP->TAGALIGN_MATVEC = NULL;
00483    }else {
00484       VP->TAGALIGN_MATVEC = (float *)SUMA_calloc(12, sizeof(float));
00485       if (VP->TAGALIGN_MATVEC != NULL) {
00486          if (atr->nfl == 12) {
00487             for (ii=0; ii<12; ++ii) VP->TAGALIGN_MATVEC[ii] = atr->fl[ii];
00488          } else {   
00489             fprintf(SUMA_STDERR,"Error %s: TAGALIGN_MATVEC does not have 12 elements.\n", FuncName);
00490          }
00491       } else {
00492          fprintf(SUMA_STDERR,"Error %s: Failed to allocate for VP->TAGALIGN_MATVEC\n", FuncName);
00493       }
00494    }
00495    
00496    
00497    atr = THD_find_float_atr( dset->dblk , "VOLREG_MATVEC_000000" ) ;
00498    if (atr == NULL) {
00499       VP->VOLREG_MATVEC = NULL;
00500    }else {
00501       VP->VOLREG_MATVEC = (float *)SUMA_calloc(12, sizeof(float));
00502       if (VP->VOLREG_MATVEC != NULL) {
00503          if (atr->nfl == 12) {
00504             for (ii=0; ii<12; ++ii) VP->VOLREG_MATVEC[ii] = atr->fl[ii];
00505          } else {   
00506             fprintf(SUMA_STDERR,"Error %s: VOLREG_MATVEC_000000 does not have 12 elements.\n", FuncName);
00507          }
00508       } else {
00509          fprintf(SUMA_STDERR,"Error %s: Failed to allocate for VP->VOLREG_MATVEC\n", FuncName);
00510       }
00511    }
00512    
00513    atr = THD_find_float_atr( dset->dblk , "VOLREG_CENTER_BASE");
00514    if (atr == NULL) {
00515       VP->VOLREG_CENTER_BASE = NULL;
00516    } else {
00517       VP->VOLREG_CENTER_BASE = (float *)SUMA_calloc(3, sizeof(float));
00518       if (VP->VOLREG_CENTER_BASE != NULL) {
00519          if (atr->nfl == 3) {
00520             for (ii=0; ii<3; ++ii) VP->VOLREG_CENTER_BASE[ii] = atr->fl[ii];
00521          } else {   
00522             fprintf(SUMA_STDERR,"Error %s: VOLREG_CENTER_BASE does not have 12 elements.\n", FuncName);
00523          }
00524       } else {
00525          fprintf(SUMA_STDERR,"Error %s: Failed to allocate for VP->VOLREG_CENTER_BASE\n", FuncName);
00526       }
00527    }
00528    
00529    atr = THD_find_float_atr( dset->dblk , "VOLREG_CENTER_OLD");
00530    if (atr == NULL) {
00531       VP->VOLREG_CENTER_OLD = NULL;
00532    } else {
00533       VP->VOLREG_CENTER_OLD = (float *)SUMA_calloc(3, sizeof(float));
00534       if (VP->VOLREG_CENTER_OLD != NULL) {
00535          if (atr->nfl == 3) {
00536             for (ii=0; ii<3; ++ii) VP->VOLREG_CENTER_OLD[ii] = atr->fl[ii];
00537          } else {   
00538             fprintf(SUMA_STDERR,"Error %s: VOLREG_CENTER_OLD does not have 12 elements.\n", FuncName);
00539          }
00540       } else {
00541          fprintf(SUMA_STDERR,"Error %s: Failed to allocate for VP->VOLREG_CENTER_OLD\n", FuncName);
00542       }
00543    }
00544    
00545    
00546    atr = THD_find_float_atr( dset->dblk , "ROTATE_CENTER_BASE");
00547    if (atr == NULL) {
00548       VP->ROTATE_CENTER_BASE = NULL;
00549    } else {
00550       VP->ROTATE_CENTER_BASE = (float *)SUMA_calloc(3, sizeof(float));
00551       if (VP->ROTATE_CENTER_BASE != NULL) {
00552          if (atr->nfl == 3) {
00553             for (ii=0; ii<3; ++ii) VP->ROTATE_CENTER_BASE[ii] = atr->fl[ii];
00554          } else {   
00555             fprintf(SUMA_STDERR,"Error %s: ROTATE_CENTER_BASE does not have 12 elements.\n", FuncName);
00556          }
00557       } else {
00558          fprintf(SUMA_STDERR,"Error %s: Failed to allocate for VP->ROTATE_CENTER_BASE\n", FuncName);
00559       }
00560    }
00561    
00562    atr = THD_find_float_atr( dset->dblk , "ROTATE_CENTER_OLD");
00563    if (atr == NULL) {
00564       VP->ROTATE_CENTER_OLD = NULL;
00565    } else {
00566       VP->ROTATE_CENTER_OLD = (float *)SUMA_calloc(3, sizeof(float));
00567       if (VP->ROTATE_CENTER_OLD != NULL) {
00568          if (atr->nfl == 3) {
00569             for (ii=0; ii<3; ++ii) VP->ROTATE_CENTER_OLD[ii] = atr->fl[ii];
00570          } else {   
00571             fprintf(SUMA_STDERR,"Error %s: ROTATE_CENTER_OLD does not have 12 elements.\n", FuncName);
00572          }
00573       } else {
00574          fprintf(SUMA_STDERR,"Error %s: Failed to allocate for VP->ROTATE_CENTER_OLD\n", FuncName);
00575       }
00576    }
00577 
00578    
00579    VP->Hand = SUMA_THD_handedness( dset );
00580    
00581    SUMA_RETURN (VP);
00582 }
00583 
00584 SUMA_VOLPAR *SUMA_VolPar_Attr (char *volparent_name)
00585 {
00586    ATR_float *atr;
00587    static char FuncName[]={"SUMA_VolPar_Attr"};
00588    SUMA_VOLPAR *VP;
00589    THD_3dim_dataset *dset;
00590    int ii;
00591    MCW_idcode idcode;
00592    SUMA_Boolean LocalHead = NOPE;
00593       
00594    SUMA_ENTRY;
00595 
00596    
00597    dset = THD_open_dataset(volparent_name);
00598    if (dset == NULL) {
00599       fprintf (SUMA_STDERR,"Error %s: Could not read %s\n", FuncName, volparent_name);
00600       SUMA_RETURN (NULL);
00601    }
00602    
00603    VP = SUMA_VolParFromDset(dset);
00604    if (!VP) {
00605       SUMA_SL_Err("Failed in SUMA_VolParFromDset");
00606    }
00607 
00608    
00609    THD_delete_3dim_dataset( dset , False ) ;
00610    
00611    SUMA_RETURN (VP);
00612 }
00613 
00614 
00615 
00616 
00617 
00618 
00619 
00620 
00621 
00622 
00623 
00624 char *SUMA_VolPar_Info (SUMA_VOLPAR *VP)
00625 {
00626    static char FuncName[]={"SUMA_VolPar_Info"};
00627    char stmp[1000], *s=NULL;
00628    SUMA_STRING *SS = NULL;
00629    
00630    SUMA_ENTRY;
00631 
00632    SS = SUMA_StringAppend (NULL, NULL);
00633    
00634    if (VP) { 
00635       sprintf (stmp,"\nVP contents:\n");
00636       SS = SUMA_StringAppend (SS, stmp);
00637       sprintf (stmp,"prefix: %s\tfilecode: %s\tdirname: %s\nId code str:%s\tID code date: %s\n", \
00638          VP->prefix, VP->filecode, VP->dirname, VP->vol_idcode_str, VP->vol_idcode_date);
00639       SS = SUMA_StringAppend (SS, stmp);
00640       if (VP->idcode_str) SS = SUMA_StringAppend (SS, "IDcode is NULL\n");
00641       else SS = SUMA_StringAppend_va (SS, "IDcode: %s\n", VP->idcode_str);
00642       
00643       sprintf (stmp,"isanat: %d\n", VP->isanat);
00644       SS = SUMA_StringAppend (SS, stmp);
00645       sprintf (stmp,"Orientation: %d %d %d\n", \
00646          VP->xxorient, VP->yyorient, VP->zzorient);
00647       if (VP->Hand == 1) SS = SUMA_StringAppend (SS, "Right Hand Coordinate System.\n");
00648       else if (VP->Hand == -1) SS = SUMA_StringAppend (SS, "Left Hand Coordinate System.\n");
00649       else SS = SUMA_StringAppend (SS, "No hand coordinate system!\n");
00650       
00651       SS = SUMA_StringAppend (SS, stmp);
00652       sprintf (stmp,"Origin: %f %f %f\n", \
00653          VP->xorg, VP->yorg, VP->zorg);
00654       SS = SUMA_StringAppend (SS, stmp);
00655       sprintf (stmp,"Delta: %f %f %f\n", \
00656          VP->dx, VP->dy, VP->dz);
00657       SS = SUMA_StringAppend (SS, stmp);
00658       sprintf (stmp,"N: %d %d %d\n",\
00659          VP->nx, VP->ny, VP->nz);
00660       SS = SUMA_StringAppend (SS, stmp);
00661 
00662       if (VP->ROTATE_MATVEC != NULL) {
00663          sprintf (stmp,"VP->ROTATE_MATVEC = \n\tMrot\tDelta\n");
00664          SS = SUMA_StringAppend (SS, stmp);
00665          sprintf (stmp,"|%f\t%f\t%f|\t|%f|\n", \
00666          VP->ROTATE_MATVEC[0], VP->ROTATE_MATVEC[1], VP->ROTATE_MATVEC[2], VP->ROTATE_MATVEC[3]); 
00667          SS = SUMA_StringAppend (SS, stmp);
00668          sprintf (stmp,"|%f\t%f\t%f|\t|%f|\n", \
00669          VP->ROTATE_MATVEC[4], VP->ROTATE_MATVEC[5], VP->ROTATE_MATVEC[6], VP->ROTATE_MATVEC[7]);
00670          SS = SUMA_StringAppend (SS, stmp);
00671          sprintf (stmp,"|%f\t%f\t%f|\t|%f|\n", \
00672          VP->ROTATE_MATVEC[8], VP->ROTATE_MATVEC[9], VP->ROTATE_MATVEC[10], VP->ROTATE_MATVEC[11]);
00673          SS = SUMA_StringAppend (SS, stmp);
00674       } else {
00675          sprintf (stmp,"VP->ROTATE_MATVEC = NULL\n");
00676          SS = SUMA_StringAppend (SS, stmp);
00677       }      
00678       if (VP->ROTATE_CENTER_OLD != NULL) {
00679          sprintf (stmp,"VP->ROTATE_CENTER_OLD = %f, %f, %f\n", \
00680            VP->ROTATE_CENTER_OLD[0], VP->ROTATE_CENTER_OLD[1], VP->ROTATE_CENTER_OLD[2]); 
00681          SS = SUMA_StringAppend (SS, stmp);
00682       }else {
00683          sprintf (stmp,"VP->ROTATE_CENTER_OLD = NULL\n");
00684          SS = SUMA_StringAppend (SS, stmp);
00685       }
00686       if (VP->ROTATE_CENTER_BASE != NULL) {
00687          sprintf (stmp,"VP->ROTATE_CENTER_BASE = %f, %f, %f\n", \
00688             VP->ROTATE_CENTER_BASE[0], VP->ROTATE_CENTER_BASE[1], VP->ROTATE_CENTER_BASE[2]); 
00689          SS = SUMA_StringAppend (SS, stmp);
00690       } else {
00691          sprintf (stmp,"VP->ROTATE_CENTER_BASE = NULL\n");
00692          SS = SUMA_StringAppend (SS, stmp);
00693       }      
00694       if (VP->TAGALIGN_MATVEC != NULL) {
00695          sprintf (stmp,"VP->TAGALIGN_MATVEC = \n\tMrot\tDelta\n");
00696          SS = SUMA_StringAppend (SS, stmp);
00697          sprintf (stmp,"|%f\t%f\t%f|\t|%f|\n", \
00698          VP->TAGALIGN_MATVEC[0], VP->TAGALIGN_MATVEC[1], VP->TAGALIGN_MATVEC[2], VP->TAGALIGN_MATVEC[3]); 
00699          SS = SUMA_StringAppend (SS, stmp);
00700          sprintf (stmp,"|%f\t%f\t%f|\t|%f|\n", \
00701          VP->TAGALIGN_MATVEC[4], VP->TAGALIGN_MATVEC[5], VP->TAGALIGN_MATVEC[6], VP->TAGALIGN_MATVEC[7]);
00702          SS = SUMA_StringAppend (SS, stmp);
00703          sprintf (stmp,"|%f\t%f\t%f|\t|%f|\n", \
00704          VP->TAGALIGN_MATVEC[8], VP->TAGALIGN_MATVEC[9], VP->TAGALIGN_MATVEC[10], VP->TAGALIGN_MATVEC[11]);
00705          SS = SUMA_StringAppend (SS, stmp);
00706       } else {
00707          sprintf (stmp,"VP->TAGALIGN_MATVEC = NULL\n");
00708          SS = SUMA_StringAppend (SS, stmp);
00709       }      
00710       
00711       if (VP->VOLREG_MATVEC != NULL) {
00712          sprintf (stmp,"VP->VOLREG_MATVEC = \n\tMrot\tDelta\n");
00713          SS = SUMA_StringAppend (SS, stmp);
00714          sprintf (stmp,"|%f\t%f\t%f|\t|%f|\n", \
00715          VP->VOLREG_MATVEC[0], VP->VOLREG_MATVEC[1], VP->VOLREG_MATVEC[2], VP->VOLREG_MATVEC[3]); 
00716          SS = SUMA_StringAppend (SS, stmp);
00717          sprintf (stmp,"|%f\t%f\t%f|\t|%f|\n", \
00718          VP->VOLREG_MATVEC[4], VP->VOLREG_MATVEC[5], VP->VOLREG_MATVEC[6], VP->VOLREG_MATVEC[7]);
00719          SS = SUMA_StringAppend (SS, stmp);
00720          sprintf (stmp,"|%f\t%f\t%f|\t|%f|\n", \
00721          VP->VOLREG_MATVEC[8], VP->VOLREG_MATVEC[9], VP->VOLREG_MATVEC[10], VP->VOLREG_MATVEC[11]);
00722          SS = SUMA_StringAppend (SS, stmp);
00723       } else {
00724          sprintf (stmp,"VP->VOLREG_MATVEC = NULL\n");
00725          SS = SUMA_StringAppend (SS, stmp);
00726       }
00727 
00728       if (VP->VOLREG_CENTER_OLD != NULL) {
00729          sprintf (stmp,"VP->VOLREG_CENTER_OLD = %f, %f, %f\n", \
00730            VP->VOLREG_CENTER_OLD[0], VP->VOLREG_CENTER_OLD[1], VP->VOLREG_CENTER_OLD[2]); 
00731          SS = SUMA_StringAppend (SS, stmp);
00732       }else {
00733          sprintf (stmp,"VP->VOLREG_CENTER_OLD = NULL\n");
00734          SS = SUMA_StringAppend (SS, stmp);
00735       }
00736 
00737       if (VP->VOLREG_CENTER_BASE != NULL) {
00738          sprintf (stmp,"VP->VOLREG_CENTER_BASE = %f, %f, %f\n", \
00739             VP->VOLREG_CENTER_BASE[0], VP->VOLREG_CENTER_BASE[1], VP->VOLREG_CENTER_BASE[2]); 
00740          SS = SUMA_StringAppend (SS, stmp);
00741       } else {
00742          sprintf (stmp,"VP->VOLREG_CENTER_BASE = NULL\n");
00743          SS = SUMA_StringAppend (SS, stmp);
00744       }
00745    }else{
00746       sprintf (stmp, "NULL Volume Parent Pointer.\n");
00747       SS = SUMA_StringAppend (SS, stmp);
00748    }
00749    
00750    
00751    SS = SUMA_StringAppend (SS, NULL);
00752    
00753    s = SS->s;
00754    SUMA_free(SS); 
00755    
00756    SUMA_RETURN (s);
00757 }
00758 
00759 
00760 
00761 
00762 void SUMA_Show_VolPar(SUMA_VOLPAR *VP, FILE *Out)
00763 {
00764    static char FuncName[]={"SUMA_Show_VolPar"};
00765    char *s;
00766    
00767    SUMA_ENTRY;
00768 
00769    if (Out == NULL) Out = SUMA_STDOUT;
00770    
00771    s =  SUMA_VolPar_Info(VP);
00772    
00773    if (s) {
00774       fprintf (Out, "%s", s);
00775       SUMA_free(s);
00776    }else {
00777       fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_VolPar_Info.\n", FuncName);
00778    }   
00779    
00780    SUMA_RETURNe;
00781       
00782 }
00783 
00784 
00785 
00786 
00787 
00788 
00789 
00790 
00791 
00792 
00793 
00794 SUMA_Boolean SUMA_Align_to_VolPar (SUMA_SurfaceObject *SO, void * S_Struct)
00795 {
00796    static char FuncName[]={"SUMA_Align_to_VolPar"};
00797    char  orcode[3];
00798    float xx, yy, zz;
00799    THD_coorder * cord_surf, *cord_RAI;
00800    int i, ND, id;
00801    SUMA_SureFit_struct *SF;
00802    SUMA_FreeSurfer_struct *FS;
00803    
00804    SUMA_ENTRY;
00805 
00806    
00807    cord_surf = (THD_coorder *)SUMA_malloc(sizeof(THD_coorder));
00808    cord_RAI = (THD_coorder *)SUMA_malloc(sizeof(THD_coorder));
00809    if (cord_surf == NULL || cord_RAI == NULL) {
00810       fprintf(SUMA_STDERR,"Error %s: failed to allocate for cord\n", FuncName);
00811       SUMA_RETURN (NOPE);
00812    }
00813    
00814    
00815    THD_coorder_fill( NULL, cord_RAI);
00816    ND = SO->NodeDim;
00817    switch (SO->FileType) {
00818       case SUMA_INVENTOR_GENERIC:
00819       case SUMA_OPENDX_MESH:
00820       case SUMA_PLY:
00821       case SUMA_VEC:
00822          
00823          break;
00824       case SUMA_FREE_SURFER:
00825       case SUMA_FREE_SURFER_PATCH:
00826          
00827 
00828          sprintf(orcode,"LPI");
00829          THD_coorder_fill(orcode , cord_surf); 
00830          
00831          for (i=0; i < SO->N_Node; ++i) {
00832             id = i * ND;
00833             THD_coorder_to_dicom (cord_surf, &(SO->NodeList[id]), &(SO->NodeList[id+1]), &(SO->NodeList[id+2])); 
00834          }
00835          break;
00836       case SUMA_SUREFIT:
00837          
00838          SF = (SUMA_SureFit_struct *)S_Struct;
00839          {   THD_fvec3 fv, iv;
00840             float D[3];
00841             
00842             for (i=0; i < 3; ++i) D[i] = SF->AC_WholeVolume[i] - SF->AC[i];
00843             
00844             for (i=0; i < SO->N_Node; ++i) {
00845                id = i * ND;
00846                
00847                iv.xyz[0] = SO->NodeList[id] + D[0];
00848                iv.xyz[1] = SO->NodeList[id+1] + D[1];
00849                iv.xyz[2] = SO->NodeList[id+2] + D[2];
00850                fv = SUMA_THD_3dfind_to_3dmm( SO, iv );
00851                
00852                
00853                iv = SUMA_THD_3dmm_to_dicomm( SO->VolPar->xxorient, SO->VolPar->yyorient, SO->VolPar->zzorient,  fv );
00854                SO->NodeList[id] = iv.xyz[0];
00855                SO->NodeList[id+1] = iv.xyz[1];
00856                SO->NodeList[id+2] = iv.xyz[2];
00857             }
00858          }
00859          break;
00860       case SUMA_BRAIN_VOYAGER:
00861          
00862 
00863 
00864 
00865 
00866 
00867 
00868          sprintf(orcode,"ASR");
00869          THD_coorder_fill(orcode , cord_surf); 
00870          
00871          for (i=0; i < SO->N_Node; ++i) {
00872             id = i * ND;
00873             THD_coorder_to_dicom (cord_surf, &(SO->NodeList[id]), &(SO->NodeList[id+1]), &(SO->NodeList[id+2])); 
00874          }
00875          break;
00876       default:
00877          fprintf(SUMA_STDERR,"Warning %s: Unknown SO->FileType. Assuming coordinates are in DICOM already.\n", FuncName);
00878          break;
00879    }
00880    
00881    if (!SUMA_Apply_VolReg_Trans (SO)) {
00882       fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_Apply_VolReg_Trans.\n", FuncName);
00883       SUMA_RETURN (NOPE);
00884    }
00885 
00886    SUMA_RETURN (YUP);
00887 }
00888 
00889 
00890 
00891 
00892 
00893 
00894 
00895 
00896 
00897 SUMA_Boolean SUMA_Apply_VolReg_Trans (SUMA_SurfaceObject *SO)
00898 {
00899    static char FuncName[]={"SUMA_Apply_VolReg_Trans"};
00900    int i, ND, id;
00901    SUMA_Boolean UseVolreg, UseTagAlign, UseRotate, Bad=YUP;
00902    
00903    SUMA_ENTRY;
00904 
00905    if (SUMAg_CF->IgnoreVolreg) {
00906       SUMA_SL_Note("Ignoring any Volreg or TagAlign transforms present in Surface Volume.\n");
00907       SO->VOLREG_APPLIED = NOPE;
00908       SUMA_RETURN (YUP);
00909    }
00910    
00911    if (SO->VOLREG_APPLIED || SO->TAGALIGN_APPLIED || SO->ROTATE_APPLIED) {
00912       fprintf (SUMA_STDERR,"Error %s: Volreg (or Tagalign or rotate) already applied. Nothing done.\n", FuncName);
00913       SUMA_RETURN (NOPE);
00914    }
00915 
00916    ND = SO->NodeDim;
00917    
00918    
00919    UseVolreg = NOPE;
00920    UseTagAlign = NOPE;
00921    UseRotate = NOPE;
00922    
00923    if (SO->VolPar->VOLREG_MATVEC != NULL || SO->VolPar->VOLREG_CENTER_OLD != NULL || SO->VolPar->VOLREG_CENTER_BASE != NULL) {
00924       Bad = NOPE;
00925       if (SO->VolPar->VOLREG_MATVEC == NULL) {
00926          fprintf(SUMA_STDERR,"Error %s: SO->VolPar->VOLREG_MATVEC = NULL. Cannot perform alignment.\n", FuncName);
00927          Bad = YUP;
00928       }
00929       if (SO->VolPar->VOLREG_CENTER_OLD == NULL) {
00930          fprintf(SUMA_STDERR,"Error %s: SO->VolPar->VOLREG_CENTER_OLD = NULL. Cannot perform alignment.\n", FuncName);
00931          Bad = YUP;
00932       }
00933       if (SO->VolPar->VOLREG_CENTER_BASE == NULL) {
00934          fprintf(SUMA_STDERR,"Error %s: SO->VolPar->VOLREG_CENTER_BASE = NULL. Cannot perform alignment.\n", FuncName);
00935          Bad = YUP;
00936       }
00937       if (!Bad) UseVolreg = YUP;
00938    }
00939    
00940    
00941    if (SO->VolPar->TAGALIGN_MATVEC) UseTagAlign = YUP;
00942    if (SO->VolPar->ROTATE_MATVEC || SO->VolPar->ROTATE_CENTER_OLD || SO->VolPar->ROTATE_CENTER_BASE) {
00943       Bad = NOPE;
00944       if (SO->VolPar->ROTATE_MATVEC == NULL) {
00945          fprintf(SUMA_STDERR,"Error %s: SO->VolPar->ROTATE_MATVEC = NULL. Cannot perform alignment.\n", FuncName);
00946          Bad = YUP;
00947       }
00948       if (SO->VolPar->ROTATE_CENTER_OLD == NULL) {
00949          fprintf(SUMA_STDERR,"Error %s: SO->VolPar->ROTATE_CENTER_OLD = NULL. Cannot perform alignment.\n", FuncName);
00950          Bad = YUP;
00951       }
00952       if (SO->VolPar->ROTATE_CENTER_BASE == NULL) {
00953          fprintf(SUMA_STDERR,"Error %s: SO->VolPar->ROTATE_CENTER_BASE = NULL. Cannot perform alignment.\n", FuncName);
00954          Bad = YUP;
00955       }
00956       if (!Bad) UseRotate = YUP;
00957    }
00958    
00959    if (UseTagAlign && UseVolreg) {
00960       SUMA_SL_Note("Found both Volreg and TagAlign fields.\n"
00961                    "Using Volreg fields for alignment.");
00962       UseTagAlign = NOPE;
00963    }
00964    if (UseRotate && UseVolreg) {
00965       SUMA_SL_Note("Found both Volreg and Rotate fields.\n"
00966                    "Using Volreg fields for alignment.");
00967       UseRotate = NOPE;
00968    }
00969    if (UseRotate && UseTagAlign) {
00970       SUMA_SL_Note("Found both Rotate and TagAlign fields.\n"
00971                    "Using Tagalign fields for alignment.");
00972       UseRotate = NOPE;
00973    }
00974    
00975    if (UseTagAlign) {
00976       float Mrot[3][3], Delta[3], x, y, z, NetShift[3];
00977       
00978       
00979       Mrot[0][0] = SO->VolPar->TAGALIGN_MATVEC[0];
00980       Mrot[0][1] = SO->VolPar->TAGALIGN_MATVEC[1];
00981       Mrot[0][2] = SO->VolPar->TAGALIGN_MATVEC[2];
00982       Delta[0]   = SO->VolPar->TAGALIGN_MATVEC[3];
00983       Mrot[1][0] = SO->VolPar->TAGALIGN_MATVEC[4];
00984       Mrot[1][1] = SO->VolPar->TAGALIGN_MATVEC[5];
00985       Mrot[1][2] = SO->VolPar->TAGALIGN_MATVEC[6];
00986       Delta[1]   = SO->VolPar->TAGALIGN_MATVEC[7];   
00987       Mrot[2][0] = SO->VolPar->TAGALIGN_MATVEC[8];
00988       Mrot[2][1] = SO->VolPar->TAGALIGN_MATVEC[9];
00989       Mrot[2][2] = SO->VolPar->TAGALIGN_MATVEC[10];
00990       Delta[2]   = SO->VolPar->TAGALIGN_MATVEC[11];
00991       
00992       NetShift[0] = Delta[0];
00993       NetShift[1] = Delta[1];
00994       NetShift[2] = Delta[2];
00995       
00996       
00997 
00998 
00999 
01000 
01001 
01002       
01003       for (i=0; i < SO->N_Node; ++i) {
01004          id = ND * i;
01005           
01006          x = SO->NodeList[id] ;
01007          y = SO->NodeList[id+1] ;
01008          z = SO->NodeList[id+2] ;
01009          
01010          
01011          SO->NodeList[id] = Mrot[0][0] * x + Mrot[0][1] * y + Mrot[0][2] * z;
01012          SO->NodeList[id+1] = Mrot[1][0] * x + Mrot[1][1] * y + Mrot[1][2] * z;
01013          SO->NodeList[id+2] = Mrot[2][0] * x + Mrot[2][1] * y + Mrot[2][2] * z;
01014          
01015          
01016          SO->NodeList[id] += NetShift[0];
01017          SO->NodeList[id+1] += NetShift[1];
01018          SO->NodeList[id+2] += NetShift[2];
01019       }
01020       SO->TAGALIGN_APPLIED = YUP;   
01021    } else
01022       SO->TAGALIGN_APPLIED = NOPE;
01023          
01024    if (UseVolreg) {
01025       float Mrot[3][3], Delta[3], x, y, z, NetShift[3];
01026       
01027       
01028       Mrot[0][0] = SO->VolPar->VOLREG_MATVEC[0];
01029       Mrot[0][1] = SO->VolPar->VOLREG_MATVEC[1];
01030       Mrot[0][2] = SO->VolPar->VOLREG_MATVEC[2];
01031       Delta[0]   = SO->VolPar->VOLREG_MATVEC[3];
01032       Mrot[1][0] = SO->VolPar->VOLREG_MATVEC[4];
01033       Mrot[1][1] = SO->VolPar->VOLREG_MATVEC[5];
01034       Mrot[1][2] = SO->VolPar->VOLREG_MATVEC[6];
01035       Delta[1]   = SO->VolPar->VOLREG_MATVEC[7];   
01036       Mrot[2][0] = SO->VolPar->VOLREG_MATVEC[8];
01037       Mrot[2][1] = SO->VolPar->VOLREG_MATVEC[9];
01038       Mrot[2][2] = SO->VolPar->VOLREG_MATVEC[10];
01039       Delta[2]   = SO->VolPar->VOLREG_MATVEC[11];
01040       
01041       NetShift[0] = SO->VolPar->VOLREG_CENTER_BASE[0] + Delta[0];
01042       NetShift[1] = SO->VolPar->VOLREG_CENTER_BASE[1] + Delta[1];
01043       NetShift[2] = SO->VolPar->VOLREG_CENTER_BASE[2] + Delta[2];
01044       
01045       
01046 
01047 
01048 
01049 
01050 
01051 
01052 
01053       
01054       for (i=0; i < SO->N_Node; ++i) {
01055          id = ND * i;
01056           
01057          x = SO->NodeList[id  ] - SO->VolPar->VOLREG_CENTER_OLD[0];
01058          y = SO->NodeList[id+1] - SO->VolPar->VOLREG_CENTER_OLD[1];
01059          z = SO->NodeList[id+2] - SO->VolPar->VOLREG_CENTER_OLD[2];
01060          
01061          
01062          SO->NodeList[id  ] = Mrot[0][0] * x + Mrot[0][1] * y + Mrot[0][2] * z;
01063          SO->NodeList[id+1] = Mrot[1][0] * x + Mrot[1][1] * y + Mrot[1][2] * z;
01064          SO->NodeList[id+2] = Mrot[2][0] * x + Mrot[2][1] * y + Mrot[2][2] * z;
01065          
01066          
01067          SO->NodeList[id  ] += NetShift[0];
01068          SO->NodeList[id+1] += NetShift[1];
01069          SO->NodeList[id+2] += NetShift[2];
01070       }
01071       SO->VOLREG_APPLIED = YUP;   
01072    } else
01073       SO->VOLREG_APPLIED = NOPE;
01074    
01075    if (UseRotate) {
01076       float Mrot[3][3], Delta[3], x, y, z, NetShift[3];
01077       
01078       
01079       Mrot[0][0] = SO->VolPar->ROTATE_MATVEC[0];
01080       Mrot[0][1] = SO->VolPar->ROTATE_MATVEC[1];
01081       Mrot[0][2] = SO->VolPar->ROTATE_MATVEC[2];
01082       Delta[0]   = SO->VolPar->ROTATE_MATVEC[3];
01083       Mrot[1][0] = SO->VolPar->ROTATE_MATVEC[4];
01084       Mrot[1][1] = SO->VolPar->ROTATE_MATVEC[5];
01085       Mrot[1][2] = SO->VolPar->ROTATE_MATVEC[6];
01086       Delta[1]   = SO->VolPar->ROTATE_MATVEC[7];   
01087       Mrot[2][0] = SO->VolPar->ROTATE_MATVEC[8];
01088       Mrot[2][1] = SO->VolPar->ROTATE_MATVEC[9];
01089       Mrot[2][2] = SO->VolPar->ROTATE_MATVEC[10];
01090       Delta[2]   = SO->VolPar->ROTATE_MATVEC[11];
01091       
01092       NetShift[0] = SO->VolPar->ROTATE_CENTER_BASE[0] + Delta[0];
01093       NetShift[1] = SO->VolPar->ROTATE_CENTER_BASE[0] + Delta[1];
01094       NetShift[2] = SO->VolPar->ROTATE_CENTER_BASE[0] + Delta[2];
01095       
01096       
01097 
01098 
01099 
01100 
01101 
01102 
01103 
01104       
01105       for (i=0; i < SO->N_Node; ++i) {
01106          id = ND * i;
01107           
01108          x = SO->NodeList[id  ] - SO->VolPar->ROTATE_CENTER_OLD[0];
01109          y = SO->NodeList[id+1] - SO->VolPar->ROTATE_CENTER_OLD[1];
01110          z = SO->NodeList[id+2] - SO->VolPar->ROTATE_CENTER_OLD[1];
01111          
01112          
01113          SO->NodeList[id  ] = Mrot[0][0] * x + Mrot[0][1] * y + Mrot[0][2] * z;
01114          SO->NodeList[id+1] = Mrot[1][0] * x + Mrot[1][1] * y + Mrot[1][2] * z;
01115          SO->NodeList[id+2] = Mrot[2][0] * x + Mrot[2][1] * y + Mrot[2][2] * z;
01116          
01117          
01118          SO->NodeList[id  ] += NetShift[0];
01119          SO->NodeList[id+1] += NetShift[1];
01120          SO->NodeList[id+2] += NetShift[2];
01121       }
01122       SO->ROTATE_APPLIED = YUP;   
01123    } else
01124       SO->ROTATE_APPLIED = NOPE;
01125    
01126    SUMA_RETURN (YUP);
01127 }
01128 
01129 
01130 
01131 
01132 
01133 
01134 
01135 
01136 
01137 
01138 
01139 
01140 
01141 
01142 
01143 
01144 
01145 
01146 
01147 
01148 
01149 
01150 
01151 
01152 
01153 
01154 
01155 
01156 THD_fvec3 SUMA_THD_3dfind_to_3dmm( SUMA_SurfaceObject *SO, 
01157                               THD_fvec3 iv )
01158 {
01159    static char FuncName[]={"SUMA_THD_3dfind_to_3dmm"};
01160    THD_fvec3     fv ;
01161 
01162    SUMA_ENTRY;
01163 
01164    fv.xyz[0] = SO->VolPar->xorg + iv.xyz[0] * SO->VolPar->dx ;
01165    fv.xyz[1] = SO->VolPar->yorg + iv.xyz[1] * SO->VolPar->dy ;
01166    fv.xyz[2] = SO->VolPar->zorg + iv.xyz[2] * SO->VolPar->dz ;
01167    SUMA_RETURN(fv) ;
01168 }
01169 
01170 
01171 
01172 THD_fvec3 SUMA_THD_3dind_to_3dmm( SUMA_SurfaceObject *SO,
01173                                    THD_ivec3 iv )
01174 {
01175    static char FuncName[]={"SUMA_THD_3dind_to_3dmm"};
01176    THD_fvec3     fv ;
01177 
01178    SUMA_ENTRY;
01179 
01180    fv.xyz[0] = SO->VolPar->xorg + iv.ijk[0] * SO->VolPar->dx ;
01181    fv.xyz[1] = SO->VolPar->yorg + iv.ijk[1] * SO->VolPar->dy ;
01182    fv.xyz[2] = SO->VolPar->zorg + iv.ijk[2] * SO->VolPar->dz ;
01183    SUMA_RETURN(fv) ;
01184 }
01185 
01186 
01187 
01188 THD_fvec3 SUMA_THD_3dmm_to_3dfind( SUMA_SurfaceObject *SO ,
01189                               THD_fvec3 fv )
01190 {
01191    static char FuncName[]={"SUMA_THD_3dmm_to_3dfind"};
01192    THD_fvec3     iv ;
01193 
01194    SUMA_ENTRY;
01195 
01196 
01197    iv.xyz[0] = (fv.xyz[0] - SO->VolPar->xorg) / SO->VolPar->dx ;
01198    iv.xyz[1] = (fv.xyz[1] - SO->VolPar->yorg) / SO->VolPar->dy ;
01199    iv.xyz[2] = (fv.xyz[2] - SO->VolPar->zorg) / SO->VolPar->dz ;
01200 
01201         if( iv.xyz[0] < 0            ) iv.xyz[0] = 0 ;
01202    else if( iv.xyz[0] > SO->VolPar->nx-1 ) iv.xyz[0] = SO->VolPar->nx-1 ;
01203 
01204         if( iv.xyz[1] <  0           ) iv.xyz[1] = 0 ;
01205    else if( iv.xyz[1] > SO->VolPar->ny-1 ) iv.xyz[1] = SO->VolPar->ny-1 ;
01206 
01207         if( iv.xyz[2] < 0            ) iv.xyz[2] = 0 ;
01208    else if( iv.xyz[2] > SO->VolPar->nz-1 ) iv.xyz[2] = SO->VolPar->nz-1 ;
01209 
01210    SUMA_RETURN(iv) ;
01211 }
01212 
01213 
01214 
01215 THD_ivec3 SUMA_THD_3dmm_to_3dind( SUMA_SurfaceObject *SO  ,
01216                              THD_fvec3 fv )
01217 {
01218    static char FuncName[]={"SUMA_THD_3dmm_to_3dind"};
01219    THD_ivec3     iv ;
01220 
01221    SUMA_ENTRY;
01222 
01223    iv.ijk[0] = (fv.xyz[0] - SO->VolPar->xorg) / SO->VolPar->dx + 0.499 ;
01224    iv.ijk[1] = (fv.xyz[1] - SO->VolPar->yorg) / SO->VolPar->dy + 0.499 ;
01225    iv.ijk[2] = (fv.xyz[2] - SO->VolPar->zorg) / SO->VolPar->dz + 0.499 ;
01226 
01227         if( iv.ijk[0] < 0            ) iv.ijk[0] = 0 ;
01228    else if( iv.ijk[0] > SO->VolPar->nx-1 ) iv.ijk[0] = SO->VolPar->nx-1 ;
01229 
01230         if( iv.ijk[1] < 0            ) iv.ijk[1] = 0 ;
01231    else if( iv.ijk[1] > SO->VolPar->ny-1 ) iv.ijk[1] = SO->VolPar->ny-1 ;
01232 
01233         if( iv.ijk[2] < 0            ) iv.ijk[2] = 0 ;
01234    else if( iv.ijk[2] > SO->VolPar->nz-1 ) iv.ijk[2] = SO->VolPar->nz-1 ;
01235 
01236    SUMA_RETURN(iv) ;
01237 }
01238 
01239 
01240 
01241 
01242 void SUMA_VolDims(THD_3dim_dataset *dset, int *nRL, int *nAP, int *nIS)
01243 {
01244    static char FuncName[]={"SUMA_VolDims"};
01245    
01246    SUMA_ENTRY;
01247    
01248    *nRL = *nAP = *nIS = -1;
01249    
01250    if (!dset) {
01251       SUMA_SL_Err("NULL dset");
01252       SUMA_RETURNe;
01253    }
01254    
01255    switch( dset->daxes->xxorient ){
01256       case ORI_R2L_TYPE:
01257       case ORI_L2R_TYPE: *nRL = DSET_NX(dset) ; break ;
01258       case ORI_P2A_TYPE:
01259       case ORI_A2P_TYPE: *nAP = DSET_NX(dset) ; break ;
01260       case ORI_I2S_TYPE:
01261       case ORI_S2I_TYPE: *nIS = DSET_NX(dset) ; break ;
01262    }
01263 
01264    switch( dset->daxes->yyorient ){
01265       case ORI_R2L_TYPE:
01266       case ORI_L2R_TYPE: *nRL = DSET_NY(dset) ; break ;
01267       case ORI_P2A_TYPE:
01268       case ORI_A2P_TYPE: *nAP = DSET_NY(dset) ; break ;
01269       case ORI_I2S_TYPE:
01270       case ORI_S2I_TYPE: *nIS = DSET_NY(dset) ; break ;
01271    }
01272 
01273    switch( dset->daxes->zzorient ){
01274       case ORI_R2L_TYPE:
01275       case ORI_L2R_TYPE: *nRL = DSET_NZ(dset) ; break ;
01276       case ORI_P2A_TYPE:
01277       case ORI_A2P_TYPE: *nAP = DSET_NZ(dset) ; break ;
01278       case ORI_I2S_TYPE:
01279       case ORI_S2I_TYPE: *nIS = DSET_NZ(dset) ; break ;
01280    }
01281    
01282    SUMA_RETURNe;
01283 }
01284 
01285 
01286 
01287 
01288 
01289 
01290 
01291 
01292 THD_fvec3 SUMA_THD_3dmm_to_dicomm( int xxorient, int yyorient, int zzorient, 
01293                               THD_fvec3 imv )
01294 {
01295    static char FuncName[]={"SUMA_THD_3dmm_to_dicomm"};   
01296    THD_fvec3 dicv ;
01297    float xim,yim,zim , xdic = 0.0, ydic = 0.0, zdic = 0.0 ;
01298 
01299    SUMA_ENTRY;
01300 
01301    xim = imv.xyz[0] ; yim = imv.xyz[1] ; zim = imv.xyz[2] ;
01302 
01303    switch( xxorient ){
01304       case ORI_R2L_TYPE:
01305       case ORI_L2R_TYPE: xdic = xim ; break ;
01306       case ORI_P2A_TYPE:
01307       case ORI_A2P_TYPE: ydic = xim ; break ;
01308       case ORI_I2S_TYPE:
01309       case ORI_S2I_TYPE: zdic = xim ; break ;
01310 
01311       default: 
01312          fprintf(SUMA_STDERR, "SUMA_THD_3dmm_to_dicomm: illegal xxorient code.\n Exiting.") ;
01313          exit (1);
01314    }
01315 
01316    switch( yyorient ){
01317       case ORI_R2L_TYPE:
01318       case ORI_L2R_TYPE: xdic = yim ; break ;
01319       case ORI_P2A_TYPE:
01320       case ORI_A2P_TYPE: ydic = yim ; break ;
01321       case ORI_I2S_TYPE:
01322       case ORI_S2I_TYPE: zdic = yim ; break ;
01323 
01324       default: 
01325          fprintf(SUMA_STDERR, "SUMA_THD_3dmm_to_dicomm: illegal xxorient code.\n Exiting.") ;
01326          exit (1);
01327    }
01328 
01329    switch( zzorient ){
01330       case ORI_R2L_TYPE:
01331       case ORI_L2R_TYPE: xdic = zim ; break ;
01332       case ORI_P2A_TYPE:
01333       case ORI_A2P_TYPE: ydic = zim ; break ;
01334       case ORI_I2S_TYPE:
01335       case ORI_S2I_TYPE: zdic = zim ; break ;
01336 
01337       default: 
01338          fprintf(SUMA_STDERR, "SUMA_THD_3dmm_to_dicomm: illegal xxorient code.\n Exiting.") ;
01339          exit (1);
01340    }
01341 
01342    dicv.xyz[0] = xdic ; dicv.xyz[1] = ydic ; dicv.xyz[2] = zdic ;
01343    SUMA_RETURN(dicv) ;
01344 }
01345 
01346 
01347 
01348 
01349 
01350 THD_fvec3 SUMA_THD_dicomm_to_3dmm( SUMA_SurfaceObject *SO ,
01351                               THD_fvec3 dicv )
01352 {
01353    static char FuncName[]={"SUMA_THD_dicomm_to_3dmm"};
01354    THD_fvec3 imv ;
01355    float xim,yim,zim , xdic,ydic,zdic ;
01356 
01357    SUMA_ENTRY;
01358 
01359    xdic = dicv.xyz[0] ; ydic = dicv.xyz[1] ; zdic = dicv.xyz[2] ;
01360 
01361    switch( SO->VolPar->xxorient ){
01362       case ORI_R2L_TYPE:
01363       case ORI_L2R_TYPE: xim = xdic ; break ;
01364       case ORI_P2A_TYPE:
01365       case ORI_A2P_TYPE: xim = ydic ; break ;
01366       case ORI_I2S_TYPE:
01367       case ORI_S2I_TYPE: xim = zdic ; break ;
01368 
01369       default: 
01370          fprintf(SUMA_STDERR, "SUMA_THD_dicomm_to_3dmm: illegal xxorient code.\n Exiting.") ;
01371          exit (1);
01372    }
01373 
01374    switch( SO->VolPar->yyorient ){
01375       case ORI_R2L_TYPE:
01376       case ORI_L2R_TYPE: yim = xdic ; break ;
01377       case ORI_P2A_TYPE:
01378       case ORI_A2P_TYPE: yim = ydic ; break ;
01379       case ORI_I2S_TYPE:
01380       case ORI_S2I_TYPE: yim = zdic ; break ;
01381 
01382       default: 
01383          fprintf(SUMA_STDERR, "SUMA_THD_dicomm_to_3dmm: illegal xxorient code.\n Exiting.") ;
01384          exit (1);
01385    }
01386 
01387    switch( SO->VolPar->zzorient ){
01388       case ORI_R2L_TYPE:
01389       case ORI_L2R_TYPE: zim = xdic ; break ;
01390       case ORI_P2A_TYPE:
01391       case ORI_A2P_TYPE: zim = ydic ; break ;
01392       case ORI_I2S_TYPE:
01393       case ORI_S2I_TYPE: zim = zdic ; break ;
01394 
01395       default: 
01396          fprintf(SUMA_STDERR, "SUMA_THD_dicomm_to_3dmm: illegal xxorient code.\n Exiting.") ;
01397          exit (1);
01398    }
01399 
01400    imv.xyz[0] = xim ; imv.xyz[1] = yim ; imv.xyz[2] = zim ;
01401    SUMA_RETURN(imv) ;
01402 }
01403 
01404 
01405 
01406 
01407 
01408 void SUMA_orcode_to_orstring (int xxorient,int  yyorient,int zzorient, char *orstr)
01409 {
01410    static char FuncName[]={"SUMA_orcode_to_orstring"};
01411    
01412    SUMA_ENTRY;
01413    
01414    if (!orstr) { SUMA_SL_Err("NULL string"); SUMA_RETURNe; }
01415    
01416    orstr[0]='\0';
01417    switch( xxorient ){
01418       case ORI_R2L_TYPE: orstr[0] = 'R'; orstr[3] = 'L'; break ;
01419       case ORI_L2R_TYPE: orstr[0] = 'L'; orstr[3] = 'R'; break ;
01420       case ORI_P2A_TYPE: orstr[0] = 'P'; orstr[3] = 'A'; break ;
01421       case ORI_A2P_TYPE: orstr[0] = 'A'; orstr[3] = 'P'; break ;
01422       case ORI_I2S_TYPE: orstr[0] = 'I'; orstr[3] = 'S'; break ;
01423       case ORI_S2I_TYPE: orstr[0] = 'S'; orstr[3] = 'I'; break ;
01424 
01425       default: 
01426          fprintf(SUMA_STDERR, "SUMA_THD_dicomm_to_3dmm: illegal xxorient code.\n") ;
01427          SUMA_RETURNe;
01428    }
01429 
01430    switch( yyorient ){
01431       case ORI_R2L_TYPE: orstr[1] = 'R'; orstr[4] = 'L'; break ;
01432       case ORI_L2R_TYPE: orstr[1] = 'L'; orstr[4] = 'R'; break ;
01433       case ORI_P2A_TYPE: orstr[1] = 'P'; orstr[4] = 'A'; break ;
01434       case ORI_A2P_TYPE: orstr[1] = 'A'; orstr[4] = 'P'; break ;
01435       case ORI_I2S_TYPE: orstr[1] = 'I'; orstr[4] = 'S'; break ;
01436       case ORI_S2I_TYPE: orstr[1] = 'S'; orstr[4] = 'I'; break ;
01437 
01438       default: 
01439          fprintf(SUMA_STDERR, "SUMA_THD_dicomm_to_3dmm: illegal yyorient code.\n ") ;
01440          SUMA_RETURNe;
01441    }
01442 
01443    switch( zzorient ){
01444       case ORI_R2L_TYPE: orstr[2] = 'R'; orstr[5] = 'L'; break ;
01445       case ORI_L2R_TYPE: orstr[2] = 'L'; orstr[5] = 'R'; break ;
01446       case ORI_P2A_TYPE: orstr[2] = 'P'; orstr[5] = 'A'; break ;
01447       case ORI_A2P_TYPE: orstr[2] = 'A'; orstr[5] = 'P'; break ;
01448       case ORI_I2S_TYPE: orstr[2] = 'I'; orstr[5] = 'S'; break ;
01449       case ORI_S2I_TYPE: orstr[2] = 'S'; orstr[5] = 'I'; break ;
01450 
01451       default: 
01452          fprintf(SUMA_STDERR, "SUMA_THD_dicomm_to_3dmm: illegal zzorient code.\n ") ;
01453          SUMA_RETURNe;
01454    }
01455    
01456    SUMA_RETURNe;
01457 }
01458 SUMA_Boolean SUMA_orstring_to_orcode (char *orstr, int *orient)
01459 {
01460    static char FuncName[]={"SUMA_orstring_to_orcode"};
01461    int i;
01462    
01463    SUMA_ENTRY;
01464    
01465    if (!orstr) { SUMA_SL_Err("NULL string"); SUMA_RETURN(NOPE); }
01466    if (!SUMA_ok_orstring(orstr)) { SUMA_SL_Err("Bad orientation string"); SUMA_RETURN(NOPE); }
01467    for (i=0; i<3; ++i) {
01468       switch (orstr[i]) {
01469          case 'R': orient[i] = ORI_R2L_TYPE; break;
01470          case 'L': orient[i] = ORI_L2R_TYPE; break;
01471          case 'A': orient[i] = ORI_A2P_TYPE; break;
01472          case 'P': orient[i] = ORI_P2A_TYPE; break;
01473          case 'I': orient[i] = ORI_I2S_TYPE; break;
01474          case 'S': orient[i] = ORI_S2I_TYPE; break;
01475          default: fprintf(SUMA_STDERR, " SUMA_orstring_to_orcode: Bad to the bones\n"); SUMA_RETURN(NOPE); 
01476       }
01477    }
01478    
01479    SUMA_RETURN(YUP);
01480 }
01481 
01482 int SUMA_ok_orstring (char *orstr)
01483 {
01484    static char FuncName[]={"SUMA_ok_orstring"};
01485    int i, d[3];
01486    
01487    SUMA_ENTRY;
01488    
01489    if (!orstr) { SUMA_RETURN(NOPE); }
01490    d[0] = d[1] = d[2] = 0;
01491    for (i=0; i<3; ++i) {
01492       switch (orstr[i]) {
01493          case 'R': ++(d[0]); break;
01494          case 'L': ++(d[0]); break;
01495          case 'A': ++(d[1]); break;
01496          case 'P': ++(d[1]); break;
01497          case 'I': ++(d[2]); break;
01498          case 'S': ++(d[2]); break;
01499          default: SUMA_RETURN(NOPE); 
01500       }
01501    }
01502    if (d[0] != 1 || d[1] != 1 || d[2] != 1) SUMA_RETURN(NOPE);
01503     
01504    SUMA_RETURN(YUP);
01505 }
01506 int SUMA_flip_orient(int xxorient)
01507 {
01508    static char FuncName[]={"SUMA_flip_orient"};
01509    
01510    SUMA_ENTRY;
01511    
01512    switch( xxorient ){
01513       case ORI_R2L_TYPE: SUMA_RETURN(ORI_L2R_TYPE); break ;
01514       case ORI_L2R_TYPE: SUMA_RETURN(ORI_R2L_TYPE); break ;
01515       
01516       case ORI_P2A_TYPE: SUMA_RETURN(ORI_A2P_TYPE); break ;
01517       case ORI_A2P_TYPE: SUMA_RETURN(ORI_P2A_TYPE); break ;
01518       
01519       case ORI_I2S_TYPE: SUMA_RETURN(ORI_S2I_TYPE); break ;
01520       case ORI_S2I_TYPE: SUMA_RETURN(ORI_I2S_TYPE); break ;
01521 
01522       default: 
01523          fprintf(SUMA_STDERR, "SUMA_opposite_orient: illegal zzorient code.\n ") ;
01524          SUMA_RETURN(-1);
01525    }
01526    
01527 }
01528 
01529 SUMA_Boolean SUMA_CoordChange (char *orc_in, char *orc_out, float *XYZ, int N_xyz)
01530 {
01531    static char FuncName[]={"SUMA_CoordChange"};
01532    int i, or_in[3], or_out[3], j, map[3], sgn[3], i3;
01533    float xyz[3];
01534    
01535    SUMA_ENTRY;
01536    
01537    if (!SUMA_orstring_to_orcode(orc_in, or_in)) {
01538       SUMA_SL_Err("Bad in code");
01539       SUMA_RETURN(NOPE);
01540    }
01541    if (!SUMA_orstring_to_orcode(orc_out, or_out)) {
01542       SUMA_SL_Err("Bad out code");
01543       SUMA_RETURN(NOPE);
01544    }
01545    
01546    
01547    for (j=0; j<3; ++j) { 
01548       i = 0;
01549       while (i<3) {
01550          if (or_in[i] == or_out[j] || or_in[i] == SUMA_flip_orient(or_out[j])) {
01551             map[j] = i;
01552             if (or_in[i] == SUMA_flip_orient(or_out[j])) sgn[j] = -1;
01553             else sgn[j] = 1;
01554             i = 3; 
01555          }
01556          ++i;
01557       }
01558    }
01559 
01560    for (i=0; i<N_xyz; ++i) {
01561       i3 = 3*i;
01562       xyz[0] = XYZ[i3]; xyz[1] = XYZ[i3+1]; xyz[2] = XYZ[i3+2];
01563       XYZ[i3  ] = sgn[0] * xyz[map[0]]; 
01564       XYZ[i3+1] = sgn[1] * xyz[map[1]]; 
01565       XYZ[i3+2] = sgn[2] * xyz[map[2]]; 
01566    }
01567    
01568    SUMA_RETURN(YUP);
01569 }
01570 
01571 
01572 
01573 
01574 
01575  
01576 void SUMA_originto3d_2_originHEAD(THD_ivec3 orient, THD_fvec3 *origin)
01577 {
01578    static char FuncName[]={"SUMA_originto3d_2_originHEAD"};
01579    
01580    SUMA_ENTRY;
01581    
01582    origin->xyz[0] = (ORIENT_sign[orient.ijk[0]] == '+')
01583                   ? (-origin->xyz[0]) : ( origin->xyz[0]) ;
01584 
01585    origin->xyz[1] = (ORIENT_sign[orient.ijk[1]] == '+')
01586                   ? (-origin->xyz[1]) : ( origin->xyz[1]) ;
01587    
01588    origin->xyz[2] = (ORIENT_sign[orient.ijk[2]] == '+')
01589                   ? (-origin->xyz[2]) : ( origin->xyz[2]) ;
01590    
01591    SUMA_RETURNe;
01592    
01593 } 
01594 
01595 
01596 
01597 
01598 
01599  
01600 
01601 void SUMA_sizeto3d_2_deltaHEAD(THD_ivec3 orient, THD_fvec3 *delta)                 
01602 {
01603    static char FuncName[]={"SUMA_sizeto3d_2_deltaHEAD"};
01604    
01605    SUMA_ENTRY;
01606    
01607    delta->xyz[0] = (ORIENT_sign[orient.ijk[0]] == '+')
01608                   ? (delta->xyz[0]) : ( -delta->xyz[0]) ;
01609 
01610    delta->xyz[1] = (ORIENT_sign[orient.ijk[1]] == '+')
01611                   ? (delta->xyz[1]) : ( -delta->xyz[1]) ;
01612    
01613    delta->xyz[2] = (ORIENT_sign[orient.ijk[2]] == '+')
01614                   ? (delta->xyz[2]) : ( -delta->xyz[2]) ;
01615    
01616    SUMA_RETURNe;
01617    
01618 }    
01619 
01620 
01621 
01622 
01623 
01624 
01625 
01626 
01627 
01628 
01629 
01630 
01631 
01632 
01633 
01634 
01635 
01636 
01637 
01638  
01639 SUMA_Boolean SUMA_vec_3dfind_to_3dmm (float *NodeList, int N_Node, SUMA_VOLPAR *VolPar)
01640 {
01641    static char FuncName[]={"SUMA_vec_3dfind_to_3dmm"};
01642    THD_fvec3 fv, iv;
01643    int i, id;
01644    SUMA_SurfaceObject SO;
01645    
01646    SUMA_ENTRY;
01647 
01648    if (!NodeList || !VolPar) { SUMA_SL_Err("Null NodeList || Null VolPar"); SUMA_RETURN(NOPE); }
01649    
01650    SO.NodeList = NodeList; SO.N_Node = N_Node; SO.VolPar = VolPar; SO.NodeDim = 3;
01651    
01652    for (i=0; i < SO.N_Node; ++i) {
01653       id = i * SO.NodeDim;
01654       
01655       iv.xyz[0] = SO.NodeList[id] ;
01656       iv.xyz[1] = SO.NodeList[id+1] ;
01657       iv.xyz[2] = SO.NodeList[id+2] ;
01658       fv = SUMA_THD_3dfind_to_3dmm( &SO, iv );
01659       SO.NodeList[id] = fv.xyz[0];
01660       SO.NodeList[id+1] = fv.xyz[1];
01661       SO.NodeList[id+2] = fv.xyz[2];
01662    }
01663 
01664    SUMA_RETURN(YUP);
01665 }
01666 
01667 SUMA_Boolean SUMA_vec_3dmm_to_3dfind (float *NodeList, int N_Node, SUMA_VOLPAR *VolPar)
01668 {
01669    static char FuncName[]={"SUMA_vec_3dmm_to_3dfind"};
01670    THD_fvec3 fv, iv;
01671    int i, id;
01672    SUMA_SurfaceObject SO;
01673 
01674    SUMA_ENTRY;
01675 
01676    if (!NodeList || !VolPar) { SUMA_SL_Err("Null NodeList || Null VolPar"); SUMA_RETURN(NOPE); }
01677    
01678    SO.NodeList = NodeList; SO.N_Node = N_Node; SO.VolPar = VolPar; SO.NodeDim = 3;
01679 
01680    for (i=0; i < SO.N_Node; ++i) {
01681       id = i * SO.NodeDim;
01682       
01683       iv.xyz[0] = SO.NodeList[id] ;
01684       iv.xyz[1] = SO.NodeList[id+1] ;
01685       iv.xyz[2] = SO.NodeList[id+2] ;
01686       fv = SUMA_THD_3dmm_to_3dfind( &SO, iv );
01687       SO.NodeList[id] = fv.xyz[0];
01688       SO.NodeList[id+1] = fv.xyz[1];
01689       SO.NodeList[id+2] = fv.xyz[2];
01690    }
01691 
01692    SUMA_RETURN(YUP);
01693 }
01694 
01695 SUMA_Boolean SUMA_vec_dicomm_to_3dfind (float *NodeList, int N_Node, SUMA_VOLPAR *VolPar)
01696 {
01697    static char FuncName[]={"SUMA_vec_dicomm_to_3dfind"};
01698 
01699    SUMA_ENTRY;
01700 
01701    if (!NodeList || !VolPar) { SUMA_SL_Err("Null NodeList || Null VolPar"); SUMA_RETURN(NOPE); }
01702    
01703    
01704    if (!SUMA_vec_dicomm_to_3dmm(NodeList, N_Node, VolPar)) { SUMA_RETURN(NOPE); }
01705    if (!SUMA_vec_3dmm_to_3dfind(NodeList, N_Node, VolPar)) { SUMA_RETURN(NOPE); }
01706 
01707    SUMA_RETURN(YUP);
01708 }
01709 
01710 SUMA_Boolean SUMA_vec_3dfind_to_dicomm (float *NodeList, int N_Node, SUMA_VOLPAR *VolPar)
01711 {
01712    static char FuncName[]={"SUMA_vec_3dfind_to_dicomm"};
01713 
01714    SUMA_ENTRY;
01715 
01716    if (!NodeList || !VolPar) { SUMA_SL_Err("Null NodeList || Null VolPar"); SUMA_RETURN(NOPE); }
01717 
01718    if (!SUMA_vec_3dfind_to_3dmm(NodeList, N_Node, VolPar)) { SUMA_RETURN(NOPE); }
01719    if (!SUMA_vec_3dmm_to_dicomm(NodeList, N_Node, VolPar)) { SUMA_RETURN(NOPE); }
01720 
01721    SUMA_RETURN(YUP);
01722 }
01723 
01724 SUMA_Boolean SUMA_vec_3dmm_to_dicomm (float *NodeList, int N_Node, SUMA_VOLPAR *VolPar)
01725 {
01726    static char FuncName[]={"SUMA_vec_3dmm_to_dicomm"};
01727    THD_fvec3 fv, iv;
01728    int i, id;
01729    SUMA_SurfaceObject SO;
01730    
01731    SUMA_ENTRY;
01732 
01733    if (!NodeList || !VolPar) { SUMA_SL_Err("Null NodeList || Null VolPar"); SUMA_RETURN(NOPE); }
01734    
01735    SO.NodeList = NodeList; SO.N_Node = N_Node; SO.VolPar = VolPar; SO.NodeDim = 3;
01736 
01737    for (i=0; i < SO.N_Node; ++i) {
01738       id = i * SO.NodeDim;
01739       iv.xyz[0] = SO.NodeList[id] ;
01740       iv.xyz[1] = SO.NodeList[id+1] ;
01741       iv.xyz[2] = SO.NodeList[id+2] ;
01742 
01743       
01744       fv = SUMA_THD_3dmm_to_dicomm( SO.VolPar->xxorient, SO.VolPar->yyorient, SO.VolPar->zzorient,  iv );
01745       SO.NodeList[id] = fv.xyz[0];
01746       SO.NodeList[id+1] = fv.xyz[1];
01747       SO.NodeList[id+2] = fv.xyz[2];
01748    }
01749 
01750    SUMA_RETURN(YUP);
01751 }   
01752 
01753 SUMA_Boolean SUMA_vec_dicomm_to_3dmm (float *NodeList, int N_Node, SUMA_VOLPAR *VolPar)
01754 {
01755    static char FuncName[]={"SUMA_vec_dicomm_to_3dmm"};
01756    THD_fvec3 fv, iv;
01757    int i, id;
01758    SUMA_SurfaceObject SO;
01759 
01760    SUMA_ENTRY;
01761 
01762    if (!NodeList || !VolPar) { SUMA_SL_Err("Null NodeList || Null VolPar"); SUMA_RETURN(NOPE); }
01763    
01764    SO.NodeList = NodeList; SO.N_Node = N_Node; SO.VolPar = VolPar; SO.NodeDim = 3;
01765 
01766    for (i=0; i < SO.N_Node; ++i) {
01767       id = i * SO.NodeDim;
01768 
01769       iv.xyz[0] = SO.NodeList[id] ;
01770       iv.xyz[1] = SO.NodeList[id+1] ;
01771       iv.xyz[2] = SO.NodeList[id+2] ;
01772 
01773       
01774       fv = SUMA_THD_dicomm_to_3dmm( &SO, iv );
01775       SO.NodeList[id] = fv.xyz[0];
01776       SO.NodeList[id+1] = fv.xyz[1];
01777       SO.NodeList[id+2] = fv.xyz[2];
01778    }
01779 
01780    SUMA_RETURN(YUP);
01781 }
01782 
01783 
01784 
01785 
01786 
01787 
01788 
01789 
01790 
01791 
01792 
01793 
01794 
01795 
01796 
01797 
01798 
01799 
01800 
01801 
01802 SUMA_Boolean SUMA_AFNItlrc_toMNI(float *NodeList, int N_Node, char *Coord)
01803 {
01804    static char FuncName[]={"SUMA_AFNItlrc_toMNI"};
01805    SUMA_Boolean DoFlip = NOPE;
01806    int i, i3;
01807    float mx = 0.0,my = 0.0,mz  = 0.0, tx = 0.0,ty = 0.0,tz = 0.0 ;
01808    SUMA_Boolean LocalHead = NOPE;
01809    
01810    if (strcmp(Coord,"RAI") == 0) DoFlip = NOPE;
01811    else if (strcmp(Coord,"LPI") == 0) DoFlip = YUP;
01812    else {
01813       SUMA_S_Err("Can't do. Either RAI or LPI");
01814       SUMA_RETURN(NOPE);
01815    }   
01816 
01817    
01818    for (i=0; i< N_Node; ++i) {
01819       i3 = 3*i;
01820       if (DoFlip) {
01821          if (!i) SUMA_LH("Flipping to LPI");
01822          tx = - NodeList[i3]; ty = -NodeList[i3+1] ;  
01823          tz = NodeList[i3+2] ;
01824       } else {
01825          if (!i) SUMA_LH("No Flipping, RAI maintained");
01826          tx =  NodeList[i3]; ty = NodeList[i3+1] ;  
01827          tz =  NodeList[i3+2] ;
01828       }
01829       mx = 1.01010 * tx ;
01830       my = 1.02962 * ty - 0.05154 * tz ;
01831       mz = 0.05434 * ty + 1.08554 * tz ;
01832       if( mz < 0.0 ) mz *= 1.09523 ;
01833       NodeList[i3] = mx;
01834       NodeList[i3+1] = my;
01835       NodeList[i3+2] = mz;
01836    }
01837    
01838    
01839    SUMA_RETURN(YUP);
01840 }
01841 
01842 
01843 
01844 
01845 
01846 
01847 
01848 
01849 
01850 
01851 
01852 
01853 
01854 SUMA_Boolean SUMA_AFNI_forward_warp_xyz( THD_warp * warp , float *xyzv, int N)
01855 {
01856    static char FuncName[]={"SUMA_AFNI_forward_warp_xyz"};
01857    THD_fvec3 new_fv, old_fv;
01858    int i, i3;
01859    
01860    SUMA_ENTRY;
01861    
01862    if( warp == NULL ) {
01863       fprintf (SUMA_STDERR, "Error %s: NULL warp.\n", FuncName);
01864       SUMA_RETURN (NOPE) ;
01865    }
01866 
01867    switch( warp->type ){
01868 
01869       default: 
01870          fprintf (SUMA_STDERR, "Error %s: bad warp->type\n", FuncName);
01871          SUMA_RETURN (NOPE); 
01872          break ;
01873 
01874       case WARP_TALAIRACH_12_TYPE:{
01875          THD_linear_mapping map ;
01876          int iw ;
01877 
01878          
01879 
01880 
01881          for (i=0; i < N; ++i) {
01882             i3 = 3*i;
01883             old_fv.xyz[0] = xyzv[i3];
01884             old_fv.xyz[1] = xyzv[i3+1];
01885             old_fv.xyz[2] = xyzv[i3+2];
01886             
01887             for( iw=0 ; iw < 12 ; iw++ ){
01888                map    = warp->tal_12.warp[iw] ;
01889                new_fv = MATVEC_SUB(map.mfor,old_fv,map.bvec) ;
01890 
01891                if( new_fv.xyz[0] >= map.bot.xyz[0] &&
01892                    new_fv.xyz[1] >= map.bot.xyz[1] &&
01893                    new_fv.xyz[2] >= map.bot.xyz[2] &&
01894                    new_fv.xyz[0] <= map.top.xyz[0] &&
01895                    new_fv.xyz[1] <= map.top.xyz[1] &&
01896                    new_fv.xyz[2] <= map.top.xyz[2]   ) break ;  
01897             }
01898             xyzv[i3] = new_fv.xyz[0];
01899             xyzv[i3+1] = new_fv.xyz[1];
01900             xyzv[i3+2] = new_fv.xyz[2];
01901             
01902          }
01903       }
01904       break ;
01905 
01906       case WARP_AFFINE_TYPE:{
01907          THD_linear_mapping map = warp->rig_bod.warp ;
01908          for (i=0; i < N; ++i) {
01909             i3 = 3*i;
01910             old_fv.xyz[0] = xyzv[i3];
01911             old_fv.xyz[1] = xyzv[i3+1];
01912             old_fv.xyz[2] = xyzv[i3+2];
01913             new_fv = MATVEC_SUB(map.mfor,old_fv,map.bvec) ;
01914             xyzv[i3] = new_fv.xyz[0];
01915             xyzv[i3+1] = new_fv.xyz[1];
01916             xyzv[i3+2] = new_fv.xyz[2];
01917          }
01918       }
01919       break ;
01920 
01921    }
01922    SUMA_RETURN(YUP);
01923 }