Exemple #1
0
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;
}
Exemple #2
0
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);
}
Exemple #3
0
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);
}
Exemple #4
0
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);
}
Exemple #5
0
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;
}
Exemple #6
0
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);
}
Exemple #7
0
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);
}