示例#1
0
文件: main.c 项目: rkrug/grass-ci
/*--------------------------------------------------------------------*/
int main(int argc, char *argv[])
{
    /* Variable declarations */
    int nsply, nsplx, nrows, ncols, nsplx_adj, nsply_adj;
    int nsubregion_col, nsubregion_row, subregion_row, subregion_col;
    int subregion = 0, nsubregions = 0;
    int last_row, last_column, grid, bilin, ext, flag_auxiliar, cross;	/* booleans */
    double stepN, stepE, lambda, mean;
    double N_extension, E_extension, edgeE, edgeN;

    const char *mapset, *drv, *db, *vector, *map;
    char table_name[GNAME_MAX], title[64];
    char xname[GNAME_MAX], xmapset[GMAPSET_MAX];

    int dim_vect, nparameters, BW;
    int *lineVect;		/* Vector restoring primitive's ID */
    double *TN, *Q, *parVect;	/* Interpolating and least-square vectors */
    double **N, **obsVect;	/* Interpolation and least-square matrix */

    SEGMENT out_seg, mask_seg;
    const char *out_file, *mask_file;
    int out_fd, mask_fd;
    double seg_size;
    int seg_mb, segments_in_memory;
    int have_mask;

    /* Structs declarations */
    int raster;
    struct Map_info In, In_ext, Out;
    struct History history;

    struct GModule *module;
    struct Option *in_opt, *in_ext_opt, *out_opt, *out_map_opt, *stepE_opt,
               *stepN_opt, *lambda_f_opt, *type_opt, *dfield_opt, *col_opt, *mask_opt,
               *memory_opt, *solver, *error, *iter;
    struct Flag *cross_corr_flag, *spline_step_flag;

    struct Reg_dimens dims;
    struct Cell_head elaboration_reg, original_reg;
    struct bound_box general_box, overlap_box, original_box;

    struct Point *observ;
    struct line_cats *Cats;
    dbCatValArray cvarr;

    int with_z;
    int nrec, ctype = 0;
    struct field_info *Fi;
    dbDriver *driver, *driver_cats;

    /*----------------------------------------------------------------*/
    /* Options declarations */
    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("surface"));
    G_add_keyword(_("interpolation"));
    G_add_keyword(_("LIDAR"));
    module->description =
        _("Performs bicubic or bilinear spline interpolation with Tykhonov regularization.");

    cross_corr_flag = G_define_flag();
    cross_corr_flag->key = 'c';
    cross_corr_flag->description =
        _("Find the best Tykhonov regularizing parameter using a \"leave-one-out\" cross validation method");

    spline_step_flag = G_define_flag();
    spline_step_flag->key = 'e';
    spline_step_flag->label = _("Estimate point density and distance");
    spline_step_flag->description =
        _("Estimate point density and distance for the input vector points within the current region extends and quit");

    in_opt = G_define_standard_option(G_OPT_V_INPUT);
    in_opt->label = _("Name of input vector point map");

    dfield_opt = G_define_standard_option(G_OPT_V_FIELD);
    dfield_opt->guisection = _("Settings");

    col_opt = G_define_standard_option(G_OPT_DB_COLUMN);
    col_opt->required = NO;
    col_opt->label =
        _("Name of the attribute column with values to be used for approximation");
    col_opt->description = _("If not given and input is 3D vector map then z-coordinates are used.");
    col_opt->guisection = _("Settings");

    in_ext_opt = G_define_standard_option(G_OPT_V_INPUT);
    in_ext_opt->key = "sparse_input";
    in_ext_opt->required = NO;
    in_ext_opt->label =
        _("Name of input vector map with sparse points");

    out_opt = G_define_standard_option(G_OPT_V_OUTPUT);
    out_opt->required = NO;
    out_opt->guisection = _("Outputs");

    out_map_opt = G_define_standard_option(G_OPT_R_OUTPUT);
    out_map_opt->key = "raster_output";
    out_map_opt->required = NO;
    out_map_opt->guisection = _("Outputs");

    mask_opt = G_define_standard_option(G_OPT_R_INPUT);
    mask_opt->key = "mask";
    mask_opt->label = _("Raster map to use for masking (applies to raster output only)");
    mask_opt->description = _("Only cells that are not NULL and not zero are interpolated");
    mask_opt->required = NO;

    stepE_opt = G_define_option();
    stepE_opt->key = "ew_step";
    stepE_opt->type = TYPE_DOUBLE;
    stepE_opt->required = NO;
    stepE_opt->answer = "4";
    stepE_opt->description =
        _("Length of each spline step in the east-west direction");
    stepE_opt->guisection = _("Settings");

    stepN_opt = G_define_option();
    stepN_opt->key = "ns_step";
    stepN_opt->type = TYPE_DOUBLE;
    stepN_opt->required = NO;
    stepN_opt->answer = "4";
    stepN_opt->description =
        _("Length of each spline step in the north-south direction");
    stepN_opt->guisection = _("Settings");

    type_opt = G_define_option();
    type_opt->key = "method";
    type_opt->description = _("Spline interpolation algorithm");
    type_opt->type = TYPE_STRING;
    type_opt->options = "bilinear,bicubic";
    type_opt->answer = "bilinear";
    type_opt->guisection = _("Settings");
    G_asprintf((char **) &(type_opt->descriptions),
               "bilinear;%s;bicubic;%s",
               _("Bilinear interpolation"),
               _("Bicubic interpolation"));

    lambda_f_opt = G_define_option();
    lambda_f_opt->key = "lambda_i";
    lambda_f_opt->type = TYPE_DOUBLE;
    lambda_f_opt->required = NO;
    lambda_f_opt->description = _("Tykhonov regularization parameter (affects smoothing)");
    lambda_f_opt->answer = "0.01";
    lambda_f_opt->guisection = _("Settings");

    solver = N_define_standard_option(N_OPT_SOLVER_SYMM);
    solver->options = "cholesky,cg";
    solver->answer = "cholesky";

    iter = N_define_standard_option(N_OPT_MAX_ITERATIONS);

    error = N_define_standard_option(N_OPT_ITERATION_ERROR);

    memory_opt = G_define_option();
    memory_opt->key = "memory";
    memory_opt->type = TYPE_INTEGER;
    memory_opt->required = NO;
    memory_opt->answer = "300";
    memory_opt->label = _("Maximum memory to be used (in MB)");
    memory_opt->description = _("Cache size for raster rows");

    /*----------------------------------------------------------------*/
    /* Parsing */
    G_gisinit(argv[0]);
    if (G_parser(argc, argv))
        exit(EXIT_FAILURE);

    vector = out_opt->answer;
    map = out_map_opt->answer;

    if (vector && map)
        G_fatal_error(_("Choose either vector or raster output, not both"));

    if (!vector && !map && !cross_corr_flag->answer)
        G_fatal_error(_("No raster or vector or cross-validation output"));

    if (!strcmp(type_opt->answer, "linear"))
        bilin = P_BILINEAR;
    else
        bilin = P_BICUBIC;

    stepN = atof(stepN_opt->answer);
    stepE = atof(stepE_opt->answer);
    lambda = atof(lambda_f_opt->answer);

    flag_auxiliar = FALSE;

    drv = db_get_default_driver_name();
    if (!drv) {
        if (db_set_default_connection() != DB_OK)
            G_fatal_error(_("Unable to set default DB connection"));
        drv = db_get_default_driver_name();
    }
    db = db_get_default_database_name();
    if (!db)
        G_fatal_error(_("No default DB defined"));

    /* Set auxiliary table's name */
    if (vector) {
        if (G_name_is_fully_qualified(out_opt->answer, xname, xmapset)) {
            sprintf(table_name, "%s_aux", xname);
        }
        else
            sprintf(table_name, "%s_aux", out_opt->answer);
    }

    /* Something went wrong in a previous v.surf.bspline execution */
    if (db_table_exists(drv, db, table_name)) {
        /* Start driver and open db */
        driver = db_start_driver_open_database(drv, db);
        if (driver == NULL)
            G_fatal_error(_("No database connection for driver <%s> is defined. Run db.connect."),
                          drv);
        db_set_error_handler_driver(driver);

        if (P_Drop_Aux_Table(driver, table_name) != DB_OK)
            G_fatal_error(_("Old auxiliary table could not be dropped"));
        db_close_database_shutdown_driver(driver);
    }

    /* Open input vector */
    if ((mapset = G_find_vector2(in_opt->answer, "")) == NULL)
        G_fatal_error(_("Vector map <%s> not found"), in_opt->answer);

    Vect_set_open_level(1);	/* WITHOUT TOPOLOGY */
    if (1 > Vect_open_old(&In, in_opt->answer, mapset))
        G_fatal_error(_("Unable to open vector map <%s> at the topological level"),
                      in_opt->answer);

    bspline_field = 0; /* assume 3D input */
    bspline_column = col_opt->answer;

    with_z = !bspline_column && Vect_is_3d(&In);

    if (Vect_is_3d(&In)) {
        if (!with_z)
            G_verbose_message(_("Input is 3D: using attribute values instead of z-coordinates for approximation"));
        else
            G_verbose_message(_("Input is 3D: using z-coordinates for approximation"));
    }
    else { /* 2D */
        if (!bspline_column)
            G_fatal_error(_("Input vector map is 2D. Parameter <%s> required."), col_opt->key);
    }

    if (!with_z) {
        bspline_field = Vect_get_field_number(&In, dfield_opt->answer);
    }

    /* Estimate point density and mean distance for current region */
    if (spline_step_flag->answer) {
        double dens, dist;
        if (P_estimate_splinestep(&In, &dens, &dist) == 0) {
            fprintf(stdout, _("Estimated point density: %.4g"), dens);
            fprintf(stdout, _("Estimated mean distance between points: %.4g"), dist);
        }
        else {
            fprintf(stdout, _("No points in current region"));
        }

        Vect_close(&In);
        exit(EXIT_SUCCESS);
    }

    /*----------------------------------------------------------------*/
    /* Cross-correlation begins */
    if (cross_corr_flag->answer) {
        G_debug(1, "CrossCorrelation()");
        cross = cross_correlation(&In, stepE, stepN);

        if (cross != TRUE)
            G_fatal_error(_("Cross validation didn't finish correctly"));
        else {
            G_debug(1, "Cross validation finished correctly");

            Vect_close(&In);

            G_done_msg(_("Cross validation finished for ew_step = %f and ns_step = %f"), stepE, stepN);
            exit(EXIT_SUCCESS);
        }
    }

    /* Open input ext vector */
    ext = FALSE;
    if (in_ext_opt->answer) {
        ext = TRUE;
        G_message(_("Vector map <%s> of sparse points will be interpolated"),
                  in_ext_opt->answer);

        if ((mapset = G_find_vector2(in_ext_opt->answer, "")) == NULL)
            G_fatal_error(_("Vector map <%s> not found"), in_ext_opt->answer);

        Vect_set_open_level(1);	/* WITHOUT TOPOLOGY */
        if (1 > Vect_open_old(&In_ext, in_ext_opt->answer, mapset))
            G_fatal_error(_("Unable to open vector map <%s> at the topological level"),
                          in_opt->answer);
    }

    /* Open output map */
    /* vector output */
    if (vector && !map) {
        if (strcmp(drv, "dbf") == 0)
            G_fatal_error(_("Sorry, the <%s> driver is not compatible with "
                            "the vector output of this module. "
                            "Try with raster output or another driver."), drv);

        Vect_check_input_output_name(in_opt->answer, out_opt->answer,
                                     G_FATAL_EXIT);
        grid = FALSE;

        if (0 > Vect_open_new(&Out, out_opt->answer, WITH_Z))
            G_fatal_error(_("Unable to create vector map <%s>"),
                          out_opt->answer);

        /* Copy vector Head File */
        if (ext == FALSE) {
            Vect_copy_head_data(&In, &Out);
            Vect_hist_copy(&In, &Out);
        }
        else {
            Vect_copy_head_data(&In_ext, &Out);
            Vect_hist_copy(&In_ext, &Out);
        }
        Vect_hist_command(&Out);

        G_verbose_message(_("Points in input vector map <%s> will be interpolated"),
                          vector);
    }


    /* read z values from attribute table */
    if (bspline_field > 0) {
        G_message(_("Reading values from attribute table..."));
        db_CatValArray_init(&cvarr);
        Fi = Vect_get_field(&In, bspline_field);
        if (Fi == NULL)
            G_fatal_error(_("Cannot read layer info"));

        driver_cats = db_start_driver_open_database(Fi->driver, Fi->database);
        /*G_debug (0, _("driver=%s db=%s"), Fi->driver, Fi->database); */

        if (driver_cats == NULL)
            G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
                          Fi->database, Fi->driver);
        db_set_error_handler_driver(driver_cats);

        nrec =
            db_select_CatValArray(driver_cats, Fi->table, Fi->key,
                                  col_opt->answer, NULL, &cvarr);
        G_debug(3, "nrec = %d", nrec);

        ctype = cvarr.ctype;
        if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_DOUBLE)
            G_fatal_error(_("Column type not supported"));

        if (nrec < 0)
            G_fatal_error(_("Unable to select data from table"));

        G_verbose_message(_("%d records selected from table"), nrec);

        db_close_database_shutdown_driver(driver_cats);
    }

    /*----------------------------------------------------------------*/
    /* Interpolation begins */
    G_debug(1, "Interpolation()");

    /* Open driver and database */
    driver = db_start_driver_open_database(drv, db);
    if (driver == NULL)
        G_fatal_error(_("No database connection for driver <%s> is defined. "
                        "Run db.connect."), drv);
    db_set_error_handler_driver(driver);

    /* Create auxiliary table */
    if (vector) {
        if ((flag_auxiliar = P_Create_Aux4_Table(driver, table_name)) == FALSE) {
            P_Drop_Aux_Table(driver, table_name);
            G_fatal_error(_("Interpolation: Creating table: "
                            "It was impossible to create table <%s>."),
                          table_name);
        }
        /* db_create_index2(driver, table_name, "ID"); */
        /* sqlite likes that ??? */
        db_close_database_shutdown_driver(driver);
        driver = db_start_driver_open_database(drv, db);
    }

    /* raster output */
    raster = -1;
    Rast_set_fp_type(DCELL_TYPE);
    if (!vector && map) {
        grid = TRUE;
        raster = Rast_open_fp_new(out_map_opt->answer);

        G_verbose_message(_("Cells for raster map <%s> will be interpolated"),
                          map);
    }

    /* Setting regions and boxes */
    G_debug(1, "Interpolation: Setting regions and boxes");
    G_get_window(&original_reg);
    G_get_window(&elaboration_reg);
    Vect_region_box(&original_reg, &original_box);
    Vect_region_box(&elaboration_reg, &overlap_box);
    Vect_region_box(&elaboration_reg, &general_box);

    nrows = Rast_window_rows();
    ncols = Rast_window_cols();

    /* Alloc raster matrix */
    have_mask = 0;
    out_file = mask_file = NULL;
    out_fd = mask_fd = -1;
    if (grid == TRUE) {
        int row;
        DCELL *drastbuf;

        seg_mb = atoi(memory_opt->answer);
        if (seg_mb < 3)
            G_fatal_error(_("Memory in MB must be >= 3"));

        if (mask_opt->answer)
            seg_size = sizeof(double) + sizeof(char);
        else
            seg_size = sizeof(double);

        seg_size = (seg_size * SEGSIZE * SEGSIZE) / (1 << 20);
        segments_in_memory = seg_mb / seg_size + 0.5;
        G_debug(1, "%d %dx%d segments held in memory", segments_in_memory, SEGSIZE, SEGSIZE);

        out_file = G_tempfile();
        out_fd = creat(out_file, 0666);
        if (Segment_format(out_fd, nrows, ncols, SEGSIZE, SEGSIZE, sizeof(double)) != 1)
            G_fatal_error(_("Can not create temporary file"));
        close(out_fd);

        out_fd = open(out_file, 2);
        if (Segment_init(&out_seg, out_fd, segments_in_memory) != 1)
            G_fatal_error(_("Can not initialize temporary file"));

        /* initialize output */
        G_message(_("Initializing output..."));

        drastbuf = Rast_allocate_buf(DCELL_TYPE);
        Rast_set_d_null_value(drastbuf, ncols);
        for (row = 0; row < nrows; row++) {
            G_percent(row, nrows, 2);
            Segment_put_row(&out_seg, drastbuf, row);
        }
        G_percent(row, nrows, 2);

        if (mask_opt->answer) {
            int row, col, maskfd;
            DCELL dval, *drastbuf;
            char mask_val;

            G_message(_("Load masking map"));

            mask_file = G_tempfile();
            mask_fd = creat(mask_file, 0666);
            if (Segment_format(mask_fd, nrows, ncols, SEGSIZE, SEGSIZE, sizeof(char)) != 1)
                G_fatal_error(_("Can not create temporary file"));
            close(mask_fd);

            mask_fd = open(mask_file, 2);
            if (Segment_init(&mask_seg, mask_fd, segments_in_memory) != 1)
                G_fatal_error(_("Can not initialize temporary file"));

            maskfd = Rast_open_old(mask_opt->answer, "");
            drastbuf = Rast_allocate_buf(DCELL_TYPE);

            for (row = 0; row < nrows; row++) {
                G_percent(row, nrows, 2);
                Rast_get_d_row(maskfd, drastbuf, row);
                for (col = 0; col < ncols; col++) {
                    dval = drastbuf[col];
                    if (Rast_is_d_null_value(&dval) || dval == 0)
                        mask_val = 0;
                    else
                        mask_val = 1;

                    Segment_put(&mask_seg, &mask_val, row, col);
                }
            }

            G_percent(row, nrows, 2);
            G_free(drastbuf);
            Rast_close(maskfd);

            have_mask = 1;
        }
    }

    /*------------------------------------------------------------------
      | Subdividing and working with tiles:
      | Each original region will be divided into several subregions.
      | Each one will be overlaped by its neighbouring subregions.
      | The overlapping is calculated as a fixed OVERLAP_SIZE times
      | the largest spline step plus 2 * edge
      ----------------------------------------------------------------*/

    /* Fixing parameters of the elaboration region */
    P_zero_dim(&dims);		/* Set dim struct to zero */

    nsplx_adj = NSPLX_MAX;
    nsply_adj = NSPLY_MAX;
    if (stepN > stepE)
        dims.overlap = OVERLAP_SIZE * stepN;
    else
        dims.overlap = OVERLAP_SIZE * stepE;
    P_get_edge(bilin, &dims, stepE, stepN);
    P_set_dim(&dims, stepE, stepN, &nsplx_adj, &nsply_adj);

    G_verbose_message(_("Adjusted EW splines %d"), nsplx_adj);
    G_verbose_message(_("Adjusted NS splines %d"), nsply_adj);

    /* calculate number of subregions */
    edgeE = dims.ew_size - dims.overlap - 2 * dims.edge_v;
    edgeN = dims.sn_size - dims.overlap - 2 * dims.edge_h;

    N_extension = original_reg.north - original_reg.south;
    E_extension = original_reg.east - original_reg.west;

    nsubregion_col = ceil(E_extension / edgeE) + 0.5;
    nsubregion_row = ceil(N_extension / edgeN) + 0.5;

    if (nsubregion_col < 0)
        nsubregion_col = 0;
    if (nsubregion_row < 0)
        nsubregion_row = 0;

    nsubregions = nsubregion_row * nsubregion_col;

    /* Creating line and categories structs */
    Cats = Vect_new_cats_struct();
    Vect_cat_set(Cats, 1, 0);

    subregion_row = 0;
    elaboration_reg.south = original_reg.north;
    last_row = FALSE;

    while (last_row == FALSE) {	/* For each subregion row */
        subregion_row++;
        P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims,
                      GENERAL_ROW);

        if (elaboration_reg.north > original_reg.north) {	/* First row */

            P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims,
                          FIRST_ROW);
        }

        if (elaboration_reg.south <= original_reg.south) {	/* Last row */

            P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims,
                          LAST_ROW);
            last_row = TRUE;
        }

        nsply =
            ceil((elaboration_reg.north -
                  elaboration_reg.south) / stepN) + 0.5;
        G_debug(1, "Interpolation: nsply = %d", nsply);
        /*
        if (nsply > NSPLY_MAX)
            nsply = NSPLY_MAX;
        */
        elaboration_reg.east = original_reg.west;
        last_column = FALSE;
        subregion_col = 0;

        /* TODO: process each subregion using its own thread (via OpenMP or pthreads) */
        /*     I'm not sure about pthreads, but you can tell OpenMP to start all at the
        	same time and it will keep num_workers supplied with the next job as free
        	cpus become available */
        while (last_column == FALSE) {	/* For each subregion column */
            int npoints = 0;
            /* needed for sparse points interpolation */
            int npoints_ext, *lineVect_ext = NULL;
            double **obsVect_ext;	/*, mean_ext = .0; */
            struct Point *observ_ext;

            subregion_col++;
            subregion++;
            if (nsubregions > 1)
                G_message(_("Processing subregion %d of %d..."), subregion, nsubregions);

            P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims,
                          GENERAL_COLUMN);

            if (elaboration_reg.west < original_reg.west) {	/* First column */

                P_set_regions(&elaboration_reg, &general_box, &overlap_box,
                              dims, FIRST_COLUMN);
            }

            if (elaboration_reg.east >= original_reg.east) {	/* Last column */

                P_set_regions(&elaboration_reg, &general_box, &overlap_box,
                              dims, LAST_COLUMN);
                last_column = TRUE;
            }
            nsplx =
                ceil((elaboration_reg.east -
                      elaboration_reg.west) / stepE) + 0.5;
            G_debug(1, "Interpolation: nsplx = %d", nsplx);
            /*
            if (nsplx > NSPLX_MAX)
            nsplx = NSPLX_MAX;
            */
            G_debug(1, "Interpolation: (%d,%d): subregion bounds",
                    subregion_row, subregion_col);
            G_debug(1, "Interpolation: \t\tNORTH:%.2f\t",
                    elaboration_reg.north);
            G_debug(1, "Interpolation: WEST:%.2f\t\tEAST:%.2f",
                    elaboration_reg.west, elaboration_reg.east);
            G_debug(1, "Interpolation: \t\tSOUTH:%.2f",
                    elaboration_reg.south);

#ifdef DEBUG_SUBREGIONS
            fprintf(stdout, "B 5\n");
            fprintf(stdout, " %.11g %.11g\n", elaboration_reg.east, elaboration_reg.north);
            fprintf(stdout, " %.11g %.11g\n", elaboration_reg.west, elaboration_reg.north);
            fprintf(stdout, " %.11g %.11g\n", elaboration_reg.west, elaboration_reg.south);
            fprintf(stdout, " %.11g %.11g\n", elaboration_reg.east, elaboration_reg.south);
            fprintf(stdout, " %.11g %.11g\n", elaboration_reg.east, elaboration_reg.north);
            fprintf(stdout, "C 1 1\n");
            fprintf(stdout, " %.11g %.11g\n", (elaboration_reg.west + elaboration_reg.east) / 2,
                    (elaboration_reg.south + elaboration_reg.north) / 2);
            fprintf(stdout, " 1 %d\n", subregion);
#endif



            /* reading points in interpolation region */
            dim_vect = nsplx * nsply;
            observ_ext = NULL;
            if (grid == FALSE && ext == TRUE) {
                observ_ext =
                    P_Read_Vector_Region_Map(&In_ext,
                                             &elaboration_reg,
                                             &npoints_ext, dim_vect,
                                             1);
            }
            else
                npoints_ext = 1;

            if (grid == TRUE && have_mask) {
                /* any unmasked cells in general region ? */
                mean = 0;
                observ_ext =
                    P_Read_Raster_Region_masked(&mask_seg, &original_reg,
                                                original_box, general_box,
                                                &npoints_ext, dim_vect, mean);
            }

            observ = NULL;
            if (npoints_ext > 0) {
                observ =
                    P_Read_Vector_Region_Map(&In, &elaboration_reg, &npoints,
                                             dim_vect, bspline_field);
            }
            else
                npoints = 1;

            G_debug(1,
                    "Interpolation: (%d,%d): Number of points in <elaboration_box> is %d",
                    subregion_row, subregion_col, npoints);
            if (npoints > 0)
                G_verbose_message(_("%d points found in this subregion"), npoints);
            /* only interpolate if there are any points in current subregion */
            if (npoints > 0 && npoints_ext > 0) {
                int i;

                nparameters = nsplx * nsply;
                BW = P_get_BandWidth(bilin, nsply);

                /* Least Squares system */
                N = G_alloc_matrix(nparameters, BW);	/* Normal matrix */
                TN = G_alloc_vector(nparameters);	/* vector */
                parVect = G_alloc_vector(nparameters);	/* Parameters vector */
                obsVect = G_alloc_matrix(npoints, 3);	/* Observation vector */
                Q = G_alloc_vector(npoints);	/* "a priori" var-cov matrix */
                lineVect = G_alloc_ivector(npoints);	/*  */

                for (i = 0; i < npoints; i++) {	/* Setting obsVect vector & Q matrix */
                    double dval;

                    Q[i] = 1;	/* Q=I */
                    lineVect[i] = observ[i].lineID;
                    obsVect[i][0] = observ[i].coordX;
                    obsVect[i][1] = observ[i].coordY;

                    /* read z coordinates from attribute table */
                    if (bspline_field > 0) {
                        int cat, ival, ret;

                        cat = observ[i].cat;
                        if (cat < 0)
                            continue;

                        if (ctype == DB_C_TYPE_INT) {
                            ret =
                                db_CatValArray_get_value_int(&cvarr, cat,
                                                             &ival);
                            obsVect[i][2] = ival;
                            observ[i].coordZ = ival;
                        }
                        else {	/* DB_C_TYPE_DOUBLE */
                            ret =
                                db_CatValArray_get_value_double(&cvarr, cat,
                                                                &dval);
                            obsVect[i][2] = dval;
                            observ[i].coordZ = dval;
                        }
                        if (ret != DB_OK) {
                            G_warning(_("Interpolation: (%d,%d): No record for point (cat = %d)"),
                                      subregion_row, subregion_col, cat);
                            continue;
                        }
                    }
                    /* use z coordinates of 3D vector */
                    else {
                        obsVect[i][2] = observ[i].coordZ;
                    }
                }

                /* Mean calculation for every point */
                mean = P_Mean_Calc(&elaboration_reg, observ, npoints);

                G_debug(1, "Interpolation: (%d,%d): mean=%lf",
                        subregion_row, subregion_col, mean);

                G_free(observ);

                for (i = 0; i < npoints; i++)
                    obsVect[i][2] -= mean;

                /* Bilinear interpolation */
                if (bilin) {
                    G_debug(1,
                            "Interpolation: (%d,%d): Bilinear interpolation...",
                            subregion_row, subregion_col);
                    normalDefBilin(N, TN, Q, obsVect, stepE, stepN, nsplx,
                                   nsply, elaboration_reg.west,
                                   elaboration_reg.south, npoints,
                                   nparameters, BW);
                    nCorrectGrad(N, lambda, nsplx, nsply, stepE, stepN);
                }
                /* Bicubic interpolation */
                else {
                    G_debug(1,
                            "Interpolation: (%d,%d): Bicubic interpolation...",
                            subregion_row, subregion_col);
                    normalDefBicubic(N, TN, Q, obsVect, stepE, stepN, nsplx,
                                     nsply, elaboration_reg.west,
                                     elaboration_reg.south, npoints,
                                     nparameters, BW);
                    nCorrectGrad(N, lambda, nsplx, nsply, stepE, stepN);
                }

                if(G_strncasecmp(solver->answer, "cg", 2) == 0)
                    G_math_solver_cg_sband(N, parVect, TN, nparameters, BW, atoi(iter->answer), atof(error->answer));
                else
                    G_math_solver_cholesky_sband(N, parVect, TN, nparameters, BW);


                G_free_matrix(N);
                G_free_vector(TN);
                G_free_vector(Q);

                if (grid == TRUE) {	/* GRID INTERPOLATION ==> INTERPOLATION INTO A RASTER */
                    G_debug(1, "Interpolation: (%d,%d): Regular_Points...",
                            subregion_row, subregion_col);

                    if (!have_mask) {
                        P_Regular_Points(&elaboration_reg, &original_reg, general_box,
                                         overlap_box, &out_seg, parVect,
                                         stepN, stepE, dims.overlap, mean,
                                         nsplx, nsply, nrows, ncols, bilin);
                    }
                    else {
                        P_Sparse_Raster_Points(&out_seg,
                                               &elaboration_reg, &original_reg,
                                               general_box, overlap_box,
                                               observ_ext, parVect,
                                               stepE, stepN,
                                               dims.overlap, nsplx, nsply,
                                               npoints_ext, bilin, mean);
                    }
                }
                else {		/* OBSERVATION POINTS INTERPOLATION */
                    if (ext == FALSE) {
                        G_debug(1, "Interpolation: (%d,%d): Sparse_Points...",
                                subregion_row, subregion_col);
                        P_Sparse_Points(&Out, &elaboration_reg, general_box,
                                        overlap_box, obsVect, parVect,
                                        lineVect, stepE, stepN,
                                        dims.overlap, nsplx, nsply, npoints,
                                        bilin, Cats, driver, mean,
                                        table_name);
                    }
                    else {	/* FLAG_EXT == TRUE */

                        /* done that earlier */
                        /*
                        int npoints_ext, *lineVect_ext = NULL;
                        double **obsVect_ext;
                        struct Point *observ_ext;

                        observ_ext =
                            P_Read_Vector_Region_Map(&In_ext,
                        			     &elaboration_reg,
                        			     &npoints_ext, dim_vect,
                        			     1);
                        */

                        obsVect_ext = G_alloc_matrix(npoints_ext, 3);	/* Observation vector_ext */
                        lineVect_ext = G_alloc_ivector(npoints_ext);

                        for (i = 0; i < npoints_ext; i++) {	/* Setting obsVect_ext vector & Q matrix */
                            obsVect_ext[i][0] = observ_ext[i].coordX;
                            obsVect_ext[i][1] = observ_ext[i].coordY;
                            obsVect_ext[i][2] = observ_ext[i].coordZ - mean;
                            lineVect_ext[i] = observ_ext[i].lineID;
                        }

                        G_free(observ_ext);

                        G_debug(1, "Interpolation: (%d,%d): Sparse_Points...",
                                subregion_row, subregion_col);
                        P_Sparse_Points(&Out, &elaboration_reg, general_box,
                                        overlap_box, obsVect_ext, parVect,
                                        lineVect_ext, stepE, stepN,
                                        dims.overlap, nsplx, nsply,
                                        npoints_ext, bilin, Cats, driver,
                                        mean, table_name);

                        G_free_matrix(obsVect_ext);
                        G_free_ivector(lineVect_ext);
                    }		/* END FLAG_EXT == TRUE */
                }		/* END GRID == FALSE */
                G_free_vector(parVect);
                G_free_matrix(obsVect);
                G_free_ivector(lineVect);
            }
            else {
                if (observ)
                    G_free(observ);
                if (observ_ext)
                    G_free(observ_ext);
                if (npoints == 0)
                    G_warning(_("No data within this subregion. "
                                "Consider increasing spline step values."));
            }
        }			/*! END WHILE; last_column = TRUE */
    }				/*! END WHILE; last_row = TRUE */

    G_verbose_message(_("Writing output..."));
    /* Writing the output raster map */
    if (grid == TRUE) {
        int row, col;
        DCELL *drastbuf, dval;


        if (have_mask) {
            Segment_release(&mask_seg);	/* release memory  */
            close(mask_fd);
            unlink(mask_file);
        }

        drastbuf = Rast_allocate_buf(DCELL_TYPE);
        for (row = 0; row < nrows; row++) {
            G_percent(row, nrows, 2);
            for (col = 0; col < ncols; col++) {
                Segment_get(&out_seg, &dval, row, col);
                drastbuf[col] = dval;
            }
            Rast_put_d_row(raster, drastbuf);
        }

        Rast_close(raster);

        Segment_release(&out_seg);	/* release memory  */
        close(out_fd);
        unlink(out_file);
        /* set map title */
        sprintf(title, "%s interpolation with Tykhonov regularization",
                type_opt->answer);
        Rast_put_cell_title(out_map_opt->answer, title);
        /* write map history */
        Rast_short_history(out_map_opt->answer, "raster", &history);
        Rast_command_history(&history);
        Rast_write_history(out_map_opt->answer, &history);
    }
    /* Writing to the output vector map the points from the overlapping zones */
    else if (flag_auxiliar == TRUE) {
        if (ext == FALSE)
            P_Aux_to_Vector(&In, &Out, driver, table_name);
        else
            P_Aux_to_Vector(&In_ext, &Out, driver, table_name);

        /* Drop auxiliary table */
        G_debug(1, "%s: Dropping <%s>", argv[0], table_name);
        if (P_Drop_Aux_Table(driver, table_name) != DB_OK)
            G_fatal_error(_("Auxiliary table could not be dropped"));
    }

    db_close_database_shutdown_driver(driver);

    Vect_close(&In);
    if (ext != FALSE)
        Vect_close(&In_ext);
    if (vector)
        Vect_close(&Out);

    G_done_msg(" ");

    exit(EXIT_SUCCESS);
}				/*END MAIN */
示例#2
0
int main(int argc, char* argv[])
{
	int it,kt,ia,is,i1,i2,tdmute,jsx,jsz,jgx,jgz,sxbeg,szbeg,gxbeg,gzbeg, distx, distz;
	int *sxz, *gxz;
	float tmp, amp, vmax;
	float *wlt, *d2x, *d1z, *bndr;
	float **v0, **vv, **dcal, **den;
	float **sp, **spz, **spx, **svz, **svx, **gp, **gpz, **gpx, **gvz, **gvx;
	float ***num, ***adcig;
    	sf_file vmodl, rtmadcig, vecx, vecz; /* I/O files */

    	sf_init(argc,argv);
#ifdef _OPENMP
    	omp_init();
#endif

    	/*< set up I/O files >*/
    	vmodl = sf_input ("in");   /* velocity model, unit=m/s */
    	rtmadcig = sf_output("out");  /* ADCIG obtained by Poynting vector */
	vecx=sf_output("vecx");
	vecz=sf_output("vecz");

    	/* get parameters for RTM */
    	if (!sf_histint(vmodl,"n1",&nz)) sf_error("no n1");
    	if (!sf_histint(vmodl,"n2",&nx)) sf_error("no n2");
    	if (!sf_histfloat(vmodl,"d1",&dz)) sf_error("no d1");
   	if (!sf_histfloat(vmodl,"d2",&dx)) sf_error("no d2");

    	if (!sf_getfloat("amp",&amp)) amp=1.e3;	
	/* maximum amplitude of ricker wavelet*/
    	if (!sf_getfloat("fm",&fm)) sf_error("no fm");	
	/* dominant freq of ricker */
    	if (!sf_getfloat("dt",&dt)) sf_error("no dt");	
	/* time interval */
    	if (!sf_getint("nt",&nt))   sf_error("no nt");	
	/* total modeling time steps */
    	if (!sf_getint("ns",&ns))   sf_error("no ns");	
	/* total shots */
    	if (!sf_getint("ng",&ng))   sf_error("no ng");	
	/* total receivers in each shot */
    	if (!sf_getint("nb",&nb))   nb=20; 
	/* thickness of split PML */
    	if (!sf_getint("na",&na)) na=30;
	/* number of angles*/
    	if (!sf_getint("kt",&kt))   kt=200;
	/* record poynting vector at kt */
	if (!sf_getint("jsx",&jsx))   sf_error("no jsx");
	/* source x-axis  jump interval  */
    	if (!sf_getint("jsz",&jsz))   jsz=0;
	/* source z-axis jump interval  */
    	if (!sf_getint("jgx",&jgx))   jgx=1;
	/* receiver x-axis jump interval */
    	if (!sf_getint("jgz",&jgz))   jgz=0;
	/* receiver z-axis jump interval */
    	if (!sf_getint("sxbeg",&sxbeg))   sf_error("no sxbeg");
	/* x-begining index of sources, starting from 0 */
    	if (!sf_getint("szbeg",&szbeg))   sf_error("no szbeg");
	/* z-begining index of sources, starting from 0 */
    	if (!sf_getint("gxbeg",&gxbeg))   sf_error("no gxbeg");
	/* x-begining index of receivers, starting from 0 */
    	if (!sf_getint("gzbeg",&gzbeg))   sf_error("no gzbeg");
	/* z-begining index of receivers, starting from 0 */
	if (!sf_getbool("csdgather",&csdgather)) csdgather=true;
	/* default, common shot-gather; if n, record at every point*/
	if (!sf_getfloat("vmute",&vmute))   vmute=1500;
	/* muting velocity to remove the low-freq noise, unit=m/s*/
	if (!sf_getint("tdmute",&tdmute))   tdmute=2./(fm*dt);
	/* number of deleyed time samples to mute */

	_dx=1./dx;
	_dz=1./dz;
	nzpad=nz+2*nb;
	nxpad=nx+2*nb;
	da=SF_PI/(float)na;/* angle unit, rad; */
	var=da/3.;
	var=2.0*var*var;

    	sf_putint(rtmadcig,"n1",nz);
    	sf_putint(rtmadcig,"n2",nx);
	sf_putfloat(rtmadcig,"n3",na);
    	sf_putfloat(rtmadcig,"d1",dz);
    	sf_putfloat(rtmadcig,"d2",dx);
	sf_putfloat(rtmadcig,"d3",90./(float)na);

	/* allocate variables */
	wlt=sf_floatalloc(nt);
	v0=sf_floatalloc2(nz,nx); 	
	vv=sf_floatalloc2(nzpad, nxpad);
	sp =sf_floatalloc2(nzpad, nxpad);
	spz=sf_floatalloc2(nzpad, nxpad);
	spx=sf_floatalloc2(nzpad, nxpad);
	svz=sf_floatalloc2(nzpad, nxpad);
	svx=sf_floatalloc2(nzpad, nxpad);
	gp =sf_floatalloc2(nzpad, nxpad);
	gpz=sf_floatalloc2(nzpad, nxpad);
	gpx=sf_floatalloc2(nzpad, nxpad);
	gvz=sf_floatalloc2(nzpad, nxpad);
	gvx=sf_floatalloc2(nzpad, nxpad);
	d1z=sf_floatalloc(nzpad);
	d2x=sf_floatalloc(nxpad);
	sxz=sf_intalloc(ns);
	gxz=sf_intalloc(ng);
	dcal=sf_floatalloc2(ng,nt);
	bndr=(float*)malloc(nt*8*(nx+nz)*sizeof(float));
	den=sf_floatalloc2(nz,nx);
	num=sf_floatalloc3(nz,nx,na);
	adcig=sf_floatalloc3(nz,nx,na);

	/* initialize variables */
	for(it=0;it<nt;it++){
		tmp=SF_PI*fm*(it*dt-1.0/fm);tmp*=tmp;
		wlt[it]=amp*(1.0-2.0*tmp)*expf(-tmp);
	}
	sf_floatread(v0[0],nz*nx,vmodl);
	expand2d(vv, v0);
	memset(sp [0],0,nzpad*nxpad*sizeof(float));
	memset(spx[0],0,nzpad*nxpad*sizeof(float));
	memset(spz[0],0,nzpad*nxpad*sizeof(float));
	memset(svx[0],0,nzpad*nxpad*sizeof(float));
	memset(svz[0],0,nzpad*nxpad*sizeof(float));
	memset(gp [0],0,nzpad*nxpad*sizeof(float));
	memset(gpx[0],0,nzpad*nxpad*sizeof(float));
	memset(gpz[0],0,nzpad*nxpad*sizeof(float));
	memset(gvx[0],0,nzpad*nxpad*sizeof(float));
	memset(gvz[0],0,nzpad*nxpad*sizeof(float));
	vmax=v0[0][0];
	for(i2=0; i2<nx; i2++)
	for(i1=0; i1<nz; i1++)
		vmax=SF_MAX(v0[i2][i1],vmax);
	pmlcoeff_init(d1z, d2x, vmax);
	if (!(sxbeg>=0 && szbeg>=0 && sxbeg+(ns-1)*jsx<nx && szbeg+(ns-1)*jsz<nz))	
	{ sf_error("sources exceeds the computing zone!"); exit(1);}
	sg_init(sxz, szbeg, sxbeg, jsz, jsx, ns);
	distx=sxbeg-gxbeg;
	distz=szbeg-gzbeg;
	if (csdgather)	{
		if (!(gxbeg>=0 && gzbeg>=0 && gxbeg+(ng-1)*jgx<nx && gzbeg+(ng-1)*jgz<nz &&
		(sxbeg+(ns-1)*jsx)+(ng-1)*jgx-distx <nx  && (szbeg+(ns-1)*jsz)+(ng-1)*jgz-distz <nz))	
		{ sf_error("geophones exceeds the computing zone!"); exit(1);}
	}else{
		if (!(gxbeg>=0 && gzbeg>=0 && gxbeg+(ng-1)*jgx<nx && gzbeg+(ng-1)*jgz<nz))	
		{ sf_error("geophones exceeds the computing zone!"); exit(1);}
	}
	sg_init(gxz, gzbeg, gxbeg, jgz, jgx, ng);
	memset(adcig[0][0], 0, na*nz*nx*sizeof(float));

	for(is=0; is<ns; is++)
	{
		wavefield_init(sp, spz, spx, svz, svx);
		if (csdgather)	{
			gxbeg=sxbeg+is*jsx-distx;
			sg_init(gxz, gzbeg, gxbeg, jgz, jgx, ng);
		}
		for(it=0; it<nt; it++)
		{
			add_source(&sxz[is], sp, 1, &wlt[it], true);
			step_forward(sp, spz, spx, svz, svx, vv, d1z, d2x);
			bndr_rw(false, svz, svx, &bndr[it*8*(nx+nz)]);
		
			record_seis(dcal[it], gxz, sp, ng);
			muting(dcal[it], gzbeg, szbeg, gxbeg, sxbeg+is*jsx, jgx, it, tdmute);
		}

		wavefield_init(gp, gpz, gpx, gvz, gvx);
		memset(num[0][0], 0, na*nz*nx*sizeof(float));
		memset(den[0], 0, nz*nx*sizeof(float));
		for(it=nt-1; it>-1; it--)
		{	
			add_source(gxz, gp, ng, dcal[it], true);
			step_forward(gp, gpz, gpx, gvz, gvx, vv, d1z, d2x);	

			if(it==kt)
			{
				window2d(v0,svx);
				sf_floatwrite(v0[0],nz*nx,vecx);
				window2d(v0,svz);
				sf_floatwrite(v0[0],nz*nx,vecz);
			}

			bndr_rw(true, svz, svx, &bndr[it*8*(nx+nz)]);	
			cross_correlation(num, den, sp, gp, svz, svx, gvz, gvx);

			step_backward(sp, svz, svx, vv);
			add_source(&sxz[is], sp, 1, &wlt[it], false);
		}	

		for(ia=0; ia<na; ia++)
		for(i2=0; i2<nx; i2++)
		for(i1=0; i1<nz; i1++)
			adcig[ia][i2][i1]+=num[ia][i2][i1]/(den[i2][i1]+SF_EPS);
	}
	sf_floatwrite(adcig[0][0], na*nz*nx,rtmadcig);

	free(wlt);
	free(*v0); free(v0);
	free(*vv); free(vv);
	free(*sp); free(sp);
	free(*spx); free(spx);
	free(*spz); free(spz);
	free(*svx); free(svx);
	free(*svz); free(svz);
	free(*gp); free(gp);
	free(*gpx); free(gpx);
	free(*gpz); free(gpz);
	free(*gvx); free(gvx);
	free(*gvz); free(gvz);
	free(d1z);
	free(d2x);
	free(sxz);
	free(gxz);
	free(bndr);
	free(*den); free(den);
	free(**num); free(*num); free(num);
	free(**adcig); free(*adcig); free(adcig);

    	exit(0);
}
void main()
{
	int i=10,j,k,N=24;
	tInt bias,scale;
	tLong frequency;
	tChar temp;
//	__bit test_resultA;

	FLG_CPL=0;
	lcd_init();
	display("Initializing...");
	enable_spi(0);
	dac_set(0);
	chip_init_CCFFE();
	pll_init();
	clearscr();
	enable_serial();
	display("Set Jumpers and ping");
	temp = receive_serial();
	clearscr();
	display("     CCFFE");
	line2();
	display("Throughput test");
	
	msDelay(1000);
	enable_serial();
	load_test_data();
	clearscr();
	display("Setting up test");
	line2();
	display("With 7 bit PRBS");
	scale = 2650/N;
	
	for(i=N;i>0;i--)
	{
		for(j=0;j<20;j++)
		{
			chip_init_CCFFE();
			sel_source(RING);
			bias=scale*i;
			dac_set(bias);
			msDelay(1000);			
			for(k=j;k>=0;k--)
			{
				tick_RX_RC_CKIN();
				msDelay(1);
			}
        	frequency = fmeasure();
        	clearscr();
        	display("f(");
			display_int(i);
			display(",");
        	display_int(j);
        	display(")=");
        	display_freq(frequency);
			write_test_data_CCFFE();
			LF_SELECT = 0;
			msDelay(1);
			LF_SELECT = 1;
			read_results_CCFFE();
			test_result = cross_correlation();//source_data);
			if(test_result)
			{
				FLG_CPL=1;
                send_byte(fm_byte[0]);
                send_byte(fm_byte[1]);
                send_byte(fm_byte[2]);
                send_int(i);
                send_byte(',');
                send_int(j);
			}
		}
	}
	

	
	clearscr();
	display("Throughput test");
	line2();
	if(FLG_CPL)
	display("SUCCESS");
	else
	display("Failed");
	while(1);
}
示例#4
0
文件: rtm.c 项目: conghui/rtm
int main(int argc, char ** argv){
	// Init Parameters.
	int nx = 1000;
	int nz = 1000;
	float dx = 10.f;
	float dz = 10.f;
	int nt = 100;
	float freq = 10.f;
	float dt = 0.002f;
	int sx = 0;
	int sz = 0;
	float * vel;
	float * wav;

	// Init Velocity model and Source Wavelet.
	int model_size = nx * nz;
	// wave velocity
	vel = (float*) malloc(sizeof(float) * model_size);
	wav = (float*) malloc(sizeof(float) * nt);
	int ix, iz;
	for (ix = 0; ix < nx; ix ++){
		for (iz = 0; iz < nz; iz ++){
			vel[ix * nz + iz] = 2000. * 2000. * dt * dt / dx / dx;
		}
	}
	ricker_wavelet(wav, nt, 60, dt, dx, freq);
	FILE * wav_file = fopen("Wavelet.bin", "w");
	fwrite(wav, sizeof(float), nt, wav_file);

	// Do Forward Modeling
	forward_propagate_2d(nx, nz, vel, wav, nt, dt, sx, sz);

	float *N_src_wave = (float *)malloc(sizeof(float) * model_size);
	// N minus 1
	float *Nm1_src_wave = (float *)malloc(sizeof(float) * model_size);
	// virtual source
	float *N_vsrc_wave = (float *)malloc(sizeof(float) * model_size);
	float *Nm1_vsrc_wave = (float *)malloc(sizeof(float) * model_size);

	int idx;
	for (idx = 0; idx < model_size; idx++) {
		N_src_wave[idx] = 0.f;
		Nm1_src_wave[idx] = 0.f;
		N_vsrc_wave[idx] = 0.f;
		Nm1_vsrc_wave[idx] = 0.f;
	}

	int time_step;
	float *image;
	image = (float*) malloc(sizeof(float) * model_size);

	for (time_step = nt - 1; time_step >= 0; time_step--) {

		if (!(time_step % 100))
			printf("In Backward Propagate, time step: %d\n", time_step);
		backward_propagate_onestep_2d(nx, nz, vel, wav, N_src_wave, Nm1_src_wave, nt, dt, sx, sz, time_step);
		if (!(time_step % 100))
			printf("In Receiver Propagate, time step: %d\n", time_step);
		receiver_propagate_onestep_2d(nx, nz, vel, wav, N_vsrc_wave, Nm1_vsrc_wave, nt, dt, sx, sz, time_step);

		cross_correlation(N_src_wave, N_vsrc_wave, image, model_size, 1.0);
	}

	free(N_src_wave);
	free(Nm1_src_wave);
	free(N_vsrc_wave);
	free(Nm1_vsrc_wave);
	return 0;
}