IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Mar 30, 2011, 9:36:02 AM (15 years ago)
Author:
eugene
Message:

merging changes from trunk

Location:
branches/eam_branches/ipp-20110213/ippToPsps/src
Files:
2 deleted
10 edited
8 copied

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/ipp-20110213/ippToPsps/src

    • Property svn:ignore
      •  

        old new  
        99config.h.in
        1010stamp-h1
        11 ippToPspsVersionDefinitions.h
         11VersionDefinitions.h
         12detectionbatch
         13initbatch
         14stackbatch
         15
  • branches/eam_branches/ipp-20110213/ippToPsps/src/Batch.c

    r30191 r31083  
    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            this->logger->print(this->logger, MSG_ERROR, "Batch", "Failed, so deleting fits file\n");
     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    // destroy objects
     90    this->fitsGenerator->destroy(this->fitsGenerator);
     91    this->initData->destroy(this->initData);
    10292
    10393    pmConfigDone();
     
    115105    if (file == NULL) {
    116106
    117         psError(PS_ERR_UNKNOWN, false, "Unable to open file at %s", this->fitsInPath);
     107        this->logger->print(this->logger, MSG_ERROR, "Batch", "Unable to open file at %s\n", this->fitsInPath);
    118108        return false;
    119109    }
     
    123113    while (fgets(line, 1000, file) != NULL) this->numOfInputFiles++;
    124114
    125     printf ("Number of input files %d\n", this->numOfInputFiles);
     115    this->logger->print(this->logger, MSG_INFO, "Batch",
     116            "%d input file%s found\n", this->numOfInputFiles, (this->numOfInputFiles > 1) ? "s" : "");
    126117
    127118    if (this->numOfInputFiles < 1) return false;
     
    151142  Sets-up and reads command-line arguments
    152143*/
    153 static bool parseArguments(Batch* this, int argc, char **argv) {
     144static bool parseArguments(Batch* this, int argc, char **argv, char* configsDir, char* fitsOutFile) {
    154145
    155146    // first deal with DVO database
     
    166157    if (!this->pmconfig) {
    167158
    168         psError(PS_ERR_UNKNOWN, false, "Unable to read configuration.");
     159        this->logger->print(this->logger, MSG_ERROR, "Batch", "Unable to read configuration\n");
    169160        this->exitCode = PS_EXIT_CONFIG_ERROR;
    170161        return false;
     
    178169    haveSurveyType = false;
    179170
     171    char fitsOutPath[1000];
     172    char configsBaseDir[1000];
     173
    180174    // decode arguments
    181175    int32_t optind = 1;
     
    193187            else if(strcmp(sw, "-output") == 0 ) {
    194188                optind++; if( optind > ( argc-1 ) ) break;
    195                 strcpy(this->fitsOutPath, argv[optind]);
     189                strcpy(fitsOutPath, argv[optind]);
    196190                haveFitsOutPath = true;
    197191            }
     
    203197            else if(strcmp(sw, "-config") == 0 ) {
    204198                optind++; if( optind > ( argc-1 ) ) break;
    205                 strcpy(this->configsDir, argv[optind]);
     199                strcpy(configsBaseDir, argv[optind]);
    206200                haveConfig = true;
    207201            }
     
    211205                haveSurveyType = true;
    212206            }
     207            else if(strcmp(sw, "-test") == 0 ) {
     208                this->testMode = true;
     209            }
    213210        }
    214211
     
    216213    }
    217214
    218 
    219     // setup command line arguments
    220     //psMetadataAddStr(this->arguments, PS_LIST_TAIL, "-survey", 0, "Survey type", NULL);
    221 
    222 
    223     // now check rest of arguments
    224     //if (argc < 2 || !psArgumentParse(this->arguments, &argc, argv)) {
    225 
    226       //  usage(this, argv[0]);
    227         //this->exitCode = PS_EXIT_CONFIG_ERROR;
    228         //return false;
    229    // }
    230 
    231     //this->surveyType = psMemIncrRefCounter(psMetadataLookupStr(NULL, this->arguments, "-survey"));
    232 
     215    // check we have some input paths
    233216    if (haveFitsInPath && !readInputFilePaths(this)) {
    234217
     
    237220    }
    238221
    239     return true;
    240 }
    241 
    242 /**
    243   Initialises file paths, creates FITS file etc
    244   */
    245 bool init(Batch* this) {
    246 
    247     // create a config object
    248     this->config = ippToPspsConfig_Constructor(this->configsDir);
    249     if (this->config == NULL) {
     222    // create an InitData object and get survey ID
     223    this->initData = new_InitData(configsBaseDir, this->logger);
     224    if (strlen(this->surveyType) > 0 &&
     225            !this->initData->getSurveyId(this->initData, this->surveyType, &this->surveyID)) {
    250226
    251227        this->exitCode = PS_EXIT_CONFIG_ERROR;
     
    253229    }
    254230
    255     // get survey ID using config object
    256     if (strlen(this->surveyType) > 0 && !ippToPspsConfig_getSurveyId(this->config, this->surveyType, &this->surveyID)) {
    257 
    258         this->exitCode = PS_EXIT_CONFIG_ERROR;
    259         return false;
    260     }
     231    // create a FitsGenerator object
     232    strcat(configsBaseDir, configsDir);
     233    this->fitsGenerator = new_FitsGenerator(this->logger, configsBaseDir);
     234
    261235    // create full FITS out path
    262     sprintf (this->fitsOutPath, "%s/%s", this->fitsOutPath, this->fitsOutFile);
     236    sprintf(fitsOutPath, "%s/%s", fitsOutPath, fitsOutFile);
    263237
    264238    // create an output FITS file
    265     int status=0;
    266     if (fits_create_file(&this->fitsOut, this->fitsOutPath, &status)) {
    267         fits_report_error(stderr, status);
    268         psError(PS_ERR_IO, false, "Unable to create file at: '%s'", this->fitsOutPath);
    269         this->exitCode = PS_EXIT_SYS_ERROR;
    270         this->fitsOut = NULL;
    271         return false;
    272     }
     239    this->fitsOut = new_Fits(fitsOutPath, this->logger);
     240    if (this->fitsOut->getFilePtr(this->fitsOut) == NULL) return false;
    273241
    274242    // create XML document for results
     
    278246        xmlNodePtr rootNode = xmlNewNode(NULL, BAD_CAST "ippToPsps_Results");
    279247        xmlDocSetRootElement(this->resultsXmlDoc, rootNode);
    280         xmlNewChild(rootNode, NULL, BAD_CAST "filename", BAD_CAST this->fitsOutFile);
     248        xmlNewChild(rootNode, NULL, BAD_CAST "filename", BAD_CAST fitsOutFile);
    281249    }
    282250
     
    289257static void print(Batch* this) {
    290258
    291     printf("\n");
    292     printf("* surveyType      : '%s'\n", this->surveyType);
    293     printf("* surveyID        : %d\n", this->surveyID);
    294     printf("* resultsPath     : '%s'\n", this->resultsPath);
    295     printf("* numOfInputFiles : %d\n", this->numOfInputFiles);
    296     printf("* fitsInPath      : '%s'\n", this->fitsInPath);
    297     printf("* fitsOutFile     : '%s'\n", this->fitsOutFile);
    298     printf("* fitsOutPath     : '%s'\n", this->fitsOutPath);
    299     printf("* configsDir      : '%s'\n", this->configsDir);
     259    this->logger->print(this->logger, MSG_INFO, "Batch", "\n");
     260    this->logger->print(this->logger, MSG_INFO, "Batch", "     Class fields:\n");
     261    this->logger->print(this->logger, MSG_INFO, "Batch", "surveyType      : %s\n", this->surveyType);
     262    this->logger->print(this->logger, MSG_INFO, "Batch", "surveyID        : %d\n", this->surveyID);
     263    this->logger->print(this->logger, MSG_INFO, "Batch", "resultsPath     : %s\n", this->resultsPath);
     264    this->logger->print(this->logger, MSG_INFO, "Batch", "numOfInputFiles : %d\n", this->numOfInputFiles);
     265    this->logger->print(this->logger, MSG_INFO, "Batch", "fitsInPath      : %s\n", this->fitsInPath);
     266    this->logger->print(this->logger, MSG_INFO, "Batch", "testMode        : %s\n", this->testMode ? "yes" : "no");
    300267}
    301268
     
    342309  Constructor. Takes a Batch object and initialises it.
    343310  */
    344 bool new_Batch(Batch *this) {
    345 
     311bool new_Batch(Logger* logger, Batch *this) {
     312
     313    this->logger = logger;
    346314    this->surveyID = -1;
    347315    this->resultsXmlDoc = NULL;
     
    349317    this->inputFiles = NULL;
    350318    this->fitsOut = NULL;
    351     this->config = NULL;
     319    this->fitsGenerator = NULL;
    352320    this->pmconfig = NULL;
    353321    this->exitCode = PS_EXIT_SUCCESS;
    354 
     322    this->testMode = false;
     323
     324    // set up function pointers
    355325    this->parseArguments = parseArguments;
    356     this->init = init;
    357326    this->print = print;
    358     this->destroy = destroy;
    359 
    360327    this->gotResultsPath = gotResultsPath;
    361328    this->gotFitsInPath = gotFitsInPath;
     
    363330    this->gotConfig = gotConfig;
    364331    this->gotSurveyType = gotSurveyType;
     332    this->destroy = destroy;
    365333
    366334    assert(this);
  • branches/eam_branches/ipp-20110213/ippToPsps/src/Batch.h

    r30812 r31083  
    1 /** @file ippToPsps.h
     1/** @file Batch.h
    22 *
    33 *  @brief Batch
     
    66 *
    77 *  @author IfA
    8  *  Copyright 2009 Institute for Astronomy, University of Hawaii
     8 *  Copyright 2011 Institute for Astronomy, University of Hawaii
    99 */
    1010
     
    1212#define IPPTOPSPS_BATCH_H
    1313
     14#include <libxml/parser.h>
     15#include <libxml/tree.h>
     16
    1417#include <psmodules.h>
    1518#include <dvo_util.h>
    16 #include "Config.h"
    17 #include <libxml/parser.h>
    18 #include <libxml/tree.h>
     19
     20#include "FitsGenerator.h"
     21#include "Fits.h"
     22#include "InitData.h"
     23#include "Logger.h"
    1924
    2025/**
     
    2530  - StackBatch
    2631
    27   All subclasses need to implement the run() method and may need to implenent print() and/or init()
     32  All subclasses need to implement the run() method and may need to implement print()
    2833  */
    2934typedef struct Batch {
    3035
    3136    // fields
    32     char surveyType[10];        // the survey type, eg 3PI, MD01, STS, SSS
    33     int8_t surveyID;            // survey ID
    34     char fitsInPath[1000];      // path to FITS input
    35     char resultsPath[1000];     // path to results file
    36     xmlDocPtr resultsXmlDoc;    // pointer to XML document for results
    37     uint16_t numOfInputFiles;   // number of input files
    38     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
    43     pmConfig* pmconfig;         // pmConfig
    44     dvoConfig* dvoConfig;       // dvo database
    45     IppToPspsConfig* config;    // config structure
    46     char todaysDate[20];        // today's date
    47     int exitCode;               // ps exit code
     37    char surveyType[10];           // the survey type, eg 3PI, MD01, STS, SSS
     38    int8_t surveyID;               // survey ID
     39    char fitsInPath[1000];         // path to FITS input
     40    char resultsPath[1000];        // path to results file
     41    xmlDocPtr resultsXmlDoc;       // pointer to XML document for results
     42    uint16_t numOfInputFiles;      // number of input files
     43    char** inputFiles;             // array of input file names
     44    Fits *fitsOut;                 // output FITS file
     45    pmConfig* pmconfig;            // pmConfig
     46    dvoConfig* dvoConfig;          // dvo database
     47    FitsGenerator* fitsGenerator;  // FitsGenerator object
     48    InitData* initData;            // InitData object
     49    char todaysDate[20];           // today's date
     50    int exitCode;                  // ps exit code
     51    bool testMode;                 // test mode boolean
     52    Logger* logger;                // Logger object
    4853
    4954    // methods
    5055    bool (*parseArguments)();
    51     bool (*init)();
    5256    int (*run)();
    5357    void (*print)();
     
    5761    bool (*gotConfig)();
    5862    bool (*gotSurveyType)();
     63
     64    // destructor
    5965    void (*destroy)();
    6066
     
    6268
    6369// public functions
    64 bool new_Batch(Batch *this);
     70bool new_Batch(Logger* logger, Batch *this);
    6571
    6672void ippToPsps_VersionPrint(void);
  • branches/eam_branches/ipp-20110213/ippToPsps/src/DetectionBatch.c

    r30193 r31083  
    11#include "DetectionBatch.h"
    22#include "DetectionBatchEnums.h"
     3
     4#include "Fits.h"
     5
    36
    47/**
     
    1821
    1922/**
     23  Writes results to XML file
     24  */
     25static bool writeResults(DetectionBatch* this, long minObjID, long maxObjID, long totalDetectionsOut) {
     26
     27    if (!this->base.resultsXmlDoc) return false;
     28
     29    xmlNodePtr rootNode = xmlDocGetRootElement(this->base.resultsXmlDoc);
     30    char tmp[100];
     31    sprintf(tmp, "%ld", minObjID);
     32    xmlNewChild(rootNode, NULL, BAD_CAST "minObjID", BAD_CAST tmp);
     33    sprintf(tmp, "%ld", maxObjID);
     34    xmlNewChild(rootNode, NULL, BAD_CAST "maxObjID", BAD_CAST tmp);
     35    sprintf(tmp, "%ld", totalDetectionsOut);
     36    xmlNewChild(rootNode, NULL, BAD_CAST "totalDetections", BAD_CAST tmp);
     37
     38    return true;
     39}
     40
     41/**
    2042  Does the work. Loops through the provided smf files, tallies the contents with the DVO database already connected to and generates a new FITS file of the fomat required by PSPS (i.e. a binary table per PSPS database table)
    2143  */
     
    2446    if (this->base.exitCode != PS_EXIT_SUCCESS) return this->base.exitCode;
    2547
    26     int status = 0;
    27     fitsfile *fitsIn;
    28 
    29     if (fits_open_file(&fitsIn, this->base.inputFiles[0], READONLY, &status)) {
    30 
    31         fits_report_error(stderr, status);
    32         return PS_EXIT_SYS_ERROR;
    33     }
    34 
    35     // get primary header and pull stuff out for later
    36     int nKeys;
    37     fits_get_hdrspace(fitsIn, &nKeys, NULL, &status);
    38 
    39     float zptObs, exposureTime;
    40     char filterType[20];
    41     double obsTime;
    42     double expStart;
    43     double expTime;
    44     status=0; fits_read_key(fitsIn, TFLOAT, "ZPT_OBS", &zptObs, NULL, &status);
    45     status=0; fits_read_key(fitsIn, TFLOAT, "EXPREQ", &exposureTime, NULL, &status);
    46     status=0; fits_read_key(fitsIn, TSTRING, "FILTERID", filterType, NULL, &status);
    47     status=0; fits_read_key(fitsIn, TDOUBLE, "MJD-OBS", &expStart, NULL, &status);
    48     status=0; fits_read_key(fitsIn, TDOUBLE, "EXPTIME", &expTime, NULL, &status);
    49     obsTime = expStart + (expTime/172800.0); // exp start plus half exp time (converted from secs to days)
    50 
    51     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], this->base.logger);
     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.fitsGenerator->createAndPopulateTable(this->base.fitsGenerator, fitsIn, this->base.fitsOut, 1, "FrameMeta", true);
    5262
    5363    // FrameMeta values
    54     fits_write_col(this->base.fitsOut, TLONG, FRAMEMETA_FRAMEID, 1, 1, 1, &this->expId, &status);
    55     fits_write_col(this->base.fitsOut, TSTRING, FRAMEMETA_FRAMENAME, 1, 1, 1, &(this->expName), &status);
    56     fits_write_col(this->base.fitsOut, TBYTE, FRAMEMETA_SURVEYID, 1, 1, 1, &this->base.surveyID, &status);
    57 
    5864    int8_t filterID = -1;
    59     if (!ippToPspsConfig_getFilterId(this->base.config, filterType, &filterID)) {
     65    if (!this->base.initData->getFilterId(this->base.initData, filterType, &filterID)) {
    6066   
    6167        this->base.exitCode = PS_EXIT_DATA_ERROR;
    6268        return this->base.exitCode;
    6369    }
    64 
    65     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
    6675
    6776    int16_t cameraID = 1; // TODO
    68     fits_write_col(this->base.fitsOut, TSHORT, FRAMEMETA_CAMERAID, 1, 1, 1, &cameraID, &status);
    69 
    7077    int16_t cameraConfigID = 1; // TODO
    71     fits_write_col(this->base.fitsOut, TSHORT, FRAMEMETA_CAMERACONFIGID, 1, 1, 1, &cameraConfigID, &status);
    72 
    7378    int16_t telescopeID = 1; // TODO
    74     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);
    7582
    7683    // stuff to keep from psf.hdr header
     
    8895    uint32_t s,d, invalidDvoRows, nChipDetectionsOut = 0;
    8996
    90     long longnull = -999;
    91     float floatnull = -999.0;
    92     int anynull = 0;
    93 
    9497    char ccdNumber[3], extensionName[15];
    95     // for storing FITS column data
     98    // for storing FITS column data - do this once, to avoid expension free/calloc for each chip
    9699    long* ippIDet = (long*)calloc(this->MAXDETECT, sizeof(long));
    97100    float* instMag = (float*)calloc(this->MAXDETECT, sizeof(float));
     
    110113    int8_t* filterIDs = (int8_t*)calloc(this->MAXDETECT, sizeof(int8_t));
    111114    int8_t* surveyIDs = (int8_t*)calloc(this->MAXDETECT, sizeof(int8_t));
    112 
    113115    char** assocDate = (char**)calloc(this->MAXDETECT, sizeof(char*));
    114116    for (uint32_t i=0; i<this->MAXDETECT;i++) assocDate[i] = (char*)malloc(20*sizeof(char));
     
    119121        filterIDs[s] = filterID;
    120122        surveyIDs[s] = this->base.surveyID;
    121         strcpy(assocDate[s], this->base.todaysDate);
     123
     124        // if running in test mode, don't use today's date
     125        if (this->base.testMode) strcpy(assocDate[s], "2010-01-01");
     126        else strcpy(assocDate[s], this->base.todaysDate);
    122127    }
    123128
     
    133138    int ippIDetNum, instMagNum, instMagErrNum, peakMagNum;
    134139    bool error = false;
    135 
    136     // loop round all 60 chips
    137     for (int x=0; x<8; x++) {
    138         for (int y=0; y<8; y++) {
     140    int startX, stopX, startY, stopY;
     141
     142    // in test mode, only run for chip 33
     143    if (this->base.testMode) {
     144
     145        startX = 3;
     146        stopX = 4;
     147        startY = 3;
     148        stopY = 4;
     149    }
     150    // in 'normal' mode, run for all chips
     151    else {
     152   
     153        startX = 0;
     154        stopX = 8;
     155        startY = 0;
     156        stopY = 8;
     157    }
     158
     159    this->base.logger->print(this->base.logger, MSG_INFO, "DetectionBatch", 
     160            "+-----------+---------+----------+----------------+--------------+--------------+\n");
     161    this->base.logger->print(this->base.logger, MSG_INFO, "DetectionBatch", 
     162            "| Extension | Rows in | Rows out |  Duplicate IDs | Invalid Flux | Bogus det ID |\n");
     163
     164    // loop round chips
     165    for (int x=startX; x<stopX; x++) {
     166        for (int y=startY; y<stopY; y++) {
    139167
    140168            // dodge the corners
     
    146174            sprintf(ccdNumber, "%d%d", x, y);
    147175
    148             // check we can move to detections table in smf
     176            // check we CAN move to detections table in smf
    149177            sprintf(extensionName, "XY%s.psf", ccdNumber);
    150             status=0;
    151             if (fits_movnam_hdu(fitsIn, BINARY_TBL, extensionName, 0, &status)) {
    152                 psError(PS_ERR_IO, false, "Can't move to extension: %s skipping this chip\n", extensionName);
    153                 continue;
    154             }
     178            if (!fitsIn->moveToBinaryTable(fitsIn, extensionName)) continue;
    155179
    156180            // move to header extension
    157181            sprintf(extensionName, "XY%s.hdr", ccdNumber);
    158             status=0;
    159             if (fits_movnam_hdu(fitsIn, IMAGE_HDU, extensionName, 0, &status)) {
    160                 psError(PS_ERR_IO, false, "Can't move to extension: %s skipping this chip\n", extensionName);
    161                 continue;
    162             }
     182            if (!fitsIn->moveToHeader(fitsIn, extensionName)) continue;
    163183
    164184            // stuff to save from psf.hdr
    165             status=0; fits_read_key(fitsIn, TFLOAT, "FWHM_MAJ", &fwhmMaj, NULL, &status);
    166             status=0; fits_read_key(fitsIn, TFLOAT, "FWHM_MIN", &fwhmMin, NULL, &status);
    167             status=0; fits_read_key(fitsIn, TFLOAT, "IQ_FW1", &momentMaj, NULL, &status);
    168             status=0; fits_read_key(fitsIn, TFLOAT, "IQ_FW2", &momentMin, NULL, &status);
    169             status=0; fits_read_key(fitsIn, TLONG, "IMAGEID", &imageId, NULL, &status);
    170             status=0; fits_read_key(fitsIn, TLONG, "SOURCEID", &sourceId, NULL, &status);
    171             status=0; fits_read_key(fitsIn, TLONG, "NASTRO", &numPhotoRef, NULL, &status);
     185            fitsIn->getHeaderKeyValue(fitsIn, TFLOAT, "FWHM_MAJ", &fwhmMaj);
     186            fitsIn->getHeaderKeyValue(fitsIn, TFLOAT, "FWHM_MIN", &fwhmMin);
     187            fitsIn->getHeaderKeyValue(fitsIn, TFLOAT, "IQ_FW1", &momentMaj);
     188            fitsIn->getHeaderKeyValue(fitsIn, TFLOAT, "IQ_FW2", &momentMin);
     189            fitsIn->getHeaderKeyValue(fitsIn, TLONG, "IMAGEID", &imageId);
     190            fitsIn->getHeaderKeyValue(fitsIn, TLONG, "SOURCEID", &sourceId);
     191            fitsIn->getHeaderKeyValue(fitsIn, TLONG, "NASTRO", &numPhotoRef);
    172192            totalNumPhotoRef += numPhotoRef; // total up for storing in FrameMeta
     193
    173194            // access DVO database
    174195            skylist = dvoSkyListByExternID(this->base.dvoConfig, sourceId, imageId, &image);
    175196            if (skylist == NULL) {
    176                 psError(PS_ERR_IO, false,
     197                this->base.logger->print(this->base.logger, MSG_ERROR, "DetectionBatch", 
    177198                        "DVO: can't find SkyList for sourceId='%d' imageId='%d' (CCD = XY%s): skipping this chip\n",
    178199                        sourceId, imageId, ccdNumber);
     
    189210            if (numDvoDetections > this->MAXDETECT ) {
    190211
    191                 psError(PS_ERR_IO, false,
    192                         " Number of detections (%d) exceeds max limit (%ld)\n",
     212                this->base.logger->print(this->base.logger, MSG_ERROR, "DetectionBatch", "Number of detections (%d) exceeds max limit (%ld)\n",
    193213                        numDvoDetections, this->MAXDETECT);
    194214                error = true;
     
    197217
    198218            // create ImageMeta
    199             ippToPspsConfig_writeTable(this->base.config, fitsIn, this->base.fitsOut, 1, "ImageMeta", true);
     219            this->base.fitsGenerator->createAndPopulateTable(this->base.fitsGenerator, fitsIn, this->base.fitsOut, 1, "ImageMeta", true);
    200220            psfFwhm = (fwhmMaj+fwhmMin)/2;
    201221            momentFwhm = (momentMaj+momentMin)/2;
    202222            imageFlags = (uint64_t)image->flags;
    203             fits_write_col(this->base.fitsOut, TLONGLONG, IMAGEMETA_IMAGEID, 1, 1, 1, &pspsImageId, &status);
    204             fits_write_col(this->base.fitsOut, TLONG, IMAGEMETA_FRAMEID, 1, 1, 1, &this->expId, &status);
    205             fits_write_col(this->base.fitsOut, TSHORT, IMAGEMETA_CCDID, 1, 1, 1, &image->ccdnum, &status);
    206             fits_write_col(this->base.fitsOut, TLONG, IMAGEMETA_PHOTOCALID, 1, 1, 1, &image->photcode, &status);
    207             fits_write_col(this->base.fitsOut, TBYTE, IMAGEMETA_FILTERID, 1, 1, 1, &filterID, &status);
    208             fits_write_col(this->base.fitsOut, TFLOAT, IMAGEMETA_PHOTOSCAT, 1, 1, 1, &zptObs, &status);
    209             fits_write_col(this->base.fitsOut, TFLOAT, IMAGEMETA_PSFFWHM, 1, 1, 1, &psfFwhm, &status);
    210             fits_write_col(this->base.fitsOut, TFLOAT, IMAGEMETA_MOMENTFWHM, 1, 1, 1, &momentFwhm, &status);
    211             fits_write_col(this->base.fitsOut, TFLOAT, IMAGEMETA_PHOTOZERO, 1, 1, 1, &zptObs, &status);
    212             fits_write_col(this->base.fitsOut, TLONGLONG, IMAGEMETA_QAFLAGS, 1, 1, 1, &imageFlags, &status);
     223            this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, IMAGEMETA_IMAGEID, 1, 1, 1, &pspsImageId);
     224            this->base.fitsOut->writeColumn(this->base.fitsOut, TLONG, IMAGEMETA_FRAMEID, 1, 1, 1, &this->expId);
     225            this->base.fitsOut->writeColumn(this->base.fitsOut, TSHORT, IMAGEMETA_CCDID, 1, 1, 1, &image->ccdnum);
     226            this->base.fitsOut->writeColumn(this->base.fitsOut, TLONG, IMAGEMETA_PHOTOCALID, 1, 1, 1, &image->photcode);
     227            this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, IMAGEMETA_FILTERID, 1, 1, 1, &filterID);
     228            this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, IMAGEMETA_PHOTOSCAT, 1, 1, 1, &zptObs);
     229            this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, IMAGEMETA_PSFFWHM, 1, 1, 1, &psfFwhm);
     230            this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, IMAGEMETA_MOMENTFWHM, 1, 1, 1, &momentFwhm);
     231            this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, IMAGEMETA_PHOTOZERO, 1, 1, 1, &zptObs);
     232            this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, IMAGEMETA_QAFLAGS, 1, 1, 1, &imageFlags);
    213233
    214234            // now move BACK to detections table in smf
    215235            sprintf(extensionName, "XY%s.psf", ccdNumber);
    216             status=0;
    217             if (fits_movnam_hdu(fitsIn, BINARY_TBL, extensionName, 0, &status)) {
    218                 psError(PS_ERR_IO, false, "Can't move to extension: %s skipping\n", extensionName);
    219                 continue;
    220             }
    221 
    222             // keep a running count of 'images' we find in order to write total to FrameMeta at the end
     236            long nChipDetectionsIn = 0;
     237            if (!fitsIn->moveToBinaryTableAndCountRows(fitsIn, extensionName, &nChipDetectionsIn)) continue;
     238
     239            // keep a running count of 'images' we find in order to write total into FrameMeta at the end
    223240            nOta++;
    224 
    225             long nChipDetectionsIn = 0;
    226             if (fits_get_num_rows(fitsIn, &nChipDetectionsIn, &status)) {
    227                 fits_report_error(stderr, status);
    228             }
    229241
    230242            // loop round detections to populate some extra stuff
    231243            s = d = nChipDetectionsOut = invalidDvoRows = 0;
    232244
    233             // determine column numbers for certain IPP detection columns
     245            // determine column numbers for certain IPP detection columns - do this only once to save time
    234246            if (firstTimeIn) {
    235247
    236                 status=0;fits_get_colnum(fitsIn, CASESEN, "IPP_IDET", &ippIDetNum, &status);
    237                 if (status) psError(PS_ERR_IO, false, "Unable to read col num for IPP_IDET");
    238                 status=0;fits_get_colnum(fitsIn, CASESEN, "PSF_INST_MAG", &instMagNum, &status);
    239                 if (status) psError(PS_ERR_IO, false, "Unable to read col num for PSF_INST_MAG");
    240                 status=0;fits_get_colnum(fitsIn, CASESEN, "PSF_INST_MAG_SIG", &instMagErrNum, &status);
    241                 if (status) psError(PS_ERR_IO, false, "Unable to read col num for PSF_INST_MAG_SIG");
    242                 status=0;fits_get_colnum(fitsIn, CASESEN, "PEAK_FLUX_AS_MAG", &peakMagNum, &status);
    243                 if (status) psError(PS_ERR_IO, false, "Unable to read col num for PEAK_FLUX_AS_MAG");
     248                fitsIn->getColumnNumber(fitsIn, "IPP_IDET", &ippIDetNum);
     249                fitsIn->getColumnNumber(fitsIn, "PSF_INST_MAG", &instMagNum);
     250                fitsIn->getColumnNumber(fitsIn, "PSF_INST_MAG_SIG", &instMagErrNum);
     251                fitsIn->getColumnNumber(fitsIn, "PEAK_FLUX_AS_MAG", &peakMagNum);
    244252
    245253                firstTimeIn=false;
    246254            }
    247255
    248             anynull = 0;
    249             fits_read_col(fitsIn, TLONG, ippIDetNum, 1, 1, nChipDetectionsIn, &longnull, ippIDet, &anynull, &status);
    250             fits_read_col(fitsIn, TFLOAT, instMagNum, 1, 1, nChipDetectionsIn, &floatnull, instMag, &anynull, &status);
    251             fits_read_col(fitsIn, TFLOAT, instMagErrNum, 1, 1, nChipDetectionsIn, &floatnull, instMagErr, &anynull, &status);
    252             fits_read_col(fitsIn, TFLOAT, peakMagNum, 1, 1, nChipDetectionsIn, &floatnull, peakMag, &anynull, &status);
     256            //anynull = 0;
     257            fitsIn->readColumn(fitsIn, TLONG, ippIDetNum, 1, 1, nChipDetectionsIn, ippIDet);
     258            fitsIn->readColumn(fitsIn, TFLOAT, instMagNum, 1, 1, nChipDetectionsIn, instMag);
     259            fitsIn->readColumn(fitsIn, TFLOAT, instMagErrNum, 1, 1, nChipDetectionsIn, instMagErr);
     260            fitsIn->readColumn(fitsIn, TFLOAT, peakMagNum, 1, 1, nChipDetectionsIn, peakMag);
    253261
    254262            // DVO detections are ordered by IPP_IDET, which increments from 0 in SMF table
     
    260268            // loop through all detections in smf file extension for this chip.
    261269            // there are three ways for a detection to be ommitted from the final FITS output:
     270            //
    262271            // 1. it has a duplicate obj ID to a previous detection
    263272            // 2. it has an invalid detection ID (< 0 or > max DVO det ID)
     
    312321
    313322                    // check for invalid flux values, and skip them
    314                     if ( !peakFluxOk || !instFluxOk) {
     323                    if (!peakFluxOk || !instFluxOk) {
    315324                        removeList[numOfDuplicates+numInvalidFlux+numOfInvalidIppIDet] = s+1;
    316325                        numInvalidFlux++;
     
    327336
    328337            // write number of rows (detections) to ImageMeta
    329             fits_write_col(this->base.fitsOut, TLONG, IMAGEMETA_NDETECT, 1, 1, 1, &nChipDetectionsOut, &status);
     338            this->base.fitsOut->writeColumn(this->base.fitsOut, TLONG, IMAGEMETA_NDETECT, 1, 1, 1, &nChipDetectionsOut);
    330339
    331340            int totalRemove = numOfDuplicates+numInvalidFlux+numOfInvalidIppIDet;
     
    335344
    336345                // detections
    337                 ippToPspsConfig_writeTable(this->base.config, fitsIn, this->base.fitsOut, nChipDetectionsIn, "Detection", false);
    338                 fits_write_col(this->base.fitsOut, TLONGLONG, DETECTION_OBJID, 1, 1, nChipDetectionsIn, objID, &status);
    339                 fits_write_col(this->base.fitsOut, TLONGLONG, DETECTION_DETECTID, 1, 1, nChipDetectionsIn, detectID, &status);
    340                 fits_write_col(this->base.fitsOut, TLONGLONG, DETECTION_IPPOBJID, 1, 1, nChipDetectionsIn, ippObjID, &status);
    341                 fits_write_col(this->base.fitsOut, TLONGLONG, DETECTION_IPPDETECTID, 1, 1, nChipDetectionsIn, ippDetectID, &status);
    342                 fits_write_col(this->base.fitsOut, TBYTE, DETECTION_FILTERID, 1, 1, nChipDetectionsIn, filterIDs, &status);
    343                 fits_write_col(this->base.fitsOut, TBYTE, DETECTION_SURVEYID, 1, 1, nChipDetectionsIn, surveyIDs, &status);
    344                 fits_write_col(this->base.fitsOut, TLONGLONG, DETECTION_IMAGEID, 1, 1, nChipDetectionsIn, imageID, &status);
    345                 fits_write_col(this->base.fitsOut, TDOUBLE, DETECTION_OBSTIME, 1, 1, nChipDetectionsIn, obsTimes, &status);
    346                 fits_write_col(this->base.fitsOut, TFLOAT, DETECTION_INSTFLUX, 1, 1, nChipDetectionsIn, instFlux, &status);
    347                 fits_write_col(this->base.fitsOut, TFLOAT, DETECTION_INSTFLUXERR, 1, 1, nChipDetectionsIn, instFluxErr, &status);
    348                 fits_write_col(this->base.fitsOut, TFLOAT, DETECTION_PEAKADU, 1, 1, nChipDetectionsIn, peakFlux, &status);
    349                 fits_write_col(this->base.fitsOut, TSTRING, DETECTION_ASSOCDATE, 1, 1, nChipDetectionsIn, assocDate, &status);
    350                 fits_write_col(this->base.fitsOut, TLONGLONG, DETECTION_INFOFLAG, 1, 1, nChipDetectionsIn, flags, &status);
    351                 if (numOfDuplicates||numInvalidFlux||numOfInvalidIppIDet)
    352                     fits_delete_rowlist(this->base.fitsOut, removeList, totalRemove, &status);
     346                this->base.fitsGenerator->createAndPopulateTable(this->base.fitsGenerator, fitsIn, this->base.fitsOut, nChipDetectionsIn, "Detection", false);
     347                this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, DETECTION_OBJID, 1, 1, nChipDetectionsIn, objID);
     348                this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, DETECTION_DETECTID, 1, 1, nChipDetectionsIn, detectID);
     349                this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, DETECTION_IPPOBJID, 1, 1, nChipDetectionsIn, ippObjID);
     350                this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, DETECTION_IPPDETECTID, 1, 1, nChipDetectionsIn, ippDetectID);
     351                this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, DETECTION_FILTERID, 1, 1, nChipDetectionsIn, filterIDs);
     352                this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, DETECTION_SURVEYID, 1, 1, nChipDetectionsIn, surveyIDs);
     353                this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, DETECTION_IMAGEID, 1, 1, nChipDetectionsIn, imageID);
     354                this->base.fitsOut->writeColumn(this->base.fitsOut, TDOUBLE, DETECTION_OBSTIME, 1, 1, nChipDetectionsIn, obsTimes);
     355                this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, DETECTION_INSTFLUX, 1, 1, nChipDetectionsIn, instFlux);
     356                this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, DETECTION_INSTFLUXERR, 1, 1, nChipDetectionsIn, instFluxErr);
     357                this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, DETECTION_PEAKADU, 1, 1, nChipDetectionsIn, peakFlux);
     358                this->base.fitsOut->writeColumn(this->base.fitsOut, TSTRING, DETECTION_ASSOCDATE, 1, 1, nChipDetectionsIn, assocDate);
     359                this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, DETECTION_INFOFLAG, 1, 1, nChipDetectionsIn, flags);
     360                if (numOfDuplicates||numInvalidFlux||numOfInvalidIppIDet) this->base.fitsOut->deleteRows(this->base.fitsOut, removeList, totalRemove);
    353361
    354362                // skinny object
    355                 ippToPspsConfig_writeTable(this->base.config, fitsIn, this->base.fitsOut, nChipDetectionsIn, "SkinnyObject", false);
    356                 fits_write_col(this->base.fitsOut, TLONGLONG, SKINNYOBJECT_OBJID, 1, 1, nChipDetectionsIn, objID, &status);
    357                 fits_write_col(this->base.fitsOut, TLONGLONG, SKINNYOBJECT_IPPOBJID, 1, 1, nChipDetectionsIn, ippObjID, &status);
    358                 fits_write_col(this->base.fitsOut, TBYTE, SKINNYOBJECT_SURVEYID, 1, 1, nChipDetectionsIn, surveyIDs, &status);
    359                 if (numOfDuplicates||numInvalidFlux||numOfInvalidIppIDet)
    360                     fits_delete_rowlist(this->base.fitsOut, removeList, totalRemove, &status);
     363                this->base.fitsGenerator->createAndPopulateTable(this->base.fitsGenerator, fitsIn, this->base.fitsOut, nChipDetectionsIn, "SkinnyObject", false);
     364                this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, SKINNYOBJECT_OBJID, 1, 1, nChipDetectionsIn, objID);
     365                this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, SKINNYOBJECT_IPPOBJID, 1, 1, nChipDetectionsIn, ippObjID);
     366                this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, SKINNYOBJECT_SURVEYID, 1, 1, nChipDetectionsIn, surveyIDs);
     367                if (numOfDuplicates||numInvalidFlux||numOfInvalidIppIDet) this->base.fitsOut->deleteRows(this->base.fitsOut, removeList, totalRemove);
    361368
    362369                // object calibration color
    363                 ippToPspsConfig_writeTable(this->base.config, fitsIn, this->base.fitsOut, nChipDetectionsIn, "ObjectCalColor", false);
    364                 fits_write_col(this->base.fitsOut, TLONGLONG, OBJECTCALCOLOR_OBJID, 1, 1, nChipDetectionsIn, objID, &status);
    365                 fits_write_col(this->base.fitsOut, TLONGLONG, OBJECTCALCOLOR_IPPOBJID, 1, 1, nChipDetectionsIn, ippObjID, &status);
    366                 fits_write_col(this->base.fitsOut, TBYTE, OBJECTCALCOLOR_FILTERID, 1, 1, nChipDetectionsIn, filterIDs, &status);
    367                 if (numOfDuplicates||numInvalidFlux||numOfInvalidIppIDet)
    368                     fits_delete_rowlist(this->base.fitsOut, removeList, totalRemove, &status);
     370                this->base.fitsGenerator->createAndPopulateTable(this->base.fitsGenerator, fitsIn, this->base.fitsOut, nChipDetectionsIn, "ObjectCalColor", false);
     371                this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, OBJECTCALCOLOR_OBJID, 1, 1, nChipDetectionsIn, objID);
     372                this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, OBJECTCALCOLOR_IPPOBJID, 1, 1, nChipDetectionsIn, ippObjID);
     373                this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, OBJECTCALCOLOR_FILTERID, 1, 1, nChipDetectionsIn, filterIDs);
     374                if (numOfDuplicates||numInvalidFlux||numOfInvalidIppIDet) this->base.fitsOut->deleteRows(this->base.fitsOut, removeList, totalRemove);
    369375            }
    370376
    371             psLogMsg("ippToPsps", PS_LOG_INFO,
    372                     "+-----------+---------+----------+----------------+--------------+--------------+\n"
    373                     "| Extension | Rows in | Rows out |  Duplicate IDs | Invalid Flux | Bogus det ID |\n"
     377            this->base.logger->print(this->base.logger, MSG_INFO, "DetectionBatch",
    374378                    "|  %s |  %5ld  |   %5d  |     %5d      |    %5d     |    %5d     |\n",
    375379                    extensionName, nChipDetectionsIn, nChipDetectionsOut, numOfDuplicates, numInvalidFlux, numOfInvalidIppIDet);
     
    384388    }
    385389
    386     psLogMsg("ippToPsps", PS_LOG_INFO, "Total detections for this exposure = %ld\n", totalDetectionsOut);
     390    this->base.logger->print(this->base.logger, MSG_INFO, "DetectionBatch", 
     391            "+-----------+---------+----------+----------------+--------------+--------------+\n");
     392
     393    this->base.logger->print(this->base.logger, MSG_INFO, "DetectionBatch", "Total detections for this exposure = %ld\n", totalDetectionsOut);
    387394
    388395    // free-up memory
     
    408415
    409416    // write number of images we have found into FrameMeta table
    410     status=0;
    411     if (fits_movnam_hdu(this->base.fitsOut, BINARY_TBL, "FrameMeta", 0, &status))
    412         psError(PS_ERR_IO, false, "Can't move back to FrameMeta extension to write number of OTAs\n");
    413     else {
    414         fits_write_col(this->base.fitsOut, TSHORT, FRAMEMETA_NOTA, 1, 1, 1, &nOta, &status);
    415         fits_write_col(this->base.fitsOut, TSHORT, FRAMEMETA_NUMPHOTOREF, 1, 1, 1, &totalNumPhotoRef, &status);
    416     }
    417     status=0;
    418     if (fits_close_file(fitsIn, &status)) fits_report_error(stderr, status);
    419     // write results
    420     if (this->base.resultsXmlDoc) {
    421 
    422         xmlNodePtr rootNode = xmlDocGetRootElement(this->base.resultsXmlDoc);
    423         char tmp[100];
    424         sprintf(tmp, "%ld", minObjID);
    425         xmlNewChild(rootNode, NULL, BAD_CAST "minObjID", BAD_CAST tmp);
    426         sprintf(tmp, "%ld", maxObjID);
    427         xmlNewChild(rootNode, NULL, BAD_CAST "maxObjID", BAD_CAST tmp);
    428         sprintf(tmp, "%ld", totalDetectionsOut);
    429         xmlNewChild(rootNode, NULL, BAD_CAST "totalDetections", BAD_CAST tmp);
    430     }
    431 
    432     psLogMsg("ippToPsps", PS_LOG_INFO, "Data written for a total of %d chips/OTAs", nOta);
     417    if (this->base.fitsOut->moveToBinaryTable(this->base.fitsOut, "FrameMeta")) {
     418
     419        this->base.fitsOut->writeColumn(this->base.fitsOut, TSHORT, FRAMEMETA_NOTA, 1, 1, 1, &nOta);
     420        this->base.fitsOut->writeColumn(this->base.fitsOut, TSHORT, FRAMEMETA_NUMPHOTOREF, 1, 1, 1, &totalNumPhotoRef);
     421    }
     422
     423    fitsIn->destroy(fitsIn);
     424
     425    writeResults(this, minObjID, maxObjID, totalDetectionsOut);
     426
     427    this->base.logger->print(this->base.logger, MSG_INFO, "DetectionBatch", "Data written for a total of %d chips/OTAs\n", nOta);
    433428
    434429    if (error || nOta < 1) this->base.exitCode = PS_EXIT_DATA_ERROR;
     
    438433}
    439434
    440 
    441435/**
    442436  Print-out this class. Calls base-calls print method first.
     
    446440    this->base.print(&this->base);
    447441
    448     printf("* exp ID          : %d\n", this->expId);
    449     printf("* exp name        : '%s'\n",  this->expName ? this->expName : "undef");
    450     printf("\n");
     442    this->base.logger->print(this->base.logger, MSG_INFO, "DetectionBatch", "exp ID          : %d\n", this->expId);
     443    this->base.logger->print(this->base.logger, MSG_INFO, "DetectionBatch", "exp name        : %s\n",  this->expName ? this->expName : "undef");
     444    this->base.logger->print(this->base.logger, MSG_INFO, "DetectionBatch", "\n");
    451445}
    452446
     
    480474    }
    481475
    482     this->base.parseArguments(&this->base, argc, argv);
     476    char fitsOutFile[40];
     477    sprintf(fitsOutFile, "%08d.FITS", this->expId);
     478    this->base.parseArguments(&this->base, argc, argv, "/detection", fitsOutFile);
    483479
    484480    if (
     
    491487            !haveExpName) {
    492488
    493         printf("\n* ERROR with supplied arguments:");
     489        this->base.logger->print(this->base.logger, MSG_ERROR, "DetectionBatch", "Problem with supplied arguments\n");
    494490        this->print(this);
    495491        this->base.exitCode = PS_EXIT_CONFIG_ERROR;
     
    503499  Constructor. Returns a new DetectionBatch object.
    504500  */
    505 DetectionBatch* new_DetectionBatch(int *argc, char **argv) {
    506 
     501DetectionBatch* new_DetectionBatch(Logger* logger, int *argc, char **argv) {
     502
     503    logger->print(logger, MSG_DEBUG, "DetectionBatch", "Constructor\n");
    507504    DetectionBatch *this = (DetectionBatch*)calloc(1, sizeof(DetectionBatch));
    508505
    509506    // call base-class constructor
    510     if (!new_Batch(&this->base)) {
    511 
    512         psError(PS_ERR_IO, false, "Unable to create Batch base-class object");
    513         return this;
    514     }
     507    new_Batch(logger, &this->base);
    515508
    516509    this->MAXDETECT = 200000;
    517510
     511    // method pointers
    518512    this->print = print;
    519513    this->destroy = destroy;
     
    522516    this->expName = (char*)calloc(100, sizeof(char));
    523517
    524     if (!parseArguments(this, *argc, argv)) { return this; }
    525 
    526     strcat(this->base.configsDir, "/detection");
    527     sprintf(this->base.fitsOutFile, "%08d.FITS", this->expId);
    528 
    529     this->base.init(&this->base);
     518    parseArguments(this, *argc, argv);
     519
     520    this->print(this);
    530521
    531522    return this;
     
    537528int main(int argc, char **argv) {
    538529
    539     psTimerStart("detectionbatch");
    540 
    541     ippToPsps_VersionPrint();
    542 
    543     int exitCode;
    544 
    545     DetectionBatch* detectionBatch = new_DetectionBatch(&argc, argv);
     530//    ippToPsps_VersionPrint();
     531
     532    Logger* logger = new_Logger(NULL, false);
     533//    Logger* logger = new_Logger("./detBatchLog.txt", false);
     534    logger->print(logger, MSG_INFO, "main", "Creating new detection batch\n");
     535
     536    DetectionBatch* detectionBatch = new_DetectionBatch(logger, &argc, argv);
    546537    detectionBatch->base.run(detectionBatch);
    547     exitCode = detectionBatch->base.exitCode;
     538    int exitCode = detectionBatch->base.exitCode;
    548539
    549540    detectionBatch->destroy(detectionBatch);
    550541
    551     double secs = psTimerMark("ippToPsps");
    552 
    553     psLogMsg("detectionbatch", 3, "detectionbatch completed %ssuccessfully, with exit code %d, in %.1f %s\n",
    554             (exitCode == PS_EXIT_SUCCESS) ? "" : "un",
    555             exitCode,
    556             (secs<60.0) ? secs : (secs/60.0),
    557             (secs<60.0) ? "sec(s)" : "min(s)");
    558 
    559542    // tidy up
    560     psTimerStop();
    561543    psLibFinalize();
     544    logger->destroy(logger);
    562545
    563546    return exitCode;
  • branches/eam_branches/ipp-20110213/ippToPsps/src/DetectionBatch.h

    r30190 r31083  
    3131} DetectionBatch;
    3232
    33 DetectionBatch *new_DetectionBatch(int *argc, char **argv);
     33DetectionBatch *new_DetectionBatch(Logger* logger, int *argc, char **argv);
    3434
    3535# endif // IPPTOPSPS_DETECTIONBATCH_H
  • branches/eam_branches/ipp-20110213/ippToPsps/src/InitBatch.c

    r30147 r31083  
    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.fitsGenerator->populateFromFile(this->base.fitsGenerator, 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 (
     
    4444            !this->base.gotConfig() ) {
    4545
    46         printf("\n* ERROR with supplied arguments:");
    47         this->print(this);
     46        this->base.logger->print(this->base.logger, MSG_ERROR, "InitBatch", "Problem with supplied arguments\n");
    4847        this->base.exitCode = PS_EXIT_CONFIG_ERROR;
    4948        return false;
    5049    }
    51 
    5250
    5351    return true;
     
    5755  Constructor
    5856  */
    59 InitBatch* new_InitBatch(int *argc, char **argv) {
     57InitBatch* new_InitBatch(Logger* logger, int *argc, char **argv) {
    6058
     59    logger->print(logger, MSG_DEBUG, "InitBatch", "Constructor\n");
    6160    InitBatch *this = (InitBatch*)calloc(1, sizeof(InitBatch));
    6261
    6362    // call base-class constructor
    64     if (!new_Batch(&this->base)) {
     63    new_Batch(logger, &this->base);
    6564
    66         psError(PS_ERR_IO, false, "Unable to create Batch base-class object");
    67         return this;
    68     }
    69 
     65    // method pointers
    7066    this->print = print;
    7167    this->destroy = destroy;
    7268    this->base.run = run;
    7369
    74     if (!parseArguments(this, *argc, argv)) { return this; }
     70    parseArguments(this, *argc, argv);
    7571
    76     strcat(this->base.configsDir, "/init");
    77     sprintf(this->base.fitsOutFile, "00000000.FITS");
    78 
    79     this->base.init(&this->base);
     72    this->print(this);
    8073
    8174    return this;
     
    8780int main(int argc, char **argv) {
    8881
    89     psTimerStart("initbatch");
     82//    ippToPsps_VersionPrint();
    9083
    91     ippToPsps_VersionPrint();
     84    Logger* logger = new_Logger(NULL, false);
     85    logger->print(logger, MSG_INFO, "main", "Creating new initialization batch\n");
    9286
    93     int exitCode;
    94 
    95     InitBatch* initBatch = new_InitBatch(&argc, argv);
     87    InitBatch* initBatch = new_InitBatch(logger, &argc, argv);
    9688    initBatch->base.run(initBatch);
    97     exitCode = initBatch->base.exitCode;
     89    int exitCode = initBatch->base.exitCode;
    9890
    9991    initBatch->destroy(initBatch);
    10092
    101     double secs = psTimerMark("initbatch");
    102 
    103     psLogMsg("initbatch", 3, "initbatch completed %ssuccessfully, with exit code %d, in %.1f %s\n",
    104             (exitCode == PS_EXIT_SUCCESS) ? "" : "un",
    105             exitCode,
    106             (secs<60.0) ? secs : (secs/60.0),
    107             (secs<60.0) ? "sec(s)" : "min(s)");
    108 
    10993    // tidy up
    110     psTimerStop();
    11194    psLibFinalize();
     95    logger->destroy(logger);
    11296
    11397    return exitCode;
  • branches/eam_branches/ipp-20110213/ippToPsps/src/InitBatch.h

    r30147 r31083  
    2424    // methods
    2525    void (*print)();
     26
     27    // destructor
    2628    void (*destroy)();
    2729
    2830} InitBatch;
    2931
    30 InitBatch *new_InitBatch(int *argc, char **argv);
     32// constructor
     33InitBatch *new_InitBatch(Logger *logger, int *argc, char **argv);
    3134
    3235# endif // IPPTOPSPS_INITBATCH_H
  • branches/eam_branches/ipp-20110213/ippToPsps/src/Makefile.am

    r30147 r31083  
    3131        Batch.c \
    3232        Version.c \
    33         Config.c
     33        Fits.c \
     34        InitData.c \
     35        Logger.c \
     36        FitsGenerator.c
    3437
    3538# detectionbatch
     
    4043        Batch.c \
    4144        Version.c \
    42         Config.c
     45        Fits.c \
     46        InitData.c \
     47        Logger.c \
     48        FitsGenerator.c
    4349
    4450# stackbatch
     
    4955        Batch.c \
    5056        Version.c \
    51         Config.c
     57        Fits.c \
     58        InitData.c \
     59        Logger.c \
     60        FitsGenerator.c
    5261
    5362clean-local:
  • branches/eam_branches/ipp-20110213/ippToPsps/src/StackBatch.c

    r30147 r31083  
    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    this->base.logger->print(this->base.logger, MSG_INFO, "StackBatch",
     61            "Looping through %ld psf detection rows from '%s'\n", nDet, extensionName);
     62    float mag;
     63    long unmatched = 0, totalDetections = 0, numOfDuplicates = 0, numInvalidFlux = 0, numDetectionsOut = 0;
     64
     65    this->base.logger->print(this->base.logger, MSG_INFO, "StackBatch", 
     66            "+---------------+---------+----------+------------------+---------------+--------------+\n");
     67    this->base.logger->print(this->base.logger, MSG_INFO, "StackBatch", 
     68            "|   Extension   | Rows in | Rows out | Missing from DVO | Duplicate IDs | Invalid Flux |\n");
     69
     70    for (long s=0; s<nDet; s++) {
     71
     72        // TODO implement this match in DVO
     73        if (1) {
     74
     75            //infoFlags[s] = ((uint64_t)flags1[s] << 32) | (uint64_t)flags2[s]; TODO implement after schema change to make infoFlag 64-bit
     76            infoFlags[s] = (uint64_t)flags1[s];
     77
     78            peakFluxOk = getFlux(exposureTime, peakMag[s], &peakFlux[s], 0.0, NULL);
     79
     80            mag = instMag[s];
     81            if (!peakFluxOk || !isfinite(mag) || mag < -998.0) {
     82
     83                removeList[numOfDuplicates+numInvalidFlux] = s+1;
     84                numInvalidFlux++;
     85            }
     86
     87            totalDetections++;
    8188        }
    82 
    83 
    84         long nDet = 0;
    85         if (fits_get_num_rows(fitsIn, &nDet, &status)) {
    86             fits_report_error(stderr, status);
     89        else {
     90
     91            unmatched++;
     92            continue;
    8793        }
    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     }
     94    }
     95
     96    numDetectionsOut = totalDetections - numInvalidFlux;
     97    if (numDetectionsOut > 0) {
     98
     99        this->base.fitsGenerator->createAndPopulateTable(this->base.fitsGenerator, fitsIn, this->base.fitsOut, nDet, "StackDetection", false);
     100        this->base.fitsOut->writeColumn(this->base.fitsOut, TLONG, STACKDETECTION_SKYCELLID, 1, 1, nDet, skycellIDs);
     101        this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, STACKDETECTION_FILTERID, 1, 1, nDet, filterIDs);
     102        this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKDETECTION_PEAKFLUX, 1, 1, nDet, peakFlux);
     103        this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, STACKDETECTION_SURVEYID, 1, 1, nDet, surveyIDs);
     104        this->base.fitsOut->writeColumn(this->base.fitsOut, TSTRING, STACKDETECTION_ASSOCDATE, 1, 1, nDet, assocDate);
     105        this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, STACKDETECTION_INFOFLAG, 1, 1, nDet, flags1);
     106
     107        if (numInvalidFlux) this->base.fitsOut->deleteRows(this->base.fitsOut, removeList, numInvalidFlux);
     108
     109    }
     110
     111    this->base.logger->print(this->base.logger, MSG_INFO, "StackBatch",
     112            "|  %12s |  %5ld  |   %5ld  |      %5ld       |    %5ld      |    %5ld     |\n",
     113            extensionName, nDet, numDetectionsOut, unmatched, numOfDuplicates, numInvalidFlux);
     114    this->base.logger->print(this->base.logger, MSG_INFO, "StackBatch",
     115            "+---------------+---------+----------+------------------+---------------+--------------+\n");
    192116
    193117
     
    195119    free(removeList);
    196120    free(instMag);
     121    free(flags1);
     122    free(flags2);
     123    free(infoFlags);
     124    for (uint32_t i=0; i<this->MAXDETECT;i++) free(assocDate[i]);
     125    free(assocDate);
     126
     127    return true;
     128}
     129/**
     130  Structure to encapsulate block of flux values for StackApFlx table
     131  */
     132typedef struct {
     133
     134    float* flx;
     135    float* flxErr;
     136    float* flxStd;
     137    float* flxFill;
     138
     139} StackApFlxFluxes;
     140
     141/**
     142  Creates the StackApFlx table for extended source attributes
     143  */
     144static bool createStackApFlxTable(
     145        StackBatch* this,
     146        Fits* fitsIn,
     147        int8_t* filterIDs,
     148        int8_t* surveyIDs
     149        ) {
     150
     151    long nDet = 0;
     152    char extensionName[15];
     153    sprintf(extensionName, "SkyChip.xrad");
     154    if (!fitsIn->moveToBinaryTableAndCountRows(fitsIn, extensionName, &nDet)) return false;
     155
     156
     157    int aperFluxColNum, aperFluxErrColNum, aperFluxStDevColNum, aperFluxFillColNum;
     158    int type; // all the same type
     159    long repeat;
     160
     161    fitsIn->getColumnMeta(fitsIn, "APER_FLUX", &aperFluxColNum, &type, &repeat);
     162    fitsIn->getColumnMeta(fitsIn, "APER_FLUX_ERR", &aperFluxErrColNum, &type, &repeat);
     163    fitsIn->getColumnMeta(fitsIn, "APER_FLUX_STDEV", &aperFluxStDevColNum, &type, &repeat);
     164    fitsIn->getColumnMeta(fitsIn, "APER_FILL", &aperFluxFillColNum, &type, &repeat);
     165    float* vector = calloc(repeat, sizeof(float));
     166
     167    // we store 10 different flux values
     168    StackApFlxFluxes* stackApFlxFluxes = (StackApFlxFluxes*)calloc(11, sizeof(StackApFlxFluxes));
     169    for (long i=0; i<11; i++) {
     170
     171        stackApFlxFluxes[i].flx = (float*)calloc(nDet, sizeof(float));
     172        stackApFlxFluxes[i].flxErr = (float*)calloc(nDet, sizeof(float));
     173        stackApFlxFluxes[i].flxStd = (float*)calloc(nDet, sizeof(float));
     174        stackApFlxFluxes[i].flxFill = (float*)calloc(nDet, sizeof(float));
     175    }
     176
     177    this->base.logger->print(this->base.logger, MSG_INFO, "StackBatch",
     178            "Looping through %ld extended source detections from extension '%s'\n", nDet, extensionName);
     179    for (long s=0; s<nDet; s++) {
     180
     181        fitsIn->getColumnVector(fitsIn, aperFluxColNum,s, type, repeat, vector);
     182        for (int i=0; i<repeat; i++) stackApFlxFluxes[i].flx[s] = vector[i];
     183
     184        fitsIn->getColumnVector(fitsIn, aperFluxErrColNum,s, type, repeat, vector);
     185        for (int i=0; i<repeat; i++) stackApFlxFluxes[i].flxErr[s] = vector[i];
     186
     187        fitsIn->getColumnVector(fitsIn, aperFluxStDevColNum,s, type, repeat, vector);
     188        for (int i=0; i<repeat; i++) stackApFlxFluxes[i].flxStd[s] = vector[i];
     189
     190        fitsIn->getColumnVector(fitsIn, aperFluxFillColNum,s, type, repeat, vector);
     191        for (int i=0; i<repeat; i++) stackApFlxFluxes[i].flxFill[s] = vector[i];
     192
     193    }
     194
     195    free(vector);
     196
     197    //int status = 0;
     198    this->base.fitsGenerator->createAndPopulateTable(this->base.fitsGenerator, fitsIn, this->base.fitsOut, nDet, "StackApFlx", false);
     199    this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, STACKAPFLX_FILTERID, 1, 1, nDet, filterIDs);
     200    this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, STACKAPFLX_SURVEYID, 1, 1, nDet, surveyIDs);
     201
     202    // R1->r10 flux values
     203    // 1
     204    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR1, 1, 1, nDet, stackApFlxFluxes[0].flx);
     205    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR1ERR, 1, 1, nDet, stackApFlxFluxes[0].flxErr);
     206    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR1STD, 1, 1, nDet, stackApFlxFluxes[0].flxStd);
     207    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR1FILL, 1, 1, nDet, stackApFlxFluxes[0].flxFill);
     208    // 2
     209    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR2, 1, 1, nDet, stackApFlxFluxes[1].flx);
     210    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR2ERR, 1, 1, nDet, stackApFlxFluxes[1].flxErr);
     211    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR2STD, 1, 1, nDet, stackApFlxFluxes[1].flxStd);
     212    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR2FILL, 1, 1, nDet, stackApFlxFluxes[1].flxFill);
     213    // 3
     214    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR3, 1, 1, nDet, stackApFlxFluxes[2].flx);
     215    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR3ERR, 1, 1, nDet, stackApFlxFluxes[2].flxErr);
     216    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR3STD, 1, 1, nDet, stackApFlxFluxes[2].flxStd);
     217    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR3FILL, 1, 1, nDet, stackApFlxFluxes[2].flxFill);
     218    // 4
     219    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR4, 1, 1, nDet, stackApFlxFluxes[3].flx);
     220    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR4ERR, 1, 1, nDet, stackApFlxFluxes[3].flxErr);
     221    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR4STD, 1, 1, nDet, stackApFlxFluxes[3].flxStd);
     222    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR4FILL, 1, 1, nDet, stackApFlxFluxes[3].flxFill);
     223    // 5
     224    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR5, 1, 1, nDet, stackApFlxFluxes[4].flx);
     225    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR5ERR, 1, 1, nDet, stackApFlxFluxes[4].flxErr);
     226    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR5STD, 1, 1, nDet, stackApFlxFluxes[4].flxStd);
     227    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR5FILL, 1, 1, nDet, stackApFlxFluxes[4].flxFill);
     228    // 6
     229    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR6, 1, 1, nDet, stackApFlxFluxes[5].flx);
     230    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR6ERR, 1, 1, nDet, stackApFlxFluxes[5].flxErr);
     231    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR6STD, 1, 1, nDet, stackApFlxFluxes[5].flxStd);
     232    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR6FILL, 1, 1, nDet, stackApFlxFluxes[5].flxFill);
     233    // 7
     234    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR7, 1, 1, nDet, stackApFlxFluxes[6].flx);
     235    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR7ERR, 1, 1, nDet, stackApFlxFluxes[6].flxErr);
     236    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR7STD, 1, 1, nDet, stackApFlxFluxes[6].flxStd);
     237    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR7FILL, 1, 1, nDet, stackApFlxFluxes[6].flxFill);
     238    // 8
     239    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR8, 1, 1, nDet, stackApFlxFluxes[7].flx);
     240    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR8ERR, 1, 1, nDet, stackApFlxFluxes[7].flxErr);
     241    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR8STD, 1, 1, nDet, stackApFlxFluxes[7].flxStd);
     242    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR8FILL, 1, 1, nDet, stackApFlxFluxes[7].flxFill);
     243    // 9
     244    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR9, 1, 1, nDet, stackApFlxFluxes[8].flx);
     245    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR9ERR, 1, 1, nDet, stackApFlxFluxes[8].flxErr);
     246    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR9STD, 1, 1, nDet, stackApFlxFluxes[8].flxStd);
     247    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR9FILL, 1, 1, nDet, stackApFlxFluxes[8].flxFill);
     248    // 10
     249    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR10, 1, 1, nDet, stackApFlxFluxes[9].flx);
     250    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR10ERR, 1, 1, nDet, stackApFlxFluxes[9].flxErr);
     251    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR10STD, 1, 1, nDet, stackApFlxFluxes[9].flxStd);
     252    this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, STACKAPFLX_FLXR10FILL, 1, 1, nDet, stackApFlxFluxes[9].flxFill);
     253
     254    for (long i=0; i<11; i++) {
     255
     256        free(stackApFlxFluxes[i].flx);
     257        free(stackApFlxFluxes[i].flxErr);
     258        free(stackApFlxFluxes[i].flxStd);
     259        free(stackApFlxFluxes[i].flxFill);
     260    }
     261
     262    free(stackApFlxFluxes);
     263
     264    return true;
     265}
     266
     267/**
     268  Creates the StackModelFit table
     269  */
     270static bool createStackModelFitTable(
     271        StackBatch* this,
     272        Fits *fitsIn,
     273        int8_t* filterIDs,
     274        int8_t* surveyIDs) {
     275
     276    long nDet = 0;
     277    char extensionName[40];
     278    sprintf(extensionName, "SkyChip.xfit");
     279    if (!fitsIn->moveToBinaryTableAndCountRows(fitsIn, extensionName, &nDet)) return false;
     280
     281    long* ippIdets = (long*)calloc(this->MAXDETECT, sizeof(long));
     282    char** modelTypes = (char**)calloc(this->MAXDETECT, sizeof(char**));
     283    for (uint32_t i=0; i<this->MAXDETECT;i++) modelTypes[i] = (char*)calloc(20,sizeof(char));
     284
     285    // read whole columns
     286    fitsIn->readColumnUsingName(fitsIn, TLONG, "IPP_IDET", 1, 1, nDet, ippIdets);
     287    fitsIn->readColumnUsingName(fitsIn, TSTRING, "MODEL_TYPE", 1, 1, nDet, modelTypes);
     288
     289    this->base.logger->print(this->base.logger, MSG_INFO, "StackBatch",
     290            "Looping through %ld model fit rows from '%s'\n", nDet, extensionName);
     291    for (long i = 0; i<nDet; i++) {
     292
     293        printf("IPP_IDET %ld model %s\n", ippIdets[i], modelTypes[i]);
     294
     295    }
     296
     297    this->base.fitsGenerator->createAndPopulateTable(this->base.fitsGenerator, fitsIn, this->base.fitsOut, nDet, "StackModelFit", false);
     298    this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, STACKMODELFIT_FILTERID, 1, 1, nDet, filterIDs);
     299    this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, STACKMODELFIT_SURVEYID, 1, 1, nDet, surveyIDs);
     300
     301    // free up
     302    free(ippIdets);
     303    for (uint32_t i=0; i<this->MAXDETECT;i++) free(modelTypes[i]);
     304    free(modelTypes);
     305
     306    return true;
     307}
     308
     309/**
     310  Creates the StackToImage table
     311  */
     312static bool createStackToImageTable(
     313        StackBatch* this,
     314        Fits* fitsIn
     315        ) {
     316
     317    this->base.fitsGenerator->createAndPopulateTable(this->base.fitsGenerator, fitsIn, this->base.fitsOut, 3/*TODO*/, "StackToImage", false);
     318
     319    return true;
     320}
     321
     322/**
     323  Does the work. Writes all extensions to new FITS file.
     324  */
     325static int run(StackBatch* this) {
     326
     327    if (this->base.exitCode != PS_EXIT_SUCCESS) return this->base.exitCode;
     328
     329    // open input FITS file
     330    Fits* fitsIn = existing_Fits(this->base.inputFiles[0], this->base.logger);
     331    if (fitsIn->getFilePtr(fitsIn) == NULL)  return PS_EXIT_SYS_ERROR;
     332
     333    // get primary header and pull stuff out for later
     334    float exposureTime; fitsIn->getHeaderKeyValue(fitsIn, TFLOAT, "EXPTIME", &exposureTime);
     335    char filterType[20]; fitsIn->getHeaderKeyValue(fitsIn, TSTRING, "FILTER", filterType);
     336
     337    int8_t filterID = -1;
     338    if (!this->base.initData->getFilterId(this->base.initData, filterType, &filterID)) {
     339
     340        //        this->base.exitCode = PS_EXIT_DATA_ERROR;
     341        //    return this->base.exitCode; TODO
     342    }
     343
     344    exposureTime = 60.0;// TODO
     345    filterID = 3; // TODO
     346
     347    // write StackMeta
     348    this->base.fitsGenerator->createAndPopulateTable(this->base.fitsGenerator, fitsIn, this->base.fitsOut, 1, "StackMeta", true);
     349    this->base.fitsOut->writeColumn(this->base.fitsOut, TLONG, STACKMETA_SKYCELLID, 1, 1, 1, &this->skycellId);
     350    this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, STACKMETA_FILTERID, 1, 1, 1, &filterID);
     351    this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, STACKMETA_SURVEYID, 1, 1, 1, &this->base.surveyID);
     352
     353    // allocate stuff for other extensions
     354    int8_t* filterIDs = (int8_t*)calloc(this->MAXDETECT, sizeof(int8_t));
     355    int8_t* surveyIDs = (int8_t*)calloc(this->MAXDETECT, sizeof(int8_t));
     356    long* skycellIDs = (long*)calloc(this->MAXDETECT, sizeof(long));
     357
     358    // some stuff is the same for all detections so we can populate here
     359    for (long s = 0; s<this->MAXDETECT; s++) {
     360
     361        skycellIDs[s] = this->skycellId;
     362        filterIDs[s] = filterID;
     363        surveyIDs[s] = this->base.surveyID;
     364    }
     365
     366    // create all extensions
     367    createStackDetectionTable(this, fitsIn, filterIDs, surveyIDs, skycellIDs, exposureTime);
     368    createStackApFlxTable(this, fitsIn, filterIDs, surveyIDs);
     369    createStackModelFitTable(this, fitsIn, filterIDs, surveyIDs);
     370    createStackToImageTable(this, fitsIn);
     371
     372    // free stuff up
    197373    free(filterIDs);
    198374    free(surveyIDs);
    199 
    200     status=0;
    201     if (fits_close_file(fitsIn, &status)) fits_report_error(stderr, status);
    202 
     375    free(skycellIDs);
     376    fitsIn->destroy(fitsIn);
    203377
    204378    return this->base.exitCode;
    205379}
    206380
    207 
    208381/**
    209382  Print-out this class. Calls base-calls print method first.
     
    213386    this->base.print(&this->base);
    214387
    215     printf("* skycell ID      : %d\n", this->skycellId);
    216     printf("\n");
     388    this->base.logger->print(this->base.logger, MSG_INFO, "StackBatch", "skycell ID      : %d\n", this->skycellId);
     389    this->base.logger->print(this->base.logger, MSG_INFO, "StackBatch", "\n");
    217390}
    218391
     
    240413    }
    241414
    242     this->base.parseArguments(&this->base, argc, argv);
     415    char fitsOutFile[40];
     416    sprintf(fitsOutFile, "%08d.FITS", this->skycellId);
     417    this->base.parseArguments(&this->base, argc, argv, "/stack", fitsOutFile);
    243418
    244419    if (
     
    262437  Constructor
    263438  */
    264 StackBatch* new_StackBatch(int *argc, char **argv) {
    265 
     439StackBatch* new_StackBatch(Logger* logger, int *argc, char **argv) {
     440
     441    logger->print(logger, MSG_DEBUG, "StackBatch", "Constructor\n");
    266442    StackBatch *this = (StackBatch*)calloc(1, sizeof(StackBatch));
    267443
    268444    // call base-class constructor
    269     if (!new_Batch(&this->base)) {
    270 
    271         psError(PS_ERR_IO, false, "Unable to create Batch base-class object");
    272         return this;
    273     }
     445    new_Batch(logger, &this->base);
    274446
    275447    this->MAXDETECT = 150000;
    276448
     449    // method pointers
    277450    this->print = print;
    278451    this->destroy = destroy;
    279452    this->base.run = run;
    280453
    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);
     454    parseArguments(this, *argc, argv);
     455
     456    this->print(this);
    287457
    288458    return this;
     
    294464int main(int argc, char **argv) {
    295465
    296     psTimerStart("stackbatch");
    297 
    298     ippToPsps_VersionPrint();
    299 
    300     int exitCode;
    301 
    302     StackBatch* stackBatch = new_StackBatch(&argc, argv);
     466//    ippToPsps_VersionPrint();
     467
     468    Logger* logger = new_Logger(NULL, false);
     469    logger->print(logger, MSG_INFO, "main", "Creating new stack batch\n");
     470
     471    StackBatch* stackBatch = new_StackBatch(logger, &argc, argv);
    303472    stackBatch->base.run(stackBatch);
    304     exitCode = stackBatch->base.exitCode;
     473    int exitCode = stackBatch->base.exitCode;
    305474
    306475    stackBatch->destroy(stackBatch);
    307476
    308     double secs = psTimerMark("stackbatch");
    309 
    310     psLogMsg("stackbatch", 3, "stackbatch completed %ssuccessfully, with exit code %d, in %.1f %s\n",
    311             (exitCode == PS_EXIT_SUCCESS) ? "" : "un",
    312             exitCode,
    313             (secs<60.0) ? secs : (secs/60.0),
    314             (secs<60.0) ? "sec(s)" : "min(s)");
    315 
    316477    // tidy up
    317     psTimerStop();
     478    logger->destroy(logger);
    318479    psLibFinalize();
    319480
     
    321482}
    322483
    323 
    324 
  • branches/eam_branches/ipp-20110213/ippToPsps/src/StackBatch.h

    r30147 r31083  
    3030} StackBatch;
    3131
    32 StackBatch *new_StackBatch(int *argc, char **argv);
     32StackBatch *new_StackBatch(Logger* logger, int *argc, char **argv);
    3333
    3434# endif // IPPTOPSPS_STACKBATCH_H
Note: See TracChangeset for help on using the changeset viewer.