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 }