static gchar* grain_dist_export_create(gpointer user_data, gssize *data_len) { const GrainDistExportData *expdata = (const GrainDistExportData*)user_data; const GrainDistArgs *args; GString *report; gdouble *values[32]; gchar buffer[32]; gint res, gno, ncols; guint i, bits; gchar *retval; memset(values, 0, sizeof(values)); args = expdata->args; res = args->fixres ? args->resolution : 0; bits = args->selected; ncols = 0; for (i = 0; bits; i++, bits /= 2) { if (bits & 1) { values[i] = gwy_data_field_grains_get_values(expdata->dfield, NULL, expdata->ngrains, expdata->grains, i); ncols++; } } report = g_string_sized_new(12*expdata->ngrains*ncols); for (gno = 1; gno <= expdata->ngrains; gno++) { bits = args->selected; for (i = 0; bits; i++, bits /= 2) { if (bits & 1) { g_ascii_formatd(buffer, sizeof(buffer), "%g", values[i][gno]); g_string_append(report, buffer); g_string_append_c(report, bits == 1 ? '\n' : '\t'); } } } bits = args->selected; for (i = 0; bits; i++, bits /= 2) { if (bits & 1) g_free(values[i]); } retval = report->str; g_string_free(report, FALSE); *data_len = -1; return retval; }
static gdouble grains_get_total_value(GwyDataField *dfield, gint ngrains, const gint *grains, gdouble **values, GwyGrainQuantity quantity) { gint i; gdouble sum; *values = gwy_data_field_grains_get_values(dfield, *values, ngrains, grains, quantity); sum = 0.0; for (i = 1; i <= ngrains; i++) sum += (*values)[i]; return sum; }
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); }