IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 15516


Ignore:
Timestamp:
Nov 8, 2007, 12:59:04 PM (19 years ago)
Author:
eugene
Message:

accepting updates from HEAD

Location:
branches/eam_branch_20071023/psModules/src
Files:
25 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branch_20071023/psModules/src/camera/pmFPAConstruct.c

    r15218 r15516  
    4545    psMetadata *cellData = psMetadataLookupMetadata(&status, cells, cellName); // The data for the particular cell
    4646    if (!status || !cellData) {
    47         psLogMsg(__func__, PS_LOG_WARN, "Unable to find specs for cell %s: ignored\n", cellName);
     47        psWarning("Unable to find specs for cell %s: ignored\n", cellName);
    4848    }
    4949
     
    304304        // Put in the cell data
    305305        if (newCell->config) {
    306             psLogMsg(__func__, PS_LOG_WARN, "Overwriting cell data in chip\n");
     306            psWarning("Overwriting cell data in chip\n");
    307307            psFree(newCell->config); // Make way!
    308308        }
     
    13041304        const char *chipName = componentsItem->name; // Name of the chip
    13051305        if (componentsItem->type != PS_DATA_STRING) {
    1306             psLogMsg(__func__, PS_LOG_WARN, "Element %s in FPA within the camera configuration is not of "
     1306            psWarning("Element %s in FPA within the camera configuration is not of "
    13071307                     "type STR (type=%x) --- ignored.\n", chipName, componentsItem->type);
    13081308            continue;
  • branches/eam_branch_20071023/psModules/src/camera/pmFPAFlags.c

    r13190 r15516  
    136136
    137137    for (int i = 0; i < fpa->chips->n; i++) {
    138         pmChip *chip = fpa->chips->data[i];
    139         if (chip == NULL) continue;
    140         if (chip->data_exists) return true;
     138        pmChip *chip = fpa->chips->data[i];
     139        if (chip == NULL) continue;
     140        if (chip->data_exists) return true;
    141141    }
    142142    return false;
     
    170170
    171171    if (view->chip == -1) {
    172         bool exists = pmFPACheckDataStatus (fpa);
    173         return exists;
     172        bool exists = pmFPACheckDataStatus (fpa);
     173        return exists;
    174174    }
    175175
    176176    if (view->chip >= fpa->chips->n) {
    177         psError(PS_ERR_IO, true, "Requested chip == %d >= fpa->chips->n == %ld", view->chip, fpa->chips->n);
    178         return false;
     177        psError(PS_ERR_IO, true, "Requested chip == %d >= fpa->chips->n == %ld", view->chip, fpa->chips->n);
     178        return false;
    179179    }
    180180    pmChip *chip = fpa->chips->data[view->chip];
    181181
    182182    if (view->cell == -1) {
    183         bool exists = pmChipCheckDataStatus (chip);
    184         return exists;
     183        bool exists = pmChipCheckDataStatus (chip);
     184        return exists;
    185185    }
    186186
    187187    if (view->cell >= chip->cells->n) {
    188         psError(PS_ERR_IO, true, "Requested cell == %d >= chip->cells->n == %ld", view->cell, chip->cells->n);
    189         return false;
     188        psError(PS_ERR_IO, true, "Requested cell == %d >= chip->cells->n == %ld", view->cell, chip->cells->n);
     189        return false;
    190190    }
    191191    pmCell *cell = chip->cells->data[view->cell];
    192192
    193193    if (view->readout == -1) {
    194         bool exists = pmCellCheckDataStatus (cell);
    195         return exists;
     194        bool exists = pmCellCheckDataStatus (cell);
     195        return exists;
    196196    }
    197197
    198198    if (view->readout >= cell->readouts->n) {
    199         psError(PS_ERR_IO, true, "Requested readout == %d >= cell->readouds->n == %ld", view->readout, cell->readouts->n);
    200         return false;
     199        psError(PS_ERR_IO, true, "Requested readout == %d >= cell->readouds->n == %ld", view->readout, cell->readouts->n);
     200        return false;
    201201    }
    202202    pmReadout *readout = cell->readouts->data[view->readout];
     
    290290    psArray *chips = fpa->chips;        // Component chips
    291291    if (chips == NULL) {
    292         psLogMsg(__func__, PS_LOG_WARN, "WARNING: fpa->chips == NULL\n");
     292        psWarning("WARNING: fpa->chips == NULL\n");
    293293        return(0);
    294294    }
    295295    if ((chipNum >= chips->n) || (NULL == (pmChip *) chips->data[chipNum])) {
    296         psLogMsg(__func__, PS_LOG_WARN, "WARNING: the specified chip (%d) does not exist.\n", chipNum);
     296        psWarning("WARNING: the specified chip (%d) does not exist.\n", chipNum);
    297297        return(0);
    298298    }
  • branches/eam_branch_20071023/psModules/src/camera/pmFPAMosaic.c

    r15288 r15516  
    704704    psArray *readouts = cell->readouts; // The array of readouts
    705705    if (readouts->n > 1) {
    706         psLogMsg(__func__, PS_LOG_WARN, "Cell contains more than one readout (%ld) --- only the first will "
    707                  "be mosaicked.\n", readouts->n);
     706        psWarning("Cell contains more than one readout (%ld) --- only the first will be mosaicked.\n",
     707                  readouts->n);
    708708    }
    709709    pmReadout *readout = readouts->data[0]; // The only readout we'll bother with
     
    754754    int x0Target = psMetadataLookupS32(&mdok, targetCell->concepts, "CELL.X0");
    755755    if (!mdok) {
    756         psLogMsg(__func__, PS_LOG_WARN, "CELL.X0 is not set for the target cell; assuming 0.\n");
     756        psWarning("CELL.X0 is not set for the target cell; assuming 0.\n");
    757757        FIX_CONCEPT(targetCell->concepts, "CELL.X0", S32, 0);
    758758    }
    759759    int y0Target = psMetadataLookupS32(&mdok, targetCell->concepts, "CELL.Y0");
    760760    if (!mdok) {
    761         psLogMsg(__func__, PS_LOG_WARN, "CELL.Y0 is not set for the target cell; assuming 0.\n");
     761        psWarning("CELL.Y0 is not set for the target cell; assuming 0.\n");
    762762        FIX_CONCEPT(targetCell->concepts, "CELL.Y0", S32, 0);
    763763    }
    764764    int xParityTarget = psMetadataLookupS32(&mdok, targetCell->concepts, "CELL.XPARITY");
    765765    if (!mdok || (xParityTarget != -1 && xParityTarget != 1)) {
    766         psLogMsg(__func__, PS_LOG_WARN, "CELL.XPARITY is not set for the target cell; assuming 1.\n");
     766        psWarning("CELL.XPARITY is not set for the target cell; assuming 1.\n");
    767767        FIX_CONCEPT(targetCell->concepts, "CELL.XPARITY", S32, 1);
    768768        xParityTarget = 1;
     
    770770    int yParityTarget = psMetadataLookupS32(&mdok, targetCell->concepts, "CELL.YPARITY");
    771771    if (!mdok || (yParityTarget != -1 && yParityTarget != 1)) {
    772         psLogMsg(__func__, PS_LOG_WARN, "CELL.YPARITY is not set for the target cell; assuming 1.\n");
     772        psWarning("CELL.YPARITY is not set for the target cell; assuming 1.\n");
    773773        FIX_CONCEPT(targetCell->concepts, "CELL.YPARITY", S32, 1);
    774774        yParityTarget = 1;
     
    863863    int x0Target = psMetadataLookupS32(&mdok, targetChip->concepts, "CHIP.X0");
    864864    if (!mdok) {
    865         psLogMsg(__func__, PS_LOG_WARN, "CHIP.X0 is not set for the target chip; assuming 0.\n");
     865        psWarning("CHIP.X0 is not set for the target chip; assuming 0.\n");
    866866        FIX_CONCEPT(targetChip->concepts, "CHIP.X0", S32, 0);
    867867    }
    868868    int y0Target = psMetadataLookupS32(&mdok, targetChip->concepts, "CHIP.Y0");
    869869    if (!mdok) {
    870         psLogMsg(__func__, PS_LOG_WARN, "CHIP.Y0 is not set for the target chip; assuming 0.\n");
     870        psWarning("CHIP.Y0 is not set for the target chip; assuming 0.\n");
    871871        FIX_CONCEPT(targetChip->concepts, "CHIP.Y0", S32, 0);
    872872    }
    873873    x0Target += psMetadataLookupS32(&mdok, targetCell->concepts, "CELL.X0");
    874874    if (!mdok) {
    875         psLogMsg(__func__, PS_LOG_WARN, "CELL.X0 is not set for the target cell; assuming 0.\n");
     875        psWarning("CELL.X0 is not set for the target cell; assuming 0.\n");
    876876        FIX_CONCEPT(targetCell->concepts, "CELL.X0", S32, 0);
    877877    }
    878878    y0Target += psMetadataLookupS32(&mdok, targetCell->concepts, "CELL.Y0");
    879879    if (!mdok) {
    880         psLogMsg(__func__, PS_LOG_WARN, "CELL.Y0 is not set for the target cell; assuming 0.\n");
     880        psWarning("CELL.Y0 is not set for the target cell; assuming 0.\n");
    881881        FIX_CONCEPT(targetCell->concepts, "CELL.Y0", S32, 0);
    882882    }
    883883    int xParityChipTarget = psMetadataLookupS32(&mdok, targetChip->concepts, "CHIP.XPARITY");
    884884    if (!mdok || (xParityChipTarget != -1 && xParityChipTarget != 1)) {
    885         psLogMsg(__func__, PS_LOG_WARN, "CHIP.XPARITY is not set for the target chip; assuming 1.\n");
     885        psWarning("CHIP.XPARITY is not set for the target chip; assuming 1.\n");
    886886        FIX_CONCEPT(targetChip->concepts, "CHIP.XPARITY", S32, 1);
    887887        xParityChipTarget = 1;
     
    889889    int yParityChipTarget = psMetadataLookupS32(&mdok, targetChip->concepts, "CHIP.YPARITY");
    890890    if (!mdok || (yParityChipTarget != -1 && yParityChipTarget != 1)) {
    891         psLogMsg(__func__, PS_LOG_WARN, "CHIP.YPARITY is not set for the target chip; assuming 1.\n");
     891        psWarning("CHIP.YPARITY is not set for the target chip; assuming 1.\n");
    892892        FIX_CONCEPT(targetChip->concepts, "CHIP.YPARITY", S32, 1);
    893893        yParityChipTarget = 1;
     
    895895    int xParityCellTarget = psMetadataLookupS32(&mdok, targetCell->concepts, "CELL.XPARITY");
    896896    if (!mdok || (xParityCellTarget != -1 && xParityCellTarget != 1)) {
    897         psLogMsg(__func__, PS_LOG_WARN, "CELL.XPARITY is not set for the target cell; assuming 1.\n");
     897        psWarning("CELL.XPARITY is not set for the target cell; assuming 1.\n");
    898898        FIX_CONCEPT(targetCell->concepts, "CELL.XPARITY", S32, 1);
    899899        xParityCellTarget = 1;
     
    901901    int yParityCellTarget = psMetadataLookupS32(&mdok, targetCell->concepts, "CELL.YPARITY");
    902902    if (!mdok || (yParityCellTarget != -1 && yParityCellTarget != 1)) {
    903         psLogMsg(__func__, PS_LOG_WARN, "CELL.YPARITY is not set for the target cell; assuming 1.\n");
     903        psWarning("CELL.YPARITY is not set for the target cell; assuming 1.\n");
    904904        FIX_CONCEPT(targetCell->concepts, "CELL.YPARITY", S32, 1);
    905905        yParityCellTarget = 1;
     
    13341334    pmHDU *sourceHDU = pmHDUGetHighest(source, firstSourceChip, firstSourceCell); // The HDU for the source
    13351335    if (!sourceHDU) {
    1336         psLogMsg(__func__, PS_LOG_WARN, "Unable to find HDU in source FPA; unable to copy headers.\n");
     1336        psWarning("Unable to find HDU in source FPA; unable to copy headers.\n");
    13371337        return false;
    13381338    }
    13391339    pmHDU *targetHDU = pmHDUGetHighest(target, targetChip, targetCell); // The HDU for the target
    13401340    if (!targetHDU) {
    1341         psLogMsg(__func__, PS_LOG_WARN, "Unable to find HDU in target FPA; unable to copy headers.\n");
     1341        psWarning("Unable to find HDU in target FPA; unable to copy headers.\n");
    13421342        return false;
    13431343    }
  • branches/eam_branch_20071023/psModules/src/camera/pmHDU.c

    r12696 r15516  
    119119
    120120    if (*images) {
    121         psLogMsg(__func__, PS_LOG_WARN, "HDU %s has already been read --- overwriting.\n", hdu->extname);
     121        psWarning("HDU %s has already been read --- overwriting.\n", hdu->extname);
    122122        psFree(*images);                // Blow away anything existing
    123123    }
     
    167167
    168168    if (!images && !hdu->header) {
    169         psLogMsg(__func__, PS_LOG_WARN, "Nothing to write for HDU %s\n", hdu->extname);
     169        psWarning("Nothing to write for HDU %s\n", hdu->extname);
    170170        return false;
    171171    }
  • branches/eam_branch_20071023/psModules/src/camera/pmHDUGenerate.c

    r15327 r15516  
    134134    psMetadataItem *biassecItem = psMetadataLookup(cell->concepts, "CELL.BIASSEC"); // Bias sections
    135135    if (!biassecItem) {
    136         psLogMsg(__func__, PS_LOG_WARN, "CELL.BIASSEC has not been initialised in cell --- "
    137                  "ignored.\n");
     136        psWarning("CELL.BIASSEC has not been initialised in cell --- ignored.\n");
    138137        return false;
    139138    }
     
    146145    if (!mdok || (cellreaddir != 1 && cellreaddir != 2)) {
    147146        // Probably unnecessary, but just in case....
    148         psLogMsg(__func__, PS_LOG_WARN, "CELL.READDIR is not set in cell --- ignored.\n");
     147        psWarning("CELL.READDIR is not set in cell --- ignored.\n");
    149148        return false;
    150149    }
     
    152151        *readdir = cellreaddir;
    153152    } else if (*readdir != cellreaddir) {
    154         psLogMsg(__func__, PS_LOG_WARN, "CELL.READDIR does not match read direction for HDU --- ignored.\n");
     153        psWarning("CELL.READDIR does not match read direction for HDU --- ignored.\n");
    155154        return false;
    156155    }
     
    255254        psMetadataItem *trimsecItem = psMetadataLookup(cell->concepts, "CELL.TRIMSEC"); // Item with trimsec
    256255        if (!trimsecItem || trimsecItem->type != PS_DATA_REGION) {
    257             psLogMsg(__func__, PS_LOG_WARN, "CELL.TRIMSEC has not been initialised in cell --- "
    258                      "ignored.\n");
     256            psWarning("CELL.TRIMSEC has not been initialised in cell --- ignored.\n");
    259257            continue;
    260258        }
     
    264262        if (!mdok || (cellreaddir != 1 && cellreaddir != 2)) {
    265263            // Probably unnecessary, but just in case....
    266             psLogMsg(__func__, PS_LOG_WARN, "CELL.READDIR is not set in cell --- ignored.\n");
     264            psWarning("CELL.READDIR is not set in cell --- ignored.\n");
    267265            continue;
    268266        }
     
    270268            readdir = cellreaddir;
    271269        } else if (readdir != cellreaddir) {
    272             psLogMsg(__func__, PS_LOG_WARN, "CELL.READDIR for cells within the HDU do not match!\n");
     270            psWarning("CELL.READDIR for cells within the HDU do not match!\n");
    273271            cellreaddir = readdir;
    274272        }
     
    282280        if (readout->mask &&
    283281                (readout->mask->numCols != image->numCols || readout->mask->numRows != image->numRows)) {
    284             psLogMsg(__func__, PS_LOG_WARN, "Image and mask have different sizes (%dx%d vs %dx%d)!\n",
     282            psWarning("Image and mask have different sizes (%dx%d vs %dx%d)!\n",
    285283                     image->numCols, image->numRows, readout->mask->numCols, readout->mask->numRows);
    286284        }
    287285        if (readout->weight &&
    288286                (readout->weight->numCols != image->numCols || readout->weight->numRows != image->numRows)) {
    289             psLogMsg(__func__, PS_LOG_WARN, "Image and weight have different sizes (%dx%d vs %dx%d)!\n",
     287            psWarning("Image and weight have different sizes (%dx%d vs %dx%d)!\n",
    290288                     image->numCols, image->numRows, readout->weight->numCols, readout->weight->numRows);
    291289        }
     
    318316
    319317    if (previous != current) {
    320         psLogMsg(__func__, PS_LOG_WARN, "Images within the HDU are of different types "
    321                  "(%x vs %x) --- promoting\n", previous, current);
     318        psWarning("Images within the HDU are of different types (%x vs %x) --- promoting\n",
     319                  previous, current);
    322320        return PS_MAX(previous, current);
    323321    }
     
    336334    if (source->numCols != region->x1 - region->x0 || source->numRows != region->y1 - region->y0) {
    337335        psString regionString = psRegionToString(*region);
    338         psLogMsg(__func__, PS_LOG_WARN, "Image size (%dx%d) does not match region (%s).\n",
     336        psWarning("Image size (%dx%d) does not match region (%s).\n",
    339337                 source->numCols, source->numRows, regionString);
    340338        psFree(regionString);
     
    475473
    476474                if (biassecs->n != readout->bias->n) {
    477                     psLogMsg(__func__, PS_LOG_WARN, "Number of bias sections (%ld) and number of biases (%ld)"
    478                              " do not match.\n", biassecs->n, readout->bias->n);
     475                    psWarning("Number of bias sections (%ld) and number of biases (%ld) do not match.\n",
     476                              biassecs->n, readout->bias->n);
    479477                }
    480478                psListIterator *biasIter = psListIteratorAlloc(readout->bias, PS_LIST_HEAD, false); // Iteratr
  • branches/eam_branch_20071023/psModules/src/camera/pmReadoutFake.c

    r15399 r15516  
    3535    pmReadout *readout = pmReadoutAlloc(NULL); // Output readout
    3636    readout->image = psImageAlloc(numCols, numRows, PS_TYPE_F32);
     37    psImageInit(readout->image, 0);
    3738
    3839    int numSources = sources->n;          // Number of stars
     
    8687        fakeModel->params->data.F32[PM_PAR_I0] = powf(10.0, -0.4 * source->psfMag) / flux0;
    8788
     89        psTrace("psModules.camera", 10, "Adding source at %f,%f with flux %f\n",
     90                fakeModel->params->data.F32[PM_PAR_XPOS], fakeModel->params->data.F32[PM_PAR_YPOS],
     91                fakeModel->params->data.F32[PM_PAR_I0]);
     92
    8893        pmSource *fakeSource = pmSourceAlloc(); // Fake source to generate
    8994        fakeSource->peak = pmPeakAlloc(x, y, fakeModel->params->data.F32[PM_PAR_I0], PM_PEAK_LONE);
  • branches/eam_branch_20071023/psModules/src/concepts/pmConceptsAverage.h

    r15399 r15516  
    44 * @author Paul Price, IfA
    55 *
    6  * @version $Revision: 1.9.10.1 $ $Name: not supported by cvs2svn $
    7  * @date $Date: 2007-10-29 01:40:54 $
     6 * @version $Revision: 1.9.10.2 $ $Name: not supported by cvs2svn $
     7 * @date $Date: 2007-11-08 22:59:04 $
    88 * Copyright 2005-2006 Institute for Astronomy, University of Hawaii
    99 */
  • branches/eam_branch_20071023/psModules/src/concepts/pmConceptsStandard.c

    r15300 r15516  
    375375    assert(pattern);
    376376
    377     psList *biassecs; // List of bias sections
     377    psList *biassecs = NULL; // List of bias sections
    378378
    379379    switch (concept->type) {
  • branches/eam_branch_20071023/psModules/src/config/pmConfig.c

    r15399 r15516  
    661661            if (!cameraReadFormats(item->data.md, item->name)) {
    662662                psWarning("Unable to read formats for camera %s: removed.\n", item->name);
     663                psErrorStackPrint(stderr, "errors from read failure\n");
     664                psErrorClear();
    663665                psMetadataRemoveKey(cameras, item->name);
     666                continue;
    664667            }
    665668            if (!cameraReadCalibrations(item->data.md, item->name)) {
    666669                psWarning("Unable to read calibrations for camera %s: removed.\n", item->name);
     670                psErrorStackPrint(stderr, "errors from read failure\n");
     671                psErrorClear();
    667672                psMetadataRemoveKey(cameras, item->name);
     673                continue;
    668674            }
    669675        }
  • branches/eam_branch_20071023/psModules/src/config/pmConfig.h

    r15399 r15516  
    55 *  @author Eugene Magnier, IfA
    66 *
    7  *  @version $Revision: 1.31.2.1 $ $Name: not supported by cvs2svn $
    8  *  @date $Date: 2007-10-29 01:40:54 $
     7 *  @version $Revision: 1.31.2.2 $ $Name: not supported by cvs2svn $
     8 *  @date $Date: 2007-11-08 22:59:04 $
    99 *
    1010 *  Copyright 2005-2006 Institute for Astronomy, University of Hawaii
  • branches/eam_branch_20071023/psModules/src/config/pmConfigCamera.c

    r15289 r15516  
    464464    while ((formatsItem = psMetadataGetAndIncrement(formatsIter))) {
    465465        assert(formatsItem->type == PS_DATA_METADATA); // We should have read it by now!
    466         psMetadata *format = formatsItem->data.V; // The camera format
     466        psMetadata *format = formatsItem->data.md; // The camera format
    467467
    468468        // Add a new RULE which uniquely describes the mosaicked format.  this is needed so
  • branches/eam_branch_20071023/psModules/src/config/pmConfigRecipes.c

    r12916 r15516  
    55#include <stdio.h>
    66#include <string.h>
    7 #include <strings.h>            /* for strn?casecmp */
     7#include <strings.h>            /* for strn?casecmp */
    88#include <unistd.h>
    99#include <libgen.h>
     
    3333        options = psMetadataAlloc ();
    3434        success = psMetadataAddPtr (config->arguments, PS_LIST_TAIL, "OPTIONS",  PS_DATA_METADATA, "", options);
    35         assert (success); // type mismatch : OPTIONS already defined but wrong type
    36         psFree (options); // drop extra reference
     35        assert (success); // type mismatch : OPTIONS already defined but wrong type
     36        psFree (options); // drop extra reference
    3737    }
    3838
     
    4444        recipe = psMetadataAlloc();
    4545        success = psMetadataAddPtr(options, PS_LIST_TAIL, recipeName,  PS_DATA_METADATA, "", recipe);
    46         assert (success); // type mismatch : OPTIONS already defined but wrong type
    47         psFree (recipe);  // drop extra reference
     46        assert (success); // type mismatch : OPTIONS already defined but wrong type
     47        psFree (recipe);  // drop extra reference
    4848    }
    4949    return recipe;
     
    6767    // master recipe files in the site:recipe location when they are built.
    6868    if (config->site && (source & PM_RECIPE_SOURCE_SITE)) {
    69         if (!loadRecipeSite(&status, config, config->site)) {
     69        if (!loadRecipeSite(&status, config, config->site)) {
    7070            psError(PS_ERR_IO, false, "Failed to read recipes from site config");
    71             return false;
    72         } 
    73         psTrace ("psModules.config", 3, "read recipes from site config");
     71            return false;
     72        }
     73        psTrace ("psModules.config", 3, "read recipes from site config");
    7474    }
    7575
     
    8181        if (!loadRecipeCamera(&status, config, config->camera)) {
    8282            psError(PS_ERR_IO, false, "Failed to read recipes from camera config");
    83             return false;
    84         } 
    85         if (status) {
    86             psTrace ("psModules.config", 3, "read recipes from camera config");
    87         } else {
    88             psLogMsg ("psModules.config", PS_LOG_DETAIL, "no recipe supplied by camera config");
    89         }
     83            return false;
     84        }
     85        if (status) {
     86            psTrace ("psModules.config", 3, "read recipes from camera config");
     87        } else {
     88            psLogMsg ("psModules.config", PS_LOG_DETAIL, "no recipe supplied by camera config");
     89        }
    9090    }
    9191
     
    9494        if (!loadRecipeFromArguments(&status, config)) {
    9595            psError(PS_ERR_IO, false, "Failed to read recipes from command-line arguments");
    96             return false;
    97         } 
    98         if (status) {
    99             psTrace ("psModules.config", 3, "read recipes from command-line arguments");
    100         } else {
    101             psLogMsg ("psModules.config", PS_LOG_DETAIL, "no recipe supplied on command-line arguments");
    102         }
     96            return false;
     97        }
     98        if (status) {
     99            psTrace ("psModules.config", 3, "read recipes from command-line arguments");
     100        } else {
     101            psLogMsg ("psModules.config", PS_LOG_DETAIL, "no recipe supplied on command-line arguments");
     102        }
    103103        if (!loadRecipeSymbols(&status, config)) {
    104104            psError(PS_ERR_IO, false, "Failed to read recipes from symbolic references");
    105             return false;
    106         } 
    107         if (status) {
    108             psTrace ("psModules.config", 3, "read recipes from symbolic references");
    109         } else {
    110             psLogMsg ("psModules.config", PS_LOG_DETAIL, "no recipe supplied by symbolic reference");
    111         }
     105            return false;
     106        }
     107        if (status) {
     108            psTrace ("psModules.config", 3, "read recipes from symbolic references");
     109        } else {
     110            psLogMsg ("psModules.config", PS_LOG_DETAIL, "no recipe supplied by symbolic reference");
     111        }
    112112        if (!loadRecipeOptions(&status, config)) {
    113113            psError(PS_ERR_IO, false, "Failed to read recipes from symbolic references");
    114             return false;
    115         } 
    116         if (status) {
     114            return false;
     115        }
     116        if (status) {
    117117            psTrace ("psModules.config", 3, "read recipes from command-line arguments");
    118118        } else {
     
    135135        options = psMetadataAlloc();
    136136        success = psMetadataAddPtr(config->arguments, PS_LIST_TAIL, "OPTIONS",  PS_DATA_METADATA, "Command-line options specified with -D", options);
    137         assert (success); // type mismatch : OPTIONS already defined but wrong type
    138         psFree (options); // drop extra reference
     137        assert (success); // type mismatch : OPTIONS already defined but wrong type
     138        psFree (options); // drop extra reference
    139139    }
    140140
     
    176176            recipe = psMetadataAlloc();
    177177            success = psMetadataAddPtr(options, PS_LIST_TAIL, recipeName,  PS_DATA_METADATA, "", recipe);
    178             assert (success); // type mismatch : recipe already defined but wrong type
    179             psFree (recipe); // drop extra reference
     178            assert (success); // type mismatch : recipe already defined but wrong type
     179            psFree (recipe); // drop extra reference
    180180        }
    181181
     
    216216bool pmConfigLoadRecipeArguments (int *argc, char **argv, pmConfig *config)
    217217{
    218     bool success; 
     218    bool success;
    219219
    220220    psMetadata *recipes = psMetadataLookupMetadata(&success, config->arguments, "RECIPES");
     
    222222        recipes = psMetadataAlloc();
    223223        success = psMetadataAddPtr (config->arguments, PS_LIST_TAIL, "RECIPES",  PS_DATA_METADATA, "", recipes);
    224         assert (success);
    225         psFree (recipes);
     224        assert (success);
     225        psFree (recipes);
    226226    }
    227227
     
    271271// Load the recipe files for SITE : REQUIRED
    272272static bool loadRecipeSite(bool *status,
    273                            pmConfig *config, // The configuration into which to read the recipes
    274                            psMetadata *source // The source configuration, from which to read the filenames
     273                           pmConfig *config, // The configuration into which to read the recipes
     274                           psMetadata *source // The source configuration, from which to read the filenames
    275275    )
    276276{
     
    300300        if (fileItem->type != PS_DATA_STRING) {
    301301            psError(PS_ERR_IO, true, "%s in site configuration RECIPES is not of type STR", fileItem->name);
    302             return false;
     302            return false;
    303303        }
    304304
    305305        // Read the recipe file. if we fail on a file, give a warning, but continue
    306306        psMetadata *recipe = NULL;
    307         if (!pmConfigFileRead(&recipe, fileItem->data.V, "recipe")) {
    308             psError(PS_ERR_IO, false, "Failed to read recipe file %s listed in site configuration\n", (char *)fileItem->data.V);
    309             return false;
     307        if (!pmConfigFileRead(&recipe, fileItem->data.str, "recipe")) {
     308            psError(PS_ERR_IO, false, "Failed to read recipe file %s listed in site configuration\n",
     309                    fileItem->data.str);
     310            return false;
    310311        }
    311312
    312313        // if this named recipe exists, supplement it
    313         psMetadataAdd(config->recipes, PS_LIST_TAIL, fileItem->name, PS_DATA_METADATA | PS_META_REPLACE,
    314                       fileItem->comment, recipe);
     314        psMetadataAdd(config->recipes, PS_LIST_TAIL, fileItem->name, PS_DATA_METADATA | PS_META_REPLACE,
     315                      fileItem->comment, recipe);
    315316        psFree(recipe);  // Drop reference
    316317    }
     
    326327// for sourceType == SITE | CAMERA, RECIPES contains a list of files to be read (pmConfigFileRead)
    327328static bool loadRecipeCamera(bool *status, // status variable
    328                              pmConfig *config, // The configuration into which to read the recipes
    329                              psMetadata *source // The source configuration, from which to read the filenames
     329                             pmConfig *config, // The configuration into which to read the recipes
     330                             psMetadata *source // The source configuration, from which to read the filenames
    330331    )
    331332{
     
    345346    psMetadata *recipes = psMetadataLookupMetadata(&success, source, "RECIPES"); // The list of recipes
    346347    if (!recipes) {
    347         psTrace ("psModules.config", 3, "RECIPES not found in the camera configuration\n");
     348        psTrace ("psModules.config", 3, "RECIPES not found in the camera configuration\n");
    348349        return true;
    349350    }
     
    355356    psMetadataItem *fileItem = NULL;    // MD item containing the filename, from recipe iteration
    356357    while ((fileItem = psMetadataGetAndIncrement(recipesIter))) {
    357         char *recipeName = fileItem->name;
    358         char *recipeFile = fileItem->data.V;
    359 
    360         psTrace("psModules.config", 3, "Supplementing %s from %s within camera configuration.\n", recipeName, recipeFile);
     358        char *recipeName = fileItem->name;
     359        char *recipeFile = fileItem->data.str;
     360
     361        psTrace("psModules.config", 3, "Supplementing %s from %s within camera configuration.\n", recipeName, recipeFile);
    361362
    362363        // type mismatch is a serious error
     
    368369        psMetadata *recipe = NULL;
    369370        if (!pmConfigFileRead(&recipe, recipeFile, "recipe")) {
    370             psError(PS_ERR_IO, false, "Failed to read recipe file %s listed in camera configuration\n", recipeFile);
    371             return false;
     371            psError(PS_ERR_IO, false, "Failed to read recipe file %s listed in camera configuration\n",
     372                    recipeFile);
     373            return false;
    372374        }
    373375
    374376        // the named recipe must exist; supplement it
    375         psMetadata *current = psMetadataLookupMetadata(NULL, config->recipes, recipeName);
    376         if (!current) {
    377             psError(PS_ERR_IO, false, "Failed to find recipe for %s in master recipe list", recipeName);
    378             psFree(recipe);  // Drop reference
    379             return false;
    380         }
    381 
    382         if (!psMetadataUpdate(current, recipe)) {
    383             psError(PS_ERR_IO, false, "Failed to update recipe for %s from camera recipe", recipeName);
    384             psFree(recipe);  // Drop reference
    385             return false;
    386         }
     377        psMetadata *current = psMetadataLookupMetadata(NULL, config->recipes, recipeName);
     378        if (!current) {
     379            psError(PS_ERR_IO, false, "Failed to find recipe for %s in master recipe list", recipeName);
     380            psFree(recipe);  // Drop reference
     381            return false;
     382        }
     383
     384        if (!psMetadataUpdate(current, recipe)) {
     385            psError(PS_ERR_IO, false, "Failed to update recipe for %s from camera recipe", recipeName);
     386            psFree(recipe);  // Drop reference
     387            return false;
     388        }
    387389        psFree(recipe);  // Drop reference
    388390    }
     
    397399// entries for an existing recipe metadata
    398400static bool loadRecipeFromArguments(bool *status,
    399                                     pmConfig *config // The configuration into which to read the recipes
     401                                    pmConfig *config // The configuration into which to read the recipes
    400402    )
    401403{
     
    425427        // increment the ref counter to protect the data
    426428
    427         psMetadata *recipe = item->data.V; // Recipe of interest
     429        psMetadata *recipe = item->data.md; // Recipe of interest
    428430
    429431        // if this named recipe exists, supplement it
    430432        psMetadata *current = psMetadataLookupMetadata(NULL, config->recipes, item->name);
    431433        if (!current) {
    432             psError(PS_ERR_IO, false, "Failed to find recipe for %s in master recipe list", item->name);
    433             psFree(recipe);  // Drop reference
    434             return false;
    435         }
    436         psTrace("psModules.config", 3, "Supplementing %s from arguments.\n", item->name);
     434            psError(PS_ERR_IO, false, "Failed to find recipe for %s in master recipe list", item->name);
     435            psFree(recipe);  // Drop reference
     436            return false;
     437        }
     438        psTrace("psModules.config", 3, "Supplementing %s from arguments.\n", item->name);
    437439
    438440        if (!psMetadataUpdate (current, recipe)) {
    439             psError(PS_ERR_IO, false, "Failed to update recipe for %s from camera recipe", item->name);
    440             return false;
    441         }
     441            psError(PS_ERR_IO, false, "Failed to update recipe for %s from camera recipe", item->name);
     442            return false;
     443        }
    442444    }
    443445    psFree(recipesIter);
     
    449451// entries for an existing recipe metadata
    450452static bool loadRecipeSymbols(bool *status,
    451                               pmConfig *config // The configuration into which to read the recipes
     453                              pmConfig *config // The configuration into which to read the recipes
    452454    )
    453455{
     
    465467    while ((item = psMetadataGetAndIncrement(iter))) {
    466468        assert(item->type == PS_DATA_STRING); // It should be this type: we put it in ourselves
    467         const char *sourceName = item->data.V; // The name of the symbolic reference
     469        const char *sourceName = item->data.str; // The name of the symbolic reference
    468470        const char *targetName = item->name;
    469         psTrace("psModules.config", 3, "Supplementing %s from %s.\n", targetName, sourceName);
    470 
    471         // the target recipe must exist; select it
    472         psMetadata *targetMD = psMetadataLookupMetadata(&found, config->recipes, targetName);
    473         if (!targetMD) {
    474             psError(PS_ERR_IO, true, "Failed to find recipe for %s in master recipe list", targetName);
    475             return false;
    476         }
     471        psTrace("psModules.config", 3, "Supplementing %s from %s.\n", targetName, sourceName);
     472
     473        // the target recipe must exist; select it
     474        psMetadata *targetMD = psMetadataLookupMetadata(&found, config->recipes, targetName);
     475        if (!targetMD) {
     476            psError(PS_ERR_IO, true, "Failed to find recipe for %s in master recipe list", targetName);
     477            return false;
     478        }
    477479
    478480        // search for sourceName : it may be in config->recipes or target MD
    479481        psMetadata *sourceMD = NULL;
    480         sourceMD = psMetadataLookupMetadata(&found, config->recipes, sourceName);
     482        sourceMD = psMetadataLookupMetadata(&found, config->recipes, sourceName);
    481483        if (!sourceMD) {
    482             sourceMD = psMetadataLookupMetadata(&found, targetMD, sourceName);
    483             if (!sourceMD) {
    484                 psError(PS_ERR_IO, false, "Selected symbolic name %s does not exist in recipes", sourceName);
    485                 return false;
    486             }
    487         }
    488 
    489         if (!psMetadataUpdate(targetMD, sourceMD)) {
    490             psError(PS_ERR_IO, false, "Failed to update recipe for %s from camera recipe", targetName);
    491             return false;
    492         }
     484            sourceMD = psMetadataLookupMetadata(&found, targetMD, sourceName);
     485            if (!sourceMD) {
     486                psError(PS_ERR_IO, false, "Selected symbolic name %s does not exist in recipes", sourceName);
     487                return false;
     488            }
     489        }
     490
     491        if (!psMetadataUpdate(targetMD, sourceMD)) {
     492            psError(PS_ERR_IO, false, "Failed to update recipe for %s from camera recipe", targetName);
     493            return false;
     494        }
    493495    }
    494496    psFree(iter);
     
    501503// entries for an existing recipe metadata
    502504static bool loadRecipeOptions(bool *status,
    503                               pmConfig *config // The configuration into which to read the recipes
     505                              pmConfig *config // The configuration into which to read the recipes
    504506    )
    505507{
     
    524526    psMetadataItem *item = NULL;    // MD item containing the filename, from recipe iteration
    525527    while ((item = psMetadataGetAndIncrement(recipesIter))) {
    526         char *recipeName = item->name;
    527         psMetadata *recipe = item->data.V;
     528        char *recipeName = item->name;
     529        psMetadata *recipe = item->data.md;
    528530
    529531        // type mismatch is a serious error
     
    535537        psMetadata *current = psMetadataLookupMetadata(NULL, config->recipes, recipeName);
    536538        if (!current) {
    537             psError(PS_ERR_IO, false, "Selected recipe %s is not found in camera recipe", recipeName);
    538             return false;
    539         }
     539            psError(PS_ERR_IO, false, "Selected recipe %s is not found in camera recipe", recipeName);
     540            return false;
     541        }
    540542        if (!psMetadataUpdate (current, recipe)) {
    541             psError(PS_ERR_IO, false, "Failed to update recipe for %s from camera recipe", recipeName);
    542             return false;
    543         }
     543            psError(PS_ERR_IO, false, "Failed to update recipe for %s from camera recipe", recipeName);
     544            return false;
     545        }
    544546    }
    545547    psFree(recipesIter);
  • branches/eam_branch_20071023/psModules/src/imcombine/pmReadoutCombine.c

    r14355 r15516  
    315315            // Combination
    316316            if (!psVectorStats(stats, pixels, errors, mask, 1)) {
    317                 psError(PS_ERR_UNKNOWN, false, "Error in statistics.");
    318                 psFree(index);
    319                 psFree(pixels);
    320                 psFree(mask);
    321                 psFree(weights);
    322                 psFree(errors);
    323                 psFree(stats);
    324                 psFree(invScale);
    325                 return false;
    326             }
    327 
    328             outputImage[yOut][xOut] = psStatsGetValue(stats, params->combine);
    329             if (!isfinite(outputImage[yOut][xOut])) {
     317                // Can't do much about it, but it's not worth worrying about
     318                psErrorClear();
     319                outputImage[yOut][xOut] = NAN;
    330320                outputMask[yOut][xOut] = params->blank;
    331             }
    332             if (params->weights) {
    333                 float stdev = psStatsGetValue(stats, combineStdev);
    334                 outputWeight[yOut][xOut] = PS_SQR(stdev); // Variance
    335                 // XXXX this is not the correct formal error.
    336                 // also, the weighted mean is not obviously the correct thing here
     321                if (params->weights) {
     322                    outputWeight[yOut][xOut] = NAN;
     323                }
     324            } else {
     325                outputImage[yOut][xOut] = psStatsGetValue(stats, params->combine);
     326                if (!isfinite(outputImage[yOut][xOut])) {
     327                    outputMask[yOut][xOut] = params->blank;
     328                }
     329                if (params->weights) {
     330                    float stdev = psStatsGetValue(stats, combineStdev);
     331                    outputWeight[yOut][xOut] = PS_SQR(stdev); // Variance
     332                    // XXXX this is not the correct formal error.
     333                    // also, the weighted mean is not obviously the correct thing here
     334                }
    337335            }
    338336        }
  • branches/eam_branch_20071023/psModules/src/imcombine/pmStack.c

    r15399 r15516  
    88 *  @author GLG, MHPCC
    99 *
    10  *  @version $Revision: 1.13.8.1 $ $Name: not supported by cvs2svn $
    11  *  @date $Date: 2007-10-29 01:40:54 $
     10 *  @version $Revision: 1.13.8.2 $ $Name: not supported by cvs2svn $
     11 *  @date $Date: 2007-11-08 22:59:04 $
    1212 *
    1313 *  Copyright 2004-2007 Institute for Astronomy, University of Hawaii
  • branches/eam_branch_20071023/psModules/src/imcombine/pmStackReject.c

    r14701 r15516  
    5252
    5353    // Convolve the image with the kernel --- we're basically applying a matched filter and then thresholding
    54     psImage *convolved = NULL;          // Convolved image
     54    pmReadout *convRO = pmReadoutAlloc(NULL); // Readout with convolved image
     55    pmReadout *inRO = pmReadoutAlloc(NULL); // Readout with input image
     56    inRO->image = image;
    5557    for (int i = 0; i < numRegions; i++) {
    5658        psRegion *region = regions->data[i]; // Region of interest
    5759        psVector *solution = solutions->data[i]; // Solution of interest
    58         if (!pmSubtractionConvolve(&convolved, NULL, NULL, image, NULL, NULL, 0,
    59                                    region, solution, kernels, true)) {
     60        if (!pmSubtractionConvolve(convRO, inRO, NULL, NULL, 0, region, solution, kernels,
     61                                   PM_SUBTRACTION_MODE_1, true)) {
    6062            psError(PS_ERR_UNKNOWN, false, "Unable to convolve mask image in region %d.", i);
    61             psFree(convolved);
    62             psFree(image);
     63            psFree(convRO);
     64            psFree(inRO);
    6365            return NULL;
    6466        }
     
    7375        if (!kernel) {
    7476            psError(PS_ERR_UNKNOWN, false, "Unable to generate kernel image.");
    75             psFree(convolved);
    76             psFree(image);
     77            psFree(convRO);
     78            psFree(inRO);
    7779            return NULL;
    7880        }
     
    8587        psFree(kernel);
    8688
    87         psImage *subConv = psImageSubset(convolved, *region); // Sub-image of convolved image
     89        psImage *subConv = psImageSubset(convRO->image, *region); // Sub-image of convolved image
    8890        psBinaryOp(subConv, subConv, "*", psScalarAlloc(1.0 / sum, PS_TYPE_F32));
    8991    }
    90     psFree(image);
     92    psFree(inRO);
     93    psImage *convolved = psMemIncrRefCounter(convRO->image);
     94    psFree(convRO);
    9195
    9296    // Threshold the convolved image
  • branches/eam_branch_20071023/psModules/src/imcombine/pmSubtraction.h

    r15325 r15516  
    66 * @author GLG, MHPCC
    77 *
    8  * @version $Revision: 1.19 $ $Name: not supported by cvs2svn $
    9  * @date $Date: 2007-10-17 02:45:40 $
     8 * @version $Revision: 1.19.2.1 $ $Name: not supported by cvs2svn $
     9 * @date $Date: 2007-11-08 22:59:04 $
    1010 *
    1111 * Copyright 2004-207 Institute for Astronomy, University of Hawaii
     
    1616
    1717#include <pslib.h>
    18 #include "pmSubtractionKernels.h"
    19 #include "pmSubtractionStamps.h"
     18
     19#include <pmHDU.h>
     20#include <pmFPA.h>
     21#include <pmSubtractionKernels.h>
     22#include <pmSubtractionStamps.h>
    2023
    2124/// @addtogroup imcombine Image Combinations
    2225/// @{
    2326
     27/// Mask values for the subtraction mask
    2428typedef enum {
    25     PM_SUBTRACTION_MASK_CLEAR     = 0x00, // No masking
    26     PM_SUBTRACTION_MASK_REF       = 0x01, // Reference image is bad
    27     PM_SUBTRACTION_MASK_INPUT     = 0x02, // Input image is bad
    28     PM_SUBTRACTION_MASK_CONVOLVE  = 0x04, // If convolved, would be bad
    29     PM_SUBTRACTION_MASK_FOOTPRINT = 0x08, // Bad pixel within the stamp footprint
    30     PM_SUBTRACTION_MASK_BORDER    = 0x10, // Image border
    31     PM_SUBTRACTION_MASK_REJ       = 0x20, // Previously tried as a stamp, and rejected
     29    PM_SUBTRACTION_MASK_CLEAR       = 0x00, // No masking
     30    PM_SUBTRACTION_MASK_BAD_1       = 0x01, // Image 1 is bad
     31    PM_SUBTRACTION_MASK_BAD_2       = 0x02, // Image 2 is bad
     32    PM_SUBTRACTION_MASK_CONVOLVE_1  = 0x04, // If image 1 is convolved, would be bad
     33    PM_SUBTRACTION_MASK_CONVOLVE_2  = 0x08, // If image 2 is convolved, would be bad
     34    PM_SUBTRACTION_MASK_FOOTPRINT_1 = 0x10, // Bad pixel within the stamp footprint of image 1
     35    PM_SUBTRACTION_MASK_FOOTPRINT_2 = 0x20, // Bad pixel within the stamp footprint of image 2
     36    PM_SUBTRACTION_MASK_BORDER      = 0x40, // Image border
     37    PM_SUBTRACTION_MASK_REJ         = 0x80, // Previously tried as a stamp, and rejected
    3238} pmSubtractionMasks;
    3339
     
    4551bool pmSubtractionConvolveStamp(pmSubtractionStamp *stamp, ///< Stamp to convolve
    4652                                const pmSubtractionKernels *kernels, ///< Kernel parameters
    47                                 int footprint ///< Half-size of region over which to calculate equation
     53                                int footprint, ///< Half-size of region over which to calculate equation
     54                                pmSubtractionMode mode ///< Mode for subtraction (which to convolve)
    4855    );
    4956
     
    5158bool pmSubtractionCalculateEquation(pmSubtractionStampList *stamps, ///< Stamps
    5259                                    const pmSubtractionKernels *kernels, ///< Kernel parameters
    53                                     int footprint ///< Half-size of region over which to calculate equation
     60                                    int footprint, ///< Half-size of region over which to calculate equation
     61                                    pmSubtractionMode mode ///< Mode for subtraction (which to convolve)
    5462                                    );
    5563
     
    5967                                     );
    6068
     69/// Calculate deviations
     70psVector *pmSubtractionCalculateDeviations(pmSubtractionStampList *stamps, ///< Stamps
     71                                           const psVector *solution, ///< Solution vector
     72                                           int footprint, ///< Half-size of stamp
     73                                           const pmSubtractionKernels *kernels, ///< Kernel parameters
     74                                           pmSubtractionMode mode ///< Mode for subtraction
     75    );
     76
    6177/// Reject stamps
    6278int pmSubtractionRejectStamps(pmSubtractionStampList *stamps, ///< Stamps
     79                              const psVector *deviations, ///< Deviations for each stamp
    6380                              psImage *subMask, ///< Subtraction mask
    64                               const psVector *solution, ///< Solution vector
    65                               int footprint, ///< Region to mask if stamp is bad
    6681                              float sigmaRej, ///< Number of RMS deviations above zero at which to reject
    67                               const pmSubtractionKernels *kernels ///< Kernel parameters
     82                              int footprint ///< Half-size of stamp
    6883    );
    6984
     
    8196
    8297/// Convolve image in preparation for subtraction
    83 bool pmSubtractionConvolve(psImage **outImage, ///< Output image
    84                            psImage **outWeight, ///< Output weight map (or NULL)
    85                            psImage **outMask, ///< Output mask (or NULL)
    86                            const psImage *inImage, ///< Input image
    87                            const psImage *inWeight, ///< Input weight map (or NULL)
     98bool pmSubtractionConvolve(pmReadout *out, ///< Output image
     99                           const pmReadout *ro1, // Input image 1
     100                           const pmReadout *ro2, // Input image 2
    88101                           const psImage *subMask, ///< Subtraction mask (or NULL)
    89102                           psMaskType blank, ///< Mask value for blank regions
     
    91104                           const psVector *solution, ///< The solution vector
    92105                           const pmSubtractionKernels *kernels, ///< Kernel parameters
     106                           pmSubtractionMode mode, ///< Mode for subtraction
    93107                           bool useFFT  ///< Use Fast Fourier Transform for the convolution?
    94108    );
  • branches/eam_branch_20071023/psModules/src/imcombine/pmSubtractionKernels.c

    r15399 r15516  
    44
    55#include <stdio.h>
    6 #include <string.h>
     6#include <strings.h>
    77#include <pslib.h>
    88
     
    488488    PS_ASSERT_INT_NONNEGATIVE(spatialOrder, NULL);
    489489    PS_ASSERT_INT_NONNEGATIVE(inner, NULL);
    490     PS_ASSERT_INT_LESS_THAN(inner, size, NULL);
     490    PS_ASSERT_INT_LESS_THAN_OR_EQUAL(inner, size, NULL);
    491491    PS_ASSERT_INT_NONNEGATIVE(ringsOrder, NULL);
    492492
     
    572572                    for (int v = -size; v <= size; v++) {
    573573                        int v2 = PS_SQR(v);   // Square of v
    574                         float vPoly = power(v, vOrder); // Value of v^vOrder
     574//                        float vPoly = power(v, vOrder); // Value of v^vOrder
     575                        float vPoly = powf(v/(float)size, vOrder); // Value of v^vOrder
    575576
    576577                        for (int u = -size; u <= size; u++) {
     
    578579                            int distance2 = u2 + v2; // Distance from the centre
    579580                            if (distance2 > lower2 && distance2 < upper2) {
    580                                 float uPoly = power(u, uOrder); // Value of u^uOrder
     581//                                float uPoly = power(u, uOrder); // Value of u^uOrder
     582                                float uPoly = powf(u/(float)size, uOrder); // Value of u^uOrder
    581583
    582584                                float polyVal = uPoly * vPoly; // Value of polynomial
  • branches/eam_branch_20071023/psModules/src/imcombine/pmSubtractionKernels.h

    r14671 r15516  
    1414    PM_SUBTRACTION_KERNEL_RINGS,        ///< Rings Instead of the Normal Gaussian Subtraction
    1515} pmSubtractionKernelsType;
     16
     17/// Modes --- specifies which image to convolve
     18typedef enum {
     19    PM_SUBTRACTION_MODE_ERR,            // Error in the mode
     20    PM_SUBTRACTION_MODE_TARGET,         // Convolve image 1 to match target PSF
     21    PM_SUBTRACTION_MODE_1,              // Convolve image 1
     22    PM_SUBTRACTION_MODE_2,              // Convolve image 2
     23    PM_SUBTRACTION_MODE_UNSURE,         // Not sure yet which image to convolve so try to satisfy both
     24    PM_SUBTRACTION_MODE_DUAL,           // Dual convolution
     25} pmSubtractionMode;
    1626
    1727/// Kernels specification
  • branches/eam_branch_20071023/psModules/src/imcombine/pmSubtractionMatch.c

    r15329 r15516  
    5050
    5151static bool getStamps(pmSubtractionStampList **stamps, // Stamps to read
    52                       const pmReadout *reference, // Reference readout
    53                       const pmReadout *input, // Input readout, or NULL to generate fake stamps
     52                      const pmReadout *ro1, // Readout 1
     53                      const pmReadout *ro2, // Readout 2
    5454                      const psImage *subMask, // Mask for subtraction, or NULL
    5555                      psImage *weight,  // Weight map
     
    5757                      float threshold,  // Threshold for stamp finding
    5858                      float stampSpacing, // Spacing between stamps
    59                       float targetWidth,// Target width for fake stamps
    6059                      int size,         // Kernel half-size
    61                       int footprint     // Convolution footprint for stamps
     60                      int footprint,     // Convolution footprint for stamps
     61                      pmSubtractionMode mode // Mode for subtraction
    6262    )
    6363{
    6464    psTrace("psModules.imcombine", 3, "Finding stamps...\n");
    65     *stamps = pmSubtractionStampsFind(*stamps, reference->image, subMask, region, threshold, stampSpacing);
     65    *stamps = pmSubtractionStampsFind(*stamps, ro1->image, subMask, region, threshold, stampSpacing, mode);
    6666    if (!*stamps) {
    6767        psError(PS_ERR_UNKNOWN, false, "Unable to find stamps.");
     
    7171    memCheck("  find stamps");
    7272
    73     if (!input && !pmSubtractionStampsGenerate(*stamps, targetWidth, footprint, size)) {
    74         psError(PS_ERR_UNKNOWN, false, "Unable to generate target stamps.");
    75         return false;
    76     }
    77 
    78     memCheck("   generate stamps");
    79 
    8073    psTrace("psModules.imcombine", 3, "Extracting stamps...\n");
    81     if (!pmSubtractionStampsExtract(*stamps, reference->image, input ? input->image : NULL,
    82                                     weight, footprint, size)) {
     74    if (!pmSubtractionStampsExtract(*stamps, ro1->image, ro2 ? ro2->image : NULL, weight, footprint, size)) {
    8375        psError(PS_ERR_UNKNOWN, false, "Unable to extract stamps.");
    8476        return false;
     
    9486
    9587
    96 bool pmSubtractionMatch(pmReadout *convolved, const pmReadout *reference, const pmReadout *input,
     88bool pmSubtractionMatch(pmReadout *convolved, const pmReadout *ro1, const pmReadout *ro2,
    9789                        int footprint, float regionSize, float stampSpacing, float threshold,
    98                         const psArray *sources, const char *stampsName, float targetWidth,
     90                        const psArray *sources, const char *stampsName,
    9991                        pmSubtractionKernelsType type, int size, int spatialOrder,
    10092                        const psVector *isisWidths, const psVector *isisOrders,
    10193                        int inner, int ringsOrder, int binning, bool optimum, const psVector *optFWHMs,
    10294                        int optOrder, float optThreshold, int iter, float rej, psMaskType maskBad,
    103                         psMaskType maskBlank, float badFrac)
     95                        psMaskType maskBlank, float badFrac, pmSubtractionMode mode)
    10496{
    10597    PS_ASSERT_PTR_NON_NULL(convolved, false);
    106     PS_ASSERT_PTR_NON_NULL(reference, false);
    107     PS_ASSERT_IMAGE_NON_NULL(reference->image, false);
    108     PS_ASSERT_IMAGE_TYPE(reference->image, PS_TYPE_F32, false);
    109     if (reference->mask) {
    110         PS_ASSERT_IMAGE_NON_NULL(reference->mask, false);
    111         PS_ASSERT_IMAGE_TYPE(reference->mask, PS_TYPE_MASK, false);
    112         PS_ASSERT_IMAGES_SIZE_EQUAL(reference->mask, reference->image, false);
    113     }
    114     if (reference->weight) {
    115         PS_ASSERT_IMAGE_NON_NULL(reference->weight, false);
    116         PS_ASSERT_IMAGE_TYPE(reference->weight, PS_TYPE_F32, false);
    117         PS_ASSERT_IMAGES_SIZE_EQUAL(reference->weight, reference->image, false);
    118     }
    119     if (input) {
    120         PS_ASSERT_IMAGE_NON_NULL(input->image, false);
    121         PS_ASSERT_IMAGE_TYPE(input->image, PS_TYPE_F32, false);
    122         PS_ASSERT_IMAGES_SIZE_EQUAL(input->image, reference->image, false);
    123         if (input->mask) {
    124             PS_ASSERT_IMAGE_NON_NULL(input->mask, false);
    125             PS_ASSERT_IMAGE_TYPE(input->mask, PS_TYPE_MASK, false);
    126             PS_ASSERT_IMAGES_SIZE_EQUAL(input->mask, reference->image, false);
    127         }
    128         if (input->weight) {
    129             PS_ASSERT_IMAGE_NON_NULL(input->weight, false);
    130             PS_ASSERT_IMAGE_TYPE(input->weight, PS_TYPE_F32, false);
    131             PS_ASSERT_IMAGES_SIZE_EQUAL(input->weight, reference->image, false);
     98    PS_ASSERT_PTR_NON_NULL(ro1, false);
     99    PS_ASSERT_IMAGE_NON_NULL(ro1->image, false);
     100    PS_ASSERT_IMAGE_TYPE(ro1->image, PS_TYPE_F32, false);
     101    if (ro1->mask) {
     102        PS_ASSERT_IMAGE_NON_NULL(ro1->mask, false);
     103        PS_ASSERT_IMAGE_TYPE(ro1->mask, PS_TYPE_MASK, false);
     104        PS_ASSERT_IMAGES_SIZE_EQUAL(ro1->mask, ro1->image, false);
     105    }
     106    if (ro1->weight) {
     107        PS_ASSERT_IMAGE_NON_NULL(ro1->weight, false);
     108        PS_ASSERT_IMAGE_TYPE(ro1->weight, PS_TYPE_F32, false);
     109        PS_ASSERT_IMAGES_SIZE_EQUAL(ro1->weight, ro1->image, false);
     110    }
     111    if (ro2) {
     112        PS_ASSERT_IMAGE_NON_NULL(ro2->image, false);
     113        PS_ASSERT_IMAGE_TYPE(ro2->image, PS_TYPE_F32, false);
     114        PS_ASSERT_IMAGES_SIZE_EQUAL(ro2->image, ro1->image, false);
     115        if (ro2->mask) {
     116            PS_ASSERT_IMAGE_NON_NULL(ro2->mask, false);
     117            PS_ASSERT_IMAGE_TYPE(ro2->mask, PS_TYPE_MASK, false);
     118            PS_ASSERT_IMAGES_SIZE_EQUAL(ro2->mask, ro1->image, false);
     119        }
     120        if (ro2->weight) {
     121            PS_ASSERT_IMAGE_NON_NULL(ro2->weight, false);
     122            PS_ASSERT_IMAGE_TYPE(ro2->weight, PS_TYPE_F32, false);
     123            PS_ASSERT_IMAGES_SIZE_EQUAL(ro2->weight, ro1->image, false);
    132124        }
    133125    } else if (!stampsName && !sources) {
     
    144136    }
    145137    // stampsName may be anything
    146     // targetWidth can be just about anything (except maybe negative, but it can be NAN)
    147138    // We'll check kernel type when we allocate the kernels
    148139    PS_ASSERT_INT_POSITIVE(size, false);
     
    196187    }
    197188
    198     psImage *inImage = NULL, *inMask = NULL; // Input image, mask, weight
    199     if (input) {
    200         inImage = input->image;
    201         inMask = input->mask;
    202     }
    203 
    204189    // Where does our weight map come from?
    205190    psImage *weight = NULL;             // Weight image to use
    206     if (input && input->weight) {
    207         weight = input->weight;
    208     } else if (reference->weight) {
    209         weight = reference->weight;
    210     } else if (input) {
    211         weight = input->image;
     191    if (ro1->weight && ro2 && ro2->weight) {
     192        weight = (psImage*)psBinaryOp(NULL, ro1->weight, "+", ro2->weight);
     193    } else if (ro1->weight) {
     194        weight = psMemIncrRefCounter(ro1->weight);
     195    } else if (ro2) {
     196        if (ro2->weight) {
     197            weight = psMemIncrRefCounter(ro2->weight);
     198        } else {
     199            weight = (psImage*)psBinaryOp(NULL, ro1->image, "+", ro2->image);
     200        }
    212201    } else {
    213         weight = reference->image;
     202        weight = psMemIncrRefCounter(ro1->image);
    214203    }
    215204
     
    221210    psVector *solution = NULL;          // Solution to match PSF
    222211    pmSubtractionKernels *kernels = NULL; // Kernel basis functions
    223 
    224     int numCols = reference->image->numCols, numRows = reference->image->numRows; // Image dimensions
     212    int numCols = ro1->image->numCols, numRows = ro1->image->numRows; // Image dimensions
    225213
    226214    memCheck("start");
    227215
    228     subMask = pmSubtractionMask(reference->mask, inMask, maskBad, size, footprint, badFrac, useFFT);
     216    subMask = pmSubtractionMask(ro1->mask, ro2 ? ro2->mask : NULL, maskBad, size, footprint,
     217                                badFrac, useFFT);
    229218    if (!subMask) {
    230219        psError(PS_ERR_UNKNOWN, false, "Unable to generate subtraction mask.");
     220        psFree(weight);
    231221        return false;
    232222    }
     
    260250
    261251            if (sources) {
    262                 stamps = pmSubtractionStampsSetFromSources(sources, subMask, region, stampSpacing,
    263                                                            input ? 0 : 2 * footprint);
     252                stamps = pmSubtractionStampsSetFromSources(sources, subMask, region, stampSpacing, mode);
    264253            } else if (stampsName && strlen(stampsName) > 0) {
    265                 // Read stamps from file
    266                 psTrace("psModules.imcombine", 3, "Reading stamps from %s...\n", stampsName);
    267                 const char *stampFormat = input ? "%f %f" : "%f %f %f"; // Format for reading stamp file
    268                 psArray *stampsData = stampsData = psVectorsReadFromFile(stampsName, stampFormat);
    269                 psVector *xStamp = NULL, *yStamp = NULL, *fluxStamp = NULL; // Stamp positions and fluxes
    270                 if (!stampsData) {
    271                     psError(PS_ERR_IO, false, "Unable to read stamps file %s", stampsName);
    272                     goto ERROR;
    273                 }
    274                 xStamp = stampsData->data[0];
    275                 yStamp = stampsData->data[1];
    276                 if (!input) {
    277                     fluxStamp = stampsData->data[2];
    278                 }
    279 
    280                 // Correct for IRAF/FITS (unit-offset) positions to C (zero-offset) positions
    281                 psBinaryOp(xStamp, xStamp, "-", psScalarAlloc(1.0, PS_TYPE_F32));
    282                 psBinaryOp(yStamp, yStamp, "-", psScalarAlloc(1.0, PS_TYPE_F32));
    283 
    284                 stamps = pmSubtractionStampsSet(xStamp, yStamp, fluxStamp, reference->image, subMask,
    285                                                 region, stampSpacing, input ? 0 : footprint + size);
    286                 psFree(stampsData);
     254                stamps = pmSubtractionStampsSetFromFile(stampsName, subMask, region, stampSpacing, mode);
     255            }
     256
     257            // We get the stamps here; we will also attempt to get stamps at the first iteration, but it
     258            // doesn't matter.
     259            if (!getStamps(&stamps, ro1, ro2, subMask, weight, NULL, threshold, stampSpacing,
     260                           size, footprint, mode)) {
     261                goto MATCH_ERROR;
     262            }
     263
     264            if (mode == PM_SUBTRACTION_MODE_UNSURE || mode == PM_SUBTRACTION_MODE_TARGET) {
     265                pmSubtractionMode newMode = pmSubtractionOrder(stamps, footprint); // Subtraction mode
     266                switch (newMode) {
     267                  case PM_SUBTRACTION_MODE_1:
     268                    psLogMsg("psModules.imcombine", PS_LOG_INFO, "Convolving image 1 to match image 2.");
     269                    break;
     270                  case PM_SUBTRACTION_MODE_2:
     271                    if (mode == PM_SUBTRACTION_MODE_TARGET) {
     272                        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
     273                                "Input PSF is larger than target PSF --- can't match image.");
     274                        goto MATCH_ERROR;
     275                    }
     276                    psLogMsg("psModules.imcombine", PS_LOG_INFO, "Convolving image 2 to match image 1.");
     277                    break;
     278                  default:
     279                    psError(PS_ERR_UNKNOWN, false, "Unable to determine subtraction order.");
     280                    goto MATCH_ERROR;
     281                }
     282                mode = newMode;
    287283            }
    288284
    289285            // Define kernel basis functions
    290286            if (optimum && (type == PM_SUBTRACTION_KERNEL_ISIS || type == PM_SUBTRACTION_KERNEL_GUNK)) {
    291                 if (!getStamps(&stamps, reference, input, subMask, weight, NULL,
    292                                threshold, stampSpacing, targetWidth, size, footprint)) {
    293                     goto ERROR;
    294                 }
    295287                kernels = pmSubtractionKernelsOptimumISIS(type, size, inner, spatialOrder, optFWHMs, optOrder,
    296                                                           stamps, footprint, optThreshold);
     288                                                          stamps, footprint, optThreshold, mode);
    297289                if (!kernels) {
    298290                    psErrorClear();
     
    314306                psLogMsg("psModules.imcombine", PS_LOG_INFO, "Iteration %d.", k);
    315307
    316                 if (!getStamps(&stamps, reference, input, subMask, weight, region,
    317                                threshold, stampSpacing, targetWidth, size, footprint)) {
    318                     goto ERROR;
     308                if (!getStamps(&stamps, ro1, ro2, subMask, weight, region, threshold, stampSpacing,
     309                               size, footprint, mode)) {
     310                    goto MATCH_ERROR;
    319311                }
    320312
    321313                psTrace("psModules.imcombine", 3, "Calculating equation...\n");
    322                 if (!pmSubtractionCalculateEquation(stamps, kernels, footprint)) {
     314                if (!pmSubtractionCalculateEquation(stamps, kernels, footprint, mode)) {
    323315                    psError(PS_ERR_UNKNOWN, false, "Unable to calculate least-squares equation.");
    324                     goto ERROR;
     316                    goto MATCH_ERROR;
    325317                }
    326318
     
    331323                if (!solution) {
    332324                    psError(PS_ERR_UNKNOWN, false, "Unable to calculate least-squares equation.");
    333                     goto ERROR;
     325                    goto MATCH_ERROR;
    334326                }
    335327
    336328                memCheck("  solve equation");
    337329
     330                psVector *deviations = pmSubtractionCalculateDeviations(stamps, solution, footprint, kernels,
     331                                                                        mode); // Deviations for each stamp
     332                if (!deviations) {
     333                    psError(PS_ERR_UNKNOWN, false, "Unable to calculate deviations.");
     334                    goto MATCH_ERROR;
     335                }
     336
     337                memCheck("   calculate deviations");
     338
    338339                psTrace("psModules.imcombine", 3, "Rejecting stamps...\n");
    339                 numRejected = pmSubtractionRejectStamps(stamps, subMask, solution, footprint, rej, kernels);
     340                numRejected = pmSubtractionRejectStamps(stamps, deviations, subMask, rej, footprint);
    340341                if (numRejected < 0) {
    341342                    psError(PS_ERR_UNKNOWN, false, "Unable to reject stamps.");
    342                     goto ERROR;
    343                 }
     343                    psFree(deviations);
     344                    goto MATCH_ERROR;
     345                }
     346                psFree(deviations);
     347
    344348                memCheck("  reject stamps");
    345349            }
     
    350354                if (!solution) {
    351355                    psError(PS_ERR_UNKNOWN, false, "Unable to calculate least-squares equation.");
    352                     goto ERROR;
    353                 }
    354                 (void)pmSubtractionRejectStamps(stamps, subMask, solution, footprint, NAN, kernels);
     356                    goto MATCH_ERROR;
     357                }
     358                psVector *deviations = pmSubtractionCalculateDeviations(stamps, solution, footprint, kernels,
     359                                                                        mode); // Deviations for each stamp
     360                if (!deviations) {
     361                    psError(PS_ERR_UNKNOWN, false, "Unable to calculate deviations.");
     362                    goto MATCH_ERROR;
     363                }
     364                pmSubtractionRejectStamps(stamps, deviations, subMask, NAN, footprint);
     365                psFree(deviations);
    355366            }
    356367            psFree(stamps);
     
    372383                            psError(PS_ERR_UNKNOWN, false, "Unable to generate kernel image.");
    373384                            psFree(convKernels);
    374                             goto ERROR;
     385                            goto MATCH_ERROR;
    375386                        }
    376387
     
    380391                            psFree(kernel);
    381392                            psFree(convKernels);
    382                             goto ERROR;
     393                            goto MATCH_ERROR;
    383394                        }
    384395                        psFree(kernel);
     
    416427
    417428            psTrace("psModules.imcombine", 2, "Convolving...\n");
    418             if (!pmSubtractionConvolve(&convolved->image, &convolved->weight, &convolved->mask,
    419                                        reference->image, reference->weight, subMask, maskBlank, region,
    420                                        solution, kernels, useFFT)) {
    421                 psError(PS_ERR_UNKNOWN, false, "Unable to convolve reference image.");
    422                 goto ERROR;
     429            if (!pmSubtractionConvolve(convolved, ro1, ro2, subMask, maskBlank, region,
     430                                       solution, kernels, mode, useFFT)) {
     431                psError(PS_ERR_UNKNOWN, false, "Unable to convolve image.");
     432                goto MATCH_ERROR;
    423433            }
    424434            psFree(kernels);
     
    461471    psFree(subMask);
    462472    subMask = NULL;
     473    psFree(weight);
     474    weight = NULL;
    463475
    464476    if (!pmSubtractionBorder(convolved->image, convolved->weight, convolved->mask, size, maskBlank)) {
    465477        psError(PS_ERR_UNKNOWN, false, "Unable to set border of convolved image.");
    466         goto ERROR;
     478        goto MATCH_ERROR;
    467479    }
    468480
     
    472484    return true;
    473485
    474 ERROR:
     486MATCH_ERROR:
    475487    psFree(region);
    476488    psFree(regionString);
     
    479491    psFree(stamps);
    480492    psFree(solution);
     493    psFree(weight);
    481494    return false;
    482495}
     496
     497// Calculate the second order moments for an image
     498static float subtractionOrderMoment(const psKernel *kernel, // Image for which to measure moments
     499                                    int radius   // Maximum radius
     500                                    )
     501{
     502    assert(kernel && kernel->kernel);
     503
     504    int xMin = PS_MAX(kernel->xMin, -radius), xMax = PS_MIN(kernel->xMax, radius); // Bounds in x
     505    int yMin = PS_MAX(kernel->yMin, -radius), yMax = PS_MIN(kernel->yMax, radius); // Bounds in y
     506
     507    float xCentroid = 0.0, yCentroid = 0.0; // Centroid (first moment)
     508    float sum = 0.0;       // Sum (zero-th moment)
     509    for (int y = yMin; y <= yMax; y++) {
     510        for (int x = xMin; x <= xMax; x++) {
     511            xCentroid += kernel->kernel[y][x] * x;
     512            yCentroid += kernel->kernel[y][x] * y;
     513            sum += kernel->kernel[y][x];
     514        }
     515    }
     516    xCentroid /= sum;
     517    yCentroid /= sum;
     518
     519    float eta20 = 0.0, eta02 = 0.0;     // Second moments
     520    for (int y = yMin; y <= yMax; y++) {
     521        float yDiff = y - yCentroid;
     522        for (int x = xMin; x <= xMax; x++) {
     523            float xDiff = x - xCentroid;
     524            eta20 += PS_SQR(xDiff) * kernel->kernel[y][x];
     525            eta02 += PS_SQR(yDiff) * kernel->kernel[y][x];
     526        }
     527    }
     528
     529    // Normalise to calculate the scale-invariant
     530    float sum2 = PS_SQR(sum);
     531    eta20 /= sum2;
     532    eta02 /= sum2;
     533    // eta11 /= sum2;
     534
     535    return eta20 + eta02;
     536}
     537
     538#if 0
     539// Calculate the deviations for a particular subtraction order
     540static psVector *subtractionOrderDeviation(float *sumKernel, // Sum of the kernel
     541                                           pmSubtractionStampList *stamps, // Stamps to convolve
     542                                           const pmSubtractionKernels *kernels, // Kernel basis functions
     543                                           int footprint, // Stamp footprint
     544                                           pmSubtractionMode mode // Mode of subtraction
     545                                           )
     546{
     547    assert(stamps);
     548    assert(footprint >= 0);
     549    assert(mode == PM_SUBTRACTION_MODE_1 || mode == PM_SUBTRACTION_MODE_2);
     550
     551    if (!pmSubtractionCalculateEquation(stamps, kernels, footprint, mode)) {
     552        psError(PS_ERR_UNKNOWN, false, "Unable to calculate least-squares equation.");
     553        return NULL;
     554    }
     555
     556    psVector *solution = pmSubtractionSolveEquation(NULL, stamps);
     557    if (!solution) {
     558        psError(PS_ERR_UNKNOWN, false, "Unable to calculate least-squares equation.");
     559        return NULL;
     560    }
     561
     562    if (sumKernel) {
     563        float sum = 0.0;                // Sum of the kernel
     564        psImage *image = pmSubtractionKernelImage(solution, kernels, 0.0, 0.0); // Image of kernel
     565        for (int y = 0; y < image->numRows; y++) {
     566            for (int x = 0; x < image->numCols; x++) {
     567                sum += image->data.F32[y][x];
     568            }
     569        }
     570        psFree(image);
     571        *sumKernel = sum;
     572    }
     573
     574    psVector *deviations = pmSubtractionCalculateDeviations(stamps, solution, footprint, kernels, mode);
     575    psFree(solution);
     576    if (!deviations) {
     577        psError(PS_ERR_UNKNOWN, false, "Unable to calculate deviations.");
     578        return NULL;
     579    }
     580
     581    return deviations;
     582}
     583#endif
     584
     585pmSubtractionMode pmSubtractionOrder(pmSubtractionStampList *stamps, int radius)
     586{
     587    PS_ASSERT_INT_POSITIVE(radius, PM_SUBTRACTION_MODE_ERR);
     588
     589    psVector *mask = psVectorAlloc(stamps->num, PS_TYPE_MASK); // Mask for stamps
     590    psVector *moments = psVectorAlloc(stamps->num, PS_TYPE_F32); // Moments
     591    for (int i = 0; i < stamps->num; i++) {
     592        pmSubtractionStamp *stamp = stamps->stamps->data[i]; // Stamp of interest
     593        if (stamp->status != PM_SUBTRACTION_STAMP_CALCULATE && stamp->status != PM_SUBTRACTION_STAMP_USED) {
     594            mask->data.PS_TYPE_MASK_DATA[i] = 0xff;
     595            continue;
     596        }
     597        mask->data.PS_TYPE_MASK_DATA[i] = 0;
     598        moments->data.F32[i] = subtractionOrderMoment(stamp->image1, radius) /
     599            subtractionOrderMoment(stamp->image2, radius);
     600    }
     601
     602    psStats *stats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN);
     603    if (!psVectorStats(stats, moments, NULL, mask, 0xff)) {
     604        psError(PS_ERR_UNKNOWN, false, "Unable to calculate statistics for moments ratio.");
     605        psFree(mask);
     606        psFree(moments);
     607        psFree(stats);
     608        return PM_SUBTRACTION_MODE_ERR;
     609    }
     610    psFree(moments);
     611    psFree(mask);
     612
     613    psLogMsg("psModules.imcombine", PS_LOG_INFO, "Median ratio of second moments: %lf", stats->robustMedian);
     614    pmSubtractionMode mode = (stats->robustMedian <= 1.0 ? PM_SUBTRACTION_MODE_1 : PM_SUBTRACTION_MODE_2);
     615    psFree(stats);
     616
     617    return mode;
     618}
     619
     620
     621
  • branches/eam_branch_20071023/psModules/src/imcombine/pmSubtractionMatch.h

    r15305 r15516  
    44#include <pslib.h>
    55
    6 #include "pmHDU.h"
    7 #include "pmFPA.h"
    8 #include "pmSubtractionKernels.h"
     6#include <pmHDU.h>
     7#include <pmFPA.h>
     8#include <pmSubtractionKernels.h>
     9#include <pmSubtractionStamps.h>
    910
    10 
     11/// Match two images
    1112bool pmSubtractionMatch(pmReadout *convolved, ///< Output convolved data
    12                         const pmReadout *reference, ///< Reference data
    13                         const pmReadout *input, ///< Input data
     13                        const pmReadout *ro1, ///< Image 1
     14                        const pmReadout *ro2, ///< Image 2
    1415                        // Stamp parameters
    1516                        int footprint,  ///< Stamp half-size
     
    1920                        const psArray *sources, ///< Sources for stamps
    2021                        const char *stampsName, ///< Filename for stamps
    21                         float targetWidth, ///< Width of PSF for simulated target
    2222                        // Kernel parameters
    2323                        pmSubtractionKernelsType type, ///< Kernel type
     
    3838                        psMaskType maskBad, ///< Value to mask
    3939                        psMaskType maskBlank, ///< Mask for blank region
    40                         float badFrac   ///< Maximum fraction of bad input pixels to accept
     40                        float badFrac,   ///< Maximum fraction of bad input pixels to accept
     41                        pmSubtractionMode mode ///< Mode of subtraction
    4142    );
    4243
     44/// Determine which image to convolve
     45pmSubtractionMode pmSubtractionOrder(pmSubtractionStampList *stamps, ///< Stamps that have been extracted
     46                                     int footprint ///< Stamp half-size
     47    );
     48
     49
    4350#endif
  • branches/eam_branch_20071023/psModules/src/imcombine/pmSubtractionParams.c

    r15247 r15516  
    5050#endif
    5151
     52/// Select the appropriate convolution, given the kernel basis function and subtraction mode
     53static inline psKernel *selectConvolution(const pmSubtractionStamp *stamp, // Stamp
     54                                          int kernelIndex, // Index for kernel component
     55                                          pmSubtractionMode mode // Mode of subtraction
     56    )
     57{
     58    switch (mode) {
     59      case PM_SUBTRACTION_MODE_1:
     60        return stamp->convolutions1->data[kernelIndex];
     61      case PM_SUBTRACTION_MODE_2:
     62        return stamp->convolutions2->data[kernelIndex];
     63      default:
     64        psAbort("Unsupported subtraction mode: %x", mode);
     65    }
     66    return NULL;                        // Unreached
     67}
     68
    5269// Accumulate cross-term sums for a stamp
    5370static void accumulateCross(double *sumI, // Sum of I(x)/sigma(x)^2
     
    5572                            double *sumIC, // Sum of I(x)conv(x)/sigma(x)^2
    5673                            const pmSubtractionStamp *stamp, // Stamp with weight
    57                             const psKernel *input, // Input image, I(x)
     74                            const psKernel *target, // Target stamp
    5875                            int kernelIndex, // Index for kernel component
    59                             int footprint // Size of region of interest
     76                            int footprint, // Size of region of interest
     77                            pmSubtractionMode mode // Mode of subtraction
    6078    )
    6179{
    6280    psKernel *weight = stamp->weight;   // Weight, sigma(x)^2
    63     psKernel *convolution = stamp->convolutions->data[kernelIndex]; // Convolution of interest
     81    psKernel *convolution = selectConvolution(stamp, kernelIndex, mode); // Convolution of interest
    6482
    6583    for (int y = -footprint; y <= footprint; y++) {
    66         psF32 *in = &input->kernel[y][-footprint]; // Dereference input
     84        psF32 *in = &target->kernel[y][-footprint]; // Dereference input
    6785        psF32 *wt = &weight->kernel[y][-footprint]; // Dereference weight
    6886        psF32 *conv = &convolution->kernel[y][-footprint]; // Dereference convolution
     
    82100                                   const pmSubtractionStamp *stamp, // Stamp with input and weight
    83101                                   int kernelIndex, // Index for kernel component
    84                                    int footprint // Size of region of interest
     102                                   int footprint, // Size of region of interest
     103                                   pmSubtractionMode mode // Mode of subtraction
    85104    )
    86105{
    87106    psKernel *weight = stamp->weight;   // Weight, sigma(x)^2
    88     psKernel *convolution = stamp->convolutions->data[kernelIndex]; // Convolution of interest
     107    psKernel *convolution = selectConvolution(stamp, kernelIndex, mode); // Convolution of interest
    89108
    90109    for (int y = -footprint; y <= footprint; y++) {
     
    100119}
    101120
    102 static double accumulateChi2(psKernel *input, // Input stamp
     121static double accumulateChi2(const psKernel *target, // Target stamp
    103122                             pmSubtractionStamp *stamp, // Stamp with weight
    104123                             int kernelIndex, // Index for kernel component
    105124                             double coeff, // Coefficient of convolution
    106125                             double bg,  // Background term
    107                              int footprint // Size of region of interest
     126                             int footprint, // Size of region of interest
     127                             pmSubtractionMode mode // Mode of subtraction
    108128    )
    109129{
    110130    double chi2 = 0.0;
    111131    psKernel *weight = stamp->weight;   // Weight, sigma(x)^2
    112     psKernel *convolution = stamp->convolutions->data[kernelIndex]; // Convolution of interest
     132    psKernel *convolution = selectConvolution(stamp, kernelIndex, mode); // Convolution of interest
    113133
    114134    for (int y = -footprint; y <= footprint; y++) {
    115         psF32 *in = &input->kernel[y][-footprint]; // Dereference input
     135        psF32 *in = &target->kernel[y][-footprint]; // Dereference input
    116136        psF32 *wt = &weight->kernel[y][-footprint]; // Dereference weight
    117137        psF32 *conv = &convolution->kernel[y][-footprint]; // Dereference convolution
     
    125145
    126146// Return the initial value of chi^2
    127 static double initialChi2(psKernel *input, // Input stamp
     147static double initialChi2(const psKernel *target, // Target stamp
    128148                          const pmSubtractionStamp *stamp, // Stamp with weight
    129                           int footprint // Size of convolution
     149                          int footprint, // Size of convolution
     150                          pmSubtractionMode mode // Mode of subtraction
    130151    )
    131152{
    132153    psKernel *weight = stamp->weight;   // Weight map
    133     psKernel *reference = stamp->reference; // Reference stamp
     154    psKernel *source;                   // Source stamp
     155    switch (mode) {
     156      case PM_SUBTRACTION_MODE_1:
     157        source = stamp->image1;
     158        break;
     159      case PM_SUBTRACTION_MODE_2:
     160        source = stamp->image2;
     161        break;
     162      default:
     163        psAbort("Unsupported subtraction mode: %x", mode);
     164    }
    134165
    135166    double chi2 = 0.0;                  // Chi^2
    136167    for (int y = -footprint; y <= footprint; y++) {
    137         psF32 *in = &input->kernel[y][-footprint]; // Dereference input
     168        psF32 *in = &target->kernel[y][-footprint]; // Dereference input
    138169        psF32 *wt = &weight->kernel[y][-footprint]; // Dereference weight
    139         psF32 *ref = &reference->kernel[y][-footprint]; // Derference reference
     170        psF32 *ref = &source->kernel[y][-footprint]; // Derference reference
    140171        for (int x = -footprint; x <= footprint; x++, in++, wt++, ref++) {
    141172            float diff = *in - *ref;    // Temporary value
     
    148179
    149180// Subtract a convolution from the input
    150 static void subtractConvolution(psKernel *input, // Input stamp
     181static void subtractConvolution(psKernel *target, // Target stamp
    151182                                const pmSubtractionStamp *stamp, // Stamp with weight
    152183                                int kernelIndex, // Index for kernel component
    153184                                float coeff, // Coefficient of subtraction
    154185                                float bg, // Background term
    155                                 int footprint // Size of region of interest
    156     )
    157 {
    158     psKernel *convolution = stamp->convolutions->data[kernelIndex]; // Convolution of interest
    159 
     186                                int footprint, // Size of region of interest
     187                                pmSubtractionMode mode // Mode of subtraction
     188    )
     189{
     190    psKernel *convolution = selectConvolution(stamp, kernelIndex, mode); // Convolution of interest
    160191    for (int y = -footprint; y <= footprint; y++) {
    161         psF32 *in = &input->kernel[y][-footprint]; // Dereference input
     192        psF32 *in = &target->kernel[y][-footprint]; // Dereference input
    162193        psF32 *conv = &convolution->kernel[y][-footprint]; // Dereference convolution
    163194        for (int x = -footprint; x <= footprint; x++, in++, conv++) {
     
    173204                                                      int spatialOrder, const psVector *fwhms, int maxOrder,
    174205                                                      const pmSubtractionStampList *stamps, int footprint,
    175                                                       float tolerance)
     206                                                      float tolerance, pmSubtractionMode mode)
    176207{
    177208    if (type != PM_SUBTRACTION_KERNEL_ISIS && type != PM_SUBTRACTION_KERNEL_GUNK) {
     
    210241    // Need to save the stamp inputs --- we're changing the values!
    211242    int numStamps = stamps->num;        // Number of stamps
    212     psArray *inputs = psArrayAlloc(numStamps); // Deep copies of the inputs
     243    psArray *targets = psArrayAlloc(numStamps); // Deep copies of the targets
    213244    psVector *badStamps = psVectorAlloc(numStamps, PS_TYPE_U8); // Mark the bad stamps
    214245    psVectorInit(badStamps, 0);
     
    219250            continue;
    220251        }
    221         psKernel *input = stamp->input; // Input image of interest
    222         psImage *copy = psImageCopy(NULL, input->image, PS_TYPE_F32); // Copy of the image
    223         inputs->data[i] = psKernelAllocFromImage(copy, size + footprint, size + footprint);
     252        psKernel *target;               // Target image of interest
     253        switch (mode) {
     254          case PM_SUBTRACTION_MODE_1:
     255            target = stamp->image2;
     256            break;
     257          case PM_SUBTRACTION_MODE_2:
     258            target = stamp->image1;
     259            break;
     260          default:
     261            psAbort("Unsupported subtraction mode: %x", mode);
     262        }
     263        psImage *copy = psImageCopy(NULL, target->image, PS_TYPE_F32); // Copy of the image
     264        targets->data[i] = psKernelAllocFromImage(copy, size + footprint, size + footprint);
    224265        psFree(copy);                   // Drop reference
    225266    }
     
    238279            continue;
    239280        }
    240         if (!pmSubtractionConvolveStamp(stamp, kernels, footprint)) {
     281        if (!pmSubtractionConvolveStamp(stamp, kernels, footprint, mode)) {
    241282            psError(PS_ERR_UNKNOWN, false, "Unable to convolve stamp %d.", i);
    242             psFree(inputs);
     283            psFree(targets);
    243284            psFree(kernels);
    244285            psFree(badStamps);
     
    258299                    "Sum of 1/sigma^2 is non-finite for stamp %d (%d,%d)\n",
    259300                    i, (int)stamp->x, (int)stamp->y);
    260             psFree(inputs);
     301            psFree(targets);
    261302            psFree(kernels);
    262303            psFree(badStamps);
     
    265306
    266307        for (int j = 0; j < numKernels; j++) {
    267             accumulateConvolutions(&sumC->data.F64[j], &sumCC->data.F64[j], stamp, j, footprint);
    268         }
    269 
    270         lastChi2 += initialChi2(inputs->data[i], stamp, footprint);
     308            accumulateConvolutions(&sumC->data.F64[j], &sumCC->data.F64[j], stamp, j, footprint, mode);
     309        }
     310
     311        lastChi2 += initialChi2(targets->data[i], stamp, footprint, mode);
    271312        numPixels += PS_SQR(2 * footprint + 1);
    272313    }
     
    297338                }
    298339                pmSubtractionStamp *stamp = stamps->stamps->data[j]; // Stamp of interest
    299                 accumulateCross(&sumI, &sumII, &sumIC, stamp, inputs->data[j], i, footprint);
     340                accumulateCross(&sumI, &sumII, &sumIC, stamp, targets->data[j], i, footprint, mode);
    300341            }
    301342
     
    310351                }
    311352                pmSubtractionStamp *stamp = stamps->stamps->data[j]; // Stamp of interest
    312                 chi2 += accumulateChi2(inputs->data[j], stamp, i, coeff, bg, footprint);
     353                chi2 += accumulateChi2(targets->data[j], stamp, i, coeff, bg, footprint, mode);
    313354            }
    314355
     
    328369        if (bestIndex == -1) {
    329370            psError(PS_ERR_UNKNOWN, false, "Unable to find best kernel component in round %d.", iter);
    330             psFree(inputs);
     371            psFree(targets);
    331372            psFree(sumC);
    332373            psFree(sumCC);
     
    345386            }
    346387            pmSubtractionStamp *stamp = stamps->stamps->data[j]; // Stamp of interest
    347             subtractConvolution(inputs->data[j], stamp, bestIndex, bestCoeff, bestBG, footprint);
     388            subtractConvolution(targets->data[j], stamp, bestIndex, bestCoeff, bestBG, footprint, mode);
    348389        }
    349390
     
    361402        lastChi2 = bestChi2;
    362403    }
    363     psFree(inputs);
     404    psFree(targets);
    364405    psFree(sumC);
    365406    psFree(sumCC);
     
    401442                pmSubtractionStamp *stamp = stamps->stamps->data[j]; // Stamp of interest
    402443                psArray *convolutions = convNew->data[j]; // Convolutions for this stamp
    403                 convolutions->data[rank] = psMemIncrRefCounter(stamp->convolutions->data[i]);
     444                convolutions->data[rank] = psMemIncrRefCounter(selectConvolution(stamp, i, mode));
    404445            }
    405446        }
     
    420461        }
    421462        pmSubtractionStamp *stamp = stamps->stamps->data[i]; // Stamp of interest
    422         psFree(stamp->convolutions);
    423         stamp->convolutions = convNew->data[i];
     463        psFree(stamp->convolutions1);
     464        psFree(stamp->convolutions2);
     465        switch (mode) {
     466          case PM_SUBTRACTION_MODE_1:
     467            stamp->convolutions1 = convNew->data[i];
     468            stamp->convolutions2 = NULL;
     469            break;
     470          case PM_SUBTRACTION_MODE_2:
     471            stamp->convolutions1 = NULL;
     472            stamp->convolutions2 = convNew->data[i];
     473            break;
     474          default:
     475            psAbort("Unsupported subtraction mode: %x", mode);
     476        }
    424477    }
    425478
  • branches/eam_branch_20071023/psModules/src/imcombine/pmSubtractionParams.h

    r14804 r15516  
    1515                                                      const pmSubtractionStampList *stamps, ///< Stamps
    1616                                                      int footprint, ///< Convolution footprint for stamps
    17                                                       float tolerance ///< Maximum difference in chi^2
     17                                                      float tolerance, ///< Maximum difference in chi^2
     18                                                      pmSubtractionMode mode // Mode for subtraction
    1819    );
    1920
  • branches/eam_branch_20071023/psModules/src/imcombine/pmSubtractionStamps.c

    r15286 r15516  
    44
    55#include <stdio.h>
     6#include <string.h>
    67#include <pslib.h>
    78
     
    4546    psFree(stamp->matrix);
    4647    psFree(stamp->vector);
    47     psFree(stamp->reference);
    48     psFree(stamp->input);
     48    psFree(stamp->image1);
     49    psFree(stamp->image2);
    4950    psFree(stamp->weight);
    50     psFree(stamp->convolutions);
     51    psFree(stamp->convolutions1);
     52    psFree(stamp->convolutions2);
    5153}
    5254
     
    6567// Is this position unmasked?
    6668static bool checkStampMask(int x, int y, // Coordinates of stamp
    67                            const psImage *mask
     69                           const psImage *mask, // Mask
     70                           pmSubtractionMode mode // Mode for subtraction
    6871                           )
    6972{
     
    7477        return false;
    7578    }
    76     return (mask->data.PS_TYPE_MASK_DATA[y][x] & (PM_SUBTRACTION_MASK_BORDER |
    77                                                   PM_SUBTRACTION_MASK_FOOTPRINT | PM_SUBTRACTION_MASK_REJ)) ?
    78         false : true;
     79
     80    psMaskType maskVal = PM_SUBTRACTION_MASK_BORDER | PM_SUBTRACTION_MASK_REJ; // Mask value
     81    switch (mode) {
     82      case PM_SUBTRACTION_MODE_1:
     83      case PM_SUBTRACTION_MODE_TARGET:
     84        maskVal |= PM_SUBTRACTION_MASK_FOOTPRINT_1;
     85        break;
     86      case PM_SUBTRACTION_MODE_2:
     87        maskVal |= PM_SUBTRACTION_MASK_FOOTPRINT_2;
     88        break;
     89      case PM_SUBTRACTION_MODE_UNSURE:
     90      case PM_SUBTRACTION_MODE_DUAL:
     91        maskVal |= PM_SUBTRACTION_MASK_FOOTPRINT_1 | PM_SUBTRACTION_MASK_FOOTPRINT_2;
     92        break;
     93      default:
     94        psAbort("Unsupported subtraction mode: %x", mode);
     95    }
     96
     97    return (mask->data.PS_TYPE_MASK_DATA[y][x] & maskVal) ? false : true;
    7998}
    8099
     
    140159    stamp->status = PM_SUBTRACTION_STAMP_INIT;
    141160
    142     stamp->reference = NULL;
    143     stamp->input = NULL;
     161    stamp->image1 = NULL;
     162    stamp->image2 = NULL;
    144163    stamp->weight = NULL;
    145     stamp->convolutions = NULL;
     164    stamp->convolutions1 = NULL;
     165    stamp->convolutions2 = NULL;
    146166
    147167    return stamp;
     
    151171pmSubtractionStampList *pmSubtractionStampsFind(pmSubtractionStampList *stamps, const psImage *image,
    152172                                                const psImage *subMask, const psRegion *region,
    153                                                 float threshold, float spacing)
     173                                                float threshold, float spacing, pmSubtractionMode mode)
    154174{
    155175    PS_ASSERT_IMAGE_NON_NULL(image, NULL);
     
    226246            for (int y = subRegion->y0; y <= subRegion->y1 ; y++) {
    227247                for (int x = subRegion->x0; x <= subRegion->y1 ; x++) {
    228                     if (checkStampMask(x, y, subMask) && image->data.F32[y][x] > fluxStamp) {
     248                    if (checkStampMask(x, y, subMask, mode) && image->data.F32[y][x] > fluxStamp) {
    229249                        fluxStamp = image->data.F32[y][x];
    230250                        xStamp = x;
     
    242262
    243263            // Reset the postage stamps since we're making a new stamp
    244             psFree(stamp->reference);
    245             psFree(stamp->input);
     264            psFree(stamp->image1);
     265            psFree(stamp->image2);
    246266            psFree(stamp->weight);
    247             stamp->reference = stamp->input = stamp->weight = NULL;
    248 
    249             stamp->status = PM_SUBTRACTION_STAMP_CALCULATE;
     267            psFree(stamp->convolutions1);
     268            psFree(stamp->convolutions2);
     269            stamp->image1 = stamp->image2 = stamp->weight = NULL;
     270            stamp->convolutions1 = stamp->convolutions2 = NULL;
     271
     272            stamp->status = PM_SUBTRACTION_STAMP_FOUND;
    250273            numFound++;
    251274            psTrace("psModules.imcombine", 5, "Found stamp in subregion %d: %d,%d\n",
     
    266289pmSubtractionStampList *pmSubtractionStampsSet(const psVector *x, const psVector *y, const psVector *flux,
    267290                                               const psImage *image, const psImage *subMask,
    268                                                const psRegion *region, float spacing, int exclusionZone)
     291                                               const psRegion *region, float spacing, pmSubtractionMode mode)
     292
    269293{
    270294    PS_ASSERT_VECTOR_NON_NULL(x, NULL);
     
    289313    }
    290314    PS_ASSERT_FLOAT_LARGER_THAN(spacing, 0.0, NULL);
    291     PS_ASSERT_INT_NONNEGATIVE(exclusionZone, NULL);
    292315
    293316    int numStars = x->n;                // Number of stars
    294     psVector *exclude = psVectorAlloc(numStars, PS_TYPE_U8); // Exclude a star?
    295     psVectorInit(exclude, 0);
    296 
    297     // Apply exclusion zone around each star --- important when we're convolving to a specified PSF; less so
    298     // when we're trying to get a good subtraction.
    299     if (exclusionZone > 0) {
    300         psTrace("psModules.imcombine", 2, "Applying exclusion zone of %d pixels for stamps\n", exclusionZone);
    301         // We use something resembling a binary search --- coordinates are sorted in the x dimension, and then
    302         // to exclude stars within a nominated distance, we need only examine (i.e., calculate the
    303         // 2-dimensional distance to) other stars in the list that are within that distance of the x
    304         // coordinate of the star of interest.  By marking both stars when we find a violation of the
    305         // exclusion zone, we need only search upwards from the x coordinate of the star of interest.
    306 
    307         int minDistance2 = PS_SQR(exclusionZone); // Minimum square distance for other stars
    308         psVector *indexes = psVectorSortIndex(NULL, x); // Indices for sorting in x
    309         for (int i = 0; i < numStars - 1; i++) {
    310             int iIndex = indexes->data.S32[i]; // Index for star i
    311             if (exclude->data.U8[iIndex]) {
    312                 continue;
    313             }
    314             float ix = x->data.F32[iIndex], iy = y->data.F32[iIndex]; // Coordinates for star i
    315             float jx, jy;                   // Coordinates for star j
    316             for (int j = i + 1, jIndex = indexes->data.S32[j];
    317                  j < numStars && (jx = x->data.F32[jIndex]) < ix + exclusionZone;
    318                  j++, jIndex = indexes->data.S32[j]) {
    319                 jy = y->data.F32[jIndex];
    320                 if (PS_SQR(ix - jx) + PS_SQR(iy - jy) < minDistance2) {
    321                     exclude->data.U8[iIndex] = 0xff;
    322                     exclude->data.U8[jIndex] = 0xff;
    323                     psTrace("psModules.imcombine", 5, "Excluding stamps %d,%d and %d,%d\n",
    324                             (int)x->data.F32[iIndex], (int)y->data.F32[iIndex],
    325                             (int)x->data.F32[jIndex], (int)y->data.F32[jIndex]);
    326                     // Would 'break' here, but there might be more stamps within the exclusion zone.
    327                 }
    328             }
    329         }
    330         psFree(indexes);
    331     }
    332 
    333317    pmSubtractionStampList *stamps = pmSubtractionStampListAlloc(subMask->numCols, subMask->numRows,
    334318                                                                 region, spacing); // Stamp list
     
    347331    // Put the stars into their appropriate subregions
    348332    for (int i = 0; i < numStars; i++) {
    349         if (exclude->data.U8[i]) {
    350             // Star has been excluded
    351             continue;
    352         }
    353333        float xStamp = x->data.F32[i], yStamp = y->data.F32[i]; // Coordinates of stamp
    354334        int xPix = xStamp + 0.5, yPix = yStamp + 0.5; // Pixel coordinate of stamp
     
    357337            continue;
    358338        }
    359         if (!checkStampMask(xPix, yPix, subMask)) {
     339        if (!checkStampMask(xPix, yPix, subMask, mode)) {
    360340            // Not a good stamp
    361341            continue;
     
    386366        }
    387367    }
    388     psFree(exclude);
    389368
    390369    // Sort the list by flux, with the brightest last
     
    421400
    422401
    423 bool pmSubtractionStampsExtract(pmSubtractionStampList *stamps, psImage *reference, psImage *input,
     402bool pmSubtractionStampsExtract(pmSubtractionStampList *stamps, psImage *image1, psImage *image2,
    424403                                psImage *weight, int footprint, int kernelSize)
    425404{
    426405    PM_ASSERT_SUBTRACTION_STAMP_LIST_NON_NULL(stamps, false);
    427     PS_ASSERT_IMAGE_NON_NULL(reference, false);
    428     PS_ASSERT_IMAGE_TYPE(reference, PS_TYPE_F32, false);
    429     if (input) {
    430         PS_ASSERT_IMAGE_NON_NULL(input, false);
    431         PS_ASSERT_IMAGES_SIZE_EQUAL(input, reference, false);
    432         PS_ASSERT_IMAGE_TYPE(input, PS_TYPE_F32, false);
    433     }
    434     if (weight) {
    435         PS_ASSERT_IMAGE_NON_NULL(weight, false);
    436         PS_ASSERT_IMAGES_SIZE_EQUAL(weight, reference, false);
    437         PS_ASSERT_IMAGE_TYPE(weight, PS_TYPE_F32, false);
    438     }
     406    PS_ASSERT_IMAGE_NON_NULL(image1, false);
     407    PS_ASSERT_IMAGE_TYPE(image1, PS_TYPE_F32, false);
     408    if (image2) {
     409        PS_ASSERT_IMAGE_NON_NULL(image2, false);
     410        PS_ASSERT_IMAGES_SIZE_EQUAL(image2, image1, false);
     411        PS_ASSERT_IMAGE_TYPE(image2, PS_TYPE_F32, false);
     412    }
     413    PS_ASSERT_IMAGE_NON_NULL(weight, false);
     414    PS_ASSERT_IMAGES_SIZE_EQUAL(weight, image1, false);
     415    PS_ASSERT_IMAGE_TYPE(weight, PS_TYPE_F32, false);
    439416    PS_ASSERT_INT_NONNEGATIVE(footprint, false);
    440417    PS_ASSERT_INT_NONNEGATIVE(kernelSize, false);
    441418
    442     int numCols = reference->numCols, numRows = reference->numRows; // Size of images
     419    int numCols = image1->numCols, numRows = image1->numRows; // Size of images
    443420    int size = kernelSize + footprint; // Size of postage stamps
    444 
    445     if (!weight) {
    446         // Use the input (or if I must, the reference) as a rough approximation to the variance map, and HOPE
    447         // that it's positive.
    448         weight = input ? input : reference;
    449     }
    450421
    451422    for (int i = 0; i < stamps->num; i++) {
    452423        pmSubtractionStamp *stamp = stamps->stamps->data[i]; // Stamp of interest
    453         if (!stamp || stamp->status != PM_SUBTRACTION_STAMP_CALCULATE) {
     424        if (!stamp || stamp->status != PM_SUBTRACTION_STAMP_FOUND) {
    454425            continue;
    455426        }
     
    468439        }
    469440
     441        // Catch memory leaks --- these should have been freed and NULLed before
     442        assert(stamp->image1 == NULL);
     443        assert(stamp->image2 == NULL);
     444        assert(stamp->weight == NULL);
     445
    470446        psRegion region = psRegionSet(x - size, x + size + 1, y - size, y + size + 1); // Region of interest
    471447
    472         psImage *refSub = psImageSubset(reference, region); // Subimage with stamp
    473         stamp->reference = psKernelAllocFromImage(refSub, size, size);
    474         psFree(refSub);                 // Drop reference
    475 
    476         if (input) {
    477             psImage *inSub = psImageSubset(input, region); // Subimage with stamp
    478             stamp->input = psKernelAllocFromImage(inSub, size, size);
    479             psFree(inSub);              // Drop reference
     448        psImage *sub1 = psImageSubset(image1, region); // Subimage with stamp
     449        stamp->image1 = psKernelAllocFromImage(sub1, size, size);
     450        psFree(sub1);                   // Drop reference
     451
     452        if (image2) {
     453            psImage *sub2 = psImageSubset(image2, region); // Subimage with stamp
     454            stamp->image2 = psKernelAllocFromImage(sub2, size, size);
     455            psFree(sub2);               // Drop reference
    480456        }
    481457
    482458        psImage *wtSub = psImageSubset(weight, region); // Subimage with stamp
    483459        stamp->weight = psKernelAllocFromImage(wtSub, size, size);
    484         psFree(wtSub);                 // Drop reference
     460        psFree(wtSub);                  // Drop reference
     461
     462        stamp->status = PM_SUBTRACTION_STAMP_CALCULATE;
    485463    }
    486464
     
    488466}
    489467
    490 
     468#if 0
    491469bool pmSubtractionStampsGenerate(pmSubtractionStampList *stamps, float fwhm, int footprint, int kernelSize)
    492470{
     
    517495        float yStamp = y - (int)(y + 0.5); // y coordinate of star in stamp frame
    518496
    519         psFree(stamp->input);
    520         stamp->input = psKernelAlloc(-size, size, -size, size);
    521         psKernel *input = stamp->input; // Target stamp
     497        psFree(stamp->image2);
     498        stamp->image2 = psKernelAlloc(-size, size, -size, size);
     499        psKernel *target = stamp->image2; // Target stamp
    522500
    523501        // Put in a Waussian, just for fun!
     
    525503            for (int u = -size; u <= size; u++) {
    526504                float z = (PS_SQR(u + xStamp) + PS_SQR(v + yStamp)) / (2.0 * PS_SQR(sigma));
    527                 input->kernel[v][u] = flux / sigma * 0.5 * M_2_SQRTPI * M_SQRT1_2 / (1.0 + z + PS_SQR(z));
     505                target->kernel[v][u] = flux / sigma * 0.5 * M_2_SQRTPI * M_SQRT1_2 / (1.0 + z + PS_SQR(z));
    528506            }
    529507        }
     
    533511    return true;
    534512}
    535 
     513#endif
    536514
    537515pmSubtractionStampList *pmSubtractionStampsSetFromSources(const psArray *sources, const psImage *subMask,
    538516                                                          const psRegion *region, float spacing,
    539                                                           int exclusionZone)
     517                                                          pmSubtractionMode mode)
    540518{
    541519    PS_ASSERT_ARRAY_NON_NULL(sources, NULL);
     
    561539
    562540    pmSubtractionStampList *stamps = pmSubtractionStampsSet(x, y, flux, NULL, subMask, region,
    563                                                             spacing, exclusionZone); // Stamps to return
     541                                                            spacing, mode); // Stamps to return
    564542    psFree(x);
    565543    psFree(y);
     
    572550    return stamps;
    573551}
     552
     553
     554pmSubtractionStampList *pmSubtractionStampsSetFromFile(const char *filename, const psImage *subMask,
     555                                                       const psRegion *region, float spacing,
     556                                                       pmSubtractionMode mode)
     557{
     558    PS_ASSERT_STRING_NON_EMPTY(filename, NULL);
     559    // Let pmSubtractionStampsSet take care of the rest of the assertions
     560
     561    const char *format = (mode == PM_SUBTRACTION_MODE_TARGET ? "%f %f %f" : "%f %f"); // Format of file
     562    psArray *data = psVectorsReadFromFile(filename, format);
     563    if (!data) {
     564        psError(PS_ERR_IO, false, "Unable to read stamps file %s", filename);
     565        return NULL;
     566    }
     567    psVector *x = data->data[0], *y = data->data[1]; // Stamp positions
     568    psVector *flux = (mode == PM_SUBTRACTION_MODE_TARGET ? data->data[2] : NULL); // Stamp fluxes
     569
     570    // Correct for IRAF/FITS (unit-offset) positions to C (zero-offset) positions
     571    psBinaryOp(x, x, "-", psScalarAlloc(1.0, PS_TYPE_F32));
     572    psBinaryOp(y, y, "-", psScalarAlloc(1.0, PS_TYPE_F32));
     573
     574    pmSubtractionStampList *stamps = pmSubtractionStampsSet(x, y, flux, NULL, subMask, region, spacing,
     575                                                            mode);
     576    psFree(data);
     577
     578    return stamps;
     579
     580}
  • branches/eam_branch_20071023/psModules/src/imcombine/pmSubtractionStamps.h

    r14802 r15516  
    99typedef enum {
    1010    PM_SUBTRACTION_STAMP_INIT,          ///< Initial state
     11    PM_SUBTRACTION_STAMP_FOUND,         ///< Found a suitable source for this stamp
     12    PM_SUBTRACTION_STAMP_CALCULATE,     ///< Calculate matrix and vector values for this stamp
    1113    PM_SUBTRACTION_STAMP_USED,          ///< Use this stamp
    1214    PM_SUBTRACTION_STAMP_REJECTED,      ///< This stamp has been rejected
    13     PM_SUBTRACTION_STAMP_CALCULATE,     ///< Calculate matrix and vector values for this stamp
    1415    PM_SUBTRACTION_STAMP_NONE           ///< No stamp in this region
    1516} pmSubtractionStampStatus;
     
    5455    float flux;                         ///< Flux
    5556    float xNorm, yNorm;                 ///< Normalised position
    56     psKernel *reference;                ///< Reference image postage stamp
    57     psKernel *input;                    ///< Input image postage stamp
     57    psKernel *image1;                   ///< Reference image postage stamp
     58    psKernel *image2;                   ///< Input image postage stamp
    5859    psKernel *weight;                   ///< Weight image postage stamp
    59     psArray *convolutions;              ///< Convolutions of the reference for each kernel component
     60    psArray *convolutions1;             ///< Convolutions of image 1 for each kernel component
     61    psArray *convolutions2;             ///< Convolutions of image 2 for each kernel component
    6062    psImage *matrix;                    ///< Associated matrix
    6163    psVector *vector;                   ///< Assoicated vector
     
    7274                                                const psRegion *region, ///< Region to search, or NULL
    7375                                                float threshold, ///< Threshold for stamps in the image
    74                                                 float spacing ///< Rough spacing for stamps
     76                                                float spacing, ///< Rough spacing for stamps
     77                                                pmSubtractionMode mode ///< Mode for subtraction
    7578    );
    7679
    7780/// Set stamps based on a list of x,y
    78 ///
    79 /// We may optionally apply an exclusion zone around each star --- this is important when we're convolving to
    80 /// a specified PSF; less so when we're only trying to get a good subtraction.
    8181pmSubtractionStampList *pmSubtractionStampsSet(const psVector *x, ///< x coordinates for each stamp
    8282                                               const psVector *y, ///< y coordinates for each stamp
     
    8686                                               const psRegion *region, ///< Region to search, or NULL
    8787                                               float spacing, ///< Rough spacing for stamps
    88                                                int exclusionZone ///< Exclusion zone around each star
     88                                               pmSubtractionMode mode ///< Mode for subtraction
    8989    );
    9090
    91 ///
     91/// Set stamps based on a list of sources
    9292pmSubtractionStampList *pmSubtractionStampsSetFromSources(
    93     const psArray *sources, ///< Sources for each stamp
    94     const psImage *subMask, ///< Mask, or NULL
    95     const psRegion *region, ///< Region to search, or NULL
    96     float spacing, ///< Rough spacing for stamps
    97     int exclusionZone ///< Exclusion zone around each star
     93    const psArray *sources,             ///< Sources for each stamp
     94    const psImage *subMask,             ///< Mask, or NULL
     95    const psRegion *region,             ///< Region to search, or NULL
     96    float spacing,                      ///< Rough spacing for stamps
     97    pmSubtractionMode mode              ///< Mode for subtraction
     98    );
     99
     100/// Set stamps based on values in a file
     101pmSubtractionStampList *pmSubtractionStampsSetFromFile(
     102    const char *filename,               ///< Filename of file containing x,y (or x,y,flux) on each line
     103    const psImage *subMask,             ///< Mask, or NULL
     104    const psRegion *region,             ///< Region to search, or NULL
     105    float spacing,                      ///< Rough spacing for stamps
     106    pmSubtractionMode mode              ///< Mode for subtraction
    98107    );
    99108
     
    107116    );
    108117
    109 /// Generate target for stamps based on list
    110 bool pmSubtractionStampsGenerate(pmSubtractionStampList *stamps, ///< Stamps
    111                                  float fwhm, ///< FWHM for each stamp
    112                                  int footprint, ///< Stamp footprint size
    113                                  int size ///< Kernel half-size
    114     );
    115 
    116118#endif
  • branches/eam_branch_20071023/psModules/src/objects/pmTrend2D.c

    r15414 r15516  
    33 *  @author EAM, IfA
    44 *
    5  *  @version $Revision: 1.4.2.1 $ $Name: not supported by cvs2svn $
    6  *  @date $Date: 2007-10-29 22:42:34 $
     5 *  @version $Revision: 1.4.2.2 $ $Name: not supported by cvs2svn $
     6 *  @date $Date: 2007-11-08 22:59:04 $
    77 *
    88 *  Copyright 2004 Institute for Astronomy, University of Hawaii
     
    1111// XXXX: Ignore (2)
    1212
     13// XXXX: ignore
     14
     15// XXXX: ignore
     16
    1317#ifdef HAVE_CONFIG_H
    1418#include <config.h>
     
    3236pmTrend2D *pmTrend2DAlloc (pmTrend2DMode mode, psImage *image, int nXtrend, int nYtrend, psStats *stats)
    3337{
    34     assert (image);
     38    PS_ASSERT_PTR_NON_NULL(stats, NULL);
     39    if (mode == PM_TREND_MAP) {
     40        PS_ASSERT_PTR_NON_NULL(image, NULL);
     41    }
    3542
    3643    pmTrend2D *trend = (pmTrend2D *) psAlloc(sizeof(pmTrend2D));
     
    7380          break;
    7481      }
    75 
     82      // XXX: Put a more graceful error here.
    7683      default:
    7784        psAbort ("error");
    7885    }
    7986    return (trend);
     87}
     88
     89bool psMemCheckTrend2D(psPtr ptr)
     90{
     91    PS_ASSERT_PTR(ptr, false);
     92    return ( psMemGetDeallocator(ptr) == (psFreeFunc) pmTrend2DFree);
    8093}
    8194
     
    123136pmTrend2D *pmTrend2DFieldAlloc (pmTrend2DMode mode, int nXfield, int nYfield, int nXtrend, int nYtrend, psStats *stats)
    124137{
     138    PS_ASSERT_PTR_NON_NULL(stats, NULL);
    125139    pmTrend2D *trend = (pmTrend2D *) psAlloc(sizeof(pmTrend2D));
    126140    psMemSetDeallocator(trend, (psFreeFunc) pmTrend2DFree);
     
    164178
    165179      default:
     180        // XXX: Put a more graceful error here.
    166181        psAbort ("error");
    167182    }
     
    169184}
    170185
    171 bool pmTrend2DFit (pmTrend2D *trend, psVector *mask, psMaskType maskVal, psVector *x, psVector *y, psVector *f, psVector *df) {
     186bool pmTrend2DFit (pmTrend2D *trend, psVector *mask, psMaskType maskVal, psVector *x,
     187                   psVector *y, psVector *f, psVector *df)
     188{
     189    PS_ASSERT_PTR_NON_NULL(trend, false);
    172190
    173191    bool status;
     
    199217}
    200218
    201 double pmTrend2DEval (pmTrend2D *trend, float x, float y) {
     219double pmTrend2DEval (pmTrend2D *trend, float x, float y)
     220{
     221    if (!trend) return 0.0;
    202222
    203223    double result;
    204 
    205     assert (trend);
    206 
    207224    switch (trend->mode) {
    208225      case PM_TREND_POLY_ORD:
     
    221238}
    222239
    223 psVector *pmTrend2DEvalVector (pmTrend2D *trend, psVector *x, psVector *y) {
    224 
     240psVector *pmTrend2DEvalVector (pmTrend2D *trend, psVector *x, psVector *y)
     241{
     242    PS_ASSERT_PTR_NON_NULL(trend, NULL);
    225243    psVector *result;
    226244
Note: See TracChangeset for help on using the changeset viewer.