IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 31011 for trunk/ippToPsps/src


Ignore:
Timestamp:
Mar 22, 2011, 4:11:23 PM (15 years ago)
Author:
rhenders
Message:

Using new Fits class and Config class

Location:
trunk/ippToPsps/src
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/ippToPsps/src/Batch.c

    r30968 r31011  
    1818#include <pslib.h>
    1919#include <psmodules.h>
     20
    2021#include "Batch.h"
    2122
     
    6263        if (this->exitCode != PS_EXIT_SUCCESS) {
    6364
    64             psError(PS_ERR_UNKNOWN, false, "Failed, so deleting %s", this->fitsOutPath);
    65 
    66             // if process failed, we need to delete that FITS file
    67             if (remove(this->fitsOutPath) == -1) {
    68 
    69                 psError(PS_ERR_UNKNOWN, false, "Unable to delete %s", this->fitsOutPath);
    70             }
     65            psError(PS_ERR_UNKNOWN, false, "Failed, so deleting fits file");
     66            this->fitsOut->delete(this->fitsOut);
    7167        }
    72         // ...otherwise, close file
    73         else {
    74 
    75             int status = 0;
    76             if (fits_close_file(this->fitsOut, &status)) {
    77 
    78                 psError(PS_ERR_IO, false, "Unable to close FITS file %s", this->fitsOutPath);
    79                 fits_report_error(stderr, status);
    80             }
    81         }
     68
     69        this->fitsOut->destroy(this->fitsOut);
    8270    }
    8371
     
    9987    if (this->dvoConfig != NULL) dvoConfigFree(this->dvoConfig);
    10088
    101     ippToPspsConfig_Destructor(this->config);
     89    this->config->destroy(this->config);
    10290
    10391    pmConfigDone();
     
    151139  Sets-up and reads command-line arguments
    152140*/
    153 static bool parseArguments(Batch* this, int argc, char **argv) {
     141static bool parseArguments(Batch* this, int argc, char **argv, char* configsDir, char* fitsOutFile) {
    154142
    155143    // first deal with DVO database
     
    178166    haveSurveyType = false;
    179167
     168    char fitsOutPath[1000];
     169    char configsBaseDir[1000];
     170
    180171    // decode arguments
    181172    int32_t optind = 1;
     
    193184            else if(strcmp(sw, "-output") == 0 ) {
    194185                optind++; if( optind > ( argc-1 ) ) break;
    195                 strcpy(this->fitsOutPath, argv[optind]);
     186                strcpy(fitsOutPath, argv[optind]);
    196187                haveFitsOutPath = true;
    197188            }
     
    203194            else if(strcmp(sw, "-config") == 0 ) {
    204195                optind++; if( optind > ( argc-1 ) ) break;
    205                 strcpy(this->configsDir, argv[optind]);
     196                strcpy(configsBaseDir, argv[optind]);
    206197                haveConfig = true;
    207198            }
     
    220211
    221212
    222     // setup command line arguments
    223     //psMetadataAddStr(this->arguments, PS_LIST_TAIL, "-survey", 0, "Survey type", NULL);
    224 
    225 
    226     // now check rest of arguments
    227     //if (argc < 2 || !psArgumentParse(this->arguments, &argc, argv)) {
    228 
    229       //  usage(this, argv[0]);
    230         //this->exitCode = PS_EXIT_CONFIG_ERROR;
    231         //return false;
    232    // }
    233 
    234     //this->surveyType = psMemIncrRefCounter(psMetadataLookupStr(NULL, this->arguments, "-survey"));
    235213
    236214    if (haveFitsInPath && !readInputFilePaths(this)) {
     
    240218    }
    241219
    242     return true;
    243 }
    244 
    245 /**
    246   Initialises file paths, creates FITS file etc
    247   */
    248 bool init(Batch* this) {
    249 
    250220    // create a config object
    251     this->config = ippToPspsConfig_Constructor(this->configsDir);
     221    strcat(configsBaseDir, configsDir);
     222    this->config = new_Config(configsBaseDir);
    252223    if (this->config == NULL) {
    253224
     
    257228
    258229    // get survey ID using config object
    259     if (strlen(this->surveyType) > 0 && !ippToPspsConfig_getSurveyId(this->config, this->surveyType, &this->surveyID)) {
     230    if (strlen(this->surveyType) > 0 && !this->config->getSurveyId(this->config, this->surveyType, &this->surveyID)) {
    260231
    261232        this->exitCode = PS_EXIT_CONFIG_ERROR;
     
    263234    }
    264235    // create full FITS out path
    265     sprintf (this->fitsOutPath, "%s/%s", this->fitsOutPath, this->fitsOutFile);
     236    sprintf (fitsOutPath, "%s/%s", fitsOutPath, fitsOutFile);
    266237
    267238    // create an output FITS file
    268     int status=0;
    269     if (fits_create_file(&this->fitsOut, this->fitsOutPath, &status)) {
    270         fits_report_error(stderr, status);
    271         psError(PS_ERR_IO, false, "Unable to create file at: '%s'", this->fitsOutPath);
    272         this->exitCode = PS_EXIT_SYS_ERROR;
    273         this->fitsOut = NULL;
    274         return false;
    275     }
     239    this->fitsOut = new_Fits(fitsOutPath);
     240    if (this->fitsOut->getFilePtr(this->fitsOut) == NULL) return false;
    276241
    277242    // create XML document for results
     
    281246        xmlNodePtr rootNode = xmlNewNode(NULL, BAD_CAST "ippToPsps_Results");
    282247        xmlDocSetRootElement(this->resultsXmlDoc, rootNode);
    283         xmlNewChild(rootNode, NULL, BAD_CAST "filename", BAD_CAST this->fitsOutFile);
     248        xmlNewChild(rootNode, NULL, BAD_CAST "filename", BAD_CAST fitsOutFile);
    284249    }
    285250
     
    298263    printf("* numOfInputFiles : %d\n", this->numOfInputFiles);
    299264    printf("* fitsInPath      : '%s'\n", this->fitsInPath);
    300     printf("* fitsOutFile     : '%s'\n", this->fitsOutFile);
    301     printf("* fitsOutPath     : '%s'\n", this->fitsOutPath);
    302     printf("* configsDir      : '%s'\n", this->configsDir);
    303265}
    304266
     
    359321    // set up function pointers
    360322    this->parseArguments = parseArguments;
    361     this->init = init;
     323    //this->init = init;
    362324    this->print = print;
    363325    this->destroy = destroy;
  • trunk/ippToPsps/src/Batch.h

    r30968 r31011  
    1818#include <libxml/tree.h>
    1919
     20#include "Fits.h"
     21
    2022/**
    2123  Abstract base class for all batches. Known subclasses are:
     
    2527  - StackBatch
    2628
    27   All subclasses need to implement the run() method and may need to implenent print() and/or init()
     29  All subclasses need to implement the run() method and may need to implenent print()
    2830  */
    2931typedef struct Batch {
     
    3739    uint16_t numOfInputFiles;   // number of input files
    3840    char** inputFiles;          // array of input file names
    39     char fitsOutFile[100];      // FITS output filename
    40     char fitsOutPath[1000];     // path to FITS output
    41     fitsfile *fitsOut;          // output FITS file
    42     char configsDir[500];       // path to IPP/PSPS mapping file
     41    Fits *fitsOut;              // output FITS file
    4342    pmConfig* pmconfig;         // pmConfig
    4443    dvoConfig* dvoConfig;       // dvo database
    45     IppToPspsConfig* config;    // config structure
     44    Config* config;    // config structure
    4645    char todaysDate[20];        // today's date
    4746    int exitCode;               // ps exit code
     
    5049    // methods
    5150    bool (*parseArguments)();
    52     bool (*init)();
    5351    int (*run)();
    5452    void (*print)();
     
    5856    bool (*gotConfig)();
    5957    bool (*gotSurveyType)();
     58
     59    // destructor
    6060    void (*destroy)();
    6161
  • trunk/ippToPsps/src/Config.c

    r30147 r31011  
    1 /** @file ippToPspsConfig.c
     1/** @file Config.c
    22 *
    33 *  @ingroup ippToPsps
     
    77 */
    88
    9 #include "ippToPspsConfig.h"
     9#include "Config.h"
    1010#include <ctype.h>
    1111#include <libxml/parser.h>
    1212#include <libxml/tree.h>
    1313
    14 // Gets PS type from string
     14#include "Fits.h"
     15
     16/**
     17   Gets PS type from string
     18   */
    1519static int ippToPsps_GetDataType(char *typename) {
    1620
     
    2832}
    2933
    30 // finds a column within this table
    31 static IppToPspsConfig_Column* ippToPspsConfig_findColumn(IppToPspsConfig_Table* table, const char* name) {
    32 
    33     IppToPspsConfig_Column* column = NULL;
     34/**
     35  Finds a column within this table
     36  */
     37static Column* findColumn(Table* table, const char* name) {
     38
     39    Column* column = NULL;
    3440
    3541    for (uint32_t i=0; i<table->numOfColumns; i++) {
     
    4652}
    4753
    48 // finds a table from the array of tables
    49 static IppToPspsConfig_Table* ippToPspsConfig_findTable(IppToPspsConfig* this, const char* name) {
    50 
    51     IppToPspsConfig_Table* table = NULL;
     54/**
     55  Finds a table from the array of tables
     56  */
     57static Table* findTable(Config* this, const char* name) {
     58
     59    Table* table = NULL;
    5260
    5361    for (uint32_t i=0; i<this->numOfTables; i++) {
     
    6472}
    6573
    66 // gets an attribute value from XML node
    67 static bool ippToPspsConfig_getAttribute(xmlNode* node, const char* attName, char* _value) {
     74/**
     75  Gets an attribute value from XML node
     76  */
     77static bool getAttribute(xmlNode* node, const char* attName, char* _value) {
    6878
    6979    xmlChar* value = xmlGetProp(node, (const xmlChar*)attName);
     
    7585}
    7686
    77 // creates a FITS binary table and populates it with defaults based on definition in schema XML
    78 static bool ippToPspsConfig_createTable(IppToPspsConfig_Table* table, fitsfile* fitsOut, const long nRows) {
     87/**
     88  Creates a FITS binary table and populates it with defaults based on definition in schema XML
     89  */
     90static bool createTable(Table* table, Fits* fitsOut, const long nRows) {
    7991
    8092    if (!table) return false;
     
    98110        switch (table->columns[i].pspsType) {
    99111
    100             case TBYTE:
    101                 sprintf(colTypes[i],"1B");
    102                 break;
    103             case TSHORT:
    104                 sprintf(colTypes[i],"1I");
    105                 break;
    106             case TLONG:
    107                 sprintf(colTypes[i],"1J"); // TODO
    108                 break;
    109             case TLONGLONG:
    110                 sprintf(colTypes[i],"1K");
    111                 break;
    112             case TFLOAT:
    113                 sprintf(colTypes[i],"1E");
    114                 break;
    115             case TDOUBLE:
    116                 sprintf(colTypes[i],"1D");
    117                 break;
    118             case TSTRING:
    119                 sprintf(colTypes[i],"32A"); // TODO width?
    120                 break;
     112            case TBYTE: sprintf(colTypes[i],"1B");
     113                        break;
     114            case TSHORT: sprintf(colTypes[i],"1I");
     115                         break;
     116            case TLONG: sprintf(colTypes[i],"1J"); // TODO
     117                        break;
     118            case TLONGLONG: sprintf(colTypes[i],"1K");
     119                            break;
     120            case TFLOAT: sprintf(colTypes[i],"1E");
     121                         break;
     122            case TDOUBLE: sprintf(colTypes[i],"1D");
     123                          break;
     124            case TSTRING: sprintf(colTypes[i],"32A"); // TODO width?
     125                          break;
    121126
    122127            default:
    123                 break;
     128                          break;
    124129        }
    125130
     
    127132    }
    128133
    129     int status = 0;
    130     if (fits_create_tbl(fitsOut, BINARY_TBL, nRows, nCols, colNames, colTypes, NULL, table->name, &status)) {
    131 
    132         fits_report_error(stderr, status);
    133         psError(PS_ERR_IO,"Unable to create table: %s", table->name);
    134     }
     134    fitsOut->createBinaryTable(fitsOut, nRows, nCols, colNames, colTypes, table->name);
    135135
    136136    for (i=0;i<nCols;i++) free(colTypes[i]);
     
    166166            case TBYTE:
    167167                for(j=0;j<nRows;j++) int8col[j] = (int8_t)tempLong;
    168                 fits_write_col(fitsOut, TBYTE, col, 1, 1, nRows, int8col, &status);
     168                fitsOut->writeColumn(fitsOut, TBYTE, col, 1, 1, nRows, int8col);
    169169                break;
    170170            case TSHORT:
    171171                for(j=0;j<nRows;j++) int16col[j] = (int16_t)tempLong;
    172                 fits_write_col(fitsOut, TSHORT, col, 1, 1, nRows, int16col, &status);
     172                fitsOut->writeColumn(fitsOut, TSHORT, col, 1, 1, nRows, int16col);
    173173                break;
    174174            case TLONG:
    175175                for(j=0;j<nRows;j++) longcol[j] = (long)tempLong;
    176                 fits_write_col(fitsOut, TLONG, col, 1, 1, nRows, longcol, &status);
     176                fitsOut->writeColumn(fitsOut, TLONG, col, 1, 1, nRows, longcol);
    177177                break;
    178178
    179179            case TLONGLONG:
    180180                for(j=0;j<nRows;j++) longcol[j] = tempLong;
    181                 fits_write_col(fitsOut, TLONGLONG, col, 1, 1, nRows, longcol, &status);
     181                fitsOut->writeColumn(fitsOut, TLONGLONG, col, 1, 1, nRows, longcol);
    182182                break;
    183183
    184184            case TFLOAT:
    185185                for(j=0;j<nRows;j++) floatcol[j] = (float)tempDouble;
    186                 fits_write_col(fitsOut, TFLOAT, col, 1, 1, nRows, floatcol, &status);
     186                fitsOut->writeColumn(fitsOut, TFLOAT, col, 1, 1, nRows, floatcol);
    187187                break;
    188188
    189189            case TDOUBLE:
    190190                for(j=0;j<nRows;j++) doublecol[j] = tempDouble;
    191                 fits_write_col(fitsOut, TDOUBLE, col, 1, 1, nRows, doublecol, &status);
     191                fitsOut->writeColumn(fitsOut, TDOUBLE, col, 1, 1, nRows, doublecol);
    192192                break;
    193193
    194194            case TSTRING:
    195195                for(j=0;j<nRows;j++) strcpy(strcol[j], tempStr);
    196                 fits_write_col(fitsOut, TSTRING, col, 1, 1, nRows, strcol, &status);
     196                fitsOut->writeColumn(fitsOut, TSTRING, col, 1, 1, nRows, strcol);
    197197                break;
    198198
     
    214214}
    215215
    216 // count number of children with the provided name
    217 static int ippToPspsConfig_countChildren(xmlNode* rootNode, const char* name) {
     216/*
     217   Counts number of children with the provided name
     218   */
     219static int countChildren(xmlNode* rootNode, const char* name) {
    218220
    219221    int count = 0;
     
    228230}
    229231
    230 // searches through this table and finds attribute value for a provided key
    231 static bool ippToPspsConfig_getRowAttribute(IppToPspsConfig* this, xmlNode* tableNode,
     232/**
     233  Searches through this table and finds attribute value for a provided key
     234  */
     235static bool getRowAttribute(Config* this, xmlNode* tableNode,
    232236        const char* keyName, const char* keyValue,
    233237        const char* attName, char* attValue) {
     
    243247
    244248            if (strcmp((const char*)node->name, "row")==0) {
    245             //psLogMsg("ippToPsps", PS_LOG_INFO, " Looking for key '%s'",  keyName );
    246 
    247                 if (!ippToPspsConfig_getAttribute(node, keyName, buffer)) continue;
    248             //psLogMsg("ippToPsps", PS_LOG_INFO, "Found key '%s' value '%s'",  keyName, buffer );
     249                //psLogMsg("ippToPsps", PS_LOG_INFO, " Looking for key '%s'",  keyName );
     250
     251                if (!getAttribute(node, keyName, buffer)) continue;
     252                //psLogMsg("ippToPsps", PS_LOG_INFO, "Found key '%s' value '%s'",  keyName, buffer );
    249253
    250254                if (strcmp(buffer, keyValue) != 0) continue;
    251                 ippToPspsConfig_getAttribute(node, attName, attValue);
     255                getAttribute(node, attName, attValue);
    252256                //printf("FOUND %s %s %s %s \n", keyName, buffer, attName, attValue );
    253257                return true;
     
    261265}
    262266
    263 // opens an XML file and returns the document
    264 static xmlDoc* ippToPspsConfig_openXmlFile(const char* path) {
     267/*
     268   opens an XML file and returns the document
     269   */
     270static xmlDoc* openXmlFile(const char* path) {
    265271
    266272    xmlDoc* doc = xmlReadFile(path, NULL, 0);
     
    269275}
    270276
    271 // closes an XML file
    272 static bool ippToPspsConfig_closeXmlFile(xmlDoc* doc) {
     277/*
     278   closes an XML file
     279   */
     280static bool closeXmlFile(xmlDoc* doc) {
    273281
    274282    xmlFreeDoc(doc);
     
    278286}
    279287
    280 // gets filter ID for this filter name from 'init' data
    281 static bool ippToPspsConfig_getInitValue(
    282         IppToPspsConfig* this,
     288/**
     289  Gets a value from the 'init' data
     290  */
     291static bool getInitValue(
     292        Config* this,
    283293        const char* tableName,
    284294        const char* keyName, const char* keyValue,
     
    290300    psStringAppend(&path, "%s/../init/data.xml", this->configsPath); // TODO nasty
    291301
    292     xmlDoc* doc = ippToPspsConfig_openXmlFile(path);
     302    xmlDoc* doc = openXmlFile(path);
    293303
    294304    if (doc == NULL) {
     
    313323
    314324            if (strcmp((const char*)node->name, "table")!=0) continue;
    315             if (!ippToPspsConfig_getAttribute(node, "name", tempStr)) continue;
     325            if (!getAttribute(node, "name", tempStr)) continue;
    316326            if (strcmp(tempStr, tableName)!=0) continue;
    317327
    318             ret = ippToPspsConfig_getRowAttribute(this, node, keyName, keyValue, attName, attValue);
     328            ret = getRowAttribute(this, node, keyName, keyValue, attName, attValue);
    319329            break;
    320330        }
     
    322332    }
    323333
    324     ippToPspsConfig_closeXmlFile(doc);
     334    closeXmlFile(doc);
    325335
    326336    return ret;
    327337}
    328338
    329 // gets survey ID from survey name
    330 bool ippToPspsConfig_getSurveyId(IppToPspsConfig* this, const char* surveyType, int8_t* surveyId) {
     339/*
     340   Gets survey ID from survey name
     341   */
     342static bool getSurveyId(Config* this, const char* surveyType, int8_t* surveyId) {
    331343
    332344    char buffer[10];
    333     if (!ippToPspsConfig_getInitValue(this, "Survey", "name", surveyType, "surveyID", buffer)) {
     345    if (!getInitValue(this, "Survey", "name", surveyType, "surveyID", buffer)) {
    334346
    335347        *surveyId = -1;
     
    341353}
    342354
    343 // gets filter ID from filter type
    344 bool ippToPspsConfig_getFilterId(IppToPspsConfig* this, const char* filterType, int8_t* filterId) {
     355/*
     356   Gets filter ID from filter type
     357   */
     358static bool getFilterId(Config* this, const char* filterType, int8_t* filterId) {
    345359
    346360    char tmp[2];
     
    348362    tmp[1] = '\0';
    349363    char buffer[10];
    350     if (!ippToPspsConfig_getInitValue(this, "Filter", "filterType", tmp, "filterID", buffer)) {
     364    if (!getInitValue(this, "Filter", "filterType", tmp, "filterID", buffer)) {
    351365
    352366        *filterId = -1;
     
    358372}
    359373
    360 // populate the provided table with data from XML
    361 static bool ippToPspsConfig_populateTable(IppToPspsConfig_Table* table, xmlNode* rootElement, fitsfile *fitsOut) {
     374/**
     375  Populates the provided table with data from XML
     376  */
     377static bool populateTable(Table* table, xmlNode* rootElement, Fits *fitsOut) {
    362378
    363379    char tempStr[100];
     
    370386
    371387            if (strcmp((const char*)node->name, "table")!=0) continue;
    372             if (!ippToPspsConfig_getAttribute(node, "name", tempStr)) continue;
     388            if (!getAttribute(node, "name", tempStr)) continue;
    373389            if (strcmp(tempStr, table->name)==0) {tableNode = node; break;}
    374390        }
     
    382398
    383399    // now count the number of rows
    384     int nRows = ippToPspsConfig_countChildren(tableNode, "row");
     400    int nRows = countChildren(tableNode, "row");
    385401    if (nRows < 1) return false;
    386     if (!ippToPspsConfig_createTable(table, fitsOut, nRows)) return false;
     402    if (!createTable(table, fitsOut, nRows)) return false;
    387403
    388404    int rows=0;
     
    411427            col = i+1;
    412428
    413             if (!ippToPspsConfig_getAttribute(node, table->columns[i].pspsName, tempStr)) continue;
     429            if (!getAttribute(node, table->columns[i].pspsName, tempStr)) continue;
    414430
    415431            strncpy(strcol[0], tempStr, 32);
     
    420436                case TBYTE:
    421437                    bytecol[0] = atoi(tempStr);
    422                     fits_write_col(fitsOut, table->columns[i].pspsType, col, rows, 1, 1, bytecol, &status);
     438                    fitsOut->writeColumn(fitsOut, table->columns[i].pspsType, col, rows, 1, 1, bytecol);
    423439                    break;
    424440                case TSHORT:
    425441                    shortcol[0] = atoi(tempStr);
    426                     fits_write_col(fitsOut, table->columns[i].pspsType, col, rows, 1, 1, shortcol, &status);
     442                    fitsOut->writeColumn(fitsOut, table->columns[i].pspsType, col, rows, 1, 1, shortcol);
    427443                    break;
    428444                case TLONG:
    429445                case TLONGLONG:
    430446                    longcol[0] = atol(tempStr);
    431                     fits_write_col(fitsOut, table->columns[i].pspsType, col, rows, 1, 1, longcol, &status);
     447                    fitsOut->writeColumn(fitsOut, table->columns[i].pspsType, col, rows, 1, 1, longcol);
    432448                    break;
    433449                case TFLOAT:
    434450                    floatcol[0] = atof(tempStr);
    435                     fits_write_col(fitsOut, table->columns[i].pspsType, col, rows, 1, 1, floatcol, &status);
     451                    fitsOut->writeColumn(fitsOut, table->columns[i].pspsType, col, rows, 1, 1, floatcol);
    436452                    break;
    437453                case TDOUBLE:
    438454                    doublecol[0] = atof(tempStr);
    439                     fits_write_col(fitsOut, table->columns[i].pspsType, col, rows, 1, 1, doublecol, &status);
     455                    fitsOut->writeColumn(fitsOut, table->columns[i].pspsType, col, rows, 1, 1, doublecol);
    440456                    break;
    441457                case TSTRING:
    442                     fits_write_col(fitsOut, table->columns[i].pspsType, col, rows, 1, 1, strcol, &status);
     458                    fitsOut->writeColumn(fitsOut, table->columns[i].pspsType, col, rows, 1, 1, strcol);
    443459                    break;
    444460
     
    460476}
    461477
    462 // loads a table description from XML
    463 static bool ippToPspsConfig_loadTableDescription(IppToPspsConfig_Table* table, xmlNode* tableNode) {
     478/**
     479  Loads a table description from XML
     480  */
     481static bool loadTableDescription(Table* table, xmlNode* tableNode) {
    464482
    465483    bool ret = true;
    466484    char tableName[100];
    467     ippToPspsConfig_getAttribute(tableNode, "name", tableName);
     485    getAttribute(tableNode, "name", tableName);
    468486    strcpy(table->name, tableName);
    469487
    470488    // count how many columns we have coming in and allocate memory for them
    471     table->numOfColumns = ippToPspsConfig_countChildren(tableNode, "column");
    472     table->columns = calloc(table->numOfColumns, sizeof(IppToPspsConfig_Column));
     489    table->numOfColumns = countChildren(tableNode, "column");
     490    table->columns = calloc(table->numOfColumns, sizeof(Column));
    473491    //    psLogMsg("ippToPsps", PS_LOG_INFO, " Found '%d' columns", table->numOfColumns);
    474492
     
    484502
    485503        // column name
    486         ippToPspsConfig_getAttribute(node, "name", buffer);
     504        getAttribute(node, "name", buffer);
    487505        sprintf(table->columns[columnNum].pspsName, buffer);
    488506
    489507        // column type
    490         ippToPspsConfig_getAttribute(node, "type", buffer);
     508        getAttribute(node, "type", buffer);
    491509        table->columns[columnNum].pspsType = ippToPsps_GetDataType(buffer);
    492510
    493511        // default value
    494         ippToPspsConfig_getAttribute(node, "default", buffer);
     512        getAttribute(node, "default", buffer);
    495513        sprintf(table->columns[columnNum].defaultValue, buffer);
    496514
    497515        // comment
    498         ippToPspsConfig_getAttribute(node, "comment", buffer);
     516        getAttribute(node, "comment", buffer);
    499517        sprintf(table->columns[columnNum].comment, buffer);
    500518
     
    523541}
    524542
    525 // read table shapes from XML file
    526 bool ippToPspsConfig_loadTableDescriptions(IppToPspsConfig* this) {
     543/**
     544  Reads table shapes from XML file
     545  */
     546static bool loadTableDescriptions(Config* this) {
    527547
    528548    bool ret = true;
     
    531551    psStringAppend(&path, "%s/tables.xml", this->configsPath);
    532552
    533     xmlDoc* doc = ippToPspsConfig_openXmlFile(path);
     553    xmlDoc* doc = openXmlFile(path);
    534554
    535555    if (doc == NULL) {
     
    549569
    550570    // count how many tables we have coming in and allocate memory for them
    551     this->numOfTables = ippToPspsConfig_countChildren(rootElement, "table");
    552     this->tables = calloc(this->numOfTables, sizeof(IppToPspsConfig_Table));
     571    this->numOfTables = countChildren(rootElement, "table");
     572    this->tables = calloc(this->numOfTables, sizeof(Table));
    553573    //    psLogMsg("ippToPsps", PS_LOG_INFO, " Found '%d' tables", this->numOfTables);
    554574
    555575    xmlNode* node = NULL;
    556     IppToPspsConfig_Table* table = NULL;
     576    Table* table = NULL;
    557577
    558578    int tableNum = 0;
     
    565585                table = this->tables+tableNum;
    566586
    567                 if (!ippToPspsConfig_loadTableDescription(table, node)) ret = false;
     587                if (!loadTableDescription(table, node)) ret = false;
    568588                else tableNum++;
    569589            }
     
    574594        psError(PS_ERR_IO, false, "Mismatch between number of tables expected (%d) and those found (%d)", this->numOfTables, tableNum);
    575595
    576     ippToPspsConfig_closeXmlFile(doc);
     596    closeXmlFile(doc);
    577597
    578598    return ret;
    579599}
    580600
    581 // loads mappings from XML for a particular table
    582 static bool ippToPspsConfig_loadTableMappings(IppToPspsConfig* this, xmlNode* tableNode) {
     601/**
     602  Loads mappings from XML for a particular table
     603  */
     604static bool loadTableMappings(Config* this, xmlNode* tableNode) {
    583605
    584606    bool ret = false;
     
    587609
    588610    char tableName[100];
    589     ippToPspsConfig_getAttribute(tableNode, "name", tableName);
    590 
    591     IppToPspsConfig_Table* table = ippToPspsConfig_findTable(this, tableName);
    592     IppToPspsConfig_Column* column = NULL;
     611    getAttribute(tableNode, "name", tableName);
     612
     613    Table* table = findTable(this, tableName);
     614    Column* column = NULL;
    593615    if (!table) return false;
    594616
     
    603625
    604626                // column type
    605                 ippToPspsConfig_getAttribute(node, "pspsName", buffer);
    606                 column = ippToPspsConfig_findColumn(table, buffer);
     627                getAttribute(node, "pspsName", buffer);
     628                column = findColumn(table, buffer);
    607629
    608630                if (!column) continue;
    609631
    610632                // IPP name
    611                 ippToPspsConfig_getAttribute(node, "ippName", buffer);
     633                getAttribute(node, "ippName", buffer);
    612634                strcpy(column->ippName, buffer);
    613635
    614636                // IPP type
    615                 ippToPspsConfig_getAttribute(node, "ippType", buffer);
     637                getAttribute(node, "ippType", buffer);
    616638                column->ippType = ippToPsps_GetDataType(buffer);
    617639
     
    626648}
    627649
    628 // reads table mappings from XML file
    629 static bool ippToPspsConfig_loadMappings(IppToPspsConfig* this) {
     650/**
     651  Reads table mappings from XML file
     652  */
     653static bool loadMappings(Config* this) {
    630654
    631655    bool ret = true;
     
    634658    psStringAppend(&path, "%s/map.xml", this->configsPath);
    635659
    636     xmlDoc* doc = ippToPspsConfig_openXmlFile(path);
     660    xmlDoc* doc = openXmlFile(path);
    637661
    638662    if (doc == NULL) {
     
    657681            if (strcmp((const char*)node->name, "table")==0) {
    658682
    659                 if (!ippToPspsConfig_loadTableMappings(this, node)) ret = false;
     683                if (!loadTableMappings(this, node)) ret = false;
    660684            }
    661685        }
    662686    }
    663687
    664     ippToPspsConfig_closeXmlFile(doc);
     688    closeXmlFile(doc);
    665689
    666690    return ret;
    667691}
    668692
    669 // populate the provided table with data from XML
    670 bool ippToPspsConfig_populateFromFile(IppToPspsConfig* this, fitsfile *fitsOut) {
     693/**
     694  Populate the provided table with data from XML
     695  */
     696static bool populateFromFile(Config* this, Fits *fitsOut) {
    671697
    672698    bool ret = true;
     
    674700    psStringAppend(&path, "%s/data.xml", this->configsPath);
    675701
    676     xmlDoc* doc = ippToPspsConfig_openXmlFile(path);
     702    xmlDoc* doc = openXmlFile(path);
    677703
    678704    if (doc == NULL) {
     
    690716
    691717    for (uint32_t i=0; i<this->numOfTables; i++) {
    692         if (!ippToPspsConfig_populateTable(this->tables+i, rootElement, fitsOut)) {
     718        if (!populateTable(this->tables+i, rootElement, fitsOut)) {
    693719            ret = false;
    694720        }
    695721    }
    696722
    697     ippToPspsConfig_closeXmlFile(doc);
     723    closeXmlFile(doc);
    698724
    699725    return ret;
    700726}
    701727
    702 // gets the contents of a FITS column vector
    703 bool ippToPspsConfig_getColumnVector(
    704         int col,
    705         long row,
    706         int type,
    707         int repeat,
    708         float* vector,
    709         fitsfile *fitsIn) {
    710 
    711     int status = 0;
    712     int anynull = 0; 
    713 
    714     fits_read_col(fitsIn, type, col, row, 1, repeat, NULL, vector, &anynull, &status);
    715 
    716     if (status) {
    717         psError(PS_ERR_IO, false, "Failed to read vector column %d row %ld", col, row);
    718         return false;
    719     }
    720 
    721     int i;
    722     for(i=0; i<repeat; i++) printf("JJJ %f\n", vector[i]);
    723 
    724     return true;
    725 }
    726 
    727 // gets metadata about a column
    728 bool ippToPspsConfig_getFitsColumnMeta(
    729         char* name,
    730         int* colNum,
    731         int* type,
    732         long* repeat,
    733         fitsfile *fitsIn) {
    734 
    735     int status = 0;
    736     fits_get_colnum(fitsIn, CASESEN, name, colNum, &status);
    737     if (status) {
    738         psError(PS_ERR_IO, false, "Unable to read col '%s'", name);
    739         return false;
    740     }
    741 
    742     status = 0;
    743     fits_get_eqcoltype(fitsIn, *colNum, type, repeat, NULL, &status);
    744     if (status) {
    745         psError(PS_ERR_IO, false, "Unable to read type info for '%s'", name);
    746         return false;
    747     }
    748 
    749     return true;
    750 }
    751 
    752 // populate with data from another FITS table into this one
    753 static bool ippToPspsConfig_populateTableFromFits(
    754         IppToPspsConfig_Table* table,
    755         fitsfile *fitsIn,
    756         fitsfile *fitsOut,
     728/**
     729  Populate with data from another FITS table into this one
     730  */
     731static bool populateTableFromFits(
     732        Table* table,
     733        Fits *fitsIn,
     734        Fits *fitsOut,
    757735        const long nRows,
    758736        const bool fromHeader) {
     
    770748        strcol[i] = (char*)calloc(50,sizeof(char)); // TODO 20? size issue
    771749
    772     int8_t int8null = -99;
    773     int16_t int16null = -999;
    774     long longnull = -999;
    775     float floatnull = -999.0;
    776     double doublenull = -999.0;
    777 
    778     int anynull = 0;
    779     int readStatus = 0;
    780     int writeStatus = 0;
    781 
    782750    // first loop round all columns and get IPP col numbers for provided column names TODO only do once, first time in
    783751    if(!fromHeader) {
     
    787755            if (strlen(table->columns[i].ippName) < 1) continue;
    788756
    789 int dummy;
    790 
    791             if (!ippToPspsConfig_getFitsColumnMeta(
    792                         table->columns[i].ippName,
    793                         &table->columns[i].ippColNum,
    794           //              &table->columns[i].ippType,  TODO getting wrong type for some reason
    795                         &dummy,
    796                         &table->columns[i].ippRepeat,
    797                         fitsIn)) {return false;}
     757            int dummy; // TODO getting wrong type for some reason
     758            if (!fitsIn->getColumnMeta(fitsIn, table->columns[i].ippName, &table->columns[i].ippColNum, &dummy, &table->columns[i].ippRepeat)) return false;
    798759        }
    799760    }
     
    802763    for (uint32_t i=0; i<table->numOfColumns; i++) {
    803764
    804         readStatus = 0;
    805         writeStatus = 0;
    806 
    807765        if (!table->columns[i].usingDefault) {
    808766
     
    813771                case TBYTE:
    814772                    if (fromHeader) {
    815                         fits_read_key(fitsIn, TBYTE, table->columns[i].ippName, &int8col[0], NULL, &readStatus);
    816                         if (!isfinite(int8col[0])) int8col[0] = int8null;
     773                        fitsIn->getHeaderKeyValue(fitsIn, TBYTE, table->columns[i].ippName, &int8col[0]);
    817774                    }
    818                     else fits_read_col(fitsIn, TBYTE, table->columns[i].ippColNum, 1, 1, nRows, &int8null, int8col, &anynull, &readStatus);
    819                     fits_write_col(fitsOut, TBYTE, col, 1, 1, nRows, int8col, &writeStatus);
     775                    else fitsIn->readColumn(fitsIn, TBYTE, table->columns[i].ippColNum, 1, 1, nRows, int8col);
     776                    fitsOut->writeColumn(fitsOut, TBYTE, col, 1, 1, nRows, int8col);
    820777                    break;
    821778                case TSHORT:
    822779                    if (fromHeader) {
    823                         fits_read_key(fitsIn, TSHORT, table->columns[i].ippName, &int16col[0], NULL, &readStatus);
    824                         if (!isfinite(int16col[0])) int16col[0] = int16null;
     780                        fitsIn->getHeaderKeyValue(fitsIn, TSHORT, table->columns[i].ippName, &int16col[0]);
    825781                    }
    826                     else fits_read_col(fitsIn, TSHORT, table->columns[i].ippColNum, 1, 1, nRows, &int16null, int16col, &anynull, &readStatus);
    827                     fits_write_col(fitsOut, TSHORT, col, 1, 1, nRows, int16col, &writeStatus);
     782                    else fitsIn->readColumn(fitsIn, TSHORT, table->columns[i].ippColNum, 1, 1, nRows, int16col);
     783                    fitsOut->writeColumn(fitsOut, TSHORT, col, 1, 1, nRows, int16col);
    828784                    break;
    829785                case TLONG:
    830786                    if (fromHeader) {
    831                         fits_read_key(fitsIn, TLONG, table->columns[i].ippName, &longcol[0], NULL, &readStatus);
    832                         if (!isfinite(longcol[0])) longcol[0] = longnull;
     787                        fitsIn->getHeaderKeyValue(fitsIn, TLONG, table->columns[i].ippName, &longcol[0]);
    833788                    }
    834                     else fits_read_col(fitsIn, TLONG, table->columns[i].ippColNum, 1, 1, nRows, &longnull, longcol, &anynull, &readStatus);
    835                     fits_write_col(fitsOut, TLONG, col, 1, 1, nRows, longcol, &writeStatus);
     789                    else fitsIn->readColumn(fitsIn, TLONG, table->columns[i].ippColNum, 1, 1, nRows, longcol);
     790                    fitsOut->writeColumn(fitsOut, TLONG, col, 1, 1, nRows, longcol);
    836791                    break;
    837792                case TLONGLONG:
    838793                    if (fromHeader) {
    839                         fits_read_key(fitsIn, TLONGLONG, table->columns[i].ippName, &longcol[0], NULL, &readStatus);
    840                         if (!isfinite(longcol[0])) longcol[0] = longnull;
     794                        fitsIn->getHeaderKeyValue(fitsIn, TLONGLONG, table->columns[i].ippName, &longcol[0]);
    841795                    }
    842                     else fits_read_col(fitsIn, TLONGLONG, table->columns[i].ippColNum, 1, 1, nRows, &longnull, longcol, &anynull, &readStatus);
    843                     fits_write_col(fitsOut, TLONGLONG, col, 1, 1, nRows, longcol, &writeStatus);
     796                    else fitsIn->readColumn(fitsIn, TLONGLONG, table->columns[i].ippColNum, 1, 1, nRows, longcol);
     797                    fitsOut->writeColumn(fitsOut, TLONGLONG, col, 1, 1, nRows, longcol);
    844798                    break;
    845799                case TFLOAT:
    846800                    if (fromHeader) {
    847                         fits_read_key(fitsIn, TFLOAT, table->columns[i].ippName,&floatcol[0], NULL, &readStatus);
    848                         if (!isfinite(floatcol[0])) floatcol[0] = floatnull;
     801                        fitsIn->getHeaderKeyValue(fitsIn, TFLOAT, table->columns[i].ippName,&floatcol[0]);
    849802                    }
    850                     else fits_read_col(fitsIn, TFLOAT, table->columns[i].ippColNum, 1, 1, nRows, &floatnull, floatcol, &anynull, &readStatus);
    851                     fits_write_col(fitsOut, TFLOAT, col, 1, 1, nRows, floatcol, &writeStatus);
     803                    else fitsIn->readColumn(fitsIn, TFLOAT, table->columns[i].ippColNum, 1, 1, nRows, floatcol);
     804                    fitsOut->writeColumn(fitsOut, TFLOAT, col, 1, 1, nRows, floatcol);
    852805                    break;
    853806                case TDOUBLE:
    854807                    if (fromHeader) {
    855                         fits_read_key(fitsIn, TDOUBLE, table->columns[i].ippName, &doublecol[0], NULL, &readStatus);
    856                         if (!isfinite(doublecol[0])) doublecol[0] = doublenull;
     808                        fitsIn->getHeaderKeyValue(fitsIn, TDOUBLE, table->columns[i].ippName, &doublecol[0]);
    857809                    }
    858                     else fits_read_col(fitsIn, TDOUBLE, table->columns[i].ippColNum, 1, 1, nRows, &doublenull, doublecol, &anynull, &readStatus);
    859                     fits_write_col(fitsOut, TDOUBLE, col, 1, 1, nRows, doublecol, &writeStatus);
     810                    else fitsIn->readColumn(fitsIn, TDOUBLE, table->columns[i].ippColNum, 1, 1, nRows, doublecol);
     811                    fitsOut->writeColumn(fitsOut, TDOUBLE, col, 1, 1, nRows, doublecol);
    860812                    break;
    861813                case TSTRING:
    862                     if (fromHeader) fits_read_key(fitsIn, TSTRING, table->columns[i].ippName, strcol[0], NULL, &readStatus);
    863                     else fits_read_col(fitsIn, TSTRING, table->columns[i].ippColNum, 1, 1, nRows, " ", strcol, &anynull, &readStatus);
    864                     fits_write_col(fitsOut, TSTRING, col, 1, 1, nRows, strcol, &writeStatus);
     814                    if (fromHeader) fitsIn->getHeaderKeyValue(fitsIn, TSTRING, table->columns[i].ippName, strcol[0]);
     815                    else fitsIn->readColumn(fitsIn, TSTRING, table->columns[i].ippColNum, 1, 1, nRows, strcol);
     816                    fitsOut->writeColumn(fitsOut, TSTRING, col, 1, 1, nRows, strcol);
    865817                    break;
    866818
     
    870822                    break;
    871823            }
    872 
    873             // TODO need these errors, but strange error handling runs out of memory
    874             //if (readStatus) {
    875             //    psError(PS_ERR_IO, false, "Unable to read col num '%d' col name '%s', type %d",
    876             //        table->columns[i].ippColNum, table->columns[i].ippName, table->columns[i].ippType);
    877             //    fits_report_error(stderr, readStatus);
    878             //}
    879             //if (writeStatus) {
    880             //    psError(PS_ERR_IO, false, "Unable to write col '%s'", table->columns[i].pspsName );
    881             //    fits_report_error(stderr, writeStatus);
    882             //}
    883824        }
    884825    }
     
    895836}
    896837
    897 // creates and populates a table
    898 bool ippToPspsConfig_writeTable(
    899         IppToPspsConfig* this,
    900         fitsfile* fitsIn,
    901         fitsfile* fitsOut,
     838/**
     839  Creates and populates a table
     840  */
     841static bool createAndPopulateTable(
     842        Config* this,
     843        Fits* fitsIn,
     844        Fits* fitsOut,
    902845        const long nRows,
    903846        const char* tableName,
    904         const bool fromHeader) {
    905 
    906 
    907     IppToPspsConfig_Table* table = ippToPspsConfig_findTable(this, tableName);
     847        const int fromHeader) {
     848
     849    Table* table = findTable(this, tableName);
    908850    if (!table) return false;
    909851
    910     if(!ippToPspsConfig_createTable(table, fitsOut, nRows)) return false;
    911     return ippToPspsConfig_populateTableFromFits(table, fitsIn, fitsOut, nRows, fromHeader);
    912 }
    913 
    914 // Destructor.
    915 void ippToPspsConfig_Destructor(IppToPspsConfig* this) {
     852    if(!createTable(table, fitsOut, nRows)) return false;
     853    return populateTableFromFits(table, fitsIn, fitsOut, nRows, fromHeader);
     854}
     855
     856/**
     857  Destructor.
     858  */
     859static void destroy(Config* this) {
    916860
    917861    if (this != NULL ) {
     
    927871}
    928872
    929 // Constructor. Loads IPP -> PSPS mappings from a csv
    930 IppToPspsConfig* ippToPspsConfig_Constructor(const char* path) {
    931 
    932     IppToPspsConfig* this = NULL;
    933 
    934     this = malloc(sizeof(IppToPspsConfig));
     873/**
     874  Constructor. Loads IPP -> PSPS mappings from an XML file
     875  */
     876Config* new_Config(const char* path) {
     877
     878    Config* this = (Config*)calloc(1, sizeof(Config));
    935879
    936880    this->configsPath = NULL;
    937881    psStringAppend(&this->configsPath, path);
    938882
     883    // method pointers
     884    this->getFilterId = getFilterId;
     885    this->getSurveyId = getSurveyId;
     886    this->createAndPopulateTable = createAndPopulateTable;
     887    this->populateFromFile = populateFromFile;
     888    this->destroy = destroy;
     889
    939890    // load tables descriptions from XML
    940     if (ippToPspsConfig_loadTableDescriptions(this)) {
     891    if (loadTableDescriptions(this)) {
    941892
    942893        // load any mappings we may have from XML       
    943         ippToPspsConfig_loadMappings(this);
     894        loadMappings(this);
    944895    }
    945896
  • trunk/ippToPsps/src/Config.h

    r30147 r31011  
    1 /** @file ippToPspsConfig.h
     1/** @file Config.h
    22 *
    33 *  @brief ippToPsps
     
    99 */
    1010
    11 #ifndef IPPTOPSPSCONFIG_H
    12 #define IPPTOPSPSCONFIG_H
     11#ifndef IPPTOPSPS_CONFIG_H
     12#define IPPTOPSPS_CONFIG_H
    1313
    1414#include <psmodules.h>
    1515
    1616// column class
    17 typedef struct {
     17typedef struct Column {
    1818
    1919    int ippColNum;
     
    2727    char comment[300];
    2828
    29 } IppToPspsConfig_Column;
     29} Column;
    3030
    3131// table class
    32 typedef struct {
     32typedef struct Table {
    3333
    3434    char name[32];
    35     IppToPspsConfig_Column* columns;
     35    Column* columns;
    3636    int numOfColumns;
    3737
    38 } IppToPspsConfig_Table;
     38} Table;
    3939
    40 // 
    41 typedef struct {
     40/**
    4241
     42  Class encapsulating ... TODO
     43
     44*/
     45typedef struct Config {
     46
     47    // fields
    4348    psString configsPath;
    44     IppToPspsConfig_Table* tables;
     49    Table* tables;
    4550    int numOfTables;
    4651
    47 } IppToPspsConfig;
     52    // methods
     53    bool (*getFilterId)();
     54    bool (*getSurveyId)();
     55    bool (*createAndPopulateTable)();
     56    bool (*populateFromFile)();
    4857
    49 IppToPspsConfig* ippToPspsConfig_Constructor(const char* filePath);
    50 bool ippToPspsConfig_populateFromFile(IppToPspsConfig* this, fitsfile *fitsOut); // TODO remove
    51 void ippToPspsConfig_Destructor();
    52 bool ippToPspsConfig_writeTable(
    53         IppToPspsConfig* this,
    54         fitsfile* fitsIn,
    55         fitsfile* fitsOut,
    56         const long nRows,
    57         const char* tableName,
    58         const bool fromHeader);
     58    // destructor
     59    void (*destroy)();
    5960
    60 // getters
    61 bool ippToPspsConfig_getFilterId(IppToPspsConfig* this, const char* filterType, int8_t* filterId);
    62 bool ippToPspsConfig_getSurveyId(IppToPspsConfig* this, const char* surveyType, int8_t* surveyId);
    63 bool ippToPspsConfig_getFitsColumnMeta(
    64         char* name,
    65         int* colNum,
    66         int* type,
    67         long* repeat,
    68         fitsfile *fitsIn);
     61} Config;
    6962
    70 bool ippToPspsConfig_getColumnVector(
    71         int col,
    72         long row,
    73         int type,
    74         int repeat,
    75         float* vector,
    76         fitsfile *fitsIn);
     63// constructor
     64Config* new_Config(const char* path);
    7765
     66#endif // IPPTOPSPS_CONFIG_H
    7867
    79 
    80 
    81 #endif // IPPTOPSPSCONFIG_H
    82 
  • trunk/ippToPsps/src/DetectionBatch.c

    r30967 r31011  
    11#include "DetectionBatch.h"
    22#include "DetectionBatchEnums.h"
     3
     4#include "Fits.h"
     5
    36
    47/**
     
    4346    if (this->base.exitCode != PS_EXIT_SUCCESS) return this->base.exitCode;
    4447
    45     int status = 0;
    46     fitsfile *fitsIn;
    47 
    48     if (fits_open_file(&fitsIn, this->base.inputFiles[0], READONLY, &status)) {
    49 
    50         fits_report_error(stderr, status);
    51         return PS_EXIT_SYS_ERROR;
    52     }
    53 
    54     // get primary header and pull stuff out for later
    55     int nKeys;
    56     fits_get_hdrspace(fitsIn, &nKeys, NULL, &status);
    57 
    58     float zptObs, exposureTime;
    59     char filterType[20];
    60     double obsTime;
    61     double expStart;
    62     double expTime;
    63     status=0; fits_read_key(fitsIn, TFLOAT, "ZPT_OBS", &zptObs, NULL, &status);
    64     status=0; fits_read_key(fitsIn, TFLOAT, "EXPREQ", &exposureTime, NULL, &status);
    65     status=0; fits_read_key(fitsIn, TSTRING, "FILTERID", filterType, NULL, &status);
    66     status=0; fits_read_key(fitsIn, TDOUBLE, "MJD-OBS", &expStart, NULL, &status);
    67     status=0; fits_read_key(fitsIn, TDOUBLE, "EXPTIME", &expTime, NULL, &status);
    68     obsTime = expStart + (expTime/172800.0); // exp start plus half exp time (converted from secs to days)
    69 
    70     ippToPspsConfig_writeTable(this->base.config, fitsIn, this->base.fitsOut, 1, "FrameMeta", true);
     48    // open input FITS file
     49    Fits* fitsIn = existing_Fits(this->base.inputFiles[0]);
     50    if (fitsIn->getFilePtr(fitsIn) == NULL)  return PS_EXIT_SYS_ERROR;
     51
     52    // read some header values
     53    float zptObs; fitsIn->getHeaderKeyValue(fitsIn, TFLOAT, "ZPT_OBS", &zptObs);
     54    float exposureTime; fitsIn->getHeaderKeyValue(fitsIn, TFLOAT, "EXPREQ", &exposureTime);
     55    char filterType[20]; fitsIn->getHeaderKeyValue(fitsIn, TSTRING, "FILTERID", filterType);
     56    double expStart; fitsIn->getHeaderKeyValue(fitsIn, TDOUBLE, "MJD-OBS", &expStart);
     57    double expTime; fitsIn->getHeaderKeyValue(fitsIn, TDOUBLE, "EXPTIME", &expTime);
     58    double obsTime = expStart + (expTime/172800.0); // exp start plus half exp time (converted from secs to days)
     59
     60
     61    this->base.config->createAndPopulateTable(this->base.config, fitsIn, this->base.fitsOut, 1, "FrameMeta", true);
    7162
    7263    // FrameMeta values
    73     fits_write_col(this->base.fitsOut, TLONG, FRAMEMETA_FRAMEID, 1, 1, 1, &this->expId, &status);
    74     fits_write_col(this->base.fitsOut, TSTRING, FRAMEMETA_FRAMENAME, 1, 1, 1, &(this->expName), &status);
    75     fits_write_col(this->base.fitsOut, TBYTE, FRAMEMETA_SURVEYID, 1, 1, 1, &this->base.surveyID, &status);
    76 
    7764    int8_t filterID = -1;
    78     if (!ippToPspsConfig_getFilterId(this->base.config, filterType, &filterID)) {
     65    if (!this->base.config->getFilterId(this->base.config, filterType, &filterID)) {
    7966   
    8067        this->base.exitCode = PS_EXIT_DATA_ERROR;
    8168        return this->base.exitCode;
    8269    }
    83 
    84     fits_write_col(this->base.fitsOut, TBYTE, FRAMEMETA_FILTERID, 1, 1, 1, &filterID, &status);
     70    this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, FRAMEMETA_FILTERID, 1, 1, 1, &filterID);
     71    this->base.fitsOut->writeColumn(this->base.fitsOut, TLONG, FRAMEMETA_FRAMEID, 1, 1, 1, &this->expId);
     72    this->base.fitsOut->writeColumn(this->base.fitsOut, TSTRING, FRAMEMETA_FRAMENAME, 1, 1, 1, &(this->expName));
     73    this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, FRAMEMETA_SURVEYID, 1, 1, 1, &this->base.surveyID);
     74
    8575
    8676    int16_t cameraID = 1; // TODO
    87     fits_write_col(this->base.fitsOut, TSHORT, FRAMEMETA_CAMERAID, 1, 1, 1, &cameraID, &status);
    88 
    8977    int16_t cameraConfigID = 1; // TODO
    90     fits_write_col(this->base.fitsOut, TSHORT, FRAMEMETA_CAMERACONFIGID, 1, 1, 1, &cameraConfigID, &status);
    91 
    9278    int16_t telescopeID = 1; // TODO
    93     fits_write_col(this->base.fitsOut, TSHORT, FRAMEMETA_TELESCOPEID, 1, 1, 1, &telescopeID, &status);
     79    this->base.fitsOut->writeColumn(this->base.fitsOut, TSHORT, FRAMEMETA_CAMERAID, 1, 1, 1, &cameraID);
     80    this->base.fitsOut->writeColumn(this->base.fitsOut, TSHORT, FRAMEMETA_CAMERACONFIGID, 1, 1, 1, &cameraConfigID);
     81    this->base.fitsOut->writeColumn(this->base.fitsOut, TSHORT, FRAMEMETA_TELESCOPEID, 1, 1, 1, &telescopeID);
    9482
    9583    // stuff to keep from psf.hdr header
     
    10795    uint32_t s,d, invalidDvoRows, nChipDetectionsOut = 0;
    10896
    109     long longnull = -999;
    110     float floatnull = -999.0;
    111     int anynull = 0;
    112 
    11397    char ccdNumber[3], extensionName[15];
    114     // for storing FITS column data
     98    // for storing FITS column data - do this once, to avoid expension free/calloc for each chip
    11599    long* ippIDet = (long*)calloc(this->MAXDETECT, sizeof(long));
    116100    float* instMag = (float*)calloc(this->MAXDETECT, sizeof(float));
     
    129113    int8_t* filterIDs = (int8_t*)calloc(this->MAXDETECT, sizeof(int8_t));
    130114    int8_t* surveyIDs = (int8_t*)calloc(this->MAXDETECT, sizeof(int8_t));
    131 
    132115    char** assocDate = (char**)calloc(this->MAXDETECT, sizeof(char*));
    133116    for (uint32_t i=0; i<this->MAXDETECT;i++) assocDate[i] = (char*)malloc(20*sizeof(char));
     
    186169            sprintf(ccdNumber, "%d%d", x, y);
    187170
    188             // check we can move to detections table in smf
     171            // check we CAN move to detections table in smf
    189172            sprintf(extensionName, "XY%s.psf", ccdNumber);
    190             if (!ippToPspsConfig_moveToExtensionTable(fitsIn, extensionName)) continue;
     173            if (!fitsIn->moveToBinaryTable(fitsIn, extensionName)) continue;
    191174
    192175            // move to header extension
    193176            sprintf(extensionName, "XY%s.hdr", ccdNumber);
    194             if (!ippToPspsConfig_moveToExtensionHeader(fitsIn, extensionName)) continue;
     177            if (!fitsIn->moveToHeader(fitsIn, extensionName)) continue;
    195178
    196179            // stuff to save from psf.hdr
    197             status=0; fits_read_key(fitsIn, TFLOAT, "FWHM_MAJ", &fwhmMaj, NULL, &status);
    198             status=0; fits_read_key(fitsIn, TFLOAT, "FWHM_MIN", &fwhmMin, NULL, &status);
    199             status=0; fits_read_key(fitsIn, TFLOAT, "IQ_FW1", &momentMaj, NULL, &status);
    200             status=0; fits_read_key(fitsIn, TFLOAT, "IQ_FW2", &momentMin, NULL, &status);
    201             status=0; fits_read_key(fitsIn, TLONG, "IMAGEID", &imageId, NULL, &status);
    202             status=0; fits_read_key(fitsIn, TLONG, "SOURCEID", &sourceId, NULL, &status);
    203             status=0; fits_read_key(fitsIn, TLONG, "NASTRO", &numPhotoRef, NULL, &status);
     180            fitsIn->getHeaderKeyValue(fitsIn, TFLOAT, "FWHM_MAJ", &fwhmMaj);
     181            fitsIn->getHeaderKeyValue(fitsIn, TFLOAT, "FWHM_MIN", &fwhmMin);
     182            fitsIn->getHeaderKeyValue(fitsIn, TFLOAT, "IQ_FW1", &momentMaj);
     183            fitsIn->getHeaderKeyValue(fitsIn, TFLOAT, "IQ_FW2", &momentMin);
     184            fitsIn->getHeaderKeyValue(fitsIn, TLONG, "IMAGEID", &imageId);
     185            fitsIn->getHeaderKeyValue(fitsIn, TLONG, "SOURCEID", &sourceId);
     186            fitsIn->getHeaderKeyValue(fitsIn, TLONG, "NASTRO", &numPhotoRef);
    204187            totalNumPhotoRef += numPhotoRef; // total up for storing in FrameMeta
     188
    205189            // access DVO database
    206190            skylist = dvoSkyListByExternID(this->base.dvoConfig, sourceId, imageId, &image);
     
    221205            if (numDvoDetections > this->MAXDETECT ) {
    222206
    223                 psError(PS_ERR_IO, false,
    224                         " Number of detections (%d) exceeds max limit (%ld)\n",
     207                psError(PS_ERR_IO, false, " Number of detections (%d) exceeds max limit (%ld)\n",
    225208                        numDvoDetections, this->MAXDETECT);
    226209                error = true;
     
    229212
    230213            // create ImageMeta
    231             ippToPspsConfig_writeTable(this->base.config, fitsIn, this->base.fitsOut, 1, "ImageMeta", true);
     214            this->base.config->createAndPopulateTable(this->base.config, fitsIn, this->base.fitsOut, 1, "ImageMeta", true);
    232215            psfFwhm = (fwhmMaj+fwhmMin)/2;
    233216            momentFwhm = (momentMaj+momentMin)/2;
    234217            imageFlags = (uint64_t)image->flags;
    235             fits_write_col(this->base.fitsOut, TLONGLONG, IMAGEMETA_IMAGEID, 1, 1, 1, &pspsImageId, &status);
    236             fits_write_col(this->base.fitsOut, TLONG, IMAGEMETA_FRAMEID, 1, 1, 1, &this->expId, &status);
    237             fits_write_col(this->base.fitsOut, TSHORT, IMAGEMETA_CCDID, 1, 1, 1, &image->ccdnum, &status);
    238             fits_write_col(this->base.fitsOut, TLONG, IMAGEMETA_PHOTOCALID, 1, 1, 1, &image->photcode, &status);
    239             fits_write_col(this->base.fitsOut, TBYTE, IMAGEMETA_FILTERID, 1, 1, 1, &filterID, &status);
    240             fits_write_col(this->base.fitsOut, TFLOAT, IMAGEMETA_PHOTOSCAT, 1, 1, 1, &zptObs, &status);
    241             fits_write_col(this->base.fitsOut, TFLOAT, IMAGEMETA_PSFFWHM, 1, 1, 1, &psfFwhm, &status);
    242             fits_write_col(this->base.fitsOut, TFLOAT, IMAGEMETA_MOMENTFWHM, 1, 1, 1, &momentFwhm, &status);
    243             fits_write_col(this->base.fitsOut, TFLOAT, IMAGEMETA_PHOTOZERO, 1, 1, 1, &zptObs, &status);
    244             fits_write_col(this->base.fitsOut, TLONGLONG, IMAGEMETA_QAFLAGS, 1, 1, 1, &imageFlags, &status);
     218            this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, IMAGEMETA_IMAGEID, 1, 1, 1, &pspsImageId);
     219            this->base.fitsOut->writeColumn(this->base.fitsOut, TLONG, IMAGEMETA_FRAMEID, 1, 1, 1, &this->expId);
     220            this->base.fitsOut->writeColumn(this->base.fitsOut, TSHORT, IMAGEMETA_CCDID, 1, 1, 1, &image->ccdnum);
     221            this->base.fitsOut->writeColumn(this->base.fitsOut, TLONG, IMAGEMETA_PHOTOCALID, 1, 1, 1, &image->photcode);
     222            this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, IMAGEMETA_FILTERID, 1, 1, 1, &filterID);
     223            this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, IMAGEMETA_PHOTOSCAT, 1, 1, 1, &zptObs);
     224            this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, IMAGEMETA_PSFFWHM, 1, 1, 1, &psfFwhm);
     225            this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, IMAGEMETA_MOMENTFWHM, 1, 1, 1, &momentFwhm);
     226            this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, IMAGEMETA_PHOTOZERO, 1, 1, 1, &zptObs);
     227            this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, IMAGEMETA_QAFLAGS, 1, 1, 1, &imageFlags);
    245228
    246229            // now move BACK to detections table in smf
    247230            sprintf(extensionName, "XY%s.psf", ccdNumber);
    248             if (!ippToPspsConfig_moveToExtensionTable(fitsIn, extensionName)) continue;
    249 
    250             // keep a running count of 'images' we find in order to write total to FrameMeta at the end
     231            long nChipDetectionsIn = 0;
     232            if (!fitsIn->moveToBinaryTableAndCountRows(fitsIn, extensionName, &nChipDetectionsIn)) continue;
     233
     234            // keep a running count of 'images' we find in order to write total into FrameMeta at the end
    251235            nOta++;
    252 
    253             long nChipDetectionsIn = 0;
    254             if (fits_get_num_rows(fitsIn, &nChipDetectionsIn, &status)) {
    255                 fits_report_error(stderr, status);
    256             }
    257236
    258237            // loop round detections to populate some extra stuff
    259238            s = d = nChipDetectionsOut = invalidDvoRows = 0;
    260239
    261             // determine column numbers for certain IPP detection columns
     240            // determine column numbers for certain IPP detection columns - do this only once to save time
    262241            if (firstTimeIn) {
    263242
    264                 status=0;fits_get_colnum(fitsIn, CASESEN, "IPP_IDET", &ippIDetNum, &status);
    265                 if (status) psError(PS_ERR_IO, false, "Unable to read col num for IPP_IDET");
    266                 status=0;fits_get_colnum(fitsIn, CASESEN, "PSF_INST_MAG", &instMagNum, &status);
    267                 if (status) psError(PS_ERR_IO, false, "Unable to read col num for PSF_INST_MAG");
    268                 status=0;fits_get_colnum(fitsIn, CASESEN, "PSF_INST_MAG_SIG", &instMagErrNum, &status);
    269                 if (status) psError(PS_ERR_IO, false, "Unable to read col num for PSF_INST_MAG_SIG");
    270                 status=0;fits_get_colnum(fitsIn, CASESEN, "PEAK_FLUX_AS_MAG", &peakMagNum, &status);
    271                 if (status) psError(PS_ERR_IO, false, "Unable to read col num for PEAK_FLUX_AS_MAG");
     243                fitsIn->getColumnNumber(fitsIn, "IPP_IDET", &ippIDetNum);
     244                fitsIn->getColumnNumber(fitsIn, "PSF_INST_MAG", &instMagNum);
     245                fitsIn->getColumnNumber(fitsIn, "PSF_INST_MAG_SIG", &instMagErrNum);
     246                fitsIn->getColumnNumber(fitsIn, "PEAK_FLUX_AS_MAG", &peakMagNum);
    272247
    273248                firstTimeIn=false;
    274249            }
    275250
    276             anynull = 0;
    277             fits_read_col(fitsIn, TLONG, ippIDetNum, 1, 1, nChipDetectionsIn, &longnull, ippIDet, &anynull, &status);
    278             fits_read_col(fitsIn, TFLOAT, instMagNum, 1, 1, nChipDetectionsIn, &floatnull, instMag, &anynull, &status);
    279             fits_read_col(fitsIn, TFLOAT, instMagErrNum, 1, 1, nChipDetectionsIn, &floatnull, instMagErr, &anynull, &status);
    280             fits_read_col(fitsIn, TFLOAT, peakMagNum, 1, 1, nChipDetectionsIn, &floatnull, peakMag, &anynull, &status);
     251            //anynull = 0;
     252            fitsIn->readColumn(fitsIn, TLONG, ippIDetNum, 1, 1, nChipDetectionsIn, ippIDet);
     253            fitsIn->readColumn(fitsIn, TFLOAT, instMagNum, 1, 1, nChipDetectionsIn, instMag);
     254            fitsIn->readColumn(fitsIn, TFLOAT, instMagErrNum, 1, 1, nChipDetectionsIn, instMagErr);
     255            fitsIn->readColumn(fitsIn, TFLOAT, peakMagNum, 1, 1, nChipDetectionsIn, peakMag);
    281256
    282257            // DVO detections are ordered by IPP_IDET, which increments from 0 in SMF table
     
    288263            // loop through all detections in smf file extension for this chip.
    289264            // there are three ways for a detection to be ommitted from the final FITS output:
     265            //
    290266            // 1. it has a duplicate obj ID to a previous detection
    291267            // 2. it has an invalid detection ID (< 0 or > max DVO det ID)
     
    355331
    356332            // write number of rows (detections) to ImageMeta
    357             fits_write_col(this->base.fitsOut, TLONG, IMAGEMETA_NDETECT, 1, 1, 1, &nChipDetectionsOut, &status);
     333            this->base.fitsOut->writeColumn(this->base.fitsOut, TLONG, IMAGEMETA_NDETECT, 1, 1, 1, &nChipDetectionsOut);
    358334
    359335            int totalRemove = numOfDuplicates+numInvalidFlux+numOfInvalidIppIDet;
     
    363339
    364340                // detections
    365                 ippToPspsConfig_writeTable(this->base.config, fitsIn, this->base.fitsOut, nChipDetectionsIn, "Detection", false);
    366                 fits_write_col(this->base.fitsOut, TLONGLONG, DETECTION_OBJID, 1, 1, nChipDetectionsIn, objID, &status);
    367                 fits_write_col(this->base.fitsOut, TLONGLONG, DETECTION_DETECTID, 1, 1, nChipDetectionsIn, detectID, &status);
    368                 fits_write_col(this->base.fitsOut, TLONGLONG, DETECTION_IPPOBJID, 1, 1, nChipDetectionsIn, ippObjID, &status);
    369                 fits_write_col(this->base.fitsOut, TLONGLONG, DETECTION_IPPDETECTID, 1, 1, nChipDetectionsIn, ippDetectID, &status);
    370                 fits_write_col(this->base.fitsOut, TBYTE, DETECTION_FILTERID, 1, 1, nChipDetectionsIn, filterIDs, &status);
    371                 fits_write_col(this->base.fitsOut, TBYTE, DETECTION_SURVEYID, 1, 1, nChipDetectionsIn, surveyIDs, &status);
    372                 fits_write_col(this->base.fitsOut, TLONGLONG, DETECTION_IMAGEID, 1, 1, nChipDetectionsIn, imageID, &status);
    373                 fits_write_col(this->base.fitsOut, TDOUBLE, DETECTION_OBSTIME, 1, 1, nChipDetectionsIn, obsTimes, &status);
    374                 fits_write_col(this->base.fitsOut, TFLOAT, DETECTION_INSTFLUX, 1, 1, nChipDetectionsIn, instFlux, &status);
    375                 fits_write_col(this->base.fitsOut, TFLOAT, DETECTION_INSTFLUXERR, 1, 1, nChipDetectionsIn, instFluxErr, &status);
    376                 fits_write_col(this->base.fitsOut, TFLOAT, DETECTION_PEAKADU, 1, 1, nChipDetectionsIn, peakFlux, &status);
    377                 fits_write_col(this->base.fitsOut, TSTRING, DETECTION_ASSOCDATE, 1, 1, nChipDetectionsIn, assocDate, &status);
    378                 fits_write_col(this->base.fitsOut, TLONGLONG, DETECTION_INFOFLAG, 1, 1, nChipDetectionsIn, flags, &status);
    379                 if (numOfDuplicates||numInvalidFlux||numOfInvalidIppIDet)
    380                     fits_delete_rowlist(this->base.fitsOut, removeList, totalRemove, &status);
     341                this->base.config->createAndPopulateTable(this->base.config, fitsIn, this->base.fitsOut, nChipDetectionsIn, "Detection", false);
     342                this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, DETECTION_OBJID, 1, 1, nChipDetectionsIn, objID);
     343                this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, DETECTION_DETECTID, 1, 1, nChipDetectionsIn, detectID);
     344                this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, DETECTION_IPPOBJID, 1, 1, nChipDetectionsIn, ippObjID);
     345                this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, DETECTION_IPPDETECTID, 1, 1, nChipDetectionsIn, ippDetectID);
     346                this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, DETECTION_FILTERID, 1, 1, nChipDetectionsIn, filterIDs);
     347                this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, DETECTION_SURVEYID, 1, 1, nChipDetectionsIn, surveyIDs);
     348                this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, DETECTION_IMAGEID, 1, 1, nChipDetectionsIn, imageID);
     349                this->base.fitsOut->writeColumn(this->base.fitsOut, TDOUBLE, DETECTION_OBSTIME, 1, 1, nChipDetectionsIn, obsTimes);
     350                this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, DETECTION_INSTFLUX, 1, 1, nChipDetectionsIn, instFlux);
     351                this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, DETECTION_INSTFLUXERR, 1, 1, nChipDetectionsIn, instFluxErr);
     352                this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, DETECTION_PEAKADU, 1, 1, nChipDetectionsIn, peakFlux);
     353                this->base.fitsOut->writeColumn(this->base.fitsOut, TSTRING, DETECTION_ASSOCDATE, 1, 1, nChipDetectionsIn, assocDate);
     354                this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, DETECTION_INFOFLAG, 1, 1, nChipDetectionsIn, flags);
     355                if (numOfDuplicates||numInvalidFlux||numOfInvalidIppIDet) this->base.fitsOut->deleteRows(this->base.fitsOut, removeList, totalRemove);
    381356
    382357                // skinny object
    383                 ippToPspsConfig_writeTable(this->base.config, fitsIn, this->base.fitsOut, nChipDetectionsIn, "SkinnyObject", false);
    384                 fits_write_col(this->base.fitsOut, TLONGLONG, SKINNYOBJECT_OBJID, 1, 1, nChipDetectionsIn, objID, &status);
    385                 fits_write_col(this->base.fitsOut, TLONGLONG, SKINNYOBJECT_IPPOBJID, 1, 1, nChipDetectionsIn, ippObjID, &status);
    386                 fits_write_col(this->base.fitsOut, TBYTE, SKINNYOBJECT_SURVEYID, 1, 1, nChipDetectionsIn, surveyIDs, &status);
    387                 if (numOfDuplicates||numInvalidFlux||numOfInvalidIppIDet)
    388                     fits_delete_rowlist(this->base.fitsOut, removeList, totalRemove, &status);
     358                this->base.config->createAndPopulateTable(this->base.config, fitsIn, this->base.fitsOut, nChipDetectionsIn, "SkinnyObject", false);
     359                this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, SKINNYOBJECT_OBJID, 1, 1, nChipDetectionsIn, objID);
     360                this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, SKINNYOBJECT_IPPOBJID, 1, 1, nChipDetectionsIn, ippObjID);
     361                this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, SKINNYOBJECT_SURVEYID, 1, 1, nChipDetectionsIn, surveyIDs);
     362                if (numOfDuplicates||numInvalidFlux||numOfInvalidIppIDet) this->base.fitsOut->deleteRows(this->base.fitsOut, removeList, totalRemove);
    389363
    390364                // object calibration color
    391                 ippToPspsConfig_writeTable(this->base.config, fitsIn, this->base.fitsOut, nChipDetectionsIn, "ObjectCalColor", false);
    392                 fits_write_col(this->base.fitsOut, TLONGLONG, OBJECTCALCOLOR_OBJID, 1, 1, nChipDetectionsIn, objID, &status);
    393                 fits_write_col(this->base.fitsOut, TLONGLONG, OBJECTCALCOLOR_IPPOBJID, 1, 1, nChipDetectionsIn, ippObjID, &status);
    394                 fits_write_col(this->base.fitsOut, TBYTE, OBJECTCALCOLOR_FILTERID, 1, 1, nChipDetectionsIn, filterIDs, &status);
    395                 if (numOfDuplicates||numInvalidFlux||numOfInvalidIppIDet)
    396                     fits_delete_rowlist(this->base.fitsOut, removeList, totalRemove, &status);
     365                this->base.config->createAndPopulateTable(this->base.config, fitsIn, this->base.fitsOut, nChipDetectionsIn, "ObjectCalColor", false);
     366                this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, OBJECTCALCOLOR_OBJID, 1, 1, nChipDetectionsIn, objID);
     367                this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, OBJECTCALCOLOR_IPPOBJID, 1, 1, nChipDetectionsIn, ippObjID);
     368                this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, OBJECTCALCOLOR_FILTERID, 1, 1, nChipDetectionsIn, filterIDs);
     369                if (numOfDuplicates||numInvalidFlux||numOfInvalidIppIDet) this->base.fitsOut->deleteRows(this->base.fitsOut, removeList, totalRemove);
    397370            }
    398371
     
    436409
    437410    // write number of images we have found into FrameMeta table
    438     if (ippToPspsConfig_moveToExtensionTable(this->base.fitsOut, "FrameMeta")) {
    439 
    440         fits_write_col(this->base.fitsOut, TSHORT, FRAMEMETA_NOTA, 1, 1, 1, &nOta, &status);
    441         fits_write_col(this->base.fitsOut, TSHORT, FRAMEMETA_NUMPHOTOREF, 1, 1, 1, &totalNumPhotoRef, &status);
    442     }
    443 
    444     status=0;
    445     if (fits_close_file(fitsIn, &status)) fits_report_error(stderr, status);
     411    if (this->base.fitsOut->moveToBinaryTable(this->base.fitsOut, "FrameMeta")) {
     412
     413        this->base.fitsOut->writeColumn(this->base.fitsOut, TSHORT, FRAMEMETA_NOTA, 1, 1, 1, &nOta);
     414        this->base.fitsOut->writeColumn(this->base.fitsOut, TSHORT, FRAMEMETA_NUMPHOTOREF, 1, 1, 1, &totalNumPhotoRef);
     415    }
     416
     417    fitsIn->destroy(fitsIn);
    446418
    447419    writeResults(this, minObjID, maxObjID, totalDetectionsOut);
     
    496468    }
    497469
    498     this->base.parseArguments(&this->base, argc, argv);
     470    char fitsOutFile[40];
     471    sprintf(fitsOutFile, "%08d.FITS", this->expId);
     472    this->base.parseArguments(&this->base, argc, argv, "/detection", fitsOutFile);
    499473
    500474    if (
     
    532506    this->MAXDETECT = 200000;
    533507
     508    // method pointers
    534509    this->print = print;
    535510    this->destroy = destroy;
     
    538513    this->expName = (char*)calloc(100, sizeof(char));
    539514
    540     if (!parseArguments(this, *argc, argv)) { return this; }
    541 
    542     strcat(this->base.configsDir, "/detection");
    543     sprintf(this->base.fitsOutFile, "%08d.FITS", this->expId);
    544 
    545     this->base.init(&this->base);
     515    parseArguments(this, *argc, argv);
    546516
    547517    return this;
     
    565535    detectionBatch->destroy(detectionBatch);
    566536
    567     double secs = psTimerMark("ippToPsps");
     537    double secs = psTimerMark("detectionbatch");
    568538
    569539    psLogMsg("detectionbatch", 3, "detectionbatch completed %ssuccessfully, with exit code %d, in %.1f %s\n",
  • trunk/ippToPsps/src/InitBatch.c

    r30147 r31011  
    1818    if (this->base.exitCode != PS_EXIT_SUCCESS) return this->base.exitCode;
    1919
    20     if (!ippToPspsConfig_populateFromFile(this->base.config, this->base.fitsOut))
     20    if (!this->base.config->populateFromFile(this->base.config, this->base.fitsOut))
    2121        this->base.exitCode = PS_EXIT_CONFIG_ERROR;
    2222    else this->base.exitCode = PS_EXIT_SUCCESS;
     
    3434
    3535/**
    36   Reads command-line arguments.  Calls base-calls print method first.
     36  Reads command-line arguments.
    3737  */
    3838static bool parseArguments(InitBatch* this, int argc, char **argv) {
    3939
    40     this->base.parseArguments(&this->base, argc, argv);
     40    this->base.parseArguments(&this->base, argc, argv, "/init", "00000000.FITS");
    4141
    4242    if (
     
    6868    }
    6969
     70    // method pointers
    7071    this->print = print;
    7172    this->destroy = destroy;
    7273    this->base.run = run;
    7374
    74     if (!parseArguments(this, *argc, argv)) { return this; }
    75 
    76     strcat(this->base.configsDir, "/init");
    77     sprintf(this->base.fitsOutFile, "00000000.FITS");
    78 
    79     this->base.init(&this->base);
     75    parseArguments(this, *argc, argv);
    8076
    8177    return this;
  • trunk/ippToPsps/src/InitBatch.h

    r30147 r31011  
    2424    // methods
    2525    void (*print)();
     26
     27    // destructor
    2628    void (*destroy)();
    2729
    2830} InitBatch;
    2931
     32// constructor
    3033InitBatch *new_InitBatch(int *argc, char **argv);
    3134
  • trunk/ippToPsps/src/StackBatch.c

    r30147 r31011  
    11#include "StackBatch.h"
    22#include "StackBatchEnums.h"
     3
     4#include "Fits.h"
    35
    46/**
     
    1315
    1416/**
    15   Does the work.
    16   */
    17 static int run(StackBatch* this) {
    18 
    19     if (this->base.exitCode != PS_EXIT_SUCCESS) return this->base.exitCode;
    20 
    21     int status = 0;
    22     fitsfile *fitsIn;
    23 
    24     if (fits_open_file(&fitsIn, this->base.inputFiles[0], READONLY, &status)) {
    25 
    26         fits_report_error(stderr, status);
    27         return PS_EXIT_SYS_ERROR;
    28     }
    29 
    30 
    31     // get primary header and pull stuff out for later
    32     int nKeys = 0;
    33     fits_get_hdrspace(fitsIn, &nKeys, NULL, &status);
    34     float exposureTime; status=0; fits_read_key(fitsIn, TFLOAT, "EXPTIME", &exposureTime, NULL, &status);
    35     char filterType[20]; status=0; fits_read_key(fitsIn, TSTRING, "FILTER", filterType, NULL, &status);
    36 
    37 
     17  Creates the StackDetection table
     18  */
     19static bool createStackDetectionTable(
     20        StackBatch* this,
     21        Fits* fitsIn,
     22        int8_t* filterIDs,
     23        int8_t* surveyIDs,
     24        long* skycellIDs,
     25        float exposureTime
     26        ) {
     27
     28    char extensionName[25];
     29    sprintf(extensionName, "SkyChip.psf");
     30    long nDet = 0;
     31    if (!fitsIn->moveToBinaryTableAndCountRows(fitsIn, extensionName, &nDet)) return false;
     32
     33
     34    // allocate stuff
    3835    char** assocDate = (char**)calloc(this->MAXDETECT, sizeof(char**));
    3936    for (uint32_t i=0; i<this->MAXDETECT;i++) assocDate[i] = (char*)calloc(20,sizeof(char));
    40 
    41 
    42 
    43     // write StackMeta
    44     ippToPspsConfig_writeTable(this->base.config, fitsIn, this->base.fitsOut, 1, "StackMeta", true);
    45     fits_write_col(this->base.fitsOut, TLONG, STACKMETA_SKYCELLID, 1, 1, 1, &this->skycellId, &status);
    46 
    47     int8_t filterID = -1;
    48     if (!ippToPspsConfig_getFilterId(this->base.config, filterType, &filterID)) {
    49 
    50 //        this->base.exitCode = PS_EXIT_DATA_ERROR;
    51     //    return this->base.exitCode; TODO
    52     }
    53 
    5437    long* removeList = (long*)calloc(this->MAXDETECT, sizeof(long));
    5538    float* instMag = (float*)calloc(this->MAXDETECT, sizeof(float));
    56     int8_t* filterIDs = (int8_t*)calloc(this->MAXDETECT, sizeof(int8_t));
    57     int8_t* surveyIDs = (int8_t*)calloc(this->MAXDETECT, sizeof(int8_t));
    58     float floatnull = -999.0;
    59     int anynull = 0;
    60 
    61     fits_write_col(this->base.fitsOut, TBYTE, STACKMETA_FILTERID, 1, 1, 1, &filterID, &status);
    62 
    63     fits_write_col(this->base.fitsOut, TBYTE, STACKMETA_SURVEYID, 1, 1, 1, &this->base.surveyID, &status);
    64 
    65 
    66     // psf detections
    67     char extensionName[15];
    68     sprintf(extensionName, "Chip.psf");
    69     if (fits_movnam_hdu(fitsIn, BINARY_TBL, extensionName, 0, &status)) {
    70         psError(PS_ERR_IO, false, "Can't move to extension: %s\n", extensionName);
    71 
    72     }
    73     else {
    74 
    75         // some stuff is the same for all detections so we can populate here
    76         for (long s = 0; s<this->MAXDETECT; s++) {
    77 
    78             filterIDs[s] = filterID;
    79             surveyIDs[s] = this->base.surveyID;
    80             strcpy(assocDate[s], this->base.todaysDate);
     39    float* peakMag = (float*)calloc(this->MAXDETECT, sizeof(float));
     40    float* peakFlux = (float*)calloc(this->MAXDETECT, sizeof(float));
     41    int* flags1 = (int*)calloc(this->MAXDETECT, sizeof(int));
     42    int* flags2 = (int*)calloc(this->MAXDETECT, sizeof(int));
     43    uint64_t* infoFlags = (uint64_t*)calloc(this->MAXDETECT, sizeof(uint64_t));
     44
     45    bool peakFluxOk;
     46
     47    // some stuff is the same for all detections so we can populate here
     48    for (long s = 0; s<this->MAXDETECT; s++) {
     49
     50        // if running in test mode, don't use today's date
     51        if (this->base.testMode) strcpy(assocDate[s], "2010-01-01");
     52        else strcpy(assocDate[s], this->base.todaysDate);
     53    }
     54
     55    fitsIn->readColumnUsingName(fitsIn, TFLOAT, "PSF_INST_MAG", 1, 1, nDet, instMag);
     56    fitsIn->readColumnUsingName(fitsIn, TFLOAT, "PEAK_FLUX_AS_MAG", 1, 1, nDet, peakMag);
     57    fitsIn->readColumnUsingName(fitsIn, TLONG, "FLAGS", 1, 1, nDet, flags1);
     58    fitsIn->readColumnUsingName(fitsIn, TLONG, "FLAGS2", 1, 1, nDet, flags2);
     59
     60    printf("Looping through %ld psf detections\n", nDet);
     61    float mag;
     62    long unmatched = 0, totalDetections = 0, numOfDuplicates = 0, numInvalidFlux = 0, numDetectionsOut = 0;
     63
     64    for (long s=0; s<nDet; s++) {
     65
     66        // TODO implement this match in DVO
     67        if (1) {
     68
     69            //infoFlags[s] = ((uint64_t)flags1[s] << 32) | (uint64_t)flags2[s]; TODO implement after schema change to make infoFlag 64-bit
     70            infoFlags[s] = (uint64_t)flags1[s];
     71
     72            peakFluxOk = getFlux(exposureTime, peakMag[s], &peakFlux[s], 0.0, NULL);
     73
     74            mag = instMag[s];
     75            if (!peakFluxOk || !isfinite(mag) || mag < -998.0) {
     76
     77                removeList[numOfDuplicates+numInvalidFlux] = s+1;
     78                numInvalidFlux++;
     79            }
     80
     81            totalDetections++;
    8182        }
    82 
    83 
    84         long nDet = 0;
    85         if (fits_get_num_rows(fitsIn, &nDet, &status)) {
    86             fits_report_error(stderr, status);
     83        else {
     84
     85            unmatched++;
     86            continue;
    8787        }
    88 
    89         int instMagNum;
    90         status=0;fits_get_colnum(fitsIn, CASESEN, "PSF_INST_MAG", &instMagNum, &status);
    91         if (status) psError(PS_ERR_IO, false, "Unable to read col num for PSF_INST_MAG");
    92         fits_read_col(fitsIn, TFLOAT, instMagNum, 1, 1, nDet, &floatnull, instMag, &anynull, &status);
    93 
    94 
    95         printf("Looping through %ld psf detections\n", nDet);
    96         float mag;
    97         long unmatched = 0, totalDetections = 0, numOfDuplicates = 0, numInvalidFlux = 0, numDetectionsOut = 0;
    98 
    99         for (long s = 0; s<nDet; s++) {
    100 
    101             // TODO implement this match in DVO
    102             if (1) {
    103 
    104                 mag = instMag[s];
    105                 if (!isfinite(mag) || mag < -998.0) {
    106 
    107                     removeList[numOfDuplicates+numInvalidFlux] = s+1;
    108                     numInvalidFlux++;
    109                 }
    110 
    111                 totalDetections++;
    112             }
    113             else {
    114 
    115                 unmatched++;
    116                 continue;
    117             }
    118         }
    119 
    120         numDetectionsOut = totalDetections - numInvalidFlux;
    121 
    122         if (numDetectionsOut > 0) {
    123 
    124             ippToPspsConfig_writeTable(this->base.config, fitsIn, this->base.fitsOut, nDet, "StackDetection", false);
    125             fits_write_col(this->base.fitsOut, TLONG, STACKDETECTION_SKYCELLID, 1, 1, 1, &this->skycellId, &status);
    126             fits_write_col(this->base.fitsOut, TBYTE, STACKDETECTION_FILTERID, 1, 1, nDet, filterIDs, &status);
    127             fits_write_col(this->base.fitsOut, TBYTE, STACKDETECTION_SURVEYID, 1, 1, nDet, surveyIDs, &status);
    128             fits_write_col(this->base.fitsOut, TSTRING, STACKDETECTION_ASSOCDATE, 1, 1, nDet, assocDate, &status);
    129 
    130             if (numInvalidFlux) fits_delete_rowlist(this->base.fitsOut, removeList, numInvalidFlux, &status);
    131 
    132         }
    133         psLogMsg("ippToPsps", PS_LOG_INFO,
    134                 "+---------------+---------+----------+------------------+---------------+--------------+\n"
    135                 "|   Extension   | Rows in | Rows out | Missing from DVO | Duplicate IDs | Invalid Flux |\n"
    136                 "|  %12s |  %5ld  |   %5ld  |      %5ld       |    %5ld      |    %5ld     |\n",
    137                 extensionName, nDet, numDetectionsOut, unmatched, numOfDuplicates, numInvalidFlux);
    138 
    139     }
    140 
    141 
    142 
    143     // extended source
    144     sprintf(extensionName, "Chip.xsrc");
    145     if (fits_movnam_hdu(fitsIn, BINARY_TBL, extensionName, 0, &status)) {
    146         psError(PS_ERR_IO, false, "Can't move to extension: %s\n", extensionName);
    147 
    148     }
    149     else {
    150 
    151         int colNum;
    152         int type;
    153         long repeat;
    154 
    155         ippToPspsConfig_getFitsColumnMeta(
    156                 "PROF_FLUX",
    157                 &colNum,
    158                 &type,
    159                 &repeat,
    160                 fitsIn);
    161         printf("PROF_FILL = %d %d %ld\n", colNum, type, repeat);
    162         float* vector = calloc(repeat, sizeof(float));
    163 
    164         ippToPspsConfig_getColumnVector(
    165                 colNum,
    166                 1,
    167                 type,
    168                 repeat,
    169                 vector,
    170                 fitsIn);
    171 
    172 
    173 
    174         free(vector);
    175 
    176         long nDet = 0;
    177         if (fits_get_num_rows(fitsIn, &nDet, &status)) {
    178             fits_report_error(stderr, status);
    179         }
    180 
    181         printf("Looping through %ld extended source detections\n", nDet);
    182         for (long s = 0; s<nDet; s++) {
    183 
    184 
    185 
    186         }
    187 
    188         ippToPspsConfig_writeTable(this->base.config, fitsIn, this->base.fitsOut, nDet, "StackApFlx", false);
    189         fits_write_col(this->base.fitsOut, TBYTE, STACKAPFLX_FILTERID, 1, 1, nDet, filterIDs, &status);
    190         fits_write_col(this->base.fitsOut, TBYTE, STACKAPFLX_SURVEYID, 1, 1, nDet, surveyIDs, &status);
    191     }
     88    }
     89
     90    numDetectionsOut = totalDetections - numInvalidFlux;
     91    if (numDetectionsOut > 0) {
     92
     93        this->base.config->createAndPopulateTable(this->base.config, fitsIn, this->base.fitsOut, nDet, "StackDetection", false);
     94        this->base.fitsOut->writeColumn(this->base.fitsOut, TLONG, STACKDETECTION_SKYCELLID, 1, 1, nDet, skycellIDs);
     95        this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, STACKDETECTION_FILTERID, 1, 1, nDet, filterIDs);
     96        this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKDETECTION_PEAKFLUX, 1, 1, nDet, peakFlux);
     97        this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, STACKDETECTION_SURVEYID, 1, 1, nDet, surveyIDs);
     98        this->base.fitsOut->writeColumn(this->base.fitsOut, TSTRING, STACKDETECTION_ASSOCDATE, 1, 1, nDet, assocDate);
     99        this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, STACKDETECTION_INFOFLAG, 1, 1, nDet, flags1);
     100
     101        if (numInvalidFlux) this->base.fitsOut->deleteRows(this->base.fitsOut, removeList, numInvalidFlux);
     102
     103    }
     104    psLogMsg("ippToPsps", PS_LOG_INFO,
     105            "+---------------+---------+----------+------------------+---------------+--------------+\n"
     106            "|   Extension   | Rows in | Rows out | Missing from DVO | Duplicate IDs | Invalid Flux |\n"
     107            "|  %12s |  %5ld  |   %5ld  |      %5ld       |    %5ld      |    %5ld     |\n",
     108            extensionName, nDet, numDetectionsOut, unmatched, numOfDuplicates, numInvalidFlux);
    192109
    193110
     
    195112    free(removeList);
    196113    free(instMag);
     114    free(flags1);
     115    free(flags2);
     116    free(infoFlags);
     117    for (uint32_t i=0; i<this->MAXDETECT;i++) free(assocDate[i]);
     118    free(assocDate);
     119
     120    return true;
     121}
     122/**
     123  Structure to encapsulate block of flux values for StackApFlx table
     124  */
     125typedef struct {
     126
     127    float* flx;
     128    float* flxErr;
     129    float* flxStd;
     130    float* flxFill;
     131
     132} StackApFlxFluxes;
     133
     134/**
     135  Creates the StackApFlx table for extended source attributes
     136  */
     137static bool createStackApFlxTable(
     138        StackBatch* this,
     139        Fits* fitsIn,
     140        int8_t* filterIDs,
     141        int8_t* surveyIDs
     142        ) {
     143
     144    long nDet = 0;
     145    if (!fitsIn->moveToBinaryTableAndCountRows(fitsIn, "SkyChip.xrad", &nDet)) return false;
     146
     147
     148    int aperFluxColNum, aperFluxErrColNum, aperFluxStDevColNum, aperFluxFillColNum;
     149    int type; // all the same type
     150    long repeat;
     151
     152    fitsIn->getColumnMeta(fitsIn, "APER_FLUX", &aperFluxColNum, &type, &repeat);
     153    fitsIn->getColumnMeta(fitsIn, "APER_FLUX_ERR", &aperFluxErrColNum, &type, &repeat);
     154    fitsIn->getColumnMeta(fitsIn, "APER_FLUX_STDEV", &aperFluxStDevColNum, &type, &repeat);
     155    fitsIn->getColumnMeta(fitsIn, "APER_FILL", &aperFluxFillColNum, &type, &repeat);
     156    float* vector = calloc(repeat, sizeof(float));
     157
     158    // we store 10 different flux values
     159    StackApFlxFluxes* stackApFlxFluxes = (StackApFlxFluxes*)calloc(11, sizeof(StackApFlxFluxes));
     160    for (long i=0; i<11; i++) {
     161
     162        stackApFlxFluxes[i].flx = (float*)calloc(nDet, sizeof(float));
     163        stackApFlxFluxes[i].flxErr = (float*)calloc(nDet, sizeof(float));
     164        stackApFlxFluxes[i].flxStd = (float*)calloc(nDet, sizeof(float));
     165        stackApFlxFluxes[i].flxFill = (float*)calloc(nDet, sizeof(float));
     166    }
     167
     168    printf("Looping through %ld extended source detections\n", nDet);
     169    for (long s=0; s<nDet; s++) {
     170
     171        fitsIn->getColumnVector(fitsIn, aperFluxColNum,s, type, repeat, vector);
     172        for (int i=0; i<repeat; i++) stackApFlxFluxes[i].flx[s] = vector[i];
     173
     174        fitsIn->getColumnVector(fitsIn, aperFluxErrColNum,s, type, repeat, vector);
     175        for (int i=0; i<repeat; i++) stackApFlxFluxes[i].flxErr[s] = vector[i];
     176
     177        fitsIn->getColumnVector(fitsIn, aperFluxStDevColNum,s, type, repeat, vector);
     178        for (int i=0; i<repeat; i++) stackApFlxFluxes[i].flxStd[s] = vector[i];
     179
     180        fitsIn->getColumnVector(fitsIn, aperFluxFillColNum,s, type, repeat, vector);
     181        for (int i=0; i<repeat; i++) stackApFlxFluxes[i].flxFill[s] = vector[i];
     182
     183    }
     184
     185    free(vector);
     186
     187    //int status = 0;
     188    this->base.config->createAndPopulateTable(this->base.config, fitsIn, this->base.fitsOut, nDet, "StackApFlx", false);
     189    this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, STACKAPFLX_FILTERID, 1, 1, nDet, filterIDs);
     190    this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, STACKAPFLX_SURVEYID, 1, 1, nDet, surveyIDs);
     191
     192    // R1->r10 flux values
     193    // 1
     194    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR1, 1, 1, nDet, stackApFlxFluxes[0].flx);
     195    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR1ERR, 1, 1, nDet, stackApFlxFluxes[0].flxErr);
     196    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR1STD, 1, 1, nDet, stackApFlxFluxes[0].flxStd);
     197    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR1FILL, 1, 1, nDet, stackApFlxFluxes[0].flxFill);
     198    // 2
     199    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR2, 1, 1, nDet, stackApFlxFluxes[1].flx);
     200    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR2ERR, 1, 1, nDet, stackApFlxFluxes[1].flxErr);
     201    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR2STD, 1, 1, nDet, stackApFlxFluxes[1].flxStd);
     202    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR2FILL, 1, 1, nDet, stackApFlxFluxes[1].flxFill);
     203    // 3
     204    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR3, 1, 1, nDet, stackApFlxFluxes[2].flx);
     205    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR3ERR, 1, 1, nDet, stackApFlxFluxes[2].flxErr);
     206    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR3STD, 1, 1, nDet, stackApFlxFluxes[2].flxStd);
     207    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR3FILL, 1, 1, nDet, stackApFlxFluxes[2].flxFill);
     208    // 4
     209    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR4, 1, 1, nDet, stackApFlxFluxes[3].flx);
     210    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR4ERR, 1, 1, nDet, stackApFlxFluxes[3].flxErr);
     211    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR4STD, 1, 1, nDet, stackApFlxFluxes[3].flxStd);
     212    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR4FILL, 1, 1, nDet, stackApFlxFluxes[3].flxFill);
     213    // 5
     214    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR5, 1, 1, nDet, stackApFlxFluxes[4].flx);
     215    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR5ERR, 1, 1, nDet, stackApFlxFluxes[4].flxErr);
     216    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR5STD, 1, 1, nDet, stackApFlxFluxes[4].flxStd);
     217    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR5FILL, 1, 1, nDet, stackApFlxFluxes[4].flxFill);
     218    // 6
     219    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR6, 1, 1, nDet, stackApFlxFluxes[5].flx);
     220    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR6ERR, 1, 1, nDet, stackApFlxFluxes[5].flxErr);
     221    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR6STD, 1, 1, nDet, stackApFlxFluxes[5].flxStd);
     222    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR6FILL, 1, 1, nDet, stackApFlxFluxes[5].flxFill);
     223    // 7
     224    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR7, 1, 1, nDet, stackApFlxFluxes[6].flx);
     225    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR7ERR, 1, 1, nDet, stackApFlxFluxes[6].flxErr);
     226    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR7STD, 1, 1, nDet, stackApFlxFluxes[6].flxStd);
     227    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR7FILL, 1, 1, nDet, stackApFlxFluxes[6].flxFill);
     228    // 8
     229    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR8, 1, 1, nDet, stackApFlxFluxes[7].flx);
     230    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR8ERR, 1, 1, nDet, stackApFlxFluxes[7].flxErr);
     231    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR8STD, 1, 1, nDet, stackApFlxFluxes[7].flxStd);
     232    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR8FILL, 1, 1, nDet, stackApFlxFluxes[7].flxFill);
     233    // 9
     234    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR9, 1, 1, nDet, stackApFlxFluxes[8].flx);
     235    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR9ERR, 1, 1, nDet, stackApFlxFluxes[8].flxErr);
     236    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR9STD, 1, 1, nDet, stackApFlxFluxes[8].flxStd);
     237    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR9FILL, 1, 1, nDet, stackApFlxFluxes[8].flxFill);
     238    // 10
     239    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR10, 1, 1, nDet, stackApFlxFluxes[9].flx);
     240    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR10ERR, 1, 1, nDet, stackApFlxFluxes[9].flxErr);
     241    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR10STD, 1, 1, nDet, stackApFlxFluxes[9].flxStd);
     242    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR10FILL, 1, 1, nDet, stackApFlxFluxes[9].flxFill);
     243
     244    for (long i=0; i<11; i++) {
     245
     246        free(stackApFlxFluxes[i].flx);
     247        free(stackApFlxFluxes[i].flxErr);
     248        free(stackApFlxFluxes[i].flxStd);
     249        free(stackApFlxFluxes[i].flxFill);
     250    }
     251
     252    free(stackApFlxFluxes);
     253
     254    return true;
     255}
     256
     257/**
     258  Creates the StackModelFit table
     259  */
     260static bool createStackModelFitTable(
     261        StackBatch* this,
     262        Fits *fitsIn,
     263        int8_t* filterIDs,
     264        int8_t* surveyIDs) {
     265
     266    long nDet = 0;
     267    if (!fitsIn->moveToBinaryTableAndCountRows(fitsIn, "SkyChip.xfit", &nDet)) return false;
     268
     269    long* ippIdets = (long*)calloc(this->MAXDETECT, sizeof(long));
     270    char** modelTypes = (char**)calloc(this->MAXDETECT, sizeof(char**));
     271    for (uint32_t i=0; i<this->MAXDETECT;i++) modelTypes[i] = (char*)calloc(20,sizeof(char));
     272
     273    // read whole columns
     274    fitsIn->readColumnUsingName(fitsIn, TLONG, "IPP_IDET", 1, 1, nDet, ippIdets);
     275    fitsIn->readColumnUsingName(fitsIn, TSTRING, "MODEL_TYPE", 1, 1, nDet, modelTypes);
     276
     277    printf("Looping through %ld model fit rows\n", nDet);
     278    for (long i = 0; i<nDet; i++) {
     279
     280        printf("IPP_IDET %ld model %s\n", ippIdets[i], modelTypes[i]);
     281
     282    }
     283
     284    this->base.config->createAndPopulateTable(this->base.config, fitsIn, this->base.fitsOut, nDet, "StackModelFit", false);
     285    this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, STACKMODELFIT_FILTERID, 1, 1, nDet, filterIDs);
     286    this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, STACKMODELFIT_SURVEYID, 1, 1, nDet, surveyIDs);
     287
     288    // free up
     289    free(ippIdets);
     290    for (uint32_t i=0; i<this->MAXDETECT;i++) free(modelTypes[i]);
     291    free(modelTypes);
     292
     293    return true;
     294}
     295
     296/**
     297  Creates the StackToImage table
     298  */
     299static bool createStackToImageTable(
     300        StackBatch* this,
     301        Fits* fitsIn
     302        ) {
     303
     304    this->base.config->createAndPopulateTable(this->base.config, fitsIn, this->base.fitsOut, 3/*TODO*/, "StackToImage", false);
     305
     306    return true;
     307}
     308
     309/**
     310  Does the work. Writes all extensions to new FITS file.
     311  */
     312static int run(StackBatch* this) {
     313
     314    if (this->base.exitCode != PS_EXIT_SUCCESS) return this->base.exitCode;
     315
     316    // open input FITS file
     317    Fits* fitsIn = existing_Fits(this->base.inputFiles[0]);
     318    if (fitsIn->getFilePtr(fitsIn) == NULL)  return PS_EXIT_SYS_ERROR;
     319
     320    // get primary header and pull stuff out for later
     321    float exposureTime; fitsIn->getHeaderKeyValue(fitsIn, TFLOAT, "EXPTIME", &exposureTime);
     322    char filterType[20]; fitsIn->getHeaderKeyValue(fitsIn, TSTRING, "FILTER", filterType);
     323
     324    int8_t filterID = -1;
     325    if (!this->base.config->getFilterId(this->base.config, filterType, &filterID)) {
     326
     327        //        this->base.exitCode = PS_EXIT_DATA_ERROR;
     328        //    return this->base.exitCode; TODO
     329    }
     330
     331    exposureTime = 60.0;// TODO
     332    filterID = 3; // TODO
     333
     334    // write StackMeta
     335    this->base.config->createAndPopulateTable(this->base.config, fitsIn, this->base.fitsOut, 1, "StackMeta", true);
     336    this->base.fitsOut->writeColumn(this->base.fitsOut, TLONG, STACKMETA_SKYCELLID, 1, 1, 1, &this->skycellId);
     337    this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, STACKMETA_FILTERID, 1, 1, 1, &filterID);
     338    this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, STACKMETA_SURVEYID, 1, 1, 1, &this->base.surveyID);
     339
     340    // allocate stuff for other extensions
     341    int8_t* filterIDs = (int8_t*)calloc(this->MAXDETECT, sizeof(int8_t));
     342    int8_t* surveyIDs = (int8_t*)calloc(this->MAXDETECT, sizeof(int8_t));
     343    long* skycellIDs = (long*)calloc(this->MAXDETECT, sizeof(long));
     344
     345    // some stuff is the same for all detections so we can populate here
     346    for (long s = 0; s<this->MAXDETECT; s++) {
     347
     348        skycellIDs[s] = this->skycellId;
     349        filterIDs[s] = filterID;
     350        surveyIDs[s] = this->base.surveyID;
     351    }
     352
     353    // create all extensions
     354    createStackDetectionTable(this, fitsIn, filterIDs, surveyIDs, skycellIDs, exposureTime);
     355    createStackApFlxTable(this, fitsIn, filterIDs, surveyIDs);
     356    printf("dsdsdddds\n\n");
     357    createStackModelFitTable(this, fitsIn, filterIDs, surveyIDs);
     358    createStackToImageTable(this, fitsIn);
     359
     360    // free stuff up
    197361    free(filterIDs);
    198362    free(surveyIDs);
    199 
    200     status=0;
    201     if (fits_close_file(fitsIn, &status)) fits_report_error(stderr, status);
    202 
     363    free(skycellIDs);
     364    fitsIn->destroy(fitsIn);
    203365
    204366    return this->base.exitCode;
    205367}
    206 
    207368
    208369/**
     
    240401    }
    241402
    242     this->base.parseArguments(&this->base, argc, argv);
     403    char fitsOutFile[40];
     404    sprintf(fitsOutFile, "%08d.FITS", this->skycellId);
     405    this->base.parseArguments(&this->base, argc, argv, "/stack", fitsOutFile);
    243406
    244407    if (
     
    275438    this->MAXDETECT = 150000;
    276439
     440    // method pointers
    277441    this->print = print;
    278442    this->destroy = destroy;
    279443    this->base.run = run;
    280444
    281     if (!parseArguments(this, *argc, argv)) { return this; }
    282 
    283     strcat(this->base.configsDir, "/stack");
    284     sprintf(this->base.fitsOutFile, "%08d.FITS", this->skycellId);
    285 
    286     this->base.init(&this->base);
     445    parseArguments(this, *argc, argv);
    287446
    288447    return this;
     
    321480}
    322481
    323 
    324 
Note: See TracChangeset for help on using the changeset viewer.