00001 
00002 
00003 
00004    
00005 #include "SUMA_suma.h"
00006 
00007 SUMA_SurfaceViewer *SUMAg_cSV; 
00008 SUMA_SurfaceViewer *SUMAg_SVv = NULL; 
00009 
00010 int SUMAg_N_SVv = 0; 
00011 SUMA_DO *SUMAg_DOv;     
00012 int SUMAg_N_DOv = 0; 
00013 SUMA_CommonFields *SUMAg_CF; 
00014 
00015 
00016 float maximum(int N, float *inarray);
00017 float minimum(int N, float *inarray);
00018 void cmp_surf_usage ();
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 int main (int argc,char *argv[])
00028 {
00029   static char FuncName[]={"SUMA_inflate_compare"}; 
00030   SUMA_SurfSpecFile Spec;
00031   char *specfilename = NULL;
00032   int kar, id;
00033   SUMA_Boolean brk;
00034   SUMA_Boolean SurfIn = NOPE;
00035 
00036   SUMA_SurfaceObject *Surf1 = NULL, *Surf2=NULL;
00037   char *Surf1_FileName = NULL;
00038   char *Surf2_FileName = NULL;
00039   char *Vol1Parent_FileName=NULL;
00040   char *Vol2Parent_FileName=NULL;
00041   
00042   
00043   SUMA_SFname *Surf1_SFName = NULL, *Surf2_SFName = NULL;
00044    
00045   
00046   int i;
00047   int num_nodes1;
00048   int num_nodes2;  
00049   float P0[3];
00050   float delta_t; 
00051   float P1[3];
00052   float N0[3];
00053   float maxdistance, mindistance;
00054   float *distance;
00055   float Points[2][3], p1[3], p2[3];
00056   SUMA_COLOR_MAP *MyColMap;
00057   SUMA_SCALE_TO_MAP_OPT *MyOpt;
00058   SUMA_COLOR_SCALED_VECT * MySV;
00059   SUMA_MT_INTERSECT_TRIANGLE *triangle;
00060   SUMA_SURF_NORM SN1;
00061   SUMA_SURF_NORM SN2;
00062   SUMA_SurfaceObject *SO1, *SO2;
00063   struct timeval tt; 
00064   FILE *colorfile;
00065   FILE *distancefile;
00066   char colorfilename[1000];
00067   char distancefilename[1000];
00068   char *tag1 = NULL;
00069   char *tag2 = NULL;
00070   char *state1 = NULL;
00071   char *state2 = NULL;
00072   char *hemi = NULL;
00073   float B_dim[3];
00074   SUMA_ISINBOX isin;
00075   SUMA_PATCH *Patch=NULL;
00076   SUMA_Boolean TryFull = NOPE, FullOnly;
00077   SUMA_MEMBER_FACE_SETS *Memb = NULL;
00078   int *FaceSet_tmp;
00079   int N_FaceSet_tmp;
00080   char *fout = NULL;
00081   int inflation = 10; 
00082   
00083   
00084   SUMAg_CF = SUMA_Create_CommonFields ();
00085   if (SUMAg_CF == NULL) {
00086     fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_Create_CommonFields\n", FuncName);
00087     exit(1);
00088   }
00089   
00090   if (argc < 5) {
00091     cmp_surf_usage();
00092     exit (1);
00093   }
00094   
00095   
00096   kar = 1;
00097   brk = NOPE;
00098   SurfIn = NOPE;
00099   FullOnly = YUP;
00100   while (kar < argc) {
00101     
00102     if ((strcmp(argv[kar], "-h") == 0) || (strcmp(argv[kar], "-help") == 0)) {
00103       cmp_surf_usage ();
00104       exit (1);
00105     }
00106     if (!brk && (strcmp(argv[kar], "-hemi")) == 0) {
00107       kar ++;
00108       if (kar >= argc) {
00109         fprintf (SUMA_STDERR, "need argument after -hemi");
00110         exit (1);
00111          }
00112       hemi = argv[kar];
00113       brk = YUP;
00114     }
00115     if (!brk && (strcmp(argv[kar], "-prefix")) == 0) {
00116       kar ++;
00117       if (kar >= argc) {
00118         fprintf (SUMA_STDERR, "need argument after -prefix");
00119         exit (1);
00120       }
00121       fout = argv[kar];
00122       brk = YUP;
00123     }
00124     if (!brk && (strcmp(argv[kar], "-spec")) == 0) {
00125       kar ++;
00126       if (kar >= argc) {
00127         fprintf (SUMA_STDERR, "need argument after -spec ");
00128         exit (1);
00129       }
00130       specfilename = argv[kar];
00131       brk = YUP;
00132     }
00133     if (!brk && (strcmp(argv[kar], "-box")) == 0) {
00134       kar ++;
00135       if (kar+2 >= argc) {
00136         fprintf (SUMA_STDERR, "need 3 arguments after -box");
00137         exit (1);
00138       }
00139       B_dim[0] = atof(argv[kar]); kar ++;
00140       B_dim[1] = atof(argv[kar]); kar ++;
00141       B_dim[2] = atof(argv[kar]);
00142       
00143       FullOnly = NOPE;
00144       brk = YUP;
00145     }
00146     if (!brk) {
00147       fprintf (SUMA_STDERR,"Error %s: Option %s not understood. Try -help for usage\n", FuncName, argv[kar]);
00148       exit (1);
00149     } 
00150     else {      
00151       brk = NOPE;
00152       kar ++;
00153     }
00154   }
00155   
00156   
00157   if (specfilename == NULL) {
00158     fprintf (SUMA_STDERR,"Error %s: No spec filename specified.\n", FuncName);
00159     exit(1);
00160   }
00161   if (!SUMA_Read_SpecFile (specfilename, &Spec)) {
00162     fprintf(SUMA_STDERR,"Error %s: Error in SUMA_Read_SpecFile\n", FuncName);
00163     exit(1);
00164   }     
00165 
00166   
00167   if (SUMA_iswordin(Spec.SurfaceType[0], "FreeSurfer") == 1) {
00168     Surf1_FileName = Spec.SurfaceFile[0];
00169     Surf1 = SUMA_Load_Surface_Object(Surf1_FileName, SUMA_FREE_SURFER, SUMA_ASCII, Vol1Parent_FileName);
00170     tag1 =  "FS";
00171   }
00172   else 
00173     if (SUMA_iswordin(Spec.SurfaceType[0], "SureFit") == 1) {
00174       Surf1_SFName = SUMA_malloc(sizeof(SUMA_SFname));
00175       strcpy(Surf1_SFName->name_coord,Spec.CoordFile[0]);
00176       strcpy(Surf1_SFName->name_topo, Spec.TopoFile[0]);
00177       strcpy(Surf1_SFName->name_param, Spec.SureFitVolParam[0]);
00178       Surf1 = SUMA_Load_Surface_Object(Surf1_SFName, SUMA_SUREFIT, SUMA_ASCII,Vol1Parent_FileName);
00179       tag1 =  "SF";
00180     }
00181   state1 = Spec.State[0];
00182   
00183   
00184   if (SUMA_iswordin(Spec.SurfaceType[0], "FreeSurfer") == 1) {
00185     Surf2_FileName = Spec.SurfaceFile[0];
00186     Surf2 = SUMA_Load_Surface_Object(Surf1_FileName, SUMA_FREE_SURFER, SUMA_ASCII, Vol1Parent_FileName);
00187     tag2 =  "FS";
00188   }
00189   else 
00190     if (SUMA_iswordin(Spec.SurfaceType[0], "SureFit") == 1) {
00191       Surf2_SFName = SUMA_malloc(sizeof(SUMA_SFname));
00192       strcpy(Surf2_SFName->name_coord,Spec.CoordFile[0]);
00193       strcpy(Surf2_SFName->name_topo, Spec.TopoFile[0]);
00194       strcpy(Surf2_SFName->name_param, Spec.SureFitVolParam[0]);
00195       Surf2 = SUMA_Load_Surface_Object(Surf1_SFName, SUMA_SUREFIT, SUMA_ASCII,Vol1Parent_FileName);
00196       tag2 =  "SF";
00197     }
00198   state2 = Spec.State[0];
00199   
00200   if (fout == NULL) { 
00201     sprintf(distancefilename, "dist_%s_%s_%s_%dmm.txt",hemi,tag1,state1,inflation);
00202     sprintf(colorfilename, "dist_%s_%s_%s_%dmm.col",hemi,tag1,state1,inflation);
00203   } 
00204   else {
00205     sprintf (colorfilename, "%s.col", fout);
00206     sprintf (distancefilename, "%s.txt", fout);
00207   }
00208   
00209   if (SUMA_filexists(colorfilename) || SUMA_filexists(distancefilename)) {
00210     fprintf (SUMA_STDERR,"Error %s: One or both of output files %s, %s exists.\nWill not overwrite.\n", \
00211              FuncName, distancefilename, colorfilename);
00212     exit(1);
00213   }
00214   
00215   
00216 
00217   SO1 = Surf1;
00218   SO2 = Surf2;
00219  
00220   
00221   
00222 
00223   num_nodes1 = SO1->N_Node;
00224   num_nodes2 = SO2->N_Node;
00225   
00226   fprintf(SUMA_STDERR, "Number of nodes in surface 1: %d \n", num_nodes1);
00227   fprintf(SUMA_STDERR, "Number of nodes in surface 2: %d \n", num_nodes2);
00228   SN1 = SUMA_SurfNorm(SO1->NodeList,  SO1->N_Node, SO1->FaceSetList, SO1->N_FaceSet);
00229   
00230   
00231 
00232 
00233 
00234    
00235   SUMA_etime (&tt, 0);
00236   for (i = 0; i < num_nodes1; i++) {
00237     id = SO1->NodeDim * i;
00238          P0[0] = SO1->NodeList[id];
00239     P0[1] = SO1->NodeList[id+1];
00240     P0[2] = SO1->NodeList[id+2];
00241     N0[0] = SN1.NodeNormList[id];
00242     N0[1] = SN1.NodeNormList[id+1];
00243     N0[2] = SN1.NodeNormList[id+2];
00244     SUMA_POINT_AT_DISTANCE(N0, P0, 10, Points);
00245     P1[0] = Points[0][0];
00246     P1[1] = Points[0][1];
00247     P1[2] = Points[0][2];
00248     
00249 
00250    
00251     SO2->NodeList[id] = P1[0];
00252     SO2->NodeList[id+1] = P1[1];
00253     SO2->NodeList[id+2] = P1[2];
00254   }
00255 
00256  
00257 
00258   SN1 = SUMA_SurfNorm(SO1->NodeList,  SO1->N_Node, SO1->FaceSetList, SO1->N_FaceSet);
00259   SN2 = SUMA_SurfNorm(SO2->NodeList,  SO2->N_Node, SO2->FaceSetList, SO2->N_FaceSet);
00260   if (!FullOnly) {
00261     
00262     fprintf(SUMA_STDOUT, "%s: Computing MemberFaceSets... \n", FuncName);
00263     Memb = SUMA_MemberFaceSets (SO2->N_Node, SO2->FaceSetList, SO2->N_FaceSet, 3, SO2->idcode_str);
00264     if (Memb->NodeMemberOfFaceSet == NULL) {
00265       fprintf(SUMA_STDERR, "Error %s: Failed in SUMA_MemberFaceSets. \n", FuncName);
00266       exit(1);
00267     }
00268   }
00269   
00270   
00271 
00272   
00273   
00274   
00275   SUMA_etime (&tt, 0);
00276   distance = SUMA_malloc(num_nodes1*sizeof(float));
00277   for (i = 0; i < num_nodes1; i++) {
00278     
00279     id = SO1->NodeDim * i;
00280          P0[0] = SO1->NodeList[id];
00281     P0[1] = SO1->NodeList[id+1];
00282     P0[2] = SO1->NodeList[id+2];
00283     N0[0] = SN1.NodeNormList[id];
00284     N0[1] = SN1.NodeNormList[id+1];
00285     N0[2] = SN1.NodeNormList[id+2];
00286     SUMA_POINT_AT_DISTANCE(N0, P0, 1000, Points);
00287     P1[0] = Points[0][0];
00288     P1[1] = Points[0][1];
00289     P1[2] = Points[0][2];
00290     if (!FullOnly) { 
00291       TryFull = NOPE;
00292       
00293       isin = SUMA_isinbox (SO2->NodeList, SO2->N_Node, P0, B_dim, 0);
00294       if (isin.nIsIn) {
00295         
00296         Patch = SUMA_getPatch (isin.IsIn, isin.nIsIn, SO2->FaceSetList, SO2->N_FaceSet, Memb, 1);
00297         if (Patch == NULL) {
00298           fprintf(SUMA_STDERR, "Error %s: Null returned from SUMA_getPatch.\n", FuncName);
00299           exit (1);
00300         }
00301         
00302         
00303         FaceSet_tmp = Patch->FaceSetList;
00304         N_FaceSet_tmp = Patch->N_FaceSet;
00305       }else {
00306         fprintf (SUMA_STDOUT, "%s: No nodes in box about node %d. Trying for full surface intersection.\n", FuncName, i);
00307         TryFull = YUP; 
00308       }
00309     } 
00310     
00311     if (FullOnly || TryFull) {
00312       Patch = NULL;
00313       FaceSet_tmp = SO2->FaceSetList;
00314       N_FaceSet_tmp = SO2->N_FaceSet;
00315     }
00316     
00317     
00318     p1[0] = Points[0][0]; 
00319     p1[1] = Points[0][1]; 
00320     p1[2] = Points[0][2];
00321     p2[0] = Points[1][0]; 
00322     p2[1] = Points[1][1]; 
00323     p2[2] = Points[1][2];
00324     triangle = SUMA_MT_intersect_triangle(p1,p2, SO2->NodeList, SO2->N_Node, SO2->FaceSetList, SO2->N_FaceSet, NULL);
00325     
00326     if (triangle->N_hits ==0) {
00327       distance[i] = -1;
00328       
00329     }
00330     else {
00331       distance[i] = sqrtf(pow(triangle->P[0]-P0[0],2)+pow(triangle->P[1]-P0[1],2)+pow(triangle->P[2]-P0[2],2));
00332       
00333     
00334     }
00335          
00336     SUMA_Free_MT_intersect_triangle(triangle); 
00337     if (Patch) SUMA_freePatch(Patch);
00338         
00339     
00340     if (!(i%100)) {
00341       delta_t = SUMA_etime(&tt, 1);
00342       fprintf (SUMA_STDERR, " [%d]/[%d] %.2f/100%% completed. Dt = %.2f min done of %.2f min total\r" ,  i, num_nodes1, (float)i / num_nodes1 * 100, delta_t/60, delta_t/i * num_nodes1/60);
00343     }      
00344   
00345   }
00346 
00347   
00348   if((distancefile = fopen(distancefilename, "w"))==NULL) {
00349     fprintf(SUMA_STDERR, "Could not open file distance.txt.\n");
00350     exit(1);
00351   }
00352   else {  
00353     for (i=0; i < num_nodes1; ++i) {
00354       fprintf (distancefile,"%d\t%f\n", i, distance[i]);
00355     }
00356     fclose (distancefile);
00357   }
00358   
00359   
00360   MyColMap = SUMA_GetStandardMap(SUMA_CMAP_MATLAB_DEF_BYR64);
00361   MyOpt = SUMA_ScaleToMapOptInit();
00362   MySV = SUMA_Create_ColorScaledVect(num_nodes1);
00363   mindistance = minimum(num_nodes1, distance);
00364   maxdistance = maximum(num_nodes1, distance);
00365   SUMA_ScaleToMap(distance,num_nodes1,mindistance, maxdistance, MyColMap,MyOpt,MySV);
00366 
00367   
00368   
00369   if((colorfile = fopen(colorfilename, "w"))==NULL) {
00370     fprintf(SUMA_STDERR, "Could not open file distance.col.\n");
00371     exit(1);
00372   }
00373   else {
00374     for (i=0; i < num_nodes1; ++i) {
00375       fprintf (colorfile,"%d\t%f\t%f\t%f\n", i, MySV->cV[3*i  ], MySV->cV[3*i+1], MySV->cV[3*i+2]);
00376     }
00377     fclose (colorfile);
00378   }
00379   
00380   if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
00381   
00382   return 1;
00383 }
00384 
00385 
00386 
00387 
00388 void cmp_surf_usage ()
00389 {
00390   printf ("\nUsage:  SUMA_inflate_compare \n\t-spec <Spec file>\n\n");
00391   printf ("\n\t-spec <Spec file>: File containing surface specification. This file is typically \n");
00392   printf ("\t                   generated by @SUMA_Make_Spec_FS (for FreeSurfer surfaces) or \n");
00393   printf ("\t                   @SUMA_Make_Spec_SF (for SureFit surfaces). The Spec file should \n");
00394   printf ("\t                   be located in the directory containing the surfaces.\n");
00395   printf ("\n\t-hemi <left or right>: specify the hemisphere being processed \n");
00396   printf ("\n\t[-prefix <fileprefix>]: Prefix for distance and node color output files.\n");
00397   printf ("\t                 This option is optional. Existing file will not be overwritten.\n");
00398   printf ("\n\t-box <wX wY wZ>: restrict intersection computations for nodes \n");
00399   printf ("\t        contained in a box of w* dimensions. This might speed things\n");
00400   printf ("\t        up sometimes if the box dimension needs not be large.\n");
00401   printf ("\t        This option is pretty much useless.\n"); 
00402   
00403 
00404 
00405 
00406   printf ("\n\n\tFor more help: http://afni.nimh.nih.gov/ssc/ziad/SUMA/SUMA_doc.htm\n");
00407   printf ("\n\n\tIf you can't get help here, please get help somewhere.\n");
00408   SUMA_Version(NULL);
00409   
00410   printf ("\n\t Shruti Japee LBC/NIMH/NIH shruti@codon.nih.gov Ziad Saad SSSC/NIMH/NIH ziad@nih.gov \n\n");
00411   exit (0);
00412 }
00413 
00414 
00415 
00416 float minimum (int N, float *inarray)
00417 {
00418   float min = inarray[0];
00419   int i;
00420   for (i = 1; i < N; i++)
00421     {
00422       if (inarray[i] < min)
00423         min = inarray[i];
00424     }
00425   return min;
00426 }
00427 
00428 float maximum (int N, float *inarray)
00429 {
00430   float max = inarray[0];
00431   int i;
00432   for (i = 1; i < N; i++)
00433     {
00434       if (inarray[i] > max)
00435         max = inarray[i];
00436     }
00437   return max;
00438 }