Ejemplo n.º 1
0
double SUMA_NI_get_double(NI_element *nel, char *attrname)
{
   static char FuncName[]={"SUMA_NI_get_double"};
   double n=0;
   char *s=NULL;
   
   SUMA_ENTRY;
   if (nel && attrname && (s=NI_get_attribute(nel,attrname))) {
      n = strtod(s,NULL);
   }
   SUMA_RETURN(n);
}
Ejemplo n.º 2
0
int SUMA_NI_get_int(NI_element *nel, char *attrname)
{
   static char FuncName[]={"SUMA_NI_get_int"};
   int n=0;
   char *s=NULL;
   
   SUMA_ENTRY;
   if (nel && attrname && (s=NI_get_attribute(nel,attrname))) {
      n = (int)strtol(s,NULL,10);
   }
   SUMA_RETURN(n);
}
Ejemplo n.º 3
0
/* (broken out from AFNI_start_fetching_url)     22 Mar 2016 [rickr] */
static int vc_check_too_soon(void)
{
   NI_element *nel=NULL;
   char       *rhs;
   int         last_time, dtime;

   nel = AFNI_read_vctime() ;
   if( nel == NULL ) return 0;

   rhs = NI_get_attribute(nel , "version_check_time");
   if( rhs == NULL ) return 0;

   last_time = strtol(rhs,NULL,10);
   dtime = ((int)time(NULL)) - last_time;

   /* too soon to worry */
   if( dtime >= 0 && dtime < VDELAY ) {
      NI_free_element(nel);
      return 1;
   }

   /* warn on version change */
   rhs = NI_get_attribute(nel,"version_string") ;  /* 27 Jan 2003 */
   if( rhs != NULL && strcmp(rhs,AVERZHN) != 0 ){
      fprintf(stderr,
              "\n** Your AFNI version changed from %s to %s since last check\n",
              rhs , AVERZHN ) ;
   }

   /* possibly update global motd_old */
   rhs = NI_get_attribute(nel,"motd") ;            /* 29 Nov 2005 */
   if( rhs != NULL ) {
      if( motd_old ) free(motd_old);
      motd_old = strdup(rhs) ;
   }

   NI_free_element(nel);
   return 0;
}
Ejemplo n.º 4
0
char *SUMA_NI_AttrOfNamedElement(NI_group *ngr, char *elname, char *attrname)
{
   static char FuncName[]={"SUMA_NI_AttrOfNamedElement"};
   NI_element *nel = NULL;
   
   SUMA_ENTRY;
   
   if (!ngr || !elname || !attrname) { 
      SUMA_S_Err("NULL input");
      fprintf(SUMA_STDERR,"%s: %p %p %p\n", FuncName, ngr, elname, attrname); 
      SUMA_RETURN(NULL); 
   }
   nel = SUMA_FindNgrNamedElement(ngr, elname);
   if (!nel) SUMA_RETURN(NULL);
   SUMA_RETURN(NI_get_attribute(nel,attrname));
}
Ejemplo n.º 5
0
MRI_shindss * GRINCOR_read_input( char *fname )
{
   NI_element *nel=NULL ;
   char *dfname=NULL , *atr ;
   NI_float_array *facar ; NI_int_array *nvar, *nnode=NULL, *ninmask=NULL;
   MRI_shindss *shd ;
   long long nbytes_needed , nbytes_dfname=0 ; int fdes ;
   void *var ; int ids , nvmax , nvtot ;
   int datum , datum_size ;

   char *geometry_string=NULL ;
   THD_3dim_dataset *tdset=NULL; int nvox;
   int no_ivec=0 , *ivec=NULL , *nvals=NULL , nvec,ndset ; float *fac=NULL ;
   NI_str_array *slabar=NULL ;

   if( fname == NULL || *fname == '\0' ) GQUIT(NULL) ;

   /* get data element */

   if (!THD_is_ondisk(fname))
     GQUIT("not on disk") ;

   nelshd = nel = NI_read_element_fromfile(fname) ;

   if( nel == NULL || nel->type != NI_ELEMENT_TYPE )
     GQUIT("not properly formatted") ;
   if( strcmp(nel->name,"3dGroupInCorr") != 0 )
     GQUIT("data element name is not '3dGroupInCorr'") ;

   /* no data vector ==> using all voxels */

   no_ivec = ( nel->vec_num < 1 ||
               nel->vec_len < 1 || nel->vec_typ[0] != NI_INT ) ;

   /* number of vectors in each dataset */

   atr = NI_get_attribute(nel,"nvec");
   if( atr == NULL ) GQUIT("nvec attribute missing?") ;
   nvec = (int)strtod(atr,NULL) ;
   if( nvec < 2 || (!no_ivec && nel->vec_len != nvec) )
     GQUIT("nvec attribute has illegal value") ;

   /* number of datasets */

   atr = NI_get_attribute(nel,"ndset");
   if( atr == NULL ) GQUIT("ndset attribute missing") ;
   ndset = (int)strtod(atr,NULL) ;
   if( ndset < 1 ) GQUIT("ndset attribute has illegal value") ;

   /* number of time points in each dataset (varies with dataset) */

   atr = NI_get_attribute(nel,"nvals");
   if( atr == NULL ) GQUIT("nvals attribute missing") ;
   nvar = NI_decode_int_list(atr,",") ;
   if( nvar == NULL || nvar->num < ndset )
     GQUIT("nvals attribute doesn't match ndset") ;
   nvals = nvar->ar ; nvar->ar = NULL ; NI_delete_int_array(nvar) ;

   nvmax = nvtot = nvals[0] ;
   for( ids=1 ; ids < ndset ; ids++ ){             /* Feb 2011 */
     nvtot += nvals[ids] ;
     if( nvals[ids] > nvmax ) nvmax = nvals[ids] ;
   }

   /* dataset labels [23 May 2010] */

   atr = NI_get_attribute(nel,"dset_labels") ;
   if( atr != NULL ){
     slabar = NI_decode_string_list(atr,";,") ;
     if( slabar == NULL || slabar->num < ndset )
       GQUIT("dset_labels attribute invalid") ;
   }

   /* datum of datasets */

   atr = NI_get_attribute(nel,"datum") ;
   if( atr != NULL && strcasecmp(atr,"byte") == 0 ){
     datum = 1 ; datum_size = sizeof(sbyte) ;
   } else {
     datum = 2 ; datum_size = sizeof(short) ;
   }

   /* number of bytes needed:
        sizeof(datum) * number of vectors per dataset
                      * number of datasets
                      * sum of per dataset vector lengths */

   nbytes_needed = 0 ;
   for( ids=0 ; ids < ndset ; ids++ ) nbytes_needed += nvals[ids] ;
   nbytes_needed *= ((long long)nvec) * datum_size ;

   if( nbytes_needed >= twogig &&
       ( sizeof(void *) < 8 || sizeof(size_t) < 8 ) ) /* too much for 32-bit */
     GQUIT("datafile size exceeds 2 GB -- you need a 64-bit computer!") ;

   /* scale factor for each dataset */

   atr = NI_get_attribute(nel,"fac") ;
   if( atr == NULL ) GQUIT("fac attribute missing") ;
   facar = NI_decode_float_list(atr,",") ;
   if( facar == NULL || facar->num < ndset )
     GQUIT("can't decode fac attribute") ;
   fac = facar->ar ; facar->ar = NULL ; NI_delete_float_array(facar) ;

   for( ids=0 ; ids < ndset ; ids++ ) if( fac[ids] <= 0.0f ) fac[ids] = 1.0f ;

   /* grid definition */

   atr = NI_get_attribute(nel,"geometry") ;
   if( atr == NULL ) GQUIT("geometry attribute missing") ;
   geometry_string = strdup(atr) ;
   tdset = EDIT_geometry_constructor( geometry_string , "GrpInCorr" ) ;
   if( tdset == NULL ) GQUIT("can't decode geometry attribute") ;
   nvox = DSET_NVOX(tdset) ;
   if(  no_ivec && nvox != nvec )
     GQUIT("geometry attribute doesn't match nvec attribute") ;
   if( !no_ivec && nvox <  nvec )
     GQUIT("geometry attribute specifies too few voxels") ;

   /* name of data file: check its size against what's needed */

#if 0
   atr = NI_get_attribute(nel,"datafile") ;
   if( atr != NULL ){
     dfname = strdup(atr) ; nbytes_dfname = THD_filesize(dfname) ;
     if( nbytes_dfname <= 0 && strstr(dfname,"/") != NULL ){
       char *tnam = THD_trailname(atr,0) ;
       nbytes_dfname = THD_filesize(tnam) ;
       if( nbytes_dfname > 0 ){ free(dfname); dfname = strdup(tnam); }
     }
   }
#endif
   if( nbytes_dfname <= 0 && strstr(fname,".niml") != NULL ){
     if( dfname != NULL ) free(dfname) ;
     dfname = strdup(fname) ; strcpy(dfname+strlen(dfname)-5,".data") ;
     nbytes_dfname = THD_filesize(dfname) ;
   }
   if( nbytes_dfname <= 0 ){
     char mess[THD_MAX_NAME+256] ;
     sprintf(mess,"datafile is missing (%s)",dfname) ; GQUIT(mess) ;
   } else if( nbytes_dfname < nbytes_needed ){
     char mess[THD_MAX_NAME+1024] ;
     sprintf(mess,"datafile %s has %s bytes but needs at least %s",
              dfname ,
              commaized_integer_string(nbytes_dfname) ,
              commaized_integer_string(nbytes_needed) ) ;
     GQUIT(mess) ;
   } else {
     INFO_message("EIC: data file %s found with %s bytes of data",
                  dfname , commaized_integer_string(nbytes_dfname) ) ;
   }
   fdes = open( dfname , O_RDWR ) ;
   if( fdes < 0 ){
     char mess[THD_MAX_NAME+256] ;
     sprintf(mess,"can't open datafile (%s)",dfname) ; GQUIT(mess) ;
   }
   NI_set_attribute( nelshd , "datafile" , dfname ) ;

   /* ivec[i] is the voxel spatial index of the i-th vector */

   if( no_ivec ){
     ivec = NULL ;  /* means all voxels: ivec[i] == i */
   } else {
     ivec = (int *)nel->vec[0] ; /* copy pointer */
     nel->vec[0] = NULL ;        /* NULL out in element so won't be free-ed */
   }

   /* And stuff for LR surface pairs      ZSS Jan 09*/
   if ((atr=NI_get_attribute(nel,"LRpair_nnode"))) {
      nnode = NI_decode_int_list(atr,",") ;
   }
   if ((atr=NI_get_attribute(nel,"LRpair_ninmask"))) {
      ninmask = NI_decode_int_list(atr,",") ;
   }

   /* create output struct */

   shd = (MRI_shindss *)malloc(sizeof(MRI_shindss)) ;

   shd->nvals = nvals ; shd->nvals_max = nvmax ; shd->nvals_tot = nvtot ;
   shd->nvec  = nvec  ;
   shd->ndset = ndset ;

   shd->geometry_string = geometry_string ;
   shd->tdset           = tdset ;
   shd->dfname          = dfname ;
   shd->nvox            = nvox ;
   shd->nx = DSET_NX(tdset); shd->ny = DSET_NY(tdset); shd->nz = DSET_NZ(tdset);

   shd->ivec = ivec ;
   shd->fac  = fac  ;

   /* and surface fields...      ZSS      Jan 09 */
   if (nnode) {
      if (nnode->num != 2) GQUIT("LRpair_nnode must have 2 values");
      shd->nnode[0] = nnode->ar[0];
      shd->nnode[1] = nnode->ar[1];
      NI_delete_int_array(nnode); nnode=NULL;
   } else {
      shd->nnode[0] = shd->nnode[1] = -1 ;
   }
   if (ninmask) {
      if (ninmask->num != 2) GQUIT("LRpair_ninmask must have 2 values");
      shd->ninmask[0] = ninmask->ar[0];
      shd->ninmask[1] = ninmask->ar[1];
      NI_delete_int_array(ninmask); ninmask=NULL;
   } else {
      shd->ninmask[0] = shd->ninmask[1] = -1 ;
   }

   /*--- 07 Apr 2010: setup default use list (all of them) ---*/

   shd->nuse = ndset ;
   shd->use  = (int *)malloc(sizeof(int)*ndset) ;
   for( ids=0 ; ids < ndset ; ids++ ) shd->use[ids] = ids ;

   shd->dslab = (slabar != NULL) ? slabar->str : NULL ;  /* 23 May 2010 */

   /*--- now have to map data from disk ---*/

   var = mmap( 0 , (size_t)nbytes_needed ,
                   PROT_WRITE , THD_MMAP_FLAG , fdes , 0 ) ;
   close(fdes) ;  /* close file descriptor does not unmap data */

   if( var == (void *)(-1) ){ /* this is bad */
     ERROR_message(
       "EIC: file %s: can't mmap() datafile -- memory space exhausted?" , dfname ) ;
     free(shd) ; return NULL ;
   }

   /*-- create array of pointers to each dataset's data array --*/

   shd->datum = datum ;

   if( datum == 2 ){  /* shorts */
     shd->sv    = (short **)malloc(sizeof(short *)*ndset) ;
     shd->bv    = NULL ;
     shd->sv[0] = (short *)var ;
     for( ids=1 ; ids < ndset ; ids++ )
       shd->sv[ids] = shd->sv[ids-1] + nvals[ids-1]*nvec ;
   } else {           /* sbytes */
     shd->sv    = NULL ;
     shd->bv    = (sbyte **)malloc(sizeof(sbyte *)*ndset) ;
     shd->bv[0] = (sbyte *)var ;
     for( ids=1 ; ids < ndset ; ids++ )
       shd->bv[ids] = shd->bv[ids-1] + nvals[ids-1]*nvec ;
   }

   shd->nbytes = nbytes_needed ;
   return shd ;
}
Ejemplo n.º 6
0
int main( int argc , char *argv[] )
{
   NI_stream ns ;
   void *nini = NULL, *vel=NULL;
   NI_element *nel=NULL;
   char *strm=NULL, *attr=NULL;
   int nn, mode = NI_TEXT_MODE, shhh=0, exact=1;
   FILE *outf = stdout;
   char *aa=NULL, *select_attr=NULL, *select_attr_val=NULL;
   int dodup = 0, nodata=0, dostderr=1, isfile=0;
   int stat = 0, excl = 0;
   
   nn = 1;
   while (nn < argc && argv[nn][0] == '-') {
      if (!strcmp(argv[nn], "-help") || !strcmp(argv[nn], "-h")) {
         usage_niccc(strlen(argv[nn]) > 3 ? 2:1);
         exit(0);
      }
      if (!strcmp(argv[nn],"-dup")) {
         dodup = 1; ++nn; continue;
            }
      if (!strcmp(argv[nn],"-nodata")) {
         nodata = 0; ++nn; continue;
      }
      if (!strcmp(argv[nn],"-stdout")) {
         dostderr = 0; ++nn; continue;
      }
      if (!strcmp(argv[nn],"-#")) {
         mode = mode|NI_HEADERSHARP_FLAG; 
         ++nn; continue;
      }
      if (!strcmp(argv[nn],"-quiet")) {
         shhh=1; 
         ++nn; continue;
      }
      if (!strcmp(argv[nn],"-f")) {
         isfile=1; 
         ++nn; continue;
      }
      if (!strcmp(argv[nn],"-s")) {
         isfile=2; 
         ++nn; continue;
      }
      if (!strcmp(argv[nn],"-attribute")) {
         ++nn;
         if (nn >= argc) {
            fprintf(stderr,"Need attribute after -attribute\n");
            exit(1);
         }  
         attr=argv[nn]; 
         ++nn; continue;
      }
      if (!strcmp(argv[nn],"-nel_from_string")) {
         ++nn;
         if (nn >= argc) {
            fprintf(stderr,"Need string after -nel_from_string\n");
            exit(1);
         }  
         nini = (NI_element *)NI_read_element_fromstring(argv[nn]);
         
         ++nn; continue;
      }
      if (!strcmp(argv[nn],"-skip_nel_with_attr") ||
          !strcmp(argv[nn],"-find_nel_with_attr")) {
         if (strstr(argv[nn],"-find")) {
            excl=0;
         } else {
            excl=1;
         }
         ++nn;
         if (nn+1 >= argc) {
            fprintf(stderr,
               "Need attribute and value after -skip_nel_with_attr\n");
            exit(1);
         }  
         select_attr=argv[nn++];
         select_attr_val = argv[nn]; 
         ++nn; continue;
      }
      if (!strcmp(argv[nn],"-match")) {
         ++nn;
         if (nn >= argc) {
            fprintf(stderr,"Need parameter after -match\n");
            exit(1);
         }  
         if (!strcmp(argv[nn],"exact")) exact = 1;
         else if (!strcmp(argv[nn],"partial")) exact = 0;
         else {
            fprintf(stderr,"%s is not a valid value for -match. \n"
                           "Use either exact or partial\n", argv[nn]);
            exit(1);
         } 
         ++nn; continue;
      }
      ERROR_message("Bad option %s. See niccc -help for details.\n", 
               argv[nn]);
      suggest_best_prog_option(argv[0], argv[nn]);
      exit(1);
   }
   if( argc < 2 ){
      ERROR_exit("Too few options");
   }

   if (nodata) mode = mode&NI_HEADERONLY_FLAG;
   
   if (nn >= argc) {
      fprintf(stderr,"Usage: niccc [-dup] streamspec\n");exit(1);
   }
   
   strm = (char *) realloc(strm, (strlen(argv[nn])+32)*sizeof(char));
   if (isfile == 2) {
      sprintf(strm,"str:");
      ns = NI_stream_open( strm , "r" ) ;
      NI_stream_setbuf( ns , argv[nn] ) ;
   } else {
      if (isfile == 1) {
         sprintf(strm,"file:%s",argv[nn]);
      } else {
         strcpy(strm, argv[nn]);
      }
      ns = NI_stream_open( strm, "r" ) ;
      if( ns == NULL ){
         fprintf(stderr,"*** niccc: NI_stream_open fails for %s\n", strm) ; 
         if (THD_is_file(strm)) {
            fprintf(stderr,
               "  It looks like %s is a file.\n"
               "  Make sure you use option -f before it\n",
               strm) ;       
         }  
         exit(1) ;
      }
   }
   /*** NI_stream_setbufsize( ns , 6666 ) ; ***/
   while(1){
     nn = NI_stream_goodcheck( ns , 1 ) ;
     if( nn < 0 ){
       if (strncmp(strm,"file:",5) && strncmp(strm,"str:",4)) {
         fprintf(stderr,"\n*** niccc: Stream %s fails\n", strm); exit(1);
       } else {
         exit(stat);
       }
     }
     if( nn == 0 ){ NI_sleep(5); continue; }  /* waiting for Godot */

     if (dostderr) outf = stderr;
     
     if ( (nn = NI_stream_readcheck( ns , 1 ) ) > 0) { /* check for data */
       if (!excl) {
         stat = 1; /* using -find, exit with status if not found */
       } else {
         stat = 0; /* you got something, exit well */
       }
       while( (nini = NI_read_element( ns , 2 )) ) {
         if (select_attr) {
            if ((aa = NI_get_attribute(nini, select_attr))) {
               if (!strcmp(aa,select_attr_val)) { /* match */
                  if (excl) goto NEXT;
                  else stat = 0; /* found something */
               } else if (!excl) goto NEXT; /* no match */
            }
         }
         if (attr) {
            if (exact) {
               aa = NI_get_attribute(nini, attr);
               if (aa) {
                  if (shhh) fprintf(outf,"%s\n", aa); 
                  else fprintf(outf,"%s: %s\n",attr, aa); 
                  exit(0);
               } else {
                  if (!shhh) fprintf(stderr,"%s: Not found.\n", attr);
                  exit(1);
               }
            } else {
               int tt=NI_element_type(nini) ;
               int nn, nfound=0;
               if( tt == NI_ELEMENT_TYPE ){
                  nel=(NI_element *)nini;
                  for( nn=0 ; nn < nel->attr_num ; nn++ ) {
                     if( strncmp(nel->attr_lhs[nn],attr, 
                                 strlen(attr)) == 0 ) {
                        if (shhh) fprintf(outf,"%s\n", nel->attr_rhs[nn]); 
                        else fprintf(outf,"%s: %s\n",
                                    nel->attr_lhs[nn], nel->attr_rhs[nn]); 
                        ++nfound;
                     }
                  }
                  if (nfound) exit(0);
                  else {
                     if (!shhh) fprintf(stderr,"%s: Not found.\n", attr);
                     exit(1);
                  }
               } else {
                  if (strncmp(strm,"file:",5)) {
                     fprintf(stderr,"\n*** niccc: not ready for non elements\n");
                     exit(1);
                   } else {
                     exit(1);
                   }   
               }
            }
         }
         if (dodup) {
            if (!shhh) fprintf(stderr,
                           "*** niccc: duplication returned element:\n");
            vel = NI_duplicate(nini, 1);
            NI_free_element( nini ) ; nini=NULL;
            NIML_to_terminal( vel, mode, dostderr ) ;
         } else {
           if (!shhh) fprintf(stderr,"*** niccc: reading returned element:\n") ;
            NIML_to_terminal( nini, mode, dostderr ) ;
         }
         NEXT:
         if (nini) NI_free_element( nini ) ; nini=NULL;
         if (vel) NI_free_element( vel ); vel = NULL;
       }
     }
   } /* while stream is good */
}
Ejemplo n.º 7
0
int main( int argc , char *argv[] )
{
   MRI_IMAGE *inim , *outim ; float *iv ;
   int iarg , ii,jj , nreg , ntime , *tau=NULL , rnum ;
   NI_element *nelmat=NULL ; char *matname=NULL ;
   MTYPE rhomax=0.7 , bmax=0.7 ; int rhonum=7 , bnum=14 ;
   char *cgl , *rst ;
   matrix X ; vector y ;
   float cput ;
   reml_collection *rrcol ;

   if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
     printf(
      "Usage: 1dREMLfit [option] file.1D\n"
      "Least squares fit with REML estimation of the ARMA(1,1) noise.\n"
      "\n"
      "Options (the first one is mandatory)\n"
      "------------------------------------\n"
      " -matrix mmm = Read the matrix 'mmm', which should have been\n"
      "                 output from 3dDeconvolve via the '-x1D' option.\n"
      " -MAXrho rm  = Set the max allowed rho parameter to 'rm' (default=0.7).\n"
      " -Nrho nr    = Use 'nr' values for the rho parameter (default=7).\n"
      " -MAXb bm    = Set max allow MA b parameter to 'bm' (default=0.7).\n"
      " -Nb nb      = Use 'nb' values for the b parameter (default=7).\n"
     ) ;
      PRINT_COMPILE_DATE ; exit(0) ;
   }

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

      /** rho and del params **/

      if( strcmp(argv[iarg],"-MAXrho") == 0 ){
        rhomax = (MTYPE)strtod(argv[++iarg],NULL) ;
             if( rhomax < 0.3 ) rhomax = 0.3 ;
        else if( rhomax > 0.9 ) rhomax = 0.9 ;
        iarg++ ; continue ;
      }
      if( strcmp(argv[iarg],"-Nrho") == 0 ){
        rhonum = (int)strtod(argv[++iarg],NULL) ;
             if( rhonum <  2 ) rhonum =  2 ;
        else if( rhonum > 20 ) rhonum = 20 ;
        iarg++ ; continue ;
      }
      if( strcmp(argv[iarg],"-MAXb") == 0 ){
        bmax = (MTYPE)strtod(argv[++iarg],NULL) ;
             if( bmax < 0.3 ) bmax = 0.3 ;
        else if( bmax > 0.9 ) bmax = 0.9 ;
        iarg++ ; continue ;
      }
      if( strcmp(argv[iarg],"-Nb") == 0 ){
        bnum = (int)strtod(argv[++iarg],NULL) ;
             if( bnum <  2 ) bnum =  2 ;
        else if( bnum > 20 ) bnum = 20 ;
        iarg++ ; continue ;
      }

      /** -matrix **/

      if( strcmp(argv[iarg],"-matrix") == 0 ){
        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 ){                     /* try to read as a 1D file */
          MRI_IMAGE *nim ; float *nar ;
          nim = mri_read_1D(argv[iarg]) ;
          if( nim != NULL ){              /* construct a minimal NIML element */
            nelmat = NI_new_data_element( "matrix" , nim->nx ) ;
            nar    = MRI_FLOAT_PTR(nim) ;
            for( jj=0 ; jj < nim->ny ; jj++ )
              NI_add_column( nelmat , NI_FLOAT , nar + nim->nx*jj ) ;
            mri_free(nim) ;
          }
        }
        if( nelmat == NULL || nelmat->type != NI_ELEMENT_TYPE )
          ERROR_exit("Can't process -matrix file!");
        iarg++ ; continue ;
      }

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

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

   inim = mri_read_1D( argv[iarg] ) ;
   if( inim == NULL ) ERROR_exit("Can't read 1D file %s",argv[iarg]) ;

   nreg  = nelmat->vec_num ;
   ntime = nelmat->vec_len ;
   if( ntime != inim->nx )
     ERROR_exit("matrix vectors are %d long but input 1D file is %d long",
                ntime,inim->nx) ;

   cgl = NI_get_attribute( nelmat , "GoodList" ) ;
   if( cgl != NULL ){
     int Ngoodlist,*goodlist , Nruns,*runs ;
     NI_int_array *giar ;
     giar = NI_decode_int_list( cgl , ";," ) ;
     if( giar == NULL || giar->num < ntime )
       ERROR_exit("-matrix 'GoodList' badly formatted?") ;
     Ngoodlist = giar->num ; goodlist = giar->ar ;
     rst = NI_get_attribute( nelmat , "RunStart" ) ;
     if( rst != NULL ){
       NI_int_array *riar = NI_decode_int_list( rst , ";,") ;
       if( riar == NULL ) ERROR_exit("-matrix 'RunStart' badly formatted?") ;
       Nruns = riar->num ; runs = riar->ar ;
     } else {
       Nruns = 1 ; runs = calloc(sizeof(int),1) ;
     }
     rnum = 0 ; tau = (int *)malloc(sizeof(int)*ntime) ;
     for( ii=0 ; ii < ntime ; ii++ ){
       jj = goodlist[ii] ;
       for( ; rnum+1 < Nruns && jj >= runs[rnum+1] ; rnum++ ) ; /*nada*/
       tau[ii] = jj + 10000*rnum ;
     }
   }

   matrix_initialize( &X ) ;
   matrix_create( ntime , nreg , &X ) ;
   if( nelmat->vec_typ[0] == NI_FLOAT ){
     float *cd ;
     for( jj=0 ; jj < nreg ; jj++ ){
       cd = (float *)nelmat->vec[jj] ;
       for( ii=0 ; ii < ntime ; ii++ ) X.elts[ii][jj] = (MTYPE)cd[ii] ;
     }
   } else if( nelmat->vec_typ[0] == NI_DOUBLE ){
     double *cd ;
     for( jj=0 ; jj < nreg ; jj++ ){
       cd = (double *)nelmat->vec[jj] ;
       for( ii=0 ; ii < ntime ; ii++ ) X.elts[ii][jj] = (MTYPE)cd[ii] ;
     }
   } else {
     ERROR_exit("-matrix file stored will illegal data type!?") ;
   }

   cput = COX_cpu_time() ;
   rrcol = REML_setup( &X , tau , rhonum,rhomax,bnum,bmax ) ;
   if( rrcol == NULL ) ERROR_exit("REML setup fails?" ) ;
   cput = COX_cpu_time() - cput ;
   INFO_message("REML setup: rows=%d cols=%d %d cases CPU=%.2f",
                ntime,nreg,rrcol->nset,cput) ;

   cput = COX_cpu_time() ;
   vector_initialize( &y ) ; vector_create_noinit( ntime , &y ) ;
   for( jj=0 ; jj < inim->ny ; jj++ ){
     iv = MRI_FLOAT_PTR(inim) + ntime*jj ;
     for( ii=0 ; ii < ntime ; ii++ ) y.elts[ii] = (MTYPE)iv[ii] ;
     (void)REML_find_best_case( &y , rrcol ) ;
     INFO_message(
       "Vector #%d: best_rho=%.2f best_b=%.2f best_lam=%.2f best_ssq=%g  olsq_ssq=%g",
       jj, REML_best_rho, REML_best_bb, REML_best_lam, REML_best_ssq, REML_olsq_ssq ) ;
   }
   cput = COX_cpu_time() - cput ;
   INFO_message("REML fitting: CPU=%.2f",cput) ;
   exit(0) ;
}
Ejemplo n.º 8
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.º 9
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) ;
}