Exemplo n.º 1
0
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);
}
Exemplo n.º 2
0
/*
 * 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);
}
Exemplo n.º 3
0
/*
 * 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);
}
Exemplo n.º 4
0
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);
}
Exemplo n.º 5
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);
}
Exemplo n.º 6
0
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);
}
Exemplo n.º 7
0
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);
}
Exemplo n.º 8
0
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);
}