00001 #include "mrilib.h"
00002 #include "thd.h"
00003 #include "niml.h"
00004 
00005 
00006 
00007 
00008 
00009 
00010 NI_group * THD_nimlize_dsetatr( THD_3dim_dataset *dset )
00011 {
00012    THD_datablock *blk ;
00013    ATR_any *atr_any ;
00014    NI_element *nel ;
00015    int ia , ii ;
00016    NI_group *ngr = NULL ;   
00017 
00018 ENTRY("THD_nimlize_dsetatr") ;
00019 
00020    
00021 
00022    if( !ISVALID_DSET(dset) ) RETURN(ngr) ;
00023    blk = dset->dblk ;
00024    if( blk == NULL )         RETURN(ngr) ;
00025 
00026    THD_set_dataset_attributes( dset ) ;
00027    if( blk->natr == 0 || blk->atr == NULL ) RETURN(ngr) ;
00028 
00029    
00030 
00031    ngr = NI_new_group_element() ;
00032 
00033    NI_rename_group( ngr , "AFNI_dataset" ) ;
00034 
00035    NI_set_attribute( ngr , "self_idcode" , dset->idcode.str ) ;
00036 
00037    
00038 
00039    for( ia=0 ; ia < blk->natr ; ia++ ){
00040 
00041      atr_any = &(blk->atr[ia]) ;
00042      if( atr_any == NULL ) continue ;   
00043 
00044      switch( atr_any->type ){
00045 
00046        
00047 
00048        case ATR_FLOAT_TYPE:{
00049          ATR_float *atr_flo = (ATR_float *)atr_any ;
00050 
00051          nel = NI_new_data_element( "AFNI_atr" , atr_flo->nfl ) ;
00052          nel->outmode = NI_TEXT_MODE ;
00053          NI_set_attribute( nel , "atr_name" , atr_flo->name ) ;
00054          NI_add_column( nel , NI_FLOAT , atr_flo->fl ) ;
00055          NI_add_to_group( ngr , nel ) ;
00056        }
00057        break ;
00058 
00059        case ATR_INT_TYPE:{
00060          ATR_int *atr_int = (ATR_int *)atr_any ;
00061 
00062          nel = NI_new_data_element( "AFNI_atr" , atr_int->nin ) ;
00063          nel->outmode = NI_TEXT_MODE ;
00064          NI_set_attribute( nel , "atr_name" , atr_int->name ) ;
00065          NI_add_column( nel , NI_INT , atr_int->in ) ;
00066          NI_add_to_group( ngr , nel ) ;
00067        }
00068        break ;
00069 
00070        
00071 
00072 
00073 #undef  SZMAX
00074 #define SZMAX 1000
00075        case ATR_STRING_TYPE:{
00076          ATR_string *atr_str = (ATR_string *)atr_any ;
00077          int nnn , nstr , istr , ibot,itop ;
00078          char **sar ;
00079 
00080          nnn  = atr_str->nch ; if( nnn <= 0 ) break ;
00081          nstr = ((nnn-1)/SZMAX) + 1 ;
00082          sar  = (char **)malloc(sizeof(char *)*nstr) ;
00083          for( istr=0 ; istr < nstr ; istr++ ){
00084            ibot = istr*SZMAX ;
00085            itop = ibot+SZMAX ; if( itop > atr_str->nch ) itop = atr_str->nch ;
00086            nnn  = itop-ibot ;
00087            sar[istr] = (char *)calloc(1,nnn+1) ;
00088            memcpy( sar[istr] , atr_str->ch+ibot , nnn ) ;
00089            THD_zblock( nnn , sar[istr] ) ;
00090            sar[istr][nnn] = '\0' ;
00091          }
00092          if( nnn > 1 && sar[nstr-1][nnn-1] == ZBLOCK )
00093            sar[nstr-1][nnn-1] = '\0' ;
00094 
00095          nel = NI_new_data_element( "AFNI_atr" , nstr ) ;
00096          nel->outmode = NI_TEXT_MODE ;
00097          NI_set_attribute( nel , "atr_name" , atr_str->name ) ;
00098 
00099          NI_add_column( nel , NI_STRING , sar ) ;
00100          NI_add_to_group( ngr , nel ) ;
00101 
00102          for( istr=0 ; istr < nstr ; istr++ ) free((void *)sar[istr]) ;
00103          free((void *)sar) ;
00104        }
00105        break ;
00106 
00107      } 
00108 
00109    } 
00110 
00111    
00112 
00113    RETURN(ngr) ;
00114 }
00115 
00116 
00117 
00118 
00119 
00120 
00121 void THD_dblkatr_from_niml( NI_group *ngr , THD_datablock *blk )
00122 {
00123    ATR_any    *atr ;
00124    NI_element *nel ;
00125    int         ip  ;
00126    char       *rhs ;
00127 
00128 ENTRY("THD_dblkatr_from_niml") ;
00129 
00130    if( ngr                  == NULL          ||
00131        NI_element_type(ngr) != NI_GROUP_TYPE ||
00132        blk                  == NULL            ) EXRETURN ;
00133 
00134    
00135 
00136    for( ip=0 ; ip < ngr->part_num ; ip++ ){
00137 
00138      switch( ngr->part_typ[ip] ){
00139 
00140        
00141 
00142        case NI_GROUP_TYPE:
00143          THD_dblkatr_from_niml( (NI_group *)ngr->part[ip] , blk ) ;
00144        break ;
00145 
00146        
00147 
00148 
00149        case NI_ELEMENT_TYPE:{ 
00150          NI_element *nel = (NI_element *)ngr->part[ip] ;
00151          char       *rhs = NI_get_attribute( nel , "atr_name" ) ;
00152          if( rhs == NULL )
00153                      rhs = NI_get_attribute( nel , "AFNI_name" ) ;
00154 
00155          if( strcasecmp(nel->name,"AFNI_atr") == 0 &&    
00156              nel->vec_num == 1                     &&    
00157              nel->vec_len >  0                     &&    
00158              rhs != NULL                           &&    
00159             *rhs != '\0'                              ){ 
00160 
00161            STATUS(rhs) ;
00162 
00163            switch( nel->vec_typ[0] ){ 
00164 
00165              
00166 
00167              case NI_FLOAT:
00168                THD_set_float_atr( blk , rhs ,
00169                                   nel->vec_len , (float *)nel->vec[0] ) ;
00170              break ;
00171 
00172              
00173 
00174              case NI_INT:
00175                THD_set_int_atr( blk , rhs ,
00176                                 nel->vec_len , (int *)nel->vec[0] ) ;
00177              break ;
00178 
00179              
00180 
00181 
00182              case NI_STRING:{
00183                char **sar = (char **)nel->vec[0] , *str ;
00184                int nch , nstr=nel->vec_len , istr , lll=0 ;
00185                for( istr=0 ; istr < nstr ; istr++ ) lll += strlen(sar[istr]) ;
00186                str = malloc(lll+4) ; *str = '\0' ;
00187                for( istr=0 ; istr < nstr ; istr++ ) strcat(str,sar[istr]) ;
00188                nch = strlen(str) ;
00189                THD_unzblock( nch+1 , str ) ;  
00190                THD_set_char_atr( blk , rhs , nch+1 , str ) ;
00191                free(str) ;
00192              }
00193              break ;
00194            }
00195          }
00196        }
00197        break ;
00198      }
00199    } 
00200 
00201    
00202 
00203 
00204 
00205                      rhs = NI_get_attribute(ngr,"self_idcode") ;
00206    if( rhs == NULL ) rhs = NI_get_attribute(ngr,"AFNI_idcode") ;
00207    if( rhs != NULL && *rhs != '\0' ){
00208      STATUS("reset idcode") ;
00209      THD_set_string_atr( blk , ATRNAME_IDSTRING , rhs ) ;
00210    }
00211 
00212    EXRETURN ;
00213 }
00214 
00215 
00216 
00217 
00218 
00219 
00220 
00221 
00222 
00223 
00224 
00225 
00226 
00227 
00228 
00229 
00230 
00231 
00232 
00233 
00234 THD_3dim_dataset * THD_niml_to_dataset( NI_group *ngr , int nodata )
00235 {
00236    THD_3dim_dataset *dset ;
00237    THD_datablock *blk ;
00238    char *rhs ;
00239    int ii ;
00240 
00241 ENTRY("THD_niml_to_dataset") ;
00242 
00243    if( ngr                  == NULL          ||
00244        NI_element_type(ngr) != NI_GROUP_TYPE   ) RETURN(NULL) ;
00245 
00246    
00247 
00248    blk = EDIT_empty_datablock() ;
00249 
00250    THD_dblkatr_from_niml( ngr , blk ) ;  
00251 
00252    
00253 
00254    ii = THD_datablock_from_atr( blk , NULL , NULL ) ;
00255 
00256    if( ii == 0 ){                               
00257      THD_delete_datablock( blk ) ; RETURN(NULL) ;
00258    }
00259 
00260    
00261 
00262    THD_allow_empty_dataset(1) ;
00263    dset = THD_3dim_from_block( blk ) ;
00264    THD_allow_empty_dataset(0) ;
00265    if( dset == NULL ){ THD_delete_datablock( blk ); RETURN(NULL); }
00266 
00267    DSET_mallocize(dset) ;   
00268 
00269    
00270 
00271    rhs = NI_get_attribute( ngr , "self_prefix" ) ;
00272    if( rhs == NULL )
00273      rhs = NI_get_attribute( ngr , "AFNI_prefix" ) ;  
00274    if( rhs != NULL )
00275      EDIT_dset_items( dset , ADN_prefix,rhs , ADN_none ) ;
00276 
00277    
00278 
00279    rhs = NI_get_attribute( ngr , "self_idcode" ) ;
00280    if( rhs == NULL )
00281      rhs = NI_get_attribute( ngr , "AFNI_idcode" ) ;  
00282    if( rhs != NULL )
00283      NI_strncpy( dset->idcode.str , rhs , MCW_IDSIZE ) ;
00284 
00285    
00286 
00287    if( !nodata ){
00288      (void)THD_add_bricks( dset , ngr ) ;
00289      THD_update_statistics( dset ) ;
00290    }
00291 
00292    
00293 
00294    rhs = NI_get_attribute( ngr , "AFNI_zerofill" ) ;
00295    if( rhs != NULL && toupper(rhs[0]) == 'Y' ) THD_zerofill_dataset(dset);
00296 
00297    RETURN(dset) ;
00298 }
00299 
00300 
00301 
00302 
00303 
00304 
00305 
00306 
00307 
00308 
00309 
00310 
00311 
00312 
00313 
00314 
00315 
00316 
00317 
00318 
00319 
00320 
00321 
00322 
00323 
00324 
00325 
00326 
00327 
00328 
00329 int THD_add_bricks( THD_3dim_dataset *dset , void *nini )
00330 {
00331    int nbr=0 , tt=NI_element_type(nini) ;
00332    NI_element *nel ;
00333    int nxyz , ii , jj , nbar , vlen , kk , bb ;
00334    void *bar ;
00335    char *str ;
00336    float fac ;
00337 
00338 ENTRY("THD_add_bricks") ;
00339 
00340    if( !ISVALID_DSET(dset) || tt < 0 ) RETURN(0) ;
00341 
00342    
00343 
00344    if( tt == NI_GROUP_TYPE ){
00345      NI_group *ngr = (NI_group *)nini ;
00346      int ip ;
00347      for( ip=0 ; ip < ngr->part_num ; ip++ )  
00348        nbr += THD_add_bricks( dset , ngr->part[ip] ) ;
00349      RETURN(nbr) ;
00350    }
00351 
00352    
00353 
00354    nel = (NI_element *)nini ;
00355 
00356    
00357 
00358    if( strcasecmp(nel->name,"VOLUME_DATA") != 0 ) RETURN(0) ;
00359 
00360    nxyz = DSET_NVOX(dset) ;   
00361    vlen = nel->vec_len ;      
00362    if( vlen > nxyz ) vlen = nxyz ;
00363 
00364    if( nel->vec_num < 1 || vlen < 1 ) RETURN(0) ;  
00365 
00366    
00367 
00368    kk  = -1 ;                                 
00369                      str = NI_get_attribute( nel , "AFNI_index" ) ;
00370    if( str == NULL ) str = NI_get_attribute( nel , "index"      ) ;
00371    if( str != NULL && isdigit(*str) )
00372      kk = (int)strtol( str , NULL , 10 ) ;
00373 
00374    
00375 
00376    fac = 0.0 ;
00377                      str = NI_get_attribute( nel , "scale_factor" ) ;
00378    if( str == NULL ) str = NI_get_attribute( nel , "AFNI_factor"  ) ;
00379    if( str != NULL && ( *str== '-' || isdigit(*str) ) )
00380      fac = (float)strtod( str , NULL ) ;
00381 
00382    if(PRINT_TRACING){
00383      char str[256] ;
00384      sprintf(str,"kk=%d vlen=%d nxyz=%d fac=%f\n",kk,vlen,nxyz,fac);
00385      STATUS(str);
00386    }
00387 
00388    
00389 
00390    for( jj=0 ; jj < nel->vec_num ; jj++ ){
00391 
00392      if( !AFNI_GOOD_DTYPE(nel->vec_typ[jj]) ) continue ; 
00393 
00394      
00395 
00396      nbar = mri_datum_size(nel->vec_typ[jj]) ;   
00397      bar = calloc( nbar , nxyz ) ;             
00398      if( bar == NULL ) RETURN(nbr) ;               
00399 
00400      
00401 
00402      memcpy( bar , nel->vec[jj] , vlen*nbar ) ;
00403 
00404      
00405 
00406      if( kk < 0 ){  
00407        for( ii=0 ; ii < DSET_NVALS(dset) ; ii++ )
00408          if( DSET_ARRAY(dset,ii) == NULL ) break ;
00409        if( ii == DSET_NVALS(dset) ) kk = ii ;  
00410        bb = ii ;                               
00411      } else if( kk > DSET_NVALS(dset) ){
00412        bb = DSET_NVALS(dset) ;                 
00413      } else {
00414        bb = kk ;                               
00415      }
00416 
00417      if( bb < DSET_NVALS(dset) ){   
00418        EDIT_substitute_brick( dset , bb , nel->vec_typ[jj] , bar ) ;
00419 
00420      } else {                       
00421        bb = DSET_NVALS(dset) ;
00422        EDIT_add_brick( dset , nel->vec_typ[jj] , 0.0 , bar ) ;
00423      }
00424      nbr++ ;   
00425 
00426           if( fac >  0.0 ) EDIT_BRICK_FACTOR(dset,bb,fac) ;
00427      else if( fac <= 0.0 ) EDIT_BRICK_FACTOR(dset,bb,0.0) ;
00428 
00429      DSET_CRUSH_BSTAT(dset,bb) ;
00430 
00431      if( kk >= 0 ) kk++ ;  
00432    }
00433 
00434    RETURN(nbr) ;
00435 }
00436 
00437 
00438 
00439 
00440 
00441 
00442 NI_element * THD_subbrick_to_niml( THD_3dim_dataset *dset, int ival, int flags )
00443 {
00444    NI_element *nel ;
00445    char rhs[64] ;
00446    void *bar ;
00447    int  ityp , nxyz , nbar ;
00448 
00449 ENTRY("THD_subbrick_to_niml") ;
00450 
00451    if( !ISVALID_DSET(dset) ||
00452        ival < 0            || ival >= DSET_NVALS(dset) ) RETURN(NULL) ;
00453 
00454    bar  = DSET_ARRAY(dset,ival) ; if( bar == NULL ) RETURN(NULL) ;
00455 
00456    ityp = DSET_BRICK_TYPE(dset,ival) ;  
00457    nbar = mri_datum_size(ityp) ;        
00458    nxyz = DSET_NVOX(dset) ;             
00459 
00460    nel = NI_new_data_element( "VOLUME_DATA" , nxyz ) ;
00461    NI_set_attribute( nel , "domain_parent_idcode" , dset->idcode.str ) ;
00462    NI_add_column( nel , ityp , bar ) ;
00463    nel->outmode = NI_BINARY_MODE ;  
00464 
00465    
00466 
00467    if( (flags & SBFLAG_INDEX) ){
00468      sprintf(rhs,"%d",ival) ;
00469      NI_set_attribute( nel , "index" , rhs ) ;
00470    }
00471 
00472    if( (flags & SBFLAG_FACTOR) ){
00473      float fac = DSET_BRICK_FACTOR(dset,ival) ;
00474      if( fac > 0.0 ){
00475        sprintf(rhs,"%f",fac) ;
00476        NI_set_attribute( nel , "scale_factor" , rhs ) ;
00477      }
00478    }
00479 
00480    RETURN(nel) ;
00481 }
00482 
00483 
00484 
00485 
00486 
00487 NI_group * THD_dataset_to_niml( THD_3dim_dataset *dset )
00488 {
00489    NI_element *nel ;
00490    NI_group *ngr ;
00491    int iv ;
00492 
00493 ENTRY("THD_dataset_to_niml") ;
00494 
00495    
00496 
00497    ngr = THD_nimlize_dsetatr( dset ) ;
00498    if( ngr == NULL ) RETURN(NULL) ;
00499 
00500    NI_rename_group( ngr , "AFNI_dataset" ) ;
00501 
00502    
00503 
00504    STATUS("adding sub-bricks") ;
00505    for( iv=0 ; iv < DSET_NVALS(dset) ; iv++ ){
00506      nel = THD_subbrick_to_niml( dset , iv , 0 ) ;
00507      if( nel != NULL ) NI_add_to_group( ngr , nel ) ;
00508    }
00509 
00510    RETURN(ngr) ;
00511 }
00512 
00513 
00514 
00515 
00516 
00517 NI_element * mri_to_niml( MRI_IMAGE *im )
00518 {
00519    NI_element *nel ;
00520    void *vpt ;
00521    char rhs[256] ;
00522 
00523 ENTRY("mri_to_niml") ;
00524 
00525    vpt = mri_data_pointer(im) ;
00526    if( vpt == NULL ) RETURN(NULL) ;
00527 
00528    nel = NI_new_data_element( "MRI_IMAGE" , im->nvox ) ;
00529 
00530    
00531  
00532    sprintf( rhs , "%d,%d,%d,%d,%d,%d,%d" ,
00533             im->nx , im->ny , im->nz , im->nt , im->nu , im->nv , im->nw ) ;
00534    NI_set_attribute( nel , "mri_dimen" , rhs ) ;
00535 
00536    if( im->dx != 0.0 || im->dy != 0.0 || im->dz != 0.0 ||
00537        im->dt != 0.0 || im->du != 0.0 || im->dv != 0.0 || im->dw != 0.0 ){
00538 
00539      sprintf( rhs , "%f,%f,%f,%f,%f,%f,%f" ,
00540               im->dx , im->dy , im->dz , im->dt , im->du , im->dv , im->dw ) ;
00541      NI_set_attribute( nel , "mri_dxyz" , rhs ) ;
00542    }
00543 
00544    if( im->xo != 0.0 || im->yo != 0.0 || im->zo != 0.0 ||
00545        im->to != 0.0 || im->uo != 0.0 || im->vo != 0.0 || im->wo != 0.0 ){
00546  
00547      sprintf( rhs , "%f,%f,%f,%f,%f,%f,%f" ,
00548               im->xo , im->yo , im->zo , im->to , im->uo , im->vo , im->wo ) ;
00549      NI_set_attribute( nel , "mri_xyzo" , rhs ) ;
00550    }
00551 
00552    if( im->name != NULL && im->name[0] != '\0' )
00553      NI_set_attribute( nel , "mri_name" , rhs ) ;
00554 
00555    
00556     NI_add_column( nel , im->kind , vpt ) ;
00557 
00558    RETURN(nel) ;
00559 }
00560 
00561 
00562 
00563 
00564 
00565 MRI_IMAGE * niml_to_mri( NI_element *nel )
00566 {
00567    char *rhs ;
00568    int   nx=1,ny=1,nz=1,nt=1,nu=1,nv=1,nw=1 ;
00569    MRI_IMAGE *im ;
00570    void *vpt ;
00571    int  nvox ;
00572 
00573 ENTRY("niml_to_mri") ;
00574 
00575    if( NI_element_type(nel)          != NI_ELEMENT_TYPE ||
00576        strcmp(nel->name,"MRI_IMAGE") != 0               ||
00577        nel->vec_num                  != 1               ||
00578        nel->vec_len                  <= 0                 ) RETURN(NULL) ;
00579 
00580    rhs = NI_get_attribute( nel , "mri_dimen" ) ;
00581    if( rhs == NULL ) RETURN(NULL) ;
00582    sscanf( rhs , "%d,%d,%d,%d,%d,%d,%d" ,
00583            &nx , &ny , &nz , &nt , &nu , &nv , &nw ) ;
00584    if( nx < 1 ) nx = 1 ;
00585    if( ny < 1 ) ny = 1 ;
00586    if( nz < 1 ) nz = 1 ;
00587    if( nt < 1 ) nt = 1 ;
00588    if( nu < 1 ) nu = 1 ;
00589    if( nv < 1 ) nv = 1 ;
00590    if( nw < 1 ) nw = 1 ;
00591 
00592    im = mri_new_7D_generic( nx,ny,nz,nt,nu,nv,nw ,
00593                             nel->vec_typ[0] , 1   ) ;
00594    if( im == NULL ) RETURN(NULL) ;
00595 
00596    vpt = mri_data_pointer(im) ;
00597    nvox = im->nvox ; if( nvox > nel->vec_len ) nvox = nel->vec_len ;
00598    memcpy( vpt , nel->vec[0] , im->pixel_size * nvox ) ;
00599 
00600    rhs = NI_get_attribute( nel , "mri_dxyz" ) ;
00601    if( rhs != NULL )
00602      sscanf( rhs , "%f,%f,%f,%f,%f,%f,%f" ,
00603              &(im->dx), &(im->dy), &(im->dz),
00604              &(im->dt), &(im->du), &(im->dv), &(im->dw) ) ;
00605 
00606    rhs = NI_get_attribute( nel , "mri_xyzo" ) ;
00607    if( rhs != NULL )
00608      sscanf( rhs , "%f,%f,%f,%f,%f,%f,%f" ,
00609              &(im->xo), &(im->yo), &(im->zo),
00610              &(im->to), &(im->uo), &(im->vo), &(im->wo) ) ;
00611 
00612    rhs = NI_get_attribute( nel , "mri_name" ) ;
00613    if( rhs != NULL ) mri_add_name( rhs , im ) ;
00614 
00615    RETURN(im) ;
00616 }
00617 
00618 
00619 
00620 int AFNI_obj_to_dataset( NI_objcontainer *dc )
00621 {
00622    THD_3dim_dataset *dset ;
00623 
00624    if( dc == NULL || strcmp(dc->self_name,"AFNI_dataset") != 0 ) return 0 ;
00625 
00626    dset = THD_niml_to_dataset( (NI_group *)dc->self_data , 0 ) ;
00627    if( dset == NULL ) return 0 ;
00628 
00629    NI_free_element( dc->self_data ) ;
00630    dc->self_data = (void *)dset ;
00631    return 1 ;
00632 }
00633 
00634 
00635 
00636 int AFNI_dataset_to_obj( NI_objcontainer *dc )
00637 {
00638    NI_group *ngr ;
00639    THD_3dim_dataset *dset ;
00640 
00641    if( dc == NULL || strcmp(dc->typename,"AFNI_dataset") != 0 ) return 0 ;
00642 
00643    dset = (THD_3dim_dataset *)dc->self_data ;
00644    if( !ISVALID_DSET(dset) ) return 0 ;
00645 
00646    ngr = THD_dataset_to_niml( dset ) ;
00647    if( ngr == NULL ) return 0 ;
00648 
00649    dc->self_data = (void *)ngr ;
00650    return 1 ;
00651 }