def main():
    # Load
    G = torch.from_numpy(np.load(os.path.join(
        data_folder, "F_niklas.npy"))).float().detach()
    grid = Grid.load(os.path.join(data_folder, "grid.pickle"))
    volcano_coords = torch.from_numpy(grid.cells).float().detach()

    # Define GP model.
    data_std = 0.1
    sigma0 = 1.0
    m0 = 2139.1
    lambda0 = 200.0

    ground_truth = torch.from_numpy(
        np.load(os.path.join(results_folder, "ground_truth.npy")))
    synth_data = torch.from_numpy(
        np.load(os.path.join(results_folder, "synth_data.npy")))

    # Now train GP model on it.
    myGP = InverseGaussianProcess(m0, sigma0, lambda0, volcano_coords, kernel)
    myGP.train(np.linspace(1.0, 2000, 20),
               G,
               synth_data,
               data_std,
               out_path=os.path.join(results_folder,
                                     "./train_res_matern52.pck"),
               n_epochs=2000,
               lr=0.5,
               n_chunks=80,
               n_flush=1)
Beispiel #2
0
def main():
    # Load static data.
    G = torch.from_numpy(
        np.load(os.path.join(data_folder,
                             "F_corrected_final.npy"))).float().detach()
    grid = Grid.load(os.path.join(data_folder, "grid.pickle"))
    volcano_coords = torch.from_numpy(grid.cells).float().detach()

    data_coords = torch.from_numpy(
        np.load(
            os.path.join(data_folder,
                         "niklas_data_coords_corrected_final.npy"))).float()
    data_values = torch.from_numpy(
        np.load(
            os.path.join(data_folder,
                         "niklas_data_obs_corrected_final.npy"))).float()

    data_std = 0.1
    sigma0_matern32 = 284.66
    m0_matern32 = 2139.1
    lambda0_matern32 = 651.58

    constant_updatable_gp = UpdatableGP(kernel,
                                        lambda0_matern32,
                                        sigma0_matern32,
                                        m0_matern32,
                                        volcano_coords,
                                        n_chunks=200)
    residuals = constant_updatable_gp.leave_1_out_residuals(
        G, data_values, data_std)
    np.save(residuals.numpy(),
            os.path.join(results_folder, "./loocv_niklas.pck"))
def main():
    grid = Grid.load(os.path.join(data_folder, "grid.pickle"))
    volcano_coords = grid.cells
    data_coords_surface = np.load(
        os.path.join(data_folder, "surface_data_coords.npy"))
    data_coords_niklas = np.load(
        os.path.join(data_folder, "niklas_data_coords.npy"))

    coast_coords = get_coast_coordinates(grid)

    threshold_small = 2600.0
    threshold_big = 2500.0

    for i in range(1, 6):
        ground_truth = torch.from_numpy(
            np.load(
                os.path.join(ground_truths_folder,
                             "prior_sample_{}.npy".format(i))))

        out_file_path = "excu_profile_small_{}".format(i)
        plot_excu_profile_with_data_revised(volcano_coords, data_coords_niklas,
                                            coast_coords, ground_truth,
                                            threshold_small, out_file_path)

        out_file_path = "excu_profile_big_{}".format(i)
        plot_excu_profile_with_data_revised(volcano_coords, data_coords_niklas,
                                            coast_coords, ground_truth,
                                            threshold_big, out_file_path)
def main():
    grid = Grid.load(os.path.join(data_folder, "grid.pickle"))
    volcano_coords = grid.cells
    data_coords_surface = np.load(
        os.path.join(data_folder, "surface_data_coords.npy"))
    data_coords_niklas = np.load(
        os.path.join(data_folder, "niklas_data_coords.npy"))
    surface_coords = np.load(
        os.path.join(data_folder, "surface_data_coords.npy"))

    coast_coords = get_coast_coordinates(grid)

    threshold = 2500.0

    def process_sample(sample_nr):
        ground_truth = torch.from_numpy(
            np.load(
                os.path.join(ground_truths_folder,
                             "prior_sample_{}.npy".format(sample_nr))))

        visited_inds = np.load(
            os.path.join(
                os.path.join(base_results_folder,
                             "sample_{}/".format(sample_nr)),
                "visited_inds.npy"))
        visited_coords = surface_coords[visited_inds, :]
        out_file_path = "excu_big_with_visited_inds_sample_{}".format(
            sample_nr)
        plot_excu_profile_with_visited_inds(volcano_coords, data_coords_niklas,
                                            visited_coords, coast_coords,
                                            ground_truth, threshold,
                                            out_file_path)

    for sample_nr in range(1, 6):
        process_sample(sample_nr)
def main():
    # Load
    grid = Grid.load(os.path.join(data_folder,
                    "grid.pickle"))
    volcano_coords = grid.cells
    data_coords = np.load(os.path.join(data_folder,"surface_data_coords.npy"))
    ground_truth = np.load("./ground_truth.npy")
    data_values = np.load(os.path.join(data_folder, "post_data_sample.npy"))
    surface_coords = grid.surface

    # Interpolate surface on regular grid.
    X_surface_mesh, Y_surface_mesh, Z_surface_mesh = point_cloud_to_2D_regular_grid(
            surface_coords, n_grid=300)

    density_structured_grid = underground_point_cloud_to_structured_grid(
                    volcano_coords, ground_truth, surface_coords,
                    n_grid=50, fill_offset=1, fill_value=-1e6)

    # Threshold to only plot one region.
    vals[vals > 500] = 0
    vals[vals < 0] = 0

    
    mlab.surf(X_surface_mesh, Y_surface_mesh, Z_surface_mesh, opacity=0.35)
    d = mlab.pipeline.add_dataset(density_structured_grid)
    iso = mlab.pipeline.iso_surface(d)
    mlab.show()
def main():
    grid = Grid.load(os.path.join(data_folder, "grid.pickle"))
    volcano_coords = grid.cells
    data_coords_surface = np.load(
        os.path.join(data_folder, "surface_data_coords.npy"))
    data_coords_niklas = np.load(
        os.path.join(data_folder, "niklas_data_coords.npy"))

    # Center the coordinates.
    X1 = data_coords_niklas[:, 0]
    Y1 = data_coords_niklas[:, 1]
    Z1 = data_coords_niklas[:, 2]

    # Center the separations and scale to meters.
    X1_centred = 111 * 1e3 * (1e-5 * (X1 - np.min(X1)))
    Y1_centred = 111 * 1e3 * (1e-5 * (Y1 - np.min(Y1)))

    volcano_X = 111 * 1e3 * (
        1e-5 * (volcano_coords[:, 0] - np.min(volcano_coords[:, 0])))
    volcano_Y = 111 * 1e3 * (
        1e-5 * (volcano_coords[:, 1] - np.min(volcano_coords[:, 1])))
    volcano_Z = volcano_coords[:, 2]

    # Same, but centred compared to volano.
    X1_centred_b = 111 * 1e3 * (1e-5 * (X1 - np.min(volcano_coords[:, 0])))
    Y1_centred_b = 111 * 1e3 * (1e-5 * (Y1 - np.min(volcano_coords[:, 1])))

    # Prepare figure layout.
    plt.rc('xtick', labelsize=5)
    plt.rc('ytick', labelsize=5)
    fig = plt.figure()
    widths = [1, 1]
    heights = [1, 1, 1, 1]
    gs = fig.add_gridspec(ncols=2,
                          nrows=4,
                          width_ratios=widths,
                          height_ratios=heights)

    f_ax1 = fig.add_subplot(gs[:, 0])
    f_ax2 = fig.add_subplot(gs[1:2, 1])
    f_ax3 = fig.add_subplot(gs[2:3, 1])

    f_ax1.scatter(X1_centred, Y1_centred, c=Z1, cmap=cmap, linewidth=0.2, s=1)
    f_ax1.set_aspect('equal')
    f_ax1.tick_params(axis='both', which='major', pad=0.1)

    f_ax2.scatter(X1_centred, Z1, c=Z1, cmap=cmap, linewidth=0.2, s=1)
    f_ax2.set_aspect(1.5)
    f_ax2.tick_params(axis='both', which='major', pad=0.1)

    f_ax3.scatter(Y1_centred, Z1, c=Z1, cmap=cmap, linewidth=0.2, s=1)
    f_ax3.set_aspect(1.5)
    f_ax3.tick_params(axis='both', which='major', pad=0.1)

    plt.savefig("niklas_data_overview",
                bbox_inches="tight",
                pad_inches=0.1,
                dpi=400)
Beispiel #7
0
def main():
    os.makedirs(output_path, exist_ok=True)

    # Load
    F = torch.from_numpy(
        np.load(os.path.join(data_folder,
                             "F_full_surface.npy"))).float().detach()
    grid = Grid.load(os.path.join(data_folder, "grid.pickle"))
    volcano_coords = torch.from_numpy(grid.cells).float().detach()

    data_coords = torch.from_numpy(
        np.load(os.path.join(data_folder, "surface_data_coords.npy"))).float()

    ground_truth = torch.from_numpy(
        np.load(os.path.join(data_folder, "post_sample.npy")))
    data_values = torch.from_numpy(
        np.load(os.path.join(data_folder, "post_data_sample.npy")))

    # Dictionary between the original Niklas data and our discretization.
    niklas_data_inds = torch.from_numpy(
        np.load(os.path.join(data_folder,
                             "niklas_data_inds_insurf.npy"))).long()
    niklas_coords = data_coords[niklas_data_inds].numpy()

    # PATHS ON THE VOLCANO.
    from volcapy.data_preparation.paths import paths as paths_niklas
    # Convert to indices in the full dataset.
    paths = []
    for path in paths_niklas:
        paths.append(niklas_data_inds[path].long())

    # --------------------------------
    # DEFINITION OF THE EXCURSION SET.
    # --------------------------------
    THRESHOLD_low = 700.0
    excursion_inds = (ground_truth >= THRESHOLD_low).nonzero()[:, 0]

    # Load results.
    visited_inds = np.load("visited_inds.npy")
    observed_data = np.load("observed_data.npy")

    # Plot situation.
    plt.scatter(data_coords[:, 0], data_coords[:, 1], c="k", alpha=0.1)

    plt.scatter(volcano_coords[excursion_inds, 0],
                volcano_coords[excursion_inds, 1],
                c="r",
                alpha=0.07)

    # plt.scatter(niklas_coords[:, 0], niklas_coords[:, 1],
    #         c=niklas_coords[:, 2])
    plt.scatter(data_coords[visited_inds, 0],
                data_coords[visited_inds, 1],
                c="g")

    plt.title("Visited locations on the Stromboli and excursion set.")
    plt.show()
    """
def main():
    os.makedirs(output_path, exist_ok=True)

    # Load
    F = torch.from_numpy(
        np.load(os.path.join(data_folder,
                             "F_full_surface.npy"))).float().detach()
    grid = Grid.load(os.path.join(data_folder, "grid.pickle"))
    volcano_coords = torch.from_numpy(grid.cells).float().detach()

    data_coords = torch.from_numpy(
        np.load(os.path.join(data_folder, "surface_data_coords.npy"))).float()

    ground_truth = torch.from_numpy(
        np.load(os.path.join(data_folder, "post_sample.npy")))
    data_values = torch.from_numpy(
        np.load(os.path.join(data_folder, "post_data_sample.npy")))

    # Dictionary between the original Niklas data and our discretization.
    niklas_data_inds = torch.from_numpy(
        np.load(os.path.join(data_folder,
                             "niklas_data_inds_insurf.npy"))).long()
    niklas_coords = data_coords[niklas_data_inds].numpy()

    # --------------------------------
    # DEFINITION OF THE EXCURSION SET.
    # --------------------------------
    THRESHOLD_low = 700.0
    excursion_inds = (ground_truth >= THRESHOLD_low).nonzero()[:, 0]

    # Params
    data_std = 0.1
    # lambda0 = 338.0
    lambda0 = 338.46
    sigma0 = 359.49
    m0 = -114.40

    # Define GP model.
    data_feed = lambda x: data_values[x]
    updatable_gp = UpdatableGP(cl,
                               lambda0,
                               sigma0,
                               m0,
                               volcano_coords,
                               n_chunks=80)

    for i, current_ind in enumerate(niklas_data_inds):
        y = data_feed(current_ind)
        G = F[current_ind, :].reshape(1, -1)
        updatable_gp.update(G, y, data_std)

        # Extract variance and coverage function.
        coverage = updatable_gp.coverage(THRESHOLD_low, None)

        # Save.
        np.save(os.path.join(output_path, "coverage_{}.npy".format(i)),
                coverage)
def main():
    os.makedirs(output_path, exist_ok=True)

    # Load
    F = torch.from_numpy(
        np.load(os.path.join(data_folder,
                             "F_full_surface.npy"))).float().detach()
    grid = Grid.load(os.path.join(data_folder, "grid.pickle"))
    volcano_coords = torch.from_numpy(grid.cells).float().detach()

    data_coords = torch.from_numpy(
        np.load(os.path.join(data_folder, "surface_data_coords.npy"))).float()

    ground_truth = torch.from_numpy(
        np.load(os.path.join(data_folder, "post_sample.npy")))
    data_values = torch.from_numpy(
        np.load(os.path.join(data_folder, "post_data_sample.npy")))

    # Dictionary between the original Niklas data and our discretization.
    niklas_data_inds = torch.from_numpy(
        np.load(os.path.join(data_folder,
                             "niklas_data_inds_insurf.npy"))).long()
    niklas_coords = data_coords[niklas_data_inds].numpy()

    # --------------------------------
    # DEFINITION OF THE EXCURSION SET.
    # --------------------------------
    THRESHOLD_low = 700.0
    excursion_inds = (ground_truth >= THRESHOLD_low).nonzero()[:, 0]

    # Params
    data_std = 0.1
    # lambda0 = 338.0
    lambda0 = 338.46
    sigma0 = 359.49
    m0 = -114.40

    # Define GP model.
    data_feed = lambda x: data_values[x]
    updatable_gp = UpdatableGP(cl,
                               lambda0,
                               sigma0,
                               m0,
                               volcano_coords,
                               n_chunks=80)

    # Asimilate myopic data collection plan.
    visited_inds = np.load(os.path.join(results_folder, "visited_inds.npy"))
    observed_data = np.load(os.path.join(results_folder, "visited_inds.npy"))

    n_chunks = 80
    for i, inds in enumerate(np.array_split(visited_inds, n_chunks)):
        print("Processing chunk {} / {}".format(i, n_chunks))
        y = data_feed(inds)
        G_current = F[inds, :]
        updatable_gp.update(G_current, y, data_std)
Beispiel #10
0
def main(sample_nr):
    ground_truth_path = os.path.join(
        data_folder, "prior_samples_v2/prior_sample_{}.npy".format(sample_nr))
    ground_truth = np.load(ground_truth_path)

    grid = Grid.load(os.path.join(data_folder, "grid.pickle"))
    volcano_coords = torch.from_numpy(grid.cells).float().detach()

    irregular_array_to_point_cloud(volcano_coords.numpy(),
                                   ground_truth,
                                   "ground_truth_{}.vtk".format(sample_nr),
                                   fill_nan_val=-20000.0)
def main():
    # Load
    G = torch.from_numpy(
            np.load(os.path.join(data_folder, "F_niklas.npy"))).float().detach()
    grid = Grid.load(os.path.join(data_folder,
                    "grid.pickle"))
    volcano_coords = torch.from_numpy(
            grid.cells).float().detach()

    # Optimal hyperparameters.
    data_std = 0.1
    sigma0 = 2.968352
    lambda0 = 207.8275

    ground_truth = torch.from_numpy(np.load(os.path.join(results_folder, "ground_truth.npy")))
    synth_data = torch.from_numpy(
            np.load(os.path.join(results_folder, "synth_data.npy")))

    # Build trends: constant cylindrical.
    x0 = volcano_coords[:, 0].mean() # Volcano center.
    y0 = volcano_coords[:, 1].mean()
    z0 = volcano_coords[:, 2].mean()
    coeff_F = torch.hstack([
        torch.ones(volcano_coords.shape[0], 1),
        cylindrical(
            volcano_coords,
            x0, y0).reshape(-1, 1)
        ]).float()

    # Now fit GP model
    updatable_gp = UniversalUpdatableGP(kernel, lambda0, torch.tensor([sigma0]),
            volcano_coords,
            coeff_F, coeff_cov="uniform", coeff_mean="uniform",
            n_chunks=200)

    # Compute cross-validation matrix.
    K_tilde = updatable_gp.compute_cv_matrix(G, synth_data, data_std=0.2)
    np.save(os.path.join(results_folder, "K_tilde.npy"),
            K_tilde.cpu().numpy())

    # Compute posterior mean.
    updatable_gp.update_uniform(G, synth_data, data_std)
    np.save(os.path.join(results_folder, "post_mean_universal.npy"),
            updatable_gp.post_mean.cpu().numpy())

    np.save(os.path.join(results_folder, "coeff_post_mean.npy"),
            updatable_gp.coeff_post_mean.cpu().numpy())

    variance = updatable_gp.covariance.extract_variance()
    np.save(os.path.join(results_folder, "variance_universal.npy"),
            variance.cpu().numpy())

    """
Beispiel #12
0
def main():
    # Load
    data_folder = "/home/cedric/PHD/Dev/VolcapySIAM/data/InversionDatas/stromboli_40357_cells"
    F = torch.from_numpy(
            np.load(os.path.join(data_folder, "F_niklas.npy"))).float().detach()

    F = torch.from_numpy(
            np.load(os.path.join(data_folder, "F_niklas_corr.npy"))).float().detach()

    grid = Grid.load(os.path.join(data_folder,
                    "grid.pickle"))
    volcano_coords = torch.from_numpy(
            grid.cells).float().detach()

    data_coords = torch.from_numpy(
            np.load(os.path.join(data_folder,"niklas_data_coords.npy"))).float()
    data_values = torch.from_numpy(
            np.load(os.path.join(data_folder,"niklas_data_obs.npy"))).float()

    print("Size of inversion grid: {} cells.".format(volcano_coords.shape[0]))
    print("Number of datapoints: {}.".format(data_coords.shape[0]))
    size = data_coords.shape[0]*volcano_coords.shape[0]*4 / 1e9
    cov_size = (volcano_coords.shape[0])**2 * 4 / 1e9
    print("Size of Covariance matrix: {} GB.".format(cov_size))
    print("Size of Pushforward matrix: {} GB.".format(size))

    # HYPERPARAMETERS
    data_std = 0.1
    sigma0 = 221.6
    m0 = 2133.8
    lambda0 = 462.0

    # Run inversion in one go to compare.
    import volcapy.covariance.exponential as kernel
    start = timer()
    myGP = InverseGaussianProcess(m0, sigma0, lambda0,
            volcano_coords, kernel,
            logger=logger)

    cov_pushfwd = cl.compute_cov_pushforward(
            lambda0, F, volcano_coords, n_chunks=20,
            n_flush=50)
    
    m_post_m, m_post_d = myGP.condition_model(F, data_values, data_std,
            concentrate=False,
            is_precomp_pushfwd=False)

    end = timer()
    print("Non-sequential inversion run in {} s.".format(end - start))

    # Train.
    myGP.train_fixed_lambda(200.0, F, data_values, data_std)
def main():
    # Load
    data_folder = "/home/cedric/PHD/Dev/VolcapySIAM/data/InversionDatas/stromboli_23823_cells"
    F = torch.from_numpy(np.load(os.path.join(
        data_folder, "F_niklas.npy"))).float().detach()

    grid = Grid.load(os.path.join(data_folder, "grid.pickle"))
    volcano_coords = torch.from_numpy(grid.cells).float().detach()

    data_coords = torch.from_numpy(
        np.load(os.path.join(data_folder, "niklas_data_coords.npy"))).float()
    data_values = torch.from_numpy(
        np.load(os.path.join(data_folder, "niklas_data_obs.npy"))).float()

    print("Size of inversion grid: {} cells.".format(volcano_coords.shape[0]))
    print("Number of datapoints: {}.".format(data_coords.shape[0]))
    size = data_coords.shape[0] * volcano_coords.shape[0] * 4 / 1e9
    cov_size = (volcano_coords.shape[0])**2 * 4 / 1e9
    print("Size of Covariance matrix: {} GB.".format(cov_size))
    print("Size of Pushforward matrix: {} GB.".format(size))

    # HYPERPARAMETERS
    data_std = 0.1
    sigma0 = 100.6
    m0 = 1000.0
    lambda0 = 300.0

    start = timer()
    myGP = InverseGaussianProcess(m0,
                                  sigma0,
                                  lambda0,
                                  volcano_coords,
                                  kernel,
                                  logger=logger)

    m_post_m, m_post_d = myGP.condition_model(F,
                                              data_values,
                                              data_std,
                                              concentrate=False,
                                              is_precomp_pushfwd=False)

    end = timer()
    print("Non-sequential inversion run in {} s.".format(end - start))

    # Train.
    myGP.train(np.linspace(20, 1400, 14),
               F,
               data_values,
               data_std,
               out_path="./train_res.pck",
               n_chunks=2,
               n_flush=50)
Beispiel #14
0
def main():
    # Load
    G = torch.from_numpy(
            np.load(os.path.join(data_folder, "F_full_surface.npy"))).float().detach()
    grid = Grid.load(os.path.join(data_folder,
                    "grid.pickle"))
    volcano_coords = torch.from_numpy(grid.cells).float().detach()

    data_coords = torch.from_numpy(
            np.load(os.path.join(data_folder,"surface_data_coords.npy"))).float()

    ground_truth = torch.from_numpy(np.load(ground_truth_path))

    # Dictionary between the original Niklas data and our discretization.
    niklas_data_inds = torch.from_numpy(
            np.load(os.path.join(data_folder, "niklas_data_inds_insurf.npy"))).long()
    niklas_coords = data_coords[niklas_data_inds].numpy()


    # --------------------------------
    # DEFINITION OF THE EXCURSION SET.
    # --------------------------------
    THRESHOLD_low = 700.0
    excursion_inds = (ground_truth >= THRESHOLD_low).nonzero()[:, 0]

    # Load results.
    visited_inds_IVR = np.load(os.path.join(
            results_folder_IVR, "visited_inds.npy"))
    visited_inds_wIVR = np.load(os.path.join(
            results_folder_wIVR, "visited_inds.npy"))

    # Observation operators.
    # G_stacked_IVR = G[visited_inds_IVR, :]
    G_stacked_wIVR = G[visited_inds_wIVR, :]

    # Reload the GPs.
    # gpIVR = UpdatableGP.load(os.path.join(results_folder_IVR, "gp_state.pkl"))
    # gpwIVR = UpdatableGP.load(os.path.join(results_folder_wIVR, "gp_state.pkl"))
    gpINFILL = UpdatableGP.load(os.path.join(results_folder_INFILL, "gp_state.pkl"))

    # Produce posterior realization.
    for reskrig_sample_nr in range(300, 400):
        prior_realization = torch.from_numpy(np.load(
                os.path.join(reskrig_samples_folder,
                        "prior_sample_{}.npy".format(reskrig_sample_nr))))
        myReal = UpdatableRealization.bootstrap(prior_realization, G_stacked_wIVR,
                data_std=0.1, gp_module=gpINFILL)
        np.save(
                os.path.join(results_folder_wIVR,
                    "Cond_Reals_Infill/conditional_real_{}.npy".format(reskrig_sample_nr)),
                myReal._realization.detach().cpu().numpy())
def main():
    # Load
    G = torch.from_numpy(np.load(os.path.join(
        data_folder, "F_niklas.npy"))).float().detach()
    grid = Grid.load(os.path.join(data_folder, "grid.pickle"))
    volcano_coords = torch.from_numpy(grid.cells).float().detach()
    data_coords = np.load(os.path.join(data_folder, "niklas_data_coords.npy"))

    data_std = 0.1
    ground_truth = torch.from_numpy(
        np.load(os.path.join(results_folder, "ground_truth.npy")))
    synth_data = torch.from_numpy(
        np.load(os.path.join(results_folder, "synth_data.npy")))

    # Build trends: constant cylindrical.
    x0 = volcano_coords[:, 0].mean()  # Volcano center.
    y0 = volcano_coords[:, 1].mean()
    z0 = volcano_coords[:, 2].mean()
    coeff_F = torch.hstack([
        torch.ones(volcano_coords.shape[0], 1),
        cylindrical(volcano_coords, x0, y0).reshape(-1, 1)
    ]).float()

    # Define GP model with arbitrary parameters (we will train them anyway).
    lambda0, sigma0 = 10, 2
    updatable_gp = UniversalUpdatableGP(kernel,
                                        lambda0,
                                        sigma0,
                                        volcano_coords,
                                        coeff_F,
                                        coeff_cov="uniform",
                                        coeff_mean="uniform",
                                        n_chunks=200)

    # Train cross-validation.
    lambda0s = np.linspace(0.2, 1000, 50)
    sigma0s = np.linspace(0.1, 100, 50)

    # Compute folds via kMeans.
    k = 10  # number of clusters.
    folds = kMeans_folds(k, data_coords)
    updatable_gp.train_cv_criterion(
        lambda0s,
        sigma0s,
        G,
        synth_data,
        data_std,
        criterion="k fold",
        folds=folds,
        out_path=os.path.join(results_folder,
                              "./{}_fold_kMeans_residuals.pck".format(k)))
Beispiel #16
0
def main():
    # Load
    G = torch.from_numpy(np.load(os.path.join(
        data_folder, "F_niklas.npy"))).float().detach()
    grid = Grid.load(os.path.join(data_folder, "grid.pickle"))
    volcano_coords = torch.from_numpy(grid.cells).float().detach()

    # Define GP model.
    data_std = 0.1
    sigma0 = 1.0
    m0 = 2139.1
    lambda0 = 200.0

    # Build trends: constant cylindrical.
    x0 = volcano_coords[:, 0].mean()  # Volcano center.
    y0 = volcano_coords[:, 1].mean()
    z0 = volcano_coords[:, 2].mean()

    coeff_mean = torch.tensor([m0, 0.01]).reshape(-1, 1).float()
    coeff_cov = torch.tensor([[200.0, 0], [0, 0.05]]).float()
    coeff_F = torch.hstack([
        torch.ones(volcano_coords.shape[0], 1),
        cylindrical(volcano_coords, x0, y0).reshape(-1, 1)
    ]).float()

    # Model with trend.
    updatable_gp = UniversalUpdatableGP(kernel,
                                        lambda0,
                                        torch.tensor([sigma0]),
                                        volcano_coords,
                                        coeff_F,
                                        coeff_cov,
                                        coeff_mean,
                                        n_chunks=200)

    ground_truth = torch.from_numpy(
        np.load(os.path.join(results_folder, "ground_truth.npy")))
    synth_data = torch.from_numpy(
        np.load(os.path.join(results_folder, "synth_data.npy")))
    lambda0s = np.linspace(1.0, 3000, 30)
    kappa_s = np.linspace(1e-5, 1, 30)

    updatable_gp.train(lambda0s,
                       kappa_s,
                       G,
                       synth_data,
                       out_path=os.path.join(results_folder,
                                             "./train_res_universal.pck"))
Beispiel #17
0
def main():
    # Create output directory.
    output_folder = os.path.join(base_folder, "./train_res.pck")

    # Load static data.
    F = torch.from_numpy(
        np.load(os.path.join(data_folder,
                             "F_corrected_final.npy"))).float().detach()
    grid = Grid.load(os.path.join(data_folder, "grid.pickle"))
    volcano_coords = torch.from_numpy(grid.cells).float().detach()

    data_coords = torch.from_numpy(
        np.load(
            os.path.join(data_folder,
                         "niklas_data_coords_corrected_final.npy"))).float()
    data_values = torch.from_numpy(
        np.load(
            os.path.join(data_folder,
                         "niklas_data_obs_corrected_final.npy"))).float()

    print("Size of inversion grid: {} cells.".format(volcano_coords.shape[0]))
    print("Number of datapoints: {}.".format(data_coords.shape[0]))
    size = data_coords.shape[0] * volcano_coords.shape[0] * 4 / 1e9
    cov_size = (volcano_coords.shape[0])**2 * 4 / 1e9
    print("Size of Covariance matrix: {} GB.".format(cov_size))
    print("Size of Pushforward matrix: {} GB.".format(size))

    # HYPERPARAMETERS to start search from.
    data_std = 0.1
    sigma0 = 340.0
    m0 = 561.0
    lambda0 = 50.0

    myGP = InverseGaussianProcess(m0, sigma0, lambda0, volcano_coords, kernel)

    # Train.
    myGP.train(np.linspace(50.0, 1450, 30),
               F,
               data_values,
               data_std,
               out_path="./train_res.pck",
               n_epochs=3000,
               lr=0.5,
               n_chunks=80,
               n_flush=1)
Beispiel #18
0
def main():
    # Load
    G = torch.from_numpy(np.load(os.path.join(
        data_folder, "F_niklas.npy"))).float().detach()
    grid = Grid.load(os.path.join(data_folder, "grid.pickle"))
    volcano_coords = torch.from_numpy(grid.cells).float().detach()
    data_coords = np.load(os.path.join(data_folder, "niklas_data_coords.npy"))

    k = 10
    kmeans = KMeans(init="random",
                    n_clusters=k,
                    n_init=10,
                    max_iter=300,
                    random_state=42)
    kmeans.fit(data_coords)

    # Plot clusters.
    import matplotlib.pyplot as plt
    plt.scatter(x=data_coords[:, 0], y=data_coords[:, 1], c=kmeans.labels_)
    plt.show()
Beispiel #19
0
def main():
    # Load static data.
    F = torch.from_numpy(
        np.load(os.path.join(data_folder,
                             "F_full_surface.npy"))).float().detach()
    grid = Grid.load(os.path.join(data_folder, "grid.pickle"))
    volcano_coords = torch.from_numpy(grid.cells).float().detach()
    data_coords = torch.from_numpy(
        np.load(os.path.join(data_folder, "surface_data_coords.npy"))).float()

    # Load generated data.
    ground_truth = torch.from_numpy(np.load(ground_truth_path))

    # --------------------------------
    # DEFINITION OF THE EXCURSION SET.
    # --------------------------------
    THRESHOLD_low = 700.0

    # Choose a starting points on the coast.
    start_ind = 4478

    # -------------------------------------
    # Define GP model.
    # -------------------------------------
    data_std = 0.1
    lambda0 = 338.46
    sigma0 = 359.49
    m0 = -114.40

    # Prepare data.
    data_values = F @ ground_truth

    data_feed = lambda x: data_values[x]
    updatable_gp = UpdatableGP(cl,
                               lambda0,
                               sigma0,
                               m0,
                               volcano_coords,
                               n_chunks=200)

    updatable_gp.update(F[1].reshape(1, -1), data_values[1], 0.1)
def sample_posterior_strategy(strategy_folder, sample_nr, prior_sample_folder,
                              static_data_folder, n_samples):
    # Load static data.
    # Load static data.
    F = torch.from_numpy(
        np.load(os.path.join(static_data_folder,
                             "F_full_surface.npy"))).float().detach()
    grid = Grid.load(os.path.join(static_data_folder, "grid.pickle"))
    volcano_coords = torch.from_numpy(grid.cells).float().detach()

    # Create GP (trained Matern 32).
    data_std = 0.1
    sigma0_matern32 = 284.66
    m0_matern32 = 2139.1
    lambda0_matern32 = 651.58

    myGP = InverseGaussianProcess(m0_matern32,
                                  sigma0_matern32,
                                  lambda0_matern32,
                                  volcano_coords,
                                  kernel,
                                  n_chunks=200,
                                  n_flush=50)

    current_folder = os.path.join(strategy_folder,
                                  "sample_{}/".format(sample_nr))
    post_sample_folder = os.path.join(current_folder, "post_samples/")
    os.makedirs(post_sample_folder, exist_ok=True)

    # Load observed data.
    visited_inds = np.load(os.path.join(current_folder,
                                        "visited_inds.npy")).flatten()
    observed_data = torch.from_numpy(
        np.load(os.path.join(current_folder,
                             "observed_data.npy")).flatten().reshape(-1, 1))
    G = F[visited_inds, :]

    sample_posterior(myGP, n_samples, prior_sample_folder, G, observed_data,
                     data_std, post_sample_folder)
Beispiel #21
0
def main():
    # Load volcano geometry.
    data_folder = "/home/cedric/PHD/Dev/VolcapySIAM/reporting/variance_extraction_benchmark/stromboli_51023_cells"
    grid = Grid.load(os.path.join(data_folder, "grid.pickle"))
    volcano_coords = grid.cells

    # Activate auto-wrapping of numpy arrays as rpy2 objects.
    numpy2ri.activate()

    # Import the R RandomFields library.
    rflib = importr("RandomFields")

    # Create the model and sample.
    model = rflib.RMexp(var=3, scale=5)
    simu = rflib.RFsimulate(model, volcano_coords)

    # Back to numpy.
    sample = np.asarray(simu.slots['data']).astype(np.float32)

    irregular_array_to_point_cloud(volcano_coords,
                                   sample,
                                   "sample.vtk",
                                   fill_nan_val=-20000.0)
Beispiel #22
0
    def discretize_in_n(n):
        """ Discretize the geometry at a given lengthscale, 
        here specifiec by the number of cells along each direction of the
        horizontal plane.
    
        """
        nx = n
        ny = n
        # Regrid.
        x, step_x = np.linspace(x_min, x_max, nx, endpoint=True, retstep=True)
        y, step_y = np.linspace(y_min, y_max, ny, endpoint=True, retstep=True)
        print("Step x {}".format(step_x))
        print("Step y {}".format(step_y))

        # Set the same resolution for z.
        z_step = float(np.mean([step_x, step_y]))
        print("Step z {}".format(z_step))

        # Find z by getting closest cell in fine grid.
        tree_x = KDTree(dsm_x)
        tree_y = KDTree(dsm_y)
        _, inds_x = tree_x.query(x[:, None])
        _, inds_y = tree_y.query(y[:, None])

        # Remesh the z-s.
        a, b = np.meshgrid(inds_x, inds_y)
        z = dsm_z[a, b]
        print("Minimal altitude {}".format(np.min(z)))

        my_grid = Grid.build_grid(x, y, z, z_low=-1600, z_step=z_step)
        print("Grid with {} cells.".format(my_grid.shape[0]))
        print(my_grid.res_x)
        print(my_grid.res_y)
        print(my_grid.res_z)

        # Return mean resolution and total number of cells.
        return my_grid.shape[0], np.mean(np.array([step_x, step_y, z_step]))
Beispiel #23
0
def sample_prior(input_path, output_path, n_realizations):
    os.makedirs(output_path, exist_ok=True)

    # Load
    grid = Grid.load(os.path.join(input_path,
                    "grid.pickle"))
    volcano_coords = torch.from_numpy(
            grid.cells).float().detach()

    # HYPERPARAMETERS.
    data_std = 0.1

    sigma0_exp = 308.89 # WARNING: Old values.
    m0_exp = 535.39
    lambda0_exp = 1925.0

    sigma0_matern32 = 284.66
    m0_matern32 = 2139.1
    lambda0_matern32 = 651.58

    sigma0_matern52 = 258.40
    m0_matern52 = 2120.93
    lambda0_matern52 = 441.05

    myGP = InverseGaussianProcess(m0_matern32, sigma0_matern32,
            lambda0_matern32,
            volcano_coords, kernel,
            n_chunks=70, n_flush=50)

    for i in range(500, 500 + n_realizations):
        start = timer()
        prior_sample = myGP.sample_prior()
        end = timer()

        print("Prior sampling run in {}s.".format(end - start))
        np.save(os.path.join(output_path, "prior_sample_{}.npy".format(i)),
                prior_sample.detach().cpu().numpy())
def main():

    # Load
    F = torch.from_numpy(
            np.load(os.path.join(data_folder, "F_full_surface.npy"))).float().detach()
    grid = Grid.load(os.path.join(data_folder,
                    "grid.pickle"))
    volcano_coords = torch.from_numpy(grid.cells).float().detach()

    data_coords = torch.from_numpy(
            np.load(os.path.join(data_folder,"surface_data_coords.npy"))).float()

    ground_truth = torch.from_numpy(np.load(ground_truth_path))

    # Dictionary between the original Niklas data and our discretization.
    niklas_data_inds = torch.from_numpy(
            np.load(os.path.join(data_folder, "niklas_data_inds_insurf.npy"))).long()
    niklas_coords = data_coords[niklas_data_inds].numpy()


    # --------------------------------
    # DEFINITION OF THE EXCURSION SET.
    # --------------------------------
    THRESHOLD_low = 700.0
    excursion_inds = (ground_truth >= THRESHOLD_low).nonzero()[:, 0]

    # Load results.
    visited_inds_IVR = np.load(os.path.join(
            results_folder_IVR, "visited_inds.npy"))
    visited_inds_wIVR = np.load(os.path.join(
            results_folder_wIVR, "visited_inds.npy"))

    def compute_mismatch(coverage):
        # -------------------------------------------------
        # -------------------------------------------------
        # Find the Vorob'ev threshold.
        vorobev_volume = np.sum(coverage)
        def f(x):
            return (np.abs(np.sum(coverage > x) - vorobev_volume))

        from scipy.optimize import minimize
        vorobev_threshold = minimize(f, 0.5, method='nelder-mead',
                               options={'xatol': 1e-3, 'disp': True}).x
        print("Vorob'ev threshold: {}.".format(vorobev_threshold))

        # Plot estimated excursion set using coverage function.
        est_excursion_inds = coverage > vorobev_threshold

        print("Vorobe'v volume: {}.".format(vorobev_volume))
        print("Current estimate volume: {}.".format(np.sum(est_excursion_inds)))

        # Compute mismatch.
        mismatch = np.zeros(volcano_coords.shape[0])
        mismatch[est_excursion_inds] = 1
        tmp = np.zeros(volcano_coords.shape[0])
        tmp[excursion_inds] = 2
        mismatch = mismatch + tmp

        excu_size = excursion_inds.shape[0] + 1
        p_false_pos = 100 * np.sum(mismatch == 1) / excu_size
        p_false_neg = 100 * np.sum(mismatch == 2) / excu_size
        p_correct = 100 * np.sum(mismatch == 3) / excu_size

        return (p_false_pos, p_false_neg, p_correct)

    mismatches_IVR = []
    mismatches_wIVR = []
    mismatches_static = []

    # Number of static datapoints.
    n_static = 542
    for i in range(1, n_static):
        coverage_static = np.load(
                os.path.join(
                        static_results_folder,
                        "coverage_{}.npy".format(i)))
        mismatches_static.append(compute_mismatch(coverage_static))

    for i in range(1, visited_inds_IVR.shape[0]):
        coverage_IVR = np.load(
                os.path.join(
                        results_folder_IVR,
                        "coverage_{}.npy".format(i)))
        mismatches_IVR.append(compute_mismatch(coverage_IVR))

    for i in range(1, visited_inds_wIVR.shape[0]):
        coverage_wIVR = np.load(
                os.path.join(
                        results_folder_wIVR,
                        "coverage_{}.npy".format(i)))
        mismatches_wIVR.append(compute_mismatch(coverage_wIVR))

    mismatches_IVR = np.array(mismatches_IVR)
    mismatches_wIVR = np.array(mismatches_wIVR)
    mismatches_static = np.array(mismatches_static)

    plt.plot(list(range(1, visited_inds_IVR.shape[0])), mismatches_IVR[:,0],
            label="false positives, IVR strategy",
            color="blue", linestyle="dashed")
    plt.plot(list(range(1, visited_inds_IVR.shape[0])), mismatches_IVR[:,1],
            label="false negatives, IVR strategy",
            color="red", linestyle="dashed")
    plt.plot(list(range(1, visited_inds_IVR.shape[0])), mismatches_IVR[:,2],
            label="correct prediction, IVR strategy",
            color="green", linestyle="dashed")

    plt.plot(list(range(1, visited_inds_wIVR.shape[0])), mismatches_wIVR[:,0],
            label="false positives, weighted IVR strategy",
            color="cornflowerblue", linestyle="solid")
    plt.plot(list(range(1, visited_inds_wIVR.shape[0])), mismatches_wIVR[:,1],
            label="false negatives, weighted IVR strategy",
            color="lightcoral", linestyle="solid")
    plt.plot(list(range(1, visited_inds_wIVR.shape[0])), mismatches_wIVR[:,2],
            label="correct prediction, weighted IVR strategy",
            color="lightgreen", linestyle="solid") 

    # Add the surface fill coverage.
    coverage_fill = np.load(os.path.join(
            infill_folder, "coverage_surface_fill.npy"))
    mismatch_fill = compute_mismatch(coverage_fill)

    # Size of the limiting horizontal line corresponding to the infill
    # strategy.
    n = 600

    plt.plot(list(range(1, n)), np.repeat(mismatch_fill[0], n-1),
            label="false positives, surface fill",
            color="cornflowerblue", linestyle="dotted")
    plt.plot(list(range(1, n)), np.repeat(mismatch_fill[1], n-1),
            label="false negatives, surface fill",
            color="lightcoral", linestyle="dotted")
    plt.plot(list(range(1, n)), np.repeat(mismatch_fill[2], n-1),
            label="correct prediction, surface fill",
            color="lightgreen", linestyle="dotted") 
    
    plt.xlim([1, 500]) 
    plt.legend()
    plt.xlabel("Number of observations")
    plt.ylabel("Size in percent of true excursion size")
    plt.savefig("mismatch_evolution_bigstep", bbox_inches="tight", pad_inches=0.1, dpi=600)
    plt.show()
Beispiel #25
0
def main(sample_nr):
    post_sample_path = os.path.join(
        ground_truth_folder,
        "post_samples/post_sample_{}.npy".format(sample_nr))
    post_data_sample_path = os.path.join(
        ground_truth_folder,
        "post_data_samples/post_data_sample_{}.npy".format(sample_nr))

    output_path = os.path.join(output_folder,
                               "INFILL_results/sample_{}".format(sample_nr))
    os.makedirs(output_path, exist_ok=True)
    save_gp_state_path = os.path.join(output_path, "gp_state.pkl")

    # Load
    F = torch.from_numpy(
        np.load(os.path.join(data_folder,
                             "F_full_surface.npy"))).float().detach()
    grid = Grid.load(os.path.join(data_folder, "grid.pickle"))
    volcano_coords = torch.from_numpy(grid.cells).float().detach()

    data_coords = torch.from_numpy(
        np.load(os.path.join(data_folder, "surface_data_coords.npy"))).float()

    ground_truth = torch.from_numpy(np.load(post_sample_path))
    data_values = torch.from_numpy(np.load(post_data_sample_path))

    # Dictionary between the original Niklas data and our discretization.
    niklas_data_inds = torch.from_numpy(
        np.load(os.path.join(data_folder,
                             "niklas_data_inds_insurf.npy"))).long()
    niklas_coords = data_coords[niklas_data_inds].numpy()

    # --------------------------------
    # DEFINITION OF THE EXCURSION SET.
    # --------------------------------
    THRESHOLD_low = 700.0
    excursion_inds = (ground_truth >= THRESHOLD_low).nonzero()[:, 0]

    # Coast data.
    coast_data_inds_infull = niklas_data_inds[coast_data_inds]

    # Choose a starting points on the coast.
    start_ind = coast_data_inds_infull[0]

    # Params
    data_std = 0.1
    # lambda0 = 338.0
    lambda0 = 338.46
    sigma0 = 359.49
    m0 = -114.40

    # Define GP model.
    data_feed = lambda x: data_values[x]
    updatable_gp = UpdatableGP(cl,
                               lambda0,
                               sigma0,
                               m0,
                               volcano_coords,
                               n_chunks=80)
    from volcapy.strategy.infill import InfillStrategy
    strategy = InfillStrategy(
        updatable_gp,
        data_coords,
        F,
        data_feed,
        lower=THRESHOLD_low,
        upper=None,
    )

    start = timer()
    visited_inds, observed_data, ivrs = strategy.run(
        start_ind,
        n_steps=2000,
        data_std=0.1,
        output_folder=output_path,
        save_coverage=True,
        max_step=310.0,
        save_gp_state_path=save_gp_state_path)

    end = timer()
    print("Run in {} mins.".format((end - start) / 60))

    np.save(os.path.join(output_path, "visited_inds.npy"), visited_inds)
    np.save(os.path.join(output_path, "observed_data.npy"), observed_data)
    np.save(os.path.join(output_path, "ivrs.npy"), ivrs)
def main(sample_nr):
    # Create output directory.
    output_folder = os.path.join(base_folder,
                                 "wIVR_final_big/sample_{}".format(sample_nr))
    os.makedirs(output_folder, exist_ok=True)

    # Load static data.
    F = torch.from_numpy(
        np.load(os.path.join(data_folder,
                             "F_full_surface.npy"))).float().detach()
    grid = Grid.load(os.path.join(data_folder, "grid.pickle"))
    volcano_coords = torch.from_numpy(grid.cells).float().detach()
    data_coords = torch.from_numpy(
        np.load(os.path.join(data_folder, "surface_data_coords.npy"))).float()

    # Load generated data.
    ground_truth_path = os.path.join(ground_truth_folder,
                                     "prior_sample_{}.npy".format(sample_nr))
    ground_truth = torch.from_numpy(np.load(ground_truth_path))

    # Load prior realizations.
    N_REALIZATIONS = 100
    prior_realizations = []
    for i in range(100, 100 + N_REALIZATIONS):
        realization_path = os.path.join(ground_truth_folder,
                                        "prior_sample_{}.npy".format(i))
        prior_realizations.append(torch.from_numpy(np.load(realization_path)))

    # --------------------------------
    # DEFINITION OF THE EXCURSION SET.
    # --------------------------------
    THRESHOLD_low = 2500.0

    # Choose a starting points on the coast.
    start_ind = 4478

    # -------------------------------------
    # Define GP model.
    # -------------------------------------
    data_std = 0.1
    sigma0_matern32 = 284.66
    m0_matern32 = 2139.1
    lambda0_matern32 = 651.58

    # Prepare data.
    data_values = F @ ground_truth
    data_feed = lambda x: data_values[x]

    updatable_gp = UpdatableGP(cl,
                               lambda0_matern32,
                               sigma0_matern32,
                               m0_matern32,
                               volcano_coords,
                               n_chunks=200)

    # -------------------------------------
    strategy = ConservativeStrategy(updatable_gp,
                                    data_coords,
                                    F,
                                    data_feed,
                                    lower=THRESHOLD_low,
                                    upper=None,
                                    prior_realizations=prior_realizations)

    # Run strategy.
    visited_inds, observed_data = strategy.run(start_ind,
                                               n_steps=4000,
                                               data_std=0.1,
                                               max_step=151.0,
                                               min_step=60.0,
                                               output_folder=output_folder)
Beispiel #27
0
def prepare_stromboli(input_path, output_path, z_step):
    dsm_x = np.load(os.path.join(input_path, "dsm_stromboli_x.npy"))
    dsm_y = np.load(os.path.join(input_path, "dsm_stromboli_y.npy"))
    dsm_z = np.load(os.path.join(input_path, "dsm_stromboli_z.npy"))

    my_grid = Grid.build_grid(dsm_x, dsm_y, dsm_z, z_low=-800, z_step=z_step)
    my_grid.save(os.path.join(output_path, "grid.pickle"))
    print("Grid with {} cells.".format(my_grid.shape[0]))

    # Name the output directory with the number of cells.
    dir_name = "stromboli_{}_cells".format(my_grid.shape[0])
    output_path = os.path.join(output_path, dir_name)
    os.makedirs(output_path, exist_ok=True)

    # Determines which cells lie deep inside the volcano (i.e. away from the
    # surface).
    # This is useful when using IVR to select new datapoints, since we are mostly
    # interested at variance reduction deep below the surface.
    DEPTH_THRESHOLD = 150.0  # Only keep cells at least that far from the surface.
    surface_tree = KDTree(my_grid.surface)

    # Loop over cells and only keep the ones that are far away from the surface.
    deep_cells_inds = []
    for i, cell in enumerate(my_grid.cells):
        print("Processing cell {}/{}".format(i, my_grid.cells.shape[0]))
        d, _ = surface_tree.query(cell)
        if d > DEPTH_THRESHOLD:
            deep_cells_inds.append(i)

    print("There are {} surface cells.".format(my_grid.surface.shape[0]))
    print("Kept {}/{} cells".format(len(deep_cells_inds),
                                    my_grid.cells.shape[0]))

    np.save(os.path.join(output_path, "deep_cells_inds.npy"),
            np.array(deep_cells_inds, dtype=np.int32))

    # Put measurement stations on the whole surface, at 1 meter from the ground.
    # First only keep cells that are outside the water.
    data_coords = np.array([x for x in my_grid.surface if x[2] > 0.0])
    print(("There are {} surface cells above sea level. " +
           "Placing potential observation " +
           "sites on each of those..").format(data_coords.shape[0]))
    data_coords[:, 2] = data_coords[:, 2] + 1.0

    # Also load locations of Niklas data points.
    from volcapy.loading import load_niklas
    niklas_data = load_niklas(ORIGINAL_NIKLAS_DATA_PATH)
    niklas_data_coords = np.array(niklas_data["data_coords"])[1:]
    niklas_data_values = np.array(niklas_data["d"])

    # Find the indices of the closest data points to Niklas data.
    # This may be used to mitigate the difference between the two in case there
    # are a lot of difference in altitude because of the discretization.
    tree_surf_data = KDTree(data_coords)
    _, inds_niklas_in_surface = tree_surf_data.query(niklas_data_coords)
    niklas_data_coords_insurf = data_coords[inds_niklas_in_surface]
    np.save(os.path.join(output_path, "niklas_data_inds_insurf.npy"),
            inds_niklas_in_surface)

    # Save location of data points before computing forward.
    # Save the surface of the volcano and the datapoints. in vtk.
    from volcapy.plotting.vtkutils import irregular_array_to_point_cloud, array_to_vector_cloud
    irregular_array_to_point_cloud(my_grid.surface,
                                   np.ones(my_grid.surface.shape[0]),
                                   os.path.join(output_path, "surface.vtk"),
                                   fill_nan_val=-20000.0)

    orientation_data = np.zeros((data_coords.shape[0], 3))
    orientation_data[:, 2] = -1.0
    array_to_vector_cloud(data_coords, orientation_data,
                          os.path.join(output_path, "data_points.vtk"))

    orientation_data = np.zeros((niklas_data_coords.shape[0], 3))
    orientation_data[:, 2] = -1.0
    orientation_data_vals = np.zeros((niklas_data_coords.shape[0], 3))
    orientation_data_vals[:, 2] = niklas_data_values
    array_to_vector_cloud(niklas_data_coords, orientation_data,
                          os.path.join(output_path, "niklas_data_coords.vtk"))
    array_to_vector_cloud(
        niklas_data_coords_insurf, orientation_data,
        os.path.join(output_path, "niklas_data_coords_insurf.vtk"))
    array_to_vector_cloud(niklas_data_coords, orientation_data_vals,
                          os.path.join(output_path, "niklas_data_vals.vtk"))

    # ----------------------------------------------------------------------

    # Also compute forward for Niklas data.
    # TODO: WARNING!!! There is one too many data site. Here remove the first, but
    # maybe its the last who should be removed.
    ref_coords = np.array(niklas_data["data_coords"][0])[None, :]

    # TODO: Verify this. According to Niklas, we should subtract the response on
    # the reference station. Assuming this is the first data site, then, from every
    # line, we should subract the first line.
    F_ref_station = compute_forward(my_grid.cells,
                                    my_grid.cells_roof,
                                    my_grid.res_x,
                                    my_grid.res_y,
                                    my_grid.res_z,
                                    ref_coords,
                                    n_procs=4)

    F_niklas = compute_forward(my_grid.cells,
                               my_grid.cells_roof,
                               my_grid.res_x,
                               my_grid.res_y,
                               my_grid.res_z,
                               niklas_data_coords,
                               n_procs=4)

    # Subtract the first station.
    F_niklas_corr = F_niklas - np.repeat(
        F_ref_station, F_niklas.shape[0], axis=0)

    np.save(os.path.join(output_path, "F_niklas.npy"), F_niklas)
    np.save(os.path.join(output_path, "F_niklas_corr.npy"), F_niklas_corr[1:])
    np.save(os.path.join(output_path, "niklas_data_coords.npy"),
            niklas_data_coords[1:, :])
    np.save(os.path.join(output_path, "niklas_data_obs.npy"),
            niklas_data['d'][1:])

    # Compute forward on whole surface.
    F_full_surface = compute_forward(my_grid.cells,
                                     my_grid.cells_roof,
                                     my_grid.res_x,
                                     my_grid.res_y,
                                     my_grid.res_z,
                                     data_coords,
                                     n_procs=4)

    # Save everything, but cut first observation.
    np.save(os.path.join(output_path, "surface_data_coords.npy"), data_coords)
    np.save(os.path.join(output_path, "F_full_surface.npy"), F_full_surface)
def prepare_groundtruth(data_path, prior_sample_path, post_sample_path,
                        post_data_sample_path):
    """ Given a realization from the prior, compute the corresponding
    conditional realization by updating.

    Parameters
    ----------
    data_path: string
        Path to the static data defining the situation (grid, forward, ...).
    prior_sample_path: string
        Path ta a realization from the prior.
    post_sample_path: float
        Where to save the computed posterior realization.
    post_data_sample_path: string
        Where to save the computed posterior realization of the data.

    """
    # Load
    F = torch.from_numpy(np.load(os.path.join(
        data_path, "F_niklas.npy"))).float().detach()
    F_full = torch.from_numpy(
        np.load(os.path.join(data_path,
                             "F_full_surface.npy"))).float().detach()

    grid = Grid.load(os.path.join(data_path, "grid.pickle"))
    volcano_coords = torch.from_numpy(grid.cells).float().detach()

    data_coords = torch.from_numpy(
        np.load(os.path.join(data_path, "niklas_data_coords.npy"))).float()
    data_coords_full = torch.from_numpy(
        np.load(os.path.join(data_path, "surface_data_coords.npy"))).float()
    data_values = torch.from_numpy(
        np.load(os.path.join(data_path, "niklas_data_obs.npy"))).float()

    print("Size of inversion grid: {} cells.".format(volcano_coords.shape[0]))
    print("Number of datapoints: {}.".format(data_coords.shape[0]))
    size = data_coords.shape[0] * volcano_coords.shape[0] * 4 / 1e9
    cov_size = (volcano_coords.shape[0])**2 * 4 / 1e9
    print("Size of Covariance matrix: {} GB.".format(cov_size))
    print("Size of Pushforward matrix: {} GB.".format(size))

    prior_sample = torch.from_numpy(np.load(prior_sample_path)).float()

    # HYPERPARAMETERS, small volcano.
    data_std = 0.1
    sigma0 = 359.49
    m0 = -114.40
    lambda0 = 338.46

    myGP = InverseGaussianProcess(m0,
                                  sigma0,
                                  lambda0,
                                  volcano_coords,
                                  kernel,
                                  logger=logger)

    start = timer()

    post_sample = myGP.update_sample(prior_sample, F, data_values, data_std)

    end = timer()
    print("Sample updating run in {}s.".format(end - start))

    np.save(post_sample_path, post_sample.detach().cpu().numpy())

    post_data_sample = F_full @ post_sample
    np.save(post_data_sample_path, post_data_sample.detach().cpu().numpy())
Beispiel #29
0
def main():
    # Load
    data_folder = "/home/cedric/PHD/Dev/VolcapySIAM/reporting/input_data"
    F = torch.from_numpy(np.load(os.path.join(
        data_folder, "F_niklas.npy"))).float().detach()
    grid = Grid.load(os.path.join(data_folder, "grid.pickle"))
    volcano_coords = torch.from_numpy(grid.cells).float().detach()

    data_coords = torch.from_numpy(
        np.load(os.path.join(data_folder, "niklas_data_coords.npy"))).float()
    data_values = torch.from_numpy(
        np.load(os.path.join(data_folder, "niklas_data_obs.npy"))).float()

    # Subdivide for variance reduction computation.
    part_ind = 60
    F_rest = F[part_ind:, :]
    F = F[:part_ind, :]

    data_coords_part = data_coords[part_ind:, :]
    data_coords = data_coords[:part_ind, :]

    data_values = data_values[:part_ind]

    print("Size of inversion grid: {} cells.".format(volcano_coords.shape[0]))
    print("Number of datapoints: {}.".format(data_coords.shape[0]))
    size = data_coords.shape[0] * volcano_coords.shape[0] * 8 / 1e9
    print("Size of Pushforward matrix: {} GB.".format(size))

    # Params
    data_std = 0.1
    lambda0 = 200.0
    sigma0 = 200.0
    m0 = 1300

    start = timer()

    # Now ready to go to updatable covariance.
    from volcapy.update.updatable_covariance import UpdatableCovariance
    updatable_cov = UpdatableCovariance(cl, lambda0, sigma0, volcano_coords)

    from volcapy.update.updatable_covariance import UpdatableMean
    updatable_mean = UpdatableMean(m0 * torch.ones(volcano_coords.shape[0]),
                                   updatable_cov)

    n_chunks = 5
    # Loop over measurement chunks.
    for i, (F_i, data_part) in enumerate(
            zip(torch.chunk(F, chunks=n_chunks, dim=0),
                torch.chunk(data_values, chunks=n_chunks, dim=0))):
        print("Processing data chunk nr {}.".format(i))
        updatable_cov.update(F_i, data_std)
        updatable_mean.update(data_part, F_i)
        m = updatable_mean.m.cpu().numpy()
        np.save("m_post_{}_stromboli.npy".format(i), m)

        irregular_array_to_point_cloud(volcano_coords.numpy(),
                                       m,
                                       "m_post_{}_stromboli.vtk".format(i),
                                       fill_nan_val=-20000.0)

    end = timer()
    print("Sequential inversion run in {} s.".format(end - start))

    # Save the variance.
    variances = updatable_cov.extract_variance()
    irregular_array_to_point_cloud(volcano_coords.numpy(),
                                   variances.detach().cpu().numpy(),
                                   "variances_stromboli.vtk",
                                   fill_nan_val=-20000.0)

    # Save the coordinates of the observation points for later plotting.
    # The point data will be used for glyph orientation when plotting.
    orientation_data = np.zeros((data_coords.shape[0], 3))
    orientation_data[:, 2] = -1.0

    # Add an offset for easier visualization.
    data_coords[:, 2] = data_coords[:, 2] + 50.0
    array_to_vector_cloud(data_coords.numpy(), orientation_data,
                          "data_points_in_IVR.vtk")

    IVRs = []
    # Now compute the variance reduction associated to the other points.
    for i, F_i in enumerate(F_rest):
        IVR = updatable_cov.compute_IVR(F_i.reshape(1, -1), data_std)
        print(IVR)
        IVRs.append(IVR)

        # Save periodically.
        if i % 15 == 0:
            print("Saving at {}.".format(i))
            np.save("IVRs.npy", np.array(IVRs))

    np.save("IVRs.npy", np.array(IVRs))
    data_coords_part[:, 2] = data_coords_part[:, 2] + 50.0
    np.save("data_coords_IVR.npy", data_coords_part)
    # Add an offset for easier visualization.
    _array_to_point_cloud(data_coords_part.numpy(), np.array(IVRs), "IVRs.vtk")
    """
Beispiel #30
0
# General torch settings and devices.
torch.set_num_threads(8)
gpu = torch.device('cuda:0')
cpu = torch.device('cpu')

# ------------------------------------------------------
# Load Niklas Data
# ------------------------------------------------------
# Dimension of the response.
# F = np.load("/home/cedric/PHD/Dev/VolcapySIAM/reporting/F_niklas.npy")
F = np.load("/home/cedric/PHD/Dev/VolcapySIAM/reporting/F.npy")
F = torch.as_tensor(F).float()
d_obs = np.load(
    "/home/cedric/PHD/Dev/VolcapySIAM/reporting/niklas_data_obs.npy")
grid = Grid.load("/home/cedric/PHD/Dev/VolcapySIAM/reporting/grid.pickle")
cells_coords = grid.cells

# Careful: we have to make a column vector here.
data_std = 0.1
d_obs = torch.as_tensor(d_obs)[:, None]
n_data = d_obs.shape[0]
data_cov = torch.eye(n_data)
cells_coords = torch.as_tensor(cells_coords).detach()

# HYPERPARAMETERS
sigma0_init = 221.6
m0 = 2133.8
lambda0 = 462.0

# ------------------------------------------------------