/* read_xmrg2.c Last modified: 2/1/2006 Added capability to work on either Big Endian or Little Endian machines. This program reads an xmrg file and writes to an ASCII vector file with each line containing col# row# and data (in mm) starting from lower left corner of the region. The program recognizes two types of xmrg headers; pre- and post AWIPS Bld 4.2 (also modified in Jan. 2000 to recognize pre-1997 headers which don't have a second record in the header). The following syntax may be used to compile and to execute on HP workstations. 1) To create an executable; (on HPUNIX) cc -g -Aa -o read_xmrg2 read_xmrg2.c (on Linux) using gcc: gcc -o read_xmrg2 read_xmrg2.c 2) To run; read_xmrg xmrgmmddyyhhz where xmrgmmddyyhhz is an input XMRG file name. The output file produced is xmrgmmddyyhhz.out. The orientation of the precipitation field with respect to the i and j indices used in the program is as follows: i j physical location ------------------------------------------------------------------ 0 0 lowerleft corner of the RFC rectangle MAXX-1 0 lowerright corner of the RFC rectangle 0 MAXY-1 upperleft corner of the RFC rectangle MAXX-1 MAXY-1 uppperright corner of the RFC rectangle The HRAP coordinates of the lowerleft corner of the RFC rectangle is given by (IORIG,JORIG) in the XMRG file header (see below). Note that the point (float(IORIG),float(JORIG)) corresponds to the lowerleft corner of the HRAP box in the lowerleft corner of the RFC rectangle. The lat-lon of this point can be obtained from the subroutine hrap_to_latlon(float(IORIG),float(JORIG),flon,flat). Likewise, the lat-lon of the upperright corner of the HRAP box in the upperright corner of the RFC rectangle is given by hrap_to_latlon(float(IORIG+MAXX),float(JORIG+MAXY),flon,flat). */ #include #include #include main(int argc,char *argv[]) { FILE *in_file_ptr,*out_file_ptr; char user_id[10],date[10],time[10],process_flag[8]; char date2[10],time2[10]; char out_name[20]; int rfchd[4]; int numbytes_a[2]; int numbytes; int MAXX,MAXY,IORIG,JORIG; int i,j; signed char fourbyte_ptr[4],end_ptr[4]; signed char numbytes_ptr[4]; short *onerow; float **matrix; float outval; short int reversebytes; void reverse_byte_order(int *,int); void reverse_byte_order_short(short *,int); /* end variable declaration */ if (argc != 2) { (void)printf("Incorrect number of arguments. Should be 2.\n"); exit(0); } in_file_ptr=fopen(argv[1],"rb"); if (in_file_ptr == NULL) { (void)printf("Can not open file %s for input.\n",argv[1]); return(1); } (void)strcpy(out_name,argv[1]); (void)strcat(out_name,".out"); out_file_ptr=fopen(out_name,"w"); /* start reading the XMRG file*/ /* determine if byte reversal is needed */ fread(&numbytes,sizeof(int),1,in_file_ptr); if (numbytes != 16) reversebytes = 1; else reversebytes = 0; /*SEEK_SET specifies the position offset from the beginning of the file*/ fseek(in_file_ptr, 4, SEEK_SET); for(i=0;i<4;i++) { fread(&rfchd[i], sizeof(int), 1, in_file_ptr); } if (reversebytes) (void) reverse_byte_order(rfchd,4); IORIG=rfchd[0]; JORIG=rfchd[1]; MAXX=rfchd[2]; MAXY=rfchd[3]; /*echo to screen*/ (void)printf("x-coordinate (HRAP) of the lowerleft corner of the RFC rectangle %d\n",IORIG); (void)printf("y-coordinate (HRAP) of the lowerleft corner of the RFC rectangle %d\n",JORIG); (void)printf("number of HRAP bins along the x-coordinate in the RFC rectangle %d\n",MAXX); (void)printf("number of HRAP bins along the y-coordinate in the RFC rectangle %d\n",MAXY); /*each record is preceded and followed by 4 bytes*/ /*first record is 4+16+4 bytes*/ fseek(in_file_ptr, 20, SEEK_SET); /*read second FORTRAN record*/ /*here I am reading an array with two elements instead of 1*/ /*because I couldn't successfully get the reverse_byte_order*/ /*routine to work with other approaches*/ fread(&numbytes_a,sizeof(int),2,in_file_ptr); if (reversebytes) (void)reverse_byte_order(numbytes_a,2); (void)printf("numbytes %d\n",numbytes_a[1]); numbytes=numbytes_a[1]; /*********************************************************** * account for all possible header lengths in xmrg files ************************************************************/ if ((int) numbytes == 66) { /* first record (24) plus second record(74=66+8) is 98*/ fseek(in_file_ptr, 98, SEEK_SET); /*(void)printf("user_id %10s\n",user_id); (void)printf("date %10s\n",date); (void)printf("time %10s\n",time); (void)printf("process_flag %8s\n",process_flag); (void)printf("datelen %d\n",strlen(date)); (void)printf("timelen %d\n",strlen(time)); (void)printf("user_id %d\n",strlen(user_id)); (void)printf("date2 %s\n",date2); (void)printf("time2 %s\n",time2);*/ } else if ((int) numbytes==38) { fseek(in_file_ptr, 70, SEEK_SET); /*(void)printf("user_id %10s\n",user_id); (void)printf("date %10s\n",date); (void)printf("time %10s\n",time); (void)printf("process_flag %8s\n",process_flag);*/ } else if ((int) numbytes==37) { fseek(in_file_ptr, 69, SEEK_SET); (void)printf("WARNING: SECOND RECORD ONLY HAS 37 BYTES\n"); (void)printf("SHOULD HAVE 38 BYTES\n"); (void)printf("Assuming data is still valid. . . \n"); /*(void)printf("date %10s\n",date); (void)printf("time %10s\n",time); (void)printf("process_flag %8s\n",process_flag); (void)printf("numbytes %d\n",numbytes);*/ } else if ((int) numbytes == (MAXX*2)) { (void)printf("Reading pre-1997 format.\n"); fseek(in_file_ptr,24, SEEK_SET); } else { /*(void)printf("numbytes %d\n",numbytes);*/ (void)printf("Error! Header file is in a nonstandard format. Data NOT READ!\n"); exit(1); } /* allocate memory for arrays */ onerow = (short int*) malloc(sizeof(short int*)*MAXX); matrix = (float**) malloc(sizeof(float*)*MAXY); for (j=0;j