IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 12098


Ignore:
Timestamp:
Feb 27, 2007, 4:14:42 PM (19 years ago)
Author:
Paul Price
Message:

Fixing up function to read and interpret orthogonal transfer shifts table. Compiles, but not yet tested.

Location:
trunk/psModules/src/detrend
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/detrend/Makefile.am

    r10610 r12098  
    1111        pmBias.c \
    1212        pmDetrendDB.c \
    13         pmShutterCorrection.c
     13        pmShutterCorrection.c \
     14        pmShifts.c
    1415
    1516#       pmSkySubtract.c
     
    2324        pmBias.h \
    2425        pmDetrendDB.h \
    25         pmShutterCorrection.h
     26        pmShutterCorrection.h \
     27        pmShifts.h
    2628
    2729#       pmSkySubtract.h
  • trunk/psModules/src/detrend/pmShifts.c

    r12010 r12098  
    88#include <pslib.h>
    99
     10#include "pmFPALevel.h"
     11#include "pmFPAUtils.h"
    1012#include "pmShifts.h"
    1113
     
    1315#define SHIFTS_BUFFER 100               // Buffer size for shifts
    1416#define ANALYSIS_NAME "OT.KERNEL"       // Name for kernel on the analysis metadata
     17#define TRACE "psModules.detrend"       // Trace facility
     18
     19// XXX To do:
     20// * Make the table column names configurable, by having a SHIFTS metadata in the camera format, with entries
     21//   specifying the column names.
    1522
    1623
     
    2330} otShifts;
    2431
    25 
    26 bool pmShiftsRead(psFits *fits, pmFPA *fpa, const pmFPAview *phuView)
     32// Allocator for otShifts
     33static otShifts *otShiftsAlloc(void)
     34{
     35    otShifts *shifts = psAlloc(sizeof(otShifts));
     36    shifts->x = psVectorAllocEmpty(SHIFTS_BUFFER, PS_TYPE_S32);
     37    shifts->y = psVectorAllocEmpty(SHIFTS_BUFFER, PS_TYPE_S32);
     38    shifts->t = psVectorAllocEmpty(SHIFTS_BUFFER, PS_TYPE_F32);
     39    shifts->num = 0;
     40    return shifts;
     41}
     42
     43// Look up the cell within a hash; supplement the hash with a new value if it doesn't exist
     44static otShifts *cellVectors(psHash *shifts, // Hash of shifts
     45                             const char *cellName // Key for hash
     46    )
     47{
     48    assert(shifts);
     49    assert(cellName);
     50
     51    // Find the appropriate cell
     52    otShifts *vectors = psHashLookup(shifts, cellName);
     53    if (!vectors) {
     54        vectors = otShiftsAlloc();
     55        psHashAdd(shifts, cellName, vectors);
     56        psFree(vectors);            // Drop reference
     57    }
     58    return vectors;
     59}
     60
     61// Generate a kernel and stuff it on the cell metadata
     62static bool stuffKernel(pmCell *cell,     // Cell to which the shifts belong
     63                        const otShifts *shifts // Shifts to apply
     64    )
     65{
     66    assert(cell);
     67    assert(shifts);
     68
     69    psKernel *kernel = psKernelGenerate(shifts->t, shifts->x, shifts->y, false, true); // Shift kernel
     70    if (!kernel) {
     71        psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to generate kernel from OT shifts");
     72        return false;
     73    }
     74    psMetadataAddPtr(cell->analysis, PS_LIST_TAIL, ANALYSIS_NAME, PS_DATA_KERNEL,
     75                     "Orthogonal transfer kernel, calculated from shifts", kernel);
     76    psFree(kernel);
     77
     78    return true;
     79}
     80
     81
     82bool pmShiftsRead(pmCell *cell, psFits *fits)
    2783{
    2884    PS_ASSERT_PTR_NON_NULL(fits, false);
    29     PS_ASSERT_PTR_NON_NULL(fpa, false);
    30     PS_ASSERT_PTR_NON_NULL(phuView, false);
    31 
    32     pmHDU *phu = pmFPAviewThisHDU(phuView, fpa); // The primary header
    33     if (!phu) {
    34         psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Provided view does not correspond to an HDU.\n");
    35         return false;
    36     }
    37 
    38     psMetadata *format = phu->format;   // Camera format
     85    PS_ASSERT_PTR_NON_NULL(cell, false);
     86
    3987    bool mdok;                          // Status of MD lookup
    40     psMetadata *fileInfo = psMetadataLookupMetadata(&mdok, format, "FILE"); // FILE information from format
     88    psKernel *check = psMetadataLookupPtr(&mdok, cell->analysis, ANALYSIS_NAME); // Kernel, or NULL
     89    if (check) {
     90        psTrace(TRACE, 2, "Cell already has OT kernel present.\n");
     91        return true;                    // No error
     92    }
     93    psTrace(TRACE, 2, "Reading FITS file for OT kernels.\n");
     94
     95    pmChip *chip = cell->parent;        // The parent chip
     96    pmFPA *fpa = chip->parent;          // The parent FPA
     97    pmHDU *phu = NULL;                  // The primary header
     98    pmFPALevel phuLevel = PM_FPA_LEVEL_NONE; // Level of the PHU
     99    long numChips = 0;                  // Number of chips below the PHU; for setting efficient hash size
     100    long numCells = 0;                  // Number of cells below the PHU; for setting efficient hash size
     101    if (fpa->hdu) {
     102        phu = fpa->hdu;
     103        // Count the cells
     104        psArray *chips = fpa->chips;    // Array of chips
     105        numChips = chips->n;
     106        for (int i = 0; i < chips->n; i++) {
     107            pmChip *chip = chips->data[i]; // Chip of interest
     108            numCells += chip->cells->n;
     109        }
     110        numCells = (float)numCells / (float)numChips + 0.5; // Average number of cells per chip
     111        phuLevel = PM_FPA_LEVEL_FPA;
     112    }
     113    if (!phu && chip->hdu) {
     114        phu = chip->hdu;
     115        numChips = 1;
     116        numCells = chip->cells->n;
     117        phuLevel = PM_FPA_LEVEL_CHIP;
     118    }
     119    if (!phu && cell->hdu) {
     120        phu = cell->hdu;
     121        numChips = 0;
     122        numCells = 1;
     123        phuLevel = PM_FPA_LEVEL_CELL;
     124    }
     125
     126    if (!phu || phuLevel == PM_FPA_LEVEL_NONE) {
     127        psError(PS_ERR_UNEXPECTED_NULL, true, "Can't find the PHU.\n");
     128        return false;
     129    }
     130
     131    // Find out what to read
     132    psMetadata *fileInfo = psMetadataLookupMetadata(&mdok, phu->format, "FILE"); // FILE in the format
    41133    if (!mdok || !fileInfo) {
    42134        psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find FILE information in camera format.\n");
     
    49141    }
    50142
    51     int numExt = psFitsGetSize(fits); // Number of extensions in FITS file
     143    // Read the FITS file
    52144    int origExt = psFitsGetExtNum(fits); // Original extension number; to preserve position
    53 
    54     for (int i = 1; i < numExt; i++) {  // Note: shifts table cannot be in PHU!
    55         psFitsMoveExtNum(fits, i, false);
    56         const char *extname = psFitsGetExtName(fits); // Name of extension
    57         if (strcmp(extname, shiftsExt) == 0) {
    58             psArray *table = psFitsReadTable(fits); // The table of shifts
    59             if (!table) {
    60                 psError(PS_ERR_IO, false, "Unable to read shifts table.\n");
     145    if (!psFitsMoveExtName(fits, shiftsExt)) {
     146        psError(PS_ERR_IO, false, "Unable to move to shifts extension %s", shiftsExt);
     147        return false;
     148    }
     149    psArray *table = psFitsReadTable(fits); // The table of shifts
     150    if (!table) {
     151        psError(PS_ERR_IO, false, "Unable to read shifts table.\n");
     152        return false;
     153    }
     154
     155    // More sensible storage
     156    otShifts *singleShifts = NULL;      // Shifts for a single cell
     157    psHash *multipleShifts = NULL;      // Shifts for multiple cells, stored by cell name
     158    switch (phuLevel) {
     159      case PM_FPA_LEVEL_FPA:
     160        multipleShifts = psHashAlloc(2 * numChips);
     161        break;
     162      case PM_FPA_LEVEL_CHIP:
     163        multipleShifts = psHashAlloc(2 * numCells);
     164        break;
     165      case PM_FPA_LEVEL_CELL:
     166        singleShifts = otShiftsAlloc();
     167        break;
     168      default:
     169        psAbort("Should never get here.\n");
     170    }
     171
     172    // Pull values out of the table into something a bit more sensible
     173    for (int i = 0; i < table->n; i++) {
     174        psMetadata *row = table->data[i]; // The row of interest
     175
     176        const char *chipName;           // Name of chip
     177        if (phuLevel == PM_FPA_LEVEL_FPA) {
     178            // Only care about the chip name if there's more than one chip
     179            chipName = psMetadataLookupStr(&mdok, row, "Chip");
     180            if (!mdok || !chipName) {
     181                psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find Chip in row %d of shifts table\n", i);
     182                psFree(multipleShifts);
     183                psFree(table);
    61184                return false;
    62185            }
    63 
    64             // Pull values out of the table into something a bit more sensible
    65             psHash *shifts = psHashAlloc(HASH_SIZE); // Shifts for each cell
    66             for (int i = 0; i < table->n; i++) {
    67                 psMetadata *row = table->data[i]; // The row of interest
    68                 const char *name = psMetadataLookupStr(&mdok, row, "Cell"); // Name of cell
    69                 if (!mdok || !name) {
    70                     psError(PS_ERR_UNEXPECTED_NULL, true,
    71                             "Unable to find Cell in row %d of shifts table\n", i);
    72                     psFree(shifts);
    73                     psFree(table);
    74                     return false;
    75                 }
    76                 float x = psMetadataLookupS32(&mdok, row, "X"); // Shift in x
    77                 if (!mdok) {
    78                     psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find X in row %d of shifts table\n", i);
    79                     psFree(shifts);
    80                     psFree(table);
    81                     return false;
    82                 }
    83                 float y = psMetadataLookupF32(&mdok, row, "Y"); // Shift in y
    84                 if (!mdok) {
    85                     psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find Y in row %d of shifts table\n", i);
    86                     psFree(shifts);
    87                     psFree(table);
    88                     return false;
    89                 }
    90                 float t = psMetadataLookupF32(&mdok, row, "Time"); // Time of shift
    91                 if (!mdok) {
    92                     psError(PS_ERR_UNEXPECTED_NULL, true,
    93                             "Unable to find Time in row %d of shifts table\n", i);
    94                     psFree(shifts);
    95                     psFree(table);
    96                     return false;
    97                 }
    98 
    99                 // Find the appropriate cell
    100                 otShifts *vectors = psHashLookup(shifts, name); // Shifts for the cell of interest
    101                 if (!vectors) {
    102                     vectors = psAlloc(sizeof(otShifts));
    103                     vectors->x = psVectorAllocEmpty(SHIFTS_BUFFER, PS_TYPE_S32);
    104                     vectors->y = psVectorAllocEmpty(SHIFTS_BUFFER, PS_TYPE_S32);
    105                     vectors->t = psVectorAllocEmpty(SHIFTS_BUFFER, PS_TYPE_F32);
    106                     vectors->num = 0;
    107                     psHashAdd(shifts, name, vectors);
    108                 }
    109 
    110                 // Add the shift
    111                 psVectorExtend(cell->x, 1, SHIFTS_BUFFER);
    112                 psVectorExtend(cell->y, 1, SHIFTS_BUFFER);
    113                 psVectorExtend(cell->t, 1, SHIFTS_BUFFER);
    114                 vectors->x->data.S32[vectors->num] = (int)x;
    115                 vectors->y->data.S32[vectors->num] = (int)y;
    116                 vectors->t->data.F32[vectors->num] = t;
    117                 vectors->num++;
     186        }
     187        const char *cellName;           // Name of cell
     188        if (phuLevel <= PM_FPA_LEVEL_CHIP) {
     189            // Only care about the cell name if there's a chip
     190            cellName = psMetadataLookupStr(&mdok, row, "Cell");
     191            if (!mdok || !cellName) {
     192                psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find Cell in row %d of shifts table\n", i);
     193                psFree(multipleShifts);
     194                psFree(table);
     195                return false;
    118196            }
     197        }
     198        float x = psMetadataLookupS32(&mdok, row, "X"); // Shift in x
     199        if (!mdok) {
     200            psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find X in row %d of shifts table\n", i);
     201            psFree(multipleShifts);
    119202            psFree(table);
    120 
    121             // Put the kernels into their own cells
    122             psList *names = psHashKeyList(shifts); // List of cells
    123             psListIterator *namesIter = psListIteratorAlloc(names, PS_LIST_HEAD, false); // Iterator for names
    124             while ((name = psListGetAndIncrement(namesIter))) {
    125                 pmChip *chip = NULL;    // Chip of interest
    126                 pmCell *cell = NULL;    // Cell of interest
    127                 if (phuView->chip != -1) {
    128                     chip = pmFPAviewThisChip(phuView, chip);
    129                     cell = pmChipFindCell(chip, name);
    130                 } else {
    131                     psList *chipCell = psStringSplit(name, ":|,", false); // The chip and cell
    132                     if (chipCell->n != 2) {
    133                         psError(PS_ERR_BAD_PARAMETER_VALUE, true,
    134                                 "Cannot determine chip and cell names from %s\n", name);
    135                         psFree(chipCell);
    136                         psFree(namesIter);
    137                         psFree(names);
    138                         psFree(shifts);
    139                         return false;
    140                     }
    141                     const char *chipName = psListGet(chipCell, PS_LIST_HEAD); // Name of chip
    142                     const char *cellName = psListGet(chipCell, PS_LIST_TAIL); // Name of cell
    143                     chip = pmFPAFindChip(fpa, chipName);
    144                     if (!chip) {
    145                         psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find chip %s", chipName);
    146                         psFree(chipCell);
    147                         psFree(namesIter);
    148                         psFree(names);
    149                         psFree(shifts);
    150                         return false;
    151                     }
    152                     cell = pmChipFindCell(chip, cellName);
    153                     psFree(chipCell);
    154                 }
    155 
    156                 if (!cell) {
    157                     psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find chip %s", chipName);
    158                     psFree(namesIter);
    159                     psFree(names);
    160                     psFree(shifts);
    161                     return false;
    162                 }
    163 
    164                 otShifts *vectors = psHashLookup(shifts, name); // Shifts for the cell of interest
    165                 psKernel *kernel = psKernelGenerate(vectors->t, vectors->x, vectors->y,
    166                                                     false, true); // Shift kernel
    167                 if (!kernel) {
    168                     psError(PS_ERR_UNEXPECTED_NULL, false,
    169                             "Unable to generate kernel from OT shifts for %s", name);
    170                     psFree(shifts);
    171                     psFree(namesIter);
    172                     psFree(names);
    173                     return false;
    174                 }
    175                 psMetadataAddPtr(cell->analysis, PS_LIST_TAIL, ANALYSIS_NAME, PS_DATA_KERNEL,
    176                                  "Orthogonal transfer kernel, calculated from shifts", kernel);
    177                 psFree(kernel);
     203            return false;
     204        }
     205        float y = psMetadataLookupF32(&mdok, row, "Y"); // Shift in y
     206        if (!mdok) {
     207            psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find Y in row %d of shifts table\n", i);
     208            psFree(multipleShifts);
     209            psFree(table);
     210            return false;
     211        }
     212        float t = psMetadataLookupF32(&mdok, row, "Time"); // Time of shift
     213        if (!mdok) {
     214            psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find Time in row %d of shifts table\n", i);
     215            psFree(multipleShifts);
     216            psFree(table);
     217            return false;
     218        }
     219
     220        otShifts *shifts = NULL;        // Shifts for the cell of interest
     221        switch (phuLevel) {
     222          case PM_FPA_LEVEL_FPA: {
     223              psHash *cells = psHashLookup(multipleShifts, chipName); // Hash of cells
     224              if (!cells) {
     225                  cells = psHashAlloc(numCells);
     226                  psHashAdd(multipleShifts, chipName, cells);
     227                  psFree(cells);          // Drop reference
     228              }
     229              shifts = cellVectors(cells, cellName);
     230              break;
     231          }
     232          case PM_FPA_LEVEL_CHIP:
     233            shifts = cellVectors(multipleShifts, cellName);
     234            break;
     235          case PM_FPA_LEVEL_CELL:
     236            shifts = singleShifts;
     237            break;
     238          default:
     239            psAbort("Should never get here.\n");
     240        }
     241
     242        // Add the shift
     243        psVectorExtend(shifts->x, 1, SHIFTS_BUFFER);
     244        psVectorExtend(shifts->y, 1, SHIFTS_BUFFER);
     245        psVectorExtend(shifts->t, 1, SHIFTS_BUFFER);
     246        shifts->x->data.S32[shifts->num] = (int)x;
     247        shifts->y->data.S32[shifts->num] = (int)y;
     248        shifts->t->data.F32[shifts->num] = t;
     249        shifts->num++;
     250    }
     251    psFree(table);
     252
     253    // Put the kernels into their own cells
     254    if (phuLevel == PM_FPA_LEVEL_CELL) {
     255        // Only a single cell
     256        if (!stuffKernel(cell, singleShifts)) {
     257            psFree(singleShifts);
     258            return false;
     259        }
     260        psFree(singleShifts);
     261    } else {
     262        psList *names = psHashKeyList(multipleShifts); // List of hash keys (chip/cell names)
     263        psListIterator *namesIter = psListIteratorAlloc(names, PS_LIST_HEAD, false); // Iterator for names
     264        const char *name;               // Name, from iteration
     265        while ((name = psListGetAndIncrement(namesIter))) {
     266            switch (phuLevel) {
     267              case PM_FPA_LEVEL_FPA: {
     268                  int chipNum = pmFPAFindChip(fpa, name); // Number of chip of interest
     269                  if (chipNum < 0) {
     270                      psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find chip %s", name);
     271                      psFree(namesIter);
     272                      psFree(names);
     273                      psFree(multipleShifts);
     274                      return false;
     275                  }
     276                  pmChip *chip = fpa->chips->data[chipNum]; // Chip of interest
     277
     278                  // Loop over component cells
     279                  psHash *cells = psHashLookup(multipleShifts, name); // Hash of cells
     280                  psList *cellNames = psHashKeyList(multipleShifts); // List of hash keys (cell names)
     281                  psListIterator *cellNamesIter = psListIteratorAlloc(cellNames, PS_LIST_HEAD, false);
     282                  const char *cellName;       // Cell name, from iteration
     283                  while ((cellName = psListGetAndIncrement(cellNamesIter))) {
     284                      int cellNum = pmChipFindCell(chip, cellName); // Number of cell of interest
     285                      if (!cell) {
     286                          psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find cell %s", cellName);
     287                          psFree(cellNamesIter);
     288                          psFree(cellNames);
     289                          psFree(namesIter);
     290                          psFree(names);
     291                          psFree(multipleShifts);
     292                          return false;
     293                      }
     294                      pmCell *cell = chip->cells->data[cellNum]; // Cell of interest
     295
     296                      otShifts *vectors = psHashLookup(cells, cellName); // Shifts for the cell of interest
     297                      if (!stuffKernel(cell, vectors)) {
     298                          psFree(cellNamesIter);
     299                          psFree(cellNames);
     300                          psFree(namesIter);
     301                          psFree(names);
     302                          psFree(multipleShifts);
     303                          return false;
     304                      }
     305                  }
     306                  psFree(cellNamesIter);
     307                  psFree(cellNames);
     308                  break;
     309              }
     310              case PM_FPA_LEVEL_CHIP: {
     311                  int cellNum = pmChipFindCell(chip, name); // Number of cell of interest
     312                  if (!cell) {
     313                      psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find cell %s", name);
     314                      psFree(namesIter);
     315                      psFree(names);
     316                      psFree(multipleShifts);
     317                      return false;
     318                  }
     319                  pmCell *cell = chip->cells->data[cellNum]; // Cell of interest
     320
     321                  otShifts *vectors = psHashLookup(multipleShifts, name); // Shifts for this cell
     322                  if (!stuffKernel(cell, vectors)) {
     323                      psFree(namesIter);
     324                      psFree(names);
     325                      psFree(multipleShifts);
     326                      return false;
     327                  }
     328                  break;
     329              }
     330              default:
     331                psAbort("Should never get here.\n");
    178332            }
    179             psFree(namesIter);
    180             psFree(names);
    181             psFree(shifts);
    182 
    183             break;
    184         }
    185     }
    186 
    187     // reposition to the original position
     333        }
     334        psFree(namesIter);
     335        psFree(names);
     336        psFree(multipleShifts);
     337    }
     338
     339    // Go back to the original position in the FITS file
    188340    return psFitsMoveExtNum(fits, origExt, false);
    189341}
  • trunk/psModules/src/detrend/pmShifts.h

    r12010 r12098  
    44#include <pslib.h>
    55#include "pmFPA.h"
    6 #include "pmFPAview.h"
    76
    8 /// Read any orthogonal transfer shifts extension in a FITS file
     7/// Read orthogonal transfer shifts table for a cell
    98///
    10 /// Given a FITS file (typically newly opened ready for processing), this function searches for the extension
    11 /// specified by the SHIFTS keyword within the FILE information in the camera format.  If the extension is
    12 /// found, the shifts table is read and translated into kernels which are placed in the analysis metadata of
    13 /// each cell.
    14 bool pmShiftsRead(psFits *fits,         ///< FITS file in which to search for OT shifts extension
    15                   pmFPA *fpa,           ///< FPA containing the cells that own the shifts
    16                   const pmFPAview *phuView ///< View of the PHU; specifies which chip(s) owns the cells
    17     );
     9/// Given a cell, this function searches for the orthogonal transfer shifts for this cell in the supplied FITS
     10/// file.  The FITS extension containing the shifts table is specified by the SHIFTS keyword within the FILE
     11/// information in the camera format.  If the extension is found, the shifts table is read and translated into
     12/// kernels which are placed in the analysis metadata of each cell.  Note that this operation is performed on
     13/// all cells within the FITS file (or at least, those contained within the shifts table), not just the cell
     14/// provided --- if we have to read the whole table, we may as well translate the whole lot.  If a kernel is
     15/// already present in the cell analysis metadata, the function returns true without doing any work.
     16bool pmShiftsRead(pmCell *cell,         ///< Cell for which to search for shifts
     17                  psFits *fits          ///< FITS file in which to search for OT shifts extension
     18                  );
    1819
    1920
Note: See TracChangeset for help on using the changeset viewer.