00001 
00002 
00003 
00004 
00005 
00006 
00007 #include "afni.h"
00008 #include "parser.h"
00009 
00010 #if 0
00011 # define VMCHECK do{ if(verbose == 2) MCHECK; } while(0)
00012 #else
00013 # define VMCHECK 
00014 #endif
00015 
00016 #define TCP_CONTROL "tcp:*:7954"      
00017 #define INFO_SIZE  (32*1024)          
00018 #define SHM_CHILD  "shm:afnibahn:32K" 
00019 
00020 #define SHORT_DELAY      1            
00021 #define LONG_DELAY      10
00022 
00023 #ifndef ALLOW_PLUGINS
00024 #  error "Plugins not properly set up -- see machdep.h"
00025 #endif
00026 
00027 #define ALLOW_REGISTRATION
00028 
00029 #ifdef ALLOW_REGISTRATION
00030 #  include "coxplot.h"
00031 #endif
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074 
00075 
00076 
00077 #include <sys/types.h>
00078 #include <unistd.h>
00079 #include <sys/wait.h>
00080 #include <signal.h>
00081 #include <ctype.h>
00082 
00083 #define DTYPE_2DZ   77
00084 #define DTYPE_2DZT  78
00085 #define DTYPE_3D    79
00086 #define DTYPE_3DT   80
00087 
00088 #define ZORDER_ALT  33
00089 #define ZORDER_SEQ  34
00090 #define ZORDER_EXP  39
00091 #define NZMAX       1024
00092 
00093 #define RT_MAX_EXPR     1024    
00094 #define RT_MAX_PREFIX    100    
00095 
00096 #define RT_MP_DEF_PORT 53214    
00097 
00098 #define DEFAULT_XYFOV    240.0
00099 #define DEFAULT_XYMATRIX  64
00100 #define DEFAULT_ZDELTA     5.0
00101 #define DEFAULT_ZNUM       2
00102 #define DEFAULT_TR         1.0
00103 
00104 #define RT_NBUF          INFO_SIZE
00105 #define NNAME            128
00106 
00107 #define ORCODE(aa) \
00108   ( (aa)=='R' ? ORI_R2L_TYPE : (aa)=='L' ? ORI_L2R_TYPE : \
00109     (aa)=='P' ? ORI_P2A_TYPE : (aa)=='A' ? ORI_A2P_TYPE : \
00110     (aa)=='I' ? ORI_I2S_TYPE : (aa)=='S' ? ORI_S2I_TYPE : ILLEGAL_TYPE )
00111 
00112 #define MAX_CHAN 32    
00113 
00114 static int        num_open_controllers ;                       
00115 static int            open_controller_index[MAX_CONTROLLERS] ;
00116 static Three_D_View * open_controller      [MAX_CONTROLLERS] ;
00117 
00118 typedef struct {
00119 
00120    int info_ok , no_data ;        
00121 
00122    int         image_mode ;       
00123    void      * image_handle ;
00124    MRI_IMAGE * image_space ;
00125 
00126    char     name_data[NNAME] ;    
00127    IOCHAN * ioc_data ;            
00128 
00129    char     name_info[NNAME] ;    
00130    IOCHAN * ioc_info ;            
00131    pid_t    child_info ;          
00132    double   child_start_time ;    
00133 
00134    int   nxx  ,nyy  ,nzz  ,       
00135          orcxx,orcyy,orczz ;      
00136 
00137    float xxfov , yyfov , zzfov ;  
00138    float dxx   , dyy   , dzz ,    
00139          xxorg,yyorg,zzorg ;      
00140    int   xxdcode,yydcode,zzdcode; 
00141 
00142    float xxoff , yyoff , zzoff ;  
00143 
00144    float zgap ;                   
00145                                   
00146 
00147    int   xcen ,ycen ,zcen  ;      
00148 
00149    float tr ;                     
00150    int   nr ;                     
00151 
00152    int   dtype ;                  
00153    int   zorder ;                 
00154    int   zorder_lock ;            
00155    int   tpattern ;               
00156    int   nzseq , zseq[NZMAX] ;    
00157    int   datum ;                  
00158    int   swap_on_read ;           
00159 
00160    int   nbuf ;                   
00161    char  buf[RT_NBUF] ;           
00162 
00163    char root_prefix[THD_MAX_PREFIX] ;  
00164 
00165    
00166 
00167 
00168    int num_chan ;                               
00169    int cur_chan ;                               
00170 
00171    int afni_status[MAX_CHAN] ;                  
00172    THD_3dim_dataset * dset[MAX_CHAN] ;          
00173    Three_D_View * im3d[MAX_CHAN] ;              
00174    THD_session * sess[MAX_CHAN] ;               
00175    int           sess_num[MAX_CHAN] ;           
00176    char * sbr[MAX_CHAN] ;                       
00177    char * im[MAX_CHAN] ;                        
00178    int nvol[MAX_CHAN] ;                         
00179    int nsl[MAX_CHAN] ;                          
00180 
00181    int sbr_size ;                 
00182    int imsize ;                   
00183    MRI_IMARR * bufar ;            
00184 
00185    THD_3dim_dataset * func_dset ; 
00186    int func_status ;              
00187    int func_code ;                
00188    int func_condit ;              
00189    int_func * func_func ;         
00190 
00191 #ifdef ALLOW_REGISTRATION
00192    
00193 
00194    THD_3dim_dataset * reg_dset ;      
00195    MRI_2dalign_basis ** reg_2dbasis ; 
00196    int reg_base_index ;               
00197    int reg_mode ;                     
00198    int reg_status ;                   
00199    int reg_nvol ;                     
00200    int reg_graph ;                    
00201    int reg_nest ;                     
00202    float * reg_tim , * reg_dx  ,
00203          * reg_dy  , * reg_phi  ;     
00204 
00205    
00206 
00207    float * reg_dz , * reg_theta , * reg_psi , * reg_rep ;
00208    MRI_3dalign_basis * reg_3dbasis ;
00209    int iha , ax1,hax1 , ax2,hax2 , ax3,hax3 ;
00210    MEM_topshell_data * mp ;
00211 
00212    int   reg_resam , reg_final_resam ;
00213    int   reg_graph_xnew, reg_graph_ynew ;
00214    float reg_graph_xr , reg_graph_yr ;
00215 
00216    
00217    PARSER_code * p_code ;                       
00218    char          p_expr   [RT_MAX_EXPR+1] ;     
00219    double        p_atoz   [26] ;                
00220    int           p_has_sym[26] ;                
00221    int           p_max_sym ;                    
00222    float       * reg_eval ;                     
00223 
00224    
00225    int           mp_tcp_use ;     
00226    int           mp_tcp_sd ;      
00227    int           mp_port ;        
00228    char          mp_host[128] ;   
00229    int           mp_nmsg ;        
00230    int           mp_npsets ;      
00231 #endif
00232 
00233    double elapsed , cpu ;         
00234    double last_elapsed ;
00235    int    last_nvol ;
00236 
00237    int    num_note ;              
00238    char **note ;
00239 
00240    int    marked_for_death ;      
00241 
00242 } RT_input ;
00243 
00244 #define SHOW_TIMES                                              \
00245   fprintf(stderr,"RT: cpu time = %.2f  elapsed time = %.2f\n" , \
00246           PLUTO_cpu_time()-rtin->cpu , PLUTO_elapsed_time()-rtin->elapsed )
00247 
00248 
00249 
00250 static char helpstring[] =
00251    " Purpose: Controlling realtime dataset acquisitions.\n"
00252    "\n"
00253    " USAGE:\n"
00254    " Set the controls to the state you want BEFORE realtime image input\n"
00255    " begins, then press one of the 'Set' buttons to send the control\n"
00256    " information to AFNI.\n"
00257    "\n"
00258    " INPUTS:\n"
00259    " Images Only = If 'No', then the input images will be used\n"
00260    "                 to assemble a dataset.  If 'Yes', then the\n"
00261    "                 input images will be displayed but not made\n"
00262    "                 into a dataset or otherwise saved.\n"
00263    "                 (They will only be stored in the image viewer\n"
00264    "                  that is opened - you can use 'Save:bkg' to\n"
00265    "                  write them to disk, if desired, before\n"
00266    "                  closing the 'Realtime Images' viewer window.)\n"
00267    "               If this input is 'Yes', then none of the other\n"
00268    "                 inputs below have much meaning!\n"
00269    "\n"
00270    " Root     = Root prefix to be used for new datasets.\n"
00271    "              The actual prefix will be of the form Root#001\n"
00272    "\n"
00273    " Update   = How often AFNI's display will be updated\n"
00274    "             = How many 3D bricks are gathered before\n"
00275    "               the images and graphs are redrawn:\n"
00276    "                0 --> don't update until all data is acquired\n"
00277    "                1 --> redraw images and graphs every time\n"
00278    "                2 --> redraw every other brick, etc.\n"
00279    "\n"
00280    " Function = Controls what kind of function analysis is done\n"
00281    "              during realtime input of time dependent datasets.\n"
00282    "\n"
00283    " Verbose  = If set to 'Yes', the plugin will print out progress\n"
00284    "              reports as information flows into it.\n"
00285    "              If set to 'Very', prints out LOTS of information.\n"
00286 #ifdef ALLOW_REGISTRATION
00287    "\n"
00288    " Registration = If activated, image registration will take place\n"
00289    "                  either in realtime or at the end of image acquisition.\n"
00290    "                * The un-registered dataset will be named something like\n"
00291    "                  Root#001 and the aligned dataset Root#001%reg2D.\n"
00292    "                * You can choose either 2D (slice-wise) registration,\n"
00293    "                  or 3D (volume-wise) registration.\n"
00294    "                * The 3D case also allows a quicker mode where the volumes\n"
00295    "                  aren't actually registered, but estimates of the motion\n"
00296    "                  parameters are computed for graphing purposes.  This is\n"
00297    "                  done in realtime.\n"
00298    "                * If 3D realtime or estimate modes are chosen, the motion\n"
00299    "                  parameters can be graphed in realtime - see 'Graph' below.\n"
00300    " Base Image   = The value sets the time index in the new dataset to which\n"
00301    "                  the alignment will take place.\n"
00302    " Resampling   = Determines the interpolation method used:\n"
00303    "                  Cubic     = fastest, least accurate interpolation\n"
00304    "                  Quintic   = intermediate in speed and accuracy\n"
00305    "                  Heptic    = another intermediate interpolation method\n"
00306    "                  Fourier   = slowest, most accurate\n"
00307    "                  Hept+Four = use Heptic for estimation, Fourier for\n"
00308    "                              the final alignment\n"
00309    "              N.B.: Linear interpolation is always used for '3D: estimate'.\n"
00310    "                    Quintic/Heptic interpolation is only available for 3D.\n"
00311    "\n"
00312    " Graph        = If set to 'Yes', will display a graph of the estimated\n"
00313    "                  motion parameters at the end of the run.\n"
00314    "                * If set to 'Realtime', will also show a cruder graph that\n"
00315    "                  alters in realtime (if realtime registration is active).\n"
00316    " NR [x-axis]  = If a realtime graph is generated, this entry specifies\n"
00317    "                  how many repetitions (TR's) to expect.\n"
00318    " YR [y-axis]  = If a realtime graph is generated, this entry specifies\n"
00319    "                  the vertical range for each motion parameter.\n"
00320 #endif
00321    "\n"
00322    "MULTICHANNEL ACQUISITION [Aug 2002]:\n"
00323    " Multiple image channels can be acquired (e.g., from multi-coil and/or\n"
00324    " multi-echo sequences).  Each image channel goes into a separate dataset.\n"
00325    "  * These datasets will have names like Root#007_03 (for the 3rd channel\n"
00326    "    in the 7th acquisition).\n"
00327    "  * Functional activation cannot be computed with multichannel acquisition.\n"
00328    "  * Registration cannot be computed with multichannel acquisition.\n"
00329    "\n"
00330    "HOW TO SEND DATA:\n"
00331    " See file README.realtime for details; see program rtfeedme.c for an example.\n"
00332    "\n"
00333 ;
00334 
00335 
00336 
00337 static char root[THD_MAX_PREFIX] = "rt." ;  
00338 static int  update               = 1  ;     
00339 
00340 #define NFUNC  2
00341 static char * FUNC_strings[NFUNC] = { "None" , "FIM" } ;
00342 static int func_code = 0 ;
00343 
00344 static int image_mode = 0 ;  
00345 
00346 #define FUNC_NONE  0  
00347 #define FUNC_RTFIM 1
00348 
00349 #define INIT_MODE     -1  
00350 #define UPDATE_MODE   -2
00351 #define FINAL_MODE    -3
00352 
00353 int RT_fim_recurse( RT_input * , int ) ;
00354 
00355 int_func * FUNC_funcs[NFUNC] = { NULL , RT_fim_recurse } ;
00356 
00357 #define NYESNO 2
00358 #define NVERB  3
00359 static char * VERB_strings[NVERB] = { "No" , "Yes" , "Very" } ;
00360 static int verbose = 1 ;
00361 
00362 #ifdef ALLOW_REGISTRATION
00363   static int regtime  = 3 ;  
00364   static int regmode  = 0 ;  
00365   static int reggraph = 0 ;  
00366 
00367   static int reg_resam = 1 ;    
00368   static int   reg_nr  = 100 ;  
00369   static float reg_yr  = 1.0 ;  
00370 
00371 #define NGRAPH 3
00372 static char * GRAPH_strings[NGRAPH] = { "No" , "Yes" , "Realtime" } ;
00373 
00374 #define NRESAM 5
00375   static char * REG_resam_strings[NRESAM] = {
00376      "Cubic" , "Quintic" , "Heptic" , "Fourier" , "Hept+Four" } ;
00377   static int REG_resam_ints[NRESAM] = {
00378      MRI_CUBIC , MRI_QUINTIC , MRI_HEPTIC , MRI_FOURIER , -666 } ;
00379 
00380 # define NREG 6
00381   static char * REG_strings[NREG] = {
00382     "None" , "2D: realtime" , "2D: at end"
00383            , "3D: realtime" , "3D: at end" , "3D: estimate" } ;
00384 
00385   static char * REG_strings_ENV[NREG] = {  
00386     "None" , "2D:_realtime" , "2D:_at_end"
00387            , "3D:_realtime" , "3D:_at_end" , "3D:_estimate" } ;
00388 
00389 # define REGMODE_NONE      0
00390 # define REGMODE_2D_RTIME  1
00391 # define REGMODE_2D_ATEND  2
00392 # define REGMODE_3D_RTIME  3
00393 # define REGMODE_3D_ATEND  4
00394 # define REGMODE_3D_ESTIM  5
00395 
00396 # define REG_IS_2D(mm) ( (mm) == REGMODE_2D_RTIME || (mm) == REGMODE_2D_ATEND )
00397 
00398 # define REG_IS_3D(mm) \
00399   ( (mm)==REGMODE_3D_RTIME || (mm)==REGMODE_3D_ATEND || (mm)==REGMODE_3D_ESTIM )
00400 
00401 # define REG_MAKE_DSET(mm)                                   \
00402   ( (mm) == REGMODE_2D_RTIME || (mm) == REGMODE_2D_ATEND ||  \
00403     (mm) == REGMODE_3D_RTIME || (mm) == REGMODE_3D_ATEND   )
00404 #endif
00405 
00406 
00407 
00408 static IOCHAN * ioc_control = NULL ;     
00409 static RT_input * rtinp = NULL ;         
00410 static PLUGIN_interface * plint = NULL ; 
00411 
00412 
00413 
00414 DEFINE_PLUGIN_PROTOTYPE
00415 
00416 char * RT_main( PLUGIN_interface * ) ;
00417 Boolean RT_worker( XtPointer ) ;
00418 RT_input * new_RT_input( IOCHAN * ) ;
00419 int RT_check_listen(void) ;
00420 int RT_acquire_info( char * ) ;
00421 int RT_process_info( int , char * , RT_input * ) ;
00422 void RT_start_dataset( RT_input * ) ;
00423 void RT_read_image( RT_input * , char * ) ;
00424 int RT_process_data( RT_input * ) ;
00425 void RT_process_image( RT_input * ) ;
00426 void RT_finish_dataset( RT_input * ) ;
00427 void RT_tell_afni( RT_input * , int ) ;
00428 void RT_start_child( RT_input * ) ;
00429 void RT_check_info( RT_input * , int ) ;
00430 void RT_process_xevents( RT_input * ) ;  
00431 
00432 void RT_tell_afni_one( RT_input * , int , int ) ;  
00433 
00434 #ifdef ALLOW_REGISTRATION
00435   void RT_registration_2D_atend( RT_input * rtin ) ;
00436   void RT_registration_2D_setup( RT_input * rtin ) ;
00437   void RT_registration_2D_close( RT_input * rtin ) ;
00438   void RT_registration_2D_onevol( RT_input * rtin , int tt ) ;
00439   void RT_registration_2D_realtime( RT_input * rtin ) ;
00440 
00441   void RT_registration_3D_atend( RT_input * rtin ) ;
00442   void RT_registration_3D_setup( RT_input * rtin ) ;
00443   void RT_registration_3D_close( RT_input * rtin ) ;
00444   void RT_registration_3D_onevol( RT_input * rtin , int tt ) ;
00445   void RT_registration_3D_realtime( RT_input * rtin ) ;
00446 
00447   int  RT_mp_comm_close       ( RT_input * rtin );
00448   int  RT_mp_comm_init        ( RT_input * rtin );
00449   int  RT_mp_comm_init_vars   ( RT_input * rtin );
00450   int  RT_mp_comm_send_data   ( RT_input * rtin, float * mp[6], int nt );
00451   int  RT_parser_init         ( RT_input * rtin );
00452   void RT_set_grapher_pinnums ( int pinnum );
00453 #endif
00454 
00455 #define TELL_NORMAL  0
00456 #define TELL_WRITE   1
00457 #define TELL_FINAL   2
00458 
00459 #define WRITE_INTERVAL 37.954  
00460 
00461 #define REAP_CHILDREN
00462 #ifdef REAP_CHILDREN
00463 #  define GRIM_REAPER waitpid(-1,NULL,WNOHANG)
00464 #else
00465 #  define GRIM_REAPER 
00466 #endif
00467 
00468 #define USE_RT_STARTUP
00469 #ifdef  USE_RT_STARTUP
00470 
00471 
00472 static void RT_startup( XtPointer junk )
00473 {
00474    PLUTO_register_workproc( RT_worker , NULL ) ;
00475    return ;
00476 }
00477 #endif
00478 
00479 
00480 
00481 
00482 
00483 
00484 PLUGIN_interface * PLUGIN_init( int ncall )
00485 {
00486    char * ept ; 
00487 
00488    if( ncall > 0 )         return NULL ;  
00489    if( ! ALLOW_real_time ) return NULL ;  
00490 
00491    
00492 
00493    plint = PLUTO_new_interface( "RT Options" , "Set Real-Time Acquisition Options" ,
00494                                 helpstring , PLUGIN_CALL_VIA_MENU , RT_main  ) ;
00495 
00496    PLUTO_add_hint( plint , "Set Real-Time Acquisition Options" ) ;
00497 
00498    PLUTO_set_sequence( plint , "A:AArealtime" ) ;
00499    PLUTO_set_butcolor( plint , "hot" ) ;
00500 
00501    PLUTO_set_runlabels( plint , "Set+Keep" , "Set+Close" ) ;  
00502 
00503    
00504 
00505    ept = getenv("AFNI_REALTIME_Images_Only") ;  
00506    if( ept != NULL ){
00507       int ii = PLUTO_string_index( ept , NYESNO , VERB_strings ) ;
00508       if( ii >= 0 && ii < NYESNO ) image_mode = ii ;
00509    }
00510 
00511    PLUTO_add_option( plint , "" , "Mode" , FALSE ) ;
00512    PLUTO_add_string( plint , "Images Only" , NYESNO,VERB_strings,image_mode ) ;
00513 
00514    
00515 
00516    ept = getenv("AFNI_REALTIME_Root") ;        
00517    if( !THD_filename_pure(ept) ) ept = NULL ;
00518    if( ept != NULL ) MCW_strncpy(root,ept,THD_MAX_PREFIX) ;
00519 
00520    PLUTO_add_option( plint , "" , "Root" , FALSE ) ;
00521    PLUTO_add_string( plint , "Root" , 0, (ept!=NULL) ? &ept : NULL , 19 ) ;
00522 
00523    
00524 
00525    ept = getenv("AFNI_REALTIME_Update") ;      
00526    if( ept != NULL ){
00527       int ii = (int) rint(strtod(ept,NULL)) ;
00528       if( ii >= 0 && ii <= 19 ) update = ii ;
00529    }
00530 
00531    PLUTO_add_option( plint , "" , "Update" , FALSE ) ;
00532    PLUTO_add_number( plint , "Update" , 0,19,0 , update , FALSE ) ;
00533 
00534    
00535 
00536    ept = getenv("AFNI_REALTIME_Function") ;   
00537    if( ept != NULL ){
00538       int ii = PLUTO_string_index( ept , NFUNC , FUNC_strings ) ;
00539       if( ii >= 0 && ii < NFUNC ) func_code = ii ;
00540    }
00541 
00542    PLUTO_add_option( plint , "" , "Function" , FALSE ) ;
00543    PLUTO_add_string( plint , "Function" , NFUNC , FUNC_strings , func_code ) ;
00544 
00545    
00546 
00547    ept = getenv("AFNI_REALTIME_Verbose") ;   
00548    if( ept != NULL ){
00549       int ii = PLUTO_string_index( ept , NVERB , VERB_strings ) ;
00550       if( ii >= 0 && ii < NVERB ) verbose = ii ;
00551    }
00552 
00553    PLUTO_add_option( plint , "" , "Verbose" , FALSE ) ;
00554    PLUTO_add_string( plint , "Verbose" , NVERB , VERB_strings , verbose ) ;
00555 
00556 #ifdef ALLOW_REGISTRATION
00557    
00558 
00559    ept = getenv("AFNI_REALTIME_Registration") ;  
00560    if( ept != NULL ){
00561       int ii = PLUTO_string_index( ept , NREG , REG_strings ) ;
00562       
00563       if ( ii < 0 ) ii = PLUTO_string_index( ept , NREG , REG_strings_ENV ) ;
00564       if( ii >= 0 && ii < NREG ) regmode = ii ;
00565    }
00566 
00567    ept = getenv("AFNI_REALTIME_Base_Image") ;     
00568    if( ept != NULL ){
00569       int ii = (int) rint(strtod(ept,NULL)) ;
00570       if( ii >= 0 && ii <= 59 ) regtime = ii ;
00571    }
00572 
00573    ept = getenv("AFNI_REALTIME_Resampling") ;    
00574    if( ept != NULL ){
00575       int ii = PLUTO_string_index( ept , NRESAM , REG_resam_strings ) ;
00576       if( ii >= 0 && ii < NRESAM ) reg_resam = ii ;
00577    }
00578 
00579    PLUTO_add_option( plint , "" , "Registration" , FALSE ) ;
00580    PLUTO_add_string( plint , "Registration" , NREG , REG_strings , regmode ) ;
00581    PLUTO_add_number( plint , "Base Image" , 0,59,0 , regtime , FALSE ) ;
00582    PLUTO_add_string( plint , "Resampling" , NRESAM , REG_resam_strings , reg_resam ) ;
00583 
00584    
00585 
00586    ept = getenv("AFNI_REALTIME_Graph")  ;  
00587    if( ept != NULL ){
00588       int ii = PLUTO_string_index( ept , NGRAPH , GRAPH_strings ) ;
00589       if( ii >= 0 && ii < NGRAPH ) reggraph = ii ;
00590    }
00591 
00592    ept = getenv("AFNI_REALTIME_NR") ;     
00593    if( ept != NULL ){
00594       int ii = (int) rint(strtod(ept,NULL)) ;
00595       if( ii >= 5 && ii <= 9999 ) reg_nr = ii ;
00596    }
00597 
00598    ept = getenv("AFNI_REALTIME_YR") ;     
00599    if( ept != NULL ){
00600       float ff = strtod(ept,NULL) ;
00601       if( ff > 0.0 ) reg_yr = ff ;
00602    }
00603 
00604    PLUTO_add_option( plint , "" , "Graphing" , FALSE ) ;
00605    PLUTO_add_string( plint , "Graph" , NGRAPH , GRAPH_strings , reggraph ) ;
00606    PLUTO_add_number( plint , "NR [x-axis]" , 5,9999,0 , reg_nr , TRUE ) ;
00607    PLUTO_add_number( plint , "YR [y-axis]" , 1,100,1 , (int)(reg_yr*10.0) , TRUE ) ;
00608 #endif
00609 
00610    
00611 
00612 #ifndef USE_RT_STARTUP
00613    PLUTO_register_workproc( RT_worker , NULL ) ;
00614 #else
00615    PLUTO_register_timeout( 1954 , RT_startup , NULL ) ;
00616 #endif
00617 
00618    
00619 
00620    ept = getenv("AFNI_REALTIME_volreg_graphgeom") ;
00621    if( ept != NULL ){
00622       char *str = malloc(strlen(ept)+20) ;
00623       sprintf(str,"AFNI_tsplotgeom=%s",ept) ;
00624       putenv(str) ;
00625    }
00626 
00627    
00628 
00629    ALLOW_real_time = 1 ;  
00630    return plint ;
00631 }
00632 
00633 
00634 
00635 
00636 
00637 char * RT_main( PLUGIN_interface * plint )
00638 {
00639    char * tag , * str , * new_prefix ;
00640    static char buf[256] ;
00641 
00642    if( plint == NULL )
00643       return "*********************\n"
00644              "RT_main:  NULL input\n"
00645              "*********************"  ;
00646 
00647 
00648 
00649 #if 0                         
00650 #ifdef ALLOW_REGISTRATION
00651    regmode = REGMODE_NONE ;   
00652 #endif
00653 #endif
00654 
00655    while( (tag=PLUTO_get_optiontag(plint)) != NULL ){
00656 
00657       
00658 
00659       if( strcmp(tag,"Mode") == 0 ){
00660          str        = PLUTO_get_string(plint) ;
00661          image_mode = PLUTO_string_index( str , NYESNO , VERB_strings ) ;
00662          continue ;
00663       }
00664 
00665       if( strcmp(tag,"Root") == 0 ){
00666          new_prefix = PLUTO_get_string(plint) ;
00667          if( ! THD_filename_pure(new_prefix) )
00668             return "**************************\n"
00669                    "RT_main:  bad root prefix\n"
00670                    "**************************"  ;
00671          strcpy(root,new_prefix) ;
00672          continue ;
00673       }
00674 
00675       if( strcmp(tag,"Update") == 0 ){
00676          update = PLUTO_get_number(plint) ;
00677          continue ;
00678       }
00679 
00680       if( strcmp(tag,"Function") == 0 ){
00681          str       = PLUTO_get_string(plint) ;
00682          func_code = PLUTO_string_index( str , NFUNC , FUNC_strings ) ;
00683          continue ;
00684       }
00685 
00686       if( strcmp(tag,"Verbose") == 0 ){
00687          str     = PLUTO_get_string(plint) ;
00688          verbose = PLUTO_string_index( str , NVERB , VERB_strings ) ;
00689          continue ;
00690       }
00691 
00692 #ifdef ALLOW_REGISTRATION
00693       if( strcmp(tag,"Registration") == 0 ){
00694          str       = PLUTO_get_string(plint) ;
00695          regmode   = PLUTO_string_index( str , NREG , REG_strings ) ;
00696 
00697          regtime   = PLUTO_get_number(plint) ;
00698 
00699          str       = PLUTO_get_string(plint) ;
00700          reg_resam = PLUTO_string_index( str , NRESAM , REG_resam_strings ) ;
00701          continue ;
00702       }
00703 
00704       if( strcmp(tag,"Graphing") == 0 ){
00705          str      = PLUTO_get_string(plint) ;
00706          reggraph = PLUTO_string_index( str , NGRAPH , GRAPH_strings ) ;
00707 
00708          reg_nr   = PLUTO_get_number(plint) ;
00709          reg_yr   = PLUTO_get_number(plint) ;
00710 
00711          
00712 
00713          if( reg_nr >= MIN_PIN && reg_nr <= MAX_PIN && IM3D_OPEN(plint->im3d) )
00714              RT_set_grapher_pinnums(reg_nr);
00715 
00716          continue ;
00717       }
00718 #endif
00719 
00720 
00721 
00722       sprintf(buf,"*****************\n"
00723                   "Illegal optiontag: %s\n"
00724                   "*****************"      , tag ) ;
00725       return buf ;
00726 
00727    }  
00728 
00729    
00730 
00731    if( image_mode ){
00732       func_code = 0 ;
00733       regmode   = 0 ;
00734       reggraph  = 0 ;
00735    }
00736 
00737    PLUTO_turnoff_options( plint ) ;  
00738 
00739    return NULL ;  
00740 }
00741 
00742 
00743 
00744 
00745 
00746 
00747 
00748 int RT_check_listen(void)
00749 {
00750    int jj ;
00751    static int newcon = 1 ;
00752 
00753 
00754 
00755    if( ioc_control == NULL ){
00756       if( verbose )
00757          fprintf(stderr,"RT: starting to listen for control stream.\n") ;
00758       ioc_control = iochan_init( TCP_CONTROL , "accept" ) ;
00759       newcon      = 1 ;
00760       if( ioc_control == NULL ){
00761          fprintf(stderr,"RT: can't listen for control stream\a\n") ;
00762          return -1 ;
00763       }
00764    }
00765 
00766 
00767 
00768    jj = iochan_goodcheck(ioc_control,SHORT_DELAY) ;
00769 
00770    if( jj == 1 ){  
00771 
00772       if( newcon ){
00773          fprintf(stderr,"RT:---------------------------------------\n") ;
00774          fprintf(stderr,"RT: connected to control stream %s\n",ioc_control->name) ;
00775          newcon = 0 ;
00776       } else {
00777 
00778 
00779 
00780 
00781       }
00782 
00783       if( ! TRUST_host(ioc_control->name) ){
00784          fprintf(stderr,"RT: untrusted host connection - closing!\a\n") ;
00785          IOCHAN_CLOSENOW(ioc_control) ;
00786          return 0 ;
00787       }
00788 
00789       jj = iochan_readcheck(ioc_control,0) ;  
00790 
00791       if( jj > 0 && verbose == 2 ) fprintf(stderr,"RT: control data is present!\n") ;
00792 
00793       return jj ;
00794 
00795    } else if( jj == -1 ){  
00796 
00797       fprintf(stderr,"RT: failure while listening for control stream!\a\n") ;
00798       IOCHAN_CLOSENOW(ioc_control) ;
00799       return 0 ;
00800    }
00801 
00802    return 0 ;  
00803 }
00804 
00805 
00806 
00807 
00808 #define CLEANUP(n) cleanup_rtinp(n)
00809 
00810 
00811 
00812 #undef  FREEUP
00813 #define FREEUP(x) do{ if( (x) != NULL ){free((x)); (x)=NULL;} } while(0)
00814 
00815 
00816 
00817 
00818 
00819 void cleanup_rtinp( int keep_ioc_data )
00820 {
00821    int cc ;
00822 
00823    if( !keep_ioc_data )
00824      IOCHAN_CLOSENOW(rtinp->ioc_data) ;    
00825 
00826    IOCHAN_CLOSENOW(rtinp->ioc_info) ;
00827 
00828    if( rtinp->child_info > 0 )             
00829       kill( rtinp->child_info , SIGTERM ) ;
00830 
00831    DESTROY_IMARR(rtinp->bufar) ;           
00832 
00833    for( cc=0 ; cc < MAX_CHAN ; cc++ ){     
00834      if( rtinp->sbr[cc] != NULL )
00835        free( rtinp->sbr[cc] ) ;            
00836    }
00837 
00838 #ifdef ALLOW_REGISTRATION
00839    if( rtinp->reg_2dbasis != NULL ){       
00840       int kk ;
00841       for( kk=0 ; kk < rtinp->nzz ; kk++ )
00842          mri_2dalign_cleanup( rtinp->reg_2dbasis[kk] ) ;
00843       free( rtinp->reg_2dbasis ) ;
00844    }
00845 
00846    if( rtinp->reg_3dbasis != NULL ){
00847       mri_3dalign_cleanup( rtinp->reg_3dbasis ) ;
00848    }
00849 
00850    FREEUP( rtinp->reg_tim   ) ; FREEUP( rtinp->reg_dx    ) ;
00851    FREEUP( rtinp->reg_dy    ) ; FREEUP( rtinp->reg_dz    ) ;
00852    FREEUP( rtinp->reg_phi   ) ; FREEUP( rtinp->reg_psi   ) ;
00853    FREEUP( rtinp->reg_theta ) ; FREEUP( rtinp->reg_rep   ) ;
00854    FREEUP( rtinp->reg_eval  ) ;
00855 #endif
00856 
00857    if( rtinp->image_handle != NULL )
00858       PLUTO_imseq_rekill( rtinp->image_handle,NULL,NULL ) ;  
00859 
00860    if( rtinp->image_space != NULL ){
00861       mri_clear_data_pointer(rtinp->image_space) ; mri_free(rtinp->image_space) ;
00862    }
00863 
00864    
00865 
00866    if( rtinp->num_note > 0 && rtinp->note != NULL ){
00867      int kk ;
00868      for( kk=0 ; kk < rtinp->num_note ; kk++ ) FREEUP( rtinp->note[kk] ) ;
00869      FREEUP(rtinp->note) ;
00870    }
00871 
00872    free(rtinp) ; rtinp = NULL ;            
00873    ioc_control = NULL ;                    
00874    GRIM_REAPER ;                           
00875 }
00876 
00877 
00878 
00879 
00880 
00881 
00882 
00883 
00884 
00885 
00886 
00887 Boolean RT_worker( XtPointer elvis )
00888 {
00889    int jj ;
00890    static int first=1 ;
00891 
00892 #if 0
00893    if( first ){
00894       if( verbose ) fprintf(stderr,"RT: first call to RT_worker()\n") ;
00895       first = 0 ;
00896    }
00897 #endif
00898 
00899 
00900 
00901 
00902    if( rtinp == NULL ){         
00903       static int nerr = 0 ;
00904       jj = RT_check_listen() ;             
00905       if( jj < 0 ){                        
00906          nerr++ ; iochan_sleep(1) ;
00907          return (nerr > 9) ? True : False; 
00908       }
00909       nerr = 0 ;                           
00910       if( jj == 0 ) return False ;         
00911       rtinp = new_RT_input(NULL) ;         
00912       IOCHAN_CLOSENOW( ioc_control ) ;     
00913       if( rtinp == NULL ) return False ;   
00914    }
00915 
00916 
00917 
00918 
00919 
00920 
00921 
00922 
00923 
00924    if( iochan_goodcheck(rtinp->ioc_data,0) != 1 ){
00925 
00926       if( rtinp->sbr[0] != NULL ){     
00927          if( verbose == 2 )
00928             fprintf(stderr,"RT: data stream closed down.\n") ;
00929          VMCHECK ;
00930          RT_finish_dataset( rtinp ) ;  
00931       } else {
00932          fprintf(stderr,"RT: data stream closed before dataset was fully defined!\a\n") ;
00933       }
00934 
00935       CLEANUP(0) ; return False ;
00936    }
00937 
00938 
00939 
00940 
00941 
00942 #define CHILD_MAX_WAIT 66.6  
00943 
00944    if( rtinp->child_info > 0 ){
00945 
00946       jj = iochan_readcheck( rtinp->ioc_info , SHORT_DELAY ) ;  
00947 
00948       if( jj == 0 ){       
00949          double et = PLUTO_elapsed_time() - rtinp->child_start_time ;
00950          double mw = CHILD_MAX_WAIT ;
00951          char *eee = getenv("AFNI_REALTIME_CHILDWAIT") ;
00952          if( eee != NULL ){
00953             double val=strtod(eee,NULL); if(val >= 1.0) mw = val;
00954          }
00955 
00956          if( et > mw ){  
00957             fprintf(stderr,
00958                     "RT: no data from child after %f seconds!  Giving up.\a\n",et) ;
00959             CLEANUP(0) ; return False ;
00960          }
00961 
00962       } else if( jj < 0 ){   
00963 
00964          fprintf(stderr,"RT: child info stream closed prematurely!\a\n") ;
00965          CLEANUP(0) ; return False ;
00966 
00967       } else if( jj > 0 ){   
00968 
00969          char * info = (char *) malloc( sizeof(char) * INFO_SIZE ) ;
00970          int   ninfo , ii ;
00971 
00972          
00973 
00974          if( verbose )
00975             fprintf(stderr,"RT: receiving data from child process\n") ;
00976          VMCHECK ;
00977 
00978          ninfo = 0 ;
00979          while(1){
00980             ii = iochan_recv( rtinp->ioc_info , info+ninfo , INFO_SIZE-ninfo ) ;
00981             if( ii < 1 ) break ;
00982             ninfo += ii ;
00983             if( ninfo >= INFO_SIZE ){
00984                fprintf(stderr,"RT: child process sent too much info!\a\n") ;
00985                break ;
00986             }
00987             ii = iochan_readcheck( rtinp->ioc_info , SHORT_DELAY ) ;
00988             if( ii < 1 ) break ;
00989          }
00990          IOCHAN_CLOSENOW( rtinp->ioc_info ) ; rtinp->child_info = 0 ;
00991 
00992          if( ninfo <= 0 ){
00993             fprintf(stderr,"RT: child info stream returned no data!\a\n") ;
00994             CLEANUP(0) ; return False ;
00995          }
00996 
00997          if( verbose == 2 )
00998             fprintf(stderr,"RT: child info stream returned %d bytes.\n",ninfo) ;
00999          VMCHECK ;
01000 
01001          
01002 
01003          jj = RT_process_info( ninfo , info , rtinp ) ; free(info) ;
01004 
01005          
01006 
01007          if( jj <= 0 ){
01008             fprintf(stderr,"RT: child info was badly formatted!\a\n") ;
01009             CLEANUP(0) ; return False ;
01010          }
01011 
01012          
01013 
01014 
01015          if( ! rtinp->no_data && ! rtinp->info_ok ){
01016             fprintf(stderr,"RT: child info was incomplete or erroneous!\a\n") ;
01017             RT_check_info( rtinp , 1 ) ;
01018             PLUTO_beep() ;
01019             PLUTO_popup_transient( plint , " \n"
01020                                            "      Heads down!\n"
01021                                            "Realtime header was bad!\n" ) ;
01022             CLEANUP(0) ; return FALSE ;
01023          }
01024 
01025          
01026 
01027          if( rtinp->sbr[0] == NULL && rtinp->info_ok ){
01028             if( verbose == 2 )
01029                fprintf(stderr,"RT: info complete --> creating dataset.\n") ;
01030             VMCHECK ;
01031             RT_start_dataset( rtinp ) ;
01032          }
01033       }
01034 
01035 
01036 
01037    }
01038 
01039 
01040 
01041 
01042    jj = iochan_readcheck( rtinp->ioc_data , SHORT_DELAY ) ;
01043 
01044    if( jj == 0 ){     
01045 
01046 #ifdef WRITE_INTERVAL
01047       double delt ;
01048       double mw = WRITE_INTERVAL ;
01049       char *eee = getenv("AFNI_REALTIME_WRITEWAIT") ;
01050       if( eee != NULL ){
01051          double val=strtod(eee,NULL); if(val >= 1.0) mw = val;
01052       }
01053 
01054 
01055 
01056 
01057 
01058       if( !rtinp->no_data                    &&
01059           rtinp->nvol[0] > rtinp->last_nvol  &&
01060           !rtinp->image_mode                 &&  
01061           (delt=PLUTO_elapsed_time()-rtinp->last_elapsed) > mw  ){
01062 
01063          int cmode , cc ;
01064 
01065          fprintf(stderr,"RT: no image data for %g seconds --> saving to disk.\n",delt) ;
01066 
01067          PLUTO_popup_transient( plint , " \n"
01068                                         " Pause in input data stream:\n"
01069                                         " Saving current dataset(s) to disk.\n" ) ;
01070 
01071          RT_tell_afni(rtinp,TELL_NORMAL) ;
01072 
01073          cmode = THD_get_write_compression() ;      
01074          THD_set_write_compression(COMPRESS_NONE) ;
01075          SHOW_AFNI_PAUSE ;
01076 
01077          for( cc=0 ; cc < rtinp->num_chan ; cc++ )
01078            THD_write_3dim_dataset( NULL,NULL , rtinp->dset[cc] , True ) ;
01079 
01080          if( rtinp->func_dset != NULL )
01081             THD_write_3dim_dataset( NULL,NULL , rtinp->func_dset , True ) ;
01082 
01083          THD_set_write_compression(cmode) ;  sync() ; 
01084          SHOW_AFNI_READY ;
01085 
01086          rtinp->last_nvol    = rtinp->nvol[0] ;
01087          rtinp->last_elapsed = PLUTO_elapsed_time() ;
01088       }
01089 #endif
01090 
01091       return False ;
01092    }
01093 
01094    if( jj < 0 ){               
01095       if( verbose == 2 )
01096          fprintf(stderr,"RT: data stream closed down.\n") ;
01097       VMCHECK ;
01098       if( rtinp->sbr[0] != NULL ) RT_finish_dataset( rtinp ) ;
01099       CLEANUP(0) ; return False ;
01100    }
01101 
01102    
01103 
01104 
01105 
01106 
01107 
01108 
01109 
01110    if( rtinp->no_data ){
01111       int ii , nb ;
01112 
01113 
01114 
01115       if( strlen(rtinp->name_info) > 0 ) RT_start_child( rtinp ) ;
01116 
01117 
01118 
01119       fprintf(stderr,"RT: receiving image metadata") ; fflush(stderr) ;
01120 
01121       nb = iochan_recv( rtinp->ioc_data , rtinp->buf , RT_NBUF ) ;
01122 
01123       if( nb <= 0 ){
01124          fprintf(stderr,"\nRT: recv on data stream fails on first try!\a\n") ;
01125          CLEANUP(0) ; return False ;
01126       }
01127 
01128       
01129 
01130       while( nb < RT_NBUF-1 ){
01131         ii = iochan_readcheck( rtinp->ioc_data , SHORT_DELAY ) ;
01132         if( ii <= 0 ) break ;
01133         ii = iochan_recv( rtinp->ioc_data , rtinp->buf+nb , RT_NBUF-nb ) ;
01134         if( ii <= 0 ) break ;
01135         nb += ii ;
01136       }
01137       rtinp->nbuf = nb ;
01138 
01139       fprintf(stderr,"=%d bytes\n",rtinp->nbuf) ;
01140 
01141       PLUTO_beep() ;
01142       PLUTO_popup_transient( plint , " \n"
01143                                      "***************************\n"
01144                                      "*       Heads Up!         *\n"
01145                                      "* Incoming realtime data! *\n"
01146                                      "***************************\n" ) ;
01147 
01148 
01149 
01150 
01151       jj = RT_process_info( rtinp->nbuf , rtinp->buf , rtinp ) ;
01152 
01153       if( jj <= 0 ){                  
01154 
01155          fprintf(stderr,"RT: initial image metadata is badly formatted!\a\n") ;
01156          CLEANUP(0) ; return False ;
01157 
01158       } else if( jj < rtinp->nbuf ){  
01159 
01160          memmove( rtinp->buf , rtinp->buf + jj , rtinp->nbuf - jj ) ;
01161          rtinp->nbuf = rtinp->nbuf - jj ;
01162 
01163       } else {                        
01164          rtinp->nbuf = 0 ;
01165       }
01166 
01167       if( verbose == 2 )
01168          fprintf(stderr,
01169                  "RT: processed %d bytes of header info from data stream\n",jj) ;
01170       VMCHECK ;
01171 
01172       rtinp->no_data = 0 ;  
01173 
01174       
01175 
01176 
01177       if( rtinp->child_info == 0 && ! rtinp->info_ok ){
01178          fprintf(stderr,"RT: image header info was incomplete!\a\n") ;
01179          RT_check_info( rtinp , 1 ) ;
01180          PLUTO_beep() ;
01181          PLUTO_popup_transient( plint , " \n"
01182                                         "      Heads down!\n"
01183                                         "Realtime header was bad!\n" ) ;
01184          CLEANUP(0) ; return FALSE ;
01185       }
01186    }
01187 
01188 
01189 
01190 
01191    jj = RT_process_data( rtinp ) ;
01192 
01193    if( jj < 0 ){
01194       fprintf(stderr,"RT: data stream aborted during image read!\n") ;
01195       if( rtinp->sbr[0] != NULL ) RT_finish_dataset( rtinp ) ;
01196       CLEANUP(0) ; return False ;
01197    }
01198 
01199    
01200 
01201 
01202 
01203 
01204 
01205 
01206    if( rtinp->marked_for_death ){
01207       RT_input *new_rtinp ;
01208       fprintf(stderr,"RT: data stream says to close dataset.\n") ;
01209       if( rtinp->sbr[0] != NULL ) RT_finish_dataset( rtinp ) ;
01210       fprintf(stderr,"RT: starting to read from existing data stream.\n") ;
01211       new_rtinp = new_RT_input( rtinp->ioc_data ) ; 
01212       CLEANUP(1) ;                                 
01213       rtinp = new_rtinp ; return False ;
01214    }
01215 
01216    
01217 
01218    rtinp->last_elapsed = PLUTO_elapsed_time() ;  
01219    return False ;
01220 }
01221 
01222 
01223 
01224 
01225 
01226 #define MAX_NEV 6
01227 #if MAX_NEV > 0
01228 void RT_process_xevents( RT_input * rtin )
01229 {
01230    Display * dis = THE_DISPLAY ;
01231    XEvent ev ; int nev=0 ;
01232 
01233    XSync( dis , False ) ;
01234    while( nev++ < MAX_NEV &&
01235           XCheckMaskEvent(dis ,
01236                           ButtonMotionMask   |PointerMotionMask|
01237                           ButtonPressMask    |ButtonReleaseMask|
01238                           KeyPressMask       |KeyReleaseMask   |
01239                           StructureNotifyMask|ExposureMask      ,&ev) ){
01240 
01241           XtDispatchEvent( &ev ) ;  
01242    }
01243    XmUpdateDisplay(THE_TOPSHELL) ;
01244    if( verbose == 2 && nev > 1 )
01245       fprintf(stderr,"RT: processed %d events\n",nev-1);
01246    return ;
01247 }
01248 #else
01249 void RT_process_xevents( RT_input * rtin ){}  
01250 #endif
01251 
01252 
01253 
01254 
01255 
01256 
01257 
01258 
01259 
01260 
01261 
01262 
01263 
01264 
01265 
01266 
01267 RT_input * new_RT_input( IOCHAN *ioc_data )
01268 {
01269    RT_input *rtin ;
01270    int ii , cc ;
01271    Three_D_View *im3d ;
01272 
01273    if( ioc_data == NULL ){ 
01274 
01275      int ncon ;
01276      char *con , *ptr ;
01277 
01278 
01279 
01280      if( iochan_readcheck(ioc_control,-1) <= 0 ){
01281         fprintf(stderr,"RT: control stream fails readcheck!\a\n") ;
01282         return NULL ;
01283      }
01284 
01285 
01286 
01287      rtin = (RT_input *) calloc( 1 , sizeof(RT_input) ) ;
01288      con  = (char *)     malloc( INFO_SIZE ) ;
01289 
01290      if( rtin == NULL || con == NULL ){
01291        fprintf(stderr,"RT: malloc fails in new_RT_input!\a\n") ; EXIT(1) ;
01292      }
01293 
01294 
01295 
01296      ncon = 0 ;  
01297      while(1){
01298         ii = iochan_recv( ioc_control , con+ncon , INFO_SIZE-ncon ) ;
01299         if( ii < 1 ) break ;
01300         ncon += ii ;
01301         if( ncon >= INFO_SIZE ){
01302            fprintf(stderr,"RT: control stream buffer overflow!\a\n") ;
01303            break ;
01304         }
01305         iochan_sleep( SHORT_DELAY ) ;
01306      }
01307 
01308      if( ncon < 1 ){
01309         fprintf(stderr,"RT: control stream sends no data!\a\n") ;
01310         free(rtin) ; free(con) ; return NULL ;
01311      }
01312 
01313 
01314 
01315 
01316 
01317 
01318 
01319 
01320 
01321 
01322 
01323 
01324 
01325 
01326 
01327      ncon = MIN( ncon , INFO_SIZE-2 ) ;
01328      con[ncon+1] = '\0' ;               
01329 
01330 
01331 
01332      ii = 0 ;
01333      for( ptr=con ; ii < NNAME && *ptr != '\0' && *ptr != '\n' ; ptr++ ){
01334         rtin->name_data[ii++] = *ptr ;
01335      }
01336      if( ii >= NNAME ){
01337         fprintf(stderr,"RT: control image_channel_spec buffer overflow!\a\n") ;
01338         ii = NNAME - 1 ;
01339      }
01340      rtin->name_data[ii] = '\0' ;
01341 
01342 
01343 
01344      rtin->ioc_data = iochan_init( rtin->name_data , "accept" ) ;
01345      if( rtin->ioc_data == NULL ){
01346         fprintf(stderr,"RT: failure to open data IOCHAN %s\a\n",rtin->name_data) ;
01347         free(rtin) ; free(con) ; return NULL ;
01348      }
01349 
01350      if( verbose == 2 )
01351         fprintf(stderr,"RT: opened data stream %s\n",rtin->name_data) ;
01352      VMCHECK ;
01353 
01354 
01355 
01356 
01357      ii = 0 ;
01358      if( *ptr != '\0' ){
01359         for( ptr++ ; ii < NNAME && *ptr != '\0' && *ptr != '\n' ; ptr++ ){
01360            rtin->name_info[ii++] = *ptr ;
01361         }
01362         if( ii >= NNAME ){
01363            fprintf(stderr,"RT: control info_command buffer overflow!\a\n") ;
01364            ii = NNAME - 1 ;
01365         }
01366      }
01367      rtin->name_info[ii] = '\0' ;
01368 
01369      if( verbose == 2 ){
01370         if( strlen(rtin->name_info) > 0 )
01371            fprintf(stderr,"RT: info command for child will be '%s'\n",rtin->name_info) ;
01372         else
01373            fprintf(stderr,"RT: no info command given.\n") ;
01374      }
01375 
01376      free(con) ;
01377      VMCHECK ;
01378 
01379 
01380 
01381    } else {  
01382 
01383 
01384 
01385      rtin = (RT_input *) calloc( 1 , sizeof(RT_input) ) ;
01386      if( rtin == NULL ){
01387        fprintf(stderr,"RT: malloc fails in new_RT_input!\a\n") ; EXIT(1) ;
01388      }
01389 
01390      MCW_strncpy( rtin->name_data , ioc_data->name , NNAME ) ;  
01391      rtin->ioc_data     = ioc_data ;
01392      rtin->name_info[0] = '\0' ;                                
01393 
01394    } 
01395 
01396    rtin->ioc_info   = NULL ;
01397    rtin->child_info = 0 ;
01398 
01399 
01400 
01401    if( verbose )
01402       fprintf(stderr,"RT: waiting for data stream to become good.\n") ;
01403    VMCHECK ;
01404 
01405    while(1){
01406       ii = iochan_goodcheck(rtin->ioc_data,1000) ;             
01407            if( ii >  0 )                 break ;               
01408       else if( ii == 0 && verbose == 2 ) fprintf(stderr,".") ; 
01409       else {                                                   
01410          fprintf(stderr,"RT: data stream fails to become good!\a\n") ;
01411          IOCHAN_CLOSENOW(rtin->ioc_data) ; free(rtin) ;
01412          return NULL ;
01413       }
01414    }
01415 
01416    if( verbose == 2 )
01417       fprintf(stderr,"RT: data stream is now bodaciously good.\n") ;
01418    VMCHECK ;
01419 
01420 
01421 
01422    rtin->info_ok = 0 ; rtin->no_data = 1 ;
01423 
01424    rtin->image_mode   = image_mode ;  
01425    rtin->image_handle = NULL ;
01426    rtin->image_space  = NULL ;
01427 
01428 #if 0                               
01429    rtin->nxx = DEFAULT_XYMATRIX ;
01430    rtin->nyy = DEFAULT_XYMATRIX ;
01431    rtin->nzz = DEFAULT_ZNUM ;
01432 
01433    rtin->orcxx = ORI_S2I_TYPE ;
01434    rtin->orcyy = ORI_A2P_TYPE ;
01435    rtin->orczz = ORI_L2R_TYPE ;
01436 
01437    rtin->xxfov = DEFAULT_XYFOV ;
01438    rtin->yyfov = DEFAULT_XYFOV ;
01439    rtin->zzfov = -1.0 ;
01440    rtin->dxx   = DEFAULT_XYFOV / DEFAULT_XYMATRIX ;
01441    rtin->dyy   = DEFAULT_XYFOV / DEFAULT_XYMATRIX ;
01442    rtin->dzz   = DEFAULT_ZDELTA ;
01443 
01444    rtin->zgap  = 0.0 ;                  
01445    rtin->xxoff = rtin->yyoff = rtin->zzoff = 0.0 ;
01446 
01447    rtin->xxorg = 0.5 * (rtin->nxx - 1) * rtin->dxx ; rtin->xcen = 1 ;
01448    rtin->yyorg = 0.5 * (rtin->nyy - 1) * rtin->dyy ; rtin->ycen = 1 ;
01449    rtin->zzorg = 0.5 * (rtin->nzz - 1) * rtin->dzz ; rtin->zcen = 1 ;
01450    rtin->xxdcode = ILLEGAL_TYPE ;
01451    rtin->yydcode = ILLEGAL_TYPE ;
01452    rtin->zzdcode = ILLEGAL_TYPE ;
01453 
01454    rtin->tr     = DEFAULT_TR ;
01455    rtin->nr     = 1 ;
01456    rtin->dtype  = DTYPE_2DZT ;
01457    rtin->datum  = MRI_short  ;
01458 
01459    rtin->zorder      = ZORDER_ALT ;
01460    rtin->zorder_lock = 0 ;              
01461 #else
01462    rtin->nxx = -1 ;
01463    rtin->nyy = -1 ;
01464    rtin->nzz = -1 ;
01465 
01466    rtin->orcxx = -1 ;
01467    rtin->orcyy = -1 ;
01468    rtin->orczz = -1 ;
01469 
01470    rtin->xxfov = 0.0 ;
01471    rtin->yyfov = 0.0 ;
01472    rtin->zzfov = 0.0 ;
01473    rtin->dxx   = 0.0 ;
01474    rtin->dyy   = 0.0 ;
01475    rtin->dzz   = 0.0 ;
01476 
01477    rtin->zgap  = 0.0 ;                  
01478    rtin->xxoff = rtin->yyoff = rtin->zzoff = 0.0 ;
01479 
01480    rtin->xxorg = 0.0 ; rtin->xcen = 1 ; rtin->xxdcode = ILLEGAL_TYPE ;
01481    rtin->yyorg = 0.0 ; rtin->ycen = 1 ; rtin->yydcode = ILLEGAL_TYPE ;
01482    rtin->zzorg = 0.0 ; rtin->zcen = 1 ; rtin->zzdcode = ILLEGAL_TYPE ;
01483 
01484    rtin->tr     = DEFAULT_TR ;
01485    rtin->nr     = 1 ;
01486    rtin->dtype  = DTYPE_2DZT ;
01487    rtin->datum  = MRI_short  ;
01488    rtin->nzseq  = 0 ;
01489 
01490    rtin->zorder      = ZORDER_ALT ;
01491    rtin->zorder_lock = 0 ;              
01492    rtin->tpattern    = ZORDER_ALT ;     
01493 #endif
01494 
01495    rtin->swap_on_read = 0 ;  
01496 
01497    rtin->nbuf   = 0    ;     
01498    rtin->imsize = 0 ;        
01499    rtin->bufar  = NULL ;     
01500 
01501    im3d = plint->im3d ;                           
01502    if( !IM3D_OPEN(im3d) )                         
01503       im3d = AFNI_find_open_controller() ;
01504 
01505 
01506 
01507    for( cc=0 ; cc < MAX_CHAN ; cc++ ){
01508       rtin->afni_status[cc] = 0 ;      
01509       rtin->dset[cc]        = NULL ;   
01510       rtin->sbr[cc]         = NULL ;   
01511       rtin->im[cc]          = NULL ;
01512       rtin->nvol[cc]        = 0 ;
01513       rtin->nsl[cc]         = 0 ;
01514       rtin->im3d[cc]        = im3d ;
01515       rtin->sess[cc]        = GLOBAL_library.sslist->ssar[im3d->vinfo->sess_num] ;
01516       rtin->sess_num[cc]    = im3d->vinfo->sess_num ;
01517    }
01518 
01519    rtin->num_chan = 1 ;   
01520    rtin->cur_chan = 0 ;   
01521 
01522    strcpy( rtin->root_prefix , root ) ;
01523 
01524 
01525 
01526    rtin->func_dset   = NULL ;  
01527    rtin->func_status = 0 ;     
01528    rtin->func_condit = 0 ;     
01529 
01530    
01531 
01532    rtin->func_code   = (rtin->dtype == DTYPE_2DZ || rtin->dtype == DTYPE_3D)
01533                        ? FUNC_NONE : func_code ;
01534 
01535    rtin->func_func   = FUNC_funcs[rtin->func_code] ; 
01536 
01537 #ifdef ALLOW_REGISTRATION
01538    rtin->reg_base_index = regtime ;  
01539    rtin->reg_mode       = regmode ;  
01540    rtin->reg_dset       = NULL ;
01541    rtin->reg_2dbasis    = NULL ;
01542    rtin->reg_status     = 0 ;        
01543    rtin->reg_nvol       = 0 ;        
01544 
01545    rtin->reg_nest  = 0 ;
01546    rtin->reg_tim   = (float *) malloc( sizeof(float) ) ;
01547    rtin->reg_dx    = (float *) malloc( sizeof(float) ) ;
01548    rtin->reg_dy    = (float *) malloc( sizeof(float) ) ;
01549    rtin->reg_phi   = (float *) malloc( sizeof(float) ) ;
01550 
01551    rtin->reg_dz       = (float *) malloc( sizeof(float) ) ;
01552    rtin->reg_theta    = (float *) malloc( sizeof(float) ) ;
01553    rtin->reg_psi      = (float *) malloc( sizeof(float) ) ;
01554    rtin->reg_rep      = (float *) malloc( sizeof(float) ) ;
01555    rtin->reg_eval     = (float *) malloc( sizeof(float) ) ;
01556    rtin->reg_3dbasis  = NULL ;
01557    rtin->mp           = NULL ;    
01558 
01559    rtin->reg_graph_xnew = 0 ;     
01560    rtin->reg_graph_ynew = 0 ;     
01561    rtin->reg_graph_xr = reg_nr ;  
01562    rtin->reg_graph_yr = reg_yr ;
01563 
01564    rtin->p_code = NULL ;          
01565 
01566    rtin->mp_tcp_use = 0 ;         
01567    rtin->mp_tcp_sd  = 0 ;
01568    rtin->mp_port    = RT_MP_DEF_PORT ;
01569    rtin->mp_nmsg    = 0 ;
01570    rtin->mp_npsets  = 0 ;
01571    strcpy(rtin->mp_host, "localhost") ;
01572 
01573    rtin->reg_resam = REG_resam_ints[reg_resam] ;
01574    if( rtin->reg_resam < 0 ){                    
01575       rtin->reg_resam       = MRI_HEPTIC ;       
01576       rtin->reg_final_resam = MRI_FOURIER ;
01577    } else {
01578       rtin->reg_final_resam = -1 ;
01579    }
01580 
01581    rtin->reg_graph = reggraph ;
01582    if( regmode==REGMODE_3D_ESTIM && reggraph==0 ) rtin->reg_graph = 1;
01583 #endif
01584 
01585 
01586 
01587    rtin->elapsed = PLUTO_elapsed_time() ; rtin->last_elapsed = rtin->elapsed ;
01588    rtin->cpu     = PLUTO_cpu_time() ;     rtin->last_nvol = 0 ;
01589 
01590    rtin->num_note = 0 ;      
01591    rtin->note     = NULL ;
01592 
01593    rtin->marked_for_death = 0 ;  
01594 
01595    return rtin ;
01596 }
01597 
01598 
01599 
01600 
01601 
01602 
01603 void RT_start_child( RT_input * rtin )
01604 {
01605    pid_t child_pid ;
01606 
01607    if( rtin == NULL || strlen(rtin->name_info) == 0 ) return ;  
01608 
01609    child_pid = fork() ;             
01610 
01611    if( child_pid == (pid_t)(-1) ){  
01612      fprintf(stderr,"RT: can't fork child process!\a\n") ; EXIT(1) ;
01613    }
01614 
01615    if( child_pid > 0 ){              
01616 
01617       if( verbose == 2 )
01618          fprintf(stderr,"RT: forked a child process to execute '%s'\n",rtin->name_info) ;
01619       VMCHECK ;
01620 
01621 
01622 
01623       rtin->child_info = child_pid ;
01624       rtin->ioc_info   = iochan_init( SHM_CHILD , "accept" ) ;
01625       if( rtinp->ioc_info == NULL ){
01626         kill( child_pid , SIGTERM ) ;
01627         fprintf(stderr,"RT: can't create read stream from child!\a\n") ;
01628         EXIT(1) ;
01629       }
01630 
01631       rtin->child_start_time = PLUTO_elapsed_time() ;  
01632 
01633 
01634 
01635    } else {                          
01636 
01637       RT_acquire_info( rtin->name_info ) ;  
01638       _exit(0) ;
01639    }
01640 
01641    return ;
01642 }
01643 
01644 
01645 
01646 
01647 
01648 
01649 
01650 
01651 
01652 int RT_acquire_info( char * command )
01653 {
01654    FILE * fp ;
01655    char * info = (char *) malloc( sizeof(char) * INFO_SIZE ) ; int ninfo = 0 ;
01656    IOCHAN * ioc ;
01657    int jj ;
01658 
01659 
01660 
01661    ioc = iochan_init( SHM_CHILD , "create" ) ;
01662    if( ioc == NULL ){
01663       fprintf(stderr,"RT: child fails to open stream back to parent!\a\n") ;
01664       _exit(1) ;
01665    }
01666 
01667 
01668 
01669    fp = popen( command , "r" ) ;
01670    if( fp == NULL ){
01671       fprintf(stderr,"RT: child fails to open pipe to command=%s\a\n",command) ;
01672       IOCHAN_CLOSENOW(ioc) ; _exit(1) ;
01673    }
01674 
01675 
01676 
01677    while( fgets(info+ninfo,INFO_SIZE-ninfo,fp) != NULL ){
01678       ninfo = strlen(info) ;
01679    }
01680    pclose(fp) ;
01681 
01682 
01683 
01684    jj = iochan_writecheck(ioc,-1) ;  
01685    if( jj < 0 ){
01686       fprintf(stderr,"RT: child can't write IOCHAN to parent!\a\n") ;
01687       IOCHAN_CLOSENOW(ioc) ; _exit(1) ;
01688    }
01689 
01690    iochan_sendall( ioc , info , ninfo+1 ) ;        
01691    iochan_sleep(LONG_DELAY) ;                      
01692    while( ! iochan_clearcheck(ioc,LONG_DELAY) )    
01693       iochan_sleep(LONG_DELAY) ;
01694 
01695    iochan_sleep(LONG_DELAY) ;                      
01696 
01697                                                    
01698    free(info); IOCHAN_CLOSENOW(ioc); _exit(0);     
01699 }                                                  
01700 
01701 
01702 
01703 
01704 
01705 
01706 #define EPR(s) fprintf(stderr,"RT: HEADER DATA ERROR - %s\a\n",(s))
01707 
01708 #define OR3OK(x,y,z) ( ((x)&6) + ((y)&6) + ((z)&6) == 6 )
01709 
01710 void RT_check_info( RT_input * rtin , int prt )
01711 {
01712    if( rtin == NULL ) return ;
01713 
01714    
01715 
01716    if( rtin->image_mode ){
01717 
01718       rtin->info_ok = ( rtin->nxx > 1 )                         &&
01719                       ( rtin->nyy > 1 )                         &&
01720                       ( AFNI_GOOD_DTYPE(rtin->datum) ) ;
01721 
01722       if( rtin->info_ok || !prt ) return ;  
01723 
01724       if( !(rtin->nxx > 1)                ) EPR("Image x-dimen not > 1") ;
01725       if( !(rtin->nyy > 1)                ) EPR("Image y-dimen not > 1") ;
01726       if( !(AFNI_GOOD_DTYPE(rtin->datum)) ) EPR("Bad datum") ;
01727       return ;
01728    }
01729 
01730    
01731 
01732    rtin->info_ok = ( rtin->dtype > 0 )                            &&
01733                    ( THD_filename_pure(rtin->root_prefix) )       &&
01734                    ( strlen(rtin->root_prefix) < THD_MAX_PREFIX ) &&
01735                    ( rtin->tr > 0 )                               &&
01736                    ( rtin->dzz > 0 || rtin->zzfov > 0 )           &&
01737                    ( rtin->xxfov > 0 )                            &&
01738                    ( rtin->yyfov > 0 )                            &&
01739                    ( rtin->nxx > 1 )                              &&
01740                    ( rtin->nyy > 1 )                              &&
01741                    ( rtin->nzz >= 1 )                             &&
01742                    ( AFNI_GOOD_DTYPE(rtin->datum) )               &&
01743                    ( rtin->zorder > 0 )                           &&
01744                    ( rtin->tpattern > 0 )                         &&
01745                    ( rtin->orcxx >= 0 )                           &&
01746                    ( rtin->orcyy >= 0 )                           &&
01747                    ( rtin->orczz >= 0 )                           &&
01748                    ( OR3OK(rtin->orcxx,rtin->orcyy,rtin->orczz) )    ;
01749 
01750    if( rtin->info_ok || !prt ) return ;  
01751 
01752    
01753 
01754    if( !(rtin->dtype > 0)                            ) EPR("Bad acquisition type") ;
01755    if( !(THD_filename_pure(rtin->root_prefix))       ) EPR("Bad prefix") ;
01756    if( !(strlen(rtin->root_prefix) < THD_MAX_PREFIX) ) EPR("Overlong prefix") ;
01757    if( !(rtin->tr > 0)                               ) EPR("TR is not positive") ;
01758    if( !(rtin->dzz > 0 || rtin->zzfov > 0)           ) EPR("Slice thickness not positive") ;
01759    if( !(rtin->xxfov > 0)                            ) EPR("x-FOV not positive") ;
01760    if( !(rtin->yyfov > 0)                            ) EPR("y-FOV not positive") ;
01761    if( !(rtin->nxx > 1)                              ) EPR("Image x-dimen not > 1") ;
01762    if( !(rtin->nyy > 1)                              ) EPR("Image y-dimen not > 1") ;
01763    if( !(rtin->nzz >= 1)                             ) EPR("Slice count (z-dimen) not >= 1") ;
01764    if( !(AFNI_GOOD_DTYPE(rtin->datum))               ) EPR("Bad datum") ;
01765    if( !(rtin->zorder > 0)                           ) EPR("Slice ordering illegal") ;
01766    if( !(rtin->tpattern > 0)                         ) EPR("Timing pattern illegal") ;
01767    if( !(rtin->orcxx >= 0)                           ) EPR("x-orientation illegal") ;
01768    if( !(rtin->orcyy >= 0)                           ) EPR("y-orientation illegal") ;
01769    if( !(rtin->orczz >= 0)                           ) EPR("z-orientation illegal") ;
01770    if( !(OR3OK(rtin->orcxx,rtin->orcyy,rtin->orczz)) ) EPR("Inconsistent xyz-orientations") ;
01771 
01772    return ;
01773 }
01774 
01775 #ifdef ALLOW_REGISTRATION
01776 
01777 
01778 
01779 
01780 
01781 
01782 int RT_mp_comm_close( RT_input * rtin )
01783 {
01784     char magic_bye[] = { 0xde, 0xad, 0xde, 0xad, 0 };
01785 
01786     if ( rtin->mp_tcp_use != 1 || rtin->mp_tcp_sd <= 0 )
01787         return 0;
01788 
01789     if ( (tcp_writecheck(rtin->mp_tcp_sd, 1)   == -1) ||
01790          (send(rtin->mp_tcp_sd, magic_bye, 4, 0) == -1 ) )
01791         fprintf(stderr,"** closing: our MP socket has gone bad?\n");
01792 
01793     fprintf(stderr,"RT: MP: closing motion param socket, "
01794                    "sent %d param sets over %d messages\n",
01795                    rtin->mp_npsets, rtin->mp_nmsg);
01796 
01797     
01798     close(rtin->mp_tcp_sd);
01799     rtin->mp_tcp_sd  = 0;
01800     rtin->mp_tcp_use = 0;
01801     rtin->mp_npsets  = 0;
01802     rtin->mp_nmsg    = 0;
01803 
01804     return 0;
01805 }
01806 
01807 
01808 
01809 
01810 
01811 
01812 
01813 
01814 int RT_mp_comm_send_data( RT_input * rtin, float * mp[6], int nt )
01815 {
01816     float data[600];            
01817     int   rv, nvals, remain;
01818     int   c, c2;
01819 
01820     if ( rtin->mp_tcp_use != 1 || nt <= 0 )
01821         return 0;
01822 
01823     if ( rtin->mp_tcp_sd <= 0 )
01824         return -1;
01825 
01826     
01827     if ( (rv = tcp_writecheck(rtin->mp_tcp_sd, 1)) == -1 )
01828     {
01829         fprintf(stderr,"** our MP socket has gone bad?\n");
01830         close(rtin->mp_tcp_sd);
01831         rtin->mp_tcp_sd  = 0;
01832         rtin->mp_tcp_use = 0;   
01833         return -1;
01834     }
01835 
01836     remain = nt;
01837     while ( remain > 0 )
01838     {
01839         nvals = MIN(remain, 100);
01840 
01841         
01842         for ( c = 0; c < nvals; c++ )
01843             for ( c2 = 0; c2 < 6; c2++ )
01844                 data[6*c+c2] = mp[c2][c];
01845 
01846         if ( send(rtin->mp_tcp_sd, data, 6*nvals*sizeof(float), 0) == -1 )
01847         {
01848             fprintf(stderr,"** failed to send %d floats, closing socket...\n",
01849                     6*nvals);
01850             close(rtin->mp_tcp_sd);
01851             rtin->mp_tcp_sd  = 0;
01852             rtin->mp_tcp_use = 0;  
01853             return -1;
01854         }
01855 
01856         
01857         rtin->mp_nmsg++;
01858         rtin->mp_npsets += nvals;
01859 
01860         remain -= nvals;
01861     }
01862 
01863     return 0;
01864 }
01865 
01866 
01867 
01868 
01869 
01870 
01871 
01872 
01873 int RT_mp_comm_init( RT_input * rtin )
01874 {
01875     struct sockaddr_in   sin;
01876     struct hostent     * hostp;
01877     char                 magic_hi[] = { 0xab, 0xcd, 0xef, 0xab };
01878     int                  sd;
01879 
01880     if ( rtin->mp_tcp_sd != 0 )
01881         fprintf(stderr,"** warning, did we not close the MP socket?\n");
01882 
01883     if ( (hostp = gethostbyname(rtin->mp_host)) == NULL )
01884     {
01885         fprintf(stderr,"** cannot lookup host '%s'\n", rtin->mp_host);
01886         rtin->mp_tcp_use = -1;
01887         return -1;
01888     }
01889 
01890     
01891     memset(&sin, 0, sizeof(sin));
01892     sin.sin_family      = AF_INET;
01893     sin.sin_addr.s_addr = ((struct in_addr *)(hostp->h_addr))->s_addr;
01894     sin.sin_port        = htons(rtin->mp_port);
01895 
01896     
01897     if ( (sd = socket(AF_INET, SOCK_STREAM, 0)) == -1 )
01898     {
01899         perror("pe: socket");
01900         rtin->mp_tcp_use = -1;   
01901         return -1;
01902     }
01903 
01904     if ( connect(sd, (struct sockaddr *)&sin, sizeof(sin)) == -1 )
01905     {
01906         perror("pe: connect");
01907         rtin->mp_tcp_use = -1;
01908         return -1;
01909     }
01910 
01911     
01912     if ( send(sd, magic_hi, 4*sizeof(char), 0) == -1 )
01913     {
01914         perror("pe: send hello");
01915         rtin->mp_tcp_use = -1;
01916         return -1;
01917     }
01918 
01919     fprintf(stderr,"RT: MP: opened motion param socket to %s:%d\n",
01920             rtin->mp_host, rtin->mp_port);
01921 
01922     
01923 
01924     rtin->mp_tcp_sd = sd;
01925 
01926     return 0;
01927 }
01928 
01929 
01930 
01931 
01932 
01933 
01934 
01935 
01936 
01937 
01938 int RT_mp_comm_init_vars( RT_input * rtin )
01939 {
01940     char * ept, * cp;
01941     int    len;
01942 
01943     if ( rtin->mp_tcp_use < 0 )     
01944         return 0;
01945 
01946     if ( rtin->mp_tcp_sd != 0 )
01947         fprintf(stderr,"** warning, did we not close the MP socket?\n");
01948     rtin->mp_tcp_sd   = 0;
01949 
01950     
01951     ept = getenv("AFNI_REALTIME_MP_HOST_PORT") ;  
01952     if( ept == NULL )
01953         return 0;
01954 
01955     cp = strchr(ept, ':');      
01956 
01957     if ( cp == NULL || !isdigit(*(cp+1)) )
01958     {
01959         fprintf(stderr,"** env var AFNI_REALTIME_MP_HOST_PORT must be in the "
01960                        "form hostname:port_num\n   (var is '%s')\n", ept);
01961         return -1;
01962     }
01963 
01964     len = cp - ept;     
01965     if ( len > 127 )
01966     {
01967         fprintf(stderr,"** motion param hostname restricted to 127 bytes,\n"
01968                        "   found %d from host in %s\n", len, ept);
01969         return -1;
01970     }
01971 
01972     fprintf(stderr,"RT: MP: found motion param env var '%s'\n", ept);
01973 
01974     rtin->mp_port = atoi(cp+1);
01975     strncpy(rtin->mp_host, ept, len);
01976     rtin->mp_host[len] = '\0';
01977     rtin->mp_tcp_use = 1;
01978 
01979     return 0;
01980 }
01981 
01982 
01983 
01984 
01985 
01986 
01987 
01988 
01989 int RT_parser_init( RT_input * rtin )
01990 {
01991     PARSER_set_printout(1);
01992     rtin->p_code = PARSER_generate_code( rtin->p_expr );
01993 
01994     if ( ! rtin->p_code )
01995     {
01996         fprintf(stderr,"** cannot parse expression '%s'\n", rtin->p_expr);
01997         return -1;
01998     }
01999 
02000     
02001     PARSER_mark_symbols( rtin->p_code, rtin->p_has_sym );
02002     for ( rtin->p_max_sym = 26; rtin->p_max_sym > 0; rtin->p_max_sym-- )
02003         if ( rtin->p_has_sym[rtin->p_max_sym - 1] )
02004             break;
02005 
02006     if ( rtin->p_max_sym > 6 )
02007     {
02008         fprintf(stderr,"** parser expression may only contain symbols a-f\n");
02009         return -2;
02010     }
02011 
02012     return 0;
02013 }
02014 #endif
02015 
02016 
02017 
02018 
02019 
02020 
02021 
02022 #define BADNEWS     fprintf(stderr,"RT: illegal header info=%s\a\n",buf)
02023 #define STARTER(st) (strncmp(buf,st,strlen(st)) == 0)
02024 #define NBUF        1024
02025 
02026 int RT_process_info( int ninfo , char * info , RT_input * rtin )
02027 {
02028    int ii , jj , nstart,nend , nuse , nbuf ;
02029    char buf[NBUF] ;
02030 
02031    if( rtin == NULL || info == NULL || ninfo == 0 ) return -1 ;
02032 
02033    for( nend=0 ; nend < ninfo && info[nend] != '\0' ; nend++ ) ; 
02034    if( nend == ninfo ){
02035       fprintf(stderr,"RT: info string not NUL-terminated!\a\n") ;
02036       return -1 ;
02037    }
02038 
02039    
02040 
02041 
02042    nstart = 0 ;
02043    while( nstart < nend ){
02044 
02045 
02046 
02047       for( ; nstart < nend && isspace(info[nstart]) ; nstart++ ) ; 
02048       if( nstart >= nend ) break ;
02049 
02050 
02051 
02052       for( nbuf=0,jj=nstart ; nbuf < NBUF && info[jj] != '\n' && info[jj] != '\0' ; ){
02053          buf[nbuf++] = info[jj++] ;
02054       }
02055       if( nbuf == NBUF ){
02056          fprintf(stderr,"RT: line buffer overflow in control information!\a\n") ;
02057          nbuf-- ;
02058       }
02059       buf[nbuf] = '\0' ; nstart = jj ;
02060 
02061       if( verbose == 2 )
02062          fprintf(stderr,"RT: info line buffer=%s\n",buf) ;
02063       VMCHECK ;
02064 
02065       
02066       
02067 
02068       if( STARTER("ACQUISITION_TYPE") ){
02069          char typ[32] ;
02070 
02071          sscanf( buf , "ACQUISITION_TYPE %31s" , typ ) ;
02072 
02073               if( strcmp(typ,"2D+z")  == 0 ) rtin->dtype = DTYPE_2DZ ;
02074          else if( strcmp(typ,"2D+zt") == 0 ) rtin->dtype = DTYPE_2DZT ;
02075          else if( strcmp(typ,"3D")    == 0 ) rtin->dtype = DTYPE_3D ;
02076          else if( strcmp(typ,"3D+t")  == 0 ) rtin->dtype = DTYPE_3DT ;
02077          else
02078               BADNEWS ;
02079 
02080 #ifdef ALLOW_REGISTRATION
02081 
02082       
02083 
02084 
02085 
02086 
02087       } else if( STARTER("GRAPH_XRANGE") ){
02088          float fval = 0.0 ;
02089          sscanf( buf , "GRAPH_XRANGE %f" , &fval ) ;
02090          if( fval >= MIN_PIN && fval <= MAX_PIN ) {
02091              rtin->reg_graph_xnew = 1;
02092              rtin->reg_graph_xr   = fval;
02093 
02094              if( rtin->reg_graph && REG_IS_3D(rtin->reg_mode) &&
02095                  IM3D_OPEN(plint->im3d) )
02096              {
02097                  plot_ts_xypush(1-rtin->reg_graph_xnew, 1-rtin->reg_graph_ynew);
02098                  RT_set_grapher_pinnums((int)(fval+0.5));
02099              }
02100 
02101          } else
02102               BADNEWS ;
02103 
02104       } else if( STARTER("GRAPH_YRANGE") ){
02105          float fval = 0.0 ;
02106          sscanf( buf , "GRAPH_YRANGE %f" , &fval ) ;
02107          if( fval > 0.0 ) {
02108             rtin->reg_graph_ynew = 1;
02109             rtin->reg_graph_yr   = fval ;
02110 
02111             
02112             if( rtin->reg_graph && REG_IS_3D(rtin->reg_mode) )
02113                 plot_ts_xypush(1-rtin->reg_graph_xnew, 1-rtin->reg_graph_ynew);
02114          } else
02115             BADNEWS ;
02116 
02117       
02118 
02119 
02120       } else if( STARTER("GRAPH_EXPR") ){
02121          sscanf( buf , "GRAPH_EXPR %1024s" , rtin->p_expr ) ;
02122          rtin->p_expr[RT_MAX_EXPR] = '\0';
02123          if ( RT_parser_init(rtin) != 0 )
02124             BADNEWS ;
02125 #endif
02126 
02127       } else if( STARTER("NAME") ){
02128          char npr[THD_MAX_PREFIX] = "\0" ;
02129          
02130          sscanf( buf , "NAME %100s" , npr ) ; 
02131          if( THD_filename_pure(npr) ) strcpy( rtin->root_prefix , npr ) ;
02132          else
02133               BADNEWS ;
02134 
02135       } else if( STARTER("PREFIX") ){           
02136          char npr[THD_MAX_PREFIX] = "\0" ;
02137          
02138          sscanf( buf , "PREFIX %100s" , npr ) ;
02139          if( THD_filename_pure(npr) ) strcpy( rtin->root_prefix , npr ) ;
02140          else
02141               BADNEWS ;
02142 
02143       } else if( STARTER("NOTE") ) {            
02144          int nn = rtin->num_note ;
02145          if( nbuf > 6 ){
02146            int ii ;
02147            rtin->note = realloc( rtin->note , sizeof(char *)*(nn+1) ); 
02148            rtin->note[nn] = strdup(buf+5) ;                            
02149            for( ii=0 ; rtin->note[nn][ii] != '\0' ; ii++ )             
02150              if( rtin->note[nn][ii] == '\a' || rtin->note[nn][ii] == '\f' )
02151                rtin->note[nn][ii] = '\n';
02152            rtin->num_note ++ ;
02153          } else
02154            BADNEWS ;
02155 
02156       } else if( STARTER("NUMVOL") ){
02157          int val = 0 ;
02158          sscanf( buf , "NUMVOL %d" , &val ) ;
02159          if( val > 0 ) rtin->nr = val ;
02160          else
02161               BADNEWS ;
02162 
02163       } else if( STARTER("TR") ){          
02164          float val = 0.0 ;
02165          sscanf( buf , "TR %f" , &val ) ;
02166          if( val > 0.0 ) rtin->tr = val ;
02167          else
02168               BADNEWS ;
02169 
02170       } else if( STARTER("ZDELTA") ){
02171          float val = 0.0 ;
02172          sscanf( buf , "ZDELTA %f" , &val ) ;
02173          if( val > 0.0 ) rtin->dzz = val ;
02174          else
02175               BADNEWS ;
02176          if( verbose == 2 )
02177             fprintf(stderr,"RT: dzz = %g\n",rtin->dzz) ;
02178          VMCHECK ;
02179 
02180       } else if( STARTER("ZGAP") ){               
02181          float val = 0.0 ;
02182          sscanf( buf , "ZGAP %f" , &val ) ;
02183          if( val >= 0.0 ) rtin->zgap = val ;
02184          else
02185               BADNEWS ;
02186          if( verbose == 2 )
02187             fprintf(stderr,"RT: zgap = %g\n",rtin->zgap) ;
02188          VMCHECK ;
02189 
02190       } else if( STARTER("XYZOFF") ){             
02191          float xval = 0.0 , yval = 0.0 , zval = 0.0 ;
02192          sscanf( buf , "XYZOFF %f %f %f" , &xval , &yval , &zval ) ;
02193          rtin->xxoff = xval ; rtin->xcen = 1 ;
02194          rtin->yyoff = yval ; rtin->ycen = 1 ;
02195          rtin->zzoff = zval ; rtin->zcen = 1 ;
02196          if( verbose == 2 )
02197             fprintf(stderr,"RT: offset = %g %g %g\n",rtin->xxoff,rtin->yyoff,rtin->zzoff) ;
02198          VMCHECK ;
02199 
02200       } else if( STARTER("ZFIRST") ){   
02201          float val = 0.0 ;
02202          char dcode = ' ' ;
02203          sscanf( buf , "ZFIRST %f%c" , &val,&dcode ) ;
02204          rtin->zzorg   = val ;
02205          rtin->zcen    = 0 ;
02206          rtin->zzdcode = ORCODE(dcode) ;
02207          if( verbose == 2 )
02208             fprintf(stderr,"RT: zzorg = %g%c\n" ,
02209                     rtin->zzorg ,
02210                     (rtin->zzdcode < 0) ? ' ' : ORIENT_first[rtin->zzdcode] ) ;
02211          VMCHECK ;
02212 
02213       } else if( STARTER("XYZFIRST") ){  
02214          float xf=0.0,yf=0.0,zf=0.0 ;
02215          char  xc=' ',yc=' ',zc=' ' ;
02216          sscanf( buf , "XYZFIRST %f%c%f%c%f%c" , &xf,&xc,&yf,&yc,&zf,&zc ) ;
02217          rtin->xxorg = xf ; rtin->xcen = 0 ; rtin->xxdcode = ORCODE(xc) ;
02218          rtin->yyorg = yf ; rtin->ycen = 0 ; rtin->yydcode = ORCODE(yc) ;
02219          rtin->zzorg = zf ; rtin->zcen = 0 ; rtin->zzdcode = ORCODE(zc) ;
02220          if( verbose == 2 )
02221             fprintf(stderr,"RT: xxorg=%g%c yyorg=%g%c zzorg=%g%c\n" ,
02222                     rtin->xxorg ,
02223                     (rtin->xxdcode < 0) ? ' ' : ORIENT_first[rtin->xxdcode] ,
02224                     rtin->yyorg ,
02225                     (rtin->yydcode < 0) ? ' ' : ORIENT_first[rtin->yydcode] ,
02226                     rtin->zzorg ,
02227                     (rtin->zzdcode < 0) ? ' ' : ORIENT_first[rtin->zzdcode]
02228                    ) ;
02229          VMCHECK ;
02230 
02231       } else if( STARTER("XYFOV") ){
02232          float xval = 0.0 , yval = 0.0 , zval = 0.0 ;
02233          sscanf( buf , "XYFOV %f %f %f" , &xval , &yval , &zval ) ;
02234          if( xval > 0.0 ){
02235             rtin->xxfov = xval ;
02236             rtin->yyfov = (yval > 0.0) ? yval : xval ;
02237             if( zval > 0.0 ) rtin->zzfov = zval ;
02238          } else
02239                 BADNEWS ;
02240          if( verbose == 2 )
02241             fprintf(stderr,"RT: fov = %g %g %g\n",rtin->xxfov,rtin->yyfov,rtin->zzfov) ;
02242          VMCHECK ;
02243 
02244       } else if( STARTER("XYMATRIX") ){
02245          int xval = 0 , yval = 0 , zval = 0 ;
02246          sscanf( buf , "XYMATRIX %d %d %d" , &xval , &yval , &zval ) ;
02247          if( xval > 1 ){
02248             rtin->nxx = xval ;
02249             rtin->nyy = (yval > 1) ? yval : xval ;
02250             if( zval > 0 ){
02251                rtin->nzz = zval ;
02252                if( rtin->nzz < 1 ) fprintf(stderr,"RT: # slices = %d!\a\n",zval) ;
02253             }
02254          } else
02255                 BADNEWS ;
02256          if( verbose == 2 )
02257             fprintf(stderr,"RT: matrix = %d %d %d\n",rtin->nxx,rtin->nyy,rtin->nzz) ;
02258          VMCHECK ;
02259 
02260       } else if( STARTER("ZNUM") ){
02261          int zval = 0 ;
02262          sscanf( buf , "ZNUM %d" , &zval ) ;
02263          if( zval > 0 ){
02264              rtin->nzz = zval ;
02265              if( rtin->nzz < 1 ) fprintf(stderr,"RT: # slices = %d!\a\n",zval) ;
02266          }
02267          else
02268               BADNEWS ;
02269          if( verbose == 2 && rtin->nzz >= 1 )
02270             fprintf(stderr,"RT: # slices = %d\n",rtin->nzz) ;
02271          VMCHECK ;
02272 
02273       } else if( STARTER("DATUM") ){
02274          int ii ;
02275          char tstr[32] = "\0" ;
02276          sscanf( buf , "DATUM %31s" , tstr ) ;
02277          for( ii=0 ; ii <= LAST_MRI_TYPE ; ii++ )
02278             if( strcmp(tstr,MRI_TYPE_name[ii]) == 0 ) break ;
02279 
02280          if( AFNI_GOOD_DTYPE(ii) ) rtin->datum = ii ;
02281          else
02282               BADNEWS ;
02283          if( verbose == 2 )
02284             fprintf(stderr,"RT: datum code = %d\n",rtin->datum) ;
02285          VMCHECK ;
02286 
02287       } else if( STARTER("BYTEORDER") ){    
02288          int bo = 0 ;
02289          char tstr[10] = "\0" ;
02290          sscanf( buf, "BYTEORDER %9s", tstr ) ;
02291 
02292          
02293          if      ( strncmp(tstr,"LSB_FIRST",9) == 0 ) bo = LSB_FIRST ;
02294          else if ( strncmp(tstr,"MSB_FIRST",9) == 0 ) bo = MSB_FIRST ;
02295          else
02296              BADNEWS ;
02297 
02298          
02299          if ( bo != 0 ) {
02300             int local_bo, one = 1;
02301             local_bo = (*(char *)&one == 1) ? LSB_FIRST : MSB_FIRST ;
02302 
02303             
02304             if ( bo != local_bo )
02305                 rtin->swap_on_read = 1 ;
02306          }
02307 
02308          if( verbose > 1 )
02309             fprintf(stderr,"RT: BYTEORDER string = '%s', swap_on_read = %d\n",
02310                     BYTE_ORDER_STRING(bo), rtin->swap_on_read) ;
02311       } else if( STARTER("LOCK_ZORDER") ){  
02312          rtin->zorder_lock = 1 ;            
02313                                             
02314       } else if( STARTER("ZORDER") ){       
02315          if( ! rtin->zorder_lock ){
02316            char str[32] = "\0" ; int nord=0 , nb = 0 , nq ;
02317            sscanf( buf , "ZORDER %31s%n" , str , &nb ) ;
02318                 if( strcmp(str,"alt") == 0 ) rtin->zorder = ZORDER_ALT ;
02319            else if( strcmp(str,"seq") == 0 ) rtin->zorder = ZORDER_SEQ ;
02320            else if( strcmp(str,"explicit") == 0 ){
02321               rtin->zorder = ZORDER_EXP ;
02322               do{                                  
02323                  rtin->zseq[nord] = -1 ; nq = -1 ;
02324                  sscanf(buf+nb , "%d%n" , &(rtin->zseq[nord]) , &nq) ;
02325                  if( nq < 1 ) break ;              
02326                  nb += nq ; nord++ ;               
02327               } while( nb < nbuf ) ;               
02328               rtin->nzseq = nord ;                 
02329               if( nord < 1 || nord > NZMAX ) BADNEWS ;
02330            }
02331            else
02332                 BADNEWS ;
02333          }
02334 
02335       } else if( STARTER("TPATTERN") ){               
02336          if( ! rtin->zorder_lock ){                   
02337            char str[32] = "\0" ;
02338            sscanf( buf , "TPATTERN %31s" , str ) ;
02339                 if( strcmp(str,"alt+z") == 0 ) rtin->tpattern = ZORDER_ALT ;
02340            else if( strcmp(str,"seq+z") == 0 ) rtin->tpattern = ZORDER_SEQ ;
02341            else
02342                 BADNEWS ;
02343          }
02344 
02345       } else if( STARTER("XYZAXES") ){
02346          int ii , orx=-1,ory=-1,orz=-1 ;
02347          char xstr[32] = "\0" , ystr[32] = "\0" , zstr[32] = "\0" ;
02348 
02349          sscanf( buf , "XYZAXES %31s %31s %31s" , xstr,ystr,zstr ) ;
02350 
02351          for( ii=0 ; ii < 6 ; ii++ ){
02352             if( strcmp(xstr,ORIENT_shortstr[ii]) == 0 ||
02353                 strcmp(xstr,ORIENT_typestr[ii])  == 0 ||
02354                 strcmp(xstr,ORIENT_tinystr[ii])  == 0   ) orx = ii ;
02355 
02356             if( strcmp(ystr,ORIENT_shortstr[ii]) == 0 ||
02357                 strcmp(ystr,ORIENT_typestr[ii])  == 0 ||
02358                 strcmp(ystr,ORIENT_tinystr[ii])  == 0   ) ory = ii ;
02359 
02360             if( strcmp(zstr,ORIENT_shortstr[ii]) == 0 ||
02361                 strcmp(zstr,ORIENT_typestr[ii])  == 0 ||
02362                 strcmp(zstr,ORIENT_tinystr[ii])  == 0   ) orz = ii ;
02363          }
02364 
02365          if( orx >= 0 && ory >= 0 && orz >= 0 && OR3OK(orx,ory,orz) ){
02366             rtin->orcxx = orx ;
02367             rtin->orcyy = ory ;
02368             rtin->orczz = orz ;
02369          } else
02370                 BADNEWS ;
02371 
02372       } else if( STARTER("NUM_CHAN") ){     
02373          int nn=0 ;
02374          sscanf( buf , "NUM_CHAN %d",&nn) ;
02375          if( nn >= 1 && nn <= MAX_CHAN )
02376            rtin->num_chan = nn ;
02377          else
02378                 BADNEWS ;
02379 
02380       } else if( STARTER("DRIVE_AFNI") ){   
02381          char cmd[1024]="\0" ;
02382          int ii ;
02383          if( strlen(buf) < 11 ){
02384             fprintf(stderr,"RT: DRIVE_AFNI lacks command\n") ;
02385          } else {  
02386             MCW_strncpy(cmd,buf+11,1024) ;
02387             if( verbose == 2 )
02388                fprintf(stderr,"RT: command DRIVE_AFNI %s\n",cmd) ;
02389             ii = AFNI_driver( cmd ) ;  
02390             if( ii < 0 )
02391                fprintf(stderr,"RT: command DRIVE_AFNI %s **FAILS**\n",cmd) ;
02392          }
02393 
02394       } else {                              
02395          BADNEWS ;
02396       }
02397    }  
02398 
02399 
02400 
02401    if( rtin->image_mode ){
02402       rtin->nzz      = 1 ;  
02403       rtin->num_chan = 1 ;  
02404    }
02405 
02406 
02407 
02408    if( rtin->num_chan > 1 ){
02409 
02410      if( rtin->reg_mode > 0 && verbose )
02411        fprintf(stderr,"RT: %d channel acquisition => no registration!\n",rtin->num_chan) ;
02412 
02413      if( rtin->func_code > 0 && verbose )
02414        fprintf(stderr,"RT: %d channel acquisition => no function!\n"    ,rtin->num_chan) ;
02415 
02416      rtin->reg_mode  = REGMODE_NONE ;  
02417      rtin->func_code = FUNC_NONE ;     
02418      rtin->func_func = NULL ;
02419      rtin->reg_graph = 0 ;
02420    }
02421 
02422    if( rtin->nzz == 1 ){                   
02423      rtin->zorder = ZORDER_SEQ ;
02424      rtin->tpattern = ZORDER_SEQ ;
02425      if( REG_IS_3D(rtin->reg_mode) ){
02426        rtin->reg_mode = REGMODE_NONE ;
02427        fprintf(stderr,"RT: can't do 3D registration on 2D dataset!\n") ;
02428      }
02429    }
02430 
02431    RT_check_info( rtin , 0 ) ;
02432 
02433 
02434 
02435    if( AFNI_GOOD_DTYPE(rtin->datum) && rtin->nxx > 0 && rtin->nyy > 0 ){
02436       int n1 = mri_datum_size( rtin->datum ) ;
02437 
02438       if( rtin->dtype == DTYPE_2DZT || rtin->dtype == DTYPE_2DZ )
02439          rtin->imsize = rtin->nxx * rtin->nyy * n1 ;
02440       else if( rtin->nzz > 0 )
02441          rtin->imsize = rtin->nxx * rtin->nyy * rtin->nzz * n1 ;
02442    }
02443 
02444    
02445    if ( rtin->swap_on_read == 1 ) {
02446 
02447       if( (rtin->datum != MRI_short) &&         
02448           (rtin->datum != MRI_int)   &&         
02449           (rtin->datum != MRI_float) &&
02450           (rtin->datum != MRI_complex) )
02451       {
02452          if( rtin->datum != MRI_byte )          
02453              fprintf(stderr,"RT: BYTEORDER applies only to short, int, float "
02454                             "or complex\n");
02455          rtin->swap_on_read = 0;
02456       }
02457    }
02458 
02459 
02460 
02461    return (nend+1) ;
02462 }
02463 
02464 
02465 
02466 
02467 
02468 
02469 
02470 void RT_start_dataset( RT_input * rtin )
02471 {
02472    THD_ivec3 nxyz , orixyz ;
02473    THD_fvec3 dxyz , orgxyz ;
02474    int nvox , npix , n1 , ii , cc ;
02475    char npr[THD_MAX_PREFIX] , ccpr[THD_MAX_PREFIX] ;
02476 
02477    
02478 
02479 
02480    if( rtin->image_mode ){
02481       nvox = rtin->nxx * rtin->nyy ;
02482       n1   = mri_datum_size( rtin->datum ) ;
02483 
02484       rtin->sbr_size = nvox * n1 ;                
02485       rtin->sbr[0]   = malloc( rtin->sbr_size ) ; 
02486       rtin->imsize   = rtin->sbr_size ;
02487       rtin->im[0]    = rtin->sbr[0] ;             
02488       rtin->nzz      = 1 ;
02489 
02490       rtin->image_space = mri_new_vol_empty( rtin->nxx, rtin->nyy, 1, rtin->datum ) ;
02491       mri_fix_data_pointer( rtin->sbr[0] , rtin->image_space ) ;
02492 
02493       return ;
02494    }
02495 
02496    
02497 
02498 
02499    
02500 
02501 
02502    if( rtin->num_chan > 1 ){
02503      int ic , tc , nc=AFNI_count_controllers() , sn ;
02504 
02505      Three_D_View *im3d = plint->im3d ;             
02506      if( !IM3D_OPEN(im3d) )                         
02507        im3d = AFNI_find_open_controller() ;
02508 
02509      sn = im3d->vinfo->sess_num ;                   
02510 
02511      
02512 
02513      if( nc < rtin->num_chan && nc < MAX_CONTROLLERS ){
02514        nc = MIN( rtin->num_chan , MAX_CONTROLLERS ) - nc ;  
02515 
02516        fprintf(stderr,
02517                "RT: %d channel data requires opening %d more AFNI controllers",
02518                rtin->num_chan , nc ) ;
02519 
02520        for( ic=0 ; ic < nc ; ic++ )                         
02521          AFNI_clone_controller_CB(NULL,NULL,NULL) ;
02522      }
02523 
02524      
02525 
02526      num_open_controllers = AFNI_count_controllers() ;
02527      for( ic=nc=0 ; ic < MAX_CONTROLLERS ; ic++ ){
02528        if( IM3D_OPEN(GLOBAL_library.controllers[ic]) ){
02529          open_controller[nc]       = GLOBAL_library.controllers[ic] ;
02530          open_controller_index[nc] = ic ;
02531          nc++ ;
02532        }
02533      }
02534      nc = num_open_controllers ;  
02535 
02536      
02537 
02538      tc = MIN( nc , rtin->num_chan ) ;
02539      for( cc=0 ; cc < rtin->num_chan ; cc++ ){
02540        if( cc < tc ) rtin->im3d[cc] = open_controller[cc] ; 
02541        else          rtin->im3d[cc] = NULL ;                
02542 
02543        
02544 
02545        rtin->sess_num[cc] = sn ;
02546        rtin->sess[cc]     = GLOBAL_library.sslist->ssar[sn] ;
02547      }
02548 
02549    
02550 
02551    } else {
02552      Three_D_View *im3d = plint->im3d ;             
02553      if( !IM3D_OPEN(im3d) )                         
02554        im3d = AFNI_find_open_controller() ;
02555 
02556      rtin->im3d[0]     = im3d ;
02557      rtin->sess_num[0] = rtin->im3d[0]->vinfo->sess_num ;
02558      rtin->sess[0]     = GLOBAL_library.sslist->ssar[rtin->sess_num[0]] ;
02559    }
02560 
02561    
02562   
02563 
02564    for( cc=0 ; cc < rtin->num_chan ; cc++ ){
02565      rtin->dset[cc] = EDIT_empty_copy(NULL) ;
02566      tross_Append_History( rtin->dset[cc] , "plug_realtime: creation" ) ;
02567 
02568      if( rtin->num_note > 0 && rtin->note != NULL ){  
02569        for( ii=0 ; ii < rtin->num_note ; ii++ )
02570          tross_Add_Note( rtin->dset[cc] , rtin->note[ii] ) ;
02571      }
02572    }
02573 
02574    
02575 
02576 
02577    for( ii=1 ; ; ii++ ){
02578       sprintf( npr , "%.*s#%03d" , RT_MAX_PREFIX, rtin->root_prefix , ii ) ;
02579 
02580       if( rtin->num_chan == 1 ){                  
02581 
02582          if( PLUTO_prefix_ok(npr) ) break ;
02583 
02584       } else {                                    
02585 
02586         for( cc=0 ; cc < rtin->num_chan ; cc++ ){ 
02587           sprintf(ccpr, "%s_%02d", npr,cc+1 ) ;
02588           if( !PLUTO_prefix_ok(ccpr) ) break ;    
02589         }
02590         if( cc == rtin->num_chan ) break ;        
02591       }
02592    }
02593 
02594    
02595 
02596 
02597    rtin->dxx = rtin->xxfov / rtin->nxx ;
02598    rtin->dyy = rtin->yyfov / rtin->nyy ;
02599 
02600    
02601 
02602    if( rtin->zzfov > 0 ) rtin->dzz = rtin->zzfov / rtin->nzz + rtin->zgap ;
02603 
02604    
02605 
02606    if( rtin->xcen ) rtin->xxorg = 0.5 * (rtin->nxx - 1) * rtin->dxx + rtin->xxoff ;
02607    if( rtin->ycen ) rtin->yyorg = 0.5 * (rtin->nyy - 1) * rtin->dyy + rtin->yyoff ;
02608    if( rtin->zcen ) rtin->zzorg = 0.5 * (rtin->nzz - 1) * rtin->dzz + rtin->zzoff ;
02609 
02610    
02611 
02612    if( ORIENT_sign[rtin->orcxx] == '-' ) rtin->dxx = - rtin->dxx ;
02613    if( ORIENT_sign[rtin->orcyy] == '-' ) rtin->dyy = - rtin->dyy ;
02614    if( ORIENT_sign[rtin->orczz] == '-' ) rtin->dzz = - rtin->dzz ;
02615 
02616    
02617 
02618 
02619 
02620 
02621 
02622 #if 0
02623    
02624 
02625   
02626 
02627    if( ORIENT_sign[rtin->orcxx] == '+' ) rtin->xxorg = - rtin->xxorg ;
02628    if( ORIENT_sign[rtin->orcyy] == '+' ) rtin->yyorg = - rtin->yyorg ;
02629 #endif
02630 
02631    
02632 
02633 
02634 
02635 
02636 
02637 
02638    if( rtin->zzdcode < 0 ){  
02639 
02640       if( ORIENT_sign[rtin->orczz] == '+' ) rtin->zzorg = - rtin->zzorg ;
02641 
02642    } else {  
02643 
02644       
02645 
02646 
02647       if( rtin->orczz != rtin->zzdcode                 &&
02648           rtin->orczz != ORIENT_OPPOSITE(rtin->zzdcode)  ){  
02649 
02650          fprintf(stderr,"RT: ZFIRST direction code = %c but Z axis = %s!\a\n",
02651                  ORIENT_first[rtin->zzdcode] , ORIENT_shortstr[rtin->orczz] ) ;
02652 
02653          if( ORIENT_sign[rtin->orczz] == '+' ) rtin->zzorg = - rtin->zzorg ;
02654 
02655       } else {  
02656 
02657          if( ORIENT_sign[rtin->zzdcode] == '+' ) rtin->zzorg = - rtin->zzorg ;
02658       }
02659    }
02660 
02661    
02662 
02663    if( rtin->xxdcode < 0 ){
02664       if( ORIENT_sign[rtin->orcxx] == '+' ) rtin->xxorg = - rtin->xxorg ;
02665    } else {
02666       if( rtin->orcxx != rtin->xxdcode                 &&
02667           rtin->orcxx != ORIENT_OPPOSITE(rtin->xxdcode)  ){
02668          fprintf(stderr,"RT: XFIRST direction code = %c but X axis = %s!\a\n",
02669                  ORIENT_first[rtin->xxdcode] , ORIENT_shortstr[rtin->orcxx] ) ;
02670          if( ORIENT_sign[rtin->orcxx] == '+' ) rtin->xxorg = - rtin->xxorg ;
02671       } else {  
02672          if( ORIENT_sign[rtin->xxdcode] == '+' ) rtin->xxorg = - rtin->xxorg ;
02673       }
02674    }
02675 
02676    
02677 
02678    if( rtin->yydcode < 0 ){
02679       if( ORIENT_sign[rtin->orcyy] == '+' ) rtin->yyorg = - rtin->yyorg ;
02680    } else {
02681       if( rtin->orcyy != rtin->yydcode                 &&
02682           rtin->orcyy != ORIENT_OPPOSITE(rtin->yydcode)  ){
02683          fprintf(stderr,"RT: YFIRST direction code = %c but Y axis = %s!\a\n",
02684                  ORIENT_first[rtin->yydcode] , ORIENT_shortstr[rtin->orcyy] ) ;
02685          if( ORIENT_sign[rtin->orcyy] == '+' ) rtin->yyorg = - rtin->yyorg ;
02686       } else {  
02687          if( ORIENT_sign[rtin->yydcode] == '+' ) rtin->yyorg = - rtin->yyorg ;
02688       }
02689    }
02690 
02691    
02692   
02693 
02694    nxyz.ijk[0]   = rtin->nxx   ; dxyz.xyz[0]   = rtin->dxx ;
02695    nxyz.ijk[1]   = rtin->nyy   ; dxyz.xyz[1]   = rtin->dyy ;
02696    nxyz.ijk[2]   = rtin->nzz   ; dxyz.xyz[2]   = rtin->dzz ;
02697 
02698    orixyz.ijk[0] = rtin->orcxx ; orgxyz.xyz[0] = rtin->xxorg ;
02699    orixyz.ijk[1] = rtin->orcyy ; orgxyz.xyz[1] = rtin->yyorg ;
02700    orixyz.ijk[2] = rtin->orczz ; orgxyz.xyz[2] = rtin->zzorg ;
02701 
02702    for( cc=0 ; cc < rtin->num_chan ; cc++ ){  
02703 
02704      if( rtin->num_chan == 1 )
02705        strcpy( ccpr , npr ) ;                      
02706      else
02707        sprintf( ccpr , "%s_%02d" , npr , cc+1 ) ;  
02708 
02709      EDIT_dset_items( rtin->dset[cc] ,
02710                          ADN_prefix      , ccpr ,
02711                          ADN_datum_all   , rtin->datum ,
02712                          ADN_nxyz        , nxyz ,
02713                          ADN_xyzdel      , dxyz ,
02714                          ADN_xyzorg      , orgxyz ,
02715                          ADN_xyzorient   , orixyz ,
02716                          ADN_malloc_type , DATABLOCK_MEM_MALLOC ,
02717                          ADN_nvals       , 1 ,
02718                          ADN_type        , HEAD_ANAT_TYPE ,
02719                          ADN_view_type   , VIEW_ORIGINAL_TYPE ,
02720                          ADN_func_type   , ANAT_EPI_TYPE ,
02721                       ADN_none ) ;
02722 
02723       
02724 
02725 
02726       if( rtin->dtype == DTYPE_3DT ||                      
02727          (rtin->dtype == DTYPE_2DZT && rtin->nzz == 1) ){  
02728 
02729          EDIT_dset_items( rtin->dset[cc] ,
02730                              ADN_ntt      , 1 ,
02731                              ADN_ttorg    , 0.0 ,
02732                              ADN_ttdel    , rtin->tr ,
02733                              ADN_ttdur    , 0.0 ,
02734                              ADN_tunits   , UNITS_SEC_TYPE ,
02735                           ADN_none ) ;
02736 
02737       } else if( rtin->dtype == DTYPE_2DZT ){  
02738 
02739          float * tpattern  = (float *) malloc( sizeof(float) * rtin->nzz ) ;
02740          float   tframe    = rtin->tr / rtin->nzz ;
02741          float   tsl ;
02742          int     ii ;
02743 
02744          if( rtin->zorder == ZORDER_ALT || rtin->tpattern == ZORDER_ALT ){
02745             
02746             tsl = 0.0 ;
02747             for( ii=0 ; ii < rtin->nzz ; ii+=2 ){
02748                tpattern[ii] = tsl ; tsl += tframe ;
02749             }
02750             for( ii=1 ; ii < rtin->nzz ; ii+=2 ){
02751                tpattern[ii] = tsl ; tsl += tframe ;
02752             }
02753          }
02754          
02755          
02756          
02757          else {
02758             tsl = 0.0 ;
02759             for( ii=0 ; ii < rtin->nzz ; ii++ ){
02760                tpattern[ii] = tsl ; tsl += tframe ;
02761             }
02762          }
02763 
02764          EDIT_dset_items( rtin->dset[cc] ,
02765                              ADN_ntt      , 1 ,
02766                              ADN_ttorg    , 0.0 ,
02767                              ADN_ttdel    , rtin->tr ,
02768                              ADN_ttdur    , 0.0 ,
02769                              ADN_tunits   , UNITS_SEC_TYPE ,
02770                              ADN_nsl      , rtin->nzz ,
02771                              ADN_zorg_sl  , rtin->zzorg ,
02772                              ADN_dz_sl    , rtin->dzz ,
02773                              ADN_toff_sl  , tpattern ,
02774                           ADN_none ) ;
02775 
02776          free( tpattern ) ;
02777       }
02778 
02779       rtin->afni_status[cc] = 0 ;  
02780       DSET_lock(rtin->dset[cc]) ;  
02781    }
02782 
02783 #ifdef ALLOW_REGISTRATION
02784    
02785 
02786    if( REG_MAKE_DSET(rtin->reg_mode) &&
02787        ((rtin->dtype==DTYPE_2DZT) || (rtin->dtype==DTYPE_3DT)) ){
02788 
02789       rtin->reg_dset = EDIT_empty_copy( rtin->dset[0] ) ;
02790       tross_Append_History( rtin->reg_dset , "plug_realtime: registration" ) ;
02791 
02792       strcpy(ccpr,npr) ;
02793            if( REG_IS_2D(rtin->reg_mode) ) strcat(ccpr,"%reg2D") ;
02794       else if( REG_IS_3D(rtin->reg_mode) ) strcat(ccpr,"%reg3D") ;
02795       else                                 strcat(ccpr,"%reg"  ) ;
02796 
02797       EDIT_dset_items( rtin->reg_dset , ADN_prefix , ccpr , ADN_none ) ;
02798       DSET_lock(rtin->reg_dset) ;
02799 
02800       if( rtin->num_note > 0 && rtin->note != NULL ){  
02801         for( ii=0 ; ii < rtin->num_note ; ii++ )
02802           tross_Add_Note( rtin->reg_dset , rtin->note[ii] ) ;
02803       }
02804    }
02805 
02806    rtin->reg_status    = 0 ;
02807    rtin->reg_nvol      = 0 ;
02808 
02809    
02810 
02811 
02812 
02813 
02814 #endif
02815 
02816    
02817 
02818 
02819    nvox = rtin->nxx * rtin->nyy * rtin->nzz ;
02820    n1   = mri_datum_size( rtin->datum ) ;
02821 
02822    rtin->sbr_size = nvox * n1 ;                
02823    for( cc=0 ; cc < rtin->num_chan ; cc++ ){
02824      rtin->sbr[cc] = malloc( rtin->sbr_size ) ; 
02825      if( rtin->sbr[cc] == NULL ){
02826        fprintf(stderr,
02827                "RT: can't malloc data space for real-time channel %02d!\a\n",
02828                cc+1) ;
02829        EXIT(1) ;
02830      }
02831    }
02832 
02833    if( rtin->dtype == DTYPE_2DZT || rtin->dtype == DTYPE_2DZ )
02834       rtin->imsize = rtin->nxx * rtin->nyy * n1 ;
02835    else
02836       rtin->imsize = nvox * n1 ;
02837 
02838    for( cc=0 ; cc < rtin->num_chan ; cc++ ){
02839      rtin->im[cc]   = rtin->sbr[cc] ;  
02840      rtin->nsl[cc]  = 0 ;              
02841      rtin->nvol[cc] = 0 ;              
02842    }
02843 
02844 
02845 
02846 
02847 
02848    if( rtin->bufar != NULL ){
02849       int ii , upsave ;
02850       MRI_IMAGE * ibb ;
02851       char * bbb ;
02852 
02853       if( verbose == 2 )
02854          fprintf(stderr,"RT: putting %d buffered images into dataset\n" ,
02855                         IMARR_COUNT(rtin->bufar) ) ;
02856       VMCHECK ;
02857 
02858       upsave = update ;  
02859       update = 0 ;
02860 
02861       for( ii=0 ; ii < IMARR_COUNT(rtin->bufar) ; ii++ ){
02862         ibb = IMARR_SUBIMAGE(rtin->bufar,ii) ;                    
02863         bbb = (char *) MRI_BYTE_PTR( ibb ) ;                      
02864         memcpy( rtin->im[rtin->cur_chan] , bbb , rtin->imsize ) ; 
02865         mri_free( ibb ) ;                                         
02866         RT_process_image( rtin ) ;                                
02867       }
02868       FREE_IMARR( rtin->bufar ) ;   
02869 
02870       update = upsave ;
02871 
02872       if( verbose == 2 )
02873          fprintf(stderr,"RT: buffered images all placed into dataset\n") ;
02874       VMCHECK ;
02875    }
02876 
02877 
02878 
02879 
02880    { char str[1024] ;
02881      char acq[128] , *sli ;
02882 
02883      switch( rtin->dtype ){
02884        case DTYPE_2DZ:  strcpy(acq,"2D+z (1 volume, by slice")        ; break ;
02885        case DTYPE_2DZT: strcpy(acq,"2D+zt (multivolume, by slice")    ; break ;
02886        case DTYPE_3D:   strcpy(acq,"3D (1 volume, all at once)")      ; break ;
02887        case DTYPE_3DT:  strcpy(acq,"3D+t (multivolume, by 3D array)") ; break ;
02888        default:         strcpy(acq,"Bizarro world")                   ; break ;
02889      }
02890 
02891      if( rtin->dtype == DTYPE_2DZ || rtin->dtype == DTYPE_2DZT ){
02892        switch( rtin->zorder ){
02893          case ZORDER_ALT: strcat(acq," - interleaved order)") ; break ;
02894          case ZORDER_SEQ: strcat(acq," - sequential order)")  ; break ;
02895          case ZORDER_EXP: strcat(acq," - explicit order)")    ; break ;
02896        }
02897      }
02898 
02899      switch( rtin->orczz ){
02900        case ORI_I2S_TYPE:
02901        case ORI_S2I_TYPE: sli = "(Axial)"    ; break ;
02902 
02903        case ORI_R2L_TYPE:
02904        case ORI_L2R_TYPE: sli = "(Sagittal)" ; break ;
02905 
02906        case ORI_P2A_TYPE:
02907        case ORI_A2P_TYPE: sli = "(Coronal)"  ; break ;
02908 
02909        default:           sli = "\0"         ; break ;  
02910      }
02911 
02912      sprintf(str," \n"
02913                  " ** Realtime Header Information **\n"
02914                  "\n"
02915                  " Dataset prefix  : %s\n"
02916                  " Brick Dimensions: %d x %d x %d\n"
02917                  " Voxel Grid Size : %.4f x %.4f x %.4f (mm)\n"
02918                  " Grid Orientation: %s x %s x %s %s\n"
02919                  " Grid Offset     : %.1f x %.1f x %.1f (mm)\n"
02920                  " Datum Type      : %s\n"
02921                  " Number Channels : %d\n"
02922                  " Acquisition Type: %s\n" ,
02923              npr ,
02924              rtin->nxx , rtin->nyy , rtin->nzz ,
02925              fabs(rtin->dxx) , fabs(rtin->dyy) , fabs(rtin->dzz) ,
02926              ORIENT_shortstr[rtin->orcxx],ORIENT_shortstr[rtin->orcyy],
02927                ORIENT_shortstr[rtin->orczz] , sli ,
02928              rtin->xxorg , rtin->yyorg , rtin->zzorg ,
02929              MRI_TYPE_name[rtin->datum] ,
02930              rtin->num_chan ,
02931              acq
02932           ) ;
02933 
02934      PLUTO_popup_transient(plint,str);
02935    }
02936 
02937    return ;
02938 }
02939 
02940 
02941 
02942 
02943 
02944 #define COMMAND_MARKER        "Et Earello Endorenna utulien!!"
02945 #define COMMAND_MARKER_LENGTH 30
02946 
02947 void RT_read_image( RT_input * rtin , char * im )
02948 {
02949    int need , have , nbuffed ;
02950 
02951 
02952 
02953    if( rtin == NULL || im == NULL ){
02954      fprintf(stderr,"RT: illegal inputs to RT_read_image!\a\n") ;
02955      EXIT(1) ;
02956    }
02957 
02958    if( rtin->imsize <= 0 ){
02959      fprintf(stderr,"RT: image data present, but don't know its size!\a\n") ;
02960      EXIT(1) ;
02961    }
02962 
02963 
02964 
02965    have = rtin->nbuf ;
02966 
02967 
02968 
02969    if( have > 0 ){
02970 
02971       nbuffed = MIN( have , rtin->imsize ) ;  
02972       memcpy( im , rtin->buf , nbuffed ) ;    
02973 
02974       if( nbuffed < have ){                   
02975          memmove( rtin->buf , rtin->buf + nbuffed , rtin->nbuf - nbuffed ) ;
02976          rtin->nbuf = rtin->nbuf - nbuffed ;
02977       } else {                                
02978          rtin->nbuf = 0 ;
02979       }
02980    } else {
02981       nbuffed = 0 ;
02982    }
02983 
02984 
02985 
02986 
02987    need = rtin->imsize - nbuffed ;  
02988 
02989    
02990 
02991    if( need > 0 )
02992       iochan_recvall( rtin->ioc_data , im + nbuffed , need ) ;
02993 
02994    
02995 
02996 
02997 
02998    if( memcmp(im,COMMAND_MARKER,COMMAND_MARKER_LENGTH) == 0 )
02999      rtin->marked_for_death = 1 ;
03000    else {
03001       
03002       if ( rtin->swap_on_read != 0 ) {
03003          if( rtin->datum == MRI_short )
03004             mri_swap2( rtin->imsize / 2, (short *)im );
03005          else
03006             mri_swap4( rtin->imsize / 4, (int *)im );
03007       }
03008    }
03009 
03010 
03011    return ;
03012 }
03013 
03014 
03015 
03016 
03017 
03018 
03019 int RT_process_data( RT_input * rtin )
03020 {
03021    int vdone ;
03022 
03023 
03024 
03025    if( rtin->sbr[0] == NULL && rtin->info_ok ){
03026       if( verbose == 2 )
03027          fprintf(stderr,"RT: info complete --> creating dataset.\n") ;
03028       VMCHECK ;
03029       RT_start_dataset( rtin ) ;
03030    }
03031 
03032 
03033 
03034    while( rtin->nbuf > 0 || iochan_readcheck(rtin->ioc_data,0) > 0 ){
03035 
03036       if( rtin->im[0] != NULL ){  
03037 
03038          RT_read_image( rtin , rtin->im[rtin->cur_chan] ) ; 
03039 
03040          if( rtin->marked_for_death ) return 0 ;            
03041 
03042          RT_process_image( rtin ) ;                         
03043 
03044       } else {                 
03045 
03046          MRI_IMAGE * newim ;
03047          char * newbuf ;
03048 
03049          if( rtin->imsize <= 0 ){
03050            fprintf(stderr,"RT: image data present, but don't know its size!\a\n") ;
03051            EXIT(1) ;
03052          }
03053 
03054          if( rtin->bufar == NULL )    
03055            INIT_IMARR(rtin->bufar) ;
03056 
03057          if( verbose == 2 && rtin->bufar->num % 10 == 0 ){
03058            fprintf(stderr,"RT: reading image into buffer[%d]\n",rtin->bufar->num) ;
03059            VMCHECK ;
03060          }
03061 
03062          newim  = mri_new( rtin->imsize , 1 , MRI_byte ) ; 
03063          newbuf = (char *) MRI_BYTE_PTR(newim) ;           
03064          ADDTO_IMARR( rtin->bufar , newim ) ;              
03065          RT_read_image( rtin , newbuf ) ;                  
03066          if( rtin->marked_for_death ) return 0 ;           
03067       }
03068 
03069       RT_process_xevents( rtinp ) ;
03070 
03071    }  
03072 
03073 
03074 
03075 
03076 
03077 
03078 
03079    return 1 ;
03080 }
03081 
03082 
03083 
03084 
03085 
03086 static void RT_image_kfun(void * kdata)                
03087 {
03088    RT_input * rtin = (RT_input *) kdata ;
03089    if( rtin != NULL ) rtin->image_handle = NULL ;
03090    return ;
03091 }
03092 
03093 
03094 
03095 
03096 
03097 
03098 
03099 #define MIN_TO_GRAPH 2
03100 
03101 void RT_process_image( RT_input * rtin )
03102 {
03103    int vdone , cc = rtin->cur_chan ;
03104 
03105 
03106 
03107    if( rtin->image_mode ){
03108       if( rtin->image_handle != NULL ){
03109          PLUTO_imseq_addto( rtin->image_handle , rtin->image_space ) ;
03110       } else {
03111          rtin->image_handle = PLUTO_imseq_popim( rtin->image_space, RT_image_kfun,rtin ) ;
03112          PLUTO_imseq_retitle( rtin->image_handle , "Realtime Images" ) ;
03113       }
03114       return ;
03115    }
03116 
03117 
03118 
03119    if( rtin->dtype == DTYPE_2DZT || rtin->dtype == DTYPE_2DZ ){
03120 
03121       if( verbose == 2 )
03122          fprintf(stderr,"RT: read image into dataset brick %d slice %d.\n",
03123                  rtin->nvol[cc],rtin->nsl[cc]) ;
03124 
03125       rtin->nsl[cc] ++ ;                     
03126       vdone = (rtin->nsl[cc] == rtin->nzz) ; 
03127 
03128    } else if( rtin->dtype == DTYPE_3DT || rtin->dtype == DTYPE_3D ){
03129 
03130 #if 0
03131       if( verbose == 2 )
03132         fprintf(stderr,"RT: read image into dataset brick %d\n",rtin->nvol[cc]) ;
03133 #endif
03134 
03135       vdone = 1 ;                        
03136    }
03137 
03138 
03139 
03140    if( vdone ){
03141 
03142       rtin->nvol[cc] ++ ;        
03143 
03144       if( verbose == 2 )
03145          fprintf(stderr,"RT: now have %d complete sub-bricks in channel %02d.\n",
03146                  rtin->nvol[cc],cc+1) ;
03147       VMCHECK ;
03148 
03149       
03150 
03151 
03152       if( rtin->nvol[cc] == 1 )
03153          EDIT_substitute_brick( rtin->dset[cc] , 0 , rtin->datum , rtin->sbr[cc] ) ;
03154       else
03155          EDIT_add_brick( rtin->dset[cc] , rtin->datum , 0.0 , rtin->sbr[cc] ) ;
03156 
03157       VMCHECK ;
03158       if( verbose == 2 )
03159          fprintf(stderr,"RT: added brick to dataset in channel %02d\n",cc+1) ;
03160       VMCHECK ;
03161 
03162       
03163 
03164 
03165       if( rtin->dtype == DTYPE_3DT || rtin->dtype == DTYPE_2DZT ){
03166          EDIT_dset_items( rtin->dset[cc] , ADN_ntt , rtin->nvol[cc] , ADN_none ) ;
03167          if( verbose == 2 )
03168             fprintf(stderr,"RT: altered ntt in dataset header in channel %02d\n",cc+1) ;
03169          VMCHECK ;
03170       } else if( rtin->nvol[cc] > 1 ){
03171          fprintf(stderr,"RT: have %d bricks for time-independent dataset!\a\n",
03172                  rtin->nvol[cc]) ;
03173          VMCHECK ;
03174       }
03175 
03176 #ifdef ALLOW_REGISTRATION
03177       
03178       switch( rtin->reg_mode ){
03179            case REGMODE_2D_RTIME: RT_registration_2D_realtime( rtin ) ;
03180            break ;
03181 
03182            case REGMODE_3D_RTIME:
03183            case REGMODE_3D_ESTIM: RT_registration_3D_realtime( rtin ) ;
03184            break ;
03185       }
03186 #endif 
03187 
03188 
03189 
03190       if( rtin->func_code > 0 ){
03191          int jj ;
03192 
03193 
03194 
03195          if( rtin->func_condit == 0 ){
03196 #if 0
03197             jj = rtin->func_func( rtin , INIT_MODE ) ;
03198 #else
03199             AFNI_CALL_VALU_2ARG( rtin->func_func , int,jj ,
03200                                  RT_input *,rtin , int,INIT_MODE ) ;
03201 #endif
03202             if( jj < 0 ){ rtin->func_code = 0 ; rtin->func_func = NULL ; }
03203             rtin->func_condit = 1 ;  
03204          }
03205 
03206 
03207 
03208          if( rtin->func_code > 0 )
03209 #if 0
03210             jj = rtin->func_func( rtin , rtin->nvol[cc] - 1 ) ;
03211 #else
03212             AFNI_CALL_VALU_2ARG( rtin->func_func , int,jj ,
03213                                  RT_input *,rtin , int,rtin->nvol[cc]-1 ) ;
03214 #endif
03215       }
03216 
03217 
03218 
03219       if( verbose == 2 )
03220          fprintf(stderr,"RT: malloc-ing %d bytes for next volume in channel %02d\n",
03221                  rtin->sbr_size,cc+1) ;
03222       VMCHECK ;
03223 
03224       rtin->sbr[cc] = malloc( rtin->sbr_size ) ;
03225       if( rtin->sbr[cc] == NULL ){
03226         fprintf(stderr,"RT: can't malloc real-time brick %d for channel %02d\a\n",
03227                 rtin->nvol[cc]+1,cc+1) ;
03228         EXIT(1) ;
03229       }
03230       if( verbose == 2 )
03231          fprintf(stderr,"RT: malloc succeeded\n") ;
03232       VMCHECK ;
03233 
03234       rtin->im[cc]  = rtin->sbr[cc] ;  
03235       rtin->nsl[cc] = 0 ;              
03236 
03237 
03238 
03239       if( update > 0 ){  
03240          int doit ;
03241 
03242          if( verbose == 2 )
03243             fprintf(stderr,"RT: checking for update status\n") ;
03244          VMCHECK ;
03245 
03246          doit = ( (rtin->dtype==DTYPE_3DT || rtin->dtype==DTYPE_2DZT) &&
03247                   (cc+1 == rtin->num_chan)                            && 
03248                   (rtin->nvol[cc] == MIN_TO_GRAPH ||
03249                    (rtin->nvol[cc] > MIN_TO_GRAPH && rtin->nvol[cc] % update == 0)) ) ;
03250 
03251          if( doit ){
03252             if( verbose == 2 )
03253                fprintf(stderr,"RT: about to tell AFNI about dataset.\n") ;
03254             VMCHECK ;
03255             RT_tell_afni(rtin,TELL_NORMAL) ;
03256          }
03257       }
03258 
03259    } else {  
03260 
03261       int noff ;  
03262 
03263       if( rtin->zorder == ZORDER_SEQ ){  
03264                                          
03265          noff = rtin->nsl[cc] ;          
03266 
03267       } else if ( rtin->zorder == ZORDER_ALT ){  
03268 
03269          int nhalf = (rtin->nzz + 1)/2 ;         
03270 
03271          if( rtin->nsl[cc] < nhalf )
03272             noff = 2 * rtin->nsl[cc] ;               
03273          else
03274             noff = 1 + 2 * (rtin->nsl[cc] - nhalf) ; 
03275       }
03276 
03277       rtin->im[cc] = rtin->sbr[cc] + (noff * rtin->imsize) ; 
03278 
03279    }
03280 
03281    
03282 
03283    if( rtin->num_chan > 1 )
03284      rtin->cur_chan = (cc+1) % rtin->num_chan ;
03285 
03286    return ;
03287 }
03288 
03289 
03290 
03291 
03292 
03293 void RT_tell_afni( RT_input *rtin , int mode )
03294 {
03295    int cc ;
03296 
03297    if( rtin == NULL ) return ;
03298 
03299    
03300 
03301    for( cc=0 ; cc < rtin->num_chan ; cc++ )
03302      RT_tell_afni_one( rtin , mode , cc ) ;
03303 
03304    
03305 
03306    if( mode == TELL_FINAL && ISVALID_DSET(rtin->dset[0]) ){
03307      char qbuf[256*(MAX_CHAN+1)] , zbuf[256] ;
03308      sprintf( qbuf ,
03309                 " \n"
03310                 " Acquisition Terminated\n\n"
03311                 " Brick Dimensions: %d x %d x %d  Datum: %s\n\n" ,
03312                rtin->nxx,rtin->nyy,rtin->nzz , MRI_TYPE_name[rtin->datum] );
03313 
03314      for( cc=0 ; cc < rtin->num_chan ; cc++ ){
03315        if( ISVALID_DSET(rtin->dset[cc]) )
03316          sprintf( zbuf ,
03317                   " Channel %02d: dataset %s has %d sub-bricks\n",
03318                   cc+1 , DSET_FILECODE(rtin->dset[cc]) , rtin->nvol[cc] ) ;
03319        else
03320          sprintf( zbuf ,
03321                   " Channel %d: INVALID DATASET?!\n",cc) ;
03322        strcat( qbuf , zbuf ) ;
03323      }
03324      strcat(qbuf,"\n") ;
03325 
03326      PLUTO_beep(); PLUTO_popup_transient(plint,qbuf);
03327 
03328      if( verbose == 2 ) SHOW_TIMES ;
03329 
03330      sync() ;  
03331    }
03332 
03333    return ;
03334 }
03335 
03336 
03337 
03338 
03339 
03340 void RT_tell_afni_one( RT_input *rtin , int mode , int cc )
03341 {
03342    Three_D_View * im3d ;
03343    THD_session * sess ;
03344    THD_3dim_dataset * old_anat ;
03345    int ii , id , afni_init=0 ;
03346    char clll , *cstr ;
03347    MCW_arrowval * tav ;
03348 
03349 
03350 
03351    if( rtin == NULL || !ISVALID_DSET(rtin->dset[cc]) ) return ;
03352 
03353    im3d = rtin->im3d[cc] ;                      
03354    sess = rtin->sess[cc] ;                      
03355 
03356    if( im3d != NULL ){   
03357 
03358      tav  = im3d->vwid->imag->time_index_av ;   
03359      ii   = AFNI_controller_index( im3d ) ;
03360      cstr = AFNI_controller_label( im3d ) ; clll = cstr[1] ;
03361 
03362      old_anat = im3d->anat_now ;  
03363    }
03364 
03365 
03366 
03367    if( rtin->afni_status[cc] == 0 ){  
03368 
03369       EDIT_dset_items( rtin->dset[cc],
03370                          ADN_directory_name,sess->sessname,
03371                        ADN_none ) ;
03372 
03373       if( im3d != NULL ){
03374         if( verbose )
03375            fprintf(stderr , "RT: sending dataset %s with %d bricks\n"
03376                             "    to AFNI[%c], session %s\n" ,
03377                    DSET_FILECODE(rtin->dset[cc]) , rtin->nvol[cc] ,
03378                    clll , sess->sessname ) ;
03379 
03380       }
03381       THD_load_statistics( rtin->dset[cc] ) ;
03382 
03383 
03384 
03385       if( GLOBAL_library.have_dummy_dataset ) UNDUMMYIZE ;
03386 
03387       id = sess->num_dsset ;
03388 
03389       if( id >= THD_MAX_SESSION_SIZE ){
03390         fprintf(stderr,"RT: max number of anat datasets exceeded!\a\n") ;
03391         EXIT(1) ;
03392       }
03393       sess->dsset[id][VIEW_ORIGINAL_TYPE] = rtin->dset[cc] ;
03394       sess->num_dsset = id+1 ;
03395       POPDOWN_strlist_chooser ;
03396 
03397       if( ISFUNC(rtin->dset[cc]) )
03398         AFNI_force_adoption( sess , False ) ;
03399 
03400 
03401 
03402       if( im3d != NULL ){
03403         if( ISANAT(rtin->dset[cc]) )
03404            im3d->vinfo->anat_num = sess->num_dsset - 1 ;
03405         else
03406            im3d->vinfo->func_num = sess->num_dsset - 1 ;
03407 
03408         im3d->vinfo->sess_num = rtin->sess_num[cc] ;
03409 
03410         im3d->vinfo->time_index = 0 ;
03411         AV_assign_ival( tav , 0 ) ;
03412       }
03413 
03414       afni_init             = 1 ; 
03415       rtin->afni_status[cc] = 1 ; 
03416 
03417    } else {  
03418 
03419       THD_update_statistics( rtin->dset[cc] ) ;
03420 
03421       if( im3d != NULL ){
03422         if( mode != TELL_FINAL && verbose )
03423           fprintf(stderr,"RT: update with %d bricks in channel %02d to AFNI[%c]\n",
03424                   rtin->nvol[cc],cc+1,clll) ;
03425 
03426         tav->fmax = tav->imax = im3d->vinfo->time_index = rtin->nvol[cc] - 1  ;
03427         AV_assign_ival( tav , tav->imax ) ;
03428       }
03429 
03430    }
03431 
03432 
03433 
03434    if( rtin->func_dset != NULL ){
03435       int jj ;
03436 
03437 #if 0
03438       jj = rtin->func_func( rtin , UPDATE_MODE ) ;  
03439 #else
03440       AFNI_CALL_VALU_2ARG( rtin->func_func , int,jj ,
03441                            RT_input *,rtin , int,UPDATE_MODE ) ;
03442 #endif
03443 
03444       if( rtin->func_condit > 1 ){             
03445 
03446          THD_load_statistics( rtin->func_dset ) ; 
03447 
03448          if( rtin->func_status == 0 ){  
03449 
03450             if( im3d != NULL && verbose )
03451                fprintf(stderr , "RT: sending dataset %s with %d bricks\n"
03452                                 "    to AFNI controller [%c] session %s\n" ,
03453                        DSET_FILECODE(rtin->func_dset) , DSET_NVALS(rtin->func_dset) ,
03454                        clll , sess->sessname ) ;
03455 
03456             EDIT_dset_items( rtin->func_dset, ADN_directory_name,sess->sessname, ADN_none ) ;
03457             id = sess->num_dsset ;
03458             if( id >= THD_MAX_SESSION_SIZE ){
03459               fprintf(stderr,"RT: max number of datasets exceeded!\a\n") ;
03460               EXIT(1) ;
03461             }
03462             sess->dsset[id][VIEW_ORIGINAL_TYPE] = rtin->func_dset ; sess->num_dsset++ ;
03463             AFNI_force_adoption( sess , False ) ;
03464             POPDOWN_strlist_chooser ;
03465 
03466             if( im3d != NULL ){
03467               im3d->vinfo->func_num = sess->num_dsset - 1 ;
03468               AFNI_SETUP_FUNC_ON(im3d) ;
03469             }
03470 
03471             rtin->func_status = 1 ;   
03472             afni_init = 1 ;           
03473 
03474          } else {  
03475 
03476 
03477 
03478          }
03479       }  
03480    }  
03481 
03482 #ifdef ALLOW_REGISTRATION
03483 
03484 
03485    if( rtin->reg_dset != NULL && rtin->reg_nvol > 0 ){
03486 
03487       if( rtin->reg_status == 0 ){  
03488 
03489          THD_load_statistics( rtin->reg_dset ) ;
03490 
03491          if( im3d != NULL ){
03492            if( verbose )
03493                  fprintf(stderr , "RT: sending dataset %s with %d bricks\n"
03494                                   "    to AFNI controller [%c] session %s\n" ,
03495                          DSET_FILECODE(rtin->reg_dset) , DSET_NVALS(rtin->reg_dset) ,
03496                          clll , sess->sessname ) ;
03497          }
03498 
03499          EDIT_dset_items( rtin->reg_dset, ADN_directory_name,sess->sessname, ADN_none ) ;
03500 
03501          id = sess->num_dsset ;
03502          if( id >= THD_MAX_SESSION_SIZE ){
03503            fprintf(stderr,"RT: max number of datasets exceeded!\a\n") ;
03504            EXIT(1) ;
03505          }
03506          sess->dsset[id][VIEW_ORIGINAL_TYPE] = rtin->reg_dset ; sess->num_dsset = id+1 ;
03507          POPDOWN_strlist_chooser ;
03508 
03509          rtin->reg_status = 1 ;   
03510 
03511       } else {  
03512 
03513          THD_update_statistics( rtin->reg_dset ) ;
03514       }
03515    }
03516 #endif
03517 
03518 
03519 
03520    if( afni_init ){  
03521 
03522      if( im3d != NULL ){
03523        AFNI_SETUP_VIEW(im3d,VIEW_ORIGINAL_TYPE) ;
03524        if( EQUIV_DSETS(rtin->dset[cc],old_anat) ) THD_update_statistics( rtin->dset[cc] ) ;
03525        else                                       THD_load_statistics  ( rtin->dset[cc] ) ;
03526 
03527        AFNI_initialize_view( old_anat , im3d ) ;  
03528      }
03529 
03530    } else {          
03531 
03532       Three_D_View * qq3d ;
03533       int review ;
03534 
03535       
03536 
03537       for( ii=0 ; ii < MAX_CONTROLLERS ; ii++ ){
03538          qq3d = GLOBAL_library.controllers[ii] ;
03539          if( !IM3D_OPEN(qq3d) ) break ;  
03540 
03541          review = (qq3d == im3d)                             ||   
03542                   EQUIV_DSETS(rtin->dset[cc],qq3d->anat_now) ||   
03543                   ( rtin->func_dset != NULL   &&                  
03544                     qq3d->vinfo->func_visible &&
03545                     EQUIV_DSETS(rtin->func_dset,qq3d->fim_now) ) ;
03546 
03547 #ifdef ALLOW_REGISTRATION
03548          review = review || ( rtin->reg_dset != NULL &&       
03549                               rtin->reg_nvol > 0     &&
03550                               EQUIV_DSETS(rtin->reg_dset,qq3d->anat_now) ) ;
03551 #endif
03552 
03553          if( review ){
03554             AFNI_modify_viewing( qq3d , False ) ;  
03555          }
03556       }
03557    }
03558 
03559    if( im3d != NULL ) XmUpdateDisplay( THE_TOPSHELL ) ;
03560 
03561 
03562 
03563    if( mode == TELL_FINAL ){
03564 
03565       int cmode ;
03566 
03567       if( verbose == 2 )
03568          fprintf(stderr,"RT: finalizing dataset to AFNI (including disk output).\n") ;
03569 
03570 #if 0
03571       if( im3d != NULL )
03572         fprintf(stderr , "RT: sending dataset %s with %d bricks\n"
03573                          "    to AFNI controller [%c] session %s\n" ,
03574                 DSET_FILECODE(rtin->dset[cc]) , rtin->nvol[cc] ,
03575                 clll , sess->sessname ) ;
03576 #endif
03577 
03578 #if 0
03579       THD_load_statistics( rtin->dset[cc] ) ;
03580 #endif
03581 
03582       
03583 
03584       cmode = THD_get_write_compression() ;
03585       THD_set_write_compression(COMPRESS_NONE) ;
03586       SHOW_AFNI_PAUSE ;
03587 
03588       THD_write_3dim_dataset( NULL,NULL , rtin->dset[cc] , True ) ;
03589       DSET_unlock( rtin->dset[cc] ) ;  
03590 
03591       if( rtin->func_dset != NULL ){
03592          int jj ;
03593 #if 0
03594          jj = rtin->func_func( rtin , FINAL_MODE ) ;
03595 #else
03596          AFNI_CALL_VALU_2ARG( rtin->func_func , int,jj ,
03597                               RT_input *,rtin , int,FINAL_MODE ) ;
03598 #endif
03599          THD_write_3dim_dataset( NULL,NULL , rtin->func_dset , True ) ;
03600          DSET_unlock( rtin->func_dset ) ;  
03601          THD_force_malloc_type( rtin->func_dset->dblk , DATABLOCK_MEM_ANY ) ;
03602       }
03603 
03604 #ifdef ALLOW_REGISTRATION
03605       if( rtin->reg_dset != NULL && rtin->reg_nvol > 0 ){
03606          THD_write_3dim_dataset( NULL,NULL , rtin->reg_dset , True ) ;
03607          DSET_unlock( rtin->reg_dset ) ;
03608          THD_force_malloc_type( rtin->reg_dset->dblk , DATABLOCK_MEM_ANY ) ;
03609       }
03610 #endif
03611 
03612       THD_set_write_compression(cmode) ;  
03613 
03614       AFNI_force_adoption( sess , GLOBAL_argopt.warp_4D ) ;
03615       AFNI_make_descendants( GLOBAL_library.sslist ) ;
03616       THD_force_malloc_type( rtin->dset[cc]->dblk , DATABLOCK_MEM_ANY ) ;
03617 
03618       AFNI_purge_unused_dsets() ;
03619       SHOW_AFNI_READY ;
03620    }
03621 
03622    return ;
03623 }
03624 
03625 
03626 
03627 
03628 
03629 
03630 void RT_finish_dataset( RT_input * rtin )
03631 {
03632    int ii , cc , nbad=0 ;
03633 
03634    if( rtin->image_mode ){
03635       if( verbose == 2 ) SHOW_TIMES ;
03636       return ;
03637    }
03638 
03639    for( cc=0 ; cc < rtin->num_chan ; cc++ ){
03640 
03641       if( ! ISVALID_3DIM_DATASET(rtin->dset[cc]) ){
03642         fprintf(stderr,"RT: attempt to finish channel %02d with incomplete dataset!\a\n",cc+1) ;
03643         nbad++ ; continue ;
03644       }
03645 
03646       if( rtin->nvol[cc] < 1 ){
03647         fprintf(stderr,"RT: attempt to finish channel %02d with 0 completed bricks!\a\n",cc+1) ;
03648         DSET_delete( rtin->dset[cc] ) ; rtin->dset[cc] = NULL ;
03649         if( rtin->func_dset != NULL ){
03650            DSET_delete( rtin->func_dset ) ; rtin->func_dset = NULL ;
03651         }
03652 #ifdef ALLOW_REGISTRATION
03653         if( rtin->reg_dset != NULL ){
03654            DSET_delete( rtin->reg_dset ) ; rtin->reg_dset = NULL ;
03655         }
03656 #endif
03657         nbad++ ;
03658       }
03659 
03660       if( rtin->nsl[cc] > 0 )
03661          fprintf(stderr,"RT: finish channel %02d with %d slices unused!\a\n",
03662                  cc+1,rtin->nsl[cc]);
03663 
03664       fprintf(stderr,"RT: finish channel %02d with %d bricks completed.\n",
03665               cc+1,rtin->nvol[cc]) ;
03666    }
03667 
03668    if( verbose ) SHOW_TIMES ;
03669    if( nbad    ) return ;
03670 
03671 #ifdef ALLOW_REGISTRATION
03672    
03673 
03674    switch( rtin->reg_mode ){
03675       case REGMODE_2D_ATEND: RT_registration_2D_atend( rtin ) ; break ;
03676       case REGMODE_3D_ATEND: RT_registration_3D_atend( rtin ) ; break ;
03677    }
03678 
03679    
03680 
03681    if( rtin->reg_graph && rtin->reg_nest > 1 && REG_IS_2D(rtin->reg_mode) ){
03682       float * yar[4] ;  
03683       int * iar , ii , nn = rtin->reg_nest ;
03684       static char * nar[3] = { "\\Delta x [mm]" , "\\Delta y [mm]" , "\\phi   [\\degree]" } ;
03685 
03686       if( verbose == 2 )
03687          fprintf(stderr,"RT: graphing estimated 2D motion parameters\n") ;
03688 
03689       
03690 
03691       iar    = (int *)   malloc( sizeof(int)   * nn ) ;  
03692       yar[0] = (float *) malloc( sizeof(float) * nn ) ;  
03693       yar[1] = (float *) malloc( sizeof(float) * nn ) ;  
03694       yar[2] = (float *) malloc( sizeof(float) * nn ) ;  
03695       yar[3] = (float *) malloc( sizeof(float) * nn ) ;  
03696 
03697       for( ii=0 ; ii < nn ; ii++ ){
03698          iar[ii] = ii ; yar[0][ii] = rtin->reg_tim[ii] ;
03699       }
03700 
03701       qsort_floatint( nn , yar[0] , iar ) ;     
03702 
03703       for( ii=0 ; ii < nn ; ii++ ){             
03704          yar[1][ii] = rtin->reg_dx [ iar[ii] ] ;
03705          yar[2][ii] = rtin->reg_dy [ iar[ii] ] ;
03706          yar[3][ii] = rtin->reg_phi[ iar[ii] ] ;
03707       }
03708 
03709       plot_ts_lab( THE_DISPLAY ,
03710                    nn , yar[0] , -3 , yar+1 ,
03711                    "time" , NULL , DSET_FILECODE(rtin->dset[0]) , nar , NULL ) ;
03712 
03713       free(iar) ; free(yar[0]) ; free(yar[1]) ; free(yar[2]) ; free(yar[3]) ;
03714    }
03715 
03716    
03717    
03718 
03719    if( rtin->reg_graph && rtin->reg_nest > 1 && REG_IS_3D(rtin->reg_mode) &&
03720        ( rtin->reg_graph_xnew == 0 || rtin->reg_graph_ynew == 0 ) ){
03721       float * yar[7] ;
03722       int     ycount = -6 ;
03723       int     nn = rtin->reg_nest ;
03724       static char * nar[6] = {
03725          "\\Delta I-S [mm]" , "\\Delta R-L [mm]" , "\\Delta A-P [mm]" ,
03726          "Roll [\\degree]" , "Pitch [\\degree]" , "Yaw [\\degree]"  } ;
03727 
03728       char *ttl = malloc( strlen(DSET_FILECODE(rtin->dset[0])) + 32 ) ;
03729       strcpy(ttl,"\\noesc ") ;
03730       strcat(ttl,DSET_FILECODE(rtin->dset[0])) ;
03731       if( rtin->reg_mode == REGMODE_3D_ESTIM ) strcat(ttl," [Estimate]") ;
03732 
03733       if( verbose == 2 )
03734          fprintf(stderr,"RT: graphing estimated 3D motion parameters\n") ;
03735 
03736       
03737 
03738       yar[0] = rtin->reg_rep   ;  
03739       yar[1] = rtin->reg_dx    ;  
03740       yar[2] = rtin->reg_dy    ;  
03741       yar[3] = rtin->reg_dz    ;  
03742       yar[4] = rtin->reg_phi   ;  
03743       yar[5] = rtin->reg_psi   ;  
03744       yar[6] = rtin->reg_theta ;  
03745 
03746       if ( rtin->p_code )
03747       {
03748          ycount = 1;
03749          yar[1] = rtin->reg_eval;
03750       }
03751 
03752       plot_ts_lab( THE_DISPLAY ,
03753                    nn , yar[0] , ycount , yar+1 ,
03754                    "reps" , NULL , ttl , nar , NULL ) ;
03755 
03756       free(ttl) ;
03757    }
03758 
03759    
03760    if ( rtin->mp_tcp_use )
03761       RT_mp_comm_close( rtin );
03762 
03763    
03764    if ( rtin->p_code )
03765    {
03766       free( rtin->p_code ) ;
03767       rtin->p_code = NULL ;
03768    }
03769 #endif
03770 
03771 
03772 
03773    RT_tell_afni(rtin,TELL_FINAL) ;
03774 
03775    return ;
03776 }
03777 
03778 #ifdef ALLOW_REGISTRATION
03779 
03780 
03781 
03782 
03783 
03784 
03785 
03786 
03787 
03788 
03789 void RT_set_grapher_pinnums( int pinnum )
03790 {
03791     
03792 
03793     if( pinnum < MIN_PIN || pinnum > MAX_PIN || !IM3D_OPEN(plint->im3d) )
03794         return;
03795 
03796     drive_MCW_grapher( plint->im3d->g123, graDR_setpinnum, (XtPointer) pinnum );
03797     drive_MCW_grapher( plint->im3d->g231, graDR_setpinnum, (XtPointer) pinnum );
03798     drive_MCW_grapher( plint->im3d->g312, graDR_setpinnum, (XtPointer) pinnum );
03799 }
03800 
03801 
03802 
03803 
03804 
03805 void RT_registration_2D_realtime( RT_input * rtin )
03806 {
03807    int tt , ntt ;
03808 
03809    if( rtin->reg_dset == NULL ) return ;
03810 
03811    
03812 
03813    if( rtin->reg_2dbasis == NULL ){  
03814 
03815       
03816 
03817       if( rtin->reg_base_index >= rtin->nvol[0] ) return ;  
03818 
03819       
03820 
03821       if( verbose )
03822          fprintf(stderr,"RT: setting up 2D registration 'realtime'\n") ;
03823 
03824       SHOW_AFNI_PAUSE ;
03825       RT_registration_2D_setup( rtin ) ;  
03826 
03827       if( rtin->reg_2dbasis == NULL ){
03828          fprintf(stderr,"RT: can't setup %s registration!\a\n",
03829                  REG_strings[REGMODE_2D_RTIME] ) ;
03830          DSET_delete( rtin->reg_dset ) ; rtin->reg_dset = NULL ;
03831          rtin->reg_mode = REGMODE_NONE ;
03832          SHOW_AFNI_READY ; return ;
03833       }
03834    }
03835 
03836    
03837 
03838    ntt = DSET_NUM_TIMES( rtin->dset[0] ) ;
03839    for( tt=rtin->reg_nvol ; tt < ntt ; tt++ )
03840       RT_registration_2D_onevol( rtin , tt ) ;
03841 
03842    
03843 
03844    XmUpdateDisplay( THE_TOPSHELL ) ;
03845    SHOW_AFNI_READY ; return ;
03846 }
03847 
03848 
03849 
03850 
03851 
03852 
03853 void RT_registration_2D_atend( RT_input * rtin )
03854 {
03855    int tt , ntt ;
03856 
03857    
03858 
03859    if( rtin->reg_base_index >= rtin->nvol[0] ){
03860       fprintf(stderr,"RT: can't do %s registration: not enough 3D volumes!\a\n",
03861               REG_strings[REGMODE_2D_ATEND] ) ;
03862       DSET_delete( rtin->reg_dset ) ; rtin->reg_dset = NULL ;
03863       rtin->reg_mode = REGMODE_NONE ;
03864       return ;
03865    }
03866 
03867    
03868 
03869    if( verbose )
03870       fprintf(stderr,"RT: starting 2D registration 'at end'\n") ;
03871 
03872    SHOW_AFNI_PAUSE ;
03873    RT_registration_2D_setup( rtin ) ;
03874 
03875    if( rtin->reg_2dbasis == NULL ){
03876       fprintf(stderr,"RT: can't setup %s registration!\a\n",
03877               REG_strings[REGMODE_2D_ATEND] ) ;
03878       DSET_delete( rtin->reg_dset ) ; rtin->reg_dset = NULL ;
03879       rtin->reg_mode = REGMODE_NONE ;
03880       SHOW_AFNI_READY ; return ;
03881    }
03882 
03883    
03884 
03885    ntt = DSET_NUM_TIMES( rtin->dset[0] ) ;
03886    for( tt=0 ; tt < ntt ; tt++ ){
03887       XmUpdateDisplay( THE_TOPSHELL ) ;
03888       RT_registration_2D_onevol( rtin , tt ) ;
03889       if( verbose == 1 ) fprintf(stderr,"%d",tt%10) ;
03890    }
03891    if( verbose == 1 ) fprintf(stderr,"\n") ;
03892 
03893    
03894 
03895    RT_registration_2D_close( rtin ) ;
03896    if( verbose ) SHOW_TIMES ;
03897    SHOW_AFNI_READY ; return ;
03898 }
03899 
03900 
03901 
03902 
03903 
03904 void RT_registration_2D_setup( RT_input * rtin )
03905 {
03906    int ibase = rtin->reg_base_index ;
03907    int kk , nx,ny,nz , kind , nbar ;
03908    MRI_IMAGE * im ;
03909    char * bar ;
03910 
03911    nx   = DSET_NX( rtin->dset[0] ) ;
03912    ny   = DSET_NY( rtin->dset[0] ) ;
03913    nz   = DSET_NZ( rtin->dset[0] ) ;
03914    kind = DSET_BRICK_TYPE( rtin->dset[0] , ibase ) ;
03915 
03916    rtin->reg_nvol  = 0 ;
03917 
03918    rtin->reg_2dbasis = (MRI_2dalign_basis **)
03919                          malloc( sizeof(MRI_2dalign_basis *) * nz ) ;
03920 
03921    im   = mri_new_vol_empty( nx,ny,1 , kind ) ;        
03922    bar  = DSET_BRICK_ARRAY( rtin->dset[0] , ibase ) ;  
03923    nbar = im->nvox * im->pixel_size ;               
03924 
03925    for( kk=0 ; kk < nz ; kk++ ){                         
03926       mri_fix_data_pointer( bar + kk*nbar , im ) ;             
03927       rtin->reg_2dbasis[kk] = mri_2dalign_setup( im , NULL ) ;
03928    }
03929 
03930    kk = rtin->reg_resam ;
03931    if( kk == MRI_QUINTIC || kk == MRI_HEPTIC )
03932       kk = MRI_BICUBIC ; 
03933 
03934    mri_2dalign_method( MRI_BILINEAR, MRI_BICUBIC, kk ) ;
03935 
03936    mri_fix_data_pointer( NULL , im ) ; mri_free( im ) ;   
03937    return ;
03938 }
03939 
03940 
03941 
03942 
03943 
03944 void RT_registration_2D_close( RT_input * rtin )
03945 {
03946    int kk , nz ;
03947 
03948    nz = DSET_NZ( rtin->dset[0] ) ;
03949    for( kk=0 ; kk < nz ; kk++ )
03950       mri_2dalign_cleanup( rtin->reg_2dbasis[kk] ) ;
03951 
03952    free( rtin->reg_2dbasis ) ; rtin->reg_2dbasis = NULL ;
03953    return ;
03954 }
03955 
03956 
03957 
03958 
03959 
03960 #ifndef D2RFAC
03961 #  define D2RFAC (PI/180.0)
03962 #  define R2DFAC (180.0/PI)
03963 #endif
03964 
03965 void RT_registration_2D_onevol( RT_input * rtin , int tt )
03966 {
03967    int kk , nx,ny,nz , kind , nbar ;
03968    MRI_IMAGE * im , * rim , * qim ;
03969    char * bar , * rar , * qar ;
03970    float dx,dy,phi ;        
03971    int   nest , nxy ;
03972 
03973    
03974 
03975    if( rtin->dset[0] == NULL || rtin->reg_dset == NULL ) return ;
03976 
03977    nx   = DSET_NX( rtin->dset[0] ) ;
03978    ny   = DSET_NY( rtin->dset[0] ) ; nxy = nx * ny ;
03979    nz   = DSET_NZ( rtin->dset[0] ) ;
03980    kind = DSET_BRICK_TYPE( rtin->dset[0] , 0 ) ;
03981 
03982    im   = mri_new_vol_empty( nx,ny,1 , kind ) ;     
03983    bar  = DSET_BRICK_ARRAY( rtin->dset[0] , tt ) ;  
03984    nbar = im->nvox * im->pixel_size ;               
03985 
03986    
03987 
03988    if( verbose == 2 )
03989       fprintf(stderr,"RT: 2D registering sub-brick %d",tt) ;
03990 
03991    rar = (char *) malloc( sizeof(char) * nx*ny*nz * im->pixel_size ) ;
03992 
03993    if( rar == NULL ){
03994       fprintf(stderr,"RT: can't malloc space for registered dataset!\a\n") ;
03995       DSET_delete( rtin->reg_dset ) ; rtin->reg_dset = NULL ;
03996       rtin->reg_mode = REGMODE_NONE ;
03997       return ;
03998    }
03999 
04000    
04001 
04002    for( kk=0 ; kk < nz ; kk++ ){
04003 
04004       if( verbose == 2 ) fprintf(stderr,".") ;
04005 
04006       mri_fix_data_pointer( bar + kk*nbar , im ) ;  
04007 
04008       
04009 
04010       rim = mri_2dalign_one( rtin->reg_2dbasis[kk] , im , &dx , &dy , &phi ) ;
04011 
04012       
04013 
04014       nest = rtin->reg_nest ;
04015       rtin->reg_tim = (float *) realloc( (void *) rtin->reg_tim ,
04016                                          sizeof(float) * (nest+1) ) ;
04017       rtin->reg_dx  = (float *) realloc( (void *) rtin->reg_dx  ,
04018                                          sizeof(float) * (nest+1) ) ;
04019       rtin->reg_dy  = (float *) realloc( (void *) rtin->reg_dy  ,
04020                                          sizeof(float) * (nest+1) ) ;
04021       rtin->reg_phi = (float *) realloc( (void *) rtin->reg_phi ,
04022                                          sizeof(float) * (nest+1) ) ;
04023 
04024       rtin->reg_tim[nest] = THD_timeof_vox( tt , kk*nxy , rtin->dset[0] ) ;
04025       rtin->reg_dx [nest] = dx * DSET_DX(rtin->dset[0]) ;
04026       rtin->reg_dy [nest] = dy * DSET_DY(rtin->dset[0]) ;
04027       rtin->reg_phi[nest] = phi * R2DFAC             ; rtin->reg_nest ++ ;
04028 
04029       
04030 
04031 
04032       switch( kind ){
04033          case MRI_float:                        
04034             qar = (char *) MRI_FLOAT_PTR(rim) ;
04035          break ;
04036 
04037          case MRI_short:
04038             qim = mri_to_short(1.0,rim) ; mri_free(rim) ; rim = qim ;
04039             qar = (char *) MRI_SHORT_PTR(rim) ;
04040          break ;
04041 
04042          case MRI_byte:
04043             qim = mri_to_byte(rim) ; mri_free(rim) ; rim = qim ;
04044             qar = (char *) MRI_BYTE_PTR(rim) ;
04045          break ;
04046 
04047          default:
04048             fprintf(stderr,"RT: can't do registration on %s images!\a\n",
04049                     MRI_TYPE_name[kind] ) ;
04050             DSET_delete( rtin->reg_dset ) ; rtin->reg_dset = NULL ;
04051             rtin->reg_mode = REGMODE_NONE ;
04052             free(rar) ;
04053             mri_free(rim) ; mri_fix_data_pointer(NULL,im) ; mri_free(im) ;
04054          return ;
04055       }
04056 
04057       
04058 
04059       memcpy( rar + kk*nbar , qar , nbar ) ;
04060 
04061       mri_free(rim) ; 
04062    }
04063 
04064    mri_fix_data_pointer(NULL,im) ; mri_free(im) ;   
04065 
04066    
04067 
04068    if( tt == 0 )
04069       EDIT_substitute_brick( rtin->reg_dset , 0 , rtin->datum , rar ) ;
04070    else
04071       EDIT_add_brick( rtin->reg_dset , rtin->datum , 0.0 , rar ) ;
04072 
04073    rtin->reg_nvol = tt+1 ;
04074 
04075    EDIT_dset_items( rtin->reg_dset , ADN_ntt , rtin->reg_nvol ,  ADN_none ) ;
04076 
04077    if( verbose == 2 ) fprintf(stderr,"\n") ;
04078    return ;
04079 }
04080 
04081 #endif 
04082 
04083 
04084 #ifdef ALLOW_REGISTRATION
04085 
04086 
04087 
04088 
04089 
04090 
04091 
04092 
04093 void MTD_killfunc( MEM_topshell_data * mp )
04094 {
04095    
04096 
04097    if( mp == NULL ) return ;
04098    if( rtinp != NULL && mp == rtinp->mp ){
04099       if( verbose ) fprintf(stderr,"RT: user killed active realtime graph\n") ;
04100       rtinp->mp = NULL ;
04101    } else {
04102       if( verbose ) fprintf(stderr,"RT: user killed inactive realtime graph\n") ;
04103    }
04104 
04105    if( mp->userdata != NULL ){ free(mp->userdata) ; mp->userdata = NULL ; }
04106    return ;
04107 }
04108 
04109 
04110 
04111 
04112 
04113 void RT_registration_3D_realtime( RT_input * rtin )
04114 {
04115    int tt , ntt , ttbot ;
04116 
04117    
04118 
04119    if( rtin->reg_3dbasis == NULL ){  
04120 
04121       
04122 
04123       if( rtin->reg_base_index >= rtin->nvol[0] ) return ;  
04124 
04125       
04126 
04127       if( verbose ){
04128          if( rtin->reg_mode == REGMODE_3D_ESTIM )
04129             fprintf(stderr,"RT: setting up 3D registration 'estimate'\n") ;
04130          else
04131             fprintf(stderr,"RT: setting up 3D registration 'realtime'\n") ;
04132       }
04133 
04134       SHOW_AFNI_PAUSE ;
04135       RT_registration_3D_setup( rtin ) ;  
04136 
04137       if( rtin->reg_3dbasis == NULL ){
04138          fprintf(stderr,"RT: can't setup %s registration!\a\n",
04139                  REG_strings[rtin->reg_mode] ) ;
04140          if( rtin->reg_dset != NULL ){
04141             DSET_delete( rtin->reg_dset ) ; rtin->reg_dset = NULL ;
04142          }
04143          rtin->reg_mode = REGMODE_NONE ;
04144          SHOW_AFNI_READY ; return ;
04145       }
04146 
04147       
04148 
04149       if( rtin->reg_graph == 2 ){
04150          int    ycount = -6 ;  
04151          static char * nar[6] = {
04152             "\\Delta I-S [mm]" , "\\Delta R-L [mm]" , "\\Delta A-P [mm]" ,
04153             "Roll [\\degree]" , "Pitch [\\degree]" , "Yaw [\\degree]"  } ;
04154 
04155          char *ttl = malloc( strlen(DSET_FILECODE(rtin->dset[0])) + 32 ) ;
04156          strcpy(ttl,"\\noesc ") ;
04157          strcat(ttl,DSET_FILECODE(rtin->dset[0])) ;
04158          if( rtin->reg_mode == REGMODE_3D_ESTIM ) strcat(ttl," [Estimate]") ;
04159 
04160          
04161          if ( rtin->p_code )
04162             ycount = 1;
04163 
04164          rtin->mp = plot_ts_init( GLOBAL_library.dc->display ,
04165                                   0.0,rtin->reg_graph_xr-1 ,
04166                                   ycount,-rtin->reg_graph_yr,rtin->reg_graph_yr,
04167                                   "reps", NULL, ttl, nar , NULL ) ;
04168 
04169          if( rtin->mp != NULL ) rtin->mp->killfunc = MTD_killfunc ;
04170 
04171          free(ttl) ;
04172 
04173          
04174          RT_mp_comm_init_vars( rtin ) ;
04175          if ( rtin->mp_tcp_use ) RT_mp_comm_init( rtin ) ;
04176       }
04177    }
04178 
04179    
04180 
04181    ntt   = DSET_NUM_TIMES( rtin->dset[0] ) ;
04182    ttbot = rtin->reg_nvol ;
04183    for( tt=ttbot ; tt < ntt ; tt++ )
04184       RT_registration_3D_onevol( rtin , tt ) ;
04185 
04186    if( rtin->mp != NULL && ntt > ttbot ){
04187       float        * yar[7] ;
04188       int            ycount = -6 ;
04189 
04190       yar[0] = rtin->reg_rep   + ttbot ;
04191       yar[1] = rtin->reg_dx    + ttbot ;
04192       yar[2] = rtin->reg_dy    + ttbot ;
04193       yar[3] = rtin->reg_dz    + ttbot ;
04194       yar[4] = rtin->reg_phi   + ttbot ;
04195       yar[5] = rtin->reg_psi   + ttbot ;
04196       yar[6] = rtin->reg_theta + ttbot ;
04197 
04198       
04199       if ( rtin->mp_tcp_use )
04200           RT_mp_comm_send_data( rtin, yar+1, ntt-ttbot );
04201 
04202       if( ttbot > 0 )  
04203       {
04204           int c;
04205           for ( c = 0; c < 7; c++ )  
04206               yar[c]--;
04207           ttbot-- ;
04208       }
04209 
04210       
04211       if ( rtin->p_code )
04212       {
04213          ycount = 1;
04214          yar[1] = rtin->reg_eval + ttbot;
04215       }
04216 
04217       plot_ts_addto( rtin->mp , ntt-ttbot , yar[0] , ycount , yar+1 ) ;
04218    }
04219 
04220    
04221 
04222    XmUpdateDisplay( THE_TOPSHELL ) ;
04223    SHOW_AFNI_READY ; return ;
04224 }
04225 
04226 
04227 
04228 
04229 
04230 
04231 void RT_registration_3D_atend( RT_input * rtin )
04232 {
04233    int tt , ntt ;
04234 
04235    
04236 
04237    if( rtin->reg_base_index >= rtin->nvol[0] ){
04238       fprintf(stderr,"RT: can't do %s registration: not enough 3D volumes!\a\n",
04239               REG_strings[rtin->reg_mode] ) ;
04240       DSET_delete( rtin->reg_dset ) ; rtin->reg_dset = NULL ;
04241       rtin->reg_mode = REGMODE_NONE ;
04242       return ;
04243    }
04244 
04245    
04246 
04247    if( verbose )
04248       fprintf(stderr,"RT: starting 3D registration 'at end'\n") ;
04249 
04250    SHOW_AFNI_PAUSE ;
04251    RT_registration_3D_setup( rtin ) ;
04252 
04253    if( rtin->reg_3dbasis == NULL ){
04254       fprintf(stderr,"RT: can't setup %s registration!\a\n",
04255               REG_strings[rtin->reg_mode] ) ;
04256       DSET_delete( rtin->reg_dset ) ; rtin->reg_dset = NULL ;
04257       rtin->reg_mode = REGMODE_NONE ;
04258       SHOW_AFNI_READY ; return ;
04259    }
04260 
04261    
04262 
04263    ntt = DSET_NUM_TIMES( rtin->dset[0] ) ;
04264    if( verbose == 1 ) fprintf(stderr,"RT: ") ;
04265    for( tt=0 ; tt < ntt ; tt++ ){
04266       XmUpdateDisplay( THE_TOPSHELL ) ;
04267       RT_registration_3D_onevol( rtin , tt ) ;
04268       if( verbose == 1 ) fprintf(stderr,"%d",tt%10) ;
04269    }
04270    if( verbose == 1 ) fprintf(stderr,"\n") ;
04271 
04272    
04273 
04274    RT_registration_3D_close( rtin ) ;
04275    if( verbose ) SHOW_TIMES ;
04276    SHOW_AFNI_READY ; return ;
04277 }
04278 
04279 
04280 
04281 
04282 
04283 #define VL_MIT  9     
04284 #define VL_DXY  0.05  
04285 #define VL_DPH  0.07  
04286 #define VL_DEL  0.70  
04287 
04288 void RT_registration_3D_setup( RT_input * rtin )
04289 {
04290    int ibase = rtin->reg_base_index ;
04291    int kk , nx,ny,nz , kind , nbar ;
04292    MRI_IMAGE * im ;
04293    char * bar , * ept ;
04294 
04295    
04296 
04297    rtin->iha  = THD_handedness( rtin->dset[0] )   ;  
04298 
04299    rtin->ax1  = THD_axcode( rtin->dset[0] , 'I' ) ;
04300    rtin->hax1 = rtin->ax1 * rtin->iha      ;      
04301 
04302    rtin->ax2  = THD_axcode( rtin->dset[0] , 'R' ) ;
04303    rtin->hax2 = rtin->ax2 * rtin->iha      ;      
04304 
04305    rtin->ax3  = THD_axcode( rtin->dset[0] , 'A' ) ;
04306    rtin->hax3 = rtin->ax3 * rtin->iha      ;      
04307 
04308    im     = DSET_BRICK(rtin->dset[0],ibase) ;
04309    im->dx = fabs( DSET_DX(rtin->dset[0]) ) ;  
04310    im->dy = fabs( DSET_DY(rtin->dset[0]) ) ;
04311    im->dz = fabs( DSET_DZ(rtin->dset[0]) ) ;
04312 
04313    switch( rtin->reg_mode ){
04314       default: rtin->reg_3dbasis = NULL ;   
04315       return ;
04316 
04317       case REGMODE_3D_RTIME:                
04318       case REGMODE_3D_ATEND:
04319          ept = getenv("AFNI_REALTIME_volreg_maxite") ;
04320          kk  = VL_MIT ;
04321          if( ept != NULL ){
04322             kk = strtol(ept,NULL,10) ; if( kk <= 0 ) kk = VL_MIT ;
04323          }
04324          mri_3dalign_params( kk , VL_DXY , VL_DPH , VL_DEL ,
04325                              abs(rtin->ax1)-1 , abs(rtin->ax2)-1 , abs(rtin->ax3)-1 , -1 ) ;
04326 
04327                                                            
04328          mri_3dalign_method( rtin->reg_resam , verbose==2 ,   0     , 1        ) ;
04329 
04330          mri_3dalign_final_regmode( rtin->reg_final_resam ) ;
04331 
04332          rtin->reg_3dbasis = mri_3dalign_setup( im ,  NULL ) ;
04333       break ;
04334 
04335       case REGMODE_3D_ESTIM:               
04336          ept = getenv("AFNI_REALTIME_volreg_maxite_est") ;
04337          kk  = 1 ;
04338          if( ept != NULL ){
04339             kk = strtol(ept,NULL,10) ; if( kk <= 0 ) kk = 1 ;
04340          }
04341 
04342          mri_3dalign_params( kk , VL_DXY , VL_DPH , 2.0*VL_DEL ,
04343                              abs(rtin->ax1)-1 , abs(rtin->ax2)-1 , abs(rtin->ax3)-1 , -1 ) ;
04344 
04345          kk = MRI_CUBIC ;                     
04346          mri_3dalign_method( kk , verbose==2 ,   1     , 0        ) ;
04347 
04348          rtin->reg_3dbasis = mri_3dalign_setup( im ,  NULL ) ;
04349 #if 0
04350          kk = MRI_LINEAR ;
04351          mri_3dalign_method( kk , verbose==2 ,   1     , 0        ) ;
04352 #endif
04353       break ;
04354    }
04355 
04356    rtin->reg_nvol  = 0 ;
04357    return ;
04358 }
04359 
04360 
04361 
04362 
04363 
04364 void RT_registration_3D_close( RT_input * rtin )
04365 {
04366    mri_3dalign_cleanup( rtin->reg_3dbasis ) ;
04367    rtin->reg_3dbasis = NULL ;
04368    return ;
04369 }
04370 
04371 
04372 
04373 
04374 
04375 #ifndef D2RFAC
04376 #  define D2RFAC (PI/180.0)
04377 #  define R2DFAC (180.0/PI)
04378 #endif
04379 
04380 void RT_registration_3D_onevol( RT_input * rtin , int tt )
04381 {
04382    MRI_IMAGE * rim , * qim ;
04383    char * qar ;
04384    float dx,dy,dz , roll,pitch,yaw , ddx,ddy,ddz ;
04385    int   nest ;
04386 
04387    
04388 
04389    if( rtin->dset[0] == NULL ) return ;
04390 
04391    
04392 
04393    if( verbose == 2 )
04394       fprintf(stderr,"RT: 3D registering sub-brick %d\n",tt) ;
04395 
04396    qim     = DSET_BRICK(rtin->dset[0],tt) ;
04397    qim->dx = fabs( DSET_DX(rtin->dset[0]) ) ;  
04398    qim->dy = fabs( DSET_DY(rtin->dset[0]) ) ;
04399    qim->dz = fabs( DSET_DZ(rtin->dset[0]) ) ;
04400 
04401    rim = mri_3dalign_one( rtin->reg_3dbasis , qim ,
04402                           &roll , &pitch , &yaw , &dx , &dy , &dz ) ;
04403 
04404    
04405 
04406    roll  *= R2DFAC ; if( rtin->hax1 < 0 ) roll  = -roll  ;
04407    pitch *= R2DFAC ; if( rtin->hax2 < 0 ) pitch = -pitch ;
04408    yaw   *= R2DFAC ; if( rtin->hax3 < 0 ) yaw   = -yaw   ;
04409 
04410    switch( rtin->dset[0]->daxes->xxorient ){
04411       case ORI_R2L_TYPE: ddy =  dx; break ; case ORI_L2R_TYPE: ddy = -dx; break ;
04412       case ORI_P2A_TYPE: ddz = -dx; break ; case ORI_A2P_TYPE: ddz =  dx; break ;
04413       case ORI_I2S_TYPE: ddx =  dx; break ; case ORI_S2I_TYPE: ddx = -dx; break ;
04414    }
04415 
04416    switch( rtin->dset[0]->daxes->yyorient ){
04417       case ORI_R2L_TYPE: ddy =  dy; break ; case ORI_L2R_TYPE: ddy = -dy; break ;
04418       case ORI_P2A_TYPE: ddz = -dy; break ; case ORI_A2P_TYPE: ddz =  dy; break ;
04419       case ORI_I2S_TYPE: ddx =  dy; break ; case ORI_S2I_TYPE: ddx = -dy; break ;
04420    }
04421 
04422    switch( rtin->dset[0]->daxes->zzorient ){
04423       case ORI_R2L_TYPE: ddy =  dz; break ; case ORI_L2R_TYPE: ddy = -dz; break ;
04424       case ORI_P2A_TYPE: ddz = -dz; break ; case ORI_A2P_TYPE: ddz =  dz; break ;
04425       case ORI_I2S_TYPE: ddx =  dz; break ; case ORI_S2I_TYPE: ddx = -dz; break ;
04426    }
04427 
04428    nest = rtin->reg_nest ;
04429    rtin->reg_tim = (float *) realloc( (void *) rtin->reg_tim ,
04430                                       sizeof(float) * (nest+1) ) ;
04431    rtin->reg_dx  = (float *) realloc( (void *) rtin->reg_dx  ,
04432                                       sizeof(float) * (nest+1) ) ;
04433    rtin->reg_dy  = (float *) realloc( (void *) rtin->reg_dy  ,
04434                                       sizeof(float) * (nest+1) ) ;
04435    rtin->reg_dz  = (float *) realloc( (void *) rtin->reg_dz  ,
04436                                       sizeof(float) * (nest+1) ) ;
04437    rtin->reg_phi = (float *) realloc( (void *) rtin->reg_phi ,
04438                                       sizeof(float) * (nest+1) ) ;
04439    rtin->reg_psi = (float *) realloc( (void *) rtin->reg_psi ,
04440                                       sizeof(float) * (nest+1) ) ;
04441    rtin->reg_theta = (float *) realloc( (void *) rtin->reg_theta ,
04442                                       sizeof(float) * (nest+1) ) ;
04443    rtin->reg_rep   = (float *) realloc( (void *) rtin->reg_rep ,
04444                                       sizeof(float) * (nest+1) ) ;
04445    rtin->reg_eval   = (float *) realloc( (void *) rtin->reg_eval ,
04446                                       sizeof(float) * (nest+1) ) ;
04447 
04448    rtin->reg_tim[nest]   = THD_timeof_vox( tt , 0 , rtin->dset[0] ) ;
04449    rtin->reg_dx [nest]   = ddx   ;
04450    rtin->reg_dy [nest]   = ddy   ;
04451    rtin->reg_dz [nest]   = ddz   ;
04452    rtin->reg_phi[nest]   = roll  ;
04453    rtin->reg_psi[nest]   = pitch ;
04454    rtin->reg_theta[nest] = yaw   ;
04455    rtin->reg_rep[nest]   = tt    ;
04456 
04457    
04458    if ( rtin->p_code )
04459    {
04460        int c ;
04461 
04462        
04463        for ( c = 6; c < 26; c++ ) rtin->p_atoz[c] = 0;
04464 
04465        rtin->p_atoz[0] = ddx ; rtin->p_atoz[1] = ddy  ; rtin->p_atoz[2] = ddz;
04466        rtin->p_atoz[3] = roll; rtin->p_atoz[4] = pitch; rtin->p_atoz[5] = yaw;
04467 
04468        
04469        rtin->reg_eval[nest] = PARSER_evaluate_one(rtin->p_code, rtin->p_atoz);
04470    }
04471 
04472    rtin->reg_nest ++ ; rtin->reg_nvol = tt+1 ;
04473 
04474    
04475 
04476 
04477    if( rim != NULL && rtin->reg_dset != NULL ){
04478       switch( rtin->datum ){
04479          case MRI_float:                        
04480             qar = (char *) MRI_FLOAT_PTR(rim) ;
04481          break ;
04482 
04483          case MRI_short:
04484             qim = mri_to_short(1.0,rim) ; mri_free(rim) ; rim = qim ;
04485             qar = (char *) MRI_SHORT_PTR(rim) ;
04486          break ;
04487 
04488          case MRI_byte:
04489             qim = mri_to_byte(rim) ; mri_free(rim) ; rim = qim ;
04490             qar = (char *) MRI_BYTE_PTR(rim) ;
04491          break ;
04492 
04493          
04494 
04495          default:
04496             fprintf(stderr,"RT: can't do registration on %s images!\a\n",
04497                     MRI_TYPE_name[rtin->datum] ) ;
04498             DSET_delete( rtin->reg_dset ) ; rtin->reg_dset = NULL ;
04499             rtin->reg_mode = REGMODE_NONE ;
04500             mri_free(rim) ;
04501          return ;
04502       }
04503 
04504       
04505 
04506       if( tt == 0 )
04507          EDIT_substitute_brick( rtin->reg_dset , 0 , rtin->datum , qar ) ;
04508       else
04509          EDIT_add_brick( rtin->reg_dset , rtin->datum , 0.0 , qar ) ;
04510 
04511       EDIT_dset_items( rtin->reg_dset , ADN_ntt , rtin->reg_nvol ,  ADN_none ) ;
04512 
04513       mri_fix_data_pointer(NULL,rim) ; mri_free(rim) ;   
04514    }
04515 
04516    return ;
04517 }
04518 
04519 #endif 
04520 
04521 #ifndef FIM_THR
04522 #define FIM_THR  0.0999
04523 #endif
04524 
04525 #define MIN_UPDT 5
04526 
04527 
04528 
04529 
04530 
04531 
04532 
04533 
04534 
04535 
04536 
04537 
04538 
04539 
04540 
04541 
04542 #define IFree(x) do{ if( (x)!=NULL ){ free(x) ; (x)=NULL ; } } while(0)
04543 
04544 int RT_fim_recurse( RT_input *rtin , int mode )
04545 {
04546    static Three_D_View * im3d ;
04547    static THD_3dim_dataset * dset_time ;
04548    static MRI_IMAGE * ref_ts ;
04549    static MRI_IMAGE * ort_ts ;
04550 
04551    static THD_3dim_dataset * new_dset ;
04552    static int nvox , ngood_ref , it1 , dtyp , nxyz , nupdt ;
04553    static float * vval=NULL , * aval=NULL , * rbest=NULL , * abest=NULL ;
04554    static int   * indx=NULL ;
04555    static PCOR_references ** pc_ref=NULL ;
04556    static PCOR_voxel_corr ** pc_vc=NULL ;
04557    static int nx_ref , ny_ref ;
04558 
04559    static int fim_nref , nx_ort , ny_ort , internal_ort ;
04560    static float * ortar ;
04561    static float * ref_vec = NULL ;
04562    static int    nref_vec = -666 ;
04563 
04564    static int polort = 1 ;  
04565 
04566    static char new_prefix[THD_MAX_PREFIX] ;
04567    static char old_prefix[THD_MAX_PREFIX] ;
04568 
04569    static int first_pass = 1;     
04570    int        start_index;        
04571 
04572    int ifim, it, iv, ivec, nnow, itbot , ip ;
04573    float fthr , topval , stataux[MAX_STAT_AUX] ;
04574    float * tsar ;
04575    short * bar ;
04576    void  * ptr ;
04577 
04578    char strbuf[128] ;  
04579 
04580    
04581 
04582 
04583    if( rtin == NULL ) return -1 ;
04584 
04585    
04586    
04587 
04588    if( mode == INIT_MODE ){
04589 
04590       dset_time = rtin->dset[0] ;       
04591 
04592 #ifdef ALLOW_REGISTRATION
04593       
04594       if( (rtin->reg_mode == REGMODE_2D_RTIME) || (rtin->reg_mode == REGMODE_3D_RTIME) )
04595          dset_time = rtin->reg_dset;
04596 #endif 
04597 
04598       if( dset_time == NULL ) return -1 ;
04599 
04600       im3d      = rtin->im3d[0] ;         if( im3d      == NULL ) return -1 ;
04601       ref_ts    = im3d->fimdata->fimref ; if( ref_ts    == NULL ) return -1 ;
04602       ort_ts    = im3d->fimdata->fimort ; 
04603       nupdt     = 0 ;                     
04604 
04605       polort    = im3d->fimdata->polort ; 
04606 
04607       if( ort_ts != NULL ){               
04608          nx_ort = ort_ts->nx ;
04609          ny_ort = ort_ts->ny ;
04610          ortar  = MRI_FLOAT_PTR(ort_ts) ;
04611          internal_ort = 0 ;
04612       } else {
04613          nx_ort = ny_ort = 0 ;
04614          ortar  = NULL ;
04615          internal_ort = 1 ;
04616       }
04617       fim_nref = (internal_ort) ? (polort+2) : (ny_ort+polort+2) ;
04618 
04619       if( nref_vec < fim_nref ){  
04620           ref_vec = (float *) XtRealloc( (char *)ref_vec, sizeof(float)*fim_nref ) ;
04621          nref_vec = fim_nref ;
04622       }
04623 
04624       itbot     = im3d->fimdata->init_ignore ;  
04625       nx_ref    = ref_ts->nx ;                  
04626       ny_ref    = ref_ts->ny ;
04627       ngood_ref =  0 ;
04628       it1       = -1 ;
04629       for( ivec=0 ; ivec < ny_ref ; ivec++ ){           
04630          tsar = MRI_FLOAT_PTR(ref_ts) + (ivec*nx_ref) ; 
04631          ifim = 0 ;                                     
04632          for( it=itbot ; it < nx_ref ; it++ ){
04633             if( tsar[it] < WAY_BIG ){ ifim++ ; if( it1 < 0 ) it1 = it ; }
04634          }
04635 
04636          if( ifim < MIN_UPDT ){
04637             fprintf(stderr,"RTfim: ideal timeseries has too few good entries!\a\n") ;
04638             return -1 ;
04639          }
04640 
04641          ngood_ref = MAX( ifim , ngood_ref ) ;
04642       }
04643 
04644 
04645 
04646 
04647       dtyp = DSET_BRICK_TYPE(dset_time,0) ;  
04648       if( ! AFNI_GOOD_FUNC_DTYPE(dtyp) ){
04649          fprintf(stderr,"RTfim: input dataset has unsupported datum %s!\a\n",
04650                  MRI_TYPE_name[dtyp] ) ;
04651          return -1 ;
04652       }
04653 
04654       if( nx_ort > 0 && nx_ort < nx_ref ){  
04655          fprintf(stderr,
04656                  "RTfim: WARNING -- ort length=%d  ideal length=%d\n",
04657                  nx_ort , nx_ref ) ;
04658       }
04659 
04660       
04661 
04662       MCW_strncpy( old_prefix , DSET_PREFIX(dset_time) , THD_MAX_PREFIX-3 ) ;
04663 
04664       for( ifim=1 ; ifim < 99 ; ifim++ ){
04665          sprintf( new_prefix , "%s@%d" , old_prefix , ifim ) ;
04666          if( PLUTO_prefix_ok(new_prefix) ) break ;
04667       }
04668       if( ifim == 99 ){
04669          fprintf(stderr,"RTfim: can't create new prefix!\a\n") ;
04670          return -1 ;
04671       }
04672 
04673       nxyz =  dset_time->dblk->diskptr->dimsizes[0]    
04674             * dset_time->dblk->diskptr->dimsizes[1]
04675             * dset_time->dblk->diskptr->dimsizes[2] ;
04676 
04677       return 1 ;
04678    }
04679 
04680    
04681    
04682 
04683    if( mode == FINAL_MODE ){
04684 
04685       
04686 
04687       if( pc_ref != NULL ){
04688          for( ivec=0 ; ivec < ny_ref ; ivec++ ){
04689             free_PCOR_references(pc_ref[ivec]) ;
04690             free_PCOR_voxel_corr(pc_vc[ivec]) ;
04691          }
04692       }
04693       IFree(vval) ; IFree(indx)  ; IFree(pc_ref) ; IFree(pc_vc)  ;
04694       IFree(aval) ; IFree(rbest) ; IFree(abest)  ;
04695 
04696       first_pass = 1;                
04697 
04698       return 1 ;
04699    }
04700 
04701    
04702    
04703 
04704    if( mode == UPDATE_MODE ){
04705 
04706       if( nupdt < MIN_UPDT ) return 1 ;  
04707 
04708       rtin->func_condit = 2 ;  
04709 
04710       
04711 
04712       stataux[0] = nupdt ;               
04713       stataux[1] = (ny_ref==1) ? 1 : 2 ; 
04714       stataux[2] = fim_nref - 1 ;        
04715       for( iv=3 ; iv < MAX_STAT_AUX ; iv++ ) stataux[iv] = 0.0 ;
04716 
04717       (void) EDIT_dset_items( new_dset, ADN_stat_aux, stataux, ADN_none ) ;
04718 
04719       
04720 
04721       if( ny_ref == 1 ){
04722 
04723       
04724 
04725          
04726 
04727 
04728          PCOR_get_coef( pc_ref[0] , pc_vc[0] , vval ) ;
04729 
04730          topval = 0.0 ;
04731          for( iv=0 ; iv < nvox ; iv++ )
04732             if( fabs(vval[iv]) > topval ) topval = fabs(vval[iv]) ;
04733 
04734          bar = DSET_ARRAY( new_dset , FUNC_ival_fim[FUNC_COR_TYPE] ) ;
04735 
04736 #ifdef DONT_USE_MEMCPY
04737          for( iv=0 ; iv < nxyz ; iv++ ) bar[iv] = 0 ;
04738 #else
04739          memset( bar , 0 , sizeof(short)*nxyz ) ;
04740 #endif
04741 
04742          if( topval > 0.0 ){
04743             topval = MRI_TYPE_maxval[MRI_short] / topval ;
04744             for( iv=0 ; iv < nvox ; iv++ )
04745                bar[indx[iv]] = (short)(topval * vval[iv] + 0.499) ;
04746 
04747             stataux[0] = 1.0/topval ;
04748          } else {
04749             stataux[0] = 0.0 ;
04750          }
04751 
04752          
04753 
04754 
04755          PCOR_get_pcor( pc_ref[0] , pc_vc[0] , vval ) ;
04756 
04757          bar = DSET_ARRAY( new_dset , FUNC_ival_thr[FUNC_COR_TYPE] ) ;
04758 
04759 #ifdef DONT_USE_MEMCPY
04760          for( iv=0 ; iv < nxyz ; iv++ ) bar[iv] = 0 ;
04761 #else
04762          memset( bar , 0 , sizeof(short)*nxyz ) ;
04763 #endif
04764 
04765          for( iv=0 ; iv < nvox ; iv++ )
04766             bar[indx[iv]] = (short)(FUNC_COR_SCALE_SHORT * vval[iv] + 0.499) ;
04767 
04768          stataux[1] = 1.0 / FUNC_COR_SCALE_SHORT ;
04769 
04770       } else {
04771 
04772       
04773 
04774          
04775 
04776          PCOR_get_coef( pc_ref[0] , pc_vc[0] , abest ) ;
04777          PCOR_get_pcor( pc_ref[0] , pc_vc[0] , rbest ) ;
04778 
04779          
04780 
04781 
04782 
04783          for( ivec=1 ; ivec < ny_ref ; ivec++ ){
04784 
04785             PCOR_get_coef( pc_ref[ivec] , pc_vc[ivec] , aval ) ;
04786             PCOR_get_pcor( pc_ref[ivec] , pc_vc[ivec] , vval ) ;
04787 
04788             for( iv=0 ; iv < nvox ; iv++ ){
04789                if( fabs(vval[iv]) > fabs(rbest[iv]) ){
04790                   rbest[iv] = vval[iv] ;
04791                   abest[iv] = aval[iv] ;
04792                }
04793             }
04794          }
04795 
04796          
04797 
04798 
04799          topval = 0.0 ;
04800          for( iv=0 ; iv < nvox ; iv++ )
04801             if( fabs(abest[iv]) > topval ) topval = fabs(abest[iv]) ;
04802 
04803          bar = DSET_ARRAY( new_dset , FUNC_ival_fim[FUNC_COR_TYPE] ) ;
04804 
04805 #ifdef DONT_USE_MEMCPY
04806          for( iv=0 ; iv < nxyz ; iv++ ) bar[iv] = 0 ;
04807 #else
04808          memset( bar , 0 , sizeof(short)*nxyz ) ;
04809 #endif
04810 
04811          if( topval > 0.0 ){
04812             topval = MRI_TYPE_maxval[MRI_short] / topval ;
04813             for( iv=0 ; iv < nvox ; iv++ )
04814                bar[indx[iv]] = (short)(topval * abest[iv] + 0.499) ;
04815 
04816             stataux[0] = 1.0/topval ;
04817          } else {
04818             stataux[0] = 0.0 ;
04819          }
04820 
04821          bar = DSET_ARRAY( new_dset , FUNC_ival_thr[FUNC_COR_TYPE] ) ;
04822 
04823 #ifdef DONT_USE_MEMCPY
04824          for( iv=0 ; iv < nxyz ; iv++ ) bar[iv] = 0 ;
04825 #else
04826          memset( bar , 0 , sizeof(short)*nxyz ) ;
04827 #endif
04828 
04829          for( iv=0 ; iv < nvox ; iv++ )
04830             bar[indx[iv]] = (short)(FUNC_COR_SCALE_SHORT * rbest[iv] + 0.499) ;
04831 
04832          stataux[1] = 1.0 / FUNC_COR_SCALE_SHORT ;
04833       }
04834 
04835       
04836 
04837       (void) EDIT_dset_items( new_dset, ADN_brick_fac, stataux, ADN_none ) ;
04838       return 1 ;
04839    }
04840 
04841    
04842    
04843 
04844    if( mode < it1 ) return 1 ;  
04845 
04846    
04847 
04848 
04849 
04850 
04851    
04852    if ( (DSET_NVALS(dset_time) <= mode) || (DSET_ARRAY(dset_time,mode) == NULL) )
04853       return 1;
04854 
04855 #if 0                           
04856    if( mode == it1 )
04857 #endif
04858 
04859    
04860    if( first_pass == 1 ){
04861 
04862       switch( dtyp ){  
04863 
04864          case MRI_short:{
04865             short * dar = (short *) DSET_ARRAY(dset_time,it1) ;
04866             for( iv=0,fthr=0.0 ; iv < nxyz ; iv++ ) fthr += abs(dar[iv]) ;
04867             fthr = FIM_THR * fthr / nxyz ;
04868             for( iv=0,nvox=0 ; iv < nxyz ; iv++ )
04869                if( abs(dar[iv]) > fthr ) nvox++ ;
04870             indx = (int *) malloc( sizeof(int) * nvox ) ;
04871             if( indx == NULL ){
04872                fprintf(stderr,"RTfim: indx malloc failure!\a\n") ;
04873                EXIT(1) ;
04874             }
04875             for( iv=0,nvox=0 ; iv < nxyz ; iv++ )
04876                if( abs(dar[iv]) > fthr ) indx[nvox++] = iv ;
04877          }
04878          break ;
04879 
04880          case MRI_float:{
04881             float * dar = (float *) DSET_ARRAY(dset_time,it1) ;
04882             for( iv=0,fthr=0.0 ; iv < nxyz ; iv++ ) fthr += fabs(dar[iv]) ;
04883             fthr = FIM_THR * fthr / nxyz ;
04884             for( iv=0,nvox=0 ; iv < nxyz ; iv++ )
04885                if( fabs(dar[iv]) > fthr ) nvox++ ;
04886             indx = (int *) malloc( sizeof(int) * nvox ) ;
04887             if( indx == NULL ){
04888               fprintf(stderr,"RTfim: indx malloc failure!\a\n") ;
04889               EXIT(1) ;
04890             }
04891             for( iv=0,nvox=0 ; iv < nxyz ; iv++ )
04892                if( fabs(dar[iv]) > fthr ) indx[nvox++] = iv ;
04893          }
04894          break ;
04895 
04896          case MRI_byte:{
04897             byte * dar = (byte *) DSET_ARRAY(dset_time,it1) ;
04898             for( iv=0,fthr=0.0 ; iv < nxyz ; iv++ ) fthr += dar[iv] ;
04899             fthr = FIM_THR * fthr / nxyz ;
04900             for( iv=0,nvox=0 ; iv < nxyz ; iv++ )
04901                if( dar[iv] > fthr ) nvox++ ;
04902             indx = (int *) malloc( sizeof(int) * nvox ) ;
04903             if( indx == NULL ){
04904               fprintf(stderr,"RTfim: indx malloc failure!\a\n") ;
04905               EXIT(1) ;
04906             }
04907             for( iv=0,nvox=0 ; iv < nxyz ; iv++ )
04908                if( dar[iv] > fthr ) indx[nvox++] = iv ;
04909          }
04910          break ;
04911       }
04912 
04913 
04914 
04915 
04916       if( verbose == 2 )
04917          fprintf(stderr,"RTfim: %d/%d voxels being FIMmed.\n",nvox,nxyz) ;
04918       VMCHECK ;
04919 
04920       vval = (float *) malloc( sizeof(float) * nvox) ;
04921       if( vval == NULL ){
04922         fprintf(stderr,"RTfim: vval malloc failure!\a\n") ;
04923         EXIT(1) ;
04924       }
04925 
04926 
04927 
04928       if( ny_ref > 1 ){
04929          aval  = (float *) malloc( sizeof(float) * nvox) ;
04930          rbest = (float *) malloc( sizeof(float) * nvox) ;
04931          abest = (float *) malloc( sizeof(float) * nvox) ;
04932          if( aval==NULL || rbest==NULL || abest==NULL ){
04933            fprintf(stderr,"RTfim: abest malloc failure!\a\n") ;
04934            EXIT(1) ;
04935          }
04936       } else {
04937          aval = rbest = abest = NULL ;
04938       }
04939 
04940       
04941 
04942       pc_ref = (PCOR_references **) malloc( sizeof(PCOR_references *) * ny_ref ) ;
04943       pc_vc  = (PCOR_voxel_corr **) malloc( sizeof(PCOR_voxel_corr *) * ny_ref ) ;
04944 
04945       if( pc_ref == NULL || pc_vc == NULL ){
04946         fprintf(stderr,"RTfim: can't malloc recursion space!\a\n") ;
04947         EXIT(1) ;
04948       }
04949 
04950       for( ivec=0 ; ivec < ny_ref ; ivec++ ){
04951          pc_ref[ivec] = new_PCOR_references( fim_nref ) ;
04952          pc_vc[ivec]  = new_PCOR_voxel_corr( nvox , fim_nref ) ;
04953          if( pc_ref[ivec] == NULL || pc_vc[ivec] == NULL ){
04954            fprintf(stderr,"RTfim: can't malloc refs and corr!\a\n") ;
04955            EXIT(1) ;
04956          }
04957       }
04958 
04959       
04960 
04961       rtin->func_dset = new_dset = EDIT_empty_copy( dset_time ) ;
04962       if( new_dset == NULL ){
04963         fprintf(stderr,"RTfim: can't create empty dataset!\a\n") ;
04964         EXIT(1) ;
04965       }
04966       tross_Append_History( new_dset , "plug_realtime: FIM" ) ;
04967 
04968       it = EDIT_dset_items( new_dset ,
04969                                ADN_prefix      , new_prefix ,
04970                                ADN_malloc_type , DATABLOCK_MEM_MALLOC ,
04971                                ADN_type        , ISHEAD(dset_time)
04972                                                  ? HEAD_FUNC_TYPE : GEN_FUNC_TYPE ,
04973                                ADN_func_type   , FUNC_COR_TYPE ,
04974                                ADN_nvals       , FUNC_nvals[FUNC_COR_TYPE] ,
04975                                ADN_datum_all   , MRI_short ,
04976                                ADN_ntt         , 0 ,
04977                             ADN_none ) ;
04978 
04979       if( it > 0 )
04980          fprintf(stderr,"RTfim: WARNING -- %d errors in dataset creation!\a\n",it) ;
04981 
04982 
04983 
04984       for( iv=0 ; iv < new_dset->dblk->nvals ; iv++ ){
04985          ptr = malloc( DSET_BRICK_BYTES(new_dset,iv) ) ;
04986          if( ptr == NULL ){
04987            fprintf(stderr,"RTfim: can't malloc dataset bricks!\a\n") ;
04988            EXIT(1) ;
04989          }
04990          mri_fix_data_pointer( ptr ,  DSET_BRICK(new_dset,iv) ) ;
04991 
04992          sprintf(strbuf,"#%d",iv) ;              
04993          EDIT_BRICK_LABEL(new_dset,iv,strbuf) ;  
04994       }
04995 
04996       DSET_lock( rtin->func_dset ) ; 
04997 
04998    }  
04999 
05000    
05001 
05002    
05003    
05004    if ( first_pass == 1 )
05005    {
05006       first_pass  = 0;
05007       start_index = it1;      
05008    }
05009    else
05010       start_index = mode;     
05011 
05012    for ( it = start_index; it <= mode; it++ )
05013    {
05014       nnow = 0 ;     
05015 
05016       if( it >= nx_ref ) return 1 ;  
05017 
05018       for( ivec=0 ; ivec < ny_ref ; ivec++ ){           
05019          tsar = MRI_FLOAT_PTR(ref_ts) + (ivec*nx_ref) ;
05020          if( tsar[it] >= WAY_BIG ) continue ;           
05021 
05022          ref_vec[0] = 1.0 ;         
05023          for( ip=1 ; ip <= polort ; ip++ )              
05024             ref_vec[ip] = ref_vec[ip-1] * ((float)it) ; 
05025 
05026          if( internal_ort ){
05027             ref_vec[ip] = tsar[it] ;                    
05028          } else {
05029             for( iv=0 ; iv < ny_ort ; iv++ )            
05030                ref_vec[iv+ip] = (it < nx_ort) ? ortar[it+iv*nx_ort]
05031                                               : 0.0 ;
05032 
05033             ref_vec[ny_ort+ip] = tsar[it] ;             
05034          }
05035 
05036          update_PCOR_references( ref_vec , pc_ref[ivec] ) ;  
05037 
05038          
05039 
05040          switch( dtyp ){
05041             case MRI_short:{
05042                short * dar = (short *) DSET_ARRAY(dset_time,it) ;
05043                for( iv=0 ; iv < nvox ; iv++ ) vval[iv] = (float) dar[indx[iv]] ;
05044             }
05045             break ;
05046 
05047             case MRI_float:{
05048                float * dar = (float *) DSET_ARRAY(dset_time,it) ;
05049                for( iv=0 ; iv < nvox ; iv++ ) vval[iv] = (float) dar[indx[iv]] ;
05050             }
05051             break ;
05052 
05053             case MRI_byte:{
05054                byte * dar = (byte *) DSET_ARRAY(dset_time,it) ;
05055                for( iv=0 ; iv < nvox ; iv++ ) vval[iv] = (float) dar[indx[iv]] ;
05056             }
05057             break ;
05058          }
05059 
05060          PCOR_update_float( vval , pc_ref[ivec] , pc_vc[ivec] ) ;  
05061          nnow++ ;
05062 
05063       }
05064       if( nnow > 0 ) nupdt++ ;  
05065    }
05066 
05067    return 1 ;
05068 }