IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 6804


Ignore:
Timestamp:
Apr 5, 2006, 2:28:28 PM (20 years ago)
Author:
Paul Price
Message:

Reworking pmFPAAddSource for better code maintainance, and to implement PHU=FPA,EXT=NONE

Location:
branches/rel10_ifa/psModules/src/astrom
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • branches/rel10_ifa/psModules/src/astrom/pmConcepts.c

    r6744 r6804  
    398398        {
    399399            psMetadataItem *cellReaddir = psMetadataItemAllocS32("CELL.READDIR",
    400                                           "Read direction, rows=1, cols=2", 1);
     400                                          "Read direction, rows=1, cols=2", 0);
    401401            pmConceptRegister(cellReaddir, NULL, NULL, PM_CONCEPT_LEVEL_CELL);
    402402            psFree(cellReaddir);
  • branches/rel10_ifa/psModules/src/astrom/pmConceptsRead.c

    r6739 r6804  
    66#include "pmFPA.h"
    77#include "pmHDU.h"
    8 #include "pmHDUGetLowest.h"
     8#include "pmHDUUtils.h"
    99#include "pmConcepts.h"
    1010#include "pmConceptsRead.h"
  • branches/rel10_ifa/psModules/src/astrom/pmConceptsWrite.c

    r6745 r6804  
    55#include "pmFPA.h"
    66#include "pmHDU.h"
    7 #include "pmHDUGetLowest.h"
     7#include "pmHDUUtils.h"
    88#include "pmConcepts.h"
    99#include "pmConceptsRead.h"
     
    3131        switch (item2->type) {
    3232        case PS_TYPE_S32:
     33            psTrace(__func__, 10, "Comparing %d and %d...\n", item1->data.S32, item2->data.S32);
    3334            return (item1->data.S32 == item2->data.S32) ? true : false;
    3435        case PS_TYPE_F32:
     36            psTrace(__func__, 10, "Comparing %d and %d...\n", item1->data.S32, (int)item2->data.F32);
    3537            return (item1->data.S32 == (int)item2->data.F32) ? true : false;
    3638        case PS_TYPE_F64:
     39            psTrace(__func__, 10, "Comparing %d and %d...\n", item1->data.S32, (int)item2->data.F64);
    3740            return (item1->data.S32 == (int)item2->data.F64) ? true : false;
    3841        default:
     
    4245        switch (item2->type) {
    4346        case PS_TYPE_S32:
     47            psTrace(__func__, 10, "Comparing %f and %f...\n", item1->data.F32, (float)item2->data.S32);
    4448            return (item1->data.F32 == (float)item2->data.S32) ? true : false;
    4549        case PS_TYPE_F32:
     50            psTrace(__func__, 10, "Comparing %f and %f...\n", item1->data.F32, item2->data.F32);
    4651            return (item1->data.F32 == item2->data.F32) ? true : false;
    4752        case PS_TYPE_F64:
     53            psTrace(__func__, 10, "Comparing %f and %f...\n", item1->data.F32, (float)item2->data.F64);
    4854            return (item1->data.F32 == (float)item2->data.F64) ? true : false;
    4955        default:
     
    5359        switch (item2->type) {
    5460        case PS_TYPE_S32:
     61            psTrace(__func__, 10, "Comparing %f and %f...\n", item1->data.F32, (double)item2->data.S32);
    5562            return (item1->data.F64 == (double)item2->data.S32) ? true : false;
    5663        case PS_TYPE_F32:
     64            psTrace(__func__, 10, "Comparing %f and %f...\n", item1->data.F32, (double)item2->data.F32);
    5765            return (item1->data.F64 == (double)item2->data.F32) ? true : false;
    5866        case PS_TYPE_F64:
     67            psTrace(__func__, 10, "Comparing %f and %f...\n", item1->data.F32, item2->data.F64);
    5968            return (item1->data.F64 == item2->data.F64) ? true : false;
    6069        default:
     
    6675            return false;
    6776        }
     77        psTrace(__func__, 10, "Comparing '%s' and '%s'\n", item1->data.V, item2->data.V);
    6878        return (strcasecmp(item1->data.V, item2->data.V) == 0) ? true : false;
    6979    default:
     
    230240}
    231241
    232 // XXX: Needs the .DEPEND stuff
    233242bool pmConceptsWriteToDefaults(psMetadata *specs, // The concept specifications
    234243                               pmFPA *fpa, // The FPA
     
    283292                if (! compareConcepts(defaultItem, formatted)) {
    284293                    psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by the DEFAULTS in the camera "
    285                              "format, but the values don't match.\n");
     294                             "format, but the values don't match.\n", name);
    286295                }
    287296                psFree(formatted);
  • branches/rel10_ifa/psModules/src/astrom/pmFPA.h

    r6713 r6804  
    77*  @author GLG, MHPCC
    88*
    9 *  @version $Revision: 1.1.4.5 $ $Name: not supported by cvs2svn $
    10 *  @date $Date: 2006-03-28 02:16:26 $
     9*  @version $Revision: 1.1.4.6 $ $Name: not supported by cvs2svn $
     10*  @date $Date: 2006-04-06 00:28:28 $
    1111*
    1212*  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     
    222222bool pmCellSetDataStatus (pmCell *cell, bool status);
    223223
    224 /** FUNC DESC
    225  *
    226  *
    227  *
    228  *
    229  */
    230 
     224/** Specify the level for an operation.
     225 */
     226typedef enum {
     227    PM_FPA_LEVEL_NONE,                  ///< No particular level specified
     228    PM_FPA_LEVEL_FPA,                   ///< Level corresponds to an FPA
     229    PM_FPA_LEVEL_CHIP,                  ///< Level corresponds to a Chip
     230    PM_FPA_LEVEL_CELL,                  ///< Level corresponds to a Cell
     231    PM_FPA_LEVEL_READOUT                ///< Level corresponds to a Readout
     232} pmFPALevel;
    231233
    232234
  • branches/rel10_ifa/psModules/src/astrom/pmFPAConstruct.c

    r6752 r6804  
    3535}
    3636
    37 // Parse a list of first:second pairs in a string
    38 static bool parsePairs(psArray **first, // Array of the first values
    39                        psArray **second, // Array of the second values
    40                        const char *string // The string to parse
    41                       )
     37// Parse a list of first:second:third pairs in a string
     38static bool parseContent(psArray **first, // Array of the first values
     39                         psArray **second, // Array of the second values
     40                         psArray **third, // Array of the third values
     41                         const char *string // The string to parse
     42                        )
    4243{
    4344    bool allOK = true;                  // Everything was OK?
    44     psList *pairs = psStringSplit(string, " ,;"); // List of the pairs
    45     *first = psArrayAlloc(pairs->n);
    46     *second = psArrayAlloc(pairs->n);
     45    psList *values = psStringSplit(string, " ,;"); // List of the parts
     46    *first = psArrayAlloc(values->n);
     47    *second = psArrayAlloc(values->n);
     48    *third = psArrayAlloc(values->n);
    4749    int num = 0;
    48     psListIterator *pairsIter = psListIteratorAlloc(pairs, PS_LIST_HEAD, false); // Iterator for pairs
    49     psString pair = NULL;               // "first:second" pair string
    50     while ((pair = psListGetAndIncrement(pairsIter))) {
    51         psList *firstSecond = psStringSplit(pair, ":"); // List containing the first and second
    52         if (firstSecond->n != 2) {
    53             psLogMsg(__func__, PS_LOG_WARN, "Badly formated first:second pair: %s --- ignored.\n", pair);
     50    psListIterator *valuesIter = psListIteratorAlloc(values, PS_LIST_HEAD, false); // Iterator for values
     51    psString value = NULL;               // "first:second:third" string
     52    while ((value = psListGetAndIncrement(valuesIter))) {
     53        psList *firstSecondThird = psStringSplit(value, ":"); // List containing the first, second, third
     54        psArray *fst = psListToArray(firstSecondThird); // An array representation
     55        psFree(firstSecondThird);
     56        psString firstPart = NULL;      // The first part
     57        psString secondPart = NULL;     // The second part
     58        psString thirdPart = NULL;      // The third part
     59        switch (firstSecondThird->n) {
     60        case 1:
     61            thirdPart = fst->data[0];
     62            break;
     63        case 2:
     64            secondPart = fst->data[0];
     65            thirdPart = fst->data[1];
     66            break;
     67        case 3:
     68            firstPart = fst->data[0];
     69            secondPart = fst->data[1];
     70            thirdPart = fst->data[2];
     71            break;
     72        default:
     73            psLogMsg(__func__, PS_LOG_WARN, "Badly formated specifier: %s --- ignored.\n", value);
    5474            allOK = false;
     75            psFree(fst);
    5576            continue;
    5677        }
    57         psString firstBit = psListGet(firstSecond, PS_LIST_HEAD); // The first bit
    58         psString secondBit = psListGet(firstSecond, PS_LIST_TAIL); // The second bit
    59         psArraySet(*first, num, firstBit);
    60         psArraySet(*second, num, secondBit);
     78        psArraySet(*first, num, firstPart);
     79        psArraySet(*second, num, secondPart);
     80        psArraySet(*third, num, thirdPart);
    6181        num++;
    62         psFree(firstSecond);
    63     }
    64     psFree(pairsIter);
    65     psFree(pairs);
     82        psFree(fst);
     83    }
     84    psFree(valuesIter);
     85    psFree(values);
    6686
    6787    return allOK;
     
    7797    psString keyword = psMetadataLookupStr(&mdok, format, name);
    7898    if (!mdok || strlen(keyword) == 0) {
    79         psError(PS_ERR_IO, false, "Unable to find %s in the FILE.\n", name);
    8099        return false;
    81100    }
     
    86105    }
    87106    return psMetadataItemParseString(resultItem);
     107}
     108
     109// Add an HDU to the FPA
     110static bool addHDUtoFPA(pmFPA *fpa,     // FPA to which to add
     111                        pmHDU *hdu      // HDU to be added
     112                       )
     113{
     114    assert(fpa);
     115    assert(hdu);
     116
     117    if (fpa->hdu) {
     118        // Something's already here
     119        if (fpa->hdu != hdu) {
     120            psError(PS_ERR_IO, true, "Unable to add HDU since FPA already has one.\n");
     121        }
     122        return false;
     123    }
     124    fpa->hdu = psMemIncrRefCounter(hdu);
     125    if (hdu->header) {
     126        pmConceptsReadFPA(fpa, PM_CONCEPT_SOURCE_HEADER, NULL);
     127    }
     128    pmFPASetFileStatus(fpa, true);
     129
     130    return true;
     131}
     132
     133// Add an HDU to the chip
     134static bool addHDUtoChip(pmChip *chip,  // Chip to which to add
     135                         pmHDU *hdu     // HDU to be added
     136                        )
     137{
     138    assert(chip);
     139    assert(hdu);
     140
     141    if (chip->hdu) {
     142        // Something's already here
     143        if (chip->hdu != hdu) {
     144            psError(PS_ERR_IO, true, "Unable to add HDU since chip already has one.\n");
     145        }
     146        return false;
     147    }
     148    chip->hdu = psMemIncrRefCounter(hdu);
     149    if (hdu->header) {
     150        pmConceptsReadChip(chip, PM_CONCEPT_SOURCE_HEADER, true, NULL);
     151    }
     152    pmChipSetFileStatus(chip, true);
     153
     154    return true;
     155}
     156
     157// Add an HDU to the cell
     158static bool addHDUtoCell(pmCell *cell,  // Cell to which to add
     159                         pmHDU *hdu     // HDU to be added
     160                        )
     161{
     162    assert(cell);
     163    assert(hdu);
     164
     165    if (cell->hdu) {
     166        // Something's already here
     167        if (cell->hdu != hdu) {
     168            psError(PS_ERR_IO, true, "Unable to add HDU since cell already has one.\n");
     169        }
     170        return false;
     171    }
     172    cell->hdu = psMemIncrRefCounter(hdu);
     173    if (hdu->header) {
     174        pmConceptsReadCell(cell, PM_CONCEPT_SOURCE_HEADER, true, NULL);
     175    }
     176    pmCellSetFileStatus(cell, true);
     177
     178    return true;
     179}
     180
     181
     182// Looks up the particular content based on the header
     183static const char *getContent(psMetadata *format, // The FORMAT from the camera format configuration
     184                              psMetadata *contents, // The CONTENTS from the camera format configuration
     185                              psMetadata *header // The (primary) header
     186                             )
     187{
     188    bool mdok = true;                   // Status of MD lookup
     189    const char *contentHeaders = psMetadataLookupStr(&mdok, format, "CONTENT"); // Headers for content
     190    if (!mdok || !contentHeaders || strlen(contentHeaders) == 0) {
     191        psError(PS_ERR_IO, true, "Unable to find CONTENT in FORMAT.\n");
     192        return NULL;
     193    }
     194
     195    psList *keywords = psStringSplit(contentHeaders, " ,;"); // List of keywords
     196    psListIterator *keywordsIter = psListIteratorAlloc(keywords, PS_LIST_HEAD, false); // Iterator
     197    psString keyword = NULL;        // Keyword, from iteration
     198    psString contentsKey = NULL;    // Key to the CONTENTS menu
     199    bool first = true;              // Is it the first value?
     200    while ((keyword = psListGetAndIncrement(keywordsIter))) {
     201        const char *value = psMetadataLookupStr(&mdok, header, keyword);
     202        if (first) {
     203            psStringAppend(&contentsKey, "%s", value);
     204            first = false;
     205        } else {
     206            psStringAppend(&contentsKey, "_%s", value);
     207        }
     208    }
     209    psTrace(__func__, 5, "Looking up %s in the CONTENTS.\n", contentsKey);
     210    const char *content = psMetadataLookupStr(&mdok, contents, contentsKey);
     211    if (!mdok || !content || strlen(content) == 0) {
     212        psError(PS_ERR_IO, true, "Unable to find %s in the CONTENTS.\n", contentsKey);
     213        return NULL;
     214    }
     215    psFree(contentsKey);
     216
     217    return content;
     218}
     219
     220
     221// Given a (string) list of contents "chip:cell:type chip:cell:type", put the HDU in the correct place and
     222// plug in the cell configuration information
     223static int processContents(pmFPA *fpa,  // The FPA
     224                           pmChip *chip, // The chip, or NULL
     225                           pmCell *cell, // The cell, or NULL
     226                           pmHDU *hdu,  // The HDU to be added
     227                           pmFPALevel level, // The level at which to add the HDU
     228                           const char *contents, // The contents line, consisting of a list of chip:cell
     229                           psMetadata *format // Camera format configuration
     230                          )
     231{
     232    assert(fpa);
     233    assert(contents && strlen(contents) > 0);
     234    assert(!cell || (cell && chip));    // Need both chip and cell if given a cell
     235
     236    if (hdu && level == PM_FPA_LEVEL_FPA) {
     237        addHDUtoFPA(fpa, hdu);
     238    }
     239
     240    // Parse the list of chip:cell:type
     241    psArray *chips = NULL;              // The chips (first bits)
     242    psArray *cells = NULL;              // The cells (second bits)
     243    psArray *types = NULL;              // The cell types (third bits)
     244    int numCells = 0;                   // Number of cells processed
     245    parseContent(&chips, &cells, &types, contents);
     246    for (int i = 0; i < types->n; i++) {
     247        psString chipName = chips->data[i]; // The name of the chip
     248        psString cellName = cells->data[i]; // The name of the cell
     249        psString cellType = types->data[i]; // The type of the cell
     250
     251        // Get the chip
     252        pmChip *newChip = NULL;         // The chip specified
     253        if (chip) {
     254            newChip = chip;
     255        } else if (chipName) {
     256            // Find the chip
     257            int chipNum = pmFPAFindChip(fpa, chipName); // The chip we're looking for
     258            if (chipNum == -1) {
     259                psLogMsg(__func__, PS_LOG_WARN, "Unable to find chip %s in fpa --- ignored.\n", chipName);
     260                continue;
     261            }
     262            newChip = fpa->chips->data[chipNum];
     263        }
     264
     265        if (!newChip) {
     266            psLogMsg(__func__, PS_LOG_WARN, "Unable to determine chip for entry %d of content (follows) --- "
     267                     "ignored.\n\t%s", i, contents);
     268            continue;
     269        }
     270
     271        // Get the cell
     272        pmCell *newCell = NULL;         // The cell specified
     273        if (cell) {
     274            newCell = cell;
     275        } else if (cellName) {
     276            // Find the cell
     277            int cellNum = pmChipFindCell(newChip, cellName); // The cell we're looking for
     278            if (cellNum == -1) {
     279                psLogMsg(__func__, PS_LOG_WARN, "Unable to find cell %s in chip %s --- ignored.\n",
     280                         cellName, chipName);
     281                continue;
     282            }
     283            newCell = newChip->cells->data[cellNum];
     284        }
     285        if (!newCell) {
     286            psLogMsg(__func__, PS_LOG_WARN, "Unable to determine cell for entry %d of content (follows) --- "
     287                     "ignored.\n\t%s", i, contents);
     288            continue;
     289        }
     290
     291        // Get the type
     292        if (!cellType) {
     293            psLogMsg(__func__, PS_LOG_WARN, "Unable to determine cell type for entry %d of content (follows) "
     294                     "--- ignored.\n\t%s", i, contents);
     295            continue;
     296        }
     297        psMetadata *cellData = getCellData(format, cellType); // Data for this cell
     298
     299        // Put in the HDU
     300        if (hdu && level == PM_FPA_LEVEL_CHIP) {
     301            addHDUtoChip(newChip, hdu);
     302        }
     303        if (hdu && level == PM_FPA_LEVEL_CELL) {
     304            addHDUtoCell(newCell, hdu);
     305        }
     306
     307        // Put in the cell data
     308        if (newCell->config) {
     309            psLogMsg(__func__, PS_LOG_WARN, "Overwriting cell data in chip %s, cell %s\n", chipName,
     310                     cellName);
     311            psFree(newCell->config); // Make way!
     312        }
     313        newCell->config = psMemIncrRefCounter(cellData);
     314        pmConceptsReadCell(newCell, PM_CONCEPT_SOURCE_CAMERA | PM_CONCEPT_SOURCE_DEFAULTS, false, NULL);
     315        numCells++;
     316    }
     317    psFree(chips);
     318    psFree(cells);
     319    psFree(types);
     320
     321    return numCells;
    88322}
    89323
     
    137371    assert(format);
    138372
    139     pmChip *chip = NULL;                // The chip, if any one in particular
    140     pmCell *cell = NULL;                // The cell, if any one in particular
    141     psString phuChipName = NULL;        // Name of the chip from the PHU
    142 
    143373    bool mdok = true;                   // Status from metadata lookups
    144374    psMetadata *formatSpec = psMetadataLookupMD(&mdok, format, "FILE"); // The format specification
     
    149379
    150380    // Check the name of the FPA
    151     const char *nameKeyword = psMetadataLookupStr(&mdok, formatSpec, "FPA.NAME"); // Keyword that gives name
    152     if (!mdok || strlen(nameKeyword) == 0) {
    153         psError(PS_ERR_IO, false, "Unable to find FPA.NAME in the format specification.\n");
    154         return NULL;
    155     }
    156     psMetadataItem *fpaNameItem = psMetadataLookup(phu, nameKeyword); // Name of the FPA
    157     if (!fpaNameItem) {
    158         psError(PS_ERR_IO, false, "Unable to find keyword %s with the name of the FPA.\n", nameKeyword);
    159         return NULL;
    160     }
    161     const char *newFPAname = psMetadataItemParseString(fpaNameItem); // FPA.NAME for new source
    162     fpaNameItem = psMetadataLookup(fpa->concepts, "FPA.NAME"); // Current name of FPA
    163     if (fpaNameItem && fpaNameItem->type == PS_DATA_STRING) {
    164         const char *currentFPAname = fpaNameItem->data.V; // Name of the current FPA
    165         if (currentFPAname && strlen(currentFPAname) > 0 && strcmp(currentFPAname, newFPAname) != 0) {
    166             psLogMsg(__func__, PS_LOG_WARN, "FPA.NAME for new source (%s) doesn't match FPA.NAME for current "
    167                      "fpa (%s).\n", newFPAname, currentFPAname);
    168         }
     381    psString newFPAname = phuNameFromHeader("FPA.NAME", formatSpec, phu); // New name for the FPA
     382    const char *currentFPAname = psMetadataLookupStr(&mdok, fpa->concepts, "FPA.NAME"); // Current name
     383    if (mdok && currentFPAname && strlen(currentFPAname) > 0 && strcmp(currentFPAname, newFPAname) != 0) {
     384        psLogMsg(__func__, PS_LOG_WARN, "FPA.NAME for new source (%s) doesn't match FPA.NAME for current "
     385                 "fpa (%s).\n", newFPAname, currentFPAname);
    169386    }
    170387    psMetadataAddStr(fpa->concepts, PS_LIST_HEAD, "FPA.NAME", PS_META_REPLACE, "Name of FPA", newFPAname);
     
    180397    phdu->header = psMemIncrRefCounter(phu);
    181398    phdu->format = psMemIncrRefCounter(format);
    182 
    183399    // Generate the view
    184400    pmFPAview *view = pmFPAviewAlloc(0); // The FPA view corresponding to the PHU, to be returned
     
    186402    view->cell = -1;
    187403    view->readout = -1;
    188     if (strcasecmp(phuType, "FPA") == 0) {
    189         if (fpa->hdu) {
    190             // Something's already here
    191             psError(PS_ERR_IO, true, "Unable to add source since FPA already has a PHU.\n");
     404
     405    // And what are the individual extensions?
     406    const char *extType = psMetadataLookupStr(&mdok, formatSpec, "EXTENSIONS"); // What's in the extns?
     407    if (!mdok || strlen(extType) == 0) {
     408        psError(PS_ERR_IO, false, "Unable to find EXTENSIONS in the format specification.\n");
     409        psFree(view);
     410        return NULL;
     411    }
     412
     413
     414    // This is a special case: PHU=FPA and EXTENSIONS=NONE.  The only reason to do this is in the case of
     415    // single CCD imagers, where the entire FPA is in the PHU image.  In this case, the CONTENTS is of type
     416    // STR (rather than METADATA), and has the usual chip:cell.
     417    if (strcasecmp(phuType, "FPA") == 0 && strcasecmp(extType, "NONE") == 0) {
     418        const char *contents = psMetadataLookupStr(&mdok, format, "CONTENTS"); // The contents of the file
     419        if (!mdok || !contents || strlen(contents) == 0) {
     420            psError(PS_ERR_IO, true, "Unable to find CONTENTS in the camera format configuration.\n");
    192421            psFree(view);
    193422            return NULL;
    194423        }
    195         fpa->hdu = phdu;
    196         pmConceptsReadFPA(fpa, PM_CONCEPT_SOURCE_HEADER, NULL);
    197         pmFPASetFileStatus (fpa, true);
     424
     425        processContents(fpa, NULL, NULL, phdu, PM_FPA_LEVEL_FPA, contents, format);
     426        psFree(phdu);
     427        return view;
     428    }
     429
     430    // In all other cases, the CONTENTS is of type METADATA, and is either a menu if EXTENSIONS=NONE, or
     431    // a list of extensions otherwise.
     432    psMetadata *contents = psMetadataLookupMD(&mdok, format, "CONTENTS"); // The contents of the FITS file
     433    if (!mdok || !contents) {
     434        psError(PS_ERR_IO, false, "Unable to find CONTENTS in the camera format configuration.\n");
     435        psFree(view);
     436        return NULL;
     437    }
     438
     439    // No extensions --- only have the PHU.  In this case, the CONTENTS is a menu, with CONTENT indicating
     440    // header keywords that provides a key to the CONTENTS menu.
     441    if (strcasecmp(extType, "NONE") == 0) {
     442        // We have already dealt with the case PHU=FPA, in a special case, above.
     443        const char *content = getContent(formatSpec, contents, phu); // The content: string of chip:cell pairs
     444
     445        // Need to look up what chip we have.
     446        const char *chipName = phuNameFromHeader("CHIP.NAME", formatSpec, phu);
     447        psTrace(__func__, 5, "This is chip %s\n", chipName);
     448        int chipNum = pmFPAFindChip(fpa, chipName); // Chip number
     449        if (chipNum == -1) {
     450            psError(PS_ERR_IO, true, "Unable to find chip %s in FPA.\n", chipName);
     451            psFree(view);
     452            return NULL;
     453        }
     454        pmChip *chip = fpa->chips->data[chipNum]; // Chip of interest
     455        view->chip = chipNum;
     456
     457        pmCell *cell = NULL;            // Cell of interest
     458
     459        pmFPALevel level = PM_FPA_LEVEL_NONE; // Level for HDU to be added
     460        if (strcasecmp(phuType, "CHIP") == 0) {
     461            level = PM_FPA_LEVEL_CHIP;
     462        } else if (strcasecmp(phuType, "CELL") == 0) {
     463            level = PM_FPA_LEVEL_CELL;
     464            // Need to look up what cell we have.
     465            const char *cellName = phuNameFromHeader("CELL.NAME", formatSpec, phu);
     466            int cellNum = pmChipFindCell(chip, cellName); // Cell number
     467            if (cellNum == -1) {
     468                psError(PS_ERR_IO, true, "Unable to find cell %s in chip %s.\n", cellName, chipName);
     469                psFree(view);
     470                return NULL;
     471            }
     472            cell = chip->cells->data[cellNum];
     473            view->cell = cellNum;
     474        } else {
     475            psError(PS_ERR_IO, true, "PHU is not FPA, CHIP or CELL.\n");
     476            psFree(view);
     477            return NULL;
     478        }
     479
     480        processContents(fpa, chip, cell, phdu, level, content, format);
     481        psFree(phdu);
     482        return view;
     483    }
     484
     485
     486    // From here on, we have extensions that we iterate through.  The CONTENTS is a list of extensions.
     487    pmChip *chip = NULL;                // The chip of interest
     488    pmCell *cell = NULL;                // The cell of interest
     489
     490    // First, put in the PHU
     491    if (strcasecmp(phuType, "FPA") == 0) {
     492        addHDUtoFPA(fpa, phdu);
    198493    } else {
    199494        // Get the chip
    200         phuChipName = phuNameFromHeader("CHIP.NAME", formatSpec, phu); // Name of the chip
    201         int chipNum = pmFPAFindChip(fpa, phuChipName); // Chip number
     495        const char *chipName = phuNameFromHeader("CHIP.NAME", formatSpec, phu); // Name of the chip
     496        int chipNum = pmFPAFindChip(fpa, chipName); // Chip number
    202497        if (chipNum == -1) {
    203             psError(PS_ERR_IO, true, "Unable to find chip %s in FPA.\n", phuChipName);
     498            psError(PS_ERR_IO, true, "Unable to find chip %s in FPA.\n", chipName);
    204499            psFree(view);
    205500            return NULL;
    206501        }
    207         chip = fpa->chips->data[chipNum];
     502        chip = fpa->chips->data[chipNum]; // The specified chip
    208503        view->chip = chipNum;
    209504
    210505        if (strcasecmp(phuType, "CHIP") == 0) {
    211             if (chip->hdu) {
    212                 // Something's already here
    213                 psError(PS_ERR_IO, true, "Unable to add source since chip already has a PHU.\n");
    214                 psFree (view);
    215                 return NULL;
    216             }
    217             chip->hdu = phdu;
    218             pmConceptsReadChip(chip, PM_CONCEPT_SOURCE_HEADER, true, NULL);
    219             pmChipSetFileStatus (chip, true);
     506            addHDUtoChip(chip, phdu);
    220507        } else if (strcasecmp(phuType, "CELL") == 0) {
    221             psError(PS_ERR_IO, true, "Not yet sure how to handle PHU=CELL.\n");
    222             psFree(view);
    223             return NULL;
    224             #if 0
    225             // Added this for possible future plans which might allow PHU=CELL
    226             phuCellName = phuNameFromHeader("CELL.NAME", formatSpec, phu); // Name of the cell
    227             int cellNum = pmChipFindCell(chip, phuCellName); // Cell number
     508            const char *cellName = phuNameFromHeader("CELL.NAME", formatSpec, phu); // Name of the cell
     509            int cellNum = pmChipFindCell(chip, cellName); // Cell number
    228510            if (cellNum == -1) {
    229                 psError(PS_ERR_IO, true, "Unable to find cell %s in chip %s.\n", phuCellName, phuChipName);
     511                psError(PS_ERR_IO, true, "Unable to find cell %s in chip %s.\n", cellName, chipName);
    230512                psFree(view);
    231513                return NULL;
    232514            }
    233             cell = chip->cells->data[cellNum];
     515            cell = chip->cells->data[cellNum]; // The specified cell
    234516            view->cell = cellNum;
    235517
    236             if (cell->hdu) {
    237                 // Something's already here
    238                 psError(PS_ERR_IO, true, "Unable to add source since cell already has a PHU.\n");
    239                 psFree(view);
    240                 return NULL;
    241             }
    242             cell->hdu = phdu;
    243             pmConceptsReadCell(cell, PM_CONCEPT_SOURCE_HEADER, true, NULL);
    244             pmCellSetFileStatus (cell, true);
    245             #endif
    246 
     518            addHDUtoCell(cell, phdu);
    247519        } else {
    248520            psError(PS_ERR_IO, true, "The format of the PHU (%s) is not FPA, CHIP or CELL.\n", phuType);
     
    251523        }
    252524    }
    253 
    254     // And the individual extensions?
    255     const char *extType = psMetadataLookupStr(&mdok, formatSpec, "EXTENSIONS"); // What's in the extns?
    256     if (!mdok || strlen(extType) == 0) {
    257         psError(PS_ERR_IO, false, "Unable to find EXTENSIONS in the format specification.\n");
     525    psFree(phdu);
     526
     527    // Where do we stick in the HDUs?
     528    pmFPALevel hduLevel = PM_FPA_LEVEL_NONE; // Level for HDU insertion
     529    if (strcasecmp(extType, "CHIP") == 0) {
     530        hduLevel = PM_FPA_LEVEL_CHIP;
     531    } else if (strcasecmp(extType, "CELL") == 0) {
     532        hduLevel = PM_FPA_LEVEL_CELL;
     533    } else {
     534        psError(PS_ERR_IO, true, "EXTENSIONS is not CHIP or CELL or NONE.\n");
    258535        psFree(view);
    259536        return NULL;
    260537    }
    261     psMetadata *contents = psMetadataLookupMD(&mdok, format, "CONTENTS"); // The contents of the FITS file
    262     if (!mdok || !contents) {
    263         psError(PS_ERR_IO, false, "Unable to find CONTENTS in the camera format configuration.\n");
    264         psFree(view);
    265         return NULL;
    266     }
    267 
    268 
    269     // Now, different actions, according to what's in the file:
    270 
    271     // No extensions --- it's all in the PHU
    272     if (strcasecmp(extType, "NONE") == 0) {
    273         if (strcasecmp(phuType, "FPA") == 0) {
    274             psError(PS_ERR_IO, true, "Not sure how to handle the case PHU=FPA, EXTENSIONS=NONE.\n");
    275             psFree(view);
    276             return NULL;
    277         }
    278         if (strcasecmp(phuType, "CELL") == 0) {
    279             psError(PS_ERR_IO, true, "Not sure how to handle the case PHU=CELL, EXTENSIONS=NONE.\n");
    280             psFree(view);
    281             return NULL;
    282         }
    283 
    284         psString content = psMetadataLookupStr(&mdok, contents, phuChipName); // The content line
    285         if (!mdok || strlen(content) == 0) {
    286             psError(PS_ERR_IO, true, "Cannot find chip %s in the list of CONTENTS.\n", phuChipName);
    287             psFree(view);
    288             return NULL;
    289         }
    290 
    291         // Parse the list of first:second
    292         psArray *names = NULL;          // The first bits
    293         psArray *values = NULL;         // The second bits
    294         parsePairs(&names, &values, content);
    295         for (int i = 0; i < names->n; i++) {
    296             psString chipName = names->data[i]; // The name of the chip specified
    297             if (phuChipName && strcmp(phuChipName, chipName) != 0) {
    298                 psLogMsg(__func__, PS_LOG_WARN, "Chip name in CONTENT (%s) does not match chip name from PHU "
    299                          "(%s) --- there may be problems when reading!\n", chipName, phuChipName);
    300                 // Find the other chip
    301                 int chipNum = pmFPAFindChip(fpa, chipName); // The chip we're looking for
    302                 if (chipNum == -1) {
    303                     psLogMsg(__func__, PS_LOG_WARN, "Unable to find chip %s in fpa --- ignored.\n", chipName);
    304                     continue;
    305                 }
    306                 chip = fpa->chips->data[chipNum];
    307             }
    308             psString cellName = values->data[i]; // The name of the cell specified
    309             int cellNum = pmChipFindCell(chip, cellName); // The cell we're looking for
    310             if (cellNum == -1) {
    311                 psLogMsg(__func__, PS_LOG_WARN, "Unable to find cell %s in chip %s --- ignored.\n",
    312                          cellName, chipName);
    313                 continue;
    314             }
    315             cell = chip->cells->data[cellNum];
    316 
    317             psMetadata *cellData = getCellData(format, cellName); // Data for this cell
    318 
    319             // Have already plugged in the PHU, which is all we have
    320 
    321             // Put in the cell data
    322             if (cell->config) {
    323                 psLogMsg(__func__, PS_LOG_WARN, "Overwriting cell data in chip %s, cell %s\n", chipName,
    324                          cellName);
    325                 psFree(cell->config); // Make way!
    326             }
    327             cell->config = psMemIncrRefCounter(cellData);
    328             pmConceptsReadCell(cell, PM_CONCEPT_SOURCE_CAMERA | PM_CONCEPT_SOURCE_DEFAULTS, false, NULL);
    329         }
    330 
    331         return view;
    332     }
    333 
    334 
    335     // Otherwise, go through the contents
     538
     539    // Now go through the contents
    336540    psMetadataIterator *contentsIter = psMetadataIteratorAlloc(contents, PS_LIST_HEAD, NULL);
    337541    psMetadataItem *contentsItem = NULL; // Item from contents
     
    346550        hdu->format = psMemIncrRefCounter(format);
    347551
    348         // Parse the list of first:second
    349         psArray *names = NULL;          // The first bits
    350         psArray *values = NULL;         // The second bits
    351         parsePairs(&names, &values, contentsItem->data.V);
    352 
    353         // XXX Memory problems in here --> leaks and/or double frees???
    354         if (strcasecmp(extType, "CHIP") == 0) {
    355             // Extensions are chips
    356             for (int i = 0; i < names->n; i++) {
    357                 psString chipName = names->data[i]; // The name of the chip
    358                 psString cellName = values->data[i]; // The name of the cell
    359                 int chipNum = pmFPAFindChip(fpa, chipName); // The chip we're looking for
    360                 if (chipNum == -1) {
    361                     psLogMsg(__func__, PS_LOG_WARN, "Unable to find chip %s in FPA --- ignored.\n", chipName);
    362                     continue;
    363                 }
    364                 chip = fpa->chips->data[chipNum];
    365                 int cellNum = pmChipFindCell(chip, cellName); // The cell we're looking for
    366                 if (cellNum == -1) {
    367                     psLogMsg(__func__, PS_LOG_WARN, "Unable to find cell %s in chip %s --- ignored\n",
    368                              cellName, chipName);
    369                     continue;
    370                 }
    371                 pmCell *cell = chip->cells->data[cellNum];
    372                 psMetadata *cellData = getCellData(format, cellName); // Data for this cell
    373 
    374                 // Put in the extension
    375                 if (chip->hdu && chip->hdu != hdu) {
    376                     psLogMsg(__func__, PS_LOG_WARN, "Overwriting HDU in chip %s\n", chipName);
    377                     psFree(chip->hdu);  // Make way!
    378                     chip->hdu = NULL;
    379                 }
    380                 if (!chip->hdu) {
    381                     chip->hdu = psMemIncrRefCounter(hdu);
    382                 }
    383 
    384                 // Put in the cell data
    385                 if (cell->config) {
    386                     psLogMsg(__func__, PS_LOG_WARN, "Overwriting cell data in chip %s, cell %s\n", chipName,
    387                              cellName);
    388                     psFree(cell->config); // Make way!
    389                 }
    390                 cell->config = psMemIncrRefCounter(cellData);
    391                 pmConceptsReadCell(cell, PM_CONCEPT_SOURCE_CAMERA | PM_CONCEPT_SOURCE_DEFAULTS, false, NULL);
    392             }
    393 
    394         } else if (strcasecmp(extType, "CELL") == 0) {
    395             // Extensions are cells
    396             psString chipName = NULL;   // Name of chip under consideration
    397             pmChip *chip = NULL;        // The chip we're looking for
    398             #if 1
    399             // Think I'm doing this at the start now
    400             if (!fpa->hdu || !fpa->hdu->phu) {
    401                 // Need to look up the name of the chip
    402                 chipName = phuNameFromHeader("CHIP.NAME", formatSpec, phu);
    403                 int chipNum = pmFPAFindChip(fpa, chipName);
    404                 if (chipNum == -1) {
    405                     psLogMsg(__func__, PS_LOG_WARN, "Unable to find chip %s in FPA --- ignored.\n", chipName);
    406                     continue;
    407                 }
    408                 chip = fpa->chips->data[chipNum];
    409             }
    410             #endif
    411             for (int i = 0; i < names->n; i++) {
    412                 psString cellType = values->data[i]; // The type of the cell
    413                 psString cellName = NULL; // The name of the cell
    414                 if (fpa->hdu && fpa->hdu->phu) {
    415                     // We've got chipName:cellType with cellType == cellName
    416                     chipName = names->data[i];
    417                     cellName = cellType;
    418                     int chipNum = pmFPAFindChip(fpa, chipName); // The chip we're looking for
    419                     if (chipNum == -1) {
    420                         psLogMsg(__func__, PS_LOG_WARN, "Unable to find chip %s in FPA --- ignored.\n",
    421                                  chipName);
    422                         continue;
    423                     }
    424                     chip = fpa->chips->data[chipNum];
    425                 } else {
    426                     // We've got cellName:cellType and the chipName comes from before
    427                     cellName = names->data[i];
    428                 }
    429                 int cellNum = pmChipFindCell(chip, cellName); // The cell we're looking for
    430                 if (cellNum == -1) {
    431                     psLogMsg(__func__, PS_LOG_WARN, "Unable to find cell %s in chip %s --- ignored.\n",
    432                              cellName, chipName);
    433                     continue;
    434                 }
    435                 pmCell *cell = chip->cells->data[cellNum];
    436                 psMetadata *cellData = getCellData(format, cellType); // Data for this cell
    437 
    438                 // Put in the extension
    439                 if (cell->hdu && cell->hdu != hdu) {
    440                     psLogMsg(__func__, PS_LOG_WARN, "Overwriting HDU in chip %s, cell %s\n", chipName,
    441                              cellName);
    442                     psFree(cell->hdu);
    443                     cell->hdu = NULL;
    444                 }
    445                 if (! cell->hdu) {
    446                     cell->hdu = psMemIncrRefCounter(hdu);
    447                 }
    448 
    449                 // Put in the cell data
    450                 if (cell->config) {
    451                     psLogMsg(__func__, PS_LOG_WARN, "Overwriting cell data in chip %s, cell %s\n", chipName,
    452                              cellName);
    453                     psFree(cell->config);
    454                 }
    455                 cell->config = psMemIncrRefCounter(cellData);
    456                 pmConceptsReadCell(cell, PM_CONCEPT_SOURCE_CAMERA | PM_CONCEPT_SOURCE_DEFAULTS, false, NULL);
    457             }
    458 
    459         }
     552        processContents(fpa, chip, cell, hdu, hduLevel, contentsItem->data.V, format);
    460553        psFree(hdu);
    461         psFree(names);
    462         psFree(values);
    463554    }
    464555    psFree(contentsIter);
     
    468559    return view;
    469560}
    470 
    471 
    472 
    473 
    474 #if 0
    475 pmFPA *pmFPAConstruct(const psMetadata *camera // The camera configuration
    476                      )
    477 {
    478     pmFPA *fpa = pmFPAAlloc(camera);    // The FPA to fill out
    479 
    480     bool mdStatus = true;               // Status from metadata lookups
    481     const char *phuType = psMetadataLookupStr(&mdStatus, camera, "PHU"); // What is the PHU?
    482     const char *extType = psMetadataLookupStr(&mdStatus, camera, "EXTENSIONS"); // What's in the extns?
    483 
    484     if (strcasecmp(phuType, "FPA") == 0) {
    485         // The FITS file contains an entire FPA
    486 
    487         psMetadata *contents = psMetadataLookupMD(&mdStatus, camera, "CONTENTS"); // The CONTENTS
    488         if (! mdStatus) {
    489             psError(PS_ERR_IO, false, "Unable to determine CONTENTS of camera.\n");
    490             psFree(fpa);
    491             return NULL;
    492         }
    493 
    494         // Set up iteration over the contents
    495         psMetadataIterator *contentsIter = psMetadataIteratorAlloc(contents, PS_LIST_HEAD, NULL);
    496         psMetadataItem *contentItem = NULL; // Item from the metadata
    497 
    498         if (strcasecmp(extType, "CHIP") == 0) {
    499             // Extensions are chips; Content contains a list of cells
    500             while ((contentItem = psMetadataGetAndIncrement(contentsIter))) {
    501                 psString extName = contentItem->name; // The name of the extension
    502                 pmChip *chip = pmChipAlloc(fpa, extName); // The chip
    503                 chip->hdu = p_pmHDUAlloc(extName); // Prepare chip to receive FITS data
    504                 if (contentItem->type != PS_DATA_STRING) {
    505                     psLogMsg(__func__, PS_LOG_WARN, "Type of content item (%x) is not string: ignored\n",
    506                              contentItem->type);
    507                     continue;
    508                 }
    509 
    510                 const char *content = contentItem->data.V; // The content of the extension
    511                 psTrace(__func__, 7, "Content of %s is: %s\n", extName, content);
    512                 psList *cellNames = psStringSplit(content, " ,"); // A list of the component cells
    513                 psListIterator *cellNamesIter = psListIteratorAlloc(cellNames, PS_LIST_HEAD, NULL);
    514                 char *cellName = NULL; // The name of a cell
    515                 while ((cellName = psListGetAndIncrement(cellNamesIter))) {
    516                     // Get the cell data
    517                     psMetadata *cellData = getCellData(camera, cellName);
    518                     pmCell *cell = pmCellAlloc(chip, cellData, cellName); // The cell
    519                     psFree(cell);       // Drop reference
    520                     //                    psFree(cellData);   // Drop reference
    521                 }
    522                 psFree(cellNamesIter);
    523                 psFree(cellNames);
    524                 psFree(chip);           // Drop reference
    525             }
    526 
    527         } else if (strcasecmp(extType, "CELL") == 0) {
    528             // Extensions are cells; Content contains a chip name and cell type
    529             psMetadata *chips = psMetadataAlloc(); // Given a chip name, holds the chip number
    530             while ((contentItem = psMetadataGetAndIncrement(contentsIter))) {
    531                 psString extName = contentItem->name; // The name of the extension
    532                 psTrace(__func__, 1, "Getting %s....\n", extName);
    533 
    534                 if (contentItem->type != PS_DATA_STRING) {
    535                     psLogMsg(__func__, PS_LOG_WARN, "Type of content item (%x) is not string: ignored\n",
    536                              contentItem->type);
    537                     continue;
    538                 }
    539                 const char *content = contentItem->data.V; // The content of the extension
    540                 psList *contents = psStringSplit(content, ": "); // Split the name from the type
    541                 if (contents->n != 2) {
    542                     psLogMsg(__func__, PS_LOG_WARN, "Unable to read contents of %s: ignored.\n", extName);
    543                 } else {
    544                     psString chipName = psListGet(contents, 0); // The name of the chip
    545                     psString cellType = psListGet(contents, 1); // The type of cell
    546                     psTrace(__func__, 7, "Extension is cell of type %s, from chip %s\n", cellType,
    547                             chipName);
    548 
    549                     psMetadataItem *chipItem = psMetadataLookup(chips, chipName); // Item containing the chip
    550                     pmChip *chip = NULL; // The chip
    551                     if (! chipItem) {
    552                         chip = pmChipAlloc(fpa, chipName);
    553                         psMetadataAdd(chips, PS_LIST_TAIL, chipName, PS_DATA_UNKNOWN, "", chip);
    554                     } else {
    555                         chip = psMemIncrRefCounter(chipItem->data.V);
    556                     }
    557                     // The cell
    558                     psMetadata *cellData = getCellData(camera, cellType);
    559                     pmCell *cell = pmCellAlloc(chip, cellData, extName); // The cell
    560                     //                  psFree(cellData); // Drop reference
    561                     cell->hdu = p_pmHDUAlloc(extName); // Prepare cell to receive FITS data
    562 
    563                     psFree(cell);       // Drop reference
    564                     psFree(chip);       // Drop reference
    565                 }
    566                 psFree(contents);
    567             }
    568             psFree(chips);
    569 
    570         } else if (strcasecmp(extType, "NONE") == 0) {
    571             // No extensions; Content contains metadata, each entry is a chip with its component cells
    572             fpa->hdu = p_pmHDUAlloc("PHU"); // Prepare FPA to receive FITS data
    573             while ((contentItem = psMetadataGetAndIncrement(contentsIter))) {
    574                 psString chipName = contentItem->name; // The name of the chip
    575 
    576                 if (contentItem->type != PS_DATA_STRING) {
    577                     psLogMsg(__func__, PS_LOG_WARN, "Type of content item (%x) is not string: ignored\n",
    578                              contentItem->type);
    579                     continue;
    580                 }
    581                 psString content = contentItem->data.V; // The content of the extension
    582                 psTrace(__func__, 5, "Component cells are: %s\n", content);
    583                 pmChip *chip = pmChipAlloc(fpa, chipName); // The chip
    584                 psList *cellNames = psStringSplit(content, ", "); // Split the list of cells
    585                 psListIterator *cellNamesIter = psListIteratorAlloc(cellNames, PS_LIST_HEAD, false);
    586                 char *cellName = NULL; // Name of the cell
    587                 while ((cellName = psListGetAndIncrement(cellNamesIter))) {
    588                     psTrace(__func__, 7, "Processing cell %s....\n", cellName);
    589                     psMetadata *cellData = getCellData(camera, cellName);
    590                     pmCell *cell = pmCellAlloc(chip, cellData, cellName); // The cell
    591                     psFree(cell);       // Drop reference
    592                     //                  psFree(cellData);   // Drop reference
    593                 }
    594                 psFree(cellNamesIter);
    595                 psFree(chip);           // Drop reference
    596             }
    597 
    598         } else {
    599             psError(PS_ERR_IO, false, "EXTENSIONS in camera definition is not CHIP, CELL or NONE.\n");
    600             psFree(fpa);
    601             return NULL;
    602         } // Type of extension
    603 
    604         psFree(contentsIter);
    605 
    606     } else if (strcasecmp(phuType, "CHIP") == 0) {
    607         // The FITS file contains a single chip only
    608         psString chipName = psStringCopy("CHIP"); // Name for chip
    609         pmChip *chip = pmChipAlloc(fpa, chipName); // The chip
    610 
    611         if (strcasecmp(extType, "NONE") == 0) {
    612             // There are no extensions --- only the PHU
    613             chip->hdu = p_pmHDUAlloc("PHU");
    614 
    615             const char *contents = psMetadataLookupStr(&mdStatus, camera, "CONTENTS");
    616             if (! mdStatus) {
    617                 psError(PS_ERR_IO, false, "Unable to determine CONTENTS of camera.\n");
    618                 psFree(fpa);
    619                 return NULL;
    620             }
    621             psList *cellNames = psStringSplit(contents, " ,"); // Names of cells
    622             psListIterator *cellIter = psListIteratorAlloc(cellNames, PS_LIST_HEAD, false); // Iterator
    623             psString cellName = NULL;
    624             while ((cellName = psListGetAndIncrement(cellIter))) {
    625                 psMetadata *cellData = getCellData(camera, cellName);
    626                 pmCell *cell = pmCellAlloc(chip, cellData, cellName); // The cell
    627                 psFree(cell);
    628             }
    629             psFree(cellIter);
    630             psFree(cellNames);
    631 
    632         } else if (strcasecmp(extType, "CELL") == 0) {
    633             // Extensions are cells
    634             psMetadata *contents = psMetadataLookupMD(&mdStatus, camera, "CONTENTS"); // The CONTENTS
    635             if (! mdStatus) {
    636                 psError(PS_ERR_IO, false, "Unable to determine CONTENTS of camera.\n");
    637                 psFree(fpa);
    638                 return NULL;
    639             }
    640 
    641             if (strcasecmp(extType, "CELL") != 0) {
    642                 psLogMsg(__func__, PS_LOG_WARN, "EXTENSIONS in camera definition is %s, but PHU is CHIP.\n"
    643                          "EXTENSIONS assumed to be CELL.\n", extType);
    644             }
    645 
    646             // Iterate through the contents
    647             psMetadataIterator *contentsIter = psMetadataIteratorAlloc(contents, PS_LIST_HEAD, NULL);
    648             psMetadataItem *contentItem = NULL; // Item from metadata
    649             while ((contentItem = psMetadataGetAndIncrement(contentsIter))) {
    650                 psString extName = contentItem->name; // The name of the extension
    651                 // Content is a cell type
    652                 if (contentItem->type != PS_DATA_STRING) {
    653                     psLogMsg(__func__, PS_LOG_WARN,
    654                              "CONTENT metadata for extension %s is not of type string, but %x --- ignored\n",
    655                              extName, contentItem->type);
    656                     continue;
    657                 }
    658                 const char *cellType = contentItem->data.V; // The type of cell
    659                 psTrace(__func__, 5, "Cell type is %s\n", cellType);
    660                 psMetadata *cellData = getCellData(camera, cellType);
    661                 pmCell *cell = pmCellAlloc(chip, cellData, extName); // The cell
    662                 //              psFree(cellData);
    663                 cell->hdu = p_pmHDUAlloc(extName); // Prepare cell to receive FITS data
    664 
    665                 psFree(cell);
    666             } // Iterating through contents
    667             psFree(contentsIter);
    668 
    669         } else {
    670             psError(PS_ERR_IO, false, "EXTENSIONS in camera definition is neither CELL or NONE.\n");
    671             psFree(fpa);
    672             return NULL;
    673         }
    674         psFree(chipName);
    675         psFree(chip);                   // Drop reference
    676 
    677     } else {
    678         psError(PS_ERR_IO, true,
    679                 "The PHU type specified in the camera configuration (%s) is not FPA or CHIP.\n",
    680                 phuType);
    681         psFree(fpa);
    682         return NULL;
    683     }
    684 
    685     return fpa;
    686 }
    687 #endif
    688561
    689562
  • branches/rel10_ifa/psModules/src/astrom/pmFPACopy.c

    r6745 r6804  
    470470    bool yFlip = (psMetadataLookupS32(NULL, target->concepts, "CELL.YPARITY") !=
    471471                  psMetadataLookupS32(NULL, source->concepts, "CELL.YPARITY")); // Switch parity in y?
     472    psTrace(__func__, 3, "xFlip: %d; yFlip: %d\n", xFlip, yFlip);
    472473
    473474    bool mdok = true;                   // Status of MD lookup
     
    535536        psString name = conceptItem->name; // Name of concept
    536537        if (strcmp(name, "CELL.TRIMSEC") != 0 && strcmp(name, "CELL.BIASSEC") != 0 &&
    537                 strcmp(name, "CELL.XPARITY") != 0 && strcmp(name, "CELL.YPARITY") != 0) {
     538                strcmp(name, "CELL.XPARITY") != 0 && strcmp(name, "CELL.YPARITY") != 0 &&
     539                strcmp(name, "CELL.X0") != 0 && strcmp(name, "CELL.Y0") != 0) {
    538540            psMetadataAddItem(target->concepts, conceptItem, PS_LIST_TAIL, PS_META_REPLACE);
    539541        }
     
    543545    // Need to update CELL.X0 and CELL.Y0 if we flipped
    544546    if (xFlip) {
    545         psMetadataItem *xZero = psMetadataLookup(target->concepts, "CELL.X0"); // CELL.X0
     547        int xZero = psMetadataLookupS32(NULL, source->concepts, "CELL.X0"); // CELL.X0 from source
     548        int xParity = psMetadataLookupS32(NULL, target->concepts, "CELL.XPARITY"); // Parity in x
    546549        pmReadout *readout = target->readouts->data[0]; // A representative readout
    547         xZero->data.S32 -= readout->image->numCols - 1;
     550        psTrace(__func__, 3, "CELL.X0: Before: %d After: %d\n", xZero,
     551                xZero - (readout->image->numCols - 1) * xParity);
     552        xZero -= (readout->image->numCols - 1) * xParity; // Change the parity on the X0 position
     553        psMetadataItem *newItem = psMetadataLookup(target->concepts, "CELL.X0"); // CELL.X0 from target
     554        newItem->data.S32 = xZero;
    548555    }
    549556    if (yFlip) {
    550         psMetadataItem *yZero = psMetadataLookup(target->concepts, "CELL.Y0"); // CELL.Y0
     557        int yZero = psMetadataLookupS32(NULL, source->concepts, "CELL.Y0"); // CELL.Y0 from source
     558        int yParity = psMetadataLookupS32(NULL, target->concepts, "CELL.YPARITY"); // Parity in y
    551559        pmReadout *readout = target->readouts->data[0]; // A representative readout
    552         yZero->data.S32 -= readout->image->numRows - 1;
     560        psTrace(__func__, 3, "CELL.Y0: Before: %d After: %d\n", yZero,
     561                yZero - (readout->image->numCols - 1) * yParity);
     562        yZero -= (readout->image->numCols - 1) * yParity; // Change the parity on the Y0 position
     563        psMetadataItem *newItem = psMetadataLookup(target->concepts, "CELL.Y0"); // CELL.Y0 from target
     564        newItem->data.S32 = yZero;
    553565    }
    554566
Note: See TracChangeset for help on using the changeset viewer.