/*
Difference between two CCR-MENU files
version 8/3/1995
Henk J.L. Witte
Hugo de Vries-Laboratory, University of Amsterdam
Kruislaan 318, 1098 SM Amsterdam, The Netherlands
email: henk_witte@sara.nl
usage:
diffccr mode header datain1 datain2 dataout (-i)
read_header reads a header file describing the CCR-MENU file. The order in
which vars/levels/timesteps are mentioned in the header is the order in
which they are processed.
Note that if you omit variables or timesteps or levels (and decrement the
number of levels for the variables) from the header file they will be
skipped when mode != 1 (mode = 1 may result in an error) and this is a
way to delete variables/timesteps from a file.
The header file has the following format:
#to_vis5d
number of variables, maximum number of levels, number of timesteps
number of rows, number of columns
variable name[1] number of levels var. [1]
variable name[2] number of levels var. [2]
variable name[n] number of levels var. [n]
level name[1]
level name[2]
level name[n]
timestep name[1] value for timestep[1]
timestep name[2] value for timestep[2]
timestep name[n] value for timestep[n]
names should correspond EXACTLY to names in the CCR-MENU file, as they
are used to search the datafile for the correct timestep/variable/level!
example:
#to_vis5d
4 4 12 40 48
T 4
T(1) 1
T(2) 1
T0 1
0.9910
850.0000
500.0000
250.0000
january
february
march
april
may
june
july
august
september
october
november
december
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "ccrutil.h"
#define MAXLEVELS 10
#define MAXVARS 100
#define MAXTIMES 12
FILE *fpin1,*fpin2,*fpout;
int i,Nr,Nc,NumVars,NumLev,NumTimes,Nl[MAXVARS],ires,
west_bound,east_bound,north_bound,south_bound;
int flag_i;
char VarName[MAXVARS][10],LevName[MAXLEVELS][10],TStepName[MAXTIMES][20];
char inStr[255];
int difference(FILE *fpin1, FILE *fpin2,FILE *fpout, int NumVars, int NumLev,
int NumTimes, int Nl[],int Nr, int Nc,char VarName[][10],char LevName[][10],
char TStepName[][20], int east_bound, int west_bound, int north_bound,
int south_bound,int flag_i)
/* Calculate difference between fields: data1 - data2 */
{
int it,iv,ir,ic,il,skip,val_cnt;
float val,val2;
fpos_t fpin_pos,fpin_pos2;
char inStr[255];
rewind(fpin1);
rewind(fpin2);
fgetpos(fpin1,&fpin_pos);
fgetpos(fpin2,&fpin_pos2);
for(it=0;it<NumTimes;it++) { /* for all timesteps */
fsetpos(fpin1,&fpin_pos); /* reset to start last timestep */
fsetpos(fpin2,&fpin_pos2); /* reset to start last timestep */
fpin1 = find_TS(fpin1,TStepName[it]);
fpin2 = find_TS(fpin2,TStepName[it]);
/* find current timestep in datafile */
if ((fpin1 == NULL)||(fpin2 == NULL))
goto err;
fgetpos(fpin1,&fpin_pos); /* start of current timestep */
fgetpos(fpin2,&fpin_pos2); /* start of current timestep */
for(iv=0;iv<NumVars;iv++) { /* for all variables */
for (il=0;il<Nl[iv] ;il++ ) { /* for all levels */
fsetpos(fpin1,&fpin_pos); /* reset to start current timestep */
fsetpos(fpin2,&fpin_pos2); /* reset to start current timestep */
if(flag_i == 1)
printf("[%s][%s][%s]\n",TStepName[it],VarName[iv],LevName[il]);
fpin1 = find_VL(fpin1,VarName[iv],LevName[il],TStepName[it]);
fpin2 = find_VL(fpin2,VarName[iv],LevName[il],TStepName[it]);
/* find current variable & level */
if ((fpin1 == NULL)||(fpin2 == NULL))
goto err;
for(skip=1;skip<=14;skip++) { /* process header */
fgets(inStr,255,fpin1);
fgets(inStr,255,fpin2);
fprintf(fpout,"%s",inStr);
}
val_cnt = 0;
for(ir=1;ir<=Nr;ir++) {
for(ic=1;ic<=Nc;ic++) {
fscanf(fpin1," %f",&val);
fscanf(fpin2," %f",&val2);
if((ir <= south_bound)&&(ir >= north_bound)&&
(ic >= west_bound)&&(ic <= east_bound)) {
val_cnt++;
if (val_cnt >= 8) {
fprintf(fpout,"%.6e\n",val-val2);
val_cnt = 0;
}
else
fprintf(fpout,"%.6e ",val-val2);
}
}
}
if (val_cnt != 0) {
fprintf(fpout,"\n");
val_cnt = 0;
}
} /* endfor levels*/
} /* endfor variables*/
} /* endfor timesteps*/
return 0;
err:
return -1;
}
int difference2(FILE *fpin1,FILE *fpin2, FILE *fpout, int NumVars, int NumLev,
int NumTimes, int Nl[],int Nr, int Nc,char VarName[][10],char LevName[][10],
char TStepName[][20], int east_bound, int west_bound, int north_bound,
int south_bound,int flag_i)
/* Calculate difference between fields: data1 - data2 */
{
int it,iv,ir,ic,il,skip,val_cnt;
float val,val2;
char inStr[255];
rewind(fpin1);
rewind(fpin2);
for(it=0;it<NumTimes;it++) { /* for all timesteps */
for(iv=0;iv<NumVars;iv++) { /* for all variables */
for (il=0;il<Nl[iv] ;il++ ) { /* for all levels */
if(flag_i == 1)
printf("[%s][%s][%s]\n",TStepName[it],VarName[iv],LevName[il]);
fpin1 = find_TSVL(fpin1,TStepName[it],VarName[iv],LevName[il]);
fpin2 = find_TSVL(fpin2,TStepName[it],VarName[iv],LevName[il]);
/* find current variable & level */
if ((fpin1 == NULL)||(fpin2 == NULL))
goto err;
for(skip=1;skip<=14;skip++) { /* process header */
fgets(inStr,255,fpin1);
fgets(inStr,255,fpin2);
fprintf(fpout,"%s",inStr);
}
val_cnt = 0;
for(ir=1;ir<=Nr;ir++) {
for(ic=1;ic<=Nc;ic++) {
fscanf(fpin1," %f",&val);
fscanf(fpin2," %f",&val2);
if((ir <= south_bound)&&(ir >= north_bound)&&
(ic >= west_bound)&&(ic <= east_bound)) {
val_cnt++;
if (val_cnt >= 8) {
fprintf(fpout,"%.6e\n",val-val2);
val_cnt = 0;
}
else
fprintf(fpout,"%.6e ",val-val2);
}
}
}
if (val_cnt != 0) {
fprintf(fpout,"\n");
val_cnt = 0;
}
} /* endfor levels*/
} /* endfor variables*/
} /* endfor timesteps*/
return 0;
err:
return -1;
}
main(int argc, char *argv[])
{
if (argc!=6 && argc!=7) {
printf("%s\n Usage: mode, header, data1, data2, output (-i)\n",
argv[0]);
printf("mode = 1: faster, timestep ordered data only\n");
}
else {
flag_i = 1;
if (argc==7 && strcmp(argv[6],"-i")==0)
flag_i = -1;
fpin1 = fopen(argv[2],"r");
if(fpin1 == NULL) {
printf("cannot open %s\n",argv[2]);
goto error;
}
if(read_header(fpin1,&NumVars,&NumLev,&NumTimes,Nl,&Nr,&Nc,VarName,LevName,
TStepName)!=0)
goto error;
printf("#variables [%i]\n#maxlevs[%i]\n#tsteps[%i]\n\n",NumVars,NumLev,
NumTimes);
printf("select area:\n");
printf("west east north south (default:[1][%i][1][%i])\n",Nr,Nc);
gets(inStr);
ires = sscanf(inStr,"%i%i%i%i",&west_bound,&east_bound,&north_bound,
&south_bound);
if (ires != 4) {
north_bound = 1;
south_bound = Nr;
west_bound = 1;
east_bound = Nc;
}
printf("selected: %i %i %i %i\n",west_bound,east_bound,north_bound,
south_bound);
printf("for header: Nr = [%i] Nc = [%i]\n",east_bound-west_bound+1,
south_bound-north_bound+1);
fclose(fpin1);
fpin1 = fopen(argv[3],"r");
if(fpin1 == NULL) {
printf("cannot open %s\n",argv[3]);
goto error;
}
fpin2 = fopen(argv[4],"r");
if(fpin2 == NULL) {
printf("cannot open %s\n",argv[4]);
goto error;
}
fpout = fopen(argv[5],"w");
if(fpout == NULL) {
printf("cannot open %s\n",argv[5]);
goto error;
}
if (strcmp(argv[1],"1")==0) {
if(difference(fpin1,fpin2,fpout,NumVars,NumLev,NumTimes,Nl,Nr,Nc,
VarName,LevName,TStepName,east_bound,west_bound,north_bound,
south_bound,flag_i)!=0)
goto error;
}
else {
if(difference2(fpin1,fpin2,fpout,NumVars,NumLev,NumTimes,Nl,Nr,Nc,
VarName,LevName,TStepName,east_bound,west_bound,north_bound,
south_bound,flag_i)!=0)
goto error;
}
fclose(fpout);
}
error:
exit(0);
}
syntax highlighted by Code2HTML, v. 0.9.1