int fm_MITIFF_fillhead_imagepal(char *asciifield, char *tag, fmio_mihead_pal *palinfo) { int i; char *pt; char *where="MITIFF fillhead_imagepal"; pt = strtok(asciifield, "\n"); palinfo->name = (char *) malloc(strlen(pt)+1); if (!palinfo->name) { fmerrmsg(where,"Memory allocation failed"); } sprintf(palinfo->name, "%s", pt); pt = strtok(NULL, "\n"); palinfo->noofcl = atoi(pt); palinfo->clname = (char **) malloc(palinfo->noofcl*sizeof(char *)); if (!palinfo->clname) { fmerrmsg(where,"Memory allocation failed"); } for (i=0; i<palinfo->noofcl; i++) { pt = strtok(NULL, "\n"); /* printf("%s %d\n",pt,strlen(pt)); */ palinfo->clname[i] = (char *) malloc((strlen(pt)+1)*sizeof(char)); if (!palinfo->clname[i]) { fmerrmsg(where,"Memory allocation failed"); } sprintf(palinfo->clname[i], "%s", pt); } return(FM_OK); }
int safcm_init(int boxsize, safcm_data *cm) { char *where="safcm_init"; char what[FMSTRING256]; int i,j; 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); } (*cm).nopix = BOXSIZE2D; (*cm).nav.iw = BOXSIZE; (*cm).nav.ih = BOXSIZE; for (j=0; j<(*cm).nopix; j++) { (*cm).data[j] = SAFCM_MISVAL; } for (i=0;i<FMCOL_NO_CLOUDTYPE_VALUES;i++) { for (j=0;j<FMSTRING256;j++) { (*cm).description[i][j] = '\0'; } } return(FM_OK); }
/* * FUNCTION: * convmeosdate * * PURPOSE: * To convert the date in MEOS MPH structure to midate format. */ int fmmeosdate2fmtime(char s[], fmtime *d) { char *where = "fmmeosdate2fmtime"; int i; char *pt; char *token[6] = {"-", "-", " ", ":", ":", "."}; pt = s; strtok(pt, token[0]); d->fm_mday = atoi(pt); for (i=1; i<6; i++) { pt = strtok(NULL, token[i]); switch (i) { case (1): { if (strcmp(pt, "JAN") == 0) { d->fm_mon = 1; } else if (strcmp(pt, "FEB") == 0) { d->fm_mon = 2; } else if (strcmp(pt, "MAR") == 0) { d->fm_mon = 3; } else if (strcmp(pt, "APR") == 0) { d->fm_mon = 4; } else if (strcmp(pt, "MAY") == 0) { d->fm_mon = 5; } else if (strcmp(pt, "JUN") == 0) { d->fm_mon = 6; } else if (strcmp(pt, "JUL") == 0) { d->fm_mon = 7; } else if (strcmp(pt, "AUG") == 0) { d->fm_mon = 8; } else if (strcmp(pt, "SEP") == 0) { d->fm_mon = 9; } else if (strcmp(pt, "OCT") == 0) { d->fm_mon = 10; } else if (strcmp(pt, "NOV") == 0) { d->fm_mon = 11; } else if (strcmp(pt, "DEC") == 0) { d->fm_mon = 12; } else { fmerrmsg(where,"Time identification of image failed"); return(FM_SYNTAX_ERR); } } case (2): { d->fm_year = atoi(pt); break; } case (3): { d->fm_hour = atoi(pt); break; } case (4): { d->fm_min = atoi(pt); break; } } } return(FM_OK); }
/* * FUNCTION: * fmMalloc * * PURPOSE: * Wrapper around the stdlib's malloc() function that performs * its own check on the returned pointer and terminates the * execution if necessary. * * CAUTION: * Do *not* use this wrapper if you do *not* want your program * to exit on an memory allocation error. * * AUTHOR: * Thomas Lavergne, METNO/FOU, 26.06.2007 */ void *fmMalloc(size_t size) { void *res; res = malloc(size); if (!res) { fmerrmsg("fmMalloc","Memory allocation problem.\n"); exit(FM_MEMALL_ERR); } return res; }
int safssi_check(fmio_img refdata, osihdf *safssi) { char *safssisat[] = {"noaa12","noaa14","noaa15","noaa16","noaa17"}; char *meossat[] = {"NOAA-12","NOAA-14","NOAA-15","NOAA-16","NOAA-17"}; char *safssiprod[] = {"dnnr","dnns","dnat","dngr"}; char *meosprod[] = {"nr","ns","at","gr"}; char *where="safssi_check"; int i, nsat=5, narea=4; fmcol_boolean sat, area, time; struct tm *ssitm; time_t mytime; sat = area = time = FMCOL_FALSE; /* * Check satellite */ for (i=0; i<nsat; i++) { if (strcmp(refdata.sa,meossat[i])==0 && strcmp(safssi->h.source,safssisat[i]) == 0) { sat = FMTRUE; break; } } /* * Check area */ for (i=0; i<narea; i++) { if (strcmp(refdata.area,meosprod[i])==0 && strcmp(safssi->h.area,safssiprod[i]) == 0) { area = FMTRUE; break; } } /* * Check time */ /* This information is not set in the files yet... mytime = (time_t) safssi->sec_1970; printf(" %d %d\n", mytime, safssi->sec_1970); ssitm = gmtime(&mytime); printf("%d %d %d %d %d\n", ssitm->tm_year,ssitm->tm_mon,ssitm->tm_mday,ssitm->tm_hour, ssitm->tm_min); */ if (!sat || !area) { fmerrmsg(where,"Either sat or area error"); fprintf(stderr," Satellite: %s <-> %s\n", refdata.sa,safssi->h.source); fprintf(stderr," Area: %s <-> %s\n", refdata.area,safssi->h.area); return(2); } return(0); }
/* * Get time valid time for the HIRLAM feltfile. */ int fmfeltfile_gettime(char *filename, fmtime *mytime) { char *where = "fmfeltfile_gettime"; char what[FMSTRING256]; long position; short uspt; FILE *fp; position = 2*1024*2+4; if (!(fp = fopen(filename,"r"))) { sprintf(what,"Could not open %s",filename); fmerrmsg(where,what); return(FM_IO_ERR); } if (fseek(fp,position,SEEK_SET) < 0) { sprintf(what,"Could position within %s",filename); fmerrmsg(where,what); return(FM_IO_ERR); } fread(&uspt, sizeof(short), 1, fp); fmbs_short(&uspt); mytime->fm_year = (int) uspt; fread(&uspt, 2, 1, fp); fmbs_short(&uspt); mytime->fm_mday = (int) (uspt%100); mytime->fm_mon = (int) (uspt/100); fread(&uspt, 2, 1, fp); fmbs_short(&uspt); mytime->fm_min = (int) (uspt%100); mytime->fm_hour = (int) (uspt/100); mytime->fm_sec = 0; fclose(fp); return(FM_OK); }
/* Read in the header and store as a string array */ int fm_get_aha_hsa(char *fname,char hsa[FMIO_MAXHDLINES][FMIO_STRMAXCHARS]) { char *where="fm_get_aha_hsa"; FILE *f1; int i, j; char line[FMIO_STRMAXCHARS]=""; f1=fopen(fname,"r"); i=0; while ((strncmp(line,"EOH",3)!=0) && !feof(f1) && (i<FMIO_MAXHDLINES)){ if (fgets(line,FMIO_STRMAXCHARS,f1) == NULL) { fmerrmsg(where,"Could not read line"); } strcpy(hsa[i],line); i++; } /* printf(">>i: %d\n",i); for (j=0;j<i;j++) printf("%02d %s",j,hsa[j]); */ fclose(f1); return(i); }
int safcm_free(safcm_data *cm) { char *where="safcm_free"; char what[FMSTRING256]; int i,j; 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); } (*cm).nopix = 0; (*cm).nav.iw = 0; (*cm).nav.ih = 0; for (i=0;i<FMCOL_NO_CLOUDTYPE_VALUES;i++) { for (j=0;j<MAX_LENGTH_STRING;j++) { (*cm).description[i][j] = '\0'; } } 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); }
/* * Bioforsk data in original format, prior to ingestion in KDVH. Only used * for historical data now. Øystein Godøy, METNO/FOU, 2014-08-21 */ int fluxval_readobs(char *path, int year, short month, stlist stl, stdata **std) { char *where="fluxval_readobs"; char *infile, *dummy; /* while testing char *pl1="TTM TTN TTX TJM TJM20 TJM50 "; char *pl2="UUM UUX RR FM2 FG2 FX2 "; char *pl3="QO BT TGM TGN TGX ST TT"; */ char *pl1="TTM TTN TTX TJM TJM20 TJM50 "; char *pl2="UUM UUX RR FM2 FG2 FX2 "; char *pl3="QO BT TGM TGN TGX ST"; char *pl; short i, sy; int j; FILE *fp; /* * Change year specification to the required 2 digits... */ if (year < 2000) { sy = (short) (year-1900); } else { sy = (short) (year-2000); } /* * Allocate memory required. */ infile = (char *) malloc(FILELEN*sizeof(char)); if (!infile) { fmerrmsg(where,"Could not allocate infile"); return(FM_MEMALL_ERR); } if (create_stdata(std, stl.cnt)) { clear_stdata(std, stl.cnt); return(FM_IO_ERR); } dummy = (char *) malloc(OBSRECLEN*sizeof(char)); if (!dummy) { clear_stdata(std, stl.cnt); fmerrmsg(where,"Could not allocate dummy"); return(FM_MEMALL_ERR); } pl = (char *) malloc(OBSRECLEN*sizeof(char)); if (!pl) { clear_stdata(std, stl.cnt); fmerrmsg(where,"Could not allocate pl"); return(FM_MEMALL_ERR); } sprintf(pl,"%s%s%s",pl1,pl2,pl3); for (i=0; i<stl.cnt; i++) { /* * Create filenames to read using year, month and station number * specification (mm0sssss.cyy). */ sprintf(infile,"%s/%02d0%05d.c%02d",path,month,stl.id[i].number,sy); fprintf(stdout," Reading autostation file: %s\n", infile); /* * Open the specified list of stations and read data into data * structure. Must read first line and the deceide how to read * data (number of parameters vary). */ fp = fopen(infile,"r"); if (!fp) { fmerrmsg(where,"Could not open %s", infile); (*std)[i].missing = 1; continue; } if (!fgets(dummy, OBSRECLEN, fp)) { fmerrmsg(where,"Could not read data."); return(FM_IO_ERR); } if (!strstr(dummy,pl)) { fmerrmsg(where,"Incorrect parameter list\ngot: %s\nexpected: %s", dummy, pl); return(FM_IO_ERR); } (*std)[i].id = stl.id[i].number; j = 0; while (fgets(dummy, OBSRECLEN, fp)) { sscanf(dummy, "%s%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f", (*std)[i].param[j].date, &((*std)[i]).param[j].TTM,&((*std)[i]).param[j].TTN, &((*std)[i]).param[j].TTX, &((*std)[i]).param[j].TJM10,&((*std)[i]).param[j].TJM20, &((*std)[i]).param[j].TJM50, &((*std)[i]).param[j].UUM,&((*std)[i]).param[j].UUX, &((*std)[i]).param[j].RR, &((*std)[i]).param[j].FM2,&((*std)[i]).param[j].FG2, &((*std)[i]).param[j].FX2, &((*std)[i]).param[j].Q0,&((*std)[i]).param[j].BT, &((*std)[i]).param[j].TGM,&((*std)[i]).param[j].TGN, &((*std)[i]).param[j].TGX, &((*std)[i]).param[j].ST, &((*std)[i]).param[j].TT); if ((*std)[i].param[j].TTM > 100000000.) { (*std)[i].param[j].TTM = -999.; } if ((*std)[i].param[j].TTN > 100000000.) { (*std)[i].param[j].TTN = -999.; } if ((*std)[i].param[j].TTX > 100000000.) { (*std)[i].param[j].TTX = -999.; } if ((*std)[i].param[j].TJM10 > 100000000.) { (*std)[i].param[j].TJM10 = -999.; } if ((*std)[i].param[j].TJM20 > 100000000.) { (*std)[i].param[j].TJM20 = -999.; } if ((*std)[i].param[j].TJM50 > 100000000.) { (*std)[i].param[j].TJM50 = -999.; } if ((*std)[i].param[j].UUM > 100000000.) { (*std)[i].param[j].UUM = -999.; } if ((*std)[i].param[j].UUX > 100000000.) { (*std)[i].param[j].UUX = -999.; } if ((*std)[i].param[j].RR > 100000000.) { (*std)[i].param[j].RR = -999.; } if ((*std)[i].param[j].FM2 > 100000000.) { (*std)[i].param[j].FM2 = -999.; } if ((*std)[i].param[j].FG2 > 100000000.) { (*std)[i].param[j].FG2 = -999.; } if ((*std)[i].param[j].FX2 > 100000000.) { (*std)[i].param[j].FX2 = -999.; } if ((*std)[i].param[j].Q0 > 100000000.) { (*std)[i].param[j].Q0 = -999.; } if ((*std)[i].param[j].BT > 100000000.) { (*std)[i].param[j].BT = -999.; } if ((*std)[i].param[j].TGM > 100000000.) { (*std)[i].param[j].TGM = -999.; } if ((*std)[i].param[j].TGN > 100000000.) { (*std)[i].param[j].TGN = -999.; } if ((*std)[i].param[j].TGX > 100000000.) { (*std)[i].param[j].TGX = -999.; } if ((*std)[i].param[j].ST > 100000000.) { (*std)[i].param[j].ST = -999.; } if ((*std)[i].param[j].TT > 100000000.) { (*std)[i].param[j].TT = -999.; } j++; } fclose(fp); } /* * Clean up before function is left. */ free(infile); free(dummy); free(pl); return(FM_OK); }
int fm_MITIFF_read(char *infile, unsigned char *image[], fmio_mihead *ginfo) { char *where="MITIFF_read"; TIFF *in; int i, status, size; short pmi; unsigned int fieldlen, currlen, nextlen, taglen; char *description, *o_description; char *currfield, *nextfield, *field, *pt; char *o_currfield, *o_nextfield, *o_field; char *fieldname[FMIO_FIELDS]={ "Satellite:", "Date and Time:", "SatDir:", "Channels:", "In this file:", "Xsize:", "Ysize:", "Map projection:", "TrueLat:", "GridRot:", "Xunit:", "Yunit:", "NPX:", "NPY:", "Ax:", "Ay:", "Bx:", "By:", "Calibration" }; /* * Open TIFF files and initialize IFD */ in=TIFFOpen(infile, "rc"); if (!in) { printf(" This is no TIFF file! \n"); return(FM_IO_ERR); } /* * Test whether this is a color palette image or not. If so another * function should be used. */ status = TIFFGetField(in, 262, &pmi); if (pmi == 3) { return(FM_IO_ERR); } description = (char *) malloc(1024*sizeof(char)); if (!description) fmerrmsg(where,"Memory allocation failed"); o_description = description; TIFFGetField(in, 270, &description); currfield = (char *) malloc(FMIO_TIFFHEAD*sizeof(char)); if (!currfield) fmerrmsg(where,"Memory allocation failed"); o_currfield = currfield; nextfield = (char *) malloc(FMIO_TIFFHEAD*sizeof(char)); if (!nextfield) fmerrmsg(where,"Memory allocation failed"); o_nextfield = nextfield; for (i=0; i<FMIO_FIELDS-1; i++) { pt = strstr(description, fieldname[i]); sprintf(currfield, "%s", pt); currlen = strlen(currfield); pt = strstr(description, fieldname[i+1]); sprintf(nextfield, "%s", pt); nextlen = strlen(nextfield); taglen = strlen(fieldname[i]); fieldlen = currlen-nextlen-taglen; field = (char *) calloc(fieldlen+1, sizeof(char)); if (!field) fmerrmsg(where,"Memory allocation failed"); o_field = field; currfield += taglen; strncpy(field, currfield, fieldlen); fillhead(field, fieldname[i], ginfo); free(o_field); } free(o_currfield); free(o_nextfield); free(o_description); /* * Read image data into matrix. */ TIFFGetField(in, 256, &ginfo->xsize); TIFFGetField(in, 257, &ginfo->ysize); size = ginfo->xsize*ginfo->ysize; /* * Memory allocated for image data in this function (*image) is freed * in function main process. */ if (ginfo->zsize > FMIO_MAXCHANNELS) { printf("\n\tNOT ENOUGH POINTERS AVAILABLE TO HOLD DATA!\n"); return(FM_IO_ERR); } for (i=0; i<ginfo->zsize; i++) { image[i] = (unsigned char *) malloc((size+1)*sizeof(char)); if (!image[i]) fmerrmsg(where,"Memory allocation failed"); status = TIFFReadRawStrip(in, 0, image[i], size); if (status == -1) return(FM_IO_ERR); if (TIFFReadDirectory(in) == 0) break; } if (ginfo->zsize != (i+1)) { printf("\n\tERROR READING MULTIPLE SUBFILES!\n"); return(FM_IO_ERR); } TIFFClose(in); 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 safssi_name(fmtime refdate, char *basename, char *path, char *filename) { int nf; const char *dummy1="."; const char *dummy2=".."; char *where="safssi_name"; char *mystr; struct dirent *direntp; DIR *dirp; mystr = (char *) malloc(NAMELEN); if (!mystr) { fmerrmsg(where,"Could not allocate mystr"); return(2); } /* * Må sjekke status her... */ sprintf(mystr,"%4d%02d%02d%02d%02d", refdate.fm_year, refdate.fm_mon, refdate.fm_mday, refdate.fm_hour, refdate.fm_min); /* printf(" #### %s %s %s\n",basename,path, mystr); */ dirp = opendir(path); if (!dirp) { fmerrmsg(where,"Opendir in did not work properly"); return(2); } nf = 0; while ((direntp = readdir(dirp)) != NULL) { if (strstr(direntp->d_name,".hdf") == NULL) { continue; } if (strstr(direntp->d_name,mystr) == NULL) { continue; } if (basename == NULL) { if (strstr(direntp->d_name,dummy1) && strlen(direntp->d_name) == 1) { continue; } if (strstr(direntp->d_name,dummy2)) { continue; } sprintf(filename,"%s",direntp->d_name); nf++; } else { if (strstr(direntp->d_name,basename) == NULL) { continue; } sprintf(filename,"%s",direntp->d_name); nf++; } } if (closedir(dirp) != 0) { fmerrmsg(where,"Could not close directory"); return(2); } free(mystr); if (nf == 0) { fmerrmsg(where, "Did not find any files"); return(3); } if (nf > 1) { fmerrmsg(where, "Did find more than 1 file!! Why??"); return(3); } return(0); }
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); }
/* * PURPOSE: * To read DNMI/TIFF palette color files containing either classed satellite * imagery or radar imagery. * * RETURN VALUES: * 0 - Normal and correct ending * 2 - This is not a Palette-color image * * NOTE: * Requires access to libtiff. * * AUTHOR: * Øystein Godøy, DNMI/FOU, 21/07/1999 * MODIFICATION: * Øystein Godøy, DNMI/FOU, 27/03/2001 * Corrected some memory allocation and freeing problems connected to * strtok actually changing the string it operates on. */ int fm_MITIFF_read_imagepal(char *infile, unsigned char *image[], fmio_mihead *ginfo, fmio_mihead_pal *palinfo) { char *where="MITIFF_read_imagepal"; TIFF *in; int i, status, size; short pmi; unsigned int fieldlen, currlen, nextlen, taglen; uint16 *red, *green, *blue; char *description, *o_description; char *currfield, *nextfield, *field, *pt; char *o_currfield, *o_nextfield, *o_field; char *fieldname[FMIO_FIELDS]={ "Satellite:", "Date and Time:", "SatDir:", "Channels:", "In this file:", "Xsize:", "Ysize:", "Map projection:", "TrueLat:", "GridRot:", "Xunit:", "Yunit:", "NPX:", "NPY:", "Ax:", "Ay:", "Bx:", "By:", "COLOR INFO:" }; /* * Open TIFF files and initialize IFD */ in=TIFFOpen(infile, "rc"); if (!in) { printf(" This is no TIFF file! \n"); return(FM_IO_ERR); } /* * Test whether this is a color palette image or not. If so another * function should be used. */ status = TIFFGetField(in, 262, &pmi); if (pmi != 3) { return(FM_IO_ERR); } status = TIFFGetField(in, 320, &red, &green, &blue); if (status != 1) { return(FM_IO_ERR); } for (i=0; i<256; i++) { palinfo->cmap[0][i] = red[i]; palinfo->cmap[1][i] = green[i]; palinfo->cmap[2][i] = blue[i]; } description = (char *) malloc(FMIO_TIFFHEAD*sizeof(char)); if (!description) fmerrmsg(where,"Memory allocation failed"); o_description = description; TIFFGetField(in, 270, &description); /* * Lead through the filed tags defined, except for the last one which will * create a segmentation fault if it is used. This is processed after the * loop. */ currfield = (char *) malloc(FMIO_TIFFHEAD*sizeof(char)); if (!currfield) fmerrmsg(where,"Memory allocation failed"); o_currfield = currfield; nextfield = (char *) malloc(FMIO_TIFFHEAD*sizeof(char)); if (!nextfield) fmerrmsg(where,"Memory allocation failed"); o_nextfield = nextfield; for (i=0; i<FMIO_FIELDS-1; i++) { pt = strstr(description, fieldname[i]); sprintf(currfield, "%s", pt); currlen = strlen(currfield); pt = strstr(description, fieldname[i+1]); sprintf(nextfield, "%s", pt); nextlen = strlen(nextfield); taglen = strlen(fieldname[i]); fieldlen = currlen-nextlen-taglen; field = (char *) malloc((fieldlen+1)*sizeof(char)); if (!field) fmerrmsg(where,"Memory allocation failed"); o_field = field; currfield += taglen; strncpy(field, currfield, fieldlen); fillhead(field, fieldname[i], ginfo); free(o_field); } /* * The last part of the information header is treated as one single string * and is extracted as the remaining part and processed in a suitable way * later... */ pt = strstr(description, fieldname[FMIO_FIELDS-1]); sprintf(currfield, "%s", pt); currlen = strlen(currfield); nextlen = strlen(description); taglen = strlen(fieldname[FMIO_FIELDS-1]); /* fieldlen = nextlen-currlen-taglen; field = (char *) malloc((fieldlen+1)*sizeof(char)); */ fieldlen = nextlen-currlen-taglen; field = (char *) malloc((currlen+1)*sizeof(char)); if (!field) fmerrmsg(where,"Memory allocation failed"); o_field = field; /* * Beware here, in order to help C keep track of which memory to free * later, currfield should be reduced by taglen imediately or better a new * work string should be used, but for now this solution is chosen... */ currfield += taglen; /* strncpy(field, currfield, fieldlen); */ strncpy(field, currfield, currlen); currfield -= taglen; /* printf(" %d-%d-%d-%d\n",currlen,nextlen,taglen,fieldlen); printf("%s\n\n%s\n",currfield, field); printf("%d - %d\n",strlen(currfield),strlen(field)); */ fillhead_imagepal(field, fieldname[FMIO_FIELDS-1], palinfo); free(o_field); free(o_currfield); free(o_nextfield); free(o_description); /* * Read image data into matrix. */ TIFFGetField(in, 256, &ginfo->xsize); TIFFGetField(in, 257, &ginfo->ysize); size = ginfo->xsize*ginfo->ysize; /* * Memory allocated for image data in this function (*image) is freed * in function main process. */ if (ginfo->zsize > FMIO_MAXCHANNELS) { printf("\n\tNOT ENOUGH POINTERS AVAILABLE TO HOLD DATA!\n"); return(FM_IO_ERR); } for (i=0; i<ginfo->zsize; i++) { image[i] = (unsigned char *) malloc((size+1)*sizeof(char)); if (!image[i]) fmerrmsg(where,"Memory allocation failed"); status = TIFFReadRawStrip(in, 0, *image, size); if (status == -1) return(FM_IO_ERR); if (TIFFReadDirectory(in) == 0) break; } if (ginfo->zsize != (i+1)) { printf("\n\tERROR READING MULTIPLE SUBFILES!\n"); return(FM_IO_ERR); } TIFFClose(in); 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); }
/* * Read data extracted from the WMO GTS data stream in BUFR. A wrapper * around bufrdump.pl has been used to generate monthly ASCII files. All * files look the same regardless of which parameters that are available. * No header is applied in files. */ int fluxval_readobs_gts(char *path, int year, short month, stlist stl, stdata **std) { char *where="fluxval_readobs"; char *infile, *dummy; char dummytime[FMSTRING32], dummytime2[FMSTRING32]; char *pl=""; /* Not used currently */ short i; fmtime obstime; int j; FILE *fp; /* * Allocate memory required. */ infile = (char *) malloc(FILELEN*sizeof(char)); if (!infile) { fmerrmsg(where,"Could not allocate infile"); return(FM_MEMALL_ERR); } if (create_stdata(std, stl.cnt)) { clear_stdata(std, stl.cnt); return(FM_IO_ERR); } dummy = (char *) malloc(OBSRECLEN*sizeof(char)); if (!dummy) { clear_stdata(std, stl.cnt); fmerrmsg(where,"Could not allocate dummy"); return(FM_MEMALL_ERR); } for (i=0; i<stl.cnt; i++) { /* * Create filenames to read using year, month and station number */ sprintf(infile,"%s/radflux_%05d_%4d%02d.txt", path,stl.id[i].number,year,month); fprintf(stdout," Reading autostation file: %s\n", infile); /* * Open the specified list of stations and read data into data * structure. Must read first line and the deceide how to read * data (number of parameters vary). */ fp = fopen(infile,"r"); if (!fp) { fmerrmsg(where,"Could not open %s", infile); (*std)[i].missing = 1; continue; } if (!fgets(dummy, OBSRECLEN, fp)) { fmerrmsg(where,"Could not read data."); return(FM_IO_ERR); } if (!fgets(dummy, OBSRECLEN, fp)) { fmerrmsg(where,"Could not read data."); return(FM_IO_ERR); } if (!fgets(dummy, OBSRECLEN, fp)) { fmerrmsg(where,"Could not read data."); return(FM_IO_ERR); } if (!strstr(dummy,pl)) { fmerrmsg(where,"Incorrect parameter list\n\tgot: %s\n\texpected: %s", dummy, pl); return(FM_IO_ERR); } (*std)[i].id = stl.id[i].number; j = 0; while (fgets(dummy, OBSRECLEN, fp)) { sscanf(dummy, "%s%s%f%f%f", dummytime, dummytime2, &((*std)[i]).param[j].Q0, &((*std)[i]).param[j].LW, &((*std)[i]).param[j].ST); strcat(dummytime," "); strcat(dummytime, dummytime2); fmstring2fmtime(dummytime,"YYYY-MM-DD hh:mm:ss",&obstime); sprintf((*std)[i].param[j].date,"%4d%02d%02d%02d%02d%02d", obstime.fm_year,obstime.fm_mon,obstime.fm_mday, obstime.fm_hour,obstime.fm_min,obstime.fm_sec); j++; } } /* * Clean up before function is left. */ free(infile); free(dummy); return(FM_OK); }
int return_product_area(fmgeopos gpos, PRODhead header, float *data, s_data *a) { char *where="return_product_area"; int dx, dy, i, j, k; long l, maxsize; int nodata = 1; fmucsref uref; fmucspos upos; fmindex xyp; uref.Bx = header.Bx; uref.By = header.By; uref.Ax = header.Ax; uref.Ay = header.Ay; uref.iw = header.iw; uref.ih = header.ih; maxsize = header.iw*header.ih; upos = fmgeo2ucs(gpos, MI); xyp = fmucs2ind(uref, upos); /* printf("%.2f %.2f\n", gpos.lat, gpos.lon); printf("%.2f %.2f %.2f %.2f\n", uref.Bx, uref.By, uref.Ax, uref.Ay); printf("%4d %4d\n", uref.iw, uref.ih); printf("%.2f %.2f\n", upos.eastings, upos.northings); */ if ((*a).iw == 1 && (*a).ih == 1) { *((*a).data) = data[fmivec(xyp.col,xyp.row,header.iw)]; return(FM_OK); } if ((*a).iw%2 == 0 || (*a).ih%2 == 0) { fmerrmsg(where, "The area specified must contain an odd number of pixels."); return(FM_IO_ERR); } dx = (int) floorf((float) (*a).iw/2.); dy = (int) floorf((float) (*a).ih/2.); /* printf("dy: %4d dx: %4d\n", dy, dx); */ k = 0; for (i=(xyp.row-dy); i<=(xyp.row+dy); i++) { for (j=(xyp.col-dx); j<=(xyp.col+dx); j++) { l = (int) fmivec(j,i,header.iw); if (l >= maxsize) { fmerrmsg(where, "Image size (%d) exceeded when subsetting image (%d)", maxsize, l); return(FM_IO_ERR); } /* printf("%4d %4d %3d %3d %.2f\n", k, l, i, j, data[l]); */ if ((int) (floorf (data[l]*100.)) != OUTOFIMAGE && (int) (floorf (data[l]*100.)) != MISVAL) { nodata = 0; } (*a).data[k] = data[l]; k++; } } if (nodata) { fmerrmsg(where,"No data were found."); return(FM_IO_ERR); } return(FM_OK); }
int safcm_check(fmio_img refdata, CTy_t *ctype) { char *safcmsat[] = {"noaa12","noaa14","noaa15","noaa16","noaa17","noaa18","noaa19","metop02"}; char *meossat[] = {"NOAA-12","NOAA-14","NOAA-15","NOAA-16","NOAA-17","NOAA-18","NOAA-19","MetOp-02"}; char *safcmprod[] = {"dnnr","dnns","dnat","dngr"}; char *meosprod[] = {"nr","ns","at","gr"}; char *where="safcm_check"; int i, nsat=8, narea=4; fmboolean sat, area, time; struct tm *cmtm; time_t mytime; sat = area = time = FMFALSE; /* printf(" %s %s %d %d\n", ctype->satellite_id, ctype->reg->id, ctype->sec_1970, ctype->orbit_number); */ /* * Check satellite */ for (i=0; i<nsat; i++) { if (strcmp(refdata.sa,meossat[i])==0 && strcmp(ctype->satellite_id,safcmsat[i]) == 0) { sat = FMTRUE; break; } } /* * Check area */ for (i=0; i<narea; i++) { if (strcmp(refdata.area,meosprod[i])==0 && strcmp(ctype->reg->id,safcmprod[i]) == 0) { area = FMTRUE; break; } } /* * Check time */ /* This information is not set in the files yet... mytime = (time_t) ctype->sec_1970; printf(" %d %d\n", mytime, ctype->sec_1970); cmtm = gmtime(&mytime); printf("%d %d %d %d %d\n", cmtm->tm_year,cmtm->tm_mon,cmtm->tm_mday,cmtm->tm_hour, cmtm->tm_min); */ if (!sat || !area) { fmerrmsg(where,"Either sat or area error"); fprintf(stderr," Satellite: [%s] <-> [%s]\n", refdata.sa,ctype->satellite_id); fprintf(stderr," Area: [%s] <-> [%s]\n", refdata.area,ctype->reg->id); fprintf(stderr," sat: %d, area: %d\n",sat,area); return(2); } return(FM_OK); }
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); }
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); }