MRI_IMAGE * THD_extract_series( int ind , THD_3dim_dataset *dset , int raw ) { int nv , typ , ii ; MRI_IMAGE *im ; void *imar ; ENTRY("THD_extract_series") ; if( !ISVALID_DSET(dset) ) RETURN(NULL) ; nv = dset->dblk->nvals ; if( raw ) typ = DSET_BRICK_TYPE(dset,0) ; /* type of output array */ else typ = MRI_float ; im = mri_new( nv , 1 , typ ) ; /* output image */ imar = mri_data_pointer(im) ; ii = THD_extract_array( ind , dset , raw , imar ) ; /* get data */ if( ii != 0 ){ mri_free(im) ; RETURN(NULL) ; } /* bad */ if( dset->taxis != NULL ){ /* 21 Oct 1996 */ float zz , tt ; int kz = ind / ( dset->daxes->nxx * dset->daxes->nyy ) ; zz = dset->daxes->zzorg + kz * dset->daxes->zzdel ; tt = THD_timeof( 0 , zz , dset->taxis ) ; im->xo = tt ; im->dx = dset->taxis->ttdel ; /* origin and delta */ if( dset->taxis->units_type == UNITS_MSEC_TYPE ){ /* convert to sec */ im->xo *= 0.001 ; im->dx *= 0.001 ; } } else { im->xo = 0.0 ; im->dx = 1.0 ; /* 08 Nov 1996 */ } RETURN(im) ; }
static int * PLUTO_4D_to_nothing (THD_3dim_dataset * old_dset , int ignore , int detrend , generic_func * user_func, void * user_data ) { byte ** bptr = NULL ; /* one of these will be the array of */ short ** sptr = NULL ; /* pointers to input dataset sub-bricks */ float ** fptr = NULL ; /* (depending on input datum type) */ complex ** cptr = NULL ; float * fxar = NULL ; /* array loaded from input dataset */ float * fac = NULL ; /* array of brick scaling factors */ float * dtr = NULL ; /* will be array of detrending coeff */ float val , d0fac , d1fac , x0,x1; double tzero=0.0 , tdelta , ts_mean , ts_slope ; int ii , old_datum , nuse , use_fac , iz,izold, nxy,nvox ; static int retval; register int kk ; /*----------------------------------------------------------*/ /*----- Check inputs to see if they are reasonable-ish -----*/ if( ! ISVALID_3DIM_DATASET(old_dset) ) return NULL ; if( user_func == NULL ) return NULL ; if( ignore < 0 ) ignore = 0 ; /*--------- set up pointers to each sub-brick in the input dataset ---------*/ old_datum = DSET_BRICK_TYPE( old_dset , 0 ) ; /* get old dataset datum */ nuse = DSET_NUM_TIMES(old_dset) - ignore ; /* # of points on time axis */ if( nuse < 2 ) return NULL ; DSET_load( old_dset ) ; /* must be in memory before we get pointers to it */ kk = THD_count_databricks( old_dset->dblk ) ; /* check if it was */ if( kk < DSET_NVALS(old_dset) ){ /* loaded correctly */ DSET_unload( old_dset ) ; return NULL ; } switch( old_datum ){ /* pointer type depends on input datum type */ default: /** don't know what to do **/ DSET_unload( old_dset ) ; return NULL ; /** create array of pointers into old dataset sub-bricks **/ /*--------- input is bytes ----------*/ /* voxel #i at time #k is bptr[k][i] */ /* for i=0..nvox-1 and k=0..nuse-1. */ case MRI_byte: bptr = (byte **) malloc( sizeof(byte *) * nuse ) ; if( bptr == NULL ) return NULL ; for( kk=0 ; kk < nuse ; kk++ ) bptr[kk] = (byte *) DSET_ARRAY(old_dset,kk+ignore) ; break ; /*--------- input is shorts ---------*/ /* voxel #i at time #k is sptr[k][i] */ /* for i=0..nvox-1 and k=0..nuse-1. */ case MRI_short: sptr = (short **) malloc( sizeof(short *) * nuse ) ; if( sptr == NULL ) return NULL ; for( kk=0 ; kk < nuse ; kk++ ) sptr[kk] = (short *) DSET_ARRAY(old_dset,kk+ignore) ; break ; /*--------- input is floats ---------*/ /* voxel #i at time #k is fptr[k][i] */ /* for i=0..nvox-1 and k=0..nuse-1. */ case MRI_float: fptr = (float **) malloc( sizeof(float *) * nuse ) ; if( fptr == NULL ) return NULL ; for( kk=0 ; kk < nuse ; kk++ ) fptr[kk] = (float *) DSET_ARRAY(old_dset,kk+ignore) ; break ; /*--------- input is complex ---------*/ /* voxel #i at time #k is cptr[k][i] */ /* for i=0..nvox-1 and k=0..nuse-1. */ case MRI_complex: cptr = (complex **) malloc( sizeof(complex *) * nuse ) ; if( cptr == NULL ) return NULL ; for( kk=0 ; kk < nuse ; kk++ ) cptr[kk] = (complex *) DSET_ARRAY(old_dset,kk+ignore) ; break ; } /* end of switch on input type */ nvox = old_dset->daxes->nxx * old_dset->daxes->nyy * old_dset->daxes->nzz ; /*---- allocate space for 1 voxel timeseries ----*/ fxar = (float *) malloc( sizeof(float) * nuse ) ; /* voxel timeseries */ if( fxar == NULL ){ ZFREE_WORKSPACE ; return NULL ; } /*--- get scaling factors for sub-bricks ---*/ fac = (float *) malloc( sizeof(float) * nuse ) ; /* factors */ if( fac == NULL ){ ZFREE_WORKSPACE ; return NULL ; } use_fac = 0 ; for( kk=0 ; kk < nuse ; kk++ ){ fac[kk] = DSET_BRICK_FACTOR(old_dset,kk+ignore) ; if( fac[kk] != 0.0 ) use_fac++ ; else fac[kk] = 1.0 ; } if( !use_fac ) ZFREEUP(fac) ; /*--- setup for detrending ---*/ dtr = (float *) malloc( sizeof(float) * nuse ) ; if( dtr == NULL ){ ZFREE_WORKSPACE ; return NULL ; } d0fac = 1.0 / nuse ; d1fac = 12.0 / nuse / (nuse*nuse - 1.0) ; for( kk=0 ; kk < nuse ; kk++ ) dtr[kk] = kk - 0.5 * (nuse-1) ; /* linear trend, orthogonal to 1 */ /*----- set up to find time at each voxel -----*/ tdelta = old_dset->taxis->ttdel ; if( DSET_TIMEUNITS(old_dset) == UNITS_MSEC_TYPE ) tdelta *= 0.001 ; if( tdelta == 0.0 ) tdelta = 1.0 ; izold = -666 ; nxy = old_dset->daxes->nxx * old_dset->daxes->nyy ; /*----------------------------------------------------*/ /*----- Setup has ended. Now do some real work. -----*/ /* start notification */ #if 0 user_func( 0.0 , 0.0 , nvox , NULL,0.0,0.0 , user_data ) ; #else { void (*uf)(double,double,int,float *,double,double,void *) = (void (*)(double,double,int,float *,double,double,void *))(user_func) ; uf( 0.0l,0.0l , nvox , NULL , 0.0l,0.0l , user_data ) ; } #endif /***** loop over voxels *****/ for( ii=0 ; ii < nvox ; ii++ ){ /* 1 time series at a time */ /*** load data from input dataset, depending on type ***/ switch( old_datum ){ /*** input = bytes ***/ case MRI_byte: for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = bptr[kk][ii] ; break ; /*** input = shorts ***/ case MRI_short: for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = sptr[kk][ii] ; break ; /*** input = floats ***/ case MRI_float: for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = fptr[kk][ii] ; break ; /*** input = complex (note we use absolute value) ***/ case MRI_complex: for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = CABS(cptr[kk][ii]) ; break ; } /* end of switch over input type */ /*** scale? ***/ if( use_fac ) for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] *= fac[kk] ; /** compute mean and slope **/ x0 = x1 = 0.0 ; for( kk=0 ; kk < nuse ; kk++ ){ x0 += fxar[kk] ; x1 += fxar[kk] * dtr[kk] ; } x0 *= d0fac ; x1 *= d1fac ; /* factors to remove mean and trend */ ts_mean = x0 ; ts_slope = x1 / tdelta ; /** detrend? **/ if( detrend ) for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] -= (x0 + x1 * dtr[kk]) ; /** compute start time of this timeseries **/ /* The info computed here is not being used in this version*/ iz = ii / nxy ; /* which slice am I in? */ if( iz != izold ){ /* in a new slice? */ tzero = THD_timeof( ignore , old_dset->daxes->zzorg + iz*old_dset->daxes->zzdel , old_dset->taxis ) ; izold = iz ; if( DSET_TIMEUNITS(old_dset) == UNITS_MSEC_TYPE ) tzero *= 0.001 ; } /*** Send data to user function ***/ #if 0 user_func( tzero,tdelta , nuse,fxar,ts_mean,ts_slope , user_data) ; #else { void (*uf)(double,double,int,float *,double,double,void *) = (void (*)(double,double,int,float *,double,double,void *))(user_func) ; uf( tzero,tdelta , nuse,fxar,ts_mean,ts_slope , user_data) ; } #endif } /* end of outer loop over 1 voxels at a time */ DSET_unload( old_dset ) ; /* end notification */ #if 0 user_func( 0.0 , 0.0 , 0 , NULL,0.0,0.0 , user_data ) ; #else { void (*uf)(double,double,int,float *,double,double,void *) = (void (*)(double,double,int,float *,double,double,void *))(user_func) ; uf( 0.0l,0.0l, 0 , NULL,0.0l,0.0l, user_data ) ; } #endif /*-------------- Cleanup and go home ----------------*/ ZFREE_WORKSPACE ; retval = 0; return &retval; /* this value is not used for now .... */ }
THD_3dim_dataset * MAKER_4D_to_typed_fim( THD_3dim_dataset * old_dset , char * new_prefix , int new_datum , int ignore , int detrend , generic_func * user_func , void * user_data ) { THD_3dim_dataset * new_dset ; /* output dataset */ byte ** bptr = NULL ; /* one of these will be the array of */ short ** sptr = NULL ; /* pointers to input dataset sub-bricks */ float ** fptr = NULL ; /* (depending on input datum type) */ complex ** cptr = NULL ; float * fxar = NULL ; /* array loaded from input dataset */ float * fac = NULL ; /* array of brick scaling factors */ float * fout = NULL ; /* will be array of output floats */ float * dtr = NULL ; /* will be array of detrending coeff */ float val , d0fac , d1fac , x0,x1; double tzero=0 , tdelta , ts_mean , ts_slope ; int ii , old_datum , nuse , use_fac , iz,izold, nxy,nvox , nbad ; register int kk ; void (*ufunc)(double,double,int,float *,double,double,void *,float *) = (void (*)(double,double,int,float *,double,double,void *,float *)) user_func ; /*----------------------------------------------------------*/ /*----- Check inputs to see if they are reasonable-ish -----*/ if( ! ISVALID_3DIM_DATASET(old_dset) ) return NULL ; if( new_datum >= 0 && new_datum != MRI_byte && new_datum != MRI_short && new_datum != MRI_float ) return NULL ; if( user_func == NULL ) return NULL ; if( ignore < 0 ) ignore = 0 ; /*--------- set up pointers to each sub-brick in the input dataset ---------*/ old_datum = DSET_BRICK_TYPE( old_dset , 0 ) ; /* get old dataset datum */ nuse = DSET_NUM_TIMES(old_dset) - ignore ; /* # of points on time axis */ if( nuse < 2 ) return NULL ; if( new_datum < 0 ) new_datum = old_datum ; /* output datum = input */ if( new_datum == MRI_complex ) return NULL ; /* but complex = bad news */ DSET_load( old_dset ) ; /* must be in memory before we get pointers to it */ kk = THD_count_databricks( old_dset->dblk ) ; /* check if it was */ if( kk < DSET_NVALS(old_dset) ){ /* loaded correctly */ DSET_unload( old_dset ) ; return NULL ; } switch( old_datum ){ /* pointer type depends on input datum type */ default: /** don't know what to do **/ DSET_unload( old_dset ) ; return NULL ; /** create array of pointers into old dataset sub-bricks **/ /*--------- input is bytes ----------*/ /* voxel #i at time #k is bptr[k][i] */ /* for i=0..nvox-1 and k=0..nuse-1. */ case MRI_byte: bptr = (byte **) malloc( sizeof(byte *) * nuse ) ; if( bptr == NULL ) return NULL ; for( kk=0 ; kk < nuse ; kk++ ) bptr[kk] = (byte *) DSET_ARRAY(old_dset,kk+ignore) ; break ; /*--------- input is shorts ---------*/ /* voxel #i at time #k is sptr[k][i] */ /* for i=0..nvox-1 and k=0..nuse-1. */ case MRI_short: sptr = (short **) malloc( sizeof(short *) * nuse ) ; if( sptr == NULL ) return NULL ; for( kk=0 ; kk < nuse ; kk++ ) sptr[kk] = (short *) DSET_ARRAY(old_dset,kk+ignore) ; break ; /*--------- input is floats ---------*/ /* voxel #i at time #k is fptr[k][i] */ /* for i=0..nvox-1 and k=0..nuse-1. */ case MRI_float: fptr = (float **) malloc( sizeof(float *) * nuse ) ; if( fptr == NULL ) return NULL ; for( kk=0 ; kk < nuse ; kk++ ) fptr[kk] = (float *) DSET_ARRAY(old_dset,kk+ignore) ; break ; /*--------- input is complex ---------*/ /* voxel #i at time #k is cptr[k][i] */ /* for i=0..nvox-1 and k=0..nuse-1. */ case MRI_complex: cptr = (complex **) malloc( sizeof(complex *) * nuse ) ; if( cptr == NULL ) return NULL ; for( kk=0 ; kk < nuse ; kk++ ) cptr[kk] = (complex *) DSET_ARRAY(old_dset,kk+ignore) ; break ; } /* end of switch on input type */ /*---- allocate space for 1 voxel timeseries ----*/ fxar = (float *) malloc( sizeof(float) * nuse ) ; /* voxel timeseries */ if( fxar == NULL ){ FREE_WORKSPACE ; return NULL ; } /*--- get scaling factors for sub-bricks ---*/ fac = (float *) malloc( sizeof(float) * nuse ) ; /* factors */ if( fac == NULL ){ FREE_WORKSPACE ; return NULL ; } use_fac = 0 ; for( kk=0 ; kk < nuse ; kk++ ){ fac[kk] = DSET_BRICK_FACTOR(old_dset,kk+ignore) ; if( fac[kk] != 0.0 ) use_fac++ ; else fac[kk] = 1.0 ; } if( !use_fac ) FREEUP(fac) ; /*--- setup for detrending ---*/ dtr = (float *) malloc( sizeof(float) * nuse ) ; if( dtr == NULL ){ FREE_WORKSPACE ; return NULL ; } d0fac = 1.0 / nuse ; d1fac = 12.0 / nuse / (nuse*nuse - 1.0) ; for( kk=0 ; kk < nuse ; kk++ ) dtr[kk] = kk - 0.5 * (nuse-1) ; /* linear trend, orthogonal to 1 */ /*---------------------- make a new dataset ----------------------*/ new_dset = EDIT_empty_copy( old_dset ) ; /* start with copy of old one */ /*-- edit some of its internal parameters --*/ ii = EDIT_dset_items( new_dset , ADN_prefix , new_prefix , /* filename prefix */ ADN_malloc_type , DATABLOCK_MEM_MALLOC , /* store in memory */ ADN_datum_all , new_datum , /* atomic datum */ ADN_nvals , 1 , /* # sub-bricks */ ADN_ntt , 0 , /* # time points */ ADN_type , ISHEAD(old_dset) /* dataset type */ ? HEAD_FUNC_TYPE : GEN_FUNC_TYPE , ADN_func_type , FUNC_FIM_TYPE , /* function type */ ADN_none ) ; if( ii != 0 ){ ERROR_message("Error creating dataset '%s'",new_prefix) ; THD_delete_3dim_dataset( new_dset , False ) ; /* some error above */ FREE_WORKSPACE ; return NULL ; } /*------ make floating point output brick (only at the end will scale to byte or shorts) ------*/ nvox = old_dset->daxes->nxx * old_dset->daxes->nyy * old_dset->daxes->nzz ; fout = (float *) malloc( sizeof(float) * nvox ) ; /* ptr to brick */ if( fout == NULL ){ THD_delete_3dim_dataset( new_dset , False ) ; FREE_WORKSPACE ; return NULL ; } /*----- set up to find time at each voxel -----*/ tdelta = old_dset->taxis->ttdel ; if( DSET_TIMEUNITS(old_dset) == UNITS_MSEC_TYPE ) tdelta *= 0.001 ; if( tdelta == 0.0 ) tdelta = 1.0 ; izold = -666 ; nxy = old_dset->daxes->nxx * old_dset->daxes->nyy ; /*----------------------------------------------------*/ /*----- Setup has ended. Now do some real work. -----*/ /* start notification */ #if 0 user_func( 0.0 , 0.0 , nvox , NULL,0.0,0.0 , user_data , NULL ) ; #else ufunc( 0.0 , 0.0 , nvox , NULL,0.0,0.0 , user_data , NULL ) ; #endif /***** loop over voxels *****/ for( ii=0 ; ii < nvox ; ii++ ){ /* 1 time series at a time */ /*** load data from input dataset, depending on type ***/ switch( old_datum ){ /*** input = bytes ***/ case MRI_byte: for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = bptr[kk][ii] ; break ; /*** input = shorts ***/ case MRI_short: for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = sptr[kk][ii] ; break ; /*** input = floats ***/ case MRI_float: for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = fptr[kk][ii] ; break ; /*** input = complex (note we use absolute value) ***/ case MRI_complex: for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = CABS(cptr[kk][ii]) ; break ; } /* end of switch over input type */ /*** scale? ***/ if( use_fac ) for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] *= fac[kk] ; /** compute mean and slope **/ x0 = x1 = 0.0 ; for( kk=0 ; kk < nuse ; kk++ ){ x0 += fxar[kk] ; x1 += fxar[kk] * dtr[kk] ; } x0 *= d0fac ; x1 *= d1fac ; /* factors to remove mean and trend */ ts_mean = x0 ; ts_slope = x1 / tdelta ; /** detrend? **/ if( detrend ) for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] -= (x0 + x1 * dtr[kk]) ; /** compute start time of this timeseries **/ iz = ii / nxy ; /* which slice am I in? */ if( iz != izold ){ /* in a new slice? */ tzero = THD_timeof( ignore , old_dset->daxes->zzorg + iz*old_dset->daxes->zzdel , old_dset->taxis ) ; izold = iz ; if( DSET_TIMEUNITS(old_dset) == UNITS_MSEC_TYPE ) tzero *= 0.001 ; } /*** compute output ***/ #if 0 user_func( tzero,tdelta , nuse,fxar,ts_mean,ts_slope , user_data , fout+ii ) ; #else ufunc( tzero,tdelta , nuse,fxar,ts_mean,ts_slope , user_data , fout+ii ) ; #endif } /* end of outer loop over 1 voxels at a time */ DSET_unload( old_dset ) ; /* don't need this no more */ /* end notification */ #if 0 user_func( 0.0 , 0.0 , 0 , NULL,0.0,0.0 , user_data , NULL ) ; #else ufunc( 0.0 , 0.0 , 0 , NULL,0.0,0.0 , user_data , NULL ) ; #endif nbad = thd_floatscan( nvox , fout ) ; /* 08 Aug 2000 */ if( nbad > 0 ) fprintf(stderr, "++ Warning: %d bad floats computed in MAKER_4D_to_typed_fim\n\a", nbad ) ; /*------------------------------------------------------------*/ /*------- The output is now in fout[ii], ii=0..nvox-1. We must now put this into the output dataset -------*/ switch( new_datum ){ /*** output is floats is the simplest: we just have to attach the fout brick to the dataset ***/ case MRI_float: EDIT_substitute_brick( new_dset , 0 , MRI_float , fout ) ; fout = NULL ; /* so it won't be freed later */ break ; /*** output is shorts: we have to create a scaled sub-brick from fout ***/ case MRI_short:{ short * bout ; float sfac ; /*-- get output sub-brick --*/ bout = (short *) malloc( sizeof(short) * nvox ) ; if( bout == NULL ){ fprintf(stderr, "\nFinal malloc error in MAKER_4D_to_fim - is memory exhausted?\n\a"); EXIT(1) ; } /*-- find scaling and then scale --*/ sfac = MCW_vol_amax( nvox,1,1 , MRI_float , fout ) ; if( sfac > 0.0 ){ sfac = 32767.0 / sfac ; EDIT_coerce_scale_type( nvox,sfac , MRI_float,fout , MRI_short,bout ) ; sfac = 1.0 / sfac ; } /*-- put output brick into dataset, and store scale factor --*/ EDIT_substitute_brick( new_dset , 0 , MRI_short , bout ) ; EDIT_dset_items( new_dset , ADN_brick_fac , &sfac , ADN_none ) ; } break ; /*** output is bytes (byte = unsigned char) we have to create a scaled sub-brick from fout ***/ case MRI_byte:{ byte * bout ; float sfac ; /*-- get output sub-brick --*/ bout = (byte *) malloc( sizeof(byte) * nvox ) ; if( bout == NULL ){ fprintf(stderr, "\nFinal malloc error in MAKER_4D_to_fim - is memory exhausted?\n\a"); EXIT(1) ; } /*-- find scaling and then scale --*/ sfac = MCW_vol_amax( nvox,1,1 , MRI_float , fout ) ; if( sfac > 0.0 ){ sfac = 255.0 / sfac ; EDIT_coerce_scale_type( nvox,sfac , MRI_float,fout , MRI_byte,bout ) ; sfac = 1.0 / sfac ; } /*-- put output brick into dataset, and store scale factor --*/ EDIT_substitute_brick( new_dset , 0 , MRI_byte , bout ) ; EDIT_dset_items( new_dset , ADN_brick_fac , &sfac , ADN_none ) ; } break ; } /* end of switch on output data type */ /*-------------- Cleanup and go home ----------------*/ FREE_WORKSPACE ; return new_dset ; }
MRI_IMAGE * FD_brick_to_series( int ixyz , FD_brick *br ) { MRI_IMAGE *im ; /* output */ int nv , ival ; char *iar ; /* brick in the input */ MRI_TYPE typ ; int ix,jy,kz , ind ; THD_ivec3 ind_fd , ind_ds ; if( ixyz < 0 || ixyz >= br->n1 * br->n2 * br->n3 ) return NULL ; /** otherwise, get ready for a real image **/ ix = ixyz % br->n1 ; jy = ( ixyz % (br->n1 * br->n2) ) / br->n1 ; kz = ixyz / (br->n1 * br->n2) ; LOAD_IVEC3( ind_fd , ix,jy,kz ) ; ind_ds = THD_fdind_to_3dind( br , ind_fd ) ; ix = ind_ds.ijk[0] ; jy = ind_ds.ijk[1] ; kz = ind_ds.ijk[2] ; ind = (kz * br->dset->daxes->nyy + jy) * br->dset->daxes->nxx + ix ; nv = br->dset->dblk->nvals ; iar = DSET_ARRAY(br->dset,0) ; if( iar == NULL ){ /* if data needs to be loaded from disk */ (void) THD_load_datablock( br->dset->dblk ) ; iar = DSET_ARRAY(br->dset,0) ; if( iar == NULL ) return NULL ; } /* 15 Sep 2004: allow for nonconstant datum */ if( !DSET_datum_constant(br->dset) ){ /* only for stupid users */ float *ar ; im = mri_new( nv , 1 , MRI_float ) ; ar = MRI_FLOAT_PTR(im) ; for( ival = 0 ; ival < nv ; ival++ ) ar[ival] = THD_get_voxel( br->dset , ind , ival ) ; goto image_done ; } /* the older (more efficient) way */ typ = DSET_BRICK_TYPE(br->dset,0) ; im = mri_new( nv , 1 , typ ) ; #if 0 mri_zero_image(im) ; /* 18 Oct 2001 */ #endif switch( typ ){ default: /* don't know what to do --> return nada */ mri_free( im ) ; return NULL ; case MRI_byte:{ byte *ar = MRI_BYTE_PTR(im) , *bar ; for( ival=0 ; ival < nv ; ival++ ){ bar = (byte *) DSET_ARRAY(br->dset,ival) ; if( bar != NULL ) ar[ival] = bar[ind] ; } } break ; case MRI_short:{ short *ar = MRI_SHORT_PTR(im) , *bar ; for( ival=0 ; ival < nv ; ival++ ){ bar = (short *) DSET_ARRAY(br->dset,ival) ; if( bar != NULL ) ar[ival] = bar[ind] ; } } break ; case MRI_float:{ float *ar = MRI_FLOAT_PTR(im) , *bar ; for( ival=0 ; ival < nv ; ival++ ){ bar = (float *) DSET_ARRAY(br->dset,ival) ; if( bar != NULL ) ar[ival] = bar[ind] ; } } break ; case MRI_int:{ int *ar = MRI_INT_PTR(im) , *bar ; for( ival=0 ; ival < nv ; ival++ ){ bar = (int *) DSET_ARRAY(br->dset,ival) ; if( bar != NULL ) ar[ival] = bar[ind] ; } } break ; case MRI_double:{ double *ar = MRI_DOUBLE_PTR(im) , *bar ; for( ival=0 ; ival < nv ; ival++ ){ bar = (double *) DSET_ARRAY(br->dset,ival) ; if( bar != NULL ) ar[ival] = bar[ind] ; } } break ; case MRI_complex:{ complex *ar = MRI_COMPLEX_PTR(im) , *bar ; for( ival=0 ; ival < nv ; ival++ ){ bar = (complex *) DSET_ARRAY(br->dset,ival) ; if( bar != NULL ) ar[ival] = bar[ind] ; } } break ; /* 15 Apr 2002: RGB types */ case MRI_rgb:{ rgbyte *ar = (rgbyte *) MRI_RGB_PTR(im) , *bar ; for( ival=0 ; ival < nv ; ival++ ){ bar = (rgbyte *) DSET_ARRAY(br->dset,ival) ; if( bar != NULL ) ar[ival] = bar[ind] ; } } break ; case MRI_rgba:{ rgba *ar = (rgba *) MRI_RGBA_PTR(im) , *bar ; for( ival=0 ; ival < nv ; ival++ ){ bar = (rgba *) DSET_ARRAY(br->dset,ival) ; if( bar != NULL ) ar[ival] = bar[ind] ; } } break ; } if( THD_need_brick_factor(br->dset) ){ MRI_IMAGE *qim ; qim = mri_mult_to_float( br->dset->dblk->brick_fac , im ) ; mri_free(im) ; im = qim ; } /* at this point, the image is ready to ship out; but first, maybe attach a time origin and spacing */ image_done: if( br->dset->taxis != NULL ){ /* 21 Oct 1996 */ float zz , tt ; zz = br->dset->daxes->zzorg + kz * br->dset->daxes->zzdel ; tt = THD_timeof( 0 , zz , br->dset->taxis ) ; im->xo = tt ; im->dx = br->dset->taxis->ttdel ; /* origin and delta */ if( br->dset->taxis->units_type == UNITS_MSEC_TYPE ){ /* convert to sec */ im->xo *= 0.001 ; im->dx *= 0.001 ; } } else { im->xo = 0.0 ; im->dx = 1.0 ; /* 08 Nov 1996 */ } return im ; }
MRI_IMARR * THD_extract_many_series( int ns, int *ind, THD_3dim_dataset *dset ) { MRI_IMARR *imar ; /* output */ MRI_IMAGE *im ; int nv , ival , kk ; char *iar ; /* brick in the input */ float **far ; /* 27 Feb 2003: ptrs to output */ ENTRY("THD_extract_many_series") ; if( ns <= 0 || ind == NULL | dset == NULL ) RETURN( NULL ); /* try to load dataset */ nv = dset->dblk->nvals ; iar = DSET_ARRAY(dset,0) ; if( iar == NULL ){ /* if data needs to be loaded from disk */ (void) THD_load_datablock( dset->dblk ) ; iar = DSET_ARRAY(dset,0) ; if( iar == NULL ){ static int nerr=0 ; if( nerr < 2 ){ ERROR_message("Can't load dataset %s",DSET_HEADNAME(dset)); nerr++; } RETURN( NULL ); } } /* create output */ far = (float **) malloc(sizeof(float *)*ns) ; /* 27 Feb 2003 */ NULL_CHECK(far) ; INIT_IMARR(imar) ; for( kk=0 ; kk < ns ; kk++ ){ im = mri_new( nv , 1 , MRI_float ) ; /* N.B.: now does 0 fill */ far[kk] = MRI_FLOAT_PTR(im) ; /* ptr to kk-th output series */ ADDTO_IMARR(imar,im) ; } /* fill the output */ switch( DSET_BRICK_TYPE(dset,0) ){ default: /* don't know what to do --> return nada */ DESTROY_IMARR(imar) ; free(far) ; RETURN( NULL ); case MRI_byte:{ byte * bar ; for( ival=0 ; ival < nv ; ival++ ){ bar = (byte *) DSET_ARRAY(dset,ival) ; if( bar != NULL ){ for( kk=0 ; kk < ns ; kk++ ){ far[kk][ival] = (float)bar[ind[kk]] ; } } } } break ; case MRI_short:{ short * bar ; for( ival=0 ; ival < nv ; ival++ ){ bar = (short *) DSET_ARRAY(dset,ival) ; if( bar != NULL ){ for( kk=0 ; kk < ns ; kk++ ){ far[kk][ival] = (float)bar[ind[kk]] ; } } } } break ; case MRI_float:{ float * bar ; for( ival=0 ; ival < nv ; ival++ ){ bar = (float *) DSET_ARRAY(dset,ival) ; if( bar != NULL ){ for( kk=0 ; kk < ns ; kk++ ){ far[kk][ival] = bar[ind[kk]] ; } } } } break ; #if 0 case MRI_int:{ int * bar ; for( ival=0 ; ival < nv ; ival++ ){ bar = (int *) DSET_ARRAY(dset,ival) ; if( bar != NULL ){ for( kk=0 ; kk < ns ; kk++ ){ far[kk][ival] = bar[ind[kk]] ; } } } } break ; case MRI_double:{ double * bar ; for( ival=0 ; ival < nv ; ival++ ){ bar = (double *) DSET_ARRAY(dset,ival) ; if( bar != NULL ){ for( kk=0 ; kk < ns ; kk++ ){ far[kk][ival] = (float)bar[ind[kk]] ; } } } } break ; #endif case MRI_complex:{ complex * bar ; for( ival=0 ; ival < nv ; ival++ ){ bar = (complex *) DSET_ARRAY(dset,ival) ; if( bar != NULL ){ for( kk=0 ; kk < ns ; kk++ ){ far[kk][ival] = bar[ind[kk]].r ; } } } } break ; } /* scale outputs, if needed */ if( THD_need_brick_factor(dset) ){ MRI_IMAGE *qim ; for( kk=0 ; kk < ns ; kk++ ){ im = IMARR_SUBIMAGE(imar,kk) ; qim = mri_mult_to_float( dset->dblk->brick_fac , im ) ; mri_free(im) ; IMARR_SUBIMAGE(imar,kk) = qim ; } } #if 0 /* 27 Feb 2003 */ /* convert to floats, if needed */ if( IMARR_SUBIMAGE(imar,0)->kind != MRI_float ){ MRI_IMAGE * qim ; for( kk=0 ; kk < ns ; kk++ ){ im = IMARR_SUBIMAGE(imar,kk) ; qim = mri_to_float( im ) ; mri_free(im) ; IMARR_SUBIMAGE(imar,kk) = qim ; } } #endif /* add time axis stuff to output images, if present */ if( dset->taxis != NULL ){ float zz , tt ; int kz ; for( kk=0 ; kk < ns ; kk++ ){ kz = ind[kk] / ( dset->daxes->nxx * dset->daxes->nyy ) ; zz = dset->daxes->zzorg + kz * dset->daxes->zzdel ; tt = THD_timeof( 0 , zz , dset->taxis ) ; im = IMARR_SUBIMAGE(imar,kk) ; im->xo = tt ; im->dx = dset->taxis->ttdel ; /* origin and delta */ if( dset->taxis->units_type == UNITS_MSEC_TYPE ){ /* convert to sec */ im->xo *= 0.001 ; im->dx *= 0.001 ; } } } else { for( kk=0 ; kk < ns ; kk++ ){ im = IMARR_SUBIMAGE(imar,kk) ; im->xo = 0.0 ; im->dx = 1.0 ; } } free(far) ; RETURN(imar); }