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 }