IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 23992 for trunk/ppSkycell/src


Ignore:
Timestamp:
Apr 28, 2009, 3:31:25 PM (17 years ago)
Author:
Paul Price
Message:

It builds. Hasn't been tested yet, though.

Location:
trunk/ppSkycell/src
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/ppSkycell/src/Makefile.am

    r23982 r23992  
    3131        ppSkycell.c             \
    3232        ppSkycellArguments.c    \
     33        ppSkycellCamera.c       \
     34        ppSkycellData.c         \
    3335        ppSkycellLoop.c         \
    34         ppSkycellReadout.c      \
    3536        ppSkycellVersion.c           
    3637
  • trunk/ppSkycell/src/ppSkycell.c

    r23982 r23992  
    55#include <stdio.h>
    66#include <pslib.h>
     7#include <psmodules.h>
     8
     9#include "ppSkycell.h"
    710
    811int main(int argc, char *argv[])
     
    1114    if (!data) {
    1215        psErrorStackPrint(stderr, "Unable to initialise.");
    13         exit(PS_EXIT_CONFIG_ERROR);
     16        return PS_EXIT_CONFIG_ERROR;
    1417    }
    1518
     
    1720        psErrorStackPrint(stderr, "Unable to parse arguments.");
    1821        psFree(data);
    19         exit(PS_EXIT_CONFIG_ERROR);
     22        return PS_EXIT_CONFIG_ERROR;
    2023    }
    2124
     25    if (!ppSkycellCamera(data)) {
     26        psErrorStackPrint(stderr, "Unable to parse camera configuration.");
     27        psFree(data);
     28        return PS_EXIT_CONFIG_ERROR;
     29    }
    2230
     31    if (!ppSkycellLoop(data)) {
     32        psErrorStackPrint(stderr, "Unable to process data.");
     33        psFree(data);
     34        return PS_EXIT_DATA_ERROR;
     35    }
    2336
     37    psFree(data);
     38
     39    return PS_EXIT_SUCCESS;
     40}
     41
  • trunk/ppSkycell/src/ppSkycell.h

    r23982 r23992  
    22#define PP_SKYCELL_H
    33
     4#include <pslib.h>
     5#include <psmodules.h>
     6
     7#define PPSKYCELL_RECIPE "PPSKYCELL"    // Recipe name
     8
     9// Data for processing
    410typedef struct {
    5     psString inName;                    // Input filename
    6     psString outName;                   // Output name
     11    psString imagesName;                // Filename with images
     12    psString masksName;                 // Filename with masks
     13    psString outRoot;                   // Output root name
    714    int numInputs;                      // Number of inputs
     15    psImageMaskType maskVal;            // Value to mask
    816    int bin1, bin2;                     // Binning factors
    917    pmConfig *config;                   // Configuration
    1018} ppSkycellData;
    1119
     20/// Initialise data for processing
     21ppSkycellData *ppSkycellDataInit(int *argc, char *argv[] // Command-line arguments
     22    );
     23
     24/// Parse command-line arguments
     25bool ppSkycellArguments(ppSkycellData *data, // Data for processing
     26                        int argc, char *argv[] // Command-line arguments
     27    );
     28
     29/// Parse camera configurations
     30bool ppSkycellCamera(ppSkycellData *data // Data for processing
     31    );
     32
     33/// Loop over input data, processing
     34bool ppSkycellLoop(ppSkycellData *data // Data for processing
     35    );
     36
     37
     38#endif
  • trunk/ppSkycell/src/ppSkycellArguments.c

    r23982 r23992  
    2929{
    3030    fprintf(stderr, "\nPan-STARRS skycell JPEGifier\n\n");
    31     fprintf(stderr, "Usage: %s INPUT.list OUTPUT_ROOT\n\n",
     31    fprintf(stderr, "Usage: %s -images INPUT.list [-masks MASK.list] OUTPUT_ROOT\n\n",
    3232            program);
    3333    fprintf(stderr, "\n");
     
    4545bool ppSkycellArguments(ppSkycellData *data, int argc, char *argv[])
    4646{
    47     assert(config);
     47    assert(data);
     48    assert(data->config);
    4849
    4950    psMetadata *arguments = psMetadataAlloc(); // Command-line arguments
    50     if (argc == 1 || !psArgumentParse(arguments, &argc, argv) || argc != 3) {
     51    psMetadataAddStr(arguments, PS_LIST_TAIL, "-images", 0, "Filename with input images", NULL);
     52    psMetadataAddStr(arguments, PS_LIST_TAIL, "-masks", 0, "Filename with input masks", NULL);
     53    if (argc == 1 || !psArgumentParse(arguments, &argc, argv) || argc != 2) {
    5154        usage(argv[0], arguments, data);
    5255    }
    5356
    54     data->inName = psStringCopy(argv[1]);
    55     data->outRoot = psStringCopy(argv[2]);
     57    data->imagesName = psMetadataLookupStr(NULL, arguments, "-images");
     58    data->masksName = psMetadataLookupStr(NULL, arguments, "-masks");
     59    data->outRoot = psStringCopy(argv[1]);
    5660
    5761    psTrace("ppSkycell", 1, "Done reading command-line arguments\n");
    5862    psFree(arguments);
     63
     64    PS_ASSERT_STRING_NON_EMPTY(data->imagesName, false);
     65    PS_ASSERT_STRING_NON_EMPTY(data->outRoot, false);
    5966
    6067    return true;
  • trunk/ppSkycell/src/ppSkycellCamera.c

    r23982 r23992  
    99#include "ppSkycell.h"
    1010
     11/// Read list of images
     12static psArray *fileList(const char *filename // Filename
     13    )
     14{
     15    psString input = psSlurpFilename(filename);
     16    if (!input) {
     17        psError(PS_ERR_IO, false, "Unable to read %s", filename);
     18        return false;
     19    }
     20    psArray *inputs = psStringSplitArray(input, "\n", false); // Input filenames
     21    psFree(input);
     22    if (!inputs || inputs->n == 0) {
     23        psError(PS_ERR_IO, false, "Unable to read filenames from %s", filename);
     24        psFree(inputs);
     25        return NULL;
     26    }
     27    return inputs;
     28}
     29
    1130/// Add a single filename to the arguments as an array, so that it can be used with pmFPAfileBindFromArgs, etc
    12 static void fileList(const char *file, // The symbolic name for the file
    13                      const char *name, // The name of the file
    14                      const char *comment, // Description of the file
    15                      pmConfig *config // Configuration
     31static void fileArguments(const char *file, // The symbolic name for the file
     32                          const char *name, // The name of the file
     33                          const char *comment, // Description of the file
     34                          pmConfig *config // Configuration
    1635    )
    1736{
    1837    psArray *files = psArrayAlloc(1); // Array with file names
    1938    files->data[0] = psStringCopy(name);
     39    if (psMetadataLookup(config->arguments, file)) {
     40        psMetadataRemoveKey(config->arguments, file);
     41    }
    2042    psMetadataAddArray(config->arguments, PS_LIST_TAIL, file, 0, comment, files);
    2143    psFree(files);
     
    2749    )
    2850{
    29     psString input = psSlurpFilename(data->inName);
    30     if (!input) {
    31         psError(PS_ERR_IO, false, "Unable to read %s", data->inName);
     51    psArray *images = fileList(data->imagesName); // Image names
     52    if (!images) {
     53        psError(psErrorCodeLast(), false, "No images provided.");
    3254        return false;
    3355    }
     56    data->numInputs = images->n;
    3457
    35     psArray *inputs = psStringSplitArray(input, "\n", false); // Input filenames
    36     psFree(input);
    37     if (!inputs || inputs->n == 0) {
    38         psError(PS_ERR_IO, false, "Unable to read filenames from %s", data->inName);
    39         psFree(inputs);
    40         return false;
    41     }
    42 
    43     data->numInputs = inputs->n;
    44     psMetadataAddArray(config->arguments, PS_LIST_TAIL, "INPUTS", 0, "Input files", inputs);
    45     psFree(inputs);
    46     psMetadataAddString(config->arguments, PS_LIST_TAIL, "OUTPUT", 0, "Output root", data->outRoot);
    47 
    48     pmFPAfile *inFile = NULL;           // Representative input file
    49     for (int i = 0; i < data->numInputs; i++) {
    50         bool found = false;             // Found file definition?
    51         pmFPAfile *file = pmFPAfileDefineSingleFromArgs(&found, data->config, "PPSKYCELL.INPUT",
    52                                                         "INPUTS", i); // Input file
    53         if (!file || !found) {
    54             psError(psErrorCodeLast(), false, "Unable to define input %d\n", i);
     58    psArray *masks = NULL;              // Mask names
     59    if (data->masksName) {
     60        masks = fileList(data->masksName);
     61        if (!masks) {
     62            psError(psErrorCodeLast(), false, "No masks provided.");
     63            psFree(images);
    5564            return false;
    5665        }
    57         if (!inFile) {
    58             inFile = file;
     66        if (masks->n != data->numInputs) {
     67            psError(PS_ERR_BAD_PARAMETER_SIZE, true, "Number of images (%ld) and masks (%ld) do not match",
     68                    images->n, masks->n);
     69            psFree(images);
     70            psFree(masks);
     71            return false;
    5972        }
    6073    }
    6174
    62     pmFPAfile *outFile = pmFPAfileDefineFromFile(data->config, inFile, data->bin1, data->bin1,
    63                                                  "PPSKYCELL.JPEG1"); // Output file
    64     if (!outFile) {
     75    psMetadataAddStr(data->config->arguments, PS_LIST_TAIL, "OUTPUT", 0, "Output root", data->outRoot);
     76
     77    for (int i = 0; i < data->numInputs; i++) {
     78        bool status = false;             // Status of file definition
     79        fileArguments("IMAGE", images->data[i], "Name of the image", data->config);
     80        pmFPAfile *image = pmFPAfileDefineFromArgs(&status, data->config, "PPSKYCELL.IMAGE", "IMAGE"); // File
     81        if (!status || !image) {
     82            psError(PS_ERR_IO, false, "Failed to build file from PPSKYCELL.IMAGE");
     83            // XXX Cleanup
     84            return false;
     85        }
     86
     87        if (data->masksName) {
     88            fileArguments("MASK", masks->data[i], "Name of the mask", data->config);
     89            if (!pmFPAfileBindFromArgs(&status, image, data->config, "PPSKYCELL.MASK", "MASK") || !status) {
     90                psError(PS_ERR_IO, false, "Failed to build file from PPSKYCELL.MASK");
     91                // XXX Cleanup
     92                return false;
     93            }
     94        }
     95    }
     96
     97    if (!pmFPAfileDefineOutput(data->config, NULL, "PPSKYCELL.JPEG1")) {
    6598        psError(psErrorCodeLast(), false, "Unable to define output.");
    6699        return false;
    67100    }
    68     if (!pmFPAfileDefineFromFile(data->config, outFile, data->bin2, data->bin2, "PPSKYCELL.JPEG2")) {
     101    if (!pmFPAfileDefineOutput(data->config, NULL, "PPSKYCELL.JPEG2")) {
    69102        psError(psErrorCodeLast(), false, "Unable to define output.");
    70103        return false;
  • trunk/ppSkycell/src/ppSkycellLoop.c

    r23982 r23992  
    1111#define BUFFER 16                       // Size of buffer for projections
    1212
    13 static psRegion *skycellRegion(psRegion *region, // Current region of skycell, or NULL
    14                                pmAstromWCS *wcs, // World Coordinate System
     13// List of input files
     14static const char *inFiles[] = { "PPSKYCELL.IMAGE", "PPSKYCELL.MASK", NULL };
     15
     16// List of output files
     17//static const char *outFiles[] = { "PPSKYCELL.JPEG1", "PPSKYCELL.JPEG2", NULL };
     18
     19
     20static void regionMinMax(psRegion *base,// Base region; modified
     21                         const psRegion *compare // Comparison region
     22                         )
     23{
     24    base->x0 = PS_MIN(base->x0, compare->x0);
     25    base->x1 = PS_MAX(base->x1, compare->x1);
     26    base->y0 = PS_MIN(base->y0, compare->y0);
     27    base->y1 = PS_MAX(base->y1, compare->y1);
     28    return;
     29}
     30
     31static psRegion *skycellRegion(pmAstromWCS *wcs, // World Coordinate System
    1532                               int numCols, int numRows // Size of image
    1633    )
    1734{
    1835    psPlane *fromCoords = psPlaneAlloc(), *toCoords = psPlaneAlloc(); // Coordinates for transforms
    19     if (!region) {
    20         region = psRegionAlloc(INFINITY, -INFINITY, INFINITY, -INFINITY);
    21     }
     36    psRegion *region = psRegionAlloc(INFINITY, -INFINITY, INFINITY, -INFINITY); // Region for skycell
    2237
    2338// Limit the region using the nominated point (X,Y)
     
    2540    fromCoords->x = (X); \
    2641    fromCoords->y = (Y); \
    27     psPlaneTransform(toCoords, wcs->transform, fromCoords); \
     42    psPlaneTransformApply(toCoords, wcs->trans, fromCoords); \
    2843    toCoords->x += wcs->crpix1; \
    2944    toCoords->y += wcs->crpix2; \
     
    3348    region->y1 = PS_MAX(region->y1, toCoords->y);
    3449
    35     REGION_RANGE(0,0);                  // Lower left
    36     REGION_RANGE(0,numRows);            // Upper left
    37     REGION_RANGE(numCols,0);            // Lower right
    38     REGION_RANGE(numCols,numRows);      // Upper right
     50    REGION_RANGE(0, 0);                 // Lower left
     51    REGION_RANGE(0, numRows);           // Upper left
     52    REGION_RANGE(numCols, 0);           // Lower right
     53    REGION_RANGE(numCols, numRows);     // Upper right
    3954
    4055    return region;
     56}
     57
     58// Activate/deactivate a single element for a list
     59void fileActivationSingle(pmConfig *config, // Configuration
     60                          const char **files, // Files to turn on/off
     61                          bool state,   // Activation state
     62                          int num // Number of file in sequence
     63                          )
     64{
     65    assert(config);
     66    for (int i = 0; files[i] != NULL; i++) {
     67        pmFPAfileActivateSingle(config->files, state, files[i], num); // Activated file
     68    }
     69    return;
     70}
     71
     72// Iterate down the hierarchy, loading files; we can get away with this because we're working on skycells
     73static pmFPAview *filesIterateDown(pmConfig *config // Configuration
     74                                   )
     75{
     76    assert(config);
     77
     78    pmFPAview *view = pmFPAviewAlloc(0); // Pointer into FPA hierarchy
     79    if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
     80        return NULL;
     81    }
     82    view->chip = 0;
     83    if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
     84        return NULL;
     85    }
     86    view->cell = 0;
     87    if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
     88        return NULL;
     89    }
     90    view->readout = 0;
     91    if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
     92        return NULL;
     93    }
     94    return view;
     95}
     96
     97// Iterate up the hierarchy, writing files; we can get away with this because we're working on skycells
     98static bool filesIterateUp(pmConfig *config // Configuration
     99                           )
     100{
     101    assert(config);
     102
     103    pmFPAview *view = pmFPAviewAlloc(0); // Pointer into FPA hierarchy
     104    view->chip = view->cell = view->readout = 0;
     105    if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
     106        return false;
     107    }
     108    view->readout = -1;
     109    if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
     110        return false;
     111    }
     112    view->cell = -1;
     113    if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
     114        return false;
     115    }
     116    view->chip = -1;
     117    if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
     118        return false;
     119    }
     120    psFree(view);
     121    return true;
    41122}
    42123
     
    49130    psVector *cdelt1 = psVectorAllocEmpty(BUFFER, PS_TYPE_F64); // CDELT1 values
    50131    psVector *cdelt2 = psVectorAllocEmpty(BUFFER, PS_TYPE_F64); // CDELT2 values
    51     psArray *regions = psArrayAllocEmpty(BUFFER); // Region for projection
     132    psArray *projRegions = psArrayAllocEmpty(BUFFER); // Region for projection
    52133    int numProj = 0;                    // Number of projections
    53134
    54135    psVector *target = psVectorAlloc(data->numInputs, PS_TYPE_S32); // Target for each input
     136    psArray *imageRegions = psArrayAlloc(data->numInputs); // Region for image
    55137
    56138    for (int i = 0; i < data->numInputs; i++) {
     
    68150        int numRows = psMetadataLookupS32(NULL, hdu->header, "NAXIS2"); // Number of rows
    69151
    70         double xLow = wcs->crpix1 / fabs(wcs->crpix1) + wcs->cdelt2 / fabs(wcs->crpix2)
    71         double xHigh = numCols + wcs->crpix1 / fabs(wcs->crpix1) + numRows * wcs->cdelt2 / fabs(wcs->crpix2);
    72 
    73152        pmAstromWCS *wcs = pmAstromWCSfromHeader(hdu->header); // World Coordinate System
    74153        if (!wcs) {
     
    76155            return false;
    77156        }
     157
     158        psRegion *region = imageRegions->data[i] = skycellRegion(wcs, numCols, numRows); // Region of image
    78159
    79160        bool found = false;             // Found a projection?
     
    83164                wcs->cdelt1 == cdelt1->data.F64[j] &&
    84165                wcs->cdelt2 == cdelt1->data.F64[j]) {
    85                 skycellRegion(regions->data[j], wcs, numCols, numRows);
     166                regionMinMax(projRegions->data[j], region);
    86167                target->data.S32[i] = j;
     168                skycellRegion(wcs, numCols, numRows);
    87169                found = true;
    88170            }
     
    94176            psVectorAppend(cdelt1, wcs->cdelt1);
    95177            psVectorAppend(cdelt2, wcs->cdelt2);
    96             psArrayAdd(regions, regions->n, skycellRegion(NULL, wcs, numCols, numRows))
     178            psArrayAdd(projRegions, projRegions->n, region);
    97179            target->data.S32[i] = numProj;
    98180
     
    101183    }
    102184
     185    pmFPAfileActivate(data->config->files, false, NULL);
     186
     187    for (int i = 0; i < numProj; i++) {
     188        psRegion *projRegion = projRegions->data[i]; // Region for skycell projection
     189        int xSize = projRegion->x1 - projRegion->x0; // Size of unbinned image
     190        int ySize = projRegion->y1 - projRegion->y0; // Size of unbinned image
     191        // Size of binned image 1
     192        int numCols1 = xSize / (float)data->bin1 + 0.5, numRows1 = ySize / (float)data->bin1 + 0.5;
     193        // Size of binned image 2
     194        int numCols2 = numCols1 / (float)data->bin2 + 0.5, numRows2 = numRows2 / (float)data->bin1 + 0.5;
     195
     196        psImage *image1 = psImageAlloc(numCols1, numRows1, PS_TYPE_F32); // Binned image
     197        psImage *image2 = psImageAlloc(numCols2, numRows2, PS_TYPE_F32); // Binned image
     198        psImageInit(image1, 0);
     199        psImageInit(image2, 0);
     200
     201        for (int j = 0; j < data->numInputs; j++) {
     202            if (target->data.S32[j] != i) {
     203                continue;
     204            }
     205
     206            fileActivationSingle(data->config, inFiles, true, j);
     207            pmFPAview *view = filesIterateDown(data->config); // View to readout
     208            if (!view) {
     209                psError(psErrorCodeLast(), false, "Unable to iterate down.");
     210                // XXX Cleanup
     211                return false;
     212            }
     213
     214            pmFPAfile *file = pmFPAfileSelectSingle(data->config->files, "PPSKYCELL.IMAGE", j);
     215            pmReadout *inRO = pmFPAviewThisReadout(view, file->fpa); // Readout with input
     216            psFree(view);
     217
     218            pmReadout *bin1RO = pmReadoutAlloc(NULL), *bin2RO = pmReadoutAlloc(NULL); // Binned readouts
     219            if (!pmReadoutRebin(bin1RO, inRO, data->maskVal, data->bin1, data->bin1)) {
     220                psError(psErrorCodeLast(), false, "Unable to rebin image");
     221                // XXX Cleanup
     222                return false;
     223            }
     224            if (!pmReadoutRebin(bin2RO, bin1RO, data->maskVal, data->bin2, data->bin2)) {
     225                psError(psErrorCodeLast(), false, "Unable to rebin image");
     226                // XXX Cleanup
     227                return false;
     228            }
     229
     230            psRegion *imageRegion = imageRegions->data[j]; // Region for image
     231            // Offsets for image on skycell
     232            int xOffset1 = (imageRegion->x0 - projRegion->x0) / (float)data->bin1 + 0.5;
     233            int yOffset1 = (imageRegion->y0 - projRegion->y0) / (float)data->bin1 + 0.5;
     234            int xOffset2 = xOffset1 / (float)data->bin2 + 0.5, yOffset2 = yOffset1 / (float)data->bin2 + 0.5;
     235
     236            // XXX Completely neglecting rotations
     237            // The skycells are divided up neatly with them all having the same orientation
     238            psImageOverlaySection(image1, bin1RO->image, xOffset1, yOffset1, "=");
     239            psImageOverlaySection(image2, bin2RO->image, xOffset2, yOffset2, "=");
     240
     241            psFree(bin1RO);
     242            psFree(bin2RO);
     243            filesIterateUp(data->config);
     244        }
     245
     246        {
     247            psString filename = NULL;   // Filename for image
     248            psStringAppend(&filename, "skycell_%d_1.fits", i);
     249            psFits *fits = psFitsOpen(filename, "w");
     250            psFree(filename);
     251            psFitsWriteImage(fits, NULL, image1, 0, NULL);
     252            psFitsClose(fits);
     253        }
     254
     255        {
     256            psString filename = NULL;   // Filename for image
     257            psStringAppend(&filename, "skycell_%d_2.fits", i);
     258            psFits *fits = psFitsOpen(filename, "w");
     259            psFree(filename);
     260            psFitsWriteImage(fits, NULL, image2, 0, NULL);
     261            psFitsClose(fits);
     262        }
     263
     264        psFree(image1);
     265        psFree(image2);
     266    }
     267
     268    // XXX Cleanup
     269    return true;
     270}
  • trunk/ppSkycell/src/ppSkycellVersion.c

    r23982 r23992  
    1818#include <pslib.h>
    1919#include <psmodules.h>
    20 #include <ppStats.h>
    2120
    2221#include "ppSkycell.h"
     
    7877    psLibVersionHeader(header);
    7978    psModulesVersionHeader(header);
    80     ppStatsVersionHeader(header);
    8179
    8280    psString version = ppSkycellVersion(); // Software version
Note: See TracChangeset for help on using the changeset viewer.