Пример #1
0
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);
}
Пример #2
0
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;
}
Пример #3
0
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));
}
Пример #4
0
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;
}
Пример #5
0
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