00001 
00002 
00003 
00004 
00005 
00006    
00007 #include "multivector.h"
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 static void MV_fval_to_char( float qval , char * buf ) ;
00017 
00018 
00019 
00020 
00021 
00022 static int my_strequiv( char * s1 , char * s2 )
00023 {
00024    int ii , ll ;
00025 
00026    if( s1 == NULL && s2 == NULL ) return 1 ;
00027    if( s1 == NULL || s2 == NULL ) return 0 ;
00028    ii = strlen(s1) ; ll = strlen(s2) ; if( ii != ll ) return 0 ;
00029    for( ii=0 ; ii < ll ; ii++ )
00030       if( toupper(s1[ii]) != toupper(s2[ii]) ) return 0 ;
00031    return 1 ;
00032 }
00033 
00034 
00035 
00036 
00037 
00038 void multivector_free( multivector * mv )
00039 {
00040    int ii ;
00041 
00042    if( mv == NULL ) return ;
00043 
00044    if( mv->name != NULL ) free(mv->name) ;
00045    if( mv->type != NULL ) free(mv->type) ;
00046    if( mv->label != NULL )
00047       for( ii=0 ; ii < mv->nvec ; ii++ ) free(mv->label[ii]) ;
00048    if( mv->vec != NULL )
00049       for( ii=0 ; ii < mv->nvec ; ii++ ) free(mv->vec[ii]) ;
00050 
00051    free(mv) ; return ;
00052 }
00053 
00054 
00055 
00056 
00057 
00058 #define NVMAX 128
00059 #define LBUF  2048
00060 #define SEPCH " \t\n"
00061 
00062 #define MERR(ss) \
00063    fprintf(stderr,"*** multivector_read error; file=%s: %s\n",fname,ss)
00064 
00065 multivector * multivector_read( char * fname )
00066 {
00067    FILE * fp ;
00068    char buf[LBUF] ;
00069    char * ptr , * pp[NVMAX] ;
00070    multivector * mv ;
00071    int ii , ll , nvec,ndim , first=0 ;
00072    float val ;
00073 
00074    
00075 
00076    if( fname == NULL || fname[0] == '\0' ) return NULL ;
00077 
00078    fp = fopen( fname , "r" ) ;
00079    if( fp == NULL ){ MERR("can't open file"); return NULL; }
00080 
00081    mv = (multivector *) malloc( sizeof(multivector) ) ;
00082    nvec = ndim = mv->nvec = mv->ndim = 0 ;
00083    mv->name = strdup(fname) ;
00084    mv->type = NULL ; mv->label = NULL ; mv->vec = NULL ;
00085 
00086    
00087 
00088    while(1){
00089       ptr = fgets( buf , LBUF , fp ) ;
00090       if( ptr == NULL ){
00091          fclose(fp); multivector_free(mv); MERR("no data"); return NULL;
00092       }
00093 
00094       ll = strlen(buf) ;
00095       for( ii=ll-1 ; ii >= 0 ; ii-- ) if( !isspace(buf[ii]) ) break ;
00096       if( ii < 0 ) continue ;       
00097 
00098       if( buf[0] != '#' ){ first=1; break; }   
00099 
00100       ptr = strtok( buf , SEPCH ) ;
00101 
00102       
00103 
00104       if( my_strequiv(ptr,"#NAME") ){
00105          ptr = strtok( NULL , SEPCH ) ;
00106          if( ptr != NULL ){
00107             free(mv->name) ; mv->name = strdup(ptr) ;
00108          }
00109          continue ;  
00110       }
00111 
00112       
00113 
00114       if( my_strequiv(ptr,"#TYPE") ){
00115          int ntyp=0 , typ[NVMAX] ;
00116 
00117          if( mv->type != NULL ){
00118             fclose(fp); multivector_free(mv); MERR("second #TYPE"); return NULL;
00119          }
00120 
00121          
00122 
00123          while(1){
00124             ptr = strtok( NULL , SEPCH ) ;
00125             if( ptr == NULL ) break ;
00126 
00127             if( ntyp >= NVMAX ){
00128                fclose(fp); multivector_free(mv); MERR("oversize #TYPE"); return NULL;
00129             }
00130 
00131                  if( my_strequiv(ptr,"STRING") ) typ[ntyp++] = MV_STRING ;
00132             else if( my_strequiv(ptr,"FLOAT")  ) typ[ntyp++] = MV_FLOAT  ;
00133             else {
00134                fclose(fp); multivector_free(mv); MERR("illegal #TYPE"); return NULL;
00135             }
00136          }
00137 
00138          if( ntyp == 0 ){
00139             fclose(fp); multivector_free(mv); MERR("illegal #TYPE"); return NULL;
00140          }
00141 
00142          if( mv->nvec > 0 && ntyp != mv->nvec ){
00143             fclose(fp); multivector_free(mv); MERR("illegal #TYPE count"); return NULL;
00144          }
00145 
00146          if( mv->nvec == 0 ) nvec = mv->nvec = ntyp ;
00147          mv->type = (int *) malloc( sizeof(int) * ntyp ) ;
00148          for( ii=0 ; ii < ntyp ; ii++ ) mv->type[ii] = typ[ii] ;
00149          continue ;  
00150       }
00151 
00152       
00153 
00154       if( my_strequiv(ptr,"#LABEL") ){
00155          int nlab=0 ; char * lab[NVMAX] ;
00156 
00157          if( mv->label != NULL ){
00158             fclose(fp); multivector_free(mv); MERR("second #LABEL"); return NULL;
00159          }
00160 
00161          
00162 
00163          while(1){
00164             ptr = strtok( NULL , SEPCH ) ;
00165             if( ptr == NULL ) break ;
00166 
00167             if( nlab >= NVMAX ){
00168                for( ii=0 ; ii < nlab ; ii++ ) free( lab[ii] ) ;
00169                fclose(fp); multivector_free(mv); MERR("oversize #LABEL"); return NULL;
00170             }
00171 
00172             lab[nlab++] = strdup(ptr) ;
00173          }
00174 
00175          if( nlab == 0 ){
00176             fclose(fp); multivector_free(mv); MERR("illegal #LABEL"); return NULL;
00177          }
00178 
00179          if( mv->nvec > 0 && nlab != mv->nvec ){
00180             for( ii=0 ; ii < nlab ; ii++ ) free( lab[ii] ) ;
00181             fclose(fp); multivector_free(mv); MERR("illegal #LABEL count"); return NULL;
00182          }
00183 
00184          if( mv->nvec == 0 ) nvec = mv->nvec = nlab ;
00185          mv->label = (char **) malloc( sizeof(char *) * nlab ) ;
00186          for( ii=0 ; ii < nlab ; ii++ ) mv->label[ii] = lab[ii] ;
00187          continue ;  
00188       }
00189 
00190       
00191 
00192    } 
00193 
00194    
00195 
00196    while(1){
00197       if( !first ) ptr = fgets( buf , LBUF , fp ) ;
00198       if( ptr == NULL ) break ;        
00199       first = 0 ;
00200 
00201       ll = strlen(buf) ;
00202       for( ii=ll-1 ; ii >= 0 ; ii-- ) if( !isspace(buf[ii]) ) break ;
00203       if( ii < 0 ) continue ;         
00204       if( buf[0] == '#' ) continue ;  
00205 
00206       
00207 
00208       pp[0] = strtok(buf,SEPCH) ; if( pp[0] == NULL ) continue ;
00209       ll = 1 ;
00210       while(1){
00211          pp[ll] = strtok(NULL,SEPCH) ; if( pp[ll] == NULL ) break ;
00212          ll++ ;
00213       }
00214 
00215       
00216 
00217       if( nvec == 0 ){
00218           mv->nvec = nvec = ll ;
00219           if( nvec > NVMAX ) MERR("too many columns") ;
00220       }
00221       if( ll > nvec ) ll = nvec ;
00222 
00223       
00224 
00225       if( mv->type == NULL ){
00226          mv->type = (int *) malloc( sizeof(int) * nvec ) ;
00227          for( ii=0 ; ii < ll ; ii++ ){
00228             val = strtod( pp[ii] , &ptr ) ;
00229             if( *ptr != '\0' ) mv->type[ii] = MV_STRING ;
00230             else               mv->type[ii] = MV_FLOAT  ;
00231          }
00232          for( ; ii < nvec ; ii++ )    
00233             mv->type[ii] = MV_FLOAT ; 
00234       }
00235 
00236       
00237 
00238       if( mv->vec == NULL ){
00239          mv->vec = (void **) malloc( sizeof(void *) * nvec ) ;
00240          for( ii=0 ; ii < nvec ; ii++ )
00241             mv->vec[ii] = (void *) malloc( sizeof(float)*16 ) ;
00242       }
00243 
00244       
00245 
00246 
00247       for( ii=0 ; ii < nvec ; ii++ ){
00248          switch( mv->type[ii] ){
00249             case MV_FLOAT:{
00250                float * fpt ;
00251                mv->vec[ii] = (void *) realloc( mv->vec[ii], sizeof(float)*(ndim+1) );
00252                fpt = (float *) mv->vec[ii] ;
00253                fpt[ndim] = (ii < ll) ? strtod( pp[ii] , NULL ) : 0.0 ;
00254             }
00255             break ;
00256 
00257             case MV_STRING:{
00258                char ** cpt ;
00259                mv->vec[ii] = (void *) realloc( mv->vec[ii], sizeof(char *)*(ndim+1) );
00260                cpt = (char **) mv->vec[ii] ;
00261                cpt[ndim] = (ii < ll) ? strdup(pp[ii]) : strdup("\0") ;
00262             }
00263             break ;
00264           }
00265       }
00266       ndim++ ;   
00267 
00268    } 
00269 
00270    
00271 
00272    mv->ndim = ndim ; return mv ;
00273 }
00274 
00275 
00276 
00277 
00278 
00279 
00280 void multivector_set_name( multivector * mv , char * nname )
00281 {
00282    if( mv->name != NULL ){ free(mv->name); mv->name = NULL; }
00283 
00284    if( nname != NULL ) mv->name = strdup(nname) ;
00285    return ;
00286 }
00287 
00288 
00289 
00290 
00291 
00292 
00293 
00294 int multivector_write( char * fname , multivector * mv )
00295 {
00296    int nvec,ndim , ii,kk,ll , width[NVMAX] ;
00297    char buf[LBUF] , fbuf[32] ;
00298    FILE * fp ;
00299    float * fpt ;
00300    char ** cpt ;
00301 
00302    
00303 
00304    if( !THD_filename_ok(fname) || mv == NULL ) return 0 ;
00305 
00306    nvec = mv->nvec ; ndim = mv->ndim ;
00307    if( nvec < 1 || ndim < 1 ) return 0 ;
00308 
00309    if( mv->type == NULL || mv->vec == NULL ) return 0 ;
00310 
00311    
00312 
00313    if( strcmp(fname,"-") == 0 ){
00314       fp = stdout ;
00315    } else {
00316       fp = fopen( fname , "w" ) ; if( fp == NULL ) return 0 ;
00317    }
00318 
00319    if( mv->name != NULL ) fprintf(fp,"#NAME %s\n",mv->name) ;
00320 
00321    if( mv->label != NULL ){
00322       sprintf(buf,"#LABEL") ;
00323       for( ii=0 ; ii < nvec ; ii++ ){
00324          ll = strlen(buf) ;
00325          if( mv->label[ii] != NULL )
00326             sprintf(buf+ll," %s",mv->label[ii]) ;
00327          else
00328             sprintf(buf+ll," -none-") ;
00329       }
00330       fprintf(fp,"%s\n",buf) ;
00331    }
00332 
00333    sprintf(buf,"#TYPE") ;
00334    for( ii=0 ; ii < nvec ; ii++ ){
00335       ll = strlen(buf) ;
00336       switch( mv->type[ii] ){
00337          case MV_FLOAT:  sprintf(buf+ll," FLOAT" ) ; break ;
00338          case MV_STRING: sprintf(buf+ll," STRING") ; break ;
00339       }
00340       width[ii] = 1 ;
00341    }
00342    fprintf(fp,"%s\n",buf) ;
00343 
00344    
00345 
00346    for( kk=0 ; kk < ndim ; kk++ ){
00347       for( ii=0 ; ii < nvec ; ii++ ){
00348          switch( mv->type[ii] ){
00349             case MV_FLOAT:
00350                fpt = (float *) mv->vec[ii] ;
00351                MV_fval_to_char( fpt[kk] , fbuf ) ; ll = strlen(fbuf) ;
00352                width[ii] = MAX( width[ii] , ll ) ;
00353             break ;
00354 
00355             case MV_STRING:
00356                cpt = (char **) mv->vec[ii] ; ll = strlen(cpt[kk]) ;
00357                width[ii] = MAX( width[ii] , ll ) ;
00358             break ;
00359          }
00360       }
00361    }
00362 
00363    
00364 
00365    for( kk=0 ; kk < ndim ; kk++ ){
00366       buf[0] = '\0' ;
00367       for( ii=0 ; ii < nvec ; ii++ ){
00368          ll = strlen(buf) ;
00369          switch( mv->type[ii] ){
00370             case MV_FLOAT:
00371                fpt = (float *) mv->vec[ii] ;
00372                MV_fval_to_char( fpt[kk] , fbuf ) ;
00373                sprintf(buf+ll," %*s",width[ii],fbuf) ;
00374             break ;
00375 
00376             case MV_STRING:
00377                cpt = (char **) mv->vec[ii] ;
00378                sprintf(buf+ll," %*s",width[ii],cpt[kk]) ;
00379             break ;
00380          }
00381       }
00382       fprintf(fp,"%s\n",buf) ;
00383    }
00384 
00385    
00386 
00387    if( fp != stdout ) fclose(fp) ;
00388    return 1 ;
00389 }
00390 
00391 
00392 
00393 
00394 
00395 #define MV_NCOL 12
00396 
00397 static void MV_fval_to_char( float qval , char * buf )
00398 {
00399    float aval = fabs(qval) ;
00400    int lv ;
00401    char lbuf[32] ;
00402    int il ;
00403 
00404    
00405 
00406    if( qval == 0.0 ){ strcpy(buf,"0"); return; }
00407 
00408    lv = (fabs(qval) < 99999999.0) ? (int)qval : 100000001 ;
00409 
00410    if( qval == lv && abs(lv) < 100000000 ){
00411       sprintf( buf, "%d" , lv ) ; return ;
00412    }
00413 
00414 
00415 
00416 #undef  BSTRIP
00417 #define BSTRIP for( il=strlen(lbuf)-1 ;                        \
00418                     il>1 && (lbuf[il]=='0' || lbuf[il]==' ') ; \
00419                     il-- ) lbuf[il] = '\0'
00420 
00421    
00422 
00423    lv = (int) (10.0001 + log10(aval)) ;
00424 
00425    switch( lv ){
00426 
00427       default:
00428          if( qval > 0.0 ) sprintf( lbuf , "%-12.6e" , qval ) ;
00429          else             sprintf( lbuf , "%-12.5e" , qval ) ;
00430       break ;
00431 
00432       case  6:  
00433       case  7:  
00434       case  8:  
00435       case  9:  
00436       case 10:  
00437          sprintf( lbuf , "%-9.6f" , qval ) ; BSTRIP ; break ;
00438 
00439       case 11:  
00440          sprintf( lbuf , "%-9.5f" , qval ) ; BSTRIP ; break ;
00441 
00442       case 12:  
00443          sprintf( lbuf , "%-9.4f" , qval ) ; BSTRIP ; break ;
00444 
00445       case 13:  
00446          sprintf( lbuf , "%-9.3f" , qval ) ; BSTRIP ; break ;
00447 
00448       case 14:  
00449          sprintf( lbuf , "%-9.2f" , qval ) ; BSTRIP ; break ;
00450 
00451       case 15:  
00452          sprintf( lbuf , "%-9.1f" , qval ) ; BSTRIP ; break ;
00453 
00454       case 16:  
00455          sprintf( lbuf , "%-9.0f" , qval ) ; break ;
00456    }
00457 
00458    strcpy(buf,lbuf) ; return ;
00459 }
00460 
00461 
00462 
00463 
00464 char * MV_format_fval( float fval )
00465 {
00466    static char buf[32] ;
00467    MV_fval_to_char( fval , buf ) ;
00468    return buf ;
00469 }
00470 
00471 
00472 
00473 
00474 
00475 
00476 
00477 
00478 
00479 
00480 char * MV_format_fval2( float fval, int len)
00481 {
00482    static char buf[32] ;
00483    int wid;
00484    char *pos = NULL;
00485    
00486    MV_fval_to_char( fval , buf ) ;
00487    if (len < 1) return (buf);
00488    if (strlen(buf) < len) return (buf);
00489    
00490    
00491    pos = strchr (buf, '.');
00492    if (!pos) return(buf);  
00493    wid = pos - buf;
00494    if (wid < len) buf[len] = '\0';
00495    if (buf[len-1] == '.') buf[len-1] = '\0'; 
00496    return buf ;
00497 
00498 }