[boinc-app-seti] 02/04: Imported Upstream version 8.00~svn3643

Gianfranco Costamagna locutusofborg at moszumanska.debian.org
Tue Apr 4 08:22:54 UTC 2017


This is an automated email from the git hooks/post-receive script.

locutusofborg pushed a commit to branch master
in repository boinc-app-seti.

commit 1c9b366303d561f628138c2437a156fe839b5271
Author: Gianfranco Costamagna <costamagnagianfranco at yahoo.it>
Date:   Tue Apr 4 10:12:05 2017 +0200

    Imported Upstream version 8.00~svn3643
---
 AUTHORS                                |   19 +
 COPYRIGHT                              |   11 +-
 assimilator/Makefile.am                |    3 +-
 assimilator/sah_assimilate_handler.cpp |   24 +-
 client/analyzeFuncs.cpp                |    2 +-
 client/seti.cpp                        | 2302 ++++++++++++++++----------------
 client/vector/analyzeFuncs_fpu.cpp     |    2 +-
 client/vector/analyzeFuncs_neon.S      |   90 +-
 client/vector/analyzeFuncs_vector.cpp  |   18 +-
 client/vector/analyzeFuncs_vfp.S       |   76 +-
 client/vector/analyzeFuncs_vfp_aux.cpp |   17 +-
 db/db_table.h                          |  151 ++-
 db/schema_master.cpp                   |   74 +-
 db/schema_master.h                     |    6 +-
 db/schema_master.sql                   |    3 +
 db/xml_util.h                          |    4 +-
 ops/bin/splitter_janitor_gbt           |  272 ++++
 splitter_pfb/Makefile.am               |    2 +-
 splitter_pfb/mb_dotransform.cpp        |    4 +-
 splitter_pfb/mb_read_blocks_guppi.cpp  |  166 ++-
 splitter_pfb/mb_wufiles.cpp            |    2 +-
 validate/Makefile.in                   |    3 +-
 validate/sah_validate.cpp              |    7 +
 23 files changed, 1851 insertions(+), 1407 deletions(-)

diff --git a/AUTHORS b/AUTHORS
index 17f7e60..8b4d067 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -23,6 +23,25 @@ Stevenj G. Johnson <stevenj at alum.mit.edu>
 Stefan Kral <skral at fftw.org> wrote genfft-k7/*.ml*, which was
 added in fftw-3.0 and removed in fftw-3.2.
 
+Additional authors of Astropulse:
+Joshua Von Korff <vonkorff at ssl.berkeley.edu>
+Paul Demorest <demorest at astro.berkeley.edu>
+
+OpenCL development by:
+Raistmer
+Urs Echternacht
+Frizz
+
+X-Branch CUDA by:
+Jason Richard Groothuis ( jgopt.org, contact at jgopt dot org ), 
+in collaboration with Josef Segur ( Lunatics.kwsn.info )
+Linux porting by Aaron Haviland.
+
+Original CUDA development by:
+Przemyslaw Zych (NVIDIA)
+Scott Le Grand (NVIDIA)
+Bob Johnston (NVIDIA)
+
 Authors of fft8g.[cpp,h]
 Takuya Ooura <ooura at kurims.kyoto-u.ac.jp>
 Eric J. Korpela <korpela at ssl.berkeley.edu>
diff --git a/COPYRIGHT b/COPYRIGHT
index 3029670..f600350 100644
--- a/COPYRIGHT
+++ b/COPYRIGHT
@@ -1,11 +1,16 @@
-// Copyright (c) 1999-2011 Regents of the University of California
+// Copyright (c) 1999-2016 Regents of the University of California
 //
-// FFTW: Copyright (c) 2003,2006 Matteo Frigo
-//       Copyright (c) 2003,2006 Massachusets Institute of Technology
+// FFTW: Copyright (c) 2003,2006-2016 Matteo Frigo
+//       Copyright (c) 2003,2006-2016 Massachusets Institute of Technology
 //
 // fft8g.[cpp,h]: Copyright (c) 1995-2001 Takya Ooura
 //
+// Brook+ and OpenCL portions of code: Copyright (c) 2010-2016 Raistmer
+//
 // ASMLIB: Copyright (c) 2004 Agner Fog
+//
+// X-Branch: Copyright (c) 2012-2016 Jason Richard Groothuis
+//
 
 // This program is free software; you can redistribute it and/or modify it 
 // under the terms of the GNU General Public License as published by the 
diff --git a/assimilator/Makefile.am b/assimilator/Makefile.am
index 1020537..ef482ec 100644
--- a/assimilator/Makefile.am
+++ b/assimilator/Makefile.am
@@ -12,6 +12,7 @@ BOINC_INC	= -I$(BOINCDIR) -I$(BOINCDIR)/api -I$(BOINCDIR)/lib -I$(BOINCDIR)/sche
 BOINC_LIBS 	=  -L$(BOINCDIR)/sched -lsched @MYSQL_LIBS@ @PTHREAD_LIBS@ -L$(BOINCDIR)/lib -lboinc -L$(SSLDIR) -lcrypto -lssl
 HEALPIX_INC     = -I$(HEALPIX)/include 
 HEALPIX_LIBS    = -L$(HEALPIX)/lib -lchealpix -lhealpix_cxx -lcxxsupport
+SYSLIBS 	= -larmadillo
 
 #bin_PROGRAMS = sah_assimilator
 noinst_PROGRAMS = sah_assimilator
@@ -30,5 +31,5 @@ sah_assimilator_SOURCES = \
 
 sah_assimilator_CFLAGS = $(AM_CFLAGS) $(BOINC_INC) $(HEALPIX_INC) $(SETILIB_CFLAGS) $(MYSQL_CFLAGS) $(INFORMIX_CFLAGS) -I.. -I../db $(PTHREAD_CFLAGS) -I../client -I../validate
 sah_assimilator_CXXFLAGS = $(AM_CXXFLAGS) $(BOINC_INC) $(SETILIB_CFLAGS) $(HEALPIX_INC) $(MYSQL_CFLAGS) $(INFORMIX_CFLAGS) -I.. -I../db $(PTHREAD_CFLAGS) -I../client -I../validate
-sah_assimilator_LDADD =  $(PTHREAD_CFLAGS) $(BOINC_LIBS) $(SETILIB_LIBS) $(MYSQL_LIBS) $(INFORMIX_LIBS) $(CLIBS) $(HEALPIX_LIBS)
+sah_assimilator_LDADD =  $(PTHREAD_CFLAGS) $(BOINC_LIBS) $(SETILIB_LIBS) $(MYSQL_LIBS) $(INFORMIX_LIBS) $(CLIBS) $(HEALPIX_LIBS) $(SYSLIBS)
 
diff --git a/assimilator/sah_assimilate_handler.cpp b/assimilator/sah_assimilate_handler.cpp
index 35a9079..194c26e 100644
--- a/assimilator/sah_assimilate_handler.cpp
+++ b/assimilator/sah_assimilate_handler.cpp
@@ -32,7 +32,7 @@
 
 // the boinc assimilator makes these available
 extern SCHED_CONFIG config;
-extern bool noinsert;		
+//extern bool noinsert;		
 
 const double  D2R =  0.017453292;
 const int fpix_res = 10;            // Hz
@@ -43,6 +43,14 @@ struct timespec nanotime;
 
 //inline long round(double x) {return long(floor(x + 0.5f));}
 
+// the init and usage functions are required by boinc
+int assimilate_handler_init(int, char**) {
+    return 0;
+}
+void assimilate_handler_usage() {
+}
+
+
 int populate_seti_result(
 	result& sah_result, 
         RESULT& boinc_canonical_result, 
@@ -143,12 +151,12 @@ int assimilate_handler(
 	}
     	// Sometimes we want to perform all assimilation functions
     	// *except* insertion into the science master DB.
-    	if (noinsert) {
-      		log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,
-      		"[%s] assimilator is in noinsert mode.\n",
-      		boinc_wu.name
-      		);
-    	}
+    	//if (noinsert) {
+        //		log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,
+        //		"[%s] assimilator is in noinsert mode.\n",
+        //		boinc_wu.name
+        //		);
+    	//}
     } else {
 /*
 	retval = db_change(sah_config.scidb_name);
@@ -166,7 +174,7 @@ int assimilate_handler(
         }
 */
    }
-   if (noinsert) return 0;   	// Note that this will result in the WU being marked as assimilated - 
+   //if (noinsert) return 0;   	// Note that this will result in the WU being marked as assimilated - 
 				// we will not see it again.
 
     // translate seti wuid for thos wus that changed ids during the DB merge
diff --git a/client/analyzeFuncs.cpp b/client/analyzeFuncs.cpp
index abd9179..a684cd4 100644
--- a/client/analyzeFuncs.cpp
+++ b/client/analyzeFuncs.cpp
@@ -790,7 +790,7 @@ int seti_analyze (ANALYSIS_STATE& state) {
             SETIERROR(WRITE_FAILED,"from outfile.printf (best triplet) in seti_analyze()");
         }
     }
-    retval=outfile.printf("<setiathome_version>"PACKAGE_VERSION"</setiathome_version>\n");
+    retval=outfile.printf("<setiathome_version>" PACKAGE_VERSION "</setiathome_version>\n");
 
 #ifdef BOINC_APP_GRAPHICS
     if (sah_graphics) strcpy(sah_graphics->status, "Work unit done");
diff --git a/client/seti.cpp b/client/seti.cpp
index c566fea..bc14289 100644
--- a/client/seti.cpp
+++ b/client/seti.cpp
@@ -1,1122 +1,1122 @@
-// Copyright 2003 Regents of the University of California
-
-// SETI_BOINC is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 2, or (at your option) any later
-// version.
-
-// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT
-// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-// more details.
-
-// You should have received a copy of the GNU General Public License along
-// with SETI_BOINC; see the file COPYING.  If not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-// In addition, as a special exception, the Regents of the University of
-// California give permission to link the code of this program with libraries
-// that provide specific optimized fast Fourier transform (FFT) functions and
-// distribute a linked executable.  You must obey the GNU General Public 
-// License in all respects for all of the code used other than the FFT library
-// itself.  Any modification required to support these libraries must be
-// distributed in source code form.  If you modify this file, you may extend 
-// this exception to your version of the file, but you are not obligated to 
-// do so. If you do not wish to do so, delete this exception statement from 
-// your version.
-
-// seti.C
-// $Id: seti.cpp,v 1.60.2.19 2007/08/10 00:38:49 korpela Exp $
-//
-// SETI-specific logic for reading/writing checkpoint files
-// and parsing WU files.
-//
-// Files:
-// state.txt
-// the last chirp rate / FFT len finished, if any
-// outfile.txt
-// The append-only result file
-//
-// What finally gets sent back as the result file is:
-// - the generic result header, with the final CPU time filled in
-// - the SETI-specific part of the WU header
-// - the contents of outfile.txt
-
-#include "sah_config.h"
-
-#include <cstdio>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <cstdlib>
-#include <cstring>
-#include <string>
-
-#ifdef BOINC_APP_GRAPHICS
-#include "sah_gfx_main.h"
-#endif
-
-#ifdef HAVE_IEEEFP_H
-#include <ieeefp.h>
-#endif
-
-#include "boinc_api.h"
-#include "str_util.h"
-#include "str_replace.h"
-
-#include "diagnostics.h"
-#include "parse.h"
-#include "filesys.h"
-#include "s_util.h"
-#include "seti_header.h"
-#include "analyze.h"
-#include "analyzeFuncs.h"
-#include "vector/analyzeFuncs_vector.h"
-#include "pulsefind.h"
-#include "analyzeReport.h"
-#include "analyzePoT.h"
-#include "malloc_a.h"
-#include "chirpfft.h"
-#include "worker.h"
-
-#include "seti.h"
-
-#define DATA_ASCII 1
-#define DATA_ENCODED 2
-#define DATA_SUN_BINARY 3
-
-APP_INIT_DATA app_init_data;
-
-ANALYSIS_STATE analysis_state;
-static int wrote_header;
-double LOAD_STORE_ADJUSTMENT=2.85;
-double SETUP_FLOPS=1.42e+10/2.85;
-
-SPIKE_INFO::SPIKE_INFO() : track_mem<SPIKE_INFO>("SPIKE_INFO"),s(), score(0), bin(0), fft_ind(0) {}
- 
-SPIKE_INFO::~SPIKE_INFO() {}
-
-SPIKE_INFO::SPIKE_INFO(const SPIKE_INFO &si) : track_mem<SPIKE_INFO>("SPIKE_INFO"),
-s(si.s), score(si.score), bin(si.bin), fft_ind(si.fft_ind) {}
-
-SPIKE_INFO &SPIKE_INFO::operator =(const SPIKE_INFO &si) {
-#ifdef USE_MANUAL_CALLSTACK
-  call_stack.enter("SPIKE_INFO::operator =");
-#endif 
-  if (&si != this) {
-    s=si.s;
-    score=si.score;
-    bin=si.bin;
-    fft_ind=si.fft_ind;
-  }
-#ifdef USE_MANUAL_CALLSTACK
-  call_stack.exit();
-#endif 
-  return *this;
-}
-
-AUTOCORR_INFO::AUTOCORR_INFO() : track_mem<AUTOCORR_INFO>("AUTOCORR_INFO"),a(), score(0), bin(0), fft_ind(0) {}
- 
-AUTOCORR_INFO::~AUTOCORR_INFO() {}
-
-AUTOCORR_INFO::AUTOCORR_INFO(const AUTOCORR_INFO &ai) : track_mem<AUTOCORR_INFO>("AUTOCORR_INFO"),
-a(ai.a), score(ai.score), bin(ai.bin), fft_ind(ai.fft_ind) {}
-
-AUTOCORR_INFO &AUTOCORR_INFO::operator =(const AUTOCORR_INFO &ai) {
-#ifdef USE_MANUAL_CALLSTACK
-  call_stack.enter("AUTOCORR_INFO::operator =");
-#endif 
-  if (&ai != this) {
-    a=ai.a;
-    score=ai.score;
-    bin=ai.bin;
-    fft_ind=ai.fft_ind;
-  }
-#ifdef USE_MANUAL_CALLSTACK
-  call_stack.exit();
-#endif 
-  return *this;
-}
-
-
-GAUSS_INFO::GAUSS_INFO() : track_mem<GAUSS_INFO>("GAUSS_INFO"),
-g(), score(0), display_power_thresh(0), bin(0), fft_ind(0) {
-}
-
-GAUSS_INFO::~GAUSS_INFO() {}
-
-GAUSS_INFO::GAUSS_INFO(const GAUSS_INFO &gi) : track_mem<GAUSS_INFO>("GAUSS_INFO"),
-g(gi.g), score(gi.score), bin(gi.bin), fft_ind(gi.fft_ind) {
-}
-
-GAUSS_INFO &GAUSS_INFO::operator =(const GAUSS_INFO &gi) {
-#ifdef USE_MANUAL_CALLSTACK
-  call_stack.enter("GAUSS_INFO::operator =");
-#endif 
-  if (&gi != this) {
-    g=gi.g;
-    score=gi.score;
-    bin=gi.bin;
-    fft_ind=gi.fft_ind;
-  }
-#ifdef USE_MANUAL_CALLSTACK
-  call_stack.exit();
-#endif 
-  return *this;
-}
-
-PULSE_INFO::PULSE_INFO() : track_mem<PULSE_INFO>("PULSE_INFO"), p(), score(0), freq_bin(0), time_bin(0) {
-
-#ifdef USE_MANUAL_CALLSTACK
-  call_stack.enter("PULSE_INFO::PULSE_INFO()");
-#endif 
-// debug possible heap corruption -- jeffc
-#ifdef _WIN32
-BOINCASSERT(_CrtCheckMemory());
-#endif
-
-    pot_min = (unsigned int *)calloc_a(swi.analysis_cfg.pulse_pot_length, sizeof(unsigned int), MEM_ALIGN);
-    if (pot_min == NULL) SETIERROR(MALLOC_FAILED, "new PULSE_INFO pot_min == NULL");
-    pot_max = (unsigned int *)calloc_a(swi.analysis_cfg.pulse_pot_length, sizeof(unsigned int), MEM_ALIGN);
-    if (pot_max == NULL) SETIERROR(MALLOC_FAILED, "new PULSE_INFO pot_max == NULL");
-
-// debug possible heap corruption -- jeffc
-#ifdef _WIN32
-BOINCASSERT(_CrtCheckMemory());
-#endif
-#ifdef USE_MANUAL_CALLSTACK
-    call_stack.exit();
-#endif 
-}
-
-
-PULSE_INFO::~PULSE_INFO() { 
-// debug possible heap corruption -- jeffc
-#ifdef _WIN32
-BOINCASSERT(_CrtCheckMemory());
-#endif
-#ifdef USE_MANUAL_CALLSTACK
-    call_stack.enter("PULSE_INFO::~PULSE_INFO()");
-#endif 
-    free_a(pot_min); 
-    free_a(pot_max); 
-
-// debug possible heap corruption -- jeffc
-#ifdef _WIN32
-BOINCASSERT(_CrtCheckMemory());
-#endif
-#ifdef USE_MANUAL_CALLSTACK
-    call_stack.exit();
-#endif 
-}
-
-
-PULSE_INFO::PULSE_INFO(const PULSE_INFO &pi) : track_mem<PULSE_INFO>("PULSE_INFO"),  
-p(pi.p), score(pi.score), freq_bin(pi.freq_bin), time_bin(pi.time_bin) {
-#ifdef USE_MANUAL_CALLSTACK
-    call_stack.enter("PULSE_INFO::PULSE_INFO(const PULSE_INFO &pi)");
-#endif 
-// debug possible heap corruption -- jeffc
-#ifdef _WIN32
-BOINCASSERT(_CrtCheckMemory());
-#endif
-
-    pot_min = (unsigned int *)calloc_a(swi.analysis_cfg.pulse_pot_length, sizeof(unsigned int), MEM_ALIGN);
-    if (pot_min == NULL) SETIERROR(MALLOC_FAILED, "copied PULSE_INFO pot_min == NULL");
-    pot_max = (unsigned int *)calloc_a(swi.analysis_cfg.pulse_pot_length, sizeof(unsigned int), MEM_ALIGN);
-    if (pot_max == NULL) SETIERROR(MALLOC_FAILED, "copied PULSE_INFO pot_max == NULL");
-
-    memcpy(pot_min,pi.pot_min,(swi.analysis_cfg.pulse_pot_length * sizeof(unsigned int)));
-    memcpy(pot_max,pi.pot_max,(swi.analysis_cfg.pulse_pot_length * sizeof(unsigned int)));
-
-// debug possible heap corruption -- jeffc
-#ifdef _WIN32
-BOINCASSERT(_CrtCheckMemory());
-#endif
-#ifdef USE_MANUAL_CALLSTACK
-    call_stack.exit();
-#endif 
-}
-
-PULSE_INFO &PULSE_INFO::operator =(const PULSE_INFO &pi) {
-#ifdef USE_MANUAL_CALLSTACK
-  call_stack.enter("PULSE_INFO::operator =");
-#endif 
-// debug possible heap corruption -- jeffc
-#ifdef _WIN32
-BOINCASSERT(_CrtCheckMemory());
-#endif
-
-  if (&pi != this) {
-    p=pi.p;
-    score=pi.score;
-    freq_bin=pi.freq_bin;
-    time_bin=pi.time_bin;
-
-    memcpy(pot_min,pi.pot_min,(swi.analysis_cfg.pulse_pot_length * sizeof(unsigned int)));
-    memcpy(pot_max,pi.pot_max,(swi.analysis_cfg.pulse_pot_length * sizeof(unsigned int)));
-  }
-
-// debug possible heap corruption -- jeffc
-#ifdef _WIN32
-BOINCASSERT(_CrtCheckMemory());
-#endif
-#ifdef USE_MANUAL_CALLSTACK
-  call_stack.exit();
-#endif 
-  return *this;
-}
-
-TRIPLET_INFO::TRIPLET_INFO() : track_mem<TRIPLET_INFO>("TRIPLET_INFO"),
-t(), score(0), bperiod(0), freq_bin(0), tpotind0_0(0), tpotind0_1(0), 
-tpotind1_0(0), tpotind1_1(0), tpotind2_0(0), tpotind2_1(0), time_bin(0), 
-scale(0) {
-#ifdef USE_MANUAL_CALLSTACK
-    call_stack.enter("TRIPLET_INFO::TRIPLET_INFO()");
-#endif 
-// debug possible heap corruption -- jeffc
-#ifdef _WIN32
-BOINCASSERT(_CrtCheckMemory());
-#endif
-
-    pot_min = (unsigned int *)calloc_a(swi.analysis_cfg.triplet_pot_length, sizeof(unsigned int), MEM_ALIGN);
-    if (pot_min == NULL) SETIERROR(MALLOC_FAILED, "new TRIPLET_INFO pot_min == NULL");
-    pot_max = (unsigned int *)calloc_a(swi.analysis_cfg.triplet_pot_length, sizeof(unsigned int), MEM_ALIGN);
-    if (pot_max == NULL) SETIERROR(MALLOC_FAILED, "new TRIPLET_INFO pot_max == NULL");
-
-// debug possible heap corruption -- jeffc
-#ifdef _WIN32
-BOINCASSERT(_CrtCheckMemory());
-#endif
-#ifdef USE_MANUAL_CALLSTACK
-    call_stack.exit();
-#endif 
-}
-
-TRIPLET_INFO::TRIPLET_INFO(const TRIPLET_INFO &ti) : track_mem<TRIPLET_INFO>("TRIPLET_INFO"), t(ti.t), score(ti.score), 
-
-    bperiod(ti.bperiod), freq_bin(ti.freq_bin), 
-    tpotind0_0(ti.tpotind0_0), tpotind0_1(ti.tpotind0_1),
-    tpotind1_0(ti.tpotind1_0), tpotind1_1(ti.tpotind1_1),
-    tpotind2_0(ti.tpotind2_0), tpotind2_1(ti.tpotind2_1), 
-    time_bin(ti.time_bin), scale(ti.scale)
-
-{
-#ifdef USE_MANUAL_CALLSTACK
-    call_stack.enter("TRIPLET_INFO::TRIPLET_INFO(const TRIPLET_INFO &ti)");
-#endif 
-// debug possible heap corruption -- jeffc
-#ifdef _WIN32
-BOINCASSERT(_CrtCheckMemory());
-#endif
-
-    pot_min = (unsigned int *)calloc_a(swi.analysis_cfg.triplet_pot_length, sizeof(unsigned int), MEM_ALIGN);
-    if (pot_min == NULL) SETIERROR(MALLOC_FAILED, "copied TRIPLET_INFO pot_min == NULL");
-    pot_max = (unsigned int *)calloc_a(swi.analysis_cfg.triplet_pot_length, sizeof(unsigned int), MEM_ALIGN);
-    if (pot_max == NULL) SETIERROR(MALLOC_FAILED, "copied TRIPLET_INFO pot_max == NULL");
-    memcpy(pot_min,ti.pot_min,(swi.analysis_cfg.triplet_pot_length * sizeof(unsigned int)));
-    memcpy(pot_max,ti.pot_max,(swi.analysis_cfg.triplet_pot_length * sizeof(unsigned int)));
-
-// debug possible heap corruption -- jeffc
-#ifdef _WIN32
-BOINCASSERT(_CrtCheckMemory());
-#endif
-#ifdef USE_MANUAL_CALLSTACK
-    call_stack.exit();
-#endif 
-}    
-
-TRIPLET_INFO &TRIPLET_INFO::operator =(const TRIPLET_INFO &ti) {
-#ifdef USE_MANUAL_CALLSTACK
-   call_stack.enter("TRIPLET_INFO::operator =");
-#endif 
-// debug possible heap corruption -- jeffc
-#ifdef _WIN32
-BOINCASSERT(_CrtCheckMemory());
-#endif
-
-  if (&ti != this) {
-    t=ti.t;
-    score=ti.score;
-    bperiod=ti.bperiod;
-    freq_bin=ti.freq_bin;
-    tpotind0_0=ti.tpotind0_0;
-    tpotind0_1=ti.tpotind0_1;
-    tpotind1_0=ti.tpotind1_0;
-    tpotind1_1=ti.tpotind1_1;
-    tpotind2_0=ti.tpotind2_0;
-    tpotind2_1=ti.tpotind2_1;
-    time_bin=ti.time_bin;
-
-    memcpy(pot_min,ti.pot_min,(swi.analysis_cfg.triplet_pot_length * sizeof(unsigned int)));
-    memcpy(pot_max,ti.pot_max,(swi.analysis_cfg.triplet_pot_length * sizeof(unsigned int)));
-  }
-
-// debug possible heap corruption -- jeffc
-#ifdef _WIN32
-BOINCASSERT(_CrtCheckMemory());
-#endif
-#ifdef USE_MANUAL_CALLSTACK
-  call_stack.exit();
-#endif 
-  return *this;
-}
-
-
-TRIPLET_INFO::~TRIPLET_INFO() { 
-#ifdef USE_MANUAL_CALLSTACK
-    call_stack.enter("TRIPLET_INFO::~TRIPLET_INFO()");
-#endif 
-// debug possible heap corruption -- jeffc
-#ifdef _WIN32
-BOINCASSERT(_CrtCheckMemory());
-#endif
-
-    free_a(pot_min); 
-    free_a(pot_max); 
-
-// debug possible heap corruption -- jeffc
-#ifdef _WIN32
-BOINCASSERT(_CrtCheckMemory());
-#endif
-#ifdef USE_MANUAL_CALLSTACK
-    call_stack.exit();
-#endif 
-}
-
-
-// Do SETI-specific initialization for a work unit.
-// - prepare outfile for appending
-// - reset scores
-int seti_init_state() {
-#ifdef USE_MANUAL_CALLSTACK
-  call_stack.enter("seti_init_state()");
-#endif 
-  analysis_state.icfft= 0;
-  analysis_state.PoT_freq_bin = -1;
-  analysis_state.PoT_activity = POT_INACTIVE;
-  progress = 0.0;
-  reset_high_scores();
-  std::string path;
-
-  boinc_resolve_filename_s(OUTFILE_FILENAME, path);
-  if (outfile.open(path.c_str(), "ab")) SETIERROR(CANT_CREATE_FILE," in seti_init_state()");
-#ifdef USE_MANUAL_CALLSTACK
-  call_stack.exit();
-#endif 
-  return 0;
-}
-
-// This gets called at the start of each chirp/fft pair.
-int result_group_start() {
-  wrote_header = 0;
-  return 0;
-}
-
-// This gets called prior to writing an entry in the output file.
-// Write the chirp/fft parameters if not done already.
-
-int result_group_write_header() {
-  if (wrote_header) return 0;
-  wrote_header = 1;
-  int retval = outfile.printf( "<ogh ncfft=%d cr=%e fl=%d>\n",
-                               analysis_state.icfft,
-                               ChirpFftPairs[analysis_state.icfft].ChirpRate,
-                               ChirpFftPairs[analysis_state.icfft].FftLen
-                             );
-  if (retval < 0) SETIERROR(WRITE_FAILED,"in result_group_write_header()");
-  return 0;
-}
-
-
-// this gets called at the end of each chirp/fft pair
-// Rewrite the state file,
-// and write an end-of-group record to log file
-// if anything was written for this group.
-int result_group_end() {
-  int retval=0;
-
-  if (wrote_header) {
-    retval = outfile.printf( "<ogt ncfft=%d cr=%e fl=%d>\n",
-                             analysis_state.icfft,
-                             ChirpFftPairs[analysis_state.icfft].ChirpRate,
-                             ChirpFftPairs[analysis_state.icfft].FftLen);
-    if (retval < 0) SETIERROR(WRITE_FAILED,"in result_group_end");
-  }
-
-  return 0;
-}
-  
-
-int checkpoint(BOOLEAN force_checkpoint) {
-#ifdef USE_MANUAL_CALLSTACK
-  call_stack.enter("checkpoint()");
-#endif 
-  int retval=0, i, l=xml_indent_level;
-  xml_indent_level=0;
-// Making state_file static to avoid overhead of reallocating of buffers on 
-// every call.  
-  static MFILE state_file;
-  char buf[2048];
-  std::string enc_field, str;
-
-  // The user may have set preferences for a long time between
-  // checkpoints to reduce disk access.
-  if (!force_checkpoint) {
-    if (!boinc_time_to_checkpoint()) {
-#ifdef USE_MANUAL_CALLSTACK
-      call_stack.exit();
-#endif 
-      return CHECKPOINT_SKIPPED;
-    }
-  }
-
-  fflush(stderr);
-
-// debug possible heap corruption -- jeffc
-#ifdef _WIN32
-BOINCASSERT(_CrtCheckMemory());
-#endif
-
-  if (state_file.open(STATE_FILENAME, "wb")) SETIERROR(CANT_CREATE_FILE,"in checkpoint()");
-  retval = state_file.printf(
-             "<ncfft>%d</ncfft>\n"
-             "<cr>%e</cr>\n"
-             "<fl>%d</fl>\n"
-             "<prog>%.8f</prog>\n"
-             "<potfreq>%d</potfreq>\n"
-             "<potactivity>%d</potactivity>\n"
-             "<signal_count>%d</signal_count>\n"
-             "<flops>%f</flops>\n"
-             "<spike_count>%d</spike_count>\n"
-             "<autocorr_count>%d</autocorr_count>\n"
-             "<pulse_count>%d</pulse_count>\n"
-             "<gaussian_count>%d</gaussian_count>\n"
-             "<triplet_count>%d</triplet_count>\n",
-             analysis_state.icfft,
-             ChirpFftPairs[analysis_state.icfft].ChirpRate,
-             ChirpFftPairs[analysis_state.icfft].FftLen,
-	     std::min(progress,0.9999999),
-             analysis_state.PoT_freq_bin,
-             analysis_state.PoT_activity,
-             signal_count,
-             analysis_state.FLOP_counter,
-             spike_count,
-	     autocorr_count,
-             pulse_count,
-             gaussian_count,
-             triplet_count
-           );
-  if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
-
-  // checkpoint the best spike thus far (if any)
-  if(best_spike->s.fft_len) {
-    retval = state_file.printf("<best_spike>\n");
-    if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
-    // the spike proper
-    str = best_spike->s.print_xml(0,0,1);
-    retval = (int)state_file.write(str.c_str(), str.size(), 1);
-    // ancillary data
-    retval = state_file.printf(
-               "<bs_score>%f</bs_score>\n"
-               "<bs_bin>%d</bs_bin>\n"
-               "<bs_fft_ind>%d</bs_fft_ind>\n",
-               best_spike->score,
-               best_spike->bin,
-               best_spike->fft_ind);
-    if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
-    retval = state_file.printf("</best_spike>\n");
-    if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
-  }
-
-  // checkpoint the best autocorr thus far (if any)
-  if(best_autocorr->a.fft_len) {
-    retval = state_file.printf("<best_autocorr>\n");
-    if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
-    // the autocorr proper
-    str = best_autocorr->a.print_xml(0,0,1);
-    retval = (int)state_file.write(str.c_str(), str.size(), 1);
-    // ancillary data
-    retval = state_file.printf(
-               "<ba_score>%f</ba_score>\n"
-               "<ba_bin>%d</ba_bin>\n"
-               "<ba_fft_ind>%d</ba_fft_ind>\n",
-               best_autocorr->score,
-               best_autocorr->bin,
-               best_autocorr->fft_ind);
-    if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
-    retval = state_file.printf("</best_autocorr>\n");
-    if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
-  }
-
-  // checkpoint the best gaussian thus far (if any)
-  if(best_gauss->g.fft_len || best_gauss->score) {
-    retval = state_file.printf("<best_gaussian>\n");
-    if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
-    // the gaussian proper 
-    str = best_gauss->g.print_xml(0,0,1);
-    retval = (int)state_file.write(str.c_str(), str.size(), 1);
-    // ancillary data
-    retval = state_file.printf(
-               "<bg_score>%f</bg_score>\n"
-               "<bg_display_power_thresh>%f</bg_display_power_thresh>\n"
-               "<bg_bin>%d</bg_bin>\n"
-               "<bg_fft_ind>%d</bg_fft_ind>\n",
-               best_gauss->score,
-               best_gauss->display_power_thresh,
-               best_gauss->bin,
-               best_gauss->fft_ind);
-    if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
-    retval = state_file.printf("</best_gaussian>\n");
-    if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
-  }
-
-  // checkpoint the best pulse thus far (if any)
-  // The check for len_prof is a kludge.
-  if(best_pulse->p.fft_len) {
-    retval = state_file.printf("<best_pulse>\n");
-    if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
-    // the pulse proper 
-    str = best_pulse->p.print_xml(0,0,1);
-    retval = (int)state_file.write(str.c_str(), str.size(), 1);
-    // ancillary data
-    retval = state_file.printf(
-               "<bp_score>%f</bp_score>\n"
-               "<bp_freq_bin>%d</bp_freq_bin>\n"
-               "<bp_time_bin>%d</bp_time_bin>\n",
-               best_pulse->score,
-               best_pulse->freq_bin,
-               best_pulse->time_bin);
-    if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
-    retval = state_file.printf("</best_pulse>\n");
-    if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
-  }
-
-  // checkpoint the best triplet thus far (if any)
-  if(best_triplet->t.fft_len) {
-    retval = state_file.printf("<best_triplet>\n");
-    if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
-    // the triplet proper 
-    str = best_triplet->t.print_xml(0,0,1);
-    retval = (int)state_file.write(str.c_str(), str.size(), 1);
-
-    // ancillary data
-    retval = state_file.printf(
-               "<bt_score>%f</bt_score>\n"
-               "<bt_bperiod>%f</bt_bperiod>\n"
-               "<bt_tpotind0_0>%d</bt_tpotind0_0>\n"
-               "<bt_tpotind0_1>%d</bt_tpotind0_1>\n"
-               "<bt_tpotind1_0>%d</bt_tpotind1_0>\n"
-               "<bt_tpotind1_1>%d</bt_tpotind1_1>\n"
-               "<bt_tpotind2_0>%d</bt_tpotind2_0>\n"
-               "<bt_tpotind2_1>%d</bt_tpotind2_1>\n"
-               "<bt_freq_bin>%d</bt_freq_bin>\n"
-               "<bt_time_bin>%f</bt_time_bin>\n"
-               "<bt_scale>%f</bt_scale>\n",
-               best_triplet->score,
-               best_triplet->bperiod,
-               best_triplet->tpotind0_0,
-               best_triplet->tpotind0_1,
-               best_triplet->tpotind1_0,
-               best_triplet->tpotind1_1,
-               best_triplet->tpotind2_0,
-               best_triplet->tpotind2_1,
-               best_triplet->freq_bin,
-               best_triplet->time_bin,
-               best_triplet->scale);
-    if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
-
-   // convert min PoT to chars, encode, and print
-   for (i=0; i<swi.analysis_cfg.triplet_pot_length; i++) {
-	buf[i] = (unsigned char)best_triplet->pot_min[i];
-   }
-   enc_field=xml_encode_string(buf, swi.analysis_cfg.triplet_pot_length, _x_csv);
-   retval = state_file.printf(
-         "<bt_pot_min length=%d encoding=\"%s\">",
-		 enc_field.size(), xml_encoding_names[_x_csv]
-   );
-   if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
-   state_file.write(enc_field.c_str(), enc_field.size(), 1);
-   retval = state_file.printf("</bt_pot_min>\n");
-   if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
-
-   // convert max PoT to chars, encode, and print
-   for (i=0; i<swi.analysis_cfg.triplet_pot_length; i++) {
-	buf[i] = (unsigned char)best_triplet->pot_max[i];
-   }
-   enc_field=xml_encode_string(buf, swi.analysis_cfg.triplet_pot_length, _x_csv);
-   state_file.printf(
-       "<bt_pot_max length=%d encoding=\"%s\">",
-	 enc_field.size(), xml_encoding_names[_x_csv]
-   );
-   if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
-   state_file.write(enc_field.c_str(), enc_field.size(), 1);
-   retval = state_file.printf("</bt_pot_max>\n");
-   if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
-   retval = state_file.printf("</best_triplet>\n");
-   if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
-  }
-
-  if (BaseLineSmooth != NULL) {
-   for (i=0;i<num_BLS;i++) {
-     if ( BaseLineSmoothFuncs[i].func == BaseLineSmooth ) {
-       state_file.printf("<baseline_smooth>%s</baseline_smooth>\n",
-         BaseLineSmoothFuncs[i].nom);
-       break;
-     }
-   }
-  }
-
-  if (GetPowerSpectrum != NULL) {
-   for (i=0;i<num_GPS;i++) {
-     if ( GetPowerSpectrumFuncs[i].func == GetPowerSpectrum ) {
-       state_file.printf("<get_power_spectrum>%s</get_power_spectrum>\n",
-         GetPowerSpectrumFuncs[i].nom);
-       break;
-     }
-   }
-  }
-
-  if (ChirpData != NULL) {
-   for (i=0;i<num_CD;i++) {
-     if ( ChirpDataFuncs[i].func == ChirpData ) {
-       state_file.printf("<chirp_data>%s</chirp_data>\n",
-         ChirpDataFuncs[i].nom);
-       break;
-     }
-   }
-  }
-
-  if (Transpose != NULL) {
-   for (i=0;i<num_TP;i++) {
-     if ( TransposeFuncs[i].func == Transpose ) {
-       state_file.printf("<transpose>%s</transpose>\n",
-         TransposeFuncs[i].nom);
-       break;
-     }
-   }
-  }
-
-  if (strlen(Foldmain.name) != 0) {
-   state_file.printf("<folding>%s</folding>\n",
-      Foldmain.name);
-  }
-
-  // The result (outfile) and state mfiles are now synchronized.
-  // Flush them both.
-  retval = outfile.flush();
-  if (retval) SETIERROR(WRITE_FAILED,"in checkpoint()");
-  retval = state_file.flush();
-  if (retval) SETIERROR(WRITE_FAILED,"in checkpoint()");
-  retval = state_file.close();
-  if (retval) SETIERROR(WRITE_FAILED,"in checkpoint()");
-  boinc_checkpoint_completed();
-  xml_indent_level=l;
-
-// debug possible heap corruption -- jeffc
-#ifdef _WIN32
-BOINCASSERT(_CrtCheckMemory());
-#endif
-#ifdef USE_MANUAL_CALLSTACK
-  call_stack.exit();
-#endif 
-  return 0;
-}
-
-// Read the state file and set analysis_state accordingly.
-// Note: The state of analysis is saved in two places:
-// 1) at the end of processing the data for any given
-//    chirp/fft pair.  In this case, the icfft index
-//    needs to be set for the *next* chirp/fft pair.
-//    If analysis was in this state when saved,
-//    PoT_freq_bin will have been set to -1.
-// 2) at the end of PoT processing for any given
-//    frequency bin (for any given chirp/fft pair).
-//    This is indicated by PoT_freq_bin containing
-//    something other than -1.  It will contain the
-//    frequency bin just completed. In this case, we
-//    are *not* finished processing for the current
-//    chirp/fft pair and we do not increment icfft to
-//    the next pair.  We do however increment PoT_freq_bin
-//    to the next frequency bin.
-//
-int parse_state_file(ANALYSIS_STATE& as) {
-  static char buf[8192];
-  std::string fname;
-  int ncfft, fl, PoT_freq_bin, PoT_activity;
-  double cr=0,flops=0;
-  FILE* state_file;
-#ifdef USE_MANUAL_CALLSTACK
-  call_stack.enter("parse_state_file()");
-#endif 
-// debug possible heap corruption -- jeffc
-#ifdef _WIN32
-BOINCASSERT(_CrtCheckMemory());
-#endif
-
-  ncfft = -1;
-  progress = 0.0;
-  PoT_freq_bin = -1;
-  PoT_activity = POT_INACTIVE;
-  state_file = boinc_fopen(STATE_FILENAME, "rb");
-  if (!state_file) SETIERROR(FOPEN_FAILED,"in parse_state_file()");
-
-  // main parsing loop
-  while (fgets(buf, sizeof(buf), state_file)) {
-    if (parse_int(buf, "<ncfft>", ncfft)) continue;
-    else if (parse_double(buf, "<cr>", cr)) continue;
-    else if (parse_int(buf, "<fl>", fl)) continue;   
-    else if (parse_double(buf, "<prog>", progress)) continue;
-    else if (parse_int(buf, "<potfreq>", PoT_freq_bin)) continue;
-    else if (parse_int(buf, "<potactivity>", PoT_activity)) continue;
-    else if (parse_int(buf, "<signal_count>", signal_count)) continue;
-    else if (parse_double(buf, "<flops>", flops)) continue;
-    else if (parse_int(buf, "<spike_count>", spike_count)) continue;
-    else if (parse_int(buf, "<autocorr_count>", autocorr_count)) continue;
-    else if (parse_int(buf, "<pulse_count>", pulse_count)) continue;
-    else if (parse_int(buf, "<gaussian_count>", gaussian_count)) continue;
-    else if (parse_int(buf, "<triplet_count>", triplet_count)) continue;
-    // best spike
-    else if (xml_match_tag(buf, "<best_spike>")) {
-      while (fgets(buf, sizeof(buf), state_file)) {
-        if (xml_match_tag(buf, "</best_spike>")) break;
-        // spike proper
-        else if (xml_match_tag(buf, "<spike>")) {
-	  char *p = buf + strlen(buf);
-          while(fgets(p, sizeof(buf)-(int)strlen(buf), state_file)) {
-            if (xml_match_tag(buf, "</spike>")) break;
-	    p += strlen(p);
-          } 
-          best_spike->s.parse_xml(buf);
-        }
-        // ancillary data
-        else if (parse_double(buf, "<bs_score>", best_spike->score)) continue;
-        else if (parse_int(buf, "<bs_bin>", best_spike->bin)) continue;
-        else if (parse_int(buf, "<bs_fft_ind>", best_spike->fft_ind)) continue;
-      } // end while in best_spike
-    }  // end if in best_spike
-
-    // best autocorr
-    else if (xml_match_tag(buf, "<best_autocorr>")) {
-      while (fgets(buf, sizeof(buf), state_file)) {
-        if (xml_match_tag(buf, "</best_autocorr>")) break;
-        // autocorr proper
-        else if (xml_match_tag(buf, "<autocorr>")) {
-	  char *p = buf + strlen(buf);
-          while(fgets(p, sizeof(buf)-(int)strlen(buf), state_file)) {
-            if (xml_match_tag(buf, "</autocorr>")) break;
-	    p += strlen(p);
-          } 
-          best_autocorr->a.parse_xml(buf);
-        }
-        // ancillary data
-        else if (parse_double(buf, "<ba_score>", best_autocorr->score)) continue;
-        else if (parse_int(buf, "<ba_bin>", best_autocorr->bin)) continue;
-        else if (parse_int(buf, "<ba_fft_ind>", best_autocorr->fft_ind)) continue;
-      } // end while in best_autocorr
-    }  // end if in best_autocorr
-
-    // best gaussian..
-    else if (xml_match_tag(buf, "<best_gaussian>")) {
-      while (fgets(buf, sizeof(buf), state_file)) {
-        if (xml_match_tag(buf, "</best_gaussian>")) break;
-        // gaussian proper
-        else if (xml_match_tag(buf, "<gaussian>")) {
-	  char *p = buf + strlen(buf);
-          while(fgets(p, sizeof(buf)-(int)strlen(buf), state_file)) {
-            if (xml_match_tag(buf, "</gaussian>")) break;
-	    p += strlen(p);
-          } 
-          best_gauss->g.parse_xml(buf);
-        }
-        // ancillary data
-        else if (parse_double(buf, "<bg_score>", best_gauss->score)) continue;
-        else if (parse_double(buf, "<bg_display_power_thresh>", 
-		best_gauss->display_power_thresh)) continue;
-        else if (parse_int(buf, "<bg_bin>", best_gauss->bin)) continue ;
-        else if (parse_int(buf, "<bg_fft_ind>", best_gauss->fft_ind)) continue;
-      }  // end while in best_gaissian
-    }  // end if in best_gaussian
-
-    // best pulse
-    else if (xml_match_tag(buf, "<best_pulse>")) {
-      while (fgets(buf, sizeof(buf), state_file)) {
-        if (xml_match_tag(buf, "</best_pulse>")) break;
-        // pulse proper
-        else if (xml_match_tag(buf, "<pulse>")) {
-	  char *p = buf + strlen(buf);
-          while(fgets(p, sizeof(buf)-(int)strlen(buf), state_file)) {
-            if (xml_match_tag(buf, "</pulse>")) break;
-	    p += strlen(p);
-          } 
-          best_pulse->p.parse_xml(buf);
-        }
-        // ancillary data
-        else if (parse_double(buf, "<bp_score>", best_pulse->score)) continue;
-        else if (parse_int(buf, "<bp_freq_bin>", best_pulse->freq_bin)) continue;
-        else if (parse_int(buf, "<bp_time_bin>", best_pulse->time_bin)) continue;
-      }  // end while in best_pulse
-    }  // end if in best_pulse
-
-    // best triplet
-    else if (xml_match_tag(buf, "<best_triplet>")) {
-      while (fgets(buf, sizeof(buf), state_file)) {
-        if (xml_match_tag(buf, "</best_triplet>")) break;
-        // triplet proper
-        else if (xml_match_tag(buf, "<triplet>")) {
-	  char *p = buf + strlen(buf);
-          while(fgets(p, sizeof(buf)-(int)strlen(buf), state_file)) {
-            if (xml_match_tag(buf, "</triplet>")) break;
-	    p += strlen(p);
-          } 
-          best_triplet->t.parse_xml(buf);
-        }
-        // ancillary data
-        else if (parse_double(buf, "<bt_score>", best_triplet->score)) continue;
-        else if (parse_double(buf, "<bt_bperiod>", best_triplet->bperiod)) continue;
-        else if (parse_int(buf, "<bt_tpotind0_0>", best_triplet->tpotind0_0)) continue;
-        else if (parse_int(buf, "<bt_tpotind0_1>", best_triplet->tpotind0_1)) continue;
-        else if (parse_int(buf, "<bt_tpotind1_0>", best_triplet->tpotind1_0)) continue;
-        else if (parse_int(buf, "<bt_tpotind1_1>", best_triplet->tpotind1_1)) continue;
-        else if (parse_int(buf, "<bt_tpotind2_0>", best_triplet->tpotind2_0)) continue;
-        else if (parse_int(buf, "<bt_tpotind2_1>", best_triplet->tpotind2_1)) continue;
-        else if (parse_int(buf, "<bt_freq_bin>", best_triplet->freq_bin)) continue;
-        else if (parse_double(buf, "<bt_time_bin>", best_triplet->time_bin)) continue;
-        else if (parse_double(buf, "<bt_scale>", best_triplet->scale)) continue;
- 	else if (xml_match_tag(buf, "<bt_pot_min")) {
-	  char *p = buf + strlen(buf);
-          while(fgets(p, sizeof(buf)-(int)strlen(buf), state_file)) {
-            if (xml_match_tag(buf, "</bt_pot_min")) break;
-	    p += strlen(p);
-          } 
-	  std::vector<unsigned char> pot_min(
-	    xml_decode_field<unsigned char>(buf,"bt_pot_min")
-	  );
-	  int i;
-	  for (i=0; i<swi.analysis_cfg.triplet_pot_length; i++) {
-	    best_triplet->pot_min[i] = pot_min[i];
-	  }
-	}  // end Min PoT
- 	else if (xml_match_tag(buf, "<bt_pot_max")) {
-	  char *p = buf + strlen(buf);
-          while(fgets(p, sizeof(buf)-(int)strlen(buf), state_file)) {
-            if (xml_match_tag(buf, "</bt_pot_max")) break;
-	    p += strlen(p);
-          } 
-	  std::vector<unsigned char> pot_max(
-	    xml_decode_field<unsigned char>(buf,"bt_pot_max")
-	  );
-	  int i;
-	  for (i=0; i<swi.analysis_cfg.triplet_pot_length; i++) {
-	    best_triplet->pot_max[i] = pot_max[i];
-	  }
-	}  // end Max PoT
-      }  // end while in best_triplet
-    }  // end if in best_triplet
-
-    // Restore best functions that were determined earlier.
-    else if (parse_str(buf,"<baseline_smooth>",fname)) {
-      int i; 
-      for (i=0;i<num_BLS;i++) {
-        if (strcmp(fname.c_str(),BaseLineSmoothFuncs[i].nom)==0) {
-          BaseLineSmooth=BaseLineSmoothFuncs[i].func;
-          found_baseline_smooth=true;
-          break;
-        }
-      }
-    }
-
-    else if (parse_str(buf,"<get_power_spectrum>",fname)) {
-      int i; 
-      for (i=0;i<num_GPS;i++) {
-        if (strcmp(fname.c_str(),GetPowerSpectrumFuncs[i].nom)==0) {
-          GetPowerSpectrum=GetPowerSpectrumFuncs[i].func;
-          found_get_power_spectrum=true;
-          break;
-        }
-      }
-    }
-
-    else if (parse_str(buf,"<chirp_data>",fname)) {
-      int i; 
-      for (i=0;i<num_CD;i++) {
-        if (strcmp(fname.c_str(),ChirpDataFuncs[i].nom)==0) {
-          ChirpData=ChirpDataFuncs[i].func;
-          found_chirp_data=true;
-          break;
-        }
-      }
-    }
-
-    else if (parse_str(buf,"<transpose>",fname)) {
-      int i; 
-      for (i=0;i<num_TP;i++) {
-        if (strcmp(fname.c_str(),TransposeFuncs[i].nom)==0) {
-          Transpose=TransposeFuncs[i].func;
-          found_transpose=true;
-          break;
-        }
-      }
-    }
-
-    else if (parse_str(buf,"<folding>",fname)) {
-      int i; 
-      for (i=0;i<num_FS;i++) {
-        if (strcmp(fname.c_str(),FoldSubs[i].fsp->name)==0) {
-          CopyFoldSet(&Foldmain,FoldSubs[i].fsp);
-          found_folding=true;
-          break;
-        }
-      }
-    }
-
-  }  // end main parsing loop
-
-  fclose(state_file);
-
-  analysis_state.FLOP_counter=flops;
-  reload_graphics_state();	// so we can draw best_of signals
-
-  // Adjust for restart - go 1 step beyond the checkpoint.
-  as.PoT_activity = PoT_activity;
-  if(PoT_freq_bin == -1) {
-    as.icfft        = ncfft+1;
-    as.PoT_freq_bin = PoT_freq_bin;
-  } else {
-    as.icfft        = ncfft;
-    as.PoT_freq_bin = PoT_freq_bin+1;
-  }
-
-// debug possible heap corruption -- jeffc
-#ifdef _WIN32
-BOINCASSERT(_CrtCheckMemory());
-#endif
-#ifdef USE_MANUAL_CALLSTACK
-  call_stack.exit();
-#endif 
-  return 0;
-}
-
-// On entry, analysis_state.data points to malloced data
-// and outfile is not open.
-// On exit, these are freed and closed
-int seti_do_work() {
-  int retval=0;
-#ifdef USE_MANUAL_CALLSTACK
-  call_stack.enter("seti_do_work()");
-#endif 
-  retval = seti_analyze(analysis_state);
-  free_a(analysis_state.data);
-  analysis_state.data = 0;
-
-  if( swi.data_type == DATA_ENCODED ) {
-      free_a(analysis_state.savedWUData);
-      analysis_state.savedWUData = 0;
-  }
-#ifdef USE_MANUAL_CALLSTACK
-  call_stack.exit();
-#endif 
-  return retval;
-}
-
-// on success, swi.data points to malloced data.
-int seti_parse_data(FILE* f, ANALYSIS_STATE& state) {
-  unsigned long nbytes, nsamples,samples_per_byte;
-  sah_complex *data;
-  unsigned long i;
-  char *p, buf[256];
-  sah_complex *bin_data=0;
-  int retval=0;
-  FORCE_FRAME_POINTER;
-#ifdef USE_MANUAL_CALLSTACK
-  call_stack.enter("seti_parse_data()");
-#endif 
-
-  nsamples = swi.nsamples;
-  samples_per_byte=(8/swi.bits_per_sample);
-  data = (sah_complex *)malloc_a(nsamples*sizeof(sah_complex), MEM_ALIGN);
-  bin_data = (sah_complex *)malloc_a(nsamples*sizeof(sah_complex), MEM_ALIGN);
-  if (!data) SETIERROR(MALLOC_FAILED, "!data");
-  if (!bin_data) SETIERROR(MALLOC_FAILED, "!bin_data");
-
-  switch(swi.data_type) {
-    case DATA_ASCII:
-      for (i=0; i<nsamples; i++) {
-        p = fgets(buf, 256, f);
-        if (!p) {
-          SETIERROR(READ_FAILED,"in seti_parse_data");
-        }
-
-        sscanf(buf, "%f%f", &data[i][0], &data[i][1]);
-      }
-      break;
-    case DATA_ENCODED:
-    case DATA_SUN_BINARY:
-      try {
-        int nread;
-        std::string tmpbuf("");
-        fseek(f,0,SEEK_SET);
-        nbytes = (nsamples/samples_per_byte);
-        tmpbuf.reserve(nbytes*3/2);
-        while ((nread=(int)fread(buf,1,sizeof(buf),f))) {
-          tmpbuf+=std::string(&(buf[0]),nread);
-        }
-        std::vector<unsigned char> datav(
-           xml_decode_field<unsigned char>(tmpbuf,"data") 
-        );
-	
-        memcpy(bin_data,&(datav[0]),datav.size());
-        if (datav.size() < nbytes) throw BAD_DECODE;
-      } catch (int i) {
-          retval=i;
-          if (data) free_a(data);
-          if (bin_data) free_a(bin_data);
-          SETIERROR(i,"in seti_parse_data()");
-      }
-      bits_to_floats((unsigned char *)bin_data, data, nsamples,swi.bits_per_sample);
-      memcpy(bin_data,data,nsamples*sizeof(sah_complex));
-      state.savedWUData = bin_data;
-      break;
-  }
-  state.npoints = nsamples;
-  state.data = data;
-
-#ifdef BOINC_APP_GRAPHICS
-  if (sah_graphics) {
-      strlcpy(sah_graphics->wu.receiver_name,swi.receiver_cfg.name,255);
-      sah_graphics->wu.s4_id = swi.receiver_cfg.s4_id;
-      sah_graphics->wu.time_recorded = swi.time_recorded;
-      sah_graphics->wu.subband_base = swi.subband_base;
-      sah_graphics->wu.start_ra = swi.start_ra;
-      sah_graphics->wu.start_dec = swi.start_dec;
-      sah_graphics->wu.subband_sample_rate = swi.subband_sample_rate;
-      sah_graphics->ready = true;
-  }
-#endif
-#ifdef USE_MANUAL_CALLSTACK
-  call_stack.exit();
-#endif 
-  return 0;
-}
-
-int seti_parse_wu(FILE* f, ANALYSIS_STATE& state) {
-  int retval=0;
-#ifdef USE_MANUAL_CALLSTACK
-  call_stack.enter("seti_parse_wu()");
-#endif 
-  retval = seti_parse_wu_header(f);
-  if (retval) SETIERROR(retval,"from seti_parse_wu_header()");
-  retval=seti_parse_data(f, state);
-#ifdef USE_MANUAL_CALLSTACK
-  call_stack.exit();
-#endif 
-  return retval;
-}
-
-void final_report() {
-#ifdef USE_MANUAL_CALLSTACK
-  call_stack.enter("final_report()");
-#endif 
+// Copyright 2003 Regents of the University of California
+
+// SETI_BOINC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2, or (at your option) any later
+// version.
+
+// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+// more details.
+
+// You should have received a copy of the GNU General Public License along
+// with SETI_BOINC; see the file COPYING.  If not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+// In addition, as a special exception, the Regents of the University of
+// California give permission to link the code of this program with libraries
+// that provide specific optimized fast Fourier transform (FFT) functions and
+// distribute a linked executable.  You must obey the GNU General Public 
+// License in all respects for all of the code used other than the FFT library
+// itself.  Any modification required to support these libraries must be
+// distributed in source code form.  If you modify this file, you may extend 
+// this exception to your version of the file, but you are not obligated to 
+// do so. If you do not wish to do so, delete this exception statement from 
+// your version.
+
+// seti.C
+// $Id: seti.cpp,v 1.60.2.19 2007/08/10 00:38:49 korpela Exp $
+//
+// SETI-specific logic for reading/writing checkpoint files
+// and parsing WU files.
+//
+// Files:
+// state.txt
+// the last chirp rate / FFT len finished, if any
+// outfile.txt
+// The append-only result file
+//
+// What finally gets sent back as the result file is:
+// - the generic result header, with the final CPU time filled in
+// - the SETI-specific part of the WU header
+// - the contents of outfile.txt
+
+#include "sah_config.h"
+
+#include <cstdio>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <cstdlib>
+#include <cstring>
+#include <string>
+
+#ifdef BOINC_APP_GRAPHICS
+#include "sah_gfx_main.h"
+#endif
+
+#ifdef HAVE_IEEEFP_H
+#include <ieeefp.h>
+#endif
+
+#include "boinc_api.h"
+#include "str_util.h"
+#include "str_replace.h"
+
+#include "diagnostics.h"
+#include "parse.h"
+#include "filesys.h"
+#include "s_util.h"
+#include "seti_header.h"
+#include "analyze.h"
+#include "analyzeFuncs.h"
+#include "vector/analyzeFuncs_vector.h"
+#include "pulsefind.h"
+#include "analyzeReport.h"
+#include "analyzePoT.h"
+#include "malloc_a.h"
+#include "chirpfft.h"
+#include "worker.h"
+
+#include "seti.h"
+
+#define DATA_ASCII 1
+#define DATA_ENCODED 2
+#define DATA_SUN_BINARY 3
+
+APP_INIT_DATA app_init_data;
+
+ANALYSIS_STATE analysis_state;
+static int wrote_header;
+double LOAD_STORE_ADJUSTMENT=2.85;
+double SETUP_FLOPS=1.42e+10/2.85;
+
+SPIKE_INFO::SPIKE_INFO() : track_mem<SPIKE_INFO>("SPIKE_INFO"),s(), score(0), bin(0), fft_ind(0) {}
+ 
+SPIKE_INFO::~SPIKE_INFO() {}
+
+SPIKE_INFO::SPIKE_INFO(const SPIKE_INFO &si) : track_mem<SPIKE_INFO>("SPIKE_INFO"),
+s(si.s), score(si.score), bin(si.bin), fft_ind(si.fft_ind) {}
+
+SPIKE_INFO &SPIKE_INFO::operator =(const SPIKE_INFO &si) {
+#ifdef USE_MANUAL_CALLSTACK
+  call_stack.enter("SPIKE_INFO::operator =");
+#endif 
+  if (&si != this) {
+    s=si.s;
+    score=si.score;
+    bin=si.bin;
+    fft_ind=si.fft_ind;
+  }
+#ifdef USE_MANUAL_CALLSTACK
+  call_stack.exit();
+#endif 
+  return *this;
+}
+
+AUTOCORR_INFO::AUTOCORR_INFO() : track_mem<AUTOCORR_INFO>("AUTOCORR_INFO"),a(), score(0), bin(0), fft_ind(0) {}
+ 
+AUTOCORR_INFO::~AUTOCORR_INFO() {}
+
+AUTOCORR_INFO::AUTOCORR_INFO(const AUTOCORR_INFO &ai) : track_mem<AUTOCORR_INFO>("AUTOCORR_INFO"),
+a(ai.a), score(ai.score), bin(ai.bin), fft_ind(ai.fft_ind) {}
+
+AUTOCORR_INFO &AUTOCORR_INFO::operator =(const AUTOCORR_INFO &ai) {
+#ifdef USE_MANUAL_CALLSTACK
+  call_stack.enter("AUTOCORR_INFO::operator =");
+#endif 
+  if (&ai != this) {
+    a=ai.a;
+    score=ai.score;
+    bin=ai.bin;
+    fft_ind=ai.fft_ind;
+  }
+#ifdef USE_MANUAL_CALLSTACK
+  call_stack.exit();
+#endif 
+  return *this;
+}
+
+
+GAUSS_INFO::GAUSS_INFO() : track_mem<GAUSS_INFO>("GAUSS_INFO"),
+g(), score(0), display_power_thresh(0), bin(0), fft_ind(0) {
+}
+
+GAUSS_INFO::~GAUSS_INFO() {}
+
+GAUSS_INFO::GAUSS_INFO(const GAUSS_INFO &gi) : track_mem<GAUSS_INFO>("GAUSS_INFO"),
+g(gi.g), score(gi.score), bin(gi.bin), fft_ind(gi.fft_ind) {
+}
+
+GAUSS_INFO &GAUSS_INFO::operator =(const GAUSS_INFO &gi) {
+#ifdef USE_MANUAL_CALLSTACK
+  call_stack.enter("GAUSS_INFO::operator =");
+#endif 
+  if (&gi != this) {
+    g=gi.g;
+    score=gi.score;
+    bin=gi.bin;
+    fft_ind=gi.fft_ind;
+  }
+#ifdef USE_MANUAL_CALLSTACK
+  call_stack.exit();
+#endif 
+  return *this;
+}
+
+PULSE_INFO::PULSE_INFO() : track_mem<PULSE_INFO>("PULSE_INFO"), p(), score(0), freq_bin(0), time_bin(0) {
+
+#ifdef USE_MANUAL_CALLSTACK
+  call_stack.enter("PULSE_INFO::PULSE_INFO()");
+#endif 
+// debug possible heap corruption -- jeffc
+#ifdef _WIN32
+BOINCASSERT(_CrtCheckMemory());
+#endif
+
+    pot_min = (unsigned int *)calloc_a(swi.analysis_cfg.pulse_pot_length, sizeof(unsigned int), MEM_ALIGN);
+    if (pot_min == NULL) SETIERROR(MALLOC_FAILED, "new PULSE_INFO pot_min == NULL");
+    pot_max = (unsigned int *)calloc_a(swi.analysis_cfg.pulse_pot_length, sizeof(unsigned int), MEM_ALIGN);
+    if (pot_max == NULL) SETIERROR(MALLOC_FAILED, "new PULSE_INFO pot_max == NULL");
+
+// debug possible heap corruption -- jeffc
+#ifdef _WIN32
+BOINCASSERT(_CrtCheckMemory());
+#endif
+#ifdef USE_MANUAL_CALLSTACK
+    call_stack.exit();
+#endif 
+}
+
+
+PULSE_INFO::~PULSE_INFO() { 
+// debug possible heap corruption -- jeffc
+#ifdef _WIN32
+BOINCASSERT(_CrtCheckMemory());
+#endif
+#ifdef USE_MANUAL_CALLSTACK
+    call_stack.enter("PULSE_INFO::~PULSE_INFO()");
+#endif 
+    free_a(pot_min); 
+    free_a(pot_max); 
+
+// debug possible heap corruption -- jeffc
+#ifdef _WIN32
+BOINCASSERT(_CrtCheckMemory());
+#endif
+#ifdef USE_MANUAL_CALLSTACK
+    call_stack.exit();
+#endif 
+}
+
+
+PULSE_INFO::PULSE_INFO(const PULSE_INFO &pi) : track_mem<PULSE_INFO>("PULSE_INFO"),  
+p(pi.p), score(pi.score), freq_bin(pi.freq_bin), time_bin(pi.time_bin) {
+#ifdef USE_MANUAL_CALLSTACK
+    call_stack.enter("PULSE_INFO::PULSE_INFO(const PULSE_INFO &pi)");
+#endif 
+// debug possible heap corruption -- jeffc
+#ifdef _WIN32
+BOINCASSERT(_CrtCheckMemory());
+#endif
+
+    pot_min = (unsigned int *)calloc_a(swi.analysis_cfg.pulse_pot_length, sizeof(unsigned int), MEM_ALIGN);
+    if (pot_min == NULL) SETIERROR(MALLOC_FAILED, "copied PULSE_INFO pot_min == NULL");
+    pot_max = (unsigned int *)calloc_a(swi.analysis_cfg.pulse_pot_length, sizeof(unsigned int), MEM_ALIGN);
+    if (pot_max == NULL) SETIERROR(MALLOC_FAILED, "copied PULSE_INFO pot_max == NULL");
+
+    memcpy(pot_min,pi.pot_min,(swi.analysis_cfg.pulse_pot_length * sizeof(unsigned int)));
+    memcpy(pot_max,pi.pot_max,(swi.analysis_cfg.pulse_pot_length * sizeof(unsigned int)));
+
+// debug possible heap corruption -- jeffc
+#ifdef _WIN32
+BOINCASSERT(_CrtCheckMemory());
+#endif
+#ifdef USE_MANUAL_CALLSTACK
+    call_stack.exit();
+#endif 
+}
+
+PULSE_INFO &PULSE_INFO::operator =(const PULSE_INFO &pi) {
+#ifdef USE_MANUAL_CALLSTACK
+  call_stack.enter("PULSE_INFO::operator =");
+#endif 
+// debug possible heap corruption -- jeffc
+#ifdef _WIN32
+BOINCASSERT(_CrtCheckMemory());
+#endif
+
+  if (&pi != this) {
+    p=pi.p;
+    score=pi.score;
+    freq_bin=pi.freq_bin;
+    time_bin=pi.time_bin;
+
+    memcpy(pot_min,pi.pot_min,(swi.analysis_cfg.pulse_pot_length * sizeof(unsigned int)));
+    memcpy(pot_max,pi.pot_max,(swi.analysis_cfg.pulse_pot_length * sizeof(unsigned int)));
+  }
+
+// debug possible heap corruption -- jeffc
+#ifdef _WIN32
+BOINCASSERT(_CrtCheckMemory());
+#endif
+#ifdef USE_MANUAL_CALLSTACK
+  call_stack.exit();
+#endif 
+  return *this;
+}
+
+TRIPLET_INFO::TRIPLET_INFO() : track_mem<TRIPLET_INFO>("TRIPLET_INFO"),
+t(), score(0), bperiod(0), freq_bin(0), tpotind0_0(0), tpotind0_1(0), 
+tpotind1_0(0), tpotind1_1(0), tpotind2_0(0), tpotind2_1(0), time_bin(0), 
+scale(0) {
+#ifdef USE_MANUAL_CALLSTACK
+    call_stack.enter("TRIPLET_INFO::TRIPLET_INFO()");
+#endif 
+// debug possible heap corruption -- jeffc
+#ifdef _WIN32
+BOINCASSERT(_CrtCheckMemory());
+#endif
+
+    pot_min = (unsigned int *)calloc_a(swi.analysis_cfg.triplet_pot_length, sizeof(unsigned int), MEM_ALIGN);
+    if (pot_min == NULL) SETIERROR(MALLOC_FAILED, "new TRIPLET_INFO pot_min == NULL");
+    pot_max = (unsigned int *)calloc_a(swi.analysis_cfg.triplet_pot_length, sizeof(unsigned int), MEM_ALIGN);
+    if (pot_max == NULL) SETIERROR(MALLOC_FAILED, "new TRIPLET_INFO pot_max == NULL");
+
+// debug possible heap corruption -- jeffc
+#ifdef _WIN32
+BOINCASSERT(_CrtCheckMemory());
+#endif
+#ifdef USE_MANUAL_CALLSTACK
+    call_stack.exit();
+#endif 
+}
+
+TRIPLET_INFO::TRIPLET_INFO(const TRIPLET_INFO &ti) : track_mem<TRIPLET_INFO>("TRIPLET_INFO"), t(ti.t), score(ti.score), 
+
+    bperiod(ti.bperiod), freq_bin(ti.freq_bin), 
+    tpotind0_0(ti.tpotind0_0), tpotind0_1(ti.tpotind0_1),
+    tpotind1_0(ti.tpotind1_0), tpotind1_1(ti.tpotind1_1),
+    tpotind2_0(ti.tpotind2_0), tpotind2_1(ti.tpotind2_1), 
+    time_bin(ti.time_bin), scale(ti.scale)
+
+{
+#ifdef USE_MANUAL_CALLSTACK
+    call_stack.enter("TRIPLET_INFO::TRIPLET_INFO(const TRIPLET_INFO &ti)");
+#endif 
+// debug possible heap corruption -- jeffc
+#ifdef _WIN32
+BOINCASSERT(_CrtCheckMemory());
+#endif
+
+    pot_min = (unsigned int *)calloc_a(swi.analysis_cfg.triplet_pot_length, sizeof(unsigned int), MEM_ALIGN);
+    if (pot_min == NULL) SETIERROR(MALLOC_FAILED, "copied TRIPLET_INFO pot_min == NULL");
+    pot_max = (unsigned int *)calloc_a(swi.analysis_cfg.triplet_pot_length, sizeof(unsigned int), MEM_ALIGN);
+    if (pot_max == NULL) SETIERROR(MALLOC_FAILED, "copied TRIPLET_INFO pot_max == NULL");
+    memcpy(pot_min,ti.pot_min,(swi.analysis_cfg.triplet_pot_length * sizeof(unsigned int)));
+    memcpy(pot_max,ti.pot_max,(swi.analysis_cfg.triplet_pot_length * sizeof(unsigned int)));
+
+// debug possible heap corruption -- jeffc
+#ifdef _WIN32
+BOINCASSERT(_CrtCheckMemory());
+#endif
+#ifdef USE_MANUAL_CALLSTACK
+    call_stack.exit();
+#endif 
+}    
+
+TRIPLET_INFO &TRIPLET_INFO::operator =(const TRIPLET_INFO &ti) {
+#ifdef USE_MANUAL_CALLSTACK
+   call_stack.enter("TRIPLET_INFO::operator =");
+#endif 
+// debug possible heap corruption -- jeffc
+#ifdef _WIN32
+BOINCASSERT(_CrtCheckMemory());
+#endif
+
+  if (&ti != this) {
+    t=ti.t;
+    score=ti.score;
+    bperiod=ti.bperiod;
+    freq_bin=ti.freq_bin;
+    tpotind0_0=ti.tpotind0_0;
+    tpotind0_1=ti.tpotind0_1;
+    tpotind1_0=ti.tpotind1_0;
+    tpotind1_1=ti.tpotind1_1;
+    tpotind2_0=ti.tpotind2_0;
+    tpotind2_1=ti.tpotind2_1;
+    time_bin=ti.time_bin;
+
+    memcpy(pot_min,ti.pot_min,(swi.analysis_cfg.triplet_pot_length * sizeof(unsigned int)));
+    memcpy(pot_max,ti.pot_max,(swi.analysis_cfg.triplet_pot_length * sizeof(unsigned int)));
+  }
+
+// debug possible heap corruption -- jeffc
+#ifdef _WIN32
+BOINCASSERT(_CrtCheckMemory());
+#endif
+#ifdef USE_MANUAL_CALLSTACK
+  call_stack.exit();
+#endif 
+  return *this;
+}
+
+
+TRIPLET_INFO::~TRIPLET_INFO() { 
+#ifdef USE_MANUAL_CALLSTACK
+    call_stack.enter("TRIPLET_INFO::~TRIPLET_INFO()");
+#endif 
+// debug possible heap corruption -- jeffc
+#ifdef _WIN32
+BOINCASSERT(_CrtCheckMemory());
+#endif
+
+    free_a(pot_min); 
+    free_a(pot_max); 
+
+// debug possible heap corruption -- jeffc
+#ifdef _WIN32
+BOINCASSERT(_CrtCheckMemory());
+#endif
+#ifdef USE_MANUAL_CALLSTACK
+    call_stack.exit();
+#endif 
+}
+
+
+// Do SETI-specific initialization for a work unit.
+// - prepare outfile for appending
+// - reset scores
+int seti_init_state() {
+#ifdef USE_MANUAL_CALLSTACK
+  call_stack.enter("seti_init_state()");
+#endif 
+  analysis_state.icfft= 0;
+  analysis_state.PoT_freq_bin = -1;
+  analysis_state.PoT_activity = POT_INACTIVE;
+  progress = 0.0;
+  reset_high_scores();
+  std::string path;
+
+  boinc_resolve_filename_s(OUTFILE_FILENAME, path);
+  if (outfile.open(path.c_str(), "ab")) SETIERROR(CANT_CREATE_FILE," in seti_init_state()");
+#ifdef USE_MANUAL_CALLSTACK
+  call_stack.exit();
+#endif 
+  return 0;
+}
+
+// This gets called at the start of each chirp/fft pair.
+int result_group_start() {
+  wrote_header = 0;
+  return 0;
+}
+
+// This gets called prior to writing an entry in the output file.
+// Write the chirp/fft parameters if not done already.
+
+int result_group_write_header() {
+  if (wrote_header) return 0;
+  wrote_header = 1;
+  int retval = outfile.printf( "<ogh ncfft=%d cr=%e fl=%d>\n",
+                               analysis_state.icfft,
+                               ChirpFftPairs[analysis_state.icfft].ChirpRate,
+                               ChirpFftPairs[analysis_state.icfft].FftLen
+                             );
+  if (retval < 0) SETIERROR(WRITE_FAILED,"in result_group_write_header()");
+  return 0;
+}
+
+
+// this gets called at the end of each chirp/fft pair
+// Rewrite the state file,
+// and write an end-of-group record to log file
+// if anything was written for this group.
+int result_group_end() {
+  int retval=0;
+
+  if (wrote_header) {
+    retval = outfile.printf( "<ogt ncfft=%d cr=%e fl=%d>\n",
+                             analysis_state.icfft,
+                             ChirpFftPairs[analysis_state.icfft].ChirpRate,
+                             ChirpFftPairs[analysis_state.icfft].FftLen);
+    if (retval < 0) SETIERROR(WRITE_FAILED,"in result_group_end");
+  }
+
+  return 0;
+}
+  
+
+int checkpoint(BOOLEAN force_checkpoint) {
+#ifdef USE_MANUAL_CALLSTACK
+  call_stack.enter("checkpoint()");
+#endif 
+  int retval=0, i, l=xml_indent_level;
+  xml_indent_level=0;
+// Making state_file static to avoid overhead of reallocating of buffers on 
+// every call.  
+  static MFILE state_file;
+  char buf[2048];
+  std::string enc_field, str;
+
+  // The user may have set preferences for a long time between
+  // checkpoints to reduce disk access.
+  if (!force_checkpoint) {
+    if (!boinc_time_to_checkpoint()) {
+#ifdef USE_MANUAL_CALLSTACK
+      call_stack.exit();
+#endif 
+      return CHECKPOINT_SKIPPED;
+    }
+  }
+
+  fflush(stderr);
+
+// debug possible heap corruption -- jeffc
+#ifdef _WIN32
+BOINCASSERT(_CrtCheckMemory());
+#endif
+
+  if (state_file.open(STATE_FILENAME, "wb")) SETIERROR(CANT_CREATE_FILE,"in checkpoint()");
+  retval = state_file.printf(
+             "<ncfft>%d</ncfft>\n"
+             "<cr>%e</cr>\n"
+             "<fl>%d</fl>\n"
+             "<prog>%.8f</prog>\n"
+             "<potfreq>%d</potfreq>\n"
+             "<potactivity>%d</potactivity>\n"
+             "<signal_count>%d</signal_count>\n"
+             "<flops>%f</flops>\n"
+             "<spike_count>%d</spike_count>\n"
+             "<autocorr_count>%d</autocorr_count>\n"
+             "<pulse_count>%d</pulse_count>\n"
+             "<gaussian_count>%d</gaussian_count>\n"
+             "<triplet_count>%d</triplet_count>\n",
+             analysis_state.icfft,
+             ChirpFftPairs[analysis_state.icfft].ChirpRate,
+             ChirpFftPairs[analysis_state.icfft].FftLen,
+	     std::min(progress,0.9999999),
+             analysis_state.PoT_freq_bin,
+             analysis_state.PoT_activity,
+             signal_count,
+             analysis_state.FLOP_counter,
+             spike_count,
+	     autocorr_count,
+             pulse_count,
+             gaussian_count,
+             triplet_count
+           );
+  if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
+
+  // checkpoint the best spike thus far (if any)
+  if(best_spike->s.fft_len) {
+    retval = state_file.printf("<best_spike>\n");
+    if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
+    // the spike proper
+    str = best_spike->s.print_xml(0,0,1);
+    retval = (int)state_file.write(str.c_str(), str.size(), 1);
+    // ancillary data
+    retval = state_file.printf(
+               "<bs_score>%f</bs_score>\n"
+               "<bs_bin>%d</bs_bin>\n"
+               "<bs_fft_ind>%d</bs_fft_ind>\n",
+               best_spike->score,
+               best_spike->bin,
+               best_spike->fft_ind);
+    if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
+    retval = state_file.printf("</best_spike>\n");
+    if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
+  }
+
+  // checkpoint the best autocorr thus far (if any)
+  if(best_autocorr->a.fft_len) {
+    retval = state_file.printf("<best_autocorr>\n");
+    if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
+    // the autocorr proper
+    str = best_autocorr->a.print_xml(0,0,1);
+    retval = (int)state_file.write(str.c_str(), str.size(), 1);
+    // ancillary data
+    retval = state_file.printf(
+               "<ba_score>%f</ba_score>\n"
+               "<ba_bin>%d</ba_bin>\n"
+               "<ba_fft_ind>%d</ba_fft_ind>\n",
+               best_autocorr->score,
+               best_autocorr->bin,
+               best_autocorr->fft_ind);
+    if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
+    retval = state_file.printf("</best_autocorr>\n");
+    if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
+  }
+
+  // checkpoint the best gaussian thus far (if any)
+  if(best_gauss->g.fft_len || best_gauss->score) {
+    retval = state_file.printf("<best_gaussian>\n");
+    if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
+    // the gaussian proper 
+    str = best_gauss->g.print_xml(0,0,1);
+    retval = (int)state_file.write(str.c_str(), str.size(), 1);
+    // ancillary data
+    retval = state_file.printf(
+               "<bg_score>%f</bg_score>\n"
+               "<bg_display_power_thresh>%f</bg_display_power_thresh>\n"
+               "<bg_bin>%d</bg_bin>\n"
+               "<bg_fft_ind>%d</bg_fft_ind>\n",
+               best_gauss->score,
+               best_gauss->display_power_thresh,
+               best_gauss->bin,
+               best_gauss->fft_ind);
+    if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
+    retval = state_file.printf("</best_gaussian>\n");
+    if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
+  }
+
+  // checkpoint the best pulse thus far (if any)
+  // The check for len_prof is a kludge.
+  if(best_pulse->p.fft_len) {
+    retval = state_file.printf("<best_pulse>\n");
+    if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
+    // the pulse proper 
+    str = best_pulse->p.print_xml(0,0,1);
+    retval = (int)state_file.write(str.c_str(), str.size(), 1);
+    // ancillary data
+    retval = state_file.printf(
+               "<bp_score>%f</bp_score>\n"
+               "<bp_freq_bin>%d</bp_freq_bin>\n"
+               "<bp_time_bin>%d</bp_time_bin>\n",
+               best_pulse->score,
+               best_pulse->freq_bin,
+               best_pulse->time_bin);
+    if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
+    retval = state_file.printf("</best_pulse>\n");
+    if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
+  }
+
+  // checkpoint the best triplet thus far (if any)
+  if(best_triplet->t.fft_len) {
+    retval = state_file.printf("<best_triplet>\n");
+    if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
+    // the triplet proper 
+    str = best_triplet->t.print_xml(0,0,1);
+    retval = (int)state_file.write(str.c_str(), str.size(), 1);
+
+    // ancillary data
+    retval = state_file.printf(
+               "<bt_score>%f</bt_score>\n"
+               "<bt_bperiod>%f</bt_bperiod>\n"
+               "<bt_tpotind0_0>%d</bt_tpotind0_0>\n"
+               "<bt_tpotind0_1>%d</bt_tpotind0_1>\n"
+               "<bt_tpotind1_0>%d</bt_tpotind1_0>\n"
+               "<bt_tpotind1_1>%d</bt_tpotind1_1>\n"
+               "<bt_tpotind2_0>%d</bt_tpotind2_0>\n"
+               "<bt_tpotind2_1>%d</bt_tpotind2_1>\n"
+               "<bt_freq_bin>%d</bt_freq_bin>\n"
+               "<bt_time_bin>%f</bt_time_bin>\n"
+               "<bt_scale>%f</bt_scale>\n",
+               best_triplet->score,
+               best_triplet->bperiod,
+               best_triplet->tpotind0_0,
+               best_triplet->tpotind0_1,
+               best_triplet->tpotind1_0,
+               best_triplet->tpotind1_1,
+               best_triplet->tpotind2_0,
+               best_triplet->tpotind2_1,
+               best_triplet->freq_bin,
+               best_triplet->time_bin,
+               best_triplet->scale);
+    if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
+
+   // convert min PoT to chars, encode, and print
+   for (i=0; i<swi.analysis_cfg.triplet_pot_length; i++) {
+	buf[i] = (unsigned char)best_triplet->pot_min[i];
+   }
+   enc_field=xml_encode_string(buf, swi.analysis_cfg.triplet_pot_length, _x_csv);
+   retval = state_file.printf(
+         "<bt_pot_min length=%d encoding=\"%s\">",
+		 enc_field.size(), xml_encoding_names[_x_csv]
+   );
+   if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
+   state_file.write(enc_field.c_str(), enc_field.size(), 1);
+   retval = state_file.printf("</bt_pot_min>\n");
+   if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
+
+   // convert max PoT to chars, encode, and print
+   for (i=0; i<swi.analysis_cfg.triplet_pot_length; i++) {
+	buf[i] = (unsigned char)best_triplet->pot_max[i];
+   }
+   enc_field=xml_encode_string(buf, swi.analysis_cfg.triplet_pot_length, _x_csv);
+   state_file.printf(
+       "<bt_pot_max length=%d encoding=\"%s\">",
+	 enc_field.size(), xml_encoding_names[_x_csv]
+   );
+   if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
+   state_file.write(enc_field.c_str(), enc_field.size(), 1);
+   retval = state_file.printf("</bt_pot_max>\n");
+   if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
+   retval = state_file.printf("</best_triplet>\n");
+   if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()");
+  }
+
+  if (BaseLineSmooth != NULL) {
+   for (i=0;i<num_BLS;i++) {
+     if ( BaseLineSmoothFuncs[i].func == BaseLineSmooth ) {
+       state_file.printf("<baseline_smooth>%s</baseline_smooth>\n",
+         BaseLineSmoothFuncs[i].nom);
+       break;
+     }
+   }
+  }
+
+  if (GetPowerSpectrum != NULL) {
+   for (i=0;i<num_GPS;i++) {
+     if ( GetPowerSpectrumFuncs[i].func == GetPowerSpectrum ) {
+       state_file.printf("<get_power_spectrum>%s</get_power_spectrum>\n",
+         GetPowerSpectrumFuncs[i].nom);
+       break;
+     }
+   }
+  }
+
+  if (ChirpData != NULL) {
+   for (i=0;i<num_CD;i++) {
+     if ( ChirpDataFuncs[i].func == ChirpData ) {
+       state_file.printf("<chirp_data>%s</chirp_data>\n",
+         ChirpDataFuncs[i].nom);
+       break;
+     }
+   }
+  }
+
+  if (Transpose != NULL) {
+   for (i=0;i<num_TP;i++) {
+     if ( TransposeFuncs[i].func == Transpose ) {
+       state_file.printf("<transpose>%s</transpose>\n",
+         TransposeFuncs[i].nom);
+       break;
+     }
+   }
+  }
+
+  if (strlen(Foldmain.name) != 0) {
+   state_file.printf("<folding>%s</folding>\n",
+      Foldmain.name);
+  }
+
+  // The result (outfile) and state mfiles are now synchronized.
+  // Flush them both.
+  retval = outfile.flush();
+  if (retval) SETIERROR(WRITE_FAILED,"in checkpoint()");
+  retval = state_file.flush();
+  if (retval) SETIERROR(WRITE_FAILED,"in checkpoint()");
+  retval = state_file.close();
+  if (retval) SETIERROR(WRITE_FAILED,"in checkpoint()");
+  boinc_checkpoint_completed();
+  xml_indent_level=l;
+
+// debug possible heap corruption -- jeffc
+#ifdef _WIN32
+BOINCASSERT(_CrtCheckMemory());
+#endif
+#ifdef USE_MANUAL_CALLSTACK
+  call_stack.exit();
+#endif 
+  return 0;
+}
+
+// Read the state file and set analysis_state accordingly.
+// Note: The state of analysis is saved in two places:
+// 1) at the end of processing the data for any given
+//    chirp/fft pair.  In this case, the icfft index
+//    needs to be set for the *next* chirp/fft pair.
+//    If analysis was in this state when saved,
+//    PoT_freq_bin will have been set to -1.
+// 2) at the end of PoT processing for any given
+//    frequency bin (for any given chirp/fft pair).
+//    This is indicated by PoT_freq_bin containing
+//    something other than -1.  It will contain the
+//    frequency bin just completed. In this case, we
+//    are *not* finished processing for the current
+//    chirp/fft pair and we do not increment icfft to
+//    the next pair.  We do however increment PoT_freq_bin
+//    to the next frequency bin.
+//
+int parse_state_file(ANALYSIS_STATE& as) {
+  static char buf[8192];
+  std::string fname;
+  int ncfft, fl, PoT_freq_bin, PoT_activity;
+  double cr=0,flops=0;
+  FILE* state_file;
+#ifdef USE_MANUAL_CALLSTACK
+  call_stack.enter("parse_state_file()");
+#endif 
+// debug possible heap corruption -- jeffc
+#ifdef _WIN32
+BOINCASSERT(_CrtCheckMemory());
+#endif
+
+  ncfft = -1;
+  progress = 0.0;
+  PoT_freq_bin = -1;
+  PoT_activity = POT_INACTIVE;
+  state_file = boinc_fopen(STATE_FILENAME, "rb");
+  if (!state_file) SETIERROR(FOPEN_FAILED,"in parse_state_file()");
+
+  // main parsing loop
+  while (fgets(buf, sizeof(buf), state_file)) {
+    if (parse_int(buf, "<ncfft>", ncfft)) continue;
+    else if (parse_double(buf, "<cr>", cr)) continue;
+    else if (parse_int(buf, "<fl>", fl)) continue;   
+    else if (parse_double(buf, "<prog>", progress)) continue;
+    else if (parse_int(buf, "<potfreq>", PoT_freq_bin)) continue;
+    else if (parse_int(buf, "<potactivity>", PoT_activity)) continue;
+    else if (parse_int(buf, "<signal_count>", signal_count)) continue;
+    else if (parse_double(buf, "<flops>", flops)) continue;
+    else if (parse_int(buf, "<spike_count>", spike_count)) continue;
+    else if (parse_int(buf, "<autocorr_count>", autocorr_count)) continue;
+    else if (parse_int(buf, "<pulse_count>", pulse_count)) continue;
+    else if (parse_int(buf, "<gaussian_count>", gaussian_count)) continue;
+    else if (parse_int(buf, "<triplet_count>", triplet_count)) continue;
+    // best spike
+    else if (xml_match_tag(buf, "<best_spike>")) {
+      while (fgets(buf, sizeof(buf), state_file)) {
+        if (xml_match_tag(buf, "</best_spike>")) break;
+        // spike proper
+        else if (xml_match_tag(buf, "<spike>")) {
+	  char *p = buf + strlen(buf);
+          while(fgets(p, sizeof(buf)-(int)strlen(buf), state_file)) {
+            if (xml_match_tag(buf, "</spike>")) break;
+	    p += strlen(p);
+          } 
+          best_spike->s.parse_xml(buf);
+        }
+        // ancillary data
+        else if (parse_double(buf, "<bs_score>", best_spike->score)) continue;
+        else if (parse_int(buf, "<bs_bin>", best_spike->bin)) continue;
+        else if (parse_int(buf, "<bs_fft_ind>", best_spike->fft_ind)) continue;
+      } // end while in best_spike
+    }  // end if in best_spike
+
+    // best autocorr
+    else if (xml_match_tag(buf, "<best_autocorr>")) {
+      while (fgets(buf, sizeof(buf), state_file)) {
+        if (xml_match_tag(buf, "</best_autocorr>")) break;
+        // autocorr proper
+        else if (xml_match_tag(buf, "<autocorr>")) {
+	  char *p = buf + strlen(buf);
+          while(fgets(p, sizeof(buf)-(int)strlen(buf), state_file)) {
+            if (xml_match_tag(buf, "</autocorr>")) break;
+	    p += strlen(p);
+          } 
+          best_autocorr->a.parse_xml(buf);
+        }
+        // ancillary data
+        else if (parse_double(buf, "<ba_score>", best_autocorr->score)) continue;
+        else if (parse_int(buf, "<ba_bin>", best_autocorr->bin)) continue;
+        else if (parse_int(buf, "<ba_fft_ind>", best_autocorr->fft_ind)) continue;
+      } // end while in best_autocorr
+    }  // end if in best_autocorr
+
+    // best gaussian..
+    else if (xml_match_tag(buf, "<best_gaussian>")) {
+      while (fgets(buf, sizeof(buf), state_file)) {
+        if (xml_match_tag(buf, "</best_gaussian>")) break;
+        // gaussian proper
+        else if (xml_match_tag(buf, "<gaussian>")) {
+	  char *p = buf + strlen(buf);
+          while(fgets(p, sizeof(buf)-(int)strlen(buf), state_file)) {
+            if (xml_match_tag(buf, "</gaussian>")) break;
+	    p += strlen(p);
+          } 
+          best_gauss->g.parse_xml(buf);
+        }
+        // ancillary data
+        else if (parse_double(buf, "<bg_score>", best_gauss->score)) continue;
+        else if (parse_double(buf, "<bg_display_power_thresh>", 
+		best_gauss->display_power_thresh)) continue;
+        else if (parse_int(buf, "<bg_bin>", best_gauss->bin)) continue ;
+        else if (parse_int(buf, "<bg_fft_ind>", best_gauss->fft_ind)) continue;
+      }  // end while in best_gaissian
+    }  // end if in best_gaussian
+
+    // best pulse
+    else if (xml_match_tag(buf, "<best_pulse>")) {
+      while (fgets(buf, sizeof(buf), state_file)) {
+        if (xml_match_tag(buf, "</best_pulse>")) break;
+        // pulse proper
+        else if (xml_match_tag(buf, "<pulse>")) {
+	  char *p = buf + strlen(buf);
+          while(fgets(p, sizeof(buf)-(int)strlen(buf), state_file)) {
+            if (xml_match_tag(buf, "</pulse>")) break;
+	    p += strlen(p);
+          } 
+          best_pulse->p.parse_xml(buf);
+        }
+        // ancillary data
+        else if (parse_double(buf, "<bp_score>", best_pulse->score)) continue;
+        else if (parse_int(buf, "<bp_freq_bin>", best_pulse->freq_bin)) continue;
+        else if (parse_int(buf, "<bp_time_bin>", best_pulse->time_bin)) continue;
+      }  // end while in best_pulse
+    }  // end if in best_pulse
+
+    // best triplet
+    else if (xml_match_tag(buf, "<best_triplet>")) {
+      while (fgets(buf, sizeof(buf), state_file)) {
+        if (xml_match_tag(buf, "</best_triplet>")) break;
+        // triplet proper
+        else if (xml_match_tag(buf, "<triplet>")) {
+	  char *p = buf + strlen(buf);
+          while(fgets(p, sizeof(buf)-(int)strlen(buf), state_file)) {
+            if (xml_match_tag(buf, "</triplet>")) break;
+	    p += strlen(p);
+          } 
+          best_triplet->t.parse_xml(buf);
+        }
+        // ancillary data
+        else if (parse_double(buf, "<bt_score>", best_triplet->score)) continue;
+        else if (parse_double(buf, "<bt_bperiod>", best_triplet->bperiod)) continue;
+        else if (parse_int(buf, "<bt_tpotind0_0>", best_triplet->tpotind0_0)) continue;
+        else if (parse_int(buf, "<bt_tpotind0_1>", best_triplet->tpotind0_1)) continue;
+        else if (parse_int(buf, "<bt_tpotind1_0>", best_triplet->tpotind1_0)) continue;
+        else if (parse_int(buf, "<bt_tpotind1_1>", best_triplet->tpotind1_1)) continue;
+        else if (parse_int(buf, "<bt_tpotind2_0>", best_triplet->tpotind2_0)) continue;
+        else if (parse_int(buf, "<bt_tpotind2_1>", best_triplet->tpotind2_1)) continue;
+        else if (parse_int(buf, "<bt_freq_bin>", best_triplet->freq_bin)) continue;
+        else if (parse_double(buf, "<bt_time_bin>", best_triplet->time_bin)) continue;
+        else if (parse_double(buf, "<bt_scale>", best_triplet->scale)) continue;
+ 	else if (xml_match_tag(buf, "<bt_pot_min")) {
+	  char *p = buf + strlen(buf);
+          while(fgets(p, sizeof(buf)-(int)strlen(buf), state_file)) {
+            if (xml_match_tag(buf, "</bt_pot_min")) break;
+	    p += strlen(p);
+          } 
+	  std::vector<unsigned char> pot_min(
+	    xml_decode_field<unsigned char>(buf,"bt_pot_min")
+	  );
+	  int i;
+	  for (i=0; i<swi.analysis_cfg.triplet_pot_length; i++) {
+	    best_triplet->pot_min[i] = pot_min[i];
+	  }
+	}  // end Min PoT
+ 	else if (xml_match_tag(buf, "<bt_pot_max")) {
+	  char *p = buf + strlen(buf);
+          while(fgets(p, sizeof(buf)-(int)strlen(buf), state_file)) {
+            if (xml_match_tag(buf, "</bt_pot_max")) break;
+	    p += strlen(p);
+          } 
+	  std::vector<unsigned char> pot_max(
+	    xml_decode_field<unsigned char>(buf,"bt_pot_max")
+	  );
+	  int i;
+	  for (i=0; i<swi.analysis_cfg.triplet_pot_length; i++) {
+	    best_triplet->pot_max[i] = pot_max[i];
+	  }
+	}  // end Max PoT
+      }  // end while in best_triplet
+    }  // end if in best_triplet
+
+    // Restore best functions that were determined earlier.
+    else if (parse_str(buf,"<baseline_smooth>",fname)) {
+      int i; 
+      for (i=0;i<num_BLS;i++) {
+        if (strcmp(fname.c_str(),BaseLineSmoothFuncs[i].nom)==0) {
+          BaseLineSmooth=BaseLineSmoothFuncs[i].func;
+          found_baseline_smooth=true;
+          break;
+        }
+      }
+    }
+
+    else if (parse_str(buf,"<get_power_spectrum>",fname)) {
+      int i; 
+      for (i=0;i<num_GPS;i++) {
+        if (strcmp(fname.c_str(),GetPowerSpectrumFuncs[i].nom)==0) {
+          GetPowerSpectrum=GetPowerSpectrumFuncs[i].func;
+          found_get_power_spectrum=true;
+          break;
+        }
+      }
+    }
+
+    else if (parse_str(buf,"<chirp_data>",fname)) {
+      int i; 
+      for (i=0;i<num_CD;i++) {
+        if (strcmp(fname.c_str(),ChirpDataFuncs[i].nom)==0) {
+          ChirpData=ChirpDataFuncs[i].func;
+          found_chirp_data=true;
+          break;
+        }
+      }
+    }
+
+    else if (parse_str(buf,"<transpose>",fname)) {
+      int i; 
+      for (i=0;i<num_TP;i++) {
+        if (strcmp(fname.c_str(),TransposeFuncs[i].nom)==0) {
+          Transpose=TransposeFuncs[i].func;
+          found_transpose=true;
+          break;
+        }
+      }
+    }
+
+    else if (parse_str(buf,"<folding>",fname)) {
+      int i; 
+      for (i=0;i<num_FS;i++) {
+        if (strcmp(fname.c_str(),FoldSubs[i].fsp->name)==0) {
+          CopyFoldSet(&Foldmain,FoldSubs[i].fsp);
+          found_folding=true;
+          break;
+        }
+      }
+    }
+
+  }  // end main parsing loop
+
+  fclose(state_file);
+
+  analysis_state.FLOP_counter=flops;
+  reload_graphics_state();	// so we can draw best_of signals
+
+  // Adjust for restart - go 1 step beyond the checkpoint.
+  as.PoT_activity = PoT_activity;
+  if(PoT_freq_bin == -1) {
+    as.icfft        = ncfft+1;
+    as.PoT_freq_bin = PoT_freq_bin;
+  } else {
+    as.icfft        = ncfft;
+    as.PoT_freq_bin = PoT_freq_bin+1;
+  }
+
+// debug possible heap corruption -- jeffc
+#ifdef _WIN32
+BOINCASSERT(_CrtCheckMemory());
+#endif
+#ifdef USE_MANUAL_CALLSTACK
+  call_stack.exit();
+#endif 
+  return 0;
+}
+
+// On entry, analysis_state.data points to malloced data
+// and outfile is not open.
+// On exit, these are freed and closed
+int seti_do_work() {
+  int retval=0;
+#ifdef USE_MANUAL_CALLSTACK
+  call_stack.enter("seti_do_work()");
+#endif 
+  retval = seti_analyze(analysis_state);
+  free_a(analysis_state.data);
+  analysis_state.data = 0;
+
+  if( swi.data_type == DATA_ENCODED ) {
+      free_a(analysis_state.savedWUData);
+      analysis_state.savedWUData = 0;
+  }
+#ifdef USE_MANUAL_CALLSTACK
+  call_stack.exit();
+#endif 
+  return retval;
+}
+
+// on success, swi.data points to malloced data.
+int seti_parse_data(FILE* f, ANALYSIS_STATE& state) {
+  unsigned long nbytes, nsamples,samples_per_byte;
+  sah_complex *data;
+  unsigned long i;
+  char *p, buf[256];
+  sah_complex *bin_data=0;
+  int retval=0;
+  FORCE_FRAME_POINTER;
+#ifdef USE_MANUAL_CALLSTACK
+  call_stack.enter("seti_parse_data()");
+#endif 
+
+  nsamples = swi.nsamples;
+  samples_per_byte=(8/swi.bits_per_sample);
+  data = (sah_complex *)malloc_a(nsamples*sizeof(sah_complex), MEM_ALIGN);
+  bin_data = (sah_complex *)malloc_a(nsamples*sizeof(sah_complex), MEM_ALIGN);
+  if (!data) SETIERROR(MALLOC_FAILED, "!data");
+  if (!bin_data) SETIERROR(MALLOC_FAILED, "!bin_data");
+
+  switch(swi.data_type) {
+    case DATA_ASCII:
+      for (i=0; i<nsamples; i++) {
+        p = fgets(buf, 256, f);
+        if (!p) {
+          SETIERROR(READ_FAILED,"in seti_parse_data");
+        }
+
+        sscanf(buf, "%f%f", &data[i][0], &data[i][1]);
+      }
+      break;
+    case DATA_ENCODED:
+    case DATA_SUN_BINARY:
+      try {
+        int nread;
+        std::string tmpbuf("");
+        fseek(f,0,SEEK_SET);
+        nbytes = (nsamples/samples_per_byte);
+        tmpbuf.reserve(nbytes*3/2);
+        while ((nread=(int)fread(buf,1,sizeof(buf),f))) {
+          tmpbuf+=std::string(&(buf[0]),nread);
+        }
+        std::vector<unsigned char> datav(
+           xml_decode_field<unsigned char>(tmpbuf,"data") 
+        );
+	
+        memcpy(bin_data,&(datav[0]),datav.size());
+        if (datav.size() < nbytes) throw BAD_DECODE;
+      } catch (int i) {
+          retval=i;
+          if (data) free_a(data);
+          if (bin_data) free_a(bin_data);
+          SETIERROR(i,"in seti_parse_data()");
+      }
+      bits_to_floats((unsigned char *)bin_data, data, nsamples,swi.bits_per_sample);
+      memcpy(bin_data,data,nsamples*sizeof(sah_complex));
+      state.savedWUData = bin_data;
+      break;
+  }
+  state.npoints = nsamples;
+  state.data = data;
+
+#ifdef BOINC_APP_GRAPHICS
+  if (sah_graphics) {
+      strlcpy(sah_graphics->wu.receiver_name,swi.receiver_cfg.name,255);
+      sah_graphics->wu.s4_id = swi.receiver_cfg.s4_id;
+      sah_graphics->wu.time_recorded = swi.time_recorded;
+      sah_graphics->wu.subband_base = swi.subband_base;
+      sah_graphics->wu.start_ra = swi.start_ra;
+      sah_graphics->wu.start_dec = swi.start_dec;
+      sah_graphics->wu.subband_sample_rate = swi.subband_sample_rate;
+      sah_graphics->ready = true;
+  }
+#endif
+#ifdef USE_MANUAL_CALLSTACK
+  call_stack.exit();
+#endif 
+  return 0;
+}
+
+int seti_parse_wu(FILE* f, ANALYSIS_STATE& state) {
+  int retval=0;
+#ifdef USE_MANUAL_CALLSTACK
+  call_stack.enter("seti_parse_wu()");
+#endif 
+  retval = seti_parse_wu_header(f);
+  if (retval) SETIERROR(retval,"from seti_parse_wu_header()");
+  retval=seti_parse_data(f, state);
+#ifdef USE_MANUAL_CALLSTACK
+  call_stack.exit();
+#endif 
+  return retval;
+}
+
+void final_report() {
+#ifdef USE_MANUAL_CALLSTACK
+  call_stack.enter("final_report()");
+#endif 
   if(verbose>0){
 	{
 	int fft=(best_spike->s.fft_len>1024)?(best_spike->s.fft_len/1024):(best_spike->s.fft_len);
@@ -1153,35 +1153,35 @@ void final_report() {
 		best_triplet->t.chirp_rate,fft,symbol);
   }
   }
-
-  fprintf(stderr,"\nFlopcounter: %f\n\n", analysis_state.FLOP_counter);
-  fprintf(stderr,"Spike count:    %d\n", spike_count);
-  fprintf(stderr,"Autocorr count: %d\n", autocorr_count);
-  fprintf(stderr,"Pulse count:    %d\n", pulse_count);
-  fprintf(stderr,"Triplet count:  %d\n", triplet_count);
-  fprintf(stderr,"Gaussian count: %d\n", gaussian_count);
-  fflush(stderr);
-#ifdef USE_MANUAL_CALLSTACK
-  call_stack.exit();
-#endif 
-}
-
-unsigned int pow2(unsigned int num){
-#ifdef USE_MANUAL_CALLSTACK
-    call_stack.enter("pow2()");
-#endif 
-    unsigned int n = num > 0 ? num - 1 : 0;
-    n |= n >> 1;
-    n |= n >> 2;
-    n |= n >> 4;
-    n |= n >> 8;
-    n |= n >> 16;
-#if SIZEOF_INT > 4
-    n |= n >> 32;
-#endif
-    n++;
-#ifdef USE_MANUAL_CALLSTACK
-    call_stack.exit();
-#endif 
-    return n >> 1;
-}
+
+  fprintf(stderr,"\nFlopcounter: %f\n\n", analysis_state.FLOP_counter);
+  fprintf(stderr,"Spike count:    %d\n", spike_count);
+  fprintf(stderr,"Autocorr count: %d\n", autocorr_count);
+  fprintf(stderr,"Pulse count:    %d\n", pulse_count);
+  fprintf(stderr,"Triplet count:  %d\n", triplet_count);
+  fprintf(stderr,"Gaussian count: %d\n", gaussian_count);
+  fflush(stderr);
+#ifdef USE_MANUAL_CALLSTACK
+  call_stack.exit();
+#endif 
+}
+
+unsigned int pow2(unsigned int num){
+#ifdef USE_MANUAL_CALLSTACK
+    call_stack.enter("pow2()");
+#endif 
+    unsigned int n = num > 0 ? num - 1 : 0;
+    n |= n >> 1;
+    n |= n >> 2;
+    n |= n >> 4;
+    n |= n >> 8;
+    n |= n >> 16;
+#if SIZEOF_INT > 4
+    n |= n >> 32;
+#endif
+    n++;
+#ifdef USE_MANUAL_CALLSTACK
+    call_stack.exit();
+#endif 
+    return n >> 1;
+}
diff --git a/client/vector/analyzeFuncs_fpu.cpp b/client/vector/analyzeFuncs_fpu.cpp
index cbcf319..878a1a9 100644
--- a/client/vector/analyzeFuncs_fpu.cpp
+++ b/client/vector/analyzeFuncs_fpu.cpp
@@ -75,7 +75,7 @@ inline double fastfrac(double val, double roundVal) {
         : "=&t" (val)
         : "0" (val), "f" (roundVal), "f" (val)
     );
-#elif defined(_WIN64) || defined (__arm__)
+#elif defined(_WIN64)//R: doesn't correctly work for ARM
     val -= ((val + roundVal) - roundVal);  // TODO: ADD CHECK THAT THIS WORKS
 #else
     val -= floor(val + 0.5);
diff --git a/client/vector/analyzeFuncs_neon.S b/client/vector/analyzeFuncs_neon.S
index 04f8d55..7d387f3 100644
--- a/client/vector/analyzeFuncs_neon.S
+++ b/client/vector/analyzeFuncs_neon.S
@@ -37,23 +37,30 @@
 
 #ifdef __arm__
 /*
- * vfp_ChirpData.S
+ * neon_ChirpData.S
  * Author: Mateusz Szpakowski
  */
 
+
 #if defined(__VFP_FP__) && !defined(__SOFTFP__)
 		.syntax unified
 #endif
+
                 .arch armv7-a
                 .fpu neon
+
 #if defined(__VFP_FP__) && !defined(__SOFTFP__)
 		.eabi_attribute 27, 3
 		.eabi_attribute 28, 1
 #endif
-	
+
+/*
                 .eabi_attribute 20, 1
                 .eabi_attribute 21, 1
                 .eabi_attribute 23, 3
+*/
+
+                .eabi_attribute 23, 1
                 .eabi_attribute 24, 1
                 .eabi_attribute 25, 1
                 .eabi_attribute 26, 2
@@ -90,6 +97,7 @@
 _Z14neon_ChirpDataPA2_fS0_idid:
                 push {r4,r5,r6,r7,r8,r9,r10,r11,r12,lr}
                 vpush {d8,d9,d10,d11,d12,d13,d14,d15}
+#ifdef ANDROID   
 #define stargidx (40+64)
                 /* r0 - input data
                  * r1 - output data
@@ -98,12 +106,33 @@ _Z14neon_ChirpDataPA2_fS0_idid:
                  * sp[2] - numDataPoints
                  * sp[4-5] - sample_rate
                  */
+#else
+//R: cause few params now in registers stack should be shorter by 20 bytes
+#define stargidx (40+64)
+//R: armhf like Parallella use registers instead of stack to pass params so another expected pattern of registers use
+/*
+	r0 - input data
+	r1 - output data
+	r2 - chirprateind
+	r3 - numDataPoints
+	d0 - chirp_rate
+	d1 - sample_rate
+*/
+//R: seems r12 isn't in use in original function so use it to preserve numDataPoins value (r3)
+		mov r12,r3
+                vmov.f64 d9, d0
+		vmov.f64 d10, d1
+#endif
                 tst r2,r2
                 bne .Lrealfunc
                 mov r3,r0   // swap addresses
                 mov r0,r1
                 mov r1,r3
+#ifdef ANDROID
                 ldr r2,[sp,#stargidx+8]     // numDataPoints
+#else
+		mov r2,r12
+#endif
                 lsl r2,r2,#3
                 bl memcpy(PLT)
                 b .Lendoffunc
@@ -116,9 +145,12 @@ _Z14neon_ChirpDataPA2_fS0_idid:
                 add r4,pc,r4
                 ldr r5,.LGOT1+4
                 ldr r5,[r4,r5]
-                
+#ifdef ANDROID            
                 ldr r3,[sp,#stargidx+8]     // numDataPoints
-                
+#else
+		mov r3,r12
+#endif              
+  
                 add r6,r3,r3,lsl #1
                 lsl r6,r6,#2
                 fldd d0,[r5,#32]
@@ -131,8 +163,10 @@ _Z14neon_ChirpDataPA2_fS0_idid:
                 sub r3,r3,#8*15
                 
                 fldd d11,.Lhalfd
+#ifdef ANDROID   //R: for armhf these doubles already in registers
                 fldd d9,[sp,#stargidx]        // chirp_rate
                 fldd d10,[sp,#stargidx+16]   // sample_rate
+#endif
                 fmuld d10,d10,d10
                 fmuld d9,d9,d11
                 fdivd d9,d9,d10
@@ -142,8 +176,11 @@ _Z14neon_ChirpDataPA2_fS0_idid:
                 fcmpd d9,d11
                 fmstat
                 fnegdmi d10,d10     // negate is negative srate
-                
+#ifdef ANDROID   
                 sub sp,sp,#16+64
+#else  //R: for armhf stack has different size so attempting to account for that
+                sub sp,sp,#16+64
+#endif
                 add r7,sp,#16
                 add r11,sp,#16+32
                 fstmiad sp,{d9,d10}
@@ -569,7 +606,11 @@ _Z14neon_ChirpDataPA2_fS0_idid:
                 cmp r0,r3
                 blo .Lsmallloop
 .Lendsmallloop:
+#ifdef ANDROID
                 add sp,sp,#16+64
+#else
+                add sp,sp,#16+64
+#endif
 .Lendoffunc:
                 mov r0,#0
                 vpop {d8,d9,d10,d11,d12,d13,d14,d15}
@@ -590,26 +631,6 @@ _Z14neon_ChirpDataPA2_fS0_idid:
  * neon_FoldSubs.S
  * Author: Mateusz Szpakowski
  */
-
-#if defined(__VFP_FP__) && !defined(__SOFTFP__)
-		.syntax unified
-#endif	
-                .arch armv7-a
-                .fpu neon
-#if defined(__VFP_FP__) && !defined(__SOFTFP__)
-		.eabi_attribute 27, 3
-		.eabi_attribute 28, 1
-#endif
-	
-                .eabi_attribute 20, 1
-                .eabi_attribute 21, 1
-                .eabi_attribute 23, 3
-                .eabi_attribute 24, 1
-                .eabi_attribute 25, 1
-                .eabi_attribute 26, 2
-                .eabi_attribute 30, 2
-                .eabi_attribute 18, 4
-                .text
                 .align  2
                 /*****
                  * fold array by 3
@@ -2498,25 +2519,6 @@ neonFoldMain:
  * Author: Mateusz Szpakowski
  */
 
-#if defined(__VFP_FP__) && !defined(__SOFTFP__)
-		.syntax unified
-#endif	
-                .arch armv7-a
-                .fpu neon
-#if defined(__VFP_FP__) && !defined(__SOFTFP__)
-		.eabi_attribute 27, 3
-		.eabi_attribute 28, 1
-#endif
-	
-                .eabi_attribute 20, 1
-                .eabi_attribute 21, 1
-                .eabi_attribute 23, 3
-                .eabi_attribute 24, 1
-                .eabi_attribute 25, 1
-                .eabi_attribute 26, 2
-                .eabi_attribute 30, 2
-                .eabi_attribute 18, 4
-                .text
                 .align  2
                 .global _Z21neon_GetPowerSpectrumPA2_fPfi
                 .type   _Z21neon_GetPowerSpectrumPA2_fPfi, %function
diff --git a/client/vector/analyzeFuncs_vector.cpp b/client/vector/analyzeFuncs_vector.cpp
index a39a7e3..169ad19 100644
--- a/client/vector/analyzeFuncs_vector.cpp
+++ b/client/vector/analyzeFuncs_vector.cpp
@@ -41,7 +41,6 @@
 #ifdef _WIN32
 #define uint32_t unsigned long
 #endif
-
 #include <csignal>
 #include <cstdlib>
 #include <cmath>
@@ -264,7 +263,7 @@ void SetCapabilities(void) {
   if ((dp & 0x00000800) && avxSupported())   CPUCaps |= BA_AVX;
 #endif
 
-#elif defined(__i386__) || defined (__x86_64__)
+#elif defined(__i386__) || defined (__x86_64__) || defined(_M_X64)
   /* we're hoping to rely on signal handling to keep us out of trouble */
   CPUCaps |= (BA_MMX | BA_SSE | BA_SSE2 | BA_SSE3 | BA_3Dnow | BA_3DnowP | BA_MMX_P );
 #if defined(USE_AVX)                    
@@ -410,7 +409,7 @@ CDtb ChirpDataFuncs[]={
      avx_ChirpData_d, BA_AVX, "avx_ChirpData_d", 
 #  endif
 #endif
-#if defined(__arm__) && defined(ANDROID) && defined(__VFP_FP__) && !defined(__SOFTFP__)
+#if defined(__arm__) && defined(__VFP_FP__) && !defined(__SOFTFP__)
      vfp_ChirpData, BA_VFP, "vfp_ChirpData",
 #ifdef USE_NEON
      neon_ChirpData, BA_NEON, "neon_ChirpData",
@@ -912,9 +911,22 @@ ChirpData_func ChooseChirpData() {
             int ind=TESTCHIRPIND;
             while ((j<100) && ((j<20) || (timing<(10*timer.resolution())))) {
                 memset(outdata,0,NumDataPoints*sizeof(sah_complex));
+#if 0
+		fprintf(stderr,"before Chirp test:%32s \n",ChirpDataFuncs[i].nom);
+		for(int k=0;k<3;k++){
+			fprintf(stderr,"in[%d].xy=(%7.5f,%7.5f)]\n",k,indata[k][0],indata[k][1]);
+		}
+#endif
                 timer.start();
                 rv=ChirpDataFuncs[i].func(indata,outdata,ind,MinChirpStep*ind,NumDataPoints,swi.subband_sample_rate);
                 onetime=timer.stop();
+#if 0
+		fprintf(stderr,"after Chirp test:%32s \n",ChirpDataFuncs[i].nom);
+		for(int k=0;k<3;k++){
+			fprintf(stderr,"out[%d].xy=(%7.5f,%7.5f)]\n",k,outdata[k][0],outdata[k][1]);
+		}
+#endif
+
                 timing+=onetime;
                 timings.push_back(onetime);
 #if !defined(USE_ASMLIB) && !defined(__APPLE_CC__)
diff --git a/client/vector/analyzeFuncs_vfp.S b/client/vector/analyzeFuncs_vfp.S
index a9b51f7..0fb5bc7 100644
--- a/client/vector/analyzeFuncs_vfp.S
+++ b/client/vector/analyzeFuncs_vfp.S
@@ -50,10 +50,13 @@
 		.eabi_attribute 27, 3
 		.eabi_attribute 28, 1
 #endif
-	
+
+/*	
                 .eabi_attribute 20, 1
                 .eabi_attribute 21, 1
                 .eabi_attribute 23, 3
+*/
+                .eabi_attribute 23, 1
                 .eabi_attribute 24, 1
                 .eabi_attribute 25, 1
                 .eabi_attribute 26, 2
@@ -75,8 +78,9 @@
                 .global _Z13vfp_ChirpDataPA2_fS0_idid
                 .type   _Z13vfp_ChirpDataPA2_fS0_idid, %function
 _Z13vfp_ChirpDataPA2_fS0_idid:
-                push {r4,r5,r6,r7,r8,lr}
+                push {r4,r5,r6,r7,r8,r9,lr}
                 vpush {d8,d9,d10,d11,d12,d13,d14,d15}
+#ifdef ANDROID
 #define stargidx (24+64)
                 /* r0 - input data
                  * r1 - output data
@@ -85,12 +89,30 @@ _Z13vfp_ChirpDataPA2_fS0_idid:
                  * sp[2] - numDataPoints
                  * sp[4-5] - sample_rate
                  */
+#else //R: armhf pass params in registers instead
+                /* r0 - input data
+                 * r1 - output data
+                 * r2 - chirprateind
+                 * d0 - chirp_rate
+                 * r3 - numDataPoints (stored in r9 for function lifetime)
+                 * d1 - sample_rate
+                 */
+
+		mov r9,r3
+		vmov.f64 d9,d0
+		vmov.f64 d10,d1
+#endif
+
                 tst r2,r2
                 bne .Lrealfunc
                 mov r3,r0   // swap addresses
                 mov r0,r1
                 mov r1,r3
+#ifdef ANDROID
                 ldr r2,[sp,#stargidx+8]     // numDataPoints
+#else
+		mov r2,r9
+#endif
                 lsl r2,r2,#3
                 bl memcpy(PLT)
                 b .Lendoffunc
@@ -103,9 +125,11 @@ _Z13vfp_ChirpDataPA2_fS0_idid:
                 add r4,pc,r4
                 ldr r5,.LGOT1+4
                 ldr r5,[r4,r5]
-                
+#ifdef ANDROID            
                 ldr r3,[sp,#stargidx+8]     // numDataPoints
-                
+#else
+		mov r3,r9
+#endif                
                 add r6,r3,r3,lsl #1
                 lsl r6,r6,#2
                 fldd d0,[r5,#32]
@@ -118,8 +142,11 @@ _Z13vfp_ChirpDataPA2_fS0_idid:
                 sub r3,r3,#8*7
                 
                 fldd d11,.Lhalfd
+#ifdef ANDROID
                 fldd d9,[sp,#stargidx]        // chirp_rate
                 fldd d10,[sp,#stargidx+16]   // sample_rate
+#endif //R: for armhf d9 and d10 already loaded 
+
                 fmuld d10,d10,d10
                 fmuld d9,d9,d11
                 fdivd d9,d9,d10
@@ -610,7 +637,7 @@ _Z13vfp_ChirpDataPA2_fS0_idid:
 .Lendoffunc:
                 mov r0,#0
                 vpop {d8,d9,d10,d11,d12,d13,d14,d15}
-                pop {r4,r5,r6,r7,r8,lr}
+                pop {r4,r5,r6,r7,r8,r9,lr}
                 bx lr
                 
                 .align  2
@@ -624,25 +651,6 @@ _Z13vfp_ChirpDataPA2_fS0_idid:
  * Author: Mateusz Szpakowski
  */
 
-#if defined(__VFP_FP__) && !defined(__SOFTFP__)
-		.syntax unified
-#endif	
-                .arch armv6
-                .fpu vfp
-#if defined(__VFP_FP__) && !defined(__SOFTFP__)
-		.eabi_attribute 27, 3
-		.eabi_attribute 28, 1
-#endif
-	
-                .eabi_attribute 20, 1
-                .eabi_attribute 21, 1
-                .eabi_attribute 23, 3
-                .eabi_attribute 24, 1
-                .eabi_attribute 25, 1
-                .eabi_attribute 26, 2
-                .eabi_attribute 30, 2
-                .eabi_attribute 18, 4
-                .text
                 .align  2
                 /*****
                  * fold array by 3 
@@ -2133,26 +2141,6 @@ vfpFoldMain:
  * vfp_GetPowerSpectrum.S
  * Author: Mateusz Szpakowski
  */
-
-#if defined(__VFP_FP__) && !defined(__SOFTFP__)
-		.syntax unified
-#endif	
-                .arch armv6
-                .fpu vfp
-#if defined(__VFP_FP__) && !defined(__SOFTFP__)
-		.eabi_attribute 27, 3
-		.eabi_attribute 28, 1
-#endif
-	
-                .eabi_attribute 20, 1
-                .eabi_attribute 21, 1
-                .eabi_attribute 23, 3
-                .eabi_attribute 24, 1
-                .eabi_attribute 25, 1
-                .eabi_attribute 26, 2
-                .eabi_attribute 30, 2
-                .eabi_attribute 18, 4
-                .text
                 .align  2
                 .global _Z20vfp_GetPowerSpectrumPA2_fPfi
                 .type   _Z20vfp_GetPowerSpectrumPA2_fPfi, %function
diff --git a/client/vector/analyzeFuncs_vfp_aux.cpp b/client/vector/analyzeFuncs_vfp_aux.cpp
index a3e6913..4ba95f7 100644
--- a/client/vector/analyzeFuncs_vfp_aux.cpp
+++ b/client/vector/analyzeFuncs_vfp_aux.cpp
@@ -33,7 +33,7 @@
 #include <vector>
 #include <cmath>
 
-#if defined(__arm__) && defined(__VFP_FP__) && !defined(__SOFTFP__)
+#if defined(__arm__) && defined(__VFP_FP__) && !defined(__SOFTFP__) || defined(__aarch64__)
 
 
 #define INVALID_CHIRP 2e+20
@@ -47,6 +47,7 @@
 #include "diagnostics.h"
 #include "asmlib.h"
 #include "pulsefind.h"
+#include "fp_arm.h"
 
 
 template <int x>
@@ -198,6 +199,7 @@ static inline int vfp_subTranspose2(int x, int y, float *in, float *out) {
 #ifdef USE_MANUAL_CALLSTACK
     call_stack.enter("vfp_subTranspose2()");
 #endif
+#if defined(__arm__) && defined(__VFP_FP__) && !defined(__SOFTFP__)
     __asm__ __volatile__ (
         "fldmias  %2, {s4, s5}\n"
         "fldmias  %3, {s6, s7}\n"
@@ -209,6 +211,19 @@ static inline int vfp_subTranspose2(int x, int y, float *in, float *out) {
     :  
     : "r" (out), "r" (out+y), "r" (in), "r" (in+x)
     : "s3", "s4", "s5", "s6", "s7" );
+#elif defined(__aarch64__)
+    __asm__ __volatile__ (
+        "ldp x4, x5, [%2], #16\n"
+        "ldp x6, x7, [%3], #16\n"
+        "mov x3,x6\n"
+        "mov x6,x5\n"
+        "mov x5,x3\n"
+        "stp x4, x5, [%0], #16\n"
+        "stp x6, x7, [%1], #16\n"
+        :
+        : "x" (out), "x" (out+y), "x" (in), "x" (in+x)
+        : "x3", "x4", "x5", "x6", "x7" );
+#endif
 #ifdef USE_MANUAL_CALLSTACK
     call_stack.exit();
 #endif
diff --git a/db/db_table.h b/db/db_table.h
index 12992e2..937b699 100644
--- a/db/db_table.h
+++ b/db/db_table.h
@@ -175,6 +175,7 @@ class db_table : public track_mem<T> {
 template <typename T>
 row_cache<T> db_table<T>::cache;
 
+#ifndef NEBULA
 template <typename T, typename ID_TYPE=long>
 class db_reference {
   private:
@@ -202,6 +203,82 @@ db_reference<T,ID_TYPE>::db_reference(ID_TYPE req_id) : id(*(ID_TYPE *)(&(r.id))
   id=req_id;
 }
 
+template <typename T,typename ID_TYPE>
+db_reference<T,ID_TYPE> &db_reference<T,ID_TYPE>::operator =(const T &t) {
+  if (&id != &(t.id)) {
+    r=t;
+  }
+  return *this;
+}
+
+template <typename T,typename ID_TYPE>
+db_reference<T,ID_TYPE> &db_reference<T,ID_TYPE>::operator =(const db_reference<T,ID_TYPE> &t) {
+  if (&id != &(t.id)) {
+    r=t.r;
+  }
+  return *this;
+}
+
+template <typename T, typename ID_TYPE>
+db_reference<T,ID_TYPE>::operator T() const {
+  return r;
+}
+
+template <typename T, typename ID_TYPE>
+T *db_reference<T,ID_TYPE>::operator ->() {
+  return &r;
+}
+
+template <typename T, typename ID_TYPE>
+const T *db_reference<T,ID_TYPE>::operator ->() const {
+  return &r;
+}
+
+template <typename T, typename ID_TYPE>
+std::string db_reference<T,ID_TYPE>::print(int full_subtables, int show_ids, int no_refs) const {
+  if (full_subtables) {
+    return r.print(full_subtables,show_ids,no_refs);
+  } else {
+    char buf[256];
+    sprintf(buf,"%"INT8_FMT,INT8_PRINT_CAST(sqlint8_t(r.id)));
+    return std::string(buf);
+  }
+}
+
+template <typename T, typename ID_TYPE>
+std::string db_reference<T,ID_TYPE>::print_xml(int full_subtables, int show_ids, int no_refs, const char *tag) const {
+  if (full_subtables) {
+    return r.print_xml(full_subtables,show_ids,no_refs,tag);
+  } else {
+    char buf[256];
+    sprintf(buf,"<id>%"INT8_FMT"</id>",INT8_PRINT_CAST(sqlint8_t(r.id)));
+    return std::string(buf);
+  }
+}
+
+template <typename T, typename ID_TYPE>
+void db_reference<T,ID_TYPE>::parse(const std::string &buf) {
+  r.parse(buf);
+}
+
+template <typename T, typename ID_TYPE>
+void db_reference<T,ID_TYPE>::parse(const SQL_ROW &buf) {
+  r.parse(buf);
+}
+
+template <typename T, typename ID_TYPE>
+void db_reference<T,ID_TYPE>::parse_xml(std::string &buf, const char *tag) {
+  r.parse_xml(buf,tag);
+}
+
+template <typename T, typename ID_TYPE>
+std::ostream &operator <<(std::ostream &o, const db_reference<T,ID_TYPE> &a) {
+  o << a.print_xml();
+  return o;
+}
+
+#endif // NEBULA
+
 template <typename T>
 db_type<T>::db_type(T &t) : track_mem<T>(T::type_name), me(&t) {}
 
@@ -224,21 +301,6 @@ db_table<T>::operator T() {
   return *me;
 }
 
-template <typename T, typename ID_TYPE>
-db_reference<T,ID_TYPE>::operator T() const {
-  return r;
-}
-
-template <typename T, typename ID_TYPE>
-T *db_reference<T,ID_TYPE>::operator ->() {
-  return &r;
-}
-
-template <typename T, typename ID_TYPE>
-const T *db_reference<T,ID_TYPE>::operator ->() const {
-  return &r;
-}
-
 #ifndef CLIENT
 template <typename T>
 sqlint8_t db_table<T>::insert(sqlint8_t lid) {
@@ -488,12 +550,6 @@ sqlint8_t db_table<T>::count(const std::string &where) {
   
 #endif
 
-template <typename T, typename ID_TYPE>
-std::ostream &operator <<(std::ostream &o, const db_reference<T,ID_TYPE> &a) {
-  o << a.print_xml();
-  return o;
-}
-
 template <typename T>
 const char *db_type<T>::search_tag(const char *s) {
   if (s) {
@@ -525,43 +581,6 @@ std::string db_type<T>::print_xml(int full_subtables, int show_ids, int no_refs,
   return me->print_xml(full_subtables,show_ids,no_refs,tag);
 }
 
-template <typename T, typename ID_TYPE>
-std::string db_reference<T,ID_TYPE>::print(int full_subtables, int show_ids, int no_refs) const {
-  if (full_subtables) {
-    return r.print(full_subtables,show_ids,no_refs);
-  } else {
-    char buf[256];
-    sprintf(buf,"%"INT8_FMT,INT8_PRINT_CAST(sqlint8_t(r.id)));
-    return std::string(buf);
-  }
-}
-
-template <typename T, typename ID_TYPE>
-std::string db_reference<T,ID_TYPE>::print_xml(int full_subtables, int show_ids, int no_refs, const char *tag) const {
-  if (full_subtables) {
-    return r.print_xml(full_subtables,show_ids,no_refs,tag);
-  } else {
-    char buf[256];
-    sprintf(buf,"<id>%"INT8_FMT"</id>",INT8_PRINT_CAST(sqlint8_t(r.id)));
-    return std::string(buf);
-  }
-}
-
-template <typename T, typename ID_TYPE>
-void db_reference<T,ID_TYPE>::parse(const std::string &buf) {
-  r.parse(buf);
-}
-
-template <typename T, typename ID_TYPE>
-void db_reference<T,ID_TYPE>::parse(const SQL_ROW &buf) {
-  r.parse(buf);
-}
-
-template <typename T, typename ID_TYPE>
-void db_reference<T,ID_TYPE>::parse_xml(std::string &buf, const char *tag) {
-  r.parse_xml(buf,tag);
-}
-
 template <typename T>
 db_type<T> &db_type<T>::operator =(const T &t) {
   if (me != &t) {
@@ -596,21 +615,5 @@ db_table<T> &db_table<T>::operator =(const db_table<T> &t) {
   return *this;
 }
 
-template <typename T,typename ID_TYPE>
-db_reference<T,ID_TYPE> &db_reference<T,ID_TYPE>::operator =(const T &t) {
-  if (&id != &(t.id)) {
-    r=t;
-  }
-  return *this;
-}
-
-template <typename T,typename ID_TYPE>
-db_reference<T,ID_TYPE> &db_reference<T,ID_TYPE>::operator =(const db_reference<T,ID_TYPE> &t) {
-  if (&id != &(t.id)) {
-    r=t.r;
-  }
-  return *this;
-}
-
 
 #endif
diff --git a/db/schema_master.cpp b/db/schema_master.cpp
index 3279e4a..6a7fffb 100644
--- a/db/schema_master.cpp
+++ b/db/schema_master.cpp
@@ -788,8 +788,8 @@ std::string data_description_t::print_xml(int full_subtables, int show_ids, int
 
 template <> const char * const db_table<receiver_config>::table_name="receiver_config";
 template <> const char * db_table<receiver_config>::_search_tag=table_name;
-template <> const int db_table<receiver_config>::_nfields=17;
-template <> const char * const db_table<receiver_config>::column_names[17]={"id","s4_id","name","beam_width","center_freq","latitude","longitude","elevation","diameter","az_orientation","az_corr_coeff","zen_corr_coeff","array_az_ellipse","array_za_ellipse","array_angle","min_vgc""polarization"};
+template <> const int db_table<receiver_config>::_nfields=20;
+template <> const char * const db_table<receiver_config>::column_names[20]={"id","s4_id","name","beam_width","center_freq","latitude","longitude","elevation","glat","glon","galt","diameter","az_orientation","az_corr_coeff","zen_corr_coeff","array_az_ellipse","array_za_ellipse","array_angle","min_vgc""polarization"};
 
 receiver_config::receiver_config() : 
 	db_table<receiver_config>(*this,-1),
@@ -800,6 +800,9 @@ receiver_config::receiver_config() :
 	latitude(0),
 	longitude(0),
 	elevation(0),
+	glat(0),
+	glon(0),
+	galt(0),
 	diameter(0),
 	az_orientation(0),
 	az_corr_coeff((float *)0,0,_x_csv),
@@ -824,6 +827,9 @@ receiver_config::receiver_config(const receiver_config &a) :
 	latitude(a.latitude),
 	longitude(a.longitude),
 	elevation(a.elevation),
+	glat(a.glat),
+	glon(a.glon),
+	galt(a.galt),
 	diameter(a.diameter),
 	az_orientation(a.az_orientation),
 	az_corr_coeff(a.az_corr_coeff),
@@ -868,6 +874,9 @@ receiver_config &receiver_config::operator =(const receiver_config &a) {
 		latitude=a.latitude;
 		longitude=a.longitude;
 		elevation=a.elevation;
+		glat=a.glat;
+		glon=a.glon;
+		galt=a.galt;
 		diameter=a.diameter;
 		az_orientation=a.az_orientation;
 		{
@@ -898,7 +907,7 @@ receiver_config &receiver_config::operator =(const receiver_config &a) {
 std::string receiver_config::update_format() const
 {	std::ostringstream rv("");
 
-	for (int i=2;i<17;i++) rv << "?,";
+	for (int i=2;i<20;i++) rv << "?,";
 	rv << "?";
 	return rv.str();
 }
@@ -911,7 +920,7 @@ std::string receiver_config::insert_format() const
 std::string receiver_config::select_format() const
 {
 std::string rv("");
-for (int i=0; i<16;i++) rv+="?,";
+for (int i=0; i<19;i++) rv+="?,";
 rv+="?";
 return rv;
 }
@@ -936,6 +945,12 @@ std::string receiver_config::print(int full_subtables, int show_ids, int no_refs
 	rv << ',';
 	rv << elevation;
 	rv << ',';
+	rv << glat;
+	rv << ',';
+	rv << glon;
+	rv << ',';
+	rv << galt;
+	rv << ',';
 	rv << diameter;
 	rv << ',';
 	rv << az_orientation;
@@ -998,6 +1013,9 @@ std::string receiver_config::print_xml(int full_subtables, int show_ids, int no_
 	rv << xml_indent() << "<latitude>" << latitude << "</latitude>\n";
 	rv << xml_indent() << "<longitude>" << longitude << "</longitude>\n";
 	rv << xml_indent() << "<elevation>" << elevation << "</elevation>\n";
+	rv << xml_indent() << "<glat>" << glat << "</glat>\n";
+	rv << xml_indent() << "<glon>" << glon << "</glon>\n";
+	rv << xml_indent() << "<galt>" << galt << "</galt>\n";
 	rv << xml_indent() << "<diameter>" << diameter << "</diameter>\n";
 	rv << xml_indent() << "<az_orientation>" << az_orientation << "</az_orientation>\n";
 	if (az_corr_coeff.size()) {
@@ -1089,6 +1107,24 @@ std::string receiver_config::print_xml(int full_subtables, int show_ids, int no_
 	        std::istringstream in(sub.c_str()+pos);
 	        in >> elevation;
 	      }
+	    if (extract_xml_record(field,"glat",sub)) {
+	        pos=sub.find(">");
+	        do { pos++; } while(sub[pos]=='\n');
+	        std::istringstream in(sub.c_str()+pos);
+	        in >> glat;
+	      }
+	    if (extract_xml_record(field,"glon",sub)) {
+	        pos=sub.find(">");
+	        do { pos++; } while(sub[pos]=='\n');
+	        std::istringstream in(sub.c_str()+pos);
+	        in >> glon;
+	      }
+	    if (extract_xml_record(field,"galt",sub)) {
+	        pos=sub.find(">");
+	        do { pos++; } while(sub[pos]=='\n');
+	        std::istringstream in(sub.c_str()+pos);
+	        in >> galt;
+	      }
 	    if (extract_xml_record(field,"diameter",sub)) {
 	        pos=sub.find(">");
 	        do { pos++; } while(sub[pos]=='\n');
@@ -1199,17 +1235,29 @@ std::string receiver_config::print_xml(int full_subtables, int show_ids, int no_
 	    }
 	  {  
 	        std::istringstream row(*(s[8]));
-	        row >> diameter;
+	        row >> glat;
 	    }
 	  {  
 	        std::istringstream row(*(s[9]));
+	        row >> glon;
+	    }
+	  {  
+	        std::istringstream row(*(s[10]));
+	        row >> galt;
+	    }
+	  {  
+	        std::istringstream row(*(s[11]));
+	        row >> diameter;
+	    }
+	  {  
+	        std::istringstream row(*(s[12]));
 	        row >> az_orientation;
 	    }
 	  {  
 	  std::string::size_type p,q;
 	  int i;
 	    az_corr_coeff.clear();
-	      SQL_ROW tmp(s[10]); 
+	      SQL_ROW tmp(s[13]); 
 	        for (i=0;i<tmp.argc();i++) {
 	          std::istringstream in(*(tmp[i]));
 	          float tmp0;
@@ -1221,7 +1269,7 @@ std::string receiver_config::print_xml(int full_subtables, int show_ids, int no_
 	  std::string::size_type p,q;
 	  int i;
 	    zen_corr_coeff.clear();
-	      SQL_ROW tmp(s[11]); 
+	      SQL_ROW tmp(s[14]); 
 	        for (i=0;i<tmp.argc();i++) {
 	          std::istringstream in(*(tmp[i]));
 	          float tmp0;
@@ -1230,29 +1278,29 @@ std::string receiver_config::print_xml(int full_subtables, int show_ids, int no_
 	      }
 	    }
 	  {  
-	        std::istringstream row(*(s[12]));
+	        std::istringstream row(*(s[15]));
 	        row >> array_az_ellipse;
 	    }
 	  {  
-	        std::istringstream row(*(s[13]));
+	        std::istringstream row(*(s[16]));
 	        row >> array_za_ellipse;
 	    }
 	  {  
-	        std::istringstream row(*(s[14]));
+	        std::istringstream row(*(s[17]));
 	        row >> array_angle;
 	    }
 	  {  
-	        std::istringstream row(*(s[15]));
+	        std::istringstream row(*(s[18]));
 	        row >> min_vgc;
 	    }
 	  {  
-	        strncpy(polarization,s[16]->c_str(),32);
+	        strncpy(polarization,s[19]->c_str(),32);
 	        polarization[31]=0;
 	    }
 	      }
 
 	void receiver_config::parse(const std::string &s) {
-	      SQL_ROW row(&s,17);
+	      SQL_ROW row(&s,20);
 	      parse(row);
 	      }
 
diff --git a/db/schema_master.h b/db/schema_master.h
index 34330c5..491e38e 100644
--- a/db/schema_master.h
+++ b/db/schema_master.h
@@ -21,7 +21,7 @@ inline int db_open() { return (db_is_open=1); }
 inline int db_close() { return !(db_is_open=0); }
 inline int db_change() { return (db_is_open=1); }
 #ifdef NEBULA
-typedef sqlint8_t long;
+typedef long sqlint8_t;
 template <typename T, typename ID_TYPE=long> 
 struct db_reference {
   ID_TYPE id;
@@ -29,6 +29,7 @@ struct db_reference {
   void parse(const std::string &buf) {};
   std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const {};
   std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=1, const char *tag=0) const {};
+  void parse(const SQL_ROW&) {};
 };
 #endif //NEBULA
 
@@ -150,6 +151,9 @@ class  receiver_config  : public db_table<receiver_config> {
 	double  latitude;
 	double  longitude;
 	double  elevation;
+	double  glat;
+	double  glon;
+	double  galt;
 	double  diameter;
 	double  az_orientation;
 	sqlblob<float>  az_corr_coeff ;
diff --git a/db/schema_master.sql b/db/schema_master.sql
index 6c54358..d8df6c0 100644
--- a/db/schema_master.sql
+++ b/db/schema_master.sql
@@ -80,6 +80,9 @@ create table receiver_config
     latitude float,
     longitude float,
     elevation float,
+    glat float,
+    glon float,
+    galt float,
     diameter smallfloat,
     az_orientation float,
     az_corr_coeff  list(float not null), 
diff --git a/db/xml_util.h b/db/xml_util.h
index 44ce6de..c4d16de 100644
--- a/db/xml_util.h
+++ b/db/xml_util.h
@@ -210,9 +210,7 @@ class xml_ifstream {
 #endif // 0
 
 #define XML_ENCODING "iso-8859-1"
-
-static const char * const xml_header=
-  "<?xml version=\"1.0\" encoding=\""XML_ENCODING"\"?>\n";
+static const char * const xml_header="<?xml version=\"1.0\" encoding=\"" XML_ENCODING "\"?>\n";
 
 // XML entity for tranlation table (not wchar_t compatible)
 struct xml_entity {
diff --git a/ops/bin/splitter_janitor_gbt b/ops/bin/splitter_janitor_gbt
new file mode 100755
index 0000000..e0557e4
--- /dev/null
+++ b/ops/bin/splitter_janitor_gbt
@@ -0,0 +1,272 @@
+#! /usr/bin/perl -w
+
+# where is the data?
+# $file_dir = "/disks/thumper/raid5_d/users/seti/dr2_data/production/processing";
+#$file_dir = "/home/seti/dr2_data/production/processing";
+$file_dir = "/mydisks/b/users/btldata";
+
+# $email_list = 'jeffc at ssl.berkeley.edu mattl at ssl.berkeley.edu korpela at ssl.berkeley.edu';
+# $email_list = 'jeffc at ssl.berkeley.edu';
+#$email_list = 'mattl at ssl.berkeley.edu jeffc at ssl.berkeley.edu';
+$email_list = 'jeffc at ssl.berkeley.edu';
+
+# num of seconds to keep files in _TO_BE_DELETED before actually deleting them
+$keep_for = 7*86400; # one week
+#$keep_for = 86400; # one day
+
+# what if we are missing beam/pol pairs out of the standard 14? should we move date to be deleted anyway?
+# 0 - no, 1 - yes;
+$delete_even_if_missing_beampols = 1;
+
+# where is seti_hsi.csh?
+$seti_hsi = "/home/boincadm/projects/sah/bin/seti_hsi.csh";
+
+# set informix env
+
+$informixdir = "/usr/local/informix";
+$currentpath = $ENV{"PATH"};
+$currentldlp = $ENV{"LD_LIBRARY_PATH"};
+$ENV{"INFORMIXDIR"}="${informixdir}";
+$ENV{"INFORMIXSERVER"}="sah_master_tcp";
+$ENV{"ONCONFIG"}="onconfig.sah_master";
+$ENV{"PATH"}="${informixdir}/bin:${currentpath}";
+$ENV{"LD_LIBRARY_PATH"}="${informixdir}/lib:${informixdir}/lib/esql:${currentldlp}";
+
+# if --check_only flag is specified, do "check only" for current directory, ignoring dot files, etc.
+# basically just check for existence at HPSS, and if all 14 tapes are in science db and
+# mail us the results without moving/deleting anything.
+
+# if --not_at_hpss flag is specified, this supercedes --check_only - and only outputs what files
+# are here at the lab and fully split/processed, but not yet copied to HPSS
+
+# if --ignore_matching_sizes is specified, ignore if files don't match in size - delete anyway if
+# otherwise deleteable
+
+# if --dir flag is specified, go into that file_dir instead of default file_dir
+
+# if --beams is specified, use that # of beams (default 64)
+# if --pols is specific, use that # of pols (default 2)
+
+$check_only = 0;
+$not_at_hpss = 0;
+$ignore_matching_sizes = 0;
+$totalbeams = 64;
+$totalpols = 2;
+$totalbeampols = $totalbeams * $totalpols;
+
+while ($arg = shift) {
+  if ($arg eq "--check_only") {
+    $file_dir = `pwd`;
+    chomp $file_dir;
+    $check_only = 1;
+    }
+  elsif ($arg eq "--not_at_hpss") {
+    $not_at_hpss = 1;
+    }
+  elsif ($arg eq "--ignore_matching_sizes") {
+    $ignore_matching_sizes = 1;
+    }
+  elsif ($arg eq "--dir") {
+    $file_dir = shift;
+    }
+  elsif ($arg eq "--beams") {
+    $totalbeams = shift;
+    }
+  elsif ($arg eq "--pols") {
+    $totalpols = shift;
+    }
+  else {
+    print "splitter_janitor [--dir file_dir] [--check_only|--not_at_hpss]\n";
+    exit(1);
+    }
+  }
+
+
+# get data file list
+
+if (! -d $file_dir) { 
+  print "no such directory: $file_dir\n";
+  exit(1);
+  }
+chdir $file_dir;
+undef @file_list;
+ at uniqobs = `/bin/ls *.[0-9][0-9][0-9][0-9].raw | sed 's/.[0-9][0-9][0-9][0-9].raw\$//' | sort | uniq`;
+foreach $obs (@uniqobs) {
+  chomp $obs;
+  $headobs = `/bin/ls $obs* | sort -n | head -1`;
+  chomp $headobs;
+  push @file_list, $headobs;
+  }
+chomp @file_list;
+
+$message = "Splitter Janitor Results:\n";
+if ($check_only == 1) {
+  $message .= "(doing check on data files in: $file_dir)\n";
+  }
+
+# is HPSS unavailable? if so, set warning, and undefine file_list and set check_only == 1
+# in order to go right to mail at end (don't care if we're doing not_at_hpss check)
+
+if ($not_at_hpss == 0) {
+  $check_hpss = `$seti_hsi --check`;
+  chomp $check_hpss;
+  if ($check_hpss eq "hpss is down") {
+    undef @file_list;
+    $check_only = 1;
+    $message .= "\nHPSS is currently unavailable - bailing...\n";
+    }
+  } 
+
+# moving on - main part:
+
+foreach $file (@file_list) {
+
+  $message .= "\n";
+  if ($not_at_hpss == 1 && 
+      ( -f "${file}.completely_done" || -f "${file}.completely_done_with_errors") &&
+      ! -f "${file}.at_hpss") { 
+    print "${file}\n";
+    }
+  elsif ($not_at_hpss == 0) {
+    if (! -f "${file}.at_hpss") {
+      $hsicommand = "$seti_hsi --list $file";
+      $retval = system ($hsicommand . "> /dev/null");
+      $retval = $retval >> 8;
+      if ($retval == 0) {
+        $message .= "${file}: had no .at_hpss suffix but actually IS at HPSS - touching ${file}.at_hpss\n";
+        system ("/bin/touch ${file}.at_hpss");
+        }
+      }
+    if (( (-f "${file}.completely_done" || -f "${file}.completely_done_with_errors") &&
+          -f "${file}.at_hpss") || $check_only == 1) {
+      $message .= "${file}: finished processing and xfering to hpss - checking...\n";
+      $domove = 1;
+      # double check that it is at HPSS
+      $hsicommand = "$seti_hsi --list $file";
+      $retval = system ($hsicommand . "> /dev/null");
+      $retval = $retval >> 8;
+      if ($retval == 1) {
+        $message .= "WARNING: ${file}: has .at_hpss suffix but IS NOT AT HPSS!\n";
+        # $domove = 0; # just a warning... still move if need be
+        }
+      else { 
+        $message .= "${file}: is at HPSS\n";
+        # now check that local/remote file sizes match     
+        $fsize = (stat($file))[7];
+		print "DEBUG: file size: - $fsize - \n";
+        $hsifsize = `$hsicommand | awk '{print \$5}'`;
+        chomp $hsifsize;
+        if ($fsize != $hsifsize && !$ignore_matching_sizes) {
+          $message .= "${file}: local size: $fsize HPSS size: $hsifsize -- DO NOT MATCH\n";
+          $domove = 0;
+          if (($hsifsize - $fsize) <= (134742016 * 5)) { # due to ragged files/software blanking - off by less then five buffers
+            $message .= "${file}: ... but the HSI size is <= 134742016 x 5 bytes (five buffers) different\n";
+            $message .= "${file}: ... we will assume due to ragged files/etc. and flag it as okay\n";
+            $domove = 1;
+            }
+          }
+        else { $message .= "${file}: local size: $fsize and HPSS size: $hsifsize match\n"; }
+        }
+      # final check - scan science database to make sure 
+      $dbcount = `echo "database sah2; select count(name) from tape where name = '${file}';" | dbaccess -e - 2>&1 | tail --l=+8 | head -1 | awk '{print \$1}'`;
+      chomp $dbcount;
+      #if ($dbcount != 14) {
+      if ($dbcount != $totalbeampols) {
+        #$message .= "${file}: tape does not have 14 entries in the tape table!\n";
+        $message .= "${file}: tape does not have ${totalbeampols} entries in the tape table!\n";
+        if ($delete_even_if_missing_beampols == 0) { # i.e. if we want to keep tapes around with missing beam/pol entries, then...
+          $domove = 0;
+          }
+        }
+      #else { $message .= "${file}: has all 14 entries in the tape table\n"; }
+      else { $message .= "${file}: has ${dbcount} entries in the tape table\n"; }
+      if ($domove == 1) { 
+        if ($check_only == 1) {
+          $message .= "${file}: completely processed and at HPSS\n";
+          }
+        else {
+          $moveto = "./_TO_BE_DELETED";
+          if (! (-f "${file}.completely_done" ||
+                 -f "${file}.completely_done_with_errors") ) { 
+            $message .= "${file}: tape not yet finished processing\n";
+            $domove = 0;
+            }
+          else {
+            if (-f "${file}.completely_done_with_errors") { $moveto = "./_TO_BE_DELETED"; }
+            }
+          if ($domove == 1) {
+            $thisdate = `/bin/date "+%F-%T"`;
+            chomp $thisdate;
+            if (-f "${file}.completely_done") { system ("/bin/mv ${file}.completely_done ./_COMPLETELY_DONE_HISTORY/${file}.completely_done.${thisdate}"); }
+            if (-f "${file}.completely_done_with_errors") { system ("/bin/mv ${file}.completely_done_with_errors ./_COMPLETELY_DONE_HISTORY/${file}.completely_done_with_errors.${thisdate}"); }
+            ($root, $seq, $ext) = split('\.', ${file});
+            system ("/bin/mv ${root}* $moveto");
+            #system ("/bin/mv ${file} $moveto");
+            #system ("/bin/mv ${file}.* $moveto");
+            $message .= "${file}: tape completely done and at HPSS - moved into $moveto\n";
+            } # end if $domove == 1
+          } # end if $check_only == 1
+        } # end if $domove = 1
+      } # end if file completely done
+    else {
+      $message .= "${file}: not finished processing/xfering to hpss yet\n";
+      if (! (-f "${file}.completely_done" || -f "${file}.completely_done_with_errors") ) {
+        $message .= "    ${file}: tape not yet finished processing\n";
+        }
+      if (! (-f "${file}.at_hpss")) {
+        $message .= "    ${file}: no .at_hpss file - not finished xfering?\n";
+        }
+      }
+    }
+  }
+
+# only bother with the actual file deleting if check_only == 0 && not_at_hpss == 0
+
+if ($not_at_hpss == 1) { exit (0); }
+
+if ($check_only == 0) {
+
+  if ($message ne "") { $message .= "\n"; } # if needed skip a line in case there's more
+  
+  chdir "./_TO_BE_DELETED";
+  undef @del_file_list;
+  open (LS,"/bin/ls . |");
+  while (<LS>) {
+    $thisfile = $_; chomp $thisfile;
+    if (/.[0-9][0-9][0-9][0-9].raw$/) { push @del_file_list, $_ }
+    }
+  close (LS);
+  chomp @del_file_list;
+  
+  foreach $del_file (@del_file_list) {
+    if (-l $del_file) {
+      $message .= "${del_file}: is a symbolic link.. skipping..\n";
+      }
+    else {
+      $cdmtime = (stat("${del_file}.completely_done"))[9];
+      $ahmtime = (stat("${del_file}.at_hpss"))[9];
+      # print "${del_file} $cdmtime $ahmtime\n";
+      $now = time();
+      if (($now - $cdmtime) > $keep_for && ($now - $ahmtime) > $keep_for) {
+        # Do not delete for real until we shake this out.  This is where the real delete would happen via : system ("/bin/rm -f ${del_file}*");
+        $cdmdelta = ($now - $cdmtime);
+        $ahmdelta = ($now - $ahmtime);
+        $message .= "${del_file}: finished splitting $cdmdelta seconds ago, copied to HPSS $ahmdelta seconds ago - deleting!\n";
+        }
+      }
+    }
+
+  }
+
+# send mail!
+
+if ($message ne "") {  
+  open(MAIL, "|/usr/sbin/sendmail -tv");
+  print MAIL "To: ${email_list}\n";
+  print MAIL 'From: seti at ssl.berkeley.edu' . "\n";
+  print MAIL "Subject: splitter_janitor report\n\n";
+  print MAIL "$message";
+  close(MAIL);
+  }
+
+exit (0);
diff --git a/splitter_pfb/Makefile.am b/splitter_pfb/Makefile.am
index ad175e2..60794a8 100644
--- a/splitter_pfb/Makefile.am
+++ b/splitter_pfb/Makefile.am
@@ -18,7 +18,7 @@ LINKOPTIONS=-Xlinker -R -Xlinker $(INFORMIXDIR)/lib:$(INFORMIXDIR)/lib/esql:$(LD
 AM_CFLAGS= -g -O3 -Wall $(INCLUDE_DIRS) -DUSE_INFORMIX @PTHREAD_CFLAGS@ -ISETILIB_PATH/include
 
 
-SYSLIBS = -lcrypto -ldl
+SYSLIBS = -lcrypto -ldl -larmadillo
 
 BOINCLIBS= -L$(BOINCDIR)/sched -lsched @MYSQL_LIBS@ @PTHREAD_LIBS@ -L$(BOINCDIR)/lib -lboinc_crypt -lboinc -L$(SSLDIR) -lcrypto -lssl
 
diff --git a/splitter_pfb/mb_dotransform.cpp b/splitter_pfb/mb_dotransform.cpp
index 8a2f8bd..8bcfa35 100644
--- a/splitter_pfb/mb_dotransform.cpp
+++ b/splitter_pfb/mb_dotransform.cpp
@@ -95,8 +95,8 @@ inline int quantize(float f,float stddev,int num_bits) {
         if (f<0) return 0;
         return static_cast<int>(round(f));
     case 8:
-        f*=(64.0/stddev);
-        if (f>127) return 127;
+        f*=(24.0/stddev);
+        if (f>127) return 128;
         if (f<-127) return -127;
         return static_cast<int>(round(f));
     default:
diff --git a/splitter_pfb/mb_read_blocks_guppi.cpp b/splitter_pfb/mb_read_blocks_guppi.cpp
index 5a005b1..700b0b2 100644
--- a/splitter_pfb/mb_read_blocks_guppi.cpp
+++ b/splitter_pfb/mb_read_blocks_guppi.cpp
@@ -74,8 +74,8 @@ struct hdrinfo {
     char frontend[24];      // Frontend used
     long double MJD_epoch;  // Starting epoch in MJD
     double fctr;            // Center frequency of the observing band (MHz)
-    double df;              // Frequency spacing between the channels (MHz)
-    double BW;              // Bandwidth of the observing band (MHz)
+    double df;              // Frequency spacing between the channels (MHz)		// in BL data, this is header item CHAN_BW
+    double BW;              // Bandwidth of the observing band (MHz)			// in BL data, this is header item OBSBW
     int nbits;              // Number of bits per data sample
     int nchan;              // Number of channels
     int rcvr_polns;         // Number of polns provided by the receiver
@@ -94,7 +94,7 @@ struct subint {
 
 unsigned long total_samples = 0;
 unsigned long limit_samples;
-unsigned long last_num_samples_read;
+unsigned long last_num_sample_bytes_read;
 
 #define RAW_DATA_HEADER_BUF_SIZE 32768
 //#define RAW_DATA_HEADER_BUF_SIZE 8192         // TODO would it help to do less reading/rewinding for each header?
@@ -156,6 +156,52 @@ void populate_header(
 ) {
 //-------------------------------------------------------
 
+
+#if 0
+	// orig frequency code:
+    // this assumes that channels are ordered with *descending* frequency 
+    // (the higher the channel, the lower the frequency) and that BW
+    // and df are always positive.
+    // TODO - channel ordering should come from a recorder_config field
+    this_tapebuffer.header.sky_freq =   (long int) (
+                              (double) 1e6 * 
+                              ( 
+                                (rawinput.pf.hdr.fctr   + 
+                                (rawinput.pf.hdr.BW/2)) -      
+                                ((control_block.channel+0.5) * rawinput.pf.hdr.df)
+                              )
+                            );
+#endif
+//#if 0
+	// new frequency code:
+    // this assumes in the case of *descending* frequency, both BW and df will
+    // be negative, otherwise positive.  Ie, this should work in all cases where
+    // the -BW and -df protocol is followed. 
+	this_tapebuffer.header.sky_freq =   (long int) ( 
+							(double) 1e6 *  
+	                        (  
+ 	                          (rawinput.pf.hdr.fctr   -  
+	 	                      (rawinput.pf.hdr.BW/2)) +  
+	                          ((control_block.channel+0.5) * rawinput.pf.hdr.df) 
+	                        ) 
+						  );
+//#endif
+
+fprintf(stderr, "rawinput.pf.hdr.BW is %f\n", rawinput.pf.hdr.BW);
+fprintf(stderr, "rawinput.pf.hdr.df is %f\n", rawinput.pf.hdr.df);
+	if(rawinput.pf.hdr.BW < 0) {
+ 		log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG,"Adjusting for negative BW : rawinput.pf.hdr.BW was %f ... ", rawinput.pf.hdr.BW); 
+		rawinput.pf.hdr.BW = fabs(rawinput.pf.hdr.BW);
+ 		log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG,"is %f ", rawinput.pf.hdr.BW); 
+	}
+	if(rawinput.pf.hdr.df < 0) {
+		log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, "Adjusting for negative BW : rawinput.pf.hdr.df was %f ... ", rawinput.pf.hdr.df); 
+		rawinput.pf.hdr.df = fabs(rawinput.pf.hdr.df);
+		log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG,"is %f ... ", rawinput.pf.hdr.df); 
+	}
+fprintf(stderr, "rawinput.pf.hdr.BW is %f\n", rawinput.pf.hdr.BW);
+fprintf(stderr, "rawinput.pf.hdr.df is %f\n", rawinput.pf.hdr.df);
+
     /* size of this header */
     this_tapebuffer.header.header_size = sizeof(this_tapebuffer.header);
 
@@ -174,16 +220,6 @@ void populate_header(
 
     /* there is no "dataseq in guppi data.  TODO - right? */
     //this_tapebuffer.header.dataseq = 0;
-
-    this_tapebuffer.header.sky_freq =   (long int) (
-                              (double) 1e6 * 
-                              ( 
-                                (rawinput.pf.hdr.fctr   - 
-                                (rawinput.pf.hdr.BW/2)) + 
-                                ((control_block.channel+0.5) * rawinput.pf.hdr.df)
-                              )
-                            );
-
     print_header(this_tapebuffer);
 }
 
@@ -363,7 +399,16 @@ int read_block(
 					
 			   		if(rawinput.gf.packetindex == control_block.curindx) {    // file integrity check - are we at the correct index?  Yes...
 
-						 fseek(rawinput.fil, gethlength(header_buf), SEEK_CUR);         // skip past header
+						 long seek_len;
+						 long hlength = (long)gethlength(header_buf);
+						 if(rawinput.pf.hdr.directio) {
+							seek_len = hlength + (512 - (hlength%512))%512;				// directio aligns on 512 byte boundaries
+							fprintf(stderr, "adjusting for directio (%d) : %ld becomes %ld\n", rawinput.pf.hdr.directio, hlength, seek_len);
+						 } else {
+							seek_len = hlength;											// not directio so no forced alignment
+							fprintf(stderr, "NOT adjusting for directio (%d) : %ld becomes %ld\n", rawinput.pf.hdr.directio, hlength, seek_len);
+						 }
+						 fseek(rawinput.fil, seek_len, SEEK_CUR);         				  // skip past header
 						 rv=0;
 						 
 						 if (control_block.currentblock > (control_block.startblock-1)){   // if we have reached user requested startblock (default 0)
@@ -381,14 +426,14 @@ int read_block(
                                // to the point of resumption.
                                if(control_block.currentblock >= control_block.last_block_done) {
                                     //if(control_block.vflag>=1) fprintf(stderr, "prior to unpack_samples : last : %ld total : %ld\n", 
-                                    //                                   last_num_samples_read, total_samples);
-						            last_num_samples_read = unpack_samples(rawinput.pf.sub.data     +   // start of raw data, ie channel 0
+                                    //                                   last_num_sample_bytes_read, total_samples);
+						            last_num_sample_bytes_read = unpack_samples(rawinput.pf.sub.data     +   // start of raw data, ie channel 0
                                                                            control_block.subint_offset, // this gets us to the requested channel 
                                                                            control_block.chanbytes,     // chanbytes does not include overlap
                                                                            control_block.polarization,
                                                                            this_tapebuffer);   			// unpack samples to the return vector   
-                                    if(control_block.vflag>=1) fprintf(stderr, "Just unpacked %ld samples from %ld bytes.  Total samples : %ld\n", 
-                                                                       last_num_samples_read, control_block.chanbytes, total_samples);
+                                    if(control_block.vflag>=1) fprintf(stderr, "Just unpacked %ld sample bytes from %ld chanbytes.  Total samples : %ld\n", 
+                                                                       last_num_sample_bytes_read, control_block.chanbytes, total_samples);
                                } else {
                                     log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG,"Not to point of resumption (%ld < %ld), skipping...\n", 
                                                         control_block.currentblock, control_block.last_block_done);
@@ -465,7 +510,7 @@ int read_block(
             retval = 0;     // we do not have a new block. Perhaps we just need to open the next file in the series.
         }
 
-    //if(control_block.vflag>=1) fprintf(stderr, "last_num_samples_read %ld chanbytes %ld\n", last_num_samples_read, control_block.chanbytes);
+    //if(control_block.vflag>=1) fprintf(stderr, "last_num_sample_bytes_read %ld chanbytes %ld\n", last_num_sample_bytes_read, control_block.chanbytes);
     return(retval);
 }
 
@@ -592,7 +637,9 @@ void dump_tapebuffer(char * file_prefix, int channel) {
                 exit(1);
         }
         for(int buffer_i=0; buffer_i < tapebuffer.size(); buffer_i++) {
+fprintf(stderr, "buffer_i %d\n", buffer_i);
             for(int buffer_j=0; buffer_j < tapebuffer[buffer_i].data.size(); buffer_j++) {
+//fprintf(stderr, "buffer_i %d buffer_j %ld\n", buffer_i, buffer_j);
                 fwrite((const void *)&tapebuffer[buffer_i].data[buffer_j].real(), 1, 1, dump_fp);
                 fwrite((const void *)&tapebuffer[buffer_i].data[buffer_j].imag(), 1, 1, dump_fp);
             }
@@ -611,6 +658,17 @@ long int read_blocks_guppi(char *           file_prefix,
                            int              vflag 
 ) {
 //-------------------------------------------------------
+// Note : a buffer is push_back()'ed to tapebuffer under two conditions:
+// 1) at the end of processing a guppi block.  This is by far the most
+//      common push_back() and will result in a tapebuffer of a standard
+//      length for a given file format until we reach the desired number
+//      of samples per call. The final buffer will likely be a partial
+//      buffer.
+// 2) Upon re-entry into read_blocks_guppi() for consecutive WUGs, we 
+//      push_back() a buffer with the left-over samples in the prior guppi 
+//      block. This will be a partial buffer.  The number of samples in 
+//      this buffer plus the number of samples in the final (partial) buffer 
+//      of the prior call should be the standard length.      
 
     int retval = 0;
     static bool first_time = true;
@@ -619,7 +677,7 @@ long int read_blocks_guppi(char *           file_prefix,
 
     long reent_total_samples = 0;
 
-    static unsigned long samples_left;
+    static unsigned long sample_bytes_left;
     static double start_data_time;
     static double end_data_time;
 	static int filecnt;
@@ -672,35 +730,35 @@ long int read_blocks_guppi(char *           file_prefix,
         for(int buffer_i=0; buffer_i < tapebuffer.size(); buffer_i++) {
             reent_total_samples += tapebuffer[buffer_i].data.size();
             if(control_block.vflag>=2) {
-                fprintf(stderr, "re-entry - tapebuffer %d has %ld samples\n", buffer_i, tapebuffer[buffer_i].data.size());
+                fprintf(stderr, "re-entry (start) - tapebuffer %d has %ld samples\n", buffer_i, tapebuffer[buffer_i].data.size());
             }
         }
         total_samples = reent_total_samples;        // starting this call with thais many samples :
         if(control_block.vflag>=2) {
-            fprintf(stderr, "re-entry - total_samples = %ld (%ld) in %ld tapebuffers\n", reent_total_samples, total_samples, tapebuffer.size());
+            fprintf(stderr, "re-entry (start) - total_samples = %ld (%ld) in %ld tapebuffers\n", reent_total_samples, total_samples, tapebuffer.size());
         }
     }  // end first/subsequent time logic 
 
 
     // take care of any samples left over in the guppi buffer
-    if(samples_left) {
-        if(control_block.vflag>=1) fprintf(stderr, "first getting the %ld samples_left starting at location %p\n", 
-                                           samples_left, rawinput.pf.sub.data + control_block.subint_offset + control_block.chanbytes - samples_left);
-	    last_num_samples_read = unpack_samples(rawinput.pf.sub.data + control_block.subint_offset + control_block.chanbytes - samples_left, 
-                                              samples_left,                          // samples left does not include overlap
+    if(sample_bytes_left) {
+        if(control_block.vflag>=1) fprintf(stderr, "first getting the %ld sample_bytes_left starting at location %p\n", 
+                                           sample_bytes_left, rawinput.pf.sub.data + control_block.subint_offset + control_block.chanbytes - sample_bytes_left);
+	    last_num_sample_bytes_read = unpack_samples(rawinput.pf.sub.data + control_block.subint_offset + control_block.chanbytes - sample_bytes_left, 
+                                              sample_bytes_left,                          // samples left does not include overlap
                                               control_block.polarization,
                                               this_tapebuffer);   				    // unpack samples to the return vector   
         tapebuffer.push_back(this_tapebuffer);                                      // this will be a partially full buffer
         this_tapebuffer.data.clear();       
-        samples_left = 0;
-    }
-    if(control_block.vflag>=2) {
-        long reent_total_samples = 0;
-        for(int buffer_i=0; buffer_i < tapebuffer.size(); buffer_i++) {
-            reent_total_samples += tapebuffer[buffer_i].data.size();
-            fprintf(stderr, "re-entry 2 tapebuffer %d has %ld samples\n", buffer_i, tapebuffer[buffer_i].data.size());
+        sample_bytes_left = 0;
+        if(control_block.vflag>=2) {
+            long reent_total_samples = 0;
+            for(int buffer_i=0; buffer_i < tapebuffer.size(); buffer_i++) {
+                reent_total_samples += tapebuffer[buffer_i].data.size();
+                fprintf(stderr, "re-entry (after adding leftover) tapebuffer %d has %ld samples\n", buffer_i, tapebuffer[buffer_i].data.size());
+            }
+            fprintf(stderr, "re-entry (after adding leftover) - total_samples = %ld (%ld) in %ld tapebuffers\n", reent_total_samples, total_samples, tapebuffer.size());
         }
-        fprintf(stderr, "re-entry 2 - total_samples = %ld (%ld) in %ld tapebuffers\n", reent_total_samples, total_samples, tapebuffer.size());
     }
     // end take care of any samples left over in the guppi buffer
 
@@ -724,7 +782,7 @@ long int read_blocks_guppi(char *           file_prefix,
                     this_tapebuffer
                  );
             if(retval && this_tapebuffer.data.size() > 0) {         // if retval (OK) and no data, assume fast forward resumption
-                this_tapebuffer.header.data_size = last_num_samples_read;
+                this_tapebuffer.header.data_size = last_num_sample_bytes_read;
                 tapebuffer.push_back(this_tapebuffer);
                 if(control_block.vflag>=1) print_header(this_tapebuffer);
                 round++;
@@ -732,33 +790,29 @@ long int read_blocks_guppi(char *           file_prefix,
             }
         if(control_block.vflag>=2) {
             reent_total_samples = 0;
-//          for(int buffer_i=0; buffer_i < tapebuffer.size(); buffer_i++) {
-//              reent_total_samples += tapebuffer[buffer_i].data.size();
-//          }
-//          fprintf(stderr, "re-entry 3 - total_samples = %ld (%ld) in %ld tapebuffers\n", reent_total_samples, total_samples, tapebuffer.size());
         }          
     } while((!(rawinput.invalid))                                                       && 
             total_samples < limit_samples);
     fprintf(stderr, "========================================================\n");
     // end read blocks until we run out of data or the numblocks request is met
 
-    samples_left = control_block.chanbytes - last_num_samples_read;             // set up for next call
+    sample_bytes_left = control_block.chanbytes - last_num_sample_bytes_read;             // set up for next call
 
     // optionally dump a full tapebuffer
     if(dumpraw) dump_tapebuffer(file_prefix, channel);
          
     if(control_block.vflag>=1) {
              fprintf(stderr, "NUM SAMPLES total %ld final buffer contains %ld of a possible %d leaving %ld for the next time through\n", 
-             total_samples, last_num_samples_read, control_block.chanbytes, control_block.chanbytes-last_num_samples_read);
+             total_samples, last_num_sample_bytes_read, control_block.chanbytes, control_block.chanbytes-last_num_sample_bytes_read);
     }
 
     if(control_block.vflag>=2) {
         reent_total_samples = 0;
         for(int buffer_i=0; buffer_i < tapebuffer.size(); buffer_i++) {
             reent_total_samples += tapebuffer[buffer_i].data.size();
-            fprintf(stderr, "re-entry 4 tapebuffer %d has %ld samples\n", buffer_i, tapebuffer[buffer_i].data.size());
+            fprintf(stderr, "finish tapebuffer %d has %ld samples\n", buffer_i, tapebuffer[buffer_i].data.size());
         }
-        fprintf(stderr, "re-entry 4 - total_samples = %ld (%ld) in %ld tapebuffers\n", reent_total_samples, total_samples, tapebuffer.size());
+        fprintf(stderr, "finish - total_samples = %ld (%ld) in %ld tapebuffers\n", reent_total_samples, total_samples, tapebuffer.size());
     }
 
     fprintf(stderr, "getting coordinate history...\n");
@@ -803,13 +857,14 @@ unsigned long unpack_samples_2bit(unsigned char * raw, long int count, int pol,
      // short circuit in the case of getting the total number of samples that we want.
      // The raw pointer will left where it is for the next time through.
 	 for(i=0; i < count && total_samples < limit_samples; i+=stride) {
-          // Note that we swap real/imag from the guppi ordering to get the order that the splitter expects.
-          // imag (2 bits of raw data)
-		  sample.imag( (signed char)quantlookup[( raw[i] >> (pol_shift * 2)      & 1)        +   // bit 0 or 4  
+          // TODO - for some data sets we may need to flip i and q.  Whether or not to do this
+          // should come from a boolean in the recorder_config table.
+          // real (2 bits of raw data)
+		  sample.real( (signed char)quantlookup[( raw[i] >> (pol_shift * 2)      & 1)        +   // bit 0 or 4  
                                                 ((raw[i] >> (pol_shift * 2 + 1)  & 1) * 2)]      // bit 1 or 5
                      ); 
-		  // real (2 bits of raw data)
-		  sample.real( (signed char)quantlookup[( raw[i] >> ((pol_shift+1) * 2)      & 1)      +   // bit 2 or 6 
+		  // imag (2 bits of raw data)
+		  sample.imag( (signed char)quantlookup[( raw[i] >> ((pol_shift+1) * 2)      & 1)      +   // bit 2 or 6 
                                                 ((raw[i] >> ((pol_shift+1) * 2 + 1)  & 1) * 2)]    // bit 3 or 7
                      ); 
           // add this sample to our vector
@@ -822,7 +877,8 @@ unsigned long unpack_samples_2bit(unsigned char * raw, long int count, int pol,
 //fprintf(stderr, "old data  : %d %d  new data  :  %d %d\n", samples[2], samples[3], this_tapebuffer.data[1].real(), this_tapebuffer.data[1].imag());
 //fprintf(stderr, "old data  : %d %d  new data  :  %d %d\n", samples[count*2-2], samples[count*2-1], this_tapebuffer.data[count-1].real(), this_tapebuffer.data[count-1].imag());
 
-	 return i/stride;   // == i in this case
+	 //return i/stride;   // == i in this case
+	 return i;            // return the number of bytes (not samples) read
 }
 
 
@@ -838,15 +894,17 @@ unsigned long unpack_samples_8bit(unsigned char * raw, long int count, int pol,
      std::complex<signed char> sample;
 
 	 for(i=0; i < count && total_samples < limit_samples; i+=stride) {
-          // Note that we swap real/imag from the guppi ordering to get the order that the splitter expects.
-          sample.imag(raw[i+pol_shift]);
-          sample.real(raw[i+1+pol_shift]);
+          // TODO - for some data sets we may need to flip i and q.  Whether or not to do this
+          // should come from a boolean in the recorder_config table.
+          sample.real(raw[i+pol_shift]);
+          sample.imag(raw[i+1+pol_shift]);
           // add this sample to our vector
           this_tapebuffer.data.push_back(sample);
           total_samples++;
 	 }
 
-	 return i/stride;
+	 //return i/stride;
+	 return i;            // return the number of bytes (not samples) read
 }
 
 
diff --git a/splitter_pfb/mb_wufiles.cpp b/splitter_pfb/mb_wufiles.cpp
index 4d031d7..b1d1d32 100644
--- a/splitter_pfb/mb_wufiles.cpp
+++ b/splitter_pfb/mb_wufiles.cpp
@@ -143,7 +143,7 @@ int make_wu_headers(std::vector<dr2_compact_block_t> &tapebuffer,
   double numtrip=std::min(3.25215e+12/std::min(wugrp.data_desc.true_angle_range,10.0),1.44774e+13);
 
   // check for VLAR workunits
-  if (wugrp.data_desc.true_angle_range < 1.2*wugrp.receiver_cfg->beam_width) {
+  if (wugrp.data_desc.true_angle_range < 2.4*wugrp.receiver_cfg->beam_width) {
     group_is_vlar=true;
   } else {
     group_is_vlar=false;
diff --git a/validate/Makefile.in b/validate/Makefile.in
index 3b8d5dc..89bda2d 100644
--- a/validate/Makefile.in
+++ b/validate/Makefile.in
@@ -32,6 +32,7 @@ MYSQL_LIBS      = @MYSQL_LIBS@
 INFORMIXDIR     = @INFORMIXDIR@
 INFORMIX_CFLAGS = @INFORMIX_CFLAGS@
 INFORMIX_LIBS   = @INFORMIX_LIBS@
+SYSLIBS 		= -larmadillo
 
 OBJS = \
     sah_validate.$(OBJEXT) \
@@ -60,7 +61,7 @@ all: Makefile $(PROG)
 	(cd ..; make config.h)
 
 $(PROG): $(OBJS) $(BOINC_OBJS)
-	$(CXX) $(OBJS) $(BOINC_OBJS) -I../db $(BOINC_CFLAGS) $(CLIBS) $(BOINC_LIBS) $(MYSQL_LIBS) $(INFORMIX_LIBS) -o $(PROG)
+	$(CXX) $(OBJS) $(BOINC_OBJS) -I../db $(BOINC_CFLAGS) $(CLIBS) $(BOINC_LIBS) $(MYSQL_LIBS) $(INFORMIX_LIBS) -o $(PROG) $(SYSLIBS)
 
 clean:
 	rm -f *.$(OBJEXT) $(PROG) dependencies config.log config.cache
diff --git a/validate/sah_validate.cpp b/validate/sah_validate.cpp
index b1167f3..4bd3a29 100644
--- a/validate/sah_validate.cpp
+++ b/validate/sah_validate.cpp
@@ -45,6 +45,13 @@ void VALIDATE_STATS::print() {
 
 VALIDATE_STATS validate_stats;
 
+// the init and usage functions are required by boinc
+int validate_handler_init(int, char**) {
+    return 0;
+}
+void validate_handler_usage() {
+}
+
 // check_set() is called from BOINC code and is passed a vector of all
 // received results for work unit.  check_set() determines the canonical
 // result and flags each result as to whether it is similar enough to the

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-boinc/boinc-app-seti.git



More information about the pkg-boinc-commits mailing list