示例#1
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);
}
示例#2
0
static void
gfilter_load_args(GwyContainer *container,
                  GFilterArgs *args)
{
    GwyInventory *inventory;
    gchar *filename, *buffer;
    gsize size;
    guint i;

    inventory = gwy_grain_values();
    *args = gfilter_defaults;

    gwy_container_gis_boolean_by_name(container, update_key, &args->update);
    gwy_container_gis_int32_by_name(container, expanded_key, &args->expanded);
    gwy_container_gis_enum_by_name(container, logical_key, &args->logical);

    for (i = 0; i < NQUANTITIES; i++) {
        RangeRecord *rr = args->ranges + i;
        gchar buf[sizeof(quantity_key) + 10];

        g_snprintf(buf, sizeof(buf), "%s%u", quantity_key, i+1);
        gwy_container_gis_string_by_name(container, buf,
                                         (const guchar**)&rr->quantity);
    }

    args->ranges_history = g_hash_table_new_full(g_str_hash, g_str_equal,
                                                 NULL, range_record_free);
    filename = g_build_filename(gwy_get_user_dir(), "grain_filter", "ranges",
                                NULL);
    if (g_file_get_contents(filename, &buffer, &size, NULL)) {
        gchar *p = buffer, *line;
        for (line = gwy_str_next_line(&p); line; line = gwy_str_next_line(&p)) {
            g_strstrip(line);
            if (*line) {
                GwyGrainValue *gvalue;
                RangeRecord *rr;
                gchar *s = line, *end;
                gdouble lower, upper;

                lower = g_ascii_strtod(s, &end);
                s = end;
                upper = g_ascii_strtod(s, &end);
                if (end == s) {
                    g_warning("Invalid grain_filter range record: %s.", line);
                    continue;
                }
                s = end;
                g_strstrip(s);
                if (!(gvalue = gwy_inventory_get_item(inventory, s))) {
                    g_warning("Invalid grain_filter range record: %s.", line);
                    continue;
                }

                rr = g_slice_new(RangeRecord);
                rr->lower = lower;
                rr->upper = upper;
                rr->quantity = gwy_resource_get_name(GWY_RESOURCE(gvalue));
                g_hash_table_insert(args->ranges_history,
                                    (gpointer)rr->quantity, rr);
            }
        }
        g_free(buffer);
    }
    g_free(filename);

    gfilter_sanitize_args(args);
}
示例#3
0
static GwyContainer*
text_dump_import(gchar *buffer,
                 gsize size,
                 const gchar *filename,
                 GError **error)
{
    gchar *val, *key, *pos, *line, *title;
    GwyContainer *data;
    GwyDataField *dfield;
    gdouble xreal, yreal;
    gint xres, yres, id;
    GwySIUnit *uxy, *uz;
    const guchar *s;
    gdouble *d;
    gsize n;

    data = gwy_container_new();

    pos = buffer;
    while ((line = gwy_str_next_line(&pos)) && *line) {
        val = strchr(line, '=');
        if (!val || *line != '/') {
            g_warning("Garbage key: %s", line);
            continue;
        }
        if ((gsize)(val - buffer) + 1 > size) {
            g_set_error(error, GWY_MODULE_FILE_ERROR,
                        GWY_MODULE_FILE_ERROR_DATA,
                        _("End of file reached when value was expected."));
            goto fail;
        }
        *val = '\0';
        val++;
        if (!gwy_strequal(val, "[") || !pos || *pos != '[') {
            gwy_debug("<%s>=<%s>", line, val);
            if (*val)
                gwy_container_set_string_by_name(data, line, g_strdup(val));
            else
                gwy_container_remove_by_name(data, line);
            continue;
        }

        g_assert(pos && *pos == '[');
        pos++;
        dfield = NULL;
        gwy_container_gis_object_by_name(data, line, &dfield);

        id = 0;
        sscanf(line, "/%d", &id);

        /* get datafield parameters from already read values, failing back
         * to values of original data field */
        key = g_strconcat(line, "/xres", NULL);
        if (gwy_container_gis_string_by_name(data, key, &s))
            xres = atoi(s);
        else if (dfield)
            xres = gwy_data_field_get_xres(dfield);
        else {
            g_set_error(error, GWY_MODULE_FILE_ERROR,
                        GWY_MODULE_FILE_ERROR_DATA,
                        _("Missing data field width."));
            goto fail;
        }
        g_free(key);

        key = g_strconcat(line, "/yres", NULL);
        if (gwy_container_gis_string_by_name(data, key, &s))
            yres = atoi(s);
        else if (dfield)
            yres = gwy_data_field_get_yres(dfield);
        else {
            g_set_error(error, GWY_MODULE_FILE_ERROR,
                        GWY_MODULE_FILE_ERROR_DATA,
                        _("Missing data field height."));
            goto fail;
        }
        g_free(key);

        key = g_strconcat(line, "/xreal", NULL);
        if (gwy_container_gis_string_by_name(data, key, &s))
            xreal = g_ascii_strtod(s, NULL);
        else if (dfield)
            xreal = gwy_data_field_get_xreal(dfield);
        else {
            g_warning("Missing real data field width.");
            xreal = 1.0;   /* 0 could cause troubles */
        }
        g_free(key);

        key = g_strconcat(line, "/yreal", NULL);
        if (gwy_container_gis_string_by_name(data, key, &s))
            yreal = g_ascii_strtod(s, NULL);
        else if (dfield)
            yreal = gwy_data_field_get_yreal(dfield);
        else {
            g_warning("Missing real data field height.");
            yreal = 1.0;   /* 0 could cause troubles */
        }
        g_free(key);

        if (!(xres > 0 && yres > 0 && xreal > 0 && yreal > 0)) {
            g_set_error(error, GWY_MODULE_FILE_ERROR,
                        GWY_MODULE_FILE_ERROR_DATA,
                        _("Data field dimensions are not positive numbers."));
            goto fail;
        }

        key = g_strconcat(line, "/unit-xy", NULL);
        if (gwy_container_gis_string_by_name(data, key, &s))
            uxy = gwy_si_unit_new((const gchar*)s);
        else if (dfield) {
            uxy = gwy_data_field_get_si_unit_xy(dfield);
            uxy = gwy_si_unit_duplicate(uxy);
        }
        else {
            g_warning("Missing lateral units.");
            uxy = gwy_si_unit_new("m");
        }
        g_free(key);

        key = g_strconcat(line, "/unit-z", NULL);
        if (gwy_container_gis_string_by_name(data, key, &s))
            uz = gwy_si_unit_new((const gchar*)s);
        else if (dfield) {
            uz = gwy_data_field_get_si_unit_z(dfield);
            uz = gwy_si_unit_duplicate(uz);
        }
        else {
            g_warning("Missing value units.");
            uz = gwy_si_unit_new("m");
        }
        g_free(key);

        key = g_strconcat(line, "/title", NULL);
        title = NULL;
        gwy_container_gis_string_by_name(data, key, (const guchar**)&title);
        /* We got the contained string but that would disappear. */
        title = g_strdup(title);
        g_free(key);

        n = xres*yres*sizeof(gdouble);
        if ((gsize)(pos - buffer) + n + 3 > size) {
            g_set_error(error, GWY_MODULE_FILE_ERROR,
                        GWY_MODULE_FILE_ERROR_DATA,
                        _("End of file reached inside a data field."));
            goto fail;
        }
        dfield = GWY_DATA_FIELD(gwy_data_field_new(xres, yres, xreal, yreal,
                                                   FALSE));
        gwy_data_field_set_si_unit_xy(dfield, GWY_SI_UNIT(uxy));
        gwy_object_unref(uxy);
        gwy_data_field_set_si_unit_z(dfield, GWY_SI_UNIT(uz));
        gwy_object_unref(uz);
        d = gwy_data_field_get_data(dfield);
#if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
        memcpy(d, pos, n);
#else
        gwy_memcpy_byte_swap(pos, (guint8*)d,
                             sizeof(gdouble), xres*yres, sizeof(gdouble)-1);
#endif
        pos += n;
        val = gwy_str_next_line(&pos);
        if (!gwy_strequal(val, "]]")) {
            g_set_error(error, GWY_MODULE_FILE_ERROR,
                        GWY_MODULE_FILE_ERROR_DATA,
                        _("Missing end of data field marker."));
            gwy_object_unref(dfield);
            goto fail;
        }
        gwy_container_remove_by_prefix(data, line);
        gwy_container_set_object_by_name(data, line, dfield);
        g_object_unref(dfield);

        if (title) {
            key = g_strconcat(line, "/title", NULL);
            gwy_container_set_string_by_name(data, key, title);
            g_free(key);
        }

        gwy_file_channel_import_log_add(data, id, NULL, filename);
    }
    return data;

fail:
    gwy_container_remove_by_prefix(data, NULL);
    g_object_unref(data);
    return NULL;
}