int nwpice_read(char *fpath, char **filenames, int nrf, int nruns, fmtime reqtime, fmucsref refucs, nwpice *nwp) { char *where="nwpice_read"; int i, imgsize; /* HIRLAM/NWP variables */ int nfiles=FFNS, iunit=10, interp=1, itime[5]; int nparam1=NOFIELDS1, nparam2=NOFIELDS2; int ierror, iundef, len1, len2; float satgrid[10], *nwpfield1, *nwpfield2; char **fnpl, **fnml, **fnsf; /* enum nwp_par {T0M,T2M,T950,T800,T750,T500,MSLP,PW,TOPO}; */ int iparam1[NOFIELDS1][4]={ /* Spec of what to get */ { 30, 2, 1000, 0}, /* Temp. at 0m */ }; /* int iparam2[NOFIELDS2][4]={ { 0, 0, 0, 7} }; */ int icontrol[6]={ /* Accep. spec */ 88, /* Producer 88 -> MI */ -32767, /* Model grid -32767-> first found */ 3, /* Min allowed forecast length in hours */ +24, /* Max allowed forecast length in hours */ -3, /* Min allowed offset in hours from image time */ +3 /* Max allowed offset in hours from image time */ }; fmtime nwptime; /* * Create the grid specification used by feltfiles and libmi. * Requested grid description, only one supported yet. */ satgrid[0] = 60.; satgrid[1] = 0.; satgrid[2] = 1000.; satgrid[3] = 1000.; satgrid[4] = 0.; satgrid[5] = 0.; satgrid[6] = refucs.Ax; satgrid[7] = refucs.Ay; satgrid[8] = refucs.Bx; satgrid[9] = refucs.By; /* Requested valid time */ itime[0] = reqtime.fm_year; itime[1] = reqtime.fm_mon; itime[2] = reqtime.fm_mday; itime[3] = reqtime.fm_hour; itime[4] = reqtime.fm_min; /* * Create the filenames to use. Currently only one level is required * for this software, implying that only one set of files containing * the surface parameters need to be read by this software. Memory * must be allocated contigous. */ if (strstr(fpath,"/opdata")) { len1 = strlen(fpath)+1+strlen(filenames[0])+6+1; } else if (strstr(fpath,"/starc")) { len1 = strlen(fpath)+1+11+strlen(filenames[0])+6+1+9; } else { fmerrmsg(where,"Could not determine source for NWP data."); return(FM_IO_ERR); } if (fmalloc_byte_2d_contiguous(&fnsf,nruns,len1)){ fmerrmsg(where,"Could not allocate fnsf"); exit(FM_MEMALL_ERR); } for (i=0;i<nruns;i++) { if (strstr(fpath,"/opdata")) { sprintf(fnsf[i],"%s/%s%02d.dat",fpath,filenames[0],(i*6)); } else if (strstr(fpath,"/starc")) { sprintf(fnsf[i],"%s/%4d/%02d/%02d/%s%02d.dat_%4d%02d%02d", fpath, reqtime.fm_year, reqtime.fm_mon,reqtime.fm_mday, filenames[0],(i*6), reqtime.fm_year, reqtime.fm_mon,reqtime.fm_mday); } } fmlogmsg(where,"Collecting HIRLAM data from %s",fpath); /* * The fields are returned in the vector "field[MAXIMGSIZE]" which is * organized like this: "field[nx*ny*nparam]", where nx and ny are * the numbers of gridpoints in x and y direction and nparam is the * number of fields/parameters collected. */ imgsize = refucs.iw*refucs.ih; if (imgsize > FMIO_MAXIMGSIZE) { fmerrmsg(where,"Data container for NWP is too small, the required size if %d while only %d is available.", imgsize, FMIO_MAXIMGSIZE); return(FM_IO_ERR); } nwpfield1 = (float *) malloc(NOFIELDS1*imgsize*sizeof(float)); if (!nwpfield1) { fmerrmsg(where,"Could not allocate nwpfield1."); return(FM_MEMALL_ERR); } /* * Collect data from the files containing surface data. */ /* getfield_(&nfiles, feltfilepresl[0], &iunit, &interp, satgrid, &refucs.iw, &refucs.ih, itime, &nparam1, iparam1, icontrol, nwpfield1, &iundef, &ierror, len1); */ getfield_(&nfiles, fnsf[0], &iunit, &interp, satgrid, &refucs.iw, &refucs.ih, itime, &nparam1, iparam1, icontrol, nwpfield1, &iundef, &ierror, len1); if (ierror) { fmerrmsg(where,"error reading surface and parameter fields"); return(FM_IO_ERR); } /* * Collect data from the files containing model level fields */ /* for (i=0;i<FFNS;i++) { printf(" feltfilemodl %s\n",feltfilemodl[i]); } */ /* Not needed... printf(" Then model fields are searched...\n"); getfield_(&nfiles, feltfilemodl[0], &iunit, &interp, satgrid, &refucs.iw, &refucs.ih, itime, &nparam2, iparam2, icontrol, nwpfield2, &iundef, &ierror, len2); if (ierror) { errmsg(where,"error reading model level fields"); return(2); } */ /* * Print status information about the model field which was found. * if "iundef" is different from 0, undefined values were found * in the HIRLAM fields. The code for undefined is +1.e+35. */ printf(" Date: %02d/%02d/%d", itime[2], itime[1], itime[0]); printf(" and time: %02d:00 UTC\n", itime[3]); printf(" Forecast length: %d\n", itime[4]); printf(" Status of 'getfield':"); printf(" ierror=%d iundef=%d\n\n", ierror, iundef); /* * Transfer the time information to the nwpice structure */ nwp->leadtime = itime[4]; nwptime.fm_year = itime[0]; nwptime.fm_mon = itime[1]; nwptime.fm_mday = itime[2]; nwptime.fm_hour = itime[3]; nwptime.fm_min = 0; nwptime.fm_sec = 0; nwp->validtime = tofmsec1970(nwptime); /* * Transfer the UCS information */ nwp->refucs = refucs; /* * Allocate the data structure that will contain the NWP data */ /* if (!nwp->t950hpa) { nwp->t950hpa = (float *) malloc(imgsize*sizeof(float)); if (!nwp->t950hpa) return(FM_MEMALL_ERR); } if (!nwp->t800hpa) { nwp->t800hpa = (float *) malloc(imgsize*sizeof(float)); if (!nwp->t800hpa) return(FM_MEMALL_ERR); } if (!nwp->t700hpa) { nwp->t700hpa = (float *) malloc(imgsize*sizeof(float)); if (!nwp->t700hpa) return(FM_MEMALL_ERR); } if (!nwp->t500hpa) { nwp->t500hpa = (float *) malloc(imgsize*sizeof(float)); if (!nwp->t500hpa) return(FM_MEMALL_ERR); } if (!nwp->t2m) { nwp->t2m = (float *) malloc(imgsize*sizeof(float)); if (!nwp->t2m) return(FM_MEMALL_ERR); } */ if (!nwp->t0m) { nwp->t0m = (float *) malloc(imgsize*sizeof(float)); if (!nwp->t0m) return(FM_MEMALL_ERR); } /* if (!nwp->ps) { nwp->ps = (float *) malloc(imgsize*sizeof(float)); if (!nwp->ps) return(FM_MEMALL_ERR); } if (!nwp->pw) { nwp->pw = (float *) malloc(imgsize*sizeof(float)); if (!nwp->pw) return(FM_MEMALL_ERR); } if (!nwp->rh) { nwp->rh = (float *) malloc(imgsize*sizeof(float)); if (!nwp->rh) return(FM_MEMALL_ERR); } if (!nwp->topo) { nwp->topo = (float *) malloc(imgsize*sizeof(float)); if (!nwp->topo) return(FM_MEMALL_ERR); } */ /* * Transfer the NWP data from the local temporary array to the nwpice * structure */ for (i=0;i<imgsize;i++) { /* * Surface, parameter and pressure fields */ nwp->t0m[i] = nwpfield1[0*imgsize+i]; /* nwp->t2m[i] = nwpfield1[1*imgsize+i]; nwp->t950hpa[i] = nwpfield1[2*imgsize+i]; nwp->t800hpa[i] = nwpfield1[3*imgsize+i]; nwp->t700hpa[i] = nwpfield1[4*imgsize+i]; nwp->t500hpa[i] = nwpfield1[5*imgsize+i]; nwp->ps[i] = nwpfield1[6*imgsize+i]; nwp->topo[i] = nwpfield1[7*imgsize+i]; nwp->rh[i] = nwpfield1[8*imgsize+i]; */ /* * Model level fields */ /* nwp->pw[i] = nwpfield2[0*imgsize+i]; */ } /* * Free allocated memory */ free(nwpfield1); /* free(nwpfield2); */ return(FM_OK); }
/* * Create HDF5 file with AVHRR data. */ int create_HDF_avhrr_file(PRODhead avhrrhead, char *outfile, float *ch1, float *ch2, float *ch3b, float *ch4, float *ch5, float *ch3a, float *soz, float *saz) { char *where="create_HDF_avhrr_file"; short status; int i, imgsize; osihdf avhrrh5p; osi_dtype avhrr_ft[AVHRRH5P_LEVS]; char *avhrr_desc[AVHRRH5P_LEVS]; fmlogmsg(where,"Creating HDF file with AVHRR fields."); /* Initiate HDF5 object for AVHRR product */ init_osihdf(&avhrrh5p); sprintf(avhrrh5p.h.source, "%s", avhrrhead.source); sprintf(avhrrh5p.h.product, "%s", avhrrhead.product); sprintf(avhrrh5p.h.area, "%s", avhrrhead.area); avhrrh5p.h.iw = avhrrhead.iw; avhrrh5p.h.ih = avhrrhead.ih; avhrrh5p.h.z = AVHRRH5P_LEVS; avhrrh5p.h.Ax = avhrrhead.Ax; avhrrh5p.h.Ay = avhrrhead.Ay; avhrrh5p.h.Bx = avhrrhead.Bx; avhrrh5p.h.By = avhrrhead.By; avhrrh5p.h.year = avhrrhead.year; avhrrh5p.h.month = avhrrhead.month; avhrrh5p.h.day = avhrrhead.day; avhrrh5p.h.hour = avhrrhead.hour; avhrrh5p.h.minute = avhrrhead.minute; for (i=0;i<AVHRRH5P_LEVS;i++) { avhrr_ft[i] = OSI_FLOAT; } avhrr_desc[0] = (char *) malloc(8*sizeof(char)); sprintf(avhrr_desc[0], "CH1"); avhrr_desc[1] = (char *) malloc(8*sizeof(char)); sprintf(avhrr_desc[1], "CH2"); avhrr_desc[2] = (char *) malloc(8*sizeof(char)); sprintf(avhrr_desc[2], "CH3B"); avhrr_desc[3] = (char *) malloc(8*sizeof(char)); sprintf(avhrr_desc[3], "CH4"); avhrr_desc[4] = (char *) malloc(8*sizeof(char)); sprintf(avhrr_desc[4], "CH5"); avhrr_desc[5] = (char *) malloc(8*sizeof(char)); sprintf(avhrr_desc[5], "CH3A"); avhrr_desc[6] = (char *) malloc(8*sizeof(char)); sprintf(avhrr_desc[6], "SOZ"); avhrr_desc[7] = (char *) malloc(8*sizeof(char)); sprintf(avhrr_desc[7], "SAZ"); status = malloc_osihdf(&avhrrh5p,avhrr_ft,avhrr_desc); if (status != 0) { fprintf(stderr,"\n\tERROR! In allocating memory (malloc_osihdf)\n"); exit(3); } /* Copy AVHRR fields to avhrrh5p object */ imgsize = avhrrhead.iw*avhrrhead.ih; for (i=0;i<imgsize;i++) { ((float *) avhrrh5p.d[0].data)[i] = ch1[i]; ((float *) avhrrh5p.d[1].data)[i] = ch2[i]; ((float *) avhrrh5p.d[2].data)[i] = ch3b[i]; ((float *) avhrrh5p.d[3].data)[i] = ch4[i]; ((float *) avhrrh5p.d[4].data)[i] = ch5[i]; ((float *) avhrrh5p.d[5].data)[i] = ch3a[i]; ((float *) avhrrh5p.d[6].data)[i] = soz[i]; ((float *) avhrrh5p.d[7].data)[i] = saz[i]; } status = store_hdf5_product(outfile,avhrrh5p); if (status != 0) { fprintf(stderr,"\n\tERROR: store_hdf5_product encountered an error.\n"); exit(2); } if (free_osihdf(&avhrrh5p) != 0) { fprintf(stderr,"\n\tERROR! Could not free avhrrh5p properly."); exit(3); } return(FM_OK); }
/* * Convert METSAT values to HDF storage values. */ int calc_avhrr_channels(fmio_img img, float *ch1, float *ch2, float *ch3b, float *ch4, float *ch5, float *ch3a, float *soz, float *saz) { char *where="calc_avhrr_channels"; long i, j; int xc, yc, ret, angarrX, angarrY; float A1, A2, A3, T3, T4, T5; float sozval, sazval; fmscale cal; fmtime date; fmsec1970 utctime, tst; fmucsref ucsref; fmucspos upos; fmgeopos gpos; fmindex xypos; fmio_subtrack subt; fmangreq angreq; fmangles *angarr; fm_img2slopes(img, &cal); fm_img2fmucsref(img, &ucsref); upos.eastings = img.Bx; upos.northings = img.By; fm_img2fmtime(img, &date); angreq.ref = ucsref; angreq.date = date; angreq.myproj = MI; angreq.subtrack.gpos = (fmgeopos *) malloc(img.numtrack*sizeof(fmgeopos)); for (i=0;i<img.numtrack;i++) { angreq.subtrack.gpos[i].lat = img.track[i].latitude; angreq.subtrack.gpos[i].lon = img.track[i].longitude; } angreq.subtrack.npoints = img.numtrack; fmlogmsg(where,"Unpacking AVHRR channels and estimating observation geometry."); /* Calculate angles for each ANGPIXDIST'th column and row */ angarrX = img.iw/ANGPIXDIST; angarrY = img.ih/ANGPIXDIST; angarr = (fmangles *) malloc(angarrX*angarrY*sizeof(fmangles)); for (yc=0;yc<img.ih;yc++) { for (xc=0;xc<img.iw;xc++) { if (xc%ANGPIXDIST == 0 && yc%ANGPIXDIST == 0) { xypos.col = xc; xypos.row = yc; gpos=fmucs2geo(upos,MI); j = fmivec((int)(xc/ANGPIXDIST),(int)(yc/ANGPIXDIST),(int)(img.iw/ANGPIXDIST)); angreq.ll = gpos; angreq.ind = xypos; if (! fmangest(angreq,&angarr[j])) { fmerrmsg(where, "Observation geometry estimation failed for pixel %d, %d", xc, yc); } } } } for (yc=0;yc<img.ih;yc++) { for (xc=0;xc<img.iw;xc++) { i = fmivec(xc,yc,img.iw); if (img.image[4][i] > 0 || img.image[0][i] > 0) { j = fmivec(mini(xc/ANGPIXDIST,angarrX),mini(yc/ANGPIXDIST,angarrY),angarrX); sozval = (angarr[j]).soz; sazval = (angarr[j]).saz; } else { sozval = -999.9; sazval = -999.9; } /*if (img.image[0][i] > 0) { A1 = calib(img.image[0][i], 1, cal); * }*/ if (img.image[0][i] > 0) { A1 = unpack_fmimage_ushort(img.image[0][i], cal, 1); } else { A1 = -999.9; } /*if (img.image[1][i] > 0) { A2 = calib(img.image[1][i], 2, cal); * }*/ if (img.image[1][i] > 0) { A2 = unpack_fmimage_ushort(img.image[1][i], cal, 1); } else { A2 = -999.9; } /*if (img.image[2][i] > 0) { T3 = calib(img.image[2][i], 3, cal); * }*/ if (img.image[2][i] > 0) { T3 = unpack_fmimage_ushort(img.image[2][i], cal, 2); } else { T3 = -999.9; } /*if (img.image[3][i] > 0) { T4 = calib(img.image[3][i], 4, cal); * }*/ if (img.image[3][i] > 0) { T4 = unpack_fmimage_ushort(img.image[3][i], cal, 2); } else { T4 = -999.9; } /*if (img.image[4][i] > 0) { T5 = calib(img.image[4][i], 5, cal); * }*/ if (img.image[4][i] > 0) { T5 = unpack_fmimage_ushort(img.image[4][i], cal, 2); } else { T5 = -999.9; } /*if (img.image[5][i] > 0) { A3 = calib(img.image[5][i], 6, cal); * }*/ if (img.image[5][i] > 0) { A3 = unpack_fmimage_ushort(img.image[5][i], cal, 1); } else { A3 = -999.9; } ch1[i] = A1; ch2[i] = A2; ch3b[i] = T3; ch4[i] = T4; ch5[i] = T5; ch3a[i] = A3; soz[i] = sozval; saz[i] = sazval; } } return(FM_OK); }
int safssi_stdat(fmgeopos gpos, fmprojspec myproj, osihdf *safssi, safssi_data *ssi) { char *where="safssi_stdat"; int dx, dy, i, j, k, l, m; int nodata = 0; fmtime timeid; fmindex xyp, tgin; fmucspos tgxy; fmgeopos tgll; fmucsref rim; /* * Convert from image header to useable data structures, first * satellite id. */ sprintf((*ssi).source,"%s", safssi->h.source); /* * The UCS info is converted */ rim.Ax = safssi->h.Ax; rim.Ay = safssi->h.Ay; rim.Bx = safssi->h.Bx; rim.By = safssi->h.By; rim.iw = safssi->h.iw; rim.ih = safssi->h.ih; /* printf(" lat: %.2f lon: %.2f\n",gpos.lat,gpos.lon); printf(" Bx: %.2f By: %.2f Ax: %.2f Ay: %.2f\n", rim.Bx,rim.By,rim.Ax,rim.Ay); */ (*ssi).nav.Ax = rim.Ax; (*ssi).nav.Ay = rim.Ay; /* * Set UNIX time for product */ timeid.fm_min = safssi->h.minute; timeid.fm_hour = safssi->h.hour; timeid.fm_mday = safssi->h.day; timeid.fm_mon = safssi->h.month; timeid.fm_year = safssi->h.year; (*ssi).vtime = tofmsec1970(timeid);; /* * Get UCS position of the requested geographical position within the * image. */ tgxy = fmgeo2ucs(gpos, myproj); tgin = fmucs2ind(rim,tgxy); if (tgin.col < 0 || tgin.row < 0) { fmerrmsg(where, "This is out of image..."); fprintf(stdout," lat: %.2f lon: %.2f\n",tgll.lat,tgll.lon); fprintf(stdout," northings: %d eastings: %d\n",tgxy.northings,tgxy.eastings); fprintf(stdout," myproj: %d\n", myproj); return(FM_SYNTAX_ERR); } (*ssi).nav.Bx = (float) tgxy.eastings; (*ssi).nav.By = (float) tgxy.northings; /* * Check bounding box size, these parameters are set by the init * function... */ if ((*ssi).nav.iw%2 == 0 || (*ssi).nav.ih%2 == 0) { fmerrmsg("avhrr_stdat","area required must be odd\n"); return(FM_SYNTAX_ERR); } /* * Collect the actual data, l is used for pixel count within the * actual image, and k within the storage tile. */ dx = (int) floorf((float) (*ssi).nav.iw/2.); dy = (int) floorf((float) (*ssi).nav.ih/2.); k = 0; for (i=(tgin.row-dy); i<=(tgin.row+dy); i++) { for (j=(tgin.col-dx); j<=(tgin.col+dx); j++) { /* * Check if within image coverage... */ if (i < 0 || j < 0 || i >= rim.ih || j >= rim.iw) continue; /* * Navigation is performed in 2D while data is stored in 1D... */ l = fmivec(j,i,rim.iw); /* * Collect data... */ (*ssi).data[k] = ((float *) safssi->d[0].data)[l]; (*ssi).qflg[k] = ((unsigned short *) safssi->d[1].data)[l]; /* * Check number of unprocessed pixels */ if ((*ssi).data[k] < -100.) nodata++; k++; } } /* * If all pixels are unprocessed this is likely to be out of coverage, * return code to indicate this... */ if (nodata == k) { fmlogmsg(where,"This request contains all unprocessed pixels."); return(FM_OTHER_ERR); } return(FM_OK); }
int safcm_stdat(fmgeopos gpos, fmprojspec myproj, CTy_t *ctype, safcm_data *cm) { char *where = "safcm_stdat"; char what[FMSTRING256]; int dx, dy, i, j, k, l, m, in, jn; int nodata = 1; int notprocessed = 0; /* struct clb c; */ fmucspos tgxy; fmindex tgin; fmgeopos tgll; fmucsref rim; if (FMCOL_NO_CLOUDTYPE_VALUES != SM_NUMBER_OF_CLOUDTYPE_VALUES) { sprintf(what,"The number of cloud types seem to have changed %d->%d",FMCOL_NO_CLOUDTYPE_VALUES,SM_NUMBER_OF_CLOUDTYPE_VALUES); fmerrmsg(where, what); return(FM_IO_ERR); } /* * Convert from image header to useable data structures, first * satellite id. */ sprintf((*cm).source,"%s", ctype->satellite_id); /* * The UCS info is converted, remember that SAFNWC use meter unit * while DNMI use kilometer... */ rim.Ax = M2KM(fabs(ctype->reg->area_extent[2]-ctype->reg->area_extent[0])/ (double) ctype->reg->xsize); rim.Ay = M2KM(fabs(ctype->reg->area_extent[3]-ctype->reg->area_extent[1])/ (double) ctype->reg->ysize); rim.Bx = M2KM(ctype->reg->area_extent[0]); rim.By = M2KM(ctype->reg->area_extent[3]); rim.iw = ctype->reg->xsize; rim.ih = ctype->reg->ysize; (*cm).nav.Ax = (float) rim.Ax; (*cm).nav.Ay = (float) rim.Ay; /* * Set UNIX time for product */ (*cm).vtime = ctype->sec_1970; /* * Get UCS position of the requested geographical position within the * image. */ tgll.lat = (double) gpos.lat; tgll.lon = (double) gpos.lon; tgxy = fmgeo2ucs(tgll, myproj) ; tgin = fmucs2ind(rim, tgxy); if (tgin.col < 0 || tgin.row < 0) return(FM_SYNTAX_ERR); (*cm).nav.Bx = (float) tgxy.eastings; (*cm).nav.By = (float) tgxy.northings; /* * Check bounding box size, these parameters are set by the init * function... */ if ((*cm).nav.iw%2 == 0 || (*cm).nav.ih%2 == 0) { fmerrmsg("avhrr_stdat","area required must be odd\n"); return(FM_SYNTAX_ERR); } /* * Transfer decoding information for cloudmask/type to storage tile * structure... */ for (i=0; i<FMCOL_NO_CLOUDTYPE_VALUES; i++) { /* printf(" Lengde: %d\n", strlen(ctype->cloudtype_lut[i])); */ if (ctype->cloudtype_lut[i]) { /* strncpy((*cm).description[i], ctype->cloudtype_lut[i],MAX_LENGTH_STRING); */ strncpy((*cm).description[i], ctype->cloudtype_lut[i],50); } else { sprintf((*cm).description[i],"NA"); } } /* * Collect the actual data, l is used for pixel count within the * actual image, and k within the storage tile. */ dx = (int) floorf((float) (*cm).nav.iw/2.); dy = (int) floorf((float) (*cm).nav.ih/2.); k = 0; for (i=(tgin.row-dy); i<=(tgin.row+dy); i++) { for (j=(tgin.col-dx); j<=(tgin.col+dx); j++) { /* * Check if within image coverage... */ if (i < 0 || j < 0 || i >= rim.ih || j >= rim.iw) continue; /* * Navigation is performed in 2D while data is stored in 1D... */ l = fmivec(j,i,rim.iw); /* * Collect data... */ (*cm).data[k] = (unsigned char) ctype->cloudtype[l]; /* * Check number of unprocessed pixels */ if (ctype->cloudtype[l] == 0) notprocessed++; k++; } } /* * If all pixels are unprocessed this is likely to be out of coverage, * return code to indicate this... */ if (notprocessed == k) { fmlogmsg(where,"This request contains all unprocessed pixels."); return(FM_OTHER_ERR); } return(FM_OK); }
fmsec1970 ymdhms2fmsec1970(char *str, int mode) { char *where="ymdhms2fmsec1970"; fmsec1970 secs; fmtime t; int i; char *dummy; /* * Check the input. */ if (strlen(str) < 14) { fmerrmsg(where,"Input datetime string is too short"); return(-1); } dummy = (char *) malloc(5*sizeof(char)); if (!dummy) return(2); /* * Initialize */ for (i=0; i<5; i++) { dummy[i] = '\0'; } /* * Get year */ for (i=0;i<4;i++) { dummy[i] = str[i]; } t.fm_year = atoi(dummy); dummy[2] = dummy[3] = '\0'; /* * Get month */ for (i=0;i<2;i++) { dummy[i] = str[4+i]; } t.fm_mon = atoi(dummy); if (t.fm_mon < 1 || t.fm_mon > 12) { t.fm_mon = -9; } /* * Get day */ for (i=0;i<2;i++) { dummy[i] = str[6+i]; } t.fm_mday = atoi(dummy); if (t.fm_mday < 1 || t.fm_mday > 31) t.fm_mday = -9; /* * Get hour */ for (i=0;i<2;i++) { dummy[i] = str[8+i]; } t.fm_hour = atoi(dummy); if (t.fm_hour < 0 || t.fm_hour > 23) t.fm_hour = -9; /* * Get minute */ for (i=0;i<2;i++) { dummy[i] = str[10+i]; } t.fm_min = atoi(dummy); if (t.fm_min < 0 || t.fm_min > 59) t.fm_min = -9; /* * Get seconds */ for (i=0;i<2;i++) { dummy[i] = str[12+i]; } t.fm_sec = atoi(dummy); if (t.fm_sec < 0 || t.fm_sec > 59) t.fm_sec = -9; /* * Release resiources */ free(dummy); if (mode > 0) { printf(" %4d-%02d-%02d %02d:%02d:%02d\n", t.fm_year,t.fm_mon,t.fm_mday, t.fm_hour,t.fm_min,t.fm_sec); } if (t.fm_sec < 0 || t.fm_min < 0 || t.fm_hour < 0 || t.fm_mday < 0 || t.fm_mon < 0 || t.fm_year < 0) { fmerrmsg(where,"Decoding of datetime string failed"); fmlogmsg(where,"Decoding of datetime string failed"); } secs = tofmsec1970(t); return(secs); }
int fm_MITIFF_fillhead(char *asciifield, char *tag, fmio_mihead *ginfo) { int i; char *errmsg="ERROR(MITIFF fillhead): "; char *where="fillhead"; fmremovenewline(asciifield); if (!strcmp(tag, "Satellite:")) { sprintf(ginfo->satellite, "%s", asciifield); } else if (!strcmp(tag, "Date and Time:")) { ginfo->hour = (unsigned short int) atoi(strtok(asciifield, ":")); ginfo->minute = (unsigned short int) atoi(strtok(NULL, " ")); ginfo->day = (unsigned short int) atoi(strtok(NULL, "/")); ginfo->month = (unsigned short int) atoi(strtok(NULL, "-")); ginfo->year = (unsigned short int) atoi(strtok(NULL, "\0")); } else if (!strcmp(tag, "Channels:")) ginfo->zsize = (unsigned short int) atoi(asciifield); else if (!strcmp(tag, "In this file:")) { if (strncmp(ginfo->satellite," NOAA",5) == 0 || strncmp(ginfo->satellite," PROC",5) == 0 || strstr(ginfo->satellite,"SAF")) { ginfo->ch[0] = (unsigned short int) atoi(strtok(asciifield, " ")); for (i=1; i<ginfo->zsize; i++) { if (ginfo->zsize>1) ginfo->ch[i] = (unsigned short int) atoi(strtok(NULL, " ")); } } else if (strncmp(ginfo->satellite," METE",5) == 0) { strtok(asciifield, " "); if (strncmp(asciifield, " VIS_RAW", 8) == 0) { ginfo->ch[0] = 7; } else if (strncmp(asciifield, " WV_CAL", 7) == 0) { ginfo->ch[0] = 8; } else if (strncmp(asciifield, " IR_CAL", 7) == 0) { ginfo->ch[0] = 9; } else { fprintf(stderr, " %s",errmsg); fprintf(stderr, "Does not recognize channel calibration.\n"); fprintf(stderr, " Input was: %s\n",asciifield); fprintf(stderr, " Exiting function check return value.\n"); return(FM_IO_ERR); } } else if (strncmp(ginfo->satellite," WR",3) == 0) { strtok(asciifield, " "); if (strncmp(asciifield, " PSC_dBz", 9) == 0) { ginfo->ch[0] = 1; } else if (strncmp(asciifield, " PSC_RR", 7) == 0) { ginfo->ch[0] = 2; } else { fprintf(stderr, " %s",errmsg); fprintf(stderr, "Does not recognize channel calibration.\n"); fprintf(stderr, " Input was: %s\n",asciifield); fprintf(stderr, " Exiting function check return value.\n"); return(FM_IO_ERR); } } else if (strncmp(ginfo->satellite," O.E.",5) == 0 || strncmp(ginfo->satellite," GTOP",5) == 0) { strtok(asciifield, " "); ginfo->ch[0] = 0; } else { fmlogmsg(where,"Could not recognize satellite, processing continues"); strtok(asciifield, " "); ginfo->ch[0] = 0; } } else if (!strcmp(tag, "Xsize:")) ginfo->xsize = atoi(asciifield); else if (!strcmp(tag, "Ysize:")) ginfo->ysize = atoi(asciifield); else if (!strcmp(tag, "Bx:")) ginfo->Bx = (float) atof(asciifield); else if (!strcmp(tag, "By:")) ginfo->By = (float) atof(asciifield); else if (!strcmp(tag, "Ax:")) ginfo->Ax = (float) atof(asciifield); else if (!strcmp(tag, "Ay:")) ginfo->Ay = (float) atof(asciifield); return(FM_OK); }
int main(int argc, char *argv[]) { extern char *optarg; char *where="fluxval"; char dir2read[FMSTRING512]; char *outfile, *infile, *indir, *stfile, *parea, *fntest, *datadir; char product[FMSTRING16]; char stime[FMSTRING16], etime[FMSTRING16]; char timeid[FMSTRING16], obstime[FMSTRING16]; int h, i, j, k, l, m, n, novalobs, cmobs, geomobs, noobs; short sflg = 0, eflg = 0, pflg =0, iflg = 0, oflg = 0, aflg = 0, dflg = 0; short rflg = 0, mflg = 0, gflg = 0, cflg = 0, kflg = 0, bflg = 0, wflg = 0; short fflg = 0, lflg = 0; short status; short obsmonth; osihdf ipd; struct tm time_str; time_t time_start, time_end; fmsec1970 tstart, tend; fmtime tstartfm, tendfm; fmstarclist starclist; fmfilelist filelist; stlist stl; stdata **std; s_data sdata; fmgeopos gpos; float meanflux, meanvalues[3], *cmdata, meancm; float meanobs; float misval=-999.; FILE *fp; /* * Decode command line arguments containing path to input files (one for * each area produced) and name (and path) of the output file. */ while ((i = getopt(argc, argv, "ablcwfks:e:p:g:i:o:dr:m:")) != EOF) { switch (i) { case 's': if (strlen(optarg) != 10) { fmerrmsg(where, "stime (%s) is not of appropriate length", optarg); exit(FM_IO_ERR); } strcpy(stime,optarg); sflg++; break; case 'e': if (strlen(optarg) != 10) { fmerrmsg(where, "etime (%s) is not of appropriate length", optarg); exit(FM_IO_ERR); } strcpy(etime,optarg); eflg++; break; case 'g': parea = (char *) malloc(FILENAMELEN); if (!parea) exit(FM_MEMALL_ERR); if (sprintf(parea,"%s",optarg) < 0) exit(FM_IO_ERR); gflg++; break; case 'i': stfile = (char *) malloc(FILENAMELEN); if (!stfile) exit(FM_MEMALL_ERR); if (sprintf(stfile,"%s",optarg) < 0) exit(FM_IO_ERR); iflg++; break; case 'o': outfile = (char *) malloc(FILENAMELEN); if (!outfile) exit(FM_MEMALL_ERR); if (sprintf(outfile,"%s",optarg) < 0) exit(FM_IO_ERR); oflg++; break; case 'r': indir = (char *) malloc(FILENAMELEN); if (!indir) exit(FM_MEMALL_ERR); if (sprintf(indir,"%s",optarg) < 0) exit(FM_IO_ERR); rflg++; break; case 'p': if (sprintf(product,"%s",optarg) < 0) exit(FM_IO_ERR); pflg++; break; case 'm': datadir = (char *) malloc(FILENAMELEN); if (!datadir) exit(FM_MEMALL_ERR); if (sprintf(datadir,"%s",optarg) < 0) exit(FM_IO_ERR); mflg++; break; case 'b': bflg++; break; case 'c': cflg++; break; case 'w': wflg++; break; case 'a': aflg++; break; case 'd': dflg++; break; case 'l': lflg++; break; case 'k': kflg++; break; case 'f': fflg++; break; default: usage(); break; } } /* * Check if all necessary information was given at command line. */ if (!sflg || !eflg || !iflg || !oflg || !pflg) usage(); if ((bflg && cflg)||(bflg && wflg)||(cflg && wflg)) usage(); if (!mflg) { datadir = (char *) malloc(FILENAMELEN); if (!datadir) exit(FM_MEMALL_ERR); if (sprintf(datadir,"%s",DATAPATH) < 0) exit(FM_IO_ERR); } /* * Create character string to test filenames against to avoid * unnecessary processing... */ fntest = (char *) malloc(FILENAMELEN); if (!fntest) exit(FM_MEMALL_ERR); if (dflg) { sprintf(fntest,"daily"); } else if (lflg) { sprintf(fntest,"24h_hl"); } else { sprintf(fntest,"%s.hdf5",parea); } /* * Decode time specification of period. */ if (timecnv(stime, &time_str) != 0) { fmerrmsg(where,"Could not decode time specification"); exit(FM_OK); } time_start = mktime(&time_str); if (timecnv(etime, &time_str) != 0) { fmerrmsg(where,"Could not decode time specification"); exit(FM_OK); } time_end = mktime(&time_str); /* * Decode station list information. */ if (decode_stlist(stfile, &stl) != 0) { fmerrmsg(where," Could not decode station file."); exit(FM_OK); } /* * Loop through products stored */ tstart = ymdh2fmsec1970(stime,0); tend = ymdh2fmsec1970(etime,0); if (tofmtime(tstart,&tstartfm)) { fmerrmsg(where,"Could not decode start time to fmtime"); exit(FM_IO_ERR); } if (tofmtime(tend,&tendfm)) { fmerrmsg(where,"Could not decode end time to fmtime"); exit(FM_IO_ERR); } if (rflg && kflg) { /* starc */ if (fmstarcdirs(tstartfm,tendfm,&starclist)) { fmerrmsg(where,"Could not create starcdirs to process."); exit(FM_IO_ERR); } } else if (rflg && fflg) { /* OSISAF archive */ if (fmsafarcdirs(tstartfm,tendfm,&starclist)) { fmerrmsg(where,"Could not create safarcdirs to process."); exit(FM_IO_ERR); } } else if (rflg) { starclist.nfiles = 1; if (fmalloc_byte_2d(&(starclist.dirname),1,FMSTRING512)) { fmerrmsg(where,"Could not allocate starclist for single directory"); exit(FM_MEMALL_ERR); } sprintf(starclist.dirname[0],"%s",indir); } else { if (fmstarcdirs(tstartfm,tendfm,&starclist)) { fmerrmsg(where,"Could not create starcdirs to process."); exit(FM_IO_ERR); } } if (starclist.nfiles == 0) { fmerrmsg(where,"No estimate files found in %s...",indir); printf("%d - %d \n", (int) tstart, (int) tend); } /* * Open file to store results in */ fp = fopen(outfile,"a"); if (!fp) { fmerrmsg(where,"Could not open output file..."); exit(FM_OK); } /* * Loop through data directories containing satellite estimates * Currently only either SSI or DLI can be read, but this could be * used in a more generic way in the future. * * But first some variables have to be prepared. */ /* * Filename for flux products */ infile = (char *) malloc(FILENAMELEN*sizeof(char)); if (!infile) { fmerrmsg(where,"Could not allocate memory for filename"); exit(FM_OK); } /* * Specifying the size of the data collection box. This should be * configurable in the future, but is hardcoded at present... */ if (dflg || lflg) { sdata.iw = 1; sdata.ih = 1; } else { sdata.iw = 13; sdata.ih = 13; } sdata.data = (float *) malloc((sdata.iw*sdata.ih)*sizeof(float)); if (!sdata.data) { fmerrmsg(where,"Could not allocate memory"); exit(FM_MEMALL_ERR); } obsmonth = 0; for (i=0;i<starclist.nfiles;i++) { if (rflg && kflg) { sprintf(dir2read,"%s/%s/%s",indir,starclist.dirname[i],product); } else if (rflg && fflg) { sprintf(dir2read,"%s/%s",indir,starclist.dirname[i]); } else if (rflg) { sprintf(dir2read,"%s",starclist.dirname[0]); } else { sprintf(dir2read,"%s/%s/%s",STARCPATH,starclist.dirname[i],product); } if (fmreaddir(dir2read, &filelist)) { fmerrmsg(where,"Could not read content of %s", dir2read); continue; } fmfilelist_sort(&filelist); fmlogmsg(where, " Directory\n\t%s\n\tcontains\n\t%d files",filelist.path, filelist.nfiles); for (j=0;j<filelist.nfiles;j++) { if (strstr(filelist.filename[j],fntest)) { fmlogmsg(where,"Processing %s", filelist.filename[j]); /* * Read the satellite derived data */ sprintf(infile,"%s/%s", dir2read,filelist.filename[j]); fmlogmsg(where, "Reading OSISAF product %s", infile); status = read_hdf5_product(infile, &ipd, 0); if (status != 0) { fmerrmsg(where, "Could not read input file %s", infile); exit(FM_OK); } printf("Source: %s\n", ipd.h.source); printf("Product: %s\n", ipd.h.product); printf("Area: %s\n", ipd.h.area); printf("\t%4d-%02d-%02d %02d:%02d\n", ipd.h.year, ipd.h.month, ipd.h.day, ipd.h.hour, ipd.h.minute); for (k=0; k<ipd.h.z; k++) { printf("\tBand %d - %s\n", k, ipd.d[k].description); } printf("\tImage width: %d\n",ipd.h.iw); printf("\tImage height: %d\n",ipd.h.ih); /* * Transform CM data to float array before further processing. */ if (ipd.h.z == 7 && strcmp(ipd.d[6].description,"CM") == 0) { cmdata = (float *) malloc((ipd.h.iw*ipd.h.ih)*sizeof(float)); if (!cmdata) { fmerrmsg(where, "Could not allocate cmdata for %s", filelist.filename[j]); exit(FM_MEMALL_ERR); } for (k=0;k<(ipd.h.iw*ipd.h.ih);k++) { cmdata[k] = (float) ((unsigned short *) ipd.d[6].data)[k]; } } /* * Get observations (if not already read) */ if (!aflg) { if (obsmonth != ipd.h.month) { if (obsmonth > 0) { clear_stdata(std, stl.cnt); } std = (stdata **) malloc(sizeof(stdata *)); if (!std) { fmerrmsg(where," Could not allocate memory"); exit(FM_OK); } fmlogmsg(where, "Reading surface observations of radiative fluxes."); if (cflg) { if (fluxval_readobs_ascii(datadir, ipd.h.year,ipd.h.month, stl, std) != 0) { fmerrmsg(where, "Could not read autostation data\n"); exit(FM_OK); } } else if (bflg) { if (fluxval_readobs_ulric(datadir, ipd.h.year,ipd.h.month, stl, std) != 0) { fmerrmsg(where, "Could not read autostation data\n"); exit(FM_OK); } } else if (wflg) { if (fluxval_readobs_gts(datadir, ipd.h.year,ipd.h.month, stl, std) != 0) { fmerrmsg(where, "Could not read autostation data\n"); exit(FM_OK); } } else { if (fluxval_readobs(datadir, ipd.h.year,ipd.h.month, stl, std) != 0) { fmerrmsg(where, "Could not read autostation data\n"); exit(FM_OK); } } obsmonth = ipd.h.month; } } /* * Store collocated flux estimates and measurements in * file. Below all available stations are looped for each * satellite derived flux file. * * Much of the averaging below can be isolated in * subroutines to make a nicer software outline... */ for (k=0; k<stl.cnt; k++) { /* * Each station listed is processed and data * surrounding the stations is extracted and processed * before storage in collocation file. */ gpos.lat = stl.id[k].lat; gpos.lon = stl.id[k].lon; /* * First the OSISAF flux data surrounding a station * are extracted on a representative subarea. */ fmlogmsg(where, "Collecting OSISAF flux estimates around station %s", stl.id[k].name); if (return_product_area(gpos, ipd.h, ipd.d[0].data, &sdata) != FM_OK) { fmerrmsg(where, "Did not find valid flux data for station %s for flux file %s", stl.id[k].name, filelist.filename[j]); continue; } /* * Average flux estimates first */ if (sdata.iw == 1 && sdata.ih == 1) { meanflux = *(sdata.data); } else { /* * Generate mean value from all satellite data * and store this in collocated file for * easier analysis. This could be changed in * the future... */ meanflux = 0.; novalobs = 0; for (l=0; l<(sdata.iw*sdata.ih); l++) { if (sdata.data[l] >= 0) { meanflux += sdata.data[l]; novalobs++; } } meanflux /= (float) novalobs; } /* * Needs info on observation geometry as well... * This block should probably be extracted into a * subroutine/function... */ for (m=0;m<3;m++) { meanvalues[m] = 0.; } meancm = 0.; if (!dflg && !lflg && (strstr(product,"ssi")!=NULL)) { for (m=0;m<3;m++) { if (return_product_area(gpos, ipd.h, ipd.d[m+3].data, &sdata) != 0) { fmerrmsg(where, " Did not find valid geom data for station %s %s", stl.id[k].name, "although flux data were found..."); continue; } /* * Average obs geom estimates use val obs found for * fluxes. */ meanvalues[m] = 0.; geomobs = 0; if (sdata.iw == 1 && sdata.ih == 1) { meanvalues[m] = *(sdata.data); } else { for (l=0; l<(sdata.iw*sdata.ih); l++) { if (sdata.data[l] >= 0) { meanvalues[m] += sdata.data[l]; geomobs++; } } meanvalues[m] /= (float) geomobs; } } } /* * Process the cloud mask information. * This block should probably be extracted into a * subroutine/function... */ if (!dflg && !lflg) { if ((ipd.h.z == 7) && (strcmp(ipd.d[6].description,"CM") == 0)) { if (return_product_area(gpos, ipd.h, cmdata, &sdata) != 0) { fmerrmsg(where, " Did not find valid CM data for station %s %s\n", stl.id[j].name, "although flux data were found..."); continue; } /* * Average CM used val obs found for fluxes. */ meancm = 0.; cmobs = 0; if (sdata.iw == 1 && sdata.ih == 1) { if (*(sdata.data) >= 0.99 && *(sdata.data) <= 4.01) { meancm = 1; } else if (*(sdata.data) >= 4.99 && *(sdata.data) <= 19.01) { meancm = 2; } } else { for (l=0; l<(sdata.iw*sdata.ih); l++) { if (sdata.data[l] >= 0.99 && sdata.data[l] <= 4.01) { meancm += 1; cmobs++; } else if (sdata.data[l] >= 4.99 && sdata.data[l] <= 19.01) { meancm += 2; cmobs++; } } meancm /= (float) cmobs; } } } /* * If only satellite data are to be extracted around * the stations listed, use the following... */ if (aflg) { /* * First print representative acquisition * time for satellite based estimates. */ fprintf(fp," %4d%02d%02d%02d%02d", ipd.h.year,ipd.h.month,ipd.h.day, ipd.h.hour,ipd.h.minute); /* * Dump satellite based estimates and * auxiliary data. The satellite data are * averaged over 13x13 pixels to * compensate for positioning error of * satellites and the different view * perspective from ground and space. */ fprintf(fp, " %7.2f %3d %3d %s %.2f %.2f %.2f %.2f", meanflux, novalobs, (sdata.iw*sdata.ih), ipd.h.source, meanvalues[0], meanvalues[1], meanvalues[2], meancm); /* * Dump all information concerning * observations. If asynchoneous logging * is done, dump placeholders for future * in situ observations to be included. */ fprintf(fp," %12s %5d %7.2f %7.2f %7.2f", "000000000000", 0, misval,misval,misval); /* * Insert newline to mark record. */ fprintf(fp,"\n"); continue; } /* * If surface observations are available and to be * stored in the same file, process these now... */ if ((*std)[k].missing) { fmerrmsg(where, "Observations are not available for station %d",k); continue; } /* * Checking that sat and obs is from the same hour. * According to Sofus Lystad the Bioforsk observations * represents integration of the last hour, time is * given in UTC. The date specification below might * cause evening observations during month changes to * be missed, but this is not a major problem... * * IPY-observations (Arctic stations) are * represented at the central time. Data are collected * at 1 minute intervals and transformed into hourly * estimates, centered at observation time. * * Ekofisk are represented by 10 min intervals, where * each time represents the data from the previous 10 * minutes. Data are reformatted to hourly data. */ if (dflg || lflg) { sprintf(timeid,"%04d%02d%02d", ipd.h.year, ipd.h.month, ipd.h.day); } else { if (ipd.h.minute > 10) { if (ipd.h.hour == 23) { sprintf(timeid,"%04d%02d%02d0000", ipd.h.year, ipd.h.month, (ipd.h.day+1)); } else { if (cflg) { sprintf(timeid,"%04d%02d%02d%02d30", ipd.h.year, ipd.h.month, ipd.h.day, ipd.h.hour); } else { sprintf(timeid,"%04d%02d%02d%02d00", ipd.h.year, ipd.h.month, ipd.h.day, (ipd.h.hour+1)); } } } else { sprintf(timeid,"%04d%02d%02d%02d00", ipd.h.year, ipd.h.month, ipd.h.day, ipd.h.hour); } } if (stl.id[k].number == (*std)[k].id) { meanobs = 0; noobs = 0; for (h=0; h<NO_MONTHOBS; h++) { if (cflg) { /* Compensating for roundoff errors in * time spec. */ sprintf(obstime,"%s",(*std)[k].param[h].date); obstime[10] = '3'; obstime[11] = '0'; obstime[12] = '0'; } else { sprintf(obstime,"%s",(*std)[k].param[h].date); } if (strstr(obstime,timeid)) { /* * First print representative acquisition * time for satellite based estimates. */ fprintf(fp," %4d%02d%02d%02d%02d", ipd.h.year,ipd.h.month,ipd.h.day, ipd.h.hour,ipd.h.minute); /* * Dump satellite based estimates and * auxiliary data. The satellite data are * averaged over 13x13 pixels to * compensate for positioning error of * satellites and the different view * perspective from ground and space. */ if (dflg || lflg) { fprintf(fp, " %7.2f %3d", meanflux, (sdata.iw*sdata.ih)); } else { fprintf(fp, " %7.2f %3d %3d %s %.2f %.2f %.2f %.2f", meanflux, novalobs, (sdata.iw*sdata.ih), ipd.h.source, meanvalues[0], meanvalues[1], meanvalues[2], meancm); } /* * Dump all information concerning * observations. */ if (dflg || lflg) { for (n=1;n<=24;n++) { if (strstr(product,"ssi")){ if ((*std)[k].param[h+n].Q0 > misval) { meanobs += (*std)[k].param[h+n].Q0; noobs++; } } else { if ((*std)[k].param[h+n].LW > misval) { meanobs += (*std)[k].param[h+n].LW; noobs++; } } } if (noobs == 0) { fprintf(fp," %05d %7.2f", (*std)[k].id,misval); fprintf(fp,"\n"); break; } meanobs /= (float) noobs; fprintf(fp," %05d %7.2f", (*std)[k].id,meanobs); fprintf(fp,"\n"); break; } else { if (cflg) { if (strstr(product,"ssi")) { fprintf(fp, " %12s %05d %7.2f", (*std)[k].param[h].date, (*std)[k].id, (*std)[k].param[h].Q0); } else { fprintf(fp, " %12s %05d %7.2f", (*std)[k].param[h].date, (*std)[k].id, (*std)[k].param[h].LW); } fprintf(fp,"\n"); } else { fprintf(fp, " %12s %05d %7.2f %7.2f %7.2f", (*std)[k].param[h].date, (*std)[k].id, (*std)[k].param[h].TTM, (*std)[k].param[h].Q0, (*std)[k].param[h].ST); fprintf(fp,"\n"); } } } } } } if ((ipd.h.z == 7) && (strcmp(ipd.d[6].description,"CM") == 0)) { free(cmdata); } free_osihdf(&ipd); } } fmfilelist_free(&filelist); } exit(FM_OK); }