[boinc-app-seti] 01/03: Imported Upstream version 7.28~svn2385
Gianfranco Costamagna
locutusofborg-guest at moszumanska.debian.org
Thu Jun 5 17:38:23 UTC 2014
This is an automated email from the git hooks/post-receive script.
locutusofborg-guest pushed a commit to branch master
in repository boinc-app-seti.
commit f02069e04f1670410935d15fb5e57312bab8677e
Author: Gianfranco Costamagna <costamagnagianfranco at yahoo.it>
Date: Thu Jun 5 19:17:57 2014 +0200
Imported Upstream version 7.28~svn2385
---
client/analyzeFuncs.cpp | 21 +-
client/analyzePoT.cpp | 6 +-
client/analyzePoT.h | 2 +
client/analyzeReport.cpp | 28 +
client/chirpfft.cpp | 35 +
client/classes/ICoreSigProc/ICoreSigProc.cpp | 53 ++
client/classes/ICoreSigProc/ICoreSigProc.h | 43 ++
client/classes/classes_history.txt | 48 ++
gbt_splitter/Makefile.am | 66 ++
gbt_splitter/angdist.cpp | 79 +++
gbt_splitter/angdist.h | 33 +
gbt_splitter/cmap_interp.cpp | 40 ++
gbt_splitter/cmap_interp.h | 6 +
gbt_splitter/coordcvt.cpp | 179 +++++
gbt_splitter/coordcvt.h | 40 ++
gbt_splitter/db_fns.cpp | 199 ++++++
gbt_splitter/db_fns.h | 48 ++
gbt_splitter/dotransform.cpp | 218 ++++++
gbt_splitter/dotransform.h | 56 ++
gbt_splitter/encode.cpp | 93 +++
gbt_splitter/encode.h | 39 ++
gbt_splitter/fftw.h | 413 ++++++++++++
gbt_splitter/four1.cpp | 88 +++
gbt_splitter/four1.h | 31 +
gbt_splitter/gencoeff.py | 143 ++++
gbt_splitter/hr_min_sec.cpp | 131 ++++
gbt_splitter/hr_min_sec.h | 106 +++
gbt_splitter/makebufs.cpp | 139 ++++
gbt_splitter/makebufs.h | 38 ++
gbt_splitter/mb_angdist.cpp | 88 +++
gbt_splitter/mb_angdist.h | 36 +
gbt_splitter/mb_dotransform.cpp | 511 ++++++++++++++
gbt_splitter/mb_dotransform.h | 73 ++
gbt_splitter/mb_message.cpp | 73 ++
gbt_splitter/mb_polyphase.cpp | 150 +++++
gbt_splitter/mb_splitter.cpp | 966 +++++++++++++++++++++++++++
gbt_splitter/mb_splitter.h | 145 ++++
gbt_splitter/mb_splittypes.h | 114 ++++
gbt_splitter/mb_validrun.cpp | 147 ++++
gbt_splitter/mb_validrun.h | 35 +
gbt_splitter/mb_wufiles.cpp | 689 +++++++++++++++++++
gbt_splitter/mb_wufiles.h | 46 ++
gbt_splitter/message.cpp | 65 ++
gbt_splitter/message.h | 40 ++
gbt_splitter/polyphase.cpp | 149 +++++
gbt_splitter/polyphase.h | 26 +
gbt_splitter/randomdata.cpp | 77 +++
gbt_splitter/readheader.cpp | 225 +++++++
gbt_splitter/readheader.h | 42 ++
gbt_splitter/readtape.cpp | 333 +++++++++
gbt_splitter/readtape.h | 85 +++
gbt_splitter/splitparms.h | 145 ++++
gbt_splitter/splitter.cpp | 717 ++++++++++++++++++++
gbt_splitter/splitter.h | 132 ++++
gbt_splitter/splittypes.h | 111 +++
gbt_splitter/squarewave.cpp | 75 +++
gbt_splitter/tags | 463 +++++++++++++
gbt_splitter/tools/disksplitter | 121 ++++
gbt_splitter/tools/sah_splitter.sh | 150 +++++
gbt_splitter/uttolst.h | 2 +
gbt_splitter/validrun.cpp | 181 +++++
gbt_splitter/validrun.h | 33 +
gbt_splitter/writeheader.cpp | 105 +++
gbt_splitter/writeheader.h | 39 ++
gbt_splitter/wufiles.cpp | 679 +++++++++++++++++++
gbt_splitter/wufiles.h | 39 ++
66 files changed, 9518 insertions(+), 10 deletions(-)
diff --git a/client/analyzeFuncs.cpp b/client/analyzeFuncs.cpp
index 46f745d..552dad3 100644
--- a/client/analyzeFuncs.cpp
+++ b/client/analyzeFuncs.cpp
@@ -654,15 +654,18 @@ int seti_analyze (ANALYSIS_STATE& state) {
// If PoT freq bin is non-negative, we are into PoT analysis
// for this cfft pair and need not redo spike and autocorr finding.
if (state.PoT_freq_bin == -1) {
- state.FLOP_counter+=(double)fftlen;
- retval = FindSpikes(
- &PowerSpectrum[CurrentSub],
- fftlen,
- ifft,
- swi
- );
- if (retval) SETIERROR(retval,"from FindSpikes");
-
+ //JWS: Don't look for Spikes at too short FFT lengths.
+ if (fftlen >= PoTInfo.SpikeMin) {
+ state.FLOP_counter+=(double)fftlen;
+ retval = FindSpikes(
+ &PowerSpectrum[CurrentSub],
+ fftlen,
+ ifft,
+ swi
+ );
+ if (retval) SETIERROR(retval,"from FindSpikes");
+ }
+
if (fftlen==ac_fft_len) {
retval = FindAutoCorrelation(
AutoCorrelation,
diff --git a/client/analyzePoT.cpp b/client/analyzePoT.cpp
index 4888eea..1358121 100644
--- a/client/analyzePoT.cpp
+++ b/client/analyzePoT.cpp
@@ -600,7 +600,11 @@ void ComputePoTInfo(int num_cfft, int NumDataPoints) {
PoTInfo.PulseFftMax = swi.analysis_cfg.pulse_fft_max;
PoTInfo.TripletThresh = swi.analysis_cfg.triplet_thresh;
PoTInfo.TripletMax = swi.analysis_cfg.triplet_max;
- PoTInfo.TripletMin = swi.analysis_cfg.triplet_min;
+ //JWS: Don't process Triplet PoTs too short to produce a reportable signal.
+ PoTInfo.TripletMin = std::max((int)swi.analysis_cfg.triplet_min,
+ (int)(ceil(3.0 * swi.analysis_cfg.triplet_thresh)));
+ //JWS: Nor Spike PoFs.
+ PoTInfo.SpikeMin = (int)(ceil(swi.analysis_cfg.spike_thresh));
PoTInfo.GaussChiSqThresh = swi.analysis_cfg.gauss_chi_sq_thresh;
PoTInfo.GaussPowerThresh = swi.analysis_cfg.gauss_power_thresh;
PoTInfo.GaussPeakPowerThresh = swi.analysis_cfg.gauss_peak_power_thresh;
diff --git a/client/analyzePoT.h b/client/analyzePoT.h
index a58d917..6e230c0 100644
--- a/client/analyzePoT.h
+++ b/client/analyzePoT.h
@@ -65,6 +65,8 @@ typedef struct {
double TripletThresh;
int TripletMax;
int TripletMin;
+
+ int SpikeMin;
}
PoTInfo_t;
diff --git a/client/analyzeReport.cpp b/client/analyzeReport.cpp
index 7fd3d8f..524e53d 100644
--- a/client/analyzeReport.cpp
+++ b/client/analyzeReport.cpp
@@ -173,6 +173,12 @@ int result_spike(SPIKE_INFO &si) {
#endif
int retval=0;
+ //R: & JWS: sanity check for found result
+ if(si.s.peak_power > si.s.fft_len){
+ boinc_temporary_exit(5*60,"Impossible Spike, retrying from checkpoint.");
+ }
+
+
retval = outfile.printf("%s", si.s.print_xml(0,0,1).c_str());
if (retval < 0) {
@@ -197,6 +203,12 @@ int result_autocorr(AUTOCORR_INFO &ai) {
call_stack.enter("result_autocorr()");
#endif
+ //R: & JWS: sanity check for found result
+ if(ai.a.peak_power > 100.0){
+ boinc_temporary_exit(5*60,"Improbable Autocorr, retrying from checkpoint.");
+ }
+
+
int retval=0;
retval = outfile.printf("%s", ai.a.print_xml(0,0,1).c_str());
@@ -223,6 +235,11 @@ int result_gaussian(GAUSS_INFO &gi) {
call_stack.enter("result_gaussian()");
#endif
+ //R: & JWS: sanity check for found result
+ if(gi.g.peak_power > swi.analysis_cfg.gauss_pot_length){
+ boinc_temporary_exit(5*60,"Improbable Gaussian, retrying from checkpoint.");}
+
+
int retval=0;
retval = outfile.printf("%s", gi.g.print_xml(0,0,1).c_str());
@@ -269,6 +286,11 @@ int ReportTripletEvent(
BOINCASSERT(_CrtCheckMemory());
#endif
+ //JWS: sanity check for found result.
+ if(Power > (float)pot_len){
+ boinc_temporary_exit(5*60,"Impossible Triplet, retrying from checkpoint.");
+ }
+
if (!inv) inv = (int*)calloc_a(swi.analysis_cfg.triplet_pot_length, sizeof(int), MEM_ALIGN);
// triplet info
@@ -390,6 +412,12 @@ int ReportPulseEvent(float PulsePower,float MeanPower, float period,
BOINCASSERT(_CrtCheckMemory());
#endif
+ //JWS: sanity check for found result. The limit would be 4/3 * period,
+ // but discrete math and short PoTs can exceed that slightly.
+ if(PulsePower > 1.4 * period){
+ boinc_temporary_exit(5*60,"Impossible Pulse, retrying from checkpoint.");
+ }
+
// pulse info
pi.score=snr/thresh;
pi.p.peak_power=PulsePower-1;
diff --git a/client/chirpfft.cpp b/client/chirpfft.cpp
index 62e1812..e91ece9 100644
--- a/client/chirpfft.cpp
+++ b/client/chirpfft.cpp
@@ -49,6 +49,7 @@
#include "s_util.h"
#include "analyze.h"
#include "worker.h"
+#include "lcgamm.h"
#include "chirpfft.h"
#ifdef __arm__
#include "vector/fp_arm.h"
@@ -81,6 +82,38 @@ size_t GenChirpFftPairs(
long MaxPulseFFTLen=
std::min((unsigned long)(swi.nsamples/(swi.analysis_cfg.pulse_min*swi.analysis_cfg.pulse_beams*BeamsPerWU)),
(unsigned long)swi.analysis_cfg.pulse_fft_max);
+
+ //JWS: Adjustment to avoid Pulse finding for short PoT lengths which cannot
+ // produce a reportable signal. The adjustment is not applied until after a
+ // chirp/fft table entry has been generated using the original logic, otherwise
+ // it could affect Spikes and Triplets too.
+ long MaxPulseFFTLenAlt;
+ if(MaxPulseFFTLen < swi.analysis_fft_lengths[0]) {
+ // If motion is so extreme we already know there will be no pulsefinds, skip.
+ MaxPulseFFTLenAlt = MaxPulseFFTLen;
+ } else {
+ // Find actual longest allowed FFT length
+ for (i = swi.num_fft_lengths; i ; i--) {
+ MaxPulseFFTLenAlt = swi.analysis_fft_lengths[i - 1];
+ if (MaxPulseFFTLenAlt <= MaxPulseFFTLen) break;
+ }
+ // An ideal folded pulse PoT would have all power in one element, That won't ever
+ // happen with real data, but simulation by putting all power into the first or second
+ // element of the original PulsePoT makes all folded PoTs ideal. Under those conditions,
+ // the shortest period tested at fold by 3 is seen as the best of the folded PoTs. Thus,
+ // to check whether a particular PulsePotLen can or cannot produce a reportable pulse
+ // the math for that fold level is used to determine if the threshold is low enough
+ // that an ideal PoT would be reportable.
+ while (MaxPulseFFTLenAlt > 1) {
+ int PulsePotLen = (int)(((NumSamples / MaxPulseFFTLenAlt) / (swi.analysis_cfg.pulse_beams*BeamsPerWU)) + 0.5);
+ int di = (PulsePotLen / 2 + 1) / 2;
+ float thresh = invert_lcgf((float)(-swi.analysis_cfg.pulse_thresh - log((float)di)), 3.0f, 0.0001f);
+ if (thresh <= (float)PulsePotLen) break;
+ if (i) MaxPulseFFTLenAlt = swi.analysis_fft_lengths[--i];
+ else MaxPulseFFTLenAlt /= 2;
+ }
+ }
+
long NumLimits = (long)swi.analysis_cfg.chirps.size();
double * ChirpSteps ;
ChirpFftPair_t tmp;
@@ -128,6 +161,8 @@ size_t GenChirpFftPairs(
sh_sint8_t key=static_cast<sh_sint8_t>(floor(CRate/(*MinChirpStep)+0.5))*2;
key*=max_fft_len*2;
key+=tmp.FftLen;
+ //JWS: Finally, reset PulseFind if a reportable pulse cannot be found.
+ if (tmp.FftLen > MaxPulseFFTLenAlt) tmp.PulseFind=0;
// Insert the positive chirp overwriting any existing with this
// key value;
ChirpFftMap[key]=tmp;
diff --git a/client/classes/ICoreSigProc/ICoreSigProc.cpp b/client/classes/ICoreSigProc/ICoreSigProc.cpp
new file mode 100644
index 0000000..5cd5e22
--- /dev/null
+++ b/client/classes/ICoreSigProc/ICoreSigProc.cpp
@@ -0,0 +1,53 @@
+#include "ICoreSigProc.h"
+
+template class ICoreSigProc<float,float>;
+
+template< class _Tin, class _Tout >
+ICoreSigProc<_Tin,_Tout>::ICoreSigProc()
+: m_name("ICoreSigProc Class"),
+m_description("Abstract Signal processor class"),
+m_n(DEFAULT_SIZE), m_batch(1), m_self_allocated_arrays(true)
+{
+ this->Alloc_new(m_n,m_batch);
+}
+
+template< class _Tin, class _Tout >
+ICoreSigProc<_Tin,_Tout>::ICoreSigProc( int n, int batch, _Tin* idata, _Tout* odata)
+: m_name("ICoreSigProc Class"),
+m_description("Abstract Signal processor class"),
+m_n(n), m_batch(batch), m_self_allocated_arrays(false)
+{
+ m_idata = idata;
+ m_odata = odata;
+}
+
+template< class _Tin, class _Tout >
+void ICoreSigProc<_Tin,_Tout>::Alloc_new(int n, int batch)
+{
+ m_self_allocated_arrays = true;
+ m_idata = new _Tin[n*batch];
+ m_odata = new _Tout[n*batch];
+}
+
+template< class _Tin, class _Tout >
+ICoreSigProc<_Tin,_Tout>::~ICoreSigProc()
+{
+ if (m_self_allocated_arrays)
+ {
+ delete[] m_idata;
+ delete[] m_odata;
+ }
+}
+
+/*
+template <class _Tin,class _Tout>
+ICoreSigProc<_Tin,_Tout>::ICoreSigProc()
+: m_name("ICoreSigProc Class"),
+m_description("Abstract Signal processor class"),
+m_n(DEFAULT_SIZE), m_batch(1)
+{
+ FILE_LOG(logDEBUG1) << "ICoreSigProc::ICoreSigProc() called, for " << m_name << endl;
+ this->Alloc_new(m_n,m_batch);
+}
+*/
+
diff --git a/client/classes/ICoreSigProc/ICoreSigProc.h b/client/classes/ICoreSigProc/ICoreSigProc.h
new file mode 100644
index 0000000..9e49456
--- /dev/null
+++ b/client/classes/ICoreSigProc/ICoreSigProc.h
@@ -0,0 +1,43 @@
+#ifndef ICORESIGPROC_H
+#define ICORESIGPROC_H
+
+#include <string>
+#include <vector>
+
+using namespace std;
+
+#define DEFAULT_SIZE 1024
+
+template <class _Tin, class _Tout>
+class ICoreSigProc
+{
+ public:
+ /** Default constructor */
+ ICoreSigProc(void); // for performance, avoid the default destructor, which uses new/delete for data arrays
+ ICoreSigProc(int n, int batch, _Tin* idata, _Tout* odata);
+ ~ICoreSigProc(void);
+
+ virtual void execute()=0;
+
+ // member getters & setters
+ string Getname() { return m_name; }
+ void Setname(string val) { m_name = val; }
+ string Getdescription() { return m_description; }
+ void Setdescription(string val) { m_description = val; }
+ size_t Getn() { return m_n; }
+ // void Setn(size_t val) { m_n = val; }
+ size_t Getbatch() { return m_batch; }
+ // void Setbatch(size_t val) { m_batch = val; }
+ protected:
+ void Alloc_new(int n, int batch);
+ string m_name; //!< Member variable "m_name"
+ string m_description;
+ size_t m_n;
+ size_t m_batch;
+ _Tin *m_idata;
+ _Tout *m_odata;
+ private:
+ bool m_self_allocated_arrays;
+};
+
+#endif // ICORESIGPROC_H
diff --git a/client/classes/classes_history.txt b/client/classes/classes_history.txt
new file mode 100644
index 0000000..634aa71
--- /dev/null
+++ b/client/classes/classes_history.txt
@@ -0,0 +1,48 @@
+-----------------------------------------------------------------------------------------------------------
+31st May 2014 - Added folder structure for ITranspose and IPowerspectrum abstract base classes
+-----------------------------------------------------------------------------------------------------------
+30th May 2014 - Initial cut, for refinement as derived classes take shape
+(FFT's will be first cab off the rank, via IFFT abstract class deriving from this, followed by fftw, oura,
+cufft, oclfft and naive dft implementation classes)
+- ICoreSigProc: Abstract (pure virtual) base template class
+template parameters <_Tin, _Tout> are input and output types respectively.
+execute() member function is pure virtual, for polymorphic use of derived classes in pipelines.
+derived classes, abstract or otherwise, should either feed pointers through using the fully
+specified constructor, or the fairly useless default constructor will be used. Will probably disable that default constructor later.
+- Fully templatised so that higher & possibly arbitrary precision gold reference implementations
+can be easily injected in test pieces, regression tests etc, while using the same class library.
+-----------------------------------------------------------------------------------------------------------
+24th May 2014, (Part 2) [Added IPulse base class, derived from ISearch]
+- Folders for some candidate derived generic classes, for devices, signal processors, and pipelines.
+IDevices: CPUs, GPUs, and Remote nodes (future RPC)
+ICoreSigProcs: Generalisations of major search algorithm processing steps.
+IPipelineSigProcs: Generalises different levels of parallelism that may be used
+-- IFFTPipeline: Might be asked to process one or more FFT's in a given CFFT pair, up to a whole CFFT
+-- ICFFTPipeline: Might be asked to process from one CFFT up to a whole Chirp full.
+-- IChirpPipeline: Might be asked to process from one Chirp, up to a whole task.
+-- ITaskPipeline: Might process from one to many tasks at once (future)
+
+Jason Groothuis ( contact at jgopt dot org )
+-----------------------------------------------------------------------------------------------------------
+24th May 2014, (Part 1)
+ Initial trial folder structure (only), mirroring top level of proposed class hierarchy (currently inactive/unused). For dropping in candidate classes for refinement and future use.
+
+Due to a lack of naming convention for C++ Abstract Classes, I'll use common capitalisation for implementation classes, and prefix with 'I' for abstract ones. Will stay fairly flexible this early, should namespace conflicts arise here. (i.e. don't expect stable interfaces yet )
+
+Expect containers/enumeration at high level for easing future development.
+
+ICoreSigProc- Abstract signal processor class,
+- parent/ancestor of all derived FFT, Chirp, Spike, Triplet, Pulse, Gaussian and Autocorrelation generic classes.
+- Another generic abstraction level under this one for wrapping implementations below.
+
+IDevice- Abstract Processing resource class,
+- parent/ancestor of all compute devices capable of processing any portion of core signal processing in any fashion
+- Another generic abstraction level under this one, for wrapping different kinds of device.
+
+IPipelineSigProc- Abstract class pipelining of ICoreSigProcs and IDevices
+- Abstracts allowable processing order/reductions of results etc, and devices
+- represents the processing algorithm at the highest levels
+- implementations and generalisations underneath may represent totally different 'ways' of arriving at a reference 'answer'.
+
+Jason Groothuis ( contact at jgopt dot org )
+-----------------------------------------------------------------------------------------------------------
\ No newline at end of file
diff --git a/gbt_splitter/Makefile.am b/gbt_splitter/Makefile.am
new file mode 100644
index 0000000..990f9ef
--- /dev/null
+++ b/gbt_splitter/Makefile.am
@@ -0,0 +1,66 @@
+CC=gcc
+BOINCDIR=@BOINCDIR@
+INFORMIXDIR=@INFORMIXDIR@
+SETILIB_PATH=@SETILIB_PATH@
+SETILIB_LIBS=@SETILIB_LIBS@
+SETIHOME=..
+
+LINKOPTIONS=
+
+GSL_LIBS = -lgsl -lgslcblas -lgsl
+
+DBLIBS=@INFORMIX_LIBS@ -lm -lstdc++
+
+
+LINKOPTIONS=-Xlinker -R -Xlinker $(INFORMIXDIR)/lib:$(INFORMIXDIR)/lib/esql:$(LD_LIBRARY_PATH)
+
+
+AM_CFLAGS= -g -O3 -Wall $(INCLUDE_DIRS) -DUSE_INFORMIX @PTHREAD_CFLAGS@ -ISETILIB_PATH/include
+
+
+SYSLIBS = -lcrypto -ldl
+
+BOINCLIBS= -L$(BOINCDIR)/sched -lsched @MYSQL_LIBS@ @PTHREAD_LIBS@ -L$(BOINCDIR)/lib -lboinc_crypt -lboinc -L$(SSLDIR) -lcrypto -lssl
+
+SPLITLIBS= $(SETILIB_LIBS) \
+ $(DBLIBS) \
+ $(BOINCLIBS) \
+ $(SYSLIBS) \
+ -lchealpix \
+ -lfftw3f
+
+noinst_PROGRAMS = mb_splitter
+
+
+mb_splitter_SOURCES=mb_angdist.cpp \
+ mb_message.cpp \
+ mb_splitter.cpp \
+ mb_wufiles.cpp \
+ mb_dotransform.cpp \
+ mb_validrun.cpp \
+ cmap_interp.cpp \
+ ../db/schema_master.cpp \
+ ../db/sqlifx.cpp \
+ ../db/sqlrow.cpp \
+ ../db/sqlblob.cpp ../db/sqlint8.cpp \
+ ../db/xml_util.cpp \
+ ../db/app_config.cpp \
+ ../client/seti_header.cpp \
+ ../client/timecvt.cpp \
+ ../client/lcgamm.cpp \
+ ../client/hr_min_sec.o
+
+mb_splitter_CXXFLAGS= \
+ -O3 \
+ -I$(SETIHOME) -I$(SETIHOME)/client -I$(SETIHOME)/db \
+ @MYSQL_CFLAGS@ -I$(HEALPIX)/include \
+ @INFORMIX_CFLAGS@ @SETILIB_CFLAGS@ \
+ @BOINC_CFLAGS@ -I$(BOINCDIR)/tools -I$(BOINCDIR)/sched -I$(BOINCDIR)/db
+mb_splitter_CFLAGS=$(mb_splitter_CXXFLAGS)
+mb_splitter_LDFLAGS=-static $(AM_LDFLAGS) -L$(HEALPIX)/lib $(LINKOPTIONS)
+mb_splitter_LDADD=$(SPLITLIBS) $(GSL_LIBS)
+
+../db/sqlifx.cpp: ../db/sqlifx.ec
+ $(INFORMIXDIR)/bin/esql -e $<
+ mv sqlifx.c $*.cpp
+
diff --git a/gbt_splitter/angdist.cpp b/gbt_splitter/angdist.cpp
new file mode 100644
index 0000000..a4d9cf2
--- /dev/null
+++ b/gbt_splitter/angdist.cpp
@@ -0,0 +1,79 @@
+/*
+ * angdist.c
+ *
+ * Computes angular distance between two lat/lon points
+ *
+ * $Id: angdist.cpp,v 1.3.4.1 2006/12/14 22:24:37 korpela Exp $
+ *
+ */
+
+#include "sah_config.h"
+#include <cstdio>
+#include <cstdlib>
+#include <math.h>
+#include "seti_header.h"
+
+#define DTOR (M_PI/180)
+
+double angdist(double r1, double d1, double r2, double d2) {
+ double alpha,dist,d;
+
+ r1*=DTOR;
+ r2*=DTOR;
+ d1*=DTOR;
+ d2*=DTOR;
+ alpha=r1-r2;
+ dist=sin(d2)*sin(d1)+cos(d1)*cos(d2)*cos(alpha);
+ if ((dist*dist)<1) {
+ d=sqrt(1.0-dist*dist);
+ } else {
+ dist=1.0;
+ d=0.0;
+ }
+ dist=atan2(d,dist);
+ dist=dist/DTOR;
+ return (dist);
+}
+
+double angdist(const SCOPE_STRING &a, const SCOPE_STRING &b) {
+ return angdist(a.ra*15,a.dec,b.ra*15,b.dec);
+}
+
+/*
+ * $Log: angdist.cpp,v $
+ * Revision 1.3.4.1 2006/12/14 22:24:37 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.3 2003/09/11 18:53:37 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.2 2003/08/05 17:23:39 korpela
+ * More work on database stuff.
+ * Further tweaks.
+ *
+ * Revision 1.1 2003/07/29 20:35:31 korpela
+ *
+ * renames .C files to .cpp
+ *
+ * Revision 1.2 2003/06/03 01:01:15 korpela
+ *
+ * First working splitter under CVS.
+ *
+ * Revision 1.1 2003/06/03 00:16:08 korpela
+ *
+ * Initial splitter under CVS control.
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.1 1998/11/02 16:41:21 korpela
+ * Minor Change.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.1 1998/10/27 00:47:33 korpela
+ * Initial revision
+ *
+ *
+ */
diff --git a/gbt_splitter/angdist.h b/gbt_splitter/angdist.h
new file mode 100644
index 0000000..c3fc069
--- /dev/null
+++ b/gbt_splitter/angdist.h
@@ -0,0 +1,33 @@
+/*
+ * angdist.h
+ *
+ * Computes angular distance between two lat/lon points
+ *
+ * $Id: angdist.h,v 1.1 2003/06/03 00:16:09 korpela Exp $
+ *
+ */
+
+double angdist(double r1, double d1, double r2, double d2) ;
+double angdist(const SCOPE_STRING &a,const SCOPE_STRING &b);
+
+/*
+ * $Log: angdist.h,v $
+ * Revision 1.1 2003/06/03 00:16:09 korpela
+ *
+ * Initial splitter under CVS control.
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.1 1998/11/02 16:41:21 korpela
+ * Minor Change.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.1 1998/10/27 01:03:21 korpela
+ * Initial revision
+ *
+ *
+ */
+
diff --git a/gbt_splitter/cmap_interp.cpp b/gbt_splitter/cmap_interp.cpp
new file mode 100644
index 0000000..d431f92
--- /dev/null
+++ b/gbt_splitter/cmap_interp.cpp
@@ -0,0 +1,40 @@
+#include <map>
+#include <math.h>
+#include "setilib.h"
+#include "sqlrow.h"
+#include "sqlblob.h"
+#include "sqlapi.h"
+#include "db_table.h"
+#include "schema_master.h"
+
+coordinate_t cmap_interp(std::map<seti_time,coordinate_t> &map, seti_time &t) {
+ std::map<seti_time,coordinate_t>::iterator above(map.upper_bound(t));
+ std::map<seti_time,coordinate_t>::iterator below;
+ below=above;
+ if (above==map.begin()) {
+ above++;
+ } else {
+ below--;
+ }
+ if (above==map.end()) {
+ above--;
+ below--;
+ }
+ coordinate_t upper(above->second);
+ coordinate_t lower(below->second);
+ coordinate_t rv;
+
+ if ((upper.ra-lower.ra)>23) lower.ra+=24;
+ if ((lower.ra-upper.ra)>23) upper.ra+=24;
+ rv.time=t.jd().uval();
+ double f=(seti_time(t.jd()-JD1970,JD1970)-seti_time(days(lower.time)))/
+ days(upper.time-lower.time);
+ rv.ra=(upper.ra-lower.ra)*f+lower.ra;
+ rv.ra=fmod(rv.ra,24.0);
+ rv.dec=(upper.dec-lower.dec)*f+lower.dec;
+ return rv;
+}
+
+
+
+
diff --git a/gbt_splitter/cmap_interp.h b/gbt_splitter/cmap_interp.h
new file mode 100644
index 0000000..37ee520
--- /dev/null
+++ b/gbt_splitter/cmap_interp.h
@@ -0,0 +1,6 @@
+
+extern coordinate_t cmap_interp(std::map<seti_time,coordinate_t> &map, seti_time &t);
+
+
+
+
diff --git a/gbt_splitter/coordcvt.cpp b/gbt_splitter/coordcvt.cpp
new file mode 100644
index 0000000..959f231
--- /dev/null
+++ b/gbt_splitter/coordcvt.cpp
@@ -0,0 +1,179 @@
+/*
+ * coordcvt.c
+ *
+ * Celestial coordinate conversion routines.
+ *
+ * $Id: coordcvt.cpp,v 1.2.4.1 2006/12/14 22:24:37 korpela Exp $
+ *
+ */
+
+#include "sah_config.h"
+#include <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+
+#include "sqlrow.h"
+#include "sqlblob.h"
+#include "sqlapi.h"
+#include "db_table.h"
+#include "schema_master.h"
+
+#include <seti_tel.h>
+#include <seti_cfg.h>
+#include <seti_coord.h>
+
+#include "splitparms.h"
+#include "splittypes.h"
+#include "coordcvt.h"
+
+extern int gregorian;
+
+namespace SPLITTER {
+
+double jd_to_lmst(double jd, double longitude) {
+/*
+ * converts from julian date/time to local mean siderial time
+ *
+ */
+
+ double tu; /* time, in centuries from Jan 0, 2000 */
+ double tusqr;
+ double tucb;
+ double g; /* derrived from tu, used to calculate gmst */
+ double gmst; /* Greenwich Mean Sidereal Time */
+ double lmst; /* Local Mean Sidereal Time */
+ double jd0=floor(jd+0.5)-0.5; /* jd at noon GMT */
+ double ddtime=fmod((jd-jd0)*24,24); /* GMT hours */
+
+ tu = (jd0 - 2451545.0)/36525;
+ tusqr = tu * tu;
+ tucb = tusqr * tu;
+
+/* computation of the gmst at ddtime UT */
+
+ g = 24110.54841 + 8640184.812866 * tu + 0.093104 * tusqr - 6.62E-6 * tucb;
+
+ for (gmst = g; gmst < 0; gmst += 86400) ;
+
+ gmst /= 3600; /* GMST at 0h UT */
+ gmst += (1.0027379093 * ddtime); /* GMST at utime UT */
+
+ gmst=fmod(gmst,24);
+
+/* computation of lmst given gmst and longitude */
+
+ lmst = gmst + ((longitude/360) * 24);
+
+ if (lmst < 0)
+ lmst += 24;
+ lmst = fmod(lmst,24);
+ return(lmst);
+}
+
+
+void horz_to_equatorial(double alt, double azimuth, double lsthour,
+ double lat, double *ra, double *dec) {
+ double dec_rad, hour_ang_rad, zenith_ang=90.0-alt;
+ double temp;
+
+ zenith_ang*=(M_PI/180.0);
+ azimuth*=(M_PI/180.0);
+
+ dec_rad = asin ((cos(zenith_ang) * sin(lat*M_PI/180)) +
+ (sin(zenith_ang) * cos(lat*M_PI/180) * cos(azimuth)));
+
+ *dec = dec_rad * 180.0/M_PI; /* radians to decimal degrees */
+
+ temp = (cos(zenith_ang) - sin(lat*M_PI/180) * sin(dec_rad)) /
+ (cos(lat*M_PI/180) * cos(dec_rad));
+ if (temp > 1)
+ temp = 1;
+ else if (temp < -1)
+ temp = -1;
+ hour_ang_rad = acos (temp);
+
+ if (sin(azimuth) > 0.0) /* insure correct quadrant */
+ hour_ang_rad = (2 * M_PI) - hour_ang_rad;
+
+
+ /* to get ra, we convert hour angle to decimal degrees, */
+ /* convert degrees to decimal hours, and subtract the */
+ /* result from local sidereal decimal hours. */
+ *ra = lsthour - ((hour_ang_rad * 180.0/M_PI) / 15.0);
+
+ // Take care of wrap situations in RA
+ if (*ra < 0.0)
+ *ra += 24.0;
+ *ra=fmod(*ra,24);
+}
+#define D2R 0.017453292
+
+void AltAzCorrection(double *alt, double *az) {
+ double zen=90-*alt;
+ co_ZenAzCorrection((telescope_id)(gregorian?AOGREG_1420:AO_1420),&zen,az);
+ *alt=90-zen;
+}
+
+}
+
+void telstr_coord_convert(SCOPE_STRING *telstr, double lat, double lon) {
+
+ double lmst=SPLITTER::jd_to_lmst(telstr->st.jd,lon);
+
+ SPLITTER::AltAzCorrection(&(telstr->alt),&(telstr->az));
+ SPLITTER::horz_to_equatorial(telstr->alt, telstr->az, lmst, lat, &(telstr->ra),
+ &(telstr->dec));
+}
+
+/*
+ * $Log: coordcvt.cpp,v $
+ * Revision 1.2.4.1 2006/12/14 22:24:37 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.2 2003/09/11 18:53:37 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.1 2003/07/29 20:35:33 korpela
+ *
+ * renames .C files to .cpp
+ *
+ * Revision 1.3 2003/06/05 19:01:45 korpela
+ *
+ * Fixed coordiate bug that allowed RA>24 hours.
+ *
+ * Revision 1.2 2003/06/05 15:52:46 korpela
+ *
+ * Fixed coordinate bug that was using the wrong zenith angle from the telescope
+ * strings when handling units from the gregorian.
+ *
+ * Revision 1.1 2003/06/03 00:16:09 korpela
+ *
+ * Initial splitter under CVS control.
+ *
+ * Revision 3.1 2003/05/20 16:01:54 eheien
+ * *** empty log message ***
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.3 1999/03/05 01:47:18 korpela
+ * New zenith angle correction.
+ *
+ * Revision 2.2 1999/02/22 22:21:09 korpela
+ * Fixed half-day error.
+ *
+ * Revision 2.1 1998/11/02 16:41:21 korpela
+ * Minor Change.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.2 1998/10/27 00:48:48 korpela
+ * Bug fixes.
+ *
+ * Revision 1.1 1998/10/19 23:02:43 korpela
+ * Initial revision
+ *
+ *
+ */
+
diff --git a/gbt_splitter/coordcvt.h b/gbt_splitter/coordcvt.h
new file mode 100644
index 0000000..5595f06
--- /dev/null
+++ b/gbt_splitter/coordcvt.h
@@ -0,0 +1,40 @@
+/*
+ * coordcvt.h
+ *
+ * Celestial coordinate conversion routines.
+ *
+ * $Id: coordcvt.h,v 1.1 2003/06/03 00:16:09 korpela Exp $
+ *
+ */
+
+#ifndef COORDCVT_H
+#define COORDCVT_H
+
+double jd_to_lmst(double jd, double longitude);
+
+void horz_to_equatorial(double alt, double azimuth, double lsthour,
+ double lat, double *ra, double *dec);
+
+void telstr_coord_convert(SCOPE_STRING *telstr, double lat, double lon);
+
+#endif
+
+/*
+ * $Log: coordcvt.h,v $
+ * Revision 1.1 2003/06/03 00:16:09 korpela
+ *
+ * Initial splitter under CVS control.
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.1 1998/11/02 16:41:21 korpela
+ * Minor Change.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.1 1998/10/19 23:03:18 korpela
+ * Initial revision
+ *
+ */
diff --git a/gbt_splitter/db_fns.cpp b/gbt_splitter/db_fns.cpp
new file mode 100644
index 0000000..9234ed3
--- /dev/null
+++ b/gbt_splitter/db_fns.cpp
@@ -0,0 +1,199 @@
+/*
+ * $Id: db_fns.cpp,v 1.3.4.2 2006/12/14 22:24:37 korpela Exp $
+ *
+ */
+
+
+#include "sah_config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "splitparms.h"
+#include "splittypes.h"
+#include "splitter.h"
+#include "message.h"
+#include "readtape.h"
+#include "sqlrow.h"
+#include "sqlblob.h"
+#include "db_table.h"
+#include "schema_master.h"
+
+
+static tape tape_struct;
+
+int update_tape_entry( tapeheader_t *tapeheader) ;
+
+int get_last_block(tapeheader_t *tapeheader) {
+ int err;
+ strncat(tape_struct.tapename,tapeheader->name,20);
+ if (!db_tape_lookup_name(&tape_struct)) {
+ return(tape_struct.last_block_done/TAPE_FRAMES_PER_RECORD);
+ } else {
+ if ((err=db_tape_new(&tape_struct))) {
+ log_messages.printf( SCHED_MSG_LOG::MSG_CRITICAL,"Unable to create db entry for tape %s error %d.\n",tapeheader->name,err);
+ exit(1);
+ }
+ return 0;
+ }
+}
+
+
+/* returns id number of tape db entry or zero if failure */
+/*int update_tape_entry( tapeheader_t *tapeheader) {
+ if (strncmp(tapeheader->name,tape_struct.tapename,20)) {
+ strncat(tape_struct.tapename,tapeheader->name,20);
+ if (db_tape_lookup_name(&tape_struct)) {
+ tape_struct.id=0;
+ strncpy(tape_struct.tapename,tapeheader->name,20);
+ tape_struct.start_time=tapeheader->st.jd;
+ tape_struct.last_block_time=tapeheader->st.jd;
+ tape_struct.last_block_done=tapeheader->frameseq;
+ if (db_tape_new(&tape_struct)) {
+ char tmpstr[256];
+ fprintf( stderr, "Point 2\n" );
+ sprintf(tmpstr,"Unable to create db entry for tape %s.",tapeheader->name);
+ message(tmpstr);
+ return(0);
+ }
+ }
+ }
+ tape_struct.last_block_time=tapeheader->st.jd;
+ tape_struct.last_block_done=tapeheader->frameseq;
+ if (db_tape_update(&tape_struct)) {
+ char tmpstr[256];
+ sprintf(tmpstr,"Unable to update db entry for tape %s.",tapeheader->name);
+ message(tmpstr);
+ return(0);
+ }
+ return(tape_struct.id);
+}
+*/
+
+/* returns workunit group id number on success, 0 on failure */
+/*
+int create_wugrp_entry(workunit_grp &wugrp, int tapenum, tapeheader_t *tapeheader) {
+ int i,n;
+
+ wugrp.tapenum=tapenum;
+ strncpy(wugrp.wugrpname,wugrpname,64);
+ wugrp.splitter_version=wuheader->wuinfo.splitter_version;
+ wugrp.start_ra=wuheader->wuinfo.start_ra;
+ wugrp.start_dec=wuheader->wuinfo.start_dec;
+ wugrp.end_ra=wuheader->wuinfo.end_ra;
+ wugrp.end_dec=wuheader->wuinfo.end_dec;
+ wugrp.angle_range=wuheader->wuinfo.angle_range;
+ wugrp.true_angle_range=wuheader->wuinfo.true_angle_range;
+ wugrp.beam_width=wuheader->wuinfo.beam_width;
+ wugrp.time_recorded=wuheader->wuinfo.time_recorded;
+ wugrp.fft_len=wuheader->wuinfo.fft_len;
+ wugrp.ifft_len=wuheader->wuinfo.ifft_len;
+ wugrp.receiver=wuheader->wuinfo.source;
+ wugrp.nsamples=wuheader->wuinfo.nsamples;
+ wugrp.sample_rate=tapeheader->samplerate;
+ wugrp.data_class=wuheader->wuinfo.data_class;
+ strncpy(wugrp.tape_version,wuheader->wuinfo.tape_version,13);
+ wugrp.num_positions=wuheader->wuinfo.num_positions;
+ if (db_workunit_grp_new(&wugrp)) {
+ char tmpstr[256];
+ sprintf(tmpstr,"Unable to create db entry for workunit_grp %s\n",wugrpname);
+ message(tmpstr);
+ return(0);
+ }
+ for (i=0;i<wugrp.num_positions;i++) {
+ char tmpstr[34];
+ sprintf(tmpstr,"%14.5f %6.3f %6.2f",
+ wuheader->wuinfo.position_history[i].st.jd,
+ wuheader->wuinfo.position_history[i].ra,
+ wuheader->wuinfo.position_history[i].dec
+ );
+ if (n=db_workunit_grp_update_position(wugrp.id,i,tmpstr)) {
+ fprintf( stderr, "%d\n", n );
+ sprintf(tmpstr,"Unable to add position %d to workunit_grp %s\n",i,wugrpname);
+ message(tmpstr);
+ }
+ }
+ return (wugrp.id);
+}
+
+int create_workunit_entry(wuheader_t *wuheader, int wugrpid, int subband_number) {
+ WORKUNIT wu;
+
+ memset(&wu,0,sizeof(wu));
+ strncpy(wu.name,wuheader->wuhead.name,63);
+ wu.grpnum=wugrpid;
+ wu.subb_center=wuheader->wuinfo.subband_center;
+ wu.subb_base=wuheader->wuinfo.subband_base;
+ wu.subb_sample_rate=wuheader->wuinfo.subband_sample_rate;
+ wu.subband_number=subband_number;
+ wu.data_class=wuheader->wuinfo.data_class;
+ if (db_workunit_new(&wu)) {
+ char tmpstr[256];
+ sprintf(tmpstr,"Unable to create workunit entry %s\n",wu.name);
+ message(tmpstr);
+ return(0);
+ }
+ return(wu.id);
+}
+*/
+
+/*
+ * $Log: db_fns.cpp,v $
+ * Revision 1.3.4.2 2006/12/14 22:24:37 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.3.4.1 2006/01/13 00:37:56 korpela
+ * Moved splitter to using standard BOINC logging mechanisms. All stderr now
+ * goes to "error.log"
+ *
+ * Added command line parameters "-iterations=" (number of workunit groups to
+ * create before exiting), "-trigger_file_path=" (path to the splitter_stop trigger
+ * file. Default is /disks/setifiler1/wutape/tapedir/splitter_stop).
+ *
+ * Reduced deadlines by a factor of three. We now need a 30 MFLOP machine to meet
+ * the deadline.
+ *
+ * Revision 1.3 2003/09/11 18:53:37 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.2 2003/08/05 17:23:40 korpela
+ * More work on database stuff.
+ * Further tweaks.
+ *
+ * Revision 1.1 2003/07/29 20:35:35 korpela
+ *
+ * renames .C files to .cpp
+ *
+ * Revision 1.2 2003/06/03 01:01:16 korpela
+ *
+ * First working splitter under CVS.
+ *
+ * Revision 1.1 2003/06/03 00:16:10 korpela
+ *
+ * Initial splitter under CVS control.
+ *
+ * Revision 3.2 2003/05/19 17:40:59 eheien
+ * *** empty log message ***
+ *
+ * Revision 3.1 2001/11/07 00:51:47 korpela
+ * Added splitter version to database.
+ * Added max_wus_ondisk option.
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 1.4 2000/12/01 01:13:29 korpela
+ * *** empty log message ***
+ *
+// Revision 1.3 1999/03/05 01:47:18 korpela
+// Added data_class field.
+//
+// Revision 1.2 1999/02/22 22:21:09 korpela
+// Fixed half-day error.
+//
+// Revision 1.1 1999/02/11 16:46:28 korpela
+// Initial revision
+//
+ *
+ */
diff --git a/gbt_splitter/db_fns.h b/gbt_splitter/db_fns.h
new file mode 100644
index 0000000..3ccf871
--- /dev/null
+++ b/gbt_splitter/db_fns.h
@@ -0,0 +1,48 @@
+/*
+ * $Id: db_fns.h,v 1.3 2003/08/05 17:23:40 korpela Exp $
+ *
+ */
+
+
+#ifndef DB_FNS_H
+#define DB_FNS_H
+
+#include "schema_master.h"
+
+int get_last_block(tapeheader_t *tapeheader) ;
+
+//int update_tape_entry( tapeheader_t *tapeheader) ;
+
+/* returns workunit group id number on success, 0 on failure */
+//int create_wugrp_entry(char *wugrpname,wuheader_t *wuheader, int tapenum, tapeheader_t *tapeheader) ;
+
+//int create_workunit_entry(wuheader_t *wuheader, int wugrpid, int subband_number) ;
+
+#endif
+
+/*
+ *
+ * $Log: db_fns.h,v $
+ * Revision 1.3 2003/08/05 17:23:40 korpela
+ * More work on database stuff.
+ * Further tweaks.
+ *
+ * Revision 1.2 2003/06/03 01:01:16 korpela
+ *
+ * First working splitter under CVS.
+ *
+ * Revision 1.1 2003/06/03 00:16:10 korpela
+ *
+ * Initial splitter under CVS control.
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 1.2 1999/02/22 22:21:09 korpela
+ * added -nodb option
+ *
+ * Revision 1.1 1999/02/11 16:46:28 korpela
+ * Initial revision
+ *
+ *
+ */
diff --git a/gbt_splitter/dotransform.cpp b/gbt_splitter/dotransform.cpp
new file mode 100644
index 0000000..1663a50
--- /dev/null
+++ b/gbt_splitter/dotransform.cpp
@@ -0,0 +1,218 @@
+/*
+ *
+ * dotransform.c
+ *
+ * Functions for division by frequency into work units.
+ *
+ * $Id: dotransform.cpp,v 1.2.4.1 2006/12/14 22:24:38 korpela Exp $
+ *
+ */
+
+#include "sah_config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <unistd.h>
+#include <limits.h>
+#include <assert.h>
+#include <math.h>
+
+#include "splitparms.h"
+#include "splittypes.h"
+#include "splitter.h"
+#include "fftw.h"
+#include "wufiles.h"
+
+/* buffer for fft input/output */
+float databuf[FFT_LEN*2];
+
+/* buffer for ftt output before data writes, needs to be multiple
+ * of three bytes long for encode to work.
+ */
+#define SAMPLES_PER_OBUF (FFT_LEN*2*3/CHAR_BIT)
+unsigned char output_buf[NSTRIPS][SAMPLES_PER_OBUF];
+
+
+int obuf_pos; /* Tracks current postition in the output buffers */
+
+
+void output_samples(float *data, int i, int buf_pos) {
+ int j,k;
+ unsigned short s;
+ float *p=data;
+
+ for (j=0;j<2;j++) {
+ s=0;
+ for (k=0; k<8; k++) {
+ s >>= 2;
+ if (*p>0) s |= 0x8000;
+ if (*(p+1)>0) s |= 0x4000;
+ p+=2;
+ }
+ output_buf[i][buf_pos++]=*(char *)(&s);
+ output_buf[i][buf_pos++]=*(((char *)(&s))+1);
+ }
+}
+
+void splitter_bits_to_float(unsigned short *raw, float *data, int nsamples) {
+ unsigned int i, j;
+ unsigned short s;
+ static int first_time=1;
+ static float lut[65536][16];
+
+ assert(!(nsamples % 8));
+
+ if (first_time) {
+ for (i=0;i<65536;i++) {
+ s=(unsigned short)i;
+ for (j=0;j<8;j++) {
+ lut[i][j*2]=(float)2*(s & 1)-1;
+ s >>= 1;
+ lut[i][j*2+1]=(float)2*(s & 1)-1;
+ s >>= 1;
+ }
+ }
+ first_time--;
+ }
+
+ for (i=0;i<(nsamples/8);i++) {
+ memcpy(data+16*i,lut[raw[i]],16*sizeof(float));
+ }
+}
+
+void process_seg(float* data) {
+ int i;
+ float* p = data;
+ static float dbuff[FFT_LEN*2];
+ static fftw_plan planfwd,planinverse;
+
+ if (!planfwd) {
+ planfwd=fftw_create_plan(FFT_LEN, FFTW_BACKWARD,
+ FFTW_MEASURE | FFTW_IN_PLACE | FFTW_USE_WISDOM );
+ planinverse=fftw_create_plan(IFFT_LEN, FFTW_FORWARD,
+ FFTW_MEASURE | FFTW_IN_PLACE | FFTW_USE_WISDOM );
+ }
+
+ fftw_one(planfwd, (fftw_complex *)data, (fftw_complex *)NULL);
+ data[0]=0;
+ data[1]=0;
+ fftw(planinverse, NSTRIPS, (fftw_complex *)data, 1, IFFT_LEN,
+ (fftw_complex *)NULL, 1, IFFT_LEN);
+ for (i=0; i<NSTRIPS; i++) {
+ output_samples(p, i, obuf_pos);
+ p += IFFT_LEN*2;
+ }
+ obuf_pos+=IFFT_LEN*2/CHAR_BIT;
+}
+
+#define TBUF_OFFSET(frame,byte) (tapebuffer+(frame)*TAPE_FRAME_SIZE+(byte)+TAPE_HEADER_SIZE)
+
+void do_transform(buffer_pos_t *start_of_wu, buffer_pos_t *end_of_wu) {
+ buffer_pos_t end_trans,start_trans=*start_of_wu;
+ int i,nsamp;
+ do {
+ obuf_pos=0; /* reset to the beginning of the output buffer */
+ for (i=0;i<768;i++) {
+ end_trans.frame=start_trans.frame;
+ end_trans.byte=start_trans.byte+(FFT_LEN*2/CHAR_BIT);
+ if (end_trans.byte > TAPE_DATA_SIZE) {
+ /* End of frame crossed need to trasfer correctly */
+ end_trans.frame++;
+ end_trans.byte-=TAPE_DATA_SIZE;
+ nsamp=(TAPE_DATA_SIZE-start_trans.byte)*(CHAR_BIT/2);
+ assert((nsamp+end_trans.byte*(CHAR_BIT/2)) == FFT_LEN);
+ splitter_bits_to_float((unsigned short *)TBUF_OFFSET(start_trans.frame,start_trans.byte),
+ databuf, nsamp);
+ splitter_bits_to_float((unsigned short *)TBUF_OFFSET(end_trans.frame,0),databuf+nsamp*2,
+ end_trans.byte*(CHAR_BIT/2));
+ } else {
+ splitter_bits_to_float((unsigned short *)TBUF_OFFSET(start_trans.frame,start_trans.byte),
+ databuf,FFT_LEN);
+ }
+ process_seg(databuf);
+ /* Go on to next transform */
+ start_trans=end_trans;
+ }
+ /* Check if we're at the end of the wu file. If so we print less bytes */
+ if ((end_trans.frame>=end_of_wu->frame) &&
+ (end_trans.byte>=end_of_wu->byte)) {
+ write_wufile_blocks(NBYTES % SAMPLES_PER_OBUF);
+ } else {
+ write_wufile_blocks(SAMPLES_PER_OBUF);
+ }
+ } while (!((end_trans.frame>=end_of_wu->frame) && (end_trans.byte>=end_of_wu->byte)));
+
+ /* Move the data in the buffer so we don't have to reread portions of the
+ * tape.
+ */
+ {
+ unsigned char *record_offset;
+ int copysize;
+ end_of_wu->frame-=WU_OVERLAP_FRAMES;
+ records_in_buffer=TAPE_RECORDS_IN_BUFFER-
+ (end_of_wu->frame/TAPE_FRAMES_PER_RECORD);
+ record_offset=tapebuffer+
+ (end_of_wu->frame/TAPE_FRAMES_PER_RECORD)*TAPE_RECORD_SIZE;
+ copysize=records_in_buffer*TAPE_RECORD_SIZE;
+ bcopy(record_offset,tapebuffer,copysize);
+ }
+}
+
+/*
+ *
+ * $Log: dotransform.cpp,v $
+ * Revision 1.2.4.1 2006/12/14 22:24:38 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.2 2003/09/11 18:53:37 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.1 2003/07/29 20:35:36 korpela
+ *
+ * renames .C files to .cpp
+ *
+ * Revision 1.1 2003/06/03 00:16:10 korpela
+ *
+ * Initial splitter under CVS control.
+ *
+ * Revision 3.2 2003/05/19 17:40:59 eheien
+ * *** empty log message ***
+ *
+ * Revision 3.1 2003/04/10 22:09:00 korpela
+ * *** empty log message ***
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.7 1999/03/27 16:19:35 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.6 1999/02/22 19:02:50 korpela
+ * Revered input real & imaginary.
+ *
+ * Revision 2.5 1999/02/10 21:49:44 korpela
+ * Zeroed DC component of forward transform.
+ *
+ * Revision 2.4 1999/02/01 22:28:52 korpela
+ * FFTW version.
+ *
+ * Revision 2.3 1998/12/14 23:41:44 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.2 1998/11/04 23:08:25 korpela
+ * Byte and bit order change.
+ *
+ * Revision 2.1 1998/11/02 16:41:21 korpela
+ * Minor Change.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.2 1998/10/30 20:26:03 korpela
+ * Bug Fixes. Now mostly working.
+ *
+ * Revision 1.1 1998/10/27 00:51:08 korpela
+ * Initial revision
+ *
+ *
+ */
diff --git a/gbt_splitter/dotransform.h b/gbt_splitter/dotransform.h
new file mode 100644
index 0000000..5b3136d
--- /dev/null
+++ b/gbt_splitter/dotransform.h
@@ -0,0 +1,56 @@
+/*
+ *
+ * dotransform.h
+ *
+ * Functions for division by frequency into work units.
+ *
+ * $Id: dotransform.h,v 1.1 2003/06/03 00:16:11 korpela Exp $
+ *
+ */
+
+/* buffer for fft input/output */
+extern float databuf[FFT_LEN*2];
+
+/* buffer for ftt output before data writes, needs to be multiple
+ * of three bytes long for encode to work.
+ */
+#define SAMPLES_PER_OBUF (FFT_LEN*2*3/CHAR_BIT)
+#define TBUF_OFFSET(frame,byte) (tapebuffer+(frame)*TAPE_FRAME_SIZE+(byte))
+extern unsigned char output_buf[NSTRIPS][SAMPLES_PER_OBUF];
+
+
+extern int obuf_pos; /* Tracks current postition in the output buffers */
+
+
+void output_samples(float *data, int i, int buf_pos);
+void splitter_bits_to_float(unsigned short *raw, float *data, int nsamples) ;
+void process_seg(float* data) ;
+void do_transform(buffer_pos_t *start_of_wu, buffer_pos_t *end_of_wu) ;
+
+/*
+ *
+ * $Log: dotransform.h,v $
+ * Revision 1.1 2003/06/03 00:16:11 korpela
+ *
+ * Initial splitter under CVS control.
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.3 1999/02/01 22:28:52 korpela
+ * FFTW version.
+ *
+ * Revision 2.2 1998/11/04 23:08:25 korpela
+ * Byte and bit order change.
+ *
+ * Revision 2.1 1998/11/02 16:41:21 korpela
+ * Minor Change.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.1 1998/10/27 01:05:22 korpela
+ * Initial revision
+ *
+ *
+ */
diff --git a/gbt_splitter/encode.cpp b/gbt_splitter/encode.cpp
new file mode 100644
index 0000000..579697b
--- /dev/null
+++ b/gbt_splitter/encode.cpp
@@ -0,0 +1,93 @@
+/*
+ *
+ * binary to ascii encoding for work unit files
+ *
+ * $Id: encode.cpp,v 1.2.4.2 2007/06/01 03:29:25 korpela Exp $
+ *
+ */
+
+#include "sah_config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <assert.h>
+
+/* Write a range of bytes encoded into printable chars.
+ * Encodes 3 bytes into 4 chars.
+ * May read up to two bytes past end
+ */
+
+void splitter_encode(unsigned char *bin, int nbytes, FILE *f) {
+ int count=0, offset=0, nleft, count1=0;
+ unsigned char c[4*1024+64];
+ unsigned char nl=10;
+ assert(nbytes<=(3*1024));
+ for (nleft = nbytes; nleft > 0; nleft -= 3) {
+ c[0+count1] = bin[offset]&0x3f; // 6
+ c[1+count1] = (bin[offset]>>6) | (bin[offset+1]<<2)&0x3f; // 2+4
+ c[2+count1] = ((bin[offset+1]>>4)&0xf) | (bin[offset+2]<<4)&0x3f;// 4+2
+ c[3+count1] = bin[offset+2]>>2; // 6
+ c[0+count1] += 0x20;
+ c[1+count1] += 0x20;
+ c[2+count1] += 0x20;
+ c[3+count1] += 0x20;
+ offset += 3;
+ count += 4;
+ count1 +=4;
+ if (count == 64) {
+ count = 0;
+ c[count1++]=nl;
+ }
+ }
+ write(fileno(f),c,count1);
+}
+
+/*
+ *
+ * $Log: encode.cpp,v $
+ * Revision 1.2.4.2 2007/06/01 03:29:25 korpela
+ * Fixes for linux build of Joe's updated code.
+ *
+ * Probably not working yet.
+ *
+ * Revision 1.2.4.1 2006/12/14 22:24:38 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.2 2003/09/11 18:53:37 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.1 2003/07/29 20:35:37 korpela
+ *
+ * renames .C files to .cpp
+ *
+ * Revision 1.1 2003/06/03 00:16:11 korpela
+ *
+ * Initial splitter under CVS control.
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.3 1998/11/04 23:08:25 korpela
+ * Byte and bit order change.
+ *
+ * Revision 2.2 1998/11/02 21:20:58 korpela
+ * changed function name from encode() to splitter_encode() to avoid
+ * conflict with encode routine in ../client/util.C. Will investigate
+ * if merging of two functions is possible.
+ *
+ * Revision 2.1 1998/11/02 16:41:21 korpela
+ * Minor Change.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.2 1998/10/30 20:26:03 korpela
+ * Bug Fixes. Now mostly working.
+ *
+ * Revision 1.1 1998/10/27 00:52:56 korpela
+ * Initial revision
+ *
+ *
+ */
+
+
diff --git a/gbt_splitter/encode.h b/gbt_splitter/encode.h
new file mode 100644
index 0000000..d17775f
--- /dev/null
+++ b/gbt_splitter/encode.h
@@ -0,0 +1,39 @@
+/*
+ *
+ * binary to ascii encoding for work unit files
+ *
+ * $Id: encode.h,v 1.1 2003/06/03 00:16:11 korpela Exp $
+ *
+ */
+
+/* Write a range of bytes encoded into printable chars.
+ * Encodes 3 bytes into 4 chars.
+ * May read up to two bytes past end
+ */
+
+void splitter_encode(unsigned char *bin, int nbytes, FILE *f);
+
+/*
+ * $Log: encode.h,v $
+ * Revision 1.1 2003/06/03 00:16:11 korpela
+ *
+ * Initial splitter under CVS control.
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.2 1998/11/02 21:20:58 korpela
+ * Changed routine name from encode() to splitter_encode(). See encode.C
+ * for details.
+ *
+ * Revision 2.1 1998/11/02 16:41:21 korpela
+ * Minor Change.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.1 1998/10/27 01:06:46 korpela
+ * Initial revision
+ *
+ *
+ */
diff --git a/gbt_splitter/fftw.h b/gbt_splitter/fftw.h
new file mode 100644
index 0000000..41698f7
--- /dev/null
+++ b/gbt_splitter/fftw.h
@@ -0,0 +1,413 @@
+/* fftw/fftw.h. Generated automatically by configure. */
+/* -*- C -*- */
+/*
+ * Copyright (c) 1997,1998 Massachusetts Institute of Technology
+ *
+ * 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 Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+/* fftw.h -- system-wide definitions */
+/* $Id: fftw.h,v 1.1 2003/06/03 00:16:12 korpela Exp $ */
+
+#ifndef FFTW_H
+#define FFTW_H
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Define for using single precision */
+/*
+ * If you can, use configure --enable-float instead of changing this
+ * flag directly
+ */
+#define FFTW_ENABLE_FLOAT 1
+
+/* our real numbers */
+#ifdef FFTW_ENABLE_FLOAT
+typedef float fftw_real;
+#else
+typedef double fftw_real;
+#endif
+
+/*********************************************
+ * Complex numbers and operations
+ *********************************************/
+typedef struct {
+ fftw_real re, im;
+} fftw_complex;
+
+#define c_re(c) ((c).re)
+#define c_im(c) ((c).im)
+
+typedef enum {
+ FFTW_FORWARD = -1, FFTW_BACKWARD = 1
+} fftw_direction;
+
+/* backward compatibility with FFTW-1.3 */
+typedef fftw_complex FFTW_COMPLEX;
+typedef fftw_real FFTW_REAL;
+
+#ifndef FFTW_1_0_COMPATIBILITY
+#define FFTW_1_0_COMPATIBILITY 0
+#endif
+
+#if FFTW_1_0_COMPATIBILITY
+/* backward compatibility with FFTW-1.0 */
+#define REAL fftw_real
+#define COMPLEX fftw_complex
+#endif
+
+/*********************************************
+ * Success or failure status
+ *********************************************/
+
+typedef enum {
+ FFTW_SUCCESS = 0, FFTW_FAILURE = -1
+} fftw_status;
+
+/*********************************************
+ * Codelets
+ *********************************************/
+typedef void (fftw_notw_codelet)
+ (const fftw_complex *, fftw_complex *, int, int);
+typedef void (fftw_twiddle_codelet)
+ (fftw_complex *, const fftw_complex *, int,
+ int, int);
+typedef void (fftw_generic_codelet)
+ (fftw_complex *, const fftw_complex *, int,
+ int, int, int);
+typedef void (fftw_real2hc_codelet)
+ (const fftw_real *, fftw_real *, fftw_real *,
+ int, int, int);
+typedef void (fftw_hc2real_codelet)
+ (const fftw_real *, const fftw_real *,
+ fftw_real *, int, int, int);
+typedef void (fftw_hc2hc_codelet)
+ (fftw_real *, const fftw_complex *,
+ int, int, int);
+typedef void (fftw_rgeneric_codelet)
+ (fftw_real *, const fftw_complex *, int,
+ int, int, int);
+
+/*********************************************
+ * Configurations
+ *********************************************/
+/*
+ * A configuration is a database of all known codelets
+ */
+
+enum fftw_node_type {
+ FFTW_NOTW, FFTW_TWIDDLE, FFTW_GENERIC, FFTW_RADER,
+ FFTW_REAL2HC, FFTW_HC2REAL, FFTW_HC2HC, FFTW_RGENERIC
+};
+
+/* description of a codelet */
+typedef struct {
+ const char *name; /* name of the codelet */
+ void (*codelet) (); /* pointer to the codelet itself */
+ int size; /* size of the codelet */
+ fftw_direction dir; /* direction */
+ enum fftw_node_type type; /* TWIDDLE or NO_TWIDDLE */
+ int signature; /* unique id */
+ int ntwiddle; /* number of twiddle factors */
+ const int *twiddle_order; /*
+ * array that determines the order
+ * in which the codelet expects
+ * the twiddle factors
+ */
+} fftw_codelet_desc;
+
+/* On Win32, you need to do funny things to access global variables
+ in shared libraries. Thanks to Andrew Sterian for this hack. */
+#if defined(__WIN32__) || defined(WIN32) || defined(_WINDOWS)
+# if defined(BUILD_FFTW_DLL)
+# define DL_IMPORT(type) __declspec(dllexport) type
+# elif defined(USE_FFTW_DLL)
+# define DL_IMPORT(type) __declspec(dllimport) type
+# else
+# define DL_IMPORT(type) type
+# endif
+#else
+# define DL_IMPORT(type) type
+#endif
+
+extern DL_IMPORT(const char *) fftw_version;
+
+/*****************************
+ * Plans
+ *****************************/
+/*
+ * A plan is a sequence of reductions to compute a FFT of
+ * a given size. At each step, the FFT algorithm can:
+ *
+ * 1) apply a notw codelet, or
+ * 2) recurse and apply a twiddle codelet, or
+ * 3) apply the generic codelet.
+ */
+
+/* structure that contains twiddle factors */
+typedef struct fftw_twiddle_struct {
+ int n;
+ const fftw_codelet_desc *cdesc;
+ fftw_complex *twarray;
+ struct fftw_twiddle_struct *next;
+ int refcnt;
+} fftw_twiddle;
+
+typedef struct fftw_rader_data_struct {
+ struct fftw_plan_struct *plan;
+ fftw_complex *omega;
+ int g, ginv;
+ int p, flags, refcount;
+ struct fftw_rader_data_struct *next;
+ fftw_codelet_desc *cdesc;
+} fftw_rader_data;
+
+typedef void (fftw_rader_codelet)
+ (fftw_complex *, const fftw_complex *, int,
+ int, int, fftw_rader_data *);
+
+/* structure that holds all the data needed for a given step */
+typedef struct fftw_plan_node_struct {
+ enum fftw_node_type type;
+
+ union {
+ /* nodes of type FFTW_NOTW */
+ struct {
+ int size;
+ fftw_notw_codelet *codelet;
+ const fftw_codelet_desc *codelet_desc;
+ } notw;
+
+ /* nodes of type FFTW_TWIDDLE */
+ struct {
+ int size;
+ fftw_twiddle_codelet *codelet;
+ fftw_twiddle *tw;
+ struct fftw_plan_node_struct *recurse;
+ const fftw_codelet_desc *codelet_desc;
+ } twiddle;
+
+ /* nodes of type FFTW_GENERIC */
+ struct {
+ int size;
+ fftw_generic_codelet *codelet;
+ fftw_twiddle *tw;
+ struct fftw_plan_node_struct *recurse;
+ } generic;
+
+ /* nodes of type FFTW_RADER */
+ struct {
+ int size;
+ fftw_rader_codelet *codelet;
+ fftw_rader_data *rader_data;
+ fftw_twiddle *tw;
+ struct fftw_plan_node_struct *recurse;
+ } rader;
+
+ /* nodes of type FFTW_REAL2HC */
+ struct {
+ int size;
+ fftw_real2hc_codelet *codelet;
+ const fftw_codelet_desc *codelet_desc;
+ } real2hc;
+
+ /* nodes of type FFTW_HC2REAL */
+ struct {
+ int size;
+ fftw_hc2real_codelet *codelet;
+ const fftw_codelet_desc *codelet_desc;
+ } hc2real;
+
+ /* nodes of type FFTW_HC2HC */
+ struct {
+ int size;
+ fftw_direction dir;
+ fftw_hc2hc_codelet *codelet;
+ fftw_twiddle *tw;
+ struct fftw_plan_node_struct *recurse;
+ const fftw_codelet_desc *codelet_desc;
+ } hc2hc;
+
+ /* nodes of type FFTW_RGENERIC */
+ struct {
+ int size;
+ fftw_direction dir;
+ fftw_rgeneric_codelet *codelet;
+ fftw_twiddle *tw;
+ struct fftw_plan_node_struct *recurse;
+ } rgeneric;
+ } nodeu;
+
+ int refcnt;
+} fftw_plan_node;
+
+struct fftw_plan_struct {
+ int n;
+ int refcnt;
+ fftw_direction dir;
+ int flags;
+ int wisdom_signature;
+ enum fftw_node_type wisdom_type;
+ struct fftw_plan_struct *next;
+ fftw_plan_node *root;
+ double cost;
+};
+
+/* a plan is just an array of instructions */
+typedef struct fftw_plan_struct *fftw_plan;
+
+/* flags for the planner */
+#define FFTW_ESTIMATE (0)
+#define FFTW_MEASURE (1)
+
+#define FFTW_OUT_OF_PLACE (0)
+#define FFTW_IN_PLACE (8)
+#define FFTW_USE_WISDOM (16)
+
+#define FFTW_THREADSAFE (128) /* guarantee plan is read-only so that the
+ same plan can be used in parallel by
+ multiple threads */
+
+#define FFTWND_FORCE_BUFFERED (256) /* internal, undocumented flag */
+
+extern fftw_plan fftw_create_plan_specific(int n, fftw_direction dir,
+ int flags,
+ fftw_complex *in, int istride,
+ fftw_complex *out, int ostride);
+#define FFTW_HAS_PLAN_SPECIFIC
+extern fftw_plan fftw_create_plan(int n, fftw_direction dir, int flags);
+extern void fftw_print_plan(fftw_plan plan);
+extern void fftw_destroy_plan(fftw_plan plan);
+extern void fftw(fftw_plan plan, int howmany, fftw_complex *in, int istride,
+ int idist, fftw_complex *out, int ostride, int odist);
+extern void fftw_one(fftw_plan plan, fftw_complex *in, fftw_complex *out);
+extern void fftw_die(const char *s);
+extern void *fftw_malloc(size_t n);
+extern void fftw_free(void *p);
+extern void fftw_check_memory_leaks(void);
+extern void fftw_print_max_memory_usage(void);
+
+typedef void *(*fftw_malloc_type_function) (size_t n);
+typedef void (*fftw_free_type_function) (void *p);
+typedef void (*fftw_die_type_function) (const char *errString);
+extern DL_IMPORT(fftw_malloc_type_function) fftw_malloc_hook;
+extern DL_IMPORT(fftw_free_type_function) fftw_free_hook;
+extern DL_IMPORT(fftw_die_type_function) fftw_die_hook;
+
+extern size_t fftw_sizeof_fftw_real(void);
+
+/* Wisdom: */
+/*
+ * define this symbol so that users know we are using a version of FFTW
+ * with wisdom
+ */
+#define FFTW_HAS_WISDOM
+extern void fftw_forget_wisdom(void);
+extern void fftw_export_wisdom(void (*emitter) (char c, void *), void *data);
+extern fftw_status fftw_import_wisdom(int (*g) (void *), void *data);
+extern void fftw_export_wisdom_to_file(FILE *output_file);
+extern fftw_status fftw_import_wisdom_from_file(FILE *input_file);
+extern char *fftw_export_wisdom_to_string(void);
+extern fftw_status fftw_import_wisdom_from_string(const char *input_string);
+
+/*
+ * define symbol so we know this function is available (it is not in
+ * older FFTWs)
+ */
+#define FFTW_HAS_FPRINT_PLAN
+extern void fftw_fprint_plan(FILE *f, fftw_plan plan);
+
+/*****************************
+ * N-dimensional code
+ *****************************/
+typedef struct {
+ int is_in_place; /* 1 if for in-place FFTs, 0 otherwise */
+
+ int rank; /*
+ * the rank (number of dimensions) of the
+ * array to be FFTed
+ */
+ int *n; /*
+ * the dimensions of the array to the
+ * FFTed
+ */
+ fftw_direction dir;
+
+ int *n_before; /*
+ * n_before[i] = product of n[j] for j < i
+ */
+ int *n_after; /* n_after[i] = product of n[j] for j > i */
+
+ fftw_plan *plans; /* 1d fftw plans for each dimension */
+
+ int nbuffers, nwork;
+ fftw_complex *work; /*
+ * work array big enough to hold
+ * nbuffers+1 of the largest dimension
+ * (has nwork elements)
+ */
+} fftwnd_data;
+
+typedef fftwnd_data *fftwnd_plan;
+
+/* Initializing the FFTWND plan: */
+extern fftwnd_plan fftw2d_create_plan(int nx, int ny, fftw_direction dir,
+ int flags);
+extern fftwnd_plan fftw3d_create_plan(int nx, int ny, int nz,
+ fftw_direction dir, int flags);
+extern fftwnd_plan fftwnd_create_plan(int rank, const int *n,
+ fftw_direction dir,
+ int flags);
+
+extern fftwnd_plan fftw2d_create_plan_specific(int nx, int ny,
+ fftw_direction dir,
+ int flags,
+ fftw_complex *in, int istride,
+ fftw_complex *out, int ostride);
+extern fftwnd_plan fftw3d_create_plan_specific(int nx, int ny, int nz,
+ fftw_direction dir, int flags,
+ fftw_complex *in, int istride,
+ fftw_complex *out, int ostride);
+extern fftwnd_plan fftwnd_create_plan_specific(int rank, const int *n,
+ fftw_direction dir,
+ int flags,
+ fftw_complex *in, int istride,
+ fftw_complex *out, int ostride);
+
+/* Freeing the FFTWND plan: */
+extern void fftwnd_destroy_plan(fftwnd_plan plan);
+
+/* Printing the plan: */
+extern void fftwnd_fprint_plan(FILE *f, fftwnd_plan p);
+extern void fftwnd_print_plan(fftwnd_plan p);
+#define FFTWND_HAS_PRINT_PLAN
+
+/* Computing the N-Dimensional FFT */
+extern void fftwnd(fftwnd_plan plan, int howmany,
+ fftw_complex *in, int istride, int idist,
+ fftw_complex *out, int ostride, int odist);
+extern void fftwnd_one(fftwnd_plan p, fftw_complex *in, fftw_complex *out);
+
+#ifdef __cplusplus
+} /* extern "C" */
+
+#endif /* __cplusplus */
+#endif /* FFTW_H */
diff --git a/gbt_splitter/four1.cpp b/gbt_splitter/four1.cpp
new file mode 100644
index 0000000..f775a98
--- /dev/null
+++ b/gbt_splitter/four1.cpp
@@ -0,0 +1,88 @@
+/*
+ *
+ * Fourier transform routine from numerical recipes.
+ *
+ * $Id: four1.cpp,v 1.2.4.1 2006/12/14 22:24:38 korpela Exp $
+ *
+ */
+
+#include "sah_config.h"
+#include <math.h>
+#define SWAP(a,b) tempr=(a);(a)=(b);(b)=tempr
+
+void four1(float data[], unsigned long nn, int isign) {
+ unsigned long n,mmax,m,j,istep,i;
+ double wtemp,wr,wpr,wpi,wi,theta;
+ float tempr,tempi;
+
+ n=nn << 1;
+ j=1;
+ for (i=1;i<n;i+=2) {
+ if (j > i) {
+ SWAP(data[j],data[i]);
+ SWAP(data[j+1],data[i+1]);
+ }
+ m=n >> 1;
+ while (m >= 2 && j > m) {
+ j -= m;
+ m >>= 1;
+ }
+ j += m;
+ }
+ mmax=2;
+ while (n > mmax) {
+ istep=mmax << 1;
+ theta=isign*(6.28318530717959/mmax);
+ wtemp=sin(0.5*theta);
+ wpr = -2.0*wtemp*wtemp;
+ wpi=sin(theta);
+ wr=1.0;
+ wi=0.0;
+ for (m=1;m<mmax;m+=2) {
+ for (i=m;i<=n;i+=istep) {
+ j=i+mmax;
+ tempr=(float)(wr*data[j]-wi*data[j+1]);
+ tempi=(float)(wr*data[j+1]+wi*data[j]);
+ data[j]=data[i]-tempr;
+ data[j+1]=data[i+1]-tempi;
+ data[i] += tempr;
+ data[i+1] += tempi;
+ }
+ wr=(wtemp=wr)*wpr-wi*wpi+wr;
+ wi=wi*wpr+wtemp*wpi+wi;
+ }
+ mmax=istep;
+ }
+}
+#undef SWAP
+
+/*
+ * $Log: four1.cpp,v $
+ * Revision 1.2.4.1 2006/12/14 22:24:38 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.2 2003/09/11 18:53:37 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.1 2003/07/29 20:35:39 korpela
+ *
+ * renames .C files to .cpp
+ *
+ * Revision 1.1 2003/06/03 00:16:13 korpela
+ *
+ * Initial splitter under CVS control.
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.1 1998/11/02 16:41:21 korpela
+ * Minor Change.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.1 1998/10/27 00:54:59 korpela
+ * Initial revision
+ *
+ *
+ */
diff --git a/gbt_splitter/four1.h b/gbt_splitter/four1.h
new file mode 100644
index 0000000..7d6e5b9
--- /dev/null
+++ b/gbt_splitter/four1.h
@@ -0,0 +1,31 @@
+/*
+ *
+ * Fourier transform routine from numerical recipes.
+ *
+ * $Id: four1.h,v 1.1 2003/06/03 00:16:13 korpela Exp $
+ *
+ */
+
+
+void four1(float data[], unsigned long nn, int isign);
+
+/*
+ * $Log: four1.h,v $
+ * Revision 1.1 2003/06/03 00:16:13 korpela
+ *
+ * Initial splitter under CVS control.
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.1 1998/11/02 16:41:21 korpela
+ * Minor Change.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.1 1998/10/27 01:08:21 korpela
+ * Initial revision
+ *
+ *
+ */
diff --git a/gbt_splitter/gencoeff.py b/gbt_splitter/gencoeff.py
new file mode 100755
index 0000000..3af6e75
--- /dev/null
+++ b/gbt_splitter/gencoeff.py
@@ -0,0 +1,143 @@
+#!/usr/bin/python2.6
+
+# vegas_gencoeff.py
+# Generate PFB filter coefficients for VEGAS HPC low-bandwidth modes. The
+# filter coefficients array contains duplicates for optimised reading
+# from the GPU.
+#
+# Created by Jayanth Chennamangalam based on code by Sean McHugh, UCSB
+
+import sys
+import getopt
+import math
+import numpy
+import matplotlib.pyplot as plotter
+
+# function definitions
+def PrintUsage(ProgName):
+ "Prints usage information."
+ print "Usage: " + ProgName + " [options]"
+ print " -h --help Display this usage information"
+ print " -n --nfft <value> Number of points in FFT"
+ print " -t --taps <value> Number of taps in PFB"
+ print " -b --sub-bands <value> Number of sub-bands in data"
+ print " -w --width-factor <value> width factor for sinc(x) call"
+ print " -d --data-type <value> Data type - \"float\" or " \
+ + "\"signedchar\""
+ print " -p --no-plot Do not plot coefficients"
+ return
+
+# default values
+NFFT = 32768 # number of points in FFT
+NTaps = 8 # number of taps in PFB
+NSubBands = 1 # number of sub-bands in data
+WidthFactor = 1.05 # width factor for sinc(x) call
+DataType = "signedchar" # data type - "float" or "signedchar"
+Plot = True # plot flag
+
+# get the command line arguments
+ProgName = sys.argv[0]
+OptsShort = "hn:t:b:w:d:p"
+OptsLong = ["help", "nfft=", "taps=", "sub-bands=", "width-factor=", "data-type=", "no-plot"]
+
+# check if the minimum expected number of arguments has been passed
+# to the program
+if (1 == len(sys.argv)):
+ sys.stderr.write("ERROR: No arguments passed to the program!\n")
+ PrintUsage(ProgName)
+ sys.exit(1)
+
+# get the arguments using the getopt module
+try:
+ (Opts, Args) = getopt.getopt(sys.argv[1:], OptsShort, OptsLong)
+except getopt.GetoptError, ErrMsg:
+ # print usage information and exit
+ sys.stderr.write("ERROR: " + str(ErrMsg) + "!\n")
+ PrintUsage(ProgName)
+ sys.exit(1)
+
+# parse the arguments
+for o, a in Opts:
+ if o in ("-h", "--help"):
+ PrintUsage(ProgName)
+ sys.exit()
+ elif o in ("-n", "--nfft"):
+ NFFT = int(a)
+ elif o in ("-t", "--taps"):
+ NTaps = int(a)
+ elif o in ("-b", "--sub-bands"):
+ NSubBands = int(a)
+ elif o in ("-w", "--width-factor"):
+ WidthFactor = float(a)
+ elif o in ("-d", "--data-type"):
+ DataType = a
+ elif o in ("-p", "--no-plot"):
+ Plot = False
+ else:
+ PrintUsage(ProgName)
+ sys.exit(1)
+
+M = NTaps * NFFT
+
+# the filter-coefficient-generation section -->
+X = numpy.array([(float(i) / NFFT) - (float(NTaps) / 2) for i in range(M)])
+PFBCoeff = numpy.sinc(X * WidthFactor) * numpy.hanning(M)
+# <-- the filter-coefficient-generation section
+
+# create conversion map
+if ("signedchar" == DataType):
+ Map = numpy.zeros(256, numpy.float32)
+ for i in range(0, 128):
+ Map[i] = float(i) / 128
+ for i in range(128, 256):
+ Map[i] = - (float(256 -i) / 128)
+
+# 32-bit (float) coefficients
+PFBCoeffFloat32 = numpy.zeros(M * NSubBands, numpy.float32)
+# 8-bit (signedchar) coefficients
+if ("signedchar" == DataType):
+ PFBCoeffInt8 = numpy.zeros(M * NSubBands, numpy.int8)
+k = 0
+for i in range(len(PFBCoeff)):
+ Coeff = float(PFBCoeff[i])
+ if ("signedchar" == DataType):
+ for j in range(256):
+ #if (math.fabs(Coeff - Map[j]) <= (0.0078125 / 2)):
+ if (math.fabs(Coeff - Map[j]) <= 0.0078125):
+ for m in range(NSubBands):
+ PFBCoeffInt8[k+m] = j
+ break
+ elif ("float" == DataType):
+ for m in range(NSubBands):
+ PFBCoeffFloat32[k+m] = Coeff
+ else:
+ # print usage information and exit
+ sys.stderr.write("ERROR: Invalid data type!\n")
+ PrintUsage(ProgName)
+ sys.exit(1)
+ k = k + NSubBands
+
+# write the coefficients to disk and also plot it
+FileCoeff = open("coeff_" \
+ + DataType + "_" \
+ + str(NTaps) + "_" \
+ + str(NFFT) + "_" \
+ + str(NSubBands) + "_" \
+ + str(WidthFactor) + ".dat", \
+ "wb")
+if ("signedchar" == DataType):
+ FileCoeff.write(PFBCoeffInt8)
+ # plot the coefficients
+ if (Plot):
+ plotter.plot(PFBCoeffInt8)
+else:
+ FileCoeff.write(PFBCoeffFloat32)
+ # plot the coefficients
+ if (Plot):
+ plotter.plot(PFBCoeffFloat32)
+
+FileCoeff.close()
+
+if (Plot):
+ plotter.show()
+
diff --git a/gbt_splitter/hr_min_sec.cpp b/gbt_splitter/hr_min_sec.cpp
new file mode 100644
index 0000000..63a7eea
--- /dev/null
+++ b/gbt_splitter/hr_min_sec.cpp
@@ -0,0 +1,131 @@
+/*
+ *
+ * timecvt.c
+ *
+ * Time conversion routines.
+ *
+ * $Id: hr_min_sec.cpp,v 1.2.4.1 2006/12/14 22:24:39 korpela Exp $
+ *
+ */
+
+#include "sah_config.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+char* hr_min_sec (double x) {
+ static char buf[256];
+ int hr = (int)(x / 3600);
+ int min = (int)((x/3600-(double)hr)*60);
+ float s = (float)(x - ((double)hr)*3600 - ((double)min)*60);
+
+ // the "-.05" below is to prevent it from printing 60.0 sec
+ // when the real value is e.g. 59.91
+ //
+ sprintf(buf, "%d hr %02d min %04.1f sec", hr, min, s-.05);
+ return buf;
+}
+
+
+/*
+ * $Log: hr_min_sec.cpp,v $
+ * Revision 1.2.4.1 2006/12/14 22:24:39 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.2 2003/09/11 18:53:38 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.1 2003/07/29 20:35:40 korpela
+ *
+ * renames .C files to .cpp
+ *
+ * Revision 1.1 2003/06/03 01:01:16 korpela
+ *
+ * First working splitter under CVS.
+ *
+ * Revision 4.4 2003/03/10 02:50:03 jeffc
+ * jeffc - t_strncpy()
+ *
+ * Revision 4.3 2003/01/22 20:51:58 korpela
+ * Changed all strcpy to strncpy.
+ * Changed all gets to fgets.
+ *
+ * Revision 4.2 2001/12/27 21:35:57 davea
+ * *** empty log message ***
+ *
+ * Revision 4.1 2001/09/10 00:25:17 davea
+ * *** empty log message ***
+ *
+ * Revision 4.0 2000/10/05 18:12:12 korpela
+ * Synchronized versions to 4.0 following release of 3.0 client
+ *
+ * Revision 3.8 2000/09/14 01:01:31 korpela
+ * *** empty log message ***
+ *
+ * Revision 3.7 2000/04/24 08:39:06 charlief
+ * eliminate compiler warning in hr_min_sec() function.
+ *
+ * Revision 3.6 2000/01/19 08:32:32 davea
+ * *** empty log message ***
+ *
+ * Revision 3.5 1999/10/19 08:07:24 davea
+ * *** empty log message ***
+ *
+ * Revision 3.4 1999/06/26 06:56:44 hiramc
+ * Hiram 99/06/25 23:59 moved the include <string.h> out of the
+ * ifdef _WIN32 to define strcpy() for all compiles
+ *
+ * Revision 3.3 1999/06/22 09:40:36 charlief
+ * Reverse last change:restore jd_string() as it was before.
+ * Add new function short_jd_string(), which does not print
+ * Julian Date as a floating point value.
+ *
+ * Revision 3.1 1999/06/10 00:44:11 korpela
+ * *** empty log message ***
+ *
+ * Revision 3.0 1999/05/14 19:17:35 korpela
+ * 1.0(Win/Mac) 1.1(Unix) Release Version
+ *
+ * Revision 2.11 1999/03/14 00:23:02 davea
+ * *** empty log message ***
+ *
+ * Revision 2.10 1999/03/11 21:46:58 korpela
+ * Fixed rounding error in st_to_ut().
+ *
+ * Revision 2.9 1999/03/05 09:15:07 kyleg
+ * *** empty log message ***
+ *
+ * Revision 2.8 1999/02/18 19:36:49 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.7 1999/02/13 23:54:44 kyleg
+ * *** empty log message ***
+ *
+ * Revision 2.6 1999/02/11 08:36:54 davea
+ * *** empty log message ***
+ *
+ * Revision 2.5 1998/11/17 21:47:02 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.4 1998/11/05 21:25:21 davea
+ * replace floor() with (int)
+ *
+ * Revision 2.3 1998/11/05 02:00:06 kyleg
+ * *** empty log message ***
+ *
+ * Revision 2.2 1998/11/02 17:59:06 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.1 1998/11/02 17:23:29 korpela
+ * .`
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.2 1998/10/27 00:58:56 korpela
+ * Bug fixes.
+ *
+ * Revision 1.1 1998/10/19 18:57:56 korpela
+ * Initial revision
+ *
+ *
+ */
diff --git a/gbt_splitter/hr_min_sec.h b/gbt_splitter/hr_min_sec.h
new file mode 100644
index 0000000..062a2c3
--- /dev/null
+++ b/gbt_splitter/hr_min_sec.h
@@ -0,0 +1,106 @@
+/*
+ *
+ * timecvt.c
+ *
+ * Time conversion routines.
+ *
+ * $Id: hr_min_sec.h,v 1.1 2003/06/03 01:01:16 korpela Exp $
+ *
+ */
+
+char* hr_min_sec (double x) ;
+
+
+/*
+ * $Log: hr_min_sec.h,v $
+ * Revision 1.1 2003/06/03 01:01:16 korpela
+ *
+ * First working splitter under CVS.
+ *
+ * Revision 4.4 2003/03/10 02:50:03 jeffc
+ * jeffc - t_strncpy()
+ *
+ * Revision 4.3 2003/01/22 20:51:58 korpela
+ * Changed all strcpy to strncpy.
+ * Changed all gets to fgets.
+ *
+ * Revision 4.2 2001/12/27 21:35:57 davea
+ * *** empty log message ***
+ *
+ * Revision 4.1 2001/09/10 00:25:17 davea
+ * *** empty log message ***
+ *
+ * Revision 4.0 2000/10/05 18:12:12 korpela
+ * Synchronized versions to 4.0 following release of 3.0 client
+ *
+ * Revision 3.8 2000/09/14 01:01:31 korpela
+ * *** empty log message ***
+ *
+ * Revision 3.7 2000/04/24 08:39:06 charlief
+ * eliminate compiler warning in hr_min_sec() function.
+ *
+ * Revision 3.6 2000/01/19 08:32:32 davea
+ * *** empty log message ***
+ *
+ * Revision 3.5 1999/10/19 08:07:24 davea
+ * *** empty log message ***
+ *
+ * Revision 3.4 1999/06/26 06:56:44 hiramc
+ * Hiram 99/06/25 23:59 moved the include <string.h> out of the
+ * ifdef _WIN32 to define strcpy() for all compiles
+ *
+ * Revision 3.3 1999/06/22 09:40:36 charlief
+ * Reverse last change:restore jd_string() as it was before.
+ * Add new function short_jd_string(), which does not print
+ * Julian Date as a floating point value.
+ *
+ * Revision 3.1 1999/06/10 00:44:11 korpela
+ * *** empty log message ***
+ *
+ * Revision 3.0 1999/05/14 19:17:35 korpela
+ * 1.0(Win/Mac) 1.1(Unix) Release Version
+ *
+ * Revision 2.11 1999/03/14 00:23:02 davea
+ * *** empty log message ***
+ *
+ * Revision 2.10 1999/03/11 21:46:58 korpela
+ * Fixed rounding error in st_to_ut().
+ *
+ * Revision 2.9 1999/03/05 09:15:07 kyleg
+ * *** empty log message ***
+ *
+ * Revision 2.8 1999/02/18 19:36:49 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.7 1999/02/13 23:54:44 kyleg
+ * *** empty log message ***
+ *
+ * Revision 2.6 1999/02/11 08:36:54 davea
+ * *** empty log message ***
+ *
+ * Revision 2.5 1998/11/17 21:47:02 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.4 1998/11/05 21:25:21 davea
+ * replace floor() with (int)
+ *
+ * Revision 2.3 1998/11/05 02:00:06 kyleg
+ * *** empty log message ***
+ *
+ * Revision 2.2 1998/11/02 17:59:06 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.1 1998/11/02 17:23:29 korpela
+ * .`
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.2 1998/10/27 00:58:56 korpela
+ * Bug fixes.
+ *
+ * Revision 1.1 1998/10/19 18:57:56 korpela
+ * Initial revision
+ *
+ *
+ */
diff --git a/gbt_splitter/makebufs.cpp b/gbt_splitter/makebufs.cpp
new file mode 100644
index 0000000..c7b5140
--- /dev/null
+++ b/gbt_splitter/makebufs.cpp
@@ -0,0 +1,139 @@
+/*
+ * makebuf.c
+ *
+ * Creates temporary files and buffers for use in processing....
+ *
+ * $Id: makebufs.cpp,v 1.3.2.2 2006/12/14 22:24:39 korpela Exp $
+ *
+ */
+
+#include "sah_config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <errno.h>
+
+#include "splitparms.h"
+#include "splittypes.h"
+#include "splitter.h"
+#include "message.h"
+
+int tapebuffd;
+char tapebufname[30];
+
+void delbuffer(void) {
+ munmap((char *)tapebuffer,TAPE_BUFFER_SIZE);
+ close(tapebuffd);
+ unlink(tapebufname);
+}
+
+void delbuffer_sig(int i) {
+ munmap((char *)tapebuffer,TAPE_BUFFER_SIZE);
+ close(tapebuffd);
+ unlink(tapebufname);
+ exit(1);
+}
+
+
+
+void makebuffers(unsigned char **tapebuffer) {
+ char buf[1024];
+/*
+ * Allocate temp files for tape and wu buffers. Memory mapping these
+ * files will prevent us from running out of virtual memory
+ */
+/* sprintf(tapebufname,"tape%d",getpid());
+
+ if ((tapebuffd=open(tapebufname,O_RDWR|O_CREAT,0777))==-1) {
+ fprintf(stderr,"Unable to open temp file!\n");
+ fprintf(errorlog,"Unable to open temp file!\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (ftruncate(tapebuffd,TAPE_BUFFER_SIZE) == -1) {
+ fprintf(stderr,"ftruncate failure\n");
+ fprintf(stderr," errno=%d\n",errno);
+ fprintf(errorlog,"ftruncate failure\n");
+ fprintf(errorlog," errno=%d\n",errno);
+ exit(EXIT_FAILURE);
+ }
+
+ if (((*tapebuffer=
+ mmap(0,TAPE_BUFFER_SIZE,PROT_READ|PROT_WRITE,MAP_SHARED,tapebuffd,0))==(char *)-1))
+ {
+ fprintf(stderr,"mmap failure\n");
+ fprintf(errorlog,"mmap failure\n");
+ exit(EXIT_FAILURE);
+ }
+
+ atexit(delbuffer);
+ signal(SIGINT,delbuffer_sig);
+*/
+ if (!(*tapebuffer=(unsigned char *)malloc(TAPE_BUFFER_SIZE))) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"unable to allocate memory for tape buffer\n");
+ exit(0);
+ }
+}
+
+/*
+ * $Log: makebufs.cpp,v $
+ * Revision 1.3.2.2 2006/12/14 22:24:39 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.3.2.1 2006/01/13 00:37:57 korpela
+ * Moved splitter to using standard BOINC logging mechanisms. All stderr now
+ * goes to "error.log"
+ *
+ * Added command line parameters "-iterations=" (number of workunit groups to
+ * create before exiting), "-trigger_file_path=" (path to the splitter_stop trigger
+ * file. Default is /disks/setifiler1/wutape/tapedir/splitter_stop).
+ *
+ * Reduced deadlines by a factor of three. We now need a 30 MFLOP machine to meet
+ * the deadline.
+ *
+ * Revision 1.3 2004/06/16 20:57:18 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.2 2003/09/11 18:53:38 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.1 2003/07/29 20:35:42 korpela
+ *
+ * renames .C files to .cpp
+ *
+ * Revision 1.1 2003/06/03 00:16:13 korpela
+ *
+ * Initial splitter under CVS control.
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.3 1998/12/14 23:41:44 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.2 1998/11/02 21:20:58 korpela
+ * Added signal handler for removal of temporary files on SIGINT.
+ *
+ * Revision 2.1 1998/11/02 16:41:21 korpela
+ * Minor Change.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.4 1998/10/30 20:26:03 korpela
+ * Bug Fixes. Now mostly working.
+ *
+ * Revision 1.3 1998/10/27 00:55:43 korpela
+ * Bug Fixes
+ *
+ * Revision 1.2 1998/10/20 20:40:54 korpela
+ * Removed wu buffer.
+ *
+ * Revision 1.1 1998/10/19 19:01:56 korpela
+ * Initial revision
+ *
+ */
diff --git a/gbt_splitter/makebufs.h b/gbt_splitter/makebufs.h
new file mode 100644
index 0000000..3e1aa59
--- /dev/null
+++ b/gbt_splitter/makebufs.h
@@ -0,0 +1,38 @@
+/*
+ * makebufs.h
+ *
+ * Creates temporary files and buffers for use in processing....
+ *
+ * $Id: makebufs.h,v 1.1 2003/06/03 00:16:14 korpela Exp $
+ *
+ */
+
+#ifndef MAKEBUFS_H
+#define MAKEBUFS_H
+
+void makebuffers(unsigned char **tapebuffer);
+
+#endif
+
+/*
+ * $Log: makebufs.h,v $
+ * Revision 1.1 2003/06/03 00:16:14 korpela
+ *
+ * Initial splitter under CVS control.
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.1 1998/11/02 16:41:21 korpela
+ * Minor Change.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.2 1998/10/20 20:41:45 korpela
+ * Remove wu buffer.
+ *
+ * Revision 1.1 1998/10/19 19:02:36 korpela
+ * Initial revision
+ *
+ */
diff --git a/gbt_splitter/mb_angdist.cpp b/gbt_splitter/mb_angdist.cpp
new file mode 100644
index 0000000..02f5bd9
--- /dev/null
+++ b/gbt_splitter/mb_angdist.cpp
@@ -0,0 +1,88 @@
+/*
+ * angdist.c
+ *
+ * Computes angular distance between two lat/lon points
+ *
+ * $Id: mb_angdist.cpp,v 1.1.2.1 2006/12/14 22:24:39 korpela Exp $
+ *
+ */
+
+#include "sah_config.h"
+#include <cstdio>
+#include <cstdlib>
+#include <math.h>
+#include "seti_header.h"
+#include "sqlrow.h"
+#include "sqlblob.h"
+#include "sqlapi.h"
+#include "db_table.h"
+#include "schema_master.h"
+#include "xml_util.h"
+#include "db/app_config.h"
+
+
+#define DTOR (M_PI/180)
+
+double angdist(double r1, double d1, double r2, double d2) {
+ double alpha,dist,d;
+
+ r1*=DTOR;
+ r2*=DTOR;
+ d1*=DTOR;
+ d2*=DTOR;
+ alpha=r1-r2;
+ dist=sin(d2)*sin(d1)+cos(d1)*cos(d2)*cos(alpha);
+ if ((dist*dist)<1) {
+ d=sqrt(1.0-dist*dist);
+ } else {
+ dist=1.0;
+ d=0.0;
+ }
+ dist=atan2(d,dist);
+ dist=dist/DTOR;
+ return (dist);
+}
+
+double angdist(const coordinate_t &a, const coordinate_t &b) {
+ return angdist(a.ra*15,a.dec,b.ra*15,b.dec);
+}
+
+
+/*
+ * $Log: mb_angdist.cpp,v $
+ * Revision 1.1.2.1 2006/12/14 22:24:39 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.3 2003/09/11 18:53:37 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.2 2003/08/05 17:23:39 korpela
+ * More work on database stuff.
+ * Further tweaks.
+ *
+ * Revision 1.1 2003/07/29 20:35:31 korpela
+ *
+ * renames .C files to .cpp
+ *
+ * Revision 1.2 2003/06/03 01:01:15 korpela
+ *
+ * First working splitter under CVS.
+ *
+ * Revision 1.1 2003/06/03 00:16:08 korpela
+ *
+ * Initial splitter under CVS control.
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.1 1998/11/02 16:41:21 korpela
+ * Minor Change.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.1 1998/10/27 00:47:33 korpela
+ * Initial revision
+ *
+ *
+ */
diff --git a/gbt_splitter/mb_angdist.h b/gbt_splitter/mb_angdist.h
new file mode 100644
index 0000000..c96b664
--- /dev/null
+++ b/gbt_splitter/mb_angdist.h
@@ -0,0 +1,36 @@
+/*
+ * angdist.h
+ *
+ * Computes angular distance between two lat/lon points
+ *
+ * $Id: mb_angdist.h,v 1.1.2.1 2006/12/14 22:24:40 korpela Exp $
+ *
+ */
+
+double angdist(double r1, double d1, double r2, double d2) ;
+double angdist(const coordinate_t &a,const coordinate_t &b);
+
+/*
+ * $Log: mb_angdist.h,v $
+ * Revision 1.1.2.1 2006/12/14 22:24:40 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.1 2003/06/03 00:16:09 korpela
+ *
+ * Initial splitter under CVS control.
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.1 1998/11/02 16:41:21 korpela
+ * Minor Change.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.1 1998/10/27 01:03:21 korpela
+ * Initial revision
+ *
+ *
+ */
+
diff --git a/gbt_splitter/mb_dotransform.cpp b/gbt_splitter/mb_dotransform.cpp
new file mode 100644
index 0000000..753f7dc
--- /dev/null
+++ b/gbt_splitter/mb_dotransform.cpp
@@ -0,0 +1,511 @@
+/*
+ *
+ * dotransform.c
+ *
+ * Functions for division by frequency into work units.
+ *
+ * $Id: mb_dotransform.cpp,v 1.1.2.3 2007/06/06 15:58:29 korpela Exp $
+ *
+ */
+
+#include "sah_config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <unistd.h>
+#include <limits.h>
+#include <assert.h>
+#include <math.h>
+#include <gsl/gsl_sf_trig.h>
+
+#include "setilib.h"
+#include "splitparms.h"
+#include "splittypes.h"
+#include "mb_splitter.h"
+#include "fftw3.h"
+#include "mb_wufiles.h"
+
+#include <sys/types.h> /* for open() */
+#include <sys/stat.h> /* for open() */
+#include <fcntl.h> /* for open() */
+#include "mb_dotransform.h" /* for new function declarations and macro
+ definitions */
+
+// PFB parameters
+int g_iNTaps;
+float g_fWidthFactor;
+
+/* the PFB data structure */
+typedef struct
+{
+ complex<float>* pcfData; // stores the data for one polyphase filtering; PFB_FFT_LEN complex floats
+ fftwf_complex* pfcData; // points to the above data
+} PFB_DATA;
+PFB_DATA* g_astPFBData; // points to g_iNTaps PFB_DATA's
+
+
+fftwf_plan g_stPlan = {0}; // FFT plan
+fftwf_complex* g_pfcFFTArray = NULL; // FFT input/output; PFB_FFT_LEN complex floats
+
+static complex<float>* g_pcfPackedDataOut = NULL; // packed FFT output, for the benefit of output_samples();
+ // PFB_OUTPUT_STACK_SIZE * PFB_FFT_LEN * 2 floats
+
+float* g_pfPFBCoeff = NULL; // filter coefficients; g_iNTaps * PFB_FFT_LEN floats
+int g_iIsFirstRun = TRUE;
+
+void gen_coeff(float * coeff, int num_coeff) {
+
+ int i;
+ float hanning_window[num_coeff];
+ float work_array[num_coeff];
+
+ seti_hanning_window(hanning_window, num_coeff);
+
+ for(i=0; i<num_coeff; i++) {
+ coeff[i] = (float(i) / PFB_FFT_LEN) - (float(g_iNTaps) / 2.0);
+ }
+
+ for(i=0; i<num_coeff; i++) {
+ coeff[i] = gsl_sf_sinc(coeff[i] * g_fWidthFactor) * hanning_window[i];
+ }
+}
+
+void output_samples(float *data, int i) {
+// outputs 8 complex samples per call (8 cplx floats -> 8 cplx chars, or 16 floats -> 16 chars)
+ int j,k;
+ unsigned short s=0;
+ float *p=data;
+
+ for (k=0; k<8; k++) {
+ s >>= 2;
+ if (*p>0) s |= 0x8000;
+ if (*(p+1)>0) s |= 0x4000;
+ p+=2;
+ }
+ // bin_data is defined in mb_wufiles.cpp as a vector<unsigned char>
+ bin_data[i].push_back((s>>8) & 0xff);
+ bin_data[i].push_back(s & 0xff);
+}
+
+void splitter_bits_to_float(unsigned short *raw, float *data, int nsamples) {
+ unsigned int i, j;
+ unsigned short s;
+ static int first_time=1;
+ static float lut[65536][16];
+
+ assert(!(nsamples % 8));
+
+ if (first_time) {
+ for (i=0;i<65536;i++) {
+ s=(unsigned short)i;
+ for (j=0;j<8;j++) {
+ lut[i][j*2]=(float)2*(s & 1)-1;
+ s >>= 1;
+ lut[i][j*2+1]=(float)2*(s & 1)-1;
+ s >>= 1;
+ }
+ }
+ first_time--;
+ }
+
+ for (i=0;i<(nsamples/8);i++) {
+ memcpy(data+16*i,lut[raw[i]],16*sizeof(float));
+ }
+}
+
+
+float randu() {
+// Uniform random numbers between 0 and 1
+ static bool first=true;
+ if (first) {
+ srand(time(0));
+ first=false;
+ }
+ return static_cast<float>(rand())/RAND_MAX;
+}
+
+float randn() {
+// normally distributed random numbers
+ static float last=0;
+ float a,b,h=0;
+ if (last==0) {
+ while (h==0 || h>=1) {
+ a=2*randu()-1;
+ b=2*randu()-1;
+ h=a*a+b*b;
+ }
+ h=sqrt(-2*log(h)/h);
+ last=a*h;
+ return b*h;
+ } else {
+ a=last;
+ last=0;
+ return a;
+ }
+}
+
+int set_iDataIdx(int iDataIdx, int &iTapeBufferIdx, int iPrevTapeBufferIdx) {
+ /* NOTE: for the last tape buffer, the last polyphase filtering we perform is for the
+ last consecutive g_iNTaps blocks */
+ /* rewind the data index by (g_iNTaps - 1) blocks */
+ iDataIdx -= ((g_iNTaps - 1) * PFB_FFT_LEN);
+ if (iTapeBufferIdx != iPrevTapeBufferIdx) {
+ if (iDataIdx != 0) { /* data index can only be negative or zero at this point */
+ /* if rewinding takes us back to the previous tapebuffer,
+ change the tapebuffer index and data index accordingly */
+ iTapeBufferIdx = iPrevTapeBufferIdx;
+ /* NOTE: data index is negative, hence the addition */
+ iDataIdx = tapebuffer[iTapeBufferIdx].data.size() + iDataIdx;
+ }
+ }
+
+ return(iDataIdx);
+}
+
+inline int inc_iDataIdx(int &iTapeBufferIdx, int &iDataIdx) {
+
+ int iFlagBreak = FALSE;
+
+ iDataIdx = (iDataIdx + 1) % tapebuffer[iTapeBufferIdx].data.size();
+ if (0 == iDataIdx) {
+ /* move to the next tapebuffer */
+ ++iTapeBufferIdx;
+ if (tapebuffer.size() == iTapeBufferIdx) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, "End of tape buffer.\n");
+ iFlagBreak = TRUE;
+ /* NOTE: do not return here, as we still need to process the current block */
+ }
+ }
+
+ return(iFlagBreak);
+}
+
+inline int load_pfb_data(int &iTapeBufferIdx, int &iDataIdx, int &i, int &k) {
+
+ g_astPFBData[i].pcfData[k] = complex<float>(
+ // The PFB has the opposite notion of i and q than that of the data recorder.
+ // To account for this, we flip real and imag here.
+ static_cast<float>(tapebuffer[iTapeBufferIdx].data[iDataIdx].imag()),
+ static_cast<float>(tapebuffer[iTapeBufferIdx].data[iDataIdx].real())
+ );
+
+ return(inc_iDataIdx(iTapeBufferIdx, iDataIdx));
+}
+
+void reorder_data(fftwf_complex *pfcPackedDataOut, int iPFBTapIdx) {
+
+ int i;
+
+ /* re-order the output data in such a way that at the end of this loop,
+ output is in the same form as before the PFB implementation,
+ so output_samples() can be used the same way as before.
+ (in the above output, frequency is the fastest-changing index,
+ but output_samples() requires data with time as the fastest-changing
+ index.) */
+ for (i = 0; i < PFB_FFT_LEN; ++i) {
+ // The PFB has the opposite notion of i and q than that of the workunit.
+ // To account for this, we flip real and imag here.
+ /* imaginary part of g_pfcFFTArray[][] */
+ pfcPackedDataOut[(i*PFB_OUTPUT_STACK_SIZE)+iPFBTapIdx][0] = g_pfcFFTArray[i][1];
+ /* real part of g_pfcFFTArray[][] */
+ pfcPackedDataOut[(i*PFB_OUTPUT_STACK_SIZE)+iPFBTapIdx][1] = g_pfcFFTArray[i][0];
+
+ }
+}
+
+
+void process_seg() {
+ int iTapeBufferIdx = 0;
+ signed int iDataIdx = 0;
+ int iFlagBreak = FALSE;
+
+ while (iTapeBufferIdx < tapebuffer.size()) { // walk tape blocks
+ while (iDataIdx < tapebuffer[iTapeBufferIdx].data.size()) { // walk data within a tape block
+ int i;
+ float* fbuff = (float*) g_pcfPackedDataOut;
+ fftwf_complex *pfcPackedDataOut = (fftwf_complex*) g_pcfPackedDataOut;
+ float r_total=0, r_mean=0, i_total=0, i_mean=0; // used for nulling the DC bin
+ int iPrevTapeBufferIdx = 0; /* to keep track of tapebuffer-index-change */
+ int iPFBOutputStackIdx;
+ int iPFBTapIdx;
+ int iPFBFftIdx;
+
+ // this outer loop just stacks up the amout of data required by output_samples()
+ for(iPFBOutputStackIdx=0; iPFBOutputStackIdx<PFB_OUTPUT_STACK_SIZE; iPFBOutputStackIdx++) {
+
+ iPrevTapeBufferIdx = iTapeBufferIdx; // save the current tapebuffer index, to check if it has changed in this read
+
+ // load the data on which the PFB + FFT will operate
+ for (iPFBTapIdx = 0; iPFBTapIdx < g_iNTaps; ++iPFBTapIdx) {
+ for (iPFBFftIdx = 0; iPFBFftIdx < PFB_FFT_LEN;iPFBFftIdx ++) {
+ iFlagBreak = load_pfb_data(iTapeBufferIdx, iDataIdx, iPFBTapIdx, iPFBFftIdx);
+ }
+ }
+
+ iDataIdx = set_iDataIdx(iDataIdx, iTapeBufferIdx, iPrevTapeBufferIdx);
+
+ DoPFB(0); // use the PFB to filter data for FFT;
+ // data set is g_iNTaps*PFB_FFT_LEN in size
+
+ fftwf_execute(g_stPlan); // this is an in-place FFT so output in g_pfcFFTArray itself;
+ // data set is now PFB_FFT_LEN in size
+
+ reorder_data(pfcPackedDataOut, iPFBOutputStackIdx);
+
+ if (iFlagBreak) break;
+ } // end stack data for output_samples()
+
+ // effectively null the DC bin. The initial complex data point in each spectra
+ // of the output stack is time domain data for subband 0, which contains the DC bin.
+ for(i=0; i<PFB_OUTPUT_STACK_SIZE; i++) {
+ r_total += pfcPackedDataOut[i*PFB_FFT_LEN][0]; // (real part)
+ i_total += pfcPackedDataOut[i*PFB_FFT_LEN][1]; // (imaginary part)
+ }
+ r_mean = r_total/PFB_OUTPUT_STACK_SIZE;
+ i_mean = i_total/PFB_OUTPUT_STACK_SIZE;
+ for(i=0; i<PFB_OUTPUT_STACK_SIZE; i++) {
+ pfcPackedDataOut[i*PFB_FFT_LEN][0] -= r_mean; // (real part)
+ pfcPackedDataOut[i*PFB_FFT_LEN][1] -= i_mean; // (imaginary part)
+ }
+
+
+ for (i=0; i<NSTRIPS; i++) { // NSTRIPS = 256 WUs in 1 WUG
+ output_samples(fbuff, i); // output_samples() outputs 8 complex samples per call
+ fbuff += PFB_OUTPUT_STACK_SIZE*2; // ..so, we move fbuff ahead by PFB_OUTPUT_STACK_SIZE (8) complex (via *2) floats
+ }
+
+ if (iFlagBreak) break;
+ } // end, walk data within a tape block
+
+ if (iFlagBreak) break;
+ } // end, walk tape blocks
+
+ return;
+}
+
+void do_transform(std::vector<dr2_compact_block_t> &tapebuffer) {
+ int iRet = EXIT_SUCCESS;
+
+ /* initialise PFB-related stuff */
+ if (g_iIsFirstRun)
+ {
+ iRet = InitPFB();
+ if (iRet != EXIT_SUCCESS)
+ {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "InitPFB() failed\n");
+ PFBCleanUp();
+ return;
+ }
+ log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, "PFB initialised.\n");
+ g_iIsFirstRun = FALSE;
+ }
+
+ process_seg();
+
+ /* Move the data in the buffer so we don't have to reread portions of the
+ * tape. Leave a 20% overlap.
+ */
+ tapebuffer.erase(tapebuffer.begin(),tapebuffer.begin()+tapebuffer.size()*8/10);
+
+}
+
+/* function that allocates memory, reads filter coefficients, creates FFT plan,
+ etc. */
+int InitPFB()
+{
+ int iRet = EXIT_SUCCESS;
+ int iFileCoeff = 0;
+ int i = 0;
+
+ g_iNTaps = splitter_settings.splitter_cfg->pfb_ntaps;
+ g_fWidthFactor = splitter_settings.splitter_cfg->pfb_width_factor;
+
+
+ /* allocate memory for the filter coefficients */
+ g_pfPFBCoeff = (float *) malloc(g_iNTaps
+ * PFB_FFT_LEN
+ * sizeof(float));
+ if (NULL == g_pfPFBCoeff)
+ {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "InitPFB(): Memory allocation failed with %s\n",
+ strerror(errno));
+ return EXIT_FAILURE;
+ }
+
+ gen_coeff(g_pfPFBCoeff, g_iNTaps * PFB_FFT_LEN); // generate the coefficients
+
+ /* allocate memory for the PFB data arrays */
+ g_astPFBData = (PFB_DATA *) malloc(g_iNTaps * sizeof(PFB_DATA));
+ if (NULL == g_astPFBData)
+ {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "InitPFB(): Memory allocation failed with %s\n",
+ strerror(errno));
+ return EXIT_FAILURE;
+ }
+ for (i = 0; i < g_iNTaps; ++i)
+ {
+ g_astPFBData[i].pcfData
+ = (complex<float>*) fftwf_malloc(PFB_FFT_LEN * sizeof(complex<float>));
+ if (NULL == g_astPFBData[i].pcfData)
+ {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "InitPFB(): Memory allocation failed with %s\n",
+ strerror(errno));
+ return EXIT_FAILURE;
+ }
+ /* pointer of type fftwf_complex */
+ g_astPFBData[i].pfcData = (fftwf_complex*) g_astPFBData[i].pcfData;
+ }
+
+ /* allocate memory for FFT input/output array */
+ g_pfcFFTArray = (fftwf_complex *) fftwf_malloc(PFB_FFT_LEN
+ * sizeof(fftwf_complex));
+ if (NULL == g_pfcFFTArray)
+ {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "InitPFB(): Memory allocation failed with %s\n",
+ strerror(errno));
+ return EXIT_FAILURE;
+ }
+
+ /* create FFT plan */
+ g_stPlan = fftwf_plan_dft_1d(PFB_FFT_LEN,
+ g_pfcFFTArray,
+ g_pfcFFTArray,
+ FFTW_FORWARD,
+ FFTW_MEASURE);
+
+ /* allocate memory to pack the output of g_iNTaps FFTs in the PFB
+ loop in the process_seg() function, so that the output data structure
+ remains same as before PFB implementation */
+ g_pcfPackedDataOut = (complex<float> *) fftwf_malloc(PFB_OUTPUT_STACK_SIZE
+ * PFB_FFT_LEN
+ * sizeof(complex<float>));
+ if (NULL == g_pcfPackedDataOut)
+ {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "InitPFB(): Memory allocation failed with %s\n",
+ strerror(errno));
+ return EXIT_FAILURE;
+ }
+
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL, "InitPFB(): Configured with NTaps %d WidthFactor %f\n",
+ g_iNTaps, g_fWidthFactor);
+ return EXIT_SUCCESS;
+}
+
+/* function that performs the PFB */
+void DoPFB(int iPFBReadIdx)
+{
+ int i = 0;
+ int j = 0;
+ int k = 0;
+ int iCoeffStartIdx = 0;
+
+ /* reset memory */
+ (void) memset(g_pfcFFTArray, '\0', PFB_FFT_LEN * sizeof(fftw_complex));
+
+ /* perform polyphase filtering, starting from the read index */
+ i = iPFBReadIdx;
+ for (j = 0; j < g_iNTaps; ++j)
+ {
+ iCoeffStartIdx = j * PFB_FFT_LEN;
+ for (k = 0; k < PFB_FFT_LEN; ++k)
+ {
+ /* real part */
+ g_pfcFFTArray[k][0] += g_astPFBData[i].pfcData[k][0]
+ * g_pfPFBCoeff[iCoeffStartIdx+k];
+ /* imaginary part */
+ g_pfcFFTArray[k][1] += g_astPFBData[i].pfcData[k][1]
+ * g_pfPFBCoeff[iCoeffStartIdx+k];
+ }
+ i = (i + 1) % g_iNTaps;
+ }
+
+ return;
+}
+
+/* function that frees resources */
+void PFBCleanUp()
+{
+ int i = 0;
+
+ /* free resources */
+ for (i = 0; i < g_iNTaps; ++i)
+ {
+ free(g_astPFBData[i].pcfData);
+ }
+
+ fftwf_free(g_pfcFFTArray);
+ free(g_pfPFBCoeff);
+
+ /* destroy plans */
+ fftwf_destroy_plan(g_stPlan);
+
+ fftwf_cleanup();
+
+ return;
+}
+
+/*
+ *
+ * $Log: mb_dotransform.cpp,v $
+ * Revision 1.1.2.3 2007/06/06 15:58:29 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.1.2.2 2007/04/25 17:27:30 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.1.2.1 2006/12/14 22:24:40 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.2 2003/09/11 18:53:37 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.1 2003/07/29 20:35:36 korpela
+ *
+ * renames .C files to .cpp
+ *
+ * Revision 1.1 2003/06/03 00:16:10 korpela
+ *
+ * Initial splitter under CVS control.
+ *
+ * Revision 3.2 2003/05/19 17:40:59 eheien
+ * *** empty log message ***
+ *
+ * Revision 3.1 2003/04/10 22:09:00 korpela
+ * *** empty log message ***
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.7 1999/03/27 16:19:35 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.6 1999/02/22 19:02:50 korpela
+ * Revered input real & imaginary.
+ *
+ * Revision 2.5 1999/02/10 21:49:44 korpela
+ * Zeroed DC component of forward transform.
+ *
+ * Revision 2.4 1999/02/01 22:28:52 korpela
+ * FFTW version.
+ *
+ * Revision 2.3 1998/12/14 23:41:44 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.2 1998/11/04 23:08:25 korpela
+ * Byte and bit order change.
+ *
+ * Revision 2.1 1998/11/02 16:41:21 korpela
+ * Minor Change.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.2 1998/10/30 20:26:03 korpela
+ * Bug Fixes. Now mostly working.
+ *
+ * Revision 1.1 1998/10/27 00:51:08 korpela
+ * Initial revision
+ *
+ *
+ */
+
diff --git a/gbt_splitter/mb_dotransform.h b/gbt_splitter/mb_dotransform.h
new file mode 100644
index 0000000..a531c89
--- /dev/null
+++ b/gbt_splitter/mb_dotransform.h
@@ -0,0 +1,73 @@
+/*
+ *
+ * dotransform.h
+ *
+ * Functions for division by frequency into work units.
+ *
+ * $Id: mb_dotransform.h,v 1.1.2.2 2007/04/25 17:20:28 korpela Exp $
+ *
+ */
+
+
+/* buffer for ftt output before data writes, needs to be multiple
+ * of three bytes long for encode to work.
+ */
+#define SAMPLES_PER_OBUF (FFT_LEN*2*3/CHAR_BIT)
+#define TBUF_OFFSET(frame,byte) (tapebuffer+(frame)*TAPE_FRAME_SIZE+(byte))
+
+#define FALSE 0
+#define TRUE 1
+
+#define FILE_COEFF_PREFIX "coeff"
+#define FILE_COEFF_DATATYPE "float"
+#define FILE_COEFF_SUFFIX ".dat"
+
+#define PFB_OUTPUT_STACK_SIZE 8 // this has to be 8 for the benefit of output_samples()
+#define PFB_FFT_LEN 256
+
+//extern int obuf_pos; /* Tracks current postition in the output buffers */
+
+
+void output_samples(float *data, int i, int buf_pos);
+void splitter_bits_to_float(unsigned short *raw, float *data, int nsamples) ;
+void process_seg(void);
+void do_transform(std::vector<dr2_compact_block_t> &tapebuffer) ;
+
+int InitPFB(void);
+void DoPFB(int iReadIdx);
+void PFBCleanUp(void);
+
+/*
+ *
+ * $Log: mb_dotransform.h,v $
+ * Revision 1.1.2.2 2007/04/25 17:20:28 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.1.2.1 2006/12/14 22:24:41 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.1 2003/06/03 00:16:11 korpela
+ *
+ * Initial splitter under CVS control.
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.3 1999/02/01 22:28:52 korpela
+ * FFTW version.
+ *
+ * Revision 2.2 1998/11/04 23:08:25 korpela
+ * Byte and bit order change.
+ *
+ * Revision 2.1 1998/11/02 16:41:21 korpela
+ * Minor Change.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.1 1998/10/27 01:05:22 korpela
+ * Initial revision
+ *
+ *
+ */
+
diff --git a/gbt_splitter/mb_message.cpp b/gbt_splitter/mb_message.cpp
new file mode 100644
index 0000000..022fbf7
--- /dev/null
+++ b/gbt_splitter/mb_message.cpp
@@ -0,0 +1,73 @@
+/*
+ * Functions for sending messages to stderr and log files.
+ *
+ * $Id: mb_message.cpp,v 1.1.2.1 2006/12/14 22:24:42 korpela Exp $
+ */
+
+#include "sah_config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "setilib.h"
+#include "sqlrow.h"
+#include "sqlblob.h"
+#include "sqlapi.h"
+#include "db_table.h"
+#include "schema_master.h"
+#include "xml_util.h"
+
+
+#include "boinc_db.h"
+#include "sched_config.h"
+#include "sched_msgs.h"
+#include "mb_splitter.h"
+
+void message(char *msg) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"%s %s",tapebuffer[0].header.name,msg);
+}
+
+
+
+/*
+ * $Log: mb_message.cpp,v $
+ * Revision 1.1.2.1 2006/12/14 22:24:42 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.2.4.1 2006/01/13 00:37:57 korpela
+ * Moved splitter to using standard BOINC logging mechanisms. All stderr now
+ * goes to "error.log"
+ *
+ * Added command line parameters "-iterations=" (number of workunit groups to
+ * create before exiting), "-trigger_file_path=" (path to the splitter_stop trigger
+ * file. Default is /disks/setifiler1/wutape/tapedir/splitter_stop).
+ *
+ * Reduced deadlines by a factor of three. We now need a 30 MFLOP machine to meet
+ * the deadline.
+ *
+ * Revision 1.2 2003/09/11 18:53:38 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.1 2003/07/29 20:35:43 korpela
+ *
+ * renames .C files to .cpp
+ *
+ * Revision 1.1 2003/06/03 00:16:14 korpela
+ *
+ * Initial splitter under CVS control.
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.2 2000/12/01 01:13:29 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.1 1998/11/02 16:41:21 korpela
+ * Minor Change.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.1 1998/10/27 00:56:16 korpela
+ * Initial revision
+ *
+ */
diff --git a/gbt_splitter/mb_polyphase.cpp b/gbt_splitter/mb_polyphase.cpp
new file mode 100644
index 0000000..6df3548
--- /dev/null
+++ b/gbt_splitter/mb_polyphase.cpp
@@ -0,0 +1,150 @@
+
+#include "sah_config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <unistd.h>
+#include <limits.h>
+#include <assert.h>
+#include <math.h>
+#include "setilib.h"
+
+#include "splitparms.h"
+#include "splittypes.h"
+#include "mb_splitter.h"
+#include "mb_fftw.h"
+#include "mb_wufiles.h"
+#include "mb_polyphase.h"
+#include "mb_dotransform.h"
+
+/* buffer for fft input/output */
+//float databuf[FFT_LEN*2];
+
+/* buffer for ftt output before data writes, needs to be multiple
+ * of three bytes long for encode to work.
+ */
+#define SAMPLES_PER_OBUF (FFT_LEN*2*3/CHAR_BIT)
+
+extern unsigned char output_buf[NSTRIPS][SAMPLES_PER_OBUF];
+
+double *filter_r, *filter_i;
+float *f_data;
+
+extern int obuf_pos; /* Tracks current postition in the output buffers */
+
+void make_FIR (int n_points, int M, int window, double *output) {
+ /* Create Mth band lowpass FIR filter, n_points long. */
+
+ /* Modify this to give 8-bit quantized filter. */
+ /* Also generate Hilbert transformed filter */
+
+ int n;
+ double q, p;
+
+ for (n=0; n<n_points; n++) {
+ if (n == n_points/2) {
+ output[n] = 1;
+ } else {
+ q = n-(n_points/2);
+ p = n_points/M;
+ output[n] = sin(M_PI*q/p)/(M_PI*q/p);
+ }
+ }
+ if (window == HANNING) {
+ for (n=0; n<n_points; n++) {
+ output[n] = output[n]*.5*(1 - cos(2*M_PI*n/(n_points-1)));
+ }
+ }
+ else if (window == WELCH) {
+ for (n=0; n<n_points; n++) {
+ output[n] = output[n]*(1 - ((n-.5*(n_points-1))/(.5*(n_points+1)))*((n-.5*(n_points-1))/(.5*(n_points+1))));
+ }
+ }
+}
+
+
+void polyphase_seg(float* data) {
+ int i,n;
+ static fftw_plan planfwd;
+ float *p;
+
+ if (!planfwd) {
+ planfwd=fftw_create_plan(P_FFT_LEN, FFTW_FORWARD,
+ FFTW_MEASURE | FFTW_IN_PLACE | FFTW_USE_WISDOM );
+ }
+
+ for (i=0;i<P_FFT_LEN;i++) {
+ f_data[2*i] = 0;
+ f_data[2*i+1] = 0;
+ for (n=0;n<N_WINDOWS;n++) {
+ f_data[2*i] += data[2*i+2*n*P_FFT_LEN]*filter_r[P_FFT_LEN*n + i];
+ f_data[2*i+1] += data[2*i+2*n*P_FFT_LEN+1]*filter_i[P_FFT_LEN*n + i];
+ }
+ }
+ fftw_one(planfwd, (fftw_complex *)f_data, (fftw_complex *)NULL);
+ /*for (i=0;i<P_FFT_LEN;i++) {
+ fprintf( stderr, "%f %f\n", f_data[2*i], f_data[2*i+1]);
+ }*/
+ //fprintf( stderr, "%f %f ", f_data[2*3], f_data[2*3+1] );
+ p = f_data;
+ for (i=0; i<P_FFT_LEN; i++) {
+ output_samples(p, i, obuf_pos);
+ p += IFFT_LEN*2;
+ }
+ obuf_pos+=IFFT_LEN*2/CHAR_BIT;
+}
+
+#define TBUF_OFFSET(frame,byte) (tapebuffer+(frame)*TAPE_FRAME_SIZE+(byte)+TAPE_HEADER_SIZE)
+
+void do_polyphase(buffer_pos_t *start_of_wu, buffer_pos_t *end_of_wu) {
+ buffer_pos_t end_trans,start_trans=*start_of_wu;
+ int i,nsamp;
+ do {
+ obuf_pos=0; // reset to the beginning of the output buffer
+ for (i=0;i<768;i++) {
+ end_trans.frame=start_trans.frame;
+ end_trans.byte=start_trans.byte+(FFT_LEN*2/CHAR_BIT);
+ if (end_trans.byte > TAPE_DATA_SIZE) {
+ // End of frame crossed need to trasfer correctly
+ end_trans.frame++;
+ end_trans.byte-=TAPE_DATA_SIZE;
+ nsamp=(TAPE_DATA_SIZE-start_trans.byte)*(CHAR_BIT/2);
+ assert((nsamp+end_trans.byte*(CHAR_BIT/2)) == FFT_LEN);
+ splitter_bits_to_float((unsigned short *)TBUF_OFFSET(start_trans.frame,start_trans.byte),
+ databuf, nsamp);
+ splitter_bits_to_float((unsigned short *)TBUF_OFFSET(end_trans.frame,0),databuf+nsamp*2,
+ end_trans.byte*(CHAR_BIT/2));
+ } else {
+ splitter_bits_to_float((unsigned short *)TBUF_OFFSET(start_trans.frame,start_trans.byte),
+ databuf,FFT_LEN);
+ }
+ polyphase_seg(databuf);
+ // Go on to next transform
+ start_trans=end_trans;
+ }
+ // Check if we're at the end of the wu file. If so we print less bytes
+ if ((end_trans.frame>=end_of_wu->frame) &&
+ (end_trans.byte>=end_of_wu->byte)) {
+ write_wufile_blocks(NBYTES % SAMPLES_PER_OBUF);
+ } else {
+ write_wufile_blocks(SAMPLES_PER_OBUF);
+ }
+ } while (!((end_trans.frame>=end_of_wu->frame) && (end_trans.byte>=end_of_wu->byte)));
+
+ // Move the data in the buffer so we don't have to reread portions of the
+ // tape.
+ //
+ {
+ unsigned char *record_offset;
+ int copysize;
+ end_of_wu->frame-=WU_OVERLAP_FRAMES;
+ records_in_buffer=TAPE_RECORDS_IN_BUFFER-
+ (end_of_wu->frame/TAPE_FRAMES_PER_RECORD);
+ record_offset=tapebuffer+
+ (end_of_wu->frame/TAPE_FRAMES_PER_RECORD)*TAPE_RECORD_SIZE;
+ copysize=records_in_buffer*TAPE_RECORD_SIZE;
+ bcopy(record_offset,tapebuffer,copysize);
+ }
+}
+
+
diff --git a/gbt_splitter/mb_splitter.cpp b/gbt_splitter/mb_splitter.cpp
new file mode 100644
index 0000000..6479b5c
--- /dev/null
+++ b/gbt_splitter/mb_splitter.cpp
@@ -0,0 +1,966 @@
+/*
+ *
+ * The splitter main program.
+ *
+ * $Id: mb_splitter.cpp,v 1.1.2.6 2007/08/16 23:03:19 jeffc Exp $
+ *
+ */
+
+#include "sah_config.h"
+#undef USE_MYSQL
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <strings.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/statvfs.h>
+#include <sys/wait.h>
+#include <errno.h>
+
+#include "boinc_db.h"
+#include "backend_lib.h"
+#include "sched_config.h"
+#include "setilib.h"
+#include "str_util.h"
+#include "str_replace.h"
+#include "splitparms.h"
+#include "splittypes.h"
+#include "mb_splitter.h"
+#include "mb_validrun.h"
+#include "mb_wufiles.h"
+#include "mb_dotransform.h"
+#include "message.h"
+#include "sqlrow.h"
+#include "sqlapi.h"
+#include "db/db_table.h"
+#include "db/schema_master.h"
+#include "db/app_config.h"
+
+extern "C" {
+ int sqldetach();
+}
+
+char trigger_file_path[1024]="/disks/setifiler1/wutape/tapedir/splitter_stop";
+
+SCHED_CONFIG boinc_config;
+DB_APP app;
+R_RSA_PRIVATE_KEY key;
+
+// configuration tables
+receiver_config rcvr;
+settings splitter_settings;
+
+// TEMPLATE DEFS ------------------------------------------------------
+// IMPORTANT: a change to a template should *always* include a change
+// to the template filename. Only the result template is used now.
+const char *wu_template_filename_id = "wu_0.xml";
+const char *wu_template=
+ "<file_info>\n"
+ " <number>0</number>\n"
+ "</file_info>\n"
+ "<workunit>\n"
+ " <file_ref>\n"
+ " <file_number>0</file_number>\n"
+ " <open_name>work_unit.sah</open_name>\n"
+ " </file_ref>\n"
+ "</workunit>\n";
+
+const char *result_template_filename_id = "result_0.xml";
+const char *result_template=
+ "<file_info>\n"
+ " <name><OUTFILE_0/></name>\n"
+ " <generated_locally/>\n"
+ " <upload_when_present/>\n"
+ " <max_nbytes>65536</max_nbytes>\n"
+ " <url>http://setiboincdata.ssl.berkeley.edu/sah_cgi/file_upload_handler</url>\n"
+ "</file_info>\n"
+ "<result>\n"
+ " <file_ref>\n"
+ " <file_name><OUTFILE_0/></file_name>\n"
+ " <open_name>result.sah</open_name>\n"
+ " </file_ref>\n"
+ "</result>\n";
+// END TEMPLATE DEFS --------------------------------------------------
+
+std::vector<dr2_compact_block_t> tapebuffer;
+std::map<seti_time,coordinate_t> coord_history;
+std::vector<workunit> wuheaders;
+char appname[256];
+int max_wus_ondisk=MAX_WUS_ONDISK;
+int nodb;
+int noencode;
+int resumetape;
+int norewind;
+int startblock;
+int dataclass;
+int atnight;
+int gregorian;
+int output_xml;
+int polyphase;
+int iters=-1;
+int beam;
+int pol;
+int alfa;
+int useanalysiscfgid = 0;
+int usereceivercfgid = 0;
+int userecordercfgid = 0;
+int usesplittercfgid = 0;
+int filter_window = 0;
+double start_time;
+double stop_time;
+unsigned long minvfsbuf=-1;
+char wd[1024];
+//char * scidb = NULL;
+char * projectdir = NULL;
+
+APP_CONFIG sah_config;
+
+//const char *result_template_filename="projectdir"/"SAH_APP_NAME"_result.tpl";
+char result_template_filename[1024];
+char result_template_filepath[1024];
+char wu_template_filename[1024];
+
+int check_for_halt();
+int wait_until_night();
+int check_free_disk_space();
+int wait_for_db_wus_ondisk();
+
+void cprint(char *p) {
+ printf("%s\n",p);
+}
+
+/* wulog: File for logging names of completed wu files */
+/* errorlog: File for logging errors */
+
+FILE *wulog,*errorlog;
+buffer_pos_t start_of_wu,end_of_wu; /* position of start and end of wu in
+ tape buffer */
+int seqno;
+
+void cleanup(void) {
+ FILE *tmpfile;
+ if ((tmpfile=fopen("seqno.dat","w"))) {
+ fprintf(tmpfile,"%d\n",seqno);
+ fclose(tmpfile);
+ } else {
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Unable to open seqno.dat for write\n");
+ }
+}
+
+
+int process_command_line(int argc, char *argv[],char **tape_device,
+ int *norewind, int *startblock, int *resumetape,
+ int *nodb, int *dataclass, int *atnight,
+ int *max_wus_ondisk, char **projectdir,
+ int *iters, int *beam, int *pol, int *alfa,
+ int *useanalysiscfgid, int *usereceivercfgid,
+ int *userecordercfgid, int *usesplittercfgid) {
+ int nargs=0,i;
+ char *ep;
+ strcpy(appname,SAH_APP_NAME);
+ for (i=1;i<argc;i++) {
+ if (argv[i][0]=='-') {
+ if (!strncmp(argv[i],"-hanning",MAX(strlen(argv[i]),3))) {
+ filter_window=2;
+ } else
+ if (!strncmp(argv[i],"-welch",MAX(strlen(argv[i]),3))) {
+ filter_window=1;
+ } else
+ if (!strncmp(argv[i],"-xml",MAX(strlen(argv[i]),3))) {
+ output_xml=1;
+ } else
+ if (!strncmp(argv[i],"-atnight",MAX(strlen(argv[i]),7))) {
+ *atnight=1;
+ } else
+ if (!strncmp(argv[i],"-nodb",MAX(strlen(argv[i]),4))) {
+ if (*resumetape) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"-nodb and -resumetape are exclusive\n");
+ return(1);
+ }
+ *nodb=1;
+ } else
+ if (!strncmp(argv[i],"-gregorian",MAX(strlen(argv[i]),2))) {
+ gregorian=1;
+ } else
+ if (!strncmp(argv[i],"-resumetape",MAX(strlen(argv[i]),2))) {
+ if (*startblock || *norewind) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"-startblock and -norewind can\'t be used with -resumetape\n");
+ return(1);
+ }
+ if (*nodb) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"-nodb and -resumetape are exclusive\n");
+ return(1);
+ }
+ *resumetape=1;
+ } else
+ if (!strncmp(argv[i],"-norewind",MAX(strlen(argv[i]),4))) {
+ if (*startblock || *resumetape) {
+ return(1);
+ }
+ *norewind=1;
+ } else
+ if ((ep=strchr(argv[i],'='))) {
+ if (!strncmp(argv[i],"-appname",MAX(ep-argv[i],3))) {
+ strlcpy(appname,ep+1,sizeof(appname));
+ } else if (!strncmp(argv[i],"-trigger_file_path",MAX(ep-argv[i],2))) {
+ char *fe=ep+1;
+ memset(trigger_file_path,0,sizeof(trigger_file_path));
+ while (isgraph(*(fe++))) trigger_file_path[fe-ep-2]=*fe ;
+ } else if (!strncmp(argv[i],"-alfa",MAX(ep-argv[i],3))) {
+ sscanf(ep+1,"%d,%d",beam,pol);
+ if (((*beam<0) || (*beam>6)) ||
+ ((*pol<0) || (*pol>1))) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"ALFA receivers must be specified with beam (0-6) and polarization (0-1), i.e. -alfa=4,0\n");
+ exit(EXIT_FAILURE);
+ }
+
+ *alfa=1;
+ } else if (!strncmp(argv[i],"-iterations",MAX(ep-argv[i],2))) {
+ sscanf(ep+1,"%d",iters);
+ } else if (!strncmp(argv[i],"-startblock",MAX(ep-argv[i],2))) {
+ if (*norewind || *resumetape) {
+ return(1);
+ }
+ sscanf(ep+1,"%d",startblock);
+ } else if (!strncmp(argv[i],"-max_wus_ondisk",MAX(ep-argv[i],2))) {
+ sscanf(ep+1,"%d",max_wus_ondisk);
+ } else if (!strncmp(argv[i],"-dataclass",MAX(ep-argv[i],2))) {
+ sscanf(ep+1,"%d",dataclass);
+ } else if (!strncmp(argv[i],"-projectdir",MAX(ep-argv[i],2))) {
+ *projectdir=(char *)calloc(strlen(ep+1)+5,1);
+ strlcpy(*projectdir,ep+1,strlen(ep+1)+5);
+ strlcat(*projectdir,"/",strlen(ep+1)+5);
+ } else if (!strncmp(argv[i],"-analysis_config",MAX(ep-argv[i],2))) {
+ sscanf(ep+1,"%d",useanalysiscfgid);
+ } else if (!strncmp(argv[i],"-recorder_config",MAX(ep-argv[i],2))) {
+ sscanf(ep+1,"%d",userecordercfgid);
+ } else if (!strncmp(argv[i],"-receiver_config",MAX(ep-argv[i],2))) {
+ sscanf(ep+1,"%d",usereceivercfgid);
+ } else if (!strncmp(argv[i],"-splitter_config",MAX(ep-argv[i],2))) {
+ sscanf(ep+1,"%d",usesplittercfgid);
+ } else {
+ return(1);
+ }
+ } else {
+ return(1);
+ }
+ } else {
+ *tape_device=argv[i];
+ nargs++;
+ }
+ }
+ //return(nargs!=1);
+
+ // check for required cmd line
+ //if (! *scidb) return (1);
+ if (! *projectdir) return (1);
+ if (! *tape_device) return (1);
+
+ return 0;
+}
+
+int main(int argc, char *argv[]) {
+ int tape_fd;
+ char *tape_device;
+ FILE *tmpfile;
+ int retval;
+ char keyfile[1024];
+ char tmpstr[1024];
+ char buf[1024];
+
+
+ /* Process command line arguments */
+ if (process_command_line(argc,argv,&tape_device,&norewind,&startblock,&resumetape,
+ &nodb,&dataclass,&atnight,&max_wus_ondisk,&projectdir,&iters,
+ &beam,&pol,&alfa,&useanalysiscfgid,&usereceivercfgid,
+ &userecordercfgid,&usesplittercfgid)) {
+ fprintf(stderr,"Usage: splitter tape_device -projectdir=s [-atnight] [-nodb]\n"
+ "[-xml] [-gregorian] [-resumetape | -norewind | -startblock=n] [-dataclass=n]\n"
+ "[-max_wus_on_disk=n] [-iterations=n] [-trigger_file_path=filename]\n"
+ "[-alfa=beam,pol] [-analysis_config=id] [-receiver_config=id]\n"
+ "[-recorder_config=id] [-splitter_config=id]\n");
+ exit(EXIT_FAILURE);
+ }
+
+ // MATTL
+ if (blanking_bit == SOFTWARE_BLANKING_BIT) log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"blanking bit: %d (SOFTWARE)\n",blanking_bit);
+ else log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"blanking bit: %d (HARDWARE)\n",blanking_bit);
+
+ /* Open log files */
+ log_messages.set_debug_level(3);
+
+ retval = sah_config.parse_file(projectdir);
+ if (retval) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Can't parse config file\n");
+ exit(EXIT_FAILURE);
+ } else {
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Using configuration:\n");
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"scidb_name = %s\n", sah_config.scidb_name);
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"max_wus_ondisk = %d\n", sah_config.max_wus_ondisk);
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"min_quorum = %d\n", sah_config.min_quorum);
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"target_nresults = %d\n", sah_config.target_nresults);
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"max_error_results = %d\n", sah_config.max_error_results);
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"max_success_results = %d\n", sah_config.max_success_results);
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"max_total_results = %d\n", sah_config.max_total_results);
+ }
+
+ // Will initially open
+ if (!db_change(sah_config.scidb_name)) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Could not open science database %s\n", sah_config.scidb_name);
+ if (!nodb) exit(EXIT_FAILURE);
+ } else {
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Using science database %s\n", sah_config.scidb_name);
+ }
+
+
+ boinc_config.parse_file(projectdir);
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Using boinc config dir %s\n", projectdir);
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Using boinc database %s\n", boinc_config.db_name);
+
+ // check / commit result template
+ strcpy(result_template_filename, "templates/");
+ strcat(result_template_filename, appname);
+ strcat(result_template_filename, "_");
+ strcat(result_template_filename, result_template_filename_id);
+ strcpy(result_template_filepath, projectdir);
+ strcat(result_template_filepath, result_template_filename);
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"%s %s\n", result_template_filename, result_template_filepath);
+ if (!(tmpfile=fopen(result_template_filepath,"r"))) {
+ if (!(tmpfile=fopen(result_template_filepath,"w"))) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Cannot open result file template : %s\n", result_template_filepath);
+ exit(1);
+ }
+ fprintf(tmpfile,result_template);
+ }
+ fclose(tmpfile);
+
+ if (boinc_db.open(boinc_config.db_name,boinc_config.db_host,boinc_config.db_user,boinc_config.db_passwd)) {
+ boinc_db.print_error("boinc_db.open");
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"boinc_db.open\n");
+ exit(1);
+ }
+
+ char tmpquery[128];
+ sprintf(tmpquery,"where name ='%s'",appname);
+ if (app.lookup(tmpquery)) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Error looking up appname\n");
+ boinc_db.print_error("boinc_app lookup");
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"boinc_app lookup\n");
+ exit(1);
+ } else {
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Splitting for application %s (ID = %d)\n", appname, app.id);
+ }
+
+ boinc_db.close();
+
+ telescope_id tel=
+ channel_to_receiverid[beam_pol_to_channel[bmpol_t(beam,pol)]];
+
+ sprintf(buf,"where active=%d and receiver_cfg=(select id from receiver_config where s4_id=%d)",app.id,AO_ALFA_0_0);
+ if (usereceivercfgid > 0) {
+ sprintf(buf,"where active=%d and receiver_cfg=%d",app.id,usereceivercfgid);
+ }
+ if (!splitter_settings.fetch(std::string(buf))) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Unable to find active settings for app.id=%d\n",app.id);
+ exit(1);
+ }
+
+ sprintf(buf,"where s4_id=%d and id>=%d",tel,splitter_settings.receiver_cfg.id);
+ if (usereceivercfgid > 0) { sprintf(buf,"where id=%d",usereceivercfgid); }
+ rcvr.fetch(buf);
+ if (usereceivercfgid > 0) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Using receiver cfg id: %d (set by user)\n",usereceivercfgid);
+ splitter_settings.receiver_cfg = usereceivercfgid;
+ splitter_settings.receiver_cfg->fetch();
+ } else {
+ splitter_settings.receiver_cfg->fetch(buf);
+ }
+ if (userecordercfgid > 0) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Using recorder cfg id: %d (set by user)\n",userecordercfgid);
+ splitter_settings.recorder_cfg = userecordercfgid;
+ }
+ splitter_settings.recorder_cfg->fetch();
+ if (usesplittercfgid > 0) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Using splitter cfg id: %d (set by user)\n",usesplittercfgid);
+ splitter_settings.splitter_cfg = usesplittercfgid;
+ }
+ splitter_settings.splitter_cfg->fetch();
+ if (useanalysiscfgid > 0) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Using analysis cfg id: %d (set by user)\n",useanalysiscfgid);
+ splitter_settings.analysis_cfg = useanalysiscfgid;
+ }
+ splitter_settings.analysis_cfg->fetch();
+
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL, "settings: \n\n%s\n", splitter_settings.print_xml(1,1,0).c_str());
+
+ strcpy(keyfile, projectdir);
+ strcat(keyfile, "/keys/upload_private");
+ if (read_key_file(keyfile,key)) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Error reading keyfile.\n");
+ exit(1);
+ }
+
+ check_for_halt();
+
+ if ((tape_fd=open(tape_device,O_RDONLY|0x2000, 0777))<0) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Unable to open tape device\n");
+ exit(EXIT_FAILURE);
+ }
+
+ // In early tapes there was a bug where the first N blocks would be duplicates
+ // of data from previous files. So we need to fast forward until we see a
+ // frame sequence number of 1.
+ int i,readbytes=HeaderSize;
+ dataheader_t header;
+ header.frameseq=100000;
+
+ while ((readbytes==HeaderSize) && (header.frameseq>10)) {
+ char buffer[HeaderSize];
+ int nread;
+ readbytes=0;
+ while ((readbytes!=HeaderSize) && (nread = read(tape_fd,buffer,HeaderSize-readbytes))) {
+ readbytes+=nread;
+ }
+ if (nread < 0) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"File error %d.\n", errno);
+ exit(1);
+ }
+ if (readbytes == HeaderSize) {
+ header.populate_from_data(buffer);
+ if (header.frameseq>10) {
+ lseek64(tape_fd,DataSize,SEEK_CUR);
+ } else {
+ lseek64(tape_fd,-1*(off64_t)HeaderSize,SEEK_CUR);
+ }
+ }
+ }
+
+ if (readbytes != HeaderSize) {
+ // we fast forwarded through the entire tape without finding the first frame
+ // maybe this is one of the really early tapes that was split into chunks.
+ lseek64(tape_fd,0,SEEK_SET);
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Warning: First block not found\n");
+ }
+
+ if (resumetape) {
+ tape thistape;
+ thistape.id=0;
+ readbytes=HeaderSize;
+ sprintf(buf,"%d",rcvr.s4_id-AO_ALFA_0_0);
+ if (thistape.fetch(std::string("where name=\'")+header.name+"\' and beam="+buf)) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG,"Resuming tape %s beam %d pol %d\n",thistape.name,beam,pol );
+ while ((readbytes==HeaderSize) && (header.dataseq!=thistape.last_block_done)) {
+ int nread=0;
+ char buffer[HeaderSize];
+ readbytes=0;
+ while ((readbytes!=HeaderSize) &&
+ ((nread = read(tape_fd,buffer,HeaderSize-readbytes)) > 0 )) {
+ readbytes+=nread;
+ }
+ if (readbytes == HeaderSize) {
+ header.populate_from_data(buffer);
+ if (header.dataseq!=thistape.last_block_done) {
+ lseek64(tape_fd,(off64_t)(DataSize+HeaderSize)*(thistape.last_block_done-header.dataseq)-HeaderSize,SEEK_CUR);
+ } else {
+ lseek64(tape_fd,-1*(off_t)HeaderSize,SEEK_CUR);
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Found starting point");
+ }
+ }
+ if (nread == 0) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"End of file.\n");
+ exit(0);
+ }
+ if (nread < 0) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"File error %d.\n",errno);
+ exit(1);
+ }
+ }
+ }
+ }
+
+ /* Start of main loop */
+
+
+ atexit(cleanup);
+
+ getcwd(wd,1024);
+
+ if (polyphase) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Polyphase not implemented\n" );
+ exit(1);
+#if 0
+ int filter_len;
+
+ filter_len = P_FFT_LEN*N_WINDOWS;
+
+ filter_r = (double *)malloc(sizeof(double)*filter_len);
+ filter_i = (double *)malloc(sizeof(double)*filter_len);
+
+ f_data = (float *)malloc(sizeof(float)*P_FFT_LEN*2);
+
+ make_FIR(filter_len, N_WINDOWS, filter_window, filter_r);
+ make_FIR(filter_len, N_WINDOWS, filter_window, filter_i);
+
+ /*
+ int i;
+ float *data;
+ data = (float*)malloc(sizeof(float)*2*2048);
+ for (double n=-20;n<20;n+=.05) {
+ for (i=0;i<2*2048;i+=2) {
+ data[i] = cos(2*(24+n)*3.1415926535*i/(2*2048));
+ data[i+1] = sin(2*(24+n)*3.1415926535*i/(2*2048));
+ }
+ polyphase_seg(data);
+ //fprintf( stderr, "%f\n", 3+n/8);
+ }
+ exit(0);
+ for(i=0;i<filter_len;i++)
+ printf( "%f\n", filter_r[i] );
+ exit(0);*/
+#endif
+ }
+ log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG,"Entering loop\n" );
+
+ blanking_filter<complex<signed char> > blanker_filter;
+ if (strcmp(splitter_settings.splitter_cfg->blanker_filter, "randomize") == 0) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG,"Setting blanker filter to randomize\n" );
+ blanker_filter = randomize;
+ } else {
+ log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG,"Setting blanker filter to null\n" );
+ blanker_filter = NULLC; // no blanking
+ }
+ while (iters-- &&
+ ((512-tapebuffer.size())==seti_StructureDr2Data(tape_fd, beam, pol,
+ 512-tapebuffer.size(), tapebuffer, blanker_filter))) {
+ /* check if we should be running now */
+ fflush(stderr);
+ if (atnight) wait_until_night();
+
+ sprintf(buf,"where active=%d and receiver_cfg=(select id from receiver_config where s4_id=%d)",app.id,AO_ALFA_0_0);
+ if (usereceivercfgid > 0) {
+ sprintf(buf,"where active=%d and receiver_cfg=%d",app.id,usereceivercfgid);
+ }
+ if (!splitter_settings.fetch(std::string(buf))) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Unable to find active settings for app.id=%d\n",app.id);
+ exit(1);
+ }
+
+ sprintf(buf,"where s4_id=%d and id>=%d",tel,splitter_settings.receiver_cfg.id);
+ if (usereceivercfgid > 0) { sprintf(buf,"where id=%d",usereceivercfgid); }
+ rcvr.fetch(buf);
+ if (usereceivercfgid > 0) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Using receiver cfg id: %d (set by user)\n",usereceivercfgid);
+ splitter_settings.receiver_cfg = usereceivercfgid;
+ splitter_settings.receiver_cfg->fetch();
+ } else {
+ splitter_settings.receiver_cfg->fetch(buf);
+ }
+ if (userecordercfgid > 0) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Using recorder cfg id: %d (set by user)\n",userecordercfgid);
+ splitter_settings.recorder_cfg = userecordercfgid;
+ }
+ splitter_settings.recorder_cfg->fetch();
+ if (usesplittercfgid > 0) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Using splitter cfg id: %d (set by user)\n",usesplittercfgid);
+ splitter_settings.splitter_cfg = usesplittercfgid;
+ }
+ splitter_settings.splitter_cfg->fetch();
+ if (useanalysiscfgid > 0) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Using analysis cfg id: %d (set by user)\n",useanalysiscfgid);
+ splitter_settings.analysis_cfg = useanalysiscfgid;
+ }
+ splitter_settings.analysis_cfg->fetch();
+
+ log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, "settings: \n\n%s\n", splitter_settings.print_xml(1,1,0).c_str());
+
+ check_for_halt();
+
+ // Make sure we have enough free disk space
+ check_free_disk_space();
+
+ // Wait for ondisk wus in the database to drop below the threshold
+ if (!nodb) wait_for_db_wus_ondisk();
+ //fprintf( stderr, "Read data\n" );
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"less than max wus on disk, continuing\n" );
+ fflush(stderr);
+
+ //printf( "Read tape data, analyzing\n" );
+ check_for_halt();
+
+ //check for an uninterrupted run
+ if (valid_run(tapebuffer,splitter_settings.receiver_cfg->min_vgc)) {
+ std::vector<dr2_compact_block_t>::iterator i=tapebuffer.begin();
+ // insert telescope coordinates into the coordinate history.
+ // this should be converted to a more accurate routine.
+ for (;i!=tapebuffer.end();i++) {
+ coord_history[i->header.coord_time].ra = i->header.ra;
+ coord_history[i->header.coord_time].dec = i->header.dec;
+ coord_history[i->header.coord_time].time = i->header.coord_time.jd().uval();
+ }
+ if (make_wu_headers(tapebuffer,tel,wuheaders)) {
+ int child_pid=-1;
+ switch (polyphase) {
+ case 1:
+ #if 0
+ do_polyphase(&start_of_wu,&end_of_wu);
+ #endif
+ break;
+ default:
+ log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG,"doing transform..." );
+ do_transform(tapebuffer);
+ log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG," done\n" );
+ }
+ wait(0);
+ if (!nodb) sql_finish();
+
+ do {
+ sleep(1);
+ child_pid=fork();
+ if (child_pid<0) log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"splitter cannot fork");
+ //fprintf( stderr, "child pid: %d\n", child_pid);
+ } while (child_pid<0);
+
+ if (!child_pid) {
+ if (!nodb) {
+ sqldetach();
+ while (!sql_database(sah_config.scidb_name)) {
+ //fprintf(stderr,"child sleeping\n");
+ sleep(10);
+ }
+ }
+ rename_wu_files();
+ if (!nodb) sql_finish();
+ _exit(0);
+ }
+
+ if (!nodb) {
+ while (!sql_database(sah_config.scidb_name)) {
+ //fprintf(stderr,"parent sleeping\n");
+ sleep(10);
+ }
+ }
+ }
+ }
+ }
+
+ // iters is initalized to -1. If the -iters flag is specified on the command
+ // line, iters is re-initialized to the user desired number of interations.
+ // Each time a WUG is proccessed iters is decremineted. If the user specifies
+ // iters and we do that number of iterations without reaching EOF then iters
+ // here will be zero. !Zero means we have reached EOF prior to performing the user
+ // desired number of iterations.
+ //
+ // On the other hand, if iters is not specified by the user, iters is decrmented
+ // downward from -1. It will never be zero in this case. But since we are not
+ // limiting the number of iterations, the only way will get here is if we reach EOF.
+ //
+ // Thus in both cases, a non-zero iters means we have reached EOF.
+ if (iters != 0) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"End of file.\n");
+ // clean stop at EOF
+ return (EXIT_NORMAL_EOF);
+ } else {
+ // clean stop, but not EOF (iters satisfied or triggered stop)
+ // (A return of 1 is an error exit somewhere else in the code.)
+ return(EXIT_NORMAL_NOT_EOF);
+ }
+}
+
+int check_for_halt() {
+ FILE *tf;
+
+ tf = fopen(trigger_file_path, "r");
+ // tf=0;
+ if (tf != NULL) { // Stop program
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Found splitter_stop, exiting.\n" );
+ exit(EXIT_NORMAL_NOT_EOF);
+ }
+ return(0); // Keep going
+}
+
+int wait_until_night() {
+ time_t t;
+ struct tm *lt;
+ do {
+ t=time(0);
+ lt=localtime(&t);
+ // Don't run M-F 8AM-6PM
+ if ((lt->tm_wday>0) && (lt->tm_wday<6) && (lt->tm_hour>8) && (lt->tm_hour<18)) {
+ sleep(100);
+ }
+ } while ((lt->tm_wday>0) && (lt->tm_wday<6) && (lt->tm_hour>8) && (lt->tm_hour<18));
+ return 0;
+}
+
+int check_free_disk_space() {
+ struct statvfs vfsbuf;
+
+ /* check disk free space in working directory */
+ statvfs("wu_inbox/.",&vfsbuf);
+ if (vfsbuf.f_frsize==0) vfsbuf.f_frsize=512;
+ if (vfsbuf.f_bavail < (100000*1024/vfsbuf.f_frsize)) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Not enough free disk space in working directory to continue\n");
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Not enough free disk space in working directory to continue\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* check free disk space in download directory tree */
+ std::string download_dir(boinc_config.download_dir);
+ int waited=0;
+ download_dir+="/.";
+ /* wait here if the disk is more than N% full */
+ statvfs(download_dir.c_str(),&vfsbuf);
+ if (vfsbuf.f_blocks > vfsbuf.f_bfree*100/sah_config.min_disk_free_pct) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Waiting for free space in download directory\n");
+ while (vfsbuf.f_blocks > vfsbuf.f_bfree*100/sah_config.min_disk_free_pct) {
+ waited+=10;
+ sleep(10);
+ statvfs(download_dir.c_str(),&vfsbuf);
+ }
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Waited %d seconds\n", waited);
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Continuing...\n");
+ }
+ return 0;
+}
+
+int wait_for_db_wus_ondisk() {
+ //int wus_ondisk,rv;
+ DB_STATE_COUNTS state_counts;
+ int retval;
+
+ // No need to check the DB for every single WUG iteration.
+ static int check_count = 100;
+ if (check_count < 100) {
+ check_count++;
+ return 0;
+ } else {
+ check_count = 0;
+ }
+
+ if (boinc_db.open(boinc_config.db_name,boinc_config.db_host,boinc_config.db_user,boinc_config.db_passwd)) {
+ boinc_db.print_error("boinc_db.open");
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"boinc_db.open\n");
+ exit(1);
+ }
+#if 0
+ retval = boinc_db.set_isolation_level(READ_UNCOMMITTED);
+ if (retval) {
+ log_messages.printf(MSG_CRITICAL, "boinc_db.set_isolation_level: %d; %s\n", rv, boinc_db.error_string());
+ exit(EXIT_FAILURE);
+ }
+ else {
+ log_messages.printf(MSG_NORMAL, "setting read uncommitted isolation level\n");
+ }
+#endif
+ do {
+ char query[1024];
+ sprintf(query,"where appid=%d",app.id);
+ retval=state_counts.lookup(query);
+ if (retval) {
+ boinc_db.print_error("state_counts.lookup");
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"DB Error, unable to count workunits on disk\n");
+ exit(EXIT_FAILURE);
+ }
+ check_for_halt();
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"%d WUs ondisk which is greater than the max of %d\n",
+ state_counts.result_server_state_2, sah_config.max_wus_ondisk);
+ if (state_counts.result_server_state_2>sah_config.max_wus_ondisk) sleep(600);
+
+#if 0
+ sprintf(query,"where appid=%d and server_state=2",app.id);
+ rv=boinc_result.count(wus_ondisk,query);
+ if (rv) {
+ boinc_db.print_error("boinc_result.count");
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"DB Error, unable to count workunits on disk\n");
+ exit(EXIT_FAILURE);
+ }
+ check_for_halt();
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"%d WUs ondisk\n", wus_ondisk);
+ if (wus_ondisk>sah_config.max_wus_ondisk) sleep(600);
+ } while (wus_ondisk>sah_config.max_wus_ondisk);
+#endif
+
+ } while (state_counts.result_server_state_2>sah_config.max_wus_ondisk);
+
+ boinc_db.close();
+ return 0;
+}
+
+/*
+ * $Log: mb_splitter.cpp,v $
+ * Revision 1.1.2.6 2007/08/16 23:03:19 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.1.2.5 2007/08/10 19:29:40 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.1.2.4 2007/06/07 20:01:52 mattl
+ * *** empty log message ***
+ *
+ * Revision 1.1.2.3 2007/06/06 15:58:29 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.1.2.2 2007/04/25 17:27:30 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.1.2.1 2006/12/14 22:24:43 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.22.2.4 2006/11/08 20:16:26 vonkorff
+ * Fixes an error message.
+ *
+ * Revision 1.22.2.3 2006/11/07 19:26:37 vonkorff
+ * Fixed lcgf
+ *
+ * Revision 1.22.2.2 2006/01/13 00:37:58 korpela
+ * Moved splitter to using standard BOINC logging mechanisms. All stderr now
+ * goes to "error.log"
+ *
+ * Added command line parameters "-iterations=" (number of workunit groups to
+ * create before exiting), "-trigger_file_path=" (path to the splitter_stop trigger
+ * file. Default is /disks/setifiler1/wutape/tapedir/splitter_stop).
+ *
+ * Reduced deadlines by a factor of three. We now need a 30 MFLOP machine to meet
+ * the deadline.
+ *
+ * Revision 1.22.2.1 2005/08/01 21:16:25 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.22 2005/01/27 23:03:27 mattl
+ *
+ * commented out tf=0 in check_for_halt
+ *
+ * Revision 1.21 2004/12/27 20:48:54 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.20 2004/08/12 15:45:41 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.19 2004/07/09 22:35:39 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.18 2004/06/27 21:07:04 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.17 2004/06/20 18:56:48 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.16 2004/06/18 23:23:32 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.15 2004/06/16 20:57:19 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.14 2004/04/08 22:25:47 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.13 2004/01/22 00:57:53 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.12 2004/01/01 18:42:01 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.11 2003/12/03 23:46:41 korpela
+ * WU count is now only for SAH workunits.
+ *
+ * Revision 1.10 2003/11/25 21:59:52 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.9 2003/11/01 20:54:02 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.8 2003/10/24 16:57:03 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.7 2003/09/26 20:48:51 jeffc
+ * jeffc - merge in branch setiathome-4_all_platforms_beta.
+ *
+ * Revision 1.5.2.2 2003/09/23 00:49:12 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.5.2.1 2003/09/22 17:39:34 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.6 2003/09/22 17:05:38 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.5 2003/09/13 20:48:38 korpela
+ * directory reorg. Moved client files to ./client
+ *
+ * Revision 1.4 2003/09/11 18:53:38 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.3 2003/08/13 23:18:47 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.2 2003/08/05 17:23:42 korpela
+ * More work on database stuff.
+ * Further tweaks.
+ *
+ * Revision 1.1 2003/07/29 20:35:50 korpela
+ *
+ * renames .C files to .cpp
+ *
+ * Revision 1.2 2003/06/03 01:01:17 korpela
+ *
+ * First working splitter under CVS.
+ *
+ * Revision 1.1 2003/06/03 00:23:40 korpela
+ *
+ * Again
+ *
+ * Revision 3.6 2003/05/21 00:41:42 korpela
+ * *** empty log message ***
+ *
+ * Revision 3.5 2003/05/19 17:40:59 eheien
+ * *** empty log message ***
+ *
+ * Revision 3.4 2003/04/09 17:46:54 korpela
+ * *** empty log message ***
+ *
+ * Revision 3.3 2002/06/20 22:09:17 eheien
+ * *** empty log message ***
+ *
+ * Revision 3.2 2001/11/07 00:51:47 korpela
+ * Added splitter version to database.
+ * Added max_wus_ondisk option.
+ *
+ * Revision 3.1 2001/08/16 23:42:08 korpela
+ * Mods for splitter to make binary workunits.
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.7 2000/12/01 01:13:29 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.6 1999/06/07 21:00:52 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.5 1999/03/27 16:19:35 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.4 1999/03/05 01:47:18 korpela
+ * Added dataclass paramter.
+ *
+ * Revision 2.3 1999/02/22 22:21:09 korpela
+ * added -nodb option
+ *
+ * Revision 2.2 1999/02/11 16:46:28 korpela
+ * Added some db access functions.
+ *
+ * Revision 2.1 1998/11/02 16:41:21 korpela
+ * Minor Change.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.2 1998/10/30 20:26:03 korpela
+ * Bug Fixes. Now mostly working.
+ *
+ * Revision 1.1 1998/10/27 00:58:16 korpela
+ * Initial revision
+ *
+ *
+ */
diff --git a/gbt_splitter/mb_splitter.h b/gbt_splitter/mb_splitter.h
new file mode 100644
index 0000000..6b52bc3
--- /dev/null
+++ b/gbt_splitter/mb_splitter.h
@@ -0,0 +1,145 @@
+/*
+ * splitter.h
+ *
+ * Global definitions from the splitter main program.
+ *
+ * $Id: mb_splitter.h,v 1.1.2.2 2007/04/25 17:20:28 korpela Exp $
+ *
+ */
+
+#ifndef SPLITTER_H
+#define SPLITTER_H
+
+#include "splitparms.h"
+#include "splittypes.h"
+
+#define MAX(x,y) ( ((x)<(y)) ? (y) : (x) )
+#define MIN(x,y) ( ((y)<(x)) ? (y) : (x) )
+
+/* wulog: File for logging names of completed wu files */
+/* errorlog: File for logging errors */
+#include "boinc_db.h"
+#include "crypt.h"
+#include "backend_lib.h"
+#include "sched_config.h"
+
+extern SCHED_CONFIG boinc_config;
+extern DB_APP app;
+extern R_RSA_PRIVATE_KEY key;
+extern FILE *wulog,*errorlog;
+extern std::vector<workunit> wuheaders;
+extern int noencode;
+extern int dataclass;
+extern char appname[256];
+extern int nodb;
+extern int resumetape;
+extern int startblock;
+extern int norewind;
+extern int output_xml;
+extern int polyphase;
+extern std::vector<long long> wu_database_id;
+extern int gregorian;
+extern char * projectdir;
+extern char trigger_file_name[1024];
+extern receiver_config rcvr;
+extern settings splitter_settings;
+
+
+/* Buffer that holds tape data */
+extern std::vector<dr2_compact_block_t> tapebuffer;
+extern std::map<seti_time,coordinate_t> coord_history;
+
+/* Number of records remaining in the buffer after WU creations is complete */
+extern int records_in_buffer;
+
+extern const char *wu_template;
+extern const char *result_template;
+// jeffc
+//extern const char *result_template_filename;
+extern char result_template_filename[];
+extern char result_template_filepath[];
+extern char wu_template_filename[];
+
+// exit values not defined elsewhere
+const int EXIT_NORMAL_EOF = 0;
+const int EXIT_NORMAL_NOT_EOF = 2;
+
+/* Persistant sequence number of wu file */
+extern int seqno;
+
+#endif
+
+/*
+ * $Log: mb_splitter.h,v $
+ * Revision 1.1.2.2 2007/04/25 17:20:28 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.1.2.1 2006/12/14 22:24:43 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.6.2.1 2006/01/13 00:37:58 korpela
+ * Moved splitter to using standard BOINC logging mechanisms. All stderr now
+ * goes to "error.log"
+ *
+ * Added command line parameters "-iterations=" (number of workunit groups to
+ * create before exiting), "-trigger_file_path=" (path to the splitter_stop trigger
+ * file. Default is /disks/setifiler1/wutape/tapedir/splitter_stop).
+ *
+ * Reduced deadlines by a factor of three. We now need a 30 MFLOP machine to meet
+ * the deadline.
+ *
+ * Revision 1.6 2004/07/09 22:35:39 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.5 2004/06/16 20:57:19 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.4 2003/09/26 20:48:52 jeffc
+ * jeffc - merge in branch setiathome-4_all_platforms_beta.
+ *
+ * Revision 1.2.2.1 2003/09/22 17:39:35 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.3 2003/09/22 17:05:38 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.2 2003/08/05 17:23:42 korpela
+ * More work on database stuff.
+ * Further tweaks.
+ *
+ * Revision 1.1 2003/06/03 00:23:40 korpela
+ *
+ * Again
+ *
+ * Revision 3.2 2003/05/19 17:40:59 eheien
+ * *** empty log message ***
+ *
+ * Revision 3.1 2001/08/16 23:42:08 korpela
+ * Mods for splitter to make binary workunits.
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.5 1999/10/20 19:20:26 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.4 1999/03/05 01:47:18 korpela
+ * Added data_class field.
+ *
+ * Revision 2.3 1999/02/22 22:21:09 korpela
+ * Added nodb option
+ *
+ * Revision 2.2 1999/02/11 16:46:28 korpela
+ * Added startblock and norewind support, and wu_database_id.
+ *
+ * Revision 2.1 1998/11/02 16:41:21 korpela
+ * Minor Change.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.1 1998/10/27 01:10:32 korpela
+ * Initial revision
+ *
+ *
+ */
diff --git a/gbt_splitter/mb_splittypes.h b/gbt_splitter/mb_splittypes.h
new file mode 100644
index 0000000..540fd74
--- /dev/null
+++ b/gbt_splitter/mb_splittypes.h
@@ -0,0 +1,114 @@
+/* splittypes.h
+ *
+ * Type definitions specific to the splitter.
+ *
+ *
+ * $Id: mb_splittypes.h,v 1.1.2.1 2006/12/14 22:24:44 korpela Exp $
+ *
+ */
+#ifndef SPLITTYPES_H
+#define SPLITTYPES_H
+
+#include <stdio.h>
+
+#include "splitparms.h"
+#include "s_util.h"
+#include "seti_header.h"
+
+//typedef struct wuheader {
+ //WU_INFO wuhead;
+ //SETI_WU_INFO wuinfo;
+//} wuheader_t;
+
+typedef struct tapeheader {
+ char name[36];
+ int rcdtype;
+ int numringbufs;
+ int numdiskbufs;
+ unsigned long frameseq;
+ unsigned long dataseq;
+ int missed;
+ TIME st;
+ SCOPE_STRING telstr;
+ int source;
+ double centerfreq,samplerate;
+ char version[16];
+} tapeheader_t;
+
+typedef struct buffer_pos {
+ int frame;
+ long offset;
+} buffer_pos_t;
+
+#endif
+/*
+ * $Log: mb_splittypes.h,v $
+ * Revision 1.1.2.1 2006/12/14 22:24:44 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.4 2003/08/05 17:23:43 korpela
+ * More work on database stuff.
+ * Further tweaks.
+ *
+ * Revision 1.3 2003/07/29 20:35:51 korpela
+ *
+ * renames .C files to .cpp
+ *
+ * Revision 1.2 2003/06/03 01:01:17 korpela
+ *
+ * First working splitter under CVS.
+ *
+ * Revision 1.1 2003/06/03 00:23:41 korpela
+ *
+ * Again
+ *
+ * Revision 3.1 2003/05/19 17:40:59 eheien
+ * *** empty log message ***
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.5 1999/02/11 16:46:28 korpela
+ * Added startblock and norewind support, and wu_database_id.
+ *
+ * Revision 2.4 1998/11/10 00:02:44 korpela
+ * Moved remaining wuheader fields into a WU_INFO structure.
+ *
+ * Revision 2.3 1998/11/05 21:18:41 korpela
+ * Moved name field from header to seti header.
+ *
+ * Revision 2.2 1998/11/02 21:20:58 korpela
+ * Moved tape_version and encoding_type into SETI_WU_INFO.
+ *
+ * Revision 2.1 1998/11/02 16:38:29 korpela
+ * Variable type changes.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.7 1998/10/30 21:01:13 davea
+ * *** empty log message ***
+ *
+ * Revision 1.6 1998/10/27 01:10:58 korpela
+ * Modified tapeheader_t to match new tape header fields.
+ *
+ * Revision 1.5 1998/10/19 23:04:32 korpela
+ * Moved times in telstr_t into an st_t.
+ * Changed name of ast_t to st_t.
+ * Added time zone (tz) field to ast_t.
+ *
+ * Revision 1.4 1998/10/15 19:13:30 korpela
+ * Renamed "unix" fields to "unix_time" because of GCC #define.
+ * Added position_history field to wuheader_t.
+ *
+ * Revision 1.3 1998/10/15 18:58:50 korpela
+ * Added time_t unix to ast_t and telstr_t types.
+ * Changed times in wuheader_t to time_t types.
+ *
+ * Revision 1.2 1998/10/15 18:01:19 korpela
+ * Removed month field from ast_t and telstr_t.
+ *
+ * Revision 1.1 1998/10/15 16:20:24 korpela
+ * Initial revision
+ *
+ */
diff --git a/gbt_splitter/mb_validrun.cpp b/gbt_splitter/mb_validrun.cpp
new file mode 100644
index 0000000..9bf7230
--- /dev/null
+++ b/gbt_splitter/mb_validrun.cpp
@@ -0,0 +1,147 @@
+/*
+ * validrun.c
+ *
+ * Functions for determining if a section of the tape buffer can be
+ * turned into a valid work unit
+ *
+ * $Id: mb_validrun.cpp,v 1.1.2.1 2006/12/14 22:24:45 korpela Exp $
+ *
+ */
+
+#include "sah_config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <assert.h>
+#include "setilib.h"
+#include "splitparms.h"
+#include "splittypes.h"
+#include "splitter.h"
+#include "message.h"
+
+
+bool valid_run(std::vector<dr2_compact_block_t> &tapebuffer, int min_vgc) {
+ unsigned long start_dataseq=tapebuffer[0].header.dataseq;
+ unsigned long end_dataseq=tapebuffer[tapebuffer.size()-1].header.dataseq;
+ bool valid=true;
+ int i;
+
+ // check for missing frames
+ if(!(end_dataseq-start_dataseq)==(tapebuffer.size()-1)) {
+ valid = false;
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Missing frames between %lu and %lu\n",
+ tapebuffer[0].header.dataseq,tapebuffer[tapebuffer.size()-1].header.dataseq);
+ for (i=tapebuffer.size()-1;i>0;i--) { // find the last "in sequence" frame
+ if (tapebuffer[i-1].header.dataseq != (tapebuffer[i].header.dataseq-1)) {
+ tapebuffer.erase(tapebuffer.begin(),tapebuffer.begin()+i); // delete all frames prior to the miss
+ }
+ }
+ }
+
+ // if still valid, check for failed blanking signal acquisition
+ if (valid) {
+ for (i=0;valid && (i<tapebuffer.size());i++) {
+ if (tapebuffer[i].header.blanking_failed) {
+ valid = false;
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Failed blanking at dataseq %lu (between %lu and %lu)\n",
+ tapebuffer[i].header.dataseq, tapebuffer[0].header.dataseq,tapebuffer[tapebuffer.size()-1].header.dataseq);
+ tapebuffer.erase(tapebuffer.begin(),tapebuffer.begin()+i+1); // delete all frames through the fail
+ }
+ }
+ }
+
+ // if still valid, check for changed frequency
+ if (valid) {
+ for (i=0;valid && (i<tapebuffer.size());i++) {
+ if (tapebuffer[i].header.sky_freq != tapebuffer[0].header.sky_freq) {
+ valid = false;
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Frequency changed from %f to %f at dataseq %lu (between %lu and %lu)\n",
+ tapebuffer[i].header.sky_freq,tapebuffer[0].header.sky_freq,
+ tapebuffer[i].header.dataseq, tapebuffer[0].header.dataseq,tapebuffer[tapebuffer.size()-1].header.dataseq);
+ tapebuffer.erase(tapebuffer.begin(),tapebuffer.begin()+i+1); // delete all frames through the change
+ }
+ }
+ }
+
+ // if still valid, check we are above minimum vgc values
+ if (valid && min_vgc > 0) {
+ for (i=0;valid && (i<tapebuffer.size());i++) {
+ if (get_vgc_for_channel(tapebuffer[i].header.channel,tapebuffer[i].header) < min_vgc) {
+ valid = false;
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"VGC value %d is below minimum (%d) at dataseq %lu\n",
+ get_vgc_for_channel(tapebuffer[i].header.channel,tapebuffer[i].header), min_vgc, tapebuffer[i].header.dataseq);
+ // tapebuffer.erase(tapebuffer.begin(),tapebuffer.begin()+i+1); // delete all frames through the change
+ tapebuffer.erase(tapebuffer.begin(),tapebuffer.end()-1); // delete all frames in entire tapebuffer (except last)!
+ }
+ }
+ }
+
+ return(valid);
+}
+
+
+/*
+ * $Log: mb_validrun.cpp,v $
+ * Revision 1.1.2.1 2006/12/14 22:24:45 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.2.4.1 2006/01/13 00:37:58 korpela
+ * Moved splitter to using standard BOINC logging mechanisms. All stderr now
+ * goes to "error.log"
+ *
+ * Added command line parameters "-iterations=" (number of workunit groups to
+ * create before exiting), "-trigger_file_path=" (path to the splitter_stop trigger
+ * file. Default is /disks/setifiler1/wutape/tapedir/splitter_stop).
+ *
+ * Reduced deadlines by a factor of three. We now need a 30 MFLOP machine to meet
+ * the deadline.
+ *
+ * Revision 1.2 2003/09/11 18:53:38 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.1 2003/07/29 20:35:57 korpela
+ *
+ * renames .C files to .cpp
+ *
+ * Revision 1.1 2003/06/03 00:23:43 korpela
+ *
+ * Again
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.7 2000/12/01 01:13:29 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.6 1999/06/07 21:00:52 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.5 1999/03/27 16:19:35 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.4 1999/02/22 22:21:09 korpela
+ * added -nodb option
+ *
+ * Revision 2.3 1999/02/11 16:46:28 korpela
+ * Added checkpointing.
+ *
+ * Revision 2.2 1998/11/04 23:08:25 korpela
+ * Byte and bit order change.
+ *
+ * Revision 2.1 1998/11/02 16:41:21 korpela
+ * Minor Change.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.3 1998/10/30 20:26:03 korpela
+ * Bug Fixes. Now mostly working.
+ *
+ * Revision 1.2 1998/10/27 00:59:22 korpela
+ * Bug fixes.
+ *
+ * Revision 1.1 1998/10/22 17:48:20 korpela
+ * Initial revision
+ *
+ *
+ */
diff --git a/gbt_splitter/mb_validrun.h b/gbt_splitter/mb_validrun.h
new file mode 100644
index 0000000..1f6482d
--- /dev/null
+++ b/gbt_splitter/mb_validrun.h
@@ -0,0 +1,35 @@
+/*
+ * validrun.h
+ *
+ * Functions for determining if a section of the tape buffer can be
+ * turned into a valid work unit
+ *
+ * $Id: mb_validrun.h,v 1.1.2.1 2006/12/14 22:24:45 korpela Exp $
+ *
+ */
+
+int valid_run(std::vector<dr2_compact_block_t> &tapebuffer, int min_vgc);
+
+/*
+ * $Log: mb_validrun.h,v $
+ * Revision 1.1.2.1 2006/12/14 22:24:45 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.1 2003/06/03 00:23:43 korpela
+ *
+ * Again
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.1 1998/11/02 16:41:21 korpela
+ * Minor Change.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.1 1998/10/22 17:49:15 korpela
+ * Initial revision
+ *
+ *
+ */
diff --git a/gbt_splitter/mb_wufiles.cpp b/gbt_splitter/mb_wufiles.cpp
new file mode 100644
index 0000000..7247eb5
--- /dev/null
+++ b/gbt_splitter/mb_wufiles.cpp
@@ -0,0 +1,689 @@
+/*
+ *
+ * Functions for managing wufiles and their data
+ *
+ * $Id: mb_wufiles.cpp,v 1.1.2.6 2007/08/10 18:21:13 korpela Exp $
+ *
+ */
+
+#include "sah_config.h"
+#undef USE_MYSQL
+#include <cstdio>
+#include <cstdlib>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <limits.h>
+#include <iostream>
+#include <string>
+#include <algorithm>
+#include <vector>
+#include <map>
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include "boinc_db.h"
+#include "sched_util.h"
+#include "setilib.h"
+#include "splitparms.h"
+#include "splittypes.h"
+#include "s_util.h"
+#include "util.h"
+#include "str_util.h"
+#include "str_replace.h"
+#include "mb_splitter.h"
+#include "message.h"
+#include "mb_angdist.h"
+#include "cmap_interp.h"
+#include "lcgamm.h"
+#include "sqlrow.h"
+#include "sqlblob.h"
+#include "sqlapi.h"
+#include "db_table.h"
+#include "schema_master.h"
+#include "xml_util.h"
+#include "db/app_config.h"
+#include "str_util.h"
+
+std::vector<long long> wu_database_id;
+std::vector<std::vector<unsigned char> > bin_data;
+
+extern APP_CONFIG sah_config;
+
+int make_wu_headers(std::vector<dr2_compact_block_t> &tapebuffer, telescope_id
+tel, std::vector<workunit> &wuheader) {
+ int procid=getpid();
+ double receiver_freq;
+ int bandno;
+ FILE *tmpfile;
+ char tmpstr[256];
+ char buf[64];
+ static const receiver_config &r(rcvr);
+ static const settings &s(splitter_settings);
+ bool group_is_vlar;
+
+ if (!strncmp(s.splitter_cfg->data_type,"encoded",
+ std::min(static_cast<size_t>(7),sizeof(s.splitter_cfg->data_type)))) {
+ noencode=0;
+ } else {
+ noencode=1;
+ }
+
+ tapebuffer[0].header.samplerate*=1e+6;
+ seconds sample_time(1.0/tapebuffer[0].header.samplerate);
+ seti_time start_time(tapebuffer[0].header.data_time
+ -tapebuffer[0].data.size()*0.5*sample_time);
+ seti_time end_time(tapebuffer[tapebuffer.size()-1].header.data_time);
+
+
+ workunit_grp wugrp;
+ sprintf(wugrp.name,"%s.%ld.%d.%d.%d",
+ tapebuffer[0].header.name,
+ procid,
+ tapebuffer[0].header.dataseq,
+ tel-AO_430,
+ s.id);
+ wugrp.receiver_cfg=r;
+ wugrp.recorder_cfg=s.recorder_cfg;
+ wugrp.splitter_cfg=s.splitter_cfg;
+ wugrp.analysis_cfg=s.analysis_cfg;
+
+ wugrp.data_desc.nsamples=NSAMPLES;
+ wugrp.data_desc.true_angle_range=0;
+ coordinate_t start_coord(cmap_interp(coord_history,start_time));
+ coordinate_t end_coord(cmap_interp(coord_history,end_time));
+ wugrp.data_desc.start_ra=start_coord.ra;
+ wugrp.data_desc.end_ra=end_coord.ra;
+ wugrp.data_desc.start_dec=start_coord.dec;
+ wugrp.data_desc.end_dec=end_coord.dec;
+ coordinate_t last_coord=start_coord;
+ double sample_rate=tapebuffer[0].header.samplerate/NSTRIPS;
+
+ // find the bracketing entries in the coordinate history
+ std::map<seti_time,coordinate_t>::iterator above(coord_history.upper_bound(end_time));
+ std::map<seti_time,coordinate_t>::iterator below(coord_history.lower_bound(start_time));
+ std::map<seti_time,coordinate_t>::iterator p;
+ if (above==coord_history.begin()) {
+ above++;
+ }
+ if (below==coord_history.end()) {
+ below=above;
+ below--;
+ }
+ if (above==below) {
+ below--;
+ }
+ // Calculate the angular distance the beam has traveled
+ for (p=below;p!=above;p++)
+ {
+ wugrp.data_desc.true_angle_range+=angdist(last_coord,p->second);
+ last_coord=p->second;
+ }
+ wugrp.data_desc.true_angle_range+=angdist(last_coord,end_coord);
+ if (wugrp.data_desc.true_angle_range==0) wugrp.data_desc.true_angle_range=1e-10;
+ // Calculate the number of unique signals that could be found in a workunit.
+ // We will use these numbers to calculate thresholds.
+ double numgauss=2.36368e+08/std::min(wugrp.data_desc.true_angle_range,10.0);
+ double numpulse=std::min(4.52067e+10/std::min(wugrp.data_desc.true_angle_range,10.0),2.00382e+11);
+ 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 < 0.12) {
+ group_is_vlar=true;
+ } else {
+ group_is_vlar=false;
+ }
+
+
+ // if (useanalysiscfgid > 0) {
+ // log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Re-reading analysis cfg id: %d (set by user):\n",useanalysiscfgid);
+ // s.analysis_cfg = useanalysiscfgid;
+ // }
+
+ // Calculate a unique key to describe this analysis config.
+ long keyuniq=floor(std::min(wugrp.data_desc.true_angle_range*100,1000.0)+0.5)+
+ s.analysis_cfg.id*1024;
+ if ((keyuniq>((s.analysis_cfg.id+1)*1024)) ||(keyuniq<(s.analysis_cfg.id)*1024)) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Invalid keyuniq value!\n");
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"%d %d %f\n",keyuniq,s.analysis_cfg.id,wugrp.data_desc.true_angle_range);
+ exit(1);
+ }
+
+ keyuniq*=-1;
+ long save_keyuniq=keyuniq;
+ splitter_settings.analysis_cfg=wugrp.analysis_cfg;
+ sprintf(tmpstr,"where keyuniq=%d",keyuniq);
+ // Check if we've already done this analysis_config...
+ // Fetch through splitter_settings, since it's alias (s) is const.
+ splitter_settings.analysis_cfg.id=0;
+ splitter_settings.analysis_cfg->fetch(tmpstr);
+
+ if (s.analysis_cfg->id==0) {
+ if (keyuniq != save_keyuniq) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"keyuniq value changed!\n");
+ exit(1);
+ }
+
+ // If not calculate the thresholds based upon the input analysis_config
+ // Triplets are distributed exponentially...
+ wugrp.analysis_cfg->triplet_thresh+=(log(numtrip)-29.0652);
+
+ // Gaussians are based upon chisqr...
+ double p_gauss=lcgf(32.0,wugrp.analysis_cfg->gauss_null_chi_sq_thresh*32.0);
+ p_gauss-=(log(numgauss)-19.5358);
+ wugrp.analysis_cfg->gauss_null_chi_sq_thresh=invert_lcgf(p_gauss,32,1e-4)*0.03125;
+
+ // Pulses thresholds are log of the probability
+ wugrp.analysis_cfg->pulse_thresh+=(log(numpulse)-24.7894);
+
+ wugrp.analysis_cfg->keyuniq=keyuniq;
+ wugrp.analysis_cfg->insert();
+ } else {
+ wugrp.analysis_cfg=s.analysis_cfg;
+ }
+
+ strlcpy(wugrp.data_desc.time_recorded,
+ short_jd_string(start_time.jd().uval()),
+ sizeof(wugrp.data_desc.time_recorded));
+ wugrp.data_desc.time_recorded_jd=start_time.jd().uval();
+ wugrp.data_desc.coords.clear();
+
+ wugrp.data_desc.coords.push_back(start_coord);
+ for (p=below;p!=above;p++)
+ {
+ wugrp.data_desc.coords.push_back(p->second);
+ }
+ wugrp.data_desc.coords.push_back(end_coord);
+
+ // indicate the state of the alfa filter bank
+ wugrp.alfa_filter_bank = tapebuffer[0].header.scram_if1.alfaFb ? 1 : 0;
+
+ wugrp.tape_info->id=0;
+ sprintf(buf,"%d",tel-AO_ALFA_0_0);
+ wugrp.tape_info->fetch(std::string("where name=\'")+tapebuffer[0].header.name+"\' and beam="+buf);
+ wugrp.tape_info->start_time=tapebuffer[0].header.data_time.jd().uval();
+ wugrp.tape_info->last_block_time=wugrp.tape_info->start_time;
+ wugrp.tape_info->last_block_done=tapebuffer[0].header.dataseq;
+ wugrp.tape_info->beam=tel-AO_ALFA_0_0;
+
+ if (!nodb) {
+ if (wugrp.tape_info.id) {
+ if (!(wugrp.tape_info->update())) {
+ char buf[1024];
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"%s",sql_error_message());
+ exit(1);
+ }
+ } else {
+ strlcpy(wugrp.tape_info->name,tapebuffer[0].header.name,sizeof(wugrp.tape_info->name));
+ wugrp.tape_info->insert();
+ }
+ }
+
+ if (!nodb) {
+ sqlint8_t wgid;
+ if ((wgid=wugrp.insert())<=0) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Workunit_grp insert failed\nwgid=%d\nSQLCODE=%d\nLAST_NON_ZERO_SQLCODE=%d\n",wgid,sql_error_code(),sql_last_error_code());
+ exit( 1 );
+ }
+ wugrp.id=wgid;
+ }
+ int i;
+ wu_database_id.resize(NSTRIPS);
+ bin_data.resize(NSTRIPS);
+ wuheader.resize(NSTRIPS);
+ for (i=0;i<NSTRIPS;i++) {
+ bin_data[i].clear();
+ wuheader[i].group_info=wugrp;
+ wuheader[i].group_info.id=wugrp.id;
+ sprintf(wuheader[i].name,"%s.%ld.%d.%ld.%d.%d",tapebuffer[0].header.name,
+ procid, tapebuffer[0].header.dataseq,
+ tel-AO_430,s.id,i);
+ if (group_is_vlar) {
+ strlcat(wuheader[i].name,".vlar",sizeof(wuheader[i].name));
+ }
+ wuheader[i].subband_desc.sample_rate=tapebuffer[0].header.samplerate/NSTRIPS;
+
+ receiver_freq=tapebuffer[0].header.sky_freq;
+
+ bandno=((i+NSTRIPS/2)%NSTRIPS)-NSTRIPS/2;
+
+ wuheader[i].subband_desc.base=receiver_freq+
+ (double)(bandno)*wuheader[i].subband_desc.sample_rate;
+ // for FFT based splitter:
+ //wuheader[i].subband_desc.center=receiver_freq+wuheader[i].subband_desc.sample_rate*NSTRIPS*((double)IFFT_LEN*bandno/FFT_LEN+(double)IFFT_LEN/(2*FFT_LEN)-1.0/(2*FFT_LEN));
+
+ // for PFB splitter:
+ //wuheader[i].subband_desc.center=receiver_freq+wuheader[i].subband_desc.sample_rate*NSTRIPS;
+ wuheader[i].subband_desc.center=wuheader[i].subband_desc.base;
+ wuheader[i].subband_desc.number=i;
+
+ if (!nodb ) {
+ if (!(wu_database_id[i]=wuheader[i].id=wuheader[i].insert())) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Database error in make_wu_headers()\n");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ sprintf(tmpstr,"./wu_inbox/%s",wuheader[i].name);
+ if ((tmpfile=fopen(tmpstr,"w"))) {
+ fprintf(tmpfile,"<workunit>\n");
+ fprintf(tmpfile,wuheader[i].print_xml().c_str());
+ fclose(tmpfile);
+ } else {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Unable to open file ./wu_inbox/%s, errno=%d\n",wuheader[i].name,errno);
+ exit(1);
+ }
+ bin_data[i].reserve(wuheaders[i].group_info->recorder_cfg->bits_per_sample*
+ wuheaders[i].group_info->data_desc.nsamples/8);
+ }
+ return(1);
+}
+
+
+void write_wufile_blocks(int nbytes) {
+ // doesn't do anything anymore. What was done here is done in output_samples.
+}
+
+int filecopy(char *oldname,char *newname) {
+ FILE *oldfile,*newfile;
+ char buffer[16384];
+ int nread;
+ if ((oldfile=fopen(oldname,"rb")) && (newfile=fopen(newname,"wb"))) {
+ do {
+ nread=fread(buffer,1,16384,oldfile);
+ fwrite(buffer,1,nread,newfile);
+ } while (nread>0);
+ fclose(oldfile);
+ fclose(newfile);
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+
+
+void rename_wu_files() {
+ int i, retval;
+ char oldname[256],newname[1024];
+ unsigned long sz;
+ DB_WORKUNIT db_wu;
+ const char *name[1];
+ char *wudir="./wu_inbox";
+ xml_encoding encoding=(noencode?_binary:_x_setiathome);
+ FILE *tmpfile;
+
+ if (boinc_db.open(boinc_config.db_name,boinc_config.db_host,boinc_config.db_user,boinc_config.db_passwd)) {
+ boinc_db.print_error("boinc_db.open");
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Fatal error in boinc_db.open\n");
+ exit(1);
+ }
+
+ for (i=0;i<NSTRIPS;i++) {
+ name[0]=wuheaders[i].name;
+ sprintf(oldname,"%s/%s",wudir,name[0]);
+
+ //sprintf(newname,"%s%s/%s",projectdir,WU_SUBDIR,name[0]);
+ retval = dir_hier_path(name[0],
+ boinc_config.download_dir,
+ boinc_config.uldl_dir_fanout,
+ newname,
+ true
+ );
+ if (retval) {
+ char buf[1024];
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"[%s] dir_hier_path() failed: %d\n", name[0], retval);
+ exit(1);
+ }
+
+ struct stat sbuf;
+ if (!stat(oldname,&sbuf) && (tmpfile=fopen(oldname,"a"))) {
+ std::string tmpstr=xml_encode_string(bin_data[i],encoding);
+ fprintf(tmpfile,"<data length=%ld encoding=\"%s\">",tmpstr.size(),
+ xml_encoding_names[encoding]);
+ fwrite(tmpstr.c_str(),tmpstr.size(),1,tmpfile);
+ fprintf(tmpfile,"</data>\n");
+ fprintf(tmpfile,"</workunit>\n");
+ sz=bin_data[i].size();
+
+ fclose(tmpfile);
+ } else {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Header file no longer exists! splitter start script may be failing\n ");
+ exit(1);
+ }
+ if (!nodb) {
+ if (!filecopy(oldname,newname)) {
+ db_wu.clear();
+ db_wu.opaque=wuheaders[i].id;
+ strncpy(db_wu.name,name[0],sizeof(db_wu.name)-2);
+ db_wu.appid=app.id;
+ //db_wu.rsc_fpops_est=2.79248e+13*6;
+ //db_wu.rsc_fpops_bound=4.46797e+14*6;
+ double beam=wuheaders[i].group_info->receiver_cfg->beam_width;
+ double ar=wuheaders[i].group_info->data_desc.true_angle_range;
+ double dur=(double)(wuheaders[i].group_info->data_desc.nsamples)/wuheaders[i].subband_desc.sample_rate;
+ double min_slew=wuheaders[i].group_info->analysis_cfg->pot_min_slew;
+ double max_slew=wuheaders[i].group_info->analysis_cfg->pot_max_slew;
+ double autocorr_len=wuheaders[i].group_info->analysis_cfg->autocorr_fftlen;
+ double autocorr_flops=0;
+ if (autocorr_len) autocorr_flops=7.5e+06*autocorr_len*log(autocorr_len);
+ if ( ar <= beam ) {
+ db_wu.rsc_fpops_est=8.036e+13+autocorr_flops;
+ } else if ( ar <= ( dur*min_slew ) ) {
+ db_wu.rsc_fpops_est=4.805e+13+autocorr_flops+2.296e+12/ar;
+ } else if ( ar <= ( dur*max_slew ) ) {
+ db_wu.rsc_fpops_est=4.592e+13+autocorr_flops+1.476e+13/ar;
+ } else {
+ db_wu.rsc_fpops_est=2.378e+13+autocorr_flops;
+ }
+ db_wu.rsc_fpops_est*=(0.333/wuheaders[i].group_info->analysis_cfg->chirp_resolution);
+ db_wu.rsc_fpops_bound=db_wu.rsc_fpops_est*20;
+ db_wu.rsc_memory_bound=33554432;
+ db_wu.rsc_disk_bound=33554432;
+ // Our minimum is a 40 MFLOP machine
+ db_wu.delay_bound=std::max(86400.0*7,db_wu.rsc_fpops_est/4e+7);
+ db_wu.min_quorum=sah_config.min_quorum;
+ db_wu.target_nresults=sah_config.target_nresults;
+ db_wu.max_error_results=sah_config.max_error_results;
+ db_wu.max_total_results=sah_config.max_total_results;
+ db_wu.max_success_results=sah_config.max_success_results;
+ strncpy(db_wu.app_name,appname,sizeof(db_wu.app_name)-2);
+ if (create_work(db_wu,
+ wu_template,
+ result_template_filename,
+ result_template_filepath,
+ name,
+ 1,
+ boinc_config,
+ NULL
+ )
+ ) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"create work failed\n");
+ exit(1);
+ }
+ //unlink(oldname); // we now *always* unlink
+ } else {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"file copy failed\n");
+ exit(1);
+ }
+ unlink(oldname);
+ }
+ }
+ boinc_db.close();
+}
+
+/*
+ * $Log: mb_wufiles.cpp,v $
+ * Revision 1.1.2.6 2007/08/10 18:21:13 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.1.2.5 2007/08/09 21:31:08 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.1.2.4 2007/06/07 20:01:52 mattl
+ * *** empty log message ***
+ *
+ * Revision 1.1.2.3 2007/06/06 15:58:30 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.1.2.2 2007/04/25 17:27:31 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.1.2.1 2006/12/14 22:24:45 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.29.2.14 2006/05/03 19:14:31 korpela
+ * Updated work estimates.
+ *
+ * Revision 1.29.2.13 2006/04/24 18:41:02 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.29.2.12 2006/01/13 00:37:58 korpela
+ * Moved splitter to using standard BOINC logging mechanisms. All stderr now
+ * goes to "error.log"
+ *
+ * Added command line parameters "-iterations=" (number of workunit groups to
+ * create before exiting), "-trigger_file_path=" (path to the splitter_stop trigger
+ * file. Default is /disks/setifiler1/wutape/tapedir/splitter_stop).
+ *
+ * Reduced deadlines by a factor of three. We now need a 30 MFLOP machine to meet
+ * the deadline.
+ *
+ * Revision 1.29.2.11 2006/01/10 00:39:04 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.29.2.10 2006/01/05 23:55:22 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.29.2.9 2005/12/05 22:11:40 korpela
+ * Fixed bug in flops estimate.
+ *
+ * Revision 1.29.2.8 2005/10/05 16:22:17 jeffc
+ * removed reference to old/new boolean for directory hash.
+ *
+ * Revision 1.29.2.7 2005/09/22 23:05:22 korpela
+ * Fixed threshold calculation. Was using chisqr rather than reduced chisqr.
+ *
+ * Revision 1.29.2.6 2005/09/21 22:11:23 korpela
+ * Updated Makefile.in for OpenSSL.
+ * Added dynamic threshold generation to wufiles.cpp.
+ *
+ * Revision 1.29.2.5 2005/08/01 17:47:38 korpela
+ * Type fixed.
+ *
+ * Revision 1.29.2.4 2005/08/01 17:43:20 korpela
+ * Refinement of FLOPS estimate for workunits.
+ *
+ * Revision 1.29.2.3 2005/07/26 17:17:01 korpela
+ * Typo fix
+ *
+ * Revision 1.29.2.2 2005/07/19 00:15:19 korpela
+ * Revised delay bound and FLOP estimate for setiathome_enhanced.
+ *
+ * Revision 1.29.2.1 2005/07/06 01:30:17 korpela
+ * Updated estimates of FPOPS per workunit for setiathome enhanced.
+ *
+ * Revision 1.29 2005/03/08 22:36:15 jeffc
+ * jeffc - fixed call to create_work()
+ *
+ * Revision 1.28 2005/02/15 23:06:47 korpela
+ * Fixed missing dir_hier symbol.
+ *
+ * Revision 1.27 2004/12/27 20:48:54 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.26 2004/11/18 22:24:48 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.25 2004/08/25 22:42:11 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.24 2004/08/14 04:44:26 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.23 2004/08/12 15:45:41 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.22 2004/07/15 17:54:20 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.21 2004/07/09 22:35:39 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.20 2004/07/01 17:56:51 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.19 2004/06/25 13:49:33 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.18 2004/06/18 23:23:32 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.17 2004/06/16 20:57:19 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.16 2004/06/02 20:51:32 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.15 2004/01/22 00:57:54 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.14 2004/01/20 22:33:44 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.13 2004/01/06 22:44:05 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.12 2004/01/01 18:42:01 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.11 2003/12/12 01:51:39 korpela
+ * Now using the opaque field in workunit to store SAH wuid.
+ *
+ * Revision 1.10 2003/12/03 23:46:41 korpela
+ * WU count is now only for SAH workunits.
+ *
+ * Revision 1.9 2003/11/25 21:59:53 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.8 2003/11/11 06:20:30 korpela
+ * Increased max fpops_max to prevent timeout on windows clients
+ *
+ * Revision 1.7 2003/10/25 18:19:44 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.6 2003/10/24 16:57:03 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.5 2003/09/26 20:48:52 jeffc
+ * jeffc - merge in branch setiathome-4_all_platforms_beta.
+ *
+ * Revision 1.3.2.2 2003/09/22 19:00:31 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.3.2.1 2003/09/22 17:39:35 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.4 2003/09/22 17:05:38 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.3 2003/09/11 18:53:38 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.2 2003/08/05 17:23:44 korpela
+ * More work on database stuff.
+ * Further tweaks.
+ *
+ * Revision 1.1 2003/07/29 20:36:00 korpela
+ *
+ * renames .C files to .cpp
+ *
+ * Revision 1.3 2003/06/05 15:52:47 korpela
+ *
+ * Fixed coordinate bug that was using the wrong zenith angle from the telescope
+ * strings when handling units from the gregorian.
+ *
+ * Revision 1.2 2003/06/03 01:01:18 korpela
+ *
+ * First working splitter under CVS.
+ *
+ * Revision 1.1 2003/06/03 00:23:44 korpela
+ *
+ * Again
+ *
+ * Revision 3.8 2003/05/19 17:40:59 eheien
+ * *** empty log message ***
+ *
+ * Revision 3.7 2003/04/10 17:32:25 korpela
+ * *** empty log message ***
+ *
+ * Revision 3.6 2002/06/21 01:42:15 eheien
+ * *** empty log message ***
+ *
+ * Revision 3.5 2001/11/07 00:51:47 korpela
+ * Added splitter version to database.
+ * Added max_wus_ondisk option.
+ *
+ * Revision 3.4 2001/08/17 22:20:54 korpela
+ * *** empty log message ***
+ *
+ * Revision 3.3 2001/08/17 01:22:31 korpela
+ * *** empty log message ***
+ *
+ * Revision 3.2 2001/08/17 01:16:53 korpela
+ * *** empty log message ***
+ *
+ * Revision 3.1 2001/08/16 23:42:08 korpela
+ * Mods for splitter to make binary workunits.
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.18 2000/12/01 01:13:29 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.17 1999/06/07 21:00:52 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.16 1999/03/27 16:19:35 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.15 1999/03/05 01:47:18 korpela
+ * Added data_class field.
+ *
+ * Revision 2.14 1999/02/22 22:21:09 korpela
+ * added -nodb option
+ *
+ * Revision 2.13 1999/02/11 16:46:28 korpela
+ * Added db access functions.
+ *
+ * Revision 2.12 1999/01/04 22:27:55 korpela
+ * Updated return codes.
+ *
+ * Revision 2.11 1998/12/14 23:41:44 korpela
+ * Added subband_base to work unit header.
+ * Changed frequency calculation.
+ *
+ * Revision 2.10 1998/12/14 21:55:07 korpela
+ * Added fft_len and ifft_len to work unit header.
+ *
+ * Revision 2.9 1998/11/13 23:58:52 korpela
+ * Modified for move of name field between structures.
+ *
+ * Revision 2.8 1998/11/13 22:18:12 davea
+ * *** empty log message ***
+ *
+ * Revision 2.7 1998/11/10 01:55:26 korpela
+ * Server requires a CR at the end of a WU file
+ * ???
+ *
+ * Revision 2.6 1998/11/10 00:02:44 korpela
+ * Moved remaining wuheader fields into a WU_INFO structure.
+ *
+ * Revision 2.5 1998/11/05 21:33:02 korpela
+ * Fixed angle_range bug.
+ *
+ * Revision 2.4 1998/11/05 21:18:41 korpela
+ * Moved name field from header to seti header.
+ *
+ * Revision 2.3 1998/11/02 21:20:58 korpela
+ * Modified for (internal) integer receiver ID.
+ *
+ * Revision 2.2 1998/11/02 18:45:39 korpela
+ * Changed location of timecvt.h
+ *
+ * Revision 2.1 1998/11/02 16:38:29 korpela
+ * Variable type changes.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.2 1998/10/30 20:26:03 korpela
+ * Bug Fixes. Now mostly working.
+ *
+ * Revision 1.1 1998/10/27 01:01:16 korpela
+ * Initial revision
+ *
+ *
+ */
diff --git a/gbt_splitter/mb_wufiles.h b/gbt_splitter/mb_wufiles.h
new file mode 100644
index 0000000..5fb95e2
--- /dev/null
+++ b/gbt_splitter/mb_wufiles.h
@@ -0,0 +1,46 @@
+/*
+ *
+ * Functions for managing wufiles and their data
+ *
+ * $Id: mb_wufiles.h,v 1.1.2.2 2007/04/25 17:20:28 korpela Exp $
+ *
+ */
+
+
+extern std::vector<std::vector<unsigned char> > bin_data;
+
+int make_wu_headers(std::vector<dr2_compact_block_t> &tapebuffer, telescope_id tel,
+ std::vector<workunit> &wuheader) ;
+void write_wufile_blocks(int nbytes) ;
+void rename_wu_files();
+
+/*
+ * $Log: mb_wufiles.h,v $
+ * Revision 1.1.2.2 2007/04/25 17:20:28 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.1.2.1 2006/12/14 22:24:46 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.2 2003/08/05 17:23:45 korpela
+ * More work on database stuff.
+ * Further tweaks.
+ *
+ * Revision 1.1 2003/06/03 00:23:44 korpela
+ *
+ * Again
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.1 1998/11/02 16:41:21 korpela
+ * Minor Change.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.1 1998/10/27 01:13:16 korpela
+ * Initial revision
+ *
+ *
+ */
diff --git a/gbt_splitter/message.cpp b/gbt_splitter/message.cpp
new file mode 100644
index 0000000..d15181e
--- /dev/null
+++ b/gbt_splitter/message.cpp
@@ -0,0 +1,65 @@
+/*
+ * Functions for sending messages to stderr and log files.
+ *
+ * $Id: message.cpp,v 1.2.4.2 2006/12/14 22:24:46 korpela Exp $
+ */
+
+#include "sah_config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "boinc_db.h"
+#include "sched_config.h"
+#include "sched_msgs.h"
+#include "splitter.h"
+
+void message(char *msg) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"%s %s",tapeheaders[0].name,msg);
+}
+
+
+
+/*
+ * $Log: message.cpp,v $
+ * Revision 1.2.4.2 2006/12/14 22:24:46 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.2.4.1 2006/01/13 00:37:57 korpela
+ * Moved splitter to using standard BOINC logging mechanisms. All stderr now
+ * goes to "error.log"
+ *
+ * Added command line parameters "-iterations=" (number of workunit groups to
+ * create before exiting), "-trigger_file_path=" (path to the splitter_stop trigger
+ * file. Default is /disks/setifiler1/wutape/tapedir/splitter_stop).
+ *
+ * Reduced deadlines by a factor of three. We now need a 30 MFLOP machine to meet
+ * the deadline.
+ *
+ * Revision 1.2 2003/09/11 18:53:38 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.1 2003/07/29 20:35:43 korpela
+ *
+ * renames .C files to .cpp
+ *
+ * Revision 1.1 2003/06/03 00:16:14 korpela
+ *
+ * Initial splitter under CVS control.
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.2 2000/12/01 01:13:29 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.1 1998/11/02 16:41:21 korpela
+ * Minor Change.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.1 1998/10/27 00:56:16 korpela
+ * Initial revision
+ *
+ */
diff --git a/gbt_splitter/message.h b/gbt_splitter/message.h
new file mode 100644
index 0000000..6c51713
--- /dev/null
+++ b/gbt_splitter/message.h
@@ -0,0 +1,40 @@
+/*
+ * Functions for sending messages to stderr and log files.
+ *
+ * $Id: message.h,v 1.1.4.1 2006/01/13 00:37:57 korpela Exp $
+ */
+
+#include "sched_msgs.h"
+
+void message(char *msg);
+
+/*
+ * $Log: message.h,v $
+ * Revision 1.1.4.1 2006/01/13 00:37:57 korpela
+ * Moved splitter to using standard BOINC logging mechanisms. All stderr now
+ * goes to "error.log"
+ *
+ * Added command line parameters "-iterations=" (number of workunit groups to
+ * create before exiting), "-trigger_file_path=" (path to the splitter_stop trigger
+ * file. Default is /disks/setifiler1/wutape/tapedir/splitter_stop).
+ *
+ * Reduced deadlines by a factor of three. We now need a 30 MFLOP machine to meet
+ * the deadline.
+ *
+ * Revision 1.1 2003/06/03 00:16:14 korpela
+ *
+ * Initial splitter under CVS control.
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.1 1998/11/02 16:41:21 korpela
+ * Minor Change.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.1 1998/10/27 01:09:00 korpela
+ * Initial revision
+ *
+ */
diff --git a/gbt_splitter/polyphase.cpp b/gbt_splitter/polyphase.cpp
new file mode 100644
index 0000000..57cbdd8
--- /dev/null
+++ b/gbt_splitter/polyphase.cpp
@@ -0,0 +1,149 @@
+
+#include "sah_config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <unistd.h>
+#include <limits.h>
+#include <assert.h>
+#include <math.h>
+
+#include "splitparms.h"
+#include "splittypes.h"
+#include "splitter.h"
+#include "fftw.h"
+#include "wufiles.h"
+#include "polyphase.h"
+#include "dotransform.h"
+
+/* buffer for fft input/output */
+//float databuf[FFT_LEN*2];
+
+/* buffer for ftt output before data writes, needs to be multiple
+ * of three bytes long for encode to work.
+ */
+#define SAMPLES_PER_OBUF (FFT_LEN*2*3/CHAR_BIT)
+
+extern unsigned char output_buf[NSTRIPS][SAMPLES_PER_OBUF];
+
+double *filter_r, *filter_i;
+float *f_data;
+
+extern int obuf_pos; /* Tracks current postition in the output buffers */
+
+void make_FIR (int n_points, int M, int window, double *output) {
+ /* Create Mth band lowpass FIR filter, n_points long. */
+
+ /* Modify this to give 8-bit quantized filter. */
+ /* Also generate Hilbert transformed filter */
+
+ int n;
+ double q, p;
+
+ for (n=0; n<n_points; n++) {
+ if (n == n_points/2) {
+ output[n] = 1;
+ } else {
+ q = n-(n_points/2);
+ p = n_points/M;
+ output[n] = sin(M_PI*q/p)/(M_PI*q/p);
+ }
+ }
+ if (window == HANNING) {
+ for (n=0; n<n_points; n++) {
+ output[n] = output[n]*.5*(1 - cos(2*M_PI*n/(n_points-1)));
+ }
+ }
+ else if (window == WELCH) {
+ for (n=0; n<n_points; n++) {
+ output[n] = output[n]*(1 - ((n-.5*(n_points-1))/(.5*(n_points+1)))*((n-.5*(n_points-1))/(.5*(n_points+1))));
+ }
+ }
+}
+
+
+void polyphase_seg(float* data) {
+ int i,n;
+ static fftw_plan planfwd;
+ float *p;
+
+ if (!planfwd) {
+ planfwd=fftw_create_plan(P_FFT_LEN, FFTW_FORWARD,
+ FFTW_MEASURE | FFTW_IN_PLACE | FFTW_USE_WISDOM );
+ }
+
+ for (i=0;i<P_FFT_LEN;i++) {
+ f_data[2*i] = 0;
+ f_data[2*i+1] = 0;
+ for (n=0;n<N_WINDOWS;n++) {
+ f_data[2*i] += data[2*i+2*n*P_FFT_LEN]*filter_r[P_FFT_LEN*n + i];
+ f_data[2*i+1] += data[2*i+2*n*P_FFT_LEN+1]*filter_i[P_FFT_LEN*n + i];
+ }
+ }
+ fftw_one(planfwd, (fftw_complex *)f_data, (fftw_complex *)NULL);
+ /*for (i=0;i<P_FFT_LEN;i++) {
+ fprintf( stderr, "%f %f\n", f_data[2*i], f_data[2*i+1]);
+ }*/
+ //fprintf( stderr, "%f %f ", f_data[2*3], f_data[2*3+1] );
+ p = f_data;
+ for (i=0; i<P_FFT_LEN; i++) {
+ output_samples(p, i, obuf_pos);
+ p += IFFT_LEN*2;
+ }
+ obuf_pos+=IFFT_LEN*2/CHAR_BIT;
+}
+
+#define TBUF_OFFSET(frame,byte) (tapebuffer+(frame)*TAPE_FRAME_SIZE+(byte)+TAPE_HEADER_SIZE)
+
+void do_polyphase(buffer_pos_t *start_of_wu, buffer_pos_t *end_of_wu) {
+ buffer_pos_t end_trans,start_trans=*start_of_wu;
+ int i,nsamp;
+ do {
+ obuf_pos=0; // reset to the beginning of the output buffer
+ for (i=0;i<768;i++) {
+ end_trans.frame=start_trans.frame;
+ end_trans.byte=start_trans.byte+(FFT_LEN*2/CHAR_BIT);
+ if (end_trans.byte > TAPE_DATA_SIZE) {
+ // End of frame crossed need to trasfer correctly
+ end_trans.frame++;
+ end_trans.byte-=TAPE_DATA_SIZE;
+ nsamp=(TAPE_DATA_SIZE-start_trans.byte)*(CHAR_BIT/2);
+ assert((nsamp+end_trans.byte*(CHAR_BIT/2)) == FFT_LEN);
+ splitter_bits_to_float((unsigned short *)TBUF_OFFSET(start_trans.frame,start_trans.byte),
+ databuf, nsamp);
+ splitter_bits_to_float((unsigned short *)TBUF_OFFSET(end_trans.frame,0),databuf+nsamp*2,
+ end_trans.byte*(CHAR_BIT/2));
+ } else {
+ splitter_bits_to_float((unsigned short *)TBUF_OFFSET(start_trans.frame,start_trans.byte),
+ databuf,FFT_LEN);
+ }
+ polyphase_seg(databuf);
+ // Go on to next transform
+ start_trans=end_trans;
+ }
+ // Check if we're at the end of the wu file. If so we print less bytes
+ if ((end_trans.frame>=end_of_wu->frame) &&
+ (end_trans.byte>=end_of_wu->byte)) {
+ write_wufile_blocks(NBYTES % SAMPLES_PER_OBUF);
+ } else {
+ write_wufile_blocks(SAMPLES_PER_OBUF);
+ }
+ } while (!((end_trans.frame>=end_of_wu->frame) && (end_trans.byte>=end_of_wu->byte)));
+
+ // Move the data in the buffer so we don't have to reread portions of the
+ // tape.
+ //
+ {
+ unsigned char *record_offset;
+ int copysize;
+ end_of_wu->frame-=WU_OVERLAP_FRAMES;
+ records_in_buffer=TAPE_RECORDS_IN_BUFFER-
+ (end_of_wu->frame/TAPE_FRAMES_PER_RECORD);
+ record_offset=tapebuffer+
+ (end_of_wu->frame/TAPE_FRAMES_PER_RECORD)*TAPE_RECORD_SIZE;
+ copysize=records_in_buffer*TAPE_RECORD_SIZE;
+ bcopy(record_offset,tapebuffer,copysize);
+ }
+}
+
+
diff --git a/gbt_splitter/polyphase.h b/gbt_splitter/polyphase.h
new file mode 100644
index 0000000..0393c38
--- /dev/null
+++ b/gbt_splitter/polyphase.h
@@ -0,0 +1,26 @@
+#define NONE 0
+#define WELCH 1
+#define HANNING 2
+
+#define N_WINDOWS 8
+#define P_FFT_LEN 256
+
+/* buffer for fft input/output */
+extern float databuf[FFT_LEN*2];
+
+/* buffer for ftt output before data writes, needs to be multiple
+ * of three bytes long for encode to work.
+ */
+#define SAMPLES_PER_OBUF (FFT_LEN*2*3/CHAR_BIT)
+#define TBUF_OFFSET(frame,byte) (tapebuffer+(frame)*TAPE_FRAME_SIZE+(byte))
+extern unsigned char output_buf[NSTRIPS][SAMPLES_PER_OBUF];
+
+extern double *filter_r, *filter_i;
+extern float *f_data;
+
+extern int obuf_pos; /* Tracks current postition in the output buffers */
+
+void make_FIR (int n_points, int M, int window, double *output);
+void polyphase_seg(float *data);
+void do_polyphase(buffer_pos_t *start_of_wu, buffer_pos_t *end_of_wu);
+
diff --git a/gbt_splitter/randomdata.cpp b/gbt_splitter/randomdata.cpp
new file mode 100644
index 0000000..094315d
--- /dev/null
+++ b/gbt_splitter/randomdata.cpp
@@ -0,0 +1,77 @@
+#include "sah_config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <math.h>
+#include <string.h>
+#include <unistd.h>
+
+#define NUM_FRAMES 200L
+#define FRAME_DATA_SIZE (1024L*1024)
+#define HEADER_SIZE 1024
+#define FILESIZE (NUM_FRAMES*(FRAME_DATA_SIZE+HEADER_SIZE))
+
+char header[HEADER_SIZE];
+
+int main(void) {
+ int i;
+ int datapos=0;
+ int frameseq=0;
+ long written=0;
+ int on=0;
+ struct tm *tm;
+ unsigned char data;
+
+ char tmpstr[256];
+ char telstr[256];
+ double time0=(double)time(0);
+ time_t clock;
+
+ srandom(time(0));
+
+ for (written=0;written<NUM_FRAMES;written++) {
+ int headerpos=0;
+ memset(header,0,HEADER_SIZE);
+ strcpy(header,"NAME=randdata");
+ headerpos+=strlen("NAME=randdata")+1;
+ strcpy(header+headerpos,"RCDTYPE=1");
+ headerpos+=strlen("RCDTYPE=1")+1;
+ sprintf(tmpstr,"FRAMESEQ=%d",frameseq);
+ strcpy(header+headerpos,tmpstr);
+ headerpos+=strlen(tmpstr)+1;
+ sprintf(tmpstr,"DATASEQ=%d",frameseq++);
+ strcpy(header+headerpos,tmpstr);
+ headerpos+=strlen(tmpstr)+1;
+ clock=floor(time0);
+ tm=localtime(&clock);
+ sprintf(tmpstr,"AST=%.2d%.3d%.2d%.2d%.2d%.2d",tm->tm_year,tm->tm_yday,tm->tm_hour,tm->tm_min,tm->tm_sec,(int)((time0-floor(time0))*100));
+ strcpy(header+headerpos,tmpstr);
+ headerpos+=strlen(tmpstr)+1;
+ if (!((frameseq-1)%5)) {
+ sprintf(telstr,"TELSTR=%.2d%.3d%.2d%.2d%.2d 0.0 0.0 15.0",tm->tm_year,tm->tm_yday,tm->tm_hour,tm->tm_min,tm->tm_sec);
+ }
+ strcpy(header+headerpos,telstr);
+ headerpos+=strlen(telstr)+1;
+ strcpy(header+headerpos,"RECEIVER=ao1420");
+ headerpos+=strlen("RECEIVER=ao1420")+1;
+ strcpy(header+headerpos,"SAMPLERATE=2.5000");
+ headerpos+=strlen("SAMPLERATE=2.5000")+1;
+ strcpy(header+headerpos,"CENTERFREQ=1420.0");
+ headerpos+=strlen("CENTERFREQ=1420.0")+1;
+ strcpy(header+headerpos,"VER=1.00");
+ headerpos+=strlen("VER=1.00")+1;
+ strcpy(header+headerpos,"NUMRINGBUFS=4");
+ headerpos+=strlen("NUMRINGBUFS=4")+1;
+ strcpy(header+headerpos,"NUMDISKBUFS=2");
+ headerpos+=strlen("NUMDISKBUFS=2")+1;
+ strcpy(header+headerpos,"EOH=");
+ write(stdout->_file, header, HEADER_SIZE);
+ for(i=0;i<FRAME_DATA_SIZE;i++) {
+ if (!((datapos++)%(100/8))) on=!on;
+ data=random()&0xff;
+ write(stdout->_file, &data, 1);
+ }
+ time0+=(1024.0*1024.0*4.0/2.5e6);
+ }
+}
+
diff --git a/gbt_splitter/readheader.cpp b/gbt_splitter/readheader.cpp
new file mode 100644
index 0000000..6a82fc2
--- /dev/null
+++ b/gbt_splitter/readheader.cpp
@@ -0,0 +1,225 @@
+/*
+ * Functions for reading tape and work unit headers
+ *
+ * This file currently assumes that the reciever is at Arecibo.
+ *
+ * $Id: readheader.cpp,v 1.3.4.2 2006/12/14 22:24:47 korpela Exp $
+ *
+ */
+
+#include "sah_config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "splitter.h"
+#include "splitparms.h"
+#include "splittypes.h"
+#include "message.h"
+#include "timecvt.h"
+#include "coordcvt.h"
+
+/* Read a tape header at buffer into a tapeheader_t */
+int read_tape_header(char *buffer, tapeheader_t *header)
+{
+ static char *receivers[]={"","synthetic","ao1420"};
+ int done=0,len;
+ int pos=0,i;
+ char tmpstr[256];
+ double dummy;
+ unsigned int firstdata;
+
+ do {
+ len=strlen(buffer+pos)+1;
+ if (!strncmp(buffer+pos,"EOH=",4)) {
+ done=1;
+ } else if (!strncmp(buffer+pos,"NAME=",5)) {
+ strncpy(tmpstr,buffer+pos+5,36);
+ i=0;
+ while(!isalnum(tmpstr[i])) i++;
+ strncpy(header->name,tmpstr+i,36);
+ } else if (!strncmp(buffer+pos,"RCDTYPE=",8)) {
+ sscanf(buffer+pos+8,"%d",&(header->rcdtype));
+ } else if (!strncmp(buffer+pos,"FRAMESEQ=",9)) {
+ sscanf(buffer+pos+9,"%lu",&(header->frameseq));
+ } else if (!strncmp(buffer+pos,"DATASEQ=",8)) {
+ sscanf(buffer+pos+8,"%lu",&(header->dataseq));
+ } else if (!strncmp(buffer+pos,"NUMRINGBUFS=",12)) {
+ sscanf(buffer+pos+12,"%d",&(header->numringbufs));
+ } else if (!strncmp(buffer+pos,"NUMDISKBUFS=",12)) {
+ sscanf(buffer+pos+12,"%d",&(header->numdiskbufs));
+ } else if (!strncmp(buffer+pos,"MISSED=",7)) {
+ sscanf(buffer+pos+7,"%d",&(header->missed));
+ } else if (!strncmp(buffer+pos,"AST=",4)) {
+ sscanf(buffer+pos+4,"%2d%3d%2d%2d%2d%2d",
+ &(header->st.y), &(header->st.d), &(header->st.h),
+ &(header->st.m), &(header->st.s), &(header->st.c));
+ header->st.tz=AST;
+ } else if (!strncmp(buffer+pos,"TELSTR=",7)) {
+ sscanf(buffer+pos+7,"%2d%3d%2d%2d%2d %lf %lf %lf",
+ &(header->telstr.st.y), &(header->telstr.st.d),
+ &(header->telstr.st.h), &(header->telstr.st.m),
+ &(header->telstr.st.s), &(header->telstr.az),
+ gregorian?&(header->telstr.alt):&dummy,
+ gregorian?&dummy:&(header->telstr.alt));
+ header->telstr.alt=90.0-header->telstr.alt;
+ header->telstr.st.tz=AST;
+ header->telstr.st.c=0;
+ } else if (!strncmp(buffer+pos,"RECEIVER=",9)) {
+ i=1;
+ while ((!strstr(buffer+pos+9,receivers[i])) && (++i<NUM_SRCS)) ;
+ if (i==NUM_SRCS) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Unknown receiver: %s\n",buffer+pos+9);
+ header->source=0;
+ } else {
+ header->source=i;
+ }
+ } else if (!strncmp(buffer+pos,"CENTERFREQ=",11)) {
+ sscanf(buffer+pos+11,"%lf",&(header->centerfreq));
+ header->centerfreq*=1e6;
+ } else if (!strncmp(buffer+pos,"SAMPLERATE=",11)) {
+ sscanf(buffer+pos+11,"%lf",&(header->samplerate));
+ header->samplerate*=1e6;
+ } else if (!strncmp(buffer+pos,"VER=",4)) {
+ strncpy(&(header->version[0]),&(buffer[pos+4]),16);
+ } else if (len>1) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Unknown header field: %40s\n",buffer+pos);
+ }
+ pos+=len;
+ } while (!done && (pos<TAPE_HEADER_SIZE));
+/* Right now were only doing this for one observatory. (Arecibo)
+ * May want to change list later to a switch statement on the reciever
+ */
+
+ st_time_convert(&(header->st));
+ header->st.jd-=(float)RECORDER_BUFFER_SAMPLES/header->samplerate/86400;
+ st_time_convert(&(header->telstr.st));
+ telstr_coord_convert(&(header->telstr),ARECIBO_LAT,ARECIBO_LON);
+
+/*
+ * Fix a bug in recorder versions prior to 1.30
+ */
+
+ if (atof(&(header->version[0]))<1.299) {
+ header->centerfreq-=2.0;
+ }
+
+/*
+ * Check for blank tape
+ */
+ firstdata=*(unsigned int *)(buffer+TAPE_HEADER_SIZE);
+ if (!(firstdata & 0x55555555) || !(firstdata & 0xaaaaaaaa) ||
+ ((firstdata & 0x55555555) == 0x55555555) ||
+ ((firstdata & 0xaaaaaaaa) == 0xaaaaaaaa)) {
+ header->missed++;
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Possible data problem...data[0] = 0x%x\n",firstdata);
+ }
+
+ return(1);
+}
+
+/* Read a work unit header from a FILE into a wuheader_t */
+//int read_wu_header(FILE *file, wuheader_t *header) {
+/* to be implemented. Don't need it yet. */
+// return(0);
+//}
+
+int parse_tape_headers(unsigned char *tapebuffer, tapeheader_t *tapeheaders) {
+ int i;
+
+ for (i=0;i<TAPE_FRAMES_IN_BUFFER;i++) {
+ read_tape_header((char *)tapebuffer+i*TAPE_FRAME_SIZE, &(tapeheaders[i]));
+ }
+ return(1);
+}
+
+/*
+ * $Log: readheader.cpp,v $
+ * Revision 1.3.4.2 2006/12/14 22:24:47 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.3.4.1 2006/01/13 00:37:57 korpela
+ * Moved splitter to using standard BOINC logging mechanisms. All stderr now
+ * goes to "error.log"
+ *
+ * Added command line parameters "-iterations=" (number of workunit groups to
+ * create before exiting), "-trigger_file_path=" (path to the splitter_stop trigger
+ * file. Default is /disks/setifiler1/wutape/tapedir/splitter_stop).
+ *
+ * Reduced deadlines by a factor of three. We now need a 30 MFLOP machine to meet
+ * the deadline.
+ *
+ * Revision 1.3 2003/09/11 18:53:38 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.2 2003/08/05 17:23:40 korpela
+ * More work on database stuff.
+ * Further tweaks.
+ *
+ * Revision 1.1 2003/07/29 20:35:48 korpela
+ *
+ * renames .C files to .cpp
+ *
+ * Revision 1.3 2003/06/05 15:52:47 korpela
+ *
+ * Fixed coordinate bug that was using the wrong zenith angle from the telescope
+ * strings when handling units from the gregorian.
+ *
+ * Revision 1.2 2003/06/03 01:01:17 korpela
+ *
+ * First working splitter under CVS.
+ *
+ * Revision 1.1 2003/06/03 00:16:16 korpela
+ *
+ * Initial splitter under CVS control.
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.9 1999/06/07 21:00:52 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.8 1999/03/05 01:47:18 korpela
+ * Added data_class field.
+ *
+ * Revision 2.7 1999/02/22 21:49:42 korpela
+ * Fixed bug in bug fix.
+ *
+ * Revision 2.6 1999/02/22 21:48:41 korpela
+ * Fixed frequency bug in recorders prior to v1.3
+ *
+ * Revision 2.5 1998/11/13 23:58:52 korpela
+ * Modified for move of name field between structures.
+ *
+ * Revision 2.4 1998/11/02 21:34:19 korpela
+ * Fixed azimuth error.
+ *
+ * Revision 2.3 1998/11/02 21:20:58 korpela
+ * Modified for (internal) integer receiver ID.
+ *
+ * Revision 2.2 1998/11/02 18:39:38 korpela
+ * Changed location of timecvt.h
+ *
+ * Revision 2.1 1998/11/02 16:41:21 korpela
+ * Minor Change.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.4 1998/10/30 20:26:03 korpela
+ * Bug Fixes. Now mostly working.
+ *
+ * Revision 1.3 1998/10/27 00:57:14 korpela
+ * Bug fixes.
+ *
+ * Revision 1.2 1998/10/15 19:16:38 korpela
+ * Corrected syntax errors.
+ *
+ * Revision 1.1 1998/10/15 19:05:33 korpela
+ * Initial revision
+ *
+ *
+ */
diff --git a/gbt_splitter/readheader.h b/gbt_splitter/readheader.h
new file mode 100644
index 0000000..67c14da
--- /dev/null
+++ b/gbt_splitter/readheader.h
@@ -0,0 +1,42 @@
+/*
+ * Functions for reading tape and work unit headers
+ *
+ * $Id: readheader.h,v 1.2 2003/08/05 17:23:41 korpela Exp $
+ *
+ */
+
+/* Read a tape header at buffer into a tapeheader_t */
+int read_tape_header(char *buffer, tapeheader_t *header);
+
+/* Read a work unit header from a FILE into a wuheader_t */
+//int read_wu_header(FILE *file, workunit *header);
+// no longer needed
+
+/* Parse tape headers from binary tape header into a tapeheader_t */
+int parse_tape_headers(unsigned char *tapebuffer, tapeheader_t *tapeheaders);
+/*
+ * $Log: readheader.h,v $
+ * Revision 1.2 2003/08/05 17:23:41 korpela
+ * More work on database stuff.
+ * Further tweaks.
+ *
+ * Revision 1.1 2003/06/03 00:16:16 korpela
+ *
+ * Initial splitter under CVS control.
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.1 1998/11/02 16:41:21 korpela
+ * Minor Change.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.2 1998/10/27 01:09:22 korpela
+ * Added parse_tape_headers()
+ *
+ * Revision 1.1 1998/10/15 17:19:21 korpela
+ * Initial revision
+ *
+ */
diff --git a/gbt_splitter/readtape.cpp b/gbt_splitter/readtape.cpp
new file mode 100644
index 0000000..9c4030a
--- /dev/null
+++ b/gbt_splitter/readtape.cpp
@@ -0,0 +1,333 @@
+/* readtape.c
+ *
+ * Functions for reading tapes.
+ *
+ * $Id: readtape.cpp,v 1.3.4.4 2007/06/07 20:01:52 mattl Exp $
+ *
+ */
+
+#include "sah_config.h"
+#undef USE_MYSQL
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/mtio.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <iostream>
+
+#include "util.h"
+#include "splitparms.h"
+#include "splitter.h"
+#include "message.h"
+#include "readheader.h"
+#include "readtape.h"
+#include "sqlrow.h"
+#include "sqlblob.h"
+#include "sqlapi.h"
+#include "db_table.h"
+#include "schema_master.h"
+#include "str_util.h"
+#include "str_replace.h"
+
+int is_tape;
+
+static tape tape_info;
+
+int current_record;
+static int tape_fd;
+struct mtget tape_status;
+
+static void update_checkpoint() {
+ FILE *file=fopen("rcd.chk","w");
+ if (file) {
+ fprintf(file,"%d\n",current_record);
+ fclose(file);
+ }
+}
+
+int read_checkpoint() {
+ FILE *file=fopen("rcd.chk","r");
+ int retval=0;
+ if (file) {
+ fscanf(file,"%d",&retval);
+ fclose(file);
+ }
+ return(retval);
+}
+
+int tape_busy() {
+/* Check if tape is busy. If so return 1 else return 0
+ */
+ if (is_tape) {
+ if (ioctl(tape_fd,MTIOCGET,&tape_status) != -1) {
+ return (tape_status.mt_dsreg);
+ } else {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Unable to get tape status\n");
+ return (1);
+ }
+ } else {
+ return (0);
+ }
+}
+
+int tape_eject() {
+/* Rewind and eject the tape. Return 1 if sucessful else return 0
+ */
+ struct mtop op={MTOFFL,1};
+
+ close(tape_fd);
+ if (is_tape) {
+ while (tape_busy()) sleep(1);
+ if (ioctl(tape_fd,MTIOCTOP,&op)==-1) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Unable to eject tape\n");
+ return(0);
+ } else {
+ return(1);
+ }
+ } else {
+ return(1);
+ }
+}
+
+
+int tape_rewind() {
+/* Rewind to beginning of tape. Return 1 if sucessful, 0 if failure
+ */
+ struct mtop op={MTREW, 1};
+ if (is_tape) {
+ while (tape_busy()) sleep(1);
+ if (ioctl(tape_fd,MTIOCTOP,&op)!=-1) {
+ current_record=0;
+ update_checkpoint();
+ } else {
+ current_record=-1;
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Tape rewind failed\n");
+ }
+ } else {
+ if (lseek(tape_fd, 0, SEEK_SET)!=-1) {
+ current_record=0;
+ update_checkpoint();
+ } else {
+ current_record=-1;
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"File rewind failed\n");
+ }
+ }
+ return (!current_record);
+}
+
+
+
+int open_tape_device(char *device) {
+/* opens a device, checks if it is a tape device. If so, sets is_tape
+ * flag. If not, it resets the flag. All tape routines check this flag
+ * so routines will work for both tapes and files
+ */
+
+
+ int fd, errcnt=0;
+ struct mtop op={MTNOP,1};
+
+ if ((fd=open(device, O_RDONLY|0x2000, 0777))!=-1) {
+ tape_fd=fd;
+ if (ioctl(tape_fd,MTIOCGET,&tape_status) != -1) {
+ is_tape = 1;
+ } else {
+ is_tape = 0;
+ }
+ while (!norewind && !tape_rewind() && errcnt<10 ) errcnt++;
+ if (!nodb && resumetape) {
+ tape_rewind();
+ fill_tape_buffer(tapebuffer,TAPE_RECORDS_IN_BUFFER);
+ parse_tape_headers(tapebuffer, &(tapeheaders[0]));
+ if (!tape_info.id) {
+ if (!tape_info.fetch(std::string("where name=\'")+tapeheaders->name+"\'")) {
+ tape_info.start_time=tapeheaders->st.jd;
+ tape_info.last_block_time=tapeheaders->st.jd;
+ tape_info.last_block_done=tapeheaders->frameseq;
+ strlcpy(tape_info.name,tapeheaders->name,sizeof(tape_info.name));
+ tape_info.insert();
+ }
+ }
+ startblock=tape_info.last_block_done/TAPE_FRAMES_PER_RECORD;
+ }
+ if (norewind) {
+ startblock=MAX(read_checkpoint()-TAPE_RECORDS_IN_BUFFER,0);
+ tape_rewind();
+ }
+ if (startblock) {
+ return select_record(startblock);
+ }
+ return (1);
+ } else {
+ perror( NULL );
+ return (0);
+ }
+}
+
+int select_record(int record_number) {
+/* seeks to a specific record number returns 1 if successful */
+ int diff;
+ struct mtop op;
+ char tmpstr[100];
+ off64_t off,offset;
+
+ if ((current_record<0) && !tape_rewind()) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Tape error: position lost and unable to rewind!\n");
+ return(0);
+ }
+
+ diff=record_number-current_record;
+
+ if (is_tape) {
+ if (diff==0) return (1);
+ if (diff>0) {
+ op.mt_op=MTFSR;
+ op.mt_count=diff;
+ } else {
+ op.mt_op=MTBSR;
+ op.mt_count=diff;
+ }
+ if (ioctl(tape_fd,MTIOCTOP,&op)==-1) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Tape error: unable to position to record %d errno=%d\n",
+ record_number,errno);
+ current_record=-1;
+ return(0);
+ } else {
+ current_record+=diff;
+ update_checkpoint();
+ return(1);
+ }
+ } else {
+ current_record=record_number;
+ update_checkpoint();
+ offset = record_number;
+ offset *= TAPE_RECORD_SIZE;
+ //fprintf( stderr, "offset: %lld", offset );
+ off=lseek64(tape_fd,offset,SEEK_SET) ;
+ //fprintf( stderr, "off: %lld", offset );
+ return (off != -1);
+ }
+}
+
+int tape_read_record(char *buffer) {
+ int bytesread=0;
+ int i;
+
+ while (tape_busy()) sleep(1);
+
+ do {
+ i=read(tape_fd,buffer+bytesread,TAPE_RECORD_SIZE);
+ if (i>0) bytesread+=i;
+ } while ((bytesread<TAPE_RECORD_SIZE) && (i>0));
+
+ if (i==0) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"End of tape. Please insert new tape\n");
+ current_record=-1;
+ return(0);
+ }
+
+ if (i<0) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Tape error.\n");
+ current_record=-1;
+ return(0);
+ }
+
+ current_record++;
+ update_checkpoint();
+ return(1);
+}
+
+int fill_tape_buffer(unsigned char *buffer, int n_records) {
+ int i;
+ long record;
+ char tmpstr[100];
+
+ for (i=0;i<n_records;i++) {
+ record=current_record;
+ //fprintf( stderr, "Reading record %d\n", i);
+ if (!tape_read_record((char *)buffer+i*TAPE_RECORD_SIZE)) {
+
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Tape error at record %d\n", current_record);
+ return(0);
+ }
+ }
+ return(1);
+}
+
+/*
+ * $Log: readtape.cpp,v $
+ * Revision 1.3.4.4 2007/06/07 20:01:52 mattl
+ * *** empty log message ***
+ *
+ * Revision 1.3.4.3 2006/12/14 22:24:47 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.3.4.2 2006/01/13 00:37:57 korpela
+ * Moved splitter to using standard BOINC logging mechanisms. All stderr now
+ * goes to "error.log"
+ *
+ * Added command line parameters "-iterations=" (number of workunit groups to
+ * create before exiting), "-trigger_file_path=" (path to the splitter_stop trigger
+ * file. Default is /disks/setifiler1/wutape/tapedir/splitter_stop).
+ *
+ * Reduced deadlines by a factor of three. We now need a 30 MFLOP machine to meet
+ * the deadline.
+ *
+ * Revision 1.3.4.1 2006/01/10 00:39:04 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.3 2003/09/11 18:53:38 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.2 2003/08/05 17:23:41 korpela
+ * More work on database stuff.
+ * Further tweaks.
+ *
+ * Revision 1.1 2003/07/29 20:35:49 korpela
+ *
+ * renames .C files to .cpp
+ *
+ * Revision 1.1 2003/06/03 00:16:16 korpela
+ *
+ * Initial splitter under CVS control.
+ *
+ * Revision 3.3 2003/05/19 17:40:59 eheien
+ * *** empty log message ***
+ *
+ * Revision 3.2 2003/04/23 22:10:29 korpela
+ * *** empty log message ***
+ *
+ * Revision 3.1 2002/06/21 00:06:09 eheien
+ * *** empty log message ***
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.3 1999/02/22 22:21:09 korpela
+ * added -nodb option
+ *
+ * Revision 2.2 1999/02/11 16:46:28 korpela
+ * Added some db access functions.
+ *
+ * Revision 2.1 1998/11/02 16:41:21 korpela
+ * Minor Change.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.3 1998/10/27 00:57:47 korpela
+ * Bug fixes.
+ *
+ * Revision 1.2 1998/10/20 21:33:25 korpela
+ * Added fill_tape_buffer()
+ * Minor bug fixes.
+ *
+ * Revision 1.1 1998/10/15 17:08:07 korpela
+ * Initial revision
+ *
+ */
+
diff --git a/gbt_splitter/readtape.h b/gbt_splitter/readtape.h
new file mode 100644
index 0000000..76987f8
--- /dev/null
+++ b/gbt_splitter/readtape.h
@@ -0,0 +1,85 @@
+/* readtape.h
+ *
+ * Functions for reading tapes.
+ *
+ * $Id: readtape.h,v 1.3.2.1 2006/12/14 22:24:47 korpela Exp $
+ *
+ */
+
+#ifndef READTAPE_H
+#define READTAPE_H
+
+#include "sah_config.h"
+
+/* Status flag to indicate whether open "tape" device is a tape drive */
+extern int is_tape;
+
+/* Check if tape is busy. If so return 1 else return 0 */
+int tape_busy();
+
+/* Rewind and eject the tape. Return 1 if sucessful else return 0 */
+int tape_eject();
+
+/* Rewind to beginning of tape. Return 1 if sucessful, 0 if failure */
+int tape_rewind();
+
+/* Open a device, check if it is a tape device. If so, set is_tape
+ * flag. If not, it resets the flag. All tape routines check this flag
+ * so routines will work for both tapes and files
+ */
+int open_tape_device(char *device);
+
+/* Seek to a specific record number returns 1 if successful */
+int select_record(int record_number);
+
+/* Read a record of length TAPE_RECORD_SIZE into a buffer
+ * Returns 1 if successful
+ */
+int tape_read_record(char *buffer);
+
+/* Fill a buffer of length n_records*TAPE_RECORD_SIZE
+ * with data from tape. Return 1 if sucessful.
+ */
+int fill_tape_buffer(unsigned char *buffer, int n_records);
+
+extern int current_record;
+
+#endif
+/*
+ * $Log: readtape.h,v $
+ * Revision 1.3.2.1 2006/12/14 22:24:47 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.3 2003/09/26 20:48:51 jeffc
+ * jeffc - merge in branch setiathome-4_all_platforms_beta.
+ *
+ * Revision 1.2.2.1 2003/09/23 16:01:45 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.2 2003/08/05 17:23:41 korpela
+ * More work on database stuff.
+ * Further tweaks.
+ *
+ * Revision 1.1 2003/06/03 00:23:39 korpela
+ *
+ * Again
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.2 1999/02/11 16:46:28 korpela
+ * Added db access functions.
+ *
+ * Revision 2.1 1998/11/02 16:41:21 korpela
+ * Minor Change.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.2 1998/10/20 21:35:51 korpela
+ * Added fill_tape_buffer()
+ *
+ * Revision 1.1 1998/10/15 16:49:59 korpela
+ * Initial revision
+ *
+ */
diff --git a/gbt_splitter/splitparms.h b/gbt_splitter/splitparms.h
new file mode 100644
index 0000000..64337a4
--- /dev/null
+++ b/gbt_splitter/splitparms.h
@@ -0,0 +1,145 @@
+/* splitparms.h
+ *
+ * Most of the definitions required by the splitter
+ *
+ * $Id: splitparms.h,v 1.10 2004/11/23 21:26:29 jeffc Exp $
+ *
+ */
+
+#ifndef SPLITPARMS_H
+#define SPLITPARMS_H
+
+#include <limits.h>
+
+#define WU_SUBDIR "/download"
+
+#define SPLITTER_VERSION 0x0012
+#define MAX_WUS_ONDISK 500000
+#define N_SIMULT_SPLITTERS 6
+
+/* Work Unit Parameters */
+#define NBYTES 262144L
+#define NSAMPLES (NBYTES*CHAR_BIT/2)
+#define MAX_POSITION_HISTORY 40
+#define WU_FILESIZE (360L*1024)
+
+/* FFT Parameters */
+#define FFT_LEN 256
+#define IFFT_LEN 1
+#define NSTRIPS (FFT_LEN/IFFT_LEN)
+
+/* Tape format parameters */
+#define TAPE_HEADER_SIZE 1024L
+#define TAPE_DATA_SIZE 1048576L
+#define TAPE_FRAMES_PER_RECORD 8L
+#define TAPE_FRAME_SIZE (TAPE_HEADER_SIZE+TAPE_DATA_SIZE)
+#define TAPE_RECORD_SIZE (TAPE_FRAMES_PER_RECORD*TAPE_FRAME_SIZE)
+#define TAPE_BUFFER_SIZE (((NSTRIPS*NBYTES*7/4)/TAPE_RECORD_SIZE+1)*TAPE_RECORD_SIZE)
+#define TAPE_RECORDS_IN_BUFFER (TAPE_BUFFER_SIZE/TAPE_RECORD_SIZE)
+#define TAPE_FRAMES_IN_BUFFER (TAPE_RECORDS_IN_BUFFER*8)
+#define TAPE_FRAMES_PER_WU (NBYTES*NSTRIPS/TAPE_DATA_SIZE)
+#define WU_OVERLAP_RECORDS 2
+#define WU_OVERLAP_FRAMES (TAPE_FRAMES_PER_RECORD*WU_OVERLAP_RECORDS)
+#define WU_OVERLAP_BYTES (WU_OVERLAP_FRAMES*TAPE_DATA_SIZE)
+#define RECORDER_BUFFER_BYTES (1024L*1024L)
+#define RECORDER_BUFFER_SAMPLES (RECORDER_BUFFER_BYTES*4)
+
+
+/* Time Zone Parameters */
+#define UTC 0.0
+#define AST (UTC-4.0)
+
+/* Arecibo Observatory Parameters */
+#define ARECIBO_LAT 18.3538056
+#define ARECIBO_LON (-66.7552222)
+
+#endif
+/*
+ * $Log: splitparms.h,v $
+ * Revision 1.10 2004/11/23 21:26:29 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.9 2004/08/14 04:44:26 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.8 2004/06/16 20:57:19 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.7 2004/05/22 18:12:18 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.6 2003/10/27 17:53:21 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.5 2003/09/26 20:48:51 jeffc
+ * jeffc - merge in branch setiathome-4_all_platforms_beta.
+ *
+ * Revision 1.3.2.1 2003/09/22 17:39:34 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.4 2003/09/22 17:05:38 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.3 2003/09/11 18:53:38 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.2 2003/08/05 17:23:42 korpela
+ * More work on database stuff.
+ * Further tweaks.
+ *
+ * Revision 1.1 2003/06/03 00:23:40 korpela
+ *
+ * Again
+ *
+ * Revision 3.1 2001/11/07 00:51:47 korpela
+ * Added splitter version to database.
+ * Added max_wus_ondisk option.
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.9 2000/12/01 01:13:29 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.8 1999/10/20 19:20:26 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.7 1999/06/07 21:00:52 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.6 1999/03/27 16:19:35 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.5 1999/03/05 01:47:18 korpela
+ * Added data_class field.
+ *
+ * Revision 2.4 1999/02/23 18:57:09 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.3 1999/02/22 22:21:09 korpela
+ * Changed version number.
+ *
+ * Revision 2.2 1999/02/11 16:46:28 korpela
+ * Added WU_FILESIZE, RECORDER_BUFFER_BYTES, RECORDER_BUFFER_SAMPLES.`
+ *
+ * Revision 2.1 1998/11/02 16:38:29 korpela
+ * Variable type changes.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.4 1998/10/27 01:10:04 korpela
+ * Bug fixes.
+ *
+ * Revision 1.3 1998/10/19 23:06:40 korpela
+ * Added UTC and AST definition.
+ * Added ARECIBO_LAT and ARECIBO_LON definitions.
+ *
+ * Revision 1.2 1998/10/16 19:22:14 korpela
+ * Reduced WU file size from 512K to 256K.
+ *
+ * Revision 1.1 1998/10/15 16:39:51 korpela
+ * Initial revision
+ *
+ */
+
diff --git a/gbt_splitter/splitter.cpp b/gbt_splitter/splitter.cpp
new file mode 100644
index 0000000..c4cea44
--- /dev/null
+++ b/gbt_splitter/splitter.cpp
@@ -0,0 +1,717 @@
+/*
+ *
+ * The splitter main program.
+ *
+ * $Id: splitter.cpp,v 1.22.2.6 2007/06/06 15:58:30 korpela Exp $
+ *
+ */
+
+#include "sah_config.h"
+#undef USE_MYSQL
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <strings.h>
+#include <sys/types.h>
+#include <sys/statvfs.h>
+#include <sys/wait.h>
+
+#include "boinc_db.h"
+#include "crypt.h"
+#include "backend_lib.h"
+#include "sched_config.h"
+#include "splitparms.h"
+#include "splittypes.h"
+#include "splitter.h"
+#include "validrun.h"
+#include "makebufs.h"
+#include "readtape.h"
+#include "readheader.h"
+#include "wufiles.h"
+#include "dotransform.h"
+#include "polyphase.h"
+#include "message.h"
+#include "sqlrow.h"
+#include "sqlapi.h"
+#include "db/db_table.h"
+#include "db/schema_master.h"
+#include "db/app_config.h"
+
+extern "C" {
+ int sqldetach();
+}
+
+char trigger_file_path[1024]="/disks/setifiler1/wutape/tapedir/splitter_stop";
+
+SCHED_CONFIG boinc_config;
+DB_APP app;
+R_RSA_PRIVATE_KEY key;
+
+
+// TEMPLATE DEFS ------------------------------------------------------
+// IMPORTANT: a change to a template should *always* include a change
+// to the template filename. Only the result template is used now.
+const char *wu_template_filename_id = "wu_0.xml";
+const char *wu_template=
+ "<file_info>\n"
+ " <number>0</number>\n"
+ "</file_info>\n"
+ "<workunit>\n"
+ " <file_ref>\n"
+ " <file_number>0</file_number>\n"
+ " <open_name>work_unit.sah</open_name>\n"
+ " </file_ref>\n"
+ "</workunit>\n";
+
+const char *result_template_filename_id = "result_0.xml";
+const char *result_template=
+ "<file_info>\n"
+ " <name><OUTFILE_0/></name>\n"
+ " <generated_locally/>\n"
+ " <upload_when_present/>\n"
+ " <max_nbytes>65536</max_nbytes>\n"
+ " <url>http://setiboincdata.ssl.berkeley.edu/sah_cgi/file_upload_handler</url>\n"
+ "</file_info>\n"
+ "<result>\n"
+ " <file_ref>\n"
+ " <file_name><OUTFILE_0/></file_name>\n"
+ " <open_name>result.sah</open_name>\n"
+ " </file_ref>\n"
+ "</result>\n";
+// END TEMPLATE DEFS --------------------------------------------------
+
+unsigned char *tapebuffer; /* A buffer for a tape section */
+workunit wuheaders[NSTRIPS];
+tapeheader_t tapeheaders[TAPE_FRAMES_IN_BUFFER];
+int max_wus_ondisk=MAX_WUS_ONDISK;
+int nodb;
+int noencode;
+int resumetape;
+int norewind;
+int startblock;
+int dataclass;
+int atnight;
+int gregorian;
+int output_xml;
+int polyphase;
+int iters=-1;
+int filter_window = 0;
+double start_time;
+double stop_time;
+unsigned long minvfsbuf=-1;
+char wd[1024];
+//char * scidb = NULL;
+char * projectdir = NULL;
+
+APP_CONFIG sah_config;
+
+//const char *result_template_filename="projectdir"/"SAH_APP_NAME"_result.tpl";
+char result_template_filename[1024];
+char result_template_filepath[1024];
+char wu_template_filename[1024];
+
+int check_for_halt();
+int wait_until_night();
+int check_free_disk_space();
+int wait_for_db_wus_ondisk();
+
+void cprint(char *p) {
+ printf("%s\n",p);
+}
+
+/* wulog: File for logging names of completed wu files */
+/* errorlog: File for logging errors */
+
+FILE *wulog,*errorlog;
+buffer_pos_t start_of_wu,end_of_wu; /* position of start and end of wu in
+ tape buffer */
+int seqno;
+int records_in_buffer;
+
+void cleanup(void) {
+ FILE *tmpfile;
+ if ((tmpfile=fopen("seqno.dat","w"))) {
+ fprintf(tmpfile,"%d\n",seqno);
+ fclose(tmpfile);
+ } else {
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Unable to open seqno.dat for write\n");
+ }
+}
+
+
+int process_command_line(int argc, char *argv[],char **tape_device,
+ int *norewind, int *startblock, int *resumetape,
+ int *nodb, int *dataclass, int *atnight,
+ int *max_wus_ondisk, char **projectdir,
+ int *iters) {
+ int nargs=0,i;
+ char *ep;
+ for (i=1;i<argc;i++) {
+ if (argv[i][0]=='-') {
+ if (!strncmp(argv[i],"-hanning",MAX(strlen(argv[i]),3))) {
+ filter_window=2;
+ } else
+ if (!strncmp(argv[i],"-welch",MAX(strlen(argv[i]),3))) {
+ filter_window=1;
+ } else
+ if (!strncmp(argv[i],"-xml",MAX(strlen(argv[i]),3))) {
+ output_xml=1;
+ } else
+ if (!strncmp(argv[i],"-atnight",MAX(strlen(argv[i]),7))) {
+ *atnight=1;
+ } else
+ if (!strncmp(argv[i],"-nodb",MAX(strlen(argv[i]),4))) {
+ if (*resumetape) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"-nodb and -resumetape are exclusive\n");
+ return(1);
+ }
+ *nodb=1;
+ } else
+ if (!strncmp(argv[i],"-gregorian",MAX(strlen(argv[i]),2))) {
+ gregorian=1;
+ } else
+ if (!strncmp(argv[i],"-resumetape",MAX(strlen(argv[i]),2))) {
+ if (*startblock || *norewind) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"-startblock and -norewind can\'t be used with -resumetape\n");
+ return(1);
+ }
+ if (*nodb) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"-nodb and -resumetape are exclusive\n");
+ return(1);
+ }
+ *resumetape=1;
+ } else
+ if (!strncmp(argv[i],"-norewind",MAX(strlen(argv[i]),4))) {
+ if (*startblock || *resumetape) {
+ return(1);
+ }
+ *norewind=1;
+ } else
+ if ((ep=strchr(argv[i],'='))) {
+ if (!strncmp(argv[i],"-trigger_file_path",MAX(ep-argv[i],2))) {
+ char *fe=ep+1;
+ memset(trigger_file_path,0,sizeof(trigger_file_path));
+ while (isgraph(*(fe++))) trigger_file_path[fe-ep-2]=*fe ;
+ } else if (!strncmp(argv[i],"-iterations",MAX(ep-argv[i],2))) {
+ sscanf(ep+1,"%d",iters);
+ } else if (!strncmp(argv[i],"-startblock",MAX(ep-argv[i],2))) {
+ if (*norewind || *resumetape) {
+ return(1);
+ }
+ sscanf(ep+1,"%d",startblock);
+ } else if (!strncmp(argv[i],"-max_wus_ondisk",MAX(ep-argv[i],2))) {
+ sscanf(ep+1,"%d",max_wus_ondisk);
+ } else if (!strncmp(argv[i],"-dataclass",MAX(ep-argv[i],2))) {
+ sscanf(ep+1,"%d",dataclass);
+ } else if (!strncmp(argv[i],"-projectdir",MAX(ep-argv[i],2))) {
+ *projectdir=calloc(strlen(ep+1)+5,1)
+ strlcpy(*projectdir,ep+1,strlen(ep+1)+5);
+ strlcat(*projectdir,"/",strlen(ep+1)+5);
+ } else {
+ return(1);
+ }
+ } else {
+ return(1);
+ }
+ } else {
+ *tape_device=argv[i];
+ nargs++;
+ }
+ }
+ //return(nargs!=1);
+
+ // check for required cmd line
+ //if (! *scidb) return (1);
+ if (! *projectdir) return (1);
+ if (! *tape_device) return (1);
+
+ return 0;
+}
+
+int main(int argc, char *argv[]) {
+ char *tape_device;
+ FILE *tmpfile;
+ int retval;
+ char keyfile[1024];
+ char tmpstr[1024];
+
+
+ /* Process command line arguments */
+ if (process_command_line(argc,argv,&tape_device,&norewind,&startblock,&resumetape,
+ &nodb,&dataclass,&atnight,&max_wus_ondisk,&projectdir,&iters)) {
+ fprintf(stderr,"Usage: splitter tape_device -projectdir=s [-atnight] [-nodb]\n"
+ "[-xml] [-gregorian] [-resumetape | -norewind | -startblock=n] [-dataclass=n]\n"
+ "[-max_wus_on_disk=n] [-iterations=n] [-trigger_file_path=filename]\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Open log files */
+ log_messages.set_debug_level(3);
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"opening log files\n");
+ if (!(wulog=fopen("wu.log","wa")) || !(errorlog=freopen("error.log","wa",stderr))) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Unable to open log files!\n");
+ exit(EXIT_FAILURE);
+ }
+
+ retval = sah_config.parse_file(projectdir);
+ if (retval) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Can't parse config file\n");
+ exit(EXIT_FAILURE);
+ } else {
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Using configuration:\n");
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"scidb_name = %s\n", sah_config.scidb_name);
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"max_wus_ondisk = %d\n", sah_config.max_wus_ondisk);
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"min_quorum = %d\n", sah_config.min_quorum);
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"target_nresults = %d\n", sah_config.target_nresults);
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"max_error_results = %d\n", sah_config.max_error_results);
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"max_success_results = %d\n", sah_config.max_success_results);
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"max_total_results = %d\n", sah_config.max_total_results);
+ }
+
+ // Will initially open
+ if (!db_change(sah_config.scidb_name)) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Could not open science database %s\n", sah_config.scidb_name);
+ if (!nodb) exit(EXIT_FAILURE);
+ } else {
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Using science database %s\n", sah_config.scidb_name);
+ }
+
+
+ boinc_config.parse_file(projectdir);
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Using boinc config dir %s\n", projectdir);
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Using boinc database %s\n", boinc_config.db_name);
+
+ // check / commit result template
+ strcpy(result_template_filename, "templates/"SAH_APP_NAME"_");
+ strcat(result_template_filename, result_template_filename_id);
+ strcpy(result_template_filepath, projectdir);
+ strcat(result_template_filepath, result_template_filename);
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"%s %s\n", result_template_filename, result_template_filepath);
+ if (!(tmpfile=fopen(result_template_filepath,"r"))) {
+ if (!(tmpfile=fopen(result_template_filepath,"w"))) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Cannot open result file template : %s\n", result_template_filepath);
+ exit(1);
+ }
+ fprintf(tmpfile,result_template);
+ }
+ fclose(tmpfile);
+
+ if (boinc_db.open(boinc_config.db_name,boinc_config.db_host,boinc_config.db_user,boinc_config.db_passwd)) {
+ boinc_db.print_error("boinc_db.open");
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"boinc_db.open\n");
+ exit(1);
+ }
+
+ if (app.lookup("where name ='"SAH_APP_NAME"'")) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Error looking up appname\n");
+ boinc_db.print_error("boinc_app lookup");
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"boinc_app lookup\n");
+ exit(1);
+ } else {
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Splitting for application %s (ID = %d)\n", SAH_APP_NAME, app.id);
+ }
+
+ boinc_db.close();
+
+ strcpy(keyfile, projectdir);
+ strcat(keyfile, "/keys/upload_private");
+ if (read_key_file(keyfile,key)) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Error reading keyfile.\n");
+ exit(1);
+ }
+
+ // if (!getenv("S4_RECEIVER_CONFIG")) putenv(s4cnf_env);
+ check_for_halt();
+
+ /* Process command line arguments */
+ //if (process_command_line(argc,argv,&tape_device,&norewind,&startblock,&resumetape,
+ // &nodb,&dataclass,&atnight,&max_wus_ondisk,&scidb,&projectdir)) {
+ // fprintf(stderr,"Usage: splitter tape_device [-atnight] [-nodb] [-xml] [-gregorian] [-resumetape | -norewind | -startblock=n] [-dataclass=n]\n");
+ // exit(EXIT_FAILURE);
+ //}
+
+
+ /* Connect to database */
+ //if (!sql_database(SCIENCE_DB)) {
+ // fprintf(stderr,"Unable to connect to database.\n");
+ // if (!nodb) exit(EXIT_FAILURE);
+ //}
+
+
+
+
+
+ /*
+ * Allocate temp files for tape buffer.
+ */
+ makebuffers(&tapebuffer);
+
+ if (!open_tape_device(tape_device)) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Unable to open tape device\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /*
+ * Get sequence number
+ */
+
+ if ((tmpfile=fopen("seqno.dat","r"))) {
+ fscanf(tmpfile,"%d",&seqno);
+ fclose(tmpfile);
+ } else {
+ seqno=0;
+ }
+ /* Start of main loop */
+
+ records_in_buffer=0;
+ start_of_wu.frame=0;
+ start_of_wu.byte=0;
+ end_of_wu.frame=0;
+ end_of_wu.byte=0;
+
+ atexit(cleanup);
+
+ getcwd(wd,1024);
+
+ if (polyphase) {
+ int filter_len;
+
+ filter_len = P_FFT_LEN*N_WINDOWS;
+
+ filter_r = (double *)malloc(sizeof(double)*filter_len);
+ filter_i = (double *)malloc(sizeof(double)*filter_len);
+
+ f_data = (float *)malloc(sizeof(float)*P_FFT_LEN*2);
+
+ make_FIR(filter_len, N_WINDOWS, filter_window, filter_r);
+ make_FIR(filter_len, N_WINDOWS, filter_window, filter_i);
+
+ /*
+ int i;
+ float *data;
+ data = (float*)malloc(sizeof(float)*2*2048);
+ for (double n=-20;n<20;n+=.05) {
+ for (i=0;i<2*2048;i+=2) {
+ data[i] = cos(2*(24+n)*3.1415926535*i/(2*2048));
+ data[i+1] = sin(2*(24+n)*3.1415926535*i/(2*2048));
+ }
+ polyphase_seg(data);
+ //fprintf( stderr, "%f\n", 3+n/8);
+ }
+ exit(0);
+ for(i=0;i<filter_len;i++)
+ printf( "%f\n", filter_r[i] );
+ exit(0);*/
+ }
+
+ log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG,"Entering loop\n" );
+ while (iters-- &&
+ fill_tape_buffer(tapebuffer+records_in_buffer*TAPE_RECORD_SIZE,
+ TAPE_RECORDS_IN_BUFFER-records_in_buffer)) {
+ /* check if we should be running now */
+ fflush(stderr);
+ if (atnight) wait_until_night();
+
+ check_for_halt();
+
+ // Make sure we have enough free disk space
+ check_free_disk_space();
+
+ // Wait for ondisk wus in the database to drop below the threshold
+ if (!nodb) wait_for_db_wus_ondisk();
+ //fprintf( stderr, "Read data\n" );
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"less than max wus on disk, continuing\n" );
+ fflush(stderr);
+
+ //printf( "Read tape data, analyzing\n" );
+ parse_tape_headers(tapebuffer, &(tapeheaders[0]));
+ check_for_halt();
+ if (valid_run(tapeheaders,&start_of_wu,&end_of_wu)) {
+ if (make_wu_headers(tapeheaders,wuheaders,&start_of_wu)) {
+ int child_pid=-1;
+ switch (polyphase) {
+ case 1:
+ do_polyphase(&start_of_wu,&end_of_wu);
+ break;
+ default:
+ log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG,"doing transform..." );
+ do_transform(&start_of_wu,&end_of_wu);
+ log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG," done\n" );
+ }
+ wait(0);
+ if (!nodb) sql_finish();
+/*
+ do {
+ sleep(1);
+ child_pid=fork();
+ if (child_pid<0) log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"splitter cannot fork");
+ //fprintf( stderr, "child pid: %d\n", child_pid);
+ } while (child_pid<0);
+*/
+ child_pid=0;
+ if (!child_pid) {
+ if (!nodb) {
+ sqldetach();
+ while (!sql_database(sah_config.scidb_name)) {
+ //fprintf(stderr,"child sleeping\n");
+ sleep(10);
+ }
+ }
+ rename_wu_files();
+ if (!nodb) sql_finish();
+// _exit(0);
+ }
+ if (!nodb) {
+ while (!sql_database(sah_config.scidb_name)) {
+ //fprintf(stderr,"parent sleeping\n");
+ sleep(10);
+ }
+ }
+ }
+ }
+ }
+return(0);
+
+}
+
+int check_for_halt() {
+ FILE *tf;
+
+ tf = fopen(trigger_file_path, "r");
+ // tf=0;
+ if (tf != NULL) { // Stop program
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Found splitter_stop, exiting.\n" );
+ exit(1);
+ }
+ return(0); // Keep going
+}
+
+int wait_until_night() {
+ time_t t;
+ struct tm *lt;
+ do {
+ t=time(0);
+ lt=localtime(&t);
+ // Don't run M-F 8AM-6PM
+ if ((lt->tm_wday>0) && (lt->tm_wday<6) && (lt->tm_hour>8) && (lt->tm_hour<18)) {
+ sleep(100);
+ }
+ } while ((lt->tm_wday>0) && (lt->tm_wday<6) && (lt->tm_hour>8) && (lt->tm_hour<18));
+ return 0;
+}
+
+int check_free_disk_space() {
+ struct statvfs vfsbuf;
+
+ /* check disk free space */
+ statvfs("wu_inbox/.",&vfsbuf);
+ if (vfsbuf.f_bavail < (100000*1024/vfsbuf.f_frsize)) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Not enough free disk space in working directory to continue\n");
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Not enough free disk space in working directory to continue\n");
+ exit(EXIT_FAILURE);
+ }
+ return 0;
+}
+
+int wait_for_db_wus_ondisk() {
+ int wus_ondisk,rv;
+
+ // The boinc db query below takes a long time. Until we fix this,
+ // we will do it only every 100 times into this routine. All other
+ // calls here will assume that we need to add WUs. -- jeffc
+ static int check_count = 100;
+ if (check_count < 100) {
+ check_count++;
+ return 0;
+ } else {
+ check_count = 0;
+ }
+
+ if (boinc_db.open(boinc_config.db_name,boinc_config.db_host,boinc_config.db_user,boinc_config.db_passwd)) {
+ boinc_db.print_error("boinc_db.open");
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"boinc_db.open\n");
+ exit(1);
+ }
+ do {
+ DB_RESULT boinc_result;
+ char query[1024];
+ sprintf(query,"where appid=%d and server_state=2",app.id);
+ rv=boinc_result.count(wus_ondisk,query);
+ if (rv) {
+ boinc_db.print_error("boinc_result.count");
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"DB Error, unable to count workunits on disk\n");
+ exit(EXIT_FAILURE);
+ }
+ check_for_halt();
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"%d WUs ondisk\n", wus_ondisk);
+ if (wus_ondisk>sah_config.max_wus_ondisk) sleep(600);
+ } while (wus_ondisk>sah_config.max_wus_ondisk);
+
+ return 0;
+}
+
+/*
+ * $Log: splitter.cpp,v $
+ * Revision 1.22.2.6 2007/06/06 15:58:30 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.22.2.5 2006/12/14 22:24:48 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.22.2.4 2006/11/08 20:16:26 vonkorff
+ * Fixes an error message.
+ *
+ * Revision 1.22.2.3 2006/11/07 19:26:37 vonkorff
+ * Fixed lcgf
+ *
+ * Revision 1.22.2.2 2006/01/13 00:37:58 korpela
+ * Moved splitter to using standard BOINC logging mechanisms. All stderr now
+ * goes to "error.log"
+ *
+ * Added command line parameters "-iterations=" (number of workunit groups to
+ * create before exiting), "-trigger_file_path=" (path to the splitter_stop trigger
+ * file. Default is /disks/setifiler1/wutape/tapedir/splitter_stop).
+ *
+ * Reduced deadlines by a factor of three. We now need a 30 MFLOP machine to meet
+ * the deadline.
+ *
+ * Revision 1.22.2.1 2005/08/01 21:16:25 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.22 2005/01/27 23:03:27 mattl
+ *
+ * commented out tf=0 in check_for_halt
+ *
+ * Revision 1.21 2004/12/27 20:48:54 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.20 2004/08/12 15:45:41 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.19 2004/07/09 22:35:39 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.18 2004/06/27 21:07:04 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.17 2004/06/20 18:56:48 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.16 2004/06/18 23:23:32 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.15 2004/06/16 20:57:19 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.14 2004/04/08 22:25:47 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.13 2004/01/22 00:57:53 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.12 2004/01/01 18:42:01 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.11 2003/12/03 23:46:41 korpela
+ * WU count is now only for SAH workunits.
+ *
+ * Revision 1.10 2003/11/25 21:59:52 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.9 2003/11/01 20:54:02 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.8 2003/10/24 16:57:03 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.7 2003/09/26 20:48:51 jeffc
+ * jeffc - merge in branch setiathome-4_all_platforms_beta.
+ *
+ * Revision 1.5.2.2 2003/09/23 00:49:12 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.5.2.1 2003/09/22 17:39:34 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.6 2003/09/22 17:05:38 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.5 2003/09/13 20:48:38 korpela
+ * directory reorg. Moved client files to ./client
+ *
+ * Revision 1.4 2003/09/11 18:53:38 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.3 2003/08/13 23:18:47 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.2 2003/08/05 17:23:42 korpela
+ * More work on database stuff.
+ * Further tweaks.
+ *
+ * Revision 1.1 2003/07/29 20:35:50 korpela
+ *
+ * renames .C files to .cpp
+ *
+ * Revision 1.2 2003/06/03 01:01:17 korpela
+ *
+ * First working splitter under CVS.
+ *
+ * Revision 1.1 2003/06/03 00:23:40 korpela
+ *
+ * Again
+ *
+ * Revision 3.6 2003/05/21 00:41:42 korpela
+ * *** empty log message ***
+ *
+ * Revision 3.5 2003/05/19 17:40:59 eheien
+ * *** empty log message ***
+ *
+ * Revision 3.4 2003/04/09 17:46:54 korpela
+ * *** empty log message ***
+ *
+ * Revision 3.3 2002/06/20 22:09:17 eheien
+ * *** empty log message ***
+ *
+ * Revision 3.2 2001/11/07 00:51:47 korpela
+ * Added splitter version to database.
+ * Added max_wus_ondisk option.
+ *
+ * Revision 3.1 2001/08/16 23:42:08 korpela
+ * Mods for splitter to make binary workunits.
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.7 2000/12/01 01:13:29 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.6 1999/06/07 21:00:52 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.5 1999/03/27 16:19:35 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.4 1999/03/05 01:47:18 korpela
+ * Added dataclass paramter.
+ *
+ * Revision 2.3 1999/02/22 22:21:09 korpela
+ * added -nodb option
+ *
+ * Revision 2.2 1999/02/11 16:46:28 korpela
+ * Added some db access functions.
+ *
+ * Revision 2.1 1998/11/02 16:41:21 korpela
+ * Minor Change.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.2 1998/10/30 20:26:03 korpela
+ * Bug Fixes. Now mostly working.
+ *
+ * Revision 1.1 1998/10/27 00:58:16 korpela
+ * Initial revision
+ *
+ *
+ */
diff --git a/gbt_splitter/splitter.h b/gbt_splitter/splitter.h
new file mode 100644
index 0000000..46b73b3
--- /dev/null
+++ b/gbt_splitter/splitter.h
@@ -0,0 +1,132 @@
+/*
+ * splitter.h
+ *
+ * Global definitions from the splitter main program.
+ *
+ * $Id: splitter.h,v 1.6.2.1 2006/01/13 00:37:58 korpela Exp $
+ *
+ */
+
+#ifndef SPLITTER_H
+#define SPLITTER_H
+
+#include "splitparms.h"
+#include "splittypes.h"
+
+#define MAX(x,y) ( ((x)<(y)) ? (y) : (x) )
+#define MIN(x,y) ( ((y)<(x)) ? (y) : (x) )
+
+/* wulog: File for logging names of completed wu files */
+/* errorlog: File for logging errors */
+#include "boinc_db.h"
+#include "crypt.h"
+#include "backend_lib.h"
+#include "sched_config.h"
+
+extern SCHED_CONFIG boinc_config;
+extern DB_APP app;
+extern R_RSA_PRIVATE_KEY key;
+extern FILE *wulog,*errorlog;
+extern workunit wuheaders[NSTRIPS];
+extern tapeheader_t tapeheaders[TAPE_FRAMES_IN_BUFFER];
+extern int noencode;
+extern int dataclass;
+extern int nodb;
+extern int resumetape;
+extern int startblock;
+extern int norewind;
+extern int output_xml;
+extern int polyphase;
+extern int wu_database_id[NSTRIPS];
+extern int gregorian;
+extern char * projectdir;
+extern char trigger_file_name[1024];
+
+
+/* Buffer that holds tape data */
+extern unsigned char *tapebuffer;
+
+/* Number of records remaining in the buffer after WU creations is complete */
+extern int records_in_buffer;
+
+extern const char *wu_template;
+extern const char *result_template;
+// jeffc
+//extern const char *result_template_filename;
+extern char result_template_filename[];
+extern char result_template_filepath[];
+extern char wu_template_filename[];
+
+/* Persistant sequence number of wu file */
+extern int seqno;
+
+#endif
+
+/*
+ * $Log: splitter.h,v $
+ * Revision 1.6.2.1 2006/01/13 00:37:58 korpela
+ * Moved splitter to using standard BOINC logging mechanisms. All stderr now
+ * goes to "error.log"
+ *
+ * Added command line parameters "-iterations=" (number of workunit groups to
+ * create before exiting), "-trigger_file_path=" (path to the splitter_stop trigger
+ * file. Default is /disks/setifiler1/wutape/tapedir/splitter_stop).
+ *
+ * Reduced deadlines by a factor of three. We now need a 30 MFLOP machine to meet
+ * the deadline.
+ *
+ * Revision 1.6 2004/07/09 22:35:39 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.5 2004/06/16 20:57:19 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.4 2003/09/26 20:48:52 jeffc
+ * jeffc - merge in branch setiathome-4_all_platforms_beta.
+ *
+ * Revision 1.2.2.1 2003/09/22 17:39:35 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.3 2003/09/22 17:05:38 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.2 2003/08/05 17:23:42 korpela
+ * More work on database stuff.
+ * Further tweaks.
+ *
+ * Revision 1.1 2003/06/03 00:23:40 korpela
+ *
+ * Again
+ *
+ * Revision 3.2 2003/05/19 17:40:59 eheien
+ * *** empty log message ***
+ *
+ * Revision 3.1 2001/08/16 23:42:08 korpela
+ * Mods for splitter to make binary workunits.
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.5 1999/10/20 19:20:26 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.4 1999/03/05 01:47:18 korpela
+ * Added data_class field.
+ *
+ * Revision 2.3 1999/02/22 22:21:09 korpela
+ * Added nodb option
+ *
+ * Revision 2.2 1999/02/11 16:46:28 korpela
+ * Added startblock and norewind support, and wu_database_id.
+ *
+ * Revision 2.1 1998/11/02 16:41:21 korpela
+ * Minor Change.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.1 1998/10/27 01:10:32 korpela
+ * Initial revision
+ *
+ *
+ */
diff --git a/gbt_splitter/splittypes.h b/gbt_splitter/splittypes.h
new file mode 100644
index 0000000..46e4b37
--- /dev/null
+++ b/gbt_splitter/splittypes.h
@@ -0,0 +1,111 @@
+/* splittypes.h
+ *
+ * Type definitions specific to the splitter.
+ *
+ *
+ * $Id: splittypes.h,v 1.4 2003/08/05 17:23:43 korpela Exp $
+ *
+ */
+#ifndef SPLITTYPES_H
+#define SPLITTYPES_H
+
+#include <stdio.h>
+
+#include "splitparms.h"
+#include "s_util.h"
+#include "seti_header.h"
+
+//typedef struct wuheader {
+ //WU_INFO wuhead;
+ //SETI_WU_INFO wuinfo;
+//} wuheader_t;
+
+typedef struct tapeheader {
+ char name[36];
+ int rcdtype;
+ int numringbufs;
+ int numdiskbufs;
+ unsigned long frameseq;
+ unsigned long dataseq;
+ int missed;
+ TIME st;
+ SCOPE_STRING telstr;
+ int source;
+ double centerfreq,samplerate;
+ char version[16];
+} tapeheader_t;
+
+typedef struct buffer_pos {
+ int frame;
+ long byte;
+} buffer_pos_t;
+
+#endif
+/*
+ * $Log: splittypes.h,v $
+ * Revision 1.4 2003/08/05 17:23:43 korpela
+ * More work on database stuff.
+ * Further tweaks.
+ *
+ * Revision 1.3 2003/07/29 20:35:51 korpela
+ *
+ * renames .C files to .cpp
+ *
+ * Revision 1.2 2003/06/03 01:01:17 korpela
+ *
+ * First working splitter under CVS.
+ *
+ * Revision 1.1 2003/06/03 00:23:41 korpela
+ *
+ * Again
+ *
+ * Revision 3.1 2003/05/19 17:40:59 eheien
+ * *** empty log message ***
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.5 1999/02/11 16:46:28 korpela
+ * Added startblock and norewind support, and wu_database_id.
+ *
+ * Revision 2.4 1998/11/10 00:02:44 korpela
+ * Moved remaining wuheader fields into a WU_INFO structure.
+ *
+ * Revision 2.3 1998/11/05 21:18:41 korpela
+ * Moved name field from header to seti header.
+ *
+ * Revision 2.2 1998/11/02 21:20:58 korpela
+ * Moved tape_version and encoding_type into SETI_WU_INFO.
+ *
+ * Revision 2.1 1998/11/02 16:38:29 korpela
+ * Variable type changes.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.7 1998/10/30 21:01:13 davea
+ * *** empty log message ***
+ *
+ * Revision 1.6 1998/10/27 01:10:58 korpela
+ * Modified tapeheader_t to match new tape header fields.
+ *
+ * Revision 1.5 1998/10/19 23:04:32 korpela
+ * Moved times in telstr_t into an st_t.
+ * Changed name of ast_t to st_t.
+ * Added time zone (tz) field to ast_t.
+ *
+ * Revision 1.4 1998/10/15 19:13:30 korpela
+ * Renamed "unix" fields to "unix_time" because of GCC #define.
+ * Added position_history field to wuheader_t.
+ *
+ * Revision 1.3 1998/10/15 18:58:50 korpela
+ * Added time_t unix to ast_t and telstr_t types.
+ * Changed times in wuheader_t to time_t types.
+ *
+ * Revision 1.2 1998/10/15 18:01:19 korpela
+ * Removed month field from ast_t and telstr_t.
+ *
+ * Revision 1.1 1998/10/15 16:20:24 korpela
+ * Initial revision
+ *
+ */
diff --git a/gbt_splitter/squarewave.cpp b/gbt_splitter/squarewave.cpp
new file mode 100644
index 0000000..7ac379d
--- /dev/null
+++ b/gbt_splitter/squarewave.cpp
@@ -0,0 +1,75 @@
+#include "sah_config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <math.h>
+#include <string.h>
+#include <unistd.h>
+
+#define NUM_FRAMES 200L
+#define FRAME_DATA_SIZE (1024L*1024)
+#define HEADER_SIZE 1024
+#define FILESIZE (NUM_FRAMES*(FRAME_DATA_SIZE+HEADER_SIZE))
+
+char header[HEADER_SIZE];
+
+int main(void) {
+ int i;
+ int datapos=0;
+ int frameseq=0;
+ long written=0;
+ int on=0;
+ struct tm *tm;
+ char data;
+
+ char tmpstr[256];
+ char telstr[256];
+ double time0=(double)time(0);
+ time_t clock;
+
+ for (written=0;written<NUM_FRAMES;written++) {
+ int headerpos=0;
+ memset(header,0,HEADER_SIZE);
+ strcpy(header,"NAME=sqrwave");
+ headerpos+=strlen("NAME=sqrwave")+1;
+ strcpy(header+headerpos,"RCDTYPE=1");
+ headerpos+=strlen("RCDTYPE=1")+1;
+ sprintf(tmpstr,"FRAMESEQ=%d",frameseq);
+ strcpy(header+headerpos,tmpstr);
+ headerpos+=strlen(tmpstr)+1;
+ sprintf(tmpstr,"DATASEQ=%d",frameseq++);
+ strcpy(header+headerpos,tmpstr);
+ headerpos+=strlen(tmpstr)+1;
+ clock=floor(time0);
+ tm=localtime(&clock);
+ sprintf(tmpstr,"AST=%.2d%.3d%.2d%.2d%.2d%.2d",tm->tm_year,tm->tm_yday,tm->tm_hour,tm->tm_min,tm->tm_sec,(int)((time0-floor(time0))*100));
+ strcpy(header+headerpos,tmpstr);
+ headerpos+=strlen(tmpstr)+1;
+ if (!((frameseq-1)%5)) {
+ sprintf(telstr,"TELSTR=%.2d%.3d%.2d%.2d%.2d 0.0 0.0 15.0",tm->tm_year,tm->tm_yday,tm->tm_hour,tm->tm_min+(tm->tm_sec>57),(tm->tm_sec+2)%60);
+ }
+ strcpy(header+headerpos,telstr);
+ headerpos+=strlen(telstr)+1;
+ strcpy(header+headerpos,"RECEIVER=ao1420");
+ headerpos+=strlen("RECEIVER=ao1420")+1;
+ strcpy(header+headerpos,"SAMPLERATE=2.5000");
+ headerpos+=strlen("SAMPLERATE=2.5000")+1;
+ strcpy(header+headerpos,"VER=1.00");
+ headerpos+=strlen("VER=1.00")+1;
+ strcpy(header+headerpos,"CENTERFREQ=1420.0");
+ headerpos+=strlen("CENTERFREQ=1420.0")+1;
+ strcpy(header+headerpos,"NUMRINGBUFS=4");
+ headerpos+=strlen("NUMRINGBUFS=4")+1;
+ strcpy(header+headerpos,"NUMDISKBUFS=2");
+ headerpos+=strlen("NUMDISKBUFS=2")+1;
+ strcpy(header+headerpos,"EOH=");
+ write(stdout->_file, header, HEADER_SIZE);
+ for(i=0;i<FRAME_DATA_SIZE;i++) {
+ if (!((datapos++)%(100/8))) on=!on;
+ data=0xaa*on;
+ write(stdout->_file, &data, 1);
+ }
+ time0+=(1024.0*1024.0*4.0/2.5e6);
+ }
+}
+
diff --git a/gbt_splitter/tags b/gbt_splitter/tags
new file mode 100644
index 0000000..36fa81d
--- /dev/null
+++ b/gbt_splitter/tags
@@ -0,0 +1,463 @@
+!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
+!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
+!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert at users.sourceforge.net/
+!_TAG_PROGRAM_NAME Exuberant Ctags //
+!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
+!_TAG_PROGRAM_VERSION 5.8 //
+ARECIBO_LAT splitparms.h 53;" d
+ARECIBO_LON splitparms.h 54;" d
+AST splitparms.h 50;" d
+AltAzCorrection coordcvt.cpp /^void AltAzCorrection(double *alt, double *az) {$/;" f namespace:SPLITTER
+COMPLEX fftw.h 74;" d
+COORDCVT_H coordcvt.h 11;" d
+D2R coordcvt.cpp 109;" d file:
+DB_FNS_H db_fns.h 8;" d
+DL_IMPORT fftw.h 141;" d
+DL_IMPORT fftw.h 143;" d
+DL_IMPORT fftw.h 145;" d
+DL_IMPORT fftw.h 148;" d
+DTOR angdist.cpp 16;" d file:
+DTOR mb_angdist.cpp 24;" d file:
+EXIT_NORMAL_EOF mb_splitter.h /^const int EXIT_NORMAL_EOF = 0;$/;" v
+EXIT_NORMAL_NOT_EOF mb_splitter.h /^const int EXIT_NORMAL_NOT_EOF = 2;$/;" v
+FFTWND_FORCE_BUFFERED fftw.h 289;" d
+FFTWND_HAS_PRINT_PLAN fftw.h 401;" d
+FFTW_1_0_COMPATIBILITY fftw.h 68;" d
+FFTW_BACKWARD fftw.h /^ FFTW_FORWARD = -1, FFTW_BACKWARD = 1$/;" e enum:__anon2
+FFTW_COMPLEX fftw.h /^typedef fftw_complex FFTW_COMPLEX;$/;" t
+FFTW_ENABLE_FLOAT fftw.h 40;" d
+FFTW_ESTIMATE fftw.h 278;" d
+FFTW_FAILURE fftw.h /^ FFTW_SUCCESS = 0, FFTW_FAILURE = -1$/;" e enum:__anon3
+FFTW_FORWARD fftw.h /^ FFTW_FORWARD = -1, FFTW_BACKWARD = 1$/;" e enum:__anon2
+FFTW_GENERIC fftw.h /^ FFTW_NOTW, FFTW_TWIDDLE, FFTW_GENERIC, FFTW_RADER,$/;" e enum:fftw_node_type
+FFTW_H fftw.h 26;" d
+FFTW_HAS_FPRINT_PLAN fftw.h 335;" d
+FFTW_HAS_PLAN_SPECIFIC fftw.h 295;" d
+FFTW_HAS_WISDOM fftw.h 322;" d
+FFTW_HC2HC fftw.h /^ FFTW_REAL2HC, FFTW_HC2REAL, FFTW_HC2HC, FFTW_RGENERIC$/;" e enum:fftw_node_type
+FFTW_HC2REAL fftw.h /^ FFTW_REAL2HC, FFTW_HC2REAL, FFTW_HC2HC, FFTW_RGENERIC$/;" e enum:fftw_node_type
+FFTW_IN_PLACE fftw.h 282;" d
+FFTW_MEASURE fftw.h 279;" d
+FFTW_NOTW fftw.h /^ FFTW_NOTW, FFTW_TWIDDLE, FFTW_GENERIC, FFTW_RADER,$/;" e enum:fftw_node_type
+FFTW_OUT_OF_PLACE fftw.h 281;" d
+FFTW_RADER fftw.h /^ FFTW_NOTW, FFTW_TWIDDLE, FFTW_GENERIC, FFTW_RADER,$/;" e enum:fftw_node_type
+FFTW_REAL fftw.h /^typedef fftw_real FFTW_REAL;$/;" t
+FFTW_REAL2HC fftw.h /^ FFTW_REAL2HC, FFTW_HC2REAL, FFTW_HC2HC, FFTW_RGENERIC$/;" e enum:fftw_node_type
+FFTW_RGENERIC fftw.h /^ FFTW_REAL2HC, FFTW_HC2REAL, FFTW_HC2HC, FFTW_RGENERIC$/;" e enum:fftw_node_type
+FFTW_SUCCESS fftw.h /^ FFTW_SUCCESS = 0, FFTW_FAILURE = -1$/;" e enum:__anon3
+FFTW_THREADSAFE fftw.h 285;" d
+FFTW_TWIDDLE fftw.h /^ FFTW_NOTW, FFTW_TWIDDLE, FFTW_GENERIC, FFTW_RADER,$/;" e enum:fftw_node_type
+FFTW_USE_WISDOM fftw.h 283;" d
+FFT_LEN splitparms.h 27;" d
+FILESIZE randomdata.cpp 12;" d file:
+FILESIZE squarewave.cpp 12;" d file:
+FRAME_DATA_SIZE randomdata.cpp 10;" d file:
+FRAME_DATA_SIZE squarewave.cpp 10;" d file:
+HANNING polyphase.h 3;" d
+HEADER_SIZE randomdata.cpp 11;" d file:
+HEADER_SIZE squarewave.cpp 11;" d file:
+IFFT_LEN splitparms.h 28;" d
+MAKEBUFS_H makebufs.h 11;" d
+MAX mb_splitter.h 16;" d
+MAX splitter.h 16;" d
+MAX_POSITION_HISTORY splitparms.h 23;" d
+MAX_WUS_ONDISK splitparms.h 17;" d
+MIN mb_splitter.h 17;" d
+MIN splitter.h 17;" d
+NBYTES splitparms.h 21;" d
+NONE polyphase.h 1;" d
+NSAMPLES splitparms.h 22;" d
+NSTRIPS splitparms.h 29;" d
+NUM_FRAMES randomdata.cpp 9;" d file:
+NUM_FRAMES squarewave.cpp 9;" d file:
+N_SIMULT_SPLITTERS splitparms.h 18;" d
+N_WINDOWS polyphase.h 5;" d
+P_FFT_LEN polyphase.h 6;" d
+READTAPE_H readtape.h 10;" d
+REAL fftw.h 73;" d
+RECORDER_BUFFER_BYTES splitparms.h 44;" d
+RECORDER_BUFFER_SAMPLES splitparms.h 45;" d
+SAMPLES_PER_OBUF dotransform.cpp 32;" d file:
+SAMPLES_PER_OBUF dotransform.h 17;" d
+SAMPLES_PER_OBUF mb_dotransform.cpp 30;" d file:
+SAMPLES_PER_OBUF mb_dotransform.h 15;" d
+SAMPLES_PER_OBUF mb_polyphase.cpp 26;" d file:
+SAMPLES_PER_OBUF polyphase.cpp 25;" d file:
+SAMPLES_PER_OBUF polyphase.h 14;" d
+SPLITPARMS_H splitparms.h 10;" d
+SPLITTER coordcvt.cpp /^namespace SPLITTER {$/;" n file:
+SPLITTER_H mb_splitter.h 11;" d
+SPLITTER_H splitter.h 11;" d
+SPLITTER_VERSION splitparms.h 16;" d
+SPLITTYPES_H mb_splittypes.h 10;" d
+SPLITTYPES_H splittypes.h 10;" d
+SWAP four1.cpp 11;" d file:
+SWAP four1.cpp 57;" d file:
+TAPE_BUFFER_SIZE splitparms.h 37;" d
+TAPE_DATA_SIZE splitparms.h 33;" d
+TAPE_FRAMES_IN_BUFFER splitparms.h 39;" d
+TAPE_FRAMES_PER_RECORD splitparms.h 34;" d
+TAPE_FRAMES_PER_WU splitparms.h 40;" d
+TAPE_FRAME_SIZE splitparms.h 35;" d
+TAPE_HEADER_SIZE splitparms.h 32;" d
+TAPE_RECORDS_IN_BUFFER splitparms.h 38;" d
+TAPE_RECORD_SIZE splitparms.h 36;" d
+TBUF_OFFSET dotransform.cpp 108;" d file:
+TBUF_OFFSET dotransform.h 18;" d
+TBUF_OFFSET mb_dotransform.h 16;" d
+TBUF_OFFSET mb_polyphase.cpp 97;" d file:
+TBUF_OFFSET polyphase.cpp 96;" d file:
+TBUF_OFFSET polyphase.h 15;" d
+USE_MYSQL mb_splitter.cpp 10;" d file:
+USE_MYSQL mb_wufiles.cpp 10;" d file:
+USE_MYSQL readtape.cpp 10;" d file:
+USE_MYSQL splitter.cpp 10;" d file:
+USE_MYSQL wufiles.cpp 10;" d file:
+UTC splitparms.h 49;" d
+WELCH polyphase.h 2;" d
+WU_FILESIZE splitparms.h 24;" d
+WU_OVERLAP_BYTES splitparms.h 43;" d
+WU_OVERLAP_FRAMES splitparms.h 42;" d
+WU_OVERLAP_RECORDS splitparms.h 41;" d
+WU_SUBDIR splitparms.h 14;" d
+alfa mb_splitter.cpp /^int alfa;$/;" v
+angdist angdist.cpp /^double angdist(const SCOPE_STRING &a, const SCOPE_STRING &b) {$/;" f
+angdist angdist.cpp /^double angdist(double r1, double d1, double r2, double d2) {$/;" f
+angdist mb_angdist.cpp /^double angdist(const coordinate_t &a, const coordinate_t &b) {$/;" f
+angdist mb_angdist.cpp /^double angdist(double r1, double d1, double r2, double d2) {$/;" f
+app mb_splitter.cpp /^DB_APP app;$/;" v
+app splitter.cpp /^DB_APP app;$/;" v
+atnight mb_splitter.cpp /^int atnight;$/;" v
+atnight splitter.cpp /^int atnight;$/;" v
+beam mb_splitter.cpp /^int beam;$/;" v
+bin_data mb_wufiles.cpp /^std::vector<std::vector<unsigned char> > bin_data;$/;" v
+bin_data wufiles.cpp /^static std::vector<unsigned char> bin_data[NSTRIPS];$/;" v file:
+boinc_config mb_splitter.cpp /^SCHED_CONFIG boinc_config;$/;" v
+boinc_config splitter.cpp /^SCHED_CONFIG boinc_config;$/;" v
+buffer_pos mb_splittypes.h /^typedef struct buffer_pos {$/;" s
+buffer_pos splittypes.h /^typedef struct buffer_pos {$/;" s
+buffer_pos_t mb_splittypes.h /^} buffer_pos_t;$/;" t typeref:struct:buffer_pos
+buffer_pos_t splittypes.h /^} buffer_pos_t;$/;" t typeref:struct:buffer_pos
+byte splittypes.h /^ long byte;$/;" m struct:buffer_pos
+c_im fftw.h 57;" d
+c_re fftw.h 56;" d
+cdesc fftw.h /^ const fftw_codelet_desc *cdesc;$/;" m struct:fftw_twiddle_struct
+cdesc fftw.h /^ fftw_codelet_desc *cdesc;$/;" m struct:fftw_rader_data_struct
+centerfreq mb_splittypes.h /^ double centerfreq,samplerate;$/;" m struct:tapeheader
+centerfreq splittypes.h /^ double centerfreq,samplerate;$/;" m struct:tapeheader
+check_for_halt mb_splitter.cpp /^int check_for_halt() {$/;" f
+check_for_halt splitter.cpp /^int check_for_halt() {$/;" f
+check_free_disk_space mb_splitter.cpp /^int check_free_disk_space() {$/;" f
+check_free_disk_space splitter.cpp /^int check_free_disk_space() {$/;" f
+cleanup mb_splitter.cpp /^void cleanup(void) {$/;" f
+cleanup splitter.cpp /^void cleanup(void) {$/;" f
+cmap_interp cmap_interp.cpp /^coordinate_t cmap_interp(std::map<seti_time,coordinate_t> &map, seti_time &t) {$/;" f
+codelet fftw.h /^ fftw_generic_codelet *codelet;$/;" m struct:fftw_plan_node_struct::__anon5::__anon8
+codelet fftw.h /^ fftw_hc2hc_codelet *codelet;$/;" m struct:fftw_plan_node_struct::__anon5::__anon12
+codelet fftw.h /^ fftw_hc2real_codelet *codelet;$/;" m struct:fftw_plan_node_struct::__anon5::__anon11
+codelet fftw.h /^ fftw_notw_codelet *codelet;$/;" m struct:fftw_plan_node_struct::__anon5::__anon6
+codelet fftw.h /^ fftw_rader_codelet *codelet;$/;" m struct:fftw_plan_node_struct::__anon5::__anon9
+codelet fftw.h /^ fftw_real2hc_codelet *codelet;$/;" m struct:fftw_plan_node_struct::__anon5::__anon10
+codelet fftw.h /^ fftw_rgeneric_codelet *codelet;$/;" m struct:fftw_plan_node_struct::__anon5::__anon13
+codelet fftw.h /^ fftw_twiddle_codelet *codelet;$/;" m struct:fftw_plan_node_struct::__anon5::__anon7
+codelet fftw.h /^ void (*codelet) (); \/* pointer to the codelet itself *\/$/;" m struct:__anon4
+codelet_desc fftw.h /^ const fftw_codelet_desc *codelet_desc;$/;" m struct:fftw_plan_node_struct::__anon5::__anon10
+codelet_desc fftw.h /^ const fftw_codelet_desc *codelet_desc;$/;" m struct:fftw_plan_node_struct::__anon5::__anon11
+codelet_desc fftw.h /^ const fftw_codelet_desc *codelet_desc;$/;" m struct:fftw_plan_node_struct::__anon5::__anon12
+codelet_desc fftw.h /^ const fftw_codelet_desc *codelet_desc;$/;" m struct:fftw_plan_node_struct::__anon5::__anon6
+codelet_desc fftw.h /^ const fftw_codelet_desc *codelet_desc;$/;" m struct:fftw_plan_node_struct::__anon5::__anon7
+coord_history mb_splitter.cpp /^std::map<seti_time,coordinate_t> coord_history;$/;" v
+cost fftw.h /^ double cost;$/;" m struct:fftw_plan_struct
+cprint mb_splitter.cpp /^void cprint(char *p) {$/;" f
+cprint splitter.cpp /^void cprint(char *p) {$/;" f
+current_record readtape.cpp /^int current_record;$/;" v
+databuf dotransform.cpp /^float databuf[FFT_LEN*2];$/;" v
+dataclass mb_splitter.cpp /^int dataclass;$/;" v
+dataclass splitter.cpp /^int dataclass;$/;" v
+dataseq mb_splittypes.h /^ unsigned long dataseq;$/;" m struct:tapeheader
+dataseq splittypes.h /^ unsigned long dataseq;$/;" m struct:tapeheader
+daynames writeheader.cpp /^char *daynames[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};$/;" v
+delbuffer makebufs.cpp /^void delbuffer(void) {$/;" f
+delbuffer_sig makebufs.cpp /^void delbuffer_sig(int i) {$/;" f
+dir fftw.h /^ fftw_direction dir;$/;" m struct:fftw_plan_node_struct::__anon5::__anon12
+dir fftw.h /^ fftw_direction dir;$/;" m struct:fftw_plan_node_struct::__anon5::__anon13
+dir fftw.h /^ fftw_direction dir; \/* direction *\/$/;" m struct:__anon4
+dir fftw.h /^ fftw_direction dir;$/;" m struct:__anon14
+dir fftw.h /^ fftw_direction dir;$/;" m struct:fftw_plan_struct
+do_polyphase mb_polyphase.cpp /^void do_polyphase(buffer_pos_t *start_of_wu, buffer_pos_t *end_of_wu) {$/;" f
+do_polyphase polyphase.cpp /^void do_polyphase(buffer_pos_t *start_of_wu, buffer_pos_t *end_of_wu) {$/;" f
+do_transform dotransform.cpp /^void do_transform(buffer_pos_t *start_of_wu, buffer_pos_t *end_of_wu) {$/;" f
+do_transform mb_dotransform.cpp /^void do_transform(std::vector<dr2_compact_block_t> &tapebuffer) {$/;" f
+end_of_wu mb_splitter.cpp /^buffer_pos_t start_of_wu,end_of_wu; \/* position of start and end of wu in$/;" v
+end_of_wu splitter.cpp /^buffer_pos_t start_of_wu,end_of_wu; \/* position of start and end of wu in$/;" v
+errorlog mb_splitter.cpp /^FILE *wulog,*errorlog;$/;" v
+errorlog splitter.cpp /^FILE *wulog,*errorlog;$/;" v
+f_data mb_polyphase.cpp /^float *f_data;$/;" v
+f_data polyphase.cpp /^float *f_data;$/;" v
+fftw_codelet_desc fftw.h /^} fftw_codelet_desc;$/;" t typeref:struct:__anon4
+fftw_complex fftw.h /^} fftw_complex;$/;" t typeref:struct:__anon1
+fftw_die_type_function fftw.h /^typedef void (*fftw_die_type_function) (const char *errString);$/;" t
+fftw_direction fftw.h /^} fftw_direction;$/;" t typeref:enum:__anon2
+fftw_free_type_function fftw.h /^typedef void (*fftw_free_type_function) (void *p);$/;" t
+fftw_generic_codelet fftw.h /^typedef void (fftw_generic_codelet) $/;" t
+fftw_hc2hc_codelet fftw.h /^typedef void (fftw_hc2hc_codelet)$/;" t
+fftw_hc2real_codelet fftw.h /^typedef void (fftw_hc2real_codelet)$/;" t
+fftw_malloc_type_function fftw.h /^typedef void *(*fftw_malloc_type_function) (size_t n);$/;" t
+fftw_node_type fftw.h /^enum fftw_node_type {$/;" g
+fftw_notw_codelet fftw.h /^typedef void (fftw_notw_codelet) $/;" t
+fftw_plan fftw.h /^typedef struct fftw_plan_struct *fftw_plan;$/;" t typeref:struct:fftw_plan_struct
+fftw_plan_node fftw.h /^} fftw_plan_node;$/;" t typeref:struct:fftw_plan_node_struct
+fftw_plan_node_struct fftw.h /^typedef struct fftw_plan_node_struct {$/;" s
+fftw_plan_struct fftw.h /^struct fftw_plan_struct {$/;" s
+fftw_rader_codelet fftw.h /^typedef void (fftw_rader_codelet) $/;" t
+fftw_rader_data fftw.h /^} fftw_rader_data;$/;" t typeref:struct:fftw_rader_data_struct
+fftw_rader_data_struct fftw.h /^typedef struct fftw_rader_data_struct {$/;" s
+fftw_real fftw.h /^typedef double fftw_real;$/;" t
+fftw_real fftw.h /^typedef float fftw_real;$/;" t
+fftw_real2hc_codelet fftw.h /^typedef void (fftw_real2hc_codelet)$/;" t
+fftw_rgeneric_codelet fftw.h /^typedef void (fftw_rgeneric_codelet)$/;" t
+fftw_status fftw.h /^} fftw_status;$/;" t typeref:enum:__anon3
+fftw_twiddle fftw.h /^} fftw_twiddle;$/;" t typeref:struct:fftw_twiddle_struct
+fftw_twiddle_codelet fftw.h /^typedef void (fftw_twiddle_codelet)$/;" t
+fftw_twiddle_struct fftw.h /^typedef struct fftw_twiddle_struct {$/;" s
+fftwnd_data fftw.h /^} fftwnd_data;$/;" t typeref:struct:__anon14
+fftwnd_plan fftw.h /^typedef fftwnd_data *fftwnd_plan;$/;" t
+filecopy mb_wufiles.cpp /^int filecopy(char *oldname,char *newname) {$/;" f
+filecopy wufiles.cpp /^int filecopy(char *oldname,char *newname) {$/;" f
+fill_tape_buffer readtape.cpp /^int fill_tape_buffer(unsigned char *buffer, int n_records) {$/;" f
+filter_i mb_polyphase.cpp /^double *filter_r, *filter_i;$/;" v
+filter_i polyphase.cpp /^double *filter_r, *filter_i;$/;" v
+filter_r mb_polyphase.cpp /^double *filter_r, *filter_i;$/;" v
+filter_r polyphase.cpp /^double *filter_r, *filter_i;$/;" v
+filter_window mb_splitter.cpp /^int filter_window = 0;$/;" v
+filter_window splitter.cpp /^int filter_window = 0;$/;" v
+flags fftw.h /^ int flags;$/;" m struct:fftw_plan_struct
+flags fftw.h /^ int p, flags, refcount;$/;" m struct:fftw_rader_data_struct
+four1 four1.cpp /^void four1(float data[], unsigned long nn, int isign) {$/;" f
+frame mb_splittypes.h /^ int frame;$/;" m struct:buffer_pos
+frame splittypes.h /^ int frame;$/;" m struct:buffer_pos
+frameseq mb_splittypes.h /^ unsigned long frameseq;$/;" m struct:tapeheader
+frameseq splittypes.h /^ unsigned long frameseq;$/;" m struct:tapeheader
+g fftw.h /^ int g, ginv;$/;" m struct:fftw_rader_data_struct
+generic fftw.h /^ } generic;$/;" m union:fftw_plan_node_struct::__anon5 typeref:struct:fftw_plan_node_struct::__anon5::__anon8
+get_last_block db_fns.cpp /^int get_last_block(tapeheader_t *tapeheader) {$/;" f
+ginv fftw.h /^ int g, ginv;$/;" m struct:fftw_rader_data_struct
+gregorian mb_splitter.cpp /^int gregorian;$/;" v
+gregorian splitter.cpp /^int gregorian;$/;" v
+hc2hc fftw.h /^ } hc2hc;$/;" m union:fftw_plan_node_struct::__anon5 typeref:struct:fftw_plan_node_struct::__anon5::__anon12
+hc2real fftw.h /^ } hc2real;$/;" m union:fftw_plan_node_struct::__anon5 typeref:struct:fftw_plan_node_struct::__anon5::__anon11
+header randomdata.cpp /^char header[HEADER_SIZE];$/;" v
+header squarewave.cpp /^char header[HEADER_SIZE];$/;" v
+horz_to_equatorial coordcvt.cpp /^void horz_to_equatorial(double alt, double azimuth, double lsthour,$/;" f namespace:SPLITTER
+hr_min_sec hr_min_sec.cpp /^char* hr_min_sec (double x) {$/;" f
+im fftw.h /^ fftw_real re, im;$/;" m struct:__anon1
+is_in_place fftw.h /^ int is_in_place; \/* 1 if for in-place FFTs, 0 otherwise *\/$/;" m struct:__anon14
+is_tape readtape.cpp /^int is_tape;$/;" v
+iters mb_splitter.cpp /^int iters=-1;$/;" v
+iters splitter.cpp /^int iters=-1;$/;" v
+jd_to_lmst coordcvt.cpp /^double jd_to_lmst(double jd, double longitude) {$/;" f namespace:SPLITTER
+key mb_splitter.cpp /^R_RSA_PRIVATE_KEY key;$/;" v
+key splitter.cpp /^R_RSA_PRIVATE_KEY key;$/;" v
+main mb_splitter.cpp /^int main(int argc, char *argv[]) {$/;" f
+main randomdata.cpp /^int main(void) {$/;" f
+main splitter.cpp /^int main(int argc, char *argv[]) {$/;" f
+main squarewave.cpp /^int main(void) {$/;" f
+make_FIR mb_polyphase.cpp /^void make_FIR (int n_points, int M, int window, double *output) {$/;" f
+make_FIR polyphase.cpp /^void make_FIR (int n_points, int M, int window, double *output) {$/;" f
+make_wu_headers mb_wufiles.cpp /^int make_wu_headers(std::vector<dr2_compact_block_t> &tapebuffer, telescope_id$/;" f
+make_wu_headers wufiles.cpp /^int make_wu_headers(tapeheader_t tapeheader[],workunit wuheader[],$/;" f
+makebuffers makebufs.cpp /^void makebuffers(unsigned char **tapebuffer) {$/;" f
+max_wus_ondisk mb_splitter.cpp /^int max_wus_ondisk=MAX_WUS_ONDISK;$/;" v
+max_wus_ondisk splitter.cpp /^int max_wus_ondisk=MAX_WUS_ONDISK;$/;" v
+message mb_message.cpp /^void message(char *msg) {$/;" f
+message message.cpp /^void message(char *msg) {$/;" f
+minvfsbuf mb_splitter.cpp /^unsigned long minvfsbuf=-1;$/;" v
+minvfsbuf splitter.cpp /^unsigned long minvfsbuf=-1;$/;" v
+missed mb_splittypes.h /^ int missed;$/;" m struct:tapeheader
+missed splittypes.h /^ int missed;$/;" m struct:tapeheader
+monthnames writeheader.cpp /^char *monthnames[]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep"$/;" v
+n fftw.h /^ int *n; \/*$/;" m struct:__anon14
+n fftw.h /^ int n;$/;" m struct:fftw_plan_struct
+n fftw.h /^ int n;$/;" m struct:fftw_twiddle_struct
+n_after fftw.h /^ int *n_after; \/* n_after[i] = product of n[j] for j > i *\/$/;" m struct:__anon14
+n_before fftw.h /^ int *n_before; \/*$/;" m struct:__anon14
+name fftw.h /^ const char *name; \/* name of the codelet *\/$/;" m struct:__anon4
+name mb_splittypes.h /^ char name[36];$/;" m struct:tapeheader
+name splittypes.h /^ char name[36];$/;" m struct:tapeheader
+nbuffers fftw.h /^ int nbuffers, nwork;$/;" m struct:__anon14
+next fftw.h /^ struct fftw_plan_struct *next;$/;" m struct:fftw_plan_struct typeref:struct:fftw_plan_struct::fftw_plan_struct
+next fftw.h /^ struct fftw_rader_data_struct *next;$/;" m struct:fftw_rader_data_struct typeref:struct:fftw_rader_data_struct::fftw_rader_data_struct
+next fftw.h /^ struct fftw_twiddle_struct *next;$/;" m struct:fftw_twiddle_struct typeref:struct:fftw_twiddle_struct::fftw_twiddle_struct
+nodb mb_splitter.cpp /^int nodb;$/;" v
+nodb splitter.cpp /^int nodb;$/;" v
+nodeu fftw.h /^ } nodeu;$/;" m struct:fftw_plan_node_struct typeref:union:fftw_plan_node_struct::__anon5
+noencode mb_splitter.cpp /^int noencode;$/;" v
+noencode splitter.cpp /^int noencode;$/;" v
+norewind mb_splitter.cpp /^int norewind;$/;" v
+norewind splitter.cpp /^int norewind;$/;" v
+notw fftw.h /^ } notw;$/;" m union:fftw_plan_node_struct::__anon5 typeref:struct:fftw_plan_node_struct::__anon5::__anon6
+ntwiddle fftw.h /^ int ntwiddle; \/* number of twiddle factors *\/$/;" m struct:__anon4
+numdiskbufs mb_splittypes.h /^ int numdiskbufs;$/;" m struct:tapeheader
+numdiskbufs splittypes.h /^ int numdiskbufs;$/;" m struct:tapeheader
+numringbufs mb_splittypes.h /^ int numringbufs;$/;" m struct:tapeheader
+numringbufs splittypes.h /^ int numringbufs;$/;" m struct:tapeheader
+nwork fftw.h /^ int nbuffers, nwork;$/;" m struct:__anon14
+obuf_pos dotransform.cpp /^int obuf_pos; \/* Tracks current postition in the output buffers *\/$/;" v
+obuf_pos mb_dotransform.cpp /^int obuf_pos; \/* Tracks current postition in the output buffers *\/$/;" v
+offset mb_splittypes.h /^ long offset;$/;" m struct:buffer_pos
+omega fftw.h /^ fftw_complex *omega;$/;" m struct:fftw_rader_data_struct
+open_tape_device readtape.cpp /^int open_tape_device(char *device) {$/;" f
+output_buf dotransform.cpp /^unsigned char output_buf[NSTRIPS][SAMPLES_PER_OBUF]; $/;" v
+output_samples dotransform.cpp /^void output_samples(float *data, int i, int buf_pos) {$/;" f
+output_samples mb_dotransform.cpp /^void output_samples(float *data, int i, int buf_pos) {$/;" f
+output_xml mb_splitter.cpp /^int output_xml;$/;" v
+output_xml splitter.cpp /^int output_xml;$/;" v
+p fftw.h /^ int p, flags, refcount;$/;" m struct:fftw_rader_data_struct
+parse_tape_headers readheader.cpp /^int parse_tape_headers(unsigned char *tapebuffer, tapeheader_t *tapeheaders) {$/;" f
+plan fftw.h /^ struct fftw_plan_struct *plan;$/;" m struct:fftw_rader_data_struct typeref:struct:fftw_rader_data_struct::fftw_plan_struct
+plans fftw.h /^ fftw_plan *plans; \/* 1d fftw plans for each dimension *\/$/;" m struct:__anon14
+pol mb_splitter.cpp /^int pol;$/;" v
+polyphase mb_splitter.cpp /^int polyphase;$/;" v
+polyphase splitter.cpp /^int polyphase;$/;" v
+polyphase_seg mb_polyphase.cpp /^void polyphase_seg(float* data) {$/;" f
+polyphase_seg polyphase.cpp /^void polyphase_seg(float* data) {$/;" f
+process_command_line mb_splitter.cpp /^int process_command_line(int argc, char *argv[],char **tape_device,$/;" f
+process_command_line splitter.cpp /^int process_command_line(int argc, char *argv[],char **tape_device,$/;" f
+process_seg dotransform.cpp /^void process_seg(float* data) {$/;" f
+process_seg mb_dotransform.cpp /^void process_seg(std::vector<complex<signed char> > &data,int offset) {$/;" f
+projectdir mb_splitter.cpp /^char * projectdir = NULL;$/;" v
+projectdir splitter.cpp /^char * projectdir = NULL;$/;" v
+rader fftw.h /^ } rader;$/;" m union:fftw_plan_node_struct::__anon5 typeref:struct:fftw_plan_node_struct::__anon5::__anon9
+rader_data fftw.h /^ fftw_rader_data *rader_data;$/;" m struct:fftw_plan_node_struct::__anon5::__anon9
+randn mb_dotransform.cpp /^float randn() {$/;" f
+randu mb_dotransform.cpp /^float randu() {$/;" f
+rank fftw.h /^ int rank; \/* $/;" m struct:__anon14
+rcdtype mb_splittypes.h /^ int rcdtype;$/;" m struct:tapeheader
+rcdtype splittypes.h /^ int rcdtype;$/;" m struct:tapeheader
+rcvr mb_splitter.cpp /^receiver_config rcvr;$/;" v
+re fftw.h /^ fftw_real re, im;$/;" m struct:__anon1
+read_checkpoint readtape.cpp /^int read_checkpoint() {$/;" f
+read_tape_header readheader.cpp /^int read_tape_header(char *buffer, tapeheader_t *header)$/;" f
+real2hc fftw.h /^ } real2hc;$/;" m union:fftw_plan_node_struct::__anon5 typeref:struct:fftw_plan_node_struct::__anon5::__anon10
+records_in_buffer splitter.cpp /^int records_in_buffer;$/;" v
+recurse fftw.h /^ struct fftw_plan_node_struct *recurse;$/;" m struct:fftw_plan_node_struct::__anon5::__anon12 typeref:struct:fftw_plan_node_struct::__anon5::__anon12::fftw_plan_node_struct
+recurse fftw.h /^ struct fftw_plan_node_struct *recurse;$/;" m struct:fftw_plan_node_struct::__anon5::__anon13 typeref:struct:fftw_plan_node_struct::__anon5::__anon13::fftw_plan_node_struct
+recurse fftw.h /^ struct fftw_plan_node_struct *recurse;$/;" m struct:fftw_plan_node_struct::__anon5::__anon7 typeref:struct:fftw_plan_node_struct::__anon5::__anon7::fftw_plan_node_struct
+recurse fftw.h /^ struct fftw_plan_node_struct *recurse;$/;" m struct:fftw_plan_node_struct::__anon5::__anon8 typeref:struct:fftw_plan_node_struct::__anon5::__anon8::fftw_plan_node_struct
+recurse fftw.h /^ struct fftw_plan_node_struct *recurse;$/;" m struct:fftw_plan_node_struct::__anon5::__anon9 typeref:struct:fftw_plan_node_struct::__anon5::__anon9::fftw_plan_node_struct
+refcnt fftw.h /^ int refcnt;$/;" m struct:fftw_plan_node_struct
+refcnt fftw.h /^ int refcnt;$/;" m struct:fftw_plan_struct
+refcnt fftw.h /^ int refcnt;$/;" m struct:fftw_twiddle_struct
+refcount fftw.h /^ int p, flags, refcount;$/;" m struct:fftw_rader_data_struct
+rename_wu_files mb_wufiles.cpp /^void rename_wu_files() {$/;" f
+rename_wu_files wufiles.cpp /^void rename_wu_files() {$/;" f
+result_template mb_splitter.cpp /^const char *result_template=$/;" v
+result_template splitter.cpp /^const char *result_template=$/;" v
+result_template_filename mb_splitter.cpp /^char result_template_filename[1024];$/;" v
+result_template_filename splitter.cpp /^char result_template_filename[1024];$/;" v
+result_template_filename_id mb_splitter.cpp /^const char *result_template_filename_id = "result_0.xml";$/;" v
+result_template_filename_id splitter.cpp /^const char *result_template_filename_id = "result_0.xml";$/;" v
+result_template_filepath mb_splitter.cpp /^char result_template_filepath[1024];$/;" v
+result_template_filepath splitter.cpp /^char result_template_filepath[1024];$/;" v
+resumetape mb_splitter.cpp /^int resumetape;$/;" v
+resumetape splitter.cpp /^int resumetape;$/;" v
+rgeneric fftw.h /^ } rgeneric;$/;" m union:fftw_plan_node_struct::__anon5 typeref:struct:fftw_plan_node_struct::__anon5::__anon13
+root fftw.h /^ fftw_plan_node *root;$/;" m struct:fftw_plan_struct
+sah_config mb_splitter.cpp /^APP_CONFIG sah_config;$/;" v
+sah_config splitter.cpp /^APP_CONFIG sah_config;$/;" v
+samplerate mb_splittypes.h /^ double centerfreq,samplerate;$/;" m struct:tapeheader
+samplerate splittypes.h /^ double centerfreq,samplerate;$/;" m struct:tapeheader
+select_record readtape.cpp /^int select_record(int record_number) {$/;" f
+seqno mb_splitter.cpp /^int seqno;$/;" v
+seqno splitter.cpp /^int seqno;$/;" v
+signature fftw.h /^ int signature; \/* unique id *\/$/;" m struct:__anon4
+size fftw.h /^ int size;$/;" m struct:fftw_plan_node_struct::__anon5::__anon10
+size fftw.h /^ int size;$/;" m struct:fftw_plan_node_struct::__anon5::__anon11
+size fftw.h /^ int size;$/;" m struct:fftw_plan_node_struct::__anon5::__anon12
+size fftw.h /^ int size;$/;" m struct:fftw_plan_node_struct::__anon5::__anon13
+size fftw.h /^ int size;$/;" m struct:fftw_plan_node_struct::__anon5::__anon6
+size fftw.h /^ int size;$/;" m struct:fftw_plan_node_struct::__anon5::__anon7
+size fftw.h /^ int size;$/;" m struct:fftw_plan_node_struct::__anon5::__anon8
+size fftw.h /^ int size;$/;" m struct:fftw_plan_node_struct::__anon5::__anon9
+size fftw.h /^ int size; \/* size of the codelet *\/$/;" m struct:__anon4
+source mb_splittypes.h /^ int source;$/;" m struct:tapeheader
+source splittypes.h /^ int source;$/;" m struct:tapeheader
+splitter_bits_to_float dotransform.cpp /^void splitter_bits_to_float(unsigned short *raw, float *data, int nsamples) {$/;" f
+splitter_bits_to_float mb_dotransform.cpp /^void splitter_bits_to_float(unsigned short *raw, float *data, int nsamples) {$/;" f
+splitter_encode encode.cpp /^void splitter_encode(unsigned char *bin, int nbytes, FILE *f) {$/;" f
+splitter_settings mb_splitter.cpp /^settings splitter_settings;$/;" v
+st mb_splittypes.h /^ TIME st;$/;" m struct:tapeheader
+st splittypes.h /^ TIME st;$/;" m struct:tapeheader
+start_of_wu mb_splitter.cpp /^buffer_pos_t start_of_wu,end_of_wu; \/* position of start and end of wu in$/;" v
+start_of_wu splitter.cpp /^buffer_pos_t start_of_wu,end_of_wu; \/* position of start and end of wu in$/;" v
+start_time mb_splitter.cpp /^double start_time;$/;" v
+start_time splitter.cpp /^double start_time;$/;" v
+startblock mb_splitter.cpp /^int startblock;$/;" v
+startblock splitter.cpp /^int startblock;$/;" v
+stop_time mb_splitter.cpp /^double stop_time;$/;" v
+stop_time splitter.cpp /^double stop_time;$/;" v
+tape_busy readtape.cpp /^int tape_busy() {$/;" f
+tape_eject readtape.cpp /^int tape_eject() {$/;" f
+tape_fd readtape.cpp /^static int tape_fd;$/;" v file:
+tape_info readtape.cpp /^static tape tape_info;$/;" v file:
+tape_read_record readtape.cpp /^int tape_read_record(char *buffer) {$/;" f
+tape_rewind readtape.cpp /^int tape_rewind() {$/;" f
+tape_status readtape.cpp /^struct mtget tape_status;$/;" v typeref:struct:mtget
+tape_struct db_fns.cpp /^static tape tape_struct;$/;" v file:
+tapebuffd makebufs.cpp /^int tapebuffd;$/;" v
+tapebuffer mb_splitter.cpp /^std::vector<dr2_compact_block_t> tapebuffer;$/;" v
+tapebuffer splitter.cpp /^unsigned char *tapebuffer; \/* A buffer for a tape section *\/$/;" v
+tapebufname makebufs.cpp /^char tapebufname[30];$/;" v
+tapeheader mb_splittypes.h /^typedef struct tapeheader {$/;" s
+tapeheader splittypes.h /^typedef struct tapeheader {$/;" s
+tapeheader_t mb_splittypes.h /^} tapeheader_t;$/;" t typeref:struct:tapeheader
+tapeheader_t splittypes.h /^} tapeheader_t;$/;" t typeref:struct:tapeheader
+tapeheaders splitter.cpp /^tapeheader_t tapeheaders[TAPE_FRAMES_IN_BUFFER];$/;" v
+telstr mb_splittypes.h /^ SCOPE_STRING telstr;$/;" m struct:tapeheader
+telstr splittypes.h /^ SCOPE_STRING telstr;$/;" m struct:tapeheader
+telstr_coord_convert coordcvt.cpp /^void telstr_coord_convert(SCOPE_STRING *telstr, double lat, double lon) {$/;" f
+trigger_file_path mb_splitter.cpp /^char trigger_file_path[1024]="\/disks\/setifiler1\/wutape\/tapedir\/splitter_stop";$/;" v
+trigger_file_path splitter.cpp /^char trigger_file_path[1024]="\/disks\/setifiler1\/wutape\/tapedir\/splitter_stop";$/;" v
+tw fftw.h /^ fftw_twiddle *tw;$/;" m struct:fftw_plan_node_struct::__anon5::__anon12
+tw fftw.h /^ fftw_twiddle *tw;$/;" m struct:fftw_plan_node_struct::__anon5::__anon13
+tw fftw.h /^ fftw_twiddle *tw;$/;" m struct:fftw_plan_node_struct::__anon5::__anon7
+tw fftw.h /^ fftw_twiddle *tw;$/;" m struct:fftw_plan_node_struct::__anon5::__anon8
+tw fftw.h /^ fftw_twiddle *tw;$/;" m struct:fftw_plan_node_struct::__anon5::__anon9
+twarray fftw.h /^ fftw_complex *twarray;$/;" m struct:fftw_twiddle_struct
+twiddle fftw.h /^ } twiddle;$/;" m union:fftw_plan_node_struct::__anon5 typeref:struct:fftw_plan_node_struct::__anon5::__anon7
+twiddle_order fftw.h /^ const int *twiddle_order; \/* $/;" m struct:__anon4
+type fftw.h /^ enum fftw_node_type type; \/* TWIDDLE or NO_TWIDDLE *\/$/;" m struct:__anon4 typeref:enum:__anon4::fftw_node_type
+type fftw.h /^ enum fftw_node_type type;$/;" m struct:fftw_plan_node_struct typeref:enum:fftw_plan_node_struct::fftw_node_type
+update_checkpoint readtape.cpp /^static void update_checkpoint() {$/;" f file:
+useanalysiscfgid mb_splitter.cpp /^int useanalysiscfgid = 0;$/;" v
+usereceivercfgid mb_splitter.cpp /^int usereceivercfgid = 0;$/;" v
+userecordercfgid mb_splitter.cpp /^int userecordercfgid = 0;$/;" v
+usesplittercfgid mb_splitter.cpp /^int usesplittercfgid = 0;$/;" v
+valid_run mb_validrun.cpp /^bool valid_run(std::vector<dr2_compact_block_t> &tapebuffer) {$/;" f
+valid_run validrun.cpp /^int valid_run(tapeheader_t tapeheader[],buffer_pos_t *start_of_wu, $/;" f
+version mb_splittypes.h /^ char version[16];$/;" m struct:tapeheader
+version splittypes.h /^ char version[16];$/;" m struct:tapeheader
+wait_for_db_wus_ondisk mb_splitter.cpp /^int wait_for_db_wus_ondisk() {$/;" f
+wait_for_db_wus_ondisk splitter.cpp /^int wait_for_db_wus_ondisk() {$/;" f
+wait_until_night mb_splitter.cpp /^int wait_until_night() {$/;" f
+wait_until_night splitter.cpp /^int wait_until_night() {$/;" f
+wd mb_splitter.cpp /^char wd[1024];$/;" v
+wd splitter.cpp /^char wd[1024];$/;" v
+wisdom_signature fftw.h /^ int wisdom_signature;$/;" m struct:fftw_plan_struct
+wisdom_type fftw.h /^ enum fftw_node_type wisdom_type;$/;" m struct:fftw_plan_struct typeref:enum:fftw_plan_struct::fftw_node_type
+work fftw.h /^ fftw_complex *work; \/* $/;" m struct:__anon14
+write_tape_header writeheader.cpp /^int write_tape_header(char *buffer, tapeheader_t *header) {$/;" f
+write_wufile_blocks mb_wufiles.cpp /^void write_wufile_blocks(int nbytes) {$/;" f
+write_wufile_blocks wufiles.cpp /^void write_wufile_blocks(int nbytes) {$/;" f
+wu_database_id mb_wufiles.cpp /^std::vector<long long> wu_database_id;$/;" v
+wu_database_id wufiles.cpp /^int wu_database_id[NSTRIPS];$/;" v
+wu_template mb_splitter.cpp /^const char *wu_template=$/;" v
+wu_template splitter.cpp /^const char *wu_template=$/;" v
+wu_template_filename mb_splitter.cpp /^char wu_template_filename[1024];$/;" v
+wu_template_filename splitter.cpp /^char wu_template_filename[1024];$/;" v
+wu_template_filename_id mb_splitter.cpp /^const char *wu_template_filename_id = "wu_0.xml";$/;" v
+wu_template_filename_id splitter.cpp /^const char *wu_template_filename_id = "wu_0.xml";$/;" v
+wuheaders mb_splitter.cpp /^std::vector<workunit> wuheaders;$/;" v
+wuheaders splitter.cpp /^workunit wuheaders[NSTRIPS];$/;" v
+wulog mb_splitter.cpp /^FILE *wulog,*errorlog;$/;" v
+wulog splitter.cpp /^FILE *wulog,*errorlog;$/;" v
diff --git a/gbt_splitter/tools/disksplitter b/gbt_splitter/tools/disksplitter
new file mode 100755
index 0000000..a4bc323
--- /dev/null
+++ b/gbt_splitter/tools/disksplitter
@@ -0,0 +1,121 @@
+#! /bin/tcsh -x
+
+set PATH=/opt/misc:/opt/misc/bin:/usr/ccs/bin:/usr/openwin/bin:/usr/openwin/bin/xview:/usr/lang:/usr/ucb:/bin:/usr/bin:/usr/local/bin:/usr/hosts:/usr/bin/X11:/usr/casual/sparc:/usr/etc:/usr/local/lib/tex/bin:/usr/local/lib/frame/bin:/disks/asimov/a/apps/informix/bin:.:/disks/albert/d/office/bin:/usr/ucb:/disks/albert/e/users/eurd/data_analysis/bin:/usr/local/lib/g++-include.bak:/disks/siren/a/users/seti/s4/siren/bin:/disks/albert/d/orfeus:/disks/albert/d/chips:/disks/asimov/a/apps/inform [...]
+# export PATH
+set LD_LIBRARY_PATH=/usr/lib/X11:/usr/openwin/lib:/usr/lib:/lib:/disks/islay/a/users/korpela/bin/lib:/disks/asimov/a/apps/informix/lib:/disks/asimov/a/apps/informix/lib/esql
+# export LD_LIBRARY_PATH
+set INFORMIXDIR=/disks/asimov/a/apps/informix
+# export INFORMIXDIR
+set INFORMIXSERVER=ejk_tcp
+# export INFORMIXSERVER
+
+set SPLIT_PROG_LOC=/disks/milkyway/a/users/anderson/seti/splitter/bin/
+set SPLIT_PROG_NAME=splitter
+set SPLIT_LOG_LOC=/disks/milkyway/a/users/anderson/seti/sethi/hi_tape_logs/
+# set HI_TAPE_DIR=/disks/philmor/a/users/eheien/hitest/
+set SPLIT_TAPE_DIR=/disks/setifiler1/wutape/tapedir/
+set SPLIT_SUFFIX=.split
+set HIDONE_SUFFIX=.hidone
+set SPLITDONE_SUFFIX=.splitdone
+set EMAIL_LIST="jeffc at ssl.berkeley.edu mattl at ssl.berkeley.edu"
+set FOUND_FILE=0
+set HOST=`hostname`
+set SPLIT_HALT_MSG=splitter_stop
+
+# Check to see if this machine is already running the splitter program
+set PROG_RUNNING=`/usr/ucb/ps -auxww | grep "$SPLIT_PROG_NAME" | grep -v "disksplitter" | wc | awk '{print $1}'`
+echo "$PROG_RUNNING"
+if( $PROG_RUNNING > 1 ) then
+ echo "Splitter is already running on this machine. Quitting."
+ exit
+endif
+
+# Get rid of all .split files here with HOSTNAME in them(?)
+
+while ( ! -f $SPLIT_TAPE_DIR$SPLIT_HALT_MSG )
+
+set FOUND_FILE=0
+cd $SPLIT_TAPE_DIR
+
+set FILE_LIST=`ls . | grep ".tape" | grep -v "done" | grep -v "reading" | grep -v "hi" | grep -v "msg" | grep -v "split"`
+
+if( -z "$FILE_LIST" ) then
+ exit
+endif
+
+foreach file ($FILE_LIST)
+ if ( $FOUND_FILE == 0 && ! -f $file$SPLITDONE_SUFFIX ) then
+ if( -f $file$SPLIT_SUFFIX ) then
+ set FOUND_FILE=0
+ else
+ echo $HOST > $file$SPLIT_SUFFIX
+ set TAPE_FILE=$file
+ set SPLIT_FILE=$SPLIT_TAPE_DIR$file
+ set SPLIT_MARK_FILE=$SPLIT_TAPE_DIR$file$SPLIT_SUFFIX
+ set HI_DONE_FILE=$SPLIT_TAPE_DIR$file$HIDONE_SUFFIX
+ set SPLIT_DONE_FILE=$SPLIT_TAPE_DIR$file$SPLITDONE_SUFFIX
+ set FOUND_FILE=1
+ endif
+ endif
+end
+
+cd /mydisks/a/servers/splitter/
+/bin/rm -f error.log rcd.chk
+touch error.log
+touch rcd.chk
+
+if ( $FOUND_FILE == 0 ) then
+# echo "" | /usr/ucb/mail -s"no more splitter tape files" $EMAIL_LIST
+ exit
+else
+ if( -f /disks/milkyway/a/users/anderson/seti/watchdogs/go_spliiter ) then
+ /bin/rm -f wu_inbox/.*
+#set START_MSG=`echo "Splitter is starting on tape" $SPLIT_FILE "on" $HOST`
+ cat error.log rcd.chk | /usr/ucb/mail -s""$HOST" splitter starting" $EMAIL_LIST
+ /bin/nice $SPLIT_PROG_LOC$SPLIT_PROG_NAME $SPLIT_FILE $1 -resume >>& splitterlog
+ set TEMP=`grep -i "end" error.log`
+ if( "$TEMP" != "" ) then
+ sleep 60 # wait for it to finish moving the files from wu_inbox
+ cat error.log rcd.chk | /usr/ucb/mail -s""$HOST" splitter finished" $EMAIL_LIST
+ /bin/rm -f error.log rcd.chk
+ /bin/rm -f wu_inbox/.*
+ /bin/rm -f $SPLIT_MARK_FILE
+ if( -f $HI_DONE_FILE ) then
+ /bin/rm -f $HI_DONE_FILE
+ /bin/rm -f `cd $SPLIT_TAPE_DIR; ls -l | grep $TAPE_FILE | awk '{print $NF}'`
+ /bin/rm -f $SPLIT_FILE
+ else
+ touch -f $SPLIT_DONE_FILE
+ endif
+ endif
+ /bin/rm -f $SPLIT_MARK_FILE
+ exit
+ else
+ /bin/rm -f $SPLIT_MARK_FILE
+ exit
+ endif
+endif
+
+#if ( 0 == 1 ) then
+# if ( grep -i done hi_log ) then
+# cat error.log rcd.chk | /usr/ucb/mail -s"end of tape on $HOST" $EMAIL_LIST
+# touch $HI_FILE$HIDONE_SUFFIX
+# if ( -f $HI_FILE$HIDONE_SUFFIX ) then
+# unlink $SPLITFILE
+# fi
+# unlink .$SPLITFILE
+# /bin/rm error.log rcd.chk
+# /bin/rm wu_inbox/.*
+# nice -10 $SPLITTER_PROG_LOC $SPLITFILE -resume 2>> splitterlog &
+#else
+# if [ -f $MARKER$HOST ]
+# then
+# /bin/rm wu_inbox/.*
+# cat error.log rcd.chk | /usr/ucb/mail -s"restarting HI analysis on $HOST" $EMAIL_LIST
+# nice -10 $SPLITTER_PROG_LOC $SPLITFILE -resume 2>> splitterlog &
+# else
+# cat error.log rcd.chk | /usr/ucb/mail -s"hi analysis disabled on $HOST" $EMAIL_LIST
+# fi
+#endif
+end
+
diff --git a/gbt_splitter/tools/sah_splitter.sh b/gbt_splitter/tools/sah_splitter.sh
new file mode 100755
index 0000000..2ff1d34
--- /dev/null
+++ b/gbt_splitter/tools/sah_splitter.sh
@@ -0,0 +1,150 @@
+#! /bin/sh
+PATH=/opt/misc:/opt/misc/bin:/usr/ccs/bin:/usr/openwin/bin:/usr/openwin/bin/xview:/usr/lang:/usr/ucb:/bin:/usr/bin:/usr/local/bin:/usr/hosts:/usr/bin/X11:/usr/casual/sparc:/usr/etc:/usr/local/lib/tex/bin:/usr/local/lib/frame/bin:/disks/asimov/a/apps/informix/bin:.:/disks/albert/d/office/bin:/usr/ucb:/disks/albert/e/users/eurd/data_analysis/bin:/usr/local/lib/g++-include.bak:/disks/siren/a/users/seti/s4/siren/bin:/disks/albert/d/orfeus:/disks/albert/d/chips:/disks/asimov/a/apps/informix/b [...]
+export PATH
+LD_LIBRARY_PATH=/lib:/disks/asimov/a/apps/informix/lib:/disks/asimov/a/apps/informix/lib/esql::/usr/ucblib:/lib:/usr/lib:/usr/openwin/lib:/usr/ccs/lib:/usr/local/gcc/lib:/disks/asimov/a/lang/gnu/H-sparc-sun-solaris2/lib:/opt/misc/lib:/usr/local/lib:/disks/ellie/a/users/korpela/lib:/usr/dt/lib
+export LD_LIBRARY_PATH
+INFORMIXDIR=/disks/asimov/a/apps/informix/
+export INFORMIXDIR
+INFORMIXSERVER=ejk_tcp
+export INFORMIXSERVER
+S4_RECEIVER_CONFIG=/usr/local/warez/projects/s4/siren/db/ReceiverConfig.tab
+export S4_RECEIVER_CONFIG
+
+PROJECTDIR=/disks/koloth/a/inet_services/boinc_www/share/projects/sah
+SPLIT_PROG_LOC=${PROJECTDIR}/bin/
+SPLIT_PROG_NAME=sah_splitter
+SPLIT_TAPE_DIR=/disks/setifiler1/wutape/tapedir/seti_boinc_public/
+SPLIT_SUFFIX=.split
+#HIDONE_SUFFIX=.hidone
+SPLITDONE_SUFFIX=.splitdone
+EMAIL_LIST="korpela at ssl.berkeley.edu jeffc at ssl.berkeley.edu mattl at ssl.berkeley.edu davea at ssl.berkeley.edu"
+FOUND_FILE=0
+HOST=`hostname`
+SPLIT_HALT_MSG=splitter_stop
+
+# Check to see if this machine is already running the splitter program
+PROG_RUNNING=`/usr/ucb/ps -auxww | grep "$SPLIT_PROG_NAME " | grep -v grep`
+if [ ! -z "$PROG_RUNNING" ]
+then
+ echo "Splitter is already running on this machine. Quitting."
+ exit 1
+fi
+
+# Get rid of all .split files here with HOSTNAME in them(?)
+
+TAPE_FILE=
+
+# get list of all tapes in the sah classic tape directory
+cd $SPLIT_TAPE_DIR/..
+FILE_LIST=`ls *.tape`
+
+cd $SPLIT_TAPE_DIR
+
+# if no sah classic tapes then bail
+if [ -z "$FILE_LIST" ]
+then
+ exit 2
+fi
+
+# for each sah classic tape...
+for file in $FILE_LIST
+do
+ # if we have already split it...
+ if [ -f $file$SPLITDONE_SUFFIX ]
+ then
+ # ... then remove it ("it" being a hard link upward into the sah classic dir)
+ if [ -f $file ]
+ then
+ /bin/rm $file
+ fi
+ else
+ # if we are in the process of splitting it...
+ if [ -f $file$SPLIT_SUFFIX ]
+ then
+ # and are splitting it from this host... (this logic prevents one host from repeating another host's tape)
+ if grep $HOST $file$SPLIT_SUFFIX
+ then
+ # trigger to restart the split
+ /bin/rm $file$SPLIT_SUFFIX
+ fi
+ fi
+ # if a restart or a brand new tape...
+ if [ ! -f $file$SPLIT_SUFFIX ]
+ then
+ # claim it for this host (there is certainly a race condition here)
+ echo $HOST > $file$SPLIT_SUFFIX
+ ln ../$file
+ TAPE_FILE=$file
+ SPLIT_FILE=$SPLIT_TAPE_DIR$file
+ SPLIT_MARK_FILE=$SPLIT_TAPE_DIR$file$SPLIT_SUFFIX
+# HI_DONE_FILE=$SPLIT_TAPE_DIR$file$HIDONE_SUFFIX
+ SPLIT_DONE_FILE=$SPLIT_TAPE_DIR$file$SPLITDONE_SUFFIX
+ break
+ fi
+ fi
+done
+
+cd /tmp/splitter/sah
+if [ ! -d splitter ]
+then
+ mkdir splitter
+fi
+cd splitter
+if [ ! -d wu_inbox ]
+then
+ mkdir wu_inbox
+fi
+/bin/rm -f error.log rcd.chk
+touch error.log
+touch rcd.chk
+
+if [ -z "$TAPE_FILE" ]
+then
+ exit 3
+else
+ /bin/rm -f wu_inbox/.*
+ cat error.log rcd.chk | /usr/ucb/mail -s""$HOST" boinc_splitter starting" $EMAIL_LIST
+ /bin/nice $SPLIT_PROG_LOC$SPLIT_PROG_NAME $SPLIT_FILE $* -resume -projectdir=$PROJECTDIR
+ if grep -i "end" error.log >/dev/null 2>&1
+ then
+ /bin/nice $SPLIT_PROG_LOC$SPLIT_PROG_NAME $SPLIT_FILE $* -resume -projectdir=$PROJECTDIR
+ fi
+ if grep -i "end" error.log >/dev/null 2>&1
+ then
+ cat error.log rcd.chk | /usr/ucb/mail -s""$HOST" boinc_splitter finished" $EMAIL_LIST
+ /bin/rm -f error.log rcd.chk
+ /bin/rm -f wu_inbox/.*
+ /bin/rm -f $SPLIT_MARK_FILE
+ /bin/rm -f `cd $SPLIT_TAPE_DIR; ls -l | grep $TAPE_FILE | awk '{print $NF}'`
+ /bin/rm -f $SPLIT_FILE
+ touch -f $SPLIT_DONE_FILE
+ exit
+ else
+ /bin/rm -f $SPLIT_MARK_FILE
+ exit 4
+ fi
+fi
+
+#if ( 0 == 1 ) then
+# if ( grep -i done hi_log ) then
+# cat error.log rcd.chk | /usr/ucb/mail -s"end of tape on $HOST" $EMAIL_LIST
+# touch $HI_FILE$HIDONE_SUFFIX
+# if ( -f $HI_FILE$HIDONE_SUFFIX ) then
+# unlink $SPLITFILE
+# fi
+# unlink .$SPLITFILE
+# /bin/rm error.log rcd.chk
+# /bin/rm wu_inbox/.*
+# nice -10 $SPLITTER_PROG_LOC $SPLITFILE -resume 2>> splitterlog &
+#else
+# if [ -f $MARKER$HOST ]
+# then
+# /bin/rm wu_inbox/.*
+# cat error.log rcd.chk | /usr/ucb/mail -s"restarting HI analysis on $HOST" $EMAIL_LIST
+# nice -10 $SPLITTER_PROG_LOC $SPLITFILE -resume 2>> splitterlog &
+# else
+# cat error.log rcd.chk | /usr/ucb/mail -s"hi analysis disabled on $HOST" $EMAIL_LIST
+# fi
+#endif
+end
+
diff --git a/gbt_splitter/uttolst.h b/gbt_splitter/uttolst.h
new file mode 100644
index 0000000..8f29efb
--- /dev/null
+++ b/gbt_splitter/uttolst.h
@@ -0,0 +1,2 @@
+double tm_UtToLst(double ddtime, double longitude,
+ long mon, long day, long year);
diff --git a/gbt_splitter/validrun.cpp b/gbt_splitter/validrun.cpp
new file mode 100644
index 0000000..45d3854
--- /dev/null
+++ b/gbt_splitter/validrun.cpp
@@ -0,0 +1,181 @@
+/*
+ * validrun.c
+ *
+ * Functions for determining if a section of the tape buffer can be
+ * turned into a valid work unit
+ *
+ * $Id: validrun.cpp,v 1.2.4.2 2006/12/14 22:24:48 korpela Exp $
+ *
+ */
+
+#include "sah_config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <assert.h>
+#include "splitparms.h"
+#include "splittypes.h"
+#include "splitter.h"
+#include "message.h"
+
+
+int valid_run(tapeheader_t tapeheader[],buffer_pos_t *start_of_wu,
+ buffer_pos_t *end_of_wu) {
+
+ int i=0,valid=1;
+ SCOPE_STRING *first_telstr;
+ double first_telstr_time=0;
+ double first_jd=tapeheader[0].st.jd;
+ char tmpstr[256];
+
+ /* find the first telstr that refers to valid data */
+
+ do {
+ first_telstr=&(tapeheader[++i].telstr);
+ first_telstr_time=first_telstr->st.jd;
+ } while ((first_telstr_time<=first_jd) && (i<TAPE_FRAMES_IN_BUFFER) &&
+ ((first_jd-first_telstr_time)<60.0/86400.0));
+
+
+ if (i==TAPE_FRAMES_IN_BUFFER) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"No valid telstr with time later than %14.5f\n",first_jd);
+ end_of_wu->frame=1+WU_OVERLAP_FRAMES;
+ end_of_wu->byte=0;
+ return(0);
+ }
+
+ /* find the correct byte offset for the start of the work unit */
+
+ start_of_wu->frame=i;
+ start_of_wu->byte=(long)((tapeheader[i].telstr.st.jd-tapeheader[i].st.jd)*86400.0*tapeheader[i].samplerate*2/CHAR_BIT);
+ start_of_wu->byte &= 0xfffffffe;
+
+
+ while (start_of_wu->byte<0) {
+ start_of_wu->frame--;
+ start_of_wu->byte+=TAPE_DATA_SIZE;
+ }
+
+ while (start_of_wu->byte>TAPE_DATA_SIZE) {
+ start_of_wu->frame++;
+ start_of_wu->byte-=TAPE_DATA_SIZE;
+ }
+
+ if (start_of_wu->frame<0) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Missing telescope strings near %lu\n",
+ tapeheader[0].frameseq);
+ end_of_wu->frame=0;
+ end_of_wu->byte=0;
+ records_in_buffer=0;
+ return(0);
+ }
+
+ if ((start_of_wu->frame+TAPE_FRAMES_PER_WU)>TAPE_FRAMES_IN_BUFFER) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Missing telescope strings near %lu\n",
+ tapeheader[0].frameseq);
+ end_of_wu->frame=0;
+ end_of_wu->byte=0;
+ records_in_buffer=0;
+ return(0);
+ }
+
+ /* check for frames in error */
+ for (i=0; i<TAPE_FRAMES_PER_WU; i++) {
+ int j=start_of_wu->frame+i;
+ // missed frames
+ if (tapeheader[j].missed) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Missing frames between %lu and %lu\n",
+ tapeheader[j-1].frameseq,tapeheader[j].frameseq);
+ valid=0;
+ }
+ // failed blanking signal acquisition
+ if (tapeheader[j].blanking_failed) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Failed blanking between frames %lu and %lu\n",
+ tapeheader[j-1].frameseq,tapeheader[j].frameseq);
+ valid=0;
+ }
+ if(!valid) {
+ end_of_wu->frame=j+WU_OVERLAP_FRAMES+1;
+ end_of_wu->byte=0;
+ assert((j+WU_OVERLAP_FRAMES)<=TAPE_FRAMES_IN_BUFFER);
+ }
+ }
+
+ if (!valid) {
+ end_of_wu->frame=0;
+ records_in_buffer=0;
+ return(valid);
+ }
+
+ end_of_wu->frame=start_of_wu->frame+TAPE_FRAMES_PER_WU;
+ end_of_wu->byte=start_of_wu->byte;
+
+ return(valid);
+}
+
+
+/*
+ * $Log: validrun.cpp,v $
+ * Revision 1.2.4.2 2006/12/14 22:24:48 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.2.4.1 2006/01/13 00:37:58 korpela
+ * Moved splitter to using standard BOINC logging mechanisms. All stderr now
+ * goes to "error.log"
+ *
+ * Added command line parameters "-iterations=" (number of workunit groups to
+ * create before exiting), "-trigger_file_path=" (path to the splitter_stop trigger
+ * file. Default is /disks/setifiler1/wutape/tapedir/splitter_stop).
+ *
+ * Reduced deadlines by a factor of three. We now need a 30 MFLOP machine to meet
+ * the deadline.
+ *
+ * Revision 1.2 2003/09/11 18:53:38 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.1 2003/07/29 20:35:57 korpela
+ *
+ * renames .C files to .cpp
+ *
+ * Revision 1.1 2003/06/03 00:23:43 korpela
+ *
+ * Again
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.7 2000/12/01 01:13:29 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.6 1999/06/07 21:00:52 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.5 1999/03/27 16:19:35 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.4 1999/02/22 22:21:09 korpela
+ * added -nodb option
+ *
+ * Revision 2.3 1999/02/11 16:46:28 korpela
+ * Added checkpointing.
+ *
+ * Revision 2.2 1998/11/04 23:08:25 korpela
+ * Byte and bit order change.
+ *
+ * Revision 2.1 1998/11/02 16:41:21 korpela
+ * Minor Change.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.3 1998/10/30 20:26:03 korpela
+ * Bug Fixes. Now mostly working.
+ *
+ * Revision 1.2 1998/10/27 00:59:22 korpela
+ * Bug fixes.
+ *
+ * Revision 1.1 1998/10/22 17:48:20 korpela
+ * Initial revision
+ *
+ *
+ */
diff --git a/gbt_splitter/validrun.h b/gbt_splitter/validrun.h
new file mode 100644
index 0000000..89f7c6d
--- /dev/null
+++ b/gbt_splitter/validrun.h
@@ -0,0 +1,33 @@
+/*
+ * validrun.h
+ *
+ * Functions for determining if a section of the tape buffer can be
+ * turned into a valid work unit
+ *
+ * $Id: validrun.h,v 1.1 2003/06/03 00:23:43 korpela Exp $
+ *
+ */
+
+int valid_run(tapeheader_t tapeheader[],buffer_pos_t *start_of_wu,
+ buffer_pos_t *end_of_wu);
+
+/*
+ * $Log: validrun.h,v $
+ * Revision 1.1 2003/06/03 00:23:43 korpela
+ *
+ * Again
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.1 1998/11/02 16:41:21 korpela
+ * Minor Change.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.1 1998/10/22 17:49:15 korpela
+ * Initial revision
+ *
+ *
+ */
diff --git a/gbt_splitter/writeheader.cpp b/gbt_splitter/writeheader.cpp
new file mode 100644
index 0000000..89296c3
--- /dev/null
+++ b/gbt_splitter/writeheader.cpp
@@ -0,0 +1,105 @@
+/*
+ * Functions for writing tape and work unit headers
+ *
+ * $Id: writeheader.cpp,v 1.3.4.1 2006/12/14 22:24:49 korpela Exp $
+ *
+ */
+
+#include "sah_config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <sys/types.h>
+
+#include "splitparms.h"
+#include "splittypes.h"
+#include "timecvt.h"
+#include "seti_header.h"
+
+extern int output_xml;
+
+/* Write a tape header into a buffer */
+int write_tape_header(char *buffer, tapeheader_t *header) {
+/* Unimplemented as yet */
+return(0);
+}
+
+char *monthnames[]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep"
+ "Oct","Nov","Dec"};
+char *daynames[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
+
+/* Write a work unit header into a FILE */
+/*int splitter_write_wu_header(FILE *file, wuheader_t *header) {
+ if (!output_xml)
+ write_wu_header(file, header->wuhead);
+ return (seti_write_wu_header(file,header->wuinfo,output_xml));
+
+}
+*/
+
+/*
+ * $Log: writeheader.cpp,v $
+ * Revision 1.3.4.1 2006/12/14 22:24:49 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.3 2003/09/11 18:53:38 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.2 2003/08/05 17:23:44 korpela
+ * More work on database stuff.
+ * Further tweaks.
+ *
+ * Revision 1.1 2003/07/29 20:35:59 korpela
+ *
+ * renames .C files to .cpp
+ *
+ * Revision 1.2 2003/06/03 01:01:18 korpela
+ *
+ * First working splitter under CVS.
+ *
+ * Revision 1.1 2003/06/03 00:23:43 korpela
+ *
+ * Again
+ *
+ * Revision 3.1 2003/05/19 17:40:59 eheien
+ * *** empty log message ***
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.6 1999/01/04 22:27:55 korpela
+ * Updated return codes.
+ *
+ * Revision 2.5 1998/11/10 00:02:44 korpela
+ * Moved remaining wuheader fields into a WU_INFO structure.
+ *
+ * Revision 2.4 1998/11/09 23:26:27 korpela
+ * Added generic version= to default header.
+ *
+ * Revision 2.3 1998/11/05 21:18:41 korpela
+ * Moved name field from header to seti header.
+ *
+ * Revision 2.2 1998/11/02 18:42:03 korpela
+ * Changed write_wu_header to call seti_write_wu_header
+ *
+ * Revision 2.1 1998/11/02 16:38:29 korpela
+ * Will be transfered to client.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.4 1998/10/30 20:26:03 korpela
+ * Bug Fixes. Now mostly working.
+ *
+ * Revision 1.3 1998/10/27 00:59:43 korpela
+ * Bug fixes.
+ * /
+ *
+ * Revision 1.2 1998/10/20 16:32:03 korpela
+ * Fixed syntax error.
+ *
+ * Revision 1.1 1998/10/20 16:27:41 korpela
+ * Initial revision
+ *
+ *
+ */
diff --git a/gbt_splitter/writeheader.h b/gbt_splitter/writeheader.h
new file mode 100644
index 0000000..c3d6d4a
--- /dev/null
+++ b/gbt_splitter/writeheader.h
@@ -0,0 +1,39 @@
+/*
+ * Functions for writing tape and work unit headers
+ *
+ * $Id: writeheader.h,v 1.2 2003/08/05 17:23:44 korpela Exp $
+ *
+ */
+
+/* Write a tape header into a buffer */
+int write_tape_header(char *buffer, tapeheader_t *header);
+
+/* Write a work unit header into a FILE */
+// int splitter_write_wu_header(FILE *file, wuheader_t *header);
+
+/*
+ * $Log: writeheader.h,v $
+ * Revision 1.2 2003/08/05 17:23:44 korpela
+ * More work on database stuff.
+ * Further tweaks.
+ *
+ * Revision 1.1 2003/06/03 00:23:44 korpela
+ *
+ * Again
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.2 1999/01/04 22:27:55 korpela
+ * Updated return codes.
+ *
+ * Revision 2.1 1998/11/02 16:41:21 korpela
+ * Minor Change.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.1 1998/10/15 17:20:01 korpela
+ * Initial revision
+ *
+ */
diff --git a/gbt_splitter/wufiles.cpp b/gbt_splitter/wufiles.cpp
new file mode 100644
index 0000000..d8663ce
--- /dev/null
+++ b/gbt_splitter/wufiles.cpp
@@ -0,0 +1,679 @@
+/*
+ *
+ * Functions for managing wufiles and their data
+ *
+ * $Id: wufiles.cpp,v 1.29.2.18 2007/08/10 18:21:13 korpela Exp $
+ *
+ */
+
+#include "sah_config.h"
+#undef USE_MYSQL
+#include <cstdio>
+#include <cstdlib>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <limits.h>
+#include <iostream>
+#include <string>
+#include <algorithm>
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include "boinc_db.h"
+#include "sched_util.h"
+#include "splitparms.h"
+#include "splittypes.h"
+#include "timecvt.h"
+#include "s_util.h"
+#include "util.h"
+#include "str_util.h"
+#include "str_replace.h"
+#include "splitter.h"
+#include "writeheader.h"
+#include "message.h"
+#include "encode.h"
+#include "dotransform.h"
+#include "angdist.h"
+#include "lcgamm.h"
+#include "readtape.h"
+#include "sqlrow.h"
+#include "sqlblob.h"
+#include "sqlapi.h"
+#include "db_table.h"
+#include "schema_master.h"
+#include "seti_tel.h"
+#include "seti_cfg.h"
+#include "xml_util.h"
+#include "db/app_config.h"
+#include "str_util.h"
+#include <errno.h>
+
+int wu_database_id[NSTRIPS];
+static std::vector<unsigned char> bin_data[NSTRIPS];
+
+extern APP_CONFIG sah_config;
+
+int make_wu_headers(tapeheader_t tapeheader[],workunit wuheader[],
+ buffer_pos_t *start_of_wu) {
+ int procid=getpid();
+ int i,j,startframe=start_of_wu->frame;
+ double receiver_freq;
+ int bandno;
+ SCOPE_STRING *lastpos;
+ FILE *tmpfile;
+ char tmpstr[256];
+ char buf[64];
+ static int HaveConfigTable=0;
+ static ReceiverConfig_t ReceiverConfig;
+ static receiver_config r;
+ static settings s;
+
+ if(!HaveConfigTable) {
+ sprintf(buf,"where s4_id=%d",gregorian?AOGREG_1420:AO_1420);
+ r.fetch(std::string(buf));
+ ReceiverConfig.ReceiverID=r.s4_id;
+ strlcpy(ReceiverConfig.ReceiverName,r.name,
+ sizeof(ReceiverConfig.ReceiverName));
+ ReceiverConfig.Latitude=r.latitude;
+ ReceiverConfig.Longitude=r.longitude;
+ ReceiverConfig.WLongitude=-r.longitude;
+ ReceiverConfig.Elevation=r.elevation;
+ ReceiverConfig.Diameter=r.diameter;
+ ReceiverConfig.BeamWidth=r.beam_width;
+ ReceiverConfig.CenterFreq=r.center_freq;
+ ReceiverConfig.AzOrientation=r.az_orientation;
+ for (i=0;i<(sizeof(ReceiverConfig.ZenCorrCoeff)/sizeof(ReceiverConfig.ZenCorrCoeff[0]));i++) {
+ ReceiverConfig.ZenCorrCoeff[i]=r.zen_corr_coeff[i];
+ ReceiverConfig.AzCorrCoeff[i]=r.az_corr_coeff[i];
+ }
+ HaveConfigTable=1;
+ }
+ sprintf(buf,"where active=%d",app.id);
+ if (!s.fetch(std::string(buf))) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Unable to find active settings for app.id=%d\n",app.id);
+ exit(1);
+ }
+ if (s.receiver_cfg->id != r.id) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Receiver config does not match settings (%d != %d)\n",s.receiver_cfg->id, r.id);
+ exit(1);
+ }
+ s.recorder_cfg->fetch();
+ s.splitter_cfg->fetch();
+ s.analysis_cfg->fetch();
+ if (!strncmp(s.splitter_cfg->data_type,"encoded",
+ std::min(static_cast<size_t>(7),sizeof(s.splitter_cfg->data_type)))) {
+ noencode=0;
+ } else {
+ noencode=1;
+ }
+
+ workunit_grp wugrp;
+ sprintf(wugrp.name,"%s.%ld.%d.%ld.%d",tapeheader[startframe].name,
+ procid,
+ (current_record-TAPE_RECORDS_IN_BUFFER)*8+startframe,
+ start_of_wu->byte,s.id);
+ wugrp.receiver_cfg=r;
+ wugrp.recorder_cfg=s.recorder_cfg;
+ wugrp.splitter_cfg=s.splitter_cfg;
+ wugrp.analysis_cfg=s.analysis_cfg;
+
+ wugrp.data_desc.start_ra=tapeheader[startframe+1].telstr.ra;
+ wugrp.data_desc.start_dec=tapeheader[startframe+1].telstr.dec;
+ wugrp.data_desc.end_ra=tapeheader[startframe+TAPE_FRAMES_PER_WU].telstr.ra;
+ wugrp.data_desc.end_dec=tapeheader[startframe+TAPE_FRAMES_PER_WU].telstr.dec;
+ wugrp.data_desc.nsamples=NSAMPLES;
+ wugrp.data_desc.true_angle_range=0;
+ {
+ double sample_rate=tapeheader[startframe].samplerate/NSTRIPS;
+ /* startframe+1 contains the first valid RA and Dec */
+ TIME st=tapeheader[startframe+1].telstr.st;
+ TIME et=tapeheader[startframe+TAPE_FRAMES_PER_WU].telstr.st;
+ double diff=(et-st).jd*86400.0;
+ for (j=2;j<TAPE_FRAMES_PER_WU;j++) {
+ wugrp.data_desc.true_angle_range+=angdist(tapeheader[startframe+j-1].telstr,tapeheader[startframe+j].telstr);
+ }
+ wugrp.data_desc.true_angle_range*=(double)wugrp.data_desc.nsamples/(double)sample_rate/diff;
+ if (wugrp.data_desc.true_angle_range==0) wugrp.data_desc.true_angle_range=1e-10;
+ }
+ // Calculate the number of unique signals that could be found in a workunit.
+ // We will use these numbers to calculate thresholds.
+ double numgauss=2.36368e+08/wugrp.data_desc.true_angle_range;
+ double numpulse=std::min(4.52067e+10/wugrp.data_desc.true_angle_range,2.00382e+11);
+ double numtrip=std::min(3.25215e+12/wugrp.data_desc.true_angle_range,1.44774e+13);
+
+
+
+ // Calculate a unique key to describe this analysis config.
+ long keyuniq=floor(std::min(wugrp.data_desc.true_angle_range*100,1000.0)+0.5)+
+ s.analysis_cfg.id*1024.0;
+ if ((keyuniq>(13*1024)) ||(keyuniq<12*1024)) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Invalid keyuniq value!\n");
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"%d %d %f\n",keyuniq,s.analysis_cfg.id,wugrp.data_desc.true_angle_range);
+ exit(1);
+ }
+
+ keyuniq*=-1;
+ long save_keyuniq=keyuniq;
+ s.analysis_cfg=wugrp.analysis_cfg;
+ sprintf(tmpstr,"where keyuniq=%d",keyuniq);
+ // Check if we've already done this analysis_config...
+ s.analysis_cfg.id=0;
+ s.analysis_cfg->fetch(tmpstr);
+
+ if (s.analysis_cfg->id==0) {
+ if (keyuniq != save_keyuniq) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"keyuniq value changed!\n");
+ exit(1);
+ }
+
+ // If not calculate the thresholds based upon the input analysis_config
+ // Triplets are distributed exponentially...
+ wugrp.analysis_cfg->triplet_thresh+=(log(numtrip)-29.0652);
+
+ // Gaussians are based upon chisqr...
+ double p_gauss=lcgf(32.0,wugrp.analysis_cfg->gauss_null_chi_sq_thresh*32.0);
+ p_gauss-=(log(numgauss)-19.5358);
+ wugrp.analysis_cfg->gauss_null_chi_sq_thresh=invert_lcgf(p_gauss,32,1e-4)*0.03125;
+
+ // Pulses thresholds are log of the probability
+ wugrp.analysis_cfg->pulse_thresh+=(log(numpulse)-24.7894);
+
+ wugrp.analysis_cfg->keyuniq=keyuniq;
+ wugrp.analysis_cfg->insert();
+ } else {
+ wugrp.analysis_cfg=s.analysis_cfg;
+ }
+
+ strlcpy(wugrp.data_desc.time_recorded,
+ short_jd_string(tapeheader[startframe+1].telstr.st.jd),
+ sizeof(wugrp.data_desc.time_recorded));
+ wugrp.data_desc.time_recorded_jd=tapeheader[startframe+1].telstr.st.jd;
+
+ lastpos=&(tapeheader[startframe].telstr);
+ coordinate_t tmpcoord;
+ tmpcoord.time=tapeheader[startframe].telstr.st.jd;
+ tmpcoord.ra=tapeheader[startframe].telstr.ra;
+ tmpcoord.dec=tapeheader[startframe].telstr.dec;
+ wugrp.data_desc.coords.push_back(tmpcoord);
+
+ for (j=1;j<TAPE_FRAMES_PER_WU;j++) {
+ if ((tapeheader[startframe+j].telstr.st.jd-lastpos->st.jd) > (1.0/86400.0))
+ {
+ lastpos=&(tapeheader[startframe+j].telstr);
+ tmpcoord.time=tapeheader[startframe+j].telstr.st.jd;
+ tmpcoord.ra=tapeheader[startframe+j].telstr.ra;
+ tmpcoord.dec=tapeheader[startframe+j].telstr.dec;
+ wugrp.data_desc.coords.push_back(tmpcoord);
+ }
+ }
+
+ wugrp.tape_info->id=0;
+ wugrp.tape_info->fetch(std::string("where name=\'")+tapeheader[startframe].name+"\'");
+ wugrp.tape_info->start_time=tapeheader[startframe].st.jd;
+ wugrp.tape_info->last_block_time=tapeheader[startframe].st.jd;
+ wugrp.tape_info->last_block_done=tapeheader[startframe].frameseq;
+
+ if (!nodb) {
+ if (wugrp.tape_info.id) {
+ if (!(wugrp.tape_info->update())) {
+ char buf[1024];
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"%s",sql_error_message());
+ exit(1);
+ }
+ } else {
+ strlcpy(wugrp.tape_info->name,tapeheader[startframe].name,sizeof(wugrp.tape_info->name));
+ wugrp.tape_info->insert();
+ }
+ }
+
+ if (!nodb) wugrp.insert();
+
+ for (i=0;i<NSTRIPS;i++) {
+ bin_data[i].clear();
+ wuheader[i].group_info=wugrp;
+ sprintf(wuheader[i].name,"%s.%ld.%d.%ld.%d.%d",tapeheader[startframe].name,
+ procid, (current_record-TAPE_RECORDS_IN_BUFFER)*8+startframe,
+ start_of_wu->byte,s.id,i);
+ wuheader[i].subband_desc.sample_rate=tapeheader[startframe].samplerate/NSTRIPS;
+
+ receiver_freq=tapeheader[startframe].centerfreq;
+
+ bandno=((i+NSTRIPS/2)%NSTRIPS)-NSTRIPS/2;
+
+ wuheader[i].subband_desc.base=receiver_freq+
+ (double)(bandno)*wuheader[i].subband_desc.sample_rate;
+ wuheader[i].subband_desc.center=receiver_freq+wuheader[i].subband_desc.sample_rate*NSTRIPS*((double)IFFT_LEN*bandno/FFT_LEN+(double)IFFT_LEN/(2*FFT_LEN)-1.0/(2*FFT_LEN));
+ wuheader[i].subband_desc.number=i;
+
+ if (!nodb ) {
+ if (!(wu_database_id[i]=wuheader[i].insert())) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Database error in make_wu_headers()\n");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ sprintf(tmpstr,"./wu_inbox/%s",wuheader[i].name);
+ if ((tmpfile=fopen(tmpstr,"w"))) {
+ fprintf(tmpfile,"<workunit>\n");
+ fprintf(tmpfile,wuheader[i].print_xml().c_str());
+ fclose(tmpfile);
+ } else {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Unable to open file ./wu_inbox/%s, errno=%d\n",wuheader[i].name,errno);
+ exit(1);
+ }
+ bin_data[i].reserve(wuheaders[i].group_info->recorder_cfg->bits_per_sample*
+ wuheaders[i].group_info->data_desc.nsamples/8);
+ }
+ return(1);
+}
+
+
+void write_wufile_blocks(int nbytes) {
+ static bool first_call=true;
+ int i,j;
+
+
+ for (i=0;i<NSTRIPS;i++) {
+ for (j=0;j<nbytes;j++) {
+ bin_data[i].push_back(output_buf[i][j]);
+ }
+ }
+}
+
+int filecopy(char *oldname,char *newname) {
+ FILE *oldfile,*newfile;
+ char buffer[16384];
+ int nread;
+ if ((oldfile=fopen(oldname,"rb")) && (newfile=fopen(newname,"wb"))) {
+ do {
+ nread=fread(buffer,1,16384,oldfile);
+ fwrite(buffer,1,nread,newfile);
+ } while (nread>0);
+ fclose(oldfile);
+ fclose(newfile);
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+
+
+void rename_wu_files() {
+ int i, retval;
+ char oldname[256],newname[1024];
+ unsigned long sz;
+ DB_WORKUNIT db_wu;
+ const char *name[1];
+ char *wudir="./wu_inbox";
+ xml_encoding encoding=(noencode?_binary:_x_setiathome);
+ FILE *tmpfile;
+
+ if (boinc_db.open(boinc_config.db_name,boinc_config.db_host,boinc_config.db_user,boinc_config.db_passwd)) {
+ boinc_db.print_error("boinc_db.open");
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Fatal error in boinc_db.open\n");
+ exit(1);
+ }
+
+ for (i=0;i<NSTRIPS;i++) {
+ name[0]=wuheaders[i].name;
+ sprintf(oldname,"%s/%s",wudir,name[0]);
+
+ //sprintf(newname,"%s%s/%s",projectdir,WU_SUBDIR,name[0]);
+ retval = dir_hier_path(name[0],
+ boinc_config.download_dir,
+ boinc_config.uldl_dir_fanout,
+ newname,
+ true
+ );
+ if (retval) {
+ char buf[1024];
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"[%s] dir_hier_path() failed: %d\n", name[0], retval);
+ exit(1);
+ }
+
+ struct stat sbuf;
+ if (!stat(oldname,&sbuf) && (tmpfile=fopen(oldname,"a"))) {
+ std::string tmpstr=xml_encode_string(bin_data[i],encoding);
+ fprintf(tmpfile,"<data length=%ld encoding=\"%s\">",tmpstr.size(),
+ xml_encoding_names[encoding]);
+ fwrite(tmpstr.c_str(),tmpstr.size(),1,tmpfile);
+ fprintf(tmpfile,"</data>\n");
+ fprintf(tmpfile,"</workunit>\n");
+ sz=bin_data[i].size();
+
+ fclose(tmpfile);
+ } else {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Header file no longer exists! splitter start script may be failing\n ");
+ exit(1);
+ }
+ if (!nodb) {
+ if (!filecopy(oldname,newname)) {
+ db_wu.clear();
+ db_wu.opaque=wuheaders[i].id;
+ strncpy(db_wu.name,name[0],sizeof(db_wu.name)-2);
+ db_wu.appid=app.id;
+ //db_wu.rsc_fpops_est=2.79248e+13*6;
+ //db_wu.rsc_fpops_bound=4.46797e+14*6;
+ double ar=wuheaders[i].group_info->data_desc.true_angle_range;
+ double dur=(double)(wuheaders[i].group_info->data_desc.nsamples)/wuheaders[i].subband_desc.sample_rate;
+ double min_slew=wuheaders[i].group_info->analysis_cfg->pot_min_slew;
+ double max_slew=wuheaders[i].group_info->analysis_cfg->pot_max_slew;
+ if ( ar < ( dur*min_slew )/2 ) {
+ db_wu.rsc_fpops_est=4.95e+13;
+ } else {
+ if ( ar < ( dur*min_slew ) ) {
+ db_wu.rsc_fpops_est=(2.85e+13+2.0e+14*ar);
+ } else {
+ if ( ar <= (dur*max_slew) ) {
+ db_wu.rsc_fpops_est=(2.22e+13/pow(ar,1.25));
+ } else {
+ db_wu.rsc_fpops_est=1.125e+13;
+ }
+ }
+ }
+ db_wu.rsc_fpops_bound=db_wu.rsc_fpops_est*10;
+ db_wu.rsc_memory_bound=32505856;
+ db_wu.rsc_disk_bound=500000;
+ // Our minimum is 10% of a 100 MFLOP machine
+ db_wu.delay_bound=db_wu.rsc_fpops_est/3e+7;
+ db_wu.min_quorum=sah_config.min_quorum;
+ db_wu.target_nresults=sah_config.target_nresults;
+ db_wu.max_error_results=sah_config.max_error_results;
+ db_wu.max_total_results=sah_config.max_total_results;
+ db_wu.max_success_results=sah_config.max_success_results;
+ strncpy(db_wu.app_name,SAH_APP_NAME,sizeof(db_wu.app_name)-2);
+ if (create_work(db_wu,
+ wu_template,
+ result_template_filename,
+ result_template_filepath,
+ name,
+ 1,
+ boinc_config,
+ NULL
+ )
+ ) {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"create work failed\n");
+ exit(1);
+ }
+ //unlink(oldname); // we now *always* unlink
+ } else {
+ log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"file copy failed\n");
+ exit(1);
+ }
+ unlink(oldname);
+ }
+ }
+ boinc_db.close();
+}
+
+/*
+ * $Log: wufiles.cpp,v $
+ * Revision 1.29.2.18 2007/08/10 18:21:13 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.29.2.17 2007/06/07 20:01:52 mattl
+ * *** empty log message ***
+ *
+ * Revision 1.29.2.16 2007/06/06 15:58:30 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.29.2.15 2006/12/14 22:24:49 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.29.2.14 2006/05/03 19:14:31 korpela
+ * Updated work estimates.
+ *
+ * Revision 1.29.2.13 2006/04/24 18:41:02 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.29.2.12 2006/01/13 00:37:58 korpela
+ * Moved splitter to using standard BOINC logging mechanisms. All stderr now
+ * goes to "error.log"
+ *
+ * Added command line parameters "-iterations=" (number of workunit groups to
+ * create before exiting), "-trigger_file_path=" (path to the splitter_stop trigger
+ * file. Default is /disks/setifiler1/wutape/tapedir/splitter_stop).
+ *
+ * Reduced deadlines by a factor of three. We now need a 30 MFLOP machine to meet
+ * the deadline.
+ *
+ * Revision 1.29.2.11 2006/01/10 00:39:04 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.29.2.10 2006/01/05 23:55:22 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.29.2.9 2005/12/05 22:11:40 korpela
+ * Fixed bug in flops estimate.
+ *
+ * Revision 1.29.2.8 2005/10/05 16:22:17 jeffc
+ * removed reference to old/new boolean for directory hash.
+ *
+ * Revision 1.29.2.7 2005/09/22 23:05:22 korpela
+ * Fixed threshold calculation. Was using chisqr rather than reduced chisqr.
+ *
+ * Revision 1.29.2.6 2005/09/21 22:11:23 korpela
+ * Updated Makefile.in for OpenSSL.
+ * Added dynamic threshold generation to wufiles.cpp.
+ *
+ * Revision 1.29.2.5 2005/08/01 17:47:38 korpela
+ * Type fixed.
+ *
+ * Revision 1.29.2.4 2005/08/01 17:43:20 korpela
+ * Refinement of FLOPS estimate for workunits.
+ *
+ * Revision 1.29.2.3 2005/07/26 17:17:01 korpela
+ * Typo fix
+ *
+ * Revision 1.29.2.2 2005/07/19 00:15:19 korpela
+ * Revised delay bound and FLOP estimate for setiathome_enhanced.
+ *
+ * Revision 1.29.2.1 2005/07/06 01:30:17 korpela
+ * Updated estimates of FPOPS per workunit for setiathome enhanced.
+ *
+ * Revision 1.29 2005/03/08 22:36:15 jeffc
+ * jeffc - fixed call to create_work()
+ *
+ * Revision 1.28 2005/02/15 23:06:47 korpela
+ * Fixed missing dir_hier symbol.
+ *
+ * Revision 1.27 2004/12/27 20:48:54 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.26 2004/11/18 22:24:48 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.25 2004/08/25 22:42:11 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.24 2004/08/14 04:44:26 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.23 2004/08/12 15:45:41 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.22 2004/07/15 17:54:20 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.21 2004/07/09 22:35:39 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.20 2004/07/01 17:56:51 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.19 2004/06/25 13:49:33 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.18 2004/06/18 23:23:32 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.17 2004/06/16 20:57:19 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.16 2004/06/02 20:51:32 jeffc
+ * *** empty log message ***
+ *
+ * Revision 1.15 2004/01/22 00:57:54 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.14 2004/01/20 22:33:44 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.13 2004/01/06 22:44:05 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.12 2004/01/01 18:42:01 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.11 2003/12/12 01:51:39 korpela
+ * Now using the opaque field in workunit to store SAH wuid.
+ *
+ * Revision 1.10 2003/12/03 23:46:41 korpela
+ * WU count is now only for SAH workunits.
+ *
+ * Revision 1.9 2003/11/25 21:59:53 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.8 2003/11/11 06:20:30 korpela
+ * Increased max fpops_max to prevent timeout on windows clients
+ *
+ * Revision 1.7 2003/10/25 18:19:44 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.6 2003/10/24 16:57:03 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.5 2003/09/26 20:48:52 jeffc
+ * jeffc - merge in branch setiathome-4_all_platforms_beta.
+ *
+ * Revision 1.3.2.2 2003/09/22 19:00:31 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.3.2.1 2003/09/22 17:39:35 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.4 2003/09/22 17:05:38 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.3 2003/09/11 18:53:38 korpela
+ * *** empty log message ***
+ *
+ * Revision 1.2 2003/08/05 17:23:44 korpela
+ * More work on database stuff.
+ * Further tweaks.
+ *
+ * Revision 1.1 2003/07/29 20:36:00 korpela
+ *
+ * renames .C files to .cpp
+ *
+ * Revision 1.3 2003/06/05 15:52:47 korpela
+ *
+ * Fixed coordinate bug that was using the wrong zenith angle from the telescope
+ * strings when handling units from the gregorian.
+ *
+ * Revision 1.2 2003/06/03 01:01:18 korpela
+ *
+ * First working splitter under CVS.
+ *
+ * Revision 1.1 2003/06/03 00:23:44 korpela
+ *
+ * Again
+ *
+ * Revision 3.8 2003/05/19 17:40:59 eheien
+ * *** empty log message ***
+ *
+ * Revision 3.7 2003/04/10 17:32:25 korpela
+ * *** empty log message ***
+ *
+ * Revision 3.6 2002/06/21 01:42:15 eheien
+ * *** empty log message ***
+ *
+ * Revision 3.5 2001/11/07 00:51:47 korpela
+ * Added splitter version to database.
+ * Added max_wus_ondisk option.
+ *
+ * Revision 3.4 2001/08/17 22:20:54 korpela
+ * *** empty log message ***
+ *
+ * Revision 3.3 2001/08/17 01:22:31 korpela
+ * *** empty log message ***
+ *
+ * Revision 3.2 2001/08/17 01:16:53 korpela
+ * *** empty log message ***
+ *
+ * Revision 3.1 2001/08/16 23:42:08 korpela
+ * Mods for splitter to make binary workunits.
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.18 2000/12/01 01:13:29 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.17 1999/06/07 21:00:52 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.16 1999/03/27 16:19:35 korpela
+ * *** empty log message ***
+ *
+ * Revision 2.15 1999/03/05 01:47:18 korpela
+ * Added data_class field.
+ *
+ * Revision 2.14 1999/02/22 22:21:09 korpela
+ * added -nodb option
+ *
+ * Revision 2.13 1999/02/11 16:46:28 korpela
+ * Added db access functions.
+ *
+ * Revision 2.12 1999/01/04 22:27:55 korpela
+ * Updated return codes.
+ *
+ * Revision 2.11 1998/12/14 23:41:44 korpela
+ * Added subband_base to work unit header.
+ * Changed frequency calculation.
+ *
+ * Revision 2.10 1998/12/14 21:55:07 korpela
+ * Added fft_len and ifft_len to work unit header.
+ *
+ * Revision 2.9 1998/11/13 23:58:52 korpela
+ * Modified for move of name field between structures.
+ *
+ * Revision 2.8 1998/11/13 22:18:12 davea
+ * *** empty log message ***
+ *
+ * Revision 2.7 1998/11/10 01:55:26 korpela
+ * Server requires a CR at the end of a WU file
+ * ???
+ *
+ * Revision 2.6 1998/11/10 00:02:44 korpela
+ * Moved remaining wuheader fields into a WU_INFO structure.
+ *
+ * Revision 2.5 1998/11/05 21:33:02 korpela
+ * Fixed angle_range bug.
+ *
+ * Revision 2.4 1998/11/05 21:18:41 korpela
+ * Moved name field from header to seti header.
+ *
+ * Revision 2.3 1998/11/02 21:20:58 korpela
+ * Modified for (internal) integer receiver ID.
+ *
+ * Revision 2.2 1998/11/02 18:45:39 korpela
+ * Changed location of timecvt.h
+ *
+ * Revision 2.1 1998/11/02 16:38:29 korpela
+ * Variable type changes.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.2 1998/10/30 20:26:03 korpela
+ * Bug Fixes. Now mostly working.
+ *
+ * Revision 1.1 1998/10/27 01:01:16 korpela
+ * Initial revision
+ *
+ *
+ */
diff --git a/gbt_splitter/wufiles.h b/gbt_splitter/wufiles.h
new file mode 100644
index 0000000..046c378
--- /dev/null
+++ b/gbt_splitter/wufiles.h
@@ -0,0 +1,39 @@
+/*
+ *
+ * Functions for managing wufiles and their data
+ *
+ * $Id: wufiles.h,v 1.2 2003/08/05 17:23:45 korpela Exp $
+ *
+ */
+
+
+
+int make_wu_headers(tapeheader_t tapeheader[],workunit wuheaders[],
+ buffer_pos_t *start_of_wu) ;
+void write_wufile_blocks(int nbytes) ;
+void rename_wu_files();
+
+/*
+ * $Log: wufiles.h,v $
+ * Revision 1.2 2003/08/05 17:23:45 korpela
+ * More work on database stuff.
+ * Further tweaks.
+ *
+ * Revision 1.1 2003/06/03 00:23:44 korpela
+ *
+ * Again
+ *
+ * Revision 3.0 2001/08/01 19:04:57 korpela
+ * Check this in before Paul screws it up.
+ *
+ * Revision 2.1 1998/11/02 16:41:21 korpela
+ * Minor Change.
+ *
+ * Revision 2.0 1998/10/30 22:00:04 korpela
+ * Conversion to C++ and merger with client source tree.
+ *
+ * Revision 1.1 1998/10/27 01:13:16 korpela
+ * Initial revision
+ *
+ *
+ */
--
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