Beispiel #1
0
static void
create_merged_field(GwyContainer *data, gint id1,
                    GwyDataField *dfield1, GwyDataField *dfield2,
                    gint px1, gint py1, gint px2, gint py2,
                    GwyMergeBoundaryType boundary, GwyMergeDirectionType dir,
                    gboolean create_mask, gboolean crop_to_rectangle)
{
    GwyDataField *result, *outsidemask = NULL;
    gint newxres, newyres, newid;

    gwy_debug("field1 %dx%d", dfield1->xres, dfield1->yres);
    gwy_debug("field2 %dx%d", dfield2->xres, dfield2->yres);
    gwy_debug("px1: %d, py1: %d, px2: %d, py2: %d", px1, py1, px2, py2);

    result = gwy_data_field_new_alike(dfield1, FALSE);

    newxres = MAX(dfield1->xres + px1, dfield2->xres + px2);
    newyres = MAX(dfield1->yres + py1, dfield2->yres + py2);

    gwy_data_field_resample(result, newxres, newyres, GWY_INTERPOLATION_NONE);
    if (create_mask && !crop_to_rectangle) {
        outsidemask = gwy_data_field_new_alike(result, FALSE);
        gwy_si_unit_set_from_string(gwy_data_field_get_si_unit_z(outsidemask),
                                    NULL);
    }
    put_fields(dfield1, dfield2, result, outsidemask,
               boundary, px1, py1, px2, py2);

    if (crop_to_rectangle) {
        GwyOrientation orientation = GWY_ORIENTATION_HORIZONTAL;
        if (dir == GWY_MERGE_DIRECTION_UP || dir == GWY_MERGE_DIRECTION_DOWN)
            orientation = GWY_ORIENTATION_VERTICAL;

        crop_result(result, dfield1, dfield2, orientation, px1, py1, px2, py2);
    }

    gwy_app_data_browser_get_current(GWY_APP_CONTAINER, &data, 0);
    newid = gwy_app_data_browser_add_data_field(result, data, TRUE);
    gwy_app_set_data_field_title(data, newid, _("Merged images"));
    gwy_app_sync_data_items(data, data, id1, newid,
                            FALSE,
                            GWY_DATA_ITEM_PALETTE,
                            GWY_DATA_ITEM_MASK_COLOR,
                            GWY_DATA_ITEM_RANGE,
                            0);

    if (outsidemask) {
        if (gwy_data_field_get_max(outsidemask) > 0.0) {
            GQuark quark = gwy_app_get_mask_key_for_id(newid);
            gwy_container_set_object(data, quark, outsidemask);
        }
        g_object_unref(outsidemask);
    }

    gwy_app_channel_log_add_proc(data, -1, newid);
    g_object_unref(result);
}
Beispiel #2
0
/* create a smaller copy of data */
static GwyContainer*
create_preview_data(GwyContainer *data,
                    GwyDataField *dfield,
                    GwyDataField *mfield,
                    gint id)
{
    GwyContainer *pdata;
    GwyDataField *pfield;
    gint xres, yres;
    gdouble zoomval;

    pdata = gwy_container_new();
    xres = gwy_data_field_get_xres(dfield);
    yres = gwy_data_field_get_yres(dfield);
    zoomval = (gdouble)PREVIEW_SIZE/MAX(xres, yres);
    xres = MAX(xres*zoomval, 3);
    yres = MAX(yres*zoomval, 3);

    /* Base data */
    pfield = gwy_data_field_new_resampled(dfield, xres, yres,
                                          GWY_INTERPOLATION_ROUND);
    gwy_container_set_object_by_name(pdata, "/source", pfield);
    g_object_unref(pfield);

    /* Mask */
    if (mfield) {
        pfield = gwy_data_field_new_resampled(mfield, xres, yres,
                                              GWY_INTERPOLATION_ROUND);
        gwy_container_set_object_by_name(pdata, "/mask", pfield);
        g_object_unref(pfield);
    }

    /* Leveled */
    pfield = gwy_data_field_new_alike(pfield, FALSE);
    gwy_container_set_object_by_name(pdata, "/0/data", pfield);
    g_object_unref(pfield);

    /* Background */
    pfield = gwy_data_field_new_alike(pfield, FALSE);
    gwy_container_set_object_by_name(pdata, "/1/data", pfield);
    g_object_unref(pfield);

    gwy_app_sync_data_items(data, pdata, id, 0, FALSE,
                            GWY_DATA_ITEM_GRADIENT,
                            0);
    gwy_app_sync_data_items(data, pdata, id, 1, FALSE,
                            GWY_DATA_ITEM_GRADIENT,
                            0);

    return pdata;
}
Beispiel #3
0
static void
line_correct_step(GwyContainer *data,
                  GwyRunType run)
{
    GwyDataField *dfield, *mask;
    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);

    gwy_data_field_absdiff_line_correct(dfield);

    mask = gwy_data_field_new_alike(dfield, TRUE);
    line_correct_step_iter(dfield, mask);
    gwy_data_field_clear(mask);
    line_correct_step_iter(dfield, mask);
    g_object_unref(mask);

    gwy_data_field_filter_conservative(dfield, 5);
    gwy_data_field_data_changed(dfield);
}
Beispiel #4
0
static void
poly_level_do(GwyContainer *data,
              GwyDataField *dfield,
              GwyDataField *mfield,
              GQuark quark,
              gint oldid,
              const PolyLevelArgs *args)
{
    GwyDataField *bg = NULL;
    gint newid;

    gwy_app_undo_qcheckpointv(data, 1, &quark);
    if (args->do_extract)
        bg = gwy_data_field_new_alike(dfield, TRUE);

    if (mfield && args->masking != GWY_MASK_IGNORE)
        poly_level_do_with_mask(dfield, mfield, dfield, bg, args);
    else if (args->independent)
        poly_level_do_independent(dfield, dfield, bg,
                                  args->col_degree, args->row_degree);
    else
        poly_level_do_maximum(dfield, dfield, bg, args->max_degree);

    if (!args->do_extract)
        return;

    newid = gwy_app_data_browser_add_data_field(bg, data, TRUE);
    g_object_unref(bg);
    gwy_app_sync_data_items(data, data, oldid, newid, FALSE,
                            GWY_DATA_ITEM_GRADIENT,
                            0);
    gwy_app_set_data_field_title(data, newid, _("Background"));
}
Beispiel #5
0
static GwyDataField*
make_mask_field(GwyDataField *dfield,
                const guchar *data)
{
    GwyDataField *mfield;
    guint xres, yres, i, j, rowstride;
    const guchar *datarow;
    gdouble *d;

    xres = gwy_data_field_get_xres(dfield);
    yres = gwy_data_field_get_yres(dfield);
    rowstride = xres;

    /* Do not create the mask if it is all zero. */
    for (i = 0; i < rowstride*yres; i++) {
        if (!data[i])
            break;
    }
    if (i == rowstride*yres)
        return NULL;

    mfield = gwy_data_field_new_alike(dfield, FALSE);
    d = gwy_data_field_get_data(mfield);

    for (i = 0; i < yres; i++) {
        datarow = data + (yres-1 - i)*rowstride;
        for (j = 0; j < xres; j++) {
            *(d++) = datarow[j];
        }
    }

    return mfield;
}
Beispiel #6
0
static void
rotate_counterclockwise_90(GwyContainer *data, GwyRunType run)
{
    GwyDataField *dfields[3], *newfield;
    GQuark quarks[3];
    gint i, id;

    g_return_if_fail(run & BASICOPS_RUN_MODES);
    gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, dfields + 0,
                                     GWY_APP_MASK_FIELD, dfields + 1,
                                     GWY_APP_SHOW_FIELD, dfields + 2,
                                     GWY_APP_DATA_FIELD_KEY, quarks + 0,
                                     GWY_APP_MASK_FIELD_KEY, quarks + 1,
                                     GWY_APP_SHOW_FIELD_KEY, quarks + 2,
                                     GWY_APP_DATA_FIELD_ID, &id,
                                     0);
    clean_quarks(G_N_ELEMENTS(quarks), quarks, dfields);
    gwy_app_undo_qcheckpointv(data, G_N_ELEMENTS(quarks), quarks);
    for (i = 0; i < G_N_ELEMENTS(dfields); i++) {
        if (dfields[i]) {
            newfield = gwy_data_field_new_alike(dfields[i], FALSE);
            flip_xy(dfields[i], newfield, TRUE);
            gwy_container_set_object(data, quarks[i], newfield);
            g_object_unref(newfield);
        }
    }
    gwy_app_data_clear_selections(data, id);
    gwy_app_channel_log_add_proc(data, id, id);
}
Beispiel #7
0
/* Note: rms and avg must be identical and contain a copy of the original data
 * field */
static void
calculate_normalization(GwyDataField *avg,
                        GwyDataField *rms,
                        gint kernel_width,
                        gint kernel_height)
{
    GwyDataField *buffer;
    gint xres, yres, i;

    g_return_if_fail(rms->xres == avg->xres && rms->yres == avg->yres);
    xres = avg->xres;
    yres = avg->yres;

    for (i = 0; i < xres*yres; i++)
        rms->data[i] *= rms->data[i];

    buffer = gwy_data_field_new_alike(avg, FALSE);
    gwy_data_field_area_gather(rms, rms, buffer,
                               kernel_width, kernel_height, TRUE,
                               0, 0, xres, yres);
    gwy_data_field_area_gather(avg, avg, buffer,
                               kernel_width, kernel_height, TRUE,
                               0, 0, xres, yres);
    g_object_unref(buffer);

    for (i = 0; i < xres*yres; i++) {
        rms->data[i] -= avg->data[i]*avg->data[i];
        rms->data[i] = sqrt(MAX(rms->data[i], 0.0));
    }
}
Beispiel #8
0
static void
laplace(GwyContainer *data, GwyRunType run)
{
    GwyDataField *dfield, *mfield, *buffer;
    GQuark dquark;
    gdouble error, cor, maxer, lastfrac, frac, starter;
    gint i, id;
    gboolean cancelled = FALSE;

    g_return_if_fail(run & LAPLACE_RUN_MODES);
    gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD_KEY, &dquark,
                                     GWY_APP_DATA_FIELD, &dfield,
                                     GWY_APP_MASK_FIELD, &mfield,
                                     GWY_APP_DATA_FIELD_ID, &id,
                                     0);
    g_return_if_fail(dfield && dquark && mfield);

    maxer = gwy_data_field_get_rms(dfield)/1.0e4;
    gwy_app_wait_start(gwy_app_find_window_for_channel(data, id),
                       _("Laplace interpolation..."));

    dfield = gwy_data_field_duplicate(dfield);
    buffer = gwy_data_field_new_alike(dfield, TRUE);
    gwy_data_field_correct_average(dfield, mfield);

    cor = 0.2;
    error = 0.0;
    lastfrac = 0.0;
    starter = 0.0;
    for (i = 0; i < 5000; i++) {
        gwy_data_field_correct_laplace_iteration(dfield, mfield, buffer,
                                                 cor, &error);
        if (error < maxer)
            break;
        if (!i)
            starter = error;

        frac = log(error/starter)/log(maxer/starter);
        if ((i/(gdouble)(5000)) > frac)
            frac = i/(gdouble)(5000);
        if (lastfrac > frac)
            frac = lastfrac;

        if (!gwy_app_wait_set_fraction(frac)) {
            cancelled = TRUE;
            break;
        }
        lastfrac = frac;
    }
    gwy_app_wait_finish();
    if (!cancelled) {
        gwy_app_undo_qcheckpointv(data, 1, &dquark);
        gwy_container_set_object(data, dquark, dfield);
        gwy_app_channel_log_add_proc(data, id, id);
    }
    g_object_unref(dfield);
    g_object_unref(buffer);
}
Beispiel #9
0
static GwyDataField*
create_mask_field(GwyDataField *dfield)
{
    GwyDataField *mfield;
    GwySIUnit *siunit;

    mfield = gwy_data_field_new_alike(dfield, FALSE);
    siunit = gwy_si_unit_new("");
    gwy_data_field_set_si_unit_z(mfield, siunit);
    g_object_unref(siunit);

    return mfield;
}
Beispiel #10
0
static GwyDataField*
prof_psdf(GwyDataField *dfield,
          const ProfArgs *args)
{
    GwyDataField *fftre, *fftim;
    GwySIUnit *zunit;
    const gdouble *im;
    gdouble *re;
    gint xres, yres, i;

    fftre = gwy_data_field_new_alike(dfield, FALSE);
    fftim = gwy_data_field_new_alike(dfield, FALSE);

    gwy_data_field_2dfft(dfield, NULL, fftre, fftim,
                         args->windowing,
                         GWY_TRANSFORM_DIRECTION_FORWARD,
                         GWY_INTERPOLATION_LINEAR,  /* ignored */
                         FALSE, 1);

    xres = gwy_data_field_get_xres(dfield);
    yres = gwy_data_field_get_yres(dfield);
    re = gwy_data_field_get_data(fftre);
    im = gwy_data_field_get_data_const(fftim);

    /* Put the PSDF to fftre. */
    for (i = 0; i < xres*yres; i++)
        re[i] = re[i]*re[i] + im[i]*im[i];

    g_object_unref(fftim);

    gwy_data_field_fft_postprocess(fftre, TRUE);

    zunit = gwy_data_field_get_si_unit_z(fftre);
    gwy_si_unit_power(gwy_data_field_get_si_unit_z(dfield), 2, zunit);
    gwy_si_unit_multiply(gwy_data_field_get_si_unit_xy(dfield), zunit, zunit);

    return fftre;
}
Beispiel #11
0
static void
gedge_process(GwyDataField *dfield,
              GwyDataField *maskfield,
              GEdgeArgs *args)
{
    GwyDataField *temp_field;

    temp_field = gwy_data_field_new_alike(dfield, FALSE);
    gwy_data_field_copy(dfield, temp_field, FALSE);
    gwy_data_field_filter_laplacian_of_gaussians(temp_field);
    gwy_data_field_grains_mark_height(temp_field, maskfield,
                                      args->threshold_laplasian, TRUE);

    g_object_unref(temp_field);
}
Beispiel #12
0
static GwyContainer*
asc_load(const gchar *filename,
         G_GNUC_UNUSED GwyRunType mode,
         GError **error)
{
    GwyContainer *container = NULL;
    GwyDataField *dfield = NULL, *mfield = NULL;
    GwyTextHeaderParser parser;
    GwySIUnit *unit;
    gchar *line, *p, *value, *buffer = NULL;
    GHashTable *hash = NULL;
    gsize size;
    GError *err = NULL;
    gdouble xreal, yreal, q;
    gint i, xres, yres;
    gdouble *data;

    if (!g_file_get_contents(filename, &buffer, &size, &err)) {
        err_GET_FILE_CONTENTS(error, &err);
        goto fail;
    }

    p = buffer;
    line = gwy_str_next_line(&p);
    if (!gwy_strequal(line, MAGIC_BARE)) {
        err_FILE_TYPE(error, "SPIP ASCII data");
        goto fail;
    }

    gwy_clear(&parser, 1);
    parser.line_prefix = "#";
    parser.key_value_separator = "=";
    parser.terminator = "# Start of Data:";
    parser.error = &header_error;
    parser.end = &header_end;
    if (!(hash = gwy_text_header_parse(p, &parser, &p, &err))) {
        g_propagate_error(error, err);
        goto fail;
    }
    if (!require_keys(hash, error,
                      "x-pixels", "y-pixels", "x-length", "y-length",
                      NULL))
        goto fail;

    xres = atoi(g_hash_table_lookup(hash, "x-pixels"));
    yres = atoi(g_hash_table_lookup(hash, "y-pixels"));
    if (err_DIMENSION(error, xres) || err_DIMENSION(error, yres))
        goto fail;

    xreal = Nanometer * g_ascii_strtod(g_hash_table_lookup(hash, "x-length"),
                                       NULL);
    yreal = Nanometer * g_ascii_strtod(g_hash_table_lookup(hash, "y-length"),
                                       NULL);
    /* Use negated positive conditions to catch NaNs */
    if (!((xreal = fabs(xreal)) > 0)) {
        g_warning("Real x size is 0.0, fixing to 1.0");
        xreal = 1.0;
    }
    if (!((yreal = fabs(yreal)) > 0)) {
        g_warning("Real y size is 0.0, fixing to 1.0");
        yreal = 1.0;
    }

    dfield = gwy_data_field_new(xres, yres, xreal, yreal, FALSE);

    unit = gwy_si_unit_new("m");
    gwy_data_field_set_si_unit_xy(dfield, unit);
    g_object_unref(unit);

    if ((value = g_hash_table_lookup(hash, "z-unit"))) {
        gint power10;

        unit = gwy_si_unit_new_parse(value, &power10);
        gwy_data_field_set_si_unit_z(dfield, unit);
        g_object_unref(unit);
        q = pow10(power10);
    }
    else if ((value = g_hash_table_lookup(hash, "Bit2nm"))) {
        q = Nanometer * g_ascii_strtod(value, NULL);
        unit = gwy_si_unit_new("m");
        gwy_data_field_set_si_unit_z(dfield, unit);
        g_object_unref(unit);
    }
    else
        q = 1.0;

    data = gwy_data_field_get_data(dfield);
    value = p;
    for (i = 0; i < xres*yres; i++) {
        data[i] = q*g_ascii_strtod(value, &p);
        if (p == value && (!*p || g_ascii_isspace(*p))) {
            g_set_error(error, GWY_MODULE_FILE_ERROR,
                        GWY_MODULE_FILE_ERROR_DATA,
                        _("End of file reached when reading sample #%d of %d"),
                        i, xres*yres);
            goto fail;
        }
        if (p == value) {
            g_set_error(error, GWY_MODULE_FILE_ERROR,
                        GWY_MODULE_FILE_ERROR_DATA,
                        _("Malformed data encountered when reading sample "
                          "#%d of %d"),
                        i, xres*yres);
            goto fail;
        }
        value = p;
    }

    if ((value = g_hash_table_lookup(hash, "voidpixels")) && atoi(value)) {
        mfield = gwy_data_field_new_alike(dfield, FALSE);
        data = gwy_data_field_get_data(mfield);
        value = p;
        for (i = 0; i < xres*yres; i++) {
            data[i] = 1.0 - g_ascii_strtod(value, &p);
            value = p;
        }
        if (!gwy_app_channel_remove_bad_data(dfield, mfield))
            GWY_OBJECT_UNREF(mfield);
    }

    container = gwy_container_new();

    gwy_container_set_object(container, gwy_app_get_data_key_for_id(0), dfield);

    if (mfield) {
        gwy_container_set_object(container, gwy_app_get_mask_key_for_id(0),
                                 mfield);
        g_object_unref(mfield);
    }

    gwy_file_channel_import_log_add(container, 0, NULL, filename);

fail:
    GWY_OBJECT_UNREF(dfield);
    g_free(buffer);
    if (hash)
        g_hash_table_destroy(hash);

    return container;
}
Beispiel #13
0
static void
dwt_anisotropy(GwyContainer *data, GwyRunType run)
{
    GtkWidget *dialog;
    GwyDataField *dfield, *mask;
    GQuark dquark, mquark;
    GwyDataLine *wtcoefs;
    DWTAnisotropyArgs args;
    gboolean ok;
    gint xsize, ysize, newsize, limit, id, i;

    g_return_if_fail(run & DWT_ANISOTROPY_RUN_MODES);

    gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD_KEY, &dquark,
                                     GWY_APP_DATA_FIELD, &dfield,
                                     GWY_APP_DATA_FIELD_ID, &id,
                                     GWY_APP_MASK_FIELD_KEY, &mquark,
                                     GWY_APP_MASK_FIELD, &mask,
                                     0);
    g_return_if_fail(dfield && dquark);

    xsize = gwy_data_field_get_xres(dfield);
    ysize = gwy_data_field_get_yres(dfield);
    if (xsize != ysize) {
        dialog = gtk_message_dialog_new
            (gwy_app_find_window_for_channel(data, id),
             GTK_DIALOG_DESTROY_WITH_PARENT,
             GTK_MESSAGE_ERROR,
             GTK_BUTTONS_OK,
             _("%s: Data must be square."), _("DWT Anisotropy"));
        gtk_dialog_run(GTK_DIALOG(dialog));
        gtk_widget_destroy(dialog);
        return;
    }

    dwt_anisotropy_load_args(gwy_app_settings_get(), &args);
    if (run == GWY_RUN_INTERACTIVE) {
        ok = dwt_anisotropy_dialog(&args);
        dwt_anisotropy_save_args(gwy_app_settings_get(), &args);
        if (!ok)
            return;
    }

    for (newsize = 1, i = xsize-1; i; i >>= 1, newsize <<= 1)
        ;

    dfield = gwy_data_field_new_resampled(dfield, newsize, newsize,
                                          args.interp);
    gwy_data_field_add(dfield, -gwy_data_field_get_avg(dfield));

    gwy_app_undo_qcheckpoint(data, dquark, mquark, 0);
    if (!mask) {
        mask = gwy_data_field_new_alike(dfield, FALSE);
        gwy_container_set_object(data, mquark, mask);
        g_object_unref(mask);
    }
    gwy_data_field_resample(mask, newsize, newsize, GWY_INTERPOLATION_NONE);

    wtcoefs = gwy_data_line_new(10, 10, TRUE);
    wtcoefs = gwy_dwt_set_coefficients(wtcoefs, args.wavelet);

    /*justo for sure clamp the lowlimit again*/
    limit = pow(2, CLAMP(args.lowlimit, 1, 20));
    gwy_data_field_dwt_mark_anisotropy(dfield, mask, wtcoefs, args.ratio,
                                       limit);

    gwy_data_field_resample(mask, xsize, ysize, GWY_INTERPOLATION_ROUND);
    g_object_unref(wtcoefs);
    g_object_unref(dfield);
    gwy_data_field_data_changed(mask);
    gwy_app_channel_log_add_proc(data, id, id);
}
Beispiel #14
0
static void
immerse_correlate(GwyDataField *image,
                  GwyDataField *kernel,
                  gint *col,
                  gint *row)
{
    GwyDataField *subimage, *subkernel, *score, *imagearea;
    gdouble factor;
    gint ixres, iyres, kxres, kyres;
    gint sixres, siyres, skxres, skyres;
    gint xfrom, yfrom, xto, yto;
    gint sx, sy, delta;

    ixres = gwy_data_field_get_xres(image);
    iyres = gwy_data_field_get_yres(image);
    kxres = gwy_data_field_get_xres(kernel);
    kyres = gwy_data_field_get_yres(kernel);
    gwy_debug("kernel: %dx%d, image: %dx%d", kxres, kyres, ixres, iyres);

    factor = MAX(downsample_factor, downsample_limit/sqrt(kxres*kyres));
    factor = MIN(factor, 1.0);

    skxres = GWY_ROUND(factor*kxres);
    skyres = GWY_ROUND(factor*kyres);
    sixres = GWY_ROUND(factor*ixres);
    siyres = GWY_ROUND(factor*iyres);
    gwy_debug("skernel: %dx%d, simage: %dx%d", skxres, skyres, sixres, siyres);

    subimage = gwy_data_field_new_resampled(image, sixres, siyres,
                                            GWY_INTERPOLATION_LINEAR);
    score = gwy_data_field_new_alike(subimage, FALSE);
    subkernel = gwy_data_field_new_resampled(kernel, skxres, skyres,
                                             GWY_INTERPOLATION_LINEAR);

    gwy_data_field_correlate(subimage, subkernel, score,
                             GWY_CORRELATION_NORMAL);
    immerse_find_maximum(score, &sx, &sy);
    gwy_debug("sx: %d, sy: %d", sx, sy);
    g_object_unref(score);
    g_object_unref(subkernel);
    g_object_unref(subimage);

    /* Top left corner coordinate */
    sx -= (skxres - 1)/2;
    sy -= (skyres - 1)/2;
    /* Upscaled to original size */
    sx = GWY_ROUND((gdouble)ixres/sixres*sx);
    sy = GWY_ROUND((gdouble)iyres/siyres*sy);
    /* Uncertainty margin */
    delta = GWY_ROUND(1.5/factor + 1);
    /* Subarea to search */
    xfrom = MAX(sx - delta, 0);
    yfrom = MAX(sy - delta, 0);
    xto = MIN(sx + kxres + delta, ixres);
    yto = MIN(sy + kyres + delta, iyres);

    imagearea = gwy_data_field_area_extract(image,
                                            xfrom, yfrom,
                                            xto - xfrom, yto - yfrom);
    score = gwy_data_field_new_alike(imagearea, FALSE);
    gwy_data_field_correlate(imagearea, kernel, score,
                             GWY_CORRELATION_NORMAL);
    immerse_find_maximum(score, &sx, &sy);
    g_object_unref(score);
    g_object_unref(imagearea);

    *col = sx + xfrom - (kxres - 1)/2;
    *row = sy + yfrom - (kyres - 1)/2;
}
Beispiel #15
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));
}
Beispiel #16
0
static gboolean
noise_synth_dialog(NoiseSynthArgs *args,
                 GwyDimensionArgs *dimsargs,
                 GwyContainer *data,
                 GwyDataField *dfield_template,
                 gint id)
{
    GtkWidget *dialog, *table, *vbox, *hbox, *notebook, *label;
    NoiseSynthControls controls;
    GwyDataField *dfield;
    GwyPixmapLayer *layer;
    gboolean finished;
    gint response;
    gint row;

    gwy_clear(&controls, 1);
    controls.in_init = TRUE;
    controls.args = args;
    dialog = gtk_dialog_new_with_buttons(_("Random Noise"),
                                         NULL, 0,
                                         _("_Reset"), RESPONSE_RESET,
                                         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                         GTK_STOCK_OK, GTK_RESPONSE_OK,
                                         NULL);
    gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
    gwy_help_add_to_proc_dialog(GTK_DIALOG(dialog), GWY_HELP_DEFAULT);
    controls.dialog = dialog;

    hbox = gtk_hbox_new(FALSE, 2);
    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox,
                       FALSE, FALSE, 4);

    vbox = gtk_vbox_new(FALSE, 4);
    gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 4);

    controls.mydata = gwy_container_new();
    dfield = gwy_data_field_new(PREVIEW_SIZE, PREVIEW_SIZE,
                                dimsargs->measure*PREVIEW_SIZE,
                                dimsargs->measure*PREVIEW_SIZE,
                                TRUE);
    gwy_container_set_object_by_name(controls.mydata, "/0/data", dfield);
    controls.noise = gwy_data_field_new_alike(dfield, FALSE);
    if (dfield_template) {
        gwy_app_sync_data_items(data, controls.mydata, id, 0, FALSE,
                                GWY_DATA_ITEM_PALETTE,
                                0);
        controls.surface = gwy_synth_surface_for_preview(dfield_template,
                                                         PREVIEW_SIZE);
        controls.zscale = gwy_data_field_get_rms(dfield_template);
    }
    controls.view = gwy_data_view_new(controls.mydata);
    layer = gwy_layer_basic_new();
    g_object_set(layer,
                 "data-key", "/0/data",
                 "gradient-key", "/0/base/palette",
                 NULL);
    gwy_data_view_set_base_layer(GWY_DATA_VIEW(controls.view), layer);

    gtk_box_pack_start(GTK_BOX(vbox), controls.view, FALSE, FALSE, 0);

    gtk_box_pack_start(GTK_BOX(vbox),
                       gwy_synth_instant_updates_new(&controls,
                                                     &controls.update_now,
                                                     &controls.update,
                                                     &args->update),
                       FALSE, FALSE, 0);
    g_signal_connect_swapped(controls.update_now, "clicked",
                             G_CALLBACK(preview), &controls);

    gtk_box_pack_start(GTK_BOX(vbox),
                       gwy_synth_random_seed_new(&controls,
                                                 &controls.seed, &args->seed),
                       FALSE, FALSE, 0);

    controls.randomize = gwy_synth_randomize_new(&args->randomize);
    gtk_box_pack_start(GTK_BOX(vbox), controls.randomize, FALSE, FALSE, 0);

    notebook = gtk_notebook_new();
    gtk_box_pack_start(GTK_BOX(hbox), notebook, TRUE, TRUE, 4);
    g_signal_connect_swapped(notebook, "switch-page",
                             G_CALLBACK(page_switched), &controls);

    controls.dims = gwy_dimensions_new(dimsargs, dfield_template);
    gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
                             gwy_dimensions_get_widget(controls.dims),
                             gtk_label_new(_("Dimensions")));
    if (controls.dims->add)
        g_signal_connect_swapped(controls.dims->add, "toggled",
                                 G_CALLBACK(noise_synth_invalidate), &controls);

    table = gtk_table_new(6 + (dfield_template ? 1 : 0), 4, FALSE);
    controls.table = GTK_TABLE(table);
    gtk_table_set_row_spacings(controls.table, 2);
    gtk_table_set_col_spacings(controls.table, 6);
    gtk_container_set_border_width(GTK_CONTAINER(table), 4);
    gtk_notebook_append_page(GTK_NOTEBOOK(notebook), table,
                             gtk_label_new(_("Generator")));
    row = 0;

    controls.distribution = distribution_selector_new(&controls);
    gwy_table_attach_hscale(table, row, _("_Distribution:"), NULL,
                            GTK_OBJECT(controls.distribution),
                            GWY_HSCALE_WIDGET);
    row++;

    label = gtk_label_new(_("Direction:"));
    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
    gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1,
                     GTK_FILL, 0, 0, 0);
    row++;

    controls.direction
        = gwy_radio_buttons_createl(G_CALLBACK(direction_type_changed),
                                    &controls, args->direction,
                                    _("S_ymmetrical"), NOISE_DIRECTION_BOTH,
                                    _("One-sided _positive"), NOISE_DIRECTION_UP,
                                    _("One-sided _negative"), NOISE_DIRECTION_DOWN,
                                    NULL);
    row = gwy_radio_buttons_attach_to_table(controls.direction,
                                            GTK_TABLE(table), 3, row);
    gtk_table_set_row_spacing(GTK_TABLE(table), row-1, 8);

    row = gwy_synth_attach_height(&controls, row,
                                  &controls.sigma, &args->sigma,
                                  _("_RMS:"), NULL, &controls.sigma_units);

    if (dfield_template) {
        controls.sigma_init
            = gtk_button_new_with_mnemonic(_("_Like Current Channel"));
        g_signal_connect_swapped(controls.sigma_init, "clicked",
                                 G_CALLBACK(sigma_init_clicked), &controls);
        gtk_table_attach(GTK_TABLE(table), controls.sigma_init,
                         1, 3, row, row+1, GTK_FILL, 0, 0, 0);
        row++;
    }

    gtk_widget_show_all(dialog);
    controls.in_init = FALSE;
    /* Must be done when widgets are shown, see GtkNotebook docs */
    gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), args->active_page);
    update_values(&controls);
    noise_synth_invalidate(&controls);

    finished = FALSE;
    while (!finished) {
        response = gtk_dialog_run(GTK_DIALOG(dialog));
        switch (response) {
            case GTK_RESPONSE_CANCEL:
            case GTK_RESPONSE_DELETE_EVENT:
            case GTK_RESPONSE_OK:
            gtk_widget_destroy(dialog);
            case GTK_RESPONSE_NONE:
            finished = TRUE;
            break;

            case RESPONSE_RESET:
            {
                gboolean temp = args->update;
                gint temp2 = args->active_page;
                *args = noise_synth_defaults;
                args->active_page = temp2;
                args->update = temp;
            }
            controls.in_init = TRUE;
            update_controls(&controls, args);
            controls.in_init = FALSE;
            if (args->update)
                preview(&controls);
            break;

            default:
            g_assert_not_reached();
            break;
        }
    }

    if (controls.sid) {
        g_source_remove(controls.sid);
        controls.sid = 0;
    }
    g_object_unref(controls.mydata);
    gwy_object_unref(controls.surface);
    gwy_object_unref(controls.noise);
    gwy_dimensions_free(controls.dims);

    return response == GTK_RESPONSE_OK;
}
Beispiel #17
0
static void
psdflp_do(const PSDFLPArgs *args, GwyDataField *dfield, GwyDataField *lpsdf)
{
    enum { N = 4 };

    GwyDataField *reout, *imout;
    gint pxres, pyres, fxres, fyres;
    gint i, j, fi, pi;
    gdouble *ldata, *redata, *imdata;
    gdouble *cosphi, *sinphi;
    gdouble xreal, yreal, f0, f_max, b, p;

    reout = gwy_data_field_new_alike(dfield, FALSE);
    imout = gwy_data_field_new_alike(dfield, FALSE);
    gwy_data_field_2dfft(dfield, NULL, reout, imout,
                         args->window, GWY_TRANSFORM_DIRECTION_FORWARD,
                         GWY_INTERPOLATION_ROUND, /* Ignored */
                         TRUE, 1);

    pxres = reout->xres;
    pyres = reout->yres;
    redata = gwy_data_field_get_data(reout);
    imdata = gwy_data_field_get_data(imout);
    for (i = 0; i < pxres*pyres; i++)
        redata[i] = redata[i]*redata[i] + imdata[i]*imdata[i];
    gwy_data_field_2dfft_humanize(reout);
    gwy_data_field_filter_gaussian(reout, args->sigma);
    for (i = 0; i < pxres*pyres; i++)
        redata[i] = sqrt(redata[i]);

    fxres = pxres/2;
    fyres = pyres/2;
    gwy_data_field_resample(lpsdf, fxres, fyres, GWY_INTERPOLATION_NONE);
    ldata = gwy_data_field_get_data(lpsdf);

    xreal = dfield->xreal;
    yreal = dfield->yreal;
    f0 = 2.0/MIN(xreal, yreal);
    f_max = 0.5*MIN(pxres/xreal, pyres/yreal);
    if (f_max <= f0) {
        g_warning("Minimum frequency is not smaller than maximum frequency.");
    }
    b = log(f_max/f0)/fyres;

    /* Incorporate some prefactors to sinphi[] and cosphi[], knowing that
     * cosine is only ever used for x and sine for y frequencies. */
    cosphi = g_new(gdouble, (N+1)*fxres);
    sinphi = g_new(gdouble, (N+1)*fxres);
    for (j = 0; j < fxres; j++) {
        gdouble phi_from = 2.0*G_PI*j/fxres;
        gdouble phi_to = 2.0*G_PI*(j + 1.0)/fxres;

        for (pi = 0; pi <= N; pi++) {
            gdouble phi = ((pi + 0.5)*phi_from + (N - 0.5 - pi)*phi_to)/N;
            cosphi[j*(N+1) + pi] = cos(phi)*xreal;
            sinphi[j*(N+1) + pi] = sin(phi)*yreal;
        }
    }

    for (i = 0; i < fyres; i++) {
        gdouble f_from = f0*exp(b*i);
        gdouble f_to = f0*exp(b*(i + 1.0));

        for (j = 0; j < fxres; j++) {
            const gdouble *cosphi_j = cosphi + j*(N+1);
            const gdouble *sinphi_j = sinphi + j*(N+1);
            guint n = 0;
            gdouble s = 0.0;

            for (fi = 0; fi <= N; fi++) {
                gdouble f = ((fi + 0.5)*f_from + (N - 0.5 - fi)*f_to)/N;
                for (pi = 0; pi <= N; pi++) {
                    gdouble x = f*cosphi_j[pi] + pxres/2.0,
                            y = f*sinphi_j[pi] + pyres/2.0;

                    if (G_UNLIKELY(x < 0.5
                                   || y < 0.5
                                   || x > pxres - 1.5
                                   || y > pyres - 1.5))
                        continue;

                    p = gwy_data_field_get_dval(reout, x, y,
                                                GWY_INTERPOLATION_SCHAUM);
                    s += p;
                    n++;
                }
            }

            if (!n)
                n = 1;

            ldata[i*fxres + j] = 2.0*G_PI/fxres * s/n*(f_to - f_from);
        }
    }

    g_object_unref(imout);
    g_object_unref(reout);

    gwy_data_field_set_xreal(lpsdf, 2.0*G_PI);
    gwy_data_field_set_xoffset(lpsdf, 0.0);
    gwy_data_field_set_yreal(lpsdf, log(f_max/f0));
    gwy_data_field_set_yoffset(lpsdf, log(f0));
    gwy_si_unit_set_from_string(gwy_data_field_get_si_unit_xy(lpsdf), "");
    gwy_si_unit_set_from_string(gwy_data_field_get_si_unit_z(lpsdf), "");
    gwy_data_field_normalize(lpsdf);
}
Beispiel #18
0
static gint
fill_data_fields(MProFile *mprofile,
                 const guchar *buffer)
{
    GwyDataField *dfield, *vpmask;
    gdouble *data, *mask;
    gdouble xreal, yreal, q;
    const guchar *p;
    guint n, id, i, j, ndata;

    ndata = 0;
    mprofile->intensity_data = NULL;
    mprofile->intensity_mask = NULL;
    mprofile->phase_data = NULL;
    mprofile->phase_mask = NULL;

    p = buffer + mprofile->header_size;

    /* Intensity data */
    n = mprofile->intens_xres * mprofile->intens_yres;
    /* Enorce consistency */
    if (!n && mprofile->nbuckets) {
        g_warning("nbuckets > 0, but intensity data have zero dimension");
        mprofile->nbuckets = 0;
    }

    if (mprofile->nbuckets) {
        const guint16 *d16;

        mprofile->intensity_data = g_new(GwyDataField*, mprofile->nbuckets);
        mprofile->intensity_mask = g_new(GwyDataField*, mprofile->nbuckets);

        q = mprofile->data_inverted ? -1.0 : 1.0;

        if (mprofile->camera_res) {
            xreal = mprofile->intens_xres * mprofile->camera_res;
            yreal = mprofile->intens_yres * mprofile->camera_res;
        }
        else {
            /* whatever */
            xreal = mprofile->intens_xres;
            yreal = mprofile->intens_yres;
        }

        for (id = 0; id < mprofile->nbuckets; id++) {
            ndata++;
            dfield = gwy_data_field_new(mprofile->intens_xres,
                                        mprofile->intens_yres,
                                        xreal, yreal,
                                        FALSE);
            vpmask = gwy_data_field_new_alike(dfield, FALSE);
            gwy_data_field_fill(vpmask, 1.0);
            data = gwy_data_field_get_data(dfield);
            mask = gwy_data_field_get_data(vpmask);
            d16 = (const guint16*)p;
            for (i = 0; i < mprofile->intens_yres; i++) {
                for (j = 0; j < mprofile->intens_xres; j++) {
                    guint v16 = GUINT16_FROM_BE(*d16);
                    if (v16 >= 65412) {
                        mask[i*mprofile->intens_xres + j] = 0.0;
                    }
                    else
                        *data = q*v16;
                    d16++;
                    data++;
                }
            }

            set_units(dfield, mprofile, "");
            if (!gwy_app_channel_remove_bad_data(dfield, vpmask))
                gwy_object_unref(vpmask);

            mprofile->intensity_data[id] = dfield;
            mprofile->intensity_mask[id] = vpmask;
            p += sizeof(guint16)*n;
        }
    }

    /* Phase data */
    n = mprofile->phase_xres * mprofile->phase_yres;
    if (n) {
        const gint32 *d32;
        gint32 d;

        ndata++;

        i = 4096;
        if (mprofile->phase_res == 1)
            i = 32768;

        q = mprofile->scale_factor * mprofile->obliquity_factor
            * mprofile->wavelength_in/i;
        if (mprofile->data_inverted)
            q = -q;
        gwy_debug("q: %g", q);

        if (mprofile->camera_res) {
            xreal = mprofile->phase_xres * mprofile->camera_res;
            yreal = mprofile->phase_yres * mprofile->camera_res;
        }
        else {
            /* whatever */
            xreal = mprofile->phase_xres;
            yreal = mprofile->phase_yres;
        }
        dfield = gwy_data_field_new(mprofile->phase_xres,
                                    mprofile->phase_yres,
                                    xreal, yreal,
                                    FALSE);
        vpmask = gwy_data_field_new_alike(dfield, FALSE);
        gwy_data_field_fill(vpmask, 1.0);
        data = gwy_data_field_get_data(dfield);
        mask = gwy_data_field_get_data(vpmask);
        d32 = (const gint32*)p;
        for (i = 0; i < mprofile->phase_yres; i++) {
            for (j = 0; j < mprofile->phase_xres; j++) {
                d = GINT32_FROM_BE(*d32);
                if (d >= 2147483640) {
                    mask[i*mprofile->phase_xres + j] = 0.0;
                }
                else
                    *data = q*d;
                d32++;
                data++;
            }
        }

        set_units(dfield, mprofile, "m");
        if (!gwy_app_channel_remove_bad_data(dfield, vpmask))
            gwy_object_unref(vpmask);

        mprofile->phase_data = dfield;
        mprofile->phase_mask = vpmask;
        p += sizeof(gint32)*n;
    }

    return ndata;
}
Beispiel #19
0
static void
tip_model_dialog(TipModelArgs *args)
{
    enum {
        RESPONSE_RESET   = 1,
        RESPONSE_PREVIEW = 2
    };
    GtkWidget *dialog, *table, *hbox, *spin;
    TipModelControls controls;
    GwyPixmapLayer *layer;
    GwyDataField *dfield;
    GwySIUnit *unit;
    GQuark quark;
    gint response, row;

    dialog = gtk_dialog_new_with_buttons(_("Model Tip"), NULL, 0, NULL);
    gtk_dialog_add_action_widget(GTK_DIALOG(dialog),
                                 gwy_stock_like_button_new(_("_Update"),
                                                           GTK_STOCK_EXECUTE),
                                 RESPONSE_PREVIEW);
    gtk_dialog_add_button(GTK_DIALOG(dialog), _("_Reset"), RESPONSE_RESET);
    gtk_dialog_add_button(GTK_DIALOG(dialog),
                          GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
    gtk_dialog_add_button(GTK_DIALOG(dialog),
                          GTK_STOCK_OK, GTK_RESPONSE_OK);
    gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
    gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);

    hbox = gtk_hbox_new(FALSE, 3);
    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox,
                       FALSE, FALSE, 4);

    controls.args = args;
    controls.vxres = 200;
    controls.vyres = 200;

    /* set up initial tip field */
    quark = gwy_app_get_data_key_for_id(args->object.id);
    dfield = GWY_DATA_FIELD(gwy_container_get_object(args->object.data, quark));

    controls.tip = gwy_data_field_new_alike(dfield, TRUE);
    gwy_data_field_resample(controls.tip, controls.vxres, controls.vyres,
                            GWY_INTERPOLATION_NONE);
    gwy_data_field_clear(controls.tip);

    /*set up data of rescaled image of the tip*/
    controls.vtip = gwy_container_new();
    gwy_app_sync_data_items(args->object.data, controls.vtip,
                            args->object.id, 0, FALSE,
                            GWY_DATA_ITEM_PALETTE, 0);

    dfield = gwy_data_field_new_alike(controls.tip, TRUE);
    gwy_container_set_object_by_name(controls.vtip, "/0/data", dfield);
    g_object_unref(dfield);

    /* set up resampled view */
    controls.view = gwy_data_view_new(controls.vtip);
    layer = gwy_layer_basic_new();
    gwy_pixmap_layer_set_data_key(layer, "/0/data");
    gwy_layer_basic_set_gradient_key(GWY_LAYER_BASIC(layer), "/0/base/palette");
    gwy_data_view_set_base_layer(GWY_DATA_VIEW(controls.view), layer);

    /* set up tip model controls */
    gtk_box_pack_start(GTK_BOX(hbox), controls.view, FALSE, FALSE, 4);

    table = gtk_table_new(6, 4, FALSE);
    gtk_table_set_row_spacings(GTK_TABLE(table), 2);
    gtk_table_set_col_spacings(GTK_TABLE(table), 6);
    gtk_container_set_border_width(GTK_CONTAINER(table), 4);
    gtk_box_pack_start(GTK_BOX(hbox), table, FALSE, FALSE, 4);
    row = 0;

    controls.type = create_preset_menu(G_CALLBACK(tip_type_cb),
                                       &controls, args->type);
    gwy_table_attach_hscale(table, row, _("Tip _type:"), NULL,
                            GTK_OBJECT(controls.type), GWY_HSCALE_WIDGET);
    row++;

    controls.nsides = gtk_adjustment_new(args->nsides, 3, 24, 1, 5, 0);
    gwy_table_attach_hscale(table, row, _("_Number of sides:"), NULL,
                            controls.nsides, 0);
    row++;

    controls.angle = gtk_adjustment_new(args->angle, 0.1, 89.9, 0.1, 1, 0);
    spin = gwy_table_attach_hscale(table, row, _("Tip _slope:"), _("deg"),
                                   controls.angle, 0);
    gtk_spin_button_set_digits(GTK_SPIN_BUTTON(spin), 2);
    row++;

    controls.theta = gtk_adjustment_new(args->theta, 0, 360, 0.1, 1, 0);
    spin = gwy_table_attach_hscale(table, row, _("Tip _rotation:"), _("deg"),
                                   controls.theta, 0);
    gtk_spin_button_set_digits(GTK_SPIN_BUTTON(spin), 2);
    row++;

    controls.radius = gtk_adjustment_new(1.0, 0.01, 1000.0, 0.01, 1.0, 0.0);
    controls.radius_spin = gtk_spin_button_new(GTK_ADJUSTMENT(controls.radius),
                                               0.1, 2);
    gtk_table_attach(GTK_TABLE(table), controls.radius_spin,
                     2, 3, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    controls.radius_label = gtk_label_new_with_mnemonic(_("Tip _apex radius:"));
    gtk_misc_set_alignment(GTK_MISC(controls.radius_label), 0.0, 0.5);
    gtk_label_set_mnemonic_widget(GTK_LABEL(controls.radius_label),
                                  controls.radius_spin);
    gtk_table_attach(GTK_TABLE(table), controls.radius_label,
                     0, 1, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    unit = gwy_data_field_get_si_unit_xy(dfield);
    controls.radius_unit
        = gwy_combo_box_metric_unit_new(G_CALLBACK(radius_changed_cb),
                                        &controls,
                                        -12, -3, unit, -9);
    gtk_table_attach(GTK_TABLE(table), controls.radius_unit,
                     3, 4, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    g_signal_connect(controls.radius, "value-changed",
                     G_CALLBACK(radius_changed_cb), &controls);
    row++;

    controls.labsize = gtk_label_new(NULL);
    gtk_misc_set_alignment(GTK_MISC(controls.labsize), 0.0, 0.5);
    gtk_table_attach(GTK_TABLE(table), controls.labsize,
                     0, 3, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    row++;

    controls.tipdone = FALSE;
    tip_model_dialog_update_controls(&controls, args);
    preview(&controls, args);

    gtk_widget_show_all(dialog);
    do {
        response = gtk_dialog_run(GTK_DIALOG(dialog));
        switch (response) {
            case GTK_RESPONSE_CANCEL:
            case GTK_RESPONSE_DELETE_EVENT:
            tip_model_dialog_update_values(&controls, args);
            gtk_widget_destroy(dialog);
            tip_model_dialog_abandon(&controls);
            case GTK_RESPONSE_NONE:
            return;
            break;

            case GTK_RESPONSE_OK:
            tip_model_do(args, &controls);
            break;

            case RESPONSE_RESET:
            args->nsides = tip_model_defaults.nsides;
            args->angle = tip_model_defaults.angle;
            args->radius = tip_model_defaults.radius;
            args->theta = tip_model_defaults.theta;
            args->type = tip_model_defaults.type;
            tip_model_dialog_update_controls(&controls, args);
            break;

            case RESPONSE_PREVIEW:
            tip_model_dialog_update_values(&controls, args);
            preview(&controls, args);
            break;

            default:
            g_assert_not_reached();
            break;
        }
    } while (response != GTK_RESPONSE_OK);

    tip_model_dialog_update_values(&controls, args);
    gtk_widget_destroy(dialog);
    tip_model_dialog_abandon(&controls);
}
Beispiel #20
0
static GwyContainer*
int_load(const gchar *filename,
         G_GNUC_UNUSED GwyRunType mode,
         GError **error)
{
    GwyContainer *container = NULL, *meta;
    GwyDataField *dfield = NULL, *mfield = NULL;
    CodeVGridDataType type;
    gchar *line, *p, *comment, *end, *buffer = NULL;
    const gchar *unit, *title;
    gchar **fields = NULL;
    gsize size;
    GError *err = NULL;
    gdouble xreal, yreal;
    gint i, xres, yres, no_data_value = 32767;
    guint fi;
    gdouble scale_size, wavelength, q = 1.0, x_scale = 1.0;
    gboolean nearest_neighbour = FALSE;
    gdouble *data, *mdata;

    if (!g_file_get_contents(filename, &buffer, &size, &err)) {
        err_GET_FILE_CONTENTS(error, &err);
        goto fail;
    }

    /* Skip comments. */
    p = buffer;
    for (line = gwy_str_next_line(&p);
         line && line[0] == '!';
         line = gwy_str_next_line(&p)) {
        gwy_debug("comment <%s>", line);
    }
    if (!line) {
        err_FILE_TYPE(error, "Code V INT");
        goto fail;
    }

    /* The title. */
    comment = line;
    if (!(line = gwy_str_next_line(&p))) {
        err_FILE_TYPE(error, "Code V INT");
        goto fail;
    }
    gwy_debug("comment <%s>", comment);

    fields = split_line_in_place(line);
    if (!fields
        || g_strv_length(fields) < 8
        || !gwy_strequal(fields[0], "GRD")
        || !(xres = atoi(fields[1]))
        || !(yres = atoi(fields[2]))
        || !(type = gwy_stramong(fields[3],
                                 "SUR", "WFR", "FIL", "THV", "BIR", "CAO",
                                 NULL))
        || !gwy_strequal(fields[4], "WVL")
        || (!(wavelength = g_ascii_strtod(fields[5], &end))
              && end == fields[5])) {
        err_FILE_TYPE(error, "Code V INT");
        goto fail;
    }
    gwy_debug("type %u (%s)", type, fields[3]);
    gwy_debug("xres %d, yres %d", xres, yres);
    gwy_debug("wavelength %g", wavelength);
    fi = 6;
    if (gwy_strequal(fields[fi], "NNB")) {
        nearest_neighbour = TRUE;
        fi++;
    }
    gwy_debug("nearest_neighbour %d", nearest_neighbour);

    if (!fields[fi] || !gwy_strequal(fields[fi], "SSZ")) {
        err_FILE_TYPE(error, "Code V INT");
        goto fail;
    }
    fi++;
    if (!(scale_size = g_ascii_strtod(fields[fi], &end)) && end == fields[fi]) {
        err_FILE_TYPE(error, "Code V INT");
        goto fail;
    }
    gwy_debug("scale_size %g", scale_size);
    if (!scale_size) {
        g_warning("Zero SSZ, fixing to 1.0");
        scale_size = 1.0;
    }
    fi++;

    if (fields[fi] && gwy_strequal(fields[fi], "NDA")) {
        fi++;
        if (!fields[fi]) {
            err_FILE_TYPE(error, "Code V INT");
            goto fail;
        }
        no_data_value = atoi(fields[fi]);
        fi++;
    }
    gwy_debug("no_data_value %d", no_data_value);

    if (fields[fi] && gwy_strequal(fields[fi], "XSC")) {
        fi++;
        if (!fields[fi]) {
            err_FILE_TYPE(error, "Code V INT");
            goto fail;
        }
        if (!(x_scale = g_ascii_strtod(fields[fi], &end))
            && end == fields[fi]) {
            err_FILE_TYPE(error, "Code V INT");
            goto fail;
        }
        fi++;
    }
    gwy_debug("x_scale %g", x_scale);
    if (!x_scale) {
        g_warning("Zero XSC, fixing to 1.0");
        x_scale = 1.0;
    }

    /* There may be more stuff but we do not know anything about it. */

    if (err_DIMENSION(error, xres) || err_DIMENSION(error, yres))
        goto fail;

    yreal = 1.0;
    xreal = x_scale*yreal;
    dfield = gwy_data_field_new(xres, yres, xreal, yreal, TRUE);

    if (type == CODEV_INT_SURFACE_DEFORMATION) {
        q = 1e-6*wavelength/scale_size;
        unit = "m";
        title = "Surface";
    }
    else if (type == CODEV_INT_WAVEFRONT_DEFORMATION) {
        q = 1e-6*wavelength/scale_size;
        unit = "m";
        title = "Wavefront";
    }
    else {
        g_warning("Don't know how to convert this grid data type to physical "
                  "units.");
        title = fields[3];
    }

    gwy_si_unit_set_from_string(gwy_data_field_get_si_unit_z(dfield), unit);

    mfield = gwy_data_field_new_alike(dfield, TRUE);
    data = gwy_data_field_get_data(dfield);
    mdata = gwy_data_field_get_data(mfield);

    for (i = 0; i < xres*yres; i++, p = end) {
        gint value = strtol(p, &end, 10);

        if (value != no_data_value && (type != CODEV_INT_INTENSITY_FILTER
                                       || value >= 0)) {
            mdata[i] = 1.0;
            data[i] = q*value;
        }
    }

    if (!gwy_app_channel_remove_bad_data(dfield, mfield))
        gwy_object_unref(mfield);

    container = gwy_container_new();

    /*
    gwy_data_field_invert(dfield, TRUE, FALSE, FALSE);
    from F. Riguet : apparently no flip is needed (the raw data import module
    gives the correct orientation without further flipping)
    */
    gwy_container_set_object(container, gwy_app_get_data_key_for_id(0), dfield);
    g_object_unref(dfield);
    gwy_app_channel_check_nonsquare(container, 0);

    gwy_container_set_string_by_name(container, "/0/data/title",
                                     g_strdup(title));

    if (mfield) {
        /*
        gwy_data_field_invert(mfield, FALSE, TRUE, FALSE);
        */
        gwy_container_set_object(container, gwy_app_get_mask_key_for_id(0),
                                 mfield);
        g_object_unref(mfield);
    }

    meta = gwy_container_new();

    gwy_container_set_string_by_name(meta, "Comment", g_strdup(comment));
    gwy_container_set_string_by_name(meta, "Interpolation",
                                     g_strdup(nearest_neighbour
                                              ? "NNB" : "Linear"));
    gwy_container_set_string_by_name(meta, "Wavelength",
                                     g_strdup_printf("%g μm", wavelength));

    gwy_container_set_object_by_name(container, "/0/meta", meta);
    g_object_unref(meta);

    gwy_file_channel_import_log_add(container, 0, NULL, filename);

fail:
    g_free(fields);
    g_free(buffer);

    return container;
}
Beispiel #21
0
static void
level_grains_do(const LevelGrainsArgs *args,
                GwyContainer *data, GQuark dquark, gint id,
                GwyDataField *dfield, GwyDataField *mfield)
{
    GwyDataField *buffer, *background, *invmask;
    gdouble error, cor, maxerr, lastfrac, frac, starterr;
    gdouble *heights, *bgdata;
    gint *grains;
    gboolean cancelled = FALSE;
    gint i, xres, yres, ngrains;

    xres = gwy_data_field_get_xres(mfield);
    yres = gwy_data_field_get_yres(mfield);
    grains = g_new0(gint, xres*yres);

    ngrains = gwy_data_field_number_grains(mfield, grains);
    if (!ngrains) {
        g_free(grains);
        return;
    }

    heights = g_new(gdouble, ngrains+1);
    gwy_data_field_grains_get_values(dfield, heights, ngrains, grains,
                                     args->base);
    heights[0] = 0.0;

    background = gwy_data_field_new_alike(dfield, FALSE);
    bgdata = gwy_data_field_get_data(background);
    for (i = 0; i < xres*yres; i++)
        bgdata[i] = -heights[grains[i]];

    invmask = gwy_data_field_duplicate(mfield);
    gwy_data_field_multiply(invmask, -1.0);
    gwy_data_field_add(invmask, 1.0);

    maxerr = gwy_data_field_get_rms(dfield)/1.0e4;
    gwy_app_wait_start(gwy_app_find_window_for_channel(data, id),
                       _("Laplace interpolation..."));

    g_free(heights);
    g_free(grains);

    buffer = gwy_data_field_new_alike(background, TRUE);
    gwy_data_field_correct_average(background, invmask);

    cor = 0.2;
    error = 0.0;
    lastfrac = 0.0;
    starterr = 0.0;
    for (i = 0; i < 5000; i++) {
        gwy_data_field_correct_laplace_iteration(background, invmask, buffer,
                                                 cor, &error);
        if (error < maxerr)
            break;
        if (!i)
            starterr = error;

        frac = log(error/starterr)/log(maxerr/starterr);
        if ((i/(gdouble)(5000)) > frac)
            frac = i/(gdouble)(5000);
        if (lastfrac > frac)
            frac = lastfrac;

        if (!gwy_app_wait_set_fraction(frac)) {
            cancelled = TRUE;
            break;
        }
        lastfrac = frac;
    }
    gwy_app_wait_finish();

    if (!cancelled) {
        gwy_data_field_invert(background, FALSE, FALSE, TRUE);
        gwy_app_undo_qcheckpointv(data, 1, &dquark);
        gwy_data_field_subtract_fields(dfield, dfield, background);
        gwy_data_field_data_changed(dfield);

        if (args->do_extract) {
            gint newid;

            newid = gwy_app_data_browser_add_data_field(background, data, TRUE);
            gwy_app_sync_data_items(data, data, id, newid, FALSE,
                                    GWY_DATA_ITEM_GRADIENT,
                                    0);
            gwy_app_set_data_field_title(data, newid, _("Background"));
        }
    }
    g_object_unref(buffer);
    g_object_unref(invmask);
    g_object_unref(background);
}
Beispiel #22
0
static void
tip_blind_dialog(TipBlindArgs *args)
{
    GtkWidget *dialog, *table, *hbox, *vbox, *label;
    GwyContainer *data;
    GwyGraphModel *gmodel;
    GwyGraphArea *area;
    TipBlindControls controls;
    GwyPixmapLayer *layer;
    GwyDataField *dfield;
    GQuark quark;
    GwySIUnit *unit;
    gint response, row;

    dialog = gtk_dialog_new_with_buttons(_("Blind Tip Estimation"), NULL, 0,
                                         _("Run _Partial"), RESPONSE_ESTIMATE,
                                         _("Run _Full"), RESPONSE_REFINE,
                                         _("_Reset Tip"), RESPONSE_RESET,
                                         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                         GTK_STOCK_OK, GTK_RESPONSE_OK,
                                         NULL);
    gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
    gwy_help_add_to_proc_dialog(GTK_DIALOG(dialog), GWY_HELP_DEFAULT);

    controls.args = args;
    controls.in_update = TRUE;
    controls.good_tip = FALSE;
    controls.dialog = dialog;
    gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog), GTK_RESPONSE_OK,
                                      controls.good_tip);

    hbox = gtk_hbox_new(FALSE, 4);
    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox,
                       FALSE, FALSE, 4);

    controls.vxres = 240;
    controls.vyres = 240;
    controls.oldnstripes = args->nstripes;

    /* set initial tip properties */
    data = gwy_app_data_browser_get(args->source.datano);
    quark = gwy_app_get_data_key_for_id(args->source.id);
    dfield = GWY_DATA_FIELD(gwy_container_get_object(data, quark));

    controls.tip = gwy_data_field_new_alike(dfield, TRUE);
    gwy_data_field_resample(controls.tip, args->xres, args->yres,
                            GWY_INTERPOLATION_NONE);
    gwy_data_field_clear(controls.tip);

    /* set up data of rescaled image of the tip */
    controls.vtip = gwy_container_new();
    gwy_app_sync_data_items(data, controls.vtip,
                            args->source.id, 0, FALSE,
                            GWY_DATA_ITEM_PALETTE,
                            0);

    dfield = gwy_data_field_new_alike(controls.tip, TRUE);
    gwy_data_field_resample(dfield, controls.vxres, controls.vyres,
                            GWY_INTERPOLATION_ROUND);
    gwy_container_set_object_by_name(controls.vtip, "/0/data", dfield);
    g_object_unref(dfield);

    /* set up rescaled image of the tip */
    vbox = gtk_vbox_new(FALSE, 0);
    gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 4);

    controls.view = gwy_data_view_new(controls.vtip);
    layer = gwy_layer_basic_new();
    gwy_pixmap_layer_set_data_key(layer, "/0/data");
    gwy_layer_basic_set_gradient_key(GWY_LAYER_BASIC(layer), "/0/base/palette");
    gwy_data_view_set_base_layer(GWY_DATA_VIEW(controls.view), layer);

    /* set up tip estimation controls */
    gtk_box_pack_start(GTK_BOX(vbox), controls.view, FALSE, FALSE, 0);

    gmodel = gwy_graph_model_new();
    controls.graph = gwy_graph_new(gmodel);
    g_object_unref(gmodel);
    gwy_axis_set_visible(gwy_graph_get_axis(GWY_GRAPH(controls.graph),
                                            GTK_POS_LEFT),
                         FALSE);
    gwy_axis_set_visible(gwy_graph_get_axis(GWY_GRAPH(controls.graph),
                                            GTK_POS_BOTTOM),
                         FALSE);
    area = GWY_GRAPH_AREA(gwy_graph_get_area(GWY_GRAPH(controls.graph)));
    gtk_widget_set_no_show_all(gwy_graph_area_get_label(area), TRUE);
    g_signal_connect_after(gwy_graph_area_get_label(area), "map",
                           G_CALLBACK(gtk_widget_hide), NULL);
    gtk_box_pack_start(GTK_BOX(vbox), controls.graph, TRUE, TRUE, 0);

    table = gtk_table_new(13, 4, FALSE);
    gtk_table_set_row_spacings(GTK_TABLE(table), 2);
    gtk_table_set_col_spacings(GTK_TABLE(table), 6);
    gtk_container_set_border_width(GTK_CONTAINER(table), 4);
    gtk_box_pack_start(GTK_BOX(hbox), table, FALSE, FALSE, 4);
    row = 0;

    controls.data = gwy_data_chooser_new_channels();
    gwy_data_chooser_set_filter(GWY_DATA_CHOOSER(controls.data),
                                tip_blind_source_filter, &args->orig, NULL);
    gwy_data_chooser_set_active_id(GWY_DATA_CHOOSER(controls.data),
                                   &args->source);
    g_signal_connect(controls.data, "changed",
                     G_CALLBACK(data_changed), &args->source);
    gwy_table_attach_hscale(table, row, _("Related _data:"), NULL,
                            GTK_OBJECT(controls.data), GWY_HSCALE_WIDGET);
    gtk_table_set_row_spacing(GTK_TABLE(table), row, 8);
    row++;

    label = gtk_label_new(_("Estimated Tip Size"));
    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
    gtk_table_attach(GTK_TABLE(table), label,
                     0, 4, row, row+1, GTK_FILL, 0, 0, 0);
    row++;

    controls.xres = gtk_adjustment_new(args->xres, MIN_RES, MAX_RES, 1, 10, 0);
    gwy_table_attach_hscale(table, row, _("_Width:"), "px", controls.xres, 0);
    g_object_set_data(G_OBJECT(controls.xres), "controls", &controls);
    g_signal_connect(controls.xres, "value-changed",
                     G_CALLBACK(width_changed), &controls);
    row++;

    controls.yres = gtk_adjustment_new(args->yres, MIN_RES, MAX_RES, 1, 10, 0);
    gwy_table_attach_hscale(table, row, _("_Height:"), "px", controls.yres, 0);
    g_object_set_data(G_OBJECT(controls.yres), "controls", &controls);
    g_signal_connect(controls.yres, "value-changed",
                     G_CALLBACK(height_changed), &controls);
    row++;

    controls.same_resolution
        = gtk_check_button_new_with_mnemonic(_("_Same resolution"));
    gtk_table_attach(GTK_TABLE(table), controls.same_resolution,
                     0, 4, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(controls.same_resolution),
                                 args->same_resolution);
    g_signal_connect(controls.same_resolution, "toggled",
                     G_CALLBACK(same_resolution_changed), &controls);
    gtk_table_set_row_spacing(GTK_TABLE(table), row, 8);
    row++;

    gtk_table_attach(GTK_TABLE(table), gwy_label_new_header(_("Options")),
                     0, 4, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    row++;

    controls.threshold = gtk_adjustment_new(1.0, 0.01, 1000.0, 0.01, 1.0, 0.0);
    controls.threshold_spin
        = gtk_spin_button_new(GTK_ADJUSTMENT(controls.threshold), 0.1, 2);
    gtk_table_attach(GTK_TABLE(table), controls.threshold_spin,
                     2, 3, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    label = gtk_label_new_with_mnemonic(_("Noise suppression t_hreshold:"));
    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
    gtk_label_set_mnemonic_widget(GTK_LABEL(label), controls.threshold_spin);
    gtk_table_attach(GTK_TABLE(table), label,
                     0, 2, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    unit = gwy_data_field_get_si_unit_z(dfield);
    controls.threshold_unit
        = gwy_combo_box_metric_unit_new(G_CALLBACK(thresh_changed),
                                        &controls,
                                        -12, -3, unit, -9);
    gtk_table_attach(GTK_TABLE(table), controls.threshold_unit,
                     3, 4, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    g_signal_connect(controls.threshold, "value-changed",
                     G_CALLBACK(thresh_changed), &controls);
    sci_entry_set_value(GTK_ADJUSTMENT(controls.threshold),
                        GTK_COMBO_BOX(controls.threshold_unit),
                        args->thresh);
    row++;

    controls.boundaries
                    = gtk_check_button_new_with_mnemonic(_("Use _boundaries"));
    gtk_table_attach(GTK_TABLE(table), controls.boundaries,
                     0, 4, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(controls.boundaries),
                                                 args->use_boundaries);
    g_signal_connect(controls.boundaries, "toggled",
                     G_CALLBACK(bound_changed), args);
    gtk_table_set_row_spacing(GTK_TABLE(table), row, 8);
    row++;

    gtk_table_attach(GTK_TABLE(table), gwy_label_new_header(_("Stripes")),
                     0, 4, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    row++;

    controls.nstripes = gtk_adjustment_new(args->nstripes,
                                           MIN_STRIPES, MAX_STRIPES, 1, 10, 0);
    gwy_table_attach_hscale(table, row, _("_Split to stripes:"), NULL,
                            controls.nstripes, GWY_HSCALE_CHECK);
    controls.split_to_stripes = gwy_table_hscale_get_check(controls.nstripes);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(controls.split_to_stripes),
                                 !args->split_to_stripes);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(controls.split_to_stripes),
                                 args->split_to_stripes);
    g_signal_connect(controls.split_to_stripes, "toggled",
                     G_CALLBACK(split_to_stripes_changed), &controls);
    g_signal_connect(controls.nstripes, "value-changed",
                     G_CALLBACK(nstripes_changed), &controls);
    row++;

    controls.stripeno = gtk_adjustment_new(1, 1, args->nstripes, 1, 10, 0);
    gwy_table_attach_hscale(table, row, _("_Preview stripe:"), NULL,
                            controls.stripeno, GWY_HSCALE_DEFAULT);
    g_signal_connect(controls.stripeno, "value-changed",
                     G_CALLBACK(stripeno_changed), &controls);
    row++;

    controls.plot_size_graph
        = gtk_check_button_new_with_mnemonic(_("Plot size _graph"));
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(controls.plot_size_graph),
                                 args->plot_size_graph);
    gtk_table_attach(GTK_TABLE(table), controls.plot_size_graph,
                     0, 4, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    g_signal_connect(controls.plot_size_graph, "toggled",
                     G_CALLBACK(plot_size_graph_changed), &controls);
    row++;

    controls.create_images
        = gtk_check_button_new_with_mnemonic(_("Create tip i_mages"));
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(controls.create_images),
                                 args->create_images);
    gtk_table_attach(GTK_TABLE(table), controls.create_images,
                     0, 4, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    g_signal_connect(controls.create_images, "toggled",
                     G_CALLBACK(create_images_changed), &controls);
    row++;

    controls.tipdone = FALSE;
    controls.in_update = FALSE;
    split_to_stripes_changed(GTK_TOGGLE_BUTTON(controls.split_to_stripes),
                             &controls);
    gtk_widget_show_all(dialog);

    do {
        response = gtk_dialog_run(GTK_DIALOG(dialog));
        switch (response) {
            case GTK_RESPONSE_CANCEL:
            case GTK_RESPONSE_DELETE_EVENT:
            gtk_widget_destroy(dialog);
            case GTK_RESPONSE_NONE:
            tip_blind_dialog_abandon(&controls);
            tip_blind_save_args(gwy_app_settings_get(), args);
            return;
            break;

            case GTK_RESPONSE_OK:
            tip_blind_save_args(gwy_app_settings_get(), args);
            tip_blind_do(&controls, args);
            break;

            case RESPONSE_RESET:
            reset(&controls, args);
            break;

            case RESPONSE_ESTIMATE:
            tip_blind_run(&controls, args, FALSE);
            break;

            case RESPONSE_REFINE:
            tip_blind_run(&controls, args, TRUE);
            break;

            default:
            g_assert_not_reached();
            break;
        }
    } while (response != GTK_RESPONSE_OK);

    gtk_widget_destroy(dialog);
    tip_blind_dialog_abandon(&controls);

    return;
}
Beispiel #23
0
static GwyDataField*
sensofar_read_data_field(SensofarDataDesc *data_desc,
                         GwyDataField **maskfield,
                         const guchar **p,
                         gsize size,
                         GError **error)
{
    GwyDataField *dfield, *mfield;
    guint xres, yres, i, j, mcount;
    GwySIUnit *units = NULL;
    gdouble *data, *mdata;

    if (maskfield)
        *maskfield = NULL;

    yres = gwy_get_guint32_le(p);
    xres = gwy_get_guint32_le(p);
    gwy_debug("Data size: %dx%d", xres, yres);
    if (err_SIZE_MISMATCH(error, xres*yres*sizeof(gfloat),
                          size - 2*sizeof(guint32), FALSE))
        return NULL;
    if (err_DIMENSION(error, xres) || err_DIMENSION(error, yres))
        return NULL;
    if (!((data_desc->axes_config.mppx
           = fabs(data_desc->axes_config.mppx)) > 0)) {
        g_warning("Real x size is 0.0, fixing to 1.0");
        data_desc->axes_config.mppx = 1.0;
    }
    if (!((data_desc->axes_config.mppy
           = fabs(data_desc->axes_config.mppy)) > 0)) {
        g_warning("Real y size is 0.0, fixing to 1.0");
        data_desc->axes_config.mppy = 1.0;
    }

    dfield = gwy_data_field_new(xres, yres, 
                                data_desc->axes_config.mppx * xres * Micrometer,
                                data_desc->axes_config.mppy * yres * Micrometer,
                                FALSE);
    units = gwy_si_unit_new("m"); // values are in um only
    gwy_data_field_set_si_unit_xy(dfield, units);
    g_object_unref(units);

    units = gwy_si_unit_new("m");
    gwy_data_field_set_si_unit_z(dfield, units);
    g_object_unref(units);

    mfield = gwy_data_field_new_alike(dfield, FALSE);
    gwy_data_field_fill(mfield, 1.0);

    data = gwy_data_field_get_data(dfield);
    mdata = gwy_data_field_get_data(mfield);
    for (i = 0; i < yres; i++) {
        for (j = 0; j < xres; j++) {
            gdouble v = gwy_get_gfloat_le(p);
            if (v == 1000001.0)
                mdata[i*xres + j] = 0.0;
            else
                data[i*xres + j] = v*Micrometer;
        }
    }

    gwy_debug("Offset: %g %g",
              data_desc->axes_config.x_0, data_desc->axes_config.y_0);
    //FIXME: offset later, support of offset determined by version?
    //gwy_data_field_set_xoffset(d, pow10(power10)*data_desc.axes_config.x_0);
    //gwy_data_field_set_yoffset(d, pow10(power10)*data_desc.axes_config.y_0);

    mcount = gwy_app_channel_remove_bad_data(dfield, mfield);

    if (maskfield && mcount)
        *maskfield = mfield;
    else
        g_object_unref(mfield);

    return dfield;
}
Beispiel #24
0
/**
 * gwy_data_field_correlate:
 * @data_field: A data field.
 * @kernel_field: Correlation kernel.
 * @score: Data field to store correlation scores to.
 * @method: Correlation score calculation method.
 *
 * Computes correlation score for all positions in a data field.
 *
 * Correlation score is compute for all points in data field @data_field
 * and full size of correlation kernel @kernel_field.
 *
 * The points in @score correspond to centers of kernel.  More precisely, the
 * point ((@kxres-1)/2, (@kyres-1)/2) in @score corresponds to kernel field
 * top left corner coincident with data field top left corner.  Points outside
 * the area where the kernel field fits into the data field completely are
 * set to -1 for %GWY_CORRELATION_NORMAL.
 **/
void
gwy_data_field_correlate(GwyDataField *data_field, GwyDataField *kernel_field,
                         GwyDataField *score, GwyCorrelationType method)
{

    gint xres, yres, kxres, kyres, i, j, k, fftxres, fftyres;
    GwyDataField *data_in_re, *data_out_re, *data_out_im;
    GwyDataField *kernel_in_re, *kernel_out_re, *kernel_out_im;
    gdouble norm;

    g_return_if_fail(data_field != NULL && kernel_field != NULL);

    xres = data_field->xres;
    yres = data_field->yres;
    kxres = kernel_field->xres;
    kyres = kernel_field->yres;

    if (kxres <= 0 || kyres <= 0) {
        g_warning("Correlation kernel has nonpositive size.");
        return;
    }

    switch (method) {
        case GWY_CORRELATION_NORMAL:
        gwy_data_field_fill(score, -1);
        /*correlation request outside kernel */
        if (kxres > xres || kyres > yres) {
            return;
        }

        {
            GwyDataField *avg, *rms;
            gdouble s, davg, drms, kavg, krms;
            gint xoff, yoff;

            /* The number of pixels the correlation kernel extends to the
             * negative direction */
            xoff = (kxres - 1)/2;
            yoff = (kyres - 1)/2;
            kavg = gwy_data_field_get_avg(kernel_field);
            krms = gwy_data_field_get_rms(kernel_field);
            avg = gwy_data_field_duplicate(data_field);
            rms = gwy_data_field_duplicate(data_field);
            calculate_normalization(avg, rms, kxres, kyres);
            for (i = yoff; i + kyres - yoff <= yres; i++) {
                for (j = xoff; j + kxres - xoff <= xres; j++) {
                    k = i*xres + j;
                    davg = avg->data[k];
                    drms = rms->data[k];
                    if (!krms || !drms) {
                        score->data[k] = 0.0;
                        continue;
                    }
                    s = gwy_data_field_get_raw_correlation_score(data_field,
                                                                 kernel_field,
                                                                 j - xoff,
                                                                 i - yoff,
                                                                 0, 0,
                                                                 kxres, kyres,
                                                                 davg, kavg);
                    score->data[k] = s/(drms*krms);
                }
            }
            g_object_unref(avg);
            g_object_unref(rms);
        }
        break;

        case GWY_CORRELATION_FFT:
        case GWY_CORRELATION_POC:
        fftxres = gwy_fft_find_nice_size(xres);
        fftyres = gwy_fft_find_nice_size(yres);
        data_in_re = gwy_data_field_new_resampled(data_field,
                                                  fftxres, fftyres,
                                                  GWY_INTERPOLATION_BILINEAR);
        kernel_in_re = gwy_data_field_new_alike(data_field, TRUE);
        gwy_data_field_area_copy(kernel_field, kernel_in_re,
                                 0, 0, kernel_field->xres, kernel_field->yres,
                                 kernel_in_re->xres/2 - kernel_field->xres/2,
                                 kernel_in_re->yres/2 - kernel_field->yres/2);
        gwy_data_field_resample(kernel_in_re, fftxres, fftyres,
                                GWY_INTERPOLATION_BILINEAR);
        gwy_data_field_resample(score, fftxres, fftyres,
                                GWY_INTERPOLATION_NONE);

        data_out_re = gwy_data_field_new_alike(data_in_re, TRUE);
        data_out_im = gwy_data_field_new_alike(data_in_re, TRUE);
        kernel_out_re = gwy_data_field_new_alike(data_in_re, TRUE);
        kernel_out_im = gwy_data_field_new_alike(data_in_re, TRUE);

        gwy_data_field_2dfft(data_in_re, NULL, data_out_re, data_out_im,
                             GWY_WINDOWING_NONE,
                             GWY_TRANSFORM_DIRECTION_FORWARD,
                             GWY_INTERPOLATION_BILINEAR, FALSE, FALSE);
        gwy_data_field_2dfft(kernel_in_re, NULL, kernel_out_re, kernel_out_im,
                             GWY_WINDOWING_NONE,
                             GWY_TRANSFORM_DIRECTION_FORWARD,
                             GWY_INTERPOLATION_BILINEAR, FALSE, FALSE);

        for (i = 0; i < fftxres*fftyres; i++) {
            /*NOTE: now we construct new "complex field" from data
             * and kernel fields, just to save memory*/
            data_in_re->data[i] = data_out_re->data[i]*kernel_out_re->data[i]
                + data_out_im->data[i]*kernel_out_im->data[i];
            kernel_in_re->data[i] = -data_out_re->data[i]*kernel_out_im->data[i]
                + data_out_im->data[i]*kernel_out_re->data[i];
            if (method == GWY_CORRELATION_POC) {
                norm = hypot(data_in_re->data[i], kernel_in_re->data[i]);
                data_in_re->data[i] /= norm;
                kernel_in_re->data[i] /= norm;
            }
        }
        gwy_data_field_2dfft(data_in_re, kernel_in_re, score, data_out_im,
                             GWY_WINDOWING_NONE,
                             GWY_TRANSFORM_DIRECTION_BACKWARD,
                             GWY_INTERPOLATION_BILINEAR, FALSE, FALSE);
        gwy_data_field_2dfft_humanize(score);

        /*TODO compute it and put to score field*/
        g_object_unref(data_in_re);
        g_object_unref(data_out_re);
        g_object_unref(data_out_im);
        g_object_unref(kernel_in_re);
        g_object_unref(kernel_out_re);
        g_object_unref(kernel_out_im);
        break;
    }

    gwy_data_field_invalidate(score);
}
Beispiel #25
0
static gboolean
xydenoise_do(XYdenoiseArgs *args)
{
    GwyContainer *data;
    GwyDataField *dfieldx, *rx, *ix, *dfieldy, *ry, *iy, *result, *iresult;
    gint i, newid, xres, yres;
    gdouble *rxdata, *rydata, *ixdata, *iydata;
    GwyWindowingType window = GWY_WINDOWING_NONE;
    GwyInterpolationType interp = GWY_INTERPOLATION_LINEAR;

    GQuark quark;

    data = gwy_app_data_browser_get(args->op1.datano);
    gwy_app_wait_start(gwy_app_find_window_for_channel(data, args->op1.id),
                       _("Initializing..."));

    quark = gwy_app_get_data_key_for_id(args->op1.id);
    dfieldx = GWY_DATA_FIELD(gwy_container_get_object(data, quark));

    data = gwy_app_data_browser_get(args->op2.datano);
    quark = gwy_app_get_data_key_for_id(args->op2.id);
    dfieldy = GWY_DATA_FIELD(gwy_container_get_object(data, quark));

    xres = gwy_data_field_get_xres(dfieldx);
    yres = gwy_data_field_get_yres(dfieldy);
    result = gwy_data_field_new_alike(dfieldx, TRUE);
    iresult = gwy_data_field_new_alike(dfieldx, TRUE);
    rx = gwy_data_field_new_alike(dfieldx, TRUE);
    ix = gwy_data_field_new_alike(dfieldx, TRUE);
    ry = gwy_data_field_new_alike(dfieldx, TRUE);
    iy = gwy_data_field_new_alike(dfieldx, TRUE);

    gwy_app_wait_set_fraction(0.1);
    gwy_app_wait_set_message(_("Computing forward FFTs..."));

    gwy_data_field_2dfft(dfieldx, NULL, rx, ix,
                         window, GWY_TRANSFORM_DIRECTION_FORWARD, interp,
                         FALSE, 0);

    gwy_data_field_2dfft(dfieldy, NULL, ry, iy,
                         window, GWY_TRANSFORM_DIRECTION_FORWARD, interp,
                         FALSE, 0);

    rxdata = gwy_data_field_get_data(rx);
    rydata = gwy_data_field_get_data(ry);
    ixdata = gwy_data_field_get_data(ix);
    iydata = gwy_data_field_get_data(iy);

    gwy_app_wait_set_fraction(0.3);
    gwy_app_wait_set_message(_("Computing image..."));

    for (i = 0; i < xres*yres; i++) {
        gdouble xmodule = sqrt(rxdata[i]*rxdata[i] + ixdata[i]*ixdata[i]);
        gdouble xphase = atan2(ixdata[i],rxdata[i]);
        gdouble ymodule = sqrt(rydata[i]*rydata[i] + iydata[i]*iydata[i]);
        /*gdouble yphase = atan2(iydata[i],rydata[i]);*/
        rxdata[i] = MIN(xmodule, ymodule)*cos(xphase);
        ixdata[i] = MIN(xmodule, ymodule)*sin(xphase);
    }

    gwy_app_wait_set_fraction(0.7);
    gwy_app_wait_set_message(_("Computing backward FFT..."));
    gwy_data_field_2dfft(rx, ix, result, iresult,
                         window, GWY_TRANSFORM_DIRECTION_BACKWARD, interp,
                         FALSE, 0);

    gwy_app_wait_set_fraction(0.9);

    data = gwy_app_data_browser_get(args->op1.datano);
    newid = gwy_app_data_browser_add_data_field(result, data, TRUE);
    gwy_app_sync_data_items(data, data, args->op1.id, newid, FALSE,
                            GWY_DATA_ITEM_GRADIENT, 0);

    gwy_app_set_data_field_title(data, newid, _("Denoised"));
    gwy_app_channel_log_add_proc(data, -1, newid);
    gwy_app_wait_finish();

    g_object_unref(result);
    g_object_unref(iresult);
    g_object_unref(rx);
    g_object_unref(ix);
    g_object_unref(ry);
    g_object_unref(iy);

    return TRUE;
}
Beispiel #26
0
static void
merge_do_correlate(MergeArgs *args)
{
    GwyDataField *dfield1, *dfield2;
    GwyDataField *correlation_data, *correlation_kernel, *correlation_score;
    GwyRectangle cdata, kdata;
    gint max_col, max_row;
    gint xres1, xres2, yres1, yres2;
    GwyMergeDirectionType real_dir = args->direction;
    GwyMergeBoundaryType real_boundary = args->boundary;
    gint px1, py1, px2, py2;
    GwyContainer *data1, *data2;
    GQuark quark;

    data1 = gwy_app_data_browser_get(args->op1.datano);
    quark = gwy_app_get_data_key_for_id(args->op1.id);
    dfield1 = GWY_DATA_FIELD(gwy_container_get_object(data1, quark));

    data2 = gwy_app_data_browser_get(args->op2.datano);
    quark = gwy_app_get_data_key_for_id(args->op2.id);
    dfield2 = GWY_DATA_FIELD(gwy_container_get_object(data2, quark));

    if ((dfield1->xres*dfield1->yres) < (dfield2->xres*dfield2->yres)) {
        GWY_SWAP(GwyDataField*, dfield1, dfield2);
        if (args->direction == GWY_MERGE_DIRECTION_UP)
            real_dir = GWY_MERGE_DIRECTION_DOWN;
        else if (args->direction == GWY_MERGE_DIRECTION_DOWN)
            real_dir = GWY_MERGE_DIRECTION_UP;
        else if (args->direction == GWY_MERGE_DIRECTION_LEFT)
            real_dir = GWY_MERGE_DIRECTION_RIGHT;
        else if (args->direction == GWY_MERGE_DIRECTION_RIGHT)
            real_dir = GWY_MERGE_DIRECTION_LEFT;
        else
            g_return_if_reached();

        if (args->boundary == GWY_MERGE_BOUNDARY_FIRST)
            real_boundary = GWY_MERGE_BOUNDARY_SECOND;
        else if (args->boundary == GWY_MERGE_BOUNDARY_SECOND)
            real_boundary = GWY_MERGE_BOUNDARY_FIRST;
    }

    xres1 = gwy_data_field_get_xres(dfield1);
    xres2 = gwy_data_field_get_xres(dfield2);
    yres1 = gwy_data_field_get_yres(dfield1);
    yres2 = gwy_data_field_get_yres(dfield2);

    /*cut data for correlation*/
    switch (real_dir) {
    case GWY_MERGE_DIRECTION_UP:
        cdata.x = 0;
        cdata.y = 0;
        cdata.width = xres1;
        cdata.height = yres1/2;
        kdata.width = MIN(xres2, cdata.width/2);
        kdata.height = MIN(yres2, cdata.height/3);
        kdata.x = MAX(0, xres2/2 - kdata.width/2);
        kdata.y = MAX(0, yres2 - cdata.height/3);
        break;

    case GWY_MERGE_DIRECTION_DOWN:
        cdata.x = 0;
        cdata.y = yres1 - (yres1/2);
        cdata.width = xres1;
        cdata.height = yres1/2;
        kdata.width = MIN(xres2, cdata.width/2);
        kdata.height = MIN(yres2, cdata.height/3);
        kdata.x = MAX(0, xres2/2 - kdata.width/2);
        kdata.y = 0;
        break;

    case GWY_MERGE_DIRECTION_RIGHT:
        cdata.x = xres1 - (xres1/2);
        cdata.y = 0;
        cdata.width = xres1/2;
        cdata.height = yres1;
        kdata.width = MIN(xres2, cdata.width/3);
        kdata.height = MIN(yres2, cdata.height/2);
        kdata.x = 0;
        kdata.y = MAX(0, yres2/2 - kdata.height/2);
        break;

    case GWY_MERGE_DIRECTION_LEFT:
        cdata.x = 0;
        cdata.y = 0;
        cdata.width = xres1/2;
        cdata.height = yres1;
        kdata.width = MIN(xres2, cdata.width/3);
        kdata.height = MIN(yres2, cdata.height/2);
        kdata.x = MAX(0, xres2 - cdata.width/3);
        kdata.y = MAX(0, yres2/2 - kdata.height/2);
        break;

    default:
        g_assert_not_reached();
        break;
    }

    correlation_data = gwy_data_field_area_extract(dfield1,
                       cdata.x,
                       cdata.y,
                       cdata.width,
                       cdata.height);
    correlation_kernel = gwy_data_field_area_extract(dfield2,
                         kdata.x,
                         kdata.y,
                         kdata.width,
                         kdata.height);
    correlation_score = gwy_data_field_new_alike(correlation_data, FALSE);

    /* get appropriate correlation score */
    if (!get_score_iteratively(correlation_data, correlation_kernel,
                               correlation_score, args))
        goto end;

    find_score_maximum(correlation_score, &max_col, &max_row);
    gwy_debug("c: %d %d %dx%d  k: %d %d %dx%d res: %d %d",
              cdata.x,
              cdata.y,
              cdata.width,
              cdata.height,
              kdata.x,
              kdata.y,
              kdata.width,
              kdata.height,
              max_col, max_row);

    px1 = 0;
    px2 = (max_col - (kdata.width-1)/2) + cdata.x - kdata.x;
    py1 = 0;
    py2 = (max_row - (kdata.height-1)/2) + cdata.y - kdata.y;
    if (px2 < 0) {
        px1 = -px2;
        px2 = 0;
    }
    if (py2 < 0) {
        py1 = -py2;
        py2 = 0;
    }

    create_merged_field(data1, args->op1.id,
                        dfield1, dfield2,
                        px1, py1, px2, py2,
                        real_boundary, real_dir,
                        args->create_mask, args->crop_to_rectangle);

end:
    g_object_unref(correlation_data);
    g_object_unref(correlation_kernel);
    g_object_unref(correlation_score);
}
Beispiel #27
0
static void
gwy_data_field_facet_distribution(GwyDataField *dfield,
                                  gint kernel_size,
                                  GwyContainer *container)
{
    GwyDataField *dtheta, *dphi, *dist;
    GwySIUnit *siunit;
    gdouble *xd, *yd, *data;
    const gdouble *xdc, *ydc;
    gdouble q, max;
    gint res, hres, i, j, mi, mj, xres, yres;

    if (gwy_container_gis_object_by_name(container, "/theta", &dtheta))
        g_object_ref(dtheta);
    else
        dtheta = gwy_data_field_new_alike(dfield, FALSE);

    if (gwy_container_gis_object_by_name(container, "/phi", &dphi))
        g_object_ref(dphi);
    else
        dphi = gwy_data_field_new_alike(dfield, FALSE);

    compute_slopes(dfield, kernel_size, dtheta, dphi);
    xres = gwy_data_field_get_xres(dfield);
    yres = gwy_data_field_get_yres(dfield);
    xd = gwy_data_field_get_data(dtheta);
    yd = gwy_data_field_get_data(dphi);

    for (i = xres*yres; i; i--, xd++, yd++) {
        gdouble theta, phi;

        slopes_to_angles(*xd, *yd, &theta, &phi);
        *xd = theta;
        *yd = phi;
    }
    q = gwy_data_field_get_max(dtheta);
    q = MIN(q*1.05, G_PI/2.0);
    q = G_SQRT2/(2.0*sin(q/2.0));

    if (gwy_container_gis_object_by_name(container, "/0/data", &dist)) {
        g_object_ref(dist);
        gwy_data_field_clear(dist);
        gwy_data_field_set_xreal(dist, 2.0*G_SQRT2/q);
        gwy_data_field_set_yreal(dist, 2.0*G_SQRT2/q);
    }
    else {
        dist = gwy_data_field_new(FDATA_RES, FDATA_RES,
                                  2.0*G_SQRT2/q, 2.0*G_SQRT2/q,
                                  TRUE);
        siunit = gwy_si_unit_new("");
        gwy_data_field_set_si_unit_z(dist, siunit);
        g_object_unref(siunit);
        /* FIXME */
        siunit = gwy_si_unit_new("");
        gwy_data_field_set_si_unit_xy(dist, siunit);
        g_object_unref(siunit);
    }

    res = FDATA_RES;
    hres = (res - 1)/2;
    data = gwy_data_field_get_data(dist);

    xdc = gwy_data_field_get_data_const(dtheta);
    ydc = gwy_data_field_get_data_const(dphi);
    for (i = xres*yres; i; i--, xdc++, ydc++) {
        gdouble x, y;
        gint xx, yy;

        angles_to_xy(*xdc, *ydc, &x, &y);
        xx = GWY_ROUND(q*x/G_SQRT2*hres) + hres;
        yy = GWY_ROUND(q*y/G_SQRT2*hres) + hres;
        data[yy*res + xx] += 1.0;
    }

    /* Find maxima */
    mi = mj = hres;
    max = 0;
    for (i = 1; i+1 < res; i++) {
        for (j = 1; j+1 < res; j++) {
            gdouble z;

            z = data[i*res + j]
                + 0.3*(data[i*res + j - 1]
                       + data[i*res + j + 1]
                       + data[i*res - res + j]
                       + data[i*res + res + j])
                + 0.1*(data[i*res - res + j - 1]
                       + data[i*res - res + j + 1]
                       + data[i*res + res + j - 1]
                       + data[i*res + res + j + 1]);
            if (G_UNLIKELY(z > max)) {
                max = z;
                mi = i;
                mj = j;
            }
        }
    }

    for (i = res*res; i; i--, data++)
        *data = pow(*data, 0.35);

    gwy_container_set_double_by_name(container, "/q", q);
    {
        gdouble x, y, theta, phi;

        x = (mj - hres)*G_SQRT2/(q*hres);
        y = (mi - hres)*G_SQRT2/(q*hres);
        xy_to_angles(x, y, &theta, &phi);
        gwy_container_set_double_by_name(container, "/theta0", theta);
        gwy_container_set_double_by_name(container, "/phi0", phi);
    }
    gwy_container_set_object_by_name(container, "/0/data", dist);
    g_object_unref(dist);
    gwy_container_set_object_by_name(container, "/theta", dtheta);
    g_object_unref(dtheta);
    gwy_container_set_object_by_name(container, "/phi", dphi);
    g_object_unref(dphi);
    gwy_container_set_string_by_name(container, "/0/base/palette",
                                     g_strdup(FVIEW_GRADIENT));

    gwy_data_field_data_changed(dist);
}
Beispiel #28
0
static void
maskcor_do(MaskcorArgs *args)
{
    enum { WORK_PER_UPDATE = 50000000 };
    GwyDataField *dfield, *kernel, *retfield, *score;
    GwyContainer *data, *kerneldata;
    GwyComputationState *state;
    GQuark quark;
    gint newid, work, wpi;

    kerneldata = gwy_app_data_browser_get(args->kernel.datano);
    quark = gwy_app_get_data_key_for_id(args->kernel.id);
    kernel = GWY_DATA_FIELD(gwy_container_get_object(kerneldata, quark));

    data = gwy_app_data_browser_get(args->data.datano);
    quark = gwy_app_get_data_key_for_id(args->data.id);
    dfield = GWY_DATA_FIELD(gwy_container_get_object(data, quark));

    retfield = gwy_data_field_new_alike(dfield, FALSE);

    /* FIXME */
    if (args->method == GWY_CORRELATION_NORMAL) {
        gwy_app_wait_start(gwy_app_find_window_for_channel(data, args->data.id),
                           _("Initializing..."));
        state = gwy_data_field_correlate_init(dfield, kernel, retfield);
        gwy_app_wait_set_message(_("Correlating..."));
        work = 0;
        wpi = gwy_data_field_get_xres(kernel)*gwy_data_field_get_yres(kernel);
        wpi = MIN(wpi, WORK_PER_UPDATE);
        do {
            gwy_data_field_correlate_iteration(state);
            work += wpi;
            if (work > WORK_PER_UPDATE) {
                work -= WORK_PER_UPDATE;
                if (!gwy_app_wait_set_fraction(state->fraction)) {
                    gwy_data_field_correlate_finalize(state);
                    gwy_app_wait_finish();
                    g_object_unref(retfield);
                    return;
                }
            }
        } while (state->state != GWY_COMPUTATION_STATE_FINISHED);
        gwy_data_field_correlate_finalize(state);
        gwy_app_wait_finish();
    }
    else
        gwy_data_field_correlate(dfield, kernel, retfield, args->method);

    /* score - do new data with score */
    if (args->result == GWY_MASKCOR_SCORE) {
        score = gwy_data_field_duplicate(retfield);
        newid = gwy_app_data_browser_add_data_field(score, data, TRUE);
        gwy_app_sync_data_items(data, data,
                                args->data.id, newid, FALSE,
                                GWY_DATA_ITEM_GRADIENT, 0);
        gwy_app_set_data_field_title(data, newid,
                                     _("Correlation score"));
        g_object_unref(score);
        gwy_app_channel_log_add_proc(data, args->data.id, newid);
    }
    else {
        /* add mask */
        quark = gwy_app_get_mask_key_for_id(args->data.id);
        gwy_app_undo_qcheckpointv(data, 1, &quark);
        if (args->result == GWY_MASKCOR_OBJECTS)
            plot_correlated(retfield,
                            gwy_data_field_get_xres(kernel),
                            gwy_data_field_get_yres(kernel),
                            args->threshold);
        else if (args->result == GWY_MASKCOR_MAXIMA)
            gwy_data_field_threshold(retfield, args->threshold, 0.0, 1.0);

        gwy_container_set_object(data, quark, retfield);
        gwy_app_channel_log_add_proc(data, args->data.id, args->data.id);
    }
    g_object_unref(retfield);
}