Example #1
0
void conv_model( float *  gs      , int     ts_length ,
                 float ** x_array , float * ts_array   )
{
   int ii, jj,jbot,jtop , kk , nid_top,nid_bot ;
   int cur_debug = 0;
   float top , val , max0, max1 ;

   static int     iter = -1;     /* iteration number */
   static int     do_scale = 0;  /* scale the curves by 1/height */

   static int     nid = 0 ;      /* number of pts in impulse */
   static float * fid0 = NULL ;  /* impulse response function */
   static float * fid1 = NULL ;  /* impulse response function */

   /*----- check for env vars -----*/

   iter++ ;
   if( iter == 0 ) {
      double dval = AFNI_numenv("AFNI_MODEL_DITER");
      if( dval >= 1.0 ) g_diter = (int)dval;  /* zero is failure */
      dval = AFNI_numenv("AFNI_MODEL_DEBUG");
      if( dval >= 1.0 ) g_debug = (int)dval;
      if(g_debug) fprintf(stderr,"\n+d TR = %f\n", x_array[1][1]-x_array[0][1]);
      do_scale = ! AFNI_noenv("AFNI_CONVDIFFGAM_DO_SCALE");
   }

   /*** make sure there is a reference function to convolve with ***/

   if( refnum <= 0 ) conv_set_ref( 0 , NULL ) ;

   /* to clean up, particularly as a parameter */
   cur_debug =  (iter == g_diter || (iter == 0 && g_debug > 1));
   if( cur_debug ) disp_floats("+d params: ", gs, 8);

   /*** initialize the output ***/

   for( ii=0 ; ii < ts_length ; ii++ ) ts_array[ii] = 0.0 ;

   /*** initialize the impulse response ***/

   if( nid < ts_length ){              /* make some space for it */
      if( fid0 ) free(fid0) ;
      if( fid1 ) free(fid1) ;
      nid = ts_length ;
      fid0 = (float *) malloc( sizeof(float) * nid ) ;
      fid1 = (float *) malloc( sizeof(float) * nid ) ;
   }

   /* compute first and second impulse functions */
   gamma_model(gs,   ts_length, x_array, fid0, do_scale, cur_debug);
   gamma_model(gs+4, ts_length, x_array, fid1, do_scale, cur_debug);

   max0 = test_n_truncate(fid0, ts_length, cur_debug);
   max1 = test_n_truncate(fid1, ts_length, cur_debug);

   /* find first and last nonzero value */
   for( nid_bot=0 ; nid_bot < ts_length ; nid_bot++ )
      if( fid0[nid_bot] != 0.0 || fid1[nid_bot] != 0.0 ) break ;
   for( nid_top=ts_length-1 ; nid_top > nid_bot ; nid_top-- )
      if( fid0[nid_top] != 0.0 || fid1[nid_top] != 0.0 ) break ;

   /*** loop over each nonzero point in the reference ***/

   for( ii=0 ; ii < refnz ; ii++ ){
      kk  = refin[ii] ; if( kk >= ts_length ) break ;
      val = refts[kk] ;

      /*** for each point in the impulse ***/

      jtop = ts_length - kk ; if( jtop > nid_top ) jtop = nid_top+1 ;
      for( jj=nid_bot ; jj < jtop ; jj++ )
         ts_array[kk+jj] += val * ( fid0[jj] - fid1[jj] ) ;
   }

   if( cur_debug ) disp_floats("+d conv    : ", ts_array, ts_length);

   return ;
}
Example #2
0
MRI_IMAGE * mri_warp3D_align_one( MRI_warp3D_align_basis *bas, MRI_IMAGE *im )
{
   float *fit , *dfit , *qfit , *tol ;
   int iter , good,ngood , ii, pp , skip_first ;
   MRI_IMAGE *tim , *fim ;
   float *pmat=MRI_FLOAT_PTR(bas->imps) , /* pseudo inverse: n X m matrix */
         *tar , tv , sfit ;
   int n=bas->imps->nx ,          /* = nfree+1 */
       m=bas->imps->ny ,          /* = imap->nx = length of ima */
    npar=bas->nparam   ,          /* = number of warp parameters */
   nfree=bas->nfree    ,          /* = number of free warp parameters */
    *ima=MRI_INT_PTR(bas->imap) , /* = indexes in fim of voxels to use */
    *pma ;                        /* = map of free to total params */
   int ctstart ;
   int do_twopass=(bas->imps_blur != NULL && bas->twoblur > 0.0f) , passnum=1 ;
   int blur_pass ;
   char      *save_prefix ;
   static int save_index=0 ;

#define AITMAX  3.33
#define NMEM    5
   float *fitmem[NMEM] ;
   int mm , last_aitken , num_aitken=0 ;
   float  sdif , fitdif[NMEM] ;   /* 28 Sep 2005 */
   int    num_bad_diff ;
   float  best_dif , best_par[999] ;  /* 09 Jan 2006 */
   int    best_ite=0 ;

ENTRY("mri_warp3D_align_one") ;

   ctstart = NI_clock_time() ;

   save_prefix = getenv("AFNI_WARPDRIVE_SAVER") ;

   /** pma[k] = external parameter index for the k-th free parameter **/

   pma = (int *)malloc(sizeof(int) * nfree) ;
   for( pp=ii=0 ; ii < npar ; ii++ )
     if( !bas->param[ii].fixed ) pma[pp++] = ii ;

#if 0
fprintf(stderr,"pma=") ;
for(pp=0;pp<nfree;pp++)fprintf(stderr," %d",pma[pp]);
fprintf(stderr,"\n") ;
#endif

   fit  = (float *)malloc(sizeof(float) * npar ) ;
   dfit = (float *)malloc(sizeof(float) * npar ) ;
   qfit = (float *)malloc(sizeof(float) * nfree) ;
   tol  = (float *)malloc(sizeof(float) * npar ) ;

   for( mm=0 ; mm < NMEM ; mm++ ) fitmem[mm] = NULL ;
   for( mm=0 ; mm < NMEM ; mm++ ) fitdif[mm] = 3.e+33 ;

   /*--- loop back point for two pass alignment ---*/

   bas->num_iter = 0 ;
   mri_warp3D_set_womask( bas->imsk ) ;

 ReStart:

   best_dif  = -666.0f ;                     /* 09 Jan 2006 */
   blur_pass = (do_twopass && passnum==1) ;
   mri_warp3D_method( blur_pass ? MRI_LINEAR : bas->regmode ) ;

   /* load initial fit parameters;
      if they are all the identity transform value,
      then skip the first transformation of the fim volume */

   if( passnum == 1 ){
     skip_first = 1 ;
     for( pp=0 ; pp < npar ; pp++ ){
       if( bas->param[pp].fixed ){
         fit[pp] = bas->param[pp].val_fixed ;
       } else {
         fit[pp] = bas->param[pp].val_init ;
       }
       skip_first = skip_first && (fit[pp] == bas->param[pp].ident) ;
     }
   } else {
     skip_first = 0 ;  /* and fit[] is unchanged */
   }

   fitmem[0] = (float *)malloc(sizeof(float)*npar) ;
   memcpy( fitmem[0] , fit , sizeof(float)*npar ) ;

   for( pp=0 ; pp < npar ; pp++ ) tol[pp] = bas->param[pp].toler ;

   if( blur_pass ){
     float fac = (1.0f+bas->twoblur) ;
     if( fac < 3.0f ) fac = 3.0f ;
     for( pp=0 ; pp < npar ; pp++ ) tol[pp] *= fac ;
   }

   if( bas->verb )
     fprintf(stderr,"++ mri_warp3D_align_one: START PASS #%d\n",passnum) ;

   /* setup base image for registration into fim,
      and pseudo-inverse of base+derivative images into pmat */

   if( blur_pass ){             /* first pass ==> registering blurred images */
     float *far , blur=bas->twoblur ;
     int nx=im->nx , ny=im->ny , nz=im->nz ;
     fim = mri_to_float( im ) ; far = MRI_FLOAT_PTR(fim) ;
     EDIT_blur_volume_3d( nx,ny,nz ,       1.0f,1.0f,1.0f ,
                          MRI_float , far, blur,blur,blur  ) ;
     pmat = MRI_FLOAT_PTR(bas->imps_blur) ;
   } else {                           /* registering original image */
     if( im->kind == MRI_float ) fim = im ;
     else                        fim = mri_to_float( im ) ;
     pmat = MRI_FLOAT_PTR(bas->imps) ;
   }

   /******** iterate fit ********/

   iter = 0 ; good = 1 ; last_aitken = 3 ; num_bad_diff = 0 ;
   while( good ){
     if( skip_first ){
       tim = fim ; skip_first = 0 ;
     } else {
       bas->vwset( npar , fit ) ;                     /**************************/
       tim = mri_warp3D( fim , 0,0,0 , bas->vwfor ) ; /* warp on current params */
     }                                                /**************************/
     tar = MRI_FLOAT_PTR(tim) ;

     sdif = mri_scaled_diff( bas->imbase , tim , bas->imsk ) ;
     if( bas->verb )
       fprintf(stderr,"++++++++++ Start iter=%d  RMS_diff=%g\n",iter+1,sdif) ;

     if( best_dif < 0.0f || sdif < best_dif ){        /* 09 Jan 2006 */
       best_dif = sdif ; best_ite = iter ;
       memcpy( best_par , fit , sizeof(float)*npar ) ;
     }

     /* find least squares fit of base + derivatives to warped image */

     sfit = 0.0f ;
     for( pp=0 ; pp < npar  ; pp++ ) dfit[pp] = 0.0f ;
     for( pp=0 ; pp < nfree ; pp++ ) qfit[pp] = 0.0f ;
     for( ii=0 ; ii < m ; ii++ ){
       tv = tar[ima[ii]] ; sfit += P(nfree,ii) * tv ;
       for( pp=0 ; pp < nfree ; pp++ ) qfit[pp] += P(pp,ii) * tv ;
     }
     if( tim != fim ) mri_free( tim ) ;
#if 0
fprintf(stderr,"qfit=");
for(pp=0;pp<nfree;pp++)fprintf(stderr," %g",qfit[pp]);
fprintf(stderr,"\n") ;
#endif
     for( pp=0 ; pp < nfree ; pp++ ) dfit[pma[pp]] = qfit[pp] ;
     for( pp=0 ; pp < npar  ; pp++ ){
       fit[pp] += dfit[pp] ;
            if( fit[pp] > bas->param[pp].max ) fit[pp] = bas->param[pp].max ;
       else if( fit[pp] < bas->param[pp].min ) fit[pp] = bas->param[pp].min ;
     }

     if( bas->verb ){
       fprintf(stderr,"+   Delta:") ;
       for( pp=0 ; pp < npar ; pp++ ) fprintf(stderr," %13.6g",dfit[pp]) ;
       fprintf(stderr,"\n") ;
       fprintf(stderr,"+   Total: scale factor=%g\n"
                      "+  #%5d:",sfit,iter+1) ;
       for( pp=0 ; pp < npar ; pp++ ) fprintf(stderr," %13.6g", fit[pp]) ;
       fprintf(stderr,"\n") ;
     }

     /* save fit results for a while into the past, and then maybe do Aitken */

     if( fitmem[NMEM-1] != NULL ) free((void *)fitmem[NMEM-1]) ;
     for( mm=NMEM-1 ; mm > 0 ; mm-- ) fitmem[mm] = fitmem[mm-1] ;
     fitmem[0] = (float *)malloc(sizeof(float)*npar) ;
     memcpy( fitmem[0] , fit , sizeof(float)*npar ) ;

     /* 28 Sep 2005: if RMS went up, back off the changes! */

     for( mm=NMEM-1 ; mm > 0 ; mm-- ) fitdif[mm] = fitdif[mm-1] ;
     fitdif[0] = sdif ;

     if( iter > 1          && num_bad_diff < 2                   &&
         fitmem[1] != NULL && fitdif[0]    > 1.0666f * fitdif[1]   ){
       for( pp=0 ; pp < npar ; pp++ )
         fit[pp] = 0.5 * ( fitmem[0][pp] + fitmem[1][pp] ) ;
       memcpy( fitmem[0] , fit , sizeof(float)*npar ) ;
       last_aitken = iter+1 ; num_bad_diff++ ;
       if( bas->verb )
         fprintf(stderr,"+++ RMS_diff changes too much! Shrinking!\n") ;
     } else {
       num_bad_diff = 0 ;
     }

     iter++ ;
     if( iter > last_aitken+NMEM && !AFNI_noenv("AFNI_WARPDRIVE_AITKEN") ){
       double s0,s1,s2 , dd , de,df ;
       num_aitken = 0 ;
       for( pp=0 ; pp < npar ; pp++ ){
         dd = fabs(fitmem[1][pp]-fit[pp]) ;
         if( dd <= tol[pp] ) continue ; /* done here */
         de = dd ;
         for( mm=2 ; mm < NMEM ; mm++ ){
           df = fabs(fitmem[mm][pp]-fitmem[mm-1][pp]) ;
           if( df <= de ) break ;
           de = df ;
         }
         if( mm == NMEM ){  /* do Aitken */
           s2 = fit[pp] ; s1 = fitmem[1][pp] ; s0 = fitmem[2][pp] ;
           de = ( (s2-s1) - (s1-s0) ) ;
           if( de != 0.0 ){
             de = -(s2-s1)*(s2-s1) / de ; dd *= AITMAX ;
             if( fabs(de) > dd ){ de = (de > 0.0) ? dd : -dd ; }
             fit[pp] += de ;
                  if( fit[pp] > bas->param[pp].max ) fit[pp] = bas->param[pp].max ;
             else if( fit[pp] < bas->param[pp].min ) fit[pp] = bas->param[pp].min ;
             num_aitken++ ;
           }
         }
       }
       if( num_aitken > 0 ) last_aitken = iter ;

       if( bas->verb && num_aitken > 0 ){
         fprintf(stderr,"+   Aitken on %d params:\n"
                        "+________:",num_aitken) ;
         for( pp=0 ; pp < npar ; pp++ ){
           if( fit[pp] != fitmem[0][pp] ){
             fprintf(stderr," %13.6g", fit[pp]) ; fitmem[0][pp] = fit[pp] ;
           } else {
             fprintf(stderr," _____________") ;
           }
         }
         fprintf(stderr,"\n") ;
       }
     }

     /* save intermediate image? */

     if( save_prefix != NULL ){
       char sname[THD_MAX_NAME] ; FILE *fp ;
       mri_warp3D_set_womask( NULL ) ;        /* must warp the whole thing */
       bas->vwset( npar , fit ) ;
       tim = mri_warp3D( fim , 0,0,0 , bas->vwfor ) ;
       tar = MRI_FLOAT_PTR(tim) ;
       mri_warp3D_set_womask( bas->imsk ) ;
       sprintf(sname,"%s_%04d.mmm",save_prefix,save_index++) ;
       fprintf(stderr,"+   Saving intermediate image to binary file %s\n",sname) ;
       fp = fopen( sname , "w" ) ;
       if( fp != NULL ){
         fwrite( tar, tim->pixel_size, tim->nvox, fp ) ; fclose(fp) ;
       }

       if( bas->vwdet != NULL ){
         int i,j,k , nx=tim->nx,ny=tim->ny,nz=tim->nz ;
         for( k=0 ; k < nz ; k++ ){
          for( j=0 ; j < ny ; j++ ){
           for( i=0 ; i < nx ; i++ ){
             tar[i+(j+k*ny)*nx] = bas->vwdet( (float)i,(float)j,(float)k ) ;
         }}}
         sprintf(sname,"%s_%04d.ddd",save_prefix,save_index-1) ;
         fprintf(stderr,"+   Saving determinant image to binary file %s\n",sname) ;
         fp = fopen( sname , "w" ) ;
         if( fp != NULL ){
           fwrite( tar, tim->pixel_size, tim->nvox, fp ) ; fclose(fp) ;
         }
       }
       mri_free( tim ) ;
     }

     /* loop back for more iterations? */

     if( last_aitken == iter ) continue ;  /* don't test, just loop */
     if( fitmem[2]   == NULL ) continue ;

     ngood = 0 ;
     for( pp=0 ; pp < npar ; pp++ )
       if( !bas->param[pp].fixed )
         ngood += ( ( fabs(fitmem[1][pp]-fitmem[0][pp]) <= tol[pp] ) &&
                    ( fabs(fitmem[2][pp]-fitmem[1][pp]) <= tol[pp] )   ) ;

     good = (ngood < nfree) && (iter < bas->max_iter) ;

   } /******** end while loop for iteration of fitting procedure ********/

   for( mm=0 ; mm < NMEM ; mm++ )
     if( fitmem[mm] != NULL ){ free((void *)fitmem[mm]); fitmem[mm] = NULL; }

   /*--- 09 Jan 2006: if prior best fit was better than current, replace ---*/

   if( best_dif > 0.0f && 1.0666f*best_dif < sdif ){
     memcpy( fit , best_par , sizeof(float)*npar ) ;
     if( bas->verb )
       fprintf(stderr,"+++++ Replacing final fit with iter #%d's fit +++++\n",
               best_ite+1) ;
   }

   /*--- do the second pass? ---*/

   if( blur_pass ){
     if( bas->verb )
       fprintf(stderr,"+++++++++++++ Loop back for next pass +++++++++++++\n");
     mri_free(fim) ; fim = NULL ; passnum++ ; goto ReStart ;
   } else {
     if( bas->verb )
       fprintf(stderr,"+++++++++++++ Convergence test passed +++++++++++++\n");
   }

   /*--- done! ---*/

   bas->num_iter = iter ;

   for( pp=0 ; pp < npar ; pp++ ) bas->param[pp].val_out = fit[pp] ;

   /*-- do the actual realignment to get the output image --*/

   if( bas->regfinal > 0 ) mri_warp3D_method( bas->regfinal ) ;
   mri_warp3D_set_womask( NULL ) ;
   bas->vwset( npar , fit ) ;
   tim = mri_warp3D( fim , 0,0,0 , bas->vwfor ) ;

   if( fim != im ) mri_free(fim) ;  /* if it was a copy, junk it */
   free((void *)dfit) ; free((void *)fit) ;
   free((void *)qfit) ; free((void *)pma) ; free((void *)tol) ;

   if( bas->verb ){
     double st = (NI_clock_time()-ctstart) * 0.001 ;
     fprintf(stderr,"++ mri_warp3D_align_one EXIT: %.2f seconds elapsed\n",st) ;
   }

   RETURN( tim ) ;
}
THD_session * THD_init_session( char *sessname )
{
    THD_session            *sess ;
    XtPointer_array        *dblk_arrarr ;
    THD_datablock_array    *dblk_arr ;
    THD_3dim_dataset       *dset=NULL , *temp_dset;
    THD_3dim_dataset_array *dset_arr ;

    int ibar , idset , iview  , nds , qview=-666 ;

    ENTRY("THD_init_session") ;

    /*-- sanity check --*/

    if( sessname == NULL || strlen(sessname) == 0 || !THD_is_directory(sessname) )
        RETURN( NULL ) ;

    /*-- initialize session --*/

    sess         = myXtNew( THD_session ) ;
    sess->type   = SESSION_TYPE ;
    sess->parent = NULL ;
#ifdef DEBUG_SESSIONS
    fprintf(stderr, "blanking session\n");
#endif
    BLANK_SESSION(sess) ;  /* null out all entries */

    /* save directory name, with a trailing slash */

    MCW_strncpy( sess->sessname , sessname , THD_MAX_NAME ) ;
    iview = strlen(sess->sessname) ;
    if( sess->sessname[iview-1] != '/' ) { /* tack trailing / onto sessname */
        sess->sessname[iview]   = '/' ;
        sess->sessname[iview+1] = '\0' ;
    } else {
        iview-- ;  /* iview now points to last non-NUL character in string */
    }

    /* save last name from sessname */
#if 1
    {   char *env = my_getenv( "AFNI_SESSTRAIL" ) ;
        int tt = 0 ;
        if( env != NULL ) tt = strtol(env,NULL,10) ;
        env = THD_trailname(sess->sessname,tt) ;
        tt = 1+strlen(env) - THD_MAX_NAME ;
        if( tt < 0 ) tt = 0 ;
        strcpy( sess->lastname , env+tt ) ;
    }
#else
    for( iview-- ; iview >= 0 ; iview-- )
        if( sess->sessname[iview] == '/' ) break ;
    MCW_strncpy( sess->lastname, &(sess->sessname[iview+1]), THD_MAX_NAME ) ;
#endif

    /*-- override dataset 'view'??  [30 May 2013] --*/

    {   char *env = my_getenv("AFNI_OVERRIDE_VIEW") ;
        if( env != NULL ) {
            if( toupper(*env) == 'T' ) qview = VIEW_TALAIRACH_TYPE ;
            else if( toupper(*env) == 'O' ) qview = VIEW_ORIGINAL_TYPE  ;
            else
                WARNING_message("AFNI_OVERRIDE_VIEW=%s is not understood",env) ;
        }
    }

    /*-- read all datablocks --*/

    dblk_arrarr = THD_init_alldir_datablocks( sess->sessname ) ;

    /*-- for each datablock array ... --*/

    for( ibar=0 ; ibar < dblk_arrarr->num ; ibar++ ) {

        /*-- get the current array of datablocks --*/

        dblk_arr = (THD_datablock_array *) dblk_arrarr->ar[ibar] ;
        if( dblk_arr == NULL || dblk_arr->num <= 0 ) continue ;    /* huh? */

        /*-- convert it into an array of datasets --*/

        dset_arr = THD_array_3dim_from_block( dblk_arr ) ;
        if( dset_arr == NULL || dset_arr->num <= 0 ) continue ;

        /*-- place it into the next row of the THD_session [28 Jul 2003] --*/

        nds = sess->num_dsset ;

        if( nds >= THD_MAX_SESSION_SIZE ) {  /* bad! */
            fprintf(stderr,
                    "\n*** Session %s table overflow with dataset %s ***\n",
                    sessname , dset_arr->ar[0]->self_name) ;
            for( idset=0 ; idset < dset_arr->num ; idset++ )
                THD_delete_3dim_dataset( dset_arr->ar[idset] , False ) ;
            FREE_3DARR(dset_arr) ;
            continue ;  /* skip to next dblk_arr (ibar loop) */
        }

        /*-- put each dataset into this row in its view place --*/

        for( idset=0 ; idset < dset_arr->num ; idset++ ) {
            dset  = dset_arr->ar[idset] ;
            iview = dset->view_type ;
            if( qview >= 0 ) iview = qview ;  /* 30 May 2013 */

            if( GET_SESSION_DSET(sess,nds,iview) != NULL ) { /* should never happen */
                fprintf(stderr,
                        "\n*** Session %s has duplicate dataset views of %s ***\n",
                        sessname , dset->self_name) ;
                THD_delete_3dim_dataset( dset , False ) ;
            } else {
#ifdef DEBUG_SESSIONS
                fprintf(stderr,"\nputting datasets into initial view \n");
#endif
                SET_SESSION_DSET(dset, sess, nds, iview);  /* should always happen */
                /*        sess->dsset_xform_table[nds][iview] = dset ; */  /* should always happen */
            }
        }

        sess->num_dsset ++ ;  /* one more row */

        FREE_3DARR(dset_arr) ;

    } /* end of loop over each datablock array (ibar) */

    /*-- throw away the datablock arrays at this point --*/

    STATUS("trashing dblk_arrarr") ;

    for( ibar=0 ; ibar < dblk_arrarr->num ; ibar++ ) {
        dblk_arr = (THD_datablock_array *) dblk_arrarr->ar[ibar] ;
        FREE_DBARR( dblk_arr ) ;
    }
    FREE_XTARR( dblk_arrarr ) ;

    /*-- 29 Oct 2001: try to read .mnc "datasets" --*/

    if( !AFNI_noenv("AFNI_MINC_DATASETS") ) {
        char ename[THD_MAX_NAME] , **fn_minc , *eee ;
        int num_minc , ii ;

        STATUS("looking for MINC files") ;

        strcpy(ename,sess->sessname) ;
        strcat(ename,"*.mnc") ;
        eee = ename ;
        MCW_file_expand( 1,&eee , &num_minc,&fn_minc ) ;  /* find files */

        if( num_minc > 0 ) {                              /* got some! */
            STATUS("opening MINC files") ;
            for( ii=0 ; ii < num_minc ; ii++ ) {            /* loop over files */
                dset = THD_open_minc( fn_minc[ii] ) ;         /* try it on */
                if( !ISVALID_DSET(dset) ) continue ;          /* doesn't fit? */
                nds = sess->num_dsset ;
                if( nds >= THD_MAX_SESSION_SIZE ) {
                    fprintf(stderr,
                            "\n*** Session %s table overflow with MINC dataset %s ***\n",
                            sessname , fn_minc[ii] ) ;
                    THD_delete_3dim_dataset( dset , False ) ;
                    break ; /* out of for loop */
                }
                iview = dset->view_type ;
                SET_SESSION_DSET(dset, sess, nds, iview);
                /*         sess->dsset_xform_table[nds][iview] = dset ;*/
                sess->num_dsset ++ ;
            } /* end of loop over files */
            MCW_free_expand( num_minc , fn_minc ) ;
        } /* end of if we found MINC files */
    }

    /*-- 06 Apr 2005: try to read NIfTI-1 files [KRH and RWC] --*/

    if( !AFNI_noenv("AFNI_NIFTI_DATASETS") ) {
        char *ename[2] , **fn_nifti ;
        int num_nifti , ii ;

        STATUS("looking for NIFTI files") ;

        ename[0] = AFMALL(char, THD_MAX_NAME) ;
        ename[1] = AFMALL(char, THD_MAX_NAME) ;
        strcpy(ename[0],sess->sessname) ;
        strcat(ename[0],"*.nii") ;
        strcpy(ename[1],sess->sessname) ;
        strcat(ename[1],"*.nii.gz") ;
        MCW_file_expand( 2,ename , &num_nifti,&fn_nifti ) ;  /* find files */
        free(ename[0]) ;
        free(ename[1]) ;

        if( num_nifti > 0 ) {                              /* got some! */
            STATUS("opening NIFTI files") ;
            for( ii=0 ; ii < num_nifti ; ii++ ) {            /* loop over files */
                dset = THD_open_nifti( fn_nifti[ii] ) ;        /* try it on */
                if( !ISVALID_DSET(dset) ) continue ;           /* doesn't fit? */
                nds = sess->num_dsset ;
                if( nds >= THD_MAX_SESSION_SIZE ) {
                    fprintf(stderr,
                            "\n*** Session %s table overflow with NIfTI dataset %s ***\n",
                            sessname , fn_nifti[ii] ) ;
                    THD_delete_3dim_dataset( dset , False ) ;
                    break ; /* out of for loop */
                }
                iview = dset->view_type ;
                SET_SESSION_DSET(dset, sess, nds, iview);
                /*         sess->dsset_xform_table[nds][iview] = dset ;*/
                sess->num_dsset ++ ;
            } /* end of loop over files */
            MCW_free_expand( num_nifti , fn_nifti ) ;
        } /* end of if we found NIFTI files */
    }
Example #4
0
int main( int argc , char *argv[] )
{
   int nx,ny,nz , nxyz , ii,kk , num1,num2 , num_tt=0 , iv ,
       piece , fim_offset;
   float dx,dy,dz , dxyz ,
         num1_inv=0.0 , num2_inv , num1m1_inv=0.0 , num2m1_inv , dof ,
         dd,tt,q1,q2 , f1,f2 , tt_max=0.0 ;
   THD_3dim_dataset *dset=NULL , *new_dset=NULL ;
   THD_3dim_dataset * base_dset;
   float *av1 , *av2 , *sd1 , *sd2 , *ffim , *gfim ;
   float *base_ary=NULL;

   void  *vsp ;
   void  *vdif ;           /* output mean difference */
   char  cbuf[THD_MAX_NAME] ;
   float fbuf[MAX_STAT_AUX] , fimfac ;
   int   output_datum ;
   float npiece , memuse ;

   float *dofbrik=NULL , *dofar=NULL ;
   THD_3dim_dataset *dof_dset=NULL ;

   /*-- read command line arguments --*/

   if( argc < 2 || strncmp(argv[1],"-help",5) == 0 ) TT_syntax(NULL) ;

   /*-- 20 Apr 2001: addto the arglist, if user wants to [RWCox] --*/

   mainENTRY("3dttest main"); machdep() ; PRINT_VERSION("3dttest") ;
   INFO_message("For most purposes, 3dttest++ should be used instead of 3dttest!") ;

   { int new_argc ; char ** new_argv ;
     addto_args( argc , argv , &new_argc , &new_argv ) ;
     if( new_argv != NULL ){ argc = new_argc ; argv = new_argv ; }
   }

   AFNI_logger("3dttest",argc,argv) ;

   TT_read_opts( argc , argv ) ;

   if( ! TT_be_quiet )
      printf("3dttest: t-tests of 3D datasets, by RW Cox\n") ;

   /*-- read first dataset in set2 to get dimensions, etc. --*/

   dset = THD_open_dataset( TT_set2->ar[0] ) ;  /* 20 Dec 1999  BDW */
   if( ! ISVALID_3DIM_DATASET(dset) )
     ERROR_exit("Unable to open dataset file %s",TT_set2->ar[0]);

   nx = dset->daxes->nxx ;
   ny = dset->daxes->nyy ;
   nz = dset->daxes->nzz ;         nxyz = nx * ny * nz ;
   dx = fabs(dset->daxes->xxdel) ;
   dy = fabs(dset->daxes->yydel) ;
   dz = fabs(dset->daxes->zzdel) ; dxyz = dx * dy * dz ;

#ifdef TTDEBUG
printf("*** nx=%d ny=%d nz=%d\n",nx,ny,nz) ;
#endif

   /*-- make an empty copy of this dataset, for eventual output --*/

#ifdef TTDEBUG
printf("*** making empty dataset\n") ;
#endif

   new_dset = EDIT_empty_copy( dset ) ;

   tross_Make_History( "3dttest" , argc,argv , new_dset ) ;

   strcpy( cbuf , dset->self_name ) ; strcat( cbuf , "+TT" ) ;

   iv = DSET_PRINCIPAL_VALUE(dset) ;

   if( TT_datum >= 0 ){
      output_datum = TT_datum ;
   } else {
      output_datum = DSET_BRICK_TYPE(dset,iv) ;
      if( output_datum == MRI_byte ) output_datum = MRI_short ;
   }

#ifdef TTDEBUG
printf(" ** datum = %s\n",MRI_TYPE_name[output_datum]) ;
#endif

   iv = EDIT_dset_items( new_dset ,
                           ADN_prefix , TT_prefix ,
                           ADN_label1 , TT_prefix ,
                           ADN_directory_name , TT_session ,
                           ADN_self_name , cbuf ,
                           ADN_type , ISHEAD(dset) ? HEAD_FUNC_TYPE : GEN_FUNC_TYPE ,
                           ADN_func_type , FUNC_TT_TYPE ,
                           ADN_nvals , FUNC_nvals[FUNC_TT_TYPE] ,
                           ADN_ntt , 0 ,                           /* 07 Jun 2007 */
                           ADN_datum_all , output_datum ,
                         ADN_none ) ;

   if( iv > 0 )
     ERROR_exit("%d errors in attempting to create output dataset!",iv ) ;

   if( THD_deathcon() && THD_is_file(new_dset->dblk->diskptr->header_name) )
      ERROR_exit(
              "Output dataset file %s already exists--cannot continue!\a",
              new_dset->dblk->diskptr->header_name ) ;

#ifdef TTDEBUG
printf("*** deleting exemplar dataset\n") ;
#endif

   THD_delete_3dim_dataset( dset , False ) ; dset = NULL ;

/** macro to test a malloc-ed pointer for validity **/

#define MTEST(ptr) \
   if((ptr)==NULL) \
      ( fprintf(stderr,"*** Cannot allocate memory for statistics!\n"), exit(0) )

   /*-- make space for the t-test computations --*/

   /* (allocate entire volumes) 13 Dec 2005 [rickr] */
                              npiece  = 3.0 ;  /* need at least this many */
   if( TT_paired )            npiece += 1.0 ;
   else if( TT_set1 != NULL ) npiece += 2.0 ;

   npiece += mri_datum_size(output_datum) / (float) sizeof(float) ;
   npiece += mri_datum_size(output_datum) / (float) sizeof(float) ;

#if 0
   piece_size = TT_workmem * MEGA / ( npiece * sizeof(float) ) ;
   if( piece_size > nxyz ) piece_size = nxyz ;

#ifdef TTDEBUG
printf("*** malloc-ing space for statistics: %g float arrays of length %d\n",
       npiece,piece_size) ;
#endif
#endif

   av2  = (float *) malloc( sizeof(float) * nxyz ) ; MTEST(av2) ;
   sd2  = (float *) malloc( sizeof(float) * nxyz ) ; MTEST(sd2) ;
   ffim = (float *) malloc( sizeof(float) * nxyz ) ; MTEST(ffim) ;
   num2 = TT_set2->num ;

   if( TT_paired ){
      av1  = sd1 = NULL ;
      gfim = (float *) malloc( sizeof(float) * nxyz ) ; MTEST(gfim) ;
      num1 = num2 ;
   } else if( TT_set1 != NULL ){
      av1  = (float *) malloc( sizeof(float) * nxyz ) ; MTEST(av1) ;
      sd1  = (float *) malloc( sizeof(float) * nxyz ) ; MTEST(sd1) ;
      gfim = NULL ;
      num1 = TT_set1->num ;
   } else {
      av1  = sd1 = NULL ;
      gfim = NULL ;
      num1 = 0 ;
   }

   vdif = (void *) malloc( mri_datum_size(output_datum) * nxyz ) ; MTEST(vdif) ;
   vsp  = (void *) malloc( mri_datum_size(output_datum) * nxyz ) ; MTEST(vsp)  ;

   /* 27 Dec 2002: make DOF dataset (if prefix is given, and unpooled is on) */

   if( TT_pooled == 0 && TT_dof_prefix[0] != '\0' ){
     dofbrik = (float *) malloc( sizeof(float) * nxyz ) ; MTEST(dofbrik) ;

     dof_dset = EDIT_empty_copy( new_dset ) ;

     tross_Make_History( "3dttest" , argc,argv , dof_dset ) ;

     EDIT_dset_items( dof_dset ,
                       ADN_prefix , TT_dof_prefix ,
                       ADN_directory_name , TT_session ,
                       ADN_type , ISHEAD(dset) ? HEAD_FUNC_TYPE : GEN_FUNC_TYPE,
                       ADN_func_type , FUNC_BUCK_TYPE ,
                       ADN_nvals , 1 ,
                       ADN_datum_all , MRI_float ,
                      ADN_none ) ;

     if( THD_is_file(dof_dset->dblk->diskptr->header_name) )
        ERROR_exit(
                "-dof_prefix dataset file %s already exists--cannot continue!\a",
                dof_dset->dblk->diskptr->header_name ) ;

     EDIT_substitute_brick( dof_dset , 0 , MRI_float , dofbrik ) ;
   }

   /* print out memory usage to edify the user */

   if( ! TT_be_quiet ){
      memuse =    sizeof(float) * nxyz * npiece
              + ( mri_datum_size(output_datum) + sizeof(short) ) * nxyz ;

      if( dofbrik != NULL ) memuse += sizeof(float) * nxyz ;  /* 27 Dec 2002 */

      printf("--- allocated %d Megabytes memory for internal use (%d volumes)\n",
             (int)(memuse/MEGA), (int)npiece) ;
   }

   mri_fix_data_pointer( vdif , DSET_BRICK(new_dset,0) ) ;  /* attach bricks */
   mri_fix_data_pointer( vsp  , DSET_BRICK(new_dset,1) ) ;  /* to new dataset */

   /** only short and float are allowed for output **/
   if( output_datum != MRI_short && output_datum != MRI_float )
      ERROR_exit("Illegal output data type %d = %s",
                 output_datum , MRI_TYPE_name[output_datum] ) ;

   num2_inv = 1.0 / num2 ;  num2m1_inv = 1.0 / (num2-1) ;
   if( num1 > 0 ){
      num1_inv = 1.0 / num1 ;  num1m1_inv = 1.0 / (num1-1) ;
   }

   /*----- loop over pieces to process the input datasets with -----*/

/** macro to open a dataset and make it ready for processing **/

#define DOPEN(ds,name)                                                            \
   do{ int pv ; (ds) = THD_open_dataset((name)) ;  /* 16 Sep 1999 */              \
       if( !ISVALID_3DIM_DATASET((ds)) )                                          \
          ERROR_exit("Can't open dataset: %s",(name)) ;                           \
       if( (ds)->daxes->nxx!=nx || (ds)->daxes->nyy!=ny || (ds)->daxes->nzz!=nz ) \
          ERROR_exit("Axes size mismatch: %s",(name)) ;                           \
       if( !EQUIV_GRIDS((ds),new_dset) )                                          \
          WARNING_message("Grid mismatch: %s",(name)) ;                           \
       if( DSET_NUM_TIMES((ds)) > 1 )                                             \
         ERROR_exit("Can't use time-dependent data: %s",(name)) ;                 \
       if( TT_use_editor ) EDIT_one_dataset( (ds), &TT_edopt ) ;                  \
       else                DSET_load((ds)) ;                                      \
       pv = DSET_PRINCIPAL_VALUE((ds)) ;                                          \
       if( DSET_ARRAY((ds),pv) == NULL )                                          \
          ERROR_exit("Can't access data: %s",(name)) ;                            \
       if( DSET_BRICK_TYPE((ds),pv) == MRI_complex )                              \
          ERROR_exit("Can't use complex data: %s",(name)) ;                       \
       break ; } while (0)

#if 0   /* can do it directly now (without offsets)  13 Dec 2005 [rickr] */
/** macro to return pointer to correct location in brick for current processing **/

#define SUB_POINTER(ds,vv,ind,ptr)                                            \
   do{ switch( DSET_BRICK_TYPE((ds),(vv)) ){                                  \
         default: ERROR_exit("Illegal datum! ***");                           \
            case MRI_short:{ short * fim = (short *) DSET_ARRAY((ds),(vv)) ;  \
                            (ptr) = (void *)( fim + (ind) ) ;                 \
            } break ;                                                         \
            case MRI_byte:{ byte * fim = (byte *) DSET_ARRAY((ds),(vv)) ;     \
                            (ptr) = (void *)( fim + (ind) ) ;                 \
            } break ;                                                         \
            case MRI_float:{ float * fim = (float *) DSET_ARRAY((ds),(vv)) ;  \
                             (ptr) = (void *)( fim + (ind) ) ;                \
            } break ; } break ; } while(0)
#endif

   /** number of pieces to process **/
   /* num_piece = (nxyz + piece_size - 1) / nxyz ; */

#if 0
   nice(2) ;  /** lower priority a little **/
#endif


   /* possibly open TT_base_dset now, and convert to floats */
   if( TT_base_dname ) {
      DOPEN(base_dset, TT_base_dname) ;
      base_ary = (float *) malloc( sizeof(float) * nxyz ) ; MTEST(base_ary) ;
      EDIT_coerce_scale_type(nxyz , DSET_BRICK_FACTOR(base_dset,0) ,
              DSET_BRICK_TYPE(base_dset,0),DSET_ARRAY(base_dset,0), /* input */
              MRI_float ,base_ary  ) ;                              /* output */
      THD_delete_3dim_dataset( base_dset , False ) ; base_dset = NULL ;
   }

   /* only 1 'piece' now   13 Dec 2005 [rickr] */
   for( piece=0 ; piece < 1 ; piece++ ){

      fim_offset = 0 ;

#ifdef TTDEBUG
printf("*** start of piece %d: length=%d offset=%d\n",piece,nxyz,fim_offset) ;
#else
      if( ! TT_be_quiet ){
         printf("--- starting piece %d/%d (%d voxels) ",piece+1,1,nxyz) ;
         fflush(stdout) ;
      }
#endif

      /** process set2 (and set1, if paired) **/

      for( ii=0 ; ii < nxyz ; ii++ ) av2[ii] = 0.0 ;
      for( ii=0 ; ii < nxyz ; ii++ ) sd2[ii] = 0.0 ;

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

         /** read in the data **/

         DOPEN(dset,TT_set2->ar[kk]) ;
         iv = DSET_PRINCIPAL_VALUE(dset) ;

#ifndef TTDEBUG
         if( ! TT_be_quiet ){ printf(".") ; fflush(stdout) ; }  /* progress */
#else
         printf(" ** opened dataset file %s\n",TT_set2->ar[kk]);
#endif

#if 0 /* fimfac will be compute when the results are ready */
         if( piece == 0 && kk == 0 ){
            fimfac = DSET_BRICK_FACTOR(dset,iv) ;
            if( fimfac == 0.0 ) fimfac = 1.0 ;
            fimfacinv = 1.0 / fimfac ;
#ifdef TTDEBUG
printf(" ** set fimfac = %g\n",fimfac) ;
#endif
         }
#endif

         /** convert it to floats (in ffim) **/
         EDIT_coerce_scale_type(nxyz , DSET_BRICK_FACTOR(dset,iv) ,
                                DSET_BRICK_TYPE(dset,iv),DSET_ARRAY(dset,iv), /* input */
                                MRI_float ,ffim  ) ;                         /* output */
         THD_delete_3dim_dataset( dset , False ) ; dset = NULL ;

         /** get the paired dataset, if present **/

         if( TT_paired ){
            DOPEN(dset,TT_set1->ar[kk]) ;
            iv = DSET_PRINCIPAL_VALUE(dset) ;

#ifndef TTDEBUG
         if( ! TT_be_quiet ){ printf(".") ; fflush(stdout) ; }  /* progress */
#else
        printf(" ** opened dataset file %s\n",TT_set1->ar[kk]);
#endif

            EDIT_coerce_scale_type(
                        nxyz , DSET_BRICK_FACTOR(dset,iv) ,
                        DSET_BRICK_TYPE(dset,iv),DSET_ARRAY(dset,iv), /* input */
                        MRI_float ,gfim  ) ;                         /* output */
            THD_delete_3dim_dataset( dset , False ) ; dset = NULL ;

            if( TT_voxel >= 0 )
              fprintf(stderr,"-- paired values #%02d: %f, %f\n",
                      kk,ffim[TT_voxel],gfim[TT_voxel]) ;

            for( ii=0 ; ii < nxyz ; ii++ ) ffim[ii] -= gfim[ii] ;
         } else if( TT_voxel >= 0 )
            fprintf(stderr,"-- set2 value #%02d: %f\n",kk,ffim[TT_voxel]);

#ifdef TTDEBUG
printf("  * adding into av2 and sd2\n") ;
#endif

         /* accumulate into av2 and sd2 */

         for( ii=0 ; ii < nxyz ; ii++ ){
            dd = ffim[ii] ; av2[ii] += dd ; sd2[ii] += dd * dd ;
         }

      }  /* end of loop over set2 datasets */

      /** form the mean and stdev of set2 **/

#ifdef TTDEBUG
printf(" ** forming mean and sigma of set2\n") ;
#endif

      for( ii=0 ; ii < nxyz ; ii++ ){
         av2[ii] *= num2_inv ;
         dd       = (sd2[ii] - num2*av2[ii]*av2[ii]) ;
         sd2[ii]  = (dd > 0.0) ? sqrt( num2m1_inv * dd ) : 0.0 ;
      }
      if( TT_voxel >= 0 )
         fprintf(stderr,"-- s2 mean = %g, sd = %g\n",
                 av2[TT_voxel],sd2[TT_voxel]) ;

      /** if set1 exists but is not paired with set2, process it now **/

      if( ! TT_paired && TT_set1 != NULL ){

         for( ii=0 ; ii < nxyz ; ii++ ) av1[ii] = 0.0 ;
         for( ii=0 ; ii < nxyz ; ii++ ) sd1[ii] = 0.0 ;

         for( kk=0 ; kk < num1 ; kk++ ){
            DOPEN(dset,TT_set1->ar[kk]) ;
            iv = DSET_PRINCIPAL_VALUE(dset) ;

#ifndef TTDEBUG
         if( ! TT_be_quiet ){ printf(".") ; fflush(stdout) ; }  /* progress */
#else
         printf(" ** opened dataset file %s\n",TT_set1->ar[kk]);
#endif

            EDIT_coerce_scale_type(
                                nxyz , DSET_BRICK_FACTOR(dset,iv) ,
                                DSET_BRICK_TYPE(dset,iv),DSET_ARRAY(dset,iv), /* input */
                                MRI_float ,ffim  ) ;                         /* output */
            THD_delete_3dim_dataset( dset , False ) ; dset = NULL ;

#ifdef TTDEBUG
printf("  * adding into av1 and sd1\n") ;
#endif

            for( ii=0 ; ii < nxyz ; ii++ ){
               dd = ffim[ii] ; av1[ii] += dd ; sd1[ii] += dd * dd ;
            }
            if( TT_voxel >= 0 )
               fprintf(stderr,"-- set1 value #%02d: %g\n",kk,ffim[TT_voxel]) ;
         }  /* end of loop over set1 datasets */

         /** form the mean and stdev of set1 **/

#ifdef TTDEBUG
printf(" ** forming mean and sigma of set1\n") ;
#endif

         for( ii=0 ; ii < nxyz ; ii++ ){
            av1[ii] *= num1_inv ;
            dd       = (sd1[ii] - num1*av1[ii]*av1[ii]) ;
            sd1[ii]  = (dd > 0.0) ? sqrt( num1m1_inv * dd ) : 0.0 ;
         }
         if( TT_voxel >= 0 )
            fprintf(stderr,"-- s1 mean = %g, sd = %g\n",
                    av1[TT_voxel], sd1[TT_voxel]) ;
      }  /* end of processing set1 by itself */

      /***** now form difference and t-statistic *****/

#ifndef TTDEBUG
         if( ! TT_be_quiet ){ printf("+") ; fflush(stdout) ; }  /* progress */
#else
         printf(" ** computing t-tests next\n") ;
#endif

#if 0 /* will do at end using EDIT_convert_dtype  13 Dec 2005 [rickr] */

      /** macro to assign difference value to correct type of array **/
#define DIFASS switch( output_datum ){                                        \
                 case MRI_short: sdar[ii] = (short) (fimfacinv*dd) ; break ;  \
                 case MRI_float: fdar[ii] = (float) dd             ; break ; }
#define TOP_SS  32700
#define TOP_TT (32700.0/FUNC_TT_SCALE_SHORT)

#endif

      if( TT_paired || TT_use_bval == 1 ){ /** case 1: paired estimate or 1-sample **/

        if( TT_paired || TT_n1 == 0 ){       /* the olde waye: 1 sample test */
          f2 = 1.0 / sqrt( (double) num2 ) ;
          for( ii=0 ; ii < nxyz ; ii++ ){
            av2[ii] -= (base_ary ? base_ary[ii] : TT_bval) ;  /* final mean */
            if( sd2[ii] > 0.0 ){
               num_tt++ ;
               tt      = av2[ii] / (f2 * sd2[ii]) ;
               sd2[ii] = tt;      /* final t-stat */

               tt = fabs(tt) ; if( tt > tt_max ) tt_max = tt ;
            } else {
               sd2[ii] = 0.0;
            }
          }
          if( TT_voxel >= 0 )
             fprintf(stderr,"-- paired/bval mean = %g, t = %g\n",
                     av2[TT_voxel], sd2[TT_voxel]) ;

        } else {  /* 10 Oct 2007: -sdn1 was used with -base1: 'two' sample test */
          f1 = (TT_n1-1.0) * (1.0/TT_n1 + 1.0/num2) / (TT_n1+num2-2.0) ;
          f2 = (num2 -1.0) * (1.0/TT_n1 + 1.0/num2) / (TT_n1+num2-2.0) ;
          for( ii=0 ; ii < nxyz ; ii++ ){
            av2[ii] -= (base_ary ? base_ary[ii] : TT_bval) ;  /* final mean */
            q1 = f1 * TT_sd1*TT_sd1 + f2 * sd2[ii]*sd2[ii] ;
            if( q1 > 0.0 ){
              num_tt++ ;
              tt = av2[ii] / sqrt(q1) ;
              sd2[ii] = tt ;      /* final t-stat */
              tt = fabs(tt) ; if( tt > tt_max ) tt_max = tt ;
            } else {
              sd2[ii] = 0.0 ;
            }
          }
        } /* end of -sdn1 special case */
#ifdef TTDEBUG
printf(" ** paired or bval test: num_tt = %d\n",num_tt) ;
#endif

      } else if( TT_pooled ){ /** case 2: unpaired 2-sample, pooled variance **/

         f1 = (num1-1.0) * (1.0/num1 + 1.0/num2) / (num1+num2-2.0) ;
         f2 = (num2-1.0) * (1.0/num1 + 1.0/num2) / (num1+num2-2.0) ;
         for( ii=0 ; ii < nxyz ; ii++ ){
            av2[ii] -= av1[ii] ;        /* final mean */
            q1 = f1 * sd1[ii]*sd1[ii] + f2 * sd2[ii]*sd2[ii] ;
            if( q1 > 0.0 ){
               num_tt++ ;
               tt = av2[ii] / sqrt(q1) ;
               sd2[ii] = tt ;      /* final t-stat */

               tt = fabs(tt) ; if( tt > tt_max ) tt_max = tt ;
            } else {
               sd2[ii] = 0.0 ;
            }
         }

         if( TT_voxel >= 0 )
            fprintf(stderr,"-- unpaired, pooled mean = %g, t = %g\n",
                    av2[TT_voxel], sd2[TT_voxel]) ;
#ifdef TTDEBUG
printf(" ** pooled test: num_tt = %d\n",num_tt) ;
#endif

      } else { /** case 3: unpaired 2-sample, unpooled variance **/
               /** 27 Dec 2002: modified to save DOF into dofar **/

         if( dofbrik != NULL ) dofar = dofbrik + fim_offset ;  /* 27 Dec 2002 */

         for( ii=0 ; ii < nxyz ; ii++ ){
            av2[ii] -= av1[ii] ;
            q1 = num1_inv * sd1[ii]*sd1[ii] ;
            q2 = num2_inv * sd2[ii]*sd2[ii] ;
            if( q1>0.0 && q2>0.0 ){               /* have positive variances? */
               num_tt++ ;
               tt = av2[ii] / sqrt(q1+q2) ;
               sd2[ii] = tt ;      /* final t-stat */

               tt = fabs(tt) ; if( tt > tt_max ) tt_max = tt ;

               if( dofar != NULL )                             /* 27 Dec 2002 */
                 dofar[ii] =  (q1+q2)*(q1+q2)
                            / (num1m1_inv*q1*q1 + num2m1_inv*q2*q2) ;
            } else {
               sd2[ii] = 0.0 ;
               if( dofar != NULL ) dofar[ii] = 1.0 ;           /* 27 Dec 2002 */
            }
         }

         if( TT_voxel >= 0 )
            fprintf(stderr,"-- unpaired, unpooled mean = %g, t = %g\n",
                    av2[TT_voxel], sd2[TT_voxel]) ;
#ifdef TTDEBUG
printf(" ** unpooled test: num_tt = %d\n",num_tt) ;
#endif
      }

#ifndef TTDEBUG
         if( ! TT_be_quiet ){ printf("\n") ; fflush(stdout) ; }
#endif

   }  /* end of loop over pieces of the input */

   if( TT_paired ){
      printf("--- Number of degrees of freedom = %d (paired test)\n",num2-1) ;
      dof = num2 - 1 ;
   } else if( TT_use_bval == 1 ){
      if( TT_n1 == 0 ){
        printf("--- Number of degrees of freedom = %d (1-sample test)\n",num2-1) ;
        dof = num2 - 1 ;
      } else {
        dof = TT_n1+num2-2 ;
        printf("--- Number of degrees of freedom = %d (-sdn1 2-sample test)\n",(int)dof) ;
      }
   } else {
      printf("--- Number of degrees of freedom = %d (2-sample test)\n",num1+num2-2) ;
      dof = num1+num2-2 ;
      if( ! TT_pooled )
         printf("    (For unpooled variance estimate, this is only approximate!)\n") ;
   }

   printf("--- Number of t-tests performed  = %d out of %d voxels\n",num_tt,nxyz) ;
   printf("--- Largest |t| value found      = %g\n",tt_max) ;

   kk = sizeof(ptable) / sizeof(float) ;
   for( ii=0 ; ii < kk ; ii++ ){
      tt = student_p2t( ptable[ii] , dof ) ;
      printf("--- Double sided tail p = %8f at t = %8f\n" , ptable[ii] , tt ) ;
   }

   /**----------------------------------------------------------------------**/
   /** now convert data to output format                13 Dec 2005 [rickr] **/

   /* first set mean */
   fimfac = EDIT_convert_dtype(nxyz , MRI_float,av2 , output_datum,vdif , 0.0) ;
   DSET_BRICK_FACTOR(new_dset, 0) = (fimfac != 0.0) ? 1.0/fimfac : 0.0 ;
   dd = fimfac; /* save for debug output */

   /* if output is of type short, limit t-stat magnitude to 32.7 */
   if( output_datum == MRI_short ){
     for( ii=0 ; ii < nxyz ; ii++ ){
       if     ( sd2[ii] >  32.7 ) sd2[ii] =  32.7 ;
       else if( sd2[ii] < -32.7 ) sd2[ii] = -32.7 ;
     }
   }

   fimfac = EDIT_convert_dtype(nxyz , MRI_float,sd2 , output_datum,vsp , 0.0) ;
   DSET_BRICK_FACTOR(new_dset, 1) = (fimfac != 0.0) ? 1.0/fimfac : 0.0 ;

#ifdef TTDEBUG
printf(" ** fimfac for mean, t-stat = %g, %g\n",dd, fimfac) ;
#endif
   /**----------------------------------------------------------------------**/

   INFO_message("Writing combined dataset into %s\n", DSET_BRIKNAME(new_dset) ) ;

   fbuf[0] = dof ;
   for( ii=1 ; ii < MAX_STAT_AUX ; ii++ ) fbuf[ii] = 0.0 ;
   (void) EDIT_dset_items( new_dset , ADN_stat_aux , fbuf , ADN_none ) ;

#if 0 /* factors already set */
   fbuf[0] = (output_datum == MRI_short && fimfac != 1.0 ) ? fimfac                    : 0.0 ;
   fbuf[1] = (output_datum == MRI_short                  ) ? 1.0 / FUNC_TT_SCALE_SHORT : 0.0 ;
   (void) EDIT_dset_items( new_dset , ADN_brick_fac , fbuf , ADN_none ) ;
#endif

   if( !AFNI_noenv("AFNI_AUTOMATIC_FDR") ) ii = THD_create_all_fdrcurves(new_dset) ;
   else                                    ii = 0 ;
   THD_load_statistics( new_dset ) ;
   THD_write_3dim_dataset( NULL,NULL , new_dset , True ) ;
   if( ii > 0 ) ININFO_message("created %d FDR curves in header",ii) ;

   if( dof_dset != NULL ){                                  /* 27 Dec 2002 */
     DSET_write( dof_dset ) ;
     WROTE_DSET( dof_dset ) ;
   }

   exit(0) ;
}
Example #5
0
int AFNI_process_environ( char *fname )
{
   int   nbuf , nused , ii ;
   char *fbuf , *fptr ;
   char  str[NSBUF] , left[NSBUF] , middle[NSBUF] ,
         right[NSBUF], fname_str[NSBUF] = {"not_set"};
   int nenv=0 , senv=0 ; static int first=1 ;  /* 13 Mar 2008 */

ENTRY("AFNI_process_environ") ;
   bloced = 1 ;

   if( fname != NULL ){
     strcpy(str,fname) ;
   } else {
     char *home ;
     if( afni_env_done ) RETURN(nenv) ;
     home = getenv("HOME") ;
     if( home != NULL ){ strcpy(str,home) ; strcat(str,"/.afnirc") ; }
     else              { strcpy(str,".afnirc") ; }
     if( !THD_is_file(str) ){                      /* 19 Sep 2007 */
       if( home != NULL ){ strcpy(str,home) ; strcat(str,"/AFNI.afnirc") ; }
       else              { strcpy(str,"AFNI.afnirc") ; }
     }
     afni_env_done = 1 ;
   }
   strcpy(fname_str,str) ; /* ZSS: Nov. 25 08 */

   fbuf = AFNI_suck_file( str ) ;
   if( fbuf == NULL ){ bloced=0; if(fname==NULL)afni_env_done=0; RETURN(nenv); }
   nbuf = strlen(fbuf) ;
   if( nbuf == 0    ){ bloced=0; if(fname==NULL)afni_env_done=0; RETURN(nenv); }

   fptr = fbuf ; nused = 0 ;

   /** scan for section strings, which start with "***" **/

   str[0] = '\0' ;  /* initialize string */

   while( nused < nbuf ){

      /**----------------------------------------**/
      /**-- skip ahead to next section keyword --**/

      SkipSection: while( ! ISTARRED(str) ){ GETSTR; }

      /*- 04 Jun 1999 -*/

      if( strcmp(str,"***END") == 0 ) break ;  /* exit main loop */

      if( strcmp(str,"***ENVIRONMENT") != 0 ){ GETSTR ; goto SkipSection ; }

      /**---------------------------------------**/
      /**-- ENVIRONMENT section [04 Jun 1999] --**/

      if( strcmp(str,"***ENVIRONMENT") == 0 ){ /* loop: find environment eqns */
         char *enveqn , *eee; int nl , nr , allow_reset ;
         senv = 1 ;

         eee = getenv("AFNI_ENVIRON_RESET") ; allow_reset = YESSISH(eee) ;

         while(1){                        /* loop, looking for 'name = value' */
            GETEQN ;

            if( !THD_filename_pure(left) ) continue ;

            nl = strlen(left) ; nr = strlen(right) ;
            enveqn = (char *) malloc(nl+nr+4) ;
            strcpy(enveqn,left) ; strcat(enveqn,"=") ; strcat(enveqn,right) ;
            if( !(eee = getenv(left)) || allow_reset ){  /* ZSS Nov 25 2008 */
               putenv(enveqn) ;
            } else if( !AFNI_noenv("AFNI_ENVIRON_WARNINGS") &&
                        strcmp(right, eee)){
               INFO_message(  "Environment variable %s already set to '%s'. "
                              "Value of '%s' from %s is ignored. \n"
                         "To kill such warnings Set AFNI_ENVIRON_WARNINGS to NO",
                              left, eee, right, fname_str);
            }
            nenv++ ;
         }

         continue ;  /* to end of outer while */
      } /* end of ENVIRONMENT */

   }  /* end of while loop */

  Done:
   if( fname == NULL && first ){
     if( senv == 0 )
       WARNING_message("didn't find '***ENVIRONMENT' line in ~/.afnirc") ;
     else if( nenv == 0 )
       WARNING_message("didn't find any environment equations in ~/.afnirc") ;
   }

   first = 0 ; free(fbuf) ; bloced = 0 ; RETURN(nenv) ;
}
Example #6
0
void AFNI_start_fetching_url( char *urlstring )
{
   pid_t child_pid ;

#ifdef CYGWIN  /* 18 Dec 2002 */
   FAIL_MESSAGE("not possible under Cygwin") ;
   return ;
#else

   /*-- decide if we are to do anything --*/

   if( AFNI_noenv("AFNI_VERSION_CHECK") ){    /* never check */
     FAIL_MESSAGE("AFNI_VERSION_CHECK forbids") ;
     return ;
   }

#undef  VDELAY
#define VDELAY 1234567 /* about 2 weeks */
   /* check if we did this in the last VDELAY seconds */
   /* also, update global motd_old                    */
   if( vc_check_too_soon() ) {
      disabled = 1 ;
      return ;
   }

   /*-- OK, start the child process --*/

   child_pid = fork() ;
   if( child_pid == (pid_t)(-1) ){  /* bad */
     FAIL_MESSAGE("can't fork") ;
     return ;
   }

   /*---------------------------------------------------------*/
   if( child_pid > 0 ){                     /* I'm the parent */

     /*-- save PID of child for later use --*/

     vc_child_pid = child_pid ;

     /*-- open an IOCHAN to talk to child --*/

     vc_ioc = iochan_init( STR_CHILD , "accept" ) ;
     if( vc_ioc == NULL ){
       kill(child_pid,SIGTERM) ;            /* cf. Abraham and Isaac */
       vc_child_pid = (pid_t)(-1) ;
       FAIL_MESSAGE("can't open connection to child") ;
     } else {
       atexit( vc_exit ) ;                                       /* 12 Dec 2002 */
     }
     return ;

   /*---------------------------------------------------------*/
   } else {                                  /* I'm the child */
                                           /* (never returns) */
     int nbuf=0 , jj ;
     char *vbuf=NULL ;
     IOCHAN *ioc ;
     struct utsname ubuf ;
     char ua[512] ;

     iochan_enable_perror(0) ;   /* don't print TCP/IP error messages */
     signal( SIGTERM , vexit ) ; /* if parent kills us, call vexit()  */

     /*-- get information from the AFNI server --*/

#define USE_HTTP_10

#ifdef USE_HTTP_10
#  undef PCLAB
#  ifdef SHOWOFF
#    undef SHSH
#    undef SHSHSH
#    define SHSH(x)   #x
#    define SHSHSH(x) SHSH(x)
#    define PCLAB     SHSHSH(SHOWOFF)
#  else
#    define PCLAB     "Unknown"
#  endif
#endif

     /** 25 Mar 2005: send more info in the request header **/

#ifdef USE_HTTP_10
     ubuf.nodename[0] = ubuf.sysname[0] = ubuf.machine[0] = '\0' ;
     jj = uname( &ubuf ) ;
     if( jj >= 0 && ubuf.nodename[0] != '\0' )
       sprintf( ua ,
               "afni (avers='%s'; prec='%s' node='%s'; sys='%s'; mach='%s')" ,
                AVERZHN, PCLAB, ubuf.nodename, ubuf.sysname, ubuf.machine   ) ;
     else
       sprintf( ua , "afni (avers='%s'; prec='%s')" , AVERZHN , PCLAB ) ;

     set_HTTP_10( 1 ) ;
     set_HTTP_user_agent( ua ) ;
#else
     set_HTTP_10( 0 ) ;
#endif

     /* send the request */

     THD_death_setup( 34567 ) ;  /* die if 34.567 seconds passes away */

     nbuf = read_URL( urlstring , &vbuf ) ;  /* may take a while */

     set_HTTP_10( 0 ) ;

     /*-- if this failed, quit --*/

     if( nbuf <= 0 || vbuf == NULL || vbuf[0] == '\0' ) {
        /* block recheck until a new DELAY has passed    22 Mar 2016 [rickr] */
        /* - also so server is not flooded when there are issues             */
        AFNI_update_vctime(NULL, NULL);
        vexit(1);
     }

     /*-- talk to parent process thru IOCHAN --*/

     ioc = iochan_init( STR_CHILD , "create" ) ;
     if( ioc == NULL )                                  vexit(2);

     /*-- wait until ioc is ready for writing --*/

     jj = iochan_writecheck(ioc,-1) ;
     if( jj < 0 )                                       vexit(3);

     /*-- send the info in vbuf --*/

     iochan_sendall( ioc , vbuf , nbuf ) ;
     while( ! iochan_clearcheck(ioc,10) )  /* loop until cleared */
       AFNI_sleep(10) ;                   /* by parent process  */

     AFNI_sleep(10); /* a little extra napping, then death */
     _exit(0);
   }
#endif  /* not CYGWIN */
}
Example #7
0
THD_3dim_dataset * THD_open_nifti( char *pathname )
{
   THD_3dim_dataset *dset=NULL ;
   nifti_image *nim ;
   int ntt , nbuc , nvals ;
   int use_qform = 0 , use_sform = 0, form_code = 0 ;
   int statcode = 0 , datum , iview , ibr ;
   int scale_data = 0 ;  /* flag based on scl_slope and inter  20 Jun 2008 */
   int xform_data = 0;
   THD_ivec3 orixyz , nxyz ;
   THD_fvec3 dxyz , orgxyz ;
   THD_mat33 R ;
   mat44 ijk_to_dicom44 ;
   char *ppp , prefix[THD_MAX_PREFIX] ;
   char form_priority = 'S' ;             /* 23 Mar 2006 */
   static int n_xform_warn=0;
   
ENTRY("THD_open_nifti") ;

   /*-- open input file --*/

   { /* set the nifti_io debug level       8 Apr 2005 [rickr] */
      char * ept = my_getenv("AFNI_NIFTI_DEBUG");
      if( ept != NULL ) nifti_set_debug_level(atoi(ept));
   }

   nifti_set_alter_cifti(1) ;  /* if CIFTI, shift dims   23 Jul 2015 [rickr] */
   nim = nifti_image_read( pathname, 0 ) ;

   if( nim == NULL || nim->nifti_type == 0 ) RETURN(NULL) ;

   /*-- extract some useful AFNI-ish information from the nim struct --*/

   /* we must have at least 2 spatial dimensions */

   /* this should be okay                 11 Jun 2007 */
   /* if( nim->nx < 2 || nim->ny < 2 ) RETURN(NULL) ; */

   /* 4th dimension = time; 5th dimension = bucket:
      these are mutually exclusive in AFNI at present */

   ntt = nim->nt ; nbuc = nim->nu ;

   /* nt and nu might be 0 now (see irritating niftilib 1.17 update)  */
   /* so ensure that ntt and nbuc are positive    02 Mar 2006 [rickr] */

   if( ntt  <= 0 ) ntt  = 1;
   if( nbuc <= 0 ) nbuc = 1;

   if( nim->nz <= 0 ) nim->nz = 1 ;  /* 03 Mar 2006: RWCox */

   if( ntt > 1 && nbuc > 1 ){
     fprintf(stderr,
             "** AFNI can't deal with 5 dimensional NIfTI(%s)\n",
             pathname ) ;
     RETURN(NULL) ;
   }

   nvals = MAX(ntt,nbuc) ;

   /* collapse higher-dimensional datasets    23 Jul 2015 [rickr] */
   /* (this includes CIFTI)                                       */
   if( nim->nv > 1 ) nvals *= nim->nv;
   if( nim->nw > 1 ) nvals *= nim->nw;
   if( ntt > 1 ) ntt = nvals;
   else          nbuc = nvals;

   /* determine type of dataset values:
      if we are scaling, or if the data type in the NIfTI file
      is something AFNI can't handle, then the result will be floats */

   /* do not scale if slope is 0 or if slope is 1 and inter is 0 */
   if( !isfinite(nim->scl_slope) || !isfinite(nim->scl_inter) ){
      fprintf(stderr,"** bad scl_slope and inter = %f, %f, ignoring...\n",
              nim->scl_slope, nim->scl_inter);
   } else {
       scale_data = nim->scl_slope != 0.0 &&
                        (nim->scl_slope != 1.0 || nim->scl_inter != 0.0) ;
   }
   { char *eee = getenv("AFNI_NIFTI_SCALE") ;
     if( eee != NULL && toupper(*eee) == 'N' ) scale_data = 0 ;
   }

   switch( nim->datatype ){
     default:
       fprintf(stderr,
               "** AFNI can't handle NIFTI datatype=%d (%s) in file %s\n",
               nim->datatype, nifti_datatype_string(nim->datatype), pathname );
       RETURN(NULL) ;
     break ;

     case DT_UINT8:     datum = scale_data ? MRI_float : MRI_byte  ;
                        xform_data = scale_data;
                        break ;
     case DT_INT16:     datum = scale_data ? MRI_float : MRI_short ;
                        xform_data = scale_data;
                        break ;
     case DT_FLOAT32:   datum = MRI_float   ; break ;
     case DT_COMPLEX64: datum = MRI_complex ; break ;
     case DT_RGB24:     datum = MRI_rgb     ; break ;

     case DT_INT8:      /* NIfTI-1 data types that AFNI can't handle directly */
     case DT_UINT16:
     case DT_INT32:
     case DT_UINT32:
     case DT_FLOAT64:   datum = MRI_float ; xform_data = 1 ; break ;

#if 0
     case DT_COMPLEX128:  /* this case would be too much like real work */
       fprintf(stderr,
               "** AFNI convert NIFTI_datatype=%d (%s) in file %s to COMPLEX64\n",
               nim->datatype, nifti_datatype_string(nim->datatype), pathname );
       datum = MRI_complex ;
     break ;
#endif
   }

   if( xform_data && !AFNI_noenv("AFNI_NIFTI_TYPE_WARN")) {
      if (!n_xform_warn || AFNI_yesenv("AFNI_NIFTI_TYPE_WARN")) {/* ZSS 04/11 */
         fprintf(stderr,
             "** AFNI converts NIFTI_datatype=%d (%s) in file %s to FLOAT32\n",
             nim->datatype, nifti_datatype_string(nim->datatype), pathname );
         if (!AFNI_yesenv("AFNI_NIFTI_TYPE_WARN")) {
            fprintf(stderr,
               "     Warnings of this type will be muted for this session.\n"
      "     Set AFNI_NIFTI_TYPE_WARN to YES to see them all, NO to see none.\n");
         }
      }
      ++n_xform_warn;
   }
   /* check for statistics code */

   if( nim->intent_code >= NIFTI_FIRST_STATCODE &&
       nim->intent_code <= NIFTI_LAST_STATCODE    ){

     if( nim->intent_code > FUNC_PT_TYPE ){
       fprintf(stderr,
               "** AFNI doesn't understand NIFTI statistic type %d (%s) in file %s\n",
               nim->intent_code , nifti_intent_string(nim->intent_code) , pathname ) ;
     } else {
       statcode = nim->intent_code ;
       if( nbuc > 1 ){
         fprintf(stderr,
                 "** AFNI doesn't support NIFTI voxel-dependent statistic parameters"
                 " in file %s\n" , pathname ) ;
         statcode = 0 ;
       }
     }
   }

   /* 23 Mar 2006: set qform or sform as having priority -- RWCox */

   ppp = my_getenv("NIFTI_FORM_PRIORITY") ;
   if( ppp == NULL ) ppp = getenv("AFNI_FORM_PRIORITY") ;
   if( ppp == NULL ) ppp = getenv("AFNI_NIFTI_PRIORITY") ;
   if( ppp == NULL ) ppp = getenv("AFNI_NIFTI_FORM") ;
   if( ppp == NULL ) ppp = getenv("AFNI_NIFTI_FORM_PRIORITY") ;
   if( ppp != NULL ){
     char fp = toupper(*ppp) ;
     if( fp == 'S' || fp == 'Q' ) form_priority = fp ;
     else WARNING_message("Illegal NIFTI_FORM_PRIORITY='%s'",ppp) ;
   }

   /** 24 Mar 2006: check determs of qform and sform, if have both **/

   if( nim->qform_code > 0 && nim->sform_code > 0 ){
     float qdet , sdet ;
     LOAD_MAT(R, nim->qto_xyz.m[0][0] ,
                 nim->qto_xyz.m[0][1] ,
                 nim->qto_xyz.m[0][2] ,
                 nim->qto_xyz.m[1][0] ,
                 nim->qto_xyz.m[1][1] ,
                 nim->qto_xyz.m[1][2] ,
                 nim->qto_xyz.m[2][0] ,
                 nim->qto_xyz.m[2][1] ,
                 nim->qto_xyz.m[2][2]  ) ; qdet = MAT_DET(R) ;

     LOAD_MAT(R, nim->sto_xyz.m[0][0] ,
                 nim->sto_xyz.m[0][1] ,
                 nim->sto_xyz.m[0][2] ,
                 nim->sto_xyz.m[1][0] ,
                 nim->sto_xyz.m[1][1] ,
                 nim->sto_xyz.m[1][2] ,
                 nim->sto_xyz.m[2][0] ,
                 nim->sto_xyz.m[2][1] ,
                 nim->sto_xyz.m[2][2]  ) ; sdet = MAT_DET(R) ;

     if( qdet*sdet < 0.0f )
       WARNING_message("NIfTI('%s'): Qform/Sform handedness differ; %c wins!",
                       pathname , form_priority ) ;
   }

   /* KRH 07/11/05 -- adding ability to choose spatial transform
      from the options of qform, sform, bothform, or noform.

      If qform is present, it will be used.

      If qform is absent, but sform present, then the sform
        will be modified to be an orthogonal rotation and used.

      If both qform and sform are absent, then we will have
        an error.

      Previously assumed qform present.  */

   /* 23 Mar 2006: use form_priority to choose between them */

   if ((nim->qform_code > 0) && (nim->sform_code > 0) ) {
     if( form_priority == 'Q' )   { use_qform = 1 ; use_sform = 0 ; }
     else                         { use_qform = 0 ; use_sform = 1 ; }
   } else if (nim->qform_code > 0){ use_qform = 1 ; use_sform = 0 ; }
     else if (nim->sform_code > 0){ use_qform = 0 ; use_sform = 1 ; }
     else {
                                    use_qform = 0 ; use_sform = 0 ;
     WARNING_message(
      "NO spatial transform (neither qform nor sform), in NIfTI file '%s'" ,
      pathname ) ;
   }

   /** now take NIfTI-1.1 coords and transform to AFNI codes **/

   if (use_qform) {

     float orgx, orgy, orgz ;

     form_code = nim->qform_code;

     /* determine orientation from the qto_xyz matrix,
      which transforms (i,j,k) voxel indexes to (x,y,z) LPI coordinates */

     LOAD_MAT(R, -nim->qto_xyz.m[0][0] ,  /* negate x and y   */
                 -nim->qto_xyz.m[0][1] ,  /* coefficients,    */
                 -nim->qto_xyz.m[0][2] ,  /* since AFNI works */
                 -nim->qto_xyz.m[1][0] ,  /* with RAI coords, */
                 -nim->qto_xyz.m[1][1] ,  /* but NIFTI uses   */
                 -nim->qto_xyz.m[1][2] ,  /* LPI coordinates. */
                  nim->qto_xyz.m[2][0] ,  /* [Which is my own] */
                  nim->qto_xyz.m[2][1] ,  /* [damn fault!!!!!] */
                  nim->qto_xyz.m[2][2]  ) ;

     LOAD_MAT44(ijk_to_dicom44,
                 -nim->qto_xyz.m[0][0] ,  /* negate x and y   */
                 -nim->qto_xyz.m[0][1] ,  /* coefficients,    */
                 -nim->qto_xyz.m[0][2] ,  /* since AFNI works */
                 -nim->qto_xyz.m[0][3] ,
                 -nim->qto_xyz.m[1][0] ,  /* with RAI coords, */
                 -nim->qto_xyz.m[1][1] ,  /* but NIFTI uses   */
                 -nim->qto_xyz.m[1][2] ,  /* LPI coordinates. */
                 -nim->qto_xyz.m[1][3] ,
                  nim->qto_xyz.m[2][0] ,  /* [Which is my own] */
                  nim->qto_xyz.m[2][1] ,  /* [damn fault!!!!!] */
                  nim->qto_xyz.m[2][2] ,  
                  nim->qto_xyz.m[2][3] ) ;

     orixyz = THD_matrix_to_orientation( R ) ;   /* compute orientation codes */

     iview = NIFTI_code_to_view(nim->qform_code);

     /* load the offsets and the grid spacings */

     if (ORIENT_xyz[orixyz.ijk[0]] == 'z' )  {
       orgx = nim->qto_xyz.m[ORIENT_xyzint[orixyz.ijk[0]] - 1][3] ;
     } else {
       orgx = - nim->qto_xyz.m[ORIENT_xyzint[orixyz.ijk[0]] - 1][3] ;
     }

     if (ORIENT_xyz[orixyz.ijk[1]] == 'z' )  {
       orgy = nim->qto_xyz.m[ORIENT_xyzint[orixyz.ijk[1]] - 1][3] ;
     } else {
       orgy = - nim->qto_xyz.m[ORIENT_xyzint[orixyz.ijk[1]] - 1][3] ;
     }

     if (ORIENT_xyz[orixyz.ijk[2]] == 'z' )  {
       orgz = nim->qto_xyz.m[ORIENT_xyzint[orixyz.ijk[2]] - 1][3] ;
     } else {
       orgz = - nim->qto_xyz.m[ORIENT_xyzint[orixyz.ijk[2]] - 1][3] ;
     }


     LOAD_FVEC3( orgxyz ,  orgx ,
                           orgy ,
                           orgz  ) ;
#if 0
     LOAD_FVEC3( orgxyz , -nim->qto_xyz.m[0][3] ,    /* again, negate  */
                        -nim->qto_xyz.m[1][3] ,    /* x and y coords */
                         nim->qto_xyz.m[2][3]  ) ;
#endif

     /* AFNI space units are always mm */

     if( nim->xyz_units == NIFTI_UNITS_METER ){
       nim->dx *= 1000.0 ; nim->dy *= 1000.0 ; nim->dz *= 1000.0 ;
     } else if(  nim->xyz_units == NIFTI_UNITS_MICRON ){
       nim->dx *= 0.001  ; nim->dy *= 0.001  ; nim->dz *= 0.001  ;
     }

     LOAD_FVEC3( dxyz , (ORIENT_sign[orixyz.ijk[0]]=='+') ? nim->dx : -nim->dx ,
                        (ORIENT_sign[orixyz.ijk[1]]=='+') ? nim->dy : -nim->dy ,
                        (ORIENT_sign[orixyz.ijk[2]]=='+') ? nim->dz : -nim->dz  ) ;

   } else if (use_sform) {

     int orimap[7] = { 6 , 1 , 0 , 2 , 3 , 4 , 5 } ;
     int oritmp[3] ;
     float dxtmp, dytmp, dztmp ;
     float xmax, ymax, zmax ;
     float orgx, orgy, orgz ;
     float fig_merit, ang_merit ;

     form_code = nim->sform_code;

     /* convert sform to nifti orientation codes */

     /* n2   10 Jul, 2015 [rickr] */
     nifti_dmat44_to_orientation(nim->sto_xyz,
                                 &oritmp[0], &oritmp[1], &oritmp[2] ) ;

     /* convert nifti orientation codes to AFNI codes and store in vector */

     LOAD_IVEC3( orixyz , orimap[oritmp[0]] ,
                          orimap[oritmp[1]] ,
                          orimap[oritmp[2]] ) ;

     /* assume original view if there's no talairach id present */
     iview = NIFTI_code_to_view(nim->sform_code);

     /* load the offsets and the grid spacings */

     if (ORIENT_xyz[orixyz.ijk[0]] == 'z' )  {
       orgx = nim->sto_xyz.m[ORIENT_xyzint[orixyz.ijk[0]] - 1][3] ;
     } else {
       orgx = - nim->sto_xyz.m[ORIENT_xyzint[orixyz.ijk[0]] - 1][3] ;
     }

     if (ORIENT_xyz[orixyz.ijk[1]] == 'z' )  {
       orgy = nim->sto_xyz.m[ORIENT_xyzint[orixyz.ijk[1]] - 1][3] ;
     } else {
       orgy = - nim->sto_xyz.m[ORIENT_xyzint[orixyz.ijk[1]] - 1][3] ;
     }

     if (ORIENT_xyz[orixyz.ijk[2]] == 'z' )  {
       orgz = nim->sto_xyz.m[ORIENT_xyzint[orixyz.ijk[2]] - 1][3] ;
     } else {
       orgz = - nim->sto_xyz.m[ORIENT_xyzint[orixyz.ijk[2]] - 1][3] ;
     }


     LOAD_FVEC3( orgxyz ,  orgx ,
                           orgy ,
                           orgz  ) ;

#if 0
     LOAD_FVEC3( orgxyz , -nim->sto_xyz.m[0][3] ,    /* again, negate  */
                          -nim->sto_xyz.m[1][3] ,    /* x and y coords */
                           nim->sto_xyz.m[2][3] ) ;
#endif

#define MAXNUM(a,b) ( (a) > (b) ? (a):(b))
#define MAX3(a,b,c) ( (MAXNUM(a,b)) > (MAXNUM(a,c)) ? (MAXNUM(a,b)):(MAXNUM(a,c)))
#define MINNUM(a,b) ( (a) < (b) ? (a):(b))
#define MIN3(a,b,c) ( (MINNUM(a,b)) < (MINNUM(a,c)) ? (MINNUM(a,b)):(MINNUM(a,c)))

     dxtmp = sqrt ( nim->sto_xyz.m[0][0] * nim->sto_xyz.m[0][0] +
                    nim->sto_xyz.m[1][0] * nim->sto_xyz.m[1][0] +
                    nim->sto_xyz.m[2][0] * nim->sto_xyz.m[2][0] ) ;

     xmax = MAX3(fabs(nim->sto_xyz.m[0][0]),fabs(nim->sto_xyz.m[1][0]),fabs(nim->sto_xyz.m[2][0])) / dxtmp ;

     dytmp = sqrt ( nim->sto_xyz.m[0][1] * nim->sto_xyz.m[0][1] +
                    nim->sto_xyz.m[1][1] * nim->sto_xyz.m[1][1] +
                    nim->sto_xyz.m[2][1] * nim->sto_xyz.m[2][1] ) ;

     ymax = MAX3(fabs(nim->sto_xyz.m[0][1]),fabs(nim->sto_xyz.m[1][1]),fabs(nim->sto_xyz.m[2][1])) / dytmp ;

     dztmp = sqrt ( nim->sto_xyz.m[0][2] * nim->sto_xyz.m[0][2] +
                    nim->sto_xyz.m[1][2] * nim->sto_xyz.m[1][2] +
                    nim->sto_xyz.m[2][2] * nim->sto_xyz.m[2][2] ) ;

     zmax = MAX3(fabs(nim->sto_xyz.m[0][2]),fabs(nim->sto_xyz.m[1][2]),fabs(nim->sto_xyz.m[2][2])) / dztmp ;

     fig_merit = MIN3(xmax,ymax,zmax) ;
     ang_merit = acos (fig_merit) * 180.0 / 3.141592653 ;
#if 0
     if (fabs(ang_merit) > .01) {
       WARNING_message (
         "qform not present in:\n"
         "   '%s'\n"
         "  oblique sform used, and the worst axis is\n"
         "  %f degrees from plumb.\n"
         "  If you are performing spatial transformations on this dset, \n"
         "  or viewing/combining it with volumes of differing obliquity,\n"
         "  you should consider running: \n"
         "     3dWarp -deoblique \n"
         "  on this and  other oblique datasets in the same session.\n"
         ,pathname, ang_merit ) ;
     }
#endif

     if( nim->xyz_units == NIFTI_UNITS_METER ){
       dxtmp *= 1000.0 ; dytmp *= 1000.0 ; dztmp *= 1000.0 ;
     } else if(  nim->xyz_units == NIFTI_UNITS_MICRON ){
       dxtmp *= 0.001  ; dytmp *= 0.001  ; dztmp *= 0.001  ;
     }

     LOAD_FVEC3( dxyz , (ORIENT_sign[orixyz.ijk[0]]=='+') ? dxtmp : -dxtmp ,
                        (ORIENT_sign[orixyz.ijk[1]]=='+') ? dytmp : -dytmp ,
                        (ORIENT_sign[orixyz.ijk[2]]=='+') ? dztmp : -dztmp ) ;

     LOAD_MAT44(ijk_to_dicom44, -nim->sto_xyz.m[0][0] ,  /* negate x and y   */
                 -nim->sto_xyz.m[0][1] ,  /* coefficients,    */
                 -nim->sto_xyz.m[0][2] ,  /* since AFNI works */
                 -nim->sto_xyz.m[0][3] ,
                 -nim->sto_xyz.m[1][0] ,  /* with RAI coords, */
                 -nim->sto_xyz.m[1][1] ,  /* but NIFTI uses   */
                 -nim->sto_xyz.m[1][2] ,  /* LPI coordinates. */
                 -nim->sto_xyz.m[1][3] ,
                  nim->sto_xyz.m[2][0] ,  /* [Which is my own] */
                  nim->sto_xyz.m[2][1] ,  /* [damn fault!!!!!] */
                  nim->sto_xyz.m[2][2] ,  
                  nim->sto_xyz.m[2][3] ) ;

   } else { /* NO SPATIAL XFORM. BAD BAD BAD BAD BAD BAD. */

     float dxtmp, dytmp, dztmp ;

     /* if pixdim data are present, use them in order to set pixel
        dimensions.  otherwise, set the dimensions to 1 unit.         */

     dxtmp = ((nim->pixdim[1] > 0) ? nim->pixdim[1] : 1) ;
     dytmp = ((nim->pixdim[2] > 0) ? nim->pixdim[2] : 1) ;
     dztmp = ((nim->pixdim[3] > 0) ? nim->pixdim[3] : 1) ;

     if( nim->xyz_units == NIFTI_UNITS_METER ){
       dxtmp *= 1000.0 ; dytmp *= 1000.0 ; dztmp *= 1000.0 ;
     } else if(  nim->xyz_units == NIFTI_UNITS_MICRON ){
       dxtmp *= 0.001  ; dytmp *= 0.001  ; dztmp *= 0.001  ;
     }

     /* set orientation to LPI by default    */

     LOAD_IVEC3( orixyz , 1 ,
                          2 ,
                          4 ) ;

     LOAD_FVEC3( dxyz , (ORIENT_sign[orixyz.ijk[0]]=='+') ? dxtmp : -dxtmp ,
                        (ORIENT_sign[orixyz.ijk[1]]=='+') ? dytmp : -dytmp ,
                        (ORIENT_sign[orixyz.ijk[2]]=='+') ? dztmp : -dztmp ) ;

     iview = NIFTI_default_view();

     /* set origin to 0,0,0   */

     LOAD_FVEC3( orgxyz , 0 ,
                          0 ,
                          0 ) ;
     /* put scaled identity matrix by default */
     LOAD_MAT44(ijk_to_dicom44, dxtmp, 0.0, 0.0, 0.0,  
                                0.0, dytmp, 0.0, 0.0,
                                0.0, 0.0, dztmp, 0.0 );
   }



   /*-- make an AFNI dataset! --*/

   dset = EDIT_empty_copy(NULL) ;

   ppp  = THD_trailname(pathname,0) ;               /* strip directory */
   MCW_strncpy( prefix , ppp , THD_MAX_PREFIX ) ;   /* to make prefix */
   
   /* You need to set the path too
      before, if you loaded ~/tmp/joe.nii the path appeared
      to be ./joe.nii, troubling in multiple instances.
                                                      ZSS Dec 2011 */
   THD_init_diskptr_names( dset->dblk->diskptr ,
                           THD_filepath(pathname) ,
                           NULL , prefix ,
                           dset->view_type , True );
                           
   nxyz.ijk[0] = nim->nx ;                          /* grid dimensions */
   nxyz.ijk[1] = nim->ny ;
   nxyz.ijk[2] = nim->nz ;

   dset->idcode.str[0] = 'N' ;  /* overwrite 1st 3 bytes with something special */
   dset->idcode.str[1] = 'I' ;
   dset->idcode.str[2] = 'I' ;

   MCW_hash_idcode( pathname , dset ) ;  /* 06 May 2005 */

   EDIT_dset_items( dset ,
                      ADN_prefix      , prefix ,
                      ADN_datum_all   , datum ,
                      ADN_nxyz        , nxyz ,
                      ADN_xyzdel      , dxyz ,
                      ADN_xyzorg      , orgxyz ,
                      ADN_xyzorient   , orixyz ,
                      ADN_malloc_type , DATABLOCK_MEM_MALLOC ,
                      ADN_view_type   , iview ,
                      ADN_type        , (statcode != 0) ? HEAD_FUNC_TYPE
                                                        : HEAD_ANAT_TYPE ,
                    ADN_none ) ;

   /* copy transformation matrix to dataset structure */
   /* moved after setting grid     4 Apr 2014 [rickr,drg] */
   dset->daxes->ijk_to_dicom_real = ijk_to_dicom44;

   /* not a time dependent dataset */

   if( ntt < 2 ){
     EDIT_dset_items( dset ,
                        ADN_nvals     , nbuc ,
                        ADN_datum_all , datum ,
                        ADN_func_type , (statcode != 0) ? FUNC_BUCK_TYPE
                                                        : ANAT_BUCK_TYPE ,
                      ADN_none ) ;

   } else {  /* is a time dependent dataset */

     if( nim->time_units == NIFTI_UNITS_MSEC ){
            nim->dt *= 0.001 ;
            nim->toffset *= 0.001 ;
     } else if( nim->time_units == NIFTI_UNITS_USEC ){
            nim->dt *= 1.e-6 ;
            nim->toffset *= 1.e-6 ;
     }
     EDIT_dset_items( dset ,
                        ADN_nvals     , ntt ,
                        ADN_ntt       , ntt ,
                        ADN_datum_all , datum ,
                        ADN_ttorg     , nim->toffset , /* 12 Oct 2007 [rickr] */
                        ADN_ttdel     , nim->dt ,
                        ADN_ttdur     , 0.0 ,
                        ADN_tunits    , UNITS_SEC_TYPE ,
                        ADN_func_type , (statcode != 0) ? FUNC_FIM_TYPE
                                                        : ANAT_EPI_TYPE ,
                      ADN_none ) ;

     /* if present, add stuff about the slice-timing offsets */

     if( nim->slice_dim      == 3               && /* AFNI can only deal with */
         nim->slice_code     >  0               && /* slice timing offsets    */
         nim->slice_duration >  0.0             && /* along the k-axis of     */
         nim->slice_start    >= 0               && /* the dataset volume      */
         nim->slice_start    < nim->nz          &&
         nim->slice_end      > nim->slice_start &&
         nim->slice_end      < nim->nz             ){

       float *toff=(float *)calloc(sizeof(float),nim->nz) , tsl ;
       int kk ;

            if( nim->time_units == NIFTI_UNITS_MSEC ) nim->slice_duration *= 0.001;
       else if( nim->time_units == NIFTI_UNITS_USEC ) nim->slice_duration *= 1.e-6;

       /* set up slice time offsets in the divers orders */

       switch( nim->slice_code ){
         case NIFTI_SLICE_SEQ_INC:
           tsl = 0.0 ;
           for( kk=nim->slice_start ; kk <= nim->slice_end ; kk++ ){
             toff[kk] = tsl ; tsl += nim->slice_duration ;
           }
         break ;
         case NIFTI_SLICE_SEQ_DEC:
           tsl = 0.0 ;
           for( kk=nim->slice_end ; kk >= nim->slice_end ; kk-- ){
             toff[kk] = tsl ; tsl += nim->slice_duration ;
           }
         break ;
         case NIFTI_SLICE_ALT_INC:
           tsl = 0.0 ;
           for( kk=nim->slice_start ; kk <= nim->slice_end ; kk+=2 ){
             toff[kk] = tsl ; tsl += nim->slice_duration ;
           }
           for( kk=nim->slice_start+1 ; kk <= nim->slice_end ; kk+=2 ){
             toff[kk] = tsl ; tsl += nim->slice_duration ;
           }
         break ;
         case NIFTI_SLICE_ALT_INC2:
           tsl = 0.0 ;
           for( kk=nim->slice_start+1 ; kk <= nim->slice_end ; kk+=2 ){
             toff[kk] = tsl ; tsl += nim->slice_duration ;
           }
           for( kk=nim->slice_start ; kk <= nim->slice_end ; kk+=2 ){
             toff[kk] = tsl ; tsl += nim->slice_duration ;
           }
         break ;
         case NIFTI_SLICE_ALT_DEC:
           tsl = 0.0 ;
           for( kk=nim->slice_end ; kk >= nim->slice_start ; kk-=2 ){
             toff[kk] = tsl ; tsl += nim->slice_duration ;
           }
           for( kk=nim->slice_end-1 ; kk >= nim->slice_start ; kk-=2 ){
             toff[kk] = tsl ; tsl += nim->slice_duration ;
           }
         break ;
         case NIFTI_SLICE_ALT_DEC2:
           tsl = 0.0 ;
           for( kk=nim->slice_end-1 ; kk >= nim->slice_start ; kk-=2 ){
             toff[kk] = tsl ; tsl += nim->slice_duration ;
           }
           for( kk=nim->slice_end ; kk >= nim->slice_start ; kk-=2 ){
             toff[kk] = tsl ; tsl += nim->slice_duration ;
           }
         break ;
       }

       EDIT_dset_items( dset ,
                          ADN_nsl     , nim->nz       ,
                          ADN_zorg_sl , orgxyz.xyz[2] ,
                          ADN_dz_sl   , dxyz.xyz[2]   ,
                          ADN_toff_sl , toff          ,
                        ADN_none ) ;

       free(toff) ;

     } /* end of slice timing stuff */

   } /* end of 3D+time dataset stuff */


   /* set atlas space based on NIFTI s/qform code */
   NIFTI_code_to_space(form_code,dset);

   /* add statistics, if present */

   if( statcode != 0 ){
     for( ibr=0 ; ibr < nvals ; ibr++ )
       EDIT_STATAUX4(dset,ibr,statcode,nim->intent_p1,nim->intent_p2,nim->intent_p3,0) ;
   }

   /*-- flag to read data from disk using NIFTI functions --*/

   dset->dblk->diskptr->storage_mode = STORAGE_BY_NIFTI ;
   strcpy( dset->dblk->diskptr->brick_name , pathname ) ;
   dset->dblk->diskptr->byte_order = nim->byteorder ;

#if 0
   for( ibr=0 ; ibr < nvals ; ibr++ ){     /* make sub-brick labels */
     sprintf(prefix,"%s[%d]",tname,ibr) ;
     EDIT_BRICK_LABEL( dset , ibr , prefix ) ;
   }
#endif

   /** 10 May 2005: see if there is an AFNI extension;
                    if so, load attributes from it and
                    then edit the dataset appropriately **/

   { int ee ;  /* extension index */

     /* scan extension list to find the first AFNI extension */

     for( ee=0 ; ee < nim->num_ext ; ee++ )
       if( nim->ext_list[ee].ecode == NIFTI_ECODE_AFNI &&
           nim->ext_list[ee].esize > 32                &&
           nim->ext_list[ee].edata != NULL               ) break ;

     /* if found an AFNI extension ... */

     if( ee < nim->num_ext ){
       char *buf = nim->ext_list[ee].edata , *rhs , *cpt ;
       int  nbuf = nim->ext_list[ee].esize - 8 ;
       NI_stream ns ;
       void     *nini ;
       NI_group *ngr , *nngr ;

       /* if have data, it's long enough, and starts properly, then ... */

       if( buf != NULL && nbuf > 32 && strncmp(buf,"<?xml",5)==0 ){
         if( buf[nbuf-1] != '\0' ) buf[nbuf-1] = '\0' ;         /* for safety */
         cpt = strstr(buf,"?>") ;                    /* find XML prolog close */
         if( cpt != NULL ){                          /* if found it, then ... */
           ns = NI_stream_open( "str:" , "r" ) ;
           NI_stream_setbuf( ns , cpt+2 ) ;        /* start just after prolog */
           nini = NI_read_element(ns,1) ;                 /* get root element */
           NI_stream_close(ns) ;
           if( NI_element_type(nini) == NI_GROUP_TYPE ){   /* must be a group */
             ngr = (NI_group *)nini ;
             if( strcmp(ngr->name,"AFNI_attributes") == 0 ){    /* root is OK */
               nngr = ngr ;
             } else {                   /* search in group for proper element */
               int nn ; void **nnini ;
               nn = NI_search_group_deep( ngr , "AFNI_attributes" , &nnini ) ;
               if( nn <= 0 ) nngr = NULL ;
               else        { nngr = (NI_group *)nnini[0]; NI_free(nnini); }
             }

             if( NI_element_type(nngr) == NI_GROUP_TYPE ){ /* have  good name */
               rhs = NI_get_attribute( nngr , "self_idcode" ) ;
               if( rhs == NULL )
                 rhs = NI_get_attribute( nngr , "AFNI_idcode" ) ;
               if( rhs != NULL )    /* set dataset ID code from XML attribute */
                 MCW_strncpy( dset->idcode.str , rhs , MCW_IDSIZE ) ;
               rhs = NI_get_attribute( nngr , "NIfTI_nums" ) ;    /* check if */
               if( rhs != NULL ){                       /* dataset dimensions */
                 char buf[128] ;                              /* were altered */
                 sprintf(buf,"%ld,%ld,%ld,%ld,%ld,%d" ,        /* 12 May 2005 */
                   nim->nx, nim->ny, nim->nz, nim->nt, nim->nu, nim->datatype );
                 if( strcmp(buf,rhs) != 0 ){
                   static int nnn=0 ;
                   if(nnn==0){fprintf(stderr,"\n"); nnn=1;}
                   fprintf(stderr,
                     "** WARNING: NIfTI file %s dimensions altered since "
                                 "AFNI extension was added\n",pathname ) ;
                 }
               }
               THD_dblkatr_from_niml( nngr , dset->dblk ); /* load attributes */
               THD_datablock_apply_atr( dset ) ;   /* apply to dataset struct */
             }
             NI_free_element( ngr ) ;          /* get rid of the root element */

           } /* end of if found a group element at the root */
         } /* end of if extension data array had an XML prolog close */
       } /* end of if had a good extension data array */
     } /* end of if had an AFNI extension */
   } /* end of processing extensions */

   /* return unpopulated dataset */

   nifti_image_free(nim) ; RETURN(dset) ;
}
Example #8
0
static char * DELAY_main( PLUGIN_interface * plint )
{
   hilbert_data_V2 uda,*ud;
   MRI_IMAGE * tsim;
   MCW_idcode * idc ;         /* input dataset idcode */
   THD_3dim_dataset * old_dset , * new_dset ;  /* input and output datasets */
   char *tmpstr , * str , *nprfxstr;                 /* strings from user */
   int   ntime, nvec ,nprfx, i;
	float * vec , fs , T ;
		
	/* Allocate as much character space as Bob specifies in afni.h + a bit more */
	
	tmpstr = (char *) calloc (PLUGIN_MAX_STRING_RANGE+10,sizeof(char));
	nprfxstr = (char *) calloc (PLUGIN_MAX_STRING_RANGE+10,sizeof(char));
	
	if (tmpstr == NULL || nprfxstr == NULL) 
									  return "********************\n"
												"Could not Allocate\n"
												"a teeni weeni bit of\n"
												"Memory ! \n"
												"********************\n";
														
	ud = &uda;		/* ud now points to an allocated space */
	ud->errcode = 0;	/*reset error flag */
	
   /*--------------------------------------------------------------------*/
   /*----- 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"
             "*************************"  ;
   
   ud->dsetname = DSET_FILECODE (old_dset);
	ud->nsamp = DSET_NUM_TIMES (old_dset);
	ud->Navg = 1 ;    /* Navg does not play a role for the p value, averaging increases sensitivity */
	ud->Nort = PLUTO_get_number(plint) ; /* Should be two by default, for mean and linear trend */
	ud->Nfit = 2 ;  /* Always 2 for phase and amplitude for this plugin */
	/*--------- go to 2nd input line, input time series ---------*/
		
	PLUTO_next_option(plint) ;
	
	tsim = PLUTO_get_timeseries(plint);
	if (tsim == NULL) return "No Timeseries Input";
	
	ud->ln = (int)tsim -> nx;									/* number of points in each vector */
	nvec 	= tsim -> ny;									/* number of vectors */
	ud->rvec   = (float *) MRI_FLOAT_PTR(tsim);	/* vec[i+j*nx] = ith point of jth vector */
																/* for i=0 .. ntime-1 and j=0 .. nvec-1 */
	
	if (is_vect_null (ud->rvec,ud->ln) == 1) 	/* check if ref vect is all zeroes */
		{
			return "Reference vector is all zeros";	
		}
		
	ud->refname = tsim->name;
	ud->ignore = PLUTO_get_number(plint) ;    /* get number item */
	
	str = PLUTO_get_string(plint) ;
   ud->Dsamp = (int)PLUTO_string_index( str , NUM_YN_STRINGS , yn_strings ) ;
   
   /*--------- go to 3rd input line, sampling frequency, and stimulus period ---------*/
   	
   PLUTO_next_option(plint) ;
   
   ud->fs = PLUTO_get_number(plint) ;    /* get number item */
   ud->T = PLUTO_get_number(plint) ;    /* get number item */
   
   ud->co = PLUTO_get_number(plint) ;    /* get number item */
   str = PLUTO_get_string(plint) ;
   ud->biasrem = (int)PLUTO_string_index( str , NUM_YN_STRINGS , yn_strings ) ;
   
   /*--------- go to 4th input line, delay units and wrp option---------*/
		
   PLUTO_next_option(plint) ;

   ud->Nseg = (int)PLUTO_get_number(plint) ;    /* get number item */
   ud->Pover = (int)PLUTO_get_number(plint) ;    /* get number item */
   
   str = PLUTO_get_string(plint) ;      						/* get string item (the method) */
   ud->unt = (int)PLUTO_string_index( str ,      				/* find it in list it is from */
             	 NUM_METHOD_STRINGS ,
             	 method_strings ) ;
	
	str = PLUTO_get_string(plint) ;  
	ud->wrp = (int)PLUTO_string_index( str , NUM_YN_STRINGS , yn_strings ) ;
	
   /*--------- go to 5th input line Output prefix ---------*/
		
   PLUTO_next_option(plint) ;
		
   ud->new_prefix = PLUTO_get_string(plint) ;   /* get string item (the output prefix) */
	
	/* check to see if the field is empty */
	if (ud->new_prefix == NULL)
			nprfx = 0;
		else
			nprfx = 1;
	/* check if the size is larger than 0. I did not want to check for this unless it's allocated */
	if (nprfx == 1 && (int)strlen (ud->new_prefix) == 0)
		nprfx = 0;
		
	if (nprfx == 0)		/* now create the new name and make new_prefix point to it */
		{
			sprintf (nprfxstr,"%s.DEL",DSET_PREFIX (old_dset));
			ud->new_prefix = nprfxstr;
			/*printf ("New prefix is set to be : %s\n\a",ud->new_prefix);*/
		}
	
   if( ! PLUTO_prefix_ok(ud->new_prefix) )      /* check if it is OK */
      return "************************\n"
             "Output Prefix is illegal\n"
             "************************"  ;
	
	str = PLUTO_get_string(plint) ; 				/* write delays to file ? */
	ud->out = (int)PLUTO_string_index( str , NUM_YN_STRINGS , yn_strings );
	
	ud->strout = PLUTO_get_string(plint) ; 				/* strout is for the outiflename, which will be used after the debugging section */
	if (ud->strout == NULL)						/* if no output name is given, use the new_prefix */
		{ud->strout = ud->new_prefix;}
		else 
			{	
				if((int)strlen (ud->strout) == 0) ud->strout = ud->new_prefix;
			}
			
	str = PLUTO_get_string(plint) ; 
	ud->outts = (int)PLUTO_string_index( str , NUM_YN_STRINGS , yn_strings );
	
	/* ------------------Done with user parameters ---------------------------- */
	
	ud->nxx = (int)old_dset->daxes->nxx;				/* get data set dimensions */
	ud->nyy = (int)old_dset->daxes->nyy;
	ud->nzz = (int)old_dset->daxes->nzz;
	
	/* No need for users to set these options ...*/
	
	ud->dtrnd = 0;
	
	if (ud->ln != (ud->nsamp - ud->ignore))
		{
			ud->errcode = ERROR_BADLENGTH;
			return "***************************\n"
					 "Bad time series length \n"
					 "Check reference time series\n"
					 " or the ignore parameter   \n"
					 "***************************\n";
		}
	
	if ((ud->unt < 0) || (ud->unt > 2))										/* unt error Check */
	  	{
         ud->errcode = ERROR_WRONGUNIT;
         return "***********************\n"
         		 " internal error: (ziad)\n"
					 "unt values out of bound\n"
					 "***********************\n";			/*unt must be between 0 and 2 */
	  	}
	  
	  if ((ud->wrp < 0) || (ud->wrp > 1))										/* wrp error Check */
	  	{
         ud->errcode = ERROR_WARPVALUES;
         return "***********************\n"
         		 " internal error: (ziad)\n"
					 "wrp values out of bound\n"
					 "***********************\n";			/* wrp must be between 0 and 1*/
	  	}
	  
	  if (ud->fs < 0.0) {       /* fs error Check */
         ud->errcode = ERROR_FSVALUES;
         return "***********************\n"
         		 " internal error: (ziad)\n"
					 "fs value is negative !\n"
					 "***********************\n";			/* fs must be >= 0*/
        }
	  
	  if (ud->T < 0.0) {        /* T error Check */
         ud->errcode = ERROR_TVALUES;
         return "***********************\n"
         		 " internal error: (ziad)\n"
					 "T value is negative !\n"
					 "***********************\n";					/*T must be >= 0  */
        }
        
           	
     if ((ud->T == 0.0) && (ud->unt > 0))                /* unt error Check */
   	{
         ud->errcode = ERROR_TaUNITVALUES;
         return "***********************\n"
         		 " internal error: (ziad)\n"
					 "T and unt val. mismatch\n"
					 "***********************\n";			/*T must be specified, and > 0 in order to use polar units*/
   	}

    
    if ((ud->wrp == 1) && (ud->T == 0.0))                  /* wrp error Check */
        {
         ud->errcode = ERROR_TaWRAPVALUES;
         return "***********************\n"
         		 " internal error: (ziad)\n"
					 "wrp and T val. mismatch\n"
					 "***********************\n"; 			/*T must be specified, and > 0 in order to use polar warp*/
        }
	 if ((ud->out == NOPE) && (ud->outts == YUP))
	 		{
	 		 ud->errcode = ERROR_OUTCONFLICT;
	 		 return"***********************\n"
         		 "error: \n"
					 "Write flag must be on\n"
					 "to use Write ts\n"
					 "***********************\n";	
	 		
	 		}
	

	/* Open the logfile, regardless of the ascii output files */
	sprintf ( tmpstr , "%s.log" , ud->strout);
	ud->outlogfile = fopen (tmpstr,"w");


	if (ud->out == YUP)									/* open outfile */
				{					
					ud->outwrite = fopen (ud->strout,"w");
					
					if (ud->outts == YUP)
						{
							sprintf ( tmpstr , "%s.ts" , ud->strout);
							ud->outwritets = fopen (tmpstr,"w");
							
						}
					
					if ((ud->outwrite == NULL) || (ud->outlogfile == NULL) ||\
					    (ud->outwritets == NULL && ud->outts == YUP) )
						{
							ud->errcode = ERROR_FILEOPEN; 
							
							return "***********************\n"
									 "Could Not Write Outfile\n"
									 "***********************\n";
						}
	
				}
	
	/* Write out user variables to Logfile */
	write_ud (ud);			/* writes user data to a file */
	
	/*show_ud (ud,0);	*/			/* For some debugging */

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

   new_dset = MAKER_4D_to_typed_fbuc ( old_dset ,             /* input dataset */
          ud->new_prefix ,           /* output prefix */
          -1,	/* negative value indicating data type is like original brick */
          ud->ignore ,               /* ignore count */
          1 ,   /* detrend = ON Let BOB do it*/
          NBUCKETS,					/*Number of values at each voxel*/
			 DELAY_tsfuncV2 ,         /* timeseries processor (bucket version)*/
			 (void *)ud,          /* data for tsfunc */
			 NULL, 0							) ; 
										 
   /* Setup the label, keywords and types of subbricks */
	i = 0;
	while (i < NBUCKETS)
		{
			switch (i)
				{
					case DELINDX:					/* delay value in results vector */
						EDIT_BRICK_LABEL (new_dset,i,"Delay");
						EDIT_BRICK_ADDKEY (new_dset,i,"D");
						++i;
						break;
					case COVINDX:					/* covariance value in results vector */
						EDIT_BRICK_LABEL (new_dset,i,"Covariance");
						EDIT_BRICK_ADDKEY (new_dset,i,"I");
						++i;
						break;
					case COFINDX:					/* cross correlation coefficient value in results vector */
						EDIT_BRICK_LABEL (new_dset,i,"Corr. Coef.");
						EDIT_BRICK_ADDKEY (new_dset,i,"r");
						/* Here you must modify either ud->Nfit or ud->Nort or most likely ud->nsamp based on ud->Navg */
						EDIT_BRICK_TO_FICO (new_dset,i,ud->nsamp - ud->ignore,ud->Nfit,ud->Nort);
						++i;
						break;
					case VARINDX:					/* FMRI time course variance value in results vector */
						EDIT_BRICK_LABEL (new_dset,i,"Variance");
						EDIT_BRICK_ADDKEY (new_dset,i,"S2");
						++i;
						break;
					default :
						return "*********************\n"
								 "Internal Error (ziad)\n"
								 " Bad i value \n"
								 "*********************\n";
						break;
				}
				
		}
	
   
   if (!AFNI_noenv("AFNI_AUTOMATIC_FDR")) {
      THD_create_all_fdrcurves( new_dset );
   }
	PLUTO_add_dset( plint , new_dset , DSET_ACTION_MAKE_CURRENT ) ;
	
	

   if (ud->out == YUP)									/* close outfile and outlogfile*/
				{
					fclose (ud->outlogfile);
					fclose (ud->outwrite);
					if (ud->outts  == YUP) fclose (ud->outwritets);
				}
				else
				{
					if (ud->outlogfile != NULL)	fclose (ud->outlogfile);		/* close outlogfile */
				}
	
	free (tmpstr);		
	free (nprfxstr);
   return NULL ;  /* null string returned means all was OK */
}