# include "dvo.h"
# define ST_SIZE 232

// this function is based on the one generated by the autocode of cmf-ps1-v5.d
int gfits_convert_CMF_PS1_V5 (unsigned char *data, off_t size, off_t nitems, char toStruct) {

  off_t i;
  unsigned char tmp;

  if (size != ST_SIZE) { 
    fprintf (stderr, "WARNING: mismatch in data types CMF_PS1_V5: "OFF_T_FMT" vs %d\n",  size,  ST_SIZE);
    return (FALSE);
  }

  /* provide initial values to avoid compiler warnings for non-BYTE_SWAP arch */
  i = tmp = 0;

  // allocate a temporary output 
  unsigned char tmpdata[64];

  // move the bytes corresponding to PEAK_FLUX_AS_MAG, RA_PSF, DEC_PSF
  if (toStruct) {
    unsigned char *row = data;
    for (i = 0; i < nitems; i++, row += size) {
      memcpy  (tmpdata, &row[92], 4); // save PEAK_FLUX_AS_MAG (92-95)
      memmove (&row[80], &row[76], 16); // move RA_PSF & DEC_PSF
      memcpy  (&row[76], tmpdata, 4); // replace PEAK_FLUX_AS_MAG
    }
  }

  // after we have moved around PEAK_FLUX_AS_MAG, RA_PSF, DEC_PSF, we can swap as needed for this platform
  unsigned char *byte = data;

# ifdef BYTE_SWAP
  byte = (unsigned char *) data;
  for (i = 0; i < nitems; i++, byte += ST_SIZE) {
    /** BYTE SWAP **/
    SWAP_WORD (0); // IPP_IDET                     
    SWAP_WORD (4); // X_PSF
    SWAP_WORD (8); // Y_PSF
    SWAP_WORD (12); // X_PSF_SIG
    SWAP_WORD (16); // Y_PSF_SIG
    SWAP_WORD (20); // POSANGLE
    SWAP_WORD (24); // PLTSCALE
    SWAP_WORD (28); // PSF_INST_MAG
    SWAP_WORD (32); // PSF_INST_MAG_SIG
    SWAP_WORD (36); // PSF_INST_FLUX
    SWAP_WORD (40); // PSF_INST_FLUX_SIG
    SWAP_WORD (44); // AP_MAG
    SWAP_WORD (48); // AP_MAG_RAW
    SWAP_WORD (52); // AP_MAG_RADIUS
    SWAP_WORD (56); // AP_FLUX
    SWAP_WORD (60); // AP_FLUX_SIG
    SWAP_WORD (64); // AP_NPIX
    SWAP_WORD (68); // CAL_PSF_MAG
    SWAP_WORD (72); // CAL_PSF_MAG_SIG
    SWAP_WORD (76); // PEAK_FLUX_AS_MAG
    SWAP_DBLE (80); // RA_PSF
    SWAP_DBLE (88); // DEC_PSF
    SWAP_WORD (96); // SKY
    SWAP_WORD (100); // SKY_SIGMA
    SWAP_WORD (104); // PSF_CHISQ
    SWAP_WORD (108); // CR_NSIGMA
    SWAP_WORD (112); // EXT_NSIGMA
    SWAP_WORD (116); // PSF_MAJOR
    SWAP_WORD (120); // PSF_MINOR
    SWAP_WORD (124); // PSF_THETA
    SWAP_WORD (128); // PSF_CORE
    SWAP_WORD (132); // PSF_FWHM_MAJ
    SWAP_WORD (136); // PSF_FWHM_MIN
    SWAP_WORD (140); // PSF_QF
    SWAP_WORD (144); // PSF_QF_PERFECT
    SWAP_WORD (148); // PSF_NDOF
    SWAP_WORD (152); // PSF_NPIX
    SWAP_WORD (156); // MOMENTS_XX
    SWAP_WORD (160); // MOMENTS_XY
    SWAP_WORD (164); // MOMENTS_YY
    SWAP_WORD (168); // MOMENTS_M3C
    SWAP_WORD (172); // MOMENTS_M3S
    SWAP_WORD (176); // MOMENTS_M4C
    SWAP_WORD (180); // MOMENTS_M4S
    SWAP_WORD (184); // MOMENTS_R1
    SWAP_WORD (188); // MOMENTS_RH
    SWAP_WORD (192); // KRON_FLUX
    SWAP_WORD (196); // KRON_FLUX_ERR
    SWAP_WORD (200); // KRON_FLUX_INNER
    SWAP_WORD (204); // KRON_FLUX_OUTER
    SWAP_WORD (208); // SKY_LIMIT_RAD
    SWAP_WORD (212); // SKY_LIMIT_FLUX
    SWAP_WORD (216); // SKY_LIMIT_SLOPE
    SWAP_WORD (220); // FLAGS
    SWAP_WORD (224); // FLAGS2
    SWAP_BYTE (228); // N_FRAMES
    SWAP_BYTE (230); // PADDING
  }
# endif  

  // move the bytes corresponding to PEAK_FLUX_AS_MAG, RA_PSF, DEC_PSF
  if (!toStruct) {
    unsigned char *row = data;
    for (i = 0; i < nitems; i++, row += size) {
      memcpy  (tmpdata, &row[76], 4); // save PEAK_FLUX_AS_MAG (92-95)
      memmove (&row[76], &row[80], 16); // move RA_PSF & DEC_PSF
      memcpy  (&row[92], tmpdata, 4); // replace PEAK_FLUX_AS_MAG
    }
  }

  return (TRUE);
} 

// data organization (input vs output)
//                FITS               struct
// WORD   (0); // IPP_IDET           IPP_IDET           / 1J                  
// WORD   (4); // X_PSF              X_PSF              / 1E                  
// WORD   (8); // Y_PSF              Y_PSF              / 1E                  
// WORD  (12); // X_PSF_SIG          X_PSF_SIG          / 1E                  
// WORD  (16); // Y_PSF_SIG          Y_PSF_SIG          / 1E                  
// WORD  (20); // POSANGLE           POSANGLE           / 1E                  
// WORD  (24); // PLTSCALE           PLTSCALE           / 1E                  
// WORD  (28); // PSF_INST_MAG       PSF_INST_MAG       / 1E                  
// WORD  (32); // PSF_INST_MAG_SIG   PSF_INST_MAG_SIG   / 1E                  
// WORD  (36); // PSF_INST_FLUX      PSF_INST_FLUX      / 1E                  
// WORD  (40); // PSF_INST_FLUX_SIG  PSF_INST_FLUX_SIG  / 1E                  
// WORD  (44); // AP_MAG             AP_MAG             / 1E                  
// WORD  (48); // AP_MAG_RAW         AP_MAG_RAW         / 1E                  
// WORD  (52); // AP_MAG_RADIUS      AP_MAG_RADIUS      / 1E                  
// WORD  (56); // AP_FLUX            AP_FLUX            / 1E                  
// WORD  (60); // AP_FLUX_SIG        AP_FLUX_SIG        / 1E                  
// WORD  (64); // AP_NPIX            AP_NPIX            / 1J                  
// WORD  (68); // CAL_PSF_MAG        CAL_PSF_MAG        / 1E                  
// WORD  (72); // CAL_PSF_MAG_SIG    CAL_PSF_MAG_SIG    / 1E                  
// WORD  (76); // PEAK_FLUX_AS_MAG   RA_PSF             / 1D                  
// DBLE  (80); // RA_PSF             DEC_PSF            / 1D                  
// DBLE  (88); // DEC_PSF            PEAK_FLUX_AS_MAG   / 1E                  
// WORD  (96); // SKY                SKY                / 1E                  
// WORD (100); // SKY_SIGMA          SKY_SIGMA          / 1E                  
// WORD (104); // PSF_CHISQ          PSF_CHISQ          / 1E                  
// WORD (108); // CR_NSIGMA          CR_NSIGMA          / 1E                  
// WORD (112); // EXT_NSIGMA         EXT_NSIGMA         / 1E                  
// WORD (116); // PSF_MAJOR          PSF_MAJOR          / 1E                  
// WORD (120); // PSF_MINOR          PSF_MINOR          / 1E                  
// WORD (124); // PSF_THETA          PSF_THETA          / 1E                  
// WORD (128); // PSF_CORE           PSF_CORE           / 1E                  
// WORD (132); // PSF_FWHM_MAJ       PSF_FWHM_MAJ       / 1E                  
// WORD (136); // PSF_FWHM_MIN       PSF_FWHM_MIN       / 1E                  
// WORD (140); // PSF_QF             PSF_QF             / 1E                  
// WORD (144); // PSF_QF_PERFECT     PSF_QF_PERFECT     / 1E                  
// WORD (148); // PSF_NDOF           PSF_NDOF           / 1J                  
// WORD (152); // PSF_NPIX           PSF_NPIX           / 1J                  
// WORD (156); // MOMENTS_XX         MOMENTS_XX         / 1E                  
// WORD (160); // MOMENTS_XY         MOMENTS_XY         / 1E                  
// WORD (164); // MOMENTS_YY         MOMENTS_YY         / 1E                  
// WORD (168); // MOMENTS_M3C        MOMENTS_M3C        / 1E                  
// WORD (172); // MOMENTS_M3S        MOMENTS_M3S        / 1E                  
// WORD (176); // MOMENTS_M4C        MOMENTS_M4C        / 1E                  
// WORD (180); // MOMENTS_M4S        MOMENTS_M4S        / 1E                  
// WORD (184); // MOMENTS_R1         MOMENTS_R1         / 1E                  
// WORD (188); // MOMENTS_RH         MOMENTS_RH         / 1E                  
// WORD (192); // KRON_FLUX          KRON_FLUX          / 1E                  
// WORD (196); // KRON_FLUX_ERR      KRON_FLUX_ERR      / 1E                  
// WORD (200); // KRON_FLUX_INNER    KRON_FLUX_INNER    / 1E                  
// WORD (204); // KRON_FLUX_OUTER    KRON_FLUX_OUTER    / 1E                  
// WORD (208); // SKY_LIMIT_RAD      SKY_LIMIT_RAD      / 1E                  
// WORD (212); // SKY_LIMIT_FLUX     SKY_LIMIT_FLUX     / 1E                  
// WORD (216); // SKY_LIMIT_SLOPE    SKY_LIMIT_SLOPE    / 1E                  
// WORD (220); // FLAGS              FLAGS              / 1J                  
// WORD (224); // FLAGS2             FLAGS2             / 1J                  
// BYTE (228); // N_FRAMES           N_FRAMES           / 1I                  
// BYTE (230); // PADDING            PADDING            / 1I                  

/*** add test of EXTNAME and header-defined columns? ***/
/* return internal structure representation */
CMF_PS1_V5 *gfits_table_get_CMF_PS1_V5 (FTable *ftable, off_t *Ndata, char *swapped) {

  int Ncols;
  CMF_PS1_V5 *data;

  Ncols = ftable[0].header[0].Naxis[0];
  if (Ncols != ST_SIZE) {
    fprintf (stderr, "ERROR: mis-match in table size: width is %d but should be %d bytes\n", Ncols, ST_SIZE);
    return NULL;
  }

  *Ndata = ftable[0].header[0].Naxis[1];
  data = (CMF_PS1_V5 *) ftable[0].buffer;
  if ((swapped == NULL) || (*swapped == FALSE)) {
    if (!gfits_convert_CMF_PS1_V5 ((unsigned char *) data, sizeof (CMF_PS1_V5), *Ndata, TRUE)) {
      return NULL;
    }
    gfits_table_scale_data (ftable);
    if (swapped != NULL) *swapped = TRUE;
  }
  return (data);
}

int gfits_table_set_CMF_PS1_V5 (FTable *ftable, CMF_PS1_V5 *data, off_t Ndata) {

  Header *header;

  header = ftable[0].header;

  /* create table header */
  if (!gfits_create_table_header (header, "BINTABLE", "CMF_PS1_V5")) return (FALSE);

  /* define table layout */
  /** TABLE DEFINITION **/
  gfits_define_bintable_column (header, "J",    "IPP_IDET",         "detection ID                     ", "",                  1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "X_PSF",            "x coord",                         "pixels",            1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "Y_PSF",            "y coord",                         "pixels",            1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "X_PSF_SIG",        "x coord error",                   "pixels",            1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "Y_PSF_SIG",        "y coord error",                   "pixels",            1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "POSANGLE",         "Posangle at source",              "degrees",           1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "PLTSCALE",         "Plate Scale at source",           "arcsec/pixel",      1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "PSF_INST_MAG",     "inst mags",                       "mags",              1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "PSF_INST_MAG_SIG", "inst mag error",                  "mags",              1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "PSF_INST_FLUX",    "psf flux",                        "counts",            1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "PSF_INST_FLUX_SIG", "psf flux error",                  "counts      ",      1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "AP_MAG",           "standard aperture mag",           "mags",              1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "AP_MAG_RAW",       "raw aperture mag",                "mags",              1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "AP_MAG_RADIUS",    "radius used for aper",            "pixels",            1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "AP_FLUX",          "aperture flux",                   "counts",            1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "AP_FLUX_SIG",      "error on ap flux",                "counts",            1.0, 0.0);
  gfits_define_bintable_column (header, "J",    "AP_NPIX",          "pixels used by aper",             "pixels",            1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "CAL_PSF_MAG",      "calibrated psf mag",              "mags",              1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "CAL_PSF_MAG_SIG",  "zero point scatter",              "mags",              1.0, 0.0);
  gfits_define_bintable_column (header, "D",    "RA_PSF",           "PSF RA coord",                    "degrees",           1.0, 0.0);
  gfits_define_bintable_column (header, "D",    "DEC_PSF",          "PSF DEC coord",                   "degrees",           1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "PEAK_FLUX_AS_MAG", "peak flux as a mag",              "mags",              1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "SKY",              "sky flux",                        "cnts/sec",          1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "SKY_SIGMA",        "sky flux error",                  "cnts/sec",          1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "PSF_CHISQ",        "psf fit chisq",                   "",                  1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "CR_NSIGMA",        "Nsigma deviations from PSF to CF", "",                  1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "EXT_NSIGMA",       "Nsigma deviations from PSF to EXT", "",                  1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "PSF_MAJOR",        "psf fit major axis",              "pixels",            1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "PSF_MINOR",        "psf fit minor axis",              "pixels",            1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "PSF_THETA",        "ellipse angle",                   "degrees",           1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "PSF_CORE",         "extra PSF parameter",             "unitless",          1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "PSF_FWHM_MAJ",     "true fwhm of psf",                "pixels",            1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "PSF_FWHM_MIN",     "true fwhm (minor)",               "pixels",            1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "PSF_QF",           "quality factor",                  "",                  1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "PSF_QF_PERFECT",   "quality factor perfect",          "",                  1.0, 0.0);
  gfits_define_bintable_column (header, "J",    "PSF_NDOF",         "psf degrees of freedom",          "",                  1.0, 0.0);
  gfits_define_bintable_column (header, "J",    "PSF_NPIX",         "psf number of pixels",            "",                  1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "MOMENTS_XX",       "second moment X",                 "pixels^2",          1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "MOMENTS_XY",       "second moment Y",                 "pixels^2",          1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "MOMENTS_YY",       "second moment XY",                "pixels^2",          1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "MOMENTS_M3C",      "third moment cos(t)",             "pixels^3",          1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "MOMENTS_M3S",      "third moment sin(t)",             "pixels^3",          1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "MOMENTS_M4C",      "fourth moment cos(t)",            "pixels^4",          1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "MOMENTS_M4S",      "fourth moment sin(t)",            "pixels^4",          1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "MOMENTS_R1",       "first radial moment",             "pixels",            1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "MOMENTS_RH",       "half radial moment",              "pixels^1/2",        1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "KRON_FLUX",        "kron flux",                       "counts",            1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "KRON_FLUX_ERR",    "kron flux error",                 "counts",            1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "KRON_FLUX_INNER",  "kron flux 1<R<2.5",               "counts",            1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "KRON_FLUX_OUTER",  "kron flux 2.5<R<4",               "counts",            1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "SKY_LIMIT_RAD",    "profile to sky limit (radius)",   "",                  1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "SKY_LIMIT_FLUX",   "profile to sky limit (flux)",     "",                  1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "SKY_LIMIT_SLOPE",  "profile to sky limit (slope)",    "",                  1.0, 0.0);
  gfits_define_bintable_column (header, "J",    "FLAGS",            "analysis flags",                  "",                  1.0, 0.0);
  gfits_define_bintable_column (header, "J",    "FLAGS2",           "analysis flags (2)",              "",                  1.0, 0.0);
  gfits_define_bintable_column (header, "I",    "N_FRAMES",         "images overlapping peak",         "",                  1.0, 0.0);
  gfits_define_bintable_column (header, "I",    "PADDING",          "padding for 8byte records",       "",                  1.0, 0.0);

  /* create table */
  if (!gfits_create_table (header, ftable)) return (FALSE);

  /* add data values */
  if (!gfits_table_scale_data (ftable)) return (FALSE);
  if (!gfits_convert_CMF_PS1_V5 ((unsigned char *) data, sizeof (CMF_PS1_V5), Ndata, FALSE)) return (FALSE);
  if (!gfits_add_rows (ftable, (char *) data, Ndata, sizeof (CMF_PS1_V5))) return (FALSE);

  return (TRUE);
}

int gfits_table_mkheader_CMF_PS1_V5 (Header *header) {

  /* create table header */
  if (!gfits_create_table_header (header, "BINTABLE", "CMF_PS1_V5")) return (FALSE);

  /* define table layout */
  /** TABLE DEFINITION **/
  gfits_define_bintable_column (header, "J",    "IPP_IDET",         "detection ID                     ", "",                  1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "X_PSF",            "x coord",                         "pixels",            1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "Y_PSF",            "y coord",                         "pixels",            1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "X_PSF_SIG",        "x coord error",                   "pixels",            1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "Y_PSF_SIG",        "y coord error",                   "pixels",            1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "POSANGLE",         "Posangle at source",              "degrees",           1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "PLTSCALE",         "Plate Scale at source",           "arcsec/pixel",      1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "PSF_INST_MAG",     "inst mags",                       "mags",              1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "PSF_INST_MAG_SIG", "inst mag error",                  "mags",              1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "PSF_INST_FLUX",    "psf flux",                        "counts",            1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "PSF_INST_FLUX_SIG", "psf flux error",                  "counts      ",      1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "AP_MAG",           "standard aperture mag",           "mags",              1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "AP_MAG_RAW",       "raw aperture mag",                "mags",              1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "AP_MAG_RADIUS",    "radius used for aper",            "pixels",            1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "AP_FLUX",          "aperture flux",                   "counts",            1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "AP_FLUX_SIG",      "error on ap flux",                "counts",            1.0, 0.0);
  gfits_define_bintable_column (header, "J",    "AP_NPIX",          "pixels used by aper",             "pixels",            1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "CAL_PSF_MAG",      "calibrated psf mag",              "mags",              1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "CAL_PSF_MAG_SIG",  "zero point scatter",              "mags",              1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "PEAK_FLUX_AS_MAG", "peak flux as a mag",              "mags",              1.0, 0.0);
  gfits_define_bintable_column (header, "D",    "RA_PSF",           "PSF RA coord",                    "degrees",           1.0, 0.0);
  gfits_define_bintable_column (header, "D",    "DEC_PSF",          "PSF DEC coord",                   "degrees",           1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "SKY",              "sky flux",                        "cnts/sec",          1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "SKY_SIGMA",        "sky flux error",                  "cnts/sec",          1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "PSF_CHISQ",        "psf fit chisq",                   "",                  1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "CR_NSIGMA",        "Nsigma deviations from PSF to CF", "",                  1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "EXT_NSIGMA",       "Nsigma deviations from PSF to EXT", "",                  1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "PSF_MAJOR",        "psf fit major axis",              "pixels",            1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "PSF_MINOR",        "psf fit minor axis",              "pixels",            1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "PSF_THETA",        "ellipse angle",                   "degrees",           1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "PSF_CORE",         "extra PSF parameter",             "unitless",          1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "PSF_FWHM_MAJ",     "true fwhm of psf",                "pixels",            1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "PSF_FWHM_MIN",     "true fwhm (minor)",               "pixels",            1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "PSF_QF",           "quality factor",                  "",                  1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "PSF_QF_PERFECT",   "quality factor perfect",          "",                  1.0, 0.0);
  gfits_define_bintable_column (header, "J",    "PSF_NDOF",         "psf degrees of freedom",          "",                  1.0, 0.0);
  gfits_define_bintable_column (header, "J",    "PSF_NPIX",         "psf number of pixels",            "",                  1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "MOMENTS_XX",       "second moment X",                 "pixels^2",          1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "MOMENTS_XY",       "second moment Y",                 "pixels^2",          1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "MOMENTS_YY",       "second moment XY",                "pixels^2",          1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "MOMENTS_M3C",      "third moment cos(t)",             "pixels^3",          1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "MOMENTS_M3S",      "third moment sin(t)",             "pixels^3",          1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "MOMENTS_M4C",      "fourth moment cos(t)",            "pixels^4",          1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "MOMENTS_M4S",      "fourth moment sin(t)",            "pixels^4",          1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "MOMENTS_R1",       "first radial moment",             "pixels",            1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "MOMENTS_RH",       "half radial moment",              "pixels^1/2",        1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "KRON_FLUX",        "kron flux",                       "counts",            1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "KRON_FLUX_ERR",    "kron flux error",                 "counts",            1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "KRON_FLUX_INNER",  "kron flux 1<R<2.5",               "counts",            1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "KRON_FLUX_OUTER",  "kron flux 2.5<R<4",               "counts",            1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "SKY_LIMIT_RAD",    "profile to sky limit (radius)",   "",                  1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "SKY_LIMIT_FLUX",   "profile to sky limit (flux)",     "",                  1.0, 0.0);
  gfits_define_bintable_column (header, "E",    "SKY_LIMIT_SLOPE",  "profile to sky limit (slope)",    "",                  1.0, 0.0);
  gfits_define_bintable_column (header, "J",    "FLAGS",            "analysis flags",                  "",                  1.0, 0.0);
  gfits_define_bintable_column (header, "J",    "FLAGS2",           "analysis flags (2)",              "",                  1.0, 0.0);
  gfits_define_bintable_column (header, "I",    "N_FRAMES",         "images overlapping peak",         "",                  1.0, 0.0);
  gfits_define_bintable_column (header, "I",    "PADDING",          "padding for 8byte records",       "",                  1.0, 0.0);

  return (TRUE);
}

int Send_CMF_PS1_V5 (int device, CMF_PS1_V5 *data, int Ndata, int copy) {

  int Nwrite, Nbytes;
  CMF_PS1_V5 *tmpdata;

  Nbytes = Ndata * sizeof (CMF_PS1_V5);

  if (copy) {
    ALLOCATE (tmpdata, CMF_PS1_V5, Ndata);
    memcpy (tmpdata, data, Nbytes);
  } else {
    tmpdata = data;
  }

  if (!gfits_convert_CMF_PS1_V5 ((unsigned char *) tmpdata, sizeof (CMF_PS1_V5), Ndata, FALSE)) return (FALSE);

  SendCommand (device, 16, "NVALUE: %6d", Ndata);
  SendCommand (device, 16, "NBYTES: %6d", Nbytes);
  Nwrite = write (device, tmpdata, Nbytes);
  if (Nwrite != Nbytes) {
    return (FALSE);
  }
  
  /* perform handshaking? */

  return (TRUE);
}

int Recv_CMF_PS1_V5 (int device, CMF_PS1_V5 **data, int *Ndata) {

  int ndata;
  IOBuffer message;
  CMF_PS1_V5 *tmpdata;

  ExpectCommand (device, 16, 1.0, &message);
  sscanf (message.buffer, "%*s %d", &ndata);
  FreeIOBuffer (&message);
  
  /* what is reasonable for timeout? */
  ExpectMessage (device, 1.0, &message);
  
  tmpdata = (CMF_PS1_V5 *) message.buffer;
  if (!gfits_convert_CMF_PS1_V5 ((unsigned char *) tmpdata, sizeof (CMF_PS1_V5), ndata, TRUE)) return (FALSE);

  /* double-check data length? */
  /* perform handshaking? */

  *Ndata = ndata;
  *data = tmpdata;

  return (TRUE);
}

