static void line_correct_step(GwyContainer *data, GwyRunType run) { GwyDataField *dfield, *mask; GQuark dquark; g_return_if_fail(run & LINECORR_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, GWY_APP_DATA_FIELD_KEY, &dquark, 0); g_return_if_fail(dfield && dquark); gwy_app_undo_qcheckpointv(data, 1, &dquark); gwy_data_field_absdiff_line_correct(dfield); mask = gwy_data_field_new_alike(dfield, TRUE); line_correct_step_iter(dfield, mask); gwy_data_field_clear(mask); line_correct_step_iter(dfield, mask); g_object_unref(mask); gwy_data_field_filter_conservative(dfield, 5); gwy_data_field_data_changed(dfield); }
static void poly_level_do(GwyContainer *data, GwyDataField *dfield, GwyDataField *mfield, GQuark quark, gint oldid, const PolyLevelArgs *args) { GwyDataField *bg = NULL; gint newid; gwy_app_undo_qcheckpointv(data, 1, &quark); if (args->do_extract) bg = gwy_data_field_new_alike(dfield, TRUE); if (mfield && args->masking != GWY_MASK_IGNORE) poly_level_do_with_mask(dfield, mfield, dfield, bg, args); else if (args->independent) poly_level_do_independent(dfield, dfield, bg, args->col_degree, args->row_degree); else poly_level_do_maximum(dfield, dfield, bg, args->max_degree); if (!args->do_extract) return; newid = gwy_app_data_browser_add_data_field(bg, data, TRUE); g_object_unref(bg); gwy_app_sync_data_items(data, data, oldid, newid, FALSE, GWY_DATA_ITEM_GRADIENT, 0); gwy_app_set_data_field_title(data, newid, _("Background")); }
static void rotate_180(GwyContainer *data, GwyRunType run) { GwyDataField *dfields[3]; GQuark quarks[3]; gint id; gint i; g_return_if_fail(run & BASICOPS_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, dfields + 0, GWY_APP_MASK_FIELD, dfields + 1, GWY_APP_SHOW_FIELD, dfields + 2, GWY_APP_DATA_FIELD_KEY, quarks + 0, GWY_APP_MASK_FIELD_KEY, quarks + 1, GWY_APP_SHOW_FIELD_KEY, quarks + 2, GWY_APP_DATA_FIELD_ID, &id, 0); clean_quarks(G_N_ELEMENTS(quarks), quarks, dfields); gwy_app_undo_qcheckpointv(data, G_N_ELEMENTS(quarks), quarks); for (i = 0; i < G_N_ELEMENTS(dfields); i++) { if (dfields[i]) { gwy_data_field_invert(dfields[i], TRUE, TRUE, FALSE); gwy_data_field_data_changed(dfields[i]); } } gwy_app_channel_log_add_proc(data, id, id); }
static void rotate_counterclockwise_90(GwyContainer *data, GwyRunType run) { GwyDataField *dfields[3], *newfield; GQuark quarks[3]; gint i, id; g_return_if_fail(run & BASICOPS_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, dfields + 0, GWY_APP_MASK_FIELD, dfields + 1, GWY_APP_SHOW_FIELD, dfields + 2, GWY_APP_DATA_FIELD_KEY, quarks + 0, GWY_APP_MASK_FIELD_KEY, quarks + 1, GWY_APP_SHOW_FIELD_KEY, quarks + 2, GWY_APP_DATA_FIELD_ID, &id, 0); clean_quarks(G_N_ELEMENTS(quarks), quarks, dfields); gwy_app_undo_qcheckpointv(data, G_N_ELEMENTS(quarks), quarks); for (i = 0; i < G_N_ELEMENTS(dfields); i++) { if (dfields[i]) { newfield = gwy_data_field_new_alike(dfields[i], FALSE); flip_xy(dfields[i], newfield, TRUE); gwy_container_set_object(data, quarks[i], newfield); g_object_unref(newfield); } } gwy_app_data_clear_selections(data, id); gwy_app_channel_log_add_proc(data, id, id); }
static void filter(GwyGraph *graph) { GwyContainer *data; GwyGraphCurveModel *cmodel, *cmodelnew; GwyGraphModel *model; const gdouble *xdata, *ydata; gdouble *newydata; gint i, ncurves, ndata; GQuark quark; gwy_app_data_browser_get_current(GWY_APP_CONTAINER, &data, GWY_APP_GRAPH_MODEL_KEY, &quark, 0); gwy_app_undo_qcheckpointv(data, 1, &quark); model = gwy_graph_get_model(graph); ncurves = gwy_graph_model_get_n_curves(model); for (i = 0; i < ncurves; i++) { cmodel = gwy_graph_model_get_curve(model, i); cmodelnew = gwy_graph_curve_model_new_alike(cmodel); xdata = gwy_graph_curve_model_get_xdata(cmodel); ydata = gwy_graph_curve_model_get_ydata(cmodel); ndata = gwy_graph_curve_model_get_ndata(cmodel); newydata = g_new(gdouble, ndata); filter_do(ydata, newydata, ndata); gwy_graph_curve_model_set_data(cmodelnew, xdata, newydata, ndata); g_free(newydata); gwy_graph_model_remove_curve(gwy_graph_get_model(graph), i); gwy_graph_model_add_curve(model, cmodelnew); g_object_unref(cmodelnew); } }
static void line_correct_median_difference(GwyContainer *data, GwyRunType run) { GwyDataField *dfield; gdouble *diffs, *row, *prev; gint xres, yres, i, j; gdouble median; GQuark dquark; g_return_if_fail(run & GWY_RUN_IMMEDIATE); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, GWY_APP_DATA_FIELD_KEY, &dquark, 0); g_return_if_fail(dfield && dquark); gwy_app_undo_qcheckpointv(data, 1, &dquark); xres = gwy_data_field_get_xres(dfield); yres = gwy_data_field_get_yres(dfield); row = gwy_data_field_get_data(dfield); diffs = g_new(gdouble, xres); for (i = 1; i < yres; i++) { prev = row; row += xres; for (j = 0; j < xres; j++) diffs[j] = prev[j] - row[j]; median = gwy_math_median(xres, diffs); for (j = 0; j < xres; j++) row[j] += median; } g_free(diffs); gwy_data_field_data_changed(dfield); }
static void run_noninteractive(FacetsArgs *args, GwyContainer *data, GwyContainer *fdata, GwyDataField *dfield, GwyDataField *mfield, GQuark mquark) { GwyDataField *dtheta, *dphi, *mask; gwy_app_undo_qcheckpointv(data, 1, &mquark); mask = create_mask_field(dfield); dtheta = GWY_DATA_FIELD(gwy_container_get_object_by_name(fdata, "/theta")); dphi = GWY_DATA_FIELD(gwy_container_get_object_by_name(fdata, "/phi")); gwy_data_field_mark_facets(dtheta, dphi, args->theta0, args->phi0, args->tolerance, mask); if (mfield && args->combine) { if (args->combine_type == GWY_MERGE_UNION) gwy_data_field_grains_add(mfield, mask); else if (args->combine_type == GWY_MERGE_INTERSECTION) gwy_data_field_grains_intersect(mfield, mask); gwy_data_field_data_changed(mfield); } else if (mfield) { gwy_data_field_copy(mask, mfield, FALSE); gwy_data_field_data_changed(mfield); } else { gwy_container_set_object(data, mquark, mask); } g_object_unref(mask); }
static void presentation_logscale(GwyContainer *data, GwyRunType run) { GwyDataField *dfield, *sfield; GQuark squark; gdouble *d; gdouble min, max, m0; gint xres, yres, i, zeroes, id; g_return_if_fail(run & PRESENTATIONOPS_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, GWY_APP_SHOW_FIELD_KEY, &squark, GWY_APP_SHOW_FIELD, &sfield, GWY_APP_DATA_FIELD_ID, &id, 0); g_return_if_fail(dfield && squark); xres = gwy_data_field_get_xres(dfield); yres = gwy_data_field_get_yres(dfield); gwy_app_undo_qcheckpointv(data, 1, &squark); if (!sfield) { sfield = gwy_data_field_duplicate(dfield); gwy_container_set_object(data, squark, sfield); g_object_unref(sfield); } else { gwy_data_field_resample(sfield, xres, yres, GWY_INTERPOLATION_NONE); gwy_data_field_copy(dfield, sfield, FALSE); } d = gwy_data_field_get_data(sfield); zeroes = 0; max = 0; min = G_MAXDOUBLE; for (i = 0; i < xres*yres; i++) { d[i] = ABS(d[i]); if (G_UNLIKELY(d[i] > max)) max = d[i]; if (d[i] == 0.0) zeroes++; else if (G_UNLIKELY(d[i] < min)) min = d[i]; } if (min == max || zeroes == xres*yres) return; if (!zeroes) { for (i = 0; i < xres*yres; i++) d[i] = log(d[i]); } else { m0 = log(min) - log(max/min)/512.0; for (i = 0; i < xres*yres; i++) d[i] = d[i] ? log(d[i]) : m0; } gwy_data_field_data_changed(sfield); gwy_app_channel_log_add_proc(data, id, id); }
static void laplace(GwyContainer *data, GwyRunType run) { GwyDataField *dfield, *mfield, *buffer; GQuark dquark; gdouble error, cor, maxer, lastfrac, frac, starter; gint i, id; gboolean cancelled = FALSE; g_return_if_fail(run & LAPLACE_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD_KEY, &dquark, GWY_APP_DATA_FIELD, &dfield, GWY_APP_MASK_FIELD, &mfield, GWY_APP_DATA_FIELD_ID, &id, 0); g_return_if_fail(dfield && dquark && mfield); maxer = gwy_data_field_get_rms(dfield)/1.0e4; gwy_app_wait_start(gwy_app_find_window_for_channel(data, id), _("Laplace interpolation...")); dfield = gwy_data_field_duplicate(dfield); buffer = gwy_data_field_new_alike(dfield, TRUE); gwy_data_field_correct_average(dfield, mfield); cor = 0.2; error = 0.0; lastfrac = 0.0; starter = 0.0; for (i = 0; i < 5000; i++) { gwy_data_field_correct_laplace_iteration(dfield, mfield, buffer, cor, &error); if (error < maxer) break; if (!i) starter = error; frac = log(error/starter)/log(maxer/starter); 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_app_undo_qcheckpointv(data, 1, &dquark); gwy_container_set_object(data, dquark, dfield); gwy_app_channel_log_add_proc(data, id, id); } g_object_unref(dfield); g_object_unref(buffer); }
static void run_noninteractive(GFilterArgs *args, GwyContainer *data, GwyDataField *mfield, GQuark mquark) { gwy_app_undo_qcheckpointv(data, 1, &mquark); gfilter_process(mfield, args); gwy_data_field_data_changed(mfield); }
static void run_noninteractive(GEdgeArgs *args, GwyContainer *data, GwyDataField *dfield, GQuark mquark) { GwyDataField *mfield; gwy_app_undo_qcheckpointv(data, 1, &mquark); mfield = create_mask_field(dfield); gedge_process(dfield, mfield, args); gwy_container_set_object(data, mquark, mfield); g_object_unref(mfield); }
static void presentation_remove(GwyContainer *data, GwyRunType run) { GQuark quark; gint id; g_return_if_fail(run & PRESENTATIONOPS_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_SHOW_FIELD_KEY, &quark, GWY_APP_DATA_FIELD_ID, &id, 0); g_return_if_fail(quark); gwy_app_undo_qcheckpointv(data, 1, &quark); gwy_container_remove(data, quark); gwy_app_channel_log_add_proc(data, id, id); }
static void mask_remove(GwyContainer *data, GwyRunType run) { GQuark mquark; gint id; g_return_if_fail(run & MASKOPS_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_MASK_FIELD_KEY, &mquark, GWY_APP_DATA_FIELD_ID, &id, 0); g_return_if_fail(mquark); gwy_app_undo_qcheckpointv(data, 1, &mquark); gwy_container_remove(data, mquark); gwy_app_channel_log_add_proc(data, id, id); }
static void fraccor(GwyContainer *data, GwyRunType run) { GwyDataField *dfield, *mfield; GQuark dquark; g_return_if_fail(run & FRACCOR_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD_KEY, &dquark, GWY_APP_DATA_FIELD, &dfield, GWY_APP_MASK_FIELD, &mfield, 0); g_return_if_fail(dfield && dquark && mfield); gwy_app_undo_qcheckpointv(data, 1, &dquark); gwy_data_field_fractal_correction(dfield, mfield, GWY_INTERPOLATION_LINEAR); gwy_data_field_data_changed(dfield); }
static void presentation_attach_do(const GwyAppDataId *source, const GwyAppDataId *target) { GwyContainer *sourcedata, *targetdata; GwyDataField *dfield; GQuark quark; sourcedata = gwy_app_data_browser_get(source->datano); targetdata = gwy_app_data_browser_get(target->datano); quark = gwy_app_get_data_key_for_id(source->id); dfield = GWY_DATA_FIELD(gwy_container_get_object(sourcedata, quark)); dfield = gwy_data_field_duplicate(dfield); quark = gwy_app_get_show_key_for_id(target->id); gwy_app_undo_qcheckpointv(targetdata, 1, &quark); gwy_container_set_object(targetdata, quark, dfield); g_object_unref(dfield); }
static void mask_invert(GwyContainer *data, GwyRunType run) { GwyDataField *mfield; GQuark mquark; gint id; g_return_if_fail(run & MASKOPS_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_MASK_FIELD, &mfield, GWY_APP_MASK_FIELD_KEY, &mquark, GWY_APP_DATA_FIELD_ID, &id, 0); g_return_if_fail(mfield && mquark); gwy_app_undo_qcheckpointv(data, 1, &mquark); gwy_data_field_grains_invert(mfield); gwy_data_field_data_changed(mfield); gwy_app_channel_log_add_proc(data, id, id); }
static void null_offsets(GwyContainer *data, GwyRunType run) { GwyDataField *dfields[3]; GQuark quarks[3]; guint i; gint id; g_return_if_fail(run & BASICOPS_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, dfields + 0, GWY_APP_MASK_FIELD, dfields + 1, GWY_APP_SHOW_FIELD, dfields + 2, GWY_APP_DATA_FIELD_KEY, quarks + 0, GWY_APP_MASK_FIELD_KEY, quarks + 1, GWY_APP_SHOW_FIELD_KEY, quarks + 2, GWY_APP_DATA_FIELD_ID, &id, 0); clean_quarks(G_N_ELEMENTS(quarks), quarks, dfields); for (i = 0; i < G_N_ELEMENTS(dfields); i++) { if (dfields[i] && !gwy_data_field_get_xoffset(dfields[i]) && !gwy_data_field_get_yoffset(dfields[i])) { quarks[i] = 0; dfields[i] = NULL; } } if (!dfields[0] && !dfields[1] && !dfields[2]) return; gwy_app_undo_qcheckpointv(data, G_N_ELEMENTS(quarks), quarks); for (i = 0; i < G_N_ELEMENTS(dfields); i++) { if (dfields[i]) { gwy_data_field_set_xoffset(dfields[i], 0.0); gwy_data_field_set_yoffset(dfields[i], 0.0); gwy_data_field_data_changed(dfields[i]); } } gwy_app_channel_log_add_proc(data, id, id); }
static void laplace(GwyContainer *data, GwyRunType run) { GwyDataField *dfield, *mfield; GQuark dquark; gint id; g_return_if_fail(run & LAPLACE_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD_KEY, &dquark, GWY_APP_DATA_FIELD, &dfield, GWY_APP_MASK_FIELD, &mfield, GWY_APP_DATA_FIELD_ID, &id, 0); g_return_if_fail(dfield && dquark && mfield); gwy_app_undo_qcheckpointv(data, 1, &dquark); gwy_data_field_laplace_solve(dfield, mfield, -1, 1.0); gwy_data_field_data_changed(dfield); gwy_app_channel_log_add_proc(data, id, id); }
static void line_correct_match(GwyContainer *data, GwyRunType run) { GwyDataField *dfield; GwyDataLine *shifts; gint xres, yres, i; gdouble *d, *s; GQuark dquark; g_return_if_fail(run & LINECORR_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, GWY_APP_DATA_FIELD_KEY, &dquark, 0); g_return_if_fail(dfield && dquark); gwy_app_undo_qcheckpointv(data, 1, &dquark); yres = gwy_data_field_get_yres(dfield); xres = gwy_data_field_get_xres(dfield); d = gwy_data_field_get_data(dfield); shifts = gwy_data_line_new(yres, 1.0, TRUE); s = gwy_data_line_get_data(shifts); s[0] = 0.0; for (i = 1; i < yres; i++) { s[i] = find_shift(xres, d + i*xres, d + (i - 1)*xres); g_printerr("%d %g\n", i, s[i]); } gwy_data_line_cumulate(shifts); for (i = 1; i < yres; i++) gwy_data_field_area_add(dfield, 0, i, xres, 1, s[i]); gwy_data_field_add(dfield, -s[yres-1]/(xres*yres)); g_object_unref(shifts); gwy_data_field_data_changed(dfield); }
static void run_noninteractive(FacetsArgs *args, GwyContainer *data, GwyContainer *fdata, GwyDataField *dfield, GwyDataField *mfield, GQuark mquark) { GwyDataField *dtheta, *dphi; gwy_app_undo_qcheckpointv(data, 1, &mquark); if (!mfield) { mfield = create_mask_field(dfield); gwy_container_set_object(data, mquark, mfield); g_object_unref(mfield); } dtheta = GWY_DATA_FIELD(gwy_container_get_object_by_name(fdata, "/theta")); dphi = GWY_DATA_FIELD(gwy_container_get_object_by_name(fdata, "/phi")); gwy_data_field_mark_facets(dtheta, dphi, args->theta0, args->phi0, args->tolerance, mfield); gwy_data_field_data_changed(mfield); }
static void tilt(GwyContainer *data, GwyRunType run) { GwyDataField *dfield; GQuark quark; TiltArgs args; gboolean ok; g_return_if_fail(run & TILT_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, GWY_APP_DATA_FIELD_KEY, &quark, 0); g_return_if_fail(dfield); tilt_load_args(gwy_app_settings_get(), &args); if (run == GWY_RUN_INTERACTIVE) { ok = tilt_dialog(&args, dfield); tilt_save_args(gwy_app_settings_get(), &args); if (!ok) return; } gwy_app_undo_qcheckpointv(data, 1, &quark); { /* Use negative values since the module says `Tilt', * not `Remove tilt' */ double bx = -args.dx*gwy_data_field_get_xmeasure(dfield); double by = -args.dy*gwy_data_field_get_ymeasure(dfield); double c = -0.5*(bx*gwy_data_field_get_xres(dfield) + by*gwy_data_field_get_yres(dfield)); gwy_data_field_plane_level(dfield, c, bx, by); } gwy_data_field_data_changed(dfield); }
static void line_correct_median(GwyContainer *data, GwyRunType run) { GwyDataField *dfield; GwyDataLine *line, *modi; gint xres, yres, i; GQuark dquark; gdouble median; g_return_if_fail(run & LINECORR_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, GWY_APP_DATA_FIELD_KEY, &dquark, 0); g_return_if_fail(dfield && dquark); gwy_app_undo_qcheckpointv(data, 1, &dquark); xres = gwy_data_field_get_xres(dfield); line = gwy_data_line_new(xres, 1.0, FALSE); yres = gwy_data_field_get_yres(dfield); modi = gwy_data_line_new(yres, 1.0, FALSE); for (i = 0; i < yres; i++) { gwy_data_field_get_row(dfield, line, i); median = gwy_math_median(xres, gwy_data_line_get_data(line)); gwy_data_line_set_val(modi, i, median); } median = gwy_data_line_get_median(modi); for (i = 0; i < yres; i++) { gwy_data_field_area_add(dfield, 0, i, xres, 1, median - gwy_data_line_get_val(modi, i)); } g_object_unref(modi); g_object_unref(line); gwy_data_field_data_changed(dfield); }
static void facets_dialog(FacetsArgs *args, GwyContainer *data, GwyContainer *fdata, GwyDataField *dfield, GwyDataField *mfield, gint id, GQuark mquark) { GtkWidget *dialog, *table, *hbox, *hbox2, *vbox, *label, *scale, *button; GtkWidget *spin; FacetsControls controls; enum { RESPONSE_RESET = 1, RESPONSE_PREVIEW = 2 }; gint response; GwyPixmapLayer *layer; GwyVectorLayer *vlayer; GwySelection *selection; gint row; memset(&controls, 0, sizeof(FacetsControls)); controls.args = args; dialog = gtk_dialog_new_with_buttons(_("Mark Facets"), NULL, GTK_DIALOG_DESTROY_WITH_PARENT, _("_Mark"), RESPONSE_PREVIEW, _("_Reset"), RESPONSE_RESET, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE); gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); controls.dialog = dialog; /* Shallow-copy stuff to temporary container */ controls.fdata = fdata; controls.mydata = gwy_container_new(); gwy_container_set_object_by_name(controls.mydata, "/0/data", dfield); gwy_app_sync_data_items(data, controls.mydata, id, 0, FALSE, GWY_DATA_ITEM_PALETTE, GWY_DATA_ITEM_RANGE, GWY_DATA_ITEM_MASK_COLOR, GWY_DATA_ITEM_REAL_SQUARE, 0); hbox = gtk_hbox_new(FALSE, 2); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 4); controls.view = gwy_data_view_new(controls.mydata); layer = gwy_layer_basic_new(); g_object_set(layer, "data-key", "/0/data", "gradient-key", "/0/base/palette", "range-type-key", "/0/base/range-type", "min-max-key", "/0/base", NULL); gwy_data_view_set_data_prefix(GWY_DATA_VIEW(controls.view), "/0/data"); gwy_data_view_set_base_layer(GWY_DATA_VIEW(controls.view), layer); gwy_set_data_preview_size(GWY_DATA_VIEW(controls.view), PREVIEW_SIZE); vlayer = g_object_new(g_type_from_name("GwyLayerPoint"), NULL); gwy_vector_layer_set_selection_key(vlayer, "/0/select/pointer"); gwy_data_view_set_top_layer(GWY_DATA_VIEW(controls.view), vlayer); selection = gwy_vector_layer_ensure_selection(vlayer); g_signal_connect(selection, "changed", G_CALLBACK(preview_selection_updated), &controls); gtk_box_pack_start(GTK_BOX(hbox), controls.view, FALSE, FALSE, 4); vbox = gtk_vbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0); hbox2 = gtk_hbox_new(FALSE, 4); gtk_box_pack_start(GTK_BOX(vbox), hbox2, FALSE, FALSE, 0); /* Slope view */ controls.fview = gwy_data_view_new(controls.fdata); gtk_box_pack_start(GTK_BOX(hbox2), controls.fview, FALSE, FALSE, 0); layer = gwy_layer_basic_new(); gwy_pixmap_layer_set_data_key(layer, "/0/data"); gwy_layer_basic_set_gradient_key(GWY_LAYER_BASIC(layer), "/0/base/palette"); gwy_data_view_set_base_layer(GWY_DATA_VIEW(controls.fview), layer); vlayer = g_object_new(g_type_from_name("GwyLayerPoint"), NULL); gwy_vector_layer_set_selection_key(vlayer, "/0/select/pointer"); gwy_data_view_set_top_layer(GWY_DATA_VIEW(controls.fview), GWY_VECTOR_LAYER(vlayer)); selection = gwy_vector_layer_ensure_selection(vlayer); g_signal_connect(selection, "changed", G_CALLBACK(facet_view_selection_updated), &controls); /* Info table */ table = gtk_table_new(7, 2, FALSE); gtk_table_set_row_spacings(GTK_TABLE(table), 2); gtk_table_set_col_spacings(GTK_TABLE(table), 6); gtk_container_set_border_width(GTK_CONTAINER(table), 4); gtk_box_pack_start(GTK_BOX(hbox2), table, TRUE, TRUE, 4); row = 0; label = gwy_label_new_header(gwy_sgettext("noun|Normal")); gtk_table_attach(GTK_TABLE(table), label, 0, 2, row, row+1, GTK_FILL, 0, 0, 0); row++; controls.theta_label = add_angle_label(table, _("θ:"), &row); controls.phi_label = add_angle_label(table, _("φ:"), &row); button = gtk_button_new_with_mnemonic(_("_Find Maximum")); gtk_table_attach(GTK_TABLE(table), button, 0, 2, row, row+1, GTK_FILL, 0, 0, 0); g_signal_connect_swapped(button, "clicked", G_CALLBACK(facet_view_reset_maximum), &controls); gtk_table_set_row_spacing(GTK_TABLE(table), row, 8); row++; label = gwy_label_new_header(_("Mean Normal")); gtk_table_attach(GTK_TABLE(table), label, 0, 2, row, row+1, GTK_FILL, 0, 0, 0); row++; controls.mtheta_label = add_angle_label(table, _("θ:"), &row); controls.mphi_label = add_angle_label(table, _("φ:"), &row); gtk_table_set_row_spacing(GTK_TABLE(table), row-1, 8); label = gtk_label_new_with_mnemonic(_("Facet plane size:")); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 0, 2, row, row+1, GTK_FILL, 0, 0, 0); row++; controls.kernel_size = gtk_adjustment_new(args->kernel_size, 0.0, MAX_PLANE_SIZE, 1.0, 1.0, 0); spin = gtk_spin_button_new(GTK_ADJUSTMENT(controls.kernel_size), 0.0, 0); gtk_label_set_mnemonic_widget(GTK_LABEL(label), spin); gtk_table_attach(GTK_TABLE(table), spin, 0, 1, row, row+1, 0, 0, 0, 0); g_signal_connect(controls.kernel_size, "value-changed", G_CALLBACK(facet_view_recompute), &controls); row++; table = gtk_table_new(9, 4, FALSE); gtk_table_set_row_spacings(GTK_TABLE(table), 2); gtk_table_set_col_spacings(GTK_TABLE(table), 6); gtk_container_set_border_width(GTK_CONTAINER(table), 4); gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 4); row = 0; controls.tolerance = gtk_adjustment_new(args->tolerance*180.0/G_PI, 0.0, 15.0, 0.01, 0.1, 0); scale = gwy_table_attach_hscale(table, row++, _("_Tolerance:"), _("deg"), controls.tolerance, 0); gtk_spin_button_set_digits(GTK_SPIN_BUTTON(scale), 3); g_signal_connect(controls.tolerance, "value-changed", G_CALLBACK(facets_tolerance_changed), &controls); controls.color_button = gwy_color_button_new(); gwy_color_button_set_use_alpha(GWY_COLOR_BUTTON(controls.color_button), TRUE); load_mask_color(controls.color_button, gwy_data_view_get_data(GWY_DATA_VIEW(controls.view))); gwy_table_attach_hscale(table, row++, _("_Mask color:"), NULL, GTK_OBJECT(controls.color_button), GWY_HSCALE_WIDGET_NO_EXPAND); g_signal_connect(controls.color_button, "clicked", G_CALLBACK(mask_color_change_cb), &controls); if (!gwy_si_unit_equal(gwy_data_field_get_si_unit_xy(dfield), gwy_data_field_get_si_unit_z(dfield))) { gtk_table_set_row_spacing(GTK_TABLE(table), row-1, 8); label = gtk_label_new(_("Warning: Lateral and value units differ. " "Angles are not physically meaningful.")); gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 0, 4, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0); row++; } facets_invalidate(&controls); gtk_widget_show_all(dialog); facet_view_select_angle(&controls, args->theta0, args->phi0); do { response = gtk_dialog_run(GTK_DIALOG(dialog)); switch (response) { case GTK_RESPONSE_CANCEL: case GTK_RESPONSE_DELETE_EVENT: gtk_widget_destroy(dialog); case GTK_RESPONSE_NONE: g_object_unref(controls.mydata); return; break; case GTK_RESPONSE_OK: break; case RESPONSE_RESET: args->tolerance = facets_defaults.tolerance; args->kernel_size = facets_defaults.kernel_size; facets_dialog_update_controls(&controls, args); break; case RESPONSE_PREVIEW: preview(&controls, args); update_average_angle(&controls, args); break; default: g_assert_not_reached(); break; } } while (response != GTK_RESPONSE_OK); gwy_app_sync_data_items(controls.mydata, data, 0, id, FALSE, GWY_DATA_ITEM_MASK_COLOR, 0); gtk_widget_destroy(dialog); if (controls.computed) { mfield = gwy_container_get_object_by_name(controls.mydata, "/0/mask"); gwy_app_undo_qcheckpointv(data, 1, &mquark); gwy_container_set_object(data, mquark, mfield); g_object_unref(controls.mydata); } else { g_object_unref(controls.mydata); run_noninteractive(args, data, fdata, dfield, mfield, mquark); } }
static void gfilter_dialog(GFilterArgs *args, GwyContainer *data, GwyDataField *dfield, GwyDataField *mfield, gint id, GQuark mquark) { GtkWidget *dialog, *table, *vbox, *hbox, *scwin, *hbox2, *label; GtkTreeView *treeview; GtkTreeSelection *selection; GFilterControls controls; gint response, row, i; GwySIUnit *siunit; GwyPixmapLayer *layer; controls.args = args; controls.mask = mfield; controls.in_init = TRUE; controls.computed = FALSE; siunit = gwy_si_unit_new(NULL); for (i = 0; i < NQUANTITIES; i++) { controls.vf[i] = gwy_si_unit_get_format_with_digits(siunit, GWY_SI_UNIT_FORMAT_VFMARKUP, 1.0, 4, NULL); } g_object_unref(siunit); dialog = gtk_dialog_new_with_buttons(_("Filter Grains"), NULL, 0, NULL); gtk_dialog_add_action_widget(GTK_DIALOG(dialog), gwy_stock_like_button_new(_("_Update"), GTK_STOCK_EXECUTE), RESPONSE_PREVIEW); gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_OK, GTK_RESPONSE_OK); gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog), RESPONSE_PREVIEW, !args->update); gwy_help_add_to_proc_dialog(GTK_DIALOG(dialog), GWY_HELP_DEFAULT); controls.dialog = dialog; hbox = gtk_hbox_new(FALSE, 2); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, TRUE, TRUE, 4); vbox = gtk_vbox_new(FALSE, 4); gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 4); controls.mydata = gwy_container_new(); gwy_container_set_object_by_name(controls.mydata, "/0/data", dfield); mfield = gwy_data_field_duplicate(mfield); gwy_container_set_object_by_name(controls.mydata, "/0/mask", mfield); g_object_unref(mfield); gwy_app_sync_data_items(data, controls.mydata, id, 0, FALSE, GWY_DATA_ITEM_PALETTE, GWY_DATA_ITEM_MASK_COLOR, GWY_DATA_ITEM_RANGE, GWY_DATA_ITEM_REAL_SQUARE, 0); controls.view = gwy_data_view_new(controls.mydata); layer = gwy_layer_basic_new(); g_object_set(layer, "data-key", "/0/data", "gradient-key", "/0/base/palette", "range-type-key", "/0/base/range-type", "min-max-key", "/0/base", NULL); gwy_data_view_set_data_prefix(GWY_DATA_VIEW(controls.view), "/0/data"); gwy_data_view_set_base_layer(GWY_DATA_VIEW(controls.view), layer); layer = gwy_layer_mask_new(); gwy_pixmap_layer_set_data_key(layer, "/0/mask"); gwy_layer_mask_set_color_key(GWY_LAYER_MASK(layer), "/0/mask"); gwy_data_view_set_alpha_layer(GWY_DATA_VIEW(controls.view), layer); gwy_set_data_preview_size(GWY_DATA_VIEW(controls.view), PREVIEW_SIZE); gtk_box_pack_start(GTK_BOX(vbox), controls.view, FALSE, FALSE, 0); controls.update = gtk_check_button_new_with_mnemonic(_("I_nstant updates")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(controls.update), args->update); gtk_box_pack_start(GTK_BOX(vbox), controls.update, FALSE, FALSE, 0); g_signal_connect_swapped(controls.update, "toggled", G_CALLBACK(update_changed), &controls); hbox2 = gtk_hbox_new(FALSE, 6); gtk_box_pack_start(GTK_BOX(vbox), hbox2, FALSE, FALSE, 0); label = gtk_label_new_with_mnemonic(_("_Mask color:")); gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0); controls.color_button = gwy_color_button_new(); gwy_color_button_set_use_alpha(GWY_COLOR_BUTTON(controls.color_button), TRUE); load_mask_color(controls.color_button, gwy_data_view_get_data(GWY_DATA_VIEW(controls.view))); gtk_label_set_mnemonic_widget(GTK_LABEL(label), controls.color_button); gtk_box_pack_start(GTK_BOX(hbox2), controls.color_button, FALSE, FALSE, 0); g_signal_connect(controls.color_button, "clicked", G_CALLBACK(mask_color_changed), &controls); table = gtk_table_new(10, 4, FALSE); gtk_table_set_row_spacings(GTK_TABLE(table), 2); gtk_table_set_col_spacings(GTK_TABLE(table), 6); gtk_container_set_border_width(GTK_CONTAINER(table), 4); gtk_box_pack_start(GTK_BOX(hbox), table, TRUE, TRUE, 4); controls.table = table; row = 0; scwin = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scwin), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_table_attach(GTK_TABLE(table), scwin, 0, 4, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); controls.values = gwy_grain_value_tree_view_new(FALSE, "name", "symbol_markup", NULL); treeview = GTK_TREE_VIEW(controls.values); gtk_widget_set_size_request(scwin, -1, 120); gtk_tree_view_set_headers_visible(treeview, FALSE); selection = gtk_tree_view_get_selection(treeview); gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE); gwy_grain_value_tree_view_set_same_units(treeview, args->units_equal); gwy_grain_value_tree_view_set_expanded_groups(treeview, args->expanded); gtk_container_add(GTK_CONTAINER(scwin), controls.values); row++; hbox2 = gtk_hbox_new(FALSE, 0); for (i = 0; i < NQUANTITIES; i++) { gchar buf[2]; buf[0] = 'A' + i; buf[1] = '\0'; controls.set_as[i] = gtk_button_new_with_label(buf); gtk_box_pack_start(GTK_BOX(hbox2), controls.set_as[i], FALSE, FALSE, 0); g_object_set_data(G_OBJECT(controls.set_as[i]), "id", GUINT_TO_POINTER(i)); g_signal_connect_swapped(controls.set_as[i], "clicked", G_CALLBACK(set_as_clicked), &controls); } gwy_table_attach_hscale(table, row++, _("Set selected as:"), NULL, GTK_OBJECT(hbox2), GWY_HSCALE_WIDGET_NO_EXPAND); controls.logical_op = gwy_enum_combo_box_newl(G_CALLBACK(logical_op_changed), &controls, args->logical, "A", GRAIN_LOGICAL_A, "A ∧ B", GRAIN_LOGICAL_A_AND_B, "A ∨ B", GRAIN_LOGICAL_A_OR_B, "A ∧ B ∧ C", GRAIN_LOGICAL_A_AND_B_AND_C, "A ∨ B ∨ C", GRAIN_LOGICAL_A_OR_B_OR_C, "(A ∧ B) ∨ C", GRAIN_LOGICAL_A_AND_B_OR_C, "(A ∨ B) ∧ C", GRAIN_LOGICAL_A_OR_B_AND_C, NULL); gwy_table_attach_hscale(table, row++, _("Keep grains satisfying:"), NULL, GTK_OBJECT(controls.logical_op), GWY_HSCALE_WIDGET); for (i = 0; i < NQUANTITIES; i++) { gtk_table_set_row_spacing(GTK_TABLE(table), row-1, 8); controls.header[i] = gtk_label_new(NULL); gtk_misc_set_alignment(GTK_MISC(controls.header[i]), 0.0, 0.5); gtk_table_attach(GTK_TABLE(table), controls.header[i], 0, 4, row, row+1, GTK_FILL, 0, 0, 0); row++; /* The values are set properly later. */ controls.lower_label[i] = gtk_label_new(_("Lower threshold:")); gtk_misc_set_alignment(GTK_MISC(controls.lower_label[i]), 0.0, 0.5); gtk_table_attach(GTK_TABLE(table), controls.lower_label[i], 0, 1, row, row+1, GTK_FILL, 0, 0, 0); controls.lower[i] = gtk_adjustment_new(0.0, 0.0, 0.0, 1.0, 10.0, 0.0); g_object_set_data(G_OBJECT(controls.lower[i]), "id", GUINT_TO_POINTER(i)); g_signal_connect_swapped(controls.lower[i], "value-changed", G_CALLBACK(threshold_changed), &controls); controls.lower_scale[i] = gtk_hscale_new(GTK_ADJUSTMENT(controls.lower[i])); gtk_scale_set_draw_value(GTK_SCALE(controls.lower_scale[i]), FALSE); gtk_widget_set_size_request(controls.lower_scale[i], GWY_HSCALE_WIDTH, -1); gtk_table_attach(GTK_TABLE(table), controls.lower_scale[i], 1, 2, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0); controls.lower_entry[i] = gtk_entry_new(); gtk_entry_set_width_chars(GTK_ENTRY(controls.lower_entry[i]), 8); gtk_table_attach(GTK_TABLE(table), controls.lower_entry[i], 2, 3, row, row+1, GTK_FILL, 0, 0, 0); gwy_widget_set_activate_on_unfocus(controls.lower_entry[i], TRUE); g_object_set_data(G_OBJECT(controls.lower_entry[i]), "id", GUINT_TO_POINTER(i)); g_signal_connect_swapped(controls.lower_entry[i], "activate", G_CALLBACK(threshold_activated), &controls); controls.lower_units[i] = gtk_label_new(NULL); gtk_misc_set_alignment(GTK_MISC(controls.lower_units[i]), 0.0, 0.5); gtk_table_attach(GTK_TABLE(table), controls.lower_units[i], 3, 4, row, row+1, GTK_FILL, 0, 0, 0); row++; controls.upper_label[i] = gtk_label_new(_("Upper threshold:")); gtk_misc_set_alignment(GTK_MISC(controls.upper_label[i]), 0.0, 0.5); gtk_table_attach(GTK_TABLE(table), controls.upper_label[i], 0, 1, row, row+1, GTK_FILL, 0, 0, 0); controls.upper[i] = gtk_adjustment_new(0.0, 0.0, 0.0, 1.0, 10.0, 0.0); g_object_set_data(G_OBJECT(controls.upper[i]), "id", GUINT_TO_POINTER(i | IS_UPPER)); g_signal_connect_swapped(controls.upper[i], "value-changed", G_CALLBACK(threshold_changed), &controls); controls.upper_scale[i] = gtk_hscale_new(GTK_ADJUSTMENT(controls.upper[i])); gtk_scale_set_draw_value(GTK_SCALE(controls.upper_scale[i]), FALSE); gtk_widget_set_size_request(controls.upper_scale[i], GWY_HSCALE_WIDTH, -1); gtk_table_attach(GTK_TABLE(table), controls.upper_scale[i], 1, 2, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0); controls.upper_entry[i] = gtk_entry_new(); gtk_entry_set_width_chars(GTK_ENTRY(controls.upper_entry[i]), 8); gtk_table_attach(GTK_TABLE(table), controls.upper_entry[i], 2, 3, row, row+1, GTK_FILL, 0, 0, 0); gwy_widget_set_activate_on_unfocus(controls.upper_entry[i], TRUE); g_object_set_data(G_OBJECT(controls.upper_entry[i]), "id", GUINT_TO_POINTER(i | IS_UPPER)); g_signal_connect_swapped(controls.upper_entry[i], "activate", G_CALLBACK(threshold_activated), &controls); controls.upper_units[i] = gtk_label_new(NULL); gtk_misc_set_alignment(GTK_MISC(controls.upper_units[i]), 0.0, 0.5); gtk_table_attach(GTK_TABLE(table), controls.upper_units[i], 3, 4, row, row+1, GTK_FILL, 0, 0, 0); row++; } for (i = 0; i < NQUANTITIES; i++) { GwyInventory *inventory; GwyGrainValue *gvalue; inventory = gwy_grain_values(); gvalue = gwy_inventory_get_item(inventory, args->ranges[i].quantity); set_up_quantity(&controls, gvalue, i); } logical_op_changed(GTK_COMBO_BOX(controls.logical_op), &controls); /* finished initializing, allow instant updates */ controls.in_init = FALSE; gfilter_invalidate(&controls); gtk_widget_show_all(dialog); do { response = gtk_dialog_run(GTK_DIALOG(dialog)); switch (response) { case GTK_RESPONSE_CANCEL: case GTK_RESPONSE_DELETE_EVENT: args->expanded = gwy_grain_value_tree_view_get_expanded_groups (GTK_TREE_VIEW(controls.values)); for (i = 0; i < NQUANTITIES; i++) gwy_si_unit_value_format_free(controls.vf[i]); gtk_widget_destroy(dialog); case GTK_RESPONSE_NONE: g_object_unref(controls.mydata); gfilter_save_args(gwy_app_settings_get(), args); return; break; case GTK_RESPONSE_OK: break; case RESPONSE_PREVIEW: preview(&controls); break; default: g_assert_not_reached(); break; } } while (response != GTK_RESPONSE_OK); for (i = 0; i < NQUANTITIES; i++) gwy_si_unit_value_format_free(controls.vf[i]); args->expanded = gwy_grain_value_tree_view_get_expanded_groups (GTK_TREE_VIEW(controls.values)); gwy_app_sync_data_items(controls.mydata, data, 0, id, FALSE, GWY_DATA_ITEM_MASK_COLOR, 0); gtk_widget_destroy(dialog); gfilter_save_args(gwy_app_settings_get(), args); if (controls.computed) { mfield = gwy_container_get_object_by_name(controls.mydata, "/0/mask"); gwy_app_undo_qcheckpointv(data, 1, &mquark); gwy_container_set_object(data, mquark, mfield); g_object_unref(controls.mydata); } else { g_object_unref(controls.mydata); run_noninteractive(args, data, controls.mask, mquark); } gwy_app_channel_log_add_proc(data, id, id); }
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); }
static void line_correct_match(GwyContainer *data, GwyRunType run) { GwyDataField *dfield; GwyDataLine *shifts; gint xres, yres, i, j; gdouble m, wsum, lambda, x; gdouble *d, *s, *w; const gdouble *a, *b; GQuark dquark; g_return_if_fail(run & LINECORR_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, GWY_APP_DATA_FIELD_KEY, &dquark, 0); g_return_if_fail(dfield && dquark); gwy_app_undo_qcheckpointv(data, 1, &dquark); yres = gwy_data_field_get_yres(dfield); xres = gwy_data_field_get_xres(dfield); d = gwy_data_field_get_data(dfield); shifts = gwy_data_line_new(yres, 1.0, TRUE); s = gwy_data_line_get_data(shifts); w = g_new(gdouble, xres-1); for (i = 1; i < yres; i++) { a = d + xres*(i - 1); b = d + xres*i; /* Diffnorm */ wsum = 0.0; for (j = 0; j < xres-1; j++) { x = a[j+1] - a[j] - b[j+1] + b[j]; wsum += fabs(x); } if (wsum == 0) continue; m = wsum/(xres-1); /* Weights */ wsum = 0.0; for (j = 0; j < xres-1; j++) { x = a[j+1] - a[j] - b[j+1] + b[j]; w[j] = exp(-(x*x/(2.0*m))); wsum += w[j]; } /* Correction */ lambda = (a[0] - b[0])*w[0]; for (j = 1; j < xres-1; j++) lambda += (a[j] - b[j])*(w[j-1] + w[j]); lambda += (a[xres-1] - b[xres-1])*w[xres-2]; lambda /= 2.0*wsum; gwy_debug("%g %g %g", m, wsum, lambda); s[i] = lambda; } gwy_data_line_cumulate(shifts); for (i = 1; i < yres; i++) gwy_data_field_area_add(dfield, 0, i, xres, 1, s[i]); gwy_data_field_add(dfield, -s[yres-1]/(xres*yres)); g_object_unref(shifts); g_free(w); gwy_data_field_data_changed(dfield); }
static void maskcor_do(MaskcorArgs *args) { enum { WORK_PER_UPDATE = 50000000 }; GwyDataField *dfield, *kernel, *retfield, *score; GwyContainer *data, *kerneldata; GwyComputationState *state; GQuark quark; gint newid, work, wpi; kerneldata = gwy_app_data_browser_get(args->kernel.datano); quark = gwy_app_get_data_key_for_id(args->kernel.id); kernel = GWY_DATA_FIELD(gwy_container_get_object(kerneldata, quark)); data = gwy_app_data_browser_get(args->data.datano); quark = gwy_app_get_data_key_for_id(args->data.id); dfield = GWY_DATA_FIELD(gwy_container_get_object(data, quark)); retfield = gwy_data_field_new_alike(dfield, FALSE); /* FIXME */ if (args->method == GWY_CORRELATION_NORMAL) { gwy_app_wait_start(gwy_app_find_window_for_channel(data, args->data.id), _("Initializing...")); state = gwy_data_field_correlate_init(dfield, kernel, retfield); gwy_app_wait_set_message(_("Correlating...")); work = 0; wpi = gwy_data_field_get_xres(kernel)*gwy_data_field_get_yres(kernel); wpi = MIN(wpi, WORK_PER_UPDATE); do { gwy_data_field_correlate_iteration(state); work += wpi; if (work > WORK_PER_UPDATE) { work -= WORK_PER_UPDATE; if (!gwy_app_wait_set_fraction(state->fraction)) { gwy_data_field_correlate_finalize(state); gwy_app_wait_finish(); g_object_unref(retfield); return; } } } while (state->state != GWY_COMPUTATION_STATE_FINISHED); gwy_data_field_correlate_finalize(state); gwy_app_wait_finish(); } else gwy_data_field_correlate(dfield, kernel, retfield, args->method); /* score - do new data with score */ if (args->result == GWY_MASKCOR_SCORE) { score = gwy_data_field_duplicate(retfield); newid = gwy_app_data_browser_add_data_field(score, data, TRUE); gwy_app_sync_data_items(data, data, args->data.id, newid, FALSE, GWY_DATA_ITEM_GRADIENT, 0); gwy_app_set_data_field_title(data, newid, _("Correlation score")); g_object_unref(score); gwy_app_channel_log_add_proc(data, args->data.id, newid); } else { /* add mask */ quark = gwy_app_get_mask_key_for_id(args->data.id); gwy_app_undo_qcheckpointv(data, 1, &quark); if (args->result == GWY_MASKCOR_OBJECTS) plot_correlated(retfield, gwy_data_field_get_xres(kernel), gwy_data_field_get_yres(kernel), args->threshold); else if (args->result == GWY_MASKCOR_MAXIMA) gwy_data_field_threshold(retfield, args->threshold, 0.0, 1.0); gwy_container_set_object(data, quark, retfield); gwy_app_channel_log_add_proc(data, args->data.id, args->data.id); } g_object_unref(retfield); }
static void run_noninteractive(NoiseSynthArgs *args, const GwyDimensionArgs *dimsargs, GwyContainer *data, GwyDataField *dfield, gint oldid, GQuark quark) { GwySIUnit *siunit; gboolean replace = dimsargs->replace && dfield; gboolean add = dimsargs->add && dfield; gint newid; if (args->randomize) args->seed = g_random_int() & 0x7fffffff; if (replace) { /* Always take a reference so that we can always unref. */ g_object_ref(dfield); gwy_app_undo_qcheckpointv(data, 1, &quark); if (!add) gwy_data_field_clear(dfield); gwy_app_channel_log_add_proc(data, oldid, oldid); } else { if (add) dfield = gwy_data_field_duplicate(dfield); else { gdouble mag = pow10(dimsargs->xypow10) * dimsargs->measure; dfield = gwy_data_field_new(dimsargs->xres, dimsargs->yres, mag*dimsargs->xres, mag*dimsargs->yres, TRUE); siunit = gwy_data_field_get_si_unit_xy(dfield); gwy_si_unit_set_from_string(siunit, dimsargs->xyunits); siunit = gwy_data_field_get_si_unit_z(dfield); gwy_si_unit_set_from_string(siunit, dimsargs->zunits); } } noise_synth_do(args, dimsargs, dfield); if (replace) gwy_data_field_data_changed(dfield); else { if (data) { newid = gwy_app_data_browser_add_data_field(dfield, data, TRUE); if (oldid != -1) gwy_app_sync_data_items(data, data, oldid, newid, FALSE, GWY_DATA_ITEM_GRADIENT, 0); } else { newid = 0; data = gwy_container_new(); gwy_container_set_object(data, gwy_app_get_data_key_for_id(newid), dfield); gwy_app_data_browser_add(data); gwy_app_data_browser_reset_visibility(data, GWY_VISIBILITY_RESET_SHOW_ALL); g_object_unref(data); } gwy_app_set_data_field_title(data, newid, _("Generated")); gwy_app_channel_log_add_proc(data, add ? oldid : -1, newid); } g_object_unref(dfield); }
static void sphrev(GwyContainer *data, GwyRunType run) { GwyDataField *dfield, *background = NULL; Sphrev1DArgs args; gint oldid, newid; GQuark dquark; gdouble xr, yr; gboolean ok = TRUE; g_return_if_fail(run & SPHREV_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, GWY_APP_DATA_FIELD_KEY, &dquark, GWY_APP_DATA_FIELD_ID, &oldid, 0); g_return_if_fail(dfield && dquark); sphrev_load_args(gwy_app_settings_get(), &args); /* FIXME: this is bogus for non-square pixels anyway */ xr = gwy_data_field_get_xreal(dfield)/gwy_data_field_get_xres(dfield); yr = gwy_data_field_get_yreal(dfield)/gwy_data_field_get_yres(dfield); args.pixelsize = hypot(xr, yr); args.valform = gwy_data_field_get_value_format_xy(dfield, GWY_SI_UNIT_FORMAT_VFMARKUP, NULL); gwy_debug("pixelsize = %g, vf = (%g, %d, %s)", args.pixelsize, args.valform->magnitude, args.valform->precision, args.valform->units); if (run == GWY_RUN_INTERACTIVE) { ok = sphrev_dialog(&args); sphrev_save_args(gwy_app_settings_get(), &args); } gwy_si_unit_value_format_free(args.valform); if (!ok) return; gwy_app_undo_qcheckpointv(data, 1, &dquark); switch (args.direction) { case SPHREV_HORIZONTAL: background = sphrev_horizontal(&args, dfield); break; case SPHREV_VERTICAL: background = sphrev_vertical(&args, dfield); break; case SPHREV_BOTH: { GwyDataField *tmp; background = sphrev_horizontal(&args, dfield); tmp = sphrev_vertical(&args, dfield); gwy_data_field_sum_fields(background, background, tmp); g_object_unref(tmp); gwy_data_field_multiply(background, 0.5); } break; default: g_assert_not_reached(); break; } gwy_data_field_subtract_fields(dfield, dfield, background); gwy_data_field_data_changed(dfield); if (!args.do_extract) { g_object_unref(background); return; } newid = gwy_app_data_browser_add_data_field(background, data, TRUE); g_object_unref(background); gwy_app_sync_data_items(data, data, oldid, newid, FALSE, GWY_DATA_ITEM_GRADIENT, 0); gwy_app_set_data_field_title(data, newid, _("Background")); }
static void median(GwyContainer *data, GwyRunType run) { GwyDataField *dfield, *background = NULL; MedianBgArgs args; gint oldid, newid; GQuark dquark; gdouble xr, yr; gboolean ok = TRUE; g_return_if_fail(run & MEDIANBG_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, GWY_APP_DATA_FIELD_KEY, &dquark, GWY_APP_DATA_FIELD_ID, &oldid, 0); g_return_if_fail(dfield && dquark); median_load_args(gwy_app_settings_get(), &args); /* FIXME: this is bogus for non-square pixels anyway */ xr = gwy_data_field_get_xreal(dfield)/gwy_data_field_get_xres(dfield); yr = gwy_data_field_get_yreal(dfield)/gwy_data_field_get_yres(dfield); args.pixelsize = hypot(xr, yr); args.valform = gwy_data_field_get_value_format_xy(dfield, GWY_SI_UNIT_FORMAT_VFMARKUP, NULL); gwy_debug("pixelsize = %g, vf = (%g, %d, %s)", args.pixelsize, args.valform->magnitude, args.valform->precision, args.valform->units); if (run == GWY_RUN_INTERACTIVE) { ok = median_dialog(&args); median_save_args(gwy_app_settings_get(), &args); } gwy_si_unit_value_format_free(args.valform); if (!ok) return; gwy_app_wait_start(gwy_app_find_window_for_channel(data, oldid), _("Median-leveling...")); background = median_background(GWY_ROUND(args.size), dfield); gwy_app_wait_finish(); if (!background) return; gwy_app_undo_qcheckpointv(data, 1, &dquark); gwy_data_field_subtract_fields(dfield, dfield, background); gwy_data_field_data_changed(dfield); gwy_app_channel_log_add_proc(data, oldid, oldid); if (!args.do_extract) { g_object_unref(background); return; } newid = gwy_app_data_browser_add_data_field(background, data, TRUE); g_object_unref(background); gwy_app_sync_data_items(data, data, oldid, newid, FALSE, GWY_DATA_ITEM_GRADIENT, 0); gwy_app_set_data_field_title(data, newid, _("Background")); gwy_app_channel_log_add(data, oldid, newid, NULL, NULL); }