Index: /trunk/Makefile
===================================================================
--- /trunk/Makefile	(revision 50)
+++ /trunk/Makefile	(revision 51)
@@ -76,9 +76,11 @@
 install : pvoconvert pvosummary
 	cp pvoconvert.x $(INSTALLDIR)/pvoconvert
-	cp pvosummary.x $(INSTALLDIR)
-	cp pvosummary $(INSTALLDIR)
+	cp pvosummary.x $(INSTALLDIR)/pvosummary
 
 pvosummary : $(BASE)/pvosummary.o $(HEADER) $(BLOCK) $(PSRFITS) $(UTILS)
 	$(CXX) -o pvosummary.x $(BASE)/pvosummary.o $(HEADER) $(BLOCK) $(PSRFITS) $(UTILS) $(LIBS)
+
+pvosummary2 : $(BASE)/pvosummary-glob.o $(HEADER) $(BLOCK) $(PSRFITS) $(UTILS)
+	$(CXX) -o pvosummary2.x $(BASE)/pvosummary-glob.o $(HEADER) $(BLOCK) $(PSRFITS) $(UTILS) $(LIBS)
 
 testNewPSRF : $(TEST)/testNewPsrfits.o $(HEADER) $(BLOCK) $(PSRFITS) $(UTILS)
Index: /trunk/Makefile.psr
===================================================================
--- /trunk/Makefile.psr	(revision 50)
+++ /trunk/Makefile.psr	(revision 51)
@@ -15,11 +15,13 @@
 
 # Also fix the library so that we use the correct version.
-# LDFLAGS := -L$(PSRHOME)/$(LOGIN_ARCH)/lib -lcfitsio #$(LDFLAGS)
- LDFLAGS := $(LDFLAGS) -lcfitsio -lm
+ LDFLAGS := -L$(PSRHOME)/$(LOGIN_ARCH)/lib -lcfitsio #$(LDFLAGS)
+# LDFLAGS := $(LDFLAGS) -lcfitsio -lm
 
-PROGRAMS = pvoconvert.C
+PROGRAMS = pvoconvert.C pvosummary.C
 
 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  
+
 include $(LOCAL_ROOT)/include/Makefile.extended
 
Index: /trunk/install_to_psr.sh
===================================================================
--- /trunk/install_to_psr.sh	(revision 50)
+++ /trunk/install_to_psr.sh	(revision 51)
@@ -13,4 +13,5 @@
 cp Makefile.psr           $PSRDEST/Makefile
 cp src/pvoconvert.cc      $PSRDEST/pvoconvert.C
+cp src/pvosummary.cc      $PSRDEST/pvosummary.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 50)
+++ /trunk/src/pvo-FITS-fileIO.cc	(revision 51)
@@ -10,596 +10,590 @@
 #include "pvo-header.hh"
 
-using namespace Block;
-using namespace Header;
-
-namespace FITS
+using namespace PVO::Block;
+using namespace PVO::Header;
+
+namespace PVO
 {
 
-  void PSRFits::fixPSRFITS()
+  namespace FITS
   {
-    /**
-     *  Corrects known errors that exist in the PSRFITS definition:
-     *  <ul><li> Set the TFORM keyword for the data column in the
-     *             SUBINT table
-     *      <li> Remove the unwanted Binary Tables.
-     *  </ul>
-     */
-    if(this->gotoSubint()){
-      std::cerr << 
-	"Error <PSRFits::fixPSRFITS> : Could not go to the SUBINT table.\n";
-      return;
-    }
-    
-    int status=0;
-    char cval[9];
-    strcpy(cval,"16X");
-    fits_update_key(this->fptr, TSTRING, "TFORM19", cval, NULL, &status);
-    if(status) FITSError("PSRFits::fixPSRFITS 1", status);
-
-    if((status=this->deleteTable("BANDPASS")))
-      FITSError("PSRFits::deleteTable(BANDPASS)", status);
-    if((status=this->deleteTable("COHDDISP")))
-      FITSError("PSRFits::deleteTable(COHDDISP)", status);
-    if((status=this->deleteTable("PSREPHEM")))
-      FITSError("PSRFits::deleteTable(PSREPHEM)", status);
-    if((status=this->deleteTable("POLYCO")))
-      FITSError("PSRFits::deleteTable(POLYCO)", status);
-    if((status=this->deleteTable("T2PREDICT")))
-      FITSError("PSRFits::deleteTable(T2PREDICT)", status);
-    if((status=this->deleteTable("FLUX_CAL")))
-      FITSError("PSRFits::deleteTable(FLUX_CAL)", status);
-    if((status=this->deleteTable("CAL_POLN")))
-      FITSError("PSRFits::deleteTable(CAL_POLN)", status);
-    if((status=this->deleteTable("FEEDPAR")))
-      FITSError("PSRFits::deleteTable(FEEDPAR)", status);
-    if((status=this->deleteTable("DIG_STAT")))
-      FITSError("PSRFits::deleteTable(DIG_STAT)", status);
-    if((status=this->deleteTable("DIG_CNTS")))
-      FITSError("PSRFits::deleteTable(DIG_CNTS)", status);
-
-    this->gotoPHU();
+
+    void PSRFits::fixPSRFITS()
+    {
+      /**
+       *  Corrects known errors that exist in the PSRFITS definition:
+       *  <ul><li> Set the TFORM keyword for the data column in the
+       *             SUBINT table
+       *      <li> Remove the unwanted Binary Tables.
+       *  </ul>
+       */
+      if(this->gotoSubint()){
+	std::cerr << 
+	  "Error <PSRFits::fixPSRFITS> : Could not go to the SUBINT table.\n";
+	return;
+      }
+    
+      int status=0;
+      char cval[9];
+      strcpy(cval,"16X");
+      fits_update_key(this->fptr, TSTRING, "TFORM19", cval, NULL, &status);
+      if(status) this->FITSError("PSRFits::fixPSRFITS 1", status);
+
+      if((status=this->deleteTable("BANDPASS")))
+	this->FITSError("PSRFits::deleteTable(BANDPASS)", status);
+      if((status=this->deleteTable("COHDDISP")))
+	this->FITSError("PSRFits::deleteTable(COHDDISP)", status);
+      if((status=this->deleteTable("PSREPHEM")))
+	this->FITSError("PSRFits::deleteTable(PSREPHEM)", status);
+      if((status=this->deleteTable("POLYCO")))
+	this->FITSError("PSRFits::deleteTable(POLYCO)", status);
+      if((status=this->deleteTable("T2PREDICT")))
+	this->FITSError("PSRFits::deleteTable(T2PREDICT)", status);
+      if((status=this->deleteTable("FLUX_CAL")))
+	this->FITSError("PSRFits::deleteTable(FLUX_CAL)", status);
+      if((status=this->deleteTable("CAL_POLN")))
+	this->FITSError("PSRFits::deleteTable(CAL_POLN)", status);
+      if((status=this->deleteTable("FEEDPAR")))
+	this->FITSError("PSRFits::deleteTable(FEEDPAR)", status);
+      if((status=this->deleteTable("DIG_STAT")))
+	this->FITSError("PSRFits::deleteTable(DIG_STAT)", status);
+      if((status=this->deleteTable("DIG_CNTS")))
+	this->FITSError("PSRFits::deleteTable(DIG_CNTS)", status);
+
+      this->gotoPHU();
+    }
+
+    //--------------------------------------------------------------------------
+
+    int PSRFits::initialise(DataBlock &block)
+    {
+      /**
+       * Initialises a fits file for use in the conversion program. The
+       * order of business is as follows: 
+       *
+       * <ul>
+       *   <li> When new:
+       *   <ul><li> Set the initial date & time (UT) for the file. 
+       *       <li> If a new file is beginning, and the time has changed
+       *       and is smaller than the existing time, we need to
+       *       increment the date. This may be the case if we are
+       *       working through a large tape file and the blocks go past
+       *       midnight. 
+       *   </ul>
+       *   <li> Set the beam used in the file.
+       *   <li> Define the FITS file name.
+       *   <li> Set the starting block value.
+       *   <li> If new, test whether file exists.
+       *   <li> Open the fits file.
+       *   <li> If new:
+       *   <ul><li> Write the PHU headers using writePHU();
+       *       <li> Setup and write the SUBINT header with setupSubint(). 
+       *   </ul>
+       * </ul>
+       * \param block The block used to get the header information.
+       */
+
+      std::string newUT,date;
+
+      if(this->newFile){
+
+	this->numSamples = 0; // Initialise the number of samples.
+
+	newUT = block.getKeyword<std::string>(UT);
+	date   = block.getKeyword<std::string>(DATE);
+
+	// if we have gone over midnight.
+	if(dmsToDec(this->UT_initial) > dmsToDec(newUT) ) 
+	  date = addDay(date);
+
+	this->setUT(newUT);
+	this->setDate(date);
+      }
+
+      this->setBeam(block.getKeyword<int>(IBEAM));
+
+      this->setFITSname(block.getSurveyType());
+
+      this->setInitialBlock(block.getKeyword<int>(BLK_CNTR));
+
+      if(this->newFile && this->fileExists()){
+	std::stringstream errmsg;
+	errmsg << "\aThe file "<< this->getFITSname() 
+	       << " already exists.\n"
+	       << "Don't want to overwrite, so exiting...\n";
+	if(this->verbose) PVOError("FITS initialise",errmsg.str());
+	return FAILURE;
+      }
+
+      if(this->openFile()) {
+	if(this->verbose) 
+	  std::cerr << "\aCannot open file "<< this->getFITSname()
+		    << ".\nExiting...\n";
+	return FAILURE;
+      }
+
+      if(this->newFile){
+      
+	//      this->writeHistoryTapeFile();
+	this->writeHistoryCommand();
+  
+	this->writePHU(block);
+
+	this->setupSubint(block);
+    
+      }
+
+      this->newFile = false;
+
+      return SUCCESS;
+
+    }
+    //--------------------------------------------------------------------------
+
+    void PSRFits::setupSubint(DataBlock &block)
+    {
+      /**
+       *  A function to set up the subintegration binary table
+       *  extension.  This defines the necessary keywords, as well as
+       *  the DAT_... arrays to go in the columns (as these will be the
+       *  same for all rows of the subintegration table -- at least as
+       *  far as the conversion program goes.)
+       *
+       *  It then calls the Subint::writeKeywords() function to write
+       *  the header keywords to the table.
+       *
+       * \param block The block containing the header information.
+       */
+    
+      this->subintTable.tsamp = block.getKeyword<float>(SAMP_INT,0)/1000.;
+      this->subintTable.nbits = block.getKeyword<int>(NBITS,0);
+      this->subintTable.nbin = 1; 
+      this->subintTable.nch_file = block.getKeyword<int>(NCHAN);
+      this->subintTable.npol = 1;
+      this->subintTable.nsblk = block.getKeyword<int>(SAMP_GRP,0) * 
+	block.getKeyword<int>(GRP_BLK);
+
+      // define the DAT_FREQ array;
+      float deltaFreq = block.getKeyword<float>(CHANBW);
+      this->subintTable.dat_freq = new float[this->subintTable.nch_file];
+      this->subintTable.dat_freq[0] = block.getKeyword<float>(FREQ_CHAN1);
+      for(int i=1;i<this->subintTable.nch_file;i++) 
+	this->subintTable.dat_freq[i] = 
+	  this->subintTable.dat_freq[i-1] + deltaFreq;
+
+      // define the DAT_WTS array;
+      this->subintTable.dat_wts = new float[this->subintTable.nch_file];
+      for(int i=0;i<this->subintTable.nch_file;i++)
+	this->subintTable.dat_wts[i] = 1.;
+
+      // define the DAT_OFFS array;
+      this->subintTable.dat_offs = new float[this->subintTable.nch_file];
+      for(int i=0;i<this->subintTable.nch_file;i++)
+	this->subintTable.dat_offs[i] = 0.;
+
+      // define the DAT_SCL array;
+      this->subintTable.dat_scl = new float[this->subintTable.nch_file];
+      for(int i=0;i<this->subintTable.nch_file;i++)
+	this->subintTable.dat_scl[i] = 1.;
+    
+    
+      this->subintTable.setAllocatedFlag(true);
+
+      // now write the keywords to the subint table
+      if(this->gotoSubint()){
+	std::cerr << 
+	  "Error <PSRFits::initialise> : Could not go to the SUBINT table.\n";
+      }
+      else{
+	int status = this->subintTable.writeKeywords(this->fptr);
+	if(status) this->FITSError("Subint::writeKeywords",status);
+      }
+
+    
+    }
+
+    //-----------------------------------------------------------------------
+
+    int Subint::writeKeywords(fitsfile *fptr)
+    {
+      /**
+       *  A special function in the Subint class to write all the header
+       *  keywords necessary for the subintegration binary table
+       *  extension. This should only need to be done once per file.
+       *
+       *  The keywords are stored as private members of Subint, and need
+       *  to be defined beforehand.
+       *
+       *  \param fptr The fitsfile pointer corresponding to the file to
+       *  be written to.
+       */
+
+      int status=0;
+      fits_update_key(fptr,TSTRING,"INT_TYPE", 
+		      (char *)this->int_type.c_str(), NULL, &status);
+      if(status) return status;
+      else{
+	
+	status=0;
+	fits_update_key(fptr,TSTRING,"INT_UNIT",
+			(char *)this->int_unit.c_str(),NULL,&status);
+	status=0;
+	fits_update_key(fptr,TFLOAT,"TSAMP",&this->tsamp,NULL,&status);    
+	status=0;
+	fits_update_key(fptr,TINT,"NBITS",&this->nbits,NULL,&status);    
+	status=0;
+	fits_update_key(fptr,TINT,"NBIN",&this->nbin,NULL,&status);
+	status=0;
+	fits_update_key(fptr,TINT,"NCH_FILE",&this->nch_file,NULL,&status);
+	status=0;
+	fits_update_key(fptr,TINT,"NCH_STRT",&this->nch_strt,NULL,&status);
+	status=0;
+	fits_update_key(fptr,TINT,"NPOL",&this->npol,NULL,&status);
+	status=0;
+	fits_update_key(fptr,TINT,"NSBLK",&this->nsblk,NULL,&status);
+	status=0;
+	int colnum=0;
+	fits_get_colnum(fptr, CASEINSEN, "DATA", &colnum, &status);
+	status=0;
+	fits_modify_vector_len (fptr, colnum, this->getDataSize(), &status);
+
+	// delete the existing "TDIM19 = (*,*,*,*)" and write the new one.
+	status=0;
+	fits_delete_key(fptr, "TDIM19", &status);
+	int naxis=4;
+	long naxes[4];
+	naxes[0] = this->nbits;
+	naxes[1] = this->nch_file;
+	naxes[2] = this->npol;
+	naxes[3] = this->nsblk;
+	status=0;
+	fits_write_tdim(fptr, colnum, naxis, naxes, &status);
+
+      }
+
+    }
+    //--------------------------------------------------------------------------
+
+    void PSRFits::writeSubintRow(DataBlock &block)
+    {
+      /**
+       * This function writes an entire new row in the SUBINT table extension.
+       * The procedure is as follows:
+       * <ul> <li> Move to the subint table.
+       *      <li> Start a new row with startNewSubintRow()
+       *      <li> Write the single-valued columns with writeColumnValue()
+       *      <li> Write the multi-valued DAT_... columns
+       *      <li> Write the data.
+       *      <li> Increment the number of samples.
+       * </ul>
+       * \param block The block containing the header info & the data.
+       */
+
+      this->gotoSubint();
+      this->startNewSubintRow(); 
+
+      float tsubint = block.getKeyword<float>(BLK_SEC);
+      double off_sub;
+    
+      off_sub = 0.5*(2.*(block.getKeyword<int>(BLK_CNTR)-this->blk_initial)+1)
+	* block.getKeyword<double>(BLK_SEC);
+
+      double lst_sub  = dmsToDec(block.getKeyword<std::string>(LST));
+      double ra_sub   = dmsToDec(block.getKeyword<std::string>(RA))*15.;
+      double dec_sub  = dmsToDec(block.getKeyword<std::string>(DEC));
+      double glon_sub = block.getKeyword<double>(GL);
+      double glat_sub = block.getKeyword<double>(GB);
+      float  fd_ang   = block.getKeyword<float>(FEED_ANGLE);
+      float  par_ang  = block.getKeyword<float>(PANGLE);
+      float  pos_ang  = remainderf(par_ang + fd_ang, 360.);
+      float  tel_az   = block.getKeyword<float>(TEL_AZ);
+      float  tel_zen  = block.getKeyword<float>(TEL_ZEN);
+    
+      this->writeColumnValue("TSUBINT",  tsubint);
+      this->writeColumnValue("OFFS_SUB", off_sub);
+      this->writeColumnValue("LST_SUB",  lst_sub);
+      this->writeColumnValue("RA_SUB",   ra_sub);
+      this->writeColumnValue("DEC_SUB",  dec_sub);
+      this->writeColumnValue("GLON_SUB", glon_sub);
+      this->writeColumnValue("GLAT_SUB", glat_sub);
+      this->writeColumnValue("FD_ANG",   fd_ang);
+      this->writeColumnValue("POS_ANG",  pos_ang);
+      this->writeColumnValue("PAR_ANG",  par_ang);
+      this->writeColumnValue("TEL_AZ",   tel_az);
+      this->writeColumnValue("TEL_ZEN",  tel_zen);
+
+      /////////////////////////////////////
+
+      long nrows = this->getNumRows();
+      int colnum = this->getColnum("DAT_FREQ");
+      int status=0;
+      fits_modify_vector_len (this->fptr, colnum, 
+			      this->subintTable.nch_file, &status);
+      if(status) this->FITSError("PSRFits::writeSubintRow", status);
+      status=0;
+      fits_write_col(this->fptr, TFLOAT, colnum, nrows, 1, 
+		     this->subintTable.nch_file, this->subintTable.dat_freq, 
+		     &status);
+      if(status) this->FITSError("PSRFits::writeSubintRow", status);
+
+      colnum = this->getColnum("DAT_WTS");
+      status=0;
+      fits_modify_vector_len (this->fptr, colnum, 
+			      this->subintTable.nch_file, &status);
+      if(status) this->FITSError("PSRFits::writeSubintRow", status);
+      status=0;
+      fits_write_col(this->fptr, TFLOAT, colnum, nrows, 1, 
+		     this->subintTable.nch_file, this->subintTable.dat_wts, 
+		     &status);
+      if(status) this->FITSError("PSRFits::writeSubintRow", status);
+
+      colnum = this->getColnum("DAT_OFFS");
+      status=0;
+      fits_modify_vector_len (this->fptr, colnum, 
+			      this->subintTable.nch_file, &status);
+      if(status) this->FITSError("PSRFits::writeSubintRow", status);
+      status=0;
+      fits_write_col(this->fptr, TFLOAT, colnum, nrows, 1, 
+		     this->subintTable.nch_file, this->subintTable.dat_offs, 
+		     &status);
+      if(status) this->FITSError("PSRFits::writeSubintRow", status);
+
+      colnum = this->getColnum("DAT_SCL");
+      status=0;
+      fits_modify_vector_len (this->fptr, colnum, 
+			      this->subintTable.nch_file, &status);
+      if(status) this->FITSError("PSRFits::writeSubintRow", status);
+      status=0;
+      fits_write_col(this->fptr, TFLOAT, colnum, nrows, 1, 
+		     this->subintTable.nch_file, this->subintTable.dat_scl, 
+		     &status);
+      if(status) this->FITSError("PSRFits::writeSubintRow", status);
+
+      //////////////////////////////////////////
+
+      unsigned char *data = (unsigned char *)block.getData();
+
+      if(this->FITSname == "PM_061222_150342_01.fits" && nrows==1){
+	std::cout << charToBinary(data[0]);
+	std::cout << charToBinary(data[1]);
+	std::cout << charToBinary(data[2]);
+	std::cout << "\n";
+      }
+
+      colnum = this->getColnum("DATA");
+      status=0;
+      fits_write_col_byt(this->fptr, colnum, nrows, 1, this->subintTable.getDataSizeBytes(), data, &status);
+      if(status) this->FITSError("PSRFits::writeDataArray 4", status);
+
+      //////////////////////////////////////////
+
+      // Increment the number of samples
+      this->numSamples += (block.getKeyword<int>(GRP_BLK) * 
+			   block.getKeyword<int>(SAMP_GRP) );
+
+    }
+    //--------------------------------------------------------------------------
+
+    void PSRFits::writePHU(DataBlock &block)
+    {
+      /**
+       *   Writes the header information contained in the DataBlock block
+       *    to the primary header unit.
+       *   At the end the current header unit will be the PHU.
+       */
+      this->gotoPHU();
+
+      char *todaysdate     = new char[25];
+      int timeref,status=0;
+      fits_get_system_time(todaysdate, &timeref, &status);
+      if(status) this->FITSError("PSRFits::writePHU", status);
+      std::string projid   = block.getSurveyName();
+      std::string telescop = block.getKeyword<std::string>(TELID);
+      if((deblank(telescop)=="")&&(block.getSurveyType()==S70)) 
+	telescop           = "PARKES";
+      double ant_x         = block.Survey().getAntX();
+      double ant_y         = block.Survey().getAntY();
+      double ant_z         = block.Survey().getAntZ();
+      std::string frontend = block.Survey().getFrontend();
+      std::string fd_poln  = block.Survey().getFd_poln();
+      int fd_hand          = block.Survey().getFd_hand();
+      float fd_sang        = block.Survey().getFd_sang();
+      float fd_xyph        = block.Survey().getFd_xyph();
+      std::string backend  = block.Survey().getBackend();
+      std::string beconfig = block.Survey().getBeconfig();
+      int be_phase         = block.Survey().getBe_phase();
+      int be_dcc           = block.Survey().getBe_dcc();
+      double tcycle        = block.Survey().getTcycle();
+      int nrcvr            = block.getKeyword<int>(NFILTER);
+      std::string obs_mode = block.Survey().getObs_mode();
+
+      std::string date_obs = 
+	makeDateObs(deblank(block.getKeyword<std::string>(DATE)),
+		    deblank(block.getKeyword<std::string>(UT))   );
+
+      double f0            = block.getKeyword<double>(FREQ_CHAN1);
+      double bw            = block.getKeyword<double>(CHANBW);
+      double nc            = block.getKeyword<double>(NCHAN);
+      float obsfreq        = f0 + ((nc-1)/2.) * bw;
+
+      std::string src_name = deblank(block.getKeyword<std::string>(PSRNAME));
+      std::string coord_md = block.getCoordMode();
+      std::string eq_str   = block.getEquinox();
+      float equinox        = 0.;
+      if(eq_str==Block::eq_j2000)       equinox = Block::eq_2000;
+      else if(eq_str==Block::eq_b1950)  equinox = Block::eq_1950;
+      std::string ra       = deblank(block.getKeyword<std::string>(RA));
+      std::string dec      = deblank(block.getKeyword<std::string>(DEC));
+      float bmaj           = block.Survey().getBmaj();
+      float bmin           = block.Survey().getBmin();
+      float bpa            = block.Survey().getBpa();
+      std::string stt_crd1 = deblank(block.getKeyword<std::string>(RA));
+      std::string stt_crd2 = deblank(block.getKeyword<std::string>(DEC));
+      std::string trk_mode = block.Survey().getTrk_mode();
+      std::string stp_crd1 = deblank(block.getKeyword<std::string>(RA));
+      std::string stp_crd2 = deblank(block.getKeyword<std::string>(DEC));
+      float scanlen        = block.Survey().getScanlen();
+      std::string fd_mode  = block.Survey().getFd_mode();
+      float fa_req         = block.getKeyword<float>(FEED_ANGLE);
+      std::string cal_mode = block.Survey().getCal_mode();
+      float cal_freq       = block.Survey().getCal_freq();
+      float cal_dcyc       = block.Survey().getCal_dcyc();
+      float cal_phs        = block.Survey().getCal_phs();
+      long stt_imjd        = block.getKeyword<int>(MJD);
+      long stt_smjd        = long(dmsToDec(deblank(block.getKeyword<std::string>(UT))) * 3600.);
+      double stt_offs      = FITS::PHU_stt_offs_default;
+      double stt_lst       = dmsToDec(block.getKeyword<std::string>(LST))*3600.;
+
+      this->updateKeyword("DATE",     todaysdate);
+      this->updateKeyword("PROJID",   projid);
+      this->updateKeyword("TELESCOP", telescop);
+      this->updateKeyword("ANT_X",    ant_x);          
+      this->updateKeyword("ANT_Y",    ant_y);        
+      this->updateKeyword("ANT_Z",    ant_z);        
+      this->updateKeyword("FRONTEND", frontend);
+      this->updateKeyword("FD_POLN",  fd_poln);
+      this->updateKeyword("FD_HAND",  fd_hand);
+      this->updateKeyword("FD_SANG",  fd_sang);
+      this->updateKeyword("FD_XYPH",  fd_xyph);
+      this->updateKeyword("BACKEND",  backend);
+      this->updateKeyword("BECONFIG", beconfig);
+      this->updateKeyword("BE_PHASE", be_phase);
+      this->updateKeyword("BE_DCC",   be_dcc);
+      this->updateKeyword("TCYCLE",   tcycle);
+      this->updateKeyword("NRCVR",    nrcvr);
+      this->updateKeyword("OBS_MODE", obs_mode);
+      this->updateKeyword("DATE-OBS", date_obs);
+      this->updateKeyword("OBSFREQ",  obsfreq);
+      this->updateKeyword("SRC_NAME", src_name);
+      this->updateKeyword("COORD_MD", coord_md);
+      if(equinox>0.)
+	this->updateKeyword("EQUINOX",  equinox);
+      this->updateKeyword("RA",       ra);
+      this->updateKeyword("DEC",      dec);
+      this->updateKeyword("BMAJ",     bmaj);
+      this->updateKeyword("BMIN",     bmin);
+      this->updateKeyword("BPA",      bpa);
+      this->updateKeyword("STT_CRD1", stt_crd1);
+      this->updateKeyword("STT_CRD2", stt_crd2);
+      this->updateKeyword("TRK_MODE", trk_mode);
+      this->updateKeyword("STP_CRD1", stp_crd1);
+      this->updateKeyword("STP_CRD2", stp_crd2);
+      this->updateKeyword("SCANLEN",  scanlen);
+      this->updateKeyword("FD_MODE",  fd_mode);
+      this->updateKeyword("FA_REQ",   fa_req);
+      this->updateKeyword("CAL_MODE", cal_mode);
+      this->updateKeyword("CAL_FREQ", cal_freq);
+      this->updateKeyword("CAL_DCYC", cal_dcyc);
+      this->updateKeyword("CAL_PHS ", cal_phs);
+      this->updateKeyword("STT_IMJD", stt_imjd);
+      this->updateKeyword("STT_SMJD", stt_smjd);
+      this->updateKeyword("STT_OFFS", stt_offs);
+      this->updateKeyword("STT_LST ", stt_lst);
+
+      //    this->addNewKeywords(block);
+
+      delete [] todaysdate;
+
+    }
+    //--------------------------------------------------------------------------
+  
+    void PSRFits::addNewKeywords(DataBlock &block)
+    {
+      /**
+       *   Adds new keywords to the PHU that have not yet been added into the 
+       *   PSRFITS definition.
+       *   Need to be in the PHU before calling this function.
+       *
+       *   NOTHING LEFT TO DO HERE.
+       */
+    
+    }
+    //--------------------------------------------------------------------------
+
+    void PSRFits::writeHistoryCommand()
+    {
+      /**
+       * Write processing history information to the HISTORY binary table 
+       * extension. This is just a row of today's date and what was entered
+       * in the command line.
+       * \param argc The number of command line arguments.
+       * \param argv Each command line argument.
+       */
+    
+      this->gotoHistory();
+
+      char *todaysdate     = new char[25];
+      int timeref,status=0;
+      fits_get_system_time(todaysdate, &timeref, &status);
+      if(status) this->FITSError("PSRFits::writeHistoryCommand", status);
+
+      //    std::string historyMessage;
+      //   historyMessage = "PVOCONVERT command: " + this->commandLine;
+
+      this->startNewRow(); 
+      this->writeColumnValue("DATE_PRO", todaysdate);
+      //    this->writeColumnValue("PROC_CMD", (char *)historyMessage.c_str());
+      this->writeColumnValue("PROC_CMD", (char *)this->commandLine.c_str());
+
+      this->gotoPHU();
+
+      delete [] todaysdate;
+
+    }
+    //--------------------------------------------------------------------------
+
+    //   void PSRFits::writeHistoryTapeFile(std::string filename)
+    void PSRFits::writeHistoryTapeFile()
+    {
+      /**
+       * Write processing history information to the HISTORY binary table 
+       * extension. This is just a row of today's date and what was entered
+       * in the command line.
+       * \param argc The number of command line arguments.
+       * \param argv Each command line argument.
+       */
+    
+      this->gotoHistory();
+
+      char *todaysdate     = new char[25];
+      int timeref,status=0;
+      fits_get_system_time(todaysdate, &timeref, &status);
+      if(status) this->FITSError("PSRFits::writeHistoryTapeFile", status);
+
+      std::string historyMessage;
+      historyMessage = "Tape file used: " + this->oldFilename;
+
+      this->startNewRow(); 
+      this->writeColumnValue("DATE_PRO", todaysdate);
+      this->writeColumnValue("PROC_CMD", (char *)historyMessage.c_str());
+
+      this->gotoPHU();
+
+      delete [] todaysdate;
+
+    }
+    //--------------------------------------------------------------------------
+
   }
 
- //--------------------------------------------------------------------------
-
-  int PSRFits::initialise(DataBlock &block)
-  {
-    /**
-     * Initialises a fits file for use in the conversion program. The
-     * order of business is as follows: 
-     *
-     * <ul>
-     *   <li> When new:
-     *   <ul><li> Set the initial date & time (UT) for the file. 
-     *       <li> If a new file is beginning, and the time has changed
-     *       and is smaller than the existing time, we need to
-     *       increment the date. This may be the case if we are
-     *       working through a large tape file and the blocks go past
-     *       midnight. 
-     *   </ul>
-     *   <li> Set the beam used in the file.
-     *   <li> Define the FITS file name.
-     *   <li> Set the starting block value.
-     *   <li> If new, test whether file exists.
-     *   <li> Open the fits file.
-     *   <li> If new:
-     *   <ul><li> Write the PHU headers using writePHU();
-     *       <li> Setup and write the SUBINT header with setupSubint(). 
-     *   </ul>
-     * </ul>
-     * \param block The block used to get the header information.
-     */
-
-    std::string newUT,date;
-
-    if(this->newFile){
-
-      this->numSamples = 0; // Initialise the number of samples.
-
-      newUT = block.getKeyword<std::string>(UT);
-      date   = block.getKeyword<std::string>(DATE);
-
-      // if we have gone over midnight.
-      if(dmsToDec(this->UT_initial) > dmsToDec(newUT) ) 
-	date = addDay(date);
-
-      this->setUT(newUT);
-      this->setDate(date);
-    }
-
-    this->setBeam(block.getKeyword<int>(IBEAM));
-
-    this->setFITSname(block.getSurveyType());
-
-    this->setInitialBlock(block.getKeyword<int>(BLK_CNTR));
-
-    if(this->newFile && this->fileExists()){
-      std::cerr << "\aThe file "<< this->getFITSname() 
-		<< " already exists.\n"
-		<< "Don't want to overwrite, so exiting...\n";
-      return FAILURE;
-    }
-
-    if(this->openFile()) {
-      std::cerr << "\aCannot open file "<< this->getFITSname()
-		<< ".\nExiting...\n";
-      return FAILURE;
-    }
-
-    if(this->newFile){
-      
-      //      this->writeHistoryTapeFile();
-      this->writeHistoryCommand();
-  
-      this->writePHU(block);
-
-      this->setupSubint(block);
-    
-    }
-
-    this->newFile = false;
-
-    return SUCCESS;
-
-  }
- //--------------------------------------------------------------------------
-
-  void PSRFits::setupSubint(DataBlock &block)
-  {
-    /**
-     *  A function to set up the subintegration binary table
-     *  extension.  This defines the necessary keywords, as well as
-     *  the DAT_... arrays to go in the columns (as these will be the
-     *  same for all rows of the subintegration table -- at least as
-     *  far as the conversion program goes.)
-     *
-     *  It then calls the Subint::writeKeywords() function to write
-     *  the header keywords to the table.
-     *
-     * \param block The block containing the header information.
-     */
-    
-    this->subintTable.tsamp = block.getKeyword<float>(SAMP_INT,0)/1000.;
-    this->subintTable.nbits = block.getKeyword<int>(NBITS,0);
-    this->subintTable.nbin = 1; 
-    this->subintTable.nch_file = block.getKeyword<int>(NCHAN);
-    this->subintTable.npol = 1;
-    this->subintTable.nsblk = block.getKeyword<int>(SAMP_GRP,0) * 
-      block.getKeyword<int>(GRP_BLK);
-
-    // define the DAT_FREQ array;
-    float deltaFreq = block.getKeyword<float>(CHANBW);
-    this->subintTable.dat_freq = new float[this->subintTable.nch_file];
-    this->subintTable.dat_freq[0] = block.getKeyword<float>(FREQ_CHAN1);
-    for(int i=1;i<this->subintTable.nch_file;i++) 
-      this->subintTable.dat_freq[i] = 
-	this->subintTable.dat_freq[i-1] + deltaFreq;
-
-    // define the DAT_WTS array;
-    this->subintTable.dat_wts = new float[this->subintTable.nch_file];
-    for(int i=0;i<this->subintTable.nch_file;i++)
-      this->subintTable.dat_wts[i] = 1.;
-
-    // define the DAT_OFFS array;
-    this->subintTable.dat_offs = new float[this->subintTable.nch_file];
-    for(int i=0;i<this->subintTable.nch_file;i++)
-      this->subintTable.dat_offs[i] = 0.;
-
-    // define the DAT_SCL array;
-    this->subintTable.dat_scl = new float[this->subintTable.nch_file];
-    for(int i=0;i<this->subintTable.nch_file;i++)
-      this->subintTable.dat_scl[i] = 1.;
-    
-    
-    this->subintTable.setAllocatedFlag(true);
-
-    // now write the keywords to the subint table
-    if(this->gotoSubint()){
-      std::cerr << 
-	"Error <PSRFits::initialise> : Could not go to the SUBINT table.\n";
-    }
-    else this->subintTable.writeKeywords(this->fptr);
-    
-  }
-
- //--------------------------------------------------------------------------
-
-  void Subint::writeKeywords(fitsfile *fptr)
-  {
-    /**
-     *  A special function in the Subint class to write all the header
-     *  keywords necessary for the subintegration binary table
-     *  extension. This should only need to be done once per file.
-     *
-     *  The keywords are stored as private members of Subint, and need
-     *  to be defined beforehand.
-     *
-     *  \param fptr The fitsfile pointer corresponding to the file to
-     *  be written to.
-     */
-
-    int status=0;
-    fits_update_key(fptr,TSTRING,"INT_TYPE", 
-		    (char *)this->int_type.c_str(), NULL, &status);
-    if(status) FITSError("Subint::writeKeywords 1",status);
-    
-    status=0;
-    fits_update_key(fptr,TSTRING,"INT_UNIT",(char *)this->int_unit.c_str(),NULL,&status);
-    if(status) FITSError("Subint::writeKeywords 2",status);
-    
-    status=0;
-    fits_update_key(fptr,TFLOAT,"TSAMP",&this->tsamp,NULL,&status);
-    if(status) FITSError("Subint::writeKeywords 3",status);
-    
-    status=0;
-    fits_update_key(fptr,TINT,"NBITS",&this->nbits,NULL,&status);
-    if(status) FITSError("Subint::writeKeywords 4",status);
-    
-    status=0;
-    fits_update_key(fptr,TINT,"NBIN",&this->nbin,NULL,&status);
-    if(status) FITSError("Subint::writeKeywords 5",status);
-    
-    status=0;
-    fits_update_key(fptr,TINT,"NCH_FILE",&this->nch_file,NULL,&status);
-    if(status) FITSError("Subint::writeKeywords 6",status);
-
-    status=0;
-    fits_update_key(fptr,TINT,"NCH_STRT",&this->nch_strt,NULL,&status);
-    if(status) FITSError("Subint::writeKeywords 7",status);
-    
-    status=0;
-    fits_update_key(fptr,TINT,"NPOL",&this->npol,NULL,&status);
-    if(status) FITSError("Subint::writeKeywords 8",status);
-    
-    status=0;
-    fits_update_key(fptr,TINT,"NSBLK",&this->nsblk,NULL,&status);
-    if(status) FITSError("Subint::writeKeywords 9",status);
-    
-    status=0;
-    int colnum=0;
-    fits_get_colnum(fptr, CASEINSEN, "DATA", &colnum, &status);
-    if(status) FITSError("Subint::writeKeywords 10", status);
-
-    status=0;
-    fits_modify_vector_len (fptr, colnum, this->getDataSize(), &status);
-    if(status) FITSError("Subint::writeKeywords 11", status);
-
-    // delete the existing "TDIM19 = (*,*,*,*)" and write the new one.
-    status=0;
-    fits_delete_key(fptr, "TDIM19", &status);
-    if(status) FITSError("Subint::writeKeywords 12", status);
-    int naxis=4;
-    long naxes[4];
-    naxes[0] = this->nbits;
-    naxes[1] = this->nch_file;
-    naxes[2] = this->npol;
-    naxes[3] = this->nsblk;
-    status=0;
-    fits_write_tdim(fptr, colnum, naxis, naxes, &status);
-    if(status) FITSError("Subint::writeKeywords 11", status);
-
-  }
- //--------------------------------------------------------------------------
-
-  void PSRFits::writeSubintRow(DataBlock &block)
-  {
-    /**
-     * This function writes an entire new row in the SUBINT table extension.
-     * The procedure is as follows:
-     * <ul> <li> Move to the subint table.
-     *      <li> Start a new row with startNewSubintRow()
-     *      <li> Write the single-valued columns with writeColumnValue()
-     *      <li> Write the multi-valued DAT_... columns
-     *      <li> Write the data.
-     *      <li> Increment the number of samples.
-     * </ul>
-     * \param block The block containing the header info & the data.
-     */
-
-    this->gotoSubint();
-    this->startNewSubintRow(); 
-
-    float tsubint = block.getKeyword<float>(BLK_SEC);
-    double off_sub;
-    
-    off_sub = 0.5*(2.*(block.getKeyword<int>(BLK_CNTR)-this->blk_initial)+1)
-      * block.getKeyword<double>(BLK_SEC);
-
-    double lst_sub  = dmsToDec(block.getKeyword<std::string>(LST));
-    double ra_sub   = dmsToDec(block.getKeyword<std::string>(RA))*15.;
-    double dec_sub  = dmsToDec(block.getKeyword<std::string>(DEC));
-    double glon_sub = block.getKeyword<double>(GL);
-    double glat_sub = block.getKeyword<double>(GB);
-    float  fd_ang   = block.getKeyword<float>(FEED_ANGLE);
-    float  par_ang  = block.getKeyword<float>(PANGLE);
-    float  pos_ang  = remainderf(par_ang + fd_ang, 360.);
-    float  tel_az   = block.getKeyword<float>(TEL_AZ);
-    float  tel_zen  = block.getKeyword<float>(TEL_ZEN);
-    
-    this->writeColumnValue("TSUBINT",  tsubint);
-    this->writeColumnValue("OFFS_SUB", off_sub);
-    this->writeColumnValue("LST_SUB",  lst_sub);
-    this->writeColumnValue("RA_SUB",   ra_sub);
-    this->writeColumnValue("DEC_SUB",  dec_sub);
-    this->writeColumnValue("GLON_SUB", glon_sub);
-    this->writeColumnValue("GLAT_SUB", glat_sub);
-    this->writeColumnValue("FD_ANG",   fd_ang);
-    this->writeColumnValue("POS_ANG",  pos_ang);
-    this->writeColumnValue("PAR_ANG",  par_ang);
-    this->writeColumnValue("TEL_AZ",   tel_az);
-    this->writeColumnValue("TEL_ZEN",  tel_zen);
-
-    /////////////////////////////////////
-
-    long nrows = this->getNumRows();
-    int colnum = this->getColnum("DAT_FREQ");
-    int status=0;
-    fits_modify_vector_len (this->fptr, colnum, 
-			    this->subintTable.nch_file, &status);
-    if(status) FITSError("PSRFits::writeSubintRow", status);
-    status=0;
-    fits_write_col(this->fptr, TFLOAT, colnum, nrows, 1, 
-		   this->subintTable.nch_file, this->subintTable.dat_freq, 
-		   &status);
-    if(status) FITSError("PSRFits::writeSubintRow", status);
-
-    colnum = this->getColnum("DAT_WTS");
-    status=0;
-    fits_modify_vector_len (this->fptr, colnum, 
-			    this->subintTable.nch_file, &status);
-    if(status) FITSError("PSRFits::writeSubintRow", status);
-    status=0;
-    fits_write_col(this->fptr, TFLOAT, colnum, nrows, 1, 
-		   this->subintTable.nch_file, this->subintTable.dat_wts, 
-		   &status);
-    if(status) FITSError("PSRFits::writeSubintRow", status);
-
-    colnum = this->getColnum("DAT_OFFS");
-    status=0;
-    fits_modify_vector_len (this->fptr, colnum, 
-			    this->subintTable.nch_file, &status);
-    if(status) FITSError("PSRFits::writeSubintRow", status);
-    status=0;
-    fits_write_col(this->fptr, TFLOAT, colnum, nrows, 1, 
-		   this->subintTable.nch_file, this->subintTable.dat_offs, 
-		   &status);
-    if(status) FITSError("PSRFits::writeSubintRow", status);
-
-    colnum = this->getColnum("DAT_SCL");
-    status=0;
-    fits_modify_vector_len (this->fptr, colnum, 
-			    this->subintTable.nch_file, &status);
-    if(status) FITSError("PSRFits::writeSubintRow", status);
-    status=0;
-    fits_write_col(this->fptr, TFLOAT, colnum, nrows, 1, 
-		   this->subintTable.nch_file, this->subintTable.dat_scl, 
-		   &status);
-    if(status) FITSError("PSRFits::writeSubintRow", status);
-
-    //////////////////////////////////////////
-
-    unsigned char *data = (unsigned char *)block.getData();
-
-    if(this->FITSname == "PM_061222_150342_01.fits" && nrows==1){
-      std::cout << charToBinary(data[0]);
-      std::cout << charToBinary(data[1]);
-      std::cout << charToBinary(data[2]);
-      std::cout << "\n";
-    }
-
-    colnum = this->getColnum("DATA");
-    status=0;
-    fits_write_col_byt(this->fptr, colnum, nrows, 1, this->subintTable.getDataSizeBytes(), data, &status);
-    if(status) FITSError("PSRFits::writeDataArray 4", status);
-
-    //////////////////////////////////////////
-
-    // Increment the number of samples
-    this->numSamples += (block.getKeyword<int>(GRP_BLK) * 
-			 block.getKeyword<int>(SAMP_GRP) );
-
-  }
- //--------------------------------------------------------------------------
-
-  void PSRFits::writePHU(DataBlock &block)
-  {
-    /**
-     *   Writes the header information contained in the DataBlock block
-     *    to the primary header unit.
-     *   At the end the current header unit will be the PHU.
-     */
-    this->gotoPHU();
-
-    char *todaysdate     = new char[25];
-    int timeref,status=0;
-    fits_get_system_time(todaysdate, &timeref, &status);
-    if(status) FITSError("PSRFits::writePHU", status);
-    std::string projid   = block.getSurveyName();
-    std::string telescop = block.getKeyword<std::string>(TELID);
-    if((deblank(telescop)=="")&&(block.getSurveyType()==S70)) 
-      telescop           = "PARKES";
-    double ant_x         = block.Survey().getAntX();
-    double ant_y         = block.Survey().getAntY();
-    double ant_z         = block.Survey().getAntZ();
-    std::string frontend = block.Survey().getFrontend();
-    std::string fd_poln  = block.Survey().getFd_poln();
-    int fd_hand          = block.Survey().getFd_hand();
-    float fd_sang        = block.Survey().getFd_sang();
-    float fd_xyph        = block.Survey().getFd_xyph();
-    std::string backend  = block.Survey().getBackend();
-    std::string beconfig = block.Survey().getBeconfig();
-    int be_phase         = block.Survey().getBe_phase();
-    int be_dcc           = block.Survey().getBe_dcc();
-    double tcycle        = block.Survey().getTcycle();
-    int nrcvr            = block.getKeyword<int>(NFILTER);
-    std::string obs_mode = block.Survey().getObs_mode();
-
-    std::string date_obs = 
-      makeDateObs(deblank(block.getKeyword<std::string>(DATE)),
-		  deblank(block.getKeyword<std::string>(UT))   );
-
-    double f0            = block.getKeyword<double>(FREQ_CHAN1);
-    double bw            = block.getKeyword<double>(CHANBW);
-    double nc            = block.getKeyword<double>(NCHAN);
-    float obsfreq        = f0 + ((nc-1)/2.) * bw;
-
-    std::string src_name = deblank(block.getKeyword<std::string>(PSRNAME));
-    std::string coord_md = block.getCoordMode();
-    std::string eq_str   = block.getEquinox();
-    float equinox        = 0.;
-    if(eq_str==Block::eq_j2000)       equinox = Block::eq_2000;
-    else if(eq_str==Block::eq_b1950)  equinox = Block::eq_1950;
-    std::string ra       = deblank(block.getKeyword<std::string>(RA));
-    std::string dec      = deblank(block.getKeyword<std::string>(DEC));
-    float bmaj           = block.Survey().getBmaj();
-    float bmin           = block.Survey().getBmin();
-    float bpa            = block.Survey().getBpa();
-    std::string stt_crd1 = deblank(block.getKeyword<std::string>(RA));
-    std::string stt_crd2 = deblank(block.getKeyword<std::string>(DEC));
-    std::string trk_mode = block.Survey().getTrk_mode();
-    std::string stp_crd1 = deblank(block.getKeyword<std::string>(RA));
-    std::string stp_crd2 = deblank(block.getKeyword<std::string>(DEC));
-    float scanlen        = block.Survey().getScanlen();
-    std::string fd_mode  = block.Survey().getFd_mode();
-    float fa_req         = block.getKeyword<float>(FEED_ANGLE);
-    std::string cal_mode = block.Survey().getCal_mode();
-    float cal_freq       = block.Survey().getCal_freq();
-    float cal_dcyc       = block.Survey().getCal_dcyc();
-    float cal_phs        = block.Survey().getCal_phs();
-    long stt_imjd        = block.getKeyword<int>(MJD);
-    long stt_smjd        = long(dmsToDec(deblank(block.getKeyword<std::string>(UT))) * 3600.);
-    double stt_offs      = FITS::PHU_stt_offs_default;
-    double stt_lst       = dmsToDec(block.getKeyword<std::string>(LST))*3600.;
-
-    this->updateKeyword("DATE",     todaysdate);
-    this->updateKeyword("PROJID",   projid);
-    this->updateKeyword("TELESCOP", telescop);
-    this->updateKeyword("ANT_X",    ant_x);          
-    this->updateKeyword("ANT_Y",    ant_y);        
-    this->updateKeyword("ANT_Z",    ant_z);        
-    this->updateKeyword("FRONTEND", frontend);
-    this->updateKeyword("FD_POLN",  fd_poln);
-    this->updateKeyword("FD_HAND",  fd_hand);
-    this->updateKeyword("FD_SANG",  fd_sang);
-    this->updateKeyword("FD_XYPH",  fd_xyph);
-    this->updateKeyword("BACKEND",  backend);
-    this->updateKeyword("BECONFIG", beconfig);
-    this->updateKeyword("BE_PHASE", be_phase);
-    this->updateKeyword("BE_DCC",   be_dcc);
-    this->updateKeyword("TCYCLE",   tcycle);
-    this->updateKeyword("NRCVR",    nrcvr);
-    this->updateKeyword("OBS_MODE", obs_mode);
-    this->updateKeyword("DATE-OBS", date_obs);
-    this->updateKeyword("OBSFREQ",  obsfreq);
-    this->updateKeyword("SRC_NAME", src_name);
-    this->updateKeyword("COORD_MD", coord_md);
-    if(equinox>0.)
-      this->updateKeyword("EQUINOX",  equinox);
-    this->updateKeyword("RA",       ra);
-    this->updateKeyword("DEC",      dec);
-    this->updateKeyword("BMAJ",     bmaj);
-    this->updateKeyword("BMIN",     bmin);
-    this->updateKeyword("BPA",      bpa);
-    this->updateKeyword("STT_CRD1", stt_crd1);
-    this->updateKeyword("STT_CRD2", stt_crd2);
-    this->updateKeyword("TRK_MODE", trk_mode);
-    this->updateKeyword("STP_CRD1", stp_crd1);
-    this->updateKeyword("STP_CRD2", stp_crd2);
-    this->updateKeyword("SCANLEN",  scanlen);
-    this->updateKeyword("FD_MODE",  fd_mode);
-    this->updateKeyword("FA_REQ",   fa_req);
-    this->updateKeyword("CAL_MODE", cal_mode);
-    this->updateKeyword("CAL_FREQ", cal_freq);
-    this->updateKeyword("CAL_DCYC", cal_dcyc);
-    this->updateKeyword("CAL_PHS ", cal_phs);
-    this->updateKeyword("STT_IMJD", stt_imjd);
-    this->updateKeyword("STT_SMJD", stt_smjd);
-    this->updateKeyword("STT_OFFS", stt_offs);
-    this->updateKeyword("STT_LST ", stt_lst);
-
-    //    this->addNewKeywords(block);
-
-    delete [] todaysdate;
-
-  }
- //--------------------------------------------------------------------------
-  
-  void PSRFits::addNewKeywords(DataBlock &block)
-  {
-    /**
-     *   Adds new keywords to the PHU that have not yet been added into the 
-     *   PSRFITS definition.
-     *   Need to be in the PHU before calling this function.
-     *
-     *   NOTHING LEFT TO DO HERE.
-     */
-    
-  }
- //--------------------------------------------------------------------------
-
-  void PSRFits::writeHistoryCommand()
-  {
-    /**
-     * Write processing history information to the HISTORY binary table 
-     * extension. This is just a row of today's date and what was entered
-     * in the command line.
-     * \param argc The number of command line arguments.
-     * \param argv Each command line argument.
-     */
-    
-   this->gotoHistory();
-
-   char *todaysdate     = new char[25];
-   int timeref,status=0;
-   fits_get_system_time(todaysdate, &timeref, &status);
-   if(status) FITSError("PSRFits::writeHistoryCommand", status);
-
-//    std::string historyMessage;
-   //   historyMessage = "PVOCONVERT command: " + this->commandLine;
-
-   this->startNewRow(); 
-   this->writeColumnValue("DATE_PRO", todaysdate);
-//    this->writeColumnValue("PROC_CMD", (char *)historyMessage.c_str());
-   this->writeColumnValue("PROC_CMD", (char *)this->commandLine.c_str());
-
-   this->gotoPHU();
-
-   delete [] todaysdate;
-
-  }
- //--------------------------------------------------------------------------
-
-//   void PSRFits::writeHistoryTapeFile(std::string filename)
-  void PSRFits::writeHistoryTapeFile()
-  {
-    /**
-     * Write processing history information to the HISTORY binary table 
-     * extension. This is just a row of today's date and what was entered
-     * in the command line.
-     * \param argc The number of command line arguments.
-     * \param argv Each command line argument.
-     */
-    
-   this->gotoHistory();
-
-   char *todaysdate     = new char[25];
-   int timeref,status=0;
-   fits_get_system_time(todaysdate, &timeref, &status);
-   if(status) FITSError("PSRFits::writeHistoryTapeFile", status);
-
-   std::string historyMessage;
-   historyMessage = "Tape file used: " + this->oldFilename;
-
-   this->startNewRow(); 
-   this->writeColumnValue("DATE_PRO", todaysdate);
-   this->writeColumnValue("PROC_CMD", (char *)historyMessage.c_str());
-
-   this->gotoPHU();
-
-   delete [] todaysdate;
-
-  }
- //--------------------------------------------------------------------------
-
 }
-
Index: /trunk/src/pvo-FITS.cc
===================================================================
--- /trunk/src/pvo-FITS.cc	(revision 50)
+++ /trunk/src/pvo-FITS.cc	(revision 51)
@@ -10,408 +10,433 @@
 #include "pvo-header.hh"
 
-using namespace Block;
-using namespace Header;
-
-namespace FITS
+using namespace PVO::Block;
+using namespace PVO::Header;
+
+namespace PVO
 {
-  
-  PSRFits::PSRFits()
+
+  namespace FITS
   {
-    this->newFile = true;
-    this->filestate = CLOSED;
-    this->UT_initial = decToDMS(0.);
+  
+    PSRFits::PSRFits()
+    {
+      this->newFile = true;
+      this->filestate = CLOSED;
+      this->UT_initial = decToDMS(0.);
+      this->verbose = true;
+    }
+    //-----------------------------------------------------------------------
+
+    PSRFits::PSRFits(std::string name)
+    {
+      this->filestate = CLOSED;
+      this->openFile(name);
+      this->verbose = true;
+    }
+    //-----------------------------------------------------------------------
+
+    void PSRFits::FITSError(std::string function, int status){
+      /** 
+       * An error message is printed, along with the relevant CFITSIO error
+       * code and message.  
+       * \param function The function from which the error was called.  
+       * \param status The status value as returned by the CFITSIO function. 
+       *  Generally, if status != 0, an error has occurred.
+       */
+      if(this->verbose){
+	std::cerr << "\aFITSError <" << function 
+		  << "> (status="    << status   <<"): ";
+	fits_report_error(stderr, status);
+      }
+    }
+    //------------------------------------------------------------
+    void PSRFits::setCommandLine(int argc, char *argv[])
+    {
+      std::stringstream ss;
+
+      // strip off any leading directory from the executable.
+      std::string exec = argv[0];
+      unsigned int found = exec.rfind("/");
+      if(found != std::string::npos){
+	exec = exec.substr(found+1,exec.size()-1);
+      }
+
+      ss << exec;
+      for(int i=1;i<argc;i++){
+	if(i>0) ss << " ";
+	ss << argv[i];
+      }
+      this->commandLine = ss.str();
+
+    };
+    //----------------------------------------------------------------------
+
+    void PSRFits::setFITSname(Header::SURVEY surveyType)
+    {
+      /**
+       * Generates a string containing the name of the FITS file, based on the
+       *  values of the initial date and time of the first observations in the 
+       *  file, and (if the multibeam receiver was used) the beam number. 
+       * The format is determined by the survey type. Possible formats are:
+       * <ul> <li> S70_yymmdd_hhmmss.fits
+       *      <li> PM_yymmdd_hhmmss_bb.fits </ul>
+       * \param surveyType The enumerated type of the survey data.
+       * \return String containing the FITS filename.
+       */
+      std::string date;
+
+      for(unsigned int i=0;i<this->DATE_initial.size();i++)
+	if(DATE_initial[i]!='/') date += this->DATE_initial[i];
+
+      std::string time = removeLeadingBlanks(this->UT_initial);
+      time = decToDMS( dmsToDec(time), 0, "");
+    
+      std::stringstream output;
+      if(surveyType == S70) output << "S70_";
+      else if(surveyType == PM) output << "PM_";
+      else if(surveyType == PH) output << "PH_";
+      else std::cerr << "Error <PSRFits::setFITSname> : unknown survey!\n";
+
+      output << date << "_" << time;
+
+      if((surveyType == PM)||(surveyType == PH))
+	output << "_" 
+	       << std::setw(2) << std::setfill('0') 
+	       << this->beam_number;
+
+      output << ".fits";
+
+      this->FITSname = output.str();
+    
+    }
+    //--------------------------------------------------------------------------
+
+    bool PSRFits::fileExists()
+    {
+      /**
+       * Checks to see whether the file is exists. Uses the CFITSIO function
+       * fits_file_exists, and the parameter PSRFits::FITSname.
+       * \return True if the file exists, false otherwise.
+       */
+      int status = 0, exists;
+      fits_file_exists(this->FITSname.c_str(), &exists, &status);
+      if(status) this->FITSError("PSRFits::fileExists",status);
+      if(exists>0) return true;
+      else return false;
+    }
+    //--------------------------------------------------------------------------
+
+    int PSRFits::openFile(std::string name)
+    {
+      /**
+       *   If the file exists, it is opened.
+       *   If not, it is created using the correct template file.
+       *    In the latter case, the fix function is called, and the file is
+       *    flagged as "new".
+       *  \param name Filename of the fits file to be opened.
+       */
+      int status = 0, exists;
+      fits_file_exists(name.c_str(),&exists,&status);
+      if(status) this->FITSError("PSRFits::openFile 1",status);
+      status=0;
+      if(exists<=0){
+	char *template_file = (char *)getPSRFITSdefn().c_str();
+	fits_create_template(&this->fptr, name.c_str(), template_file, &status);
+	std::cerr << "Creating new file " << name << "\n";
+	this->newFile = true;
+      }
+      else{
+	fits_open_file(&this->fptr, name.c_str(), READWRITE, &status);
+      }
+      if(status) this->FITSError("PSRFits::openFile 2",status);
+      else{
+	if(exists<=0) this->fixPSRFITS();
+	this->gotoPHU();
+	this->filestate = OPEN;
+      }
+      return status;
+    }
+    //--------------------------------------------------------------------------
+  
+    bool PSRFits::fitsFull(DataBlock &block)
+    {
+      /**
+       * Checks to see if the FITS file has reached the point where it
+       * needs to be closed. This should not happen until the later of:
+       * <ul><li> MOVE flag is set to moving.
+       *     <li> Number of samples is at least the minimum number
+       *     determined by the survey.
+       * </ul>
+       * \return True if we have met *both* of these conditions. False
+       * if we have not reached that point yet.
+       */
+      bool moveFlag = !block.telescopeOK();
+      bool sampleFlag = (this->numSamples >= block.Survey().getMinSamples());
+      return (moveFlag && sampleFlag);
+    }
+    //--------------------------------------------------------------------------
+  
+    int PSRFits::closeFile()
+    {
+      /**
+       *   Closes the file if it is open. Adjusts the filestate variable
+       *   as well.
+       */
+      int status = 0;
+      if(this->filestate == OPEN){
+	fits_close_file(this->fptr, &status);
+	if(status) this->FITSError("PSRFits::closeFile",status);
+	this->filestate = CLOSED;
+      }
+      return status;
+    }
+    //--------------------------------------------------------------------------
+  
+    int PSRFits::gotoPHU()
+    {
+      int status = 0;
+      fits_movabs_hdu(this->fptr, 1, NULL, &status);    
+      if(status) this->FITSError("PSRFits::gotoPHU",status);
+      return status;
+    }
+    //--------------------------------------------------------------------------
+  
+    int PSRFits::gotoHistory()
+    {
+      int status = 0;
+      char name[8];
+      strcpy(name,"HISTORY");
+      fits_movnam_hdu(this->fptr, BINARY_TBL, name, 0, &status);
+      if(status) this->FITSError("PSRFits::gotoHistory",status);
+      return status;
+    }
+    //--------------------------------------------------------------------------
+  
+    int PSRFits::deleteTable(char tableName[])
+    {
+      /** 
+       * Deletes the named binary table -- first moving to the HDU then
+       * deleting it. At completion, we have returned to the PHU.
+       */ 
+      int status = 0;
+      int newHDUtype;
+      fits_movnam_hdu(this->fptr, BINARY_TBL, tableName, 0, &status);
+      if(status) this->FITSError("PSRFits::deleteTable",status);
+      fits_delete_hdu(this->fptr, &newHDUtype, &status);
+      if(status) this->FITSError("PSRFits::deleteTable",status);
+      gotoPHU();
+      return status;
+    }
+    //--------------------------------------------------------------------------
+  
+    int PSRFits::gotoSubint()
+    {
+      int status = 0;
+      char name[8];
+      strcpy(name,"SUBINT");
+      fits_movnam_hdu(this->fptr, BINARY_TBL, name, 0, &status);
+      if(status) this->FITSError("PSRFits::gotoSubint",status);
+      return status;
+    }
+    //--------------------------------------------------------------------------
+  
+    template <typename T> int PSRFits::updateKeyword(std::string name, T value)
+    {
+      /**
+       *   Updates the keyword "name" in the current header unit, giving
+       *    it the value given by "value".
+       *   A templated function that should work for all cases.
+       */
+      int status=0;
+      fits_update_key(this->fptr, TINT, name.c_str(), &value, NULL, &status);
+      if(status) this->FITSError("PSRFits::updateKeyword",status);
+      return status;
+    }
+    template <> int PSRFits::updateKeyword(std::string name, int value){
+      int status=0;
+      fits_update_key(this->fptr, TINT, (char *)name.c_str(), 
+		      &value, NULL, &status);
+      if(status) this->FITSError("PSRFits::updateKeyword",status);
+      return status;
+    }
+    template <> int PSRFits::updateKeyword(std::string name, long value){
+      int status=0;
+      fits_update_key(this->fptr, TLONG, (char *)name.c_str(), 
+		      &value, NULL, &status);
+      if(status) this->FITSError("PSRFits::updateKeyword",status);
+      return status;
+    }
+    template <> int PSRFits::updateKeyword(std::string name, float value){
+      int status=0;
+      fits_update_key(this->fptr, TFLOAT, (char *)name.c_str(),
+		      &value, NULL, &status);
+      if(status) this->FITSError("PSRFits::updateKeyword",status);
+      return status;
+    }
+    template <> int PSRFits::updateKeyword(std::string name, double value){
+      int status=0;
+      fits_update_key(this->fptr, TDOUBLE, (char *)name.c_str(), 
+		      &value, NULL, &status);
+      if(status) this->FITSError("PSRFits::updateKeyword",status);
+      return status;
+    }
+    template <> int PSRFits::updateKeyword(std::string name, std::string value){
+      int status=0;
+      fits_update_key(this->fptr, TSTRING, (char *)name.c_str(), 
+		      (char *)value.c_str(), NULL, &status);
+      if(status) this->FITSError("PSRFits::updateKeyword",status);
+      return status;
+    }
+    template <> int PSRFits::updateKeyword(std::string name, char *value){
+      int status=0;
+      fits_update_key(this->fptr, TSTRING, (char *)name.c_str(), 
+		      value, NULL, &status);
+      if(status) this->FITSError("PSRFits::updateKeyword",status);
+      return status;
+    }
+    //--------------------------------------------------------------------------
+  
+    template <typename T> int PSRFits::getKeyword(std::string name, T &value)
+    {
+      /**
+       *   Finds the keyword "name" in the current header unit, returning the value in the "value" parameter.
+       *   A templated function that should work for all cases.
+       *  \param name The name of the keyword.
+       *  \param value The returned value of the keyword.
+       *  \return The status value from the fits_read_keyword function.
+       */
+      int status=0;
+      char keywordValue[80], keywordComment[80];
+      fits_read_keyword(this->fptr, (char *)name.c_str(), keywordValue, 
+			keywordComment, &status);
+      if(status) {
+	if(PVO::verbose) this->FITSError("PSRFits::getKeyword",status);
+      }
+      else{
+	std::stringstream ss;
+	ss.str(keywordValue);
+	ss >> value;
+      }
+      return status;
+    }
+    template int PSRFits::getKeyword<int>(std::string name, int &value);
+    template int PSRFits::getKeyword<long>(std::string name, long &value);
+    template int PSRFits::getKeyword<float>(std::string name, float &value);
+    template int PSRFits::getKeyword<double>(std::string name, double &value);
+    template <> int PSRFits::getKeyword<std::string>(std::string name, std::string &value){
+      int status=0;
+      char keywordValue[80], keywordComment[80];
+      fits_read_keyword(this->fptr, (char *)name.c_str(), keywordValue, 
+			keywordComment, &status);
+      if(status) {
+	if(PVO::verbose) this->FITSError("PSRFits::getKeyword",status);
+      }
+      else value = keywordValue;
+      if(value[0]=='\'') value.erase(0,1);
+      if(value[value.size()-1]=='\'') value.erase(value.size()-1,1);
+      return status;
+    }
+    
+  
+    //--------------------------------------------------------------------------
+
+    int PSRFits::getColnum(char *name)
+    {
+      int status=0,colnum=0;
+      fits_get_colnum(this->fptr, CASEINSEN, name, &colnum, &status);
+      if(status) this->FITSError("getColnum", status);
+      return colnum;
+    }
+  
+    long PSRFits::getNumRows()
+    {
+      int status=0;
+      long nrows=0;
+      fits_get_num_rows(this->fptr, &nrows, &status);
+      if(status) this->FITSError("getNumRows", status);
+      return nrows;
+    }
+    //--------------------------------------------------------------------------
+  
+    template <class T> int PSRFits::writeColumnValue(char *name, T value)
+    {
+      /**
+       *   Writes a new value in the column "name" in the current binary table.
+       *   It adds a single value at the bottom of the table (ie. in the largest
+       *    numbered row).
+       *   A templated function that should work for all cases.
+       */
+      int status=0;
+      int colnum = this->getColnum(name);
+      long nrows = this->getNumRows();
+      fits_write_col(this->fptr, TINT, colnum, nrows, 1, 1, &value, &status);
+      if(status) this->FITSError("PSRFits::writeColumnValue", status);
+      return status;
+    }
+    template <> int PSRFits::writeColumnValue(char *name, long value)
+    {
+      int status=0;
+      int colnum = this->getColnum(name);
+      long nrows = this->getNumRows();
+      fits_write_col(this->fptr, TLONG, colnum, nrows, 1, 1, &value, &status);
+      if(status) this->FITSError("PSRFits::writeColumnValue", status);
+      return status;
+    }
+    template <> int PSRFits::writeColumnValue(char *name, float value)
+    {
+      int status=0;
+      int colnum = this->getColnum(name);
+      long nrows = this->getNumRows();
+      fits_write_col(this->fptr, TFLOAT, colnum, nrows, 1, 1, &value, &status);
+      if(status) this->FITSError("PSRFits::writeColumnValue", status);
+      return status;
+    }
+    template <> int PSRFits::writeColumnValue(char *name, double value)
+    {
+      int status=0;
+      int colnum = this->getColnum(name);
+      long nrows = this->getNumRows();
+      fits_write_col(this->fptr, TDOUBLE, colnum, nrows, 1, 1, &value, &status);
+      if(status) this->FITSError("PSRFits::writeColumnValue", status);
+      return status;
+    }
+    template <> int PSRFits::writeColumnValue(char *name, char *value)
+    {
+      int status=0;
+      int colnum = this->getColnum(name);
+      long nrows = this->getNumRows();
+      fits_write_col(this->fptr, TSTRING, colnum, nrows, 1, 1, &value, &status);
+      if(status) this->FITSError("PSRFits::writeColumnValue", status);
+      return status;
+    }
+    //--------------------------------------------------------------------------
+
+    int PSRFits::startNewRow()
+    {
+      /**
+       *    Adds a new row to the bottom of the current binary table.
+       *    Also adds the row number as the ISUBINT column value.
+       */
+      int nrows = this->getNumRows();
+      int status = 0;
+      fits_insert_rows(this->fptr, nrows, 1, &status);
+      if(status) this->FITSError("PSRFits::startNewRow", status);
+      return status;
+    }
+    //--------------------------------------------------------------------------
+
+    void PSRFits::startNewSubintRow()
+    {
+      /**
+       *    Adds a new row to the bottom of the current binary table.
+       *    Also adds the row number as the ISUBINT column value.
+       */
+      this->startNewRow();
+      this->writeColumnValue("ISUBINT", this->getNumRows());
+    }
+    //--------------------------------------------------------------------------
+
+
   }
- //--------------------------------------------------------------------------
-
-  PSRFits::PSRFits(std::string name)
-  {
-    this->filestate = CLOSED;
-    this->openFile(name);
-  }
- //--------------------------------------------------------------------------
-
-  void PSRFits::setCommandLine(int argc, char *argv[])
-  {
-    std::stringstream ss;
-
-    // strip off any leading directory from the executable.
-    std::string exec = argv[0];
-    unsigned int found = exec.rfind("/");
-    if(found != std::string::npos){
-      exec = exec.substr(found+1,exec.size()-1);
-    }
-
-    ss << exec;
-    for(int i=1;i<argc;i++){
-      if(i>0) ss << " ";
-      ss << argv[i];
-    }
-    this->commandLine = ss.str();
-
-  };
-  //--------------------------------------------------------------------------
-
-  void PSRFits::setFITSname(Header::SURVEY surveyType)
-  {
-    /**
-     * Generates a string containing the name of the FITS file, based on the
-     *  values of the initial date and time of the first observations in the 
-     *  file, and (if the multibeam receiver was used) the beam number. 
-     * The format is determined by the survey type. Possible formats are:
-     * <ul> <li> S70_yymmdd_hhmmss.fits
-     *      <li> PM_yymmdd_hhmmss_bb.fits </ul>
-     * \param surveyType The enumerated type of the survey data.
-     * \return String containing the FITS filename.
-     */
-    std::string date;
-
-    for(unsigned int i=0;i<this->DATE_initial.size();i++)
-      if(DATE_initial[i]!='/') date += this->DATE_initial[i];
-
-    std::string time = removeLeadingBlanks(this->UT_initial);
-    time = decToDMS( dmsToDec(time), 0, "");
-    
-    std::stringstream output;
-    if(surveyType == S70) output << "S70_";
-    else if(surveyType == PM) output << "PM_";
-    else if(surveyType == PH) output << "PH_";
-    else std::cerr << "Error <PSRFits::setFITSname> : unknown survey!\n";
-
-    output << date << "_" << time;
-
-    if((surveyType == PM)||(surveyType == PH))
-      output << "_" 
-	     << std::setw(2) << std::setfill('0') 
-	     << this->beam_number;
-
-    output << ".fits";
-
-    this->FITSname = output.str();
-    
-  }
- //--------------------------------------------------------------------------
-
-  bool PSRFits::fileExists()
-  {
-    /**
-     * Checks to see whether the file is exists. Uses the CFITSIO function
-     * fits_file_exists, and the parameter PSRFits::FITSname.
-     * \return True if the file exists, false otherwise.
-     */
-    int status = 0, exists;
-    fits_file_exists(this->FITSname.c_str(), &exists, &status);
-    if(status) FITSError("PSRFits::fileExists",status);
-    if(exists>0) return true;
-    else return false;
-  }
- //--------------------------------------------------------------------------
-
-  int PSRFits::openFile(std::string name)
-  {
-    /**
-     *   If the file exists, it is opened.
-     *   If not, it is created using the correct template file.
-     *    In the latter case, the fix function is called, and the file is
-     *    flagged as "new".
-     *  \param name Filename of the fits file to be opened.
-     */
-    int status = 0, exists;
-    fits_file_exists(name.c_str(),&exists,&status);
-    if(status) FITSError("PSRFits::openFile 1",status);
-    status=0;
-    if(exists<=0){
-      char *template_file = (char *)getPSRFITSdefn().c_str();
-      fits_create_template(&this->fptr, name.c_str(), template_file, &status);
-      std::cerr << "Creating new file " << name << "\n";
-      this->newFile = true;
-    }
-    else{
-      fits_open_file(&this->fptr, name.c_str(), READWRITE, &status);
-    }
-    if(status) FITSError("PSRFits::openFile 2",status);
-    else{
-      if(exists<=0) this->fixPSRFITS();
-      this->gotoPHU();
-      this->filestate = OPEN;
-    }
-    return status;
-  }
- //--------------------------------------------------------------------------
-  
-  bool PSRFits::fitsFull(DataBlock &block)
-  {
-    /**
-     * Checks to see if the FITS file has reached the point where it
-     * needs to be closed. This should not happen until the later of:
-     * <ul><li> MOVE flag is set to moving.
-     *     <li> Number of samples is at least the minimum number
-     *     determined by the survey.
-     * </ul>
-     * \return True if we have met *both* of these conditions. False
-     * if we have not reached that point yet.
-     */
-    bool moveFlag = !block.telescopeOK();
-    bool sampleFlag = (this->numSamples >= block.Survey().getMinSamples());
-    return (moveFlag && sampleFlag);
-  }
- //--------------------------------------------------------------------------
-  
-  int PSRFits::closeFile()
-  {
-    /**
-     *   Closes the file if it is open. Adjusts the filestate variable
-     *   as well.
-     */
-    int status = 0;
-    if(this->filestate == OPEN){
-      fits_close_file(this->fptr, &status);
-      if(status) FITSError("PSRFits::closeFile",status);
-      this->filestate = CLOSED;
-    }
-    return status;
-  }
- //--------------------------------------------------------------------------
-  
-  int PSRFits::gotoPHU()
-  {
-    int status = 0;
-    fits_movabs_hdu(this->fptr, 1, NULL, &status);    
-    if(status) FITSError("PSRFits::gotoPHU",status);
-    return status;
-  }
- //--------------------------------------------------------------------------
-  
-  int PSRFits::gotoHistory()
-  {
-    int status = 0;
-    char name[8];
-    strcpy(name,"HISTORY");
-    fits_movnam_hdu(this->fptr, BINARY_TBL, name, 0, &status);
-    if(status) FITSError("PSRFits::gotoHistory",status);
-    return status;
-  }
- //--------------------------------------------------------------------------
-  
-  int PSRFits::deleteTable(char tableName[])
-  {
-    /** 
-     * Deletes the named binary table -- first moving to the HDU then
-     * deleting it. At completion, we have returned to the PHU.
-     */ 
-    int status = 0;
-    int newHDUtype;
-    fits_movnam_hdu(this->fptr, BINARY_TBL, tableName, 0, &status);
-    if(status) FITSError("PSRFits::deleteTable",status);
-    fits_delete_hdu(this->fptr, &newHDUtype, &status);
-    if(status) FITSError("PSRFits::deleteTable",status);
-    gotoPHU();
-    return status;
-  }
- //--------------------------------------------------------------------------
-  
-  int PSRFits::gotoSubint()
-  {
-    int status = 0;
-    char name[8];
-    strcpy(name,"SUBINT");
-    fits_movnam_hdu(this->fptr, BINARY_TBL, name, 0, &status);
-    if(status) FITSError("PSRFits::gotoSubint",status);
-    return status;
-  }
- //--------------------------------------------------------------------------
-  
-  template <typename T> int PSRFits::updateKeyword(std::string name, T value)
-  {
-  /**
-   *   Updates the keyword "name" in the current header unit, giving
-   *    it the value given by "value".
-   *   A templated function that should work for all cases.
-   */
-    int status=0;
-    fits_update_key(this->fptr, TINT, name.c_str(), &value, NULL, &status);
-    if(status) FITSError("PSRFits::updateKeyword",status);
-    return status;
-  }
-  template <> int PSRFits::updateKeyword(std::string name, int value){
-    int status=0;
-    fits_update_key(this->fptr, TINT, (char *)name.c_str(), 
-		    &value, NULL, &status);
-    if(status) FITSError("PSRFits::updateKeyword",status);
-    return status;
-  }
-  template <> int PSRFits::updateKeyword(std::string name, long value){
-    int status=0;
-    fits_update_key(this->fptr, TLONG, (char *)name.c_str(), 
-		    &value, NULL, &status);
-    if(status) FITSError("PSRFits::updateKeyword",status);
-    return status;
-  }
-  template <> int PSRFits::updateKeyword(std::string name, float value){
-    int status=0;
-    fits_update_key(this->fptr, TFLOAT, (char *)name.c_str(),
-		    &value, NULL, &status);
-    if(status) FITSError("PSRFits::updateKeyword",status);
-    return status;
-  }
-  template <> int PSRFits::updateKeyword(std::string name, double value){
-    int status=0;
-    fits_update_key(this->fptr, TDOUBLE, (char *)name.c_str(), 
-		    &value, NULL, &status);
-    if(status) FITSError("PSRFits::updateKeyword",status);
-    return status;
-  }
-  template <> int PSRFits::updateKeyword(std::string name, std::string value){
-    int status=0;
-    fits_update_key(this->fptr, TSTRING, (char *)name.c_str(), 
-		    (char *)value.c_str(), NULL, &status);
-    if(status) FITSError("PSRFits::updateKeyword",status);
-    return status;
-  }
-  template <> int PSRFits::updateKeyword(std::string name, char *value){
-    int status=0;
-    fits_update_key(this->fptr, TSTRING, (char *)name.c_str(), 
-		    value, NULL, &status);
-    if(status) FITSError("PSRFits::updateKeyword",status);
-    return status;
-  }
- //--------------------------------------------------------------------------
-  
-  template <typename T> int PSRFits::getKeyword(std::string name, T &value)
-  {
-  /**
-   *   Finds the keyword "name" in the current header unit, returning the value in the "value" parameter.
-   *   A templated function that should work for all cases.
-   *  \param name The name of the keyword.
-   *  \param value The returned value of the keyword.
-   *  \return The status value from the fits_read_keyword function.
-   */
-    int status=0;
-    char keywordValue[80], keywordComment[80];
-    fits_read_keyword(this->fptr, (char *)name.c_str(), keywordValue, 
-		      keywordComment, &status);
-    if(status) FITSError("PSRFits::getKeyword",status);
-    else{
-      std::stringstream ss;
-      ss.str(keywordValue);
-      ss >> value;
-    }
-    return status;
-  }
-  template int PSRFits::getKeyword<int>(std::string name, int &value);
-  template int PSRFits::getKeyword<long>(std::string name, long &value);
-  template int PSRFits::getKeyword<float>(std::string name, float &value);
-  template int PSRFits::getKeyword<double>(std::string name, double &value);
-  template <> int PSRFits::getKeyword<std::string>(std::string name, std::string &value){
-    int status=0;
-    char keywordValue[80], keywordComment[80];
-    fits_read_keyword(this->fptr, (char *)name.c_str(), keywordValue, 
-		      keywordComment, &status);
-    if(status) FITSError("PSRFits::getKeyword",status);
-    else value = keywordValue;
-    if(value[0]=='\'') value.erase(0,1);
-    if(value[value.size()-1]=='\'') value.erase(value.size()-1,1);
-    return status;
-  }
-    
-  
- //--------------------------------------------------------------------------
-
-  int PSRFits::getColnum(char *name)
-  {
-    int status=0,colnum=0;
-    fits_get_colnum(this->fptr, CASEINSEN, name, &colnum, &status);
-    if(status) FITSError("getColnum", status);
-    return colnum;
-  }
-  
-  long PSRFits::getNumRows()
-  {
-    int status=0;
-    long nrows=0;
-    fits_get_num_rows(this->fptr, &nrows, &status);
-    if(status) FITSError("getNumRows", status);
-    return nrows;
-  }
- //--------------------------------------------------------------------------
-  
-  template <class T> int PSRFits::writeColumnValue(char *name, T value)
-  {
-    /**
-     *   Writes a new value in the column "name" in the current binary table.
-     *   It adds a single value at the bottom of the table (ie. in the largest
-     *    numbered row).
-     *   A templated function that should work for all cases.
-     */
-    int status=0;
-    int colnum = this->getColnum(name);
-    long nrows = this->getNumRows();
-    fits_write_col(this->fptr, TINT, colnum, nrows, 1, 1, &value, &status);
-    if(status) FITSError("PSRFits::writeColumnValue", status);
-    return status;
-  }
-  template <> int PSRFits::writeColumnValue(char *name, long value)
-  {
-    int status=0;
-    int colnum = this->getColnum(name);
-    long nrows = this->getNumRows();
-    fits_write_col(this->fptr, TLONG, colnum, nrows, 1, 1, &value, &status);
-    if(status) FITSError("PSRFits::writeColumnValue", status);
-    return status;
-  }
-  template <> int PSRFits::writeColumnValue(char *name, float value)
-  {
-    int status=0;
-    int colnum = this->getColnum(name);
-    long nrows = this->getNumRows();
-    fits_write_col(this->fptr, TFLOAT, colnum, nrows, 1, 1, &value, &status);
-    if(status) FITSError("PSRFits::writeColumnValue", status);
-    return status;
-  }
-  template <> int PSRFits::writeColumnValue(char *name, double value)
-  {
-    int status=0;
-    int colnum = this->getColnum(name);
-    long nrows = this->getNumRows();
-    fits_write_col(this->fptr, TDOUBLE, colnum, nrows, 1, 1, &value, &status);
-    if(status) FITSError("PSRFits::writeColumnValue", status);
-    return status;
-  }
-  template <> int PSRFits::writeColumnValue(char *name, char *value)
-  {
-    int status=0;
-    int colnum = this->getColnum(name);
-    long nrows = this->getNumRows();
-    fits_write_col(this->fptr, TSTRING, colnum, nrows, 1, 1, &value, &status);
-    if(status) FITSError("PSRFits::writeColumnValue", status);
-    return status;
-  }
- //--------------------------------------------------------------------------
-
-  int PSRFits::startNewRow()
-  {
-    /**
-     *    Adds a new row to the bottom of the current binary table.
-     *    Also adds the row number as the ISUBINT column value.
-     */
-    int nrows = this->getNumRows();
-    int status = 0;
-    fits_insert_rows(this->fptr, nrows, 1, &status);
-    if(status) FITSError("PSRFits::startNewRow", status);
-    return status;
-  }
- //--------------------------------------------------------------------------
-
-  void PSRFits::startNewSubintRow()
-  {
-    /**
-     *    Adds a new row to the bottom of the current binary table.
-     *    Also adds the row number as the ISUBINT column value.
-     */
-    this->startNewRow();
-    this->writeColumnValue("ISUBINT", this->getNumRows());
-   }
- //--------------------------------------------------------------------------
-
 
 }
-
Index: /trunk/src/pvo-FITS.hh
===================================================================
--- /trunk/src/pvo-FITS.hh	(revision 50)
+++ /trunk/src/pvo-FITS.hh	(revision 51)
@@ -6,299 +6,298 @@
 #include "pvo-header.hh"
 
-using namespace Block;
-using namespace Header;
-
-/**
- * The namespace to control all things related to reading and writing
- * fits files in the PSRFITS format.
- */ 
-
-namespace FITS
+using namespace PVO::Block;
+using namespace PVO::Header;
+
+namespace PVO
 {
 
-  /** Has a function worked or not? */
-  enum RESULT { SUCCESS, FAILURE };
+
+  /**
+   * The namespace to control all things related to reading and writing
+   * fits files in the PSRFITS format.
+   */ 
+
+  namespace FITS
+  {
+
+    /** Has a function worked or not? */
+    enum RESULT { SUCCESS, FAILURE };
 	
-  /** The state of the file */
-  enum STATE { OPEN,  ///< file is open
-	       CLOSED ///< file is closed
-  };
-
-  /** 
-   * Report a CFITSIO error, along with the offending function.  
-   * An error message is printed, along with the relevant CFITSIO error
-   * code and message.  
-   * \param function The function from which the error was called.  
-   * \param status The status value as returned by the CFITSIO function. 
-   *  Generally, if status != 0, an error has occurred.
-   */
-  inline void FITSError(std::string function, int status){
-    //    if(FITS::verbose){
-    std::cerr << "\aFITSError <" << function << "> (status="<<status<<"): ";
-    fits_report_error(stderr, status);
+    /** The state of the file */
+    enum STATE { OPEN,  ///< file is open
+		 CLOSED ///< file is closed
+    };
+
+
+
+    //===========================================================
+
+    /**
+     *  A class to keep track of the header keywords for the SUBINT
+     *  binary table extension.
+     */
+    class Subint
+    {
+    public:
+
+
+      Subint(){
+	allocated = false;
+	nch_strt = 0;
+	int_type = "TIME";
+	int_unit = "SEC";
+      };
+      virtual ~Subint(){
+	if(allocated){
+	  delete [] dat_freq;
+	  delete [] dat_wts;
+	  delete [] dat_offs;
+	  delete [] dat_scl;
+	}
+      };
+
+      friend class PSRFits;
+
+      long   getNch_file(){return nch_file;};
+      void   setNch_file(long l){nch_file=l;};
+      long   getNch_strt(){return nch_strt;};
+      void   setNch_strt(long l){nch_strt=l;};
+      long   getNbits(){return nbits;};
+      void   setNbits(long l){nbits=l;};
+      long   getNbin(){return nbin;};
+      void   setNbin(long l){nbin=l;};
+      long   getNpol(){return npol;};
+      void   setNpol(long l){npol=l;};
+      long   getNsblk(){return nsblk;};
+      void   setNsblk(long l){nsblk=l;};
+      float  getTsamp(){return tsamp;};
+      void   setTsamp(float f){tsamp=f;};
+      std::string getInt_type(){return int_type;};
+      void   setInt_type(std::string s){int_type=s;};
+      std::string getInt_unit(){return int_unit;};
+      void   setInt_unit(std::string s){int_unit=s;};
+      bool   getAllocatedFlag(){return allocated;};
+      void   setAllocatedFlag(bool b){allocated=b;};
+
+      float *getDAT_freq(){return dat_freq;};
+      void   setDAT_freq(float *f){dat_freq=f;};
+      float *getDAT_wts(){return dat_wts;};
+      void   setDAT_wts(float *f){dat_wts=f;};
+      float *getDAT_offs(){return dat_offs;};
+      void   setDAT_offs(float *f){dat_offs=f;};
+      float *getDAT_scl(){return dat_scl;};
+      void   setDAT_scl(float *f){dat_scl=f;};
+
+      /** Return the size of the data array */
+      long   getDataSize(){return nbits*nch_file*npol*nsblk;};
+
+      /** Return the size of the data array in bytes */
+      long   getDataSizeBytes(){return nbits*nch_file*npol*nsblk / 8;};
+
+      /** A function that will write to a file the full set of keywords. */
+      int    writeKeywords(fitsfile *fptr);
+ 
+    private:
+      long        nbin;       ///< The SUBINT table keyword NBIN
+      long        nbits;      ///< The SUBINT table keyword NBITS
+      long        nch_strt;   ///< The SUBINT table keyword NCH_STRT
+      long        nch_file;   ///< The SUBINT table keyword NCH_FILE
+      long        npol;	    ///< The SUBINT table keyword NPOL
+      long        nsblk;	    ///< The SUBINT table keyword NSBLK
+      std::string int_type;   ///< The SUBINT table keyword INT_TYPE
+      std::string int_unit;   ///< The SUBINT table keyword INT_UNIT
+      float       tsamp;	    ///< The SUBINT table keyword TSAMP
+
+      bool        allocated;  ///< Have the arrays been allocated yet?
+      float      *dat_freq;   ///< The SUBINT table array DAT_FREQ
+      float      *dat_wts;    ///< The SUBINT table array DAT_WTS
+      float      *dat_offs;   ///< The SUBINT table array DAT_OFFS
+      float      *dat_scl;    ///< The SUBINT table array DAT_SCL
+
+
+    };
+
+  
+    const int SUBINT_kw_nch_strt = 0; 
+    ///< The nch_strt keyword for the SUBINT table.
+
+    const std::string SUBINT_kw_int_type = "TIME";
+    ///< The int_type keyword for the SUBINT table.
+
+    const std::string SUBINT_kw_int_unit = "SEC"; 
+    ///< The int_unit keyword for the SUBINT table.
+  
+    const std::string PHU_kw_coord_md = "J2000.0"; 
+    ///< The coord_md keyword for the Primary header.
+
+    const double PHU_stt_offs_default = 0.;
+    ///< The default value for the STT_OFFS PHU keyword. */
+  
+    /**
+     * A class to deal with individual fits files.
+     * This keeps track of all information relevant for a particular PSRFITS file.
+     * All the functions that write to particular extensions are in here, as 
+     *  well as general I/O routines.
+     */ 
+
+    class PSRFits
+    {
+    public:
+      PSRFits(); ///<
+      PSRFits(std::string name);
+      virtual ~PSRFits(){};
+
+      // Inline functions
+      /** Is the file newly created? */
+      bool        isNewFile(){return newFile;};
+      void        setNewFile(){newFile = true;};
+      void        setNewFile(bool f){newFile = f;};
+
+      /** Is the file open or closed? */
+      STATE       getFilestate(){return filestate;};
+
+      /** Set the file state. */
+      void        setFilestate(STATE S){filestate=S;};
+
+      /** Get the UT of the first observations in the file. */
+      std::string getUT(){return UT_initial;};
+
+      /** Save the UT of the first observations. */
+      void        setUT(std::string s){UT_initial=s;};
+
+      /** Get the date of the first observations in the file. */
+      std::string getDate(){return DATE_initial;};
+
+      /** Save the date of the first observations. */
+      void        setDate(std::string s){DATE_initial=s;};
+
+      /** Get the beam number used for the observations. */
+      int         getBeam(){return beam_number;};
+
+      /** Save the beam number used for the observations. */
+      void        setBeam(int i){beam_number=i;};
+
+      /** Get the filename of the fits file. */
+      std::string getFITSname(){return FITSname;};
+
+      /** Manually set the filename of the fits file. */
+      void        setFITSname(std::string name){FITSname = name;};
+
+      /** Get the number of the first block stored in the file. */
+      int         getInitialBlock(){return blk_initial;};
+
+      /** Save the number of the first block stored in the file. */
+      void        setInitialBlock(int block){blk_initial = block;};
+
+      /** Opens file -- uses openFile(std::string) */
+      int         openFile(){ return this->openFile(this->FITSname); };
+
+
+      // Functions found in PSRFits.cc (in the same order...)
+      /** Generate the name of the fits file. */
+      void        setFITSname(Header::SURVEY surveyType); 
+
+      /** Does the file exist on disk already? */
+      bool        fileExists();                           
+       
+      /** Opens the file named by the argument. */
+      int         openFile(std::string name);              
+       
+      /** Makes corrections to PSRFITS definition. */
+      void        fixPSRFITS();  
+       
+      /** Writes new keywords to the primary fits header. */
+      void        addNewKeywords(DataBlock &block); 
+    
+      /** Check whether the FITS file should be closed. */
+      bool        fitsFull(DataBlock &block);
+      long        getNumSamples(){return numSamples;};
+
+      int         closeFile();   ///< Closes the file.
+      int         gotoPHU();     ///< Moves to the primary header unit
+      int         gotoHistory(); ///< Moves to the HISTORY binary table
+      ///   extension.
+      int         gotoSubint();  ///< Moves to the SUBINT binary table
+      ///   extension.
+
+      /** Delete a named binary table. */
+      int         deleteTable(char tableName[]);
+
+      /** Update the value of a keyword. */
+      template <class T> int updateKeyword(std::string name, T value); 
+
+      /** Return the value of a keyword. */
+      template <class T> int getKeyword(std::string name, T &value); 
+
+      /** Returns the number of the named column. */
+      int         getColnum(char *name);
+       
+      /** Returns the number of rows in the current binary table. */
+      long        getNumRows();          
+
+      /** Write a value to a named column. */
+      template <class T> int writeColumnValue(char *name, T value);
+
+      /** Add new row to current table. */
+      int         startNewRow();         
+
+      /** Add new row to SUBINT table. */
+      void        startNewSubintRow();   
+
+      /** Write Primary Header Unit data. */
+      void        writePHU(DataBlock &block);      
+
+      /** Set up a FITS file */       
+      int         initialise(DataBlock &block);
+
+      /** Define and write the header keywords for the SUBINT table. */
+      void        setupSubint(DataBlock &block);
+
+      /** Write a row of SUBINT table data. */
+      void        writeSubintRow(DataBlock &block);          
+
+      /** Write information to HISTORY table. */
+      //     void        writeHistoryCommand(int argc, char * argv[]);
+      void        writeHistoryCommand();
+      void        writeHistoryTapeFile();
+
+      /** Dealing with the command line arguments */
+      void        setCommandLine(int argc, char *argv[]);
+
+      /** Storing the name of the old-format data file */
+      void        setOldFilename(std::string filename){oldFilename = filename;};
+      /** Report a CFITSIO error, along with the offending function. */
+      void FITSError(std::string function, int status);
+
+      /** Set the verbose flag */
+      void setVerbosity(bool b){verbose=b;};
+
+    private:
+      fitsfile *fptr;           ///< The CFITSIO file variable
+      std::string FITSname;     ///< The output FITS filename
+      bool newFile;             ///< Is the file a new one?
+      STATE filestate;          ///< OPEN or CLOSED?
+      std::string UT_initial;   ///< The UT at the start of the FITS
+      ///   file data.
+      std::string DATE_initial; ///< The UT date at the start of the
+      ///   data.
+      int beam_number;          ///< What beam are we using? Necessary
+      ///   for FITS file name
+      int blk_initial;          ///< The block number of the first block
+      ///   in the file.
+      long numSamples;          ///< The number of samples stored in the
+      ///   FITS file.
+      Subint subintTable;       ///< Subint class containing table
+      ///   header keywords.
+
+      std::string oldFilename;  ///< The filename of the old-format data.
+      std::string commandLine;  ///< The full command-line statement.
+
+      bool verbose;             ///< Whether to print all error messages.
+
+    };
+
   }
 
-
-  //===========================================================
-
-  /**
-   *  A class to keep track of the header keywords for the SUBINT
-   *  binary table extension.
-   */
-  class Subint
-  {
-  public:
-
-
-    Subint(){
-      allocated = false;
-      nch_strt = 0;
-      int_type = "TIME";
-      int_unit = "SEC";
-    };
-    virtual ~Subint(){
-      if(allocated){
-	delete [] dat_freq;
-	delete [] dat_wts;
-	delete [] dat_offs;
-	delete [] dat_scl;
-      }
-    };
-
-    friend class PSRFits;
-
-    long   getNch_file(){return nch_file;};
-    void   setNch_file(long l){nch_file=l;};
-    long   getNch_strt(){return nch_strt;};
-    void   setNch_strt(long l){nch_strt=l;};
-    long   getNbits(){return nbits;};
-    void   setNbits(long l){nbits=l;};
-    long   getNbin(){return nbin;};
-    void   setNbin(long l){nbin=l;};
-    long   getNpol(){return npol;};
-    void   setNpol(long l){npol=l;};
-    long   getNsblk(){return nsblk;};
-    void   setNsblk(long l){nsblk=l;};
-    float  getTsamp(){return tsamp;};
-    void   setTsamp(float f){tsamp=f;};
-    std::string getInt_type(){return int_type;};
-    void   setInt_type(std::string s){int_type=s;};
-    std::string getInt_unit(){return int_unit;};
-    void   setInt_unit(std::string s){int_unit=s;};
-    bool   getAllocatedFlag(){return allocated;};
-    void   setAllocatedFlag(bool b){allocated=b;};
-
-    float *getDAT_freq(){return dat_freq;};
-    void   setDAT_freq(float *f){dat_freq=f;};
-    float *getDAT_wts(){return dat_wts;};
-    void   setDAT_wts(float *f){dat_wts=f;};
-    float *getDAT_offs(){return dat_offs;};
-    void   setDAT_offs(float *f){dat_offs=f;};
-    float *getDAT_scl(){return dat_scl;};
-    void   setDAT_scl(float *f){dat_scl=f;};
-
-    /** Return the size of the data array */
-    long   getDataSize(){return nbits*nch_file*npol*nsblk;};
-
-    /** Return the size of the data array in bytes */
-    long   getDataSizeBytes(){return nbits*nch_file*npol*nsblk / 8;};
-
-    /** A function that will write to a file the full set of keywords. */
-    void writeKeywords(fitsfile *fptr);
- 
-  private:
-    long        nbin;       ///< The SUBINT table keyword NBIN
-    long        nbits;      ///< The SUBINT table keyword NBITS
-    long        nch_strt;   ///< The SUBINT table keyword NCH_STRT
-    long        nch_file;   ///< The SUBINT table keyword NCH_FILE
-    long        npol;	    ///< The SUBINT table keyword NPOL
-    long        nsblk;	    ///< The SUBINT table keyword NSBLK
-    std::string int_type;   ///< The SUBINT table keyword INT_TYPE
-    std::string int_unit;   ///< The SUBINT table keyword INT_UNIT
-    float       tsamp;	    ///< The SUBINT table keyword TSAMP
-
-    bool        allocated;  ///< Have the arrays been allocated yet?
-    float      *dat_freq;   ///< The SUBINT table array DAT_FREQ
-    float      *dat_wts;    ///< The SUBINT table array DAT_WTS
-    float      *dat_offs;   ///< The SUBINT table array DAT_OFFS
-    float      *dat_scl;    ///< The SUBINT table array DAT_SCL
-
-
-  };
-
-  
-  const int SUBINT_kw_nch_strt = 0; 
-  ///< The nch_strt keyword for the SUBINT table.
-
-  const std::string SUBINT_kw_int_type = "TIME";
-  ///< The int_type keyword for the SUBINT table.
-
-  const std::string SUBINT_kw_int_unit = "SEC"; 
-  ///< The int_unit keyword for the SUBINT table.
-  
-  const std::string PHU_kw_coord_md = "J2000.0"; 
-  ///< The coord_md keyword for the Primary header.
-
-  const double PHU_stt_offs_default = 0.;
-  ///< The default value for the STT_OFFS PHU keyword. */
-  
-  /**
-   * A class to deal with individual fits files.
-   * This keeps track of all information relevant for a particular PSRFITS file.
-   * All the functions that write to particular extensions are in here, as 
-   *  well as general I/O routines.
-   */ 
-
-  class PSRFits
-  {
-  public:
-    PSRFits(); ///<
-    PSRFits(std::string name);
-    virtual ~PSRFits(){};
-
-    // Inline functions
-    /** Is the file newly created? */
-    bool        isNewFile(){return newFile;};
-    void        setNewFile(){newFile = true;};
-    void        setNewFile(bool f){newFile = f;};
-
-    /** Is the file open or closed? */
-    STATE       getFilestate(){return filestate;};
-
-    /** Set the file state. */
-    void        setFilestate(STATE S){filestate=S;};
-
-    /** Get the UT of the first observations in the file. */
-    std::string getUT(){return UT_initial;};
-
-    /** Save the UT of the first observations. */
-    void        setUT(std::string s){UT_initial=s;};
-
-    /** Get the date of the first observations in the file. */
-    std::string getDate(){return DATE_initial;};
-
-    /** Save the date of the first observations. */
-    void        setDate(std::string s){DATE_initial=s;};
-
-    /** Get the beam number used for the observations. */
-    int         getBeam(){return beam_number;};
-
-    /** Save the beam number used for the observations. */
-    void        setBeam(int i){beam_number=i;};
-
-    /** Get the filename of the fits file. */
-    std::string getFITSname(){return FITSname;};
-
-    /** Manually set the filename of the fits file. */
-    void        setFITSname(std::string name){FITSname = name;};
-
-    /** Get the number of the first block stored in the file. */
-    int         getInitialBlock(){return blk_initial;};
-
-    /** Save the number of the first block stored in the file. */
-    void        setInitialBlock(int block){blk_initial = block;};
-
-    /** Opens file -- uses openFile(std::string) */
-    int         openFile(){ return this->openFile(this->FITSname); };
-
-
-    // Functions found in PSRFits.cc (in the same order...)
-    /** Generate the name of the fits file. */
-    void        setFITSname(Header::SURVEY surveyType); 
-
-    /** Does the file exist on disk already? */
-    bool        fileExists();                           
-       
-    /** Opens the file named by the argument. */
-    int         openFile(std::string name);              
-       
-    /** Makes corrections to PSRFITS definition. */
-    void        fixPSRFITS();  
-       
-    /** Writes new keywords to the primary fits header. */
-    void        addNewKeywords(DataBlock &block); 
-    
-    /** Check whether the FITS file should be closed. */
-    bool        fitsFull(DataBlock &block);
-    long        getNumSamples(){return numSamples;};
-
-    int         closeFile();   ///< Closes the file.
-    int         gotoPHU();     ///< Moves to the primary header unit
-    int         gotoHistory(); ///< Moves to the HISTORY binary table
-			       ///   extension.
-    int         gotoSubint();  ///< Moves to the SUBINT binary table
-			       ///   extension.
-
-    /** Delete a named binary table. */
-    int         deleteTable(char tableName[]);
-
-    /** Update the value of a keyword. */
-    template <class T> int updateKeyword(std::string name, T value); 
-
-    /** Return the value of a keyword. */
-    template <class T> int getKeyword(std::string name, T &value); 
-
-    /** Returns the number of the named column. */
-    int         getColnum(char *name);
-       
-    /** Returns the number of rows in the current binary table. */
-    long        getNumRows();          
-
-    /** Write a value to a named column. */
-    template <class T> int writeColumnValue(char *name, T value);
-
-    /** Add new row to current table. */
-    int         startNewRow();         
-
-    /** Add new row to SUBINT table. */
-    void        startNewSubintRow();   
-
-    /** Write Primary Header Unit data. */
-    void        writePHU(DataBlock &block);      
-
-    /** Set up a FITS file */       
-    int         initialise(DataBlock &block);
-
-    /** Define and write the header keywords for the SUBINT table. */
-    void        setupSubint(DataBlock &block);
-
-    /** Write a row of SUBINT table data. */
-    void        writeSubintRow(DataBlock &block);          
-
-    /** Write information to HISTORY table. */
-//     void        writeHistoryCommand(int argc, char * argv[]);
-    void        writeHistoryCommand();
-    void        writeHistoryTapeFile();
-
-    /** Dealing with the command line arguments */
-    void        setCommandLine(int argc, char *argv[]);
-
-    /** Storing the name of the old-format data file */
-    void        setOldFilename(std::string filename){oldFilename = filename;};
-
-
-  private:
-    fitsfile *fptr;           ///< The CFITSIO file variable
-    std::string FITSname;     ///< The output FITS filename
-    bool newFile;             ///< Is the file a new one?
-    STATE filestate;          ///< OPEN or CLOSED?
-    std::string UT_initial;   ///< The UT at the start of the FITS
-			      ///   file data.
-    std::string DATE_initial; ///< The UT date at the start of the
-			      ///   data.
-    int beam_number;          ///< What beam are we using? Necessary
-			      ///   for FITS file name
-    int blk_initial;          ///< The block number of the first block
-			      ///   in the file.
-    long numSamples;          ///< The number of samples stored in the
-			      ///   FITS file.
-    Subint subintTable;       ///< Subint class containing table
-			      ///   header keywords.
-
-    std::string oldFilename;  ///< The filename of the old-format data.
-    std::string commandLine;  ///< The full command-line statement.
-
-  };
-
 }
 
Index: /trunk/src/pvo-block.cc
===================================================================
--- /trunk/src/pvo-block.cc	(revision 50)
+++ /trunk/src/pvo-block.cc	(revision 51)
@@ -1,3 +1,2 @@
-#include "pvo.hh"
 #include "pvo-header.hh"
 #include "pvo-block.hh"
@@ -11,305 +10,309 @@
 
 using std::string;
-using namespace Header;
+using namespace PVO::Header;
  
-namespace Block
+namespace PVO
 {
 
-  DataBlock::DataBlock(SURVEY inputSurveyType)
+  namespace Block
   {
-    /**
-     * Initialise a block, by allocating the various arrays 
-     *
-     */
-    this->headerString = string(" ",headerLength);
-    Header::SurveySchema *temp = new Header::SurveySchema(inputSurveyType);
-    this->survey = *temp;
-    this->surveyType = inputSurveyType;
-    this->data = new char[dataLength];
-//     this->surveyName = survey;
-    delete temp;
+
+    DataBlock::DataBlock(SURVEY inputSurveyType)
+    {
+      /**
+       * Initialise a block, by allocating the various arrays 
+       *
+       */
+      this->headerString = string(" ",headerLength);
+      Header::SurveySchema *temp = new Header::SurveySchema(inputSurveyType);
+      this->survey = *temp;
+      this->surveyType = inputSurveyType;
+      this->data = new char[dataLength];
+      //     this->surveyName = survey;
+      delete temp;
+    }
+    //-----------------------------------------------------------------------
+
+    DataBlock::~DataBlock()
+    {
+      /** Deallocate survey and data first. */
+      delete [] this->data;
+    }
+    //-----------------------------------------------------------------------
+
+    bool DataBlock::readBlock(std::ifstream &file)
+    {
+      /**
+       * Front end to the other two read functions.
+       * \param file The file stream to read the block from.
+       * \return False if readHeader() does not work. Otherwise true.
+       */
+      if(!this->readHeader(file)) return false;
+      this->readData(file);
+      return true;
+    }
+    //--------------------------------------------------------------------------
+
+    bool DataBlock::readHeader(std::ifstream &file)
+    {
+      /**
+       * Read in the full set of header information into the headerString string.
+       * \param file The file stream to read the block from.
+       * \return False if the file is at eof, else read header and return true.
+       */
+      char *hdr = new char[Block::headerLength];
+      file.read( hdr, headerLength*sizeof(char) );
+      bool returnval = true;;
+      if(file.eof()) returnval = false;
+      for(int c=0;c<headerLength;c++) this->headerString[c] = hdr[c];
+      delete [] hdr;
+      return returnval;
+    }
+    //--------------------------------------------------------------------------
+
+    void DataBlock::readData(std::ifstream &file)
+    {
+      /**
+       * Read in the full set of data into the data array (as type char).
+       * \param file The file stream to read the block from.
+       * \return No return value, as the file is assumed to be open.
+       */
+      file.read( this->data, dataLength*sizeof(char) );
+    }
+    //--------------------------------------------------------------------------
+
+    void DataBlock::saveData(char *dataArray, int size)
+    {
+      /**
+       * Saves an array of char values to the data array
+       * \param dataArray The array of bytes to be saved.
+       * \param size The size of dataArray. If less than
+       * Block::dataLength, all elements will be written, but if more,
+       * only Block::dataLength elements will be written
+       * \return No return value.
+       */
+
+      int max = size;
+      if(size>Block::dataLength) max = Block::dataLength;
+      for(int i=0;i<max;i++) this->data[i] = dataArray[i];
+    
+    }
+    //--------------------------------------------------------------------------
+
+    std::string DataBlock::getEquinox()
+    {
+      /**
+       * Returns the value of the equinox, assuming the coordinate type
+       * is equatorial. If we are using Galactic or Ecliptic, a blank
+       * string is returned.
+       *\return A std::string containing the equinox value.
+       */
+      int type = this->getKeyword<int>(COORD_TYPE);
+      std::string output;
+      switch(type){
+      case 2: output = "";               break;
+      case 3: output = Block::eq_b1950;  break;
+      case 4: output = "";               break;
+      case 5:
+      default: output = Block::eq_j2000; break;
+      }
+      return output;
+    }
+    //--------------------------------------------------------------------------
+
+    std::string DataBlock::getCoordMode()
+    {
+      /**
+       * Returns the value of the coord_md keyword as one of a number of
+       * alternative strings. This keyword should be one of EQUAT, GAL,
+       * ECLIP, etc. If the equinox is B1950 or J2000, return EQUAT.
+       * \return A coord type: one of EQUAT, GAL, ECLIP...
+       */
+      int type = this->getKeyword<int>(COORD_TYPE);
+      std::string output;
+      switch(type){
+      case 2: output = Block::eq_date;   break;
+      case 3: output = Block::eq_equat;  break;
+      case 4: output = Block::eq_gal;    break;
+      case 5:
+      default: output = Block::eq_equat; break;
+      }
+      return output;
+    }
+    //--------------------------------------------------------------------------
+
+    bool DataBlock::telescopeOK()
+    {
+      /**
+       * A way of determining whether the current block was taken at a time
+       *  when the telescope was suitably positioned.
+       *
+       * The function tests the MOVE keyword (which is a coded integer),
+       * and translates it according to the survey being conducted. There are
+       * particular values of the keyword that are acceptable for each survey,
+       * and if the keyword takes this value, everything is OK. Otherwise, the
+       * telescope may have been moving, or not in survey mode.
+       * \return True if everything is OK, false otherwise.
+       */
+      std::string move=this->getKeyword<std::string>(MOVE);
+
+      if(this->surveyType == S70){
+	if(move == "02") return false;
+	else return true;
+      }
+      else if((this->surveyType == PM)||(this->surveyType == PH)){
+	if(move[1]=='0') return true;
+	else return false;
+      }
+      return false;
+    }
+    //--------------------------------------------------------------------------
+
+    std::string DataBlock::getFITSname()
+    {
+      /**
+       * Generates a string containing the name of the FITS file that the block
+       * data should be written to. This depends on the survey, the date & time,
+       * and (if the multibeam receiver was used) the beam number:
+       * <ul> <li> S70_yymmdd_hhmmss.fits
+       *      <li> PM_yymmdd_hhmmss_bb.fits </ul>
+       * \return String containing the FITS filename.
+       */
+      std::string date = this->getKeyword<std::string>(DATE);
+      std::string newdate;
+
+      for(unsigned int i=0;i<date.size();i++)
+	if(date[i]!='/') newdate += date[i];
+
+      std::string time = this->getKeyword<std::string>(UT_STRT);
+      time = removeLeadingBlanks(time);
+      time = decToDMS( dmsToDec(time), 0, "");
+    
+      std::stringstream output;
+      if(this->surveyType == S70) output << "S70_";
+      else if(this->surveyType == PM) output << "PM_";
+      else if(this->surveyType == PH) output << "PH_";
+      else std::cerr << "Error <DataBlock::getFITSname> : unknown survey!\n";
+
+      output << newdate << "_" << time;
+
+      if((this->surveyType == PM)||(this->surveyType == PH))
+	output << "_" 
+	       << std::setw(2) << std::setfill('0') 
+	       << this->getKeyword<int>(IBEAM);
+
+      output << ".fits";
+
+      return output.str();
+
+    }
+    //--------------------------------------------------------------------------
+    //   template <typename Type> 
+    //   Type DataBlock::getKeyword(int field, int element)
+    //   {
+    //     Type output = 
+    //       this->survey.readParameter<Type>(this->headerString,field,element);
+    //     return output;
+    //   }
+    //   template int DataBlock::getKeyword<int>(int field, int element);
+    //   template float DataBlock::getKeyword<float>(int field, int element);
+    //   template string DataBlock::getKeyword<string>(int field, int element);
+    //--------------------------------------------------------------------------
+
+    template <class T> 
+    T DataBlock::getKeyword(int field, int elementNumber)
+    {
+      /**
+       * Returns the value of the keyword. In the case of keywords that have more
+       * than one value (some have 2 values, one for each band, and some have up 
+       * to 8, describing individual comments etc), one can select which element
+       * to return. This choice defaults to the first one if not given.
+       *
+       * The function is templated, so that you can elect to get the
+       * numerical value or the string representation of the keyword.
+       *
+       * \param field The number representing the keyword field. This can be
+       * represented by the enumerated list of values given by Header::FIELDS.
+       * \param elementNumber Optional parameter indicating which element of a
+       * multi-dimensional keyword to return. Defaults to 0, which is the first
+       * element.
+       */
+      int dim = this->survey.getFieldDimension(field);
+      std::stringstream ss;
+      std::vector<T> output(dim);
+      for(int i=0;i<dim;i++){
+	int start = this->survey.getStartPosition(field)+i*dim;
+	int length = this->survey.getFieldLength(field);
+	ss.str(this->headerString.substr(start,length));
+	ss >> output[i];      
+      }
+      return output[elementNumber];
+    }
+    template int DataBlock::getKeyword<int>(int field, int elementNumber);
+    template float DataBlock::getKeyword<float>(int field, int elementNumber);
+    template double DataBlock::getKeyword<double>(int field, int elementNumber);
+    template std::string DataBlock::getKeyword<std::string>(int field, int elementNumber);
+  
+    //   template<> int DataBlock::getKeyword<int>(int field, int element){
+    //     return this->survey.readParameter<int>(this->headerString,field,element);
+    //   }
+    //   template<> float DataBlock::getKeyword<float>(int field, int element){
+    //     return this->survey.readParameter<float>(this->headerString,field,element);
+    //   }
+    //   template<> double DataBlock::getKeyword<double>(int field, int element){
+    //     return this->survey.readParameter<double>(this->headerString,field,element);
+    //   }
+    //   template<> string DataBlock::getKeyword<string>(int field, int element){
+    //    return this->survey.readParameter<string>(this->headerString,field,element);
+    //   }
+    //--------------------------------------------------------------------------
+    template <class T> 
+    std::vector<T> DataBlock::getFullKeyword(int field)
+    {
+      /**
+       * Returns the full list of values of the keyword, in a vector of
+       * the relevant (or requested) type. This function is useful to
+       * obtain all values for the case of keywords that have more than
+       * one value (some have 2 values, one for each band, and some have
+       * up to 8, describing individual comments etc).
+       *
+       * The function is templated, so that you can elect to get the
+       * numerical values or the string representations of individual
+       * values of the keyword.
+       *
+       * \param field The number representing the keyword field. This can be
+       * represented by the enumerated list of values given by Header::FIELDS.
+       */
+      int dim = this->survey.getFieldDimension(field);
+      std::stringstream ss;
+      std::vector<T> output(dim);
+      for(int i=0;i<dim;i++){
+	int start = this->survey.getStartPosition(field)+i*dim;
+	int length = this->survey.getFieldLength(field);
+	ss.str(this->headerString.substr(start,length));
+	ss >> output[i];      
+      }
+      return output;
+    }
+    template<> std::vector<int> DataBlock::getFullKeyword<int>(int field){
+      std::vector<int> output(this->survey.getFieldDimension(field));
+      for(int i=0;i<this->survey.getFieldDimension(field);i++)
+	output[i]=this->survey.readParameter<int>(this->headerString,field,i);
+      return output;
+    }
+    template<> std::vector<float> DataBlock::getFullKeyword<float>(int field){
+      std::vector<float> output(this->survey.getFieldDimension(field));
+      for(int i=0;i<this->survey.getFieldDimension(field);i++)
+	output[i]= this->survey.readParameter<float>(this->headerString,field,i);
+      return output;
+    }
+    template<> std::vector<string> DataBlock::getFullKeyword<string>(int field){
+      std::vector<string> output(this->survey.getFieldDimension(field));
+      for(int i=0;i<this->survey.getFieldDimension(field);i++)
+	output[i]=this->survey.readParameter<string>(this->headerString,field,i);
+      return output;
+    }
+
   }
-  //--------------------------------------------------------------------------
-
-  DataBlock::~DataBlock()
-  {
-    /** Deallocate survey and data first. */
-    delete [] this->data;
-  }
-  //--------------------------------------------------------------------------
-
-  bool DataBlock::readBlock(std::ifstream &file)
-  {
-    /**
-     * Front end to the other two read functions.
-     * \param file The file stream to read the block from.
-     * \return False if readHeader() does not work. Otherwise true.
-     */
-    if(!this->readHeader(file)) return false;
-    this->readData(file);
-    return true;
-  }
-  //--------------------------------------------------------------------------
-
-  bool DataBlock::readHeader(std::ifstream &file)
-  {
-    /**
-     * Read in the full set of header information into the headerString string.
-     * \param file The file stream to read the block from.
-     * \return False if the file is at eof, else read header and return true.
-     */
-    char *hdr = new char[Block::headerLength];
-    file.read( hdr, headerLength*sizeof(char) );
-    bool returnval = true;;
-    if(file.eof()) returnval = false;
-    for(int c=0;c<headerLength;c++) this->headerString[c] = hdr[c];
-    delete [] hdr;
-    return returnval;
-  }
-  //--------------------------------------------------------------------------
-
-  void DataBlock::readData(std::ifstream &file)
-  {
-    /**
-     * Read in the full set of data into the data array (as type char).
-     * \param file The file stream to read the block from.
-     * \return No return value, as the file is assumed to be open.
-     */
-    file.read( this->data, dataLength*sizeof(char) );
-  }
-  //--------------------------------------------------------------------------
-
-  void DataBlock::saveData(char *dataArray, int size)
-  {
-    /**
-     * Saves an array of char values to the data array
-     * \param dataArray The array of bytes to be saved.
-     * \param size The size of dataArray. If less than
-     * Block::dataLength, all elements will be written, but if more,
-     * only Block::dataLength elements will be written
-     * \return No return value.
-     */
-
-    int max = size;
-    if(size>Block::dataLength) max = Block::dataLength;
-    for(int i=0;i<max;i++) this->data[i] = dataArray[i];
-    
-  }
-  //--------------------------------------------------------------------------
-
-  std::string DataBlock::getEquinox()
-  {
-    /**
-     * Returns the value of the equinox, assuming the coordinate type
-     * is equatorial. If we are using Galactic or Ecliptic, a blank
-     * string is returned.
-     *\return A std::string containing the equinox value.
-     */
-    int type = this->getKeyword<int>(COORD_TYPE);
-    std::string output;
-    switch(type){
-    case 2: output = "";               break;
-    case 3: output = Block::eq_b1950;  break;
-    case 4: output = "";               break;
-    case 5:
-    default: output = Block::eq_j2000; break;
-    }
-    return output;
-  }
-  //--------------------------------------------------------------------------
-
-  std::string DataBlock::getCoordMode()
-  {
-    /**
-     * Returns the value of the coord_md keyword as one of a number of
-     * alternative strings. This keyword should be one of EQUAT, GAL,
-     * ECLIP, etc. If the equinox is B1950 or J2000, return EQUAT.
-     * \return A coord type: one of EQUAT, GAL, ECLIP...
-     */
-    int type = this->getKeyword<int>(COORD_TYPE);
-    std::string output;
-    switch(type){
-    case 2: output = Block::eq_date;   break;
-    case 3: output = Block::eq_equat;  break;
-    case 4: output = Block::eq_gal;    break;
-    case 5:
-    default: output = Block::eq_equat; break;
-    }
-    return output;
-  }
-  //--------------------------------------------------------------------------
-
-  bool DataBlock::telescopeOK()
-  {
-    /**
-     * A way of determining whether the current block was taken at a time
-     *  when the telescope was suitably positioned.
-     *
-     * The function tests the MOVE keyword (which is a coded integer),
-     * and translates it according to the survey being conducted. There are
-     * particular values of the keyword that are acceptable for each survey,
-     * and if the keyword takes this value, everything is OK. Otherwise, the
-     * telescope may have been moving, or not in survey mode.
-     * \return True if everything is OK, false otherwise.
-     */
-    std::string move=this->getKeyword<std::string>(MOVE);
-
-    if(this->surveyType == S70){
-      if(move == "02") return false;
-      else return true;
-    }
-    else if((this->surveyType == PM)||(this->surveyType == PH)){
-      if(move[1]=='0') return true;
-      else return false;
-    }
-    return false;
-  }
-  //--------------------------------------------------------------------------
-
-  std::string DataBlock::getFITSname()
-  {
-    /**
-     * Generates a string containing the name of the FITS file that the block
-     * data should be written to. This depends on the survey, the date & time,
-     * and (if the multibeam receiver was used) the beam number:
-     * <ul> <li> S70_yymmdd_hhmmss.fits
-     *      <li> PM_yymmdd_hhmmss_bb.fits </ul>
-     * \return String containing the FITS filename.
-     */
-    std::string date = this->getKeyword<std::string>(DATE);
-    std::string newdate;
-
-    for(unsigned int i=0;i<date.size();i++)
-      if(date[i]!='/') newdate += date[i];
-
-    std::string time = this->getKeyword<std::string>(UT_STRT);
-    time = removeLeadingBlanks(time);
-    time = decToDMS( dmsToDec(time), 0, "");
-    
-    std::stringstream output;
-    if(this->surveyType == S70) output << "S70_";
-    else if(this->surveyType == PM) output << "PM_";
-    else if(this->surveyType == PH) output << "PH_";
-    else std::cerr << "Error <DataBlock::getFITSname> : unknown survey!\n";
-
-    output << newdate << "_" << time;
-
-    if((this->surveyType == PM)||(this->surveyType == PH))
-      output << "_" 
-	     << std::setw(2) << std::setfill('0') 
-	     << this->getKeyword<int>(IBEAM);
-
-    output << ".fits";
-
-    return output.str();
-
-  }
-  //--------------------------------------------------------------------------
-//   template <typename Type> 
-//   Type DataBlock::getKeyword(int field, int element)
-//   {
-//     Type output = 
-//       this->survey.readParameter<Type>(this->headerString,field,element);
-//     return output;
-//   }
-//   template int DataBlock::getKeyword<int>(int field, int element);
-//   template float DataBlock::getKeyword<float>(int field, int element);
-//   template string DataBlock::getKeyword<string>(int field, int element);
-  //--------------------------------------------------------------------------
-
-  template <class T> 
-  T DataBlock::getKeyword(int field, int elementNumber)
-  {
-    /**
-     * Returns the value of the keyword. In the case of keywords that have more
-     * than one value (some have 2 values, one for each band, and some have up 
-     * to 8, describing individual comments etc), one can select which element
-     * to return. This choice defaults to the first one if not given.
-     *
-     * The function is templated, so that you can elect to get the
-     * numerical value or the string representation of the keyword.
-     *
-     * \param field The number representing the keyword field. This can be
-     * represented by the enumerated list of values given by Header::FIELDS.
-     * \param elementNumber Optional parameter indicating which element of a
-     * multi-dimensional keyword to return. Defaults to 0, which is the first
-     * element.
-     */
-    int dim = this->survey.getFieldDimension(field);
-    std::stringstream ss;
-    std::vector<T> output(dim);
-    for(int i=0;i<dim;i++){
-      int start = this->survey.getStartPosition(field)+i*dim;
-      int length = this->survey.getFieldLength(field);
-      ss.str(this->headerString.substr(start,length));
-      ss >> output[i];      
-    }
-    return output[elementNumber];
-  }
-  template int DataBlock::getKeyword<int>(int field, int elementNumber);
-  template float DataBlock::getKeyword<float>(int field, int elementNumber);
-  template double DataBlock::getKeyword<double>(int field, int elementNumber);
-  template std::string DataBlock::getKeyword<std::string>(int field, int elementNumber);
-  
-//   template<> int DataBlock::getKeyword<int>(int field, int element){
-//     return this->survey.readParameter<int>(this->headerString,field,element);
-//   }
-//   template<> float DataBlock::getKeyword<float>(int field, int element){
-//     return this->survey.readParameter<float>(this->headerString,field,element);
-//   }
-//   template<> double DataBlock::getKeyword<double>(int field, int element){
-//     return this->survey.readParameter<double>(this->headerString,field,element);
-//   }
-//   template<> string DataBlock::getKeyword<string>(int field, int element){
-//    return this->survey.readParameter<string>(this->headerString,field,element);
-//   }
-  //--------------------------------------------------------------------------
-  template <class T> 
-  std::vector<T> DataBlock::getFullKeyword(int field)
-  {
-    /**
-     * Returns the full list of values of the keyword, in a vector of
-     * the relevant (or requested) type. This function is useful to
-     * obtain all values for the case of keywords that have more than
-     * one value (some have 2 values, one for each band, and some have
-     * up to 8, describing individual comments etc).
-     *
-     * The function is templated, so that you can elect to get the
-     * numerical values or the string representations of individual
-     * values of the keyword.
-     *
-     * \param field The number representing the keyword field. This can be
-     * represented by the enumerated list of values given by Header::FIELDS.
-     */
-    int dim = this->survey.getFieldDimension(field);
-    std::stringstream ss;
-    std::vector<T> output(dim);
-    for(int i=0;i<dim;i++){
-      int start = this->survey.getStartPosition(field)+i*dim;
-      int length = this->survey.getFieldLength(field);
-      ss.str(this->headerString.substr(start,length));
-      ss >> output[i];      
-    }
-    return output;
-  }
-  template<> std::vector<int> DataBlock::getFullKeyword<int>(int field){
-    std::vector<int> output(this->survey.getFieldDimension(field));
-    for(int i=0;i<this->survey.getFieldDimension(field);i++)
-      output[i]=this->survey.readParameter<int>(this->headerString,field,i);
-    return output;
-  }
-  template<> std::vector<float> DataBlock::getFullKeyword<float>(int field){
-    std::vector<float> output(this->survey.getFieldDimension(field));
-    for(int i=0;i<this->survey.getFieldDimension(field);i++)
-      output[i]= this->survey.readParameter<float>(this->headerString,field,i);
-    return output;
-  }
-  template<> std::vector<string> DataBlock::getFullKeyword<string>(int field){
-    std::vector<string> output(this->survey.getFieldDimension(field));
-    for(int i=0;i<this->survey.getFieldDimension(field);i++)
-      output[i]=this->survey.readParameter<string>(this->headerString,field,i);
-    return output;
-  }
 
 }
-
Index: /trunk/src/pvo-block.hh
===================================================================
--- /trunk/src/pvo-block.hh	(revision 50)
+++ /trunk/src/pvo-block.hh	(revision 51)
@@ -7,97 +7,104 @@
 #include "pvo-header.hh"
 
-/** This controls the way blocks from existing survey files are dealt with. */
-namespace Block
+namespace PVO
 {
-  const int headerLength = 640; ///< The length of the header string [bytes]
-  /** The length of the data part of the block [bytes] */
-  const int dataLength = 49152; // = 48*1024
-  /** Four possible ways to express the equinox. These are return values for DataBlock::getEquinox().  */
-  const std::string eq_date  = "Equat. of date"; 
-  const std::string eq_b1950 = "B1950";
-  const std::string eq_gal   = "GAL";
-  const std::string eq_j2000 = "J2000";
-//   const std::string eq_equat = "J2000";
-  const std::string eq_equat = "EQUAT";
-  const float eq_1950 = 1950.;
-  const float eq_2000 = 2000.;
 
-  /**
-   *  A single block of data.
-   *
-   *  This class holds one block of data: 48k long, plus 640 bytes
-   *  of header information. It also records information about the 
-   *  type of survey that the data is from, as well as the schema 
-   *  defining how the headers are defined (which depends on the survey).
-   */
+  /** This controls the way blocks from existing survey files are
+      dealt with. */
+  namespace Block
+  {
+    const int headerLength = 640; ///< The length of the header string [bytes]
+    /** The length of the data part of the block [bytes] */
+    const int dataLength = 49152; // = 48*1024
+    /** Four possible ways to express the equinox. These are return
+	values for DataBlock::getEquinox().  */
+    const std::string eq_date  = "Equat. of date"; 
+    const std::string eq_b1950 = "B1950";
+    const std::string eq_gal   = "GAL";
+    const std::string eq_j2000 = "J2000";
+    //   const std::string eq_equat = "J2000";
+    const std::string eq_equat = "EQUAT";
+    const float eq_1950 = 1950.;
+    const float eq_2000 = 2000.;
 
-  class DataBlock
-  {
-  public:
-    /** Constructor for particular survey. */
-    DataBlock(Header::SURVEY surveyType);
-    virtual ~DataBlock(); ///< Destructor
+    /**
+     *  A single block of data.
+     *
+     *  This class holds one block of data: 48k long, plus 640 bytes
+     *  of header information. It also records information about the 
+     *  type of survey that the data is from, as well as the schema 
+     *  defining how the headers are defined (which depends on the survey).
+     */
 
-    /** Read in a full block (headers+data) from a file stream. */
-    bool readBlock(std::ifstream &file);
+    class DataBlock
+    {
+    public:
+      /** Constructor for particular survey. */
+      DataBlock(Header::SURVEY surveyType);
+      virtual ~DataBlock(); ///< Destructor
 
-    /** Read in the headers from a file stream. */
-    bool readHeader(std::ifstream &file);
+      /** Read in a full block (headers+data) from a file stream. */
+      bool readBlock(std::ifstream &file);
 
-    /** Read in the data from a file stream. */
-    void readData(std::ifstream &file);
+      /** Read in the headers from a file stream. */
+      bool readHeader(std::ifstream &file);
 
-    /** Save an array of data to the Block. */
-    void saveData(char *dataArray, int size);
+      /** Read in the data from a file stream. */
+      void readData(std::ifstream &file);
 
-    /** Get an individual data point. */
-    char getDatum(int i){return data[i];};
+      /** Save an array of data to the Block. */
+      void saveData(char *dataArray, int size);
 
-    /** Get the entire string of data */
-    char *getData(){return data;};
+      /** Get an individual data point. */
+      char getDatum(int i){return data[i];};
 
-    /** Get the name of the survey */
-    std::string getSurveyName(){return surveyName;};
+      /** Get the entire string of data */
+      char *getData(){return data;};
 
-    /** Get the type of survey */
-    Header::SURVEY getSurveyType(){return surveyType;};
+      /** Get the name of the survey */
+      std::string getSurveyName(){return surveyName;};
 
-    /** Get the equinox in a string format. */
-    std::string getEquinox();
+      /** Get the type of survey */
+      Header::SURVEY getSurveyType(){return surveyType;};
 
-    /** Get the coordinate type. */
-    std::string getCoordMode();
+      /** Get the equinox in a string format. */
+      std::string getEquinox();
 
-    /** Was the telescope not moving, and tracking fine for this block? */
-    bool telescopeOK();
+      /** Get the coordinate type. */
+      std::string getCoordMode();
 
-    /** Generate the name of the fits file this block should be written to. */
-    std::string getFITSname();
+      /** Was the telescope not moving, and tracking fine for this block? */
+      bool telescopeOK();
 
-    /** Return a particular element of a keyword set */
-    template <typename T> T getKeyword(int field, int elementNumber=0);
+      /** Generate the name of the fits file this block should be written to. */
+      std::string getFITSname();
 
-    /** Return the full set of values for a particular keyword */
-    template <typename T> std::vector<T> getFullKeyword(int field);
+      /** Return a particular element of a keyword set */
+      template <typename T> T getKeyword(int field, int elementNumber=0);
 
-    /** Provide a reference to the survey schema. */
-    Header::SurveySchema& Survey(){
-      Header::SurveySchema& rsurv=survey;
-      return rsurv;
+      /** Return the full set of values for a particular keyword */
+      template <typename T> std::vector<T> getFullKeyword(int field);
+
+      /** Provide a reference to the survey schema. */
+      Header::SurveySchema& Survey(){
+	Header::SurveySchema& rsurv=survey;
+	return rsurv;
+      };
+
+      /** Provide a reference to the header string. */
+      std::string& Header(){
+	std::string& rhead=headerString;
+	return rhead;
+      };
+
+    private:
+      std::string headerString;    ///< the header string of the block
+      char *data;                  ///< the set of data, stored as chars
+      Header::SURVEY surveyType;   ///< what type of survey the block deals with
+      Header::SurveySchema survey; ///< how the headers of the survey are defined
+      std::string surveyName;      ///< the name of the survey
     };
 
-    /** Provide a reference to the header string. */
-    std::string& Header(){
-      std::string& rhead=headerString;
-      return rhead;
-    };
-
-  private:
-    std::string headerString;    ///< the header string of the block
-    char *data;                  ///< the set of data, stored as chars
-    Header::SURVEY surveyType;   ///< what type of survey the block deals with
-    Header::SurveySchema survey; ///< how the headers of the survey are defined
-    std::string surveyName;      ///< the name of the survey
-  };
+  }
 
 }
Index: /trunk/src/pvo-header.cc
===================================================================
--- /trunk/src/pvo-header.cc	(revision 50)
+++ /trunk/src/pvo-header.cc	(revision 51)
@@ -7,283 +7,288 @@
 using std::string;
 
-namespace Header
+namespace PVO
 {
 
-  SurveySchema::SurveySchema(const SurveySchema& s)
+  namespace Header
   {
-    for(int i=0;i<numKeywords;i++) startPosition[i]  = s.startPosition[i];
-    for(int i=0;i<numKeywords;i++) fieldLength[i]    = s.fieldLength[i];
-    for(int i=0;i<numKeywords;i++) fieldDimension[i] = s.fieldDimension[i];
-    minSamples = s.minSamples;
-    ant_x      = s.ant_x;
-    ant_y      = s.ant_y;   
-    ant_z      = s.ant_z;    
-    frontend   = s.frontend;
-    fd_poln    = s.fd_poln;  
-    fd_hand    = s.fd_hand; 
-    fd_sang    = s.fd_sang; 
-    fd_xyph    = s.fd_xyph; 
-    backend    = s.backend; 
-    beconfig   = s.beconfig; 
-    be_phase   = s.be_phase;
-    be_dcc     = s.be_dcc;
-    tcycle     = s.tcycle;   
-    obs_mode   = s.obs_mode; 
-    trk_mode   = s.trk_mode; 
-    scanlen    = s.scanlen;  
-    fd_mode    = s.fd_mode; 
-    cal_mode   = s.cal_mode; 
-    cal_freq   = s.cal_freq; 
-    cal_dcyc   = s.cal_dcyc; 
-    cal_phs    = s.cal_phs; 
-    bmaj       = s.bmaj;
-    bmin       = s.bmin;
-    bpa        = s.bpa;
-  }
-  //--------------------------------------------------------------------------
-
-  SurveySchema& SurveySchema::operator= (const SurveySchema& s)
-  {
-    if(this == &s) return *this;   // Gracefully handle self assignment
+
+    SurveySchema::SurveySchema(const SurveySchema& s)
+    {
+      for(int i=0;i<numKeywords;i++) startPosition[i]  = s.startPosition[i];
+      for(int i=0;i<numKeywords;i++) fieldLength[i]    = s.fieldLength[i];
+      for(int i=0;i<numKeywords;i++) fieldDimension[i] = s.fieldDimension[i];
+      minSamples = s.minSamples;
+      ant_x      = s.ant_x;
+      ant_y      = s.ant_y;   
+      ant_z      = s.ant_z;    
+      frontend   = s.frontend;
+      fd_poln    = s.fd_poln;  
+      fd_hand    = s.fd_hand; 
+      fd_sang    = s.fd_sang; 
+      fd_xyph    = s.fd_xyph; 
+      backend    = s.backend; 
+      beconfig   = s.beconfig; 
+      be_phase   = s.be_phase;
+      be_dcc     = s.be_dcc;
+      tcycle     = s.tcycle;   
+      obs_mode   = s.obs_mode; 
+      trk_mode   = s.trk_mode; 
+      scanlen    = s.scanlen;  
+      fd_mode    = s.fd_mode; 
+      cal_mode   = s.cal_mode; 
+      cal_freq   = s.cal_freq; 
+      cal_dcyc   = s.cal_dcyc; 
+      cal_phs    = s.cal_phs; 
+      bmaj       = s.bmaj;
+      bmin       = s.bmin;
+      bpa        = s.bpa;
+    }
+    //-----------------------------------------------------------------------
+
+    SurveySchema& SurveySchema::operator= (const SurveySchema& s)
+    {
+      if(this == &s) return *this;   // Gracefully handle self assignment
     
-    for(int i=0;i<numKeywords;i++) this->startPosition[i]  = s.startPosition[i];
-    for(int i=0;i<numKeywords;i++) this->fieldLength[i]    = s.fieldLength[i];
-    for(int i=0;i<numKeywords;i++) this->fieldDimension[i] = s.fieldDimension[i];
-    this->minSamples = s.minSamples;
-    this->ant_x      = s.ant_x;
-    this->ant_y      = s.ant_y;   
-    this->ant_z      = s.ant_z;    
-    this->frontend   = s.frontend;
-    this->fd_poln    = s.fd_poln;  
-    this->fd_hand    = s.fd_hand; 
-    this->fd_sang    = s.fd_sang; 
-    this->fd_xyph    = s.fd_xyph; 
-    this->backend    = s.backend; 
-    this->beconfig   = s.beconfig; 
-    this->be_phase   = s.be_phase;
-    this->be_dcc     = s.be_dcc;
-    this->tcycle     = s.tcycle;   
-    this->obs_mode   = s.obs_mode; 
-    this->trk_mode   = s.trk_mode; 
-    this->scanlen    = s.scanlen;  
-    this->fd_mode    = s.fd_mode; 
-    this->cal_mode   = s.cal_mode; 
-    this->cal_freq   = s.cal_freq; 
-    this->cal_dcyc   = s.cal_dcyc; 
-    this->cal_phs    = s.cal_phs;  
-    this->bmaj       = s.bmaj;
-    this->bmin       = s.bmin;
-    this->bpa        = s.bpa;
-
-    return *this;
-  }
-  //--------------------------------------------------------------------------
-
-  SurveySchema::SurveySchema(SURVEY surveyType)
-  {
-    /**
-     * The constructor used to define a setup for a specific survey. The choice
-     *  of survey determines the values of the start and length arrays for 
-     *  each field. If a field does not appear in the header setup for a given
-     *  survey, the start element is set to the RESERVE value, and the length
-     *  is set to 0.
-     * \param surveyType The type of survey, as expressed by the Header::SURVEY
-     * enumeration.
-     */
-
-    // Generic PHU Keywords that are the same for all surveys with PKS.
-    this->ant_x    = -4554231.5;
-    this->ant_y    = 2816759.1;
-    this->ant_z    = -3454036.3;
-    this->backend  = "FB_1BIT";
-    this->beconfig = "";
-    this->be_phase = 0;  // 0=unknown
-    this->be_dcc   = 0;
-    this->tcycle   = 0;
-    this->obs_mode = "SEARCH";
-    this->trk_mode = "TRACK";
-    this->cal_mode = "OFF"; 
-    this->cal_freq = 0.;
-    this->cal_dcyc = 0.;
-    this->cal_phs  = 0.;
+      for(int i=0;i<numKeywords;i++) this->startPosition[i]  = s.startPosition[i];
+      for(int i=0;i<numKeywords;i++) this->fieldLength[i]    = s.fieldLength[i];
+      for(int i=0;i<numKeywords;i++) this->fieldDimension[i] = s.fieldDimension[i];
+      this->minSamples = s.minSamples;
+      this->ant_x      = s.ant_x;
+      this->ant_y      = s.ant_y;   
+      this->ant_z      = s.ant_z;    
+      this->frontend   = s.frontend;
+      this->fd_poln    = s.fd_poln;  
+      this->fd_hand    = s.fd_hand; 
+      this->fd_sang    = s.fd_sang; 
+      this->fd_xyph    = s.fd_xyph; 
+      this->backend    = s.backend; 
+      this->beconfig   = s.beconfig; 
+      this->be_phase   = s.be_phase;
+      this->be_dcc     = s.be_dcc;
+      this->tcycle     = s.tcycle;   
+      this->obs_mode   = s.obs_mode; 
+      this->trk_mode   = s.trk_mode; 
+      this->scanlen    = s.scanlen;  
+      this->fd_mode    = s.fd_mode; 
+      this->cal_mode   = s.cal_mode; 
+      this->cal_freq   = s.cal_freq; 
+      this->cal_dcyc   = s.cal_dcyc; 
+      this->cal_phs    = s.cal_phs;  
+      this->bmaj       = s.bmaj;
+      this->bmin       = s.bmin;
+      this->bpa        = s.bpa;
+
+      return *this;
+    }
+    //--------------------------------------------------------------------------
+
+    SurveySchema::SurveySchema(SURVEY surveyType)
+    {
+      /**
+       * The constructor used to define a setup for a specific survey. The choice
+       *  of survey determines the values of the start and length arrays for 
+       *  each field. If a field does not appear in the header setup for a given
+       *  survey, the start element is set to the RESERVE value, and the length
+       *  is set to 0.
+       * \param surveyType The type of survey, as expressed by the Header::SURVEY
+       * enumeration.
+       */
+
+      // Generic PHU Keywords that are the same for all surveys with PKS.
+      this->ant_x    = -4554231.5;
+      this->ant_y    = 2816759.1;
+      this->ant_z    = -3454036.3;
+      this->backend  = "FB_1BIT";
+      this->beconfig = "";
+      this->be_phase = 0;  // 0=unknown
+      this->be_dcc   = 0;
+      this->tcycle   = 0;
+      this->obs_mode = "SEARCH";
+      this->trk_mode = "TRACK";
+      this->cal_mode = "OFF"; 
+      this->cal_freq = 0.;
+      this->cal_dcyc = 0.;
+      this->cal_phs  = 0.;
     
-    if(surveyType == S70){
-      //=============
-      // 70-cm Survey
-      //=============
-
-      this->minSamples = 512 * 1024;
-
-      this->frontend = "70cm_Cavity_Disk";
-      this->fd_mode  = "FA";
-      this->fd_poln  = "LIN";
-      this->fd_hand  = 1;
-      this->fd_sang  = 0.;
-      this->fd_xyph  = 0.;
-
-      this->bmaj = 0.75;
-      this->bmin = 0.75;
-      this->bpa = 0.;
-
-      this->scanlen = 152.;
-
-      // This initialises the SurveyHeader arrays for the S70 setup.
-      int s70Start[numKeywords] = {0,8,12,16,20,
-				   28,36,44,60,
-				   72,74,90,106,114,
-				   602,602,122,130,138,
-				   202,204,220,228,
-				   252,276,284,292,602,300,
-				   304,320,332,348,364,372,380,388,
-				   396,602,428,492,500,508,
-				   516,598,520,524,536,540,
-				   556,560,568,576,578,584,586,
-				   588,602,602,602,602};
-      for(int i=0;i<numKeywords;i++) this->startPosition[i] = s70Start[i];
+      if(surveyType == S70){
+	//=============
+	// 70-cm Survey
+	//=============
+
+	this->minSamples = 512 * 1024;
+
+	this->frontend = "70cm_Cavity_Disk";
+	this->fd_mode  = "FA";
+	this->fd_poln  = "LIN";
+	this->fd_hand  = 1;
+	this->fd_sang  = 0.;
+	this->fd_xyph  = 0.;
+
+	this->bmaj = 0.75;
+	this->bmin = 0.75;
+	this->bpa = 0.;
+
+	this->scanlen = 152.;
+
+	// This initialises the SurveyHeader arrays for the S70 setup.
+	int s70Start[numKeywords] = {0,8,12,16,20,
+				     28,36,44,60,
+				     72,74,90,106,114,
+				     602,602,122,130,138,
+				     202,204,220,228,
+				     252,276,284,292,602,300,
+				     304,320,332,348,364,372,380,388,
+				     396,602,428,492,500,508,
+				     516,598,520,524,536,540,
+				     556,560,568,576,578,584,586,
+				     588,602,602,602,602};
+	for(int i=0;i<numKeywords;i++) this->startPosition[i] = s70Start[i];
       
-      int s70Length[numKeywords] = {8,4,4,4,8,
-				    8,8,16,12,
-				    2,16,16,8,8,
-				    0,0,8,8,64,
-				    2,8,4,12,
-				    12,4,8,8,0,4,
-				    16,12,16,16,8,8,8,8,
-				    8,0,8,8,8,8,
-				    4,4,4,12,4,16,
-				    2,8,4,2,6,2,2,
-				    10,0,0,0,38};
-      for(int i=0;i<numKeywords;i++) this->fieldLength[i] = s70Length[i];
-
-      int s70Dim[numKeywords] = {1,1,1,1,1,
-				 1,1,1,1,
-				 1,1,1,1,1,
-				 1,1,1,1,1,
-				 1,2,2,2,
-				 2,2,1,1,1,1,
-				 1,1,1,1,1,1,1,1,
-				 4,1,8,1,1,1,
-				 1,1,1,1,1,1,
-				 2,1,2,1,1,1,1,
-				 1,1,1,1,1};
-      for(int i=0;i<numKeywords;i++) this->fieldDimension[i] = s70Dim[i];
-    }
-    else if(surveyType == PM || surveyType == PH){
-      //==================
-      // Multibeam Surveys
-      //==================
-
-      this->minSamples = 2050 * 4096;
-
-      this->frontend = "20cm_MB";
-      this->fd_poln  = "LIN";
-      this->fd_hand  = 1;
-      this->fd_sang  = -90.;
-      this->fd_xyph  = 0.;
-      this->beconfig = "";
-      this->fd_mode  = "CPA";
-//       this->fa_req  = 30.;
-
-      this->bmaj = 0.24;
-      this->bmin = 0.24;
-      this->bpa = 0.;
-
-      if(surveyType == PM) this->scanlen = 2100.;
-      else                 this->scanlen = 265.;
-
-      // This initialises the SurveyHeader arrays for the PM setup.
-      int pmStart[numKeywords] = {0,6,10,16,20,
-				  28,36,44,60,
-				  72,74,90,106,114,
-				  122,130,618,618,138,
-				  202,204,220,228,
-				  252,276,284,292,300,302,
-				  304,320,332,348,364,372,380,388,
-				  618,396,412,492,500,508,
-				  618,516,520,524,618,540,
-				  556,560,568,576,578,584,586,
-				  588,598,606,614,618};
-      for(int i=0;i<numKeywords;i++) this->startPosition[i] = pmStart[i];
+	int s70Length[numKeywords] = {8,4,4,4,8,
+				      8,8,16,12,
+				      2,16,16,8,8,
+				      0,0,8,8,64,
+				      2,8,4,12,
+				      12,4,8,8,0,4,
+				      16,12,16,16,8,8,8,8,
+				      8,0,8,8,8,8,
+				      4,4,4,12,4,16,
+				      2,8,4,2,6,2,2,
+				      10,0,0,0,38};
+	for(int i=0;i<numKeywords;i++) this->fieldLength[i] = s70Length[i];
+
+	int s70Dim[numKeywords] = {1,1,1,1,1,
+				   1,1,1,1,
+				   1,1,1,1,1,
+				   1,1,1,1,1,
+				   1,2,2,2,
+				   2,2,1,1,1,1,
+				   1,1,1,1,1,1,1,1,
+				   4,1,8,1,1,1,
+				   1,1,1,1,1,1,
+				   2,1,2,1,1,1,1,
+				   1,1,1,1,1};
+	for(int i=0;i<numKeywords;i++) this->fieldDimension[i] = s70Dim[i];
+      }
+      else if(surveyType == PM || surveyType == PH){
+	//==================
+	// Multibeam Surveys
+	//==================
+
+	this->minSamples = 2050 * 4096;
+
+	this->frontend = "20cm_MB";
+	this->fd_poln  = "LIN";
+	this->fd_hand  = 1;
+	this->fd_sang  = -90.;
+	this->fd_xyph  = 0.;
+	this->beconfig = "";
+	this->fd_mode  = "CPA";
+	//       this->fa_req  = 30.;
+
+	this->bmaj = 0.24;
+	this->bmin = 0.24;
+	this->bpa = 0.;
+
+	if(surveyType == PM) this->scanlen = 2100.;
+	else                 this->scanlen = 265.;
+
+	// This initialises the SurveyHeader arrays for the PM setup.
+	int pmStart[numKeywords] = {0,6,10,16,20,
+				    28,36,44,60,
+				    72,74,90,106,114,
+				    122,130,618,618,138,
+				    202,204,220,228,
+				    252,276,284,292,300,302,
+				    304,320,332,348,364,372,380,388,
+				    618,396,412,492,500,508,
+				    618,516,520,524,618,540,
+				    556,560,568,576,578,584,586,
+				    588,598,606,614,618};
+	for(int i=0;i<numKeywords;i++) this->startPosition[i] = pmStart[i];
       
-      int pmLength[numKeywords] = {6,4,6,4,8,
-				   8,8,16,12,
-				   2,16,16,8,8,
-				   8,8,0,0,64,
-				   2,8,4,12,
-				   12,4,8,8,2,1,
-				   16,12,16,16,8,8,8,8,
-				   0,4,4,8,8,8,
-				   0,4,4,16,0,16,
-				   2,8,4,2,6,2,2,
-				   10,8,8,4,22};
-      for(int i=0;i<numKeywords;i++) this->fieldLength[i] = pmLength[i];
-
-      int pmDim[numKeywords] = {1,1,1,1,1,
-				1,1,1,1,
-				1,1,1,1,1,
-				1,1,1,1,1,
-				1,2,2,2,
-				2,2,1,1,1,2,
-				1,1,1,1,1,1,1,1,
-				1,4,20,1,1,1,
-				1,1,1,1,1,1,
-				2,1,2,1,1,1,1,
-				1,1,1,1,1};
-      for(int i=0;i<numKeywords;i++) this->fieldDimension[i] = pmDim[i];
-    }
-    //     else throw xBadSurvey(surveyType);
-  }
-  //--------------------------------------------------------------------------
-
-  template <class T> 
-  T SurveySchema::readParameter(string headerString, int field,
-				int elementNumber)
-  {
-    /**
-     * Read a parameter from a certain field in a header string. The function
-     *  is templated, so one can obtain a numerical value or the string
-     *  representation.
-     * \param headerString The character string containing the full header.
-     * \param field The number of the desired header field. Can use the 
-     *  Header::FIELDS enumeration.
-     * \param elementNumber Which element of a multi-valued field to return. 
-     *  Defaults to 0 (ie. the first element).
-     * \return The value of the parameter, in the format in which the function 
-     *  is instantiated.
-     */
-    int dim = this->fieldDimension[field];
-    int length = this->fieldLength[field];
-    int pos = this->startPosition[field];
-    std::stringstream ss;
-    std::vector<T> output(dim);
-    for(int i=0;i<dim;i++){
-      ss.str( headerString.substr(pos+elementNumber*length, length) );
-      ss >> output[i];    
-    }
-    return output[elementNumber];
-  }
-  template <> string 
-  SurveySchema::readParameter<string>(string headerString, 
-				      int field, int elementNumber)
-  {
-    //    int dim = this->fieldDimension[field];
-    int length = this->fieldLength[field];
-    int pos = this->startPosition[field];
-    return headerString.substr(pos+elementNumber*length, length);
-  }
-  template int SurveySchema::readParameter<int>(string headerString, 
-						int field,
-						int elementNumber);
-  template float SurveySchema::readParameter<float>(string headerString, 
-						    int field,
-						    int elementNumber);
-  template double SurveySchema::readParameter<double>(string headerString, 
+	int pmLength[numKeywords] = {6,4,6,4,8,
+				     8,8,16,12,
+				     2,16,16,8,8,
+				     8,8,0,0,64,
+				     2,8,4,12,
+				     12,4,8,8,2,1,
+				     16,12,16,16,8,8,8,8,
+				     0,4,4,8,8,8,
+				     0,4,4,16,0,16,
+				     2,8,4,2,6,2,2,
+				     10,8,8,4,22};
+	for(int i=0;i<numKeywords;i++) this->fieldLength[i] = pmLength[i];
+
+	int pmDim[numKeywords] = {1,1,1,1,1,
+				  1,1,1,1,
+				  1,1,1,1,1,
+				  1,1,1,1,1,
+				  1,2,2,2,
+				  2,2,1,1,1,2,
+				  1,1,1,1,1,1,1,1,
+				  1,4,20,1,1,1,
+				  1,1,1,1,1,1,
+				  2,1,2,1,1,1,1,
+				  1,1,1,1,1};
+	for(int i=0;i<numKeywords;i++) this->fieldDimension[i] = pmDim[i];
+      }
+      //     else throw xBadSurvey(surveyType);
+    }
+    //--------------------------------------------------------------------------
+
+    template <class T> 
+    T SurveySchema::readParameter(string headerString, int field,
+				  int elementNumber)
+    {
+      /**
+       * Read a parameter from a certain field in a header string. The function
+       *  is templated, so one can obtain a numerical value or the string
+       *  representation.
+       * \param headerString The character string containing the full header.
+       * \param field The number of the desired header field. Can use the 
+       *  Header::FIELDS enumeration.
+       * \param elementNumber Which element of a multi-valued field to return. 
+       *  Defaults to 0 (ie. the first element).
+       * \return The value of the parameter, in the format in which the function 
+       *  is instantiated.
+       */
+      int dim = this->fieldDimension[field];
+      int length = this->fieldLength[field];
+      int pos = this->startPosition[field];
+      std::stringstream ss;
+      std::vector<T> output(dim);
+      for(int i=0;i<dim;i++){
+	ss.str( headerString.substr(pos+elementNumber*length, length) );
+	ss >> output[i];    
+      }
+      return output[elementNumber];
+    }
+    template <> string 
+    SurveySchema::readParameter<string>(string headerString, 
+					int field, int elementNumber)
+    {
+      //    int dim = this->fieldDimension[field];
+      int length = this->fieldLength[field];
+      int pos = this->startPosition[field];
+      return headerString.substr(pos+elementNumber*length, length);
+    }
+    template int SurveySchema::readParameter<int>(string headerString, 
+						  int field,
+						  int elementNumber);
+    template float SurveySchema::readParameter<float>(string headerString, 
 						      int field,
 						      int elementNumber);
-  template string SurveySchema::readParameter<string>(string headerString, 
-						      int field,
-						      int elementNumber);
-  //--------------------------------------------------------------------------
-
-
+    template double SurveySchema::readParameter<double>(string headerString, 
+							int field,
+							int elementNumber);
+    template string SurveySchema::readParameter<string>(string headerString, 
+							int field,
+							int elementNumber);
+    //--------------------------------------------------------------------------
+
+
+
+  }
 
 }
Index: /trunk/src/pvo-header.hh
===================================================================
--- /trunk/src/pvo-header.hh	(revision 50)
+++ /trunk/src/pvo-header.hh	(revision 51)
@@ -5,185 +5,190 @@
 #include <fstream>  
 
-/** This controls how the headers of existing files are interpreted. */
-namespace Header
+namespace PVO
 {
-  /** Codes for the different surveys.*/
-  enum SURVEY { S70=0, ///< 70-cm Survey (Parkes Southern Pulsar Survey).
-		PM,    ///< Parkes Multibeam Survey
-		PH,    ///< Parkes High-Latitude (multibeam) Survey
-		DUD,   ///< Unknown survey -- this may be a problem!
-		NONEXISTENT ///< File does not exist.
-  };
 
-  /** Human-readable names for the surveys */
-  const std::string surveyNames[DUD+1] = {
-"70-cm survey", 
-"Parkes Multibeam survey", 
-"Parkes High-latitude survey", 
-"Not a valid survey" 
-  };
-
-  /**
-   *  What survey does a file contain?
-   *
-   *  Reads the first few bytes of a file, which contain information about
-   *  the type of survey data recorded in the file.
-   *  \param file String with name of the file to be examined.
-   *  \return An enumerated Header::SURVEY type.
-   */
-  inline SURVEY idSurvey(std::string file)
+  /** This controls how the headers of existing files are interpreted. */
+  namespace Header
   {
-    std::ifstream fin;
-    fin.open(file.c_str(), std::ios::binary);
-    if(fin.fail()){
-      fin.close();
-      return NONEXISTENT;
-    }
-    char *hdr = new char[5];
-    fin.read( hdr, 5*sizeof(char) );
-    fin.close();
-    hdr[4] = '\0';
-    unsigned char compstring_s70[5] = {182, 'm', 'm', 219, 0};
-    unsigned char compstring_pm[4] = {'P', 'M', 'D'};
-    compstring_pm[3] = '\0';
-    SURVEY returnval;
-    if(strcmp((const char*)compstring_s70,hdr)==0) returnval = S70;
-    else if(strncmp((const char*)compstring_pm,hdr,3)==0) returnval = PM;
-    else returnval = DUD;
-    delete [] hdr;
-    return returnval;
-  }
-
-  /** Codes for the different moving states. \deprecated */
-  enum ISMOVING { NOTGRID=0, POINT, MOVING, SCANNING };
-
-  /** Codes representing the different header keywords */
-  enum FIELDS 
-    {CODE=0, VERSION, TAPENR, SCAN_CNTR, BLK_CNTR, 
-     DATE, MJD, UT_STRT, LST_STRT, 
-     COORD_TYPE, RA_STRT, DEC_STRT, GL_STRT, GB_STRT, 
-     FEED_ANGLE, OBS_TIME, SCAN_RATE, SCAN_LEN, COMMENT, 
-     NFILTER, CHANBW, NCHAN, FREQ_CHAN1, 
-     SAMP_INT, SAMP_GRP, GRP_BLK, BLK_SEC, FDCNTRL, DATA_TYPE,
-     UT, LST, RA, DEC, GL, GB, TEL_ZEN, TEL_AZ, 
-     STATUS, ATTEN, TPOWER, NBLK_READ, SCAN_RATEL, SCAN_RATEB, 
-     BYTE_GRP, NBEAM, IBEAM, PSRNAME, DATA_TWO, OBS_FILEN, 
-     NBITS, DDM, NDDCH, MOVE, PNTERR, TREE, NSYS, 
-     TELID, PANGLE, SMP_BSW, CAL_CYCLE, RESERVE
+    /** Codes for the different surveys.*/
+    enum SURVEY { S70=0, ///< 70-cm Survey (Parkes Southern Pulsar Survey).
+		  PM,    ///< Parkes Multibeam Survey
+		  PH,    ///< Parkes High-Latitude (multibeam) Survey
+		  DUD,   ///< Unknown survey -- this may be a problem!
+		  NONEXISTENT ///< File does not exist.
     };
 
-  const int numKeywords = RESERVE + 1; ///< The total number of keywords.
+    /** Human-readable names for the surveys */
+    const std::string surveyNames[DUD+1] = {
+      "70-cm survey", 
+      "Parkes Multibeam survey", 
+      "Parkes High-latitude survey", 
+      "Not a valid survey" 
+    };
+
+    /**
+     *  What survey does a file contain?
+     *
+     *  Reads the first few bytes of a file, which contain information about
+     *  the type of survey data recorded in the file.
+     *  \param file String with name of the file to be examined.
+     *  \return An enumerated Header::SURVEY type.
+     */
+    inline SURVEY idSurvey(std::string file)
+    {
+      std::ifstream fin;
+      fin.open(file.c_str(), std::ios::binary);
+      if(fin.fail()){
+	fin.close();
+	return NONEXISTENT;
+      }
+      char *hdr = new char[5];
+      fin.read( hdr, 5*sizeof(char) );
+      fin.close();
+      hdr[4] = '\0';
+      unsigned char compstring_s70[5] = {182, 'm', 'm', 219, 0};
+      unsigned char compstring_pm[4] = {'P', 'M', 'D'};
+      compstring_pm[3] = '\0';
+      SURVEY returnval;
+      if(strcmp((const char*)compstring_s70,hdr)==0) returnval = S70;
+      else if(strncmp((const char*)compstring_pm,hdr,3)==0) returnval = PM;
+      else returnval = DUD;
+      delete [] hdr;
+      return returnval;
+    }
+
+    /** Codes for the different moving states. \deprecated */
+    enum ISMOVING { NOTGRID=0, POINT, MOVING, SCANNING };
+
+    /** Codes representing the different header keywords */
+    enum FIELDS 
+      {CODE=0, VERSION, TAPENR, SCAN_CNTR, BLK_CNTR, 
+       DATE, MJD, UT_STRT, LST_STRT, 
+       COORD_TYPE, RA_STRT, DEC_STRT, GL_STRT, GB_STRT, 
+       FEED_ANGLE, OBS_TIME, SCAN_RATE, SCAN_LEN, COMMENT, 
+       NFILTER, CHANBW, NCHAN, FREQ_CHAN1, 
+       SAMP_INT, SAMP_GRP, GRP_BLK, BLK_SEC, FDCNTRL, DATA_TYPE,
+       UT, LST, RA, DEC, GL, GB, TEL_ZEN, TEL_AZ, 
+       STATUS, ATTEN, TPOWER, NBLK_READ, SCAN_RATEL, SCAN_RATEB, 
+       BYTE_GRP, NBEAM, IBEAM, PSRNAME, DATA_TWO, OBS_FILEN, 
+       NBITS, DDM, NDDCH, MOVE, PNTERR, TREE, NSYS, 
+       TELID, PANGLE, SMP_BSW, CAL_CYCLE, RESERVE
+      };
+
+    const int numKeywords = RESERVE + 1; ///< The total number of keywords.
 
 
-  /**
-   * Definitions of the different survey headers.
-   *
-   * This class contains the information needed to make sense of the header
-   *  strings found in the existing survey data files. Each survey has a 
-   *  different header structure, and so this class handles the definitions
-   *  of where one keyword ends and another starts.
-   */
+    /**
+     * Definitions of the different survey headers.
+     *
+     * This class contains the information needed to make sense of the header
+     *  strings found in the existing survey data files. Each survey has a 
+     *  different header structure, and so this class handles the definitions
+     *  of where one keyword ends and another starts.
+     */
 
-  class SurveySchema
-  {
-  public:
-    SurveySchema(){};
-    virtual ~SurveySchema(){};
-    SurveySchema(SURVEY surveyType); ///< Survey-specific constructor
-    SurveySchema(const SurveySchema& s); ///< Copy constructor
-    SurveySchema& operator= (const SurveySchema& s); ///< Copy constructor.
+    class SurveySchema
+    {
+    public:
+      SurveySchema(){};
+      virtual ~SurveySchema(){};
+      SurveySchema(SURVEY surveyType); ///< Survey-specific constructor
+      SurveySchema(const SurveySchema& s); ///< Copy constructor
+      SurveySchema& operator= (const SurveySchema& s); ///< Copy constructor.
 
-    /** Get the character number that a given field starts at. */
-    int getStartPosition(int field){return startPosition[field];};
-    /** Get the number of characters in a given field. */
-    int getFieldLength(int field){return fieldLength[field];};
-     /** Get the number of elements that a given field contains. */
-    int getFieldDimension(int field){return fieldDimension[field];};
+      /** Get the character number that a given field starts at. */
+      int getStartPosition(int field){return startPosition[field];};
+      /** Get the number of characters in a given field. */
+      int getFieldLength(int field){return fieldLength[field];};
+      /** Get the number of elements that a given field contains. */
+      int getFieldDimension(int field){return fieldDimension[field];};
 
-    template <class T> T readParameter(std::string headerString, int field,
-				       int elementNumber = 0);
-    ///< Read a particular header parameter.
+      template <class T> T readParameter(std::string headerString, int field,
+					 int elementNumber = 0);
+      ///< Read a particular header parameter.
 
-    /** Exception class for a bad survey code. Not used at the moment. */
-    class xBadSurvey{
-    public:
-      xBadSurvey(std::string s){surveyName=s;};
-      virtual ~xBadSurvey(){};
-      std::string getSurvey(){return surveyName;};
+      /** Exception class for a bad survey code. Not used at the moment. */
+      class xBadSurvey{
+      public:
+	xBadSurvey(std::string s){surveyName=s;};
+	virtual ~xBadSurvey(){};
+	std::string getSurvey(){return surveyName;};
+      private:
+	std::string surveyName;
+      };
+
+      long        getMinSamples(){return minSamples;};
+
+      // accessor functions for PHU keyword values -- only get functions needed.
+      double      getAntX(){return ant_x;};
+      double      getAntY(){return ant_y;};
+      double      getAntZ(){return ant_z;};
+      std::string getFrontend(){return frontend;};
+      std::string getFd_poln(){return fd_poln;};
+      int         getFd_hand(){return fd_hand;};
+      float       getFd_sang(){return fd_sang;};
+      float       getFd_xyph(){return fd_xyph;};
+      std::string getBackend(){return backend;};
+      std::string getBeconfig(){return beconfig;};
+      int         getBe_phase(){return be_phase;};
+      int         getBe_dcc(){return be_dcc;};
+      double      getTcycle(){return tcycle;};
+      std::string getObs_mode(){return obs_mode;};
+      std::string getTrk_mode(){return trk_mode;};
+      float       getScanlen(){return scanlen;};
+      std::string getFd_mode(){return fd_mode;};
+      std::string getCal_mode(){return cal_mode;};
+      float       getCal_freq(){return cal_freq;};
+      float       getCal_dcyc(){return cal_dcyc;};
+      float       getCal_phs(){return cal_phs;};
+      float       getBmaj(){return bmaj;};
+      float       getBmin(){return bmin;};
+      float       getBpa(){return bpa;};
+
+ 
     private:
-      std::string surveyName;
+      int startPosition[numKeywords];  ///< The character number at
+      ///   which each field commences.
+      int fieldLength[numKeywords];    ///< The number of characters in
+      ///   each field.
+      int fieldDimension[numKeywords]; ///< The number of elements in
+      ///   each field.
+
+      long        minSamples;  ///< The minimum number of samples to be
+      ///   included in a FITS file
+
+      // The following are PHU keywords that are survey-dependent.
+      double      ant_x;
+      double      ant_y;
+      double      ant_z;
+      std::string frontend;
+      std::string fd_poln;
+      int         fd_hand;
+      float       fd_sang;
+      float       fd_xyph;
+      std::string backend;
+      std::string beconfig;
+      int         be_phase;
+      int         be_dcc;
+      double      tcycle;
+      std::string obs_mode;
+      std::string trk_mode;
+      float       scanlen;
+      std::string fd_mode;
+      std::string cal_mode;
+      float       cal_freq;
+      float       cal_dcyc;
+      float       cal_phs;
+
+      float       bmaj;
+      float       bmin;
+      float       bpa;
+
+
     };
 
-    long        getMinSamples(){return minSamples;};
+    // Inline functions
 
-    // accessor functions for PHU keyword values -- only get functions needed.
-    double      getAntX(){return ant_x;};
-    double      getAntY(){return ant_y;};
-    double      getAntZ(){return ant_z;};
-    std::string getFrontend(){return frontend;};
-    std::string getFd_poln(){return fd_poln;};
-    int         getFd_hand(){return fd_hand;};
-    float       getFd_sang(){return fd_sang;};
-    float       getFd_xyph(){return fd_xyph;};
-    std::string getBackend(){return backend;};
-    std::string getBeconfig(){return beconfig;};
-    int         getBe_phase(){return be_phase;};
-    int         getBe_dcc(){return be_dcc;};
-    double      getTcycle(){return tcycle;};
-    std::string getObs_mode(){return obs_mode;};
-    std::string getTrk_mode(){return trk_mode;};
-    float       getScanlen(){return scanlen;};
-    std::string getFd_mode(){return fd_mode;};
-    std::string getCal_mode(){return cal_mode;};
-    float       getCal_freq(){return cal_freq;};
-    float       getCal_dcyc(){return cal_dcyc;};
-    float       getCal_phs(){return cal_phs;};
-    float       getBmaj(){return bmaj;};
-    float       getBmin(){return bmin;};
-    float       getBpa(){return bpa;};
-
- 
-  private:
-    int startPosition[numKeywords];  ///< The character number at
-				     ///   which each field commences.
-    int fieldLength[numKeywords];    ///< The number of characters in
-				     ///   each field.
-    int fieldDimension[numKeywords]; ///< The number of elements in
-				     ///   each field.
-
-    long        minSamples;  ///< The minimum number of samples to be
-                             ///   included in a FITS file
-
-    // The following are PHU keywords that are survey-dependent.
-    double      ant_x;
-    double      ant_y;
-    double      ant_z;
-    std::string frontend;
-    std::string fd_poln;
-    int         fd_hand;
-    float       fd_sang;
-    float       fd_xyph;
-    std::string backend;
-    std::string beconfig;
-    int         be_phase;
-    int         be_dcc;
-    double      tcycle;
-    std::string obs_mode;
-    std::string trk_mode;
-    float       scanlen;
-    std::string fd_mode;
-    std::string cal_mode;
-    float       cal_freq;
-    float       cal_dcyc;
-    float       cal_phs;
-
-    float       bmaj;
-    float       bmin;
-    float       bpa;
-
-
-  };
-
-  // Inline functions
+  }
 
 }
Index: /trunk/src/pvo-utils.cc
===================================================================
--- /trunk/src/pvo-utils.cc	(revision 50)
+++ /trunk/src/pvo-utils.cc	(revision 51)
@@ -8,317 +8,341 @@
 #include <iomanip>
 
-std::string removeLeadingBlanks(std::string s)
+namespace PVO
 {
-  /**
-   * All blank spaces from the start of the string to the first non-blank-space
-   * character are deleted.
-   */ 
-  int i=0;
-  while(s[i]==' '){
-    i++;
-  }
-  std::string newstring;
-  for(unsigned int j=i;j<s.size();j++) newstring += s[j];
-  return newstring;
+  
+  void PVOError(std::string subroutine, std::string error)
+  {
+    /**
+     * Prints an ERROR message to the standard error stream, quoting
+     * the subroutine that the problem occurred in, a descriptive
+     * warning text, and sounding the bell.
+     *
+     * Format: ERROR \<function\> : Something bad happened.
+     */
+    std::string preamble = "\aERROR <" + subroutine + "> : ";
+    std::cerr << preamble;
+    for(int i=0;i<error.size();i++){
+      std::cerr << error[i];
+      if((i!=error.size()-1)&&(error[i]=='\n'))
+	std::cerr << std::setw(preamble.size()-1) <<": ";
+    }
+  }
+  //------------------------------------------------------------
+
+  std::string removeLeadingBlanks(std::string s)
+  {
+    /**
+     * All blank spaces from the start of the string to the first
+     * non-blank-space character are deleted.
+     */ 
+    int i=0;
+    while(s[i]==' '){
+      i++;
+    }
+    std::string newstring;
+    for(unsigned int j=i;j<s.size();j++) newstring += s[j];
+    return newstring;
+  }
+  //------------------------------------------------------------------------
+
+  std::string deblank(std::string s)
+  {
+    /**
+     * All blank spaces from the start of the string to the first
+     * non-blank-space character, and from the last non-blank-space
+     * character to the end are deleted.
+     */ 
+    int beg=0;
+    while(s[beg]==' '){
+      beg++;
+    }
+    int end=s.size()-1;
+    while(s[end]==' '){
+      end--;
+    }
+    std::string newstring;
+    for(int j=beg;j<=end;j++) newstring += s[j];
+    return newstring;
+  }
+  //------------------------------------------------------------------------
+
+  std::string charToBinary(char c)
+  {
+    /**
+     * A single byte, represented by a char type, is read in and converted
+     * to a binary representation.
+     *
+     * Used for debugging the single-bit writing and reading tasks.
+     *
+     * \param c A single byte, of char type.
+     * \return A std:string that shows the binary representation of that byte.
+     */
+
+    std::stringstream ss;
+    int num=c;
+    if (num<0) num+=256;
+    int factor = 128;
+    for(int i=0;i<8;i++){
+      ss << num/factor;
+      num -= num/factor * factor;
+      factor /= 2;
+    }
+    return ss.str();
+  }
+  //------------------------------------------------------------------------
+
+  std::string binaryToString(std::vector<bool> v)
+  {
+    /**
+     * A string of bits, read in as a vector of bool types, is coverted to the
+     *  equivalent string of bytes, in the form of chars (in fact, a std::string).
+     *
+     * Used for debugging the single-bit writing and reading tasks.
+     *
+     * \param v String of bits.
+     * \return Std::string of bytes (each byte a char).
+     */
+    int size = v.size();
+    int nbytes = (size-1)/8 + 1;
+    std::string output;
+    for(int byte=0;byte<nbytes;byte++){
+      int c=0;
+      for(int bit=0;bit<8;bit++){
+	int pt = byte*8+bit;
+	if(v[pt]) c += int(pow(2,7-bit));
+      }
+      //    std::cerr << int(c) << std::endl;
+      output += char(c);
+    }
+    return output;
+  }
+  //------------------------------------------------------------------------
+
+  unsigned int * binaryToInt(std::vector<bool> v)
+  {
+    /**
+     * A string of bits, read in as a vector of bool types, is coverted to a 
+     *  series of bytes, which are expressed as an array of integers (with the
+     *  decimal value of each byte).
+     *
+     * Used for debugging the single-bit writing and reading tasks.
+     *
+     * \param v String of bits.
+     * \return Sequence of integers, being the decimal value of each byte.
+     */
+    int size = v.size();
+    int nbytes = (size-1)/8 + 1;
+    unsigned int *output = new unsigned int[nbytes];
+    for(int byte=0;byte<nbytes;byte++){
+      int c=0;
+      for(int bit=0;bit<8;bit++){
+	int pt = byte*8+bit;
+	if(v[pt]) c += (unsigned int)pow(2,7-bit);
+      }
+      //    std::cerr << c << std::endl;
+      output[byte] = c;
+    }
+    return output;
+  }
+  //------------------------------------------------------------------------
+
+  double dmsToDec(std::string input)
+  {
+    /** 
+     *   Assumes the angle given is in degrees, so if passing RA as the argument,
+     *   need to multiply by 15 to get the result in degrees rather than hours.
+     *   The sign of the angle is preserved, if present.
+     */
+
+    std::string dms = removeLeadingBlanks(input);
+
+    bool isNeg = false;
+    if(dms[0]=='-') isNeg = true;
+
+    for(unsigned int i=0;i<dms.size();i++) if(dms[i]==':') dms[i]=' ';
+
+    std::stringstream ss;
+    ss.str(dms);
+
+    std::string deg,min,sec;
+    getline(ss,deg,' ');
+    getline(ss,min,' ');
+    getline(ss,sec);
+    char *end;
+    double d = strtod(deg.c_str(),&end);
+    double m = strtod(min.c_str(),&end);
+    double s = strtod(sec.c_str(),&end);  
+
+    double dec = fabs(d) + m/60. + s/3600.;
+    if(isNeg) dec = dec * -1.;
+
+    return dec;
+
+  }
+  //------------------------------------------------------------------------
+
+  std::string decToDMS(double input, int secondPrecision, std::string separator)
+  {
+    /**
+     *   This is the general form, where one can specify the degree of precision
+     *   of the seconds, and the separating character.
+     *  \param input Angle in decimal degrees.
+     *  \param secondPrecision How many decimal places to quote the seconds to.
+     *  \param separator The character (or string) to use as a separator between
+     *    hh and mm, and mm and ss.sss.
+     */ 
+    double hour = trunc(input);
+    double fraction = fabs(input - hour);
+    double min = trunc( fraction * 60. );
+    fraction = fraction * 60. - min;
+    double sec = fraction * 60.;
+  
+    int secondWidth = 2;
+    if(secondPrecision>0) secondWidth += 1 + secondPrecision;
+
+    std::stringstream output;
+    output << std::setw(2) << std::setfill('0') << std::setprecision(0)
+	   << hour << separator 
+	   << std::setw(2) << std::setfill('0') << std::setprecision(0)
+	   << min  << separator ;
+    output.setf(std::ios::fixed);
+    output << std::setw(secondWidth) << std::setfill('0') 
+	   << std::setprecision(secondPrecision) << sec;
+
+    return output.str();
+  }
+  //------------------------------------------------------------------------
+
+  std::string getIAUName(double ra, double dec)
+  {
+    /**
+     *  The positions are assumed to be J2000.0, since the name is
+     *  prefixed by a J.
+     *
+     *  \param ra RA position, in degrees.
+     *  \param dec Dec position, in degrees.
+     *  \return Name of the form J1234m4321 or J1234p0123
+     */
+
+    double raHrs = ra / 15.;
+    int h = int(raHrs);
+    int m = (int)(fmod(raHrs,1.)*60.);
+    int s = (int)(fmod(raHrs,1./60.)*3600.);
+    std::stringstream ss(std::stringstream::out);
+    ss.setf(std::ios::showpoint);
+    ss.setf(std::ios::fixed);
+    ss << "J"; 
+    ss<<std::setw(2)<<std::setfill('0')<<h;
+    ss<<std::setw(2)<<std::setfill('0')<<m;
+    ss<<std::setw(2)<<std::setfill('0')<<s;
+    int sign = int( dec / fabs(dec) );
+    double d = dec / sign;
+    h = int(d);
+    m = (int)(fmod(d,1.)*60.);
+    s = (int)(fmod(d,1./60.)*3600.);
+    if(sign==1) ss<<"p"; else ss<<"m";
+    ss<<std::setw(2)<<std::setfill('0')<<h;
+    ss.unsetf(std::ios::showpos);
+    ss<<std::setw(2)<<std::setfill('0')<<m;
+    ss<<std::setw(2)<<std::setfill('0')<<s;
+    return ss.str();
+  }
+  //------------------------------------------------------------------------
+
+  time_t my_timegm (struct tm *tm) {
+    /**
+     * Local function to get the proper GM time.
+     */
+    time_t ret;
+    char *tz;
+
+    tz = getenv("TZ");
+    setenv("TZ", "", 1);
+    tzset();
+    ret = mktime(tm);
+    if (tz) setenv("TZ", tz, 1);
+    else    unsetenv("TZ");
+    tzset();
+    return ret;
+  }
+
+  std::string addDay(std::string date)
+  {
+    /**
+     *   This assumes the format is yy/mm/dd or yymmdd or yy-mm-dd
+     *    -- the crucial thing is that the day number is in the last spot.
+     *   The format of the date is preserved, as long as it is one of those 3.
+     *  \param date Input date.
+     *  \return Date of same format as input, but one day later.
+     */ 
+
+    struct tm time;
+    time.tm_hour=0;
+    time.tm_min =0;
+    time.tm_sec =1;
+    char buf[255];
+    std::string output;
+    time_t temp;
+    if(date.size()==6) {
+      strptime(date.c_str(), "%y%m%d", &time);
+      time.tm_mday += 1;
+      temp = my_timegm(&time);
+      strftime(buf, sizeof(buf), "%y%m%d", gmtime(&temp));
+    }
+    else if(date[2]=='/'){
+      strptime(date.c_str(), "%y/%m/%d", &time);
+      time.tm_mday += 1;
+      temp = my_timegm(&time);
+      strftime(buf, sizeof(buf), "%y/%m/%d", gmtime(&temp));
+    }
+    else if(date[2]=='-'){
+      strptime(date.c_str(), "%y-%m-%d", &time);
+      time.tm_mday += 1;
+      temp = my_timegm(&time);
+      strftime(buf, sizeof(buf), "%y-%m-%d", gmtime(&temp));
+    }
+    else{
+      std::cerr << "<addDay> : date (" << date << ") has unknown format!\n";
+      return date;
+    }
+    output = buf;
+    return output;
+  
+  }
+  //------------------------------------------------------------------------
+
+  std::string makeDateObs(std::string date, std::string time)
+  {
+
+    /**
+     * This produces a string of the form YY-MM-DDThh:mm:ss.sss, using
+     * strings containing the date and the time. It is simply a matter
+     * of concatenating them, but we check the date string to make sure
+     * it has the hyphens in it.
+     *
+     * \param date A date string, assumed to be of the format YY-MM-DD,
+     * YY/MM/DD, or YYMMDD.
+     * \param time A time string, assumed to be in the format
+     * hh:mm:ss[.sss] (the fractional seconds are optional).
+     * \return A properly formatted date/time string.
+     */
+
+    std::string date_obs;
+    bool hashyphens = false;
+    for(int i=0;i<date.size();i++) 
+      hashyphens = hashyphens || (date[i]=='-') || (date[i] == '/');
+    if(hashyphens) date_obs = date;
+    else date_obs = date.substr(0,2) + "-" + 
+	   date.substr(2,2) + "-" + date.substr(4,2);
+    if(date[0]=='0') date_obs = "20" + date_obs;
+    else             date_obs = "19" + date_obs;
+    for(int i=0;i<date_obs.size();i++) 
+      if(date_obs[i]=='/') date_obs[i]='-';
+
+    date_obs += "T" + time;
+
+    return date_obs;
+
+  }
+
 }
-//------------------------------------------------------------------------
-
-std::string deblank(std::string s)
-{
-  /**
-   * All blank spaces from the start of the string to the first
-   * non-blank-space character, and from the last non-blank-space character
-   * to the end are deleted.
-   */ 
-  int beg=0;
-  while(s[beg]==' '){
-    beg++;
-  }
-  int end=s.size()-1;
-  while(s[end]==' '){
-    end--;
-  }
-  std::string newstring;
-  for(int j=beg;j<=end;j++) newstring += s[j];
-  return newstring;
-}
-//------------------------------------------------------------------------
-
-std::string charToBinary(char c)
-{
-  /**
-   * A single byte, represented by a char type, is read in and converted
-   * to a binary representation.
-   *
-   * Used for debugging the single-bit writing and reading tasks.
-   *
-   * \param c A single byte, of char type.
-   * \return A std:string that shows the binary representation of that byte.
-   */
-
-  std::stringstream ss;
-  int num=c;
-  if (num<0) num+=256;
-  int factor = 128;
-  for(int i=0;i<8;i++){
-    ss << num/factor;
-    num -= num/factor * factor;
-    factor /= 2;
-  }
-  return ss.str();
-}
-//------------------------------------------------------------------------
-
-std::string binaryToString(std::vector<bool> v)
-{
-  /**
-   * A string of bits, read in as a vector of bool types, is coverted to the
-   *  equivalent string of bytes, in the form of chars (in fact, a std::string).
-   *
-   * Used for debugging the single-bit writing and reading tasks.
-   *
-   * \param v String of bits.
-   * \return Std::string of bytes (each byte a char).
-   */
-  int size = v.size();
-  int nbytes = (size-1)/8 + 1;
-  std::string output;
-  for(int byte=0;byte<nbytes;byte++){
-    int c=0;
-    for(int bit=0;bit<8;bit++){
-      int pt = byte*8+bit;
-      if(v[pt]) c += int(pow(2,7-bit));
-    }
-    //    std::cerr << int(c) << std::endl;
-    output += char(c);
-  }
-  return output;
-}
-//------------------------------------------------------------------------
-
-unsigned int * binaryToInt(std::vector<bool> v)
-{
-  /**
-   * A string of bits, read in as a vector of bool types, is coverted to a 
-   *  series of bytes, which are expressed as an array of integers (with the
-   *  decimal value of each byte).
-   *
-   * Used for debugging the single-bit writing and reading tasks.
-   *
-   * \param v String of bits.
-   * \return Sequence of integers, being the decimal value of each byte.
-   */
-  int size = v.size();
-  int nbytes = (size-1)/8 + 1;
-  unsigned int *output = new unsigned int[nbytes];
-  for(int byte=0;byte<nbytes;byte++){
-    int c=0;
-    for(int bit=0;bit<8;bit++){
-      int pt = byte*8+bit;
-      if(v[pt]) c += (unsigned int)pow(2,7-bit);
-    }
-    //    std::cerr << c << std::endl;
-    output[byte] = c;
-  }
-  return output;
-}
-//------------------------------------------------------------------------
-
-double dmsToDec(std::string input)
-{
-  /** 
-   *   Assumes the angle given is in degrees, so if passing RA as the argument,
-   *   need to multiply by 15 to get the result in degrees rather than hours.
-   *   The sign of the angle is preserved, if present.
-   */
-
-  std::string dms = removeLeadingBlanks(input);
-
-  bool isNeg = false;
-  if(dms[0]=='-') isNeg = true;
-
-  for(unsigned int i=0;i<dms.size();i++) if(dms[i]==':') dms[i]=' ';
-
-  std::stringstream ss;
-  ss.str(dms);
-
-  std::string deg,min,sec;
-  getline(ss,deg,' ');
-  getline(ss,min,' ');
-  getline(ss,sec);
-  char *end;
-  double d = strtod(deg.c_str(),&end);
-  double m = strtod(min.c_str(),&end);
-  double s = strtod(sec.c_str(),&end);  
-
-  double dec = fabs(d) + m/60. + s/3600.;
-  if(isNeg) dec = dec * -1.;
-
-  return dec;
-
-}
-//------------------------------------------------------------------------
-
-std::string decToDMS(double input, int secondPrecision, std::string separator)
-{
-  /**
-   *   This is the general form, where one can specify the degree of precision
-   *   of the seconds, and the separating character.
-   *  \param input Angle in decimal degrees.
-   *  \param secondPrecision How many decimal places to quote the seconds to.
-   *  \param separator The character (or string) to use as a separator between
-   *    hh and mm, and mm and ss.sss.
-   */ 
-  double hour = trunc(input);
-  double fraction = fabs(input - hour);
-  double min = trunc( fraction * 60. );
-  fraction = fraction * 60. - min;
-  double sec = fraction * 60.;
-  
-  int secondWidth = 2;
-  if(secondPrecision>0) secondWidth += 1 + secondPrecision;
-
-  std::stringstream output;
-  output << std::setw(2) << std::setfill('0') << std::setprecision(0)
-	 << hour << separator 
-	 << std::setw(2) << std::setfill('0') << std::setprecision(0)
-	 << min  << separator ;
-  output.setf(std::ios::fixed);
-  output << std::setw(secondWidth) << std::setfill('0') 
-	 << std::setprecision(secondPrecision) << sec;
-
-  return output.str();
-}
-//------------------------------------------------------------------------
-
-std::string getIAUName(double ra, double dec)
-{
-  /**
-   *  The positions are assumed to be J2000.0, since the name is
-   *  prefixed by a J.
-   *
-   *  \param ra RA position, in degrees.
-   *  \param dec Dec position, in degrees.
-   *  \return Name of the form J1234m4321 or J1234p0123
-   */
-
-  double raHrs = ra / 15.;
-  int h = int(raHrs);
-  int m = (int)(fmod(raHrs,1.)*60.);
-  int s = (int)(fmod(raHrs,1./60.)*3600.);
-  std::stringstream ss(std::stringstream::out);
-  ss.setf(std::ios::showpoint);
-  ss.setf(std::ios::fixed);
-  ss << "J"; 
-  ss<<std::setw(2)<<std::setfill('0')<<h;
-  ss<<std::setw(2)<<std::setfill('0')<<m;
-  ss<<std::setw(2)<<std::setfill('0')<<s;
-  int sign = int( dec / fabs(dec) );
-  double d = dec / sign;
-  h = int(d);
-  m = (int)(fmod(d,1.)*60.);
-  s = (int)(fmod(d,1./60.)*3600.);
-  if(sign==1) ss<<"p"; else ss<<"m";
-  ss<<std::setw(2)<<std::setfill('0')<<h;
-  ss.unsetf(std::ios::showpos);
-  ss<<std::setw(2)<<std::setfill('0')<<m;
-  ss<<std::setw(2)<<std::setfill('0')<<s;
-  return ss.str();
-}
-//------------------------------------------------------------------------
-
-time_t my_timegm (struct tm *tm) {
-  /**
-   * Local function to get the proper GM time.
-   */
-  time_t ret;
-  char *tz;
-
-  tz = getenv("TZ");
-  setenv("TZ", "", 1);
-  tzset();
-  ret = mktime(tm);
-  if (tz) setenv("TZ", tz, 1);
-  else    unsetenv("TZ");
-  tzset();
-  return ret;
-}
-
-std::string addDay(std::string date)
-{
-  /**
-   *   This assumes the format is yy/mm/dd or yymmdd or yy-mm-dd
-   *    -- the crucial thing is that the day number is in the last spot.
-   *   The format of the date is preserved, as long as it is one of those 3.
-   *  \param date Input date.
-   *  \return Date of same format as input, but one day later.
-   */ 
-
-  struct tm time;
-  time.tm_hour=0;
-  time.tm_min =0;
-  time.tm_sec =1;
-  char buf[255];
-  std::string output;
-  time_t temp;
-  if(date.size()==6) {
-    strptime(date.c_str(), "%y%m%d", &time);
-    time.tm_mday += 1;
-    temp = my_timegm(&time);
-    strftime(buf, sizeof(buf), "%y%m%d", gmtime(&temp));
-  }
-  else if(date[2]=='/'){
-    strptime(date.c_str(), "%y/%m/%d", &time);
-    time.tm_mday += 1;
-    temp = my_timegm(&time);
-    strftime(buf, sizeof(buf), "%y/%m/%d", gmtime(&temp));
-  }
-  else if(date[2]=='-'){
-    strptime(date.c_str(), "%y-%m-%d", &time);
-    time.tm_mday += 1;
-    temp = my_timegm(&time);
-    strftime(buf, sizeof(buf), "%y-%m-%d", gmtime(&temp));
-  }
-  else{
-    std::cerr << "<addDay> : date (" << date << ") has unknown format!\n";
-    return date;
-  }
-  output = buf;
-  return output;
-  
-}
-//------------------------------------------------------------------------
-
-std::string makeDateObs(std::string date, std::string time)
-{
-
-  /**
-   * This produces a string of the form YY-MM-DDThh:mm:ss.sss, using
-   * strings containing the date and the time. It is simply a matter
-   * of concatenating them, but we check the date string to make sure
-   * it has the hyphens in it.
-   *
-   * \param date A date string, assumed to be of the format YY-MM-DD,
-   * YY/MM/DD, or YYMMDD.
-   * \param time A time string, assumed to be in the format
-   * hh:mm:ss[.sss] (the fractional seconds are optional).
-   * \return A properly formatted date/time string.
-   */
-
-  std::string date_obs;
-  bool hashyphens = false;
-  for(int i=0;i<date.size();i++) 
-    hashyphens = hashyphens || (date[i]=='-') || (date[i] == '/');
-  if(hashyphens) date_obs = date;
-  else date_obs = date.substr(0,2) + "-" + 
-	 date.substr(2,2) + "-" + date.substr(4,2);
-  if(date[0]=='0') date_obs = "20" + date_obs;
-  else             date_obs = "19" + date_obs;
-  for(int i=0;i<date_obs.size();i++) 
-    if(date_obs[i]=='/') date_obs[i]='-';
-
-  date_obs += "T" + time;
-
-  return date_obs;
-
-}
Index: /trunk/src/pvo-utils.hh
===================================================================
--- /trunk/src/pvo-utils.hh	(revision 50)
+++ /trunk/src/pvo-utils.hh	(revision 51)
@@ -5,46 +5,66 @@
 #include <vector>
 
-/** Return the filename of the defintion file of the PSRFITS format. */
-inline std::string getPSRFITSdefn(){ 
-  return getenv("PSRFITSDEFN"); 
+namespace PVO
+{
 
-//   std::cerr << "Using local PSRFITS definition! --> $PVO/templates/psrheader_20070209.fits\n"; 
-//   return "/DATA/SITAR_1/whi550/VO/PulsarVO/templates/psrheader_20070209.fits"; 
-};
+  static bool verbose;
+  
+  /** Report a general error, along with the offending function. */
+  void PVOError(std::string subroutine, std::string error);
+  
+  const std::string pvoconvert_help_msg = 
+"Usage: pvoconvert [options] <fits file>\n\
+  Options:\n\
+  -H  Use the PH (High Latitude) Survey settings, rather than the PM/Multibeam Survey\n\
+  -h  Display this help page.\n\
+  -v  Verbose mode for error/warning messages.\n";
 
-std::string removeLeadingBlanks(std::string s);
-///< Remove blank spaces from start of a string.
 
-std::string deblank(std::string s);
-///< Remove blank spaces from start and end of a string.  
+  /** Return the filename of the defintion file of the PSRFITS format. */
+  inline std::string getPSRFITSdefn(){ 
+    return getenv("PSRFITSDEFN"); 
+
+    //   std::cerr << "Using local PSRFITS definition! --> $PVO/templates/psrheader_20070209.fits\n"; 
+    //   return "/DATA/SITAR_1/whi550/VO/PulsarVO/templates/psrheader_20070209.fits"; 
+  };
+
+  std::string removeLeadingBlanks(std::string s);
+  ///< Remove blank spaces from start of a string.
+
+  std::string deblank(std::string s);
+  ///< Remove blank spaces from start and end of a string.  
    
-std::string charToBinary(char c);
-///< Convert a byte to binary representation.
+  std::string charToBinary(char c);
+  ///< Convert a byte to binary representation.
 
-std::string binaryToString(std::vector<bool> v);
-///< Convert a bit-wise binary representation to a set of bytes. 
+  std::string binaryToString(std::vector<bool> v);
+  ///< Convert a bit-wise binary representation to a set of bytes. 
 
-unsigned int * binaryToInt(std::vector<bool> v);
-///<Convert a series of bits into a series of bytes in decimal format.
+  unsigned int * binaryToInt(std::vector<bool> v);
+  ///<Convert a series of bits into a series of bytes in decimal format.
 
-double dmsToDec(std::string input);   
-///< Converts a string in the format +12:23:34.45 to a decimal angle in degrees.
+  double dmsToDec(std::string input);   
+  ///< Converts a string in the format +12:23:34.45 to a decimal angle
+  ///in degrees.
 
-std::string decToDMS(double input, int secondPrecision, std::string separator);
-///< Converts a decimal into a dd:mm:ss.ss format.
+  std::string decToDMS(double input, int secondPrecision, 
+		       std::string separator);
+  ///< Converts a decimal into a dd:mm:ss.ss format.
 
-/** Particular instance of decToDMS(double,int,std::string) with
-    standard precision & separator */
-inline std::string decToDMS(double input){ return decToDMS(input,2,":"); };
+  /** Particular instance of decToDMS(double,int,std::string) with
+      standard precision & separator */
+  inline std::string decToDMS(double input){ return decToDMS(input,2,":"); };
 
-std::string getIAUName(double ra, double dec);  
-///< Create an IAU-style formatted name, based on the equatorial position.
+  std::string getIAUName(double ra, double dec);  
+  ///< Create an IAU-style formatted name, based on the equatorial position.
 
-std::string addDay(std::string date);
-///< A function to add a day onto the date.
+  std::string addDay(std::string date);
+  ///< A function to add a day onto the date.
 
-/** Makes the DATE-OBS header keyword in the format mandated by the
-    FITS standard. */
-std::string makeDateObs(std::string date, std::string time);
+  /** Makes the DATE-OBS header keyword in the format mandated by the
+      FITS standard. */
+  std::string makeDateObs(std::string date, std::string time);
+
+}
 
 #endif /*UTILS_HH_*/
Index: /trunk/src/pvoconvert.cc
===================================================================
--- /trunk/src/pvoconvert.cc	(revision 50)
+++ /trunk/src/pvoconvert.cc	(revision 51)
@@ -4,4 +4,5 @@
 #include <iomanip>
 #include <string>
+#include <unistd.h>
 #include "pvo-block.hh"
 #include "pvo-header.hh"
@@ -9,41 +10,39 @@
 #include "pvo-utils.hh"
 
-using namespace Header;
-using namespace Block;
-using namespace FITS;
+using namespace PVO;
+using namespace PVO::Header;
+using namespace PVO::Block;
+using namespace PVO::FITS;
 using std::string;
 
 int main(int argc, char * argv[])
 {
+  PSRFits fitsfile;
+  fitsfile.setVerbosity(false);
   std::string fname;
   bool usingHighLatitude = false;
-  if(argc==2){
-    fname = argv[1];
-    if(fname=="-h") {
-      std::cerr << "Usage: \"pvoconvert filename\"\n"
-		<< "   or: \"pvoconvert -ph filename\" to set PH survey.\n"
-		<< "   or: \"pvoconvert -h \" to see this message.\n";
-      return 0;
+
+  char c;
+  int optCount=0;
+  while( ( c = getopt(argc,argv,"H:v:h") )!=-1){
+    optCount++;
+    switch(c) {
+    case 'v':
+      fitsfile.setVerbosity(true);
+      fname = optarg;
+      break;
+    case 'H':
+      usingHighLatitude = true;
+      fname = optarg;
+      break;
+    case 'h':
+    default:
+      std::cout << PVO::pvoconvert_help_msg;
+      return 1;
+      break;
     }
   }
-  else if(argc==3){
-    std::string opt = argv[1];
-    fname = argv[2];
-    if(opt == "-ph") {
-      usingHighLatitude = true;
-    }
-    else {
-      std::cerr << "Usage: \"pvoconvert.x filename\"\n"
-		<< "   or: \"pvoconvert.x -ph filename\" to set PH survey.\n"
-		<< "   or: \"pvoconvert.x -h \" to see this message.\n";
-      return 1;
-    }
-  }
-  else{
-    std::cerr << "Usage: \"pvoconvert.x filename\"...\n"
-	      << "   or: \"pvoconvert.x -ph filename\" to set PH survey.\n"
-	      << "   or: \"pvoconvert.x -h \" to see this message.\n";
-    return 1;
-  }
+
+  if(optCount==0) fname = argv[1];
 
   SURVEY currentSurvey = idSurvey(fname);
@@ -81,5 +80,4 @@
   bool oldMoveFlag;
 
-  PSRFits fitsfile;
   fitsfile.setOldFilename(fname);
   fitsfile.setCommandLine(argc,argv);
Index: /trunk/src/pvosummary.cc
===================================================================
--- /trunk/src/pvosummary.cc	(revision 50)
+++ /trunk/src/pvosummary.cc	(revision 51)
@@ -4,4 +4,5 @@
 #include <iomanip>
 #include <string>
+#include <glob.h>
 #include "pvo-block.hh"
 #include "pvo-header.hh"
@@ -9,7 +10,8 @@
 #include "pvo-utils.hh"
 
-using namespace Header;
-using namespace Block;
-using namespace FITS;
+using namespace PVO;
+using namespace PVO::Header;
+using namespace PVO::Block;
+using namespace PVO::FITS;
 using std::string;
 
@@ -17,30 +19,62 @@
 {
 
-  std::string name;
-  if(argc!=2){
+  bool verboseflag = false;
+
+  std::vector<std::string> namelist;
+  int i;
+  switch(argc){
+  case 1:
+    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];
+    break;
+  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";
+      return 0;
+    }
+    namelist.resize(1);
+    namelist[0] = argv[1];
+    break;
+  default:
     std::cerr << " Usage : \"pvosummary filename\"\n";
     return 0;
+    break;
   }
 
-  name = argv[1];
+  for(i=0;i<namelist.size();i++){
 
-  PSRFits fitsfile;
-//   fitsfile.setVerbosity(false);
-  int status = fitsfile.openFile(name);
+    PSRFits fitsfile;
+    fitsfile.setVerbosity(verboseflag);
+    int status = fitsfile.openFile(namelist[i]);
   
-  if(status==0){
-    fitsfile.gotoPHU();
+    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;
+      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;
     
-    std::cout << name << ": \t"
-	      << std::setw(14) << ra   << " "
-	      << std::setw(14) << dec  << " "
-	      << std::setw(20) << date << "\n";
+      std::cout << namelist[i] << ": \t"
+		<< std::setw(14) << ra   << " "
+		<< std::setw(14) << dec  << " "
+		<< std::setw(20) << date << "\n";
+    }
   }
+
 }
