IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Aug 7, 2009, 4:08:25 PM (17 years ago)
Author:
Paul Price
Message:

Merging trunk (r25026) to get up-to-date on old branch.

Location:
branches/pap
Files:
17 edited
1 copied

Legend:

Unmodified
Added
Removed
  • branches/pap

  • branches/pap/magic

    • Property svn:ignore set to
      magic
      ssa-core-cpp
      Makefile
      Makefile.bak
  • branches/pap/magic/remove/src

    • Property svn:ignore
      •  

        old new  
         1isdestreaked
        12streaksremove
        23streaksreplace
        34streakscompare
        45streaksrelease
         6makefile
  • branches/pap/magic/remove/src/Line.c

    r21156 r25027  
    1616{
    1717    double temp = *first;
     18    *first = *second;
     19    *second = temp;
     20}
     21
     22/** Internal routine to swap integer values */
     23
     24void SwapInt (int* first, int* second)
     25{
     26    int temp = *first;
    1827    *first = *second;
    1928    *second = temp;
     
    255264}
    256265
    257 /** Map a line to an image for its specified width and store as a list
    258     of pixel positions
     266/** Clip the line between (minX,minY) and (maxX,maxY)
     267
     268    @param[in,out] line line to be clipped within the bounds
     269    @param[in] minX minimum X (columns) for the line
     270    @param[in] minY minimum Y (rows) for the line
     271    @param[in] maxX maximum X (columns) for the line
     272    @param[in] maxY maximum Y (rows) for the line
     273    @return true if line overlaps the clip boundaries           */
     274
     275bool LineClipFull (Line *line, int minX, int minY, int maxX, int maxY)
     276{
     277    unsigned int i, found = 0;
     278    Line boundLine, clipLine;
     279    strkPt tuple1, tuple2, vertices[4];
     280    vertices[0].x = minX; vertices[0].y = minY;
     281    vertices[1].x = maxX; vertices[1].y = minY;
     282    vertices[2].x = maxX; vertices[2].y = maxY;
     283    vertices[3].x = minX; vertices[3].y = maxY;
     284
     285    for (i = 0; i < 4 && found < 2; ++i)
     286    {
     287        boundLine.begin = vertices[i];
     288        boundLine.end   = vertices[(i + 1) % 4];
     289        if (LineIntercept (line, &boundLine, &tuple1, &tuple2, false, true))
     290        {
     291            if (found == 0)
     292            {
     293                clipLine.begin = tuple1;
     294                ++found;
     295            }
     296            else if (tuple1.x != clipLine.begin.x ||
     297                     tuple1.y != clipLine.begin.y)
     298            {
     299                clipLine.end = tuple1;
     300                ++found;
     301            }
     302        }
     303    }
     304   
     305    // If two endpoints are found, clip the line
     306   
     307    if (found > 1)
     308    {
     309        if (clipLine.begin.x <= clipLine.end.x)
     310        {
     311            line->begin = clipLine.begin;
     312            line->end   = clipLine.end;
     313        }
     314        else
     315        {
     316            line->begin = clipLine.end;
     317            line->end   = clipLine.begin;
     318        }
     319    }
     320    return found > 1;
     321}
     322
     323/** Move a line by the specified X and Y offsets
     324    @param[in,out] line Line to move by X and Y offsets
     325    @param[in] xOffset X shift applied to both endpoints
     326    @param[in] yOffset Y shift applied to both endpoints        */
     327
     328void LineMove (Line *line, double xOffset, double yOffset)
     329{
     330    line->begin.x += xOffset;
     331    line->begin.y += yOffset;
     332    line->end.x   += xOffset;
     333    line->end.y   += yOffset;
     334}
     335
     336/** Return the maximum bounds between the line endpoints and
     337    current bounds
     338    @param[in] line Line endpoints to compare
     339    @param[in,out] xMin minimum X value to update
     340    @param[in,out] xMax maximum X value to update
     341    @param[in,out] yMin minimum Y value to update
     342    @param[in,out] yMax maximum Y value to update               */
     343
     344void MaxBounds (Line *line, int *xMin, int *xMax,  int *yMin, int *yMax)
     345{
     346    if (line->begin.x < *xMin) *xMin = (int) floor (line->begin.x);
     347    if (line->end.x   < *xMin) *xMin = (int) floor (line->end.x);
     348    if (line->begin.y < *yMin) *yMin = (int) floor (line->begin.y);
     349    if (line->end.y   < *yMin) *yMin = (int) floor (line->end.y);
     350
     351    if (line->begin.x > *xMax) *xMax = (int) ceil (line->begin.x);
     352    if (line->end.x   > *xMax) *xMax = (int) ceil (line->end.x);
     353    if (line->begin.y > *yMax) *yMax = (int) ceil (line->begin.y);
     354    if (line->end.y   > *yMax) *yMax = (int) ceil (line->end.y);
     355}
     356
     357/** Map a line to an image for its specified width and store as
     358    a list of pixel positions
    259359
    260360    @param[out] pixels list of PixelPos pointers corresponding
    261361                       based on the line settings
    262     @param[in] line Line to map to pixels                       */
    263 
    264 void PixelsFromLine (StreakPixels* pixels, Line *line)
    265 {
     362    @param[in] line Line to map to pixels   
     363    @param[in] numCols maximum X (columns) for the line
     364    @param[in] numRows maximum Y (rows) for the line            */
     365
     366void PixelsFromLine (StreakPixels* pixels, Line *line, int numCols, int numRows)
     367{
     368    Line offsetLine;
    266369    PixelPos *pixel;
    267     double slope, xOffset, yOffset, xMid, yMid, xBegin, yBegin, xEnd, yEnd, x, y;
     370    double slope, xOffset, yOffset, xMid, yMid;
     371    int x, y, xBegin = numCols, yBegin = numRows, xEnd = 0, yEnd = 0;
    268372
    269373    // Extract the endpoints
     
    280384    double dr = sqrt (dx * dx + dy * dy);
    281385    double halfWidth  = line->width / 2.0;
    282     double halfWidth2 = halfWidth * halfWidth;
    283386    if (!dr) return;
    284    
     387
     388    // Compute the intercepts of line width bounds and determine maximum
     389    // bounds in each axis
     390
     391    xOffset = -halfWidth * dy / dr;
     392    yOffset =  halfWidth * dx / dr;
     393
     394    offsetLine = *line;
     395    LineMove (&offsetLine, xOffset, yOffset);
     396    if (LineClip (&offsetLine, numCols, numRows))
     397        MaxBounds (&offsetLine, &xBegin, &xEnd, &yBegin, &yEnd);
     398
     399    offsetLine = *line;
     400    LineMove (&offsetLine, -xOffset, -yOffset);
     401    if (LineClip (&offsetLine, numCols, numRows))
     402        MaxBounds (&offsetLine, &xBegin, &xEnd, &yBegin, &yEnd);
     403
    285404    // Step point by point based on the dominate axis
    286405   
     
    307426        // Compute the x and y offsets for the line width extent
    308427
    309         xOffset = halfWidth * dy / dr;
    310         yOffset = halfWidth * dr / dx;
    311         yMid   = y1 + slope * (floor (x1 - xOffset) - x1);
    312         xBegin = floor (x1 - xOffset);
    313         xEnd   = ceil  (x2 + xOffset) + 1.0;
    314 
    315         for (x = xBegin; x < xEnd; ++x)
    316         {
    317             yBegin = floor (yMid - yOffset);
    318             yEnd   = ceil  (yMid + yOffset) + 1.0;
    319             for (y = yBegin; y < yEnd; ++y)
    320             {
    321                 if (DistanceSquared (line, x, y) <= halfWidth2)
     428        if (xBegin > xEnd)
     429            SwapInt (&xBegin, &xEnd);
     430        else
     431            ++xEnd;
     432        if (xBegin < 0) xBegin = 0;
     433        if (xEnd > numCols) xEnd = numCols;
     434
     435        yMid = y1 + slope * (xBegin - x1);
     436        yOffset = fabs (halfWidth * dr / dx);
     437
     438        for (x = xBegin; x != xEnd; ++x)
     439        {
     440            yBegin = (int) floor (yMid - yOffset);
     441            yEnd   = (int) ceil  (yMid + yOffset) + 1;
     442            for (y = yBegin; y != yEnd; ++y)
     443            {
     444                if (y >= 0 && y < numRows)
    322445                {
    323                     if (x >=0 && y >= 0) {
    324                         pixel = psAlloc (sizeof(PixelPos));
    325                         pixel->x = (unsigned int) x;
    326                         pixel->y = (unsigned int) y;
    327                         psArrayAdd (pixels, 1024, pixel);
    328                         psFree (pixel);
    329                     }
     446                    psImageSet(pixels, x, y, 1);
    330447                }
    331448            }
     
    354471       
    355472        // Compute the x and y offsets for the line width extent
    356        
    357         xOffset = halfWidth * dr / dy;
    358         yOffset = halfWidth * dx / dr;
    359 
    360         xMid   = x1 + slope * (floor (y1 - yOffset) - y1);
    361         yBegin = floor (y1 - yOffset);
    362         yEnd   = ceil  (y2 + yOffset) + 1.0;
    363        
    364         for (y = yBegin; y < yEnd; ++y)
    365         {
    366             xBegin = floor (xMid - xOffset);
    367             xEnd   = ceil  (xMid + xOffset) + 1.0;
    368             for (x = xBegin; x < xEnd; ++x)
    369             {
    370                 if (DistanceSquared (line, x, y) <= halfWidth2)
     473
     474        if (yBegin > yEnd)
     475            SwapInt (&yBegin, &yEnd);
     476        else
     477            ++yEnd;
     478        if (yBegin < 0) yBegin = 0;
     479        if (yEnd > numRows) yEnd = numRows;
     480
     481        xMid = x1 + slope * (yBegin - y1);
     482        xOffset = fabs (halfWidth * dr / dy);
     483       
     484        for (y = yBegin; y != yEnd; ++y)
     485        {
     486            xBegin = (int) floor (xMid - xOffset);
     487            xEnd   = (int) ceil  (xMid + xOffset) + 1;
     488            for (x = xBegin; x != xEnd; ++x)
     489            {
     490                if (x >=0 && x < numCols)
    371491                {
    372                     if (x >=0 && y >= 0) {
    373                         pixel = psAlloc (sizeof(PixelPos));
    374                         pixel->x = (unsigned int) x;
    375                         pixel->y = (unsigned int) y;
    376                         psArrayAdd (pixels, 1024, pixel);
    377                         psFree (pixel);
    378                     }
     492                    psImageSet(pixels, x, y, 1);
    379493                }
    380494            }
  • branches/pap/magic/remove/src/Line.h

    r20308 r25027  
    2121extern bool LineClip (Line *line, int numCols, int numRows);
    2222
     23/** Clip the line between (minX,minY) and (maxX,maxY)
     24
     25    @param[in,out] line line to be clipped within the bounds
     26    @param[in] minX minimum X (columns) for the line
     27    @param[in] minY minimum Y (rows) for the line
     28    @param[in] maxX maximum X (columns) for the line
     29    @param[in] maxY maximum Y (rows) for the line
     30    @return true if line overlaps the clip boundaries           */
     31
     32extern bool LineClipFull (Line *line, int minX, int minY, int maxX, int maxY);
     33
    2334/** Map a line to an image for its specified width and append as
    2435    a list of pixel positions
     
    2637    @param[out] pixels list of PixelPos pointers corresponding
    2738                       based on the line settings
    28     @param[in] line Line to map to pixels                       */
     39    @param[in] line Line to map to pixels   
     40    @param[in] numCols maximum X (columns) for the line
     41    @param[in] numRows maximum Y (rows) for the line            */
    2942
    30 extern void PixelsFromLine (StreakPixels* pixels, Line *line);
     43extern void PixelsFromLine (StreakPixels* pixels, Line *line,
     44                            int numCols, int numRows);
    3145
    3246#endif /* STREAK_LINE_H */
  • branches/pap/magic/remove/src/Makefile.simple

    r23910 r25027  
    2828    streaksrelease.o
    2929
    30 # STREAKSFLAGS=-DSTREAKS_COMPRESS_OUTPUT=1
     30ISDESTREAKED_OBJECTS=      \
     31    ${COMMON_OBJECTS} \
     32    isdestreaked.o
     33
     34
     35HEADERS= Line.h  streaksastrom.h  streaksextern.h  streaksio.h  streaksremove.h
     36
     37STREAKSFLAGS=-DSTREAKS_COMPRESS_OUTPUT=1
    3138OPTFLAGS= -g -O2
    32 OPTFLAGS= -g
     39#OPTFLAGS= -g
    3340CFLAGS=`psmodules-config --cflags` -std=gnu99 ${OPTFLAGS} ${STREAKSFLAGS}
    3441#CFLAGS=`psmodules-config --cflags` -std=gnu99 ${OPTFLAGS}
    3542LDFLAGS=`psmodules-config --libs`
    3643
    37 PROGRAMS= streaksremove streaksreplace streakscompare streaksrelease
     44PROGRAMS= streaksremove streaksreplace streakscompare streaksrelease isdestreaked
     45HEADERS=Line.h streaksastrom.h streaksextern.h streaksio.h streaksremove.h
    3846
    3947all:    ${PROGRAMS}
    4048
     49${REMOVE_OBJECTS}:      ${HEADERS}
    4150streaksremove:  ${REMOVE_OBJECTS}
    4251
     
    4756streaksrelease:  ${RELEASE_OBJECTS}
    4857
     58isdestreaked:   ${ISDESTREAKED_OBJECTS}
     59
     60
    4961install:        ${PROGRAMS}
    5062        install -t  $(PSCONFDIR)/$(PSCONFIG)/bin streaksremove
     
    5264        install -t  $(PSCONFDIR)/$(PSCONFIG)/bin streakscompare
    5365        install -t  $(PSCONFDIR)/$(PSCONFIG)/bin streaksrelease
     66        install -t  $(PSCONFDIR)/$(PSCONFIG)/bin isdestreaked
    5467
    5568clean:
  • branches/pap/magic/remove/src/streaksastrom.c

    r21437 r25027  
    150150 
    151151bool
     152SkyToLocal(strkPt *outPt, strkAstrom *astrom, double ra, double dec)
     153{
     154    // generate a local project using the RA, DEC of the 0,0 pixel of the chip as the
     155    // projection center with the same plate scale as the nominal TP->Sky astrometry.
     156
     157    pmFPA *fpa   = (pmFPA *) astrom->fpa;
     158    pmChip *chip = (pmChip *) astrom->chip;
     159
     160    // find the RA,DEC coords of the 0,0 pixel for this chip:
     161
     162    psPlane ptTP;
     163    psSphere ptSky;
     164
     165    ptSky.r = ra;
     166    ptSky.d = dec;
     167    ptSky.rErr = 0.0;
     168    ptSky.dErr = 0.0;
     169
     170    psProject(&ptTP, &ptSky, fpa->toSky);
     171
     172    outPt->x = ptTP.x;
     173    outPt->y = ptTP.y;
     174
     175    return true;
     176}
     177
     178bool
     179LocalToSky(strkPt *outPt, strkAstrom *astrom, strkPt *inPt)
     180{
     181    // generate a local project using the RA, DEC of the 0,0 pixel of the chip as the
     182    // projection center with the same plate scale as the nominal TP->Sky astrometry.
     183
     184    pmFPA *fpa   = (pmFPA *) astrom->fpa;
     185    pmChip *chip = (pmChip *) astrom->chip;
     186
     187    // find the RA,DEC coords of the 0,0 pixel for this chip:
     188
     189    psPlane ptTP;
     190    psSphere ptSky;
     191
     192    ptTP.x = inPt->x;
     193    ptTP.y = inPt->y;
     194    ptTP.xErr = 0.0;
     195    ptTP.yErr = 0.0;
     196
     197    psDeproject(&ptSky, &ptTP, fpa->toSky);
     198
     199    outPt->x = ptSky.r;
     200    outPt->y = ptSky.d;
     201
     202    return true;
     203}
     204
     205bool
     206componentBounds(int *minX, int *minY, int *maxX, int *maxY, strkAstrom *astrom, int numCols, int numRows)
     207{
     208    // find the bounds of the (padded) chip region in tangent-plane coordinates
     209
     210    pmFPA *fpa   = (pmFPA *) astrom->fpa;
     211    pmChip *chip = (pmChip *) astrom->chip;
     212
     213    psPlane ptCH, ptFP, TPo, TPx, TPy;
     214
     215    // coordinate of the chip center:
     216    ptCH.x = 0.5*numCols;
     217    ptCH.y = 0.5*numRows;
     218    psPlaneTransformApply(&ptFP, chip->toFPA, &ptCH);
     219    psPlaneTransformApply(&TPo, fpa->toTPA,  &ptFP);
     220
     221    // coordinate of the chip center + dX/2:
     222    ptCH.x = numCols;
     223    ptCH.y = 0.5*numRows;
     224    psPlaneTransformApply(&ptFP, chip->toFPA, &ptCH);
     225    psPlaneTransformApply(&TPx, fpa->toTPA,  &ptFP);
     226
     227    // coordinate of the chip center + dY/2:
     228    ptCH.x = 0.5*numCols;
     229    ptCH.y = numRows;
     230    psPlaneTransformApply(&ptFP, chip->toFPA, &ptCH);
     231    psPlaneTransformApply(&TPy, fpa->toTPA,  &ptFP);
     232
     233    // half-lengths of the two sides in tangent-plane coords:
     234    double xSize = hypot (TPx.x - TPo.x, TPx.y - TPo.y);
     235    double ySize = hypot (TPy.x - TPo.x, TPy.y - TPo.y);
     236    double radius = hypot (xSize, ySize);
     237
     238    // define the region encompassed by the radius with some padding:
     239    *minX = TPo.x - 1.1*radius;
     240    *minY = TPo.y - 1.1*radius;
     241    *maxX = TPo.x + 1.1*radius;
     242    *maxY = TPo.y + 1.1*radius;
     243
     244    return true;
     245}
     246
     247bool
    152248skyToCell(strkPt *outPt, strkAstrom *astrom, double ra, double dec)
    153249{
     
    281377}
    282378
    283 void
     379bool
    284380linearizeTransforms(strkAstrom *astrom)
    285381{
    286382    if (!pmAstromLinearizeTransforms((pmFPA *) astrom->fpa, (pmChip *) astrom->chip)) {
    287         streaksExit("linear fit to astrometry failed\n", PS_EXIT_UNKNOWN_ERROR);
    288     }
    289 }
     383        // streaksExit("linear fit to astrometry failed\n", PS_EXIT_UNKNOWN_ERROR);
     384        psError(PS_ERR_UNKNOWN, false, "linear fit to astrometry failed ignoring");
     385        return false;
     386    }
     387    return true;
     388}
  • branches/pap/magic/remove/src/streaksastrom.h

    r21155 r25027  
    3030extern bool skyToCell(strkPt *, strkAstrom *astrom, double ra, double dec);
    3131extern bool cellToSky(strkPt *, strkAstrom *astrom, double x, double y);
    32 extern void linearizeTransforms(strkAstrom *astrom);
     32extern bool linearizeTransforms(strkAstrom *astrom);
     33
     34extern bool SkyToLocal(strkPt *outPt, strkAstrom *astrom, double ra, double dec);
     35extern bool LocalToSky(strkPt *outPt, strkAstrom *astrom, strkPt *inPt);
     36extern bool componentBounds(int *minX, int *minY, int *maxX, int *maxY, strkAstrom *astrom, int numCols, int numRows);
    3337
    3438#endif // STREAKS_ASTROM_H
  • branches/pap/magic/remove/src/streaksextern.c

    r21439 r25027  
    3434    int i;
    3535    Line line;
    36     StreakPixels *pixels = psArrayAllocEmpty (1024);
     36    StreakPixels *pixels = psImageAlloc(numCols, numRows, PS_TYPE_U8);
     37    psImageInit(pixels, 0);
    3738    int streaksOnComponent = 0;
     39
     40    int minX, minY, maxX, maxY;
     41
     42    // find the chip dimensions in the tangent-plane coordinates (length of hypotenuse)
     43    componentBounds (&minX, &minY, &maxX, &maxY, astrom, numCols, numRows);
     44
    3845    for (i = 0; i != streaks->size; ++i)
    3946    {
     
    4148
    4249        line.width = streaks->list[i].width;
    43         if (skyToCell (&line.begin, astrom,
    44                        streaks->list[i].ra1, streaks->list[i].dec1) &&
    45             skyToCell (&line.end, astrom,
    46                        streaks->list[i].ra2, streaks->list[i].dec2) &&
     50
     51        /* Use tangent plane coordinates to narrow down the ra,dec range of the line closer to
     52         * the chip boundaries.  Use these new ra,dec positions to generate the line on the
     53         * chip using the full non-linear astrometry */
     54           
     55        // project the ends of the line using a linear projection centered on the chip center:
     56        Line full;
     57        SkyToLocal (&full.begin, astrom, streaks->list[i].ra1, streaks->list[i].dec1);
     58        SkyToLocal (&full.end,   astrom, streaks->list[i].ra2, streaks->list[i].dec2);
     59
     60        // clip the line to a square box with diameter = hypotenuse of the chip image centerd
     61        // on the chip center in tangent-plane coordinates.  skip the rest of this streak if
     62        // the line does not intersect this region
     63        if (!LineClipFull (&full, minX, minY, maxX, maxY)) {
     64            continue;
     65        }
     66
     67        // convert the end points back into ra, dec pairs:
     68        strkPt sky1, sky2;
     69        LocalToSky (&sky1, astrom, &full.begin);
     70        LocalToSky (&sky2, astrom, &full.end);
     71
     72        if (skyToCell (&line.begin, astrom, sky1.x, sky1.y) &&
     73            skyToCell (&line.end,   astrom, sky2.x, sky2.y) &&
    4774            LineClip (&line, numCols, numRows))
    4875        {
    49             PixelsFromLine (pixels, &line);
     76            PixelsFromLine (pixels, &line, numCols, numRows);
    5077            streaksOnComponent++;
    5178        }
  • branches/pap/magic/remove/src/streaksextern.h

    r20308 r25027  
    44/** psLib includes */
    55
    6 #include "psArray.h"
     6#include "psImage.h"
    77
    88/** streakremove includes */
     
    3636/** For now, use psArray to define a list of PixelPos pointers */
    3737
    38 typedef psArray StreakPixels;
     38typedef psImage StreakPixels;
    3939
    4040/** Create a list of pixel positions from a Streaks pointer list
  • branches/pap/magic/remove/src/streaksio.c

    r23946 r25027  
    1010static nebServer *ourNebServer = NULL;
    1111
     12// Assumptions about the file structure of non-raw files
     13// The 'image' for each file (image, mask weight) is contained in the first
     14// extension.
     15
     16
    1217// open the files required for streaks procesing.
    1318// if remove is true the calling program is streaksremove and the recovery files are outputs
    1419// if false the recovery files are inputs
    15 streakFiles *openFiles(pmConfig *config, bool remove)
     20streakFiles *openFiles(pmConfig *config, bool remove, char *program_name)
    1621{
    1722    bool status;
     
    2126
    2227    sf->config = config;
     28    sf->program_name = basename(program_name);
     29
     30    if (remove) {
     31        // remember pointer so that streaksExit can delete temps
     32        setStreakFiles(sf);
     33    }
     34
    2335
    2436    // error checking is done by sFileOpen. If a file can't be opened we just exit
     
    5971    // if we are passed a mask it is camera stage mask and we also
    6072    // need to destreak the chip level mask file as well
     73    // If it doesn't exist, we didn't have a camera mask
    6174    if (remove && sf->inMask && (stage == IPP_STAGE_CHIP)) {
    62         sf->inChMask = sFileOpen(config, stage, "INPUT.CHMASK", NULL, true);
    63         inputBasename = basename(sf->inChMask->name);
    64         sf->outChMask = sFileOpen(config, stage, "OUTPUT", inputBasename, true);
    65         sf->recChMask = sFileOpen(config, stage, "RECOVERY", inputBasename, false);
     75        sf->inChMask = sFileOpen(config, stage, "INPUT.CHMASK", NULL, false);
     76        if (sf->inChMask) {
     77            inputBasename = basename(sf->inChMask->name);
     78            sf->outChMask = sFileOpen(config, stage, "OUTPUT", inputBasename, true);
     79            sf->recChMask = sFileOpen(config, stage, "RECOVERY", inputBasename, false);
     80        }
    6681    }
    6782
     
    7489        } else {
    7590            sf->recWeight = sFileOpen(config, stage, "RECOVERY.WEIGHT", NULL, true);
     91        }
     92    }
     93    if (remove) {
     94        sf->inSources = sFileOpen(config, stage, "SOURCES", NULL, false);
     95        if (sf->inSources) {
     96            inputBasename = basename(sf->inSources->name);
     97            sf->outSources = sFileOpen(config, stage, "OUTPUT", inputBasename, true);
    7698        }
    7799    }
     
    159181}
    160182
     183// figure out if a nebulous instance is a non-destreaked file
     184static bool
     185nebFileIsDestreaked(sFile *sfile)
     186{
     187    if (!sfile->resolved_name) {
     188        psError(PS_ERR_PROGRAMMING, true, "resolved name is null");
     189        return false;
     190    }
     191    psFits *fits = psFitsOpen(sfile->resolved_name, "r");
     192    if (!fits) {
     193        psError(PS_ERR_IO, true, "failed open %s", sfile->name);
     194        // can't tell if it is a destreaked file
     195        return false;
     196    }
     197    psMetadata *header = psFitsReadHeader(NULL, fits);
     198    if (!header) {
     199        psError(PS_ERR_IO, true, "failed to read header for: %s", sfile->name);
     200        return false;
     201    }
     202    bool mdok;
     203    bool isDestreaked = psMetadataLookupBool(&mdok, header, "PSDESTRK");
     204    if (mdok && isDestreaked) {
     205        return true;
     206    } else {
     207        psError(PS_ERR_IO, false, "output file already exists and may not be de-streaked: %s", sfile->name);
     208        return false;
     209    }
     210}
     211
    161212static psString
    162213resolveFilename(pmConfig *config, sFile *sfile, bool create)
     
    170221            // delete the existing file, since there may be more than one
    171222            // instance. It will get created below in pmConfigConvertFilename
    172             if (nebFind(server, sfile->name)) {
     223            if ((sfile->resolved_name = nebFind(server, sfile->name)) != NULL) {
     224                if (!nebFileIsDestreaked(sfile)) {
     225                    psError(PS_ERR_IO, false, "attempting to delete file that has not been destreaked %s", sfile->name);
     226                    return NULL;
     227                }
     228                nebFree(sfile->resolved_name);
     229                sfile->resolved_name = NULL;
    173230                nebDelete(server, sfile->name);
    174231            }
     
    192249    // all of the keywords in the raw image files written to the output destreaked files
    193250
    194     if (!CHIP_LEVEL_INPUT(stage) && !strcmp(fileSelect, "INPUT")) {
     251    if (!outputFilename && !CHIP_LEVEL_INPUT(stage) && !strcmp(fileSelect, "INPUT")) {
    195252        // stage is warp or diff AND fileSelect eq "INPUT"
    196253        // get data from pmFPAfile.
     
    234291        sfile->header = (psMetadata*) psMemIncrRefCounter(sfile->pmfile->fpa->hdu->header);
    235292
     293        sfile->nHDU = psFitsGetSize(sfile->pmfile->fits);
     294
    236295        return sfile;
    237296    }
     
    249308    }
    250309
    251     // if outputFilename is not null name it contains the "directory"
     310    // if outputFilename is not null name it contains the "directory" (perhaps with a prefix like SR_)
    252311    // and outputFilename is the basename name of the file (or nebulous key)
    253312    // and the file is to be opened for writing
     
    333392
    334393void
     394addDestreakKeyword(psMetadata *header)
     395{
     396    psMetadataAddBool(header, PS_LIST_TAIL, "PSDESTRK", PS_META_REPLACE,
     397        "Have streaks been removed from image?", true);
     398}
     399
     400void
     401addRecoveryKeyword(psMetadata *header)
     402{
     403    psMetadataAddBool(header, PS_LIST_TAIL, "PSRECOVR", PS_META_REPLACE,
     404        "Does this image contain excised streak pixels?", true);
     405}
     406
     407void
    335408copyPHU(streakFiles *sfiles, bool remove)
    336409{
     
    343416        streaksExit("", PS_EXIT_DATA_ERROR);
    344417    }
    345 
    346     // TODO: add keyword indicating that streaks have been removed
     418    psMetadata *recHeader = NULL;
     419    if (remove && sfiles->recImage) {
     420       recHeader = psMetadataCopy(NULL, imageHeader);
     421       addRecoveryKeyword(recHeader);
     422    }
     423
     424    // add keyword indicating that streaks have been removed
     425    addDestreakKeyword(imageHeader);
     426
    347427    if (!psFitsWriteBlank(sfiles->outImage->fits, imageHeader, NULL)) {
    348428        psError(PS_ERR_IO, false, "failed to write primary header to %s",
     
    350430        streaksExit("", PS_EXIT_DATA_ERROR);
    351431    }
    352     // TODO: add keyword indicating that this is the recovery image
    353     if (remove && sfiles->recImage && !psFitsWriteBlank(sfiles->recImage->fits, imageHeader, NULL)) {
     432    if (recHeader && !psFitsWriteBlank(sfiles->recImage->fits, recHeader, NULL)) {
    354433        psError(PS_ERR_IO, false, "failed to write primary header to %s",
    355434            sfiles->recImage->resolved_name);
    356435        streaksExit("", PS_EXIT_DATA_ERROR);
    357436    }
     437    psFree(recHeader);
     438    recHeader = NULL;
    358439    psFree(imageHeader);
    359440
     
    366447            streaksExit("", 1);
    367448        }
    368         // TODO: add keyword indicating that streaks have been removed
     449        if (remove && sfiles->recMask) {
     450            recHeader = psMetadataCopy(NULL, maskHeader);
     451            // add keyword indicating that this is the recovery image
     452           addRecoveryKeyword(recHeader);
     453        }
     454        // add keyword indicating that streaks have been removed
     455        addDestreakKeyword(maskHeader);
    369456        if (!psFitsWriteBlank(sfiles->outMask->fits, maskHeader, NULL)) {
    370457            psError(PS_ERR_IO, false, "failed to write primary header to %s",
     
    372459            streaksExit("", PS_EXIT_DATA_ERROR);
    373460        }
    374         // TODO: add keyword indicating that this is the recovery image
    375         if (remove && sfiles->recMask && !psFitsWriteBlank(sfiles->recMask->fits, maskHeader, NULL)) {
     461        if (recHeader && !psFitsWriteBlank(sfiles->recMask->fits, recHeader, NULL)) {
    376462            psError(PS_ERR_IO, false, "failed to write primary header to %s",
    377463                sfiles->recMask->resolved_name);
    378464            streaksExit("", PS_EXIT_DATA_ERROR);
    379465        }
     466        psFree(recHeader);
     467        recHeader = NULL;
    380468        psFree(maskHeader);
    381469    }
     
    388476            streaksExit("", 1);
    389477        }
    390         // TODO: add keyword indicating that streaks have been removed
     478        if (remove && sfiles->recWeight) {
     479            recHeader = psMetadataCopy(NULL, weightHeader);
     480            // add keyword indicating that this is a recovery image
     481           addRecoveryKeyword(recHeader);
     482        }
     483
     484        // add keyword indicating that streaks have been removed
     485        addDestreakKeyword(weightHeader);
    391486        if (!psFitsWriteBlank(sfiles->outWeight->fits, weightHeader, NULL)) {
    392487            psError(PS_ERR_IO, false, "failed to write primary header to %s",
     
    394489            streaksExit("", PS_EXIT_DATA_ERROR);
    395490        }
    396         // TODO: add keyword indicating that this is a recovery image
    397         if (remove && sfiles->recWeight && !psFitsWriteBlank(sfiles->recWeight->fits, weightHeader, NULL)) {
     491        if (recHeader && !psFitsWriteBlank(sfiles->recWeight->fits, recHeader, NULL)) {
    398492            psError(PS_ERR_IO, false, "failed to write primary header to %s",
    399493                sfiles->recWeight->resolved_name);
     
    401495        }
    402496        psFree(weightHeader);
     497        psFree(recHeader);
    403498    }
    404499}
     
    530625        streaksExit("", PS_EXIT_DATA_ERROR);
    531626    }
    532 
     627 
    533628    bool status;
    534629    in->extname = psMetadataLookupStr(&status, in->header, "EXTNAME");
     
    565660
    566661static void
    567 setFitsOptions(sFile *sfile, int bitpix, float bscale, float bzero)
     662setFitsOptions(sFile *sfile, int bitpix, float bscale, float bzero, psFitsCompressionType compType,
     663    psVector *tiles)
    568664{
    569665    if (!sfile) {
     
    578674    sfile->fits->options->bscale = bscale;
    579675    sfile->fits->options->bzero = bzero;
    580 }
    581 
    582 void
    583 copyFitsOptions(sFile *out, sFile *rec, sFile *in)
    584 {
     676
     677    psFitsSetCompression(sfile->fits, compType, tiles, 8, 0, 0);
     678}
     679
     680void
     681copyFitsOptions(sFile *out, sFile *rec, sFile *in, psVector *tiles)
     682{
     683    bool mdok;
     684    psString compTypeStr = psMetadataLookupStr(&mdok, in->header, "ZCMPTYPE");
     685    psFitsCompressionType compType = psFitsCompressionTypeFromString(compTypeStr);
     686    if (compType == PS_FITS_COMPRESS_NONE) {
     687        return;
     688    }
    585689    // Get current BITPIX, BSCALE, BZERO, EXTNAME
    586690    // Probably not necessary to look the numerical values up in this
     
    609713
    610714#ifdef STREAKS_COMPRESS_OUTPUT
    611     // Paul says that I should be able to leave this blank
    612     bitpix = 0;
    613     setFitsOptions(out, bitpix, bscale, bzero);
    614     setFitsOptions(rec, bitpix, bscale, bzero);
     715    // printf("%d %f %f\n", bitpix, bscale, bzero);
     716    setFitsOptions(out, bitpix, bscale, bzero, compType, tiles);
     717    setFitsOptions(rec, bitpix, bscale, bzero, compType, tiles);
    615718#endif
    616719}
     
    789892
    790893bool
    791 replicate(sFile *sfile, void *xattr)
    792 {
    793     if (!sfile->inNebulous) {
     894replicate(sFile *outFile, sFile *inFile)
     895{
     896    if (!outFile->inNebulous) {
    794897        return true;
    795898    }
    796899    nebServer *server = getNebServer(NULL);
    797900
    798     // for now just set "user.copies" to 2
    799     if (!nebSetXattr(server, sfile->name, "user.copies", "2",  NEB_REPLACE)) {
    800         psError(PM_ERR_UNKNOWN, true, "nebSetXattr failed for %s\n%s", sfile->name, nebErr(server));
     901    char *user_copies = nebGetXattr(server, inFile->name, "user.copies");
     902    bool free_user_copies = true;
     903    if (user_copies == NULL) {
     904        user_copies = "2";
     905        free_user_copies = false;
     906    }
     907    if (!nebSetXattr(server, outFile->name, "user.copies", user_copies,  NEB_REPLACE)) {
     908        psError(PM_ERR_UNKNOWN, true, "nebSetXattr failed for %s\n%s", outFile->name, nebErr(server));
    801909        return false;
    802910    }
    803     if (!nebReplicate(server, sfile->name, NULL, NULL)) {
    804         psError(PM_ERR_UNKNOWN, true, "nebSetXattr failed for %s\n%s", sfile->name, nebErr(server));
     911    if (!nebReplicate(server, outFile->name, "any", NULL)) {
     912        psError(PM_ERR_UNKNOWN, true, "nebReplicate failed for %s\n%s", outFile->name, nebErr(server));
    805913        return false;
     914    }
     915    if (free_user_copies) {
     916        nebFree(user_copies);
    806917    }
    807918    return true;
     
    816927    bool status = false;
    817928
    818     // XXX: TODO: need a nebGetXatrr function, but there isn't one
    819     // another option would be to take the number of copies to be
    820     // created as an option. That way the system could decide
    821     // whether to replicate anything other than raw Image files
    822     void *xattr = NULL;
    823 
    824     if (!replicate(sfiles->outImage, xattr)) {
     929    if (!replicate(sfiles->outImage, sfiles->inImage)) {
    825930        psError(PM_ERR_SYS, false, "failed to replicate outImage.");
    826931        return false;
    827932    }
    828933
    829 #ifdef notyet
    830     // XXX: don't replicate mask and weight images until we can look up
    831     // the input's xattr. There may be a perl program that can getXattr
    832934    if (sfiles->outMask) {
    833         // get xattr from input to see if we need to replicate
    834         if (!replicate(sfiles->outMask, xattr)) {
     935        if (!replicate(sfiles->outMask, sfiles->inMask)) {
    835936            psError(PM_ERR_SYS, false, "failed to replicate outImage.");
    836937            return false;
    837938        }
    838939    }
    839     if (sfiles->outWeight) {
    840         // get xattr from input to see if we need to replicate
    841         if (!replicate(sfiles->outWeight, xattr)) {
     940    if (sfiles->outChMask) {
     941        if (!replicate(sfiles->outChMask, sfiles->inChMask)) {
    842942            psError(PM_ERR_SYS, false, "failed to replicate outImage.");
    843943            return false;
    844944        }
    845945    }
    846 #endif
    847 
    848 //      replicate the recovery images (if in nebulous)
     946    if (sfiles->outWeight) {
     947        if (!replicate(sfiles->outWeight, sfiles->inWeight)) {
     948            psError(PM_ERR_SYS, false, "failed to replicate outImage.");
     949            return false;
     950        }
     951    }
     952
     953    if (sfiles->outSources) {
     954        if (!replicate(sfiles->outSources, sfiles->inSources)) {
     955            psError(PM_ERR_SYS, false, "failed to replicate outSources.");
     956            return false;
     957        }
     958    }
     959
     960//      XXX: replicate the recovery images (if in nebulous)
    849961//      perhaps whether we do that or not should be configurable.
    850962//      Sounds like we need a recipe
     
    9031015    }
    9041016
     1017    if (sfiles->outChMask) {
     1018        if (!swapOutputToInput(sfiles->inChMask, sfiles->outChMask)) {
     1019            psError(PM_ERR_SYS, false, "failed to swap instances for chip mask.");
     1020            return false;
     1021        }
     1022    }
     1023
     1024    if (sfiles->outSources) {
     1025        if (!swapOutputToInput(sfiles->inSources, sfiles->outSources)) {
     1026            psError(PM_ERR_SYS, false, "failed to swap instances for sources.");
     1027            return false;
     1028        }
     1029    }
     1030
    9051031    if (!swapOutputToInput(sfiles->inImage, sfiles->outImage)) {
    9061032        psError(PM_ERR_SYS, false, "failed to swap instances for Image.");
     
    9081034    }
    9091035
     1036
    9101037    return true;
    9111038}
     
    9141041deleteFile(sFile *sfile)
    9151042{
    916 #if 0
    917     // XXX API for nebDelete has changed; need to fix this later
    9181043    if (sfile->inNebulous) {
    9191044        nebServer *server = getNebServer(NULL);
     
    9301055        }
    9311056    }
    932 #endif
    9331057    return true;
    9341058}
     
    9381062{
    9391063    if (sfiles->outMask) {
    940         if (!deleteFile(sfiles->outMask)) {
    941             psError(PM_ERR_SYS, false, "failed to delete Mask.");
    942             return false;
    943         }
     1064        deleteFile(sfiles->outMask);
     1065    }
     1066
     1067    if (sfiles->outChMask) {
     1068        deleteFile(sfiles->outChMask);
    9441069    }
    9451070
    9461071    if (sfiles->outWeight) {
    947         if (!deleteFile(sfiles->outWeight)) {
    948             psError(PM_ERR_SYS, false, "failed to delete Weight.");
    949             return false;
    950         }
    951     }
    952 
    953     if (!deleteFile(sfiles->outImage)) {
    954         psError(PM_ERR_SYS, false, "failed to delete Image.");
    955         return false;
     1072        deleteFile(sfiles->outWeight);
     1073    }
     1074
     1075    if (sfiles->outImage) {
     1076        deleteFile(sfiles->outImage);
     1077    }
     1078
     1079    if (sfiles->outSources) {
     1080        deleteFile(sfiles->outSources);
    9561081    }
    9571082
     
    10181143        }
    10191144        if (printCounts) {
    1020             printf("time to NAN mask pixels: %f\n", psTimerClear("NAN_MASKED"));
     1145            psLogMsg(sfiles->program_name, PS_LOG_INFO, "time to NAN mask pixels: %f\n", psTimerClear("NAN_MASKED"));
    10211146            int totalPixels = image->numRows * image->numCols;
    1022             printf("pixels:        %10ld\n", totalPixels);
    1023             printf("masked pixels: %10ld %4.2f%%\n", maskedPixels, 100. * maskedPixels / totalPixels);
    1024             printf("nand pixels:   %10ld %4.2f%%\n", nandPixels, 100. * nandPixels / totalPixels);
     1147            psLogMsg(sfiles->program_name, PS_LOG_INFO, "pixels:        %10ld\n", totalPixels);
     1148            psLogMsg(sfiles->program_name, PS_LOG_INFO, "masked pixels: %10ld %4.2f%%\n", maskedPixels, 100. * maskedPixels / totalPixels);
     1149            psLogMsg(sfiles->program_name, PS_LOG_INFO, "nand pixels:   %10ld %4.2f%%\n", nandPixels, 100. * nandPixels / totalPixels);
    10251150            if (weight) {
    1026                 printf("nand weights:  %10ld %4.2f%%\n", nandWeights, 100. * nandWeights / totalPixels);
     1151                psLogMsg(sfiles->program_name, PS_LOG_INFO, "nand weights:  %10ld %4.2f%%\n", nandWeights, 100. * nandWeights / totalPixels);
    10271152            }
    10281153        }
     
    10501175strkGetMaskValues(streakFiles *sfiles, psU32 *maskStreak, psU32 *maskMask)
    10511176{
    1052     if (sfiles->inMask->header) {
     1177    if (sfiles->inMask && sfiles->inMask->header) {
    10531178        if (!pmConfigMaskReadHeader(sfiles->config, sfiles->inMask->header)) {
    10541179            streaksExit("failed to read mask values from file", PS_EXIT_CONFIG_ERROR);
     
    10801205    *maskMask = ~convPoor;
    10811206}
     1207
     1208static void
     1209doCopyExtraExtensions(streakFiles *sf, sFile *in, sFile *out)
     1210{
     1211    for (int extnum = sf->extnum; extnum < in->nHDU; extnum++) {
     1212        moveExt(in, extnum);
     1213        readImage(in, extnum, sf->stage, false);
     1214
     1215        if (SFILE_IS_IMAGE(in)) {
     1216            // Turn off compression (code adapted from pmFPAWrite)
     1217#ifdef SAVE_AND_RESTORE_COMPRESSION
     1218            int bitpix = out->fits->options ? out->fits->options->bitpix : 0; // Desired bits per pixel
     1219            psFitsCompression *compress = psFitsCompressionGet(out->fits); // Current compression options
     1220#endif
     1221            if (!psFitsSetCompression(out->fits, PS_FITS_COMPRESS_NONE, NULL, 0, 0, 0)) {
     1222                psError(PM_ERR_UNKNOWN, false, "failed to turn off compression for extension %d\n", extnum);
     1223                streaksExit("", PS_EXIT_UNKNOWN_ERROR);
     1224            }
     1225#ifdef SAVE_AND_RESTORE_COMPRESSION
     1226            if (out->fits->options) {
     1227                out->fits->options->bitpix = 0;
     1228            }
     1229            if (!psFitsWriteImage(out->fits, in->header, in->image, 0, in->extname)) {
     1230                psError(PM_ERR_UNKNOWN, false, "failed to write image for extension %d\n", extnum);
     1231                streaksExit("", PS_EXIT_UNKNOWN_ERROR);
     1232            }
     1233            if (out->fits->options) {
     1234                out->fits->options->bitpix = bitpix;
     1235            }
     1236            if (!psFitsCompressionApply(out->fits, compress)) {
     1237                psError(PM_ERR_UNKNOWN, false, "failed to rest compression image for extension %d\n", extnum);
     1238                streaksExit("", PS_EXIT_UNKNOWN_ERROR);
     1239            }
     1240#endif
     1241        } else {
     1242            copyTable(out, in, extnum);
     1243        }
     1244    }
     1245}
     1246
     1247void
     1248copyExtraExtensions(streakFiles *sf)
     1249{
     1250    // XXX: Bad assumption, the begining of the mask and weight files have the same structure as the image
     1251    // So we are currently at the image portion
     1252    sf->extnum = sf->inImage->nHDU;
     1253
     1254    if (sf->inWeight && sf->outWeight) {
     1255        doCopyExtraExtensions(sf, sf->inWeight, sf->outWeight);
     1256    }
     1257    if (sf->inMask && sf->outMask) {
     1258        doCopyExtraExtensions(sf, sf->inMask, sf->outMask);
     1259    }
     1260    if (sf->inChMask && sf->outChMask) {
     1261        doCopyExtraExtensions(sf, sf->inChMask, sf->outChMask);
     1262    }
     1263}
  • branches/pap/magic/remove/src/streaksio.h

    r23936 r25027  
    22#define STREAKS_IO_H 1
    33
    4 streakFiles *openFiles(pmConfig *config, bool remove);
     4streakFiles *openFiles(pmConfig *config, bool remove, char *program_name);
    55
    66sFile *sFileOpen(pmConfig *config, ippStage stage, psString fileSelect,
     
    1414void copyPHU(streakFiles *sfiles, bool remove);
    1515void copyTable(sFile *out, sFile *in, int extnum);
    16 void copyFitsOptions(sFile *out, sFile *rec, sFile *in);
     16void copyFitsOptions(sFile *out, sFile *rec, sFile *in, psVector *tiles);
    1717void setupImageRefs(sFile *out, sFile *recoveryOut, sFile *in, int extnum, bool exciseAll);
    1818void strkGetMaskValues(streakFiles *sfiles, psU32 *maskStreak, psU32 *maskMask);
     19void copyExtraExtensions(streakFiles *sfiles);
    1920
    2021void writeImage(sFile *sfile, psString extname, int extnum);
    2122void writeImageCube(sFile *sfile, psArray *imagecube, psString extname, int extnum);
    22 bool replicate(sFile *sfile, void *xattr);
     23bool replicate(sFile *outFile, sFile *inFile);
    2324void readImageFrom_pmFile(streakFiles *sf);
     25
     26void addDestreakKeyword(psMetadata *);
     27void addRecoveryKeyword(psMetadata *);
    2428
    2529bool streakFilesNextExtension(streakFiles *sf);
  • branches/pap/magic/remove/src/streaksrelease.c

    r23257 r25027  
    2323    }
    2424
    25     psMetadata *masks = psMetadataLookupMetadata(&status, config->recipes, "MASKS");
    26     if (!status) {
    27         psError(PM_ERR_CONFIG, false, "failed to lookup MASKS in recipes\n");
    28         return PS_EXIT_CONFIG_ERROR;
    29     }
    30     psU8 poorWarp = (double) psMetadataLookupU8(&status, masks, "POOR.WARP");
    31     if (!status) {
    32         psError(PM_ERR_CONFIG, false, "failed to lookup mask value for POOR.WARP in recipes\n");
    33         return PS_EXIT_CONFIG_ERROR;
    34     }
    35     // we're setting pixels with any mask bits execpt POOR.WARP to NAN
    36     psU8 maskMask = ~poorWarp;
     25    // Values to set for masked pixels
     26    psU32 maskStreak = 0;           // for the image and weight (usually NAN, MAXINT for integer images)
     27    psU32 maskMask = 0;             // value looked up for MASK.STREAK
    3728
    3829    // Does true work here?
    39     streakFiles *sfiles = openFiles(config, true);
     30    streakFiles *sfiles = openFiles(config, true, argv[0]);
    4031
    4132    if (sfiles->stage == IPP_STAGE_RAW) {
     
    6455        }
    6556
     57        // now that we've read the input files, lookup the mask values that we read
     58        if (maskStreak == 0) {
     59            strkGetMaskValues(sfiles, &maskStreak, &maskMask);
     60        }
     61
    6662        setMaskedToNAN(sfiles, maskMask, true);
    6763
     
    7167        printf("time to process component %d: %f\n", sfiles->extnum, psTimerClear("PROCESS_COMPONENT"));
    7268    } while (streakFilesNextExtension(sfiles));
     69
     70    // check the weight and mask files for extra extensions that might be in files
     71    // (covariance matrix for example)
     72    copyExtraExtensions(sfiles);
     73
     74
    7375
    7476    psTimerStart("CLOSE_IMAGES");
     
    7779    printf("time to close images: %f\n", psTimerClear("CLOSE_IMAGES"));
    7880
    79 #ifdef NOTYET
    80     if (!replicateOutputs(sfiles)) {
    81         psError(PS_ERR_UNKNOWN, false, "failed to replicate output files");
    82         psErrorStackPrint(stderr, "");
    83         exit(PS_EXIT_UNKNOWN_ERROR);
    84     }
    85 
    86     if (psMetadataLookupBool(&status, config->arguments, "REPLACE")) {
    87         //     swap the instances for the input and output
    88         //     Note this is a database operation. No file I/O is performed
    89         if (!swapOutputsToInputs(sfiles)) {
    90             psError(PS_ERR_UNKNOWN, false, "failed to swap files");
    91 
    92             // XXX: Now what? I guess swapOutputsToInputs will need to undo anything that
    93             // it has done and give a detailed report of what happened
    94 
    95             psErrorStackPrint(stderr, "");
    96             exit(PS_EXIT_UNKNOWN_ERROR);
    97         }
    98 
    99         if (psMetadataLookupBool(&status, config->arguments, "REMOVE")) {
    100             //      delete the temporary storage objects (which now points to the original image(s)
    101             if (!deleteTemps(sfiles)) {
    102                 psError(PS_ERR_UNKNOWN, false, "failed to delete temporary files");
    103                 // XXX: Now what? At this point the output files have been swapped, so we can't
    104                 // repeat the operation.
    105 
    106                 // Returning error status here is problematic. The inputs have been streak removed
    107                 // but they're still lying around
    108                 // Maybe just print an error message and
    109                 // let other system tools clean up
    110                 psErrorStackPrint(stderr, "");
    111                 exit(PS_EXIT_UNKNOWN_ERROR);
    112             }
    113         }
    114     }
    115 #endif  // REPLACE, REMOVE
    11681    printf("time to run streaksrelease: %f\n", psTimerClear("STREAKSREMOVE"));
    11782
     
    275240
    276241    // set up the compression parameters
    277 #ifdef STREAKS_COMPRESS_OUTPUT
    278     // compression of the image pixels is disabled for now. Some consortium members
    279     // have problems reading them
    280     copyFitsOptions(sf->outImage, sf->recImage, sf->inImage);
    281 
    282     // XXX: TODO: can we derive these values from the input header?
    283     // psFitsCompressionGet(sf->inImage->image) gives compression none
    284     // perhaps we should just use the definition of COMP_IMG in the configuration
    285     psFitsSetCompression(sf->outImage->fits, PS_FITS_COMPRESS_RICE, sf->tiles, 8, 0, 0);
    286     if (sf->recImage) {
    287         psFitsSetCompression(sf->recImage->fits, PS_FITS_COMPRESS_RICE, sf->tiles, 8, 0, 0);
    288     }
    289 #endif
     242    copyFitsOptions(sf->outImage, sf->recImage, sf->inImage, sf->tiles);
    290243
    291244    if (sf->inMask) {
     
    306259            }
    307260
    308 #ifdef STREAKS_COMPRESS_OUTPUT
    309             // XXX: see note above
    310             copyFitsOptions(sf->outMask, sf->recMask, sf->inMask);
    311             psFitsSetCompression(sf->outMask->fits, PS_FITS_COMPRESS_PLIO, sf->tiles, 8, 0, 0);
    312             if (sf->recMask) {
    313                 psFitsSetCompression(sf->recMask->fits, PS_FITS_COMPRESS_PLIO, sf->tiles, 8, 0, 0);
    314             }
     261            copyFitsOptions(sf->outMask, sf->recMask, sf->inMask, sf->tiles);
    315262            if (sf->outChMask) {
    316                 copyFitsOptions(sf->outChMask, sf->recChMask, sf->inMask);
    317                 psFitsSetCompression(sf->outChMask->fits, PS_FITS_COMPRESS_PLIO, sf->tiles, 8, 0, 0);
    318                 if (sf->recChMask) {
    319                     psFitsSetCompression(sf->recChMask->fits, PS_FITS_COMPRESS_PLIO, sf->tiles, 8, 0, 0);
    320                 }
    321             }
    322 #endif
     263                copyFitsOptions(sf->outChMask, sf->recChMask, sf->inMask, sf->tiles);
     264            }
    323265        }
    324266    }
     
    332274        setupImageRefs(sf->outWeight, sf->recWeight, sf->inWeight, sf->extnum, exciseAll);
    333275
    334 #ifdef STREAKS_COMPRESS_OUTPUT
    335         copyFitsOptions(sf->outWeight, sf->recWeight, sf->inWeight);
    336         // XXX: see note above
    337         psFitsSetCompression(sf->outWeight->fits, PS_FITS_COMPRESS_RICE, sf->tiles, 8, 0, 0);
    338         if (sf->recWeight) {
    339             psFitsSetCompression(sf->recWeight->fits, PS_FITS_COMPRESS_RICE, sf->tiles, 8, 0, 0);
    340         }
    341 #endif
     276        copyFitsOptions(sf->outWeight, sf->recWeight, sf->inWeight, sf->tiles);
    342277    }
    343278    // and for raw images, create sub images that represent the actual image
  • branches/pap/magic/remove/src/streaksremove.c

    r23936 r25027  
     1/*
     2 * streaksremove
     3 *
     4 * Convert satellite streak detctions into masks and remove the covered pixels from the
     5 * input images.
     6 * Optionally swap the inputs with the outputs so that subsequent references to the original
     7 * images access the destreaked versions.
     8 */
     9
    110#include "streaksremove.h"
    211
     
    413static bool readAndCopyToOutput(streakFiles *sf, bool exciseAll);
    514static void exciseNonWarpedPixels(streakFiles *sfiles, double newMaskValue);
    6 static bool warpedPixel(streakFiles *sfiles, PixelPos *cellCoord);
     15static bool warpedPixel(streakFiles *sfiles, int x, int y);
    716static void excisePixel(streakFiles *sfiles, unsigned int x, unsigned int y, bool streak, double newMaskValue);
    817static void writeImages(streakFiles *sf, bool exciseImageCube);
    918static void updateAstrometry(streakFiles *sfiles);
     19static void censorSources(streakFiles *sfiles, psU32 maskStreak);
    1020
    1121int
     
    2333    }
    2434
    25     psU32 maskStreak = 0;
    26     psU32 maskMask = 0;
     35    // Values to set for masked pixels
     36    psU32 maskStreak = 0;           // for the image and weight (usually NAN, MAXINT for integer images)
     37    psU32 maskMask = 0;             // value looked up for MASK.STREAK
    2738
    2839    psString streaksFileName = psMetadataLookupStr(NULL, config->arguments, "STREAKS");
    2940
     41    // call Paul Sydney's code to parse the streaks file that DetectStreaks produced
    3042    Streaks *streaks = readStreaksFile(streaksFileName);
    3143    if (!streaks) {
    32         psErrorStackPrint(stderr, "failed to read streaks file: %s", streaksFileName);
     44        psError(PS_ERR_UNKNOWN, "failed to read streaks file: %s", streaksFileName);
    3345        streaksExit("", PS_EXIT_PROG_ERROR);
    3446    }
    3547
    36     streakFiles *sfiles = openFiles(config, true);
     48    // open all of the input and output files, save their descriptions in the streakFiles struct
     49    streakFiles *sfiles = openFiles(config, true, argv[0]);
    3750    setupAstrometry(sfiles);
    3851
     52    // Optionally we can set pixels that are masked to NAN since they couldn't have been
     53    // examined for streaks. Usually this is done by the distribution system just prior
     54    // to release
    3955    bool nanForRelease = psMetadataLookupBool(&status, config->arguments, "NAN_FOR_RELEASE");
    4056    if (nanForRelease && (sfiles->inMask == NULL)) {
     
    5268
    5369    if (checkNonWarpedPixels ) {
    54         // From ICD:
     70        // From magic ICD:
    5571        // In the raw and detrended images, the pixels which were not
    5672        // included in any of the streak-processed warps must also be masked.
     
    6581        }
    6682        psF64 cwp_t = psTimerClear("COMPUTE_WARPED_PIXELS");
    67         printf("time to compute warped pixels: %f\n", cwp_t);
     83        psLogMsg("streaksremove", PS_LOG_INFO, "time to compute warped pixels: %f\n", cwp_t);
    6884    }
    6985   
    7086    if (sfiles->stage == IPP_STAGE_RAW) {
    71         // copy PHU to output files
     87        // Except for raw stage, all of our (GPC1) files have one image extension.
     88        // Raw files have a phu and multiple extensions, one per chip
     89        // Since this is a raw file, copy it's PHU to output files
    7290        copyPHU(sfiles, true);
    7391
     
    82100    int totalStreakPixels = 0;
    83101
    84     // Iterate through each component of the input (there is only one except for raw images)
     102    // Iterate through each component of the input (except for raw images there is only one)
    85103    do {
    86104        bool exciseImageCube = false;
     
    110128            psTimerStart("GET_STREAK_PIXELS");
    111129
    112             StreakPixels *pixels = streak_on_component (streaks, sfiles->astrom,
    113                                       sfiles->inImage->numCols, sfiles->inImage->numRows);
    114 
    115             printf("time to get streak pixels: %f\n", psTimerClear("GET_STREAK_PIXELS"));
    116 
     130            // call Paul Sydney's code to compute the set of pixels that are covered by the detected streaks
     131            StreakPixels *pixels = streak_on_component(streaks, sfiles->astrom, sfiles->inImage->numCols,
     132                                                        sfiles->inImage->numRows);
     133            psLogMsg("streaksremove", PS_LOG_INFO, "time to get streak pixels: %f\n", psTimerClear("GET_STREAK_PIXELS"));
    117134           
     135            // if this extension contained an image, excise the streaked pixels.
     136            // otherwise it contained an image cube (video cell) which is handled in the if block
    118137            if (sfiles->inImage->image) {
    119138                if (checkNonWarpedPixels) {
     
    124143                    exciseNonWarpedPixels(sfiles, maskStreak);
    125144
    126                     printf("time to excise non warped pixels: %f\n", psTimerClear("EXCISE_NON_WARPED"));
     145                    psLogMsg("streaksremove", PS_LOG_INFO, "time to excise non warped pixels: %f\n", psTimerClear("EXCISE_NON_WARPED"));
    127146                }
    128                 totalStreakPixels +=  psArrayLength(pixels);
     147
     148
    129149                psTimerStart("REMOVE_STREAKS");
    130                 for (int i = 0; i < psArrayLength (pixels); ++i) {
    131                     PixelPos *pixelPos = psArrayGet (pixels, i);
    132 
    133                     if (!checkNonWarpedPixels || warpedPixel(sfiles, pixelPos)) {
    134 
    135                         excisePixel(sfiles, pixelPos->x, pixelPos->y, true, maskStreak);
    136 
    137                     } else {
    138                         // This pixel was not included in any warp and has thus already excised
    139                         // by exciseNonWarpedPixels
     150
     151                for (int y=0 ; y < sfiles->inImage->numRows; y++) {
     152                    for (int x = 0; x < sfiles->inImage->numCols; x++) {
     153                        if (psImageGet(pixels, x, y)) {
     154                            ++totalStreakPixels;
     155                            if (!checkNonWarpedPixels || warpedPixel(sfiles, x, y)) {
     156
     157                                excisePixel(sfiles, x, y, true, maskStreak);
     158
     159                            } else {
     160                                // This pixel was not included in any warp and has thus already excised
     161                                // by exciseNonWarpedPixels
     162                            }
     163                        }
    140164                    }
    141165                }
    142                 printf("time to remove streak pixels: %f\n", psTimerClear("REMOVE_STREAKS"));
     166
     167                psLogMsg("streaksremove", PS_LOG_INFO, "time to remove streak pixels: %f\n", psTimerClear("REMOVE_STREAKS"));
    143168
    144169                if (nanForRelease) {
     170                    // set any pixels that were masked, to NAN (unless they are already NAN)
    145171                    setMaskedToNAN(sfiles, maskMask, true);
    146172                }
    147173
    148174            } else {
    149                 // this component contains an image cube, excise it completely
     175                // this component contains an image cube
     176                // For now excise it completely
    150177                exciseImageCube = true;
    151178            }
    152             psArrayElementsFree (pixels);
    153179            psFree(pixels);
    154180        }
    155181
    156182        if (sfiles->stage == IPP_STAGE_CHIP) {
     183            // as a convience to the user of the output, replace the bogus WCS transform in the
     184            // chip processed files with the data calcuated by psastro at the camera stage
     185            // (actually we use a linear approximation)
    157186            updateAstrometry(sfiles);
    158187        }
    159188
    160         // write out the destreaked temporary images and the recovery images
     189        censorSources(sfiles, maskStreak);
     190
     191        // write the destreaked "temporary" images and the recovery images
    161192        writeImages(sfiles, exciseImageCube);
    162193
    163         printf("time to process component %d: %f\n", sfiles->extnum, psTimerClear("PROCESS_COMPONENT"));
     194
     195        psLogMsg("streaksremove", PS_LOG_INFO, "time to process component %d: %f\n", sfiles->extnum, psTimerClear("PROCESS_COMPONENT"));
    164196    } while (streakFilesNextExtension(sfiles));
    165197
     198
    166199    psFree(streaks);
    167200
    168     printf("pixels: %ld streak pixels: %ld %4.2f%%\n", totalPixels, totalStreakPixels, 100. * totalStreakPixels / totalPixels);
     201    psLogMsg("streaksremove", PS_LOG_INFO, "pixels: %ld streak pixels: %ld %4.2f%%\n", totalPixels, totalStreakPixels, 100. * totalStreakPixels / totalPixels);
     202
     203    // check the weight and mask files for extra extensions that might be in files
     204    // (covariance matrix for example)
     205    copyExtraExtensions(sfiles);
     206
     207    // all done close the files. This is where the files are written so it can take a long time.
    169208
    170209    psTimerStart("CLOSE_IMAGES");
    171     // close all files
     210
    172211    closeImages(sfiles);
    173     printf("time to close images: %f\n", psTimerClear("CLOSE_IMAGES"));
     212
     213    psLogMsg("streaksremove", PS_LOG_INFO, "time to close images: %f\n", psTimerClear("CLOSE_IMAGES"));
     214
     215
     216    if (!replicateOutputs(sfiles)) {
     217        psError(PS_ERR_UNKNOWN, false, "failed to replicate output files");
     218        deleteTemps(sfiles);
     219        psErrorStackPrint(stderr, "");
     220        exit(PS_EXIT_UNKNOWN_ERROR);
     221    }
    174222
    175223    // NOTE: from here on we can't just quit if something goes wrong.
    176224    // especially if we're working at the raw stage
    177 
    178     if (!replicateOutputs(sfiles)) {
    179         psError(PS_ERR_UNKNOWN, false, "failed to replicate output files");
    180         psErrorStackPrint(stderr, "");
    181         exit(PS_EXIT_UNKNOWN_ERROR);
    182     }
     225    // turn off automatic deletion of output files by streaksExit
     226    setStreakFiles(NULL);
    183227
    184228    if (psMetadataLookupBool(&status, config->arguments, "REPLACE")) {
    185229        //     swap the instances for the input and output
    186         //     Note this is a database operation. No file I/O is performed
     230        //     Note this is a nebulous database operation. No file I/O is performed
    187231        if (!swapOutputsToInputs(sfiles)) {
    188             psError(PS_ERR_UNKNOWN, false, "failed to swap files");
    189 
    190             // XXX: Now what? I guess swapOutputsToInputs will need to undo anything that
    191             // it has done and give a detailed report of what happened
    192 
    193             psErrorStackPrint(stderr, "");
     232            // XXX: Now what?
     233            // It is up to the program that reverts failed destreak runs to insure that
     234            // any input files that have been swapped are restored and that the de-streaked
     235            // versions are deleted
     236
     237            psErrorStackPrint(stderr, "failed to swap files");
     238
     239            // XXX: pick a specific error code for this failure
    194240            exit(PS_EXIT_UNKNOWN_ERROR);
    195241        }
    196 
    197         if (psMetadataLookupBool(&status, config->arguments, "REMOVE")) {
    198             //      delete the temporary storage objects (which now points to the original image(s)
    199             if (!deleteTemps(sfiles)) {
    200                 psError(PS_ERR_UNKNOWN, false, "failed to delete temporary files");
    201                 // XXX: Now what? At this point the output files have been swapped, so we can't
    202                 // repeat the operation.
    203 
    204                 // Returning error status here is problematic. The inputs have been streak removed
    205                 // but they're still lying around
    206                 // Maybe just print an error message and
    207                 // let other system tools clean up
    208                 psErrorStackPrint(stderr, "");
    209                 exit(PS_EXIT_UNKNOWN_ERROR);
    210             }
    211         }
    212     }
     242    }
     243    // all done. Clean up to look for memory leaks.
    213244
    214245    psFree(sfiles);
     
    218249    streaksNebulousCleanup();
    219250    pmConfigDone();
    220     printf("time to run streaksremove: %f\n", psTimerClear("STREAKSREMOVE"));
     251    psLogMsg("streaksremove", PS_LOG_INFO, "time to run streaksremove: %f\n", psTimerClear("STREAKSREMOVE"));
    221252    psLibFinalize();
    222253
     
    235266    fprintf(stderr, "\t-weight WEIGHT.fits: weight file to de-streak\n");
    236267    fprintf(stderr, "\t-replace: replace the input images with the output\n");
    237     fprintf(stderr, "\t-remove: remove the original image after processing (requires -replace)\n");
    238268    fprintf(stderr, "\t-keepnonwarped: do not exise pixels that were not part of difference processing\n");
    239269    fprintf(stderr, "\t-transparent val: instead of setting excicsed pixel to NAN add val\n");
     
    311341    bool gotReplace = false;
    312342    if ((argnum = psArgumentGet(argc, argv, "-replace"))) {
     343        if (!nebulousImage) {
     344            psError(PS_ERR_UNKNOWN, true, "replace is only supported for nebulous files");
     345            usage();
     346        }
    313347        gotReplace = true;
    314348        psArgumentRemove(argnum, &argc, argv);
     
    394428        psArgumentRemove(argnum, &argc, argv);
    395429    }
     430    if ((argnum = psArgumentGet(argc, argv, "-sources"))) {
     431        psArgumentRemove(argnum, &argc, argv);
     432        bool nebulousSources = IN_NEBULOUS(argv[argnum]);
     433        if (nebulousSources != nebulousImage) {
     434            psError(PS_ERR_UNKNOWN, true, "sources file must have %snebulous path with %s image path\n",
     435                nebulousImage ? "" : "non ", nebulousImage ? "nebulous" : "regular");
     436            usage();
     437        }
     438        psMetadataAddStr(config->arguments, PS_LIST_TAIL, "SOURCES", 0,
     439                "name of input sources file", argv[argnum]);
     440        psArgumentRemove(argnum, &argc, argv);
     441    }
    396442
    397443    if ((argnum = psArgumentGet(argc, argv, "-tmproot"))) {
     
    403449            usage();
    404450        }
    405         psString dir = pathToDirectory(argv[argnum]);
    406         psMetadataAddStr(config->arguments, PS_LIST_TAIL, "OUTPUT", 0, "directory for temporary files",
    407             dir);
    408         psFree(dir);
     451        psMetadataAddStr(config->arguments, PS_LIST_TAIL, "OUTPUT", 0, "path for (temporary if replae) output files",
     452            argv[argnum]);
    409453        psArgumentRemove(argnum, &argc, argv);
    410454    } else {
     
    415459    if ((argnum = psArgumentGet(argc, argv, "-recovery"))) {
    416460        psArgumentRemove(argnum, &argc, argv);
    417         psString dir = pathToDirectory(argv[argnum]);
    418         psMetadataAddStr(config->arguments, PS_LIST_TAIL, "RECOVERY", 0, "directory for recovery files",
    419             dir);
    420         psFree(dir);
     461        psMetadataAddStr(config->arguments, PS_LIST_TAIL, "RECOVERY", 0, "path for recovery files",
     462            argv[argnum]);
    421463        psArgumentRemove(argnum, &argc, argv);
    422464    } else if ((stage == IPP_STAGE_RAW) && gotReplace) {
    423465        psError(PS_ERR_UNKNOWN, true, "-recovery is required for -stage raw with -replace\n");
    424466        usage();
    425     }
    426 
    427     if ((argnum = psArgumentGet(argc, argv, "-remove"))) {
    428         if (!gotReplace) {
    429             psError(PS_ERR_UNKNOWN, true, "-replace is required with -remove\n");
    430             usage();
    431         }
    432         psArgumentRemove(argnum, &argc, argv);
    433         psMetadataAddBool(config->arguments, PS_LIST_TAIL, "REMOVE", 0, "remove original files",
    434             true);
    435467    }
    436468
     
    451483updateAstrometry(streakFiles *sf)
    452484{
     485    // XXX: why do I check this here? Shouldn't it be just around the call to linearizeTransforms?
    453486    if (sf->bilevelAstrometry) {
    454487
    455         linearizeTransforms(sf->astrom);
     488        if (!linearizeTransforms(sf->astrom)) {
     489            // fit failed, leave the astrometry unchanged
     490            return;
     491        }
    456492
    457493        if (!pmAstromWriteWCS(sf->outImage->header, sf->inAstrom->fpa, sf->chip, 0.001)) {
     
    501537        }
    502538    }
    503     sf->outImage->header = (psMetadata*) psMemIncrRefCounter(sf->inImage->header);
     539    sf->outImage->header = psMemIncrRefCounter(sf->inImage->header);
    504540    if (sf->recImage) {
    505         sf->recImage->header = (psMetadata*) psMemIncrRefCounter(sf->inImage->header);
    506     }
     541        sf->recImage->header = psMetadataCopy(NULL, sf->inImage->header);
     542        addRecoveryKeyword(sf->recImage->header);
     543    }
     544    addDestreakKeyword(sf->outImage->header);
    507545
    508546    if (!SFILE_IS_IMAGE(sf->inImage)) {
     
    520558
    521559    // set up the compression parameters
    522 #ifdef STREAKS_COMPRESS_OUTPUT
    523     // compression of the image pixels is disabled for now. Some consortium members
    524     // have problems reading them
    525     copyFitsOptions(sf->outImage, sf->recImage, sf->inImage);
    526 
    527     // XXX: TODO: can we derive these values from the input header?
    528     // psFitsCompressionGet(sf->inImage->image) gives compression none
    529     // perhaps we should just use the definition of COMP_IMG in the configuration
    530     psFitsSetCompression(sf->outImage->fits, PS_FITS_COMPRESS_RICE, sf->tiles, 8, 0, 0);
    531     if (sf->recImage) {
    532         psFitsSetCompression(sf->recImage->fits, PS_FITS_COMPRESS_RICE, sf->tiles, 8, 0, 0);
    533     }
    534 #endif
     560    copyFitsOptions(sf->outImage, sf->recImage, sf->inImage, sf->tiles);
    535561
    536562    if (sf->inMask) {
     
    539565            sf->outMask->header = (psMetadata*) psMemIncrRefCounter(sf->inMask->header);
    540566            if (sf->recMask) {
    541                 sf->recMask->header = (psMetadata*) psMemIncrRefCounter(sf->inMask->header);
    542             }
     567                sf->recMask->header = psMetadataCopy(NULL, sf->outMask->header);
     568                addRecoveryKeyword(sf->recMask->header);
     569            }
     570            addDestreakKeyword(sf->outMask->header);
    543571            if (updateAstrometry) {
    544572                pmAstromWriteWCS(sf->outMask->header, sf->inAstrom->fpa, sf->chip, 0.001);
     
    554582            }
    555583
    556 #ifdef STREAKS_COMPRESS_OUTPUT
    557             // XXX: see note above
    558             copyFitsOptions(sf->outMask, sf->recMask, sf->inMask);
    559             psFitsSetCompression(sf->outMask->fits, PS_FITS_COMPRESS_PLIO, sf->tiles, 8, 0, 0);
    560             if (sf->recMask) {
    561                 psFitsSetCompression(sf->recMask->fits, PS_FITS_COMPRESS_PLIO, sf->tiles, 8, 0, 0);
    562             }
     584            copyFitsOptions(sf->outMask, sf->recMask, sf->inMask, sf->tiles);
    563585            if (sf->outChMask) {
    564                 copyFitsOptions(sf->outChMask, sf->recChMask, sf->inMask);
    565                 psFitsSetCompression(sf->outChMask->fits, PS_FITS_COMPRESS_PLIO, sf->tiles, 8, 0, 0);
    566                 if (sf->recChMask) {
    567                     psFitsSetCompression(sf->recChMask->fits, PS_FITS_COMPRESS_PLIO, sf->tiles, 8, 0, 0);
    568                 }
    569             }
    570 #endif
     586                copyFitsOptions(sf->outChMask, sf->recChMask, sf->inMask, sf->tiles);
     587            }
    571588        }
    572589    }
     
    576593        sf->outWeight->header = (psMetadata*) psMemIncrRefCounter(sf->inWeight->header);
    577594        if (sf->recWeight) {
    578             sf->recWeight->header = (psMetadata*) psMemIncrRefCounter(sf->inWeight->header);
    579         }
     595            sf->recWeight->header = psMetadataCopy(NULL, sf->outWeight->header);
     596            addRecoveryKeyword(sf->recWeight->header);
     597        }
     598        addDestreakKeyword(sf->outWeight->header);
    580599        if (updateAstrometry) {
    581600            pmAstromWriteWCS(sf->inWeight->header, sf->inAstrom->fpa, sf->chip, 0.001);
     
    583602        setupImageRefs(sf->outWeight, sf->recWeight, sf->inWeight, sf->extnum, exciseAll);
    584603
    585 #ifdef STREAKS_COMPRESS_OUTPUT
    586         copyFitsOptions(sf->outWeight, sf->recWeight, sf->inWeight);
    587         // XXX: see note above
    588         psFitsSetCompression(sf->outWeight->fits, PS_FITS_COMPRESS_RICE, sf->tiles, 8, 0, 0);
    589         if (sf->recWeight) {
    590             psFitsSetCompression(sf->recWeight->fits, PS_FITS_COMPRESS_RICE, sf->tiles, 8, 0, 0);
    591         }
    592 #endif
    593     }
    594     // and for raw images, create sub images that represent the actual image
    595     // area (no overscan)
     604        copyFitsOptions(sf->outWeight, sf->recWeight, sf->inWeight, sf->tiles);
     605    }
    596606
    597607    return true;
    598608}
    599 
    600 
    601609
    602610static void
     
    746754
    747755static bool
    748 warpedPixel(streakFiles *sfiles, PixelPos *cellCoord)
     756warpedPixel(streakFiles *sfiles, int x, int y)
    749757{
    750758    PixelPos chipCoord;
     
    757765    // we clip so that the streak calculation code doesn't have to
    758766    // clipping here insures that we don't touch the overscan regions
    759     if ((cellCoord->x < 0) || (cellCoord->x >= sfiles->inImage->numCols) ||
    760         (cellCoord->y < 0) || (cellCoord->y >= sfiles->inImage->numRows)) {
     767    if ((x < 0) || (x >= sfiles->inImage->numCols) ||
     768        (y < 0) || (y >= sfiles->inImage->numRows)) {
    761769        return false;
    762770    }
    763771
    764     cellToChipInt(&chipCoord.x, &chipCoord.y, sfiles->astrom, cellCoord->x, cellCoord->y);
     772    cellToChipInt(&chipCoord.x, &chipCoord.y, sfiles->astrom, x, y);
    765773
    766774    if (chipCoord.x < 0 || chipCoord.x >= sfiles->warpedPixels->numCols) {
     
    774782}
    775783
     784// read a sources file (.cmf) and remove any rows whose coordinate is convered by a
     785// streak mask
     786static void
     787censorSources(streakFiles *sfiles, psU32 maskStreak)
     788{
     789    if ((!sfiles->inSources) || (!sfiles->outMask)) {
     790        return;
     791    }
     792    psImage *maskImage = sfiles->outMask->image;
     793    if (!maskImage) {
     794        psError(PS_ERR_IO, false, "maskImage is null!");
     795        streaksExit("", PS_EXIT_PROG_ERROR);
     796    }
     797
     798    sFile *in = sfiles->inSources;
     799    sFile *out = sfiles->outSources;
     800
     801    in->header = psFitsReadHeader(NULL, in->fits);
     802    if (!in->header) {
     803        psError(PS_ERR_IO, false, "failed to read header from %s", in->resolved_name);
     804        streaksExit("", PS_EXIT_DATA_ERROR);
     805    }
     806
     807    bool status;
     808    psString extname = psMetadataLookupStr(&status, in->header, "EXTNAME");
     809    if (!extname) {
     810        psError(PS_ERR_IO, false, "failed to find extname in header of %s", in->resolved_name);
     811        streaksExit("", PS_EXIT_DATA_ERROR);
     812    }
     813
     814    psArray *inTable = psFitsReadTable(in->fits);
     815    if (!inTable->n) {
     816        psError(PS_ERR_IO, false, "table in %s is empty", in->resolved_name);
     817        streaksExit("", PS_EXIT_DATA_ERROR);
     818    }
     819
     820    psArray *outTable = psArrayAllocEmpty(inTable->n);
     821    int j = 0;
     822    int numCensored = 0;
     823    for (int i = 0 ; i < inTable->n; i++) {
     824        psMetadata *row = inTable->data[i];
     825
     826        psF32 x = psMetadataLookupF32 (&status, row, "X_PSF");
     827        psF32 y = psMetadataLookupF32 (&status, row, "Y_PSF");
     828       
     829        psU32 mask = psImageGet(maskImage, x, y);
     830
     831        // Key the source if the center pixel is not masked with maskStreak
     832        if (! (mask & maskStreak) ) {
     833            psArraySet(outTable, j++, row);
     834        } else {
     835            numCensored++;
     836        }
     837    }
     838
     839    // get rid of unused elements (don't know if this is necessary)
     840    psArrayRealloc(outTable, j);
     841
     842    addDestreakKeyword(in->header);
     843    if (psArrayLength(outTable) > 0) {
     844        printf("Censored %d sources\n", numCensored);
     845        if (! psFitsWriteTable(out->fits, in->header, outTable, extname)) {
     846            psError(PS_ERR_IO, false, "failed to write table to %s", out->resolved_name);
     847            streaksExit("", PS_EXIT_DATA_ERROR);
     848        }
     849    } else {
     850        printf("Censored ALL %d sources\n", numCensored);
     851        if (! psFitsWriteTableEmpty(out->fits, in->header, inTable->data[0], extname)) {
     852            psError(PS_ERR_IO, false, "failed to write empty table to %s", out->resolved_name);
     853            streaksExit("", PS_EXIT_DATA_ERROR);
     854        }
     855    }
     856
     857    if (!psFitsClose(out->fits)) {
     858        psError(PS_ERR_IO, false, "failed to close table %s", out->resolved_name);
     859        streaksExit("", PS_EXIT_DATA_ERROR);
     860    }
     861}
  • branches/pap/magic/remove/src/streaksremove.h

    r21156 r25027  
    6262    sFile *outChMask;
    6363    sFile *recChMask;
     64    sFile *inSources;
     65    sFile *outSources;
    6466    psString class_id;
    6567    pmFPAfile  *inAstrom;
     
    7274    psVector    *tiles;
    7375    double  transparentStreaks;
     76    psString    program_name;
    7477} streakFiles;
    7578
     
    8790extern ippStage parseStage(psString);
    8891extern psString pathToDirectory(char *path);
     92extern void setStreakFiles( streakFiles *);
    8993
    9094#define CHIP_LEVEL_INPUT(_stage) ((_stage == IPP_STAGE_RAW) || (_stage == IPP_STAGE_CHIP))
     
    9498#define IN_NEBULOUS(_filename) (!strncasecmp(_filename, "neb://", strlen("neb://")))
    9599
     100
    96101#endif // STREAKS_H
  • branches/pap/magic/remove/src/streaksreplace.c

    r23258 r25027  
    3333    }
    3434
    35     streakFiles *sfiles = openFiles(config, false);
     35    streakFiles *sfiles = openFiles(config, false, argv[0]);
    3636
    3737    if (sfiles->stage == IPP_STAGE_RAW) {
     
    9797    }
    9898
    99 #ifdef NOTYET
    100     if (psMetadataLookupBool(&status, config->arguments, "REPLACE")) {
    101         //     swap the instances for the input and output
    102         //     Note this is a database operation. No file I/O is performed
    103         if (!swapOutputsToInputs(sfiles)) {
    104             psError(PS_ERR_UNKNOWN, false, "failed to swap files");
    105 
    106             // XXX: Now what? I guess swapOutputsToInputs will need to undo anything that
    107             // it has done and give a detailed report of what happened
    108 
    109             psErrorStackPrint(stderr, "");
    110             exit(PS_EXIT_UNKNOWN_ERROR);
    111         }
    112 
    113         if (psMetadataLookupBool(&status, config->arguments, "REMOVE")) {
    114             //      delete the temporary storage objects (which now points to the original image(s)
    115             if (!deleteTemps(sfiles)) {
    116                 psError(PS_ERR_UNKNOWN, false, "failed to delete temporary files");
    117                 // XXX: Now what? At this point the output files have been swapped, so we can't
    118                 // repeat the operation.
    119 
    120                 // Returning error status here is problematic. The inputs have been streak removed
    121                 // but they're still lying around
    122                 // Maybe just print an error message and
    123                 // let other system tools clean up
    124                 psErrorStackPrint(stderr, "");
    125                 exit(PS_EXIT_UNKNOWN_ERROR);
    126             }
    127         }
    128     }
    129 #endif  // REPLACE, REMOVE
    13099//    nebServerFree(ourNebServer);
    131100    psFree(config);
     
    344313
    345314    // set up the compression parameters
    346 #ifdef STREAKS_COMPRESS_OUTPUT
    347     // compression of the image pixels is disabled for now. Some consortium members
    348     // have problems reading compressed images.
    349     copyFitsOptions(sf->outImage, sf->recImage, sf->inImage);
    350 
    351     // XXX: TODO: can we derive these values from the input header?
    352     // psFitsCompressionGet(sf->inImage->image) gives compression none
    353     // perhaps we should just use the definition of COMP_IMG in the configuration
    354     psFitsSetCompression(sf->outImage->fits, PS_FITS_COMPRESS_RICE, sf->tiles, 8, 0, 0);
    355 #endif
     315    copyFitsOptions(sf->outImage, sf->recImage, sf->inImage, sf->tiles);
     316
    356317    if (sf->inMask) {
    357318        readImage(sf->inMask, sf->extnum, sf->stage, true);
     
    362323        setupImageRefs(sf->outMask, NULL, sf->inMask, sf->extnum, false);
    363324
    364         // XXX: see note above
    365         copyFitsOptions(sf->outMask, NULL, sf->inMask);
    366         psFitsSetCompression(sf->outMask->fits, PS_FITS_COMPRESS_PLIO, sf->tiles, 8, 0, 0);
     325        copyFitsOptions(sf->outMask, NULL, sf->inMask, sf->tiles);
    367326    }
    368327
     
    374333        setupImageRefs(sf->outMask, NULL, sf->inMask, sf->extnum, false);
    375334
    376         copyFitsOptions(sf->outWeight, NULL, sf->inWeight);
    377         // XXX: see note above
    378         psFitsSetCompression(sf->outWeight->fits, PS_FITS_COMPRESS_RICE, sf->tiles, 8, 0, 0);
     335        copyFitsOptions(sf->outWeight, NULL, sf->inWeight, sf->tiles);
    379336    }
    380337
  • branches/pap/magic/remove/src/streaksutil.c

    r20816 r25027  
    3333}
    3434
     35streakFiles *ourStreakFiles = NULL;
     36
     37void
     38setStreakFiles(streakFiles *sfiles)
     39{
     40    ourStreakFiles = sfiles;
     41}
     42
    3543// to enhance clarity in these programs we don't propagate errors up the stack
    3644// we just bail out
    3745void streaksExit(psString str, int exitCode) {
    3846    psErrorStackPrint(stderr, str);
     47    if (ourStreakFiles) {
     48        deleteTemps(ourStreakFiles);
     49    }
    3950    exit(exitCode);
    4051}
Note: See TracChangeset for help on using the changeset viewer.