static gboolean maskcor_kernel_filter(GwyContainer *data, gint id, gpointer user_data) { GwyAppDataId *object = (GwyAppDataId*)user_data; GwyDataField *kernel, *dfield; GQuark quark; quark = gwy_app_get_data_key_for_id(id); kernel = GWY_DATA_FIELD(gwy_container_get_object(data, quark)); data = gwy_app_data_browser_get(object->datano); quark = gwy_app_get_data_key_for_id(object->id); dfield = GWY_DATA_FIELD(gwy_container_get_object(data, quark)); if (gwy_data_field_get_xreal(kernel) <= gwy_data_field_get_xreal(dfield)/4 && gwy_data_field_get_yreal(kernel) <= gwy_data_field_get_yreal(dfield)/4 && !gwy_data_field_check_compatibility(kernel, dfield, GWY_DATA_COMPATIBILITY_LATERAL | GWY_DATA_COMPATIBILITY_VALUE)) return TRUE; return FALSE; }
static void flip_xy(GwyDataField *source, GwyDataField *dest, gboolean minor) { gint xres, yres, i, j; gdouble *dd; const gdouble *sd; xres = gwy_data_field_get_xres(source); yres = gwy_data_field_get_yres(source); gwy_data_field_resample(dest, yres, xres, GWY_INTERPOLATION_NONE); sd = gwy_data_field_get_data_const(source); dd = gwy_data_field_get_data(dest); if (minor) { for (i = 0; i < xres; i++) { for (j = 0; j < yres; j++) { dd[i*yres + j] = sd[j*xres + (xres - 1 - i)]; } } } else { for (i = 0; i < xres; i++) { for (j = 0; j < yres; j++) { dd[i*yres + (yres - 1 - j)] = sd[j*xres + i]; } } } gwy_data_field_set_xreal(dest, gwy_data_field_get_yreal(source)); gwy_data_field_set_yreal(dest, gwy_data_field_get_xreal(source)); }
static gboolean outliers(GwyContainer *data, GwyRunType run) { GObject *maskfield; GwyDataField *dfield; gdouble thresh; g_assert(run & OUTLIERS_RUN_MODES); dfield = GWY_DATA_FIELD(gwy_container_get_object_by_name(data, "/0/data")); gwy_app_undo_checkpoint(data, "/0/mask", NULL); if (!gwy_container_gis_object_by_name(data, "/0/mask", &maskfield)) { maskfield = gwy_data_field_new(gwy_data_field_get_xres(dfield), gwy_data_field_get_yres(dfield), gwy_data_field_get_xreal(dfield), gwy_data_field_get_yreal(dfield), TRUE); gwy_container_set_object_by_name(data, "/0/mask", maskfield); g_object_unref(maskfield); } thresh = 3.0; gwy_data_field_mask_outliers(dfield, GWY_DATA_FIELD(maskfield), thresh); return TRUE; }
static void compute_slopes(GwyDataField *dfield, gint kernel_size, GwyDataField *xder, GwyDataField *yder) { gint xres, yres; xres = gwy_data_field_get_xres(dfield); yres = gwy_data_field_get_yres(dfield); if (kernel_size) { GwyPlaneFitQuantity quantites[] = { GWY_PLANE_FIT_BX, GWY_PLANE_FIT_BY }; GwyDataField *fields[2]; fields[0] = xder; fields[1] = yder; gwy_data_field_fit_local_planes(dfield, kernel_size, 2, quantites, fields); gwy_data_field_multiply(xder, xres/gwy_data_field_get_xreal(dfield)); gwy_data_field_multiply(yder, yres/gwy_data_field_get_yreal(dfield)); } else gwy_data_field_filter_slope(dfield, xder, yder); }
static gboolean curvature_set_selection(GwyDataField *dfield, const Intersection *i1, const Intersection *i2, GwySelection *selection) { gdouble xreal, yreal; gdouble xy[4]; gint xres, yres; guint i; xreal = gwy_data_field_get_xreal(dfield); yreal = gwy_data_field_get_yreal(dfield); xres = gwy_data_field_get_xres(dfield); yres = gwy_data_field_get_yres(dfield); for (i = 0; i < 2; i++) { xy[0] = CLAMP(i1[i].x, 0, xreal*(xres - 1)/xres); xy[1] = CLAMP(i1[i].y, 0, yreal*(yres - 1)/yres); xy[2] = CLAMP(i2[i].x, 0, xreal*(xres - 1)/xres); xy[3] = CLAMP(i2[i].y, 0, yreal*(yres - 1)/yres); gwy_selection_set_object(selection, i, xy); } return TRUE; }
static gboolean prepare_fields(GwyDataField *tipfield, GwyDataField *surface, gint xres, gint yres) { gint xoldres, yoldres; /*set real sizes corresponding to actual data*/ gwy_data_field_set_xreal(tipfield, gwy_data_field_get_xmeasure(surface) *gwy_data_field_get_xres(tipfield)); gwy_data_field_set_yreal(tipfield, gwy_data_field_get_ymeasure(surface) *gwy_data_field_get_yres(tipfield)); /*if user has changed tip size, change it*/ if ((xres != gwy_data_field_get_xres(tipfield)) || (yres != gwy_data_field_get_yres(tipfield))) { xoldres = gwy_data_field_get_xres(tipfield); yoldres = gwy_data_field_get_yres(tipfield); gwy_data_field_resample(tipfield, xres, yres, GWY_INTERPOLATION_NONE); gwy_data_field_set_xreal(tipfield, gwy_data_field_get_xreal(tipfield) /xoldres*xres); gwy_data_field_set_yreal(tipfield, gwy_data_field_get_yreal(tipfield) /yoldres*yres); gwy_data_field_clear(tipfield); return FALSE; } return TRUE; }
static gchar* asc_format_header(GwyContainer *data, GwyDataField *dfield, gboolean *zunit_is_nm) { static const gchar asc_header_template[] = "# File Format = ASCII\n" "# Created by Gwyddion %s\n" "# Original file: %s\n" "# x-pixels = %u\n" "# y-pixels = %u\n" "# x-length = %s\n" "# y-length = %s\n" "# x-offset = %s\n" "# y-offset = %s\n" "# Bit2nm = 1.0\n" "%s" "# Start of Data:\n"; GwySIUnit *zunit; gchar *header, *zunit_str, *zunit_line; gchar xreal_str[G_ASCII_DTOSTR_BUF_SIZE], yreal_str[G_ASCII_DTOSTR_BUF_SIZE], xoff_str[G_ASCII_DTOSTR_BUF_SIZE], yoff_str[G_ASCII_DTOSTR_BUF_SIZE]; const guchar *filename = "NONE"; gdouble xreal, yreal, xoff, yoff; /* XXX: Gwyddion can have lateral dimensions as whatever we want. But * who knows about the SPIP ASC format... */ xreal = gwy_data_field_get_xreal(dfield)/Nanometer; yreal = gwy_data_field_get_yreal(dfield)/Nanometer; xoff = gwy_data_field_get_xoffset(dfield)/Nanometer; yoff = gwy_data_field_get_yoffset(dfield)/Nanometer; zunit = gwy_data_field_get_si_unit_z(dfield); g_ascii_dtostr(xreal_str, G_ASCII_DTOSTR_BUF_SIZE, xreal); g_ascii_dtostr(yreal_str, G_ASCII_DTOSTR_BUF_SIZE, yreal); g_ascii_dtostr(xoff_str, G_ASCII_DTOSTR_BUF_SIZE, xoff); g_ascii_dtostr(yoff_str, G_ASCII_DTOSTR_BUF_SIZE, yoff); zunit_str = gwy_si_unit_get_string(zunit, GWY_SI_UNIT_FORMAT_PLAIN); if ((*zunit_is_nm = gwy_strequal(zunit_str, "m"))) zunit_line = g_strdup(""); else zunit_line = g_strdup_printf("# z-unit = %s\n", zunit_str); gwy_container_gis_string_by_name(data, "/filename", &filename); header = g_strdup_printf(asc_header_template, gwy_version_string(), filename, gwy_data_field_get_xres(dfield), gwy_data_field_get_yres(dfield), xreal_str, yreal_str, xoff_str, yoff_str, zunit_line); g_free(zunit_str); g_free(zunit_line); return header; }
static void immerse_detail_cb(GwyDataChooser *chooser, ImmerseControls *controls) { GwyDataField *dfield, *ifield; GwyContainer *data; GQuark quark; GwyAppDataId *object; object = &controls->args->detail; gwy_data_chooser_get_active_id(chooser, object); gwy_debug("data: %d %d", object->datano, object->id); data = gwy_app_data_browser_get(object->datano); gtk_dialog_set_response_sensitive(GTK_DIALOG(controls->dialog), GTK_RESPONSE_OK, data != NULL); gtk_dialog_set_response_sensitive(GTK_DIALOG(controls->dialog), RESPONSE_ESTIMATE, data != NULL); gtk_dialog_set_response_sensitive(GTK_DIALOG(controls->dialog), RESPONSE_REFINE, data != NULL); if (data) { quark = gwy_app_get_data_key_for_id(object->id); dfield = gwy_container_get_object(data, quark); quark = gwy_app_get_data_key_for_id(controls->args->image.id); data = gwy_app_data_browser_get(controls->args->image.datano); ifield = gwy_container_get_object(data, quark); controls->xmax = (gwy_data_field_get_xreal(ifield) - gwy_data_field_get_xreal(dfield) + gwy_data_field_get_xmeasure(ifield)/2.0); controls->ymax = (gwy_data_field_get_yreal(ifield) - gwy_data_field_get_yreal(dfield) + gwy_data_field_get_ymeasure(ifield)/2.0); } immerse_update_detail_pixbuf(controls); immerse_clamp_detail_offset(controls, controls->args->xpos, controls->args->ypos); if (GTK_WIDGET_DRAWABLE(controls->view)) gtk_widget_queue_draw(controls->view); }
static void compute_slopes(GwyDataField *dfield, gint kernel_size, GwyDataField *xder, GwyDataField *yder) { gint xres, yres; xres = gwy_data_field_get_xres(dfield); yres = gwy_data_field_get_yres(dfield); if (kernel_size > 1) { GwyPlaneFitQuantity quantites[] = { GWY_PLANE_FIT_BX, GWY_PLANE_FIT_BY }; GwyDataField *fields[2]; fields[0] = xder; fields[1] = yder; gwy_data_field_fit_local_planes(dfield, kernel_size, 2, quantites, fields); } else { gint col, row; gdouble *xd, *yd; const gdouble *data; gdouble d; data = gwy_data_field_get_data_const(dfield); xd = gwy_data_field_get_data(xder); yd = gwy_data_field_get_data(yder); for (row = 0; row < yres; row++) { for (col = 0; col < xres; col++) { if (!col) d = data[row*xres + col + 1] - data[row*xres + col]; else if (col == xres-1) d = data[row*xres + col] - data[row*xres + col - 1]; else d = (data[row*xres + col + 1] - data[row*xres + col - 1])/2; *(xd++) = d; if (!row) d = data[row*xres + xres + col] - data[row*xres + col]; else if (row == yres-1) d = data[row*xres + col] - data[row*xres - xres + col]; else d = (data[row*xres + xres + col] - data[row*xres - xres + col])/2; *(yd++) = d; } } } gwy_data_field_multiply(xder, xres/gwy_data_field_get_xreal(dfield)); gwy_data_field_multiply(yder, yres/gwy_data_field_get_yreal(dfield)); }
static void gwy_data_view_make_pixmap(GwyDataView *data_view) { GtkWidget *widget; GwyDataField *data_field; gint width, height, scwidth, scheight, src_width, src_height; data_field = GWY_DATA_FIELD( gwy_container_get_object_by_name(data_view->data, "/0/data")); src_width = gwy_data_field_get_xres(data_field); src_height = gwy_data_field_get_yres(data_field); if (!data_view->base_pixbuf) { data_view->base_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, BITS_PER_SAMPLE, src_width, src_height); gwy_debug_objects_creation(G_OBJECT(data_view->base_pixbuf)); } if (data_view->pixbuf) { width = gdk_pixbuf_get_width(data_view->pixbuf); height = gdk_pixbuf_get_height(data_view->pixbuf); } else width = height = -1; widget = GTK_WIDGET(data_view); data_view->zoom = MIN((gdouble)widget->allocation.width/src_width, (gdouble)widget->allocation.height/src_height); data_view->newzoom = data_view->zoom; scwidth = floor(src_width * data_view->zoom + 0.000001); scheight = floor(src_height * data_view->zoom + 0.000001); data_view->xmeasure = gwy_data_field_get_xreal(data_field)/scwidth; data_view->ymeasure = gwy_data_field_get_yreal(data_field)/scheight; data_view->xoff = (widget->allocation.width - scwidth)/2; data_view->yoff = (widget->allocation.height - scheight)/2; if (scwidth != width || scheight != height) { gwy_object_unref(data_view->pixbuf); data_view->pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, BITS_PER_SAMPLE, scwidth, scheight); gwy_debug_objects_creation(G_OBJECT(data_view->pixbuf)); gdk_pixbuf_fill(data_view->pixbuf, 0x00000000); gwy_data_view_paint(data_view); } }
static GwyDataField* rhkspm32_read_data(RHKPage *rhkpage) { GwyDataField *dfield; const guint16 *p; GwySIUnit *siunit; gdouble *data; const gchar *s; gdouble q; gint power10; guint i, j, xres, yres; p = (const guint16*)(rhkpage->buffer + rhkpage->data_offset); xres = rhkpage->xres; yres = rhkpage->yres; // the scales are no longer gurunteed to be positive, // so they must be "fixed" here (to enable spectra) dfield = gwy_data_field_new(xres, yres, xres*fabs(rhkpage->x.scale), yres*fabs(rhkpage->y.scale), FALSE); data = gwy_data_field_get_data(dfield); for (i = 0; i < yres; i++) { for (j = 0; j < xres; j++) data[i*xres + xres-1 - j] = GINT16_FROM_LE(p[i*xres + j]); } siunit = gwy_data_field_get_si_unit_xy(dfield); gwy_si_unit_set_from_string_parse(siunit, rhkpage->x.units, &power10); if (power10) { q = pow10(power10); gwy_data_field_set_xreal(dfield, q*gwy_data_field_get_xreal(dfield)); gwy_data_field_set_yreal(dfield, q*gwy_data_field_get_yreal(dfield)); } siunit = gwy_data_field_get_si_unit_z(dfield); s = rhkpage->z.units; /* Fix some silly units */ if (gwy_strequal(s, "N/sec")) s = "s^-1"; gwy_si_unit_set_from_string_parse(siunit, s, &power10); q = pow10(power10); gwy_data_field_multiply(dfield, q*fabs(rhkpage->z.scale)); gwy_data_field_add(dfield, q*rhkpage->z.offset); return dfield; }
/** * gwy_set_data_preview_size: * @data_view: A data view used for module preview. * @max_size: Maximum allowed @data_view size (width and height). * * Sets up data view zoom to not exceed specified size. * * Before calling this function, data keys have be set, data fields and layers * have to be present and physically square mode set in the container. * Sizing of both pixel-wise square and physically square displays is performed * correctly. * * Since: 2.7 **/ void gwy_set_data_preview_size(GwyDataView *data_view, gint max_size) { GwyContainer *container; GwyDataField *data_field; GwyPixmapLayer *layer; gdouble zoomval, scale, xreal, yreal; gboolean realsquare; gint xres, yres; const gchar *prefix; gchar *key; g_return_if_fail(GWY_IS_DATA_VIEW(data_view)); g_return_if_fail(max_size >= 2); container = gwy_data_view_get_data(data_view); g_return_if_fail(GWY_IS_CONTAINER(container)); layer = gwy_data_view_get_base_layer(data_view); g_return_if_fail(GWY_IS_PIXMAP_LAYER(layer)); prefix = gwy_pixmap_layer_get_data_key(layer); g_return_if_fail(prefix); data_field = gwy_container_get_object_by_name(container, prefix); g_return_if_fail(GWY_IS_DATA_FIELD(data_field)); prefix = gwy_data_view_get_data_prefix(data_view); g_return_if_fail(prefix); key = g_strconcat(prefix, "/realsquare", NULL); realsquare = FALSE; gwy_container_gis_boolean_by_name(container, key, &realsquare); g_free(key); xres = gwy_data_field_get_xres(data_field); yres = gwy_data_field_get_yres(data_field); if (!realsquare) zoomval = max_size/(gdouble)MAX(xres, yres); else { xreal = gwy_data_field_get_xreal(data_field); yreal = gwy_data_field_get_yreal(data_field); scale = MAX(xres/xreal, yres/yreal); zoomval = max_size/(scale*MAX(xreal, yreal)); } gwy_data_view_set_zoom(data_view, zoomval); }
static void apply(GwyUnitoolState *state) { static const gchar *field_names[] = { "/0/data", "/0/mask", "/0/show" }; GtkWidget *data_window; GwyDataView *data_view; GwyContainer *data; GwyDataField *dfield; gint ximin, yimin, ximax, yimax; gdouble sel[4]; gsize i; if (!gwy_vector_layer_get_selection(state->layer, sel)) return; data_view = GWY_DATA_VIEW(GWY_DATA_VIEW_LAYER(state->layer)->parent); data = gwy_data_view_get_data(data_view); data = GWY_CONTAINER(gwy_serializable_duplicate(G_OBJECT(data))); gwy_app_clean_up_data(data); for (i = 0; i < G_N_ELEMENTS(field_names); i++) { if (!gwy_container_gis_object_by_name(data, field_names[i], (GObject**)&dfield)) continue; ximin = gwy_data_field_rtoj(dfield, sel[0]); yimin = gwy_data_field_rtoi(dfield, sel[1]); ximax = gwy_data_field_rtoj(dfield, sel[2]) + 1; yimax = gwy_data_field_rtoi(dfield, sel[3]) + 1; gwy_data_field_set_xreal(dfield, (ximax - ximin) *gwy_data_field_get_xreal(dfield) /gwy_data_field_get_xres(dfield)); gwy_data_field_set_yreal(dfield, (yimax - yimin) *gwy_data_field_get_yreal(dfield) /gwy_data_field_get_yres(dfield)); gwy_data_field_resize(dfield, ximin, yimin, ximax, yimax); } data_window = gwy_app_data_window_create(data); gwy_app_data_window_set_untitled(GWY_DATA_WINDOW(data_window), NULL); gwy_vector_layer_unselect(state->layer); gwy_data_view_update(data_view); gwy_debug("%d %d", gwy_data_field_get_xres(dfield), gwy_data_field_get_yres(dfield)); }
static void gwy_app_file_chooser_describe_channel(GwyContainer *container, gint id, GString *str) { GwyDataField *dfield; GwySIUnit *siunit; GwySIValueFormat *vf; GQuark quark; gint xres, yres; gdouble xreal, yreal; gchar *s; g_string_truncate(str, 0); quark = gwy_app_get_data_key_for_id(id); dfield = GWY_DATA_FIELD(gwy_container_get_object(container, quark)); g_return_if_fail(GWY_IS_DATA_FIELD(dfield)); s = gwy_app_get_data_field_title(container, id); g_string_append(str, s); g_free(s); siunit = gwy_data_field_get_si_unit_z(dfield); s = gwy_si_unit_get_string(siunit, GWY_SI_UNIT_FORMAT_MARKUP); g_string_append_printf(str, " [%s]\n", s); g_free(s); xres = gwy_data_field_get_xres(dfield); yres = gwy_data_field_get_yres(dfield); g_string_append_printf(str, "%d×%d px\n", xres, yres); xreal = gwy_data_field_get_xreal(dfield); yreal = gwy_data_field_get_yreal(dfield); siunit = gwy_data_field_get_si_unit_xy(dfield); vf = gwy_si_unit_get_format(siunit, GWY_SI_UNIT_FORMAT_VFMARKUP, sqrt(xreal*yreal), NULL); g_string_append_printf(str, "%.*f×%.*f%s%s", vf->precision, xreal/vf->magnitude, vf->precision, yreal/vf->magnitude, (vf->units && *vf->units) ? " " : "", vf->units); gwy_si_unit_value_format_free(vf); }
static void immerse_update_detail_pixbuf(ImmerseControls *controls) { GwyContainer *data; GwyDataField *dfield; GwyGradient *gradient; GdkPixbuf *pixbuf; const guchar *name; gchar *key; GQuark quark; gint w, h, xres, yres; GWY_OBJECT_UNREF(controls->detail); data = gwy_app_data_browser_get(controls->args->detail.datano); if (!data) return; quark = gwy_app_get_data_key_for_id(controls->args->detail.id); dfield = gwy_container_get_object(data, quark); gwy_data_view_coords_real_to_xy(GWY_DATA_VIEW(controls->view), gwy_data_field_get_xreal(dfield), gwy_data_field_get_yreal(dfield), &w, &h); gwy_debug("%dx%d", w, h); w = MAX(w, 2); h = MAX(h, 2); key = g_strdup_printf("/%d/base/palette", controls->args->image.id); name = NULL; data = gwy_app_data_browser_get(controls->args->image.datano); gwy_container_gis_string_by_name(data, key, &name); g_free(key); gradient = gwy_gradients_get_gradient(name); /* Handle real-square properly by using an intermediate * pixel-square pixbuf with sufficient resolution */ xres = gwy_data_field_get_xres(dfield); yres = gwy_data_field_get_yres(dfield); pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, xres, yres); gwy_pixbuf_draw_data_field(pixbuf, dfield, gradient); controls->detail = gdk_pixbuf_scale_simple(pixbuf, w, h, GDK_INTERP_TILES); g_object_unref(pixbuf); }
static void rotate_datafield(GwyDataField *dfield, RotateArgs *args) { gint xres, yres, xborder, yborder; gdouble xreal, yreal, phi, min; GwyDataField *df; if (!args->expand) { gwy_data_field_rotate(dfield, args->angle, args->interp); return; } xres = gwy_data_field_get_xres(dfield); yres = gwy_data_field_get_yres(dfield); xreal = gwy_data_field_get_xreal(dfield); yreal = gwy_data_field_get_yreal(dfield); min = gwy_data_field_get_min(dfield); phi = args->angle; xborder = fabs(xres/2.0 * cos(phi)) + fabs(yres/2.0 * sin(phi)); xborder -= xres/2; yborder = fabs(yres/2.0 * cos(phi)) + fabs(xres/2.0 * sin(phi)); yborder -= yres/2; df = gwy_data_field_new(xres + fabs(2*xborder), yres + fabs(2*yborder), 1.0, 1.0, FALSE); gwy_data_field_fill(df, min); gwy_data_field_area_copy(dfield, df, 0, 0, xres, yres, fabs(xborder), fabs(yborder)); gwy_data_field_rotate(df, args->angle, args->interp); gwy_data_field_resample(dfield, xres + 2*xborder, yres + 2*yborder, GWY_INTERPOLATION_NONE); if (xborder <= 0) gwy_data_field_area_copy(df, dfield, fabs(2*xborder), 0, xres + 2*xborder, yres + 2*yborder, 0, 0); else { if (yborder <= 0) gwy_data_field_area_copy(df, dfield, 0, fabs(2*yborder), xres + 2*xborder, yres + 2*yborder, 0, 0); else gwy_data_field_area_copy(df, dfield, 0, 0, xres + 2*xborder, yres + 2*yborder, 0, 0); } gwy_data_field_set_xreal(dfield, xreal*(xres + 2.0*xborder)/xres); gwy_data_field_set_yreal(dfield, yreal*(yres + 2.0*yborder)/yres); g_object_unref(df); }
static void gwy_recent_file_update_thumbnail(GwyRecentFile *rf, GwyContainer *data, gint hint, GdkPixbuf *use_this_pixbuf) { GwyDataField *dfield; GdkPixbuf *pixbuf; GStatBuf st; gchar *fnm; GwySIUnit *siunit; GwySIValueFormat *vf; gdouble xreal, yreal; gchar str_mtime[22]; gchar str_size[22]; gchar str_width[22]; gchar str_height[22]; GError *err = NULL; GQuark quark; gint id; g_return_if_fail(GWY_CONTAINER(data)); if (use_this_pixbuf) { /* If we are given a pixbuf, hint must be the ultimate channel id. * We also ignore the thnumbnail state then. */ g_return_if_fail(GDK_IS_PIXBUF(use_this_pixbuf)); id = hint; pixbuf = g_object_ref(use_this_pixbuf); } else { pixbuf = NULL; id = gwy_recent_file_find_some_channel(data, hint); if (rf->file_state == FILE_STATE_UNKNOWN) gwy_app_recent_file_try_load_thumbnail(rf); } /* Find channel with the lowest id not smaller than hint */ if (id == G_MAXINT) { gwy_debug("There is no channel in the file, cannot make thumbnail."); return; } if (g_stat(rf->file_sys, &st) != 0) { g_warning("File <%s> was just loaded or saved, but it doesn't seem to " "exist any more: %s", rf->file_utf8, g_strerror(errno)); return; } if ((gulong)rf->file_mtime == (gulong)st.st_mtime) return; quark = gwy_app_get_data_key_for_id(id); dfield = GWY_DATA_FIELD(gwy_container_get_object(data, quark)); g_return_if_fail(GWY_IS_DATA_FIELD(dfield)); rf->file_mtime = st.st_mtime; rf->file_size = st.st_size; rf->image_width = gwy_data_field_get_xres(dfield); rf->image_height = gwy_data_field_get_yres(dfield); xreal = gwy_data_field_get_xreal(dfield); yreal = gwy_data_field_get_yreal(dfield); siunit = gwy_data_field_get_si_unit_xy(dfield); vf = gwy_si_unit_get_format(siunit, GWY_SI_UNIT_FORMAT_VFMARKUP, sqrt(xreal*yreal), NULL); g_free(rf->image_real_size); rf->image_real_size = g_strdup_printf("%.*f×%.*f%s%s", vf->precision, xreal/vf->magnitude, vf->precision, yreal/vf->magnitude, (vf->units && *vf->units) ? " " : "", vf->units); rf->file_state = FILE_STATE_OK; gwy_si_unit_value_format_free(vf); if (g_str_has_prefix(rf->file_sys, gwy_recent_file_thumbnail_dir())) { gchar c; c = rf->file_sys[strlen(gwy_recent_file_thumbnail_dir())]; if (!c || G_IS_DIR_SEPARATOR(c)) return; } if (!pixbuf) pixbuf = gwy_app_get_channel_thumbnail(data, id, TMS_NORMAL_THUMB_SIZE, TMS_NORMAL_THUMB_SIZE); g_snprintf(str_mtime, sizeof(str_mtime), "%lu", rf->file_mtime); g_snprintf(str_size, sizeof(str_size), "%lu", rf->file_size); g_snprintf(str_width, sizeof(str_width), "%d", rf->image_width); g_snprintf(str_height, sizeof(str_height), "%d", rf->image_height); /* invent an unique temporary name for atomic save * FIXME: rough, but works on Win32 */ fnm = g_strdup_printf("%s.%u", rf->thumb_sys, getpid()); if (!gdk_pixbuf_save(pixbuf, fnm, "png", &err, KEY_SOFTWARE, PACKAGE_NAME, KEY_THUMB_URI, rf->file_uri, KEY_THUMB_MTIME, str_mtime, KEY_THUMB_FILESIZE, str_size, KEY_THUMB_IMAGE_WIDTH, str_width, KEY_THUMB_IMAGE_HEIGHT, str_height, KEY_THUMB_GWY_REAL_SIZE, rf->image_real_size, NULL)) { g_clear_error(&err); rf->thumb_state = FILE_STATE_FAILED; } #ifndef G_OS_WIN32 chmod(fnm, 0600); #endif g_unlink(rf->thumb_sys); if (g_rename(fnm, rf->thumb_sys) != 0) { g_unlink(fnm); rf->thumb_state = FILE_STATE_FAILED; rf->thumb_mtime = 0; } else { rf->thumb_state = FILE_STATE_UNKNOWN; /* force reload */ rf->thumb_mtime = rf->file_mtime; } g_free(fnm); gwy_object_unref(rf->pixbuf); g_object_unref(pixbuf); }
static void immerse_search(ImmerseControls *controls, gint search_type) { GwyDataField *dfield, *dfieldsub, *ifield, *iarea; gdouble wr, hr, xpos, ypos, deltax, deltay; gint w, h, xfrom, xto, yfrom, yto, ixres, iyres, col, row; GwyContainer *data; GQuark quark; data = gwy_app_data_browser_get(controls->args->detail.datano); quark = gwy_app_get_data_key_for_id(controls->args->detail.id); dfield = gwy_container_get_object(data, quark); data = gwy_app_data_browser_get(controls->args->image.datano); quark = gwy_app_get_data_key_for_id(controls->args->image.id); ifield = gwy_container_get_object(data, quark); ixres = gwy_data_field_get_xres(ifield); iyres = gwy_data_field_get_yres(ifield); wr = gwy_data_field_get_xreal(dfield)/gwy_data_field_get_xmeasure(ifield); hr = gwy_data_field_get_yreal(dfield)/gwy_data_field_get_ymeasure(ifield); if (wr*hr < 6.0) { g_warning("Detail image is too small for correlation"); return; } w = GWY_ROUND(MAX(wr, 1.0)); h = GWY_ROUND(MAX(hr, 1.0)); gwy_debug("w: %d, h: %d", w, h); g_assert(w <= ixres && h <= iyres); if (search_type == RESPONSE_REFINE) { xfrom = gwy_data_field_rtoj(ifield, controls->args->xpos); yfrom = gwy_data_field_rtoi(ifield, controls->args->ypos); /* Calculate the area we will search the detail in */ deltax = improve_search_window(w, ixres); deltay = improve_search_window(h, iyres); gwy_debug("deltax: %g, deltay: %g", deltax, deltay); xto = MIN(xfrom + w + deltax, ixres); yto = MIN(yfrom + h + deltay, iyres); xfrom = MAX(xfrom - deltax, 0); yfrom = MAX(yfrom - deltay, 0); } else { xfrom = yfrom = 0; xto = ixres; yto = iyres; } gwy_debug("x: %d..%d, y: %d..%d", xfrom, xto, yfrom, yto); /* Cut out only the interesting part from the image data field */ if (xfrom == 0 && yfrom == 0 && xto == ixres && yto == iyres) iarea = g_object_ref(ifield); else iarea = gwy_data_field_area_extract(ifield, xfrom, yfrom, xto - xfrom, yto - yfrom); dfieldsub = gwy_data_field_new_resampled(dfield, w, h, GWY_INTERPOLATION_LINEAR); immerse_correlate(iarea, dfieldsub, &col, &row); gwy_debug("[c] col: %d, row: %d", col, row); col += xfrom; row += yfrom; xpos = gwy_data_field_jtor(dfieldsub, col + 0.5); ypos = gwy_data_field_itor(dfieldsub, row + 0.5); g_object_unref(iarea); g_object_unref(dfieldsub); gwy_debug("[C] col: %d, row: %d", col, row); /* Upsample and refine */ xfrom = MAX(col - 1, 0); yfrom = MAX(row - 1, 0); xto = MIN(col + w + 1, ixres); yto = MIN(row + h + 1, iyres); gwy_debug("x: %d..%d, y: %d..%d", xfrom, xto, yfrom, yto); iarea = gwy_data_field_area_extract(ifield, xfrom, yfrom, xto - xfrom, yto - yfrom); wr = gwy_data_field_get_xreal(iarea)/gwy_data_field_get_xmeasure(dfield); hr = gwy_data_field_get_yreal(iarea)/gwy_data_field_get_ymeasure(dfield); gwy_data_field_resample(iarea, GWY_ROUND(wr), GWY_ROUND(hr), GWY_INTERPOLATION_LINEAR); immerse_correlate(iarea, dfield, &col, &row); gwy_debug("[U] col: %d, row: %d", col, row); xpos = gwy_data_field_jtor(dfield, col + 0.5) + gwy_data_field_jtor(ifield, xfrom); ypos = gwy_data_field_itor(dfield, row + 0.5) + gwy_data_field_itor(ifield, yfrom); g_object_unref(iarea); immerse_clamp_detail_offset(controls, xpos, ypos); }
static void immerse_do(ImmerseArgs *args) { GwyDataField *resampled, *image, *detail, *result; GwyContainer *data; gint newid; gint kxres, kyres; gint x, y, w, h; gdouble iavg, davg; GQuark quark; data = gwy_app_data_browser_get(args->image.datano); quark = gwy_app_get_data_key_for_id(args->image.id); image = GWY_DATA_FIELD(gwy_container_get_object(data, quark)); data = gwy_app_data_browser_get(args->detail.datano); quark = gwy_app_get_data_key_for_id(args->detail.id); detail = GWY_DATA_FIELD(gwy_container_get_object(data, quark)); davg = gwy_data_field_get_avg(detail); kxres = gwy_data_field_get_xres(detail); kyres = gwy_data_field_get_yres(detail); switch (args->sampling) { case GWY_IMMERSE_SAMPLING_DOWN: result = gwy_data_field_duplicate(image); x = gwy_data_field_rtoj(image, args->xpos); y = gwy_data_field_rtoi(image, args->ypos); w = GWY_ROUND(gwy_data_field_get_xreal(detail) /gwy_data_field_get_xmeasure(image)); h = GWY_ROUND(gwy_data_field_get_yreal(detail) /gwy_data_field_get_ymeasure(image)); w = MAX(w, 1); h = MAX(h, 1); gwy_debug("w: %d, h: %d", w, h); resampled = gwy_data_field_new_resampled(detail, w, h, GWY_INTERPOLATION_LINEAR); if (args->leveling == GWY_IMMERSE_LEVEL_MEAN) { iavg = gwy_data_field_area_get_avg(result, NULL, x, y, w, h); gwy_data_field_add(resampled, iavg - davg); } gwy_data_field_area_copy(resampled, result, 0, 0, w, h, x, y); g_object_unref(resampled); break; case GWY_IMMERSE_SAMPLING_UP: w = GWY_ROUND(gwy_data_field_get_xreal(image) /gwy_data_field_get_xmeasure(detail)); h = GWY_ROUND(gwy_data_field_get_yreal(image) /gwy_data_field_get_ymeasure(detail)); gwy_debug("w: %d, h: %d", w, h); result = gwy_data_field_new_resampled(image, w, h, GWY_INTERPOLATION_LINEAR); x = gwy_data_field_rtoj(result, args->xpos); y = gwy_data_field_rtoi(result, args->ypos); if (args->leveling == GWY_IMMERSE_LEVEL_MEAN) { iavg = gwy_data_field_area_get_avg(result, NULL, x, y, kxres, kyres); gwy_data_field_area_copy(detail, result, 0, 0, kxres, kyres, x, y); gwy_data_field_area_add(result, x, y, kxres, kyres, iavg - davg); } else gwy_data_field_area_copy(detail, result, 0, 0, kxres, kyres, x, y); break; default: g_return_if_reached(); break; } gwy_app_data_browser_get_current(GWY_APP_CONTAINER, &data, 0); newid = gwy_app_data_browser_add_data_field(result, data, TRUE); gwy_app_set_data_field_title(data, newid, _("Immersed detail")); g_object_unref(result); gwy_app_channel_log_add_proc(data, args->image.id, newid); }
/* Does not include x and y offsets of the data field */ static gboolean curvature_calculate(GwyDataField *dfield, GwyDataField *mask, const CurvatureArgs *args, gdouble *params, Intersection *i1, Intersection *i2) { enum { DEGREE = 2 }; enum { A, BX, CXX, BY, CXY, CYY, NTERMS }; gint term_powers[2*NTERMS]; gdouble coeffs[NTERMS], ccoeffs[NTERMS]; gdouble xreal, yreal, qx, qy, q, mx, my; gint xres, yres, i, j, k; gboolean ok; k = 0; g_assert(NTERMS == (DEGREE + 1)*(DEGREE + 2)/2); for (i = 0; i <= DEGREE; i++) { for (j = 0; j <= DEGREE - i; j++) { term_powers[k++] = j; term_powers[k++] = i; } } gwy_data_field_fit_poly(dfield, mask, NTERMS, term_powers, args->masking != GWY_MASK_INCLUDE, coeffs); gwy_debug("NORM a=%g, bx=%g, by=%g, cxx=%g, cxy=%g, cyy=%g", coeffs[A], coeffs[BX], coeffs[BY], coeffs[CXX], coeffs[CXY], coeffs[CYY]); /* Transform coeffs from normalized coordinates to coordinates that are * still numerically around 1 but have the right aspect ratio. */ xres = gwy_data_field_get_xres(dfield); yres = gwy_data_field_get_yres(dfield); xreal = gwy_data_field_get_xreal(dfield); yreal = gwy_data_field_get_yreal(dfield); qx = 2.0/xreal*xres/(xres - 1.0); qy = 2.0/yreal*yres/(yres - 1.0); q = sqrt(qx*qy); mx = sqrt(qx/qy); my = sqrt(qy/qx); ccoeffs[0] = coeffs[A]; ccoeffs[1] = mx*coeffs[BX]; ccoeffs[2] = my*coeffs[BY]; ccoeffs[3] = mx*mx*coeffs[CXX]; ccoeffs[4] = coeffs[CXY]; ccoeffs[5] = my*my*coeffs[CYY]; gwy_math_curvature(ccoeffs, params + PARAM_R1, params + PARAM_R2, params + PARAM_PHI1, params + PARAM_PHI2, params + PARAM_X0, params + PARAM_Y0, params + PARAM_A); /* Transform to physical values. */ /* FIXME: Why we have q*q here? */ params[PARAM_R1] = 1.0/(q*q*params[PARAM_R1]); params[PARAM_R2] = 1.0/(q*q*params[PARAM_R2]); params[PARAM_X0] = params[PARAM_X0]/q + 0.5*xreal; params[PARAM_Y0] = params[PARAM_Y0]/q + 0.5*yreal; ok = TRUE; for (i = 0; i < 2; i++) { ok &= intersect_with_boundary(params[PARAM_X0], params[PARAM_Y0], -params[PARAM_PHI1 + i], xreal, yreal, i1 + i, i2 + i); } return ok; }
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 GwyDataField* unisoku_read_data_field(const guchar *buffer, gsize size, UnisokuFile *ufile, GError **error) { gint i, n, power10; const gchar *unit; GwyDataField *dfield; GwySIUnit *siunit; gdouble q, pmin, pmax, rmin, rmax; gdouble *data; n = ufile->xres * ufile->yres; if (err_SIZE_MISMATCH(error, n*type_sizes[ufile->data_type], size, FALSE)) return NULL; dfield = gwy_data_field_new(ufile->xres, ufile->yres, fabs((ufile->end_x - ufile->start_x)), fabs((ufile->end_y - ufile->start_y)), FALSE); data = gwy_data_field_get_data(dfield); /* FIXME: what to do when ascii_flag is set? */ switch (ufile->data_type) { case UNISOKU_UINT8: for (i = 0; i < n; i++) data[i] = buffer[i]; break; case UNISOKU_SINT8: for (i = 0; i < n; i++) data[i] = (signed char)buffer[i]; break; case UNISOKU_UINT16: { const guint16 *pdata = (const guint16*)buffer; for (i = 0; i < n; i++) data[i] = GUINT16_FROM_LE(pdata[i]); } break; case UNISOKU_SINT16: { const gint16 *pdata = (const gint16*)buffer; for (i = 0; i < n; i++) data[i] = GINT16_FROM_LE(pdata[i]); } break; case UNISOKU_FLOAT: for (i = 0; i < n; i++) data[i] = gwy_get_gfloat_le(&buffer); break; default: g_return_val_if_reached(NULL); break; } unit = ufile->unit_x; if (!*unit) unit = "nm"; siunit = gwy_si_unit_new_parse(unit, &power10); gwy_data_field_set_si_unit_xy(dfield, siunit); q = pow10((gdouble)power10); gwy_data_field_set_xreal(dfield, q*gwy_data_field_get_xreal(dfield)); gwy_data_field_set_yreal(dfield, q*gwy_data_field_get_yreal(dfield)); g_object_unref(siunit); unit = ufile->unit_z; /* XXX: No fallback yet, just make z unitless */ siunit = gwy_si_unit_new_parse(unit, &power10); gwy_data_field_set_si_unit_z(dfield, siunit); q = pow10((gdouble)power10); pmin = q*ufile->min_z; pmax = q*ufile->max_z; rmin = ufile->min_raw_z; rmax = ufile->max_raw_z; gwy_data_field_multiply(dfield, (pmax - pmin)/(rmax - rmin)); gwy_data_field_add(dfield, (pmin*rmax - pmax*rmin)/(rmax - rmin)); g_object_unref(siunit); return dfield; }
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; }
static void preview(DepositControls *controls, DepositArgs *args) { GwyDataField *dfield, *lfield, *zlfield, *zdfield; gint xres, yres, oxres, oyres; gint add, i, ii, m, k; gdouble size, width; gint xdata[10000]; gint ydata[10000]; gdouble disizes[10000]; gdouble rdisizes[10000]; gdouble rx[10000]; gdouble ry[10000]; gdouble rz[10000]; gdouble ax[10000]; gdouble ay[10000]; gdouble az[10000]; gdouble vx[10000]; gdouble vy[10000]; gdouble vz[10000]; gdouble fx[10000]; gdouble fy[10000]; gdouble fz[10000]; gint xpos, ypos, ndata, too_close; gdouble disize, mdisize; gdouble xreal, yreal, oxreal, oyreal; gdouble diff; gdouble mass = 1; gint presetval; gint nloc, maxloc = 1; gint max = 5000000; gdouble rxv, ryv, rzv, timestep = 3e-7; //5e-7 deposit_dialog_update_values(controls, args); dfield = GWY_DATA_FIELD(gwy_container_get_object_by_name(controls->mydata, "/0/data")); gwy_container_set_object_by_name(controls->mydata, "/0/data", gwy_data_field_duplicate(controls->old_dfield)); dfield = GWY_DATA_FIELD(gwy_container_get_object_by_name(controls->mydata, "/0/data")); if (controls->in_init) { gwy_data_field_data_changed(dfield); while (gtk_events_pending()) gtk_main_iteration(); return; } oxres = gwy_data_field_get_xres(dfield); oyres = gwy_data_field_get_yres(dfield); oxreal = gwy_data_field_get_xreal(dfield); oyreal = gwy_data_field_get_yreal(dfield); diff = oxreal/oxres/10; size = args->size*5e-9; // width = args->width*5e-9 + 2*size; //increased manually to fill boundaries width = 2*size; add = gwy_data_field_rtoi(dfield, size + width); mdisize = gwy_data_field_rtoi(dfield, size); xres = oxres + 2*add; yres = oyres + 2*add; xreal = oxreal + 2*(size+width); yreal = oyreal + 2*(size+width); // printf("For field of size %g and particle nominak %g, real %g (%g), the final size will change from %d to %d\n", // gwy_data_field_get_xreal(dfield), args->size, size, disize, oxres, xres); /*make copy of datafield, with mirrored boundaries*/ lfield = gwy_data_field_new(xres, yres, gwy_data_field_itor(dfield, xres), gwy_data_field_jtor(dfield, yres), TRUE); gwy_data_field_area_copy(dfield, lfield, 0, 0, oxres, oyres, add, add); gwy_data_field_invert(dfield, 1, 0, 0); gwy_data_field_area_copy(dfield, lfield, 0, oyres-add-1, oxres, add, add, 0); gwy_data_field_area_copy(dfield, lfield, 0, 0, oxres, add, add, yres-add-1); gwy_data_field_invert(dfield, 1, 0, 0); gwy_data_field_invert(dfield, 0, 1, 0); gwy_data_field_area_copy(dfield, lfield, oxres-add-1, 0, add, oyres, 0, add); gwy_data_field_area_copy(dfield, lfield, 0, 0, add, oyres, xres-add-1, add); gwy_data_field_invert(dfield, 0, 1, 0); gwy_data_field_invert(dfield, 1, 1, 0); gwy_data_field_area_copy(dfield, lfield, oxres-add-1, oyres-add-1, add, add, 0, 0); gwy_data_field_area_copy(dfield, lfield, 0, 0, add, add, xres-add-1, yres-add-1); gwy_data_field_area_copy(dfield, lfield, oxres-add-1, 0, add, add, 0, yres-add-1); gwy_data_field_area_copy(dfield, lfield, 0, oyres-add-1, add, add, xres-add-1, 0); gwy_data_field_invert(dfield, 1, 1, 0); zlfield = gwy_data_field_duplicate(lfield); zdfield = gwy_data_field_duplicate(dfield); /*determine number of spheres necessary for given coverage*/ for (i=0; i<10000; i++) { ax[i] = ay[i] = az[i] = vx[i] = vy[i] = vz[i] = 0; } srand ( time(NULL) ); ndata = 0; /* for test only */ /* disize = mdisize; xpos = oxres/2 - 2*disize; ypos = oyres/2; xdata[ndata] = xpos; ydata[ndata] = ypos; disizes[ndata] = disize; rdisizes[ndata] = size; rx[ndata] = (gdouble)xpos*oxreal/(gdouble)oxres; ry[ndata] = (gdouble)ypos*oyreal/(gdouble)oyres; rz[ndata] = 2.0*gwy_data_field_get_val(lfield, xpos, ypos) + rdisizes[ndata]; ndata++; xpos = oxres/2 + 2*disize; ypos = oyres/2; xdata[ndata] = xpos; ydata[ndata] = ypos; disizes[ndata] = disize; rdisizes[ndata] = size; rx[ndata] = (gdouble)xpos*oxreal/(gdouble)oxres; ry[ndata] = (gdouble)ypos*oyreal/(gdouble)oyres; rz[ndata] = 2.0*gwy_data_field_get_val(lfield, xpos, ypos) + rdisizes[ndata]; ndata++; */ /*end of test*/ i = 0; presetval = args->coverage*10; while (ndata < presetval && i<max) { //disize = mdisize*(0.8+(double)(rand()%20)/40.0); disize = mdisize; xpos = disize+(rand()%(xres-2*(gint)(disize+1))) + 1; ypos = disize+(rand()%(yres-2*(gint)(disize+1))) + 1; i++; { too_close = 0; /*sync real to integer positions*/ for (k=0; k<ndata; k++) { if (((xpos-xdata[k])*(xpos-xdata[k]) + (ypos-ydata[k])*(ypos-ydata[k]))<(4*disize*disize)) { too_close = 1; break; } } if (too_close) continue; if (ndata>=10000) { break; } xdata[ndata] = xpos; ydata[ndata] = ypos; disizes[ndata] = disize; rdisizes[ndata] = size; rx[ndata] = (gdouble)xpos*oxreal/(gdouble)oxres; ry[ndata] = (gdouble)ypos*oyreal/(gdouble)oyres; //printf("surface at %g, particle size %g\n", gwy_data_field_get_val(lfield, xpos, ypos), rdisizes[ndata]); rz[ndata] = 1.0*gwy_data_field_get_val(lfield, xpos, ypos) + rdisizes[ndata]; //2 ndata++; } }; // if (i==max) printf("Maximum reached, only %d particles depositd instead of %d\n", ndata, presetval); // else printf("%d particles depositd\n", ndata); /*refresh shown data and integer positions (necessary in md calculation)*/ gwy_data_field_copy(zlfield, lfield, 0); showit(lfield, zdfield, rdisizes, rx, ry, rz, xdata, ydata, ndata, oxres, oxreal, oyres, oyreal, add, xres, yres); gwy_data_field_area_copy(lfield, dfield, add, add, oxres, oyres, 0, 0); gwy_data_field_data_changed(dfield); for (i=0; i<(20*args->revise); i++) { // printf("###### step %d of %d ##########\n", i, (gint)(20*args->revise)); /*try to add some particles if necessary, do this only for first half of molecular dynamics*/ if (ndata<presetval && i<(10*args->revise)) { ii = 0; nloc = 0; while (ndata < presetval && ii<(max/1000) && nloc<maxloc) { disize = mdisize; xpos = disize+(rand()%(xres-2*(gint)(disize+1))) + 1; ypos = disize+(rand()%(yres-2*(gint)(disize+1))) + 1; ii++; { too_close = 0; rxv = ((gdouble)xpos*oxreal/(gdouble)oxres); ryv = ((gdouble)ypos*oyreal/(gdouble)oyres); rzv = gwy_data_field_get_val(zlfield, xpos, ypos) + 5*size; for (k=0; k<ndata; k++) { if (((rxv-rx[k])*(rxv-rx[k]) + (ryv-ry[k])*(ryv-ry[k]) + (rzv-rz[k])*(rzv-rz[k]))<(4.0*size*size)) { too_close = 1; break; } } if (too_close) continue; if (ndata>=10000) { // printf("Maximum reached!\n"); break; } xdata[ndata] = xpos; ydata[ndata] = ypos; disizes[ndata] = disize; rdisizes[ndata] = size; rx[ndata] = rxv; ry[ndata] = ryv; rz[ndata] = rzv; vz[ndata] = -0.01; ndata++; nloc++; } }; // if (ii==(max/100)) printf("Maximum reached, only %d particles now present instead of %d\n", ndata, presetval); // else printf("%d particles now at surface\n", ndata); } /*test succesive LJ steps on substrate (no relaxation)*/ for (k=0; k<ndata; k++) { fx[k] = fy[k] = fz[k] = 0; /*calculate forces for all particles on substrate*/ if (gwy_data_field_rtoi(lfield, rx[k])<0 || gwy_data_field_rtoj(lfield, ry[k])<0 || gwy_data_field_rtoi(lfield, rx[k])>=xres || gwy_data_field_rtoj(lfield, ry[k])>=yres) continue; for (m=0; m<ndata; m++) { if (m==k) continue; // printf("(%g %g %g) on (%g %g %g)\n", rx[m], ry[m], rz[m], rx[k], ry[k], rz[k]); fx[k] -= (get_lj_potential_spheres(rx[m], ry[m], rz[m], rx[k]+diff, ry[k], rz[k], gwy_data_field_itor(dfield, disizes[k])) -get_lj_potential_spheres(rx[m], ry[m], rz[m], rx[k]-diff, ry[k], rz[k], gwy_data_field_itor(dfield, disizes[k])))/2/diff; fy[k] -= (get_lj_potential_spheres(rx[m], ry[m], rz[m], rx[k], ry[k]+diff, rz[k], gwy_data_field_itor(dfield, disizes[k])) -get_lj_potential_spheres(rx[m], ry[m], rz[m], rx[k], ry[k]-diff, rz[k], gwy_data_field_itor(dfield, disizes[k])))/2/diff; fz[k] -= (get_lj_potential_spheres(rx[m], ry[m], rz[m], rx[k], ry[k], rz[k]+diff, gwy_data_field_itor(dfield, disizes[k])) -get_lj_potential_spheres(rx[m], ry[m], rz[m], rx[k], ry[k], rz[k]-diff, gwy_data_field_itor(dfield, disizes[k])))/2/diff; } fx[k] -= (integrate_lj_substrate(zlfield, rx[k]+diff, ry[k], rz[k], rdisizes[k]) - integrate_lj_substrate(zlfield, rx[k]-diff, ry[k], rz[k], rdisizes[k]))/2/diff; fy[k] -= (integrate_lj_substrate(zlfield, rx[k], ry[k]-diff, rz[k], rdisizes[k]) - integrate_lj_substrate(zlfield, rx[k], ry[k]+diff, rz[k], rdisizes[k]))/2/diff; fz[k] -= (integrate_lj_substrate(zlfield, rx[k], ry[k], rz[k]+diff, rdisizes[k]) - integrate_lj_substrate(zlfield, rx[k], ry[k], rz[k]-diff, rdisizes[k]))/2/diff; } for (k=0; k<ndata; k++) { if (gwy_data_field_rtoi(lfield, rx[k])<0 || gwy_data_field_rtoj(lfield, ry[k])<0 || gwy_data_field_rtoi(lfield, rx[k])>=xres || gwy_data_field_rtoj(lfield, ry[k])>=yres) continue; /*move all particles*/ rx[k] += vx[k]*timestep + 0.5*ax[k]*timestep*timestep; vx[k] += 0.5*ax[k]*timestep; ax[k] = fx[k]/mass; vx[k] += 0.5*ax[k]*timestep; vx[k] *= 0.9; if (fabs(vx[k])>0.01) vx[k] = 0; //0.2 ry[k] += vy[k]*timestep + 0.5*ay[k]*timestep*timestep; vy[k] += 0.5*ay[k]*timestep; ay[k] = fy[k]/mass; vy[k] += 0.5*ay[k]*timestep; vy[k] *= 0.9; if (fabs(vy[k])>0.01) vy[k] = 0; //0.2 rz[k] += vz[k]*timestep + 0.5*az[k]*timestep*timestep; vz[k] += 0.5*az[k]*timestep; az[k] = fz[k]/mass; vz[k] += 0.5*az[k]*timestep; vz[k] *= 0.9; if (fabs(vz[k])>0.01) vz[k] = 0; if (rx[k]<=gwy_data_field_itor(dfield, disizes[k])) rx[k] = gwy_data_field_itor(dfield, disizes[k]); if (ry[k]<=gwy_data_field_itor(dfield, disizes[k])) ry[k] = gwy_data_field_itor(dfield, disizes[k]); if (rx[k]>=(xreal-gwy_data_field_itor(dfield, disizes[k]))) rx[k] = xreal-gwy_data_field_itor(dfield, disizes[k]); if (ry[k]>=(yreal-gwy_data_field_itor(dfield, disizes[k]))) ry[k] = yreal-gwy_data_field_itor(dfield, disizes[k]); } gwy_data_field_copy(zlfield, lfield, 0); showit(lfield, zdfield, rdisizes, rx, ry, rz, xdata, ydata, ndata, oxres, oxreal, oyres, oyreal, add, xres, yres); gwy_data_field_area_copy(lfield, dfield, add, add, oxres, oyres, 0, 0); gwy_data_field_data_changed(dfield); while (gtk_events_pending()) gtk_main_iteration(); } gwy_data_field_area_copy(lfield, dfield, add, add, oxres, oyres, 0, 0); gwy_data_field_data_changed(dfield); args->computed = TRUE; gwy_object_unref(lfield); gwy_object_unref(zlfield); gwy_object_unref(zdfield); }
static gboolean surffile_save(GwyContainer *data, const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { FILE *fh; gboolean ok = TRUE; SurfWriter surf; gfloat uintmax = 1073741824.0; gdouble zmaxreal; gdouble zminreal; gdouble xreal; gdouble yreal; gchar *dxunittmp; gchar *dyunittmp; gchar *dzunittmp; GwySIUnit *xysi; GwySIUnit *zsi; GwyContainer *current_data; int power = 0; int k = 0; GwyDataField *dfield; const gdouble *points; gint32 *integer_values; strncpy(surf.signature, "DIGITAL SURF", 12); surf.format = 0; surf.nobjects = 1; surf.version = 1; surf.type = 1; strncpy(surf.object_name, "SCRATCH", 30); strncpy(surf.operator_name, "csm", 30); surf.material_code = 0; surf.acquisition = 0; surf.range = 1; surf.special_points = 0; surf.absolute = 1; strncpy(surf.reserved, " ", 8); surf.pointsize = 32; surf.zmin = 0; surf.zmax = 1073741824.0; strncpy(surf.xaxis, "X", 16); strncpy(surf.yaxis, "Y", 16); strncpy(surf.zaxis, "Z", 16); surf.xunit_ratio = 1; surf.yunit_ratio = 1; surf.zunit_ratio = 1; surf.imprint = 1; surf.inversion = 0; surf.leveling = 0; strncpy(surf.obsolete, " ", 12); surf.seconds = 0; surf.minutes = 0; surf.hours = 0; surf.day = 5; surf.month = 1; surf.year = 2001; surf.dayof = 0; surf.measurement_duration = 1.0; strncpy(surf.obsolete2, " ", 10); surf.comment_size = 0; surf.private_size = 0; strncpy(surf.client_zone," ", 128); surf.XOffset = 0.0; surf.YOffset = 0.0; surf.ZOffset = 0.0; strncpy(surf.reservedzone, " ", 34); if (!(fh = gwy_fopen( filename, "wb"))) { err_OPEN_WRITE(error); return FALSE; } gwy_app_data_browser_get_current(GWY_APP_CONTAINER, ¤t_data, 0); if (!current_data) { err_NO_CHANNEL_EXPORT(error); return FALSE; } if (data != current_data) { return FALSE; } gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, 0); if (!dfield) { err_NO_CHANNEL_EXPORT(error); return FALSE; } /*header values*/ xysi = gwy_data_field_get_si_unit_xy(dfield); zsi = gwy_data_field_get_si_unit_z(dfield); dxunittmp = gwy_si_unit_get_string(xysi, GWY_SI_UNIT_FORMAT_PLAIN); dyunittmp = gwy_si_unit_get_string (xysi, GWY_SI_UNIT_FORMAT_PLAIN); dzunittmp = gwy_si_unit_get_string (zsi, GWY_SI_UNIT_FORMAT_PLAIN); strncpy(surf.dx_unit, dxunittmp, 16); strncpy(surf.dy_unit, dyunittmp, 16); strncpy(surf.dz_unit, dzunittmp, 16); g_free(dxunittmp); g_free(dyunittmp); g_free(dzunittmp); /*extrema*/ zmaxreal = gwy_data_field_get_max(dfield); zminreal = gwy_data_field_get_min(dfield); surf.xres = gwy_data_field_get_xres(dfield); surf.yres = gwy_data_field_get_yres(dfield); surf.nofpoints = surf.xres * surf.yres; xreal = gwy_data_field_get_xreal(dfield); yreal = gwy_data_field_get_yreal(dfield); /*units*/ power = 0; surf.dx = (gfloat)(xreal / surf.xres); get_unit(surf.dx_unit, &power, xreal); surf.dx *= pow10(power); strncpy(surf.xlength_unit, surf.dx_unit, 16); power = 0; surf.dy = (gfloat)(yreal / surf.yres); get_unit(surf.dy_unit, &power, yreal); surf.dy *= pow10(power); strncpy(surf.ylength_unit, surf.dy_unit, 16); power = 0; if (zmaxreal > zminreal) { get_unit(surf.dz_unit, &power, (zmaxreal - zminreal)); } strncpy(surf.zlength_unit, surf.dz_unit, 16); zmaxreal *= pow10(power); zminreal *= pow10(power); surf.dz = (zmaxreal - zminreal) / uintmax; surf.ZOffset = zminreal; /*convert data into integer32*/ integer_values = g_new(gint32, surf.nofpoints); points = gwy_data_field_get_data_const(dfield); if (zminreal != zmaxreal) { for (k = 0; k < surf.nofpoints; k++) { // * pow10( power ) to convert in the dz_unit integer_values[k] = floor(uintmax * (points[k] * pow10(power) - zminreal) / (zmaxreal - zminreal)); } } else { for (k = 0; k < surf.nofpoints; k++) { integer_values[k] = 0; } } /* byte order*/ surf.format = GINT16_TO_LE(surf.format); surf.nobjects = GUINT16_TO_LE(surf.nobjects); surf.version = GINT16_TO_LE(surf.version); surf.type = GINT16_TO_LE(surf.type); surf.material_code = GINT16_TO_LE(surf.material_code); surf.acquisition = GINT16_TO_LE(surf.acquisition); surf.range = GINT16_TO_LE(surf.range); surf.special_points = GINT16_TO_LE(surf.special_points); surf.absolute = GINT16_TO_LE(surf.absolute); surf.pointsize = GINT16_TO_LE(surf.pointsize); surf.zmin = GINT32_TO_LE(surf.zmin); surf.zmax = GINT32_TO_LE(surf.zmax); surf.xres = GINT32_TO_LE(surf.xres); surf.yres = GINT32_TO_LE(surf.yres); surf.nofpoints = GINT32_TO_LE(surf.nofpoints); surf.dx = GFLOAT_TO_LE(surf.dx); surf.dy = GFLOAT_TO_LE(surf.dy); surf.dz = GFLOAT_TO_LE(surf.dz); surf.xunit_ratio = GFLOAT_TO_LE(surf.xunit_ratio); surf.yunit_ratio = GFLOAT_TO_LE(surf.yunit_ratio); surf.zunit_ratio = GFLOAT_TO_LE(surf.zunit_ratio); surf.imprint = GINT16_TO_LE(surf.imprint); surf.inversion = GINT16_TO_LE(surf.inversion); surf.leveling = GINT16_TO_LE(surf.leveling); surf.seconds = GINT16_TO_LE(surf.seconds); surf.minutes = GINT16_TO_LE(surf.minutes); surf.hours = GINT16_TO_LE(surf.hours); surf.day = GINT16_TO_LE(surf.day); surf.month = GINT16_TO_LE(surf.month); surf.year = GINT16_TO_LE(surf.year); surf.dayof = GINT16_TO_LE(surf.dayof); surf.measurement_duration = GFLOAT_TO_LE(surf.measurement_duration); surf.comment_size = GINT16_TO_LE(surf.comment_size); surf.private_size = GINT16_TO_LE(surf.private_size); surf.XOffset = GFLOAT_TO_LE(surf.XOffset); surf.YOffset = GFLOAT_TO_LE(surf.YOffset); surf.ZOffset = GFLOAT_TO_LE(surf.ZOffset); for (k = 0; k < surf.nofpoints; k++) { integer_values[k] = GINT32_TO_LE(integer_values[k]); } //write // fwrite(&surf, sizeof( SurfWriter ), 1, fh) bad struct align if( fwrite(&surf.signature, sizeof(char), 12, fh) != 12 || fwrite(&surf.format, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.nobjects, sizeof(guint16), 1, fh) != 1 || fwrite(&surf.version, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.type, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.object_name, sizeof(char), 30, fh) != 30 || fwrite(&surf.operator_name, sizeof(char), 30, fh) != 30 || fwrite(&surf.material_code, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.acquisition, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.range, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.special_points, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.absolute, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.reserved, sizeof(char), 8, fh) != 8 || fwrite(&surf.pointsize, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.zmin, sizeof(gint32), 1, fh) != 1 || fwrite(&surf.zmax, sizeof(gint32), 1, fh) != 1 || fwrite(&surf.xres, sizeof(gint32), 1, fh) != 1 || fwrite(&surf.yres, sizeof(gint32), 1, fh) != 1 || fwrite(&surf.nofpoints, sizeof(gint32), 1, fh) != 1 || fwrite(&surf.dx, sizeof(gfloat), 1, fh) != 1 || fwrite(&surf.dy, sizeof(gfloat), 1, fh) != 1 || fwrite(&surf.dz, sizeof(gfloat), 1, fh) != 1 || fwrite(&surf.xaxis, sizeof(char), 16, fh) != 16 || fwrite(&surf.yaxis, sizeof(char), 16, fh) != 16 || fwrite(&surf.zaxis, sizeof(char), 16, fh) != 16 || fwrite(&surf.dx_unit, sizeof(char), 16, fh) != 16 || fwrite(&surf.dy_unit, sizeof(char), 16, fh) != 16 || fwrite(&surf.dz_unit, sizeof(char), 16, fh) != 16 || fwrite(&surf.xlength_unit, sizeof(char), 16, fh) != 16 || fwrite(&surf.ylength_unit, sizeof(char), 16, fh) != 16 || fwrite(&surf.zlength_unit, sizeof(char), 16, fh) != 16 || fwrite(&surf.xunit_ratio, sizeof(gfloat), 1, fh) != 1 || fwrite(&surf.yunit_ratio, sizeof(gfloat), 1, fh) != 1 || fwrite(&surf.zunit_ratio, sizeof(gfloat), 1, fh) != 1 || fwrite(&surf.imprint, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.inversion, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.leveling, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.obsolete, sizeof(char), 12, fh) != 12 || fwrite(&surf.seconds, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.minutes, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.hours, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.day, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.month, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.year, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.dayof, sizeof(gint16),1,fh) != 1 || fwrite(&surf.measurement_duration, sizeof(gfloat), 1, fh) != 1 || fwrite(&surf.obsolete2, sizeof(char), 10, fh) != 10 || fwrite(&surf.comment_size, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.private_size, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.client_zone, sizeof(char), 128, fh) != 128 || fwrite(&surf.XOffset, sizeof(gfloat), 1, fh) != 1 || fwrite(&surf.YOffset, sizeof(gfloat), 1, fh) != 1 || fwrite(&surf.ZOffset, sizeof(gfloat), 1, fh) != 1 || fwrite(&surf.reservedzone, sizeof(char), 34, fh)!= 34 || fwrite(integer_values, sizeof(gint32), surf.nofpoints, fh) != surf.nofpoints ) { err_WRITE(error); ok = FALSE; g_unlink(filename); } g_free(integer_values); fclose( fh ); return ok; }
static gboolean gsf_export(GwyContainer *container, const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { static const gchar zeroes[4] = { 0, 0, 0, 0 }; GString *header = NULL; gfloat *dfl = NULL; guint i, xres, yres, padding; gint id; GwyDataField *dfield; const gdouble *d; gdouble v; gchar *s; GwySIUnit *unit, *emptyunit; FILE *fh; gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, GWY_APP_DATA_FIELD_ID, &id, 0); if (!dfield) { err_NO_CHANNEL_EXPORT(error); return FALSE; } if (!(fh = g_fopen(filename, "wb"))) { err_OPEN_WRITE(error); return FALSE; } xres = gwy_data_field_get_xres(dfield); yres = gwy_data_field_get_yres(dfield); header = g_string_new(MAGIC); g_string_append_printf(header, "XRes = %u\n", xres); g_string_append_printf(header, "YRes = %u\n", yres); append_num(header, "XReal", gwy_data_field_get_xreal(dfield)); append_num(header, "YReal", gwy_data_field_get_yreal(dfield)); if ((v = gwy_data_field_get_xoffset(dfield))) append_num(header, "XOffset", v); if ((v = gwy_data_field_get_yoffset(dfield))) append_num(header, "YOffset", v); emptyunit = gwy_si_unit_new(NULL); unit = gwy_data_field_get_si_unit_xy(dfield); if (!gwy_si_unit_equal(unit, emptyunit)) { s = gwy_si_unit_get_string(unit, GWY_SI_UNIT_FORMAT_PLAIN); g_string_append_printf(header, "XYUnits = %s\n", s); g_free(s); } unit = gwy_data_field_get_si_unit_z(dfield); if (!gwy_si_unit_equal(unit, emptyunit)) { s = gwy_si_unit_get_string(unit, GWY_SI_UNIT_FORMAT_PLAIN); g_string_append_printf(header, "ZUnits = %s\n", s); g_free(s); } g_object_unref(emptyunit); s = gwy_app_get_data_field_title(container, id); g_string_append_printf(header, "Title = %s\n", s); g_free(s); if (fwrite(header->str, 1, header->len, fh) != header->len) { err_WRITE(error); goto fail; } padding = 4 - (header->len % 4); if (fwrite(zeroes, 1, padding, fh) != padding) { err_WRITE(error); goto fail; } g_string_free(header, TRUE); header = NULL; dfl = g_new(gfloat, xres*yres); d = gwy_data_field_get_data_const(dfield); for (i = 0; i < xres*yres; i++) { union { guchar pp[4]; float f; } z; z.f = d[i]; #if (G_BYTE_ORDER == G_BIG_ENDIAN) GWY_SWAP(guchar, z.pp[0], z.pp[3]); GWY_SWAP(guchar, z.pp[1], z.pp[2]); #endif dfl[i] = z.f; } if (fwrite(dfl, sizeof(gfloat), xres*yres, fh) != xres*yres) { err_WRITE(error); goto fail; } g_free(dfl); fclose(fh); return TRUE; fail: if (fh) fclose(fh); g_unlink(filename); if (header) g_string_free(header, TRUE); g_free(dfl); return FALSE; }
static gboolean aafm_export(G_GNUC_UNUSED GwyContainer *data, const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { union { guchar pp[4]; float f; } z; guint16 res, r; gint16 *x; gint16 v; gint i, j, xres, yres, n; GwyDataField *dfield; const gdouble *d; gdouble min, max, q, z0; FILE *fh; gboolean ok = TRUE; gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, 0); if (!dfield) { err_NO_CHANNEL_EXPORT(error); return FALSE; } if (!(fh = gwy_fopen(filename, "wb"))) { err_OPEN_WRITE(error); return FALSE; } d = gwy_data_field_get_data_const(dfield); xres = gwy_data_field_get_xres(dfield); yres = gwy_data_field_get_yres(dfield); res = MIN(MIN(xres, yres), 32767); n = (gint)res*(gint)res; r = GUINT16_TO_LE(res); fwrite(&res, 1, sizeof(r), fh); gwy_data_field_get_min_max(dfield, &min, &max); if (min == max) { q = 0.0; z0 = 0.0; } else { q = 65533.0/(max - min); z0 = -32766.5*(max + min)/(max - min); } z.f = MIN(gwy_data_field_get_xreal(dfield), gwy_data_field_get_yreal(dfield))/Angstrom; #if (G_BYTE_ORDER == G_BIG_ENDIAN) GWY_SWAP(guchar, z.pp[0], z.pp[3]); GWY_SWAP(guchar, z.pp[1], z.pp[2]); #endif fwrite(&z, 1, sizeof(z), fh); x = g_new(gint16, n); for (i = 0; i < res; i++) { for (j = 0; j < res; j++) { v = GWY_ROUND(d[(res-1 - j)*res + i]*q + z0); x[i*res + j] = GINT16_TO_LE(v); } } if (!(ok = (fwrite(x, 1, 2*n, fh) == 2*n))) { err_WRITE(error); g_unlink(filename); } else { z.f = (max - min)/Angstrom; #if (G_BYTE_ORDER == G_BIG_ENDIAN) GWY_SWAP(guchar, z.pp[0], z.pp[3]); GWY_SWAP(guchar, z.pp[1], z.pp[2]); #endif fwrite(&z, 1, sizeof(z), fh); } fclose(fh); g_free(x); return ok; }
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); }
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 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; }