A histogram creator
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

262 lines
7.9 KiB

/******************************************************************/
/* */
/* 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�hrungszeichen werden nicht ver�ndert
' Ersetzt Tabulator durch Leerzeichen
' mehrfache Leerzeichen zwischen W�rtern werden entfernt
' wenn fl&=1 , gib Gro�buchstaben zur�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;
}