00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 #define PROGRAM_NAME    "2dImReg"                   
00049 #define PROGRAM_INITIAL "04 Feb 1998"     
00050 #define PROGRAM_LATEST  "02 Dec 2002"     
00051 
00052 
00053 
00054 #include "mrilib.h"
00055 #include "matrix.h"
00056 
00057 #define MAX_NAME_LENGTH THD_MAX_NAME   
00058 #define STATE_DIM 4                    
00059 
00060 
00061  
00062 int * t_to_z = NULL;             
00063 int * z_to_t = NULL;           
00064 
00065 
00066 static char * commandline = NULL ;       
00067  
00068 
00069 typedef struct IR_options      
00070 {
00071   char * input_filename;       
00072   char * base_filename;        
00073   int base_vol_index;          
00074   int nofine;                  
00075   float blur;                  
00076   float dxy;                   
00077   float dphi;                  
00078   char * new_prefix;           
00079   char * dprefix;              
00080   int dmm;                     
00081   char * rprefix;              
00082   int debug;                   
00083 } IR_options;
00084 
00085 
00086 #include "matrix.c"
00087 
00088 
00089 
00090 
00091 
00092 
00093 
00094 void display_help_menu()
00095 {
00096   printf 
00097     (
00098      "This program performs 2d image registration.  Image alignment is      \n"
00099      "performed on a slice-by-slice basis for the input 3d+time dataset,    \n"
00100      "relative to a user specified base image.                              \n"
00101      "                                                                      \n"
00102      "Usage:                                                                \n"
00103      "2dImReg                                                               \n"
00104      "-input fname           Filename of input 3d+time dataset to process   \n"
00105      "-basefile fname        Filename of 3d+time dataset for base image     \n"
00106      "                         (default = current input dataset)            \n"
00107      "-base num              Time index for base image  (0 <= num)          \n"
00108      "                         (default:  num = 3)                          \n"
00109      "-nofine                Deactivate fine fit phase of image registration\n"
00110      "                         (default:  fine fit is active)               \n"
00111      "-fine blur dxy dphi    Set fine fit parameters                        \n"
00112      "   where:                                                             \n"
00113      "     blur = FWHM of blurring prior to registration (in pixels)        \n"
00114      "               (default:  blur = 1.0)                                 \n"
00115      "     dxy  = Convergence tolerance for translations (in pixels)        \n"
00116      "               (default:  dxy  = 0.07)                                \n"
00117      "     dphi = Convergence tolerance for rotations (in degrees)          \n"
00118      "               (default:  dphi = 0.21)                                \n"
00119      "                                                                      \n"
00120      "-prefix pname     Prefix name for output 3d+time dataset              \n"
00121      "                                                                      \n"
00122      "-dprefix dname    Write files 'dname'.dx, 'dname'.dy, 'dname'.psi     \n"
00123      "                    containing the registration parameters for each   \n"
00124      "                    slice in chronological order.                     \n"
00125      "                    File formats:                                     \n"
00126      "                      'dname'.dx:    time(sec)   dx(pixels)           \n"
00127      "                      'dname'.dy:    time(sec)   dy(pixels)           \n"
00128      "                      'dname'.psi:   time(sec)   psi(degrees)         \n"
00129      "-dmm              Change dx and dy output format from pixels to mm    \n"
00130      "                                                                      \n"
00131      "-rprefix rname    Write files 'rname'.oldrms and 'rname'.newrms       \n"
00132      "                    containing the volume RMS error for the original  \n"
00133      "                    and the registered datasets, respectively.        \n"
00134      "                    File formats:                                     \n"
00135      "                      'rname'.oldrms:   volume(number)   rms_error    \n"
00136      "                      'rname'.newrms:   volume(number)   rms_error    \n"
00137      "                                                                      \n"
00138      "-debug            Lots of additional output to screen                 \n"
00139     );
00140   
00141   exit(0);
00142 }
00143 
00144 
00145 
00146 
00147 
00148 
00149 
00150 void IR_error 
00151 (
00152   char * message               
00153 )
00154 
00155 {
00156   fprintf (stderr, "%s Error: %s \n", PROGRAM_NAME, message);
00157   exit(1);
00158 }
00159 
00160 
00161 
00162 
00163 
00164 
00165 
00166 void initialize_options
00167 (
00168   IR_options ** opt            
00169 )
00170 
00171 {
00172   (*opt) = (IR_options *) malloc (sizeof(IR_options));
00173 
00174   (*opt)->input_filename = NULL;
00175   (*opt)->base_filename = NULL;
00176   (*opt)->base_vol_index = 3;       
00177   (*opt)->nofine = 0;
00178   (*opt)->blur = 1.0;     
00179   (*opt)->dxy  = 0.07;    
00180   (*opt)->dphi = 0.21;   
00181   (*opt)->new_prefix = NULL;
00182   (*opt)->dprefix = NULL;
00183   (*opt)->rprefix = NULL;
00184   (*opt)->dmm = 0;
00185   (*opt)->debug = 0;
00186 }
00187 
00188 
00189 
00190 
00191 
00192 
00193 
00194 void get_user_inputs 
00195 (
00196   int argc,                       
00197   char ** argv,                    
00198   IR_options ** option_data       
00199 )
00200 
00201 {
00202   int nopt = 1;                   
00203   int ival;
00204   float fval;
00205   char message[80];               
00206 
00207   
00208   
00209   if (argc < 2 || strncmp(argv[1], "-help", 5) == 0)  display_help_menu();  
00210   
00211 
00212    
00213   while (nopt < argc )
00214     {
00215 
00216       
00217       if (strncmp(argv[nopt], "-input", 6) == 0)
00218         {
00219           nopt++;
00220           if (nopt >= argc)  IR_error ("Need argument after -input ");
00221           (*option_data)->input_filename 
00222             = (char *) malloc (sizeof(char) * MAX_NAME_LENGTH);
00223           strcpy ((*option_data)->input_filename, argv[nopt]);
00224           nopt++;
00225           continue;
00226         }
00227      
00228 
00229       
00230       if (strncmp(argv[nopt], "-basefile", 9) == 0)
00231         {
00232           nopt++;
00233           if (nopt >= argc)  IR_error ("Need argument after -basefile ");
00234           (*option_data)->base_filename 
00235             = (char *) malloc (sizeof(char) * MAX_NAME_LENGTH);
00236           strcpy ((*option_data)->base_filename, argv[nopt]);
00237           nopt++;
00238           continue;
00239         }
00240      
00241 
00242       
00243       if (strncmp(argv[nopt], "-base", 5) == 0)
00244         {
00245           nopt++;
00246           if (nopt >= argc)  IR_error ("Need argument after -base ");
00247           sscanf (argv[nopt], "%d", &ival);
00248           if (ival < 0) 
00249             IR_error ("Illegal argument after -base  ( must be >= 0 ) ");
00250           (*option_data)->base_vol_index = ival;
00251           nopt++;
00252           continue;
00253         }
00254 
00255 
00256       
00257       if (strncmp(argv[nopt], "-prefix", 7) == 0)
00258         {
00259           nopt++;
00260           if (nopt >= argc)  IR_error ("Need argument after -prefix ");
00261           (*option_data)->new_prefix 
00262             = (char *) malloc (sizeof(char) * MAX_NAME_LENGTH);
00263           strcpy ((*option_data)->new_prefix, argv[nopt]);
00264 
00265           nopt++;
00266           continue;
00267         }
00268      
00269 
00270       
00271       if (strncmp(argv[nopt], "-dprefix", 8) == 0)
00272         {
00273           nopt++;
00274           if (nopt >= argc)  IR_error ("Need argument after -dprefix ");
00275           (*option_data)->dprefix 
00276             = (char *) malloc (sizeof(char) * MAX_NAME_LENGTH);
00277           strcpy ((*option_data)->dprefix, argv[nopt]);
00278 
00279           nopt++;
00280           continue;
00281         }
00282      
00283 
00284       
00285       if (strncmp(argv[nopt], "-rprefix", 8) == 0)
00286         {
00287           nopt++;
00288           if (nopt >= argc)  IR_error ("Need argument after -rprefix ");
00289           (*option_data)->rprefix 
00290             = (char *) malloc (sizeof(char) * MAX_NAME_LENGTH);
00291           strcpy ((*option_data)->rprefix, argv[nopt]);
00292 
00293           nopt++;
00294           continue;
00295         }
00296      
00297 
00298       
00299       if (strncmp(argv[nopt], "-nofine", 7) == 0)
00300         {
00301           (*option_data)->nofine = 1;
00302           nopt++;
00303           continue;
00304         }
00305 
00306            
00307       
00308       if (strncmp(argv[nopt], "-fine", 5) == 0)
00309         {
00310           nopt++;
00311           if (nopt+2 >= argc)  IR_error ("Need 3 arguments after -fine ");
00312           (*option_data)->nofine = 0;
00313 
00314           sscanf (argv[nopt], "%f", &fval);
00315           if (fval <= 0.0) 
00316             IR_error ("Illegal argument for blur  ( must be > 0 ) ");
00317           (*option_data)->blur = fval;
00318           nopt++;
00319 
00320           sscanf (argv[nopt], "%f", &fval);
00321           if (fval <= 0.0)
00322             IR_error ("Illegal argument for dxy  ( must be > 0 ) ");
00323           (*option_data)->dxy = fval;
00324           nopt++;
00325 
00326           sscanf (argv[nopt], "%f", &fval);
00327           if (fval <= 0.0)
00328             IR_error ("Illegal argument for dphi  ( must be > 0 ) ");
00329           (*option_data)->dphi = fval;
00330           nopt++;
00331 
00332           continue;
00333         }
00334       
00335 
00336       
00337       if (strncmp(argv[nopt], "-dmm", 4) == 0)
00338         {
00339           (*option_data)->dmm = 1;
00340           nopt++;
00341           continue;
00342         }
00343 
00344            
00345       
00346       if (strncmp(argv[nopt], "-debug", 6) == 0)
00347         {
00348           (*option_data)->debug = 1;
00349           nopt++;
00350           continue;
00351         }
00352 
00353            
00354       
00355       sprintf(message,"Unrecognized command line option: %s\n", argv[nopt]);
00356       IR_error (message);
00357 
00358 
00359     }
00360       
00361  
00362 }
00363 
00364 
00365 
00366 
00367 
00368 
00369 
00370 void read_dataset 
00371 (
00372   char * filename,                
00373   THD_3dim_dataset ** dset        
00374 )
00375 
00376 {
00377   char message[80];               
00378 
00379 
00380   
00381   *dset = THD_open_one_dataset (filename);
00382   if (*dset == NULL)  
00383     { 
00384       sprintf (message, 
00385                "Unable to open data file: %s", filename);
00386       IR_error (message);
00387     }
00388 
00389 }
00390 
00391 
00392 
00393 
00394 
00395 
00396 
00397 void initialize_slice_sequence 
00398 (
00399   IR_options * option_data,        
00400   THD_3dim_dataset * dset          
00401 )
00402 
00403 {
00404   int num_slices;                  
00405   int ivolume;                     
00406   int itemp;                       
00407   float ttemp;                     
00408   float * time_array = NULL;       
00409   int iz, i, j;                    
00410   float z;                         
00411 
00412 
00413   
00414   num_slices = dset->taxis->nsl;
00415   ivolume = 0;
00416 
00417   if ( num_slices <= 0 )            
00418       num_slices = dset->daxes->nzz;
00419 
00420   
00421   t_to_z = (int *) malloc (sizeof(int) * num_slices);
00422   z_to_t = (int *) malloc (sizeof(int) * num_slices);
00423   time_array = (float *) malloc (sizeof(float) * num_slices);
00424 
00425 
00426   
00427   for (iz = 0;  iz < num_slices;  iz++)
00428     {
00429       z = iz * dset->taxis->dz_sl + dset->taxis->zorg_sl;
00430       time_array[iz] = THD_timeof (ivolume, z, dset->taxis);
00431       t_to_z[iz] = iz;
00432     }
00433 
00434 
00435   
00436   for (i = 0;  i < num_slices-1;  i++)
00437     for (j = i+1;  j < num_slices;  j++)
00438       if (time_array[j] < time_array[i])
00439         {
00440           itemp = t_to_z[i];
00441           t_to_z[i] = t_to_z[j];
00442           t_to_z[j] = itemp;
00443 
00444           ttemp = time_array[i];
00445           time_array[i] = time_array[j];
00446           time_array[j] = ttemp;
00447         } 
00448 
00449 
00450   
00451   for (i = 0;  i < num_slices;  i++)
00452     {
00453       j = t_to_z[i];
00454       z_to_t[j] = i;
00455     }
00456 
00457 
00458   
00459   if (option_data->debug)
00460     for (i = 0;  i < num_slices;  i++)
00461       printf ("time[%2d] = %12.3f   t_to_z[%2d] = %2d   z_to_t[%2d] = %2d\n",
00462               i, time_array[i], i, t_to_z[i], i, z_to_t[i]);
00463 
00464   
00465   
00466   free (time_array);   time_array = NULL;
00467 } 
00468 
00469 
00470 
00471 
00472 
00473 
00474 
00475 void initialize_state_history 
00476 (
00477   THD_3dim_dataset * dset,            
00478   vector ** state_history             
00479 )
00480 
00481 {
00482   int num_slices;                     
00483   int ts_length;                      
00484   int num_vectors;                    
00485   int i;                              
00486 
00487 
00488   
00489   num_slices = dset->taxis->nsl;
00490 
00491   if ( num_slices <= 0 )              
00492       num_slices = dset->daxes->nzz;
00493 
00494   ts_length = DSET_NUM_TIMES(dset);
00495   num_vectors = ts_length * num_slices;
00496 
00497 
00498   
00499   *state_history = (vector *) malloc (sizeof(vector) * num_vectors);
00500 
00501 
00502   
00503   for (i = 0;  i < num_vectors;  i++)
00504     {
00505       vector_initialize (&((*state_history)[i]));
00506       vector_create (STATE_DIM, &((*state_history)[i]));
00507     }
00508 }
00509 
00510  
00511 
00512 
00513 
00514 
00515 
00516 void initialize_rms_arrays 
00517 (
00518   THD_3dim_dataset * dset,       
00519   float ** old_rms_array,        
00520   float ** new_rms_array         
00521 )
00522 
00523 {
00524   int ts_length;                 
00525 
00526 
00527   ts_length = DSET_NUM_TIMES(dset);
00528 
00529   
00530   *old_rms_array = (float *) malloc (sizeof(float) * ts_length);
00531   *new_rms_array = (float *) malloc (sizeof(float) * ts_length);
00532   
00533 
00534 }
00535 
00536  
00537 
00538 
00539 
00540 
00541 
00542 void initialize_program
00543 (
00544   int argc,                       
00545   char ** argv,                    
00546   IR_options ** option_data,      
00547   vector ** state_history,        
00548   float ** old_rms_array,         
00549   float ** new_rms_array          
00550 )
00551 
00552 {
00553   THD_3dim_dataset * dset = NULL;
00554 
00555 
00556   
00557   commandline = tross_commandline( PROGRAM_NAME , argc,argv ) ;
00558 
00559 
00560   
00561   initialize_options (option_data);
00562 
00563 
00564   
00565   get_user_inputs (argc, argv, option_data);
00566 
00567 
00568   
00569   read_dataset ((*option_data)->input_filename, &dset);
00570 
00571   
00572   
00573   initialize_slice_sequence (*option_data, dset);
00574 
00575 
00576   
00577   if ((*option_data)->dprefix != NULL)
00578     initialize_state_history (dset, state_history);
00579 
00580 
00581   
00582   if ((*option_data)->rprefix != NULL)
00583     initialize_rms_arrays (dset, old_rms_array, new_rms_array);
00584 
00585 
00586   
00587   THD_delete_3dim_dataset (dset, False);   dset = NULL;
00588 
00589 }
00590 
00591 
00592 
00593 
00594 
00595 
00596 
00597 
00598 THD_3dim_dataset * copy_dset( THD_3dim_dataset * dset , char * new_prefix )
00599 {
00600    THD_3dim_dataset * new_dset ;
00601    int ival , ityp , nbytes , nvals ;
00602    void * new_brick , * old_brick ;
00603 
00604    
00605 
00606    if( ! ISVALID_3DIM_DATASET(dset) ) return NULL ;
00607 
00608    
00609 
00610    new_dset = EDIT_empty_copy( dset ) ;
00611 
00612    
00613 
00614    if( new_prefix != NULL )
00615       EDIT_dset_items( new_dset ,
00616                           ADN_prefix , new_prefix ,
00617                           ADN_label1 , new_prefix ,
00618                        ADN_none ) ;
00619 
00620    
00621 
00622    THD_load_datablock( dset->dblk ) ;  
00623 
00624    nvals = DSET_NVALS(dset) ;
00625 
00626    for( ival=0 ; ival < nvals ; ival++ ){
00627       ityp      = DSET_BRICK_TYPE(new_dset,ival) ;   
00628       nbytes    = DSET_BRICK_BYTES(new_dset,ival) ;  
00629       new_brick = malloc( nbytes ) ;                 
00630 
00631       if( new_brick == NULL ){
00632         THD_delete_3dim_dataset( new_dset , False ) ;
00633         return NULL ;
00634       }
00635 
00636       EDIT_substitute_brick( new_dset , ival , ityp , new_brick ) ;
00637 
00638       
00639 
00640       old_brick = DSET_BRICK_ARRAY(dset,ival) ;
00641 
00642       if( old_brick == NULL ){
00643          THD_delete_3dim_dataset( new_dset , False ) ;
00644          return NULL ;
00645       }
00646 
00647       memcpy( new_brick , old_brick , nbytes ) ;
00648    }
00649 
00650    return new_dset ;
00651 }
00652 
00653 
00654 
00655 
00656 
00657 
00658 
00659 void check_output_file 
00660 (
00661   THD_3dim_dataset * dset,      
00662   char * filename               
00663 )
00664 
00665 {
00666   THD_3dim_dataset * new_dset=NULL;   
00667   int ierror;                         
00668   
00669   
00670   
00671   new_dset = EDIT_empty_copy( dset ) ;
00672   
00673   
00674   ierror = EDIT_dset_items( new_dset ,
00675                             ADN_prefix , filename ,
00676                             ADN_label1 , filename ,
00677                             ADN_self_name , filename ,
00678                             ADN_type , ISHEAD(dset) ? HEAD_FUNC_TYPE : 
00679                                                       GEN_FUNC_TYPE ,
00680                             ADN_none ) ;
00681   
00682   if( ierror > 0 ){
00683     fprintf(stderr,
00684             "*** %d errors in attempting to create output dataset!\n", ierror ) ;
00685     exit(1) ;
00686   }
00687   
00688   if( THD_is_file(new_dset->dblk->diskptr->header_name) ){
00689     fprintf(stderr,
00690             "*** Output dataset file %s already exists--cannot continue!\a\n",
00691             new_dset->dblk->diskptr->header_name ) ;
00692     exit(1) ;
00693   }
00694   
00695      
00696   THD_delete_3dim_dataset( new_dset , False ) ; new_dset = NULL ;
00697   
00698 }
00699 
00700 
00701 
00702 
00703 
00704 
00705 
00706 void eval_registration
00707 (
00708   IR_options * option_data,       
00709   THD_3dim_dataset * old_dset,    
00710   THD_3dim_dataset * new_dset,    
00711   THD_3dim_dataset * base_dset,   
00712   int base,                       
00713   float * old_rms_array,          
00714   float * new_rms_array           
00715   )
00716      
00717 {
00718   int nx, ny, nz, nxyz;
00719   int ix, jy, kz;
00720   int ixyz;
00721   int datum, base_datum;
00722   float old_sse, new_sse;
00723   float diff;
00724   float old_rmse, new_rmse;
00725   int ivolume, num_volumes;
00726   byte  * bold = NULL, * bnew = NULL, * bbase = NULL;
00727   short * sold = NULL, * snew = NULL, * sbase = NULL;
00728   float * fold = NULL, * fnew = NULL, * fbase = NULL;
00729   float float_base, float_old, float_new;
00730 
00731 
00732   
00733   nx = old_dset->daxes->nxx;
00734   ny = old_dset->daxes->nyy;
00735   nz = old_dset->daxes->nzz;
00736   nxyz = nx * ny * nz;
00737   num_volumes = DSET_NUM_TIMES (old_dset);
00738   datum       = DSET_BRICK_TYPE (new_dset,0) ;
00739   base_datum  = DSET_BRICK_TYPE (base_dset,0);
00740 
00741 
00742   
00743   switch ( base_datum )
00744     { 
00745     case MRI_byte:
00746       bbase = (byte *) DSET_ARRAY(base_dset,base);  break;
00747       
00748     case MRI_short:
00749       sbase = (short *) DSET_ARRAY(base_dset,base);  break;
00750 
00751     case MRI_float:
00752       fbase = (float *) DSET_ARRAY(base_dset,base);  break;
00753     }
00754 
00755 
00756   for (ivolume = 0;  ivolume < num_volumes; ivolume++)
00757     {
00758       old_sse = 0.0;
00759       new_sse = 0.0;
00760 
00761       
00762       switch ( datum )
00763         {  
00764         case MRI_byte:
00765           bold = (byte *) DSET_ARRAY(old_dset,ivolume);  
00766           bnew = (byte *) DSET_ARRAY(new_dset,ivolume);  break;
00767           
00768         case MRI_short:
00769           sold = (short *) DSET_ARRAY(old_dset,ivolume);  
00770           snew = (short *) DSET_ARRAY(new_dset,ivolume);  break;
00771           
00772         case MRI_float:
00773           fold = (float *) DSET_ARRAY(old_dset,ivolume);  
00774           fnew = (float *) DSET_ARRAY(new_dset,ivolume);  break;
00775         }
00776 
00777       
00778       for (kz = 0;  kz < nz;  kz++)
00779         for (jy = 0;  jy < ny;  jy++)
00780           for (ix = 0;  ix < nx;  ix++)
00781             {
00782               ixyz = ix + jy*nx + kz*nx*ny;
00783 
00784               
00785               switch ( base_datum )
00786                 { 
00787                 case MRI_byte:   float_base = (float) bbase[ixyz];  break;
00788                   
00789                 case MRI_short:  float_base = (float) sbase[ixyz];  break;
00790                   
00791                 case MRI_float:  float_base = fbase[ixyz];  break;
00792                 }
00793               
00794               
00795               switch ( datum )
00796                 {  
00797                 case MRI_byte:
00798                   float_old = (float) bold[ixyz];  
00799                   float_new = (float) bnew[ixyz];  break;
00800                   
00801                 case MRI_short:
00802                   float_old = (float) sold[ixyz];  
00803                   float_new = (float) snew[ixyz];  break;
00804                   
00805                 case MRI_float:
00806                   float_old = fold[ixyz];  
00807                   float_new = fnew[ixyz];  break;
00808                 }
00809 
00810               diff = float_old - float_base;
00811               old_sse += diff*diff;
00812               diff = float_new - float_base;
00813               new_sse += diff*diff;
00814             }
00815       
00816       old_rmse = sqrt (old_sse / nxyz);
00817       new_rmse = sqrt (new_sse / nxyz);
00818 
00819       if (option_data->debug)
00820         printf ("Volume = %d   OLD RMSE = %f   NEW RMSE = %f \n", 
00821                 ivolume, old_rmse, new_rmse);
00822       
00823       old_rms_array[ivolume] = old_rmse;
00824       new_rms_array[ivolume] = new_rmse;
00825 
00826     }
00827 
00828 }
00829 
00830 
00831 
00832 
00833 
00834 
00835 
00836 
00837 
00838 #define FREEUP(x) do{if((x) != NULL){free((x)); (x)=NULL;}}while(0)
00839 
00840 #define FREE_WORKSPACE                             \
00841   do{ FREEUP(bptr) ; FREEUP(sptr) ; FREEUP(fptr) ; \
00842       FREEUP(bout) ; FREEUP(sout) ; FREEUP(fout) ; \
00843       FREEUP(dxar) ; FREEUP(dyar) ; FREEUP(phiar); \
00844     } while(0) ;
00845 
00846 
00847 char * IMREG_main 
00848 (
00849   IR_options * opt,
00850   vector * state_history,
00851   float * old_rms_array,
00852   float * new_rms_array
00853 )
00854 {
00855    THD_3dim_dataset * old_dset , * new_dset ;  
00856    THD_3dim_dataset * base_dset;               
00857    char * new_prefix ;                         
00858    int base , ntime , datum , nx,ny,nz , ii,kk , npix ;
00859    float                      dx,dy,dz ;
00860    int base_datum;
00861    MRI_IMARR * ims_in , * ims_out ;
00862    MRI_IMAGE * im , * imbase ;
00863 
00864    byte   ** bptr = NULL , * bbase = NULL, ** bout = NULL ;
00865    short  ** sptr = NULL , * sbase = NULL, ** sout = NULL ; 
00866    float  ** fptr = NULL , * fbase = NULL, ** fout = NULL ;
00867 
00868    float * dxar = NULL , * dyar = NULL , * phiar = NULL ;
00869 
00870    int it;
00871 
00872    
00873    
00874 
00875    old_dset = THD_open_one_dataset(opt->input_filename) ;   
00876                                                       
00877    if( old_dset == NULL )
00878       return "*************************\n"
00879              "Cannot find Input Dataset\n"
00880              "*************************"  ;
00881 
00882    ntime = DSET_NUM_TIMES(old_dset) ;
00883    if( ntime < 2 )
00884       return "*****************************\n"
00885              "Dataset has only 1 time point\n"
00886              "*****************************"  ;
00887 
00888    ii = DSET_NVALS_PER_TIME(old_dset) ;
00889    if( ii > 1 )
00890       return "************************************\n"
00891              "Dataset has > 1 value per time point\n"
00892              "************************************"  ;
00893 
00894    nx = old_dset->daxes->nxx ; dx = old_dset->daxes->xxdel ;
00895    ny = old_dset->daxes->nyy ; dy = old_dset->daxes->yydel ; npix = nx*ny ;
00896    nz = old_dset->daxes->nzz ; dz = old_dset->daxes->zzdel ;
00897 
00898    if( nx != ny || fabs(dx) != fabs(dy) ){
00899 
00900      if (opt->debug)
00901        fprintf(stderr,"\nIMREG: nx=%d ny=%d nz=%d  dx=%f dy=%f dz=%f\n",
00902                nx,ny,nz,dx,dy,dz ) ;
00903 
00904       return "***********************************\n"
00905              "Dataset does not have square slices\n"
00906              "***********************************"  ;
00907    }
00908 
00909    new_prefix = opt->new_prefix;     
00910    if (new_prefix == NULL)           
00911       return "************************\n"
00912              "Output Prefix is illegal\n"
00913              "************************"  ;
00914 
00915    
00916    check_output_file (old_dset, new_prefix);
00917 
00918 
00919    
00920 
00921    if (opt->base_filename == NULL)
00922      base_dset = old_dset;
00923    else
00924      {
00925        base_dset = THD_open_one_dataset(opt->base_filename) ;   
00926                                                   
00927        if( base_dset == NULL )
00928          return "************************\n"
00929                 "Cannot find Base Dataset\n"
00930                 "************************"  ;
00931 
00932        if ( (nx != base_dset->daxes->nxx) || (dx != base_dset->daxes->xxdel)
00933          || (ny != base_dset->daxes->nyy) || (dy != base_dset->daxes->yydel)
00934          || (nz != base_dset->daxes->nzz) || (dz != base_dset->daxes->zzdel) )
00935          {
00936            if (opt->debug)
00937                {
00938                  fprintf(stderr,"\nIMREG: Input Dataset:\n");
00939                  fprintf(stderr,"nx=%d ny=%d nz=%d  dx=%f dy=%f dz=%f\n",
00940                      nx,ny,nz,dx,dy,dz ) ;
00941 
00942                  fprintf(stderr,"\nIMREG: Base Dataset:\n");
00943                  fprintf(stderr,"nx=%d ny=%d nz=%d  dx=%f dy=%f dz=%f\n",
00944                          base_dset->daxes->nxx,   base_dset->daxes->nyy,
00945                          base_dset->daxes->nzz,   base_dset->daxes->xxdel,
00946                          base_dset->daxes->yydel, base_dset->daxes->zzdel) ;
00947                }
00948            return "*************************************************\n"
00949                   "Base Dataset is not compatible with Input Dataset\n"
00950                   "*************************************************"  ;
00951          }
00952      }
00953 
00954    base_datum = DSET_BRICK_TYPE(base_dset,0);
00955 
00956    base = opt->base_vol_index;
00957 
00958    if( base >= DSET_NUM_TIMES(base_dset))
00959       return "******************************\n"
00960              "Base image number is too large\n"
00961              "******************************"  ;
00962 
00963 
00964    
00965    if (opt->nofine)
00966      mri_align_params( 0 , 0.0,0.0,0.0 , 0.0,0.0,0.0 ) ;
00967    else{
00968       float fsig , fdxy , fdph ;
00969       fsig = opt->blur * 0.42466090;
00970       fdxy = opt->dxy;
00971       fdph = opt->dphi;
00972       mri_align_params( 0 , 0.0,0.0,0.0 , fsig,fdxy,fdph ) ;
00973 
00974       if (opt->debug)
00975         fprintf(stderr,"Set fine params = %f %f %f\n",fsig,fdxy,fdph) ; 
00976    }
00977 
00978    
00979 
00980    if (opt->debug)
00981      fprintf(stderr,"IMREG: loading dataset\n") ;
00982 
00983 
00984    DSET_load( old_dset ) ;
00985    
00986    if (opt->base_filename != NULL)
00987      DSET_load (base_dset);
00988 
00989    
00990 
00991    if (opt->debug)
00992      fprintf(stderr,"IMREG: Copying dataset\n") ;
00993 
00994 
00995    new_dset = copy_dset( old_dset , new_prefix ) ;
00996    if( new_dset == NULL )
00997       return "****************************\n"
00998              "Failed to copy input dataset\n"
00999              "****************************"  ;
01000 
01001    
01002 
01003    if (opt->debug)
01004      fprintf(stderr,"IMREG: making empty images\n") ;
01005 
01006 
01007    datum = DSET_BRICK_TYPE(new_dset,0) ;
01008 
01009    INIT_IMARR(ims_in) ;
01010    for( ii=0 ; ii < ntime ; ii++ ){
01011       im = mri_new_vol_empty( nx , ny , 1 , datum ) ;
01012       ADDTO_IMARR(ims_in,im) ;
01013    }
01014 
01015    imbase = mri_new_vol_empty( nx , ny , 1 , base_datum ) ;
01016 
01017    dxar  = (float *) malloc( sizeof(float) * ntime ) ;
01018    dyar  = (float *) malloc( sizeof(float) * ntime ) ;
01019    phiar = (float *) malloc( sizeof(float) * ntime ) ;
01020 
01021    
01022 
01023    if (opt->debug)
01024      fprintf(stderr,"IMREG: getting input brick pointers\n") ;
01025 
01026 
01027    switch( datum ){  
01028       case MRI_byte:
01029          bptr  = (byte **) malloc( sizeof(byte *) * ntime ) ;
01030          bout  = (byte **) malloc( sizeof(byte *) * ntime ) ;
01031          for( ii=0 ; ii < ntime ; ii++ ){
01032             bptr[ii]  = (byte *) DSET_ARRAY(old_dset,ii) ;
01033             bout[ii]  = (byte *) DSET_ARRAY(new_dset,ii) ;
01034          }
01035       break ;
01036 
01037       case MRI_short:
01038          sptr  = (short **) malloc( sizeof(short *) * ntime ) ;
01039          sout  = (short **) malloc( sizeof(short *) * ntime ) ;
01040          for( ii=0 ; ii < ntime ; ii++ ){
01041             sptr[ii]  = (short *) DSET_ARRAY(old_dset,ii) ;
01042             sout[ii]  = (short *) DSET_ARRAY(new_dset,ii) ;
01043          }
01044 
01045          if (opt->debug)
01046            fprintf(stderr,"IMREG: sptr[0] = %p  sout[0] = %p\n",
01047                    sptr[0],sout[0]) ;
01048 
01049       break ;
01050 
01051       case MRI_float:
01052          fptr  = (float **) malloc( sizeof(float *) * ntime ) ;
01053          fout  = (float **) malloc( sizeof(float *) * ntime ) ;
01054          for( ii=0 ; ii < ntime ; ii++ ){
01055             fptr[ii]  = (float *) DSET_ARRAY(old_dset,ii) ;
01056             fout[ii]  = (float *) DSET_ARRAY(new_dset,ii) ;
01057          }
01058       break ;
01059    }
01060 
01061    switch( base_datum ){  
01062       case MRI_byte:
01063         bbase = (byte *) DSET_ARRAY(base_dset,base) ; 
01064       break ;
01065 
01066       case MRI_short:
01067         sbase = (short *) DSET_ARRAY(base_dset,base) ;
01068         if (opt->debug)
01069           fprintf(stderr,"IMREG: sbase[%d] = %p \n", base, sbase) ;
01070       break ;
01071 
01072       case MRI_float:
01073         fbase = (float *) DSET_ARRAY(base_dset,base) ;
01074       break ;
01075    }
01076 
01077    
01078 
01079    for( kk=0 ; kk < nz ; kk++ ){
01080 
01081       
01082 
01083      if (opt->debug)
01084        fprintf(stderr,"IMREG: slice %d -- setup input images\n",kk) ;
01085 
01086 
01087       for( ii=0 ; ii < ntime ; ii++ ){
01088          im = IMARR_SUBIMAGE(ims_in,ii) ;
01089          switch( datum ){
01090             case MRI_byte:  
01091               mri_fix_data_pointer( bptr[ii] + kk*npix, im ) ; break ;
01092             case MRI_short: 
01093               mri_fix_data_pointer( sptr[ii] + kk*npix, im ) ; break ;
01094             case MRI_float: 
01095               mri_fix_data_pointer( fptr[ii] + kk*npix, im ) ; break ;
01096          }
01097       }
01098 
01099       
01100 
01101       if (opt->debug)
01102         fprintf(stderr,"IMREG: slice %d -- setup base image\n",kk) ;
01103 
01104 
01105       switch( base_datum ){
01106          case MRI_byte:  
01107            mri_fix_data_pointer( bbase + kk*npix, imbase ) ; break ;
01108          case MRI_short: 
01109            mri_fix_data_pointer( sbase + kk*npix, imbase ) ; break ;
01110          case MRI_float: 
01111            mri_fix_data_pointer( fbase + kk*npix, imbase ) ; break ;
01112       }
01113 
01114       
01115 
01116       if (opt->debug)
01117         fprintf(stderr,"IMREG: slice %d -- register\n",kk) ;
01118 
01119 
01120       ims_out = mri_align_dfspace( imbase , NULL , ims_in ,
01121                                    ALIGN_REGISTER_CODE , dxar,dyar,phiar ) ;
01122 
01123       if( ims_out == NULL )
01124         fprintf(stderr,"IMREG: mri_align_dfspace return NULL\n") ;
01125 
01126       
01127       
01128       if (opt->dprefix != NULL)
01129         for (ii = 0;  ii < ntime;  ii++)
01130           {
01131             it = ii*nz + z_to_t[kk];
01132             if (opt->dmm)
01133               {
01134                 state_history[it].elts[1] = dxar[ii] * dx;
01135                 state_history[it].elts[2] = dyar[ii] * dy;
01136               }
01137             else
01138               {
01139                 state_history[it].elts[1] = dxar[ii];
01140                 state_history[it].elts[2] = dyar[ii];
01141               }
01142 
01143             state_history[it].elts[3] = (180.0/PI)*phiar[ii];
01144           }
01145       
01146 
01147       
01148 
01149 
01150       if (opt->debug)
01151         fprintf(stderr,"IMREG: slice %d -- put output back into dataset\n",kk);
01152 
01153 
01154       for( ii=0 ; ii < ntime ; ii++ ){
01155          switch( datum ){
01156            case MRI_byte:
01157               im = mri_to_mri( MRI_byte , IMARR_SUBIMAGE(ims_out,ii) ) ;
01158               memcpy( bout[ii] + kk*npix , MRI_BYTE_PTR(im) , 
01159                       sizeof(byte)*npix ) ;
01160               mri_free(im) ;
01161            break ;
01162 
01163            case MRI_short:
01164 
01165              if (opt->debug)
01166                if( ii==0 )
01167                  fprintf(stderr,"IMREG: conversion to short at ii=%d\n",ii) ;
01168 
01169               im = mri_to_mri( MRI_short , IMARR_SUBIMAGE(ims_out,ii) ) ;
01170 
01171               if (opt->debug)
01172                 if( ii==0 )
01173                   fprintf(stderr,"IMREG: copying to %p from %p\n",
01174                           sout[ii] + kk*npix,MRI_SHORT_PTR(im)) ;
01175 
01176 
01177               memcpy( sout[ii] + kk*npix , MRI_SHORT_PTR(im) , 
01178                       sizeof(short)*npix ) ;
01179 
01180               if (opt->debug)
01181                 if( ii==0 )
01182                   fprintf(stderr,"IMREG: freeing\n") ;
01183 
01184 
01185               mri_free(im) ;
01186            break ;
01187 
01188            case MRI_float:
01189               im = IMARR_SUBIMAGE(ims_out,ii) ;
01190               memcpy( fout[ii] + kk*npix , MRI_FLOAT_PTR(im) , 
01191                       sizeof(float)*npix ) ;
01192            break ;
01193          }
01194       }
01195 
01196       
01197 
01198       if (opt->debug)
01199         fprintf(stderr,"IMREG: destroying aligned output\n") ;
01200 
01201 
01202       DESTROY_IMARR( ims_out ) ;
01203    }
01204 
01205    
01206 
01207    if (opt->debug)
01208      fprintf(stderr,"IMREG: destroy workspaces\n") ;
01209 
01210 
01211    mri_clear_data_pointer(imbase) ; mri_free(imbase) ;
01212    for( ii=0 ; ii < ntime ; ii++ ){
01213       im = IMARR_SUBIMAGE(ims_in,ii) ;
01214       mri_clear_data_pointer(im) ;
01215    }
01216    DESTROY_IMARR(ims_in) ;
01217    FREE_WORKSPACE ;
01218 
01219    
01220 
01221    if (opt->debug)
01222      fprintf(stderr,"IMREG: write new dataset to disk\n") ;
01223 
01224 
01225   
01226    tross_Copy_History( old_dset , new_dset ) ;
01227    if( commandline != NULL )
01228      tross_Append_History( new_dset , commandline ) ;
01229 
01230 
01231   THD_load_statistics( new_dset ) ;
01232   THD_write_3dim_dataset( NULL,NULL , new_dset , True ) ;
01233   
01234 
01235   
01236   if (opt->rprefix != NULL)
01237     eval_registration (opt, old_dset, new_dset, base_dset, base, 
01238                        old_rms_array, new_rms_array);
01239 
01240 
01241      
01242   THD_delete_3dim_dataset( old_dset , False ) ; old_dset = NULL ;
01243   THD_delete_3dim_dataset( new_dset , False ) ; new_dset = NULL ;
01244   if (opt->base_filename != NULL)
01245     THD_delete_3dim_dataset( base_dset , False ) ; base_dset = NULL ;
01246     
01247 
01248 
01249    return NULL ;  
01250 }
01251 
01252 
01253 
01254 
01255 
01256 
01257 
01258 
01259 void output_rms_arrays
01260 (
01261   IR_options * option_data,     
01262   THD_3dim_dataset * dset,      
01263   float * old_rms_array,        
01264   float * new_rms_array         
01265 )
01266 
01267 {
01268   int it;                                  
01269   int ts_length;                             
01270   char filename[MAX_NAME_LENGTH];          
01271   FILE * old_rms_file , * new_rms_file;    
01272 
01273 
01274   
01275   ts_length = DSET_NUM_TIMES(dset);
01276 
01277 
01278   
01279   strcpy (filename, option_data->rprefix);
01280   strcat (filename, ".oldrms");
01281   old_rms_file = fopen (filename, "w");
01282   strcpy (filename, option_data->rprefix);
01283   strcat (filename, ".newrms");
01284   new_rms_file = fopen (filename, "w");
01285 
01286 
01287   
01288   for (it = 0;  it < ts_length;  it++)
01289     {
01290       fprintf (old_rms_file, "%d  %f\n" , it, old_rms_array[it]);
01291       fprintf (new_rms_file, "%d  %f\n" , it, new_rms_array[it]);
01292     }
01293 
01294 
01295   
01296   fclose (old_rms_file);
01297   fclose (new_rms_file);
01298 
01299 }
01300 
01301 
01302 
01303 
01304 
01305 
01306  
01307 float get_time  (int ivolume, int iz,  THD_3dim_dataset * dset)
01308 
01309 {
01310   float time;
01311   float z;
01312 
01313 
01314   z = iz * dset->taxis->dz_sl + dset->taxis->zorg_sl;
01315   time = THD_timeof (ivolume, z, dset->taxis);
01316   
01317   if (dset->taxis->units_type == UNITS_MSEC_TYPE)
01318     time /= 1000.0;
01319 
01320   return (time);
01321 }
01322 
01323 
01324 
01325 
01326 
01327 
01328 
01329 
01330 void output_state_history
01331 (
01332   IR_options * option_data,     
01333   THD_3dim_dataset * dset,
01334   vector * state_history
01335 )
01336 
01337 {
01338   int iv;                           
01339   int ts_length;                    
01340   int num_slices;                   
01341   int num_vectors;                  
01342   int ivolume;                      
01343   int iz;                           
01344   float t;                          
01345   char filename[MAX_NAME_LENGTH];   
01346 
01347   FILE * dx_file, * dy_file, * psi_file;   
01348 
01349 
01350   
01351   num_slices = dset->taxis->nsl;
01352   ts_length = DSET_NUM_TIMES(dset);
01353 
01354   if ( num_slices <= 0 )            
01355       num_slices = dset->daxes->nzz;
01356 
01357 
01358   
01359   num_vectors = ts_length * num_slices;
01360 
01361 
01362   
01363   strcpy (filename, option_data->dprefix);
01364   strcat (filename, ".dx");
01365   dx_file = fopen (filename, "w");
01366 
01367   strcpy (filename, option_data->dprefix);
01368   strcat (filename, ".dy");
01369   dy_file = fopen (filename, "w");
01370 
01371   strcpy (filename, option_data->dprefix);
01372   strcat (filename, ".psi");
01373   psi_file = fopen (filename, "w");
01374 
01375   
01376   
01377   for (iv = 0;  iv < num_vectors;  iv++)
01378     {
01379       ivolume = iv / num_slices;
01380       iz = t_to_z[iv % num_slices];
01381       t = get_time (ivolume, iz, dset);
01382       fprintf (dx_file,  "%f   %f\n", t, state_history[iv].elts[1]);
01383       fprintf (dy_file,  "%f   %f\n", t, state_history[iv].elts[2]);
01384       fprintf (psi_file, "%f   %f\n", t, state_history[iv].elts[3]);
01385     }
01386 
01387 
01388   
01389   fclose (dx_file);
01390   fclose (dy_file);
01391   fclose (psi_file);
01392 }
01393 
01394 
01395 
01396 
01397 
01398 
01399 
01400 void output_results  
01401 (
01402   IR_options * option_data,     
01403   vector * state_history,       
01404   float * old_rms_array,        
01405   float * new_rms_array         
01406 )
01407 
01408 {
01409   THD_3dim_dataset * dset;
01410 
01411 
01412   read_dataset (option_data->input_filename, &dset);
01413 
01414 
01415   
01416   if (option_data->dprefix != NULL)
01417     output_state_history (option_data, dset, state_history);
01418 
01419 
01420   
01421   if (option_data->rprefix != NULL)
01422     output_rms_arrays (option_data, dset, old_rms_array, new_rms_array);
01423 
01424 
01425   THD_delete_3dim_dataset (dset, False);   dset = NULL;
01426 
01427 }
01428 
01429 
01430 
01431 
01432 
01433 
01434 
01435 void terminate_program  
01436 (
01437   IR_options ** option_data,
01438   vector ** state_history,       
01439   float ** old_rms_array,        
01440   float ** new_rms_array         
01441 )
01442 
01443 {
01444   THD_3dim_dataset * dset = NULL;   
01445   int num_slices;                   
01446   int ts_length;                    
01447   int num_vectors;                  
01448   int i;                            
01449 
01450 
01451   
01452   read_dataset ((*option_data)->input_filename, &dset);
01453   num_slices = dset->taxis->nsl;
01454 
01455   if ( num_slices <= 0 )            
01456       num_slices = dset->daxes->nzz;
01457 
01458   ts_length = DSET_NUM_TIMES(dset);
01459   num_vectors = ts_length * num_slices;
01460   THD_delete_3dim_dataset (dset, False);   dset = NULL;
01461 
01462 
01463   
01464   free (*option_data);     *option_data = NULL;
01465   free (t_to_z);           t_to_z = NULL;
01466   free (z_to_t);           z_to_t = NULL;
01467 
01468   
01469   if (*old_rms_array != NULL)
01470     { free (*old_rms_array);   *old_rms_array = NULL; }
01471   if (*new_rms_array != NULL)
01472     { free (*new_rms_array);   *new_rms_array = NULL; }
01473 
01474 
01475   
01476   if (*state_history != NULL)
01477     {
01478       for (i = 0;  i < num_vectors;  i++)
01479         vector_destroy (&((*state_history)[i]));
01480       free (*state_history);   *state_history = NULL;
01481     }
01482 
01483 }
01484 
01485 
01486 
01487 
01488 int main
01489 (
01490   int argc,                    
01491   char ** argv                  
01492 )
01493 
01494 {
01495   IR_options * option_data = NULL;     
01496   char * chptr;                        
01497   vector * state_history = NULL;       
01498   float * old_rms_array = NULL;        
01499   float * new_rms_array = NULL;        
01500 
01501 
01502    
01503   
01504   printf ("\n\n");
01505   printf ("Program:          %s \n", PROGRAM_NAME);
01506   printf ("Initial Release:  %s \n", PROGRAM_INITIAL);
01507   printf ("Latest Revision:  %s \n", PROGRAM_LATEST);
01508   printf ("\n");
01509 
01510   
01511   
01512   initialize_program (argc, argv, &option_data, &state_history, 
01513                       &old_rms_array, &new_rms_array);
01514 
01515 
01516   
01517   chptr = IMREG_main (option_data, state_history,
01518                       old_rms_array, new_rms_array);
01519 
01520 
01521   
01522   if (chptr != NULL)   
01523     {
01524       printf ("%s \n\n", chptr);
01525       exit(1);
01526     }
01527 
01528 
01529   
01530   output_results (option_data, state_history, 
01531                   old_rms_array, new_rms_array);
01532 
01533 
01534   
01535   terminate_program (&option_data, &state_history,
01536                      &old_rms_array, &new_rms_array);
01537  
01538 }
01539 
01540 
01541