Changeset 25027 for branches/pap/magic/remove/src/streaksremove.c
- Timestamp:
- Aug 7, 2009, 4:08:25 PM (17 years ago)
- Location:
- branches/pap
- Files:
-
- 4 edited
-
. (modified) (1 prop)
-
magic (modified) (1 prop)
-
magic/remove/src (modified) (1 prop)
-
magic/remove/src/streaksremove.c (modified) (24 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/pap
- Property svn:mergeinfo changed
-
branches/pap/magic
-
Property svn:ignore
set to
magic
ssa-core-cpp
Makefile
Makefile.bak
-
Property svn:ignore
set to
-
branches/pap/magic/remove/src
- Property svn:ignore
-
old new 1 isdestreaked 1 2 streaksremove 2 3 streaksreplace 3 4 streakscompare 4 5 streaksrelease 6 makefile
-
- Property svn:ignore
-
branches/pap/magic/remove/src/streaksremove.c
r23936 r25027 1 /* 2 * streaksremove 3 * 4 * Convert satellite streak detctions into masks and remove the covered pixels from the 5 * input images. 6 * Optionally swap the inputs with the outputs so that subsequent references to the original 7 * images access the destreaked versions. 8 */ 9 1 10 #include "streaksremove.h" 2 11 … … 4 13 static bool readAndCopyToOutput(streakFiles *sf, bool exciseAll); 5 14 static void exciseNonWarpedPixels(streakFiles *sfiles, double newMaskValue); 6 static bool warpedPixel(streakFiles *sfiles, PixelPos *cellCoord);15 static bool warpedPixel(streakFiles *sfiles, int x, int y); 7 16 static void excisePixel(streakFiles *sfiles, unsigned int x, unsigned int y, bool streak, double newMaskValue); 8 17 static void writeImages(streakFiles *sf, bool exciseImageCube); 9 18 static void updateAstrometry(streakFiles *sfiles); 19 static void censorSources(streakFiles *sfiles, psU32 maskStreak); 10 20 11 21 int … … 23 33 } 24 34 25 psU32 maskStreak = 0; 26 psU32 maskMask = 0; 35 // Values to set for masked pixels 36 psU32 maskStreak = 0; // for the image and weight (usually NAN, MAXINT for integer images) 37 psU32 maskMask = 0; // value looked up for MASK.STREAK 27 38 28 39 psString streaksFileName = psMetadataLookupStr(NULL, config->arguments, "STREAKS"); 29 40 41 // call Paul Sydney's code to parse the streaks file that DetectStreaks produced 30 42 Streaks *streaks = readStreaksFile(streaksFileName); 31 43 if (!streaks) { 32 psError StackPrint(stderr, "failed to read streaks file: %s", streaksFileName);44 psError(PS_ERR_UNKNOWN, "failed to read streaks file: %s", streaksFileName); 33 45 streaksExit("", PS_EXIT_PROG_ERROR); 34 46 } 35 47 36 streakFiles *sfiles = openFiles(config, true); 48 // open all of the input and output files, save their descriptions in the streakFiles struct 49 streakFiles *sfiles = openFiles(config, true, argv[0]); 37 50 setupAstrometry(sfiles); 38 51 52 // Optionally we can set pixels that are masked to NAN since they couldn't have been 53 // examined for streaks. Usually this is done by the distribution system just prior 54 // to release 39 55 bool nanForRelease = psMetadataLookupBool(&status, config->arguments, "NAN_FOR_RELEASE"); 40 56 if (nanForRelease && (sfiles->inMask == NULL)) { … … 52 68 53 69 if (checkNonWarpedPixels ) { 54 // From ICD:70 // From magic ICD: 55 71 // In the raw and detrended images, the pixels which were not 56 72 // included in any of the streak-processed warps must also be masked. … … 65 81 } 66 82 psF64 cwp_t = psTimerClear("COMPUTE_WARPED_PIXELS"); 67 p rintf("time to compute warped pixels: %f\n", cwp_t);83 psLogMsg("streaksremove", PS_LOG_INFO, "time to compute warped pixels: %f\n", cwp_t); 68 84 } 69 85 70 86 if (sfiles->stage == IPP_STAGE_RAW) { 71 // copy PHU to output files 87 // Except for raw stage, all of our (GPC1) files have one image extension. 88 // Raw files have a phu and multiple extensions, one per chip 89 // Since this is a raw file, copy it's PHU to output files 72 90 copyPHU(sfiles, true); 73 91 … … 82 100 int totalStreakPixels = 0; 83 101 84 // Iterate through each component of the input ( there is only one except for raw images)102 // Iterate through each component of the input (except for raw images there is only one) 85 103 do { 86 104 bool exciseImageCube = false; … … 110 128 psTimerStart("GET_STREAK_PIXELS"); 111 129 112 StreakPixels *pixels = streak_on_component (streaks, sfiles->astrom, 113 sfiles->inImage->numCols, sfiles->inImage->numRows); 114 115 printf("time to get streak pixels: %f\n", psTimerClear("GET_STREAK_PIXELS")); 116 130 // call Paul Sydney's code to compute the set of pixels that are covered by the detected streaks 131 StreakPixels *pixels = streak_on_component(streaks, sfiles->astrom, sfiles->inImage->numCols, 132 sfiles->inImage->numRows); 133 psLogMsg("streaksremove", PS_LOG_INFO, "time to get streak pixels: %f\n", psTimerClear("GET_STREAK_PIXELS")); 117 134 135 // if this extension contained an image, excise the streaked pixels. 136 // otherwise it contained an image cube (video cell) which is handled in the if block 118 137 if (sfiles->inImage->image) { 119 138 if (checkNonWarpedPixels) { … … 124 143 exciseNonWarpedPixels(sfiles, maskStreak); 125 144 126 p rintf("time to excise non warped pixels: %f\n", psTimerClear("EXCISE_NON_WARPED"));145 psLogMsg("streaksremove", PS_LOG_INFO, "time to excise non warped pixels: %f\n", psTimerClear("EXCISE_NON_WARPED")); 127 146 } 128 totalStreakPixels += psArrayLength(pixels); 147 148 129 149 psTimerStart("REMOVE_STREAKS"); 130 for (int i = 0; i < psArrayLength (pixels); ++i) { 131 PixelPos *pixelPos = psArrayGet (pixels, i); 132 133 if (!checkNonWarpedPixels || warpedPixel(sfiles, pixelPos)) { 134 135 excisePixel(sfiles, pixelPos->x, pixelPos->y, true, maskStreak); 136 137 } else { 138 // This pixel was not included in any warp and has thus already excised 139 // by exciseNonWarpedPixels 150 151 for (int y=0 ; y < sfiles->inImage->numRows; y++) { 152 for (int x = 0; x < sfiles->inImage->numCols; x++) { 153 if (psImageGet(pixels, x, y)) { 154 ++totalStreakPixels; 155 if (!checkNonWarpedPixels || warpedPixel(sfiles, x, y)) { 156 157 excisePixel(sfiles, x, y, true, maskStreak); 158 159 } else { 160 // This pixel was not included in any warp and has thus already excised 161 // by exciseNonWarpedPixels 162 } 163 } 140 164 } 141 165 } 142 printf("time to remove streak pixels: %f\n", psTimerClear("REMOVE_STREAKS")); 166 167 psLogMsg("streaksremove", PS_LOG_INFO, "time to remove streak pixels: %f\n", psTimerClear("REMOVE_STREAKS")); 143 168 144 169 if (nanForRelease) { 170 // set any pixels that were masked, to NAN (unless they are already NAN) 145 171 setMaskedToNAN(sfiles, maskMask, true); 146 172 } 147 173 148 174 } else { 149 // this component contains an image cube, excise it completely 175 // this component contains an image cube 176 // For now excise it completely 150 177 exciseImageCube = true; 151 178 } 152 psArrayElementsFree (pixels);153 179 psFree(pixels); 154 180 } 155 181 156 182 if (sfiles->stage == IPP_STAGE_CHIP) { 183 // as a convience to the user of the output, replace the bogus WCS transform in the 184 // chip processed files with the data calcuated by psastro at the camera stage 185 // (actually we use a linear approximation) 157 186 updateAstrometry(sfiles); 158 187 } 159 188 160 // write out the destreaked temporary images and the recovery images 189 censorSources(sfiles, maskStreak); 190 191 // write the destreaked "temporary" images and the recovery images 161 192 writeImages(sfiles, exciseImageCube); 162 193 163 printf("time to process component %d: %f\n", sfiles->extnum, psTimerClear("PROCESS_COMPONENT")); 194 195 psLogMsg("streaksremove", PS_LOG_INFO, "time to process component %d: %f\n", sfiles->extnum, psTimerClear("PROCESS_COMPONENT")); 164 196 } while (streakFilesNextExtension(sfiles)); 165 197 198 166 199 psFree(streaks); 167 200 168 printf("pixels: %ld streak pixels: %ld %4.2f%%\n", totalPixels, totalStreakPixels, 100. * totalStreakPixels / totalPixels); 201 psLogMsg("streaksremove", PS_LOG_INFO, "pixels: %ld streak pixels: %ld %4.2f%%\n", totalPixels, totalStreakPixels, 100. * totalStreakPixels / totalPixels); 202 203 // check the weight and mask files for extra extensions that might be in files 204 // (covariance matrix for example) 205 copyExtraExtensions(sfiles); 206 207 // all done close the files. This is where the files are written so it can take a long time. 169 208 170 209 psTimerStart("CLOSE_IMAGES"); 171 // close all files 210 172 211 closeImages(sfiles); 173 printf("time to close images: %f\n", psTimerClear("CLOSE_IMAGES")); 212 213 psLogMsg("streaksremove", PS_LOG_INFO, "time to close images: %f\n", psTimerClear("CLOSE_IMAGES")); 214 215 216 if (!replicateOutputs(sfiles)) { 217 psError(PS_ERR_UNKNOWN, false, "failed to replicate output files"); 218 deleteTemps(sfiles); 219 psErrorStackPrint(stderr, ""); 220 exit(PS_EXIT_UNKNOWN_ERROR); 221 } 174 222 175 223 // NOTE: from here on we can't just quit if something goes wrong. 176 224 // especially if we're working at the raw stage 177 178 if (!replicateOutputs(sfiles)) { 179 psError(PS_ERR_UNKNOWN, false, "failed to replicate output files"); 180 psErrorStackPrint(stderr, ""); 181 exit(PS_EXIT_UNKNOWN_ERROR); 182 } 225 // turn off automatic deletion of output files by streaksExit 226 setStreakFiles(NULL); 183 227 184 228 if (psMetadataLookupBool(&status, config->arguments, "REPLACE")) { 185 229 // swap the instances for the input and output 186 // Note this is a database operation. No file I/O is performed230 // Note this is a nebulous database operation. No file I/O is performed 187 231 if (!swapOutputsToInputs(sfiles)) { 188 psError(PS_ERR_UNKNOWN, false, "failed to swap files"); 189 190 // XXX: Now what? I guess swapOutputsToInputs will need to undo anything that 191 // it has done and give a detailed report of what happened 192 193 psErrorStackPrint(stderr, ""); 232 // XXX: Now what? 233 // It is up to the program that reverts failed destreak runs to insure that 234 // any input files that have been swapped are restored and that the de-streaked 235 // versions are deleted 236 237 psErrorStackPrint(stderr, "failed to swap files"); 238 239 // XXX: pick a specific error code for this failure 194 240 exit(PS_EXIT_UNKNOWN_ERROR); 195 241 } 196 197 if (psMetadataLookupBool(&status, config->arguments, "REMOVE")) { 198 // delete the temporary storage objects (which now points to the original image(s) 199 if (!deleteTemps(sfiles)) { 200 psError(PS_ERR_UNKNOWN, false, "failed to delete temporary files"); 201 // XXX: Now what? At this point the output files have been swapped, so we can't 202 // repeat the operation. 203 204 // Returning error status here is problematic. The inputs have been streak removed 205 // but they're still lying around 206 // Maybe just print an error message and 207 // let other system tools clean up 208 psErrorStackPrint(stderr, ""); 209 exit(PS_EXIT_UNKNOWN_ERROR); 210 } 211 } 212 } 242 } 243 // all done. Clean up to look for memory leaks. 213 244 214 245 psFree(sfiles); … … 218 249 streaksNebulousCleanup(); 219 250 pmConfigDone(); 220 p rintf("time to run streaksremove: %f\n", psTimerClear("STREAKSREMOVE"));251 psLogMsg("streaksremove", PS_LOG_INFO, "time to run streaksremove: %f\n", psTimerClear("STREAKSREMOVE")); 221 252 psLibFinalize(); 222 253 … … 235 266 fprintf(stderr, "\t-weight WEIGHT.fits: weight file to de-streak\n"); 236 267 fprintf(stderr, "\t-replace: replace the input images with the output\n"); 237 fprintf(stderr, "\t-remove: remove the original image after processing (requires -replace)\n");238 268 fprintf(stderr, "\t-keepnonwarped: do not exise pixels that were not part of difference processing\n"); 239 269 fprintf(stderr, "\t-transparent val: instead of setting excicsed pixel to NAN add val\n"); … … 311 341 bool gotReplace = false; 312 342 if ((argnum = psArgumentGet(argc, argv, "-replace"))) { 343 if (!nebulousImage) { 344 psError(PS_ERR_UNKNOWN, true, "replace is only supported for nebulous files"); 345 usage(); 346 } 313 347 gotReplace = true; 314 348 psArgumentRemove(argnum, &argc, argv); … … 394 428 psArgumentRemove(argnum, &argc, argv); 395 429 } 430 if ((argnum = psArgumentGet(argc, argv, "-sources"))) { 431 psArgumentRemove(argnum, &argc, argv); 432 bool nebulousSources = IN_NEBULOUS(argv[argnum]); 433 if (nebulousSources != nebulousImage) { 434 psError(PS_ERR_UNKNOWN, true, "sources file must have %snebulous path with %s image path\n", 435 nebulousImage ? "" : "non ", nebulousImage ? "nebulous" : "regular"); 436 usage(); 437 } 438 psMetadataAddStr(config->arguments, PS_LIST_TAIL, "SOURCES", 0, 439 "name of input sources file", argv[argnum]); 440 psArgumentRemove(argnum, &argc, argv); 441 } 396 442 397 443 if ((argnum = psArgumentGet(argc, argv, "-tmproot"))) { … … 403 449 usage(); 404 450 } 405 psString dir = pathToDirectory(argv[argnum]); 406 psMetadataAddStr(config->arguments, PS_LIST_TAIL, "OUTPUT", 0, "directory for temporary files", 407 dir); 408 psFree(dir); 451 psMetadataAddStr(config->arguments, PS_LIST_TAIL, "OUTPUT", 0, "path for (temporary if replae) output files", 452 argv[argnum]); 409 453 psArgumentRemove(argnum, &argc, argv); 410 454 } else { … … 415 459 if ((argnum = psArgumentGet(argc, argv, "-recovery"))) { 416 460 psArgumentRemove(argnum, &argc, argv); 417 psString dir = pathToDirectory(argv[argnum]); 418 psMetadataAddStr(config->arguments, PS_LIST_TAIL, "RECOVERY", 0, "directory for recovery files", 419 dir); 420 psFree(dir); 461 psMetadataAddStr(config->arguments, PS_LIST_TAIL, "RECOVERY", 0, "path for recovery files", 462 argv[argnum]); 421 463 psArgumentRemove(argnum, &argc, argv); 422 464 } else if ((stage == IPP_STAGE_RAW) && gotReplace) { 423 465 psError(PS_ERR_UNKNOWN, true, "-recovery is required for -stage raw with -replace\n"); 424 466 usage(); 425 }426 427 if ((argnum = psArgumentGet(argc, argv, "-remove"))) {428 if (!gotReplace) {429 psError(PS_ERR_UNKNOWN, true, "-replace is required with -remove\n");430 usage();431 }432 psArgumentRemove(argnum, &argc, argv);433 psMetadataAddBool(config->arguments, PS_LIST_TAIL, "REMOVE", 0, "remove original files",434 true);435 467 } 436 468 … … 451 483 updateAstrometry(streakFiles *sf) 452 484 { 485 // XXX: why do I check this here? Shouldn't it be just around the call to linearizeTransforms? 453 486 if (sf->bilevelAstrometry) { 454 487 455 linearizeTransforms(sf->astrom); 488 if (!linearizeTransforms(sf->astrom)) { 489 // fit failed, leave the astrometry unchanged 490 return; 491 } 456 492 457 493 if (!pmAstromWriteWCS(sf->outImage->header, sf->inAstrom->fpa, sf->chip, 0.001)) { … … 501 537 } 502 538 } 503 sf->outImage->header = (psMetadata*)psMemIncrRefCounter(sf->inImage->header);539 sf->outImage->header = psMemIncrRefCounter(sf->inImage->header); 504 540 if (sf->recImage) { 505 sf->recImage->header = (psMetadata*) psMemIncrRefCounter(sf->inImage->header); 506 } 541 sf->recImage->header = psMetadataCopy(NULL, sf->inImage->header); 542 addRecoveryKeyword(sf->recImage->header); 543 } 544 addDestreakKeyword(sf->outImage->header); 507 545 508 546 if (!SFILE_IS_IMAGE(sf->inImage)) { … … 520 558 521 559 // set up the compression parameters 522 #ifdef STREAKS_COMPRESS_OUTPUT 523 // compression of the image pixels is disabled for now. Some consortium members 524 // have problems reading them 525 copyFitsOptions(sf->outImage, sf->recImage, sf->inImage); 526 527 // XXX: TODO: can we derive these values from the input header? 528 // psFitsCompressionGet(sf->inImage->image) gives compression none 529 // perhaps we should just use the definition of COMP_IMG in the configuration 530 psFitsSetCompression(sf->outImage->fits, PS_FITS_COMPRESS_RICE, sf->tiles, 8, 0, 0); 531 if (sf->recImage) { 532 psFitsSetCompression(sf->recImage->fits, PS_FITS_COMPRESS_RICE, sf->tiles, 8, 0, 0); 533 } 534 #endif 560 copyFitsOptions(sf->outImage, sf->recImage, sf->inImage, sf->tiles); 535 561 536 562 if (sf->inMask) { … … 539 565 sf->outMask->header = (psMetadata*) psMemIncrRefCounter(sf->inMask->header); 540 566 if (sf->recMask) { 541 sf->recMask->header = (psMetadata*) psMemIncrRefCounter(sf->inMask->header); 542 } 567 sf->recMask->header = psMetadataCopy(NULL, sf->outMask->header); 568 addRecoveryKeyword(sf->recMask->header); 569 } 570 addDestreakKeyword(sf->outMask->header); 543 571 if (updateAstrometry) { 544 572 pmAstromWriteWCS(sf->outMask->header, sf->inAstrom->fpa, sf->chip, 0.001); … … 554 582 } 555 583 556 #ifdef STREAKS_COMPRESS_OUTPUT 557 // XXX: see note above 558 copyFitsOptions(sf->outMask, sf->recMask, sf->inMask); 559 psFitsSetCompression(sf->outMask->fits, PS_FITS_COMPRESS_PLIO, sf->tiles, 8, 0, 0); 560 if (sf->recMask) { 561 psFitsSetCompression(sf->recMask->fits, PS_FITS_COMPRESS_PLIO, sf->tiles, 8, 0, 0); 562 } 584 copyFitsOptions(sf->outMask, sf->recMask, sf->inMask, sf->tiles); 563 585 if (sf->outChMask) { 564 copyFitsOptions(sf->outChMask, sf->recChMask, sf->inMask); 565 psFitsSetCompression(sf->outChMask->fits, PS_FITS_COMPRESS_PLIO, sf->tiles, 8, 0, 0); 566 if (sf->recChMask) { 567 psFitsSetCompression(sf->recChMask->fits, PS_FITS_COMPRESS_PLIO, sf->tiles, 8, 0, 0); 568 } 569 } 570 #endif 586 copyFitsOptions(sf->outChMask, sf->recChMask, sf->inMask, sf->tiles); 587 } 571 588 } 572 589 } … … 576 593 sf->outWeight->header = (psMetadata*) psMemIncrRefCounter(sf->inWeight->header); 577 594 if (sf->recWeight) { 578 sf->recWeight->header = (psMetadata*) psMemIncrRefCounter(sf->inWeight->header); 579 } 595 sf->recWeight->header = psMetadataCopy(NULL, sf->outWeight->header); 596 addRecoveryKeyword(sf->recWeight->header); 597 } 598 addDestreakKeyword(sf->outWeight->header); 580 599 if (updateAstrometry) { 581 600 pmAstromWriteWCS(sf->inWeight->header, sf->inAstrom->fpa, sf->chip, 0.001); … … 583 602 setupImageRefs(sf->outWeight, sf->recWeight, sf->inWeight, sf->extnum, exciseAll); 584 603 585 #ifdef STREAKS_COMPRESS_OUTPUT 586 copyFitsOptions(sf->outWeight, sf->recWeight, sf->inWeight); 587 // XXX: see note above 588 psFitsSetCompression(sf->outWeight->fits, PS_FITS_COMPRESS_RICE, sf->tiles, 8, 0, 0); 589 if (sf->recWeight) { 590 psFitsSetCompression(sf->recWeight->fits, PS_FITS_COMPRESS_RICE, sf->tiles, 8, 0, 0); 591 } 592 #endif 593 } 594 // and for raw images, create sub images that represent the actual image 595 // area (no overscan) 604 copyFitsOptions(sf->outWeight, sf->recWeight, sf->inWeight, sf->tiles); 605 } 596 606 597 607 return true; 598 608 } 599 600 601 609 602 610 static void … … 746 754 747 755 static bool 748 warpedPixel(streakFiles *sfiles, PixelPos *cellCoord)756 warpedPixel(streakFiles *sfiles, int x, int y) 749 757 { 750 758 PixelPos chipCoord; … … 757 765 // we clip so that the streak calculation code doesn't have to 758 766 // clipping here insures that we don't touch the overscan regions 759 if (( cellCoord->x < 0) || (cellCoord->x >= sfiles->inImage->numCols) ||760 ( cellCoord->y < 0) || (cellCoord->y >= sfiles->inImage->numRows)) {767 if ((x < 0) || (x >= sfiles->inImage->numCols) || 768 (y < 0) || (y >= sfiles->inImage->numRows)) { 761 769 return false; 762 770 } 763 771 764 cellToChipInt(&chipCoord.x, &chipCoord.y, sfiles->astrom, cellCoord->x, cellCoord->y);772 cellToChipInt(&chipCoord.x, &chipCoord.y, sfiles->astrom, x, y); 765 773 766 774 if (chipCoord.x < 0 || chipCoord.x >= sfiles->warpedPixels->numCols) { … … 774 782 } 775 783 784 // read a sources file (.cmf) and remove any rows whose coordinate is convered by a 785 // streak mask 786 static void 787 censorSources(streakFiles *sfiles, psU32 maskStreak) 788 { 789 if ((!sfiles->inSources) || (!sfiles->outMask)) { 790 return; 791 } 792 psImage *maskImage = sfiles->outMask->image; 793 if (!maskImage) { 794 psError(PS_ERR_IO, false, "maskImage is null!"); 795 streaksExit("", PS_EXIT_PROG_ERROR); 796 } 797 798 sFile *in = sfiles->inSources; 799 sFile *out = sfiles->outSources; 800 801 in->header = psFitsReadHeader(NULL, in->fits); 802 if (!in->header) { 803 psError(PS_ERR_IO, false, "failed to read header from %s", in->resolved_name); 804 streaksExit("", PS_EXIT_DATA_ERROR); 805 } 806 807 bool status; 808 psString extname = psMetadataLookupStr(&status, in->header, "EXTNAME"); 809 if (!extname) { 810 psError(PS_ERR_IO, false, "failed to find extname in header of %s", in->resolved_name); 811 streaksExit("", PS_EXIT_DATA_ERROR); 812 } 813 814 psArray *inTable = psFitsReadTable(in->fits); 815 if (!inTable->n) { 816 psError(PS_ERR_IO, false, "table in %s is empty", in->resolved_name); 817 streaksExit("", PS_EXIT_DATA_ERROR); 818 } 819 820 psArray *outTable = psArrayAllocEmpty(inTable->n); 821 int j = 0; 822 int numCensored = 0; 823 for (int i = 0 ; i < inTable->n; i++) { 824 psMetadata *row = inTable->data[i]; 825 826 psF32 x = psMetadataLookupF32 (&status, row, "X_PSF"); 827 psF32 y = psMetadataLookupF32 (&status, row, "Y_PSF"); 828 829 psU32 mask = psImageGet(maskImage, x, y); 830 831 // Key the source if the center pixel is not masked with maskStreak 832 if (! (mask & maskStreak) ) { 833 psArraySet(outTable, j++, row); 834 } else { 835 numCensored++; 836 } 837 } 838 839 // get rid of unused elements (don't know if this is necessary) 840 psArrayRealloc(outTable, j); 841 842 addDestreakKeyword(in->header); 843 if (psArrayLength(outTable) > 0) { 844 printf("Censored %d sources\n", numCensored); 845 if (! psFitsWriteTable(out->fits, in->header, outTable, extname)) { 846 psError(PS_ERR_IO, false, "failed to write table to %s", out->resolved_name); 847 streaksExit("", PS_EXIT_DATA_ERROR); 848 } 849 } else { 850 printf("Censored ALL %d sources\n", numCensored); 851 if (! psFitsWriteTableEmpty(out->fits, in->header, inTable->data[0], extname)) { 852 psError(PS_ERR_IO, false, "failed to write empty table to %s", out->resolved_name); 853 streaksExit("", PS_EXIT_DATA_ERROR); 854 } 855 } 856 857 if (!psFitsClose(out->fits)) { 858 psError(PS_ERR_IO, false, "failed to close table %s", out->resolved_name); 859 streaksExit("", PS_EXIT_DATA_ERROR); 860 } 861 }
Note:
See TracChangeset
for help on using the changeset viewer.
