IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jun 7, 2007, 2:31:50 PM (19 years ago)
Author:
Paul Price
Message:

Adding automatically-generated skycell pseudo-cameras, constructed from the user-defined cameras. This gives a couple of benefits: (1) skycells inherit the recipes of their original camera; (2) skycells use the same FILERULES as their original camera.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/config/pmConfigCamera.c

    r12890 r13704  
    55#include <stdio.h>
    66#include <string.h>
    7 #include <strings.h>            /* for strn?casecmp */
     7#include <strings.h>            /* for strn?casecmp */
    88#include <pslib.h>
    99
     
    1111#include "pmFPA.h"
    1212#include "pmFPALevel.h"
     13#include "pmVersion.h"
    1314#include "pmConcepts.h"
    1415#include "pmConfigCamera.h"
     
    2122static void removeCellConceptsSources(psMetadata *source);
    2223static void removeChipConceptsSources(psMetadata *source);
     24
     25// Generate the skycell version of a named camera configuration
     26bool pmConfigCameraSkycellVersion(psMetadata *site, // The site configuration
     27                           const char *name // Name of the un-mosaicked camera
     28                           )
     29{
     30    PS_ASSERT_METADATA_NON_NULL(site, false);
     31    PS_ASSERT_STRING_NON_EMPTY(name, false);
     32
     33    bool mdok;                          // Status of MD lookup
     34    psMetadata *cameras = psMetadataLookupMetadata(&mdok, site, "CAMERAS"); // List of cameras
     35    if (!mdok || !cameras) {
     36        psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find CAMERAS in the site configuration.\n");
     37        return false;
     38    }
     39    if (!pmConfigGenerateSkycellVersion(cameras, cameras, name)) {
     40        psError(PS_ERR_UNKNOWN, true, "Failed to build skycell camera description for %s\n", name);
     41        return false;
     42    }
     43    return true;
     44}
     45
     46
     47bool pmConfigCameraSkycellVersionsAll(psMetadata *site)
     48{
     49    PS_ASSERT_METADATA_NON_NULL(site, false);
     50
     51    bool mdok;                          // Status of MD lookup
     52    psMetadata *cameras = psMetadataLookupMetadata(&mdok, site, "CAMERAS"); // List of cameras
     53    if (!mdok || !cameras) {
     54        psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find CAMERAS in the site configuration.\n");
     55        return false;
     56    }
     57
     58    psMetadataIterator *camerasIter = psMetadataIteratorAlloc(cameras, PS_LIST_HEAD, NULL); // Iterator
     59    psMetadataItem *camerasItem = NULL; // Item from iteration
     60    psMetadata *new = psMetadataAlloc();// New cameras to add
     61    while ((camerasItem = psMetadataGetAndIncrement(camerasIter))) {
     62        assert(camerasItem->type == PS_DATA_METADATA); // Only metadata are allowed here!
     63        if (!pmConfigGenerateSkycellVersion(cameras, new, camerasItem->name)) {
     64            psError(PS_ERR_UNKNOWN, true, "Failed to build skycell camera description for %s\n",
     65                    camerasItem->name);
     66            return false;
     67        }
     68    }
     69    psFree(camerasIter);
     70
     71    // Now put the new cameras at the top of the list of cameras, so they get recognised first
     72    // Note: going from the top, and putting everything to the top as we get there, so that the last one on
     73    // goes to the top.  This preserves the original order of the cameras, putting the skycell versions
     74    // before the originals.
     75    camerasIter = psMetadataIteratorAlloc(new, PS_LIST_HEAD, NULL); // Iterator
     76    while ((camerasItem = psMetadataGetAndIncrement(camerasIter))) {
     77        psMetadataAddItem(cameras, camerasItem, PS_LIST_HEAD, 0);
     78    }
     79    psFree(camerasIter);
     80    psFree(new);
     81
     82    return true;
     83}
     84
     85// Generate a skycell version of a camera configuration
     86bool pmConfigGenerateSkycellVersion(psMetadata *oldCameras, // Old list of camera configurations
     87                                    psMetadata *newCameras, // New list of camera configurations
     88                                    const char *name // Name of original camera configuration
     89                                    )
     90{
     91    assert(oldCameras);
     92    assert(newCameras);
     93    assert(name);
     94
     95    // See if the old one is there
     96    psMetadata *camera = psMetadataLookupMetadata(NULL, oldCameras, name); // The camera configuration
     97    if (!camera) {
     98        psError(PS_ERR_UNEXPECTED_NULL, false, "Can't find camera to be skycelled in camera list.");
     99        return false;
     100    }
     101
     102    // See if the new one is already there
     103    psString newName = NULL;       // Name of skycelled camera
     104    psStringAppend(&newName, "_%s-SKYCELL", name);
     105    if (psMetadataLookup(oldCameras, newName)) {
     106        return true;
     107    }
     108
     109    psMetadata *new = psMetadataCopy(NULL, camera); // Copy of the camera description
     110
     111    // Fix the FPA description to contain a single chip with single cell
     112    {
     113        psMetadata *fpa = psMetadataAlloc();// The FPA description
     114        psMetadataAddStr(fpa, PS_LIST_HEAD, "SkyChip", 0, "Single chip with single cell", "SkyCell");
     115        psMetadataAddMetadata(new, PS_LIST_TAIL, "FPA", PS_META_REPLACE, "Description of FPA hierarchy", fpa);
     116        psFree(fpa);
     117    }
     118
     119    // Clear out the formats, replace them with the One True Format
     120    psMetadata *formats = psMetadataLookupMetadata(NULL, new, "FORMATS"); // The list of formats
     121    if (!formats) {
     122        psError(PS_ERR_UNEXPECTED_NULL, false, "Can't find FORMATS within camera configuration.");
     123        psFree(new);
     124        return false;
     125    }
     126    while (psListLength(formats->list) > 0) {
     127        psMetadataRemoveIndex(formats, PS_LIST_HEAD);
     128    }
     129    psMetadata *format = psMetadataAlloc(); // The One True Format
     130
     131    {
     132        psMetadata *rule = psMetadataAlloc(); // The RULE --- how to recognise the camera
     133        psMetadataAddStr(rule, PS_LIST_TAIL, "PSCAMERA", 0, "Camera name", name);
     134        psMetadataAddStr(rule, PS_LIST_TAIL, "PSFORMAT", 0, "Camera format", "SKYCELL");
     135        psString version = psModulesVersion();
     136        psMetadataAddStr(rule, PS_LIST_TAIL, "ORIGIN", 0, "File origin", version);
     137        psFree(version);
     138        psMetadataAddMetadata(format, PS_LIST_TAIL, "RULE", 0, "How to recognise this type of file", rule);
     139        psFree(rule);
     140    }
     141
     142    {
     143        psMetadata *file = psMetadataAlloc(); // The FILE --- how to read the data
     144        psMetadataAddStr(file, PS_LIST_TAIL, "PHU", 0, "What level the FITS file represents", "FPA");
     145        psMetadataAddStr(file, PS_LIST_TAIL, "EXTENSIONS", 0, "What level the extensions represent", "NONE");
     146        psMetadataAddStr(file, PS_LIST_TAIL, "FPA.NAME", 0, "PHU keyword for unique identifier", "FPA.NAME");
     147        psMetadataAddMetadata(format, PS_LIST_TAIL, "FILE", 0, "How to read this type of file", file);
     148        psFree(file);
     149    }
     150
     151    psMetadataAddStr(format, PS_LIST_TAIL, "CONTENTS", 0, "What's in this type of file",
     152                     "SkyChip:SkyCell:_skycell");
     153
     154    {
     155        psMetadata *cells = psMetadataAlloc(); // The CELLS --- how to read the cells
     156        psMetadata *skycell = psMetadataAlloc(); // How to read the skycell
     157        psMetadataAddStr(skycell, PS_LIST_TAIL, "CELL.TRIMSEC", 0, "Trim section", "CELL.TRIMSEC");
     158        psMetadataAddStr(skycell, PS_LIST_TAIL, "CELL.BIASSEC", 0, "Bias section", "CELL.BIASSEC");
     159        psMetadataAddStr(skycell, PS_LIST_TAIL, "CELL.TRIMSEC.SOURCE", 0, "Source for trim section",
     160                         "HEADER");
     161        psMetadataAddStr(skycell, PS_LIST_TAIL, "CELL.BIASSEC.SOURCE", 0, "Source for bias section",
     162                         "HEADER");
     163        psMetadataAddMetadata(cells, PS_LIST_TAIL, "_skycell", 0, "Skycell specification", skycell);
     164        psFree(skycell);
     165        psMetadataAddMetadata(format, PS_LIST_TAIL, "CELLS", 0, "How to read the cells", cells);
     166        psFree(cells);
     167    }
     168
     169    // Stuffing all concepts into the header, by their PS concept name (e.g., "FPA.AIRMASS").
     170    // (HIERARCH will take care of the long names, implemented in psLib.)
     171    // Some people may not like this, but it's quick and easy and will do for now.
     172    // An alternative may be provided later.
     173    {
     174        psMetadata *translation = psMetadataAlloc(); // The TRANSLATION --- how to read the FITS headers
     175
     176        psList *concepts;               // List of concepts for each level
     177        psListIterator *iter;           // Iterator for concepts
     178        psString name;                  // Concept name, from iteration
     179
     180        concepts = pmConceptsList(PM_FPA_LEVEL_FPA); // FPA-level concepts
     181        iter = psListIteratorAlloc(concepts, PS_LIST_HEAD, false);
     182        while ((name = psListGetAndIncrement(iter))) {
     183            psMetadataAddStr(translation, PS_LIST_TAIL, name, 0, NULL, name);
     184        }
     185        psFree(iter);
     186        psFree(concepts);
     187
     188        concepts = pmConceptsList(PM_FPA_LEVEL_CHIP);
     189        iter = psListIteratorAlloc(concepts, PS_LIST_HEAD, false);
     190        while ((name = psListGetAndIncrement(iter))) {
     191            psMetadataAddStr(translation, PS_LIST_TAIL, name, 0, NULL, name);
     192        }
     193        psFree(iter);
     194        psFree(concepts);
     195
     196        concepts = pmConceptsList(PM_FPA_LEVEL_CELL);
     197        iter = psListIteratorAlloc(concepts, PS_LIST_HEAD, false);
     198        while ((name = psListGetAndIncrement(iter))) {
     199            // We've done CELL.BIASSEC and CELL.TRIMSEC under CELLS, above.
     200            if (strcmp(name, "CELL.BIASSEC") != 0 && strcmp(name, "CELL.TRIMSEC") != 0) {
     201                psMetadataAddStr(translation, PS_LIST_TAIL, name, 0, NULL, name);
     202            }
     203        }
     204        psFree(iter);
     205        psFree(concepts);
     206
     207        psMetadataAddMetadata(format, PS_LIST_TAIL, "TRANSLATION", 0, "How to translate the FITS headers",
     208                              translation);
     209        psFree(translation);
     210    }
     211
     212    {
     213        psMetadata *defaults = psMetadataAlloc(); // Default values for concepts
     214        psMetadataAddMetadata(format, PS_LIST_TAIL, "DEFAULTS", 0, "Default values for concepts", defaults);
     215        psFree(defaults);
     216    }
     217
     218    {
     219        psMetadata *database = psMetadataAlloc(); // Database values for concepts
     220        psMetadataAddMetadata(format, PS_LIST_TAIL, "DATABASE", 0, "Database values for concepts", database);
     221        psFree(database);
     222    }
     223
     224    {
     225        psMetadata *conceptFormats = psMetadataAlloc(); // Format peculiarities for various concepts
     226        // These are the only essential formats
     227        psMetadataAddStr(conceptFormats, PS_LIST_TAIL, "FPA.RA", 0, "Units for RA", "HOURS");
     228        psMetadataAddStr(conceptFormats, PS_LIST_TAIL, "FPA.DEC", 0, "Units for RA", "DEGREES");
     229        psMetadataAddMetadata(format, PS_LIST_TAIL, "FORMATS", 0, "Formats for various concepts",
     230                              conceptFormats);
     231        psFree(conceptFormats);
     232    }
     233
     234    psMetadataAddMetadata(formats, PS_LIST_TAIL, "SKYCELL", 0, "The One True Format for skycells", format);
     235    psFree(format);
     236
     237    // New camera MUST go to the head of the metadata, so that it will be recognised first
     238    // The old camera doesn't contain the PSCAMERA and PSFORMAT headers, so it will match anything!
     239    psMetadataAddMetadata(newCameras, PS_LIST_HEAD, newName, PS_META_REPLACE,
     240                          "Automatically generated", new);
     241    psFree(newName);
     242    psFree(new);
     243
     244    return true;
     245}
    23246
    24247// Generate the Chip and FPA mosaicked version of a named camera configuration
     
    66289        assert(camerasItem->type == PS_DATA_METADATA); // Only metadata are allowed here!
    67290        if (!pmConfigGenerateMosaickedVersion(cameras, new, camerasItem->name, PM_FPA_LEVEL_CHIP)) {
    68             psError(PS_ERR_UNKNOWN, true, "Failed to build Chip mosaic camera description for %s\n", camerasItem->name);
    69             return false;
    70         }
     291            psError(PS_ERR_UNKNOWN, true, "Failed to build Chip mosaic camera description for %s\n", camerasItem->name);
     292            return false;
     293        }
    71294        if (!pmConfigGenerateMosaickedVersion(cameras, new, camerasItem->name, PM_FPA_LEVEL_FPA)) {
    72             psError(PS_ERR_UNKNOWN, true, "Failed to build FPA mosaic camera description for %s\n", camerasItem->name);
    73             return false;
    74         }
     295            psError(PS_ERR_UNKNOWN, true, "Failed to build FPA mosaic camera description for %s\n", camerasItem->name);
     296            return false;
     297        }
    75298    }
    76299    psFree(camerasIter);
     
    92315// Generate a mosaicked version of a camera configuration
    93316bool pmConfigGenerateMosaickedVersion(psMetadata *oldCameras, // Old list of camera configurations
    94                                       psMetadata *newCameras, // New list of camera configurations
    95                                       const char *name, // Name of original camera configuration
    96                                       pmFPALevel mosaicLevel // Level to which we are mosaicking
     317                                      psMetadata *newCameras, // New list of camera configurations
     318                                      const char *name, // Name of original camera configuration
     319                                      pmFPALevel mosaicLevel // Level to which we are mosaicking
    97320    )
    98321{
     
    101324    assert(name);
    102325    assert(mosaicLevel == PM_FPA_LEVEL_CHIP || mosaicLevel == PM_FPA_LEVEL_FPA);
     326
     327    // Don't generate a mosaicked version of a skycell
     328    if (name[0] == '_' && strlen(name) > 9 && strcmp(name + strlen(name) - 8, "-SKYCELL") == 0) {
     329        return true;
     330    }
    103331
    104332    // See if the old one is there
Note: See TracChangeset for help on using the changeset viewer.