Changeset 26899
- Timestamp:
- Feb 10, 2010, 7:42:02 PM (16 years ago)
- Location:
- trunk/ppSub
- Files:
-
- 12 edited
- 2 copied
-
doc (copied) (copied from branches/eam_branches/20091201/ppSub/doc )
-
doc/outline.txt (copied) (copied from branches/eam_branches/20091201/ppSub/doc/outline.txt )
-
src/ppSub.c (modified) (1 diff)
-
src/ppSub.h (modified) (2 diffs)
-
src/ppSubBackground.c (modified) (1 diff)
-
src/ppSubCamera.c (modified) (10 diffs)
-
src/ppSubDefineOutput.c (modified) (2 diffs)
-
src/ppSubFiles.c (modified) (1 diff)
-
src/ppSubLoop.c (modified) (3 diffs)
-
src/ppSubMakePSF.c (modified) (4 diffs)
-
src/ppSubMatchPSFs.c (modified) (8 diffs)
-
src/ppSubReadoutJpeg.c (modified) (1 diff)
-
src/ppSubReadoutPhotometry.c (modified) (7 diffs)
-
src/ppSubThreshold.c (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ppSub/src/ppSub.c
r25847 r26899 24 24 int main(int argc, char *argv[]) 25 25 { 26 27 # if 0 28 psLibInit(NULL); 29 pmVisualSetVisual(true); 30 for (int order = 2; order < 11; order ++) { 31 pmSubtractionDeconvolutionTest (order); 32 } 33 psLibFinalize(); 34 exit (1); 35 # endif 36 26 37 psExit exitValue = PS_EXIT_SUCCESS; // Exit value 27 38 psTimerStart("ppSub"); -
trunk/ppSub/src/ppSub.h
r24862 r26899 152 152 ); 153 153 154 /// Generate JPEG images 155 bool ppSubResidualSampleJpeg(pmConfig *config); 156 154 157 /// Generate inverse subtraction 155 158 bool ppSubReadoutInverse(pmConfig *config // Configuration … … 160 163 bool psMetadataCopySingle(psMetadata *target, psMetadata *source, const char *name); 161 164 165 bool ppSubCopyPSF (pmFPAfile *output, pmFPAfile *input, pmFPAview *view); 166 162 167 ///@} 163 168 #endif -
trunk/ppSub/src/ppSubBackground.c
r23740 r26899 42 42 if (!modelRO) { 43 43 // Create the background model 44 if (!psphotModelBackground (config, view, "PPSUB.OUTPUT")) {44 if (!psphotModelBackgroundReadoutFileIndex(config, view, "PPSUB.OUTPUT", 0)) { 45 45 psError(PS_ERR_UNKNOWN, false, "Unable to model background"); 46 46 psFree(view); -
trunk/ppSub/src/ppSubCamera.c
r26571 r26899 23 23 24 24 // Define an input file 25 static pmFPAfile *defineInputFile(pmConfig *config,// Configuration 25 static pmFPAfile *defineInputFile(bool *success, 26 pmConfig *config,// Configuration 26 27 pmFPAfile *bind, // File to which to bind, or NULL 27 28 char *filerule, // Name of file rule … … 32 33 bool status; 33 34 35 *success = false; 36 34 37 pmFPAfile *file = NULL; 38 35 39 // look for the file on the argument list 36 40 if (bind) { … … 39 43 file = pmFPAfileDefineFromArgs(&status, config, filerule, argname); 40 44 } 45 41 46 if (!status) { 42 47 psError(PS_ERR_UNKNOWN, false, "Failed to load file definition for %s", filerule); … … 53 58 54 59 if (!file) { 60 // no file defined 61 *success = true; 55 62 return NULL; 56 63 } … … 61 68 } 62 69 70 *success = true; 63 71 return file; 64 72 } … … 137 145 bool ppSubCamera(ppSubData *data) 138 146 { 147 bool success = true; 148 139 149 psAssert(data, "Require processing data"); 140 150 pmConfig *config = data->config; … … 142 152 143 153 // Input image 144 pmFPAfile *input = defineInputFile( config, NULL, "PPSUB.INPUT", "INPUT", PM_FPA_FILE_IMAGE);145 if (! input) {154 pmFPAfile *input = defineInputFile(&success, config, NULL, "PPSUB.INPUT", "INPUT", PM_FPA_FILE_IMAGE); 155 if (!success) { 146 156 psError(PS_ERR_IO, false, "Failed to build FPA from PPSUB.INPUT"); 147 157 return false; 148 158 } 149 defineInputFile(config, input, "PPSUB.INPUT.MASK", "INPUT.MASK", PM_FPA_FILE_MASK); 150 pmFPAfile *inVar = defineInputFile(config, input, "PPSUB.INPUT.VARIANCE", "INPUT.VARIANCE", 151 PM_FPA_FILE_VARIANCE); 152 defineInputFile(config, NULL, "PPSUB.INPUT.SOURCES", "INPUT.SOURCES", PM_FPA_FILE_CMF); 159 160 defineInputFile(&success, config, input, "PPSUB.INPUT.MASK", "INPUT.MASK", PM_FPA_FILE_MASK); 161 if (!success) { 162 psError(PS_ERR_IO, false, "Failed to build FPA from PPSUB.INPUT.MASK"); 163 return false; 164 } 165 166 pmFPAfile *inVar = defineInputFile(&success, config, input, "PPSUB.INPUT.VARIANCE", "INPUT.VARIANCE", PM_FPA_FILE_VARIANCE); 167 if (!success) { 168 psError(PS_ERR_IO, false, "Failed to build FPA from PPSUB.INPUT.VARIANCE"); 169 return false; 170 } 171 172 defineInputFile(&success, config, NULL, "PPSUB.INPUT.SOURCES", "INPUT.SOURCES", PM_FPA_FILE_CMF); 173 if (!success) { 174 psError(PS_ERR_IO, false, "Failed to build FPA from PPSUB.INPUT.SOURCES"); 175 return false; 176 } 153 177 154 178 // Reference image 155 pmFPAfile *ref = defineInputFile( config, NULL, "PPSUB.REF", "REF", PM_FPA_FILE_IMAGE);156 if (! ref) {179 pmFPAfile *ref = defineInputFile(&success, config, NULL, "PPSUB.REF", "REF", PM_FPA_FILE_IMAGE); 180 if (!success) { 157 181 psError(PS_ERR_IO, false, "Failed to build FPA from PPSUB.REF"); 158 182 return false; 159 183 } 160 defineInputFile(config, ref, "PPSUB.REF.MASK", "REF.MASK", PM_FPA_FILE_MASK); 161 pmFPAfile *refVar = defineInputFile(config, ref, "PPSUB.REF.VARIANCE", "REF.VARIANCE", 162 PM_FPA_FILE_VARIANCE); 163 defineInputFile(config, NULL, "PPSUB.REF.SOURCES", "REF.SOURCES", PM_FPA_FILE_CMF); 164 184 185 defineInputFile(&success, config, ref, "PPSUB.REF.MASK", "REF.MASK", PM_FPA_FILE_MASK); 186 if (!success) { 187 psError(PS_ERR_IO, false, "Failed to build FPA from PPSUB.REF.MASK"); 188 return false; 189 } 190 191 pmFPAfile *refVar = defineInputFile(&success, config, ref, "PPSUB.REF.VARIANCE", "REF.VARIANCE", PM_FPA_FILE_VARIANCE); 192 if (!success) { 193 psError(PS_ERR_IO, false, "Failed to build FPA from PPSUB.REF.VARIANCE"); 194 return false; 195 } 196 197 defineInputFile(&success, config, NULL, "PPSUB.REF.SOURCES", "REF.SOURCES", PM_FPA_FILE_CMF); 198 if (!success) { 199 psError(PS_ERR_IO, false, "Failed to build FPA from PPSUB.REF.SOURCES"); 200 return false; 201 } 165 202 166 203 // Now that the camera has been determined, we can read the recipe … … 298 335 jpeg2->save = true; 299 336 337 // Output residual JPEG 338 pmFPAfile *jpeg3 = pmFPAfileDefineOutput(config, NULL, "PPSUB.OUTPUT.RESID.JPEG"); 339 if (!jpeg3) { 340 psError(PS_ERR_IO, false, _("Unable to generate output file from PPSUB.OUTPUT.RESID.JPEG")); 341 return false; 342 } 343 if (jpeg3->type != PM_FPA_FILE_JPEG) { 344 psError(PS_ERR_IO, true, "PPSUB.OUTPUT.RESID.JPEG is not of type JPEG"); 345 return false; 346 } 347 jpeg3->save = true; 348 300 349 // Output subtraction kernel 301 350 pmFPAfile *kernel = defineCalcFile(config, NULL, "PPSUB.OUTPUT.KERNELS", PM_FPA_FILE_SUBKERNEL); … … 306 355 307 356 // psPhot input 308 if (data->photometry ) {357 if (data->photometry || 1) { 309 358 psphotModelClassInit(); // load implementation-specific models 310 359 … … 318 367 return false; 319 368 } 369 // specify the number of psphot input images 370 psMetadataAddS32 (config->arguments, PS_LIST_TAIL, "PSPHOT.INPUT.NUM", PS_META_REPLACE, "number of inputs", 1); 320 371 pmFPAfileActivate(config->files, false, "PSPHOT.INPUT"); 321 372 322 // Internal -ishfile for getting the PSF from the minuend323 pmFPAfile *psf = pmFPAfileDefine OutputFromFile(config, psphot, "PSPHOT.PSF.LOAD");373 // Internal file for getting the PSF from the minuend 374 pmFPAfile *psf = pmFPAfileDefineFromFPA(config, output->fpa, 1, 1, "PSPHOT.PSF.LOAD"); 324 375 if (!psf) { 325 376 psError(PS_ERR_IO, false, "Failed to build FPA from PSPHOT.PSF.LOAD"); -
trunk/ppSub/src/ppSubDefineOutput.c
r23740 r26899 51 51 bool mdok; // Status of MD lookup 52 52 psMetadata *analysis = inConv->analysis; // Analysis metadata with kernel information 53 pmSubtractionKernels *kernels = psMetadataLookupPtr(&mdok, analysis, 54 PM_SUBTRACTION_ANALYSIS_KERNEL); // Subtraction kernel 53 pmHDU *hdu = pmHDUFromCell(inConv->parent); 54 pmSubtractionKernels *kernels = psMetadataLookupPtr(&mdok, analysis, PM_SUBTRACTION_ANALYSIS_KERNEL); // Subtraction kernel 55 55 56 if (!kernels) { 57 hdu = pmHDUFromCell(refConv->parent); 56 58 analysis = refConv->analysis; 57 59 kernels = psMetadataLookupPtr(&mdok, analysis, PM_SUBTRACTION_ANALYSIS_KERNEL); … … 62 64 return false; 63 65 } 64 psMetadataAddStr(outHDU->header, PS_LIST_TAIL, "PPSUB.KERNEL", 0, "Subtraction kernel", 65 kernels->description); 66 psAssert (hdu, "unable to find HDU"); 67 psMetadataAddStr(outHDU->header, PS_LIST_TAIL, "PPSUB.KERNEL", 0, "Subtraction kernel", kernels->description); 68 outHDU->header = psMetadataCopy(outHDU->header, hdu->header); 66 69 67 70 // Add additional data to the header -
trunk/ppSub/src/ppSubFiles.c
r23740 r26899 23 23 // Subtraction files 24 24 static const char *subFiles[] = { "PPSUB.OUTPUT", "PPSUB.OUTPUT.MASK", "PPSUB.OUTPUT.VARIANCE", 25 "PPSUB.OUTPUT.JPEG1", "PPSUB.OUTPUT.JPEG2", 25 "PPSUB.OUTPUT.JPEG1", "PPSUB.OUTPUT.JPEG2", "PPSUB.OUTPUT.RESID.JPEG", 26 26 NULL }; 27 27 -
trunk/ppSub/src/ppSubLoop.c
r24862 r26899 27 27 28 28 pmConfigCamerasCull(config, NULL); 29 pmConfigRecipesCull(config, "PPSUB,PPSTATS,PSPHOT, MASKS,JPEG");29 pmConfigRecipesCull(config, "PPSUB,PPSTATS,PSPHOT,PSASTRO,MASKS,JPEG"); 30 30 31 31 … … 54 54 // Can't do anything at all 55 55 return true; 56 } 57 // generate the residual stamp grid for visualization 58 if (!ppSubResidualSampleJpeg(config)) { 59 psError(PS_ERR_UNKNOWN, false, "Unable to update."); 60 return false; 56 61 } 57 62 … … 130 135 } 131 136 137 // generate the binned image used to write the jpeg 132 138 if (!ppSubReadoutJpeg(config)) { 133 139 psError(PS_ERR_UNKNOWN, false, "Unable to update."); -
trunk/ppSub/src/ppSubMakePSF.c
r26263 r26899 22 22 #include "ppSub.h" 23 23 24 psArray *ppSubSelectPSFSources(psArray *sources); 25 24 26 bool ppSubMakePSF(ppSubData *data) 25 27 { … … 61 63 return false; 62 64 } 65 63 66 pmReadout *photRO = pmFPAviewThisReadout(view, photFile->fpa); // Readout to photometer 64 if (psMetadataLookup(photRO->analysis, "PSPHOT.SOURCES")) { 65 psMetadataRemoveKey(photRO->analysis, "PSPHOT.SOURCES"); 66 } 67 68 // psphotSaveImage (photFile->fpa->hdu->header, photRO->image, "findpsf.im.fits"); 69 // psphotSaveImage (photFile->fpa->hdu->header, photRO->variance, "findpsf.wt.fits"); 70 // psphotSaveImage (photFile->fpa->hdu->header, photRO->mask, "findpsf.mk.fits"); 71 72 // XXX for testing, can i dump a complete copy of the psphot sources here? 73 // I actually only need the X,Y coordinates to test this. 67 68 // we need to remove any existing PSPHOT.DETECTIONS (why not do this in psphot?) 69 if (psMetadataLookup(photRO->analysis, "PSPHOT.DETECTIONS")) { 70 psMetadataRemoveKey(photRO->analysis, "PSPHOT.DETECTIONS"); 71 } 72 if (psMetadataLookup(photRO->parent->parent->analysis, "PSPHOT.PSF")) { 73 psMetadataRemoveKey(photRO->parent->parent->analysis, "PSPHOT.PSF"); 74 } 75 76 # ifdef TESTING 77 // XXX for testing, dump these images: 78 psphotSaveImage (NULL, photRO->image, "findpsf.im.fits"); 79 psphotSaveImage (NULL, photRO->variance, "findpsf.wt.fits"); 80 psphotSaveImage (NULL, photRO->mask, "findpsf.mk.fits"); 81 # endif 74 82 75 83 // Extract the loaded sources from the associated readout, and generate PSF 76 84 // Here, we assume the image is background-subtracted 77 psArray *sources = psMetadataLookupPtr(&mdok, minuend->analysis, "PSPHOT.SOURCES"); 78 if (!psphotReadoutFindPSF(config, view, sources)) { 85 pmDetections *detections = psMetadataLookupPtr(&mdok, minuend->analysis, "PSPHOT.DETECTIONS"); 86 psAssert(detections, "missing detections?"); 87 psArray *sources = detections->allSources; 88 psAssert(sources, "missing sources?"); 89 90 // XXX filter sources? limit the total number and return only brighter objects? 91 // use flags to toss totally bogus entries? 92 psArray *goodSources = ppSubSelectPSFSources (sources); 93 if (!psphotReadoutFindPSF(config, view, goodSources)) { 79 94 // This is likely a data quality issue 80 95 // XXX Split into multiple cases using error codes? … … 83 98 ppSubDataQuality(data, PSPHOT_ERR_PSF, PPSUB_FILES_PHOT_SUB | PPSUB_FILES_PHOT_INV); 84 99 psFree(view); 100 psFree(goodSources); 85 101 return true; 102 } 103 104 // save the resulting PSF information on the pmFPAfile PSPHOT.PSF.LOAD 105 pmFPAfile *psfFile = psMetadataLookupPtr(&mdok, config->files, "PSPHOT.PSF.LOAD"); // PSF file 106 if (!ppSubCopyPSF (psfFile, photFile, view)) { 107 psErrorStackPrint(stderr, "PSF was not generated"); 108 psWarning("PSF was not generated --- suspect bad data quality."); 109 ppSubDataQuality(data, psErrorCodeLast(), PPSUB_FILES_PHOT_SUB | PPSUB_FILES_PHOT_INV); 86 110 } 87 111 … … 89 113 psMetadataRemoveKey(photRO->analysis, "PSPHOT.HEADER"); 90 114 91 if (!data->quality) { 92 data->psf = psMemIncrRefCounter(psMetadataLookupPtr(NULL, photRO->parent->parent->analysis, 93 "PSPHOT.PSF")); 94 } 95 115 psFree(goodSources); 96 116 psFree(view); 97 117 98 118 return true; 99 119 } 120 121 bool ppSubCopyPSF (pmFPAfile *output, pmFPAfile *input, pmFPAview *view) { 122 123 bool mdok = false; 124 125 pmChip *inputChip = pmFPAviewThisChip(view, input->fpa); // Chip with PSF info 126 pmChip *outputChip = pmFPAviewThisChip(view, output->fpa); // Chip to store PSF info 127 128 pmReadout *inputRO = pmFPAviewThisReadout(view, input->fpa); // Readout with PSF info 129 pmReadout *outputRO = pmFPAviewThisReadout(view, output->fpa); // Readout to store PSF info 130 131 if (!outputRO) { 132 pmCell *outputCell = pmFPAviewThisCell(view, output->fpa); 133 outputRO = pmReadoutAlloc(outputCell); 134 outputRO->image = psMemIncrRefCounter (inputRO->image); 135 } 136 137 // copy the PSF-related data to PSPHOT.PSF.LOAD for safe-keeping 138 psMetadata *psfRegions = psMetadataAlloc(); 139 140 int nRegions = psMetadataLookupS32 (&mdok, inputRO->analysis, "PSF.CLUMP.NREGIONS"); 141 if (!nRegions) { 142 psErrorStackPrint(stderr, "No PSF available"); 143 return false; 144 } 145 psMetadataAddS32 (psfRegions, PS_LIST_TAIL, "PSF.CLUMP.NREGIONS", PS_META_REPLACE, "psf clump regions", nRegions); 146 147 for (int i = 0; i < nRegions; i++) { 148 char fieldName[80]; 149 snprintf (fieldName, 80, "PSF.CLUMP.REGION.%03d", i); 150 psMetadata *regionMD = psMetadataLookupPtr (&mdok, inputRO->analysis, fieldName); 151 if (!regionMD) { 152 psWarning ("missing psf clump region metadata for entry %d", i); 153 continue; 154 } 155 psMetadataAddMetadata (psfRegions, PS_LIST_TAIL, fieldName, PS_META_REPLACE, "psf clump region", regionMD); 156 } 157 158 // XXX why am I replacing the entire analysis MD? 159 psFree(outputRO->analysis); 160 outputRO->analysis = psfRegions; 161 162 // copy the PSF model data 163 pmPSF *psf = psMetadataLookupPtr(NULL, inputChip->analysis, "PSPHOT.PSF"); // PSF for photometry 164 if (!psf) { 165 psErrorStackPrint(stderr, "No PSF available"); 166 return false; 167 } 168 169 psMetadataAddPtr(outputChip->analysis, PS_LIST_TAIL, "PSPHOT.PSF", PS_DATA_UNKNOWN | PS_META_REPLACE, "PSF from ppSubMakePSF", psf); 170 171 return true; 172 } 173 174 175 // XXX hardwired MAX for now 176 # define MAX_NPSF 500 177 178 psArray *ppSubSelectPSFSources(psArray *sources){ 179 180 sources = psArraySort (sources, pmSourceSortBySN); 181 182 psArray *subset = psArrayAllocEmpty(MAX_NPSF); 183 184 int nPSF = 0; 185 for (int i = 0; (nPSF < MAX_NPSF) && (i < sources->n); i++) { 186 187 pmSource *source = sources->data[i]; 188 if (!source) continue; 189 190 // skip non-astronomical objects (very likely defects) 191 if (source->type == PM_SOURCE_TYPE_DEFECT) continue; 192 if (source->type == PM_SOURCE_TYPE_SATURATED) continue; 193 if (source->mode & PM_SOURCE_MODE_SATSTAR) continue; 194 195 psArrayAdd (subset, 100, source); 196 nPSF++; 197 } 198 199 return subset; 200 } -
trunk/ppSub/src/ppSubMatchPSFs.c
r26036 r26899 18 18 #include <pslib.h> 19 19 #include <psmodules.h> 20 #include <psphot.h> 20 21 21 22 #include "ppSub.h" 23 24 #define COVAR_FRAC 0.01 // Truncation fraction for covariance matrix 22 25 23 26 // Normalise a region on an image … … 37 40 } 38 41 42 // Measure the PSF for an image 43 static float subImagePSF(ppSubData *data, // Processing data 44 const pmReadout *ro, // Readout for which to measure PSF 45 psArray *sources // Sources with positions at which to measure PSF 46 ) 47 { 48 psAssert(data, "Require processing data"); 49 pmConfig *config = data->config; // Configuration 50 psAssert(config, "Require configuration"); 51 52 psAssert(ro, "Need readout"); 53 psAssert(sources, "Need sources."); 54 55 pmFPAfile *photFile = psMetadataLookupPtr(NULL, config->files, "PSPHOT.INPUT"); // Photometry file 56 psAssert(photFile, "Need photometry file."); 57 if (!pmFPACopy(photFile->fpa, ro->parent->parent->parent)) { 58 psError(PS_ERR_UNKNOWN, false, "Unable to copy FPA for photometry"); 59 return false; 60 } 61 62 pmFPAview *view = ppSubViewReadout(); // View to readout 63 pmReadout *photRO = pmFPAviewThisReadout(view, photFile->fpa); // Readout to photometer 64 65 if (psMetadataLookup(photRO->analysis, "PSPHOT.DETECTIONS")) { 66 psMetadataRemoveKey(photRO->analysis, "PSPHOT.DETECTIONS"); 67 } 68 if (psMetadataLookup(photRO->parent->parent->analysis, "PSPHOT.PSF")) { 69 psMetadataRemoveKey(photRO->parent->parent->analysis, "PSPHOT.PSF"); 70 } 71 72 // Extract the loaded sources from the associated readout, and generate PSF 73 // Here, we assume the image is background-subtracted 74 if (!psphotReadoutFindPSF(config, view, sources)) { 75 psErrorStackPrint(stderr, "Unable to determine PSF"); 76 psWarning("Unable to determine PSF."); 77 psFree(view); 78 return true; 79 } 80 81 psFree(view); 82 83 psMetadata *header = psMetadataLookupMetadata(NULL, photRO->analysis, "PSPHOT.HEADER"); 84 psAssert(header, "Require header."); 85 float fwhm = psMetadataLookupF32(NULL, header, "FWHM_MAJ"); 86 87 return fwhm; 88 } 89 90 // Scale the kernel parameters according to the PSFs 91 static bool subScaleKernel(ppSubData *data, // Processing data 92 psVector *kernelWidths, // Widths for kernel 93 int *kernelSize, // Size of kernel 94 int *stampSize // Size of stamps (footprint) 95 ) 96 { 97 psAssert(data, "Require processing data"); 98 pmConfig *config = data->config; // Configuration 99 psAssert(config, "Require configuration"); 100 101 // Nothing to do if pre-calculated kernel exists 102 pmFPAview *view = ppSubViewReadout(); // View to readout 103 pmReadout *kernelRO = pmFPAfileThisReadout(config->files, view, "PPSUB.OUTPUT.KERNELS"); // RO with kernel 104 if (kernelRO) { 105 psFree(view); 106 return true; 107 } 108 109 // Look up recipe values 110 psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSUB_RECIPE); // Recipe for ppSim 111 psAssert(recipe, "We checked this earlier, so it should be here."); 112 if (!psMetadataLookupBool(NULL, recipe, "SCALE")) { 113 // No scaling requested 114 psFree(view); 115 return true; 116 } 117 118 // Input images 119 pmReadout *inRO = pmFPAfileThisReadout(config->files, view, "PPSUB.INPUT"); // Input readout 120 pmReadout *refRO = pmFPAfileThisReadout(config->files, view, "PPSUB.REF"); // Reference readout 121 122 // Input sources 123 pmReadout *inSourceRO = pmFPAfileThisReadout(config->files, view, "PPSUB.INPUT.SOURCES"); 124 pmReadout *refSourceRO = pmFPAfileThisReadout(config->files, view, "PPSUB.REF.SOURCES"); 125 // XXX assert on inSourcesRO and refSourcesRO? 126 127 pmDetections *inDetections = psMetadataLookupPtr(NULL, inSourceRO->analysis, "PSPHOT.DETECTIONS"); // Input sources 128 pmDetections *refDetections = psMetadataLookupPtr(NULL, refSourceRO->analysis, "PSPHOT.DETECTIONS"); // Ref sources 129 130 psFree(view); 131 132 if (!inDetections || !refDetections) { 133 psWarning("Unable to scale kernel, since no sources were provided."); 134 return true; 135 } 136 137 psArray *inSources = inDetections->allSources; 138 psAssert (inSources, "missing inSources?"); 139 140 psArray *refSources = refDetections->allSources; 141 psAssert (refSources, "missing refSources?"); 142 143 float inFWHM = subImagePSF(data, inRO, inSources); // FWHM for input 144 float refFWHM = subImagePSF(data, refRO, refSources); // FWHM for reference 145 146 psLogMsg("ppSub", PS_LOG_INFO, "Input FWHM: %f\nReference FWHM: %f\n", inFWHM, refFWHM); 147 if (!isfinite(inFWHM) || !isfinite(refFWHM)) { 148 psWarning("Unable to scale kernel, since unable to measure PSFs."); 149 return true; 150 } 151 152 float scaleRef = psMetadataLookupF32(NULL, recipe, "SCALE.REF"); // Reference for scaling 153 float scaleMin = psMetadataLookupF32(NULL, recipe, "SCALE.MIN"); // Minimum for scaling 154 float scaleMax = psMetadataLookupF32(NULL, recipe, "SCALE.MAX"); // Maximum for scaling 155 if (!isfinite(scaleRef) || !isfinite(scaleMin) || !isfinite(scaleMax)) { 156 psError(PPSUB_ERR_ARGUMENTS, false, 157 "Scale parameters (SCALE.REF=%f, SCALE.MIN=%f, SCALE.MAX=%f) not set in recipe.", 158 scaleRef, scaleMin, scaleMax); 159 return false; 160 } 161 162 if (!pmSubtractionParamsScale(kernelSize, stampSize, kernelWidths, inFWHM, refFWHM, 163 scaleRef, scaleMin, scaleMax)) { 164 psError(PS_ERR_UNKNOWN, false, "Unable to scale parameters."); 165 return false; 166 } 167 168 return true; 169 } 170 39 171 40 172 bool ppSubMatchPSFs(ppSubData *data) … … 71 203 pmReadout *kernelRO = pmFPAfileThisReadout(config->files, view, "PPSUB.OUTPUT.KERNELS"); // RO with kernel 72 204 73 psFree(view);74 75 205 // Sources in image, used for stamps: these must be loaded from previous analysis stages 76 206 pmReadout *inSourceRO = pmFPAfileThisReadout(config->files, view, "PPSUB.INPUT.SOURCES"); 77 207 pmReadout *refSourceRO = pmFPAfileThisReadout(config->files, view, "PPSUB.REF.SOURCES"); 78 psArray *inSources = inSourceRO ? psMetadataLookupPtr(&mdok, inSourceRO->analysis, "PSPHOT.SOURCES") : 79 NULL; // Source list from input image 80 psArray *refSources = refSourceRO ? psMetadataLookupPtr(&mdok, refSourceRO->analysis, "PSPHOT.SOURCES") : 81 NULL ; // Source list from reference image 82 83 psArray *sources = NULL; // Merged list of sources 84 if (inSources && refSources) { 208 209 pmDetections *inDetections = inSourceRO ? psMetadataLookupPtr(&mdok, inSourceRO->analysis, "PSPHOT.DETECTIONS") : NULL; // Input sources 210 pmDetections *refDetections = refSourceRO ? psMetadataLookupPtr(&mdok, refSourceRO->analysis, "PSPHOT.DETECTIONS") : NULL; // Ref sources 211 212 psFree(view); 213 214 pmDetections *detections = NULL; // Merged detection set 215 if (inDetections && refDetections) { 216 psArray *inSources = inDetections->allSources; 217 psArray *refSources = refDetections->allSources; 218 219 psAssert (inSources, "missing in sources?"); 220 psAssert (refSources, "missing ref sources?"); 221 222 detections = pmDetectionsAlloc(); 85 223 float radius = psMetadataLookupF32(NULL, recipe, "SOURCE.RADIUS"); // Matching radius 86 224 psArray *lists = psArrayAlloc(2); // Source lists 87 225 lists->data[0] = psMemIncrRefCounter(inSources); 88 226 lists->data[1] = psMemIncrRefCounter(refSources); 89 sources = pmSourceMatchMerge(lists, radius);227 detections->allSources = pmSourceMatchMerge(lists, radius); 90 228 psFree(lists); 91 if (! sources) {229 if (!detections->allSources) { 92 230 psError(PS_ERR_UNKNOWN, false, "Unable to merge source lists"); 231 psFree(detections); 93 232 return false; 94 233 } 95 } else if (inSources) {96 sources = psMemIncrRefCounter(inSources);97 } else if (refSources) {98 sources = psMemIncrRefCounter(refSources);99 }100 101 psMetadataAddArray(inConv->analysis, PS_LIST_TAIL, "PSPHOT.SOURCES", PS_META_REPLACE,102 "Merged source list", sources); 103 psMetadataAdd Array(refConv->analysis, PS_LIST_TAIL, "PSPHOT.SOURCES", PS_META_REPLACE,104 "Merged source list", sources);105 psFree( sources); // Drop reference234 } 235 if (!detections && inDetections) { 236 detections = psMemIncrRefCounter(inDetections); 237 } 238 if (!detections && refDetections) { 239 detections = psMemIncrRefCounter(refDetections); 240 } 241 242 psMetadataAddPtr(inConv->analysis, PS_LIST_TAIL, "PSPHOT.DETECTIONS", PS_META_REPLACE | PS_DATA_UNKNOWN, "Merged source list", detections); 243 psMetadataAddPtr(refConv->analysis, PS_LIST_TAIL, "PSPHOT.DETECTIONS", PS_META_REPLACE | PS_DATA_UNKNOWN, "Merged source list", detections); 244 psFree(detections); // Drop reference 106 245 107 246 int footprint = psMetadataLookupS32(NULL, recipe, "STAMP.FOOTPRINT"); // Stamp half-size … … 131 270 float rej = psMetadataLookupF32(NULL, recipe, "REJ"); // Rejection threshold 132 271 float kernelErr = psMetadataLookupF32(NULL, recipe, "KERNEL.ERR"); // Relative systematic error in kernel 272 float normFrac = psMetadataLookupF32(NULL, recipe, "NORM.FRAC"); // Fraction of window for normalisn windw 133 273 float sysErr = psMetadataLookupF32(NULL, recipe, "SYS.ERR"); // Relative systematic error in images 274 float skyErr = psMetadataLookupF32(NULL, recipe, "SKY.ERR"); // Additional error in sky 275 float covarFrac = psMetadataLookupF32(NULL, recipe, "COVAR.FRAC"); // Fraction for covariance calculation 134 276 135 277 float badFrac = psMetadataLookupF32(NULL, recipe, "BADFRAC"); // Maximum bad fraction … … 169 311 break; 170 312 default: 171 psError StackPrint(stderr, "Invalid value for -convolve");313 psError(PS_ERR_BAD_PARAMETER_VALUE, false, "Invalid value for -convolve"); 172 314 return false; 173 315 } 316 } 317 318 if (!subScaleKernel(data, widths, &size, &footprint)) { 319 psError(PS_ERR_UNKNOWN, false, "Unable to scale kernel parameters"); 320 return false; 174 321 } 175 322 … … 177 324 if (threads > 0) { 178 325 pmSubtractionThreadsInit(inRO, refRO); 326 } 327 328 if (inRO->covariance) { 329 psImageCovarianceTruncate(inRO->covariance, COVAR_FRAC); 330 } 331 if (refRO->covariance) { 332 psImageCovarianceTruncate(refRO->covariance, COVAR_FRAC); 179 333 } 180 334 … … 183 337 if (kernelRO) { 184 338 success = pmSubtractionMatchPrecalc(inConv, refConv, inRO, refRO, kernelRO->analysis, 185 stride, kernelErr, maskVal, maskBad, maskPoor, poorFrac, badFrac); 339 stride, kernelErr, covarFrac, maskVal, maskBad, maskPoor, 340 poorFrac, badFrac); 186 341 } else { 187 342 success = pmSubtractionMatch(inConv, refConv, inRO, refRO, footprint, stride, regionSize, 188 spacing, threshold, sources, data->stamps, type, size, order,343 spacing, threshold, detections->allSources, data->stamps, type, size, order, 189 344 widths, orders, inner, ringsOrder, binning, penalty, optimum, 190 optWidths, optOrder, optThresh, iter, rej, sysErr, kernelErr, maskVal, 191 maskBad, maskPoor, poorFrac, badFrac, subMode); 192 } 345 optWidths, optOrder, optThresh, iter, rej, normFrac, 346 sysErr, skyErr, kernelErr, covarFrac, maskVal, maskBad, maskPoor, 347 poorFrac, badFrac, subMode); 348 } 349 350 # ifdef TESTING 351 // XXX for testing 352 psphotSaveImage (NULL, refRO->image, "refRO.im.fits"); 353 psphotSaveImage (NULL, refRO->variance, "refRO.wt.fits"); 354 psphotSaveImage (NULL, refRO->mask, "refRO.mk.fits"); 355 356 psphotSaveImage (NULL, inRO->image, "inRO.im.fits"); 357 psphotSaveImage (NULL, inRO->variance, "inRO.wt.fits"); 358 psphotSaveImage (NULL, inRO->mask, "inRO.mk.fits"); 359 360 psphotSaveImage (NULL, inConv->image, "inConv.im.fits"); 361 psphotSaveImage (NULL, inConv->variance, "inConv.wt.fits"); 362 psphotSaveImage (NULL, inConv->mask, "inConv.mk.fits"); 363 364 psphotSaveImage (NULL, refConv->image, "refConv.im.fits"); 365 psphotSaveImage (NULL, refConv->variance, "refConv.wt.fits"); 366 psphotSaveImage (NULL, refConv->mask, "refConv.mk.fits"); 367 # endif 193 368 194 369 psFree(optWidths); … … 261 436 pmConceptsCopyFPA(refConv->parent->parent->parent, refRO->parent->parent->parent, true, true); 262 437 438 if (inConv->covariance) { 439 psImageCovarianceTruncate(inConv->covariance, COVAR_FRAC); 440 } 441 if (refConv->covariance) { 442 psImageCovarianceTruncate(refConv->covariance, COVAR_FRAC); 443 } 444 263 445 if (inConv->variance) { 264 446 psImageCovarianceTransfer(inConv->variance, inConv->covariance); -
trunk/ppSub/src/ppSubReadoutJpeg.c
r23740 r26899 49 49 return true; 50 50 } 51 52 bool ppSubResidualSampleJpeg(pmConfig *config) 53 { 54 return true; 55 56 pmFPAview *view = ppSubViewReadout(); // View to readout 57 58 // we save sample difference stamps on the convolved image readout->analysis metadata 59 pmReadout *inConv = pmFPAfileThisReadout(config->files, view, "PPSUB.INPUT.CONV"); // Input convolved 60 61 psArray *samples = psArrayAllocEmpty(16); // Array of sample stamp images 62 63 // we may have multiple entries with the same name; pull them off into a separate array: 64 psString regex = NULL; // Regular expression 65 psStringAppend(®ex, "^%s$", "SUBTRACTION.SAMPLE.STAMP.SET"); 66 psMetadataIterator *iter = psMetadataIteratorAlloc(inConv->analysis, PS_LIST_HEAD, regex); // Iterator 67 psFree(regex); 68 69 psMetadataItem *item = NULL;// Item from iteration 70 while ((item = psMetadataGetAndIncrement(iter))) { 71 assert(item->type == PS_DATA_ARRAY); 72 psArray *sampleStamps = item->data.V; 73 samples = psArrayAdd(samples, 16, sampleStamps); 74 } 75 psFree(iter); 76 psAssert (samples, "no sample stamps?"); 77 psAssert (samples->n, "no sample stamps?"); 78 79 // get the kernel sizes 80 psArray *kernels = samples->data[0]; 81 psAssert (kernels, "no valid kernel?"); 82 psAssert (kernels->n, "no valid kernel?"); 83 84 psImage *kernel = kernels->data[0]; 85 psAssert (kernel, "missing valid kernel?"); 86 87 int DX = kernel->numCols; 88 int DY = kernel->numRows; 89 90 // each array contains up to 9 sample stamps. generate an image mosaicking these together in 3x3 blocks. 91 int innerBorder = 1; 92 int outerBorder = 2; 93 int NXblock = sqrt(samples->n); 94 int NYblock = samples->n / NXblock; 95 if (samples->n % NXblock) NYblock ++; 96 97 int NXpix = NXblock * (3 * (DX + innerBorder) + outerBorder); 98 int NYpix = NYblock * (3 * (DY + innerBorder) + outerBorder); 99 100 // output cell 101 pmCell *cell = pmFPAfileThisCell(config->files, view, "PPSUB.OUTPUT.RESID.JPEG"); 102 pmReadout *readout = pmReadoutAlloc(cell); 103 readout->image = psImageAlloc(NXpix, NYpix, PS_TYPE_F32); 104 105 cell->data_exists = true; 106 cell->parent->data_exists = true; 107 108 psImageInit (readout->image, 0.0); 109 110 for (int i = 0; i < samples->n; i++) { 111 112 int xBlock = i % NXblock; 113 int yBlock = i / NYblock; 114 115 psArray *kernels = samples->data[i]; 116 117 for (int j = 0; j < kernels->n; j++) { 118 119 psImage *kernel = kernels->data[j]; 120 121 int xSub = j % 3; 122 int ySub = j / 3; 123 124 int xPix = xBlock * (3 * (DX + innerBorder) + outerBorder) + xSub * (DX + innerBorder); 125 int yPix = yBlock * (3 * (DX + innerBorder) + outerBorder) + ySub * (DY + innerBorder); 126 127 for (int y = 0; y < kernel->numRows; y++) { 128 for (int x = 0; x < kernel->numCols; x++) { 129 readout->image->data.F32[y + yPix][x + xPix] = kernel->data.F32[y][x]; 130 } 131 } 132 } 133 } 134 135 { 136 psFits *fits = psFitsOpen ("resid.stamps.fits", "w"); 137 psFitsWriteImage (fits, NULL, readout->image, 0, NULL); 138 psFitsClose (fits); 139 } 140 141 return true; 142 } -
trunk/ppSub/src/ppSubReadoutPhotometry.c
r26264 r26899 24 24 bool ppSubReadoutPhotometry(const char *name, ppSubData *data) 25 25 { 26 bool mdok = false; 27 26 28 psAssert(data, "Require processing data"); 27 29 pmConfig *config = data->config; // Configuration … … 42 44 } 43 45 44 // The PSF (measured in ppSubMakePSF) is stored on the chip->analysis of PSPHOT.INPUT 45 // In order to use an incoming PSF, it must be stored on the chip->analysis of PSPHOT.PSF.LOAD 46 // select the view of interest 46 47 pmFPAview *view = ppSubViewReadout(); // View to readout 47 pmChip *psfInputChip = pmFPAfileThisChip(config->files, view, "PSPHOT.INPUT"); // Chip with PSF48 psAssert (psfInputChip, "should have been generated for ppSubMakePSF");49 pmChip *psfLoadChip = pmFPAfileThisChip(config->files, view, "PSPHOT.PSF.LOAD"); // Chip to have PSF50 psAssert (psfLoadChip, "PSPHOT.PSF.LOAD should have been defined in ppSubCamera");51 pmPSF *psf = psMetadataLookupPtr(NULL, psfInputChip->analysis, "PSPHOT.PSF"); // PSF for photometry52 if (!psf) {53 psErrorStackPrint(stderr, "No PSF available");54 psWarning("No PSF available --- suspect bad data quality.");55 ppSubDataQuality(data, psErrorCodeLast(), PPSUB_FILES_PHOT_SUB | PPSUB_FILES_PHOT_INV);56 return true;57 }58 psMetadataAddPtr(psfLoadChip->analysis, PS_LIST_TAIL, "PSPHOT.PSF", PS_DATA_UNKNOWN | PS_META_REPLACE,59 "PSF from ppSubMakePSF", psf);60 61 bool mdok = false;62 48 63 49 // psphotReadoutMinimal performs the photometry analysis on PSPHOT.INPUT; we need to move 64 // around the pointers so PSPHOT.INPUT corresponds to the output image; previously, it was 65 // equivalent to the minuend image. 66 pmReadout *inRO = pmFPAfileThisReadout(config->files, view, name); // Readout with image and sources 67 if (psMetadataLookup(inRO->analysis, "PSPHOT.SOURCES")) { 68 psMetadataRemoveKey(inRO->analysis, "PSPHOT.SOURCES"); 69 } 70 50 // around the pointers so PSPHOT.INPUT corresponds to the output image of interest (on one 51 // pass this is the subtraction image, in another it is negative of the subtraction 71 52 pmFPAfile *photFile = psMetadataLookupPtr(&mdok, config->files, "PSPHOT.INPUT"); // Photometry file 72 53 pmFPAfile *inFile = psMetadataLookupPtr(&mdok, config->files, name); // Input file … … 76 57 return false; 77 58 } 59 60 // drop references to PSPHOT.DETECTIONS on both of these (why is this needed for both??) 78 61 pmReadout *photRO = pmFPAviewThisReadout(view, photFile->fpa); // Readout to photometer 79 if (psMetadataLookup(photRO->analysis, "PSPHOT.SOURCES")) { 80 psMetadataRemoveKey(photRO->analysis, "PSPHOT.SOURCES"); 62 if (psMetadataLookup(photRO->analysis, "PSPHOT.DETECTIONS")) { 63 psMetadataRemoveKey(photRO->analysis, "PSPHOT.DETECTIONS"); 64 } 65 pmReadout *inRO = pmFPAfileThisReadout(config->files, view, name); // Readout with image and sources 66 if (psMetadataLookup(inRO->analysis, "PSPHOT.DETECTIONS")) { 67 psMetadataRemoveKey(inRO->analysis, "PSPHOT.DETECTIONS"); 81 68 } 82 69 83 psMetadataAddPtr(photRO->parent->parent->analysis, PS_LIST_TAIL, "PSPHOT.PSF", 84 PS_META_REPLACE | PS_DATA_UNKNOWN, "Point-spread function", data->psf); 85 86 psFree(photRO->analysis); 87 photRO->analysis = psMetadataAlloc(); 70 // grab the PSF information from the pmFPAfile PSPHOT.PSF.LOAD 71 pmFPAfile *psfFile = psMetadataLookupPtr(&mdok, config->files, "PSPHOT.PSF.LOAD"); // PSF file 72 ppSubCopyPSF (photFile, psfFile, view); 88 73 89 74 // psphotSaveImage (photFile->fpa->hdu->header, photRO->image, "findsrc.im.fits"); 90 75 // psphotSaveImage (photFile->fpa->hdu->header, photRO->variance, "findsrc.wt.fits"); 91 76 // psphotSaveImage (photFile->fpa->hdu->header, photRO->mask, "findsrc.mk.fits"); 77 78 // erase the overlays from a previous psphot-related step 79 if (pmVisualIsVisual()) { 80 // psphotVisualEraseOverlays (1, "all"); 81 } 92 82 93 83 if (!psphotReadoutMinimal(config, view)) { … … 100 90 101 91 // If no sources were found, there's no error, but we want to trigger 'bad quality' 102 p sArray *sources = psMetadataLookupPtr(NULL, photRO->analysis, "PSPHOT.SOURCES"); // Sources103 if (! sources) {92 pmDetections *detections = psMetadataLookupPtr(NULL, photRO->analysis, "PSPHOT.DETECTIONS"); // Sources 93 if (!detections) { 104 94 ppSubDataQuality(data, PSPHOT_ERR_DATA, PPSUB_FILES_PHOT_SUB | PPSUB_FILES_PHOT_INV); 105 95 } 96 psArray *sources = detections->allSources; 97 psAssert (sources, "missing sources?"); 106 98 107 99 if (data->stats) { … … 118 110 119 111 if (!data->quality) { 120 if (!psMetadataCopySingle(inRO->analysis, photRO->analysis, "PSPHOT. SOURCES")) {121 psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to copy PSPHOT. SOURCES");112 if (!psMetadataCopySingle(inRO->analysis, photRO->analysis, "PSPHOT.DETECTIONS")) { 113 psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to copy PSPHOT.DETECTIONS"); 122 114 return false; 123 115 } … … 125 117 psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to copy PSPHOT.HEADER"); 126 118 return false; 119 } 120 if (!psMetadataCopySingle(inRO->analysis, photRO->analysis, PM_DETEFF_ANALYSIS)) { 121 psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to copy Detection Efficiency"); 122 return false; 123 } 124 125 // Ensure photometry information is put in the header 126 pmHDU *hdu = pmHDUFromReadout(inRO); // HDU for readout 127 if (hdu) { 128 psMetadata *photHeader = psMetadataLookupMetadata(NULL, inRO->analysis, "PSPHOT.HEADER"); // Header 129 hdu->header = psMetadataCopy(hdu->header, photHeader); 127 130 } 128 131 } … … 134 137 } 135 138 136 137 138 139 140 139 #ifdef TESTING 141 140 // Record data about sources: not everything gets into the output CMF files 142 141 { 143 142 pmReadout *photRO = pmFPAviewThisReadout(view, photFile->fpa); // Readout with the sources 144 psArray *sources = psMetadataLookupPtr(NULL, photRO->analysis, "PSPHOT.SOURCES"); // Sources 143 pmDetections *detections = psMetadataLookupPtr(NULL, photRO->analysis, "PSPHOT.DETECTIONS"); // Sources 144 psArray *sources = detections->allSources; 145 145 FILE *sourceFile = fopen("sources.dat", "w"); // File for sources 146 146 fprintf(sourceFile, -
trunk/ppSub/src/ppSubThreshold.c
r24862 r26899 27 27 psImageMaskType maskIgnore, // Ignore pixels with this mask 28 28 psImageMaskType maskThresh, // Give pixels this mask if below threshold 29 psRegion *region, // Region of interest 29 30 const char *description // Description of image 30 31 ) … … 37 38 psImage *image = ro->image; // Image 38 39 psImage *mask = ro->mask; // Mask 39 int numCols = ro->image->numCols, numRows = ro->image->numRows; // Size of image 40 41 psImage *subImage = psImageSubset(image, *region); // Image with region of interest 42 psImage *subMask = psImageSubset(mask, *region); // Maks with region of interest 40 43 41 44 psStats *stats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); // Statistics 42 45 psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS); // Random number generator 43 if (!psImageBackground(stats, NULL, image, mask, maskIgnore, rng)) {46 if (!psImageBackground(stats, NULL, subImage, subMask, maskIgnore, rng)) { 44 47 psError(PS_ERR_UNKNOWN, false, "Unable to determine threshold."); 45 48 psFree(rng); … … 49 52 psFree(rng); 50 53 54 psFree(subImage); 55 psFree(subMask); 56 51 57 float threshold = stats->robustMedian - thresh * stats->robustStdev; // Threshold below which to clip 52 58 psFree(stats); 53 59 psLogMsg("ppSub", PS_LOG_INFO, "Masking pixels below %f in %s", threshold, description); 54 60 55 for (int y = 0; y < numRows; y++) {56 for (int x = 0; x < numCols; x++) {61 for (int y = region->y0; y < region->y1; y++) { 62 for (int x = region->x0; x < region->x1; x++) { 57 63 if (mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & maskIgnore) { 58 64 continue; … … 94 100 return false; 95 101 } 96 if (!lowThreshold(in, thresh, maskVal, maskThresh, "input convolved image")) {97 psError(PS_ERR_UNKNOWN, false, "Unable to threshold input image.");98 return false;99 }100 102 101 103 pmReadout *ref = pmFPAfileThisReadout(config->files, view, "PPSUB.REF.CONV"); // Reference image … … 104 106 return false; 105 107 } 106 if (!lowThreshold(ref, thresh, maskVal, maskThresh, "reference convolved image")) { 107 psError(PS_ERR_UNKNOWN, false, "Unable to threshold input image."); 108 return false; 108 109 psMetadataIterator *regIter = psMetadataIteratorAlloc(in->analysis, PS_LIST_HEAD, 110 "^" PM_SUBTRACTION_ANALYSIS_REGION "$"); 111 psMetadataItem *regItem; // Item with region 112 while ((regItem = psMetadataGetAndIncrement(regIter))) { 113 psAssert(regItem->type == PS_DATA_REGION && regItem->data.V, "Expect region type"); 114 psRegion *region = regItem->data.V; // Region of interest 115 if (!lowThreshold(in, thresh, maskVal, maskThresh, region, "input convolved image")) { 116 psError(PS_ERR_UNKNOWN, false, "Unable to threshold input image."); 117 return false; 118 } 119 if (!lowThreshold(ref, thresh, maskVal, maskThresh, region, "reference convolved image")) { 120 psError(PS_ERR_UNKNOWN, false, "Unable to threshold input image."); 121 return false; 122 } 109 123 } 124 psFree(regIter); 110 125 111 126 psFree(view);
Note:
See TracChangeset
for help on using the changeset viewer.
