Index: /trunk/Makefile
===================================================================
--- /trunk/Makefile	(revision 53)
+++ /trunk/Makefile	(revision 54)
@@ -77,7 +77,11 @@
 	cp pvoconvert.x $(INSTALLDIR)/pvoconvert
 	cp pvosummary.x $(INSTALLDIR)/pvosummary
+	cp pvoconesearch.x $(INSTALLDIR)/pvoconesearch
 
 pvosummary : $(BASE)/pvosummary.o $(HEADER) $(BLOCK) $(PSRFITS) $(UTILS)
 	$(CXX) -o pvosummary.x $(BASE)/pvosummary.o $(HEADER) $(BLOCK) $(PSRFITS) $(UTILS) $(LIBS)
+
+pvoconesearch : $(BASE)/pvoconesearch.o $(HEADER) $(BLOCK) $(PSRFITS) $(UTILS)
+	$(CXX) -o pvoconesearch.x $(BASE)/pvoconesearch.o $(HEADER) $(BLOCK) $(PSRFITS) $(UTILS) $(LIBS)
 
 pvosummary2 : $(BASE)/pvosummary-glob.o $(HEADER) $(BLOCK) $(PSRFITS) $(UTILS)
Index: /trunk/Makefile.psr
===================================================================
--- /trunk/Makefile.psr	(revision 53)
+++ /trunk/Makefile.psr	(revision 54)
@@ -4,5 +4,5 @@
 include $(LOCAL_ROOT)/include/Makefile.standard
 
-# BINDIR = $(PSRHOME)/bin/$(LOGIN_ARCH)
+ BINDIR = $(PSRHOME)/bin/$(LOGIN_ARCH)
 
 INCLUDES = pvo-FITS.hh  pvo-block.hh  pvo-header.hh  pvo-utils.hh
@@ -18,5 +18,5 @@
 # LDFLAGS := $(LDFLAGS) -lcfitsio -lm
 
-PROGRAMS = pvoconvert.C pvosummary.C
+PROGRAMS = pvoconvert.C pvosummary.C pvoconesearch.C
 
 pvoconvert.srcs = pvo-header.C  pvo-block.C  pvo-utils.C pvo-FITS.C  pvo-FITS-fileIO.C  
@@ -24,4 +24,6 @@
 pvosummary.srcs = pvo-header.C  pvo-block.C  pvo-utils.C pvo-FITS.C  pvo-FITS-fileIO.C  
 
+pvoconesearch.srcs = pvo-header.C  pvo-block.C  pvo-utils.C pvo-FITS.C  pvo-FITS-fileIO.C  
+
 include $(LOCAL_ROOT)/include/Makefile.extended
 
Index: /trunk/install_to_psr.sh
===================================================================
--- /trunk/install_to_psr.sh	(revision 53)
+++ /trunk/install_to_psr.sh	(revision 54)
@@ -14,4 +14,5 @@
 cp src/pvoconvert.cc      $PSRDEST/pvoconvert.C
 cp src/pvosummary.cc      $PSRDEST/pvosummary.C
+cp src/pvoconesearch.cc   $PSRDEST/pvoconesearch.C
 cp src/pvo-header.cc      $PSRDEST/pvo-header.C
 cp src/pvo-block.cc       $PSRDEST/pvo-block.C
Index: /trunk/src/pvo-FITS-fileIO.cc
===================================================================
--- /trunk/src/pvo-FITS-fileIO.cc	(revision 53)
+++ /trunk/src/pvo-FITS-fileIO.cc	(revision 54)
@@ -271,5 +271,5 @@
 
       }
-
+      return 0;
     }
     //--------------------------------------------------------------------------
@@ -516,5 +516,5 @@
 
     }
-    //--------------------------------------------------------------------------
+    //-----------------------------------------------------------------------
   
     void PSRFits::addNewKeywords(DataBlock &block)
@@ -529,5 +529,5 @@
     
     }
-    //--------------------------------------------------------------------------
+    //-----------------------------------------------------------------------
 
     void PSRFits::writeHistoryCommand()
Index: /trunk/src/pvo-FITS.cc
===================================================================
--- /trunk/src/pvo-FITS.cc	(revision 53)
+++ /trunk/src/pvo-FITS.cc	(revision 54)
@@ -295,5 +295,5 @@
       return status;
     }
-    //--------------------------------------------------------------------------
+    //------------------------------------------------------------------------
   
     template <typename T> int PSRFits::getKeyword(std::string name, T &value)
@@ -310,7 +310,5 @@
       fits_read_keyword(this->fptr, (char *)name.c_str(), keywordValue, 
 			keywordComment, &status);
-      if(status) {
-	if(PVO::verbose) this->FITSError("PSRFits::getKeyword",status);
-      }
+      if(status) this->FITSError("PSRFits::getKeyword",status);
       else{
 	std::stringstream ss;
@@ -329,7 +327,5 @@
       fits_read_keyword(this->fptr, (char *)name.c_str(), keywordValue, 
 			keywordComment, &status);
-      if(status) {
-	if(PVO::verbose) this->FITSError("PSRFits::getKeyword",status);
-      }
+      if(status) this->FITSError("PSRFits::getKeyword",status);
       else value = keywordValue;
       if(value[0]=='\'') value.erase(0,1);
@@ -339,5 +335,5 @@
     
   
-    //--------------------------------------------------------------------------
+    //------------------------------------------------------------------------
 
     int PSRFits::getColnum(char *name)
Index: /trunk/src/pvo-utils.cc
===================================================================
--- /trunk/src/pvo-utils.cc	(revision 53)
+++ /trunk/src/pvo-utils.cc	(revision 54)
@@ -22,5 +22,5 @@
     std::string preamble = "\aERROR <" + subroutine + "> : ";
     std::cerr << preamble;
-    for(int i=0;i<error.size();i++){
+    for(unsigned int i=0;i<error.size();i++){
       std::cerr << error[i];
       if((i!=error.size()-1)&&(error[i]=='\n'))
@@ -331,5 +331,5 @@
     std::string date_obs;
     bool hashyphens = false;
-    for(int i=0;i<date.size();i++) 
+    for(unsigned int i=0;i<date.size();i++) 
       hashyphens = hashyphens || (date[i]=='-') || (date[i] == '/');
     if(hashyphens) date_obs = date;
@@ -338,5 +338,5 @@
     if(date[0]=='0') date_obs = "20" + date_obs;
     else             date_obs = "19" + date_obs;
-    for(int i=0;i<date_obs.size();i++) 
+    for(unsigned int i=0;i<date_obs.size();i++) 
       if(date_obs[i]=='/') date_obs[i]='-';
 
@@ -346,4 +346,26 @@
 
   }
+  //------------------------------------------------------------------------
+
+  double angSep(std::string ra1, std::string dec1, 
+		std::string ra2, std::string dec2)
+  {
+    double r1,d1,r2,d2;
+    r1 = dmsToDec(ra1) * 15. * M_PI / 180.;
+    d1 = dmsToDec(dec1) * M_PI / 180.;
+    r2 = dmsToDec(ra2) * 15. * M_PI / 180.;
+    d2 = dmsToDec(dec2) * M_PI / 180.;
+    if((fabs(r1-r2)<0.01)&&(fabs(d1-d2)<0.01)){
+      return fabs(r1-r2)*cos(d1)*180./M_PI;
+    }
+    else{
+      long double angsep = // cos(r1-r2)*cos(d1)*cos(d2)
+	cos(r1)*cos(d1)*cos(r2)*cos(d2)
+	+ sin(r1)*cos(d1)*sin(r2)*cos(d2)
+	+ sin(d1)*sin(d2);
+      
+      return acosl(angsep)*180./M_PI;
+    }
+  }
 
 }
Index: /trunk/src/pvo-utils.hh
===================================================================
--- /trunk/src/pvo-utils.hh	(revision 53)
+++ /trunk/src/pvo-utils.hh	(revision 54)
@@ -8,5 +8,5 @@
 {
 
-  static bool verbose;
+//   static bool verbose;
   
   /** Report a general error, along with the offending function. */
@@ -56,4 +56,8 @@
   inline std::string decToDMS(double input){ return decToDMS(input,2,":"); };
 
+  /** Find the angular separation of two sky positions.*/
+  double angSep(std::string ra1, std::string dec1, 
+		std::string ra2, std::string dec2);
+
   std::string getIAUName(double ra, double dec);  
   ///< Create an IAU-style formatted name, based on the equatorial position.
Index: /trunk/src/pvoconesearch.cc
===================================================================
--- /trunk/src/pvoconesearch.cc	(revision 54)
+++ /trunk/src/pvoconesearch.cc	(revision 54)
@@ -0,0 +1,127 @@
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <iomanip>
+#include <string>
+#include <glob.h>
+#include "pvo-block.hh"
+#include "pvo-header.hh"
+#include "pvo-FITS.hh"
+#include "pvo-utils.hh"
+
+using namespace PVO;
+using namespace PVO::Header;
+using namespace PVO::Block;
+using namespace PVO::FITS;
+using std::string;
+
+
+const std::string help_text = 
+"Usage:\n\
+  1. pvoconesearch ra dec radius\n\
+  2. pvoconesearch -h\n\
+---------\n\
+  1. Prints RA, DEC, DATE-OBS, BEAMSIZE, OFFSET for all FITS files that\n\
+     lie within \"radius\" of the position given by ra, dec.\n\
+  3. Prints this help information.\n\
+ The RA and DEC should be in the form hh:mm:ss.ss etc.\n\
+ Note that if a keyword is not present, --- is printed.\n";
+
+int main(int argc, char * argv[])
+{
+
+  bool verboseflag = false;
+
+  std::vector<std::string> namelist;
+  std::string RAcentre,DECcentre;
+  double radius;
+  unsigned int i;
+  switch(argc){
+  case 4:
+    glob_t globbuf1,globbuf2;
+    globbuf1.gl_offs = 0;
+    globbuf2.gl_offs = 0;
+    glob("*.fits", GLOB_DOOFFS, NULL, &globbuf1);
+    glob("*.rf", GLOB_DOOFFS, NULL, &globbuf2);
+    namelist.resize(globbuf1.gl_pathc+globbuf2.gl_pathc);
+    for(i=0;i<globbuf1.gl_pathc+globbuf1.gl_offs;i++) 
+      namelist[i] = globbuf1.gl_pathv[i];
+    for(i=0;i<globbuf2.gl_pathc+globbuf2.gl_offs;i++) 
+      namelist[globbuf1.gl_pathc+i] = globbuf2.gl_pathv[i];
+
+    RAcentre = argv[1];
+    DECcentre = argv[2];
+    radius = atof(argv[3]) / 60.;
+    
+    std::cout << "RA = " << RAcentre
+	      << ", DEC = " << DECcentre
+	      << ", radius = " << radius << " deg\n";
+
+    break;
+  case 2:
+    //    if(strcmp(argv[1],"-h")==0){
+      std::cout << help_text;
+      return 0;
+      //    }
+    break;
+  default:
+    std::cerr << help_text;
+    return 0;
+    break;
+  }
+
+  int maxsize = 0;
+  for(i=0;i<namelist.size();i++) 
+    maxsize = std::max(maxsize,int(namelist[i].size()));
+
+  std::cout << std::setw(maxsize) << "FILE"      << ": "
+	    << std::setw(14)      << "RA"        << " "
+	    << std::setw(14)      << "DEC"       << " "
+	    << std::setw(30)      << "DATE-OBS"  << " "
+	    << std::setw(10)      << "BEAM FWHM"  << " "
+	    << std::setw(10)      << "OFFSET"    << "\n";
+  std::cout << std::setw(maxsize) << ""          << "  "
+	    << std::setw(14)      << ""          << " "
+	    << std::setw(14)      << ""          << " "
+	    << std::setw(30)      << ""          << " "
+	    << std::setw(10)      << "[arcmin]"  << " "
+	    << std::setw(10)      << "[arcmin]"  << "\n";
+
+
+  for(i=0;i<namelist.size();i++){
+
+    PSRFits fitsfile;
+    fitsfile.setVerbosity(verboseflag);
+    int status = fitsfile.openFile(namelist[i]);
+  
+    if(status==0){
+      fitsfile.gotoPHU();
+    
+      std::string ra,dec,date;
+      //     std::string missing = "N/A";
+      std::string missing = "---";
+      if(fitsfile.getKeyword<std::string>("RA",ra)!=0) ra = missing;
+      if(fitsfile.getKeyword<std::string>("DEC",dec)!=0) dec = missing;
+      if(fitsfile.getKeyword<std::string>("DATE-OBS",date)!=0) date = missing;
+      float beamradius,bmaj,bmin;
+      fitsfile.getKeyword<float>("BMAJ",bmaj);
+      fitsfile.getKeyword<float>("BMIN",bmin);
+      beamradius = 0.5*(bmaj+bmin)/2.;
+
+      if(ra!=missing && dec!=missing){
+	double angsep = angSep(ra,dec,RAcentre,DECcentre);
+// 	std::cerr << namelist[i] << " " << angsep<<"\n";
+	if(angsep < radius+beamradius){
+
+	  std::cout << std::setw(maxsize) << namelist[i] << ": "
+		    << std::setw(14)      << ra          << " "
+		    << std::setw(14)      << dec         << " "
+		    << std::setw(30)      << date        << " "
+		    << std::setw(10)      << beamradius*2.*60.<< " "
+		    << std::setw(10)      << angsep*60.  << "\n";
+	}
+      }
+    }
+  }
+
+}
Index: /trunk/src/pvosummary.cc
===================================================================
--- /trunk/src/pvosummary.cc	(revision 53)
+++ /trunk/src/pvosummary.cc	(revision 54)
@@ -16,4 +16,16 @@
 using std::string;
 
+
+const std::string help_text = 
+"Usage:\n\
+  1. pvosummary [FILE]\n\
+  2. pvosummary\n\
+  3. pvosummary -h\n\
+---------\n\
+  1. Prints RA, DEC, DATE-OBS for single FITS file.\n\
+  2. Prints RA, DEC, DATE-OBS for all fits files in the current directory.\n\
+  3. Prints this help information.\n\
+ Note that if a keyword is not present, --- is printed.\n";
+
 int main(int argc, char * argv[])
 {
@@ -22,5 +34,5 @@
 
   std::vector<std::string> namelist;
-  int i;
+  unsigned int i;
   switch(argc){
   case 1:
@@ -38,10 +50,5 @@
   case 2:
     if(strcmp(argv[1],"-h")==0){
-      std::cout << "Usage:\n"
-		<< "  1. pvosummary [FILE]\n"
-		<< "  2. pvosummary\n---------\n"
-		<< "  1. Prints RA, DEC, DATE-OBS for single FITS file.\n"
-		<< "  2. Prints RA, DEC, DATE-OBS for all fits files in the current directory.\n"
-		<< " Note that if a keyword is not present, --- is printed.\n";
+      std::cout << help_text;
       return 0;
     }
@@ -50,5 +57,5 @@
     break;
   default:
-    std::cerr << " Usage : \"pvosummary filename\"\n";
+    std::cerr << help_text;
     return 0;
     break;
@@ -58,4 +65,9 @@
   for(i=0;i<namelist.size();i++) 
     maxsize = std::max(maxsize,int(namelist[i].size()));
+
+  std::cout << std::setw(maxsize) << "FILE"      << ": "
+	    << std::setw(14)      << "RA"        << " "
+	    << std::setw(14)      << "DEC"       << " "
+	    << std::setw(30)      << "DATE-OBS"  << "\n";
 
   for(i=0;i<namelist.size();i++){
@@ -75,8 +87,8 @@
       if(fitsfile.getKeyword<std::string>("DATE-OBS",date)!=0) date = missing;
     
-      std::cout << std::setw(maxsize) << namelist[i] << ": \t"
+      std::cout << std::setw(maxsize) << namelist[i] << ": "
 		<< std::setw(14)      << ra          << " "
 		<< std::setw(14)      << dec         << " "
-		<< std::setw(20)      << date        << "\n";
+		<< std::setw(30)      << date        << "\n";
     }
   }
