// NOTE, if you don't have the netinet/in.h, just comment it out. // then manually set whether or not to swap the bytes (see commented // section down in the main, it isn't hard to fix) - dlr // // lvis_release_reader.c // // HOWTO compile: gcc -Wall lvis_release_reader.c -o lvis_release_reader // // HOWTO execute: // ./lvis_release_reader LVIS_HB_2003_grid_0.lce // ./lvis_release_reader LVIS_HOW_2003_grid_0.lce -lon 290.00-291.40 -lat 44.74-44.76 // ./lvis_release_reader LVIS_HOW_2003_Flux_Tower_West_grid_0.lgw -c // // Version 1.0 // Begun: 2004/08/19 // David Lloyd Rabine // NASA GSFC Code 924.0 Laser Remote Sensing Branch // david@ltpmail.gsfc.nasa.gov // 301-614-6771 // http://lvis.gsfc.nasa.gov // // EXAMPLE program to convert the LVIS data file formats (LCE, LGW and LGE) // to ASCII // // Version 1.01 - 20051028 // added LFID and SHOTNUMBER to the structure // // Version 1.02 - 20060418 // added TIME to the structure (for ocean data, we're going to need time for tide calculations) // // // Systems Tested on: Linux Slackware 9.1 && 10.2 xi686 // Solaris Ultra 2 // Mac OS X // #include <stdio.h> #include <stdlib.h> #include <string.h> #include "lvis_release_structures.h" typedef unsigned char byte; typedef unsigned short word; typedef unsigned long dword; #ifndef LVIS_RELEASE_READER_VERSION # define LVIS_RELEASE_READER_VERSION 1.02 #endif #ifndef LVIS_RELEASE_READER_VERSION_DATE # define LVIS_RELEASE_READER_VERSION_DATE 20060418 #endif #ifndef GENLIB_LITTLE_ENDIAN # define GENLIB_LITTLE_ENDIAN 0x00 #endif #ifndef GENLIB_BIG_ENDIAN # define GENLIB_BIG_ENDIAN 0x01 #endif // if you want a little more info to start...uncomment this // #define DEBUG_ON double host_double(double input_double,int host_endian) { double return_value; unsigned char * inptr, * outptr; inptr = (unsigned char *) &input_double; outptr = (unsigned char *) &return_value; if(host_endian == GENLIB_BIG_ENDIAN) { outptr[0] = inptr[7]; outptr[1] = inptr[6]; outptr[2] = inptr[5]; outptr[3] = inptr[4]; outptr[4] = inptr[3]; outptr[5] = inptr[2]; outptr[6] = inptr[1]; outptr[7] = inptr[0]; return return_value; } if(host_endian == GENLIB_LITTLE_ENDIAN) { return input_double; } return input_double; // by default just send it back } float host_float(float input_float,int host_endian) { float return_value; unsigned char * inptr, * outptr; inptr = (unsigned char *) &input_float; outptr = (unsigned char *) &return_value; if(host_endian == GENLIB_BIG_ENDIAN) { outptr[0] = inptr[3]; outptr[1] = inptr[2]; outptr[2] = inptr[1]; outptr[3] = inptr[0]; return return_value; } if(host_endian == GENLIB_LITTLE_ENDIAN) { return input_float; } return input_float; // by default just send it back } dword host_dword(dword input_dword,int host_endian) { dword return_value; unsigned char * inptr, * outptr; inptr = (unsigned char *) &input_dword; outptr = (unsigned char *) &return_value; if(host_endian == GENLIB_BIG_ENDIAN) { outptr[0] = inptr[3]; outptr[1] = inptr[2]; outptr[2] = inptr[1]; outptr[3] = inptr[0]; return return_value; } if(host_endian == GENLIB_LITTLE_ENDIAN) { return input_dword; } return input_dword; // by default just send it back } word host_word(word input_word,int host_endian) { word return_value; unsigned char * inptr, * outptr; inptr = (unsigned char *) &input_word; outptr = (unsigned char *) &return_value; if(host_endian == GENLIB_BIG_ENDIAN) { outptr[0] = inptr[1]; outptr[1] = inptr[0]; return return_value; } if(host_endian == GENLIB_LITTLE_ENDIAN) { return input_word; } return input_word; // by default just send it back } int host_endian(void) { int host_endian; union { char c; int i; } tester; tester.i = 0; tester.c = 1; if(tester.i == 1) host_endian = GENLIB_LITTLE_ENDIAN; else host_endian = GENLIB_BIG_ENDIAN; return host_endian; } void display_usage(char * proggy) { printf("USAGE: %s <input> [options]\n",proggy); printf("\n"); printf("-c Delimit data with commas (default = TAB)\n"); printf("-i Generate an index column\n"); printf("-lat dd.dddd-dd.dddd Cut by latitude (min -> max decimal degrees)\n"); printf("-lon dd.dddd-dd.dddd Cut by longitude (min -> max decimal degrees)\n"); printf("-lce Force file type to LCE (normally chooses by file extension)\n"); printf("-lge Force file type to LGE\n"); printf("-lgw Force file type to LGW\n"); printf("-v Print program version and exit\n"); printf("\n"); printf("\n"); } int main(int argc, char *argv[]) { double minlon,maxlon,minlat,maxlat; char delim[16],temp[1024],tempa[1204],tempb[1024]; int i,j,myendian,filetype,indexcol; unsigned long colnum; // make a single shot record of each type lvis_lce lce; lvis_lge lge; lvis_lgw lgw; FILE *fp; // set up variable defaults minlat = -400.0; maxlat = 400.0; minlon = -400.0; maxlon = 400.0; memset(delim,0,sizeof(delim)); strncpy(delim,"\t",1); indexcol=0; // figure out what endian this host machine is myendian = host_endian(); // less than 2 arguments? we need at least an input file name if(argc<2) { display_usage(argv[0]); exit(-1); } // check for a version flag strcpy(temp,argv[1]); if(strncmp(temp,"-v",2)==0) { minlon = LVIS_RELEASE_READER_VERSION; maxlon = LVIS_RELEASE_READER_VERSION_DATE; printf("LVIS Release Reader Version %5.2f (%lu)\n",minlon,(dword) maxlon); minlon = LVIS_RELEASE_STRUCTURE_VERSION; maxlon = LVIS_RELEASE_STRUCTURE_DATE; printf("LVIS Release Data Structure %5.2f (%lu)\n",minlon,(dword) maxlon); exit(1); } // open up the file for read access if((fp = fopen(argv[1],"rb"))==NULL) { fprintf(stderr,"Error opening the input file: %s\n",argv[1]); exit(-1); } // detect the file type by the extension strcpy(temp,argv[1]); i = strlen(temp); filetype = 0; // give it a default value of no data if(strncmp(&temp[i-3],"lce",3)==0) filetype = LVIS_RELEASE_FILETYPE_LCE; if(strncmp(&temp[i-3],"lge",3)==0) filetype = LVIS_RELEASE_FILETYPE_LGE; if(strncmp(&temp[i-3],"lgw",3)==0) filetype = LVIS_RELEASE_FILETYPE_LGW; // check for command line arguments i=2; // set a pointer at arguement 2 of the command line while(i<argc) { strcpy(temp,argv[i]); if(strncmp(temp,"-v",2)==0) { minlon = LVIS_RELEASE_READER_VERSION; printf("Lvis Release Reader Version %5.2f\n",minlon); exit(1); } if(strncmp(temp,"-c",2)==0) { strncpy(delim,",",1);} if(strncmp(temp,"-i",2)==0) { indexcol=1; } if(strncmp(temp,"-lce",4)==0) { filetype = LVIS_RELEASE_FILETYPE_LCE; } if(strncmp(temp,"-lge",4)==0) { filetype = LVIS_RELEASE_FILETYPE_LGE; } if(strncmp(temp,"-lgw",4)==0) { filetype = LVIS_RELEASE_FILETYPE_LGW; } if(strncmp(temp,"-lat",4)==0) { i++; if(i<argc) { strcpy(tempa,argv[i]); // find the '-' character in the string j=0; // j will be our pointer while(j++<strlen(tempa) && tempa[j]!='-'); if(j>=strlen(tempa)) printf("Invalid argument to -lat parameter!\n"); else { // split the string around j into min/max memset(tempb,0,sizeof(tempb)); strncpy(tempb,&tempa[0],j); minlat = atof(tempb); memset(tempb,0,sizeof(tempb)); strncpy(tempb,&tempa[j+1],strlen(tempa)-j); maxlat = atof(tempb); } } } if(strncmp(temp,"-lon",4)==0) { i++; if(i<argc) { strcpy(tempa,argv[i]); // find the '-' character in the string j=0; while(j++<strlen(tempa) && tempa[j]!='-'); if(j>=strlen(tempa)) printf("Invalid argument to -lon parameter!\n"); else { memset(tempb,0,sizeof(tempb)); strncpy(tempb,&tempa[0],j); minlon = atof(tempb); memset(tempb,0,sizeof(tempb)); strncpy(tempb,&tempa[j+1],strlen(tempa)-j); maxlon = atof(tempb); } } } i++; } #ifdef DEBUG_ON // uncomment the #define up top if you want to see these messages printf("input file name = %s (strlen=%d)\n",temp,strlen(temp)); printf("input file type = %d\n",filetype); printf("lce structure size = %d bytes\n",sizeof(lce)); printf("lge structure size = %d bytes\n",sizeof(lge)); if(myendian == GENLIB_LITTLE_ENDIAN) printf("system is LITTLE ENDIAN.\n"); if(myendian == GENLIB_BIG_ENDIAN) printf("system is BIG ENDIAN.\n"); #endif colnum = 1; // set the index column counter to one (1) // do this while loop if this data is LGE if(filetype==LVIS_RELEASE_FILETYPE_LGE) while(fread(&lge,sizeof(lge),1,fp)==1) // read in the data one block at a time { if(myendian==GENLIB_LITTLE_ENDIAN) // only need to swap if little { // swap each item of this block lge.lfid = host_dword(lge.lfid,GENLIB_BIG_ENDIAN); lge.shotnumber = host_dword(lge.shotnumber,GENLIB_BIG_ENDIAN); lge.lvistime = host_double(lge.lvistime,GENLIB_BIG_ENDIAN); lge.glon = host_double(lge.glon,GENLIB_BIG_ENDIAN); lge.glat = host_double(lge.glat,GENLIB_BIG_ENDIAN); lge.zg = host_float(lge.zg,GENLIB_BIG_ENDIAN); lge.rh25 = host_float(lge.rh25,GENLIB_BIG_ENDIAN); lge.rh50 = host_float(lge.rh50,GENLIB_BIG_ENDIAN); lge.rh75 = host_float(lge.rh75,GENLIB_BIG_ENDIAN); lge.rh100 = host_float(lge.rh100,GENLIB_BIG_ENDIAN); } // print the data in tab delimited columns for this data block if(lge.glon>minlon && lge.glon<maxlon && lge.glat>minlat && lge.glat<maxlat) { if(indexcol==1) printf("%10li%s",colnum++,delim); printf("%lu%s%lu%s%12.6f%s",lge.lfid,delim,lge.shotnumber,delim,lge.lvistime,delim); printf("%14.10f%s%14.10f%s%9.4f%s",lge.glon,delim,lge.glat,delim,lge.zg,delim); printf("%9.4f%s%9.4f%s%9.4f%s%9.4f\n",lge.rh25,delim,lge.rh50,delim,lge.rh75,delim,lge.rh100); // the format for the %f print is: // # total number of digits (including decimal) . # digits after the decimal } } // do this while loop if this data is LCE if(filetype==LVIS_RELEASE_FILETYPE_LCE) while(fread(&lce,sizeof(lce),1,fp)==1) { if(myendian==GENLIB_LITTLE_ENDIAN) // only need to swap if little { lce.lfid = host_dword(lce.lfid,GENLIB_BIG_ENDIAN); lce.shotnumber = host_dword(lce.shotnumber,GENLIB_BIG_ENDIAN); lce.lvistime = host_double(lce.lvistime,GENLIB_BIG_ENDIAN); lce.tlon = host_double(lce.tlon,GENLIB_BIG_ENDIAN); lce.tlat = host_double(lce.tlat,GENLIB_BIG_ENDIAN); lce.zt = host_float(lce.zt,GENLIB_BIG_ENDIAN); } if(lce.tlon>minlon && lce.tlon<maxlon && lce.tlat>minlat && lce.tlat<maxlat) { if(indexcol==1) printf("%10li%s",colnum++,delim); printf("%lu%s%lu%s%12.6f%s",lce.lfid,delim,lce.shotnumber,delim,lce.lvistime,delim); printf("%14.10f%s%14.10f%s%9.4f\n",lce.tlon,delim,lce.tlat,delim,lce.zt); } } // do this while loop if this data is LGW if(filetype==LVIS_RELEASE_FILETYPE_LGW) while(fread(&lgw,sizeof(lgw),1,fp)==1) { if(myendian==GENLIB_LITTLE_ENDIAN) // only need to swap if little { lgw.lfid = host_dword(lgw.lfid,GENLIB_BIG_ENDIAN); lgw.shotnumber = host_dword(lgw.shotnumber,GENLIB_BIG_ENDIAN); lgw.lvistime = host_double(lgw.lvistime,GENLIB_BIG_ENDIAN); lgw.lon0 = host_double(lgw.lon0,GENLIB_BIG_ENDIAN); lgw.lat0 = host_double(lgw.lat0,GENLIB_BIG_ENDIAN); lgw.z0 = host_float(lgw.z0,GENLIB_BIG_ENDIAN); lgw.lon431 = host_double(lgw.lon431,GENLIB_BIG_ENDIAN); lgw.lat431 = host_double(lgw.lat431,GENLIB_BIG_ENDIAN); lgw.z431 = host_float(lgw.z431,GENLIB_BIG_ENDIAN); lgw.sigmean = host_float(lgw.sigmean,GENLIB_BIG_ENDIAN); } if(lgw.lon431>minlon && lgw.lon431<maxlon && lgw.lat431>minlat && lgw.lat431<maxlat) { if(indexcol==1) printf("%10li%s",colnum++,delim); printf("%lu%s%lu%s%12.6f%s",lgw.lfid,delim,lgw.shotnumber,delim,lgw.lvistime,delim); printf("%14.10f%s%14.10f%s%9.4f%s",lgw.lon0,delim,lgw.lat0,delim,lgw.z0,delim); printf("%14.10f%s%14.10f%s%9.4f%s",lgw.lon431,delim,lgw.lat431,delim,lgw.z431,delim); printf("%9.4f%s",lgw.sigmean,delim); for(j=0;j<sizeof(lgw.wave)-1;j++) printf("%03d%s",lgw.wave[j],delim); printf("%03d\n",lgw.wave[j]); } } fclose(fp); return(1); }