static void fit_plot_curve(FitArgs *args) { GwyGraphCurveModel *cmodel; gdouble *xd, *yd; gboolean initial, ok; /* XXX: ignored */ gint i, n; gdouble *param; if (!args->is_fitted && !args->is_estimated) return; initial = !args->is_fitted; n = gwy_nlfit_preset_get_nparams(args->fitfunc); param = g_newa(gdouble, n); for (i = 0; i < n; i++) { FitParamArg *arg; arg = &g_array_index(args->param, FitParamArg, i); param[i] = initial ? arg->init : arg->value; } n = gwy_data_line_get_res(args->xdata); g_return_if_fail(n == gwy_data_line_get_res(args->ydata)); xd = gwy_data_line_get_data(args->xdata); yd = gwy_data_line_get_data(args->ydata); for (i = 0; i < n; i++) yd[i] = gwy_nlfit_preset_get_value(args->fitfunc, xd[i], param, &ok); if (gwy_graph_model_get_n_curves(args->graph_model) == 2) cmodel = gwy_graph_model_get_curve(args->graph_model, 1); else { cmodel = gwy_graph_curve_model_new(); g_object_set(cmodel, "mode", GWY_GRAPH_CURVE_LINE, "color", &args->fitcolor, NULL); gwy_graph_model_add_curve(args->graph_model, cmodel); g_object_unref(cmodel); } g_object_set(cmodel, "description", initial ? gwy_sgettext("Estimate") : gwy_sgettext("Fit"), NULL); gwy_graph_curve_model_set_data(cmodel, xd, yd, n); }
static GwyGraphModel* spectra_to_graph(GwySpectra *spectra) { GwyGraphModel *gmodel; const gchar* graph_title; GwyGraphCurveModel *cmodel; gchar *curve_title = NULL; guint j, k, n_spectra, n_points; GwyDataLine *dline; gdouble *data, *xdata, *ydata, x_offset, x_realsize; GwySIUnit *x_si_unit, *y_si_unit; if (!(n_spectra = gwy_spectra_get_n_spectra(spectra))) { gwy_debug("rhk-spm32: no spectra in rhkpage - something is odd\n"); return NULL; } dline = gwy_spectra_get_spectrum(spectra, 0); n_points = gwy_data_line_get_res(dline); x_si_unit = gwy_data_line_get_si_unit_x(dline); y_si_unit = gwy_data_line_get_si_unit_y(dline); xdata = g_new0(gdouble, n_points); ydata = g_new0(gdouble, n_points); x_offset = gwy_data_line_get_offset(dline); x_realsize = gwy_data_line_get_real(dline); for (j = 0; j < n_points; j++) xdata[j] = x_offset+j*x_realsize; gmodel = gwy_graph_model_new(); g_object_set(gmodel, "si-unit-x", x_si_unit, "si-unit-y", y_si_unit, NULL); graph_title = gwy_spectra_get_title(spectra); g_object_set(gmodel, "title", graph_title, NULL); // tends to obstruct the curves - if there are more than a few - not // good - makes it hard to grab curves? //g_object_set(gmodel, "label-visible", FALSE, NULL); for (k = 1; k <= n_spectra; k++) { dline = gwy_spectra_get_spectrum(spectra, k-1); data = gwy_data_line_get_data(dline); for (j = 0; j < n_points; j++) ydata[j] = data[j]; cmodel = gwy_graph_curve_model_new(); gwy_graph_model_add_curve(gmodel, cmodel); g_object_unref(cmodel); curve_title = g_strdup_printf("%s %d", graph_title, k); g_object_set(cmodel, "description", curve_title, "mode", GWY_GRAPH_CURVE_LINE, "color", gwy_graph_get_preset_color(k), NULL); gwy_graph_curve_model_set_data(cmodel, xdata, ydata, n_points); } g_free(ydata); g_free(xdata); return gmodel; }
static void preview(EntropyControls *controls) { EntropyArgs *args = controls->args; GwyDataField *dfield = controls->dfield; GwyDataField *mfield = controls->mfield; GwyGraphModel *gmodel; GwyGraphCurveModel *gcmodel; GwyDataLine *ecurve; gchar buf[24]; gdouble S, s, Smax = 0.0; ecurve = gwy_data_line_new(1, 1.0, FALSE); if (args->mode == ENTROPY_VALUES) { S = gwy_data_field_area_get_entropy_at_scales(dfield, ecurve, mfield, args->masking, 0, 0, dfield->xres, dfield->yres, 0); s = gwy_data_field_area_get_rms_mask(dfield, mfield, args->masking, 0, 0, dfield->xres, dfield->yres); Smax = ENTROPY_NORMAL + log(s); } else { GwyDataField *xder = gwy_data_field_new_alike(dfield, FALSE); GwyDataField *yder = gwy_data_field_new_alike(dfield, FALSE); compute_slopes(controls->dfield, args->fit_plane ? args->kernel_size : 0, xder, yder); xder = fake_mask(xder, mfield, args->masking); yder = fake_mask(yder, mfield, args->masking); if (args->mode == ENTROPY_ANGLES) transform_to_sphere(xder, yder); S = gwy_data_field_get_entropy_2d_at_scales(xder, yder, ecurve, 0); if (args->mode == ENTROPY_SLOPES) { s = calculate_sigma2_2d(xder, yder); Smax = ENTROPY_NORMAL_2D + log(s); } g_object_unref(xder); g_object_unref(yder); } g_snprintf(buf, sizeof(buf), "%g", S); gtk_label_set_text(GTK_LABEL(controls->entropy), buf); if (args->mode != ENTROPY_ANGLES) { g_snprintf(buf, sizeof(buf), "%g", Smax - S); gtk_label_set_text(GTK_LABEL(controls->entropydef), buf); } else gtk_label_set_text(GTK_LABEL(controls->entropydef), _("N.A.")); gmodel = gwy_graph_get_model(GWY_GRAPH(controls->graph)); gwy_graph_model_remove_all_curves(gmodel); g_object_set(gmodel, "axis-label-bottom", "log h", "axis-label-left", "S", "label-position", GWY_GRAPH_LABEL_NORTHWEST, NULL); if (gwy_data_line_get_min(ecurve) > -0.5*G_MAXDOUBLE) { gcmodel = gwy_graph_curve_model_new(); g_object_set(gcmodel, "description", _("Entropy at scales"), "mode", GWY_GRAPH_CURVE_LINE_POINTS, "color", gwy_graph_get_preset_color(0), NULL); gwy_graph_curve_model_set_data_from_dataline(gcmodel, ecurve, 0, 0); gwy_graph_model_add_curve(gmodel, gcmodel); g_object_unref(gcmodel); } if (S > -0.5*G_MAXDOUBLE) { GwyDataLine *best = gwy_data_line_duplicate(ecurve); gdouble *ydata = gwy_data_line_get_data(best); guint i, res = gwy_data_line_get_res(best); for (i = 0; i < res; i++) ydata[i] = S; gcmodel = gwy_graph_curve_model_new(); g_object_set(gcmodel, "description", _("Best estimate"), "mode", GWY_GRAPH_CURVE_LINE, "color", gwy_graph_get_preset_color(1), NULL); gwy_graph_curve_model_set_data_from_dataline(gcmodel, best, 0, 0); gwy_graph_model_add_curve(gmodel, gcmodel); g_object_unref(gcmodel); g_object_unref(best); } g_object_unref(ecurve); zoom_in_changed(controls, GTK_TOGGLE_BUTTON(controls->zoom_in)); }
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 void fit_do(FitControls *controls) { FitParamArg *arg; FitArgs *args; GtkWidget *dialog; gdouble *param, *error; gboolean *fixed; gint i, j, nparams, nfree = 0; gboolean allfixed, errorknown; args = controls->args; nparams = gwy_nlfit_preset_get_nparams(args->fitfunc); fixed = g_newa(gboolean, nparams); allfixed = TRUE; for (i = 0; i < nparams; i++) { arg = &g_array_index(args->param, FitParamArg, i); fixed[i] = arg->fix; allfixed &= fixed[i]; arg->value = arg->init; if (!fixed[i]) nfree++; } if (allfixed) return; if (!normalize_data(args)) return; if (gwy_data_line_get_res(args->xdata) <= nfree) { dialog = gtk_message_dialog_new(GTK_WINDOW(controls->dialog), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("It is necessary to select more " "data points than free fit " "parameters")); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); return; } if (args->fitter) gwy_math_nlfit_free(args->fitter); param = g_newa(gdouble, nparams); error = g_newa(gdouble, nparams); for (i = 0; i < nparams; i++) param[i] =g_array_index(args->param, FitParamArg, i).value; args->fitter = gwy_nlfit_preset_fit(args->fitfunc, NULL, gwy_data_line_get_res(args->xdata), gwy_data_line_get_data_const(args->xdata), gwy_data_line_get_data_const(args->ydata), param, error, fixed); errorknown = (args->fitter->covar != NULL); for (i = 0; i < nparams; i++) { arg = &g_array_index(args->param, FitParamArg, i); arg->value = param[i]; arg->error = error[i]; fit_param_row_update_value(controls, i, errorknown); } if (errorknown) { gchar buf[16]; /* FIXME: this is _scaled_ dispersion */ g_snprintf(buf, sizeof(buf), "%2.3g", gwy_math_nlfit_get_dispersion(args->fitter)); gtk_label_set_markup(GTK_LABEL(controls->chisq), buf); for (i = 0; i < nparams; i++) { for (j = 0; j <= i; j++) { g_snprintf(buf, sizeof(buf), "%0.3f", gwy_math_nlfit_get_correlations(args->fitter, i, j)); fix_minus(buf, sizeof(buf)); gtk_label_set_markup(SLi(controls->covar, GtkLabel*, i, j), buf); } } } else