|
|
/******************************************************************/ |
|
|
/* */ |
|
|
/* Binning Routine fuer Histogramme */ |
|
|
/* */ |
|
|
/* little program to produce histograms from space separated */ |
|
|
/* input data files. Output is a space separated histogram. */ |
|
|
/* */ |
|
|
/* example: */ |
|
|
/* binning */ |
|
|
/* */ |
|
|
/* compile: gcc binning.c -o binning */ |
|
|
/* */ |
|
|
/* */ |
|
|
/* (c) Markus Hoffmann 1995 Letzte Bearbeitung: 30.03.1996 */ |
|
|
/* (c) Markus Hoffmann 1995-2010 Letzte Bearbeitung: 30.03.2010 */ |
|
|
/* */ |
|
|
/******************************************************************/ |
|
|
#include <stdio.h> |
|
|
#include <stdlib.h> |
|
|
#include <string.h> |
|
|
#include <unistd.h> |
|
|
#include <ctype.h> |
|
|
#ifdef WINDOWS |
|
|
#define EX_OK 0 |
|
|
#define EX_USAGE 0 |
|
|
#define EX_NOINPUT 0 |
|
|
#define EX_CANTCREAT 0 |
|
|
#else |
|
|
#include <sysexits.h> |
|
|
#endif |
|
|
#include <math.h> |
|
|
|
|
|
#define VERSION "1.03" |
|
|
#define VERSION_DATE "Mi 12. Mai 10:18:39 CEST 2010" |
|
|
|
|
|
#define FALSE 0 |
|
|
#define TRUE (!FALSE) |
|
|
#define PI 3.141592654 |
|
|
#define E 2.718281828 |
|
|
#define round(a) ((int)(a+0.5)) |
|
|
#define min(a,b) ((a<b)?a:b) |
|
|
#define max(a,b) ((a>b)?a:b) |
|
|
#define sgn(x) ((x<0)?-1:1) |
|
|
#define rad(x) (PI*x/180) |
|
|
#define deg(x) (180*x/PI) |
|
|
|
|
|
char *progname="binning"; |
|
|
int verbose=1; |
|
|
char *ifilename="input.dat"; |
|
|
char *ofilename="output.dat"; |
|
|
int *b; |
|
|
int n=200; |
|
|
int col=1; |
|
|
int doauto=FALSE; |
|
|
double anfang=-.6; |
|
|
double ende=.6; |
|
|
|
|
|
int wort_sep (char *,char,int,char *, char *); |
|
|
void xtrim(char *,int , char *); |
|
|
|
|
|
char *lineinput(FILE *n, char *line) { /* liest eine ganze Zeile aus einem ASCII-File ein */ |
|
|
char c; int i=0; |
|
|
|
|
|
while((c=fgetc(n))!=EOF) { |
|
|
if(c=='\n') { |
|
|
line[i]='\0'; |
|
|
return line; |
|
|
} else line[i++]=c; |
|
|
} |
|
|
line[i]='\0'; |
|
|
return line; |
|
|
} |
|
|
|
|
|
void usage(){ |
|
|
printf("Usage: binning [options] filename\n\n"); |
|
|
printf("--input filename --- Einlesefile [%s]\n",ifilename); |
|
|
printf("-o, --output file --- Outputfile [%s]\n",ofilename); |
|
|
printf("--anfang x --- Startbereich [%g]\n",anfang); |
|
|
printf("--ende x --- Endbereich [%g]\n",ende); |
|
|
printf("--auto --- Auto-Bereich [%s]\n",(doauto?"on":"off")); |
|
|
printf("-n x --- Anzahl Bins [%d]\n",n); |
|
|
printf("-c, --col x --- Spalte [%d]\n",col); |
|
|
puts( "-h --help --- Show usage\n" |
|
|
"-v --- be more verbose\n" |
|
|
"-q --- be more quiet"); |
|
|
} |
|
|
void intro(){ |
|
|
puts("*********************************************************\n" |
|
|
"* BINNING V." VERSION " *\n" |
|
|
"* (c) by Markus Hoffmann 1997-2010 *\n" |
|
|
"* version date: " VERSION_DATE " *\n" |
|
|
"*********************************************************\n"); |
|
|
} |
|
|
|
|
|
|
|
|
int main(int argc, char *argv[]) { |
|
|
FILE *dptr,*dptr2; |
|
|
|
|
|
double a,mean=0; |
|
|
int anzdata=0,over=0,under=0; |
|
|
double dmin=1e300,dmax=-1e300; |
|
|
char zz[2560],w1[2560]; |
|
|
int i,j=0,k; |
|
|
int DoExit=0; |
|
|
int doversion=0; |
|
|
|
|
|
progname=argv[0]; |
|
|
|
|
|
if(argc>1) { |
|
|
int count; |
|
|
for(count=1;count<argc;count++) { /* Kommandozeile bearbeiten */ |
|
|
if(strcmp(argv[count],"-h")==0 || strcmp(argv[count],"--help")==0) { |
|
|
usage(); |
|
|
DoExit=1; |
|
|
} |
|
|
else if(strcmp(argv[count],"-v")==0) verbose++; |
|
|
else if(strcmp(argv[count],"-q")==0) verbose--; |
|
|
else if(strcmp(argv[count],"--input")==0) ifilename=argv[++count]; |
|
|
else if(strcmp(argv[count],"-o")==0 || |
|
|
strcmp(argv[count],"--output")==0) ofilename=argv[++count]; |
|
|
else if(strcmp(argv[count],"-n")==0) n=atoi(argv[++count]); |
|
|
else if(strcmp(argv[count],"--anfang")==0) anfang=atof(argv[++count]); |
|
|
else if(strcmp(argv[count],"--ende")==0) ende=atof(argv[++count]); |
|
|
else if(strcmp(argv[count],"--auto")==0) doauto=TRUE; |
|
|
else if(strcmp(argv[count],"--version")==0) doversion=TRUE; |
|
|
else if(strcmp(argv[count],"-c")==0 || |
|
|
strcmp(argv[count],"--col")==0) col=atoi(argv[++count]); |
|
|
else if(*(argv[count])=='-') |
|
|
printf("%s: Unknown commandline option <%s> ignored.\n",progname,argv[count]); |
|
|
else |
|
|
ifilename=argv[count]; |
|
|
} |
|
|
} else { |
|
|
intro(); |
|
|
usage(); |
|
|
return(EX_USAGE); |
|
|
} /* zu weinig Parameter */ |
|
|
if(doversion) intro(); |
|
|
if(DoExit) return(EX_OK); |
|
|
|
|
|
|
|
|
b=(int *)malloc(n*sizeof(int)); |
|
|
|
|
|
/* ANzal der Daten zaehlen */ |
|
|
dptr2=fopen(ifilename,"r"); |
|
|
if(!dptr2) { |
|
|
printf("%s: ERROR, %s could not be read.\n",progname,ifilename); |
|
|
return(EX_NOINPUT); |
|
|
} |
|
|
if(verbose) printf("PASS 1 %s [",ifilename); |
|
|
while(feof(dptr2)==0) { |
|
|
lineinput(dptr2,zz); |
|
|
xtrim(zz,0,zz); |
|
|
if(strlen(zz) && *zz!='%' && *zz!='#') { |
|
|
for(i=0;i<col;i++) { |
|
|
wort_sep(zz,' ',0,w1,zz); |
|
|
} |
|
|
a=atof(w1); |
|
|
dmin=min(dmin,a); |
|
|
dmax=max(dmax,a); |
|
|
mean+=a; |
|
|
anzdata++; |
|
|
} |
|
|
} |
|
|
if(anzdata) mean/=anzdata; |
|
|
if(verbose) printf("] %d min=%g max=%g mean=%g\n",anzdata,dmin,dmax,mean); |
|
|
|
|
|
|
|
|
if(doauto==TRUE) { |
|
|
anfang=dmin; |
|
|
ende=dmax; |
|
|
} |
|
|
|
|
|
rewind(dptr2); /* prepare for PASS 2 */ |
|
|
|
|
|
if(verbose) printf("PASS 2 %s [",ifilename); |
|
|
while(feof(dptr2)==0) { |
|
|
lineinput(dptr2,zz); |
|
|
xtrim(zz,0,zz); |
|
|
if(strlen(zz) && zz[0]!='%' && *zz!='#') { |
|
|
for(i=0;i<col;i++) { |
|
|
wort_sep(zz,' ',0,w1,zz); |
|
|
} |
|
|
a=atof(w1); |
|
|
i=(int)(n*(a-anfang)/(ende-anfang)); |
|
|
if(i<0) under++; |
|
|
else if (i>=n) over++; |
|
|
else b[(int)(n*(a-anfang)/(ende-anfang))]++; |
|
|
} |
|
|
} |
|
|
fclose(dptr2); |
|
|
if(verbose) printf("] %d %d\n",under,over); |
|
|
|
|
|
|
|
|
dptr=fopen(ofilename,"w");j=0; |
|
|
if(!dptr) { |
|
|
printf("%s: ERROR, %s could not be created.\n",progname,ofilename); |
|
|
return(EX_CANTCREAT); |
|
|
} |
|
|
if(verbose) printf("> %s[",ofilename); |
|
|
|
|
|
fprintf(dptr,"# binning V." VERSION " (c) Markus Hoffmann 1997-2010\n"); |
|
|
fprintf(dptr,"# FILE=<%s> COL=%d\n",ifilename,col); |
|
|
fprintf(dptr,"# [%g:%g] %d\n",anfang,ende,n); |
|
|
fprintf(dptr,"# ANZDATA=%d\n",anzdata); |
|
|
fprintf(dptr,"# OVER= %d\n",over); |
|
|
fprintf(dptr,"# UNDER= %d\n",under); |
|
|
|
|
|
for(k=0;k<n;k++) { |
|
|
fprintf(dptr,"%g %d \n",(double)k/n*(ende-anfang)+anfang,b[k]); |
|
|
printf("."); j++; |
|
|
} |
|
|
fclose(dptr); |
|
|
if(verbose) printf("] %d \n",j); |
|
|
free(b); |
|
|
return(EX_OK); |
|
|
} |
|
|
int wort_sep (char *t,char c,int klamb ,char *w1, char *w2) { |
|
|
int f=0, klam=0; |
|
|
|
|
|
/* klamb=0 : keine Klammern werden beruecksichtigt |
|
|
klamb=1 : normale Klammern werden beruecksichtigt |
|
|
klamb=2 : eckige Klammern werden beruecksichtigt |
|
|
klamb=4 : geschweifte Klammern werden beruecksichtigt |
|
|
*/ |
|
|
|
|
|
if(!(*t)) return(*w1=*w2=0); |
|
|
|
|
|
while(*t && (*t!=c || f || klam>0)) { |
|
|
if(*t=='"') f=!f; |
|
|
else if(!f && (((klamb&1) && *t=='(') || ((klamb&2) && *t=='[') || ((klamb&4) && *t=='{'))) klam++; |
|
|
else if(!f && (((klamb&1) && *t==')') || ((klamb&2) && *t==']') || ((klamb&4) && *t=='}'))) klam--; |
|
|
*w1++=*t++; |
|
|
} |
|
|
if(!(*t)) { |
|
|
*w2=*w1=0; |
|
|
return(1); |
|
|
} else { |
|
|
*w1=0; |
|
|
strcpy(w2,++t); |
|
|
return(2); |
|
|
} |
|
|
} |
|
|
/* (c) Markus Hoffmann |
|
|
' Teile in Anf<EFBFBD>hrungszeichen werden nicht ver<EFBFBD>ndert |
|
|
' Ersetzt Tabulator durch Leerzeichen |
|
|
' mehrfache Leerzeichen zwischen W<EFBFBD>rtern werden entfernt |
|
|
' wenn fl&=1 , gib Gro<EFBFBD>buchstaben zur<EFBFBD>ck |
|
|
*/ |
|
|
|
|
|
void xtrim(char *t,int f, char *w ) { |
|
|
register int a=0,u=0,b=0; |
|
|
while(*t) { |
|
|
while(*t && (!isspace(*t) || a)) { |
|
|
if(*t=='"') a=!a; |
|
|
u=1; if(b==1) {*w++=' '; b=0;} |
|
|
if(f && !a) *w++=toupper(*t++); else *w++=*t++; |
|
|
} |
|
|
if(u && !b) b=1; |
|
|
if(*t) t++; |
|
|
} *w=0; |
|
|
}
|
|
|
|