/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * nmc_sfc.c * * sample read program for nmc surface observation data * * only categories 51 (land surface data) and 8 (additional data) * are expected in the KuDA land rawinsonde data set. * * Copyright 1992, University Corporation for * Atmospheric Research, All Rights Reserved * * ADM (NCAR/ATD/RAF) 92 OCT 13 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* ---- compiler #includes ---- */ #include #include #include #define MXLV8 16 #define IDD 50 #define MX /*128*/ 32 #define TRUE 1 #define FALSE 0 #define OK 1 #define NOTOK 0 struct rec_read { int idsrch; int iyr; int imo; int idy; int ihr; int idstyp; int irtyp; int lth; int iintyp; float xlat; float xlon; float xhr; float xelev; char ic25; char ic26; char ic27; } rd; struct sadp { float slp; float stp; float ddd; float fff; float at; float dpd; float atmx; float atmn; char qslp; char qstp; char qddff; char qat; char qdwx; int ivv; int ipw; int iw1; int in; int inh; int ic1; int izcb; int ic2; int ic3; int icpt; int ipt; } sd; /* forward function declarations */ int is_quit(); /* globals */ char nbf[10000], nadd[MXLV8][11], asta[6]; int nu=99999, na=0, lthr=0; /* ****** local global data ****** */ static int infh, /* input file handle */ outfh; /* output file handle */ /* *------------------------------------------------------------------- * * main program * * program adp77 * * asks user for filename and date, searches file for record * of that date, displays data, and asks for next record *------------------------------------------------------------------- */ main() { char flnm[128], ymd[20]; int nro, nr, istat, nlvw, cc, /* condition code */ icc, i, /* general purpose index */ year, month, day, notfnd; int ncnt; int nlv; /* --- set condition code to all's well */ icc=0; do { /* infinite loop */ /* --- set no matching records found flag */ notfnd = TRUE; /* - - - - - - - - - - - - - - - - - - -*/ do { /* while the input file is not open or does not exist */ /* * ask user for desired file */ printf("\n"); printf(" Enter file name to read or 'quit' -> "); gets(flnm); if ((i=is_quit(flnm))==TRUE) { printf("exiting program\n"); exit(); } /* * -- open input file */ if ((infh = open (flnm,O_RDONLY,0)) == -1) { printf(" cannot find file %s\n", flnm); printf(" please select another file.\n"); } /* end if fd */ } while (infh == -1); /* - - - - - - - - - - - - - - - - - - -*/ nro=0; /* --- now enter yymmdd */ icc=0; do { cc=OK; printf("\n"); printf(" Enter YYMMDD or 'quit' -> "); gets(ymd); if ((i=is_quit(ymd))==TRUE) { printf("exiting program\n"); exit(); } sscanf(ymd, "%2d%2d%2d", &year, &month, &day); if (year < 90) { printf(" error: year must be greater than 90\n"); cc=NOTOK; } if (month < 1 || month > 12) { printf(" error: month not between 1 and 12\n"); cc=NOTOK; } if (day < 1 || day > 31) { printf(" error: day not between 1 and 31\n"); cc=NOTOK; } } while(cc==NOTOK); printf("\n SEARCHING INPUT FILE\n\n"); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* read a record (end of record marked by carraige return) */ nr=0; /* 70 continue */ do { do { istat = rdadp(infh); icc = istat; if (icc == 0) { nr=nr+1; nro=nro+1; if (rd.iyr > year) icc = 2; else if (rd.imo > month && rd.iyr == year) icc = 2; else if (rd.idy > day && rd.imo == month && rd.iyr == year) icc = 2; } /* end if(icc==0) */ } while (icc==0 && (rd.iyr != year || rd.imo != month || rd.idy != day)); /* ---------------------------------------------------------- */ if (icc == 0) { if (notfnd) { printf("\n STATN YR MO DY HR LAT LON ELEV"); printf(" WIND DIR WIND SPD TEMP DEWPT DPR\n"); printf(" ----- -- -- -- -- --- --- ----"); printf(" -------- -------- ---- ---------\n"); } notfnd=FALSE; /* */ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - C --- READ CATEGORY 51 DATA CALL SADP51(NCNT,SLP,STP,DDD,FFF,AT,DPD,ATMX,ATMN, 2 QSLP,QSTP,QDDFF,QAT,QDWX,IVV,IPW,IW1,IN,INH,IC1,IZCB, 3 IC2,IC3,ICPT,IPT) */ ncnt = sadp51(); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - C --- READ CATEGORY 8 DATA CALL SADP08(NADD,NLV8,MXLV8) */ ncnt = sadp08(MXLV8); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - DISPLAY DATA */ printf("%6s %3d%3d%3d%3d%7.2f%7.2f%7.1f%10.1f%10.1f%7.1f%7.1f\n", asta, rd.iyr, rd.imo, rd.idy, rd.ihr, rd.xlat, rd.xlon, rd.xelev, sd.ddd, sd.fff, sd.at, sd.dpd); /* WRITE(LOUT,1003)ASTA,IYR,IMO,IDY,IHR,XLAT,XLON,XELEV, 2 DDD,FFF,AT,DPD 1003 FORMAT(1X,A6,4I3,2F7.2,F7.0,2F10.1,2F7.1) */ } /* end if (icc == 0) */ } while (icc==0); /* ---------------------------------------------------------- */ /* close the input file - a different one may be opened next */ close(infh); switch(icc) { case 0: break; case 2: if (notfnd) { printf("no records found for date entered\n"); } break; case 4: /* user entered quit so stop program */ printf("exiting program\n"); exit(); break; case 5: /* end of file */ printf(" end of file reached - # of records=%d\n",nro); break; default: /* unknown system error on open or read - stop program */ printf("unrecoverable error\n"); exit(); break; } /* end switch(icc) */ } while(TRUE); /* end infinite loop */ } /* end main() */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* c-------------------------------------------------------------------- c c subroutine rdadp c c reads 60 character header info: c 10 character yymmddhh block c 40 character report identification block (lat,lon) c-------------------------------------------------------------------- */ int rdadp(fh) int fh; { int ist, i, istat, nbytes, lat, lon, hr, elev; nu=nu+lthr; do { ist=1; i=0; /* read a record */ do { nbytes = read(fh,&nbf[i],1); if (nbytes == 0) { istat=5; return(istat); } else if (nbytes < 0) { printf(" err in rdadp- nu=%d, nbf=%40s\n", nu, &nbf[nu]); istat=5; return(istat); } } while(nbf[i++] != '\n'); ist=0; nu=1; /* --- the first 10 characters of each record contain the year, */ /* --- month, day, and hour (2x,4i2) of each observation */ /* --- get date from leader */ i=sscanf(nbf, " %2d%2d%2d%2d", &rd.iyr,&rd.imo,&rd.idy,&rd.ihr); if (i==EOF) { istat=5; return(istat); } /* --- get id for current report */ nu=11; /* --- the next 40 characters of each record contain the latitude, */ /* --- longitude, etc. */ i=sscanf(&nbf[nu-1], "%5d%5d%6s%4d%*4s%c%c%c%3d%5d%2d%3d", &lat, &lon, asta, &hr, &rd.ic25, &rd.ic26, &rd.ic27, &rd.irtyp, &elev, &rd.iintyp, &rd.lth ); rd.xlat=lat*0.01; rd.xlon=lon*0.01; rd.xhr=hr*0.01; rd.xelev=elev*1.0; if (i==EOF) { istat=5; return(istat); } /**/ lthr= (rd.lth) * 10; istat=0; if(lthr > 40) return(istat); /* --- error encountered */ printf(" err in rdadp- nu=%d, nbf=%40s\n", nu, &nbf[nu]); } while(TRUE); /* go to 5 */ /* -----end of file reached */ istat=5; return(istat); } /* end rdadp() */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* c-------------------------------------------------------------------- c function sadp51() c-------------------------------------------------------------------- */ int sadp51() { int i,j; int ncnt, ntu, nlv, categ, ntn, nent, categc, istat; int i_slp,i_stp,i_ddd,i_fff,i_at,i_dpd,i_atmx,i_atmn; ntu=nu+40; ncnt=0; nlv=0; /* look for category 51 */ do { if(i=(strncmp(&nbf[ntu-1], "END REPORT",9)) == 0) { sd.slp=sd.stp=9999.9; sd.ddd=sd.fff=sd.atmx=sd.atmn=999.0; sd.at=999.9; sd.dpd=99.9; sd.qslp=sd.qstp=sd.qddff=sd.qat=sd.qdwx='9'; sd.ivv=sd.ipw=sd.ipt=999; sd.iw1=sd.in=sd.inh=sd.ic1=sd.izcb=sd.ic2=sd.ic3=99; sd.icpt=9; return(ncnt); } /* * ncc=category code * ntn=number of ten character words, * nent=number of entries * nccc=total # of chars in current category */ j=sscanf(&nbf[ntu-1], "%2d%3d%2d%3d", &categ, &ntn, &nent, &categc); if (j==EOF) { printf(" decode error in cat51 %60s\n",nbf[ntu-1]); ncnt=-1; istat=5; return(ncnt); } if(ntn <= 0) { /*go to 95*/ printf(" decode error in cat51 %60s\n",nbf[ntu-1]); ncnt=-1; return(ncnt); } if(categ != 51) ntu=nu+10*(ntn-1); } while(categ != 51); ntu=ntu+10; j=sscanf(&nbf[ntu-1], "%5d%5d%3d%3d%4d%3d%4d%4d%c%c%c%c%c", &i_slp,&i_stp,&i_ddd,&i_fff,&i_at,&i_dpd,&i_atmx,&i_atmn, &sd.qslp,&sd.qstp,&sd.qddff,&sd.qat,&sd.qdwx); if (j==EOF) { printf(" decode error in cat51 %60s\n",nbf[ntu-1]); ncnt=-1; return(ncnt); } sd.slp = i_slp * 0.1; sd.stp = i_stp * 0.1; sd.ddd = i_ddd * 1.0; sd.fff = i_fff * 1.0; sd.at = i_at * 0.1; sd.dpd = i_dpd * 0.1; sd.atmx = i_atmx * 0.1; sd.atmn = i_atmn * 0.1; j=sscanf(&nbf[ntu-1+36], "%3d%3d%2d%2d%2d%2d%2d%2d%2d%1d%3d", &sd.ivv, &sd.ipw, &sd.iw1, &sd.in, &sd.inh, &sd.ic1, &sd.izcb, &sd.ic2, &sd.ic3, &sd.icpt, &sd.ipt); if (j==EOF) { printf(" decode error in cat51 %60s\n",nbf[ntu-1]); ncnt=-1; return(ncnt); } ncnt=ncnt+1; return(ncnt); } /* end sadp51() */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* c-------------------------------------------------------------------- c function sadp08() c-------------------------------------------------------------------- */ int sadp08(maxlev) int maxlev; { int i,j; int ncnt, ntu, nlv, categ, ntn, nent, categc; int pp,tt,hh,dd,ff; float x; ntu=nu+40; ncnt=0; nlv=0; /* look for category 8 */ do { if(strncmp(&nbf[ntu-1], "END REPORT", 10) == 0) { ncnt=nlv; return(ncnt); } j=sscanf(&nbf[ntu-1], "%2d%3d%2d%3d", &categ, &ntn, &nent, &categc); if (j==EOF) { printf(" decode error in cat08 %10s\n",&nbf[ntu]); ncnt=-1; return(ncnt); } if(ntn <= 0) { /*go to 95*/ printf(" decode error in cat08 %10s\n",&nbf[ntu]); ncnt=-1; return(ncnt); } if(categ != 8) ntu=nu+10*(ntn-1); } while (categ != 8); nlv=nent; if (nlv > maxlev) { printf(" too many levels in sadp08 %10d",nlv); nlv=maxlev; } ntu=ntu+10; for(i=0; i