static void grain_stat(GwyContainer *data, GwyRunType run) { GtkWidget *dialog, *table, *hbox, *button; GwyDataField *dfield, *mfield; GwySIUnit *siunit, *siunit2; GwySIValueFormat *vf, *vf2; gint xres, yres, ngrains; gdouble total_area, area, size, vol_0, vol_min, vol_laplace, bound_len, v; gdouble *values = NULL; gint *grains; GString *str, *str2; GPtrArray *report; const guchar *title; gchar *key, *value; gint row, id; guint i, maxlen; g_return_if_fail(run & STAT_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, GWY_APP_MASK_FIELD, &mfield, GWY_APP_DATA_FIELD_ID, &id, 0); g_return_if_fail(dfield); g_return_if_fail(mfield); report = g_ptr_array_sized_new(20); if (gwy_container_gis_string_by_name(data, "/filename", &title)) { g_ptr_array_add(report, _("File:")); g_ptr_array_add(report, g_strdup(title)); } key = g_strdup_printf("/%d/data/title", id); if (gwy_container_gis_string_by_name(data, key, &title)) { g_ptr_array_add(report, _("Data channel:")); g_ptr_array_add(report, g_strdup(title)); } g_free(key); /* Make empty line in the report */ g_ptr_array_add(report, NULL); g_ptr_array_add(report, NULL); xres = gwy_data_field_get_xres(mfield); yres = gwy_data_field_get_yres(mfield); total_area = gwy_data_field_get_xreal(dfield) *gwy_data_field_get_yreal(dfield); grains = g_new0(gint, xres*yres); ngrains = gwy_data_field_number_grains(mfield, grains); area = grains_get_total_value(dfield, ngrains, grains, &values, GWY_GRAIN_VALUE_PROJECTED_AREA); size = grains_get_total_value(dfield, ngrains, grains, &values, GWY_GRAIN_VALUE_EQUIV_SQUARE_SIDE); vol_0 = grains_get_total_value(dfield, ngrains, grains, &values, GWY_GRAIN_VALUE_VOLUME_0); vol_min = grains_get_total_value(dfield, ngrains, grains, &values, GWY_GRAIN_VALUE_VOLUME_MIN); vol_laplace = grains_get_total_value(dfield, ngrains, grains, &values, GWY_GRAIN_VALUE_VOLUME_LAPLACE); bound_len = grains_get_total_value(dfield, ngrains, grains, &values, GWY_GRAIN_VALUE_FLAT_BOUNDARY_LENGTH); g_free(values); g_free(grains); dialog = gtk_dialog_new_with_buttons(_("Grain Statistics"), NULL, 0, GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL); gwy_help_add_to_proc_dialog(GTK_DIALOG(dialog), GWY_HELP_DEFAULT); table = gtk_table_new(10, 2, FALSE); gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), table); gtk_container_set_border_width(GTK_CONTAINER(table), 4); row = 0; str = g_string_new(NULL); str2 = g_string_new(NULL); g_string_printf(str, "%d", ngrains); add_report_row(GTK_TABLE(table), &row, _("Number of grains:"), str->str, str->str, report); siunit = gwy_data_field_get_si_unit_xy(dfield); siunit2 = gwy_si_unit_power(siunit, 2, NULL); v = area; vf = gwy_si_unit_get_format_with_digits(siunit2, GWY_SI_UNIT_FORMAT_VFMARKUP, v, 3, NULL); vf2 = gwy_si_unit_get_format_with_digits(siunit2, GWY_SI_UNIT_FORMAT_PLAIN, v, 3, NULL); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); g_string_printf(str2, "%.*f %s", vf2->precision, v/vf2->magnitude, vf2->units); add_report_row(GTK_TABLE(table), &row, _("Total projected area (abs.):"), str->str, str2->str, report); g_string_printf(str, "%.2f %%", 100.0*area/total_area); add_report_row(GTK_TABLE(table), &row, _("Total projected area (rel.):"), str->str, str->str, report); v = area/ngrains; gwy_si_unit_get_format_with_digits(siunit2, GWY_SI_UNIT_FORMAT_VFMARKUP, v, 3, vf); gwy_si_unit_get_format_with_digits(siunit2, GWY_SI_UNIT_FORMAT_PLAIN, v, 3, vf2); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); g_string_printf(str2, "%.*f %s", vf2->precision, v/vf2->magnitude, vf2->units); add_report_row(GTK_TABLE(table), &row, _("Mean grain area:"), str->str, str2->str, report); v = size/ngrains; gwy_si_unit_get_format_with_digits(siunit, GWY_SI_UNIT_FORMAT_VFMARKUP, v, 3, vf); gwy_si_unit_get_format_with_digits(siunit, GWY_SI_UNIT_FORMAT_PLAIN, v, 3, vf2); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); g_string_printf(str2, "%.*f %s", vf2->precision, v/vf2->magnitude, vf2->units); add_report_row(GTK_TABLE(table), &row, _("Mean grain size:"), str->str, str2->str, report); siunit = gwy_data_field_get_si_unit_z(dfield); gwy_si_unit_multiply(siunit2, siunit, siunit2); v = vol_0; gwy_si_unit_get_format_with_digits(siunit2, GWY_SI_UNIT_FORMAT_VFMARKUP, v, 3, vf); gwy_si_unit_get_format_with_digits(siunit2, GWY_SI_UNIT_FORMAT_PLAIN, v, 3, vf2); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); g_string_printf(str2, "%.*f %s", vf2->precision, v/vf2->magnitude, vf2->units); add_report_row(GTK_TABLE(table), &row, _("Total grain volume (zero):"), str->str, str2->str, report); v = vol_min; gwy_si_unit_get_format_with_digits(siunit2, GWY_SI_UNIT_FORMAT_VFMARKUP, v, 3, vf); gwy_si_unit_get_format_with_digits(siunit2, GWY_SI_UNIT_FORMAT_PLAIN, v, 3, vf2); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); g_string_printf(str2, "%.*f %s", vf2->precision, v/vf2->magnitude, vf2->units); add_report_row(GTK_TABLE(table), &row, _("Total grain volume (minimum):"), str->str, str2->str, report); v = vol_laplace; gwy_si_unit_get_format_with_digits(siunit2, GWY_SI_UNIT_FORMAT_VFMARKUP, v, 3, vf); gwy_si_unit_get_format_with_digits(siunit2, GWY_SI_UNIT_FORMAT_PLAIN, v, 3, vf2); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); g_string_printf(str2, "%.*f %s", vf2->precision, v/vf2->magnitude, vf2->units); add_report_row(GTK_TABLE(table), &row, _("Total grain volume (laplacian):"), str->str, str2->str, report); v = bound_len; gwy_si_unit_get_format_with_digits(siunit, GWY_SI_UNIT_FORMAT_VFMARKUP, v, 3, vf); gwy_si_unit_get_format_with_digits(siunit, GWY_SI_UNIT_FORMAT_PLAIN, v, 3, vf2); g_string_printf(str, "%.*f %s", vf->precision, v/vf->magnitude, vf->units); g_string_printf(str2, "%.*f %s", vf2->precision, v/vf2->magnitude, vf2->units); add_report_row(GTK_TABLE(table), &row, _("Total projected boundary length:"), str->str, str2->str, report); gwy_si_unit_value_format_free(vf2); gwy_si_unit_value_format_free(vf); g_object_unref(siunit2); maxlen = 0; for (i = 0; i < report->len/2; i++) { key = (gchar*)g_ptr_array_index(report, 2*i); if (key) maxlen = MAX(strlen(key), maxlen); } g_string_truncate(str, 0); g_string_append(str, _("Grain Statistics")); g_string_append(str, "\n\n"); for (i = 0; i < report->len/2; i++) { key = (gchar*)g_ptr_array_index(report, 2*i); if (key) { value = (gchar*)g_ptr_array_index(report, 2*i + 1); g_string_append_printf(str, "%-*s %s\n", maxlen+1, key, value); g_free(value); } else g_string_append_c(str, '\n'); } g_ptr_array_free(report, TRUE); g_object_set_data(G_OBJECT(dialog), "report", str->str); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 0); button = grain_stats_add_aux_button(hbox, GTK_STOCK_SAVE, _("Save table to a file")); g_signal_connect_swapped(button, "clicked", G_CALLBACK(grain_stat_save), dialog); button = grain_stats_add_aux_button(hbox, GTK_STOCK_COPY, _("Copy table to clipboard")); g_signal_connect_swapped(button, "clicked", G_CALLBACK(grain_stat_copy), dialog); gtk_widget_show_all(dialog); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); g_string_free(str2, TRUE); g_string_free(str, TRUE); }
static 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); }
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; }