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 GwyDataField* sphrev_vertical(Sphrev1DArgs *args, GwyDataField *dfield) { GwyDataField *rfield; GwyDataLine *sphere; gdouble *data, *rdata, *sphdata, *sum, *sum2, *weight, *tmp; gdouble q; gint i, j, k, size, xres, yres; 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); q = gwy_data_field_get_rms(dfield)/sqrt(2.0/3.0 - G_PI/16.0); sphere = sphrev_make_sphere(args->size, gwy_data_field_get_yres(dfield)); /* Scale-freeing. * Data is normalized to have the same RMS as if it was composed from * spheres of radius args->radius. Actually we normalize the sphere * instead, but the effect is the same. */ gwy_data_line_multiply(sphere, -q); sphdata = gwy_data_line_get_data(sphere); size = gwy_data_line_get_res(sphere)/2; sum = g_new(gdouble, 4*yres); sum2 = sum + yres; weight = sum + 2*yres; tmp = sum + 3*yres; /* Weights for RMS filter. The xresl-proof way is to sum 1's. */ for (j = 0; j < yres; j++) weight[j] = 1.0; moving_sums(yres, weight, sum, size); memcpy(weight, sum, yres*sizeof(gdouble)); for (i = 0; i < xres; i++) { gdouble *rcol = rdata + i; gdouble *dcol = data + i; /* Kill data that stick down too much */ for (j = 0; j < yres; j++) tmp[j] = dcol[j*xres]; moving_sums(yres, tmp, sum, size); for (j = 0; j < yres; j++) { /* transform to avg - 2.5*rms */ sum[j] = sum[j]/weight[j]; sum2[j] = 2.5*sqrt(sum2[j]/weight[j] - sum[j]*sum[j]); sum[j] -= sum2[j]; } for (j = 0; j < yres; j++) tmp[j] = MAX(dcol[j*xres], sum[j]); /* Find the touching point */ for (j = 0; j < yres; j++) { gdouble *col = tmp + j; gint from, to, km; gdouble min; from = MAX(0, j-size) - j; to = MIN(j+size, yres-1) - j; min = G_MAXDOUBLE; km = 0; for (k = from; k <= to; k++) { if (-(sphdata[size+k] - col[k]) < min) { min = -(sphdata[size+k] - col[k]); km = k; } } rcol[j*xres] = min; } } g_free(sum); g_object_unref(sphere); return rfield; }
static GwySpectra* omicron_read_cs_data(OmicronFile *ofile, OmicronSpectroChannel *channel, GError **error) { GError *err = NULL; GwyDataLine *dline; GwySIUnit *siunit = NULL, *coord_unit = NULL; GwySpectra *spectra = NULL; GPtrArray *spectrum = NULL; gchar *filename; gdouble *data, x, y; gdouble *coords = NULL; gchar *buffer; gdouble scale; guint i, j; gint power10 = 0; gint ncurves = 0; gchar* line; filename = omicron_fix_file_name(ofile->filename, channel->filename, error); if (!filename) return NULL; gwy_debug("Succeeded with <%s>", filename); if (!g_file_get_contents(filename, &buffer, NULL , &err)) { g_free(filename); err_GET_FILE_CONTENTS(error, &err); return NULL; } g_free(filename); scale = channel->resolution; /* can also be extracted from min&max raw and phys settings */ while ((line = gwy_str_next_line(&buffer))) { if (strstr(line, ";n_curves")) { /* Find number of curves this should appear first in file */ ncurves = g_ascii_strtod(strchr(line, ':')+1, NULL); } if (strstr(line, "BEGIN COORD")) { /* Read in cordinates Spectroscopy Curves */ i = 0; coord_unit = gwy_si_unit_new_parse("nm", &power10); while ((line = gwy_str_next_line(&buffer))) { gchar *val2; if (strstr(line, "END")) { if (i != ncurves) { gwy_debug("Less coords than ncurves"); } break; } if (i == ncurves) { g_critical("More coords than ncurves."); break; } if (!coords) { if (!(coords = g_new0(gdouble, ncurves*2))) { gwy_debug("Failed to allocate mem: coords"); return NULL; } } val2 = line+16; x = g_ascii_strtod(line, &val2) * pow10(power10); y = g_ascii_strtod(val2, NULL) * pow10(power10); gwy_debug("Coord %i: x:%g y:%g", i, x, y); coords[2*i] = x; coords[2*i+1] = y; i++; } /* i is set to 0 and used as a counter for the dline */ i = 0; } if (strstr(line, "BEGIN") && !strstr(line, "COORD")) { /* Read spectroscopy points */ dline = gwy_data_line_new(channel->npoints, channel->end - channel->start, FALSE); gwy_data_line_set_offset(dline, (channel->start)); data = gwy_data_line_get_data(dline); j = 0; while ((line = gwy_str_next_line(&buffer))) { gchar *val2; if (strstr(line, "END") || j >= channel->npoints) break; val2 = line+13; x = g_ascii_strtod(line, &val2); y = g_ascii_strtod(val2, NULL)*scale; data[j] = y; j++; } /* Set Units for the parameter (x) axis */ if ((channel->param[0] == 'V') || (channel->param[0] == 'E')) { siunit = gwy_si_unit_new("V"); power10 = 0; } else if (channel->param[0] == 'I') siunit = gwy_si_unit_new_parse("nA", &power10); else if (channel->param[0] == 'Z') siunit = gwy_si_unit_new_parse("nm", &power10); else { gwy_debug("Parameter unit not recognised"); } if (siunit) { gwy_data_line_set_si_unit_x(dline, siunit); g_object_unref(siunit); } if (power10) { gdouble offset = 0; gdouble realsize = 0; offset = gwy_data_line_get_offset(dline)*pow10(power10); realsize = gwy_data_line_get_real(dline)*pow10(power10); gwy_data_line_set_offset(dline, offset); gwy_data_line_set_real(dline, realsize); } /* Set Units for the Value (y) Axis */ siunit = gwy_si_unit_new_parse(channel->units, &power10); gwy_data_line_set_si_unit_y(dline, siunit); g_object_unref(siunit); if (power10) gwy_data_line_multiply(dline, pow10(power10)); if (!spectrum) spectrum = g_ptr_array_sized_new(ncurves); g_ptr_array_add(spectrum, dline); } } if (!spectrum) spectrum = g_ptr_array_new(); if (spectrum->len < ncurves) { gwy_debug("Less actual spectra than ncurves"); ncurves = spectrum->len; } if (spectrum->len > ncurves) { gwy_debug("More actual spectra than ncurves, " "remaining pos will be set at (0.0,0.0)"); coords = g_renew(gdouble, coords, spectrum->len*2); if (!coords) { g_critical("Could not reallocate mem for coords."); return NULL; } while (spectrum->len > ncurves) { coords[ncurves*2] = 0.0; coords[ncurves*2+1] = 0.0; ncurves++; } } spectra = gwy_spectra_new(); if (coord_unit) { gwy_spectra_set_si_unit_xy(spectra, coord_unit); g_object_unref(coord_unit); } for (i = 0; i < ncurves; i++) { dline = g_ptr_array_index(spectrum, i); gwy_spectra_add_spectrum(spectra, dline, coords[i*2], ofile->yreal - coords[i*2+1]); g_object_unref(dline); } g_ptr_array_free(spectrum, TRUE); g_free(coords); g_free(buffer); return spectra; }