Doxygen Source Code Documentation
thd_niftiwrite.c File Reference
#include "mrilib.h"#include "thd_niftiwrite.h"Go to the source code of this file.
Defines | |
| #define | MYEPSILON 0.00001 |
| #define | MYFPEQ(a, b) (fabs((a) - (b)) < MYEPSILON) |
Functions | |
| nifti_image * | populate_nifti_image (THD_3dim_dataset *dset, niftiwr_opts_t options) |
| void | nifti_set_afni_extension (THD_3dim_dataset *dset, nifti_image *nim) |
| int | THD_write_nifti (THD_3dim_dataset *dset, niftiwr_opts_t options) |
Variables | |
| char * | badlist [] |
Define Documentation
|
|
|
|
|
|
Function Documentation
|
||||||||||||
|
Create the AFNI extension string for a NIfTI-1.1 file, and insert this metadata into the nifti_image struct for output to disk.
Definition at line 583 of file thd_niftiwrite.c. References AFNI_yesenv(), badlist, calloc, free, NI_element::name, NI_ELEMENT_TYPE, NI_free_element(), NI_get_attribute(), NI_remove_from_group(), NI_rename_group(), NI_set_attribute(), NI_stream_close(), NI_stream_getbuf(), NI_stream_open(), NI_stream_writestring(), NI_TEXT_MODE, NI_write_element(), NI_group::part, NI_group::part_num, NI_group::part_typ, and THD_nimlize_dsetatr(). Referenced by THD_write_nifti().
00584 {
00585 THD_datablock *blk ;
00586 NI_group *ngr ;
00587 NI_element *nel ;
00588 NI_stream ns ;
00589 char *rhs , buf[128] ;
00590 int ii,bb , npart,*bpart ;
00591
00592 if( nim == NULL ) return ; /* stupid or evil caller */
00593 if( AFNI_yesenv("AFNI_NIFTI_NOEXT") ) return ; /* not allowed */
00594
00595 /** write all dataset 'attributes' into a NIML group */
00596
00597 ngr = THD_nimlize_dsetatr( dset ) ;
00598 if( ngr == NULL ) return ; /* bad */
00599 NI_rename_group( ngr , "AFNI_attributes" ) ;
00600
00601 /* 12 May 2005: add a signature to check the file on input to AFNI */
00602
00603 sprintf(buf,"%d,%d,%d,%d,%d,%d" ,
00604 nim->nx, nim->ny, nim->nz, nim->nt, nim->nu, nim->datatype ) ;
00605 NI_set_attribute( ngr , "NIfTI_nums" , buf ) ;
00606
00607 /** now, scan attribute elements in the group, and mark some
00608 of them as being useless or redundant in the NIfTI world **/
00609
00610 npart = ngr->part_num ;
00611 bpart = (int *)calloc(sizeof(int),npart) ;
00612 for( ii=0 ; ii < npart ; ii++ ){
00613 if( ngr->part_typ[ii] != NI_ELEMENT_TYPE ) continue ;
00614 nel = (NI_element *) ngr->part[ii] ;
00615 if( strcmp(nel->name,"AFNI_atr") != 0 ) continue ;
00616 rhs = NI_get_attribute( nel , "AFNI_name" ) ;
00617 if( rhs == NULL ) continue ;
00618
00619 for( bb=0 ; badlist[bb] != NULL ; bb++ )
00620 if( strcmp(rhs,badlist[bb]) == 0 ){ bpart[ii] = 1; break; }
00621 }
00622
00623 /** remove marked attributes from the NIML group **/
00624
00625 for( ii=npart-1 ; ii >= 0 ; ii-- ){
00626 if( bpart[ii] )
00627 NI_remove_from_group( ngr , ngr->part[ii] ) ;
00628 }
00629 free((void *)bpart) ; /* done with this */
00630 if( ngr->part_num <= 0 ){ NI_free_element(ngr); return; }
00631
00632 /** format into a character string to put in the NIfTI-1.1 extension **/
00633
00634 ns = NI_stream_open( "str:" , "w" ) ;
00635 NI_stream_writestring( ns , "<?xml version='1.0' ?>\n" ) ;
00636 NI_write_element( ns , ngr , NI_TEXT_MODE ) ;
00637 rhs = NI_stream_getbuf( ns ) ;
00638
00639 /** write contents of the string into the nifti_image struct **/
00640
00641 nifti_add_extension( nim , rhs , strlen(rhs)+1 , NIFTI_ECODE_AFNI ) ;
00642
00643 NI_stream_close(ns) ; /* frees the string buffer, too */
00644 NI_free_element(ngr) ; /* done with this trashola */
00645 return ;
00646 }
|
|
||||||||||||
|
Definition at line 85 of file thd_niftiwrite.c. References calloc, THD_3dim_dataset::daxes, THD_3dim_dataset::dblk, niftiwr_opts_t::debug_level, DSET_BRICK_FACTOR, DSET_BRICK_STATCODE, DSET_BRICK_STATPAR, DSET_BRICK_TYPE, DSET_NUM_TIMES, DSET_NUM_TTOFF, DSET_NVALS, DSET_TIMEORIGIN, DSET_TIMEUNITS, ENTRY, THD_3dim_dataset::func_type, niftiwr_opts_t::infile_name, ISFUNC, THD_datablock::nvals, THD_dataxes::nxx, THD_dataxes::nyy, THD_dataxes::nzz, RETURN, STATUS, THD_3dim_dataset::taxis, THD_timeaxis::toff_sl, TR, THD_timeaxis::ttdel, UNITS_MSEC_TYPE, VIEW_TALAIRACH_TYPE, THD_3dim_dataset::view_type, THD_dataxes::xxdel, THD_dataxes::xxorg, THD_dataxes::xxorient, THD_dataxes::yydel, THD_dataxes::yyorg, THD_dataxes::yyorient, THD_dataxes::zzdel, THD_dataxes::zzorg, and THD_dataxes::zzorient.
00086 {
00087 int nparam, type0 , ii , jj, val;
00088 int nif_x_axnum, nif_y_axnum, nif_z_axnum ;
00089 int slast, sfirst ;
00090 int pattern_unknown = 0 ;
00091 nifti_image * nim ;
00092 char axcode[3], axsign[3] ;
00093 float axstep[3] , axstart[3] ;
00094 int axnum[3] ;
00095 float fac0 ;
00096 float dumqx, dumqy, dumqz, dumdx, dumdy, dumdz ;
00097 float pixdimfac[4] ;
00098 float odd_del, even_del, tmp_float ;
00099 int even_parity_sign = 0 ;
00100
00101 ENTRY("populate_nifti_image") ;
00102 /*-- create nifti_image structure --*/
00103
00104 nim = (nifti_image *) calloc( 1 , sizeof(nifti_image) ) ;
00105 if( !nim ) {
00106 fprintf(stderr, "** ERROR: failed to allocate nifti image\n");
00107 RETURN(0) ;
00108 }
00109
00110 /*-- calculate and set ndim and intents --*/
00111 /* cases to allow for:
00112 1. 3d+time dataset
00113 2. 3d func bucket
00114 (not going to handle this currently, may extend later)
00115 -- RWC: modified so that 'u' dimension is for buckets
00116 3. 3d single brick
00117 4. 2d and 1d spatial
00118 (if 2d or 1d spatial + time, treat as #1)
00119 5. Don't know of any vectors in AFNI, so won't do those either
00120 6. Single 3d (or 2d or 1d) functional brik */
00121
00122 if (dset->dblk->nvals > 1) {
00123 STATUS("4D dataset") ;
00124 nim->ndim = (dset->taxis != NULL) ? 4 : 5 ; /* RWC: bucket stored as 5th dimen */
00125
00126 /*-- check sub-bricks for uniformity in type and scale --*/
00127
00128 type0 = DSET_BRICK_TYPE(dset,0) ;
00129 fac0 = DSET_BRICK_FACTOR(dset,0) ;
00130
00131 for( ii=1 ; ii < DSET_NVALS(dset) ; ii++ ){
00132 if( DSET_BRICK_TYPE(dset,ii) != type0){
00133 fprintf(stderr,
00134 "** ERROR: CANNOT WRITE NIFTI FILE; BRICK DATA TYPES NOT CONSISTENT\n") ;
00135 RETURN(0);
00136 } else if( DSET_BRICK_FACTOR(dset,ii) != fac0) {
00137 fprintf(stderr,
00138 "** ERROR: CANNOT WRITE NIFTI FILE; BRICK FACTORS NOT CONSISTENT\n") ;
00139 fprintf(stderr,
00140 "RICH HAMMETT SHOULD FIX THIS REAL SOON NOW\n") ;
00141 RETURN(0);
00142 }
00143 }
00144 } else { /* we only have one brick */
00145 STATUS("3D dataset") ;
00146 if( options.debug_level > 1 ) fprintf(stderr,"ONLY ONE BRICK!!!\n") ;
00147 type0 = DSET_BRICK_TYPE(dset,0);
00148 fac0 = DSET_BRICK_FACTOR(dset,0) ;
00149 if (ISFUNC(dset)) {
00150 STATUS("functional dataset") ;
00151 if( options.debug_level > 1 )
00152 fprintf(stderr,"ONLY ONE BRICK, AND IT'S FUNCTIONAL!!!\n") ;
00153 nim->intent_code = DSET_BRICK_STATCODE(dset,0);
00154 if (nim->intent_code < 0) nim->intent_code = dset->func_type ;
00155 if (nim->intent_code < 0) nim->intent_code = NIFTI_INTENT_NONE ;
00156 if( options.debug_level > 1 )
00157 fprintf(stderr,"ONLY ONE BRICK, AND ITS FUNCTIONAL STAT CODE IS %d !!!\n",nim->intent_code) ;
00158 if(PRINT_TRACING){
00159 char str[256]; sprintf(str,"intent_code = %d",nim->intent_code);STATUS(str);
00160 }
00161 if (nim->intent_code > -1) {
00162 nparam = FUNC_need_stat_aux[nim->intent_code];
00163 if (nparam >= 1) nim->intent_p1 = DSET_BRICK_STATPAR(dset,0,1);
00164 if (nparam >= 2) nim->intent_p2 = DSET_BRICK_STATPAR(dset,0,2);
00165 if (nparam == 3) nim->intent_p3 = DSET_BRICK_STATPAR(dset,0,3);
00166 }
00167 }
00168 if (dset->daxes->nzz > 1) {
00169 nim->ndim = 3 ;
00170 } else if (dset->daxes->nyy > 1) {
00171 nim->ndim = 2 ;
00172 } else {
00173 nim->ndim = 1;
00174 }
00175 }
00176
00177
00178 /*-- set datatype, size, etc. --*/
00179
00180 STATUS("set datatype") ;
00181 switch(type0) {
00182 case MRI_byte:
00183 nim->datatype = DT_UNSIGNED_CHAR;
00184 nim->nbyper = 1 ;
00185 break;
00186 case MRI_short:
00187 nim->datatype = DT_SIGNED_SHORT;
00188 nim->nbyper = 2 ;
00189 break;
00190 case MRI_int:
00191 nim->datatype = DT_SIGNED_INT;
00192 nim->nbyper = 4 ;
00193 break;
00194 case MRI_float:
00195 nim->datatype = DT_FLOAT;
00196 nim->nbyper = 4 ;
00197 break;
00198 case MRI_double:
00199 nim->datatype = DT_DOUBLE;
00200 nim->nbyper = 8 ;
00201 break;
00202 case MRI_complex:
00203 nim->datatype = DT_COMPLEX;
00204 nim->nbyper = 8 ;
00205 break;
00206 case MRI_rgb:
00207 nim->datatype = DT_RGB24;
00208 nim->nbyper = 3 ;
00209 break;
00210 case MRI_rgba:
00211 fprintf(stderr,
00212 "** ERROR: Can't write NIFTI file since dataset is RGBA: %s\n",
00213 options.infile_name) ;
00214 RETURN(0) ;
00215 break;
00216 default:
00217 fprintf(stderr,
00218 "** ERROR: Can't write NIFTI file since datatype is unknown: %s\n",
00219 options.infile_name) ;
00220 RETURN(0) ;
00221 break;
00222 }
00223
00224 /*-- scaling --*/
00225
00226 nim->scl_slope = fac0 ;
00227 nim->scl_inter = 0 ;
00228
00229 /*-- spatial transforms --*/
00230
00231 STATUS("set orientation") ;
00232
00233 axcode[0] = ORIENT_xyz[ dset->daxes->xxorient ] ; axnum[0] = dset->daxes->nxx ;
00234 axcode[1] = ORIENT_xyz[ dset->daxes->yyorient ] ; axnum[1] = dset->daxes->nyy ;
00235 axcode[2] = ORIENT_xyz[ dset->daxes->zzorient ] ; axnum[2] = dset->daxes->nzz ;
00236
00237 axsign[0] = ORIENT_sign[ dset->daxes->xxorient ] ;
00238 axsign[1] = ORIENT_sign[ dset->daxes->yyorient ] ;
00239 axsign[2] = ORIENT_sign[ dset->daxes->zzorient ] ;
00240
00241 axstep[0] = dset->daxes->xxdel ; axstart[0] = dset->daxes->xxorg ;
00242 axstep[1] = dset->daxes->yydel ; axstart[1] = dset->daxes->yyorg ;
00243 axstep[2] = dset->daxes->zzdel ; axstart[2] = dset->daxes->zzorg ;
00244
00245 for (ii = 0 ; ii < 3 ; ii++ ) {
00246 if (axcode[ii] == 'x') {
00247 nif_x_axnum = ii ;
00248 } else if (axcode[ii] == 'y') {
00249 nif_y_axnum = ii ;
00250 } else nif_z_axnum = ii ;
00251 }
00252
00253 nim->qto_xyz.m[0][0] = nim->qto_xyz.m[0][1] = nim->qto_xyz.m[0][2] =
00254 nim->qto_xyz.m[1][0] = nim->qto_xyz.m[1][1] = nim->qto_xyz.m[1][2] =
00255 nim->qto_xyz.m[2][0] = nim->qto_xyz.m[2][1] = nim->qto_xyz.m[2][2] = 0.0 ;
00256
00257 /*-- set voxel and time deltas and units --*/
00258
00259 nim->dx = nim->pixdim[1] = fabs ( axstep[0] ) ;
00260 nim->dy = nim->pixdim[2] = fabs ( axstep[1] ) ;
00261 nim->dz = nim->pixdim[3] = fabs ( axstep[2] ) ;
00262
00263 nim->du = nim->pixdim[5] = 0 ;
00264 nim->dv = nim->pixdim[6] = 0 ;
00265 nim->dw = nim->pixdim[7] = 0 ;
00266
00267 #if 0
00268 val = (axsign[nif_x_axnum] == '+') ? -1 : 1 ;
00269 nim->qto_xyz.m[0][nif_x_axnum] = val * nim->pixdim[nif_x_axnum + 1];
00270 val = (axsign[nif_y_axnum] == '+') ? -1 : 1 ;
00271 nim->qto_xyz.m[1][nif_y_axnum] = val * nim->pixdim[nif_y_axnum + 1];
00272 val = (axsign[nif_x_axnum] == '-') ? -1 : 1 ;
00273 nim->qto_xyz.m[2][nif_z_axnum] = val * nim->pixdim[nif_z_axnum + 1];
00274 #else
00275 nim->qto_xyz.m[0][nif_x_axnum] = - axstep[nif_x_axnum];
00276 nim->qto_xyz.m[1][nif_y_axnum] = - axstep[nif_y_axnum];
00277 nim->qto_xyz.m[2][nif_z_axnum] = axstep[nif_z_axnum];
00278 #endif
00279
00280 /* nifti origin stuff */
00281
00282 #if 0
00283 nim->qoffset_x = axstart[nif_x_axnum] ;
00284 if (axsign[nif_x_axnum] == '+') nim->qoffset_x = - nim->qoffset_x ;
00285 nim->qoffset_y = axstart[nif_y_axnum];
00286 if (axsign[nif_y_axnum] == '+') nim->qoffset_y = - nim->qoffset_y ;
00287 nim->qoffset_z = axstart[nif_z_axnum];
00288 if (axsign[nif_z_axnum] == '-') nim->qoffset_z = - nim->qoffset_z ;
00289 #endif
00290
00291 nim->qoffset_x = -axstart[nif_x_axnum] ;
00292 nim->qoffset_y = -axstart[nif_y_axnum];
00293 nim->qoffset_z = axstart[nif_z_axnum];
00294
00295 #if 0
00296 nim->qoffset_x = -axstart[0] ;
00297 nim->qoffset_y = -axstart[1];
00298 nim->qoffset_z = axstart[2];
00299 #endif
00300
00301 nim->qto_xyz.m[0][3] = nim->qoffset_x ;
00302 nim->qto_xyz.m[1][3] = nim->qoffset_y ;
00303 nim->qto_xyz.m[2][3] = nim->qoffset_z ;
00304
00305 /*-- from the above info, calculate the quaternion qform --*/
00306
00307 STATUS("set quaternion") ;
00308
00309 nifti_mat44_to_quatern( nim->qto_xyz , &nim->quatern_b, &nim->quatern_c, &nim->quatern_d,
00310 &dumqx, &dumqy, &dumqz, &dumdx, &dumdy, &dumdz, &nim->qfac ) ;
00311
00312 /*-- from the same above info, set the sform matrix to equal the qform --*/
00313 /* KRH 7/6/05 - using sform to duplicate qform for
00314 interoperability with FSL */
00315
00316 for ( ii = 0 ; ii < 3 ; ii++ ) {
00317 for ( jj = 0 ; jj < 4 ; jj++ ) {
00318 nim->sto_xyz.m[ii][jj] = nim->qto_xyz.m[ii][jj] ;
00319 }
00320 }
00321
00322 /*-- verify dummy quaternion parameters --*/
00323
00324 if( options.debug_level > 2 )
00325 fprintf(stderr,"++ Quaternion check:\n"
00326 "%f , %f\n %f , %f\n %f , %f\n %f , %f\n %f , %f\n %f , %f\n; %f\n",
00327 nim->qoffset_x, dumqx , nim->qoffset_y, dumqy , nim->qoffset_z, dumqz ,
00328 nim->dx, dumdx , nim->dy, dumdy , nim->dz, dumdz, nim->qfac ) ;
00329
00330 /*-- calculate inverse qform --*/
00331
00332 nim->qto_ijk = nifti_mat44_inverse( nim->qto_xyz ) ;
00333
00334 /*-- set dimensions of grid array --*/
00335
00336 nim->nt = nim->nu = nim->nv = nim->nw = 1 ;
00337 nim->nx = axnum[0] ;
00338 nim->ny = axnum[1] ;
00339 nim->nz = axnum[2] ;
00340
00341 if (dset->taxis == NULL) {
00342 nim->nu = DSET_NVALS(dset) ; /* RWC: bucket is 5th dimension */
00343 } else {
00344 nim->nt = DSET_NUM_TIMES(dset) ; /* time is 4th dimension */
00345 }
00346
00347 if ( nim->nt > 1){
00348 float TR = dset->taxis->ttdel ;
00349 if( DSET_TIMEUNITS(dset) == UNITS_MSEC_TYPE ) TR *= 0.001; /* 10 May 2005 */
00350 nim->dt = nim->pixdim[4] = TR ;
00351 }
00352
00353 nim->dim[0] = nim->ndim;
00354 nim->dim[1] = nim->nx;
00355 nim->dim[2] = nim->ny;
00356 nim->dim[3] = nim->nz;
00357 nim->dim[4] = nim->nt; /* RWC: at most one of nt and nu is > 1 */
00358 nim->dim[5] = nim->nu;
00359 nim->dim[6] = nim->nv;
00360 nim->dim[7] = nim->nw;
00361
00362 nim->nvox = nim->nx * nim->ny * nim->nz * nim->nt
00363 * nim->nu * nim->nv * nim->nw ;
00364
00365 /*-- slice timing --*/
00366
00367 nim->freq_dim = nim->phase_dim = 0 ;
00368 if (dset->taxis != NULL) { /* if time axis exists */
00369 nim->slice_dim = 3 ;
00370 nim->slice_duration = 0 ;
00371 nim->slice_start = 0 ;
00372 nim->slice_end = nim->nz - 1;
00373 nim->toffset = DSET_TIMEORIGIN(dset);
00374
00375 /*-- this bit assumes that afni slice timing offsets *
00376 *-- are created starting from zero and including all *
00377 *-- slices initially. They may later be modified by *
00378 *-- zero padding at either end. No other *
00379 *-- modifications are intentionally accepted right now. */
00380
00381 if (DSET_NUM_TTOFF(dset) > 0 ) { /* if time offset exists */
00382
00383 /*-- Find first and last non-zero element */
00384 #define MYEPSILON 0.00001
00385 #define MYFPEQ(a, b) (fabs((a) - (b)) < MYEPSILON)
00386
00387 for (ii = 0 ; ii < nim->nz ; ii++ ) {
00388 if (!MYFPEQ(dset->taxis->toff_sl[ii],0.0)) break ;
00389 }
00390 sfirst = ii ;
00391 for (ii = nim->nz - 1 ; ii >= sfirst ; ii-- ) {
00392 if (!MYFPEQ(dset->taxis->toff_sl[ii],0.0)) break ;
00393 }
00394 slast = ii ;
00395
00396 if (slast == sfirst) {
00397 /* only zero or one non-zero elements */
00398 pattern_unknown = 1 ;
00399 } else { /* if there is more than one non-zero slice time */
00400
00401 /*-- Calc deltas between offsets in above range. */
00402 /*-- Special case for only two elements!!!!!!!!!!!!!!*/
00403
00404 if ( slast - sfirst == 1 ) {
00405 if (dset->taxis->toff_sl[slast] > dset->taxis->toff_sl[sfirst] ) {
00406 nim->slice_code = NIFTI_SLICE_SEQ_INC ;
00407 } else {
00408 nim->slice_code = NIFTI_SLICE_SEQ_DEC ;
00409 }
00410 } else { /* if there are more than two slice timing offsets */
00411
00412 /*-- While storing in two variables, delta_even and *
00413 *-- delta_odd, check to see if all evens are equal *
00414 *-- and all odds are equal. Fail if not. */
00415
00416 odd_del = dset->taxis->toff_sl[sfirst + 1] -
00417 dset->taxis->toff_sl[sfirst] ;
00418 even_del = dset->taxis->toff_sl[sfirst + 2] -
00419 dset->taxis->toff_sl[sfirst + 1];
00420 for (ii = sfirst + 2 ; ii < slast - 1 ; ii += 2 ) {
00421 if (MYFPEQ(odd_del, dset->taxis->toff_sl[ii + 1] - dset->taxis->toff_sl[ii])) {
00422 if (MYFPEQ(even_del, dset->taxis->toff_sl[ii + 2] - dset->taxis->toff_sl[ii + 1])) {
00423 continue;
00424 }
00425 }
00426 pattern_unknown = 1 ;
00427 break ;
00428 }
00429
00430 if (ii == slast - 1 ) {
00431 if (!MYFPEQ(odd_del, dset->taxis->toff_sl[ii + 1] - dset->taxis->toff_sl[ii])) {
00432 pattern_unknown = 1 ;
00433 }
00434 } else {
00435 tmp_float = (dset->taxis->toff_sl[ii] - dset->taxis->toff_sl[ii - 1]) / odd_del ;
00436 even_parity_sign = tmp_float / fabs (tmp_float) ;
00437 }
00438
00439 /*-- If evens equal odds, it's NIFTI_SLICE_SEQ_INC (if *
00440 *-- positive) or NIFTI_SLICE_SEQ_DEC (if negative) */
00441 if (!pattern_unknown ) {
00442 if (MYFPEQ(odd_del, even_del)) {
00443 if (odd_del > 0) nim->slice_code = NIFTI_SLICE_SEQ_INC ;
00444 else nim->slice_code = NIFTI_SLICE_SEQ_INC ;
00445 } else {
00446
00447 /*-- Else if they ARE of opposite sign, then the *
00448 *-- order is NIFTI_SLICE_ALT_INC if the sum of delta_odd *
00449 *-- and delta_even is positive, and NIFTI_SLICE_ALT_DEC *
00450 *-- if negative. */
00451
00452 if ((odd_del * even_del < 0 ) && (even_parity_sign != -1)) {
00453 if (odd_del + even_del > 0 ) {
00454 nim->slice_code = NIFTI_SLICE_ALT_INC ;
00455 } else {
00456 if (odd_del + even_del < 0 ) {
00457 nim->slice_code = NIFTI_SLICE_ALT_DEC ;
00458 } else {
00459 pattern_unknown = 1 ;
00460 }
00461 }
00462 } else {
00463 pattern_unknown = 1 ;
00464 }
00465 }
00466 }
00467 } /* if there are more than two slice timing offsets */
00468 } /* if there is more than one non-zero slice time */
00469 } else { /* time offset not exists */
00470 pattern_unknown = 1 ;
00471 }
00472
00473 /*-- Now store slice_start and slice_end from the position *
00474 *-- of the first and last non-zero elements above. IFF *
00475 *-- we have removed at least one zero from the beginning *
00476 *-- of an INC order or the end of a DEC order, then *
00477 *-- shift slice_start or slice end to add exactly one zero*
00478 *-- back to the appropriate end. */
00479 /*-- If we've done all of this, we might as well populate *
00480 *-- slice_duration as well. It is the absolute value of *
00481 *-- the delta for the sequential cases, or the sum of the *
00482 *-- two deltas for the alternating cases. */
00483
00484 if (!pattern_unknown ) {
00485 switch (nim->slice_code) {
00486 case NIFTI_SLICE_SEQ_INC:
00487 nim->slice_duration = odd_del ;
00488 if (sfirst > 0) sfirst-- ;
00489 break ;
00490 case NIFTI_SLICE_ALT_INC:
00491 nim->slice_duration = fabs (odd_del + even_del ) ;
00492 if (sfirst > 0) sfirst-- ;
00493 break ;
00494 case NIFTI_SLICE_SEQ_DEC:
00495 nim->slice_duration = fabs (odd_del) ;
00496 if (slast < nim->nz - 1) slast++ ;
00497 break ;
00498 case NIFTI_SLICE_ALT_DEC:
00499 nim->slice_duration = fabs (odd_del + even_del ) ;
00500 if (slast < nim->nz - 1) slast++ ;
00501 break ;
00502 default: /* sanity check */
00503 fprintf(stderr,
00504 "++ ERROR: CANNOT WRITE NIFTI FILE; LOGIC BORKED IN SLICE TIMING\n") ;
00505 fprintf(stderr, "RICH HAMMETT SHOULD FIX THIS REAL SOON NOW\n") ;
00506 RETURN(0);
00507 }
00508
00509 nim->slice_start = sfirst ;
00510 nim->slice_end = slast ;
00511
00512 } else {
00513 nim->slice_code = NIFTI_SLICE_UNKNOWN ;
00514 nim->slice_start = 0 ;
00515 nim->slice_end = 0 ;
00516 } /* end the if !pattern_unknown final assignment section */
00517
00518 nim->time_units = NIFTI_UNITS_SEC ;
00519
00520 } else { /* if time axis not exists */
00521 nim->slice_dim = 0 ;
00522 nim->time_units = NIFTI_UNITS_UNKNOWN ;
00523 }
00524
00525 /*-- byte order --*/
00526
00527 nim->byteorder = nifti_short_order() ;
00528
00529 /* KRH 7/25/05 modified to note talairach view into NIfTI file */
00530
00531 if ( dset->view_type == VIEW_TALAIRACH_TYPE ) {
00532 nim->qform_code = NIFTI_XFORM_TALAIRACH ;
00533 } else {
00534 nim->qform_code = NIFTI_XFORM_SCANNER_ANAT ;
00535 }
00536 nim->sform_code = nim->qform_code ; /* KRH 7/6/05 - using */
00537 /* sform to duplicate qform for interoperability with FSL */
00538
00539
00540 /*-- odds and ends that are constant for AFNI files --*/
00541 nim->cal_min = nim->cal_max = 0 ;
00542 nim->nifti_type = 1 ;
00543 nim->xyz_units = NIFTI_UNITS_MM ;
00544 nim->num_ext = 0;
00545 nim->ext_list = NULL ;
00546 nim->iname_offset = 352 ; /* until extensions are added */
00547 nim->data = NULL ;
00548
00549 RETURN(nim) ;
00550 }
|
|
||||||||||||
|
Write an AFNI dataset as a NIFTI file.
Definition at line 19 of file thd_niftiwrite.c. References niftiwr_opts_t::debug_level, DSET_ARRAY, DSET_BRICK_BYTES, DSET_load, DSET_LOADED, DSET_NVALS, ENTRY, niftiwr_opts_t::infile_name, ISVALID_DSET, malloc, nifti_set_afni_extension(), populate_nifti_image(), RETURN, and THD_filename_ok(). Referenced by main(), and THD_write_3dim_dataset().
00020 {
00021 nifti_image * nim ;
00022 nifti_brick_list nbl ;
00023 int ii ;
00024 char * fname ;
00025
00026 ENTRY("THD_write_nifti") ;
00027
00028 nifti_set_debug_level(options.debug_level) ;
00029
00030 /*-- check inputs for goodness --*/
00031
00032 fname = nifti_strdup(options.infile_name );
00033
00034 if( !THD_filename_ok(fname) || fname[0] == '-' ){
00035 fprintf(stderr,"** ERROR: Illegal filename for NIFTI output: %s\n",
00036 (fname != NULL) ? fname : "(null)" ) ;
00037 RETURN(0) ;
00038 }
00039
00040 if( !ISVALID_DSET(dset) ){
00041 fprintf(stderr,
00042 "** ERROR: Illegal input dataset for NIFTI output: %s\n",
00043 fname ) ;
00044 RETURN(0) ;
00045 }
00046
00047 /*-- load dataset from disk, if need be --*/
00048
00049 DSET_load(dset) ;
00050 if( !DSET_LOADED(dset) ){
00051 fprintf(stderr,
00052 "** ERROR: Can't write NIFTI file since dataset isn't loaded: %s\n", fname) ;
00053 RETURN(0) ;
00054 }
00055
00056 nim = populate_nifti_image(dset,options) ;
00057
00058 /*-- construct filename --*/
00059
00060 nim->fname = malloc( strlen(fname)+16 ) ;
00061 nim->iname = malloc( strlen(fname)+16 ) ;
00062 strcpy(nim->fname,fname) ;
00063 strcpy(nim->iname,fname) ;
00064
00065 /*-- construct nifti_brick_list of pointers to data briks */
00066
00067 if( options.debug_level > 2 ) nifti_image_infodump(nim) ;
00068 nbl.bricks = (void **) malloc ( DSET_NVALS(dset) * sizeof(void*) ) ;
00069 nbl.nbricks = DSET_NVALS(dset) ;
00070 nbl.bsize = DSET_BRICK_BYTES(dset,0) ;
00071 for (ii = 0 ; ii < DSET_NVALS(dset) ; ii++ ) {
00072 nbl.bricks[ii] = DSET_ARRAY(dset,ii) ;
00073 }
00074
00075 /*-- use handy-dandy library function to write out data */
00076
00077 nifti_set_afni_extension( dset , nim ) ; /* 09 May 2005 - RWCox */
00078
00079 nifti_image_write_bricks (nim, &nbl ) ;
00080 RETURN(1) ;
00081 }
|
Variable Documentation
|
|
Initial value: {
"IDCODE_STRING" ,
"DATASET_RANK" ,
"DATASET_DIMENSIONS" ,
"TYPESTRING" ,
"SCENE_DATA" ,
"ORIENT_SPECIFIC" ,
"ORIGIN" ,
"DELTA" ,
"TAXIS_NUMS" ,
"TAXIS_FLOATS" ,
"TAXIS_OFFSETS" ,
"BYTEORDER_STRING" ,
"BRICK_TYPES" ,
"BRICK_FLOAT_FACS" ,
"STAT_AUX" ,
"LABEL_1" ,
"LABEL_2" ,
"DATASET_NAME" ,
NULL }Definition at line 555 of file thd_niftiwrite.c. Referenced by nifti_set_afni_extension(). |