IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 34596 for trunk


Ignore:
Timestamp:
Oct 25, 2012, 11:37:10 AM (14 years ago)
Author:
bills
Message:

New features for ppstamp

-sources <sources file>
-write_cmf

If sources file is supplied (or -write_cmf and astrom is supplied) extract sources
from the region of interest and output them into a cmf file.

Also do a better job insuring that zero point is saved in the output headers.

Location:
trunk/pstamp/src
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/pstamp/src/ppstampArguments.c

    r33504 r34596  
    2525    fprintf(stderr, "   [-mask   mk_image]    : mask image\n");
    2626    fprintf(stderr, "   [-variance var_image] : variance image\n");
     27    fprintf(stderr, "   [-sources sources]    : sources cmf (ignored for chip stage)\n");
    2728    fprintf(stderr, "   [-stage stage]        : stage of input image (raw, chip, warp, stack, diff)\n");
    2829    fprintf(stderr, "   [-write_jpeg]         : write a JPEG  format of the image stamp\n");
     30    fprintf(stderr, "   [-write_cmf]          : create an output cmf with the sources overlapping the stamp\n");
     31    fprintf(stderr, "   [-wholefile]          : ignore the region of interest and process the entire input image\n");
    2932    // fprintf(stderr, "   [-no_censor_masked]   : do not set masked pixels to NAN\n");
    3033    fprintf(stderr, "\n");
     
    9295        options->stage = psStringCopy(argv[argnum]);
    9396        psArgumentRemove(argnum, &argc, argv);
     97    } else {
     98        // Should we require this?
     99        options->stage = psStringCopy("unknown");
    94100    }
    95101    if ((argnum = psArgumentGet(argc, argv, "-write_jpeg"))) {
    96102        psArgumentRemove(argnum, &argc, argv);
    97103        options->writeJPEG = true;
    98     } else {
    99         options->writeJPEG = false;
     104    }
     105    if ((argnum = psArgumentGet(argc, argv, "-write_cmf"))) {
     106        psArgumentRemove(argnum, &argc, argv);
     107        options->writeCMF = true;
    100108    }
    101109
    102     pmConfigFileSetsMD(config->arguments, &argc, argv, "ASTROM", "-astrom", "-astromlist");
     110    // XXX: Note: the various list options have never been tested with ppstamp to my knowledge
     111    bool gotAstrom = false;
     112    if ((argnum = psArgumentGet(argc, argv, "-astrom"))) {
     113        gotAstrom = true;
     114        pmConfigFileSetsMD(config->arguments, &argc, argv, "ASTROM", "-astrom", "-astromlist");
     115    }
    103116    pmConfigFileSetsMD(config->arguments, &argc, argv, "MASK",   "-mask", "-masklist");
    104117    pmConfigFileSetsMD(config->arguments, &argc, argv, "VARIANCE", "-variance", "-variancelist");
    105118
    106     // the input file is a required argument; if not found, we will exit
     119    if ((argnum = psArgumentGet(argc, argv, "-sources"))) {
     120        pmConfigFileSetsMD(config->arguments, &argc, argv, "SOURCES", "-sources", "-sourceslist");
     121        // supplying a sources file implies that we want to save the output
     122        options->writeCMF = true;
     123    } else if (options->writeCMF && !gotAstrom) {
     124        // if we didn't get a sources file but the user wanted us to write the sources we must
     125        // have an astrometry file supplied
     126        // XXX: Is this too restrictive? Could the sources be contained in say the input file?
     127        psError(PSTAMP_ERR_ARGUMENTS, true, "cannot write cmf file unless input sources are supplied\n");
     128        usage();
     129    }
     130
     131    // the input image file is a required argument; if not found, we will exit
    107132    bool status = pmConfigFileSetsMD (config->arguments, &argc, argv, "INPUT", "-file", "-list");
    108133    if (!status) {
     
    126151    }
    127152
    128     // finally the output file
     153    // finally the only argument left must be output outroot
    129154    if (argc < 2) {
    130155        psError(PSTAMP_ERR_ARGUMENTS, true, "must specify OUTPUT\n");
     
    135160    }
    136161
    137     // Add the output image (which remains on the command-line) to the arguments list
    138162    psMetadataAddStr(config->arguments, PS_LIST_TAIL, "OUTPUT", 0, "Name of the output image", argv[1]);
    139 
    140     // psMetadataPrint(stdout, config->arguments,0);
    141163
    142164    return config;
  • trunk/pstamp/src/ppstampMakeStamp.c

    r33504 r34596  
    1919static void chipToSky(pmAstromObj *pt, pmFPA *fpa, pmChip *chip);
    2020static bool setMaskedToNAN(pmConfig *config, psImage *image, psImage *mask, psImage *variance);
     21static bool copySources(pmReadout *outputReadout, pmReadout *inputReadout, pmReadout *astromReadout, psRegion extractRegion);
    2122
    2223// convert the input chip's transforms to the output
     
    8081}
    8182
    82 static bool copyMetadata(pmFPAfile *output, pmFPAfile *input, pmChip *inChip, ppstampOptions *options, pmAstromObj *center)
     83static bool copyMetadata(pmFPAfile *output, pmFPAfile *input, pmChip *inChip, ppstampOptions *options, pmAstromObj *center, pmFPAfile *astrom, pmFPAview *inView)
    8384{
    8485    pmChip    *outChip;
    85     pmFPAview *view = pmFPAviewAlloc(0);
     86    pmFPAview *outView = pmFPAviewAlloc(0);
    8687
    8788    // our output file has a single chip
    88     view->chip = 0;
    89     outChip = pmFPAviewThisChip(view, output->fpa);
    90     psFree(view);
    91 
    92     // copy data from the input chip header to the output.
     89    outView->chip = 0;
     90    outChip = pmFPAviewThisChip(outView, output->fpa);
     91    psFree(outView);
     92    pmHDU *outHDU = pmHDUGetHighest(output->fpa, outChip, NULL);
     93
     94    // copy data from the input's chip header to the output.
    9395    // since some of the keywords might be duplicated we may not want to copy both
    9496
    95     pmHDU *inHDU  = pmHDUFromChip(inChip);
    96     pmHDU *outHDU = pmHDUGetHighest(output->fpa, outChip, NULL);
     97    pmHDU *inHDU  = NULL;
     98    if (strcmp(options->stage, "raw") && input != astrom) {
     99        // Copy the header from the astrometry file since it contains the psphot and psastro results
     100        pmChip *astromChip = pmFPAviewThisChip(inView, astrom->fpa);
     101        inHDU  = pmHDUFromChip(astromChip);
     102    } else {
     103        inHDU  = pmHDUFromChip(inChip);
     104    }
    97105
    98106    if (inHDU->header) {
     
    102110    }
    103111
    104     // copy the fpa concepts
     112    // copy the fpa and chip concepts
    105113    pmConceptsCopyFPA(output->fpa, input->fpa, false, false);
     114    // Needed to preserve FPA.ZP
    106115    pmConceptsCopyChip(outChip, inChip, false);
     116
     117    // copy the cell concepts (needed to get CELL.EXPOSURE which gets used to set EXPTIME)
    107118    pmCell *outCell = outChip->cells->data[0]; // The only output cell
    108119
     
    122133    }
    123134
    124     // If input had WCS convert it for stamp
     135    // If input had WCS convert it for the new image coordinate system of our stamp
    125136    if (input->fpa->toSky) {
    126137        // copy the input fpa's transforms
     
    135146        }
    136147    } else {
    137         psWarning("No WCS present in input\n");
    138     }
    139 
     148        psLogMsg("ppstampMakeStamp", PS_LOG_WARN, "No WCS present in input.");
     149    }
     150
     151    // Save our specific metadata
    140152    psMetadataAddF64(outHDU->header, PS_LIST_TAIL, "RA_DEG", PS_META_REPLACE, "Right Ascension of stamp center", RAD_TO_DEG(center->sky->r));
    141153    psMetadataAddF64(outHDU->header, PS_LIST_TAIL, "DEC_DEG", PS_META_REPLACE, "Declination of stamp center", RAD_TO_DEG(center->sky->d));
     154
     155    // XXX: TODO: save the region of interest boundary and the offset to be applied.
     156    // XXX: Gene thinks that there may be a way to handle this in the WCS
     157
     158    // Now a few sanity checks
     159    // Make sure zero point in the fpa concepts matches the observed value in the input header
     160    bool status;
     161    float zpt_obs = psMetadataLookupF32(&status, outHDU->header, "ZPT_OBS");
     162    if (status) {
     163        psMetadataAddF32(output->fpa->concepts, PS_LIST_TAIL, "FPA.ZP", PS_META_REPLACE, "Magnitude zero point", zpt_obs);
     164    }
    142165
    143166    ppstampVersionMetadata(outHDU->header, options);
     
    324347
    325348            if (options->censorMasked && !setMaskedToNAN(config, outReadout->image, outReadout->mask, outReadout->variance)) {
    326                  psError(PS_ERR_UNKNOWN, false, "failed to create postage stamp mask image\n");
    327                  status = false;
    328                  break;
     349                psError(PS_ERR_UNKNOWN, false, "failed to create postage stamp mask image\n");
     350                status = false;
     351                break;
    329352            }
    330353        }
     
    335358        status = true;
    336359
     360        if (options->writeCMF) {
     361            pmReadout *astromReadout = NULL;
     362            if (astrom->fpa != input->fpa) {
     363                astromReadout = pmFPAviewThisReadout(srcView, astrom->fpa);
     364            }
     365            if (!copySources(outReadout, astromReadout, astromReadout, extractRegion)) {
     366                psError(PS_ERR_UNKNOWN, false, "failed to extract sources from region of interest.\n");
     367                status = false;
     368                break;
     369            }
     370        }
     371
    337372        psFree(outReadout); // drop reference
    338373    }
     
    341376
    342377    if (status) {
    343         status = copyMetadata(output, input, inChip, options, center);
     378        // For raw stage we need to do more work to build a proper header
     379        status = copyMetadata(output, input, inChip, options, center, astrom, view);
    344380    }
    345381    return status ? PS_EXIT_SUCCESS : PS_EXIT_UNKNOWN_ERROR;
     
    428464    double dy = 0.5 * options->roip.dDEC / fpa->toSky->Ys;
    429465
    430     if (dx > 5000) {
    431         fprintf(stderr, "requested width %f too large reducing to 5000\n", dx);
    432         dx = 5000;
    433     }
    434     if (dy > 5000) {
    435         fprintf(stderr, "requested height %f too large reducing to 5000\n", dy);
    436         dy = 5000;
     466    // XXX: why do we limit this?
     467    if (dx > 8000) {
     468        psWarning( "requested width %f too large reducing to 8000\n", dx);
     469        dx = 8000;
     470    }
     471    if (dy > 8000) {
     472        psWarning( "requested height %f too large reducing to 8000\n", dy);
     473        dy = 8000;
    437474    }
    438475
     
    480517    ppstampOverlap   returnval = PPSTAMP_OFF;
    481518
    482 //    fprintf(stderr, "ppstampChipBounds: %s\n", psRegionToString(*chipBounds));
    483 
    484519    // set up the astrometry
    485520    pmHDU *hdu = pmFPAviewThisHDU(view, astrom->fpa);
     
    498533        }
    499534    } else {
    500         // we use a default FPA pixel scale of 1.0
    501535        if (!pmAstromReadWCS (input->fpa, chip, hdu->header, 1.0) && mustHaveAstrometry) {
    502536            psError(PS_ERR_UNKNOWN, false, "Unable to read WCS astrometry for input FPA.");
     
    537571            center->chip->yErr = 0;
    538572            onChip = true;
    539             chipToSky(center, input->fpa, chip);
     573            if (input->fpa->toSky) {
     574                chipToSky(center, input->fpa, chip);
     575            }
    540576        }
    541577    }
     
    550586                int width  = options->roip.dX;
    551587                int height = options->roip.dY;
    552                 if (width > 7000) {
    553                     fprintf(stderr, "requested width %d too large reducing to 7000\n", width);
    554                     width = 7000;
     588                if (width > 8000) {
     589                    psWarning( "requested width %d too large reducing to 8000\n", width);
     590                    width = 8000;
    555591                }
    556                 if (height > 7000) {
    557                     fprintf(stderr, "requested height %d too large reducing to 7000\n", height);
    558                     height = 7000;
     592                if (height > 8000) {
     593                    psWarning( "requested height %d too large reducing to 8000\n", height);
     594                    height = 8000;
    559595                }
    560596
     
    675711
    676712    if (!foundOverlap && (returnval == PS_EXIT_SUCCESS)) {
    677         fprintf(stderr, "ROI not found in input\n");
     713        psWarning( "ROI not found in input\n");
    678714        returnval = PSTAMP_NO_OVERLAP;
    679715    }
     
    739775    }
    740776
    741     // XXX: this shouldn't be a fprintf
    742     fprintf(stderr, "Censored %ld masked pixels\n", numCensored);
     777    psLogMsg("ppstamp", PS_LOG_DETAIL, "Censored %ld masked pixels\n", numCensored);
    743778
    744779    return true;
    745780}
     781
     782static bool copySources(pmReadout *outReadout, pmReadout *inReadout, pmReadout *astromReadout, psRegion extractRegion) {
     783    bool status;
     784
     785    // first look for detections in the input readout. Those would have come from the -sources file
     786    pmDetections *inDetections = psMetadataLookupPtr (&status, inReadout->analysis, "PSPHOT.DETECTIONS");
     787    if (!inDetections) {
     788        // No detections on the input readout. Try the astrometry readout if supplied.
     789        if (astromReadout) {
     790            inDetections = psMetadataLookupPtr (&status, astromReadout->analysis, "PSPHOT.DETECTIONS");
     791            if (!inDetections) {
     792                psLogMsg("ppstampMakeStamp", PS_LOG_WARN, "no detections found on input or astrometry readout\n");
     793                return false;
     794            } else {
     795                psLogMsg("ppstampMakeStamp", PS_LOG_INFO, "using detections from astrom file\n");
     796            }
     797        } else {
     798            psLogMsg("ppstampMakeStamp", PS_LOG_WARN, "no detections found on input readout\n");
     799            return false;
     800        }
     801    }
     802    if (!inDetections->allSources) {
     803        psLogMsg("ppstampMakeStamp", PS_LOG_WARN, "no sources array found on detections structure\n");
     804        return false;
     805    }
     806
     807    // Ok we have sources, allocate a detections structure and copy them to the output readout
     808    psArray *inSources = inDetections->allSources;
     809
     810    pmDetections *outDetections = pmDetectionsAlloc();
     811    psMetadataAddPtr (outReadout->analysis, PS_LIST_TAIL, "PSPHOT.DETECTIONS", PS_META_REPLACE | PS_DATA_UNKNOWN,
     812        "psphot detections", outDetections);
     813
     814    psArray *outSources = outDetections->allSources = psArrayAllocEmpty( 100 );
     815
     816    // include sources that are off the stamp by just a little bit
     817    #define EXPAND_SIZE 16
     818    psRegion sourceRegion = extractRegion;
     819    sourceRegion.x0 -= EXPAND_SIZE;
     820    sourceRegion.y0 -= EXPAND_SIZE;
     821    sourceRegion.x1 += EXPAND_SIZE;
     822    sourceRegion.y1 += EXPAND_SIZE;
     823
     824    for (int i = 0; i < inSources->n; i++ ) {
     825        pmSource *src = inSources->data[i];
     826
     827        float x = src->peak->xf;
     828        float y = src->peak->yf;
     829        if (x < sourceRegion.x0 || x > sourceRegion.x1 ||
     830            y < sourceRegion.y0 || y > sourceRegion.y1) {
     831            continue;
     832        }
     833        psArrayAdd(outSources, 100, src);
     834    }
     835
     836    return true;
     837}
  • trunk/pstamp/src/ppstampOptions.c

    r33504 r34596  
    3232    options->censorMasked = false;
    3333    options->writeJPEG = false;
     34    options->writeCMF = false;
    3435    options->nocompress = false;
    3536    options->wholeFile = false;
  • trunk/pstamp/src/ppstampOptions.h

    r33504 r34596  
    1414    bool        censorMasked;
    1515    bool        writeJPEG;
     16    bool        writeCMF;
    1617    bool        nocompress;
    1718    //
  • trunk/pstamp/src/ppstampParseCamera.c

    r33504 r34596  
    120120    }
    121121
     122    // Set up the input and output sources files if needed
     123    if (options->writeCMF) {
     124        bool status;
     125
     126        // see if -sources file was supplied.
     127        // If so define the file.
     128        psPtr sourcesFile = psMetadataLookupStr(&status, config->arguments, "SOURCES");
     129        if (sourcesFile) {
     130            pmFPAfile *sources = pmFPAfileBindFromArgs(&status, input, config, "PPSTAMP.INPUT.SOURCES", "SOURCES");
     131            if (!status) {
     132                psError(psErrorCodeLast(), false, "Failed to load file definition for PPSTAMP.INPUT.SOURCES");
     133                return false;
     134            }
     135            if (!sources && !astrom) {
     136                psError(psErrorCodeLast(), false, "Failed to define input sources file");
     137                return false;
     138            }
     139        } else {
     140            psLogMsg ("ppstamp", PS_LOG_INFO, "output sources file requested but no input supplied. Will try the supplied astrometry file.\n");
     141        }
     142       
     143        pmFPAfile *outputSources = NULL;
     144        outputSources = pmFPAfileDefineSkycell(config, output->fpa, "PPSTAMP.OUTPUT.SOURCES");
     145        if (!outputSources) {
     146            psError(psErrorCodeLast(), false, "Failed to define output sources file");
     147            return false;
     148        }
     149        outputSources->save = true;
     150    }
     151
    122152    pmFPAfile *chipImage = pmFPAfileDefineChipMosaic(config, input->fpa, "PPSTAMP.CHIP");
    123153    if (!chipImage) {
  • trunk/pstamp/src/pstamp.h

    r28291 r34596  
    2626
    2727// values for options mask.
    28 #define PSTAMP_SELECT_IMAGE      1
    29 #define PSTAMP_SELECT_MASK       2
    30 #define PSTAMP_SELECT_WEIGHT     4
    31 #define PSTAMP_SELECT_CMF        8
    32 #define PSTAMP_SELECT_PSF       16
    33 #define PSTAMP_SELECT_BACKMDL   32
    34 #define PSTAMP_SELECT_INVERSE 1024
    35 #define PSTAMP_SELECT_UNCONV  2048
    36 #define PSTAMP_USE_IMFILE_ID 16384
     28#define PSTAMP_SELECT_IMAGE         1
     29#define PSTAMP_SELECT_MASK          2
     30#define PSTAMP_SELECT_WEIGHT        4
     31#define PSTAMP_SELECT_SOURCES       8
     32#define PSTAMP_SELECT_CMF           8
     33#define PSTAMP_SELECT_PSF           16
     34#define PSTAMP_SELECT_BACKMDL       32
     35#define PSTAMP_SELECT_JPEG          64
     36// unused                           128
     37// unused                           256
     38#define PSTAMP_SELECT_UNCOMPRESSED  512
     39#define PSTAMP_SELECT_INVERSE       1024
     40#define PSTAMP_SELECT_UNCONV        2048
     41#define PSTAMP_RESTORE_BACKGROUND   4096
     42// unused                           8192
     43#define PSTAMP_USE_IMFILE_ID        16384
    3744
    38 #define PSTAMP_NO_WAIT_FOR_UPDATE 32768
     45#define PSTAMP_NO_WAIT_FOR_UPDATE   32768
     46#define PSTAMP_REQUEST_UNCENSORED  0x10000
     47#define PSTAMP_REQUIRE_UNCENSORED  0x20000
    3948
    4049#define PSTAMP_CENTER_IN_PIXELS 1
Note: See TracChangeset for help on using the changeset viewer.