IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 13704


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.

Location:
trunk/psModules/src
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/camera/pmFPAfileDefine.c

    r13669 r13704  
    9393}
    9494
    95 // define a pmFPAfile, bind to the optional fpa if supplied
    96 pmFPAfile *pmFPAfileDefineOutput(const pmConfig *config, pmFPA *fpa, const char *name)
    97 {
    98     PS_ASSERT_PTR_NON_NULL(config, NULL);
    99     PS_ASSERT_PTR_NON_NULL(config->files, NULL);
    100     PS_ASSERT_PTR_NON_NULL(config->camera, NULL);
    101     PS_ASSERT_STRING_NON_EMPTY(name, NULL);
    102 
     95// Define an output pmFPAfile
     96static pmFPAfile *fpaFileDefineOutput(const pmConfig *config, // Configuration
     97                                      pmFPA *fpa, // Optional FPA to bind
     98                                      const char *name, // Name of file rule
     99                                      const char *cameraName, // Name of camera configuration to use
     100                                      const char *formatName // Name of camera format to use
     101    )
     102{
    103103    bool status;
    104104
    105105    // select the FILERULES from the camera config
    106     psMetadata *filerules = psMetadataLookupPtr (&status, config->camera, "FILERULES");
     106    psMetadata *filerules = psMetadataLookupPtr(&status, config->camera, "FILERULES");
    107107    if (filerules == NULL) {
    108108        psError(PS_ERR_IO, true, "Can't find FILERULES in the CAMERA configuration!");
     
    112112    // select the name from the FILERULES
    113113    // check for alias name (type == STR, name is aliased name)
    114     const char *realname = psMetadataLookupStr (&status, filerules, name);
     114    const char *realname = psMetadataLookupStr(&status, filerules, name);
    115115    if (!realname || strlen(realname) == 0) {
    116116        realname = name;
     
    123123    }
    124124
    125     pmFPAfile *file = pmFPAfileAlloc ();
     125    pmFPAfile *file = pmFPAfileAlloc();
    126126
    127127    // save the name of this pmFPAfile
    128     file->name = psStringCopy (name);
    129 
    130     file->filerule = psMemIncrRefCounter(psMetadataLookupStr (&status, data, "FILENAME.RULE"));
    131 
    132     const char *type = psMetadataLookupStr (&status, data, "FILE.TYPE");
     128    file->name = psStringCopy(name);
     129
     130    file->filerule = psMemIncrRefCounter(psMetadataLookupStr(&status, data, "FILENAME.RULE"));
     131
     132    const char *type = psMetadataLookupStr(&status, data, "FILE.TYPE");
    133133    file->type = pmFPAfileTypeFromString(type);
    134134    if (file->type == PM_FPA_FILE_NONE) {
     
    153153    }
    154154
    155     psMetadata *camera;                 // Camera to use
    156     if (fpa && fpa->camera) {
    157         camera = (psMetadata*)fpa->camera; // Casting away const, so I can put it in the file
     155    // Use the camera we were told to, the camera of the provided FPA, or default to the default camera
     156    psMetadata *camera;                 // Camera configuration
     157    if (!cameraName || strlen(cameraName) == 0) {
     158        if (fpa && fpa->camera) {
     159            camera = (psMetadata*)fpa->camera; // Casting away const, so I can put it in the file
     160        } else {
     161            camera = config->camera;
     162        }
    158163    } else {
    159         camera = config->camera;
     164        bool mdok;                      // Status of MD lookup
     165        psMetadata *cameras = psMetadataLookupMetadata(&mdok, config->site, "CAMERAS"); // Known cameras
     166        if (!mdok || !cameras) {
     167            psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find CAMERAS in the site configuration.\n");
     168            return NULL;
     169        }
     170        camera = psMetadataLookupMetadata(&mdok, cameras, cameraName); // Camera configuration of interest
     171        if (!mdok || !camera) {
     172            psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find automatically generated "
     173                    "camera configuration %s in site configuration.\n", cameraName);
     174            return NULL;
     175        }
     176
     177        if (fpa && fpa->camera && fpa->camera != camera) {
     178            psAbort("Camera of bound FPA is not the requested camera --- there is an inconsistency!");
     179        }
    160180    }
    161181    file->camera = psMemIncrRefCounter(camera);
    162182
    163     // select the format list from the selected camera
    164     const char *formatName = psMetadataLookupStr (&status, data, "FILE.FORMAT");
    165     if (!formatName || strcmp(formatName, "NONE") == 0) {
    166         // Try to get by with the default
    167         formatName = config->formatName;
     183    // Use the format we were told to, the format specified in the file rule, or default to the default format
     184    if (!formatName || strlen(formatName) == 0) {
     185        // select the format list from the selected camera
     186        formatName = psMetadataLookupStr(&status, data, "FILE.FORMAT");
     187        if (!formatName || strcmp(formatName, "NONE") == 0) {
     188            // Try to get by with the default
     189            formatName = config->formatName;
     190        }
    168191    }
    169192    psMetadata *formats = psMetadataLookupMetadata(&status, file->camera, "FORMATS"); // List of formats
     
    177200    file->format = psMemIncrRefCounter(format);
    178201
    179     file->fpa = psMemIncrRefCounter(fpa);
     202    if (fpa) {
     203        file->fpa = psMemIncrRefCounter(fpa);
     204    } else {
     205        file->fpa = pmFPAConstruct(file->camera);
     206    }
    180207
    181208    file->fileLevel = pmFPAPHULevel(format);
     
    219246}
    220247
     248// define a pmFPAfile, bind to the optional fpa if supplied
     249pmFPAfile *pmFPAfileDefineOutput(const pmConfig *config, pmFPA *fpa, const char *name)
     250{
     251    PS_ASSERT_PTR_NON_NULL(config, NULL);
     252    PS_ASSERT_PTR_NON_NULL(config->files, NULL);
     253    PS_ASSERT_PTR_NON_NULL(config->camera, NULL);
     254    PS_ASSERT_STRING_NON_EMPTY(name, NULL);
     255
     256    return fpaFileDefineOutput(config, fpa, name, NULL, NULL);
     257}
    221258
    222259// search for argname on the config->argument list
     
    245282    psArray *infiles = psMetadataLookupPtr(&status, config->arguments, argname);
    246283    if (!status) {
    247         if (success) *success = true;
     284        if (success) *success = true;
    248285        return NULL;
    249286    }
     
    415452    if (!status) {
    416453        // this is not an error: this just means no matching argument was supplied
    417         if (success) *success = true;
     454        if (success) *success = true;
    418455        return NULL;
    419456    }
     
    545582    if (!status) {
    546583        psTrace("psModules.camera", 5, "Failed to find %s in argument list", argname);
    547         if (success) *success = true;
     584        if (success) *success = true;
    548585        return NULL;
    549586    }
     
    679716        // don't free the file here: it is left on config->files
    680717        // to be used optionally by pmFPAfileDefineFromDetDB (or others)
    681         if (success) *success = true;
     718        if (success) *success = true;
    682719        return NULL;
    683720    }
     
    908945}
    909946
     947pmFPAfile *pmFPAfileDefineSkycell(const pmConfig *config, pmFPA *fpa, const char *filename)
     948{
     949    PS_ASSERT_PTR_NON_NULL(config, NULL);
     950    PS_ASSERT_STRING_NON_EMPTY(filename, NULL);
     951    PS_ASSERT_STRING_NON_EMPTY(config->cameraName, NULL);
     952    PS_ASSERT_STRING_NON_EMPTY(config->formatName, NULL);
     953
     954    pmFPAfile *file;                    // The new file
     955
     956    if (config->cameraName[0] == '_' &&
     957        strcmp(config->cameraName + strlen(config->cameraName) - 8, "-SKYCELL") == 0) {
     958        // The input camera is already a skycell
     959        file = fpaFileDefineOutput(config, fpa, filename, config->cameraName, "SKYCELL");
     960    } else {
     961        // Find the correct camera configuration
     962        psString cameraName = NULL;         // Name of the new (automatically-generated) camera configuration
     963        psStringAppend(&cameraName, "_%s-SKYCELL", config->cameraName);
     964
     965        file = fpaFileDefineOutput(config, fpa, filename, cameraName, "SKYCELL");
     966        psFree(cameraName);
     967    }
     968
     969    // Ensure everything is written out at the appropriate level
     970    file->fileLevel = PM_FPA_LEVEL_FPA;
     971    file->dataLevel = PM_FPA_LEVEL_FPA;
     972    file->freeLevel = PM_FPA_LEVEL_FPA;
     973
     974    return file;
     975}
     976
    910977pmFPAfile *pmFPAfileDefineChipMosaic(const pmConfig *config, pmFPA *src, const char *filename)
    911978{
     
    916983    PS_ASSERT_STRING_NON_EMPTY(config->formatName, NULL);
    917984
     985    pmFPAfile *file;                    // The new file
    918986    if (config->cameraName[0] == '_' &&
    919987        strcmp(config->cameraName + strlen(config->cameraName) - 5, "-CHIP") == 0) {
    920988        // The input camera has already been mosaicked to this level
    921         pmFPAfile *file = pmFPAfileDefineOutput(config, NULL, filename);
    922         psFree (file->camera);
    923         psFree (file->format);
    924         psFree (file->fpa);
    925         file->camera = psMemIncrRefCounter(config->camera);
    926         file->format = psMemIncrRefCounter(config->format);
    927         file->fpa = pmFPAConstruct(file->camera);
    928         return file;
    929     }
    930 
    931     // Find the correct camera configuration
    932     bool mdok;                          // Status of MD lookup
    933     psMetadata *cameras = psMetadataLookupMetadata(&mdok, config->site, "CAMERAS"); // Camera configurations
    934     if (!mdok || !cameras) {
    935         psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find CAMERAS in the site configuration.\n");
    936         return NULL;
    937     }
    938     psString name = NULL;               // Name of the new (automatically-generated) camera configuration
    939     psStringAppend(&name, "_%s-CHIP", config->cameraName);
    940     psMetadata *camera = psMetadataLookupMetadata(&mdok, cameras, name); // Camera configuration of interest
    941     if (!mdok || !camera) {
    942         psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find automatically generated "
    943                 "camera configuration %s in site configuration.\n", name);
    944         psFree(name);
    945         return NULL;
    946     }
    947     psFree(name);
    948 
    949     // Need to look up the format of the same name, but under the mosaic camera
    950     psMetadata *formats = psMetadataLookupMetadata(&mdok, camera, "FORMATS"); // The FORMATS
    951     if (!mdok || !formats) {
    952         psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find FORMATS in camera configuration %s.\n",
    953                 config->cameraName);
    954         return NULL;
    955     }
    956     psMetadata *format = psMetadataLookupMetadata(&mdok, formats, config->formatName); // The format
    957     if (!mdok || !format) {
    958         psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find camera format %s within camera %s.\n",
    959                 config->formatName, config->cameraName);
    960         return NULL;
    961     }
    962 
    963     pmFPA *fpa = pmFPAConstruct(camera);
    964     if (!fpa) {
    965         psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to generate mosaicked camera.\n");
    966         return NULL;
    967     }
    968     pmFPAfile *file = pmFPAfileDefineOutput(config, fpa, filename);
    969     if (!file) {
    970         psErrorStackPrint(stderr, "file %s not defined\n", filename);
    971         return NULL;
    972     }
     989        file = fpaFileDefineOutput(config, NULL, filename, config->cameraName, config->formatName);
     990    } else {
     991        psString cameraName = NULL;         // Name of the new (automatically-generated) camera configuration
     992        psStringAppend(&cameraName, "_%s-CHIP", config->cameraName);
     993
     994        // Find the correct camera configuration
     995        file = fpaFileDefineOutput(config, NULL, filename, cameraName, config->formatName);
     996        psFree(cameraName);
     997    }
     998
    973999    file->src = src; // inherit output elements from this source pmFPA
     1000
    9741001    file->mosaicLevel = PM_FPA_LEVEL_CHIP; // don't do any I/O on this at a lower level
    975 
    976     psFree (file->format);
    977     file->format = psMemIncrRefCounter(format);
    978 
    979     psFree(fpa);
    9801002
    9811003    return file;
     
    9891011    PS_ASSERT_STRING_NON_EMPTY(config->cameraName, NULL);
    9901012
     1013    pmFPAfile *file;                    // The new file
    9911014    if (config->cameraName[0] == '_' &&
    9921015            strcmp(config->cameraName + strlen(config->cameraName) - 4 , "-FPA") == 0) {
    9931016        // The input camera has already been mosaicked to this level
    994         pmFPAfile *file = pmFPAfileDefineOutput(config, NULL, filename);
    995         psFree (file->camera);
    996         psFree (file->format);
    997         psFree (file->fpa);
    998         file->camera = psMemIncrRefCounter(config->camera);
    999         file->format = psMemIncrRefCounter(config->format);
    1000         file->fpa = pmFPAConstruct(file->camera);
    1001         return file;
    1002     }
    1003 
    1004     // Find the correct camera configuration
    1005     bool mdok;                          // Status of MD lookup
    1006     psMetadata *cameras = psMetadataLookupMetadata(&mdok, config->site, "CAMERAS"); // Camera configurations
    1007     if (!mdok || !cameras) {
    1008         psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find CAMERAS in the site configuration.\n");
    1009         return NULL;
    1010     }
    1011     psString original;                  // Name of the original camera configuration
    1012     psString name = NULL;               // Name of the new (automatically-generated) camera configuration
    1013     if (config->cameraName[0] == '_' &&
     1017        file = fpaFileDefineOutput(config, NULL, filename, config->cameraName, config->formatName);
     1018    } else {
     1019
     1020        psString original;                  // Name of the original camera configuration
     1021        if (config->cameraName[0] == '_' &&
    10141022            strcmp(config->cameraName + strlen(config->cameraName) - 5 , "-CHIP") == 0) {
    1015         // It's a chip mosaic; we need to get the original name
    1016         original = psStringNCopy(config->cameraName + 1, strlen(config->cameraName) - 6);
    1017     } else {
    1018         original = psMemIncrRefCounter(config->cameraName);
    1019     }
    1020     psStringAppend(&name, "_%s-FPA", original);
    1021     psFree(original);
    1022     psMetadata *camera = psMetadataLookupMetadata(&mdok, cameras, name); // Camera configuration of interest
    1023     if (!mdok || !camera) {
    1024         psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find automatically generated "
    1025                 "camera configuration %s in site configuration.\n", name);
    1026         psFree(name);
    1027         return NULL;
    1028     }
    1029     psFree(name);
    1030 
    1031     // Need to look up the format of the same name, but under the mosaic camera
    1032     psMetadata *formats = psMetadataLookupMetadata(&mdok, camera, "FORMATS"); // The FORMATS
    1033     if (!mdok || !formats) {
    1034         psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find FORMATS in camera configuration %s.\n",
    1035                 config->cameraName);
    1036         return NULL;
    1037     }
    1038     psMetadata *format = psMetadataLookupMetadata(&mdok, formats, config->formatName); // The format
    1039     if (!mdok || !format) {
    1040         psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find camera format %s within camera %s.\n",
    1041                 config->formatName, config->cameraName);
    1042         return NULL;
    1043     }
    1044 
    1045     pmFPA *fpa = pmFPAConstruct(camera);
    1046     if (!fpa) {
    1047         psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to generate mosaicked camera.\n");
    1048         return NULL;
    1049     }
    1050     pmFPAfile *file = pmFPAfileDefineOutput(config, fpa, filename);
    1051     if (!file) {
    1052         psErrorStackPrint(stderr, "file %s not defined\n", filename);
    1053         return NULL;
    1054     }
     1023            // It's a chip mosaic; we need to get the original name
     1024            original = psStringNCopy(config->cameraName + 1, strlen(config->cameraName) - 6);
     1025        } else {
     1026            original = psMemIncrRefCounter(config->cameraName);
     1027        }
     1028        psString cameraName = NULL;
     1029        psStringAppend(&cameraName, "_%s-FPA", original);
     1030
     1031        file = fpaFileDefineOutput(config, NULL, filename, cameraName, config->formatName);
     1032        psFree(cameraName);
     1033    }
     1034
    10551035    file->src = src; // inherit output elements from this source pmFPA
     1036
    10561037    file->mosaicLevel = PM_FPA_LEVEL_FPA; // don't do any I/O on this at a lower level
    1057     psFree (file->format);
    1058     file->format = psMemIncrRefCounter(format);
    1059 
    1060     psFree(fpa);
    10611038
    10621039    return file;
  • trunk/psModules/src/camera/pmFPAfileDefine.h

    r13496 r13704  
    44 * @author EAM, IfA
    55 *
    6  * @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
    7  * @date $Date: 2007-05-24 02:38:07 $
     6 * @version $Revision: 1.12 $ $Name: not supported by cvs2svn $
     7 * @date $Date: 2007-06-08 00:31:50 $
    88 * Copyright 2004-2005 Institute for Astronomy, University of Hawaii
    99 */
     
    6666pmFPAfile *pmFPAfileDefineNewCamera (const pmConfig *config, const char *filename);
    6767
     68/// Create a new output pmFPAfile for a skycell of the default camera
     69///
     70/// The new pmFPAfile is inserted into the config->files metadata, freed and returned; so that the user does
     71/// not have to (and should not!) free the result.
     72pmFPAfile *pmFPAfileDefineSkycell(const pmConfig *config, ///< Configuration data
     73                                  pmFPA *fpa, ///< FPA to which to bind
     74                                  const char *filename ///< Output (root) filename
     75    );
     76
     77
    6878/// Create a new output pmFPAfile based upon a chip mosaic of an existing FPA
    6979///
  • trunk/psModules/src/config/pmConfig.c

    r13355 r13704  
    44 *  @author EAM (IfA)
    55 *
    6  *  @version $Revision: 1.94 $ $Name: not supported by cvs2svn $
    7  *  @date $Date: 2007-05-11 23:28:15 $
     6 *  @version $Revision: 1.95 $ $Name: not supported by cvs2svn $
     7 *  @date $Date: 2007-06-08 00:31:50 $
    88 *
    99 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    533533                                  "Camera specified on command line", config->camera);
    534534
     535            if (!pmConfigCameraSkycellVersion(config->site, cameraFile)) {
     536                psError(PS_ERR_UNKNOWN, false,
     537                        "Unable to generate skycell versions of specified camera %s.\n",
     538                        cameraFile);
     539                psFree(config);
     540                return NULL;
     541            }
     542
    535543            if (!pmConfigCameraMosaickedVersions(config->site, cameraFile)) {
    536544                psError(PS_ERR_UNKNOWN, false,
     
    570578        psFree(iter);
    571579
     580        if (!pmConfigCameraSkycellVersionsAll(config->site)) {
     581            psError(PS_ERR_UNKNOWN, false, "Unable to generate skycell versions of cameras.\n");
     582            psFree(config);
     583            return NULL;
     584        }
    572585        if (!pmConfigCameraMosaickedVersionsAll(config->site)) {
    573586            psError(PS_ERR_UNKNOWN, false, "Unable to generate mosaicked versions of cameras.\n");
  • 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
  • trunk/psModules/src/config/pmConfigCamera.h

    r12696 r13704  
    11/*  @file pmConfigCamera.h
    22 *  @brief Camera Configuration functions
    3  * 
     3 *
    44 *  @author Paul Price, IfA
    55 *  @author Eugene Magnier, IfA
    6  * 
    7  *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
    8  *  @date $Date: 2007-03-30 21:12:56 $
     6 *
     7 *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
     8 *  @date $Date: 2007-06-08 00:31:50 $
    99 *  Copyright 2005-2006 Institute for Astronomy, University of Hawaii
    1010 */
     
    1616/// @{
    1717
     18// Generate a skycell version of a camera configuration
     19bool pmConfigGenerateSkycellVersion(psMetadata *oldCameras, // Old list of camera configurations
     20                                    psMetadata *newCameras, // New list of camera configurations
     21                                    const char *name // Name of original camera configuration
     22    );
     23
     24/// Generate the skycell version of a particular camera configuration
     25bool pmConfigCameraSkycellVersion(psMetadata *site, // The site configuration
     26                           const char *name // Name of the un-mosaicked camera
     27    );
     28
     29
     30/// Generate skycell versions of all the camera configurations
     31bool pmConfigCameraSkycellVersionsAll(psMetadata *site // Site configuration
     32    );
     33
    1834// Generate a mosaicked version of a camera configuration
    1935bool pmConfigGenerateMosaickedVersion(psMetadata *oldCameras, // Old list of camera configurations
    20                                       psMetadata *newCameras, // New list of camera configurations
    21                                       const char *name, // Name of original camera configuration
    22                                       pmFPALevel mosaicLevel // Level to which we are mosaicking
     36                                      psMetadata *newCameras, // New list of camera configurations
     37                                      const char *name, // Name of original camera configuration
     38                                      pmFPALevel mosaicLevel // Level to which we are mosaicking
    2339    );
    2440
Note: See TracChangeset for help on using the changeset viewer.