Index: trunk/ippToPsps/src/DetectionBatch.c
===================================================================
--- trunk/ippToPsps/src/DetectionBatch.c	(revision 30967)
+++ trunk/ippToPsps/src/DetectionBatch.c	(revision 31011)
@@ -1,4 +1,7 @@
 #include "DetectionBatch.h"
 #include "DetectionBatchEnums.h"
+
+#include "Fits.h"
+
 
 /**
@@ -43,53 +46,38 @@
     if (this->base.exitCode != PS_EXIT_SUCCESS) return this->base.exitCode;
 
-    int status = 0;
-    fitsfile *fitsIn;
-
-    if (fits_open_file(&fitsIn, this->base.inputFiles[0], READONLY, &status)) {
-
-        fits_report_error(stderr, status);
-        return PS_EXIT_SYS_ERROR;
-    }
-
-    // get primary header and pull stuff out for later
-    int nKeys;
-    fits_get_hdrspace(fitsIn, &nKeys, NULL, &status);
-
-    float zptObs, exposureTime;
-    char filterType[20];
-    double obsTime;
-    double expStart;
-    double expTime;
-    status=0; fits_read_key(fitsIn, TFLOAT, "ZPT_OBS", &zptObs, NULL, &status);
-    status=0; fits_read_key(fitsIn, TFLOAT, "EXPREQ", &exposureTime, NULL, &status);
-    status=0; fits_read_key(fitsIn, TSTRING, "FILTERID", filterType, NULL, &status);
-    status=0; fits_read_key(fitsIn, TDOUBLE, "MJD-OBS", &expStart, NULL, &status);
-    status=0; fits_read_key(fitsIn, TDOUBLE, "EXPTIME", &expTime, NULL, &status);
-    obsTime = expStart + (expTime/172800.0); // exp start plus half exp time (converted from secs to days)
-
-    ippToPspsConfig_writeTable(this->base.config, fitsIn, this->base.fitsOut, 1, "FrameMeta", true);
+    // open input FITS file
+    Fits* fitsIn = existing_Fits(this->base.inputFiles[0]);
+    if (fitsIn->getFilePtr(fitsIn) == NULL)  return PS_EXIT_SYS_ERROR;
+
+    // read some header values 
+    float zptObs; fitsIn->getHeaderKeyValue(fitsIn, TFLOAT, "ZPT_OBS", &zptObs);
+    float exposureTime; fitsIn->getHeaderKeyValue(fitsIn, TFLOAT, "EXPREQ", &exposureTime);
+    char filterType[20]; fitsIn->getHeaderKeyValue(fitsIn, TSTRING, "FILTERID", filterType);
+    double expStart; fitsIn->getHeaderKeyValue(fitsIn, TDOUBLE, "MJD-OBS", &expStart); 
+    double expTime; fitsIn->getHeaderKeyValue(fitsIn, TDOUBLE, "EXPTIME", &expTime);
+    double obsTime = expStart + (expTime/172800.0); // exp start plus half exp time (converted from secs to days)
+
+
+    this->base.config->createAndPopulateTable(this->base.config, fitsIn, this->base.fitsOut, 1, "FrameMeta", true);
 
     // FrameMeta values
-    fits_write_col(this->base.fitsOut, TLONG, FRAMEMETA_FRAMEID, 1, 1, 1, &this->expId, &status);
-    fits_write_col(this->base.fitsOut, TSTRING, FRAMEMETA_FRAMENAME, 1, 1, 1, &(this->expName), &status);
-    fits_write_col(this->base.fitsOut, TBYTE, FRAMEMETA_SURVEYID, 1, 1, 1, &this->base.surveyID, &status);
-
     int8_t filterID = -1;
-    if (!ippToPspsConfig_getFilterId(this->base.config, filterType, &filterID)) {
+    if (!this->base.config->getFilterId(this->base.config, filterType, &filterID)) {
     
         this->base.exitCode = PS_EXIT_DATA_ERROR;
         return this->base.exitCode;
     }
-
-    fits_write_col(this->base.fitsOut, TBYTE, FRAMEMETA_FILTERID, 1, 1, 1, &filterID, &status);
+    this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, FRAMEMETA_FILTERID, 1, 1, 1, &filterID);
+    this->base.fitsOut->writeColumn(this->base.fitsOut, TLONG, FRAMEMETA_FRAMEID, 1, 1, 1, &this->expId);
+    this->base.fitsOut->writeColumn(this->base.fitsOut, TSTRING, FRAMEMETA_FRAMENAME, 1, 1, 1, &(this->expName));
+    this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, FRAMEMETA_SURVEYID, 1, 1, 1, &this->base.surveyID);
+
 
     int16_t cameraID = 1; // TODO
-    fits_write_col(this->base.fitsOut, TSHORT, FRAMEMETA_CAMERAID, 1, 1, 1, &cameraID, &status);
-
     int16_t cameraConfigID = 1; // TODO
-    fits_write_col(this->base.fitsOut, TSHORT, FRAMEMETA_CAMERACONFIGID, 1, 1, 1, &cameraConfigID, &status);
-
     int16_t telescopeID = 1; // TODO
-    fits_write_col(this->base.fitsOut, TSHORT, FRAMEMETA_TELESCOPEID, 1, 1, 1, &telescopeID, &status);
+    this->base.fitsOut->writeColumn(this->base.fitsOut, TSHORT, FRAMEMETA_CAMERAID, 1, 1, 1, &cameraID);
+    this->base.fitsOut->writeColumn(this->base.fitsOut, TSHORT, FRAMEMETA_CAMERACONFIGID, 1, 1, 1, &cameraConfigID);
+    this->base.fitsOut->writeColumn(this->base.fitsOut, TSHORT, FRAMEMETA_TELESCOPEID, 1, 1, 1, &telescopeID);
 
     // stuff to keep from psf.hdr header
@@ -107,10 +95,6 @@
     uint32_t s,d, invalidDvoRows, nChipDetectionsOut = 0;
 
-    long longnull = -999;
-    float floatnull = -999.0;
-    int anynull = 0;
-
     char ccdNumber[3], extensionName[15];
-    // for storing FITS column data
+    // for storing FITS column data - do this once, to avoid expension free/calloc for each chip
     long* ippIDet = (long*)calloc(this->MAXDETECT, sizeof(long));
     float* instMag = (float*)calloc(this->MAXDETECT, sizeof(float));
@@ -129,5 +113,4 @@
     int8_t* filterIDs = (int8_t*)calloc(this->MAXDETECT, sizeof(int8_t));
     int8_t* surveyIDs = (int8_t*)calloc(this->MAXDETECT, sizeof(int8_t));
-
     char** assocDate = (char**)calloc(this->MAXDETECT, sizeof(char*));
     for (uint32_t i=0; i<this->MAXDETECT;i++) assocDate[i] = (char*)malloc(20*sizeof(char));
@@ -186,21 +169,22 @@
             sprintf(ccdNumber, "%d%d", x, y);
 
-            // check we can move to detections table in smf
+            // check we CAN move to detections table in smf
             sprintf(extensionName, "XY%s.psf", ccdNumber);
-            if (!ippToPspsConfig_moveToExtensionTable(fitsIn, extensionName)) continue;
+            if (!fitsIn->moveToBinaryTable(fitsIn, extensionName)) continue;
 
             // move to header extension
             sprintf(extensionName, "XY%s.hdr", ccdNumber);
-            if (!ippToPspsConfig_moveToExtensionHeader(fitsIn, extensionName)) continue;
+            if (!fitsIn->moveToHeader(fitsIn, extensionName)) continue;
 
             // stuff to save from psf.hdr
-            status=0; fits_read_key(fitsIn, TFLOAT, "FWHM_MAJ", &fwhmMaj, NULL, &status);
-            status=0; fits_read_key(fitsIn, TFLOAT, "FWHM_MIN", &fwhmMin, NULL, &status);
-            status=0; fits_read_key(fitsIn, TFLOAT, "IQ_FW1", &momentMaj, NULL, &status);
-            status=0; fits_read_key(fitsIn, TFLOAT, "IQ_FW2", &momentMin, NULL, &status);
-            status=0; fits_read_key(fitsIn, TLONG, "IMAGEID", &imageId, NULL, &status);
-            status=0; fits_read_key(fitsIn, TLONG, "SOURCEID", &sourceId, NULL, &status);
-            status=0; fits_read_key(fitsIn, TLONG, "NASTRO", &numPhotoRef, NULL, &status);
+            fitsIn->getHeaderKeyValue(fitsIn, TFLOAT, "FWHM_MAJ", &fwhmMaj);
+            fitsIn->getHeaderKeyValue(fitsIn, TFLOAT, "FWHM_MIN", &fwhmMin);
+            fitsIn->getHeaderKeyValue(fitsIn, TFLOAT, "IQ_FW1", &momentMaj);
+            fitsIn->getHeaderKeyValue(fitsIn, TFLOAT, "IQ_FW2", &momentMin);
+            fitsIn->getHeaderKeyValue(fitsIn, TLONG, "IMAGEID", &imageId);
+            fitsIn->getHeaderKeyValue(fitsIn, TLONG, "SOURCEID", &sourceId);
+            fitsIn->getHeaderKeyValue(fitsIn, TLONG, "NASTRO", &numPhotoRef);
             totalNumPhotoRef += numPhotoRef; // total up for storing in FrameMeta
+
             // access DVO database
             skylist = dvoSkyListByExternID(this->base.dvoConfig, sourceId, imageId, &image);
@@ -221,6 +205,5 @@
             if (numDvoDetections > this->MAXDETECT ) {
 
-                psError(PS_ERR_IO, false,
-                        " Number of detections (%d) exceeds max limit (%ld)\n",
+                psError(PS_ERR_IO, false, " Number of detections (%d) exceeds max limit (%ld)\n",
                         numDvoDetections, this->MAXDETECT);
                 error = true;
@@ -229,54 +212,46 @@
 
             // create ImageMeta
-            ippToPspsConfig_writeTable(this->base.config, fitsIn, this->base.fitsOut, 1, "ImageMeta", true);
+            this->base.config->createAndPopulateTable(this->base.config, fitsIn, this->base.fitsOut, 1, "ImageMeta", true);
             psfFwhm = (fwhmMaj+fwhmMin)/2;
             momentFwhm = (momentMaj+momentMin)/2;
             imageFlags = (uint64_t)image->flags;
-            fits_write_col(this->base.fitsOut, TLONGLONG, IMAGEMETA_IMAGEID, 1, 1, 1, &pspsImageId, &status);
-            fits_write_col(this->base.fitsOut, TLONG, IMAGEMETA_FRAMEID, 1, 1, 1, &this->expId, &status);
-            fits_write_col(this->base.fitsOut, TSHORT, IMAGEMETA_CCDID, 1, 1, 1, &image->ccdnum, &status);
-            fits_write_col(this->base.fitsOut, TLONG, IMAGEMETA_PHOTOCALID, 1, 1, 1, &image->photcode, &status);
-            fits_write_col(this->base.fitsOut, TBYTE, IMAGEMETA_FILTERID, 1, 1, 1, &filterID, &status);
-            fits_write_col(this->base.fitsOut, TFLOAT, IMAGEMETA_PHOTOSCAT, 1, 1, 1, &zptObs, &status);
-            fits_write_col(this->base.fitsOut, TFLOAT, IMAGEMETA_PSFFWHM, 1, 1, 1, &psfFwhm, &status);
-            fits_write_col(this->base.fitsOut, TFLOAT, IMAGEMETA_MOMENTFWHM, 1, 1, 1, &momentFwhm, &status);
-            fits_write_col(this->base.fitsOut, TFLOAT, IMAGEMETA_PHOTOZERO, 1, 1, 1, &zptObs, &status);
-            fits_write_col(this->base.fitsOut, TLONGLONG, IMAGEMETA_QAFLAGS, 1, 1, 1, &imageFlags, &status);
+            this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, IMAGEMETA_IMAGEID, 1, 1, 1, &pspsImageId);
+            this->base.fitsOut->writeColumn(this->base.fitsOut, TLONG, IMAGEMETA_FRAMEID, 1, 1, 1, &this->expId);
+            this->base.fitsOut->writeColumn(this->base.fitsOut, TSHORT, IMAGEMETA_CCDID, 1, 1, 1, &image->ccdnum);
+            this->base.fitsOut->writeColumn(this->base.fitsOut, TLONG, IMAGEMETA_PHOTOCALID, 1, 1, 1, &image->photcode);
+            this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, IMAGEMETA_FILTERID, 1, 1, 1, &filterID);
+            this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, IMAGEMETA_PHOTOSCAT, 1, 1, 1, &zptObs);
+            this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, IMAGEMETA_PSFFWHM, 1, 1, 1, &psfFwhm);
+            this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, IMAGEMETA_MOMENTFWHM, 1, 1, 1, &momentFwhm);
+            this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, IMAGEMETA_PHOTOZERO, 1, 1, 1, &zptObs);
+            this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, IMAGEMETA_QAFLAGS, 1, 1, 1, &imageFlags);
 
             // now move BACK to detections table in smf
             sprintf(extensionName, "XY%s.psf", ccdNumber);
-            if (!ippToPspsConfig_moveToExtensionTable(fitsIn, extensionName)) continue;
-
-            // keep a running count of 'images' we find in order to write total to FrameMeta at the end
+            long nChipDetectionsIn = 0;
+            if (!fitsIn->moveToBinaryTableAndCountRows(fitsIn, extensionName, &nChipDetectionsIn)) continue;
+
+            // keep a running count of 'images' we find in order to write total into FrameMeta at the end
             nOta++;
-
-            long nChipDetectionsIn = 0;
-            if (fits_get_num_rows(fitsIn, &nChipDetectionsIn, &status)) {
-                fits_report_error(stderr, status);
-            }
 
             // loop round detections to populate some extra stuff
             s = d = nChipDetectionsOut = invalidDvoRows = 0;
 
-            // determine column numbers for certain IPP detection columns
+            // determine column numbers for certain IPP detection columns - do this only once to save time
             if (firstTimeIn) {
 
-                status=0;fits_get_colnum(fitsIn, CASESEN, "IPP_IDET", &ippIDetNum, &status);
-                if (status) psError(PS_ERR_IO, false, "Unable to read col num for IPP_IDET");
-                status=0;fits_get_colnum(fitsIn, CASESEN, "PSF_INST_MAG", &instMagNum, &status);
-                if (status) psError(PS_ERR_IO, false, "Unable to read col num for PSF_INST_MAG");
-                status=0;fits_get_colnum(fitsIn, CASESEN, "PSF_INST_MAG_SIG", &instMagErrNum, &status);
-                if (status) psError(PS_ERR_IO, false, "Unable to read col num for PSF_INST_MAG_SIG");
-                status=0;fits_get_colnum(fitsIn, CASESEN, "PEAK_FLUX_AS_MAG", &peakMagNum, &status);
-                if (status) psError(PS_ERR_IO, false, "Unable to read col num for PEAK_FLUX_AS_MAG");
+                fitsIn->getColumnNumber(fitsIn, "IPP_IDET", &ippIDetNum);
+                fitsIn->getColumnNumber(fitsIn, "PSF_INST_MAG", &instMagNum);
+                fitsIn->getColumnNumber(fitsIn, "PSF_INST_MAG_SIG", &instMagErrNum);
+                fitsIn->getColumnNumber(fitsIn, "PEAK_FLUX_AS_MAG", &peakMagNum);
 
                 firstTimeIn=false;
             }
 
-            anynull = 0;
-            fits_read_col(fitsIn, TLONG, ippIDetNum, 1, 1, nChipDetectionsIn, &longnull, ippIDet, &anynull, &status);
-            fits_read_col(fitsIn, TFLOAT, instMagNum, 1, 1, nChipDetectionsIn, &floatnull, instMag, &anynull, &status);
-            fits_read_col(fitsIn, TFLOAT, instMagErrNum, 1, 1, nChipDetectionsIn, &floatnull, instMagErr, &anynull, &status);
-            fits_read_col(fitsIn, TFLOAT, peakMagNum, 1, 1, nChipDetectionsIn, &floatnull, peakMag, &anynull, &status);
+            //anynull = 0;
+            fitsIn->readColumn(fitsIn, TLONG, ippIDetNum, 1, 1, nChipDetectionsIn, ippIDet);
+            fitsIn->readColumn(fitsIn, TFLOAT, instMagNum, 1, 1, nChipDetectionsIn, instMag);
+            fitsIn->readColumn(fitsIn, TFLOAT, instMagErrNum, 1, 1, nChipDetectionsIn, instMagErr);
+            fitsIn->readColumn(fitsIn, TFLOAT, peakMagNum, 1, 1, nChipDetectionsIn, peakMag);
 
             // DVO detections are ordered by IPP_IDET, which increments from 0 in SMF table
@@ -288,4 +263,5 @@
             // loop through all detections in smf file extension for this chip.
             // there are three ways for a detection to be ommitted from the final FITS output:
+            //
             // 1. it has a duplicate obj ID to a previous detection
             // 2. it has an invalid detection ID (< 0 or > max DVO det ID)
@@ -355,5 +331,5 @@
 
             // write number of rows (detections) to ImageMeta
-            fits_write_col(this->base.fitsOut, TLONG, IMAGEMETA_NDETECT, 1, 1, 1, &nChipDetectionsOut, &status);
+            this->base.fitsOut->writeColumn(this->base.fitsOut, TLONG, IMAGEMETA_NDETECT, 1, 1, 1, &nChipDetectionsOut);
 
             int totalRemove = numOfDuplicates+numInvalidFlux+numOfInvalidIppIDet;
@@ -363,36 +339,33 @@
 
                 // detections
-                ippToPspsConfig_writeTable(this->base.config, fitsIn, this->base.fitsOut, nChipDetectionsIn, "Detection", false);
-                fits_write_col(this->base.fitsOut, TLONGLONG, DETECTION_OBJID, 1, 1, nChipDetectionsIn, objID, &status);
-                fits_write_col(this->base.fitsOut, TLONGLONG, DETECTION_DETECTID, 1, 1, nChipDetectionsIn, detectID, &status);
-                fits_write_col(this->base.fitsOut, TLONGLONG, DETECTION_IPPOBJID, 1, 1, nChipDetectionsIn, ippObjID, &status);
-                fits_write_col(this->base.fitsOut, TLONGLONG, DETECTION_IPPDETECTID, 1, 1, nChipDetectionsIn, ippDetectID, &status);
-                fits_write_col(this->base.fitsOut, TBYTE, DETECTION_FILTERID, 1, 1, nChipDetectionsIn, filterIDs, &status);
-                fits_write_col(this->base.fitsOut, TBYTE, DETECTION_SURVEYID, 1, 1, nChipDetectionsIn, surveyIDs, &status);
-                fits_write_col(this->base.fitsOut, TLONGLONG, DETECTION_IMAGEID, 1, 1, nChipDetectionsIn, imageID, &status);
-                fits_write_col(this->base.fitsOut, TDOUBLE, DETECTION_OBSTIME, 1, 1, nChipDetectionsIn, obsTimes, &status);
-                fits_write_col(this->base.fitsOut, TFLOAT, DETECTION_INSTFLUX, 1, 1, nChipDetectionsIn, instFlux, &status);
-                fits_write_col(this->base.fitsOut, TFLOAT, DETECTION_INSTFLUXERR, 1, 1, nChipDetectionsIn, instFluxErr, &status);
-                fits_write_col(this->base.fitsOut, TFLOAT, DETECTION_PEAKADU, 1, 1, nChipDetectionsIn, peakFlux, &status);
-                fits_write_col(this->base.fitsOut, TSTRING, DETECTION_ASSOCDATE, 1, 1, nChipDetectionsIn, assocDate, &status);
-                fits_write_col(this->base.fitsOut, TLONGLONG, DETECTION_INFOFLAG, 1, 1, nChipDetectionsIn, flags, &status);
-                if (numOfDuplicates||numInvalidFlux||numOfInvalidIppIDet) 
-                    fits_delete_rowlist(this->base.fitsOut, removeList, totalRemove, &status);
+                this->base.config->createAndPopulateTable(this->base.config, fitsIn, this->base.fitsOut, nChipDetectionsIn, "Detection", false);
+                this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, DETECTION_OBJID, 1, 1, nChipDetectionsIn, objID);
+                this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, DETECTION_DETECTID, 1, 1, nChipDetectionsIn, detectID);
+                this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, DETECTION_IPPOBJID, 1, 1, nChipDetectionsIn, ippObjID);
+                this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, DETECTION_IPPDETECTID, 1, 1, nChipDetectionsIn, ippDetectID);
+                this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, DETECTION_FILTERID, 1, 1, nChipDetectionsIn, filterIDs);
+                this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, DETECTION_SURVEYID, 1, 1, nChipDetectionsIn, surveyIDs);
+                this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, DETECTION_IMAGEID, 1, 1, nChipDetectionsIn, imageID);
+                this->base.fitsOut->writeColumn(this->base.fitsOut, TDOUBLE, DETECTION_OBSTIME, 1, 1, nChipDetectionsIn, obsTimes);
+                this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, DETECTION_INSTFLUX, 1, 1, nChipDetectionsIn, instFlux);
+                this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, DETECTION_INSTFLUXERR, 1, 1, nChipDetectionsIn, instFluxErr);
+                this->base.fitsOut->writeColumn(this->base.fitsOut, TFLOAT, DETECTION_PEAKADU, 1, 1, nChipDetectionsIn, peakFlux);
+                this->base.fitsOut->writeColumn(this->base.fitsOut, TSTRING, DETECTION_ASSOCDATE, 1, 1, nChipDetectionsIn, assocDate);
+                this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, DETECTION_INFOFLAG, 1, 1, nChipDetectionsIn, flags);
+                if (numOfDuplicates||numInvalidFlux||numOfInvalidIppIDet) this->base.fitsOut->deleteRows(this->base.fitsOut, removeList, totalRemove); 
 
                 // skinny object
-                ippToPspsConfig_writeTable(this->base.config, fitsIn, this->base.fitsOut, nChipDetectionsIn, "SkinnyObject", false);
-                fits_write_col(this->base.fitsOut, TLONGLONG, SKINNYOBJECT_OBJID, 1, 1, nChipDetectionsIn, objID, &status);
-                fits_write_col(this->base.fitsOut, TLONGLONG, SKINNYOBJECT_IPPOBJID, 1, 1, nChipDetectionsIn, ippObjID, &status);
-                fits_write_col(this->base.fitsOut, TBYTE, SKINNYOBJECT_SURVEYID, 1, 1, nChipDetectionsIn, surveyIDs, &status);
-                if (numOfDuplicates||numInvalidFlux||numOfInvalidIppIDet)
-                    fits_delete_rowlist(this->base.fitsOut, removeList, totalRemove, &status);
+                this->base.config->createAndPopulateTable(this->base.config, fitsIn, this->base.fitsOut, nChipDetectionsIn, "SkinnyObject", false);
+                this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, SKINNYOBJECT_OBJID, 1, 1, nChipDetectionsIn, objID);
+                this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, SKINNYOBJECT_IPPOBJID, 1, 1, nChipDetectionsIn, ippObjID);
+                this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, SKINNYOBJECT_SURVEYID, 1, 1, nChipDetectionsIn, surveyIDs);
+                if (numOfDuplicates||numInvalidFlux||numOfInvalidIppIDet) this->base.fitsOut->deleteRows(this->base.fitsOut, removeList, totalRemove);
 
                 // object calibration color
-                ippToPspsConfig_writeTable(this->base.config, fitsIn, this->base.fitsOut, nChipDetectionsIn, "ObjectCalColor", false);
-                fits_write_col(this->base.fitsOut, TLONGLONG, OBJECTCALCOLOR_OBJID, 1, 1, nChipDetectionsIn, objID, &status);
-                fits_write_col(this->base.fitsOut, TLONGLONG, OBJECTCALCOLOR_IPPOBJID, 1, 1, nChipDetectionsIn, ippObjID, &status);
-                fits_write_col(this->base.fitsOut, TBYTE, OBJECTCALCOLOR_FILTERID, 1, 1, nChipDetectionsIn, filterIDs, &status);
-                if (numOfDuplicates||numInvalidFlux||numOfInvalidIppIDet)
-                    fits_delete_rowlist(this->base.fitsOut, removeList, totalRemove, &status);
+                this->base.config->createAndPopulateTable(this->base.config, fitsIn, this->base.fitsOut, nChipDetectionsIn, "ObjectCalColor", false);
+                this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, OBJECTCALCOLOR_OBJID, 1, 1, nChipDetectionsIn, objID);
+                this->base.fitsOut->writeColumn(this->base.fitsOut, TLONGLONG, OBJECTCALCOLOR_IPPOBJID, 1, 1, nChipDetectionsIn, ippObjID);
+                this->base.fitsOut->writeColumn(this->base.fitsOut, TBYTE, OBJECTCALCOLOR_FILTERID, 1, 1, nChipDetectionsIn, filterIDs);
+                if (numOfDuplicates||numInvalidFlux||numOfInvalidIppIDet) this->base.fitsOut->deleteRows(this->base.fitsOut, removeList, totalRemove);
             }
 
@@ -436,12 +409,11 @@
 
     // write number of images we have found into FrameMeta table
-    if (ippToPspsConfig_moveToExtensionTable(this->base.fitsOut, "FrameMeta")) { 
-
-        fits_write_col(this->base.fitsOut, TSHORT, FRAMEMETA_NOTA, 1, 1, 1, &nOta, &status);
-        fits_write_col(this->base.fitsOut, TSHORT, FRAMEMETA_NUMPHOTOREF, 1, 1, 1, &totalNumPhotoRef, &status);
-    }
-
-    status=0;
-    if (fits_close_file(fitsIn, &status)) fits_report_error(stderr, status);
+    if (this->base.fitsOut->moveToBinaryTable(this->base.fitsOut, "FrameMeta")) {
+
+        this->base.fitsOut->writeColumn(this->base.fitsOut, TSHORT, FRAMEMETA_NOTA, 1, 1, 1, &nOta);
+        this->base.fitsOut->writeColumn(this->base.fitsOut, TSHORT, FRAMEMETA_NUMPHOTOREF, 1, 1, 1, &totalNumPhotoRef);
+    }
+
+    fitsIn->destroy(fitsIn);
 
     writeResults(this, minObjID, maxObjID, totalDetectionsOut);
@@ -496,5 +468,7 @@
     }
 
-    this->base.parseArguments(&this->base, argc, argv);
+    char fitsOutFile[40];
+    sprintf(fitsOutFile, "%08d.FITS", this->expId);
+    this->base.parseArguments(&this->base, argc, argv, "/detection", fitsOutFile);
 
     if (
@@ -532,4 +506,5 @@
     this->MAXDETECT = 200000;
 
+    // method pointers
     this->print = print;
     this->destroy = destroy;
@@ -538,10 +513,5 @@
     this->expName = (char*)calloc(100, sizeof(char));
 
-    if (!parseArguments(this, *argc, argv)) { return this; }
-
-    strcat(this->base.configsDir, "/detection");
-    sprintf(this->base.fitsOutFile, "%08d.FITS", this->expId);
-
-    this->base.init(&this->base);
+    parseArguments(this, *argc, argv);
 
     return this;
@@ -565,5 +535,5 @@
     detectionBatch->destroy(detectionBatch);
 
-    double secs = psTimerMark("ippToPsps");
+    double secs = psTimerMark("detectionbatch");
 
     psLogMsg("detectionbatch", 3, "detectionbatch completed %ssuccessfully, with exit code %d, in %.1f %s\n",
