Index: /trunk/Makefile
===================================================================
--- /trunk/Makefile	(revision 66)
+++ /trunk/Makefile	(revision 67)
@@ -16,4 +16,6 @@
 UTILS = $(BASE)/pvo-utils.o
 
+METADATA = $(BASE)/pvo-metadata.o
+
 ifeq ($(DEBUG),-g)
 CFITSIODIR = /DATA/SITAR_1/whi550/Packages/cfitsio-myHack-debug
@@ -28,4 +30,8 @@
 LIBS = $(CFITSIOLIB) -lm
 CINC=  $(CFITSIOINC)
+
+USE_METADATA_HH = $(BASE)/pvo-metadata.o\
+	$(BASE)/pvosummary.o\
+	$(BASE)/pvoconesearch.o
 
 USE_HEADER_HH =  $(BASE)/pvoconvert.o\
@@ -88,9 +94,9 @@
 	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)
+pvosummary : $(BASE)/pvosummary.o $(HEADER) $(BLOCK) $(PSRFITS) $(UTILS) $(METADATA)
+	$(CXX) -o pvosummary.x $(BASE)/pvosummary.o $(HEADER) $(BLOCK) $(PSRFITS) $(UTILS) $(METADATA) $(LIBS)
 
-pvoconesearch : $(BASE)/pvoconesearch.o $(HEADER) $(BLOCK) $(PSRFITS) $(UTILS)
-	$(CXX) -o pvoconesearch.x $(BASE)/pvoconesearch.o $(HEADER) $(BLOCK) $(PSRFITS) $(UTILS) $(LIBS)
+pvoconesearch : $(BASE)/pvoconesearch.o $(HEADER) $(BLOCK) $(PSRFITS) $(UTILS) $(METADATA)
+	$(CXX) -o pvoconesearch.x $(BASE)/pvoconesearch.o $(HEADER) $(BLOCK) $(PSRFITS) $(UTILS) $(METADATA) $(LIBS)
 
 pvosummary2 : $(BASE)/pvosummary-glob.o $(HEADER) $(BLOCK) $(PSRFITS) $(UTILS)
@@ -154,4 +160,5 @@
 $(USE_BLOCK_HH) : $(BASE)/pvo-block.hh
 $(USE_PSRFITS_HH) : $(BASE)/pvo-FITS.hh
+$(USE_METADATA_HH) : $(BASE)/pvo-metadata.hh
 
 .cc.o:
Index: /trunk/Makefile.psr
===================================================================
--- /trunk/Makefile.psr	(revision 66)
+++ /trunk/Makefile.psr	(revision 67)
@@ -7,5 +7,5 @@
  BINDIR = $(PSRHOME)/$(LOGIN_ARCH)/bin
 
-INCLUDES = pvo-FITS.hh  pvo-block.hh  pvo-header.hh  pvo-utils.hh
+INCLUDES = pvo-FITS.hh  pvo-block.hh  pvo-header.hh  pvo-utils.hh  pvo-metadata.hh
 
 # This forces us to use the fitsio.h file in /psr/linux/include, which
@@ -23,7 +23,7 @@
 pvoconvert.srcs = pvo-header.C  pvo-block.C  pvo-utils.C pvo-FITS.C  pvo-FITS-fileIO.C  
 
-pvosummary.srcs = pvo-header.C  pvo-block.C  pvo-utils.C pvo-FITS.C  pvo-FITS-fileIO.C  
+pvosummary.srcs = pvo-header.C  pvo-block.C  pvo-utils.C pvo-FITS.C  pvo-FITS-fileIO.C  pvo-metadata.C
 
-pvoconesearch.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  pvo-metadata.C
 
 include $(LOCAL_ROOT)/include/Makefile.extended
Index: /trunk/install_to_psr.sh
===================================================================
--- /trunk/install_to_psr.sh	(revision 66)
+++ /trunk/install_to_psr.sh	(revision 67)
@@ -20,3 +20,4 @@
 cp src/pvo-FITS-fileIO.cc $PSRDEST/pvo-FITS-fileIO.C
 cp src/pvo-utils.cc       $PSRDEST/pvo-utils.C
+cp src/pvo-metadata.cc    $PSRDEST/pvo-metadata.C
 cp src/*.hh               $PSRDEST
Index: /trunk/src/pvo-FITS.cc
===================================================================
--- /trunk/src/pvo-FITS.cc	(revision 66)
+++ /trunk/src/pvo-FITS.cc	(revision 67)
@@ -148,4 +148,5 @@
       else{
 	fits_open_file(&this->fptr, name.c_str(), READWRITE, &status);
+	this->FITSname = name;
       }
       if(status) this->FITSError("PSRFits::openFile 2",status);
@@ -371,4 +372,5 @@
       return status;
     }
+    template int PSRFits::writeColumnValue<int>(char *name, int value);
     template <> int PSRFits::writeColumnValue(char *name, long value)
     {
@@ -405,4 +407,63 @@
       fits_write_col(this->fptr, TSTRING, colnum, nrows, 1, 1, &value, &status);
       if(status) this->FITSError("PSRFits::writeColumnValue", status);
+      return status;
+    }
+     //--------------------------------------------------------------------------
+  
+    template <class T> int PSRFits::readColumnValue(char *name, int row, T *value)
+    {
+      /**
+       *   Read the value in the column "name" in the current binary table.
+       *   If the column is not present, the corresponding null value is returned. 
+       *   A templated function that should work for all cases.
+       */
+      int status=0, anynul=0;
+      int colnum = this->getColnum(name);
+      long nrows = this->getNumRows();
+      T null=nullInt;
+      fits_read_col(this->fptr, TINT, colnum, row, 1, 1, &null, value, &anynul, &status);
+      if(status) this->FITSError("PSRFits::readColumnValue", status);
+      return status;
+    }
+    template int PSRFits::readColumnValue<int>(char *name, int row, int *value);
+    template <> int PSRFits::readColumnValue(char *name, int row, long *value)
+    {
+      int status=0, anynul=0;
+      int colnum = this->getColnum(name);
+      long nrows = this->getNumRows();
+      long null=nullInt;
+      fits_read_col(this->fptr, TLONG, colnum, row, 1, 1, &null, value, &anynul, &status);
+      if(status) this->FITSError("PSRFits::readColumnValue", status);
+      return status;
+    }
+    template <> int PSRFits::readColumnValue(char *name, int row, float *value)
+    {
+      int status=0, anynul=0;
+      int colnum = this->getColnum(name);
+      long nrows = this->getNumRows();
+     float null=nullFloat;
+      fits_read_col(this->fptr, TFLOAT, colnum, row, 1, 1, &null, value, &anynul, &status);
+      if(status) this->FITSError("PSRFits::readColumnValue", status);
+      return status;
+    }
+    template <> int PSRFits::readColumnValue(char *name, int row, double *value)
+    {
+      int status=0, anynul=0;
+      int colnum = this->getColnum(name);
+      long nrows = this->getNumRows();
+      double null=nullFloat;
+      fits_read_col(this->fptr, TDOUBLE, colnum, row, 1, 1, &null, value, &anynul, &status);
+      if(status) this->FITSError("PSRFits::readColumnValue", status);
+      return status;
+    }
+    template <> int PSRFits::readColumnValue(char *name, int row, char *value)
+    {
+      int status=0, anynul=0;
+      int colnum = this->getColnum(name);
+      long nrows = this->getNumRows();
+      char *null;
+      strcpy(null,nullString.c_str());
+      fits_read_col(this->fptr, TSTRING, colnum, row, 1, 1, null, value, &anynul, &status);
+      if(status) this->FITSError("PSRFits::readColumnValue", status);
       return status;
     }
Index: /trunk/src/pvo-FITS.hh
===================================================================
--- /trunk/src/pvo-FITS.hh	(revision 66)
+++ /trunk/src/pvo-FITS.hh	(revision 67)
@@ -239,4 +239,7 @@
       template <class T> int writeColumnValue(char *name, T value);
 
+      /** Write a named column value. */
+      template <class T> int readColumnValue(char *name, int row, T *value);
+
       /** Add new row to current table. */
       int         startNewRow();         
Index: /trunk/src/pvo-block.cc
===================================================================
--- /trunk/src/pvo-block.cc	(revision 66)
+++ /trunk/src/pvo-block.cc	(revision 67)
@@ -178,4 +178,5 @@
 	do{ ss >> temp; } while( temp[0]!='G' && !ss.eof());
 	if(temp[0]=='G') field=temp;
+	field = deblank(field);
       }
       return field;
Index: /trunk/src/pvo-metadata.cc
===================================================================
--- /trunk/src/pvo-metadata.cc	(revision 67)
+++ /trunk/src/pvo-metadata.cc	(revision 67)
@@ -0,0 +1,244 @@
+#include <iostream>
+#include <sstream>
+#include <iomanip>
+#include <vector>
+#include <unistd.h>
+#include "pvo-metadata.hh"
+#include "pvo-FITS.hh"
+#include "pvo-utils.hh"
+
+namespace PVO
+{
+
+  namespace Meta
+  {
+
+    void Metadata::define(FITS::PSRFits fitsfile)
+    {
+
+      this->filename = fitsfile.getFITSname();
+
+      std::string file_loc = "";
+      if(this->filename[0]!='/'){
+	this->fileloc = get_current_dir_name();
+	this->fileloc += "/";
+      }
+      this->fileloc += this->filename;
+
+      fitsfile.gotoPHU();
+
+      if(fitsfile.getKeyword<std::string>("HDRVER",this->headerversion)!=0) 
+	this->headerversion = nullString;
+      this->headerversion = deblank(this->headerversion);
+
+      if(fitsfile.getKeyword<std::string>("SRC_NAME",this->srcname)!=0) this->srcname = nullString;
+      else this->srcname = deblank(this->srcname);
+      if(this->srcname=="") this->srcname = nullString;
+
+      if(fitsfile.getKeyword<std::string>("RA",this->raj)!=0) this->raj = nullString;
+      else this->rajd = dmsToDec(this->raj) * 15.;
+
+      if(fitsfile.getKeyword<std::string>("DEC",this->decj)!=0) this->decj = nullString;
+      else this->decjd = dmsToDec(this->decj);
+
+      if(fitsfile.getKeyword<std::string>("DATE-OBS",this->date)!=0) this->date = nullString;
+
+      if(fitsfile.getKeyword<float>("OBSFREQ",this->obsfreq)!=0) this->obsfreq = nullFloat;
+  
+      if(fitsfile.getKeyword<float>("BMAJ",this->bmaj)==0){
+	fitsfile.getKeyword<float>("BMIN",this->bmin);
+	fitsfile.getKeyword<float>("BPA",this->bpa);
+	this->beamsize = 0.5*(bmaj+bmin); 
+      }
+      else this->bmaj = this->bmin = this->bpa = this->beamsize = nullFloat;
+
+      if(fitsfile.getKeyword<float>("SCANLEN",this->scanlen)!=0) this->scanlen = nullFloat;
+
+      fitsfile.gotoHistory();
+      if(fitsfile.readColumnValue("TBIN",1,&this->tbin)!=0) this->tbin = nullFloat;
+      else this->tbin *= 1000.;
+      if(!(this->tbin>0.)) this->tbin = nullFloat;
+
+      if(fitsfile.readColumnValue("NCHAN",1,&this->nchan)!=0) this->nchan = nullInt;
+      if(this->nchan == 0) this->nchan = nullInt;
+
+      if(fitsfile.readColumnValue("CHAN_BW",1,&this->chanbw)!=0) this->chanbw = nullFloat;
+      if(!(this->chanbw>0.)) this->chanbw = nullFloat;
+
+    }
+
+    bool Metadata::close(float radius)
+    {
+      if(this->angsep < 0.) return false;
+      else return (this->angsep < (radius + 0.5*this->beamsize));
+    }
+
+    bool Metadata::close(float ra, float dec, float radius)
+    {
+      this->setAngSep(ra,dec);
+      return (angsep < (radius+0.5*this->beamsize));
+    }
+
+
+    std::string floatToString(float f)
+    {
+      if(f > nullFloat){
+	std::stringstream ss;
+	ss << std::fixed << std::setprecision(fltwidth) << f;
+	return ss.str();
+      }
+      else return nullString;
+    }
+
+    std::string intToString(int i)
+    {
+      if(i > nullInt){
+	std::stringstream ss;
+	ss << i;
+	return ss.str();
+      }
+      else return nullString;
+    }
+
+    void printMetadataShort(std::ostream &theStream, Metadata data)
+    {
+      std::vector<Metadata> datalist;
+      datalist.push_back(data);
+      printMetadataShort(theStream, datalist);
+    }
+
+    void printMetadataShort(std::ostream &theStream, std::vector<Metadata> datalist)
+    {
+      int filenameSize = 8; // size of "FILENAME"
+      unsigned int i;
+      for(i=0;i<datalist.size();i++) 
+	filenameSize = std::max(filenameSize,int(datalist[i].getFilename().size()));
+    
+      theStream << std::setfill('-')  
+		<< std::setw(filenameSize+1+15+15+31+11+11+11) << "-";
+      if(datalist[0].showSep()) theStream << std::setw(13) << "-";
+
+      theStream << "\n" << std::setfill(' ') 
+		<< std::setw(filenameSize) << "FILENAME"  << " "
+		<< std::setw(14)           << "RA"        << " "
+		<< std::setw(14)           << "DEC"       << " "
+		<< std::setw(10)           << "BEAM FWHM" << " "
+		<< std::setw(10)           << "OBSFREQ"   << " "
+		<< std::setw(10)           << "TBIN"   << " "
+		<< std::setw(30)           << "DATE-OBS";
+      if(datalist[0].showSep())
+	theStream  << " " << std::setw(12) << "OFFSET"    << "\n";
+      else theStream << "\n";
+     
+      theStream << std::setw(filenameSize) << ""          << " "
+		<< std::setw(14)           << "[deg]"     << " "
+		<< std::setw(14)           << "[deg]"     << " "
+		<< std::setw(10)           << "[deg]"     << " "
+		<< std::setw(10)           << "[MHz]"     << " "
+		<< std::setw(10)           << "[ms]"      << " "
+		<< std::setw(30)           << "";
+      if(datalist[0].showSep())
+	theStream << " " << std::setw(12)  << "[deg]" << "\n";
+      else  theStream << "\n";
+
+      theStream << std::setfill('-')  
+		<< std::setw(filenameSize+1+15+15+31+11+11+11) << "-";
+      if(datalist[0].showSep()) theStream << std::setw(13) << "-";
+      theStream << "\n"<< std::setfill(' ') ;
+    
+      for(i=0;i<datalist.size();i++){
+
+	theStream << std::setw(filenameSize) << datalist[i].getFilename() << " ";
+
+	if(datalist[0].showSep())
+	  theStream << std::setprecision(6)
+		    << std::setw(14)         << datalist[i].getRaD()       << " "
+		    << std::setw(14)         << datalist[i].getDecD()      << " ";
+	else
+	  theStream << std::setw(14)         << datalist[i].getRaS()       << " "
+		    << std::setw(14)         << datalist[i].getDecS()      << " ";
+
+	theStream << std::setprecision(4)
+		  << std::setw(10)           << floatToString(datalist[i].getBeamsize()) << " "
+		  << std::setw(10)           << floatToString(datalist[i].getObsfreq())  << " "
+		  << std::setw(10)           << floatToString(datalist[i].getTbin())     << " "
+		  << std::setw(30)           << datalist[i].getDate();
+
+	if(datalist[0].showSep()) 
+	  theStream << " " << std::setw(12)  << floatToString(datalist[i].getAngSep())   << "\n";
+	else theStream << "\n";
+
+      }
+
+
+    }
+
+    void printMetadataFull(std::string filename, Metadata data)
+    {
+      std::vector<Metadata> datalist;
+      datalist.push_back(data);
+      printMetadataFull(filename, datalist);
+    }
+
+    void printMetadataFull(std::string filename, std::vector<Metadata> datalist)
+    {
+      std::ofstream fileout(filename.c_str());
+
+      unsigned int i;
+    
+      fileout << "Filename,"
+	      << "\"File Location\","
+	      << "\"Header version\","
+	      << "\"Source Name\","
+	      << "RAJ,"
+	      << "DECJ,"
+	      << "RAJd,"
+	      << "DECJd,"
+	      << "BMAJ,"
+	      << "BMIN,"
+	      << "BPA,"
+	      << "Date-Obs,"
+	      << "Obsfreq,"
+	      << "ChanBW,"
+	      << "NChan,"
+	      << "\"Scan length\","
+	      << "Tbin";	    
+      if(datalist[0].showSep())	fileout  << ",Offset\n";
+      else fileout << "\n";
+     
+      for(i=0;i<datalist.size();i++){
+
+	fileout << "\""<< datalist[i].getFilename()      << "\",";
+	fileout << "\""<< datalist[i].getFileloc()       << "\",";
+	fileout << "\""<< datalist[i].getHeaderVersion() << "\",";
+	fileout << "\""<< datalist[i].getSrcname()       << "\",";
+	
+	fileout << "\""<< datalist[i].getRaS()  <<"\""      << ","
+		<< "\""<< datalist[i].getDecS() <<"\""      << ",";
+	fileout << std::fixed << std::setprecision(6)
+		<< datalist[i].getRaD()                     << ","
+		<< datalist[i].getDecD()                    << ",";
+
+	fileout << floatToString(datalist[i].getBmaj())     << ","
+		<< floatToString(datalist[i].getBmin())     << ","
+		<< floatToString(datalist[i].getBpa())      << ","
+		<< datalist[i].getDate()                    << ","
+		<< floatToString(datalist[i].getObsfreq())  << ","
+		<< floatToString(datalist[i].getChanbw())   << ","
+		<< intToString(datalist[i].getNchan())      << ","
+		<< floatToString(datalist[i].getScanlen())  << ","
+		<< floatToString(datalist[i].getTbin());
+
+	if(datalist[0].showSep()) 
+	  fileout << "," << floatToString(datalist[i].getAngSep()) << "\n";
+	else fileout << "\n";
+
+      }
+
+      fileout.close();
+
+    }
+
+  }// end namespace Meta
+
+} // end namespace PVO
Index: /trunk/src/pvo-metadata.hh
===================================================================
--- /trunk/src/pvo-metadata.hh	(revision 67)
+++ /trunk/src/pvo-metadata.hh	(revision 67)
@@ -0,0 +1,116 @@
+#ifndef PSRMETADATA_HH_
+#define PSRMETADATA_HH_
+#include <fitsio.h>
+#include <string>
+#include "pvo-FITS.hh"
+#include "pvo-utils.hh"
+
+namespace PVO
+{
+
+  namespace Meta
+  {
+
+    /** The precision for printing floats */
+    const int     fltwidth=4;
+
+    std::string   floatToString(float f);
+    std::string   intToString(int i);
+
+    /**
+     * The namespace to record only relevant details about a PSRFITS
+     * file, that can be used by the utility programs pvosummary and
+     * pvoconesearch.
+     */
+    class Metadata
+    {
+    public:
+      Metadata(){sepFlag=false; angsep=nullFloat;};
+      virtual ~Metadata(){};
+
+      void        define(FITS::PSRFits fitsfile);
+      friend bool operator< (Metadata lhs, Metadata rhs){
+	return (lhs.angsep < rhs.angsep);
+      };
+
+      void        setAngSep(float ra, float dec){angsep = angSep(ra, dec, rajd, decjd); sepFlag=true;};
+      bool        close(float radius);
+      bool        close(float ra, float dec, float radius);
+
+      std::string getFilename(){return filename;};
+      void        setFilename(std::string s){filename=s;};
+      std::string getFileloc(){return fileloc;};
+      void        setFileloc(std::string s){fileloc=s;};
+      std::string getHeaderVersion(){return headerversion;};
+      void        setHeaderVersion(std::string s){headerversion=s;};
+      std::string getSrcname(){return srcname;};
+      void        setSrcname(std::string s){srcname=s;};
+      std::string getRaS(){return raj;};
+      void        setRaS(std::string s){raj=s;};
+      std::string getDecS(){return decj;};
+      void        setDecS(std::string s){decj=s;};
+      float       getRaD(){return rajd;};
+      void        setRaD(float f){rajd=f;};
+      float       getDecD(){return decjd;};
+      void        setDecD(float f){decjd=f;};
+      std::string getDate(){return date;};
+      void        setDate(std::string s){date=s;};
+      float       getBeamsize(){return beamsize;};
+      void        setBeamsize(float f){beamsize=f;};
+      float       getBmaj(){return bmaj;};
+      void        setBmaj(float f){bmaj=f;};
+      float       getBmin(){return bmin;};
+      void        setBmin(float f){bmin=f;};
+      float       getBpa(){return bpa;};
+      void        setBpa(float f){bpa=f;};
+      float       getObsfreq(){return obsfreq;};
+      void        setObsfreq(float f){obsfreq=f;};
+      float       getTbin(){return tbin;};
+      void        setTbin(float f){tbin=f;};
+      float       getScanlen(){return scanlen;};
+      void        setScanlen(float f){scanlen=f;};
+      int         getNchan(){return nchan;};
+      void        setNchan(int i){nchan=i;};
+      float       getChanbw(){return chanbw;};
+      void        setChanbw(float f){chanbw=f;};
+      float       getAngSep(){if(sepFlag) return angsep; else return -1.;};
+      void        setAngSep(float f){angsep=f; sepFlag=true;};
+      bool        showSep(){return sepFlag;};
+
+      std::string getBeamsizeS();
+      std::string getObsfreqS();
+      std::string getTbinS();
+      std::string getAngSepS();
+
+    private:
+      std::string filename;
+      std::string fileloc;
+      std::string headerversion;
+      std::string srcname;
+      std::string raj;
+      std::string decj;
+      float       rajd;
+      float       decjd;
+      std::string date;
+      float       beamsize;
+      float       bmaj;
+      float       bmin;
+      float       bpa;
+      float       obsfreq;
+      float       tbin;
+      float       scanlen;
+      int         nchan;
+      float       chanbw;
+      float       angsep;
+      bool        sepFlag;
+    };
+
+    void printMetadataShort(std::ostream &theStream, Metadata data);
+    void printMetadataShort(std::ostream &theStream, std::vector<Metadata> datalist);
+    void printMetadataFull(std::string filename, Metadata data);
+    void printMetadataFull(std::string filename, std::vector<Metadata> datalist);
+
+  }
+}
+
+#endif //PSRSUMMARY_HH_
Index: /trunk/src/pvo-utils.hh
===================================================================
--- /trunk/src/pvo-utils.hh	(revision 66)
+++ /trunk/src/pvo-utils.hh	(revision 67)
@@ -7,4 +7,13 @@
 namespace PVO
 {
+
+  /** Standard NULL value for strings. */
+  const std::string nullString = "NULL";
+
+  /** Standard NULL value for floats. */
+  const float       nullFloat = -9999.;
+
+  /** Standard NULL value for ints. */
+  const int         nullInt = -9999;
 
   /** Help text for pvoconvert -h */
@@ -43,5 +52,5 @@
       current directory.\n\
   3. Prints this help information.\n\
- Note that if a keyword is not present, --- is printed.\n\
+ Note that if a keyword is not present, NULL is printed.\n\
  FITS files are assumed to have suffixes of .fits or .rf\n";
   /** Brief help text for pvosummary -h */
@@ -67,5 +76,5 @@
  The search radius is in degrees. The beam size is also taken into account,\n\
   so the effective search radius becomes (radius + 0.5*beamFWHM).\n\
- Note that if a keyword is not present, --- is printed.\n\
+ Note that if a keyword is not present, NULL is printed.\n\
  FITS files are assumed to have suffixes of .fits or .rf\n";
   /** Brief help text for pvoconesearch -h */
Index: /trunk/src/pvoconesearch.cc
===================================================================
--- /trunk/src/pvoconesearch.cc	(revision 66)
+++ /trunk/src/pvoconesearch.cc	(revision 67)
@@ -9,4 +9,5 @@
 #include "pvo-FITS.hh"
 #include "pvo-utils.hh"
+#include "pvo-metadata.hh"
 
 using namespace PVO;
@@ -14,28 +15,7 @@
 using namespace PVO::Block;
 using namespace PVO::FITS;
+using namespace PVO::Meta;
 using std::string;
 
-
-class Match
-{
-public:
-  
-  Match(){};
-  virtual ~Match(){};
-  friend bool operator< (const Match& lhs, const Match& rhs){
-    return (lhs.angsep < rhs.angsep);
-  };
-  void define(std::string n, double r, double d, std::string t,
-	      float b, std::string f, float a){
-    name=n; ra=r; dec=d; date=t; beam=b; obsfreq=f; angsep=a;
-  }
-  std::string name;
-  double ra;
-  double dec;
-  std::string date;
-  float beam;
-  std::string obsfreq;
-  float angsep;
-};
 
 
@@ -117,5 +97,8 @@
   }
 
-  std::vector<Match> goodlist;
+  ///////////////////////////////////////////
+  // Now actually do the work...
+
+  std::vector<Metadata> goodlist;
 
   for(i=0;i<namelist.size();i++){
@@ -126,31 +109,7 @@
   
     if(status==0){
-      fitsfile.gotoPHU();
-    
-      std::string raS,decS,date,obsfreqS;
-      std::string missing = "---";
-      if(fitsfile.getKeyword<std::string>("RA",raS)!=0) raS = missing;
-      if(fitsfile.getKeyword<std::string>("DEC",decS)!=0) decS = missing;
-      if(fitsfile.getKeyword<std::string>("DATE-OBS",date)!=0) date = missing;
-      if(fitsfile.getKeyword<std::string>("OBSFREQ",obsfreqS)!=0) obsfreqS = missing;
-      float beamfwhm,bmaj,bmin;
-      fitsfile.getKeyword<float>("BMAJ",bmaj);
-      fitsfile.getKeyword<float>("BMIN",bmin);
-      beamfwhm = 0.5*(bmaj+bmin); // average FWHM, in deg
-
-      double ra = dmsToDec(raS)*15;
-      double dec = dmsToDec(decS);
-
-      if(raS!=missing && decS!=missing){
-	double angsep = angSep(ra, dec, RAcentre, DECcentre);
-
-	if(angsep < radius+beamfwhm/2.) {
-	  Match newmatch;
-	  newmatch.define(namelist[i],ra,dec,date,beamfwhm,obsfreqS,angsep);
-	  goodlist.push_back(newmatch);
-	}
-
-      
-      }
+      Metadata newmatch;
+      newmatch.define(fitsfile);
+      if(newmatch.close(RAcentre,DECcentre,radius)) goodlist.push_back(newmatch);
     }
   }
@@ -158,40 +117,5 @@
   std::stable_sort(goodlist.begin(),goodlist.end());
 
-  int maxsize = 8; // size of "FILENAME"
-  for(i=0;i<goodlist.size();i++) 
-    maxsize = std::max(maxsize,int(goodlist[i].name.size()));
-
-  std::cout << std::setfill('-')  
-	    << std::setw(maxsize+1+15+15+31+11+11+13) << "-"
-	    << "\n" << std::setfill(' ') 
-	    << std::setw(maxsize) << "FILENAME"  << " "
-	    << std::setw(14)      << "RA"        << " "
-	    << std::setw(14)      << "DEC"       << " "
-	    << std::setw(10)      << "BEAM FWHM" << " "
-	    << std::setw(10)      << "OBSFREQ"   << " "
-	    << std::setw(30)      << "DATE-OBS"  << " "
-	    << std::setw(12)      << "OFFSET"    << "\n"
-	    << std::setw(maxsize) << ""          << " "
-	    << std::setw(14)      << "[deg]"     << " "
-	    << std::setw(14)      << "[deg]"     << " "
-	    << std::setw(10)      << "[deg]"     << " "
-	    << std::setw(10)      << "[MHz]"     << " "
-	    << std::setw(30)      << ""          << " "
-	    << std::setw(12)      << "[deg]"     << "\n"
-	    << std::setfill('-')  
-	    << std::setw(maxsize+1+15+15+31+11+11+13) << "-"
-	    << "\n"<< std::setfill(' ') ;
-
-  for(i=0;i<goodlist.size();i++){
-    std::cout << std::setw(maxsize) << goodlist[i].name    << " "
-	      << std::setprecision(6)
-	      << std::setw(14)      << goodlist[i].ra      << " "
-	      << std::setw(14)      << goodlist[i].dec     << " "
-	      << std::setprecision(4)
-	      << std::setw(10)      << goodlist[i].beam    << " "
-	      << std::setw(10)      << goodlist[i].obsfreq << " "
-	      << std::setw(30)      << goodlist[i].date    << " "
-	      << std::setw(12)      << goodlist[i].angsep  << "\n";
-  }
+  printMetadataShort(std::cout,goodlist);
 
 }
Index: /trunk/src/pvoconvert.cc
===================================================================
--- /trunk/src/pvoconvert.cc	(revision 66)
+++ /trunk/src/pvoconvert.cc	(revision 67)
@@ -99,6 +99,10 @@
   }
 
-  std::string file_loc = get_current_dir_name();
-  file_loc += "/"+fname;
+  std::string file_loc = "";
+  if(fname[0]!='/'){
+    file_loc = get_current_dir_name();
+    file_loc += "/";
+  }
+  file_loc += fname;
   std::cerr << "Input file " << file_loc <<" : " << surveyNames[currentSurvey]<<"\n";
   if(currentSurvey == DUD){
Index: /trunk/src/pvosummary.cc
===================================================================
--- /trunk/src/pvosummary.cc	(revision 66)
+++ /trunk/src/pvosummary.cc	(revision 67)
@@ -9,4 +9,5 @@
 #include "pvo-FITS.hh"
 #include "pvo-utils.hh"
+#include "pvo-metadata.hh"
 
 using namespace PVO;
@@ -14,4 +15,5 @@
 using namespace PVO::Block;
 using namespace PVO::FITS;
+using namespace PVO::Meta;
 using std::string;
 
@@ -48,4 +50,5 @@
   switch(argc){
   case 1:
+  case 3:
     glob_t globbuf1,globbuf2;
     globbuf1.gl_offs = 0;
@@ -58,6 +61,9 @@
     for(i=0;i<globbuf2.gl_pathc+globbuf2.gl_offs;i++) 
       namelist[globbuf1.gl_pathc+i] = globbuf2.gl_pathv[i];
+    if(argc==3){
+    }
     break;
   case 2:
+  case 4:
     if(strcmp(argv[1],"-h")==0){
       std::cout << pvosummary_usage_text;
@@ -66,4 +72,6 @@
     namelist.resize(1);
     namelist[0] = argv[1];
+    if(argc==4){
+    }
     break;
   default:
@@ -73,26 +81,6 @@
   }
 
-  int maxsize = 8; // size of "FILENAME"
-  for(i=0;i<namelist.size();i++) 
-    maxsize = std::max(maxsize,int(namelist[i].size()));
 
-  std::cout << std::setfill('-')  
-	    << std::setw(maxsize+1+15+15+31+11+11) << "-"
-	    << "\n" << std::setfill(' ') 
-	    << std::setw(maxsize) << "FILENAME"  << " "
-	    << std::setw(14)      << "RA"        << " "
-	    << std::setw(14)      << "DEC"       << " "
-	    << std::setw(10)      << "BEAM FWHM" << " "
-	    << std::setw(10)      << "OBSFREQ"   << " "
-	    << std::setw(30)      << "DATE-OBS"  << "\n"
-	    << std::setw(maxsize) << ""          << " "
-	    << std::setw(14)      << ""          << " "
-	    << std::setw(14)      << ""          << " "
-	    << std::setw(10)      << "[deg]"     << " "
-	    << std::setw(10)      << "[MHz]"     << " "
-	    << std::setw(30)      << ""          << "\n"
-	    << std::setfill('-')  
-	    << std::setw(maxsize+1+15+15+31+11+11) << "-"
-	    << "\n"<< std::setfill(' ') ;
+  std::vector<Metadata> goodlist;
 
   for(i=0;i<namelist.size();i++){
@@ -103,25 +91,13 @@
   
     if(status==0){
-      fitsfile.gotoPHU();
-    
-      std::string ra,dec,date,obsfreqS;
-      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;
-      if(fitsfile.getKeyword<std::string>("OBSFREQ",obsfreqS)!=0) obsfreqS = missing;
-      float beamradius,bmaj,bmin,obsfreq;
-      fitsfile.getKeyword<float>("BMAJ",bmaj);
-      fitsfile.getKeyword<float>("BMIN",bmin);
-      beamradius = 0.5*(bmaj+bmin); // average FWHM, in deg
-
-      std::cout << std::setw(maxsize) << namelist[i]  << " "
-		<< std::setw(14)      << ra           << " "
-		<< std::setw(14)      << dec          << " "
-		<< std::setw(10)      << beamradius   << " "
-		<< std::setw(10)      << obsfreqS     << " "
-		<< std::setw(30)      << date         << "\n";
+      Metadata newmatch;
+      newmatch.define(fitsfile);
+      goodlist.push_back(newmatch);
     }
   }
 
+  printMetadataShort(std::cout,goodlist);
+
+  printMetadataFull("PVOsummary.csv",goodlist);
+
 }
