Index: trunk/Ohana/src/opihi/dvo/Makefile
===================================================================
--- trunk/Ohana/src/opihi/dvo/Makefile	(revision 27593)
+++ trunk/Ohana/src/opihi/dvo/Makefile	(revision 27594)
@@ -28,4 +28,5 @@
 $(SRC)/dvomisc.$(ARCH).o		\
 $(SRC)/region_list.$(ARCH).o		\
+$(SRC)/find_matches.$(ARCH).o		\
 $(SRC)/photometry.$(ARCH).o             \
 $(SRC)/dbBooleanCond.$(ARCH).o		\
@@ -43,4 +44,5 @@
 cmds = \
 $(SRC)/avextract.$(ARCH).o	  	\
+$(SRC)/avmatch.$(ARCH).o	  	\
 $(SRC)/badimages.$(ARCH).o	  	\
 $(SRC)/calextract.$(ARCH).o      	\
Index: trunk/Ohana/src/opihi/dvo/avextract.c
===================================================================
--- trunk/Ohana/src/opihi/dvo/avextract.c	(revision 27593)
+++ trunk/Ohana/src/opihi/dvo/avextract.c	(revision 27594)
@@ -182,5 +182,4 @@
 
   if ((argc > N + 1) && !strcasecmp (argv[N+1], "fields")) {
-    gprint (GP_ERR, " USAGE: avextract field[,field,field...] where (expression)\n");
     gprint (GP_ERR, "  RA : right ascension (J2000) [degrees]\n");
     gprint (GP_ERR, "  DEC : declination [degrees]\n");
Index: trunk/Ohana/src/opihi/dvo/avmatch.c
===================================================================
--- trunk/Ohana/src/opihi/dvo/avmatch.c	(revision 27594)
+++ trunk/Ohana/src/opihi/dvo/avmatch.c	(revision 27594)
@@ -0,0 +1,220 @@
+# include "dvoshell.h"
+
+/* This function uses the 'find_match' algorithm to select the objects of interest.
+   Each entry in the match vectors (RA, DEC, RADIUS) yields a result value -- if no
+   source matches, the resulting fields are all NAN.
+
+   * choose the sky regions based on the provided RA,DEC points
+   * loop over the catalogs
+   * within a catalog, use the find_match code to find the matching coordinates
+   * use dbExtractAverages to get the fields for the matched entry 
+ */
+
+int avmatch (int argc, char **argv) {
+  
+  off_t i, j, n, m, *index;
+  int N, Ncat, Npts, NPTS, last, Nfields, Nsecfilt;
+  int VERBOSE;
+  char name[1024];
+  void *Signal;
+  float RADIUS;
+
+  Catalog catalog;
+
+  Vector **vec, *RAvec, *DECvec;
+  dbField *fields;
+  dbValue *values;
+  SkyList *skylist;
+
+  /* defaults */
+  vec = NULL;
+  fields = NULL;
+  values = NULL;
+  skylist = NULL;
+
+  if ((N = get_argument (argc, argv, "-h"))) goto help;
+  if ((N = get_argument (argc, argv, "--help"))) goto help;
+  if (argc < 5) goto help;
+
+  VERBOSE = FALSE;
+  if ((N = get_argument (argc, argv, "-v"))) {
+    remove_argument (N, &argc, argv);
+    VERBOSE = TRUE;
+  }
+
+  dvo_catalog_init (&catalog, TRUE);
+
+  /* load photcode information */
+  if (!InitPhotcodes ()) goto escape;
+  Nsecfilt = GetPhotcodeNsecfilt ();
+
+  // get vectors corresponding to coordinates of interest
+  if ((RAvec  = SelectVector (argv[1], ANYVECTOR, TRUE)) == NULL) goto help;
+  if ((DECvec = SelectVector (argv[2], ANYVECTOR, TRUE)) == NULL) goto help;
+  RADIUS = atof (argv[3]);
+
+  // strip off RA, DEC, RADIUS arguments
+  remove_argument (1, &argc, argv);
+  remove_argument (1, &argc, argv);
+  remove_argument (1, &argc, argv);
+
+  // parse the fields to be extracted and returned
+  fields = dbCmdlineFields (argc, argv, DVO_TABLE_AVERAGE, &last, &Nfields);
+  if (fields == NULL) goto help;
+  if ((Nfields == 0) || (last != argc)) {
+    dbFreeFields (fields, Nfields);
+    dvo_catalog_free (&catalog);
+    goto help;
+  }
+
+  /* load regions which contain all supplied RA,DEC coordinates */
+  if ((skylist = SelectRegionsByCoordVectors (RAvec, DECvec)) == NULL) goto escape;
+
+  /* create output storage vectors */
+  NPTS = RAvec->Nelements;
+  ALLOCATE (values, dbValue, Nfields);
+  ALLOCATE (vec, Vector *, Nfields);
+  for (i = 0; i < Nfields; i++) {
+    if (ISNUM(fields[i].name[0])) {
+      sprintf (name, "v_%s", fields[i].name);
+    } else {
+      sprintf (name, "%s", fields[i].name);
+    }
+    if ((vec[i] = SelectVector (name, ANYVECTOR, TRUE)) == NULL) goto escape;
+    ResetVector (vec[i], fields[i].type, NPTS);
+  }
+  ALLOCATE (index, off_t, NPTS);
+
+  // grab data from all selected sky regions
+  Signal = signal (SIGINT, handle_interrupt);
+  interrupt = FALSE;
+  for (i = 0; (i < skylist[0].Nregions) && !interrupt; i++) {
+    /* lock, load, unlock catalog */
+    catalog.filename = skylist[0].filename[i];
+    catalog.catflags = LOAD_AVES | LOAD_MEAS | LOAD_SECF;
+    catalog.Nsecfilt = 0;
+
+    if (VERBOSE) gprint (GP_ERR, "trying %s (%lld of %lld)\n", catalog.filename, (long long) i, (long long) skylist[0].Nregions);
+      
+    // an error exit status here is a significant error
+    if (!dvo_catalog_open (&catalog, NULL, FALSE, "r")) {
+      gprint (GP_ERR, "ERROR: failure to open catalog file %s\n", catalog.filename);
+      exit (2);
+    }
+    dvo_catalog_unlock (&catalog);  /// we can unlock here since this is read-only (do not block other access)
+
+    find_matches_by_vectors (skylist[0].regions[i], &catalog, RAvec, DECvec, RADIUS, index);
+
+    for (j = 0; (j < NPTS) && !interrupt; j++) {
+      Ncat = index[j];
+      Npts = j;
+
+      if (Ncat == -1) continue;
+      if (Ncat == -2) {
+	for (n = 0; n < Nfields; n++) {
+	  if (vec[n][0].type == OPIHI_FLT) {
+	    vec[n][0].elements.Flt[Npts] = NAN;
+	  } else {
+	    vec[n][0].elements.Int[Npts] = 0; // or NAN_INT?
+	  }
+	}
+	continue;
+      }
+      // XXX set a 'found' vector to double check we catch everything?
+      m = catalog.average[Ncat].measureOffset;
+
+      // reset counters for saved fields, extract fields
+      dbExtractAveragesInit (); 
+      for (n = 0; n < Nfields; n++) {
+	values[n] = dbExtractAverages (&catalog.average[Ncat], &catalog.secfilt[Ncat*Nsecfilt], &catalog.measure[m], &fields[n]);
+      }
+
+      // XXX if we are allowed to return more rows than the supplied RA,DEC we will need to create an output RA,DEC
+      for (n = 0; n < Nfields; n++) {
+	if (vec[n][0].type == OPIHI_FLT) {
+	  vec[n][0].elements.Flt[Npts] = values[n].Flt;
+	} else {
+	  vec[n][0].elements.Int[Npts] = values[n].Int;
+	}
+      }
+    }
+    dvo_catalog_free (&catalog);
+  }
+  signal (SIGINT, Signal);
+  interrupt = FALSE;
+
+  if (vec) free (vec);
+  if (values) free (values);
+  dbFreeFields (fields, Nfields);
+  SkyListFree (skylist);
+  dvo_catalog_free (&catalog);
+  return (TRUE);
+
+ escape:
+  if (vec) free (vec);
+  if (values) free (values);
+  dbFreeFields (fields, Nfields);
+  SkyListFree (skylist);
+  dvo_catalog_free (&catalog);
+  return (FALSE);
+
+ help:
+  gprint (GP_ERR, "USAGE: avmatch (RA) (DEC) (RADIUS) field[,field,field...]\n");
+
+  if ((argc > N + 1) && !strcasecmp (argv[N+1], "fields")) {
+    gprint (GP_ERR, "  RA : right ascension (J2000) [degrees]\n");
+    gprint (GP_ERR, "  DEC : declination [degrees]\n");
+    gprint (GP_ERR, "  GLON : galactic longitude [degrees]\n");
+    gprint (GP_ERR, "  GLAT : galactic latitude [degrees]\n");
+    gprint (GP_ERR, "  ELON : ecliptic longitude [degrees]\n");
+    gprint (GP_ERR, "  ELAT : ecliptic latitude [degrees]\n");
+    gprint (GP_ERR, "  dRA : ra scatter [degrees]\n");
+    gprint (GP_ERR, "  dDEC : dec scatter [degrees]\n");
+    gprint (GP_ERR, "  uRA : proper motion in ra [arcseconds]\n");
+    gprint (GP_ERR, "  uDEC : proper motion in dec [arcseconds]\n");
+    gprint (GP_ERR, "  duRA : proper motion error in ra [arcseconds]\n");
+    gprint (GP_ERR, "  duDEC : proper motion error in dec [arcseconds]\n");
+    gprint (GP_ERR, "  PAR : parallax\n");
+    gprint (GP_ERR, "  dPAR : parallax error \n");
+
+    gprint (GP_ERR, "  ChiSqPos : chi square of position fit \n");
+    gprint (GP_ERR, "  ChiSqPM  : chi square of proper-motion fit \n");
+    gprint (GP_ERR, "  ChiSqPar : chi square of parallax fit \n");
+
+    gprint (GP_ERR, "  Tmean : mean epoch (reference for proper motion)\n");
+    gprint (GP_ERR, "  Trange : range of times used for proper motion/parallax fit\n");
+
+    gprint (GP_ERR, "  Nmeas : number of measurements\n");
+    gprint (GP_ERR, "  Nmiss : number of non-detections\n");
+    gprint (GP_ERR, "  Npos  : number of measurments used for astrometry\n");
+    gprint (GP_ERR, "  Nastrom  : number of measurments used for astrometry (= Npos)\n");
+
+    gprint (GP_ERR, "  flags     : object flags\n");
+    gprint (GP_ERR, "  objflags  : object flags\n");
+    gprint (GP_ERR, "  obj_flags : object flags\n");
+
+    gprint (GP_ERR, "  objID : object ID (32 bit, unique in catalog)\n");
+    gprint (GP_ERR, "  catID : catalog ID (32 bit)\n");
+    gprint (GP_ERR, "  extID_hi : external ID (upper 32 of 64 bit) -- eg, PSPS ID\n");
+    gprint (GP_ERR, "  extID_lo : external ID (lower 32 of 64 bit) -- eg, PSPS ID\n");
+
+    gprint (GP_ERR, "  <photcode>:ave : average magnitude for <photcode>\n");
+    gprint (GP_ERR, "  <photcode>:ref : reference magnitude system for <photcode>\n");
+    gprint (GP_ERR, "  <photcode>:inst : first instrumental magnitude for <photcode>\n");
+    gprint (GP_ERR, "  <photcode>:cat : first catalog magnitude for <photcode>\n");
+    gprint (GP_ERR, "  <photcode>:sys : first system magnitude for <photcode>\n");
+    gprint (GP_ERR, "  <photcode>:rel : first relative magnitude for <photcode>\n");
+    gprint (GP_ERR, "  <photcode>:cal : first calibrated magnitude for <photcode> \n");
+    gprint (GP_ERR, "  <photcode>:err : magnitude error for photcode\n");
+    gprint (GP_ERR, "  <photcode>:chisq : raw chi-square of magnitude fit\n");
+    gprint (GP_ERR, "  <photcode>:ncode : number of measurements matching photcode \n");
+    gprint (GP_ERR, "  <photcode>:nphot : number of measurements used for average magnitude in this photcode\n");
+
+    // gprint (GP_ERR, "  Xp : NOT VALID\n");
+    // gprint (GP_ERR, "  type : dophot type (unused)\n");
+    // gprint (GP_ERR, "  typefrac : dophot type fraction (unused)\n");
+    return (FALSE);
+  }
+  gprint (GP_ERR, " avextract --help fields : for a complete listing of allowed fields\n");
+  return (FALSE);
+}
Index: trunk/Ohana/src/opihi/dvo/dbCmdlineFields.c
===================================================================
--- trunk/Ohana/src/opihi/dvo/dbCmdlineFields.c	(revision 27593)
+++ trunk/Ohana/src/opihi/dvo/dbCmdlineFields.c	(revision 27594)
@@ -57,5 +57,5 @@
   status = FALSE;
 
-  // examine each argv[i] entry until we reach a 'where' or a 'matched' 
+  // examine each argv[i] entry until we reach a 'where', a 'matched', or the end of the line
   for (i = 1; (i < argc) && strcasecmp (argv[i], "where") && strcasecmp (argv[i], "match"); i++) {
     // split the word by ","
Index: trunk/Ohana/src/opihi/dvo/find_matches.c
===================================================================
--- trunk/Ohana/src/opihi/dvo/find_matches.c	(revision 27594)
+++ trunk/Ohana/src/opihi/dvo/find_matches.c	(revision 27594)
@@ -0,0 +1,132 @@
+# include "dvoshell.h"
+
+// SkyRegion *region, Stars *stars, unsigned int NstarsIn, Catalog *catalog, AddstarClientOptions options)
+
+// attempt to match every RA,DEC entry with an entry in the catalog.  the result is stored in 'index'
+// index >= 0 : valid match; index == -2 : no valid match; index == -1 : not contained by this catalog
+int find_matches_by_vectors (SkyRegion *region, Catalog *catalog, Vector *RAvec, Vector *DECvec, float RADIUS, off_t *index) {
+
+  off_t i, j, J, Jmin, n, N, Npoints;
+  off_t *N1, *N2;
+  double *X1, *Y1, *X2, *Y2;
+  double dX, dY, dR;
+  int status;
+  double RADIUS2, Rmin;
+  off_t Nave;
+  Coords tcoords;
+
+  assert(catalog[0].sorted);
+
+  Npoints = RAvec->Nelements;
+
+  /** allocate local arrays (points) **/
+  ALLOCATE (X1, double, Npoints);
+  ALLOCATE (Y1, double, Npoints);
+  ALLOCATE (N1, off_t,  Npoints);
+
+  /** allocate local arrays (catalog) **/
+  Nave = catalog[0].Naverage;
+  ALLOCATE (X2, double, Nave);
+  ALLOCATE (Y2, double, Nave);
+  ALLOCATE (N2, off_t,  Nave);
+
+  /* project onto rectilinear grid with 1 arcsec pixels. the choice of ARC projection has
+   * the advantage that every point in R,D has a mapping to a unique X,Y.  However, note
+   * that not all possible X,Y points map back to R,D and the local plate scale changes
+   * far from the projection pole. We use the center of the region (catalog) for crval1,2.
+   */
+  tcoords.crval1 = 0.5*(region[0].Rmin + region[0].Rmax);
+  if (region[0].Dmax < 90) {
+    tcoords.crval2 = 0.5*(region[0].Dmin + region[0].Dmax);
+  } else {
+    tcoords.crval2 = 90.0;
+  }
+  tcoords.crpix1 = 0;
+  tcoords.crpix2 = 0;
+  tcoords.cdelt1 = tcoords.cdelt2 = 1.0 / 3600.0;
+  tcoords.pc1_1 = tcoords.pc2_2 = 1.0;
+  tcoords.pc1_2 = tcoords.pc2_1 = 0.0;
+  tcoords.Npolyterms = 1;
+  strcpy (tcoords.ctype, "RA---ARC");
+
+  // identify the entries contained by this catalog & init index
+  for (i = 0; i < Npoints; i++) {
+    index[i] = -1;
+    if (RAvec->elements.Flt[i] < region[0].Rmin) continue;
+    if (RAvec->elements.Flt[i] > region[0].Rmax) continue;
+    if (DECvec->elements.Flt[i] < region[0].Dmin) continue;
+    if (DECvec->elements.Flt[i] > region[0].Dmax) continue;
+    index[i] = -2;
+  }
+
+  /* build spatial index (RA sort) referencing input array sequence */
+  for (i = 0; i < Npoints; i++) {
+    X1[i] = Y1[i] = NAN;
+    N1[i] = i;
+    if (index[i] == -1) continue;
+    status = RD_to_XY (&X1[i], &Y1[i], RAvec->elements.Flt[i], DECvec->elements.Flt[i], &tcoords);
+    assert (status);
+  }
+  if (Npoints > 1) sort_coords_index (X1, Y1, N1, Npoints);
+
+  /* build spatial index (RA sort) */
+  for (i = 0; i < Nave; i++) {
+    RD_to_XY (&X2[i], &Y2[i], catalog[0].average[i].R, catalog[0].average[i].D, &tcoords);
+    N2[i] = i;
+  }
+  if (Nave > 1) sort_coords_index (X2, Y2, N2, Nave);
+
+  /* choose a radius for matches */
+  RADIUS2 = RADIUS*RADIUS;
+
+# define NEXTi { i++; continue; }                                                                                                                                                
+# define NEXTj { j++; continue; }                                                                                                                                                
+                                                                                                                                                                                 
+  /** find matched stars **/
+  for (i = j = 0; (i < Npoints) && (j < Nave); ) {
+    if (index[i] == -1) NEXTi;
+    if (!finite(X1[i]) || !finite(Y1[i])) NEXTi;
+    if (!finite(X2[j]) || !finite(Y2[j])) NEXTj;
+    
+    /* negative dX: j is too large */
+    dX = X1[i] - X2[j];
+    if (dX <= -1.02*RADIUS) NEXTi;
+
+    /* positive dX, i is too large */
+    if (dX >= 1.02*RADIUS) NEXTj;
+
+    /* within match range; look for matches */
+    Jmin = -1;
+    Rmin = RADIUS2;
+    for (J = j; (dX > -1.02*RADIUS) && (J < Nave); J++) {
+      /* find closest match for this detection */
+      dX = X1[i] - X2[J];
+      dY = Y1[i] - Y2[J];
+      dR = dX*dX + dY*dY;
+      if (dR > RADIUS2) continue;
+      if (dR < Rmin) {
+	Rmin = dR;
+	Jmin  = J;
+      }
+    }
+
+    /* no match, try next detection */ 
+    if (Jmin == -1) NEXTi;
+
+    /*** a match is found, set the index for this entry ***/
+    n = N2[Jmin];
+    N = N1[i];
+    index[N] = n;
+
+    NEXTi;
+  }
+
+  free (X1);
+  free (Y1);
+  free (N1);
+  free (N2);
+  free (X2);
+  free (Y2);
+
+  return (TRUE);
+}
Index: trunk/Ohana/src/opihi/dvo/init.c
===================================================================
--- trunk/Ohana/src/opihi/dvo/init.c	(revision 27593)
+++ trunk/Ohana/src/opihi/dvo/init.c	(revision 27594)
@@ -2,4 +2,5 @@
 
 int avextract       PROTO((int, char **));
+int avmatch         PROTO((int, char **));
 int badimages       PROTO((int, char **));
 int calextract      PROTO((int, char **));
@@ -55,4 +56,5 @@
 static Command cmds[] = {  
   {1, "avextract",   avextract,    "extract average data values"},
+  {1, "avmatch",     avmatch,      "extract average data values matched to RA,DEC points"},
   {1, "badimages",   badimages,    "look for images with anomalous astrometry"},
   {1, "calextract",  calextract,   "extract photometry calibration"},
Index: trunk/Ohana/src/opihi/dvo/mextract.c
===================================================================
--- trunk/Ohana/src/opihi/dvo/mextract.c	(revision 27593)
+++ trunk/Ohana/src/opihi/dvo/mextract.c	(revision 27594)
@@ -202,5 +202,4 @@
 
   if ((argc > N + 1) && !strcasecmp (argv[N+1], "fields")) {
-    gprint (GP_ERR, " USAGE: avextract field[,field,field...] where (expression)\n");
     gprint (GP_ERR, "  RA : right ascension (J2000) for detection [degrees]\n");
     gprint (GP_ERR, "  DEC : declination for detection [degrees]\n");
Index: trunk/Ohana/src/opihi/dvo/skyregion.c
===================================================================
--- trunk/Ohana/src/opihi/dvo/skyregion.c	(revision 27593)
+++ trunk/Ohana/src/opihi/dvo/skyregion.c	(revision 27594)
@@ -44,2 +44,105 @@
   return TRUE;
 }
+
+/* find region which overlaps c at given depth (-1 : populated ) */
+int SkyRegionByPoint_r (SkyTable *table, SkyList *list, int depth, double ra, double dec) {
+  
+  int i, Ns, Ne, No;
+  SkyRegion *skyregion;
+
+  list[0].Nregions = 0;
+  list[0].ownElements = FALSE; // this list is only holding a view to the elements
+
+  skyregion = table[0].regions;
+
+  Ns = 0;
+  Ne = 1;
+
+  while (1) {
+    No = -1;
+    for (i = Ns; (i < Ne) && (i < table[0].Nregions); i++) {
+      if (ra  < skyregion[i].Rmin) continue;
+      if (ra  > skyregion[i].Rmax) continue;
+      if (dec < skyregion[i].Dmin) continue;
+      if (dec > skyregion[i].Dmax) continue;
+      No = i;
+      break;
+    }
+    if (No == -1) return (FALSE);
+    if ((depth == -1) && (skyregion[No].table)) break;
+    if (depth == skyregion[No].depth) break;
+    if ((depth > skyregion[No].depth) && !skyregion[No].child) return (FALSE);
+
+    /* need to check Ns, Ne, or guarantee valid range */
+    Ns = skyregion[No].childS;
+    Ne = skyregion[No].childE;
+  }
+
+  list[0].regions[0] = &skyregion[No];
+  list[0].filename[0] = table[0].filename[No];
+  list[0].Nregions = 1;
+  return (TRUE);
+}
+
+SkyList *SelectRegionsByCoordVectors (Vector *RA, Vector *DEC) {
+  
+  int i, j, Npts, Nout, NOUT, *found;
+  double ra, dec;
+  SkyList *new, *list;
+  SkyTable *sky;
+
+  sky = GetSkyTable ();
+
+  Npts = RA->Nelements;
+  ALLOCATE (found, int, Npts);
+  memset (found, 0, Npts*sizeof(int));
+
+  ALLOCATE (new, SkyList, 1);
+  ALLOCATE (new[0].regions,  SkyRegion *, 1);
+  ALLOCATE (new[0].filename,  char *, 1);
+
+  // output list
+  Nout = 0;
+  NOUT = 100;
+  ALLOCATE (list, SkyList, 1);
+  ALLOCATE (list[0].regions,  SkyRegion *, NOUT);
+  ALLOCATE (list[0].filename,  char *, NOUT);
+  list[0].Nregions = 0;
+  list[0].ownElements = FALSE; // this list is only holding a view to the elements
+
+  for (i = 0; i < Npts; i++) {
+    if (found[i]) continue;
+
+    SkyRegionByPoint_r (sky, new, -1, RA->elements.Flt[i], DEC->elements.Flt[i]);
+    if (new->Nregions == 0) continue;
+    assert (new->Nregions == 1);
+    // append new region to output list
+    list[0].regions[Nout] = new[0].regions[0];
+    list[0].filename[Nout] = new[0].filename[0];
+    Nout ++;
+    if (Nout >= NOUT) {
+	NOUT += 100;
+	REALLOCATE (list[0].regions, SkyRegion *, NOUT);
+	REALLOCATE (list[0].filename, char *, NOUT);
+    }
+    found[i] = TRUE;
+
+    // scan over the remaining points to find any that lie within this region
+    // if we sorted the ra,dec inputs we could break out of this more quickly
+    for (j = i + 1; j < Npts; j++) {
+      ra = RA->elements.Flt[j];
+      dec = DEC->elements.Flt[j];
+      if (ra  < new[0].regions[0][0].Rmin) continue;
+      if (ra  > new[0].regions[0][0].Rmax) continue;
+      if (dec < new[0].regions[0][0].Dmin) continue;
+      if (dec > new[0].regions[0][0].Dmax) continue;
+      found[j] = TRUE;
+    }
+  }
+
+  free (found);
+  SkyListFree (new);
+
+  return (list);
+}
+
Index: trunk/Ohana/src/opihi/include/dvoshell.h
===================================================================
--- trunk/Ohana/src/opihi/include/dvoshell.h	(revision 27593)
+++ trunk/Ohana/src/opihi/include/dvoshell.h	(revision 27594)
@@ -314,4 +314,9 @@
 SkyRegionSelection *SetRegionSelection    PROTO((int *argc, char **argv));
 
+int           SkyRegionByPoint_r    PROTO((SkyTable *table, SkyList *list, int depth, double ra, double dec));
+SkyList      *SelectRegionsByCoordVectors PROTO((Vector *RA, Vector *DEC));
+
+int           find_matches_by_vectors PROTO((SkyRegion *region, Catalog *catalog, Vector *RAvec, Vector *DECvec, float RADIUS, off_t *index));
+
 int           SetImageSelection     PROTO((int mode, SkyRegionSelection *selection));
 int           SetPhotSelections     PROTO((int *argc, char **argv, int Nparams));
