IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 18601


Ignore:
Timestamp:
Jul 17, 2008, 12:38:15 PM (18 years ago)
Author:
Paul Price
Message:

The FPA format in psastroDataSave was bad: the GPC1 inputs (which is used for the output) had HDUs in the chips, but the output format is supposed to have an HDU in the FPA. It comes down to a pmFPAfileSuitableFPA not being called at the right place. To fix this, I've sprinkled calls to pmFPAfileSuitableFPA in all the FITS writing functions. This provides the HDU in the right place to these functions. pmFPAfileSuitableFPA should now automatically take care of header conformity, updating concepts, etc. Now, if adding a function to write FITS data, you should make sure that you call pmFPAfileSuitableFPA to get the right format, HDU, header keywords, etc.

Location:
trunk/psModules/src
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/astrom/pmAstrometryModel.c

    r18008 r18601  
    22 *
    33 *  @brief Functions to read and write astrometric model
    4  * 
     4 *
    55 *  The generic model does not specify the location of the boresite on the sky, and it includes
    66 *  a model for the rotator and motion of the boresite.
     
    99 *
    1010 *  @author EAM, IfA
    11  *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
    12  *  @date $Date: 2008-06-09 01:53:31 $
     11 *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
     12 *  @date $Date: 2008-07-17 22:38:15 $
    1313 *
    1414 *  Copyright 2007 Institute for Astronomy, University of Hawaii
     
    3838#include "pmFPAfile.h"
    3939#include "pmFPAExtent.h"
     40#include "pmFPAfileFitsIO.h"
    4041#include "pmAstrometryWCS.h"
    4142#include "pmAstrometryUtils.h"
     
    9697/********************* Write Data functions *****************************/
    9798
    98 bool pmAstromModelWriteForView (const pmFPAview *view, pmFPAfile *file, const pmConfig *config) {
    99 
     99bool pmAstromModelWriteForView (const pmFPAview *view, pmFPAfile *file, pmConfig *config)
     100{
    100101    // write the full model in one pass: require the level to be FPA
    101102    if (view->chip != -1) {
    102         psError(PS_ERR_IO, false, "Astrometry must be written at the FPA level");
    103         return false;
    104     }
    105 
    106     if (!pmAstromModelWriteFPA (file)) {
    107         psError(PS_ERR_IO, false, "Failed to write Astrometry for fpa");
    108         return false;
    109     }
     103        psError(PS_ERR_IO, false, "Astrometry must be written at the FPA level");
     104        return false;
     105    }
     106
     107    pmFPA *fpa = pmFPAfileSuitableFPA(file, view, config, false); // Suitable FPA for writing
     108
     109    if (!pmAstromModelWriteFPA(file, fpa)) {
     110        psError(PS_ERR_IO, false, "Failed to write Astrometry for fpa");
     111        psFree(fpa);
     112        return false;
     113    }
     114
     115    psFree(fpa);
     116
    110117    return true;
    111118}
    112119
    113120// write out all chip-level Astrometry data for this FPA
    114 bool pmAstromModelWriteFPA (pmFPAfile *file) {
    115 
    116     if (!pmAstromModelWritePHU (file)) {
    117         psError(PS_ERR_IO, false, "Failed to write PHU for Astrometry model");
    118         return false;
     121bool pmAstromModelWriteFPA (pmFPAfile *file, const pmFPA *fpa)
     122{
     123
     124
     125    if (!pmAstromModelWritePHU (file, fpa)) {
     126        psError(PS_ERR_IO, false, "Failed to write PHU for Astrometry model");
     127        return false;
    119128    }
    120129
    121130    if (!pmAstromModelWriteChips (file)) {
    122         psError(PS_ERR_IO, false, "Failed to write Astrometry for chips");
    123         return false;
     131        psError(PS_ERR_IO, false, "Failed to write Astrometry for chips");
     132        return false;
    124133    }
    125134
    126135    if (!pmAstromModelWriteFP (file)) {
    127         psError(PS_ERR_IO, false, "Failed to write Sky for Astrometry model");
    128         return false;
     136        psError(PS_ERR_IO, false, "Failed to write Sky for Astrometry model");
     137        return false;
    129138    }
    130139
    131140    if (!pmAstromModelWriteTP (file)) {
    132         psError(PS_ERR_IO, false, "Failed to write Sky for Astrometry model");
    133         return false;
     141        psError(PS_ERR_IO, false, "Failed to write Sky for Astrometry model");
     142        return false;
    134143    }
    135144
    136145    if (!pmAstromModelWriteSky (file)) {
    137         psError(PS_ERR_IO, false, "Failed to write Sky for Astrometry model");
    138         return false;
    139     }
    140 
    141     return true;
    142 }
    143 
    144 bool pmAstromModelWritePHU (pmFPAfile *file) {
    145 
    146     // output header data
     146        psError(PS_ERR_IO, false, "Failed to write Sky for Astrometry model");
     147        return false;
     148    }
     149
     150    return true;
     151}
     152
     153bool pmAstromModelWritePHU (pmFPAfile *file, const pmFPA *fpa) {
     154    // Need to have an FPA suitable for writing, so that the headers are all kosher
     155
     156    // output header data
    147157    psMetadata *outhead = psMetadataAlloc();
    148158
    149159    // use the FPA phu to generate the PHU header
    150     pmHDU *phu = file->fpa->hdu;
     160    pmHDU *phu = fpa->hdu;
    151161
    152162    // if there is no FPA PHU, this is a single header+image (extension-less) file. This could be
     
    154164    // write it out as a 'blank'
    155165    if (phu) {
    156         psMetadataCopy (outhead, phu->header);
     166        psMetadataCopy (outhead, phu->header);
    157167    } else {
    158         pmConfigConformHeader (outhead, file->format);
    159 
    160 # if (0)
    161         // XXX this is no longer needed : FPA.OBS is now correctly copied in pmConfigConformHeader
    162         // XXX probably need other info to conform the header
    163         psMetadata *fileData = psMetadataLookupMetadata(NULL, file->format, "FILE"); // File information
    164         const char *fpaNameHdr = psMetadataLookupStr(NULL, fileData, "FPA.NAME");
    165         if (fpaNameHdr && strlen(fpaNameHdr) > 0) {
    166             const char *fpaName = psMetadataLookupStr(NULL, file->fpa->concepts, "FPA.NAME");
    167             psMetadataAddStr(outhead, PS_LIST_TAIL, fpaNameHdr, PS_META_REPLACE, "FPA name", fpaName);
    168         }
    169 # endif
     168        pmConfigConformHeader (outhead, file->format);
    170169    }
    171170
     
    184183
    185184    psMetadata *header = psMetadataAlloc();
    186     psMetadataAddStr(header, PS_LIST_TAIL, "COORD",    PS_META_REPLACE, "name of this layer",   "CHIPS");
    187     psMetadataAddStr(header, PS_LIST_TAIL, "PARENT",   PS_META_REPLACE, "next layer up",        "FOCAL_PLANE");
    188     psMetadataAddStr(header, PS_LIST_TAIL, "BOUNDARY", PS_META_REPLACE, "validity region",      "RECTANGLE");
    189     psMetadataAddStr(header, PS_LIST_TAIL, "TRANSFRM", PS_META_REPLACE, "mapping to parent",    "POLYNOMIAL");
     185    psMetadataAddStr(header, PS_LIST_TAIL, "COORD",    PS_META_REPLACE, "name of this layer",   "CHIPS");
     186    psMetadataAddStr(header, PS_LIST_TAIL, "PARENT",   PS_META_REPLACE, "next layer up",        "FOCAL_PLANE");
     187    psMetadataAddStr(header, PS_LIST_TAIL, "BOUNDARY", PS_META_REPLACE, "validity region",      "RECTANGLE");
     188    psMetadataAddStr(header, PS_LIST_TAIL, "TRANSFRM", PS_META_REPLACE, "mapping to parent",    "POLYNOMIAL");
    190189
    191190    psArray *model = psArrayAllocEmpty (1);
     
    196195    while ((chip = pmFPAviewNextChip (view, file->fpa, 1)) != NULL) {
    197196
    198         if (!chip->toFPA) continue;
    199         assert (chip->toFPA->x);
    200         assert (chip->toFPA->y);
    201      
    202         psRegion *region = pmChipPixels (chip);
    203 
    204         // set the chip name
    205         char *chiprule = psStringCopy ("{CHIP.NAME}");
     197        if (!chip->toFPA) continue;
     198        assert (chip->toFPA->x);
     199        assert (chip->toFPA->y);
     200
     201        psRegion *region = pmChipPixels (chip);
     202
     203        // set the chip name
     204        char *chiprule = psStringCopy ("{CHIP.NAME}");
    206205        char *chipname = pmFPAfileNameFromRule (chiprule, file, view);
    207206
    208         for (int i = 0; i <= chip->toFPA->x->nX; i++) {
    209             for (int j = 0; j <= chip->toFPA->x->nY; j++) {
    210                 psMetadata *row = psMetadataAlloc ();
    211                
    212                 psMetadataAddStr(row,    PS_LIST_TAIL, "SEGMENT",  PS_META_REPLACE, "name of this segment", chipname);
    213                 psMetadataAddStr(row,    PS_LIST_TAIL, "PARENT",   PS_META_REPLACE, "next layer up",        "FOCAL_PLANE");
    214                 psMetadataAddF32(row,    PS_LIST_TAIL, "MINX",     PS_META_REPLACE, "range", region->x0);
    215                 psMetadataAddF32(row,    PS_LIST_TAIL, "MAXX",     PS_META_REPLACE, "range", region->x1);
    216                 psMetadataAddF32(row,    PS_LIST_TAIL, "MINY",     PS_META_REPLACE, "range", region->y0);
    217                 psMetadataAddF32(row,    PS_LIST_TAIL, "MAXY",     PS_META_REPLACE, "range", region->y1);
    218    
    219                 psMetadataAddS32(row,    PS_LIST_TAIL, "XORDER",   PS_META_REPLACE, "", i);
    220                 psMetadataAddS32(row,    PS_LIST_TAIL, "YORDER",   PS_META_REPLACE, "", j);
    221                 psMetadataAddS32(row,    PS_LIST_TAIL, "NXORDER",  PS_META_REPLACE, "", chip->toFPA->x->nX);
    222                 psMetadataAddS32(row,    PS_LIST_TAIL, "NYORDER",  PS_META_REPLACE, "", chip->toFPA->x->nY);
    223                 psMetadataAddF32(row,    PS_LIST_TAIL, "POLY_X",   PS_META_REPLACE, "", chip->toFPA->x->coeff[i][j]);
    224                 psMetadataAddF32(row,    PS_LIST_TAIL, "POLY_Y",   PS_META_REPLACE, "", chip->toFPA->y->coeff[i][j]);
    225                 psMetadataAddF32(row,    PS_LIST_TAIL, "ERROR_X",  PS_META_REPLACE, "", chip->toFPA->x->coeffErr[i][j]);
    226                 psMetadataAddF32(row,    PS_LIST_TAIL, "ERROR_Y",  PS_META_REPLACE, "", chip->toFPA->y->coeffErr[i][j]);
    227                 psMetadataAddU8 (row,    PS_LIST_TAIL, "MASK_X",   PS_META_REPLACE, "", chip->toFPA->x->coeffMask[i][j]);
    228                 psMetadataAddU8 (row,    PS_LIST_TAIL, "MASK_Y",   PS_META_REPLACE, "", chip->toFPA->y->coeffMask[i][j]);
    229                 psArrayAdd (model, 100, row);
    230                 psFree (row);
    231             }
    232         }
    233         psFree (chiprule);
    234         psFree (chipname);
    235         psFree (region);
     207        for (int i = 0; i <= chip->toFPA->x->nX; i++) {
     208            for (int j = 0; j <= chip->toFPA->x->nY; j++) {
     209                psMetadata *row = psMetadataAlloc ();
     210
     211                psMetadataAddStr(row,    PS_LIST_TAIL, "SEGMENT",  PS_META_REPLACE, "name of this segment", chipname);
     212                psMetadataAddStr(row,    PS_LIST_TAIL, "PARENT",   PS_META_REPLACE, "next layer up",        "FOCAL_PLANE");
     213                psMetadataAddF32(row,    PS_LIST_TAIL, "MINX",     PS_META_REPLACE, "range", region->x0);
     214                psMetadataAddF32(row,    PS_LIST_TAIL, "MAXX",     PS_META_REPLACE, "range", region->x1);
     215                psMetadataAddF32(row,    PS_LIST_TAIL, "MINY",     PS_META_REPLACE, "range", region->y0);
     216                psMetadataAddF32(row,    PS_LIST_TAIL, "MAXY",     PS_META_REPLACE, "range", region->y1);
     217
     218                psMetadataAddS32(row,    PS_LIST_TAIL, "XORDER",   PS_META_REPLACE, "", i);
     219                psMetadataAddS32(row,    PS_LIST_TAIL, "YORDER",   PS_META_REPLACE, "", j);
     220                psMetadataAddS32(row,    PS_LIST_TAIL, "NXORDER",  PS_META_REPLACE, "", chip->toFPA->x->nX);
     221                psMetadataAddS32(row,    PS_LIST_TAIL, "NYORDER",  PS_META_REPLACE, "", chip->toFPA->x->nY);
     222                psMetadataAddF32(row,    PS_LIST_TAIL, "POLY_X",   PS_META_REPLACE, "", chip->toFPA->x->coeff[i][j]);
     223                psMetadataAddF32(row,    PS_LIST_TAIL, "POLY_Y",   PS_META_REPLACE, "", chip->toFPA->y->coeff[i][j]);
     224                psMetadataAddF32(row,    PS_LIST_TAIL, "ERROR_X",  PS_META_REPLACE, "", chip->toFPA->x->coeffErr[i][j]);
     225                psMetadataAddF32(row,    PS_LIST_TAIL, "ERROR_Y",  PS_META_REPLACE, "", chip->toFPA->y->coeffErr[i][j]);
     226                psMetadataAddU8 (row,    PS_LIST_TAIL, "MASK_X",   PS_META_REPLACE, "", chip->toFPA->x->coeffMask[i][j]);
     227                psMetadataAddU8 (row,    PS_LIST_TAIL, "MASK_Y",   PS_META_REPLACE, "", chip->toFPA->y->coeffMask[i][j]);
     228                psArrayAdd (model, 100, row);
     229                psFree (row);
     230            }
     231        }
     232        psFree (chiprule);
     233        psFree (chipname);
     234        psFree (region);
    236235    }
    237236
     
    254253
    255254    psMetadata *header = psMetadataAlloc();
    256     psMetadataAddStr(header, PS_LIST_TAIL, "COORD",    PS_META_REPLACE, "name of this layer",   "FOCAL_PLANE");
    257     psMetadataAddStr(header, PS_LIST_TAIL, "PARENT",   PS_META_REPLACE, "next layer up",        "TANGENT_PLANE");
    258     psMetadataAddStr(header, PS_LIST_TAIL, "BOUNDARY", PS_META_REPLACE, "validity region",      "RECTANGLE");
    259     psMetadataAddStr(header, PS_LIST_TAIL, "TRANSFRM", PS_META_REPLACE, "mapping to parent",    "POLYNOMIAL");
     255    psMetadataAddStr(header, PS_LIST_TAIL, "COORD",    PS_META_REPLACE, "name of this layer",   "FOCAL_PLANE");
     256    psMetadataAddStr(header, PS_LIST_TAIL, "PARENT",   PS_META_REPLACE, "next layer up",        "TANGENT_PLANE");
     257    psMetadataAddStr(header, PS_LIST_TAIL, "BOUNDARY", PS_META_REPLACE, "validity region",      "RECTANGLE");
     258    psMetadataAddStr(header, PS_LIST_TAIL, "TRANSFRM", PS_META_REPLACE, "mapping to parent",    "POLYNOMIAL");
    260259
    261260    psArray *model = psArrayAllocEmpty (1);
     
    265264
    266265    // rotate the toTPA to have 0.0 posangle
    267     float posangle = psMetadataLookupF32 (&status, file->fpa->concepts, "FPA.POSANGLE"); 
     266    float posangle = psMetadataLookupF32 (&status, file->fpa->concepts, "FPA.POSANGLE");
    268267
    269268    // the to/from TPA transform currently has rotation of posangle; remove it & create the toTPA version
     
    272271
    273272    for (int i = 0; i <= toTPA->x->nX; i++) {
    274         for (int j = 0; j <= toTPA->x->nY; j++) {
    275             psMetadata *row = psMetadataAlloc ();
    276             psMetadataAddStr(row,    PS_LIST_TAIL, "SEGMENT",  PS_META_REPLACE, "name of this segment", "FOCAL_PLANE");
    277             psMetadataAddStr(row,    PS_LIST_TAIL, "PARENT",   PS_META_REPLACE, "next layer up",        "TANGENT_PLANE");
    278             psMetadataAddF32(row,    PS_LIST_TAIL, "MINX",     PS_META_REPLACE, "range", region->x0);
    279             psMetadataAddF32(row,    PS_LIST_TAIL, "MAXX",     PS_META_REPLACE, "range", region->x1);
    280             psMetadataAddF32(row,    PS_LIST_TAIL, "MINY",     PS_META_REPLACE, "range", region->y0);
    281             psMetadataAddF32(row,    PS_LIST_TAIL, "MAXY",     PS_META_REPLACE, "range", region->y1);
    282    
    283             psMetadataAddS32(row,    PS_LIST_TAIL, "XORDER",   PS_META_REPLACE, "", i);
    284             psMetadataAddS32(row,    PS_LIST_TAIL, "YORDER",   PS_META_REPLACE, "", j);
    285             psMetadataAddS32(row,    PS_LIST_TAIL, "NXORDER",  PS_META_REPLACE, "", toTPA->x->nX);
    286             psMetadataAddS32(row,    PS_LIST_TAIL, "NYORDER",  PS_META_REPLACE, "", toTPA->x->nY);
    287             psMetadataAddF32(row,    PS_LIST_TAIL, "POLY_X",   PS_META_REPLACE, "", toTPA->x->coeff[i][j]);
    288             psMetadataAddF32(row,    PS_LIST_TAIL, "POLY_Y",   PS_META_REPLACE, "", toTPA->y->coeff[i][j]);
    289             psMetadataAddF32(row,    PS_LIST_TAIL, "ERROR_X",  PS_META_REPLACE, "", toTPA->x->coeffErr[i][j]);
    290             psMetadataAddF32(row,    PS_LIST_TAIL, "ERROR_Y",  PS_META_REPLACE, "", toTPA->y->coeffErr[i][j]);
    291             psMetadataAddU8 (row,    PS_LIST_TAIL, "MASK_X",   PS_META_REPLACE, "", toTPA->x->coeffMask[i][j]);
    292             psMetadataAddU8 (row,    PS_LIST_TAIL, "MASK_Y",   PS_META_REPLACE, "", toTPA->y->coeffMask[i][j]);
    293 
    294             psArrayAdd (model, 100, row);
    295             psFree (row);
    296         }
     273        for (int j = 0; j <= toTPA->x->nY; j++) {
     274            psMetadata *row = psMetadataAlloc ();
     275            psMetadataAddStr(row,    PS_LIST_TAIL, "SEGMENT",  PS_META_REPLACE, "name of this segment", "FOCAL_PLANE");
     276            psMetadataAddStr(row,    PS_LIST_TAIL, "PARENT",   PS_META_REPLACE, "next layer up",        "TANGENT_PLANE");
     277            psMetadataAddF32(row,    PS_LIST_TAIL, "MINX",     PS_META_REPLACE, "range", region->x0);
     278            psMetadataAddF32(row,    PS_LIST_TAIL, "MAXX",     PS_META_REPLACE, "range", region->x1);
     279            psMetadataAddF32(row,    PS_LIST_TAIL, "MINY",     PS_META_REPLACE, "range", region->y0);
     280            psMetadataAddF32(row,    PS_LIST_TAIL, "MAXY",     PS_META_REPLACE, "range", region->y1);
     281
     282            psMetadataAddS32(row,    PS_LIST_TAIL, "XORDER",   PS_META_REPLACE, "", i);
     283            psMetadataAddS32(row,    PS_LIST_TAIL, "YORDER",   PS_META_REPLACE, "", j);
     284            psMetadataAddS32(row,    PS_LIST_TAIL, "NXORDER",  PS_META_REPLACE, "", toTPA->x->nX);
     285            psMetadataAddS32(row,    PS_LIST_TAIL, "NYORDER",  PS_META_REPLACE, "", toTPA->x->nY);
     286            psMetadataAddF32(row,    PS_LIST_TAIL, "POLY_X",   PS_META_REPLACE, "", toTPA->x->coeff[i][j]);
     287            psMetadataAddF32(row,    PS_LIST_TAIL, "POLY_Y",   PS_META_REPLACE, "", toTPA->y->coeff[i][j]);
     288            psMetadataAddF32(row,    PS_LIST_TAIL, "ERROR_X",  PS_META_REPLACE, "", toTPA->x->coeffErr[i][j]);
     289            psMetadataAddF32(row,    PS_LIST_TAIL, "ERROR_Y",  PS_META_REPLACE, "", toTPA->y->coeffErr[i][j]);
     290            psMetadataAddU8 (row,    PS_LIST_TAIL, "MASK_X",   PS_META_REPLACE, "", toTPA->x->coeffMask[i][j]);
     291            psMetadataAddU8 (row,    PS_LIST_TAIL, "MASK_Y",   PS_META_REPLACE, "", toTPA->y->coeffMask[i][j]);
     292
     293            psArrayAdd (model, 100, row);
     294            psFree (row);
     295        }
    297296    }
    298297
     
    300299        psError(PS_ERR_IO, false, "writing sky data\n");
    301300        psFree(model);
    302         psFree (header);
    303         psFree (region);
     301        psFree (header);
     302        psFree (region);
    304303        return false;
    305304    }
     
    317316
    318317    // get the boresite model parameters
    319     float Xo = psMetadataLookupF32 (&status, file->fpa->concepts, "FPA.BORE.X0"); 
    320     float Yo = psMetadataLookupF32 (&status, file->fpa->concepts, "FPA.BORE.Y0"); 
    321     float RX = psMetadataLookupF32 (&status, file->fpa->concepts, "FPA.BORE.RX"); 
    322     float RY = psMetadataLookupF32 (&status, file->fpa->concepts, "FPA.BORE.RY"); 
    323     float To = psMetadataLookupF32 (&status, file->fpa->concepts, "FPA.BORE.T0"); 
    324     float Po = psMetadataLookupF32 (&status, file->fpa->concepts, "FPA.BORE.P0"); 
     318    float Xo = psMetadataLookupF32 (&status, file->fpa->concepts, "FPA.BORE.X0");
     319    float Yo = psMetadataLookupF32 (&status, file->fpa->concepts, "FPA.BORE.Y0");
     320    float RX = psMetadataLookupF32 (&status, file->fpa->concepts, "FPA.BORE.RX");
     321    float RY = psMetadataLookupF32 (&status, file->fpa->concepts, "FPA.BORE.RY");
     322    float To = psMetadataLookupF32 (&status, file->fpa->concepts, "FPA.BORE.T0");
     323    float Po = psMetadataLookupF32 (&status, file->fpa->concepts, "FPA.BORE.P0");
    325324    float PosZero = psMetadataLookupF32 (&status, file->fpa->concepts, "FPA.POS_ZERO");  /// XXX be consistent with degrees v radians
    326325    char *refChip = psMetadataLookupStr (&status, file->fpa->concepts, "FPA.REF.CHIP");
    327326
    328327    psMetadata *header = psMetadataAlloc();
    329     psMetadataAddStr(header, PS_LIST_TAIL, "COORD",    PS_META_REPLACE, "name of this layer",   "TANGENT_PLANE");
    330     psMetadataAddStr(header, PS_LIST_TAIL, "PARENT",   PS_META_REPLACE, "next layer up",        "SKY");
    331     psMetadataAddStr(header, PS_LIST_TAIL, "BOUNDARY", PS_META_REPLACE, "validity region",      "RECTANGLE");
    332     psMetadataAddStr(header, PS_LIST_TAIL, "TRANSFRM", PS_META_REPLACE, "mapping to parent",    "PROJECTION");
     328    psMetadataAddStr(header, PS_LIST_TAIL, "COORD",    PS_META_REPLACE, "name of this layer",   "TANGENT_PLANE");
     329    psMetadataAddStr(header, PS_LIST_TAIL, "PARENT",   PS_META_REPLACE, "next layer up",        "SKY");
     330    psMetadataAddStr(header, PS_LIST_TAIL, "BOUNDARY", PS_META_REPLACE, "validity region",      "RECTANGLE");
     331    psMetadataAddStr(header, PS_LIST_TAIL, "TRANSFRM", PS_META_REPLACE, "mapping to parent",    "PROJECTION");
    333332
    334333    psArray *model = psArrayAllocEmpty (1);
     
    342341    psMetadataAddF32(row,    PS_LIST_TAIL, "MINY",     PS_META_REPLACE, "range", region->y0);
    343342    psMetadataAddF32(row,    PS_LIST_TAIL, "MAXY",     PS_META_REPLACE, "range", region->y1);
    344    
     343
    345344    // psMetadataAddF32(row,    PS_LIST_TAIL, "XREF",     PS_META_REPLACE, "", file->fpa->toSky->R  * PS_DEG_RAD);
    346345    // psMetadataAddF32(row,    PS_LIST_TAIL, "YREF",     PS_META_REPLACE, "", file->fpa->toSky->D  * PS_DEG_RAD);
     
    362361    if (!psFitsWriteTable (file->fits, header, model, "TP")) {
    363362        psError(PS_ERR_IO, false, "writing sky data\n");
    364         psFree (region);
     363        psFree (region);
    365364        psFree (model);
    366         psFree (header);
     365        psFree (header);
    367366        return false;
    368367    }
     
    378377
    379378    psMetadata *header = psMetadataAlloc();
    380     psMetadataAddStr(header, PS_LIST_TAIL, "COORD",    PS_META_REPLACE, "name of this layer",   "SKY");
    381     psMetadataAddStr(header, PS_LIST_TAIL, "PARENT",   PS_META_REPLACE, "next layer up",        "NONE");
    382     psMetadataAddStr(header, PS_LIST_TAIL, "BOUNDARY", PS_META_REPLACE, "validity region",      "NONE");
    383     psMetadataAddStr(header, PS_LIST_TAIL, "TRANSFRM", PS_META_REPLACE, "mapping to parent",    "NONE");
     379    psMetadataAddStr(header, PS_LIST_TAIL, "COORD",    PS_META_REPLACE, "name of this layer",   "SKY");
     380    psMetadataAddStr(header, PS_LIST_TAIL, "PARENT",   PS_META_REPLACE, "next layer up",        "NONE");
     381    psMetadataAddStr(header, PS_LIST_TAIL, "BOUNDARY", PS_META_REPLACE, "validity region",      "NONE");
     382    psMetadataAddStr(header, PS_LIST_TAIL, "TRANSFRM", PS_META_REPLACE, "mapping to parent",    "NONE");
    384383
    385384    psArray *model = psArrayAllocEmpty (1);
     
    387386    psMetadataAddStr(row,    PS_LIST_TAIL, "SEGMENT",  PS_META_REPLACE, "name of this segment", "SKY");
    388387    psMetadataAddStr(row,    PS_LIST_TAIL, "PARENT",   PS_META_REPLACE, "next layer up",        "NONE");
    389    
     388
    390389    psArrayAdd (model, 100, row);
    391390    psFree (row);
     
    407406    {
    408407
    409         // write the full model in one pass: require the level to be FPA
    410         if (view->chip != -1) {
    411             psError(PS_ERR_IO, false, "Astrometry must be read at the FPA level");
    412             return false;
    413         }
    414 
    415         if (!pmAstromModelReadFPA (file)) {
    416             psError(PS_ERR_IO, false, "Failed to read Astrometry for fpa");
    417             return false;
    418         }
    419         return true;
     408        // write the full model in one pass: require the level to be FPA
     409        if (view->chip != -1) {
     410            psError(PS_ERR_IO, false, "Astrometry must be read at the FPA level");
     411            return false;
     412        }
     413
     414        if (!pmAstromModelReadFPA (file)) {
     415            psError(PS_ERR_IO, false, "Failed to read Astrometry for fpa");
     416            return false;
     417        }
     418        return true;
    420419    }
    421420
     
    424423
    425424    if (!pmAstromModelReadPHU (file)) {
    426         psError(PS_ERR_IO, false, "Failed to read PHU for Astrometry model");
    427         return false;
     425        psError(PS_ERR_IO, false, "Failed to read PHU for Astrometry model");
     426        return false;
    428427    }
    429428
    430429    if (!pmAstromModelReadChips (file)) {
    431         psError(PS_ERR_IO, false, "Failed to read Astrometry for chips");
    432         return false;
     430        psError(PS_ERR_IO, false, "Failed to read Astrometry for chips");
     431        return false;
    433432    }
    434433
    435434    if (!pmAstromModelReadFP (file)) {
    436         psError(PS_ERR_IO, false, "Failed to read Sky for Astrometry model");
    437         return false;
     435        psError(PS_ERR_IO, false, "Failed to read Sky for Astrometry model");
     436        return false;
    438437    }
    439438
     
    441440    // transformation determined in FP
    442441    if (!pmAstromModelReadTP (file)) {
    443         psError(PS_ERR_IO, false, "Failed to read Sky for Astrometry model");
    444         return false;
     442        psError(PS_ERR_IO, false, "Failed to read Sky for Astrometry model");
     443        return false;
    445444    }
    446445
    447446    if (!pmAstromModelReadSky (file)) {
    448         psError(PS_ERR_IO, false, "Failed to read Sky for Astrometry model");
    449         return false;
    450     }
    451 
    452     return true;
    453 }
    454 
    455 bool pmAstromModelReadPHU (pmFPAfile *file) { 
     447        psError(PS_ERR_IO, false, "Failed to read Sky for Astrometry model");
     448        return false;
     449    }
     450
     451    return true;
     452}
     453
     454bool pmAstromModelReadPHU (pmFPAfile *file) {
    456455
    457456    fprintf (stderr, "not sure we need to read PHU\n");
     
    462461
    463462    for (int i = 0; i < fpa->chips->n; i++) {
    464         pmChip *chip = fpa->chips->data[i];
    465         if (!chip) continue;
    466         char *thisone = psMetadataLookupStr (NULL, chip->concepts, "CHIP.NAME");
    467         if (!thisone) continue;
    468         if (!strcmp (name, thisone)) return (i);
     463        pmChip *chip = fpa->chips->data[i];
     464        if (!chip) continue;
     465        char *thisone = psMetadataLookupStr (NULL, chip->concepts, "CHIP.NAME");
     466        if (!thisone) continue;
     467        if (!strcmp (name, thisone)) return (i);
    469468    }
    470469    return -1;
     
    474473
    475474    for (int i = 0; i < fpa->chips->n; i++) {
    476         pmChip *chip = fpa->chips->data[i];
    477         if (!chip) continue;
    478         char *thisone = psMetadataLookupStr (NULL, chip->concepts, "CHIP.NAME");
    479         if (!thisone) continue;
    480         if (!strcmp (name, thisone)) return (chip);
     475        pmChip *chip = fpa->chips->data[i];
     476        if (!chip) continue;
     477        char *thisone = psMetadataLookupStr (NULL, chip->concepts, "CHIP.NAME");
     478        if (!thisone) continue;
     479        if (!strcmp (name, thisone)) return (chip);
    481480    }
    482481    return NULL;
     
    496495    // free exising tranformations in prep for new alloc below
    497496    for (int i = 0; i < file->fpa->chips->n; i++) {
    498         pmChip *chip = file->fpa->chips->data[i];
    499         psFree (chip->toFPA);
    500         chip->toFPA = NULL;
     497        pmChip *chip = file->fpa->chips->data[i];
     498        psFree (chip->toFPA);
     499        chip->toFPA = NULL;
    501500    }
    502501
     
    512511    // parse the model entries
    513512    for (int i = 0; i < model->n; i++) {
    514         psMetadata *row = model->data[i];
    515 
    516         // name of the chip for this row.
    517         char *chipname = psMetadataLookupStr (&status, row, "SEGMENT");
    518 
    519         // get chip from name
    520         pmChip *chip = pmConceptsChipFromName (file->fpa, chipname);
    521         REQUIRE (chip, "invalid chip name");
    522 
    523         // define the toFPA transform if not already defined
    524         int nX = psMetadataLookupS32(&status, row, "NXORDER"); REQUIRE (status, "missing NXORDER");
    525         int nY = psMetadataLookupS32(&status, row, "NYORDER"); REQUIRE (status, "missing NYORDER");
    526         if (chip->toFPA == NULL) {
    527             chip->toFPA = psPlaneTransformAlloc(nX, nY);
    528         } else {
    529             REQUIRE (chip->toFPA->x->nX == nX, "mismatch in chip order");
    530             REQUIRE (chip->toFPA->x->nY == nY, "mismatch in chip order");
    531             REQUIRE (chip->toFPA->y->nX == nX, "mismatch in chip order");
    532             REQUIRE (chip->toFPA->y->nY == nY, "mismatch in chip order");
    533         }
    534 
    535         int ix = psMetadataLookupS32(&status, row, "XORDER");  REQUIRE (status, "missing XORDER");
    536         int iy = psMetadataLookupS32(&status, row, "YORDER");  REQUIRE (status, "missing YORDER");
    537 
    538         // XXX do I need to use this or can i rely on the camera concepts?
    539         // minX = psMetadataLookupF32(&status, row, "MINX");
    540         // maxX = psMetadataLookupF32(&status, row, "MAXX");
    541         // minY = psMetadataLookupF32(&status, row, "MINY");
    542         // maxY = psMetadataLookupF32(&status, row, "MAXY");
    543 
    544         // XXX need to include mask values
    545         chip->toFPA->x->coeff[ix][iy]    = psMetadataLookupF32(&status, row, "POLY_X");
    546         chip->toFPA->y->coeff[ix][iy]    = psMetadataLookupF32(&status, row, "POLY_Y");
    547         chip->toFPA->x->coeffErr[ix][iy] = psMetadataLookupF32(&status, row, "ERROR_X");
    548         chip->toFPA->y->coeffErr[ix][iy] = psMetadataLookupF32(&status, row, "ERROR_Y");
    549         chip->toFPA->x->coeffMask[ix][iy] = psMetadataLookupU8(&status, row, "MASK_X");
    550         chip->toFPA->y->coeffMask[ix][iy] = psMetadataLookupU8(&status, row, "MASK_Y");
     513        psMetadata *row = model->data[i];
     514
     515        // name of the chip for this row.
     516        char *chipname = psMetadataLookupStr (&status, row, "SEGMENT");
     517
     518        // get chip from name
     519        pmChip *chip = pmConceptsChipFromName (file->fpa, chipname);
     520        REQUIRE (chip, "invalid chip name");
     521
     522        // define the toFPA transform if not already defined
     523        int nX = psMetadataLookupS32(&status, row, "NXORDER"); REQUIRE (status, "missing NXORDER");
     524        int nY = psMetadataLookupS32(&status, row, "NYORDER"); REQUIRE (status, "missing NYORDER");
     525        if (chip->toFPA == NULL) {
     526            chip->toFPA = psPlaneTransformAlloc(nX, nY);
     527        } else {
     528            REQUIRE (chip->toFPA->x->nX == nX, "mismatch in chip order");
     529            REQUIRE (chip->toFPA->x->nY == nY, "mismatch in chip order");
     530            REQUIRE (chip->toFPA->y->nX == nX, "mismatch in chip order");
     531            REQUIRE (chip->toFPA->y->nY == nY, "mismatch in chip order");
     532        }
     533
     534        int ix = psMetadataLookupS32(&status, row, "XORDER");  REQUIRE (status, "missing XORDER");
     535        int iy = psMetadataLookupS32(&status, row, "YORDER");  REQUIRE (status, "missing YORDER");
     536
     537        // XXX do I need to use this or can i rely on the camera concepts?
     538        // minX = psMetadataLookupF32(&status, row, "MINX");
     539        // maxX = psMetadataLookupF32(&status, row, "MAXX");
     540        // minY = psMetadataLookupF32(&status, row, "MINY");
     541        // maxY = psMetadataLookupF32(&status, row, "MAXY");
     542
     543        // XXX need to include mask values
     544        chip->toFPA->x->coeff[ix][iy]    = psMetadataLookupF32(&status, row, "POLY_X");
     545        chip->toFPA->y->coeff[ix][iy]    = psMetadataLookupF32(&status, row, "POLY_Y");
     546        chip->toFPA->x->coeffErr[ix][iy] = psMetadataLookupF32(&status, row, "ERROR_X");
     547        chip->toFPA->y->coeffErr[ix][iy] = psMetadataLookupF32(&status, row, "ERROR_Y");
     548        chip->toFPA->x->coeffMask[ix][iy] = psMetadataLookupU8(&status, row, "MASK_X");
     549        chip->toFPA->y->coeffMask[ix][iy] = psMetadataLookupU8(&status, row, "MASK_Y");
    551550    }
    552551
    553552    // convert the toFPA transfomations to fromFPA transformations
    554553    for (int i = 0; i < file->fpa->chips->n; i++) {
    555         pmChip *chip = file->fpa->chips->data[i];
    556         if (!chip->toFPA) continue;
    557         psRegion *region = pmChipPixels (chip);
    558         psFree (chip->fromFPA);
    559         chip->fromFPA = psPlaneTransformInvert(NULL, chip->toFPA, *region, 50);
    560         psFree (region);
     554        pmChip *chip = file->fpa->chips->data[i];
     555        if (!chip->toFPA) continue;
     556        psRegion *region = pmChipPixels (chip);
     557        psFree (chip->fromFPA);
     558        chip->fromFPA = psPlaneTransformInvert(NULL, chip->toFPA, *region, 50);
     559        psFree (region);
    561560    }
    562561
     
    589588    // parse the model
    590589    for (int i = 0; i < model->n; i++) {
    591         psMetadata *row = model->data[i];
    592 
    593         // there is only one transformation in this model; the order is defined in the header
    594         int nX = psMetadataLookupS32(&status, row, "NXORDER"); REQUIRE (status, "missing NXORDER");
    595         int nY = psMetadataLookupS32(&status, row, "NYORDER"); REQUIRE (status, "missing NYORDER");
    596         if (file->fpa->toTPA == NULL) {
    597             // allocate the new transformation
    598             file->fpa->toTPA = psPlaneTransformAlloc(nX, nY);
    599         } else {
    600             REQUIRE (file->fpa->toTPA->x->nX == nX, "mismatch in chip order");
    601             REQUIRE (file->fpa->toTPA->x->nY == nY, "mismatch in chip order");
    602             REQUIRE (file->fpa->toTPA->y->nX == nX, "mismatch in chip order");
    603             REQUIRE (file->fpa->toTPA->y->nY == nY, "mismatch in chip order");
    604         }
    605 
    606         int ix = psMetadataLookupS32(&status, row, "XORDER"); REQUIRE (status, "missing XORDER");
    607         int iy = psMetadataLookupS32(&status, row, "YORDER"); REQUIRE (status, "missing YORDER");
    608         file->fpa->toTPA->x->coeff[ix][iy]     = psMetadataLookupF32(&status, row, "POLY_X");  REQUIRE (status, "missing POLY_X");
    609         file->fpa->toTPA->y->coeff[ix][iy]     = psMetadataLookupF32(&status, row, "POLY_Y");  REQUIRE (status, "missing POLY_Y");
    610         file->fpa->toTPA->x->coeffErr[ix][iy]  = psMetadataLookupF32(&status, row, "ERROR_X"); REQUIRE (status, "missing ERROR_X");
    611         file->fpa->toTPA->y->coeffErr[ix][iy]  = psMetadataLookupF32(&status, row, "ERROR_Y"); REQUIRE (status, "missing ERROR_Y");
    612         file->fpa->toTPA->x->coeffMask[ix][iy] = psMetadataLookupU8 (&status, row, "MASK_X");  REQUIRE (status, "missing MASK_X");
    613         file->fpa->toTPA->y->coeffMask[ix][iy] = psMetadataLookupU8 (&status, row, "MASK_Y");  REQUIRE (status, "missing MASK_Y");
     590        psMetadata *row = model->data[i];
     591
     592        // there is only one transformation in this model; the order is defined in the header
     593        int nX = psMetadataLookupS32(&status, row, "NXORDER"); REQUIRE (status, "missing NXORDER");
     594        int nY = psMetadataLookupS32(&status, row, "NYORDER"); REQUIRE (status, "missing NYORDER");
     595        if (file->fpa->toTPA == NULL) {
     596            // allocate the new transformation
     597            file->fpa->toTPA = psPlaneTransformAlloc(nX, nY);
     598        } else {
     599            REQUIRE (file->fpa->toTPA->x->nX == nX, "mismatch in chip order");
     600            REQUIRE (file->fpa->toTPA->x->nY == nY, "mismatch in chip order");
     601            REQUIRE (file->fpa->toTPA->y->nX == nX, "mismatch in chip order");
     602            REQUIRE (file->fpa->toTPA->y->nY == nY, "mismatch in chip order");
     603        }
     604
     605        int ix = psMetadataLookupS32(&status, row, "XORDER"); REQUIRE (status, "missing XORDER");
     606        int iy = psMetadataLookupS32(&status, row, "YORDER"); REQUIRE (status, "missing YORDER");
     607        file->fpa->toTPA->x->coeff[ix][iy]     = psMetadataLookupF32(&status, row, "POLY_X");  REQUIRE (status, "missing POLY_X");
     608        file->fpa->toTPA->y->coeff[ix][iy]     = psMetadataLookupF32(&status, row, "POLY_Y");  REQUIRE (status, "missing POLY_Y");
     609        file->fpa->toTPA->x->coeffErr[ix][iy]  = psMetadataLookupF32(&status, row, "ERROR_X"); REQUIRE (status, "missing ERROR_X");
     610        file->fpa->toTPA->y->coeffErr[ix][iy]  = psMetadataLookupF32(&status, row, "ERROR_Y"); REQUIRE (status, "missing ERROR_Y");
     611        file->fpa->toTPA->x->coeffMask[ix][iy] = psMetadataLookupU8 (&status, row, "MASK_X");  REQUIRE (status, "missing MASK_X");
     612        file->fpa->toTPA->y->coeffMask[ix][iy] = psMetadataLookupU8 (&status, row, "MASK_Y");  REQUIRE (status, "missing MASK_Y");
    614613    }
    615614
     
    629628    psMetadataItem *newItem = psMetadataItemCopy(item); \
    630629    if (!psMetadataAddItem(TO, newItem, PS_LIST_TAIL, PS_META_REPLACE)) { \
    631         psAbort ("cannot copy %s", NAME); \
     630        psAbort ("cannot copy %s", NAME); \
    632631    } \
    633632    psFree (newItem); }
     
    635634// third layer applies boresite corrections and converts tangent plane to sky
    636635bool pmAstromModelReadTP (pmFPAfile *file) {
    637    
     636
    638637    if (!psFitsMoveExtName (file->fits, "TP")) {
    639638        psError(PS_ERR_IO, false, "missing TP extension in astrometry model\n");
     
    692691// third layer applies boresite corrections and converts tangent plane to sky
    693692bool pmAstromModelSetTP (pmFPAfile *file, psMetadata *concepts) {
    694    
     693
    695694    bool status;
    696695
     
    748747    psPlaneTransformApply (boreFP, chip->toFPA, boreCH);
    749748    psPlaneTransformApply (boreTP, file->fpa->toTPA, boreFP);
    750     psDeproject (boreSky, boreTP, file->fpa->toSky); 
     749    psDeproject (boreSky, boreTP, file->fpa->toSky);
    751750
    752751    // modify the projection to account for offset between true and reported boresite
  • trunk/psModules/src/astrom/pmAstrometryModel.h

    r17034 r18601  
    44 * @author EAM, IfA
    55 *
    6  * @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
    7  * @date $Date: 2008-03-18 18:24:29 $
     6 * @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
     7 * @date $Date: 2008-07-17 22:38:15 $
    88 * Copyright 2006 Institute for Astronomy, University of Hawaii
    99 */
     
    1919bool pmAstromModelCheckDataStatusForChip (const pmChip *chip);
    2020
    21 bool pmAstromModelWriteForView (const pmFPAview *view, pmFPAfile *file, const pmConfig *config);
    22 bool pmAstromModelWriteFPA (pmFPAfile *file);
    23 bool pmAstromModelWritePHU (pmFPAfile *file);
     21bool pmAstromModelWriteForView (const pmFPAview *view, pmFPAfile *file, pmConfig *config);
     22bool pmAstromModelWriteFPA (pmFPAfile *file, const pmFPA *fpa);
     23bool pmAstromModelWritePHU (pmFPAfile *file, const pmFPA *fpa);
    2424bool pmAstromModelWriteSky (pmFPAfile *file);
    2525bool pmAstromModelWriteTP (pmFPAfile *file);
  • trunk/psModules/src/astrom/pmAstrometryRefstars.c

    r17062 r18601  
    11/* @file  pmAstrometryRefstars.c
    22 * @brief Functions to write (and read?) astrometric reference stars
    3  * 
     3 *
    44 * @ingroup AstroImage
    55 *
    66 * @author EAM, IfA
    7  * @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
    8  * @date $Date: 2008-03-20 00:27:00 $
     7 * @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
     8 * @date $Date: 2008-07-17 22:38:15 $
    99 * Copyright 2008 Institute for Astronomy, University of Hawaii
    1010 */
     
    3232#include "pmFPAview.h"
    3333#include "pmFPAfile.h"
     34#include "pmFPAfileFitsIO.h"
    3435#include "pmAstrometryObjects.h"
    3536#include "pmAstrometryRefstars.h"
     
    144145}
    145146
    146 bool pmAstromRefstarsWritePHU (const pmFPAview *view, pmFPAfile *file, const pmConfig *config) {
    147 
    148     // output header data 
     147bool pmAstromRefstarsWritePHU (const pmFPAview *view, pmFPAfile *file, pmConfig *config) {
     148
     149    // output header data
    149150    psMetadata *outhead = psMetadataAlloc();
    150151
    151152    // use the FPA phu to generate the PHU header
    152     pmHDU *phu = file->fpa->hdu;
     153    pmFPA *fpa = pmFPAfileSuitableFPA(file, view, config, false); // Suitable FPA for writing
     154    pmHDU *phu = psMemIncrRefCounter(fpa->hdu);
     155    psFree(fpa);
    153156
    154157    // if there is no FPA PHU, this is a single header+image (extension-less) file. This could be
     
    156159    // write it out as a 'blank'
    157160    if (phu) {
    158         psMetadataCopy (outhead, phu->header);
     161        psMetadataCopy (outhead, phu->header);
    159162    } else {
    160         pmConfigConformHeader (outhead, file->format);
    161     }
     163        pmConfigConformHeader (outhead, file->format);
     164    }
     165    psFree(phu);
    162166
    163167    psMetadataAddBool (outhead, PS_LIST_TAIL, "EXTEND", PS_META_REPLACE, "this file has extensions", true);
     
    256260
    257261    // set the extname : we are really only allowed one entry per chip; check this here?
    258     char *chiprule = psStringCopy ("{CHIP.NAME}"); 
     262    char *chiprule = psStringCopy ("{CHIP.NAME}");
    259263    char *chipname = pmFPAfileNameFromRule (chiprule, file, view);
    260264
    261265    for (int i = 0; i < refstars->n; i++) {
    262266      psMetadata *row = psMetadataAlloc ();
    263                
     267
    264268      pmAstromObj *ref = refstars->data[i];
    265269
    266       psMetadataAddF64(row,    PS_LIST_TAIL, "RA",      PS_META_REPLACE, "degrees", PS_DEG_RAD*ref->sky->r);
    267       psMetadataAddF64(row,    PS_LIST_TAIL, "DEC",     PS_META_REPLACE, "degrees", PS_DEG_RAD*ref->sky->d);
    268       psMetadataAddF32(row,    PS_LIST_TAIL, "TP_X",    PS_META_REPLACE, "microns", ref->TP->x);
    269       psMetadataAddF32(row,    PS_LIST_TAIL, "TP_Y",    PS_META_REPLACE, "microns", ref->TP->y);
    270       psMetadataAddF32(row,    PS_LIST_TAIL, "FP_X",    PS_META_REPLACE, "microns", ref->FP->x);
    271       psMetadataAddF32(row,    PS_LIST_TAIL, "FP_Y",    PS_META_REPLACE, "microns", ref->FP->y);
    272       psMetadataAddF32(row,    PS_LIST_TAIL, "CHIP_X",  PS_META_REPLACE, "microns", ref->chip->x);
    273       psMetadataAddF32(row,    PS_LIST_TAIL, "CHIP_Y",  PS_META_REPLACE, "microns", ref->chip->y);
    274       psMetadataAddF32(row,    PS_LIST_TAIL, "MAG",     PS_META_REPLACE, "microns", ref->Mag);
     270      psMetadataAddF64(row,    PS_LIST_TAIL, "RA",      PS_META_REPLACE, "degrees", PS_DEG_RAD*ref->sky->r);
     271      psMetadataAddF64(row,    PS_LIST_TAIL, "DEC",     PS_META_REPLACE, "degrees", PS_DEG_RAD*ref->sky->d);
     272      psMetadataAddF32(row,    PS_LIST_TAIL, "TP_X",    PS_META_REPLACE, "microns", ref->TP->x);
     273      psMetadataAddF32(row,    PS_LIST_TAIL, "TP_Y",    PS_META_REPLACE, "microns", ref->TP->y);
     274      psMetadataAddF32(row,    PS_LIST_TAIL, "FP_X",    PS_META_REPLACE, "microns", ref->FP->x);
     275      psMetadataAddF32(row,    PS_LIST_TAIL, "FP_Y",    PS_META_REPLACE, "microns", ref->FP->y);
     276      psMetadataAddF32(row,    PS_LIST_TAIL, "CHIP_X",  PS_META_REPLACE, "microns", ref->chip->x);
     277      psMetadataAddF32(row,    PS_LIST_TAIL, "CHIP_Y",  PS_META_REPLACE, "microns", ref->chip->y);
     278      psMetadataAddF32(row,    PS_LIST_TAIL, "MAG",     PS_META_REPLACE, "microns", ref->Mag);
    275279      psMetadataAddF32(row,    PS_LIST_TAIL, "MAG_ERR", PS_META_REPLACE, "microns", ref->dMag);
    276280
     
    281285        psError(PS_ERR_IO, false, "writing refstars\n");
    282286        psFree (table);
    283         psFree (header);
    284         psFree (chiprule);
    285         psFree (chipname);
     287        psFree (header);
     288        psFree (chiprule);
     289        psFree (chipname);
    286290        return false;
    287291    }
  • trunk/psModules/src/astrom/pmAstrometryRefstars.h

    r17034 r18601  
    55 *
    66 * @author EAM, IfA
    7  * @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
    8  * @date $Date: 2008-03-18 18:24:29 $
     7 * @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
     8 * @date $Date: 2008-07-17 22:38:15 $
    99 * Copyright 2008 Institute for Astronomy, University of Hawaii
    1010 */
     
    2323
    2424bool pmAstromRefstarsWriteForView (const pmFPAview *view, pmFPAfile *file, const pmConfig *config);
    25 bool pmAstromRefstarsWritePHU (const pmFPAview *view, pmFPAfile *file, const pmConfig *config);
     25bool pmAstromRefstarsWritePHU (const pmFPAview *view, pmFPAfile *file, pmConfig *config);
    2626
    2727bool pmAstromRefstarsWriteFPA (pmFPA *fpa, const pmFPAview *view, pmFPAfile *file, const pmConfig *config);
  • trunk/psModules/src/camera/pmFPAfileFitsIO.c

    r18554 r18601  
    2222#include "pmFPAConstruct.h"
    2323#include "pmDark.h"
    24 
    25 pmFPA *pmFPAfileSuitableFPA(const pmFPAfile *file, const pmFPAview *view, const pmConfig *config)
    26 {
    27     PS_ASSERT_PTR_NON_NULL(file, NULL);
    28     PS_ASSERT_PTR_NON_NULL(view, NULL);
     24#include "pmConcepts.h"
     25
     26// Get a suitable FPA for the file; generate it if necessary
     27static pmFPA *suitableFPA(const pmFPAfile *file, // File for which to get FPA
     28                          const pmFPAview *view, // View at which to produce the FPA
     29                          pmConfig *config, // Configuration (for concepts update)
     30                          bool pixels   // Worry about copying pixels?
     31    )
     32{
     33    psAssert(file, "It's supposed to be here");
     34    psAssert(view, "It's supposed to be here");
     35    psAssert(config, "It's supposed to be here");
    2936
    3037    if (!file->format) {                // Working with the same output format as input format
     
    8693    switch (level) {
    8794      case PM_FPA_LEVEL_FPA:
    88         if (!pmFPACopy(copy, file->fpa)) {
     95        if ((pixels && !pmFPACopy(copy, file->fpa)) ||
     96            (!pixels && !pmFPACopyStructure(copy, file->fpa, 1, 1))) {
    8997            psError(PS_ERR_UNKNOWN, false, "Unable to copy FPA for format conversion.\n");
    9098            return NULL;
     
    94102          pmChip *chip = pmFPAviewThisChip(view, copy); // Chip of interest
    95103          pmChip *srcChip = pmFPAviewThisChip(view, file->fpa); // Source chip
    96           if (!pmChipCopy(chip, srcChip)) {
     104          if ((pixels && !pmChipCopy(chip, srcChip)) ||
     105              (!pixels && !pmChipCopyStructure(chip, srcChip, 1, 1))) {
    97106              psError(PS_ERR_UNKNOWN, false, "Unable to copy chip for format conversion.\n");
    98107              return false;
     
    103112          pmCell *cell = pmFPAviewThisCell(view, copy); // Cell of interest
    104113          pmCell *srcCell = pmFPAviewThisCell(view, file->fpa); // Source cell
    105           if (!pmCellCopy(cell, srcCell)) {
     114          if ((pixels && !pmCellCopy(cell, srcCell)) ||
     115              (!pixels && !pmCellCopyStructure(cell, srcCell, 1, 1))) {
    106116              psError(PS_ERR_UNKNOWN, false, "Unable to copy cell for format conversion.\n");
    107117              return false;
     
    115125    }
    116126
     127    // Unreachable
    117128    return NULL;
    118 
     129}
     130
     131
     132pmFPA *pmFPAfileSuitableFPA(const pmFPAfile *file, const pmFPAview *view, pmConfig *config, bool pixels)
     133{
     134    PS_ASSERT_PTR_NON_NULL(file, NULL);
     135    PS_ASSERT_PTR_NON_NULL(view, NULL);
     136    PS_ASSERT_PTR_NON_NULL(config, NULL);
     137
     138    pmFPA *fpa = suitableFPA(file, view, config, pixels); // A suitable FPA for writing
     139    if (!fpa) {
     140        psError(PS_ERR_UNKNOWN, false, "Unable to produce suitable FPA.");
     141        return NULL;
     142    }
     143
     144    // Ensure headers and all are updated
     145    // This is here so that the individual write functions (e.g., images, PSFs, sources, etc) don't have to
     146    // take care of all this themselves (because they generally don't).
     147    switch (file->type) {
     148      case PM_FPA_FILE_IMAGE:
     149      case PM_FPA_FILE_MASK:
     150      case PM_FPA_FILE_WEIGHT:
     151      case PM_FPA_FILE_HEADER:
     152      case PM_FPA_FILE_FRINGE:
     153      case PM_FPA_FILE_DARK:
     154      case PM_FPA_FILE_CMP:
     155      case PM_FPA_FILE_CMF:
     156      case PM_FPA_FILE_PSF:
     157      case PM_FPA_FILE_ASTROM_MODEL:
     158      case PM_FPA_FILE_ASTROM_REFSTARS: {
     159          pmHDU *hdu = pmFPAviewThisHDU(view, fpa);
     160          if (hdu) {
     161              if (!hdu->header) {
     162                  hdu->header = psMetadataAlloc();
     163              }
     164              pmConfigConformHeader(hdu->header, file->format);
     165
     166              // whenever we write out a mask image, we should define the bits which represent mask concepts
     167              if (file->type == PM_FPA_FILE_MASK) {
     168                  assert (hdu->header);
     169                  if (!pmConfigMaskWriteHeader(config, hdu->header)) {
     170                      psError(PS_ERR_UNKNOWN, false,
     171                              "failed to set the bitmask names in the PHU header for Image %s (%s)\n",
     172                              file->filename, file->name);
     173                      return false;
     174                  }
     175              }
     176          }
     177
     178          pmChip *chip = pmFPAviewThisChip(view, fpa); // Chip of interest, or NULL
     179          pmCell *cell = pmFPAviewThisCell(view, fpa); // Cell of interest, or NULL
     180          if (!pmFPAUpdateNames(fpa, chip, cell)) {
     181              psError(PS_ERR_UNKNOWN, false, "Unable to update names in header.");
     182              return false;
     183          }
     184
     185          pmConceptSource sources = PM_CONCEPT_SOURCE_HEADER | PM_CONCEPT_SOURCE_CELLS |
     186              PM_CONCEPT_SOURCE_DEFAULTS | PM_CONCEPT_SOURCE_DATABASE; // Concept sources to write
     187          if (cell) {
     188              if (!pmConceptsWriteCell(cell, sources, true, config)) {
     189                  psError(PS_ERR_IO, false, "Unable to write concepts for cell.\n");
     190                  return false;
     191              }
     192          } else if (chip) {
     193              if (!pmConceptsWriteChip(chip, sources, true, true, config)) {
     194                  psError(PS_ERR_IO, false, "Unable to write concepts for chip.\n");
     195                  return false;
     196              }
     197          } else if (!pmConceptsWriteFPA(fpa, sources, true, config)) {
     198              psError(PS_ERR_IO, false, "Unable to write concepts for FPA.\n");
     199              return false;
     200          }
     201          break;
     202      }
     203      default:
     204        // No action
     205        break;
     206    }
     207
     208    return fpa;
    119209}
    120210
     
    142232
    143233// given an already-opened fits file, write the table corresponding to the specified view
    144 bool pmFPAviewWriteFitsTable(const pmFPAview *view, pmFPAfile *file, const char *name)
    145 {
    146     PS_ASSERT_PTR_NON_NULL(view, false);
    147     PS_ASSERT_PTR_NON_NULL(file, false);
    148 
    149     pmFPA *fpa = file->fpa;            // FPA of interest
     234bool pmFPAviewWriteFitsTable(const pmFPAview *view, pmFPAfile *file, const char *name, pmConfig *config)
     235{
     236    PS_ASSERT_PTR_NON_NULL(view, false);
     237    PS_ASSERT_PTR_NON_NULL(file, false);
     238
     239    pmFPA *fpa = pmFPAfileSuitableFPA(file, view, config, false); // FPA of interest
    150240    psFits *fits = file->fits;          // FITS file
    151241
     
    280370    PS_ASSERT_PTR_NON_NULL(fits, false);
    281371
    282     pmFPA *fpa = pmFPAfileSuitableFPA(file, view, config); // FPA to write
     372    pmFPA *fpa = pmFPAfileSuitableFPA(file, view, config, true); // FPA to write
    283373
    284374    switch (pmFPAviewLevel(view)) {
     
    489579
    490580    // select or generate the desired fpa in the correct output format
    491     pmFPA *fpa = pmFPAfileSuitableFPA(file, view, config);
     581    pmFPA *fpa = pmFPAfileSuitableFPA(file, view, config, false);
    492582    pmHDU *phu = pmFPAviewThisHDU(view, fpa);
    493583    if (!phu || !phu->blankPHU) {
     
    499589    // whenever we write out a mask image, we should define the bits which represent mask concepts
    500590    if (file->type == PM_FPA_FILE_MASK) {
    501         assert (phu->header);
    502         if (!pmConfigMaskWriteHeader (config, phu->header)) {
    503             psError(PS_ERR_UNKNOWN, false, "failed to set the bitmask names in the PHU header for Image %s (%s)\n", file->filename, file->name);
    504             return false;
    505         }
     591        assert (phu->header);
     592        if (!pmConfigMaskWriteHeader (config, phu->header)) {
     593            psError(PS_ERR_UNKNOWN, false, "failed to set the bitmask names in the PHU header for Image %s (%s)\n", file->filename, file->name);
     594            return false;
     595        }
    506596    }
    507597
  • trunk/psModules/src/camera/pmFPAfileFitsIO.h

    r18364 r18601  
    55 * @author PAP, IfA
    66 *
    7  * @version $Revision: 1.14 $ $Name: not supported by cvs2svn $
    8  * @date $Date: 2008-06-30 00:53:45 $
     7 * @version $Revision: 1.15 $ $Name: not supported by cvs2svn $
     8 * @date $Date: 2008-07-17 22:38:15 $
    99 * Copyright 2004-2005 Institute for Astronomy, University of Hawaii
    1010 */
     
    8686bool pmFPAviewWriteFitsTable(const pmFPAview *view, ///<  View specifying level of interest
    8787                             pmFPAfile *file, ///< FPA file to write
    88                              const char *name ///< Name of table
     88                             const char *name, ///< Name of table
     89                             pmConfig *config ///< Configuration
    8990                            );
    9091
     
    9798pmFPA *pmFPAfileSuitableFPA(const pmFPAfile *file,///< File containing the fpa
    9899                            const pmFPAview *view, ///< View at which to produce the fpa
    99                             const pmConfig *config ///< Configuration
     100                            pmConfig *config, ///< Configuration
     101                            bool pixels ///< Worry about copying the pixels?
    100102                           );
    101103
  • trunk/psModules/src/camera/pmFPAfileIO.c

    r18554 r18601  
    405405    }
    406406
    407     // check if the file is a FITS file (or uses the fits header)
    408     bool fitsType = false;
    409     fitsType |= (file->type == PM_FPA_FILE_IMAGE);
    410     fitsType |= (file->type == PM_FPA_FILE_MASK);
    411     fitsType |= (file->type == PM_FPA_FILE_WEIGHT);
    412     fitsType |= (file->type == PM_FPA_FILE_HEADER);
    413     fitsType |= (file->type == PM_FPA_FILE_FRINGE);
    414     fitsType |= (file->type == PM_FPA_FILE_DARK);
    415     fitsType |= (file->type == PM_FPA_FILE_CMP);
    416     fitsType |= (file->type == PM_FPA_FILE_CMF);
    417     fitsType |= (file->type == PM_FPA_FILE_PSF);
    418     fitsType |= (file->type == PM_FPA_FILE_ASTROM_MODEL);
    419     fitsType |= (file->type == PM_FPA_FILE_ASTROM_REFSTARS);
    420 
    421     // Ensure headers and all are updated
    422     // This is here so that the individual write functions (e.g., images, PSFs, sources, etc) don't have to
    423     // take care of all this themselves (because they generally don't).
    424     if (fitsType) {
    425         pmHDU *hdu = pmFPAviewThisHDU(view, file->fpa);
    426         if (hdu) {
    427             if (!hdu->header) {
    428                 hdu->header = psMetadataAlloc();
    429             }
    430             pmConfigConformHeader(hdu->header, file->format);
    431 
    432             // whenever we write out a mask image, we should define the bits which represent mask concepts
    433             if (file->type == PM_FPA_FILE_MASK) {
    434                 assert (hdu->header);
    435                 if (!pmConfigMaskWriteHeader (config, hdu->header)) {
    436                     psError(PS_ERR_UNKNOWN, false, "failed to set the bitmask names in the PHU header for Image %s (%s)\n", file->filename, file->name);
    437                     return false;
    438                 }
    439             }
    440         }
    441 
    442         pmFPA *fpa = file->fpa;         // FPA of interest
    443         pmChip *chip = pmFPAviewThisChip(view, file->fpa); // Chip of interest, or NULL
    444         pmCell *cell = pmFPAviewThisCell(view, file->fpa); // Cell of interest, or NULL
    445         if (!pmFPAUpdateNames(fpa, chip, cell)) {
    446             psError(PS_ERR_UNKNOWN, false, "Unable to update names in header.");
    447             return false;
    448         }
    449 
    450         pmConceptSource sources = PM_CONCEPT_SOURCE_HEADER | PM_CONCEPT_SOURCE_CELLS |
    451             PM_CONCEPT_SOURCE_DEFAULTS | PM_CONCEPT_SOURCE_DATABASE; // Concept sources to write
    452         if (cell) {
    453             if (!pmConceptsWriteCell(cell, sources, true, config)) {
    454                 psError(PS_ERR_IO, false, "Unable to write concepts for cell.\n");
    455                 return false;
    456             }
    457         } else if (chip) {
    458             if (!pmConceptsWriteChip(chip, sources, true, true, config)) {
    459                 psError(PS_ERR_IO, false, "Unable to write concepts for chip.\n");
    460                 return false;
    461             }
    462         } else if (!pmConceptsWriteFPA(fpa, sources, true, config)) {
    463             psError(PS_ERR_IO, false, "Unable to write concepts for FPA.\n");
    464             return false;
    465         }
    466     }
     407    // IMPORTANT: If adding a FITS-based file, make sure your write function uses an FPA produced by
     408    // pmFPAfileSuitableFPA.  This ensures the HDUs are at the correct level for your output format, and sets
     409    // the headers correctly.
    467410
    468411    // select a writing method
     
    487430        status = pmFPAviewWriteFitsImage (view, file, config);
    488431        if (status) {
    489             if (!pmFPAviewWriteFitsTable(view, file, "FRINGE")) {
     432            if (!pmFPAviewWriteFitsTable(view, file, "FRINGE", config)) {
    490433                psError(PS_ERR_UNKNOWN, false, "Unable to write fringe data from %s.\n", file->filename);
    491434                return false;
     
    802745          }
    803746
    804           // XXX if we have a mask file, then we need to read the mask bit names
    805           // defined for this file
    806           if (file->type == PM_FPA_FILE_MASK) {
    807             if (!pmConfigMaskReadHeader (config, phu)) {
    808                 psError(PS_ERR_IO, false, "error in mask bits");
    809                 return false;
    810             }
    811           }
     747          // XXX if we have a mask file, then we need to read the mask bit names
     748          // defined for this file
     749          if (file->type == PM_FPA_FILE_MASK) {
     750            if (!pmConfigMaskReadHeader (config, phu)) {
     751                psError(PS_ERR_IO, false, "error in mask bits");
     752                return false;
     753            }
     754          }
    812755
    813756          // determine the current format from the header
  • trunk/psModules/src/objects/pmPSF_IO.c

    r18600 r18601  
    66 *  @author EAM, IfA
    77 *
    8  *  @version $Revision: 1.33 $ $Name: not supported by cvs2svn $
    9  *  @date $Date: 2008-07-17 20:43:38 $
     8 *  @version $Revision: 1.34 $ $Name: not supported by cvs2svn $
     9 *  @date $Date: 2008-07-17 22:38:15 $
    1010 *
    1111 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    3535#include "pmFPAview.h"
    3636#include "pmFPAfile.h"
     37#include "pmFPAfileFitsIO.h"
    3738
    3839#include "pmPeaks.h"
     
    107108}
    108109
    109 bool pmPSFmodelWriteForView (const pmFPAview *view, pmFPAfile *file, const pmConfig *config)
     110bool pmPSFmodelWriteForView (const pmFPAview *view, pmFPAfile *file, pmConfig *config)
    110111{
    111112    PS_ASSERT_PTR_NON_NULL(view, false);
     
    142143
    143144// read in all chip-level PSFmodel files for this FPA
    144 bool pmPSFmodelWriteFPA (pmFPA *fpa, const pmFPAview *view, pmFPAfile *file, const pmConfig *config)
     145bool pmPSFmodelWriteFPA (pmFPA *fpa, const pmFPAview *view, pmFPAfile *file, pmConfig *config)
    145146{
    146147    PS_ASSERT_PTR_NON_NULL(view, false);
     
    164165
    165166// read in all cell-level PSFmodel files for this chip
    166 bool pmPSFmodelWriteChip (pmChip *chip, const pmFPAview *view, pmFPAfile *file, const pmConfig *config)
     167bool pmPSFmodelWriteChip (pmChip *chip, const pmFPAview *view, pmFPAfile *file, pmConfig *config)
    167168{
    168169    PS_ASSERT_PTR_NON_NULL(view, false);
     
    185186//   - psf table (+header) : FITS Table
    186187bool pmPSFmodelWrite (psMetadata *analysis, const pmFPAview *view,
    187                       pmFPAfile *file, const pmConfig *config)
     188                      pmFPAfile *file, pmConfig *config)
    188189{
    189190    PS_ASSERT_PTR_NON_NULL(view, false);
     
    208209
    209210    // get the current header
    210     pmHDU *hdu = pmFPAviewThisHDU (view, file->fpa);
     211    pmFPA *fpa = pmFPAfileSuitableFPA(file, view, config, false); // Suitable FPA for writing
     212    pmHDU *hdu = psMemIncrRefCounter(pmFPAviewThisHDU(view, fpa));
     213    psFree(fpa);
    211214    if (!hdu) {
    212215        psError(PS_ERR_UNKNOWN, false, "Unable to find HDU");
     
    229232        if (!menu) {
    230233            psError(PS_ERR_UNKNOWN, true, "missing EXTNAME.RULES in camera.config");
     234            psFree(hdu);
    231235            return false;
    232236        }
     
    236240        if (!rule) {
    237241            psError(PS_ERR_UNKNOWN, false, "missing entry for PSF.HEAD in EXTNAME.RULES in camera.config");
     242            psFree(hdu);
    238243            return false;
    239244        }
     
    245250            psError(PS_ERR_UNKNOWN, false, "missing entry for PSF.TABLE in EXTNAME.RULES in camera.config");
    246251            psFree (headName);
     252            psFree(hdu);
    247253            return false;
    248254        }
     
    255261            psFree (headName);
    256262            psFree (tableName);
     263            psFree(hdu);
    257264            return false;
    258265        }
     
    278285        psFree (headName);
    279286    }
     287    psFree(hdu);
    280288
    281289    // select the psf of interest
     
    481489
    482490// if this file needs to have a PHU written out, write one
    483 bool pmPSFmodelWritePHU (const pmFPAview *view, pmFPAfile *file, const pmConfig *config)
     491bool pmPSFmodelWritePHU (const pmFPAview *view, pmFPAfile *file, pmConfig *config)
    484492{
    485493    PS_ASSERT_PTR_NON_NULL(view, false);
     
    496504    if (file->fpa->chips->n == 1) return true;
    497505
     506
    498507    // find the FPA phu
    499     pmHDU *phu = pmFPAviewThisPHU (view, file->fpa);
     508    pmFPA *fpa = pmFPAfileSuitableFPA(file, view, config, false); // Suitable FPA for writing
     509    pmHDU *phu = psMemIncrRefCounter(pmFPAviewThisPHU(view, fpa));
     510    psFree(fpa);
    500511
    501512    // if there is no PHU, this is a single header+image (extension-less) file. This could be
     
    508519        pmConfigConformHeader (outhead, file->format);
    509520    }
     521    psFree(phu);
    510522
    511523    psMetadataAddBool (outhead, PS_LIST_TAIL, "EXTEND", PS_META_REPLACE, "this file has extensions", true);
  • trunk/psModules/src/objects/pmPSF_IO.h

    r15000 r18601  
    66 * @author EAM, IfA
    77 *
    8  * @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
    9  * @date $Date: 2007-09-24 21:27:58 $
     8 * @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
     9 * @date $Date: 2008-07-17 22:38:15 $
    1010 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii
    1111 */
     
    1717/// @{
    1818
    19 bool pmPSFmodelWriteForView (const pmFPAview *view, pmFPAfile *file, const pmConfig *config);
    20 bool pmPSFmodelWriteFPA (pmFPA *fpa, const pmFPAview *view, pmFPAfile *file, const pmConfig *config);
    21 bool pmPSFmodelWriteChip (pmChip *chip, const pmFPAview *view, pmFPAfile *file, const pmConfig *config);
    22 bool pmPSFmodelWrite (psMetadata *analysis, const pmFPAview *view, pmFPAfile *file, const pmConfig *config);
     19bool pmPSFmodelWriteForView (const pmFPAview *view, pmFPAfile *file, pmConfig *config);
     20bool pmPSFmodelWriteFPA (pmFPA *fpa, const pmFPAview *view, pmFPAfile *file, pmConfig *config);
     21bool pmPSFmodelWriteChip (pmChip *chip, const pmFPAview *view, pmFPAfile *file, pmConfig *config);
     22bool pmPSFmodelWrite (psMetadata *analysis, const pmFPAview *view, pmFPAfile *file, pmConfig *config);
    2323
    24 bool pmPSFmodelWritePHU (const pmFPAview *view, pmFPAfile *file, const pmConfig *config);
     24bool pmPSFmodelWritePHU (const pmFPAview *view, pmFPAfile *file, pmConfig *config);
    2525
    2626bool pmPSFmodelReadForView (const pmFPAview *view, pmFPAfile *file, const pmConfig *config);
  • trunk/psModules/src/objects/pmSourceIO.c

    r18599 r18601  
    33 *  @author EAM, IfA
    44 *
    5  *  @version $Revision: 1.62 $ $Name: not supported by cvs2svn $
    6  *  @date $Date: 2008-07-17 20:43:23 $
     5 *  @version $Revision: 1.63 $ $Name: not supported by cvs2svn $
     6 *  @date $Date: 2008-07-17 22:38:15 $
    77 *
    88 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    2828#include "pmFPAview.h"
    2929#include "pmFPAfile.h"
     30#include "pmFPAfileFitsIO.h"
    3031#include "pmConcepts.h"
    3132
     
    108109
    109110// Given a FITS file pointer, write the table of object data
    110 bool pmFPAviewWriteObjects (const pmFPAview *view, pmFPAfile *file, const pmConfig *config)
     111bool pmFPAviewWriteObjects (const pmFPAview *view, pmFPAfile *file, pmConfig *config)
    111112{
    112113    PS_ASSERT_PTR_NON_NULL(view, false);
     
    114115    PS_ASSERT_PTR_NON_NULL(file->fpa, false);
    115116
    116     pmFPA *fpa = file->fpa;
     117    pmFPA *fpa = pmFPAfileSuitableFPA(file, view, config, false); // Suitable FPA for writing
    117118
    118119    if (view->chip == -1) {
    119120        if (!pmFPAWriteObjects (fpa, view, file, config)) {
    120121            psError(PS_ERR_IO, false, "Failed to write objects from fpa");
    121             return false;
    122         }
     122            psFree(fpa);
     123            return false;
     124        }
     125        psFree(fpa);
    123126        return true;
    124127    }
     
    126129    if (view->chip >= fpa->chips->n) {
    127130        psError(PS_ERR_UNKNOWN, false, "Writing chip == %d (>= chips->n == %ld)", view->chip, fpa->chips->n);
     131        psFree(fpa);
    128132        return false;
    129133    }
     
    133137        if (!pmChipWriteObjects (chip, view, file, config)) {
    134138            psError(PS_ERR_IO, false, "Failed to write objects from chip");
    135             return false;
    136         }
     139            psFree(fpa);
     140            return false;
     141        }
     142        psFree(fpa);
    137143        return true;
    138144    }
     
    141147        psError(PS_ERR_UNKNOWN, false, "Writing cell == %d (>= cells->n == %ld)",
    142148                view->cell, chip->cells->n);
     149        psFree(fpa);
    143150        return false;
    144151    }
     
    148155        if (!pmCellWriteObjects (cell, view, file, config)) {
    149156            psError(PS_ERR_IO, false, "Failed to write objects from cell");
    150             return false;
    151         }
    152 
     157            psFree(fpa);
     158            return false;
     159        }
     160        psFree(fpa);
    153161        return true;
    154162    }
     
    157165        psError(PS_ERR_UNKNOWN, false, "Writing readout == %d (>= readouts->n == %ld)",
    158166                view->readout, cell->readouts->n);
     167        psFree(fpa);
    159168        return false;
    160169    }
     
    163172    if (!pmReadoutWriteObjects (readout, view, file, config)) {
    164173        psError(PS_ERR_IO, false, "Failed to write objects from readout %d", view->readout);
    165         return false;
    166     }
    167 
     174        psFree(fpa);
     175        return false;
     176    }
     177
     178    psFree(fpa);
    168179    return true;
    169180}
     
    244255    PS_ASSERT_PTR_NON_NULL(view, false);
    245256    PS_ASSERT_PTR_NON_NULL(file, false);
    246     PS_ASSERT_PTR_NON_NULL(file->fpa, false);
     257
     258    pmCell *cell = readout->parent;
     259    PS_ASSERT_PTR_NON_NULL(cell, false);
     260    pmChip *chip = cell->parent;
     261    PS_ASSERT_PTR_NON_NULL(chip, false);
     262    pmFPA *fpa = chip->parent;
     263    PS_ASSERT_PTR_NON_NULL(fpa, false);
    247264
    248265    bool status;
     
    281298      case PM_FPA_FILE_CMP:
    282299        // a SPLIT format : only one header and object table per file
    283         hdu = pmFPAviewThisHDU (view, file->fpa);
     300        hdu = pmFPAviewThisHDU (view, fpa);
    284301        if (!hdu) {
    285302            psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find HDU to write sources.");
     
    317334
    318335        // get the current header
    319         hdu = pmFPAviewThisHDU (view, file->fpa);
     336        hdu = pmFPAviewThisHDU (view, fpa);
    320337        if (!hdu) {
    321338            psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find HDU to write sources.");
     
    486503
    487504// if this file needs to have a PHU written out, write one
    488 bool pmSource_CMF_WritePHU (const pmFPAview *view, pmFPAfile *file, const pmConfig *config)
     505bool pmSource_CMF_WritePHU (const pmFPAview *view, pmFPAfile *file, pmConfig *config)
    489506{
    490507    PS_ASSERT_PTR_NON_NULL(view, false);
     
    503520    if (file->fpa->chips->n == 1) return true;
    504521
     522
    505523    // find the FPA phu
    506     pmHDU *phu = pmFPAviewThisPHU (view, file->fpa);
     524    pmFPA *fpa = pmFPAfileSuitableFPA(file, view, config, false); // Suitable FPA for writing
     525    pmHDU *phu = psMemIncrRefCounter(pmFPAviewThisPHU(view, fpa));
    507526
    508527    // if there is no PHU, this is a single header+image (extension-less) file. This could be
     
    513532        psMetadataCopy (outhead, phu->header);
    514533    }
     534    psFree(phu);
    515535
    516536    pmConfigConformHeader (outhead, file->format);
     
    521541    // XXX why are these not correctly inserted by pmConfigConformHeader??
    522542
    523     psMetadata *headers = psMetadataLookupMetadata(NULL, file->fpa->camera, BLANK_HEADERS); // Header names
     543    // Because these concepts are not part of the "RULE" in the camera format, pmConfigConformHeader only adds
     544    // what is required by the "RULE".
     545    // Though we can configure Ohana to look at particular header keywords, it doesn't like having the
     546    // important values in "HIERARCH FPA.TIME", etc, as is done for skycells, so we stoop to its level,
     547    // putting in additional header keywords that it can understand.
     548
     549    psMetadata *headers = psMetadataLookupMetadata(NULL, fpa->camera, BLANK_HEADERS); // Header names
    524550    if (!headers) {
    525551        psError(PS_ERR_UNEXPECTED_NULL, false,
    526552                "Unable to find %s metadata within camera configuration", BLANK_HEADERS);
    527553        psFree(outhead);
     554        psFree(fpa);
    528555        return false;
    529556    }
     
    535562                    "Unable to find FPA.TIME in %s within camera configuration.", BLANK_HEADERS);
    536563            psFree(outhead);
    537             return false;
    538         }
    539         psTime *time = psMetadataLookupTime(NULL, file->fpa->concepts, "FPA.TIME"); // Time of observation
     564            psFree(fpa);
     565            return false;
     566        }
     567        psTime *time = psMetadataLookupTime(NULL, fpa->concepts, "FPA.TIME"); // Time of observation
    540568        double mjd = psTimeToMJD(time); // The MJD of observation
    541569        psMetadataAddF64(outhead, PS_LIST_TAIL, mjdName, PS_META_REPLACE,
     
    550578                    BLANK_HEADERS);
    551579            psFree(outhead);
    552             return false;
    553         }
    554         float exptime = psMetadataLookupF32(NULL, file->fpa->concepts,
    555                                             "FPA.EXPOSURE"); // Exposure time
     580            psFree(fpa);
     581            return false;
     582        }
     583        float exptime = psMetadataLookupF32(NULL, fpa->concepts, "FPA.EXPOSURE"); // Exposure time
    556584        psMetadataAddF32(outhead, PS_LIST_TAIL, expName, PS_META_REPLACE,
    557585                         "Exposure time (sec)", exptime);
     
    565593                    BLANK_HEADERS);
    566594            psFree(outhead);
    567             return false;
    568         }
    569         float airmass = psMetadataLookupF32(NULL, file->fpa->concepts, "FPA.AIRMASS"); // Airmass
     595            psFree(fpa);
     596            return false;
     597        }
     598        float airmass = psMetadataLookupF32(NULL, fpa->concepts, "FPA.AIRMASS"); // Airmass
    570599        psMetadataAddF32(outhead, PS_LIST_TAIL, amName, PS_META_REPLACE,
    571600                         "Observation airmass", airmass);
     
    575604    const char *fpaNameHdr = psMetadataLookupStr(NULL, fileData, "FPA.OBS");
    576605    if (fpaNameHdr && strlen(fpaNameHdr) > 0) {
    577         const char *fpaName = psMetadataLookupStr(NULL, file->fpa->concepts, "FPA.OBS");
     606        const char *fpaName = psMetadataLookupStr(NULL, fpa->concepts, "FPA.OBS");
    578607        psMetadataAddStr(outhead, PS_LIST_TAIL, fpaNameHdr, PS_META_REPLACE,
    579608                         "FPA observation identifier", fpaName);
     
    581610
    582611    // if we have mosaic-level astrometry information, add it here:
    583     psMetadata *updates = psMetadataLookupPtr (&status, file->fpa->analysis, "PSASTRO.HEADER");
     612    psMetadata *updates = psMetadataLookupPtr (&status, fpa->analysis, "PSASTRO.HEADER");
    584613    if (updates) {
    585614        psMetadataCopy (outhead, updates);
    586615    }
     616    psFree(fpa);
    587617
    588618    psMetadataAddBool (outhead, PS_LIST_TAIL, "EXTEND", PS_META_REPLACE, "this file has extensions", true);
  • trunk/psModules/src/objects/pmSourceIO.h

    r17850 r18601  
    44 * @author EAM, IfA; GLG, MHPCC
    55 *
    6  * @version $Revision: 1.17 $ $Name: not supported by cvs2svn $
    7  * @date $Date: 2008-05-29 13:25:38 $
     6 * @version $Revision: 1.18 $ $Name: not supported by cvs2svn $
     7 * @date $Date: 2008-07-17 22:38:15 $
    88 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii
    99 *
     
    3030bool pmSourcesWrite_PS1_DEV_1_XFIT (psFits *fits, psArray *sources, char *extname);
    3131
    32 bool pmSource_CMF_WritePHU (const pmFPAview *view, pmFPAfile *file, const pmConfig *config);
     32bool pmSource_CMF_WritePHU (const pmFPAview *view, pmFPAfile *file, pmConfig *config);
    3333
    3434psArray *pmSourcesReadCMP (char *filename, psMetadata *header);
     
    5050bool pmReadoutReadObjects (pmReadout *readout, const pmFPAview *view, pmFPAfile *file, const pmConfig *config);
    5151
    52 bool pmFPAviewWriteObjects (const pmFPAview *view, pmFPAfile *file, const pmConfig *config);
     52bool pmFPAviewWriteObjects (const pmFPAview *view, pmFPAfile *file, pmConfig *config);
    5353bool pmFPAWriteObjects (pmFPA *fpa, const pmFPAview *view, pmFPAfile *file, const pmConfig *config);
    5454bool pmChipWriteObjects (pmChip *chip, const pmFPAview *view, pmFPAfile *file, const pmConfig *config);
Note: See TracChangeset for help on using the changeset viewer.