Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

mri_symbolize.c File Reference

#include "mrilib.h"

Go to the source code of this file.


Functions

floatvecvecSYM_expand_ranges (int nlast, int nrang, SYM_irange *rang, char *str)

Function Documentation

floatvecvec* SYM_expand_ranges int    nlast,
int    nrang,
SYM_irange   rang,
char *    str
 

Expand a string like "Fred 2*Jed -Ned[1..3]" into a float vector.

Each SYM_irange struct has 4 fields

  • name = string that names this field
  • nbot,ntop = range of indexes valid for this name (nbot <= ntop, please)
  • gbot = global index that maps to nbot
The set of structs in rang[] should collectively span global indexes from 0..nlast (inclusive). The returned floatvec will have nlast+1 entries. ------------------------------------------------------------------------------

Definition at line 15 of file mri_symbolize.c.

References floatvec::ar, calloc, ENTRY, free, floatvecvec::fvar, SYM_irange::gbot, KILL_floatvec, malloc, MCW_get_intlist(), MCW_intlist_allow_negative(), name, floatvec::nar, SYM_irange::nbot, NI_decode_string_list(), NI_delete_str_array, SYM_irange::ntop, NI_str_array::num, floatvecvec::nvec, RETURN, NI_str_array::str, and strtod().

Referenced by read_glt_matrix().

00016 {
00017    floatvec *fv ;
00018    floatvecvec *fvv=NULL ;
00019    int rr , ii , ss , gg, *qlist , nvec=0 , iv ;
00020    NI_str_array *sar ;
00021    char qname[64] , *qstr , *qpt , *qls ;
00022    float fac ;
00023 
00024 ENTRY("SYM_expand_ranges") ;
00025 
00026    if( nlast < 0 ) RETURN(NULL) ;  /* bad input */
00027 
00028    /* check if have anything to scan for */
00029 
00030    if( nrang < 1 || rang == NULL || str == NULL || *str == '\0' ) RETURN(NULL) ;
00031 
00032    /* check if input line is a comment */
00033 
00034    for( ii=0 ; str[ii] != '\0' && isspace(str[ii]) ; ii++ ) ;  /*nada*/
00035 
00036    if( str[ii] == '\0' ||                   /* all blank */
00037        str[ii] == '#'  ||                   /* starts with "#" */
00038       (str[ii] == '/' && str[ii+1] == '/')  /* starts with "//" */
00039    ) RETURN(NULL) ;
00040 
00041    fv     = (floatvec *)malloc(sizeof(floatvec)) ;    /* create empty output */
00042    fv->nar = nlast+1 ;
00043    fv->ar  = (float *)calloc(sizeof(float),nlast+1) ;
00044 
00045    /* break input string into separate chunks */
00046 
00047    sar = NI_decode_string_list( str , "~" ) ;
00048    if( sar == NULL ){
00049      fvv  = (floatvecvec *)malloc(sizeof(floatvecvec)) ;
00050      fvv->nvec = 1 ;
00051      fvv->fvar = fv ;
00052      RETURN(fvv) ;
00053    }
00054 
00055    /* scan each chunk */
00056 
00057    for( ss=0 ; ss < sar->num ; ss++ ){
00058      qstr = sar->str[ss] ;
00059      if( qstr == NULL || *qstr == '\0' ) continue ;          /* bad entry? */
00060      if( *qstr == '#' ||                              /* comment ends line */
00061         (*qstr == '/' && *(qstr+1) == '/') ) break ;
00062 
00063      qstr  = strdup(sar->str[ss]) ;               /* duplicate for surgery */
00064      qls   = strchr(qstr,'[') ;      /* find and decode "[...]" subscripts */
00065      qlist = NULL ;                        /* if they are present, that is */
00066      if( qls != NULL ){
00067        *qls  = '\0' ;                  /* cut string off at '[' subscripts */
00068        qls++ ;                      /* will scan for intlist starting here */
00069      }
00070 
00071      qpt = strchr(qstr,'*') ;           /* find and decode factor in front */
00072      if( qpt != NULL ){                       /* if it is present, that is */
00073        fac = (float)strtod(qstr,NULL) ;
00074        if( fac == 0.0 && *qstr != '0' ) fac = 1.0 ;
00075        qpt++ ;
00076      } else if( *qstr == '+' ){                  /* "+" is same as "+1.0*" */
00077        qpt = qstr+1 ; fac =  1.0 ;
00078      } else if( *qstr == '-' ){                  /* "-" is same as "-1.0*" */
00079        qpt = qstr+1 ; fac = -1.0 ;
00080      } else {                                            /* default is "+" */
00081        qpt = qstr   ; fac =  1.0 ;
00082      }
00083 
00084      for( rr=0 ; rr < nrang ; rr++ )                 /* match name in list */
00085        if( strcmp(qpt,rang[rr].name) == 0 ) break ;
00086      if( rr == nrang ){                                      /* no match!? */
00087        fprintf(stderr,"** ERROR: can't match symbolic name '%s'\n",qpt) ;
00088        free((void *)qstr) ; continue ;
00089      }
00090                                        /* now scan for intlist, if present */
00091      if( qls != NULL ){
00092        MCW_intlist_allow_negative( (rang[rr].nbot < 0) ) ;
00093        qlist = MCW_get_intlist( rang[rr].ntop+1 , qls ) ;
00094 
00095        if( qlist != NULL && *qls == '[' ){  /** [[...]] type of subscript **/
00096          if( nvec == 0 ){
00097            nvec = qlist[0] ;
00098            fvv  = (floatvecvec *)malloc(sizeof(floatvecvec)) ;
00099            fvv->nvec = nvec ;
00100            fvv->fvar = (floatvec *)calloc(sizeof(floatvec),nvec) ;
00101            for( iv=0 ; iv < nvec ; iv++ ){
00102              fvv->fvar[iv].nar = nlast+1 ;
00103              fvv->fvar[iv].ar  = (float *)calloc(sizeof(float),nlast+1) ;
00104            }
00105          } else if( qlist[0] != nvec ){
00106            fprintf(stderr,"** ERROR: mismatch in use of -gltsym [[...]]: '%s'\n",
00107                    sar->str[ss] ) ;
00108            free((void *)qlist) ; free((void *)qstr) ;
00109            continue ;
00110          }
00111          for( iv=0 ; iv < nvec ; iv++ ){
00112            gg = qlist[iv+1] - rang[rr].nbot + rang[rr].gbot ;
00113            if( gg >= 0 && gg <= nlast ) fvv->fvar[iv].ar[gg] = fac ;
00114          }
00115          free((void *)qlist) ; free((void *)qstr) ;
00116          continue ;          /** skip to next one, since this was special **/
00117        }
00118      }
00119                                          /* make up a fake list, if needed */
00120      if( qlist == NULL ){
00121        qlist = (int *)malloc(sizeof(int)*(rang[rr].ntop-rang[rr].nbot+2)) ;
00122        qlist[0] = rang[rr].ntop-rang[rr].nbot+1 ;
00123        for( ii=0 ; ii < qlist[0] ; ii++ ) qlist[ii+1] = rang[rr].nbot+ii ;
00124      }
00125                                          /* insert values into output list */
00126 
00127      for( ii=0 ; ii < qlist[0] ; ii++ ){
00128        if( qlist[ii+1] < rang[rr].nbot || qlist[ii+1] > rang[rr].ntop ){
00129          fprintf(stderr,"** ERROR: subscript %s[%d] out of range %d..%d\n",
00130                  rang[rr].name , qlist[ii+1] , rang[rr].nbot,rang[rr].ntop ) ;
00131          continue ;
00132        }
00133        gg = qlist[ii+1] - rang[rr].nbot + rang[rr].gbot ;
00134        if( gg >= 0 && gg <= nlast ) fv->ar[gg] = fac ;
00135      }
00136 
00137      free((void *)qlist) ; free((void *)qstr) ;
00138    }
00139    MCW_intlist_allow_negative(0) ;
00140 
00141    NI_delete_str_array(sar);
00142 
00143    /* if had no [[...]] subscripts, only have 1 vector for output */
00144 
00145    if( nvec == 0 ){
00146      fvv  = (floatvecvec *)malloc(sizeof(floatvecvec)) ;
00147      fvv->nvec = 1 ;
00148      fvv->fvar = fv ;
00149    } else {              /* have multiple outputs */
00150      for( iv=0 ; iv < nvec ; iv++ ){
00151        for( gg=0 ; gg <= nlast ; gg++ ){
00152         if( fvv->fvar[iv].ar[gg] == 0.0f ) fvv->fvar[iv].ar[gg] = fv->ar[gg] ;
00153        }
00154      }
00155      KILL_floatvec(fv) ;
00156    }
00157 
00158    RETURN(fvv) ;
00159 }
 

Powered by Plone

This site conforms to the following standards: