static GPtrArray* calculate_all_grain_values(GwyDataField *dfield, GwyDataField *mask, guint *ngrains, gint **grains) { GwyGrainValue **gvalues; guint xres = dfield->xres, yres = dfield->yres, n, i; GwyInventory *inventory; GPtrArray *valuedata; *grains = g_new0(gint, xres*yres); *ngrains = gwy_data_field_number_grains(mask, *grains); inventory = gwy_grain_values(); n = gwy_inventory_get_n_items(inventory); valuedata = g_ptr_array_new(); g_ptr_array_set_size(valuedata, n); gvalues = g_new(GwyGrainValue*, n); for (i = 0; i < n; i++) { gvalues[i] = gwy_inventory_get_nth_item(inventory, i); g_ptr_array_index(valuedata, i) = g_new(gdouble, *ngrains + 1); } gwy_grain_values_calculate(n, gvalues, (gdouble**)valuedata->pdata, dfield, *ngrains, *grains); g_free(gvalues); return valuedata; }
static void grain_cross(GwyContainer *data, GwyRunType run) { GwySIUnit *siunitxy, *siunitz; GrainCrossArgs args; GwyDataField *dfield; GwyDataField *mfield; gint id; g_return_if_fail(run & CROSS_RUN_MODES); grain_cross_load_args(gwy_app_settings_get(), &args); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, GWY_APP_DATA_FIELD_ID, &id, GWY_APP_MASK_FIELD, &mfield, 0); g_return_if_fail(dfield && mfield); siunitxy = gwy_data_field_get_si_unit_xy(dfield); siunitz = gwy_data_field_get_si_unit_z(dfield); args.units_equal = gwy_si_unit_equal(siunitxy, siunitz); if (!args.units_equal) { GwyGrainValue *abscissa, *ordinate; GwyGrainValueFlags aflags, oflags; abscissa = gwy_grain_values_get_grain_value(args.abscissa); ordinate = gwy_grain_values_get_grain_value(args.ordinate); aflags = gwy_grain_value_get_flags(abscissa); oflags = gwy_grain_value_get_flags(ordinate); if ((aflags | oflags) & GWY_GRAIN_VALUE_SAME_UNITS) { if (run == GWY_RUN_IMMEDIATE) { require_same_units_dialog(data, id); return; } if (aflags & GWY_GRAIN_VALUE_SAME_UNITS) { args.abscissa = grain_cross_defaults.abscissa; args.abscissa_expanded = grain_cross_defaults.abscissa_expanded; } if (oflags & GWY_GRAIN_VALUE_SAME_UNITS) { args.ordinate = grain_cross_defaults.ordinate; args.ordinate_expanded = grain_cross_defaults.ordinate_expanded; } } } args.grains = g_new0(gint, mfield->xres*mfield->yres); args.ngrains = gwy_data_field_number_grains(mfield, args.grains); if (run == GWY_RUN_IMMEDIATE) grain_cross_run(&args, data, dfield); else { if (grain_cross_dialog(&args, dfield)) grain_cross_run(&args, data, dfield); grain_cross_save_args(gwy_app_settings_get(), &args); } g_free(args.grains); }
static void grain_dist_run(GrainDistArgs *args, GwyContainer *data, GwyDataField *dfield, GwyDataField *mfield) { GrainDistExportData expdata; gint *grains; guint i, bits; gint res, ngrains; grains = g_new0(gint, gwy_data_field_get_xres(mfield) *gwy_data_field_get_yres(mfield)); ngrains = gwy_data_field_number_grains(mfield, grains); switch (args->mode) { case MODE_GRAPH: res = args->fixres ? args->resolution : 0; bits = args->selected & args->bitmask; for (i = 0; bits; i++, bits /= 2) { if (bits & 1) add_one_distribution(data, dfield, ngrains, grains, i, res); } break; case MODE_RAW: expdata.args = args; expdata.dfield = dfield; expdata.ngrains = ngrains; expdata.grains = grains; gwy_save_auxiliary_with_callback(_("Export Raw Grain Values"), NULL, grain_dist_export_create, (GwySaveAuxiliaryDestroy)g_free, &expdata); break; default: g_assert_not_reached(); break; } g_free(grains); }
static void grain_stat(GwyContainer *data, GwyRunType run) { GtkWidget *dialog, *table, *hbox, *button; GwyDataField *dfield, *mfield; GwySIUnit *siunit, *siunit2; GwySIValueFormat *vf, *vf2; gint xres, yres, ngrains; gdouble total_area, area, size, vol_0, vol_min, vol_laplace, bound_len, v; gdouble *values = NULL; gint *grains; GString *str, *str2; GPtrArray *report; const guchar *title; gchar *key, *value; gint row, id; guint i, maxlen; g_return_if_fail(run & STAT_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, GWY_APP_MASK_FIELD, &mfield, GWY_APP_DATA_FIELD_ID, &id, 0); g_return_if_fail(dfield); g_return_if_fail(mfield); report = g_ptr_array_sized_new(20); if (gwy_container_gis_string_by_name(data, "/filename", &title)) { g_ptr_array_add(report, _("File:")); g_ptr_array_add(report, g_strdup(title)); } key = g_strdup_printf("/%d/data/title", id); if (gwy_container_gis_string_by_name(data, key, &title)) { g_ptr_array_add(report, _("Data channel:")); g_ptr_array_add(report, g_strdup(title)); } g_free(key); /* Make empty line in the report */ g_ptr_array_add(report, NULL); g_ptr_array_add(report, NULL); xres = gwy_data_field_get_xres(mfield); yres = gwy_data_field_get_yres(mfield); total_area = gwy_data_field_get_xreal(dfield) *gwy_data_field_get_yreal(dfield); grains = g_new0(gint, xres*yres); ngrains = gwy_data_field_number_grains(mfield, grains); area = grains_get_total_value(dfield, ngrains, grains, &values, GWY_GRAIN_VALUE_PROJECTED_AREA); size = grains_get_total_value(dfield, ngrains, grains, &values, GWY_GRAIN_VALUE_EQUIV_SQUARE_SIDE); vol_0 = grains_get_total_value(dfield, ngrains, grains, &values, GWY_GRAIN_VALUE_VOLUME_0); vol_min = grains_get_total_value(dfield, ngrains, grains, &values, GWY_GRAIN_VALUE_VOLUME_MIN); vol_laplace = grains_get_total_value(dfield, ngrains, grains, &values, GWY_GRAIN_VALUE_VOLUME_LAPLACE); bound_len = grains_get_total_value(dfield, ngrains, grains, &values, GWY_GRAIN_VALUE_FLAT_BOUNDARY_LENGTH); g_free(values); g_free(grains); dialog = gtk_dialog_new_with_buttons(_("Grain Statistics"), NULL, 0, GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL); gwy_help_add_to_proc_dialog(GTK_DIALOG(dialog), GWY_HELP_DEFAULT); table = gtk_table_new(10, 2, FALSE); gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), table); gtk_container_set_border_width(GTK_CONTAINER(table), 4); row = 0; str = g_string_new(NULL); str2 = g_string_new(NULL); g_string_printf(str, "%d", ngrains); add_report_row(GTK_TABLE(table), &row, _("Number of grains:"), str->str, str->str, report); siunit = gwy_data_field_get_si_unit_xy(dfield); siunit2 = gwy_si_unit_power(siunit, 2, NULL); v = area; vf = gwy_si_unit_get_format_with_digits(siunit2, GWY_SI_UNIT_FORMAT_VFMARKUP, v, 3, NULL); vf2 = gwy_si_unit_get_format_with_digits(siunit2, GWY_SI_UNIT_FORMAT_PLAIN, v, 3, NULL); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); g_string_printf(str2, "%.*f %s", vf2->precision, v/vf2->magnitude, vf2->units); add_report_row(GTK_TABLE(table), &row, _("Total projected area (abs.):"), str->str, str2->str, report); g_string_printf(str, "%.2f %%", 100.0*area/total_area); add_report_row(GTK_TABLE(table), &row, _("Total projected area (rel.):"), str->str, str->str, report); v = area/ngrains; gwy_si_unit_get_format_with_digits(siunit2, GWY_SI_UNIT_FORMAT_VFMARKUP, v, 3, vf); gwy_si_unit_get_format_with_digits(siunit2, GWY_SI_UNIT_FORMAT_PLAIN, v, 3, vf2); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); g_string_printf(str2, "%.*f %s", vf2->precision, v/vf2->magnitude, vf2->units); add_report_row(GTK_TABLE(table), &row, _("Mean grain area:"), str->str, str2->str, report); v = size/ngrains; gwy_si_unit_get_format_with_digits(siunit, GWY_SI_UNIT_FORMAT_VFMARKUP, v, 3, vf); gwy_si_unit_get_format_with_digits(siunit, GWY_SI_UNIT_FORMAT_PLAIN, v, 3, vf2); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); g_string_printf(str2, "%.*f %s", vf2->precision, v/vf2->magnitude, vf2->units); add_report_row(GTK_TABLE(table), &row, _("Mean grain size:"), str->str, str2->str, report); siunit = gwy_data_field_get_si_unit_z(dfield); gwy_si_unit_multiply(siunit2, siunit, siunit2); v = vol_0; gwy_si_unit_get_format_with_digits(siunit2, GWY_SI_UNIT_FORMAT_VFMARKUP, v, 3, vf); gwy_si_unit_get_format_with_digits(siunit2, GWY_SI_UNIT_FORMAT_PLAIN, v, 3, vf2); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); g_string_printf(str2, "%.*f %s", vf2->precision, v/vf2->magnitude, vf2->units); add_report_row(GTK_TABLE(table), &row, _("Total grain volume (zero):"), str->str, str2->str, report); v = vol_min; gwy_si_unit_get_format_with_digits(siunit2, GWY_SI_UNIT_FORMAT_VFMARKUP, v, 3, vf); gwy_si_unit_get_format_with_digits(siunit2, GWY_SI_UNIT_FORMAT_PLAIN, v, 3, vf2); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); g_string_printf(str2, "%.*f %s", vf2->precision, v/vf2->magnitude, vf2->units); add_report_row(GTK_TABLE(table), &row, _("Total grain volume (minimum):"), str->str, str2->str, report); v = vol_laplace; gwy_si_unit_get_format_with_digits(siunit2, GWY_SI_UNIT_FORMAT_VFMARKUP, v, 3, vf); gwy_si_unit_get_format_with_digits(siunit2, GWY_SI_UNIT_FORMAT_PLAIN, v, 3, vf2); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); g_string_printf(str2, "%.*f %s", vf2->precision, v/vf2->magnitude, vf2->units); add_report_row(GTK_TABLE(table), &row, _("Total grain volume (laplacian):"), str->str, str2->str, report); v = bound_len; gwy_si_unit_get_format_with_digits(siunit, GWY_SI_UNIT_FORMAT_VFMARKUP, v, 3, vf); gwy_si_unit_get_format_with_digits(siunit, GWY_SI_UNIT_FORMAT_PLAIN, v, 3, vf2); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); g_string_printf(str2, "%.*f %s", vf2->precision, v/vf2->magnitude, vf2->units); add_report_row(GTK_TABLE(table), &row, _("Total projected boundary length:"), str->str, str2->str, report); gwy_si_unit_value_format_free(vf2); gwy_si_unit_value_format_free(vf); g_object_unref(siunit2); maxlen = 0; for (i = 0; i < report->len/2; i++) { key = (gchar*)g_ptr_array_index(report, 2*i); if (key) maxlen = MAX(strlen(key), maxlen); } g_string_truncate(str, 0); g_string_append(str, _("Grain Statistics")); g_string_append(str, "\n\n"); for (i = 0; i < report->len/2; i++) { key = (gchar*)g_ptr_array_index(report, 2*i); if (key) { value = (gchar*)g_ptr_array_index(report, 2*i + 1); g_string_append_printf(str, "%-*s %s\n", maxlen+1, key, value); g_free(value); } else g_string_append_c(str, '\n'); } g_ptr_array_free(report, TRUE); g_object_set_data(G_OBJECT(dialog), "report", str->str); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 0); button = grain_stats_add_aux_button(hbox, GTK_STOCK_SAVE, _("Save table to a file")); g_signal_connect_swapped(button, "clicked", G_CALLBACK(grain_stat_save), dialog); button = grain_stats_add_aux_button(hbox, GTK_STOCK_COPY, _("Copy table to clipboard")); g_signal_connect_swapped(button, "clicked", G_CALLBACK(grain_stat_copy), dialog); gtk_widget_show_all(dialog); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); g_string_free(str2, TRUE); g_string_free(str, TRUE); }
static gboolean stats(GwyContainer *data, GwyRunType run) { GtkWidget *dialog, *table, *label; GwyDataField *dfield; GwySIUnit *siunit, *siunit2; GwySIValueFormat *vf; gint i, xres, yres, ngrains, npix; gdouble area, v; GString *str; gint *grains; gint row; g_return_val_if_fail(run & DIST_RUN_MODES, FALSE); g_return_val_if_fail(gwy_container_contains_by_name(data, "/0/mask"), FALSE); dfield = GWY_DATA_FIELD(gwy_container_get_object_by_name(data, "/0/mask")); xres = gwy_data_field_get_xres(dfield); yres = gwy_data_field_get_yres(dfield); area = gwy_data_field_get_xreal(dfield)*gwy_data_field_get_yreal(dfield); grains = g_new0(gint, xres*yres); ngrains = gwy_data_field_number_grains(dfield, grains); npix = 0; for (i = 0; i < xres*yres; i++) npix += (grains[i] != 0); g_free(grains); dialog = gtk_dialog_new_with_buttons(_("Grain Statistics"), NULL, 0, GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL); gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE); g_signal_connect(dialog, "response", G_CALLBACK(gtk_widget_destroy), NULL); table = gtk_table_new(4, 2, FALSE); gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), table); gtk_container_set_border_width(GTK_CONTAINER(table), 4); row = 0; str = g_string_new(""); label = gtk_label_new(_("Number of grains:")); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_FILL, 0, 2, 2); g_string_printf(str, "%d", ngrains); label = gtk_label_new(str->str); gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 1, 2, row, row+1, GTK_FILL, 0, 2, 2); row++; /* FIXME: simplify with 2.x unit methods */ siunit = gwy_data_field_get_si_unit_xy(dfield); siunit2 = GWY_SI_UNIT(gwy_si_unit_new("")); gwy_si_unit_multiply(siunit, siunit, siunit2); label = gtk_label_new(_("Total projected area (abs.):")); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_FILL, 0, 2, 2); v = npix*area/(xres*yres); vf = gwy_si_unit_get_format(siunit2, v, NULL); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); label = gtk_label_new(NULL); gtk_label_set_markup(GTK_LABEL(label), str->str); gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 1, 2, row, row+1, GTK_FILL, 0, 2, 2); row++; label = gtk_label_new(_("Total projected area (rel.):")); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0); gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_FILL, 0, 2, 2); g_string_printf(str, "%.2f %%", 100.0*npix/(xres*yres)); label = gtk_label_new(str->str); gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 1, 2, row, row+1, GTK_FILL, 0, 2, 2); row++; label = gtk_label_new(_("Mean grain area:")); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_FILL, 0, 2, 2); v = npix*area/(ngrains*xres*yres); gwy_si_unit_get_format(siunit2, v, vf); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); label = gtk_label_new(NULL); gtk_label_set_markup(GTK_LABEL(label), str->str); gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 1, 2, row, row+1, GTK_FILL, 0, 2, 2); row++; label = gtk_label_new(_("Mean grain size:")); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_FILL, 0, 2, 2); v = sqrt(npix*area/(ngrains*xres*yres)); gwy_si_unit_get_format(siunit, v, vf); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); label = gtk_label_new(NULL); gtk_label_set_markup(GTK_LABEL(label), str->str); gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 1, 2, row, row+1, GTK_FILL, 0, 2, 2); row++; gwy_si_unit_value_format_free(vf); g_string_free(str, TRUE); g_object_unref(siunit2); gtk_widget_show_all(dialog); return FALSE; }
static void grain_stat(G_GNUC_UNUSED GwyContainer *data, GwyRunType run) { GtkWidget *dialog, *table; GwyDataField *dfield, *mfield; GwySIUnit *siunit, *siunit2; GwySIValueFormat *vf; gint xres, yres, ngrains; gdouble total_area, area, size, vol_0, vol_min, vol_laplace, v; gdouble *values = NULL; gint *grains; GString *str; gint row; g_return_if_fail(run & STAT_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, GWY_APP_MASK_FIELD, &mfield, 0); g_return_if_fail(dfield); g_return_if_fail(mfield); xres = gwy_data_field_get_xres(mfield); yres = gwy_data_field_get_yres(mfield); total_area = gwy_data_field_get_xreal(dfield) *gwy_data_field_get_yreal(dfield); grains = g_new0(gint, xres*yres); ngrains = gwy_data_field_number_grains(mfield, grains); area = grains_get_total_value(dfield, ngrains, grains, &values, GWY_GRAIN_VALUE_PROJECTED_AREA); size = grains_get_total_value(dfield, ngrains, grains, &values, GWY_GRAIN_VALUE_EQUIV_SQUARE_SIDE); vol_0 = grains_get_total_value(dfield, ngrains, grains, &values, GWY_GRAIN_VALUE_VOLUME_0); vol_min = grains_get_total_value(dfield, ngrains, grains, &values, GWY_GRAIN_VALUE_VOLUME_MIN); vol_laplace = grains_get_total_value(dfield, ngrains, grains, &values, GWY_GRAIN_VALUE_VOLUME_LAPLACE); g_free(values); g_free(grains); dialog = gtk_dialog_new_with_buttons(_("Grain Statistics"), NULL, 0, GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL); gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE); table = gtk_table_new(7, 2, FALSE); gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), table); gtk_container_set_border_width(GTK_CONTAINER(table), 4); row = 0; str = g_string_new(NULL); g_string_printf(str, "%d", ngrains); add_report_row(GTK_TABLE(table), &row, _("Number of grains:"), str->str); siunit = gwy_data_field_get_si_unit_xy(dfield); siunit2 = gwy_si_unit_power(siunit, 2, NULL); v = area; vf = gwy_si_unit_get_format(siunit2, GWY_SI_UNIT_FORMAT_VFMARKUP, v, NULL); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); add_report_row(GTK_TABLE(table), &row, _("Total projected area (abs.):"), str->str); g_string_printf(str, "%.2f %%", 100.0*area/total_area); add_report_row(GTK_TABLE(table), &row, _("Total projected area (rel.):"), str->str); v = area/ngrains; gwy_si_unit_get_format(siunit2, GWY_SI_UNIT_FORMAT_VFMARKUP, v, vf); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); add_report_row(GTK_TABLE(table), &row, _("Mean grain area:"), str->str); v = size/ngrains; gwy_si_unit_get_format(siunit, GWY_SI_UNIT_FORMAT_VFMARKUP, v, vf); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); add_report_row(GTK_TABLE(table), &row, _("Mean grain size:"), str->str); siunit = gwy_data_field_get_si_unit_z(dfield); gwy_si_unit_multiply(siunit2, siunit, siunit2); v = vol_0; gwy_si_unit_get_format(siunit2, GWY_SI_UNIT_FORMAT_VFMARKUP, v, vf); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); add_report_row(GTK_TABLE(table), &row, _("Total grain volume (zero):"), str->str); v = vol_min; gwy_si_unit_get_format(siunit2, GWY_SI_UNIT_FORMAT_VFMARKUP, v, vf); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); add_report_row(GTK_TABLE(table), &row, _("Total grain volume (minimum):"), str->str); v = vol_laplace; gwy_si_unit_get_format(siunit2, GWY_SI_UNIT_FORMAT_VFMARKUP, v, vf); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); add_report_row(GTK_TABLE(table), &row, _("Total grain volume (laplacian):"), str->str); gwy_si_unit_value_format_free(vf); g_string_free(str, TRUE); g_object_unref(siunit2); gtk_widget_show_all(dialog); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); }
static void level_grains_do(const LevelGrainsArgs *args, GwyContainer *data, GQuark dquark, gint id, GwyDataField *dfield, GwyDataField *mfield) { GwyDataField *buffer, *background, *invmask; gdouble error, cor, maxerr, lastfrac, frac, starterr; gdouble *heights, *bgdata; gint *grains; gboolean cancelled = FALSE; gint i, xres, yres, ngrains; xres = gwy_data_field_get_xres(mfield); yres = gwy_data_field_get_yres(mfield); grains = g_new0(gint, xres*yres); ngrains = gwy_data_field_number_grains(mfield, grains); if (!ngrains) { g_free(grains); return; } heights = g_new(gdouble, ngrains+1); gwy_data_field_grains_get_values(dfield, heights, ngrains, grains, args->base); heights[0] = 0.0; background = gwy_data_field_new_alike(dfield, FALSE); bgdata = gwy_data_field_get_data(background); for (i = 0; i < xres*yres; i++) bgdata[i] = -heights[grains[i]]; invmask = gwy_data_field_duplicate(mfield); gwy_data_field_multiply(invmask, -1.0); gwy_data_field_add(invmask, 1.0); maxerr = gwy_data_field_get_rms(dfield)/1.0e4; gwy_app_wait_start(gwy_app_find_window_for_channel(data, id), _("Laplace interpolation...")); g_free(heights); g_free(grains); buffer = gwy_data_field_new_alike(background, TRUE); gwy_data_field_correct_average(background, invmask); cor = 0.2; error = 0.0; lastfrac = 0.0; starterr = 0.0; for (i = 0; i < 5000; i++) { gwy_data_field_correct_laplace_iteration(background, invmask, buffer, cor, &error); if (error < maxerr) break; if (!i) starterr = error; frac = log(error/starterr)/log(maxerr/starterr); if ((i/(gdouble)(5000)) > frac) frac = i/(gdouble)(5000); if (lastfrac > frac) frac = lastfrac; if (!gwy_app_wait_set_fraction(frac)) { cancelled = TRUE; break; } lastfrac = frac; } gwy_app_wait_finish(); if (!cancelled) { gwy_data_field_invert(background, FALSE, FALSE, TRUE); gwy_app_undo_qcheckpointv(data, 1, &dquark); gwy_data_field_subtract_fields(dfield, dfield, background); gwy_data_field_data_changed(dfield); if (args->do_extract) { gint newid; newid = gwy_app_data_browser_add_data_field(background, data, TRUE); gwy_app_sync_data_items(data, data, id, newid, FALSE, GWY_DATA_ITEM_GRADIENT, 0); gwy_app_set_data_field_title(data, newid, _("Background")); } } g_object_unref(buffer); g_object_unref(invmask); g_object_unref(background); }