IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

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.

File:
1 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
Note: See TracChangeset for help on using the changeset viewer.