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(). |