コード例 #1
0
ファイル: rhk-spm32.c プロジェクト: DavidMercier/gwyddion
static GwyDataField*
rhkspm32_read_data(RHKPage *rhkpage)
{
    GwyDataField *dfield;
    const guint16 *p;
    GwySIUnit *siunit;
    gdouble *data;
    const gchar *s;
    gdouble q;
    gint power10;
    guint i, j, xres, yres;

    p = (const guint16*)(rhkpage->buffer + rhkpage->data_offset);
    xres = rhkpage->xres;
    yres = rhkpage->yres;
    // the scales are no longer gurunteed to be positive,
    // so they must be "fixed" here (to enable spectra)
    dfield = gwy_data_field_new(xres, yres,
                                xres*fabs(rhkpage->x.scale),
                                yres*fabs(rhkpage->y.scale),
                                FALSE);

    data = gwy_data_field_get_data(dfield);
    for (i = 0; i < yres; i++) {
        for (j = 0; j < xres; j++)
            data[i*xres + xres-1 - j] = GINT16_FROM_LE(p[i*xres + j]);
    }

    siunit = gwy_data_field_get_si_unit_xy(dfield);
    gwy_si_unit_set_from_string_parse(siunit, rhkpage->x.units, &power10);
    if (power10) {
        q = pow10(power10);
        gwy_data_field_set_xreal(dfield, q*gwy_data_field_get_xreal(dfield));
        gwy_data_field_set_yreal(dfield, q*gwy_data_field_get_yreal(dfield));
    }

    siunit = gwy_data_field_get_si_unit_z(dfield);
    s = rhkpage->z.units;
    /* Fix some silly units */
    if (gwy_strequal(s, "N/sec"))
        s = "s^-1";
    gwy_si_unit_set_from_string_parse(siunit, s, &power10);
    q = pow10(power10);

    gwy_data_field_multiply(dfield, q*fabs(rhkpage->z.scale));
    gwy_data_field_add(dfield, q*rhkpage->z.offset);

    return dfield;
}
コード例 #2
0
ファイル: gwysiunit.c プロジェクト: svn2github/gwyddion
/**
 * gwy_si_unit_set_from_string:
 * @siunit: An SI unit.
 * @unit_string: Unit string to set @siunit from (it can be %NULL for an empty
 *               unit).
 *
 * Sets string that represents unit.
 *
 * It must be base unit with no prefixes (e. g. "m", "N", "A", etc.).
 **/
void
gwy_si_unit_set_from_string(GwySIUnit *siunit,
                            const gchar *unit_string)
{
    g_return_if_fail(GWY_IS_SI_UNIT(siunit));
    gwy_si_unit_set_from_string_parse(siunit, unit_string, NULL);
}
コード例 #3
0
ファイル: shimadzu.c プロジェクト: DavidMercier/gwyddion
static GwyDataField*
read_text_data(const gchar *buffer,
               gint text_data_start,
               GHashTable *hash,
               GError **error)
{
    const gchar *p;
    gchar *end;
    gint xres, yres, i, power10;
    gdouble xreal, yreal, zscale, xoff, yoff, zoff;
    GwySIUnit *unitxy, *unitz;
    GwyDataField *dfield = NULL;
    gdouble *d;

    unitxy = gwy_si_unit_new(NULL);
    unitz = gwy_si_unit_new(NULL);

    if (!get_scales(hash, TRUE,
                    &xres, &yres, &xreal, &yreal, &xoff, &yoff, unitxy,
                    &zscale, &zoff, unitz, error))
        goto fail;

    p = g_hash_table_lookup(hash, "DATA Unit");
    gwy_si_unit_set_from_string_parse(unitz, p, &power10);
    zscale = pow10(power10);

    dfield = gwy_data_field_new(xres, yres, xreal, yreal, FALSE);
    gwy_data_field_set_xoffset(dfield, xoff);
    gwy_data_field_set_yoffset(dfield, yoff);
    gwy_data_field_set_si_unit_xy(dfield, unitxy);
    gwy_data_field_set_si_unit_z(dfield, unitz);
    d = gwy_data_field_get_data(dfield);

    p = (const gchar*)buffer + text_data_start;
    for (i = 0; i < xres*yres; i++) {
        d[i] = zscale*g_ascii_strtod(p, &end) + zoff;
        if (end == p) {
            g_set_error(error, GWY_MODULE_FILE_ERROR,
                        GWY_MODULE_FILE_ERROR_DATA,
                        _("Cannot parse data values after %d of %d."),
                        i, xres*yres);
            gwy_object_unref(dfield);
            goto fail;
        }
        p = end + (*end == ',');
    }

fail:
    g_object_unref(unitxy);
    g_object_unref(unitz);
    return dfield;
}
コード例 #4
0
ファイル: shimadzu.c プロジェクト: DavidMercier/gwyddion
static gboolean
get_scales(GHashTable *hash,
           gboolean is_text,
           gint *xres, gint *yres,
           gdouble *xreal, gdouble *yreal,
           gdouble *xoff, gdouble *yoff,
           GwySIUnit *si_unit_xy,
           gdouble *zscale,
           gdouble *zoff,
           GwySIUnit *si_unit_z,
           GError **error)
{
    GwySIUnit *unit;
    gint power10, zp;
    gchar *p;
    gboolean has_unit = FALSE;

    /* Dimensions are mandatory. */
    if (!require_keys(hash, error,
                      "SCANNING PARAMS::PixelsX",
                      "SCANNING PARAMS::PixelsY",
                      "SCANNING PARAMS::PixelsZ",
                      "SCANNING PARAMS::SizeX",
                      "SCANNING PARAMS::SizeY",
                      "SCANNING PARAMS::SizeZ",
                      NULL))
        return FALSE;

    *xres = atoi(g_hash_table_lookup(hash, "SCANNING PARAMS::PixelsX"));
    if (err_DIMENSION(error, *xres))
        return FALSE;
    *yres = atoi(g_hash_table_lookup(hash, "SCANNING PARAMS::PixelsY"));
    if (err_DIMENSION(error, *yres))
        return FALSE;

    unit = gwy_si_unit_new(NULL);

    p = g_hash_table_lookup(hash, "SCANNING PARAMS::SizeX");
    *xreal = fabs(g_ascii_strtod(p, &p));
    if (!*xreal) {
        g_warning("Real x size is 0.0, fixing to 1.0");
        *xreal = 1.0;
    }
    gwy_si_unit_set_from_string_parse(si_unit_xy, p, &power10);
    *xreal *= pow10(power10);

    p = g_hash_table_lookup(hash, "SCANNING PARAMS::SizeY");
    *yreal = fabs(g_ascii_strtod(p, &p));
    if (!*yreal) {
        g_warning("Real y size is 0.0, fixing to 1.0");
        *yreal = 1.0;
    }
    gwy_si_unit_set_from_string_parse(unit, p, &power10);
    *yreal *= pow10(power10);
    if (!gwy_si_unit_equal(unit, si_unit_xy)) {
        g_warning("X and Y units differ, using X");
    }

    zp = atoi(g_hash_table_lookup(hash, "SCANNING PARAMS::PixelsZ"));
    if (!zp) {
        g_warning("Z pixels is 0, fixing to 1");
        zp = 1;
    }
    p = g_hash_table_lookup(hash, "SCANNING PARAMS::SizeZ");
    *zscale = g_ascii_strtod(p, &p);
    *zoff = 0.0;
    gwy_si_unit_set_from_string_parse(si_unit_z, p, &power10);
    *zscale *= pow10(power10)/zp;
    /* XXX: Version 4 can have UNIT section that takes precedence.  The Conv
     * factor may not be enough.  Apparently, binary phase data need
     * subtracting 180 deg because data are unsinged.  Bite me. */
    if ((p = g_hash_table_lookup(hash, "UNIT::Unit"))) {
        const gchar *s = g_hash_table_lookup(hash, "UNIT::Name");
        has_unit = TRUE;
        gwy_si_unit_set_from_string_parse(si_unit_z, p, &power10);
        *zscale *= pow10(power10);
        if ((p = g_hash_table_lookup(hash, "UNIT::Conv")))
            *zscale *= g_ascii_strtod(p, NULL);

        if (!is_text && gwy_strequal(s, "Phase"))
            *zoff = -180.0;
    }

    /* Offsets are optional. */
    *xoff = 0.0;
    if ((p = g_hash_table_lookup(hash, "SCANNING PARAMS::OffsetX"))) {
        *xoff = g_ascii_strtod(p, &p);
        gwy_si_unit_set_from_string_parse(unit, p, &power10);
        if (gwy_si_unit_equal(unit, si_unit_xy))
            *xoff *= pow10(power10);
        else {
            g_warning("X offset units differ from X size units, ignoring.");
            *xoff = 0.0;
        }
    }

    *yoff = 0.0;
    if ((p = g_hash_table_lookup(hash, "SCANNING PARAMS::OffsetY"))) {
        *yoff = g_ascii_strtod(p, &p);
        gwy_si_unit_set_from_string_parse(unit, p, &power10);
        if (gwy_si_unit_equal(unit, si_unit_xy))
            *yoff *= pow10(power10);
        else {
            g_warning("Y offset units differ from Y size units, ignoring.");
            *yoff = 0.0;
        }
    }

    // Don't know what to do with the offset when UNIT section is present.
    // It seems to be always 0 in wrong units, so skip it.
    if (!has_unit) {
        if ((p = g_hash_table_lookup(hash, "SCANNING PARAMS::OffsetZ"))) {
            *zoff = g_ascii_strtod(p, &p);
            gwy_si_unit_set_from_string_parse(unit, p, &power10);
            if (gwy_si_unit_equal(unit, si_unit_z))
                *zoff *= pow10(power10);
            else {
                g_warning("Z offset units differ from Z size units, ignoring.");
                *zoff = 0.0;
            }
        }
    }

    g_object_unref(unit);

    return TRUE;
}
コード例 #5
0
ファイル: igorfile.c プロジェクト: DavidMercier/gwyddion
static GwyDataField*
igor_read_data_field(const IgorFile *igorfile,
                     const guchar *buffer,
                     guint i,
                     const gchar *zunits,
                     gboolean imaginary)
{
    const IgorWaveHeader5 *wave5;
    guint n, xres, yres, skip;
    GwyDataField *dfield;
    GwySIUnit *unit;
    gdouble *data;
    const guchar *p;
    gint power10;
    gdouble q;

    wave5 = &igorfile->wave5;
    xres = wave5->n_dim[0];
    yres = wave5->n_dim[1];
    p = buffer + igorfile->headers_size + xres*yres*igorfile->type_size*i;
    n = xres*yres;

    dfield = gwy_data_field_new(xres, yres,
                                wave5->sfA[0]*xres, wave5->sfA[1]*yres,
                                FALSE);
    data = gwy_data_field_get_data(dfield);

    g_return_val_if_fail(!imaginary || (wave5->type & IGOR_COMPLEX), dfield);
    skip = imaginary ? igorfile->type_size/2 : 0;
    if (imaginary)
        p += skip;

    /* TODO: Support extended units */
    unit = gwy_data_field_get_si_unit_xy(dfield);
    gwy_si_unit_set_from_string_parse(unit, wave5->dim_units[0], &power10);
    gwy_data_field_set_xreal(dfield, pow10(power10)*wave5->sfA[0]*xres);
    gwy_data_field_set_yreal(dfield, pow10(power10)*wave5->sfA[1]*yres);

    unit = gwy_data_field_get_si_unit_z(dfield);
    gwy_si_unit_set_from_string_parse(unit, zunits ? zunits : wave5->data_units,
                                      &power10);
    q = pow10(power10);

    switch ((guint)wave5->type) {
        case IGOR_INT8:
        {
            const gint8 *ps = (const gint8*)buffer;
            while (n--) {
                *(data++) = *(ps++) * q;
                ps += skip;
            }
        }
        break;

        case IGOR_INT8 | IGOR_UNSIGNED:
        while (n--) {
            *(data++) = *(p++) * q;
            p += skip;
        }
        break;

        case IGOR_INT16:
        while (n--) {
            *(data++) = igorfile->get_gint16(&p) * q;
            p += skip;
        }
        break;

        case IGOR_INT16 | IGOR_UNSIGNED:
        while (n--) {
            *(data++) = igorfile->get_guint16(&p) * q;
            p += skip;
        }
        break;

        case IGOR_INT32:
        while (n--) {
            *(data++) = igorfile->get_gint32(&p) * q;
            p += skip;
        }
        break;

        case IGOR_INT32 | IGOR_UNSIGNED:
        while (n--) {
            *(data++) = igorfile->get_guint32(&p) * q;
            p += skip;
        }
        break;

        case IGOR_SINGLE:
        while (n--) {
            *(data++) = igorfile->get_gfloat(&p) * q;
            p += skip;
        }
        break;

        case IGOR_DOUBLE:
        while (n--) {
            *(data++) = igorfile->get_gdouble(&p) * q;
            p += skip;
        }
        break;

        default:
        g_return_val_if_reached(NULL);
        break;
    }

    gwy_data_field_invert(dfield, TRUE, FALSE, FALSE);

    return dfield;
}
コード例 #6
0
ファイル: fitsfile.c プロジェクト: DavidMercier/gwyddion
static GwyContainer*
fits_load(const gchar *filename,
          G_GNUC_UNUSED GwyRunType mode,
          GError **error)
{
    GwyContainer *container = NULL;
    fitsfile *fptr = NULL;
    GwyDataField *field = NULL, *mask;
    gint status = 0;   /* Must be initialised to zero! */
    gint hdutype, naxis, anynull, nkeys, k;
    glong res[3];    /* First index is the fast looping one. */
    char strvalue[FLEN_VALUE];
    gchar *invalid = NULL;
    gdouble real, off;

    if (fits_open_image(&fptr, filename, READONLY, &status)) {
        err_FITS(error, status);
        return NULL;
    }

    if (fits_get_hdu_type(fptr, &hdutype, &status)) {
        err_FITS(error, status);
        goto fail;
    }

    gwy_debug("hdutype %d", hdutype);
    if (hdutype != IMAGE_HDU) {
        g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA,
                    _("Only two-dimensional images are supported."));
        goto fail;
    }

    if (fits_get_img_dim(fptr, &naxis, &status)) {
        err_FITS(error, status);
        goto fail;
    }

    gwy_debug("naxis %d", naxis);
    if (naxis != 2 && naxis != 3) {
        g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA,
                    _("Only two-dimensional images are supported."));
        goto fail;
    }

    if (fits_get_img_size(fptr, naxis, res, &status)) {
        err_FITS(error, status);
        goto fail;
    }

    if (naxis == 3 && res[2] != 1) {
        g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA,
                    _("Only two-dimensional images are supported."));
        goto fail;
    }

    gwy_debug("xres %ld, yres %ld", res[0], res[1]);
    if (err_DIMENSION(error, res[0]) || err_DIMENSION(error, res[1]))
        goto fail;

    field = gwy_data_field_new(res[0], res[1], res[0], res[1], FALSE);
    invalid = g_new(gchar, res[0]*res[1]);
    if (fits_read_imgnull(fptr, TDOUBLE, 1, res[0]*res[1],
                          field->data, invalid, &anynull, &status)) {
        err_FITS(error, status);
        goto fail;
    }

    container = gwy_container_new();
    gwy_container_set_object_by_name(container, "/0/data", field);

    /* Failures here are non-fatal.  We already have an image. */
    if (fits_get_hdrspace(fptr, &nkeys, NULL, &status)) {
        g_warning("Cannot get the first hdrspace.");
        goto fail;
    }

    if (!fits_read_key(fptr, TSTRING, "BUINT   ", strvalue, NULL, &status)) {
        gint power10;

        gwy_debug("BUINT = <%s>", strvalue);
        gwy_si_unit_set_from_string_parse(gwy_data_field_get_si_unit_z(field),
                                          strvalue, &power10);
        if (power10)
            gwy_data_field_multiply(field, pow10(power10));
    }
    status = 0;

    if (get_real_and_offset(fptr, 1, res[0], &real, &off)) {
        if (real < 0.0) {
            off += real;
            real = -real;
            gwy_data_field_invert(field, FALSE, TRUE, FALSE);
        }
        gwy_data_field_set_xreal(field, real);
        gwy_data_field_set_xoffset(field, off);
    }

    if (get_real_and_offset(fptr, 2, res[1], &real, &off)) {
        if (real < 0.0) {
            off += real;
            real = -real;
            gwy_data_field_invert(field, TRUE, FALSE, FALSE);
        }
        gwy_data_field_set_yreal(field, real);
        gwy_data_field_set_yoffset(field, off);
    }

    /* Create a mask of invalid data. */
    for (k = 0; k < field->xres*field->yres; k++) {
        if (invalid[k])
            field->data[k] = NAN;
    }
    if ((mask = gwy_app_channel_mask_of_nans(field, TRUE))) {
        gwy_container_set_object_by_name(container, "/0/mask", mask);
        g_object_unref(mask);
    }

fail:
    fits_close_file(fptr, &status);
    gwy_object_unref(field);
    g_free(invalid);

    return container;
}