Index: /trunk/Ohana/src/opihi/dvo/Makefile
===================================================================
--- /trunk/Ohana/src/opihi/dvo/Makefile	(revision 3460)
+++ /trunk/Ohana/src/opihi/dvo/Makefile	(revision 3461)
@@ -72,4 +72,5 @@
 $(SDIR)/lcat.$(ARCH).o		  	\
 $(SDIR)/lcurve.$(ARCH).o	  	\
+$(SDIR)/lightcurve.$(ARCH).o	  	\
 $(SDIR)/mextract.$(ARCH).o	  	\
 $(SDIR)/pcat.$(ARCH).o		  	\
Index: /trunk/Ohana/src/opihi/dvo/init.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/init.c	(revision 3460)
+++ /trunk/Ohana/src/opihi/dvo/init.c	(revision 3461)
@@ -1,3 +1,3 @@
-# include "dvo.h"
+# include "dvo1.h"
 
 int avextract	    PROTO((int, char **));
@@ -35,4 +35,5 @@
 int lcat	    PROTO((int, char **));
 int lcurve	    PROTO((int, char **));
+int lightcurve	    PROTO((int, char **));
 int mextract	    PROTO((int, char **));
 int pcat	    PROTO((int, char **));
@@ -83,4 +84,5 @@
   {"lcat",    	  lcat,         "list catalogs in region"},
   {"lcurve",      lcurve,       "plot lightcurve for a star"},
+  {"lightcurve",  lightcurve,   "extract lightcurve for a star"},
   {"mextract",    mextract,     "extract measure data values"},
   {"pcat",    	  pcat,         "plot catalog boundaries"},
Index: /trunk/Ohana/src/opihi/dvo/lightcurve.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/lightcurve.c	(revision 3461)
+++ /trunk/Ohana/src/opihi/dvo/lightcurve.c	(revision 3461)
@@ -0,0 +1,149 @@
+# include "dvo1.h"
+
+int lightcurve (int argc, char **argv) {
+  
+  char filename[128], catdir[256];
+  double Ra, Dec, Radius, Radius2, r;
+  float *RA, *DEC;
+  int Nstars, found, PhotCodeSelect;
+  int i, j, k, m, N, NPTS, Nsec, RELPHOT, *N1, Nregions, TimeFormat;
+  time_t TimeReference;
+  RegionFile *regions;
+  Vector *tvec, *mvec, *dmvec;
+  Catalog catalog;
+  PhotCode *code;
+
+  VarConfig ("CATDIR", "%s", catdir);
+  if (!InitPhotcodes ()) return (FALSE);
+  Nsec = GetPhotcodeNsecfilt ();
+
+  if ((tvec = SelectVector ("tc", ANYVECTOR, TRUE)) == NULL) return (FALSE);
+  if ((mvec = SelectVector ("mc", ANYVECTOR, TRUE)) == NULL) return (FALSE);
+  if ((dmvec = SelectVector ("dmc", ANYVECTOR, TRUE)) == NULL) return (FALSE);
+
+  RELPHOT = FALSE;
+  if ((N = get_argument (argc, argv, "-rel"))) {
+    remove_argument (N, &argc, argv);
+    RELPHOT = TRUE;
+  }
+
+  PhotCodeSelect = FALSE;
+  if ((N = get_argument (argc, argv, "-photcode"))) {
+    remove_argument (N, &argc, argv);
+    if ((code = GetPhotcodebyName (argv[N])) == NULL) {
+      fprintf (stderr, "ERROR: photcode not found in photcode table\n");
+      return (FALSE);
+    }
+    PhotCodeSelect = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+
+  if (argc < 4) {
+    fprintf (stderr, "USAGE: lightcurve RA DEC Radius\n");
+    return (FALSE);
+  }
+  
+  Ra = atof (argv[1]);
+  Dec = atof (argv[2]);
+  Radius = atof (argv[3]);
+
+  regions = find_regions (Ra, Dec, Radius, &Nregions);
+
+  if (Nregions > 1) {
+    fprintf (stderr, "warning, radius overlaps region boundary, not yet implemented\n");
+  }
+
+  /* set filename, read in header */
+  sprintf (filename, "%s/%s", catdir, regions[0].name);
+  catalog.filename = filename;
+  switch (lock_catalog (&catalog, LCK_SOFT)) {
+  case 2:
+    unlock_catalog (&catalog);
+  case 0:
+    return (FALSE);
+  }
+  if (!load_catalog (&catalog, LOAD_AVES | LOAD_MEAS | LOAD_SECF, TRUE)) {
+    unlock_catalog (&catalog);
+    return (FALSE);
+  }
+  unlock_catalog (&catalog);
+
+  Nstars = catalog.Naverage;
+  ALLOCATE (RA, float, Nstars);
+  ALLOCATE (DEC, float, Nstars);
+  ALLOCATE (N1, int, Nstars);
+
+  /* find star(s) in RA, DEC list -- use a dumb algorithm for now, improve later */
+  /* stars are not guaranteed to be sorted in RA or in DEC, so first sort the list */
+  for (i = 0; i < Nstars; i++) {
+    RA[i] = catalog.average[i].R;
+    DEC[i] = catalog.average[i].D;
+    N1[i] = i;
+  }
+  /* sort list by DEC */
+  if (Nstars > 1) sort_lists (DEC, RA, N1, Nstars);
+  /* at this point, RA, DEC, and N1 are sorted by DEC.  
+     catalog.average[N1[i]].R = RA[i] */
+
+  N = 0;
+  NPTS = 100;
+  REALLOCATE (tvec[0].elements, float, NPTS);
+  REALLOCATE (mvec[0].elements, float, NPTS);
+  REALLOCATE (dmvec[0].elements, float, NPTS);
+  
+  GetTimeFormat (&TimeReference, &TimeFormat);
+
+  Radius2 = Radius*Radius;
+  found = FALSE;
+  for (i = 0; (i < catalog.Naverage) && !found; i++) {
+
+    /* this can be improved by using a couple of jumps to get within range */
+    if (Dec > DEC[i] + Radius)
+      continue;
+    
+    r = SQ(Dec - DEC[i]) + SQ(Ra - RA[i]);
+    if (r < Radius2) {
+      k = N1[i];
+      /* found star, extract measurements */
+      m = catalog.average[k].offset;
+      for (j = 0; j < catalog.average[k].Nm; j++, m++) {
+
+	if (PhotCodeSelect) {
+	  if ((code[0].type == PHOT_REF) || (code[0].type == PHOT_DEP)) {
+	    if (code[0].code != catalog.measure[m].source) continue;
+	  } 
+	  if ((code[0].type == PHOT_PRI) || (code[0].type == PHOT_SEC)) {
+	    if (code[0].code != GetPhotcodeEquivCodebyCode (catalog.measure[m].source)) continue;
+	  } 
+	}      
+
+	tvec[0].elements[N] = TimeValue (catalog.measure[m].t, TimeReference, TimeFormat);
+	dmvec[0].elements[N] = 0.001*catalog.measure[m].dM;
+	if (RELPHOT) {
+	  mvec[0].elements[N] = PhotCat (&catalog.measure[m]);
+	} else {
+	  mvec[0].elements[N] = PhotRel (&catalog.measure[m], &catalog.average[k], &catalog.secfilt[k*Nsec]);
+	}
+	N++; 
+	if (N == NPTS) {
+	  NPTS += 100;
+	  REALLOCATE (tvec[0].elements, float, NPTS);
+	  REALLOCATE (mvec[0].elements, float, NPTS);
+	  REALLOCATE (dmvec[0].elements, float, NPTS);
+	}
+      }      
+    }
+  }
+  sortthree (tvec[0].elements, mvec[0].elements, dmvec[0].elements, N);
+  tvec[0].Nelements = mvec[0].Nelements = dmvec[0].Nelements = N;
+
+  free (RA);
+  free (DEC);
+  free (N1);
+  if (catalog.average != 0) free (catalog.average);
+  if (catalog.measure != 0) free (catalog.measure);
+  if (catalog.secfilt != 0) free (catalog.secfilt);
+ 
+  return (TRUE);
+
+}
