IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Mar 10, 2006, 5:20:10 PM (20 years ago)
Author:
Paul Price
Message:

Changing concepts to only get stuff as the source becomes available; nearly done

File:
1 edited

Legend:

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

    r6552 r6570  
    77#include "psAdditionals.h"
    88
     9//////////////////////////////////////////////////////////////////////////////////////////////////////////////
     10// File-static functions
     11//////////////////////////////////////////////////////////////////////////////////////////////////////////////
    912
    1013static bool compareConcepts(psMetadataItem *item1, // First item to compare
     
    6770}
    6871
     72// Format a single concept
     73static psMetadataItem *conceptFormat(pmConceptSpec *spec, // The concept specification
     74                                     psMetadataItem *concept, // The concept to parse
     75                                     psMetadata *cameraFormat, // The camera format
     76                                     pmFPA *fpa, // The FPA
     77                                     pmChip *chip, // The chip
     78                                     pmCell *cell // The cell
     79                                    )
     80{
     81    if (concept) {
     82        psMetadataItem *formatted = NULL;  // The formatted concept
     83        if (spec->format) {
     84            formatted = spec->format(concept, cameraFormat, fpa, chip, cell);
     85        } else {
     86            formatted = psMemIncrRefCounter(concept);
     87        }
     88
     89        return formatted;
     90    }
     91}
     92
     93static bool writeHeader(pmHDU *hdu,     // HDU for which to add to the header
     94                        const char *keyword, // Keyword to add
     95                        psMetadataItem *item // Item to add to the header
     96                       )
     97{
     98    switch (item->type) {
     99    case PS_DATA_STRING:
     100        return psMetadataAddStr(hdu->header, PS_LIST_TAIL, keyword, PS_META_REPLACE, item->comment,
     101                                item->data.V);
     102    case PS_DATA_S32:
     103        return psMetadataAddS32(hdu->header, PS_LIST_TAIL, keyword, PS_META_REPLACE, item->comment,
     104                                item->data.S32);
     105    case PS_DATA_F32:
     106        return psMetadataAddF32(hdu->header, PS_LIST_TAIL, keyword, PS_META_REPLACE, item->comment,
     107                                item->data.F32);
     108    case PS_DATA_F64:
     109        return psMetadataAddF64(hdu->header, PS_LIST_TAIL, keyword, PS_META_REPLACE, item->comment,
     110                                item->data.F64);
     111    default:
     112        psLogMsg(__func__, PS_LOG_WARN, "Type of %s is not suitable for a FITS header --- not added.\n",
     113                 item->name);
     114        return false;
     115    }
     116}
     117
     118
     119//////////////////////////////////////////////////////////////////////////////////////////////////////////////
     120// Public functions
     121//////////////////////////////////////////////////////////////////////////////////////////////////////////////
     122
     123bool pmConceptsWriteToCamera(psMetadata *specs, // The concept specifications
     124                             pmCell *cell,   // The cell
     125                             psMetadata *concepts // The concepts
     126                            )
     127{
     128    if (cell) {
     129        pmHDU *hdu = getLowestHDU(NULL, NULL, cell); // The HDU at the lowest level
     130        psMetadata *cameraFormat = hdu->format; // The camera format
     131        psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
     132        psMetadataItem *specItem = NULL;    // Item from the specs metadata
     133        while ((specItem = psMetadataGetAndIncrement(specsIter))) {
     134            pmConceptSpec *spec = specItem->data.V; // The specification
     135            psString name = specItem->name; // The concept name
     136            psMetadataItem *cameraItem = psMetadataLookup(cell->config, name); // The concept from the camera,
     137            // or NULL
     138            if (cameraItem) {
     139                // Grab the concept
     140                psMetadataItem *conceptItem = psMetadataLookup(concepts, name); // The concept
     141                // Formatted version
     142                psMetadataItem *formatted = conceptFormat(spec, conceptItem, cameraFormat, NULL, NULL, cell);
     143                psString nameSource = NULL; // String with the concept name and ".SOURCE" added
     144                psStringAppend(nameSource, "%s.SOURCE", name);
     145                bool mdok = true;       // Status of MD lookup
     146                psString source = psMetadataLookupStr(&mdok, cell->config, nameSource); // The source
     147                if (mdok && strlen(source) > 0) {
     148                    if (strcasecmp(source, "HEADER") == 0) {
     149                        if (cameraItem->type != PS_DATA_STRING) {
     150                            psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by header, but is not "
     151                                     "of type STR --- ignored.\n", conceptItem->name)
     152                            continue;
     153                        }
     154                        writeHeader(hdu, cameraItem->data.V, formatted);
     155                        continue;
     156                    }
     157                    if (strcasecmp(source, "VALUE") == 0) {
     158                        if (! compareConcepts(cameraItem, formatted)) {
     159                            psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by value in the camera "
     160                                     "format, but the values don't match.\n");
     161                        }
     162                        continue;
     163                    }
     164                    psLogMsg(__func__, PS_LOG_WARN, "Concept source %s isn't HEADER or VALUE --- can't "
     165                             "write\n", nameSource);
     166                    continue;
     167                }
     168                // Assume it's specified by value
     169                if (! compareConcepts(cameraItem, formatted)) {
     170                    psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by value in the camera "
     171                             "format, but the values don't match.\n");
     172                }
     173            }
     174
     175        }
     176        psFree(specsIter);
     177        return true;
     178    }
     179    return false;
     180}
     181
     182
     183bool pmConceptsWriteToDefault(psMetadata *specs, // The concept specifications
     184                              pmFPA *fpa, // The FPA
     185                              pmChip *chip, // The chip
     186                              pmCell *cell, // The cell
     187                              psMetadata *concepts // The concepts
     188                             )
     189{
     190    bool mdok = true;               // Status of MD lookup
     191    psMetadata *defaults = psMetadataLookupMD(&mdok, cameraFormat, "DEFAULTS"); // The DEFAULTS spec
     192    if (mdok && defaults) {
     193        pmHDU *hdu = getLowestHDU(fpa, chip, cell); // The HDU at the lowest level
     194        psMetadata *cameraFormat = hdu->format; // The camera format
     195        psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
     196        psMetadataItem *specItem = NULL;    // Item from the specs metadata
     197        while ((specItem = psMetadataGetAndIncrement(specsIter))) {
     198            pmConceptSpec *spec = specItem->data.V; // The specification
     199            psString name = specItem->name; // The concept name
     200            psMetadataItem *defaultItem = psMetadataLookup(defaults, name); // The item from the DEFAULTS
     201            if (defaultItem) {
     202                psMetadataItem *conceptItem = psMetadataLookup(concepts, name); // The item from the concepts
     203                psMetadataItem *formatted = conceptFormat(spec, conceptItem, cameraFormat, fpa, chip, cell);
     204                if (! compareConcepts(cameraItem, formatted)) {
     205                    psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by the DEFAULTS in the camera "
     206                             "format, but the values don't match.\n");
     207                }
     208            }
     209        }
     210        psFree(specsIter);
     211        return true;
     212    }
     213    return false;
     214}
     215
     216// XXX need to write multiple headers if I get a list
     217bool pmConceptsWriteToHeader(psMetadata *specs, // The concept specifications
     218                             pmFPA *fpa, // The FPA
     219                             pmChip *chip, // The chip
     220                             pmCell *cell, // The cell
     221                             psMetadata *concepts // The concepts
     222                            )
     223{
     224    bool mdok = true;               // Status of MD lookup
     225    psMetadata *translation = psMetadataLookupMD(&mdok, cameraFormat, "TRANSLATION"); // The TRANSLATION spec
     226    if (mdok && translation) {
     227        pmHDU *hdu = getLowestHDU(fpa, chip, cell); // The HDU at the lowest level
     228        psMetadata *cameraFormat = hdu->format; // The camera format
     229        psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
     230        psMetadataItem *specItem = NULL;    // Item from the specs metadata
     231        while ((specItem = psMetadataGetAndIncrement(specsIter))) {
     232            pmConceptSpec *spec = specItem->data.V; // The specification
     233            psString name = specItem->name; // The concept name
     234            psMetadataItem *headerItem = psMetadataLookup(translation, name); // The item from the TRANSLATION
     235            if (headerItem) {
     236                if (headerItem->type != PS_DATA_STRING) {
     237                    psLogMsg(__func__, PS_LOG_WARN, "TRANSLATION keyword for concept %s isn't of type STR ---"
     238                             " ignored.", name);
     239                    continue;
     240                }
     241                psMetadataItem *conceptItem = psMetadataLookup(concepts, name); // The item from the concepts
     242                psMetadataItem *formatted = conceptFormat(spec, conceptItem, cameraFormat, fpa, chip, cell);
     243                psList *keywords = psStringSplit(headerItem->data.V, " ,;"); // List of header keywords
     244                if (formatted->type == PS_DATA_LIST) {
     245                    psList *values = formatted->data.V; // The values for the headers
     246                    if (values->n != keywords->n) {
     247                        psLogMsg(__func__, PS_LOG_WARN, "Number of headers specified does not match number "
     248                                 "of values for concept %s.\n", name);
     249                    }
     250                    psListIterator *valuesIter = psListIteratorAlloc(values, PS_LIST_HEAD, false); // Iterator
     251                    psListIterator *keywordsIter = psListIteratorAlloc(keywords, PS_LIST_HEAD, false);
     252                    psMetadataItem *valuesItem = NULL; // Item from list
     253                    while ((valuesItem = psListGetAndIncrement(valuesIter))) {
     254                        psString keyword = psListGetAndIncrement(keywordsIter); // Keyword from the list
     255                        if (strlen(keyword) > 0) {
     256                            writeHeader(hdu, keyword, formatted);
     257                        }
     258                    }
     259                    psFree(valuesIter);
     260                    psFree(keywordsIter);
     261                } else {
     262                    psString keyword = psListGet(keywords, PS_LIST_HEAD); // The keyword
     263                    writeHeader(hdu, keyword, formatted);
     264                }
     265            }
     266        }
     267        psFree(specsIter);
     268        return true;
     269    }
     270    return false;
     271}
     272
     273
     274bool pmConceptsWriteToDatabase(psMetadata *specs, // The concept specifications
     275                               pmFPA *fpa, // The FPA
     276                               pmChip *chip, // The chip
     277                               pmCell *cell, // The cell
     278                               psDB *db,// The database handle
     279                               psMetadata *concepts // The concepts
     280                              )
     281{
     282    bool mdok = true;               // Status of MD lookup
     283    psMetadata *database = psMetadataLookupMD(&mdok, cameraFormat, "DATABASE"); // The DATABASE spec
     284    if (mdok && database) {
     285        pmHDU *hdu = getLowestHDU(fpa, chip, cell); // The HDU at the lowest level
     286        psMetadata *cameraFormat = hdu->format; // The camera format
     287        psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
     288        psMetadataItem *specItem = NULL;    // Item from the specs metadata
     289        while ((specItem = psMetadataGetAndIncrement(specsIter))) {
     290            pmConceptSpec *spec = specItem->data.V; // The specification
     291            psString name = specItem->name; // The concept name
     292
     293            psMetadataItem *dbItem = psMetadataLookup(&mdok, database, name); // The item from the DATABASE
     294            if (dbItem) {
     295                if (dbItem->type != PS_DATA_METADATA) {
     296                    psLogMsg(__func__, PS_LOG_WARN, "DATABASE keyword for concept %s isn't of type METADATA "
     297                             "--- ignored.\n", name);
     298                    continue;
     299                }
     300
     301                psMetadataItem *conceptItem = psMetadataLookup(concepts, name); // The item from the concepts
     302                psMetadataItem *formatted = conceptFormat(spec, conceptItem, cameraFormat, fpa, chip, cell);
     303
     304                psMetadata *dbLookup = dbItem->data.V; // How to look up the value of interest
     305                // Name of the table
     306                const char *tableName = psMetadataLookupStr(&mdStatus, dbLookup, "TABLE");
     307                // Name of "where" columns
     308                const char *givenCols = psMetadataLookupStr(&mdStatus, dbLookup, "GIVENDBCOL");
     309                // Values for "where" columns
     310                const char *givenPS = psMetadataLookupStr(&mdStatus, dbLookup, "GIVENPS");
     311
     312                // Now, need to get the "given"s
     313                if (strlen(givenCols) || strlen(givenPS)) {
     314                    psList *cols = psStringSplit(givenCols, ",;"); // List of column names
     315                    psList *values = psStringSplit(givenPS, ",;"); // List of value names for the columns
     316                    psMetadata *selection = psMetadataAlloc(); // The stuff to select in the DB
     317                    if (cols->n != values->n) {
     318                        psLogMsg(__func__, PS_LOG_WARN,
     319                                 "The GIVENDBCOL and GIVENPS entries for %s do not have "
     320                                 "the same number of entries --- ignored.\n", concept);
     321                    } else {
     322                        // Iterators for the lists
     323                        psListIterator *colsIter = psListIteratorAlloc(cols, PS_LIST_HEAD, false);
     324                        psListIterator *valuesIter = psListIteratorAlloc(values, PS_LIST_HEAD, false);
     325                        char *column = NULL;    // Name of the column
     326                        while ((column = psListGetAndIncrement(colsIter))) {
     327                            char *name = psListGetAndIncrement(valuesIter); // Name for the value
     328                            if (!strlen(column) || !strlen(name)) {
     329                                psLogMsg(__func__, PS_LOG_WARN, "One of the columns or value names for %s is "
     330                                         " empty --- ignored.\n", concept);
     331                            } else {
     332                                // Search for the value name
     333                                psMetadataItem *item = pmConceptReadFromHeader(fpa, chip, cell, name);
     334                                if (! item) {
     335                                    item = pmConceptReadFromDefault(fpa, chip, cell, name);
     336                                }
     337                                if (! item) {
     338                                    psLogMsg(__func__, PS_LOG_ERROR,
     339                                             "Unable to find the value name %s for DB "
     340                                             " lookup on %s --- ignored.\n", name, concept);
     341                                } else {
     342                                    // We need to create a new psMetadataItem.  I don't think we can't simply
     343                                    // hack the existing one, since that could conceivably cause memory leaks
     344                                    psMetadataAddItem(selection, formatted, PS_LIST_TAIL, PS_META_REPLACE);
     345                                    psFree(formatted);
     346                                }
     347                            }
     348                            psFree(name);
     349                            psFree(column);
     350                        } // Iterating through the columns
     351                        psFree(colsIter);
     352                        psFree(valuesIter);
     353
     354                        // Check first to make sure we're only going to touch one row
     355                        psArray *dbResult = psDBSelectRows(db, tableName, selection, 2); // Lookup result
     356                        // Note that we use limit=2 in order to test if there are multiple rows returned
     357                        if (! dbResult || dbResult->n == 0) {
     358                            psLogMsg(__func__, PS_LOG_WARN, "Unable to find any rows in DB for %s --- "
     359                                     "ignored\n", concept->name);
     360                            return false;
     361                        } else {
     362                            if (dbResult->n > 1) {
     363                                psLogMsg(__func__, PS_LOG_WARN, "Multiple rows returned in DB lookup for %s "
     364                                         "--- ignored.\n", concept->name);
     365                            }
     366                            // Update the DB
     367                            psMetadata *update = psMetadataAlloc();
     368                            psMetadataAddItem(update, concept, PS_LIST_HEAD, 0);
     369                            psDBUpdateRows(db, tableName, selection, update);
     370                            psFree(update);
     371                            return true;
     372                        }
     373                    }
     374                    psFree(cols);
     375                    psFree(values);
     376                } // Doing the "given"s.
     377            }
     378        }
     379        psFree(specsIter);
     380        return true;
     381    }
     382    return false;
     383}
     384
     385
     386
     387
     388#if 0
    69389
    70390// Well, not really "write", but check to make sure it's there and matches
     
    368688}
    369689
     690#endif
Note: See TracChangeset for help on using the changeset viewer.