00001 #include "afni.h"
00002 #include "vol2surf.h"
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 #define NUM_NIML   2                        
00042 
00043 
00044 
00045 
00046 static NI_stream_type *ns_listen[NUM_NIML] ;
00047 
00048 
00049 
00050 
00051 static char ns_name[NUM_NIML][64] ;
00052 
00053 
00054 
00055 
00056 static int ns_flags[NUM_NIML] ;
00057 
00058 
00059 
00060 #define FLAG_WAITING    1
00061 
00062 
00063 
00064 #define FLAG_CONNECTED  2
00065 
00066 
00067 
00068 #define FLAG_SKIP       4
00069 
00070 
00071 
00072 
00073 #define NS_SUMA 0
00074 
00075 
00076 
00077 
00078 static int dont_tell_suma = 1 ;
00079 
00080 
00081 
00082 static int dont_overlay_suma = 1 ;
00083 
00084 
00085 
00086 
00087 static int dont_hear_suma = 0 ;
00088 
00089 
00090 
00091 
00092 static int g_show_as_popup = 0 ;     
00093 
00094 #undef  SHOW_MESSAGE
00095 
00096 
00097 
00098 #define SHOW_MESSAGE(mmm)                                      \
00099  do{      if( g_show_as_popup == 1 ) AFNI_popup_message(mmm);  \
00100      else if( g_show_as_popup == 0 ) fputs(mmm,stderr) ;      } while(0)
00101 
00102 
00103 
00104 #ifndef SUMA_TCP_PORT
00105 #define SUMA_TCP_PORT 53211
00106 #endif
00107 
00108 
00109 
00110 
00111 #ifndef NIML_TCP_FIRST_PORT
00112 #define NIML_TCP_FIRST_PORT 53212
00113 #endif
00114 
00115 
00116 
00117 #define EPS 0.01  
00118 
00119 
00120 
00121 typedef struct {
00122    char * idcode_ldp;
00123    char * label_ldp;
00124    char   full_label_ldp[64];
00125    int    nsurf;
00126    int    sA, sB;
00127    int    use_v2s;
00128 } ldp_surf_list;
00129 
00130 typedef struct {
00131    ldp_surf_list * list;
00132    int             nused, nalloc;
00133 } LDP_list;
00134 
00135 
00136 
00137 
00138 static int sendit=1 ;
00139 static int serrit=0 ;  
00140 
00141 
00142 
00143 
00144 static int started = 0 ;
00145 
00146 static int redisplay_key[MAX_CONTROLLERS] ;
00147 static int viewpoint_key[MAX_CONTROLLERS] ;
00148 
00149 
00150 
00151 
00152 static void    AFNI_niml_atexit( void ) ;
00153 static Boolean AFNI_niml_workproc( XtPointer ) ;
00154 static void    AFNI_process_NIML_data( int , void * , int ) ;
00155 static void    AFNI_niml_redisplay_CB( int,int,void *,void * ) ;
00156 static void    AFNI_niml_viewpoint_CB( int,int,void *,void * ) ;
00157 static void    AFNI_niml_driver( char * , NI_stream_type *, NI_element * ) ;
00158 
00159 
00160 
00161 
00162 
00163 
00164 
00165 static int     process_NIML_SUMA_ixyz( NI_element * nel, int ct_start ) ;
00166 static int     process_NIML_SUMA_ijk( NI_element * nel, int ct_start ) ;
00167 static int     process_NIML_SUMA_node_normals( NI_element * nel, int ct_start );
00168 static int     process_NIML_SUMA_crosshair_xyz(NI_element * nel) ;
00169 static int     process_NIML_Node_ROI( NI_element * nel, int ct_start ) ;
00170 
00171 static int     disp_ldp_surf_list(LDP_list * ldp_list, THD_session * sess);
00172 static int     fill_ldp_surf_list(LDP_list * ldp_list, THD_session * sess,
00173                                   v2s_plugin_opts * po);
00174 static int     int_list_posn(int * vals, int nvals, int test_val);
00175 static int     slist_choose_surfs(LDP_list * ldp_list, THD_session * sess,
00176                                   v2s_plugin_opts * po);
00177 static int     slist_check_user_surfs(ldp_surf_list * lsurf, int * surfs,
00178                                       v2s_plugin_opts * po);
00179 static int     slist_surfs_for_ldp(ldp_surf_list * lsurf, int * surfs, int max,
00180                                    THD_session * sess, int debug);
00181 
00182 
00183 
00184 
00185 
00186 
00187 static void    process_NIML_AFNI_dataset   ( NI_group *   , int ) ;
00188 static void    process_NIML_AFNI_volumedata( void *       , int ) ;
00189 static void    process_NIML_MRI_IMAGE      ( NI_element * , int ) ;
00190 
00191 
00192 
00193 
00194 
00195 
00196 
00197 static void AFNI_niml_atexit( void )
00198 {
00199 #if 0              
00200    int cc ;
00201 STATUS("called AFNI_niml_atexit") ;
00202    for( cc=0 ; cc < NUM_NIML ; cc++ )        
00203      NI_stream_closenow( ns_listen[cc] ) ;
00204 #endif
00205    return ;
00206 }
00207 
00208 
00209 
00210 
00211 
00212 void AFNI_init_niml( void )
00213 {
00214    int cc , ii ;
00215 
00216 ENTRY("AFNI_init_niml") ;
00217 
00218    if( started ) EXRETURN ;
00219 
00220    PLUTO_register_workproc( AFNI_niml_workproc , NULL ) ;
00221 #if 0
00222    atexit( AFNI_niml_atexit ) ;
00223 #endif
00224 
00225    
00226 
00227    for( cc=0 ; cc < NUM_NIML ; cc++ ){
00228      ns_listen[cc] = NULL ;
00229      ns_flags[cc]  = 0 ;
00230    }
00231 
00232    
00233 
00234    cc = GLOBAL_argopt.port_niml ;
00235    if( cc < 1024 || cc > 65535 ) cc = SUMA_TCP_PORT ;
00236    sprintf( ns_name[0] , "tcp:host:%d" , cc ) ;
00237 
00238    
00239 
00240    cc = AFNI_numenv( "AFNI_NIML_FIRST_PORT" ) ;
00241    if( cc < 1024 || cc > 65535 ) cc = NIML_TCP_FIRST_PORT ;
00242    for( ii=1 ; ii < NUM_NIML ; ii++ )
00243      sprintf( ns_name[ii] , "tcp:host:%d" , (cc+ii-1) ) ;
00244 
00245    
00246 
00247    for( cc=0 ; cc < MAX_CONTROLLERS ; cc++ ){
00248      redisplay_key[cc] = -1 ;
00249      viewpoint_key[cc] = -1 ;
00250    }
00251 
00252    
00253 
00254 
00255    redisplay_key[0] = AFNI_receive_init( GLOBAL_library.controllers[0] ,
00256                                          RECEIVE_FUNCDISPLAY_MASK ,
00257                                          AFNI_niml_redisplay_CB ,
00258                                          GLOBAL_library.controllers[0] ,
00259                                          "AFNI_niml_redisplay_CB" ) ;
00260 
00261    
00262 
00263 
00264    viewpoint_key[0] = AFNI_receive_init( GLOBAL_library.controllers[0] ,
00265                                          RECEIVE_VIEWPOINT_MASK ,
00266                                          AFNI_niml_viewpoint_CB ,
00267                                          GLOBAL_library.controllers[0] ,
00268                                          "AFNI_niml_viewpoint_CB" ) ;
00269 
00270    
00271 
00272    sendit = !AFNI_yesenv("AFNI_NIML_DONTSEND") ;
00273    serrit = !sendit || AFNI_yesenv("AFNI_NIML_STDERR") ;   
00274 
00275    
00276 
00277    NI_register_doer( "DRIVE_AFNI" , AFNI_niml_driver ) ;
00278 
00279    
00280 
00281         if( AFNI_yesenv("AFNI_SHOW_SURF_POPUPS") ) g_show_as_popup =  1 ;
00282    else if( AFNI_yesenv("AFNI_KILL_SURF_POPUPS") ) g_show_as_popup = -1 ;
00283 
00284    
00285 
00286    started = 1 ; EXRETURN ;
00287 }
00288 
00289 
00290 
00291 
00292 void AFNI_niml_driver( char *object , NI_stream_type *ns , NI_element *nel )
00293 {
00294    (void) AFNI_driver( object ) ;
00295    return ;
00296 }
00297 
00298 
00299 
00300 
00301 
00302 void NIML_to_stderr( void *nini , int send )
00303 {
00304    NI_stream ns_err ;
00305    if( NI_element_type(nini) != NI_ELEMENT_TYPE ) return ;
00306    ns_err = NI_stream_open( "stderr:" , "w" ) ;
00307    if( ns_err != NULL ){
00308      if( send )
00309        fprintf(stderr,"-------------- AFNI sends NIML element: --------------\n");
00310      else
00311        fprintf(stderr,"-------------- AFNI gets NIML element:  --------------\n");
00312      NI_write_element( ns_err , nini , NI_TEXT_MODE | NI_HEADERONLY_FLAG ) ;
00313      NI_stream_closenow( ns_err ) ;
00314    }
00315 }
00316 
00317 
00318 
00319 
00320 
00321 
00322 
00323 
00324 
00325 
00326 static Boolean AFNI_niml_workproc( XtPointer elvis )
00327 {
00328    int cc , nn , ct , ngood=0 ;
00329    void *nini ;
00330    char str[512] ;
00331    int keep_reading , read_msec ; 
00332 
00333 ENTRY("AFNI_niml_workproc") ;
00334 
00335 
00336 
00337    for( cc=0 ; cc < NUM_NIML ; cc++ ){
00338 
00339      keep_reading = 0 ;  
00340 
00341      
00342 
00343      if( ns_listen[cc] == NULL && (ns_flags[cc]&FLAG_SKIP)==0 ){
00344        if(PRINT_TRACING){
00345          sprintf(str,"call NI_stream_open('%s')",ns_name[cc]) ;
00346          STATUS(str) ;
00347        }
00348 
00349        ns_listen[cc] = NI_stream_open( ns_name[cc] , "r" ) ;
00350 
00351        if( ns_listen[cc] == NULL ){
00352          STATUS("NI_stream_open failed") ;
00353          ns_flags[cc] = FLAG_SKIP ; continue ;  
00354        }
00355        ns_flags[cc]  = FLAG_WAITING ;
00356      }
00357      if( ns_listen[cc] == NULL ) continue ; 
00358 
00359      ngood++ ;
00360 
00361      
00362 
00363      if(PRINT_TRACING){
00364        sprintf(str,"call NI_stream_goodcheck('%s')",ns_listen[cc]->orig_name);
00365        STATUS(str) ;
00366      }
00367 
00368      
00369 
00370   Keep_Reading:
00371      read_msec = (keep_reading) ? 222 : 1 ;  
00372 
00373      nn = NI_stream_goodcheck( ns_listen[cc] , 1 ) ;
00374 
00375      if( nn < 0 ){                          
00376        STATUS("NI_stream_goodcheck was unhappy") ;
00377        fprintf(stderr,"++ NIML connection closed from %s\n",
00378                 NI_stream_name(ns_listen[cc])               ) ;
00379 
00380        NI_stream_closenow( ns_listen[cc] ) ;
00381        ns_listen[cc] = NULL ;  
00382        ns_flags[cc]  = 0 ;
00383        keep_reading  = 0 ;
00384        continue ;              
00385      }
00386 
00387      if( nn == 0 ){
00388        STATUS("NI_stream_goodcheck was neutral") ;
00389        keep_reading = 0 ;
00390        continue ;  
00391      }
00392 
00393      
00394 
00395      STATUS("NI_stream_goodcheck was good!") ;
00396 
00397      
00398 
00399      if( ns_flags[cc] & FLAG_WAITING ){
00400        ns_flags[cc] = FLAG_CONNECTED ;
00401        NI_stream_setbufsize( ns_listen[cc] , 3*NI_BUFSIZE ) ; 
00402        fprintf(stderr,"++ NIML connection opened from %s\n",
00403                NI_stream_name(ns_listen[cc])                ) ;
00404      }
00405 
00406      
00407 
00408      nn = NI_stream_hasinput( ns_listen[cc] , read_msec ) ;
00409 
00410      if( nn > 0 ){                                           
00411        STATUS("Reading data!") ;
00412        ct   = NI_clock_time() ;                           
00413        nini = NI_read_element( ns_listen[cc] , read_msec ) ;  
00414 
00415        if( nini != NULL ){                                  
00416          if( serrit ) NIML_to_stderr(nini,0) ;
00417 
00418          
00419 
00420          if( NI_element_type(nini) == NI_PROCINS_TYPE ){  
00421            NI_procins *npi = (NI_procins *)nini ;
00422 
00423            
00424 
00425 
00426 
00427 
00428            if(PRINT_TRACING){
00429              char sss[256]; sprintf("Processing instruction: '%s'",npi->name);
00430              STATUS(sss) ;
00431            }
00432            if( strcasecmp(npi->name,"keep_reading") == 0 )
00433              keep_reading = 1 ;
00434            else if( strcasecmp(npi->name,"pause_reading") == 0 )
00435              keep_reading = 0 ;
00436            else if( strcasecmp(npi->name,"drive_afni") == 0 ){
00437              char *cmd = NI_get_attribute(npi,"cmd") ;
00438              if( cmd != NULL ) (void) AFNI_driver(cmd) ;
00439            }
00440 
00441          
00442 
00443          } else {
00444 
00445            STATUS("Actual NIML data!") ;
00446            AFNI_process_NIML_data( cc , nini , ct ) ;    
00447 
00448          }
00449 
00450          STATUS("Freeing NIML element") ;
00451          NI_free_element( nini ) ;                           
00452        }
00453 
00454      } else keep_reading = 0 ;  
00455 
00456      if( keep_reading ){
00457        STATUS("Loopback to Keep_Reading") ;
00458        goto Keep_Reading ;              
00459      }
00460 
00461    } 
00462 
00463    dont_tell_suma = 0 ;                              
00464    dont_overlay_suma = 0 ;
00465 
00466    
00467 
00468    if( ngood == 0 ){
00469      fprintf(stderr,"++ NIML shutting down: no listening sockets\n") ;
00470      RETURN( True ) ;
00471    }
00472 
00473    RETURN( False ) ;   
00474 }
00475 
00476 
00477 
00478 
00479 
00480 
00481 static void AFNI_process_NIML_data( int chan, void *nini, int ct_start )
00482 {
00483    int tt=NI_element_type(nini) ;
00484    NI_element *nel ;
00485    char msg[256] ;
00486 
00487 ENTRY("AFNI_process_NIML_data") ;
00488 
00489    if( tt < 0 ) EXRETURN ;  
00490 
00491    if( tt == NI_PROCINS_TYPE ) EXRETURN ;   
00492 
00493    
00494 
00495    if( tt == NI_GROUP_TYPE ){
00496      NI_group *ngr = (NI_group *) nini ;
00497 
00498      
00499 
00500      if( strcmp(ngr->name,"AFNI_dataset") == 0 ){
00501 
00502        process_NIML_AFNI_dataset( ngr , ct_start ) ;   
00503 
00504      } else if( strcmp(ngr->name,"VOLUME_DATA") == 0 ){
00505 
00506        process_NIML_AFNI_volumedata( ngr , ct_start ) ;    
00507 
00508      } else {                 
00509 
00510        int ii ;
00511        for( ii=0 ; ii < ngr->part_num ; ii++ )
00512           AFNI_process_NIML_data( chan , ngr->part[ii] , -1 ) ; 
00513      }
00514 
00515      EXRETURN ;
00516    }
00517 
00518    if( tt != NI_ELEMENT_TYPE ) EXRETURN ;  
00519 
00520    
00521 
00522 
00523    nel = (NI_element *)nini ;
00524 
00525 #if 0
00526  fprintf(stderr,"AFNI received NIML element name=%s\n",nel->name) ;
00527 #endif
00528 
00529    
00530 
00531    if( strcmp(nel->name,"SUMA_ixyz") == 0 ){
00532 
00533      process_NIML_SUMA_ixyz(nel, ct_start) ;  
00534 
00535    } else if( strcmp(nel->name,"SUMA_ijk") == 0 ){
00536 
00537      process_NIML_SUMA_ijk(nel, ct_start) ;   
00538 
00539    } else if( strcmp(nel->name,"SUMA_node_normals") == 0 ){
00540 
00541      process_NIML_SUMA_node_normals(nel, ct_start) ;
00542 
00543    } else if( strcmp(nel->name,"SUMA_crosshair_xyz") == 0 ){
00544 
00545      process_NIML_SUMA_crosshair_xyz(nel) ;            
00546 
00547    } else if( strcmp(nel->name,"Node_ROI") == 0 ){
00548 
00549      process_NIML_Node_ROI(nel, ct_start) ;         
00550 
00551    } else if( strcmp(nel->name,"VOLUME_DATA") == 0 ){         
00552 
00553      process_NIML_AFNI_volumedata( nel , ct_start ) ;     
00554 
00555    } else if( strcmp(nel->name,"MRI_IMAGE") == 0 ){           
00556 
00557      process_NIML_MRI_IMAGE( nel , ct_start ) ;       
00558 
00559    } else {
00560      
00561      sprintf(msg,"*** ERROR:\n\n"
00562                  " Unknown NIML input: \n"
00563                  "  <%.222s ...> \n"
00564                  " Ignoring it, and hoping it goes away.\n" ,
00565                  nel->name) ;
00566      AFNI_popup_message(msg) ;
00567    }
00568    EXRETURN ;
00569 }
00570 
00571 
00572 
00573 void AFNI_disable_suma_overlay( int aa )
00574 {
00575    dont_overlay_suma = aa ;
00576 }
00577 
00578 
00579 
00580 
00581 
00582 static void AFNI_niml_redisplay_CB( int why, int q, void *qq, void *qqq )
00583 {
00584    static LDP_list ldp_list = { NULL, 0, 0 };   
00585    Three_D_View *im3d = (Three_D_View *) qqq ;
00586    THD_3dim_dataset *adset , *fdset ;
00587    SUMA_irgba *map ;
00588    float      *rdata, rthresh ;
00589    int        nmap, nvtot , ct , kldp ;
00590    int        sA, sB;
00591    NI_element *nel ;
00592    char msg[16] ;
00593    THD_session *sess ;   
00594 
00595 ENTRY("AFNI_niml_redisplay_CB") ;
00596 
00597    
00598 
00599    if( dont_tell_suma            ||
00600        dont_overlay_suma         ||
00601        !IM3D_OPEN(im3d)          ||
00602        !im3d->vinfo->func_visible  ) EXRETURN ;
00603 
00604    sess  = im3d->ss_now   ; if( sess->su_num  == 0    ) EXRETURN ;
00605    adset = im3d->anat_now ;
00606    fdset = im3d->fim_now  ; if( fdset         == NULL ) EXRETURN ;
00607 
00608    if( sendit ){
00609      if( NI_stream_goodcheck(ns_listen[NS_SUMA],1) < 1 ) EXRETURN ;
00610    }
00611 
00612    
00613 
00614    ct = NI_clock_time() ;
00615 
00616    if ( gv2s_plug_opts.sopt.debug > 0 || gv2s_plug_opts.sopt.dnode >= 0 )
00617       fprintf(stderr,
00618            "============================================================\n");
00619 
00620    if( fill_ldp_surf_list(&ldp_list, sess, &gv2s_plug_opts) != 0 )
00621      EXRETURN ;
00622 
00623    if( gv2s_plug_opts.sopt.debug > 1 )    
00624       disp_ldp_surf_list(&ldp_list, sess);
00625 
00626    
00627 
00628 
00629    for( kldp=0 ; kldp < ldp_list.nused ; kldp++ ){
00630 
00631      
00632 
00633 
00634 
00635 
00636      sA = ldp_list.list[kldp].sA;   
00637      sB = ldp_list.list[kldp].sB;
00638 
00639      rdata = NULL;   
00640      rthresh = 0.0;
00641 
00642      if( ldp_list.list[kldp].use_v2s ){            
00643        nmap = AFNI_vol2surf_func_overlay(im3d, &map, sA,sB, 0, NULL, &rthresh);
00644      } else if ( ldp_list.list[kldp].nsurf > 1 ){  
00645        nmap = AFNI_vol2surf_func_overlay(im3d, &map, sA,sB, 1, NULL, &rthresh);
00646      } else {  
00647        
00648        
00649 
00650        nmap = AFNI_vol2surf_func_overlay(im3d, &map, sA, -1, 1, NULL, &rthresh);
00651      }
00652 
00653 #if 0
00654      if( serrit ) fprintf(stderr,"AFNI_niml_redisplay_CB: nmap=%d\n",nmap) ;
00655 
00656      
00657      if( ! v2s && ( nmap < 0 || sess->su_surf[sA]->vn == NULL ) )
00658      {
00659        if( gv2s_plug_opts.sopt.debug > 0 )
00660          fprintf(stderr,"** afni: bad surface %d, ret: %d,%p\n", sA, nmap, map);
00661        continue ; 
00662      }
00663 #endif
00664 
00665      
00666      if( nmap < 0 || (nmap > 0 && !map) ) 
00667      {
00668        if( gv2s_plug_opts.sopt.debug > 0 )
00669          fprintf(stderr,"** bad v2s map %d, ret: %d,%p\n", sA, nmap, map);
00670        continue ; 
00671      }
00672 
00673      if( nmap > 0 ){  
00674 
00675        int *icol ; byte *rcol, *gcol, *bcol, *acol ; int ii ;
00676 
00677        nel = NI_new_data_element( "SUMA_irgba" , nmap ) ;
00678 
00679        
00680 
00681        NI_add_column( nel , NI_INT  , NULL ) ; icol = nel->vec[0] ;
00682        NI_add_column( nel , NI_BYTE , NULL ) ; rcol = nel->vec[1] ;
00683        NI_add_column( nel , NI_BYTE , NULL ) ; gcol = nel->vec[2] ;
00684        NI_add_column( nel , NI_BYTE , NULL ) ; bcol = nel->vec[3] ;
00685        NI_add_column( nel , NI_BYTE , NULL ) ; acol = nel->vec[4] ;
00686 
00687 #if 0       
00688        if( rdata ){
00689           if( gv2s_plug_opts.sopt.debug > 1 )
00690             fprintf(stderr,"-d sending data and thresh (%f) to suma\n",rthresh);
00691           NI_add_column( nel , NI_FLOAT, rdata ) ;
00692           free(rdata) ;
00693           rdata = NULL ;
00694        }
00695 #endif
00696 
00697        for( ii=0 ; ii < nmap ; ii++ ){   
00698          icol[ii] = map[ii].id ;
00699          rcol[ii] = map[ii].r  ; gcol[ii] = map[ii].g ;
00700          bcol[ii] = map[ii].b  ; acol[ii] = map[ii].a ;
00701        }
00702 
00703        free(map) ;       
00704 
00705      } else {         
00706 
00707        nel = NI_new_data_element( "SUMA_irgba" , 0 ) ;
00708      }
00709 
00710      if ( sess->su_surf[sA]->vn )            
00711        nvtot = sess->su_surf[sA]->vn->nvox ; 
00712      else
00713        nvtot = -1;      
00714 
00715      
00716 
00717      NI_set_attribute( nel, "surface_idcode" , sess->su_surf[sA]->idcode ) ;
00718      NI_set_attribute( nel, "local_domain_parent_ID" ,
00719                             sess->su_surf[sA]->idcode_ldp ) ;
00720      NI_set_attribute( nel, "volume_idcode"  , adset->idcode.str ) ;
00721      NI_set_attribute( nel, "function_idcode", fdset->idcode.str ) ;
00722 
00723      
00724 
00725 
00726      if( nvtot >= 0 ) {
00727        sprintf(msg,"%d",nvtot) ;
00728        NI_set_attribute( nel , "numvox_total" , msg ) ;
00729      }
00730 
00731 #if 0  
00732      if ( nvused >= 0 ) {
00733        sprintf(msg,"%d",nvused) ;
00734        NI_set_attribute( nel , "numvox_used" , msg ) ;
00735      }
00736 #endif
00737 
00738      
00739      NI_set_attribute( nel , "threshold" , MV_format_fval(rthresh)) ;
00740 
00741      if( sendit )
00742        NI_write_element( ns_listen[NS_SUMA] , nel , NI_BINARY_MODE ) ;
00743      if( serrit )
00744        NIML_to_stderr(nel,1) ;
00745 
00746 #if 0
00747      if( serrit || GLOBAL_argopt.yes_niml > 1 )
00748        fprintf(stderr,
00749                "++ NIML write colored surface: voxels=%d nodes=%d time=%d ms\n",
00750                nvused , nmap , ct = NI_clock_time() - ct ) ;
00751 #endif
00752 
00753      NI_free_element(nel) ;  
00754 
00755    } 
00756 
00757    EXRETURN ;
00758 }
00759 
00760 
00761 
00762 
00763 static int disp_ldp_surf_list(LDP_list * ldp_list, THD_session * sess)
00764 {
00765    ldp_surf_list * slist;
00766    int             ldp;
00767 
00768 ENTRY("disp_ldp_surf_list");
00769 
00770    if(!ldp_list || !sess ) {
00771       fprintf(stderr,"** disp_ldp_surf_list: bad params (%p,%p)\n",
00772               ldp_list, sess);
00773       RETURN(1);
00774    }
00775 
00776    if( ldp_list->nused <= 0 ){
00777       fprintf(stderr,"+d LDP_list: empty\n");
00778       RETURN(0);
00779    }
00780 
00781    fprintf(stderr,"+d LDP_list:\n"
00782                   "     (nused, nalloc)       = (%d, %d)\n",
00783                   ldp_list->nused, ldp_list->nalloc);
00784 
00785    for (ldp = 0, slist = ldp_list->list; ldp < ldp_list->nused; ldp++, slist++ )
00786       fprintf(stderr,"     (nsurf,sA,sB,use_v2s) = (%d, %d, %d, %d) : '%s'\n",
00787            slist->nsurf, slist->sA, slist->sB, slist->use_v2s,
00788            slist->full_label_ldp[0] ? slist->full_label_ldp : slist->label_ldp);
00789    RETURN(0);
00790 }
00791 
00792 
00793 
00794 
00795 static int fill_ldp_surf_list(LDP_list * ldp_list, THD_session * sess,
00796                               v2s_plugin_opts * po)
00797 {
00798    ldp_surf_list * slist;
00799    int             surf, ldp;
00800 
00801 ENTRY("fill_ldp_surf_list");
00802 
00803    if(!ldp_list || !sess || !po ) {
00804       fprintf(stderr,"** fill_ldp_surf_list: bad params (%p,%p,%p)\n",
00805               ldp_list, sess, po);
00806       RETURN(1);
00807    }
00808 
00809    if ( sess->su_num <= 0 ) RETURN(0);
00810 
00811    
00812    if( ldp_list->nalloc < sess->su_num ){
00813       ldp_list->nalloc = sess->su_num;
00814       ldp_list->list = (ldp_surf_list *)realloc(ldp_list->list,
00815                                  ldp_list->nalloc * sizeof(ldp_surf_list));
00816       if( !ldp_list->list ){
00817          fprintf(stderr,"** cannot allocate ldp_list (%d)\n", ldp_list->nalloc);
00818          exit(1);
00819       }
00820    }
00821 
00822    
00823    ldp_list->nused = 0;
00824 
00825    
00826    for ( surf = 0; surf < sess->su_num; surf++ ) {
00827       for ( ldp = 0; ldp < ldp_list->nused; ldp++ )  
00828          if ( strncmp(ldp_list->list[ldp].idcode_ldp,
00829                       sess->su_surf[surf]->idcode_ldp,32) == 0 )
00830             break;
00831       slist = &ldp_list->list[ldp];     
00832 
00833       if( ldp == ldp_list->nused ){     
00834          slist->idcode_ldp        = sess->su_surf[surf]->idcode_ldp;
00835          slist->label_ldp         = sess->su_surf[surf]->label_ldp;
00836          slist->full_label_ldp[0] = '\0';  
00837          slist->nsurf             = 1;     
00838          slist->sA                = surf;  
00839          slist->sB                = -1;    
00840          slist->use_v2s           = 0;     
00841 
00842          ldp_list->nused++;     
00843 
00844          if ( po->sopt.debug > 2 )
00845             fprintf(stderr,"+d ldp_list add: ldp '%s', surf #%d '%s'\n",
00846                     slist->label_ldp, surf, sess->su_surf[surf]->label);
00847       } else {
00848          slist->nsurf++;
00849          if( slist->nsurf == 2 ) slist->sB = surf;
00850 
00851          if ( po->sopt.debug > 2 )
00852             fprintf(stderr,"+d ldp_list add: ldp '%s', surf #%d '%s'\n",
00853                     slist->label_ldp, surf, sess->su_surf[surf]->label);
00854       }
00855    }
00856 
00857    (void)slist_choose_surfs(ldp_list, sess, po);
00858 
00859    RETURN(0);
00860 }
00861 
00862 
00863 
00864 
00865 
00866 
00867 
00868 
00869 static int slist_choose_surfs(LDP_list * ldp_list, THD_session * sess,
00870                                   v2s_plugin_opts * po)
00871 {
00872    ldp_surf_list * lsurf;
00873    int           * surfs, max_surf, ldp;
00874    int             first, surf;
00875 
00876 ENTRY("slist_choose_surfs");
00877 
00878    
00879    max_surf = 0;
00880    for ( ldp = 0; ldp < ldp_list->nused; ldp++ )  
00881       if ( ldp_list->list[ldp].nsurf > max_surf )
00882          max_surf = ldp_list->list[ldp].nsurf;
00883 
00884    
00885    surfs = (int *)malloc(max_surf * sizeof(int));
00886    if ( !surfs ) {
00887       fprintf(stderr,"** scs: failed to allocate %d ints\n", max_surf);
00888       exit(1);
00889    }
00890 
00891    
00892    for ( ldp = 0; ldp < ldp_list->nused; ldp++ ) {
00893       lsurf = &ldp_list->list[ldp];                      
00894       
00895 
00896 
00897       if ( slist_surfs_for_ldp(lsurf, surfs, max_surf, sess, po->sopt.debug) )
00898          continue;                              
00899 
00900       slist_check_user_surfs(lsurf, surfs, po);
00901 
00902       if ( lsurf->sB < 0 ) first = 1;               
00903       else                 first = 2;
00904 
00905       
00906       if ( (first < lsurf->nsurf) && (! lsurf->use_v2s || po->sopt.debug > 1) ){
00907          fprintf(stderr,
00908            "--------------------------------------------------\n"
00909            "received too many surfaces for LDP '%s'\n",
00910            lsurf->full_label_ldp[0] ? lsurf->full_label_ldp : lsurf->label_ldp);
00911          for ( surf = 0; surf < first; surf++ )
00912             fprintf(stderr,"    using    surf #%d : %s\n",
00913                     surfs[surf], sess->su_surf[surfs[surf]]->label);
00914          for ( surf = first; surf < lsurf->nsurf; surf++ )
00915             fprintf(stderr,"    ignoring surf #%d : %s\n",
00916                     surfs[surf], sess->su_surf[surfs[surf]]->label);
00917       }
00918    }
00919 
00920    free(surfs);
00921 
00922    RETURN(0);
00923 }
00924 
00925 
00926 
00927 
00928 static int slist_check_user_surfs( ldp_surf_list * lsurf, int * surfs,
00929                                    v2s_plugin_opts * po )
00930 {
00931    int done = 0, posn;
00932    ENTRY("slist_check_user_surfs");
00933 
00934    
00935    if ( ! po->ready ) RETURN(0);
00936    if ( ! po->use0 && ! po->use1 ) RETURN(0);
00937 
00938    if ( po->use0 ) {
00939       posn = int_list_posn(surfs, lsurf->nsurf, po->s0A);
00940       if ( posn >= 0 ) {
00941          done = 1;
00942          lsurf->use_v2s = 1;                            
00943          if ( posn != 0 ) {                             
00944              lsurf->sA   = surfs[posn];
00945              surfs[posn] = surfs[0];
00946              surfs[0]    = lsurf->sA;
00947          }
00948 
00949          
00950          if ( po->s0B < 0 )
00951             lsurf->sB = -1;
00952          else {
00953             posn = int_list_posn(surfs+1, lsurf->nsurf-1, po->s0B) + 1;
00954             if ( posn >= 1 ) {                          
00955                if ( posn != 1 ) {                       
00956                    lsurf->sB   = surfs[posn];
00957                    surfs[posn] = surfs[1];
00958                    surfs[1]    = lsurf->sB;
00959                }
00960             } else                      
00961                fprintf(stderr,"** user requested surf pair (%d,%d), but\n"
00962                            "   cannot find surf %d for LDP '%s'\n"
00963                            "   --> giving up and using pair (%d,%d)\n",
00964                            po->s0A, po->s0B, po->s0B, lsurf->label_ldp,
00965                            lsurf->sA, lsurf->sB);
00966          }
00967       }
00968    }
00969 
00970    
00971    if ( ! done && po->use1 ) {
00972       posn = int_list_posn(surfs, lsurf->nsurf, po->s1A);
00973       if ( posn >= 0 ) {
00974          done = 1;
00975          lsurf->use_v2s = 1;                            
00976          if ( posn != 0 ) {                             
00977              lsurf->sA   = surfs[posn];
00978              surfs[posn] = surfs[0];
00979              surfs[0]    = lsurf->sA;
00980          }
00981 
00982          
00983          if ( po->s1B < 0 )
00984             lsurf->sB = -1;
00985          else {
00986             posn = int_list_posn(surfs+1, lsurf->nsurf-1, po->s1B) + 1;
00987             if ( posn >= 1 ) {
00988                if ( posn != 1 ) {                       
00989                    lsurf->sB   = surfs[posn];
00990                    surfs[posn] = surfs[1];
00991                    surfs[1]    = lsurf->sB;
00992                }
00993             } else                      
00994                fprintf(stderr,"** user requested surf pair (%d,%d), but\n"
00995                               "   cannot find surf %d for LDP '%s'\n"
00996                               "   --> giving up and using pair (%d,%d)\n",
00997                               po->s1A, po->s1B, po->s1B, lsurf->label_ldp,
00998                               lsurf->sA, lsurf->sB);
00999          }
01000       }
01001    }
01002 
01003    if ( po->sopt.debug > 1 ) {
01004       if ( done )
01005          fprintf(stderr,"+d user surfs (sA,sB) = (%d,%d) {of %d}, LDP '%s'\n",
01006                           lsurf->sA, lsurf->sB, lsurf->nsurf, lsurf->label_ldp);
01007       else
01008          fprintf(stderr,"+d default    (sA,sB) = (%d,%d) {of %d}, LDP '%s'\n",
01009                           lsurf->sA, lsurf->sB, lsurf->nsurf, lsurf->label_ldp);
01010    }
01011 
01012    RETURN(0);
01013 }
01014 
01015 
01016 
01017 static int int_list_posn(int * vals, int nvals, int test_val)
01018 {
01019    int c;
01020 ENTRY("int_list_posn");
01021 
01022    for (c = 0; c < nvals; c++)
01023       if ( vals[c] == test_val )
01024          RETURN(c);
01025 
01026    RETURN(-1);
01027 }
01028 
01029 
01030 
01031 static int slist_surfs_for_ldp( ldp_surf_list * lsurf, int * surfs, int max,
01032                                 THD_session * sess, int debug )
01033 {
01034    SUMA_surface * ss;
01035    int            count, surf, len;
01036 
01037 ENTRY("slist_surfs_for_ldp");
01038 
01039    if ( debug > 2 )
01040       fprintf(stderr,"-d ss_for_ldp: LDP '%s', ldp.nsurf = %d, su_num = %d\n",
01041               lsurf->label_ldp, lsurf->nsurf, sess->su_num);
01042 
01043    count = 0;
01044    for ( surf = 0; surf < sess->su_num; surf++ )
01045    {
01046       ss = sess->su_surf[surf];
01047 
01048       if ( strncmp(lsurf->idcode_ldp, ss->idcode_ldp, 32) == 0 ) {
01049          if (count >= max) {
01050             fprintf(stderr,"** failure: ss_for_ldp #1 (%s: %d,%d,%d)\n",
01051                     lsurf->label_ldp, surf, count, max);
01052             RETURN(1);
01053          }
01054 
01055          if ( debug > 2 )
01056             fprintf(stderr,"-d surfs_for_ldp: surf %d '%s' matches LDP '%s'\n",
01057                     surf, ss->label, ss->label_ldp);
01058 
01059          
01060          surfs[count++] = surf;
01061          len = strlen(ss->label_ldp);
01062          if ( ((len >= 4) && (strncmp(ss->label+len-4, "SAME", 4) == 0)) ||
01063               (strncmp(lsurf->idcode_ldp, ss->idcode, 64) == 0) ) {
01064             
01065             strncpy(lsurf->full_label_ldp, ss->label, 63);
01066             lsurf->full_label_ldp[63] = '\0';
01067             if ( strlen(lsurf->full_label_ldp) < (63 - 11) )
01068                strcat(lsurf->full_label_ldp, " (via SAME)");
01069 
01070             if ( debug > 2 )
01071                fprintf(stderr,"-d surfs_for_ldp: surf %d '%s' is LDP '%s'\n",
01072                     surf, ss->label, lsurf->full_label_ldp);
01073          }
01074       }
01075    }
01076 
01077    
01078    if ( lsurf->sA != surfs[0] ) {
01079       fprintf(stderr,"** failure: ss_for_ldp #2 (%d,%d)\n",lsurf->sA,surfs[0]);
01080       RETURN(1);
01081    }
01082    if ( lsurf->nsurf > 1 && lsurf->sB != surfs[1] ) {
01083       fprintf(stderr,"** failure: ss_for_ldp #3 (%d,%d)\n",lsurf->sB,surfs[1]);
01084       RETURN(1);
01085    }
01086    
01087    if ( count != lsurf->nsurf ) {
01088       fprintf(stderr,"** failure: ss_for_ldp #4 (%d,%d)\n",count,lsurf->nsurf);
01089       RETURN(1);
01090    }
01091 
01092    RETURN(0);
01093 }
01094 
01095 
01096 
01097 
01098 
01099 
01100 static void AFNI_niml_viewpoint_CB( int why, int q, void *qq, void *qqq )
01101 {
01102    Three_D_View *im3d = (Three_D_View *) qqq ;
01103    NI_element *nel ;
01104    float xyz[3] ;
01105    static float xold=-666,yold=-777,zold=-888 ;
01106    int kbest=-1,ibest=-1 ;
01107 
01108 ENTRY("AFNI_niml_viewpoint_CB") ;
01109 
01110    if( dont_tell_suma                  ||
01111        !IM3D_OPEN(im3d)                ||
01112        im3d->ss_now->su_num     == 0   ||
01113        im3d->ss_now->su_surf[0] == NULL  ) EXRETURN ;
01114 
01115    if( sendit ){
01116      if( NI_stream_goodcheck(ns_listen[NS_SUMA],1) < 1 ) EXRETURN ;
01117    }
01118 
01119    xyz[0] = im3d->vinfo->xi ;  
01120    xyz[1] = im3d->vinfo->yj ;
01121    xyz[2] = im3d->vinfo->zk ;
01122 
01123    if( fabs(xyz[0]-xold) < EPS &&
01124        fabs(xyz[1]-yold) < EPS &&
01125        fabs(xyz[2]-zold) < EPS    ) EXRETURN ;  
01126 
01127    
01128 
01129    AFNI_get_xhair_node( im3d , &kbest , &ibest ) ;
01130 
01131    if( kbest < 0 ) kbest = 0 ;  
01132 
01133    
01134 
01135    nel = NI_new_data_element( "SUMA_crosshair_xyz" , 3 ) ;
01136    NI_add_column( nel , NI_FLOAT , xyz ) ;
01137 
01138    
01139 
01140    NI_set_attribute( nel, "surface_idcode", im3d->ss_now->su_surf[kbest]->idcode ) ;
01141    NI_set_attribute( nel, "volume_idcode" , im3d->anat_now->idcode.str ) ;
01142 
01143    
01144 
01145    if( ibest >= 0 ){
01146      char str[32] ;
01147      sprintf(str,"%d",ibest) ;
01148      NI_set_attribute( nel, "surface_nodeid" , str ) ;
01149    }
01150 
01151    xold = xyz[0] ; yold = xyz[1] ; zold = xyz[2] ;  
01152 
01153    if( sendit )
01154      NI_write_element( ns_listen[NS_SUMA] , nel , NI_TEXT_MODE ) ;
01155    if( serrit )
01156      NIML_to_stderr(nel,1) ;
01157 
01158    NI_free_element(nel) ;
01159    EXRETURN ;
01160 }
01161 
01162 
01163 
01164 void AFNI_get_xhair_node( void *qq3d , int *kkbest , int *iibest )
01165 {
01166    Three_D_View *im3d = (Three_D_View *)qq3d ;
01167    int ks , kbest=-1,ibest=-1     ,ii , nnod ;
01168    float  xyz[3] ,   dbest=WAY_BIG,dd , xbot,xtop,ybot,ytop,zbot,ztop ;
01169    SUMA_surface *ag ;
01170    SUMA_ixyz *nod ;
01171 
01172    if( !IM3D_OPEN(im3d) || (kkbest==NULL && iibest==NULL) ) return ;
01173    if( im3d->ss_now->su_num     == 0   ||
01174        im3d->ss_now->su_surf[0] == NULL  ) return ;
01175 
01176    xyz[0] = im3d->vinfo->xi ;  
01177    xyz[1] = im3d->vinfo->yj ;
01178    xyz[2] = im3d->vinfo->zk ;
01179 
01180    
01181 
01182    xbot = ybot = zbot = xtop = ytop = ztop = 0.0 ;   
01183 
01184    if( im3d->vinfo->view_setter > 0 ){   
01185      THD_fvec3 fv ;
01186      LOAD_FVEC3(fv,DSET_DX(im3d->anat_now),
01187                    DSET_DY(im3d->anat_now),DSET_DZ(im3d->anat_now)) ;
01188      fv = THD_3dmm_to_dicomm(im3d->anat_now,fv) ;
01189      switch( im3d->vinfo->view_setter ){
01190        case AXIAL:
01191          dd = 0.499*fabs(fv.xyz[2]) ; zbot = xyz[2]-dd ; ztop = xyz[2]+dd ;
01192        break ;
01193        case SAGITTAL:
01194          dd = 0.499*fabs(fv.xyz[0]) ; xbot = xyz[0]-dd ; xtop = xyz[0]+dd ;
01195        break ;
01196        case CORONAL:
01197          dd = 0.499*fabs(fv.xyz[1]) ; ybot = xyz[1]-dd ; ytop = xyz[1]+dd ;
01198        break ;
01199      }
01200 #if 0
01201      fprintf(stderr,"view_setter=%d box=%f,%f  %f,%f  %f,%f\n",
01202              im3d->vinfo->view_setter , xbot,xtop,ybot,ytop,zbot,ztop ) ;
01203 #endif
01204    }
01205 
01206    
01207 
01208    for( ks=0 ; ks < im3d->ss_now->su_num ; ks++ ){
01209      ag  = im3d->ss_now->su_surf[ks]; if( ag == NULL ) continue;
01210      nod = ag->ixyz ; nnod = ag->num_ixyz ;
01211      ii = AFNI_find_closest_node( nnod,nod , xyz[0],xyz[1],xyz[2] ,
01212                                   xbot,xtop,ybot,ytop,zbot,ztop    ) ;
01213      if( ii >= 0 ){
01214        dd = sqrt( (xyz[0]-nod[ii].x)*(xyz[0]-nod[ii].x)
01215                  +(xyz[1]-nod[ii].y)*(xyz[1]-nod[ii].y)
01216                  +(xyz[2]-nod[ii].z)*(xyz[2]-nod[ii].z) ) ;
01217        if( kbest < 0 || dd < dbest ){
01218          kbest = ks ; ibest = ii ; dbest = dd ;
01219        }
01220      }
01221    }
01222 
01223    
01224    if( kbest < 0 && im3d->vinfo->view_setter > 0 ){
01225      xbot = ybot = zbot = xtop = ytop = ztop = 0.0 ;
01226      for( ks=0 ; ks < im3d->ss_now->su_num ; ks++ ){
01227        ag  = im3d->ss_now->su_surf[ks]; if( ag == NULL ) continue;
01228        nod = ag->ixyz ; nnod = ag->num_ixyz ;
01229        ii = AFNI_find_closest_node( nnod,nod , xyz[0],xyz[1],xyz[2] ,
01230                                     xbot,xtop,ybot,ytop,zbot,ztop    ) ;
01231        if( ii >= 0 ){
01232          dd = sqrt( (xyz[0]-nod[ii].x)*(xyz[0]-nod[ii].x)
01233                    +(xyz[1]-nod[ii].y)*(xyz[1]-nod[ii].y)
01234                    +(xyz[2]-nod[ii].z)*(xyz[2]-nod[ii].z) ) ;
01235          if( kbest < 0 || dd < dbest ){
01236            kbest = ks ; ibest = ii ; dbest = dd ;
01237          }
01238        }
01239      }
01240    }
01241 
01242    if( kbest >= 0 ){
01243      ag = im3d->ss_now->su_surf[kbest] ; nod = ag->ixyz ;
01244      ibest = nod[ibest].id ;
01245    }
01246 
01247    if( kkbest != NULL ) *kkbest = kbest ;
01248    if( iibest != NULL ) *iibest = ibest ;
01249    return ;
01250 }
01251 
01252 
01253 
01254 
01255 
01256 
01257 
01258 
01259 static int process_NIML_SUMA_ixyz( NI_element * nel, int ct_start )
01260 {
01261    THD_slist_find find ;
01262    THD_3dim_dataset *dset ;
01263    THD_session *sess ;      
01264    SUMA_surface *ag, *sold;
01265    int *ic ; float *xc,*yc,*zc ; char *idc , idstr[32] ;
01266    int num , surf_num , replace ;
01267    Three_D_View *im3d = AFNI_find_open_controller() ;
01268    MCW_choose_cbs cbs ;
01269    int nss = GLOBAL_library.sslist->num_sess ;
01270    int ct_read = 0, ct_tot = 0 ;
01271    char msg[1024] ;
01272 
01273 ENTRY("process_NIML_SUMA_ixyz");
01274 
01275    if( dont_hear_suma ) RETURN(0) ;
01276 
01277    if( ct_start >= 0 ) ct_read = NI_clock_time() - ct_start ;
01278 
01279    
01280 
01281    if( nel->vec_len    <  1        ||  
01282        nel->vec_filled <  1        ||  
01283        nel->vec_num    <  4        ||  
01284        nel->vec_typ[0] != NI_INT   ||  
01285        nel->vec_typ[1] != NI_FLOAT ||
01286        nel->vec_typ[2] != NI_FLOAT ||
01287        nel->vec_typ[3] != NI_FLOAT   ){
01288 
01289      AFNI_popup_message( "*** ERROR:\n\n"
01290                          " SUMA_ixyz surface data\n"
01291                          " is badly formatted! \n" ) ;
01292 
01293      if( nel->vec_len    < 1 )
01294         fprintf(stderr,"** SUMA_ixyz vec_len    = %d\n",nel->vec_len) ;
01295      if( nel->vec_filled < 1 )
01296         fprintf(stderr,"** SUMA_ixyz vec_filled = %d\n",nel->vec_filled) ;
01297      RETURN(1) ;
01298    }
01299 
01300    
01301 
01302 
01303 
01304    idc = NI_get_attribute( nel , "volume_idcode" ) ;
01305    if( idc == NULL )
01306      idc = NI_get_attribute( nel , "dataset_idcode" ) ;
01307    if( idc == NULL && nss > 1 ){
01308       AFNI_popup_message( "*** ERROR:\n "
01309                           " SUMA_ixyz surface input\n"
01310                           " does not identify dataset! \n " ) ;
01311       RETURN(1) ;
01312    }
01313    find = PLUTO_dset_finder(idc) ; dset = find.dset ;
01314    if( dset == NULL && nss > 1 ){
01315       sprintf(msg, "*** ERROR:\n\n"
01316                    " SUMA_ixyz volume dataset idcode is \n"
01317                    "   %s\n"
01318                    " Can't find this in AFNI\n", idc ) ;
01319       AFNI_popup_message( msg ) ;
01320       RETURN(1) ;
01321    }
01322 
01323    if( dset != NULL )
01324      sess = GLOBAL_library.sslist->ssar[find.sess_index] ;  
01325    else
01326      sess = GLOBAL_library.sslist->ssar[0] ;
01327 
01328    
01329 
01330    idc = NI_get_attribute( nel , "surface_idcode" ) ;
01331    if( idc == NULL )
01332      idc = NI_get_attribute( nel , "SUMA_idcode" ) ;
01333    if( idc == NULL ){
01334      UNIQ_idcode_fill(idstr) ; idc = idstr ;
01335    }
01336 
01337    
01338 
01339 
01340 
01341    num = sess->su_num ;  
01342 
01343    
01344 
01345    for( surf_num=0 ; surf_num < num ; surf_num++ )
01346      if( strstr(sess->su_surf[surf_num]->idcode,idc) != NULL ) break ;
01347 
01348    
01349 
01350    if( surf_num < num ){
01351       replace = 1 ;       
01352    } else {
01353       replace = 0 ;
01354       num++ ;             
01355 
01356       
01357       sess->su_surf = (SUMA_surface **) realloc(sess->su_surf,
01358                                              num*sizeof(SUMA_surface *)) ;
01359    }
01360    
01361 
01362    
01363 
01364    ag = SUMA_create_empty_surface() ;
01365 
01366    MCW_strncpy(ag->idcode,idc,32);  
01367 
01368    
01369 
01370    idc = NI_get_attribute( nel , "local_domain_parent_ID" ) ;
01371    if( idc == NULL ){
01372      UNIQ_idcode_fill(idstr) ; idc = idstr ;
01373    }
01374    MCW_strncpy(ag->idcode_ldp,idc,32) ;
01375 
01376    
01377 
01378    idc = NI_get_attribute( nel , "surface_label" ) ;
01379    if( idc == NULL )
01380      idc = NI_get_attribute( nel , "SUMA_label" ) ;
01381 
01382    if( idc != NULL )
01383      MCW_strncpy(ag->label,idc,64) ;
01384    else
01385      sprintf(ag->label,"Surf#%d",num) ;
01386 
01387    
01388 
01389    idc = NI_get_attribute( nel , "local_domain_parent" ) ;
01390    if( idc == NULL )
01391      sprintf(ag->label_ldp,"Surf#%d_local_domain_parent",num) ;
01392    else
01393      MCW_strncpy(ag->label_ldp,idc,64) ;
01394 
01395    
01396 
01397    if( dset != NULL )
01398      MCW_strncpy( ag->idcode_dset , dset->idcode.str , 32 ) ;
01399 
01400    
01401 
01402    ic = (int *)   nel->vec[0] ;  
01403    xc = (float *) nel->vec[1] ;  
01404    yc = (float *) nel->vec[2] ;  
01405    zc = (float *) nel->vec[3] ;  
01406 
01407    
01408 
01409    SUMA_add_nodes_ixyz( ag , nel->vec_filled , ic,xc,yc,zc ) ;
01410 
01411    
01412 
01413    SUMA_ixyzsort_surface( ag ) ;
01414 
01415    sess->su_num = num ;     
01416 
01417    
01418 
01419    sold = sess->su_surf[surf_num] ;  
01420    sess->su_surf[surf_num] = ag ;    
01421 
01422    if( replace ){
01423       if( sold->num_ixyz == ag->num_ixyz ){
01424          
01425          ag->num_ijk  = sold->num_ijk  ;     sold->num_ijk  = 0    ;
01426          ag->nall_ijk = sold->nall_ijk ;     sold->nall_ijk = 0    ;
01427          ag->ijk      = sold->ijk      ;     sold->ijk      = NULL ;
01428       } else { 
01429          sprintf(msg,"+++ NOTICE:\n"
01430                "  Surface '%-14.14s' (#%d) for\n"
01431                "  session '%.222s'\n"
01432                "  went from %d nodes to %d nodes\n" ,
01433                ag->label, surf_num, sess->sessname,
01434                sold->num_ixyz , ag->num_ixyz) ;
01435          AFNI_popup_message( msg ) ;  
01436       }
01437       
01438       SUMA_destroy_surface( sold ) ;
01439    }
01440 
01441    
01442 
01443    if( ct_start >= 0 )                     
01444      ct_tot = NI_clock_time() - ct_start ; 
01445 
01446    
01447    sprintf(msg,"\n+++ NOTICE: SUMA_ixyz: %s %d nodes\n"
01448                "  for surface %-14.14s (#%d),\n"
01449                "  session %.222s\n" ,
01450                replace ? "replaced" : "received",
01451                nel->vec_filled, ag->label, surf_num, sess->sessname ) ;
01452 
01453    if( ct_tot > 0 )
01454          sprintf(msg+strlen(msg),
01455                  "  I/O time = %4d ms, Processing = %4d ms\n" ,
01456                  ct_read , ct_tot-ct_read ) ;
01457 
01458    
01459 
01460    if( dset != NULL && find.sess_index != im3d->vinfo->sess_num ){
01461      cbs.ival = find.sess_index ;
01462      AFNI_finalize_dataset_CB( im3d->vwid->view->choose_sess_pb ,
01463                                (XtPointer) im3d ,  &cbs          ) ;
01464    }
01465 #if 1
01466    if( dset != NULL && find.dset_index != im3d->vinfo->anat_num ){
01467      cbs.ival = find.dset_index ;
01468      AFNI_finalize_dataset_CB( im3d->vwid->view->choose_anat_pb ,
01469                                (XtPointer) im3d ,  &cbs          ) ;
01470    }
01471 #endif
01472 
01473    SHOW_MESSAGE(msg) ;
01474 
01475    
01476 
01477 
01478    AFNI_update_all_surface_widgets( sess ) ;  
01479 
01480    dont_tell_suma = 1 ;
01481    PLUTO_dset_redisplay( dset ) ;  
01482    dont_tell_suma = 0 ;
01483 
01484 #if 0
01485    XtSetSensitive( im3d->vwid->imag->pop_sumato_pb, True  ) ;
01486 #endif
01487    RETURN(0) ;
01488 }
01489 
01490 
01491 
01492 static int process_NIML_SUMA_ijk( NI_element * nel, int ct_start )
01493 {
01494    THD_3dim_dataset *dset ;
01495    SUMA_surface *ag ;
01496    int *it, *jt , *kt ; char *idc ;
01497    int num , surf_num , nold ;
01498    THD_session *sess ;             
01499    THD_slist_find find ;
01500    int ct_read = 0, ct_tot = 0 ;
01501    char msg[1024] ;
01502 
01503 ENTRY("process_NIML_SUMA_ijk");
01504 
01505    if( dont_hear_suma ) RETURN(0) ;
01506 
01507    if( ct_start >= 0 ) ct_read = NI_clock_time() - ct_start ;
01508 
01509    
01510 
01511    if( nel->vec_len    <  1      ||  
01512        nel->vec_filled <  1      ||  
01513        nel->vec_num    <  3      ||  
01514        nel->vec_typ[0] != NI_INT ||  
01515        nel->vec_typ[1] != NI_INT ||
01516        nel->vec_typ[2] != NI_INT   ){
01517 
01518      AFNI_popup_message( "*** ERROR:\n\n"
01519                          " SUMA_ijk surface data \n"
01520                          " is badly formatted!\n" ) ;
01521      RETURN(1) ;
01522    }
01523 
01524    
01525 
01526 
01527 
01528    idc = NI_get_attribute( nel , "volume_idcode" ) ;
01529    if( idc == NULL )
01530      idc = NI_get_attribute( nel , "dataset_idcode" ) ;
01531    if( idc == NULL ){
01532       AFNI_popup_message( "*** ERROR:\n "
01533                           " SUMA_ijk surface input\n"
01534                           " does not identify dataset! \n" ) ;
01535       RETURN(1) ;
01536    }
01537    find = PLUTO_dset_finder( idc ) ; dset = find.dset ;
01538    if( dset == NULL ){
01539       sprintf(msg, "*** ERROR:\n\n"
01540                    " SUMA_ijk surface dataset idcode is \n"
01541                    "   %s\n"
01542                    " Can't find this in AFNI\n", idc ) ;
01543       AFNI_popup_message( msg ) ;
01544       RETURN(1) ;
01545    }
01546    sess = GLOBAL_library.sslist->ssar[find.sess_index] ;  
01547 
01548    
01549 
01550    num = sess->su_num ;
01551    if( num == 0 ){
01552       sprintf(msg,"*** ERROR:\n\n"
01553                   " SUMA_ijk surface data\n"
01554                   " received for dataset\n"
01555                   "  %.222s\n"
01556                   " before any SUMA_ixyz data! \n" ,
01557               DSET_FILECODE(dset) ) ;
01558       AFNI_popup_message( msg ) ;
01559       RETURN(1) ;
01560    }
01561 
01562    idc = NI_get_attribute( nel , "surface_idcode" ) ;
01563    if( idc == NULL )
01564      idc = NI_get_attribute( nel , "SUMA_idcode" ) ;
01565    if( idc == NULL ){
01566       AFNI_popup_message( "*** ERROR:\n\n"
01567                           " SUMA_ijk surface input\n"
01568                           " does not have surface idcode! \n" ) ;
01569       RETURN(1) ;
01570    }
01571 
01572    
01573 
01574    for( surf_num=0 ; surf_num < num ; surf_num++ )
01575      if( strstr(sess->su_surf[surf_num]->idcode,idc) != NULL ) break ;
01576 
01577    if( surf_num == num ){
01578       sprintf(msg, "*** ERROR:\n\n"
01579                    " SUMA_ijk surface input surface idcode\n"
01580                    "  %s\n"
01581                    " does not match any surface in session \n"
01582                    "  %.222s\n" ,
01583               idc, sess->sessname ) ;
01584       AFNI_popup_message( msg ) ;
01585       RETURN(1) ;
01586    }
01587 
01588    ag = sess->su_surf[surf_num] ; 
01589 
01590    if( ag->num_ijk > 0 ){
01591       sprintf(msg, "*** WARNING:\n\n"
01592                    " SUMA_ijk surface input surface idcode\n"
01593                    "  %s\n"
01594                    " already has %d triangles in it, and\n"
01595                    " the SUMA user is trying to add %d more!\n" ,
01596               idc, ag->num_ijk , nel->vec_filled ) ;
01597       AFNI_popup_message( msg ) ;
01598       RETURN(1) ;   
01599    }
01600 
01601    
01602 
01603    it = (int *) nel->vec[0] ;  
01604    jt = (int *) nel->vec[1] ;  
01605    kt = (int *) nel->vec[2] ;  
01606 
01607    
01608 
01609    nold = ag->num_ijk ;  
01610 
01611    SUMA_add_triangles( ag , nel->vec_filled , it,jt,kt ) ;
01612 
01613    
01614 
01615    if( ct_start >= 0 )                      
01616      ct_tot = NI_clock_time() - ct_start ;  
01617 
01618    
01619    if( nold == 0 )
01620      sprintf(msg,"\n+++ NOTICE: SUMA_ijk: %d triangles attached\n"
01621                  "  to surface %-14.14s (#%d),\n"
01622                  "  session %.222s\n" ,
01623                  nel->vec_filled, ag->label, surf_num, sess->sessname ) ;
01624    else
01625      sprintf(msg,"\n+++ NOTICE: SUMA_ijk: %d triangles ADDED\n"
01626                  "  (was %d) to surface %-14.14s (#%d),\n"
01627                  "  session %.222s\n" ,
01628                  nel->vec_filled, nold, ag->label, surf_num, sess->sessname ) ;
01629 
01630    if( ct_tot > 0 ) sprintf(msg+strlen(msg),
01631                             "  I/O time = %4d ms, Processing = %4d ms\n" ,
01632                             ct_read , ct_tot-ct_read ) ;
01633 
01634    SHOW_MESSAGE(msg) ;
01635 
01636    dont_tell_suma = 1 ;
01637    PLUTO_dset_redisplay( dset ) ;  
01638    dont_tell_suma = 0 ;
01639 
01640    RETURN(0) ;
01641 }
01642 
01643 
01644 
01645 static int process_NIML_SUMA_node_normals( NI_element * nel, int ct_start )
01646 {
01647    THD_3dim_dataset *dset ;
01648    SUMA_surface *ag ;
01649    float *xc, *yc, *zc ;
01650    char  *idc ;
01651    int num , surf_num ;
01652    THD_session *sess ;
01653    THD_slist_find find ;
01654    int ct_read = 0, ct_tot = 0 ;
01655    char msg[1024] ;
01656 
01657 ENTRY("process_NIML_SUMA_node_normals");
01658 
01659    if( dont_hear_suma ) RETURN(0) ;
01660 
01661    if( ct_start >= 0 ) ct_read = NI_clock_time() - ct_start ;
01662 
01663    
01664 
01665    if( nel->vec_len    <  1        ||  
01666        nel->vec_filled <  1        ||  
01667        nel->vec_num    <  3        ||  
01668        nel->vec_typ[0] != NI_FLOAT ||  
01669        nel->vec_typ[1] != NI_FLOAT ||
01670        nel->vec_typ[2] != NI_FLOAT ){
01671 
01672      AFNI_popup_message( "*** ERROR:\n\n"
01673                          " SUMA_node_normals data \n"
01674                          " is badly formatted!\n" ) ;
01675      RETURN(1) ;
01676    }
01677 
01678    
01679 
01680 
01681 
01682    idc = NI_get_attribute( nel , "volume_idcode" ) ;
01683    if( idc == NULL )
01684      idc = NI_get_attribute( nel , "dataset_idcode" ) ;
01685    if( idc == NULL ){
01686       AFNI_popup_message( "*** ERROR:\n "
01687                           " SUMA_node_normals input\n"
01688                           " does not identify dataset! \n" ) ;
01689       RETURN(1) ;
01690    }
01691    find = PLUTO_dset_finder( idc ) ; dset = find.dset ;
01692    if( dset == NULL ){
01693       sprintf(msg, "*** ERROR:\n\n"
01694                    " SUMA_node_normals surface dataset idcode is \n"
01695                    "   %s\n"
01696                    " Can't find this in AFNI\n", idc ) ;
01697       AFNI_popup_message( msg ) ;
01698       RETURN(1) ;
01699    }
01700    sess = GLOBAL_library.sslist->ssar[find.sess_index] ;
01701 
01702    
01703 
01704    num = sess->su_num ;
01705    if( num == 0 ){
01706       sprintf(msg,"*** ERROR:\n\n"
01707                   " SUMA_node_normals surface data\n"
01708                   " received for dataset\n"
01709                   "  %.222s\n"
01710                   " before any SUMA_ixyz data! \n" ,
01711               DSET_FILECODE(dset) ) ;
01712       AFNI_popup_message( msg ) ;
01713       RETURN(1) ;
01714    }
01715 
01716    idc = NI_get_attribute( nel , "surface_idcode" ) ;
01717    if( idc == NULL )
01718      idc = NI_get_attribute( nel , "SUMA_idcode" ) ;
01719    if( idc == NULL ){
01720       AFNI_popup_message( "*** ERROR:\n\n"
01721                           " SUMA_node_normals surface input\n"
01722                           " does not have surface idcode! \n" ) ;
01723       RETURN(1) ;
01724    }
01725 
01726    
01727 
01728    for( surf_num=0 ; surf_num < num ; surf_num++ )
01729      if( strstr(sess->su_surf[surf_num]->idcode,idc) != NULL ) break ;
01730 
01731    if( surf_num == num ){
01732       sprintf(msg, "*** ERROR:\n\n"
01733                    " SUMA_node_normals surface input surface idcode\n"
01734                    "  %s\n"
01735                    " does not match any surface in session \n"
01736                    "  %.222s\n" ,
01737               idc, sess->sessname ) ;
01738       AFNI_popup_message( msg ) ;
01739       RETURN(1) ;
01740    }
01741 
01742    ag = sess->su_surf[surf_num] ; 
01743 
01744    if( nel->vec_filled != ag->num_ixyz ){
01745       sprintf(msg, "*** ERROR:\n\n"
01746                    " SUMA_node_normals surface input surface idcode\n"
01747                    "  %s\n"
01748                    " has %d nodes, but has been sent %d normals\n" ,
01749                    idc, ag->num_ixyz, nel->vec_filled ) ;
01750       AFNI_popup_message( msg ) ;
01751       RETURN(1) ;
01752    }
01753 
01754    if( ag->norm != NULL ){
01755       sprintf(msg, "*** WARNING:\n\n"
01756                    " SUMA_node_normals surface input surface idcode\n"
01757                    "  %s\n"
01758                    " already has normals associated with it,\n"
01759                    " replacing old normals with new ones\n" , idc ) ;
01760       AFNI_popup_message( msg ) ;
01761    }
01762 
01763    
01764 
01765    xc = (float *) nel->vec[0] ;  
01766    yc = (float *) nel->vec[1] ;  
01767    zc = (float *) nel->vec[2] ;  
01768 
01769    
01770 
01771    if( SUMA_add_norms_xyz( ag , nel->vec_filled , xc,yc,zc ) ){
01772       sprintf(msg, "*** ERROR:SUMA_add_norms_ixyz failure!\n");
01773       AFNI_popup_message( msg ) ;
01774       RETURN(1) ;
01775    }
01776 
01777    
01778 
01779    if( ct_start >= 0 )                      
01780      ct_tot = NI_clock_time() - ct_start ;  
01781 
01782    sprintf(msg,"\n+++ NOTICE: %d normals attached\n"
01783                "  to surface %-14.14s (#%d),\n"
01784                "  session %.222s\n" ,
01785                nel->vec_filled , ag->label , surf_num , sess->sessname ) ;
01786 
01787    if( ct_tot > 0 ) sprintf(msg+strlen(msg),
01788                             "  I/O time = %4d ms, Processing = %4d ms\n" ,
01789                             ct_read , ct_tot-ct_read ) ;
01790 
01791    SHOW_MESSAGE(msg) ;
01792 
01793    dont_tell_suma = 1 ;
01794    PLUTO_dset_redisplay( dset ) ;  
01795    dont_tell_suma = 0 ;
01796 
01797    RETURN(0) ;
01798 }
01799 
01800 
01801 
01802 static int process_NIML_SUMA_crosshair_xyz(NI_element * nel)
01803 {
01804   float *xyz ;
01805 
01806 ENTRY("process_NIML_SUMA_crosshair_xyz");
01807 
01808    if( dont_hear_suma ) RETURN(0) ;
01809 
01810    if( nel->vec_len    <  3        ||
01811        nel->vec_filled <  3        ||
01812        nel->vec_num    <  1        ||
01813        nel->vec_typ[0] != NI_FLOAT   ){
01814 
01815      SHOW_MESSAGE( "+++ WARNING:\n\n"
01816                    " SUMA_crosshair_xyz input \n"
01817                    " is badly formatted!\n" );
01818      RETURN(1) ;
01819    }
01820 
01821    xyz = (float *) nel->vec[0] ;
01822    dont_tell_suma = 1 ;
01823    AFNI_jumpto_dicom( AFNI_find_open_controller(), xyz[0],xyz[1],xyz[2] );
01824    dont_tell_suma = 0 ;
01825    RETURN(0) ;
01826 }
01827 
01828 
01829 
01830 static int process_NIML_Node_ROI( NI_element * nel, int ct_start )
01831 {
01832    int *nlist , *nval , num_list , num,ii,jj,pp,ks ;
01833    char *surf_idc , *roi_prefix , *dset_idc ;
01834    THD_slist_find find ;
01835    THD_3dim_dataset *dset_anat , *dset_func ;
01836    SUMA_surface *ag ;
01837    Three_D_View *im3d = AFNI_find_open_controller() ;
01838    MCW_choose_cbs cbs ;
01839    THD_session *sess ;
01840    THD_fvec3 fv ; THD_ivec3 iv ;
01841    short *funcar ;
01842    float xbot,ybot,zbot , xtop,ytop,ztop ;
01843    int wodsave , nx,ny,nxy ;
01844    int ct_read = 0 ;
01845    char msg[1024] ;
01846 
01847 ENTRY("process_NIML_Node_ROI");
01848 
01849    if( dont_hear_suma ) RETURN(0) ;
01850 
01851    if( ct_start >= 0 ) ct_read = NI_clock_time() - ct_start ;
01852 
01853 STATUS("received Node_ROI element") ;
01854 
01855    if( nel->vec_num    <  2        ||
01856        nel->vec_typ[0] != NI_INT   ||
01857        nel->vec_typ[1] != NI_INT     ){
01858 
01859      SHOW_MESSAGE( "+++ WARNING:\n\n"
01860                    " Node_ROI input \n"
01861                    " is badly formatted!\n" );
01862      RETURN(1) ;
01863    }
01864 
01865    nlist    = (int *) nel->vec[0] ;  
01866    nval     = (int *) nel->vec[1] ;  
01867    num_list = nel->vec_filled ;      
01868 
01869 
01870 
01871 STATUS("checking Node_ROI ID codes") ;
01872 
01873    surf_idc = NI_get_attribute( nel , "MeshParent_idcode" ) ;
01874    if( surf_idc == NULL )
01875      surf_idc = NI_get_attribute( nel , "surface_idcode" ) ;
01876    if( surf_idc == NULL )
01877      surf_idc = NI_get_attribute( nel , "SUMA_idcode" ) ;
01878 
01879    dset_idc = NI_get_attribute( nel , "volume_idcode" ) ;
01880    if( dset_idc == NULL )
01881      dset_idc = NI_get_attribute( nel , "dataset_idcode" ) ;
01882 
01883 
01884 
01885    roi_prefix = NI_get_attribute( nel , "target_volume" ) ;
01886    if( roi_prefix == NULL )
01887      roi_prefix = NI_get_attribute( nel , "ROI_prefix" ) ;
01888 
01889 
01890 
01891    if( surf_idc == NULL ){
01892      AFNI_popup_message( "*** ERROR:\n\n"
01893                          " Node_ROI input doesn't\n"
01894                          " set 'MeshParent_idcode'!\n" ) ;
01895      RETURN(1) ;
01896    }
01897    if( dset_idc == NULL ){
01898      AFNI_popup_message( "*** ERROR:\n\n"
01899                          " Node_ROI input doesn't\n"
01900                          " set 'volume_idcode'!\n" ) ;
01901      RETURN(1) ;
01902    }
01903    if( roi_prefix == NULL ){
01904      AFNI_popup_message( "*** ERROR:\n\n"
01905                          " Node_ROI input doesn't\n"
01906                          " set 'target_volume'!\n" ) ;
01907      RETURN(1) ;
01908    }
01909    if( !THD_filename_pure(roi_prefix) ){
01910      sprintf(msg, "*** ERROR:\n\n"
01911                   " Node_ROI 'target_volume' prefix \n"
01912                   "   %s\n"
01913                   " contains illegal characters!\n" , roi_prefix ) ;
01914      AFNI_popup_message( msg ) ;
01915      RETURN(1) ;
01916    }
01917 
01918 
01919 
01920 STATUS("searching for Node_ROI parent volume") ;
01921 
01922    find = PLUTO_dset_finder( dset_idc ) ; dset_anat = find.dset ;
01923    if( dset_anat == NULL ){
01924      sprintf(msg, "*** ERROR:\n\n"
01925                   " Node_ROI volume dataset idcode is \n"
01926                   "   %s\n"
01927                   " Can't find this in AFNI\n", dset_idc ) ;
01928      AFNI_popup_message( msg ) ;
01929      RETURN(1) ;
01930    }
01931    sess = GLOBAL_library.sslist->ssar[find.sess_index] ;  
01932 
01933 
01934 
01935 STATUS("searching for Node_ROI surface") ;
01936 
01937    num = sess->su_num ;
01938    if( num == 0 ){
01939      sprintf(msg,"*** ERROR:\n\n"
01940                  " Node_ROI data received for dataset\n"
01941                  "  %.222s\n"
01942                  " but no surfaces available in session! \n" ,
01943              DSET_FILECODE(dset_anat) ) ;
01944      AFNI_popup_message( msg ) ;
01945      RETURN(1) ;
01946    }
01947 
01948    for( ks=0 ; ks < num ; ks++ )
01949      if( strstr(sess->su_surf[ks]->idcode,surf_idc) != NULL ) break ;
01950 
01951    if( ks == num ){
01952      sprintf(msg, "*** ERROR:\n\n"
01953                   " Node_ROI surface idcode\n"
01954                   "  %s\n"
01955                   " does not match any surface in session \n"
01956                   "  %.222s\n" ,
01957              surf_idc, sess->sessname ) ;
01958      AFNI_popup_message( msg ) ;
01959      RETURN(1) ;
01960    }
01961 
01962    ag = sess->su_surf[ks] ; 
01963 
01964 
01965 
01966    if( find.sess_index != im3d->vinfo->sess_num ){
01967      cbs.ival = find.sess_index ;
01968      AFNI_finalize_dataset_CB( im3d->vwid->view->choose_sess_pb ,
01969                                (XtPointer) im3d ,  &cbs          ) ;
01970    }
01971    if( find.dset_index >= 0 && find.dset_index != im3d->vinfo->anat_num ){
01972      cbs.ival = find.dset_index ;
01973      AFNI_finalize_dataset_CB( im3d->vwid->view->choose_anat_pb ,
01974                                (XtPointer) im3d ,  &cbs          ) ;
01975    }
01976 
01977    AFNI_update_all_surface_widgets( sess ) ;
01978 #if 0
01979    XtSetSensitive( im3d->vwid->imag->pop_sumato_pb, True ) ;
01980 #endif
01981 
01982    
01983 
01984 STATUS("searching for Node_ROI functional dataset") ;
01985 
01986    find = THD_dset_in_session( FIND_PREFIX , roi_prefix , sess ) ;
01987    dset_func = find.dset ;
01988 
01989    
01990 
01991    if( dset_func != NULL ){
01992      if( !EQUIV_DATAXES(dset_anat->daxes,dset_func->daxes) ){
01993        sprintf(msg, "*** ERROR:\n\n"
01994                     " Node_ROI functional dataset\n"
01995                     "  %.222s\n"
01996                     " exists, but doesn't match geometry of anat dataset\n"
01997                     "  %.222s\n" ,
01998                roi_prefix , DSET_FILECODE(dset_anat) ) ;
01999        AFNI_popup_message( msg ) ;
02000        RETURN(1) ;
02001      }
02002      DSET_mallocize(dset_func) ;     
02003      if( !DSET_LOADED(dset_func) ){
02004        DSET_load(dset_func) ;
02005        if( !DSET_LOADED(dset_func) ){
02006          sprintf(msg, "*** ERROR:\n\n"
02007                       " Node_ROI functional dataset\n"
02008                       "  %.222s\n"
02009                       " exists, but doesn't have data!\n" ,
02010                  roi_prefix ) ;
02011          AFNI_popup_message( msg ) ;
02012          RETURN(1) ;
02013        }
02014        DESTROY_VVLIST(ag->vv) ; ag->vv = NULL ;
02015        sprintf(msg,"+++ NOTICE:\n\n"
02016                    " Node_ROI command is using existing dataset\n"
02017                    "  %.222s\n" , DSET_FILECODE(dset_func) ) ;
02018        SHOW_MESSAGE( msg ) ;
02019      }
02020      if( find.dset_index >= 0 && find.dset_index != im3d->vinfo->func_num ){
02021        cbs.ival = find.dset_index ;
02022        AFNI_finalize_dataset_CB( im3d->vwid->view->choose_func_pb ,
02023                                  (XtPointer) im3d ,  &cbs          ) ;
02024      }
02025 
02026    } else { 
02027 
02028      ii = sess->num_dsset ;
02029      if( ii >= THD_MAX_SESSION_SIZE ){
02030        sprintf(msg, "*** ERROR:\n\n"
02031                     " Can't create Node_ROI dataset\n"
02032                     "  %.222s\n"
02033                     " because of AFNI session overflow!\n" ,
02034                roi_prefix ) ;
02035        AFNI_popup_message( msg ) ;
02036        RETURN(1) ;
02037      }
02038 
02039      dset_func = EDIT_empty_copy( dset_anat ) ;
02040      EDIT_dset_items( dset_func ,
02041                         ADN_prefix    , roi_prefix     ,
02042                         ADN_type      , HEAD_FUNC_TYPE ,
02043                         ADN_func_type , FUNC_BUCK_TYPE ,
02044                         ADN_nvals     , 1              ,
02045                         ADN_ntt       , 0              ,
02046                         ADN_brick_fac , NULL           ,
02047                       ADN_none ) ;
02048      EDIT_BRICK_TO_NOSTAT( dset_func , 0 ) ;
02049      EDIT_substitute_brick( dset_func , 0 , MRI_short , NULL ) ;
02050 
02051      sess->dsset[ii][dset_func->view_type] = dset_func ;
02052      sess->num_dsset ++ ;
02053 
02054 STATUS("switching func to Node_ROI dataset") ;
02055 
02056      cbs.ival = ii ;
02057      AFNI_finalize_dataset_CB( im3d->vwid->view->choose_func_pb ,
02058                                (XtPointer) im3d ,  &cbs          ) ;
02059 
02060 STATUS("popping up Node_ROI dataset creation notice") ;
02061      sprintf(msg,"+++ NOTICE:\n\n"
02062                  " Node_ROI command is creating dataset\n"
02063                  "  %.222s\n" ,
02064             DSET_FILECODE(dset_func) ) ;
02065      SHOW_MESSAGE( msg ) ;
02066 
02067 STATUS("destroying any pre-existing Node_ROI vvlist") ;
02068      DESTROY_VVLIST(ag->vv) ; ag->vv = NULL ;
02069    }
02070 
02071 STATUS("locking Node_ROI dataset into memory") ;
02072    DSET_lock(dset_func) ;  
02073 
02074    funcar = (short *) DSET_BRICK_ARRAY(dset_func,0) ;  
02075 
02076 
02077 
02078 
02079    if( ag->vv != NULL ){
02080  fprintf(stderr,"++ erasing %d voxels from previous SUMA ROI\n",ag->vv->nvox) ;
02081      for( ii=0 ; ii < ag->vv->nvox ; ii++ ) funcar[ ag->vv->voxijk[ii] ] = 0;
02082      DESTROY_VVLIST(ag->vv) ; ag->vv = NULL ;
02083    } else {
02084 STATUS("no old Node_ROI vvlist") ;
02085    }
02086 
02087 
02088 
02089    if( num_list > 0 ){
02090  fprintf(stderr,"++ writing %d voxels from SUMA ROI\n",num_list) ;
02091      ag->vv = (SUMA_vvlist *) malloc( sizeof(SUMA_vvlist) ) ;
02092      ag->vv->nvox   = num_list ;
02093      ag->vv->voxijk = (int *)   malloc( sizeof(int)  *num_list ) ;
02094      ag->vv->voxval = (float *) malloc( sizeof(float)*num_list ) ;
02095 
02096      wodsave = dset_func->wod_flag ; dset_func->wod_flag = 0 ;
02097 
02098      xbot = DSET_XXMIN(dset_func) ; xtop = DSET_XXMAX(dset_func) ;
02099      ybot = DSET_YYMIN(dset_func) ; ytop = DSET_YYMAX(dset_func) ;
02100      zbot = DSET_ZZMIN(dset_func) ; ztop = DSET_ZZMAX(dset_func) ;
02101      nx = DSET_NX(dset_func); ny = DSET_NY(dset_func); nxy = nx*ny ;
02102 
02103      for( ii=0 ; ii < num_list ; ii++ ){
02104        pp = SUMA_find_node_id( ag , nlist[ii] ) ;
02105        if( pp >= 0 ){
02106          LOAD_FVEC3( fv , ag->ixyz[pp].x, ag->ixyz[pp].y, ag->ixyz[pp].z ) ;
02107          fv = THD_dicomm_to_3dmm( dset_func , fv ) ;
02108          if( fv.xyz[0] < xbot || fv.xyz[0] > xtop ) continue ;
02109          if( fv.xyz[1] < ybot || fv.xyz[1] > ytop ) continue ;
02110          if( fv.xyz[2] < zbot || fv.xyz[2] > ztop ) continue ;
02111          iv = THD_3dmm_to_3dind( dset_func , fv ) ;
02112          jj = iv.ijk[0] + iv.ijk[1]*nx + iv.ijk[2]*nxy ;
02113          funcar[jj] = nval[ii] ;
02114          ag->vv->voxijk[ii] = jj ; ag->vv->voxval[ii] = nval[ii] ;
02115        }
02116      }
02117    } else {
02118 STATUS("no nodes in Node_ROI input") ;
02119    }
02120 
02121    DSET_write( dset_func ) ;  
02122 
02123    dont_overlay_suma = 1 ;
02124 
02125 STATUS("redisplay Node_ROI function") ;
02126    MCW_set_bbox( im3d->vwid->view->see_func_bbox , 1 ) ;
02127    im3d->vinfo->func_visible = 1 ;
02128    PLUTO_dset_redisplay( dset_func ) ;  
02129    AFNI_process_drawnotice( im3d ) ;
02130 
02131    RETURN(0) ;
02132 }
02133 
02134 
02135 
02136 
02137 
02138 
02139 
02140 
02141 static void process_NIML_AFNI_dataset( NI_group *ngr , int ct_start )
02142 {
02143    Three_D_View *im3d = AFNI_find_open_controller() ;
02144    THD_3dim_dataset *dset , *old_dset ;
02145    THD_slist_find find ;
02146    THD_session *ss ;
02147    int ii , vv , ww ;
02148 
02149    int ct_read = 0, ct_tot = 0 ;
02150    char msg[1024] ;
02151 
02152 ENTRY("process_NIML_AFNI_dataset") ;
02153 
02154    if( ct_start >= 0 ) ct_read = NI_clock_time() - ct_start ;
02155 
02156    
02157 
02158    dset = THD_niml_to_dataset( ngr , 1 ) ;  
02159    if( dset == NULL ){
02160      AFNI_popup_message("\n*** ERROR:\n"
02161                         " Received bad '<AFNI_dataset ...>'\n"
02162                         " Discarding data and continuing.\n"  ) ;
02163      EXRETURN ;
02164    }
02165 
02166    
02167 
02168    find = PLUTO_dset_finder( dset->idcode.str ) ; old_dset = find.dset ;
02169 
02170    if( old_dset == NULL ){     
02171 
02172      ss = GLOBAL_library.sslist->ssar[im3d->vinfo->sess_num] ;  
02173      ii = ss->num_dsset ;                                       
02174      vv = dset->view_type ;                                     
02175 
02176      if( ii >= THD_MAX_SESSION_SIZE ){                 
02177        DSET_delete(dset) ;
02178        AFNI_popup_message("\n*** ERROR:\n"
02179                           " Received new dataset but am out of space!\n\n" ) ;
02180        EXRETURN ;
02181      }
02182 
02183      ss->dsset[ii][vv] = dset ;     
02184      ss->num_dsset++ ;
02185      POPDOWN_strlist_chooser ;
02186 
02187    } else {                  
02188 
02189      DSET_delete(dset) ;                             
02190      dset = old_dset ;     
02191    }
02192 
02193    DSET_superlock(dset) ;  
02194 
02195    
02196 
02197    (void)THD_add_bricks( dset , ngr ) ;
02198    THD_update_statistics( dset ) ;
02199 
02200 
02201 
02202    if( ct_start >= 0 )                      
02203      ct_tot = NI_clock_time() - ct_start ;  
02204 
02205    if( old_dset == NULL )
02206      sprintf(msg,"\n+++ NOTICE: New AFNI dataset received.\n\n") ;
02207    else
02208      sprintf(msg,"\n+++ NOTICE: Replacement AFNI dataset received.\n\n") ;
02209 
02210    if( ct_tot > 0 ) sprintf(msg+strlen(msg),
02211                             "  I/O time = %4d ms, Processing = %4d ms\n" ,
02212                             ct_read , ct_tot-ct_read ) ;
02213    SHOW_MESSAGE( msg ) ;
02214    UNDUMMYIZE ;
02215    EXRETURN ;
02216 }
02217 
02218 
02219 
02220 
02221 
02222 
02223 
02224 static void process_NIML_AFNI_volumedata( void *nini , int ct_start )
02225 {
02226    char *idc ;
02227    THD_slist_find find ;
02228 
02229    int ct_read = 0, ct_tot = 0 ;
02230    char msg[1024] ;
02231 
02232 ENTRY("process_NIML_AFNI_volumedata") ;
02233 
02234    if( ct_start >= 0 ) ct_read = NI_clock_time() - ct_start ;
02235 
02236 
02237 
02238                      idc = NI_get_attribute( nini , "domain_parent_idcode" ) ;
02239    if( idc == NULL ) idc = NI_get_attribute( nini , "AFNI_idcode" ) ;
02240    if( idc == NULL ) idc = NI_get_attribute( nini , "idcode"      ) ;
02241    if( idc == NULL ){
02242      fprintf(stderr,"\n** ERROR: anonymous VOLUME_DATA received via NIML\a\n");
02243      EXRETURN ;
02244    }
02245 
02246    find = PLUTO_dset_finder(idc) ;
02247    if( find.dset == NULL ){
02248      fprintf(stderr,"\n** ERROR: orphan VOLUME_DATA received via NIML\a\n");
02249      EXRETURN ;
02250    }
02251 
02252 
02253 
02254    (void)THD_add_bricks( find.dset , nini ) ;
02255    THD_update_statistics( find.dset ) ;
02256 
02257 
02258 
02259    if( ct_start >= 0 )                      
02260      ct_tot = NI_clock_time() - ct_start ;  
02261 
02262    sprintf(msg,"\n+++ NOTICE: Replacement AFNI sub-bricks received.\n\n") ;
02263 
02264    if( ct_tot > 0 ) sprintf(msg+strlen(msg),
02265                             "  I/O time = %4d ms, Processing = %4d ms\n" ,
02266                             ct_read , ct_tot-ct_read ) ;
02267    SHOW_MESSAGE( msg ) ;
02268    EXRETURN ;
02269 }
02270 
02271 
02272 
02273 
02274 
02275 
02276 static void process_NIML_MRI_IMAGE( NI_element *nel , int ct_start )
02277 {
02278    MRI_IMAGE *im ;
02279 
02280 ENTRY("process_NIML_MRI_IMAGE") ;
02281 
02282    im = niml_to_mri( nel ) ;   
02283 
02284    
02285 
02286    if( im == NULL ) EXRETURN ;
02287    if( im->nx < 2 || im->nz > 1 || im->ny > 99 ){ mri_free(im); EXRETURN; }
02288 
02289    
02290 
02291    if( im->kind != MRI_float ){
02292      MRI_IMAGE *qim = mri_to_float(im) ;
02293      if( qim != NULL ){ mri_free(im); im = qim; }
02294    }
02295 
02296    
02297 
02298    if( im->name == NULL || im->name[0] == '\0' ){
02299      static int nnn=1 ; char mmm[32] ;
02300      sprintf(mmm,"niml_%03d",nnn) ;
02301      mri_add_name(mmm,im) ;
02302    }
02303 
02304    
02305 
02306    AFNI_add_timeseries( im ) ;
02307    EXRETURN ;
02308 }