IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 31014


Ignore:
Timestamp:
Mar 23, 2011, 8:52:13 AM (15 years ago)
Author:
mwv
Message:

Added option so that if Nsubset < 0.1 * Npixels
standard random-number-picking of pixels will
be used instead of sorting entire array.
This was on the suggestions of Gene who pointed out
that MWV's fix for not double-counting pixels was
painfully slow when taking a small subsample of
a large number of pixels.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/ipp-20110213/psLib/src/imageops/psImageBackground.c

    r30981 r31014  
    100100        // This is not optimal, since there may be a large masked fraction that leaves us with few good pixels.
    101101        // In that case, you should have set Nsubset.......
    102         // 2011/03/16 - MWV:  Fixed double-sampling of sky pixels.
    103         //   The pick-a-random-pixel-at-a-time approach  doesn't work well when Npixels is close to Nsubset
    104         //   If Nsubset is 0.8*Npixels, then we will get lots of pixels double-counted
    105         //   This is correct on average, but isn't the optimal way to estimate the sky level
    106         // I suggest instead the following approach:
    107         //   1) Calculate a random ordering of the pixels
    108         //   2) Go through this ordering up to Nsubset to select pixels
    109         psVector *frndPixelOrder = psVectorAlloc(Npixels, PS_TYPE_F32);
    110         for (long i = 0; i < Npixels; i++) {
    111             frndPixelOrder->data.F32[i] = psRandomUniform(rng);
    112         }
    113         // Now sort the array so that we end up with a list of the pixels in random order
    114         psVector *frndSortedPixelOrder = psVectorSortIndex(NULL, frndPixelOrder);
    115         // Now loop in our new sorted order;
    116         // Note that it's the number of good samples found, "n", that will generally terminate the loop
    117         for (long i = 0; n < Nsubset && i < Npixels; i++) {
    118             int pixel = frndSortedPixelOrder->data.S32[i];
    119             int ix = pixel % nx;
    120             int iy = pixel / nx;
    121 
    122             if (bad->data.U8[iy][ix]) {
    123                 continue;
    124             }
    125 
    126             float value = image->data.F32[iy][ix];
    127             // 2011/03/16 - MWV:  Keep a running overall min and max
    128             min = PS_MIN(value, min);
    129             max = PS_MAX(value, max);
    130             values->data.F32[n] = value;
    131             n++;
     102
     103        // 2011/03/22 - MWV:  On prompting from Gene, changed the sampling so that it doesn't build and then sort
     104        //     a huge array when Nsubset << Npixel. 
     105        //   O(Npixel) log(Npixel) is unnecessarily painful when Npixel=38 million (one skycell)
     106        //     but we only needed Nsubset pixels and Nsubset << Npixel.
     107
     108        //   It also perhaps partially defeats any gain of taking only subsamples if we're sorting the array.
     109        //   I should do some performance tests on this anyway.
     110
     111        // If our chance of collision is low and the gain from not sorting the array is likely to be high,
     112        // then just pick randomnly
     113        // Note that we're guaranteeing Nsubset pixels returned here (up to the limit of Npixels)
     114        if (Nsubset < 0.1 * Npixels) {
     115            for (long i = 0; n < Nsubset && i < Npixels; i++) {
     116                float frnd = psRandomUniform(rng);
     117                int pixel = Npixels * frnd;
     118                int ix = pixel % nx;
     119                int iy = pixel / nx;
     120
     121                if (bad->data.U8[iy][ix]) {
     122                    continue;
     123                }
     124
     125                float value = image->data.F32[iy][ix];
     126                min = PS_MIN(value, min);
     127                max = PS_MAX(value, max);
     128                values->data.F32[n] = value;
     129                n++;
     130            }
     131        } else {
     132            // 2011/03/16 - MWV:  Fixed double-sampling of sky pixels.
     133            //   The pick-a-random-pixel-at-a-time approach  doesn't work well when Npixels is close to Nsubset
     134            //   If Nsubset is 0.8*Npixels, then we will get lots of pixels double-counted
     135            //   This is correct on average, but isn't the optimal way to estimate the sky level
     136            // Instead we take the following approach:
     137            //   1) Calculate a random ordering of the pixels
     138            //   2) Go through this ordering up to Nsubset to select pixels
     139            // This is O(n log(n))
     140            psVector *frndPixelOrder = psVectorAlloc(Npixels, PS_TYPE_F32);
     141            for (long i = 0; i < Npixels; i++) {
     142                frndPixelOrder->data.F32[i] = psRandomUniform(rng);
     143            }
     144            // Now sort the array so that we end up with a list of the pixels in random order
     145            psVector *frndSortedPixelOrder = psVectorSortIndex(NULL, frndPixelOrder);
     146            // Now loop in our new sorted order;
     147            // Note that it's the number of good samples found, "n", that will generally terminate the loop
     148            for (long i = 0; n < Nsubset && i < Npixels; i++) {
     149                int pixel = frndSortedPixelOrder->data.S32[i];
     150                int ix = pixel % nx;
     151                int iy = pixel / nx;
     152
     153                if (bad->data.U8[iy][ix]) {
     154                    continue;
     155                }
     156
     157                float value = image->data.F32[iy][ix];
     158                min = PS_MIN(value, min);
     159                max = PS_MAX(value, max);
     160                values->data.F32[n] = value;
     161                n++;
     162            }
    132163        }
    133164    }
Note: See TracChangeset for help on using the changeset viewer.