static gboolean prewitt_vertical(GwyContainer *data, GwyRunType run) { GObject *shadefield; GwyDataField *dfield; g_assert(run & GRADIENT_RUN_MODES); dfield = GWY_DATA_FIELD(gwy_container_get_object_by_name(data, "/0/data")); gwy_app_undo_checkpoint(data, "/0/show", NULL); if (gwy_container_gis_object_by_name(data, "/0/show", &shadefield)) { gwy_data_field_resample(GWY_DATA_FIELD(shadefield), gwy_data_field_get_xres(dfield), gwy_data_field_get_yres(dfield), GWY_INTERPOLATION_NONE); } else { shadefield = gwy_serializable_duplicate(G_OBJECT(dfield)); gwy_container_set_object_by_name(data, "/0/show", shadefield); g_object_unref(shadefield); } gwy_data_field_area_copy(dfield, GWY_DATA_FIELD(shadefield), 0, 0, gwy_data_field_get_xres(dfield), gwy_data_field_get_yres(dfield), 0, 0); gwy_data_field_area_filter_prewitt(GWY_DATA_FIELD(shadefield), GTK_ORIENTATION_VERTICAL, 0, 0, gwy_data_field_get_xres(dfield), gwy_data_field_get_yres(dfield)); 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 void merge_do_none(MergeArgs *args) { GwyDataField *dfield1, *dfield2; gint xres1, xres2, yres1, yres2; gint px1, py1, px2, py2; GwyContainer *data1, *data2; GQuark quark; data1 = gwy_app_data_browser_get(args->op1.datano); quark = gwy_app_get_data_key_for_id(args->op1.id); dfield1 = GWY_DATA_FIELD(gwy_container_get_object(data1, quark)); data2 = gwy_app_data_browser_get(args->op2.datano); quark = gwy_app_get_data_key_for_id(args->op2.id); dfield2 = GWY_DATA_FIELD(gwy_container_get_object(data2, quark)); xres1 = gwy_data_field_get_xres(dfield1); xres2 = gwy_data_field_get_xres(dfield2); yres1 = gwy_data_field_get_yres(dfield1); yres2 = gwy_data_field_get_yres(dfield2); if (args->direction == GWY_MERGE_DIRECTION_UP) { px1 = px2 = 0; py1 = yres2; py2 = 0; } else if (args->direction == GWY_MERGE_DIRECTION_DOWN) { px1 = px2 = 0; py1 = 0; py2 = yres1; } else if (args->direction == GWY_MERGE_DIRECTION_LEFT) { py1 = py2 = 0; px1 = xres2; px2 = 0; } else if (args->direction == GWY_MERGE_DIRECTION_RIGHT) { py1 = py2 = 0; px1 = 0; px2 = xres1; } else { g_assert_not_reached(); } create_merged_field(data1, args->op1.id, dfield1, dfield2, px1, py1, px2, py2, args->boundary, args->direction, args->create_mask, args->crop_to_rectangle); }
/* Note this is not a correlation score since we care also about absolute * differences and try to suppress the influence of outliers. */ static gdouble get_row_difference(GwyDataField *dfield1, gint col1, gint row1, GwyDataField *dfield2, gint col2, gint row2, gint width, gint height) { gint xres1, yres1, xres2, yres2, i, j; const gdouble *data1, *data2; gdouble *row; gdouble s = 0.0; g_return_val_if_fail(width > 0, G_MAXDOUBLE); g_return_val_if_fail(height > 0, G_MAXDOUBLE); xres1 = gwy_data_field_get_xres(dfield1); yres1 = gwy_data_field_get_yres(dfield1); xres2 = gwy_data_field_get_xres(dfield2); yres2 = gwy_data_field_get_yres(dfield2); data1 = gwy_data_field_get_data_const(dfield1); data2 = gwy_data_field_get_data_const(dfield2); g_return_val_if_fail(col1 + width <= xres1, G_MAXDOUBLE); g_return_val_if_fail(col2 + width <= xres2, G_MAXDOUBLE); g_return_val_if_fail(row1 + height <= yres1, G_MAXDOUBLE); g_return_val_if_fail(row2 + height <= yres2, G_MAXDOUBLE); row = g_new(gdouble, width); for (i = 0; i < height; i++) { const gdouble *d1 = data1 + (row1 + i)*xres1 + col1; const gdouble *d2 = data2 + (row2 + i)*xres2 + col2; gdouble d; for (j = 0; j < width; j++) { d = d1[j] - d2[j]; row[j] = d; } d = gwy_math_median(width, row); s += d*d; } g_free(row); return sqrt(s/height); }
static gdouble get_column_difference(GwyDataField *dfield1, gint col1, gint row1, GwyDataField *dfield2, gint col2, gint row2, gint width, gint height) { gint xres1, yres1, xres2, yres2, i, j; const gdouble *data1, *data2; gdouble *column; gdouble s = 0.0; g_return_val_if_fail(width > 0, G_MAXDOUBLE); g_return_val_if_fail(height > 0, G_MAXDOUBLE); xres1 = gwy_data_field_get_xres(dfield1); yres1 = gwy_data_field_get_yres(dfield1); xres2 = gwy_data_field_get_xres(dfield2); yres2 = gwy_data_field_get_yres(dfield2); data1 = gwy_data_field_get_data_const(dfield1); data2 = gwy_data_field_get_data_const(dfield2); g_return_val_if_fail(col1 + width <= xres1, G_MAXDOUBLE); g_return_val_if_fail(col2 + width <= xres2, G_MAXDOUBLE); g_return_val_if_fail(row1 + height <= yres1, G_MAXDOUBLE); g_return_val_if_fail(row2 + height <= yres2, G_MAXDOUBLE); column = g_new(gdouble, height); for (j = 0; j < width; j++) { const gdouble *d1 = data1 + row1*xres1 + col1 + j; const gdouble *d2 = data2 + row2*xres2 + col2 + j; gdouble d; for (i = 0; i < height; i++) { d = d1[i*xres1] - d2[i*xres2]; column[i] = d; } d = gwy_math_median(height, column); s += d*d; } g_free(column); return sqrt(s/height); }
static gboolean asciiexport_save(GwyContainer *data, const gchar *filename) { GwyDataField *dfield; gint xres, yres, i, j; gdouble *d; FILE *fh; if (!(fh = fopen(filename, "w"))) return FALSE; dfield = GWY_DATA_FIELD(gwy_container_get_object_by_name(data, "/0/data")); xres = gwy_data_field_get_xres(dfield); yres = gwy_data_field_get_yres(dfield); d = gwy_data_field_get_data(dfield); for (i = 0; i < yres; i++) { for (j = 0; j < xres; j++) { if (fprintf(fh, "%g%c", d[i*xres + j], j == xres-1 ? '\n' : '\t') < 2) { unlink(filename); return FALSE; } } } fclose(fh); return TRUE; }
static void gwy_data_field_absdiff_line_correct(GwyDataField *dfield) { MedianLineData mldata; gint xres, yres, i, j; gdouble shift, csum, mindiff, maxdiff, x; gdouble *d; yres = gwy_data_field_get_yres(dfield); xres = gwy_data_field_get_xres(dfield); d = gwy_data_field_get_data(dfield); csum = 0.0; mldata.n = xres; for (i = 1; i < yres; i++) { mldata.a = d + xres*(i - 1); mldata.b = d + xres*i; mindiff = G_MAXDOUBLE; maxdiff = -G_MAXDOUBLE; for (j = 0; j < xres; j++) { x = mldata.b[j] - mldata.a[j]; if (x < mindiff) mindiff = x; if (x > maxdiff) maxdiff = x; } shift = find_minima_golden(sum_of_abs_diff, mindiff, maxdiff, &mldata); gwy_data_field_area_add(dfield, 0, i, xres, 1, -shift); csum -= shift; } gwy_data_field_add(dfield, -csum/(xres*yres)); }
static void line_correct_median_difference(GwyContainer *data, GwyRunType run) { GwyDataField *dfield; gdouble *diffs, *row, *prev; gint xres, yres, i, j; gdouble median; GQuark dquark; g_return_if_fail(run & GWY_RUN_IMMEDIATE); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, GWY_APP_DATA_FIELD_KEY, &dquark, 0); g_return_if_fail(dfield && dquark); gwy_app_undo_qcheckpointv(data, 1, &dquark); xres = gwy_data_field_get_xres(dfield); yres = gwy_data_field_get_yres(dfield); row = gwy_data_field_get_data(dfield); diffs = g_new(gdouble, xres); for (i = 1; i < yres; i++) { prev = row; row += xres; for (j = 0; j < xres; j++) diffs[j] = prev[j] - row[j]; median = gwy_math_median(xres, diffs); for (j = 0; j < xres; j++) row[j] += median; } g_free(diffs); gwy_data_field_data_changed(dfield); }
/* create a smaller copy of data */ static GwyContainer* create_preview_data(GwyContainer *data, GwyDataField *dfield, gint id) { GwyContainer *pdata; GwyDataField *pfield; gint xres, yres; gdouble zoomval; pdata = gwy_container_new(); xres = gwy_data_field_get_xres(dfield); yres = gwy_data_field_get_yres(dfield); zoomval = (gdouble)PREVIEW_SIZE/MAX(xres, yres); xres = MAX(xres*zoomval, 3); yres = MAX(yres*zoomval, 3); pfield = gwy_data_field_new_resampled(dfield, xres, yres, GWY_INTERPOLATION_ROUND); gwy_container_set_object_by_name(pdata, "/0/data", pfield); g_object_unref(pfield); pfield = gwy_data_field_new_alike(pfield, FALSE); gwy_container_set_object_by_name(pdata, "/0/show", pfield); g_object_unref(pfield); gwy_app_sync_data_items(data, pdata, id, 0, FALSE, GWY_DATA_ITEM_GRADIENT, 0); return pdata; }
static void gwy_data_field_mark_facets(GwyDataField *dtheta, GwyDataField *dphi, gdouble theta0, gdouble phi0, gdouble tolerance, GwyDataField *mask) { gdouble cr, cth0, sth0, cro; const gdouble *xd, *yd; gdouble *md; gint i; cr = cos(tolerance); cth0 = cos(theta0); sth0 = sin(theta0); xd = gwy_data_field_get_data_const(dtheta); yd = gwy_data_field_get_data_const(dphi); md = gwy_data_field_get_data(mask); for (i = gwy_data_field_get_xres(dtheta)*gwy_data_field_get_yres(dtheta); i; i--, xd++, yd++, md++) { cro = cth0*cos(*xd) + sth0*sin(*xd)*cos(*yd - phi0); *md = (cro >= cr); } }
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 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 void plot_correlated(GwyDataField *retfield, gint xsize, gint ysize, gdouble threshold) { GwyDataField *tmp; gint xres, yres, i, j, col, row, w, h; const gdouble *data; tmp = gwy_data_field_duplicate(retfield); gwy_data_field_clear(retfield); xres = gwy_data_field_get_xres(retfield); yres = gwy_data_field_get_yres(retfield); data = gwy_data_field_get_data_const(tmp); /* FIXME: this is very inefficient */ for (i = 0; i < yres; i++) { row = MAX(i - ysize/2, 0); h = MIN(i + ysize - ysize/2, yres) - row; for (j = 0; j < xres; j++) { if (data[i*xres + j] > threshold) { col = MAX(j - xsize/2, 0); w = MIN(j + xsize - xsize/2, xres) - col; gwy_data_field_area_fill(retfield, col, row, w, h, 1.0); } } } g_object_unref(tmp); }
static GwyDataField* make_mask_field(GwyDataField *dfield, const guchar *data) { GwyDataField *mfield; guint xres, yres, i, j, rowstride; const guchar *datarow; gdouble *d; xres = gwy_data_field_get_xres(dfield); yres = gwy_data_field_get_yres(dfield); rowstride = xres; /* Do not create the mask if it is all zero. */ for (i = 0; i < rowstride*yres; i++) { if (!data[i]) break; } if (i == rowstride*yres) return NULL; mfield = gwy_data_field_new_alike(dfield, FALSE); d = gwy_data_field_get_data(mfield); for (i = 0; i < yres; i++) { datarow = data + (yres-1 - i)*rowstride; for (j = 0; j < xres; j++) { *(d++) = datarow[j]; } } return mfield; }
static void noise_synth_do(const NoiseSynthArgs *args, const GwyDimensionArgs *dimsargs, GwyDataField *dfield) { const NoiseSynthGenerator *generator; PointNoiseFunc point_noise; GwyRandGenSet *rngset; gdouble *data; gdouble sigma; gint xres, yres, i; generator = get_point_noise_generator(args->distribution); point_noise = generator->point_noise[args->direction]; rngset = gwy_rand_gen_set_new(1); gwy_rand_gen_set_init(rngset, args->seed); xres = gwy_data_field_get_xres(dfield); yres = gwy_data_field_get_yres(dfield); data = gwy_data_field_get_data(dfield); sigma = args->sigma * pow10(dimsargs->zpow10); for (i = 0; i < xres*yres; i++) data[i] += point_noise(rngset, sigma); gwy_rand_gen_set_free(rngset); }
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 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 void line_correct_step_iter(GwyDataField *dfield, GwyDataField *mask) { const gdouble threshold = 3.0; gint xres, yres, i, j, len; gdouble u, v, w; const gdouble *d, *drow; gdouble *m, *mrow; yres = gwy_data_field_get_yres(dfield); xres = gwy_data_field_get_xres(dfield); d = gwy_data_field_get_data_const(dfield); m = gwy_data_field_get_data(mask); w = 0.0; for (i = 0; i < yres-1; i++) { drow = d + i*xres; for (j = 0; j < xres; j++) { v = drow[j + xres] - drow[j]; w += v*v; } } w = w/(yres-1)/xres; for (i = 0; i < yres-2; i++) { drow = d + i*xres; mrow = m + (i + 1)*xres; for (j = 0; j < xres; j++) { u = drow[xres + j]; v = (u - drow[j])*(u - drow[j + 2*xres]); if (G_UNLIKELY(v > threshold*w)) { if (2*u - drow[j] - drow[j + 2*xres] > 0) mrow[j] = 1.0; else mrow[j] = -1.0; } } len = 1; for (j = 1; j < xres; j++) { if (mrow[j] == mrow[j-1]) len++; else { if (mrow[j-1]) calcualte_segment_correction(drow + j-len, mrow + j-len, xres, len); len = 1; } } if (mrow[j-1]) { calcualte_segment_correction(drow + j-len, mrow + j-len, xres, len); } } gwy_data_field_sum_fields(dfield, dfield, mask); }
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 presentation_logscale(GwyContainer *data, GwyRunType run) { GwyDataField *dfield, *sfield; GQuark squark; gdouble *d; gdouble min, max, m0; gint xres, yres, i, zeroes, id; g_return_if_fail(run & PRESENTATIONOPS_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, GWY_APP_SHOW_FIELD_KEY, &squark, GWY_APP_SHOW_FIELD, &sfield, GWY_APP_DATA_FIELD_ID, &id, 0); g_return_if_fail(dfield && squark); xres = gwy_data_field_get_xres(dfield); yres = gwy_data_field_get_yres(dfield); gwy_app_undo_qcheckpointv(data, 1, &squark); if (!sfield) { sfield = gwy_data_field_duplicate(dfield); gwy_container_set_object(data, squark, sfield); g_object_unref(sfield); } else { gwy_data_field_resample(sfield, xres, yres, GWY_INTERPOLATION_NONE); gwy_data_field_copy(dfield, sfield, FALSE); } d = gwy_data_field_get_data(sfield); zeroes = 0; max = 0; min = G_MAXDOUBLE; for (i = 0; i < xres*yres; i++) { d[i] = ABS(d[i]); if (G_UNLIKELY(d[i] > max)) max = d[i]; if (d[i] == 0.0) zeroes++; else if (G_UNLIKELY(d[i] < min)) min = d[i]; } if (min == max || zeroes == xres*yres) return; if (!zeroes) { for (i = 0; i < xres*yres; i++) d[i] = log(d[i]); } else { m0 = log(min) - log(max/min)/512.0; for (i = 0; i < xres*yres; i++) d[i] = d[i] ? log(d[i]) : m0; } gwy_data_field_data_changed(sfield); gwy_app_channel_log_add_proc(data, id, id); }
static void dwt(GwyContainer *data, GwyRunType run) { GtkWidget *dialog; GwyDataField *dfield; GwyDataLine *wtcoefs; DWTArgs args; gboolean ok; gint xsize, ysize, newsize, newid, oldid, i; g_return_if_fail(run & DWT_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, GWY_APP_DATA_FIELD_ID, &oldid, 0); g_return_if_fail(dfield); xsize = gwy_data_field_get_xres(dfield); ysize = gwy_data_field_get_yres(dfield); if (xsize != ysize) { dialog = gtk_message_dialog_new (gwy_app_find_window_for_channel(data, oldid), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("%s: Data must be square."), "DWT"); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); return; } for (newsize = 1, i = xsize-1; i; i >>= 1, newsize <<= 1) ; dwt_load_args(gwy_app_settings_get(), &args); if (run == GWY_RUN_INTERACTIVE) { ok = dwt_dialog(&args, xsize, newsize); dwt_save_args(gwy_app_settings_get(), &args); if (!ok) return; } dfield = gwy_data_field_new_resampled(dfield, newsize, newsize, args.interp); gwy_data_field_add(dfield, -gwy_data_field_get_avg(dfield)); wtcoefs = GWY_DATA_LINE(gwy_data_line_new(10, 10, TRUE)); wtcoefs = gwy_dwt_set_coefficients(wtcoefs, args.wavelet); gwy_data_field_dwt(dfield, wtcoefs, 1, 4); newid = gwy_app_data_browser_add_data_field(dfield, data, TRUE); g_object_unref(dfield); gwy_app_set_data_field_title(data, newid, _("DWT")); gwy_app_sync_data_items(data, data, oldid, newid, FALSE, GWY_DATA_ITEM_PALETTE, 0); g_object_unref(wtcoefs); }
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 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 immerse_find_maximum(GwyDataField *score, gint *col, gint *row) { const gdouble *d; gint i, n, m; d = gwy_data_field_get_data_const(score); n = gwy_data_field_get_xres(score)*gwy_data_field_get_yres(score); m = 0; for (i = 1; i < n; i++) { if (d[i] > d[m]) m = i; } *row = m/gwy_data_field_get_xres(score); *col = m % gwy_data_field_get_xres(score); }
static void prof_update_curve(ProfControls *controls, gint i) { GwyGraphCurveModel *gcmodel; gdouble xy[4], h; gint xl0, yl0, xl1, yl1; gint n, lineres; gchar *desc; g_return_if_fail(gwy_selection_get_object(controls->selection, i, xy)); /* The ω=0 pixel is always at res/2, for even dimensions it means it is * shifted half-a-pixel to the right from the precise centre. */ xl0 = gwy_data_field_get_xres(controls->psdffield)/2; yl0 = gwy_data_field_get_yres(controls->psdffield)/2; xl1 = floor(gwy_data_field_rtoj(controls->psdffield, xy[0])); yl1 = floor(gwy_data_field_rtoi(controls->psdffield, xy[1])); xy[0] += gwy_data_field_get_xoffset(controls->psdffield); xy[1] += gwy_data_field_get_yoffset(controls->psdffield); h = hypot(controls->hx*xy[0], controls->hy*xy[1])/hypot(xy[0], xy[1]); if (!controls->args->fixres) { lineres = GWY_ROUND(hypot(abs(xl0 - xl1) + 1, abs(yl0 - yl1) + 1)); lineres = MAX(lineres, MIN_RESOLUTION); } else lineres = controls->args->resolution; gwy_data_field_get_profile(controls->psdffield, controls->line, xl0, yl0, xl1, yl1, lineres, 1, controls->args->interpolation); gwy_data_line_multiply(controls->line, h); n = gwy_graph_model_get_n_curves(controls->gmodel); if (i < n) { gcmodel = gwy_graph_model_get_curve(controls->gmodel, i); } else { gcmodel = gwy_graph_curve_model_new(); g_object_set(gcmodel, "mode", GWY_GRAPH_CURVE_LINE, "color", gwy_graph_get_preset_color(i), NULL); gwy_graph_model_add_curve(controls->gmodel, gcmodel); g_object_unref(gcmodel); } gwy_graph_curve_model_set_data_from_dataline(gcmodel, controls->line, 0, 0); desc = g_strdup_printf(_("PSDF %.0f°"), 180.0/G_PI*atan2(-xy[1], xy[0])); g_object_set(gcmodel, "description", desc, NULL); g_free(desc); }
static void tip_process(TipModelArgs *args, TipModelControls *controls) { const GwyTipModelPreset *preset; GwyDataField *dfield; GwyDataField *sfield; GQuark quark; gchar label[64]; gint xres, yres; gdouble xstep, ystep, min, max, zrange; gdouble params[2]; preset = gwy_tip_model_get_preset(args->type); g_return_if_fail(preset); tip_model_dialog_update_values(controls, args); /* estimate x and y size */ dfield = controls->tip; quark = gwy_app_get_data_key_for_id(args->object.id); sfield = GWY_DATA_FIELD(gwy_container_get_object(args->object.data, quark)); gwy_data_field_set_xreal(dfield, gwy_data_field_get_xmeasure(sfield) *gwy_data_field_get_xres(dfield)); gwy_data_field_set_yreal(dfield, gwy_data_field_get_ymeasure(sfield) *gwy_data_field_get_yres(dfield)); params[0] = args->nsides; params[1] = args->angle*G_PI/180; gwy_data_field_get_min_max(sfield, &min, &max); zrange = max - min; preset->guess(sfield, zrange, args->radius, params, &xres, &yres); /* process tip */ /* FIXME: this must be solved within guess functions */ xres = CLAMP(xres, 20, 1000); yres = CLAMP(yres, 20, 1000); g_snprintf(label, sizeof(label), _("Tip resolution: %d × %d pixels"), xres, yres); gtk_label_set_text(GTK_LABEL(controls->labsize), label); xstep = gwy_data_field_get_xmeasure(dfield); ystep = gwy_data_field_get_ymeasure(dfield); gwy_data_field_resample(dfield, xres, yres, GWY_INTERPOLATION_NONE); gwy_data_field_set_xreal(dfield, xstep*xres); gwy_data_field_set_yreal(dfield, ystep*yres); preset->func(dfield, zrange, args->radius, args->theta*G_PI/180, params); tip_update(controls, args); }
static inline gboolean gwy_data_field_inside(GwyDataField *data_field, gint i, gint j) { if (i >= 0 && j >= 0 && i < gwy_data_field_get_xres(data_field) && j < gwy_data_field_get_yres(data_field)) return TRUE; else return FALSE; }
/*integrate over some volume around particle (ax, ay, az), if there is substrate, add this to potential*/ static gdouble integrate_lj_substrate(GwyDataField *lfield, gdouble ax, gdouble ay, gdouble az, gdouble size) { /*make l-j only from idealistic substrate now*/ gdouble zval, sigma, dist; sigma = 1.2*size; //empiric zval = gwy_data_field_get_val(lfield, CLAMP(gwy_data_field_rtoi(lfield, ax), 0, gwy_data_field_get_xres(lfield)-1), CLAMP(gwy_data_field_rtoi(lfield, ay), 0, gwy_data_field_get_yres(lfield)-1)); dist = sqrt((az-zval)*(az-zval)); //printf("%g %g \n", dist, (pow(sigma, 12)/45.0/pow(dist, 9) - pow(sigma, 6)/6.0/pow(dist, 3))); return 1e18*(pow(sigma, 12)/45.0/pow(dist, 9) - pow(sigma, 6)/6.0/pow(dist, 3)); }
static void find_score_maximum(GwyDataField *correlation_score, gint *max_col, gint *max_row) { gint i, n, maxi = 0; gdouble max = -G_MAXDOUBLE; const gdouble *data; n = gwy_data_field_get_xres(correlation_score) *gwy_data_field_get_yres(correlation_score); data = gwy_data_field_get_data_const(correlation_score); for (i = 0; i < n; i++) { if (max < data[i]) { max = data[i]; maxi = i; } } *max_row = (gint)floor(maxi/gwy_data_field_get_xres(correlation_score)); *max_col = maxi - (*max_row)*gwy_data_field_get_xres(correlation_score); }
static GwyDataField* median_background(gint size, GwyDataField *dfield) { GwyDataField *rfield; gint *circle; gdouble *data, *rdata, *buffer; gint i, j, xres, yres, buflen; data = gwy_data_field_get_data(dfield); rfield = gwy_data_field_duplicate(dfield); xres = gwy_data_field_get_xres(rfield); yres = gwy_data_field_get_yres(rfield); rdata = gwy_data_field_get_data(rfield); buflen = 0; circle = median_make_circle(size); for (i = 0; i < 2*size + 1; i++) buflen += 2*circle[i] + 1; buffer = g_new(gdouble, buflen); for (i = 0; i < yres; i++) { for (j = 0; j < xres; j++) { gint n, k, from, to; n = 0; for (k = MAX(0, i - size); k <= MIN(yres - 1, i + size); k++) { gdouble *row = data + k*xres; from = MAX(0, j - circle[k - i + size]); to = MIN(xres - 1, j + circle[k - i + size]); memcpy(buffer + n, row + from, (to - from + 1)*sizeof(gdouble)); n += to - from + 1; } rdata[i*xres + j] = gwy_math_median(n, buffer); } if (i % 10 == 0 && !gwy_app_wait_set_fraction((gdouble)i/yres)) { g_free(circle); g_object_unref(rfield); return NULL; } } g_free(circle); return rfield; }