Ejemplo n.º 1
0
MRI_IMAGE * mri_bport( float dt, float fbot, float ftop, int nblock, int *ntim )
{
   MRI_IMAGE *tim ; MRI_IMARR *bimar ;
   int nrow , nbef , naft , tt ;

ENTRY("mri_bport") ;

   if( nblock <= 0 || ntim == NULL ) RETURN(NULL) ;
   if( nblock == 1 ){
     tim = mri_bport_contig( dt,fbot,ftop , ntim[0],0,0 ) ;
     RETURN(tim) ;
   }

   for( nrow=tt=0 ; tt < nblock ; tt++ ){
     if( ntim[tt] < 9 ) RETURN(NULL) ;
     nrow += ntim[tt] ;
   }
   INIT_IMARR(bimar) ;

   nbef = 0 ;
   naft = nrow - ntim[0] ;
   for( tt=0 ; tt < nblock ; tt++ ){
     tim = mri_bport_contig( dt,fbot,ftop , ntim[tt],nbef,naft ) ;
     if( tim == NULL ){
       DESTROY_IMARR(bimar) ; RETURN(NULL) ;
     }
     ADDTO_IMARR(bimar,tim) ;
     if( tt < nblock-1 ){ nbef += ntim[tt]; naft -= ntim[tt+1]; }
   }

   tim = mri_catvol_1D( bimar , 2 ) ;
   DESTROY_IMARR(bimar) ;
   RETURN(tim) ;
}
Ejemplo n.º 2
0
THD_3dim_dataset * THD_detrend_dataset( THD_3dim_dataset *dset ,
                                        int nref , float **ref ,
                                        int meth , int scl ,
                                        byte *mask , MRI_IMARR **imar )
{
   MRI_IMARR *qmar ;
   int ii,jj,kk , nvals,nvox , iv ;
   float *var ;
   THD_3dim_dataset *newset ;

ENTRY("THD_detrend_dataset") ;

   if( !ISVALID_DSET(dset) ) RETURN(NULL) ;
   nvals = DSET_NVALS(dset) ; nvox = DSET_NVOX(dset) ;

   qmar = THD_time_fit_dataset( dset , nref,ref , meth , mask ) ;
   if( qmar == NULL ) RETURN(NULL) ;

   newset = EDIT_empty_copy(dset) ;
   for( iv=0 ; iv < nvals ; iv++ ){
     EDIT_substitute_brick( newset , iv , MRI_float , NULL ) ;
     EDIT_BRICK_FACTOR( newset , iv , 0.0f ) ;  /* 04 Jun 2007 */
   }

   var = (float *)malloc(sizeof(float)*nvals) ;
   for( ii=0 ; ii < nvox ; ii++ ){
     if( mask == NULL || mask[ii] )
       THD_extract_detrended_array( dset , nref,ref , qmar , ii,scl , var ) ;
     else
       memset(var,0,sizeof(float)*nvals) ;
     THD_insert_series( ii , newset , nvals , MRI_float , var , 0 ) ;
   }

   free(var) ;
   if( imar != NULL ) *imar = qmar ;
   else               DESTROY_IMARR(qmar) ;

   RETURN(newset) ;
}
Ejemplo n.º 3
0
int main( int argc , char *argv[] )
{
   THD_3dim_dataset *inset=NULL , *outset=NULL ;
   MCW_cluster *nbhd=NULL ;
   byte *mask=NULL ; int mask_nx,mask_ny,mask_nz , automask=0 ;
   char *prefix="./LocalCormat" ;
   int iarg=1 , verb=1 , ntype=0 , kk,nx,ny,nz,nxy,nxyz,nt , xx,yy,zz, vstep ;
   float na,nb,nc , dx,dy,dz ;
   MRI_IMARR *imar=NULL ; MRI_IMAGE *pim=NULL ;
   int mmlag=10 , ii,jj , do_arma=0 , nvout ;
   MRI_IMAGE *concim=NULL ; float *concar=NULL ;

   if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
     printf(
       "Usage: 3dLocalCORMAT [options] inputdataset\n"
       "\n"
       "Compute the correlation matrix (in time) of the input dataset,\n"
       "up to lag given by -maxlag.  The matrix is averaged over the\n"
       "neighborhood specified by the -nbhd option, and then the entries\n"
       "are output at each voxel in a new dataset.\n"
       "\n"
       "Normally, the input to this program would be the -errts output\n"
       "from 3dDeconvolve, or the equivalent residuals from some other\n"
       "analysis.  If you input a non-residual time series file, you at\n"
       "least should use an appropriate -polort level for detrending!\n"
       "\n"
       "Options:\n"
       "  -input inputdataset\n"
       "  -prefix ppp\n"
       "  -mask mset    {these 2 options are}\n"
       "  -automask     {mutually exclusive.}\n"
       "  -nbhd nnn     [e.g., 'SPHERE(9)' for 9 mm radius]\n"
       "  -polort ppp   [default = 0, which is reasonable for -errts output]\n"
       "  -concat ccc   [as in 3dDeconvolve]\n"
       "  -maxlag mmm   [default = 10]\n"
       "  -ARMA         [estimate ARMA(1,1) parameters into last 2 sub-bricks]\n"
       "\n"
       "A quick hack for my own benignant purposes -- RWCox -- June 2008\n"
     ) ;
     PRINT_COMPILE_DATE ; exit(0) ;
   }

   /*---- official startup ---*/

   PRINT_VERSION("3dLocalCormat"); mainENTRY("3dLocalCormat main"); machdep();
   AFNI_logger("3dLocalCormat",argc,argv); AUTHOR("Zhark the Toeplitzer");

   /*---- loop over options ----*/

   while( iarg < argc && argv[iarg][0] == '-' ){

#if 0
fprintf(stderr,"argv[%d] = %s\n",iarg,argv[iarg]) ;
#endif

     if( strcmp(argv[iarg],"-ARMA") == 0 ){
       do_arma = 1 ; iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-polort") == 0 ){
       char *cpt ;
       if( ++iarg >= argc )
         ERROR_exit("Need argument after option %s",argv[iarg-1]) ;
       pport = (int)strtod(argv[iarg],&cpt) ;
       if( *cpt != '\0' )
         WARNING_message("Illegal non-numeric value after -polort") ;
       if( pport > 3 ){
         pport = 3 ; WARNING_message("-polort set to 3 == max implemented") ;
       } else if( pport < 0 ){
         pport = 0 ; WARNING_message("-polort set to 0 == min implemented") ;
       }
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-input") == 0 ){
       if( inset != NULL  ) ERROR_exit("Can't have two -input options") ;
       if( ++iarg >= argc ) ERROR_exit("Need argument after '-input'") ;
       inset = THD_open_dataset( argv[iarg] ) ;
       CHECK_OPEN_ERROR(inset,argv[iarg]) ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-prefix") == 0 ){
       if( ++iarg >= argc ) ERROR_exit("Need argument after '-prefix'") ;
       prefix = strdup(argv[iarg]) ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-mask") == 0 ){
       THD_3dim_dataset *mset ; int mmm ;
       if( ++iarg >= argc ) ERROR_exit("Need argument after '-mask'") ;
       if( mask != NULL || automask ) ERROR_exit("Can't have two mask inputs") ;
       mset = THD_open_dataset( argv[iarg] ) ;
       CHECK_OPEN_ERROR(mset,argv[iarg]) ;
       DSET_load(mset) ; CHECK_LOAD_ERROR(mset) ;
       mask_nx = DSET_NX(mset); mask_ny = DSET_NY(mset); mask_nz = DSET_NZ(mset);
       mask = THD_makemask( mset , 0 , 0.5f, 0.0f ) ; DSET_delete(mset) ;
       if( mask == NULL ) ERROR_exit("Can't make mask from dataset '%s'",argv[iarg]) ;
       mmm = THD_countmask( mask_nx*mask_ny*mask_nz , mask ) ;
       INFO_message("Number of voxels in mask = %d",mmm) ;
       if( mmm < 2 ) ERROR_exit("Mask is too small to process") ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-automask") == 0 ){
       if( mask != NULL ) ERROR_exit("Can't have -automask and -mask") ;
       automask = 1 ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-nbhd") == 0 ){
       char *cpt ;
       if( ntype  >  0    ) ERROR_exit("Can't have 2 '-nbhd' options") ;
       if( ++iarg >= argc ) ERROR_exit("Need argument after '-nbhd'") ;

       cpt = argv[iarg] ;
       if( strncasecmp(cpt,"SPHERE",6) == 0 ){
         sscanf( cpt+7 , "%f" , &na ) ;
         if( na == 0.0f ) ERROR_exit("Can't have a SPHERE of radius 0") ;
         ntype = NTYPE_SPHERE ;
       } else if( strncasecmp(cpt,"RECT",4) == 0 ){
         sscanf( cpt+5 , "%f,%f,%f" , &na,&nb,&nc ) ;
         if( na == 0.0f && nb == 0.0f && nc == 0.0f )
           ERROR_exit("'RECT(0,0,0)' is not a legal neighborhood") ;
         ntype = NTYPE_RECT ;
       } else if( strncasecmp(cpt,"RHDD",4) == 0 ){
         sscanf( cpt+5 , "%f" , &na ) ;
         if( na == 0.0f ) ERROR_exit("Can't have a RHDD of radius 0") ;
         ntype = NTYPE_RHDD ;
       } else {
          ERROR_exit("Unknown -nbhd shape: '%s'",cpt) ;
       }
       iarg++ ; continue ;
     }
       
     if( strcmp(argv[iarg],"-maxlag") == 0 ){
       if( ++iarg >= argc )
         ERROR_exit("Need argument after option %s",argv[iarg-1]) ;
       mmlag = (int)strtod(argv[iarg],NULL) ;
       iarg++ ; continue ;
     }   

     if( strcmp(argv[iarg],"-concat") == 0 ){
       if( concim != NULL )
         ERROR_exit("Can't have two %s options!",argv[iarg]) ;
       if( ++iarg >= argc )
         ERROR_exit("Need argument after option %s",argv[iarg-1]) ;
       concim = mri_read_1D( argv[iarg] ) ;
       if( concim == NULL )
         ERROR_exit("Can't read -concat file '%s'",argv[iarg]) ;
       if( concim->nx < 2 )
         ERROR_exit("-concat file '%s' must have at least 2 entries!",
                    argv[iarg]) ;
       concar = MRI_FLOAT_PTR(concim) ;
       for( ii=1 ; ii < concim->nx ; ii++ )
         if( (int)concar[ii-1] >= (int)concar[ii] )
           ERROR_exit("-concat file '%s' is not ordered increasingly!",
                      argv[iarg]) ;
       iarg++ ; continue ;
     }

     ERROR_exit("Unknown option '%s'",argv[iarg]) ;

   } /*--- end of loop over options ---*/

   if( do_arma && mmlag > 0 && mmlag < 5 )
     ERROR_exit("Can't do -ARMA with -maxlag %d",mmlag) ;

   /*---- deal with input dataset ----*/

   if( inset == NULL ){
     if( iarg >= argc ) ERROR_exit("No input dataset on command line?") ;
     inset = THD_open_dataset( argv[iarg] ) ;
     CHECK_OPEN_ERROR(inset,argv[iarg]) ;
   }
   ntime = DSET_NVALS(inset) ;
   if( ntime < 9 )
     ERROR_exit("Must have at least 9 values per voxel") ;

   DSET_load(inset) ; CHECK_LOAD_ERROR(inset) ;

   if( mask != NULL ){
     if( mask_nx != DSET_NX(inset) ||
         mask_ny != DSET_NY(inset) ||
         mask_nz != DSET_NZ(inset)   )
       ERROR_exit("-mask dataset grid doesn't match input dataset") ;

   } else if( automask ){
     int mmm ;
     mask = THD_automask( inset ) ;
     if( mask == NULL )
       ERROR_message("Can't create -automask from input dataset?") ;
     mmm = THD_countmask( DSET_NVOX(inset) , mask ) ;
     INFO_message("Number of voxels in automask = %d",mmm) ;
     if( mmm < 2 ) ERROR_exit("Automask is too small to process") ;
   }

   /*-- set up blocks of continuous time data --*/
       
   if( DSET_IS_TCAT(inset) ){
     if( concim != NULL ){
       WARNING_message("Ignoring -concat, since dataset is auto-catenated") ;
       mri_free(concim) ;
     }
     concim = mri_new(inset->tcat_num,1,MRI_float) ;
     concar = MRI_FLOAT_PTR(concim) ;
     concar[0] = 0.0 ;
     for( ii=0 ; ii < inset->tcat_num-1 ; ii++ )
       concar[ii+1] = concar[ii] + inset->tcat_len[ii] ;
   } else if( concim == NULL ){ 
     concim = mri_new(1,1,MRI_float) ;
     concar = MRI_FLOAT_PTR(concim)  ; concar[0] = 0 ;
   }
   nbk = concim->nx ;
   bk  = (int *)malloc(sizeof(int)*(nbk+1)) ;
   for( ii=0 ; ii < nbk ; ii++ ) bk[ii] = (int)concar[ii] ;
   bk[nbk] = ntime ;
   mri_free(concim) ;
   mlag = DSET_NVALS(inset) ;
   for( ii=0 ; ii < nbk ; ii++ ){
     jj = bk[ii+1]-bk[ii] ; if( jj < mlag ) mlag = jj ;
     if( bk[ii] < 0 || jj < 9 )
       ERROR_exit("something is rotten in the dataset run lengths") ;
   }
   mlag-- ;
   if( mmlag > 0 && mlag > mmlag ) mlag = mmlag ;
   else                            INFO_message("Max lag set to %d",mlag) ;

   if( do_arma && mlag < 5 )
     ERROR_exit("Can't do -ARMA with maxlag=%d",mlag) ;

   /*---- create neighborhood (as a cluster) -----*/

   if( ntype <= 0 ){         /* default neighborhood */
     ntype = NTYPE_SPHERE ; na = -1.01f ;
     INFO_message("Using default neighborhood = self + 6 neighbors") ;
   }

   switch( ntype ){
     default:
       ERROR_exit("WTF?  ntype=%d",ntype) ;

     case NTYPE_SPHERE:{
       if( na < 0.0f ){ dx = dy = dz = 1.0f ; na = -na ; }
       else           { dx = fabsf(DSET_DX(inset)) ;
                        dy = fabsf(DSET_DY(inset)) ;
                        dz = fabsf(DSET_DZ(inset)) ; }
       nbhd = MCW_spheremask( dx,dy,dz , na ) ;
     }
     break ;

     case NTYPE_RECT:{
       if( na < 0.0f ){ dx = 1.0f; na = -na; } else dx = fabsf(DSET_DX(inset));
       if( nb < 0.0f ){ dy = 1.0f; nb = -nb; } else dy = fabsf(DSET_DY(inset));
       if( nc < 0.0f ){ dz = 1.0f; nc = -nc; } else dz = fabsf(DSET_DZ(inset));
       nbhd = MCW_rectmask( dx,dy,dz , na,nb,nc ) ;
     }
     break ;

     case NTYPE_RHDD:{
       if( na < 0.0f ){ dx = dy = dz = 1.0f ; na = -na ; }
       else           { dx = fabsf(DSET_DX(inset)) ;
                        dy = fabsf(DSET_DY(inset)) ;
                        dz = fabsf(DSET_DZ(inset)) ; }
       nbhd = MCW_rhddmask( dx,dy,dz , na ) ;
     }
     break ;
   }
   MCW_radsort_cluster( nbhd , dx,dy,dz ) ;  /* 26 Feb 2008 */

   INFO_message("Neighborhood comprises %d voxels",nbhd->num_pt) ;

   /** create output dataset **/

   outset = EDIT_empty_copy(inset) ;
   nvout  = mlag ; if( do_arma ) nvout += 2 ;
   EDIT_dset_items( outset,
                      ADN_prefix   , prefix,
                      ADN_brick_fac, NULL  ,
                      ADN_nvals    , nvout ,
                      ADN_ntt      , nvout ,
                    ADN_none );
   tross_Copy_History( inset , outset ) ;
   tross_Make_History( "3dLocalCormat" , argc,argv , outset ) ;
   for( kk=0 ; kk < nvout ; kk++ )
     EDIT_substitute_brick( outset , kk , MRI_float , NULL ) ;

   nx = DSET_NX(outset) ;
   ny = DSET_NY(outset) ; nxy  = nx*ny  ;
   nz = DSET_NZ(outset) ; nxyz = nxy*nz ;
   vstep = (verb && nxyz > 999) ? nxyz/50 : 0 ;
   if( vstep ) fprintf(stderr,"++ voxel loop: ") ;

   /** actually do the long long slog through all voxels **/

   for( kk=0 ; kk < nxyz ; kk++ ){
     if( vstep && kk%vstep==vstep-1 ) vstep_print() ;
     if( !INMASK(kk) ) continue ;
     IJK_TO_THREE( kk , xx,yy,zz , nx,nxy ) ;
     imar = THD_get_dset_nbhd_array( inset , mask , xx,yy,zz , nbhd ) ;
     if( imar == NULL ) continue ;
     pim = mri_cormat_vector(imar) ; DESTROY_IMARR(imar) ;
     if( pim == NULL ) continue ;
     THD_insert_series( kk, outset, pim->nx, MRI_float, MRI_FLOAT_PTR(pim), 0 ) ;

     if( do_arma ){  /* estimate ARMA(1,1) params and store those, too */
       float_pair ab ;
       float *aa=DSET_ARRAY(outset,mlag), *bb=DSET_ARRAY(outset,mlag+1) ;
       ab = estimate_arma11( pim->nx , MRI_FLOAT_PTR(pim) ) ;
       aa[kk] = ab.a ; bb[kk] = ab.b ;
     }

     mri_free(pim) ;
   }
   if( vstep ) fprintf(stderr,"\n") ;

   DSET_delete(inset) ;
   DSET_write(outset) ;
   WROTE_DSET(outset) ;

   exit(0) ;
}
Ejemplo n.º 4
0
int main( int argc , char *argv[] )
{
   THD_3dim_dataset *inset=NULL ;
   byte *mask=NULL ; int mask_nx=0,mask_ny=0,mask_nz=0 , automask=0 , masknum=0 ;
   int iarg=1 , verb=1 , ntype=0 , nev,kk,ii,nxyz,nt ;
   float na,nb,nc , dx,dy,dz ;
   MRI_IMARR *imar=NULL ; int *ivox ; MRI_IMAGE *pim ;
   int do_vmean=0 , do_vnorm=0 , sval_itop=0 ;
   int polort=-1 ; float *ev ;
   MRI_IMARR *ortar ; MRI_IMAGE *ortim ; int nyort=0 ;
   float bpass_L=0.0f , bpass_H=0.0f , dtime ; int do_bpass=0 ;

   if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
     printf(
       "Usage:  3dmaskSVD [options] inputdataset\n"
       "Author: Zhark the Gloriously Singular\n"
       "\n"
       "* Computes the principal singular vector of the time series\n"
       "    vectors extracted from the input dataset over the input mask.\n"
       "  ++ You can use the '-sval' option to change which singular\n"
       "     vectors are output.\n"
       "* The sign of the output vector is chosen so that the average\n"
       "    of arctanh(correlation coefficient) over all input data\n"
       "    vectors (from the mask) is positive.\n"
       "* The output vector is normalized: the sum of its components\n"
       "    squared is 1.\n"
       "* You probably want to use 3dDetrend (or something similar) first,\n"
       "    to get rid of annoying artifacts, such as motion, breathing,\n"
       "    dark matter interactions with the brain, etc.\n"
       "  ++ If you are lazy scum like Zhark, you might be able to get\n"
       "     away with using the '-polort' option.\n"
       "  ++ In particular, if your data time series has a nonzero mean,\n"
       "     then you probably want at least '-polort 0' to remove the\n"
       "     mean, otherwise you'll pretty much just get a constant\n"
       "     time series as the principal singular vector!\n"
       "* An alternative to this program would be 3dmaskdump followed\n"
       "    by 1dsvd, which could give you all the singular vectors you\n"
       "    could ever want, and much more -- enough to confuse you for days.\n"
       "  ++ In particular, although you COULD input a 1D file into\n"
       "     3dmaskSVD, the 1dsvd program would make much more sense.\n"
       "* This program will be pretty slow if there are over about 2000\n"
       "    voxels in the mask.  It could be made more efficient for\n"
       "    such cases, but you'll have to give Zhark some 'incentive'.\n"
       "* Result vector goes to stdout.  Redirect per your pleasures and needs.\n"
       "* Also see program 3dLocalSVD if you want to compute the principal\n"
       "    singular time series vector from a neighborhood of EACH voxel.\n"
       "  ++ (Which is a pretty slow operation!)\n"
       "* http://en.wikipedia.org/wiki/Singular_value_decomposition\n"
       "\n"
       "-------\n"
       "Options:\n"
       "-------\n"
       " -vnorm      = L2 normalize all time series before SVD [recommended!]\n"
       " -sval a     = output singular vectors 0 .. a [default a=0 = first one only]\n"
       " -mask mset  = define the mask [default is entire dataset == slow!]\n"
       " -automask   = you'll have to guess what this option does\n"
       " -polort p   = if you are lazy and didn't run 3dDetrend (like Zhark)\n"
       " -bpass L H  = bandpass [mutually exclusive with -polort]\n"
       " -ort xx.1D  = time series to remove from the data before SVD-ization\n"
       "               ++ You can give more than 1 '-ort' option\n"
       "               ++ 'xx.1D' can contain more than 1 column\n"
       " -input ddd  = alternative way to give the input dataset name\n"
       "\n"
       "-------\n"
       "Example:\n"
       "-------\n"
       " You have a mask dataset with discrete values 1, 2, ... 77 indicating\n"
       " some ROIs; you want to get the SVD from each ROI's time series separately,\n"
       " and then put these into 1 big 77 column .1D file.  You can do this using\n"
       " a csh shell script like the one below:\n"
       "\n"
       " # Compute the individual SVD vectors\n"
       " foreach mm ( `count 1 77` )\n"
       "   3dmaskSVD -vnorm -mask mymask+orig\"<${mm}..${mm}>\" epi+orig > qvec${mm}.1D\n"
       " end\n"
       " # Glue them together into 1 big file, then delete the individual files\n"
       " 1dcat qvec*.1D > allvec.1D\n"
       " /bin/rm -f qvec*.1D\n"
       " # Plot the results to a JPEG file, then compute their correlation matrix\n"
       " 1dplot -one -nopush -jpg allvec.jpg allvec.1D\n"
       " 1ddot -terse allvec.1D > allvec_COR.1D\n"
       "\n"
       " [[ If you use the bash shell,  you'll have to figure out the syntax ]]\n"
       " [[ yourself. Zhark has no sympathy for you bash shell infidels, and ]]\n"
       " [[ considers you only slightly better than those lowly Emacs users. ]]\n"
       " [[ And do NOT ever even mention 'nedit' in Zhark's august presence! ]]\n"
     ) ;
     PRINT_COMPILE_DATE ; exit(0) ;
   }

   /*---- official startup ---*/

   PRINT_VERSION("3dmaskSVD"); mainENTRY("3dmaskSVD main"); machdep();
   AFNI_logger("3dmaskSVD",argc,argv); AUTHOR("Zhark the Singular");

   /*---- loop over options ----*/

   INIT_IMARR(ortar) ;

   mpv_sign_meth = AFNI_yesenv("AFNI_3dmaskSVD_meansign") ;

   while( iarg < argc && argv[iarg][0] == '-' ){

     if( strcasecmp(argv[iarg],"-bpass") == 0 ){
       if( iarg+2 >= argc ) ERROR_exit("need 2 args after -bpass") ;
       bpass_L = (float)strtod(argv[++iarg],NULL) ;
       bpass_H = (float)strtod(argv[++iarg],NULL) ;
       if( bpass_L < 0.0f || bpass_H <= bpass_L )
         ERROR_exit("Illegal values after -bpass: %g %g",bpass_L,bpass_H) ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-ort") == 0 ){  /* 01 Oct 2009 */
       int nx,ny ;
       if( ++iarg >= argc ) ERROR_exit("Need argument after '-ort'") ;
       ortim = mri_read_1D( argv[iarg] ) ;
       if( ortim == NULL ) ERROR_exit("-ort '%s': Can't read 1D file",argv[iarg]) ;
       nx = ortim->nx ; ny = ortim->ny ;
       if( nx == 1 && ny > 1 ){
         MRI_IMAGE *tim=mri_transpose(ortim); mri_free(ortim); ortim = tim; ny = 1;
       }
       mri_add_name(argv[iarg],ortim) ; ADDTO_IMARR(ortar,ortim) ; nyort += ny ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-polort") == 0 ){
       char *qpt ;
       if( ++iarg >= argc ) ERROR_exit("Need argument after '-polort'") ;
       polort = (int)strtod(argv[iarg],&qpt) ;
       if( *qpt != '\0' ) WARNING_message("Illegal non-numeric value after -polort") ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-vnorm") == 0 ){
       do_vnorm = 1 ; iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-input") == 0 ){
       if( inset != NULL  ) ERROR_exit("Can't have two -input options") ;
       if( ++iarg >= argc ) ERROR_exit("Need argument after '-input'") ;
       inset = THD_open_dataset( argv[iarg] ) ;
       CHECK_OPEN_ERROR(inset,argv[iarg]) ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-sval") == 0 ){
       if( ++iarg >= argc ) ERROR_exit("Need argument after '-sval'") ;
       sval_itop = (int)strtod(argv[iarg],NULL) ;
       if( sval_itop < 0 ){ sval_itop = 0 ; WARNING_message("'-sval' reset to 0") ; }
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-mask") == 0 ){
       THD_3dim_dataset *mset ; int mmm ;
       if( ++iarg >= argc ) ERROR_exit("Need argument after '-mask'") ;
       if( mask != NULL || automask ) ERROR_exit("Can't have two mask inputs") ;
       mset = THD_open_dataset( argv[iarg] ) ;
       CHECK_OPEN_ERROR(mset,argv[iarg]) ;
       DSET_load(mset) ; CHECK_LOAD_ERROR(mset) ;
       mask_nx = DSET_NX(mset); mask_ny = DSET_NY(mset); mask_nz = DSET_NZ(mset);
       mask = THD_makemask( mset , 0 , 0.5f, 0.0f ) ; DSET_delete(mset) ;
       if( mask == NULL ) ERROR_exit("Can't make mask from dataset '%s'",argv[iarg]) ;
       masknum = mmm = THD_countmask( mask_nx*mask_ny*mask_nz , mask ) ;
       INFO_message("Number of voxels in mask = %d",mmm) ;
       if( mmm < 2 ) ERROR_exit("Mask is too small to process") ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-automask") == 0 ){
       if( mask != NULL ) ERROR_exit("Can't have two mask inputs!") ;
       automask = 1 ; iarg++ ; continue ;
     }

     ERROR_exit("Unknown option '%s'",argv[iarg]) ;

   } /*--- end of loop over options ---*/

   /*---- deal with input dataset ----*/

   if( inset == NULL ){
     if( iarg >= argc ) ERROR_exit("No input dataset on command line?") ;
     inset = THD_open_dataset( argv[iarg] ) ;
     CHECK_OPEN_ERROR(inset,argv[iarg]) ;
   }
   nt = DSET_NVALS(inset) ;  /* vector lengths */
   if( nt < 9 )
     ERROR_exit("Must have at least 9 values per voxel") ;
   if( polort+1 >= nt )
     ERROR_exit("'-polort %d' too big for time series length = %d",polort,nt) ;

   DSET_load(inset) ; CHECK_LOAD_ERROR(inset) ;
   nxyz = DSET_NVOX(inset) ;

   DSET_UNMSEC(inset) ;
   dtime = DSET_TR(inset) ;
   if( dtime <= 0.0f ) dtime = 1.0f ;
   do_bpass = (bpass_L < bpass_H) ;
   if( do_bpass ){
     kk = THD_bandpass_OK( nt , dtime , bpass_L , bpass_H , 1 ) ;
     if( kk <= 0 ) ERROR_exit("Can't continue since -bpass setup is illegal") ;
     polort = -1 ;
   }

   /*--- deal with the masking ---*/

   if( mask != NULL ){
     if( mask_nx != DSET_NX(inset) ||
         mask_ny != DSET_NY(inset) ||
         mask_nz != DSET_NZ(inset)   )
       ERROR_exit("-mask dataset grid doesn't match input dataset") ;

   } else if( automask ){
     int mmm ;
     mask = THD_automask( inset ) ;
     if( mask == NULL )
       ERROR_message("Can't create -automask from input dataset?") ;
     masknum = mmm = THD_countmask( DSET_NVOX(inset) , mask ) ;
     INFO_message("Number of voxels in automask = %d",mmm) ;
     if( mmm < 9 ) ERROR_exit("Automask is too small to process") ;
   } else {
     mask = (byte *)malloc(sizeof(byte)*nxyz) ; masknum = nxyz ;
     memset( mask , 1 , sizeof(byte)*nxyz ) ;
     INFO_message("Using all %d voxels in dataset",nxyz) ;
   }

   nev = MIN(nt,masknum) ;  /* max possible number of eigenvalues */
   if( sval_itop >= nev ){
     sval_itop = nev-1 ;
     WARNING_message("'-sval' reset to '%d'",sval_itop) ;
   }
   mri_principal_vector_params( 0 , do_vnorm , sval_itop ) ;
   mri_principal_setev(nev) ;

   /*-- get data vectors --*/

   ivox = (int *)malloc(sizeof(int)*masknum) ;
   for( kk=ii=0 ; ii < nxyz ; ii++ ) if( mask[ii] ) ivox[kk++] = ii ;
   INFO_message("Extracting data vectors") ;
   imar = THD_extract_many_series( masknum, ivox, inset ) ; DSET_unload(inset) ;
   if( imar == NULL ) ERROR_exit("Can't get data vector?!") ;

   /*-- detrending --*/

   if( polort >= 0 || nyort > 0 || do_bpass ){
     float **polref=NULL ; float *tsar ;
     int nort=IMARR_COUNT(ortar) , nref=0 ;

     if( polort >= 0 ){  /* polynomials */
       nref = polort+1 ; polref = THD_build_polyref(nref,nt) ;
     }

     if( nort > 0 ){     /* other orts */
       float *oar , *par ; int nx,ny , qq,tt ;
       for( kk=0 ; kk < nort ; kk++ ){  /* loop over input -ort files */
         ortim = IMARR_SUBIM(ortar,kk) ;
         nx = ortim->nx ; ny = ortim->ny ;
         if( nx < nt )
           ERROR_exit("-ort '%s' length %d shorter than dataset length %d" ,
                      ortim->name , nx , nt ) ;
         polref = (float **)realloc(polref,(nref+ny)*sizeof(float *)) ;
         oar    = MRI_FLOAT_PTR(ortim) ;
         for( qq=0 ; qq < ny ; qq++,oar+=nx ){
           par = polref[nref+qq] = (float *)malloc(sizeof(float)*nt) ;
           for( tt=0 ; tt < nt ; tt++ ) par[tt] = oar[tt] ;
                if( polort == 0 ) THD_const_detrend (nt,par,NULL) ;
           else if( polort >  0 ) THD_linear_detrend(nt,par,NULL,NULL) ;
         }
         nref += ny ;
       }
       DESTROY_IMARR(ortar) ;
     }

     if( !do_bpass ){            /* old style ort-ification */

       MRI_IMAGE *imq , *imp ; float *qar ;
       INFO_message("Detrending data vectors") ;
#if 1
       imq = mri_new( nt , nref , MRI_float) ; qar = MRI_FLOAT_PTR(imq) ;
       for( kk=0 ; kk < nref ; kk++ )
         memcpy( qar+kk*nt , polref[kk] , sizeof(float)*nt ) ;
       imp = mri_matrix_psinv( imq , NULL , 1.e-8 ) ;
       for( kk=0 ; kk < IMARR_COUNT(imar) ; kk++ ){
         mri_matrix_detrend( IMARR_SUBIM(imar,kk) , imq , imp ) ;
       }
       mri_free(imp) ; mri_free(imq) ;
#else
       for( kk=0 ; kk < IMARR_COUNT(imar) ; kk++ ){
         tsar = MRI_FLOAT_PTR(IMARR_SUBIM(imar,kk)) ;
         THD_generic_detrend_LSQ( nt , tsar , -1 , nref , polref , NULL ) ;
       }
#endif

     } else {                   /* bandpass plus (maybe) orts */

       float **vec = (float **)malloc(sizeof(float *)*IMARR_COUNT(imar)) ;
       INFO_message("Bandpassing data vectors") ;
       for( kk=0 ; kk < IMARR_COUNT(imar) ; kk++ )
         vec[kk] = MRI_FLOAT_PTR(IMARR_SUBIM(imar,kk)) ;
       (void)THD_bandpass_vectors( nt    , IMARR_COUNT(imar) , vec     ,
                                   dtime , bpass_L           , bpass_H ,
                                   2     , nref              , polref   ) ;
       free(vec) ;
     }

     for( kk=0 ; kk < nref; kk++ ) free(polref[kk]) ;
     free(polref) ;
   } /* end of detrendization */

   /*--- the actual work ---*/

   INFO_message("Computing SVD") ;
   pim  = mri_principal_vector( imar ) ; DESTROY_IMARR(imar) ;
   if( pim == NULL ) ERROR_exit("SVD failure!?!") ;
   ev = mri_principal_getev() ;
   switch(sval_itop+1){
     case 1:
       INFO_message("First singular value: %g",ev[0]) ; break ;
     case 2:
       INFO_message("First 2 singular values: %g %g",ev[0],ev[1]) ; break ;
     case 3:
       INFO_message("First 3 singular values: %g %g %g",ev[0],ev[1],ev[2]) ; break ;
     case 4:
       INFO_message("First 4 singular values: %g %g %g %g",ev[0],ev[1],ev[2],ev[3]) ; break ;
     default:
     case 5:
       INFO_message("First 5 singular values: %g %g %g %g %g",ev[0],ev[1],ev[2],ev[3],ev[4]) ; break ;
   }
   mri_write_1D(NULL,pim) ;

   exit(0) ;
}
Ejemplo n.º 5
0
MRI_IMARR * THD_get_many_timeseries( THD_string_array * dlist )
{
   int id , ii , ndir ;
   MRI_IMARR * outar=NULL, * tmpar=NULL ;
   char * epath , * eee ;
   char   efake[] = "./" ;
   THD_string_array *qlist ; /* 02 Feb 2002 */

ENTRY("THD_get_many_timeseries") ;

   /*----- sanity check and initialize -----*/

                       epath = my_getenv( "AFNI_TSPATH" ) ;
   if( epath == NULL ) epath = my_getenv( "AFNI_TS_PATH" ) ; /* 07 Oct 1996 */
   if( epath == NULL ) epath = efake ;                      /* 07 Oct 1996 */

   ndir = (dlist != NULL) ? dlist->num : 0 ;

   if( ndir == 0 && epath == NULL ) RETURN( outar ) ;

   INIT_IMARR( outar ) ;
   INIT_SARR( qlist ) ;

   /*----- for each input directory, find all *.1D files -----*/

   for( id=0 ; id < ndir ; id++ ){

      ADDTO_SARR(qlist,dlist->ar[id]) ;

      tmpar = THD_get_all_timeseries( dlist->ar[id] ) ;
      if( tmpar == NULL ) continue ;

      for( ii=0 ; ii < tmpar->num ; ii++ )  /* move images to output array */
         ADDTO_IMARR( outar , tmpar->imarr[ii] ) ;

      FREE_IMARR(tmpar) ;  /* don't need this no more */
   }

   /*----- also do directories in environment path, if any -----*/

   if( epath != NULL ){
      int epos =0 , ll = strlen(epath) ;
      char * elocal ;
      char ename[THD_MAX_NAME] ;

      /* copy path list into local memory */

      elocal = (char *) malloc( sizeof(char) * (ll+2) ) ;
      if( elocal == NULL ){
         fprintf(stderr,
                "\n*** THD_get_many_timeseries malloc failure - is memory full? ***\n");
         EXIT(1) ;
      }
      strcpy( elocal , epath ) ; elocal[ll] = ' ' ; elocal[ll+1] = '\0' ;

      /* replace colons with blanks */

      for( ii=0 ; ii < ll ; ii++ )
         if( elocal[ii] == ':' ) elocal[ii] = ' ' ;

      /* extract blank delimited strings,
         use as directory names to get timeseries files */

      do{
         ii = sscanf( elocal+epos , "%s%n" , ename , &id ) ;
         if( ii < 1 ) break ;  /* no read --> end of work */
         epos += id ;          /* epos = char after last one scanned */

         ii = strlen(ename) ;                         /* make sure name has */
         if( ename[ii-1] != '/' ){                    /* a trailing '/' on it */
            ename[ii]  = '/' ; ename[ii+1] = '\0' ;
         }

         if( !THD_is_directory(ename) ) continue ;  /* 21 May 2002 - rcr */

         /* 02 Feb 2002: check if scanned this directory before */

         for( ii=0 ; ii < qlist->num ; ii++ )
            if( THD_equiv_files(qlist->ar[ii],ename) ) break ;
         if( ii < qlist->num ) continue ;  /* skip to end of do loop */
         ADDTO_SARR(qlist,ename) ;

         tmpar = THD_get_all_timeseries( ename ) ; /* read this directory */
         if( tmpar != NULL ){
            for( ii=0 ; ii < tmpar->num ; ii++ )   /* move images to output array */
               ADDTO_IMARR( outar , tmpar->imarr[ii] ) ;

            FREE_IMARR(tmpar) ;                    /* don't need this no more */
         }
      } while( epos < ll ) ;  /* scan until 'epos' is after end of epath */

      free(elocal) ;
   }

   if( IMARR_COUNT(outar) == 0 ) DESTROY_IMARR(outar) ;

   DESTROY_SARR(qlist) ;
   RETURN( outar ) ;
}
Ejemplo n.º 6
0
MRI_IMARR * THD_get_all_timeseries( char * dname )
{
   THD_string_array * flist , * rlist ;
   int ir , ll , ii ;
   char * fname , * tname ;
   float * far ;
   MRI_IMARR * outar ;
   MRI_IMAGE * outim , * flim ;

#ifdef NEWWAY
   char * pat ;
#endif

   unsigned long max_fsize ;  /* 20 Jul 2004: max 1D file size to load */

   max_fsize = (unsigned long) AFNI_numenv( "AFNI_MAX_1DSIZE" ) ;
   if( max_fsize == 0 ) max_fsize = 123*1024 ;

   /*----- sanity check and initialize -----*/

   if( dname == NULL || strlen(dname) == 0 ) return NULL ;
   INIT_IMARR( outar ) ;

   /*----- find all *.1D files -----*/

#ifdef NEWWAY
   ii  = strlen(dname) ;
   pat = (char *) malloc(sizeof(char)*(ii+8)) ;
   strcpy(pat,dname) ;
   if( pat[ii-1] != '/' ) strcat(pat,"/") ;
   strcat(pat,"*.1D*") ;
   flist = THD_get_wildcard_filenames( pat ) ;
   free(pat) ;
#else
   flist = THD_get_all_filenames( dname ) ;
#endif

   if( flist == NULL || flist->num <= 0 ){
      DESTROY_SARR(flist) ;
      DESTROY_IMARR(outar) ;
      return NULL ;
   }

   rlist = THD_extract_regular_files( flist ) ;
   DESTROY_SARR(flist) ;
   if( rlist == NULL || rlist->num <= 0 ){
      DESTROY_SARR(rlist) ;
      DESTROY_IMARR(outar) ;
      return NULL ;
   }

   for( ir=0 ; ir < rlist->num ; ir++ ){
      fname = rlist->ar[ir] ; if( fname == NULL ) continue ;

      ll = strlen(fname) - 3 ; if( ll < 1 ) continue ;

      if( strcmp(fname+ll,".1D")==0 ||
          strcmp(fname+ll,"1Dx")==0 ||
          strcmp(fname+ll,"1Dv")==0   ){

         if( THD_filesize(fname) > max_fsize ) continue ;  /* 20 Jul 2004 */

         flim = mri_read_1D( fname ) ;
         if( flim != NULL ){
            far = MRI_FLOAT_PTR(flim) ;
            for( ii=0 ; ii < flim->nvox ; ii++ )
               if( fabs(far[ii]) >= 33333.0 ) far[ii] = WAY_BIG ;

            tname = THD_trailname(fname,1) ;
            mri_add_name( tname , flim ) ;
            ADDTO_IMARR( outar , flim ) ;
         }
      }
   }

   DESTROY_SARR(rlist) ;

   if( IMARR_COUNT(outar) == 0 ) DESTROY_IMARR(outar) ;

   return outar ;
}
Ejemplo n.º 7
0
int main( int argc , char *argv[] )
{
   THD_3dim_dataset *yset=NULL , *aset=NULL , *mset=NULL , *wset=NULL ;
   MRI_IMAGE *fim=NULL, *qim,*tim, *pfim=NULL , *vim     , *wim=NULL  ;
   float     *flar    , *qar,*tar, *par=NULL  , *var     , *war=NULL  ;
   MRI_IMARR *fimar=NULL ;
   MRI_IMAGE *aim , *yim ; float *aar , *yar ;
   int nt=0 , nxyz=0 , nvox=0 , nparam=0 , nqbase , polort=0 , ii,jj,kk,bb ;
   byte *mask=NULL ; int nmask=0 , iarg ;
   char *fname_out="-" ;   /** equiv to stdout **/

   float alpha=0.0f ;
   int   nfir =0 ; float firwt[5]={0.09f,0.25f,0.32f,0.25f,0.09f} ;
   int   nmed =0 ;
   int   nwt  =0 ;

#define METHOD_C  3
#define METHOD_K 11
   int   method = METHOD_C ;

   /**--- help the pitiful user? ---**/

   if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
     printf(
      "Usage: 3dInvFMRI [options]\n"
      "Program to compute stimulus time series, given a 3D+time dataset\n"
      "and an activation map (the inverse of the usual FMRI analysis problem).\n"
      "-------------------------------------------------------------------\n"
      "OPTIONS:\n"
      "\n"
      " -data yyy  =\n"
      "   *OR*     = Defines input 3D+time dataset [a non-optional option].\n"
      " -input yyy =\n"
      "\n"
      " -map  aaa  = Defines activation map; 'aaa' should be a bucket dataset,\n"
      "                each sub-brick of which defines the beta weight map for\n"
      "                an unknown stimulus time series [also non-optional].\n"
      "\n"
      " -mapwt www = Defines a weighting factor to use for each element of\n"
      "                the map.  The dataset 'www' can have either 1 sub-brick,\n"
      "                or the same number as in the -map dataset.  In the\n"
      "                first case, in each voxel, each sub-brick of the map\n"
      "                gets the same weight in the least squares equations.\n"
      "                  [default: all weights are 1]\n"
      "\n"
      " -mask mmm  = Defines a mask dataset, to restrict input voxels from\n"
      "                -data and -map.  [default: all voxels are used]\n"
      "\n"
      " -base fff  = Each column of the 1D file 'fff' defines a baseline time\n"
      "                series; these columns should be the same length as\n"
      "                number of time points in 'yyy'.  Multiple -base options\n"
      "                can be given.\n"
      " -polort pp = Adds polynomials of order 'pp' to the baseline collection.\n"
      "                The default baseline model is '-polort 0' (constant).\n"
      "                To specify no baseline model at all, use '-polort -1'.\n"
      "\n"
      " -out vvv   = Name of 1D output file will be 'vvv'.\n"
      "                [default = '-', which is stdout; probably not good]\n"
      "\n"
      " -method M  = Determines the method to use.  'M' is a single letter:\n"
      "               -method C = least squares fit to data matrix Y [default]\n"
      "               -method K = least squares fit to activation matrix A\n"
      "\n"
      " -alpha aa  = Set the 'alpha' factor to 'aa'; alpha is used to penalize\n"
      "                large values of the output vectors.  Default is 0.\n"
      "                A large-ish value for alpha would be 0.1.\n"
      "\n"
      " -fir5     = Smooth the results with a 5 point lowpass FIR filter.\n"
      " -median5  = Smooth the results with a 5 point median filter.\n"
      "               [default: no smoothing; only 1 of these can be used]\n"
      "-------------------------------------------------------------------\n"
      "METHODS:\n"
      " Formulate the problem as\n"
      "    Y = V A' + F C' + errors\n"
      " where Y = data matrix      (N x M) [from -data]\n"
      "       V = stimulus         (N x p) [to -out]\n"
      "       A = map matrix       (M x p) [from -map]\n"
      "       F = baseline matrix  (N x q) [from -base and -polort]\n"
      "       C = baseline weights (M x q) [not computed]\n"
      "       N = time series length = length of -data file\n"
      "       M = number of voxels in mask\n"
      "       p = number of stimulus time series to estimate\n"
      "         = number of parameters in -map file\n"
      "       q = number of baseline parameters\n"
      "   and ' = matrix transpose operator\n"
      " Next, define matrix Z (Y detrended relative to columns of F) by\n"
      "                       -1\n"
      "   Z = [I - F(F'F)  F']  Y\n"
      "-------------------------------------------------------------------\n"
      " The method C solution is given by\n"
      "                 -1\n"
      "   V0 = Z A [A'A]\n"
      "\n"
      " This solution minimizes the sum of squares over the N*M elements\n"
      " of the matrix   Y - V A' + F C'   (N.B.: A' means A-transpose).\n"
      "-------------------------------------------------------------------\n"
      " The method K solution is given by\n"
      "             -1                            -1\n"
      "   W = [Z Z']  Z A   and then   V = W [W'W]\n"
      "\n"
      " This solution minimizes the sum of squares of the difference between\n"
      " the A(V) predicted from V and the input A, where A(V) is given by\n"
      "                    -1\n"
      "   A(V) = Z' V [V'V]   = Z'W\n"
      "-------------------------------------------------------------------\n"
      " Technically, the solution is unidentfiable up to an arbitrary\n"
      " multiple of the columns of F (i.e., V = V0 + F G, where G is\n"
      " an arbitrary q x p matrix); the solution above is the solution\n"
      " that is orthogonal to the columns of F.\n"
      "\n"
      "-- RWCox - March 2006 - purely for experimental purposes!\n"
     ) ;

     printf("\n"
     "===================== EXAMPLE USAGE =====================================\n"
     "** Step 1: From a training dataset, generate activation map.\n"
     "  The input dataset has 4 runs, each 108 time points long.  3dDeconvolve\n"
     "  is used on the first 3 runs (time points 0..323) to generate the\n"
     "  activation map.  There are two visual stimuli (Complex and Simple).\n"
     "\n"
     "  3dDeconvolve -x1D xout_short_two.1D -input rall_vr+orig'[0..323]'   \\\n"
     "      -num_stimts 2                                                   \\\n"
     "      -stim_file 1 hrf_complex.1D               -stim_label 1 Complex \\\n"
     "      -stim_file 2 hrf_simple.1D                -stim_label 2 Simple  \\\n"
     "      -concat '1D:0,108,216'                                          \\\n"
     "      -full_first -fout -tout                                         \\\n"
     "      -bucket func_ht2_short_two -cbucket cbuc_ht2_short_two\n"
     "\n"
     "  N.B.: You may want to de-spike, smooth, and register the 3D+time\n"
     "        dataset prior to the analysis (as usual).  These steps are not\n"
     "        shown here -- I'm presuming you know how to use AFNI already.\n"
     "\n"
     "** Step 2: Create a mask of highly activated voxels.\n"
     "  The F statistic threshold is set to 30, corresponding to a voxel-wise\n"
     "  p = 1e-12 = very significant.  The mask is also lightly clustered, and\n"
     "  restricted to brain voxels.\n"
     "\n"
     "  3dAutomask -prefix Amask rall_vr+orig\n"
     "  3dcalc -a 'func_ht2_short+orig[0]' -b Amask+orig -datum byte \\\n"
     "         -nscale -expr 'step(a-30)*b' -prefix STmask300\n"
     "  3dmerge -dxyz=1 -1clust 1.1 5 -prefix STmask300c STmask300+orig\n"
     "\n"
     "** Step 3: Run 3dInvFMRI to estimate the stimulus functions in run #4.\n"
     "  Run #4 is time points 324..431 of the 3D+time dataset (the -data\n"
     "  input below).  The -map input is the beta weights extracted from\n"
     "  the -cbucket output of 3dDeconvolve.\n"
     "\n"
     "  3dInvFMRI -mask STmask300c+orig                       \\\n"
     "            -data rall_vr+orig'[324..431]'              \\\n"
     "            -map cbuc_ht2_short_two+orig'[6..7]'        \\\n"
     "            -polort 1 -alpha 0.01 -median5 -method K    \\\n"
     "            -out ii300K_short_two.1D\n"
     "\n"
     "  3dInvFMRI -mask STmask300c+orig                       \\\n"
     "            -data rall_vr+orig'[324..431]'              \\\n"
     "            -map cbuc_ht2_short_two+orig'[6..7]'        \\\n"
     "            -polort 1 -alpha 0.01 -median5 -method C    \\\n"
     "            -out ii300C_short_two.1D\n"
     "\n"
     "** Step 4: Plot the results, and get confused.\n"
     "\n"
     "  1dplot -ynames VV KK CC -xlabel Run#4 -ylabel ComplexStim \\\n"
     "         hrf_complex.1D'{324..432}'                         \\\n"
     "         ii300K_short_two.1D'[0]'                           \\\n"
     "         ii300C_short_two.1D'[0]'\n"
     "\n"
     "  1dplot -ynames VV KK CC -xlabel Run#4 -ylabel SimpleStim \\\n"
     "         hrf_simple.1D'{324..432}'                         \\\n"
     "         ii300K_short_two.1D'[1]'                          \\\n"
     "         ii300C_short_two.1D'[1]'\n"
     "\n"
     "  N.B.: I've found that method K works better if MORE voxels are\n"
     "        included in the mask (lower threshold) and method C if\n"
     "        FEWER voxels are included.  The above threshold gave 945\n"
     "        voxels being used to determine the 2 output time series.\n"
     "=========================================================================\n"
     ) ;

     PRINT_COMPILE_DATE ; exit(0) ;
   }

   /**--- bureaucracy ---**/

   mainENTRY("3dInvFMRI main"); machdep();
   PRINT_VERSION("3dInvFMRI"); AUTHOR("Zhark");
   AFNI_logger("3dInvFMRI",argc,argv) ;

   /**--- scan command line ---**/

   iarg = 1 ;
   while( iarg < argc ){

     if( strcmp(argv[iarg],"-method") == 0 ){
       switch( argv[++iarg][0] ){
         default:
           WARNING_message("Ignoring illegal -method '%s'",argv[iarg]) ;
         break ;
         case 'C': method = METHOD_C ; break ;
         case 'K': method = METHOD_K ; break ;
       }
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-fir5") == 0 ){
       if( nmed > 0 ) WARNING_message("Ignoring -fir5 in favor of -median5") ;
       else           nfir = 5 ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-median5") == 0 ){
       if( nfir > 0 ) WARNING_message("Ignoring -median5 in favor of -fir5") ;
       else           nmed = 5 ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-alpha") == 0 ){
       alpha = (float)strtod(argv[++iarg],NULL) ;
       if( alpha <= 0.0f ){
         alpha = 0.0f ; WARNING_message("-alpha '%s' ignored!",argv[iarg]) ;
       }
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-data") == 0 || strcmp(argv[iarg],"-input") == 0 ){
       if( yset != NULL ) ERROR_exit("Can't input 2 3D+time datasets") ;
       yset = THD_open_dataset(argv[++iarg]) ;
       CHECK_OPEN_ERROR(yset,argv[iarg]) ;
       nt = DSET_NVALS(yset) ;
       if( nt < 2 ) ERROR_exit("Only 1 sub-brick in dataset %s",argv[iarg]) ;
       nxyz = DSET_NVOX(yset) ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-map") == 0 ){
       if( aset != NULL ) ERROR_exit("Can't input 2 -map datasets") ;
       aset = THD_open_dataset(argv[++iarg]) ;
       CHECK_OPEN_ERROR(aset,argv[iarg]) ;
       nparam = DSET_NVALS(aset) ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-mapwt") == 0 ){
       if( wset != NULL ) ERROR_exit("Can't input 2 -mapwt datasets") ;
       wset = THD_open_dataset(argv[++iarg]) ;
       CHECK_OPEN_ERROR(wset,argv[iarg]) ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-mask") == 0 ){
       if( mset != NULL ) ERROR_exit("Can't input 2 -mask datasets") ;
       mset = THD_open_dataset(argv[++iarg]) ;
       CHECK_OPEN_ERROR(mset,argv[iarg]) ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-polort") == 0 ){
       char *cpt ;
       polort = (int)strtod(argv[++iarg],&cpt) ;
       if( *cpt != '\0' ) WARNING_message("Illegal non-numeric value after -polort") ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-out") == 0 ){
       fname_out = strdup(argv[++iarg]) ;
       if( !THD_filename_ok(fname_out) )
         ERROR_exit("Bad -out filename '%s'",fname_out) ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-base") == 0 ){
       if( fimar == NULL ) INIT_IMARR(fimar) ;
       qim = mri_read_1D( argv[++iarg] ) ;
       if( qim == NULL ) ERROR_exit("Can't read 1D file %s",argv[iarg]) ;
       ADDTO_IMARR(fimar,qim) ;
       iarg++ ; continue ;
     }

     ERROR_exit("Unrecognized option '%s'",argv[iarg]) ;
   }

   /**--- finish up processing options ---**/

   if( yset == NULL ) ERROR_exit("No input 3D+time dataset?!") ;
   if( aset == NULL ) ERROR_exit("No input FMRI -map dataset?!") ;

   if( DSET_NVOX(aset) != nxyz )
     ERROR_exit("Grid mismatch between -data and -map") ;

   INFO_message("Loading dataset for Y") ;
   DSET_load(yset); CHECK_LOAD_ERROR(yset) ;
   INFO_message("Loading dataset for A") ;
   DSET_load(aset); CHECK_LOAD_ERROR(aset) ;

   if( wset != NULL ){
     if( DSET_NVOX(wset) != nxyz )
       ERROR_exit("Grid mismatch between -data and -mapwt") ;
     nwt = DSET_NVALS(wset) ;
     if( nwt > 1 && nwt != nparam )
       ERROR_exit("Wrong number of values=%d in -mapwt; should be 1 or %d",
                  nwt , nparam ) ;
     INFO_message("Loading dataset for mapwt") ;
     DSET_load(wset); CHECK_LOAD_ERROR(wset) ;
   }

   if( mset != NULL ){
     if( DSET_NVOX(mset) != nxyz )
       ERROR_exit("Grid mismatch between -data and -mask") ;
     INFO_message("Loading dataset for mask") ;
     DSET_load(mset); CHECK_LOAD_ERROR(mset) ;
     mask  = THD_makemask( mset , 0 , 1.0f,-1.0f ); DSET_delete(mset);
     nmask = THD_countmask( nxyz , mask ) ;
     if( nmask < 3 ){
       WARNING_message("Mask has %d voxels -- ignoring!",nmask) ;
       free(mask) ; mask = NULL ; nmask = 0 ;
     }
   }

   nvox = (nmask > 0) ? nmask : nxyz ;
   INFO_message("N = time series length  = %d",nt    ) ;
   INFO_message("M = number of voxels    = %d",nvox  ) ;
   INFO_message("p = number of params    = %d",nparam) ;

   /**--- set up baseline funcs in one array ---*/

   nqbase = (polort >= 0 ) ? polort+1 : 0 ;
   if( fimar != NULL ){
     for( kk=0 ; kk < IMARR_COUNT(fimar) ; kk++ ){
       qim = IMARR_SUBIMAGE(fimar,kk) ;
       if( qim != NULL && qim->nx != nt )
         WARNING_message("-base #%d length=%d; data length=%d",kk+1,qim->nx,nt) ;
       nqbase += qim->ny ;
     }
   }

   INFO_message("q = number of baselines = %d",nqbase) ;

#undef  F
#define F(i,j) flar[(i)+(j)*nt]   /* nt X nqbase */
   if( nqbase > 0 ){
     fim  = mri_new( nt , nqbase , MRI_float ) ;   /* F matrix */
     flar = MRI_FLOAT_PTR(fim) ;
     bb = 0 ;
     if( polort >= 0 ){                /** load polynomial baseline **/
       double a = 2.0/(nt-1.0) ;
       for( jj=0 ; jj <= polort ; jj++ ){
         for( ii=0 ; ii < nt ; ii++ )
           F(ii,jj) = (float)Plegendre( a*ii-1.0 , jj ) ;
       }
       bb = polort+1 ;
     }
#undef  Q
#define Q(i,j) qar[(i)+(j)*qim->nx]  /* qim->nx X qim->ny */

     if( fimar != NULL ){             /** load -base baseline columns **/
       for( kk=0 ; kk < IMARR_COUNT(fimar) ; kk++ ){
         qim = IMARR_SUBIMAGE(fimar,kk) ; qar = MRI_FLOAT_PTR(qim) ;
         for( jj=0 ; jj < qim->ny ; jj++ ){
           for( ii=0 ; ii < nt ; ii++ )
             F(ii,bb+jj) = (ii < qim->nx) ? Q(ii,jj) : 0.0f ;
         }
         bb += qim->ny ;
       }
       DESTROY_IMARR(fimar) ; fimar=NULL ;
     }

     /* remove mean from each column after first? */

     if( polort >= 0 && nqbase > 1 ){
       float sum ;
       for( jj=1 ; jj < nqbase ; jj++ ){
         sum = 0.0f ;
         for( ii=0 ; ii < nt ; ii++ ) sum += F(ii,jj) ;
         sum /= nt ;
         for( ii=0 ; ii < nt ; ii++ ) F(ii,jj) -= sum ;
       }
     }

     /* compute pseudo-inverse of baseline matrix,
        so we can project it out from the data time series */

     /*      -1          */
     /* (F'F)  F' matrix */

     INFO_message("Computing pseudo-inverse of baseline matrix F") ;
     pfim = mri_matrix_psinv(fim,NULL,0.0f) ; par = MRI_FLOAT_PTR(pfim) ;

#undef  P
#define P(i,j) par[(i)+(j)*nqbase]   /* nqbase X nt */

#if 0
     qim = mri_matrix_transpose(pfim) ;    /** save to disk? **/
     mri_write_1D( "Fpsinv.1D" , qim ) ;
     mri_free(qim) ;
#endif
   }

   /**--- set up map image into aim/aar = A matrix ---**/

#undef  GOOD
#define GOOD(i) (mask==NULL || mask[i])

#undef  A
#define A(i,j) aar[(i)+(j)*nvox]   /* nvox X nparam */

   INFO_message("Loading map matrix A") ;
   aim = mri_new( nvox , nparam , MRI_float ); aar = MRI_FLOAT_PTR(aim);
   for( jj=0 ; jj < nparam ; jj++ ){
     for( ii=kk=0 ; ii < nxyz ; ii++ ){
       if( GOOD(ii) ){ A(kk,jj) = THD_get_voxel(aset,ii,jj); kk++; }
   }}
   DSET_unload(aset) ;

   /**--- set up map weight into wim/war ---**/

#undef  WT
#define WT(i,j) war[(i)+(j)*nvox]   /* nvox X nparam */

   if( wset != NULL ){
     int numneg=0 , numpos=0 ;
     float fac ;

     INFO_message("Loading map weight matrix") ;
     wim = mri_new( nvox , nwt , MRI_float ) ; war = MRI_FLOAT_PTR(wim) ;
     for( jj=0 ; jj < nwt ; jj++ ){
       for( ii=kk=0 ; ii < nxyz ; ii++ ){
         if( GOOD(ii) ){
           WT(kk,jj) = THD_get_voxel(wset,ii,jj);
                if( WT(kk,jj) > 0.0f ){ numpos++; WT(kk,jj) = sqrt(WT(kk,jj)); }
           else if( WT(kk,jj) < 0.0f ){ numneg++; WT(kk,jj) = 0.0f;            }
           kk++;
         }
     }}
     DSET_unload(wset) ;
     if( numpos <= nparam )
       WARNING_message("Only %d positive weights found in -wtmap!",numpos) ;
     if( numneg > 0 )
       WARNING_message("%d negative weights found in -wtmap!",numneg) ;

     for( jj=0 ; jj < nwt ; jj++ ){
       fac = 0.0f ;
       for( kk=0 ; kk < nvox ; kk++ ) if( WT(kk,jj) > fac ) fac = WT(kk,jj) ;
       if( fac > 0.0f ){
         fac = 1.0f / fac ;
         for( kk=0 ; kk < nvox ; kk++ ) WT(kk,jj) *= fac ;
       }
     }
   }

   /**--- set up data image into yim/yar = Y matrix ---**/

#undef  Y
#define Y(i,j) yar[(i)+(j)*nt]   /* nt X nvox */

   INFO_message("Loading data matrix Y") ;
   yim = mri_new( nt , nvox , MRI_float ); yar = MRI_FLOAT_PTR(yim);
   for( ii=0 ; ii < nt ; ii++ ){
     for( jj=kk=0 ; jj < nxyz ; jj++ ){
       if( GOOD(jj) ){ Y(ii,kk) = THD_get_voxel(yset,jj,ii); kk++; }
   }}
   DSET_unload(yset) ;

   /**--- project baseline out of data image = Z matrix ---**/

   if( pfim != NULL ){
#undef  T
#define T(i,j) tar[(i)+(j)*nt]  /* nt X nvox */
     INFO_message("Projecting baseline out of Y") ;
     qim = mri_matrix_mult( pfim , yim ) ;   /* nqbase X nvox */
     tim = mri_matrix_mult(  fim , qim ) ;   /* nt X nvox */
     tar = MRI_FLOAT_PTR(tim) ;              /* Y projected onto baseline */
     for( jj=0 ; jj < nvox ; jj++ )
       for( ii=0 ; ii < nt ; ii++ ) Y(ii,jj) -= T(ii,jj) ;
     mri_free(tim); mri_free(qim); mri_free(pfim); mri_free(fim);
   }

   /***** At this point:
             matrix A is in aim,
             matrix Z is in yim.
          Solve for V into vim, using the chosen method *****/

   switch( method ){
     default: ERROR_exit("Illegal method code!  WTF?") ; /* Huh? */

     /*.....................................................................*/
     case METHOD_C:
       /**--- compute pseudo-inverse of A map ---**/

       INFO_message("Method C: Computing pseudo-inverse of A") ;
       if( wim != NULL ) WARNING_message("Ignoring -mapwt dataset") ;
       pfim = mri_matrix_psinv(aim,NULL,alpha) ;  /* nparam X nvox */
       if( pfim == NULL ) ERROR_exit("mri_matrix_psinv() fails") ;
       mri_free(aim) ;

       /**--- and apply to data to get results ---*/

       INFO_message("Computing result V") ;
       vim = mri_matrix_multranB( yim , pfim ) ; /* nt x nparam */
       mri_free(pfim) ; mri_free(yim) ;
     break ;

     /*.....................................................................*/
     case METHOD_K:
       /**--- compute pseudo-inverse of transposed Z ---*/

       INFO_message("Method K: Computing pseudo-inverse of Z'") ;
       if( nwt > 1 ){
         WARNING_message("Ignoring -mapwt dataset: more than 1 sub-brick") ;
         nwt = 0 ; mri_free(wim) ; wim = NULL ; war = NULL ;
       }

       if( nwt == 1 ){
         float fac ;
         for( kk=0 ; kk < nvox ; kk++ ){
           fac = war[kk] ;
           for( ii=0 ; ii < nt     ; ii++ ) Y(ii,kk) *= fac ;
           for( ii=0 ; ii < nparam ; ii++ ) A(kk,ii) *= fac ;
         }
       }

       tim  = mri_matrix_transpose(yim)        ; mri_free(yim) ;
       pfim = mri_matrix_psinv(tim,NULL,alpha) ; mri_free(tim) ;
       if( pfim == NULL ) ERROR_exit("mri_matrix_psinv() fails") ;

       INFO_message("Computing W") ;
       tim = mri_matrix_mult( pfim , aim ) ;
       mri_free(aim) ; mri_free(pfim) ;

       INFO_message("Computing result V") ;
       pfim = mri_matrix_psinv(tim,NULL,0.0f) ; mri_free(tim) ;
       vim  = mri_matrix_transpose(pfim)      ; mri_free(pfim);
     break ;

   } /* end of switch on method */

   if( wim != NULL ) mri_free(wim) ;

   /**--- smooth? ---**/

   if( nfir > 0 && vim->nx > nfir ){
     INFO_message("FIR-5-ing result") ;
     var = MRI_FLOAT_PTR(vim) ;
     for( jj=0 ; jj < vim->ny ; jj++ )
       linear_filter_reflect( nfir,firwt , vim->nx , var + (jj*vim->nx) ) ;
   }

   if( nmed > 0 && vim->nx > nmed ){
     INFO_message("Median-5-ing result") ;
     var = MRI_FLOAT_PTR(vim) ;
     for( jj=0 ; jj < vim->ny ; jj++ )
       median5_filter_reflect( vim->nx , var + (jj*vim->nx) ) ;
   }

   /**--- write results ---**/

   INFO_message("Writing result to '%s'",fname_out) ;
   mri_write_1D( fname_out , vim ) ;
   exit(0) ;
}
Ejemplo n.º 8
0
int main( int argc , char *argv[] )
{
   int iarg , ii,jj,kk,mm , nvec , nx=0,ny , ff , vlen=4 ;
   MRI_IMAGE *tim , *vsim=NULL ;
   MRI_IMARR *tar ;
   char **vecnam , *tnam ;
   float *far , **tvec , *vsig=NULL , xsig,ysig ;
   float_quad qcor ; float_pair pci ; float corst, cor025, cor500, cor975 ;
   char fmt[256] ;
   int cormeth=0 ;    /* 0=Pearson, 1=Spearman, 2=Quadrant, 3=Kendall tau_b */
   float (*corfun)(int,float *,float *) ;

   /*-- start the AFNI machinery --*/

   mainENTRY("1dCorrelate main") ; machdep() ;

   /* check for options */

   iarg = 1 ; nvec = 0 ;
   while( iarg < argc && argv[iarg][0] == '-' ){
      /* I get by with a little help from my friends? */

      if( strcmp(argv[iarg],"-help") == 0 || strcmp(argv[iarg],"-h") == 0){
         usage_1dCorrelate(strlen(argv[iarg])>3 ? 2:1);
         exit(0) ;
      }

     /*--- methods ---*/

     if( toupper(argv[iarg][1]) == 'P' ){ cormeth = 0 ; iarg++ ; continue ; }
     if( toupper(argv[iarg][1]) == 'S' ){ cormeth = 1 ; iarg++ ; continue ; }
     if( toupper(argv[iarg][1]) == 'Q' ){ cormeth = 2 ; iarg++ ; continue ; }
     if( toupper(argv[iarg][1]) == 'K' ){ cormeth = 3 ; iarg++ ; continue ; }
     if( toupper(argv[iarg][1]) == 'T' ){ cormeth = 4 ; iarg++ ; continue ; }
     if( toupper(argv[iarg][1]) == 'U' ){ cormeth = 5 ; iarg++ ; continue ; }

     /*--- set nboot ---*/

     if( strcasecmp(argv[iarg],"-nboot") == 0 || strcasecmp(argv[iarg],"-num") == 0 ){
       iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-nboot'") ;
       nboot = (int)strtod(argv[iarg],NULL) ;
       if( nboot < NBMIN ){
         WARNING_message("Replacing -nboot %d with %d",nboot,NBMIN) ;
         nboot = NBMIN ;
       }
       iarg++ ; continue ;
     }

     /*--- set alpha ---*/

     if( strcasecmp(argv[iarg],"-alpha") == 0 ){
       iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-alpha'") ;
       alpha = (float)strtod(argv[iarg],NULL) ;
       if( alpha < 1.0f ){
         WARNING_message("Replacing -alpha %.1f with 1",alpha) ;
         alpha = 0.01f ;
       } else if( alpha > 20.0f ){
         WARNING_message("Replacing -alpha %.1f with 20",alpha) ;
         alpha = 0.20f ;
       } else {
         alpha *= 0.01f ;  /* convert from percent to fraction */
       }
       iarg++ ; continue ;
     }

     /*--- block resampling ---*/

     if( strcasecmp(argv[iarg],"-blk") == 0 || strcasecmp(argv[iarg],"-block") == 0 ){
       doblk = 1 ; iarg++ ; continue ;
     }

     if( strcasecmp(argv[iarg],"-vsig") == 0 ){
       if( vsim != NULL ) ERROR_exit("Can't use -vsig twice!") ;
       if( ++iarg >= argc ) ERROR_exit("Need argument after -vsig") ;
       vsim = mri_read_1D(argv[iarg]) ;
       if( vsim == NULL ) ERROR_exit("Can't read -vsig file '%s'",argv[iarg]) ;
       iarg++ ; continue ;
     }

     /*--- user should be flogged ---*/

     ERROR_message("Monstrously illegal option '%s'",argv[iarg]) ;
     suggest_best_prog_option(argv[0], argv[iarg]);
     exit(1);
   }

   /*--- user should be flogged twice ---*/

   if( argc < 2 ){
     usage_1dCorrelate(1) ; exit(0) ; 
   }

   if( iarg == argc )
     ERROR_exit("No 1D files on command line!?\n") ;

   /* the function to compute the correlation */

   corfun = cor_func[cormeth] ;

   /* check and assemble list of input 1D files */

   ff = iarg ;
   INIT_IMARR(tar) ;
   for( ; iarg < argc ; iarg++ ){
     tim = mri_read_1D( argv[iarg] ) ;
     if( tim == NULL ) ERROR_exit("Can't read 1D file '%s'",argv[iarg]) ;
     if( nx == 0 ){
       nx = tim->nx ;
       if( nx < 3 )
         ERROR_exit("1D file '%.77s' length=%d is less than 3",argv[iarg],nx) ;
       else if( nx < 7 )
         WARNING_message("1D file '%.77s' length=%d is less than 7",argv[iarg],nx) ;
     } else if( tim->nx != nx ){
       ERROR_exit("Length of 1D file '%.77s' [%d] doesn't match first file [%d]",
                   argv[iarg] , tim->nx , nx );
     }
     nvec += tim->ny ;
     ADDTO_IMARR(tar,tim) ;
   }

   /* user is really an idiot -- flogging's too good for him */

   if( nvec < 2 ) ERROR_exit("Must have at least 2 input columns!") ;

   if( nx < 20 && doblk ){
     doblk = 0 ;
     WARNING_message("Column length %d < 20 ==> cannot use block resampling",nx) ;
   }

   if( vsim != NULL ){
     if( vsim->nvox < nvec )
       ERROR_exit("-vsig file only has %d entries, but needs at least %d",vsim->nvox,nvec) ;
     vsig = MRI_FLOAT_PTR(vsim) ;
   }

   /* create vectors from 1D files */

   tvec = (float **)malloc( sizeof(float *)*nvec ) ;
   vecnam = (char **)malloc( sizeof(char *)*nvec ) ;
   for( jj=0 ; jj < nvec ; jj++ ){
     tvec[jj] = (float *)malloc( sizeof(float)*nx ) ;
     vecnam[jj] = (char *)malloc(sizeof(char)*THD_MAX_NAME) ;
   }

   /* copy data into new space, create output labels, check for stoopiditees */

   for( kk=mm=0 ; mm < IMARR_COUNT(tar) ; mm++ ){
     tim = IMARR_SUBIM(tar,mm) ;
     far = MRI_FLOAT_PTR(tim) ;
     tnam = tim->name ; if( tnam == NULL ) tnam = "File" ;
     for( jj=0 ; jj < tim->ny ; jj++,kk++ ){
       for( ii=0 ; ii < nx ; ii++ ) tvec[kk][ii] = far[ii+jj*nx] ;
       sprintf(vecnam[kk],"%s[%d]",THD_trailname(tnam,0),jj) ; /* vector name */
       iarg = strlen(vecnam[kk]) ; vlen = MAX(vlen,iarg) ;
       if( THD_is_constant(nx,tvec[kk]) )
         ERROR_exit("Column %s is constant!",vecnam[kk]) ;
     }
   }
   DESTROY_IMARR(tar) ;

   /*--- Print a beeyootiful header ---*/

   printf("# %s correlation [n=%d #col=%d]\n",cor_name[cormeth],nx,nvec) ;
   sprintf(fmt,"# %%-%ds  %%-%ds",vlen,vlen) ;
   printf(fmt,"Name","Name") ;
   printf("   Value   BiasCorr  %5.2f%%   %5.2f%%",50.0f*alpha,100.0f-50.0f*alpha) ;
   if( cormeth == 0 )  /* Pearson */
     printf("  N:%5.2f%% N:%5.2f%%",50.0f*alpha,100.0f-50.0f*alpha) ;
   printf("\n") ;
   printf("# ") ;
   for( ii=0 ; ii < vlen ; ii++ ) printf("-") ;
   printf("  ") ;
   for( ii=0 ; ii < vlen ; ii++ ) printf("-") ;
   printf(" ") ;
   printf(" --------") ;
   printf(" --------") ;
   printf(" --------") ;
   printf(" --------") ;
   if( cormeth == 0 ){ printf(" --------") ; printf(" --------") ; }
   printf("\n") ;
   if( cormeth != 0 )  /* non-Pearson */
     sprintf(fmt,"  %%-%ds  %%-%ds  %%+8.5f %%+8.5f %%+8.5f %%+8.5f\n",vlen,vlen) ;
   else                /* Pearson */
     sprintf(fmt,"  %%-%ds  %%-%ds  %%+8.5f %%+8.5f %%+8.5f %%+8.5f %%+8.5f %%+8.5f\n",vlen,vlen) ;

   /*--- Do some actual work for a suprising change ---*/

   for( jj=0 ; jj < nvec ; jj++ ){       /* loops over column pairs */
     for( kk=jj+1 ; kk < nvec ; kk++ ){

       if( vsig != NULL ){ xsig = vsig[jj]; ysig = vsig[kk]; } else { xsig = ysig = 0.0f; }

       qcor = Corrboot( nx, tvec[jj], tvec[kk], xsig, ysig, corfun ) ;  /* outsourced */

       corst = qcor.a ; cor025 = qcor.b ; cor500 = qcor.c ; cor975 = qcor.d ;

       if( cormeth == 0 ){                      /* Pearson */
         pci = PCorrCI( nx , corst , alpha ) ;
         printf(fmt, vecnam[jj], vecnam[kk], corst, cor500, cor025, cor975, pci.a,pci.b ) ;
       } else {                                 /* all other methods */
         printf(fmt, vecnam[jj], vecnam[kk], corst, cor500, cor025, cor975 ) ;
       }

     }
   }

   /* Finished -- go back to watching Star Trek reruns -- Tribbles ahoy, Cap'n! */

   exit(0) ;
}
Ejemplo n.º 9
0
int main( int argc , char *argv[] )
{
   int iarg , nerr=0 , nvals,nvox , nx,ny,nz , ii,jj,kk ;
   char *prefix="LSSout" , *save1D=NULL , nbuf[256] ;
   THD_3dim_dataset *inset=NULL , *outset ;
   MRI_vectim   *inset_mrv=NULL ;
   byte *mask=NULL ; int mask_nx=0,mask_ny=0,mask_nz=0, automask=0, nmask=0 ;
   NI_element *nelmat=NULL ; char *matname=NULL ;
   char *cgl ;
   int Ngoodlist,*goodlist=NULL , nfull , ncmat,ntime ;
   NI_int_array *giar ; NI_str_array *gsar ; NI_float_array *gfar ;
   MRI_IMAGE *imX, *imA, *imC, *imS ; float *Xar, *Sar ; MRI_IMARR *imar ;
   int nS ; float *ss , *oo , *fv , sum ; int nvec , iv ;
   int nbstim , nst=0 , jst_bot,jst_top ; char *stlab="LSS" ;
   int nodata=1 ;

   /*--- help me if you can ---*/

   if( argc < 2 || strcasecmp(argv[1],"-HELP") == 0 ) LSS_help() ;

   /*--- bureaucratic startup ---*/

   PRINT_VERSION("3dLSS"); mainENTRY("3dLSS main"); machdep();
   AFNI_logger("3dLSS",argc,argv); AUTHOR("RWCox");
   (void)COX_clock_time() ;

   /**------- scan command line --------**/

   iarg = 1 ;
   while( iarg < argc ){

     if( strcmp(argv[iarg],"-verb") == 0 ){ verb++  ; iarg++ ; continue ; }
     if( strcmp(argv[iarg],"-VERB") == 0 ){ verb+=2 ; iarg++ ; continue ; }

     /**==========   -mask  ==========**/

     if( strcasecmp(argv[iarg],"-mask") == 0 ){
       THD_3dim_dataset *mset ;
       if( ++iarg >= argc ) ERROR_exit("Need argument after '-mask'") ;
       if( mask != NULL || automask ) ERROR_exit("Can't have two mask inputs") ;
       mset = THD_open_dataset( argv[iarg] ) ;
       CHECK_OPEN_ERROR(mset,argv[iarg]) ;
       DSET_load(mset) ; CHECK_LOAD_ERROR(mset) ;
       mask_nx = DSET_NX(mset); mask_ny = DSET_NY(mset); mask_nz = DSET_NZ(mset);
       mask = THD_makemask( mset , 0 , 0.5f, 0.0f ) ; DSET_delete(mset) ;
       if( mask == NULL ) ERROR_exit("Can't make mask from dataset '%.33s'",argv[iarg]) ;
       nmask = THD_countmask( mask_nx*mask_ny*mask_nz , mask ) ;
       if( verb || nmask < 1 ) INFO_message("Number of voxels in mask = %d",nmask) ;
       if( nmask < 1 ) ERROR_exit("Mask is too small to process") ;
       iarg++ ; continue ;
     }

     if( strcasecmp(argv[iarg],"-automask") == 0 ){
       if( mask != NULL ) ERROR_exit("Can't have -automask and -mask") ;
       automask = 1 ; iarg++ ; continue ;
     }

     /**==========   -matrix  ==========**/

     if( strcasecmp(argv[iarg],"-matrix") == 0 ){
       if( ++iarg >= argc ) ERROR_exit("Need argument after '%s'",argv[iarg-1]) ;
       if( nelmat != NULL ) ERROR_exit("More than 1 -matrix option!?");
       nelmat = NI_read_element_fromfile( argv[iarg] ) ; /* read NIML file */
       matname = argv[iarg];
       if( nelmat == NULL || nelmat->type != NI_ELEMENT_TYPE )
         ERROR_exit("Can't process -matrix file '%s'!?",matname) ;
       iarg++ ; continue ;
     }

     /**==========   -nodata  ===========**/

     if( strcasecmp(argv[iarg],"-nodata") == 0 ){
       nodata = 1 ; iarg++ ; continue ;
     }

     /**==========   -input  ==========**/

     if( strcasecmp(argv[iarg],"-input") == 0 ){
       if( inset != NULL  ) ERROR_exit("Can't have two -input options!?") ;
       if( ++iarg >= argc ) ERROR_exit("Need argument after '%s'",argv[iarg-1]) ;
       inset = THD_open_dataset( argv[iarg] ) ;
       CHECK_OPEN_ERROR(inset,argv[iarg]) ;
       nodata = 0 ; iarg++ ; continue ;
     }

     /**==========   -prefix  =========**/

     if( strcasecmp(argv[iarg],"-prefix") == 0 ){
       if( ++iarg >= argc ) ERROR_exit("Need argument after '%s'",argv[iarg-1]) ;
       prefix = strdup(argv[iarg]) ;
       if( !THD_filename_ok(prefix) ) ERROR_exit("Illegal string after %s",argv[iarg-1]) ;
       if( verb && strcmp(prefix,"NULL") == 0 )
         INFO_message("-prefix NULL ==> no dataset will be written") ;
       iarg++ ; continue ;
     }

     /**==========   -save1D  =========**/

     if( strcasecmp(argv[iarg],"-save1D") == 0 ){
       if( ++iarg >= argc ) ERROR_exit("Need argument after '%s'",argv[iarg-1]) ;
       save1D = strdup(argv[iarg]) ;
       if( !THD_filename_ok(save1D) ) ERROR_exit("Illegal string after %s",argv[iarg-1]) ;
       iarg++ ; continue ;
     }

     /***** Loser User *****/

      ERROR_message("Unknown option: %s",argv[iarg]) ;
      suggest_best_prog_option(argv[0], argv[iarg]);
      exit(1);

   }  /* end of loop over options */

   /*----- check for errors -----*/

   if( nelmat == NULL ){ ERROR_message("No -matrix option!?") ; nerr++ ; }
   if( nerr > 0 ) ERROR_exit("Can't continue without these inputs!") ;

   if( inset != NULL ){
     nvals = DSET_NVALS(inset) ; nvox = DSET_NVOX(inset) ;
     nx = DSET_NX(inset) ; ny = DSET_NY(inset) ; nz = DSET_NZ(inset) ;
   } else {
     automask = nvals = 0 ;
     nvox = nx = ny = nz = nodata = 1 ;  /* nodata */
     mask = NULL ;
   }

   /*----- masque -----*/

   if( mask != NULL ){     /* check -mask option for compatibility */
     if( mask_nx != nx || mask_ny != ny || mask_nz != nz )
       ERROR_exit("-mask dataset grid doesn't match input dataset :-(") ;

   } else if( automask ){  /* create a mask from input dataset */
     mask = THD_automask( inset ) ;
     if( mask == NULL )
       ERROR_message("Can't create -automask from input dataset :-(") ;
     nmask = THD_countmask( nvox , mask ) ;
     if( verb || nmask < 1 )
       INFO_message("Number of voxels in automask = %d (out of %d = %.1f%%)",
                    nmask, nvox, (100.0f*nmask)/nvox ) ;
     if( nmask < 1 ) ERROR_exit("Automask is too small to process") ;

   } else if( !nodata ) {       /* create a 'mask' for all voxels */
     if( verb )
       INFO_message("No mask ==> computing for all %d voxels",nvox) ;
     mask = (byte *)malloc(sizeof(byte)*nvox) ; nmask = nvox ;
     memset( mask , 1 , sizeof(byte)*nvox ) ;

   }

   /*----- get matrix info from the NIML element -----*/

   if( verb ) INFO_message("extracting matrix info") ;

   ncmat = nelmat->vec_num ;  /* number of columns */
   ntime = nelmat->vec_len ;  /* number of rows */
   if( ntime < ncmat+2 )
     ERROR_exit("Matrix has too many columns (%d) for number of rows (%d)",ncmat,ntime) ;

   /*--- number of rows in the full matrix (without censoring) ---*/

   cgl = NI_get_attribute( nelmat , "NRowFull" ) ;
   if( cgl == NULL ) ERROR_exit("Matrix is missing 'NRowFull' attribute!") ;
   nfull = (int)strtod(cgl,NULL) ;
   if( nodata ){
     nvals = nfull ;
   } else if( nvals != nfull ){
     ERROR_exit("-input dataset has %d time points, but matrix indicates %d",
                nvals , nfull ) ;
   }

   /*--- the goodlist = mapping from matrix row index to time index
                        (which allows for possible time point censoring) ---*/

   cgl = NI_get_attribute( nelmat , "GoodList" ) ;
   if( cgl == NULL ) ERROR_exit("Matrix is missing 'GoodList' attribute!") ;
   giar = NI_decode_int_list( cgl , ";," ) ;
   if( giar == NULL || giar->num < ntime )
     ERROR_exit("Matrix 'GoodList' badly formatted?!") ;
   Ngoodlist = giar->num ; goodlist = giar->ar ;
   if( Ngoodlist != ntime )
     ERROR_exit("Matrix 'GoodList' incorrect length?!") ;
   else if( verb > 1 && Ngoodlist < nfull )
     ININFO_message("censoring reduces time series length from %d to %d",nfull,Ngoodlist) ;

   /*--- extract the matrix from the NIML element ---*/

   imX = mri_new( ntime , ncmat , MRI_float ) ;
   Xar = MRI_FLOAT_PTR(imX) ;

   if( nelmat->vec_typ[0] == NI_FLOAT ){  /* from 3dDeconvolve_f */
     float *cd ;
     for( jj=0 ; jj < ncmat ; jj++ ){
       cd = (float *)nelmat->vec[jj] ;
       for( ii=0 ; ii < ntime ; ii++ ) Xar[ii+jj*ntime] = cd[ii] ;
     }
   } else if( nelmat->vec_typ[0] == NI_DOUBLE ){  /* from 3dDeconvolve */
     double *cd ;
     for( jj=0 ; jj < ncmat ; jj++ ){
       cd = (double *)nelmat->vec[jj] ;
       for( ii=0 ; ii < ntime ; ii++ ) Xar[ii+jj*ntime] = cd[ii] ;
     }
   } else {
     ERROR_exit("Matrix file stored with illegal data type!?") ;
   }

   /*--- find the stim_times_IM option ---*/

   cgl = NI_get_attribute( nelmat , "BasisNstim") ;
   if( cgl == NULL ) ERROR_exit("Matrix doesn't have 'BasisNstim' attribute!") ;
   nbstim = (int)strtod(cgl,NULL) ;
   if( nbstim <= 0 ) ERROR_exit("Matrix 'BasisNstim' attribute is %d",nbstim) ;
   for( jj=1 ; jj <= nbstim ; jj++ ){
     sprintf(nbuf,"BasisOption_%06d",jj) ;
     cgl = NI_get_attribute( nelmat , nbuf ) ;
     if( cgl == NULL || strcmp(cgl,"-stim_times_IM") != 0 ) continue ;
     if( nst > 0 )
       ERROR_exit("More than one -stim_times_IM option was found in the matrix") ;
     nst = jj ;
     sprintf(nbuf,"BasisColumns_%06d",jj) ;
     cgl = NI_get_attribute( nelmat , nbuf ) ;
     if( cgl == NULL )
       ERROR_exit("Matrix doesn't have %s attribute!",nbuf) ;
     jst_bot = jst_top = -1 ;
     sscanf(cgl,"%d:%d",&jst_bot,&jst_top) ;
     if( jst_bot < 0 || jst_top < 0 )
       ERROR_exit("Can't decode matrix attribute %s",nbuf) ;
     if( jst_bot == jst_top )
       ERROR_exit("Matrix attribute %s shows only 1 column for -stim_time_IM:\n"
                  "      -->> 3dLSS is meant to be used when more than one stimulus\n"
                  "           time was given, and then it computes the response beta\n"
                  "           for each stim time separately. If you have only one\n"
                  "           stim time with -stim_times_IM, you can use the output\n"
                  "           dataset from 3dDeconvolve (or 3dREMLfit) to get that\n"
                  "           single beta directly.\n" , nbuf ) ;
     if( jst_bot >= jst_top || jst_top >= ncmat )
       ERROR_exit("Matrix attribute %s has illegal value: %d:%d (ncmat=%d)",nbuf,jst_bot,jst_top,ncmat) ;
     sprintf(nbuf,"BasisName_%06d",jj) ;
     cgl = NI_get_attribute( nelmat , nbuf ) ;
     if( cgl != NULL ) stlab = strdup(cgl) ;
     if( verb > 1 )
       ININFO_message("-stim_times_IM at stim #%d; cols %d..%d",jj,jst_bot,jst_top) ;
   }
   if( nst == 0 )
     ERROR_exit("Matrix doesn't have any -stim_times_IM options inside :-(") ;

   /*--- mangle matrix to segregate IM regressors from the rest ---*/

   if( verb ) INFO_message("setting up LSS vectors") ;

   imar = LSS_mangle_matrix( imX , jst_bot , jst_top ) ;
   if( imar == NULL )
     ERROR_exit("Can't compute LSS 'mangled' matrix :-(") ;

   /*--- setup for LSS computations ---*/

   imA = IMARR_SUBIM(imar,0) ;
   imC = IMARR_SUBIM(imar,1) ;
   imS = LSS_setup( imA , imC ) ; DESTROY_IMARR(imar) ;
   if( imS == NULL )
     ERROR_exit("Can't complete LSS setup :-((") ;
   nS = imS->ny ; Sar = MRI_FLOAT_PTR(imS) ;

   if( save1D != NULL ){
     mri_write_1D( save1D , imS ) ;
     if( verb ) ININFO_message("saved LSS vectors into file %s",save1D) ;
   } else if( nodata ){
     WARNING_message("-nodata used but -save1D not used ==> you get no output!") ;
   }

   if( nodata || strcmp(prefix,"NULL") == 0 ){
     INFO_message("3dLSS ends since prefix is 'NULL' or -nodata was used") ;
     exit(0) ;
   }

   /*----- create output dataset -----*/

   if( verb ) INFO_message("creating output datset in memory") ;

   outset = EDIT_empty_copy(inset) ;
   EDIT_dset_items( outset ,
                      ADN_prefix    , prefix    ,
                      ADN_datum_all , MRI_float ,
                      ADN_brick_fac , NULL      ,
                      ADN_nvals     , nS        ,
                      ADN_ntt       , nS        ,
                    ADN_none ) ;
   tross_Copy_History( inset , outset ) ;
   tross_Make_History( "3dLSS" , argc,argv , outset ) ;
   for( kk=0 ; kk < nS ; kk++ ){
     EDIT_substitute_brick( outset , kk , MRI_float , NULL ) ;
     sprintf(nbuf,"%s#%03d",stlab,kk) ;
     EDIT_BRICK_LABEL( outset , kk , nbuf ) ;
   }

   /*----- convert input dataset to vectim -----*/

   if( verb ) INFO_message("loading input dataset into memory") ;

   DSET_load(inset) ; CHECK_LOAD_ERROR(inset) ;
   inset_mrv = THD_dset_to_vectim( inset , mask , 0 ) ;
   DSET_unload(inset) ;

   /*----- compute dot products, store results -----*/

   if( verb ) INFO_message("computing away, me buckos!") ;

   nvec = inset_mrv->nvec ;
   for( kk=0 ; kk < nS ; kk++ ){
     ss = Sar + kk*ntime ;
     oo = DSET_ARRAY(outset,kk) ;
     for( iv=0 ; iv < nvec ; iv++ ){
       fv = VECTIM_PTR(inset_mrv,iv) ;
       for( sum=0.0f,ii=0 ; ii < ntime ; ii++ )
         sum += ss[ii] * fv[goodlist[ii]] ;
       oo[inset_mrv->ivec[iv]] = sum ;
     }
   }

   DSET_write(outset) ; WROTE_DSET(outset) ;

   /*-------- Hasta la vista, baby --------*/

   if( verb )
     INFO_message("3dLSS finished: total CPU=%.2f Elapsed=%.2f",
                  COX_cpu_time() , COX_clock_time() ) ;
   exit(0) ;
}
Ejemplo n.º 10
0
MRI_IMAGE * LSS_setup( MRI_IMAGE *ima , MRI_IMAGE *imc )
{
   int nn, mm, nc, ii, jj, ic , nwarn=0 ;
   float *cc, *pp, *qq, *qj, *vv, *ss, *pv , cj, cvdot, pc ;
   MRI_IMAGE *ims , *imp , *imq ;
   MRI_IMARR *imar ;

ENTRY("LSS_setup") ;

   if( ima == NULL || imc == NULL ){  /* bad user */
     ERROR_message("LSS_setup: NULL input image?!") ;
     RETURN(NULL) ;
   }

   /* [A] is nn X mm ; [C] is nn x nc */

   nn = ima->nx ; mm = ima->ny ; nc = imc->ny ; cc = MRI_FLOAT_PTR(imc) ;

   if( imc->nx != nn || nn <= mm+2 ){  /* stoopid user */
     ERROR_message("LSS_setup: ima->nx=%d does not equal imc->nx=%d :-(" ,
                   ima->nx,imc->nx) ;
     RETURN(NULL) ;
   }

   /* get imp = [P] = psinv of [A] = mm X nn matrix
          imq = [Q] = ortproj onto column null space of [A] = nn X nn matrix */

   mri_matrix_psinv_svd(1) ;
   imar = mri_matrix_psinv_ortproj( ima , 1 ) ;

   if( imar == NULL ){  /* should not happen */
     ERROR_message("LSS_setup: cannot compute pseudo-inverse :-(") ;
     RETURN(NULL) ;
   }

   imp = IMARR_SUBIM(imar,0) ; pp = MRI_FLOAT_PTR(imp) ;
   imq = IMARR_SUBIM(imar,1) ; qq = MRI_FLOAT_PTR(imq) ;

   /* create output image = [S] = nn X nc
      Each column of [S] is the vector that we
      dot into a data vector [z] to get the estimate of
      gamma+delta for the corresponding column from [C] */

   ims = mri_new(nn,nc,MRI_float) ; ss = MRI_FLOAT_PTR(ims) ;

   /* workspace vectors */

   vv = (float *)malloc(sizeof(float)*nn) ;  /* will be [Q] [c] */

   pv = (float *)malloc(sizeof(float)*nn) ;  /* last row of [P] */
   for( ii=0 ; ii < nn ; ii++ ) pv[ii] = pp[ mm-1 + ii*mm ] ;

   /* loop over columns of [C] (and [S]) */

   for( ic=0 ; ic < nc ; ic++,cc+=nn,ss+=nn ){

     /* compute [v] = [Q] [c] */

     for( ii=0 ; ii < nn ; ii++ ) vv[ii] = 0.0f ;     /* initialize [v] to 0 */
     for( jj=0 ; jj < nn ; jj++ ){                 /* loop over columns of Q */
       qj = qq + jj*nn ;                         /* ptr to jj-th column of Q */
       cj = cc[jj] ;                                   /* jj-th value of [c] */
       for( ii=0 ; ii < nn ; ii++ ) vv[ii] += qj[ii] * cj ;  /* sum into [v] */
     }

     /* compute cvdot = [c] *dot* [v]
                cj    = [c] *dot* [c]
                pc    = [c] *dot* {last row of [P] = pv} */

     for( pc=cj=cvdot=ii=0 ; ii < nn ; ii++ ){
       cvdot += cc[ii]*vv[ii] ; cj += cc[ii]*cc[ii] ; pc += pv[ii]*cc[ii] ;
     }

     /* initialize [s] = last row of [P] */

     for( ii=0 ; ii < nn ; ii++ ) ss[ii] = pv[ii] ;

     /* If cvdot is zero(ish), this means that the extra column [c]
        is collinear(ish) with the columns of [A], and we skip the next step.
        Note that since [Q] is an orthogonal matrix,
        we are guaranteed that L2norm([Q][c]) == L2norm([c]),
        which implies that abs(cvdot) <= abs(cj), by the triangle inequality. */

     if( fabsf(cvdot) >= 1.e-5*cj ){

       /* add the proper fraction of [v] into [s] */

       pc = (1.0f - pc) / cvdot ;
       for( ii=0 ; ii < nn ; ii++ ) ss[ii] += pc * vv[ii] ;
     } else {
       nwarn++ ;
     }

   } /* end of loop over columns of [C] */

   if( verb && nwarn > 0 )
     INFO_message("%d (out of %d) LSS individual estimators were collinear",
                  nwarn , nc ) ;

   /* toss the trash and return the output set of columns */

   free(pv) ; free(vv) ; DESTROY_IMARR(imar) ; RETURN(ims) ;
}
Ejemplo n.º 11
0
int main( int argc , char *argv[] )
{
   int iarg , ii,jj,kk,mm , nvec , do_one=0 , nx=0,ny , ff, doterse = 0 ;
   MRI_IMAGE *tim ;
   MRI_IMARR *tar ;
   double sum , *eval , *amat , **tvec , *bmat , *svec ;
   float *far ;
   int demean=0 , docov=0 ;
   char *matname ;
   int okzero = 0;

   mainENTRY("1ddot main"); machdep();
   /* options */

   iarg = 1 ; nvec = 0 ;
   while( iarg < argc && argv[iarg][0] == '-' ){

     if (strcmp(argv[iarg],"-help") == 0 || strcmp(argv[iarg],"-h") == 0){
       usage_1ddot(strlen(argv[iarg])>3 ? 2:1);
       exit(0);
     }

     if( strcmp(argv[iarg],"-one") == 0 ){
       demean = 0 ; do_one = 1 ; iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-okzero") == 0 ){
       okzero = 1 ; iarg++ ; continue ;
     }

     if( strncmp(argv[iarg],"-dem",4) == 0 ){
       demean = 1 ; do_one = 0 ; iarg++ ; continue ;
     }

     if( strncmp(argv[iarg],"-cov",4) == 0 ){
       docov = 1 ; iarg++ ; continue ;
     }

     if( strncmp(argv[iarg],"-inn",4) == 0 ){
       docov = 2 ; iarg++ ; continue ;
     }

     if( strcasecmp(argv[iarg],"-rank")     == 0 ||
         strcasecmp(argv[iarg],"-spearman") == 0   ){
       do_one = 0; docov = 3; demean = 0; doterse = 1; iarg++; continue;
     }

     if( strncmp(argv[iarg],"-terse",4) == 0 ){
       doterse = 1 ; iarg++ ; continue ;
     }

     fprintf(stderr,"** Unknown option: %s\n",argv[iarg]);
     suggest_best_prog_option(argv[0], argv[iarg]);
     exit(1);
   }

   if( argc < 2 ){ usage_1ddot(1); exit(0) ; }

   if( iarg == argc ) ERROR_exit("No 1D files on command line!?") ;

   /* input 1D files */

   ff = iarg ;
   INIT_IMARR(tar) ; if( do_one ) nvec = 1 ;
   for( ; iarg < argc ; iarg++ ){
     tim = mri_read_1D( argv[iarg] ) ;
     if( tim == NULL ){
       fprintf(stderr,"** Can't read 1D file %s\n",argv[iarg]); exit(1);
     }
     if( nx == 0 ){
       nx = tim->nx ;
     } else if( tim->nx != nx ){
       fprintf(stderr,"** 1D file %s doesn't match first file in length!\n",
               argv[iarg]); exit(1);
     }
     nvec += tim->ny ;
     ADDTO_IMARR(tar,tim) ;
   }

   if (!doterse) {
      printf("\n") ;
      printf("++ 1ddot input vectors:\n") ;
   }
   jj = 0 ;
   if( do_one ){
     if (!doterse) printf("00..00: all ones\n") ;
     jj = 1 ;
   }
   for( mm=0 ; mm < IMARR_COUNT(tar) ; mm++ ){
     tim = IMARR_SUBIM(tar,mm) ;
     if (!doterse) printf("%02d..%02d: %s\n", jj,jj+tim->ny-1, argv[ff+mm] ) ;
     jj += tim->ny ;
   }

   /* create vectors from 1D files */

   tvec = (double **) malloc( sizeof(double *)*nvec ) ;
   svec = (double * ) malloc( sizeof(double  )*nvec ) ;
   for( jj=0 ; jj < nvec ; jj++ )
     tvec[jj] = (double *) malloc( sizeof(double)*nx ) ;

   kk = 0 ;
   if( do_one ){
     svec[0] = 1.0 / sqrt((double)nx) ;
     for( ii=0 ; ii < nx ; ii++ ) tvec[0][ii] = 1.0 ;
     kk = 1 ;
   }

   for( mm=0 ; mm < IMARR_COUNT(tar) ; mm++ ){
     tim = IMARR_SUBIM(tar,mm) ;
     far = MRI_FLOAT_PTR(tim) ;
     for( jj=0 ; jj < tim->ny ; jj++,kk++ ){
       for( ii=0 ; ii < nx ; ii++ ) tvec[kk][ii] = far[ii+jj*nx] ;
       if( demean ){
         sum = 0.0 ;
         for( ii=0 ; ii < nx ; ii++ ) sum += tvec[kk][ii] ;
         sum /= nx ;
         for( ii=0 ; ii < nx ; ii++ ) tvec[kk][ii] -= sum ;
       }
       sum = 0.0 ;
       for( ii=0 ; ii < nx ; ii++ ) sum += tvec[kk][ii] * tvec[kk][ii] ;
       if( sum == 0.0 ) {
         if (okzero) svec[kk] = 0.0;
         else ERROR_exit("Input column %02d is all zero!",kk) ;
       } else {
         svec[kk] = 1.0 / sqrt(sum) ;
       }
     }
   }
   DESTROY_IMARR(tar) ;

   /* normalize vectors? (for ordinary correlation) */

   if( !docov ){
     for( kk=0 ; kk < nvec ; kk++ ){
       sum = svec[kk] ;
       for( ii=0 ; ii < nx ; ii++ ) tvec[kk][ii] *= sum ;
     }
   }

   switch(docov){
     default:
     case 3:  matname = "Spearman"     ; break ;
     case 2:  matname = "InnerProduct" ; break ;
     case 1:  matname = "Covariance"   ; break ;
     case 0:  matname = "Correlation"  ; break ;
   }

   /* create matrix from dot product of vectors */

   amat = (double *) calloc( sizeof(double) , nvec*nvec ) ;

   if( docov != 3 ){
     for( kk=0 ; kk < nvec ; kk++ ){
       for( jj=0 ; jj <= kk ; jj++ ){
         sum = 0.0 ;
         for( ii=0 ; ii < nx ; ii++ ) sum += tvec[jj][ii] * tvec[kk][ii] ;
         amat[jj+nvec*kk] = sum ;
         if( jj < kk ) amat[kk+nvec*jj] = sum ;
       }
     }
   } else {  /* Spearman */
     for( kk=0 ; kk < nvec ; kk++ ){
       for( jj=0 ; jj <= kk ; jj++ ){
         amat[jj+nvec*kk] = THD_spearman_corr_dble( nx , tvec[jj] , tvec[kk] ) ;
         if( jj < kk ) amat[kk+nvec*jj] = amat[jj+nvec*kk] ;
       }
     }
   }

   /* normalize */
   if (docov==1) {
      for( kk=0 ; kk < nvec ; kk++ ){
         for( jj=0 ; jj <= kk ; jj++ ){
            sum = amat[jj+nvec*kk] / (double) (nx-1);
            amat[jj+nvec*kk] = sum;
            if( jj < kk ) amat[kk+nvec*jj] = sum ;
         }
      }
   }

   /* print matrix out */

   if (!doterse) {
      printf("\n"
             "++ %s Matrix:\n   ",matname) ;
      for( jj=0 ; jj < nvec ; jj++ ) printf("    %02d    ",jj) ;
      printf("\n   ") ;
      for( jj=0 ; jj < nvec ; jj++ ) printf(" ---------") ;
      printf("\n") ;
   }
   for( kk=0 ; kk < nvec ; kk++ ){
     if (!doterse) printf("%02d:",kk) ;
     for( jj=0 ; jj < nvec ; jj++ ) printf(" %9.5f",amat[jj+kk*nvec]) ;
     printf("\n") ;
   }

   if (doterse) exit(0) ; /* au revoir */

   /* compute eigendecomposition */

   eval = (double *) malloc( sizeof(double)*nvec ) ;
   symeig_double( nvec , amat , eval ) ;

   printf("\n"
          "++ Eigensolution of %s Matrix:\n   " , matname ) ;
   for( jj=0 ; jj < nvec ; jj++ ) printf(" %9.5f",eval[jj]) ;
   printf("\n   ") ;
   for( jj=0 ; jj < nvec ; jj++ ) printf(" ---------") ;
   printf("\n") ;
   for( kk=0 ; kk < nvec ; kk++ ){
     printf("%02d:",kk) ;
     for( jj=0 ; jj < nvec ; jj++ ) printf(" %9.5f",amat[kk+jj*nvec]) ;
     printf("\n") ;
   }

   /* compute matrix inverse */
   if ( eval[0]/eval[nvec-1] < 1.0e-10) {
      printf("\n"
             "-- WARNING: Matrix is near singular,\n"
             "            rubbish likely for inverses ahead.\n");
   }
   for( jj=0 ; jj < nvec ; jj++ ) eval[jj] = 1.0 / eval[jj] ;

   bmat = (double *) calloc( sizeof(double) , nvec*nvec ) ;

   for( ii=0 ; ii < nvec ; ii++ ){
     for( jj=0 ; jj < nvec ; jj++ ){
       sum = 0.0 ;
       for( kk=0 ; kk < nvec ; kk++ )
         sum += amat[ii+kk*nvec] * amat[jj+kk*nvec] * eval[kk] ;
       bmat[ii+jj*nvec] = sum ;
     }
   }

   printf("\n") ;
   printf("++ %s Matrix Inverse:\n   " , matname ) ;
   for( jj=0 ; jj < nvec ; jj++ ) printf("    %02d    ",jj) ;
   printf("\n   ") ;
   for( jj=0 ; jj < nvec ; jj++ ) printf(" ---------") ;
   printf("\n") ;
   for( kk=0 ; kk < nvec ; kk++ ){
     printf("%02d:",kk) ;
     for( jj=0 ; jj < nvec ; jj++ ) printf(" %9.5f",bmat[jj+kk*nvec]) ;
     printf("\n") ;
   }

   /* square roots of diagonals of the above */

   printf("\n") ;
   printf("++ %s sqrt(diagonal)\n   ",matname) ;
   for( jj=0 ; jj < nvec ; jj++ ) printf(" %9.5f",sqrt(bmat[jj+jj*nvec])) ;
   printf("\n") ;

   /* normalize matrix inverse */

   for( ii=0 ; ii < nvec ; ii++ ){
     for( jj=0 ; jj < nvec ; jj++ ){
       sum = bmat[ii+ii*nvec] * bmat[jj+jj*nvec] ;
       if( sum > 0.0 )
         amat[ii+jj*nvec] = bmat[ii+jj*nvec] / sqrt(sum) ;
       else
         amat[ii+jj*nvec] = 0.0 ;
     }
   }

   printf("\n") ;
   printf("++ %s Matrix Inverse Normalized:\n   " , matname ) ;
   for( jj=0 ; jj < nvec ; jj++ ) printf("    %02d    ",jj) ;
   printf("\n   ") ;
   for( jj=0 ; jj < nvec ; jj++ ) printf(" ---------") ;
   printf("\n") ;
   for( kk=0 ; kk < nvec ; kk++ ){
     printf("%02d:",kk) ;
     for( jj=0 ; jj < nvec ; jj++ ) printf(" %9.5f",amat[jj+kk*nvec]) ;
     printf("\n") ;
   }

   /* done */

   exit(0) ;
}
Ejemplo n.º 12
0
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);
}
Ejemplo n.º 13
0
char * IMREG_main( PLUGIN_interface * plint )
{
    MCW_idcode * idc ;                          /* input dataset idcode */
    THD_3dim_dataset * old_dset , * new_dset ;  /* input and output datasets */
    char * new_prefix , * str ;                 /* strings from user */
    int base , ntime , datum , nx,ny,nz , ii,kk , npix ;
    float                      dx,dy,dz ;
    MRI_IMARR * ims_in , * ims_out ;
    MRI_IMAGE * im , * imbase ;

    byte   ** bptr = NULL , ** bout = NULL ;
    short  ** sptr = NULL , ** sout = NULL ;
    float  ** fptr = NULL , ** fout = NULL ;

    float * dxar = NULL , * dyar = NULL , * phiar = NULL ;

    /*--------------------------------------------------------------------*/
    /*----- Check inputs from AFNI to see if they are reasonable-ish -----*/

    /*--------- go to first input line ---------*/

    PLUTO_next_option(plint) ;

    idc      = PLUTO_get_idcode(plint) ;   /* get dataset item */
    old_dset = PLUTO_find_dset(idc) ;      /* get ptr to dataset */
    if( old_dset == NULL )
        return "*************************\n"
               "Cannot find Input Dataset\n"
               "*************************"  ;

    ntime = DSET_NUM_TIMES(old_dset) ;
    if( ntime < 2 )
        return "*****************************\n"
               "Dataset has only 1 time point\n"
               "*****************************"  ;

    ii = DSET_NVALS_PER_TIME(old_dset) ;
    if( ii > 1 )
        return "************************************\n"
               "Dataset has > 1 value per time point\n"
               "************************************"  ;

    nx = old_dset->daxes->nxx ;
    dx = old_dset->daxes->xxdel ;
    ny = old_dset->daxes->nyy ;
    dy = old_dset->daxes->yydel ;
    npix = nx*ny ;
    nz = old_dset->daxes->nzz ;
    dz = old_dset->daxes->zzdel ;

    if( nx != ny || fabs(dx) != fabs(dy) ) {

#ifdef IMREG_DEBUG
        fprintf(stderr,"\nIMREG: nx=%d ny=%d nz=%d  dx=%f dy=%f dz=%f\n",
                nx,ny,nz,dx,dy,dz ) ;
#endif

        return "***********************************\n"
               "Dataset does not have square slices\n"
               "***********************************"  ;
    }

    new_prefix = PLUTO_get_string(plint) ;   /* get string item (the output prefix) */
    if( ! PLUTO_prefix_ok(new_prefix) )      /* check if it is OK */
        return "************************\n"
               "Output Prefix is illegal\n"
               "************************"  ;

    /*--------- go to next input line ---------*/

    PLUTO_next_option(plint) ;

    base = PLUTO_get_number(plint) ;
    if( base >= ntime )
        return "********************\n"
               "Base value too large\n"
               "********************"  ;

    /*--------- see if the 3rd option line is present --------*/

    str = PLUTO_get_optiontag( plint ) ;
    if( str != NULL ) {
        float fsig , fdxy , fdph ;
        fsig = PLUTO_get_number(plint) * 0.42466090 ;
        fdxy = PLUTO_get_number(plint) ;
        fdph = PLUTO_get_number(plint) ;
        mri_align_params( 0 , 0.0,0.0,0.0 , fsig,fdxy,fdph ) ;
        /* fprintf(stderr,"Set fine params = %f %f %f\n",fsig,fdxy,fdph) ; */
    }

    /*------------- ready to compute new dataset -----------*/

#ifdef IMREG_DEBUG
    fprintf(stderr,"IMREG: loading dataset\n") ;
#endif

    DSET_load( old_dset ) ;

    /*** 1) Copy the dataset in toto ***/

#ifdef IMREG_DEBUG
    fprintf(stderr,"IMREG: Copying dataset\n") ;
#endif

    new_dset = PLUTO_copy_dset( old_dset , new_prefix ) ;
    if( new_dset == NULL )
        return "****************************\n"
               "Failed to copy input dataset\n"
               "****************************"  ;

    /*** 2) Make an array of empty images ***/

#ifdef IMREG_DEBUG
    fprintf(stderr,"IMREG: making empty images\n") ;
#endif

    datum = DSET_BRICK_TYPE(new_dset,0) ;

    INIT_IMARR(ims_in) ;
    for( ii=0 ; ii < ntime ; ii++ ) {
        im = mri_new_vol_empty( nx , ny , 1 , datum ) ;
        ADDTO_IMARR(ims_in,im) ;
    }

    imbase = mri_new_vol_empty( nx , ny , 1 , datum ) ;

    dxar  = (float *) malloc( sizeof(float) * ntime ) ;
    dyar  = (float *) malloc( sizeof(float) * ntime ) ;
    phiar = (float *) malloc( sizeof(float) * ntime ) ;

    /*** 3) Get pointers to sub-bricks in old and new datasets ***/

#ifdef IMREG_DEBUG
    fprintf(stderr,"IMREG: getting input brick pointers\n") ;
#endif

    switch( datum ) { /* pointer type depends on input datum type */
    case MRI_byte:
        bptr = (byte **) malloc( sizeof(byte *) * ntime ) ;
        bout = (byte **) malloc( sizeof(byte *) * ntime ) ;
        for( ii=0 ; ii < ntime ; ii++ ) {
            bptr[ii] = (byte *) DSET_ARRAY(old_dset,ii) ;
            bout[ii] = (byte *) DSET_ARRAY(new_dset,ii) ;
        }
        break ;

    case MRI_short:
        sptr = (short **) malloc( sizeof(short *) * ntime ) ;
        sout = (short **) malloc( sizeof(short *) * ntime ) ;
        for( ii=0 ; ii < ntime ; ii++ ) {
            sptr[ii] = (short *) DSET_ARRAY(old_dset,ii) ;
            sout[ii] = (short *) DSET_ARRAY(new_dset,ii) ;
        }

#ifdef IMREG_DEBUG
        fprintf(stderr,"IMREG: sptr[0] = %p  sout[0] = %p\n",sptr[0],sout[0]) ;
#endif

        break ;

    case MRI_float:
        fptr = (float **) malloc( sizeof(float *) * ntime ) ;
        fout = (float **) malloc( sizeof(float *) * ntime ) ;
        for( ii=0 ; ii < ntime ; ii++ ) {
            fptr[ii] = (float *) DSET_ARRAY(old_dset,ii) ;
            fout[ii] = (float *) DSET_ARRAY(new_dset,ii) ;
        }
        break ;
    }

    /*** 4) Loop over slices ***/

    PLUTO_popup_meter(plint) ;

    for( kk=0 ; kk < nz ; kk++ ) {

        /*** 4a) Setup ims_in images to point to input slices ***/

#ifdef IMREG_DEBUG
        fprintf(stderr,"IMREG: slice %d -- setup input images\n",kk) ;
#endif

        for( ii=0 ; ii < ntime ; ii++ ) {
            im = IMARR_SUBIMAGE(ims_in,ii) ;
            switch( datum ) {
            case MRI_byte:
                mri_fix_data_pointer( bptr[ii] + kk*npix, im ) ;
                break ;
            case MRI_short:
                mri_fix_data_pointer( sptr[ii] + kk*npix, im ) ;
                break ;
            case MRI_float:
                mri_fix_data_pointer( fptr[ii] + kk*npix, im ) ;
                break ;
            }
        }

        /*** 4b) Setup im to point to base image ***/

#ifdef IMREG_DEBUG
        fprintf(stderr,"IMREG: slice %d -- setup base image\n",kk) ;
#endif

        switch( datum ) {
        case MRI_byte:
            mri_fix_data_pointer( bptr[base] + kk*npix, imbase ) ;
            break ;
        case MRI_short:
            mri_fix_data_pointer( sptr[base] + kk*npix, imbase ) ;
            break ;
        case MRI_float:
            mri_fix_data_pointer( fptr[base] + kk*npix, imbase ) ;
            break ;
        }

        /*** 4c) Register this slice at all times ***/

#ifdef IMREG_DEBUG
        fprintf(stderr,"IMREG: slice %d -- register\n",kk) ;
#endif

        ims_out = mri_align_dfspace( imbase , NULL , ims_in ,
                                     ALIGN_REGISTER_CODE , dxar,dyar,phiar ) ;

        if( ims_out == NULL )
            fprintf(stderr,"IMREG: mri_align_dfspace return NULL\n") ;

        /*** 4d) Put the output back in on top of the input;
                 note that the output is always in MRI_float format ***/

#ifdef IMREG_DEBUG
        fprintf(stderr,"IMREG: slice %d -- put output back into dataset\n",kk) ;
#endif

        for( ii=0 ; ii < ntime ; ii++ ) {
            switch( datum ) {
            case MRI_byte:
                im = mri_to_mri( MRI_byte , IMARR_SUBIMAGE(ims_out,ii) ) ;
                memcpy( bout[ii] + kk*npix , MRI_BYTE_PTR(im) , sizeof(byte)*npix ) ;
                mri_free(im) ;
                break ;

            case MRI_short:
#ifdef IMREG_DEBUG
                if( ii==0 )fprintf(stderr,"IMREG: conversion to short at ii=%d\n",ii) ;
#endif

                im = mri_to_mri( MRI_short , IMARR_SUBIMAGE(ims_out,ii) ) ;

#ifdef IMREG_DEBUG
                if( ii==0 )fprintf(stderr,"IMREG: copying to %p from %p\n",sout[ii] + kk*npix,MRI_SHORT_PTR(im)) ;
#endif

                memcpy( sout[ii] + kk*npix , MRI_SHORT_PTR(im) , sizeof(short)*npix ) ;

#ifdef IMREG_DEBUG
                if( ii==0 )fprintf(stderr,"IMREG: freeing\n") ;
#endif

                mri_free(im) ;
                break ;

            case MRI_float:
                im = IMARR_SUBIMAGE(ims_out,ii) ;
                memcpy( fout[ii] + kk*npix , MRI_FLOAT_PTR(im) , sizeof(float)*npix ) ;
                break ;
            }
        }

        PLUTO_set_meter(plint, (100*(kk+1))/nz ) ;

        /*** 4e) Destroy the output images ***/

#ifdef IMREG_DEBUG
        fprintf(stderr,"IMREG: destroying aligned output\n") ;
#endif

        DESTROY_IMARR( ims_out ) ;
    }

    /*** 5) Destroy the empty images and other workspaces ***/

#ifdef IMREG_DEBUG
    fprintf(stderr,"IMREG: destroy workspaces\n") ;
#endif

    mri_clear_data_pointer(imbase) ;
    mri_free(imbase) ;
    for( ii=0 ; ii < ntime ; ii++ ) {
        im = IMARR_SUBIMAGE(ims_in,ii) ;
        mri_clear_data_pointer(im) ;
    }
    DESTROY_IMARR(ims_in) ;
    FREE_WORKSPACE ;

    /*------------- let AFNI know about the new dataset ------------*/

#ifdef IMREG_DEBUG
    fprintf(stderr,"IMREG: send result to AFNI\n") ;
#endif

    PLUTO_add_dset( plint , new_dset , DSET_ACTION_MAKE_CURRENT ) ;

    return NULL ;  /* null string returned means all was OK */
}
Ejemplo n.º 14
0
int main( int argc , char *argv[] )
{
   int force=0 ; /* KRH loudly deprecating usage 04/13/05/ */
   int iarg=1 ;
   THD_3dim_dataset *dset ;    /* output dataset */
   int nvals , ii , jj , kk ;

   MRI_IMARR *anar ;      /* stuff from ANALYZE headers */
   MRI_IMAGE *anim ;
   int nxan=0,nyan=0,nzan=0 , an_datum=0 , an_swapped=0 ;
   float dxan=-1.0,dyan=0.0,dzan=0.0 ;
   char anor[8] = "\0" ;

   THD_ivec3 nxyz , orixyz ;
   THD_fvec3 dxyz , orgxyz ;

   float TR=1.0 ; int tunits=UNITS_SEC_TYPE ;
   int is_fbuc=0 , is_abuc=0 , is_3dtime=0 ;
   int view_type=VIEW_ORIGINAL_TYPE ;
   char *prefix="a2a" ;
   int xorient=-1, yorient=-1, zorient=-1 ;
   int use_zoff=0,use_xoff=0,use_yoff=0 ; float zoff=0.0,xoff=0.0,yoff=0.0 ;
   THD_3dim_dataset *gset=NULL ;  /* geometry parent */
   float *fac ;

   char **flab , *fatr ;

   /*-- help the poor user? --*/

   if( argc < 2 || strcmp(argv[1],"-help") == 0 ){ A2A_help(); exit(0); }

   mainENTRY("3dANALYZEtoAFNI main"); machdep(); PRINT_VERSION("3dANALYZEtoAFNI");

   /*-- parse options --*/

   while( iarg < argc && argv[iarg][0] == '-' ){

     /* -prefix */

     if( strcmp(argv[iarg],"-prefix") == 0 ){
       if( ++iarg >= argc ){
         fprintf(stderr,"** -prefix needs an argument!\n"); exit(1);
       }
       prefix = argv[iarg] ;
       if( !THD_filename_ok(prefix) ){
         fprintf(stderr,"** Illegal prefix!\n"); exit(1);
       }
       if( strstr(prefix,"/") != NULL ){
         fprintf(stderr,"** Can't use directory names in the prefix!\n"); exit(1);
       }
       iarg++ ; continue ;
     }

     /* -view */

     if( strcmp(argv[iarg],"-view") == 0 ){
       char *str ;
       if( ++iarg >= argc ){
         fprintf(stderr,"** -view needs an argument!\n"); exit(1);
       }
       str = argv[iarg] ; if( str[0] == '+' ) str++ ;
       for( ii=FIRST_VIEW_TYPE ; ii <= LAST_VIEW_TYPE ; ii++ )
         if( strcmp(str,VIEW_codestr[ii]) == 0 ) break ;

       if( ii <= LAST_VIEW_TYPE ){
         view_type = ii ;
       } else {
         fprintf(stderr,"** Illegal -view code!\n"); exit(1);
       }
       iarg++ ; continue ;
     }

     /* -zorigin */

     if( strcmp(argv[iarg],"-zorigin") == 0 ){
       if( ++iarg >= argc ){
         fprintf(stderr,"** -zorigin needs an argument!\n"); exit(1);
       }
       zoff = strtod( argv[iarg] , NULL ) ;
       use_zoff = 1 ;
       iarg++ ; continue ;
     }

     /* -orient */

#define ORCODE(aa) \
  ( (aa)=='R' ? ORI_R2L_TYPE : (aa)=='L' ? ORI_L2R_TYPE : \
    (aa)=='P' ? ORI_P2A_TYPE : (aa)=='A' ? ORI_A2P_TYPE : \
    (aa)=='I' ? ORI_I2S_TYPE : (aa)=='S' ? ORI_S2I_TYPE : ILLEGAL_TYPE )

#define OR3OK(x,y,z) ( ((x)&6) + ((y)&6) + ((z)&6) == 6 )

     if( strcmp(argv[iarg],"-orient") == 0 ){
       char acod ;

       if( ++iarg >= argc ){
         fprintf(stderr,"** -orient needs an argument!\n"); exit(1);
       }
       if( strlen(argv[iarg]) != 3 ){
         fprintf(stderr,"** Illegal -orient code!\n"); exit(1);
       }
       acod = toupper(argv[iarg][0]) ; xorient = ORCODE(acod) ;
       acod = toupper(argv[iarg][1]) ; yorient = ORCODE(acod) ;
       acod = toupper(argv[iarg][2]) ; zorient = ORCODE(acod) ;
       if( xorient<0 || yorient<0 || zorient<0 ||
           ! OR3OK(xorient,yorient,zorient)      ){
         fprintf(stderr,"** Unusable -orient code!\n"); exit(1);
       }
       iarg++ ; continue ;
     }

      /* -geomparent */

     if( strcmp(argv[iarg],"-geomparent") == 0 ){
       if( ++iarg >= argc ){
         fprintf(stderr,"** -geomparent needs an argument!\n"); exit(1);
       }
       gset = THD_open_dataset( argv[iarg] ); CHECK_OPEN_ERROR(gset,argv[iarg]);
       iarg++ ; continue ;
     }

     /* -TR */

     if( strcmp(argv[iarg],"-TR") == 0 ){
       char *eptr ;
       if( ++iarg >= argc ){
         fprintf(stderr,"** -geomparent needs an argument!\n"); exit(1);
       }
       TR = strtod( argv[iarg] , &eptr ) ;
       if( TR <= 0.0 ){
         fprintf(stderr,"** -TR needs a positive value after it!\n"); exit(1);
       }

       if( strcmp(eptr,"ms")==0 || strcmp(eptr,"msec")==0 ){
          tunits = UNITS_MSEC_TYPE ;
          WARNING_message("TR in millisecond units is deprecated.") ;
       } else if( strcmp(eptr,"s")==0 || strcmp(eptr,"sec")==0 ){
          tunits = UNITS_SEC_TYPE ;
       } else if( strcmp(eptr,"Hz")==0 || strcmp(eptr,"Hertz")==0 ){
          tunits = UNITS_HZ_TYPE ;
       }

       is_3dtime = 1 ; is_abuc = is_fbuc = 0 ;
       iarg++ ; continue ;
     }

     /* -fbuc */

     if( strcmp(argv[iarg],"-fbuc") == 0 ){
       is_fbuc = 1 ; is_abuc = is_3dtime = 0 ;
       iarg++ ; continue ;
     }

     /* -abuc */

     if( strcmp(argv[iarg],"-abuc") == 0 ){
       is_abuc = 1 ; is_fbuc = is_3dtime = 0 ;
       iarg++ ; continue ;
     }

     /* -OK */

     if( strcmp(argv[iarg],"-OK") == 0 ){
       force = 1 ;
       iarg++ ; continue ;
     }

     /** don't know this one **/

     fprintf(stderr,"** Illegal option %s\n",argv[iarg]); exit(1);
   }

   if (!force) { A2A_help(); exit(0);
   }

   /*-- check number of remaining args --*/

   nvals = argc - iarg ;
   if( nvals <= 0 ){
     fprintf(stderr,"** No ANALYZE files on command line!?\n"); exit(1);
   }

   /*-- try to read each ANALYZE file and glean info from it --*/

   CLEAR_MRILIB_globals ;  /* setup */

   fac = (float *) malloc(sizeof(float)*nvals) ;

   for( ii=iarg ; ii < argc ; ii++ ){

     if( strstr(argv[ii],"/") != NULL ){
       fprintf(stderr,"** ANALYZE files must all be in current directory!\n") ;
       exit(1) ;
     }

     anar = mri_read_analyze75( argv[ii] ) ;  /* read it */

     if( anar == NULL || IMARR_COUNT(anar) == 0 ){
       fprintf(stderr,"** Can't read %s as ANALYZE-75 format .hdr file!\n",argv[ii]);
       exit(1) ;
     }

     anim = IMARR_SUBIM(anar,0) ;     /* first 2D image */

     fac[ii-iarg] = anim->dv ;        /* save scale factor, if any */

     if( ii == iarg ){                /* first time in: store header values */

       nxan = anim->nx ; nyan = anim->ny ; nzan = IMARR_COUNT(anar) ;
       if( MRILIB_orients[0] != '\0' ) strcpy(anor,MRILIB_orients) ;
       an_datum = anim->kind ;
       if( anim->dw > 0.0 ){ dxan = anim->dx; dyan = anim->dy; dzan = anim->dz; }
       an_swapped = anim->was_swapped ;

     } else {                         /* check later sub-bricks */

       if( nxan != anim->nx || nyan != anim->ny || nzan != IMARR_COUNT(anar) ){
         fprintf(stderr,"** File %s has different dimensions than %s\n",
                 argv[ii] , argv[iarg] ) ;
         exit(1) ;
       }
       if( an_datum != anim->kind ){
         fprintf(stderr,"** File %s has different kind of data than %s\n",
                 argv[ii] , argv[iarg] ) ;
         exit(1) ;
       }
       if( an_swapped != anim->was_swapped ){
         fprintf(stderr,"** File %s %s byte-swapped, but %s %s\n",
                 argv[ii]   , (anim->was_swapped) ? "is" : "isn't" ,
                 argv[iarg] , (an_swapped)        ? "is" : "isn't"  ) ;
         exit(1) ;
       }
       if( anim->dw > 0.0 ){
         if( dxan < 0.0 ){
           dxan = anim->dx; dyan = anim->dy; dzan = anim->dz;
         } else {
           if( dxan != anim->dx || dyan != anim->dy || dzan != anim->dz ){
             fprintf(stderr,"++ WARNING: File %s has variant voxel sizes!\n",
                     argv[ii]) ;
           }
         }
       }
       if( anor[0] == '\0' && MRILIB_orients[0] != '\0' )
         strcpy(anor,MRILIB_orients) ;

     } /* end of checking later volumes for compatibility */

     /* destroy this data (we've sucked it dry) */

     DESTROY_IMARR(anar) ;

  } /* end of loop over ANALYZE files */

  /*-- check geomparent, if present --*/

  if( gset != NULL ){

    if( DSET_NX(gset)!=nxan || DSET_NY(gset)!=nyan || DSET_NZ(gset)!=nzan ){
      fprintf(stderr,"** geomparent and ANALYZE files have different dimensions!\n");
      exit(1) ;
    }

    if( xorient >= 0 ){
      fprintf(stderr,"++ WARNING: geomparent overrides -orient!\n") ;
    }
    xorient = gset->daxes->xxorient ;
    yorient = gset->daxes->yyorient ;
    zorient = gset->daxes->zzorient ;

    if( use_zoff ){
      fprintf(stderr,"++ WARNING: geomparent overrides -zorigin!\n") ;
    }
    use_xoff = use_yoff = use_zoff = 1 ;
    xoff = gset->daxes->xxorg ;
    yoff = gset->daxes->yyorg ;
    zoff = gset->daxes->zzorg ;

    dxan = gset->daxes->xxdel ;
    dyan = gset->daxes->yydel ;
    dzan = gset->daxes->zzdel ;

    if( gset->taxis != NULL ){
       TR     = gset->taxis->ttdel ;
       tunits = gset->taxis->units_type ;
    }

    DSET_delete(gset) ;  /* delete to save memory */

  } else {         /* don't have geomparent, so check if other data is OK */

    if( xorient < 0 ){
      xorient = ORI_R2L_TYPE ;
      yorient = ORI_A2P_TYPE ;
      zorient = ORI_I2S_TYPE ;
      fprintf(stderr,"++ WARNING: orientation defaults to RAI\n") ;
    }

    if( dxan <= 0.0 ){
      dxan = dyan = dzan = 1.0 ;
      fprintf(stderr,"++ WARNING: voxel size defaults to 1 mm\n") ;
    }

    if( ORIENT_sign[xorient] == '-' ) dxan = -dxan ;
    if( ORIENT_sign[yorient] == '-' ) dyan = -dyan ;
    if( ORIENT_sign[zorient] == '-' ) dzan = -dzan ;

  } /* end of setup for new dataset parameters */

  /*-- At last: create empty output dataset --*/

  dset = EDIT_empty_copy(NULL) ;

  nxyz.ijk[0] = nxan ; dxyz.xyz[0] = dxan ;
  nxyz.ijk[1] = nyan ; dxyz.xyz[1] = dyan ;
  nxyz.ijk[2] = nzan ; dxyz.xyz[2] = dzan ;

  orixyz.ijk[0] = xorient ;
  orixyz.ijk[1] = yorient ;
  orixyz.ijk[2] = zorient ;

  orgxyz.xyz[0] = (use_xoff) ? xoff : -0.5*(nxan-1)*dxan ;
  orgxyz.xyz[1] = (use_yoff) ? yoff : -0.5*(nyan-1)*dyan ;
  orgxyz.xyz[2] = (use_zoff) ? zoff : -0.5*(nzan-1)*dzan ;

  EDIT_dset_items( dset ,
                     ADN_prefix      , prefix ,
                     ADN_datum_all   , an_datum ,
                     ADN_nxyz        , nxyz ,
                     ADN_xyzdel      , dxyz ,
                     ADN_xyzorg      , orgxyz ,
                     ADN_xyzorient   , orixyz ,
                     ADN_nvals       , nvals ,
                     ADN_view_type   , view_type ,
                     ADN_brick_fac   , fac ,
                   ADN_none ) ;

  /*-- select dataset type (3D+time or bucket) --*/

  if( nvals == 1 && is_3dtime ){
    is_3dtime = 0; is_abuc = 1;
    fprintf(stderr,"++ WARNING: can't make a 3D+time dataset from 1 volume!\n") ;
  }

  if( !is_3dtime && !is_abuc && !is_fbuc ){
    if( nvals > 1 ) is_3dtime = 1 ;
    else            is_abuc   = 1 ;
  }

  if( is_3dtime ){
    EDIT_dset_items( dset ,
                       ADN_ntt      , nvals ,
                       ADN_ttorg    , 0.0 ,
                       ADN_ttdel    , TR ,
                       ADN_ttdur    , 0.0 ,
                       ADN_tunits   , tunits ,
                       ADN_type     , HEAD_ANAT_TYPE ,
                       ADN_func_type, ANAT_EPI_TYPE ,
                     ADN_none ) ;
  } else if( is_abuc ){
    EDIT_dset_items( dset ,
                       ADN_type     , HEAD_ANAT_TYPE ,
                       ADN_func_type, ANAT_BUCK_TYPE ,
                     ADN_none ) ;
  } else if( is_fbuc ){
    EDIT_dset_items( dset ,
                       ADN_type     , HEAD_FUNC_TYPE ,
                       ADN_func_type, FUNC_BUCK_TYPE ,
                     ADN_none ) ;
  }

  /*-- make filename array and store it in dataset header --*/

  flab = (char **) malloc(sizeof(char *)*nvals) ;

  kk = 0 ;
  for( ii=0 ; ii < nvals ; ii++ ){
    jj = strlen( argv[iarg+ii] ) ;             /* convert .hdr */
    flab[ii] = strdup( argv[iarg+ii] ) ;       /* filename to */
    strcpy( flab[ii]+jj-3 , "img" ) ;          /* .img name  */
    kk += (jj+2) ;
    THD_store_datablock_label( dset->dblk , ii , flab[ii] ) ;
  }

  fatr = malloc(kk) ; fatr[0] = '\0' ;         /* all filenames */
  for( ii=0 ; ii < nvals ; ii++ ){             /* into one big */
    strcat(fatr,flab[ii] ); strcat(fatr," ");  /* string      */
    free(flab[ii]) ;
  }

  /*-- setting this attribute marks the dataset as being
       stored by volumes, rather than all data in one .BRIK file --*/

  THD_set_string_atr( dset->dblk , "VOLUME_FILENAMES" , fatr ) ;
  free(fatr) ; free(flab) ;

  /*-- set byte ordering flag --*/

  jj = mri_short_order() ;  /* order of this CPU */

  if( an_swapped )
    dset->dblk->diskptr->byte_order = REVERSE_ORDER(jj) ;
  else
    dset->dblk->diskptr->byte_order = jj ;

  /*-- set history attribute --*/

  tross_Make_History( "3dANALYZEtoAFNI" , argc,argv , dset ) ;

  /*-- write dataset header --*/

  THD_write_3dim_dataset( NULL,NULL , dset , False ) ;
  fprintf(stderr,"++ Wrote dataset header %s\n",DSET_HEADNAME(dset)) ;
  exit(0) ;
}