Beispiel #1
0
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);
}
Beispiel #2
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;
}
Beispiel #3
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;
}