Index: trunk/Ohana/src/libdvo/Makefile
===================================================================
--- trunk/Ohana/src/libdvo/Makefile	(revision 11991)
+++ trunk/Ohana/src/libdvo/Makefile	(revision 12332)
@@ -29,5 +29,10 @@
 $(SRC)/version.$(ARCH).o	 \
 $(SRC)/coordops.$(ARCH).o	 \
+$(SRC)/dvo_photcode_ops.$(ARCH).o \
 $(SRC)/LoadPhotcodes.$(ARCH).o   \
+$(SRC)/LoadPhotcodesText.$(ARCH).o   \
+$(SRC)/LoadPhotcodesFITS.$(ARCH).o   \
+$(SRC)/SavePhotcodesText.$(ARCH).o   \
+$(SRC)/SavePhotcodesFITS.$(ARCH).o   \
 $(SRC)/imreg_datatypes.$(ARCH).o \
 $(SRC)/mosaic_astrom.$(ARCH).o   \
@@ -41,12 +46,15 @@
 $(SRC)/dvo_catalog_split.$(ARCH).o     \
 $(SRC)/dvo_catalog_create.$(ARCH).o    \
+$(SRC)/dvo_catalog_chipcoords.$(ARCH).o \
 $(SRC)/dvo_convert.$(ARCH).o           \
 $(SRC)/dvo_convert_elixir.$(ARCH).o    \
 $(SRC)/dvo_convert_loneos.$(ARCH).o    \
-$(SRC)/dvo_convert_panstarrs.$(ARCH).o \
-$(SRC)/dvo_convert_pmtest.$(ARCH).o \
+$(SRC)/dvo_convert_panstarrs_DEV_0.$(ARCH).o \
 $(SRC)/skyregion_io.$(ARCH).o    \
 $(SRC)/skyregion_gsc.$(ARCH).o    \
 $(SRC)/skyregion_ops.$(ARCH).o
+
+# $(SRC)/dvo_convert_panstarrs.$(ARCH).o \
+# $(SRC)/dvo_convert_pmtest.$(ARCH).o \
 
 include ../libautocode/Makefile.Targets
Index: trunk/Ohana/src/libdvo/doc/dvo-structures.txt
===================================================================
--- trunk/Ohana/src/libdvo/doc/dvo-structures.txt	(revision 11991)
+++ trunk/Ohana/src/libdvo/doc/dvo-structures.txt	(revision 12332)
@@ -1,2 +1,76 @@
+
+2007.02.22
+
+I have several DVO improvements to implement.  I need to plan them a
+bit carefully.  Here are my thoughts on these updates.
+
+- add chip X,Y to measure table
+
+  this is a fairly simple addition.  In addstar/find_matches, I just need
+  to assign the X,Y value from the incoming star data.  For loading
+  old catalogs which don't include X,Y in the table, I need to
+  calculate the X,Y position based on the R,D after finding the
+  matching image.  I have code to do this calculation currently in
+  dvo/photometry.c for looking up X,Y on the fly.  once this is moved
+  into the load functions, it will not be needed in photometry.c
+
+- remove PRI/SEC and only use secfilt table for mags
+
+  this is not a very difficult change, conceptually, but it may be a
+  fair amount of work.  all of the functions which currently switch on
+  the case of PRI/SEC just need to look in the secfilt location.  the
+  value of Nsec needs to increase by 1.  the load from tables which
+  used PRI/SEC need to move the PRI values to the correct location in
+  secfilt
+
+  eventually, rename 'secfilt' to a better name choice
+
+- add image, average, measure IDs
+
+  for PS1, the image and measure need to be generated by the external
+  software.  they would just be part of the input stream.  for the
+  case were the IDs are not supplied, DVO needs to generate them in a
+  unique way.  I probably need to understand / define that mechanism
+  before tackling this problem.
+
+  one point: I need to keep the old averef index.  how do this index
+  and the objID work together?
+
+- link measure to image
+
+  temporariliy use an index like averef?
+
+- move photcode table to catdir (also zero points)
+
+  should be fairly easy: just like the SkyTable, look in the catdir
+  first, then generate from the default text table if it is missing.
+
+- color term as a function of mosaic position
+ 
+- mextract field,field,field 
+
+  this should not be a very difficult job.  just add a loop to the
+  avextract / mextract functions.
+
+- mextract field(s) where condition
+
+  this is a bit trickier, and could make use of the code in the dvo
+  math functions
+
+- dvo select from mysql
+
+  not very difficult: need to define the commands to select the
+  database and set up a connection, then parse the select line into
+  the appropriate format.  just need to as the db for the type of the
+  fields that are requested: must be numerical.
+
+  select field,field,field from table where condition
+
+- change vectors to doubles
+
+  probably not a terrible job.  this will depend on how the union is
+  defined.  I don't want this to explode the size of an image!
+
+---------
 
 I now have the ability to load and save DVO databases in old formats,
@@ -12,10 +86,11 @@
 - CFHT Elixir databases: cmp files, ELIXIR format
 - Brandon's Taurus db: incorrect 'PANSTARRS' format, should be called
-  'PSTEST1'
+  'PSTEST1'.  drop support for this eventually? have brandon migrate to
+  the new panstarrs formats?
 
 I am going to use the following naming convention for future db table
 updates:
 
-- PANSTARRS.DEV.0
+- PANSTARRS.DEV.0, PANSTARRS.DEV.1, etc
 - PANSTARRS.PS1.0, PANSTARRS.PS1.1, etc
 - PANSTARRS.PS4.0, PANSTARRS.PS4.1, etc
Index: trunk/Ohana/src/libdvo/doc/notes.txt
===================================================================
--- trunk/Ohana/src/libdvo/doc/notes.txt	(revision 12332)
+++ trunk/Ohana/src/libdvo/doc/notes.txt	(revision 12332)
@@ -0,0 +1,55 @@
+
+Adding a new dvo catalog format.  Assume the new format name is 'foo'.
+
+1) create the autocode definition files for average, measure, secfilt, image
+   these files must be a subset of the internal versions of these same
+   tables.  if you intend to add fields which don't exist in the
+   internal tables, you must update the internal tables as well.  the
+   naming convention is: average-foo.d, etc.
+
+2) add the new definition files to libautocode/Makefile.Targets (both
+   .o and .h lists).
+
+3) set the STRUCT and EXTNAME for these definitions files to have a
+   unique value. the naming convention for EXTNAME is DVO_AVERAGE_FOO
+   and for STRUCT is AverageFoo (add version info with underscores and
+   uppercase, eg: AveragePanstarrs_DEV_0, AveragePanstarrs_PS1_2).
+
+4) create a DVOTableFormat entry for the new format
+   (libdvo/include/dvo.h).  the naming convetion is DVO_FORMAT_FOO.
+
+5) add an entry for the new format in dvo_catalog_catformat
+ (libdvo/src/dvo_catalog.c).  The name should be "FOO".
+
+6) add entry for structure size in dvo_catalog_load_raw
+   (libdvo/src/dvo_catalog_raw.c), since this is not available from
+   the header.
+
+7) add entries in ReadRawAverage, WriteRawAverage, ReadRawMeasure,
+   WriteRawMeasure, ReadRawSecFilt, WriteRawSecFilt.  Make sure to use
+   the new STRUCT names. the conversion function gfit_convert_Foo will
+   be automatically generated.
+
+8) add entry in WriteRawAverage, making sure to use the new STRUCT
+   name. the conversion function gfit_convert_Foo will be
+   automatically generated.  
+
+9) create a new conversion file dvo_convert_foo.c and define the
+   internal to Foo conversions.
+
+* Note some esoteric format issues:  
+
+  - LONEOS and ELIXIR lack chip coordinates, and must apply an
+    on-the-fly conversion, implemented in dvo_catalog_chipcoords. 
+
+  - LONEOS and ELIXIR use the old primary/secondary photcode concept,
+    and must have one photcode dataset extracted from the average
+    table on read and resupplied on write.  this happens in
+    dvo_catalog_save_mef, dvo_catalog_save_raw,
+    dvo_catalog_save_split, dvo_catalog_update_split
+
+  - LONEOS and ELIXIR have old versions where the header does not
+    specify the type explicitly.  the functions dvo_catalog_load_raw
+    and dvo_image_load_raw identify these types based on special
+    keywords.
+
Index: trunk/Ohana/src/libdvo/include/dvo.h
===================================================================
--- trunk/Ohana/src/libdvo/include/dvo.h	(revision 11991)
+++ trunk/Ohana/src/libdvo/include/dvo.h	(revision 12332)
@@ -18,9 +18,40 @@
 
 /* DVO table formats */
-enum {DVO_FORMAT_UNDEF, DVO_FORMAT_INTERNAL, DVO_FORMAT_ELIXIR, DVO_FORMAT_LONEOS, DVO_FORMAT_PANSTARRS, DVO_FORMAT_PMTEST} DVOTableFormat;
+enum {DVO_FORMAT_UNDEF, 
+      DVO_FORMAT_INTERNAL, 
+      DVO_FORMAT_ELIXIR, 
+      DVO_FORMAT_LONEOS, 
+      DVO_FORMAT_PANSTARRS, 
+      DVO_FORMAT_PMTEST, 
+      DVO_FORMAT_PANSTARRS_DEV_0
+} DVOTableFormat;
 
 /* image data modes in RegImage */
 enum {T_UNDEF = -1, T_NONE, T_OBJECT, T_DARK, T_BIAS, T_FLAT, T_MASK, T_FRINGE, T_SCATTER, T_MODES, T_FRINGEPTS, T_ANY, N_TYPE};
 enum {M_UNDEF = -1, M_NONE, M_MEF, M_SPLIT, M_SINGLE, M_CUBE, M_SLICE, M_MODES, N_MODE};
+
+typedef enum {
+    PROJ_NONE, // undefined
+    PROJ_ZEA, // zenithal
+    PROJ_ZPL, // zenithal
+    PROJ_ARC, // zenithal
+    PROJ_STG, // zenithal
+    PROJ_SIN, // zenithal
+    PROJ_TAN, // zenithal
+    PROJ_DIS, // zenithal (TAN + polyterms)
+    PROJ_LIN, // cartesian
+    PROJ_PLY, // cartesian
+    PROJ_WRP, // cartesian
+    PROJ_AIT, // pseudocyl
+    PROJ_GLS, // pseudocyl
+    PROJ_PAR, // pseudocyl
+} OhanaProjection;
+
+typedef enum {
+  PROJ_MODE_NONE,
+  PROJ_MODE_CARTESIAN,
+  PROJ_MODE_ZENITHAL,
+  PROJ_MODE_PSEUDOCYL,
+} OhanaProjectionMode;
 
 /* RegImage.flag values */
@@ -39,5 +70,5 @@
 
 /* photometry code types */
-# define PHOT_PRI 0x01
+// # define PHOT_PRI 0x01
 # define PHOT_SEC 0x02
 # define PHOT_DEP 0x03
@@ -133,8 +164,9 @@
 
 typedef struct {
-  int Ncode;
-  int Nsecfilt;
-  int hashcode[0x10000];
-  int hashNsec[0x10000];
+  int Ncode;					  // number of photcodes
+  int Nsecfilt;					  // number of average magnitudes
+  int hashcode[0x10000];		  // index from photcode value to sequence
+  int hashNsec[0x10000];		  // index from photcode value to Nsec seq
+  int codeNsec[0x10000];		  // index from Nsec seq to photcode value
   PhotCode *code;
 } PhotCodeData;
@@ -191,4 +223,8 @@
 
 /* in coords.c, using libautocode/def/coords.d */
+int  XY_to_LM (double *L, double *M, double x,  double y,   Coords *coords);
+int  LM_to_XY (double *x,  double *y,   double L, double M, Coords *coords);
+int  RD_to_LM (double *L, double *M, double ra,  double dec,   Coords *coords);
+int  LM_to_RD (double *ra, double *dec,   double L, double M, Coords *coords);
 int  XY_to_RD (double *ra, double *dec, double x,  double y,   Coords *coords);
 int  RD_to_XY (double *x,  double *y,   double ra, double dec, Coords *coords);
@@ -199,4 +235,7 @@
 void RegisterMosaic (Coords *coords);
 void coords_precess (double *ra, double *dec, double in_epoch, double out_epoch);
+OhanaProjection GetProjection (char *ctype);
+int SetProjection (char *ctype, OhanaProjection proj);
+OhanaProjectionMode GetProjectionMode (OhanaProjection proj);
 
 char *libdvo_version ();
@@ -232,21 +271,17 @@
 float PhotdM (PhotCode *code, Average *average, SecFilt *secfilt);
 
-# if (0)
-short iPhotInst (Measure *measure);
-short iPhotAbs (Measure *measure);
-short iPhotCat (Measure *measure);
-short iPhotSys (Measure *measure, Average *average, SecFilt *secfilt);
-short iPhotRel (Measure *measure, Average *average, SecFilt *secfilt);
-short iPhotCal (Measure *thisone, Average *average, SecFilt *secfilt, Measure *measure, PhotCode *code);
-short iPhotAve (PhotCode *code, Average *average, SecFilt *secfilt);
-short iPhotRef (PhotCode *code, Average *average, SecFilt *secfilt, Measure *measure);
-short iPhotXm (PhotCode *code, Average *average, SecFilt *secfilt);
-short iPhotdM (PhotCode *code, Average *average, SecFilt *secfilt);
-# endif
-
-float iPhotColor (Average *average, SecFilt *secfilt, Measure *measure, PhotCode *code);
+float PhotColorForCode (Average *average, SecFilt *secfilt, Measure *measure, PhotCode *code);
 int PhotColor (Average *average, SecFilt *secfilt, Measure *measure, int c1, int c2, double *color);
 
-int LoadPhotcodes (char *filename);
+PhotCodeData *GetPhotcodeTable ();
+
+int LoadPhotcodes (char *catdir_file, char *master_file);
+int LoadPhotcodesText (char *filename);
+int LoadPhotcodesFITS (char *filename);
+int SavePhotcodesText (char *filename);
+int SavePhotcodesFITS (char *filename);
+
+void PrintPhotcodeNamebyCode (FILE *f, char *format, int code);
+
 int GetPhotcodeCodebyName (char *name);
 int GetPhotcodeEquivCodebyName (char *name);
@@ -297,40 +332,61 @@
 
 /*** conversion functions / I/O conversions ***/
-Average *ReadRawAverage (FILE *f, int Naverage, int format);
+Average *ReadRawAverage (FILE *f, int Naverage, int format, SecFilt **primary);
 Measure *ReadRawMeasure (FILE *f, int Nmeasure, int format);
 SecFilt *ReadRawSecFilt (FILE *f, int Nsecfilt, int format);
-int WriteRawAverage (FILE *f, Average *average, int Naverage, int format);
+int WriteRawAverage (FILE *f, Average *average, int Naverage, int format, SecFilt *primary);
 int WriteRawMeasure (FILE *f, Measure *measure, int Nmeasure, int format);
 int WriteRawSecFilt (FILE *f, SecFilt *secfilt, int Nsecfilt, int format);
 
-Average *FtableToAverage (FTable *ftable, int *Naverage, int *format);
-Average *AverageLoneosToInternal (AverageLoneos *in, int Nvalues);
-Average *AverageElixirToInternal (AverageElixir *in, int Nvalues);
-Average *AveragePanstarrsToInternal (AveragePanstarrs *in, int Nvalues);
-Average *AveragePMtestToInternal (AveragePMtest *in, int Nvalues);
-AverageLoneos *AverageInternalToLoneos (Average *in, int Nvalues);
-AverageElixir *AverageInternalToElixir (Average *in, int Nvalues);
-AveragePanstarrs *AverageInternalToPanstarrs (Average *in, int Nvalues);
-AveragePMtest *AverageInternalToPMtest (Average *in, int Nvalues);
-
+Average *FtableToAverage (FTable *ftable, int *Naverage, int *format, SecFilt **primary);
 Measure *FtableToMeasure (FTable *ftable, int *Nmeasure, int *format);
-Measure *MeasureLoneosToInternal (MeasureLoneos *in, int Nvalues);
-Measure *MeasureElixirToInternal (MeasureElixir *in, int Nvalues);
-Measure *MeasurePanstarrsToInternal (MeasurePanstarrs *in, int Nvalues);
-MeasureLoneos *MeasureInternalToLoneos (Measure *in, int Nvalues);
-MeasureElixir *MeasureInternalToElixir (Measure *in, int Nvalues);
-MeasurePanstarrs *MeasureInternalToPanstarrs (Measure *in, int Nvalues);
-
 SecFilt *FtableToSecFilt (FTable *ftable, int *Nsecfilt, int *format);
-SecFilt *SecFiltLoneosToInternal (SecFiltLoneos *in, int Nvalues);
-SecFilt *SecFiltElixirToInternal (SecFiltElixir *in, int Nvalues);
-SecFilt *SecFiltPanstarrsToInternal (SecFiltPanstarrs *in, int Nvalues);
-SecFiltLoneos *SecFiltInternalToLoneos (SecFilt *in, int Nvalues);
-SecFiltElixir *SecFiltInternalToElixir (SecFilt *in, int Nvalues);
-SecFiltPanstarrs *SecFiltInternalToPanstarrs (SecFilt *in, int Nvalues);
-
-int AverageToFtable (FTable *ftable, Average *average, int Naverage, int format);
+int FtableToImage (FTable *ftable, Header *theader, int *format);
+
+int AverageToFtable (FTable *ftable, Average *average, int Naverage, int format, SecFilt *primary);
 int MeasureToFtable (FTable *ftable, Measure *measure, int Nmeasure, int format);
 int SecFiltToFtable (FTable *ftable, SecFilt *secfilt, int Nsecfilt, int format);
+int ImageToFtable (FTable *ftable, Header *theader, int format);
+int ImageToVtable (VTable *vtable, Header *theader, int format);
+
+Image 		       *ImageElixirToInternal (ImageElixir *in, int Nvalues);
+Image 		       *ImageLoneosToInternal (ImageLoneos *in, int Nvalues);
+Image 		       *ImagePanstarrsToInternal (ImagePanstarrs *in, int Nvalues);
+Image 		       *ImagePanstarrs_DEV_0_ToInternal (ImagePanstarrs_DEV_0 *in, int Nvalues);
+
+ImageElixir 	       *ImageInternalToElixir (Image *in, int Nvalues);
+ImageLoneos 	       *ImageInternalToLoneos (Image *in, int Nvalues);
+ImagePanstarrs         *ImageInternalToPanstarrs (Image *in, int Nvalues);
+ImagePanstarrs_DEV_0   *ImageInternalToPanstarrs_DEV_0 (Image *in, int Nvalues);
+
+Average                *AverageLoneosToInternal (AverageLoneos *in, int Nvalues, SecFilt **primary);
+Average 	       *AverageElixirToInternal (AverageElixir *in, int Nvalues, SecFilt **primary);
+Average 	       *AveragePanstarrsToInternal (AveragePanstarrs *in, int Nvalues);
+Average 	       *AveragePanstarrs_DEV_0_ToInternal (AveragePanstarrs_DEV_0 *in, int Nvalues);
+
+AverageLoneos 	       *AverageInternalToLoneos (Average *in, int Nvalues, SecFilt *primary);
+AverageElixir 	       *AverageInternalToElixir (Average *in, int Nvalues, SecFilt *primary);
+AveragePanstarrs       *AverageInternalToPanstarrs (Average *in, int Nvalues);
+AveragePanstarrs_DEV_0 *AverageInternalToPanstarrs_DEV_0 (Average *in, int Nvalues);
+
+Measure                *MeasureLoneosToInternal (MeasureLoneos *in, int Nvalues);
+Measure 	       *MeasureElixirToInternal (MeasureElixir *in, int Nvalues);
+Measure 	       *MeasurePanstarrsToInternal (MeasurePanstarrs *in, int Nvalues);
+Measure 	       *MeasurePanstarrs_DEV_0_ToInternal (MeasurePanstarrs_DEV_0 *in, int Nvalues);
+
+MeasureLoneos 	       *MeasureInternalToLoneos (Measure *in, int Nvalues);
+MeasureElixir 	       *MeasureInternalToElixir (Measure *in, int Nvalues);
+MeasurePanstarrs       *MeasureInternalToPanstarrs (Measure *in, int Nvalues);
+MeasurePanstarrs_DEV_0 *MeasureInternalToPanstarrs_DEV_0 (Measure *in, int Nvalues);
+
+SecFilt 	       *SecFiltLoneosToInternal (SecFiltLoneos *in, int Nvalues);
+SecFilt 	       *SecFiltElixirToInternal (SecFiltElixir *in, int Nvalues);
+SecFilt 	       *SecFiltPanstarrsToInternal (SecFiltPanstarrs *in, int Nvalues);
+SecFilt 	       *SecFiltPanstarrs_DEV_0_ToInternal (SecFiltPanstarrs_DEV_0 *in, int Nvalues);
+
+SecFiltLoneos 	       *SecFiltInternalToLoneos (SecFilt *in, int Nvalues);
+SecFiltElixir 	       *SecFiltInternalToElixir (SecFilt *in, int Nvalues);
+SecFiltPanstarrs       *SecFiltInternalToPanstarrs (SecFilt *in, int Nvalues);
+SecFiltPanstarrs_DEV_0 *SecFiltInternalToPanstarrs_DEV_0 (SecFilt *in, int Nvalues);
 
 /*** DVO image db I/O Functions ***/
@@ -345,14 +401,4 @@
 int dvo_image_addrows (FITS_DB *db, Image *new, int Nnew);
 void dvo_image_create (FITS_DB *db, double ZeroPoint);
-
-int FtableToImage (FTable *ftable, Header *theader, int *format);
-int ImageToFtable (FTable *ftable, Header *theader, int format);
-int ImageToVtable (VTable *vtable, Header *theader, int format);
-Image *ImageElixirToInternal (ImageElixir *in, int Nvalues);
-ImageElixir *ImageInternalToElixir (Image *in, int Nvalues);
-Image *ImageLoneosToInternal (ImageLoneos *in, int Nvalues);
-ImageLoneos *ImageInternalToLoneos (Image *in, int Nvalues);
-Image *ImagePanstarrsToInternal (ImagePanstarrs *in, int Nvalues);
-ImagePanstarrs *ImageInternalToPanstarrs (Image *in, int Nvalues);
 
 /* skyregion APIs */
Index: trunk/Ohana/src/libdvo/src/LoadPhotcodes.c
===================================================================
--- trunk/Ohana/src/libdvo/src/LoadPhotcodes.c	(revision 11991)
+++ trunk/Ohana/src/libdvo/src/LoadPhotcodes.c	(revision 12332)
@@ -1,801 +1,17 @@
 # include <dvo.h>
 
-# define NCTERMS 4
-# define F_PS 0.001
-# define NO_MAG_PS 100.0
+int LoadPhotcodes (char *catdir_file, char *master_file) {
 
-static PhotCodeData *photcodes = NULL;
-static double ZERO_POINT;
-static short int Nseclist[0x10000];
-
-/* static short int iZERO_POINT; */
-
-void SetZeroPoint (double ZP) {
-  ZERO_POINT = ZP;
-  /* iZERO_POINT = 1000 * ZP; */
-}
-
-int LoadPhotcodes (char *filename) {
+  /* first try to load the photcodes from the specified CATDIR location */
+  if (LoadPhotcodesFITS (catdir_file)) return TRUE;
   
-  FILE *f;
-  int i, Ns, Np, NPHOTCODE, Npri, Nfield;
-  PhotCode *photcode;
-  int code;
-  char *c;
-  char line[256];
-  char name[32], type[32], Zero[32], Airmass[32], Offset[32],
-    C1[32], C2[32], Slope[32], Color[32], Primary[32];
-  int c1, c2;
-
-  /* allocate space to photcode table, free existing data */
-  if (photcodes == NULL) {
-    ALLOCATE (photcodes, PhotCodeData, 1);
-    photcodes[0].code = NULL;
-  }
-  if (photcodes[0].code != NULL) free (photcodes[0].code);
-
-  f = fopen (filename, "r");
-  if (f == (FILE *) NULL) {
-    photcodes[0].Ncode    = 0;
-    photcodes[0].Nsecfilt = 0;
-    photcodes[0].code     = (PhotCode *) NULL;
-    return (FALSE);
+  /* next try to load the photcodes from the master text photcode file */
+  /* automatically (or on demand?) save the text file to the FITS version */
+  if (LoadPhotcodesText (master_file)) { 
+      if (!check_file_access (catdir_file, TRUE, TRUE)) return TRUE;
+      SavePhotcodesFITS (catdir_file);
+      return TRUE;
   }
 
-  Np = 0;
-  NPHOTCODE = 10;
-  ALLOCATE (photcode, PhotCode, NPHOTCODE);
-  photcodes[0].Nsecfilt = 0;
-  for (i = 0; i < 0x10000; i++) {
-    photcodes[0].hashcode[i] = -1;
-    photcodes[0].hashNsec[i] = -1;
-  }
-
-  while (scan_line (f, line) != EOF) {
-    for (c = line; isspace (*c); c++);
-    if (*c == '#') continue;
-    Nfield = sscanf (c, "%d %s %s %s %s %s %s %s %s %s %s", 
-		     &code, name, type, Zero, Airmass, Offset, C1, C2, Slope, Color, Primary);
-    if (Nfield != 11) { continue; }
-    
-    c1 = atof (C1);
-    c2 = atof (C2);
-    if (!strcmp (C1, "-")) { c1 = 0; }
-    if (!strcmp (C2, "-")) { c2 = 0; }
-
-    photcode[Np].type = 0;
-    photcode[Np].code = code;
-    strcpy (photcode[Np].name, name);
-    if (!strncasecmp (type, "pri", 3)) {
-      photcode[Np].type  = PHOT_PRI;
-      photcode[Np].C     = 1000*atof (Zero);
-      photcode[Np].K     = atof (Airmass);
-      photcode[Np].dC    = 1000*atof (Offset);
-      photcode[Np].dX    = 1000*atof (Color);
-      photcode[Np].c1    = c1;
-      photcode[Np].c2    = c2;
-      photcode[Np].equiv = atoi (Primary);
-      ParseColorTerms (Slope, photcode[Np].X, &photcode[Np].Nc);
-      Nseclist[0] = Np;
-    }      
-    if (!strncasecmp (type, "sec", 3)) {
-      photcode[Np].type  = PHOT_SEC;
-      photcode[Np].C     = 1000*atof (Zero);
-      photcode[Np].K     = atof (Airmass);
-      photcode[Np].dC    = 1000*atof (Offset);
-      photcode[Np].dX    = 1000*atof (Color);
-      photcode[Np].c1    = c1;
-      photcode[Np].c2    = c2;
-      photcode[Np].equiv = atoi (Primary);
-      photcodes[0].Nsecfilt ++;
-      ParseColorTerms (Slope, photcode[Np].X, &photcode[Np].Nc);
-      Nseclist[photcodes[0].Nsecfilt] = Np;
-    }      
-    if (!strncasecmp (type, "dep", 3)) {
-      photcode[Np].type  = PHOT_DEP;
-      photcode[Np].C     = 1000*atof (Zero);    /* zero point in millimags */
-      photcode[Np].K     = atof (Airmass);      /* airmass coeff (millimag / millimag) */
-      photcode[Np].dC    = 1000*atof (Offset);  /* color ref z.p. (millimag) */
-      photcode[Np].dX    = 1000*atof (Color);   /* average color (millimag) */
-      photcode[Np].c1    = c1;
-      photcode[Np].c2    = c2;
-      photcode[Np].equiv = atoi (Primary);
-      ParseColorTerms (Slope, photcode[Np].X, &photcode[Np].Nc);
-    }      
-    if (!strncasecmp (type, "ref", 3)) {
-      photcode[Np].type  = PHOT_REF;
-      photcode[Np].C     = 0;
-      photcode[Np].K     = 0;
-      photcode[Np].dC    = 0;
-      photcode[Np].dX    = 0;
-      photcode[Np].c1    = 0;
-      photcode[Np].c2    = 0;
-      photcode[Np].equiv = atoi (Primary);
-      photcode[Np].X[0]  = 0;
-      photcode[Np].Nc    = 0;
-    }
-
-    /* alt photcodes are a little different: they have the SAME photcode as an existing
-       pri/sec photcode, but define an alternate transformation for that code */
-    if (!strncasecmp (type, "alt", 3)) {
-      photcode[Np].type  = PHOT_ALT;
-      photcode[Np].C     = 1000*atof (Zero);    /* zero point in millimags */
-      photcode[Np].K     = atof (Airmass);      /* airmass coeff (millimag / millimag) */
-      photcode[Np].dC    = 1000*atof (Offset);  /* color ref z.p. (millimag) */
-      photcode[Np].dX    = 1000*atof (Color);   /* average color (millimag) */
-      photcode[Np].c1    = c1;
-      photcode[Np].c2    = c2;
-      photcode[Np].equiv = atoi (Primary);
-      ParseColorTerms (Slope, photcode[Np].X, &photcode[Np].Nc);
-    }
-    if (!photcode[Np].type) {
-      fprintf (stderr, "error in Photfile: unknown type %s\n", type);
-    }
-
-    Np++;
-    if (Np == NPHOTCODE) {
-      NPHOTCODE += 10;
-      REALLOCATE (photcode, PhotCode, NPHOTCODE);
-    }
-  }
-  fclose (f);
-  
-  /* set up hashcode for photcode refs:
-   * the hashcode gives the structure sequence for a given photcode:
-   * photcode[i].hashcode[photcode[i].code] == i
-   */
-
-  Ns = 0;
-  for (i = 0; i < Np; i++) {
-    if (photcode[i].type == PHOT_ALT) continue; /* no hashcode for ALT codes */
-    if (photcodes[0].hashcode[photcode[i].code] != -1) {
-      fprintf (stderr, "duplicate photcodes in file\n");
-      code = photcodes[0].hashcode[photcode[i].code];
-      fprintf (stderr, "conflict between %s (%d) and %s (%d)\n",
-	       photcode[i].name, photcode[i].code, photcode[code].name, photcode[code].code);
-      free (photcode);
-      return (FALSE);
-    }
-    photcodes[0].hashcode[photcode[i].code] = i;
-    if (photcode[i].type == PHOT_SEC) {
-      photcodes[0].hashNsec[photcode[i].code] = Ns;
-      Ns ++;
-    }
-  }
-  /* validity check for references */
-  for (i = 0; i < Np; i++) {
-    if (photcode[i].type == PHOT_DEP) {
-      Npri = photcodes[0].hashcode[photcode[i].equiv];
-      if ((Npri >= Np) || (Npri < 0)) {
-	fprintf (stderr, "reference for dependent photcode is not in photcodes\n");
-	free (photcode);
-	return (FALSE);
-      }
-      if ((photcode[Npri].type != PHOT_PRI) && (photcode[Npri].type != PHOT_SEC)) {
-	fprintf (stderr, "reference for dependent photcode is not a primary or secondary code\n");
-	free (photcode);
-	return (FALSE);
-      }
-    }
-    if (photcode[i].type == PHOT_ALT) {
-      Npri = photcodes[0].hashcode[photcode[i].code];
-      if ((Npri >= Np) || (Npri < 0)) {
-	fprintf (stderr, "reference for alternate photcode is not in photcodes\n");
-	free (photcode);
-	return (FALSE);
-      }
-      if ((photcode[Npri].type != PHOT_PRI) && (photcode[Npri].type != PHOT_SEC)) {
-	fprintf (stderr, "reference for alternate photcode is not a primary or secondary code\n");
-	free (photcode);
-	return (FALSE);
-      }
-    }
-  }
-  photcodes[0].code = photcode;
-  photcodes[0].Ncode = Np;
-
-  return (TRUE);
-
+  return FALSE;
 }
-
-void ParseColorTerms (char *terms, float *X, int *N) {
-
-  int i;
-  char *p;
-
-  p = terms;
-
-  for (i = 0; (p != NULL) && (i < NCTERMS); i++) {
-    X[i] = atof (p);
-    p = strchr (p, ',');
-    if (p == (char *) NULL) continue;
-    p ++;
-  }
-  *N = i;
-}
-
-/********** photcode lookups **********/
-
-/* return photcode for given name */
-PhotCode *GetPhotcodebyName (char *name) {
-  
-  int i;
-
-  if (name == (char *) NULL ) return (NULL);
-  
-  for (i = 0; i < photcodes[0].Ncode; i++) {
-    if (!strcmp (photcodes[0].code[i].name, name)) {
-      return (&photcodes[0].code[i]);
-    }
-  }
-  return (NULL);
-}
-/* return photcode.code for given name */
-int GetPhotcodeCodebyName (char *name) {
-  
-  int i;
-  
-  if (name == (char *) NULL ) return (0);
-
-  for (i = 0; i < photcodes[0].Ncode; i++) {
-    if (!strcmp (photcodes[0].code[i].name, name)) {
-      return (photcodes[0].code[i].code);
-    }
-  }
-  return (0);
-}
-/* return equivalent photcode for given name */
-PhotCode *GetPhotcodeEquivbyName (char *name) {
-  
-  int i, equiv;
-  
-  if (name == (char *) NULL ) return (NULL);
-
-  for (i = 0; i < photcodes[0].Ncode; i++) {
-    if (!strcmp (photcodes[0].code[i].name, name)) {
-      if (photcodes[0].code[i].equiv == 0) return (NULL);
-      equiv = photcodes[0].hashcode[photcodes[0].code[i].equiv];
-      if (equiv == -1) return (NULL);
-      return (&photcodes[0].code[equiv]);
-    }
-  }
-  return (NULL);
-}
-/* return equivalent photcode.code for given name */
-int GetPhotcodeEquivCodebyName (char *name) {
-  
-  int i, equiv;
-  
-  if (name == (char *) NULL ) return (0);
-
-  for (i = 0; i < photcodes[0].Ncode; i++) {
-    if (!strcmp (photcodes[0].code[i].name, name)) {
-      if (photcodes[0].code[i].equiv == 0) return (0);
-      equiv = photcodes[0].hashcode[photcodes[0].code[i].equiv];
-      if (equiv == -1) return (0);
-      return (photcodes[0].code[equiv].code);
-    }
-  }
-  return (0);
-}
-
-/* return photcode for given code */
-PhotCode *GetPhotcodebyCode (int code) {
-  
-  int entry;
-  
-  if (code < 0) return (NULL);
-  if (code > 0x10000) return (NULL);
-
-  entry = photcodes[0].hashcode[code];
-  if (entry == -1) return (NULL);
-
-  return (&photcodes[0].code[entry]);
-}
-/* return photcode.code for given code */
-char *GetPhotcodeNamebyCode (int code) {
-  
-  int entry;
-  
-  if (code < 0) return (NULL);
-  if (code > 0x10000) return (NULL);
-
-  entry = photcodes[0].hashcode[code];
-  if (entry == -1) return (NULL);
-
-  return (photcodes[0].code[entry].name);
-}
-/* return equivalent photcode for given code */
-PhotCode *GetPhotcodeEquivbyCode (int code) {
-  
-  int entry, equiv;
-  
-  if (code < 0) return (NULL);
-  if (code > 0x10000) return (NULL);
-
-  entry = photcodes[0].hashcode[code];
-  if (entry == -1) return (NULL);
-
-  if (photcodes[0].code[entry].equiv == 0) return (NULL);
-  equiv = photcodes[0].hashcode[photcodes[0].code[entry].equiv];
-
-  if (equiv == -1) return (NULL);
-  return (&photcodes[0].code[equiv]);
-}
-/* return equivalent photcode.code for given code */
-int GetPhotcodeEquivCodebyCode (int code) {
-  
-  int entry;
-  
-  if (code < 0) return (0);
-  if (code > 0x10000) return (0);
-
-  entry = photcodes[0].hashcode[code];
-  if (entry == -1) return (0);
-  return (photcodes[0].code[entry].equiv);
-}
-
-int GetPhotcodeNsec (int code) {
-  
-  int Nsec;
-  
-  if (code < 0) return (-1);
-  if (code > 0x10000) return (-1);
-
-  Nsec = photcodes[0].hashNsec[code];
-  return (Nsec);
-}
-
-/* Nsec of 0 is PRI */
-PhotCode *GetPhotcodebyNsec (int Nsec) {
-  
-  if (Nsec > photcodes[0].Nsecfilt) return (NULL);
-  if (Nsec < 0) return (NULL);
-  
-  return (&photcodes[0].code[Nseclist[Nsec]]);
-}
-
-int GetPhotcodeNsecfilt () {
-  return (photcodes[0].Nsecfilt);
-}
-
-/* ALLOCATE and return list of all photcodes
-   with photcode.equiv == code */
-int *GetPhotcodeEquivList (int code, int *nlist) {
-
-  int i, Nlist;
-  int *list;
-
-  ALLOCATE (list, int, MAX (1, photcodes[0].Ncode));
-  Nlist = 0;
-  for (i = 0; i < photcodes[0].Ncode; i++) {
-    if (photcodes[0].code[i].equiv != code) continue;
-    list[Nlist] = photcodes[0].code[i].code;
-    Nlist ++;
-  }
-  REALLOCATE (list, int, MAX (1, Nlist));
-
-  *nlist = Nlist;
-  return (list);
-}
-
-/**** conversion to INTERNAL vs TABLE types makes the iPhot versions irrelevant ****/
-# if (0) 
-/******** photometry conversions *********/
-double PhotInst (Measure *measure) {
-
-  short Mi;
-  double M;
-
-  Mi = iPhotInst (measure);
-  M = 0.001*Mi;
-  return (M);
-}
-
-/****/
-double PhotCat (Measure *measure) {
-
-  short Mi;
-  double M;
-
-  Mi = iPhotCat (measure);
-  M = 0.001*Mi;
-  return (M);
-}
-
-/****/
-double PhotSys (Measure *measure, Average *average, SecFilt *secfilt) {
-
-  short Mi;
-  double M;
-
-  Mi = iPhotSys (measure, average, secfilt);
-  M = 0.001*Mi;
-  return (M);
-}
-
-/****/
-double PhotRel (Measure *measure, Average *average, SecFilt *secfilt) {
-
-  short Mi;
-  double M;
-
-  Mi = iPhotRel (measure, average, secfilt);
-  M = 0.001*Mi;
-  return (M);
-}
-
-/****/
-double PhotCal (Measure *thisone, Average *average, SecFilt *secfilt, Measure *measure, PhotCode *code) {
-
-  short Mi;
-  double M;
-
-  Mi = iPhotCal (thisone, average, secfilt, measure, code);
-  M = 0.001*Mi;
-  return (M);
-}
-
-/****/
-double PhotRef (PhotCode *code, Average *average, SecFilt *secfilt, Measure *measure) {
-
-  short Mi;
-  double M;
-
-  Mi = iPhotRef (code, average, secfilt, measure);
-  M = 0.001*Mi;
-  return (M);
-}
-
-/****/
-double PhotAve (PhotCode *code, Average *average, SecFilt *secfilt) {
-
-  short Mi;
-  double M;
-
-  Mi = iPhotAve (code, average, secfilt);
-  M = 0.001*Mi;
-  return (M);
-}
-
-/****/
-double PhotdM (PhotCode *code, Average *average, SecFilt *secfilt) {
-
-  short Mi;
-  double M;
-
-  Mi = iPhotdM (code, average, secfilt);
-  M = 0.001*Mi;
-  return (M);
-}
-
-/****/
-double PhotXm (PhotCode *code, Average *average, SecFilt *secfilt) {
-
-  int Mi;
-  double Xm;
-
-  Mi = iPhotXm (code, average, secfilt);
-  Xm = (Mi == NO_MAG) ? -1.0 : pow (10.0, 0.01*Mi);
-  return (Xm);
-}
-
-# endif 
-
-/******** internal photometry conversions (keeps values in short int millimags) *********/
-float PhotInst (Measure *measure) {
-
-  int Np;
-  float M;
-
-  Np = photcodes[0].hashcode[measure[0].source];
-  if (Np == -1) return (NO_MAG_PS);
-
-  if (photcodes[0].code[Np].type == PHOT_REF) {
-    M = measure[0].M_PS;
-    return (M);
-  }
-
-  M = measure[0].M_PS - measure[0].dt_PS - ZERO_POINT;
-	  
-  return (M);
-
-}
-
-float PhotCat (Measure *measure) {
-
-  int Np;
-  float Mcat;
-  PhotCode *code;
-
-  Np = photcodes[0].hashcode[measure[0].source];
-  if (Np == -1) return (NO_MAG_PS);
-
-  if (photcodes[0].code[Np].type == PHOT_REF) {
-    Mcat = measure[0].M_PS;
-    return (Mcat);
-  }
-  code = &photcodes[0].code[Np];
-  Mcat = measure[0].M_PS - ZERO_POINT + code[0].K*(measure[0].airmass_PS - 1.000) + F_PS*code[0].C;
-  
-  return (Mcat);
-}
-
-float PhotSys (Measure *measure, Average *average, SecFilt *secfilt) {
-
-  int i, Np;
-  float Mcat, Mcol, Msys, mc, Mc;
-  PhotCode *code;
-
-  Np = photcodes[0].hashcode[measure[0].source];
-  if (Np == -1) return (NO_MAG_PS);
-
-  if (photcodes[0].code[Np].type == PHOT_REF) {
-    Msys = measure[0].M_PS;
-    return (Msys);
-  }
-  code = &photcodes[0].code[Np];
-  Mcat = measure[0].M_PS - ZERO_POINT + code[0].K*(measure[0].airmass_PS - 1.000) + F_PS*code[0].C;
-
-  /* for DEP, color must be made of PRI/SEC */
-  mc = iPhotColor (average, secfilt, NULL, code);
-  if (mc == NO_MAG_PS) return (Mcat);
-  mc = mc - F_PS*code[0].dX;
-
-  Mc = mc;
-  Mcol = 0;
-  for (i = 0; i < code[0].Nc; i++) {
-    Mcol += code[0].X[i]*Mc;
-    Mc *= mc;
-  }
-  Msys = Mcat + Mcol;
-  return (Msys);
-}
-
-float PhotRel (Measure *measure, Average *average, SecFilt *secfilt) {
-
-  int i, Np;
-  float Mcat, Mcol, Mrel, mc, Mc;
-  PhotCode *code;
-
-  Np = photcodes[0].hashcode[measure[0].source];
-  if (Np == -1) return (NO_MAG_PS);
-
-  if (photcodes[0].code[Np].type == PHOT_REF) {
-    Mcat = measure[0].M_PS;
-    return (Mcat);
-  }
-  code = &photcodes[0].code[Np];
-  Mrel = measure[0].M_PS - ZERO_POINT + code[0].K*(measure[0].airmass_PS - 1.000) + F_PS*code[0].C - measure[0].Mcal_PS;
-
-  /* for DEP, color must be made of PRI/SEC */
-  mc = iPhotColor (average, secfilt, NULL, code);
-  if (mc == NO_MAG_PS) return (Mrel);
-  mc = mc - F_PS*code[0].dX;
-
-  Mc = mc;
-  Mcol = 0;
-  for (i = 0; i < code[0].Nc; i++) {
-    Mcol += code[0].X[i]*Mc;
-    Mc *= mc;    /* the 0.001 is needed for higher order terms to keep the units mag = mag^n */
-  }
-  Mrel += Mcol;
-  return (Mrel);
-}
-
-/* return calibrated magnitude from measure for given photcode */
-float PhotCal (Measure *thisone, Average *average, SecFilt *secfilt, Measure *measure, PhotCode *code) {
-
-  int i, Np; 
-  float Mcal, Mrel, Mcol, mc, Mc;
-
-  /* code must be the matching PRI/SEC code for this measurement or an equivalent ALT */
-  Np = photcodes[0].hashcode[thisone[0].source];
-  if (Np == -1) {
-    return (NO_MAG_PS);
-  }
-
-  if (photcodes[0].code[Np].type == PHOT_REF) {
-    Mrel = thisone[0].M_PS;
-    return (Mrel);
-  }
-  if (code[0].code != photcodes[0].code[Np].equiv) {
-    return (NO_MAG_PS);
-  }
-
-  Mcal = PhotRel (thisone, average, secfilt) + F_PS*code[0].C;
-
-  mc = iPhotColor (average, secfilt, measure, code);
-  if (mc == NO_MAG_PS) return (Mcal);
-  mc = mc - F_PS*code[0].dX;
-
-  Mc = mc;
-  Mcol = 0;
-  for (i = 0; i < code[0].Nc; i++) {
-    Mcol += code[0].X[i]*Mc;
-    Mc *= mc;
-  }
-  Mcal += Mcol;
-  return (Mcal);
-}
-
-/* color term may not use DEP magnitude */
-float iPhotColor (Average *average, SecFilt *secfilt, Measure *measure, PhotCode *code) {
-
-  int i, Ns1, Ns2, Ns;
-  float m1, m2, mc;
-  PhotCode *color;
-
-  m1 = m2 = NO_MAG_PS;
-
-  if (measure == NULL) {
-    Ns1 = photcodes[0].hashNsec[code[0].c1];
-    Ns2 = photcodes[0].hashNsec[code[0].c2];
-  
-    m1 = (Ns1 == -1) ? average[0].M : secfilt[Ns1].M_PS;
-    m2 = (Ns2 == -1) ? average[0].M : secfilt[Ns2].M_PS;
-    mc = ((m1 == NO_MAG_PS) || (m2 == NO_MAG_PS)) ? NO_MAG_PS : (m1 - m2);
-    return (mc);
-  }
-
-  /* find magnitude matching first color term */
-  color = GetPhotcodebyCode (code[0].c1);
-  if (color == NULL) return (NO_MAG_PS);
-  if (color[0].type == PHOT_REF) {
-    for (i = 0; (i < average[0].Nm) && (m1 == NO_MAG_PS); i++) {
-      if (measure[i].source == color[0].code) {
-	m1 = measure[i].M_PS;
-      }
-    }
-  } else {
-    Ns = photcodes[0].hashNsec[color[0].code];
-    m1 = (Ns == -1) ? average[0].M : secfilt[Ns].M_PS;
-  }	
-
-  /* find magnitude matching second color term */
-  color = GetPhotcodebyCode (code[0].c2);
-  if (color == NULL) return (NO_MAG_PS);
-  if (color[0].type == PHOT_REF) {
-    for (i = 0; (i < average[0].Nm) && (m2 == NO_MAG_PS); i++) {
-      if (measure[i].source == color[0].code) {
-	m2 = measure[i].M_PS;
-      }
-    }
-  } else {
-    Ns = photcodes[0].hashNsec[color[0].code];
-    m2 = (Ns == -1) ? average[0].M : secfilt[Ns].M_PS;
-  }	
-  mc = ((m1 == NO_MAG_PS) || (m2 == NO_MAG_PS)) ? NO_MAG_PS : (m1 - m2);
-  return (mc);
-}
-
-/* return calibrated magnitude from average/secfilt for given photcode */
-float PhotRef (PhotCode *code, Average *average, SecFilt *secfilt, Measure *measure) {
-
-  int i, Ns;
-  float Mave, Mref, Mcol, mc;
-  double Mc;
-
-  Ns = photcodes[0].hashNsec[code[0].code];
-  Mave = (Ns == -1) ? average[0].M : secfilt[Ns].M_PS;
-  Mref = Mave + F_PS*code[0].C;
-
-  mc = iPhotColor (average, secfilt, measure, code);
-  if (mc == NO_MAG_PS) return (Mref);
-  mc = mc - F_PS*code[0].dX;
-
-  Mc = mc;
-  Mcol = 0;
-  for (i = 0; i < code[0].Nc; i++) {
-    Mcol += code[0].X[i]*Mc;
-    Mc *= mc;    /* the 0.001 is needed for higher order terms to keep the units mag = mag^n */
-  }
-  Mref += Mcol;
-  return (Mref);
-}
-
-/***/
-float PhotAve (PhotCode *code, Average *average, SecFilt *secfilt) {
-
-  int Ns;
-  float Mave;
-
-  Ns = photcodes[0].hashNsec[code[0].code];
-  Mave = (Ns == -1) ? average[0].M : secfilt[Ns].M_PS;
-  return (Mave);
-}
-
-/*** note that this is NOT a wrapper around iPhotdM ***/
-float PhotdM (PhotCode *code, Average *average, SecFilt *secfilt) {
-
-  int Ns;
-  float dM;
-
-  Ns = photcodes[0].hashNsec[code[0].code];
-  dM  = (Ns == -1) ? average[0].dM : secfilt[Ns].dM_PS;
-  return (dM);
-}
-
-/*** note that this is NOT a wrapper around iPhotXm ***/
-float PhotXm (PhotCode *code, Average *average, SecFilt *secfilt) {
-
-  int Ns;
-  short Mi;
-  float Xm;
-
-  Ns = photcodes[0].hashNsec[code[0].code];
-  Mi = (Ns == -1) ? average[0].Xm : secfilt[Ns].Xm;
-  Xm = (Mi == NO_MAG_PS) ? -1.0 : pow (10.0, 0.01*Mi);
-  return (Xm);
-}
-
-/* given a photcode pair c1 & c2, return the color of this star (NaN if not found) */
-int PhotColor (Average *average, SecFilt *secfilt, Measure *measure, int c1, int c2, double *color) {
-
-  int i, Ns;
-  double M1, M2, dM;
-  PhotCode *code;
-  
-  code = GetPhotcodebyCode (c1);
-  if (code == NULL) return (FALSE);
-  if (code[0].type == PHOT_REF) {
-    for (i = 0; i < average[0].Nm; i++) {
-      if (measure[i].source == c1) {
-	M1 = measure[i].M_PS;
-	goto filter1;
-      }
-    }	
-    return (FALSE);
-  } else {
-    Ns = photcodes[0].hashNsec[code[0].code];
-    M1 = (Ns == -1) ? average[0].M : secfilt[Ns].M_PS;
-  }	
-
-filter1:
-  code = GetPhotcodebyCode (c2);
-  if (code == NULL) return (FALSE);
-  if (code[0].type == PHOT_REF) {
-    for (i = 0; i < average[0].Nm; i++) {
-      if (measure[i].source == c2) {
-	M2 = measure[i].M_PS;
-	goto filter2;
-      }
-    }	
-    return (FALSE);
-  } else {
-    Ns = photcodes[0].hashNsec[code[0].code];
-    M2 = (Ns == -1) ? average[0].M : secfilt[Ns].M_PS;
-  }	
-  
-filter2:
-
-  dM = M1 - M2;
-  *color = dM;
-  
-  return (TRUE);
-}
-
-/* photcode table should have the following format: 
-
-# code name     type  zero  airmass  offset  c1 c2  slope  <color>  primary
-1    B        pri   24.0  0.15     -       -  -   -      -        -
-2    B        pri   24.0  0.15     -       -  -   -      -        -
-3    B1       sec   22.5  0.18     0.15    1  2   0.10   0.50     1
-1000 USNO_B   ref   -     -        -       -  -   -      -        -
-
-*/
-
-
-/*
-  Nc1 = photcodes[0].code[Np].c1;
-  Ns1 = photcodes[0].hashNsec[Nc1];
-
-  Nc2 = photcodes[0].code[Np].c2;
-  Ns2 = photcodes[0].hashNsec[Nc2];
-
-  Xlam = photcodes[0].code[Np].X[0];
-  Klam = photcodes[0].code[Np].K;
-  
-  m1 = (Ns1 == -1) ? average[0].M : secfilt[Ns1].M;
-  m2 = (Ns2 == -1) ? average[0].M : secfilt[Ns2].M;
-*/
Index: trunk/Ohana/src/libdvo/src/LoadPhotcodesFITS.c
===================================================================
--- trunk/Ohana/src/libdvo/src/LoadPhotcodesFITS.c	(revision 12332)
+++ trunk/Ohana/src/libdvo/src/LoadPhotcodesFITS.c	(revision 12332)
@@ -0,0 +1,110 @@
+# include <dvo.h>
+
+/* this is a read-only function to load the FITS photcode file into the internal photcode table */
+/* locking is used to avoid collisions with programs trying to update the photcodes values */
+/* XXX better distinction between NOT FOUND and FAILURE */
+int LoadPhotcodesFITS (char *filename) {
+
+  PhotCodeData *table = NULL;
+  PhotCode *photcode;
+  FITS_DB db;
+
+  int i, code, Ncode, Nsec, Nsecfilt;
+
+  /* XXX choose more sensible lock timeouts! */
+  db.lockstate = LCK_SOFT;
+  db.timeout   = 10.0;
+  gfits_db_init (&db);
+
+  /* does this mean the db is empty, non-existent, or has access errors? */
+  // XXX we need better error handling here
+  if (!gfits_db_lock (&db, filename)) {
+    // fprintf (stderr, "ERROR: failure to lock db\n");
+    gfits_db_close (&db);
+    return FALSE;
+  }
+  if (db.dbstate == LCK_EMPTY) {
+    // fprintf (stderr, "ERROR: db is empty\n");
+    gfits_db_close (&db);
+    return FALSE;
+  } 
+  if (!gfits_db_load (&db)) {
+    // fprintf (stderr, "ERROR: failure to load db\n");
+    gfits_db_close (&db);
+    return FALSE;
+  }
+  gfits_db_close (&db);
+
+  /* convert FITS format data to internal format (just byteswaps) */
+  photcode = gfits_table_get_PhotCode (&db.ftable, &Ncode, &db.swapped);
+
+  table = GetPhotcodeTable ();
+  if (table[0].code != NULL) free (table[0].code);
+  /* we are using a 16-bit int for the photcodes, so these indexes can be fixed-length */
+  /* XXX if we need to go with a larger photcode, we'll need to use a sequenced index and a
+     binary search to get to a given value (0x100000000 ints would take quite a few
+     bytes...) */
+  for (i = 0; i < 0x10000; i++) {
+    table[0].hashcode[i] = -1;
+    table[0].hashNsec[i] = -1;
+    table[0].codeNsec[i] = -1;
+  }
+
+  /* set up photcode indexes (see dvo_photcode_ops.c) */
+  Nsecfilt = 0;
+  for (i = 0; i < Ncode; i++) {
+    if (photcode[i].type == PHOT_ALT) continue; /* no hashcode for ALT codes */
+    if (table[0].hashcode[photcode[i].code] != -1) {
+      fprintf (stderr, "duplicate photcodes in file\n");
+      code = table[0].hashcode[photcode[i].code];
+      fprintf (stderr, "conflict between %s (%d) and %s (%d)\n",
+	       photcode[i].name, photcode[i].code, photcode[code].name, photcode[code].code);
+      free (photcode);
+      return FALSE;
+    }
+    table[0].hashcode[photcode[i].code] = i;
+    if (photcode[i].type == PHOT_SEC) {
+      table[0].hashNsec[photcode[i].code] = Nsecfilt;
+      table[0].codeNsec[Nsecfilt] = photcode[i].code;
+      Nsecfilt ++;
+    }
+  }
+
+  // validity check for references
+  // photcode.equiv of 0 means "undefined"
+  for (i = 0; i < Ncode; i++) {
+    if (photcode[i].type == PHOT_DEP) {
+      if (photcode[i].equiv == 0) continue;
+      Nsec = table[0].hashcode[photcode[i].equiv];
+      if ((Nsec >= Ncode) || (Nsec < 0)) {
+	fprintf (stderr, "reference for dependent photcode is not in photcodes\n");
+	free (photcode);
+	return FALSE;
+      }
+      if (photcode[Nsec].type != PHOT_SEC) {
+	fprintf (stderr, "reference for dependent photcode is not an average photcode\n");
+	free (photcode);
+	return FALSE;
+      }
+    }
+    if (photcode[i].type == PHOT_ALT) {
+      Nsec = table[0].hashcode[photcode[i].code];
+      if ((Nsec >= Ncode) || (Nsec < 0)) {
+	fprintf (stderr, "reference for alternate photcode is not in photcodes\n");
+	free (photcode);
+	return FALSE;
+      }
+      if (photcode[Nsec].type != PHOT_SEC) {
+	fprintf (stderr, "reference for alternate photcode is not an average photcode\n");
+	free (photcode);
+	return FALSE;
+      }
+    }
+  }
+
+  table[0].code     = photcode;
+  table[0].Ncode    = Ncode;
+  table[0].Nsecfilt = Nsecfilt;
+
+  return (TRUE);
+}
Index: trunk/Ohana/src/libdvo/src/LoadPhotcodesText.c
===================================================================
--- trunk/Ohana/src/libdvo/src/LoadPhotcodesText.c	(revision 12332)
+++ trunk/Ohana/src/libdvo/src/LoadPhotcodesText.c	(revision 12332)
@@ -0,0 +1,208 @@
+# include <dvo.h>
+
+/* load the text photcode table */
+int LoadPhotcodesText (char *filename) {
+  
+  /* XXX fix these */
+  PhotCodeData *table = NULL;
+  PhotCode *photcode;
+
+  FILE *f;
+  int i, Nsecfilt, Nsec, Ncode, NPHOTCODE, Nfield;
+  int code;
+  char *c;
+  char line[256];
+  char name[32], type[32], Zero[32], Airmass[32], Offset[32],
+    C1[32], C2[32], Slope[32], Color[32], Primary[32];
+  int c1, c2;
+
+  table = GetPhotcodeTable ();
+  if (table[0].code != NULL) free (table[0].code);
+  /* we are using a 16-bit int for the photcodes, so these indexes can be fixed-length */
+  /* XXX if we need to go with a larger photcode, we'll need to use a sequenced index and a
+     binary search to get to a given value (0x100000000 ints would take quite a few
+     bytes...) */
+  for (i = 0; i < 0x10000; i++) {
+    table[0].hashcode[i] = -1;
+    table[0].hashNsec[i] = -1;
+    table[0].codeNsec[i] = -1;
+  }
+
+  f = fopen (filename, "r");
+  if (f == (FILE *) NULL) {
+    table[0].Ncode    = 0;
+    table[0].Nsecfilt = 0;
+    table[0].code     = (PhotCode *) NULL;
+    return (FALSE);
+  }
+
+  Ncode = 0;
+  NPHOTCODE = 10;
+  ALLOCATE (photcode, PhotCode, NPHOTCODE);
+
+  while (scan_line (f, line) != EOF) {
+    for (c = line; isspace (*c); c++);
+    if (*c == '#') continue;
+    Nfield = sscanf (c, "%d %s %s %s %s %s %s %s %s %s %s", 
+		     &code, name, type, Zero, Airmass, Offset, C1, C2, Slope, Color, Primary);
+    if (Nfield != 11) { continue; }
+    
+    c1 = atof (C1);
+    c2 = atof (C2);
+    if (!strcmp (C1, "-")) { c1 = 0; }
+    if (!strcmp (C2, "-")) { c2 = 0; }
+
+    if (!code) {
+	fprintf (stderr, "photcode values may not be 0: fix %s\n", name);
+	return (FALSE);
+    }
+
+    photcode[Ncode].type = 0;
+    photcode[Ncode].code = code;
+    memset (photcode[Ncode].name, 0, 32);
+    strcpy (photcode[Ncode].name, name);
+    if (!strncasecmp (type, "pri", 3)) {
+      photcode[Ncode].type  = PHOT_SEC;
+      photcode[Ncode].C     = 1000*atof (Zero);
+      photcode[Ncode].K     = atof (Airmass);
+      photcode[Ncode].dC    = 1000*atof (Offset);
+      photcode[Ncode].dX    = 1000*atof (Color);
+      photcode[Ncode].c1    = c1;
+      photcode[Ncode].c2    = c2;
+      photcode[Ncode].equiv = atoi (Primary);
+      ParseColorTerms (Slope, photcode[Ncode].X, &photcode[Ncode].Nc);
+    }      
+    if (!strncasecmp (type, "sec", 3)) {
+      photcode[Ncode].type  = PHOT_SEC;
+      photcode[Ncode].C     = 1000*atof (Zero);
+      photcode[Ncode].K     = atof (Airmass);
+      photcode[Ncode].dC    = 1000*atof (Offset);
+      photcode[Ncode].dX    = 1000*atof (Color);
+      photcode[Ncode].c1    = c1;
+      photcode[Ncode].c2    = c2;
+      photcode[Ncode].equiv = atoi (Primary);
+      ParseColorTerms (Slope, photcode[Ncode].X, &photcode[Ncode].Nc);
+    }      
+    if (!strncasecmp (type, "dep", 3)) {
+      photcode[Ncode].type  = PHOT_DEP;
+      photcode[Ncode].C     = 1000*atof (Zero);    /* zero point in millimags */
+      photcode[Ncode].K     = atof (Airmass);      /* airmass coeff (millimag / millimag) */
+      photcode[Ncode].dC    = 1000*atof (Offset);  /* color ref z.p. (millimag) */
+      photcode[Ncode].dX    = 1000*atof (Color);   /* average color (millimag) */
+      photcode[Ncode].c1    = c1;
+      photcode[Ncode].c2    = c2;
+      photcode[Ncode].equiv = atoi (Primary);
+      ParseColorTerms (Slope, photcode[Ncode].X, &photcode[Ncode].Nc);
+    }      
+    if (!strncasecmp (type, "ref", 3)) {
+      photcode[Ncode].type  = PHOT_REF;
+      photcode[Ncode].C     = 0;
+      photcode[Ncode].K     = 0;
+      photcode[Ncode].dC    = 0;
+      photcode[Ncode].dX    = 0;
+      photcode[Ncode].c1    = 0;
+      photcode[Ncode].c2    = 0;
+      photcode[Ncode].equiv = atoi (Primary);
+      photcode[Ncode].X[0]  = 0;
+      photcode[Ncode].Nc    = 0;
+    }
+
+    /* alt photcodes are a little different: they have the SAME photcode as an existing
+       pri/sec photcode, but define an alternate transformation for that code */
+    if (!strncasecmp (type, "alt", 3)) {
+      photcode[Ncode].type  = PHOT_ALT;
+      photcode[Ncode].C     = 1000*atof (Zero);    /* zero point in millimags */
+      photcode[Ncode].K     = atof (Airmass);      /* airmass coeff (millimag / millimag) */
+      photcode[Ncode].dC    = 1000*atof (Offset);  /* color ref z.p. (millimag) */
+      photcode[Ncode].dX    = 1000*atof (Color);   /* average color (millimag) */
+      photcode[Ncode].c1    = c1;
+      photcode[Ncode].c2    = c2;
+      photcode[Ncode].equiv = atoi (Primary);
+      ParseColorTerms (Slope, photcode[Ncode].X, &photcode[Ncode].Nc);
+    }
+    if (!photcode[Ncode].type) {
+      fprintf (stderr, "error in Photfile: unknown type %s\n", type);
+    }
+
+    Ncode++;
+    if (Ncode == NPHOTCODE) {
+      NPHOTCODE += 10;
+      REALLOCATE (photcode, PhotCode, NPHOTCODE);
+    }
+  }
+  fclose (f);
+  
+  /* set up photcode indexes (see dvo_photcode_ops.c) */
+  Nsecfilt = 0;
+  for (i = 0; i < Ncode; i++) {
+    if (photcode[i].type == PHOT_ALT) continue; /* no hashcode for ALT codes */
+    if (table[0].hashcode[photcode[i].code] != -1) {
+      fprintf (stderr, "duplicate photcodes in file\n");
+      code = table[0].hashcode[photcode[i].code];
+      fprintf (stderr, "conflict between %s (%d) and %s (%d)\n",
+	       photcode[i].name, photcode[i].code, photcode[code].name, photcode[code].code);
+      free (photcode);
+      return (FALSE);
+    }
+    table[0].hashcode[photcode[i].code] = i;
+    if (photcode[i].type == PHOT_SEC) {
+      table[0].hashNsec[photcode[i].code] = Nsecfilt;
+      table[0].codeNsec[Nsecfilt] = photcode[i].code;
+      Nsecfilt ++;
+    }
+  }
+
+  // validity check for references
+  // photcode.equiv of 0 means "undefined"
+  for (i = 0; i < Ncode; i++) {
+    if (photcode[i].type == PHOT_DEP) {
+      if (photcode[i].equiv == 0) continue;
+      Nsec = table[0].hashcode[photcode[i].equiv];
+      if ((Nsec >= Ncode) || (Nsec < 0)) {
+	fprintf (stderr, "reference for dependent photcode is not a valid photcode\n");
+	free (photcode);
+	return (FALSE);
+      }
+      if (photcode[Nsec].type != PHOT_SEC) {
+	fprintf (stderr, "reference for dependent photcode is not an average photcode\n");
+	free (photcode);
+	return (FALSE);
+      }
+    }
+    if (photcode[i].type == PHOT_ALT) {
+      Nsec = table[0].hashcode[photcode[i].code];
+      if ((Nsec >= Ncode) || (Nsec < 0)) {
+	fprintf (stderr, "reference for alternate photcode is not in photcodes\n");
+	free (photcode);
+	return (FALSE);
+      }
+      if (photcode[Nsec].type != PHOT_SEC) {
+	fprintf (stderr, "reference for alternate photcode is not an average photcode\n");
+	free (photcode);
+	return (FALSE);
+      }
+    }
+  }
+  table[0].code     = photcode;
+  table[0].Ncode    = Ncode;
+  table[0].Nsecfilt = Nsecfilt;
+
+  return (TRUE);
+}
+
+# define NCTERMS 4
+void ParseColorTerms (char *terms, float *X, int *N) {
+
+  int i;
+  char *p;
+
+  p = terms;
+
+  for (i = 0; (p != NULL) && (i < NCTERMS); i++) {
+    X[i] = atof (p);
+    p = strchr (p, ',');
+    if (p == (char *) NULL) continue;
+    p ++;
+  }
+  *N = i;
+}
Index: trunk/Ohana/src/libdvo/src/SavePhotcodesFITS.c
===================================================================
--- trunk/Ohana/src/libdvo/src/SavePhotcodesFITS.c	(revision 12332)
+++ trunk/Ohana/src/libdvo/src/SavePhotcodesFITS.c	(revision 12332)
@@ -0,0 +1,41 @@
+# include <dvo.h>
+
+/* this function saves the FITS photcode file into the internal photcode table */
+/* locking is used to avoid collisions with programs trying to update the photcodes values */
+/* XXX better distinction between NOT FOUND and FAILURE */
+int SavePhotcodesFITS (char *filename) {
+
+  PhotCodeData *table = NULL;
+  PhotCode *photcode;
+  FITS_DB db;
+
+  int i, code, Ncode, Nsec;
+
+  table = GetPhotcodeTable ();
+  if (table == NULL) {
+    fprintf (stderr, "ERROR: no internal photcode table is defined\n");
+    return FALSE;
+  }
+
+  /* XXX choose more sensible lock timeouts! */
+  db.lockstate = LCK_XCLD;
+  db.timeout   = 10.0;
+  gfits_db_init (&db);
+
+  /* does this mean the db is empty, non-existent, or has access errors? */
+  if (!gfits_db_lock (&db, filename)) {
+    fprintf (stderr, "ERROR: failure to lock db, cannot save photcode table to %s\n", filename);
+    gfits_db_close (&db);
+    return FALSE;
+  }
+
+  /* convert FITS format data to internal format (just byteswaps) */
+  gfits_db_create (&db);
+  gfits_table_set_PhotCode (&db.ftable, table[0].code, table[0].Ncode);
+  gfits_db_save (&db);
+  gfits_db_close (&db);
+
+  /* gfits_table_set_PhotCode performs the needed byte swap.  swap back */
+  gfits_convert_PhotCode (table[0].code, sizeof(PhotCode), table[0].Ncode);
+  return TRUE;
+}
Index: trunk/Ohana/src/libdvo/src/SavePhotcodesText.c
===================================================================
--- trunk/Ohana/src/libdvo/src/SavePhotcodesText.c	(revision 12332)
+++ trunk/Ohana/src/libdvo/src/SavePhotcodesText.c	(revision 12332)
@@ -0,0 +1,96 @@
+# include <dvo.h>
+# define SCALE 0.001
+
+static char *PHOT_PRI_NAME = "pri";
+static char *PHOT_SEC_NAME = "sec";
+static char *PHOT_ALT_NAME = "alt";
+static char *PHOT_REF_NAME = "ref";
+static char *PHOT_DEP_NAME = "dep";
+
+/* this function saves the FITS photcode file into the internal photcode table */
+/* locking is used to avoid collisions with programs trying to update the photcodes values */
+/* XXX better distinction between NOT FOUND and FAILURE */
+int SavePhotcodesText (char *filename) {
+
+  PhotCodeData *table = NULL;
+  PhotCode *photcode;
+  struct stat filestat;
+  char *type;
+  int i, j, status;
+  FILE *f;
+
+  table = GetPhotcodeTable ();
+  if (table == NULL) {
+    fprintf (stderr, "ERROR: no internal photcode table is defined\n");
+    return FALSE;
+  }
+
+  /* check if file exists */
+  status = stat (filename, &filestat);
+  if (status == -1) {
+    if (errno != ENOENT) {
+      fprintf (stderr, "ERROR: problem accessing output path for%s\n", filename);
+      return FALSE;
+    }
+  } else {
+    make_backup (filename);
+  } 
+
+  f = fopen (filename, "w");
+  if (f == NULL) {
+    fprintf (stderr, "ERROR: problem creating photcode file %s\n", filename);
+    return FALSE;
+  }
+
+  for (i = 0; i < table[0].Ncode; i++) {
+    switch (table[0].code[i].type) {
+      case PHOT_SEC:
+	type = PHOT_SEC_NAME;
+	break;
+      case PHOT_ALT:
+	type = PHOT_ALT_NAME;
+	break;
+      case PHOT_REF:
+	type = PHOT_REF_NAME;
+	break;
+      case PHOT_DEP:
+	type = PHOT_DEP_NAME;
+	break;
+      default:
+	fprintf (stderr, "ERROR: problem with photcode type for %s\n", GetPhotcodeNamebyCode(table[0].code[i].code));
+	return FALSE;
+    }
+
+    fprintf (f, "  %-5d %-18s  %4s  %6.3f %6.3f %5.3f ",
+	     table[0].code[i].code,
+	     GetPhotcodeNamebyCode (table[0].code[i].code),
+	     type,
+	     table[0].code[i].C*SCALE, 
+	     table[0].code[i].K*SCALE, 
+	     table[0].code[i].dC*SCALE);
+
+    PrintPhotcodeNamebyCode (f, "%5d ", table[0].code[i].c1);
+    PrintPhotcodeNamebyCode (f, "%5d ", table[0].code[i].c2);
+
+    for (j = 0; j < table[0].code[i].Nc - 1; j++) {
+      fprintf (f, " %f,", table[0].code[i].X[j]);
+    }
+    fprintf (f, "%f %f ", table[0].code[i].X[j], table[0].code[i].dX);
+    PrintPhotcodeNamebyCode (f, "%5d ", table[0].code[i].equiv);
+    fprintf (f, "\n");
+  }
+  fclose (f);
+  return TRUE;
+}
+
+void PrintPhotcodeNamebyCode (FILE *f, char *format, int code) {
+
+  char *name;
+  
+  name = GetPhotcodeNamebyCode (code);
+  if (name == NULL) {
+    fprintf (f, "    - ");
+  } else {
+    fprintf (f, format, code);
+  }
+}
Index: trunk/Ohana/src/libdvo/src/coordops.c
===================================================================
--- trunk/Ohana/src/libdvo/src/coordops.c	(revision 11991)
+++ trunk/Ohana/src/libdvo/src/coordops.c	(revision 12332)
@@ -7,29 +7,7 @@
 }
 
-int XY_to_RD (double *ra, double *dec, double x, double y, Coords *coords) {
-
-  int Zenith1, Zenith2, Zenithal, Polynomial, Cartesian, PseudoCyl;
-  char *type;
-  double L, M, X, Y, T, Z, Z2;
-  double R, sphi, cphi, stht, ctht;
-  double alpha, delta, salp, calp, sdel, sdp, cdp;
-  
-  *ra  = 0;
-  *dec = 0;
-  stht = ctht = 1;
-  type = &coords[0].ctype[4];
-  
-  /* PLY is equiv to LIN with higher order terms
-     ZPL is equiv to ZEA with higher order terms
-     DIS is equiv to TAN with higher order terms
-     WRP is equiv to PLY, with implied mosaic */
-
-  Polynomial = !strcmp(type, "-PLY") || !strcmp(type, "-DIS") || !strcmp(type, "-WRP") || !strcmp(type, "-ZPL");
-  Cartesian  = !strcmp(type, "-LIN") || !strcmp(type, "-PLY") || !strcmp(type, "-WRP") || !strcmp(&coords[0].ctype[0], "GENE");
-  PseudoCyl  = !strcmp(type, "-AIT") || !strcmp(type, "-GLS") || !strcmp(type, "-PAR");
-  Zenith1    = !strcmp(type, "-DIS") || !strcmp(type, "-TAN") || !strcmp(type, "-STG");
-  Zenith2    = !strcmp(type, "-SIN") || !strcmp(&coords[0].ctype[0], "MM");
-  Zenithal   = !strcmp(type, "-ZEA") || !strcmp(type, "-ZPL") || Zenith1 || Zenith2;
-  if (!Zenithal && !Cartesian && !PseudoCyl) return (FALSE);
+int XY_to_LM (double *L, double *M, double x, double y, Coords *coords) {
+
+  double X, Y;
 
   /** convert pixel coordinates to cartesian system **/
@@ -37,24 +15,41 @@
   Y = coords[0].cdelt2*(y - coords[0].crpix2);
 
-  L = (X*coords[0].pc1_1 + Y*coords[0].pc1_2);
-  M = (X*coords[0].pc2_1 + Y*coords[0].pc2_2);
+  *L = (X*coords[0].pc1_1 + Y*coords[0].pc1_2);
+  *M = (X*coords[0].pc2_1 + Y*coords[0].pc2_2);
 
   /** extra polynomial terms **/
   if (coords[0].Npolyterms > 1) {
-    L += X*X*coords[0].polyterms[0][0] + X*Y*coords[0].polyterms[1][0] + Y*Y*coords[0].polyterms[2][0];
-    M += X*X*coords[0].polyterms[0][1] + X*Y*coords[0].polyterms[1][1] + Y*Y*coords[0].polyterms[2][1];
+    *L += X*X*coords[0].polyterms[0][0] + X*Y*coords[0].polyterms[1][0] + Y*Y*coords[0].polyterms[2][0];
+    *M += X*X*coords[0].polyterms[0][1] + X*Y*coords[0].polyterms[1][1] + Y*Y*coords[0].polyterms[2][1];
   }
   if (coords[0].Npolyterms > 2) {
-    L += X*X*X*coords[0].polyterms[3][0] + X*X*Y*coords[0].polyterms[4][0] + X*Y*Y*coords[0].polyterms[5][0] + Y*Y*Y*coords[0].polyterms[6][0];
-    M += X*X*X*coords[0].polyterms[3][1] + X*X*Y*coords[0].polyterms[4][1] + X*Y*Y*coords[0].polyterms[5][1] + Y*Y*Y*coords[0].polyterms[6][1];
-  }
-
-  /**** Locally Cartesian Projections ****/
-  if (Cartesian) {
+    *L += X*X*X*coords[0].polyterms[3][0] + X*X*Y*coords[0].polyterms[4][0] + X*Y*Y*coords[0].polyterms[5][0] + Y*Y*Y*coords[0].polyterms[6][0];
+    *M += X*X*X*coords[0].polyterms[3][1] + X*X*Y*coords[0].polyterms[4][1] + X*Y*Y*coords[0].polyterms[5][1] + Y*Y*Y*coords[0].polyterms[6][1];
+  }
+
+  return (TRUE);
+}
+
+int LM_to_RD (double *ra, double *dec, double L, double M, Coords *coords) {
+
+  OhanaProjection proj;
+  OhanaProjectionMode mode;
+  double R, T, Z, Z2, sphi, cphi, stht, ctht;
+  double alpha, delta, salp, calp, sdel, sdp, cdp;
+
+  proj = GetProjection (coords[0].ctype);
+  mode = GetProjectionMode (proj);
+  if (proj == PROJ_NONE) return (FALSE);
+  if (proj == PROJ_MODE_NONE) return (FALSE);
+
+  stht = ctht = 1;
+
+  /** Locally Cartesian Projections **/
+  if (mode == PROJ_MODE_CARTESIAN) {
     *ra  = L + coords[0].crval1;
     *dec = M + coords[0].crval2;
 
     /* mosaic astrometry : WRP is chip astrometry; apply mosaic (DIS) term */
-    if (!strcmp(type, "-WRP")) {
+    if (proj == PROJ_WRP) {
       if (mosaic == NULL) return (FALSE);
       XY_to_RD (ra, dec, L + coords[0].crval1, M + coords[0].crval2, mosaic);
@@ -63,6 +58,6 @@
   }
   
-  /**** Zenithal Projections ****/
-  if (Zenithal) {
+  /** Zenithal Projections **/
+  if (mode == PROJ_MODE_ZENITHAL) {
     R = hypot (L,M);
     if ((L == 0) && (M == 0)) {
@@ -74,29 +69,36 @@
     }
 
-    /* this is wrong : STG is not TAN - need to put in correct relationships.  but is a close approx */
-    if (Zenith1) {
-      if (R == 0) {
-	stht = 1.0;
-	ctht = 0.0;
-      } else {
-	T = DEG_RAD / R;
-	stht =   T / sqrt ( 1.0 + T*T);
-	ctht = 1.0 / sqrt ( 1.0 + T*T);
-      }
-    }
-    if (Zenith2) {
-      ctht = RAD_DEG * R;
-      stht = sqrt (1 - ctht*ctht);
-    }
-    if (!strcmp(type, "-ZEA") || !strcmp(type, "-ZPL")) {
-      if (R > 2*DEG_RAD) {
-	*ra = L;
-	*dec = M;
+    switch (proj) {
+      case PROJ_TAN:
+	if (R == 0) {
+	  stht = 1.0;
+	  ctht = 0.0;
+	} else {
+	  T = DEG_RAD / R;
+	  stht =   T / sqrt ( 1.0 + T*T);
+	  ctht = 1.0 / sqrt ( 1.0 + T*T);
+	}
+	break;
+      case PROJ_STG:
+	stht = (4 - RAD_DEG*R) / (4 + RAD_DEG*R);
+	ctht = sqrt (1 - stht*stht);
+	break;
+      case PROJ_SIN:
+	ctht = RAD_DEG * R;
+	stht = sqrt (1 - ctht*ctht);
+	break;
+      case PROJ_ZEA:
+      case PROJ_ZPL:
+	if (R > 2*DEG_RAD) {
+	  *ra = L;
+	  *dec = M;
+	  return (FALSE);
+	}
+	stht = 1 - 0.5*SQ(R*RAD_DEG);
+	ctht = sqrt (1 - stht*stht);
+	break;
+      default:
 	return (FALSE);
-      }
-      stht = 1 - 0.5*SQ(R*RAD_DEG);
-      ctht = sqrt (1 - stht*stht);
-    }
-
+    }
     sdp  = sin(RAD_DEG*coords[0].crval2);
     cdp  = cos(RAD_DEG*coords[0].crval2);
@@ -119,6 +121,7 @@
   
   /**** Other Conventional Projections ****/
-  if (PseudoCyl) {
-    if (!strcmp(type, "-AIT")) {
+  if (mode == PROJ_MODE_PSEUDOCYL) {
+    switch (proj) {
+      case PROJ_AIT:
       Z2 = (1.0 - SQ(RAD_DEG*0.25*L) - SQ(RAD_DEG*0.5*M));
       if (Z2 < 0) return (FALSE);
@@ -126,21 +129,21 @@
       alpha = 2.0 * DEG_RAD * atan2 (RAD_DEG*0.5*Z*L, 2.0*Z2 - 1.0);
       delta = DEG_RAD * asin (RAD_DEG*M*Z);
-      *ra  = alpha + coords[0].crval1;
-      *dec = delta + coords[0].crval2;
-    }
-    if (!strcmp(type, "-GLS")) {
-      /* L,M in degrees, alpha,delta in degrees */
-      alpha = L / cos (RAD_DEG * M);
-      delta = M;
-      *ra  = alpha + coords[0].crval1;
-      *dec = delta + coords[0].crval2;
-    }
-    if (!strcmp(type, "-PAR")) {
-      /* L,M in degrees, alpha,delta in degrees */
-      alpha = L / (1.0 - SQ(2.0*M/180));
-      delta = 3 * DEG_RAD * asin (M/180.0);
-      *ra  = alpha + coords[0].crval1;
-      *dec = delta + coords[0].crval2;
-    }
+      break;
+      
+      case PROJ_GLS:
+	/* L,M in degrees, alpha,delta in degrees */
+	alpha = L / cos (RAD_DEG * M);
+	delta = M;
+	break;
+      case PROJ_PAR:
+	/* L,M in degrees, alpha,delta in degrees */
+	alpha = L / (1.0 - SQ(2.0*M/180));
+	delta = 3 * DEG_RAD * asin (M/180.0);
+	break;
+      default:
+	return (FALSE);
+    }
+    *ra  = alpha + coords[0].crval1;
+    *dec = delta + coords[0].crval2;
 
     /* rationalize ra range 0 - 360.0 */
@@ -153,44 +156,37 @@
 }
 
-int RD_to_XY (double *x, double *y, double ra, double dec, Coords *coords) {
-
-  char *type;
-  int i, status, Polynomial, Zenith1, Zenith2, Zenithal, Cartesian, PseudoCyl;
+int RD_to_LM (double *L, double *M, double ra, double dec, Coords *coords) {
+
   double phi, theta;
-  double determ;
-  double X, Y, L, M, Lo, Mo, dL, dM;
+  double Lo, Mo;
   double sphi, cphi, stht;
   double salp, calp, sdel, cdel, sdp, cdp;
   double P, A, Rc;
-
-  status = TRUE;
-  *x = 0;
-  *y = 0;
-  type = &coords[0].ctype[4];
-  L = M = 0;
-
-  Polynomial = !strcmp(type, "-PLY") || !strcmp(type, "-DIS") || !strcmp(type, "-WRP") || !strcmp(type, "-ZPL");
-  Cartesian  = !strcmp(type, "-LIN") || !strcmp(type, "-PLY") || !strcmp(type, "-WRP") || !strcmp(&coords[0].ctype[0], "GENE");
-  PseudoCyl  = !strcmp(type, "-AIT") || !strcmp(type, "-GLS") || !strcmp(type, "-PAR");
-  Zenith1    = !strcmp(type, "-DIS") || !strcmp(type, "-TAN") || !strcmp(type, "-STG");
-  Zenith2    = !strcmp(type, "-SIN") || !strcmp(&coords[0].ctype[0], "MM");
-  Zenithal   = !strcmp(type, "-ZEA") || !strcmp(type, "-ZPL") || Zenith1 || Zenith2;
-  if (!Zenithal && !Cartesian && !PseudoCyl) return (FALSE);
+  OhanaProjection proj;
+  OhanaProjectionMode mode;
+
+  *L = *M = 0;
+
+  proj = GetProjection (coords[0].ctype);
+  mode = GetProjectionMode (proj);
+  if (proj == PROJ_NONE) return (FALSE);
+  if (proj == PROJ_MODE_NONE) return (FALSE);
 
   /**** Locally Cartesian Projections ****/
-  if (Cartesian) {
-    if (!strcmp(type, "-WRP")) {
+  if (mode == PROJ_MODE_CARTESIAN) {
+    if (proj == PROJ_WRP) {
       if (mosaic == NULL) return (FALSE);
       RD_to_XY (&Lo, &Mo, ra, dec, mosaic);
-      L = (Lo - coords[0].crval1);
-      M = (Mo - coords[0].crval2);
-    } else {
-      L = (ra  - coords[0].crval1);
-      M = (dec - coords[0].crval2);
-    }
+      *L = (Lo - coords[0].crval1);
+      *M = (Mo - coords[0].crval2);
+      return (TRUE);
+    }
+    *L = (ra  - coords[0].crval1);
+    *M = (dec - coords[0].crval2);
+    return (TRUE);
   }
   
   /**** Zenithal Projections ****/
-  if (Zenithal)  {
+  if (mode == PROJ_MODE_ZENITHAL) {
     sdp  = sin(RAD_DEG*coords[0].crval2);
     cdp  = cos(RAD_DEG*coords[0].crval2);
@@ -203,50 +199,72 @@
     sphi = cdel*salp;                   /* = cos(theta)*sin(phi) */
     cphi = cdel*sdp*calp - sdel*cdp;    /* = cos(theta)*cos(phi) */
-    if (stht < 0) status = FALSE;
-
-    if (Zenith1) {
-      L =  DEG_RAD * sphi / stht;
-      M = -DEG_RAD * cphi / stht;
-    }
-    if (Zenith2) {
-      L =  DEG_RAD * sphi;
-      M = -DEG_RAD * cphi;
-    }
-    if (!strcmp(type, "-ZEA") || !strcmp(type, "-ZPL")) {
-      Rc = DEG_RAD * M_SQRT2 / sqrt (1 + stht);
-      L =  Rc * sphi;
-      M = -Rc * cphi;
-      status = TRUE;
-    }
+    if (stht < 0) return (FALSE);
+
+    switch (proj) {
+      case PROJ_TAN:
+      case PROJ_DIS:
+	*L =  DEG_RAD * sphi / stht;
+	*M = -DEG_RAD * cphi / stht;
+	return (TRUE);
+      case PROJ_SIN:
+	*L =  DEG_RAD * sphi;
+	*M = -DEG_RAD * cphi;
+	return (TRUE);
+      case PROJ_ZEA:
+      case PROJ_ZPL:
+	Rc = DEG_RAD * M_SQRT2 / sqrt (1 + stht);
+	*L =  Rc * sphi;
+	*M = -Rc * cphi;
+	return (TRUE);
+      default:
+	return (FALSE);
+    }
+    return (FALSE);
   }
 
   /**** Other Standard Projections ****/
-  if (PseudoCyl) {
-    if (!strcmp(type, "-AIT")) {
-      phi = RAD_DEG*(ra - coords[0].crval1);
-      theta = RAD_DEG*(dec - coords[0].crval2);
-      P = 1.0 + cos (theta) * cos (0.5*phi);
-      if (P != 0.0) {
+  if (mode == PROJ_MODE_PSEUDOCYL) {
+    switch (proj) {
+      case PROJ_AIT:
+	phi = RAD_DEG*(ra - coords[0].crval1);
+	theta = RAD_DEG*(dec - coords[0].crval2);
+	P = 1.0 + cos (theta) * cos (0.5*phi);
+	if (P == 0.0) {
+	  *L =  0.0;
+	  *M =  0.0;
+	  return (TRUE);
+	} 
 	A =  DEG_RAD * sqrt (2.0 / P);
-	L =  2.0 * A * cos (theta) * sin (0.5*phi);
-	M =  A * sin (theta);
-      } else { 
-	L =  0.0;
-	M =  0.0;
-      }	
-    }
-    if (!strcmp(type, "-GLS")) {
-      phi = ra - coords[0].crval1;
-      theta = dec - coords[0].crval2;
-      L = phi * cos(RAD_DEG * theta);
-      M = theta;
-    }
-    if (!strcmp(type, "-PAR")) {
-      phi = ra - coords[0].crval1;
-      theta = dec - coords[0].crval2;
-      L = phi * (2.0*cos(2*RAD_DEG*theta/3.0) - 1);
-      M = 180.0 * sin (RAD_DEG*theta/3.0);
-    }
-  }
+	*L =  2.0 * A * cos (theta) * sin (0.5*phi);
+	*M =  A * sin (theta);
+	return (TRUE);
+      case PROJ_GLS:
+	phi = ra - coords[0].crval1;
+	theta = dec - coords[0].crval2;
+	*L = phi * cos(RAD_DEG * theta);
+	*M = theta;
+	return (TRUE);
+      case PROJ_PAR:
+	phi = ra - coords[0].crval1;
+	theta = dec - coords[0].crval2;
+	*L = phi * (2.0*cos(2*RAD_DEG*theta/3.0) - 1);
+	*M = 180.0 * sin (RAD_DEG*theta/3.0);
+	return (TRUE);
+      default:
+	return (FALSE);
+    }
+    return (FALSE);
+  }
+  return (FALSE);
+}
+
+int LM_to_XY (double *x, double *y, double L, double M, Coords *coords) {
+
+  int i;
+  double determ;
+  double X, Y, Lo, Mo, dL, dM;
+
+  *x = 0;
+  *y = 0;
 
   /* convert L,M to X,Y */
@@ -270,5 +288,4 @@
       dL = (L - Lo);
       dM = (M - Mo);
-      // fprintf (stderr, "%d: %f,%f : %f,%f : %f,%f : %f,%f\n", i, L, M, X, Y, Lo, Mo, dL, dM);
 
       X += determ * (coords[0].pc2_2*dL - coords[0].pc1_2*dM);
@@ -281,6 +298,29 @@
   *y = Y / coords[0].cdelt2 + coords[0].crpix2;
 
+  return (TRUE);
+}
+
+int XY_to_RD (double *ra, double *dec, double x, double y, Coords *coords) {
+
+  double L, M;
+  int status;
+
+  status = XY_to_LM (&L, &M, x, y, coords);
+  if (!status) return FALSE;
+
+  status = LM_to_RD (ra, dec, L, M, coords);
   return (status);
-  
+}
+
+int RD_to_XY (double *x, double *y, double ra, double dec, Coords *coords) {
+
+  double L, M;
+  int status;
+
+  status = RD_to_LM (&L, &M, ra, dec, coords);
+  if (!status) return FALSE;
+
+  status = LM_to_XY (x, y, L, M, coords);
+  return (status);
 }
 
@@ -599,2 +639,70 @@
 
 */
+
+  /* PLY is equiv to LIN with higher order terms
+     ZPL is equiv to ZEA with higher order terms
+     DIS is equiv to TAN with higher order terms
+     WRP is equiv to PLY, with implied mosaic */
+
+OhanaProjection GetProjection (char *ctype) {
+  if (!strcmp(&ctype[4], "-ZEA")) return PROJ_ZEA;
+  if (!strcmp(&ctype[4], "-ZPL")) return PROJ_ZPL;
+  if (!strcmp(&ctype[4], "-ARC")) return PROJ_ARC;
+  if (!strcmp(&ctype[4], "-STG")) return PROJ_STG;
+  if (!strcmp(&ctype[4], "-SIN")) return PROJ_SIN;
+  if (!strcmp(&ctype[0], "MM"))   return PROJ_SIN; // note ctype[0]
+  if (!strcmp(&ctype[4], "-TAN")) return PROJ_TAN;
+  if (!strcmp(&ctype[4], "-DIS")) return PROJ_DIS;
+  if (!strcmp(&ctype[4], "-LIN")) return PROJ_LIN;
+  if (!strcmp(&ctype[0], "GENE")) return PROJ_LIN; // note ctype[0]
+  if (!strcmp(&ctype[4], "-PLY")) return PROJ_PLY;
+  if (!strcmp(&ctype[4], "-WRP")) return PROJ_WRP;
+  if (!strcmp(&ctype[4], "-AIT")) return PROJ_AIT;
+  if (!strcmp(&ctype[4], "-GLS")) return PROJ_GLS;
+  if (!strcmp(&ctype[4], "-PAR")) return PROJ_PAR;
+  return PROJ_NONE;
+}
+  
+int SetProjection (char *ctype, OhanaProjection proj) {
+  switch (proj) {
+    case PROJ_ZEA: strcpy(&ctype[4], "-ZEA"); return TRUE;
+    case PROJ_ZPL: strcpy(&ctype[4], "-ZPL"); return TRUE;
+    case PROJ_ARC: strcpy(&ctype[4], "-ARC"); return TRUE;
+    case PROJ_STG: strcpy(&ctype[4], "-STG"); return TRUE;
+    case PROJ_SIN: strcpy(&ctype[4], "-SIN"); return TRUE;
+    case PROJ_TAN: strcpy(&ctype[4], "-TAN"); return TRUE;
+    case PROJ_DIS: strcpy(&ctype[4], "-DIS"); return TRUE;
+    case PROJ_LIN: strcpy(&ctype[4], "-LIN"); return TRUE;
+    case PROJ_PLY: strcpy(&ctype[4], "-PLY"); return TRUE;
+    case PROJ_WRP: strcpy(&ctype[4], "-WRP"); return TRUE;
+    case PROJ_AIT: strcpy(&ctype[4], "-AIT"); return TRUE;
+    case PROJ_GLS: strcpy(&ctype[4], "-GLS"); return TRUE;
+    case PROJ_PAR: strcpy(&ctype[4], "-PAR"); return TRUE;
+    case PROJ_NONE: return FALSE;
+  }
+  return FALSE;
+}  
+
+OhanaProjectionMode GetProjectionMode (OhanaProjection proj) {
+  switch (proj) {
+    case PROJ_ZEA:
+    case PROJ_ZPL:
+    case PROJ_ARC:
+    case PROJ_STG:
+    case PROJ_SIN:
+    case PROJ_TAN:
+    case PROJ_DIS:
+      return PROJ_MODE_ZENITHAL;
+    case PROJ_LIN: 
+    case PROJ_PLY: 
+    case PROJ_WRP: 
+      return PROJ_MODE_CARTESIAN;
+    case PROJ_AIT:
+    case PROJ_GLS:
+    case PROJ_PAR:
+      return PROJ_MODE_PSEUDOCYL;
+    default: PROJ_MODE_NONE;
+  }
+  return PROJ_MODE_NONE;
+}
+
Index: trunk/Ohana/src/libdvo/src/coordops.update.c
===================================================================
--- trunk/Ohana/src/libdvo/src/coordops.update.c	(revision 11991)
+++ trunk/Ohana/src/libdvo/src/coordops.update.c	(revision 12332)
@@ -86,4 +86,9 @@
       case PROJ_ZEA:
       case PROJ_ZPL:
+	if (R > 2*DEG_RAD) {
+	  *ra = L;
+	  *dec = M;
+	  return (FALSE);
+	}
 	stht = 1 - 0.5*SQ(R*RAD_DEG);
 	ctht = sqrt (1 - stht*stht);
@@ -110,5 +115,5 @@
   
   /**** Other Conventional Projections ****/
-  if (mode == PROJ_MODE_ZENITHAL) {
+  if (mode == PROJ_MODE_PSEUDOCLY) {
     switch (proj) {
       case PROJ_AIT:
@@ -119,5 +124,5 @@
       delta = DEG_RAD * asin (RAD_DEG*M*Z);
       break;
-
+      
       case PROJ_GLS:
 	/* L,M in degrees, alpha,delta in degrees */
@@ -213,29 +218,31 @@
 
   /**** Other Standard Projections ****/
-  if (PseudoCyl) {
-    if (!strcmp(type, "-AIT")) {
-      phi = RAD_DEG*(ra - coords[0].crval1);
-      theta = RAD_DEG*(dec - coords[0].crval2);
-      P = 1.0 + cos (theta) * cos (0.5*phi);
-      if (P != 0.0) {
-	A =  DEG_RAD * sqrt (2.0 / P);
-	L =  2.0 * A * cos (theta) * sin (0.5*phi);
-	M =  A * sin (theta);
-      } else { 
-	L =  0.0;
-	M =  0.0;
-      }	
-    }
-    if (!strcmp(type, "-GLS")) {
-      phi = ra - coords[0].crval1;
-      theta = dec - coords[0].crval2;
-      L = phi * cos(RAD_DEG * theta);
-      M = theta;
-    }
-    if (!strcmp(type, "-PAR")) {
-      phi = ra - coords[0].crval1;
-      theta = dec - coords[0].crval2;
-      L = phi * (2.0*cos(2*RAD_DEG*theta/3.0) - 1);
-      M = 180.0 * sin (RAD_DEG*theta/3.0);
+  if (mode == PROJ_MODE_PSEUDOCYL) {
+    switch (proj) {
+      case PROJ_AIT:
+	phi = RAD_DEG*(ra - coords[0].crval1);
+	theta = RAD_DEG*(dec - coords[0].crval2);
+	P = 1.0 + cos (theta) * cos (0.5*phi);
+	if (P != 0.0) {
+	  A =  DEG_RAD * sqrt (2.0 / P);
+	  L =  2.0 * A * cos (theta) * sin (0.5*phi);
+	  M =  A * sin (theta);
+	} else { 
+	  L =  0.0;
+	  M =  0.0;
+	}	
+	break;
+      case PROJ_GLS:
+	phi = ra - coords[0].crval1;
+	theta = dec - coords[0].crval2;
+	L = phi * cos(RAD_DEG * theta);
+	M = theta;
+	break;
+      case PROJ_PAR:
+	phi = ra - coords[0].crval1;
+	theta = dec - coords[0].crval2;
+	L = phi * (2.0*cos(2*RAD_DEG*theta/3.0) - 1);
+	M = 180.0 * sin (RAD_DEG*theta/3.0);
+	break;
     }
   }
@@ -261,5 +268,4 @@
       dL = (L - Lo);
       dM = (M - Mo);
-      // fprintf (stderr, "%d: %f,%f : %f,%f : %f,%f : %f,%f\n", i, L, M, X, Y, Lo, Mo, dL, dM);
 
       X += determ * (coords[0].pc2_2*dL - coords[0].pc1_2*dM);
@@ -273,5 +279,4 @@
 
   return (status);
-  
 }
 
Index: trunk/Ohana/src/libdvo/src/dvo_catalog.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_catalog.c	(revision 11991)
+++ trunk/Ohana/src/libdvo/src/dvo_catalog.c	(revision 12332)
@@ -50,4 +50,5 @@
   if (!strcasecmp (catformat, "PANSTARRS")) return (DVO_FORMAT_PANSTARRS);
   if (!strcasecmp (catformat, "PMTEST"))    return (DVO_FORMAT_PMTEST);
+  if (!strcasecmp (catformat, "PANSTARRS_DEV_0")) return (DVO_FORMAT_PANSTARRS_DEV_0);
   return (DVO_FORMAT_UNDEF);
 }
@@ -340,11 +341,11 @@
     for (in = out = i = 0; i < catalog[0].Naverage; i++) {
       for (j = 0; j < catalog[0].Nsecfilt; j++, in++, out++) {
-	outsec[out].M_PS  = insec[in].M_PS;
-	outsec[out].dM_PS = insec[in].dM_PS;
+	outsec[out].M  = insec[in].M;
+	outsec[out].dM = insec[in].dM;
 	outsec[out].Xm = insec[in].Xm;
       }
       for (j = 0; j < Nextra; j++, out++) {
-	outsec[out].M_PS  = NO_MAG;
-	outsec[out].dM_PS = NO_MAG;
+	outsec[out].M  = NO_MAG;
+	outsec[out].dM = NO_MAG;
 	outsec[out].Xm    = NO_MAG;
       }
@@ -386,5 +387,5 @@
 /*
   mode   : items to read (LOAD_AVES | LOAD_MEAS | LOAD_MISS | LOAD_SECF)
-  format : what structure on disk (INTERNAL, ELIXIR, LONEOS, PANSTARRS)
+  format : what table structure on disk (INTERNAL, LONEOS, etc, )
   style  : raw, mef, split, mysql
 */
Index: trunk/Ohana/src/libdvo/src/dvo_catalog_chipcoords.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_catalog_chipcoords.c	(revision 12332)
+++ trunk/Ohana/src/libdvo/src/dvo_catalog_chipcoords.c	(revision 12332)
@@ -0,0 +1,68 @@
+# include <dvo.h>
+
+int dvo_match_image (Image *image, int Nimage, unsigned int T, short int S) {
+
+  int N, Nlo, Nhi, N1, N2;
+
+  /* bracket first value of interest */
+  Nlo = 0; Nhi = Nimage;
+  while (Nhi - Nlo > 10) {
+    N = 0.5*(Nlo + Nhi);
+    if (image[N].tzero < T) {
+      Nlo = N;
+    } else {
+      Nhi = N + 1;
+    }
+  }
+  N1 = Nlo;
+
+  /* bracket last value of interest */
+  Nlo = 0; Nhi = Nimage;
+  while (Nhi - Nlo > 10) {
+    N = 0.5*(Nlo + Nhi);
+    if (image[N].tzero > T) {
+      Nhi = N;
+    } else {
+      Nlo = N - 1;
+    }
+  }
+  N2 = Nhi;
+
+  for (N = N1; N < N2; N++) {
+    if ((image[N].tzero == T) && (image[N].photcode == S)) {
+      return (N);
+    }
+  }
+  return (-1);
+}
+
+// if necessary, determine chip coordinates for all measures
+int dvo_catalog_chipcoords (Catalog *catalog, Image *image, int Nimage) {
+
+  int i, j, m, N;
+  double ra, dec, x, y;
+  Average *average;
+  Measure *measure;
+
+  if (catalog[0].catformat == DVO_FORMAT_LONEOS) goto do_convert;  // special conversion for LONEOS
+  if (catalog[0].catformat == DVO_FORMAT_ELIXIR) goto do_convert;  // special conversion for ELIXIR
+  return TRUE;
+
+do_convert:
+  average = catalog[0].average;
+  measure = catalog[0].measure;
+  
+  for (i = 0; i < catalog[0].Naverage; i++) {
+    m = average[i].offset;
+    for (j = 0; j < average[i].Nm; j++, m++) {
+      ra  = average[i].R - measure[m].dR / 3600.0;
+      dec = average[i].D - measure[m].dD / 3600.0;
+      N = dvo_match_image (image, Nimage, measure[m].t, measure[m].photcode);
+      if (N == -1) continue;
+      RD_to_XY (&x, &y, ra, dec, &image[N].coords);
+      measure[m].Xccd = x;
+      measure[m].Yccd = y;
+    }
+  }
+  return TRUE;
+}
Index: trunk/Ohana/src/libdvo/src/dvo_catalog_mef.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_catalog_mef.c	(revision 11991)
+++ trunk/Ohana/src/libdvo/src/dvo_catalog_mef.c	(revision 12332)
@@ -9,4 +9,5 @@
   Matrix matrix;
   FTable ftable;
+  SecFilt *primary;
 
   f = catalog[0].f;
@@ -44,5 +45,6 @@
       return (FALSE);
     }
-    catalog[0].average = FtableToAverage (&ftable, &catalog[0].Naverage, &catalog[0].catformat);
+    /* old versions of DVO stored one of the average magnitudes in Average. we save this if needed */
+    catalog[0].average = FtableToAverage (&ftable, &catalog[0].Naverage, &catalog[0].catformat, &primary);
     if (Naverage != catalog[0].Naverage) {
       fprintf (stderr, "Warning: mismatch between Naverage in PHU and Table headers (%d vs %d)\n", Naverage, catalog[0].Naverage);
@@ -96,7 +98,4 @@
   }
 
-  // catalog[0].secfilt = gfits_table_get_SecFilt (&ftable, &Nitems, NULL);
-  // catalog[0].Nsecfilt = Nitems / catalog[0].Naverage;
-
   /* read secfilt table header */
   if (!gfits_fread_header (f, &header)) {
@@ -110,4 +109,6 @@
       return (FALSE);
     }
+
+    /* how many entries do we expect from the secfilt table? */
     Nexpect = catalog[0].Nsecfilt * catalog[0].Naverage;
     catalog[0].secfilt = FtableToSecFilt (&ftable, &Nitems, &catalog[0].catformat);
@@ -115,8 +116,30 @@
       fprintf (stderr, "Warning: mismatch between Nsecfilt items in PHU and Table headers (%d vs %d)\n", Nexpect, Nitems);
     }
+
+    /* if primary is defined, we were supplied with one additional average magnitude from Average
+       we need to interleave these magnitudes with the secfilt entries just loaded */
+    if (primary != NULL) {
+      int Ntmpfilt, Ntotal, i, j;
+      SecFilt *tmpfilt;
+      tmpfilt  = catalog[0].secfilt;
+      Ntmpfilt = catalog[0].Nsecfilt;
+      Nsecfilt = catalog[0].Nsecfilt + 1;
+      Ntotal = Nsecfilt * catalog[0].Naverage;
+      ALLOCATE (catalog[0].secfilt, SecFilt, Ntotal);
+      for (i = 0; i < catalog[0].Naverage; i++) {
+	catalog[0].secfilt[i*Nsecfilt + 0] = primary[i];
+	for (j = 0; j < Ntmpfilt; j++) {
+	  catalog[0].secfilt[i*Nsecfilt + j + 1] = tmpfilt[i*Ntmpfilt + j];
+	}
+      }		
+      catalog[0].Nsecfilt = Nsecfilt;
+      free (primary);
+    } 
+
   } else {
     /* no real need to skip the data array here... */
     Nbytes = gfits_matrix_size (&header);
     fseek (f, Nbytes, SEEK_CUR);
+    if (primary != NULL) free (primary);
   }
 
@@ -129,6 +152,6 @@
 }
 
+/* XXX need to decompose the primary and secfilt entries for Elixir and Loneos */
 /* save_catalog_mef writes a complete new file from scratch */
-
 int dvo_catalog_save_mef (Catalog *catalog, char VERBOSE) {
 
@@ -138,4 +161,7 @@
   Header header;
   FTable ftable;
+  SecFilt *primary;
+  SecFilt *secfilt;
+  int i, j, Nsecfilt, Nallfilt, Ntotal;
 
   if (catalog[0].Naverage == 0) {
@@ -171,6 +197,27 @@
   gfits_free_matrix (&matrix);
 
+  /* for the appropriate types, pull out the first secfilt and pass to AverageToFtable as primary */
+  if ((catalog[0].catformat == DVO_FORMAT_ELIXIR) || // special case for ELIXIR 
+      (catalog[0].catformat == DVO_FORMAT_LONEOS)) { // special case for LONEOS
+    Nallfilt = catalog[0].Nsecfilt;
+    Nsecfilt = catalog[0].Nsecfilt - 1;
+    Ntotal = Nsecfilt * catalog[0].Naverage;
+    ALLOCATE (primary, SecFilt, catalog[0].Naverage);
+    ALLOCATE (secfilt, SecFilt, Ntotal);
+
+    for (i = 0; i < catalog[0].Naverage; i++) {
+      primary[i] = catalog[0].secfilt[i*Nallfilt + 0];
+      for (j = 0; j < Nsecfilt; j++) {
+	secfilt[i*Nsecfilt + j] = catalog[0].secfilt[i*Nallfilt + j + 1];
+      }
+    }		
+  } else {
+    primary = NULL;
+    secfilt = catalog[0].secfilt;
+    Nsecfilt = catalog[0].Nsecfilt;
+  }
+
   /* write out Average table (convert to FITS table format) */
-  AverageToFtable (&ftable, catalog[0].average, catalog[0].Naverage, catalog[0].catformat);
+  AverageToFtable (&ftable, catalog[0].average, catalog[0].Naverage, catalog[0].catformat, primary);
   if (!gfits_fwrite_Theader (catalog[0].f, &header)) {
     fprintf (stderr, "can't write table header");
@@ -211,16 +258,22 @@
 
   /* write out SecFilt table (convert to FITS table format) */
-  Nitems = catalog[0].Naverage * catalog[0].Nsecfilt;
-  SecFiltToFtable (&ftable, catalog[0].secfilt, Nitems, catalog[0].catformat);
-  if (!gfits_fwrite_Theader (catalog[0].f, &header)) {
-    fprintf (stderr, "can't write table header");
-    return (FALSE);
-  }
-  if (!gfits_fwrite_table (catalog[0].f, &ftable)) {
-    fprintf (stderr, "can't write table data");
-    return (FALSE);
-  }
-  gfits_free_table (&ftable);
-  gfits_free_header (&header);
+  Nitems = catalog[0].Naverage * Nsecfilt;
+  SecFiltToFtable (&ftable, secfilt, Nitems, catalog[0].catformat);
+  if (!gfits_fwrite_Theader (catalog[0].f, &header)) {
+    fprintf (stderr, "can't write table header");
+    return (FALSE);
+  }
+  if (!gfits_fwrite_table (catalog[0].f, &ftable)) {
+    fprintf (stderr, "can't write table data");
+    return (FALSE);
+  }
+  gfits_free_table (&ftable);
+  gfits_free_header (&header);
+
+  /* free temp storage */
+  if (primary != NULL) {
+    free (primary);
+    free (secfilt);
+  }
 
   return (TRUE);
@@ -228,15 +281,15 @@
 
 /*
-   catalog data is:
-   header (bitpix == 8)
-   matrix (empty)
-   average header
-   average table
-   measure header
-   measure table
-   missing header
-   missing table
-   secfilt header
-   secfilt table
+  catalog data is:
+  header (bitpix == 8)
+  matrix (empty)
+  average header
+  average table
+  measure header
+  measure table
+  missing header
+  missing table
+  secfilt header
+  secfilt table
 */
    
Index: trunk/Ohana/src/libdvo/src/dvo_catalog_raw.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_catalog_raw.c	(revision 11991)
+++ trunk/Ohana/src/libdvo/src/dvo_catalog_raw.c	(revision 12332)
@@ -12,4 +12,5 @@
   struct stat filestatus;
   char format[80], telescope[80];
+  SecFilt *primary;
 
   f = catalog[0].f;
@@ -28,23 +29,19 @@
   catalog[0].catformat = DVO_FORMAT_UNDEF;
   if (gfits_scan (&catalog[0].header, "FORMAT",  "%s", 1, format)) {
-    if (!strcmp (format, "INTERNAL")) catalog[0].catformat = DVO_FORMAT_INTERNAL;
-    if (!strcmp (format, "LONEOS")) catalog[0].catformat = DVO_FORMAT_LONEOS;
-    if (!strcmp (format, "ELIXIR")) catalog[0].catformat = DVO_FORMAT_ELIXIR;
-    if (!strcmp (format, "PANSTARRS")) catalog[0].catformat = DVO_FORMAT_PANSTARRS;
-    if (!strcmp (format, "PMTEST")) catalog[0].catformat = DVO_FORMAT_PMTEST;
+    catalog[0].catformat = dvo_catalog_catformat (format);
     if (catalog[0].catformat != DVO_FORMAT_UNDEF) goto got_format;
   }
   /* special cases: old versions of the DB tables which were poorly identified */
   if (gfits_scan (&catalog[0].header, "NEWMEAS",  "%t", 1, &NewMeasure)) {
-    catalog[0].catformat = DVO_FORMAT_ELIXIR;
+    catalog[0].catformat = DVO_FORMAT_ELIXIR; // special case for ELIXIR
     goto got_format;
   }
   if (gfits_scan (&catalog[0].header, "TELESCOP",  "%s", 1, telescope)) {
     if (!strncmp (telescope, "LONEOS", strlen("LONEOS"))) {
-      catalog[0].catformat = DVO_FORMAT_LONEOS;
+      catalog[0].catformat = DVO_FORMAT_LONEOS; // special case for LONEOS
       goto got_format;
     }
     if (!strncmp (telescope, "1.3m McGraw-Hill", strlen("1.3m McGraw-Hill"))) {
-      catalog[0].catformat = DVO_FORMAT_ELIXIR;
+      catalog[0].catformat = DVO_FORMAT_ELIXIR; // special case for ELIXIR
       goto got_format;
     }
@@ -59,26 +56,33 @@
       AverageSize = sizeof(Average);
       MeasureSize = sizeof(Measure);
-      SecFiltSize = sizeof (SecFilt);
+      SecFiltSize = sizeof(SecFilt);
       break;
     case DVO_FORMAT_LONEOS:
       AverageSize = sizeof(AverageLoneos);
       MeasureSize = sizeof(MeasureLoneos);
-      SecFiltSize = sizeof (SecFiltLoneos);
+      SecFiltSize = sizeof(SecFiltLoneos);
       break;
     case DVO_FORMAT_ELIXIR:
       AverageSize = sizeof(AverageElixir);
       MeasureSize = sizeof(MeasureElixir);
-      SecFiltSize = sizeof (SecFiltElixir);
+      SecFiltSize = sizeof(SecFiltElixir);
       break;
+    case DVO_FORMAT_PANSTARRS_DEV_0:
+      AverageSize = sizeof(AveragePanstarrs_DEV_0);
+      MeasureSize = sizeof(MeasurePanstarrs_DEV_0);
+      SecFiltSize = sizeof(SecFiltPanstarrs_DEV_0);
+      break;
+# if 0
     case DVO_FORMAT_PANSTARRS:
       AverageSize = sizeof(AveragePanstarrs);
       MeasureSize = sizeof(MeasurePanstarrs);
-      SecFiltSize = sizeof (SecFiltPanstarrs);
+      SecFiltSize = sizeof(SecFiltPanstarrs);
       break;
     case DVO_FORMAT_PMTEST:
       AverageSize = sizeof(AveragePMtest);
       MeasureSize = sizeof(MeasurePanstarrs);
-      SecFiltSize = sizeof (SecFiltPanstarrs);
+      SecFiltSize = sizeof(SecFiltPanstarrs);
       break;
+# endif
     default:
       fprintf (stderr, "programming error in phot_catalog_raw\n");
@@ -120,6 +124,7 @@
 
   /* read and convert the averages (use a macro to clean this up?) */
+  /* old versions of DVO stored one of the average magnitudes in Average. we save this if needed */
   if (catalog[0].catflags & LOAD_AVES) {
-    catalog[0].average = ReadRawAverage (catalog[0].f, catalog[0].Naverage, catalog[0].catformat);
+    catalog[0].average = ReadRawAverage (catalog[0].f, catalog[0].Naverage, catalog[0].catformat, &primary);
   } else {
     /* skip over averages */
@@ -157,8 +162,30 @@
     Nitems = catalog[0].Naverage * catalog[0].Nsecfilt;
     catalog[0].secfilt = ReadRawSecFilt (catalog[0].f, Nitems, catalog[0].catformat);
+
+    /* if primary is defined, we were supplied with one additional average magnitude from Average
+       we need to interleave these magnitudes with the secfilt entries just loaded */
+    if (primary != NULL) {
+      int Ntmpfilt, Nsecfilt, Ntotal, i, j;
+      SecFilt *tmpfilt;
+      tmpfilt  = catalog[0].secfilt;
+      Ntmpfilt = catalog[0].Nsecfilt;
+      Nsecfilt = catalog[0].Nsecfilt + 1;
+      Ntotal = Nsecfilt * catalog[0].Naverage;
+      ALLOCATE (catalog[0].secfilt, SecFilt, Ntotal);
+      for (i = 0; i < catalog[0].Naverage; i++) {
+	catalog[0].secfilt[i*Nsecfilt + 0] = primary[i];
+	for (j = 0; j < Ntmpfilt; j++) {
+	  catalog[0].secfilt[i*Nsecfilt + j + 1] = tmpfilt[i*Ntmpfilt + j];
+	}
+      }		
+      catalog[0].Nsecfilt = Nsecfilt;
+      free (primary);
+    } 
+
   } else {
     /* skip over secfilts */
     Nskip = catalog[0].Nsecfilt * catalog[0].Naverage * SecFiltSize;
     fseek (f, Nskip, SEEK_CUR); 
+    if (primary != NULL) free (primary);
   }
 
@@ -194,4 +221,7 @@
   int Nitems, nitems;
   FILE *f;
+  SecFilt *primary;
+  SecFilt *secfilt;
+  int i, j, Nsecfilt, Nallfilt, Ntotal;
 
   if (catalog[0].Naverage == 0) {
@@ -210,6 +240,7 @@
   if (catalog[0].catformat == DVO_FORMAT_LONEOS)    gfits_modify (&catalog[0].header, "FORMAT", "%s", 1, "LONEOS");
   if (catalog[0].catformat == DVO_FORMAT_ELIXIR)    gfits_modify (&catalog[0].header, "FORMAT", "%s", 1, "ELIXIR");
-  if (catalog[0].catformat == DVO_FORMAT_PANSTARRS) gfits_modify (&catalog[0].header, "FORMAT", "%s", 1, "PANSTARRS");
-  if (catalog[0].catformat == DVO_FORMAT_PMTEST)    gfits_modify (&catalog[0].header, "FORMAT", "%s", 1, "PMTEST");
+  if (catalog[0].catformat == DVO_FORMAT_PANSTARRS_DEV_0) gfits_modify (&catalog[0].header, "FORMAT", "%s", 1, "PANSTARRS_DEV_0");
+  // if (catalog[0].catformat == DVO_FORMAT_PANSTARRS) gfits_modify (&catalog[0].header, "FORMAT", "%s", 1, "PANSTARRS");
+  // if (catalog[0].catformat == DVO_FORMAT_PMTEST)    gfits_modify (&catalog[0].header, "FORMAT", "%s", 1, "PMTEST");
 
   /* rewind file pointers and truncate file */
@@ -225,6 +256,27 @@
   }
 
+  /* for the appropriate types, pull out the first secfilt and pass to WriteRawAverage as primary */
+  if ((catalog[0].catformat == DVO_FORMAT_ELIXIR) || // special case for ELIXIR
+      (catalog[0].catformat == DVO_FORMAT_LONEOS)) { // special case for LONEOS
+    Nallfilt = catalog[0].Nsecfilt;
+    Nsecfilt = catalog[0].Nsecfilt - 1;
+    Ntotal = Nsecfilt * catalog[0].Naverage;
+    ALLOCATE (primary, SecFilt, catalog[0].Naverage);
+    ALLOCATE (secfilt, SecFilt, Ntotal);
+
+    for (i = 0; i < catalog[0].Naverage; i++) {
+      primary[i] = catalog[0].secfilt[i*Nallfilt + 0];
+      for (j = 0; j < Nsecfilt; j++) {
+	secfilt[i*Nsecfilt + j] = catalog[0].secfilt[i*Nallfilt + j + 1];
+      }
+    }		
+  } else {
+    primary = NULL;
+    secfilt = catalog[0].secfilt;
+    Nsecfilt = catalog[0].Nsecfilt;
+  }
+
   /* write averages and measures */
-  WriteRawAverage (f, catalog[0].average, catalog[0].Naverage, catalog[0].catformat);
+  WriteRawAverage (f, catalog[0].average, catalog[0].Naverage, catalog[0].catformat, primary);
   WriteRawMeasure (f, catalog[0].measure, catalog[0].Nmeasure, catalog[0].catformat);
 
@@ -240,4 +292,11 @@
   Nitems = catalog[0].Naverage * catalog[0].Nsecfilt;
   WriteRawSecFilt (f, catalog[0].secfilt, Nitems, catalog[0].catformat);
+
+  /* free temp storage */
+  if (primary != NULL) {
+    free (primary);
+    free (secfilt);
+  }
+
   return (TRUE);
 }
@@ -250,15 +309,15 @@
 /** Average / Raw Table conversions **/
 
-Average *ReadRawAverage (FILE *f, int Naverage, int format) {
+Average *ReadRawAverage (FILE *f, int Naverage, int format, SecFilt **primary) {
 
   int nitems;
   Average *average;
-  AverageElixir *tmpAverageElixir;
-  AverageLoneos *tmpAverageLoneos;
-  AveragePanstarrs *tmpAveragePanstarrs;
-  AveragePMtest *tmpAveragePMtest;
+
+  /* in the Elixir and Loneos cases, we are supplied with an average magnitude in Average
+     in these cases, save these values in primary; otherwise set primary to NULL */
+  *primary = NULL;
 
   switch (format) {
-    case DVO_FORMAT_INTERNAL:
+    case DVO_FORMAT_INTERNAL: {
       ALLOCATE (average, Average, MAX (Naverage, 1));
       nitems = fread (average, sizeof(Average), Naverage, f);
@@ -268,49 +327,67 @@
       }
       gfits_convert_Average (average, sizeof(Average), Naverage);
-      break;
-    case DVO_FORMAT_ELIXIR:
-      ALLOCATE (tmpAverageElixir, AverageElixir, MAX (Naverage, 1));
-      nitems = fread (tmpAverageElixir, sizeof(AverageElixir), Naverage, f);
+      break; }
+    case DVO_FORMAT_ELIXIR: {
+      AverageElixir *tmpAverage;
+      ALLOCATE (tmpAverage, AverageElixir, MAX (Naverage, 1));
+      nitems = fread (tmpAverage, sizeof(AverageElixir), Naverage, f);
       if (nitems != Naverage) {
 	fprintf (stderr, "failed to read averages (%d vs %d)\n", nitems, Naverage);
 	return (NULL);
       }
-      gfits_convert_AverageElixir (tmpAverageElixir, sizeof(AverageElixir), Naverage);
-      average = AverageElixirToInternal (tmpAverageElixir, Naverage);
-      free (tmpAverageElixir);
-      break;
-    case DVO_FORMAT_LONEOS:
-      ALLOCATE (tmpAverageLoneos, AverageLoneos, MAX (Naverage, 1));
-      nitems = fread (tmpAverageLoneos, sizeof(AverageLoneos), Naverage, f);
+      gfits_convert_AverageElixir (tmpAverage, sizeof(AverageElixir), Naverage);
+      average = AverageElixirToInternal (tmpAverage, Naverage, primary);
+      free (tmpAverage);
+      break; }
+    case DVO_FORMAT_LONEOS: {
+      AverageLoneos *tmpAverage;
+      ALLOCATE (tmpAverage, AverageLoneos, MAX (Naverage, 1));
+      nitems = fread (tmpAverage, sizeof(AverageLoneos), Naverage, f);
       if (nitems != Naverage) {
 	fprintf (stderr, "failed to read averages (%d vs %d)\n", nitems, Naverage);
 	return (NULL);
       }
-      gfits_convert_AverageLoneos (tmpAverageLoneos, sizeof(AverageLoneos), Naverage);
-      average = AverageLoneosToInternal (tmpAverageLoneos, Naverage);
-      free (tmpAverageLoneos);
-      break;
-    case DVO_FORMAT_PANSTARRS:
-      ALLOCATE (tmpAveragePanstarrs, AveragePanstarrs, MAX (Naverage, 1));
-      nitems = fread (tmpAveragePanstarrs, sizeof(AveragePanstarrs), Naverage, f);
+      gfits_convert_AverageLoneos (tmpAverage, sizeof(AverageLoneos), Naverage);
+      average = AverageLoneosToInternal (tmpAverage, Naverage, primary);
+      free (tmpAverage);
+      break; }
+    case DVO_FORMAT_PANSTARRS_DEV_0: {
+      AveragePanstarrs_DEV_0 *tmpAverage;
+      ALLOCATE (tmpAverage, AveragePanstarrs_DEV_0, MAX (Naverage, 1));
+      nitems = fread (tmpAverage, sizeof(AveragePanstarrs_DEV_0), Naverage, f);
       if (nitems != Naverage) {
 	fprintf (stderr, "failed to read averages (%d vs %d)\n", nitems, Naverage);
 	return (NULL);
       }
-      gfits_convert_AveragePanstarrs (tmpAveragePanstarrs, sizeof(AveragePanstarrs), Naverage);
-      average = AveragePanstarrsToInternal (tmpAveragePanstarrs, Naverage);
-      free (tmpAveragePanstarrs);
-      break;
-    case DVO_FORMAT_PMTEST:
-      ALLOCATE (tmpAveragePMtest, AveragePMtest, MAX (Naverage, 1));
-      nitems = fread (tmpAveragePMtest, sizeof(AveragePMtest), Naverage, f);
+      gfits_convert_AveragePanstarrs_DEV_0 (tmpAverage, sizeof(AveragePanstarrs_DEV_0), Naverage);
+      average = AveragePanstarrs_DEV_0_ToInternal (tmpAverage, Naverage);
+      free (tmpAverage);
+      break; }
+# if 0
+    case DVO_FORMAT_PANSTARRS: {
+      AveragePanstarrs *tmpAverage;
+      ALLOCATE (tmpAverage, AveragePanstarrs, MAX (Naverage, 1));
+      nitems = fread (tmpAverage, sizeof(AveragePanstarrs), Naverage, f);
       if (nitems != Naverage) {
 	fprintf (stderr, "failed to read averages (%d vs %d)\n", nitems, Naverage);
 	return (NULL);
       }
-      gfits_convert_AveragePMtest (tmpAveragePMtest, sizeof(AveragePMtest), Naverage);
-      average = AveragePMtestToInternal (tmpAveragePMtest, Naverage);
-      free (tmpAveragePMtest);
-      break;
+      gfits_convert_AveragePanstarrs (tmpAverage, sizeof(AveragePanstarrs), Naverage);
+      average = AveragePanstarrsToInternal (tmpAverage, Naverage);
+      free (tmpAverage);
+      break; }
+    case DVO_FORMAT_PMTEST: {
+      AveragePMtest *tmpAverage;
+      ALLOCATE (tmpAverage, AveragePMtest, MAX (Naverage, 1));
+      nitems = fread (tmpAverage, sizeof(AveragePMtest), Naverage, f);
+      if (nitems != Naverage) {
+	fprintf (stderr, "failed to read averages (%d vs %d)\n", nitems, Naverage);
+	return (NULL);
+      }
+      gfits_convert_AveragePMtest (tmpAverage, sizeof(AveragePMtest), Naverage);
+      average = AveragePMtestToInternal (tmpAverage, Naverage);
+      free (tmpAverage);
+      break; }
+# endif
     default:
       fprintf (stderr, "error reading measures\n");
@@ -322,14 +399,10 @@
 /* accepts and converts internal average formats and outputs 
    raw data in the specified format */
-int WriteRawAverage (FILE *f, Average *average, int Naverage, int format) {
+int WriteRawAverage (FILE *f, Average *average, int Naverage, int format, SecFilt *primary) {
 
   int nitems;
-  AverageElixir *tmpAverageElixir;
-  AverageLoneos *tmpAverageLoneos;
-  AveragePanstarrs *tmpAveragePanstarrs;
-  AveragePMtest *tmpAveragePMtest;
 
   switch (format) {
-    case DVO_FORMAT_INTERNAL:
+    case DVO_FORMAT_INTERNAL: {
       gfits_convert_Average (average, sizeof(Average), Naverage);
       nitems = fwrite (average, sizeof(Average), Naverage, f);
@@ -338,45 +411,62 @@
 	return (FALSE);
       }
-      break;
-    case DVO_FORMAT_ELIXIR:
-      tmpAverageElixir = AverageInternalToElixir (average, Naverage);
-      gfits_convert_AverageElixir (tmpAverageElixir, sizeof(AverageElixir), Naverage);
-      nitems = fwrite (tmpAverageElixir, sizeof(AverageElixir), Naverage, f);
-      free (tmpAverageElixir);
+      break; }
+    case DVO_FORMAT_ELIXIR: {
+      AverageElixir *tmpAverage;
+      tmpAverage = AverageInternalToElixir (average, Naverage, primary);
+      gfits_convert_AverageElixir (tmpAverage, sizeof(AverageElixir), Naverage);
+      nitems = fwrite (tmpAverage, sizeof(AverageElixir), Naverage, f);
+      free (tmpAverage);
       if (nitems != Naverage) {
 	fprintf (stderr, "failed to write averages (%d vs %d)\n", nitems, Naverage);
 	return (FALSE);
       }
-      break;
-    case DVO_FORMAT_LONEOS:
-      tmpAverageLoneos = AverageInternalToLoneos (average, Naverage);
-      gfits_convert_AverageLoneos (tmpAverageLoneos, sizeof(AverageLoneos), Naverage);
-      nitems = fwrite (tmpAverageLoneos, sizeof(AverageLoneos), Naverage, f);
-      free (tmpAverageLoneos);
+      break; }
+    case DVO_FORMAT_LONEOS: {
+      AverageLoneos *tmpAverage;
+      tmpAverage = AverageInternalToLoneos (average, Naverage, primary);
+      gfits_convert_AverageLoneos (tmpAverage, sizeof(AverageLoneos), Naverage);
+      nitems = fwrite (tmpAverage, sizeof(AverageLoneos), Naverage, f);
+      free (tmpAverage);
       if (nitems != Naverage) {
 	fprintf (stderr, "failed to write averages (%d vs %d)\n", nitems, Naverage);
 	return (FALSE);
       }
-      break;
-    case DVO_FORMAT_PANSTARRS:
-      tmpAveragePanstarrs = AverageInternalToPanstarrs (average, Naverage);
-      gfits_convert_AveragePanstarrs (tmpAveragePanstarrs, sizeof(AveragePanstarrs), Naverage);
-      nitems = fwrite (tmpAveragePanstarrs, sizeof(AveragePanstarrs), Naverage, f);
-      free (tmpAveragePanstarrs);
+      break; }
+    case DVO_FORMAT_PANSTARRS_DEV_0: {
+      AveragePanstarrs_DEV_0 *tmpAverage;
+      tmpAverage = AverageInternalToPanstarrs_DEV_0 (average, Naverage);
+      gfits_convert_AveragePanstarrs_DEV_0 (tmpAverage, sizeof(AveragePanstarrs_DEV_0), Naverage);
+      nitems = fwrite (tmpAverage, sizeof(AveragePanstarrs_DEV_0), Naverage, f);
+      free (tmpAverage);
       if (nitems != Naverage) {
 	fprintf (stderr, "failed to write averages (%d vs %d)\n", nitems, Naverage);
 	return (FALSE);
       }
-      break;
-    case DVO_FORMAT_PMTEST:
-      tmpAveragePMtest = AverageInternalToPMtest (average, Naverage);
-      gfits_convert_AveragePMtest (tmpAveragePMtest, sizeof(AveragePMtest), Naverage);
-      nitems = fwrite (tmpAveragePMtest, sizeof(AveragePMtest), Naverage, f);
-      free (tmpAveragePMtest);
+      break; }
+# if 0
+    case DVO_FORMAT_PANSTARRS: {
+      AveragePanstarrs *tmpAverage;
+      tmpAverage = AverageInternalToPanstarrs (average, Naverage);
+      gfits_convert_AveragePanstarrs (tmpAverage, sizeof(AveragePanstarrs), Naverage);
+      nitems = fwrite (tmpAverage, sizeof(AveragePanstarrs), Naverage, f);
+      free (tmpAverage);
       if (nitems != Naverage) {
 	fprintf (stderr, "failed to write averages (%d vs %d)\n", nitems, Naverage);
 	return (FALSE);
       }
-      break;
+      break; }
+    case DVO_FORMAT_PMTEST: {
+      AveragePMtest *tmpAverage;
+      tmpAverage = AverageInternalToPMtest (average, Naverage);
+      gfits_convert_AveragePMtest (tmpAverage, sizeof(AveragePMtest), Naverage);
+      nitems = fwrite (tmpAverage, sizeof(AveragePMtest), Naverage, f);
+      free (tmpAverage);
+      if (nitems != Naverage) {
+	fprintf (stderr, "failed to write averages (%d vs %d)\n", nitems, Naverage);
+	return (FALSE);
+      }
+      break; }
+# endif
     default:
       fprintf (stderr, "error writing averages\n");
@@ -392,10 +482,7 @@
   int nitems;
   Measure *measure;
-  MeasureElixir *tmpMeasureElixir;
-  MeasureLoneos *tmpMeasureLoneos;
-  MeasurePanstarrs *tmpMeasurePanstarrs;
 
   switch (format) {
-    case DVO_FORMAT_INTERNAL:
+    case DVO_FORMAT_INTERNAL: {
       ALLOCATE (measure, Measure, MAX (Nmeasure, 1));
       nitems = fread (measure, sizeof(Measure), Nmeasure, f);
@@ -405,39 +492,55 @@
       }
       gfits_convert_Measure (measure, sizeof(Measure), Nmeasure);
-      break;
-    case DVO_FORMAT_ELIXIR:
-      ALLOCATE (tmpMeasureElixir, MeasureElixir, MAX (Nmeasure, 1));
-      nitems = fread (tmpMeasureElixir, sizeof(MeasureElixir), Nmeasure, f);
+      break; }
+    case DVO_FORMAT_ELIXIR: {
+      MeasureElixir *tmpMeasure;
+      ALLOCATE (tmpMeasure, MeasureElixir, MAX (Nmeasure, 1));
+      nitems = fread (tmpMeasure, sizeof(MeasureElixir), Nmeasure, f);
       if (nitems != Nmeasure) {
 	fprintf (stderr, "failed to read measures (%d vs %d)\n", nitems, Nmeasure);
 	return (NULL);
       }
-      gfits_convert_MeasureElixir (tmpMeasureElixir, sizeof(MeasureElixir), Nmeasure);
-      measure = MeasureElixirToInternal (tmpMeasureElixir, Nmeasure);
-      free (tmpMeasureElixir);
-      break;
-    case DVO_FORMAT_LONEOS:
-      ALLOCATE (tmpMeasureLoneos, MeasureLoneos, MAX (Nmeasure, 1));
-      nitems = fread (tmpMeasureLoneos, sizeof(MeasureLoneos), Nmeasure, f);
+      gfits_convert_MeasureElixir (tmpMeasure, sizeof(MeasureElixir), Nmeasure);
+      measure = MeasureElixirToInternal (tmpMeasure, Nmeasure);
+      free (tmpMeasure);
+      break; }
+    case DVO_FORMAT_LONEOS: {
+      MeasureLoneos *tmpMeasure;
+      ALLOCATE (tmpMeasure, MeasureLoneos, MAX (Nmeasure, 1));
+      nitems = fread (tmpMeasure, sizeof(MeasureLoneos), Nmeasure, f);
       if (nitems != Nmeasure) {
 	fprintf (stderr, "failed to read measures (%d vs %d)\n", nitems, Nmeasure);
 	return (NULL);
       }
-      gfits_convert_MeasureLoneos (tmpMeasureLoneos, sizeof(MeasureLoneos), Nmeasure);
-      measure = MeasureLoneosToInternal (tmpMeasureLoneos, Nmeasure);
-      free (tmpMeasureLoneos);
-      break;
-    case DVO_FORMAT_PANSTARRS:
-    case DVO_FORMAT_PMTEST:
-      ALLOCATE (tmpMeasurePanstarrs, MeasurePanstarrs, MAX (Nmeasure, 1));
-      nitems = fread (tmpMeasurePanstarrs, sizeof(MeasurePanstarrs), Nmeasure, f);
+      gfits_convert_MeasureLoneos (tmpMeasure, sizeof(MeasureLoneos), Nmeasure);
+      measure = MeasureLoneosToInternal (tmpMeasure, Nmeasure);
+      free (tmpMeasure);
+      break; }
+    case DVO_FORMAT_PANSTARRS_DEV_0: {
+      MeasurePanstarrs_DEV_0 *tmpMeasure;
+      ALLOCATE (tmpMeasure, MeasurePanstarrs_DEV_0, MAX (Nmeasure, 1));
+      nitems = fread (tmpMeasure, sizeof(MeasurePanstarrs_DEV_0), Nmeasure, f);
       if (nitems != Nmeasure) {
 	fprintf (stderr, "failed to read measures (%d vs %d)\n", nitems, Nmeasure);
 	return (NULL);
       }
-      gfits_convert_MeasurePanstarrs (tmpMeasurePanstarrs, sizeof(MeasurePanstarrs), Nmeasure);
-      measure = MeasurePanstarrsToInternal (tmpMeasurePanstarrs, Nmeasure);
-      free (tmpMeasurePanstarrs);
-      break;
+      gfits_convert_MeasurePanstarrs_DEV_0 (tmpMeasure, sizeof(MeasurePanstarrs_DEV_0), Nmeasure);
+      measure = MeasurePanstarrs_DEV_0_ToInternal (tmpMeasure, Nmeasure);
+      free (tmpMeasure);
+      break; }
+# if 0
+    case DVO_FORMAT_PANSTARRS: {
+      MeasurePanstarrs *tmpMeasure;
+      ALLOCATE (tmpMeasure, MeasurePanstarrs, MAX (Nmeasure, 1));
+      nitems = fread (tmpMeasure, sizeof(MeasurePanstarrs), Nmeasure, f);
+      if (nitems != Nmeasure) {
+	fprintf (stderr, "failed to read measures (%d vs %d)\n", nitems, Nmeasure);
+	return (NULL);
+      }
+      gfits_convert_MeasurePanstarrs (tmpMeasure, sizeof(MeasurePanstarrs), Nmeasure);
+      measure = MeasurePanstarrsToInternal (tmpMeasure, Nmeasure);
+      free (tmpMeasure);
+      break; }
+# endif
     default:
       fprintf (stderr, "error reading measures\n");
@@ -452,10 +555,7 @@
 
   int nitems;
-  MeasureElixir *tmpMeasureElixir;
-  MeasureLoneos *tmpMeasureLoneos;
-  MeasurePanstarrs *tmpMeasurePanstarrs;
 
   switch (format) {
-    case DVO_FORMAT_INTERNAL:
+    case DVO_FORMAT_INTERNAL: {
       gfits_convert_Measure (measure, sizeof(Measure), Nmeasure);
       nitems = fwrite (measure, sizeof(Measure), Nmeasure, f);
@@ -464,36 +564,51 @@
 	return (FALSE);
       }
-      break;
-    case DVO_FORMAT_ELIXIR:
-      tmpMeasureElixir = MeasureInternalToElixir (measure, Nmeasure);
-      gfits_convert_MeasureElixir (tmpMeasureElixir, sizeof(MeasureElixir), Nmeasure);
-      nitems = fwrite (tmpMeasureElixir, sizeof(MeasureElixir), Nmeasure, f);
-      free (tmpMeasureElixir);
+      break; }
+    case DVO_FORMAT_ELIXIR: {
+      MeasureElixir *tmpMeasure;
+      tmpMeasure = MeasureInternalToElixir (measure, Nmeasure);
+      gfits_convert_MeasureElixir (tmpMeasure, sizeof(MeasureElixir), Nmeasure);
+      nitems = fwrite (tmpMeasure, sizeof(MeasureElixir), Nmeasure, f);
+      free (tmpMeasure);
       if (nitems != Nmeasure) {
 	fprintf (stderr, "failed to write measures (%d vs %d)\n", nitems, Nmeasure);
 	return (FALSE);
       }
-      break;
-    case DVO_FORMAT_LONEOS:
-      tmpMeasureLoneos = MeasureInternalToLoneos (measure, Nmeasure);
-      gfits_convert_MeasureLoneos (tmpMeasureLoneos, sizeof(MeasureLoneos), Nmeasure);
-      nitems = fwrite (tmpMeasureLoneos, sizeof(MeasureLoneos), Nmeasure, f);
-      free (tmpMeasureLoneos);
+      break; }
+    case DVO_FORMAT_LONEOS: {
+      MeasureLoneos *tmpMeasure;
+      tmpMeasure = MeasureInternalToLoneos (measure, Nmeasure);
+      gfits_convert_MeasureLoneos (tmpMeasure, sizeof(MeasureLoneos), Nmeasure);
+      nitems = fwrite (tmpMeasure, sizeof(MeasureLoneos), Nmeasure, f);
+      free (tmpMeasure);
       if (nitems != Nmeasure) {
 	fprintf (stderr, "failed to write measures (%d vs %d)\n", nitems, Nmeasure);
 	return (FALSE);
       }
-      break;
-    case DVO_FORMAT_PANSTARRS:
-    case DVO_FORMAT_PMTEST:
-      tmpMeasurePanstarrs = MeasureInternalToPanstarrs (measure, Nmeasure);
-      gfits_convert_MeasurePanstarrs (tmpMeasurePanstarrs, sizeof(MeasurePanstarrs), Nmeasure);
-      nitems = fwrite (tmpMeasurePanstarrs, sizeof(MeasurePanstarrs), Nmeasure, f);
-      free (tmpMeasurePanstarrs);
+      break; }
+    case DVO_FORMAT_PANSTARRS_DEV_0: {
+      MeasurePanstarrs_DEV_0 *tmpMeasure;
+      tmpMeasure = MeasureInternalToPanstarrs_DEV_0 (measure, Nmeasure);
+      gfits_convert_MeasurePanstarrs_DEV_0 (tmpMeasure, sizeof(MeasurePanstarrs_DEV_0), Nmeasure);
+      nitems = fwrite (tmpMeasure, sizeof(MeasurePanstarrs_DEV_0), Nmeasure, f);
+      free (tmpMeasure);
       if (nitems != Nmeasure) {
 	fprintf (stderr, "failed to write measures (%d vs %d)\n", nitems, Nmeasure);
 	return (FALSE);
       }
-      break;
+      break; }
+# if 0
+    case DVO_FORMAT_PANSTARRS: {
+      MeasurePanstarrs *tmpMeasure;
+      tmpMeasure = MeasureInternalToPanstarrs (measure, Nmeasure);
+      gfits_convert_MeasurePanstarrs (tmpMeasure, sizeof(MeasurePanstarrs), Nmeasure);
+      nitems = fwrite (tmpMeasure, sizeof(MeasurePanstarrs), Nmeasure, f);
+      free (tmpMeasure);
+      if (nitems != Nmeasure) {
+	fprintf (stderr, "failed to write measures (%d vs %d)\n", nitems, Nmeasure);
+	return (FALSE);
+      }
+      break; }
+# endif
     default:
       fprintf (stderr, "error writing measures\n");
@@ -509,10 +624,7 @@
   int nitems;
   SecFilt *secfilt;
-  SecFiltElixir *tmpSecFiltElixir;
-  SecFiltLoneos *tmpSecFiltLoneos;
-  SecFiltPanstarrs *tmpSecFiltPanstarrs;
 
   switch (format) {
-    case DVO_FORMAT_INTERNAL:
+    case DVO_FORMAT_INTERNAL: {
       ALLOCATE (secfilt, SecFilt, MAX (Nsecfilt, 1));
       nitems = fread (secfilt, sizeof(SecFilt), Nsecfilt, f);
@@ -522,39 +634,55 @@
       }
       gfits_convert_SecFilt (secfilt, sizeof(SecFilt), Nsecfilt);
-      break;
-    case DVO_FORMAT_ELIXIR:
-      ALLOCATE (tmpSecFiltElixir, SecFiltElixir, MAX (Nsecfilt, 1));
-      nitems = fread (tmpSecFiltElixir, sizeof(SecFiltElixir), Nsecfilt, f);
+      break; }
+    case DVO_FORMAT_ELIXIR: {
+      SecFiltElixir *tmpSecFilt;
+      ALLOCATE (tmpSecFilt, SecFiltElixir, MAX (Nsecfilt, 1));
+      nitems = fread (tmpSecFilt, sizeof(SecFiltElixir), Nsecfilt, f);
       if (nitems != Nsecfilt) {
 	fprintf (stderr, "failed to read secfilts (%d vs %d)\n", nitems, Nsecfilt);
 	return (NULL);
       }
-      gfits_convert_SecFiltElixir (tmpSecFiltElixir, sizeof(SecFiltElixir), Nsecfilt);
-      secfilt = SecFiltElixirToInternal (tmpSecFiltElixir, Nsecfilt);
-      free (tmpSecFiltElixir);
-      break;
-    case DVO_FORMAT_LONEOS:
-      ALLOCATE (tmpSecFiltLoneos, SecFiltLoneos, MAX (Nsecfilt, 1));
-      nitems = fread (tmpSecFiltLoneos, sizeof(SecFiltLoneos), Nsecfilt, f);
+      gfits_convert_SecFiltElixir (tmpSecFilt, sizeof(SecFiltElixir), Nsecfilt);
+      secfilt = SecFiltElixirToInternal (tmpSecFilt, Nsecfilt);
+      free (tmpSecFilt);
+      break; }
+    case DVO_FORMAT_LONEOS: {
+      SecFiltLoneos *tmpSecFilt;
+      ALLOCATE (tmpSecFilt, SecFiltLoneos, MAX (Nsecfilt, 1));
+      nitems = fread (tmpSecFilt, sizeof(SecFiltLoneos), Nsecfilt, f);
       if (nitems != Nsecfilt) {
 	fprintf (stderr, "failed to read secfilts (%d vs %d)\n", nitems, Nsecfilt);
 	return (NULL);
       }
-      gfits_convert_SecFiltLoneos (tmpSecFiltLoneos, sizeof(SecFiltLoneos), Nsecfilt);
-      secfilt = SecFiltLoneosToInternal (tmpSecFiltLoneos, Nsecfilt);
-      free (tmpSecFiltLoneos);
-      break;
-    case DVO_FORMAT_PANSTARRS:
-    case DVO_FORMAT_PMTEST:
-      ALLOCATE (tmpSecFiltPanstarrs, SecFiltPanstarrs, MAX (Nsecfilt, 1));
-      nitems = fread (tmpSecFiltPanstarrs, sizeof(SecFiltPanstarrs), Nsecfilt, f);
+      gfits_convert_SecFiltLoneos (tmpSecFilt, sizeof(SecFiltLoneos), Nsecfilt);
+      secfilt = SecFiltLoneosToInternal (tmpSecFilt, Nsecfilt);
+      free (tmpSecFilt);
+      break; }
+    case DVO_FORMAT_PANSTARRS_DEV_0: {
+      SecFiltPanstarrs_DEV_0 *tmpSecFilt;
+      ALLOCATE (tmpSecFilt, SecFiltPanstarrs_DEV_0, MAX (Nsecfilt, 1));
+      nitems = fread (tmpSecFilt, sizeof(SecFiltPanstarrs_DEV_0), Nsecfilt, f);
       if (nitems != Nsecfilt) {
 	fprintf (stderr, "failed to read secfilts (%d vs %d)\n", nitems, Nsecfilt);
 	return (NULL);
       }
-      gfits_convert_SecFiltPanstarrs (tmpSecFiltPanstarrs, sizeof(SecFiltPanstarrs), Nsecfilt);
-      secfilt = SecFiltPanstarrsToInternal (tmpSecFiltPanstarrs, Nsecfilt);
-      free (tmpSecFiltPanstarrs);
-      break;
+      gfits_convert_SecFiltPanstarrs_DEV_0 (tmpSecFilt, sizeof(SecFiltPanstarrs_DEV_0), Nsecfilt);
+      secfilt = SecFiltPanstarrs_DEV_0_ToInternal (tmpSecFilt, Nsecfilt);
+      free (tmpSecFilt);
+      break; }
+# if 0
+    case DVO_FORMAT_PANSTARRS: {
+      SecFiltPanstarrs *tmpSecFilt;
+      ALLOCATE (tmpSecFilt, SecFiltPanstarrs, MAX (Nsecfilt, 1));
+      nitems = fread (tmpSecFilt, sizeof(SecFiltPanstarrs), Nsecfilt, f);
+      if (nitems != Nsecfilt) {
+	fprintf (stderr, "failed to read secfilts (%d vs %d)\n", nitems, Nsecfilt);
+	return (NULL);
+      }
+      gfits_convert_SecFiltPanstarrs (tmpSecFilt, sizeof(SecFiltPanstarrs), Nsecfilt);
+      secfilt = SecFiltPanstarrsToInternal (tmpSecFilt, Nsecfilt);
+      free (tmpSecFilt);
+      break; }
+# endif
     default:
       fprintf (stderr, "error reading measures\n");
@@ -569,10 +697,7 @@
 
   int nitems;
-  SecFiltElixir *tmpSecFiltElixir;
-  SecFiltLoneos *tmpSecFiltLoneos;
-  SecFiltPanstarrs *tmpSecFiltPanstarrs;
 
   switch (format) {
-    case DVO_FORMAT_INTERNAL:
+    case DVO_FORMAT_INTERNAL: {
       gfits_convert_SecFilt (secfilt, sizeof(SecFilt), Nsecfilt);
       nitems = fwrite (secfilt, sizeof(SecFilt), Nsecfilt, f);
@@ -581,36 +706,51 @@
 	return (FALSE);
       }
-      break;
-    case DVO_FORMAT_ELIXIR:
-      tmpSecFiltElixir = SecFiltInternalToElixir (secfilt, Nsecfilt);
-      gfits_convert_SecFiltElixir (tmpSecFiltElixir, sizeof(SecFiltElixir), Nsecfilt);
-      nitems = fwrite (tmpSecFiltElixir, sizeof(SecFiltElixir), Nsecfilt, f);
-      free (tmpSecFiltElixir);
+      break; }
+    case DVO_FORMAT_ELIXIR: {
+      SecFiltElixir *tmpSecFilt;
+      tmpSecFilt = SecFiltInternalToElixir (secfilt, Nsecfilt);
+      gfits_convert_SecFiltElixir (tmpSecFilt, sizeof(SecFiltElixir), Nsecfilt);
+      nitems = fwrite (tmpSecFilt, sizeof(SecFiltElixir), Nsecfilt, f);
+      free (tmpSecFilt);
       if (nitems != Nsecfilt) {
 	fprintf (stderr, "failed to write secfilts (%d vs %d)\n", nitems, Nsecfilt);
 	return (FALSE);
       }
-      break;
-    case DVO_FORMAT_LONEOS:
-      tmpSecFiltLoneos = SecFiltInternalToLoneos (secfilt, Nsecfilt);
-      gfits_convert_SecFiltLoneos (tmpSecFiltLoneos, sizeof(SecFiltLoneos), Nsecfilt);
-      nitems = fwrite (tmpSecFiltLoneos, sizeof(SecFiltLoneos), Nsecfilt, f);
-      free (tmpSecFiltLoneos);
+      break; }
+    case DVO_FORMAT_LONEOS: {
+      SecFiltLoneos *tmpSecFilt;
+      tmpSecFilt = SecFiltInternalToLoneos (secfilt, Nsecfilt);
+      gfits_convert_SecFiltLoneos (tmpSecFilt, sizeof(SecFiltLoneos), Nsecfilt);
+      nitems = fwrite (tmpSecFilt, sizeof(SecFiltLoneos), Nsecfilt, f);
+      free (tmpSecFilt);
       if (nitems != Nsecfilt) {
 	fprintf (stderr, "failed to write secfilts (%d vs %d)\n", nitems, Nsecfilt);
 	return (FALSE);
       }
-      break;
-    case DVO_FORMAT_PANSTARRS:
-    case DVO_FORMAT_PMTEST:
-      tmpSecFiltPanstarrs = SecFiltInternalToPanstarrs (secfilt, Nsecfilt);
-      gfits_convert_SecFiltPanstarrs (tmpSecFiltPanstarrs, sizeof(SecFiltPanstarrs), Nsecfilt);
-      nitems = fwrite (tmpSecFiltPanstarrs, sizeof(SecFiltPanstarrs), Nsecfilt, f);
-      free (tmpSecFiltPanstarrs);
+      break; }
+    case DVO_FORMAT_PANSTARRS_DEV_0: {
+      SecFiltPanstarrs_DEV_0 *tmpSecFilt;
+      tmpSecFilt = SecFiltInternalToPanstarrs_DEV_0 (secfilt, Nsecfilt);
+      gfits_convert_SecFiltPanstarrs_DEV_0 (tmpSecFilt, sizeof(SecFiltPanstarrs_DEV_0), Nsecfilt);
+      nitems = fwrite (tmpSecFilt, sizeof(SecFiltPanstarrs_DEV_0), Nsecfilt, f);
+      free (tmpSecFilt);
       if (nitems != Nsecfilt) {
 	fprintf (stderr, "failed to write secfilts (%d vs %d)\n", nitems, Nsecfilt);
 	return (FALSE);
       }
-      break;
+      break; }
+# if 0
+    case DVO_FORMAT_PANSTARRS: {
+      SecFiltPanstarrs *tmpSecFilt;
+      tmpSecFilt = SecFiltInternalToPanstarrs (secfilt, Nsecfilt);
+      gfits_convert_SecFiltPanstarrs (tmpSecFilt, sizeof(SecFiltPanstarrs), Nsecfilt);
+      nitems = fwrite (tmpSecFilt, sizeof(SecFiltPanstarrs), Nsecfilt, f);
+      free (tmpSecFilt);
+      if (nitems != Nsecfilt) {
+	fprintf (stderr, "failed to write secfilts (%d vs %d)\n", nitems, Nsecfilt);
+	return (FALSE);
+      }
+      break; }
+# endif
     default:
       fprintf (stderr, "error writing secfilts\n");
Index: trunk/Ohana/src/libdvo/src/dvo_catalog_split.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_catalog_split.c	(revision 11991)
+++ trunk/Ohana/src/libdvo/src/dvo_catalog_split.c	(revision 12332)
@@ -8,4 +8,5 @@
   Matrix matrix;
   FTable ftable;
+  SecFilt *primary;
   Catalog *measure, *missing, *secfilt;
 
@@ -54,5 +55,6 @@
       return (FALSE);
     }
-    catalog[0].average = FtableToAverage (&ftable, &catalog[0].Naverage, &catalog[0].catformat);
+    /* old versions of DVO stored one of the average magnitudes in Average. we save this if needed */
+    catalog[0].average = FtableToAverage (&ftable, &catalog[0].Naverage, &catalog[0].catformat, &primary);
     if (Naverage != catalog[0].Naverage) {
       fprintf (stderr, "Warning: mismatch between Naverage in PHU and Table headers (%d vs %d)\n", Naverage, catalog[0].Naverage);
@@ -240,7 +242,32 @@
       fprintf (stderr, "Warning: mismatch between Nsecfilt items in PHU and Table headers (%d vs %d)\n", Nexpect, Nitems);
     }
+
+    /* if primary is defined, we were supplied with one additional average magnitude from Average
+       we need to interleave these magnitudes with the secfilt entries just loaded */
+    if (primary != NULL) {
+      int Ntmpfilt, Ntotal, i, j;
+      SecFilt *tmpfilt;
+      tmpfilt  = catalog[0].secfilt;
+      Ntmpfilt = catalog[0].Nsecfilt;
+      Nsecfilt = catalog[0].Nsecfilt + 1;
+      Ntotal = Nsecfilt * catalog[0].Naverage;
+      ALLOCATE (catalog[0].secfilt, SecFilt, Ntotal);
+      for (i = 0; i < catalog[0].Naverage; i++) {
+	catalog[0].secfilt[i*Nsecfilt + 0] = primary[i];
+	for (j = 0; j < Ntmpfilt; j++) {
+	  catalog[0].secfilt[i*Nsecfilt + j + 1] = tmpfilt[i*Ntmpfilt + j];
+	}
+      }		
+      catalog[0].Nsecfilt = Nsecfilt;
+      free (primary);
+    } 
+
+
     gfits_free_header (&header);
     gfits_free_matrix (&matrix);
-  } 
+  } else {
+    if (primary != NULL) free (primary);
+  }
+
   catalog[0].secfilt_catalog = secfilt;
 
@@ -254,5 +281,4 @@
 
 /* save_catalog_split writes complete new files from scratch */
-
 int dvo_catalog_save_split (Catalog *catalog, char VERBOSE) {
 
@@ -261,5 +287,7 @@
   Header header;
   FTable ftable;
-  Catalog *measure, *missing, *secfilt;
+  Catalog *catfile;
+  SecFilt *primary, *secfilt;
+  int i, j, Nsecfilt, Nallfilt, Ntotal;
 
   ftable.header = &header;
@@ -289,4 +317,31 @@
   /* in split mode, we can save only part of the data */ 
 
+  /* for the appropriate types, pull out the first secfilt and pass to AverageToFtable as primary */
+  if ((catalog[0].catformat == DVO_FORMAT_ELIXIR) || // special case for ELIXIR
+      (catalog[0].catformat == DVO_FORMAT_LONEOS)) { // special case for LONEOS
+    if (catalog[0].secfilt == NULL) {       
+      fprintf (stderr, "missing secfilt, cannot build output averages (dvo_catalog_split.c:544)\n");
+      exit (1);
+    }
+    secfilt = catalog[0].secfilt;
+
+    Nallfilt = catalog[0].Nsecfilt;
+    Nsecfilt = catalog[0].Nsecfilt - 1;
+    Ntotal = Nsecfilt * catalog[0].Naverage;
+    ALLOCATE (primary, SecFilt, catalog[0].Naverage);
+    ALLOCATE (secfilt, SecFilt, Ntotal);
+
+    for (i = 0; i < catalog[0].Naverage; i++) {
+      primary[i] = secfilt[i*Nallfilt + 0];
+      for (j = 0; j < Nsecfilt; j++) {
+	secfilt[i*Nsecfilt + j] = catalog[0].secfilt[i*Nallfilt + j + 1];
+      }
+    }		
+  } else {
+    primary = NULL;
+    secfilt = catalog[0].secfilt;
+    Nsecfilt = catalog[0].Nsecfilt;
+  }
+
   /*** Average Table ***/
 
@@ -303,5 +358,5 @@
 
     /* write out Average table (convert to FITS table format) */
-    AverageToFtable (&ftable, catalog[0].average, catalog[0].Naverage, catalog[0].catformat);
+    AverageToFtable (&ftable, catalog[0].average, catalog[0].Naverage, catalog[0].catformat, primary);
     if (!gfits_fwrite_Theader (catalog[0].f, &header)) {
       fprintf (stderr, "can't write table header");
@@ -317,8 +372,8 @@
 
   /*** Measure Table ***/
-
   if (catalog[0].measure != NULL) {
 
-    measure = catalog[0].measure_catalog;
+    /* catalog file data is stored in separate structure */
+    catfile = catalog[0].measure_catalog;
 
     /* XXX EAM : warn about this condition; add code to handle? */
@@ -329,9 +384,9 @@
 
     /* rewind file pointers and truncate (file is still open) */
-    fseek (measure[0].f, 0, SEEK_SET);
-    ftruncate (fileno (measure[0].f), 0);
+    fseek (catfile[0].f, 0, SEEK_SET);
+    ftruncate (fileno (catfile[0].f), 0);
 
     /* write table PHU header */
-    if (!gfits_fwrite_header  (measure[0].f, &measure[0].header)) {
+    if (!gfits_fwrite_header  (catfile[0].f, &catfile[0].header)) {
       fprintf (stderr, "can't write primary header");
       return (FALSE);
@@ -339,6 +394,6 @@
 
     /* this is probably a NOP, do I have to keep it in? */
-    gfits_create_matrix (&measure[0].header, &matrix);
-    if (!gfits_fwrite_matrix  (measure[0].f, &matrix)) {
+    gfits_create_matrix (&catfile[0].header, &matrix);
+    if (!gfits_fwrite_matrix  (catfile[0].f, &matrix)) {
       fprintf (stderr, "can't write primary matrix");
       return (FALSE);
@@ -348,9 +403,9 @@
     /* write out Measure table (convert to FITS table format) */
     MeasureToFtable (&ftable, catalog[0].measure, catalog[0].Nmeasure, catalog[0].catformat);
-    if (!gfits_fwrite_Theader (measure[0].f, &header)) {
+    if (!gfits_fwrite_Theader (catfile[0].f, &header)) {
       fprintf (stderr, "can't write table header");
       return (FALSE);
     }
-    if (!gfits_fwrite_table (measure[0].f, &ftable)) {
+    if (!gfits_fwrite_table (catfile[0].f, &ftable)) {
       fprintf (stderr, "can't write table data");
       return (FALSE);
@@ -361,15 +416,15 @@
 
   /*** Missing Table ***/
-
   if (catalog[0].missing != NULL) {
 
-    missing = catalog[0].missing_catalog;
+    /* catalog data is stored in separate catalog */
+    catfile = catalog[0].missing_catalog;
 
     /* rewind file pointers and truncate (file is still open) */
-    fseek (missing[0].f, 0, SEEK_SET);
-    ftruncate (fileno (missing[0].f), 0);
+    fseek (catfile[0].f, 0, SEEK_SET);
+    ftruncate (fileno (catfile[0].f), 0);
 
     /* write table PHU header */
-    if (!gfits_fwrite_header  (missing[0].f, &missing[0].header)) {
+    if (!gfits_fwrite_header  (catfile[0].f, &catfile[0].header)) {
       fprintf (stderr, "can't write primary header");
       return (FALSE);
@@ -377,6 +432,6 @@
 
     /* this is probably a NOP, do I have to keep it in? */
-    gfits_create_matrix (&missing[0].header, &matrix);
-    if (!gfits_fwrite_matrix  (missing[0].f, &matrix)) {
+    gfits_create_matrix (&catfile[0].header, &matrix);
+    if (!gfits_fwrite_matrix  (catfile[0].f, &matrix)) {
       fprintf (stderr, "can't write primary matrix");
       return (FALSE);
@@ -386,9 +441,9 @@
     /* write out Missing table (convert to FITS table format) */
     gfits_table_set_Missing (&ftable, catalog[0].missing, catalog[0].Nmissing);
-    if (!gfits_fwrite_Theader (missing[0].f, &header)) {
+    if (!gfits_fwrite_Theader (catfile[0].f, &header)) {
       fprintf (stderr, "can't write table header");
       return (FALSE);
     }
-    if (!gfits_fwrite_table (missing[0].f, &ftable)) {
+    if (!gfits_fwrite_table (catfile[0].f, &ftable)) {
       fprintf (stderr, "can't write table data");
       return (FALSE);
@@ -399,15 +454,15 @@
 
   /*** Secfilt Table ***/
-
   if (catalog[0].secfilt != NULL) {
 
-    secfilt = catalog[0].secfilt_catalog;
+    /* catalog file data is stored in a separate catalog structure */
+    catfile = catalog[0].secfilt_catalog;
 
     /* rewind file pointers and truncate (file is still open) */
-    fseek (secfilt[0].f, 0, SEEK_SET);
-    ftruncate (fileno (secfilt[0].f), 0);
+    fseek (catfile[0].f, 0, SEEK_SET);
+    ftruncate (fileno (catfile[0].f), 0);
 
     /* write table PHU header */
-    if (!gfits_fwrite_header  (secfilt[0].f, &secfilt[0].header)) {
+    if (!gfits_fwrite_header  (catfile[0].f, &catfile[0].header)) {
       fprintf (stderr, "can't write primary header");
       return (FALSE);
@@ -415,6 +470,6 @@
 
     /* this is probably a NOP, do I have to keep it in? */
-    gfits_create_matrix (&secfilt[0].header, &matrix);
-    if (!gfits_fwrite_matrix  (secfilt[0].f, &matrix)) {
+    gfits_create_matrix (&catfile[0].header, &matrix);
+    if (!gfits_fwrite_matrix  (catfile[0].f, &matrix)) {
       fprintf (stderr, "can't write primary matrix");
       return (FALSE);
@@ -424,10 +479,10 @@
     /* write out SecFilt table (convert to FITS table format) */
     Nitems = catalog[0].Naverage * catalog[0].Nsecfilt;
-    SecFiltToFtable (&ftable, catalog[0].secfilt, Nitems, catalog[0].catformat);
-    if (!gfits_fwrite_Theader (secfilt[0].f, &header)) {
+    SecFiltToFtable (&ftable, secfilt, Nitems, catalog[0].catformat);
+    if (!gfits_fwrite_Theader (catfile[0].f, &header)) {
       fprintf (stderr, "can't write table header");
       return (FALSE);
     }
-    if (!gfits_fwrite_table (secfilt[0].f, &ftable)) {
+    if (!gfits_fwrite_table (catfile[0].f, &ftable)) {
       fprintf (stderr, "can't write table data");
       return (FALSE);
@@ -435,4 +490,10 @@
     gfits_free_table (&ftable);
     gfits_free_header (&header);
+  }
+
+  /* free temp storage */
+  if (primary != NULL) {
+    free (primary);
+    free (secfilt);
   }
 
@@ -453,5 +514,7 @@
   FTable ftable;
   VTable vtable;
-  Catalog *measure, *missing, *secfilt;
+  Catalog *catfile;
+  SecFilt *primary, *secfilt;
+  int j, Nsecfilt, Nallfilt, Ntotal;
 
   ftable.header = &header;
@@ -480,6 +543,32 @@
   }
 
+  /** for the appropriate types, pull out the first secfilt and pass to AverageToFtable as primary **/
+  if ((catalog[0].catformat == DVO_FORMAT_ELIXIR) || // special case for ELIXIR
+      (catalog[0].catformat == DVO_FORMAT_LONEOS)) { // special case for LONEOS
+    if (catalog[0].secfilt == NULL) { 
+      fprintf (stderr, "missing secfilt, cannot build output averages (dvo_catalog_split.c:544)\n");
+      exit (1);
+    }
+    secfilt = catalog[0].secfilt;
+
+    Nallfilt = catalog[0].Nsecfilt;
+    Nsecfilt = catalog[0].Nsecfilt - 1;
+    Ntotal = Nsecfilt * catalog[0].Naverage;
+    ALLOCATE (primary, SecFilt, catalog[0].Naverage);
+    ALLOCATE (secfilt, SecFilt, Ntotal);
+
+    for (i = 0; i < catalog[0].Naverage; i++) {
+      primary[i] = secfilt[i*Nallfilt + 0];
+      for (j = 0; j < Nsecfilt; j++) {
+	secfilt[i*Nsecfilt + j] = catalog[0].secfilt[i*Nallfilt + j + 1];
+      }
+    }		
+  } else {
+    primary = NULL;
+    secfilt = catalog[0].secfilt;
+    Nsecfilt = catalog[0].Nsecfilt;
+  }
+
   /*** Average Table ***/
-
   if (catalog[0].average != NULL) {
 
@@ -492,5 +581,5 @@
 
     /* write out Average table (convert to FITS table format) */
-    AverageToFtable (&ftable, catalog[0].average, catalog[0].Naverage, catalog[0].catformat);
+    AverageToFtable (&ftable, catalog[0].average, catalog[0].Naverage, catalog[0].catformat, primary);
     /* convert only output rows to vtable */
     gfits_table_to_vtable (&ftable, &vtable, catalog[0].Nave_disk, Nout);
@@ -510,12 +599,11 @@
 
   /*** Measure Table ***/
-
   if (catalog[0].measure != NULL) {
 
-    measure = catalog[0].measure_catalog;
+    catfile = catalog[0].measure_catalog;
 
     /* skip past PHU header and matrix */
-    Nskip = measure[0].header.size + gfits_matrix_size (&measure[0].header);
-    fseek (measure[0].f, Nskip, SEEK_SET);
+    Nskip = catfile[0].header.size + gfits_matrix_size (&catfile[0].header);
+    fseek (catfile[0].f, Nskip, SEEK_SET);
 
     Ndisk  = catalog[0].Nmeas_disk;
@@ -547,9 +635,9 @@
     vtable.pad = vtable.size - Nx*Ny;
 
-    if (!gfits_fwrite_Theader (measure[0].f, &header)) {
+    if (!gfits_fwrite_Theader (catfile[0].f, &header)) {
       fprintf (stderr, "can't write table header");
       return (FALSE);
     }
-    if (!gfits_fwrite_vtable (measure[0].f, &vtable)) {
+    if (!gfits_fwrite_vtable (catfile[0].f, &vtable)) {
       fprintf (stderr, "can't write table data");
       return (FALSE);
@@ -566,12 +654,12 @@
   if (catalog[0].missing != NULL) {
 
-    missing = catalog[0].missing_catalog;
+    catfile = catalog[0].missing_catalog;
 
     /* rewind file pointers and truncate (file is still open) */
-    fseek (missing[0].f, 0, SEEK_SET);
-    ftruncate (fileno (missing[0].f), 0);
+    fseek (catfile[0].f, 0, SEEK_SET);
+    ftruncate (fileno (catfile[0].f), 0);
 
     /* write table PHU header */
-    if (!gfits_fwrite_header  (missing[0].f, &missing[0].header)) {
+    if (!gfits_fwrite_header  (catfile[0].f, &catfile[0].header)) {
       fprintf (stderr, "can't write primary header");
       return (FALSE);
@@ -579,6 +667,6 @@
 
     /* this is probably a NOP, do I have to keep it in? */
-    gfits_create_matrix (&missing[0].header, &matrix);
-    if (!gfits_fwrite_matrix  (missing[0].f, &matrix)) {
+    gfits_create_matrix (&catfile[0].header, &matrix);
+    if (!gfits_fwrite_matrix  (catfile[0].f, &matrix)) {
       fprintf (stderr, "can't write primary matrix");
       return (FALSE);
@@ -588,9 +676,9 @@
     /* write out Missing table (convert to FITS table format) */
     gfits_table_set_Missing (&ftable, catalog[0].missing, catalog[0].Nmissing);
-    if (!gfits_fwrite_Theader (missing[0].f, &header)) {
+    if (!gfits_fwrite_Theader (catfile[0].f, &header)) {
       fprintf (stderr, "can't write table header");
       return (FALSE);
     }
-    if (!gfits_fwrite_table (missing[0].f, &ftable)) {
+    if (!gfits_fwrite_table (catfile[0].f, &ftable)) {
       fprintf (stderr, "can't write table data");
       return (FALSE);
@@ -601,12 +689,11 @@
 
   /*** Secfilt Table ***/
-
   if (catalog[0].secfilt != NULL) {
 
-    secfilt = catalog[0].secfilt_catalog;
+    catfile = catalog[0].secfilt_catalog;
 
     /* skip past PHU header and matrix */
-    Nskip = secfilt[0].header.size + gfits_matrix_size (&secfilt[0].header);
-    fseek (secfilt[0].f, Nskip, SEEK_SET);
+    Nskip = catfile[0].header.size + gfits_matrix_size (&catfile[0].header);
+    fseek (catfile[0].f, Nskip, SEEK_SET);
 
     /* how many lines to write out? */
@@ -616,13 +703,13 @@
     /* convert to output format FITS table */
     Nitems = catalog[0].Naverage * catalog[0].Nsecfilt;
-    SecFiltToFtable (&ftable, catalog[0].secfilt, Nitems, catalog[0].catformat);
+    SecFiltToFtable (&ftable, secfilt, Nitems, catalog[0].catformat);
     /* convert only output rows to vtable */
     gfits_table_to_vtable (&ftable, &vtable, Ndisk, Nout);
 
-    if (!gfits_fwrite_Theader (secfilt[0].f, &header)) {
+    if (!gfits_fwrite_Theader (catfile[0].f, &header)) {
       fprintf (stderr, "can't write table header");
       return (FALSE);
     }
-    if (!gfits_fwrite_vtable (secfilt[0].f, &vtable)) {
+    if (!gfits_fwrite_vtable (catfile[0].f, &vtable)) {
       fprintf (stderr, "can't write table data");
       return (FALSE);
@@ -631,4 +718,10 @@
     gfits_free_table (&ftable);
     gfits_free_header (&header);
+  }
+
+  /* free temp storage */
+  if (primary != NULL) {
+    free (primary);
+    free (secfilt);
   }
 
Index: trunk/Ohana/src/libdvo/src/dvo_convert.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_convert.c	(revision 11991)
+++ trunk/Ohana/src/libdvo/src/dvo_convert.c	(revision 12332)
@@ -13,8 +13,12 @@
 /*** Average / FTable conversion functions ***/
 
-Average *FtableToAverage (FTable *ftable, int *Naverage, int *format) {
+Average *FtableToAverage (FTable *ftable, int *Naverage, int *format, SecFilt **primary) {
 
   Average *average;
   char extname[80];
+
+  /* in the Elixir and Loneos cases, we are supplied with an average magnitude in Average
+     in these cases, save these values in primary; otherwise set primary to NULL */
+  *primary = NULL;
 
   /* convert to the internal format */
@@ -31,5 +35,5 @@
     AverageElixir *tmpAverage;
     tmpAverage = gfits_table_get_AverageElixir (ftable, Naverage, NULL);
-    average = AverageElixirToInternal (tmpAverage, *Naverage);
+    average = AverageElixirToInternal (tmpAverage, *Naverage, primary);
     free (tmpAverage);
     *format = DVO_FORMAT_ELIXIR;
@@ -39,9 +43,21 @@
     AverageLoneos *tmpAverage;
     tmpAverage = gfits_table_get_AverageLoneos (ftable, Naverage, NULL);
-    average = AverageLoneosToInternal (tmpAverage, *Naverage);
+    average = AverageLoneosToInternal (tmpAverage, *Naverage, primary);
     free (tmpAverage);
     *format = DVO_FORMAT_LONEOS;
     return (average);
   }
+  if (!strcmp (extname, "DVO_AVERAGE_PANSTARRS_DEV_0")) {
+    AveragePanstarrs_DEV_0 *tmpAverage;
+    tmpAverage = gfits_table_get_AveragePanstarrs_DEV_0 (ftable, Naverage, NULL);
+    average = AveragePanstarrs_DEV_0_ToInternal (tmpAverage, *Naverage);
+    free (tmpAverage);
+    *format = DVO_FORMAT_PANSTARRS_DEV_0;
+    return (average);
+  }
+/* disable the new and minimally-used versions for now.  
+   put them back in after dev work is further along
+   OR replace with other output formats */
+# if 0
   if (!strcmp (extname, "DVO_AVERAGE_PANSTARRS")) {
     AveragePanstarrs *tmpAverage;
@@ -60,4 +76,5 @@
     return (average);
   }
+# endif
 
   fprintf (stderr, "table format unknown: %s\n", extname);
@@ -67,36 +84,44 @@
 }
 
-int AverageToFtable (FTable *ftable, Average *average, int Naverage, int format) {
-
-  AverageElixir *tmpAverageElixir;
-  AverageLoneos *tmpAverageLoneos ;
-  AveragePanstarrs *tmpAveragePanstarrs;
-  AveragePMtest *tmpAveragePMtest;
+int AverageToFtable (FTable *ftable, Average *average, int Naverage, int format, SecFilt *primary) {
+
 
   /* convert from the internal format */
   switch (format) {
-    case DVO_FORMAT_INTERNAL:
+    case DVO_FORMAT_INTERNAL: {
       gfits_table_set_Average (ftable, average, Naverage);
-      break;
-    case DVO_FORMAT_ELIXIR:
-      tmpAverageElixir = AverageInternalToElixir (average, Naverage);
-      gfits_table_set_AverageElixir (ftable, tmpAverageElixir, Naverage);
-      free (tmpAverageElixir);
-      break;
-    case DVO_FORMAT_LONEOS:
-      tmpAverageLoneos  = AverageInternalToLoneos (average, Naverage);
-      gfits_table_set_AverageLoneos (ftable, tmpAverageLoneos , Naverage);
-      free (tmpAverageLoneos );
-      break;
-    case DVO_FORMAT_PANSTARRS:
-      tmpAveragePanstarrs = AverageInternalToPanstarrs (average, Naverage);
-      gfits_table_set_AveragePanstarrs (ftable, tmpAveragePanstarrs, Naverage);
-      free (tmpAveragePanstarrs);
-      break;
-    case DVO_FORMAT_PMTEST:
-      tmpAveragePMtest = AverageInternalToPMtest (average, Naverage);
-      gfits_table_set_AveragePMtest (ftable, tmpAveragePMtest, Naverage);
-      free (tmpAveragePMtest);
-      break;
+      break; }
+    case DVO_FORMAT_ELIXIR: {
+      AverageElixir *tmpAverage;
+      tmpAverage = AverageInternalToElixir (average, Naverage, primary);
+      gfits_table_set_AverageElixir (ftable, tmpAverage, Naverage);
+      free (tmpAverage);
+      break; }
+    case DVO_FORMAT_LONEOS: {
+      AverageLoneos *tmpAverage ;
+      tmpAverage  = AverageInternalToLoneos (average, Naverage, primary);
+      gfits_table_set_AverageLoneos (ftable, tmpAverage, Naverage);
+      free (tmpAverage );
+      break; }
+    case DVO_FORMAT_PANSTARRS_DEV_0: {
+      AveragePanstarrs_DEV_0 *tmpAverage;
+      tmpAverage = AverageInternalToPanstarrs_DEV_0 (average, Naverage);
+      gfits_table_set_AveragePanstarrs_DEV_0 (ftable, tmpAverage, Naverage);
+      free (tmpAverage);
+      break; }
+# if 0
+    case DVO_FORMAT_PANSTARRS: {
+      AveragePanstarrs *tmpAverage;
+      tmpAverage = AverageInternalToPanstarrs (average, Naverage);
+      gfits_table_set_AveragePanstarrs (ftable, tmpAverage, Naverage);
+      free (tmpAverage);
+      break; }
+    case DVO_FORMAT_PMTEST: {
+      AveragePMtest *tmpAverage;
+      tmpAverage = AverageInternalToPMtest (average, Naverage);
+      gfits_table_set_AveragePMtest (ftable, tmpAverage, Naverage);
+      free (tmpAverage);
+      break; }
+# endif
     default:
       fprintf (stderr, "table format unknown (average)\n");
@@ -139,4 +164,13 @@
     return (measure);
   }
+  if (!strcmp (extname, "DVO_MEASURE_PANSTARRS_DEV_0")) {
+    MeasurePanstarrs_DEV_0 *tmpMeasure;
+    tmpMeasure = gfits_table_get_MeasurePanstarrs_DEV_0 (ftable, Nmeasure, NULL);
+    measure = MeasurePanstarrs_DEV_0_ToInternal (tmpMeasure, *Nmeasure);
+    free (tmpMeasure);
+    *format = DVO_FORMAT_PANSTARRS_DEV_0;
+    return (measure);
+  }
+# if 0
   if (!strcmp (extname, "DVO_MEASURE_PANSTARRS") || !strcmp (extname, "DVO_MEASURE_PMTEST")) {
     MeasurePanstarrs *tmpMeasure;
@@ -147,4 +181,5 @@
     return (measure);
   }
+# endif
 
   fprintf (stderr, "table format unknown: %s\n", extname);
@@ -156,29 +191,36 @@
 int MeasureToFtable (FTable *ftable, Measure *measure, int Nmeasure, int format) {
 
-  MeasureElixir *tmpMeasureElixir;
-  MeasureLoneos *tmpMeasureLoneos;
-  MeasurePanstarrs *tmpMeasurePanstarrs;
 
   /* convert from the internal format */
   switch (format) {
-    case DVO_FORMAT_INTERNAL:
+    case DVO_FORMAT_INTERNAL: {
       gfits_table_set_Measure (ftable, measure, Nmeasure);
-      break;
-    case DVO_FORMAT_ELIXIR:
-      tmpMeasureElixir = MeasureInternalToElixir (measure, Nmeasure);
-      gfits_table_set_MeasureElixir (ftable, tmpMeasureElixir, Nmeasure);
-      free (tmpMeasureElixir);
-      break;
-    case DVO_FORMAT_LONEOS:
-      tmpMeasureLoneos = MeasureInternalToLoneos (measure, Nmeasure);
-      gfits_table_set_MeasureLoneos (ftable, tmpMeasureLoneos, Nmeasure);
-      free (tmpMeasureLoneos);
-      break;
-    case DVO_FORMAT_PANSTARRS:
-    case DVO_FORMAT_PMTEST:
-      tmpMeasurePanstarrs = MeasureInternalToPanstarrs (measure, Nmeasure);
-      gfits_table_set_MeasurePanstarrs (ftable, tmpMeasurePanstarrs, Nmeasure);
-      free (tmpMeasurePanstarrs);
-      break;
+      break; }
+    case DVO_FORMAT_ELIXIR: {
+      MeasureElixir *tmpMeasure;
+      tmpMeasure = MeasureInternalToElixir (measure, Nmeasure);
+      gfits_table_set_MeasureElixir (ftable, tmpMeasure, Nmeasure);
+      free (tmpMeasure);
+      break; }
+    case DVO_FORMAT_LONEOS: {
+      MeasureLoneos *tmpMeasure;
+      tmpMeasure = MeasureInternalToLoneos (measure, Nmeasure);
+      gfits_table_set_MeasureLoneos (ftable, tmpMeasure, Nmeasure);
+      free (tmpMeasure);
+      break; }
+    case DVO_FORMAT_PANSTARRS_DEV_0: {
+      MeasurePanstarrs_DEV_0 *tmpMeasure;
+      tmpMeasure = MeasureInternalToPanstarrs_DEV_0 (measure, Nmeasure);
+      gfits_table_set_MeasurePanstarrs_DEV_0 (ftable, tmpMeasure, Nmeasure);
+      free (tmpMeasure);
+      break; }
+# if 0
+    case DVO_FORMAT_PANSTARRS: {
+      MeasurePanstarrs *tmpMeasure;
+      tmpMeasure = MeasureInternalToPanstarrs (measure, Nmeasure);
+      gfits_table_set_MeasurePanstarrs (ftable, tmpMeasure, Nmeasure);
+      free (tmpMeasure);
+      break; }
+# endif
     default:
       fprintf (stderr, "table format unknown (measure)\n");
@@ -221,4 +263,13 @@
     return (secfilt);
   }
+  if (!strcmp (extname, "DVO_SECFILT_PANSTARRS_DEV_0")) {
+    SecFiltPanstarrs_DEV_0 *tmpSecFilt;
+    tmpSecFilt = gfits_table_get_SecFiltPanstarrs_DEV_0 (ftable, Nsecfilt, NULL);
+    secfilt = SecFiltPanstarrs_DEV_0_ToInternal (tmpSecFilt, *Nsecfilt);
+    free (tmpSecFilt);
+    *format = DVO_FORMAT_PANSTARRS_DEV_0;
+    return (secfilt);
+  }
+# if 0
   if (!strcmp (extname, "DVO_SECFILT_PANSTARRS") || !strcmp (extname, "DVO_SECFILT_PMTEST")) {
     SecFiltPanstarrs *tmpSecFilt;
@@ -229,4 +280,5 @@
     return (secfilt);
   }
+# endif
 
   fprintf (stderr, "table format unknown: %s\n", extname);
@@ -238,29 +290,35 @@
 int SecFiltToFtable (FTable *ftable, SecFilt *secfilt, int Nsecfilt, int format) {
 
-  SecFiltElixir *tmpSecFiltElixir;
-  SecFiltLoneos *tmpSecFiltLoneos;
-  SecFiltPanstarrs *tmpSecFiltPanstarrs;
-
   /* convert from the internal format */
   switch (format) {
-    case DVO_FORMAT_INTERNAL:
+    case DVO_FORMAT_INTERNAL: {
       gfits_table_set_SecFilt (ftable, secfilt, Nsecfilt);
-      break;
-    case DVO_FORMAT_ELIXIR:
-      tmpSecFiltElixir = SecFiltInternalToElixir (secfilt, Nsecfilt);
-      gfits_table_set_SecFiltElixir (ftable, tmpSecFiltElixir, Nsecfilt);
-      free (tmpSecFiltElixir);
-      break;
-    case DVO_FORMAT_LONEOS:
-      tmpSecFiltLoneos = SecFiltInternalToLoneos (secfilt, Nsecfilt);
-      gfits_table_set_SecFiltLoneos (ftable, tmpSecFiltLoneos, Nsecfilt);
-      free (tmpSecFiltLoneos);
-      break;
-    case DVO_FORMAT_PANSTARRS:
-    case DVO_FORMAT_PMTEST:
-      tmpSecFiltPanstarrs = SecFiltInternalToPanstarrs (secfilt, Nsecfilt);
-      gfits_table_set_SecFiltPanstarrs (ftable, tmpSecFiltPanstarrs, Nsecfilt);
-      free (tmpSecFiltPanstarrs);
-      break;
+      break; }
+    case DVO_FORMAT_ELIXIR: {
+      SecFiltElixir *tmpSecFilt;
+      tmpSecFilt = SecFiltInternalToElixir (secfilt, Nsecfilt);
+      gfits_table_set_SecFiltElixir (ftable, tmpSecFilt, Nsecfilt);
+      free (tmpSecFilt);
+      break; }
+    case DVO_FORMAT_LONEOS: {
+      SecFiltLoneos *tmpSecFilt;
+      tmpSecFilt = SecFiltInternalToLoneos (secfilt, Nsecfilt);
+      gfits_table_set_SecFiltLoneos (ftable, tmpSecFilt, Nsecfilt);
+      free (tmpSecFilt);
+      break; }
+    case DVO_FORMAT_PANSTARRS_DEV_0: {
+      SecFiltPanstarrs_DEV_0 *tmpSecFilt;
+      tmpSecFilt = SecFiltInternalToPanstarrs_DEV_0 (secfilt, Nsecfilt);
+      gfits_table_set_SecFiltPanstarrs_DEV_0 (ftable, tmpSecFilt, Nsecfilt);
+      free (tmpSecFilt);
+      break; }
+# if 0
+    case DVO_FORMAT_PANSTARRS: {
+      SecFiltPanstarrs *tmpSecFilt;
+      tmpSecFilt = SecFiltInternalToPanstarrs (secfilt, Nsecfilt);
+      gfits_table_set_SecFiltPanstarrs (ftable, tmpSecFilt, Nsecfilt);
+      free (tmpSecFilt);
+      break; }
+# endif
     default:
       fprintf (stderr, "table format unknown (secfilt)\n");
@@ -278,5 +336,5 @@
 
   /* extname may be set from outside if the source is RAW not MEF */
-  if (*format == DVO_FORMAT_ELIXIR) {
+  if (*format == DVO_FORMAT_ELIXIR) {		  // special case for ELIXIR
     ImageElixir *tmpimage;
     tmpimage = gfits_table_get_ImageElixir (ftable, &Nimage, NULL);
@@ -313,4 +371,13 @@
     goto set_header;
   }
+  if (!strcmp (extname, "DVO_IMAGE_PANSTARRS_DEV_0")) {
+    ImagePanstarrs_DEV_0 *tmpimage;
+    *format = DVO_FORMAT_PANSTARRS_DEV_0;
+    tmpimage = gfits_table_get_ImagePanstarrs_DEV_0 (ftable, &Nimage, NULL);
+    ftable[0].buffer = (char *) ImagePanstarrs_DEV_0_ToInternal (tmpimage, Nimage);
+    free (tmpimage);
+    goto set_header;
+  }
+# if 0
   if (!strcmp (extname, "DVO_IMAGE_PANSTARRS") || !strcmp (extname, "DVO_IMAGE_PMTEST")) {
     ImagePanstarrs *tmpimage;
@@ -321,4 +388,5 @@
     goto set_header;
   }
+# endif
   fprintf (stderr, "table format unknown: %s\n", extname);
   return (FALSE);
@@ -336,7 +404,4 @@
 
   int Nimage;
-  ImageElixir *tmpImageElixir;
-  ImageLoneos *tmpImageLoneos;
-  ImagePanstarrs *tmpImagePanstarrs;
 
   Nimage = theader[0].Naxis[1];
@@ -344,26 +409,37 @@
   /* convert from the internal format */
   switch (format) {
-    case DVO_FORMAT_INTERNAL:
+    case DVO_FORMAT_INTERNAL: {
       gfits_convert_Image ((Image *) ftable[0].buffer, sizeof(Image), Nimage);
-      break;
-    case DVO_FORMAT_ELIXIR:
-      tmpImageElixir = ImageInternalToElixir ((Image *) ftable[0].buffer, Nimage);
+      break; }
+    case DVO_FORMAT_ELIXIR: {
+      ImageElixir *tmpImage;
+      tmpImage = ImageInternalToElixir ((Image *) ftable[0].buffer, Nimage);
       free (ftable[0].buffer);
-      gfits_table_set_ImageElixir (ftable, tmpImageElixir, Nimage);
-      free (tmpImageElixir);
-      break;
-    case DVO_FORMAT_LONEOS:
-      tmpImageLoneos = ImageInternalToLoneos ((Image *) ftable[0].buffer, Nimage);
+      gfits_table_set_ImageElixir (ftable, tmpImage, Nimage);
+      free (tmpImage);
+      break; }
+    case DVO_FORMAT_LONEOS: {
+      ImageLoneos *tmpImage;
+      tmpImage = ImageInternalToLoneos ((Image *) ftable[0].buffer, Nimage);
       free (ftable[0].buffer);
-      gfits_table_set_ImageLoneos (ftable, tmpImageLoneos, Nimage);
-      free (tmpImageLoneos);
-      break;
-    case DVO_FORMAT_PANSTARRS:
-    case DVO_FORMAT_PMTEST:
-      tmpImagePanstarrs = ImageInternalToPanstarrs ((Image *) ftable[0].buffer, Nimage);
+      gfits_table_set_ImageLoneos (ftable, tmpImage, Nimage);
+      free (tmpImage);
+      break; }
+    case DVO_FORMAT_PANSTARRS_DEV_0: {
+      ImagePanstarrs_DEV_0 *tmpImage;
+      tmpImage = ImageInternalToPanstarrs_DEV_0 ((Image *) ftable[0].buffer, Nimage);
       free (ftable[0].buffer);
-      gfits_table_set_ImagePanstarrs (ftable, tmpImagePanstarrs, Nimage);
-      free (tmpImagePanstarrs);
-      break;
+      gfits_table_set_ImagePanstarrs_DEV_0 (ftable, tmpImage, Nimage);
+      free (tmpImage);
+      break; }
+# if 0
+    case DVO_FORMAT_PANSTARRS: {
+      ImagePanstarrs *tmpImage;
+      tmpImage = ImageInternalToPanstarrs ((Image *) ftable[0].buffer, Nimage);
+      free (ftable[0].buffer);
+      gfits_table_set_ImagePanstarrs (ftable, tmpImage, Nimage);
+      free (tmpImage);
+      break; }
+# endif
     default:
       fprintf (stderr, "table format unknown (image ftable)\n");
@@ -375,7 +451,4 @@
 int ImageToVtable (VTable *vtable, Header *theader, int format) {
 
-  ImageElixir *tmpImageElixir;
-  ImageLoneos *tmpImageLoneos;
-  ImagePanstarrs *tmpImagePanstarrs;
   int i, Nrow, Nimage;
 
@@ -384,16 +457,17 @@
   /* convert from the internal format */
   switch (format) {
-    case DVO_FORMAT_INTERNAL:
+    case DVO_FORMAT_INTERNAL: {
       for (i = 0; i < Nrow; i++) {
 	gfits_convert_Image ((Image *) vtable[0].buffer[i], sizeof(Image), 1);
       }
-      return (TRUE);
-    case DVO_FORMAT_ELIXIR:
+      return (TRUE); }
+    case DVO_FORMAT_ELIXIR: {
+      ImageElixir *tmpImage;
       /* convert table rows from internal to external format */
       for (i = 0; i < Nrow; i++) {
-	tmpImageElixir = ImageInternalToElixir ((Image *) vtable[0].buffer[i], 1);
-	gfits_convert_ImageElixir (tmpImageElixir, sizeof(ImageElixir), 1);
+	tmpImage = ImageInternalToElixir ((Image *) vtable[0].buffer[i], 1);
+	gfits_convert_ImageElixir (tmpImage, sizeof(ImageElixir), 1);
 	free (vtable[0].buffer[i]);
-	vtable[0].buffer[i] = (char *) tmpImageElixir;
+	vtable[0].buffer[i] = (char *) tmpImage;
       }
 
@@ -407,12 +481,13 @@
       theader[0].Naxis[1] = Nimage;
       vtable[0].size = gfits_matrix_size (theader);
-      return (TRUE);
-    case DVO_FORMAT_LONEOS:
+      return (TRUE); }
+    case DVO_FORMAT_LONEOS: {
+      ImageLoneos *tmpImage;
       /* convert table rows from internal to external format */
       for (i = 0; i < Nrow; i++) {
-	tmpImageLoneos = ImageInternalToLoneos ((Image *) vtable[0].buffer[i], 1);
-	gfits_convert_ImageLoneos (tmpImageLoneos, sizeof(ImageLoneos), 1);
+	tmpImage = ImageInternalToLoneos ((Image *) vtable[0].buffer[i], 1);
+	gfits_convert_ImageLoneos (tmpImage, sizeof(ImageLoneos), 1);
 	free (vtable[0].buffer[i]);
-	vtable[0].buffer[i] = (char *) tmpImageLoneos;
+	vtable[0].buffer[i] = (char *) tmpImage;
       }
 
@@ -426,15 +501,32 @@
       theader[0].Naxis[1] = Nimage;
       vtable[0].size = gfits_matrix_size (theader);
-      return (TRUE);
-    case DVO_FORMAT_PANSTARRS:
-    case DVO_FORMAT_PMTEST:
+      return (TRUE); }
+    case DVO_FORMAT_PANSTARRS_DEV_0: {
+      ImagePanstarrs_DEV_0 *tmpImage;
       /* convert table rows from internal to external format */
       for (i = 0; i < Nrow; i++) {
-	tmpImagePanstarrs = ImageInternalToPanstarrs ((Image *) vtable[0].buffer[i], 1);
-	gfits_convert_ImagePanstarrs (tmpImagePanstarrs, sizeof(ImagePanstarrs), 1);
+	tmpImage = ImageInternalToPanstarrs_DEV_0 ((Image *) vtable[0].buffer[i], 1);
+	gfits_convert_ImagePanstarrs_DEV_0 (tmpImage, sizeof(ImagePanstarrs_DEV_0), 1);
 	free (vtable[0].buffer[i]);
-	vtable[0].buffer[i] = (char *) tmpImagePanstarrs;
+	vtable[0].buffer[i] = (char *) tmpImage;
       }
-
+      /* convert header from old format to new format */
+      gfits_scan (theader, "NAXIS2", "%d", 1, &Nimage);
+      gfits_free_header (theader);
+      gfits_table_mkheader_ImagePanstarrs_DEV_0 (theader);
+      gfits_modify (theader, "NAXIS2", "%d", 1, Nimage);
+      theader[0].Naxis[1] = Nimage;
+      vtable[0].size = gfits_matrix_size (theader);
+      return (TRUE); }
+# if 0
+    case DVO_FORMAT_PANSTARRS: {
+      ImagePanstarrs *tmpImage;
+      /* convert table rows from internal to external format */
+      for (i = 0; i < Nrow; i++) {
+	tmpImage = ImageInternalToPanstarrs ((Image *) vtable[0].buffer[i], 1);
+	gfits_convert_ImagePanstarrs (tmpImage, sizeof(ImagePanstarrs), 1);
+	free (vtable[0].buffer[i]);
+	vtable[0].buffer[i] = (char *) tmpImage;
+      }
       /* convert header from old format to new format */
       gfits_scan (theader, "NAXIS2", "%d", 1, &Nimage);
@@ -444,5 +536,6 @@
       theader[0].Naxis[1] = Nimage;
       vtable[0].size = gfits_matrix_size (theader);
-      return (TRUE);
+      return (TRUE); }
+# endif
     default:
       break;
Index: trunk/Ohana/src/libdvo/src/dvo_convert_elixir.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_convert_elixir.c	(revision 11991)
+++ trunk/Ohana/src/libdvo/src/dvo_convert_elixir.c	(revision 12332)
@@ -10,17 +10,64 @@
 
   for (i = 0; i < Nvalues; i++) {
-    out[i].dR_PS   = in[i].dR * 0.01;
-    out[i].dD_PS   = in[i].dD * 0.01;
-    out[i].M_PS    = in[i].M  * 0.001;
-    out[i].dM_PS   = in[i].dM * 0.001;
-    out[i].dt_PS      = in[i].dt * 0.001;
-    out[i].Mcal_PS    = in[i].Mcal * 0.001;
-    out[i].Mgal_PS    = in[i].Mgal * 0.001;
-    out[i].airmass_PS = in[i].airmass * 0.001;
+    out[i].dR       = in[i].dR * 0.01;
+    out[i].dD       = in[i].dD * 0.01;
+    out[i].M        = in[i].M  * 0.001;
+    out[i].dM       = in[i].dM * 0.001;
+    out[i].dt       = in[i].dt * 0.001;
+    out[i].Mcal     = in[i].Mcal * 0.001;
+    out[i].Mgal     = in[i].Mgal * 0.001;
+    out[i].airmass  = in[i].airmass * 0.001;
+    out[i].FWx 	    = in[i].FWx;
+    out[i].FWy 	    = in[i].fwy * in[i].FWx * 0.01;
+    out[i].theta    = in[i].theta*(0x10000 / 0x100);
+    out[i].dophot   = in[i].dophot;
+    out[i].photcode = in[i].source;
+    out[i].t        = in[i].t;
+    out[i].averef   = in[i].averef;
+    out[i].flags    = in[i].flags;
+    
+    /* these can be determined if needed / desired */
+    out[i].Xccd     = 0;
+    out[i].Yccd     = 0;
+    out[i].dXccd    = 0;
+    out[i].dYccd    = 0;
+
+    /* these do not have a corresponding value */
+    out[i].stargal  = 0;
+    out[i].Sky      = 0;
+    out[i].dSky     = 0;
+    out[i].qPSF     = 0;
+
+    /* XXX add these later */
+    out[i].detID_hi = 0;
+    out[i].detID_lo = 0;
+    out[i].imageID_hi = 0;
+    out[i].imageID_lo = 0;
+  }
+  return (out);
+}
+
+/* convert internal measures to elixir-format measures */
+MeasureElixir *MeasureInternalToElixir (Measure *in, int Nvalues) {
+
+  int i;
+  MeasureElixir *out;
+
+  ALLOCATE (out, MeasureElixir, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    out[i].dR      = in[i].dR * 100.0;
+    out[i].dD 	   = in[i].dD * 100.0;
+    out[i].M       = in[i].M  * 1000.0;
+    out[i].dM      = in[i].dM * 1000.0;
+    out[i].dt      = in[i].dt * 1000.0;
+    out[i].Mcal    = in[i].Mcal * 1000.0;
+    out[i].Mgal    = in[i].Mgal * 1000.0;
+    out[i].airmass = in[i].airmass * 1000.0;
     out[i].FWx 	   = in[i].FWx;
-    out[i].FWy 	   = in[i].fwy * in[i].FWx * 0.01;
-    out[i].theta   = in[i].theta;
+    out[i].fwy 	   = in[i].FWy * 100.0 / in[i].FWx;
+    out[i].theta   = in[i].theta*(0x100/ 0x10000);
     out[i].dophot  = in[i].dophot;
-    out[i].source  = in[i].source;
+    out[i].source  = in[i].photcode;
     out[i].t       = in[i].t;
     out[i].averef  = in[i].averef;
@@ -30,35 +77,6 @@
 }
 
-/* convert internal measures to elixir-format measures */
-MeasureElixir *MeasureInternalToElixir (Measure *in, int Nvalues) {
-
-  int i;
-  MeasureElixir *out;
-
-  ALLOCATE (out, MeasureElixir, Nvalues);
-
-  for (i = 0; i < Nvalues; i++) {
-    out[i].dR      = in[i].dR_PS * 100.0;
-    out[i].dD 	   = in[i].dD_PS * 100.0;
-    out[i].M       = in[i].M_PS  * 1000.0;
-    out[i].dM      = in[i].dM_PS * 1000.0;
-    out[i].dt      = in[i].dt_PS * 1000.0;
-    out[i].Mcal    = in[i].Mcal_PS * 1000.0;
-    out[i].Mgal    = in[i].Mgal_PS * 1000.0;
-    out[i].airmass = in[i].airmass_PS * 1000.0;
-    out[i].FWx 	   = in[i].FWx;
-    out[i].fwy 	   = 100.0 * in[i].FWy / in[i].FWx;
-    out[i].theta   = in[i].theta;
-    out[i].dophot  = in[i].dophot;
-    out[i].source  = in[i].source;
-    out[i].t       = in[i].t;
-    out[i].averef  = in[i].averef;
-    out[i].flags   = in[i].flags;
-  }
-  return (out);
-}
-
 /* convert elixir-format averages to internal averages */
-Average *AverageElixirToInternal (AverageElixir *in, int Nvalues) {
+Average *AverageElixirToInternal (AverageElixir *in, int Nvalues, SecFilt **primary) {
 
   int i;
@@ -66,12 +84,10 @@
 
   ALLOCATE (out, Average, Nvalues);
+  ALLOCATE (*primary, SecFilt, Nvalues);
 
   for (i = 0; i < Nvalues; i++) {
     out[i].R       = in[i].R;      
     out[i].D       = in[i].D;      
-    out[i].M       = in[i].M  * 0.001;      
-    out[i].dM      = in[i].dM * 0.001;      
     out[i].Xp      = in[i].Xp;     
-    out[i].Xm      = in[i].Xm;     
     out[i].Nm      = in[i].Nm;     
     out[i].Nn      = in[i].Nn;     
@@ -79,5 +95,4 @@
     out[i].offset  = in[i].offset; 
     out[i].missing = in[i].missing;
-    out[i].Xg      = in[i].Xg;
 
     /* these don't exist in Elixir */
@@ -90,4 +105,17 @@
     out[i].P       = 0;
     out[i].dP      = 0;
+
+    /* XXX add these later */
+    out[i].objID_hi = 0;
+    out[i].objID_lo = 0;
+
+    primary[0][i].M  = in[i].M  * 0.001;      
+    primary[0][i].dM = in[i].dM * 0.001;      
+    primary[0][i].Xm = in[i].Xm;     
+    primary[0][i].Ncode = 0;     
+    primary[0][i].Nused = 0;
+
+    // XXX drop this or keep this?
+    // primary[0][i].Xg = in[i].Xg;
   }
   return (out);
@@ -95,5 +123,5 @@
 
 /* convert internal averages to elixir-format averages */
-AverageElixir *AverageInternalToElixir (Average *in, int Nvalues) {
+AverageElixir *AverageInternalToElixir (Average *in, int Nvalues, SecFilt *primary) {
 
   int i;
@@ -105,8 +133,5 @@
     out[i].R       = in[i].R;      
     out[i].D       = in[i].D;      
-    out[i].M       = in[i].M  * 1000.0;      
-    out[i].dM      = in[i].dM * 1000.0;
     out[i].Xp      = in[i].Xp;     
-    out[i].Xm      = in[i].Xm;     
     out[i].Nm      = in[i].Nm;     
     out[i].Nn      = in[i].Nn;     
@@ -114,5 +139,9 @@
     out[i].offset  = in[i].offset; 
     out[i].missing = in[i].missing;
-    out[i].Xg      = in[i].Xg;
+
+    out[i].M       = primary[i].M  * 1000.0;      
+    out[i].dM      = primary[i].dM * 1000.0;
+    out[i].Xm      = primary[i].Xm;     
+    // out[i].Xg      = in[i].Xg;
   }
   return (out);
@@ -128,7 +157,9 @@
 
   for (i = 0; i < Nvalues; i++) {
-    out[i].M_PS    = in[i].M  * 0.001;      
-    out[i].dM_PS   = in[i].dM * 0.001;      
-    out[i].Xm      = in[i].Xm;     
+    out[i].M     = in[i].M  * 0.001;      
+    out[i].dM    = in[i].dM * 0.001;      
+    out[i].Xm    = in[i].Xm;     
+    out[i].Ncode = 0;
+    out[i].Nused = 0;
   }
   return (out);
@@ -144,6 +175,6 @@
 
   for (i = 0; i < Nvalues; i++) {
-    out[i].M       = in[i].M_PS  * 1000.0;      
-    out[i].dM      = in[i].dM_PS * 1000.0;
+    out[i].M       = in[i].M  * 1000.0;      
+    out[i].dM      = in[i].dM * 1000.0;
     out[i].Xm      = in[i].Xm;     
   }
@@ -166,13 +197,13 @@
     out[i].tzero    	    = in[i].tzero;
     out[i].nstar    	    = in[i].nstar;
-    out[i].secz_PS    	    = in[i].secz * 0.001;
+    out[i].secz    	    = in[i].secz * 0.001;
     out[i].NX	    	    = in[i].NX;
     out[i].NY	    	    = in[i].NY;
-    out[i].apmifit_PS  	    = in[i].apmifit * 0.001;
-    out[i].dapmifit_PS 	    = in[i].dapmifit * 0.001;
-    out[i].Mcal_PS   	    = in[i].Mcal * 0.001;
-    out[i].dMcal_PS   	    = in[i].dMcal * 0.001;
+    out[i].apmifit  	    = in[i].apmifit * 0.001;
+    out[i].dapmifit 	    = in[i].dapmifit * 0.001;
+    out[i].Mcal   	    = in[i].Mcal * 0.001;
+    out[i].dMcal   	    = in[i].dMcal * 0.001;
     out[i].Xm	    	    = in[i].Xm;
-    out[i].source   	    = in[i].source;
+    out[i].photcode   	    = in[i].source;
     out[i].exptime  	    = in[i].exptime;
     out[i].detection_limit  = in[i].detection_limit;
@@ -199,4 +230,8 @@
     out[i].Mxyyy	    = in[i].Mxyyy;
     out[i].Myyyy	    = in[i].Myyyy;
+
+    /* XXX add these later */
+    out[i].imageID_hi = 0;
+    out[i].imageID_lo = 0;
   }
   return (out);
@@ -218,13 +253,13 @@
     out[i].tzero    	    = in[i].tzero;
     out[i].nstar    	    = in[i].nstar;
-    out[i].secz	    	    = in[i].secz_PS * 1000.0;
+    out[i].secz	    	    = in[i].secz * 1000.0;
     out[i].NX	    	    = in[i].NX;
     out[i].NY	    	    = in[i].NY;
-    out[i].apmifit  	    = in[i].apmifit_PS * 1000.0;
-    out[i].dapmifit 	    = in[i].dapmifit_PS * 1000.0;
-    out[i].Mcal	    	    = in[i].Mcal_PS * 1000.0;
-    out[i].dMcal    	    = in[i].dMcal_PS * 1000.0;
+    out[i].apmifit  	    = in[i].apmifit * 1000.0;
+    out[i].dapmifit 	    = in[i].dapmifit * 1000.0;
+    out[i].Mcal	    	    = in[i].Mcal * 1000.0;
+    out[i].dMcal    	    = in[i].dMcal * 1000.0;
     out[i].Xm	    	    = in[i].Xm;
-    out[i].source   	    = in[i].source;
+    out[i].source   	    = in[i].photcode;
     out[i].exptime  	    = in[i].exptime;
     out[i].detection_limit  = in[i].detection_limit;
Index: trunk/Ohana/src/libdvo/src/dvo_convert_loneos.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_convert_loneos.c	(revision 11991)
+++ trunk/Ohana/src/libdvo/src/dvo_convert_loneos.c	(revision 12332)
@@ -10,11 +10,11 @@
 
   for (i = 0; i < Nvalues; i++) {
-    out[i].dR_PS   = in[i].dR * 0.01;
-    out[i].dD_PS   = in[i].dD * 0.01;
-    out[i].M_PS    = in[i].M  * 0.001;
-    out[i].dM_PS   = in[i].dM * 0.001;
-    out[i].Mcal_PS = in[i].Mcal * 0.001;
+    out[i].dR   = in[i].dR * 0.01;
+    out[i].dD   = in[i].dD * 0.01;
+    out[i].M    = in[i].M  * 0.001;
+    out[i].dM   = in[i].dM * 0.001;
+    out[i].Mcal = in[i].Mcal * 0.001;
     out[i].dophot  = in[i].dophot;
-    out[i].source  = in[i].source;
+    out[i].photcode  = in[i].source;
     out[i].t       = in[i].t;
 
@@ -24,10 +24,26 @@
 
     /* these values don't exist in the Loneos format */
-    out[i].Mgal_PS    = in[i].M;
-    out[i].dt_PS      = 0;
-    out[i].airmass_PS = 0;
+    out[i].Mgal    = in[i].M;
+    out[i].dt      = 0;
+    out[i].airmass = 0;
     out[i].FWx 	      = 0;
     out[i].FWy 	      = 0;
     out[i].theta      = 0;
+    out[i].stargal  = 0;
+    out[i].Sky      = 0;
+    out[i].dSky     = 0;
+    out[i].qPSF     = 0;
+
+    /* these can be determined if needed / desired */
+    out[i].Xccd     = 0;
+    out[i].Yccd     = 0;
+    out[i].dXccd    = 0;
+    out[i].dYccd    = 0;
+
+    /* XXX add these later */
+    out[i].detID_hi = 0;
+    out[i].detID_lo = 0;
+    out[i].imageID_hi = 0;
+    out[i].imageID_lo = 0;
   }
   return (out);
@@ -43,11 +59,11 @@
 
   for (i = 0; i < Nvalues; i++) {
-    out[i].dR 	  = in[i].dR_PS * 100.0;
-    out[i].dD 	  = in[i].dD_PS * 100.0;
-    out[i].M  	  = in[i].M_PS  * 1000.0;
-    out[i].dM 	  = in[i].dM_PS * 1000.0;
-    out[i].Mcal   = in[i].Mcal_PS * 1000.0;
+    out[i].dR 	  = in[i].dR * 100.0;
+    out[i].dD 	  = in[i].dD * 100.0;
+    out[i].M  	  = in[i].M  * 1000.0;
+    out[i].dM 	  = in[i].dM * 1000.0;
+    out[i].Mcal   = in[i].Mcal * 1000.0;
     out[i].dophot = in[i].dophot;
-    out[i].source = in[i].source;
+    out[i].source = in[i].photcode;
     out[i].t      = in[i].t;
 
@@ -59,5 +75,5 @@
 
 /* convert loneos-format averages to internal averages */
-Average *AverageLoneosToInternal (AverageLoneos *in, int Nvalues) {
+Average *AverageLoneosToInternal (AverageLoneos *in, int Nvalues, SecFilt **primary) {
 
   int i;
@@ -65,11 +81,10 @@
 
   ALLOCATE (out, Average, Nvalues);
+  ALLOCATE (*primary, SecFilt, Nvalues);
 
   for (i = 0; i < Nvalues; i++) {
     out[i].R       = in[i].R;      
     out[i].D       = in[i].D;      
-    out[i].M       = in[i].M * 0.001;      
     out[i].Xp      = in[i].Xp;     
-    out[i].Xm      = in[i].Xm;     
     out[i].Nm      = in[i].Nm;     
     out[i].Nn      = in[i].Nn;     
@@ -87,6 +102,17 @@
     out[i].P       = 0;
     out[i].dP      = 0;
-    out[i].dM      = 0xffff;
-    out[i].Xg      = 0xffff;
+
+    /* XXX add these later */
+    out[i].objID_hi = 0;
+    out[i].objID_lo = 0;
+
+    primary[0][i].M  = in[i].M  * 0.001;      
+    primary[0][i].Xm = in[i].Xm;     
+    primary[0][i].dM = 0xffff;
+    primary[0][i].Ncode = 0;     
+    primary[0][i].Nused = 0;
+
+    // XXX drop this or keep this?
+    // primary[0][i].Xg = in[i].Xg;
   }
   return (out);
@@ -94,5 +120,5 @@
 
 /* convert internal averages to loneos-format averages */
-AverageLoneos *AverageInternalToLoneos (Average *in, int Nvalues) {
+AverageLoneos *AverageInternalToLoneos (Average *in, int Nvalues, SecFilt *primary) {
 
   int i;
@@ -104,7 +130,5 @@
     out[i].R       = in[i].R;      
     out[i].D       = in[i].D;      
-    out[i].M       = in[i].M * 1000.0;      
     out[i].Xp      = in[i].Xp;     
-    out[i].Xm      = in[i].Xm;     
     out[i].Nm      = in[i].Nm;     
     out[i].Nn      = in[i].Nn;     
@@ -112,4 +136,7 @@
     out[i].offset  = in[i].offset; 
     out[i].missing = in[i].missing;
+
+    out[i].M       = primary[i].M * 1000.0;      
+    out[i].Xm      = primary[i].Xm;     
   }
   return (out);
@@ -125,7 +152,9 @@
 
   for (i = 0; i < Nvalues; i++) {
-    out[i].M_PS  = in[i].M*0.001;      
-    out[i].dM_PS = 0xffff;
+    out[i].M     = in[i].M*0.001;      
     out[i].Xm    = in[i].Xm;      
+    out[i].dM    = 0xffff;
+    out[i].Ncode = 0;
+    out[i].Nused = 0;
   }
   return (out);
@@ -141,5 +170,5 @@
 
   for (i = 0; i < Nvalues; i++) {
-    out[i].M    = in[i].M_PS*1000.0;      
+    out[i].M    = in[i].M*1000.0;      
     out[i].Xm   = in[i].Xm;      
   }
@@ -162,13 +191,13 @@
     out[i].tzero    	    = in[i].tzero;
     out[i].nstar    	    = in[i].nstar;
-    out[i].secz_PS    	    = in[i].secz * 0.001;
+    out[i].secz    	    = in[i].secz * 0.001;
     out[i].NX	    	    = in[i].NX;
     out[i].NY	    	    = in[i].NY;
-    out[i].apmifit_PS  	    = in[i].apmifit * 0.001;
-    out[i].dapmifit_PS 	    = in[i].dapmifit * 0.001;
-    out[i].Mcal_PS	    = in[i].Mcal * 0.001;
-    out[i].dMcal_PS    	    = in[i].dMcal * 0.001;
+    out[i].apmifit  	    = in[i].apmifit * 0.001;
+    out[i].dapmifit 	    = in[i].dapmifit * 0.001;
+    out[i].Mcal	    = in[i].Mcal * 0.001;
+    out[i].dMcal    	    = in[i].dMcal * 0.001;
     out[i].Xm	    	    = in[i].Xm;
-    out[i].source   	    = in[i].source;
+    out[i].photcode   	    = in[i].source;
     out[i].exptime  	    = in[i].exptime;
     out[i].detection_limit  = in[i].detection_limit;
@@ -195,4 +224,8 @@
     out[i].Mxyyy	    = in[i].Mxyyy;
     out[i].Myyyy	    = in[i].Myyyy;
+
+    /* XXX add these later */
+    out[i].imageID_hi = 0;
+    out[i].imageID_lo = 0;
   }
   return (out);
@@ -214,13 +247,13 @@
     out[i].tzero    	    = in[i].tzero;
     out[i].nstar    	    = in[i].nstar;
-    out[i].secz	    	    = in[i].secz_PS * 1000.0;
+    out[i].secz	    	    = in[i].secz * 1000.0;
     out[i].NX	    	    = in[i].NX;
     out[i].NY	    	    = in[i].NY;
-    out[i].apmifit  	    = in[i].apmifit_PS * 1000.0;
-    out[i].dapmifit 	    = in[i].dapmifit_PS * 1000.0;
-    out[i].Mcal	    	    = in[i].Mcal_PS * 1000.0;
-    out[i].dMcal    	    = in[i].dMcal_PS * 1000.0;
+    out[i].apmifit  	    = in[i].apmifit * 1000.0;
+    out[i].dapmifit 	    = in[i].dapmifit * 1000.0;
+    out[i].Mcal	    	    = in[i].Mcal * 1000.0;
+    out[i].dMcal    	    = in[i].dMcal * 1000.0;
     out[i].Xm	    	    = in[i].Xm;
-    out[i].source   	    = in[i].source;
+    out[i].source   	    = in[i].photcode;
     out[i].exptime  	    = in[i].exptime;
     out[i].detection_limit  = in[i].detection_limit;
Index: trunk/Ohana/src/libdvo/src/dvo_convert_panstarrs.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_convert_panstarrs.c	(revision 11991)
+++ trunk/Ohana/src/libdvo/src/dvo_convert_panstarrs.c	(revision 12332)
@@ -1,5 +1,5 @@
 # include <dvo.h>
 
-/*** note that these structures are identical ***/
+/*** XXX is this format actually used by anyone?? ***/
 
 /* convert panstarrs-format measures to internal measures */
@@ -12,20 +12,38 @@
 
   for (i = 0; i < Nvalues; i++) {
-    out[i].dR_PS      = in[i].dR;
-    out[i].dD_PS      = in[i].dD;
-    out[i].M_PS       = in[i].M;
-    out[i].dM_PS      = in[i].dM;
-    out[i].Mcal_PS    = in[i].Mcal;
-    out[i].Mgal_PS    = in[i].Mgal;
-    out[i].airmass_PS = in[i].airmass;
-    out[i].dt_PS      = in[i].dt;
+    out[i].dR         = in[i].dR;
+    out[i].dD         = in[i].dD;
+    out[i].M          = in[i].M;
+    out[i].dM         = in[i].dM;
+    out[i].Mcal       = in[i].Mcal;
+    out[i].Mgal       = in[i].Mgal;
+    out[i].airmass    = in[i].airmass;
+    out[i].dt         = in[i].dt;
     out[i].FWx 	      = in[i].FWx;
     out[i].FWy 	      = in[i].FWy;
     out[i].theta      = in[i].theta;
     out[i].dophot     = in[i].dophot;
-    out[i].source     = in[i].source;
+    out[i].photcode   = in[i].source;
     out[i].t          = in[i].t;
     out[i].averef     = in[i].averef;
     out[i].flags      = in[i].flags;
+    
+    /* these can be determined if needed / desired */
+    out[i].Xccd     = 0;
+    out[i].Yccd     = 0;
+    out[i].dXccd    = 0;
+    out[i].dYccd    = 0;
+
+    /* these do not have a corresponding value */
+    out[i].stargal  = 0;
+    out[i].Sky      = 0;
+    out[i].dSky     = 0;
+    out[i].qPSF     = 0;
+
+    /* XXX add these later */
+    out[i].detID_hi = 0;
+    out[i].detID_lo = 0;
+    out[i].imageID_hi = 0;
+    out[i].imageID_lo = 0;
   }
   return (out);
@@ -41,17 +59,17 @@
 
   for (i = 0; i < Nvalues; i++) {
-    out[i].dR 	   = in[i].dR_PS;
-    out[i].dD 	   = in[i].dD_PS;
-    out[i].M       = in[i].M_PS;
-    out[i].dM      = in[i].dM_PS;
-    out[i].Mcal    = in[i].Mcal_PS;
-    out[i].Mgal    = in[i].Mgal_PS;
-    out[i].airmass = in[i].airmass_PS;
-    out[i].dt      = in[i].dt_PS;
+    out[i].dR 	   = in[i].dR;
+    out[i].dD 	   = in[i].dD;
+    out[i].M       = in[i].M;
+    out[i].dM      = in[i].dM;
+    out[i].Mcal    = in[i].Mcal;
+    out[i].Mgal    = in[i].Mgal;
+    out[i].airmass = in[i].airmass;
+    out[i].dt      = in[i].dt;
     out[i].FWx 	   = in[i].FWx;
     out[i].FWy 	   = in[i].FWy;
     out[i].theta   = in[i].theta;
     out[i].dophot  = in[i].dophot;
-    out[i].source  = in[i].source;
+    out[i].source  = in[i].photcode;
     out[i].t       = in[i].t;
     out[i].averef  = in[i].averef;
@@ -92,4 +110,8 @@
     out[i].P       = 0;
     out[i].dP      = 0;
+
+    /* XXX add these later */
+    out[i].objID_hi = 0;
+    out[i].objID_lo = 0;
   }
   return (out);
@@ -130,8 +152,10 @@
 
   for (i = 0; i < Nvalues; i++) {
-    out[i].M_PS    = in[i].M;      
-    out[i].dM_PS   = in[i].dM;      
-    out[i].Xm      = in[i].Xm;     
-  }
+    out[i].M    = in[i].M;      
+    out[i].dM   = in[i].dM;      
+    out[i].Xm      = in[i].Xm;     
+     out[i].Ncode = 0;
+    out[i].Nused = 0;
+ }
   return (out);
 }
@@ -146,6 +170,6 @@
 
   for (i = 0; i < Nvalues; i++) {
-    out[i].M       = in[i].M_PS;      
-    out[i].dM      = in[i].dM_PS;
+    out[i].M       = in[i].M;      
+    out[i].dM      = in[i].dM;
     out[i].Xm      = in[i].Xm;     
   }
@@ -168,13 +192,13 @@
     out[i].tzero    	    = in[i].tzero;
     out[i].nstar    	    = in[i].nstar;
-    out[i].secz_PS	    	    = in[i].secz;
+    out[i].secz	    	    = in[i].secz;
     out[i].NX	    	    = in[i].NX;
     out[i].NY	    	    = in[i].NY;
-    out[i].apmifit_PS  	    = in[i].apmifit;
-    out[i].dapmifit_PS 	    = in[i].dapmifit;
-    out[i].Mcal_PS	    	    = in[i].Mcal;
-    out[i].dMcal_PS    	    = in[i].dMcal;
+    out[i].apmifit  	    = in[i].apmifit;
+    out[i].dapmifit 	    = in[i].dapmifit;
+    out[i].Mcal	    	    = in[i].Mcal;
+    out[i].dMcal    	    = in[i].dMcal;
     out[i].Xm	    	    = in[i].Xm;
-    out[i].source   	    = in[i].source;
+    out[i].photcode   	    = in[i].source;
     out[i].exptime  	    = in[i].exptime;
     out[i].detection_limit  = in[i].detection_limit;
@@ -201,4 +225,8 @@
     out[i].Mxyyy	    = in[i].Mxyyy;
     out[i].Myyyy	    = in[i].Myyyy;
+
+    /* XXX add these later */
+    out[i].imageID_hi = 0;
+    out[i].imageID_lo = 0;
   }
   return (out);
@@ -220,13 +248,13 @@
     out[i].tzero    	    = in[i].tzero;
     out[i].nstar    	    = in[i].nstar;
-    out[i].secz	    	    = in[i].secz_PS;
+    out[i].secz	    	    = in[i].secz;
     out[i].NX	    	    = in[i].NX;
     out[i].NY	    	    = in[i].NY;
-    out[i].apmifit  	    = in[i].apmifit_PS;
-    out[i].dapmifit 	    = in[i].dapmifit_PS;
-    out[i].Mcal	    	    = in[i].Mcal_PS;
-    out[i].dMcal    	    = in[i].dMcal_PS;
+    out[i].apmifit  	    = in[i].apmifit;
+    out[i].dapmifit 	    = in[i].dapmifit;
+    out[i].Mcal	    	    = in[i].Mcal;
+    out[i].dMcal    	    = in[i].dMcal;
     out[i].Xm	    	    = in[i].Xm;
-    out[i].source   	    = in[i].source;
+    out[i].source   	    = in[i].photcode;
     out[i].exptime  	    = in[i].exptime;
     out[i].detection_limit  = in[i].detection_limit;
Index: trunk/Ohana/src/libdvo/src/dvo_convert_panstarrs_DEV_0.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_convert_panstarrs_DEV_0.c	(revision 12332)
+++ trunk/Ohana/src/libdvo/src/dvo_convert_panstarrs_DEV_0.c	(revision 12332)
@@ -0,0 +1,295 @@
+# include <dvo.h>
+
+/* convert panstarrs-format measures to internal measures */
+Measure *MeasurePanstarrs_DEV_0_ToInternal (MeasurePanstarrs_DEV_0 *in, int Nvalues) {
+
+  int i;
+  Measure *out;
+
+  ALLOCATE (out, Measure, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    out[i].dR         = in[i].dR;
+    out[i].dD         = in[i].dD;
+    out[i].M          = in[i].M;
+    out[i].dM         = in[i].dM;
+    out[i].Mcal       = in[i].Mcal;
+    out[i].Mgal       = in[i].Mgal;
+    out[i].airmass    = in[i].airmass;
+    out[i].az         = in[i].az;
+    out[i].dt         = in[i].dt;
+    out[i].FWx 	      = in[i].FWx;
+    out[i].FWy 	      = in[i].FWy;
+    out[i].theta      = in[i].theta;
+    out[i].dophot     = in[i].dophot;
+    out[i].photcode   = in[i].photcode;
+    out[i].t          = in[i].t;
+    out[i].averef     = in[i].averef;
+    out[i].flags      = in[i].flags;
+    out[i].Xccd       = in[i].Xccd;
+    out[i].Yccd       = in[i].Yccd;
+    out[i].dXccd      = in[i].dXccd;
+    out[i].dYccd      = in[i].dYccd;
+    out[i].stargal    = in[i].stargal;
+    out[i].Sky        = in[i].Sky;
+    out[i].dSky       = in[i].dSky;
+    out[i].qPSF       = in[i].qPSF;
+    out[i].detID_hi   = in[i].detID_hi;
+    out[i].detID_lo   = in[i].detID_lo;
+    out[i].imageID_hi = in[i].imageID_hi;
+    out[i].imageID_lo = in[i].imageID_lo;
+  }
+  return (out);
+}
+
+/* convert internal measures to panstarrs-format measures */
+MeasurePanstarrs_DEV_0 *MeasureInternalToPanstarrs_DEV_0 (Measure *in, int Nvalues) {
+
+  int i;
+  MeasurePanstarrs_DEV_0 *out;
+
+  ALLOCATE (out, MeasurePanstarrs_DEV_0, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    out[i].dR         = in[i].dR;
+    out[i].dD         = in[i].dD;
+    out[i].M          = in[i].M;
+    out[i].dM         = in[i].dM;
+    out[i].Mcal       = in[i].Mcal;
+    out[i].Mgal       = in[i].Mgal;
+    out[i].airmass    = in[i].airmass;
+    out[i].az         = in[i].az;
+    out[i].dt         = in[i].dt;
+    out[i].FWx 	      = in[i].FWx;
+    out[i].FWy 	      = in[i].FWy;
+    out[i].theta      = in[i].theta;
+    out[i].dophot     = in[i].dophot;
+    out[i].photcode   = in[i].photcode;
+    out[i].t          = in[i].t;
+    out[i].averef     = in[i].averef;
+    out[i].flags      = in[i].flags;
+    out[i].Xccd       = in[i].Xccd;
+    out[i].Yccd       = in[i].Yccd;
+    out[i].dXccd      = in[i].dXccd;
+    out[i].dYccd      = in[i].dYccd;
+    out[i].stargal    = in[i].stargal;
+    out[i].Sky        = in[i].Sky;
+    out[i].dSky       = in[i].dSky;
+    out[i].qPSF       = in[i].qPSF;
+    out[i].detID_hi   = in[i].detID_hi;
+    out[i].detID_lo   = in[i].detID_lo;
+    out[i].imageID_hi = in[i].imageID_hi;
+    out[i].imageID_lo = in[i].imageID_lo;
+  }
+  return (out);
+}
+
+/* convert panstarrs-format averages to internal averages */
+Average *AveragePanstarrs_DEV_0_ToInternal (AveragePanstarrs_DEV_0 *in, int Nvalues) {
+
+  int i;
+  Average *out;
+
+  ALLOCATE (out, Average, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    out[i].R        = in[i].R;      
+    out[i].D        = in[i].D;      
+    out[i].Xp       = in[i].Xp;     
+    out[i].Nm       = in[i].Nm;     
+    out[i].Nn       = in[i].Nn;     
+    out[i].code     = in[i].code;   
+    out[i].offset   = in[i].offset; 
+    out[i].missing  = in[i].missing;
+    out[i].dR       = in[i].dR;
+    out[i].dD       = in[i].dD;
+    out[i].uR       = in[i].uR;
+    out[i].uD       = in[i].uD;
+    out[i].duR      = in[i].duR;
+    out[i].duD      = in[i].duD;
+    out[i].P        = in[i].P;
+    out[i].dP       = in[i].dP;
+    out[i].objID_hi = in[i].objID_hi;
+    out[i].objID_lo = in[i].objID_lo;
+  }
+  return (out);
+}
+
+/* convert internal averages to panstarrs-format averages */
+AveragePanstarrs_DEV_0 *AverageInternalToPanstarrs_DEV_0 (Average *in, int Nvalues) {
+
+  int i;
+  AveragePanstarrs_DEV_0 *out;
+
+  ALLOCATE (out, AveragePanstarrs_DEV_0, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    out[i].R        = in[i].R;      
+    out[i].D        = in[i].D;      
+    out[i].Xp       = in[i].Xp;     
+    out[i].Nm       = in[i].Nm;     
+    out[i].Nn       = in[i].Nn;     
+    out[i].code     = in[i].code;   
+    out[i].offset   = in[i].offset; 
+    out[i].missing  = in[i].missing;
+    out[i].dR       = in[i].dR;
+    out[i].dD       = in[i].dD;
+    out[i].uR       = in[i].uR;
+    out[i].uD       = in[i].uD;
+    out[i].duR      = in[i].duR;
+    out[i].duD      = in[i].duD;
+    out[i].P        = in[i].P;
+    out[i].dP       = in[i].dP;
+    out[i].objID_hi = in[i].objID_hi;
+    out[i].objID_lo = in[i].objID_lo;
+  }
+  return (out);
+}
+
+/* convert panstarrs-format secfilts to internal secfilts */
+SecFilt *SecFiltPanstarrs_DEV_0_ToInternal (SecFiltPanstarrs_DEV_0 *in, int Nvalues) {
+
+  int i;
+  SecFilt *out;
+
+  ALLOCATE (out, SecFilt, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    out[i].M     = in[i].M;      
+    out[i].dM    = in[i].dM;      
+    out[i].Xm    = in[i].Xm;     
+    out[i].Ncode = in[i].Ncode;
+    out[i].Nused = in[i].Nused;
+ }
+  return (out);
+}
+
+/* convert internal secfilts to panstarrs-format secfilts */
+SecFiltPanstarrs_DEV_0 *SecFiltInternalToPanstarrs_DEV_0 (SecFilt *in, int Nvalues) {
+
+  int i;
+  SecFiltPanstarrs_DEV_0 *out;
+
+  ALLOCATE (out, SecFiltPanstarrs_DEV_0, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    out[i].M     = in[i].M;      
+    out[i].dM    = in[i].dM;      
+    out[i].Xm    = in[i].Xm;     
+    out[i].Ncode = in[i].Ncode;
+    out[i].Nused = in[i].Nused;
+  }
+  return (out);
+}
+
+/* convert panstarrs-format images to internal images */
+Image *ImagePanstarrs_DEV_0_ToInternal (ImagePanstarrs_DEV_0 *in, int Nvalues) {
+
+  int i;
+  Image *out;
+
+  ALLOCATE (out, Image, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
+    strcpy (out[i].name, in[i].name);
+
+    out[i].tzero    	    = in[i].tzero;
+    out[i].nstar    	    = in[i].nstar;
+    out[i].secz	    	    = in[i].secz;
+    out[i].NX	    	    = in[i].NX;
+    out[i].NY	    	    = in[i].NY;
+    out[i].apmifit  	    = in[i].apmifit;
+    out[i].dapmifit 	    = in[i].dapmifit;
+    out[i].Mcal	    	    = in[i].Mcal;
+    out[i].dMcal    	    = in[i].dMcal;
+    out[i].Xm	    	    = in[i].Xm;
+    out[i].photcode   	    = in[i].photcode;
+    out[i].exptime  	    = in[i].exptime;
+    out[i].sidtime  	    = in[i].sidtime;
+    out[i].latitude  	    = in[i].latitude;
+    out[i].detection_limit  = in[i].detection_limit;
+    out[i].saturation_limit = in[i].saturation_limit;
+    out[i].cerror	    = in[i].cerror;
+    out[i].fwhm_x	    = in[i].fwhm_x;
+    out[i].fwhm_y	    = in[i].fwhm_y;
+    out[i].trate	    = in[i].trate;
+    out[i].code		    = in[i].code;
+    out[i].ccdnum	    = in[i].ccdnum;
+    out[i].imageID_hi	    = in[i].imageID_hi;
+    out[i].imageID_lo	    = in[i].imageID_lo;
+
+    out[i].order	    = in[i].order;
+    out[i].Mx		    = in[i].Mx;
+    out[i].My		    = in[i].My;
+    out[i].Mxx		    = in[i].Mxx;
+    out[i].Mxy		    = in[i].Mxy;
+    out[i].Myy		    = in[i].Myy;
+    out[i].Mxxx		    = in[i].Mxxx;
+    out[i].Mxxy		    = in[i].Mxxy;
+    out[i].Mxyy		    = in[i].Mxyy;
+    out[i].Myyy		    = in[i].Myyy;
+    out[i].Mxxxx	    = in[i].Mxxxx;
+    out[i].Mxxxy	    = in[i].Mxxxy;
+    out[i].Mxxyy	    = in[i].Mxxyy;
+    out[i].Mxyyy	    = in[i].Mxyyy;
+    out[i].Myyyy	    = in[i].Myyyy;
+  }
+  return (out);
+}
+
+/* convert internal images to panstarrs-format images */
+ImagePanstarrs_DEV_0 *ImageInternalToPanstarrs_DEV_0 (Image *in, int Nvalues) {
+
+  int i;
+  ImagePanstarrs_DEV_0 *out;
+
+  ALLOCATE (out, ImagePanstarrs_DEV_0, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
+    strcpy (out[i].name, in[i].name);
+
+    out[i].tzero    	    = in[i].tzero;
+    out[i].nstar    	    = in[i].nstar;
+    out[i].secz	    	    = in[i].secz;
+    out[i].NX	    	    = in[i].NX;
+    out[i].NY	    	    = in[i].NY;
+    out[i].apmifit  	    = in[i].apmifit;
+    out[i].dapmifit 	    = in[i].dapmifit;
+    out[i].Mcal	    	    = in[i].Mcal;
+    out[i].dMcal    	    = in[i].dMcal;
+    out[i].Xm	    	    = in[i].Xm;
+    out[i].photcode   	    = in[i].photcode;
+    out[i].exptime  	    = in[i].exptime;
+    out[i].sidtime  	    = in[i].sidtime;
+    out[i].latitude  	    = in[i].latitude;
+    out[i].detection_limit  = in[i].detection_limit;
+    out[i].saturation_limit = in[i].saturation_limit;
+    out[i].cerror	    = in[i].cerror;
+    out[i].fwhm_x	    = in[i].fwhm_x;
+    out[i].fwhm_y	    = in[i].fwhm_y;
+    out[i].trate	    = in[i].trate;
+    out[i].code		    = in[i].code;
+    out[i].ccdnum	    = in[i].ccdnum;
+    out[i].imageID_hi	    = in[i].imageID_hi;
+    out[i].imageID_lo	    = in[i].imageID_lo;
+
+    out[i].order	    = in[i].order;
+    out[i].Mx		    = in[i].Mx;
+    out[i].My		    = in[i].My;
+    out[i].Mxx		    = in[i].Mxx;
+    out[i].Mxy		    = in[i].Mxy;
+    out[i].Myy		    = in[i].Myy;
+    out[i].Mxxx		    = in[i].Mxxx;
+    out[i].Mxxy		    = in[i].Mxxy;
+    out[i].Mxyy		    = in[i].Mxyy;
+    out[i].Myyy		    = in[i].Myyy;
+    out[i].Mxxxx	    = in[i].Mxxxx;
+    out[i].Mxxxy	    = in[i].Mxxxy;
+    out[i].Mxxyy	    = in[i].Mxxyy;
+    out[i].Mxyyy	    = in[i].Mxyyy;
+    out[i].Myyyy	    = in[i].Myyyy;
+  }
+  return (out);
+}
Index: trunk/Ohana/src/libdvo/src/dvo_convert_pmtest.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_convert_pmtest.c	(revision 11991)
+++ trunk/Ohana/src/libdvo/src/dvo_convert_pmtest.c	(revision 12332)
@@ -1,3 +1,91 @@
 # include <dvo.h>
+
+/* convert elixir-format measures to internal measures */
+Measure *MeasureElixirToInternal (MeasureElixir *in, int Nvalues) {
+
+  int i;
+  Measure *out;
+
+  ALLOCATE (out, Measure, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    out[i].dR         = in[i].dR;
+    out[i].dD         = in[i].dD;
+    out[i].M          = in[i].M;
+    out[i].dM         = in[i].dM;
+    out[i].dt         = in[i].dt;
+    out[i].Mcal       = in[i].Mcal;
+    out[i].Mgal       = in[i].Mgal;
+    out[i].airmass    = in[i].airmass;
+    out[i].FWx 	      = in[i].FWx;
+    out[i].FWy 	      = in[i].FWy;
+    out[i].theta      = in[i].theta;
+    out[i].dophot     = in[i].dophot;
+    out[i].photcode   = in[i].source;
+    out[i].t          = in[i].t;
+    out[i].averef     = in[i].averef;
+    out[i].flags      = in[i].flags;
+
+    out[i].Xccd       = in[i].Xccd;
+    out[i].Yccd       = in[i].Yccd;
+    out[i].dXccd      = in[i].dXccd;
+    out[i].dYccd      = in[i].dYccd;
+					    
+    out[i].stargal    = in[i].stargal;
+    out[i].Sky        = in[i].Sky;
+    out[i].dSky       = in[i].dSky;
+    out[i].qPSF       = in[i].qPSF;
+					    
+    out[i].detID_hi   = in[i].detID_hi;
+    out[i].detID_lo   = in[i].detID_lo;
+    out[i].imageID_hi = in[i].imageID_hi;
+    out[i].imageID_lo = in[i].imageID_lo;
+  }
+  return (out);
+}
+
+/* convert internal measures to elixir-format measures */
+MeasureElixir *MeasureInternalToElixir (Measure *in, int Nvalues) {
+
+  int i;
+  MeasureElixir *out;
+
+  ALLOCATE (out, MeasureElixir, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    out[i].dR         = in[i].dR;
+    out[i].dD         = in[i].dD;
+    out[i].M          = in[i].M;
+    out[i].dM         = in[i].dM;
+    out[i].dt         = in[i].dt;
+    out[i].Mcal       = in[i].Mcal;
+    out[i].Mgal       = in[i].Mgal;
+    out[i].airmass    = in[i].airmass;
+    out[i].FWx 	      = in[i].FWx;
+    out[i].FWy 	      = in[i].FWy;
+    out[i].theta      = in[i].theta;
+    out[i].dophot     = in[i].dophot;
+    out[i].photcode   = in[i].source;
+    out[i].t          = in[i].t;
+    out[i].averef     = in[i].averef;
+    out[i].flags      = in[i].flags;
+
+    out[i].Xccd       = in[i].Xccd;
+    out[i].Yccd       = in[i].Yccd;
+    out[i].dXccd      = in[i].dXccd;
+    out[i].dYccd      = in[i].dYccd;
+					    
+    out[i].stargal    = in[i].stargal;
+    out[i].Sky        = in[i].Sky;
+    out[i].dSky       = in[i].dSky;
+    out[i].qPSF       = in[i].qPSF;
+					    
+    out[i].detID_hi   = in[i].detID_hi;
+    out[i].detID_lo   = in[i].detID_lo;
+    out[i].imageID_hi = in[i].imageID_hi;
+    out[i].imageID_lo = in[i].imageID_lo;
+  }
+  return (out);
+}
 
 /* convert panstarrs-format averages to internal averages */
Index: trunk/Ohana/src/libdvo/src/dvo_image.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_image.c	(revision 11991)
+++ trunk/Ohana/src/libdvo/src/dvo_image.c	(revision 12332)
@@ -187,9 +187,10 @@
   gfits_modify (&db[0].header, "ZERO_PT", "%lf", 1, ZeroPoint);
 
-  if (db[0].format == DVO_FORMAT_INTERNAL)  gfits_modify (&db[0].header, "FORMAT", "%s", 1, "INTERNAL");
-  if (db[0].format == DVO_FORMAT_LONEOS)    gfits_modify (&db[0].header, "FORMAT", "%s", 1, "LONEOS");
-  if (db[0].format == DVO_FORMAT_ELIXIR)    gfits_modify (&db[0].header, "FORMAT", "%s", 1, "ELIXIR");
-  if (db[0].format == DVO_FORMAT_PANSTARRS) gfits_modify (&db[0].header, "FORMAT", "%s", 1, "PANSTARRS");
-  if (db[0].format == DVO_FORMAT_PMTEST)    gfits_modify (&db[0].header, "FORMAT", "%s", 1, "PMTEST");
+  if (db[0].format == DVO_FORMAT_INTERNAL)  	  gfits_modify (&db[0].header, "FORMAT", "%s", 1, "INTERNAL");
+  if (db[0].format == DVO_FORMAT_LONEOS)    	  gfits_modify (&db[0].header, "FORMAT", "%s", 1, "LONEOS");
+  if (db[0].format == DVO_FORMAT_ELIXIR)    	  gfits_modify (&db[0].header, "FORMAT", "%s", 1, "ELIXIR");
+  if (db[0].format == DVO_FORMAT_PANSTARRS_DEV_0) gfits_modify (&db[0].header, "FORMAT", "%s", 1, "PANSTARRS_DEV_0");
+  // if (db[0].format == DVO_FORMAT_PANSTARRS) 	  gfits_modify (&db[0].header, "FORMAT", "%s", 1, "PANSTARRS");
+  // if (db[0].format == DVO_FORMAT_PMTEST)    	  gfits_modify (&db[0].header, "FORMAT", "%s", 1, "PMTEST");
   
   return;
Index: trunk/Ohana/src/libdvo/src/dvo_image_raw.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_image_raw.c	(revision 11991)
+++ trunk/Ohana/src/libdvo/src/dvo_image_raw.c	(revision 12332)
@@ -20,18 +20,14 @@
   db[0].format = DVO_FORMAT_UNDEF;
   if (gfits_scan (&db[0].header, "FORMAT",  "%s", 1, format)) {
-    if (!strcmp (format, "INTERNAL")) db[0].format = DVO_FORMAT_INTERNAL;
-    if (!strcmp (format, "LONEOS")) db[0].format = DVO_FORMAT_LONEOS;
-    if (!strcmp (format, "ELIXIR")) db[0].format = DVO_FORMAT_ELIXIR;
-    if (!strcmp (format, "PANSTARRS")) db[0].format = DVO_FORMAT_PANSTARRS;
-    if (!strcmp (format, "PMTEST")) db[0].format = DVO_FORMAT_PANSTARRS;
+    db[0].format = dvo_catalog_catformat (format);
     if (db[0].format != DVO_FORMAT_UNDEF) goto got_format;
   }
   if (gfits_scan (&db[0].header, "TELESCOP",  "%s", 1, telescope)) {
     if (!strncmp (telescope, "LONEOS", strlen("LONEOS"))) {
-      db[0].format = DVO_FORMAT_LONEOS;
+      db[0].format = DVO_FORMAT_LONEOS; // special case for LONEOS
       goto got_format;
     }
     if (!strncmp (telescope, "1.3m McGraw-Hill", strlen("1.3m McGraw-Hill"))) {
-      db[0].format = DVO_FORMAT_ELIXIR;
+      db[0].format = DVO_FORMAT_ELIXIR; // special case for ELIXIR
       goto got_format;
     }
@@ -51,8 +47,9 @@
   /* get datatype size */
   ImageSize = 0;
-  if (db[0].format == DVO_FORMAT_INTERNAL)  ImageSize = sizeof(Image);
-  if (db[0].format == DVO_FORMAT_LONEOS)    ImageSize = sizeof(ImageLoneos);
-  if (db[0].format == DVO_FORMAT_ELIXIR)    ImageSize = sizeof(ImageElixir);
-  if (db[0].format == DVO_FORMAT_PANSTARRS) ImageSize = sizeof(ImagePanstarrs);
+  if (db[0].format == DVO_FORMAT_INTERNAL)  	  ImageSize = sizeof(Image);
+  if (db[0].format == DVO_FORMAT_LONEOS)    	  ImageSize = sizeof(ImageLoneos);
+  if (db[0].format == DVO_FORMAT_ELIXIR)    	  ImageSize = sizeof(ImageElixir);
+  if (db[0].format == DVO_FORMAT_PANSTARRS) 	  ImageSize = sizeof(ImagePanstarrs);
+  if (db[0].format == DVO_FORMAT_PANSTARRS_DEV_0) ImageSize = sizeof(ImagePanstarrs_DEV_0);
 
   /* check that filesize makes sense */
@@ -72,8 +69,9 @@
   db[0].ftable.header = &db[0].theader;
 
-  if (db[0].format == DVO_FORMAT_INTERNAL)  gfits_table_mkheader_Image (&db[0].theader);
-  if (db[0].format == DVO_FORMAT_LONEOS)    gfits_table_mkheader_ImageLoneos (&db[0].theader);
-  if (db[0].format == DVO_FORMAT_ELIXIR)    gfits_table_mkheader_ImageElixir (&db[0].theader);
-  if (db[0].format == DVO_FORMAT_PANSTARRS) gfits_table_mkheader_ImagePanstarrs (&db[0].theader);
+  if (db[0].format == DVO_FORMAT_INTERNAL)  	  gfits_table_mkheader_Image (&db[0].theader);
+  if (db[0].format == DVO_FORMAT_LONEOS)    	  gfits_table_mkheader_ImageLoneos (&db[0].theader);
+  if (db[0].format == DVO_FORMAT_ELIXIR)    	  gfits_table_mkheader_ImageElixir (&db[0].theader);
+  if (db[0].format == DVO_FORMAT_PANSTARRS) 	  gfits_table_mkheader_ImagePanstarrs (&db[0].theader);
+  if (db[0].format == DVO_FORMAT_PANSTARRS_DEV_0) gfits_table_mkheader_ImagePanstarrs_DEV_0 (&db[0].theader);
     
   /* read data from file */
Index: trunk/Ohana/src/libdvo/src/dvo_photcode_ops.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_photcode_ops.c	(revision 12332)
+++ trunk/Ohana/src/libdvo/src/dvo_photcode_ops.c	(revision 12332)
@@ -0,0 +1,526 @@
+# include <dvo.h>
+
+/* we use a static variable to save the pre-loaded the photcodes.
+   photcode conversion functions refer to this table for ref values */
+
+/* We have three indexes:
+
+   table[0].hashcode provides the table photcode sequence for a photcode value
+   table[0].hashNsec provides the Nsec sequence for a photcode value
+   table[0].codeNsec provides the photcode value for an Nsec sequence
+
+   given photcode = table[0].code[i] and code = photcode[0].code
+
+   hashcode[code] = i
+   hashNsec[code] = Nsec or -1 if not a PRI/SEC code
+   codeNsec[Nsec] = code
+*/
+
+static PhotCodeData *photcodes = NULL;
+
+PhotCodeData *GetPhotcodeTable () {
+
+  /* allocate space to photcode table, free existing data */
+  if (photcodes == NULL) {
+    ALLOCATE (photcodes, PhotCodeData, 1);
+    photcodes[0].code = NULL;
+  }
+  return photcodes;
+}
+
+/* the static ZERO_POINT is used by programs as an approximate nominal */
+static double ZERO_POINT;
+
+void SetZeroPoint (double ZP) {
+  ZERO_POINT = ZP;
+}
+
+# define SCALE 0.001
+
+/********** photcode lookup functions **********/
+
+/* return photcode for given name */
+PhotCode *GetPhotcodebyName (char *name) {
+  
+  int i;
+
+  if (name == NULL) return (NULL);
+  
+  for (i = 0; i < photcodes[0].Ncode; i++) {
+    if (!strcmp (photcodes[0].code[i].name, name)) {
+      return (&photcodes[0].code[i]);
+    }
+  }
+  return (NULL);
+}
+/* return photcode.code for given name */
+int GetPhotcodeCodebyName (char *name) {
+  
+  int i;
+  
+  if (name == NULL) return (0);
+
+  for (i = 0; i < photcodes[0].Ncode; i++) {
+    if (!strcmp (photcodes[0].code[i].name, name)) {
+      return (photcodes[0].code[i].code);
+    }
+  }
+  return (0);
+}
+/* return equivalent photcode for given name */
+PhotCode *GetPhotcodeEquivbyName (char *name) {
+  
+  int i, equiv;
+  
+  if (name == NULL) return (NULL);
+
+  for (i = 0; i < photcodes[0].Ncode; i++) {
+    if (!strcmp (photcodes[0].code[i].name, name)) {
+      if (photcodes[0].code[i].equiv == 0) return (NULL);
+      equiv = photcodes[0].hashcode[photcodes[0].code[i].equiv];
+      if (equiv == -1) return (NULL);
+      return (&photcodes[0].code[equiv]);
+    }
+  }
+  return (NULL);
+}
+/* return equivalent photcode.code for given name */
+int GetPhotcodeEquivCodebyName (char *name) {
+  
+  int i, equiv;
+  
+  if (name == NULL) return (0);
+
+  for (i = 0; i < photcodes[0].Ncode; i++) {
+    if (!strcmp (photcodes[0].code[i].name, name)) {
+      if (photcodes[0].code[i].equiv == 0) return (0);
+      equiv = photcodes[0].hashcode[photcodes[0].code[i].equiv];
+      if (equiv == -1) return (0);
+      return (photcodes[0].code[equiv].code);
+    }
+  }
+  return (0);
+}
+
+/* return photcode for given code */
+PhotCode *GetPhotcodebyCode (int code) {
+  
+  int entry;
+  
+  if (code < 0) return (NULL);
+  if (code > 0x10000) return (NULL);
+
+  entry = photcodes[0].hashcode[code];
+  if (entry == -1) return (NULL);
+
+  return (&photcodes[0].code[entry]);
+}
+/* return photcode.code for given code */
+char *GetPhotcodeNamebyCode (int code) {
+  
+  int entry;
+  
+  if (code < 0) return (NULL);
+  if (code > 0x10000) return (NULL);
+
+  entry = photcodes[0].hashcode[code];
+  if (entry == -1) return (NULL);
+
+  return (photcodes[0].code[entry].name);
+}
+/* return equivalent photcode for given code */
+PhotCode *GetPhotcodeEquivbyCode (int code) {
+  
+  int entry, equiv;
+  
+  if (code < 0) return (NULL);
+  if (code > 0x10000) return (NULL);
+
+  entry = photcodes[0].hashcode[code];
+  if (entry == -1) return (NULL);
+
+  if (photcodes[0].code[entry].equiv == 0) return (NULL);
+  equiv = photcodes[0].hashcode[photcodes[0].code[entry].equiv];
+
+  if (equiv == -1) return (NULL);
+  return (&photcodes[0].code[equiv]);
+}
+/* return equivalent photcode.code for given code */
+int GetPhotcodeEquivCodebyCode (int code) {
+  
+  int entry;
+  
+  if (code < 0) return (0);
+  if (code > 0x10000) return (0);
+
+  entry = photcodes[0].hashcode[code];
+  if (entry == -1) return (0);
+  return (photcodes[0].code[entry].equiv);
+}
+
+int GetPhotcodeNsec (int code) {
+  
+  int Nsec;
+  
+  if (code < 0) return (-1);
+  if (code > 0x10000) return (-1);
+
+  Nsec = photcodes[0].hashNsec[code];
+  return (Nsec);
+}
+
+/* Nsec of 0 is PRI */
+PhotCode *GetPhotcodebyNsec (int Nsec) {
+  
+  int Ncode;
+  int Nseq;
+
+  if (Nsec > photcodes[0].Nsecfilt) return (NULL);
+  if (Nsec < 0) return (NULL);
+  
+  Ncode = photcodes[0].codeNsec[Nsec];
+  if (Ncode < 0) return (NULL);
+
+  Nseq = photcodes[0].hashcode[Ncode];
+  return (&photcodes[0].code[Nseq]);
+}
+
+int GetPhotcodeNsecfilt () {
+  return (photcodes[0].Nsecfilt);
+}
+
+/* ALLOCATE and return list of all photcodes
+   with photcode.equiv == code */
+int *GetPhotcodeEquivList (int code, int *nlist) {
+
+  int i, Nlist;
+  int *list;
+
+  ALLOCATE (list, int, MAX (1, photcodes[0].Ncode));
+  Nlist = 0;
+  for (i = 0; i < photcodes[0].Ncode; i++) {
+    if (photcodes[0].code[i].equiv != code) continue;
+    list[Nlist] = photcodes[0].code[i].code;
+    Nlist ++;
+  }
+  REALLOCATE (list, int, MAX (1, Nlist));
+
+  *nlist = Nlist;
+  return (list);
+}
+
+/******** photometry conversion functions *********/
+float PhotInst (Measure *measure) {
+
+  int Np;
+  float M;
+
+  Np = photcodes[0].hashcode[measure[0].photcode];
+  if (Np == -1) return (NO_MAG);
+
+  if (photcodes[0].code[Np].type == PHOT_REF) {
+    M = measure[0].M;
+    return (M);
+  }
+
+  M = measure[0].M - measure[0].dt - ZERO_POINT;
+	  
+  return (M);
+
+}
+
+float PhotCat (Measure *measure) {
+
+  int Np;
+  float Mcat;
+  PhotCode *code;
+
+  Np = photcodes[0].hashcode[measure[0].photcode];
+  if (Np == -1) return (NO_MAG);
+
+  if (photcodes[0].code[Np].type == PHOT_REF) {
+    Mcat = measure[0].M;
+    return (Mcat);
+  }
+  code = &photcodes[0].code[Np];
+  Mcat = measure[0].M - ZERO_POINT + code[0].K*(measure[0].airmass - 1.000) + SCALE*code[0].C;
+  
+  return (Mcat);
+}
+
+float PhotSys (Measure *measure, Average *average, SecFilt *secfilt) {
+
+  int i, Np;
+  float Mcat, Mcol, Msys, mc, Mc;
+  PhotCode *code;
+
+  Np = photcodes[0].hashcode[measure[0].photcode];
+  if (Np == -1) return (NO_MAG);
+
+  if (photcodes[0].code[Np].type == PHOT_REF) {
+    Msys = measure[0].M;
+    return (Msys);
+  }
+  code = &photcodes[0].code[Np];
+  Mcat = measure[0].M - ZERO_POINT + code[0].K*(measure[0].airmass - 1.000) + SCALE*code[0].C;
+
+  /* for DEP, color must be made of PRI/SEC */
+  mc = PhotColorForCode (average, secfilt, NULL, code);
+  if (mc == NO_MAG) return (Mcat);
+  mc = mc - SCALE*code[0].dX;
+
+  Mc = mc;
+  Mcol = 0;
+  for (i = 0; i < code[0].Nc; i++) {
+    Mcol += code[0].X[i]*Mc;
+    Mc *= mc;
+  }
+  Msys = Mcat + Mcol;
+  return (Msys);
+}
+
+float PhotRel (Measure *measure, Average *average, SecFilt *secfilt) {
+
+  int i, Np;
+  float Mcat, Mcol, Mrel, mc, Mc;
+  PhotCode *code;
+
+  Np = photcodes[0].hashcode[measure[0].photcode];
+  if (Np == -1) return (NO_MAG);
+
+  if (photcodes[0].code[Np].type == PHOT_REF) {
+    Mcat = measure[0].M;
+    return (Mcat);
+  }
+  code = &photcodes[0].code[Np];
+  Mrel = measure[0].M - ZERO_POINT + code[0].K*(measure[0].airmass - 1.000) + SCALE*code[0].C - measure[0].Mcal;
+
+  /* for DEP, color must be made of PRI/SEC */
+  mc = PhotColorForCode (average, secfilt, NULL, code);
+  if (mc == NO_MAG) return (Mrel);
+  mc = mc - SCALE*code[0].dX;
+
+  Mc = mc;
+  Mcol = 0;
+  for (i = 0; i < code[0].Nc; i++) {
+    Mcol += code[0].X[i]*Mc;
+    Mc *= mc;    /* the 0.001 is needed for higher order terms to keep the units mag = mag^n */
+  }
+  Mrel += Mcol;
+  return (Mrel);
+}
+
+/* return calibrated magnitude from measure for given photcode */
+float PhotCal (Measure *thisone, Average *average, SecFilt *secfilt, Measure *measure, PhotCode *code) {
+
+  int i, Np; 
+  float Mcal, Mrel, Mcol, mc, Mc;
+
+  /* code must be the matching PRI/SEC code for this measurement or an equivalent ALT */
+  Np = photcodes[0].hashcode[thisone[0].photcode];
+  if (Np == -1) {
+    return (NO_MAG);
+  }
+
+  if (photcodes[0].code[Np].type == PHOT_REF) {
+    Mrel = thisone[0].M;
+    return (Mrel);
+  }
+  if (code[0].code != photcodes[0].code[Np].equiv) {
+    return (NO_MAG);
+  }
+
+  Mcal = PhotRel (thisone, average, secfilt) + SCALE*code[0].C;
+
+  mc = PhotColorForCode (average, secfilt, measure, code);
+  if (mc == NO_MAG) return (Mcal);
+  mc = mc - SCALE*code[0].dX;
+
+  Mc = mc;
+  Mcol = 0;
+  for (i = 0; i < code[0].Nc; i++) {
+    Mcol += code[0].X[i]*Mc;
+    Mc *= mc;
+  }
+  Mcal += Mcol;
+  return (Mcal);
+}
+
+/* color term may not use DEP magnitude */
+float PhotColorForCode (Average *average, SecFilt *secfilt, Measure *measure, PhotCode *code) {
+
+  int i, Ns1, Ns2, Ns;
+  float m1, m2, mc;
+  PhotCode *color;
+
+  m1 = m2 = NO_MAG;
+
+  if (measure == NULL) {
+    Ns1 = photcodes[0].hashNsec[code[0].c1];
+    Ns2 = photcodes[0].hashNsec[code[0].c2];
+  
+    m1 = (Ns1 == -1) ? NO_MAG : secfilt[Ns1].M;
+    m2 = (Ns2 == -1) ? NO_MAG : secfilt[Ns2].M;
+    mc = ((m1 == NO_MAG) || (m2 == NO_MAG)) ? NO_MAG : (m1 - m2);
+    return (mc);
+  }
+
+  /* find magnitude matching first color term */
+  color = GetPhotcodebyCode (code[0].c1);
+  if (color == NULL) return (NO_MAG);
+  if (color[0].type == PHOT_REF) {
+    for (i = 0; (i < average[0].Nm) && (m1 == NO_MAG); i++) {
+      if (measure[i].photcode == color[0].code) {
+	m1 = measure[i].M;
+      }
+    }
+  } else {
+    Ns = photcodes[0].hashNsec[color[0].code];
+    m1 = (Ns == -1) ? NO_MAG : secfilt[Ns].M;
+  }	
+
+  /* find magnitude matching second color term */
+  color = GetPhotcodebyCode (code[0].c2);
+  if (color == NULL) return (NO_MAG);
+  if (color[0].type == PHOT_REF) {
+    for (i = 0; (i < average[0].Nm) && (m2 == NO_MAG); i++) {
+      if (measure[i].photcode == color[0].code) {
+	m2 = measure[i].M;
+      }
+    }
+  } else {
+    Ns = photcodes[0].hashNsec[color[0].code];
+    m2 = (Ns == -1) ? NO_MAG : secfilt[Ns].M;
+  }	
+  mc = ((m1 == NO_MAG) || (m2 == NO_MAG)) ? NO_MAG : (m1 - m2);
+  return (mc);
+}
+
+/* return calibrated magnitude from average/secfilt for given photcode */
+float PhotRef (PhotCode *code, Average *average, SecFilt *secfilt, Measure *measure) {
+
+  int i, Ns;
+  float Mave, Mref, Mcol, mc;
+  double Mc;
+
+  Ns = photcodes[0].hashNsec[code[0].code];
+  Mave = (Ns == -1) ? NO_MAG : secfilt[Ns].M;
+  Mref = Mave + SCALE*code[0].C;
+
+  mc = PhotColorForCode (average, secfilt, measure, code);
+  if (mc == NO_MAG) return (Mref);
+  mc = mc - SCALE*code[0].dX;
+
+  Mc = mc;
+  Mcol = 0;
+  for (i = 0; i < code[0].Nc; i++) {
+    Mcol += code[0].X[i]*Mc;
+    Mc *= mc;    /* the 0.001 is needed for higher order terms to keep the units mag = mag^n */
+  }
+  Mref += Mcol;
+  return (Mref);
+}
+
+/***/
+float PhotAve (PhotCode *code, Average *average, SecFilt *secfilt) {
+
+  int Ns;
+  float Mave;
+
+  Ns = photcodes[0].hashNsec[code[0].code];
+  Mave = (Ns == -1) ? NO_MAG : secfilt[Ns].M;
+  return (Mave);
+}
+
+float PhotdM (PhotCode *code, Average *average, SecFilt *secfilt) {
+
+  int Ns;
+  float dM;
+
+  Ns = photcodes[0].hashNsec[code[0].code];
+  dM  = (Ns == -1) ? NO_MAG : secfilt[Ns].dM;
+  return (dM);
+}
+
+float PhotXm (PhotCode *code, Average *average, SecFilt *secfilt) {
+
+  int Ns;
+  short Mi;
+  float Xm;
+
+  Ns = photcodes[0].hashNsec[code[0].code];
+  Mi = (Ns == -1) ? NO_MAG : secfilt[Ns].Xm;
+  Xm = (Mi == NO_MAG) ? -1.0 : pow (10.0, 0.01*Mi);
+  return (Xm);
+}
+
+/* given a photcode pair c1 & c2, return the color of this star (NaN if not found) */
+int PhotColor (Average *average, SecFilt *secfilt, Measure *measure, int c1, int c2, double *color) {
+
+  int i, Ns;
+  double M1, M2, dM;
+  PhotCode *code;
+  
+  code = GetPhotcodebyCode (c1);
+  if (code == NULL) return (FALSE);
+  if (code[0].type == PHOT_REF) {
+    for (i = 0; i < average[0].Nm; i++) {
+      if (measure[i].photcode == c1) {
+	M1 = measure[i].M;
+	goto filter1;
+      }
+    }	
+    return (FALSE);
+  } else {
+    Ns = photcodes[0].hashNsec[code[0].code];
+    M1 = (Ns == -1) ? NO_MAG : secfilt[Ns].M;
+  }	
+
+filter1:
+  code = GetPhotcodebyCode (c2);
+  if (code == NULL) return (FALSE);
+  if (code[0].type == PHOT_REF) {
+    for (i = 0; i < average[0].Nm; i++) {
+      if (measure[i].photcode == c2) {
+	M2 = measure[i].M;
+	goto filter2;
+      }
+    }	
+    return (FALSE);
+  } else {
+    Ns = photcodes[0].hashNsec[code[0].code];
+    M2 = (Ns == -1) ? NO_MAG : secfilt[Ns].M;
+  }	
+  
+filter2:
+
+  dM = M1 - M2;
+  *color = dM;
+  
+  return (TRUE);
+}
+
+/* photcode table should have the following format: 
+
+# code name     type  zero  airmass  offset  c1 c2  slope  <color>  primary
+1    B        pri   24.0  0.15     -       -  -   -      -        -
+2    B        pri   24.0  0.15     -       -  -   -      -        -
+3    B1       sec   22.5  0.18     0.15    1  2   0.10   0.50     1
+1000 USNO_B   ref   -     -        -       -  -   -      -        -
+
+*/
+
+
+/*
+  Nc1 = photcodes[0].code[Np].c1;
+  Ns1 = photcodes[0].hashNsec[Nc1];
+
+  Nc2 = photcodes[0].code[Np].c2;
+  Ns2 = photcodes[0].hashNsec[Nc2];
+
+  Xlam = photcodes[0].code[Np].X[0];
+  Klam = photcodes[0].code[Np].K;
+  
+  m1 = (Ns1 == -1) ? average[0].M : secfilt[Ns1].M;
+  m2 = (Ns2 == -1) ? average[0].M : secfilt[Ns2].M;
+*/
Index: trunk/Ohana/src/libdvo/src/photfits.c
===================================================================
--- trunk/Ohana/src/libdvo/src/photfits.c	(revision 11991)
+++ trunk/Ohana/src/libdvo/src/photfits.c	(revision 12332)
@@ -61,13 +61,13 @@
   switch (image[0].order) {
   case 0:
-    c[0] = image[0].Mcal_PS;
-    return;
-  case 1:
-    c[0] = image[0].Mcal_PS;
+    c[0] = image[0].Mcal;
+    return;
+  case 1:
+    c[0] = image[0].Mcal;
     c[1] = getMi (image[0].Mx);
     c[2] = getMi (image[0].My);
     return;
   case 2:
-    c[0] = image[0].Mcal_PS;
+    c[0] = image[0].Mcal;
     c[1] = getMi (image[0].Mx);
     c[2] = getMi (image[0].Mxx);
@@ -77,5 +77,5 @@
     return;
   case 3:
-    c[0] = image[0].Mcal_PS;
+    c[0] = image[0].Mcal;
     c[1] = getMi (image[0].Mx);
     c[2] = getMi (image[0].Mxx);
@@ -89,5 +89,5 @@
     return;
   case 4:
-    c[0] = image[0].Mcal_PS;
+    c[0] = image[0].Mcal;
     c[1] = getMi (image[0].Mx);
     c[2] = getMi (image[0].Mxx);
@@ -117,13 +117,13 @@
   switch (order) {
   case 0:
-    image[0].Mcal_PS = c[0];
-    return;
-  case 1:
-    image[0].Mcal_PS = c[0];
+    image[0].Mcal = c[0];
+    return;
+  case 1:
+    image[0].Mcal = c[0];
     image[0].Mx    = putMi(c[1]);
     image[0].My    = putMi(c[2]);
     return;
   case 2:
-    image[0].Mcal_PS = c[0];
+    image[0].Mcal = c[0];
     image[0].Mx    = putMi(c[1]);
     image[0].Mxx   = putMi(c[2]);
@@ -133,5 +133,5 @@
     return;
   case 3:
-    image[0].Mcal_PS = c[0];
+    image[0].Mcal = c[0];
     image[0].Mx    = putMi(c[1]);
     image[0].Mxx   = putMi(c[2]);
@@ -145,5 +145,5 @@
     return;
   case 4:
-    image[0].Mcal_PS = c[0];
+    image[0].Mcal = c[0];
     image[0].Mx    = putMi(c[1]);
     image[0].Mxx   = putMi(c[2]);
@@ -162,5 +162,5 @@
     return;
   default:
-    image[0].Mcal_PS = 0.0;
+    image[0].Mcal = 0.0;
     image[0].order = 0;
     return;
Index: trunk/Ohana/src/libdvo/src/skyregion_gsc.c
===================================================================
--- trunk/Ohana/src/libdvo/src/skyregion_gsc.c	(revision 11991)
+++ trunk/Ohana/src/libdvo/src/skyregion_gsc.c	(revision 12332)
@@ -209,6 +209,6 @@
   SkyRegion *regions;
   SkyRegion tempregion;
-  char **filename;
-  char *tempfile;
+  char *tempfile = NULL;
+  char **filename = NULL;
   
   N = table[0].Nregions;
