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 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 void crop_result(GwyDataField *result, GwyDataField *dfield1, GwyDataField *dfield2, GwyOrientation orientation, gint px1, gint py1, gint px2, gint py2) { if (orientation == GWY_ORIENTATION_HORIZONTAL) { gint top = MAX(MAX(py1, py2), 0); gint bot = MIN(MIN(dfield1->yres + py1, dfield2->yres + py2), result->yres); gdouble yreal = (bot - top)*gwy_data_field_get_ymeasure(result); g_return_if_fail(bot > top); gwy_data_field_resize(result, 0, top, result->xres, bot); gwy_data_field_set_yreal(result, yreal); } else { gint left = MAX(MAX(px1, px2), 0); gint right = MIN(MIN(dfield1->xres + px1, dfield2->xres + px2), result->xres); gdouble xreal = (right - left)*gwy_data_field_get_xmeasure(result); g_return_if_fail(right > left); gwy_data_field_resize(result, left, 0, right, result->yres); gwy_data_field_set_xreal(result, xreal); } }
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 fix_scales(EZDSection *section, gint idx, GwyContainer *container) { GwyDataField *dfield; GwySIUnit *siunit; gchar key[40]; gint power10; gdouble r; g_snprintf(key, sizeof(key), "/%d/data", idx); dfield = GWY_DATA_FIELD(gwy_container_get_object_by_name(container, key)); /* Fix value scale */ siunit = gwy_si_unit_new_parse(section->zrange.unit, &power10); gwy_data_field_set_si_unit_z(dfield, siunit); g_object_unref(siunit); r = pow10(power10); gwy_data_field_multiply(dfield, r*section->zrange.range); gwy_data_field_add(dfield, r*section->zrange.min); /* Fix lateral scale */ siunit = gwy_si_unit_new_parse(section->xrange.unit, &power10); gwy_data_field_set_si_unit_xy(dfield, siunit); g_object_unref(siunit); gwy_data_field_set_xreal(dfield, pow10(power10)*section->xrange.range); siunit = gwy_si_unit_new_parse(section->yrange.unit, &power10); gwy_data_field_set_yreal(dfield, pow10(power10)*section->yrange.range); g_object_unref(siunit); /* Some metadata */ if (section->zrange.name) { const gchar *s; switch (section->direction) { case SCAN_FORWARD: s = " forward"; break; case SCAN_BACKWARD: s = " backward"; break; default: s = ""; break; } g_snprintf(key, sizeof(key), "/%d/data/title", idx); gwy_container_set_string_by_name(container, key, g_strdup_printf("%s%s", section->zrange.name, s)); } }
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; }
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 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_data_field_facet_distribution(GwyDataField *dfield, gint kernel_size, GwyContainer *container) { GwyDataField *dtheta, *dphi, *dist; GwySIUnit *siunit; gdouble *xd, *yd, *data; const gdouble *xdc, *ydc; gdouble q, max; gint res, hres, i, j, mi, mj, xres, yres; if (gwy_container_gis_object_by_name(container, "/theta", &dtheta)) g_object_ref(dtheta); else dtheta = gwy_data_field_new_alike(dfield, FALSE); if (gwy_container_gis_object_by_name(container, "/phi", &dphi)) g_object_ref(dphi); else dphi = gwy_data_field_new_alike(dfield, FALSE); compute_slopes(dfield, kernel_size, dtheta, dphi); xres = gwy_data_field_get_xres(dfield); yres = gwy_data_field_get_yres(dfield); xd = gwy_data_field_get_data(dtheta); yd = gwy_data_field_get_data(dphi); for (i = xres*yres; i; i--, xd++, yd++) { gdouble theta, phi; slopes_to_angles(*xd, *yd, &theta, &phi); *xd = theta; *yd = phi; } q = gwy_data_field_get_max(dtheta); q = MIN(q*1.05, G_PI/2.0); q = G_SQRT2/(2.0*sin(q/2.0)); if (gwy_container_gis_object_by_name(container, "/0/data", &dist)) { g_object_ref(dist); gwy_data_field_clear(dist); gwy_data_field_set_xreal(dist, 2.0*G_SQRT2/q); gwy_data_field_set_yreal(dist, 2.0*G_SQRT2/q); } else { dist = gwy_data_field_new(FDATA_RES, FDATA_RES, 2.0*G_SQRT2/q, 2.0*G_SQRT2/q, TRUE); siunit = gwy_si_unit_new(""); gwy_data_field_set_si_unit_z(dist, siunit); g_object_unref(siunit); /* FIXME */ siunit = gwy_si_unit_new(""); gwy_data_field_set_si_unit_xy(dist, siunit); g_object_unref(siunit); } res = FDATA_RES; hres = (res - 1)/2; data = gwy_data_field_get_data(dist); xdc = gwy_data_field_get_data_const(dtheta); ydc = gwy_data_field_get_data_const(dphi); for (i = xres*yres; i; i--, xdc++, ydc++) { gdouble x, y; gint xx, yy; angles_to_xy(*xdc, *ydc, &x, &y); xx = GWY_ROUND(q*x/G_SQRT2*hres) + hres; yy = GWY_ROUND(q*y/G_SQRT2*hres) + hres; data[yy*res + xx] += 1.0; } /* Find maxima */ mi = mj = hres; max = 0; for (i = 1; i+1 < res; i++) { for (j = 1; j+1 < res; j++) { gdouble z; z = data[i*res + j] + 0.3*(data[i*res + j - 1] + data[i*res + j + 1] + data[i*res - res + j] + data[i*res + res + j]) + 0.1*(data[i*res - res + j - 1] + data[i*res - res + j + 1] + data[i*res + res + j - 1] + data[i*res + res + j + 1]); if (G_UNLIKELY(z > max)) { max = z; mi = i; mj = j; } } } for (i = res*res; i; i--, data++) *data = pow(*data, 0.35); gwy_container_set_double_by_name(container, "/q", q); { gdouble x, y, theta, phi; x = (mj - hres)*G_SQRT2/(q*hres); y = (mi - hres)*G_SQRT2/(q*hres); xy_to_angles(x, y, &theta, &phi); gwy_container_set_double_by_name(container, "/theta0", theta); gwy_container_set_double_by_name(container, "/phi0", phi); } gwy_container_set_object_by_name(container, "/0/data", dist); g_object_unref(dist); gwy_container_set_object_by_name(container, "/theta", dtheta); g_object_unref(dtheta); gwy_container_set_object_by_name(container, "/phi", dphi); g_object_unref(dphi); gwy_container_set_string_by_name(container, "/0/base/palette", g_strdup(FVIEW_GRADIENT)); gwy_data_field_data_changed(dist); }
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 void put_fields(GwyDataField *dfield1, GwyDataField *dfield2, GwyDataField *result, GwyDataField *outsidemask, GwyMergeBoundaryType boundary, gint px1, gint py1, gint px2, gint py2) { GwyRectangle res_rect; GwyCoord f1_pos; GwyCoord f2_pos; gint w1, w2, h1, h2; gdouble xreal, yreal; gwy_debug("field1 %dx%d", dfield1->xres, dfield1->yres); gwy_debug("field2 %dx%d", dfield2->xres, dfield2->yres); gwy_debug("result %dx%d", result->xres, result->yres); gwy_debug("px1: %d, py1: %d, px2: %d, py2: %d", px1, py1, px2, py2); gwy_data_field_fill(result, MIN(gwy_data_field_get_min(dfield1), gwy_data_field_get_min(dfield2))); w1 = gwy_data_field_get_xres(dfield1); h1 = gwy_data_field_get_yres(dfield1); w2 = gwy_data_field_get_xres(dfield2); h2 = gwy_data_field_get_yres(dfield2); if (boundary == GWY_MERGE_BOUNDARY_SECOND) { gwy_data_field_area_copy(dfield1, result, 0, 0, w1, h1, px1, py1); gwy_data_field_area_copy(dfield2, result, 0, 0, w2, h2, px2, py2); } else { gwy_data_field_area_copy(dfield2, result, 0, 0, w2, h2, px2, py2); gwy_data_field_area_copy(dfield1, result, 0, 0, w1, h1, px1, py1); } if (outsidemask) { gwy_data_field_fill(outsidemask, 1.0); gwy_data_field_area_clear(outsidemask, px1, py1, w1, h1); gwy_data_field_area_clear(outsidemask, px2, py2, w2, h2); } /* adjust boundary to be as smooth as possible */ if (boundary == GWY_MERGE_BOUNDARY_AVERAGE || boundary == GWY_MERGE_BOUNDARY_INTERPOLATE) { if (px1 < px2) { res_rect.x = px2; res_rect.width = px1 + w1 - px2; } else { res_rect.x = px1; res_rect.width = px2 + w2 - px1; } if (py1 < py2) { res_rect.y = py2; res_rect.height = py1 + h1 - py2; } else { res_rect.y = py1; res_rect.height = py2 + h2 - py1; } res_rect.height = MIN(res_rect.height, MIN(h1, h2)); res_rect.width = MIN(res_rect.width, MIN(w1, w2)); /* This is where the result rectangle is positioned in the fields, * not where the fields themselves are placed! */ f1_pos.x = res_rect.x - px1; f1_pos.y = res_rect.y - py1; f2_pos.x = res_rect.x - px2; f2_pos.y = res_rect.y - py2; merge_boundary(dfield1, dfield2, result, res_rect, f1_pos, f2_pos, boundary); } /* Use the pixels sizes of field 1 -- they must be identical. */ xreal = result->xres * gwy_data_field_get_xmeasure(dfield1); yreal = result->yres * gwy_data_field_get_ymeasure(dfield1); gwy_data_field_set_xreal(result, xreal); gwy_data_field_set_yreal(result, yreal); if (outsidemask) { gwy_data_field_set_xreal(outsidemask, xreal); gwy_data_field_set_yreal(outsidemask, yreal); } }
static GwyContainer* gxsm_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { static const gchar *dimensions[] = { "time", "value", "dimy", "dimx" }; GwyContainer *data = NULL; GwyDataField *dfield; GwySIUnit *siunit; NetCDF cdffile; const NetCDFDim *dim; const NetCDFVar *var; const NetCDFAttr *attr; gdouble real; gint i, power10; if (!cdffile_load(&cdffile, filename, error)) return NULL; if (cdffile.nrecs) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("NetCDF records are not supported.")); goto gxsm_load_fail; } /* Look for variable "H" or "FloatField". This seems to be how GXSM calls * data. */ if (!(var = cdffile_get_var(&cdffile, "H")) && !(var = cdffile_get_var(&cdffile, "FloatField"))) { err_NO_DATA(error); goto gxsm_load_fail; } /* Check the dimensions. We only know how to handle time=1 and value=1. */ for (i = 0; i < var->ndims; i++) { dim = cdffile.dims + var->dimids[i]; if (!gwy_strequal(dim->name, dimensions[i]) || (i < 2 && dim->length != 1)) { /* XXX */ err_NO_DATA(error); goto gxsm_load_fail; } } if (err_DIMENSION(error, cdffile.dims[var->dimids[3]].length) || err_DIMENSION(error, cdffile.dims[var->dimids[2]].length)) goto gxsm_load_fail; dfield = read_data_field((const guchar*)(cdffile.buffer + var->begin), cdffile.dims[var->dimids[3]].length, cdffile.dims[var->dimids[2]].length, var->type); if ((siunit = read_real_size(&cdffile, "rangex", &real, &power10))) { /* Use negated positive conditions to catch NaNs */ if (!((real = fabs(real)) > 0)) { g_warning("Real x size is 0.0, fixing to 1.0"); real = 1.0; } gwy_data_field_set_xreal(dfield, real*pow10(power10)); gwy_data_field_set_si_unit_xy(dfield, siunit); g_object_unref(siunit); } if ((siunit = read_real_size(&cdffile, "rangey", &real, &power10))) { /* Use negated positive conditions to catch NaNs */ if (!((real = fabs(real)) > 0)) { g_warning("Real y size is 0.0, fixing to 1.0"); real = 1.0; } gwy_data_field_set_yreal(dfield, real*pow10(power10)); /* must be the same gwy_data_field_set_si_unit_xy(dfield, siunit); */ g_object_unref(siunit); } if ((siunit = read_real_size(&cdffile, "rangez", &real, &power10))) { /* rangez seems to be some bogus value, take only units */ gwy_data_field_set_si_unit_z(dfield, siunit); gwy_data_field_multiply(dfield, pow10(power10)); g_object_unref(siunit); } if ((siunit = read_real_size(&cdffile, "dz", &real, &power10))) { /* on the other hand the units seem to be bogus here, take the range */ gwy_data_field_multiply(dfield, real); g_object_unref(siunit); } data = gwy_container_new(); gwy_container_set_object_by_name(data, "/0/data", dfield); g_object_unref(dfield); if ((attr = cdffile_get_attr(var->attrs, var->nattrs, "long_name")) && attr->type == NC_CHAR && attr->nelems) { gwy_container_set_string_by_name(data, "/0/data/title", g_strndup(attr->values, attr->nelems)); } gxsm_load_fail: gwy_file_abandon_contents(cdffile.buffer, cdffile.size, NULL); cdffile_free(&cdffile); return data; }
static void psdflp_do(const PSDFLPArgs *args, GwyDataField *dfield, GwyDataField *lpsdf) { enum { N = 4 }; GwyDataField *reout, *imout; gint pxres, pyres, fxres, fyres; gint i, j, fi, pi; gdouble *ldata, *redata, *imdata; gdouble *cosphi, *sinphi; gdouble xreal, yreal, f0, f_max, b, p; reout = gwy_data_field_new_alike(dfield, FALSE); imout = gwy_data_field_new_alike(dfield, FALSE); gwy_data_field_2dfft(dfield, NULL, reout, imout, args->window, GWY_TRANSFORM_DIRECTION_FORWARD, GWY_INTERPOLATION_ROUND, /* Ignored */ TRUE, 1); pxres = reout->xres; pyres = reout->yres; redata = gwy_data_field_get_data(reout); imdata = gwy_data_field_get_data(imout); for (i = 0; i < pxres*pyres; i++) redata[i] = redata[i]*redata[i] + imdata[i]*imdata[i]; gwy_data_field_2dfft_humanize(reout); gwy_data_field_filter_gaussian(reout, args->sigma); for (i = 0; i < pxres*pyres; i++) redata[i] = sqrt(redata[i]); fxres = pxres/2; fyres = pyres/2; gwy_data_field_resample(lpsdf, fxres, fyres, GWY_INTERPOLATION_NONE); ldata = gwy_data_field_get_data(lpsdf); xreal = dfield->xreal; yreal = dfield->yreal; f0 = 2.0/MIN(xreal, yreal); f_max = 0.5*MIN(pxres/xreal, pyres/yreal); if (f_max <= f0) { g_warning("Minimum frequency is not smaller than maximum frequency."); } b = log(f_max/f0)/fyres; /* Incorporate some prefactors to sinphi[] and cosphi[], knowing that * cosine is only ever used for x and sine for y frequencies. */ cosphi = g_new(gdouble, (N+1)*fxres); sinphi = g_new(gdouble, (N+1)*fxres); for (j = 0; j < fxres; j++) { gdouble phi_from = 2.0*G_PI*j/fxres; gdouble phi_to = 2.0*G_PI*(j + 1.0)/fxres; for (pi = 0; pi <= N; pi++) { gdouble phi = ((pi + 0.5)*phi_from + (N - 0.5 - pi)*phi_to)/N; cosphi[j*(N+1) + pi] = cos(phi)*xreal; sinphi[j*(N+1) + pi] = sin(phi)*yreal; } } for (i = 0; i < fyres; i++) { gdouble f_from = f0*exp(b*i); gdouble f_to = f0*exp(b*(i + 1.0)); for (j = 0; j < fxres; j++) { const gdouble *cosphi_j = cosphi + j*(N+1); const gdouble *sinphi_j = sinphi + j*(N+1); guint n = 0; gdouble s = 0.0; for (fi = 0; fi <= N; fi++) { gdouble f = ((fi + 0.5)*f_from + (N - 0.5 - fi)*f_to)/N; for (pi = 0; pi <= N; pi++) { gdouble x = f*cosphi_j[pi] + pxres/2.0, y = f*sinphi_j[pi] + pyres/2.0; if (G_UNLIKELY(x < 0.5 || y < 0.5 || x > pxres - 1.5 || y > pyres - 1.5)) continue; p = gwy_data_field_get_dval(reout, x, y, GWY_INTERPOLATION_SCHAUM); s += p; n++; } } if (!n) n = 1; ldata[i*fxres + j] = 2.0*G_PI/fxres * s/n*(f_to - f_from); } } g_object_unref(imout); g_object_unref(reout); gwy_data_field_set_xreal(lpsdf, 2.0*G_PI); gwy_data_field_set_xoffset(lpsdf, 0.0); gwy_data_field_set_yreal(lpsdf, log(f_max/f0)); gwy_data_field_set_yoffset(lpsdf, log(f0)); gwy_si_unit_set_from_string(gwy_data_field_get_si_unit_xy(lpsdf), ""); gwy_si_unit_set_from_string(gwy_data_field_get_si_unit_z(lpsdf), ""); gwy_data_field_normalize(lpsdf); }
static GwyDataField* igor_read_data_field(const IgorFile *igorfile, const guchar *buffer, guint i, const gchar *zunits, gboolean imaginary) { const IgorWaveHeader5 *wave5; guint n, xres, yres, skip; GwyDataField *dfield; GwySIUnit *unit; gdouble *data; const guchar *p; gint power10; gdouble q; wave5 = &igorfile->wave5; xres = wave5->n_dim[0]; yres = wave5->n_dim[1]; p = buffer + igorfile->headers_size + xres*yres*igorfile->type_size*i; n = xres*yres; dfield = gwy_data_field_new(xres, yres, wave5->sfA[0]*xres, wave5->sfA[1]*yres, FALSE); data = gwy_data_field_get_data(dfield); g_return_val_if_fail(!imaginary || (wave5->type & IGOR_COMPLEX), dfield); skip = imaginary ? igorfile->type_size/2 : 0; if (imaginary) p += skip; /* TODO: Support extended units */ unit = gwy_data_field_get_si_unit_xy(dfield); gwy_si_unit_set_from_string_parse(unit, wave5->dim_units[0], &power10); gwy_data_field_set_xreal(dfield, pow10(power10)*wave5->sfA[0]*xres); gwy_data_field_set_yreal(dfield, pow10(power10)*wave5->sfA[1]*yres); unit = gwy_data_field_get_si_unit_z(dfield); gwy_si_unit_set_from_string_parse(unit, zunits ? zunits : wave5->data_units, &power10); q = pow10(power10); switch ((guint)wave5->type) { case IGOR_INT8: { const gint8 *ps = (const gint8*)buffer; while (n--) { *(data++) = *(ps++) * q; ps += skip; } } break; case IGOR_INT8 | IGOR_UNSIGNED: while (n--) { *(data++) = *(p++) * q; p += skip; } break; case IGOR_INT16: while (n--) { *(data++) = igorfile->get_gint16(&p) * q; p += skip; } break; case IGOR_INT16 | IGOR_UNSIGNED: while (n--) { *(data++) = igorfile->get_guint16(&p) * q; p += skip; } break; case IGOR_INT32: while (n--) { *(data++) = igorfile->get_gint32(&p) * q; p += skip; } break; case IGOR_INT32 | IGOR_UNSIGNED: while (n--) { *(data++) = igorfile->get_guint32(&p) * q; p += skip; } break; case IGOR_SINGLE: while (n--) { *(data++) = igorfile->get_gfloat(&p) * q; p += skip; } break; case IGOR_DOUBLE: while (n--) { *(data++) = igorfile->get_gdouble(&p) * q; p += skip; } break; default: g_return_val_if_reached(NULL); break; } gwy_data_field_invert(dfield, TRUE, FALSE, FALSE); return dfield; }
static GwyContainer* fits_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GwyContainer *container = NULL; fitsfile *fptr = NULL; GwyDataField *field = NULL, *mask; gint status = 0; /* Must be initialised to zero! */ gint hdutype, naxis, anynull, nkeys, k; glong res[3]; /* First index is the fast looping one. */ char strvalue[FLEN_VALUE]; gchar *invalid = NULL; gdouble real, off; if (fits_open_image(&fptr, filename, READONLY, &status)) { err_FITS(error, status); return NULL; } if (fits_get_hdu_type(fptr, &hdutype, &status)) { err_FITS(error, status); goto fail; } gwy_debug("hdutype %d", hdutype); if (hdutype != IMAGE_HDU) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Only two-dimensional images are supported.")); goto fail; } if (fits_get_img_dim(fptr, &naxis, &status)) { err_FITS(error, status); goto fail; } gwy_debug("naxis %d", naxis); if (naxis != 2 && naxis != 3) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Only two-dimensional images are supported.")); goto fail; } if (fits_get_img_size(fptr, naxis, res, &status)) { err_FITS(error, status); goto fail; } if (naxis == 3 && res[2] != 1) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Only two-dimensional images are supported.")); goto fail; } gwy_debug("xres %ld, yres %ld", res[0], res[1]); if (err_DIMENSION(error, res[0]) || err_DIMENSION(error, res[1])) goto fail; field = gwy_data_field_new(res[0], res[1], res[0], res[1], FALSE); invalid = g_new(gchar, res[0]*res[1]); if (fits_read_imgnull(fptr, TDOUBLE, 1, res[0]*res[1], field->data, invalid, &anynull, &status)) { err_FITS(error, status); goto fail; } container = gwy_container_new(); gwy_container_set_object_by_name(container, "/0/data", field); /* Failures here are non-fatal. We already have an image. */ if (fits_get_hdrspace(fptr, &nkeys, NULL, &status)) { g_warning("Cannot get the first hdrspace."); goto fail; } if (!fits_read_key(fptr, TSTRING, "BUINT ", strvalue, NULL, &status)) { gint power10; gwy_debug("BUINT = <%s>", strvalue); gwy_si_unit_set_from_string_parse(gwy_data_field_get_si_unit_z(field), strvalue, &power10); if (power10) gwy_data_field_multiply(field, pow10(power10)); } status = 0; if (get_real_and_offset(fptr, 1, res[0], &real, &off)) { if (real < 0.0) { off += real; real = -real; gwy_data_field_invert(field, FALSE, TRUE, FALSE); } gwy_data_field_set_xreal(field, real); gwy_data_field_set_xoffset(field, off); } if (get_real_and_offset(fptr, 2, res[1], &real, &off)) { if (real < 0.0) { off += real; real = -real; gwy_data_field_invert(field, TRUE, FALSE, FALSE); } gwy_data_field_set_yreal(field, real); gwy_data_field_set_yoffset(field, off); } /* Create a mask of invalid data. */ for (k = 0; k < field->xres*field->yres; k++) { if (invalid[k]) field->data[k] = NAN; } if ((mask = gwy_app_channel_mask_of_nans(field, TRUE))) { gwy_container_set_object_by_name(container, "/0/mask", mask); g_object_unref(mask); } fail: fits_close_file(fptr, &status); gwy_object_unref(field); g_free(invalid); return container; }
static GwyContainer* micromap_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { SDFile sdfile; GwyContainer *container = NULL; gchar *p, *buffer = NULL; gsize len, size = 0; GError *err = NULL; GwyDataField *dfield = NULL; gdouble objectivemag, tubemag, cameraxpixel, cameraypixel; if (!g_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } len = size; p = buffer; if (sdfile_read_header_text(&p, &len, &sdfile, error)) { if (check_params(&sdfile, len, error)) dfield = sdfile_read_data_text(&sdfile, error); } if (!dfield) { g_free(buffer); return NULL; } if (!sdfile.extras) { err_MISSING_FIELD(error, "OBJECTIVEMAG"); goto fail; } if (!require_keys(sdfile.extras, error, "OBJECTIVEMAG", "TUBEMAG", "CAMERAXPIXEL", "CAMERAYPIXEL", NULL)) goto fail; objectivemag = g_ascii_strtod(g_hash_table_lookup(sdfile.extras, "OBJECTIVEMAG"), NULL); tubemag = g_ascii_strtod(g_hash_table_lookup(sdfile.extras, "TUBEMAG"), NULL); cameraxpixel = g_ascii_strtod(g_hash_table_lookup(sdfile.extras, "CAMERAXPIXEL"), NULL); cameraypixel = g_ascii_strtod(g_hash_table_lookup(sdfile.extras, "CAMERAYPIXEL"), NULL); sdfile_set_units(&sdfile, dfield); gwy_data_field_set_xreal(dfield, Micrometer * sdfile.xres * objectivemag * tubemag * cameraxpixel); gwy_data_field_set_yreal(dfield, Micrometer * sdfile.yres * objectivemag * tubemag * cameraypixel); container = gwy_container_new(); gwy_container_set_object_by_name(container, "/0/data", dfield); gwy_container_set_string_by_name(container, "/0/data/title", g_strdup("Topography")); fail: g_object_unref(dfield); g_free(buffer); if (sdfile.extras) g_hash_table_destroy(sdfile.extras); return container; }