Exemple #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);
}
Exemple #2
0
static GwyDataLine*
sphrev_make_sphere(gdouble radius, gint maxres)
{
    GwyDataLine *dline;
    gdouble *data;
    gint i, size;

    size = GWY_ROUND(MIN(radius, maxres));
    dline = gwy_data_line_new(2*size+1, 1.0, FALSE);
    data = gwy_data_line_get_data(dline);

    if (radius/8 > maxres) {
        /* Pathological case: very flat sphere */
        for (i = 0; i <= size; i++) {
            gdouble u = i/radius;

            data[size+i] = data[size-i] = u*u/2.0*(1.0 + u*u/4.0*(1 + u*u/2.0));
        }
    }
    else {
        /* Normal sphere */
        for (i = 0; i <= size; i++) {
            gdouble u = i/radius;

            if (G_UNLIKELY(u > 1.0))
                data[size+i] = data[size-i] = 1.0;
            else
                data[size+i] = data[size-i] = 1.0 - sqrt(1.0 - u*u);
        }
    }

    return dline;
}
Exemple #3
0
static void
oldmda_read_data(OldMDAFile *mdafile, const gchar *buffer)
{
    GwyBrick *brick;
    GwyDataField *dfield;
    GwyDataLine *cal;
    gdouble *data;
    gint i, j, k;
    const guchar *p;

    p = buffer;
    brick = gwy_brick_new(mdafile->xres, mdafile->yres, mdafile->zres,
                          mdafile->xreal, mdafile->yreal, mdafile->zres,
                          TRUE);
    data = gwy_brick_get_data(brick);

    for (k = 0; k < mdafile->zres; k++) {
        p = buffer + k * 4;
        for (i = 0; i < mdafile->yres; i++)
            for (j = 0; j < mdafile->xres; j++) {
                *(data + k * mdafile->xres * mdafile->yres + j
                    + (mdafile->yres - i - 1) * mdafile->xres)
                        = (gdouble)gwy_get_gint32_le(&p);
                p += (mdafile->zres - 1) * 4;
            }
    }

    gwy_brick_set_si_unit_x(brick, mdafile->siunitx);
    gwy_brick_set_si_unit_y(brick, mdafile->siunity);
    gwy_brick_set_si_unit_z(brick, mdafile->siunitz);

    cal = gwy_data_line_new(mdafile->zres, mdafile->zres, FALSE);
    data = gwy_data_line_get_data(cal);
    for (k = 0; k < mdafile->zres; k++) {
        *(data++) = g_array_index(mdafile->xdata, gdouble, k);
    }
    gwy_data_line_set_si_unit_y(cal, mdafile->siunitz);
    gwy_brick_set_zcalibration(brick, cal);
    g_object_unref(cal);

    g_object_unref(mdafile->siunitx);
    g_object_unref(mdafile->siunity);
    g_object_unref(mdafile->siunitz);

    dfield = gwy_data_field_new(mdafile->xres, mdafile->yres,
                                mdafile->xreal, mdafile->yreal,
                                TRUE);
    gwy_container_set_object_by_name(mdafile->data, "/brick/0", brick);
    gwy_container_set_string_by_name(mdafile->data, "/brick/0/title",
                                     g_strdup("MDA data"));
    gwy_brick_mean_plane(brick, dfield, 0, 0, 0,
                         mdafile->xres, mdafile->yres, -1, FALSE);
    gwy_container_set_object_by_name(mdafile->data, "/brick/0/preview",
                                     dfield);
    g_object_unref(dfield);
    g_object_unref(brick);

    gwy_file_volume_import_log_add(mdafile->data, 0, NULL, mdafile->filename);
}
Exemple #4
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;
}
Exemple #5
0
static void
line_correct_match(GwyContainer *data,
                   GwyRunType run)
{
    GwyDataField *dfield;
    GwyDataLine *shifts;
    gint xres, yres, i;
    gdouble *d, *s;
    GQuark dquark;

    g_return_if_fail(run & LINECORR_RUN_MODES);
    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);

    yres = gwy_data_field_get_yres(dfield);
    xres = gwy_data_field_get_xres(dfield);
    d = gwy_data_field_get_data(dfield);

    shifts = gwy_data_line_new(yres, 1.0, TRUE);
    s = gwy_data_line_get_data(shifts);
    s[0] = 0.0;

    for (i = 1; i < yres; i++) {
        s[i] = find_shift(xres, d + i*xres, d + (i - 1)*xres);
        g_printerr("%d %g\n", i, s[i]);
    }

    gwy_data_line_cumulate(shifts);
    for (i = 1; i < yres; i++)
        gwy_data_field_area_add(dfield, 0, i, xres, 1, s[i]);
    gwy_data_field_add(dfield, -s[yres-1]/(xres*yres));

    g_object_unref(shifts);
    gwy_data_field_data_changed(dfield);
}
Exemple #6
0
static void
line_correct_median(GwyContainer *data, GwyRunType run)
{
    GwyDataField *dfield;
    GwyDataLine *line, *modi;
    gint xres, yres, i;
    GQuark dquark;
    gdouble median;

    g_return_if_fail(run & LINECORR_RUN_MODES);
    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);
    line = gwy_data_line_new(xres, 1.0, FALSE);
    yres = gwy_data_field_get_yres(dfield);
    modi = gwy_data_line_new(yres, 1.0, FALSE);

    for (i = 0; i < yres; i++) {
        gwy_data_field_get_row(dfield, line, i);
        median = gwy_math_median(xres, gwy_data_line_get_data(line));
        gwy_data_line_set_val(modi, i, median);
    }
    median = gwy_data_line_get_median(modi);

    for (i = 0; i < yres; i++) {
        gwy_data_field_area_add(dfield, 0, i, xres, 1,
                                median - gwy_data_line_get_val(modi, i));
    }

    g_object_unref(modi);
    g_object_unref(line);
    gwy_data_field_data_changed(dfield);
}
Exemple #7
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));
}
Exemple #8
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;
}
Exemple #9
0
static GwySpectra*
rhkspm32_read_spectra(RHKPage *rhkpage)
{
    guint i, j;
    gdouble *data;
    GwySIUnit *siunit = NULL;
    GwyDataLine *dline;
    GwySpectra *spectra = NULL;
    GPtrArray *spectrum = NULL;
    // i'm leaving this alone, though it probably doesn't make sense,
    // and i should just create graphs straight away - but in case of
    // future use, i'll just convert the data later to graphs

    // xres stores number of data points per spectra,
    // yres stores the number of spectra

    // reading data
    gwy_debug("rhk-spm32: %d spectra in this page\n", rhkpage->yres);
    for (i = 0; i < rhkpage->yres; i++) {
        dline = gwy_data_line_new(rhkpage->xres, rhkpage->x.scale, FALSE);
        gwy_data_line_set_offset(dline, (rhkpage->x.offset));
        data = gwy_data_line_get_data(dline);
        // store line data in physical units - which are the z values, not y
        if ((rhkpage->data_type) == RHK_DATA_INT16) {
                const guint16 *p = (const guint16*)(rhkpage->buffer
                                                    + rhkpage->data_offset);
                for (j = 0; j < rhkpage->xres; j++) {
                    data[j] = GINT16_FROM_LE(p[i*(rhkpage->xres) + j])
                            *(rhkpage->z.scale)+(rhkpage->z.offset);
                }
        }
        else if ((rhkpage->data_type) == RHK_DATA_SINGLE) {
                const guchar *p = (const guchar*)(rhkpage->buffer
                                                  + rhkpage->data_offset);
                for (j = 0; j < rhkpage->xres; j++) {
                    data[j] = gwy_get_gfloat_le(&p)*rhkpage->z.scale
                              + rhkpage->z.offset;
                }
        }
        siunit = gwy_si_unit_new(rhkpage->x.units);
        gwy_data_line_set_si_unit_x(dline, siunit);
        g_object_unref(siunit);

        // the y units (and data) for a 1D graph are stored in Z in the rhk
        // spm32 format!
        /* Fix "/\xfbHz" to "/Hz".
         * XXX: It might be still wrong as the strange character might mean
         * sqrt. */
        if (g_str_has_suffix(rhkpage->z.units, "/\xfbHz")) {
            gchar *s = gwy_strkill(g_strdup(rhkpage->z.units), "\xfb");
            siunit = gwy_si_unit_new(s);
            g_free(s);
        }
        else
            siunit = gwy_si_unit_new(rhkpage->z.units);
        gwy_data_line_set_si_unit_y(dline, siunit);
        g_object_unref(siunit);

        if (!spectrum)
            spectrum = g_ptr_array_sized_new(rhkpage->yres);
        g_ptr_array_add(spectrum, dline);
    }
    gwy_debug("rhk-spm32: finished parsing sps data\n");
    spectra = gwy_spectra_new();

    for (i = 0; i < rhkpage->yres; i++) {
        dline = g_ptr_array_index(spectrum, i);
        // since RHK spm32 does not record where it took the spectra,
        // i'm setting these to zero
        gwy_spectra_add_spectrum(spectra, dline, 0, 0);
        g_object_unref(dline);
    }
    gwy_spectra_set_title(spectra, rhkpage->label);

    if (spectrum)
        g_ptr_array_free(spectrum, TRUE);

    return spectra;
}
Exemple #10
0
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;
}
Exemple #11
0
static void
line_correct_match(GwyContainer *data,
                   GwyRunType run)
{
    GwyDataField *dfield;
    GwyDataLine *shifts;
    gint xres, yres, i, j;
    gdouble m, wsum, lambda, x;
    gdouble *d, *s, *w;
    const gdouble *a, *b;
    GQuark dquark;

    g_return_if_fail(run & LINECORR_RUN_MODES);
    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);

    yres = gwy_data_field_get_yres(dfield);
    xres = gwy_data_field_get_xres(dfield);
    d = gwy_data_field_get_data(dfield);

    shifts = gwy_data_line_new(yres, 1.0, TRUE);
    s = gwy_data_line_get_data(shifts);

    w = g_new(gdouble, xres-1);
    for (i = 1; i < yres; i++) {
        a = d + xres*(i - 1);
        b = d + xres*i;

        /* Diffnorm */
        wsum = 0.0;
        for (j = 0; j < xres-1; j++) {
            x = a[j+1] - a[j] - b[j+1] + b[j];
            wsum += fabs(x);
        }
        if (wsum == 0)
            continue;
        m = wsum/(xres-1);

        /* Weights */
        wsum = 0.0;
        for (j = 0; j < xres-1; j++) {
            x = a[j+1] - a[j] - b[j+1] + b[j];
            w[j] = exp(-(x*x/(2.0*m)));
            wsum += w[j];
        }

        /* Correction */
        lambda = (a[0] - b[0])*w[0];
        for (j = 1; j < xres-1; j++)
            lambda += (a[j] - b[j])*(w[j-1] + w[j]);
        lambda += (a[xres-1] - b[xres-1])*w[xres-2];
        lambda /= 2.0*wsum;

        gwy_debug("%g %g %g", m, wsum, lambda);

        s[i] = lambda;
    }
    gwy_data_line_cumulate(shifts);
    for (i = 1; i < yres; i++)
        gwy_data_field_area_add(dfield, 0, i, xres, 1, s[i]);
    gwy_data_field_add(dfield, -s[yres-1]/(xres*yres));

    g_object_unref(shifts);
    g_free(w);
    gwy_data_field_data_changed(dfield);
}