Esempio n. 1
0
fmsec1970 fmcet2tst(fmsec1970 cet, double lon){

    fmsec1970 tst, deltat, tmptime;
    fmtime t;

    /*
     * The difference between local time and UTC is 240 seconds per degree
     * longitude. Longitude is taken positive eastwards.
     */
    tmptime = cet+fmloncorr(15.,lon);

    /*
     * In addition the local time and true solar time differs by the
     * equation of time which compensates for the irregular behaviour of
     * the Earth's orbit around the Sun.
     */
    tofmtime(tmptime,&t);
    deltat = fmequationoftime(t.fm_yday);

    tst = tmptime+deltat;
    
    return(tst);
}
Esempio n. 2
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);
}