IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 15041


Ignore:
Timestamp:
Sep 26, 2007, 6:27:03 PM (19 years ago)
Author:
eugene
Message:

added case of 1xN or Nx1 maps

Location:
trunk/psLib/src/imageops
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/imageops/psImageMap.h

    r14988 r15041  
    77 *  @author Eugene Magnier, IfA
    88 *
    9  *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
    10  *  @date $Date: 2007-09-24 02:59:46 $
     9 *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
     10 *  @date $Date: 2007-09-27 04:27:03 $
    1111 *
    1212 *  Copyright 2007 Institute for Astronomy, University of Hawaii
     
    5757bool psImageMapClipFit (psImageMap *map, psStats *stats, psVector *mask, psMaskType maskValue, psVector *x, psVector *y, psVector *f, psVector *df);
    5858
     59bool psImageMapFit1DinY (psImageMap *map, psVector *mask, psMaskType maskValue, psVector *x, psVector *y, psVector *f, psVector *df);
     60bool psImageMapFit1DinX (psImageMap *map, psVector *mask, psMaskType maskValue, psVector *x, psVector *y, psVector *f, psVector *df);
     61
    5962/// @}
    6063#endif // #ifndef PS_IMAGE_MAP_H
  • trunk/psLib/src/imageops/psImageMapFit.c

    r15001 r15041  
    77 *  @author Eugene Magnier, IfA
    88 *
    9  *  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
    10  *  @date $Date: 2007-09-24 21:29:10 $
     9 *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
     10 *  @date $Date: 2007-09-27 04:27:03 $
    1111 *
    1212 *  Copyright 2007 Institute for Astronomy, University of Hawaii
     
    6868
    6969    if (Nx == 1) {
    70         psAbort ("un-implemented edge case");
    71         goto insert;
     70        bool status;
     71        status = psImageMapFit1DinY (map, mask, maskValue, x, y, f, df);
     72        return status;
    7273    }
    7374    if (Ny == 1) {
    74         psAbort ("un-implemented edge case");
    75         goto insert;
     75        bool status;
     76        status = psImageMapFit1DinX (map, mask, maskValue, x, y, f, df);
     77        return status;
    7678    }
    7779
     
    231233            sA[+1][+1] = dx_rx_dy_ry;
    232234
    233         insert:
    234235            // I[ 0][ 0] = index for this n,m element:
    235236            I = n + Nx * m;
     
    271272    }
    272273
    273     # if (0)
     274# if (0)
    274275    psFits *fits = psFitsOpen ("Agj.fits", "w");
    275276    psFitsWriteImage (fits, NULL, A, 0, NULL);
     
    285286    psFitsClose (fits);
    286287    psFree (vector);
    287     # endif
     288# endif
    288289
    289290    if (!psMatrixGJSolveF32(A, B)) {
     
    433434    return true;
    434435}
     436
     437// map defines the output image dimensions and scaling.
     438bool psImageMapFit1DinY (psImageMap *map, psVector *mask, psMaskType maskValue, psVector *x, psVector *y, psVector *f, psVector *df) {
     439
     440    int I, J;
     441
     442    // XXX Add Asserts
     443    assert (map->binning->nXruff == 1);
     444
     445    // dimensions of the output map image
     446    int Ny = map->binning->nYruff;
     447
     448    // set up the redirection table so we can use sA[-1][-1], etc
     449    float SAv[3], *sA;
     450
     451    sA = SAv + 1;
     452
     453    // elements of the matrix equation Ax = B; we are solving for the vector x
     454    psImage *A = psImageAlloc (Ny, Ny, PS_TYPE_F32);
     455    psVector *B = psVectorAlloc (Ny, PS_TYPE_F32);
     456
     457    psImageInit (A, 0.0);
     458    psVectorInit (B, 0.0);
     459
     460    for (int m = 0; m < Ny; m++) {
     461        // define & init summing variables
     462        float ry_ry = 0;
     463        float dy_ry = 0;
     464        float fi_ry = 0;
     465        float py_py = 0;
     466        float qy_py = 0;
     467        float fi_py = 0;
     468
     469        // generate the sums for the fitting matrix element I,J
     470        // I = m
     471        // J = m + jm
     472        for (int i = 0; i < y->n; i++) {
     473
     474            if (mask && (mask->data.U8[i] & maskValue)) continue;
     475
     476            float dy = psImageBinningGetRuffY (map->binning, y->data.F32[i]) - (m + 0.5);
     477
     478            bool edgeY = false;
     479            edgeY |= ((m == 1) && (dy < -1.0));
     480            edgeY |= ((m == Ny - 2) && (dy > +1.0));
     481
     482            // skip points outside of 2x2 grid centered on n,m:
     483            if (!edgeY && (fabs(dy) > 1.0)) continue;
     484
     485            // related offset values
     486            float ry = 1.0 - dy;
     487            float py = 1.0 + dy;
     488            float qy = -dy;
     489
     490            // data value & weight for this point
     491            float fi = f->data.F32[i];
     492            float wt = 1.0;
     493            if (df != NULL) {
     494                if (df->data.F32[i] == 0.0) {
     495                    wt = 0.0;
     496                } else {
     497                    wt = 1.0 / PS_SQR(df->data.F32[i]); // XXX test for dz == NULL or dz_i = 0
     498                }
     499            }
     500
     501            // sum the appropriate elements for the different quadrants
     502            int Qy = (dy >= 0) ? 1 : 0;
     503            if (m ==      0) Qy = 1;
     504            if (m == Ny - 1) Qy = 0;
     505
     506            assert (isfinite(fi));
     507            assert (isfinite(wt));
     508            assert (isfinite(ry));
     509
     510            // points at offset 1,1
     511            if (Qy == 1) {
     512                ry_ry += ry*ry*wt;
     513                dy_ry += dy*ry*wt;
     514                fi_ry += fi*ry*wt;
     515            }
     516            // points at offset 1,0
     517            if (Qy == 0) {
     518                py_py += py*py*wt;
     519                qy_py += qy*py*wt;
     520                fi_py += fi*py*wt;
     521            }
     522        }
     523
     524        // the chi-square derivatives have elements of the form g(n+jn,m+jm)*A(jn,jm),
     525        // jn,jm = -1 to +1. Convert the sums above into the correct coefficients
     526        sA[-1] = qy_py;
     527        sA[ 0] = ry_ry + py_py;
     528        sA[+1] = dy_ry;
     529
     530        // I[ 0][ 0] = index for this n,m element:
     531        I = m;
     532        B->data.F32[I] = fi_ry + fi_py;
     533
     534        // insert these values into their corresponding locations in A, B
     535        for (int jm = -1; jm <= +1; jm++) {
     536            if (m + jm <   0) continue;
     537            if (m + jm >= Ny) continue;
     538            J = (m + jm);
     539            A->data.F32[J][I] = sA[jm];
     540        }
     541    }
     542
     543    // test for empty diagonal elements (unconstained cells), mark, and set pivots to 1.0
     544    psVector *Empty = psVectorAlloc (Ny, PS_TYPE_S8);
     545    psVectorInit (Empty, 0);
     546    for (int i = 0; i < Ny; i++) {
     547        if (A->data.F32[i][i] == 0.0) {
     548            Empty->data.S8[i] = 1;
     549            for (int j = 0; j < Ny; j++) {
     550                A->data.F32[i][j] = 0.0;
     551                A->data.F32[j][i] = 0.0;
     552            }
     553            A->data.F32[i][i] = 1.0;
     554            B->data.F32[i] = 0.0;
     555        }
     556    }
     557
     558    if (!psMatrixGJSolveF32(A, B)) {
     559        psAbort ("failed on linear equations");
     560        psError(PS_ERR_UNKNOWN, false, "Could not solve linear equations.  Returning NULL.\n");
     561        psFree (A);
     562        psFree (B);
     563        return false;
     564    }
     565
     566    // set bad values to NaN
     567    for (int i = 0; i < Ny; i++) {
     568        if (Empty->data.S8[i]) {
     569            B->data.F32[i] = NAN;
     570        }
     571    }
     572
     573    for (int m = 0; m < Ny; m++) {
     574        map->map->data.F32[m][0] = B->data.F32[m];
     575        map->error->data.F32[m][0] = sqrt(A->data.F32[m][m]);
     576    }
     577
     578    psFree (A);
     579    psFree (B);
     580    psFree (Empty);
     581
     582    return true;
     583}
     584
     585// map defines the output image dimensions and scaling.
     586bool psImageMapFit1DinX (psImageMap *map, psVector *mask, psMaskType maskValue, psVector *x, psVector *y, psVector *f, psVector *df) {
     587
     588    int I, J;
     589
     590    // XXX Add Asserts
     591    assert (map->binning->nXruff == 1);
     592
     593    // dimensions of the output map image
     594    int Nx = map->binning->nXruff;
     595
     596    // set up the redirection table so we can use sA[-1][-1], etc
     597    float SAv[3], *sA;
     598
     599    sA = SAv + 1;
     600
     601    // elements of the matrix equation Ax = B; we are solving for the vector x
     602    psImage *A = psImageAlloc (Nx, Nx, PS_TYPE_F32);
     603    psVector *B = psVectorAlloc (Nx, PS_TYPE_F32);
     604
     605    psImageInit (A, 0.0);
     606    psVectorInit (B, 0.0);
     607
     608    for (int m = 0; m < Nx; m++) {
     609        // define & init summing variables
     610        float rx_rx = 0;
     611        float dx_rx = 0;
     612        float fi_rx = 0;
     613        float px_px = 0;
     614        float qx_px = 0;
     615        float fi_px = 0;
     616
     617        // generate the sums for the fitting matrix element I,J
     618        // I = m
     619        // J = m + jm
     620        for (int i = 0; i < x->n; i++) {
     621
     622            if (mask && (mask->data.U8[i] & maskValue)) continue;
     623
     624            float dx = psImageBinningGetRuffX (map->binning, x->data.F32[i]) - (m + 0.5);
     625
     626            bool edgeX = false;
     627            edgeX |= ((m == 1) && (dx < -1.0));
     628            edgeX |= ((m == Nx - 2) && (dx > +1.0));
     629
     630            // skip points outside of 2x2 grid centered on n,m:
     631            if (!edgeX && (fabs(dx) > 1.0)) continue;
     632
     633            // related offset values
     634            float rx = 1.0 - dx;
     635            float px = 1.0 + dx;
     636            float qx = -dx;
     637
     638            // data value & weight for this point
     639            float fi = f->data.F32[i];
     640            float wt = 1.0;
     641            if (df != NULL) {
     642                if (df->data.F32[i] == 0.0) {
     643                    wt = 0.0;
     644                } else {
     645                    wt = 1.0 / PS_SQR(df->data.F32[i]); // XXX test for dz == NULL or dz_i = 0
     646                }
     647            }
     648
     649            // sum the appropriate elements for the different quadrants
     650            int Qx = (dx >= 0) ? 1 : 0;
     651            if (m ==      0) Qx = 1;
     652            if (m == Nx - 1) Qx = 0;
     653
     654            assert (isfinite(fi));
     655            assert (isfinite(wt));
     656            assert (isfinite(rx));
     657
     658            // points at offset 1,1
     659            if (Qx == 1) {
     660                rx_rx += rx*rx*wt;
     661                dx_rx += dx*rx*wt;
     662                fi_rx += fi*rx*wt;
     663            }
     664            // points at offset 1,0
     665            if (Qx == 0) {
     666                px_px += px*px*wt;
     667                qx_px += qx*px*wt;
     668                fi_px += fi*px*wt;
     669            }
     670        }
     671
     672        // the chi-square derivatives have elements of the form g(n+jn,m+jm)*A(jn,jm),
     673        // jn,jm = -1 to +1. Convert the sums above into the correct coefficients
     674        sA[-1] = qx_px;
     675        sA[ 0] = rx_rx + px_px;
     676        sA[+1] = dx_rx;
     677
     678        // I[ 0][ 0] = index for this n,m element:
     679        I = m;
     680        B->data.F32[I] = fi_rx + fi_px;
     681
     682        // insert these values into their corresponding locations in A, B
     683        for (int jm = -1; jm <= +1; jm++) {
     684            if (m + jm <   0) continue;
     685            if (m + jm >= Nx) continue;
     686            J = (m + jm);
     687            A->data.F32[J][I] = sA[jm];
     688        }
     689    }
     690
     691    // test for empty diagonal elements (unconstained cells), mark, and set pivots to 1.0
     692    psVector *Empty = psVectorAlloc (Nx, PS_TYPE_S8);
     693    psVectorInit (Empty, 0);
     694    for (int i = 0; i < Nx; i++) {
     695        if (A->data.F32[i][i] == 0.0) {
     696            Empty->data.S8[i] = 1;
     697            for (int j = 0; j < Nx; j++) {
     698                A->data.F32[i][j] = 0.0;
     699                A->data.F32[j][i] = 0.0;
     700            }
     701            A->data.F32[i][i] = 1.0;
     702            B->data.F32[i] = 0.0;
     703        }
     704    }
     705
     706    if (!psMatrixGJSolveF32(A, B)) {
     707        psAbort ("failed on linear equations");
     708        psError(PS_ERR_UNKNOWN, false, "Could not solve linear equations.  Returning NULL.\n");
     709        psFree (A);
     710        psFree (B);
     711        return false;
     712    }
     713
     714    // set bad values to NaN
     715    for (int i = 0; i < Nx; i++) {
     716        if (Empty->data.S8[i]) {
     717            B->data.F32[i] = NAN;
     718        }
     719    }
     720
     721    for (int m = 0; m < Nx; m++) {
     722        map->map->data.F32[0][m] = B->data.F32[I];
     723        map->error->data.F32[0][m] = sqrt(A->data.F32[I][I]);
     724    }
     725
     726    psFree (A);
     727    psFree (B);
     728    psFree (Empty);
     729
     730    return true;
     731}
     732
Note: See TracChangeset for help on using the changeset viewer.