#include "mrilib.h"
int main( int argc , char * argv[] )
{
THD_3dim_dataset *dset1,*dset2=NULL , *mset=NULL , *oset ;
MRI_IMAGE *dbr1,*dbr2;
float fac1, fac2;
char *prefix = "cmplx" ;
byte *mask=NULL ; float *rr,*gg ; complex *cmx ;
int iarg=1 , dofim=0 , ii,nvox , mode=0 ;
if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
printf("Usage #1: 3dTwotoComplex [options] dataset\n"
"Usage #2: 3dTwotoComplex [options] dataset1 dataset2\n"
"\n"
"Converts 2 sub-bricks of input to a complex-valued dataset.\n"
"* If you have 1 input dataset, then sub-bricks [0..1] are\n"
" used to form the 2 components of the output.\n"
"* If you have 2 input datasets, then the [0] sub-brick of\n"
" each is used to form the components.\n"
"* Complex datasets have two 32-bit float components per voxel.\n"
"\n"
"Options:\n"
" -prefix ppp = Write output into dataset with prefix 'ppp'.\n"
" [default='cmplx']\n"
" -RI = The 2 inputs are real and imaginary parts.\n"
" [this is the default]\n"
" -MP = The 2 inputs are magnitude and phase.\n"
" [phase is in radians, please!]\n"
" -mask mset = Only output nonzero values where the mask\n"
" dataset 'mset' is nonzero.\n"
"Notes:\n"
"* Input datasets must be byte-, short-, or float-valued.\n"
"* You might calculate the component datasets using 3dcalc.\n"
"* At present, there is limited support for complex datasets.\n"
" About the only thing you can do is display them in 2D\n"
" slice windows in AFNI.\n"
"\n"
"-- RWCox - March 2006\n"
) ;
exit(0) ;
}
mainENTRY("3dTwotoComplex main"); machdep();
AFNI_logger("3dTwotoComplex",argc,argv);
/*-- options --*/
#define GOOD_TYPE(tt) ((tt)==MRI_short || (tt)==MRI_byte || (tt)==MRI_float)
while( iarg < argc && argv[iarg][0] == '-' ){
if( strcmp(argv[iarg],"-prefix") == 0 ){
prefix = argv[++iarg] ;
if( !THD_filename_ok(prefix) )
ERROR_exit("-prefix %s is illegal!\n",prefix) ;
iarg++ ; continue ;
}
if( strcmp(argv[iarg],"-mask") == 0 ){
if( mset != NULL )
ERROR_exit("can't have 2 -mask options!\n");
mset = THD_open_dataset( argv[++iarg] ) ;
if( !ISVALID_DSET(mset) )
ERROR_exit("can't open -mset %s\n",argv[iarg]);
if( !GOOD_TYPE( DSET_BRICK_TYPE(mset,0) ) )
ERROR_exit("-mset %s has invalid data type\n",argv[iarg]);
DSET_load(mset) ; CHECK_LOAD_ERROR(mset) ;
iarg++ ; continue ;
}
if( strcmp(argv[iarg],"-RI") == 0 ){
mode = 0 ; iarg++ ; continue ;
}
if( strcmp(argv[iarg],"-MP") == 0 ){
mode = 1 ; iarg++ ; continue ;
}
ERROR_exit("ILLEGAL option: %s\n",argv[iarg]) ;
}
if( iarg >= argc )
ERROR_exit("No datasets on command line!?\n");
/*-- read input datasets --*/
#define OPENIT(ds,aa) \
do{ ds = THD_open_dataset(aa) ; \
if( !ISVALID_DSET(ds) ) ERROR_exit("Can't open dataset %s\n",aa); \
DSET_load(ds) ; CHECK_LOAD_ERROR(ds) ; \
} while(0)
if( iarg == argc-1 ){ /* one dataset */
OPENIT(dset1,argv[iarg]) ;
if( DSET_NVALS(dset1) < 2 )
ERROR_exit("Dataset %s needs at least 2 sub-bricks!\n",argv[iarg]);
if( !GOOD_TYPE( DSET_BRICK_TYPE(dset1,0) ) ||
!GOOD_TYPE( DSET_BRICK_TYPE(dset1,1) ) )
ERROR_exit("ILLEGAL dataset type in %s\n",argv[iarg]);
dbr1 = DSET_BRICK(dset1,0) ; fac1 = DSET_BRICK_FACTOR(dset1,0) ;
dbr2 = DSET_BRICK(dset1,1) ; fac2 = DSET_BRICK_FACTOR(dset1,1) ;
} else if( iarg+1 < argc ){ /* two datasets */
OPENIT(dset1,argv[iarg]) ;
if( !GOOD_TYPE( DSET_BRICK_TYPE(dset1,0) ) )
ERROR_exit("ILLEGAL dataset type in %s\n",argv[iarg]) ;
OPENIT(dset2,argv[iarg+1]) ;
if( !GOOD_TYPE( DSET_BRICK_TYPE(dset2,0) ) )
ERROR_exit("ILLEGAL dataset type in %s\n",argv[iarg+1]);
dbr1 = DSET_BRICK(dset1,0) ; fac1 = DSET_BRICK_FACTOR(dset1,0) ;
dbr2 = DSET_BRICK(dset2,0) ; fac2 = DSET_BRICK_FACTOR(dset2,0) ;
if( dbr1->nx != dbr2->nx ) ERROR_exit("Dataset x-axes don't match!\n") ;
if( dbr1->ny != dbr2->ny ) ERROR_exit("Dataset y-axes don't match!\n") ;
if( dbr1->nz != dbr2->nz ) ERROR_exit("Dataset z-axes don't match!\n") ;
if( iarg+1 < argc-1 )
WARNING_message("extra arguments on command line: %s ...\n",
argv[iarg+2] ) ;
} else { /* this is bad */
ERROR_exit("Need either 1 or 2 datasets on command line!?\n");
}
/* make a mask, if any */
if( mset != NULL ){
if( dbr1->nx != DSET_NX(mset) )
ERROR_exit("Mask and dataset x-axes don't match!\n");
if( dbr1->ny != DSET_NY(mset) )
ERROR_exit("Mask and dataset y-axes don't match!\n");
if( dbr1->nz != DSET_NZ(mset) )
ERROR_exit("Mask and dataset z-axes don't match!\n");
mask = THD_makemask( mset , 0 , 1.0,0.0 ) ;
if( mask == NULL )
ERROR_exit("Can't make mask!\n");
DSET_unload(mset) ;
}
/* convert input sub-bricks to floats */
nvox = dbr1->nvox ;
rr = (float *) calloc(sizeof(float),nvox) ;
if( fac1 == 0.0 ) fac1 = 1.0 ;
EDIT_coerce_scale_type( nvox , fac1 ,
dbr1->kind , mri_data_pointer(dbr1) ,
MRI_float , rr ) ;
DSET_unload(dset1) ;
gg = (float *) calloc(sizeof(float),nvox) ;
if( fac2 == 0.0 ) fac2 = 1.0 ;
EDIT_coerce_scale_type( nvox , fac2 ,
dbr2->kind , mri_data_pointer(dbr2) ,
MRI_float , gg ) ;
if( dset2 != NULL ) DSET_unload(dset2) ;
/* merge inputs to output */
cmx = (complex *) calloc(sizeof(complex),nvox) ;
#define T2C(a,b) \
(mode==0) ? CMPLX((a),(b)) : CMPLX((a)*cos(b),(a)*sin(b))
if( mask != NULL ){
for( ii=0 ; ii < nvox ; ii++ )
if( mask[ii] ) cmx[ii] = T2C(rr[ii],gg[ii]) ;
} else {
for( ii=0 ; ii < nvox ; ii++ )
cmx[ii] = T2C(rr[ii],gg[ii]) ;
}
free(mask) ; free(rr) ; free(gg) ;
/* make output dataset */
oset = EDIT_empty_copy( dset1 ) ;
EDIT_dset_items( oset ,
ADN_prefix , prefix ,
ADN_datum_all, MRI_complex ,
ADN_nvals , 1 ,
ADN_ntt , 0 ,
ADN_type , (dofim) ? HEAD_FUNC_TYPE : HEAD_ANAT_TYPE,
ADN_func_type, (dofim) ? FUNC_FIM_TYPE : ANAT_SPGR_TYPE,
ADN_none ) ;
EDIT_substitute_brick( oset , 0 , MRI_complex , cmx ) ;
/* make history */
tross_Copy_History( oset , dset1 ) ;
tross_Make_History( "3dTwotoComplex", argc,argv, oset ) ;
DSET_write( oset ) ;
WROTE_DSET( oset ) ;
exit(0) ;
}
syntax highlighted by Code2HTML, v. 0.9.1