IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Apr 17, 2006, 8:10:08 AM (20 years ago)
Author:
magnier
Message:

fixed up conflicts

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/imcombine/pmReadoutCombine.c

    r6511 r6873  
    55 *  @author GLG, MHPCC
    66 *
    7  *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
    8  *  @date $Date: 2006-03-04 01:01:33 $
     7 *  @version $Revision: 1.7 $ $Name: not supported by cvs2svn $
     8 *  @date $Date: 2006-04-17 18:10:08 $
    99 *
    1010 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    3636}
    3737
     38static void pmCombineParamsFree (pmCombineParams *params)
     39{
     40
     41    if (params == NULL)
     42        return;
     43
     44    psFree (params->stats);
     45    return;
     46}
     47
     48pmCombineParams *pmCombineParamsAlloc (psStatsOptions statsOptions)
     49{
     50
     51    pmCombineParams *params = psAlloc (sizeof(pmCombineParams));
     52    psMemSetDeallocator(params, (psFreeFunc) pmCombineParamsFree);
     53
     54    params->stats = psStatsAlloc (statsOptions);
     55    params->maskVal = 0;
     56    params->fracHigh = 0.25;
     57    params->fracHigh = 0.25;
     58    params->nKeep = 3;
     59
     60    return (params);
     61}
     62
    3863/******************************************************************************
    3964XXX: Must add support for S16 and S32 types.  F32 currently supported.
    4065 *****************************************************************************/
    4166psImage *pmReadoutCombine(psImage *output,
    42                           const psList *inputs,
    43                           psCombineParams *params,
     67                          const psArray *inputs,
    4468                          const psVector *zero,
    4569                          const psVector *scale,
     70                          pmCombineParams *params,
    4671                          bool applyZeroScale,
    4772                          psF32 gain,
    4873                          psF32 readnoise)
     74{
     75    PS_ASSERT_PTR_NON_NULL(inputs, NULL);
     76    PS_ASSERT_PTR_NON_NULL(params, NULL);
     77    PS_ASSERT_PTR_NON_NULL(params->stats, NULL);
     78    if (zero != NULL) {
     79        PS_ASSERT_VECTOR_TYPE(zero, PS_TYPE_F32, NULL);
     80        //        PS_ASSERT_VECTOR_TYPE_S16_S32_F32(zero, NULL);
     81    }
     82    if (scale != NULL) {
     83        PS_ASSERT_VECTOR_TYPE(scale, PS_TYPE_F32, NULL);
     84        //        PS_ASSERT_VECTOR_TYPE_S16_S32_F32(scale, NULL);
     85    }
     86    if ((zero != NULL) && (scale != NULL)) {
     87        PS_ASSERT_VECTOR_TYPE_EQUAL(zero, scale, NULL);
     88        // PS_ASSERT_VECTOR_TYPE_S16_S32_F32(scale, NULL);
     89    }
     90
     91    psStats *stats = params->stats;
     92    psS32 maxInputCols = 0;
     93    psS32 maxInputRows = 0;
     94    psS32 minInputCols = PS_MAX_S32;
     95    psS32 minInputRows = PS_MAX_S32;
     96    pmReadout *tmpReadout = NULL;
     97    psS32 tmpI;
     98    psElemType outputType = PS_TYPE_F32;
     99
     100    if (DetermineNumBits(stats->options) != 1) {
     101        psError(PS_ERR_UNKNOWN, true,
     102                "Multiple statistical options have been requested.  Returning NULL.\n");
     103        return(NULL);
     104    }
     105
     106    // We step through each readout in the input image list.  If any readout is
     107    // NULL, empty, or has the wrong type, we generate an error and return
     108    // NULL.  We determine how big of an output image is needed to combine
     109    // these input images.  We do this by taking the
     110    //     max(readout->col0 + readout->numCols + image->col0 + image->numCols)
     111    //     max(readout->row0 + readout->numRows + image->row0 + image->numRows)
     112    //
     113    for (int i = 0; i < inputs->n; i++) {
     114        tmpReadout = inputs->data[i];
     115        PS_ASSERT_READOUT_NON_NULL(tmpReadout, output);
     116        PS_ASSERT_READOUT_NON_EMPTY(tmpReadout, output);
     117        PS_ASSERT_READOUT_TYPE(tmpReadout, PS_TYPE_F32, output);
     118
     119        minInputRows = PS_MIN(minInputRows, (tmpReadout->row0 + tmpReadout->image->row0));
     120        tmpI = tmpReadout->row0 +
     121               tmpReadout->image->row0 +
     122               tmpReadout->image->numRows;
     123        maxInputRows = PS_MAX(maxInputRows, tmpI);
     124
     125        minInputCols = PS_MIN(minInputCols, (tmpReadout->col0 + tmpReadout->image->col0));
     126        tmpI = tmpReadout->col0 +
     127               tmpReadout->image->col0 +
     128               tmpReadout->image->numCols;
     129        maxInputCols = PS_MAX(maxInputCols, tmpI);
     130    }
     131
     132    // We ensure that the zero vector is of the proper size.
     133    if (zero != NULL) {
     134        PS_ASSERT_VECTOR_TYPE(zero, PS_TYPE_F32, NULL);
     135        if (zero->n < inputs->n) {
     136            psError(PS_ERR_UNKNOWN, true, "zero vector has incorrect size (%d).  Returning NULL.\n", zero->n);
     137            return(NULL);
     138        } else if (zero->n > inputs->n) {
     139            // XXX EAM : abort on this condition? is probably an error
     140            psLogMsg(__func__, PS_LOG_WARN,
     141                     "WARNING: the zero vector too many elements (%d)\n", zero->n);
     142        }
     143    }
     144
     145    // We ensure that the scale vector is of the proper size.
     146    if (scale != NULL) {
     147        PS_ASSERT_VECTOR_TYPE(scale, PS_TYPE_F32, NULL);
     148        if (scale->n < inputs->n) {
     149            psError(PS_ERR_UNKNOWN, true, "scale vector has incorrect size (%d).  Returning NULL.\n", scale->n);
     150            return(NULL);
     151        } else if (scale->n > inputs->n) {
     152            // XXX EAM : abort on this condition? is probably an error
     153            psLogMsg(__func__, PS_LOG_WARN,
     154                     "WARNING: the scale vector has too many elements (%d)\n", scale->n);
     155        }
     156    }
     157
     158    // At this point, the following variables have been computed:
     159    // maxInputRows: the largest input row value, in output image space.
     160    // maxInputCols: the largest input column value, in output image space.
     161    // minInputRows: the smallest input row value, in output image space.
     162    // minInputCols: the smallest input column value, in output image space.
     163    //
     164    if (output == NULL) {
     165        output = psImageAlloc(maxInputCols-minInputCols, maxInputRows-minInputRows, outputType);
     166        *(psS32 *) &(output->col0) = minInputCols;
     167        *(psS32 *) &(output->row0) = minInputRows;
     168    } else {
     169
     170        // XXX EAM : recycle the existing output image?  why would we care about the existing pixels?
     171        PS_ASSERT_IMAGE_TYPE(output, PS_TYPE_F32, NULL);
     172        if (((output->col0 + output->numCols) < maxInputCols) ||
     173                ((output->row0 + output->numRows) < maxInputRows)) {
     174            psError(PS_ERR_UNKNOWN, true,
     175                    "Output image (%d, %d) is too small to hold combined images.  Returning NULL.\n",
     176                    output->row0 + output->numRows,
     177                    output->col0 + output->numCols);
     178            return(NULL);
     179        }
     180
     181        // reset output origin using logic of above
     182        *(psS32 *) &(output->col0) = minInputCols;
     183        *(psS32 *) &(output->row0) = minInputRows;
     184    }
     185
     186    psVector *tmpPixels     = psVectorAlloc(inputs->n, PS_TYPE_F32);
     187    psVector *tmpPixelsKeep = psVectorAlloc(inputs->n, PS_TYPE_F32);
     188    psVector *outRowLower   = psVectorAlloc(inputs->n, PS_TYPE_U32);
     189    psVector *outRowUpper   = psVectorAlloc(inputs->n, PS_TYPE_U32);
     190    psVector *outColLower   = psVectorAlloc(inputs->n, PS_TYPE_U32);
     191    psVector *outColUpper   = psVectorAlloc(inputs->n, PS_TYPE_U32);
     192
     193    // For each input readout, we store the min/max pixel indices for that readout, in detector coordinates,
     194    // in the psVectors (outRowLower, outColLower, outRowUpper, outColUpper).
     195    for (int i = 0; i < inputs->n; i++) {
     196        tmpReadout = (pmReadout *) inputs->data[i];
     197        outRowLower->data.U32[i] = tmpReadout->row0 + tmpReadout->image->row0;
     198        outColLower->data.U32[i] = tmpReadout->col0 + tmpReadout->image->col0;
     199        outRowUpper->data.U32[i] = tmpReadout->row0 +
     200                                   tmpReadout->image->row0 +
     201                                   tmpReadout->image->numRows;
     202        outColUpper->data.U32[i] = tmpReadout->col0 +
     203                                   tmpReadout->image->col0 +
     204                                   tmpReadout->image->numCols;
     205    }
     206
     207    // We loop through each pixel in the output image.  We loop through each
     208    // input readout.  We determine if that output pixel is contained in the
     209    // image from that readout.  If so, we save it in psVector tmpPixels.
     210    // If not, we set a mask for that element in tmpPixels.  Then, we mask off
     211    // pixels not between fracLow and fracHigh.  Then we call the vector
     212    // stats routine on those pixels/mask.  Then we set the output pixel value
     213    // to the result of the stats call.
     214
     215    int nx, ny;
     216    int nKeep, nMin;
     217    float keepFrac = 1.0 - params->fracLow - params->fracHigh;
     218    float value = 0;
     219    psF32 *saveVector = tmpPixelsKeep->data.F32;
     220
     221    for (int j = output->row0; j < (output->row0 + output->numRows) ; j++) {
     222        if (j % 10 == 0)
     223            fprintf (stderr, ".");
     224        for (int i = output->col0; i < (output->col0 + output->numCols) ; i++) {
     225            int nPix = 0;
     226            for (int r = 0; r < inputs->n; r++) {
     227                tmpReadout = (pmReadout *) inputs->data[r];
     228
     229                // psTrace (__func__, 6, "[%d][%d]: [%d][%d] to [%d][%d]\n", i, j, outColLower->data.U32[r], outRowLower->data.U32[r], outColUpper->data.U32[r], outRowUpper->data.U32[r]);
     230                if (i <  outColLower->data.U32[r])
     231                    continue;
     232                if (i >= outColUpper->data.U32[r])
     233                    continue;
     234                if (j <  outRowLower->data.U32[r])
     235                    continue;
     236                if (j >= outRowUpper->data.U32[r])
     237                    continue;
     238
     239                nx = i - (tmpReadout->col0 + tmpReadout->image->col0);
     240                ny = j - (tmpReadout->row0 + tmpReadout->image->row0);
     241
     242                if (tmpReadout->mask != NULL) {
     243                    if (tmpReadout->mask->data.U8[ny][nx] && params->maskVal)
     244                        continue;
     245                }
     246
     247                tmpPixels->data.F32[nPix] = tmpReadout->image->data.F32[ny][nx];
     248                // psTrace (__func__, 6, "readout[%d], image [%d][%d] is %f\n", r, i, j, tmpPixels->data.F32[nPix]);
     249                nPix ++;
     250            }
     251            tmpPixels->n = nPix;
     252
     253            // are there enough valid pixels to apply fracLow,fracHigh?
     254            nKeep = nPix * keepFrac;
     255            if (nKeep >= params->nKeep) {
     256                psVectorSort (tmpPixels, tmpPixels);
     257                nMin = nPix * params->fracLow;
     258                tmpPixelsKeep->data.F32 = &tmpPixels->data.F32[nMin];
     259                tmpPixelsKeep->n = nKeep;
     260            } else {
     261                tmpPixelsKeep->data.F32 = tmpPixels->data.F32;
     262                tmpPixelsKeep->n = nPix;
     263            }
     264
     265            // tmpPixelsKeep is already sorted.  sample mean and median are very easy
     266            if (stats->options & PS_STAT_SAMPLE_MEAN) {
     267                value = 0;
     268                for (int r = 0; r < tmpPixelsKeep->n; r++) {
     269                    value += tmpPixelsKeep->data.F32[r];
     270                }
     271                if (tmpPixelsKeep->n == 0) {
     272                    value = 0;
     273                } else {
     274                    value = value / tmpPixelsKeep->n;
     275                }
     276            }
     277            if (stats->options & PS_STAT_SAMPLE_MEDIAN) {
     278                int r = tmpPixelsKeep->n / 2;
     279                if (tmpPixelsKeep->n == 0) {
     280                    value = 0;
     281                    goto got_value;
     282                }
     283                if (tmpPixelsKeep->n % 2 == 1) {
     284                    int r = 0.5*tmpPixelsKeep->n;
     285                    value = tmpPixelsKeep->data.F32[r];
     286                    goto got_value;
     287                }
     288                if (tmpPixelsKeep->n % 2 == 0) {
     289                    value = 0.5*(tmpPixelsKeep->data.F32[r] +
     290                                 tmpPixelsKeep->data.F32[r-1]);
     291                    goto got_value;
     292                }
     293            }
     294got_value:
     295            output->data.F32[j-output->row0][i-output->col0] = value;
     296        }
     297    }
     298    tmpPixelsKeep->data.F32 = saveVector;
     299
     300    psFree(tmpPixels);
     301    psFree(tmpPixelsKeep);
     302    psFree(outRowLower);
     303    psFree(outRowUpper);
     304    psFree(outColLower);
     305    psFree(outColUpper);
     306
     307    return(output);
     308}
     309
     310/******************************************************************************
     311XXX: Must add support for S16 and S32 types.  F32 currently supported.
     312 *****************************************************************************/
     313psImage *pmReadoutCombine_OLD(psImage *output,
     314                              const psList *inputs,
     315                              pmCombineParams *params,
     316                              const psVector *zero,
     317                              const psVector *scale,
     318                              bool applyZeroScale,
     319                              psF32 gain,
     320                              psF32 readnoise)
    49321{
    50322    PS_ASSERT_PTR_NON_NULL(inputs, NULL);
     
    418690    psRegion minRegion;
    419691    psRegion maxRegion;
    420     psStats *minStats = psStatsAlloc(PS_STAT_FITTED_MEAN);
    421     psStats *maxStats = psStatsAlloc(PS_STAT_FITTED_MEAN);
     692    psStats *minStats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN);
     693    psStats *maxStats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN);
    422694    psStats *diffStats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN);
    423695    psVector *diffs = psVectorAlloc(fringePoints->n, PS_TYPE_F32);
     
    454726        }
    455727
    456         fp->midValue = 0.5 * (maxStats->fittedMean + minStats->fittedMean);
    457         fp->delta = maxStats->fittedMean - minStats->fittedMean;
     728        fp->midValue = 0.5 * (maxStats->robustMedian + minStats->robustMedian);
     729        fp->delta = maxStats->robustMedian - minStats->robustMedian;
    458730        diffs->data.F32[i] = fp->delta;
    459731    }
     
    464736    psFree(diffs);
    465737    if (diffStats == NULL) {
    466         psError(PS_ERR_UNKNOWN, true, "Could not determine fitted median of the differences.\n");
     738        psError(PS_ERR_UNKNOWN, true, "Could not determine robust median of the differences.\n");
    467739        return(NULL);
    468740    }
    469741    return(diffStats);
    470742}
    471 
    472 
    473743
    474744/**
Note: See TracChangeset for help on using the changeset viewer.