コード例 #1
0
void THD_load_tcat( THD_datablock *dblk )
{
   int ivout , dd , iv ;
   THD_3dim_dataset *dset_in , *dset_out ;
   NI_str_array *sar ;

ENTRY("THD_load_tcat") ;

   if( !ISVALID_DBLK(dblk) ) EXRETURN ;
   dset_out = (THD_3dim_dataset *)dblk->parent ;
   if( !ISVALID_DSET(dset_out) ) EXRETURN ;
   sar = NI_decode_string_list( dset_out->tcat_list , "~" ) ;
   if( sar == NULL ) EXRETURN ;
   if( sar->num != dset_out->tcat_num ){ NI_delete_str_array(sar); EXRETURN; }

   ivout = 0 ;
   for( dd=0 ; dd < sar->num ; dd++ ){
     dset_in = THD_open_dataset( sar->str[dd] ) ;
     if( dset_in == NULL ){
       NI_delete_str_array(sar) ; DSET_unload(dset_out) ;
       EXRETURN ;
     }
     DSET_mallocize(dset_in) ; DSET_load(dset_in) ;
     if( !DSET_LOADED(dset_in) ){
       NI_delete_str_array(sar) ; DSET_unload(dset_out) ; DSET_delete(dset_in) ;
       EXRETURN ;
     }

     for( iv=0 ; iv < DSET_NVALS(dset_in) ; iv++ ){
       EDIT_substitute_brick( dset_out , ivout ,
                              DSET_BRICK_TYPE(dset_in,iv), DSET_ARRAY(dset_in,iv) );
       mri_fix_data_pointer( NULL , DSET_BRICK(dset_in,iv) ) ;
       EDIT_BRICK_FACTOR( dset_out , ivout , DSET_BRICK_FACTOR(dset_in,iv) ) ;
       EDIT_BRICK_LABEL(dset_out, ivout, 
                        DSET_BRICK_LABEL(dset_in, iv)); /* ZSS Aug. 27 2012 */
       ivout++ ;
     }
     DSET_delete(dset_in) ;
   }

   NI_delete_str_array(sar) ; EXRETURN ;
}
コード例 #2
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 ;
}
コード例 #3
0
THD_3dim_dataset * THD_open_tcat( char *dlist )
{
   THD_3dim_dataset *dset_out , **dset_in ;
   int ndset_in , dd , nerr , new_nvals, sb=0 ;
   NI_str_array *sar ;
   double angle=0.0;
   char *dp, *dlocal = dlist;   /* local dlist, in case it is altered */
   
ENTRY("THD_open_tcat") ;

   if( dlocal == NULL || *dlocal == '\0' ) RETURN(NULL) ;

   /* allow file list to be read from a file   23 Jul 2012 [rickr] */
   if( ! strncmp(dlocal, "filelist:", 9) ) {
      dlocal = AFNI_suck_file(dlocal+9) ;
      if ( ! dlocal ) {
         ERROR_message("THD_open_tcat: failed to open '%s' as filelist",
                       dlocal+9);
         RETURN(NULL) ;
      }
      /* make it look more like expected */
      for( dd=0, dp=dlocal; dd < strlen(dlocal); dd++, dp++ )
         if( *dp == '\n' || *dp  == '\r' ) *dp = ' ';
   }

   if( strchr(dlocal,' ') == NULL ){
     dset_out = THD_open_dataset(dlocal) ; RETURN(dset_out) ;
   }

   sar = NI_decode_string_list( dlocal , "~" ) ;
   if( sar == NULL ) RETURN(NULL) ;

   ndset_in = sar->num ;
   dset_in  = (THD_3dim_dataset **)malloc(sizeof(THD_3dim_dataset *)*sar->num) ;
   for( nerr=dd=0 ; dd < ndset_in ; dd++ ){
     dset_in[dd] = THD_open_dataset( sar->str[dd] ) ;
     if( dset_in[dd] == NULL ){
       fprintf(stderr,"** THD_open_tcat: can't open dataset %s\n",sar->str[dd]) ;
       nerr++ ;
     }
   }
   if( nerr > 0 ){
     for( dd=0 ; dd < ndset_in ; dd++ )
       if( dset_in[dd] != NULL ) DSET_delete(dset_in[dd]) ;
     free((void *)dset_in) ;
     NI_delete_str_array(sar) ;
     RETURN(NULL) ;
   }
   if( ndset_in == 1 ){
     dset_out = dset_in[0] ;
     free((void *)dset_in) ;
     NI_delete_str_array(sar) ;
     RETURN(dset_out) ;
   }

   (void)THD_check_for_duplicates( sar->num , sar->str , 1 ) ;  /* 31 May 2007 */

   for( nerr=0,dd=1 ; dd < ndset_in ; dd++ ){
     if( DSET_NX(dset_in[0]) != DSET_NX(dset_in[dd]) ||
         DSET_NY(dset_in[0]) != DSET_NY(dset_in[dd]) ||
         DSET_NZ(dset_in[0]) != DSET_NZ(dset_in[dd])   ){
       ERROR_message(
               "THD_open_tcat: %s [%dx%dx%d] doesn't match %s [%dx%dx%d]\n",
               sar->str[0] ,DSET_NX(dset_in[0]) ,
                            DSET_NY(dset_in[0]) ,DSET_NZ(dset_in[0]) ,
               sar->str[dd],DSET_NX(dset_in[dd]),
                            DSET_NY(dset_in[dd]),DSET_NZ(dset_in[dd]) ) ;
       nerr++ ;
     } else {
       if( !EQUIV_DATAXES(dset_in[dd]->daxes,dset_in[0]->daxes) ){
         WARNING_message(
                  "THD_open_tcat: %s grid mismatch with %s\n",
                  sar->str[0] , sar->str[dd] ) ;  /* don't increment nerr! */
       }
       angle = dset_obliquity_angle_diff(dset_in[dd], dset_in[0], -1.0);
       if (angle > 0.0) {
         WARNING_message(
            "dataset %s has an obliquity difference of %f degress with %s\n",
            dset_in[dd] ,
            angle, dset_in[0] );
       }
     }
   }
   if( nerr > 0 ){
     for( dd=0 ; dd < ndset_in ; dd++ )
       if( dset_in[dd] != NULL ) DSET_delete(dset_in[dd]) ;
     free((void *)dset_in) ;
     NI_delete_str_array(sar) ;
     RETURN(NULL) ;
   }

   /*-- Check for type problems                    ZSS: Aug 27 2012 --*/
   for (nerr=0,dd=0; dd < ndset_in ; dd++) {
      for (sb=0; sb < DSET_NVALS(dset_in[dd]); ++sb) {
         if ( DSET_BRICK_TYPE(dset_in[0],0) != 
              DSET_BRICK_TYPE(dset_in[dd],sb) ) {
            ++nerr;    
         }
      }
   }
   if (nerr > 0) { /* don't die, just complain */
      WARNING_message(
      "Command-line catenated dataset has %d sub-bricks that differ \n"
      "  in data type from the first sub-brick of the first set.\n"
      "  Mme Irma sees potential for grief if you go down that path. \n"
      "  Use 3dinfo -datum on each input to understand why this is happening.\n"
      "  You can use 3dcalc's -datum option to rewrite the dataset with \n"
      "  all sub-bricks set to the same type then start over.\n\n",
            nerr);
      nerr=0;
   }
   
   /*-- OK, start making new dataset --*/

   new_nvals = 0 ;
   for( dd=0 ; dd < ndset_in ; dd++ )
     new_nvals += DSET_NVALS(dset_in[dd]) ;

   for( dd=0 ; dd < ndset_in ; dd++ )
      if( DSET_TIMESTEP(dset_in[dd]) > 0.0 ) break ;  /* 1st 3D+time */
   if( dd == ndset_in ) dd = 0 ;

   dset_out = EDIT_empty_copy( dset_in[dd] ) ;

   /* since this is basically an input dataset, set the storage_mode
    * to match                                   27 Jul 2010 [rickr] */
   if( DSET_ONDISK(dset_out) && IS_VALID_NON_AFNI_DSET(dset_in[dd]) )
      THD_set_storage_mode(dset_out, dset_in[dd]->dblk->diskptr->storage_mode);

   EDIT_dset_items( dset_out ,
                      ADN_prefix    , "tcat" ,
                      ADN_func_type , ISANAT(dset_in[dd]) ? ANAT_EPI_TYPE
                                                          : FUNC_FIM_TYPE ,
                      ADN_ntt       , new_nvals ,
                      ADN_nvals     , new_nvals ,
                    ADN_none ) ;
   DSET_mallocize( dset_out ) ;

   /* check if we have a valid time axis; if not, make one up */

   if( DSET_TIMESTEP(dset_out) <= 0.0f ){
      float TR=1.0f , torg=0.0f , tdur=0.0f ;
      int tunits=UNITS_SEC_TYPE ;
      EDIT_dset_items( dset_out ,
                          ADN_tunits , tunits ,
                          ADN_ttdel  , TR ,
                          ADN_ttorg  , torg ,
                          ADN_ttdur  , tdur ,
                       ADN_none ) ;
   }

   dset_out->tcat_list = strdup( dlocal ) ;
   dset_out->tcat_num  = ndset_in ;
   dset_out->tcat_len  = (int *)malloc(sizeof(int)*ndset_in) ;
   for( dd=0 ; dd < ndset_in ; dd++ ){
     dset_out->tcat_len[dd] = DSET_NVALS(dset_in[dd]) ;
     DSET_delete(dset_in[dd]) ;
   }
   free((void *)dset_in) ;
   NI_delete_str_array(sar) ;

#if 0
fprintf(stderr,"THD_open_tcat('%s'):",dset_out->tcat_list);
for(dd=0;dd<ndset_in;dd++)fprintf(stderr," %d",dset_out->tcat_len[dd]);
fprintf(stderr,"\n");
#endif

   RETURN(dset_out) ;
}
コード例 #4
0
int THD_datablock_from_atr( THD_datablock *dblk, char *dirname, char *headname )
{
   THD_diskptr       *dkptr ;
   ATR_int           *atr_rank , *atr_dimen , *atr_scene , *atr_btype ;
   ATR_float         *atr_flt ;
   ATR_string        *atr_labs ;
   int   ii , view_type , func_type , dset_type , 
         nx,ny,nz,nvox , nvals , ibr,typ ;
   Boolean ok ;
   char prefix[THD_MAX_NAME]="Unknown" ;
   MRI_IMAGE *qim ;
   int brick_ccode ;
   char name[666] ;

ENTRY("THD_datablock_from_atr") ;

   if( dblk == NULL || dblk->natr <= 0 ) RETURN(0) ; /* bad input */

   dkptr = dblk->diskptr ;

   /*-- get relevant attributes: rank, dimensions, view_type & func_type --*/

   atr_rank  = THD_find_int_atr( dblk , ATRNAME_DATASET_RANK ) ;
   atr_dimen = THD_find_int_atr( dblk , ATRNAME_DATASET_DIMENSIONS ) ;
   atr_scene = THD_find_int_atr( dblk , ATRNAME_SCENE_TYPE ) ;

   /*-- missing an attribute ==> quit now --*/

   if( atr_rank == NULL || atr_dimen == NULL || atr_scene == NULL ) RETURN(0) ;

   /*-- load type codes from SCENE attribute --*/

   STATUS("loading *_type from SCENE") ;

   view_type = atr_scene->in[0] ;
   func_type = atr_scene->in[1] ;
   dset_type = atr_scene->in[2] ;

   /*-- load other values from attributes into relevant places --*/

   ok   = True ;
   nvox = 1 ;

   STATUS("loading from RANK") ;

   dkptr->rank = atr_rank->in[0] ;                /* N.B.: rank isn't used much */
   dkptr->nvals = dblk->nvals = nvals = atr_rank->in[1] ;  /* but nvals is used */

   STATUS("loading from DIMENSIONS") ;

   for( ii=0 ; ii < dkptr->rank ; ii++ ){
     dkptr->dimsizes[ii] = atr_dimen->in[ii] ;
     ok                  = ( ok && dkptr->dimsizes[ii] >= 1 ) ;
     nvox               *= dkptr->dimsizes[ii] ;
   }

#if 0
   if( PRINT_TRACING ){
     char str[256] ;
     sprintf(str,"rank=%d nvals=%d dim[0]=%d dim[1]=%d dim[2]=%d nvox=%d",
             dkptr->rank , dkptr->nvals ,
             dkptr->dimsizes[0] , dkptr->dimsizes[1] , dkptr->dimsizes[2] , nvox ) ;
     STATUS(str) ;
   }
#endif

   if( !ok || nvals < 1 ||
       dkptr->rank < THD_MIN_RANK || dkptr->rank > THD_MAX_RANK ){
     STATUS("bad rank!!??") ;
     RETURN(0) ;
   }

   /*-- create the storage filenames --*/

   STATUS("creating storage filenames") ;

   if( headname != NULL && strchr(headname,'+') != NULL ){
     FILENAME_TO_PREFIX(headname,prefix) ;
     THD_init_diskptr_names( dkptr, dirname,NULL,prefix , view_type , True ) ;
   } else {
     if( headname != NULL ) MCW_strncpy(prefix,headname,THD_MAX_NAME) ;
     THD_init_diskptr_names( dkptr, dirname,NULL,prefix , view_type , True ) ;
   }

   /*-- determine if the BRIK file exists --*/

   STATUS("checking if .BRIK file exists") ;

   brick_ccode = COMPRESS_filecode(dkptr->brick_name) ;
   if (dkptr->storage_mode == STORAGE_UNDEFINED) { /* ZSS: Oct. 2011 
               the next line was being called all the time before */
      if( brick_ccode != COMPRESS_NOFILE )
        dkptr->storage_mode = STORAGE_BY_BRICK ;  /* a .BRIK file */
   }
   
   /*-- if VOLUME_FILENAMES attribute exists, make it so [20 Jun 2002] --*/

   if( headname != NULL && dkptr->storage_mode == STORAGE_UNDEFINED ){
     atr_labs = THD_find_string_atr(dblk,"VOLUME_FILENAMES") ;
     if( atr_labs != NULL ){
       dkptr->storage_mode = STORAGE_BY_VOLUMES ;
       dblk->malloc_type   = DATABLOCK_MEM_MALLOC ;
     }
   }

   /*-- now set the memory allocation codes, etc. --*/

   dblk->brick_fac = (float *) XtMalloc( sizeof(float) * nvals ) ;
   for( ibr=0 ; ibr < nvals ; ibr++ ) dblk->brick_fac[ibr] = 0.0 ;

   /* scaling factors from short type to float type, if nonzero */

   if( !AFNI_yesenv("AFNI_IGNORE_BRICK_FLTFAC") ){
     atr_flt = THD_find_float_atr( dblk , ATRNAME_BRICK_FLTFAC ) ;
     if( atr_flt != NULL ){
       for( ibr=0 ; ibr < nvals && ibr < atr_flt->nfl ; ibr++ )
         dblk->brick_fac[ibr] = atr_flt->fl[ibr] ;
     }
   }

   /** Now create an empty shell of the "brick" == the data structure
       that will hold all the voxel data.  Note that all datablocks
       will have a brick, even if they never actually contain data
       themselves (are only warp-on-demand).

       If the BRICK_TYPES input attribute doesn't exist, then all
       sub-bricks are shorts.  This makes the code work with old-style
       datasets, which were always made up of shorts.
   **/

   atr_btype = THD_find_int_atr( dblk , ATRNAME_BRICK_TYPES ) ;

   if( atr_btype == NULL ){
     THD_init_datablock_brick( dblk , MRI_short , NULL ) ;
   } else {
     THD_init_datablock_brick( dblk , atr_btype->nin , atr_btype->in ) ;
   }

   if( !THD_datum_constant(dblk) ){ /* 15 Sep 2004 */
     fprintf(stderr,
             "\n** WARNING: File %s has mixed-type sub-bricks. ", MYHEAD ) ;
   }

   /* 25 April 1998: check if the byte order is stored inside */

   atr_labs = THD_find_string_atr( dblk , ATRNAME_BYTEORDER ) ;
   if( atr_labs != NULL && atr_labs->nch > 0 ){

     if( strncmp(atr_labs->ch,LSB_FIRST_STRING,ORDER_LEN) == 0 )
       dkptr->byte_order = LSB_FIRST ;
     else if( strncmp(atr_labs->ch,MSB_FIRST_STRING,ORDER_LEN) == 0 )
       dkptr->byte_order = MSB_FIRST ;
     else
       fprintf(stderr,"*** Unknown %s found in dataset %s\n",
               ATRNAME_BYTEORDER , MYHEAD ) ;

   } else if( !no_ordwarn                         &&
              DBLK_BRICK_TYPE(dblk,0) != MRI_byte &&
              dblk->diskptr->storage_mode == STORAGE_BY_BRICK ){ /* 20 Sep 1999 */

     static int first=1 ;
     if( first ){
       fprintf(stderr,
         "\n*** The situation below can be rectified with program '3drefit -byteorder':\n");
       first = 0 ;
     }
     fprintf(stderr," ** Dataset %s: assuming byteorder %s\n",
             MYHEAD , BYTE_ORDER_STRING(dkptr->byte_order)  ) ;
   }

   /* if the data is not on disk, the flag remains at DATABLOCK_MEM_UNDEFINED,
      otherwise the flag says how the memory for the bricks is to be created. */

   if( dkptr->storage_mode == STORAGE_BY_BRICK ){
#if MMAP_THRESHOLD > 0
     dblk->malloc_type = (dblk->total_bytes > MMAP_THRESHOLD)
                         ? DATABLOCK_MEM_MMAP : DATABLOCK_MEM_MALLOC ;
     DBLK_mmapfix(dblk) ;  /* 18 Mar 2005 */
#else
     dblk->malloc_type = DATABLOCK_MEM_MALLOC ;
#endif

     /* must be malloc-ed if:
           data is compressed,
           data is not in native byte order, or
           user explicity forbids use of mmap   */

     if( brick_ccode >= 0 || dkptr->byte_order != native_order || no_mmap )
        dblk->malloc_type = DATABLOCK_MEM_MALLOC ;
   }

   /* 30 Nov 1997: create the labels for sub-bricks */

   THD_init_datablock_labels( dblk ) ;

   atr_labs = THD_find_string_atr( dblk , ATRNAME_BRICK_LABS ) ;
   if( atr_labs != NULL && atr_labs->nch > 0 ){  /* create labels from attribute */
     int ipos = -1 , ipold , ngood ;

     for( ibr=0 ; ibr < nvals ; ibr++ ){  /* loop over bricks */

       for( ipold = ipos++ ;                                     /* skip to */
            ipos < atr_labs->nch && atr_labs->ch[ipos] != '\0' ; /* next \0 */
            ipos++ ) /* nada */ ;                                /* or end. */

       ngood = ipos - ipold - 1 ;                   /* number of good chars */
       if( ngood > 0 ){
         XtFree(dblk->brick_lab[ibr]) ;
         /* 27 Oct 2011 - increase to 64 */
         if( ngood > THD_MAX_SBLABEL ) ngood = THD_MAX_SBLABEL;  
         dblk->brick_lab[ibr] = (char *) XtMalloc(sizeof(char)*(ngood+2)) ;
         memcpy( dblk->brick_lab[ibr] , atr_labs->ch+(ipold+1) , ngood ) ;
         dblk->brick_lab[ibr][ngood] = '\0' ;

       }

        if( ipos >= atr_labs->nch ) break ;  /* nothing more to do */
     } /* end of loop over sub-bricks */
   }

   /* create the keywords for sub-bricks */

   THD_init_datablock_keywords( dblk ) ;

   atr_labs = THD_find_string_atr( dblk , ATRNAME_BRICK_KEYWORDS ) ;

   if( atr_labs != NULL && atr_labs->nch > 0 ){  /* create keywords from attribute */
     int ipos = -1 , ipold , ngood ;

     for( ibr=0 ; ibr < nvals ; ibr++ ){  /* loop over bricks */

       for( ipold = ipos++ ;                                     /* skip to */
            ipos < atr_labs->nch && atr_labs->ch[ipos] != '\0' ; /* next \0 */
            ipos++ ) /* nada */ ;                                /* or end. */

       ngood = ipos - ipold - 1 ;                   /* number of good chars */
       if( ngood > 0 ){
         XtFree(dblk->brick_keywords[ibr]) ;
         dblk->brick_keywords[ibr] = (char *) XtMalloc(sizeof(char)*(ngood+2)) ;
         memcpy( dblk->brick_keywords[ibr] , atr_labs->ch+(ipold+1) , ngood ) ;
         dblk->brick_keywords[ibr][ngood] = '\0' ;
       }

       if( ipos >= atr_labs->nch ) break ;  /* nothing more to do */
     } /* end of loop over sub-bricks */
   }

   /* create the auxiliary statistics stuff for each brick, if present */

   atr_labs = THD_find_string_atr( dblk , "BRICK_STATSYM" ) ;  /* 01 Jun 2005 */
   if( atr_labs != NULL && atr_labs->nch > 0 ){
     NI_str_array *sar ; int scode,np ; float parm[3] ;
     sar = NI_decode_string_list( atr_labs->ch , ";" ) ;
     if( sar != NULL && sar->num > 0 ){
       for( ibr=0 ; ibr < nvals && ibr < sar->num ; ibr++ ){
         NI_stat_decode( sar->str[ibr] , &scode , parm,parm+1,parm+2 ) ;
         if( scode >= AFNI_FIRST_STATCODE && scode <= AFNI_LAST_STATCODE ){
           np = NI_stat_numparam(scode) ;
           THD_store_datablock_stataux( dblk , ibr,scode,np,parm ) ;
         }
       }
       NI_delete_str_array(sar) ;
     }
   } else {          /*--- the olde way to get ye brick stataux parameters ---*/
     atr_flt = THD_find_float_atr( dblk , ATRNAME_BRICK_STATAUX ) ;
     if( atr_flt != NULL && atr_flt->nfl >= 3 ){
       int ipos=0 , iv,nv,jv ;

       /* attribute stores all stataux stuff as follows:
            sub-brick-index  statcode  no.-of-values value ... value
            sub-brick-index  statcode  no.-of-values value ... value, etc. */

       while( ipos <= atr_flt->nfl - 3 ){
         iv = (int) ( atr_flt->fl[ipos++] ) ;  /* which sub-brick */
         jv = (int) ( atr_flt->fl[ipos++] ) ;  /* statcode */
         nv = (int) ( atr_flt->fl[ipos++] ) ;  /* # of values that follow */

         if( nv > atr_flt->nfl - ipos ) nv = atr_flt->nfl - ipos ;

         THD_store_datablock_stataux( dblk , iv , jv , nv , atr_flt->fl + ipos ) ;
         ipos += nv ;
       }
     }
   }
#if 0
   if( PRINT_TRACING ){
     char str[256] ;
     sprintf(str,"rank=%d nvals=%d dim[0]=%d dim[1]=%d dim[2]=%d",
             dkptr->rank , dkptr->nvals ,
             dkptr->dimsizes[0] , dkptr->dimsizes[1] , dkptr->dimsizes[2] ) ;
     STATUS(str) ;
   }
#endif

   /*-- FDR curves [23 Jan 2008] --*/

   for( ibr=0 ; ibr < dblk->nvals ; ibr++ ){
     sprintf(name,"FDRCURVE_%06d",ibr) ;
     atr_flt = THD_find_float_atr( dblk , name ) ;
     if( atr_flt != NULL && atr_flt->nfl > 3 ){
       int nv = atr_flt->nfl - 2 ; floatvec *fv ;
       MAKE_floatvec(fv,nv) ;
       fv->x0 = atr_flt->fl[0] ; fv->dx = atr_flt->fl[1] ;
       memcpy( fv->ar , atr_flt->fl + 2 , sizeof(float)*nv ) ;
       if( dblk->brick_fdrcurve == NULL )
         dblk->brick_fdrcurve = (floatvec **)calloc(sizeof(floatvec *),dblk->nvals);
       dblk->brick_fdrcurve[ibr] = fv ;
     }
   }

   for( ibr=0 ; ibr < dblk->nvals ; ibr++ ){
     sprintf(name,"MDFCURVE_%06d",ibr) ;
     atr_flt = THD_find_float_atr( dblk , name ) ;
     if( atr_flt != NULL && atr_flt->nfl > 3 ){
       int nv = atr_flt->nfl - 2 ; floatvec *fv ;
       MAKE_floatvec(fv,nv) ;
       fv->x0 = atr_flt->fl[0] ; fv->dx = atr_flt->fl[1] ;
       memcpy( fv->ar , atr_flt->fl + 2 , sizeof(float)*nv ) ;
       if( dblk->brick_mdfcurve == NULL )
         dblk->brick_mdfcurve = (floatvec **)calloc(sizeof(floatvec *),dblk->nvals);
       dblk->brick_mdfcurve[ibr] = fv ;
     }
   }

   RETURN(1) ;
}
コード例 #5
0
ファイル: 1dcat.c プロジェクト: Gilles86/afni
int main( int argc , char * argv[] )
{
   int nim , ii , jj , kk , nx, narg, oform ;
   MRI_IMAGE **inim ;
   float *far;
   char *formatstr=NULL, *sel=NULL, *fname=NULL;
   int nonconst=0 , ncol,ncold , cc , nonfixed=0 , stack=0;
   intvec *ncv=NULL ;
   char *hline=NULL ;

   mainENTRY("1dcat:main");
   
   /*-- help? --*/

   if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
     printf(
"Usage: 1dcat [options] a.1D b.1D ...\n"
"  where each file a.1D, b.1D, etc. is a 1D file.\n"
"  In the simplest form, a 1D file is an ASCII file of numbers\n"
"  arranged in rows and columns.\n"
"\n"
"1dcat takes as input one or more 1D files, and writes out a 1D file\n"
"containing the side-by-side concatenation of all or a subset of the\n"
"columns from the input files.\n"
"\n"
"* Output goes to stdout (the screen); redirect (e.g., '>') to save elsewhere.\n"
"* All files MUST have the same number of rows!\n"
"* Any header lines (i.e., lines that start with '#') will be lost.\n"
"* For generic 1D file usage help and information, see '1dplot -help'\n"
"\n"
"OPTIONS:\n"
"--------\n"
"  -nonconst: Columns that are identically constant should be omitted\n"
"             from the output.\n"
"\n"
"  -nonfixed: Keep only columns that are marked as 'free' in the \n"
"             3dAllineate header from '-1Dparam_save'.\n"
"             If there is no such header, all columns are kept.\n"
"\n"
"  -form FORM: Format of the numbers to be output.\n"
"              You can also substitute -form FORM with shortcuts such \n"
"              as -i, -f, or -c.\n"
"              For help on -form's usage, and its shortcut versions\n"
"              see ccalc's help for the option of the same name. \n"
"\n"
"  -stack: Stack the columns of the resultant matrix in the output.\n"
"\n"
"  -sel SEL: Apply the same column/row selection string to all filenames\n"
"            on the command line.\n"
"            For example:\n"
"              1dcat -sel '[0,2]' f1.1D f2.1D\n"
"            is the same as: 1dcat f1.1D'[1,2]' f2.1D'[1,2]'\n"
"            The advantage of the option is that it allows wildcard use\n"
"            in file specification so that you can run something like:\n"
"              1dcat -sel '[0,2]' f?.1D\n"
"\n"
"EXAMPLE:\n"
"--------\n"
"  Input file 1:\n   1\n   2\n   3\n   4\n"
"  Input file 2:\n   5\n   6\n   7\n   8\n"
"\n"
"  1dcat data1.1D data2.1D > catout.1D\n" 
"  Output file: \n   1 5\n   2 6\n   3 7\n   4 8\n"
"\n"
           ) ;
      PRINT_COMPILE_DATE ; exit(0) ;
   }

   machdep() ;

   /* do we have any options? */
   oform = CCALC_NOT_SET; 
   sel = NULL;
   stack = 0;
   narg = 1;
   while (narg < argc && argv[narg][0] == '-') {

      if( strncmp(argv[narg],"-nonconst",7) == 0 ){  /* 04 Dec 2010 */
        nonconst++ ; narg++ ; continue ;
      }

      if( strncmp(argv[narg],"-nonfixed",7) == 0 ){  /* 06 Dec 2010 */
        nonfixed++ ; narg++ ; continue ;
      }
      
      if( strncmp(argv[narg],"-stack",6) == 0 ){  /* 05 Sep 2013 */
        stack = 1 ; narg++ ; continue ;
      }
      
      if (strcmp(argv[narg],"-form") == 0) {
         ++narg;
         if (narg >= argc)  {
	         fprintf (stderr, "need argument after -form ");
	         exit (1);
         }
         if (strcmp(argv[narg],"double") == 0 ) oform = CCALC_DOUBLE;
         else if (strcmp(argv[narg],"nice") == 0 ) oform = CCALC_NICE;
         else if (strcmp(argv[narg],"int") == 0 ) oform = CCALC_INT;
         else if (strcmp(argv[narg],"rint") == 0 ) oform = CCALC_INT;
         else if (strcmp(argv[narg],"fint") == 0 ) oform = CCALC_FINT;
         else if (strcmp(argv[narg],"cint") == 0 ) oform = CCALC_CINT;
         else if (strlen(argv[narg])<=256) {
            oform = CCALC_CUSTOM;
            formatstr = argv[narg];
         }
         else {
            fprintf (stderr,  "Format type '%s' not supported.\n"
                              "See -help for details.\n", argv[narg]);
            exit (1);
         }
         ++narg;
      } else if (strcmp(argv[narg],"-sel") == 0) {
         ++narg;
         if (narg >= argc)  {
	         fprintf (stderr, "need argument after -sel ");
	         exit (1);
         }
         sel = argv[narg]; ++narg;
      } else if (strncmp(argv[narg],"-d",2) == 0) {
         oform = CCALC_DOUBLE; ++narg;
      } else if (strncmp(argv[narg],"-n",2) == 0) {
         oform = CCALC_NICE; ++narg;
      } else if (strncmp(argv[narg],"-i",2) == 0) {
         oform = CCALC_INT; ++narg;
      } else if (strncmp(argv[narg],"-r",2) == 0) {
         oform = CCALC_INT; ++narg;
      } else if (strncmp(argv[narg],"-f",2) == 0) {
         oform = CCALC_FINT; ++narg;
      } else if (strncmp(argv[narg],"-c",2) == 0) {
         oform = CCALC_CINT; ++narg;
      } else { /* break if option is not recognized */
         ++narg;
         break; 
      }
   }
   
   /* read input files */

   nim = argc-narg ;
   inim = (MRI_IMAGE **) malloc( sizeof(MRI_IMAGE *) * nim ) ;
   ncol = 0 ;
   if( nonconst || nonfixed ) MAKE_intvec(ncv,1) ;
   for( jj=0 ; jj < nim ; jj++ ){

#if 0                                   /** for testing only **/
      if( AFNI_yesenv("ragged") ){
        MRI_IMAGE *qim ;
        qim      = mri_read_ascii_ragged( argv[jj+narg] , 3.e+33 ) ;
        fprintf(stderr,"qim: nx=%d ny=%d\n",qim->nx,qim->ny) ;
        inim[jj] = mri_transpose(qim) ; mri_free(qim) ;
      } else
#endif

      if (sel) {
         fname = (char *)
                  calloc((strlen(argv[jj+narg])+strlen(sel)+1), sizeof(char));
         strcat(fname, argv[jj+narg]); strcat(fname, sel);
      } else {
         fname = argv[jj+narg];  
      }
      inim[jj] = mri_read_1D( fname ) ;
      if( inim[jj] == NULL )
        ERROR_exit("Can't read input file '%s'",fname) ;
      if( jj > 0 && inim[jj]->nx != inim[0]->nx )
        ERROR_exit("Input file %s doesn't match first file %s in length!",
                   fname,argv[1]) ;

      ncold = ncol ; ncol += inim[jj]->ny ;
      if( ncv != NULL ){     /* check for constant columns [04 Dec 2010] */
        RESIZE_intvec(ncv,ncol) ;
        for( kk=0 ; kk < inim[jj]->ny ; kk++ ) ncv->ar[ncold+kk] = 1 ;
        far = MRI_FLOAT_PTR(inim[jj]) ; nx = inim[jj]->nx ;
        if( nonconst ){
          for( kk=0 ; kk < inim[jj]->ny ; kk++ ){ /* loop over columns */
            for( ii=1 ; ii < nx ; ii++ ){         /* loop down column */
              if( far[ii+kk*nx] != far[kk*nx] ) break ;
            }
            if( ii == nx ) ncv->ar[ncold+kk] = 0 ; /* constant */
          }
        }
        if( nonfixed ){
          char *hl = mri_read_1D_headerlines( fname ) ;
          if( hl != NULL && *hl == '#' ){
            char *spt = strchr(hl,'\n') ;
            if( spt != NULL ) spt = strchr(spt,'#') ; /* start of line 2 */
            if( spt != NULL ){
              NI_str_array *sar = NI_decode_string_list( spt+1 , "~" ) ;
              if( sar != NULL && sar->num >= inim[jj]->ny ){
                for( kk=0 ; kk < inim[jj]->ny ; kk++ ){
                  spt = strchr(sar->str[kk],'$') ;
                  if( spt != NULL && spt[1] == '\0' ) ncv->ar[ncold+kk] = 0 ;
                  else {
                    if( hline == NULL ) hline = strdup("#") ;
                    hline = THD_zzprintf( hline , " %s" , sar->str[kk] ) ;
                  }
                }
              }
              NI_delete_str_array(sar) ;
            }
          }
        }
      } /* end of computing ncv = array marking non-constant vectors */
      if (sel) {
         free(fname); fname = NULL;
      }
   } /* end of input loop */

   /* now do the output */

   if( hline != NULL ) printf("%s\n",hline) ;

   nx = inim[0]->nx ;

   if (stack) {
      if (oform == CCALC_NOT_SET) {
         for( cc=jj=0 ; jj < nim ; jj++ ){
            far = MRI_FLOAT_PTR(inim[jj]) ;
            for( kk=0 ; kk < inim[jj]->ny ; kk++,cc++ ){
               for( ii=0 ; ii < nx ; ii++ ){
                  if( ncv == NULL || ncv->ar[cc] )
                    printf(" %g\n", far[ii+kk*nx] ) ; 
               }
            }
         }
      } else {
         for( cc=jj=0 ; jj < nim ; jj++ ){
            far = MRI_FLOAT_PTR(inim[jj]) ;
            for( kk=0 ; kk < inim[jj]->ny ; kk++,cc++ ){
               for( ii=0 ; ii < nx ; ii++ ){
                  if( ncv == NULL || ncv->ar[cc] )
                    printf(" %s\n", 
                        format_value_4print(far[ii+kk*nx], oform, formatstr )); 
               }
            }
         }
      }
   } else {
      if (oform == CCALC_NOT_SET) {
         for( ii=0 ; ii < nx ; ii++ ){
            for( cc=jj=0 ; jj < nim ; jj++ ){
               far = MRI_FLOAT_PTR(inim[jj]) ;
               for( kk=0 ; kk < inim[jj]->ny ; kk++,cc++ ){
                  if( ncv == NULL || ncv->ar[cc] )
                    printf(" %g", far[ii+kk*nx] ) ; 
                 /* printf(" %+.2f", far[ii+kk*nx] ) ;*/
               }
            }
            printf("\n") ;
         }
      } else {
         for( ii=0 ; ii < nx ; ii++ ){
            for( cc=jj=0 ; jj < nim ; jj++ ){
               far = MRI_FLOAT_PTR(inim[jj]) ;
               for( kk=0 ; kk < inim[jj]->ny ; kk++,cc++ ){
                  if( ncv == NULL || ncv->ar[cc] )
                    printf(" %s", 
                        format_value_4print(far[ii+kk*nx], oform, formatstr )); 
               }
            }
            printf("\n") ;
         }
      }
   }
   exit(0) ;
}
コード例 #6
0
floatvecvec * SYM_expand_ranges( int nlast, int nrang, SYM_irange *rang, char *str )
{
   floatvec *fv ;
   floatvecvec *fvv=NULL ;
   int rr , ii , ss , gg, *qlist , nvec=0 , iv ;
   NI_str_array *sar ;
   char qname[64] , *qstr , *qpt , *qls ;
   float fac ;

ENTRY("SYM_expand_ranges") ;

   if( nlast < 0 ) RETURN(NULL) ;  /* bad input */

   /* check if have anything to scan for */

   if( nrang < 1 || rang == NULL || str == NULL || *str == '\0' ) RETURN(NULL) ;

   /* check if input line is a comment */

   for( ii=0 ; str[ii] != '\0' && isspace(str[ii]) ; ii++ ) ;  /*nada*/

   if( str[ii] == '\0' ||                   /* all blank */
       str[ii] == '#'  ||                   /* starts with "#" */
      (str[ii] == '/' && str[ii+1] == '/')  /* starts with "//" */
   ) RETURN(NULL) ;

   fv      = (floatvec *)malloc(sizeof(floatvec)) ;    /* create empty output */
   fv->nar = nlast+1 ;
   fv->ar  = (float *)calloc(sizeof(float),nlast+1) ;

   /* break input string into separate chunks */

   sar = NI_decode_string_list( str , "~" ) ;
   if( sar == NULL ){
     fvv  = (floatvecvec *)malloc(sizeof(floatvecvec)) ;
     fvv->nvec = 1 ;
     fvv->fvar = fv ;
     ERROR_message("empty line in -gltsym?") ; nerr++ ;
     RETURN(fvv) ;
   }

   /* scan each chunk */

   for( ss=0 ; ss < sar->num ; ss++ ){
     qstr = sar->str[ss] ;
     if( qstr == NULL || *qstr == '\0' ) continue ;          /* bad entry? */
     if( *qstr == '#' ||                              /* comment ends line */
        (*qstr == '/' && *(qstr+1) == '/') ) break ;

     qstr  = strdup(sar->str[ss]) ;               /* duplicate for surgery */
     qls   = strchr(qstr,'[') ;      /* find and decode "[...]" subscripts */
     qlist = NULL ;                        /* if they are present, that is */
     if( qls != NULL ){
       *qls  = '\0' ;                  /* cut string off at '[' subscripts */
       qls++ ;                      /* will scan for intlist starting here */
     }

     qpt = strchr(qstr,'*') ;           /* find and decode factor in front */
     if( qpt != NULL ){                       /* if it is present, that is */
       char *ept ;
       fac = (float)strtod(qstr,&ept) ;
       if( fac == 0.0f && ept == qstr ){     /* bad factor interpretation? */
         fac = 1.0f ;            /* ==> replace with 1, and bitch about it */
         WARNING_message(
           "-gltsym: Can't interpret '*' scale factor in '%s' -- replaced by 1",
           qstr) ;
       }
       if( ept != qpt )  /* 27 May 2008 */
         WARNING_message(
           "-gltsym: '*' scale factor in '%s' not at start of string?",qstr ) ;
       qpt++ ;
     } else if( *qstr == '+' ){                  /* "+" is same as "+1.0*" */
       qpt = qstr+1 ; fac =  1.0 ;
     } else if( *qstr == '-' ){                  /* "-" is same as "-1.0*" */
       qpt = qstr+1 ; fac = -1.0 ;
     } else {                                            /* default is "+" */
       qpt = qstr   ; fac =  1.0 ;
     }

     for( rr=0 ; rr < nrang ; rr++ )                 /* match name in list */
       if( strcmp(qpt,rang[rr].name) == 0 ) break ;
     if( rr == nrang ){                                      /* no match!? */
       ERROR_message("-gltsym: can't match symbolic name '%s'\n",qpt) ;
       nerr++ ; free((void *)qstr) ; continue ;
     }
                                       /* now scan for intlist, if present */
     if( qls != NULL ){
       MCW_intlist_allow_negative( (rang[rr].nbot < 0) ) ;
       qlist = MCW_get_intlist( rang[rr].ntop+1 , qls ) ;

       if( qlist != NULL && *qls == '[' ){  /** [[...]] type of subscript **/
         if( nvec == 0 ){
           nvec = qlist[0] ;
           fvv  = (floatvecvec *)malloc(sizeof(floatvecvec)) ;
           fvv->nvec = nvec ;
           fvv->fvar = (floatvec *)calloc(sizeof(floatvec),nvec) ;
           for( iv=0 ; iv < nvec ; iv++ ){
             fvv->fvar[iv].nar = nlast+1 ;
             fvv->fvar[iv].ar  = (float *)calloc(sizeof(float),nlast+1) ;
           }
         } else if( qlist[0] != nvec ){
           ERROR_message("mismatch in use of -gltsym [[...]]: '%s'\n",
                   sar->str[ss] ) ;
           nerr++ ;free((void *)qlist) ; free((void *)qstr) ;
           continue ;
         }
         for( iv=0 ; iv < nvec ; iv++ ){
           gg = qlist[iv+1] - rang[rr].nbot + rang[rr].gbot ;
           if( gg >= 0 && gg <= nlast ) fvv->fvar[iv].ar[gg] = fac ;
         }
         free((void *)qlist) ; free((void *)qstr) ;
         continue ;          /** skip to next one, since this was special **/
       }
     }
                                         /* make up a fake list, if needed */
     if( qlist == NULL ){
       qlist = (int *)malloc(sizeof(int)*(rang[rr].ntop-rang[rr].nbot+2)) ;
       qlist[0] = rang[rr].ntop-rang[rr].nbot+1 ;
       for( ii=0 ; ii < qlist[0] ; ii++ ) qlist[ii+1] = rang[rr].nbot+ii ;
     }
                                         /* insert values into output list */

     for( ii=0 ; ii < qlist[0] ; ii++ ){
       if( qlist[ii+1] < rang[rr].nbot || qlist[ii+1] > rang[rr].ntop ){
         ERROR_message("-gltsym subscript %s[%d] out of range %d..%d\n",
                 rang[rr].name , qlist[ii+1] , rang[rr].nbot,rang[rr].ntop ) ;
         nerr++ ; continue ;
       }
       gg = qlist[ii+1] - rang[rr].nbot + rang[rr].gbot ;
       if( gg >= 0 && gg <= nlast ) fv->ar[gg] = fac ;
     }

     free((void *)qlist) ; free((void *)qstr) ;
   }
   MCW_intlist_allow_negative(0) ;

   NI_delete_str_array(sar);

   /* if had no [[...]] subscripts, only have 1 vector for output */

   if( nvec == 0 ){
     fvv  = (floatvecvec *)malloc(sizeof(floatvecvec)) ;
     fvv->nvec = 1 ;
     fvv->fvar = fv ;
   } else {              /* have multiple outputs */
     for( iv=0 ; iv < nvec ; iv++ ){
       for( gg=0 ; gg <= nlast ; gg++ ){
        if( fvv->fvar[iv].ar[gg] == 0.0f ) fvv->fvar[iv].ar[gg] = fv->ar[gg] ;
       }
     }
     KILL_floatvec(fv) ;
   }

   RETURN(fvv) ;
}