IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 25383 for trunk/psLib


Ignore:
Timestamp:
Sep 15, 2009, 12:45:01 PM (17 years ago)
Author:
Paul Price
Message:

Merging branches/pap (detection efficiency development) into trunk.

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/psLib/src/fits/psFits.c

    r25049 r25383  
    344344// Therefore, we implement our own version of moving to an extension specified by name.  The pure cfitsio
    345345// version is used if "conventions.compression" handling is turned off in the psFits structure.
    346 bool psFitsMoveExtName(const psFits* fits,
    347                        const char* extname)
     346static bool fitsMoveExtName(const psFits* fits, // FITS file
     347                            const char* extname, // Extension name
     348                            bool errors // Generate errors?
     349    )
    348350{
    349351    PS_ASSERT_FITS_NON_NULL(fits, false);
     
    356358        // User wants to use cfitsio.  Good luck to them!
    357359        if (fits_movnam_hdu(fits->fd, ANY_HDU, (char*)extname, 0, &status) != 0) {
    358             psFitsError(status, true, _("Could not find HDU '%s'"), extname);
     360            if (errors) {
     361                psFitsError(status, true, _("Could not find HDU '%s'"), extname);
     362            }
    359363            return false;
    360364        }
     
    378382        if (fits_movabs_hdu(fits->fd, i, &hdutype, &status)) {
    379383            // We've run off the end
    380             psFitsError(status, true, _("Could not find HDU with %s = '%s'"), extword, extname);
     384            if (errors) {
     385                psFitsError(status, true, _("Could not find HDU with %s = '%s'"), extword, extname);
     386            }
    381387            return false;
    382388        }
     
    406412    }
    407413    psAbort("Should never reach here.");
     414}
     415
     416
     417bool psFitsMoveExtName(const psFits* fits, const char* extname)
     418{
     419    return fitsMoveExtName(fits, extname, true);
     420}
     421
     422bool psFitsMoveExtNameClean(const psFits* fits, const char* extname)
     423{
     424    return fitsMoveExtName(fits, extname, false);
    408425}
    409426
  • trunk/psLib/src/fits/psFits.h

    r19035 r25383  
    245245);
    246246
     247/** Moves the FITS HDU to the specified extension name without generating errors.
     248 *
     249 *  @return bool        TRUE if the extension name was found and move was
     250 *                      successful, otherwise FALSE
     251 */
     252bool psFitsMoveExtNameClean(
     253    const psFits* fits,                ///< the psFits object to move
     254    const char* extname                ///< the extension name
     255);
     256
    247257/** Moves the FITS HDU to the specified extension number
    248258 *
  • trunk/psLib/src/imageops/psImageConvolve.c

    r24272 r25383  
    678678}
    679679
     680static bool imageSmoothMaskPixels(psVector *out, const psImage *image, const psImage *mask,
     681                                  psImageMaskType maskVal, const psVector *x, const psVector *y,
     682                                  const psVector *gaussNorm, float minGauss, int size, int start, int stop)
     683{
     684    const psF32 *gauss = &gaussNorm->data.F32[size]; // Gaussian convolution kernel
     685    int numCols = image->numCols, numRows = image->numRows; // Size of image
     686    int xLast = numCols - 1, yLast = numRows - 1; // Last index
     687    for (int i = start; i < stop; i++) {
     688        int xPix = x->data.S32[i], yPix = y->data.S32[i]; // Pixel coordinates for smoothing
     689
     690        int yMin = PS_MAX(yPix - size, 0);
     691        int yMax = PS_MIN(yPix + size, yLast);
     692        int xMin = PS_MAX(xPix - size, 0);
     693        int xMax = PS_MIN(xPix + size, xLast);
     694
     695        const float *yGauss = &gauss[yMin - yPix];
     696
     697        double ySumIG = 0.0, ySumG = 0.0;
     698        for (int v = yMin; v <= yMax; v++, yGauss++) {
     699            const float *xGauss = &gauss[xMin - xPix];
     700            double xSumIG = 0.0, xSumG = 0.0;
     701            const psImageMaskType *maskData = &mask->data.PS_TYPE_IMAGE_MASK_DATA[v][xMin];
     702            const psF32 *imageData = &image->data.F32[v][xMin];
     703            for (int u = xMin; u <= xMax; u++, xGauss++, imageData++, maskData++) {
     704                if (*maskData & maskVal) {
     705                    continue;
     706                }
     707                xSumIG += *imageData * *xGauss;
     708                xSumG += *xGauss;
     709            }
     710            if (xSumG > minGauss) {
     711                ySumIG += xSumIG * *yGauss;
     712                ySumG += xSumG * *yGauss;
     713            }
     714        }
     715
     716        out->data.F32[i] = ySumG > minGauss ? ySumIG / ySumG : NAN;
     717    }
     718
     719    return true;
     720}
     721
     722static bool psImageSmoothMaskPixelsThread(psThreadJob *job)
     723{
     724    PS_ASSERT_THREAD_JOB_NON_NULL(job, false);
     725    psAssert(job->args, "programming error: no job arguments");
     726    psAssert(job->args->n == 11, "programming error: wrong number of job arguments");
     727
     728    psVector *out = job->args->data[0]; // Output vector
     729    const psImage *image  = job->args->data[1]; // Input image
     730    const psImage *mask   = job->args->data[2]; // Input mask
     731    psImageMaskType maskVal = PS_SCALAR_VALUE(job->args->data[3], PS_TYPE_IMAGE_MASK_DATA);
     732    const psVector *x = job->args->data[4];
     733    const psVector *y = job->args->data[5];
     734    const psVector *gaussNorm = job->args->data[6];
     735    float minGauss = PS_SCALAR_VALUE(job->args->data[7], F32);
     736    int size = PS_SCALAR_VALUE(job->args->data[8], S32);
     737    int start = PS_SCALAR_VALUE(job->args->data[9], S32);
     738    int stop = PS_SCALAR_VALUE(job->args->data[10], S32);
     739    return imageSmoothMaskPixels(out, image, mask, maskVal, x, y, gaussNorm,
     740                                 minGauss, size, start, stop);
     741}
     742
     743
     744psVector *psImageSmoothMaskPixels(const psImage *image, const psImage *mask, psImageMaskType maskVal,
     745                                  const psVector *x, const psVector *y,
     746                                  float sigma, float numSigma, float minGauss)
     747{
     748    PS_ASSERT_IMAGE_NON_NULL(image, NULL);
     749    PS_ASSERT_IMAGE_NON_NULL(mask, NULL);
     750    PS_ASSERT_IMAGE_TYPE(mask, PS_TYPE_IMAGE_MASK, NULL);
     751    PS_ASSERT_IMAGES_SIZE_EQUAL(image, mask, NULL);
     752    PS_ASSERT_VECTOR_NON_NULL(x, NULL);
     753    PS_ASSERT_VECTOR_TYPE(x, PS_TYPE_S32, NULL);
     754    PS_ASSERT_VECTOR_NON_NULL(y, NULL);
     755    PS_ASSERT_VECTOR_TYPE(y, PS_TYPE_S32, NULL);
     756    PS_ASSERT_VECTORS_SIZE_EQUAL(x, y, NULL);
     757
     758    int size = sigma * numSigma + 0.5;  // Half-size of kernel
     759
     760    int num = x->n;                     // Number of pixels to smooth
     761    psVector *out = psVectorAlloc(num, PS_TYPE_F32); // Output results
     762
     763    // Generate normalized gaussian
     764    IMAGE_SMOOTH_GAUSS(gaussNorm, size, sigma, F32);
     765
     766    // Columns
     767    if (threaded) {
     768        int numThreads = psThreadPoolSize(); // Number of threads
     769        int delta = (numThreads) ? num / numThreads + 1 : num; // Block of cols to do at once
     770        for (int start = 0; start < num; start += delta) {
     771            int stop = PS_MIN(start + delta, num);  // End of block
     772
     773            psThreadJob *job = psThreadJobAlloc("PSLIB_IMAGE_SMOOTHMASK_PIXELS");
     774            psArrayAdd(job->args, 1, out);
     775            psArrayAdd(job->args, 1, (psImage*)image);
     776            psArrayAdd(job->args, 1, (psImage*)mask);
     777            PS_ARRAY_ADD_SCALAR(job->args, maskVal, PS_TYPE_IMAGE_MASK);
     778            psArrayAdd(job->args, 1, (psVector*)x);
     779            psArrayAdd(job->args, 1, (psVector*)y);
     780            psArrayAdd(job->args, 1, gaussNorm);
     781            PS_ARRAY_ADD_SCALAR(job->args, minGauss, PS_TYPE_F32);
     782            PS_ARRAY_ADD_SCALAR(job->args, size, PS_TYPE_S32);
     783            PS_ARRAY_ADD_SCALAR(job->args, start, PS_TYPE_S32);
     784            PS_ARRAY_ADD_SCALAR(job->args, stop, PS_TYPE_S32);
     785            if (!psThreadJobAddPending(job)) {
     786                psFree(job);
     787                psFree(gaussNorm);
     788                psFree(out);
     789                return NULL;
     790            }
     791            psFree(job);
     792        }
     793    } else if (!imageSmoothMaskPixels(out, image, mask, maskVal, x, y,
     794                                      gaussNorm, minGauss, size, 0, num)) {
     795        psError(PS_ERR_UNKNOWN, false, "Unable to smooth pixels.");
     796        psFree(gaussNorm);
     797        psFree(out);
     798        return NULL;
     799    }
     800
     801    if (threaded && !psThreadPoolWait(true)) {
     802        psError(PS_ERR_UNKNOWN, false, "Error waiting for threads.");
     803        psFree(gaussNorm);
     804        psFree(out);
     805        return NULL;
     806    }
     807
     808    psFree(gaussNorm);
     809    return out;
     810}
     811
     812
    680813// Smooth an image with masked pixels
    681814// The calculation and calcMask images are *deliberately* backwards (row,col instead of col,row or
     
    13251458    if (threaded) {
    13261459        int numThreads = psThreadPoolSize(); // Number of threads
    1327         int deltaRows = (numThreads) ? numRows / numThreads : numRows; // Block of rows to do at once
     1460        int deltaRows = (numThreads) ? numRows / numThreads + 1 : numRows; // Block of rows to do at once
    13281461        for (int start = 0; start < numRows; start += deltaRows) {
    1329             int stop = PS_MIN (start + deltaRows, numRows);  // end of row block
     1462            int stop = PS_MIN(start + deltaRows, numRows);  // end of row block
    13301463
    13311464            psThreadJob *job = psThreadJobAlloc("PSLIB_IMAGE_CONVOLVE_MASK");
     
    13631496    if (threaded) {
    13641497        int numThreads = psThreadPoolSize(); // Number of threads
    1365         int deltaCols = (numThreads) ? numCols / numThreads : numCols; // Block of cols to do at once
     1498        int deltaCols = (numThreads) ? numCols / numThreads + 1 : numCols; // Block of cols to do at once
    13661499        for (int start = 0; start < numCols; start += deltaCols) {
    1367             int stop = PS_MIN (start + deltaCols, numCols);  // end of col block
     1500            int stop = PS_MIN(start + deltaCols, numCols);  // end of col block
    13681501
    13691502            psThreadJob *job = psThreadJobAlloc("PSLIB_IMAGE_CONVOLVE_MASK");
     
    14861619            psFree(task);
    14871620        }
     1621        {
     1622            psThreadTask *task = psThreadTaskAlloc("PSLIB_IMAGE_SMOOTHMASK_PIXELS", 9);
     1623            task->function = &psImageSmoothMaskPixelsThread;
     1624            psThreadTaskAdd(task);
     1625            psFree(task);
     1626        }
    14881627    } else if (!set && threaded) {
    14891628        psThreadTaskRemove("PSLIB_IMAGE_CONVOLVE_MASK");
  • trunk/psLib/src/imageops/psImageConvolve.h

    r24272 r25383  
    222222    );
    223223
     224/// Smooth particular pixels on an image, allowing for masked pixels
     225///
     226/// Applies a circularly symmetric Gaussian smoothing first in x and then in y
     227/// directions with just a vector.  This process is 2N faster than 2D convolutions (in general).
     228psVector *psImageSmoothMaskPixels(
     229    const psImage *image,               ///< Input image (F32)
     230    const psImage *mask,                ///< Mask image
     231    psImageMaskType maskVal,            ///< Value to mask
     232    const psVector *x,                  ///< x coordinates
     233    const psVector *y,                  ///< y coordinates
     234    float sigma,                        ///< Width of the smoothing kernel (pixels)
     235    float numSigma,                     ///< Size of the smoothing box (sigma)
     236    float minGauss                      ///< Minimum fraction of Gaussian to accept
     237    );
    224238
    225239psImage *psImageSmoothMask_Threaded(psImage *output,
  • trunk/psLib/src/types/psMetadata.c

    r21183 r25383  
    996996    if (metadataItem->type == PS_DATA_METADATA_MULTI) {
    997997        // if multiple keys found, use the first.
    998         //        metadataItem = (psMetadataItem*)((metadataItem->data.list)->head);
    999998        metadataItem = (psMetadataItem*)(metadataItem->data.list->head->data);
    1000999        if (status) {
     
    10821081    } \
    10831082    \
    1084     /* psFree(metadataItem); currently, the lookup doesn't increment the ref count */ \
    10851083    return value; \
    10861084}
     
    11011099psMetadataLookupNumTYPE(VectorMaskType,VectorMask)
    11021100psMetadataLookupNumTYPE(ImageMaskType,ImageMask)
     1101
     1102#define psMetadataLookupPtrTYPE(TYPENAME,NAME,TYPE,VAL) \
     1103TYPENAME psMetadataLookup##NAME(bool *status, const psMetadata *md, const char *key) \
     1104{ \
     1105    PS_ASSERT_METADATA_NON_NULL(md, NULL); \
     1106    PS_ASSERT_STRING_NON_EMPTY(key, NULL); \
     1107    psMetadataItem *item = psMetadataLookup((psMetadata*)md, key); /* The item of interest */ \
     1108    if (!item) { \
     1109        if (status) { \
     1110            *status = false; \
     1111        } else { \
     1112            psError(PS_ERR_IO, true, "Couldn't find %s in the metadata.\n", key); \
     1113        } \
     1114        return NULL; \
     1115    } \
     1116    \
     1117    if (item->type == PS_DATA_METADATA_MULTI) { \
     1118        /* if multiple keys found, use the first. */ \
     1119        item = item->data.list->head->data; \
     1120    } \
     1121    if (item->type != TYPE) { \
     1122        if (status) { \
     1123            *status = false; \
     1124        } else { \
     1125            psLogMsg(__func__, PS_LOG_DETAIL, "%s isn't of type PS_DATA_META, as expected.\n", key); \
     1126        } \
     1127        return NULL; \
     1128    } \
     1129    \
     1130    if (status) { \
     1131        *status = true; \
     1132    } \
     1133    return item->data.VAL; \
     1134}
     1135
     1136psMetadataLookupPtrTYPE(psMetadata*, Metadata, PS_DATA_METADATA, md)
     1137psMetadataLookupPtrTYPE(psString, Str, PS_DATA_STRING, str)
     1138psMetadataLookupPtrTYPE(psTime*, Time, PS_DATA_TIME, V)
     1139psMetadataLookupPtrTYPE(psVector*, Vector, PS_DATA_VECTOR, V)
     1140
    11031141
    11041142psMetadataItem* psMetadataGet(const psMetadata *md,
     
    12571295}
    12581296
    1259 psMetadata *psMetadataLookupMetadata(bool *status,
    1260                                      const psMetadata *md,
    1261                                      const char *key)
    1262 {
    1263     PS_ASSERT_METADATA_NON_NULL(md,NULL);
    1264     psMetadataItem *item = psMetadataLookup((psMetadata*)md, key); // The metadata with instruments
    1265     psMetadata *value = NULL;  // The value to return
    1266     if (!item) {
    1267         // The given key isn't in the metadata
    1268         if (status) {
    1269             *status = false;
    1270         } else {
    1271             psError(PS_ERR_IO, true, "Couldn't find %s in the metadata.\n", key);
    1272         }
    1273     } else if (item->type != PS_DATA_METADATA) {
    1274         // The value at the key isn't metadata
    1275         if (status) {
    1276             *status = false;
    1277         } else {
    1278             psLogMsg(__func__, PS_LOG_DETAIL, "%s isn't of type PS_DATA_META, as expected.\n", key);
    1279         }
    1280         //        value = NULL;
    1281     } else {
    1282         // We have the requested metadata
    1283         if (status) {
    1284             *status = true;
    1285         }
    1286         value = item->data.md; // The requested metadata
    1287     }
    1288     return value;
    1289 }
    1290 
    1291 psTime *psMetadataLookupTime(bool *status,
    1292                              const psMetadata *md,
    1293                              const char *key)
    1294 {
    1295     PS_ASSERT_METADATA_NON_NULL(md,NULL);
    1296 
    1297     psMetadataItem *item = psMetadataLookup((psMetadata*)md, key);
    1298     if (!item) {
    1299         // The given key isn't in the metadata
    1300         if (status) {
    1301             *status = false;
    1302         } else {
    1303             psError(PS_ERR_IO, true, "Couldn't find %s in the metadata.\n", key);
    1304         }
    1305         return NULL;
    1306     }
    1307 
    1308     if (item->type != PS_DATA_TIME) {
    1309         // The value at the key isn't metadata
    1310         if (status) {
    1311             *status = false;
    1312         } else {
    1313             psLogMsg(__func__, PS_LOG_DETAIL, "%s isn't of type PS_DATA_TIME, as expected.\n", key);
    1314         }
    1315         return NULL;
    1316     }
    1317 
    1318     // We have the requested metadata
    1319     if (status) {
    1320         *status = true;
    1321     }
    1322 
    1323     return item->data.V;
    1324 }
    1325 
    1326 
    1327 psString psMetadataLookupStr(bool *status,
    1328                              const psMetadata *md,
    1329                              const char *key)
    1330 {
    1331     PS_ASSERT_METADATA_NON_NULL(md,NULL);
    1332 
    1333     psMetadataItem *item = psMetadataLookup((psMetadata*)md, key); // The metadata with instruments
    1334     //    char *value = NULL;   // The value to return
    1335     psString value = NULL;
    1336     if (!item) {
    1337         // The given key isn't in the metadata
    1338         if (status) {
    1339             *status = false;
    1340         } else {
    1341             psError(PS_ERR_IO, true, "Couldn't find %s in the metadata.\n", key);
    1342         }
    1343     } else if (item->type != PS_DATA_STRING) {
    1344         // The value at the key isn't of the desired type
    1345         if (status) {
    1346             *status = false;
    1347         } else {
    1348             psLogMsg(__func__, PS_LOG_DETAIL, "%s isn't of type PS_DATA_STRING, as expected.\n", key);
    1349         }
    1350         //        value = NULL;
    1351     } else {
    1352         // We have the requested metadata
    1353         if (status) {
    1354             *status = true;
    1355         }
    1356         value = item->data.V;
    1357     }
    1358     return value;
    1359 }
     1297
     1298
     1299
    13601300
    13611301psList *psMetadataKeys(psMetadata *md)
  • trunk/psLib/src/types/psMetadata.h

    r23148 r25383  
    717717PS_METADATA_LOOKUP_TYPE_DECL(Ptr, psPtr);
    718718PS_METADATA_LOOKUP_TYPE_DECL(Str, psString);
     719PS_METADATA_LOOKUP_TYPE_DECL(Vector, psVector*);
    719720PS_METADATA_LOOKUP_TYPE_DECL(Metadata, psMetadata*);
    720721PS_METADATA_LOOKUP_TYPE_DECL(Time, psTime*);
Note: See TracChangeset for help on using the changeset viewer.