boinc-app-seti_8.00~svn3701.orig/0000755000175000017500000000000013155506332016515 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/tools/0000755000175000017500000000000013155506301017651 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/tools/readwu.cpp0000644000175000017500000001130412437201231021637 0ustar locutuslocutus// SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // workunit_resample - a program to read in a workunit and convert it to // real samples at twice the sampling rate with all frequencies shifted to // be positive. #include "sah_config.h" #include #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_SYS_STAT_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #include #include #include #include #include #include "export.h" #ifdef HAVE_IEEEFP_H #include #endif #include "client/timecvt.h" #include "client/s_util.h" #include "db/db_table.h" #include "db/schema_master.h" #include "seti.h" #define ARRLEN(arr) (sizeof(arr)/sizeof(arr[0])) workunit_header header; extern "C" { IDL_VPTR readwu(int argc, IDL_VPTR argv[], char *argk); void readwu_exit_handler(void) { } int IDL_Load(void); } static IDL_SYSFUN_DEF2 readwu_fns[] = { {(IDL_VARIABLE *(*)())readwu, "READWU", 1, 1, IDL_SYSFUN_DEF_F_KEYWORDS, 0}, }; static IDL_MSG_DEF msg_arr[] = { {"READWU_ERROR", "%NError: %s"}, }; static IDL_MSG_BLOCK readwu_msg_block; int readwu_startup(void) { if (!IDL_SysRtnAdd(readwu_fns,TRUE,ARRLEN(readwu_fns))) { return NULL; } IDL_ExitRegister(readwu_exit_handler); return IDL_TRUE; } int IDL_Load(void) { if (!(readwu_msg_block=IDL_MessageDefineBlock("readwu", ARRLEN(msg_arr),msg_arr))) { return NULL; } if (!readwu_startup()) { IDL_MessageFromBlock(readwu_msg_block,0,IDL_MSG_RET,"can't load readwu"); } return IDL_TRUE; } IDL_VPTR readwu(int argc, IDL_VPTR argv[], char *argk) { IDL_VPTR filename=NULL; static IDL_VARIABLE rv; rv.type=IDL_TYP_INT; rv.flags=IDL_V_CONST|IDL_V_NULL; rv.value.i=-1; char *outfile=NULL, buf[256]; struct stat statbuf; int nbytes,nread,nsamples; std::string tmpbuf(""); int i=0,j; if (argc != 1) { fprintf(stderr,"argc=%d\n",argc); fprintf(stderr,"array=readwu(wufile_name)\n"); return &rv; } IDL_STRING *infile=NULL; if (argv[0]->type != IDL_TYP_STRING) { IDL_MessageFromBlock(readwu_msg_block,0,IDL_MSG_RET,"Parameter 1 must be type STRING"); } else { infile=(IDL_STRING *)(&argv[0]->value.s); } FILE *in=fopen(infile->s,"r"); if (!in) { IDL_MessageFromBlock(readwu_msg_block,0,IDL_MSG_RET,"File not found"); return &rv; } stat(infile->s,&statbuf); nbytes=statbuf.st_size; fseek(in,0,SEEK_SET); tmpbuf.reserve(nbytes); // read entire file into a buffer. while ((nread=(int)fread(buf,1,sizeof(buf),in))) { tmpbuf+=std::string(&(buf[0]),nread); } // parse the header header.parse_xml(tmpbuf); // decode the data std::vector datav( xml_decode_field(tmpbuf,"data") ); tmpbuf.clear(); nsamples=header.group_info->data_desc.nsamples; nbytes=nsamples*header.group_info->recorder_cfg->bits_per_sample/8; if (datav.size() < nbytes) { fprintf(stderr,"Data size does not match number of samples\n"); return &rv; } // convert the data to floating point sah_complex *fpdata=(sah_complex *)IDL_MemAlloc(nsamples*sizeof(sah_complex),0,IDL_MSG_RET); if (!fpdata) { fprintf(stderr,"Unable to allocate memory!\r\n"); return &rv; } bits_to_floats(&(datav[0]),fpdata,nsamples); datav.clear(); IDL_MEMINT dims[]={nsamples}; return IDL_ImportArray(1,dims,IDL_TYP_COMPLEX,(UCHAR *)fpdata,NULL,NULL); } boinc-app-seti_8.00~svn3701.orig/tools/fakedata.cpp0000755000175000017500000003457610671336410022141 0ustar locutuslocutus// fakedata [ options ] filename // // Title : fakedata.c // Programmer : Jeff Cobb / David Anderson // History : 12/13/95 - first release // : 10/25/05 - Modified for setiathome_enhanced Eric Korpela // Copyright (c) 1998 University of California Regents // Credits for seti@home reference package: // algorithm design: Dan Werthimer (UCB), // Mike Lampton, (UCB), // Charles Donnelly (UCB), // Jeff Cobb (UCB) // reference code programming: Jeff Cobb // seti@home network design and programming: David Anderson // This program is to be used to generate fake digital data // for testing seti@home algorithms. It generates random // noise embedded with any of the following signal types: // - continuous // - pulsed // - chirped // - showing an gaussian power profile over time // The randomness of the noise can be colored by: // - change in noise amplitude over time // - favoring certain frequencies (changing noise // amplitude over frequency) // The signal to noise ratio you want to use to emulate a setiathome work // unit depends upon the signal type and the FFT length you want to find it at. // For example if you want to build a gaussian that is 5 times the noise power // at an FFT length of 16384 you should specify a noise amplitude of 1 and // a gaussian amplitude of 5/sqrt(16384) (about 0.04). If you want to specify // a spike of 30 times the mean noise power at an FFT length of 128k you would // specify a sine wave of amplitude 30/sqrt(128k) (about 0.083). // The output file contains // the number of data points and an array of floating // point numbers representing power over time. // That the array is a series of complex values, // using 2 array elements for each data point. // Real parts are held in even elements (starting with [0]) // and imaginary parts are held in the adjacent odd elements. // options: // // -sr n // samples per second // -dur x // duration of data (seconds) // -sine amp freq chirp start end // inject a sine wave, amplitude amp // freq: frequency at center of time interval // (note: freqs must lie in [-sr/2, sr/2] // chirp rate in Hz/sec // NOTE: chirp is applied starting from time 0 // (not necessarily from the start of the sine wave) // Start and end times; if zero, whole duration // -noise amp // inject noise of amplitude amp; // -gauss amp midpt sig freq chirp // Inject a Gaussian signal with the given amplitude and midpoint, // halfpower width (seconds), frequency (Hz), chirp rate (Hz/sec) // -pulse period duty // Inject a pulse signal with the given period (seconds) and duty cycle (percent). It // is "encased" in the Gaussian envelope determined by the -gaussian parameters // -ascii // generate ascii data // default: 1-bit output samples (binary). //#define DEBUG #include #include #include #include #include "analyze.h" #include "seti_header.h" #include "xml_util.h" #define NEG_LN_ONE_HALF 0.693 #if 0 #define EXP(a,b,c) exp(-(NEG_LN_ONE_HALF * pow((double)(a) - (double)(b), 2.0)) / (double)(c)) #endif struct SIGNAL_DESC { double sample_rate; double dur; bool onebit; double noise_amp; double sine_amp; double sine_freq; double sine_chirp; double sine_start; double sine_end; double gauss_amp; double gauss_midpt; double gauss_sigma; double gauss_freq; double gauss_chirp; double pulse_period; double pulse_duty_cycle; }; void bad_args() { fprintf(stderr, "bad args\n"); exit(1); } float randu() { // Uniform random numbers between 0 and 1 static bool first=true; if (first) { srand(time(0)); first=false; } return static_cast(rand())/RAND_MAX; } float rande() { // exponentially distributed random numbers return -log(randu()); } 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; } } void getopts(int argc, char* argv[], SIGNAL_DESC& sd) { int i; sd.onebit = true; for (i=1; i data; time_t st=time(0); if (argc < 2) bad_args(); idum = -time(NULL); memset(&sd, 0, sizeof(sd)); getopts(argc, argv, sd); // some default values -- added by EK ///////////////////////////// if (sd.sample_rate == 0) sd.sample_rate=9765.625; if (sd.noise_amp == 0) sd.noise_amp=1; if (sd.dur==0) { npoints=1024*1024; sd.dur=npoints/sd.sample_rate; } else { npoints = (int)(sd.sample_rate * sd.dur); } data.reserve(npoints/4); if (sd.gauss_sigma == 0) sd.gauss_sigma=12.5; //////////////////////////////////////////////////////////////////// if (sd.sine_end == 0) sd.sine_end = sd.dur; // Added workunit header - EK /////////////////////////////////// sprintf(wu.name,"fake.%d.0",st); ///////////////////////// Group Info //////////////////////////// sprintf(wu.group_info->name,"fake.%d",st); ///////////////////////// Tape Info ///////////////////////////// sprintf(wu.group_info->tape_info->name,"fake"); wu.group_info->tape_info->start_time=time_t_to_jd(st); wu.group_info->tape_info->last_block_time=time_t_to_jd(st); ///////////////////////// Recv Conf ///////////////////////////// wu.group_info->receiver_cfg->s4_id=1; sprintf(wu.group_info->receiver_cfg->name,"fake"); wu.group_info->receiver_cfg->beam_width=5.0/60.0; wu.group_info->receiver_cfg->center_freq=1420.0; wu.group_info->receiver_cfg->az_corr_coeff.push_back(0.0); wu.group_info->receiver_cfg->zen_corr_coeff.push_back(0.0); ///////////////////////// Recorder Cfg ////////////////////////// sprintf(wu.group_info->recorder_cfg->name,"fake"); wu.group_info->recorder_cfg->bits_per_sample=2; wu.group_info->recorder_cfg->beams=1; wu.group_info->recorder_cfg->sample_rate=sd.sample_rate; ///////////////////////// Splitter Cfg ////////////////////////// wu.group_info->splitter_cfg->version=0.17; sprintf(wu.group_info->splitter_cfg->data_type,"encoded"); sprintf(wu.group_info->splitter_cfg->filter,"fft"); sprintf(wu.group_info->splitter_cfg->window,"welsh"); wu.group_info->splitter_cfg->fft_len=1; wu.group_info->splitter_cfg->ifft_len=1; ///////////////////////// Data Desc ///////////////////////////// wu.group_info->data_desc.start_ra=0; wu.group_info->data_desc.start_dec=18.4; wu.group_info->data_desc.end_dec=18.4; wu.group_info->data_desc.time_recorded_jd=time_t_to_jd(st); sprintf(wu.group_info->data_desc.time_recorded,"%s",jd_string(time_t_to_jd(st))); wu.group_info->data_desc.nsamples=npoints; wu.group_info->data_desc.true_angle_range=sd.dur/sd.gauss_sigma*wu.group_info->receiver_cfg->beam_width; { time_t dt=0; double dr=wu.group_info->data_desc.true_angle_range/(cos(18.4*M_PI/180)*15*sd.dur); while (dt<(sd.dur+5)) { coordinate_t tmp; tmp.time=time_t_to_jd(st+dt); tmp.dec=18.4; tmp.ra=dt*dr; wu.group_info->data_desc.coords.push_back(tmp); dt+=5; } } ///////////////////////// Subband Desc ///////////////////////////// wu.subband_desc.number=0; wu.subband_desc.center=1420000000; wu.subband_desc.base=1420000000; wu.subband_desc.sample_rate=sd.sample_rate; ///////////////////////// Analysis Cfg ///////////////////////////// wu.group_info->analysis_cfg->spike_thresh=24.0; wu.group_info->analysis_cfg->spikes_per_spectrum=1; wu.group_info->analysis_cfg->gauss_null_chi_sq_thresh=2.2249999; wu.group_info->analysis_cfg->gauss_chi_sq_thresh=1.41999996; wu.group_info->analysis_cfg->gauss_power_thresh=3; wu.group_info->analysis_cfg->gauss_peak_power_thresh=3.2; wu.group_info->analysis_cfg->gauss_pot_length=64; wu.group_info->analysis_cfg->pulse_thresh=19.5; wu.group_info->analysis_cfg->pulse_display_thresh=0.5; wu.group_info->analysis_cfg->pulse_max=40960; wu.group_info->analysis_cfg->pulse_min=16; wu.group_info->analysis_cfg->pulse_fft_max=8192; wu.group_info->analysis_cfg->pulse_pot_length=256; wu.group_info->analysis_cfg->triplet_thresh=8.5; wu.group_info->analysis_cfg->triplet_max=131072; wu.group_info->analysis_cfg->triplet_min=16; wu.group_info->analysis_cfg->triplet_pot_length=256; wu.group_info->analysis_cfg->pot_overlap_factor=0.5; wu.group_info->analysis_cfg->pot_t_offset=1; wu.group_info->analysis_cfg->pot_min_slew=0.00209999993; wu.group_info->analysis_cfg->pot_max_slew=0.0104999999; wu.group_info->analysis_cfg->chirp_resolution=0.333; wu.group_info->analysis_cfg->analysis_fft_lengths=262136; wu.group_info->analysis_cfg->bsmooth_boxcar_length=8192; wu.group_info->analysis_cfg->bsmooth_chunk_size=32768; { chirp_parameter_t tmp; tmp.chirp_limit=20; tmp.fft_len_flags=262136; wu.group_info->analysis_cfg->chirps.push_back(tmp); tmp.chirp_limit=50; tmp.fft_len_flags=65528; wu.group_info->analysis_cfg->chirps.push_back(tmp); } wu.group_info->analysis_cfg->pulse_beams=1; wu.group_info->analysis_cfg->max_signals=3000; wu.group_info->analysis_cfg->max_spikes=3000; wu.group_info->analysis_cfg->max_gaussians=3000; wu.group_info->analysis_cfg->max_pulses=3000; wu.group_info->analysis_cfg->max_triplets=3000; ///////////////////////////////////////////////////////////////// fprintf (stderr, "sample rate: %f\n", sd.sample_rate); fprintf (stderr, "duration: %f\n", sd.dur); fprintf (stderr, "number of points: %d\n", npoints); fprintf (stderr, "noise: %f\n", sd.noise_amp); fprintf (stderr, "sine_amp: %f\n", sd.sine_amp); fprintf (stderr, "sine_freq: %f (wu %d)\n", sd.sine_freq, freq_to_wu(sd, sd.sine_freq) ); fprintf (stderr, "sine_chirp: %f\n", sd.sine_chirp); fprintf (stderr, "sine_start: %f\n", sd.sine_start); fprintf (stderr, "sine_end: %f\n", sd.sine_end); fprintf (stderr, "gauss_amp: %f\n", sd.gauss_amp); fprintf (stderr, "gauss_midpt: %f\n", sd.gauss_midpt); fprintf (stderr, "gauss_sigma: %f\n", sd.gauss_sigma); fprintf (stderr, "gauss_freq: %f (wu %d)\n", sd.gauss_freq, freq_to_wu(sd, sd.gauss_freq) ); fprintf (stderr, "gauss_chirp: %f\n", sd.gauss_chirp); fprintf (stderr, "pulse_period: %f\n", sd.pulse_period); fprintf (stderr, "pulse_duty_cycle: %f\n", sd.pulse_duty_cycle); fprintf (stderr, "data format: %s\n", sd.onebit?"binary":"ascii"); cnt = 0; if(!sd.onebit) { printf("nsamples=%d\n", npoints); printf("real imag\n"); } double sine_phase = 0, sine_freq; double sine_midpt = (sd.sine_end - sd.sine_start)/2; double gauss_phase = 0, gauss_freq; double dt = sd.dur/npoints; double sigma_sq = sd.gauss_sigma*sd.gauss_sigma; double pulseActive = 1.0; double pulseTime = sd.pulse_period*sd.pulse_duty_cycle/100.0; for (i=0; i 0) { real += randn()*sd.noise_amp; imag += randn()*sd.noise_amp; } if (sd.sine_amp) { if (mytime >= sd.sine_start && mytime <= sd.sine_end) { real += sd.sine_amp*cos(sine_phase); imag -= sd.sine_amp*sin(sine_phase); } sine_freq = sd.sine_freq + sd.sine_chirp*mytime; sine_phase += M_PI*2*dt*sine_freq; } if (sd.pulse_period > 0) { if( (mytime - (floor(mytime/sd.pulse_period))*sd.pulse_period) > pulseTime ) { pulseActive = 0.0; } } if (sd.gauss_amp > 0) { double gauss_factor = EXP(mytime, sd.gauss_midpt, sigma_sq); real += gauss_factor*pulseActive*sd.gauss_amp*cos(gauss_phase); imag -= gauss_factor*pulseActive*sd.gauss_amp*sin(gauss_phase); gauss_freq = sd.gauss_freq + sd.gauss_chirp*mytime; gauss_phase += M_PI*2*dt*gauss_freq; } if (sd.onebit) { c >>= 2; if (real >= 0) c |= 0x8000; if (imag >= 0) c |= 0x4000; cnt += 2; if (cnt == 16) { cnt = 0; data.push_back(c/256); data.push_back(c&255); } } else { printf("%e %e\n", real, imag); } } // flush out remaining samples if (sd.onebit) { for (i=0; i<7; i++) { c >>= 2; cnt += 2; if (cnt == 16) { cnt = 0; data.push_back(c/256); data.push_back(c&255); } } printf("\n"); std::cout << wu; std::string tmpstr=xml_encode_string(data,_x_setiathome); printf("",tmpstr.size(), xml_encoding_names[_x_setiathome]); fwrite(tmpstr.c_str(),tmpstr.size(),1,stdout); printf("\n\n"); } } void print_error( int e ) { printf( "Error %d\n", e ); exit(1); } boinc-app-seti_8.00~svn3701.orig/tools/Makefile.am0000644000175000017500000000347012437201231021705 0ustar locutuslocutus## $Id: Makefile.am,v 1.1.2.2 2006/01/04 00:47:33 korpela Exp $ include $(top_srcdir)/Makefile.incl LDFLAGS= AM_LDFLAGS= BOINC_LIBS = -L$(BOINCDIR)/api -lboinc_api -L$(BOINCDIR)/lib -lboinc CLIENT_C_FLAGS = $(CFLAGS) \ $(DEFS) \ -DTEXT_UI -DNDEBUG -DCLIENT \ -include $(top_builddir)/config.h \ -I$(top_srcdir)/db \ -I$(top_srcdir)/client \ $(BOINC_CFLAGS) \ $(PTHREAD_CFLAGS) CLIENT_LD_FLAGS = $(PTHREAD_CFLAGS) $(LDFLAGS) $(PTHREAD_LIBS) $(BOINC_LIBS) noinst_PROGRAMS = fakedata workunit_resample readwu.so fakedata_SOURCES = \ fakedata.cpp \ ../client/seti_header.cpp \ ../client/timecvt.cpp \ ../db/schema_master.cpp \ ../db/sqlrow.cpp \ ../db/sqlblob.cpp \ ../db/xml_util.cpp fakedata_CFLAGS = $(CLIENT_C_FLAGS) fakedata_CXXFLAGS = $(CLIENT_C_FLAGS) fakedata_LDFLAGS = $(CLIENT_LD_FLAGS) workunit_resample_SOURCES = \ workunit_resample.cpp \ ../client/seti_header.cpp \ ../client/timecvt.cpp \ ../client/s_util.cpp \ ../db/schema_master.cpp \ ../db/sqlrow.cpp \ ../db/sqlblob.cpp \ ../db/xml_util.cpp workunit_resample_CFLAGS = $(CLIENT_C_FLAGS) workunit_resample_CXXFLAGS = $(CLIENT_C_FLAGS) workunit_resample_LDFLAGS = $(CLIENT_LD_FLAGS) workunit_resample_LDADD = -lfftw3f readwu_so_SOURCES = \ readwu.cpp \ ../client/seti_header.cpp \ ../client/timecvt.cpp \ ../client/s_util.cpp \ ../db/schema_master.cpp \ ../db/sqlrow.cpp \ ../db/sqlblob.cpp \ ../db/xml_util.cpp readwu_so_CFLAGS = $(CLIENT_C_FLAGS) -fPIC -I/usr/local/rsi/idl/external readwu_so_CXXFLAGS = $(CLIENT_C_FLAGS) -fPIC -I/usr/local/rsi/idl/external readwu_so_LDFLAGS = $(CLIENT_LD_FLAGS) -shared -fPIC -Bsymbolic --warn-once readwu_so_LDADD = $(BOINCDIR)/lib/libboinc.a readwu_so_LINK = $(CXX) $(LDFLAGS) $(readwu_so_LDFLAGS) -o $@ boinc-app-seti_8.00~svn3701.orig/tools/workunit_resample.cpp0000644000175000017500000001056011475554252024144 0ustar locutuslocutus// SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // workunit_resample - a program to read in a workunit and convert it to // real samples at twice the sampling rate with all frequencies shifted to // be positive. #include "sah_config.h" #include #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_SYS_STAT_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #include #include #include #include #include #ifdef HAVE_IEEEFP_H #include #endif #include "client/timecvt.h" #include "client/s_util.h" #include "db/db_table.h" #include "db/schema_master.h" #include "seti.h" #include "fftw3.h" workunit_header header; int main(int argc, char *argv[]) { char *outfile=NULL, buf[256]; struct stat statbuf; int nbytes,nread,nsamples; std::string tmpbuf(""); int i=0,j; if ((argc < 2) || (argc > 3)) { fprintf(stderr,"%s infile [outfile]\n",argv[0]); exit(1); } char *infile=argv[1]; if (argc==3) { outfile=argv[2]; } FILE *in=fopen(infile,"r"); FILE *out; if (outfile) { out=fopen(outfile,"w"); } else { out=stdout; } stat(infile,&statbuf); nbytes=statbuf.st_size; fseek(in,0,SEEK_SET); tmpbuf.reserve(nbytes); // read entire file into a buffer. while ((nread=(int)fread(buf,1,sizeof(buf),in))) { tmpbuf+=std::string(&(buf[0]),nread); } // parse the header header.parse_xml(tmpbuf); // decode the data std::vector datav( xml_decode_field(tmpbuf,"data") ); tmpbuf.clear(); nsamples=header.group_info->data_desc.nsamples; nbytes=nsamples*header.group_info->recorder_cfg->bits_per_sample/8; if (datav.size() < nbytes) { fprintf(stderr,"Data size does not match number of samples\n"); exit(1); } // convert the data to floating point sah_complex *fpdata=(sah_complex *)calloc(nsamples,sizeof(sah_complex)); sah_complex *fpout=(sah_complex *)calloc(2048,sizeof(sah_complex)); sah_complex *tmpb=(sah_complex *)calloc(1024,sizeof(sah_complex)); if (!fpdata || !fpout) { fprintf(stderr,"Memory allocation failure\n"); exit(1); } bits_to_floats(&(datav[0]),fpdata,nsamples); datav.clear(); sah_complex workbuf[2048]; fftwf_plan reverse=fftwf_plan_dft_1d(2048,workbuf,fpout,FFTW_BACKWARD,FFTW_MEASURE); fftwf_plan forward=fftwf_plan_dft_1d(1024,tmpb,workbuf,FFTW_FORWARD,FFTW_MEASURE|FFTW_PRESERVE_INPUT); while (i tag to the XML print routine for the printing of the best signals. client/ analyzeFuncs.cpp Eric K 09/25/03 Binary types in db tables are now of class sqlblob Makefile.in client/Makefile.in client/analyzeReport.cpp client/seti.h db/db_table.h db/schema_master.cpp db/schema_master.h db/schema_master.sql db/schema_to_class.awk db/sqlblob.cpp db/sqlblob.h db/tools/Makefile db/tools/Makefile.in Eric K 09/28/03 Added operator =() to all db_table<> children. Changed db_*::operator =() to call the child = operators. db/db_table.h db/schema_to_class.awk db/schema_master.h db/schema_master.cpp Jeff 9/29/03 Boolean standalone now initialized to false. If we have no WU to read (fopen() failed) in read_wu_state(), we set retval to FOPEN_FAILED and return. This is certainly good to do and prevents seg faults due to empty SWI's. But we need to also check SWI data before using it. client/main.cpp client/worker.cpp David Sept 30 2003 - include graphics-related stuff only if BOINC_APP_GRAPHICS is defined main.cpp David Oct 2 2003 - read_wu_state(): if there's no input file, return an error - got rid of windows .exe client/ worker.cpp client/win_build/Debug seti_boinc.exe (removed) Eric K. Oct 2 2003 - moved xml_indent() from sqlrow.cpp, sqlrow.h to boinc/lib/xml_util.[Ch] db/sqlrow.cpp db/sqlrow.h David Oct 4 2003 - Reorganized graphics code to facilitate graphical variation Factored user prefs into GRAPHICS_PREFS Combined all graphics-related stuff into SAH_GRAPHICS This inherits from GDATA, GRAPHICS_PREFS etc. so that its member functions (all render-related code) can access data without qualification. There are three top-level graphics "styles": Classic: 3D version of original graphics Panels: text is on rotating panels Headsup: text is 2D in corners of screen Each of these styles has numerous user-configurable settings. Not everything is working yet but the code is in better shape. client/ analyzeFuncs.cpp gdata.cpp,h main.cpp sah_gfx.cpp,h win_build/ seti_boinc.dsp David Oct 6 2003 - Implement rotating-panels display for SETI@home - Factor out generation of text in display client/ analyzeFuncs.cpp sah_gfx.cpp,h win_build/ seti_boinc.dsp p004_640.jpg (new, just a sample background image) David Oct 7 2003 NOTE: there are three different structs for each signal type. E.g.: class gaussian (in schema_master.h) has PoT array in unsigned chars struct GAUSS_INFO (in seti.h) contains "gaussian" as an element. Also has score, bin, and the PoT array in floats G_GAUSS_INFO (in gdata.h) Has the minimal set of info needed to display a Gaussian. A few fields from GAUSS_INFO, plus an "is_best" flag, and a "dirty" flag (has this been displayed yet?) Has a "copy" member function for copying from a GAUSS_INFO The variable best_gauss (of type GAUSS_INFO) etc. (in analyzeReport.cpp) stores the best Gaussian found so far (zero power if none) Stored and read from the state file. The variable SAH_GRAPHICS::gi (of type G_GAUSS_INFO) stores the Gaussian currently being displayed (zero power if none) Normally SAH_GRAPHICS::gi is copied from best_gauss, and its is_best flag is true. However, during analyze_pot(), SAH_GRAPHICS::gi is just the most recent Gaussian computed, and is_best is false. - Set the "dirty" flag of SAH_GRAPHIC's signals whenever copy to them (i.e. don't need to do this separately) - Remove "is_best" field of GAUSS_INFO etc. - Copy PoT arrays using a for loop, not a memcpy() - In graphics code: factor out the decision about which signal to display into a separate function (choose_signal_to_display()). Display a dirty signal if there is one, otherwise rotate among those that are actually there. client/ analyzeReport.cpp gaussfit.cpp gdata.cpp,h sah_gfx.cpp,h seti.h David Oct 7 2003 - show CPU time in Classic-style graphics - improve code factoring in Classic-style graphics - add "present" flag to TEXTURE_DESC - fix function names client/ gdata.h sah_gfx.cpp win_build/seti_boinc.dsp Oliver Oct 8 2003 - draws logos and user icons - fixed headsup display client/ sah_gfx.cpp win_build/seti_boinc.dsp David Oct 8 2003 - Use new texture-drawing interface sah_gfx.cpp,h Jeff Oct 9 2003 Fixed bug in calls to ::parse_xml(). The string passed to these routines must include the outer signal tags (eg . client/ seti.cpp Jeff Oct 10 2003 Checkpoint triplet PoTs. client/ seti.cpp David Oct 10 2003 - The functions that copy signals to the graphics structure now have a "best_of" flag - The functions that copy signals to the graphics structure now check whether what they're copying is the same as what's already there; if so they don't set the "dirty" flag (otherwise the copy of the best-of signals after each PoT analysis disrupt the 5-second cycle of signals) - Fixed the code that implements 5-second cycle of signals (it was doing integer arithmetic on a huge double, yielding negative results) - Alpha of pillars is one (opaque) - made a STARFIELD class - changed GRAPH_2D to RIBBON_GRAPH - Added support for tick marks in RIBBON_GRAPH - tested parsing of XML preferences. Preferred way of changing graphics is to edit app_init.xml client/ AnalyzeFuncs.cpp AnalyzeReport.cpp gdata.cpp,h sah_gfx.cpp,h win_build/ init_data.xml Jeff Oct 10 2003 - Fixed bug that was preventing the choosing of the first best spike (a legitimate spike score can be < 0). client/ spike.cpp Oliver Oct 10 2003 - Updated panel display, moved camera to origen client/ sah_gfx.c,h David Oct 14 2003 - changed angle param from "rate" to "period" - put complete set of graphics prefs in init_data.xml - updated graphics prefs code to use same set of parameters and names as the Web code (astropulse/html/project_specific_prefs.inc) - removed cruft client/ main.cpp sah_gfx.cpp,h seti.cpp win_builc/init_data.xml Oliver Oct 14 2003 - fixed stars, moved camera back to original location client/ sah_gfx.cpp Oliver Oct 16 2003 - more improvements on star generation - fixed resize via. applying a universal glScale client/ sah_gfx.cpp,H Jeff Oct 16 2003 - tested, debugged and added documentation to the validator and assimilator. - Built production executables and installed them in the "astropulse" beta test. - Added the informix lib paths to the boinc master cron program. This is needed for the assimilator. - Note that at this point server side executables (and all parts that make them up) have to be built on koloth (the production host). This is because koloth has a different gcc (and libs) than our other machines. Our standard gcc is v 3.0.4 (bundled with libstdc++.so.3) while on koloth we have gcc 3.3 (bundled with libstdc++.so.5). Running on koloth after building elsewhere gives: fatal: libstdc++.so.3: open failed: No such file or directory - Note that various Makefile.in's specify the mysql library as being /usr/local/mysql. But for koloth it needs to be /usr/local/mysql_32bit. Linking against /usr/local/mysql on koloth (a 64 bit mysql) gives ld: warning: file /usr/local/mysql/lib/libmysqlclient.a(libmysql.o): wrong ELF class: ELFCLASS64 There will be a sysadmin fix for this to make /usr/local/mysql correct on all hosts. code: assimilator/ sah_assimilate_handler.cpp,h validate/ sah_boinc_db.cpp,h sah_result.cpp,h sah_validate.cpp systems: koloth:~boincadm/projects/ AstroPulse_Beta/ config.xml cron/ cron-boinc David 16 Oct 2003 - Factored out the part of graphics that is common to both SETI@home and Astropulse (SAH_GRAPHICS_BASE, in sah_gfx_base.cpp) This will make it easier to maintain consistent graphics and preferences between the two apps client/ sah_gfx.cpp,h sah_gfx_base.cpp,h (new!) win_build/seti_boinc.dsp Jeff 17 Oct 2003 - Best triplet PoT starting tag now has encoding type and length. - Flush the results file (outfile) only at checkpoint time and workunit completion time. - Cleared out various old comments and debug lines. client/ analyzeFuncs.cpp analyzeReport.cpp seti.cpp Oliver 17 Oct 2003 - Fixed panel size client/ sah_gfx.cpp Jeff 17 Oct 2003 - Checkpoint the gaussian display power threshold. This used to be set to zero at program start/restart and then get bumped to a higher value with the first gaussian (but then get set back to zero on the next restart). Thus, if the best gaussian in the WU was in fact below tha higher thershold, the same WU could yield different best gassians depending on restart history. This would have interfered with redundacy based validation. client/ analyzeReport.cpp gaussfit.cpp seti.cpp seti.h Jeff 18 Oct 2003 - Code cleanup. Removed some long commented out code and unneeded header files. client/ analyzeReport.cpp,h gaussfit.cpp seti.cpp,h spike.cpp David 20 Oct 2003 - Don't use len_prof as pulse PoT length; use PULSE_POT_LEN client/ gdata.cpp,h sah_gfx.cpp Jeff 22 Oct 2003 - Specify app version as 2.00. - Use new xml_util routines to output the triplet PoTs to the state file as comma separated values. The min and max PoTs are now printed to the state file as 2 separate PoTs. configure.ac client/ seti.cpp David 23 Oct 2003 - fixed bug where an MFILE::printf() was overrunning its static buffer. (use MFILE::write() instead; also upped buffer size to 20K) client/ seti.cpp Oliver 24 Oct 2003 - updated so that it will pass the name of the axis labels in when graph is created client/ analyzeFuncs.cpp sah_gfx.cpp sah_gfx_base.cpp,h David 25 Oct 2003 - split the graphics initialization into two parts: 1) worker thread, which sets up the data structure shared between worker and graphics 2) graphics thread, which does OpenGL calls (must be in graphics thread). This fixes a race condition where sometimes the worker thread would access the shared data structure before it was initialized. - check for logos present before drawing. Fixes bug with white boxes drawn in place of logos client/ main.cpp sah_gfx.cpp sah_gfx_base.cpp,h Jeff 27 Oct 2003 - use match_tag() rather than parse_str() to find the triplet PoT's in the state file. - bump version to 2.01. configure.ac client/ seti.cpp Eric K. 27 Oct 2003 - tried to fix the indentation problem by storing and recovering the xml_indent_level at the beginning and end of write_state_file() client/ seti.cpp Jeff 27 Oct 2003 - renamed output file to result.sah client/ s_util.h David 28 Oct 2003 - call boinc_resolve_filename() for input, output files client/ worker.cpp Jeff 29 Oct 2003 - bumped version to 2.03 configure.ac Oliver 29 Oct 2003 - fixed scaled logos client/ sah_gfx_base.cpp Jeff 29 Oct 2003 - gather up the entire triplet PoT from the state file before sending it off to the XML parser. - bump version to 2.04 client/ seti.cpp configure.ac Jeff 30 Oct 2003 - simplified the coding and raised the buffer size to 8K in parse_state_file(). client/ seti.cpp David 31 Oct 2003 - reorganized graphics to accommodate new BOINC mechanism for adaptation to changing user preferences. SAH_GRAPHICS now includes graphics objects rather than pointers, since the may need to be init()ed repeatedly. The code organization is described in a block comment at the top of sah_gfx.cpp - in panel display, panel colors are 1/3 and 2/3 points of hue range client/ analyzeFuncs.cpp main.cpp sah_gfx.cpp,h sah_gfx_base.cpp,h win_build/ seti_boinc.dsp David 1 Nov 2003 - more "graphics follow prefs" changes client/ sah_gfx.cpp sah_gfx_base.cpp David 4 Nov 2003 - removed old code (reduce_output() etc.) that output the top N signals globally - removed *_start() and *_end() functions from source files. These are relics of an old and failed code-checksum scheme - use string instead of char[256] a few places client/ analyzePot.cpp analyzeReport.cpp gasdev.cpp gaussfit.cpp malloc_a.cpp pulsefind.cpp ran1.cpp seti.cpp seti_header.cpp worker.cpp David 4 Nov 2003 - released version 2.05 in beta test Jeff 5 Nov 2003 - beta released setiathome_2.06_sparc-sun-solaris2.7. Looks like setiathome_2.06_windows_intelx86 was released yesterday. David 6 Nov 2003 - track BOINC API changes client/ sah_gfx.cpp win_build/ seti_boinc.dsp David 6 Nov 2003 - release windows version 2.07 Jeff 17 Nov 2003 - Added the GNU GPL to files in client/, db/ (except db/tools/), m4/, and some top level files. Removed some obsolete files. client/ * added GPL except... fft8g.cpp added ooura license *.{cpp,h} removed CVS/RCS log lines gasdev.cpp removed ran1.cpp removed nr.h removed lcgamm_test.cpp removed Makefile.in removed references to nr stuff db/* added GPL (but not to files in tools/) m4/* added GPL - I also created a public release distribution that includes everything needed to build the client side application. We should automate this. For reference, the distro contains no CVS directories and does contain: COPYING config.guess config.h.in config.sub configure configure.ac install-sh Makefile.in aclocal.m4 config.h client/* *except* : win_build/ Logo2.bmp Logo2.jpg p004_640.jpg db/* *except*: tools m4/* Karl 2003-11-21 - recompiled with BOINC api bug fix. - 2.08 client release (non-Windows only) David 25 Nov 2003 - change to - restored missing }; - removed deleted files from .dsp file client/ analyzeFuncs.cpp analyzeReport.cpp spike.cpp sah_gfx_base.h,cpp win_build/ seti_boinc.dsp Jeff 27 Nov 2003 - New release - bumbed version to 2.10 configure.ac Jeff 01 Dec 2003 - Added debug code and fixed path bugs in validator and assimilator. The production validator should be working at this point. validator/ sah_boinc_db.cpp sah_boinc_db.o assimlator/ sah_assimilate_handler.cpp Karl 2003-12-02 - created script to trim sources of files we don't want to distribute. (it's a badass 'find' line) - created nightly tarball script. trim-sources (added) nightly-tarball (added) Jeff 03 Dec 2003 - released a statically linked version of the app for linux. Bumped version to 2.11 configure.ac Jeff 08 Dec 2003 - We have the same gcc version problem with solaris that we do with linux whereby if the version number of libstdc++.so on the run machine is different than that on the build machine, the loader fails. However, on solaris you cannot just say gcc -static as there are dynamic only versions of some needed libs, namely libdl and libaio. I tried to use the -Xlinker gcc option which theoretically should allow us to specify the link (collect2) line in precise detail. But -lstdc++ kept showing up twice with one occurrence being outside my -Xlinker -B -Xlinker static directive. So I hand crafted a collect2 line and placed it in a file - collect2_line. Sourcing this file produces an executable that will load and run across gcc versions (and solaris versions for that matter). I don't like it but it works. client/ collect2_line (new file) Jeff 09 Dec 2003 - Released version 2.12 for solaris 7, with a statically linked stdc++. configure.ac client/ collect2_line Eric K. 13 Dec 2003 - Changed from error return to exception based error handling. - The seti_error class is defined in s_util.[h,cpp] - Not yet tested under Windows... client/ analyzeFuncs.cpp analyzePoT.cpp analyzeReport.cpp chirpfft.cpp gaussfit.cpp main.cpp pulsefind.cpp s_util.cpp s_util.h seti.cpp seti_header.cpp spike.cpp worker.cpp 12/16/03 jeffc - The SETI_WU_HEADER was declared gloabally as "seti_wu_header" but was passed around by reference, usually under the name "swi". This passing around was historical and had become confusing and needless. This change is the first of 2 steps to have all code access the global SETI_WU_HEADER as "swi". I removed the passing of the entire swi from all function calls that had it. Still to do is to remove the passing of individual fields of swi. client/ analyzeFuncs.cpp,h analyzePoT.cpp,h analyzeReport.cpp chirpfft.cpp,h gaussfit.cpp seti.cpp,h seti_header.cpp,h spike.cpp worker.cpp 12/16/03 jeffc - The assimlator to insert into the science DB. assimilate/ sah_assimilate_handler.cpp Jeff 18 Dec 2003 - Commented out the catch "(boinc_error e) {}" in main.cpp. Windows compiles were failing on it. - Removed the second parameter, "wu", from the cnvt_fftlen_hz() call in in sah_gfx.cpp. The prototype of cnvt_fftlen_hz() has changed and wu was wrong (and unused) anyway. client/ main.cpp sah_gfx.cpp Jeff 19 Dec 2003 - New windows release - setiathome_2.13_windows_intelx86. This was built on machine "bart", winXP, VC6. - Note that with this release I started archiving both release and debug builds (with symbol table files) in apps_release_sets/ in the project directory. The contents fo this windows release is: apps_release_sets/setiathome_2.13_windows_intelx86/release/ setiathome_2.13_windows_intelx86 vc60.idb apps_release_sets/setiathome_2.13_windows_intelx86/debug/ setiathome_2.13_windows_intelx86.exe setiathome_2.13_windows_intelx86.pdb vc60.idb vc60.pdb Jeff 22 Dec 2003 - New windows release - setiathome_2.14_windows_intelx86. This is the debug build associated with release 2.13. David 23 Dec 2003 - fixed bug in seti_parse_data(): "catch" clause was freeing a pointer that wasn't always assigned client/ seti.cpp Jeff 26 Dec 2003 - Made sure that we always initialize retval to 0. client/ analyzeFuncs.cpp analyzeReport.cpp seti.cpp worker.cpp Jeff 26 Dec 2003 - Added boinc/lib/filesys.C,h to windows VC++ project. - Bumped version to 2.17. - Released windows app 2.17 (debug version). client/ configure.ac client/win_build/ seti_boinc.dsp Eric (via Jeff) 26 Dec 2003 - Implement copy and assignment constructors for SPIKE_INFO. client/ seti.h spike.cpp analyzePoT.cpp Jeff 28 Dec 2003 - Make sure that retval is checked after calls to MFILE::printf. client/ analyzeFuncs.cpp seti.cpp Jeff 28 Dec 2003 - release windows app 2.18 Jeff 29 Dec 2003 - release solaris app 2.18 (semi-static build) configure.ac (bump version) configure Jeff 30 Dec 2003 - release linux app 2.18 (static build). The build was done on host shaggy. There is some malfunctioning of autoconf/configure such that I had to hand code -DHAVE_ATOLL and -DHAVE_DIRENT_H into client/Makefile and VERSION_MAJOR VERSION_MINOR into config.h. Jeff 5 Jan 2004 - Commented out the generation of reconfigure code in the top level Makefile. Makefile.in Jeff 5 Jan 2004 - Removed depricated code used in processing old style (nonXML) WU headers. - Removed depricated code used in processing command line science params (science tuning is now done in the WU header). - Overloaded the seti_parse_wu_header() and seti_write_wu_header() functions. One version of each makes use on the global SETI_WU_INFO structure and one version of each takes a SETI_WU_INFO reference as a parameter. - Moved the global SETI_WU_INFO from seti.cpp to seti_header.cpp so that the splitter could see it. Linking the splitter to seti.o produced a number of unresolved symbols. We should probably put all global objects in some file called global.cpp. - Added a CC= line to the splitter's Makefile.in and removed some test programs. client/ main.cpp seti.cpp seti_header.cpp,h splitter/ Makefile.in Jeff 9 Jan 2004 - The splitter places the seti WU ID into the boinc WU opaque field. Now the assimlator reads that ID from the boinc WU opaque field and places it into the seti result wuid field, providing a reference from result to workunit. assimlator/ sah_assimilate_handler.cpp Jeff 13 Jan 2004 - A many line set of changes to have the code use the analysis configuration parameters in the WU header rather than those in analyze.h. Specifically: - Removed all analysis paramters from analyze.h. For reference, these were: #define BOX_CAR_LENGTH 8192 #define POINTS_IN_CHUNK 32768 #define SPIKES_TO_REPORT 1 #define SIGMA_THRESH 22 #define THRESH_IN_MEAN 3 #define THRESH_IN_TRUEMEAN 3.2f #define CHI_SQ_THRESH 8.8f #define PULSE_MAX 40960 #define PULSE_MIN 16 #define PULSE_FFT_MAX 8192 #define PULSE_THRESH 17.0 #define PULSE_DISPLAY_THRESH 0.5f #define TRIPLET_MAX 131072 #define TRIPLET_MIN 16 #define TRIPLET_THRESH 7.75 #define OVERLAP_FACTOR 0.5 #define PULSE_BEAMS 1.0 #define GAUSS_POT_LEN 64 #define PULSE_POT_LEN 256 #define TRIPLET_POT_LEN 256 #define POT_LEN 64 #define T_OFFSET 1 #define MIN_SLEW 0.0021f #define MAX_SLEW 0.0105f #define BEAM_WIDTH 0.1 #define GAUSS_SIGMA 6.78 #define GAUSS_SIGMA_SQ 45.9684 - In all places where analyze.h paramters where used, switched to the corresponding swi.analysis_cfg field. - Many of the PoTInfo fields had been initialized at compile time with analyze.h values. PoTInfo is now initialized at compile time with zeros and and with swi.analysis_cfg values at run time in ComputePoTInfo(). - The signal info objects (SPIKE_INFO, etc) used to be globally instantiated at compile time in analyzeReport.cpp. These are now global pointers (in analyzeReport.cpp). They are instantiated via reset_high_scores() at run time. reset_high_scores() first deletes the signal info objects if they exist and then (re)new's them into existance. This change was needed because PoT array sizing within these objects is now a run time function. - All '.' notation to get to signal info fields had to be changed to "->" throughout the code. - Moved the signal info method code from seti.h (where it was inline) to seti.cpp (where it is not). client/ analyze.h analyzeFuncs.cpp,h analyzePoT.cpp analyzeReport.cpp,h gaussfit.cpp pulsefind.cpp seti.cpp,h seti_header.cpp spike.cpp,h Jeff 14 Jan 2004 - added the following #defines back, in gdata.h this time. There are graphics only global signal info structures whose PoT arrays are sized at compile time. Making these dynamic would probably mean instantiating them via new in main.cpp right before the call to sah_graphics.worker_thread_init() or in sah_graphics.worker_thread_init() itself. Note that at this point, graphics initialing happens *before* we read in the WU and the included analysis config info. That would have to change. #define GAUSS_POT_LEN 64 #define PULSE_POT_LEN 256 #define TRIPLET_POT_LEN 256 client/ gdata.h Jeff 14 Jan 2004 - Added 2 new fields to analysis_config table: pulse_beams smallfloat max_signals integer These fields have been added to analysis_config table in the sah2@master_tcp database but have not yet been given values. db/ schema_master.sql schema_master.h schema_master.cpp Jeff 15 Jan 2004 - Changed to pointer syntax for _INFO structs in the G__INFO copy constructors. client/ gaussfit.cpp spike.cpp analyzeReport.cpp gdata.cpp,h Jeff 15 Jan 2004 - Added new row (id = 4) to table analysis_config in the backend DB. Changed: bsmooth_chunk_size from 32767 to 32768 pulse_beams from NULL to 1.0 (new field) max_signals from NULL to 30 (new field) max_signals may need to be adjusted. db/tools/ analysis_configs.xml Jeff 15 jan 2004 - Added stackwalker source to the client win_build directory. This code was copied over from the boinc source tree. client/ win_build/ Stackwalker.cpp,h David 15 Jan 2004 - validator: if can't get output file, mark the result as invalid. This deals with situations where (usually because of a BOINC bug) there is no output file, and infinite retrying won't help. validate/ sah_boinc_db.cpp sah_validate.cpp David 19 Jan 2004 - call initGL() in SAH_GRAPHICS_BASE::graphics_thread_init() (moved from windows_opengl.C, to remove OpenGL dependency) - add win_util.h to project client/ sah_gfx_base.cpp win_build/ seti_boinc.dsp Jeff 20 Jan 2004 - fixed a bug in the G_PULSE_INFO copy constructor where the pulse proper pot was being assigned rather than pot_max. - removed references to GAUSS_INFO.pot as it was not being used anywhere. This was the floating point pot outside of the gaussian proper. client/ gdata.cpp seti.cpp,h Jeff 21 Jan 2004 - removed a redundant call to reset_high_scores() in parse_state_file(). The call in seti_init_state() suffices. - removed the call to report_init() in seti_analyze and replaced its functionality with a call to new function reload_graphics_state() in parse_state_file(). - removed unneeded calls to boinc_time_to_checkpoint() in seti_analyze(). client/ analyzeFuncs.cpp analyzeReport.cpp,h seti.cpp Jeff 22 Jan 2004 - app release 2.19. Cvs tagged as app_release_2_19. client/ configure configure.ac Jeff 22 Jan 2004 - removed depricated and commented out code. client/ analyzeFuncs.cpp analyzePoT.cpp analyzeReport.cpp main.cpp seti.cpp seti_header.cpp spike.cpp Jeff 26 Jan 2004 - changed all calls to match_tag() to xml_match_tag(). - (via Eric) implemented assignment and copy constructors for TRIPLET_INFO. - moved call to seti_init_state() to after the call to seti_parse_wu(). This is was necessary because seti_init_state() needs configuration data contained in the WU header. This may fix a number of access violations and seg faults. client/ analyzeReport.cpp seti.cpp,h seti_header.cpp worker.cpp Jeff 28 Jan 2004 - Fixed a bug in the copy constructor for PULSE_INFO - Got stackwalker working (Rom Walton did this). - got rid of the dependency on the windows debug runtime (Rom). - Bumped version to 2.21 for release. - Cvs tagged as app_release_2_21. client/ main.cpp seti.cpp configure.ac configure win_build/ seti_boinc.vcproj Jeff 30 Jan 2004 - Invoke stackwalker in stack trace mode only. It was crashing with with an access violation during memory allocation tracing. (Rom Walton) - Made progress more linear by treating pulse finding as it should be - an (n^2)log(n) operation. - Update global progress upon each return from find_pulse. This happens several times for reach frequency bin, ie much more often than before. - CVS tagged source as app_release_2_22 and released as version 2.22 on the windows platform. configure.ac configure client/ main.cpp (Rom) analyzeFuncs.cpp analyzePoT.cpp progress.cpp,h (new files) Makefile.in win_build/ seti_boinc.vcproj (added new files) Jeff 01 Feb 2004 - Changed the pulse finding progress scale factor from 1/1e6 to 1/.65e6. - Removed commented out code. client/ progress.cpp analyzeFuncs.cpp analyzePoT.cpp Jeff 02 Feb 2004 - Progress clean up. client/ analyzePoT.cpp progress.cpp Rom 02 Feb 2004 - Hooked up to diagnostics library - Replaced ANSI C assert with BOINCASSERT client/ analyzePot.cpp analyzeReport.cpp lcgamm.cpp main.cpp spike.cpp client/winbuild seti_boinc.vcproj Rom 03 Feb 2004 - Modified stackwalker so it attemps to use the dbghelp.dll that is included with BOINC before using the search path. client/winbuild stackwalker.cpp Jeff 03 Feb 2004 - Moved progress related globals from analyzeFuncs.cpp,h to progress.cpp,h. - Changed some floats to doubles to get rid of compile warnings. client/ analyzeFuncs.cpp,h analyzePoT.cpp progress.cpp,h seti.cpp worker.cpp Jeff 04 Feb 2004 - Windows release. - CVS tagged source as app_release_2_23. Rom 05 Feb 2004 - Remove stackwalker from the project as it has been moved to the boinc project api folder - updated project files to new locations client/win_build/ seti_boinc.vcproj stackwalker.h stackwalker.cpp Rom 06 Feb 2004 - Removed boincdiag.cpp, h from project files. client/win_build/ seti_boinc.vcproj Jeff 08 Feb 2004 - Impelmented overflow detection. Upon reaching a maximum signal count the app will throw a RESULT_OVERFLOW exception on the next attempt to write a signal. Max_signals is an anlaysis config parameter. It is not yet being provided in the WU headeer so the app has it hard coded with the value 30. The current signal count is saved to and read from the state file. - PoTInfo.PulseBeams now gets its value from an analysis config paramter. It is not yet being provided in the WU headeer so the app has it hard coded with the value 1.0. - Renamed write_state_file() to checkpoint() as this routine is doing more than writing to the state file. - Routine checkpoint() now has a paramter to tell it to force the checkpoint without a call to boinc_time_to_checkpoint(). client/ analyzeFuncs.cpp analyzePoT.cpp analyzeReport.cpp,h main.cpp s_util.cpp,h seti.cpp,h seti_header.cpp Jeff 11 Feb 2004 - kludge fix to the pulse display PoT assert failures. If we see a value over 255, we set it to 255. - change all match_tag() calls to xml_match_tag() calls in the db/ code. - bumped version to 2.24. - Windows release. - CVS tagged source as app_release_2_23. client/ analyzeReport.cpp win_build/ seti_boinc.vcproj db/ schema_master.cpp schema_to_class.awk configure configure.ac Jeff 12 Feb 2004 - max_signals and PoTInfo.PulseBeams both now get their values from the analysis_cfg in the swi. - make sure that the work areas are freed before exiting GenChirpFftPairs(). client/ seti_header.cpp chirpfft.cpp Rom 19 Feb 2004 - Attempt to track down error 128 by specifying GLU32.DLL, GLUT32.DLL, OPENGL32.DLL, and OLE32.DLL (Debug Build Only) as Delay-Load DLL's. This causes an exception to be thrown if the DLL isn't found instead of the OS poping up a dialog the user has to deal with. client/win_build/ seti_boinc.vcproj Jeff Feb 19 2004 - CVS tagged as seti_boinc_app_release_2_25. Rom 19 Feb 2004 - When throwing exceptions, make the exception contain line and file information. client/ analyzeFuncs.cpp analyzePoT.cpp analyzeReport.cpp chirpfft.cpp gaussfit.cpp main.cpp pulsefind.cpp s_util.cpp, h seti.cpp seti_header.cpp spike.cpp worker.cpp Rom 19 Feb 2004 - Revert one try/catch block back to the orginal int type instead of what I converted it to so it'll actually execute the cleanup code for DATA_SUN_BINARY encodings. client/ seti.cpp Rom 23 Feb 2004 - Sample exception in main. client/ main.cpp Jeff Feb 25 2004 - CVS tagged as seti_boinc_app_release_2_26. This tag is a little late but the sources should be little if any changed. Rom 06 Mar 2004 - Include file overhaul on the Windows platform. This fixes the build breaks introduced by the changes to the BOINC include file structure on the Windows platform I pretty much touched all the source and header files. This checkin should not have any effect on any platform other than Windows. Rom 08 Mar 2004 - Fix build breaks on Solaris/Linux Lib/ sah_gfx.cpp sah_gfx_base.cpp Eric 08 Mar 2004 - Fixed pulse reported POT for len_prof>analysis_config.pulse_pot_max. pulse.len_prof is now set to zero and the pi.pot is .clear()ed. - changed match_tag in db_table.h to xml_match_tag to fix parsing problem client/ analyzeReport.h analyzeReport.cpp db/ db_table.h Jeff 09 Mar 2004 - Bumped to version 2.27. - CVS tagged as seti_boinc_app_release_2_27. configure.ac configure Rom 09 Mar 2004 - Reduce user confusion by marking the results_overflow exception as an informational message instead of an error. client/ main.cpp Rom 13 Mar 2004 - Updated time_sources script so that the image libraries could be included in the nightly drops. Jeff Mar 15 2004 - CVS tagged boinc and seti_boinc as boinc_app_release_2_28. Jeff Mar 18 2004 - Validator overflow code. validate/ sah_validate.cpp Jeff Mar 19 2004 - Result file now has bounding tags. client/ worker.cpp analyzeFuncs.cpp BTW, here is how to build the mac osx client/app in such a way that you can specify the build name: configure --build powerpc-apple-darwin Jeff Mar 22 2004 - Improved debug logging in the validator. validate/ sah_validate.cpp Rom Mar 22 2004 - Force the memory allocation functions to include file and line information for each allocation. - Turn on the memory leak detection report for Windows built binaries - replaced malloc_a/calloc_a/free_a with their Windows CRT equivs. This only applies to Windows when being compiled as Debug. - Fixed a couple of bugs where the copy constructors and assignment operators were only coping a fraction of what they intended to copy client/ analyzeFuncs.cpp analyzePoT.cpp analyzeReport.cpp main.cpp malloc_a.h pulsefind.cpp seti.cpp stdafx.h client/win_build/ seti_boinc.vcproj Rom Mar 22 2004 - Attempt to force load glut32.dll in a specific location, if it fails catch the SEH exception and just disable grapgics. client/ sah_gfx_base.cpp stdafx.h Rom Mar 23 2004 - client applications don't really need to dump leak detection information for public consumption. So remark it out for public release. - Tag for a 2.29 release. Rom Mar 23 2004 - Unify all diagnostics functionality under the same banner, SETI_BOINC, BOINC_CLI, BOINC_GUI, upper_case now all initialize the BOINC Diagnostics Library which sets up stdout and stderr redirection, heap corruption detection, stackwalker for Windows, and stackalker fo *nix can be pluged in and be automatically used by all applications. - Taskbase#1131 -- closed - Taskbase#1132 -- closed client/ analyzeReport.cpp lcgamm.cpp main.cpp stdafx.h client/winbuild/ seti_boinc.vcproj Jeff Mar 24 2004 - Fixed nightly tarball generation so that autoconf,configure,make will result in a successful build. trim_sources added awk line to trim configure.ac configure.ac made sure lines to be trimmed are clear of autoconf special characters Rom Mar 25 2004 - I have made SETI_BOINC Glut Free, Basically copied font code from glut and put it into the glut folder. - Removed Glut libraries - Removed Delay Load technologies client/win_build seti_boinc.vcproj client/win_build/glut glut/ Rom Mar 25 2004 - Fix up project file so it'll build on a clean platform. client/win_build seti_boinc.vcproj Jeff Mar 26 2004 - Release tags. Sources were tagged as seti_boinc_release_2_30 and then, after some build problems were fixed, were tagged as seti_boinc_release_2_30a. The build from this latter tag was what was released as app version 2.30. Jeff Mar 26 2004 - Removed parseOutfile from the project. Rom Mar 26 2004 - Fix a minor bug where after the screen saver shutdown BOINC would fire-up a new SAH Window - Tag for a 2.31 release. client/win_build seti_boinc.vcproj Rom Mar 30 2004 - Include the glut folder in the nightly tarball / trim_sources Jeff Mar 31 2004 - Nightly tarball generation now runs autoconf to produce a configure script stripped of the trimmed directories. trim_sources David Mar 31 2004 - handle mouse events, and offer a simple interface where dragging rotates the 3D objects client/ sah_gfx.cpp sah_gfx_base.cpp,h Jeff April 2 2004 - Kludge fix for the access violations we see in csv encoding. In the checkpoint routine I check len_prof of the best_pulse and if it is zero we do not write that pulse to the state file. - tagged as seti_boinc_app_release_2_32 and released to alpha. client/ seti.cpp Jeff April 8 2004 - Have splitter give full path to result template on read error. - Correct configure defined PROJECTDIR / aclocal.m4 configure splitter/ splitter.cpp Jeff April 12 2004 - tagged with: seti_boinc_app_release_3_00 David April 12 2004 - when get OVERFLOW exception we need to call boinc_finish(), else the core client won't regard the result as done client/ main.cpp David April 14 2004 - include "mfile.h" client/ analyzeReport.h Rom April 20 2004 - Turn on tracing of CRT warnings by default since the CRT considers heap corruption a warning offense instead of an error. client/ main.cpp David April 22 2004 - change all fopen()s to boinc_fopen(). This is necessary to avoid EINTR failures on Unix, and locking-related failures on Windows client/ chirpfft.cpp seti.cpp worker.cpp Jeff April 30 2004 - Fixed bug where a call to encode() lacked a parameter. db/ sqlblob.h Jeff May 13 2004 - Overflow results are now marked thusly in the SAH master science DB. Boinc result.opaque is used to pass the overflow flag from the validator to the assimilator. - Fixed bug that resulted in the following assimilator error message: Too many open SQL statements (> 20) for sql operations The fix (via Eric) was to do an sql_close(fd) before each return(false) in sql_run(). validate/ sah_validate.cpp sah_result.h assimilator/ sah_assimilate_handler.cpp db/ sqlifx.ec David May 15 2004 - Some changes to reflect the new STARFIELD handling (which is done entirely in 2D). Call app_init_camera() in SAH_GFX_BASE::render(), instead of just once at the beginning. Since this is where viewpoint distance is handled, we no longer have to do it in the mouse handler. - add glFlush() to SAH_GFX_BASE::render() client/ sah_gfx.cpp sah_gfx_base.cpp,h win_build/init_data.xml Jeff May 18 2004 - corrected printf format for logging seti WU ID as contained in the boinc:result.opaque field. assimilate/ sah_assimilate_handler.cpp Jeff May 18 2004 - Testing notes. I followed WU 11se03aa.9564.4544.428382.126 through the system (seti side DB, boinc side DB, files) and found that the following (at least) are working properly: - seti workunit_grp points to tape - seti wu points to workunit_grp - seti result points to seti wu - seti result points to boinc result - the data description in the workunit_grp (DB) looks OK and appears properly in the wu file - the following all look good in the seti DB and appear properly in the wu file: - receiver_config - recorder_config - splitter_config - analysis_config *except* that the xml field in the wu file receiver_config section has the string "apos" improperly embedded (task 1275). - the workunit_header's in the wu file and result file are identical *except* that the wu name in the result file is incomplete (task 1274). - the 1 reported pulse signal also appears as the best pulse in the result file and is inserted properly in the DB. - the 1 triplet signal also appears as the best triplet in the result file and is inserted properly in the DB. - the 7 spikes are inserted properly in the DB and the highest power spike appears as the best spike. - there was no gaussian in this wu. Jeff May 18 2004 - Place app version number and received time as julian day into the result record in the seti master DB. assimilate/ sah_assimilate_handler.cpp Jeff May 21 2004 - Targeted heap checking. Placed the following code: #ifdef _WIN32 BOINCASSERT(_CrtCheckMemory()); #endif at the beginning and end of the following functions: find_pulse() ReportPulseEvent() ReportTripletEvent() checkpoint() parse_state_file() and at the beginning and end of all PULSE_INFO and TRIPLET_INFO contructors and destructors. - use time_t_to_jd() to calculate julian day in the assimilator. client/ pulsefind.cpp analyzeReport.cpp seti.cpp assimilate/ sah_assimilate_handler.cpp Makefile.in Jeff May 25 2004 - Obtain analysis configuration table for result pre-proccessing (eg barycentric frequency calculation). - Pre-processing stub routines. - Check the new noinsert flag (command line parameter). assimilate/ sah_assimilate_handler.cpp Rom May 25 2004 - tagged with: seti_boinc_app_release_3_07 Rom May 26 2004 - updated config.guess based of David's checkin in BOINC - Update config.guess so we don't have to add the --build command to each execution of ./configure for the Macs / config.guess David May 27 2004 - resize(), graphics_thread_init(): do OpenGL stuff ourselves client/ sah_gfx_base.cpp David May 27 2004 - change logo-rendering code to use (0,1)x(0,1) coord system instead of bizarre 3x4 stuff client/ sah_gfx.cpp sah_gfx_base.cpp,h Jeff june 2 2004 - Upped minimum quorum from 2 to 3. splitter/ wufiles.cpp David June 2 2004 - changed default graphics prefs client/ sah_gfx_base.cpp David June 8 2004 - change boinc_resolve_filename() calls client/ seti.cpp worker.cpp David June 11 2004 - moved xml_util* here from BOINC db/ xml_util.C,h (new) David June 11 2004 - added xml_util.C,h to Windows project file Note: doesn't build on Windows. Indecipherable error messages involving std::XXX stuff client/win_build/ init_data.xml seti_boinc.vcproj db/ xml_util.C Rom June 12 2004 - Cleanup build errors on Windows client/ chirpfft.cpp s_util.cpp sah_gfx.cpp sah_gfx_base.cpp stdafx.cpp timecvt.cpp client/win_build/ seti_boinc.vcproj db/ schema_master.cpp schema_to_class.awk sqlrow.cpp xml_util.C, .h Jeff June 15 2004 - Check for memory allocation failures in signal info constructors. - Cleanup build errors on *nix. client/ seti.cpp db/ Makefile.in Jeff (for Eric) June 15 2004 - New routine, db_change(). db/ schema_to_class.awk schema_master.cpp schema_master.h Rom June 15 2004 - Tag for 3.08 release, all platforms seti_boinc_app_release_3_08 Jeff June 15 2004 - Strip leading zero from minor version. configure.ac David 15 June 2004 - added rule for .C files client/Makefile.in Jeff 16 June 2004 - Modifications to allow the same splitter executable to run under different projects, say beta and public. The mods are: - The backend sciece DB name was hard coded in splitter.cpp and is now a required command line parameter (-scidb=). We are using the new db_change() routine to attach to the desired DB. - The project directory was hard coded in config.h (PROJECTDIR) and is now a required command line parameter (-projectdir=). - the download directory was hard coded in splitparms.h as WU_DIR. This was changed to WU_SUBDIR which equates to "download" and concatenated to the projectdir to get the fully qualified download directory. splitter/ splitter.cpp,h splitparms.h makebufs.cpp wufiles.cpp Rom 16 June 2004 - Fix awk script so it'll coreectly deal with stdafx.h db/ schema_master.cpp schema_to_class.awk David 16 June 2004 - include miofile.C in project client/win_build/ seti_boinc.vcproj Jeff 17 June 2004 - Change xml_util.C to xml_util.cpp. db/ xml_util.C deleted xml_util.cpp added Makefile.in Jeff 18 June 2004 - Splitter now reads the science DB name from an application config file. This config file and the parsing of it is modeled on the boinc config file. It is called sah_config.xml and resides in the project directory. - Routine db_change() now dies nothing is the requested DB is already open. db/ app_config.cpp,h new files schema_to_class.awk schema_master.h Makefile.in splitter/ splitter.cpp wufiles.cpp Jeff 20 June 2004 - Assimilator now reads the science DB name from an application config file. - Added pre_process stubs to assimilator (will be used for reference frame correction etc). assimilator/ sah_assimilate_handler.cpp,h Makefile.in Jeff 21 June 2004 - Changed fpops numbers on the splitter (these numbers appear in the WU. db_wu.rsc_fpops_est from 3.9e+12 to 2.79248e+13 db_wu.rsc_fpops_bound from 6.4e+13 to 4.46797e+14 Keeping the ratio of bound to estimated at 16/1. splitter/ wufiles.cpp Karl 2004-06-24 OpenBSD compile fixes from Daniel Hartmeier client/ worker.cpp db/ xml_util.h Eric K 30 June 2004 - Removed "using" directives from header files. "using" directives should not be used in header files for the following reasons. - A "using namespace" directive cannot be revoked for any source file including the header. It forces the use of the namespace regardless of the consequences. - Dropping the namespace qualifier on STL templates ambiguates the resolution of template functions. (How many C libraries or headers have you seen that define the function min()?) - Reducing typing is not a good reason to drop namespace qualifiers any more than it would be a good idea to "#define p printf" - Namespaces exist for a reason. - It's acceptable to have "using" directive in a source file, since it won't affect other files. It's better to have "using std::string;" directives than "using namespace std;" for hopefully obvious reasons. Eric K 1 July 2004 - changed the sql type of pot in gauss in triplet from char[64] to byte - added a print_raw() method to the sqlblob class - changed the gaussian null chisqr threshold to 2.075 to increase the number of gaussians found. client/gaussfit.cpp db/schema_master.cpp db/schema_master.sql db/schema_to_class.awk db/sqlblob.h db/sqlifx.ec db/sqlrow.cpp db/sqlrow.h db/tools/analysis_configs.xml David 7 June 2004 - compile fixes, and use new BOINC API client/ main.cpp sah_gfx_base.cpp Jeff 9 July 2004 - Splitter uses new prototype to create_work() in order to specify the fully qualified path to the result template file. - Because the query to count unsent results takes a long time, we only perform the query every once every 100 times into wait_for_db_wus_ondisk(). All other calls to this routine return immediately, indicating a need for work. Further, while in the wait for work loop, we perform the query only every 10 minutes. - For Eric - the FOPS estimates have bben increased by a factor of 6 (previous code checkin). splitter/ splitter.cpp,h wufiles.cpp Jeff 12 July 2004 - db_change() will do nothing but return db_is_open if the requested database is already open. db/ schema_to_class.awk Jeff 12 July 2004 - as a matter of policy, application handlers called by boinc programs (ie the validator and assimilator) should handle error returns from boinc functions themselves rather than return the error up to boinc code. This change is for the assimilator to issue a message and then exit if it cannot parse the project config file or if it cannot connect the the project (boinc) DB. ssimilator/ sah_assimilate_handler.cpp Jeff 15 July 2004 - At Rom's request, backed out Eric's fops estimation changes (see entry of 9 July 2004). splitter/ wufiles.cpp Rom July 15 2004 - Tag for 4.00 release, all platforms seti_boinc_app_release_4_00 David July 19 2004 - Win build: changed output filename to 4.00 client/win_build/ seti_boinc.vcproj Noaa 30 July 2004 - changed headers for sah_gfx_base.cpp - different Makefile.in (ie Makefile.in.graphics) that can be put in place of Makefile.in before configure to configure for graphics, may need to be changed slightly depending on user, description in Makefile.Readme client/ sah_gfx_base.cpp Makefile.in.graphics (new) Makefile.Readme David 3 Aug 2004 - BOINC API change client/ main.cpp Noaa 5 August 2004 - changed lglut to lboincglut in Makefile.in.graphics - changed Makefile.Readme to reflect that - added a Graphics.Readme to explain how to install w/graphics / Graphics.Readme client/ Makefile.in.graphics Makefile.Readme Noaa 6 August 2004 - Minor change to Makefile.Readme - change of sah_gfx_base.cpp headers client/ Makefile.Readme sah_gfx_base.cpp Jeff 12 Aug 2004 - use hierarchical uldl directory structures (see boinc checkin notes). - call perror() when splitter cannot fork(). assimilator/ sah_assimilate_handler.cpp validate/ sah_boinc_db.cpp splitter/ splitter.cpp wufiles.cpp Jeff 13 Aug 2004 - bumbed the WU ondisk threshold from 20k to 50k. - fixed a bad call to create_work(). The prototype had changed. splitter/ splitparms.h wufiles.cpp Jeff 24 Aug 2004 - officially renamed the splitter executable to sah_splitter splitter/ Makefile.in Jeff 25 Aug 2004 - tell dir_hier_path() to create download subdirs as needed. splitter/ wufiles.cpp David 30 Aug 2004 - created html/ directory html/ (new) project.inc Jeff 09 Sep 2004 - Change to the validator to handle the case where one or more of the result files for a WU's result set are missing. Before this change this state would result in this WU and it's results never getting looked at again. No science, no credit. This is coordinated seti_boinc / boinc change. This note is repeated in the boinc checkin_notes. seti_boinc changes: - get_result_file(), if it cannot read the result file, tries to read the directory where the result file should be. If it can read the directory, it returns ERR_FOPEN, as before. If it cannot read the directory, it resturns ERR_OPENDIR. ERR_OPENDIR in this context signals a possibly transient problem. Upon a successful result read, it sets sah_result.have_result (a new data member as of this change) to true. - check_set(), upon return from get_result_file() : - sets result.validate_state to VALIDATE_STATE_ERROR (a new state as of this change) and retval to zero if there is a nonzero retval from check_set() and it is not ERR_OPENDIR. It then continues. - otherwise just continues. check_set() then determines if any IO errors brought the result count below wu.min_quorum. If not, it continues. Otherwise it returns. In all subsequent logic any results for which sah_result.have_result == false are skipped. Note that the result and the sah_result vectors are associated. validate/ sah_result.h sah_validate.cpp sah_boinc_db.cpp boinc changes: - new validate state VALIDATE_STATE_ERROR. - in the enumeration for check_set(), we now include a clause to check for VALIDATE_STATE_INIT in order to ignore results set to VALIDATE_STATE_ERROR. This enumeration query now matches that for check_pair(). Note that the only possible retvals from check_set() are now zero or ERR_OPENDIR. Note that logic to retry possibly transient errors still needs to be done. Also left to be done is a transitioner change to subtract the number of results in state VALIDATE_STATE_ERROR from the count of active results. The latter change is needed to stimulate the production of additional results for the affected WU. sched/ validator.C db/ boinc_db.h Jeff 09 Sep 2004 - Some changes to the validator mods of today. Validator logic now matches the updated validator documentation on the boinc website. validate/ sah_validate.cpp Jeff 19 Sep 2004 - Some time ago a bug was fixed that reduced the amount of time it takes to do pulse searching but the progress unit computation remained tuned to the bug. This resulted in an overestimation of the percentage of total processing time spent in pulse searcing. We do the most intensive pulse searching at the start of a WU so what the user sees is an early and false jump in percentage done. This change is just a retuning of PulseProgressUnits(). I changed: return(PulsePoTLen * PulsePoTLen * log(PulsePoTLen) * FftLen / 0.65e6); to: return(PulsePoTLen * PulsePoTLen * log(PulsePoTLen) * FftLen / 2.65e6); client/ progress.cpp David 29 Sept 2004 - fixed "heads-up" graphics display client/ sah_gfx.cpp David 11 Oct 2004 - accommodate change to BOINC graphics API Moved exception-catchers from main() to worker() - renamed SAH_GRAPHICS_BASE::worker_thread_init() to data_struct_init() (since this is now called by graphics thread, not worker) client/ main.cpp sah_gfx.cpp,h sah_gfx_base.cpp,h worker.cpp,h win_build/ seti_boinc.vcproj Lana 13 Oct 2004 - cleanup validator code to correspond to the boinc API requirements for handling error conditions validate/ sah_validate.cpp David 13 Oct 2004 - compile fixes client/ sah_gfx_base.cpp,h David 26 Oct 2004 - track change to BOINC API client/ main.cpp Rom 26 Oct 2004 - Tag for 4.06 release, all platforms seti_boinc_app_release_4_06 Eric 28 Oct 2004 - Added support for threaded clients - Fixed problem with retrieving insert ids related to ifx_getserial8() - Fixed problem in xml_util.h when compiling on LLP64 platforms aclocal.m4 config.h.in configure.ac configure m4/ acx_pthread.m4 assimilator/ Makefile.in client/ Makefile.in db/ sqlifx.ec xml_util.h db/tools/ Makefile.in splitter/ Makefile.in validate/ Makefile.in Rom 29 Oct 2004 - Tag for 4.07 release, all platforms seti_boinc_app_release_4_07 David 31 Oct 2004 - add config line to get rt library (sched_get_priority_min) on Solaris configure.ac Jeff 10 Nov 2004 - Started using the "best_" signals in a result for validation. We had always meant to do this in order to provide robust validation for results with no signals exceeding threshold. Plus, the way the validator is written, zero signal results arriving after the initial WU validation would always recieve zero credit (at least one signal was expected). - Siganls counts now appear in the log (DEBUG level). validate/ sah_result.{h,cpp} sah_validate.cpp David 12 Nov 2004 - move code to parse BOINC init file from data_struct_init() to graphics_thread_init(); fixes bug where user name and team didn't show - Win compile fixes client/ sah_gfx_base.cpp win_build/ seti_boinc.vcproj David 17 Nov 2004 - use regular GLUT library client/ Makefile.in.graphics Eric K. 18 Nov 2004 - increased memory resource bound to 64M to prevent core client from killing application when running with graphics enabled. - Fixed base64 and base85 decoders in xml_util.h - Altered BLOB printing so a minimum of 1 byte will always be inserted. This fixes a problem with the new informix SDK. db/ xml_util.h schema_to_class.awk schema_master.cpp schema_master.h splitter/ wufiles.cpp - addendum (jeffc) : The BLOB fix here does indeed fix the problem whereby some 5% of pulse inserts failed. Spike and triplet inserts still fail at a rate of less than 1% in each case. The cause of this is as yet unknown. The first public project SAH result ID processed since today's fix was put in place was 2969946. Jeff 18 Nov 2004 - Added better error checking around inserts into the science DB. assimilator/ sah_assimilate_handler.cpp Jeff 19 Nov 2004 - Return from handler if result insert fails. assimilator/ sah_assimilate_handler.cpp Jeff 19 Nov 2004 - added the following fields to analysis_config table (all initialized to zero): max_spikes max_gaussians max_pulses max_triplets db/ schema_master.sql schema_master.cpp schema_master.h tools/ analysis_configs.xml with a recompile of the splitter and assimilator. Jeff 23 Nov 2004 - bumped MAX_WUS_ONDISK back up to 500000. splitter/ splitparams.h Rom 23 Nov 2004 - Tag for 4.09 release, all platforms seti_boinc_app_release_4_09 Jeff 29 Nov 2004 - Master science DB fetches to obtain analysis config. This is used to find max allowable inserts for any given signal type. assimilator/ sah_assimilate_handler.cpp Jeff 30 Nov 2004 - Final step in the "limit spike insertions to 8" project. Stopped splitters, made a new analysis_config row (id=4), updated settings to make analysis_cfg=4, and restarted splitters. The max(id)'s of the following tables prior to splitter restart were: seti master DB (sah2) workunit_grp : 22423 seti master DB (sah2) workunit : 5736259 boinc DB (SETI_BOINC) workunit : 5279254 db/tools/ analysis_configs.xml Jeff 02 Dec 2004 - Removed 2 files. uttolst.cpp contained a buggy routine, tm_UtToLst() which did not handle multiple 24 hour wraps in the calculation of LMST. This bug is what led to some RA's being >= 24. Eric fixed this with an fmod() call in the new LMST routine, jd_to_lmst(), contained in source file coordcvt.cpp. The only program to use code from uttolst.cpp is testcoord, a program that Eric used to test jd_to_lmst(). jd_to_lmst() has been fully tested and in production for quite some time (over a year). splitter/ Makefile.in uttolst.cpp removed testcoord.cpp removed Jeff 03 Dec 2004 - Added the start of a public app build and test page. Needs work. html/ sah_source_code.php Jeff 03 Dec 2004 - added code (commented out for now) for precessing and reference frame correcting signals. assimilator/ sah_assimilate_handler.cpp Jeff 07 Dec 2004 - Finished source code / build instruction page for the web site. - Placed a reference result in the test WU directory. - Removed the old style reference result. html/ sah_participate.php sah_source_code.php client/ test_workunits/ old_format_reference_result.sah (removed) reference_result.sah Rom 07 Dec 2004 - Cleanup from header file changes client/ lcgamm.cpp main.cpp sah_gfx.cpp sah_gfx_base.cpp client/win/ seti_boinc.vcproj image_libs/ bmplib.cpp Jeff 08 Dec 2004 - Corrected tolerances in the validator so that they match this policy: ra 0.00066 hours absolute dec 0.01 degrees absolute time .000011574 days absolute frequency 0.01 Hz absolute chirp_rate 0.01 Hz/s absolute powers 1% relative chisqrs 1% relative triplet period 0.01 second absolute pulse period 0.1% relative pulse threshold 1% relative pulse snr 1% relative Diffs: was: if (abs_diff(ra, s.ra) > .15) return false; // .01 deg is: if (abs_diff(ra, s.ra) > .00066) return false; // .01 deg case SIGNAL_TYPE_PULSE: was: if (abs_diff(period, s.period) > .01) return false; // .01 sec is: if (rel_diff(period, s.period) > .01) return false; // 1% case SIGNAL_TYPE_TRIPLET: was: if (rel_diff(period, s.period) > .01) return false; // 1% is: if (abs_diff(period, s.period) > .01) return false; // .01 sec max(id) for result in the master science DB (sah2) prior to this change (assimilator was allowed to drain): 4345521 validate/ sah_result.cpp David 10 Dec 2004 - Fixed Windows compile. Added ../../../boinc/win_build to the include path to pick up config.h client/win_build/ init_data.xml libboincapi.vcproj seti_boinc.vcproj setiboincdb.vcproj Jeff 16 Dec 2004 - Record the app exit value in the master result record. Max(id) in the master DB result table before this change was 4873677. assimilator/ sah_assimilate_handler.cpp Jeff 17 Dec 2004 - Record the boinc WU_ERROR state in the master result record. Max(id) in the master DB result table before this change was 4923923. This is being recorded in the result.reserved field. This field needs to be renamed. assimilator/ sah_assimilate_handler.cpp Jeff 17 Dec 2004 - Fixed link problem in the client directory. We now need to link to the boinc_api as well as the boinc lib. client/ Makefile.in Jeff 21 Dec 2004 - Brought the assimilate handler into compliance with the new prototype. It now returns a non zero retval on any error and zero on success. All errors are potentially recoverable. assimilator/ sah_assimilate_handler.cpp Eric K 23 Dec 2004 - First step in getting a universal graphical/non-graphical application. - Added a -nographics command line option to turn off graphics. - Graphics calls are now wrapped in "if (!nographics)" - Added a client_stage variable which contains the initialization state of the graphics (PREGRX,GRXINIT,POSTINIT). If a fatal error occurs, this allows the client to guess at whether the failure was graphics related. - Added an atexit handler which restarts the application in nographics mode if exit is called in stage GRXINIT. - If found, seti_boinc uses the native libjpeg. aclocal.m4 config.h.in configure configure.ac client/ Makefile.in analyzeFuncs.cpp analyzePoT.cpp analyzeReport.cpp gaussfit.cpp main.cpp s_util.[h,cpp] seti.[h,cpp] spike.[h,cpp] worker.[h,cpp] Jeffc 23 Dec 2004 - Started the add of setilib to the configuration. configure.ac aclocal.m4 config.h.in configure m4/ sah_check_setilib.m4 assimilate/ Makefile.in David 25 Dec 2004 - compile fix for windows - commented out sleep(10) in worker client/ worker.cpp win_build/ libboinc.vcproj David 25 Dec 2004 - more compile fixes for Windows, which mysteriously didn't compile the debug version correctly added ../../../boinc/win_build to the include search path for all projects, and removed boinc/api/win and boinc/client/win (these don't exist) Removed the forced include of ../config.h (this file doesn't exist) Note: on Windows, as far as I know, "config.h" refers to the file boinc/win_build/config.h client/ worker.cpp win_build/ libboinc.vcproj libboincapi.vcproj seti_boinc.sln seti_boinc.vcproj setiboincdb.vcproj Jeff 27 Dec 2004 - More values are now read from sah_config.xml. Current values: sah2@master_tcp 500000 2 WAS 3 3 5 10 WAS 7 5 - max WU IDs before this change went online: SETI_BOINC DB : 7084313 sah2 (science master) DB : 7545411 splitter/ splitter.cpp wufiles.cpp db/ app_config.cpp app_config.h David 29 Dec 2004 - Got the windows client to compile. Added a file win_build/win_version.h that defines MAJOR_VERSION and MINOR_VERSION. Currently these are in configure.ac, but I don't see how to convey these values to a file included in the Windows compile. If there's a better way feel free to undo this change client/ version.cpp win_build/ seti_boinc.vcproj win_build/ win_version.h (new) Jeff 4 Jan 2005 - Rather than call dir_hier_path() directly, call boinc routine get_output_file_path() to get path to result files. This automatically gives us the new path hash algorithm. (see boinc checkin notes on 1/1/2005). Max result ID in the master science DB prior to the assimilator change was 5993798. validate/ Makefile.in sah_boinc_db.cpp assimilator/ Makefile.in sah_assimilate_handler.cpp Jeff 4 Jan 2005 - Added calls to setilib routines to precess RA and declination to J2000. At this point, this is only done for spikes and the results of the calculations are printed to the log only - we are not actually updating the spike coords. After making sure the precession is correct, we can start updating all signals. Max result ID in the master science DB prior to this change was 6005078. assimilator/ sah_assimilate_handler.cpp Jeff 11 Jan 2005 - Calculate barycentric frequency for all signals (not updating yet). validate/ sah_assimilate_handler.cpp David 8 Feb 2005 Various changes to get the Win version to compile, hopefully with graphics working: - removed SAH_GRAPHICS_BASE_INTERFACE class. The new idea is to have a SAH_GRAPHICS object, which in the shared-library case lives in the shared library. The main program has a pointer to this object, but calls only its data-modification functions, so it doesn't need to link with OpenGL or GLUT. - Moved render() from SAH_GRAPHICS_BASE to SAH_GRAPHICS. This eliminates the need for virtual functions. - added reduce.C, md5*.C to project files client/ sah_gfx.cpp,h sah_gfx_base.cpp,h seti.h worker.cpp win_build/ libboinc.vcproj libboincapi.vcproj Eric 8 Feb 2005 - Removed the db directory from the Makefile.am build list - Added SETILIBDIR and INFORMIXDIR to Makefile.incl - Changed references to /bin/false in configure.ac to remove path - Changes to make the unix client compatible with davids changes above: - worker thread needs access to SAH_GRAPHICS_BASE::get_generate_buffer() and SAH_GRAPHICS_BASE::generate_done(), so added #ifdefs to make them visible to the executable during build - Reordered db/db_table.h to re-fix undefined symbols Makefile.am Makefile.in Makefile.incl configure.ac configure client/ Makefile.am Makefile.in sah_gfx.[h,cpp] sah_gfx_base.[h,cpp] db/ db_table.h Eric 10 Feb 2005 - Removed aclocal.m4 and configure because they are generated by _autosetup. - Simplified the folding algorithm bases on code send by Ben Herndon. On superscalar processors this can also be a speedup. On SPARC, it's a 0.24% slowdown, not enough that we should stick with the more complex original code. - Changed the automake file to remove references to "installing" seti_boinc into /usr/local/bin - Fixes to get the windows client running. - Added check for _int32 and int32_t to configure.ac - Now that sah_graphics is dynamically allocated, a lot of our graphics structures weren't getting initialized properly. I've written default constructors for: G_GAUSS_INFO, G_TRIPLET_INFO, G_PULSE_INFO, GDATA, SAH_GRAPHICS_BASE, SAH_GRAPHICS, SETI_WU_INFO, GRAPH_BUFFER, and GRAPHICS_PREFS. - Added ltmain.sh, depcomp and win_build/* to the nightly tarball. - Changed trim_sources to use _autosetup instead of autoconf. aclocal.m4 (removed) configure (removed) trim_sources configure.ac config.h.in client/ pulsefind.cpp Makefile.am worker.cpp sah_gfx.[h,cpp] sah_gfx_base.[h,cpp] seti_header.cpp gdata.h jpeglib/ jpeglib.h Jeff 14 Feb 2005 - put libboinc at the end of the lib list (functions in other libs use symbols defined in libboinc) - change some assimilator messages to DEBUG level. assimlator/ Makefile.am sah_assimilate_handler.cpp validate/ Makefile.am Eric K. 15 Feb 2005 - fixed missing definition of dir_hier_path() in wufiles.cpp - reordered initializations in constructors to get rid of warning messages - modified configure script to set CXXFLAGS to equal CFLAGS if CXXFLAGS is not defined - The client was trying to look up the graphics library symbol "x11_glut_is_initialized" rather than "xwin_glut_is_initialized" configure.ac client/ gdata.h sah_gfx_base.cpp worker.cpp splitter/ wufiles.cpp Eric K. 16 Feb 2005 - Fixed broken nightly tarball trim_sources Eric K. 16 Feb 2005 -Rather than rechirping the original data every 1000 chirp steps, we now rechirp the original data every step. This will make results more repeatable when restarting work units. It may also allow floating point rather than double precision trig functions. -The savedWUData in analysis_state used to be the raw data from the file. As of now it is the baseline smoothed data floating point data (unchirpped). client/ seti.h seti.cpp analyzeFuncs.cpp - Fixed broken nightly tarball Eric K. 10 Mar 2005 -To better support systems with concurrent calculation of sin() and cos() I've added a sincos() and sincosf() function for systems without these intrinsics. -Modified analyzeFuncs and fft8g to use sincosf(). -Fixed bug that prevented baseline smoothing on chirp 0 data. -Modified configure to check for sinf(),cosf(),sincos() and sincosf() configure.ac config.h.in client/ fft8g.cpp sincos.h analyzeFuncs.cpp Jeff 11 Mar 2005 - Templated the science pre_processing function. Max(id) for result in the master science DB before putting this change online was 9289454. assimilator/ sah_assimilate_handler.cpp Charlie 11 Mar 2005 - Add support for building Mac SETI@home application using XCODE IDE on Macintosh. mac_build/ HowToBuildBOINC_XCode.rtf seti_boinc.xcode.zip Jeff 16 Mar 2005 - We now do values checking on signals and do not pass a signal on to preprocessing is there is a critical value out of range (ra, decl, time, freq at this point). We so however attemp to insert such a signal into the master DB, with the value 1 placed in rfi_found. Max(id) for result in the master science DB before putting this change online was 9826217. It came to light during testing this change that the occasional insert failures that we see are for signals with wildly bad values (NaNs ?). assimilator/ sah_assimilate_handler.cpp Jeff 17 Mar 2005 - Began inserting signals with pre-processed values: - precession of coordinates from EOD to J2000. This uses the serendip precession code. This was tested by comparing assimilator precession results to those obtained by the online FUSE precession calculator: http://fuse.pha.jhu.edu/cgi-bin/precess_tool There was agreement to under an arcsecond. This was also tested under RA wrap conditions. Here are 2 examples: obs RA obs decl sah precession obs time precession by fuse calc sah-fuse diff in arcsec RA decl RA decl RA decl RA decl 17.018570 18.127011 17.014893 18.134086 2453368.151255 17.014886 18.13411 0.378 -0.0864 0.001608 28.397810 23.997351 28.37006 2453365.416415 23.997336 28.36997 0.81 0.324 - calculation of the signal's barycentric frequency. This also uses serendip code. Frequency shifts were within the expected range (max ~= 142KHz) but no independent tests were done. - calculation of the cubic pixel number. This was tested by reversing the qpix calculation and comparing the resulting RA/Decl with the the original. There was agreement to a max deviation of ~1.3 arcminutes which is OK because the qpix reversal gives you the pixel center coordinates which is a max of ~1.3 arcmin arcminutes from the pixel edge (given nside=2048). Most diviations on reversal were smaller than this. Max(id) for result in the master science DB before putting this change online was 9927205. assimilator/ sah_assimilate_handler.cpp Jeff 21 Mar 2005 - Better debugging output during WU file path resolution. assimilator/ sah_assimilate_handler.cpp Rom 23 Mar 2005 - Fix the release build of the S@H app on Windows client/ version.cpp client/win_build/ seti_boinc.vcproj Eric 12 Apr 2005 - Fix bug in database code. The informix interface was expecting blobs to be presented in hex format rather than raw binary. So informix interface was attempting to translate the code to binary. In addition there was a bug in the translating code such that only characters 'a'-'f' and 'A'-'F' were being translated. The result was that most of the blob data were reassigned blob[i]=(blob[2*i]*16+blob[2*i+1])&0xff. - For better debugging, I changed the sqlifx.ec chk_status() macro (which included a RETURN!!! Yuck!) into a boolean function. - Since the informix SQLCODE variable (and the identical sqlca.sqlcode) aren't available to the debugger, I replaced accesses to this variable with calls to sql_error_code(). - Since when errors were detected, sql_close() was being called which cleared the error code. We've added a function sql_last_error_code() to return the last non-zero error code and sql_reset_error_code() to reset the last non-zero error code. There's still some work to do as far as returning proper error status to the calling environment - Changed the database name in the schema to sah2@sci_master_tcp to match move to new db server/ db/ schema_master.[cpp,h,sql] schema_to_class.awk sqlapi.h sqlblob.h sqlifx.ec Jeff 27 Apr 2005 - Many changes to the informix related code in db/ in order to get the science master DB migration code to work and to fix a bug that was preventing the proper insertion of PoT's (both gaussian and pulse). Eric L essentially rewrote sqlifx.ec. Note that to allow DB insertions with ID's the symbol KEEP_ID must be defined at compile time. - also some mods to the config insert tools in order to add some new configs. db/ db_table.h schema_master.cpp schema_to_class.awk sqlapi.h sqlblob.h sqlifx.ec sqlrow.cpp sqlrow.h tools/ Makefile.in insert_analysis_config.cpp insert_s4_receivers.cpp insert_splitter_config.cpp settings.sql splitter_configs.xml Jeff 01 May 2005 - recompiled the validater to pick up the credit fix referenced: Bruce 29 April 2005 and started it in the public project. Here is the start line of sah_validate1: 2005-05-01 13:37:32 [normal ] Starting validator Jeff 02 May 2005 - Assimilator changes: - If there is no canonical result for a WU, return 0. This will cause the boinc assimilator to mark the WU as assimilated and it will then have it's file's and it's DB record(s) deleted. No canonical result means that too many results were returned with no concensus. - use sql_last_error_code() rather than sql_error_code(), as the latter always returns 0. - I a result insert get an informix error -239, return 0. This will cause the boinc assimilator to mark the WU as assimilated and it will then have it's file's and it's DB record(s) deleted. A -239 (uniqueness violation, in this case on sah result field boinc_result) means that we have already inserted the canonical result for this WU. This should "never" happen but maybe with aome odd stop/start combo it does. - If the bad value check detects a bad value in a signal, replace this bad value with a recognizable marker. This is in addition to flagging the signal in the rfi_found field. This value replacement is needed because some bad values cannot be interted into the DB. The marker value is -91.0. This is an impossible value for ra, decl, time, and freq. - Max(id) for result in the master science DB before this change went online was 13364296. assimilator/ sah_assimilate_handler.cpp Charlie 05 May 2005 Mac: Modify projects and rebuild with OS 10.3.0 compatibility SDK. Update build instructions. Check in XCode project. mac_build/ HowToBuildBOINC_XCode.rtf seti_boinc.xcode boinc.pbproj/ project.pbxproj (add) Eric K. 18 May 2005 - Changed includes of C headers to includes of C++ headers. (i.e. we now include rather than ) - Modified malloc_a() to use native aligned allocation routines if available. - Removed explicit use of _aligned_malloc on _WIN32 platforms since malloc_a() will use _aligned_malloc(). - Defined type sah_complex which is compatible with the FFTW complex data type. Complex arrays that used to be defined a float arrays are now of type sah_complex. Code accessing these arrays has been modified where necessary. - Added mods to allow the function prototypes in sincos.h to work if these functions are present, but not in the system header. - Modified the method by which the chirp table is computed. The goal is to have the drift be less than 1 bin over the duration of interest to the analysis. In the case of gaussians that duration is 2 beam crossings. In the case of pulses it's one beam crossing. In the case of spikes it's one fft length. This should pick up 1.5 dB in sensitivity to gaussians, pulses and triplets. We could pick up another 0.25 dB with another doubling of this duration, but I think we've reached diminishing returns. - Replaced repeated allocations of WorkData in the main loop with one allocation prior to loop entry - Made main processing loop compatible with FFTW. The configure script now detects the FFTW library and header files and if both are available USE_FFTW is defined in "config.h". This define determines which FFT is used. config.guess config.sub ltmain.sh Makefile Makefile.incl configure.ac client/ Makefile.am analyzeFuncs.[cpp,h] malloc_a.[cpp,h] fft8g.[cpp,h] chirpfft.cpp lcgamm.cpp analyzePoT.cpp s_util.[cpp,h] main.cpp progress.cpp pulsefind.cpp seti.[cpp,h] analyzeReport.cpp sincos.h test_workunits/ reference_work_unit.sah Rom 26 June 2005 - Update Windows project files to use the FFTW library and optimize for SSE client/ win-config.h client/win_build/ seti_boinc.vcproj Jeff 26 July 2005 - Added a sky_map table to the db schema. This will be the primary table used to control the near time persistency checker. - Split a while() loop into 2 lines because otherwise gdb would not allow a break to be set inside the loop (Eric change). db/ schema_master.sql schema_master.[cpp,h] sqlifx.ec Jeff 09 Sept 2005 - added a couple of libs to the splitter makefile that the new boinc crypto code needs. splitter/ Makefile.in Jeff 05 Oct 2005 - Removed old/new hash boolean from call to dir_hier_path(). splitter/ wufiles.cpp Jeff 28 Oct 2005 - Fixed memory leak in the validator. - Sync with changes in the BOINC SCHED_MSG_LOG definition. validate/ sah_validate.cpp sah_boinc_db.cpp Jeff 1/9/2006 Jeff Splitter related changes. - account for new command_line parm in create_work() - we just pass NULL. - changed all instances of safe_strncpy() to strlcpy(). - change the app config file name to sah_enhanced_config.xml. - added settings ID WU name. splitter/ readtape.cpp wufiles.cpp db/ app_config.cpp Jeff 1/11/2006 - More safe_strncpy -> strlcpy(). client/ timecvt.cpp Jeff 1/19/2006 - added field sb_id to tape, workunit_grp, workunit, and result. These fields were required for the DB merge. We can drop thme after a while. - app config file name back to sah_config.xml. This should be a command line item. db/ app_config.cpp schema_master.cpp schema_master.h schema_master.sql Jeff 1/23/2006 - The assimilator now uses the settings ID that is embedded in the wu/result name to get to the analysis_config and receiver_config tables. If the settings ID has not changed from one result to the next (normally true until the enhanced client gets released) then we do no DB accessing. This replaces the logic whereby we were reading the wu and wug for each result. - Both the enhanced and old splitter were previously modified to embed the settings ID into the wu/result names. assimilator/ sah_assimilate_handler.cpp Jeff 1/24/2006 - Templated signal insertion. There were several other small code changes secondary to this. - if (appid == 2) signal.reserved = 1. This is temporary for enhanced rollout plus DB correction. The correction code needs to know is the signals were returned by an enhanced app or not. This sah2:result.max(id) before this change went on was 1615350419. assimilator/ sah_assimilate_handler.cpp Jeff 2/7/2006 - Changed the type of q_pix in all 4 signal table schemas from integer to int8. - The assimilator now inserts signals with "n_pix", a 64 bit integer. It contains "q_pix" in the high order 32 bits and frequency with a resoltion of 10 Hz in the low order 32 bits. All floating point numbers are cast (ie floored) to integers in this processed. Note: the max IDs before this change were: spike 1017689548 gaussian 116885361 pulse 173469464 triplet 125669326 -------------------- Testing notes (all tests look good) ------------------ Here is a new spike. id 1017690489 result_id 1619052602 peak_power 24.45193290000 mean_power 1.000000000000 time 2453342.626688 ra 2.944765570000 decl 26.35156250000 q_pix 3601673817190043 freq 1421050038.263 detection_freq 1421049936.330 barycentric_freq 1421103637.391 fft_len 131072 chirp_rate -1.38084543000 rfi_checked 0 rfi_found 0 reserved 0 n_pix q_pix freq ---------------- ----------- ----------- 3601673817190043 = 00 0C CB B4 08 78 6E 9B 00 0C CB B4 = 838580.00 which translates to RA 2.9443359 and Decl 26.3392294 from DB 2.9447656 26.3515625 --------- ---------- 37 arcsec diff 44 arcsec diff 08 78 6E 9B = 142110363 1421103637.391/10 = 142110363 --------- 0 Hz diff Here is a new gaussian: id 116899622 result_id 1619068124 peak_power 1.717239500000 mean_power 0.458329827 time 2452982.120403 ra 14.84703540000 decl 18.09752270000 q_pix 38639321233114672 freq 1419769999.385 detection_freq 1419770480.211 barycentric_freq 1419689449.058 fft_len 16384 chirp_rate 11.23900990000 rfi_checked 0 rfi_found 0 reserved 0 sigma 6.227958200000 chisqr 1.342639920000 null_chisqr 2.142316580000 score 0.00 max_power 4.632330890000 pot n_pix q_pix freq ----------------- ----------- ----------- 38639321233114672 = 00 89 46 42 08 76 46 30 00 89 46 42 = 8996418 which translates to RA 14.8461914 18.0921908 from DB 14.8470354 18.0975227 ---------- ---------- 73 arcsec diff 19 arcsec diff 08 76 46 30 = 141968944 1419689449.058/10 = 141968944 --------- 0 Hz diff Here is a new triplet: id 125678570 result_id 1619068730 peak_power 10.59097860000 mean_power 0.00197354145 time 2453358.223775 ra 18.05746840000 decl 20.87687870000 q_pix 142995601912863989 freq 1419248962.402 detection_freq 1419248962.402 barycentric_freq 1419256216.076 fft_len 32 chirp_rate 0.00 rfi_checked 0 rfi_found 0 reserved 0 period 0.919142425 n_pix q_pix freq ------------------ ----------- ----------- 142995601912863989 = 01 fc 05 be 08 75 9c f5 01 FC 05 BE = 33293758 which translates to RA 18.0571289 Decl 20.8620894 from DB 18.0574684 20.8768787 ---------- ---------- 29 arcsec diff 53 arcsec diff 08 75 9C F5 = 141925621 1419256216/10 = 141925621 --------- 0 Hz diff Here is a new pulse: id 173470235 result_id 1619053031 peak_power 0.919080853 mean_power 0.00388364005 time 2453357.914301 ra 10.59253220000 decl 18.10714530000 q_pix 121561945579447491 freq 1420880737.305 detection_freq 1420880737.305 barycentric_freq 1420750751.969 fft_len 64 chirp_rate 0.00 rfi_checked 0 rfi_found 0 reserved 0 period 0.293273598 snr 7.352646830000 thresh 7.250113490000 score 0.00 len_prof 44 pot n_pix q_pix freq ------------------ ----------- ----------- 121561945579447491 = 01 AF DF F2 08 77 E4 C3 01 AF DF F2 = 28303346.00 which translates to RA 10.5922852 Decl 18.0921908 from DB 10.5925322 Decl 18.1071453 ---------- ---------- 21 arcsec diff 54 arcsec diff 08 77 E4 C3 = 142075075 1420750751.969/10 = 142075075 --------- 0 Hz diff 2/23/2006 Jeff - Changed the frequency to fpix conversion from a cast-to-long to a round function: inline long round(double x) {return long(floor(x + 0.5f));} Casts from floating point to integers are always equivalent to either (int)floor() or (int)ceil(), depending on the rounding mode of the platform. This sah2:result.max(id) before this change went on was 1623225559. assimilator/ sah_assimilate_handler.cpp I then thought there was a problem and fell back on this change. The old assimilator went back on after result id 1623229153. I confirmed that there was in fact no problem and the new assimilator went back on on 2/24/06 after result id 1623492910. Testing notes: Here is a new spike: id 1024551102 result_id 1623225782 peak_power 24.31553840000 mean_power 1.000000000000 time 2451858.467759 ra 21.35094640000 decl 18.07765010000 q_pix 55794923851997434 freq 1420622880.906 detection_freq 1420621698.453 barycentric_freq 1420741058.565 fft_len 131072 chirp_rate -19.5776901000 rfi_checked 0 rfi_found 0 reserved 0 n_pix q_pix freq ------------------ ----------- ----------- 55794923851997434 00 C6 39 30 08 77 E0 FA 00 C6 39 30 = 12990768 which translates to RA 21.3515625 Decl 18.0725708 21.3509464 18.0776501 ---------- ---------- 53 arcsec diff 18 arcsec diff 0877E0FA = 142074106 round(1420741058.565/10) = 142074106 --------- 0 Hz diff Here is a new pulse: id 176938950 result_id 1623229140 peak_power 0.229531646 mean_power 0.00195498206 time 2451802.752266 ra 1.953974720000 decl 19.68553160000 q_pix 2934081280477886 freq 1420283508.301 detection_freq 1420283508.301 barycentric_freq 1420192624.394 fft_len 32 chirp_rate 0.00 rfi_checked 0 rfi_found 0 reserved 0 period 0.0233727992 snr 5.806743140000 thresh 5.665772440000 score 0.00 len_prof 7 pot n_pix q_pix freq ------------------ ----------- ----------- 2934081280477886 00 0A 6C 88 08 77 0A BE 000A6C88 = 683144 which translates to RA 1.9541016 Decl 19.6889732 1.95397472 Decl 19.6855316 ---------- ---------- 11 arcsec diff 12 arcsec diff 08770ABE = 142019262 round(1420192624.394/10) = 142019262 --------- 0 Hz diff Here is a new gaussian: id 120516510 result_id 1623489856 peak_power 3.313514950000 mean_power 0.580334067 time 2451925.666315 ra 7.090055470000 decl 8.357689860000 q_pix 98579528333729636 freq 1418915066.719 detection_freq 1418912570.889 barycentric_freq 1418934757.328 fft_len 16384 chirp_rate -35.8465271000 rfi_checked 0 rfi_found 0 reserved 0 sigma 3.568017480000 chisqr 1.412076230000 null_chisqr 2.102728610000 score 0.00 max_power 8.865511890000 pot n_pix q_pix freq ------------------ ----------- ----------- 98579528333729636 01 5E 39 8F 08 75 1F 64 015E398F = 22952335 which translates to RA 7.0898438 Decl 8.3666866 7.09005547 Decl 8.35768986 ---------- ---------- 18 arcsec diff 32 arcsec diff 08751F64 = 141893476 round(1418934757.328/10) = 141893476 --------- 0 Hz diff 3/24/06 Jeff Validator result overflow checking no longer uses an internal buffer. stderr_out is checked in place. validate/ sah_validate.cpp 3/30/06 David Added gutil_text.C to windows project 5/4/06 Charlie - Mac: Fix glut.h to be compatible with Mac's OpenGL framework. - Create combined config.h file for Intel and PowerPC Macs. - Create shell script to build fftw-3.1.1 library as universal binary (PowerPC and Intel). - Update seti_boinc XCode project to build both PowerPC and Intel versions of SETI@home Enhanced application for Macintosh. glut/ glut.h mac_build/ config.h buildfftw-3.1.1.sh seti_boinc.xcodeproj/ project.pbxproj 5/5/06 Charlie - Mac: Fix fftw-3.1.1 build script to work on PowerPC as well as Intel Macs. mac_build/ buildfftw-3.1.1.sh 5/8/06 Charlie - Mac: Add icon to SETI@home enhanced. client/ app_icon.h (added) main.cpp mac_build/ seti_boinc.xcodeproj/ project.pbxproj 5/9/06 Charlie - Mac: Fix crash bug on systems 10.3.0 through 10.3.8 due to undefined sinf, cosf, atanf functions in dynamic linked library usr/lib/libSystem.B.dylib. The fix is to not #define HAVE_SINF, HAVE_COSF and HAVE_ATANF in config.h file for PowerPC builds. - Update Mac version to 5.13 mac_build/ config.h 5/15/06 Eric - Version to 5.15 - Embedded calls to boinc_worker_timer() in main loop 6/14/06 Eric - Version to 5.17 - Removed calls to boinc_worker_timer() from main loop. - Added support for transposing the PoT array on large memory machines. This can improve performance, since caching is better for the transposed PoT. Initial code by Alex Kan. - Added several variations of transpose functions. Depending upon the size and associativity of the machine cache, one may outperform the rest. - Fixed some boinc compile problems (changes to the boinc_app_mouse_move(), etc prototypes) - added files in "client/vector" to the Dev-C++ and VCC projects. - added high resolution timer class (vector/hires_timer.*) for function timing. - added timing code for on the fly function testing and switching. This currently supporst BaseLineSmooth(), GetPowerSpectrum(), ChirpData(), and Transpose(). Support for pulse, triplet and Gaussian finding will come later. Functions can be added to the tests by adding them to the arrays in analyzeFuncs_vector.cpp. client/ analyzeFuncs.[cpp,h] analyzePot.[cpp,h] analyzeReport.[cpp,h] sah_gfx.cpp sah_gfx_base.cpp win-config.h seti.h pulsefind.cpp chirpfft.cpp s_util.h vector/ analyzeFuncs_vector.[cpp,h] hires_timer.[cpp,h] analyzeFuncs_altivec.cpp win_build/ *.dev *.vcproj win_build/ win_version.h m4/ optimizations.m4 configure.ac 7/20/06 Charlie - Mac: Update seti_boinc XCode project for added source files and to link with universal binary versions of BOINC libraries as built by current BOINC XCode project (but seti_boinc project still builds separate PPC and Intel applications.) mac_build/ seti_boinc.xcodeproj/ project.pbxproj 8/1/06 Charlie - Mac: Update seti_boinc XCode project for Altivec support. mac_build/ seti_boinc.xcodeproj/ project.pbxproj 8/2/06 Charlie - Mac: Create a new mac-specific config.h file which #includes either config-i386.h or config-ppc.h; include instructions for generating these files. Tthis is much easier than trying to merge them into one combined file with "#ifdef i386" etc. - #undef'ed HAVE_ATANF, HAVE_COSF and HAVE_SINF because this generates much smaller code - Create a new shell script makeseticonfigs.sh to automatically create config-i386.h and config-ppc.h. mac_build/ config.h config-i386.h (new) config-ppc.h (new) makeseticonfigs.sh (new) seti_boinc.xcodeproj/ project.pbxproj 8/3/06 Charlie - Mac: Allow HAVE_ATANF, HAVE_COSF and HAVE_SINF for Intel to match earlier versions. mac_build/ config.h 8/28/06 Charlie - Mac: Incresae stack size by 8MB for Intel Macs only. This seems to take care of the remaining screensaver graphics crashes. client/ main.cpp 9/19/06 Charlie - Mac: Incresae stack size by another 8MB for Intel Macs only for a total of 24MB. There were still a few occasional crashes with 16MB stack. Tripling the original stack allocation is consistent with my observation that memory sizes for most applications on Intel Macs seem to be about three times that on PowerPC Macs. client/ main.cpp 1/29/07 Charlie - Mac: Set Maximum stack size to system limit, for compatibvility with future versions of core client (rlp.rlim_cur = rlp.rlim_max). The core client will do this after fork() and before execv(). NOTE: if the OS has set rlim_max to RLIM_INFINITY, that value is -1. So adding a fixed amount (like 16MB) to -1 would actually reduce the limit instead of increasing it. This change avoids that problem. client/ main.cpp 3/16/07 Jeffc - some setilib related name changes. No logic change. assimilator/ sah_assimilate_handler.cpp 4/23/07 jeffc - Upon recompile of the assimilator for bruno (i686-linux), it aborted with: *** stack smashing detected *** This turned out to be an undersized char array in routine sql_insert_id(). I increased it from 21 bytes to 256 bytes. Still not too safe... sah:result.max(id) before this change was 1691705161. db/ sqlifx.ec 5/2/07 jeffc - Assimilator changes: - Functions radecl2pix(), pix2radecl(), and eod2stdepoch() were moved to setilib. - The code to pack ra, decl, and freq into signal.q_pix was put in setilib function co_radeclfreq2npix(). - Lots of little code and build cleanups. sah:result.max(id) before this change was 1694234121. assimilator/ Makefile.am sah_assimilate_handler.cpp 5/31/07 korpela - Increased version number to 5.20 !!! THIS IS NOT YET A WORKING BUILD. I WILL TAG IT WHEN IT WORKS !!! - Lots of changes by Joe Segur to implement optimized algorithms. - Current build finds extra triplets. Tracking that down now. - This might not build on Visual Studio. Significant changes are: 1. Modified Pulse finding. This includes both algorithmic improvements effective on all systems, and the possibility of using vectorized folding subroutines on systems with SIMD capability. Files: pulsefind.cpp, h - primary changes analyzeReport.cpp, h - minor supporting change AKfoldSSE.cpp - new The algorithmic improvements include: - The sums produced in the folding subroutines are not divided by the fold level, saving a small amount of time. - The invert_lcgf() caching saves the display threshold value rather than the report threshold, and also doesn't scale by fold level. This allows a quick comparison where only for the approximately 1% of cases where display threshold is reached does report threshold need to be calculated and checked. - Calculations of period values are kept in integer form and only converted to floating point for reporting. - The memcpy() of Pulse PoT arrays before the initial fold by 3, 4, or 5 is removed. - The sequence of folding operations for Pulse PoTs of length 511 and shorter is cached. This reduces the 3 nested loops to a single faster loop for most cases where the loop overhead was using a significant fraction of the time for folding. - The default folding subroutines are optimized for FPU and coded to encourage efficient instruction scheduling by the compiler. In support of SIMD folding: - Outputs of the folding subroutines are written 16 byte aligned so the next fold can use aligned loads. (This is also more cache-friendly even when SIMD isn't available). - Because SIMD routines are not very efficient for the shortest PoT lengths, particularly those not divisible by 4, the choice of routine for each length up to 31 is table-driven. (Again, this proved to also be a help for the default FPU optimized routines). Overall, the algorithmic improvements approach a 10% improvement in total crunch time, SIMD folding another 10%. 2. Transpose changes and additions: - Transpose is only done for chirp/fft pairs for which Gaussian, Pulse, or Triplet searching will be done. - Changed testing from 512x2048 to 16Kx64 which is used much more. That had very little effect on my Pentium-M with 1 MiB L2 cache, more on my Willamette P4 with 256 KiB L2, and most on my Pentium-MMX with 256 KiB very slow L2 on the motherboard. - Added a non-prefetch version of v_vTranspose4. It's faster on my Willamette P4 system than the original, though slightly slower on my Pentium-M system. (I also did the same for the GetPowerSpectrum routines with similar effect.) - Added another vectorized 4x4 subtranspose which differs mainly in using non-temporal writes, plus a variety of functions which use it. One of those always measures fastest on my two systems with SIMD capability, by a 30% or more margin. files: analyzeFuncs.cpp, h analyzeFuncs_sse.cpp, h analyzeFuncs_vector.cpp, h 3. Chirping changes and additions: - Modified CalcTrigArray() so when going two or more ChirpRateInd steps it only transits the two 16 MiB arrays once. - Modified testing so the change from negative to positive chirp goes two steps up. That provides a better overall speed approximation, though it's only a rough match to the number of chirp indices which are skipped in typical WUs. - Modified testing to start at chirp index 27040 so the error check is including the difficult angles of over 262144 which make single float rounding produce fractional input to the SinCos approximation with only 5 bits of precision. - After testing, if TrigArray isn't chosen then InitTrigArray() is not called again. - Added SSE3, SSE2, and SSE1 versions derived from Alex Kan's sources. - Added an FPU version patterned after the SIMD versions; quick rounding and non-branching polynomial SinCos approximation. On my systems it's quicker than TrigArray and of course it doesn't need the extra 32 MiB array space. This one isn't yet in a lunatics.at release, but Simon has built pretest versions so I'll find out soon if it's faster on AMD systems. Note 1: The DevC++ builds do a good job of making main() align per the default preferred_stack_boundary of 2^4, but not the worker thread. To work around that so the SIMD chirping wouldn't crash I added a hack near the beginning of worker() to force the stack pointer to a multiple of 16 for GNUC builds. The calculations in those SIMD routines are complex enough that there are register spills to temporary stack variables, so the kind of aligned alloca() used in analyzeFuncs_x86_64.cpp isn't adequate, I did try that. I suppose adding enough additional aligned variables could make that approach work, but I'm reluctant to modify those well-tested routines more than strictly necessary. Note 2: The "const" in float4 constant definitions seems to conflict with the MinGW intrinsics. I'm not sure why, I thought the C style cast to (void *) used in the *mmintrin.h files should work, so I just removed "const" for now. files: x86_float4.cpp, h - modified analyzeFuncs.cpp, h - modified analyzeFuncs_vector.cpp, h - modified analyzeFuncs_sse.cpp - modified analyzeFuncs_fpu.cpp - new analyzeFuncs_sse2.cpp - new analyzeFuncs_sse3.cpp - new 4. Miscellaneous: - In seti.cpp, h added save to and restore from state file of individual signal counts, plus relocated the final report of those values there; it's now called before both the normal exit in analyzeFuncs.cpp and the overflow exit in worker.cpp. - In analyzeFuncs.cpp added output of a CUSTOM_STRING (if defined) to the beginning of stderr, and a restart indication with the progress in percent. - In worker.cpp replaced the try/catch for parsing the state file with a check for existence of that file, same as in my 517STxx builds from the "Builds for unexplained error test" NC forum thread. - In analyzeFuncs_vector.cpp, h restructured the tables of functions to test to a single table for each type, adding a field indicating what CPU capabilities are required for the function. Also added a routine to set a variable to the host capabilities; the testing routines compare those and don't try unsupported routines. 06/07/2007 Eric K. - Version to 5.21 - Fixed crash on non-SSE processors. - More optimized code merging from Joe Segur "In analyzeFuncs.cpp I moved the call to ComputePoTInfo up before the call to ChooseFunctions() because the folding test uses some of the PoTInfo values both directly and indirectly. The 3 new arguments in ChooseFunctions() are needed because the folding test accesses the ChirpFftPairs array. client/ analyzeFuncs.cpp pulsefind.h vector/ AKfoldSSE.cpp (removed) analyzeFuncs_sse.cpp analyzeFuncs_vector.[cpp,h] x86_float4.h win_build/ seti_boinc.dev 7/20/07 jeffc Added science table hotpix. db/ schema_master.{sql,cpp,h} 7/21/07 Charlie - Mac: Changed files for new vector functions, changed config.h to sah_config.h, version 5.23, etc. mac_build/ config-i386.h config-ppc.h makeseticonfigs.sh seti_boinc.xcodeproj/ project.pbxproj 7/24/07 Charlie - Mac: Reconfigure XCode project for separate PowerPC and Intel targets, to allow individual source files to have different compiler flags for each architecture. - Mac: Use auto-config to build new config-i386.h, config-ppc.h; add changes to sah_config.h to override certain items in these files. -Mac: Update build instructions. mac_build/ config-i386.h config-ppc.h sah_config.h seti_boinc.xcodeproj/ project.pbxproj HowToBuildSETI_XCode.rtf 7/25/07 Charlie - Mac: More tweaks to XCode project and sah_config.h. mac_build/ sah_config.h seti_boinc.xcodeproj/ project.pbxproj 7/25/07 jeffc The assimilator now populates a new table - hotpix. Rows consist of a qpix and the time of assimlation. For each result assimilated a unique list of qpixes for the signal set is constructed. For each of these qpixes a new row in hotpix will be inserted, unless there is already a row for that qpix, in which case the time will be unpdated. Max ID for result in beta before this change was 379785. assimilator/ Makefile.am sah_assimilate_handler.cpp 7/25/07 jeffc Placed a uniqueness constraint on hotpix.id via a unique index. db/ schema_master.{sql,h,cpp} 8/16/07 Charlie - Mac: Update build instructions to put updating the version number in the proper section. - Mac: define USING_XCODE in project settings. - Mac: Add path to BOINC version.h in header search paths; adjust analyzeFuncs.cpp to get the library version from version.h instead of config.h if USING_XCODE. - Mac: Don't include sah_config.h from command line in XCODE project. - Mac: tweaks to sah_config.h to correctly get COMPILER_STRING with GCC version number. - Mac: Fix compile error in analyzeFuncs_vector.cpp: included header file contains "#undef isnan". client/ analyzeFuncs.cpp vector/ analyzeFuncs_vector.cpp mac_build/ sah_config.h seti_boinc.xcodeproj/ project.pbxproj HowToBuildSETI_XCode.rtf 8/16/07 jeffc - splitter: repeat read of all config's for each WUG. Not doing this for the analysis_config lead to gradual lowering of (at least) the triplet threshold that resulted in WUs that got bogged down in triplet finding (looking at every PoT bin) and WU overflows (again, triplets). splitter/ mb_splitter.cpp Jeff 10 Sep 2007 - The CVS repository is deprecated this date. We now use SVN. Eric K. 6 Dec 07 - Checked in David's extensive changes for V6 Graphics Charlie 7 Dec 07 - Mac: Update XCode project for V6 graphics (separate graphics application) - Fix compile error on Mac (memset undefined in this context) client/ gdata.h mac_build/ seti_boinc.xcodeproj/ project.pbxproj Eric K. 17 Dec 07 - Fixed problem with SAH_PACKAGE_STRING assignment. - Modified seti_boinc.dev for V6 graphics build with DevC++ - Added seti_graphics.dev for building V6 graphics display app. client/ analyzeFuncs.cpp sah_gfx.cpp win-sah_config.h win_build/ seti_boinc.dev seti_graphics.dev Charlie 18 Dec 07 - Mac: Fix bugs in definition of COMPILER_STRING. - Mac: Put version number definitions in mac_build/sahconfig.h instead of in 2 places (config-i386.h and config-ppc.h). - Mac: Change version number to 6.00. - Mac: Fix bug in XCode project (ppc targets had Run Script phase after build instead of before.) mac_build/ config-i386.h config-ppc.h sah_config.h seti_boinc.xcodeproj/ project.pbxproJ Eric 20 Dec 2007 - Added three new methods to the db tables. bool authorize_delete(bool auth); bool DELETE(sqlint8_t id); bool DELETE(std::string where); Before delete is called, the caller must call (using the same instance) authorized_delete(true). This must be called prior to each call to DELETE(). - Added a xml_encoding_from_string() call to xml_util.h db/ db_table.h xml_util.h Eric 31 Jan 2008 - Fixed problem with incorrect receiver name in graphics output for multibeam workunits. - Added copyright notices to files that were missing them. - Added #include to analyzeFuncs_fpu.cpp - Changed sqlblob input processing client/ seti.cpp gdata.h sah_gfx.cpp sah_gfx_main.cpp sah_gfx_main.h vector/ analyzeFuncs_fpu.cpp win_build/ seti_graphics.dev seti_boinc_private.rc db/ schema_to_class.awk schema_master.cpp sqlblob.h Eric K Feb 19, 2008 - First attempt at simplifying autoconf. May break some builds on some platforms. - fixed problem with SAH_CHECK_ASMLIB macro m4/ sah_asmlib.m4 configure.ac Makefile.incl Makefile.am sah_config.h client/ sah_gfx.cpp client/ Makefile.am David 10 June 2008 - Add mechanism so that main program doesn't update shmem if no graphics app is running client/ gdata.h sah_gfx.cpp sah_gfx_main.cpp,.h Rom 11 Aug 2010 - WIN: Use BOINC defined library project files for Visual Studio. client/win_build/ libboinc.vcproj (deleted) libboincapi.vcproj (deleted) libgraphics2.vcproj (deleted) seti_boinc.sln Charlie 17 Aug 11 - Mac: Clean up XCode project (remove redundant build rules.) mac_build/ seti_boinc.xcodeproj/ project.pbxproj Charlie 21 Sep 12 - Bump version number in configure.ac to 7.00. - Mac: Fix path to graphics library, update Mac-specific configure files. configure.ac mac_build/ config_i386.h config_ppc.h seti_boinc.xcodeproj/ project.pbxproj boinc-app-seti_8.00~svn3701.orig/configure.ac0000644000175000017500000005205112645024153021005 0ustar locutuslocutus# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. # $Id: $ AC_PREREQ(2.57) AC_INIT(setiathome_v8, 8.00, korpela@ssl.berkeley.edu) AC_CONFIG_MACRO_DIR([m4]) svnrev="`svn info | grep Revision:`" if test -n "${svnrev}" ; then AC_REVISION("${svnrev}") AC_DEFINE_UNQUOTED(SVN_REV,"${svnrev}", [Define to be the subversion revision number]) else AC_REVISION([$Revision: 1146 $]) AC_DEFINE(SVN_REV,"$Revision: 1146 $", [Define to be the subversion revision number]) fi echo "WARNING! Changes have been made which are not compatible with SETI@home" echo "v7. Do not use this version with the projects until v8 is released" AC_CANONICAL_TARGET AM_INIT_AUTOMAKE(dist-zip) AC_CONFIG_SRCDIR([client/analyze.h]) AC_CACHE_SAVE # Set up the prefix early. if test "x$prefix" = "xNONE" ; then prefix="${ac_default_prefix}" fi if test "x$exec_prefix" = "xNONE" ; then exec_prefix="${ac_default_prefix}" fi # Make sure we use the same initial CFLAGS and CXXFLAGS unless otherwise told. if test -z "${CXXFLAGS}" then CXXFLAGS="${CFLAGS}" elif test -z "${CFLAGS}" then CFLAGS="${CXXFLAGS}" fi # make sure $includedir is in CFLAGS and $libdir is in LDFLAGS. tmpinc="`eval echo ${includedir}`" tmplib="`eval echo ${libdir}`" if test -z "`echo ${CFLAGS} | grep ${tmpinc}`" ; then CFLAGS="${CFLAGS} -I${tmpinc}" fi if test -z "`echo ${CXXFLAGS} | grep ${tmpinc}`" ; then CXXFLAGS="${CXXFLAGS} -I${tmpinc}" fi if test -z "`echo ${LDFLAGS} | grep ${tmplib}`" ; then LDFLAGS="${LDFLAGS} -L${tmplib}" fi AC_ARG_ENABLE(intrinsics, AS_HELP_STRING([--disable-intrinsics], [disable use of intrinsics in SIMD code])) if test "x$enable_intrinsics" != xno ; then enable_intrinsics=yes fi AC_ARG_ENABLE(graphics, AC_HELP_STRING([--disable-graphics], [disable building the client graphics])) if test "x$enable_graphics" != xno ; then enable_graphics=yes else enable_graphics=no fi AC_ARG_ENABLE(tests, AC_HELP_STRING([--disable-tests], [disable tests (fakedata and hires_timer_test)]), [], [enable_tests=yes]) AC_ARG_ENABLE(server, AC_HELP_STRING([--disable-server], [disable building the seti@home server components]), [], [enable_server=yes]) AC_ARG_ENABLE(client, AC_HELP_STRING([--disable-client], [disable building the client]), [], [enable_client=yes]) AC_ARG_ENABLE(static-client, AC_HELP_STRING([--disable-static-client], [allow dynamic libraries to be used in the client]), [enable_static_client=${enableval}], [enable_static_client=yes]) m4_divert_once([HELP_ENABLE], AC_HELP_STRING([], [Default: --enable-server --enable-client: builds both server and client])) if test "${enable_server}" = yes ; then if test "${enable_client}" = yes ; then configured_to_build='server & client' else configured_to_build='server only' fi else if test "${enable_client}" = yes ; then configured_to_build='client only' else AC_MSG_WARN([Youve disabled both the server and the client. Nothing useful will be built]) fi fi AC_MSG_NOTICE(["--- Configuring SETI_BOINC AC_PACKAGE_VERSION (${configured_to_build}) ---"]) AC_COPYRIGHT([ Copyright (C) 2004 Regents of the University of California SETI_BOINC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with SETI_BOINC; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Contributor(s): ]) major_version=`echo AC_PACKAGE_VERSION | sed 's/\..*//'` minor_version=`echo AC_PACKAGE_VERSION | sed 's/.*\.//' | sed 's/^0//'` AC_SUBST([MAJOR_VERSION], [$major_version]) AC_SUBST([MINOR_VERSION], [$minor_version]) AC_DEFINE_UNQUOTED([VERSION_MAJOR],$major_version, [SETI@home major version number]) AC_DEFINE_UNQUOTED([VERSION_MINOR],$minor_version, [SETI@home minor version number]) AC_DEFINE_UNQUOTED([SAH_APP_NAME],["$PACKAGE_NAME"], [Define to the BOINC application name for setiathome]) SAH_TOP_DIR=`pwd` AC_SUBST([SAH_TOP_DIR]) AM_MAINTAINER_MODE # Checks for programs. PATH="/usr/xpg4/bin:${PATH}" AC_PROG_CXX AC_PROG_CXXCPP AM_PROG_CC_C_O AM_PROG_AS AC_PROG_AWK AC_PROG_LN_S AC_PATH_PROG(TR,[tr]) AC_PATH_PROGS(AR,[ar lib]) AC_PATH_PROG(GREP,[grep]) AC_PATH_PROG(AUTOCONF,[autoconf]) AC_PATH_PROG(AUTOHEADER,[autoheader]) AC_PATH_PROGS(INDENT,[astyle indent]) AC_PATH_PROGS(CP,[cp copy]) AC_PATH_PROGS(LN,[ln cp copy]) AC_PATH_PROG(SORT,[sort]) AC_PATH_PROG(UNIQ,[uniq]) AC_PATH_PROG(CAT,[cat type]) AC_PATH_PROG(MV,[mv]) AC_PATH_PROGS(RM,[rm Rm del erase delete]) AC_LIBTOOL_DLOPEN AC_LIBTOOL_WIN32_DLL AM_PROG_LIBTOOL AC_SUBST(PICFLAGS,${lt_prog_compiler_pic}) AC_SUBST(SED) AC_C_BIGENDIAN AX_C_FLOAT_WORDS_BIGENDIAN SAH_OPTION_BITNESS SAH_REQUIRES([boinc],[SAH_CHECK_BOINC],["${no_boinc}" = yes], [ ERROR: trying to build the seti_boinc client or server but BOINC was not found. You can get boinc at http://boinc.ssl.berkeley.edu/ ], [exit 1]) AC_SUBST([BOINCDIR]) dnl Determine the BOINC platform given the target arch-platform-os. BOINC_PLATFORM if test -n `echo $INDENT | grep astyle` then AC_SUBST([INDENT_FLAGS],["--c --indent-classes --indent-switches --brackets=attach --convert-tabs"]) else AC_SUBST([INDENT_FLAGS],["-kr"]) fi AC_PROG_MAKE_SET SAH_DLLEXT SAH_LIBEXT if test -n "$EXEEXT" then DOTEXEEXT=".$EXEEXT" fi AC_SUBST(DOTEXEEXT) AC_SYS_LARGEFILE AX_PTHREAD([AC_DEFINE(HAVE_PTHREAD,1, [Have pthread])]) if test "x$enable_client" = xyes ; then # find the right flag for building a static app if test "x$enable_static_client" != xno ; then svldflags="$LDFLAGS" SAH_CHECK_LDFLAG([-static],[LDSTATIC=-static]) LDFLAGS="$svldflags" fi # Check libraries required or desired for seti_boinc app # Checks for libraries. APP_LDFLAGS="$LDSTATIC $LDFLAGS" APP_CFLAGS="$CFLAGS" AC_CHECK_LIB([log],[__android_log_print], [APP_LIBS="-llog ${APP_LIBS}"]) dnl AC_CHECK_LIB([corkscrew],[unwind_backtrace_signal_arch], dnl [APP_LIBS="-lcorkscrew ${APP_LIBS}"]) AC_CHECK_LIB([m], [sin],[ AC_DEFINE([HAVE_LIBM],[1],[Define to 1 if you have the math library]) APP_LIBS="-lm ${APP_LIBS}" ]) SAH_CHECK_MATH_FUNCS([sqrt floor sinf cosf sincos sincosf atanf isnan _isnan __isnan __isnanf _isnanf isnanf]) AC_CHECK_LIB([fftw3f], [fftwf_plan_dft_1d], [ AC_DEFINE([HAVE_LIBFFTW3F],[1],[Define to 1 if you have the fftw3f library]) APP_LIBS="-lfftw3f ${APP_LIBS}" ], [], [-lm]) AC_CHECK_LIB([fftw3], [fftwf_plan_dft_1d], [ AC_DEFINE([HAVE_LIBFFTW3F],[1],[Define to 1 if you have the fftw3f library]) APP_LIBS="-lfftw3 ${APP_LIBS}" ], [], [-lm]) AC_CHECK_LIB([cpufeatures], [android_getCpuFeatures], [ AC_DEFINE([HAVE_LIBCPUFEATURES],[1],[Define to 1 if you have the cpufeatures library]) APP_LIBS="-lcpufeatures ${APP_LIBS}" ], [], [-lm]) AC_ARG_ENABLE(neon, AC_HELP_STRING([--disable-neon], [Disable neon instruction set on ARM devices]), [enable_neon=${enableval}], [enable_neon=yes]) if test "x${enable_neon}" = xyes ; then AC_DEFINE([USE_NEON],1,[Define to 1 to enable neon instructions on ARM devices]) fi SAH_CHECK_ASMLIB APP_LIBS="${ASMLIB_LIBS} ${APP_LIBS}" APP_CFLAGS="${ASMLIB_CFLAGS} ${APP_CFLAGS}" APP_LDFLAGS="${ASMLIB_LDFLAGS} ${APP_LDFLAGS}" # Check for additional optimization flags SAH_OPTIMIZATIONS # Check for intel performance primatives SAH_CHECK_IPP if test x$found_ipp = xyes ; then APP_LDFLAGS="-L${IPPDIR}/lib ${APP_LDFLAGS}" APP_LIBS="-lippcore -lippsmerged ${APP_LIBS}" APP_CFLAGS="-I${IPPDIR}/include ${APP_CFLAGS}" fi AC_SUBST([APP_LIBS]) AC_SUBST([APP_LDFLAGS]) AC_SUBST([APP_CFLAGS]) if test "$enable_graphics" = yes ; then SAH_GRX_LIBS AX_CHECK_GL AX_CHECK_GLU AX_CHECK_GLUT if test "$no_gl" = yes -o "$no_glu" = yes -o "$no_glut" = yes ; then have_glut=no enable_graphics=no AC_MSG_WARN([ ================================================================================ WARNING: GL/GLU/GLUT not found. The GL, GLU, and GLUT libraries are required in order to build the graphical parts of the BOINC application API library. ==> only building non-graphical parts of the BOINC API Library for now. ================================================================================ ]) else AC_DEFINE([BOINC_APP_GRAPHICS],1,[Define to 1 to build a graphical application]) SAH_GRX_INCLUDES GRAPHICS_CFLAGS="${GRX_CFLAGS} ${GL_CFLAGS} ${GLU_CFLAGS} ${GLUT_CFLAGS}" GRAPHICS_LIBS="${GL_LIBS} ${GLU_LIBS} ${GLUT_LIBS} ${GRX_LIBS} -ljpeg" case ${target} in powerpc-apple*) GRAPHICS_LIBS="${GRAPHICS_LIBS} -framework AppKit -framework CoreServices" ;; esac GRAPHICS_LIBS_RAW="${PTHREAD_CFLAGS} -L${BOINCDIR}/api -L${BOINCDIR}/lib -lboinc_graphics2 -lboinc ${GRAPHICS_LIBS}" dnl SAH_RAW_LDFLAGS(["${PTHREAD_CFLAGS} -L${BOINCDIR}/api -L${BOINCDIR}/lib -lboinc_graphics2 -lboinc ${GRAPHICS_LIBS}"],[GRAPHICS_LIBS_RAW]) have_glut=yes enable_graphics=yes fi fi AC_SUBST([LDSTATIC]) AC_SUBST([GRAPHICS_CFLAGS]) AC_SUBST([GRAPHICS_LIBS]) AC_SUBST([GRAPHICS_LIBS_RAW]) AC_CACHE_SAVE fi dnl SAH_CHECK_LIB([c],[atexit], dnl AC_DEFINE([HAVE_LIBC],[1],[Define to 1 if you have the c library])) dnl SAH_CHECK_LIB([pthread],[pthread_join], dnl AC_DEFINE([HAVE_LIBPTHREAD],[1],[Define to 1 if you have the pthread library])) dnl AC_CHECK_LIB([gcc],[sscanf], dnl AC_DEFINE([HAVE_LIBGCC],[1],[Define to 1 if you have the gcc library])) dnl SAH_CHECK_LIB([gcc_eh],[_Unwind_Resume], dnl AC_DEFINE([HAVE_LIBGCC_EH],[1],[Define to 1 if you have the gcc_eh library])) dnl SAH_CHECK_LIB([gcc_s],[sscanf], dnl AC_DEFINE([HAVE_LIBGCC_S],[1],[Define to 1 if you have the gcc_s library])) dnl AC_CHECK_LIB([stdc++],[sscanf], dnl AC_DEFINE([HAVE_LIBSTDC__],[1],[Define to 1 if you have the stdc++ library])) dnl AC_CHECK_LIB([z], [uncompress], dnl AC_DEFINE([HAVE_LIBZ],[1],[Define to 1 if you have the z library])) dnl AC_CHECK_LIB([socket], [bind], dnl AC_DEFINE([HAVE_LIBSOCKET],[1],[Define to 1 if you have the socket library])) dnl AC_CHECK_LIB([rt], [sched_get_priority_min], dnl AC_DEFINE([HAVE_LIBRT],[1],[Define to 1 if you have the rt library])) dnl AC_CHECK_LIB([nsl], [gethostbyname], dnl AC_DEFINE([HAVE_LIBNSL],[1],[Define to 1 if you have the nsl library])) dnl AC_CHECK_LIB([elf], [elf_hash], dnl AC_DEFINE([HAVE_LIBELF],[1],[Define to 1 if you have the elf library])) dnl AC_CHECK_LIB([aio], [aio_fork], dnl AC_DEFINE([HAVE_LIBAIO],[1],[Define to 1 if you have the aio library])) CHECK_SSL AC_CHECK_LIB([ssl], [fopen], [BOINC_EXTRA_LIBS="${BOINC_EXTRA_LIBS} -L${SSLDIR}/lib ${sah_lib_last}"]) AC_CHECK_LIB([crypto], [RSA_new], [BOINC_EXTRA_LIBS="${BOINC_EXTRA_LIBS} -L${SSLDIR}/lib ${sah_lib_last}"]) dnl AC_CHECK_LIB([dl], [dlopen], dnl AC_DEFINE([HAVE_LIBDL],[1],[Define to 1 if you have the dl library])) AC_LANG(C++) case ${target} in *-apple-darwin*) CLIENT_EXTRA_LIBS="${CLIENT_EXTRA_LIBS} -framework Accelerate -framework CoreServices" ;; esac if test "${ac_cv_cxx_compiler_gnu}" = "yes" ; then gcc_version_string="`${CXX} --version | head -1`" AC_DEFINE_UNQUOTED([COMPILER_STRING],"$gcc_version_string",[Define to a string identifying your compiler]) else if test -n "${CXX}" ; then AC_DEFINE_UNQUOTED([COMPILER_STRING],"$CXX",[Define to a string identifying your compiler]) else if test -n "${CC}" ; then AC_DEFINE_UNQUOTED([COMPILER_STRING],"$CC",[Define to a string identifying your compiler]) fi fi fi SAH_SERVER_REQUIRES([mysql],[SAH_CHECK_MYSQL],["${no_mysql}" = yes]) SAH_SERVER_REQUIRES([informix],[SAH_CHECK_INFORMIX],["${no_informix}" = yes]) SAH_SERVER_REQUIRES([setilib],[SAH_FIND_SETILIB],["${no_setilib}" = yes]) SAH_SERVER_REQUIRES([healpix],[SAH_CHECK_HEALPIX],["${no_healpix}" = yes]) SAH_SERVER_REQUIRES([cfitsio],[SAH_CHECK_CFITSIO],["${no_cfitsio}" = yes]) SAH_SERVER_REQUIRES([seti_gbt],[SAH_CHECK_SETI_GBT],["${no_seti_gbt}" = yes]) # Checks for header files. AC_HEADER_STDC SAH_LARGEFILE_BREAKS_CXX SAH_HEADER_STDCXX AC_HEADER_SYS_WAIT AC_HEADER_TIME AC_CHECK_HEADERS([mmap.h mman.h sys/mman.h fcntl.h inttypes.h limits.h memory.h alloca.h malloc.h stdlib.h string.h strings.h errno.h sys/time.h sys/types.h sys/ioctl.h sys/statvfs.h unistd.h dirent.h math.h float.h ieeefp.h floatingpoint.h complex.h fftw3.h setjmp.h signal.h mach/mach_time.h sys/param.h sys/systm.h machine/cpu.h cpu-features.h sys/cpu-features.h machine/cpu-features.h]) save_cxxflags="${CXXFLAGS}" save_cppflags="${CPPFLAGS}" CXXFLAGS="${CXXFLAGS} -msse3" CPPFLAGS="${CPPFLAGS} -msse3" AC_CHECK_HEADERS([intrin.h x86intrin.h pmmintrin.h xmmintrin.h emmintrin.h]) CXXFLAGS="${save_cxxflags} -mavx" CPPFLAGS="${save_cppflags} -mavx" AC_CHECK_HEADERS([immintrin.h avxintrin.h]) CXXFLAGS="${save_cxxflags}" CPPFLAGS="${save_cppflags}" if test "x$enable_intrinsics" != "xno" ; then if test "x$ac_cv_header_xmmintrin_h" != "xno" -o "x$ac_cv_header_emmintrin_h" != "xno" ; then AC_DEFINE([USE_INTRINSICS],[1],[Define to 1 to use SIMD intrinsics rather than inline assembly]) fi fi AC_CACHE_SAVE # Checks for typedefs, structures, and compiler characteristics. AC_HEADER_STDBOOL AC_C_CONST AC_C_INLINE AC_C_LONG_DOUBLE AC_TYPE_OFF_T AC_TYPE_SIZE_T AC_STRUCT_ST_BLOCKS AC_STRUCT_TM AC_CHECK_SIZEOF([short]) AC_CHECK_SIZEOF([int]) AC_CHECK_SIZEOF([long int]) AC_CHECK_SIZEOF([float]) AC_CHECK_SIZEOF([double]) AC_CHECK_SIZEOF([long double]) AC_CHECK_TYPES([long long,_int64,int64_t,bool,_int32, _uint32, int32_t, uint32_t, hrtime_t, uint_fast64_t, uint64_t, _uint64, u_int64_t, ptrdiff_t, ssize_t, off64_t]) AC_CHECK_TYPES([sigjmp_buf, jmp_buf], [], [], [[#ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif #ifdef HAVE_SIGNAL_H # include #endif #ifdef HAVE_SETJMP_H # include #endif ]]) CXXFLAGS="${save_cxxflags} -mavx" CPPFLAGS="${save_cppflags} -mavx" AC_CHECK_TYPES([__m256,_m256,__m256d,_m256d,__m256i,_m256i],[],[],[[#ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif #define __AVX__ 1 #if defined(HAVE_IMMINTRIN_H) #include #elif defined(HAVE_AVXINTRIN_H) #include #elif defined(HAVE_X86INTRIN_H) #include #elif defined(HAVE_INTRIN_H) #include #endif ]]) CXXFLAGS="${save_cxxflags}" CPPFLAGS="${save_cppflags}" AC_CACHE_SAVE # Checks for library functions. AC_LANG(C) AC_FUNC_FORK AC_HEADER_MAJOR AC_FUNC_ALLOCA if test "${ac_cv_func_alloca_works}" = "yes" ; then ac_cv_func_alloca="yes" fi AC_FUNC_STAT AC_FUNC_STRFTIME AC_CHECK_DECLS([__builtin_alloca,__builtin_popcount,__builtin_prefetch,__builtin_clz,__builtin_ffs,__builtin_isnan], [],[],[[ #include #include ]]) if test "${ac_cv_have_decl___builtin_alloca}" = "yes" ; then ac_cv_func___builtin_alloca="yes" fi if test "${ac_cv_have_decl___builtin_popcount}" = "yes" ; then ac_cv_func___builtin_popcount="yes" fi if test "${ac_cv_have_decl___builtin_prefetch}" = "yes" ; then ac_cv_func___builtin_prefetch="yes" fi if test "${ac_cv_have_decl___builtin_clz}" = "yes" ; then ac_cv_func___builtin_clz="yes" fi if test "${ac_cv_have_decl___builtin_ffs}" = "yes" ; then ac_cv_func___builtin_ffs="yes" fi if test "${ac_cv_have_decl___builtin_isnan}" = "yes" ; then ac_cv_func___builtin_isnan="yes" fi AC_CHECK_FUNCS([ _aligned_malloc alloca _alloca __builtin_alloca __builtin_popcount __builtin_prefetch __builtin_clz __builtin_ffs posix_memalign memalign atexit exit _exit getcwd memset munmap putenv strchr strstr strcasestr atoll dlopen gethrtime mach_absolute_time get_cyclecount clock_gettime nanotime microtime gettimeofday sqrt floor sinf cosf sincos sincosf atanf isnan _isnan __isnan __builtin_isnan isnanf _isnanf __isnanf siglongjmp sigsetjmp sigaction sysv_signal bsd_signal ]) SAH_CHECK_NAMESPACES AH_TEMPLATE([HAVE_STD_MIN],[Define to 1 if min is in namespace std::]) AH_TEMPLATE([HAVE_STD_MAX],[Define to 1 if max is in namespace std::]) AH_TEMPLATE([HAVE_STD_TRANSFORM],[Define to 1 if transform is in namespace std::]) SAH_FUNCS_IN_NAMESPACE([['min(0,0)'] ['max(0,0)'] ['transform((char *)0,(char *)0,(char *)0,(int(*)(int))malloc)']],std) SAH_AVX AM_CONDITIONAL(USE_MY_IMAGELIBS, [false]) AM_CONDITIONAL(USE_MY_GLUT, [false]) AM_CONDITIONAL(ENABLE_TESTS, [test "${enable_tests}" = yes]) AM_CONDITIONAL(ENABLE_SERVER, [test "${enable_server}" = yes]) AM_CONDITIONAL(ENABLE_CLIENT, [test "${enable_client}" = yes]) AM_CONDITIONAL(ENABLE_GUI, [test "${enable_graphics}" = yes]) AM_CONDITIONAL(LINUX, [test -n "`echo ${target} | grep linux`"]) AM_CONDITIONAL(I386, [test -n "`echo ${target} | $EGREP 'i.86|x86_64|amd64'`" -a $COMPILER_MODEL_BITS -eq 32]) AM_CONDITIONAL(X86_64, [test -n "`echo ${target} | $EGREP 'i.86|x86_64|amd64'`" -a $COMPILER_MODEL_BITS -eq 64 ]) AM_CONDITIONAL(PPC, [test -n "`echo ${target} | grep 'powerpc'`" -o -n "`echo ${target} | grep 'ppc'`" ]) AM_CONDITIONAL(AVX, [test "x${have_avx}" = "xyes"]) if test "x${avx_type}" != "x" ; then AC_DEFINE_UNQUOTED([AVX_MASKSTORE_TYPECAST(x)],[reinterpret_cast<$avx_type>(x)], [Define to the typecast required for arg 2 of _mm256_maskstore_ps()]) else AC_DEFINE_UNQUOTED([AVX_MASKSTORE_TYPECAST(x)],[(x)], [Define to the typecast required for arg 2 of _mm256_maskstore_ps()]) fi AC_ARG_WITH([float-abi], AC_HELP_STRING([--with-float-abi=], [set -mfloat-abi parameter for gcc]), [FP_ABI_FLAGS="-mfloat-abi=$withval"],[ if test "x$FP_ABI_FLAGS" = "x" && test "x`echo ${CFLAGS} ${CPPFLAGS} ${CXXFLAGS} | grep mfloat-ab`" = "x" ; then case $host in arm-*-armhf|arm-*-gnueabihf) FP_ABI_FLAGS="-mfloat-abi=hard" ;; arm-*-armel|arm-*-androideabi|arm-*-gnueabi) FP_ABI_FLAGS="-mfloat-abi=softfp" ;; *) FP_ABI_FLAGS= ;; esac fi ]) AC_ARG_WITH([fpu], AC_HELP_STRING([--with-fpu=], [set -mfpu parameter for gcc]), [FP_FLAGS="-mfpu=$withval"],[ if test "x$FP_ABI_FLAGS" != "x-mfloat-abi=soft" && ! ( echo ${CFLAGS} ${CPPFLAGS} ${CXXFLAGS} | grep "mfloat-abi=soft[[ $]]" >/dev/null ) ; then if test "x$FP_FLAGS" = "x" && ! ( echo ${CFLAGS} ${CPPFLAGS} ${CXXFLAGS} | grep mfpu >/dev/null ) ; then case $host in arm-*-armhf|arm-*-armel|arm-*-androideabi) FP_FLAGS="-mfpu=vfp" ;; *) FP_FLAGS= ;; esac fi fi ]) AC_SUBST([FP_ABI_FLAGS]) AC_SUBST([FP_FLAGS]) AC_CACHE_SAVE AH_TOP([ #ifndef _SAH_CONFIG_H_ #define _SAH_CONFIG_H_ #if defined(__linux__) #define _POSIX_C_SOURCE 1 #endif #ifdef _WIN32 #include "win-sah_config.h" #else ]) AH_BOTTOM([ /* Define USE_NAMESPACES if you may access more than one database from the * same program */ #endif /* * Use fftw if we have the library */ #if defined(HAVE_LIBFFTW3F) && defined(HAVE_FFTW3_H) #define USE_FFTWF #endif #if defined(USE_INFORMIX) && defined(USE_MYSQL) && defined(HAVE_NAMESPACES) #define USE_NAMESPACES #endif #if !defined(CUSTOM_STRING) && defined(COMPILER_STRING) #define CUSTOM_STRING PACKAGE_STRING" "SVN_REV" "COMPILER_STRING #endif #include "std_fixes.h" #endif ]) AC_SUBST([CLIENT_EXTRA_LIBS]) AC_CONFIG_FILES([Makefile glut/Makefile image_libs/Makefile jpeglib/Makefile client/Makefile tools/Makefile db/Makefile db/tools/Makefile db/schema_to_class assimilator/Makefile validate/Makefile splitter_pfb/Makefile splitter_fft/Makefile ]) AC_CONFIG_HEADERS([sah_config.h]) AC_OUTPUT chmod +x db/schema_to_class boinc-app-seti_8.00~svn3701.orig/AUTHORS0000644000175000017500000000255212667707323017603 0ustar locutuslocutus Authors of SETI@home: Eric J. Korpela Jeff Cobb Matt Lebofsky David Anderson Charlie Fenton Rom Walton Tetsuji Rai Eric Heien Hiram Clawson Alex Kan Ben Herndon Josef Segur Simon Zadra Jason Groothuis Raistmer Mateusz Szpakowski Authors of FFTW (reachable at fftw at fftw.org): Matteo Frigo Stevenj G. Johnson Stefan Kral wrote genfft-k7/*.ml*, which was added in fftw-3.0 and removed in fftw-3.2. Additional authors of Astropulse: Joshua Von Korff Paul Demorest OpenCL development by: Raistmer Urs Echternacht Frizz X-Branch CUDA by: Jason Richard Groothuis ( jgopt.org, contact at jgopt dot org ), in collaboration with Josef Segur ( Lunatics.kwsn.info ) Linux porting by Aaron Haviland. Original CUDA development by: Przemyslaw Zych (NVIDIA) Scott Le Grand (NVIDIA) Bob Johnston (NVIDIA) Authors of fft8g.[cpp,h] Takuya Ooura Eric J. Korpela Jeff Cobb Author of ASMLIB Agner Fog Background artwork by Tatiana Plakhova ( http://complexitygraphics.com/ ) boinc-app-seti_8.00~svn3701.orig/setiathome.pbproj/0000755000175000017500000000000013155506301022146 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/setiathome.pbproj/project.pbxproj0000644000175000017500000015454210671336410025237 0ustar locutuslocutus// !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 38; objects = { 0249A665FF388DC511CA2CEA = { isa = PBXApplicationReference; path = setiathome.app; refType = 3; }; 0249A669FF388E3911CA2CEA = { isa = PBXFileReference; name = "libstdc++.a"; path = "/usr/lib/libstdc++.a"; refType = 0; }; //020 //021 //022 //023 //024 //040 //041 //042 //043 //044 04313892FE3035C9C02AAC07 = { buildActionMask = 2147483647; files = ( ); isa = PBXRezBuildPhase; runOnlyForDeploymentPostprocessing = 0; }; //040 //041 //042 //043 //044 //050 //051 //052 //053 //054 05952DFCFFF02D1B11CA0E50 = { buildRules = ( ); buildSettings = { COPY_PHASE_STRIP = NO; OPTIMIZATION_CFLAGS = "-O0"; }; isa = PBXBuildStyle; name = Development; }; 05952DFDFFF02D1B11CA0E50 = { buildRules = ( ); buildSettings = { COPY_PHASE_STRIP = YES; }; isa = PBXBuildStyle; name = Deployment; }; //050 //051 //052 //053 //054 //060 //061 //062 //063 //064 0640BAA4FFF0323A11CA0E50 = { isa = PBXFrameworkReference; name = ApplicationServices.framework; path = /System/Library/Frameworks/ApplicationServices.framework; refType = 0; }; 0640BAA5FFF0323A11CA0E50 = { isa = PBXFrameworkReference; name = CoreServices.framework; path = /System/Library/Frameworks/CoreServices.framework; refType = 0; }; //060 //061 //062 //063 //064 //190 //191 //192 //193 //194 195DF8C9FE9D4F0611CA2CBB = { children = ( 0249A665FF388DC511CA2CEA, ); isa = PBXGroup; name = Products; refType = 4; }; //190 //191 //192 //193 //194 //200 //201 //202 //203 //204 20286C28FDCF999611CA2CEA = { buildStyles = ( 05952DFCFFF02D1B11CA0E50, 05952DFDFFF02D1B11CA0E50, ); hasScannedForEncodings = 1; isa = PBXProject; mainGroup = 20286C29FDCF999611CA2CEA; projectDirPath = ""; targets = ( 20286C34FDCF999611CA2CEA, ); }; 20286C29FDCF999611CA2CEA = { children = ( AA3FFC8F053BDEC000164350, AA3FFC00053BCCC700164350, AA6AA8C804113B7B00A80164, 20286C2AFDCF999611CA2CEA, 20286C2CFDCF999611CA2CEA, 20286C32FDCF999611CA2CEA, 195DF8C9FE9D4F0611CA2CBB, ); isa = PBXGroup; name = "¬´PROJECTNAME¬ª"; path = ""; refType = 4; }; 20286C2AFDCF999611CA2CEA = { children = ( AA763A9B0400775C00A80164, AA3FFB63053BC42600164350, AA763A910400775C00A80164, AA3FFB0B053BC3AA00164350, AA763A930400775C00A80164, AA763A940400775C00A80164, AA763A950400775C00A80164, AA3FFB0C053BC3AA00164350, AA763A970400775C00A80164, AA3FFB64053BC42600164350, AABC80520410BC6E00A80164, AA763A9C0400775C00A80164, AA763A9E0400775C00A80164, AA763A9D0400775C00A80164, AA763A9F0400775C00A80164, AA763AB00400777000A80164, AA763AB20400777000A80164, AABC80550410BCCF00A80164, AABC80540410BCCF00A80164, AADBC6EE04226C0F00A80164, AADBC6EF04226C0F00A80164, AA763AB30400777000A80164, AA763AB10400777000A80164, AA3FFB69053BC4DA00164350, AA3FFBF2053BC99600164350, AA3FFBF3053BC99600164350, AA3FFBF8053BCAAD00164350, AA3FFBF9053BCAAD00164350, ); isa = PBXGroup; name = "BOINC Sources"; path = ""; refType = 4; }; 20286C2CFDCF999611CA2CEA = { children = ( ); isa = PBXGroup; name = Resources; path = ""; refType = 4; }; 20286C32FDCF999611CA2CEA = { children = ( 20286C33FDCF999611CA2CEA, 0249A669FF388E3911CA2CEA, 0640BAA4FFF0323A11CA0E50, 0640BAA5FFF0323A11CA0E50, AA763B590400789200A80164, AA763B5B040078AC00A80164, AA763B5C040078AC00A80164, AA763B6104007BB800A80164, AA6AA8C60410C8B300A80164, ); isa = PBXGroup; name = "External Frameworks and Libraries"; path = ""; refType = 4; }; 20286C33FDCF999611CA2CEA = { isa = PBXFrameworkReference; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; refType = 0; }; 20286C34FDCF999611CA2CEA = { buildPhases = ( 20286C35FDCF999611CA2CEA, 20286C36FDCF999611CA2CEA, 20286C38FDCF999611CA2CEA, 20286C3BFDCF999611CA2CEA, 04313892FE3035C9C02AAC07, ); buildSettings = { FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ""; INSTALL_PATH = "$(HOME)/Applications"; LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.1; OTHER_CFLAGS = "-DHAVE_DIRENT_H -DHAVE_SYS_RESOURCE_H -DHAVE_INTTYPES_H -DHAVE_UNISTD_H -DHAVE_SIGNAL_H -DHAVE_SYS_TIME_H -DFFTW_ENABLE_FLOAT -DBOINC_APP_GRAPHICS -DHAVE_SYS_SHM_H -DHAVE_SYS_IPC_H -DHAVE_SYS_MOUNT_H -DCLIENT -DVERSION_MINOR=00 -DVERSION_MAJOR=4 -DHAVE_ATOLL -DFAR="; OTHER_LDFLAGS = ""; OTHER_REZFLAGS = ""; PRODUCT_NAME = setiathome; SECTORDER_FLAGS = ""; WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas"; WRAPPER_EXTENSION = app; }; dependencies = ( ); isa = PBXApplicationTarget; name = setiathome; productInstallPath = "$(HOME)/Applications"; productName = "¬´PROJECTNAME¬ª"; productReference = 0249A665FF388DC511CA2CEA; productSettingsXML = " CFBundleDevelopmentRegion English CFBundleExecutable setiathome CFBundleIconFile CFBundleInfoDictionaryVersion 6.0 CFBundlePackageType APPL CFBundleSignature ???? CFBundleVersion 0.1 CSResourcesFileMapped "; }; 20286C35FDCF999611CA2CEA = { buildActionMask = 2147483647; files = ( AA763AAC0400775C00A80164, AA763AAD0400775C00A80164, AA763AB40400777000A80164, AA763AB50400777000A80164, AABC80570410BCCF00A80164, AABC806A0410BD2600A80164, AABC806E0410BD2800A80164, AABC80730410BEEE00A80164, AABC80790410C06700A80164, AA6AA8B10410C34000A80164, AADBC6F104226C0F00A80164, AA3FFB39053BC3EB00164350, AA3FFB3B053BC3EB00164350, AA3FFB3D053BC3EB00164350, AA3FFB3F053BC3EB00164350, AA3FFB41053BC3EB00164350, AA3FFB43053BC3EB00164350, AA3FFB46053BC3EB00164350, AA3FFB48053BC3EB00164350, AA3FFB4B053BC3EB00164350, AA3FFB4E053BC3EB00164350, AA3FFB4F053BC3EB00164350, AA3FFB51053BC3EB00164350, AA3FFB54053BC3EB00164350, AA3FFB56053BC3EB00164350, AA3FFB58053BC3EB00164350, AA3FFB5A053BC3EB00164350, AA3FFB5C053BC3EB00164350, AA3FFB5E053BC3EB00164350, AA3FFB60053BC3EB00164350, AA3FFB62053BC3EB00164350, AA3FFB6A053BC4DA00164350, AA3FFBF5053BC99600164350, AA3FFBFB053BCAAD00164350, AA3FFBFF053BCAF200164350, AA3FFC43053BCCE200164350, AA3FFC44053BCCE200164350, AA3FFC4B053BCCE200164350, AA3FFC51053BCCE200164350, AA3FFC5D053BCCE200164350, AA3FFC60053BCCE200164350, AA3FFC6B053BCCE200164350, AA3FFC73053BCCE200164350, AA3FFC76053BCCE200164350, AA3FFC77053BCCE200164350, AA3FFC78053BCCE200164350, AA3FFC79053BCCE200164350, AA3FFC7D053BCCE200164350, AA3FFC86053BCDAD00164350, AA3FFC8A053BD34A00164350, AA3FFC8E053BDE9100164350, ); isa = PBXHeadersBuildPhase; runOnlyForDeploymentPostprocessing = 0; }; 20286C36FDCF999611CA2CEA = { buildActionMask = 2147483647; files = ( ); isa = PBXResourcesBuildPhase; runOnlyForDeploymentPostprocessing = 0; }; 20286C38FDCF999611CA2CEA = { buildActionMask = 2147483647; files = ( AA763AAE0400775C00A80164, AA763AAF0400775C00A80164, AA763AB60400777000A80164, AA763AB70400777000A80164, AABC80530410BC6E00A80164, AABC80560410BCCF00A80164, AABC80720410BEED00A80164, AADBC6F004226C0F00A80164, AA3FFB0D053BC3AA00164350, AA3FFB0E053BC3AA00164350, AA3FFB3A053BC3EB00164350, AA3FFB3C053BC3EB00164350, AA3FFB3E053BC3EB00164350, AA3FFB40053BC3EB00164350, AA3FFB42053BC3EB00164350, AA3FFB44053BC3EB00164350, AA3FFB45053BC3EB00164350, AA3FFB47053BC3EB00164350, AA3FFB4A053BC3EB00164350, AA3FFB4C053BC3EB00164350, AA3FFB4D053BC3EB00164350, AA3FFB50053BC3EB00164350, AA3FFB52053BC3EB00164350, AA3FFB53053BC3EB00164350, AA3FFB55053BC3EB00164350, AA3FFB57053BC3EB00164350, AA3FFB59053BC3EB00164350, AA3FFB5B053BC3EB00164350, AA3FFB5D053BC3EB00164350, AA3FFB5F053BC3EB00164350, AA3FFB61053BC3EB00164350, AA3FFB65053BC42600164350, AA3FFB66053BC42600164350, AA3FFBF4053BC99600164350, AA3FFBFA053BCAAD00164350, AA3FFBFE053BCAF200164350, AA3FFC45053BCCE200164350, AA3FFC46053BCCE200164350, AA3FFC47053BCCE200164350, AA3FFC48053BCCE200164350, AA3FFC49053BCCE200164350, AA3FFC4A053BCCE200164350, AA3FFC4C053BCCE200164350, AA3FFC4D053BCCE200164350, AA3FFC4E053BCCE200164350, AA3FFC4F053BCCE200164350, AA3FFC50053BCCE200164350, AA3FFC52053BCCE200164350, AA3FFC53053BCCE200164350, AA3FFC54053BCCE200164350, AA3FFC55053BCCE200164350, AA3FFC56053BCCE200164350, AA3FFC57053BCCE200164350, AA3FFC58053BCCE200164350, AA3FFC59053BCCE200164350, AA3FFC5A053BCCE200164350, AA3FFC5B053BCCE200164350, AA3FFC5C053BCCE200164350, AA3FFC5E053BCCE200164350, AA3FFC5F053BCCE200164350, AA3FFC61053BCCE200164350, AA3FFC62053BCCE200164350, AA3FFC63053BCCE200164350, AA3FFC64053BCCE200164350, AA3FFC65053BCCE200164350, AA3FFC66053BCCE200164350, AA3FFC67053BCCE200164350, AA3FFC68053BCCE200164350, AA3FFC69053BCCE200164350, AA3FFC6A053BCCE200164350, AA3FFC6C053BCCE200164350, AA3FFC6D053BCCE200164350, AA3FFC6E053BCCE200164350, AA3FFC6F053BCCE200164350, AA3FFC70053BCCE200164350, AA3FFC71053BCCE200164350, AA3FFC72053BCCE200164350, AA3FFC74053BCCE200164350, AA3FFC75053BCCE200164350, AA3FFC7A053BCCE200164350, AA3FFC7B053BCCE200164350, AA3FFC7C053BCCE200164350, AA3FFC7E053BCCE200164350, AA3FFC7F053BCCE200164350, AA3FFC80053BCCE200164350, AA3FFC81053BCCE200164350, AA3FFC82053BCCE200164350, AA3FFC83053BCCE200164350, AA3FFC84053BCCE200164350, AA3FFC89053BD34A00164350, AA3FFC8D053BDE9100164350, ); isa = PBXSourcesBuildPhase; runOnlyForDeploymentPostprocessing = 0; }; 20286C3BFDCF999611CA2CEA = { buildActionMask = 2147483647; files = ( AA763B5A0400789200A80164, AA763B5E040078AC00A80164, AA763B6304007BD100A80164, AA763B8904007C2F00A80164, AA763B8A04007C8A00A80164, AA6AA8C70410C8B300A80164, ); isa = PBXFrameworksBuildPhase; runOnlyForDeploymentPostprocessing = 0; }; //200 //201 //202 //203 //204 //AA0 //AA1 //AA2 //AA3 //AA4 AA3FFB0B053BC3AA00164350 = { fileEncoding = 30; isa = PBXFileReference; name = gutil.C; path = ../boinc/api/gutil.C; refType = 4; }; AA3FFB0C053BC3AA00164350 = { fileEncoding = 30; isa = PBXFileReference; name = reduce.C; path = ../boinc/api/reduce.C; refType = 4; }; AA3FFB0D053BC3AA00164350 = { fileRef = AA3FFB0B053BC3AA00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB0E053BC3AA00164350 = { fileRef = AA3FFB0C053BC3AA00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB0F053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = analyze.h; path = client/analyze.h; refType = 4; }; AA3FFB10053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = analyzeFuncs.cpp; path = client/analyzeFuncs.cpp; refType = 4; }; AA3FFB11053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = analyzeFuncs.h; path = client/analyzeFuncs.h; refType = 4; }; AA3FFB12053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = analyzePoT.cpp; path = client/analyzePoT.cpp; refType = 4; }; AA3FFB13053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = analyzePoT.h; path = client/analyzePoT.h; refType = 4; }; AA3FFB14053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = analyzeReport.cpp; path = client/analyzeReport.cpp; refType = 4; }; AA3FFB15053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = analyzeReport.h; path = client/analyzeReport.h; refType = 4; }; AA3FFB16053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = chirpfft.cpp; path = client/chirpfft.cpp; refType = 4; }; AA3FFB17053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = chirpfft.h; path = client/chirpfft.h; refType = 4; }; AA3FFB18053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = fft8g.cpp; path = client/fft8g.cpp; refType = 4; }; AA3FFB19053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = fft8g.h; path = client/fft8g.h; refType = 4; }; AA3FFB1A053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = gasdev.cpp; path = client/gasdev.cpp; refType = 4; }; AA3FFB1B053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = gaussfit.cpp; path = client/gaussfit.cpp; refType = 4; }; AA3FFB1C053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = gaussfit.h; path = client/gaussfit.h; refType = 4; }; AA3FFB1D053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = gdata.cpp; path = client/gdata.cpp; refType = 4; }; AA3FFB1E053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = gdata.h; path = client/gdata.h; refType = 4; }; AA3FFB20053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = lcgamm.cpp; path = client/lcgamm.cpp; refType = 4; }; AA3FFB21053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = lcgamm.h; path = client/lcgamm.h; refType = 4; }; AA3FFB22053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = main.cpp; path = client/main.cpp; refType = 4; }; AA3FFB23053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = malloc_a.cpp; path = client/malloc_a.cpp; refType = 4; }; AA3FFB24053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = malloc_a.h; path = client/malloc_a.h; refType = 4; }; AA3FFB25053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = nr.h; path = client/nr.h; refType = 4; }; AA3FFB26053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = pulsefind.cpp; path = client/pulsefind.cpp; refType = 4; }; AA3FFB27053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = pulsefind.h; path = client/pulsefind.h; refType = 4; }; AA3FFB28053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = ran1.cpp; path = client/ran1.cpp; refType = 4; }; AA3FFB29053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = s_util.cpp; path = client/s_util.cpp; refType = 4; }; AA3FFB2A053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = s_util.h; path = client/s_util.h; refType = 4; }; AA3FFB2B053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = sah_gfx.cpp; path = client/sah_gfx.cpp; refType = 4; }; AA3FFB2C053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = sah_gfx.h; path = client/sah_gfx.h; refType = 4; }; AA3FFB2D053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = seti_header.cpp; path = client/seti_header.cpp; refType = 4; }; AA3FFB2E053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = seti_header.h; path = client/seti_header.h; refType = 4; }; AA3FFB2F053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = seti.cpp; path = client/seti.cpp; refType = 4; }; AA3FFB30053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = seti.h; path = client/seti.h; refType = 4; }; AA3FFB31053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = spike.cpp; path = client/spike.cpp; refType = 4; }; AA3FFB32053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = spike.h; path = client/spike.h; refType = 4; }; AA3FFB33053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = timecvt.cpp; path = client/timecvt.cpp; refType = 4; }; AA3FFB34053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = timecvt.h; path = client/timecvt.h; refType = 4; }; AA3FFB35053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = version.cpp; path = client/version.cpp; refType = 4; }; AA3FFB36053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = version.h; path = client/version.h; refType = 4; }; AA3FFB37053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = worker.cpp; path = client/worker.cpp; refType = 4; }; AA3FFB38053BC3EB00164350 = { fileEncoding = 30; isa = PBXFileReference; name = worker.h; path = client/worker.h; refType = 4; }; AA3FFB39053BC3EB00164350 = { fileRef = AA3FFB0F053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB3A053BC3EB00164350 = { fileRef = AA3FFB10053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB3B053BC3EB00164350 = { fileRef = AA3FFB11053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB3C053BC3EB00164350 = { fileRef = AA3FFB12053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB3D053BC3EB00164350 = { fileRef = AA3FFB13053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB3E053BC3EB00164350 = { fileRef = AA3FFB14053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB3F053BC3EB00164350 = { fileRef = AA3FFB15053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB40053BC3EB00164350 = { fileRef = AA3FFB16053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB41053BC3EB00164350 = { fileRef = AA3FFB17053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB42053BC3EB00164350 = { fileRef = AA3FFB18053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB43053BC3EB00164350 = { fileRef = AA3FFB19053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB44053BC3EB00164350 = { fileRef = AA3FFB1A053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB45053BC3EB00164350 = { fileRef = AA3FFB1B053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB46053BC3EB00164350 = { fileRef = AA3FFB1C053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB47053BC3EB00164350 = { fileRef = AA3FFB1D053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB48053BC3EB00164350 = { fileRef = AA3FFB1E053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB4A053BC3EB00164350 = { fileRef = AA3FFB20053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB4B053BC3EB00164350 = { fileRef = AA3FFB21053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB4C053BC3EB00164350 = { fileRef = AA3FFB22053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB4D053BC3EB00164350 = { fileRef = AA3FFB23053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB4E053BC3EB00164350 = { fileRef = AA3FFB24053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB4F053BC3EB00164350 = { fileRef = AA3FFB25053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB50053BC3EB00164350 = { fileRef = AA3FFB26053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB51053BC3EB00164350 = { fileRef = AA3FFB27053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB52053BC3EB00164350 = { fileRef = AA3FFB28053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB53053BC3EB00164350 = { fileRef = AA3FFB29053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB54053BC3EB00164350 = { fileRef = AA3FFB2A053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB55053BC3EB00164350 = { fileRef = AA3FFB2B053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB56053BC3EB00164350 = { fileRef = AA3FFB2C053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB57053BC3EB00164350 = { fileRef = AA3FFB2D053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB58053BC3EB00164350 = { fileRef = AA3FFB2E053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB59053BC3EB00164350 = { fileRef = AA3FFB2F053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB5A053BC3EB00164350 = { fileRef = AA3FFB30053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB5B053BC3EB00164350 = { fileRef = AA3FFB31053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB5C053BC3EB00164350 = { fileRef = AA3FFB32053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB5D053BC3EB00164350 = { fileRef = AA3FFB33053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB5E053BC3EB00164350 = { fileRef = AA3FFB34053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB5F053BC3EB00164350 = { fileRef = AA3FFB35053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB60053BC3EB00164350 = { fileRef = AA3FFB36053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB61053BC3EB00164350 = { fileRef = AA3FFB37053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB62053BC3EB00164350 = { fileRef = AA3FFB38053BC3EB00164350; isa = PBXBuildFile; settings = { }; }; AA3FFB63053BC42600164350 = { fileEncoding = 30; isa = PBXFileReference; name = mac_app_opengl.C; path = ../boinc/api/mac_app_opengl.C; refType = 4; }; AA3FFB64053BC42600164350 = { fileEncoding = 30; isa = PBXFileReference; name = mac_carbon_gl.C; path = ../boinc/api/mac_carbon_gl.C; refType = 4; }; AA3FFB65053BC42600164350 = { fileRef = AA3FFB63053BC42600164350; isa = PBXBuildFile; settings = { }; }; AA3FFB66053BC42600164350 = { fileRef = AA3FFB64053BC42600164350; isa = PBXBuildFile; settings = { }; }; AA3FFB69053BC4DA00164350 = { fileEncoding = 30; isa = PBXFileReference; name = config.h; path = ../boinc/config.h; refType = 4; }; AA3FFB6A053BC4DA00164350 = { fileRef = AA3FFB69053BC4DA00164350; isa = PBXBuildFile; settings = { }; }; AA3FFBF2053BC99600164350 = { fileEncoding = 30; isa = PBXFileReference; name = app_ipc.C; path = ../boinc/lib/app_ipc.C; refType = 4; }; AA3FFBF3053BC99600164350 = { fileEncoding = 30; isa = PBXFileReference; name = app_ipc.h; path = ../boinc/lib/app_ipc.h; refType = 4; }; AA3FFBF4053BC99600164350 = { fileRef = AA3FFBF2053BC99600164350; isa = PBXBuildFile; settings = { }; }; AA3FFBF5053BC99600164350 = { fileRef = AA3FFBF3053BC99600164350; isa = PBXBuildFile; settings = { }; }; AA3FFBF8053BCAAD00164350 = { fileEncoding = 30; isa = PBXFileReference; name = xml_util.C; path = ../boinc/lib/xml_util.C; refType = 4; }; AA3FFBF9053BCAAD00164350 = { fileEncoding = 30; isa = PBXFileReference; name = xml_util.h; path = ../boinc/lib/xml_util.h; refType = 4; }; AA3FFBFA053BCAAD00164350 = { fileRef = AA3FFBF8053BCAAD00164350; isa = PBXBuildFile; settings = { }; }; AA3FFBFB053BCAAD00164350 = { fileRef = AA3FFBF9053BCAAD00164350; isa = PBXBuildFile; settings = { }; }; AA3FFBFC053BCAF200164350 = { fileEncoding = 30; isa = PBXFileReference; name = schema_master.cpp; path = db/schema_master.cpp; refType = 4; }; AA3FFBFD053BCAF200164350 = { fileEncoding = 30; isa = PBXFileReference; name = schema_master.h; path = db/schema_master.h; refType = 4; }; AA3FFBFE053BCAF200164350 = { fileRef = AA3FFBFC053BCAF200164350; isa = PBXBuildFile; settings = { }; }; AA3FFBFF053BCAF200164350 = { fileRef = AA3FFBFD053BCAF200164350; isa = PBXBuildFile; settings = { }; }; AA3FFC00053BCCC700164350 = { children = ( AA3FFC01053BCCE100164350, AA3FFC02053BCCE100164350, AA3FFC03053BCCE100164350, AA3FFC04053BCCE100164350, AA3FFC05053BCCE100164350, AA3FFC06053BCCE100164350, AA3FFC07053BCCE100164350, AA3FFC08053BCCE100164350, AA3FFC09053BCCE100164350, AA3FFC0A053BCCE100164350, AA3FFC0B053BCCE100164350, AA3FFC0C053BCCE100164350, AA3FFC0D053BCCE100164350, AA3FFC0E053BCCE100164350, AA3FFC0F053BCCE100164350, AA3FFC10053BCCE100164350, AA3FFC11053BCCE100164350, AA3FFC12053BCCE100164350, AA3FFC13053BCCE100164350, AA3FFC14053BCCE100164350, AA3FFC15053BCCE100164350, AA3FFC16053BCCE100164350, AA3FFC17053BCCE100164350, AA3FFC18053BCCE100164350, AA3FFC19053BCCE100164350, AA3FFC1A053BCCE100164350, AA3FFC1B053BCCE100164350, AA3FFC1C053BCCE100164350, AA3FFC1D053BCCE100164350, AA3FFC1E053BCCE100164350, AA3FFC1F053BCCE100164350, AA3FFC20053BCCE100164350, AA3FFC21053BCCE100164350, AA3FFC22053BCCE100164350, AA3FFC23053BCCE100164350, AA3FFC24053BCCE100164350, AA3FFC25053BCCE100164350, AA3FFC26053BCCE100164350, AA3FFC27053BCCE100164350, AA3FFC28053BCCE100164350, AA3FFC29053BCCE100164350, AA3FFC2A053BCCE100164350, AA3FFC2B053BCCE100164350, AA3FFC2C053BCCE100164350, AA3FFC2D053BCCE100164350, AA3FFC2E053BCCE100164350, AA3FFC2F053BCCE100164350, AA3FFC30053BCCE200164350, AA3FFC31053BCCE200164350, AA3FFC32053BCCE200164350, AA3FFC33053BCCE200164350, AA3FFC34053BCCE200164350, AA3FFC35053BCCE200164350, AA3FFC36053BCCE200164350, AA3FFC37053BCCE200164350, AA3FFC38053BCCE200164350, AA3FFC39053BCCE200164350, AA3FFC3A053BCCE200164350, AA3FFC3B053BCCE200164350, AA3FFC3C053BCCE200164350, AA3FFC3D053BCCE200164350, AA3FFC3E053BCCE200164350, AA3FFC3F053BCCE200164350, AA3FFC40053BCCE200164350, AA3FFC41053BCCE200164350, AA3FFC42053BCCE200164350, ); isa = PBXGroup; name = JPEGLib; refType = 4; }; AA3FFC01053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = cderror.h; path = ../boinc/jpeglib/cderror.h; refType = 4; }; AA3FFC02053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = cdjpeg.h; path = ../boinc/jpeglib/cdjpeg.h; refType = 4; }; AA3FFC03053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jcapimin.c; path = ../boinc/jpeglib/jcapimin.c; refType = 4; }; AA3FFC04053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jcapistd.c; path = ../boinc/jpeglib/jcapistd.c; refType = 4; }; AA3FFC05053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jccoefct.c; path = ../boinc/jpeglib/jccoefct.c; refType = 4; }; AA3FFC06053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jccolor.c; path = ../boinc/jpeglib/jccolor.c; refType = 4; }; AA3FFC07053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jcdctmgr.c; path = ../boinc/jpeglib/jcdctmgr.c; refType = 4; }; AA3FFC08053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jchuff.c; path = ../boinc/jpeglib/jchuff.c; refType = 4; }; AA3FFC09053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jchuff.h; path = ../boinc/jpeglib/jchuff.h; refType = 4; }; AA3FFC0A053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jcinit.c; path = ../boinc/jpeglib/jcinit.c; refType = 4; }; AA3FFC0B053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jcmainct.c; path = ../boinc/jpeglib/jcmainct.c; refType = 4; }; AA3FFC0C053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jcmarker.c; path = ../boinc/jpeglib/jcmarker.c; refType = 4; }; AA3FFC0D053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jcmaster.c; path = ../boinc/jpeglib/jcmaster.c; refType = 4; }; AA3FFC0E053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jcomapi.c; path = ../boinc/jpeglib/jcomapi.c; refType = 4; }; AA3FFC0F053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jconfig.h; path = ../boinc/jpeglib/jconfig.h; refType = 4; }; AA3FFC10053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jcparam.c; path = ../boinc/jpeglib/jcparam.c; refType = 4; }; AA3FFC11053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jcphuff.c; path = ../boinc/jpeglib/jcphuff.c; refType = 4; }; AA3FFC12053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jcprepct.c; path = ../boinc/jpeglib/jcprepct.c; refType = 4; }; AA3FFC13053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jcsample.c; path = ../boinc/jpeglib/jcsample.c; refType = 4; }; AA3FFC14053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jctrans.c; path = ../boinc/jpeglib/jctrans.c; refType = 4; }; AA3FFC15053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jdapimin.c; path = ../boinc/jpeglib/jdapimin.c; refType = 4; }; AA3FFC16053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jdapistd.c; path = ../boinc/jpeglib/jdapistd.c; refType = 4; }; AA3FFC17053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jdatadst.c; path = ../boinc/jpeglib/jdatadst.c; refType = 4; }; AA3FFC18053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jdatasrc.c; path = ../boinc/jpeglib/jdatasrc.c; refType = 4; }; AA3FFC19053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jdcoefct.c; path = ../boinc/jpeglib/jdcoefct.c; refType = 4; }; AA3FFC1A053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jdcolor.c; path = ../boinc/jpeglib/jdcolor.c; refType = 4; }; AA3FFC1B053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jdct.h; path = ../boinc/jpeglib/jdct.h; refType = 4; }; AA3FFC1C053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jddctmgr.c; path = ../boinc/jpeglib/jddctmgr.c; refType = 4; }; AA3FFC1D053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jdhuff.c; path = ../boinc/jpeglib/jdhuff.c; refType = 4; }; AA3FFC1E053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jdhuff.h; path = ../boinc/jpeglib/jdhuff.h; refType = 4; }; AA3FFC1F053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jdinput.c; path = ../boinc/jpeglib/jdinput.c; refType = 4; }; AA3FFC20053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jdmainct.c; path = ../boinc/jpeglib/jdmainct.c; refType = 4; }; AA3FFC21053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jdmarker.c; path = ../boinc/jpeglib/jdmarker.c; refType = 4; }; AA3FFC22053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jdmaster.c; path = ../boinc/jpeglib/jdmaster.c; refType = 4; }; AA3FFC23053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jdmerge.c; path = ../boinc/jpeglib/jdmerge.c; refType = 4; }; AA3FFC24053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jdphuff.c; path = ../boinc/jpeglib/jdphuff.c; refType = 4; }; AA3FFC25053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jdpostct.c; path = ../boinc/jpeglib/jdpostct.c; refType = 4; }; AA3FFC26053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jdsample.c; path = ../boinc/jpeglib/jdsample.c; refType = 4; }; AA3FFC27053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jdtrans.c; path = ../boinc/jpeglib/jdtrans.c; refType = 4; }; AA3FFC28053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jerror.c; path = ../boinc/jpeglib/jerror.c; refType = 4; }; AA3FFC29053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jerror.h; path = ../boinc/jpeglib/jerror.h; refType = 4; }; AA3FFC2A053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jfdctflt.c; path = ../boinc/jpeglib/jfdctflt.c; refType = 4; }; AA3FFC2B053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jfdctfst.c; path = ../boinc/jpeglib/jfdctfst.c; refType = 4; }; AA3FFC2C053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jfdctint.c; path = ../boinc/jpeglib/jfdctint.c; refType = 4; }; AA3FFC2D053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jidctflt.c; path = ../boinc/jpeglib/jidctflt.c; refType = 4; }; AA3FFC2E053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jidctfst.c; path = ../boinc/jpeglib/jidctfst.c; refType = 4; }; AA3FFC2F053BCCE100164350 = { fileEncoding = 30; isa = PBXFileReference; name = jidctint.c; path = ../boinc/jpeglib/jidctint.c; refType = 4; }; AA3FFC30053BCCE200164350 = { fileEncoding = 30; isa = PBXFileReference; name = jidctred.c; path = ../boinc/jpeglib/jidctred.c; refType = 4; }; AA3FFC31053BCCE200164350 = { fileEncoding = 30; isa = PBXFileReference; name = jinclude.h; path = ../boinc/jpeglib/jinclude.h; refType = 4; }; AA3FFC32053BCCE200164350 = { fileEncoding = 30; isa = PBXFileReference; name = jmemmgr.c; path = ../boinc/jpeglib/jmemmgr.c; refType = 4; }; AA3FFC33053BCCE200164350 = { fileEncoding = 30; isa = PBXFileReference; name = jmemnobs.c; path = ../boinc/jpeglib/jmemnobs.c; refType = 4; }; AA3FFC34053BCCE200164350 = { fileEncoding = 30; isa = PBXFileReference; name = jmemsys.h; path = ../boinc/jpeglib/jmemsys.h; refType = 4; }; AA3FFC35053BCCE200164350 = { fileEncoding = 30; isa = PBXFileReference; name = jmorecfg.h; path = ../boinc/jpeglib/jmorecfg.h; refType = 4; }; AA3FFC36053BCCE200164350 = { fileEncoding = 30; isa = PBXFileReference; name = jpegint.h; path = ../boinc/jpeglib/jpegint.h; refType = 4; }; AA3FFC37053BCCE200164350 = { fileEncoding = 30; isa = PBXFileReference; name = jpeglib.h; path = ../boinc/jpeglib/jpeglib.h; refType = 4; }; AA3FFC38053BCCE200164350 = { fileEncoding = 30; isa = PBXFileReference; name = jquant1.c; path = ../boinc/jpeglib/jquant1.c; refType = 4; }; AA3FFC39053BCCE200164350 = { fileEncoding = 30; isa = PBXFileReference; name = jquant2.c; path = ../boinc/jpeglib/jquant2.c; refType = 4; }; AA3FFC3A053BCCE200164350 = { fileEncoding = 30; isa = PBXFileReference; name = jutils.c; path = ../boinc/jpeglib/jutils.c; refType = 4; }; AA3FFC3B053BCCE200164350 = { fileEncoding = 30; isa = PBXFileReference; name = jversion.h; path = ../boinc/jpeglib/jversion.h; refType = 4; }; AA3FFC3C053BCCE200164350 = { fileEncoding = 30; isa = PBXFileReference; name = rdbmp.c; path = ../boinc/jpeglib/rdbmp.c; refType = 4; }; AA3FFC3D053BCCE200164350 = { fileEncoding = 30; isa = PBXFileReference; name = rdcolmap.c; path = ../boinc/jpeglib/rdcolmap.c; refType = 4; }; AA3FFC3E053BCCE200164350 = { fileEncoding = 30; isa = PBXFileReference; name = rdgif.c; path = ../boinc/jpeglib/rdgif.c; refType = 4; }; AA3FFC3F053BCCE200164350 = { fileEncoding = 30; isa = PBXFileReference; name = rdppm.c; path = ../boinc/jpeglib/rdppm.c; refType = 4; }; AA3FFC40053BCCE200164350 = { fileEncoding = 30; isa = PBXFileReference; name = rdrle.c; path = ../boinc/jpeglib/rdrle.c; refType = 4; }; AA3FFC41053BCCE200164350 = { fileEncoding = 30; isa = PBXFileReference; name = rdswitch.c; path = ../boinc/jpeglib/rdswitch.c; refType = 4; }; AA3FFC42053BCCE200164350 = { fileEncoding = 30; isa = PBXFileReference; name = rdtarga.c; path = ../boinc/jpeglib/rdtarga.c; refType = 4; }; AA3FFC43053BCCE200164350 = { fileRef = AA3FFC01053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC44053BCCE200164350 = { fileRef = AA3FFC02053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC45053BCCE200164350 = { fileRef = AA3FFC03053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC46053BCCE200164350 = { fileRef = AA3FFC04053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC47053BCCE200164350 = { fileRef = AA3FFC05053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC48053BCCE200164350 = { fileRef = AA3FFC06053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC49053BCCE200164350 = { fileRef = AA3FFC07053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC4A053BCCE200164350 = { fileRef = AA3FFC08053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC4B053BCCE200164350 = { fileRef = AA3FFC09053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC4C053BCCE200164350 = { fileRef = AA3FFC0A053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC4D053BCCE200164350 = { fileRef = AA3FFC0B053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC4E053BCCE200164350 = { fileRef = AA3FFC0C053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC4F053BCCE200164350 = { fileRef = AA3FFC0D053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC50053BCCE200164350 = { fileRef = AA3FFC0E053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC51053BCCE200164350 = { fileRef = AA3FFC0F053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC52053BCCE200164350 = { fileRef = AA3FFC10053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC53053BCCE200164350 = { fileRef = AA3FFC11053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC54053BCCE200164350 = { fileRef = AA3FFC12053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC55053BCCE200164350 = { fileRef = AA3FFC13053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC56053BCCE200164350 = { fileRef = AA3FFC14053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC57053BCCE200164350 = { fileRef = AA3FFC15053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC58053BCCE200164350 = { fileRef = AA3FFC16053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC59053BCCE200164350 = { fileRef = AA3FFC17053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC5A053BCCE200164350 = { fileRef = AA3FFC18053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC5B053BCCE200164350 = { fileRef = AA3FFC19053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC5C053BCCE200164350 = { fileRef = AA3FFC1A053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC5D053BCCE200164350 = { fileRef = AA3FFC1B053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC5E053BCCE200164350 = { fileRef = AA3FFC1C053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC5F053BCCE200164350 = { fileRef = AA3FFC1D053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC60053BCCE200164350 = { fileRef = AA3FFC1E053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC61053BCCE200164350 = { fileRef = AA3FFC1F053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC62053BCCE200164350 = { fileRef = AA3FFC20053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC63053BCCE200164350 = { fileRef = AA3FFC21053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC64053BCCE200164350 = { fileRef = AA3FFC22053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC65053BCCE200164350 = { fileRef = AA3FFC23053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC66053BCCE200164350 = { fileRef = AA3FFC24053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC67053BCCE200164350 = { fileRef = AA3FFC25053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC68053BCCE200164350 = { fileRef = AA3FFC26053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC69053BCCE200164350 = { fileRef = AA3FFC27053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC6A053BCCE200164350 = { fileRef = AA3FFC28053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC6B053BCCE200164350 = { fileRef = AA3FFC29053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC6C053BCCE200164350 = { fileRef = AA3FFC2A053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC6D053BCCE200164350 = { fileRef = AA3FFC2B053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC6E053BCCE200164350 = { fileRef = AA3FFC2C053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC6F053BCCE200164350 = { fileRef = AA3FFC2D053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC70053BCCE200164350 = { fileRef = AA3FFC2E053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC71053BCCE200164350 = { fileRef = AA3FFC2F053BCCE100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC72053BCCE200164350 = { fileRef = AA3FFC30053BCCE200164350; isa = PBXBuildFile; settings = { }; }; AA3FFC73053BCCE200164350 = { fileRef = AA3FFC31053BCCE200164350; isa = PBXBuildFile; settings = { }; }; AA3FFC74053BCCE200164350 = { fileRef = AA3FFC32053BCCE200164350; isa = PBXBuildFile; settings = { }; }; AA3FFC75053BCCE200164350 = { fileRef = AA3FFC33053BCCE200164350; isa = PBXBuildFile; settings = { }; }; AA3FFC76053BCCE200164350 = { fileRef = AA3FFC34053BCCE200164350; isa = PBXBuildFile; settings = { }; }; AA3FFC77053BCCE200164350 = { fileRef = AA3FFC35053BCCE200164350; isa = PBXBuildFile; settings = { }; }; AA3FFC78053BCCE200164350 = { fileRef = AA3FFC36053BCCE200164350; isa = PBXBuildFile; settings = { }; }; AA3FFC79053BCCE200164350 = { fileRef = AA3FFC37053BCCE200164350; isa = PBXBuildFile; settings = { }; }; AA3FFC7A053BCCE200164350 = { fileRef = AA3FFC38053BCCE200164350; isa = PBXBuildFile; settings = { }; }; AA3FFC7B053BCCE200164350 = { fileRef = AA3FFC39053BCCE200164350; isa = PBXBuildFile; settings = { }; }; AA3FFC7C053BCCE200164350 = { fileRef = AA3FFC3A053BCCE200164350; isa = PBXBuildFile; settings = { }; }; AA3FFC7D053BCCE200164350 = { fileRef = AA3FFC3B053BCCE200164350; isa = PBXBuildFile; settings = { }; }; AA3FFC7E053BCCE200164350 = { fileRef = AA3FFC3C053BCCE200164350; isa = PBXBuildFile; settings = { }; }; AA3FFC7F053BCCE200164350 = { fileRef = AA3FFC3D053BCCE200164350; isa = PBXBuildFile; settings = { }; }; AA3FFC80053BCCE200164350 = { fileRef = AA3FFC3E053BCCE200164350; isa = PBXBuildFile; settings = { }; }; AA3FFC81053BCCE200164350 = { fileRef = AA3FFC3F053BCCE200164350; isa = PBXBuildFile; settings = { }; }; AA3FFC82053BCCE200164350 = { fileRef = AA3FFC40053BCCE200164350; isa = PBXBuildFile; settings = { }; }; AA3FFC83053BCCE200164350 = { fileRef = AA3FFC41053BCCE200164350; isa = PBXBuildFile; settings = { }; }; AA3FFC84053BCCE200164350 = { fileRef = AA3FFC42053BCCE200164350; isa = PBXBuildFile; settings = { }; }; AA3FFC85053BCDAD00164350 = { fileEncoding = 30; isa = PBXFileReference; name = sqlint8.h; path = db/sqlint8.h; refType = 4; }; AA3FFC86053BCDAD00164350 = { fileRef = AA3FFC85053BCDAD00164350; isa = PBXBuildFile; settings = { }; }; AA3FFC87053BD34A00164350 = { fileEncoding = 30; isa = PBXFileReference; name = sqlblob.cpp; path = db/sqlblob.cpp; refType = 4; }; AA3FFC88053BD34A00164350 = { fileEncoding = 30; isa = PBXFileReference; name = sqlblob.h; path = db/sqlblob.h; refType = 4; }; AA3FFC89053BD34A00164350 = { fileRef = AA3FFC87053BD34A00164350; isa = PBXBuildFile; settings = { }; }; AA3FFC8A053BD34A00164350 = { fileRef = AA3FFC88053BD34A00164350; isa = PBXBuildFile; settings = { }; }; AA3FFC8B053BDE9100164350 = { fileEncoding = 30; isa = PBXFileReference; name = sqlrow.cpp; path = db/sqlrow.cpp; refType = 4; }; AA3FFC8C053BDE9100164350 = { fileEncoding = 30; isa = PBXFileReference; name = sqlrow.h; path = db/sqlrow.h; refType = 4; }; AA3FFC8D053BDE9100164350 = { fileRef = AA3FFC8B053BDE9100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC8E053BDE9100164350 = { fileRef = AA3FFC8C053BDE9100164350; isa = PBXBuildFile; settings = { }; }; AA3FFC8F053BDEC000164350 = { children = ( AA3FFBFC053BCAF200164350, AA3FFBFD053BCAF200164350, AA3FFC85053BCDAD00164350, AA3FFC87053BD34A00164350, AA3FFC88053BD34A00164350, AA3FFC8B053BDE9100164350, AA3FFC8C053BDE9100164350, ); isa = PBXGroup; name = DB; refType = 4; }; AA6AA8B10410C34000A80164 = { fileRef = AA763A950400775C00A80164; isa = PBXBuildFile; settings = { }; }; AA6AA8C60410C8B300A80164 = { isa = PBXFrameworkReference; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; refType = 0; }; AA6AA8C70410C8B300A80164 = { fileRef = AA6AA8C60410C8B300A80164; isa = PBXBuildFile; settings = { }; }; AA6AA8C804113B7B00A80164 = { children = ( AA3FFB0F053BC3EB00164350, AA3FFB10053BC3EB00164350, AA3FFB11053BC3EB00164350, AA3FFB12053BC3EB00164350, AA3FFB13053BC3EB00164350, AA3FFB14053BC3EB00164350, AA3FFB15053BC3EB00164350, AA3FFB16053BC3EB00164350, AA3FFB17053BC3EB00164350, AA3FFB18053BC3EB00164350, AA3FFB19053BC3EB00164350, AA3FFB1A053BC3EB00164350, AA3FFB1B053BC3EB00164350, AA3FFB1C053BC3EB00164350, AA3FFB1D053BC3EB00164350, AA3FFB1E053BC3EB00164350, AA3FFB20053BC3EB00164350, AA3FFB21053BC3EB00164350, AA3FFB22053BC3EB00164350, AA3FFB23053BC3EB00164350, AA3FFB24053BC3EB00164350, AA3FFB25053BC3EB00164350, AA3FFB26053BC3EB00164350, AA3FFB27053BC3EB00164350, AA3FFB28053BC3EB00164350, AA3FFB29053BC3EB00164350, AA3FFB2A053BC3EB00164350, AA3FFB2B053BC3EB00164350, AA3FFB2C053BC3EB00164350, AA3FFB2D053BC3EB00164350, AA3FFB2E053BC3EB00164350, AA3FFB2F053BC3EB00164350, AA3FFB30053BC3EB00164350, AA3FFB31053BC3EB00164350, AA3FFB32053BC3EB00164350, AA3FFB33053BC3EB00164350, AA3FFB34053BC3EB00164350, AA3FFB35053BC3EB00164350, AA3FFB36053BC3EB00164350, AA3FFB37053BC3EB00164350, AA3FFB38053BC3EB00164350, ); isa = PBXGroup; name = "SETI@home"; refType = 4; }; AA763A910400775C00A80164 = { fileEncoding = 30; isa = PBXFileReference; name = gutil.h; path = ../boinc/api/gutil.h; refType = 2; }; AA763A930400775C00A80164 = { fileEncoding = 30; isa = PBXFileReference; name = graphics_data.h; path = ../boinc/api/graphics_data.h; refType = 2; }; AA763A940400775C00A80164 = { fileEncoding = 30; isa = PBXFileReference; name = graphics_data.C; path = ../boinc/api/graphics_data.C; refType = 2; }; AA763A950400775C00A80164 = { fileEncoding = 30; isa = PBXFileReference; name = reduce.h; path = ../boinc/api/reduce.h; refType = 2; }; AA763A970400775C00A80164 = { fileEncoding = 30; isa = PBXFileReference; name = mac_carbon_gl.h; path = ../boinc/api/mac_carbon_gl.h; refType = 2; }; AA763A9B0400775C00A80164 = { fileEncoding = 30; isa = PBXFileReference; name = mac_app_opengl.h; path = ../boinc/api/mac_app_opengl.h; refType = 2; }; AA763A9C0400775C00A80164 = { fileEncoding = 30; isa = PBXFileReference; name = graphics_api.h; path = ../boinc/api/graphics_api.h; refType = 2; }; AA763A9D0400775C00A80164 = { fileEncoding = 30; isa = PBXFileReference; name = boinc_api.h; path = ../boinc/api/boinc_api.h; refType = 2; }; AA763A9E0400775C00A80164 = { fileEncoding = 30; isa = PBXFileReference; name = graphics_api.C; path = ../boinc/api/graphics_api.C; refType = 2; }; AA763A9F0400775C00A80164 = { fileEncoding = 30; isa = PBXFileReference; name = boinc_api.C; path = ../boinc/api/boinc_api.C; refType = 2; }; AA763AAC0400775C00A80164 = { fileRef = AA763A9C0400775C00A80164; isa = PBXBuildFile; settings = { }; }; AA763AAD0400775C00A80164 = { fileRef = AA763A9D0400775C00A80164; isa = PBXBuildFile; settings = { }; }; AA763AAE0400775C00A80164 = { fileRef = AA763A9E0400775C00A80164; isa = PBXBuildFile; settings = { }; }; AA763AAF0400775C00A80164 = { fileRef = AA763A9F0400775C00A80164; isa = PBXBuildFile; settings = { }; }; AA763AB00400777000A80164 = { fileEncoding = 30; isa = PBXFileReference; name = filesys.h; path = ../boinc/lib/filesys.h; refType = 2; }; AA763AB10400777000A80164 = { fileEncoding = 30; isa = PBXFileReference; name = util.h; path = ../boinc/lib/util.h; refType = 2; }; AA763AB20400777000A80164 = { fileEncoding = 30; isa = PBXFileReference; name = filesys.C; path = ../boinc/lib/filesys.C; refType = 2; }; AA763AB30400777000A80164 = { fileEncoding = 30; isa = PBXFileReference; name = util.C; path = ../boinc/lib/util.C; refType = 2; }; AA763AB40400777000A80164 = { fileRef = AA763AB00400777000A80164; isa = PBXBuildFile; settings = { }; }; AA763AB50400777000A80164 = { fileRef = AA763AB10400777000A80164; isa = PBXBuildFile; settings = { }; }; AA763AB60400777000A80164 = { fileRef = AA763AB20400777000A80164; isa = PBXBuildFile; settings = { }; }; AA763AB70400777000A80164 = { fileRef = AA763AB30400777000A80164; isa = PBXBuildFile; settings = { }; }; AA763B590400789200A80164 = { isa = PBXFrameworkReference; name = AGL.framework; path = /System/Library/Frameworks/AGL.framework; refType = 0; }; AA763B5A0400789200A80164 = { fileRef = AA763B590400789200A80164; isa = PBXBuildFile; settings = { }; }; AA763B5B040078AC00A80164 = { isa = PBXFrameworkReference; name = DrawSprocket.framework; path = /System/Library/Frameworks/DrawSprocket.framework; refType = 0; }; AA763B5C040078AC00A80164 = { isa = PBXFrameworkReference; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; refType = 0; }; AA763B5E040078AC00A80164 = { fileRef = AA763B5C040078AC00A80164; isa = PBXBuildFile; settings = { }; }; AA763B6104007BB800A80164 = { isa = PBXFrameworkReference; name = GLUT.framework; path = /System/Library/Frameworks/GLUT.framework; refType = 0; }; AA763B6304007BD100A80164 = { fileRef = AA763B6104007BB800A80164; isa = PBXBuildFile; settings = { }; }; AA763B8904007C2F00A80164 = { fileRef = 20286C33FDCF999611CA2CEA; isa = PBXBuildFile; settings = { }; }; AA763B8A04007C8A00A80164 = { fileRef = AA763B5B040078AC00A80164; isa = PBXBuildFile; settings = { }; }; AABC80520410BC6E00A80164 = { fileEncoding = 30; isa = PBXFileReference; name = mfile.C; path = ../boinc/api/mfile.C; refType = 2; }; AABC80530410BC6E00A80164 = { fileRef = AABC80520410BC6E00A80164; isa = PBXBuildFile; settings = { }; }; AABC80540410BCCF00A80164 = { fileEncoding = 30; isa = PBXFileReference; name = parse.C; path = ../boinc/lib/parse.C; refType = 2; }; AABC80550410BCCF00A80164 = { fileEncoding = 30; isa = PBXFileReference; name = parse.h; path = ../boinc/lib/parse.h; refType = 2; }; AABC80560410BCCF00A80164 = { fileRef = AABC80540410BCCF00A80164; isa = PBXBuildFile; settings = { }; }; AABC80570410BCCF00A80164 = { fileRef = AABC80550410BCCF00A80164; isa = PBXBuildFile; settings = { }; }; AABC806A0410BD2600A80164 = { fileRef = AA763A970400775C00A80164; isa = PBXBuildFile; settings = { }; }; AABC806E0410BD2800A80164 = { fileRef = AA763A9B0400775C00A80164; isa = PBXBuildFile; settings = { }; }; AABC80720410BEED00A80164 = { fileRef = AA763A940400775C00A80164; isa = PBXBuildFile; settings = { }; }; AABC80730410BEEE00A80164 = { fileRef = AA763A930400775C00A80164; isa = PBXBuildFile; settings = { }; }; AABC80790410C06700A80164 = { fileRef = AA763A910400775C00A80164; isa = PBXBuildFile; settings = { }; }; AADBC6EE04226C0F00A80164 = { fileEncoding = 30; isa = PBXFileReference; name = shmem.C; path = ../boinc/lib/shmem.C; refType = 4; }; AADBC6EF04226C0F00A80164 = { fileEncoding = 30; isa = PBXFileReference; name = shmem.h; path = ../boinc/lib/shmem.h; refType = 4; }; AADBC6F004226C0F00A80164 = { fileRef = AADBC6EE04226C0F00A80164; isa = PBXBuildFile; settings = { }; }; AADBC6F104226C0F00A80164 = { fileRef = AADBC6EF04226C0F00A80164; isa = PBXBuildFile; settings = { }; }; }; rootObject = 20286C28FDCF999611CA2CEA; } boinc-app-seti_8.00~svn3701.orig/COPYING0000644000175000017500000004311011531243074017544 0ustar locutuslocutus GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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 Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. boinc-app-seti_8.00~svn3701.orig/splitter_fft/0000755000175000017500000000000013155506304021221 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/splitter_fft/mb_message.cpp0000644000175000017500000000351312111524644024027 0ustar locutuslocutus/* * 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 #include #include #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 * */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/splitparms.h0000644000175000017500000000746312111524644023600 0ustar locutuslocutus/* 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 #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 2048 #define IFFT_LEN 8 #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 * */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/tools/0000755000175000017500000000000013155506304022361 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/splitter_fft/tools/disksplitter0000755000175000017500000001055312111524644025032 0ustar locutuslocutus#! /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/informix/bin:/usr/local/tex # 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@ssl.berkeley.edu mattl@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 boinc-app-seti_8.00~svn3701.orig/splitter_fft/tools/sah_splitter.sh0000755000175000017500000001141112111524644025415 0ustar locutuslocutus#! /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/bin:/usr/local/tex 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@ssl.berkeley.edu jeffc@ssl.berkeley.edu mattl@ssl.berkeley.edu davea@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 boinc-app-seti_8.00~svn3701.orig/splitter_fft/db_fns.h0000644000175000017500000000202612111524644022623 0ustar locutuslocutus/* * $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 * * */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/splittypes.h0000644000175000017500000000520712111524644023614 0ustar locutuslocutus/* 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 #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 * */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/wufiles.h0000644000175000017500000000150412111524644023046 0ustar locutuslocutus/* * * 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 * * */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/mb_splitter.cpp0000644000175000017500000010134712111524644024255 0ustar locutuslocutus/* * * 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 #include #include #include #include #include #include #include #include #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= "\n" " 0\n" "\n" "\n" " \n" " 0\n" " work_unit.sah\n" " \n" "\n"; const char *result_template_filename_id = "result_0.xml"; const char *result_template= "\n" " \n" " \n" " \n" " 65536\n" " http://setiboincdata.ssl.berkeley.edu/sah_cgi/file_upload_handler\n" "\n" "\n" " \n" " \n" " result.sah\n" " \n" "\n"; // END TEMPLATE DEFS -------------------------------------------------- std::vector tapebuffer; std::map coord_history; std::vector 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;i6)) || ((*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 > 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::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\n", state_counts.result_server_state_2); 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 * * */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/mb_splitter.h0000644000175000017500000000746112111524644023724 0ustar locutuslocutus/* * 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 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 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 tapebuffer; extern std::map 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 * * */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/mb_splittypes.h0000644000175000017500000000534512111524644024275 0ustar locutuslocutus/* 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 #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 * */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/mb_angdist.cpp0000644000175000017500000000341012111524644024030 0ustar locutuslocutus/* * 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 #include #include #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 * * */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/fftw.h0000644000175000017500000002762412111524644022351 0ustar locutuslocutus/* 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 #include #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 */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/libfftw.a0000644000175000017500000074454412111524644023040 0ustar locutuslocutus! / 915488408 0 0 0 4748 ` hhLL##))//7p7p==FlFlN\N\^^ffvHvHDD||PPllXX  88,,GG||dd,,((  !!OOSSYhYh^^e|e|l4l4tt||ddddd+++++7x7x>>>>>>>>>>>>>>>>>>>>iiiiiiiir4r4r4r4r4DDDfftw_no_twiddle_1fftw_no_twiddle_1_descfftw_no_twiddle_2fftw_no_twiddle_2_descfftw_no_twiddle_3fftw_no_twiddle_3_descfftw_no_twiddle_4fftw_no_twiddle_4_descfftw_no_twiddle_5fftw_no_twiddle_5_descfftw_no_twiddle_6fftw_no_twiddle_6_descfftw_no_twiddle_7fftw_no_twiddle_7_descfftw_no_twiddle_8fftw_no_twiddle_8_descfftw_no_twiddle_9fftw_no_twiddle_9_descfftw_no_twiddle_10fftw_no_twiddle_10_descfftw_no_twiddle_11fftw_no_twiddle_11_descfftw_no_twiddle_12fftw_no_twiddle_12_descfftw_no_twiddle_13fftw_no_twiddle_13_descfftw_no_twiddle_14fftw_no_twiddle_14_descfftw_no_twiddle_15fftw_no_twiddle_15_descfftw_no_twiddle_16fftw_no_twiddle_16_descfftw_no_twiddle_32fftw_no_twiddle_32_descfftw_no_twiddle_64fftw_no_twiddle_64_descfftw_twiddle_2fftw_twiddle_2_descfftw_twiddle_3fftw_twiddle_3_descfftw_twiddle_4fftw_twiddle_4_descfftw_twiddle_5fftw_twiddle_5_descfftw_twiddle_6fftw_twiddle_6_descfftw_twiddle_7fftw_twiddle_7_descfftw_twiddle_8fftw_twiddle_8_descfftw_twiddle_9fftw_twiddle_9_descfftw_twiddle_10fftw_twiddle_10_descfftw_twiddle_16fftw_twiddle_16_descfftw_twiddle_32fftw_twiddle_32_descfftw_twiddle_64fftw_twiddle_64_descfftwi_no_twiddle_1fftwi_no_twiddle_1_descfftwi_no_twiddle_2fftwi_no_twiddle_2_descfftwi_no_twiddle_3fftwi_no_twiddle_3_descfftwi_no_twiddle_4fftwi_no_twiddle_4_descfftwi_no_twiddle_5fftwi_no_twiddle_5_descfftwi_no_twiddle_6fftwi_no_twiddle_6_descfftwi_no_twiddle_7fftwi_no_twiddle_7_descfftwi_no_twiddle_8fftwi_no_twiddle_8_descfftwi_no_twiddle_9fftwi_no_twiddle_9_descfftwi_no_twiddle_10fftwi_no_twiddle_10_descfftwi_no_twiddle_11fftwi_no_twiddle_11_descfftwi_no_twiddle_12fftwi_no_twiddle_12_descfftwi_no_twiddle_13fftwi_no_twiddle_13_descfftwi_no_twiddle_14fftwi_no_twiddle_14_descfftwi_no_twiddle_15fftwi_no_twiddle_15_descfftwi_no_twiddle_16fftwi_no_twiddle_16_descfftwi_no_twiddle_32fftwi_no_twiddle_32_descfftwi_no_twiddle_64fftwi_no_twiddle_64_descfftwi_twiddle_2fftwi_twiddle_2_descfftwi_twiddle_3fftwi_twiddle_3_descfftwi_twiddle_4fftwi_twiddle_4_descfftwi_twiddle_5fftwi_twiddle_5_descfftwi_twiddle_6fftwi_twiddle_6_descfftwi_twiddle_7fftwi_twiddle_7_descfftwi_twiddle_8fftwi_twiddle_8_descfftwi_twiddle_9fftwi_twiddle_9_descfftwi_twiddle_10fftwi_twiddle_10_descfftwi_twiddle_16fftwi_twiddle_16_descfftwi_twiddle_32fftwi_twiddle_32_descfftwi_twiddle_64fftwi_twiddle_64_descfftw_configfftw_create_plan_specificfftw_create_planfftw_destroy_planfftw_twiddle_sizefftw_create_twiddlefftw_destroy_twiddlefftw_versionfftw_strided_copyfftw_executor_simplefftwfftw_onefftw_twiddle_genericfftwi_twiddle_genericfftwnd_measure_runtimefftwndfftwnd_create_plan_auxfftwnd_new_plan_arrayfftwnd_create_plans_genericfftwnd_work_sizefftwnd_create_plans_specificfftwnd_create_plan_specificfftwnd_destroy_planfftw2d_create_plan_specificfftw3d_create_plan_specificfftwnd_create_planfftw2d_create_planfftw3d_create_planfftwnd_fprint_planfftwnd_print_planfftw_bufferedfftwnd_auxfftwnd_aux_howmanyfftwnd_onefftw_malloc_hookfftw_free_hookfftw_die_hookfftw_mallocfftw_diefftw_freefftw_check_memory_leaksfftw_print_max_memory_usagefftw_wisdom_lookupfftw_wisdom_addfftw_forget_wisdomfftw_export_wisdomfftw_import_wisdomfftw_export_wisdom_to_filefftw_import_wisdom_from_filefftw_export_wisdom_to_stringfftw_import_wisdom_from_stringfftw_node_cntfftw_plan_cntfftw_make_nodefftw_use_nodefftw_make_node_notwfftw_make_node_real2hcfftw_make_node_hc2realfftw_make_node_twiddlefftw_make_node_hc2hcfftw_make_node_genericfftw_make_node_rgenericfftw_rader_topfftw_destroy_plan_internalfftw_make_planfftw_complete_twiddlefftw_use_planfftw_make_empty_tablefftw_insertfftw_lookupfftw_destroy_tablefftw_estimate_nodefftw_pick_betterfftw_factorfftw_fprint_planfftw_print_planfftw_sizeof_fftw_realfftw_twiddle_raderfftwi_twiddle_raderfftw_make_node_raderfn_1.o/ 915488203 571 300 100664 888 ` ELF4( "@ "`fftw_no_twiddle_1GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.data.rela.data.bss.rodata.comment4!H '` 2h7h?zHh  F/ fn_1.cgcc2_compiled.*ABS*fftw_no_twiddle_1fftw_no_twiddle_1_desc fn_2.o/ 915488204 571 300 100664 936 ` ELF4( * Ȣ"*"@ "@   Ȣ"@ ""`!fftw_no_twiddle_2GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.data.rela.data.bss.rodata.comment4D!x ' 27?H  HFD/ fn_2.cgcc2_compiled.*ABS*fftw_no_twiddle_2fftw_no_twiddle_2_desc fn_3.o/ 915488206 571 300 100664 1192 ` ELF|4( ** ( Ȥ)$I")#" #I("@H"**"@"@ @ "`@""`1??]fftw_no_twiddle_3GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4!`0  , 2  =BJ'S4  \"-3E fn_3.cgcc2_compiled.K500000000K866025403*ABS*fftw_no_twiddle_3fftw_no_twiddle_3_desc, 0 @ H  fn_4.o/ 915488207 571 300 100664 1064 ` ELF4( *H"H *"* ("Ȣ "Ȩ(*"@&**@ @H"@ * H)(@ "@"@ " "`Afftw_no_twiddle_4GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.data.rela.data.bss.rodata.comment4! ' 27?*?H  F/ fn_4.cgcc2_compiled.*ABS*fftw_no_twiddle_4fftw_no_twiddle_4_desc fn_5.o/ 915488209 571 300 100664 1512 ` ELFT4( **** # ()"ȣ  "ȩ `$ȥ% "H#I0H $0ȥ",I&# +Ȧ/* /Ȣ,+"I.Ȩ .I-H"*** ("@"@ "@*"@"@"(@@ @"`@ "" "`Q>?y?sxq?fftw_no_twiddle_5GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4t!p`  , 2  =B"JS  r"-8 CIt[ fn_5.cgcc2_compiled.K250000000K587785252K951056516K559016994*ABS*fftw_no_twiddle_5fftw_no_twiddle_5_desc\ d x |      fn_6.o/ 915488210 571 300 100664 1432 ` ELFl4( * (" Ȣ*" * (HH"** HH"& H) "  HH"'1ȧȨ#%#3H$Ȥ$123&2*. $(***. ("@*@"@)@Ȫ"@"@"@ "@ Ȣ@@ " + "`@ ""`a?]?fftw_no_twiddle_6GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4!P0  , 2  =BJS$  \"-3E fn_6.cgcc2_compiled.K866025403K500000000*ABS*fftw_no_twiddle_6fftw_no_twiddle_6_desc     fn_7.o/ 915488212 571 300 100664 1932 ` ELF4( 㿐..(.( ./  =H.;` 4H`ȨI9Ȥ 'H)%(  '"I%9+I#)I'%7%<$Ȣ$I4> #Ȫ 4Ȳ:$Ȧ #H9ȧI$&H9ȴI=$H5  76H" 7I65 ;3 =#"3% =2HI;&I5HI7% ;#3HI3Ȧ6-.5.ȧ((.(6&@#&@.&@.@@&@@Ȣ&@@&@&@$&`@@& '  &&&`q>c܇?f?>&?y?H&fftw_no_twiddle_7GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4!  , 2t  =B*J*?SL  \"-8 CNY_q fn_7.cgcc2_compiled.K222520933K900968867K623489801K433883739K974927912K781831482*ABS*fftw_no_twiddle_7fftw_no_twiddle_7_descP T \ ` |     fn_8.o/ 915488214 571 300 100664 1496 ` ELF4( *H"H "*Ȣ*  ("  *(H"# (HHH$* (H H"ȣ'# 6  Ȣ"(%ȢH"H*3)ȩH1"H&#+ "ȰH &H"* **Ȧ**"@@/@ "@ @&   "* ("`"@Ȣ*" (*"@ "@ "@@H"@ @ @H$  " "@ "@ ?5fftw_no_twiddle_8GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4!  ,8 2  =XBXJrS  TQ"(: fn_8.cgcc2_compiled.K707106781*ABS*fftw_no_twiddle_8fftw_no_twiddle_8_desc, 4  fn_9.o/ 915488215 571 300 100664 2220 ` ELFL4( * ( (<I66  "ȢI8 8*Ȣ# (*$I&H ȹ#H"H#I%H  H$H%7**Ȥ (2&I$* $#=$I"= I& "<;2HH"#&I).!# ȣ$,5- )H!; %3 5$%&HI)&% 9)*"@*$ȧ (("@@I""@@Ȥ  "` 7$* ("@"@7"@"@ 0,.9H'.40%"ȼI%I&%$&Ȥ@@ȱ* "($" * *3"@@"@"@Ȫ @@ "` ?p>D?|\>1?$?D}?]?fftw_no_twiddle_9GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4\!  , 2  =B2JS0  4"-8 CNYdou\ fn_9.cgcc2_compiled.K939692620K342020143K984807753K173648177K642787609K766044443K866025403K500000000*ABS*fftw_no_twiddle_9fftw_no_twiddle_9_desc    |             fn_10.o/ 915488217 571 300 100664 1972 ` ELF4( 㿐.(HH" Ȣ.".' (."(".(Ȣ"%..#'";$5, `"H8` Ȣ"HH"%  HH"+HȫHH(H'"H<#H- 5HH 80I*ȵH"3#6ȢI&Ȫ 6(/ȣ= =$#ȴ/$H/1I):".$I9"H2:."!...( (.@/ 2 '@. .(!&@ȥ.@&@@'&@&@&@&@H7&@&@&@&@"@@@@@ '`' %@&& &`H@#" &&` >??y?sxqfftw_no_twiddle_10GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4<!<`  ,p 2  =B#JS  u #.9 DJ<] fn_10.cgcc2_compiled.K250000000K559016994K587785252K951056516*ABS*fftw_no_twiddle_10fftw_no_twiddle_10_descX \ h l |     fn_11.o/ 915488220 571 300 100664 4132 ` ELF \4( 㼐../  .(`''\'|I'./ '`. 'L\(H'T* 'D'lD' LH.@"@'.'d'I 'ldH  ''+I  '쁠I5 ='I0H>''ԃ /;''!' -'t ''I& '' ('I5'䉠 '' *!'|'t !'l (H|!I-'́ 0'\'dtI/\'TT!,'H &'''''LldH 'I'H(5'<L'<D!'<0'4I '44H&', !',,/'$ H I*ȷ$'$́-I(''' -H!'샠I/HH2'! &'  0܋H'I'I  '􃤈'' *!|'! 5H1'dH!̥% &t!\HԋI/THlI-  0LH'< (!H'4'D䝢H.I*,! !'I '$I5 ԍI&́I-' I/ I0䑠 (ȡ"셠 !܇ȡH,H$I;%̉ 'ԃI>̏''䁣I=*''ԏ! 6#̇ ! !'ȠēH&I H-䓢HI H쓢HI  ȵH! =H'|'̹ !H6ěH H! ;䑠I H!$̅ I6 !H*I #ī !쇠I =*'l䅠I;'|I> 'd̿ !H'䏠 !H($ ! !><č8 !4l I6(Ȣ'\'t셠I 䫠I>H'dȠ;$'Ĺ !ȯȰ'\ =ȡ'̉ !ȿ''TI I ȣ5L 6!䡠I  ̃I 'D >&@'< !.'4(&@ ԃI .(',D(D!&@&@ԃI '$>ԱG?W\d? gp?hݤ?}d?Ax>?@fftw_no_twiddle_11GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4 `!  , 2   = B ;J  S P  d #.9 DOZep {$ ` fn_11.cgcc2_compiled.K959492973K654860733K142314838K415415013K841253532K540640817K909631995K989821441K755749574K281732556*ABS*fftw_no_twiddle_11fftw_no_twiddle_11_descL $P $       8 < X \ t x       (fn_12.o/ 915488224 571 300 100664 1980 ` ELF4( h..9 $.H+.Ȥ656`$Ȣ./ H4Ȥ /  4(.'@Ȣ(+0:,:-H-H:%/ %Ȣ-" $#@.$#Ȣ`" ##H$ȦHH)H"'쁥 9#'䁧 0H3 ,2'( 5'܁H4H1ȹȬ ;H;H *"H# .* ?Ȼ$.ȪȥȮ%")'ԁHH#ȱ':.1../ 8/ / '/ H@('쯥ȸ&@&@@䛣H&&@&@@܉ȩ@ &`ԍȫ.&  @) '@. @+ ..̏&@&@&@@&@&@ @ȯ  @ Ȳ/..&@@2&@&@&@ @&` ?]?fftw_no_twiddle_12GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4!t0  , 2  =BJ#8SD  _ #.4G fn_12.cgcc2_compiled.K866025403K500000000*ABS*fftw_no_twiddle_12fftw_no_twiddle_12_desc, @    fn_13.o/ 915488229 571 300 100664 3928 ` ELF4( 㾨..@/`./   ."."@@.Ȣ/`)/  (+"/  &ȢȦ ;$ * "ȤȢ/';ȫ'%'/ %%ȣ.'ԡ&"I)I(H"'䃡(H,'",ȢH-  `"`' % "  " 'đ+,.ȴȬ'ܓ"2 `"# I%#I+'̹"'3H(("'I8HH5 ;ȫ6H'-' 0*'|HI'H0'lH1'tI3H$I8'0 =&' ,8'd'\=I63'ȴ'# 6'TȧI*'TH" ,;%ȧHI7'L)!3I*9%#L 7$)H)Ȧ%3H#ȴ#"Ȧ"'D $ȩ'<I '  &'4t)I H$Ƚ %,|', !"H% lHI *I!"H'2HdI2$'$\ <:쉤 !ȺTԥ !H.5 习2> #><> ->2Qd?>:>,>,>X?=,>̑! !>엢Ƞ *'\\H* )ȭ'TH2 !'́I*'읠H. >'̥+I >'d '̓H!콠> *'L'dI! ēHd''''ܓH) &'䑠!%' 'Ȼd H!"' !ȹ+I!ȿ %Ƚ!&ȣ'd( !I 't !%'|ē!l ''LtH &H''l !H&l'D|I!'d !'\'<!#ć '%" |! 7LHl ܅H"' DH<| !'T'4ă !܏'I7*' l !| ȥ'!Ȧ''' 7'I!' '!'쁠!ȣ' ܃H' !',́'$\ ,'$H 'D !,'!H"'tI H  D'H &'!\ !ԋ%'!H."/` '| !H.&@%.&@ / .'D.|I ..(Ht. ԇ H" (((&@ԉ !&@&@ &@(&@&@7!.@@ &@ \&@|!&@ \&@&@tT &@4'`# DH0 @@ I!@"' "'t& t@@@ ĉ/#'ll@H@ &`'@@@& "" "`&`>c܇?f?>&?H&?yfftw_no_twiddle_14GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4!   , 2   = ,B 0+J [ pS |    #.9 DOZ`s fn_14.cgcc2_compiled.K222520933K900968867K623489801K433883739K781831482K974927912*ABS*fftw_no_twiddle_14fftw_no_twiddle_14_desc      D L P T \ ` fn_15.o/ 915488234 571 300 100664 2944 ` ELF4( 㾰.((#Ȣ%H "H$Ȣ".%@ $'l$*`#(. #:'䷠  +"*` * H.H<H+* #`)H( $'̷ :H*Ⱥ)$'('ԃH. "H'H('!" <'H1'H'>'''';%.H+.6* )'<H2H"*`+*` HH2H+ /# %ȥ/=(%  Ȧ "'(H; 6' )"''|8&!.I-ȸ0'$!-HI$ȡ?-'tȲI#?2$'\'T;I4&)&@'L"䛠H4H&I('D!I"-4HȢH"&'<ijH'4ԅ*HH&I9ȻI*H$I+!9#',(9ȫ(I3ȴ'$3ȡ#I;ȡ,"I/!'|HI,H#5;I5&'H;̧(H".#@&(+ + @/`.I..Ȣ(((t(.H;..I6#. ("\I:&@TȬL&@&@ &@D:<&@ H.t&@ (ȡ(.@&@"46&@,H&@&`ܐ@(@@ I,@ H@@ @$ȱ@" '`#""` "H7' & @ %@ @ H@ @ H$&@&@ &@&@&@ ?y?sxq>???]fftw_no_twiddle_15GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4!  , 2 h  =B+J0S <   L #.9 DOZ`s fn_15.cgcc2_compiled.K587785252K951056516K250000000K559016994K500000000K866025403*ABS*fftw_no_twiddle_15fftw_no_twiddle_15_desc( , H P       < D fn_16.o/ 915488236 571 300 100664 2504 ` ELFd4(  ." H".H./ H"H&HHH5"HȢ.H$."@"(H/`"ȢHH"/ / ##("&'ȢȤȥ"%.'䃢H("ȢH# H"H/`H/ "%Ȣ'ԃ2` "'컦$Ȣ '#@("ȣ `Ȣ"(=+'܏"H'H0 HH"'!&3ȥȨ%"<)H&'ăȩH8"H'ȡȣ#'ԅ.H"&@&@HI#ȣ#I"'ԙ!H *,'̏I#H"왡 4!HI'HI&'H# *' 44'䅢 !&ȫ -/I#& !ȣHI+# -+'HH"-ȥHH% 0H"ܱ !.-. 7/ .̞"@! 0++.%@@I Ľ& @  .&&`H* &@ .Ȧ&@&@ܫH) !@./ Ȣ&@@ 7. @ @"&. &@&@& $/ &(&@/ &@@ Ȣ@ &@&@"@ @' H@(.H$@&@&@ H** @@ H#&@&@ @ &`?l^>?5fftw_no_twiddle_16GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4! hH  , 2   =B#JS  j #.9?R fn_16.cgcc2_compiled.K923879532K382683432K707106781*ABS*fftw_no_twiddle_16fftw_no_twiddle_16_desc       fn_32.o/ 915488238 571 300 100664 5548 ` ELF|4( 㻘.H"H 'l".Ȣ.@*`H"H&"Ȣ$..'l@H,`"'lH#'̫H,'"Ȣ.$**`"Ȣ(")'%Ȥ'H$.""'''H''*'H#''d/ "Ȣ H*`*H"'\#('D"Ȣ",`#@("Ȣ*"*`#($*/ 'T"Ȣ'<,'L'|<H!H'dG?{?l^>?5fftw_no_twiddle_32GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4!  , 2  =B3J(S4  T #.9 DOZek~ fn_32.cgcc2_compiled.K831469612K555570233K195090322K980785280K923879532K382683432K707106781*ABS*fftw_no_twiddle_32fftw_no_twiddle_32_desc    D P   ,  0  |    fn_64.o/ 915488243 571 300 100664 12116 ` ELF)4( ."Ȣ ".Ȣ.'T(",Ȭ"H+..* "Ȣ$".Ȣ'L!-`TH) "ȢȪ'H"H$'̃2HȰ/H"'H)'ܽ"'Ȧ%&'ȥ.'"'䉡") '''Ȫ''''D#'<'4/ "Ȣ'$ .H'l!- TH") %("-`-) '@"@(Ȣ(`H" H$* !(',Ȥ#" $#H1%#H'tH+(H%'dHHHH".H'L&#5'TH)#'</"H'DH'$'lH"'\'4','$Ȥ'L $+ H"&H Ȧ'"T) Ȣ* -"&"- -`"Ȣ7' "#) ,+H"H-'."H' 2H"'2H('ܣ/#+ #Ȫ'H"/H %ȫ'̣ /+H$%'佣H' "H +H$&"H%#&+ $ $'Ȣ''''H'('" &Ȣ#'|HH"* #@,((' "ȢH%'HȢȤ"$-`"- $@H5, (" H+H"+ ("H2ȢHH5H"9' 9(&"6 -'H 'H*-& "Ȭ'Ȧ:'# +'d /('t'\ $"'Tȥ+'lH''L'D$%& (ȣ :'<+#H4H$'4Ȣ"lH'/ "Ȣ'$H"Ȣ@H)+ /`"''܆/*"-HȢH#H"@$* ','H+`H' ȧH&'"'ԅH>H"Hȥ'ċ,('' ďH''H"Ȩ'HȣH'싢5#)-'܏H"'H#H"'䃡ȣ'̋+$#&'ă'ԽH$*LH&' "@*`Ȣ /`Ȥ "/ $("Ȣ/5 + H ' H"('H``"#H&  Ȣ"$H7'"ȥ'ȷ)(''Ȩȱ"'HHH#H*-'l1"'|#"'t$#&'dȤ$) '\H- "$H&, '4+H''H$  ",Ȣ-`H(`"H&Ȣ'/``"'T H"#'DHȧ'"HH4H-'L"'<ȥ(H'',H"'Ȩ=H'HHH#)*"' Ȣ$"'Ȥ$1"'ԇH'샠&"'ܽȦ,'$"&'Ȣ+`-"' ("Ȣ'Ľ%' 5`HHH"$@,`''̃ȭ* " =-/Ȣ`= ' /"T%-H/-"4% HHH"ȣ#"ȴ (5' "$('H*)'' >H# % *H"'Ȧ'H$>&Ȩ%Ȥ 'H'#''Ⱦ'%'H>'+'H>,'|H>"HȢ'|LH4#tt!H"ԛ! !HHȧH&(H#''TH'\'L'D'<H' HH$H#ԏtt,L<'$'D>H"'4>'|H!,H1',dH>.&@L'!H1,ȡ'&#'',''I&1T4!d!%"4#$'4' ''H4'I%H$4T"'|d,H|I$ȬI",''t'ܙ|"'lHtI$d'dLtd!'|"$'H>'|dI>H'\tI$I>ȫ'L엠I>'DlH:)Dԓ!\L'I>|HHLԃI>''\DI>%'dL샠I>"'<D̅I>H&\dHH$'Hȧ"..ȣ, .!- H&- '4.H:'\&@H.@@T @L' D#<&@&@&ħ,, , '@H"&`' ,&@ .. , &@>@ @ )@&.&@&@& %(',*!'$) %@Ȣ' 4"&@) H%@&@@@ @  & &@&@$(&@H>&@ @. @* 'DH=H4) @Ȫ@  !''!'t%Ŀ>I%ȿ,'l\H> LH>"ğ*I('I"\,H?'d' L)Hȱ#'쟣1'H>I)'䟧!'DH#-'I4(HI6H"I4'ܣH/6!H#I ̱?!I>'|H>'ԣH>"̿I!>H$1 '䕣I!Ƚ Hܩ*H1"H'8H$'Ȣ'܉"''|#&6'tȢ'l"='dH('TԕHȢH'D&'4̃H%'$|H"''H>'\'L'<',' $%! &|H> %'H>&$ 5H" $쇠H> $HlDH51Tl)HH' "쁠H$4lD"H>H쉤 $H>="'lTH> =ȱ 6)6+"$H+#ȢȪ"HH$'H'܁"'$>H쿤>%H#'ԋ>H6't&>Ȣ("'ld'>H'\'H>llH>D'䣠I*\>' ''L)D&I)(\H%L* 'H!D<,H?LȢI$"I,''\HD$ H'<=ȵI&5'䭣&'H>H4I=H'>Ȩ' !H$>H6#ĉ !#!$ > !"H'l܅!'"ll\Ⱦ'ttH(*ȧ'|I7HH$I*"7%ȪH"6'dHȶ'Tȷ'D'<|!H">7䅤H+!Ȣ|!H&'4l%>"'t'dąHȱt'LH>',Ht"dH>H,ȫ(+'\'$DH7I%d'6I('|%H"*dHL' 6DHI#HDHI+'L+H)I*'H#ܗ+H9D6Ȧ䍣! >#!H4 >) !H̩!,>䅠# !Ht0tdȦDH",ȮLI0+"H)$I,H''콧DI0셠H"'ԅ6'ܽȤ&$'̽H"H.H'''<>',!'\!<!'ȱ&")ȥ&'I)'$4'!H#$'!*$%H"'H#I"H'|'\$4$'T$ĽȨI"'t䷤"HįI$$\(<'l(ĕ$6(Ȱ\TH>$H'dܣ!#ēI>"'L!ķ7I>H(|Hć$!I>"ܯȶI!%ğ>HH/ȭH)-H"ȥ(;'D"',H>t'I"|dI"I#''tI#,'-&@H3 /왣$&@|H>, '@+  䳧-(&@$+ &@'&@I/4$) #@. @T |HI/- ",`I&@@ @| t&&@&lȢ&@'H>. *"/'d(&@\@T&@D ԅI>,"@*+L@L !ȫH3@D@<  H>'4'&@D!,&@H>H$, + &@L&@I>ȳ$) 3@ D'ėI>@- @@ L& !@,`@@$ &@̇*&@L&@ԉI>(`@+`+"/`'@&@D HI>* ,H$@'@  %H>, + - ,ȯ@'*` &@*`,*@>&@/`dH/&@T@\H#&@ @L@D  $Ȣ@@'ĽH @! % &@'t&@&@&@ @  ԕ**-/`/`H"@@'|'|#| tH@&@|/`H!l@ &@ DȲ&@&@@@&@ @@ ' @ t$"&@&@H@-`"/ ܭ-@&@@H&@ @ H(@%`"&@&@@?9?T1?aŘ>Z>1?t ?{>G?~m=Ƚ6?E?"g?l^>?5fftw_no_twiddle_64GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4(x!-h  ,( 2/<  =(B(SJ)#)8S+D  , #.9 DOZep {$(,048(x fn_64.cgcc2_compiled.K555570233K831469612K881921264K471396736K290284677K956940335K980785280K195090322K995184726K098017140K773010453K634393284K923879532K382683432K707106781*ABS*fftw_no_twiddle_64fftw_no_twiddle_64_desc 8 8l 4p 4| 0 0 , ,  (( ( $ $          x |   4 < H L @ftw_2.o/ 915488245 571 300 100664 1048 ` ELFT4(  +  *`%@''%#HH$#` Ȣ"   fftw_twiddle_2GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.data.rela.data.bss.rodata.comment4! '$ 27? H  O &,; ftw_2.cgcc2_compiled.twiddle_order*ABS*fftw_twiddle_2fftw_twiddle_2_desc ftw_3.o/ 915488247 571 300 100664 1348 ` ELF4( B + ` ** `"@$$" (@'(& 'H$%"I'Ȣ #'#I(H@" % `H"" #@ @@ #`@ ͆ 0?]?fftw_twiddle_3GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4!0  ,H 2 $  =hBhJS  e #.<BQ ftw_3.cgcc2_compiled.K866025403K500000000twiddle_order*ABS*fftw_twiddle_3fftw_twiddle_3_desc$ ( 0 4  ftw_4.o/ 915488252 571 300 100664 1248 ` ELF4( O + `** ( * "# #"H +`I"@#I#'"@'H&+H) '-$Ȣ@"Ȫ$H#'(H ` " #`  @@ %  #@@ @fftw_twiddle_4GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.data.rela.data.bss.rodata.comment4H!| '$ 27?H  lO  &,H; ftw_4.cgcc2_compiled.twiddle_order*ABS*fftw_twiddle_4fftw_twiddle_4_desc ftw_5.o/ 915488256 571 300 100664 1712 ` ELF4( 㿐|..(..` @#@`""#`@ I"`@#I#"@` I$@`H"&I"Ȫ$H+@@(@) ,ȣ#, (H.$/H%&)I)0@H$I"Ȧ$Ȱ+"H #%H-I-HH"I*(`*"#, '"Ȥ #` '@'@'@"'@'@'`&`  *`@& P>??y?sxqfftw_twiddle_5GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4!,`  ,< 2$  =\B`/JS  { #.9 DRXg ftw_5.cgcc2_compiled.K250000000K559016994K587785252K951056516twiddle_order*ABS*fftw_twiddle_5fftw_twiddle_5_desc( , 4 8 @ D L P   ftw_6.o/ 915488259 571 300 100664 1660 ` ELF(4( 㿐.(....(`$@ 쑡I$@ "I"$@`"@I$$@I"Ȩ@$%@ ("`0$"@-%@H襡 "'") %@Ȧ@(@-&*-H(#%'"ȪI#ȩ1"#H"I&.H'0(I#ȥ"+H"HI$#(`(.'@ 4'@'@&  "&*'@'@'@'`@&` `??]fftw_twiddle_6GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment48!(0  ,l 2X$  =B/JS  e #.<B8Q ftw_6.cgcc2_compiled.K500000000K866025403twiddle_order*ABS*fftw_twiddle_6fftw_twiddle_6_desc< @ H L   ftw_7.o/ 915488261 571 300 100664 2176 ` ELF`4( 㿐Қ...((.(.`@ 衡"@  ## "@ ` $@ `""$@ `I"앢@ $(I$."`&@I$`@ I"ȣ#I"@&I$@ "ȴ@ȭ $3 $ȯ 6H+ "@H)$H4@$H%&(*@6 -5--4#-0I)/#+"I4I*#)ȥ8#Ȧ*2Ȥ)61ȥ #6$,.ȦI.1#Ȣ ,0"I3H.H0*'H#`*3*I0H3'3H& 10 '*,*,Ȭ1ȱ?  0H"`0'@'@ '@ ''@'@'@'@ '`&`&  Ȯ &+`@I&p>c܇?f?>&?y?H&fftw_twiddle_7GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4`!  , 2\$  =B?J S  8 #.9 DOZhn`} ftw_7.cgcc2_compiled.K222520933K900968867K623489801K433883739K974927912K781831482twiddle_order*ABS*fftw_twiddle_7fftw_twiddle_7_desc0 4 < @ H L T X ` d l p 0 ftw_8.o/ 915488263 571 300 100664 1760 ` ELF4( 㿐..!(.(.(.(`$@ $@ ""$`@  "` @ $$"@ $@ H@I"H)&I$H` "䱠5@ I$ȳ@ `H"*$I",@ `H( #@ `Ȭ "#ȴ% "@- (@੠"*$ "Ȫ(@Ȧ -H@@&(, (HH%3-8$HȢ0H"H6$(.HȮ95'ȹȢ#$#H,"H&H+H#"ȩ 8`8'@ '@H&`& +'`H"&'@ '@ '@ /'@  ,`ȫ'@'@@&d' ?5fftw_twiddle_8GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4!  , 2$  =(B(/JWlSx  HZ #17F ftw_8.cgcc2_compiled.K707106781twiddle_order*ABS*fftw_twiddle_8fftw_twiddle_8_descH L   ftw_9.o/ 915488264 571 300 100664 2580 ` ELF4( h.((.(.#(.'.'.'`4''@?ܣ #@`?I"@ ?رI0I# "@ ? %H@?H$&@   ' &#%@ ?쓡#@ ` %H/;?@ "I"H4=?@ ""H# %H 0&'H(@#$3@ Ȣ?䣢I$`%"+@@?гȹ "H,"=3#@ I"%?豠"H+ȧ$@ &@ H?I,2H,)I&%"H$Ȣ%#ȩH#%H&3(&#-"ȱH"H$H셠 ,%+5#䏠 (<*ȯ̟H5 0H3ȣ챠ȳ (#I:'䙠 ,&$I0̵ :4&06(Ȭ %+"ȣܟ& -I)"ԅ .H$'̡+ )ȤI%Ȣܝ .#Hԛ -Ȧ-'H.H"H"%;? @ @H'# @ @ @H6 `' '` @ @ @ &  6 , @ @ @ @&& &` ?p>D?|\>1?$?D}??]fftw_twiddle_9GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4! 0  , 2 $  =BOJ'<SH@   #.9 DOZep ~ ftw_9.cgcc2_compiled.K939692620K342020143K984807753K173648177K642787609K766044443K500000000K866025403twiddle_order*ABS*fftw_twiddle_9fftw_twiddle_9_desc@ D H L P T ` d l p x |     @ ftw_10.o/ 915488266 571 300 100664 2372 ` ELF4( `.(..(.(.("(.'`<'@?䓡#@`?苡 "" #?@"?@##"H@@ #H?ȸ@ &"H)#`: "H @#@ +I"I#("@H?쭠&?H'@I"H.ȥI&"%@ ?̽ $@ `H#?б">0 "?ԯH@ #H6Ⱦ$?؛H@  '졢"7H*"H#'Ļ1?@  "?@ ,I# #ȱI"''@ ?*@ )%HH.%*#H82$ȫH0;H#+I(ԛHI2' " ($I"2ܙI,Ȭ# )(I3'įH=I)" 3*ȩԉI7?ċH:܋I%ԇI)H$H" /HܳH)I.%I&#䓢=I/ &Ȯԍ/I)Ȧ䗢ȽI-&셧H 5ȨܗI+( -쓢H=I5"H5` H H @ @ @ H$ @ @'`& " ' & @ @ @ @ @ `#&&` -`@  ?y?sxq>? fftw_twiddle_10GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4!`  , 2 $  =BHJ 5S@  @~ $/: E$SYi ftw_10.cgcc2_compiled.K587785252K951056516K250000000K559016994twiddle_order*ABS*fftw_twiddle_10fftw_twiddle_10_descP T ` d l p x | 8 ftw_16.o/ 915488268 571 300 100664 3256 ` ELF 04( `''/`'l/`'\/`. 'L/`$@('<. &('4/`$('ԙ. /`((. .((`$','$'l @ # @  " #"?'d\@ #?@  " #" 4'TL@ # 8@ I" " PH'DI#<@@ )" L&@ #`#;Ȥ" ,4Ȳ@ I# 0*@ `"#,H(I" ԯȬ@ #@  H' I".@ ?졤&"%I#-?@H%@ 'ԃH1`"H'?"H&?@ ")'ğ"0* % (@  " $@ '%HH$%'+" DH@%/ @ȫI$@ HH'̯ "H#쥤"'@#'. %&@I"' 'I"I$@`"'?౦2"(# @@ "* <@H)##H"/@ ȷI(@ $.Ȳ%I$'"(H+)@%@H?*#*%'3"'̃Hȧ0'|̇HH''t,I%H"ȯI#$ĝ$ "̥H; )H2 >/'$#I)$ 6I>+ "$ 6>ȥ'̣H 6',ęI, %I1' 2ąH#''ąI& $I-̷ȠI9,$ &H;I5ȱI-%ȤI9 5#H9ȢȤ;$5ȣ,"''ԋȡH"HH܍Ht*&H$tH ,ԇ #!' $ "&H# *H")!H"8ܩ!Ȣ4|H H H!'仠Ȣx'4!' @ "< @  @ ԉȺ @ '`"`" " @: @ @ @&`Ȥ H4l &  @ $ @ @ @#'' && @ ȷL @ @ \ @ d `"T"D" x*.@>?l^?5 fftw_twiddle_16GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4! LH  ,L 2 $  =lBpXJS   s $/: <HN^ ftw_16.cgcc2_compiled.K382683432K923879532K707106781twiddle_order*ABS*fftw_twiddle_16fftw_twiddle_16_desc     H   ftw_32.o/ 915488272 571 300 100664 6924 ` ELF4( @''܀M'-'t-'d-. 'T-'<"('4. %('-%*`' -%@+'. 'ܷ-.'̕+'.'@('+'('. &* '.'D@('<.'4(' *`'* 'ܟ+'Ա. '̷.'@/`'/ '.'`d't('t` #` #  "'l"d ԙ #ؔ I" "`T'\T (I#ȩ H'"`X'L"`4 I'H$`'*('$Ȫ/ &$"`LI$', H &' ''`P"H( "$ &` ' H# $ ,`"1H "H''$ ̭%) Ȫ'$ "-("ȥ ).H/''<'DȮ I(H"'D '%HI%H'䕢('# ' %-''I"ȣ&I%̙ " +'|`4#' '쏡"싥%`8't"H'H$# `xH,'l$ ȫ`t('H(.$Ȯ#/& %9 #H %ȱ #,'d`,%''\ )'T $'L'`0 #"#ȯ`l $H'< I# ȭ`p'4 "H*'I"'- # &Ȯ'$*()*H&#&%','D'#&"'D#ȫ`h `H"`d #$ȰH%#'''L"' H'|<`$+ #`(1  "$H#H)4'l" '\'dLI(  蝥."'THI"&쇠(HH/I&H,`$%HI$" &'T`\' %`` -$Ȫ'* $"(%'쯧H'`, $''',H#` ,"), "'Ȳ܏$' ' *I) (`"'I"ȧ)`0 %'$('`"  $'$'$Ȫ`D('ȫ /I% 'I$+'`H"ԣ$` '` "&#%` Ȧ䝢I$ 'H $-I" '.$)􋠉$('  $ # %5%H'# $*0'' `<$ `@H'ĕ#%H"$&'#H`| I$ ``."H$ȧȵI" H1 *  '@&8)* &H$ȥ%ȢH/"ȭȣ#'|%H"'H9'$'\:H:H"H4:&ĉ(+7%l HȢ&H"H$-'H.H't'd\''|'l'\='T4T*ćȨ,lH"'LH t#"#*'Dt#%'4H,H#-'$H'<Ⱥ'<','' '̽:Ⱥ/t! Ȱ&: 6ܻ: &06 'ȺH' 0H"'#t'0H4T $7$Ⱥ# 7 #"t 7 0$t)H􉢉0Ȣ ) %ȢH#'䓦t"4H,5,'쉢H$'Ե"HH)'t'l7'''t1'\0:H8tH-"'$D:ȯt"H#'̵H9 7':䍢7H'' 2&7ȸ,L792'',t'|#'t&Ȣ̵:H"$ 7H'T䧤8 :'Lī7&'l$1T"H;'DLI1:'\ȣ3\D72"H''<|I3)",$H+$! ܗH'! 䏡ȥ"ċ *"܅&! ̕! 쉡"! ԅ! <&#'`" ! D!! 4! H|$$ /tH"# ,$`! $1! !  ! ' && &`!!!  ! #`""`"! H! 4!  ! 􍡈"""","! !! 1! "H"""`* >G?{?T1?9>?l^?5 fftw_twiddle_32GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4T!@  , 2$  =BJPeSp0   $/: EP[f|tzT ftw_32.cgcc2_compiled.K195090322K980785280K831469612K555570233K382683432K923879532K707106781twiddle_order*ABS*fftw_twiddle_32fftw_twiddle_32_desc   p  |       L P X l  ftw_64.o/ 915488286 571 300 100664 15276 ` ELF54( 㱘''܀ '-'-'-'('-'̢@'ģ,`'-(',`',`'('\'$@'L,`'D&,`'4-'l$@('ܣ-'܆$@('L(,`'$@(',`'$@('-'$@'|,`'t|'t,`'d. 'LL,`'<`,`'ą(,`'',,`('l''|'t'` #`I#`I" "' #`"#4'쏡"#8I#`I"'ԍ"`4I#`8H`"H(#Ȳ'I"' #H&`I" "`%''I#`&``#+H$#&" 3'읣2``H #( #ȥ 3H'|H1"Ht",H/#H&H3 3H|&-H"#3$H''t(l-T' % X`H-"%'ę'`T'd\H "''H'T`'H*#'4`X"."HD#ȩ'`ԯ0$'`ط`I#)I$"' "',`'I#x&` ";I"'$ #,``t'`x&H' Ԣ`##%&Ȥ|."9#/t9't %H'|%-'t*"/'''܅H0''|#Ht5#'|'t|*)3,'l$Ⱥt'a'\'|:I#a"'T I#Ⱥ`I"2'ldI"'d`'L'D?쭡#`ȸ`$"ܝȮ#',H4"`ē+, '\ #&``Ȼ-", "'THL'"'$%H('<#''4;`'D#6' '' #1?t ?aŘ>Z?9?T1?E?"g=Ƚ6?~m?{>G?5?l^>  !"#$%&'()*+,-./0123456789:;<=>?fftw_twiddle_64GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment43!: h  ,3 2;$  =4 B4HJ5X5mS7x  9( $/: EP[fq |$(,048<3 ftw_64.cgcc2_compiled.K290284677K956940335K881921264K471396736K555570233K831469612K773010453K634393284K098017140K995184726K980785280K195090322K707106781K923879532K382683432twiddle_order*ABS*fftw_twiddle_64fftw_twiddle_64_desc 8 8 4 4 0 0 , , ( (L $T $` d |    " " " " #h #l #| # # # # # 8?sxq?y?fftwi_no_twiddle_5GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4t!t`  , 2  =B#JS  u #.9 DJt] fni_5.cgcc2_compiled.K250000000K951056516K587785252K559016994*ABS*fftwi_no_twiddle_5fftwi_no_twiddle_5_desc\ ` |       fni_6.o/ 915488300 571 300 100664 1436 ` ELFl4( * (" Ȣ*"*  (HH"** HH"4H- "   HH"#1ȧȨ#H$#3H$Ȥ$123&2*. $(***. ("@*@"@)@Ȫ"@"@"@ "@ Ȣ@@ " + "`@ ""`i?]?fftwi_no_twiddle_6GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4!T0  , 2  =BJS$  _ #.4G fni_6.cgcc2_compiled.K866025403K500000000*ABS*fftwi_no_twiddle_6fftwi_no_twiddle_6_desc     fni_7.o/ 915488301 571 300 100664 1936 ` ELF4( 㿐..(.(`./  H"H.H` 4H)I9( '  '"9I#+ I'";%I%%I4>"%)$Ȣ$ #Ȫ 4Ȳ:$Ȧ #H9ȧI$&H9ȴI=$H5  76H" 7I65 <3 =#"3% =2HI<&I5HI7% <#3HI3Ȧ6-.5ȧ(.((.6&@#&@.&@.@@&@@Ȣ&@@&@&@$&`@@& '  &&&`y>c܇?f?>&?y?H&fftwi_no_twiddle_7GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4!  , 2x  =B+J+@SL  \ #.9 DOZ`s fni_7.cgcc2_compiled.K222520933K900968867K623489801K433883739K974927912K781831482*ABS*fftwi_no_twiddle_7fftwi_no_twiddle_7_descP T \ ` |     fni_8.o/ 915488303 571 300 100664 1496 ` ELF4( *" H"*H*  ("Ȣ5  *("# (#"H/*  ȥ(   H&H#(HH'&HH$'H3ȢHH&Ȳ$H20I"1I#"* ((**"@@ȩ"@@ @ # " I""`H/"@ "@ *" * @I) "@ * ȥ("@@"@ %"@"@@ "`?5fftwi_no_twiddle_8GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4!  ,8 2  =XBXJsS  TT #)< fni_8.cgcc2_compiled.K707106781*ABS*fftwi_no_twiddle_8fftwi_no_twiddle_8_desc, 4  fni_9.o/ 915488304 571 300 100664 2280 ` ELF4( h* ( ($  4!45#t H5HtH**# ##l("Ȣ6# H6H#(ȶ  (3* (*">Ȣ$1* $l!H #| 1H""I+&H/H$(HH:H+<="H(I:Ⱥ#"H#%H ?H. #d| ȩ?#$Ȣ",Ȧ*$*H (("@H$"@"@#@Hd@  H"`*+"@"@(H#(* (@"@ /631| 7!7! 3H)I0&Ȥ0(I/H"*%Ȫ(%"(@@*# " (*" ,"@@"@"@  @ @""`#h ?$?D}?p>D?|\>1?]?fftwi_no_twiddle_9GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4!  , 2  =B3J0S<0  l #.9 DOZepv fni_9.cgcc2_compiled.K642787609K766044443K939692620K342020143K984807753K173648177K866025403K500000000*ABS*fftwi_no_twiddle_9fftwi_no_twiddle_9_desc    \ ` h l          fni_10.o/ 915488306 571 300 100664 1972 ` ELF4( 㿐.(HH" Ȣ.".' (Ȣ."(".(Ȣ"%.ȣ.H#&H": H`H$H5"-` "H8HH"ȭ  ")Ȧȩ&%",I#;I"Ȼ 5= 8HH (H#H# 'ȩ)&9I$"I&ȩ$H$1HȦI3&3H#60< 6#I0 +Ȱ2 . <$?..ȴ&+I (..2 . . .Ȣ(I?&@Ȭ.@&@&@H*&@&@&@&@7&@&@&@ "@@@@@@@& " #&`H,@' '`&&` ?>?sxq?yfftwi_no_twiddle_10GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4<!<`  ,p 2  =B$JS  x $/: EK<_ fni_10.cgcc2_compiled.K559016994K250000000K951056516K587785252*ABS*fftwi_no_twiddle_10fftwi_no_twiddle_10_descT X d h      fni_11.o/ 915488308 571 300 100664 4144 ` ELF d4( 㼐../  .(`''\H'|I'./ '`. 'L\('T* 'D'lL' DH.@"@'.'d'I 'dlH  ''+I  '쁠I5 ,'I0H)''ԃ /;'''tI-'t' #'I&'H"' (''䉠 'I5 *'!'|'t !'l (H|!I-'́ 0.'\'dtI/\'TT!''''' &l'LdH 'HI'H(5'<L'<D!'<0'4I '44H&', !Ȼ',,I*/'''$'$ H $́-I(' -H!'샠I/HH2'! &'  0܋H'I'I ' ''! *|!'H1 5dH!'̥% &t!\HԋI/THlI- L 0H<'! (H'4'D䝢H.I*,! !'I '$I5 ԍI&́I-' I/ I0H,䑠 (ȡ"왣% !H$̇ȡ I7ԙ'I=̏''䁣I<*'' 6!# ! !'ȠēH&I H-䓢HI H쓢HI  ȵH! č8 !4l I6(Ȣ'\'t셠I 䫠I=H'dȠ7$'Ĺ !ȯȰ'\ <ȡ'̉ !ȿ''TI I ȣ5L 6!䡠I  ̃I 'D =&@'< !.'4(&@ ԃI .(',D(D!&@&@ԃI '$>ԱG?W\d? gp?hݤ?}d?Ax>?@fftwi_no_twiddle_11GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4 h!(  , 2  = B <J  S P  l $/: EP[fq |$ h fni_11.cgcc2_compiled.K959492973K654860733K142314838K415415013K841253532K540640817K909631995K989821441K755749574K281732556*ABS*fftwi_no_twiddle_11fftwi_no_twiddle_11_descL $P $       8 < X \ t x       (fni_12.o/ 915488309 571 300 100664 1984 ` ELF4( h..# 7.+Ȥ.5#5`3 ./ &/ Ȥ .'@(&(ȢH/0ȥH0HH0+HH+H+H#H/ $" ȼ"$+%@."`)"H$ȥ $8ȢH"'쁥HH$H%'ȣ 7# )'܁ ' ,Ȭ 3&H7).? /H3#/ -" >ȥHH<%="(Ȣ'ԁHH#ȸ*$8..(... (( '̭1(&@&@@&@&@&@ܰ@&(&` & H.. &@H'&@@@̏Ȧ@ @ & #(&&@&@&@&@. @.-@@ @2  #&@&@ ?]?fftwi_no_twiddle_12GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4!x0  , 2  =BJ$9SD  b $/5I fni_12.cgcc2_compiled.K866025403K500000000*ABS*fftwi_no_twiddle_12fftwi_no_twiddle_12_desc, <    fni_13.o/ 915488311 571 300 100664 3904 ` ELFt4( 㾠..@/` ."/ /  Ȣ(. / @H" +H#H ;."@H * "0;H$.Ȱ/`'("/ H"H"*ȢH%#H&Hȣ 'H*H'쟡'H'HH$.H,H# "H #H,ȢH  `"$Ȣ  `'ԍ "Ȣ $ "*('`'Ȩ'䣢"H2  '"'̃Ȳ.# *"1Ȯ'Ȣ ;$-'- 9" )'t'I5I/4'l-I/'ȶ 9'dI)6 5'9 <I/.3'\'TI*H5' 7 #>2><> ->2Qd?>:>,?=,>,>X?]>c܇?f?>&?H&?yfftwi_no_twiddle_14GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4 ! d  ,T 2   =tBx,JS     $/: EP[a u fni_14.cgcc2_compiled.K222520933K900968867K623489801K433883739K781831482K974927912*ABS*fftwi_no_twiddle_14fftwi_no_twiddle_14_desc       ( 4 < P T fni_15.o/ 915488315 571 300 100664 2924 ` ELFl4( .(("Ȣ"I% "Ȣ"I&% & #.* '@(>."I*#* '+Ȥ'܄*.I+$'썤HH" #'ԁȣ .H+#I'&/ I(H ȤH''䃦- "(',"'ā! 6'8''H;'H $ȸ'6@.''H/`"`$I4+* .I7H&H"H4 $ȤH7I2$* H "H2I5' ȩ="!5 * -('HȪH')Ȩ'|H /H,%'$, 1I<%'t쥠H1H<H1I&!2I1ȥ3%'l#ԑH3H1$#HI"3('dȣ#&@'\'T*!.%H"*ȡ'L. I#HI+Ȥ#$"ȱI%'D$H䍣0%9H+5̵9'???]fftwi_no_twiddle_15GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4!  , 2 T  =B,JS $   4 $/: EP[au fni_15.cgcc2_compiled.K951056516K587785252K250000000K559016994K500000000K866025403*ABS*fftwi_no_twiddle_15fftwi_no_twiddle_15_desc4 < H L       < @ fni_16.o/ 915488318 571 300 100664 2508 ` ELFd4( 0.H"H "../ "&ȢȦ4".%."@"(/`"H"/ / H$#("&Ȣ'ȣ".("$Ȣ% "/`$/ "Ȥ%` "Ȣ'칡- '܃Ȱ@('䏣"Ȣ #`HH"(H+"Ȣ1 H"Ȧ)&'ԽHȩ=;H$,H#-';H #H" &쥤! ,3& *#Ȭ .'ܓ>H, 30*)3Ȱ #HȣH" +#+.ȥ >%. /"'䧣!./.ԋ 6"/`/`.&' >+.%@@1̋H @ Ȧ 1&&`@H(.6䕠Ȣ&@&@+.H/ ! "@ ((&@&@H$@ @ &.&@H&@/ @H" @ +H(&@&@H$@ @ H&@&@&. @+ @* &@@&@H#@&'`&@&@ >?l^?5fftwi_no_twiddle_16GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4! lH  , 2   =B$JS  m $/:@T fni_16.cgcc2_compiled.K382683432K923879532K707106781*ABS*fftwi_no_twiddle_16fftwi_no_twiddle_16_desc    ( ,  fni_32.o/ 915488324 571 300 100664 5688 ` ELF4( (."Ȣ ".Ȣ.@*`"&'쁡."%Ȣ'܃HH#.@,`."ȢH"H.$Ȧ**`"'́&"ȥ')%('"'$."'*/ 'ԡ"'䟠Ȣ HH"*`*H#("'d,'Ȣ'tȪ"*,`'\H'#@('ĝ"HH**`H"#('l$/ '"+'Ȣ'|)"'lHȽ'dH#"'\'T1'DH-%'<"'$HȢ',#Ȥ/`'<'T"Ȣ'D"Ȣ,`H, H"H'4&H3',4H'Lȥ"ȧ'I7,'$$7H't'L'4'"' $&,I"H$"*3H' * '"I#I3 ȥ "#*`/ # ''쏡H"H'H! ` "'I:Ȣ' %:''"' #I!(I$Ȧ)I"H#$'H* "''''''' "/`+"`"@,`+` H"H9` `HH"+ H , "' H  '쁠ȢH$"'.䭤H!ȩ'ȶH#'̝*̅H"'䣤H쇡HH H&''!"HȢH(''ċ'H'5䍠H"D'\'H 'H#ȥ'(%"=$'HH"&$H#'&'|H6'''t'l!)䍠!&#'d<ldH (H Ȩ̃H '\!(H'D'TtH"!#,'4dȬ!'<'L','$T!<H:!,.#@,`DH @ H"I''I'(I&<'|I&HI#>I"H&I#(I"HȦH$"&' H%H#''̉;"'I0H47 /ĉ! 0$|2I/'< 'H8I8'ȥ'ԁ 80I'$Ȣ"'$ '܉H%'܋I Ȣ"' ܟH, 'H$#TI!'ĝ/I H'!$'d,#I T'\d!'''H''t\HH"'l#"lȢ'T'|!#' |'| 'D!"'<$ȥI '4ԏH I1$LȦ! 1'L%',ȡI $$!Ȣ' LI "ȭ H!H+ ܍!ȱ䍢&!H,H'$,"'$H$+'lȤ!H&''''\!' 'L!''ĝHH!< #'|H$|H"'I#H $H #H4'I$H%I't (+I( '")ȣ../ .H.,`@#' .&@&@|@t @ l@d&@&@.T/ L&@&@D@< @4 , &`$H"&@&@@.  @ !/  /`@ , !..H(&@&@|!H$/ '@I%@  (@䏥I!&@&@ H I 3ȳ'H "@*@4 !.I%'(&@t"** / .#H/` G?{?T1?9>?l^?5fftwi_no_twiddle_32GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4!x  ,D 2   =dBh4JS   $/: EP[fl fni_32.cgcc2_compiled.K195090322K980785280K831469612K555570233K382683432K923879532K707106781*ABS*fftwi_no_twiddle_32fftwi_no_twiddle_32_descd l p t   d h x    $  ( 0  fni_64.o/ 915488332 571 300 100664 11840 ` ELF(t4( 㶠."Ȣ ".Ȣ.) ","..* "Ȣ."Ȣ. @-`) "ȢH"H+'쯦H$H)"H'̯*H-&'ܿ%'<'''$ȧ'|."'T'/ '#''''''t'l'd'\(`"Ȣ Ȣ) . @"- %("-`) -''@"@(Ȣ(`H"H#"'L*  @*(  #&H)H'#H'H+(H't"ȯHȢ'd''L.ȤH*#/"'T'D#"',4%&'4'$'D'l%'\'<''&' | @+ 'H"H ") Ȣ* -""Ȣ- --`""Ȣ#) 9+H"#H/H"H'ȱ'"'1# 3,HH #'13#'ܩ %"HH8%'俢 "('̣ /'/%"+ &$' "'ԣH'''''('(" $Ȣ (#H$H"* #@,("Ȣ+*Hȣ-`H""- $@(H, "ȢH$Ȣ"+H+ ("Ȣ'|H-"'Ȥ' ;%$/H /HH3&H( &H$ ""*; +'#/+'dH('t % <"'\<Ȧȫ '$%'TȢH'#'Dȥ5',H:%'4"'$#'l'<'L'ȴ'<'4','$@/ "Ȣ"Ȣ@+ /`"-*"-HȢH#$@+`"*  &H#'H)H'(#HȣHH1'''"ȤȢ+'܏8'쇣ȦH*/"H#''信"&#'ԯȦ%&'' 'Ŀ''''%'|*' H"@*`H /`H HH"/ H#("- Ȣ" ``*D@("+    &#H)H'H#H1'(H+"HȬȢ'=/'HH*"#H'HH"&H#'|Ȧ%;- T%, (`''t&'d'l"'\'T'Ȣ+` H"H-`L$(`"`' 1'`" H,H#")(#*#ȣ)/%H#'4H+'LH%"H'DȢH$"'$?' &Ȣ?'|7'''4ȷ"(H?Ht*?')H('<t5)&t,\'셦H?'Ȣ\<*"'$'<,ȵd'܇Ⱦ$\Ht$ȹ95\ȼI5ȧI&4''䫣&ȿH#' ?$'ď7H4H5? 7ijȣ4$ 7?ă#܍" ?7"HH1='I8H"H$I=8%HHH"4'HH"''ć5'<78,(?Ȣ?H&'%7"'''|77H|7#'dI%4'($'tD8%'lH,īȵI$ȢI#H"+'ddȴD#ȸHI+'\'Tt4H)='LȾܙ47)>t=&䍤 7H$ȣ?"$7< ?<7̩ȩ̻)$ ?# 7䝣?"0ȷ|ȷ8,t0HH)808ȣ'&#'<'4H"1#',H'Ȣ'l7H8' \(?'"t?H$\?&'H$'47&*'$$$'7"'ȥ$HH+'$'4ȿ"H#$ȿ.ȥ$''"䓤"Ȳȿ%tȿ\$ȿ+''ԇ%0%+) ?ȤI7?"'ħ+I7Hȷ'|ȷHĉ%?ȢI7" ȸI?Ȫ7*H/ȭH-'H)"ȣH'Ŀ="'H'-'H,'Ȩ'T'?l?H3)ȭ'ȥ'(')H",?#?#'"#:$",ȿ&ȿ'L-%'T2&|74@& @ -H, . &@싡H$ T'|ȿ-@l ȷ'D%,+@* 2@܅(&@ԑ&@&@&@@2 @ LT?.. @'t D%&Ȣ@ t?H\'l@l(@&@/`&@쏥?,&@@|&@ ?tH$?ȥ@t #7+ 'd+@, <72 4@ '\,$t&@7#@%@,"$@&@H?&@&@ @7 - @ @t -`7H$- ,$@-'<*&@&@@&@<@ܭ?&@.'ԟ , ́6 @ @ / &@@&@/&@&@@H#D   @'(`@\ȭ+ t'4 |@ +`&@l@d&@&@\@T&@L  d-<"4(`@ @, d&@l$7* /`-*ȣl@$@&@ &@&@@  H% " @ &@,&@H"d"l*ȷ., / +`#"@(@䥢&@&@'`@'`|@\ @&  @("&@&@&@&@@@( $ \@Ƞ @ &@ @ &@ &@&@"@ "`+  (@\+ 4" @ &@Ȩ&@ &@&@ @ $@ |#`Ȧ(tG?{?E?"g=Ƚ6?~m?T1?9?t >1>Z?aŘ>?l^?5fftwi_no_twiddle_64GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4'`!,h  ,' 2.(  ='B'TJ( (!S*,  + $/: EP[fq |$(,048'` fni_64.cgcc2_compiled.K195090322K980785280K773010453K634393284K098017140K995184726K831469612K555570233K956940335K290284677K471396736K881921264K382683432K923879532K707106781*ABS*fftwi_no_twiddle_64fftwi_no_twiddle_64_desc 8 8h 4p 4| 0 0 ,  , ( ( $ $          < @ d h     @ftwi_2.o/ 915488333 571 300 100664 1056 ` ELFX4(  +  *@'`$$'H&Ȣ%"` "  (fftwi_twiddle_2GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.data.rela.data.bss.rodata.comment4! '$ 27? H  R '-= ftwi_2.cgcc2_compiled.twiddle_order*ABS*fftwi_twiddle_2fftwi_twiddle_2_desc ftwi_3.o/ 915488335 571 300 100664 1348 ` ELF4( B + ` ** @I#`"I"#*@$+$H*H()H"I# "HH#"I&ȩ@" ' `"" #@ @@ #`@ ͆ 8?]?fftwi_twiddle_3GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4!0  ,H 2 $  =hBh JS  h $/=CS ftwi_3.cgcc2_compiled.K866025403K500000000twiddle_order*ABS*fftwi_twiddle_3fftwi_twiddle_3_desc$ ( 0 4  ftwi_4.o/ 915488336 571 300 100664 1256 ` ELF 4( O + `* (* *"$$"I$I"I"I$`@H&(@, +H" (&+H-ȦH@Ȫ"&#H$*H ` " H #` @@ H)  #@@ Hfftwi_twiddle_4GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.data.rela.data.bss.rodata.comment4H!| '$ 27 ?H  pR  '-H= ftwi_4.cgcc2_compiled.twiddle_order*ABS*fftwi_twiddle_4fftwi_twiddle_4_desc ftwi_5.o/ 915488338 571 300 100664 1716 ` ELF4( 㿐|..(..` @ #@`I" "I#`@ "`@I##I"@` $`@"'$*"@H -@0@%Ȧ %*-#ȯ.)/&H'@I$"0 "HI&H$Ȣ%$ȥH#I,ȩ-)H,H&`I-"# +("# Ȥ` '@'@'@"'@'@'`&`  *`@& X?>?sxq?yfftwi_twiddle_5GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4!0`  ,< 2$  =\B`0JS  ~ $/: ESYi ftwi_5.cgcc2_compiled.K559016994K250000000K951056516K587785252twiddle_order*ABS*fftwi_twiddle_5fftwi_twiddle_5_desc( , 4 8 @ D L P   ftwi_6.o/ 915488339 571 300 100664 1660 ` ELF(4( 㿐.(....(`$@ 썠$@ I"@(I$"@$@)`"@"ȥ&$@I&@  "`0"1 (@ȪI"-裢 "ȬȤ &,@-ȧ@@&H1'&H-*ȢHHH#H$3,I$#$I&#"0'ȢH/ȥI#H+""HI%#(`()'@ H4'@'@&  H"&*'@'@'@'`@&` h??]fftwi_twiddle_6GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment48!(0  ,l 2X$  =B0JS  h $/=C8S ftwi_6.cgcc2_compiled.K500000000K866025403twiddle_order*ABS*fftwi_twiddle_6fftwi_twiddle_6_desc< @ H L   ftwi_7.o/ 915488341 571 300 100664 2176 ` ELF`4( 㿐Қ...((.(.`@ #@ 蛢 "" #`@ I"@ ` $I$"쟣-@ $Ȩ@ ` "+* $ȥ "`Ȫ@$ȧ`@ #I"@+I$"3@I$@2I"., 6I"I$H52@@$$H*&+3H(2Ȣ$HȭI*H+@I26.I)H#), ,H9*3$$)+6,ȣ $%6Ȧ/$1ȢI/0 -H0"-I4/H1*'H#`*4*I1H4'4H& 01 '*-*-ȭ0Ȱ?  0H"`0'@'@ '@ ''@'@'@'@ '`&`&  ȯ &+`@I&x>c܇?f?>&?y?H&fftwi_twiddle_7GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4`!  , 2\$  =B@J S  8 $/: EP[io` ftwi_7.cgcc2_compiled.K222520933K900968867K623489801K433883739K974927912K781831482twiddle_order*ABS*fftwi_twiddle_7fftwi_twiddle_7_desc0 4 < @ H L T X ` d l p 0 ftwi_8.o/ 915488345 571 300 100664 1764 ` ELF4( 㿐..!(.(.(.(`$@ $@ ""$`@  I"` @ $I$*@ "쥤(@ I$Ȧ@ "`.$4I"@ $@ 藢3`I"+"HȫI$@ ` &`H6@  "% "3&৤H$@I"@H+I+4("@-@@8%3%+6-Ȣ$Ȥ#5,H*H$(H.,H+9$#ȫ"H&/H#"ȯ 8`8'@ '@&`& ''`"&'@ '@ '@ .'@  ,`'@'@@&d' ?5fftwi_twiddle_8GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4!  , 2$  =(B(0JXmSx  H] $28H ftwi_8.cgcc2_compiled.K707106781twiddle_order*ABS*fftwi_twiddle_8fftwi_twiddle_8_descH L   ftwi_9.o/ 915488349 571 300 100664 2584 ` ELF4( h.((.(.#(.'.'.'`4''@?ܣ$@`?"@ ?I&"$@ ?ԥ /@?$I$ȣ&?@ #H"?ض@  "H' "H-=?@ " "#@ H )@ `5 $H.$)% /'7H@#*"$4@,ȸ?а@ "7"#?@ ,"?䥤$@ I##(I"@ =$@ 9?-Ȯ4-H$H(H")#"Ȩ#"7$ȷ&Ȣ$:#"/Ȯ",̧# '"+셠 6`D?|\>1??]fftwi_twiddle_9GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4! 4  , 2 $  =BPJ(=SH@   $/: EP[fq  ftwi_9.cgcc2_compiled.K642787609K766044443K939692620K342020143K984807753K173648177K500000000K866025403twiddle_order*ABS*fftwi_twiddle_9fftwi_twiddle_9_desc@ D H L P T X \ h l x |     @ ftwi_10.o/ 915488353 571 300 100664 2372 ` ELF4( h.(..(.(.("(.'`<'@`?苡"@?䓡 ## "?@#?@"?@&#"@H%#@@?ȹH "H)`#:H0" @ # Ȫ@I"H- ",I#@ H?̙$@?H+"Ȩ")(&@ ?н`I"ȣ2>1"ȮI$H6@  ?ة"?ԏȭ@ '졢I$7.$HI"?'̻3@ $?@ 1I"ȳ"HI$.'@ ? -@ $+H" $H-Ȧ8H0&1;#)ԅI2( "ȨI*2܉I$H0I"̥= **ȢԕH?I2%I." .̗Ƚ 4:ܛHI+"I4ȫԝI*# 'HI'+ܛI-"H*I/H$ /Ȧ/'I5䏢H= ,HԉI'䓢H 5셧HI,%ܓI)5H"쏡=` HȬ H @ @ @ @ @ '`& # ' & @" @ @ @ @ `#&&` -`@  ?sxq?y>? fftwi_twiddle_10GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4|!`  , 2 $  =BIJ.S<  < %0; F$TZ|k ftwi_10.cgcc2_compiled.K951056516K587785252K250000000K559016994twiddle_order*ABS*fftwi_twiddle_10fftwi_twiddle_10_descP T ` d l p x | 8 ftwi_16.o/ 915488356 571 300 100664 3248 ` ELF $4( X''/`'l/`'T/`. '?l^?5 fftwi_twiddle_16GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4 ! DH  ,@ 2 $  =`B`YJS   v %0; <IO ` ftwi_16.cgcc2_compiled.K382683432K923879532K707106781twiddle_order*ABS*fftwi_twiddle_16fftwi_twiddle_16_desc     H   ftwi_32.o/ 915488360 571 300 100664 7148 ` ELF4( 㹈''܀'-'T-'<-. ',-'"(' . %('-%*`'-%@+'ܕ. 'ķ-.'+'.'@('+'('t. &* '\.'@(' .'('ԓ*`'* '+'. '.'@/`'/ '|.'t`d'D('T` #` I" "I#'L< $ 'Dؙ"")D`T$'4, , +`X "ȣ ")` +.'$ '\ *% "H#`"H`L% 2'\' '̔ I#%'`PH"\H$I"'('āH$` #쵦' I$1` H"ȨI"ȧ'$' '( 'С,I"H'I(/"0' ' "#'- "'' ' '􍡈 %''$")1 "Ȥ%# '|`8 Ȱ"`4$'$H'H&" 2`t'd) -`x$0ȧ$H&)H/Ȣ'l$&'HI"Ȩ"'tH/`,I&(' ȥI$`0 +"('\Ȧ$#'T'|I"'LȰ'Dt'<`lH #'4`p1 "#H/`l'l\I", ','dd# '$)쏡 +H(+H #.'I#H'"H, "%#`d '$ '#''T`$`h "1".' #`$$ I%Ȩ `I"'LH*`("'4 %'<''$ ".', 䏡I*,H *&싡I"0' &H'# 'I"HȰI&'쇡H"ȭ'􁡈  `\H+  $'䍡#``$"'܍H)1 "%(H$` `"'ԁH'H3 $'$'H''ܑ ".' +) `'I"Ȩ'"(I)2`  "`H# '6'HH$`D"H %, Ȯ"'`HI"`#' $ȣI% 'Ȧ "4`'ęI"&I$ H,+ȯ- '$ȥ$&+2Ȣ$Ȫ Ȥ&' `*' "''"%'# &`@ȧ  "Ȭ`< I&( &*'|'t!I"|`|Ȩ I#` `H".I"ȩt#6  @)% 'l,2H%(,Ȣ$H&H#H6-"H6'd('T\H '\H "|H 4H &H H$t H HȦH'&Ȣ#,$'L'DH.'<'4','$\H|ԃH!'H4H'%ȡHH#t H*$DI#ȣ#I"' 'D* #% 0'.'' !ȤI6ȱ"'1 6''HI ȧ''HH-'H"'Ȥ<'H4''|쵠H'tD'lLI 'D4I "쇠H2ԅ3DdI Ȣ'dDT !$,L!DԋI$ܭ6䕢 "'Dl !ĉ D$!'\ 䃠H 0'T'LDI2L LH'<'4Hl H%ė! #䉠H "','$ĥ! %I$H-';#ȳ"(Ļ#ȫl"'쇠H $''HI%I#%샠H " #'(lH I"H3#H5H%H%H"=#'ȮHH)"%ܔH$' ,'܉!H#',LH!D! <"<4! ,L! "$4'"$" ! ! ""! ! ",$Hԅ-"! "! |ȡ! td! \' T" &L#G?l^>?5 fftwi_twiddle_32GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4(!  ,\ 2$  =|BJ)>SL0  | %0; FQ\g|u{( ftwi_32.cgcc2_compiled.K555570233K831469612K980785280K195090322K923879532K382683432K707106781twiddle_order*ABS*fftwi_twiddle_32fftwi_twiddle_32_desc      l p x       ftwi_64.o/ 915488372 571 300 100664 15100 ` ELF5 4( X''܀ '-'-' -'('-'Ԡ'̡, 'ą-(', ', '('d'$'T, 'L&, '<-'t$('-'$('T(, 'Ą$(', '$('-'$', '', '. 'T, '`, '̅(, 'L't, (''''|'$`I#`  " #I"' I# "#4'I"I#8 "#I"`4'#`8 I"(I#Ȥ/"'H #H ` "1'&, "ȥ #`ȫ' "H/`+"&H%2ȣ H`$%$H1H42'&|$H#I$0I2,H.27'H"I,H'|#ȲI#HH Xȹ't'& "H#%'Ļ#T "ȤH''l %d3`T')#`X'- "'\4"L'5`Ԡ#'Ȩ'D'H6I&`رH I#Ȣ(I#"I&<Ȫ''|'3 ؑ"*H"('Ȧa '4䉡+ 'Ha "H#'5'H "` 'ԇ('`H I"%'tI''l'\`'̷4"'dH0' &'<; `ЧI"$I&Ȥ "'T# &ȣ'LР '"''#H23 "&0 "1*I"`'|, I#'@( ',I"`(#'I#'D1''lĝ"$' L'tȥ#'dP/ ""8`L.#, $(-'\ ( Ȯ`P"(H* ",%'L'I(0 I"0'죤I"`,'Ȱ̫I(, &$, '컥 %)`0'ܠ H"'̻#%ȩ'T'ĩ "' /', 'l'$H#' pI",ċH", ''&/ I$'`p I"`lȭI#''I#', &@I",',H#' ȫ' "''+'"H'ܠ', :' #''D''|``H ;, &-  "ȩ`앧*"쁠='#'dTH!,  #&H>+`'\&H "2Ȥ"H%&'T| ȣ "` "ȧ,'L"H''t'l'D'|L=)'<|>I"ȰLH<=Ȭ',|5#% ;+'$#HI2'4|2'Ȩ"''I;9' |DI$#$'<|ȢI;Ƞ쁧H4|38'''4'`(,  #'T=, I$6"',`H>"'$.l#H'' ȮI"t, 0 %6"'$H>  "' 'x)ĝ ", '`t&HI34 %.|< -`x##H%&ȵȢ$I<HI%56H'|I%ȢI$H/'6H#''I)"'I$ 7|H#I)a'܇ȱ '̉Ha'|'l$'tI#D 'd< ")' #'\'T4,=I"`9'L$'I#` I"H2'DI"+`7'`'I#8  '< H!"` H#H&2+'$#'',('4"'&Ġ' ԏ$ H'̗"6ğH$'"H'쟣 $+  "'1 "'Ȧ $`'|t'䫣I% ` "#3 %I"'DH)'l%5'd H"H3"ȵ%,-`D)0`H %%().Ȣ$Ȥ2#'ܻH'\'̻H"$H$ 'Ļ*('Գ#$'ȸ'',#H9`(*'$ȳ' *"`$#'H6#'ȱ'H,. "'/'`#7''  `虢ȨI""'t, '䏡 %ȮI#(' -" "'|#'̽", %'L #''< 5 " #'T' "`+#3`' 'I"$I#d"1''D#' -h"4"ȥ@'4.`1#'Ġ ȴ`h%+`d)H.)%(Ȣȭ$-2#H''L'DH"$ԠH #'<*' #'|Ƚ$` '䉥+   HI" ',*`I#8I#'ȷI"'H't,'4'$' /*' H1`ܠ  #ȯ`'(I"'4H7I#**"+'4%>'l ȩ"' '0$5"'|'dH9% ''  "H6"Ȧ $@`*` ȣ'\ %  3` "# %-'T "L4\I&'D -`"ȴ,I"\&`\0* )`` H.&H&($)ȢHH5H#"ȥȢ'#H+<'<\%I#@'Ľ& '̻ "ȥI"'H #.'`@ H"`<*'I#H+'/#HI"''H|, ' $') '쫣"'ȧ= "'@H('4$H5 `H>"2`|', #H0# ".`'H#'䡣H "H4`H%"''$ԻH)(H#`.I) 2`"$"H.('̝% I"aȥ ". +2'' 'ĕ& )' .@%HȮ%)+$ȢȤHH=H#"H1H'tI&ȶ'l|#"' H&H|I#H,"H*6I#H'/H5I#H'\|'H'dH.'T!|I#H!"I04I-H|Ȧ-H'TH>$I0H"Ȱ='L'D'<"'4','$'tH>ďH(|:ȧ<H>&#L'D=ԇ=#tĉHH>H$="t1=H,>H)H,$H''(*'+Ȩ$I"H$#H"'t$>'d"H'LH1'T$;I"'lH&I#'D)'4H'$T'ȸ|$'<:'=|'# lH'|"I#̅$'='\=|#I$ l=|%"',HȮ|.I$#<%Ȳ|I32H17HI$":#$H)I"H*$('I3H|7(ȷH#'$I4$H' #1I+ȢH4''-'+ȭ'쉡"$I'4$ I>'$,TI>/'l<$'D=H#'\4$='''''t$='ܽȢ'\H$$I>'|lH"lH!H%'% 'ܓ'$Ȣ셧$)H%"T4H)$4I>"''$H'H$,I>H#'L'HI''H$I,%'('I,H'|ԉHH&T4H#H",LH(|I"%,I#0I%-"#/&H|$H:ȥ&"$+Ȣȧ"H#'tH=H$H'l"#'\Ȫ'L='T,'D&"'<HH>',"H#'!!| 'd!'t'4d'$!lt!d4$ \"D$ L' T! $ D$ <셠$ 4l'$ ,\$ $L!4<=!! !l!􏧈=!$ $ $ $ !H!'t!=!$ $ $ \=|lH>$ !H'&H>$'* ܏$H>Ȣ&쉧H>%)H>4$TH>"H)H>H0,$LH>HȬI'% ",0'애Ȧ 0#$I"H'䡧 $=H04T= '/H> 1LH=䋧$H #" $H!H9H(#"ȤH 9Ȣ1H)H'ܑH*"'셧ȧ$'̻">'H'đH-H$'H0'Ȣ'"' =$"H'I>H%#|'|'=<=H't=|,'=.#$%Ȧ''l'd=D=|<=d=|ĵ=$#"|\H>$I"'=䏧H$L=(H$'H#'T䏥'"")l"\'\H>(9d51Ȩ$I"#1I&$"̇H1-#H&-H$#H,$-HH01HH$H"HȣH?H'H$'L"ȹ',\H/'4H'|4I> H'䅧I>TH$,%'D''|=HD'ԋ4=l\"=H$d&HH(5$'|=5%H0 LH%4"H' d"ȱ$$#Ȥ\/|H/*$I1$0/)H$H#H11ȩ##/ȦH'1ȢH#"H-H$HHH4H#'ĽH"'4'̉,'1'H'$'tH"I>',"$'d='$$*L=.'d:$'T#'T$'I>'''|'l'\'$HdH$I>'dHtTHH\'L䋧ԏ$,$H"'䅧"$,=&#H#'$#=H4''|D,"|$4=(%''$< &$ %$$= )#')䣧"H)ȱD$H4ȯH䏡/I&H!< "(" #H-#. ( 䁠$LH9 '"H'H6 $,'DH'H>ȩH#I&2$<=Ȳ%H"'#ȶ|H2"%'쥧#H"đ7I(6#'H"I#Ȭ('܇܅Hܠ? ȣ''tl#!!!Hd'\!$ T$ L$ D<$ !4\!,$!!$ $  $ $ ! !=L!!d$ l$ D$ <$ ! ! ! !|\$ tT$ l$ dt$ L!D!<!4!,$ $Ȳ$ ,$  *$  $$!Ȣ!䷦Ȥ!"!,H$ 3$ 짤Ȧ$ ܉$ !0!t"!셧=!$ $ |$ l$ |! t!l!!d$ \$ Td$ \$ t4!,!!$!#|$ l$ '$ ܡ" $ T!ą!!"!d$ L$ $ Ȼ$ \!!!!T$ d$ $ H-$ |!H8!!H)!$ tH$ $ $ a, @?=Ƚ6?~m?E?"g>G?{>Z?aŘ?t >1?T1?9?5>?l^  !"#$%&'()*+,-./0123456789:;<=>?fftwi_twiddle_64GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment43!9ph  ,34 2:$  =3TB3XIJ44S6  8t %0; FQ\gr }$(,048<3 ftwi_64.cgcc2_compiled.K098017140K995184726K773010453K634393284K195090322K980785280K471396736K881921264K956940335K290284677K831469612K555570233K707106781K382683432K923879532twiddle_order*ABS*fftwi_twiddle_64fftwi_twiddle_64_desc 8 8 4 4 0 0 ,  ,, (4 ( $ $    h l "P "\ "p "x # #  # # #( #, #0 #4 8?@ABCplanner.o/ 915488382 571 300 100664 6380 ` ELF 4( x  ?? *`@&@@" @  @  #\#`  @ &#\@ @d@  )?聨 -?蒤@d@      7'-` x  \`#\#`#d@ -0m@  @@0a@#\#`@u @``@@@0C     2`   `  @ 2 쀢 " ` ` 2`쀢@2`@2 ` $@ `2` 㿀'  \ 5` 2,  2( 2$@  @@`  <` @`@@<` @ 2  `P ` 2H` 2D`@ 2= $: @"5@#\#`@ @``@@@`  <` @`@@<` @`2`    ~ @@ ` `  ` `" `2` ݐ@#\#`@W@ @ @`  7<` @`@@<` @ c&@ @ @`  <` @`@@<` @@@ 㿈\`@"#\@#`M #\#`Ś@  #\ @#`㿀\`7 @@"#\@#` #\#`@  #\ @#`@ @㿀M@,`` ,` `8 @@"#\@0&#`Ú  #\#`; @   #\  @#`@ @@0A` `8 @@"#\@0&#`   #\#`  @   #\  @#`@ @㿐@B_ _ Ae@?6C-bug in plannerGCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.bss.rodata.comment4 H! , |2 |7 ??  H  |R / >FtU[amw|,BWcx D*6@ 4planner.cgcc2_compiled.fftw_measure_runtimeplanner_wisdomplannerplanner_normal*ABS*.umul__floatdidfgethrtimefftw.rem.divfftw_wisdom_lookupfftw_make_node_notwfftw_make_planfftw_use_planfftw_make_node_twiddlefftw_destroy_plan_internalfftw_configfftw_estimate_nodefftw_pick_betterfftwi_twiddle_genericfftw_twiddle_genericfftw_factorfftw_make_node_raderfftw_make_node_genericfftw_diefftw_lookupfftw_insertfftw_wisdom_addfftw_create_plan_specificfftw_make_empty_tablefftw_destroy_tablefftw_complete_twiddlefftw_create_planfftw_mallocfftw_freefftw_destroy_plan   $ < @ X \ l|  (0 4 < @ P (d ( $`|      , |    (\x    Hdlt    $< @ L 4Pt  0 ! 04"H#$ & (" < # $ ' ( * H& X" l # $ ' ( + T& d" x # $ ' $( 8twiddle.o/ 915488384 571 300 100664 2896 ` ELF4( 㿀'Ā` ?@.  '荡B?@@&@&``0` 2G`` `@@* @?3 ) @@'B?@,@&@$@ܐӦ J@ `  2 6 :   @   @@* + 6$$@`,@@'荡B?@, @%$ ڤ 㿐 821  @ %`" `@ `@ `@`   `*`  @ &   "   &  2@ && @"&  & `& "`㿐 ? &  `@2  "@ "@ @"@02@@ compute_twiddle: invalid argument @!`BUG in fftw_destroy_twiddle GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.bss.rodata.comment4! L ,27U?MbH<`   /6<AGLX\`i{H4twiddle.cgcc2_compiled.fftw_compute_twiddletwlist*ABS*.div.umul.remfftw_malloccossinfftw_diefftw_twiddle_sizefftw_create_twiddlefftw_destroy_twiddlefftw_free ( ((dx   ( Ph      (T l         ( L P \ x   8 8executor.o/ 915488386 571 300 100664 3108 ` ELF4( 㿐   *  &" -@- @``` `` ``-`&  "-&  @"* &"  @* &" .@ ݲ` 㿐 "  8 `00 @@@  , @ ,` @Ӱ  `@@0W @@@  , @ ,` @ `0- @@@@  , @ .  |`@ `0@ 㿐\` ]`$   `  0@- J `n@0j ` c  /` @0V@-  @` , ϖ`@`8@04`2   0)  #   ,`,@  @0  ,` ,@ ۚ @㿐 %      0@,`   n @0   FFTW V2.0.1 ($Id: executor.c,v 1.62 1998/09/28 19:18:53 athena Exp $)BUG in executor: invalid plan GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4!   ,2   =BgJ/DS P0    !.4FK\`il\nzexecutor.cgcc2_compiled.*ABS*fftw_version.umulfftw_strided_copy.divfftw_executor_simplefftw_diefftwfftw_mallocfftw_freefftw_one\   8 Hd x    , <    \` Ht\generic.o/ 915488387 571 300 100664 1628 ` ELF 4( 㿐@. E@*   @*(%(  *`@I'@ #I#'H&H"@@%"@## `@ݘ  (@ @`#`@# ` Ć@㿐@. E@*   @*(%(  *`@ '@ & &H#'H%@@""@## `@ݘ  (@ @`#`@# ` Ć@GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.bss.rodata.comment4p!x ,27?H  |g  &8;GQ88generic.cgcc2_compiled.*ABS*.umulfftw_twiddle_genericfftw_mallocfftw_freefftwi_twiddle_generic  H L ( < X   ` fftwnd.o/ 915488390 571 300 100664 11080 ` ELF4( x`  0p  `, @ @ `   ?? *`@&@@" @  @  #\#`  @E &#\@ @d@  )?聨 -?蒤@d@      7'-` 㿐   @ `@ (& & & & & $& & && & 0 ,@& @& @&    " $? ,"@ @@?$$*` @ $@ @, $@㿐. @    $  "@`@ &"@㿐` 2 0 -  ?  @*` ` ?` *`@@  $@  $ ٢`㿐 ?@   * 4 &  . ? 4@. 㿀'쀦` `d @@] Z @   * @ 4`@ &@` ` .`? 4`@*`3 * .` 쀍 @ #\\@h@#\\d@& Հ`@`''Җ   . @ l \i?. @      "@`@ &"@ 7 4 61%`?  ? @*` ` ?` *`@@쀢  $@ %`$ ٢`%`  %`%` `?@ x  * 4 &m ?@  *  4 &  . ? 4@  @  %` 2 %`$@*  %`$0^%`$. @      "@`@ &"@ 5 1 /? ? @*` ` ?` *`@@쀢  $@q  $ ٢`. @      "@`@ &"@ ` 'h @L@a ^ ?   * @ 4`@ &@   . ? 4 @* 5? * '̻. ̀Ԁ @@ #\@@`@#\\@% ̀@ 2 %`@@ޒ0%` ?@   *  4 &  . ? 4@*` %` \`%` %`?ؒ ?@   *  4 &  . ? 4@*` %` \`؁;%``$ %`@%`$@~ `?@    * 4 &  . ? 4@?*` %` @*  %`$@v @N㿀? \`#\#`x?'\ `d#\#`ٔ㿈#\ #` ̚ 㿀?#\ #`   x?'#\ #`   㿐`  @ `*```` @@ @㿐 ? !  @ `*```` @@ @  " @  " @  " $@ $ @@㿐``` @`0W@``  %# ``,  @ `  @``@``@`` ''% `@? *`@ `@`@`` &`㿐 㿀'\ / ``. &@@ * 5 +`+  "@"`@"@"`@"@"`@"@"`@6  "@"`@ К@ #\#` @ 66 +`+  @"`"@@"`"@@"`"@@"`"@6  @"`"@ К@&@y&@㿈\  .`  @ -  * @ @ #\#`@4  @ @#\@#`@  6  @, @#\`+  @ ` .` @ #\#`@0.` @#\- @ #`㿀`h  .`  ?@J@  ! 6e    @ * @#\#`* @I 6F    * @, @#\d#`\+`@ $  6   @, @* `\#\#`d#d#h@   4.`@  , \d  #\@#`0.`@-  \,  d  #\K#`㿀\ ` ` $ 2 $@*` $ I   #\@#`:  #\@#`/ ` #\#`#d#h   6   #\ ,` ,@  @  $ @㿀  `   $ 2 $@*` $ 2      #\@#`#    #\@#`     #\  ,  6```  $ @B_ _ Ae@?6C-plan for rank 0 (null) transform. plan for %s%dx transform: -- using buffered transforms (%d buffers) -- using unbuffered transform * dimension %d (size %d) plan is same as dimension %d plan. GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.bss.rodata.comment4!%<  ,27 4?TiH D  "W ,28D[el@(T|\ $0@l T<p@44h8<x$P).t9TL<fftwnd.cgcc2_compiled.destroy_plan_array*ABS*.umul__floatdidffftwnd_measure_runtimegethrtimefftwndfftwnd_create_plan_auxfftw_mallocfftwnd_new_plan_arrayfftwnd_create_plans_genericfftw_create_planfftwnd_work_sizefftwnd_create_plans_specificfftw_freefftw_create_plan_specificfftwnd_create_plan_specificfftwnd_destroy_planfftw2d_create_plan_specificfftw3d_create_plan_specificfftwnd_create_planfftw2d_create_planfftw3d_create_planfftw_destroy_planfftwnd_fprint_planfprintffftw_fprint_planfftwnd_print_plan__iobfftw_bufferedfftwfftwnd_auxfftwnd_aux_howmanyfftwnd_one  @ \ ` l p        0 8 < t |   ( ( 0 0 lx  0    Dx   (  L  D     4  |  T H\0H`h 8! 8 `! ` p p x  x !  !$ 8 <!@ L P!T h l  !"!  $ $ ` h& &  <&d |  &  &< T &  H & <&&(&T&malloc.o/ 915488391 571 300 100664 2148 ` ELFl4( 㿐 ` @ " @@ 㿐   `@0@㿐 `!@! @ `@@ 㿐  !   ! @  @`@ fftw_malloc: out of memory fftw: %sMEMORY LEAK!!! node=%d plan=%d twiddle=%d GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.bss.rodata.comment4p! , 27\? !H   0?MTY`TiT<sx~hmalloc.cgcc2_compiled.*ABS*fftw_malloc_hookfftw_free_hookfftw_die_hookfftw_mallocmallocfftw_diefftw_freefree__iobfflushfprintfexitfftw_check_memory_leaksfftw_node_cntfftw_plan_cntfftw_twiddle_sizefftw_print_max_memory_usage  0 @ H ` d                  $ (4 08 < @ D H L PT 0Xwisdom.o/ 915488393 571 300 100664 7792 ` ELF4( 㿐\``/d*`2# 2 2 2 2 2 "@   @! 2 㿐`E`C  *` 2"  2 2 2 2  2 \`" "'\'`2 @ $"" " " " " \`" " " "㿐`     @$  2 !$  (  *`:  €N  `!%  € ( €p@@Op  pN € N   €p`@Op  pN € N   €p`@Op  pN € N   €p` @Op  pN € N   €p`@Op  pN € N   €p`@Op  pN € N   €p`@Op  pN € N   €p`@Op  pN € N  ) €` `O ` )€㿐  @  + '? `@` % $ @ `#` -'?%@` $`"  @ "'? `@` % $ @ ` @  ?"` +)? , @*```€@ ` $`% @ @p#$`!$ ` "?$  @ " ?  @` $$ @   @ ?) %  @` $$ @  #`?! (o?%@` $ ?$` @ ?  @` $$ @   N /# )%?`    @` $`$ @  ?`N 2&? @$`  ($ N ` @ ) %?  @` $$ @  ` )1) ?``   @` $`& @   ?q` (2۰? @$`  (&  ` Z T  M  F @ :  3``   @` $`& @  ``   @` $`& @   ?` ) m?@$`  (& '而F'쀌C  * 2"  2 2 2 2  2 " "''쀢2 @ $"" " " " " " " " "``   @` $`& @  ` ) FFTW-2.0.1%dGCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.rela.data.bss.rodata.comment4,!< (  ,`2d  =p4BpJS  D %;@IS ]0io$@<TLwisdom.cgcc2_compiled.wisdom_listWISDOM_FORMAT_VERSIONemitread_intnext_charget_inputinput_error*ABS*fftw_wisdom_lookupfftw_wisdom_addfftw_mallocfftw_forget_wisdomfftw_freefftw_export_wisdomsprintf.umul__ctypefftw_import_wisdom         $ @ D T \ l            $ @ ` tx        < \ pt       8 X t x       0   0      8 < 0@ 0D H X d 0p   0      0 0  0    08P T X 0\ 0l |  0      0       0 4 8 0H L 0P 0\ ` p t   0      0           0 (  8  <  @ \  ` 0 p t 0   0         0    0 , 0  4  @ 0 D P  T  X  h  l  p  0 0   0 0 0  0 4 0 P 0 h 0 0 0           0           <  @ 0 P T 0 `  l  0 p  t            0    wisdomio.o/ 915488395 571 300 100664 1988 ` ELF4( 㿐@ 㿐@ ?㿈' @@ 2'  @ @ 㿈 ' @?㿐@? &@. : @0``&`*@㿐? & `&  @@@"@@"@(@(H "HUnexpected output string length!GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.bss.rodata.comment4! ,27!?)>H  / H(8@7xHW,hn  ,Lp4&wisdomio.cgcc2_compiled.file_emitterfile_get_inputemission_counterstring_emitterstring_get_input*ABS*fftw_export_wisdom_to_filefftw_export_wisdomfftw_import_wisdom_from_filefftw_import_wisdomfftw_export_wisdom_to_stringfftw_mallocfftw_diefftw_import_wisdom_from_string__flsbuf__filbuf  , 804 8T xX x\h     dputils.o/ 915488400 571 300 100664 7720 ` ELFH4( 㿐@ " `" " 㿐@ " `"" ``"" " 㿐@ " `"" ``"" " 㿐@ " `"" ``"" " 㿐@ " `&`& ``& & & " &@& & 㿐@ " & & & `& & & " &@& & 㿐@ "  && & &  `" &@ & & 㿐@ " ``"@ 2 @  && & & &  ` ' @ & & 㿐 k ? f& `\ *`  "I @E  "A @=   " @ 2 ? -$     `  `@ `"  $`" @@ @ @    " @ @`?"`㿐@ ("" " `&" " " $" " " " `"㿐`H *`    @& @+   #    @ & @          @& @   " 㿐 ?  & $ @""`"@"`"`"  2    2㿐 #  ?  &  `@$`2 㿀`g *`  ?'@ BOB  ?' BD+  ?' BD  ?@'B#F  . * 'D@  ?@'BF㿐 `%# ` =` ? & f @"?  &`X`@"㿐   @ @  㿐`c@`_ *`  ````@0@``@4`)```@%``! `@``@?` ` ``@`㿐` @`` 㿐!  @`   invalid size for rgeneric codelet invalid Rader data pointer ??@$Dx@%*sFFTW_NOTW %d %*sFFTW_REAL2HC %d %*sFFTW_HC2REAL %d %*sFFTW_TWIDDLE %d %*sFFTW_HC2HC %d %*sFFTW_GENERIC %d %*sFFTW_RADER %d %*splan for size %d convolution: %*sFFTW_RGENERIC %d plan: (cost = %e) GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.bss.rodata.comment4 4!@ , h 2 t7 xs? H  x & (17ES(bn(|8@x@@|tpd2;J_\@zX4L H \h "' \3; 0L 8\b ,putils.cgcc2_compiled.destroy_treeprint_node*ABS*fftw_node_cntfftw_plan_cntfftw_make_nodefftw_mallocfftw_use_nodefftw_make_node_notwfftw_make_node_real2hcfftw_make_node_hc2realfftw_make_node_twiddlefftw_create_twiddlefftw_make_node_hc2hcfftw_make_node_generic.divfftw_make_node_rgenericfftw_diefftw_rader_topfftw_destroy_twiddlefftw_destroy_plan_internalfftw_freefftw_make_planfftw_complete_twiddlefftw_use_planfftw_make_empty_tablefftw_insertfftw_lookupfftw_destroy_table.umulfftw_estimate_nodefftw_pick_better.remfftw_factorfprintffftw_fprint_planfftw_print_plan__iobfftw_sizeof_fftw_real   <L X d |   $ D X|    $ 4 Hlx |    4 L8 LLPlTX\`d|h||  ( (,0 (L P \dl      ( @, @@DD`HLPDTDX\t,|    @ LP x | T P P X X P P X X8 P< PH XP Xh%| ` ` ` `% ` `  h  h t x   % ( D \ H \ \ | ` d h ( l p t x  p  p      *     *       *  ,  0  8 < D* P  T  d*  H  H  *   ` *  ` -  -   ` *  `rader.o/ 915488405 571 300 100664 4580 ` ELF |4( 㿐`` 6`@ :`@@p?'ą¶ '@ @ $ @'` @@@ 2@`@&@?@ ?  2 :`?@@?,`@?@@'Ĩ  *?'?'荡B?@؁@䅠"$@?Ѕ@¦@$@ߤ?  @ @%@%`%`%` %`%` %`%`@ %` "` " ` " ` ?"` `  "`` " ` " ` " P'''ܠ@, ` '`  '`@-  @"@*  &  " "&ȥ`#Ԡ $$@@@@ @" & "  @' & `,`  `'@?*  #I#` "I"#@&"`'&`"`@ @ @ܤ@*&  `̐  @"@@ܑ(.?'&u @P'''ܠ@, ` '`  '`@-  @"@* $  ""$%`ȦԠ $$@@@@ @" & Ȣ  @' & `,`  `'@?*  #I#` "I"#@&"`'&`("`@ @ @ܤ@`*&   "@ @@ܑ(.?'&v @㿐@ &&    & ?2 2  "ΐ`""`& & @ "&   @& non-prime order in Rader couldn't find generator for Rader ?@!`GCC: (GNU) 2.7-96q3.symtab.strtab.shstrtab.text.rela.text.data.bss.rodata.comment4 ! , 2 7 \?  1H      l"l39?DMYjnrLrader.cgcc2_compiled.power_modcreate_rader_aux*ABS*.umul.remfftw_diefftw_mallocfftw_create_plancossinfftw_executor_simplefftw_freefftw_twiddle_raderfftwi_twiddle_raderfftw_make_node_raderfftw_make_nodefftw_rader_topfftw_use_nodefftw_create_twiddleP X  H H      < @ D    P P@l  `   $ T @`   D t   \  8 @       @ D L X tboinc-app-seti_8.00~svn3701.orig/splitter_fft/uttolst.h0000644000175000017500000000014512111524644023106 0ustar locutuslocutusdouble tm_UtToLst(double ddtime, double longitude, long mon, long day, long year); boinc-app-seti_8.00~svn3701.orig/splitter_fft/angdist.cpp0000644000175000017500000000314112111524644023353 0ustar locutuslocutus/* * 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 #include #include #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 * * */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/validrun.cpp0000644000175000017500000001144612111524644023555 0ustar locutuslocutus/* * 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 #include #include #include #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) && (iframe=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; iframe+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 * * */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/hr_min_sec.cpp0000644000175000017500000000644512111524644024042 0ustar locutuslocutus/* * * 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 #include 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 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 * * */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/makebufs.cpp0000644000175000017500000000700012111524644023515 0ustar locutuslocutus/* * 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 #include #include #include #include #include #include #include #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 * */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/mb_validrun.cpp0000644000175000017500000001165212111524644024232 0ustar locutuslocutus/* * 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 #include #include #include #include "setilib.h" #include "splitparms.h" #include "splittypes.h" #include "splitter.h" #include "message.h" bool valid_run(std::vector &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 0) { for (i=0;valid && (i #include #include #include #include #include #include #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= "\n" " 0\n" "\n" "\n" " \n" " 0\n" " work_unit.sah\n" " \n" "\n"; const char *result_template_filename_id = "result_0.xml"; const char *result_template= "\n" " \n" " \n" " \n" " 65536\n" " http://setiboincdata.ssl.berkeley.edu/sah_cgi/file_upload_handler\n" "\n" "\n" " \n" " \n" " result.sah\n" " \n" "\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;itm_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 * * */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/message.cpp0000644000175000017500000000324212111524644023350 0ustar locutuslocutus/* * 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 #include #include #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 * */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/mb_angdist.h0000644000175000017500000000146512111524644023505 0ustar locutuslocutus/* * 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 * * */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/cmap_interp.cpp0000644000175000017500000000171012111524644024223 0ustar locutuslocutus#include #include #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 &map, seti_time &t) { std::map::iterator above(map.upper_bound(t)); std::map::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; } boinc-app-seti_8.00~svn3701.orig/splitter_fft/readtape.h0000644000175000017500000000415412111524644023161 0ustar locutuslocutus/* 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 * */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/squarewave.cpp0000644000175000017500000000452012111524644024107 0ustar locutuslocutus#include "sah_config.h" #include #include #include #include #include #include #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;writtentm_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_file, &data, 1); } time0+=(1024.0*1024.0*4.0/2.5e6); } } boinc-app-seti_8.00~svn3701.orig/splitter_fft/db_fns.cpp0000644000175000017500000001356212111524644023165 0ustar locutuslocutus/* * $Id: db_fns.cpp,v 1.3.4.2 2006/12/14 22:24:37 korpela Exp $ * */ #include "sah_config.h" #include #include #include #include #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;iwuinfo.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 // * */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/polyphase.h0000644000175000017500000000140212111524644023371 0ustar locutuslocutus#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); boinc-app-seti_8.00~svn3701.orig/splitter_fft/wufiles.cpp0000644000175000017500000005222712111524644023411 0ustar locutuslocutus/* * * 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 #include #include #include #include #include #include #include #include #ifdef HAVE_ERRNO_H #include #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 int wu_database_id[NSTRIPS]; static std::vector 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(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(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;jst.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;ibyte,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,"\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;i0); 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",tmpstr.size(), xml_encoding_names[encoding]); fwrite(tmpstr.c_str(),tmpstr.size(),1,tmpfile); fprintf(tmpfile,"\n"); fprintf(tmpfile,"\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 * * */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/makebufs.h0000644000175000017500000000141112111524644023162 0ustar locutuslocutus/* * 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 * */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/Makefile.am0000644000175000017500000000324212111524644023254 0ustar locutuslocutusCC=gcc BOINCDIR=@BOINCDIR@ INFORMIXDIR=@INFORMIXDIR@ SETILIB_PATH=@SETILIB_PATH@ SETILIB_LIBS=@SETILIB_LIBS@ SETIHOME=.. LINKOPTIONS= DBLIBS=@INFORMIX_LIBS@ -lm -lstdc++ LINKOPTIONS=-Xlinker -R -Xlinker $(INFORMIXDIR)/lib:$(INFORMIXDIR)/lib/esql:$(LD_LIBRARY_PATH) AM_CFLAGS= -g -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= \ -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) ../db/sqlifx.cpp: ../db/sqlifx.ec $(INFORMIXDIR)/bin/esql -e $< mv sqlifx.c $*.cpp boinc-app-seti_8.00~svn3701.orig/splitter_fft/encode.h0000644000175000017500000000162312111524644022627 0ustar locutuslocutus/* * * 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 * * */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/mb_dotransform.h0000644000175000017500000000276012111524644024411 0ustar locutuslocutus/* * * 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)) 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(std::vector &data,int offset) ; void do_transform(std::vector &tapebuffer) ; /* * * $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 * * */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/readtape.cpp0000644000175000017500000001763512111524644023524 0ustar locutuslocutus/* 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 #include #include #include #include #include #include #include #include #include #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 ((bytesread0)); 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 #include #include #include #include #include #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;writtentm_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_file, &data, 1); } time0+=(1024.0*1024.0*4.0/2.5e6); } } boinc-app-seti_8.00~svn3701.orig/splitter_fft/dotransform.h0000644000175000017500000000265312111524644023734 0ustar locutuslocutus/* * * 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 * * */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/message.h0000644000175000017500000000215512111524644023017 0ustar locutuslocutus/* * 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 * */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/hr_min_sec.h0000644000175000017500000000520412111524644023477 0ustar locutuslocutus/* * * 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 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 * * */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/four1.h0000644000175000017500000000120112111524644022416 0ustar locutuslocutus/* * * 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 * * */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/mb_validrun.h0000644000175000017500000000142412111524644023673 0ustar locutuslocutus/* * 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 &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 * * */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/dotransform.cpp0000644000175000017500000001366312111524644024272 0ustar locutuslocutus/* * * 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 #include #include #include #include #include #include #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 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 * * */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/writeheader.cpp0000644000175000017500000000504112111524644024226 0ustar locutuslocutus/* * 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 #include #include #include #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 * * */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/polyphase.cpp0000644000175000017500000001100012111524644023717 0ustar locutuslocutus #include "sah_config.h" #include #include #include #include #include #include #include #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 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); } } boinc-app-seti_8.00~svn3701.orig/splitter_fft/mb_wufiles.cpp0000644000175000017500000005200612111524644024062 0ustar locutuslocutus/* * * 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 #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_ERRNO_H #include #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 wu_database_id; std::vector > bin_data; extern APP_CONFIG sah_config; int make_wu_headers(std::vector &tapebuffer, telescope_id tel, std::vector &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(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::iterator above(coord_history.upper_bound(end_time)); std::map::iterator below(coord_history.lower_bound(start_time)); std::map::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); 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\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",tmpstr.size(), xml_encoding_names[encoding]); fwrite(tmpstr.c_str(),tmpstr.size(),1,tmpfile); fprintf(tmpfile,"\n"); fprintf(tmpfile,"\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; if ( ar <= beam ) { db_wu.rsc_fpops_est=9.193e+13; } else if ( ar <= ( dur*min_slew ) ) { db_wu.rsc_fpops_est=5.962e+13+2.296e+12/ar; } else if ( ar <= ( dur*max_slew ) ) { db_wu.rsc_fpops_est=5.749e+13+1.476e+13/ar; } else { db_wu.rsc_fpops_est=3.535e+13; } 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*10; 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 * * */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/writeheader.h0000644000175000017500000000166012111524644023676 0ustar locutuslocutus/* * 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 * */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/cmap_interp.h0000644000175000017500000000013512111524644023670 0ustar locutuslocutus extern coordinate_t cmap_interp(std::map &map, seti_time &t); boinc-app-seti_8.00~svn3701.orig/splitter_fft/mb_polyphase.cpp0000644000175000017500000001104412111524644024405 0ustar locutuslocutus #include "sah_config.h" #include #include #include #include #include #include #include #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 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); } } boinc-app-seti_8.00~svn3701.orig/splitter_fft/splitter.h0000644000175000017500000000663612111524644023251 0ustar locutuslocutus/* * 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 * * */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/validrun.h0000644000175000017500000000133312111524644023214 0ustar locutuslocutus/* * 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 * * */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/encode.cpp0000644000175000017500000000461412111524644023165 0ustar locutuslocutus/* * * 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 #include #include #include /* 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 * * */ boinc-app-seti_8.00~svn3701.orig/splitter_fft/mb_dotransform.cpp0000644000175000017500000001507212111524644024744 0ustar locutuslocutus/* * * 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 #include #include #include #include #include #include #include "setilib.h" #include "splitparms.h" #include "splittypes.h" #include "mb_splitter.h" #include "fftw3.h" #include "mb_wufiles.h" /* 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) 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=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[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(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; } } void process_seg(std::vector > &data,int offset) { int i; static complex *dbuff=(complex *)fftwf_malloc(FFT_LEN*sizeof(complex)); memset(dbuff,0,FFT_LEN*sizeof(complex)); float* fbuff = (float *)dbuff; fftwf_complex *fcbuff=(fftwf_complex *)dbuff; static fftwf_plan planfwd,planinverse; if (!planfwd) { planfwd=fftwf_plan_dft_1d(FFT_LEN, fcbuff, fcbuff, FFTW_BACKWARD, FFTW_MEASURE ); int n=IFFT_LEN; planinverse=fftwf_plan_many_dft(1, &n, FFT_LEN/IFFT_LEN, fcbuff, &n, 1, n, fcbuff, &n, 1, n, FFTW_FORWARD, FFTW_MEASURE ); } for (i=0;i( static_cast(data[i+offset].real()), static_cast(data[i+offset].imag()) ); } fftwf_execute(planfwd); dbuff[0]=complex(0.0f,0.0f); // null the DC bin // highpass filter the rest if (splitter_settings.splitter_cfg->highpass != 0) { fprintf(stderr,"Doing highpass filter\n"); float filter_bins=FFT_LEN*splitter_settings.splitter_cfg->highpass/splitter_settings.recorder_cfg->sample_rate; complex stddev=0,avg=0; for (i=0;i temp(dbuff[i]); avg+=temp; stddev+=complex(temp.real()*temp.real(),temp.imag()*temp.imag()); } avg/=(float)FFT_LEN; stddev-=(float)FFT_LEN*complex(avg.real()*avg.real(),avg.imag()*avg.imag()); stddev=complex(sqrt(stddev.real()),sqrt(stddev.imag()))/(float)FFT_LEN; for (i=0;i(randn()*stddev.real(),randn()*stddev.imag())*(n+0.25f); dbuff[FFT_LEN-(i+1)]+=complex(randn()*stddev.real(),randn()*stddev.imag())*(n+0.25f); } } dbuff[0]=complex(0.0f,0.0f); // null the DC bin fftwf_execute(planinverse); for (i=0; i &tapebuffer) { int i,j; // long sum=0,sum0; for (i=0;i #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 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 #include #include #include #include #include #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])) && (++isource=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 && (posst)); 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 #include #include #include "sqlrow.h" #include "sqlblob.h" #include "sqlapi.h" #include "db_table.h" #include "schema_master.h" #include #include #include #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 * * */ boinc-app-seti_8.00~svn3701.orig/trim_sources0000755000175000017500000000601310671336410021157 0ustar locutuslocutus#!/bin/sh # $Id: trim_sources,v 1.23.2.1 2006/01/05 23:54:44 korpela Exp $ # delete sources we don't want to distribute. # so we don't accidentally run this script: test "$1" = DOIT || { echo "syntax: $0 DOIT" ; exit 1 ; } find . -depth \( \! \ \( \ -path ./COPYING -o \ -path ./config.guess -o \ -path ./config.h.in -o \ -path ./config.sub -o \ -path ./configure -o \ -path ./configure.ac -o \ -path ./_autosetup -o \ -path ./install-sh -o \ -path ./Makefile.am -o \ -path ./Makefile.in -o \ -path ./Makefile.incl -o \ -path ./aclocal.m4 -o \ -path ./ltmain.sh -o \ -path ./missing -o \ -path ./compile -o \ -path ./depcomp -o \ -path ./config.h -o \ -path ./client/\* -o \ -path ./client/test_workunits/\* -o \ -path ./image_libs/\* -o \ -path ./jpeglib/\* -o \ -path ./tools/\* -o \ -path ./win_build/\* -o \ -path ./glut/\* -o \ -path ./db/\* -o \ -path ./m4/\* \ \) -o \( \ -path ./client/win_build/\*.jpg -o \ -path ./client/win_build/\*.bmp \ \) -o \( \ -path ./db/tools/\* \ \) -o -path '*/CVS/*' \ \) \ -type f -exec rm {} \; -o \ -type d -empty -exec rmdir {} \; awk '{if ($1 != "db/tools/Makefile" && \ $1 != "validate/Makefile" && \ $1 != "assimilator/Makefile" && \ $1 != "splitter/Makefile") \ print $0}' configure.ac > configure.ac.trimmed mv configure.ac.trimmed configure.ac ./_autosetup boinc-app-seti_8.00~svn3701.orig/image_libs/0000755000175000017500000000000013155506302020605 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/image_libs/bmplib.cpp0000644000175000017500000001236010671336410022561 0ustar locutuslocutus#include #ifdef _WIN32 #include "windows.h" #endif #include "bmplib.h" // Returns true for success -- false otherwise bool DIB_BITMAP::set_size(int width, int height, int channels) { // If DIB_BITMAP has already been set -- clear it out first FreeDIB_BMP(); // Create a temporary compatible device context HDC temp_hdc = CreateCompatibleDC(NULL); // Error Check if(!temp_hdc) return false; bmp_width = width; // Set the width bmp_height = height; // Set the height bmp_channels = channels; // Set the channels (3 == 24-bit, 4 == 32-bit) // Set stride -- The stride is the TRUE number of bytes in a line of pixels // Windows makes all the .bmps DWORD aligned (divisible evenly by 4) // So if you bitmap say was 103x103 pixels, Windows would add 1 "padding byte" to it // so in memory it would be 104x103 pixels. The "padding bytes" do not get blit (drawn) // to the screen, they're just there so again everything is DWORD aligned which makes // blitting (drawing to the screen) easier for the OS bmp_stride = bmp_width * bmp_channels; while((bmp_stride % 4) != 0) // Ensure bmp_stride is DWORD aligned bmp_stride++; BITMAPINFO bmp_info = {0}; // Initialize the parameters that we care about bmp_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmp_info.bmiHeader.biWidth = width; bmp_info.bmiHeader.biHeight = height; bmp_info.bmiHeader.biPlanes = 1; // Always equal 1 bmp_info.bmiHeader.biBitCount = channels * 8; bmp_info.bmiHeader.biCompression = BI_RGB; // No compression bmp_info.bmiHeader.biClrUsed = 0; // Always equals 0 with a 24 or 32-bit .bmp // Create a DIBSection -- This returns us two things, an HBITMAP handle and // a memory pointer (pointer to the pixels) in surface_bits hbitmap = CreateDIBSection(temp_hdc, &bmp_info, DIB_RGB_COLORS, (void**)&surface_bits, 0, 0); // Release our temporary HDC DeleteDC(temp_hdc); // Error Check -- Make sure the call to CreateDIBSection() DID NOT fail if(!hbitmap) return false; return true; // We're sized :) } // end of set_size(int width, int height, int channels) bool DIB_BITMAP::loadBMP(const char *file_name) { // If DIB_BITMAP has already been set -- clear it out first FreeDIB_BMP(); // Error Check -- Make sure they passed in a valid file name if(!file_name) return false; FILE *bmp_file = fopen(file_name, "rb"); // Error Check -- Make sure the file could be opened if(!bmp_file) return false; BITMAPFILEHEADER bmp_fileheader; // Read the BITMAPFILEHEADER if(!fread(&bmp_fileheader, sizeof(BITMAPFILEHEADER), 1, bmp_file)) { fclose(bmp_file); return false; } // Check the type field to make sure we have a .bmp file if(memcmp(&bmp_fileheader.bfType, "BM", 2)) { fclose(bmp_file); return false; } BITMAPINFOHEADER bmp_infoheader; // Read the BITMAPINFOHEADER. if(!fread(&bmp_infoheader, sizeof(BITMAPINFOHEADER), 1, bmp_file)) { fclose(bmp_file); return false; } // We only support 24-bit and 32-bit .bmps so make sure that's what we have if((bmp_infoheader.biBitCount != 24) && (bmp_infoheader.biBitCount != 32)) { fclose(bmp_file); return false; } // Set the size of our DIB_BITMAP, once we do this we're ready to store the pixel // data in it if(set_size(bmp_infoheader.biWidth,bmp_infoheader.biHeight,bmp_infoheader.biBitCount / 8) == false) { fclose(bmp_file); return false; } // Jump to the location where the pixel data is stored if(fseek(bmp_file, bmp_fileheader.bfOffBits, SEEK_SET)) { fclose(bmp_file); return false; } unsigned int bytesPerLine = bmp_width * bmp_channels; // Bytes per line (number of bytes // in a scan line) // Calculate how many "padding" bytes there are -- WE DO NOT want to read in the // padding bytes (we will just skip over those) // **Remember** Windows adds padding bytes to ensure ALL .bmps are DWORD aligned // (divisible evenly by 4) unsigned int padding = bmp_stride - bytesPerLine; // Loop over all the scan lines (all the rows of pixels in the image) for(int y = bmp_height-1; y >= 0; y--) { // Get the "current" line pointer uchar *LinePtr = getLinePtr(y); // Read the precise number of bytes that the scan line requires into the bitmap if(!fread(LinePtr, bytesPerLine, 1, bmp_file)) { fclose(bmp_file); return false; } // Skip over any padding bytes. if(fseek(bmp_file, padding, SEEK_CUR)) { fclose(bmp_file); return false; } } // end of for (int y = 0; y < bmp_infoheader.biHeight; y++) fclose(bmp_file); return true; // If we get here .bmp was read in successfully } // end of loadBMP(char *file_name, HDC hdc) // Returns the address in memory of the specified line. This gives you a pointer to at least // width * channels bytes. Lines are numbered such that when the bitmap // is displayed line zero is at the top. uchar* DIB_BITMAP::getLinePtr(int which_line) { return (surface_bits + bmp_stride * which_line); } // Release the memory void DIB_BITMAP::FreeDIB_BMP() { // If we created an HBITMAP, delete it if(hbitmap) DeleteObject(hbitmap); // Zero out all data associated with DIB_BITMAP hbitmap = NULL; surface_bits = NULL; bmp_width = bmp_height = bmp_channels = bmp_stride = 0; return; } // Deconstructor DIB_BITMAP::~DIB_BITMAP() { FreeDIB_BMP(); } boinc-app-seti_8.00~svn3701.orig/image_libs/bmplib.h0000644000175000017500000000372510671336410022233 0ustar locutuslocutus#ifndef BITMAP_CLASS_H #define BITMAP_CLASS_H typedef unsigned char uchar; // We're lazy so typedef "unsigned char" as "uchar" // We will use this class to load 24 and 32-bit .bmp for us class DIB_BITMAP { public: // Constructor() -- Zero's out DIB_BITMAP DIB_BITMAP():hbitmap(NULL),surface_bits(NULL),bmp_width(0),bmp_height(0), bmp_channels(0),bmp_stride(0) { GdiFlush(); /* Guarantee that writing to DIB_BITMAP is okay */ } // Data Access Functions ************ inline int get_width() const { return bmp_width; } inline int get_height() const { return bmp_height; } inline int get_channels() const { return bmp_channels; } inline int get_stride() const { return bmp_stride; } // ****** End of Data Access Functions // Creates a "empty" DIB_BITMAP with the "traits" of the parameters passed in // Returns true for success -- false otherwise // If set_size is called on a DIB_BITMAP that already has memory associated with it // that memory is freed and the new size is implemented bool set_size(int width, int height, int channels); // Loads a bmp with specified file_name -- Returns true on success, false otherwise // If loadBMP() is called on a DIB_BITMAP that already has memory associated with // it, that memory is freed and the .bmp is loaded bool loadBMP(const char *file_name); uchar* getLinePtr(int which_line); // returns a pointer to the line passed in // Deconstructor(); ~DIB_BITMAP(); private: int bmp_width; // The width of the bitmap int bmp_height; // The height of the bitmap int bmp_channels; // How many channels is the bitmap (3 == 24-bit, 4 == 32-bit) int bmp_stride; // The TRUE number of bytes in a scan line (in a line of pixels // in memory) HBITMAP hbitmap; // This will be the handle to our bitmap uchar *surface_bits; // This is a pointer to the actual pixels of the bitmap void FreeDIB_BMP(); // Frees all memory associated with DIB_BITMAP }; #endif boinc-app-seti_8.00~svn3701.orig/image_libs/tgalib.cpp0000644000175000017500000002062610671336410022562 0ustar locutuslocutus #include "tgalib.h" tImageTGA *LoadTGA(const char *filename) { tImageTGA *pImageData = NULL; // This stores our important image data WORD width = 0, height = 0; // The dimensions of the image byte length = 0; // The length in bytes to the pixels byte imageType = 0; // The image type (RLE, RGB, Alpha...) byte bits = 0; // The bits per pixel for the image (16, 24, 32) FILE *pFile = NULL; // The file pointer int channels = 0; // The channels of the image (3 = RGA : 4 = RGBA) int stride = 0; // The stride (channels * width) int i = 0; // A counter // This function loads in a TARGA (.TGA) file and returns its data to be // used as a texture or what have you. This currently loads in a 16, 24 // and 32-bit targa file, along with RLE compressed files. Eventually you // will want to do more error checking to make it more robust. This is // also a perfect start to go into a modular class for an engine. // Basically, how it works is, you read in the header information, then // move your file pointer to the pixel data. Before reading in the pixel // data, we check to see the if it's an RLE compressed image. This is because // we will handle it different. If it isn't compressed, then we need another // check to see if we need to convert it from 16-bit to 24 bit. 24-bit and // 32-bit textures are very similar, so there's no need to do anything special. // We do, however, read in an extra bit for each color. // Open a file pointer to the targa file and check if it was found and opened if((pFile = fopen(filename, "rb")) == NULL) { return NULL; } // Allocate the structure that will hold our eventual image data (must free it!) pImageData = (tImageTGA*)malloc(sizeof(tImageTGA)); // Read in the length in bytes from the header to the pixel data fread(&length, sizeof(byte), 1, pFile); // Jump over one byte fseek(pFile,1,SEEK_CUR); // Read in the imageType (RLE, RGB, etc...) fread(&imageType, sizeof(byte), 1, pFile); // Skip past general information we don't care about fseek(pFile, 9, SEEK_CUR); // Read the width, height and bits per pixel (16, 24 or 32) fread(&width, sizeof(WORD), 1, pFile); fread(&height, sizeof(WORD), 1, pFile); fread(&bits, sizeof(byte), 1, pFile); // Now we move the file pointer to the pixel data fseek(pFile, length + 1, SEEK_CUR); // Check if the image is RLE compressed or not if(imageType != TGA_RLE) { // Check if the image is a 24 or 32-bit image if(bits == 24 || bits == 32) { // Calculate the channels (3 or 4) - (use bits >> 3 for more speed). // Next, we calculate the stride and allocate enough memory for the pixels. channels = bits / 8; stride = channels * width; pImageData->data = new unsigned char[stride * height]; // Load in all the pixel data line by line for(int y = 0; y < height; y++) { // Store a pointer to the current line of pixels unsigned char *pLine = &(pImageData->data[stride * y]); // Read in the current line of pixels fread(pLine, stride, 1, pFile); // Go through all of the pixels and swap the B and R values since TGA // files are stored as BGR instead of RGB (or use GL_BGR_EXT verses GL_RGB) for(i = 0; i < stride; i += channels) { int temp = pLine[i]; pLine[i] = pLine[i + 2]; pLine[i + 2] = temp; } } } // Check if the image is a 16 bit image (RGB stored in 1 unsigned short) else if(bits == 16) { unsigned short pixels = 0; int r=0, g=0, b=0; // Since we convert 16-bit images to 24 bit, we hardcode the channels to 3. // We then calculate the stride and allocate memory for the pixels. channels = 3; stride = channels * width; pImageData->data = new unsigned char[stride * height]; // Load in all the pixel data pixel by pixel for(int i = 0; i < width*height; i++) { // Read in the current pixel fread(&pixels, sizeof(unsigned short), 1, pFile); // To convert a 16-bit pixel into an R, G, B, we need to // do some masking and such to isolate each color value. // 0x1f = 11111 in binary, so since 5 bits are reserved in // each unsigned short for the R, G and B, we bit shift and mask // to find each value. We then bit shift up by 3 to get the full color. b = (pixels & 0x1f) << 3; g = ((pixels >> 5) & 0x1f) << 3; r = ((pixels >> 10) & 0x1f) << 3; // This essentially assigns the color to our array and swaps the // B and R values at the same time. pImageData->data[i * 3 + 0] = r; pImageData->data[i * 3 + 1] = g; pImageData->data[i * 3 + 2] = b; } } // Else return a NULL for a bad or unsupported pixel format else return NULL; } // Else, it must be Run-Length Encoded (RLE) else { // First, let me explain real quickly what RLE is. // For further information, check out Paul Bourke's intro article at: // http://astronomy.swin.edu.au/~pbourke/dataformats/rle/ // // Anyway, we know that RLE is a basic type compression. It takes // colors that are next to each other and then shrinks that info down // into the color and a integer that tells how much of that color is used. // For instance: // aaaaabbcccccccc would turn into a5b2c8 // Well, that's fine and dandy and all, but how is it down with RGB colors? // Simple, you read in an color count (rleID), and if that number is less than 128, // it does NOT have any optimization for those colors, so we just read the next // pixels normally. Say, the color count was 28, we read in 28 colors like normal. // If the color count is over 128, that means that the next color is optimized and // we want to read in the same pixel color for a count of (colorCount - 127). // It's 127 because we add 1 to the color count, as you'll notice in the code. // Create some variables to hold the rleID, current colors read, channels, & stride. byte rleID = 0; int colorsRead = 0; channels = bits / 8; stride = channels * width; // Next we want to allocate the memory for the pixels and create an array, // depending on the channel count, to read in for each pixel. pImageData->data = new unsigned char[stride * height]; byte *pColors = new byte [channels]; // Load in all the pixel data while(i < width*height) { // Read in the current color count + 1 fread(&rleID, sizeof(byte), 1, pFile); // Check if we don't have an encoded string of colors if(rleID < 128) { // Increase the count by 1 rleID++; // Go through and read all the unique colors found while(rleID) { // Read in the current color fread(pColors, sizeof(byte) * channels, 1, pFile); // Store the current pixel in our image array pImageData->data[colorsRead + 0] = pColors[2]; pImageData->data[colorsRead + 1] = pColors[1]; pImageData->data[colorsRead + 2] = pColors[0]; // If we have a 4 channel 32-bit image, assign one more for the alpha if(bits == 32) pImageData->data[colorsRead + 3] = pColors[3]; // Increase the current pixels read, decrease the amount // of pixels left, and increase the starting index for the next pixel. i++; rleID--; colorsRead += channels; } } // Else, let's read in a string of the same character else { // Minus the 128 ID + 1 (127) to get the color count that needs to be read rleID -= 127; // Read in the current color, which is the same for a while fread(pColors, sizeof(byte) * channels, 1, pFile); // Go and read as many pixels as are the same while(rleID) { // Assign the current pixel to the current index in our pixel array pImageData->data[colorsRead + 0] = pColors[2]; pImageData->data[colorsRead + 1] = pColors[1]; pImageData->data[colorsRead + 2] = pColors[0]; // If we have a 4 channel 32-bit image, assign one more for the alpha if(bits == 32) pImageData->data[colorsRead + 3] = pColors[3]; // Increase the current pixels read, decrease the amount // of pixels left, and increase the starting index for the next pixel. i++; rleID--; colorsRead += channels; } } } // Free up pColors delete[] pColors; } // Close the file pointer that opened the file fclose(pFile); // Fill in our tImageTGA structure to pass back pImageData->channels = channels; pImageData->sizeX = width; pImageData->sizeY = height; // Return the TGA data (remember, you must free this data after you are done) return pImageData; } boinc-app-seti_8.00~svn3701.orig/image_libs/Makefile.in0000644000175000017500000000017412631640074022657 0ustar locutuslocutus subdir = image_libs SUFFIXES = .cpp .h all: Makefile clean: rm -f *.o distclean: clean -rm -f Makefile boinc-app-seti_8.00~svn3701.orig/image_libs/Makefile0000644000175000017500000000017412631640074022252 0ustar locutuslocutus subdir = image_libs SUFFIXES = .cpp .h all: Makefile clean: rm -f *.o distclean: clean -rm -f Makefile boinc-app-seti_8.00~svn3701.orig/image_libs/tgalib.h0000644000175000017500000000110010671336410022211 0ustar locutuslocutus#ifndef TGALIB_H #define TGALIB_H #include #include #define TGA_RGB 2 // This tells us it's a normal RGB (really BGR) file #define TGA_A 3 // This tells us it's a ALPHA file #define TGA_RLE 10 // This tells us that the targa is Run-Length Encoded (RLE) struct tImageTGA { int channels; // The channels in the image (3 = RGB : 4 = RGBA) int sizeX; // The width of the image in pixels int sizeY; // The height of the image in pixels unsigned char *data; // The image pixel data }; tImageTGA *LoadTGA(const char *filename); #endif boinc-app-seti_8.00~svn3701.orig/db/0000755000175000017500000000000013155506301017076 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/db/sqlint8.h0000644000175000017500000000747210671336410020665 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef _SQLINT8_H_ #define _SQLINT8_H_ #include "sah_config.h" #include #ifdef HAVE_INTTYPES_H #include typedef int64_t sqlint8_t; #ifdef PRIdLEAST64 #define INT8_FMT PRIdLEAST64 #else #if SIZEOF_LONG_INT >=8 #define INT8_FMT "ld" #else #define INT8_FMT "lld" #endif #endif #define INT8_PRINT_CAST(x) x #define INT8_USING_INT64_T #elif SIZEOF_LONG_INT >= 8 typedef long sqlint8_t; #define INT8_FMT "ld" #define INT8_PRINT_CAST(x) x #define INT8_USING_LONG #elif defined(LLONG_MAX) || defined(HAVE_LONG_LONG) typedef long long sqlint8_t; #define INT8_FMT "lld" #define INT8_PRINT_CAST(x) x #define INT8_USING_LONG_LONG #elif defined(USE_MYSQL) && !defined(CLIENT) #include "my_config.h" #include "global.h" typedef longlong sqlint8_t; #define INT8_FMT "lld" #define INT8_PRINT_CAST(x) x #define INT8_USING_LONGLONG #elif defined(_INTEGRAL_MAX_BITS) && (_INTEGRAL_MAX_BITS >= 64) typedef _int64 sqlint8_t; #define INT8_FMT "lld" #define INT8_PRINT_CAST(x) x #define INT8_USING_INT64 #elif defined(USE_INFORMIX) #include "int8.h" #include "sqlhdr.h" #include #include class _ifx_int8 { public: _ifx_int8(ifx_int8 a) : val(a) {}; _ifx_int8(const char *s) {ifx_int8cvasc(const_cast(s),strlen(s),&val);}; _ifx_int8(double d) {ifx_int8cvdbl(d,&val);}; _ifx_int8(long l) {ifx_int8cvlong(l,&val);}; _ifx_int8(int l=0) {ifx_int8cvlong(static_cast(l),&val);}; operator const char *() const ; operator long() const ; private: ifx_int8 val; static char pval[20]; }; inline _ifx_int8::operator const char *() const { ifx_int8toasc(const_cast(&val),pval,20); pval[19]=0; return pval; } inline _ifx_int8::operator long() const { long l; ifx_int8tolong(const_cast(&val),&l); return l; } typedef _ifx_int8 sqlint8_t; #define INT8_FMT "s" #define INT8_PRINT_CAST(x) static_cast(x) #define INT8_USING_IFX #elif defined(HAVE_LONG_DOUBLE) typedef long double sqlint8_t; #define INT8_FMT "lf21.0" #define INT8_PRINT_CAST(x) x #define INT8_USING_LONG_DOUBLE #else typedef double sqlint8_t; #define INT8_FMT "f16.0" #define INT8_PRINT_CAST(x) x #define INT8_USING_DOUBLE #endif #ifndef HAVE_ATOLL inline sqlint8_t atoll(const char *p) { sqlint8_t rv=0; sqlint8_t sign=1; while (isspace(*(p++))) /* do nothing */ ; if (*p=='-') { sign=-1; p++; } while (isdigit(*(p++))) { rv*=10; rv+=(*(p-1)-'0'); } rv*=sign; return rv; } #endif #if defined(INT8_USING_INT64) || defined(INT8_USING_IFX) inline std::ostream &operator <<(std::ostream &o, const sqlint8_t &p) { char buf[32]; sprintf(buf,"%"INT8_FMT,INT8_PRINT_CAST(p)); o << buf ; return o; } inline std::istream &operator >>(std::istream &i, sqlint8_t &p) { char c=' '; sqlint8_t sign=1; p=0; while (isspace(c) && !i.eof()) i.get(c); if (c=='-') { sign=-1; if (!i.eof()) i.get(c); } while (isdigit(c) && !i.eof()) { p*=10; p+=(c-'0'); i.get(c); } if (!i.eof()) i.putback(c); p*=sign; return i; } #endif #endif boinc-app-seti_8.00~svn3701.orig/db/sqlint8.cpp0000644000175000017500000000222510671336410021207 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "sah_config.h" #include #include #include #include "sqlint8.h" #ifdef HAVE_INTTYPES_H #elif defined(LLONG_MAX) || defined(HAVE_LONG_LONG) #elif defined(USE_MYSQL) && defined(longlong_defined) #elif defined(USE_INFORMIX) char _ifx_int8::pval[20]; #elif defined(_INTEGRAL_MAX_BITS) && (_INTEGRAL_MAX_BITS >= 64) #elif defined(HAVE_LONG_DOUBLE) #else #endif boinc-app-seti_8.00~svn3701.orig/db/tools/0000755000175000017500000000000013155506301020236 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/db/tools/insert_s4_receivers.cpp0000644000175000017500000000313610671336410024730 0ustar locutuslocutus#include "sah_config.h" #include #include #include #include #include #include "s_util.h" #include "sqlapi.h" #include "db_table.h" #include "schema_master.h" #include #include #define S4_RECEIVER_CONFIG_FILE "/usr/local/warez/projects/s4/siren/db/ReceiverConfig.tab" ReceiverConfig_t input; receiver_config output; int main() { int i,j; if (!sql_database("sah2b@sci_master_tcp")) exit(1); if (!getenv("S4_RECEIVER_CONFIG")) putenv("S4_RECEIVER_CONFIG="S4_RECEIVER_CONFIG_FILE); for (i=0;i<3;i++) { memset(&input,0,sizeof(input)); s4cfg_GetReceiverConfig(i, &input); output.s4_id=input.ReceiverID; strncpy(output.name,input.ReceiverName,255); output.name[254]=0; output.beam_width=input.BeamWidth; output.center_freq=input.CenterFreq; output.latitude=input.Latitude; output.longitude=input.Longitude; output.elevation=input.Elevation; output.diameter=input.Diameter; output.az_orientation=input.AzOrientation; output.zen_corr_coeff.clear(); output.az_corr_coeff.clear(); for (j=0;j<13;j++) { output.zen_corr_coeff.push_back(input.ZenCorrCoeff[j]); output.az_corr_coeff.push_back(input.AzCorrCoeff[j]); } db_change("sah2b@sci_master_tcp"); output.id=0; if (output.insert()) { std::cout << "inserted row (id=" << output.id << ")" << std::endl; } else { std::cout << "insert failed, sql_error_code =" << sql_error_code() << " sql_last_error_code =" << sql_last_error_code() << std::endl; } } } boinc-app-seti_8.00~svn3701.orig/db/tools/print_s4_receivers.cpp0000644000175000017500000000115310671336410024555 0ustar locutuslocutus#include "sah_config.h" #include #include #include #include #include #include #include "s_util.h" #include "sqlapi.h" #include "xml_util.h" #include "db_table.h" #include "schema_master.h" receiver_config input; int main() { if (!sql_database("sah2b@sci_master_tcp")) exit(1); std::cout << "\n"; std::cout << xml_indent() << "" << input.count() << "\n" ; if (input.open_query()) { while (input.get_next()) { std::cout << input.print_xml(); } } std::cout << "\n"; } boinc-app-seti_8.00~svn3701.orig/db/tools/insert_rfi_zones.cpp0000644000175000017500000000256511326132630024332 0ustar locutuslocutus#include "sah_config.h" #include #include #include #include #include #include #include "parse.h" #include "s_util.h" #include "sqlapi.h" #include "db_table.h" #include "schema_master.h" rfi_zone zone; int main(int argc, char **argv) { int i=0; bool beta=false, sah=false; if (argc != 3) { fprintf(stderr,"Usage:\n insert_rfi_zones beta|sah filename\n"); exit(1); } if (strcmp(argv[1], "beta") == 0) { beta = true; fprintf(stderr, "Inserting into the beta DB\n"); } else if (strcmp(argv[1], "sah") == 0) { sah = true; fprintf(stderr, "Inserting into the sah DB\n"); } else { fprintf(stderr,"Usage:\n insert_rfi_zones beta|sah filename\n"); exit(1); } std::ifstream f(argv[2]); if (!f.is_open()) { fprintf(stderr,"File not found!\n"); exit(1); } if(beta) { db_change("sah2b@sci_master_tcp"); } else if(sah) { db_change("sah2@sci_master_tcp"); } else { fprintf(stderr,"bad DB specification\n"); } while (!f.eof()) { f >> zone; if (!f.eof()) { i++; zone.insert(); fprintf(stderr, "SQLCODE is %d last SQLCODE is %d\n", sql_error_code(), sql_last_error_code()); } } std::cout << "Found " << i << " rfi zones." << std::endl; } boinc-app-seti_8.00~svn3701.orig/db/tools/settings.sql0000644000175000017500000000017612321065336022625 0ustar locutuslocutusdatabase sah2@sah_master_tcp; -- update settings set active=0 where 1 = 1 ; insert into settings values(0,11,2,6,9197,7); boinc-app-seti_8.00~svn3701.orig/db/tools/insert_splitter_config.cpp0000644000175000017500000000153412321065336025526 0ustar locutuslocutus#include "sah_config.h" #include #include #include #include #include #include #include "parse.h" #include "s_util.h" #include "sqlapi.h" #include "db_table.h" #include "schema_master.h" splitter_config cfg; int main(int argc, char **argv) { int i=0; if (argc != 2) { fprintf(stderr,"Usage:\n insert_splitter_config filename\n"); exit(1); } std::ifstream f(argv[1]); if (!f.is_open()) { fprintf(stderr,"File not found!\n"); exit(1); } db_change("sah2b@sah_master_tcp"); while (!f.eof()) { f >> cfg; if (!f.eof()) { i++; cfg.insert(); if (!cfg.id) std::cout << sql_error_message() << " " << sql_error_code(); } } std::cout << "Found " << i << " splitter configs." << std::endl; } boinc-app-seti_8.00~svn3701.orig/db/tools/insert_analysis_config.cpp0000644000175000017500000000261411547136352025511 0ustar locutuslocutus#include "sah_config.h" #include #include #include #include #include #include #include "parse.h" #include "s_util.h" #include "sqlapi.h" #include "db_table.h" #include "schema_master.h" analysis_config cfg; int main(int argc, char **argv) { int i=0; bool beta=false, sah=false; if (argc != 3) { fprintf(stderr,"Usage:\n insert_analysis_config beta|sah filename\n"); exit(1); } if (strcmp(argv[1], "beta") == 0) { beta = true; fprintf(stderr, "Inserting into the beta DB\n"); } else if (strcmp(argv[1], "sah") == 0) { sah = true; fprintf(stderr, "Inserting into the sah DB\n"); } else { fprintf(stderr,"Usage:\n insert_analysis_config beta|sah filename\n"); exit(1); } std::ifstream f(argv[2]); if (!f.is_open()) { fprintf(stderr,"File not found!\n"); exit(1); } if(beta) { db_change("sah2b@sah_master_tcp"); } else if(sah) { db_change("sah2@sah_master_tcp"); } else { fprintf(stderr,"bad DB specification\n"); } while (!f.eof()) { f >> cfg; if (!f.eof()) { i++; cfg.insert(); fprintf(stderr, "SQLCODE is %d last SQLCODE is %d\n", sql_error_code(), sql_last_error_code()); } } std::cout << "Found " << i << " analysis configs." << std::endl; } boinc-app-seti_8.00~svn3701.orig/db/tools/recorder_configs.sql0000644000175000017500000000015110671336410024273 0ustar locutuslocutusdatabase sah2@sci_master_tcp; insert into recorder_config values(0,"seti_dr2_ALFA",2,2500000,14,1.99); boinc-app-seti_8.00~svn3701.orig/db/tools/analysis_configs.xml0000644000175000017500000001003412632143161024311 0ustar locutuslocutus 24.0 1 17.8 1 131072 2.225 1.42 3.0 3.2 64 19.5 0.5 40960 16 8192 256 8.50 131072 16 256 0.5 1 0.0064 # should be beams/s rather and degrees 0.0320 # should be beams/s rather and degrees 0.1665 262136 8192 # should be seconds 32768 # should be seconds 30.0 262136 100.0 65528 1.0 30 8 8 0 0 0 35 2.85 24.0 1 17.8 1 131072 2.225 1.42 3.0 3.2 64 19.5 0.5 40960 16 8192 256 8.50 131072 16 256 0.5 1 0.0010 # should be beams/s rather and degrees 0.0053 # should be beams/s rather and degrees 0.1665 262136 8192 # should be seconds 32768 # should be seconds 30.0 262136 100.0 65528 1.0 30 8 8 0 0 0 36 2.85 boinc-app-seti_8.00~svn3701.orig/db/tools/s4_receivers.xml0000644000175000017500000003003510671336410023360 0ustar locutuslocutus 0 ao430 0.166999996 430 18.3538056 -66.7552222 497 168 0 7.4,5.4,-49.1,355,0,0,0,0,0,0,0,0,0 -97.1,66.1,14.3,321.7,0,0,0,0,0,0,0,0,0 1 ao1420 0.0829999968 1420 18.3538056 -66.7552222 497 168 0 7.4,5.4,-49.1,-1091,0,0,0,0,0,0,0,0,0 -5146.7,66.1,14.3,321.7,0,0,0,0,0,0,0,0,0 2 aogreg1420 0.0500000007 1420 18.3538056 -66.7552222 497 168 180 -16.41,-6.41,99.16,-713.84,-1028.24,-22.2,-12.08,7.31,111.56,2.49,-0.69, -1.93,0.91 -90.48,-100.92,-5.74,175.81,489.81,-11.42,-7.8,4,1.25,0.43,-0.42,-0.3, -0.19 3 Arecibo 1.4GHz Array, Beam 0, Pol 0 0.05 1420 18.3538056 -66.7552222 497 168 180 -37,-6.05,92.35,-731.21,-1013.97,-24.53,-11.19,9.18,106.04,3.02,-1.74, -3.46,1.29 -57.55,-95.56,-4.13,141.69,677.51,-10.41,-7.71,-10.39,0.08,0.43,-0.62, 0.03,-0.36 4 Arecibo 1.4GHz Array, Beam 0, Pol 1 0.05 1420 18.3538056 -66.7552222 497 168 180 -37,-6.05,92.35,-731.21,-1013.97,-24.53,-11.19,9.18,106.04,3.02,-1.74, -3.46,1.29 -57.55,-95.56,-4.13,141.69,677.51,-10.41,-7.71,-10.39,0.08,0.43,-0.62, 0.03,-0.36 5 Arecibo 1.4GHz Array, Beam 1, Pol 0 0.05 1420 18.3538056 -66.7552222 497 168 180 -37,-6.05,92.35,-731.21,-1013.97,-24.53,-11.19,9.18,106.04,3.02,-1.74, -3.46,1.29 -57.55,-95.56,-4.13,141.69,677.51,-10.41,-7.71,-10.39,0.08,0.43,-0.62, 0.03,-0.36 329.06 384.005 120.0 6 Arecibo 1.4GHz Array, Beam 1, Pol 1 0.05 1420 18.3538056 -66.7552222 497 168 180 -37,-6.05,92.35,-731.21,-1013.97,-24.53,-11.19,9.18,106.04,3.02,-1.74, -3.46,1.29 -57.55,-95.56,-4.13,141.69,677.51,-10.41,-7.71,-10.39,0.08,0.43,-0.62, 0.03,-0.36 329.06 384.005 120.0 7 Arecibo 1.4GHz Array, Beam 2, Pol 0 0.05 1420 18.3538056 -66.7552222 497 168 180 -37,-6.05,92.35,-731.21,-1013.97,-24.53,-11.19,9.18,106.04,3.02,-1.74, -3.46,1.29 -57.55,-95.56,-4.13,141.69,677.51,-10.41,-7.71,-10.39,0.08,0.43,-0.62, 0.03,-0.36 329.06 384.005 180.0 8 Arecibo 1.4GHz Array, Beam 2, Pol 1 0.05 1420 18.3538056 -66.7552222 497 168 180 -37,-6.05,92.35,-731.21,-1013.97,-24.53,-11.19,9.18,106.04,3.02,-1.74, -3.46,1.29 -57.55,-95.56,-4.13,141.69,677.51,-10.41,-7.71,-10.39,0.08,0.43,-0.62, 0.03,-0.36 329.06 384.005 180.0 9 Arecibo 1.4GHz Array, Beam 3, Pol 0 0.05 1420 18.3538056 -66.7552222 497 168 180 -37,-6.05,92.35,-731.21,-1013.97,-24.53,-11.19,9.18,106.04,3.02,-1.74, -3.46,1.29 -57.55,-95.56,-4.13,141.69,677.51,-10.41,-7.71,-10.39,0.08,0.43,-0.62, 0.03,-0.36 329.06 384.005 -120.0 10 Arecibo 1.4GHz Array, Beam 3, Pol 1 0.05 1420 18.3538056 -66.7552222 497 168 180 -37,-6.05,92.35,-731.21,-1013.97,-24.53,-11.19,9.18,106.04,3.02,-1.74, -3.46,1.29 -57.55,-95.56,-4.13,141.69,677.51,-10.41,-7.71,-10.39,0.08,0.43,-0.62, 0.03,-0.36 329.06 384.005 -120.0 11 Arecibo 1.4GHz Array, Beam 4, Pol 0 0.05 1420 18.3538056 -66.7552222 497 168 180 -37,-6.05,92.35,-731.21,-1013.97,-24.53,-11.19,9.18,106.04,3.02,-1.74, -3.46,1.29 -57.55,-95.56,-4.13,141.69,677.51,-10.41,-7.71,-10.39,0.08,0.43,-0.62, 0.03,-0.36 329.06 384.005 -60.0 12 Arecibo 1.4GHz Array, Beam 4, Pol 1 0.05 1420 18.3538056 -66.7552222 497 168 180 -37,-6.05,92.35,-731.21,-1013.97,-24.53,-11.19,9.18,106.04,3.02,-1.74, -3.46,1.29 -57.55,-95.56,-4.13,141.69,677.51,-10.41,-7.71,-10.39,0.08,0.43,-0.62, 0.03,-0.36 329.06 384.005 -60.0 13 Arecibo 1.4GHz Array, Beam 5, Pol 0 0.05 1420 18.3538056 -66.7552222 497 168 180 -37,-6.05,92.35,-731.21,-1013.97,-24.53,-11.19,9.18,106.04,3.02,-1.74, -3.46,1.29 -57.55,-95.56,-4.13,141.69,677.51,-10.41,-7.71,-10.39,0.08,0.43,-0.62, 0.03,-0.36 329.06 384.005 0.0 14 Arecibo 1.4GHz Array, Beam 5, Pol 1 0.05 1420 18.3538056 -66.7552222 497 168 180 -37,-6.05,92.35,-731.21,-1013.97,-24.53,-11.19,9.18,106.04,3.02,-1.74, -3.46,1.29 -57.55,-95.56,-4.13,141.69,677.51,-10.41,-7.71,-10.39,0.08,0.43,-0.62, 0.03,-0.36 329.06 384.005 0.0 15 Arecibo 1.4GHz Array, Beam 6, Pol 0 0.05 1420 18.3538056 -66.7552222 497 168 180 -37,-6.05,92.35,-731.21,-1013.97,-24.53,-11.19,9.18,106.04,3.02,-1.74, -3.46,1.29 -57.55,-95.56,-4.13,141.69,677.51,-10.41,-7.71,-10.39,0.08,0.43,-0.62, 0.03,-0.36 329.06 384.005 60.0 16 Arecibo 1.4GHz Array, Beam 6, Pol 1 0.05 1420 18.3538056 -66.7552222 497 168 180 -37,-6.05,92.35,-731.21,-1013.97,-24.53,-11.19,9.18,106.04,3.02,-1.74, -3.46,1.29 -57.55,-95.56,-4.13,141.69,677.51,-10.41,-7.71,-10.39,0.08,0.43,-0.62, 0.03,-0.36 329.06 384.005 60.0 boinc-app-seti_8.00~svn3701.orig/db/tools/Makefile.in0000644000175000017500000000455311326132630022310 0ustar locutuslocutusBOINCDIR = @BOINCDIR@ INFORMIXDIR= @INFORMIXDIR@ BOINCLIBS=-L$(BOINCDIR)/lib -lboinc SETIHOME=../.. DBLIBS=../xml_util.o ../sqlblob.o ../sqlrow.o ../sqlifx.o @INFORMIX_LIBS@ -ldl -lm -lstdc++ @PTHREAD_LIBS@ INCLUDE_DIRS= -I$(SETIHOME) -I$(SETIHOME)/client -I$(SETIHOME)/db \ @MYSQL_CFLAGS@ \ @INFORMIX_CFLAGS@ \ @PTHREAD_CFLAGS@ \ -I$(BOINCDIR) -I$(BOINCDIR)/lib -I$(BOINCDIR)/sched -I$(BOINCDIR)/db -I$(BOINCDIR)/tools LINKOPTIONS=-Xlinker -R -Xlinker $(LD_LIBRARY_PATH):$(INFORMIXDIR)/lib:$(INFORMIXDIR)/lib/esql SUFFIXES = .cpp .o .cpp.o: $(CXX) $(CXXFLAGS) -c $< CC = @CC@ CFLAGS = @CFLAGS@ @DEFS@ $(INCLUDE_DIRS) -DUSE_INFORMIX CXX = @CXX@ CXXFLAGS = $(CFLAGS) dependencies: *.cpp $(CC) $(CFLAGS) -M *.cpp > dependencies all: dependencies print_s4_receivers insert_analysis_config insert_splitter_config insert_receiver_config insert_rfi_zones insert_s4_receivers: insert_s4_receivers.o ../schema_master.o ../sqlifx.o ../sqlrow.o $(CC) $(LINKOPTIONS) -o insert_s4_receivers insert_s4_receivers.o ../schema_master.o $(S4LIBS) $(DBLIBS) $(BOINCLIBS) insert_receiver_config: insert_receiver_config.o ../schema_master.o ../sqlifx.o ../sqlrow.o $(CC) $(LINKOPTIONS) -o insert_receiver_config insert_receiver_config.o ../schema_master.o $(S4LIBS) $(DBLIBS) $(BOINCLIBS) insert_analysis_config: insert_analysis_config.o ../schema_master.o ../sqlifx.o ../sqlrow.o $(CC) $(LINKOPTIONS) -o insert_analysis_config insert_analysis_config.o ../schema_master.o $(S4LIBS) $(DBLIBS) $(BOINCLIBS) insert_rfi_zones: insert_rfi_zones.o ../schema_master.o ../sqlifx.o ../sqlrow.o $(CC) $(LINKOPTIONS) -o insert_rfi_zones insert_rfi_zones.o ../schema_master.o $(S4LIBS) $(DBLIBS) $(BOINCLIBS) insert_science_config: insert_science_config.o ../schema_master.o ../sqlifx.o ../sqlrow.o $(CC) $(LINKOPTIONS) -o insert_science_config insert_science_config.o ../schema_master.o $(S4LIBS) $(DBLIBS) $(BOINCLIBS) insert_splitter_config: insert_splitter_config.o ../schema_master.o ../sqlifx.o ../sqlrow.o $(CC) $(LINKOPTIONS) -o insert_splitter_config insert_splitter_config.o ../schema_master.o $(S4LIBS) $(DBLIBS) $(BOINCLIBS) print_s4_receivers: print_s4_receivers.o ../schema_master.o ../sqlifx.o ../sqlrow.o $(CC) $(LINKOPTIONS) -o print_s4_receivers print_s4_receivers.o ../schema_master.o $(S4LIBS) $(DBLIBS) $(BOINCLIBS) include dependencies boinc-app-seti_8.00~svn3701.orig/db/tools/rfi_zones_to_xml.pro0000644000175000017500000000167511326132630024347 0ustar locutuslocutuspro zones_to_xml, zones, file unit = 1 openw, unit, file n = n_elements(zones) for i=0,n-1 do begin printf, unit, "" printf, unit, " ", zones[i].min_time, "" printf, unit, " ", zones[i].max_time, "" printf, unit, " ", zones[i].CENTRAL_DETECTION_FREQ, "" printf, unit, " ", zones[i].detection_freq_width, "" printf, unit, " ", zones[i].central_period, "" printf, unit, " ", zones[i].period_width, "" printf, unit, " ", zones[i].fft_len_flags, "" printf, unit, " ", zones[i].signal_type_flags, "" printf, unit, "" endfor close, unit end boinc-app-seti_8.00~svn3701.orig/db/tools/insert_receiver_config.cpp0000644000175000017500000000141110671336410025456 0ustar locutuslocutus#include "sah_config.h" #include #include #include #include #include #include #include "parse.h" #include "s_util.h" #include "sqlapi.h" #include "db_table.h" #include "schema_master.h" receiver_config cfg; int main(int argc, char **argv) { int i=0; if (argc != 2) { fprintf(stderr,"Usage:\n insert_receiver_config filename\n"); exit(1); } std::ifstream f(argv[1]); if (!f.is_open()) { fprintf(stderr,"File not found!\n"); exit(1); } db_change("sah2@sci_master_tcp"); while (!f.eof()) { f >> cfg; if (!f.eof()) { i++; cfg.insert(); } } std::cout << "Found " << i << " receiver configs." << std::endl; } boinc-app-seti_8.00~svn3701.orig/db/tools/insert_science_config.cpp0000644000175000017500000000270111155544663025277 0ustar locutuslocutus#include "sah_config.h" #include #include #include #include #include #include #include "parse.h" #include "s_util.h" #include "sqlapi.h" #include "db_table.h" #include "schema_master.h" science_config cfg; int main(int argc, char **argv) { int i=0; bool beta=false, sah=false; if (argc != 3) { fprintf(stderr,"Usage:\n insert_science_config beta|sah filename\n"); exit(1); } if (strcmp(argv[1], "beta") == 0) { beta = true; fprintf(stderr, "Inserting into the beta DB\n"); } else if (strcmp(argv[1], "sah") == 0) { sah = true; fprintf(stderr, "Inserting into the sah DB\n"); } else { fprintf(stderr,"Usage:\n insert_science_config beta|sah filename\n"); exit(1); } std::ifstream f(argv[2]); if (!f.is_open()) { fprintf(stderr,"File not found!\n"); exit(1); } if(beta) { db_change("sah2b@sci_master_tcp"); } else if(sah) { db_change("sah2@sci_master_tcp"); } else { fprintf(stderr,"bad DB specification\n"); } while (!f.eof()) { f >> cfg; if (!f.eof()) { i++; fprintf(stderr, "%s\n", cfg.print_xml().c_str()); cfg.insert(); fprintf(stderr, "SQLCODE is %d last SQLCODE is %d\n", sql_error_code(), sql_last_error_code()); } } std::cout << "Found " << i << " science configs." << std::endl; } boinc-app-seti_8.00~svn3701.orig/db/tools/splitter_configs.xml0000644000175000017500000000051112321065336024335 0ustar locutuslocutus 0.30 encoded 2048 16 fft welsh 4194304 0.0 randomize boinc-app-seti_8.00~svn3701.orig/db/tools/science_configs.xml0000644000175000017500000000374211155544663024122 0ustar locutuslocutus 0 NEST 2048 10.0 2500000.0 50.0 0.05 0.05 14400.0 2000 10.0 50000.0 0.0 0.0 107.0 0.010417 12.5 0.0 0.0 0.0 0.0 place_holder 1 NEST 2048 10.0 2500000.0 50.0 0.05 0.05 14400.0 2000 10. 50000. 0.0 0.000694 107.0 0.000694 12.5 0.000694 12.5 0.000694 0.0 place_holder boinc-app-seti_8.00~svn3701.orig/db/app_config.cpp0000644000175000017500000000453311417355256021726 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "sah_config.h" #include #include #include #ifdef HAVE_IEEEFP_H #include #endif #include "util.h" #include "parse.h" #include "error_numbers.h" #include "app_config.h" const char* APP_CONFIG_FILE = "sah_config.xml"; //const char* APP_CONFIG_FILE = "sah_enhanced_config.xml"; int APP_CONFIG::parse(char* buf) { memset(this, 0, sizeof(APP_CONFIG)); min_disk_free_pct=10; parse_str(buf, "", scidb_name, sizeof(scidb_name)); parse_int(buf, "", max_wus_ondisk); parse_double(buf, "", min_disk_free_pct); parse_int(buf, "", min_quorum ); parse_int(buf, "", target_nresults); parse_int(buf, "", max_error_results); parse_int(buf, "", max_success_results); parse_int(buf, "", max_total_results); parse_bool(buf, "", assim_check_rfi); if (match_tag(buf, "")) return 0; return ERR_XML_PARSE; } int APP_CONFIG::parse_file(char* dir) { char* p; char path[256]; int retval; sprintf(path, "%s/%s", dir, APP_CONFIG_FILE); retval = read_file_malloc(path, p); if (retval) return retval; return parse(p); } // main routine for testing //int main(int argc, char** argv) { // // APP_CONFIG sah_config; // int retval; // // retval = sah_config.parse_file(".."); // if (retval) { // fprintf(stderr, "Can't parse config file\n"); // } else { // fprintf(stderr, "db name is %s\n", sah_config.scidb_name); // } //} boinc-app-seti_8.00~svn3701.orig/db/find_references.awk0000644000175000017500000000317710671336410022735 0ustar locutuslocutus# Copyright 2003 Regents of the University of California # SETI_BOINC is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free # Software Foundation; either version 2, or (at your option) any later # version. # SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # more details. # You should have received a copy of the GNU General Public License along # with SETI_BOINC; see the file COPYING. If not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. /create table/ { n=split($3,a,"."); table=a[n]; } /create table/,/\);/ { for (i=1;i(empty_row)); /* open the query specified by statement and substitute all ? with * parameters specified * compiles the query and allocates space for return values */ extern "C" { #endif int begin_work(); /* starts a transaction */ int commit_work(); /* commits a transaction */ int rollback_work(); /* rolls backs a transaction */ #ifdef __cplusplus } bool sql_close(SQL_CURSOR); /* close the compiled query and release all memory allocated for it */ bool sql_fetch(SQL_CURSOR); /* fetch a single row into the allocated space * use sql_values to retrieve it * (there is no need to free the sql_values return value! * the program manages this space efficiently by reallocating more * space if needed and does not do repeated malloc and free.) */ bool sql_run(const char *stmt, SQL_ROW &argv=const_cast(empty_row)); /* calls sql_open, sql_fetch and then sql_close */ bool sql_explain(int); /* sets debug on for all queries if int is not 0 else turns off */ bool sql_reopen(SQL_CURSOR fd, SQL_ROW &argv); /* reopen the cursor so that fetches may be done from the * start again. uses the old parameters for the open * if argc is specified bind the variables again */ SQL_ROW sql_values(SQL_CURSOR fd, int *numvalues=0, int dostrip=1); /* if dostrip is 1, it will strip all trailing blanks */ bool chk_cursor(SQL_CURSOR fd,const char *s); /* * performs an error check on the cursor * if NDEBUG is not defined then an error message is printed */ bool sql_print(SQL_CURSOR fd); /* * prints implementation defined info about the query in process */ #ifdef USE_NAMESPACE } #endif #endif #endif boinc-app-seti_8.00~svn3701.orig/db/row_cache.h0000644000175000017500000000675011376571111021215 0ustar locutuslocutus// $Id: db_table.h,v 1.45.2.10 2007/05/31 22:03:18 korpela Exp $ // Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include #include template class row_cache { private: class cache_element { public: T item; time_t insert_time; cache_element(const T &val) : item(val), insert_time(time(0)) {}; cache_element &operator =(const T &val) { if (&item != &val) { item=val; insert_time=time(0); } return *this; }; }; int size; std::vector elements; typedef typename std::vector::iterator element_iterator; typedef typename std::map::iterator id_iterator; typedef typename std::multimap::iterator time_iterator; std::map id_index; std::multimap time_index; time_t ttl; size_t hits; size_t misses; public: // constructors row_cache(int newsize=1024, time_t newttl=3600) : size(newsize), ttl(newttl), hits(0), misses(0) { invalidate_all(); }; ~row_cache() { #ifndef _NDEBUG print_stats(); #endif }; void print_stats() { printf("Cache statistics on %s\n",T::table_name); printf("%ld hits %ld misses %f percent hit rate\n", misses, hits, (double)hits/(hits+misses)); } void invalidate_all() { elements.clear(); elements.reserve(size); time_index.clear(); id_index.clear(); }; void set_size(int newsize) { size=newsize; invalidate_all(); } int get_size() { return(size); } void set_ttl(time_t newttl) { ttl=newttl; } time_t get_ttl() { return(ttl); } void insert(const T &val) { element_iterator inserted; if (elements.size() < size) { // not full yet, just push_back() elements.push_back(val); inserted=elements.end()-1; } else { // We're full so we'll find the oldest element to overwrite. time_iterator oldest=time_index.begin(); inserted=oldest->second; // remove it from the indexes id_index.erase(id_index.find(inserted->item.id)); time_index.erase(oldest); // overwrite the old cache item with the new one. *inserted=val; } // add the new item to the indexes. id_index[inserted->item.id]=inserted; time_index.insert(std::pair(inserted->insert_time,inserted)); }; T *find(sqlint8_t id) { id_iterator i=id_index.find(id); if ((i == id_index.end()) || (i->second->insert_time+ttl < time(0))) { misses++; return NULL; } hits++; return &(i->second->item); }; }; boinc-app-seti_8.00~svn3701.orig/db/sqldefs.h0000644000175000017500000000257110775255213020725 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef _SQLDEFS_H_ #define _SQLDEFS_H_ #ifndef CLIENT #ifdef USE_INFORMIX #include "int8.h" #include "sqlca.h" #include "sqlda.h" #include "locator.h" #include "sqltypes.h" #include "sqlstype.h" #ifdef MAX_QUERY_LEN #undef MAX_QUERY_LEN #endif namespace sql { static const int MAXBLOB=8192; static const int MAXVARCHAR=255; static const int MAXCURSORS=20; static const int MAX_QUERY_LEN=8192; } #elif defined(USE_MYSQL) #include "mysql.h" namespace sql { static const int MAXBLOB=4096; static const int MAXVARCHAR=255; static const int MAXCURSORS=20; static const int MAX_QUERY_LEN=8192; } #endif #endif #endif boinc-app-seti_8.00~svn3701.orig/db/db_table.h0000644000175000017500000003674113073254736021031 0ustar locutuslocutus// $Id: db_table.h,v 1.45.2.10 2007/05/31 22:03:18 korpela Exp $ // Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef _DB_TABLE_H_ #define _DB_TABLE_H_ #include "sah_config.h" #include #include #include #include #include "track_mem.h" #include "sqlrow.h" #include "sqlblob.h" #include "sqlint8.h" #include "db_util.h" #ifndef CLIENT #include "sqlapi.h" #endif #include "row_cache.h" template class db_type : public track_mem { private: static const char * const type_name; static const char * const column_names[]; public: db_type(T &t); ~db_type(); db_type &operator =(const T &t); db_type &operator =(const db_type &t); void clear() { *me = T(); }; std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=1, const char *tag=type_name) const; const char *search_tag(const char *s=0); operator T(); static int nfields() { return _nfields; }; private: T *me; static const char * _search_tag; static const int _nfields; }; template class db_table; template std::ostream &operator <<(std::ostream &o, const db_type &a) { o << a.print_xml(); return o; } template std::ostream &operator <<(std::ostream &o, const db_table &a) { o << a.me->print_xml(); return o; } template std::istream &operator >>(std::istream &i, db_table &a) { std::string s; static std::string remainder(""); std::string s_tag("<"); std::string e_tag("> s; if (!found && xml_match_tag(s,s_tag.c_str())) { found=true; a.clear(); } if (found) buffer+=(s+' '); if (found && xml_match_tag(s,e_tag.c_str())) { found=false; done=true; } } a.me->parse_xml(buffer); std::string::size_type p=buffer.find(e_tag); if (p != std::string::npos) { p=buffer.find('>',p+1); if (p != std::string::npos) { remainder=buffer.substr(p,buffer.size()-p); } else { remainder=std::string(""); } } return i; } #ifdef _WIN32 #undef DELETE #endif template class db_table : public track_mem { public: db_table(T &t, SQL_CURSOR c); ~db_table(); #ifndef CLIENT sqlint8_t insert(sqlint8_t lid=0); std::string update_format() const; std::string insert_format() const; std::string select_format() const; bool update(); bool fetch(sqlint8_t lid=0); bool cached_fetch(sqlint8_t lid=0); bool fetch(const std::string &where); bool authorize_delete(bool auth) {return delete_flag=auth;}; bool DELETE(sqlint8_t lid=0); bool DELETE(const std::string &where); bool open_query(const std::string &where="",const std::string &order="",const std::string &directives=""); bool get_next(bool cache_result); bool get_next() { return get_next(false); }; bool close_query(); static int nfields() { return _nfields; }; sqlint8_t count(const std::string &where=""); SQL_CURSOR get_cursor(); int set_cache_size(int i) { cache.set_size(i); return(cache.get_size()); }; time_t set_cache_ttl(time_t i) { cache.set_ttl(i); return(cache.get_ttl()); }; #endif const char *search_tag(const char *s=0); operator T(); db_table &operator =(const T &t); db_table &operator =(const db_table &t); void clear() { *me = T(); }; #if !defined(_WIN32) || (_MSC_VER > 1300) || defined(__MINGW32__) friend std::ostream &operator <<(std::ostream &o, const db_table &a); friend std::istream &operator >>(std::istream &i, db_table &a); #else friend std::ostream &operator <<(std::ostream &o, const db_table &a); friend std::istream &operator >>(std::istream &i, db_table &a); #endif static const char * const table_name; private: T *me; static row_cache cache; static const char *_search_tag; static const int _nfields; static const char * const column_names[]; bool delete_flag; SQL_CURSOR cursor; }; template row_cache db_table::cache; #ifndef NEBULA template class db_reference { private: T r; public: ID_TYPE &id; db_reference(ID_TYPE req_id=0); db_reference(const db_reference &a) : r(a.r), id(*(ID_TYPE *)(&(r.id))) {}; T &get(); std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=1, const char *tag=0) const; void parse_xml(std::string &buf, const char *tag); void parse(const std::string &buf); void parse(const SQL_ROW &buf); operator T() const; T *operator ->(); const T *operator ->() const; db_reference &operator =(const T &t); db_reference &operator =(const db_reference &t); }; template db_reference::db_reference(ID_TYPE req_id) : id(*(ID_TYPE *)(&(r.id))) { id=req_id; } template db_reference &db_reference::operator =(const T &t) { if (&id != &(t.id)) { r=t; } return *this; } template db_reference &db_reference::operator =(const db_reference &t) { if (&id != &(t.id)) { r=t.r; } return *this; } template db_reference::operator T() const { return r; } template T *db_reference::operator ->() { return &r; } template const T *db_reference::operator ->() const { return &r; } template std::string db_reference::print(int full_subtables, int show_ids, int no_refs) const { if (full_subtables) { return r.print(full_subtables,show_ids,no_refs); } else { char buf[256]; sprintf(buf,"%" INT8_FMT,INT8_PRINT_CAST(sqlint8_t(r.id))); return std::string(buf); } } template std::string db_reference::print_xml(int full_subtables, int show_ids, int no_refs, const char *tag) const { if (full_subtables) { return r.print_xml(full_subtables,show_ids,no_refs,tag); } else { char buf[256]; sprintf(buf,"%" INT8_FMT "",INT8_PRINT_CAST(sqlint8_t(r.id))); return std::string(buf); } } template void db_reference::parse(const std::string &buf) { r.parse(buf); } template void db_reference::parse(const SQL_ROW &buf) { r.parse(buf); } template void db_reference::parse_xml(std::string &buf, const char *tag) { r.parse_xml(buf,tag); } template std::ostream &operator <<(std::ostream &o, const db_reference &a) { o << a.print_xml(); return o; } #endif // NEBULA template db_type::db_type(T &t) : track_mem(T::type_name), me(&t) {} template db_type::~db_type() {} template db_table::db_table(T &t, SQL_CURSOR c) : track_mem(T::table_name), me(&t), delete_flag(false), cursor(c) {} template db_table::~db_table() {} template db_type::operator T() { return *me; } template db_table::operator T() { return *me; } #ifndef CLIENT template sqlint8_t db_table::insert(sqlint8_t lid) { int rv=0; std::string query=std::string("insert into ")+table_name+" values ("+me->insert_format()+");"; // jeffc me->id=lid; std::string tmpstr(me->print()); // old SQL_ROW valarr(tmpstr.c_str(),_nfields); SQL_ROW valarr(&tmpstr,_nfields); const char *q=query.c_str(); while (*q) { if (*(q++)=='?') rv++; } if ((int)valarr.argc() != rv) { std::cout << "Error " << valarr.argc() << "!=" << rv << std::endl; std::cout << query << std::endl; for (int i=0; i<(int)valarr.argc(); i++) { std::cout << i << " " << valarr[i] << std::endl; } } #ifndef NODB rv=sql_open(query.c_str(),valarr); if (rv>=0 && sql_fetch(rv)) { me->id=sql_insert_id(rv); sql_close(rv); return static_cast(me->id); } #else std::cout << query << std::endl; #endif return 0; } template sqlint8_t db_new(T &t) { return (static_cast *>(&t)->insert()); } template bool db_table::update() { char buf[256]; int rv,i; sprintf(buf," where id=%"INT8_FMT,INT8_PRINT_CAST(sqlint8_t(me->id))); #if 0 std::string query=std::string("update ")+table_name+" set ("; for (i=1;i<_nfields-1;i++) query+=std::string(column_names[i])+','; query+=std::string(column_names[i])+")=("+me->update_format()+") "; #else std::string query=std::string("update ")+table_name+" set "; for (i=1;i<_nfields-1;i++) query+=std::string(column_names[i])+"=?,"; query+=std::string(column_names[i])+"=?"; #endif std::string tmpstr(me->print()); // old SQL_ROW valarr(SQL_ROW(tmpstr.c_str(),_nfields)+1); SQL_ROW valarr(SQL_ROW(&tmpstr,_nfields)+1); query+=buf; #ifndef NODB rv=sql_run(query.c_str(),valarr); #else std::cout << query << std::endl; rv=true; #endif return rv; } template bool db_update(T &t) { return (static_cast *>(&t)->update()); } template bool db_table::DELETE(sqlint8_t lid) { bool rv; char buf[256]; if (!delete_flag) return false; if (lid) me->id=lid; sprintf(buf," where id=%"INT8_FMT,INT8_PRINT_CAST(sqlint8_t(me->id))); std::string query=std::string("delete from ")+table_name+std::string(buf); rv=sql_run(query.c_str()); delete_flag=false; return rv; } template bool db_table::DELETE(const std::string &where) { bool rv; if (!delete_flag) return false; if (where.size() = 0) return false; std::string query=std::string("delete from ")+table_name+std::string(" ")+where; rv=sql_run(query.c_str()); delete_flag=false; return rv; } template bool db_table::cached_fetch(sqlint8_t lid) { T *item; if (!lid) { lid=me->id; } if ((item=cache.find(lid)) != NULL) { *this=*item; return true; } else { bool rv=fetch(lid); if (rv) cache.insert(*this); return rv; } } template bool db_table::fetch(sqlint8_t lid) { char buf[1024]; int tmp; SQL_ROW values; int rv; bool rv2=false; if (!lid) { lid=me->id; } sprintf(buf,"select * from %s where id=%"INT8_FMT,table_name,lid); #ifndef NODB if (((rv=sql_open(buf))>=0) && (rv2=sql_fetch(rv))) { values=sql_values(rv,&tmp); me->parse(values); } if (rv>=0) sql_close(rv); #else std::cout << buf << std::endl; #endif return (rv2); } template bool db_table::fetch(const std::string &where) { char buf[1024]; int tmp; SQL_ROW values; int rv; bool rv2=false; sprintf(buf,"select * from %s %s",table_name,where.c_str()); #ifndef NODB if (((rv=sql_open(buf))>=0) && (rv2=sql_fetch(rv))) { values=sql_values(rv,&tmp); me->parse(values); } if (rv>=0) sql_close(rv); #else std::cout << buf << std::endl; rv=0; #endif return (rv2); } template bool db_table::open_query(const std::string &where,const std::string &order,const std::string &directives) { bool rv; std::string query=std::string("select ")+directives+" * from "+table_name+" "+where+" "+order; #ifndef NODB if (cursor>=0) sql_close(cursor); rv=(chk_cursor(cursor=sql_open(query.c_str()),"db_table<>::open_query")); if (!rv) { sql_close(cursor); cursor=-1; } return (cursor>=0); #else std::cout << query << std::endl; return true; #endif } template bool db_table::get_next(bool cache) { int rv; static bool is_signal, init; if(!init) { if(strcmp(table_name,"spike") == 0 || strcmp(table_name,"spike_small") == 0 || strcmp(table_name,"gaussian") == 0 || strcmp(table_name,"gaussian_small") == 0 || strcmp(table_name,"pulse") == 0 || strcmp(table_name,"pulse_small") == 0 || strcmp(table_name,"triplet") == 0 || strcmp(table_name,"triplet_small") == 0 || strcmp(table_name,"autocorr") == 0 || strcmp(table_name,"autocorr_small") == 0) { is_signal = true; } init = true; } #ifndef NODB if ((rv=sql_fetch(cursor))) { SQL_ROW r(sql_values(cursor,&rv)); me->parse(r); if(is_signal) { signal_preprocess(me); } } else { sql_close(cursor); } return (rv); #else static int i=30; me->id=i; return ((i--)>0); #endif } template bool db_table::close_query() { #ifndef NODB if (cursor>=0) sql_close(cursor); #endif cursor=-1; return cursor; } template sqlint8_t db_table::count(const std::string &where) { std::string query=std::string("select count(*) from ")+table_name+" "+where; int fd,rv=0; sqlint8_t lrv=-1; #ifndef NODB if ((fd=sql_open(query.c_str()))>=0) { if (sql_fetch(fd)) { SQL_ROW r(sql_values(fd,&rv)); if (rv) { lrv=atoll(r[0]->c_str()); } } sql_close(fd); } return lrv; #else return 30; #endif } #endif template const char *db_type::search_tag(const char *s) { if (s) { _search_tag=s; } else { _search_tag=type_name; } return _search_tag; } template const char *db_table::search_tag(const char *s) { if (s) { _search_tag=s; } else { _search_tag=table_name; } return _search_tag; } template std::string db_type::print(int full_subtables, int show_ids, int no_refs) const { return me->print(full_subtables,show_ids,no_refs); } template std::string db_type::print_xml(int full_subtables, int show_ids, int no_refs, const char *tag) const { return me->print_xml(full_subtables,show_ids,no_refs,tag); } template db_type &db_type::operator =(const T &t) { if (me != &t) { *me=t; } return *this; } template db_type &db_type::operator =(const db_type &t) { if (this != &t) { *me=*(t.me); } return *this; } template db_table &db_table::operator =(const T &t) { if (me != &t) { *me=t; cursor=-1; } return *this; } template db_table &db_table::operator =(const db_table &t) { if (this != &t) { *me=*(t.me); cursor=-1; } return *this; } #endif boinc-app-seti_8.00~svn3701.orig/db/sqlmysql.cpp0000644000175000017500000001705512136062447021505 0ustar locutuslocutus// Copyright (c) 1999-2013 Regents of the University of California // // FFTW: Copyright (c) 2003,2006-2011 Matteo Frigo // Copyright (c) 2003,2006-2011 Massachusets Institute of Technology // // fft8g.[cpp,h]: Copyright (c) 1995-2001 Takya Ooura // // ASMLIB: Copyright (c) 2004 Agner Fog // 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, 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; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions // as an alternative to FFTW and distribute a linked executable and // source code. You must obey the GNU General Public License in all // respects for all of the code used other than the FFT library itself. // Any modification required to support these libraries must be distributed // under the terms of this license. If you modify this program, you may extend // this exception to your version of the program, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. Please be aware that FFTW and ASMLIB are not covered by // this exception, therefore you may not use FFTW and ASMLIB in any derivative // work so modified without permission of the authors of those packages. #include "sah_config.h" #include #include #include #include #include #include "sqlapi.h" struct CURSOR { CURSOR() : active(0), is_select(1), rp(0), current_row(0) {}; int active; int is_select; MYSQL_RES *rp; MYSQL_ROW current_row; }; MYSQL* mysql; char sql_dbname[256]; const char *myerrormsg; CURSOR cursor_arr[sql::MAXCURSORS]; bool chk_cursor(SQL_CURSOR fd, const char *s) { bool rv=true; if (fd<0) rv=false; if (fd>(sql::MAXCURSORS-1)) rv=false; if (rv) rv=(cursor_arr[fd].active); if (!rv) { myerrormsg=s; fprintf(stderr,"%s: %s\r\n",s,sql_error_message()); } else { myerrormsg=0; } return (rv); } // convert ' to \' in place static void escape_single_quotes(char* field) { char buf[sql::MAX_QUERY_LEN]; char* q = buf, *p = field; while (*p) { if (*p == '\'') { *q++ = '\\'; *q++ = '\''; } else { *q++ = *p; } p++; } *q = 0; strcpy(field, buf); } static void unescape_single_quotes(char* p) { char* q; while (1) { q = strstr(p, "\\'"); if (!q) break; strcpy(q, q+1); } } bool sql_database(const char* dbname, const char* password, int exclusive) { char buf[256], *p, *host; if ((!dbname) || (strlen(dbname)==0)) { dbname=getenv("DATABASE"); } buf[0]=0; if (dbname) { strncpy(buf,dbname,254); strncpy(sql_dbname,dbname,254); buf[255]=0; } if ((p=strchr(buf,'@'))) { host=p+1; *p=0; } else { host=0; } mysql = mysql_init(0); if (!mysql) { fprintf(stderr,"mysql_init() failed:"); fprintf(stderr,"%s\r\n",sql_error_message()); return false; } if (buf[0]) { mysql = mysql_real_connect(mysql, host, 0, password, buf, 0, 0, 0); } else { mysql = mysql_real_connect(mysql, host, 0, password, 0, 0, 0, 0); } if (!mysql) { fprintf(stderr,"mysql_real_connect(%p,%s,0,%s,%s,0,0,0) failed:",mysql,host,password,buf); fprintf(stderr,"%s\r\n",sql_error_message()); return false; } return true; } bool sql_run(const char *stmt, SQL_ROW &argv) { SQL_CURSOR fd; bool ret=true; fd = sql_open(stmt, argv); if (ret=chk_cursor(fd, stmt)) { if (cursor_arr[fd].is_select) { ret=sql_fetch(fd); if (ret) { argv=sql_values(fd); } else { ret=chk_cursor(fd, stmt); } } } if (fd>=0) sql_close(fd); return ret; } int begin_work() { return mysql_query(mysql,"begin"); } int commit_work() { return mysql_query(mysql,"commit"); } int rollback_work() { return mysql_query(mysql,"rollback"); } bool sql_finish() { mysql_close(mysql); return 1; } sqlint8_t sql_insert_id(SQL_CURSOR fd) { return mysql_insert_id(mysql); } int sql_error_code() { return mysql_errno(mysql); } const char *sql_error_message() { return mysql?mysql_error(mysql):"Not connected"; } bool sql_exists(const char *table, const char *field, const char *value, const char *where) { char stmt[sql::MAX_QUERY_LEN]; SQL_CURSOR c; int rv=false; if (value && *value) { sprintf(stmt,"select '1' from %s where %s = %s", table, field, value); } else { sprintf(stmt,"select '1' from %s",table); if (where && *where) { sprintf(stmt+strlen(stmt),"where %s",where); } } if (((c=sql_open(stmt))>=0) && sql_fetch(c)) { rv=true; } sql_close(c); return rv; } bool sql_fetch(SQL_CURSOR c) { return ((!(cursor_arr[c].is_select)) || (cursor_arr[c].active && cursor_arr[c].rp && (cursor_arr[c].current_row=mysql_fetch_row(cursor_arr[c].rp)))) ; } SQL_ROW sql_values(SQL_CURSOR c, int *num, int dostrip) { SQL_ROW rv; if (cursor_arr[c].active && cursor_arr[c].rp) { MYSQL_RES *rp=cursor_arr[c].rp; const char **row=const_cast(cursor_arr[c].current_row); if (row) { if (num) { *num=mysql_num_fields(rp); } rv=SQL_ROW(row,mysql_num_fields(rp)); } } return rv; } SQL_CURSOR allocate_cursor() { int i=0; while (cursor_arr[i].active && (i=0)) { //printf("mysql= %p",mysql); fflush(stdout); rv=mysql_real_query(mysql,query.c_str(),query.size()); //printf("rv= %d",rv); fflush(stdout); } else { //fprintf(stderr,"field mismatch: %d != %d in %s\r\n",argv.argc(),n_sub,query.c_str()); } if (rv) { chk_cursor(c,"mysql_real_query"); free_cursor(c); return -1; } if (store_result(c)) { cursor_arr[c].is_select=1; } else { if (mysql_field_count(mysql)!=0) { fprintf(stderr,"mysql_field_count()!=0 : %s\r\n",query.c_str()); free_cursor(c); return -1; } cursor_arr[c].is_select=0; } return c; } boinc-app-seti_8.00~svn3701.orig/db/schema_master.sql0000644000175000017500000007634013041730641022444 0ustar locutuslocutus-- Copyright 2003 Regents of the University of California -- SETI_BOINC is free software; you can redistribute it and/or modify it under -- the terms of the GNU General Public License as published by the Free -- Software Foundation; either version 2, or (at your option) any later -- version. -- SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT -- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -- more details. -- You should have received a copy of the GNU General Public License along -- with SETI_BOINC; see the file COPYING. If not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -- In addition, as a special exception, the Regents of the University of -- California give permission to link the code of this program with libraries -- that provide specific optimized fast Fourier transform (FFT) functions and -- distribute a linked executable. You must obey the GNU General Public -- License in all respects for all of the code used other than the FFT library -- itself. Any modification required to support these libraries must be -- distributed in source code form. If you modify this file, you may extend -- this exception to your version of the file, but you are not obligated to -- do so. If you do not wish to do so, delete this exception statement from -- your version. create database sah2b@sah_master_tcp in sah2dbs; -- informix create row type coordinate_t ( time float, ra float, dec float ); create row type chirp_parameter_t ( chirp_limit smallfloat, fft_len_flags integer -- bitfield ); create row type subband_description_t ( number integer, center float, base float, sample_rate float ); create row type data_description_t ( start_ra float, start_dec float, end_ra float, end_dec float, true_angle_range smallfloat, time_recorded varchar(255), time_recorded_jd float, nsamples integer, coords list(coordinate_t not null) ); create table receiver_config ( id serial primary key, s4_id integer unique, name varchar(255) unique, beam_width smallfloat, -- degrees center_freq float, -- MHz latitude float, longitude float, elevation float, glat float, glon float, galt float, diameter smallfloat, az_orientation float, az_corr_coeff list(float not null), zen_corr_coeff list(float not null), array_az_ellipse float default 0 not null, array_za_ellipse float default 0 not null, array_angle float default 0 not null, min_vgc integer default 0, polarization char(32) ); create table recorder_config ( id serial primary key, name char(64), bits_per_sample integer, sample_rate float, beams integer, version smallfloat unique ); create table splitter_config ( id serial primary key, version smallfloat, data_type char(64), fft_len integer, ifft_len integer, filter char(64), window char(64), samples_per_wu integer default 1048576 not null, highpass smallfloat default 0 not null, blanker_filter char(64) default "none" not null, pfb_ntaps integer not null, pfb_width_factor smallfloat not null, wu_bits_per_sample integer default 2 not null ); create table analysis_config ( id serial primary key, spike_thresh smallfloat, spikes_per_spectrum integer, autocorr_thresh smallfloat, autocorr_per_spectrum integer, autocorr_fftlen integer, gauss_null_chi_sq_thresh smallfloat, gauss_chi_sq_thresh smallfloat, gauss_power_thresh smallfloat, gauss_peak_power_thresh smallfloat, gauss_pot_length integer, pulse_thresh smallfloat, pulse_display_thresh smallfloat, pulse_max integer, pulse_min integer, pulse_fft_max integer, pulse_pot_length integer, triplet_thresh smallfloat, triplet_max integer, triplet_min integer, triplet_pot_length integer, pot_overlap_factor smallfloat, pot_t_offset smallfloat, pot_min_slew smallfloat, pot_max_slew smallfloat, chirp_resolution float, analysis_fft_lengths integer, -- bitfield bsmooth_boxcar_length integer, bsmooth_chunk_size integer, chirps list(chirp_parameter_t not null), pulse_beams smallfloat, max_signals integer, max_spikes integer, max_autocorr integer, max_gaussians integer, max_pulses integer, max_triplets integer, keyuniq integer, credit_rate smallfloat ); create table science_config ( id serial primary key, active integer not null, qpix_scheme char(16) not null, qpix_nside integer not null, fpix_width float not null, total_bandwidth float not null, freq_uncertainty float not null, fwhm_beamwidth float not null, sky_disc_radius float not null, observable_sky float not null, epoch integer not null, bary_chirp_window float not null, bary_freq_window integer not null, nonbary_freq_window integer not null, spike_obs_duration float not null, spike_obs_interval float not null, gauss_obs_duration float not null, gauss_obs_interval float not null, pulse_obs_duration float not null, pulse_obs_interval float not null, triplet_obs_duration float not null, triplet_obs_interval float not null, min_spike_id int8, min_autocorr_id int8, min_gaussian_id int8, min_pulse_id int8, min_triplet_id int8, min_app_version float not null, info_xml varchar(255) ); create row type candidate_t ( type integer not null, id int8 not null, num_obs integer not null, score float not null, is_rfi integer not null -- bitfield ); create table meta_candidate ( id serial8 not null, version integer not null, time_last_updated float not null, num_spikes integer not null, num_spike_b_multiplets integer not null, best_spike_b_mp_score float not null, num_spike_nb_multiplets integer not null, best_spike_nb_mp_score float not null, spike_high_id int8 not null, num_gaussians integer not null, num_gaussian_b_multiplets integer not null, best_gaussian_b_mp_score float not null, num_gaussian_nb_multiplets integer not null, best_gaussian_nb_mp_score float not null, gaussian_high_id int8 not null, num_pulses integer not null, num_pulse_b_multiplets integer not null, best_pulse_b_mp_score float not null, num_pulse_nb_multiplets integer not null, best_pulse_nb_mp_score float not null, pulse_high_id int8 not null, num_triplets integer not null, num_triplet_b_multiplets integer not null, best_triplet_b_mp_score float not null, num_triplet_nb_multiplets integer not null, best_triplet_nb_mp_score float not null, triplet_high_id int8 not null, num_stars integer not null, best_star_score float not null, meta_score float not null, rfi_clean integer, state smallint -- 0 : the ntpckr has (re)scored this MC - rfi should look at it -- 1 : the signal set has changed - ntpckr should look at it -- 2 : this is a stable and clean candidate ); create table meta_candidate_tinysky ( id serial8 not null, version integer not null, time_last_updated float not null, num_spikes integer not null, num_spike_b_multiplets integer not null, best_spike_b_mp_score float not null, num_spike_nb_multiplets integer not null, best_spike_nb_mp_score float not null, spike_high_id int8 not null, num_gaussians integer not null, num_gaussian_b_multiplets integer not null, best_gaussian_b_mp_score float not null, num_gaussian_nb_multiplets integer not null, best_gaussian_nb_mp_score float not null, gaussian_high_id int8 not null, num_pulses integer not null, num_pulse_b_multiplets integer not null, best_pulse_b_mp_score float not null, num_pulse_nb_multiplets integer not null, best_pulse_nb_mp_score float not null, pulse_high_id int8 not null, num_triplets integer not null, num_triplet_b_multiplets integer not null, best_triplet_b_mp_score float not null, num_triplet_nb_multiplets integer not null, best_triplet_nb_mp_score float not null, triplet_high_id int8 not null, num_stars integer not null, best_star_score float not null, meta_score float not null, rfi_clean integer, state smallint -- 0 : the ntpckr has (re)scored this MC - rfi should look at it -- 1 : the signal set has changed - ntpckr should look at it -- 2 : this is a stable and clean candidate ); create table multiplet ( id serial primary key, version integer not null, signal_type int not null, mp_type int not null, qpix integer not null, freq_win float not null, mean_ra float not null, mean_decl float not null, ra_stddev float not null, decl_stddev float not null, mean_angular_distance float not null, angular_distance_stddev float not null, mean_frequency float not null, frequency_stddev float not null, mean_chirp float not null, chirp_stddev float not null, mean_period float not null, period_stddev float not null, mean_snr float not null, snr_stddev float not null, mean_threshold float not null, threshold_stddev float not null, score float not null, num_detections integer not null, signal_ids list(int8 not null) ) fragment by expression (mod(id,4)=0) in page_8k_dbs5, (mod(id,4)=1) in page_8k_dbs6, (mod(id,4)=2) in page_8k_dbs7, (mod(id,4)=3) in page_8k_dbs8 extent size 209714 next size 204714; create table star ( id integer not null, object_type varchar(16) not null, catalog_name varchar(64), catalog_number integer, object_name varchar(64), ra smallfloat not null, decl smallfloat not null, qpix integer, v_mag smallfloat, b_minus_v smallfloat, parallax smallfloat, stellar_type varchar(32), planets integer, score smallfloat ); create table candidate_count ( id integer not null, spikes int8 not null, gaussians int8 not null, pulses int8 not null, triplets int8 not null, spike_barycentric_multiplets int8 not null, gaussian_barycentric_multiplets int8 not null, pulse_barycentric_multiplets int8 not null, triplet_barycentric_multiplets int8 not null, spike_nonbarycentric_multiplets int8 not null, gaussian_nonbarycentric_multiplets int8 not null, pulse_nonbarycentric_multiplets int8 not null, triplet_nonbarycentric_multiplets int8 not null, stars int8 not null, time_last_updated integer not null ); create table tape ( id serial primary key, name char(128) not null , start_time float not null , last_block_time float not null , last_block_done integer not null , missed integer not null , tape_quality integer, beam integer default 0 not null -- , -- unique (name,beam) constraint uniq_namebeam ); create table settings ( id serial primary key, active integer, recorder_cfg integer references recorder_config, splitter_cfg integer references splitter_config, analysis_cfg integer references analysis_config, receiver_cfg integer references receiver_config ); create table workunit_grp ( id serial primary key, tape_info integer not null , --references tape name char(128) not null , data_desc data_description_t, receiver_cfg integer references receiver_config, recorder_cfg integer references recorder_config, splitter_cfg integer references splitter_config, analysis_cfg integer references analysis_config, sb_id integer, iq_modified integer, alfa_filter_bank smallint ); create table workunit_header ( id serial8 primary key, name char(128) not null , group_info integer not null , -- references workunit_grp subband_desc subband_description_t, sb_id int8 ) fragment by expression (mod(id,4)=0) in other_dbs001, (mod(id,4)=1) in other_dbs002, (mod(id,4)=2) in other_dbs003, (mod(id,4)=3) in other_dbs004 extent size 209714 next size 204714; create synonym workunit for workunit_header; create table result ( id serial8 primary key, boinc_result int8 not null, wuid int8 not null , -- references workunit_header received float not null, hostid integer not null, versionid integer not null, return_code integer not null, overflow smallint not null, reserved integer not null, sb_id int8 ) fragment by expression (mod(id,4)=0) in other_dbs001, (mod(id,4)=1) in other_dbs002, (mod(id,4)=2) in other_dbs003, (mod(id,4)=3) in other_dbs004 extent size 209714 next size 204714; create table triplet ( id serial8 not null , result_id int8, -- references result peak_power smallfloat not null , mean_power smallfloat not null , time float not null , ra smallfloat not null , decl smallfloat not null , q_pix int8 not null , freq float not null , detection_freq float not null, barycentric_freq float not null, fft_len integer not null , chirp_rate smallfloat not null , rfi_checked int, rfi_found int, reserved integer, period smallfloat not null ) fragment by expression (mod(id,4)=0) in page_16k_dbs1, (mod(id,4)=1) in page_16k_dbs2, (mod(id,4)=2) in page_16k_dbs3, (mod(id,4)=3) in page_16k_dbs4 extent size 1048576 next size 1048576; create table triplet_small ( id serial8 not null , result_id int8, -- references result peak_power smallfloat not null , mean_power smallfloat not null , time float not null , ra smallfloat not null , decl smallfloat not null , q_pix int8 not null , freq float not null , detection_freq float not null, barycentric_freq float not null, fft_len integer not null , chirp_rate smallfloat not null , rfi_checked int, rfi_found int, reserved integer, period smallfloat not null ) fragment by expression (mod(id,4)=0) in small_sig_dbs1, (mod(id,4)=1) in small_sig_dbs2, (mod(id,4)=2) in small_sig_dbs3, (mod(id,4)=3) in small_sig_dbs4 extent size 209714 next size 204714; create table gaussian ( id serial8 not null , result_id int8, -- references result peak_power smallfloat not null , mean_power smallfloat not null , time float not null , ra smallfloat not null , decl smallfloat not null , q_pix int8 not null , freq float not null , detection_freq float not null, barycentric_freq float not null, fft_len integer not null , chirp_rate smallfloat not null , rfi_checked int, rfi_found int, reserved integer, sigma smallfloat not null , chisqr smallfloat not null , null_chisqr smallfloat not null , score smallfloat not null , max_power smallfloat, pot byte -- binary ) fragment by expression (mod(id,4)=0) in page_16k_dbs5, (mod(id,4)=1) in page_16k_dbs6, (mod(id,4)=2) in page_16k_dbs7, (mod(id,4)=3) in page_16k_dbs8 extent size 1048576 next size 1048576; create table gaussian_small ( id serial8 not null , result_id int8, -- references result peak_power smallfloat not null , mean_power smallfloat not null , time float not null , ra smallfloat not null , decl smallfloat not null , q_pix int8 not null , freq float not null , detection_freq float not null, barycentric_freq float not null, fft_len integer not null , chirp_rate smallfloat not null , rfi_checked int, rfi_found int, reserved integer, sigma smallfloat not null , chisqr smallfloat not null , null_chisqr smallfloat not null , score smallfloat not null , max_power smallfloat ) fragment by expression (mod(id,4)=0) in small_sig_dbs1, (mod(id,4)=1) in small_sig_dbs2, (mod(id,4)=2) in small_sig_dbs3, (mod(id,4)=3) in small_sig_dbs4 extent size 209714 next size 204714; create table pulse ( id serial8 not null , result_id int8, -- references result peak_power smallfloat not null , mean_power smallfloat not null , time float not null , ra smallfloat not null , decl smallfloat not null , q_pix int8 not null , freq float not null , detection_freq float not null, barycentric_freq float not null, fft_len integer not null , chirp_rate smallfloat not null , rfi_checked int, rfi_found int, reserved integer, period smallfloat not null , snr smallfloat not null , thresh smallfloat not null , score smallfloat not null , len_prof smallint not null , pot byte -- binary ) fragment by expression (mod(id,4)=0) in other_dbs001, (mod(id,4)=1) in other_dbs002, (mod(id,4)=2) in other_dbs003, (mod(id,4)=3) in other_dbs004 extent size 209714 next size 204714; create table pulse_small ( id serial8 not null , result_id int8, -- references result peak_power smallfloat not null , mean_power smallfloat not null , time float not null , ra smallfloat not null , decl smallfloat not null , q_pix int8 not null , freq float not null , detection_freq float not null, barycentric_freq float not null, fft_len integer not null , chirp_rate smallfloat not null , rfi_checked int, rfi_found int, reserved integer, period smallfloat not null , snr smallfloat not null , thresh smallfloat not null , score smallfloat not null ) fragment by expression (mod(id,4)=0) in small_sig_dbs1, (mod(id,4)=1) in small_sig_dbs2, (mod(id,4)=2) in small_sig_dbs3, (mod(id,4)=3) in small_sig_dbs4 extent size 209714 next size 204714; create table sah_pointing ( time_id integer not null , time float not null , ra float not null , dec float not null , q_pix integer not null, angle_range float not null , bad smallint ); create table sky_map ( npix int8, -- the primary search key qpix int, -- for fast spatial maps fpix int, -- for fast frequency maps spike_max_id int8 , gaussian_max_id int8, pulse_max_id int8, triplet_max_id int8, spike_count int, gaussian_count int, pulse_count int, triplet_count int, new_data smallint, -- a boolean score float ); create table hotpix ( id int, -- qpix last_hit_time int ); create table hotpix_tinysky ( id int, -- qpix last_hit_time int ); create table spike ( id serial8 not null , result_id int8, -- references result peak_power smallfloat not null , mean_power smallfloat not null , time float not null , ra smallfloat not null , decl smallfloat not null , q_pix int8 not null , freq float not null , detection_freq float not null, barycentric_freq float not null, fft_len integer not null , chirp_rate smallfloat not null , rfi_checked int, rfi_found int, reserved integer ) fragment by expression (mod(id,4)=0) in spike21_dbs, (mod(id,4)=1) in spike22_dbs, (mod(id,4)=2) in spike23_dbs, (mod(id,4)=3) in spike24_dbs extent size 2047100 next size 2047100; create table spike_small ( id serial8 not null , result_id int8, -- references result peak_power smallfloat not null , mean_power smallfloat not null , time float not null , ra smallfloat not null , decl smallfloat not null , q_pix int8 not null , freq float not null , detection_freq float not null, barycentric_freq float not null, fft_len integer not null , chirp_rate smallfloat not null , rfi_checked int, rfi_found int, reserved integer ) fragment by expression (mod(id,4)=0) in small_sig_dbs1, (mod(id,4)=1) in small_sig_dbs2, (mod(id,4)=2) in small_sig_dbs3, (mod(id,4)=3) in small_sig_dbs4 extent size 209714 next size 204714; create table autocorr ( id serial8 not null , result_id int8, -- references result peak_power smallfloat not null , mean_power smallfloat not null , time float not null , ra smallfloat not null , decl smallfloat not null , q_pix int8 not null , delay float not null , freq float not null , detection_freq float not null, barycentric_freq float not null, fft_len integer not null , chirp_rate smallfloat not null , rfi_checked int, rfi_found int, reserved integer ) fragment by expression (mod(id,4)=0) in page_16k_dbs9, (mod(id,4)=1) in page_16k_dbs10, (mod(id,4)=2) in page_16k_dbs11, (mod(id,4)=3) in page_16k_dbs12 extent size 1048576 next size 1048576; create table autocorr_small ( id serial8 not null , result_id int8, -- references result peak_power smallfloat not null , mean_power smallfloat not null , time float not null , ra smallfloat not null , decl smallfloat not null , q_pix int8 not null , delay float not null , freq float not null , detection_freq float not null, barycentric_freq float not null, fft_len integer not null , chirp_rate smallfloat not null , rfi_checked int, rfi_found int, reserved integer ) fragment by expression (mod(id,4)=0) in small_sig_dbs1, (mod(id,4)=1) in small_sig_dbs2, (mod(id,4)=2) in small_sig_dbs3, (mod(id,4)=3) in small_sig_dbs4 extent size 209714 next size 204714; create table classic_versions ( id serial not null, ver_major integer not null, ver_minor integer not null, platformid integer not null, comment char(254), filename char(254), md5_cksum char(254), sum_cksum char(254), cksum_cksum char(254), file_cksum integer not null ); create table classic_active_versions ( id integer, versionid integer, ver_major integer, ver_minor integer ); create table classic_active_versionids ( id integer, versionid integer ); create table rfi_zone ( id serial not null, min_receiver_s4id integer not null, max_receiver_s4id integer not null, min_splitter_config integer not null, max_splitter_config integer not null, min_analysis_config integer not null, max_analysis_config integer not null, min_tape_id integer not null, max_tape_id integer not null, min_workunit_id int8 not null, max_workunit_id int8 not null, min_result_id int8 not null, max_result_id int8 not null, min_time float not null, max_time float not null, central_baseband_freq float not null, baseband_freq_width float not null, central_detection_freq float not null, detection_freq_width float not null, central_period float not null, period_width float not null, fft_len_flags int not null, signal_type_flags int not null, ra float not null, dec float not null, angular_distance float not null ); create table bad_data ( name char(128) not null, beam integer default 0 not null, reason varchar(255) ); create table spike_tinysky ( id serial8 not null , result_id int8, -- references result peak_power smallfloat not null , mean_power smallfloat not null , time float not null , ra smallfloat not null , decl smallfloat not null , q_pix int8 not null , freq float not null , detection_freq float not null, barycentric_freq float not null, fft_len integer not null , chirp_rate smallfloat not null , rfi_checked int, rfi_found int, reserved integer ) fragment by expression (mod(id,4)=0) in small_sig_dbs1, (mod(id,4)=1) in small_sig_dbs2, (mod(id,4)=2) in small_sig_dbs3, (mod(id,4)=3) in small_sig_dbs4 extent size 209714 next size 204714; create table gaussian_tinysky ( id serial8 not null , result_id int8, -- references result peak_power smallfloat not null , mean_power smallfloat not null , time float not null , ra smallfloat not null , decl smallfloat not null , q_pix int8 not null , freq float not null , detection_freq float not null, barycentric_freq float not null, fft_len integer not null , chirp_rate smallfloat not null , rfi_checked int, rfi_found int, reserved integer, sigma smallfloat not null , chisqr smallfloat not null , null_chisqr smallfloat not null , score smallfloat not null , max_power smallfloat , pot byte -- binary ) fragment by expression (mod(id,4)=0) in small_sig_dbs1, (mod(id,4)=1) in small_sig_dbs2, (mod(id,4)=2) in small_sig_dbs3, (mod(id,4)=3) in small_sig_dbs4 extent size 209714 next size 204714; create table pulse_tinysky ( id serial8 not null , result_id int8, -- references result peak_power smallfloat not null , mean_power smallfloat not null , time float not null , ra smallfloat not null , decl smallfloat not null , q_pix int8 not null , freq float not null , detection_freq float not null, barycentric_freq float not null, fft_len integer not null , chirp_rate smallfloat not null , rfi_checked int, rfi_found int, reserved integer, period smallfloat not null , snr smallfloat not null , thresh smallfloat not null , score smallfloat not null , len_prof smallint not null , pot byte -- binary ) fragment by expression (mod(id,4)=0) in small_sig_dbs1, (mod(id,4)=1) in small_sig_dbs2, (mod(id,4)=2) in small_sig_dbs3, (mod(id,4)=3) in small_sig_dbs4 extent size 209714 next size 204714; create table triplet_tinysky ( id serial8 not null , result_id int8, -- references result peak_power smallfloat not null , mean_power smallfloat not null , time float not null , ra smallfloat not null , decl smallfloat not null , q_pix int8 not null , freq float not null , detection_freq float not null, barycentric_freq float not null, fft_len integer not null , chirp_rate smallfloat not null , rfi_checked int, rfi_found int, reserved integer, period smallfloat not null ) fragment by expression (mod(id,4)=0) in small_sig_dbs1, (mod(id,4)=1) in small_sig_dbs2, (mod(id,4)=2) in small_sig_dbs3, (mod(id,4)=3) in small_sig_dbs4 extent size 209714 next size 204714; create table autocorr_tinysky ( id serial8 not null , result_id int8, -- references result peak_power smallfloat not null , mean_power smallfloat not null , time float not null , ra smallfloat not null , decl smallfloat not null , q_pix int8 not null , delay float not null , freq float not null , detection_freq float not null, barycentric_freq float not null, fft_len integer not null , chirp_rate smallfloat not null , rfi_checked int, rfi_found int, reserved integer ) fragment by expression (mod(id,4)=0) in small_sig_dbs1, (mod(id,4)=1) in small_sig_dbs2, (mod(id,4)=2) in small_sig_dbs3, (mod(id,4)=3) in small_sig_dbs4 extent size 209714 next size 204714; create index spike_res on spike(result_id); create index autocorr_res on autocorr(result_id); create index gaussian_res on gaussian(result_id); create index pulse_res on pulse(result_id); create index triplet_res on triplet(result_id); create index result_wu on result(wuid); create index workunit_wu_grp on workunit(group_info); create index wugrp_tapenum on workunit(tape_info); alter table workunit_grp add constraint (foreign key (tape_info) references tape (id)); create index wu_grpnum on workunit(group_info); alter table workunit add constraint (foreign key (group_info) references workunit_grp (id)); create index res_wuid on result(wuid); alter table result add constraint (foreign key (wuid) references workunit_header (id)), add constraint unique(boinc_result); create index trip_res on triplet(result_id); alter table triplet add constraint (foreign key (result_id) references result (id)); crete index gauss-res on gaussian(result_id); alter table gaussian add constraint (foreign key (result_id) references result (id)); create index pulse_res on pulse(result_id); alter table pulse add constraint (foreign key (result_id) references result (id)); create index spike_res on spike(result_id); alter table spike add constraint (foreign key (result_id) references result (id) constraint result_spike); create unique index namebeam on tape (name, beam); create index spike_tinysky_res on spike_tinysky(result_id); create unique index spike_tinysky_id on spike_tinysky(id); create index spike_tinysky_qpix on spike_tinysky(q_pix); create index gaussian_tinysky_res on gaussian_tinysky(result_id); create unique index gaussian_tinysky_id on gaussian_tinysky(id); create index gaussian_tinysky_qpix on gaussian_tinysky(q_pix); create index pulse_tinysky_res on pulse_tinysky(result_id); create unique index pulse_tinysky_id on pulse_tinysky(id); create index pulse_tinysky_qpix on pulse_tinysky(q_pix); create index triplet_tinysky_res on triplet_tinysky(result_id); create unique index triplet_tinysky_id on triplet_tinysky(id); create index triplet_tinysky_qpix on triplet_tinysky(q_pix); create index autocorr_tinysky_res on autocorr_tinysky(result_id); create unique index autocorr_tinysky_id on autocorr_tinysky(id); create index autocorr_tinysky_qpix on autocorr_tinysky(q_pix); boinc-app-seti_8.00~svn3701.orig/db/sqlrow.cpp0000644000175000017500000002575712554454501021157 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "sah_config.h" #include #include #include #include #include #include "sqlrow.h" const SQL_ROW empty_row; const std::string empty_string(""); #define found(x) ((x != std::string::npos)) std::string *SQL_ROW::string_delimited(std::string &s, char c_start, char c_end) { // return the substring of a string delimited by c_start and c_end. // c_start and c_end. The substring returned will include everything from // c_start and before the comma or end or string following c_end. std::string::size_type open,cls,strt,comma; std::string::size_type q(s.find(c_start)); // find the opening delimiter. if (found(q)) { strt=q; int nopen=1; // since any of the items inside this type could be sql defined // types themselves, we need to find the matching close delimiter do { open=s.find(c_start,q+1); cls=s.find(c_end,q+1); if (found(cls) && (cls SQL_ROW::parse_delimited(std::string &s,char c_start,char c_end) { // parse a section of a comma separated string delimited by the characters // c_start and c_end. The substring parsed will include everything after // c_start and before the comma or end of string following c_end. This allows // sql types of the format "ROW(a,b,c)::type_name" to be properly parsed // to return a,b and c. std::string *sub(string_delimited(s,c_start,c_end)); // Get delimited string std::string tmp(*sub,1,sub->size()-1); // Remove opening delimiter std::vector rv(parse_row(tmp)); delete sub; #ifdef DEBUG_ALLOCATIONS fprintf(stderr,"std::string deleted at 0x%p\n",sub); fflush(stderr); #endif return rv; } std::vector SQL_ROW::parse_type(std::string &s) { // Parses informix defined types of the format "ROW(a,b,c)::typename" return parse_delimited(s,'(',')'); } std::vector SQL_ROW::parse_list(std::string &s) { // Parses informix lists of the format "LIST{a,b,c}" return parse_delimited(s,'{','}'); } std::string *SQL_ROW::parse_blob(std::string &s) { // Parsed binary objects of the format "fasd874235vxzfdgas" // or binary objects consisting of the entire string. std::string *rv; std::string::size_type etag=s.find('>'); ssize_t length; if (found(etag)) { std::string::size_type p(s.find('=')); if (p SQL_ROW::parse_row(std::string &s) { // parses a SQL row of the format "value,value,value,value", // where value can be of the form: // number (i.e. 10) // "string" // 'string' // LIST{value,value,value} // ROW(value,value,value)::typename // the passed string is consumed by this routine. // WARNING: NOT THREAD SAFE std::string::size_type comma,dquote,quote,p; std::vector::iterator i; std::vector rv; static bool outer=true; while (s.size()) { // While there's still bits of string left to process // get rid of leading spaces and commas while (isspace(s[0]) && s.size()) s.erase(0,1); while (s[0]==',') s.erase(0,1); // Handle the special cases first... if (s.find("LIST")==0) { // only parse a LIST if the entire string passed to parse_row was a list if (outer) { outer=false; std::vector tmprow(parse_list(s)); for (i=tmprow.begin();i tmprow(parse_type(s)); for (i=tmprow.begin();i("SQL_ROW") { if (s) { std::string tmp(*s); pval=parse_row(tmp); } else { pval.clear(); for (size_t i=0;i &t) : track_mem("SQL_ROW") { std::string s(""); size_t i,tot_size=0; for (i=0;i("SQL_ROW") { ssize_t i; std::string *p; if (end_col<(ssize_t)start_col) end_col=(ssize_t)s.argc()-1; for (i=start_col;i<(end_col+1);i++) { if (s.exists(i)) { p=new std::string(*(s[i])); #ifdef DEBUG_ALLOCATIONS fprintf(stderr,"std::string allocated at 0x%p\n",p); fflush(stderr); #endif } else { p=0; } pval.push_back(p); } } SQL_ROW &SQL_ROW::operator =(const SQL_ROW &s) { if (this != &s) { size_t i; std::string *p; for (i=0;i #include #include #include #include #include #include #undef loc_t #include "sqlint8.h" #include "sqlca.h" #include "sqlda.h" #include "sqlhdr.h" #include "locator.h" #include "sqltypes.h" #include "sqlstype.h" #include "sqldefs.h" #include "sqlint8.h" #include "sqlblob.h" #include "sqlrow.h" #include "sqlapi.h" extern sqlca_s sqlca; #ifdef USE_NAMESPACE namespace ifx { #endif #define found(x) ((x != std::string::npos)) struct IFX_LOC_T : private track_mem, public loc_t { IFX_LOC_T() : track_mem("IFX_LOC_T") { // fprintf(stderr,"Creating IFX_LOC_T, this=%x\n",this); // fflush(stderr); memset(this,0,sizeof(IFX_LOC_T)); }; IFX_LOC_T(const IFX_LOC_T &s) : track_mem("IFX_LOC_T") { // fprintf(stderr,"Creating IFX_LOC_T, this=%x\n",this); // fflush(stderr); memcpy(this,&s,sizeof(IFX_LOC_T)); if (s.loc_buffer) { if (s.loc_bufsize) { loc_buffer=new char [s.loc_bufsize]; } else { loc_buffer=new char [strlen(s.loc_buffer)]; loc_bufsize=strlen(s.loc_buffer)+1; loc_size=loc_bufsize; } memcpy(loc_buffer,s.loc_buffer,loc_bufsize); } } IFX_LOC_T(const std::string &s) : track_mem("IFX_LOC_T") { // fprintf(stderr,"Creating IFX_LOC_T, this=%x\n",this); // fflush(stderr); memset(this,0,sizeof(IFX_LOC_T)); loc_loctype=LOCMEMORY; loc_buffer=new char [s.size()+1]; loc_bufsize=s.size(); loc_size=loc_bufsize; memcpy(loc_buffer,s.c_str(),s.size()); loc_buffer[s.size()]=0; } IFX_LOC_T(const char *s, size_t l) : track_mem("IFX_LOC_T") { // fprintf(stderr,"Creating IFX_LOC_T, this=%x\n",this); // fflush(stderr); memset(this,0,sizeof(IFX_LOC_T)); loc_loctype=LOCMEMORY; loc_buffer=new char [l+1]; loc_bufsize=l; loc_size=loc_bufsize; memcpy(loc_buffer,s,l); loc_buffer[l]=0; } ~IFX_LOC_T() { // fprintf(stderr,"In ~IFX_LOC_T()\n"); // fflush(stderr); if (loc_buffer) delete [] loc_buffer; loc_buffer=NULL; } }; struct SQLVAR : private track_mem, public ifx_sqlvar_t { static int ref_cnt; void clear(); bool is_blob() { return ((sqltype == CLOCATORTYPE) || ((sqltype & SQLTYPE) == SQLTEXT) || ((sqltype & SQLTYPE) == SQLBYTES)); } SQLVAR &operator =(const SQLVAR &s); SQLVAR(); SQLVAR(const SQLVAR &s); SQLVAR(const std::string &s); SQLVAR(const IFX_LOC_T &s); ~SQLVAR(); }; int SQLVAR::ref_cnt; SQLVAR::SQLVAR() { // fprintf(stderr,"Creating SQLVAR, this=%x\n",this); // fflush(stderr); sqldata=0; sqltype=0; ref_cnt++; } SQLVAR::SQLVAR(const SQLVAR &s) : track_mem("SQLVAR") { // fprintf(stderr,"Creating SQLVAR, this=%x\n",this); // fflush(stderr); ref_cnt++; memcpy(this,&s,sizeof(SQLVAR)); if (sqltype == CLOCATORTYPE) { IFX_LOC_T *sloc=(IFX_LOC_T *)s.sqldata; IFX_LOC_T *loc=new IFX_LOC_T(*sloc); sqldata=(char *)loc; } else { sqldata=new char [s.sqllen+1]; memcpy(sqldata,s.sqldata,s.sqllen); sqldata[s.sqllen]=0; } } SQLVAR::SQLVAR(const std::string &s) : track_mem("SQLVAR") { // fprintf(stderr,"Creating SQLVAR, this=%x\n",this); // fflush(stderr); ref_cnt++; memset(this,0,sizeof(SQLVAR)); sqltype=CCHARTYPE; sqllen=s.size(); sqldata=new char [s.size()+1]; memcpy(sqldata,s.c_str(),s.size()+1); sqldata[s.size()]=0; } SQLVAR::SQLVAR(const IFX_LOC_T &s) : track_mem("SQLVAR") { // fprintf(stderr,"Creating SQLVAR, this=%x\n",this); // fflush(stderr); ref_cnt++; memset(this,0,sizeof(SQLVAR)); sqltype=CLOCATORTYPE; IFX_LOC_T *loc=new IFX_LOC_T(s); sqllen=sizeof(IFX_LOC_T); sqldata=(char *)loc; } SQLVAR &SQLVAR::operator =(const SQLVAR &s) { if (this != &s) { clear(); memcpy(this,&s,sizeof(SQLVAR)); if (sqltype == CLOCATORTYPE) { IFX_LOC_T *sloc=(IFX_LOC_T *)s.sqldata; IFX_LOC_T *loc=new IFX_LOC_T(*sloc); sqldata=(char *)loc; } else { sqldata=new char [s.sqllen+1]; memcpy(sqldata,s.sqldata,s.sqllen); sqldata[s.sqllen]=0; } } return *this; } void SQLVAR::clear() { if (sqldata) { if (sqltype == CLOCATORTYPE) { delete (IFX_LOC_T *)sqldata; } else { delete [] sqldata; } sqldata=NULL; } } SQLVAR::~SQLVAR() { ref_cnt--; // fprintf(stderr,"Destroying SQLVAR() this=%x\n",this); // fflush(stderr); clear(); } struct SQLDA : public track_mem, public ifx_sqlda_t { void resize(int argc) { int i; if (argc>sqld) { SQLVAR *tmp=(SQLVAR *)sqlvar; sqlvar=new SQLVAR [argc]; if (tmp) { for (i=0;i { char *cmd; unsigned int opened:1; unsigned int is_select:1; SQLDA *in; SQLDA *out; SQLDA *exec; int *arr_sqltype; int arr_sqltype_len; int *arr_sqllen; char p_name[19]; char c_name[19]; sqlint8_t insert_id; SSQL() : cmd(0), opened(0), is_select(0), in(0), out(0), exec(0), arr_sqltype(0), arr_sqltype_len(0), arr_sqllen(0), insert_id(0) { p_name[0]=0; c_name[0]=0; } }; static char *null_cmd=""; #define debug(s) s #define errmalloc(pointer, func, len) \ if (!pointer) {\ sprintf(errmsg, "Cannot malloc for %uld in %s errno %d",len,func,errno);\ debug(fprintf(stderr, "%s\n", errmsg));\ return false;\ } #define is_hex_digit(c) \ ((((c)>='0') && ((c)<='9')) || (((c)>='a') && ((c)<='f')) || (((c)>='A') && ((c)<='F'))) #define make_into_char(arg) \ (((arg) >= 'A' && (arg) <= 'F')?((arg) - 'A' + 10):\ (((arg) >= 'a' && (arg) <= 'f')?((arg) - 'a' + 10):(arg-'0'))) bool print_status(const char *p1,const char *p2); int chk_status(int fd, const char *p1, const char *p2) { int sav=sql_error_code(); if (sav != 0) { if (sav < 0) { sql_close(fd); print_status(p1, p2); return (sav); } print_status(p1,p2); } return 0; } static SSQL ssql[sql::MAXCURSORS+1]; static char *database_name; static char *connection_name; static char errmsg[1024+1]; #ifndef lint static char const rcs[] = "@(#)$Id: sqlifx.ec,v 1.22.2.7 2007/04/23 22:04:07 jeffc Exp $"; #endif sqlint8_t sql_insert_id() { sqlint8_t rv(0); ifx_int8_t val; char a[256]; a[0]=0; ifx_getserial8(&val); ifx_int8toasc(&val,&a[0],24); a[255]=0; sscanf(a,"%"INT8_FMT,&rv); if (!rv) { rv=static_cast(sqlca.sqlerrd[1]); } return rv; } #define INSERT_ID sql_insert_id() sqlint8_t sql_insert_id(SQL_CURSOR fd) { return ssql[fd].insert_id; } bool chk_cursor(SQL_CURSOR fd, const char *function) { if (fd < 0 || fd >= sql::MAXCURSORS || !ssql[fd].cmd) { sprintf(errmsg, "Invalid fd %d passed to %s()", fd, function); debug(fprintf(stderr, "%s\n", errmsg)); return false; } return true; } /* removes trailing white spaces */ static void strip(std::string &s) { while (s.size() && isspace(s[s.size()-1])) { s.erase(s.size()-1,1); } } static void strip(char *s, int len) { while (len>=0 && s[len]) s[len--]=0; } static void undelimit(std::string &s,char c_start,char c_end) { while (s.size() && (isspace(s[0]) || (s[0]==c_start))) s.erase(0,1); while (s.size() && (isspace(s[s.size()-1]) || (s[s.size()-1]==c_end))) s.erase(s.size()-1,1); } /* Using the previous SQL error code, format the Informix error message */ bool print_status(const char *p1, const char *p2) { int retcode = sql_error_code(); if (retcode < 0) { int msglen; errmsg[0] = '\0'; rgetlmsg(sql_error_code(), errmsg, sizeof(errmsg), &msglen); if (sqlca.sqlerrd[1]) { int len = strlen(errmsg); errmsg[len] = '\0'; rgetlmsg(sqlca.sqlerrd[1], &errmsg[len], sizeof(errmsg) - len, &msglen); } strip(sqlca.sqlerrp,strlen(sqlca.sqlerrp)); sprintf(&errmsg[strlen(errmsg)], "%d:%ld:%s %s %s %s\n", sql_error_code(), sqlca.sqlerrd[1], sqlca.sqlerrp, sqlca.sqlerrm, p1, p2); debug(fprintf(stderr, "%s\n", errmsg)); } return (retcode>=0); } /* Set explain on or off */ bool sql_explain(int n) { int fd=0; if (n) { $set explain on; chk_status(fd,"sql_explain","set explain on"); } else { $set explain off; chk_status(fd,"sql_explain","set explain off"); } return ((sql_error_code())==0); } /* Return the error message stored in the buffer */ const char *sql_error_message(void) { return errmsg; } /* ** Check whether column (field) exists in table with value specified by val ** subject to additional constraints specified in where. ** ** returns ** true if field exists in table, ** false otherwise */ static int alloc_stmt(); bool sql_exists(const char *table, const char *field, const char *p_val, const char *where) { $char *value = const_cast(p_val); $char stmt[sql::MAXBLOB+1]; $char result[2]; int fetch_code = 0; /* NOTUSED */ int fd=alloc_stmt(); if (value && *value != '\0') { sprintf(stmt, "select '1' from %s where %s = ?", table, field); if (where && *where != '\0') sprintf(&stmt[strlen(stmt)], " and %s", where); } else { sprintf(stmt, "select '1' from %s", table); if (where && *where != '\0') sprintf(&stmt[strlen(stmt)], " where %s", where); } $prepare pexist from $stmt; if (chk_status(fd,"PREPARE(EXISTS)", stmt)) return false; $declare pexist_cur cursor for pexist; if (chk_status(fd,"DECLARE(EXISTS)", stmt)) return false; if (value && *value != '\0') $open pexist_cur using $value; else $open pexist_cur; if (chk_status(fd,"OPEN(EXISTS)", stmt)) return false; $fetch pexist_cur into $result; fetch_code = sql_error_code(); $close pexist_cur; sql_close(fd); return (fetch_code==0); } std::string decode_hex(std::string input) { std::string tgt; int i,j; tgt.resize(input.size()/2); for (i = j = 0; i < input.size(); i += 2) { if (!is_hex_digit(input[i]) || !is_hex_digit(input[i+1])) return input; tgt[j++] = make_into_char(input[i])*16 + make_into_char(input[i+1]); } return tgt; } static bool sql_set_values(SQL_CURSOR fd, SQL_ROW &argv) { SQLVAR *col; SQLVAR *ecol; SQLDA *udesc; SQLDA *edesc; int i; int argc=argv.argc(); udesc = ssql[fd].in; edesc = ssql[fd].exec; if (argc > 0) { if (edesc && (argc > edesc->sqld)) { edesc->resize(argc); } if (udesc && argc != udesc->sqld) { sprintf(errmsg, "Incorrect number (%d) of bind variables specified - %d required", argc, udesc->sqld); debug(fprintf(stderr, "%s\n", errmsg)); return false; } if (udesc) delete (SQLDA *)udesc; udesc = ssql[fd].in = new SQLDA(argc); if (edesc && edesc->sqld <= 0) edesc = NULL; if (edesc && edesc->sqlvar) ecol = (SQLVAR *)edesc->sqlvar; else ecol = NULL; for (i = 0, col = (SQLVAR *)udesc->sqlvar; i < argc; i++, col++) { int blob = 0; /* Is our column a blob? */ if (ecol) { if (ecol->is_blob()) blob = 1; } if (!argv.exists(i)) argv[i]=new std::string(""); /* remove leading and trailing single quotes */ undelimit(*(argv[i]),'\'','\''); /* Check for blobs */ if (blob) { /* Remove tags */ if ((argv[i]->find("find("find('>'); if (found(etag)) argv[i]->erase(0,etag+1); } std::string tmpstr=decode_hex(*(argv[i])); IFX_LOC_T tmploc=IFX_LOC_T(tmpstr); SQLVAR tmpvar=SQLVAR(tmploc); *col=tmpvar; } else { SQLVAR tmpvar=SQLVAR(*(argv[i])); *col=tmpvar; } col->sqlname = 0; col->sqlind = 0; if (ecol) ecol++; } } return true; } /* Returns true on successful execution sqlca.sqlcode otherwise */ bool sql_run(const char *stmt, SQL_ROW &argv) { SQL_CURSOR fd; int ret; if (isdigit(stmt[0])) { fd = atoi(stmt); if (!chk_cursor(fd, "sql_run")) sql_close(fd); return false; if (!sql_set_values(fd, argv)) sql_close(fd); return false; return sql_fetch(fd); } fd = sql_open(stmt, argv); if (fd < 0) { sql_close(fd); return false; } ret = sql_fetch(fd); sql_close(fd); return ret; } /* ** Allocate a statement number ** Returns: ** -1: no available statements ** 0..sql::MAXCURSORS-1: new statement number */ static int alloc_stmt() { int i; for (i = 0; i < sql::MAXCURSORS; i++) { if (!ssql[i].cmd) break; } if (i >= sql::MAXCURSORS) { sprintf(errmsg, "FATAL ERROR: Too many open SQL statements (> %d) for sql operations\n", sql::MAXCURSORS); debug(fprintf(stderr, "%s\n", errmsg)); i = -1; exit(1); } else { ssql[i].cmd=null_cmd; sprintf(ssql[i].p_name, "p_%d", i); sprintf(ssql[i].c_name, "c_%d", i); } return(i); } SQL_CURSOR sql_open(const char *sql, SQL_ROW &argv) { SQLVAR *col = 0L; ifx_sqlda_t *udesc = 0L; $char *stmt = const_cast(sql); int i; int fd; int len; char *save; $char *p_name; $char *c_name; int rv; if ((fd = alloc_stmt()) < 0) return(-1); len = strlen(stmt); save = new char [len+1]; strcpy(save, stmt); ssql[fd].cmd = save; p_name = ssql[fd].p_name; $prepare $p_name from $stmt; if (rv=chk_status(fd,"PREPARE(OPEN)", stmt)) return rv; $describe $p_name into udesc; if (rv=chk_status(fd,"DESCRIBE(OPEN)", stmt)) return rv; /** ** The cursory statements are: ** -- EXECUTE PROCEDURE ** -- SELECT without INTO TEMP ** Fortunately, SELECT INTO TEMP is given code SQ_SELINTO ** Unfortunately, SELECT is not given code SQ_SELECT (2) but 0 ** Non-cursory statements need minimal extra attention. */ if ((sql_error_code()) != 0 && ((sql_error_code()) != SQ_EXECPROC || udesc->sqld == 0) && (sql_error_code()) != SQ_SELECT) { ssql[fd].is_select = 0; ssql[fd].exec = (SQLDA *)udesc; if (!sql_set_values(fd, argv)) return sql_close(fd), -1; return fd; } ssql[fd].is_select = 1; ssql[fd].out = (SQLDA *)udesc; if (!udesc) { sprintf(errmsg, "No columns selected !\n"); fprintf(stderr, "No columns selected !\n"); return -1; } for (i = 0, col = (SQLVAR *)udesc->sqlvar; i < udesc->sqld; i++, col++) { int blob = 0; if ((col->sqltype & SQLTYPE) != SQLCHAR && (col->sqltype & SQLTYPE) != SQLVCHAR) { if (col->is_blob()) { blob = 1; } else if ((col->sqltype & SQLTYPE) == SQLROW) { col->sqllen = sql::MAXBLOB; } else if ((col->sqltype & SQLTYPE) == SQLLIST) { col->sqllen = sql::MAXBLOB; } else { col->sqllen = rtypwidth(col->sqltype, col->sqllen); } /* Should allocate at least 12 characters for backward compat. ! */ if (col->sqllen < 12) col->sqllen = 12; } if (blob) { IFX_LOC_T tmploc; tmploc.loc_loctype=LOCMEMORY; tmploc.loc_bufsize=-1; SQLVAR tmpvar(tmploc); *col=tmpvar; } else { std::string tmpstr(col->sqllen+2,0); col->sqllen++; SQLVAR tmpvar(tmpstr); *col=tmpvar; } col->sqlind = new short; *(col->sqlind) = 0; } c_name = ssql[fd].c_name; $declare $c_name cursor for $p_name; if (rv=chk_status(fd,"DECLARE(OPEN)", stmt)) return rv; if (!sql_reopen(fd,argv)) { sql_close(fd); fd=-1; } if (rv=chk_status(fd,"OPEN(OPEN)", stmt)) return rv; ssql[fd].opened = 1; ssql[fd].insert_id=INSERT_ID; return fd; } static int LAST_NON_ZERO_SQLCODE; int sql_error_code() { if (SQLCODE != 0) LAST_NON_ZERO_SQLCODE = SQLCODE; return SQLCODE; } int sql_last_error_code() { return LAST_NON_ZERO_SQLCODE; } void sql_reset_error_code() { LAST_NON_ZERO_SQLCODE=0; } bool sql_reopen(SQL_CURSOR fd, SQL_ROW &argv) { struct sqlda *udesc; $ char *c_name; if (!chk_cursor(fd, "sql_reopen")) return false; if (!sql_set_values(fd, argv)) return false; udesc = ssql[fd].in; c_name = ssql[fd].c_name; if (udesc && udesc->sqld) $open $c_name using descriptor udesc; else $open $c_name; if (chk_status(fd,"OPEN","sql_reopen()")) return false; return (sql_error_code()>=0); } /* ** If this is a non-cursory statement, sql_fetch() executes the statement. ** If this is a cursory statement, then it fetches a row of data. */ bool sql_fetch(SQL_CURSOR fd) { int ret; SQLDA *udesc; if (!chk_cursor(fd, "sql_fetch")) return false; if (!ssql[fd].is_select) { $char *p_name = ssql[fd].p_name; udesc = ssql[fd].in; if (udesc) $execute $p_name using descriptor udesc; else $execute $p_name; ret = sql_error_code(); if (chk_status(fd,"EXECUTE(RUN)", ssql[fd].cmd)) return false; } else { $char *c_name = ssql[fd].c_name; udesc = ssql[fd].out; if (udesc && udesc->sqld) $fetch $c_name using descriptor udesc; else $fetch $c_name; ret = sql_error_code(); if (chk_status(fd,"FETCH(OPEN)", ssql[fd].cmd)) return false; } ssql[fd].insert_id=INSERT_ID; return ((ret>=0) && (ret!=100)); } /* Convert (blob) memory to hex encoding used in UNLOAD */ static char *convert_ascii(const char *str, int len) { int i; int j; char *hex = "0123456789ABCDEF"; char *p; p = new char [len*2+1]; if (!p) return p; /* BCD to ASCII legible ! */ for (i = j = 0; i < len; i++) { p[j++] = hex[((str[i] & 0xF0) >> 4)]; p[j++] = hex[(str[i] & 0x0F)]; } p[j] = '\0'; return p; } SQL_ROW sql_values(SQL_CURSOR fd, int *num, int dostrip) { static SQL_ROW argv; static int maxnum; SQLDA *udesc; SQLVAR *col; int i; if (!chk_cursor(fd, "sql_values")) return SQL_ROW(NULL); if (!ssql[fd].is_select) { sprintf(errmsg, "Cannot get values for a non-select statement " "(fd %d) passed to sql_values", fd); debug(fprintf(stderr, "%s\n", errmsg)); return SQL_ROW(NULL); } if (!ssql[fd].opened) { sprintf(errmsg, "Cannot get values for unopened statement " "(fd %d) passed to sql_values", fd); debug(fprintf(stderr, "%s\n", errmsg)); return SQL_ROW(NULL); } udesc = ssql[fd].out; if (!udesc) return SQL_ROW(NULL); if (udesc->sqld > maxnum) { argv.argc(udesc->sqld); maxnum = udesc->sqld; } for (i = 0, col = (SQLVAR *)udesc->sqlvar; i < udesc->sqld; i++, col++) { // if something is already there, free it argv.clear(i); // build our SQL_ROW entries from what we have. if (col->is_blob()) { IFX_LOC_T *loc = (IFX_LOC_T *)col->sqldata; if (loc->loc_size >= 0) { argv[i] = new std::string(loc->loc_buffer,loc->loc_size); } else { argv[i] = new std::string(loc->loc_buffer); } if (dostrip == 1) strip(*(argv[i])); } else { argv[i] = new std::string((col->sqldata)?col->sqldata:""); if (dostrip == 1) strip(*(argv[i])); } } if (num) *num = udesc->sqld; return argv; } char *sql_command(SQL_CURSOR fd) { if (!chk_cursor(fd, "sql_command")) return NULL; return ssql[fd].cmd; } bool sql_close(SQL_CURSOR fd) { struct sqlda *udesc; struct sqlvar_struct *col; if (!ssql[fd].cmd) return true; if (ssql[fd].is_select) { /* XXX - Error handling? */ $char *c_name = ssql[fd].c_name; if (ssql[fd].opened) $close $c_name; $free $c_name; } { /* XXX - Error handling? */ $char *p_name = ssql[fd].p_name; $free $p_name; } /* XXX - Valid to assert ssql[fd].cmd != 0 ? */ if (ssql[fd].cmd && (ssql[fd].cmd != null_cmd)) delete [] ssql[fd].cmd; ssql[fd].cmd = NULL; udesc = ssql[fd].in; if (udesc) { delete (SQLDA *)udesc; udesc = NULL; } ssql[fd].in = NULL; udesc = ssql[fd].out; if (udesc) { #ifndef FIXBUG // since the sqlvars for out and exec are allocated by describe // we need to make sure they don't get freed by us. Lets hope informix // is doing some garbage collecting. udesc->sqlvar=NULL; #endif delete (SQLDA *)udesc; udesc = NULL; } udesc = ssql[fd].out; ssql[fd].out = NULL; /* If out and exec are the same then no need to the following */ if (udesc != ssql[fd].exec && ssql[fd].exec) { udesc = ssql[fd].exec; #ifndef FIXBUG // since the sqlvars for out and exec are allocated by describe // we need to make sure they don't get freed by us. Lets hope informix // is doing some garbage collecting. udesc->sqlvar=NULL; #endif delete (SQLDA *)udesc; udesc = NULL; } ssql[fd].exec = NULL; memset(&ssql[fd], 0, sizeof(SSQL)); return (sql_error_code()>=0); } bool sql_print(SQL_CURSOR fd) { struct sqlda *udesc; struct sqlvar_struct *col; if (fd < 0 || fd >= sql::MAXCURSORS) { sprintf(errmsg, "Invalid fd %d passed to sql_print", fd); debug(fprintf(stderr, "%s\n", errmsg)); return false; } printf("Command string for fd %d: %s", fd, (ssql[fd].cmd?ssql[fd].cmd:"null")); if (!ssql[fd].opened) printf(" not "); printf(" opened, "); if (!ssql[fd].opened) printf(" not "); printf(" selected\n"); if (ssql[fd].in) { int i; udesc = ssql[fd].in; printf("Input:"); for (i = 0, col = udesc->sqlvar; i < udesc->sqld; i++, col++) { if (!(col->sqlname)) col->sqlname="null"; printf("(%s,%ld,%s)\n",col->sqlname, col->sqllen, col->sqldata); } } if (ssql[fd].out) { int i; udesc = ssql[fd].out; printf("Output:\n"); for (i = 0, col = udesc->sqlvar; i < udesc->sqld; i++, col++) { if (!(col->sqlname)) col->sqlname="null"; printf("(%s,%ld,%s)\n",col->sqlname, col->sqllen, col->sqldata); } } return true; } bool sql_database(const char *dbname, const char *password, int exclusive) { $char *p; int len; int fd=alloc_stmt(); if (!dbname || *dbname == '\0') { p = getenv("DATABASE"); if (!p) p = "NODATABASE"; } else p = const_cast(dbname); if (exclusive) { $database $p exclusive; if (chk_status(fd,"DATABASE EXCLUSIVE", p)) return false; $set lock mode to wait; } else { $database $p; if (chk_status(fd,"DATABASE", p)) return false; $set lock mode to wait; } if (database_name) { delete database_name; database_name = NULL; } len = strlen(p) + 1; database_name = new char [len]; errmalloc(database_name, "DATABASE", len); strcpy(database_name, p); sql_close(fd); if (SQLCODE<0) { return false; } return true; } bool sql_connect(const char *dbname, const char *uid, const char *pw, const char *cname, int with_contrans) { $char *p; $char *username; $char *password; $char *conn_name; int fd=alloc_stmt(); int len; if (!dbname || *dbname == '\0') { p = getenv("DATABASE"); if (!p) p = "NODATABASE"; } else p = const_cast(dbname); conn_name = const_cast(cname); username = const_cast(uid); password = const_cast(pw); if (cname && *cname != '\0') { if (with_contrans) { $connect to $p as $conn_name user $username using $password with concurrent transaction; } else { $connect to $p as $conn_name user $username using $password; } } else { if (with_contrans) { $connect to $p user $username using $password with concurrent transaction; } else { $connect to $p user $username using $password; } } if (chk_status(fd,"CONNECT", p)) return false; len = strlen(p) + 1; if (connection_name) { delete connection_name; connection_name = NULL; } connection_name = new char [len]; errmalloc(connection_name, "CONNECT", len); strcpy(connection_name, p); sql_close(fd); return (SQLCODE>=0); } bool sql_disconnect(const char *arg) { $char *cname; cname = const_cast(arg); if (!arg) { sprintf(errmsg, "No argument passed to sql_disconnect"); debug(fprintf(stderr, "%s\n", errmsg)); return false; } if (strcmp(arg, "current") == 0) { $disconnect current; } else if (strcmp(arg, "default") == 0) { $disconnect default; } else if (strcmp(arg, "all") == 0) { $disconnect all; } else { $disconnect $cname; } int fd=alloc_stmt(); if (chk_status(fd,"DISCONNECT", arg)) return false; sql_close(fd); return true; } bool sql_sigcmd(const char *arg) { $char *cname; cname = const_cast(arg); if (!arg) { sprintf(errmsg, "Argument must be one of sqlbreak, sqldetach, sqlexit, sqldone"); debug(fprintf(stderr, "%s\n", errmsg)); return false; } if (strcmp(arg, "sqlbreak") == 0) { return (!sqlbreak()); } else if (strcmp(arg, "sqldetach") == 0) { return !sqldetach(); } else if (strcmp(arg, "sqlexit") == 0) { return !sqlexit(); } else if (strcmp(arg, "sqldone") == 0) { return !sqlexit(); } else { sprintf(errmsg, "Argument must be one of sqlbreak, sqldetach, sqlexit, sqldone"); debug(fprintf(stderr, "%s\n", errmsg)); return false; } } bool sql_setconnection(const char *arg, int dormant) { $char *cname; cname = const_cast(arg); if (!arg) { sprintf(errmsg, "No argument passed to sql_setconnection"); debug(fprintf(stderr, "%s\n", errmsg)); return false; } if (strcmp(arg, "current") == 0) { if (dormant) $set connection current dormant; else /* NOTE: COREDUMPs occur if dormant is removed and no connection is open !!!!*/ /* HENCE DORMANT IS ALWAYS USED */ $set connection current dormant; } else if (strcmp(arg, "default") == 0) { if (dormant) $set connection default dormant; else $set connection default; } else { if (dormant) $set connection $cname dormant; else $set connection $cname; } int fd=alloc_stmt(); if (dormant) { if (chk_status(fd,"SET CONNECTION DORMANT", arg)) return false; } else { if (chk_status(fd,"SET CONNECTION", arg)) return false; } sql_close(fd); return true; } bool sql_finish(void) { if (database_name) { delete [] database_name; database_name = NULL; } $close database; int fd=0; if (chk_status(fd,"CLOSE", "DATABASE")) return false; return true; } bool sql_begin(void) { $begin work; int fd=alloc_stmt(); if (chk_status(fd,"BEGIN", "WORK")) return false; sql_close(fd); return true; } int sql_commit(void) { $commit work; int fd=alloc_stmt(); if (chk_status(fd,"COMMIT", "WORK")) return false; sql_close(fd); return true; } int sql_rollback(void) { $rollback work; int fd=alloc_stmt(); if (chk_status(fd,"ROLLBACK", "WORK")) return false; sql_close(fd); return true; } char *sql_getdatabase(void) { return database_name; } /* sql readblob table column "rowid = NUM" intofilename [append] if success (0) returns NULL or SIZE of blob written else returns ERROR (-1) sql writeblob table column "rowid = NUM" [fromfilename | null] [size|-1] if success (0) returns SIZE of blob written else returns ERROR (-1) */ int sql_readblob(const char *table, const char *column, const char *rowidclause, const char *intofile, int appendmode) { $loc_t sloc; $char stmt[sql::MAXBLOB+1]; int fd=alloc_stmt(); if (atoi(rowidclause) > 0) sprintf(stmt, "select %s from %s where rowid = %s", column, table, rowidclause); else sprintf(stmt, "select %s from %s where %s", column, table, rowidclause); sloc.loc_loctype = LOCFNAME; sloc.loc_fname = const_cast(intofile); if (appendmode) sloc.loc_oflags = LOC_APPEND; else sloc.loc_oflags = LOC_WONLY; $prepare tcl_readblob from $stmt; if (chk_status(fd,"PREPARE(READBLOB)", stmt)) return false; $declare tcl_readblob_cur cursor for tcl_readblob; if (chk_status(fd,"DECLARE(READBLOB)", stmt)) return false; $open tcl_readblob_cur; if (chk_status(fd,"OPEN(READBLOB)", stmt)) return false; $fetch tcl_readblob_cur into $sloc; if (chk_status(fd,"FETCH(READBLOB)", stmt)) return false; if (sql_error_code() != 0) { sprintf(errmsg, "No record found.\n"); debug(fprintf(stderr, "%s\n", errmsg)); sql_close(fd); return -1; } /* After getting it sloc.loc_size # of bytes, sloc.loc_indicator = -1 for null, sloc.loc_status = 0 for success, -ve for error */ if (sql_error_code() == 0 && sloc.loc_status == 0) { if (sloc.loc_indicator == -1) { $close tcl_readblob_cur; sql_close(fd); return -2; } $close tcl_readblob_cur; sql_close(fd); return sloc.loc_size; } $close tcl_readblob_cur; sql_close(fd); return -1; } int sql_writeblob(const char *table, const char *column, const char *rowidclause, const char *fromfile, int fromsize) { $loc_t uloc; $char stmt[sql::MAXBLOB+1]; $char *colname; int fd=alloc_stmt(); colname = const_cast(column); if (atoi(rowidclause) > 0) sprintf(stmt, "update %s set %s = ? where rowid = %s", table, column, rowidclause); else sprintf(stmt, "update %s set %s = ? where %s", table, column, rowidclause); /* sprintf(stmt, "select 1 from %s where %s FOR UPDATE OF %s", table, rowidclause, column); */ uloc.loc_loctype = LOCFNAME; uloc.loc_fname = const_cast(fromfile); uloc.loc_oflags = LOC_RONLY; uloc.loc_size = fromsize; uloc.loc_indicator = 0; if (fromfile) if (strcmp(fromfile,"null") == 0 || strcmp(fromfile, "NULL") == 0) uloc.loc_indicator = -1; $prepare tcl_writeblob from $stmt; if (chk_status(fd,"PREPARE(WRITEBLOB)", stmt)) return false; $execute tcl_writeblob using $uloc; if (chk_status(fd,"EXECUTE(WRITEBLOB)", stmt)) return false; /* $declare tcl_writeblob_cur cursor for tcl_writeblob; chk_status(fd,"DECLARE(WRITEBLOB)", stmt); $open tcl_writeblob_cur; chk_status(fd,"OPEN(WRITEBLOB)", stmt); $fetch tcl_writeblob_cur into :found; chk_status(fd,"FETCH(WRITEBLOB)", stmt); sprintf(stmt, "update %s set %s = ? where current of tcl_writeblob_cur", table, column); $prepare tcl_writeblob_new from $stmt; chk_status(fd,"PREPARE UPDATE(WRITEBLOB)", stmt); $execute tcl_writeblob_new using $uloc; chk_status(fd,"EXECUTE UPDATE(WRITEBLOB)", stmt); */ /* After updating it uloc.loc_size # of bytes transferred uloc.loc_status = 0 for success, -ve for error */ sql_close(fd); if (sql_error_code() == 0 && uloc.loc_status == 0) return uloc.loc_size; return -1; } #ifdef USE_NAMESPACE } #endif boinc-app-seti_8.00~svn3701.orig/db/track_mem.h0000644000175000017500000000141410671336410021213 0ustar locutuslocutus #ifndef _TRACK_MEM_H_ #define _TRACK_MEM_H_ #include #include template class track_mem { #ifdef DEBUG_ALLOCATIONS private: static const char *name; static int ref_count; public: track_mem(const char *n="unknown") { name=n; fprintf(stderr,"%s #%d: allocated 0x%lx bytes at 0x%p\n",name,++ref_count,sizeof(T),this); fflush(stderr); }; ~track_mem() { fprintf(stderr,"%s #%d: freed 0x%lx bytes at 0x%p\n",name,this->ref_count--,sizeof(T),this); fflush(stderr); }; #else public: track_mem(const char *n=0) {}; ~track_mem() {}; #endif }; #ifdef DEBUG_ALLOCATIONS template const char *track_mem::name; template int track_mem::ref_count; #endif #endif boinc-app-seti_8.00~svn3701.orig/db/migrate_test.cpp0000644000175000017500000001127010671336410022274 0ustar locutuslocutus#include #include #include #include #include #include "db_table.h" #include "schema_master.h" #include "sqlhdr.h" const char * from_db = "sah2@sci_master_shm"; const char * to_db = "t_sah@temp_master_tcp"; template int read_and_compare_dbs (T& table, int modulo, int remainder, int maxnum, int minid, int maxid); int main(int argc, char ** argv) { receiver_config receiver_cfg; recorder_config recorder_cfg; splitter_config splitter_cfg; analysis_config analysis_cfg; tape tp; settings set; workunit_grp wug; workunit_header wuh; result res; triplet trip; gaussian gauss; pulse pul; spike sp; char type[32]; int modulo, remainder, maxnum, minid, maxid; if (argc != 7) { fprintf(stderr, "Usage: migrate_test table_name modulo remainder maximum_number_of_elements minimum_id maximum_id\n"); exit (1); } else { strcpy(type, argv[1]); modulo = atoi(argv[2]); remainder = atoi(argv[3]); maxnum = atoi(argv[4]); minid = atoi(argv[5]); maxid = atoi(argv[6]); } // how to call read_and_compare_dbs? if (strcmp(type,"receiver_config") == 0) { read_and_compare_dbs (receiver_cfg, modulo, remainder, maxnum, minid, maxid); } else if (strcmp(type,"recorder_config") == 0) { read_and_compare_dbs (recorder_cfg, modulo, remainder, maxnum, minid, maxid); } else if (strcmp(type,"splitter_config") == 0) { read_and_compare_dbs (splitter_cfg, modulo, remainder, maxnum, minid, maxid); } else if (strcmp(type,"analysis_config") == 0) { read_and_compare_dbs (analysis_cfg, modulo, remainder, maxnum, minid, maxid); } else if (strcmp(type,"tape") == 0) { read_and_compare_dbs (tp, modulo, remainder, maxnum, minid, maxid); } else if (strcmp(type,"settings") == 0) { read_and_compare_dbs (set, modulo, remainder, maxnum, minid, maxid); } else if (strcmp(type,"workunit_grp") == 0) { read_and_compare_dbs (wug, modulo, remainder, maxnum, minid, maxid); } else if (strcmp(type,"workunit_header") == 0) { read_and_compare_dbs (wuh, modulo, remainder, maxnum, minid, maxid); } else if (strcmp(type,"result") == 0) { read_and_compare_dbs (res, modulo, remainder, maxnum, minid, maxid); } else if (strcmp(type,"triplet") == 0) { read_and_compare_dbs (trip, modulo, remainder, maxnum, minid, maxid); } else if (strcmp(type,"gaussian") == 0) { read_and_compare_dbs (gauss, modulo, remainder, maxnum, minid, maxid); } else if (strcmp(type,"pulse") == 0) { read_and_compare_dbs (pul, modulo, remainder, maxnum, minid, maxid); } else if (strcmp(type,"spike") == 0) { read_and_compare_dbs (sp, modulo, remainder, maxnum, minid, maxid); } else { fprintf(stderr, "Don't recognize table: %s\n", type); exit(1); } exit (0); } template int read_and_compare_dbs (T& table, int modulo, int remainder, int maxnum, int minid, int maxid) { int retval, get_next_retval; int i, match, dontmatch; std::vector id_list; char c_string[256]; std::string where_clause; if (remainder != 0) { sprintf(c_string, "where id >= %d and id <= %d and MOD(id, %d) = %d", minid, maxid, modulo, remainder); } else { sprintf(c_string, "where id >= %d and id <= %d", minid, maxid); } where_clause = c_string; std::cerr << "where clause: " << where_clause << "\n"; retval = db_change(from_db); fprintf(stderr, "db_change(%s) returns %d\n", from_db, retval); retval = table.open_query(where_clause); fprintf(stderr, "open_query returns %d, %d\n", retval, sql_last_error_code()); i = 0; while (get_next_retval = table.get_next() && (i++) < maxnum) id_list.push_back (table.id); table.close_query(); typename std::vector::iterator id_iter = id_list.begin(); T from_thisrow; T to_thisrow; match = dontmatch = 0; while (id_iter != id_list.end()) { sprintf(c_string, "where id = %d", (*id_iter)); where_clause = c_string; db_change(from_db); table.open_query(where_clause); table.get_next(); from_thisrow = table; db_change(to_db); table.open_query(where_clause); table.get_next(); to_thisrow = table; std::cerr << "FROM DATABASE:\n" << from_thisrow.print(0,1,0) << "\n\nTO DATABASE:\n" << to_thisrow.print(0,1,0) << "\n"; if (from_thisrow.print(0,1,0) == to_thisrow.print(0,1,0)) { match++; } else { dontmatch++; fprintf(stderr,"DON'T MATCH!!!\n"); } fprintf(stderr,"--------------------------\n"); id_iter++; } fprintf(stderr,"num match: %d don't match: %d\n",match,dontmatch); return 0; } boinc-app-seti_8.00~svn3701.orig/db/xml_util.cpp0000644000175000017500000005073311217035323021445 0ustar locutuslocutus// $Id: xml_util.cpp,v 1.3.2.8 2007/02/28 01:45:17 vonkorff Exp $ // The contents of this file are subject to the BOINC Public License // Version 1.0 (the "License"); you may not use this file except in // compliance with the License. You may obtain a copy of the License at // http://boinc.berkeley.edu/license_1.0.txt // // Software distributed under the License is distributed on an "AS IS" // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the // License for the specific language governing rights and limitations // under the License. // // The Original Code is the Berkeley Open Infrastructure for Network Computing. // // The Initial Developer of the Original Code is the SETI@home project. // Portions created by the SETI@home project are Copyright (C) 2002 // University of California at Berkeley. All Rights Reserved. // // Contributor(s): // // Revision History // $Log: xml_util.cpp,v $ // Revision 1.3.2.8 2007/02/28 01:45:17 vonkorff // // stopped using BUFSIZ to size temporary buffers // // Revision 1.3.2.7 2007/02/22 02:27:23 vonkorff // // Added #include "str_util.h" // // Revision 1.3.2.6 2006/12/14 22:26:30 korpela // *** empty log message *** // // Revision 1.3.2.5 2006/05/04 21:45:46 charlief // *** empty log message *** // // Revision 1.3.2.4 2006/05/04 12:36:10 charlief // *** empty log message *** // // Revision 1.3.2.3 2006/01/04 00:47:30 korpela // Upped version to 5.0 // Made it clear in graphics that this is SETI@home Enhanced // // Revision 1.3.2.2 2005/11/17 18:44:39 jeffc // Fixed a problem with the << operator for db_table.h. // Also altered << operator to stop looking for the start tag after it is found // and to not look for the stop tag until after the start is found. // Modified xml_match_tag() to not search zero length strings. // // Revision 1.3.2.1 2005/10/17 22:14:48 korpela // Fixed bugs with XML formatting and CSV vector input. The XML formatting bug // fixes were submitted by Tetsuji "Maverick" Rai. The CSV input problem was due // to my misunderstanding of the istream::operator void *(). I had thought the // operator returned NULL if the past operation had failed. Instead it returns // NULL if the NEXT operation will fail. // // Revision 1.3 2004/07/02 21:21:16 korpela // Removed include of stdafx.h where it was not necessary. // // Revision 1.2 2004/06/30 20:52:28 korpela // *** empty log message *** // // Revision 1.1 2004/06/17 22:41:28 jeffc // *** empty log message *** // // Revision 1.3 2004/06/12 18:38:30 rwalton // *** empty log message *** // // Revision 1.2 2004/06/12 05:56:14 davea // *** empty log message *** // // Revision 1.1 2004/06/11 17:43:22 davea // *** empty log message *** // // Revision 1.29 2004/04/05 20:09:41 korpela // Rewrote extract_xml_record() to solve some problems... // // Revision 1.28 2004/03/06 09:45:25 rwalton // *** empty log message *** // // Revision 1.27 2004/01/22 17:57:41 davea // *** empty log message *** // // Revision 1.26 2004/01/20 02:51:50 korpela // VC 7 mods // // Revision 1.25 2003/12/01 23:42:05 korpela // Under some compilers template parameters of type char [] weren't getting // cast to char *. Template functions now use &(array[0]) to ensure correct // type is used. // // #include "sah_config.h" #include #include #include #include #include #include #include "std_fixes.h" #include "util.h" #include "str_util.h" #include "str_replace.h" #include "xml_util.h" using std::string; using std::min; int xml_indent_level=0; std::string xml_indent(int i) { if (i) xml_indent_level+=i; xml_indent_level = (xml_indent_level>0) ? xml_indent_level : 0; return string(min(xml_indent_level,XML_MAX_INDENT),' '); } // Most of these entries are for reverse translation of poorly written HTML. // Forward translation doesn't translate most printable characters. const xml_entity xml_trans[]= { { 0x07, "&bel;" }, { 0x0a, "&lf;" }, { 0x0d, "&cr;" }, { ' ', "&sp;" }, { '!', "!" }, { '\"', """ }, { '\"', "&dquot;" }, { '#', "#" }, { '$', "$" }, { '%', "%" }, { '&', "&" }, { '\'', "'" }, { '(', "(" }, { ')', ")" }, { '*', "*" }, { '+', "+" }, { ',', "," }, { '-', "‐" }, { '-', "−" }, { '.', "." }, { '/', "/" }, { ':', ":" }, { ';', ";" }, { '<', "<" }, { '=', "=" }, { '>', ">" }, { '?', "?" }, { '@', "@" }, { '[', "[" }, { '\\', "\" }, { ']', "]" }, { '^', "ˆ" }, { '_', "_" }, { '_', "―" }, { '`', "`" }, { '{', "{" }, { '|', "|" }, { '}', "}" }, { '~', "˜" }, { 0x82, "‚" }, { 0x84, "„" }, { 0x85, "&ldots;" }, { 0x8a, "Š" }, { 0x8b, "‹" }, { 0x8c, "Œ" }, { 0x91, "‘" }, { 0x91, "’" }, { 0x92, "’" }, { 0x93, "“" }, { 0x93, "”" }, { 0x94, "”" }, { 0x95, "•" }, { 0x96, "–" }, { 0x96, "&endash;" }, { 0x97, "—" }, { 0x97, "&emdash;" }, { 0xa0, " " }, { 0xa1, "¡" }, { 0xa2, "¢" }, { 0xa3, "£" }, { 0xa4, "¤" }, { 0xa5, "¥" }, { 0xa6, "¦" }, { 0xa7, "§" }, { 0xa8, "¨" }, { 0xa9, "©" }, { 0xaa, "ª" }, { 0xab, "«" }, { 0xac, "¬" }, { 0xad, "­" }, { 0xae, "®" }, { 0xaf, "¯" }, { 0xb0, "°" }, { 0xb1, "±" }, { 0xb2, "²" }, { 0xb3, "³" }, { 0xb4, "´" }, { 0xb5, "µ" }, { 0xb6, "¶" }, { 0xb7, "·" }, { 0xb8, "¸" }, { 0xb9, "¹" }, { 0xba, "º" }, { 0xbb, "»" }, { 0xbc, "¼" }, { 0xbd, "½" }, { 0xbe, "¾" }, { 0xbf, "¿" }, { 0xc0, "À" }, { 0xc1, "Á" }, { 0xc2, "Â" }, { 0xc3, "Ã" }, { 0xc4, "Ä" }, { 0xc5, "Å" }, { 0xc6, "Æ" }, { 0xc7, "Ç" }, { 0xc8, "È" }, { 0xc9, "É" }, { 0xca, "Ê" }, { 0xcb, "Ë" }, { 0xcc, "Ì" }, { 0xcd, "Í" }, { 0xce, "Î" }, { 0xcf, "Ï" }, { 0xd0, "Ð" }, { 0xd1, "Ñ" }, { 0xd2, "Ò" }, { 0xd3, "Ó" }, { 0xd4, "Ô" }, { 0xd5, "Õ" }, { 0xd6, "Ö" }, { 0xd7, "×" }, { 0xd8, "Ø" }, { 0xd9, "Ù" }, { 0xda, "Ú" }, { 0xdb, "Û" }, { 0xdc, "Ü" }, { 0xdd, "Ý" }, { 0xde, "Þ" }, { 0xdf, "ß" }, { 0xe0, "à" }, { 0xe1, "á" }, { 0xe2, "â" }, { 0xe3, "ã" }, { 0xe4, "ä" }, { 0xe5, "å" }, { 0xe6, "æ" }, { 0xe7, "ç" }, { 0xe8, "è" }, { 0xe9, "é" }, { 0xea, "ê" }, { 0xeb, "ë" }, { 0xec, "ì" }, { 0xed, "í" }, { 0xee, "î" }, { 0xef, "ï" }, { 0xf0, "ð" }, { 0xf1, "ñ" }, { 0xf2, "ò" }, { 0xf3, "ó" }, { 0xf4, "ô" }, { 0xf5, "õ" }, { 0xf6, "ö" }, { 0xf7, "÷" }, { 0xf8, "ø" }, { 0xf9, "ù" }, { 0xfa, "ú" }, { 0xfb, "û" }, { 0xfc, "ü" }, { 0xfd, "ý" }, { 0xfe, "þ" }, { 0xff, "ÿ" }, { 0x00, 0 } }; #if 0 xml_ofstream::xml_ofstream() : my_tag(), os() {} xml_ofstream::xml_ofstream(const char *filename, const char *tag, std::ios_base::openmode m) : , my_tag(tag), os(filename,m) { if (is_open()) { write_head(); } } xml_ostream::xml_ostream(std::ostream &o, const char *tag) : my_tag(tag), os(o) { write_head(); } xml_ostream::~xml_ostream() { write_foot(); } xml_ofstream::~xml_ofstream() { close(); } void xml_ofstream::open(const char *filename, const char *tag, std::ios_base::openmode m) { my_tag=std::string(tag); os.open(filename,m); if (is_open()) { write_head(); } } void xml_ofstream::close() { write_foot(); os.close(); } void xml_ostream::write_head() { xml_indent_level=0; os << xml_header << std::endl; os << '<' << my_tag << '>' << std::endl; xml_indent(2); } void xml_ofstream::write_head() { xml_indent_level=0; os << xml_header << std::endl; os << '<' << my_tag << '>' << std::endl; xml_indent(2); } void xml_ostream::write_foot() { xml_indent(-2); os << "' << std::endl; } void xml_ofstream::write_foot() { xml_indent(-2); os << "' << std::endl; } xml_ifstream::xml_ifstream() : , my_tag(""), xml_start(0), ifs() xml_end(0) {} xml_ifstream::xml_ifstream(const char *filename, const char *tag, std::ios_base::openmode m) : std::ifstream(filename,m), my_tag(tag), xml_start(0), xml_end(0) { if (is_open()) { seek_head(); } } xml_istream::xml_istream(std::istream &i, const char *tag) : my_tag(tag), is(i) { } xml_ifstream::~xml_ifstream() { close(); } void xml_ifstream::open(const char *filename, const char *tag, std::ios_base::openmode m) { my_tag=std::string(tag); std::ifstream::open(filename,m); if (is_open()) { seek_head(); } } void xml_istream::seek_head() { std::string tmp; char c; unsigned int i=0; bool start_found=false; if (my_tag.size()) { while (is) { is.get(c); if (c=='<') { do { is.get(c); i++; } while (c == my_tag[i-1]); if ((i==my_tag.size()) && !isalnum(c)) { start_found=true; break; } } } } else { while (is) { is.get(c); if (c=='<') { do { is.get(c); if (isalnum(c)) my_tag+=c; } while (isalnum(c)); } if (my_tag.size()) { start_found=true; break; } } } if (start_found) { while ((c != '>') && is) is.get(c); } } void xml_ifstream::seek_head() { if (!xml_start) { std::string tmp; std::string::size_type tag_start, tag_end; bool start_found=false; std::ifstream::seekg(0,std::ios::beg); if (my_tag.size()) { do { *this >> tmp; if ((tag_start=tmp.find(std::string("<")+my_tag)) != std::string::npos) { tag_start=tmp.find('>'); std::ifstream::seekg(tag_start-tmp.size()+my_tag.size()+2,std::ios::cur); start_found=true; } else { if ((tag_start=tmp.find("<")) != std::string::npos) { if (isalpha(tmp[tag_start+1])) { while (isalnum(tmp[++tag_start])) my_tag+=tmp[tag_start]; start_found=true; tag_start=tmp.find(">",tag_start-1); std::ifstream::seekg(tag_start-tmp.size(),std::ios::cur); } } } } while (!start_found && !std::ifstream::eof()); xml_start=std::ifstream::tellg(); } if (my_tag.size()) { int nstarts=1; std::string start_tag(std::string("<")+my_tag); std::string end_tag(std::string("> tmp; if (tmp.find(start_tag)!=std::string::npos) { nstarts++; } if ((tag_end=tmp.find(end_tag))!=std::string::npos) { nstarts--; } } while (nstarts && !std::ifstream::eof()); std::ifstream::seekg(tag_end-tmp.size(),std::ios::cur); xml_end=std::ifstream::tellg(); } } if (xml_start) std::ifstream::seekg(xml_start,std::ios::beg); } xml_ifstream &xml_ifstream::seekg(pos_type p) { if (xml_start) std::ifstream::seekg(xml_start+p); return *this; } xml_ifstream &xml_ifstream::seekg(off_type o, std::ios::seekdir d) { switch (d) { case std::ios::beg: seekg(o); break; case std::ios::end: std::ifstream::seekg(xml_end+o); break; default: std::ifstream::seekg(o,d); break; } return *this; } std::ios::pos_type xml_ifstream::tellg() { return std::ifstream::tellg()-xml_start; } bool xml_ifstream::eof() { if (std::ifstream::tellg() >= xml_end) { return true; } else { return std::ifstream::tellg(); } } #endif // 0 #ifdef HAVE_MAP #include std::multimap encode_map; std::map decode_map; void populate_encode_map() { int i=0; do { encode_map.insert(std::make_pair(xml_trans[i].c,xml_trans[i].s)); } while (xml_trans[++i].s); } void populate_decode_map() { int i=0; do { decode_map[xml_trans[i].s]=xml_trans[i].c; } while (xml_trans[++i].s); } #endif const char * encode_arr="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; const char * encode_arr85= "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxy!#$()*+,-./:;=?@^`{|}~z_"; bool isencchar(char c) { bool rv=((c>='A') && (c<='Z')); rv|=((c>='a') && (c<='z')); rv|=((c>='0') && (c<='9')); rv|=((c=='+') || (c=='/') || (c=='=')); return rv; } bool isencchar85(char c) { bool rv=((c>='A') && (c<='Z')); rv|=((c>='a') && (c<='z')); rv|=((c>='0') && (c<='9')); switch (c) { case '!': case '#': case '$': case '(': case ')': case '*': case '+': case ',': case '-': case '.': case '/': case ':': case ';': case '=': case '?': case '@': case '^': case '`': case '{': case '|': case '}': case '~': case '_': rv=true; break; default: break; } return rv; } std::string encode_char(unsigned char c) { #ifdef HAVE_MAP if (!(encode_map.size())) populate_encode_map(); std::multimap::iterator p=encode_map.find(c); if (p!=encode_map.end()) { return (p->second); } else { #else int i=0; while (xml_trans[i].s) { if (xml_trans[i].c == c) return std::string(xml_trans[i].s); i++; } { #endif char buf[16]; sprintf(buf,"&#%.3d;",static_cast(c)); #ifdef HAVE_MAP encode_map.insert(std::make_pair(c,&(buf[0]))); #endif return std::string(buf); } } unsigned char decode_char(const char *s) { char code[32]; int i=0; code[31]=0; while (*s && (*s != ';') && i<31) { code[i]=*s; s++; i++; } code[i]=';'; code[i+1]=0; #ifdef HAVE_MAP if (!(decode_map.size())) populate_decode_map(); std::map::iterator p=decode_map.find(code); if (p!=decode_map.end()) { return (p->second); } else { #else while (xml_trans[i].s) { if (!strcmp(xml_trans[i].s,(const char *)(&code[0]))) return xml_trans[i].c; i++; } { #endif if (code[1]=='#') { sscanf((const char *)(code+2),"%d",&i); #ifdef HAVE_MAP decode_map.insert(std::make_pair(std::string(code),static_cast(i&0xff))); #endif } else { fprintf(stderr,"Unknown XML entity \"%s\"\n",code); i='&'; } return static_cast(i&0xff); } } std::string x_csv_encode_char(const unsigned char *bin, size_t nelements) { std::ostringstream rv(""); long lastlen,i,ival; rv << std::endl << xml_indent(2); lastlen=(long)rv.str().size(); for (i=0;i<(long)(nelements-1);i++) { ival=bin[i]; rv << ival << ','; if ((static_cast(rv.str().size()) -(lastlen-min(xml_indent_level,XML_MAX_INDENT)))>73) { // TMR rv << std::endl << xml_indent(); lastlen=(long)rv.str().size(); } } ival=bin[i]; rv << ival << std::endl << xml_indent(-2); return rv.str(); } // test if a character is an xml tag delimiter bool isxmldelim(char c) { return ((c==' ') || (c=='\n') || (c=='\r') || (c==',') || (c=='<') || (c=='>') || (c==0)); } // return true if the tag appears in the line // bool xml_match_tag(const char* buf, const char* tag) { char tmp_tag[8192]={'<',0}; if (strlen(buf)==0) return false; if (tag[0] == '<') { strlcpy(tmp_tag,tag,8192); } else { strlcat(tmp_tag,tag,8192); } char *p=tmp_tag+strlen(tmp_tag); do { *(p--)=0; } while (isxmldelim(*p)); while ((buf=strstr(buf,tmp_tag))) { if (isxmldelim(buf[strlen(tmp_tag)])) return true; buf++; } return false; } bool xml_match_tag(const std::string &s, const char* tag) { return xml_match_tag(s.c_str(),tag); } size_t xml_find_tag(const char* buf, const char* tag) { const char *buf0=buf; char tmp_tag[8192]={'<',0}; if (tag[0] == '<') { strlcpy(tmp_tag,tag,8192); } else { strlcat(tmp_tag,tag,8192); } char *p=tmp_tag+strlen(tmp_tag); do { *(p--)=0; } while (isxmldelim(*p)); while ((buf=strstr(buf,tmp_tag))) { if (isxmldelim(buf[strlen(tmp_tag)])) return buf-buf0; buf++; } return strlen(buf0); } std::string::size_type xml_find_tag(const std::string &s, const char* tag) { std::string::size_type p=xml_find_tag(s.c_str(),tag); return (p!=strlen(s.c_str()))?p:(std::string::npos); } bool extract_xml_record(const std::string &field, const char *tag, std::string &record) { char end_tag[256]; sprintf(end_tag,"/%s",tag); std::string::size_type j,k; // find the start_tag j=xml_find_tag(field,tag); if (j==std::string::npos) return false; // find the end tag k=xml_find_tag(std::string(field,j,field.length()-j),end_tag); if (k==std::string::npos) return false; record=std::string(field,j,k+strlen(end_tag)+1); return true; } // // $Log: xml_util.cpp,v $ // Revision 1.3.2.8 2007/02/28 01:45:17 vonkorff // // stopped using BUFSIZ to size temporary buffers // // Revision 1.3.2.7 2007/02/22 02:27:23 vonkorff // // Added #include "str_util.h" // // Revision 1.3.2.6 2006/12/14 22:26:30 korpela // *** empty log message *** // // Revision 1.3.2.5 2006/05/04 21:45:46 charlief // *** empty log message *** // // Revision 1.3.2.4 2006/05/04 12:36:10 charlief // *** empty log message *** // // Revision 1.3.2.3 2006/01/04 00:47:30 korpela // Upped version to 5.0 // Made it clear in graphics that this is SETI@home Enhanced // // Revision 1.3.2.2 2005/11/17 18:44:39 jeffc // Fixed a problem with the << operator for db_table.h. // Also altered << operator to stop looking for the start tag after it is found // and to not look for the stop tag until after the start is found. // Modified xml_match_tag() to not search zero length strings. // // Revision 1.3.2.1 2005/10/17 22:14:48 korpela // Fixed bugs with XML formatting and CSV vector input. The XML formatting bug // fixes were submitted by Tetsuji "Maverick" Rai. The CSV input problem was due // to my misunderstanding of the istream::operator void *(). I had thought the // operator returned NULL if the past operation had failed. Instead it returns // NULL if the NEXT operation will fail. // // Revision 1.3 2004/07/02 21:21:16 korpela // Removed include of stdafx.h where it was not necessary. // // Revision 1.2 2004/06/30 20:52:28 korpela // *** empty log message *** // // Revision 1.1 2004/06/17 22:41:28 jeffc // *** empty log message *** // // Revision 1.3 2004/06/12 18:38:30 rwalton // *** empty log message *** // // Revision 1.2 2004/06/12 05:56:14 davea // *** empty log message *** // // Revision 1.1 2004/06/11 17:43:22 davea // *** empty log message *** // // Revision 1.29 2004/04/05 20:09:41 korpela // Rewrote extract_xml_record() to solve some problems... // // Revision 1.28 2004/03/06 09:45:25 rwalton // *** empty log message *** // // Revision 1.27 2004/01/22 17:57:41 davea // *** empty log message *** // // Revision 1.26 2004/01/20 02:51:50 korpela // VC 7 mods // // Revision 1.25 2003/12/01 23:42:05 korpela // Under some compilers template parameters of type char [] weren't getting // cast to char *. Template functions now use &(array[0]) to ensure correct // type is used. // // Revision 1.24 2003/11/11 17:29:01 quarl // *** empty log message *** // // Revision 1.23 2003/10/29 20:08:49 korpela // *** empty log message *** // // Revision 1.22 2003/10/27 23:07:34 korpela // *** empty log message *** // // Revision 1.21 2003/10/27 20:07:11 korpela // *** empty log message *** // // Revision 1.20 2003/10/27 19:41:23 korpela // // Fixed potential buffer overrun in decode_char() // // Revision 1.19 2003/10/27 17:52:49 korpela // *** empty log message *** // // Revision 1.18 2003/10/24 16:58:10 korpela // *** empty log message *** // // Revision 1.17 2003/10/24 00:05:02 davea // *** empty log message *** // // Revision 1.16 2003/10/23 19:58:20 jeffc // jeffc - bug fix in csv encode routine // // Revision 1.15 2003/10/23 19:18:38 jeffc // jeffc - put back in line feeds - no longer using parese_str(). // // Revision 1.14 2003/10/23 15:39:54 korpela // no message // // Revision 1.13 2003/10/23 00:25:15 jeffc // jeffc - no line feeds in CSV encoding // // Revision 1.12 2003/10/22 18:23:23 korpela // *** empty log message *** // // Revision 1.11 2003/10/22 18:01:41 korpela // *** empty log message *** // // Revision 1.10 2003/10/22 15:24:10 korpela // *** empty log message *** // // Revision 1.9 2003/10/21 18:14:36 korpela // *** empty log message *** // // boinc-app-seti_8.00~svn3701.orig/db/db_util.h0000644000175000017500000000031012115730023020656 0ustar locutuslocutustemplate void signal_preprocess(T &signal) { // this is where just in time iq flipping will occur //fprintf(stderr, "I am a %s and my ID is %ld\n", signal->table_name, signal->id); } boinc-app-seti_8.00~svn3701.orig/db/Makefile.in0000644000175000017500000000367410671550155021163 0ustar locutuslocutus# $Id: Makefile.in,v 1.14.2.1 2007/03/13 17:41:27 vonkorff Exp $ # # @SET_MAKE@ EXEEXT = @EXEEXT@ OBJEXT = @OBJEXT@ LIBEXT = @LIBEXT@ DLLEXT = @DLLEXT@ DOTEXEEXT = @DOTEXEEXT@ SUFFIXES = .ec .cpp .c .@OBJEXT@ .@DLLEXT@ .@LIBEXT@ @DOTEXEEXT@ BOINCDIR = @BOINCDIR@ INFORMIXDIR = @INFORMIXDIR@ MYSQL_LIBS = @MYSQL_LIBS@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ INFORMIX_CFLAGS = @INFORMIX_CFLAGS@ DBLIBS=@INFORMIX_LIBS@ @MYSQL_LIBS@ -lsocket -lm -lstdc++ @PTHREAD_LIBS@ CC = @CC@ CXX = @CXX@ CFLAGS = @CFLAGS@ -I.. -I$(BOINCDIR) -I$(BOINCDIR)/lib -I$(BOINCDIR)/api $(INFORMIX_CFLAGS) $(MYSQL_CFLAGS) @PTHREAD_CFLAGS@ CXXFLAGS = $(CFLAGS) .cpp.@OBJEXT@: $(CXX) $(CXXFLAGS) -o $*.@OBJEXT@ -c $< all: dependencies app_config.@OBJEXT@ schema_master_client.@OBJEXT@ sqlrow_client.@OBJEXT@ schema_master.@OBJEXT@ sqlrow.@OBJEXT@ sqlifx.@OBJEXT@ sqlblob.@OBJEXT@ sqlint8.@OBJEXT@ xml_util.@OBJEXT@ schema_master.cpp: schema_master.sql find_references.awk schema_to_class.awk chmod +x schema_to_class ./schema_to_class schema_master.sql schema_master.h: schema_master.sql find_references.awk schema_to_class.awk chmod +x schema_to_class ./schema_to_class schema_master.sql schema_master_client.@OBJEXT@: schema_master.cpp schema_master.h db_table.h Makefile $(CXX) $(CXXFLAGS) -DCLIENT -c -o schema_master_client.@OBJEXT@ schema_master.cpp sqlrow_client.@OBJEXT@: sqlrow.cpp sqlrow.h Makefile $(CXX) $(CXXFLAGS) -DCLIENT -c -o sqlrow_client.@OBJEXT@ sqlrow.cpp schema_master.@OBJEXT@: schema_master.cpp schema_master.h db_table.h sqlifx.cpp: sqlifx.ec $(INFORMIXDIR)/bin/esql -e $< mv $*.c $*.cpp sqlifx.@OBJEXT@: sqlifx.cpp xml_util.@OBJEXT@: xml_util.cpp app_config.@OBJEXT@: app_config.cpp .ec.cpp: $(INFORMIXDIR)/bin/esql -e $< mv $*.c $*.cpp Makefile: Makefile.in ../config.status ../configure ../configure.ac (cd ..; $(MAKE) config.status) dependencies: schema_master.cpp *.cpp *.h $(CXX) $(CXXFLAGS) -M *.cpp > dependencies include dependencies boinc-app-seti_8.00~svn3701.orig/db/xml_util.h0000644000175000017500000007034513040227144021113 0ustar locutuslocutus// $Id: xml_util.h,v 1.8.2.6 2007/05/31 22:03:31 korpela Exp $ // The contents of this file are subject to the BOINC Public License // Version 1.0 (the "License"); you may not use this file except in // compliance with the License. You may obtain a copy of the License at // http://boinc.berkeley.edu/license_1.0.txt // // Software distributed under the License is distributed on an "AS IS" // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the // License for the specific language governing rights and limitations // under the License. // // The Original Code is the Berkeley Open Infrastructure for Network Computing. // // The Initial Developer of the Original Code is the SETI@home project. // Portions created by the SETI@home project are Copyright (C) 2002 // University of California at Berkeley. All Rights Reserved. // // Contributor(s): // // Additional routines to help maintain XML compliance. // // Revision History: // $Log: xml_util.h,v $ // Revision 1.8.2.6 2007/05/31 22:03:31 korpela // *** empty log message *** // // Revision 1.8.2.5 2007/03/09 00:21:15 vonkorff // Fixed missing trailing null in base64 encoding. // // Revision 1.8.2.4 2006/12/14 22:26:30 korpela // *** empty log message *** // // Revision 1.8.2.3 2005/12/01 00:01:01 korpela // Changed to an Intel compile of fftw3.dll. Hopefully this will fix the problem // with crashes on Pentium-MMX and earlier. // // Added a Dev-C++ project and modified source files to allow seti_boinc to compile // under MinGW. // // Revision 1.8.2.2 2005/10/17 22:33:33 korpela // Continuing previous fix // // Revision 1.8.2.1 2005/10/17 22:14:49 korpela // Fixed bugs with XML formatting and CSV vector input. The XML formatting bug // fixes were submitted by Tetsuji "Maverick" Rai. The CSV input problem was due // to my misunderstanding of the istream::operator void *(). I had thought the // operator returned NULL if the past operation had failed. Instead it returns // NULL if the NEXT operation will fail. // // Revision 1.8 2004/12/07 23:42:23 korpela // Added undef of min and max in case they are defined in a previously included // header file. // // Revision 1.7 2004/11/18 19:17:04 korpela // Fixed base64 and base85 decoding. // // // Revision 1.21 2004/04/05 22:07:08 korpela // // Segfault problem fixed? // // Revision 1.17 2003/12/01 23:42:05 korpela // Under some compilers template parameters of type char [] weren't getting // cast to char *. Template functions now use &(array[0]) to ensure correct // type is used. // // #ifndef _XML_UTIL_H_ #define _XML_UTIL_H_ #include "sah_config.h" #include #include #include #include #include #include #include #include "error_numbers.h" // Just in case, undef min and max #ifdef min #undef min #endif #ifdef max #undef max #endif typedef enum tag_xml_encoding { _x_xml_entity=0, _x_xml_cdata, _x_xml_values, _quoted_printable, _base64, _x_base85, _x_setiathome, _x_hex, _x_csv, _x_uuencode, _8bit, _binary } xml_encoding; const char * const xml_encoding_names[]= { "x-xml-entity", "x-xml-cdata", "x-xml-values", "quoted-printable", "base64", "x-base85", "x-setiathome", "x-hex", "x-csv", "x-uuencode", "8bit", "binary" }; #if 0 // the xml_ostream class is an ostream, which can be constructed // from an existing ostream (i.e. cout). When constructed, // an xml header and the opening tag are written. When destructed, // the closing tag is written. class xml_ostream { public: xml_ostream(ostream &o, const char *tag); ~xml_ostream(); template xml_ostream &operator <<(const T &t) { os << t; return *this; }; private: void write_head(); void write_foot(); std::string my_tag; std::ostream &os; }; // the xml_ofstream class is an ofstream. When the file is opened, // an xml header and the opening tag are written. Upon close, // the closing tag is written. class xml_ofstream { public: xml_ofstream(); explicit xml_ofstream(const char *filename, const char *tag, ios_base::openmode m=ios_base::out|ios_base::binary); ~xml_ofstream(); void open(const char *p, const char *tag, ios_base::openmode m=ios_base::out|ios_base::binary); void close(); private: void write_head(); void write_foot(); std::string my_tag; std::ofstream &os; }; // the xml_istream class is an istream that can be constructed from // an existing istream. When constructed, the stream is read until // the opening tag or end of file is found. This is really only useful // for reading XML from stdin. class xml_istream { public: explicit xml_istream(istream &i, const char *tag=0); ~xml_istream(); operator istream &() {return is;}; private: void seek_head(); std::string my_tag; std::istream &is; }; // the xml_ifstream class is an ifstream. When the file is opened, // the file pointer is set after the opening tag. An attempt to // read past the closing tag will fail as if the end of the file has // been reached. If no tag is given, it will assume the first tag // found is the main tag. #ifndef HAVE_STD_POS_TYPE typedef off_t pos_type; #endif #ifndef HAVE_STD_OFF_TYPE typedef off_t off_type; #endif class xml_ifstream { public: xml_ifstream(); explicit xml_ifstream(const char *filename, const char *tag=0, ios_base::openmode m=ios_base::in|ios_base::binary); ~xml_ifstream(); void open(const char *filename, const char *tag=0, ios_base::openmode m=ios_base::in|ios_base::binary); xml_ifstream &seekg(pos_type p); xml_ifstream &seekg(off_type o, ios_base::seekdir d); pos_type tellg(); bool eof(); private: void seek_head(); std::string my_tag; std::pos_type xml_start; std::pos_type xml_end; std::ifstream &ifs; }; #endif // 0 #define XML_ENCODING "iso-8859-1" static const char * const xml_header="\n"; // XML entity for tranlation table (not wchar_t compatible) struct xml_entity { unsigned char c; const char *s; }; // change the xml indent level (number of spaces) by adding or subtracting // "i" spaces. return a string of spaces corresponding to the current xml // indent level. std::string xml_indent(int i=0); static const int XML_MAX_INDENT=40; extern int xml_indent_level; // decode an XML character string. Return a the decoded string in a vector // (null not necessarily a terminator). //template //vector xml_decode_string(const char *input, size_t length=0, // const char *encoding="x_xml_entity"); // do the same thing, but get the length and encoding type from the // xml tag properties. template std::vector xml_decode_field(const std::string &input, const char *tag); // encode an XML character string. Return the encoded string. //template //string xml_encode_string(const T *input, size_t n_elements=0, // xml_encoding encoding=_x_xml_entity); template std::string xml_encode_string(const std::vector &input, xml_encoding encoding=_x_xml_entity) { return xml_encode_string(&(*(input.begin())),input.size(),encoding); } #include #include #include #include extern const char *encode_arr; extern const char *encode_arr85; bool isencchar(char c); bool isencchar85(char c); template std::string base64_encode(const T *tbin, size_t n_elements) { size_t nbytes=n_elements*sizeof(T); const unsigned char *bin=(const unsigned char *)(tbin); int count=0, offset=0, nleft; const char crlf[]= {0xa,0xd,0x0}; std::string rv(""); rv.reserve(nbytes*4/3+nbytes*2/57); char c[5]; for (nleft = (int)nbytes; nleft > 0; nleft -= 3) { int i; c[0] = (bin[offset]>>2) & 0x3f ; // 6 c[1] = (bin[offset]<<4) & 0x3f | ((bin[offset+1]>>4)&0xf); // 2+4 c[2] = ((bin[offset+1]<<2)&0x3f) | ((bin[offset+2]>>6)&0x3);// 4+2 c[3] = bin[offset+2]&0x3f; // 6 for (i=0;i<((nleft>3)?4:(nleft+1));i++) c[i]=encode_arr[(int)c[i]]; for (;i<4;i++) c[i]='='; c[4]=0; rv+=c; offset += 3; count += 4; if (count == 76 ) { count = 0; rv+=crlf; } } rv+=crlf; return rv; } template std::vector base64_decode(const char *data, size_t nbytes) { const char *p=data,*eol,*eol2,*eos; const char cr=0xa,lf=0xd; char in[4],c[3]; int i; std::vector rv; rv.reserve(nbytes*3/4); while (p<(data+nbytes)) { while (*p && (p<(data+nbytes)) && !isencchar(*p)) { p++; } if (!(*p) || (p>=(data+nbytes))) break; eol=strchr(p,cr); eol2=strchr(p,lf); eos=p+strlen(p); if (eol) { eol=std::min(eol,eos); } else { eol=eos; } if (eol && eol2) { eol=std::min(eol,eol2); } for (;p<(eol-1);p+=4) { for ( i=0;i<4;i++) { if ((p[i]>='A') && (p[i]<='Z')) { in[i]=p[i]-'A'; } else if ((p[i]>='a') && (p[i]<='z')) { in[i]=p[i]-'a'+26; } else if ((p[i]>='0') && (p[i]<='9')) { in[i]=p[i]-'0'+52; } else { switch (p[i]) { case '+': in[i]=62; break; case '/': in[i]=63; break; default : in[i]=0; } } } c[0]=(in[0]<<2) | ((in[1] >> 4) & 0x3); c[1]=(in[1]<<4) | ((in[2] >> 2) & 0xf); c[2]=(in[2]<<6) | in[3]; for ( i=0;i<3;i++) rv.push_back(c[i]); } } return std::vector((T *)(&(rv[0])),(T *)(&(rv[0]))+rv.size()/sizeof(T)); } template std::string base85_encode(const T *tbin, size_t n_elements) { size_t nbytes=n_elements*sizeof(T); const unsigned char *bin=(const unsigned char *)(tbin); int count=0; const char crlf[]= {0xa,0xd,0x0}; std::string rv(""); rv.reserve(nbytes*4/3+nbytes*2/57); char c[6]; int n_pads; unsigned int j=0; while (j3)?4:(nbytes-j));i++) val=(val<<8)+bin[j+i]; if (val) { for (n_pads=4-i;i<4;i++) val*=((i==3)?84:85); } if (val == 0) { c[0]='z'; // If the word is entirely zero use a single digit c[1]=0; // zero pad of 'z' } else { for (i=4;i<5;i--) { c[i]=(char)(val % ((i==4)?84:85)); // First division is by 84 to prevent val/= ((i==4)?84:85); // having a pad in the final digit. } if (c[0]==83) { // need to change a high order 'z' into c[0]=84; // an "_" so it won't look like a zero word. } for (i=0;i<5;i++) c[i]=encode_arr85[(int)c[i]]; for (i=5-n_pads;i<5;i++) c[i]='_'; // add pad characters c[5]=0; } j+=4; if (count>74) { rv+=crlf; count=0; } count+=(int)strlen(c); rv+=c; } return rv; } template std::vector base85_decode(const char *data, size_t nbytes) { const char *p=data,*eol,*eol2,*eos; const char cr=0xa,lf=0xd; unsigned long val; int npads,i; std::vector rv; rv.reserve(nbytes*4/5); while (p<(data+nbytes)) { while (*p && (p<(data+nbytes)) && !isencchar85(*p)) { p++; } if (!(*p) || (p>=(data+nbytes))) break; eol=strchr(p,cr); eol2=strchr(p,lf); eos=p+strlen(p); if (eol) { eol=std::min(eol,eos); } else { eol=eos; } if (eol && eol2) { eol=std::min(eol,eol2); } while (p0) { if (p[i]!='_') break; npads++; } for (i=0;i='0') && (p[i]<='9')) { val+=p[i]-'0'; } else if ((p[i]>='A') && (p[i]<='Z')) { val+=p[i]-'A'+10; } else if ((p[i]>='a') && (p[i]<='y')) { val+=p[i]-'a'+36; } else { for (int j=61; j<85; j++) { if (p[i]==encode_arr85[j]) { val+=j; j=85; } } if ((i==0) && (p[i]=='_')) val--; } } } val<<=(npads*8); char c[5]; c[4]=0; for (int i=3;i>=0;i--) { c[i]=(char)(val & 0xff); val>>=8; } for (int i=0;i<4;i++) { rv.push_back(c[i]); } p+=5; } } return std::vector((T *)(&(rv[0])),(T *)(&(rv[0]))+rv.size()/sizeof(T)); } template std::string x_setiathome_encode(const T *tbin, size_t n_elements) { size_t nbytes=n_elements*sizeof(T); const unsigned char *bin=(const unsigned char *)(tbin); int count=0, offset=0, nleft; const char cr=0xa; std::string rv(""); rv.reserve(nbytes*4/3+nbytes*2/48); rv+="\n"; char c[5]; for (nleft = (int)nbytes; nleft > 0; nleft -= 3) { c[0] = bin[offset]&0x3f; // 6 c[1] = (bin[offset]>>6) | (bin[offset+1]<<2)&0x3f; // 2+4 c[2] = ((bin[offset+1]>>4)&0xf) | (bin[offset+2]<<4)&0x3f;// 4+2 c[3] = bin[offset+2]>>2; // 6 for (int i=0;i<4;i++) c[i]+=0x20; c[4]=0; rv+=c; offset += 3; count += 4; if (count == 64) { count = 0; rv+=cr; } } rv+=cr; return rv; } template std::vector x_setiathome_decode(const char *data, size_t nbytes) { const char *p=data,*eol,*eol2,*eos; char in[4],c[3]; int i; std::vector rv; rv.reserve(nbytes*3/4); while (p<(data+nbytes)) { while ((*p<0x20) || (*p>0x60)) { p++; } eol=strchr(p,'\n'); eol2=strchr(p,'\r'); eos=p+strlen(p); if (eol) { eol=std::min(eol,eos); } else { eol=eos; } if (eol && eol2) { eol=std::min(eol,eol2); } for (;p<(eol-1);p+=4) { memcpy(in,p,4); for ( i=0;i<4;i++) in[i]-=0x20; c[0]=in[0]&0x3f | in[1]<<6; c[1]=in[1]>>2 | in[2]<<4; c[2]=in[2]>>4 | in[3]<<2; for ( i=0;i<3;i++) rv.push_back(c[i]); } } return std::vector((T *)(&(rv[0])),(T *)(&(rv[0]))+rv.size()/sizeof(T)); } template std::string quoted_printable_encode(const T *tbin, size_t n_elements) { size_t nbytes=n_elements*sizeof(T); const unsigned char *bin=(const unsigned char *)(tbin); int line_len=0; const char crlf[]= {'=',0xa,0xd,0x0}; std::string rv(""); rv.reserve(nbytes*4/3+nbytes*2/48); for (size_t i=0;i 74) { rv+=crlf; line_len=1; } rv+=bin[i]; } else { line_len+=3; if (line_len>72) { rv+=crlf; line_len=3; } char buf[4]; sprintf(buf,"=%.2X",bin[i]); rv+=buf; } } return rv; } template std::vector quoted_printable_decode(const char* data, size_t nbytes) { std::vector rv; rv.reserve(strlen(data)); size_t i=0; while (i((T *)(&(rv[0])),(T *)(&(rv[0]))+rv.size()/sizeof(T)); } template std::string x_hex_encode(const T *tbin, size_t n_elements) { size_t nbytes=n_elements*sizeof(T); const unsigned char *bin=(const unsigned char *)(tbin); std::string rv; int count=0; rv.reserve(nbytes*2+nbytes*2/76); for (unsigned int i=0; i std::vector x_hex_decode(const char *data, size_t nbytes) { std::vector rv; rv.reserve(nbytes/2); unsigned int i=0; while (i(c)); } return std::vector((T *)(&(rv[0])),(T *)(&(rv[0]))+rv.size()/sizeof(T)); } std::string x_csv_encode_char(const unsigned char *bin, size_t nelements); template std::string x_csv_encode(const T *bin, size_t nelements) { std::ostringstream rv(""); long lastlen,i; if (sizeof(T)==1) // if T is a char, print in another way return x_csv_encode_char((const unsigned char *)bin,nelements); rv << std::endl << xml_indent(2); // TMR moved here to fix PoT format lastlen=(long)rv.str().size(); // TMR for (i=0;i<(static_cast(nelements)-1);i++) { rv << bin[i] << ','; if ((static_cast(rv.str().size()) -(lastlen-std::min(xml_indent_level,XML_MAX_INDENT)))>73) { // TMR rv << std::endl << xml_indent(); lastlen=(long)rv.str().size(); } } rv << bin[i] << "\n" << xml_indent(-2); return rv.str(); } template std::vector x_csv_decode(const char *data, size_t nbytes) { std::vector rv; while (!isdigit(*data)) { data++; nbytes--; } std::istringstream in(std::string(data,nbytes)); bool ischar=(sizeof(T)==1); while (in) { T t; if (!ischar) { in >> t; } else { int i; in >> i; t=i & 0xff; } rv.push_back(t); char c=' '; while (in && !isdigit(c)) { in.get(c); } if (isdigit(c)) in.putback(c); } return rv; } std::string encode_char(unsigned char c); unsigned char decode_char(const char *s); template std::vector x_xml_entity_decode(const char *input, size_t length) { size_t i; char c; if (!length) { // We're going to decode until we see a null. Including the null. length=strlen((const char *)input); } std::vector rv; char *p; rv.reserve(length); for (i=0; i((T *)(&(rv[0])),(T *)(&(rv[0]))+rv.size()/sizeof(T)); } template std::string x_xml_entity_encode(const T *tbin, size_t n_elements) { size_t length=n_elements*sizeof(T); const unsigned char *input=(const unsigned char *)(tbin); unsigned int i; std::string rv; rv.reserve(length); for (i=0; i': case '<': case '&': case '\'': case '"': rv+=encode_char(input[i]); break; default: rv+=input[i]; } } else { char buf[16]; sprintf(buf,"&#%.3d;",input[i]); rv+=buf; } } return rv; } template std::string x_xml_values_encode(const T *bin, size_t n_elements) { std::ostringstream rv(""); unsigned int i; for (i=0;i std::vector x_xml_values_decode(const char *data, size_t length) { std::istringstream r(std::string(data,length)); std::vector rv; T t; while (!r.eof()) { r >> t ; rv.push_back(t); while ((isspace(r.peek()) || (r.peek() == ',')) && !r.eof()) { char c; r.get(c); } } return rv; } template std::string x_xml_cdata_encode(const T *tbin, size_t n_elements) { size_t length=n_elements*sizeof(T); const unsigned char *input=(const unsigned char *)(tbin); unsigned int i; std::string rv("0x1f) { switch (input[i]) { case ']': if (((length-i)>1) && (input[i+1]==']') && (input[i+2]=='>')) { rv+="&&endcdt;"; } else { rv+=']'; } break; default: rv+=input[i]; } } else { char buf[16]; sprintf(buf,"&&#%.2d;",input[i]); rv+=buf; } } rv+="]]>"; return rv; } template std::vector x_xml_cdata_decode(const char *input, size_t length) { size_t i; char c; if (!length) { // We're going to decode until we see a null. Including the null. length=strlen(input); } std::vector rv; char *p; rv.reserve(length); for (i=0; i8) && !strncmp((const char *)(input+i),"&&endcdt;",9)) { rv.push_back(']'); rv.push_back(']'); rv.push_back('>'); i+=8; } else { if (input[i+1]=='&') { rv.push_back(c=decode_char(input+i+1)); if ((c!='&') || !strncmp((const char *)(input+i+1),"&",5)) { p=strchr((char *)(input+i+1),';'); i=(p-input); } } else { rv.push_back(input[i]); } } } else { rv.push_back(input[i]); } } return std::vector((T *)(&(rv[0])),(T *)(&(rv[0]))+rv.size()/sizeof(T)); } template std::vector x_uudecode(const char *data, size_t nbytes) { std::vector rv; return rv; } template std::string x_uuencode(const T *data, size_t nbytes) { std::string rv; return rv; } inline int xml_encoding_from_string(const char *enc_string) { int i=_x_xml_entity; const char *p="xqb8"; // find the start to the encoding string (maybe prepended by // quote or whitespace. while (*enc_string && (strchr(p,*enc_string) == NULL)) enc_string++; do { if (!strncmp(enc_string,xml_encoding_names[i],strlen(xml_encoding_names[i]))) break; } while (i++ != _binary); return i; } template std::vector xml_decode_string(const char *input, size_t length=0, const char *encoding="x_xml_entity") { int i=xml_encoding_from_string(encoding); switch (i) { case _x_xml_entity: return x_xml_entity_decode(input,length); case _x_xml_cdata: return x_xml_cdata_decode(input,length); case _x_xml_values: return x_xml_values_decode(input,length); case _quoted_printable: return quoted_printable_decode(input,length); case _base64: return base64_decode(input,length); case _x_base85: return base85_decode(input,length); case _x_setiathome: return x_setiathome_decode(input,length); case _x_hex: return x_hex_decode(input,length); case _x_csv: return x_csv_decode(input,length); case _x_uuencode: return x_uudecode(input,length); case _8bit: case _binary: return std::vector((const T *)input,(const T *)input+length/sizeof(T)); default: return x_xml_entity_decode(input,length); } } template std::vector xml_decode_field(const std::string &input, const char *tag) { std::string start_tag("<"),end_tag("',start)+1; if (!length) { length=(unsigned int)endt - (unsigned int)start; } return (xml_decode_string(&(input.c_str()[start]),length,encoding)); } template std::string xml_encode_string(const T *input, size_t length=0, xml_encoding encoding=_x_xml_entity) { switch (encoding) { case _x_xml_entity: return x_xml_entity_encode(input,length); case _x_xml_cdata: return x_xml_cdata_encode(input,length); case _x_xml_values: return x_xml_values_encode(input,length); case _quoted_printable: return quoted_printable_encode(input,length); case _base64: return base64_encode(input,length); case _x_base85: return base85_encode(input,length); case _x_setiathome: return x_setiathome_encode(input,length); case _x_hex: return x_hex_encode(input,length); case _x_csv: return x_csv_encode(input,length); case _x_uuencode: return x_uuencode(input,length); case _8bit: case _binary: return std::string((const char *)(input),length*sizeof(T)); default: return x_xml_entity_encode(input,length); } } extern bool xml_match_tag(const char*, const char*); extern bool xml_match_tag(const std::string &, const char*); extern bool extract_xml_record(const std::string &field, const char *tag, std::string &record); #endif // // $Log: xml_util.h,v $ // Revision 1.8.2.6 2007/05/31 22:03:31 korpela // *** empty log message *** // // Revision 1.8.2.5 2007/03/09 00:21:15 vonkorff // Fixed missing trailing null in base64 encoding. // // Revision 1.8.2.4 2006/12/14 22:26:30 korpela // *** empty log message *** // // Revision 1.8.2.3 2005/12/01 00:01:01 korpela // Changed to an Intel compile of fftw3.dll. Hopefully this will fix the problem // with crashes on Pentium-MMX and earlier. // // Added a Dev-C++ project and modified source files to allow seti_boinc to compile // under MinGW. // // Revision 1.8.2.2 2005/10/17 22:33:33 korpela // Continuing previous fix // // Revision 1.8.2.1 2005/10/17 22:14:49 korpela // Fixed bugs with XML formatting and CSV vector input. The XML formatting bug // fixes were submitted by Tetsuji "Maverick" Rai. The CSV input problem was due // to my misunderstanding of the istream::operator void *(). I had thought the // operator returned NULL if the past operation had failed. Instead it returns // NULL if the NEXT operation will fail. // // Revision 1.8 2004/12/07 23:42:23 korpela // Added undef of min and max in case they are defined in a previously included // header file. // // Revision 1.7 2004/11/18 19:17:04 korpela // Fixed base64 and base85 decoding. // // Revision 1.6 2004/10/29 04:35:21 korpela // *** empty log message *** // // Revision 1.5 2004/10/21 22:02:48 korpela // *** empty log message *** // // Revision 1.4 2004/06/30 20:52:29 korpela // *** empty log message *** // // Revision 1.3 2004/06/24 08:55:29 quarl // *** empty log message *** // // Revision 1.2 2004/06/12 18:38:30 rwalton // *** empty log message *** // // Revision 1.1 2004/06/11 17:43:22 davea // *** empty log message *** // // Revision 1.21 2004/04/05 22:07:08 korpela // // Segfault problem fixed? // // Revision 1.20 2004/03/06 09:45:25 rwalton // *** empty log message *** // // Revision 1.19 2004/02/05 05:32:22 quarl // *** empty log message *** // // Revision 1.18 2004/01/22 17:57:41 davea // *** empty log message *** // // Revision 1.17 2003/12/01 23:42:05 korpela // Under some compilers template parameters of type char [] weren't getting // cast to char *. Template functions now use &(array[0]) to ensure correct // type is used. // // Revision 1.16 2003/10/29 20:08:50 korpela // *** empty log message *** // // Revision 1.15 2003/10/27 23:07:34 korpela // *** empty log message *** // // Revision 1.14 2003/10/27 20:07:12 korpela // *** empty log message *** // // Revision 1.13 2003/10/25 18:20:03 korpela // *** empty log message *** // // Revision 1.12 2003/10/24 16:58:11 korpela // *** empty log message *** // // Revision 1.11 2003/10/23 15:39:54 korpela // no message // // Revision 1.10 2003/10/22 23:11:49 davea // *** empty log message *** // // Revision 1.9 2003/10/22 22:36:52 jeffc // jeffc - init xml_encode/decode_string in the definition, not the prototype // // Revision 1.8 2003/10/22 18:13:39 korpela // *** empty log message *** // // Revision 1.7 2003/10/22 17:43:10 korpela // *** empty log message *** // // Revision 1.6 2003/10/22 15:24:10 korpela // *** empty log message *** // // Revision 1.5 2003/10/22 03:09:55 korpela // *** empty log message *** // // Revision 1.4 2003/10/21 18:14:36 korpela // *** empty log message *** // // boinc-app-seti_8.00~svn3701.orig/db/schema_master.h0000644000175000017500000014062113043230061022057 0ustar locutuslocutus// This file is automatically generated. Do not edit #ifndef _H_schema_master_H #define _H_schema_master_H extern const char *db_name; extern int db_is_open; #if !defined(CLIENT) && !defined(NEBULA) inline int db_open() { if (!db_is_open) db_is_open=sql_database(db_name); return db_is_open; } inline int db_close() { if (db_is_open) db_is_open=!sql_finish(); return !db_is_open; } inline int db_change(const char *name) { if(strcmp(db_name, name) || !db_is_open) { db_close(); db_name=name; db_open(); } return(db_is_open); } #else inline int db_open() { return (db_is_open=1); } inline int db_close() { return !(db_is_open=0); } inline int db_change() { return (db_is_open=1); } #ifdef NEBULA typedef long sqlint8_t; template struct db_reference { ID_TYPE id; void parse_xml(std::string &buf, const char *tag) {}; void parse(const std::string &buf) {}; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const {}; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=1, const char *tag=0) const {}; void parse(const SQL_ROW&) {}; }; #endif //NEBULA #endif //CLIENT || NEBULA class coordinate_t : public db_type { public: double time; double ra; double dec; coordinate_t(); coordinate_t(const coordinate_t &a); coordinate_t(const SQL_ROW &a); coordinate_t(const std::string &s,const char *tag="coordinate_t"); coordinate_t &operator =(const coordinate_t &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="coordinate_t") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="coordinate_t"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class chirp_parameter_t : public db_type { public: double chirp_limit; long fft_len_flags; chirp_parameter_t(); chirp_parameter_t(const chirp_parameter_t &a); chirp_parameter_t(const SQL_ROW &a); chirp_parameter_t(const std::string &s,const char *tag="chirp_parameter_t"); chirp_parameter_t &operator =(const chirp_parameter_t &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="chirp_parameter_t") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="chirp_parameter_t"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class subband_description_t : public db_type { public: long number; double center; double base; double sample_rate; subband_description_t(); subband_description_t(const subband_description_t &a); subband_description_t(const SQL_ROW &a); subband_description_t(const std::string &s,const char *tag="subband_description_t"); subband_description_t &operator =(const subband_description_t &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="subband_description_t") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="subband_description_t"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class data_description_t : public db_type { public: double start_ra; double start_dec; double end_ra; double end_dec; double true_angle_range; char time_recorded[255]; double time_recorded_jd; long nsamples; sqlblob coords ; data_description_t(); data_description_t(const data_description_t &a); data_description_t(const SQL_ROW &a); data_description_t(const std::string &s,const char *tag="data_description_t"); data_description_t &operator =(const data_description_t &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="data_description_t") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="data_description_t"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class receiver_config : public db_table { public: long id; long s4_id; char name[255]; double beam_width; double center_freq; double latitude; double longitude; double elevation; double glat; double glon; double galt; double diameter; double az_orientation; sqlblob az_corr_coeff ; sqlblob zen_corr_coeff ; double array_az_ellipse; double array_za_ellipse; double array_angle; long min_vgc; char polarization[32]; receiver_config(); receiver_config(const receiver_config &a); receiver_config(const SQL_ROW &a); receiver_config(const std::string &s,const char *tag="receiver_config"); receiver_config &operator =(const receiver_config &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="receiver_config") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="receiver_config"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class recorder_config : public db_table { public: long id; char name[64]; long bits_per_sample; double sample_rate; long beams; double version; recorder_config(); recorder_config(const recorder_config &a); recorder_config(const SQL_ROW &a); recorder_config(const std::string &s,const char *tag="recorder_config"); recorder_config &operator =(const recorder_config &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="recorder_config") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="recorder_config"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class splitter_config : public db_table { public: long id; double version; char data_type[64]; long fft_len; long ifft_len; char filter[64]; char window[64]; long samples_per_wu; double highpass; char blanker_filter[64]; long pfb_ntaps; double pfb_width_factor; long wu_bits_per_sample; splitter_config(); splitter_config(const splitter_config &a); splitter_config(const SQL_ROW &a); splitter_config(const std::string &s,const char *tag="splitter_config"); splitter_config &operator =(const splitter_config &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="splitter_config") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="splitter_config"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class analysis_config : public db_table { public: long id; double spike_thresh; long spikes_per_spectrum; double autocorr_thresh; long autocorr_per_spectrum; long autocorr_fftlen; double gauss_null_chi_sq_thresh; double gauss_chi_sq_thresh; double gauss_power_thresh; double gauss_peak_power_thresh; long gauss_pot_length; double pulse_thresh; double pulse_display_thresh; long pulse_max; long pulse_min; long pulse_fft_max; long pulse_pot_length; double triplet_thresh; long triplet_max; long triplet_min; long triplet_pot_length; double pot_overlap_factor; double pot_t_offset; double pot_min_slew; double pot_max_slew; double chirp_resolution; long analysis_fft_lengths; long bsmooth_boxcar_length; long bsmooth_chunk_size; sqlblob chirps ; double pulse_beams; long max_signals; long max_spikes; long max_autocorr; long max_gaussians; long max_pulses; long max_triplets; long keyuniq; double credit_rate; analysis_config(); analysis_config(const analysis_config &a); analysis_config(const SQL_ROW &a); analysis_config(const std::string &s,const char *tag="analysis_config"); analysis_config &operator =(const analysis_config &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="analysis_config") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="analysis_config"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class science_config : public db_table { public: long id; long active; char qpix_scheme[16]; long qpix_nside; double fpix_width; double total_bandwidth; double freq_uncertainty; double fwhm_beamwidth; double sky_disc_radius; double observable_sky; long epoch; double bary_chirp_window; long bary_freq_window; long nonbary_freq_window; double spike_obs_duration; double spike_obs_interval; double gauss_obs_duration; double gauss_obs_interval; double pulse_obs_duration; double pulse_obs_interval; double triplet_obs_duration; double triplet_obs_interval; sqlint8_t min_spike_id; sqlint8_t min_autocorr_id; sqlint8_t min_gaussian_id; sqlint8_t min_pulse_id; sqlint8_t min_triplet_id; double min_app_version; char info_xml[255]; science_config(); science_config(const science_config &a); science_config(const SQL_ROW &a); science_config(const std::string &s,const char *tag="science_config"); science_config &operator =(const science_config &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="science_config") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="science_config"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class candidate_t : public db_type { public: long type; sqlint8_t id; long num_obs; double score; long is_rfi; candidate_t(); candidate_t(const candidate_t &a); candidate_t(const SQL_ROW &a); candidate_t(const std::string &s,const char *tag="candidate_t"); candidate_t &operator =(const candidate_t &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="candidate_t") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="candidate_t"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class meta_candidate : public db_table { public: sqlint8_t id; long version; double time_last_updated; long num_spikes; long num_spike_b_multiplets; double best_spike_b_mp_score; long num_spike_nb_multiplets; double best_spike_nb_mp_score; sqlint8_t spike_high_id; long num_gaussians; long num_gaussian_b_multiplets; double best_gaussian_b_mp_score; long num_gaussian_nb_multiplets; double best_gaussian_nb_mp_score; sqlint8_t gaussian_high_id; long num_pulses; long num_pulse_b_multiplets; double best_pulse_b_mp_score; long num_pulse_nb_multiplets; double best_pulse_nb_mp_score; sqlint8_t pulse_high_id; long num_triplets; long num_triplet_b_multiplets; double best_triplet_b_mp_score; long num_triplet_nb_multiplets; double best_triplet_nb_mp_score; sqlint8_t triplet_high_id; long num_stars; double best_star_score; double meta_score; long rfi_clean; long state; meta_candidate(); meta_candidate(const meta_candidate &a); meta_candidate(const SQL_ROW &a); meta_candidate(const std::string &s,const char *tag="meta_candidate"); meta_candidate &operator =(const meta_candidate &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="meta_candidate") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="meta_candidate"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class meta_candidate_tinysky : public db_table { public: sqlint8_t id; long version; double time_last_updated; long num_spikes; long num_spike_b_multiplets; double best_spike_b_mp_score; long num_spike_nb_multiplets; double best_spike_nb_mp_score; sqlint8_t spike_high_id; long num_gaussians; long num_gaussian_b_multiplets; double best_gaussian_b_mp_score; long num_gaussian_nb_multiplets; double best_gaussian_nb_mp_score; sqlint8_t gaussian_high_id; long num_pulses; long num_pulse_b_multiplets; double best_pulse_b_mp_score; long num_pulse_nb_multiplets; double best_pulse_nb_mp_score; sqlint8_t pulse_high_id; long num_triplets; long num_triplet_b_multiplets; double best_triplet_b_mp_score; long num_triplet_nb_multiplets; double best_triplet_nb_mp_score; sqlint8_t triplet_high_id; long num_stars; double best_star_score; double meta_score; long rfi_clean; long state; meta_candidate_tinysky(); meta_candidate_tinysky(const meta_candidate_tinysky &a); meta_candidate_tinysky(const SQL_ROW &a); meta_candidate_tinysky(const std::string &s,const char *tag="meta_candidate_tinysky"); meta_candidate_tinysky &operator =(const meta_candidate_tinysky &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="meta_candidate_tinysky") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="meta_candidate_tinysky"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class multiplet : public db_table { public: long id; long version; long signal_type; long mp_type; long qpix; double freq_win; double mean_ra; double mean_decl; double ra_stddev; double decl_stddev; double mean_angular_distance; double angular_distance_stddev; double mean_frequency; double frequency_stddev; double mean_chirp; double chirp_stddev; double mean_period; double period_stddev; double mean_snr; double snr_stddev; double mean_threshold; double threshold_stddev; double score; long num_detections; sqlblob signal_ids ; multiplet(); multiplet(const multiplet &a); multiplet(const SQL_ROW &a); multiplet(const std::string &s,const char *tag="multiplet"); multiplet &operator =(const multiplet &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="multiplet") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="multiplet"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class star : public db_table { public: long id; char object_type[16]; char catalog_name[64]; long catalog_number; char object_name[64]; double ra; double decl; long qpix; double v_mag; double b_minus_v; double parallax; char stellar_type[32]; long planets; double score; star(); star(const star &a); star(const SQL_ROW &a); star(const std::string &s,const char *tag="star"); star &operator =(const star &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="star") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="star"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class candidate_count : public db_table { public: long id; sqlint8_t spikes; sqlint8_t gaussians; sqlint8_t pulses; sqlint8_t triplets; sqlint8_t spike_barycentric_multiplets; sqlint8_t gaussian_barycentric_multiplets; sqlint8_t pulse_barycentric_multiplets; sqlint8_t triplet_barycentric_multiplets; sqlint8_t spike_nonbarycentric_multiplets; sqlint8_t gaussian_nonbarycentric_multiplets; sqlint8_t pulse_nonbarycentric_multiplets; sqlint8_t triplet_nonbarycentric_multiplets; sqlint8_t stars; long time_last_updated; candidate_count(); candidate_count(const candidate_count &a); candidate_count(const SQL_ROW &a); candidate_count(const std::string &s,const char *tag="candidate_count"); candidate_count &operator =(const candidate_count &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="candidate_count") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="candidate_count"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class tape : public db_table { public: long id; char name[128]; double start_time; double last_block_time; long last_block_done; long missed; long tape_quality; long beam; tape(); tape(const tape &a); tape(const SQL_ROW &a); tape(const std::string &s,const char *tag="tape"); tape &operator =(const tape &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="tape") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="tape"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class settings : public db_table { public: long id; long active; db_reference recorder_cfg; db_reference splitter_cfg; db_reference analysis_cfg; db_reference receiver_cfg; settings(); settings(const settings &a); settings(const SQL_ROW &a); settings(const std::string &s,const char *tag="settings"); settings &operator =(const settings &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="settings") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="settings"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class workunit_grp : public db_table { public: long id; db_reference tape_info; char name[128]; data_description_t data_desc; db_reference receiver_cfg; db_reference recorder_cfg; db_reference splitter_cfg; db_reference analysis_cfg; long sb_id; long iq_modified; long alfa_filter_bank; workunit_grp(); workunit_grp(const workunit_grp &a); workunit_grp(const SQL_ROW &a); workunit_grp(const std::string &s,const char *tag="workunit_grp"); workunit_grp &operator =(const workunit_grp &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="workunit_grp") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="workunit_grp"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class workunit_header : public db_table { public: sqlint8_t id; char name[128]; db_reference group_info; subband_description_t subband_desc; sqlint8_t sb_id; workunit_header(); workunit_header(const workunit_header &a); workunit_header(const SQL_ROW &a); workunit_header(const std::string &s,const char *tag="workunit_header"); workunit_header &operator =(const workunit_header &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="workunit_header") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="workunit_header"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; typedef workunit_header workunit; class result : public db_table { public: sqlint8_t id; sqlint8_t boinc_result; db_reference wuid; double received; long hostid; long versionid; long return_code; long overflow; long reserved; sqlint8_t sb_id; result(); result(const result &a); result(const SQL_ROW &a); result(const std::string &s,const char *tag="result"); result &operator =(const result &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="result") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="result"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class triplet : public db_table { public: sqlint8_t id; db_reference result_id; double peak_power; double mean_power; double time; double ra; double decl; sqlint8_t q_pix; double freq; double detection_freq; double barycentric_freq; long fft_len; double chirp_rate; long rfi_checked; long rfi_found; long reserved; double period; triplet(); triplet(const triplet &a); triplet(const SQL_ROW &a); triplet(const std::string &s,const char *tag="triplet"); triplet &operator =(const triplet &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="triplet") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="triplet"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class triplet_small : public db_table { public: sqlint8_t id; db_reference result_id; double peak_power; double mean_power; double time; double ra; double decl; sqlint8_t q_pix; double freq; double detection_freq; double barycentric_freq; long fft_len; double chirp_rate; long rfi_checked; long rfi_found; long reserved; double period; triplet_small(); triplet_small(const triplet_small &a); triplet_small(const SQL_ROW &a); triplet_small(const std::string &s,const char *tag="triplet_small"); triplet_small &operator =(const triplet_small &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="triplet_small") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="triplet_small"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class gaussian : public db_table { public: sqlint8_t id; db_reference result_id; double peak_power; double mean_power; double time; double ra; double decl; sqlint8_t q_pix; double freq; double detection_freq; double barycentric_freq; long fft_len; double chirp_rate; long rfi_checked; long rfi_found; long reserved; double sigma; double chisqr; double null_chisqr; double score; double max_power; sqlblob pot; gaussian(); gaussian(const gaussian &a); gaussian(const SQL_ROW &a); gaussian(const std::string &s,const char *tag="gaussian"); gaussian &operator =(const gaussian &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="gaussian") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="gaussian"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class gaussian_small : public db_table { public: sqlint8_t id; db_reference result_id; double peak_power; double mean_power; double time; double ra; double decl; sqlint8_t q_pix; double freq; double detection_freq; double barycentric_freq; long fft_len; double chirp_rate; long rfi_checked; long rfi_found; long reserved; double sigma; double chisqr; double null_chisqr; double score; double max_power; gaussian_small(); gaussian_small(const gaussian_small &a); gaussian_small(const SQL_ROW &a); gaussian_small(const std::string &s,const char *tag="gaussian_small"); gaussian_small &operator =(const gaussian_small &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="gaussian_small") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="gaussian_small"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class pulse : public db_table { public: sqlint8_t id; db_reference result_id; double peak_power; double mean_power; double time; double ra; double decl; sqlint8_t q_pix; double freq; double detection_freq; double barycentric_freq; long fft_len; double chirp_rate; long rfi_checked; long rfi_found; long reserved; double period; double snr; double thresh; double score; long len_prof; sqlblob pot; pulse(); pulse(const pulse &a); pulse(const SQL_ROW &a); pulse(const std::string &s,const char *tag="pulse"); pulse &operator =(const pulse &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="pulse") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="pulse"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class pulse_small : public db_table { public: sqlint8_t id; db_reference result_id; double peak_power; double mean_power; double time; double ra; double decl; sqlint8_t q_pix; double freq; double detection_freq; double barycentric_freq; long fft_len; double chirp_rate; long rfi_checked; long rfi_found; long reserved; double period; double snr; double thresh; double score; pulse_small(); pulse_small(const pulse_small &a); pulse_small(const SQL_ROW &a); pulse_small(const std::string &s,const char *tag="pulse_small"); pulse_small &operator =(const pulse_small &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="pulse_small") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="pulse_small"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class sah_pointing : public db_table { public: long time_id; double time; double ra; double dec; long q_pix; double angle_range; long bad; sah_pointing(); sah_pointing(const sah_pointing &a); sah_pointing(const SQL_ROW &a); sah_pointing(const std::string &s,const char *tag="sah_pointing"); sah_pointing &operator =(const sah_pointing &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="sah_pointing") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="sah_pointing"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class sky_map : public db_table { public: sqlint8_t npix; long qpix; long fpix; sqlint8_t spike_max_id; sqlint8_t gaussian_max_id; sqlint8_t pulse_max_id; sqlint8_t triplet_max_id; long spike_count; long gaussian_count; long pulse_count; long triplet_count; long new_data; double score; sky_map(); sky_map(const sky_map &a); sky_map(const SQL_ROW &a); sky_map(const std::string &s,const char *tag="sky_map"); sky_map &operator =(const sky_map &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="sky_map") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="sky_map"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class hotpix : public db_table { public: long id; long last_hit_time; hotpix(); hotpix(const hotpix &a); hotpix(const SQL_ROW &a); hotpix(const std::string &s,const char *tag="hotpix"); hotpix &operator =(const hotpix &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="hotpix") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="hotpix"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class hotpix_tinysky : public db_table { public: long id; long last_hit_time; hotpix_tinysky(); hotpix_tinysky(const hotpix_tinysky &a); hotpix_tinysky(const SQL_ROW &a); hotpix_tinysky(const std::string &s,const char *tag="hotpix_tinysky"); hotpix_tinysky &operator =(const hotpix_tinysky &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="hotpix_tinysky") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="hotpix_tinysky"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class spike : public db_table { public: sqlint8_t id; db_reference result_id; double peak_power; double mean_power; double time; double ra; double decl; sqlint8_t q_pix; double freq; double detection_freq; double barycentric_freq; long fft_len; double chirp_rate; long rfi_checked; long rfi_found; long reserved; spike(); spike(const spike &a); spike(const SQL_ROW &a); spike(const std::string &s,const char *tag="spike"); spike &operator =(const spike &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="spike") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="spike"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class spike_small : public db_table { public: sqlint8_t id; db_reference result_id; double peak_power; double mean_power; double time; double ra; double decl; sqlint8_t q_pix; double freq; double detection_freq; double barycentric_freq; long fft_len; double chirp_rate; long rfi_checked; long rfi_found; long reserved; spike_small(); spike_small(const spike_small &a); spike_small(const SQL_ROW &a); spike_small(const std::string &s,const char *tag="spike_small"); spike_small &operator =(const spike_small &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="spike_small") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="spike_small"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class autocorr : public db_table { public: sqlint8_t id; db_reference result_id; double peak_power; double mean_power; double time; double ra; double decl; sqlint8_t q_pix; double delay; double freq; double detection_freq; double barycentric_freq; long fft_len; double chirp_rate; long rfi_checked; long rfi_found; long reserved; autocorr(); autocorr(const autocorr &a); autocorr(const SQL_ROW &a); autocorr(const std::string &s,const char *tag="autocorr"); autocorr &operator =(const autocorr &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="autocorr") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="autocorr"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class autocorr_small : public db_table { public: sqlint8_t id; db_reference result_id; double peak_power; double mean_power; double time; double ra; double decl; sqlint8_t q_pix; double delay; double freq; double detection_freq; double barycentric_freq; long fft_len; double chirp_rate; long rfi_checked; long rfi_found; long reserved; autocorr_small(); autocorr_small(const autocorr_small &a); autocorr_small(const SQL_ROW &a); autocorr_small(const std::string &s,const char *tag="autocorr_small"); autocorr_small &operator =(const autocorr_small &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="autocorr_small") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="autocorr_small"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class classic_versions : public db_table { public: long id; long ver_major; long ver_minor; long platformid; char comment[254]; char filename[254]; char md5_cksum[254]; char sum_cksum[254]; char cksum_cksum[254]; long file_cksum; classic_versions(); classic_versions(const classic_versions &a); classic_versions(const SQL_ROW &a); classic_versions(const std::string &s,const char *tag="classic_versions"); classic_versions &operator =(const classic_versions &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="classic_versions") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="classic_versions"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class classic_active_versions : public db_table { public: long id; long versionid; long ver_major; long ver_minor; classic_active_versions(); classic_active_versions(const classic_active_versions &a); classic_active_versions(const SQL_ROW &a); classic_active_versions(const std::string &s,const char *tag="classic_active_versions"); classic_active_versions &operator =(const classic_active_versions &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="classic_active_versions") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="classic_active_versions"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class classic_active_versionids : public db_table { public: long id; long versionid; classic_active_versionids(); classic_active_versionids(const classic_active_versionids &a); classic_active_versionids(const SQL_ROW &a); classic_active_versionids(const std::string &s,const char *tag="classic_active_versionids"); classic_active_versionids &operator =(const classic_active_versionids &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="classic_active_versionids") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="classic_active_versionids"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class rfi_zone : public db_table { public: long id; long min_receiver_s4id; long max_receiver_s4id; long min_splitter_config; long max_splitter_config; long min_analysis_config; long max_analysis_config; long min_tape_id; long max_tape_id; sqlint8_t min_workunit_id; sqlint8_t max_workunit_id; sqlint8_t min_result_id; sqlint8_t max_result_id; double min_time; double max_time; double central_baseband_freq; double baseband_freq_width; double central_detection_freq; double detection_freq_width; double central_period; double period_width; long fft_len_flags; long signal_type_flags; double ra; double dec; double angular_distance; rfi_zone(); rfi_zone(const rfi_zone &a); rfi_zone(const SQL_ROW &a); rfi_zone(const std::string &s,const char *tag="rfi_zone"); rfi_zone &operator =(const rfi_zone &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="rfi_zone") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="rfi_zone"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class bad_data : public db_table { public: char name[128]; long beam; char reason[255]; bad_data(); bad_data(const bad_data &a); bad_data(const SQL_ROW &a); bad_data(const std::string &s,const char *tag="bad_data"); bad_data &operator =(const bad_data &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="bad_data") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="bad_data"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class spike_tinysky : public db_table { public: sqlint8_t id; db_reference result_id; double peak_power; double mean_power; double time; double ra; double decl; sqlint8_t q_pix; double freq; double detection_freq; double barycentric_freq; long fft_len; double chirp_rate; long rfi_checked; long rfi_found; long reserved; spike_tinysky(); spike_tinysky(const spike_tinysky &a); spike_tinysky(const SQL_ROW &a); spike_tinysky(const std::string &s,const char *tag="spike_tinysky"); spike_tinysky &operator =(const spike_tinysky &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="spike_tinysky") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="spike_tinysky"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class gaussian_tinysky : public db_table { public: sqlint8_t id; db_reference result_id; double peak_power; double mean_power; double time; double ra; double decl; sqlint8_t q_pix; double freq; double detection_freq; double barycentric_freq; long fft_len; double chirp_rate; long rfi_checked; long rfi_found; long reserved; double sigma; double chisqr; double null_chisqr; double score; double max_power; sqlblob pot; gaussian_tinysky(); gaussian_tinysky(const gaussian_tinysky &a); gaussian_tinysky(const SQL_ROW &a); gaussian_tinysky(const std::string &s,const char *tag="gaussian_tinysky"); gaussian_tinysky &operator =(const gaussian_tinysky &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="gaussian_tinysky") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="gaussian_tinysky"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class pulse_tinysky : public db_table { public: sqlint8_t id; db_reference result_id; double peak_power; double mean_power; double time; double ra; double decl; sqlint8_t q_pix; double freq; double detection_freq; double barycentric_freq; long fft_len; double chirp_rate; long rfi_checked; long rfi_found; long reserved; double period; double snr; double thresh; double score; long len_prof; sqlblob pot; pulse_tinysky(); pulse_tinysky(const pulse_tinysky &a); pulse_tinysky(const SQL_ROW &a); pulse_tinysky(const std::string &s,const char *tag="pulse_tinysky"); pulse_tinysky &operator =(const pulse_tinysky &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="pulse_tinysky") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="pulse_tinysky"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class triplet_tinysky : public db_table { public: sqlint8_t id; db_reference result_id; double peak_power; double mean_power; double time; double ra; double decl; sqlint8_t q_pix; double freq; double detection_freq; double barycentric_freq; long fft_len; double chirp_rate; long rfi_checked; long rfi_found; long reserved; double period; triplet_tinysky(); triplet_tinysky(const triplet_tinysky &a); triplet_tinysky(const SQL_ROW &a); triplet_tinysky(const std::string &s,const char *tag="triplet_tinysky"); triplet_tinysky &operator =(const triplet_tinysky &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="triplet_tinysky") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="triplet_tinysky"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; class autocorr_tinysky : public db_table { public: sqlint8_t id; db_reference result_id; double peak_power; double mean_power; double time; double ra; double decl; sqlint8_t q_pix; double delay; double freq; double detection_freq; double barycentric_freq; long fft_len; double chirp_rate; long rfi_checked; long rfi_found; long reserved; autocorr_tinysky(); autocorr_tinysky(const autocorr_tinysky &a); autocorr_tinysky(const SQL_ROW &a); autocorr_tinysky(const std::string &s,const char *tag="autocorr_tinysky"); autocorr_tinysky &operator =(const autocorr_tinysky &a); std::string update_format() const; std::string insert_format() const; std::string select_format() const; std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="autocorr_tinysky") const; void parse(const SQL_ROW &s); void parse(const std::string &s); void parse_xml(const std::string &s,const char *tag="autocorr_tinysky"); #ifdef NEBULA bool nebula_read(FILE *f); #endif private: }; #endif boinc-app-seti_8.00~svn3701.orig/db/sqlblob.cpp0000644000175000017500000000331210671336410021241 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "sah_config.h" #include #include #include #include #include #include #include "sqldefs.h" #include "sqlrow.h" #include "sqlblob.h" #ifndef CLIENT #include "sqlapi.h" #endif std::string escape_char(unsigned char c) { std::string rv(""); if (isprint(c)) { switch (c) { case '\\': rv="\\\\"; break; case '\'': rv="\\'"; break; case '"': rv="\\\""; break; case ',': rv="\\,"; break; default: rv+=c; } } else { char buf[8]; sprintf(buf,"\\%.4o",c); rv=buf; } return rv; } unsigned char unescape_char(const unsigned char *&s) { unsigned char rv; int i; if (*s != '\\') return *s; switch (*(s+1)) { case '0': sscanf((const char *)(s+1),"%4o",&i); rv=i&0xff; s+=4; break; default: rv=*(++s); } return rv; } boinc-app-seti_8.00~svn3701.orig/db/schema_to_class.awk0000644000175000017500000007216312632143161022742 0ustar locutuslocutus# Copyright 2003-2005 Regents of the University of California # SETI_BOINC is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free # Software Foundation; either version 2, or (at your option) any later # version. # SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # more details. # You should have received a copy of the GNU General Public License along # with SETI_BOINC; see the file COPYING. If not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Copyright 2003-2005 Regents, University of California # All rights reserved # # $Id: schema_to_class.awk,v 1.57.2.5 2007/03/29 01:08:22 korpela Exp $ # BEGIN { print "processing BEGIN" # Work around gawk FILENAME bug. if ((FILENAME=="") || (FILENAME=="-")) { tmpfilename=ARGV[ARGC-1] headerfile=ARGV[ARGC-1]".h" sourcefile=ARGV[ARGC-1]".cpp" } else { tmpfilename=FILENAME headerfile=FILENAME".h" sourcefile=FILENAME".cpp" } print "// This file is automatically generated. Do not edit" > sourcefile print "// This file is automatically generated. Do not edit" > headerfile print "#include \"sah_config.h\"" > sourcefile print "" > sourcefile print "#include " > sourcefile print "#include " >sourcefile print "#include " >sourcefile print "#include " >sourcefile print "#include " >sourcefile print "#include " >sourcefile print "#include " > sourcefile print "" > sourcefile print "#include \"parse.h\"" > sourcefile print "#include \"xml_util.h\"" > sourcefile print "#include \"db_table.h\"" >sourcefile n=split(tmpfilename,a,"/") print "#include \""a[n]".h\"" >sourcefile print "\n#ifdef _WIN32" >sourcefile print "#pragma warning( disable : 4355 )" >sourcefile print "#endif\n" >sourcefile print "#ifndef _H_"a[n]"_H" >headerfile print "#define _H_"a[n]"_H" >headerfile print "#define found(x) ((x != std::string::npos))" >sourcefile print "" > sourcefile nrefs=1 nfields=1 ref_table[1]="" ref_row[1]="" ref_rtable[1]="" def_types[1]="no_types_defined" ndef_types=1 } /^begin_refs/,/^end_refs/ \ { print "processing refs" ref_table[nrefs]=$1 ref_row[nrefs]=$2 ref_rtable[nrefs++]=$3 } /synonym/,/;/ \ { print "processing synonym" if (index($5,";")) { split($5,a,";") tt=a[1] } else { tt=$5 } print "typedef "tt" "$3";" >headerfile next } /database/,/;/ \ { dbtype="" print "processing database" for (i=0;isourcefile print "using namespace "dbtype";" >sourcefile print "#endif\n\n" >sourcefile } if (index(db_name,";")) { split(db_name,a,";") db_name=a[1] } print "extern const char *db_name;" >headerfile print "const char *db_name=\""db_name"\";" >sourcefile print "extern int db_is_open;\n" >headerfile print "int db_is_open;\n" >sourcefile print "#if !defined(CLIENT) && !defined(NEBULA)" >headerfile print "inline int db_open() { \n\t if (!db_is_open) db_is_open=sql_database(db_name);\n\t return db_is_open; }" >headerfile print "inline int db_close() { \n\t if (db_is_open) db_is_open=!sql_finish();\n\t return !db_is_open; }" >headerfile print "inline int db_change(const char *name) { \n\t if(strcmp(db_name, name) || !db_is_open) { \n\t\t db_close();\n\t\t db_name=name;\n\t\t db_open(); } return(db_is_open); }" >headerfile print "#else" >headerfile print "inline int db_open() { return (db_is_open=1); }" >headerfile print "inline int db_close() { return !(db_is_open=0); }" >headerfile print "inline int db_change() { return (db_is_open=1); }" >headerfile print "#ifdef NEBULA" > headerfile print "typedef sqlint8_t long;" > headerfile print "template " > headerfile print "struct db_reference {" > headerfile print " ID_TYPE id;" > headerfile print " void parse_xml(std::string &buf, const char *tag) {};" >headerfile print " void parse(const std::string &buf) {};" >headerfile print " std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const {};" > headerfile print " std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=1, const char *tag=0) const {};" > headerfile print "};" > headerfile print "#endif //NEBULA\n" >headerfile print "#endif //CLIENT || NEBULA\n" >headerfile next } /{/ { print "// "$0 > headerfile print "// "$0 > sourcefile while (!index($0,"}")) { getline print "// "$0 > headerfile print "// "$0 > sourcefile } print "\n" >headerfile print "\n" >sourcefile next } /deprecated/ { next } /alter/ { while (!index($0,";")) { getline } next } /revoke/ { while (!index($0,";")) { getline } next } /index/ { while (!index($0,";")) { getline } next } /create[ \t]/ { print "processing create" if ($2 == "table") { if (index($3,"\.")) { n=split($3,a,"\.") } else { n=1 a[n]=$3 } is_typedef=0 } else { if (index($4,"\.")) { n=split($4,a,"\.") } else { n=1 a[n]=$4 } is_typedef=1 } nfields=1 fields[1]="" type[1]="" nsf=1 sf[1]="" sfz[1]=0 table=a[n] if (is_typedef) { def_types[ndef_types++]=a[n] print "class ",a[n], \ " : public db_type<"a[n]"> {\n public:" \ > headerfile } else { print "class ",a[n], \ " : public db_table<"a[n]"> {\n public:" \ > headerfile } } /list\(/ { print "processing list" isref=0 islist=1 n=split($2,a,"(") if (a[n] == "int8" || a[n] == "bigint" || a[n] == "integer8") { a[n]="sqlint8_t" } type[nfields]="v "a[n] fields[nfields++]=$1 print "\tsqlblob<"a[n]"> ",$1,";" > headerfile next } /integer8|bigint|int8/ { print "processing integer8" isref=0 type[nfields]="ld" if (index($NF,"bitfield")) type[nfields]="lb" fields[nfields++]=$1 for (i=1;i "ref_row[i]";" >headerfile type[nfields-1]="r" } } if (!isref) print "\tsqlint8_t ",$1";" > headerfile if ($1=="id") { id_type[table]="sqlint8_t " id_name[table]=$1 } next } /[ \t]integer|[ \t]int/ { print "processing integer" isref=0 type[nfields]="d" fields[nfields++]=$1 for (i=1;i "ref_row[i]";" >headerfile type[nfields-1]="r" } } if (!isref) print "\tlong ",$1";" > headerfile if ($1=="id") { id_type[table]="long" id_name[table]=$1 } next } /[ \t]smallint|[ \t]mediumint/ { print "processing smallint" isref=0 type[nfields]="d" fields[nfields++]=$1 for (i=1;i "ref_row[i]";" >headerfile print ref_rtable[i],table"."ref_row[i] type[nfields-1]="r" } } if (!isref) print "\tlong ",$1";" > headerfile if ($1=="id") { id_type[table]="long" id_name[table]=$1 } next } /serial8|bigint*auto_increment/ { print "processing serial8" key=$1 type[nfields]="ld" id_type[table]="sqlint8_t" id_name[table]=$1 fields[nfields++]=$1 print "\tsqlint8_t ",$1";" > headerfile next } /serial|auto_increment/ { print "processing serial" key=$1 type[nfields]="d" id_type[table]="long" id_name[table]=$1 fields[nfields++]=$1 print "\tlong ",$1";" > headerfile next } /smallfloat/ { print "processing smallfloat" type[nfields]="f" fields[nfields++]=$1 print "\tdouble ",$1";" > headerfile next } /[ \t]float|[ \t]double/ { print "processing float" type[nfields]="f" fields[nfields++]=$1 print "\tdouble ",$1";" > headerfile next } /char[ \t\(]|[ \t]byte/ { print "processing char" type[nfields]="s" for (i=0;i headerfile } else { print "\tsqlblob ",$1";" >headerfile; } next } /,/ { print "processing ," for (i=1;iheaderfile next } } } /./ { print "processing ." for (i=1;iheaderfile next } } } /;/ { print "processing ; nfields=",nfields if (nfields!=1) { firstcomma=0 for (i=(nfields-1);i;i--) { if (firstcomma) { comma[i]="," } else { comma[i]="" } if (type[i]!="s") firstcomma=1 } print "\t"table"();" >headerfile print "\t"table"(const "table" &a);" >headerfile print "\t"table"(const SQL_ROW &a);" >headerfile print "\t"table"(const std::string &s,const char *tag=\""table"\");" >headerfile print "\t"table" &operator =(const "table" &a);" >headerfile print "\tstd::string update_format() const;" >headerfile print "\tstd::string insert_format() const;" >headerfile print "\tstd::string select_format() const;" >headerfile print "\tstd::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const;" >headerfile print "\tstd::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag=\""table"\") const;" >headerfile print "\tvoid parse(const SQL_ROW &s);" >headerfile print "\tvoid parse(const std::string &s);" >headerfile print "\tvoid parse_xml(const std::string &s,const char *tag=\""table"\");" >headerfile print "#ifdef NEBULA\n\tbool nebula_read(FILE *f);\n#endif" >headerfile print " private:\n};\n\n" >headerfile if (is_typedef) { print "template <> const char * const db_type<"table">::type_name=\""table"\";" >sourcefile print "template <> const char * db_type<"table">::_search_tag=type_name;" >sourcefile print "template <> const int db_type<"table">::_nfields="nfields-1";" >sourcefile printf("template <> const char * const db_type<%s>::column_names[%d]={",table,nfields-1) >sourcefile } else { print "template <> const char * const db_table<"table">::table_name=\""table"\";" >sourcefile print "template <> const char * db_table<"table">::_search_tag=table_name;" >sourcefile print "template <> const int db_table<"table">::_nfields="nfields-1";" >sourcefile printf("template <> const char * const db_table<%s>::column_names[%d]={",table,nfields-1) >sourcefile } for (i=1;isourcefile print "};\n" >sourcefile print table"::"table"() : " >sourcefile if (is_typedef) { print "\tdb_type<"table">(*this)," > sourcefile } else { print "\tdb_table<"table">(*this,-1)," > sourcefile } for (i=1;isourcefile } else if ((type[i]=="r")||(type[i]=="t")) { printf("\t%s()%s\n",fields[i],comma[i]) >sourcefile } else if (type[i]=="b") { printf("\t%s((unsigned char *)0,%d,_x_csv)%s\n",fields[i],arrlen[i],comma[i]) >sourcefile } else if (index(type[i],"v")==1) { n=split(type[i],a," ") stype=a[n] n=split(stype,a,"(") stype=a[n] sis_deftype=0 for (n=1;nsourcefile } else { printf("\t%s((%s *)0,%d,_x_xml_values)%s\n",fields[i],stype,arrlen[i],comma[i]) >sourcefile } } } print "{\n\tdb_open();" >sourcefile for (i=1;isourcefile } print "}\n\n" >sourcefile print table"::"table"(const "table" &a) : " >sourcefile if (is_typedef) { print "\tdb_type<"table">(*this)," > sourcefile } else { print "\tdb_table<"table">(*this,-1)," > sourcefile } for (i=1;isourcefile } print "{\n\tdb_open();" >sourcefile for (i=1;isourcefile } print "}\n\n" >sourcefile print table"::"table"(const SQL_ROW &a) : " >sourcefile if (is_typedef) { print "\tdb_type<"table">(*this)" > sourcefile } else { print "\tdb_table<"table">(*this,-1)" > sourcefile } print "{\n\tdb_open();" >sourcefile print "\tparse(a);\n}\n\n" >sourcefile print table"::"table"(const std::string &s,const char *tag) : " >sourcefile #for (i=1;isourcefile # } else if ((type[i]=="r")||(type[i]=="t")) { # printf("\t%s(),\n",fields[i]) >sourcefile # } #} if (is_typedef) { print "\tdb_type<"table">(*this)" > sourcefile } else { print "\tdb_table<"table">(*this,-1)" > sourcefile } print "{\n\tdb_open();" >sourcefile print "\tif (xml_match_tag(s,tag)) {" >sourcefile print "\t parse_xml(s,tag);" >sourcefile print "\t} else {\n\t parse(s);\n\t}\n}\n\n" >sourcefile print table" &"table"::operator =(const "table" &a) {" >sourcefile print "\tif (&a != this) {" >sourcefile for (i=1;isourcefile } else { if (index(type[i],"v") == 1) { n=split(type[i],a," ") stype=a[n] n=split(stype,a,"(") stype=a[n] print "\t\t{" >sourcefile print "\t\t "fields[i]".clear();" > sourcefile print "\t\t std::vector<"stype">::const_iterator i(a."fields[i]".begin());" > sourcefile print "\t\t for (;i!=a."fields[i]".end();i++) {" >sourcefile print "\t\t "fields[i]".push_back(*i); " >sourcefile print "\t\t }\n\t\t}" >sourcefile } } } for (i=1;isourcefile } print "\t}\n\treturn (*this);\n}\n\n" >sourcefile print "std::string "table"::update_format() const" >sourcefile if (is_typedef) { print "{\tstd::ostringstream rv(\"\");\n" >sourcefile print "\trv << \"ROW(\";" >sourcefile i=1 } else { print "{\tstd::ostringstream rv(\"\");\n" >sourcefile i=2 } print "\tfor (int i="i";i<"nfields-1";i++) rv << \"?,\";" >sourcefile print "\trv << \"?\";" >sourcefile if (is_typedef) { print "rv << \")\";\n" >sourcefile } print "\treturn rv.str();\n}\n\n" >sourcefile print "std::string "table"::insert_format() const" >sourcefile if (is_typedef) { print "{\treturn update_format();\n}\n" >sourcefile } else { print "{\treturn std::string(\"?,\")+update_format();\n}\n" >sourcefile } print "std::string "table"::select_format() const" >sourcefile print "{\nstd::string rv(\"\");" >sourcefile print "for (int i=0; i<"nfields-2";i++) rv+=\"?,\";" >sourcefile print "rv+=\"?\";\nreturn rv;\n}\n" >sourcefile print "std::string "table"::print(int full_subtables, int show_ids, int no_refs) const" >sourcefile print "{\tstd::ostringstream rv(\"\");\n" >sourcefile print "\trv.precision(14);" >sourcefile if (is_typedef) { print "\trv << \"ROW(\";" >> sourcefile } for (i=1;isourcefile print "\t if (full_subtables) {" > sourcefile print "\t rv << "fields[i]".print(full_subtables,show_ids,no_refs);" > sourcefile print "\t} else {" > sourcefile print "\t rv << "fields[i]".id;" > sourcefile print "\t }\n\t}" > sourcefile } else if (type[i] == "t") { print "\trv << "fields[i]".print(full_subtables,show_ids,no_refs);" > sourcefile } else if (index(type[i],"v")==1) { n=split(type[i],a," ") stype=a[n] n=split(stype,a,"(") stype=a[n] print "\trv << \"LIST {\";" > sourcefile print "\t{\n\tstd::vector<"stype">::const_iterator p="fields[i]".begin();" > sourcefile print "\tfor (;p<"fields[i]".end();p++) {" > sourcefile sis_deftype=0 for (n=1;n sourcefile } else { print "\t rv << p->print();" >sourcefile } print "\t if (p != "fields[i]".end()-1) {" >sourcefile print "\t rv << ',';" >sourcefile print "\t } else {" >sourcefile print "\t rv << \"}\";" >sourcefile print "\t }" >sourcefile print "\t}\n\t}" >sourcefile } else if ((type[i]=="s")) { print "\trv << \"'\" << "fields[i]" << \"'\";" >sourcefile } else if ((type[i]=="b")) { if (dbtype == "ifx") { print "\trv << \"\" << "fields[i]".print_hex() ;" >sourcefile } else { print "\trv << \"\" << "fields[i]".print_raw() ;" >sourcefile } } else { printf("\t") > sourcefile if ((i==1) && (!is_typedef)) { printf("if (show_ids) ") > sourcefile } print "rv << "fields[i]";" > sourcefile } if (i!=(nfields-1)) print "\trv << ',';" >sourcefile } if (is_typedef) { print "\trv << \")\";" > sourcefile } print "\treturn rv.str();\n}\n\n" >sourcefile print "std::string "table"::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const " >sourcefile print "{\n\tstd::ostringstream rv(\"\");\n" >sourcefile print "\trv.precision(14);" >sourcefile print "\trv << xml_indent() << '<' << tag << \">\\n\";" >sourcefile print "\txml_indent(2);" >sourcefile for (i=1;isourcefile print "\t if (full_subtables) {" > sourcefile print "\t rv << "fields[i]".print_xml(full_subtables,show_ids,no_refs,\""fields[i]"\");" > sourcefile print "\t} else {" > sourcefile print "\t rv << xml_indent() << \"<"fields[i]">\" << "fields[i]".id << \"\\n\";" > sourcefile print "\t }\n\t}" > sourcefile } else if (type[i] == "t") { print "\trv << "fields[i]".print_xml(full_subtables,show_ids,no_refs,\""fields[i]"\");" > sourcefile } else if (index(type[i],"v")==1) { n=split(type[i],a," ") stype=a[n] n=split(stype,a,"(") stype=a[n] sis_deftype=0 for (n=1;nsourcefile print "\t rv << xml_indent() << \"<"fields[i]"\";" >sourcefile print "\t {\n\t std::string enc_string="fields[i]".print_xml();" >sourcefile if (!sis_deftype) { print "\t rv << \" length=\" << enc_string.size() << \" encoding=\\\"\" << xml_encoding_names["fields[i]".encoding] << \"\\\">\" ;" >sourcefile } else { print "\t rv << \">\\n\" ;" >sourcefile } print "\t rv << enc_string;" >sourcefile print "\t }\n}" >sourcefile if (sis_deftype) print "\trv << xml_indent(-2);" > sourcefile print "\trv << \"\\n\"; " >sourcefile } else if (type[i]=="s") { print "\t{\n\t std::string enc_field=xml_encode_string("fields[i]",std::min(strlen("fields[i]"),sizeof("fields[i]")));" > sourcefile print "\t rv << xml_indent() << \"<"fields[i]">\";" > sourcefile print "\t rv << enc_field << \"\\n\";" >sourcefile print "\t}" >> sourcefile } else if (type[i]=="b") { print "\tif ("fields[i]".size()) {\n\t std::string enc_field=xml_encode_string("fields[i]","fields[i]".encoding);" > sourcefile print "\t rv << xml_indent() << \"<"fields[i]" length=\" << enc_field.size() << \" encoding=\\\"\" << xml_encoding_names["fields[i]".encoding] << \"\\\">\"; "> sourcefile print "\t rv << enc_field << \"\\n\";" >sourcefile print "\t}" >> sourcefile } else { printf("\t") > sourcefile if ((i==1) && (!is_typedef)) { printf("if (show_ids) ") > sourcefile } print "rv << xml_indent() << \"<"fields[i]">\" << "fields[i]" << \"\\n\";" > sourcefile } } print "\txml_indent(-2);" >sourcefile print "\trv << xml_indent() << \"\\n\";" >sourcefile print "\treturn rv.str();\n}\n\n" >sourcefile print "\tvoid "table"::parse_xml(const std::string &s,const char *tag) {" >sourcefile print "\t std::string field,sub;" > sourcefile print "\t if (extract_xml_record(s,tag,field)) {" >sourcefile print "\t std::string::size_type pos=0;" >sourcefile for (i=1;i sourcefile print "\t "fields[i]".parse_xml(sub,\""fields[i]"\");" >sourcefile print "\t }" > sourcefile } else if (index(type[i],"v")==1) { n=split(type[i],a," ") stype=a[n] n=split(stype,a,"(") stype=a[n] sis_deftype=0 for (n=1;nsourcefile print "\t if (extract_xml_record(field,\""fields[i]"\",sub)) {" >sourcefile if (sis_deftype) { print "\t pos=0;" >sourcefile print "\t while ((pos=sub.find(\"<"stype"\",pos)) != std::string::npos) { " >sourcefile print "\t "fields[i]".push_back("stype"(std::string(sub.c_str()+pos))); " >sourcefile print "\t pos=sub.find(\"sourcefile print "\t pos=sub.find(\">\",pos);" >sourcefile print "\t }" > sourcefile } else { print "\t pos=sub.find(\">\");" >sourcefile print "\t do {" > sourcefile print "\t if (pos!=std::string::npos) {" >sourcefile print "\t do { pos++; } while ((sub[pos]=='\\n') || (sub[pos]==','));" >sourcefile print "\t std::istringstream in(std::string(sub.c_str()+pos)); " >sourcefile print "\t "stype" tmp;" >sourcefile print "\t in >> tmp;" >sourcefile print "\t "fields[i]".push_back(tmp);" >sourcefile print "\t }" >sourcefile print "\t } while ((pos=sub.find(\",\",pos)) != std::string::npos); " >sourcefile } print "\t }" > sourcefile } else { print "\t if (extract_xml_record(field,\""fields[i]"\",sub)) {" > sourcefile if ((type[i] != "s") && (type[i] != "b")) { print "\t pos=sub.find(\">\");" >sourcefile print "\t do { pos++; } while(sub[pos]=='\\n');" >sourcefile print "\t std::istringstream in(sub.c_str()+pos);" >sourcefile print "\t in >> "fields[i]";" > sourcefile } else if (type[i] == "b") { print "\t std::istringstream in(sub.c_str());" >sourcefile print "\t in >> "fields[i]";" >sourcefile } else { print "\t pos=sub.find(\">\");" >sourcefile print "\t do { pos++; } while(sub[pos]=='\\n');" >sourcefile print "\t std::string::size_type epos=sub.find(\"<\",pos);" >sourcefile print "\t if (epos==std::string::npos) epos=sub.find('\\n',pos);" > sourcefile print "\t if (epos==std::string::npos) epos=pos+strlen(sub.c_str()+pos);" > sourcefile print "\t std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos));" >sourcefile print "\t strncpy("fields[i]",(const char *)&(in.front()),std::min(in.size(),(size_t)"arrlen[i]"));" >sourcefile print "\t "fields[i]"[std::min(in.size(),(size_t)"arrlen[i]-1")]=0;" > sourcefile } print "\t }" >sourcefile } } print "\t }" >sourcefile print "\t }\n" >sourcefile print "\tvoid "table"::parse(const SQL_ROW &s) {" >sourcefile for (i=1;isourcefile if (type[i]=="r" || type[i]=="t") { print "\t "fields[i]".parse(SQL_ROW(s["i-1"],0));" >sourcefile } else if (index(type[i],"v")==1) { n=split(type[i],a," ") stype=a[n] n=split(stype,a,"(") stype=a[n] sis_deftype=0 for (n=1;nsourcefile print "\t int i;" >sourcefile print "\t "fields[i]".clear();" >sourcefile print "\t SQL_ROW tmp(s["i-1"]); ">sourcefile if (sis_deftype) { print "\t for (i=0;isourcefile print "\t "fields[i]".push_back("stype"(SQL_ROW(tmp[i])));" >sourcefile } else { print "\t for (i=0;isourcefile print "\t std::istringstream in(*(tmp[i]));" >sourcefile print "\t "stype" tmp0;" >sourcefile print "\t in >> tmp0;" >sourcefile print "\t "fields[i]".push_back(tmp0);" >sourcefile } print "\t }" >sourcefile } else { if ((type[i] != "s") && (type[i] != "b")) { print "\t std::istringstream row(*(s["i-1"]));" >sourcefile print "\t row >> "fields[i]";" > sourcefile } else if (type[i] == "b") { print "\t "fields[i]"=sqlblob(*(s["i-1"]));" >sourcefile } else { print "\t strncpy("fields[i]",s["i-1"]->c_str(),"arrlen[i]");">sourcefile print "\t "fields[i]"["arrlen[i]-1"]=0;" > sourcefile } } print "\t }" >sourcefile } print "\t }\n" >sourcefile print "\tvoid "table"::parse(const std::string &s) {" >sourcefile print "\t SQL_ROW row(&s,"nfields-1");" >sourcefile print "\t parse(row);" >sourcefile print "\t }\n" >sourcefile nfields=1 } } END { print "processing END" print "#endif"> headerfile } boinc-app-seti_8.00~svn3701.orig/db/schema_master.cpp0000644000175000017500000147416413041730641022436 0ustar locutuslocutus// This file is automatically generated. Do not edit #include "sah_config.h" #include #include #include #include #include #include #include #include "parse.h" #include "xml_util.h" #include "db_table.h" #include "schema_master.h" #ifdef _WIN32 #pragma warning( disable : 4355 ) #endif #define found(x) ((x != std::string::npos)) #ifdef USE_NAMESPACE using namespace ifx; #endif const char *db_name="sah2b@sah_master_tcp"; int db_is_open; template <> const char * const db_type::type_name="coordinate_t"; template <> const char * db_type::_search_tag=type_name; template <> const int db_type::_nfields=3; template <> const char * const db_type::column_names[3]={"time","ra","dec"}; coordinate_t::coordinate_t() : db_type(*this), time(0), ra(0), dec(0) { db_open(); } coordinate_t::coordinate_t(const coordinate_t &a) : db_type(*this), time(a.time), ra(a.ra), dec(a.dec) { db_open(); } coordinate_t::coordinate_t(const SQL_ROW &a) : db_type(*this) { db_open(); parse(a); } coordinate_t::coordinate_t(const std::string &s,const char *tag) : db_type(*this) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } coordinate_t &coordinate_t::operator =(const coordinate_t &a) { if (&a != this) { time=a.time; ra=a.ra; dec=a.dec; } return (*this); } std::string coordinate_t::update_format() const { std::ostringstream rv(""); rv << "ROW("; for (int i=1;i<3;i++) rv << "?,"; rv << "?"; rv << ")"; return rv.str(); } std::string coordinate_t::insert_format() const { return update_format(); } std::string coordinate_t::select_format() const { std::string rv(""); for (int i=0; i<2;i++) rv+="?,"; rv+="?"; return rv; } std::string coordinate_t::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); rv << "ROW("; rv << time; rv << ','; rv << ra; rv << ','; rv << dec; rv << ")"; return rv.str(); } std::string coordinate_t::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); rv << xml_indent() << "\n"; rv << xml_indent() << "" << ra << "\n"; rv << xml_indent() << "" << dec << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void coordinate_t::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"time",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> time; } if (extract_xml_record(field,"ra",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> ra; } if (extract_xml_record(field,"dec",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> dec; } } } void coordinate_t::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> time; } { std::istringstream row(*(s[1])); row >> ra; } { std::istringstream row(*(s[2])); row >> dec; } } void coordinate_t::parse(const std::string &s) { SQL_ROW row(&s,3); parse(row); } template <> const char * const db_type::type_name="chirp_parameter_t"; template <> const char * db_type::_search_tag=type_name; template <> const int db_type::_nfields=2; template <> const char * const db_type::column_names[2]={"chirp_limit","fft_len_flags"}; chirp_parameter_t::chirp_parameter_t() : db_type(*this), chirp_limit(0), fft_len_flags(0) { db_open(); } chirp_parameter_t::chirp_parameter_t(const chirp_parameter_t &a) : db_type(*this), chirp_limit(a.chirp_limit), fft_len_flags(a.fft_len_flags) { db_open(); } chirp_parameter_t::chirp_parameter_t(const SQL_ROW &a) : db_type(*this) { db_open(); parse(a); } chirp_parameter_t::chirp_parameter_t(const std::string &s,const char *tag) : db_type(*this) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } chirp_parameter_t &chirp_parameter_t::operator =(const chirp_parameter_t &a) { if (&a != this) { chirp_limit=a.chirp_limit; fft_len_flags=a.fft_len_flags; } return (*this); } std::string chirp_parameter_t::update_format() const { std::ostringstream rv(""); rv << "ROW("; for (int i=1;i<2;i++) rv << "?,"; rv << "?"; rv << ")"; return rv.str(); } std::string chirp_parameter_t::insert_format() const { return update_format(); } std::string chirp_parameter_t::select_format() const { std::string rv(""); for (int i=0; i<1;i++) rv+="?,"; rv+="?"; return rv; } std::string chirp_parameter_t::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); rv << "ROW("; rv << chirp_limit; rv << ','; rv << fft_len_flags; rv << ")"; return rv.str(); } std::string chirp_parameter_t::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); rv << xml_indent() << "" << chirp_limit << "\n"; rv << xml_indent() << "" << fft_len_flags << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void chirp_parameter_t::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"chirp_limit",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> chirp_limit; } if (extract_xml_record(field,"fft_len_flags",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> fft_len_flags; } } } void chirp_parameter_t::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> chirp_limit; } { std::istringstream row(*(s[1])); row >> fft_len_flags; } } void chirp_parameter_t::parse(const std::string &s) { SQL_ROW row(&s,2); parse(row); } template <> const char * const db_type::type_name="subband_description_t"; template <> const char * db_type::_search_tag=type_name; template <> const int db_type::_nfields=4; template <> const char * const db_type::column_names[4]={"number","center","base","sample_rate"}; subband_description_t::subband_description_t() : db_type(*this), number(0), center(0), base(0), sample_rate(0) { db_open(); } subband_description_t::subband_description_t(const subband_description_t &a) : db_type(*this), number(a.number), center(a.center), base(a.base), sample_rate(a.sample_rate) { db_open(); } subband_description_t::subband_description_t(const SQL_ROW &a) : db_type(*this) { db_open(); parse(a); } subband_description_t::subband_description_t(const std::string &s,const char *tag) : db_type(*this) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } subband_description_t &subband_description_t::operator =(const subband_description_t &a) { if (&a != this) { number=a.number; center=a.center; base=a.base; sample_rate=a.sample_rate; } return (*this); } std::string subband_description_t::update_format() const { std::ostringstream rv(""); rv << "ROW("; for (int i=1;i<4;i++) rv << "?,"; rv << "?"; rv << ")"; return rv.str(); } std::string subband_description_t::insert_format() const { return update_format(); } std::string subband_description_t::select_format() const { std::string rv(""); for (int i=0; i<3;i++) rv+="?,"; rv+="?"; return rv; } std::string subband_description_t::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); rv << "ROW("; rv << number; rv << ','; rv << center; rv << ','; rv << base; rv << ','; rv << sample_rate; rv << ")"; return rv.str(); } std::string subband_description_t::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); rv << xml_indent() << "" << number << "\n"; rv << xml_indent() << "
" << center << "
\n"; rv << xml_indent() << "" << base << "\n"; rv << xml_indent() << "" << sample_rate << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void subband_description_t::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"number",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> number; } if (extract_xml_record(field,"center",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> center; } if (extract_xml_record(field,"base",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> base; } if (extract_xml_record(field,"sample_rate",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> sample_rate; } } } void subband_description_t::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> number; } { std::istringstream row(*(s[1])); row >> center; } { std::istringstream row(*(s[2])); row >> base; } { std::istringstream row(*(s[3])); row >> sample_rate; } } void subband_description_t::parse(const std::string &s) { SQL_ROW row(&s,4); parse(row); } template <> const char * const db_type::type_name="data_description_t"; template <> const char * db_type::_search_tag=type_name; template <> const int db_type::_nfields=9; template <> const char * const db_type::column_names[9]={"start_ra","start_dec","end_ra","end_dec","true_angle_range","time_recorded","time_recorded_jd","nsamples","coords"}; data_description_t::data_description_t() : db_type(*this), start_ra(0), start_dec(0), end_ra(0), end_dec(0), true_angle_range(0), time_recorded_jd(0), nsamples(0), coords((coordinate_t *)0,0,_x_xml_values) { db_open(); time_recorded[0]=0; } data_description_t::data_description_t(const data_description_t &a) : db_type(*this), start_ra(a.start_ra), start_dec(a.start_dec), end_ra(a.end_ra), end_dec(a.end_dec), true_angle_range(a.true_angle_range), time_recorded_jd(a.time_recorded_jd), nsamples(a.nsamples), coords(a.coords) { db_open(); strcpy(time_recorded,a.time_recorded); } data_description_t::data_description_t(const SQL_ROW &a) : db_type(*this) { db_open(); parse(a); } data_description_t::data_description_t(const std::string &s,const char *tag) : db_type(*this) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } data_description_t &data_description_t::operator =(const data_description_t &a) { if (&a != this) { start_ra=a.start_ra; start_dec=a.start_dec; end_ra=a.end_ra; end_dec=a.end_dec; true_angle_range=a.true_angle_range; time_recorded_jd=a.time_recorded_jd; nsamples=a.nsamples; { coords.clear(); std::vector::const_iterator i(a.coords.begin()); for (;i!=a.coords.end();i++) { coords.push_back(*i); } } strcpy(time_recorded,a.time_recorded); } return (*this); } std::string data_description_t::update_format() const { std::ostringstream rv(""); rv << "ROW("; for (int i=1;i<9;i++) rv << "?,"; rv << "?"; rv << ")"; return rv.str(); } std::string data_description_t::insert_format() const { return update_format(); } std::string data_description_t::select_format() const { std::string rv(""); for (int i=0; i<8;i++) rv+="?,"; rv+="?"; return rv; } std::string data_description_t::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); rv << "ROW("; rv << start_ra; rv << ','; rv << start_dec; rv << ','; rv << end_ra; rv << ','; rv << end_dec; rv << ','; rv << true_angle_range; rv << ','; rv << "'" << time_recorded << "'"; rv << ','; rv << time_recorded_jd; rv << ','; rv << nsamples; rv << ','; rv << "LIST {"; { std::vector::const_iterator p=coords.begin(); for (;pprint(); if (p != coords.end()-1) { rv << ','; } else { rv << "}"; } } } rv << ")"; return rv.str(); } std::string data_description_t::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); rv << xml_indent() << "" << start_ra << "\n"; rv << xml_indent() << "" << start_dec << "\n"; rv << xml_indent() << "" << end_ra << "\n"; rv << xml_indent() << "" << end_dec << "\n"; rv << xml_indent() << "" << true_angle_range << "\n"; { std::string enc_field=xml_encode_string(time_recorded,std::min(strlen(time_recorded),sizeof(time_recorded))); rv << xml_indent() << ""; rv << enc_field << "\n"; } rv << xml_indent() << "" << time_recorded_jd << "\n"; rv << xml_indent() << "" << nsamples << "\n"; if (coords.size()) { rv << xml_indent() << "\n" ; rv << enc_string; } } rv << xml_indent(-2); rv << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void data_description_t::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"start_ra",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> start_ra; } if (extract_xml_record(field,"start_dec",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> start_dec; } if (extract_xml_record(field,"end_ra",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> end_ra; } if (extract_xml_record(field,"end_dec",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> end_dec; } if (extract_xml_record(field,"true_angle_range",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> true_angle_range; } if (extract_xml_record(field,"time_recorded",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::string::size_type epos=sub.find("<",pos); if (epos==std::string::npos) epos=sub.find('\n',pos); if (epos==std::string::npos) epos=pos+strlen(sub.c_str()+pos); std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); strncpy(time_recorded,(const char *)&(in.front()),std::min(in.size(),(size_t)255)); time_recorded[std::min(in.size(),(size_t)254)]=0; } if (extract_xml_record(field,"time_recorded_jd",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> time_recorded_jd; } if (extract_xml_record(field,"nsamples",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> nsamples; } coords.clear(); if (extract_xml_record(field,"coords",sub)) { pos=0; while ((pos=sub.find("",pos); } } } } void data_description_t::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> start_ra; } { std::istringstream row(*(s[1])); row >> start_dec; } { std::istringstream row(*(s[2])); row >> end_ra; } { std::istringstream row(*(s[3])); row >> end_dec; } { std::istringstream row(*(s[4])); row >> true_angle_range; } { strncpy(time_recorded,s[5]->c_str(),255); time_recorded[254]=0; } { std::istringstream row(*(s[6])); row >> time_recorded_jd; } { std::istringstream row(*(s[7])); row >> nsamples; } { std::string::size_type p,q; int i; coords.clear(); SQL_ROW tmp(s[8]); for (i=0;i const char * const db_table::table_name="receiver_config"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=20; template <> const char * const db_table::column_names[20]={"id","s4_id","name","beam_width","center_freq","latitude","longitude","elevation","glat","glon","galt","diameter","az_orientation","az_corr_coeff","zen_corr_coeff","array_az_ellipse","array_za_ellipse","array_angle","min_vgc""polarization"}; receiver_config::receiver_config() : db_table(*this,-1), id(0), s4_id(0), beam_width(0), center_freq(0), latitude(0), longitude(0), elevation(0), glat(0), glon(0), galt(0), diameter(0), az_orientation(0), az_corr_coeff((float *)0,0,_x_csv), zen_corr_coeff((float *)0,0,_x_csv), array_az_ellipse(0), array_za_ellipse(0), array_angle(0), min_vgc(0) { db_open(); name[0]=0; polarization[0]=0; } receiver_config::receiver_config(const receiver_config &a) : db_table(*this,-1), id(a.id), s4_id(a.s4_id), beam_width(a.beam_width), center_freq(a.center_freq), latitude(a.latitude), longitude(a.longitude), elevation(a.elevation), glat(a.glat), glon(a.glon), galt(a.galt), diameter(a.diameter), az_orientation(a.az_orientation), az_corr_coeff(a.az_corr_coeff), zen_corr_coeff(a.zen_corr_coeff), array_az_ellipse(a.array_az_ellipse), array_za_ellipse(a.array_za_ellipse), array_angle(a.array_angle), min_vgc(a.min_vgc) { db_open(); strcpy(name,a.name); strcpy(polarization,a.polarization); } receiver_config::receiver_config(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } receiver_config::receiver_config(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } receiver_config &receiver_config::operator =(const receiver_config &a) { if (&a != this) { id=a.id; s4_id=a.s4_id; beam_width=a.beam_width; center_freq=a.center_freq; latitude=a.latitude; longitude=a.longitude; elevation=a.elevation; glat=a.glat; glon=a.glon; galt=a.galt; diameter=a.diameter; az_orientation=a.az_orientation; { az_corr_coeff.clear(); std::vector::const_iterator i(a.az_corr_coeff.begin()); for (;i!=a.az_corr_coeff.end();i++) { az_corr_coeff.push_back(*i); } } { zen_corr_coeff.clear(); std::vector::const_iterator i(a.zen_corr_coeff.begin()); for (;i!=a.zen_corr_coeff.end();i++) { zen_corr_coeff.push_back(*i); } } array_az_ellipse=a.array_az_ellipse; array_za_ellipse=a.array_za_ellipse; array_angle=a.array_angle; min_vgc=a.min_vgc; strcpy(name,a.name); strcpy(polarization,a.polarization); } return (*this); } std::string receiver_config::update_format() const { std::ostringstream rv(""); for (int i=2;i<20;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string receiver_config::insert_format() const { return std::string("?,")+update_format(); } std::string receiver_config::select_format() const { std::string rv(""); for (int i=0; i<19;i++) rv+="?,"; rv+="?"; return rv; } std::string receiver_config::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; rv << s4_id; rv << ','; rv << "'" << name << "'"; rv << ','; rv << beam_width; rv << ','; rv << center_freq; rv << ','; rv << latitude; rv << ','; rv << longitude; rv << ','; rv << elevation; rv << ','; rv << glat; rv << ','; rv << glon; rv << ','; rv << galt; rv << ','; rv << diameter; rv << ','; rv << az_orientation; rv << ','; rv << "LIST {"; { std::vector::const_iterator p=az_corr_coeff.begin(); for (;p::const_iterator p=zen_corr_coeff.begin(); for (;p\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; rv << xml_indent() << "" << s4_id << "\n"; { std::string enc_field=xml_encode_string(name,std::min(strlen(name),sizeof(name))); rv << xml_indent() << ""; rv << enc_field << "\n"; } rv << xml_indent() << "" << beam_width << "\n"; rv << xml_indent() << "" << center_freq << "\n"; rv << xml_indent() << "" << latitude << "\n"; rv << xml_indent() << "" << longitude << "\n"; rv << xml_indent() << "" << elevation << "\n"; rv << xml_indent() << "" << glat << "\n"; rv << xml_indent() << "" << glon << "\n"; rv << xml_indent() << "" << galt << "\n"; rv << xml_indent() << "" << diameter << "\n"; rv << xml_indent() << "" << az_orientation << "\n"; if (az_corr_coeff.size()) { rv << xml_indent() << "" ; rv << enc_string; } } rv << "\n"; if (zen_corr_coeff.size()) { rv << xml_indent() << "" ; rv << enc_string; } } rv << "\n"; rv << xml_indent() << "" << array_az_ellipse << "\n"; rv << xml_indent() << "" << array_za_ellipse << "\n"; rv << xml_indent() << "" << array_angle << "\n"; rv << xml_indent() << "" << min_vgc << "\n"; { std::string enc_field=xml_encode_string(polarization,std::min(strlen(polarization),sizeof(polarization))); rv << xml_indent() << ""; rv << enc_field << "\n"; } xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void receiver_config::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"s4_id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> s4_id; } if (extract_xml_record(field,"name",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::string::size_type epos=sub.find("<",pos); if (epos==std::string::npos) epos=sub.find('\n',pos); if (epos==std::string::npos) epos=pos+strlen(sub.c_str()+pos); std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); strncpy(name,(const char *)&(in.front()),std::min(in.size(),(size_t)255)); name[std::min(in.size(),(size_t)254)]=0; } if (extract_xml_record(field,"beam_width",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> beam_width; } if (extract_xml_record(field,"center_freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> center_freq; } if (extract_xml_record(field,"latitude",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> latitude; } if (extract_xml_record(field,"longitude",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> longitude; } if (extract_xml_record(field,"elevation",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> elevation; } if (extract_xml_record(field,"glat",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> glat; } if (extract_xml_record(field,"glon",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> glon; } if (extract_xml_record(field,"galt",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> galt; } if (extract_xml_record(field,"diameter",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> diameter; } if (extract_xml_record(field,"az_orientation",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> az_orientation; } az_corr_coeff.clear(); if (extract_xml_record(field,"az_corr_coeff",sub)) { pos=sub.find(">"); do { if (pos!=std::string::npos) { do { pos++; } while ((sub[pos]=='\n') || (sub[pos]==',')); std::istringstream in(std::string(sub.c_str()+pos)); float tmp; in >> tmp; az_corr_coeff.push_back(tmp); } } while ((pos=sub.find(",",pos)) != std::string::npos); } zen_corr_coeff.clear(); if (extract_xml_record(field,"zen_corr_coeff",sub)) { pos=sub.find(">"); do { if (pos!=std::string::npos) { do { pos++; } while ((sub[pos]=='\n') || (sub[pos]==',')); std::istringstream in(std::string(sub.c_str()+pos)); float tmp; in >> tmp; zen_corr_coeff.push_back(tmp); } } while ((pos=sub.find(",",pos)) != std::string::npos); } if (extract_xml_record(field,"array_az_ellipse",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> array_az_ellipse; } if (extract_xml_record(field,"array_za_ellipse",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> array_za_ellipse; } if (extract_xml_record(field,"array_angle",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> array_angle; } if (extract_xml_record(field,"min_vgc",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> min_vgc; } if (extract_xml_record(field,"polarization",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::string::size_type epos=sub.find("<",pos); if (epos==std::string::npos) epos=sub.find('\n',pos); if (epos==std::string::npos) epos=pos+strlen(sub.c_str()+pos); std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); strncpy(polarization,(const char *)&(in.front()),std::min(in.size(),(size_t)32)); polarization[std::min(in.size(),(size_t)31)]=0; } } } void receiver_config::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { std::istringstream row(*(s[1])); row >> s4_id; } { strncpy(name,s[2]->c_str(),255); name[254]=0; } { std::istringstream row(*(s[3])); row >> beam_width; } { std::istringstream row(*(s[4])); row >> center_freq; } { std::istringstream row(*(s[5])); row >> latitude; } { std::istringstream row(*(s[6])); row >> longitude; } { std::istringstream row(*(s[7])); row >> elevation; } { std::istringstream row(*(s[8])); row >> glat; } { std::istringstream row(*(s[9])); row >> glon; } { std::istringstream row(*(s[10])); row >> galt; } { std::istringstream row(*(s[11])); row >> diameter; } { std::istringstream row(*(s[12])); row >> az_orientation; } { std::string::size_type p,q; int i; az_corr_coeff.clear(); SQL_ROW tmp(s[13]); for (i=0;i> tmp0; az_corr_coeff.push_back(tmp0); } } { std::string::size_type p,q; int i; zen_corr_coeff.clear(); SQL_ROW tmp(s[14]); for (i=0;i> tmp0; zen_corr_coeff.push_back(tmp0); } } { std::istringstream row(*(s[15])); row >> array_az_ellipse; } { std::istringstream row(*(s[16])); row >> array_za_ellipse; } { std::istringstream row(*(s[17])); row >> array_angle; } { std::istringstream row(*(s[18])); row >> min_vgc; } { strncpy(polarization,s[19]->c_str(),32); polarization[31]=0; } } void receiver_config::parse(const std::string &s) { SQL_ROW row(&s,20); parse(row); } template <> const char * const db_table::table_name="recorder_config"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=6; template <> const char * const db_table::column_names[6]={"id","name","bits_per_sample","sample_rate","beams","version"}; recorder_config::recorder_config() : db_table(*this,-1), id(0), bits_per_sample(0), sample_rate(0), beams(0), version(0) { db_open(); name[0]=0; } recorder_config::recorder_config(const recorder_config &a) : db_table(*this,-1), id(a.id), bits_per_sample(a.bits_per_sample), sample_rate(a.sample_rate), beams(a.beams), version(a.version) { db_open(); strcpy(name,a.name); } recorder_config::recorder_config(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } recorder_config::recorder_config(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } recorder_config &recorder_config::operator =(const recorder_config &a) { if (&a != this) { id=a.id; bits_per_sample=a.bits_per_sample; sample_rate=a.sample_rate; beams=a.beams; version=a.version; strcpy(name,a.name); } return (*this); } std::string recorder_config::update_format() const { std::ostringstream rv(""); for (int i=2;i<6;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string recorder_config::insert_format() const { return std::string("?,")+update_format(); } std::string recorder_config::select_format() const { std::string rv(""); for (int i=0; i<5;i++) rv+="?,"; rv+="?"; return rv; } std::string recorder_config::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; rv << "'" << name << "'"; rv << ','; rv << bits_per_sample; rv << ','; rv << sample_rate; rv << ','; rv << beams; rv << ','; rv << version; return rv.str(); } std::string recorder_config::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; { std::string enc_field=xml_encode_string(name,std::min(strlen(name),sizeof(name))); rv << xml_indent() << ""; rv << enc_field << "\n"; } rv << xml_indent() << "" << bits_per_sample << "\n"; rv << xml_indent() << "" << sample_rate << "\n"; rv << xml_indent() << "" << beams << "\n"; rv << xml_indent() << "" << version << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void recorder_config::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"name",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::string::size_type epos=sub.find("<",pos); if (epos==std::string::npos) epos=sub.find('\n',pos); if (epos==std::string::npos) epos=pos+strlen(sub.c_str()+pos); std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); strncpy(name,(const char *)&(in.front()),std::min(in.size(),(size_t)64)); name[std::min(in.size(),(size_t)63)]=0; } if (extract_xml_record(field,"bits_per_sample",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> bits_per_sample; } if (extract_xml_record(field,"sample_rate",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> sample_rate; } if (extract_xml_record(field,"beams",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> beams; } if (extract_xml_record(field,"version",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> version; } } } void recorder_config::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { strncpy(name,s[1]->c_str(),64); name[63]=0; } { std::istringstream row(*(s[2])); row >> bits_per_sample; } { std::istringstream row(*(s[3])); row >> sample_rate; } { std::istringstream row(*(s[4])); row >> beams; } { std::istringstream row(*(s[5])); row >> version; } } void recorder_config::parse(const std::string &s) { SQL_ROW row(&s,6); parse(row); } template <> const char * const db_table::table_name="splitter_config"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=13; template <> const char * const db_table::column_names[13]={"id","version","data_type","fft_len","ifft_len","filter","window","samples_per_wu","highpass","blanker_filter","pfb_ntaps","pfb_width_factor","wu_bits_per_sample"}; splitter_config::splitter_config() : db_table(*this,-1), id(0), version(0), fft_len(0), ifft_len(0), samples_per_wu(0), highpass(0), pfb_ntaps(0), pfb_width_factor(0), wu_bits_per_sample(0) { db_open(); data_type[0]=0; filter[0]=0; window[0]=0; blanker_filter[0]=0; } splitter_config::splitter_config(const splitter_config &a) : db_table(*this,-1), id(a.id), version(a.version), fft_len(a.fft_len), ifft_len(a.ifft_len), samples_per_wu(a.samples_per_wu), highpass(a.highpass), pfb_ntaps(a.pfb_ntaps), pfb_width_factor(a.pfb_width_factor), wu_bits_per_sample(a.wu_bits_per_sample) { db_open(); strcpy(data_type,a.data_type); strcpy(filter,a.filter); strcpy(window,a.window); strcpy(blanker_filter,a.blanker_filter); } splitter_config::splitter_config(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } splitter_config::splitter_config(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } splitter_config &splitter_config::operator =(const splitter_config &a) { if (&a != this) { id=a.id; version=a.version; fft_len=a.fft_len; ifft_len=a.ifft_len; samples_per_wu=a.samples_per_wu; highpass=a.highpass; pfb_ntaps=a.pfb_ntaps; pfb_width_factor=a.pfb_width_factor; wu_bits_per_sample=a.wu_bits_per_sample; strcpy(data_type,a.data_type); strcpy(filter,a.filter); strcpy(window,a.window); strcpy(blanker_filter,a.blanker_filter); } return (*this); } std::string splitter_config::update_format() const { std::ostringstream rv(""); for (int i=2;i<13;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string splitter_config::insert_format() const { return std::string("?,")+update_format(); } std::string splitter_config::select_format() const { std::string rv(""); for (int i=0; i<12;i++) rv+="?,"; rv+="?"; return rv; } std::string splitter_config::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; rv << version; rv << ','; rv << "'" << data_type << "'"; rv << ','; rv << fft_len; rv << ','; rv << ifft_len; rv << ','; rv << "'" << filter << "'"; rv << ','; rv << "'" << window << "'"; rv << ','; rv << samples_per_wu; rv << ','; rv << highpass; rv << ','; rv << "'" << blanker_filter << "'"; rv << ','; rv << pfb_ntaps; rv << ','; rv << pfb_width_factor; rv << ','; rv << wu_bits_per_sample; return rv.str(); } std::string splitter_config::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; rv << xml_indent() << "" << version << "\n"; { std::string enc_field=xml_encode_string(data_type,std::min(strlen(data_type),sizeof(data_type))); rv << xml_indent() << ""; rv << enc_field << "\n"; } rv << xml_indent() << "" << fft_len << "\n"; rv << xml_indent() << "" << ifft_len << "\n"; { std::string enc_field=xml_encode_string(filter,std::min(strlen(filter),sizeof(filter))); rv << xml_indent() << ""; rv << enc_field << "\n"; } { std::string enc_field=xml_encode_string(window,std::min(strlen(window),sizeof(window))); rv << xml_indent() << ""; rv << enc_field << "\n"; } rv << xml_indent() << "" << samples_per_wu << "\n"; rv << xml_indent() << "" << highpass << "\n"; { std::string enc_field=xml_encode_string(blanker_filter,std::min(strlen(blanker_filter),sizeof(blanker_filter))); rv << xml_indent() << ""; rv << enc_field << "\n"; } rv << xml_indent() << "" << pfb_ntaps << "\n"; rv << xml_indent() << "" << pfb_width_factor << "\n"; rv << xml_indent() << "" << wu_bits_per_sample << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void splitter_config::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"version",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> version; } if (extract_xml_record(field,"data_type",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::string::size_type epos=sub.find("<",pos); if (epos==std::string::npos) epos=sub.find('\n',pos); if (epos==std::string::npos) epos=pos+strlen(sub.c_str()+pos); std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); strncpy(data_type,(const char *)&(in.front()),std::min(in.size(),(size_t)64)); data_type[std::min(in.size(),(size_t)63)]=0; } if (extract_xml_record(field,"fft_len",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> fft_len; } if (extract_xml_record(field,"ifft_len",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> ifft_len; } if (extract_xml_record(field,"filter",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::string::size_type epos=sub.find("<",pos); if (epos==std::string::npos) epos=sub.find('\n',pos); if (epos==std::string::npos) epos=pos+strlen(sub.c_str()+pos); std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); strncpy(filter,(const char *)&(in.front()),std::min(in.size(),(size_t)64)); filter[std::min(in.size(),(size_t)63)]=0; } if (extract_xml_record(field,"window",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::string::size_type epos=sub.find("<",pos); if (epos==std::string::npos) epos=sub.find('\n',pos); if (epos==std::string::npos) epos=pos+strlen(sub.c_str()+pos); std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); strncpy(window,(const char *)&(in.front()),std::min(in.size(),(size_t)64)); window[std::min(in.size(),(size_t)63)]=0; } if (extract_xml_record(field,"samples_per_wu",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> samples_per_wu; } if (extract_xml_record(field,"highpass",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> highpass; } if (extract_xml_record(field,"blanker_filter",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::string::size_type epos=sub.find("<",pos); if (epos==std::string::npos) epos=sub.find('\n',pos); if (epos==std::string::npos) epos=pos+strlen(sub.c_str()+pos); std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); strncpy(blanker_filter,(const char *)&(in.front()),std::min(in.size(),(size_t)64)); blanker_filter[std::min(in.size(),(size_t)63)]=0; } if (extract_xml_record(field,"pfb_ntaps",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> pfb_ntaps; } if (extract_xml_record(field,"pfb_width_factor",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> pfb_width_factor; } if (extract_xml_record(field,"wu_bits_per_sample",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> wu_bits_per_sample; } } } void splitter_config::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { std::istringstream row(*(s[1])); row >> version; } { strncpy(data_type,s[2]->c_str(),64); data_type[63]=0; } { std::istringstream row(*(s[3])); row >> fft_len; } { std::istringstream row(*(s[4])); row >> ifft_len; } { strncpy(filter,s[5]->c_str(),64); filter[63]=0; } { strncpy(window,s[6]->c_str(),64); window[63]=0; } { std::istringstream row(*(s[7])); row >> samples_per_wu; } { std::istringstream row(*(s[8])); row >> highpass; } { strncpy(blanker_filter,s[9]->c_str(),64); blanker_filter[63]=0; } { std::istringstream row(*(s[10])); row >> pfb_ntaps; } { std::istringstream row(*(s[11])); row >> pfb_width_factor; } { std::istringstream row(*(s[12])); row >> wu_bits_per_sample; } } void splitter_config::parse(const std::string &s) { SQL_ROW row(&s,13); parse(row); } template <> const char * const db_table::table_name="analysis_config"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=39; template <> const char * const db_table::column_names[39]={"id","spike_thresh","spikes_per_spectrum","autocorr_thresh","autocorr_per_spectrum","autocorr_fftlen","gauss_null_chi_sq_thresh","gauss_chi_sq_thresh","gauss_power_thresh","gauss_peak_power_thresh","gauss_pot_length","pulse_thresh","pulse_display_thresh","pulse_max","pulse_min","pulse_fft_max","pulse_pot_length","triplet_thresh","triplet_max","triplet_min","triplet_pot_length","pot_overlap_factor","pot_t_offset","pot_min_slew","pot_max_slew","chirp_resolution","analysis_fft_lengths","bsmooth_boxcar_length","bsmooth_chunk_size","chirps","pulse_beams","max_signals","max_spikes","max_autocorr","max_gaussians","max_pulses","max_triplets","keyuniq","credit_rate"}; analysis_config::analysis_config() : db_table(*this,-1), id(0), spike_thresh(0), spikes_per_spectrum(0), autocorr_thresh(0), autocorr_per_spectrum(0), autocorr_fftlen(0), gauss_null_chi_sq_thresh(0), gauss_chi_sq_thresh(0), gauss_power_thresh(0), gauss_peak_power_thresh(0), gauss_pot_length(0), pulse_thresh(0), pulse_display_thresh(0), pulse_max(0), pulse_min(0), pulse_fft_max(0), pulse_pot_length(0), triplet_thresh(0), triplet_max(0), triplet_min(0), triplet_pot_length(0), pot_overlap_factor(0), pot_t_offset(0), pot_min_slew(0), pot_max_slew(0), chirp_resolution(0), analysis_fft_lengths(0), bsmooth_boxcar_length(0), bsmooth_chunk_size(0), chirps((chirp_parameter_t *)0,0,_x_xml_values), pulse_beams(0), max_signals(0), max_spikes(0), max_autocorr(0), max_gaussians(0), max_pulses(0), max_triplets(0), keyuniq(0), credit_rate(0) { db_open(); } analysis_config::analysis_config(const analysis_config &a) : db_table(*this,-1), id(a.id), spike_thresh(a.spike_thresh), spikes_per_spectrum(a.spikes_per_spectrum), autocorr_thresh(a.autocorr_thresh), autocorr_per_spectrum(a.autocorr_per_spectrum), autocorr_fftlen(a.autocorr_fftlen), gauss_null_chi_sq_thresh(a.gauss_null_chi_sq_thresh), gauss_chi_sq_thresh(a.gauss_chi_sq_thresh), gauss_power_thresh(a.gauss_power_thresh), gauss_peak_power_thresh(a.gauss_peak_power_thresh), gauss_pot_length(a.gauss_pot_length), pulse_thresh(a.pulse_thresh), pulse_display_thresh(a.pulse_display_thresh), pulse_max(a.pulse_max), pulse_min(a.pulse_min), pulse_fft_max(a.pulse_fft_max), pulse_pot_length(a.pulse_pot_length), triplet_thresh(a.triplet_thresh), triplet_max(a.triplet_max), triplet_min(a.triplet_min), triplet_pot_length(a.triplet_pot_length), pot_overlap_factor(a.pot_overlap_factor), pot_t_offset(a.pot_t_offset), pot_min_slew(a.pot_min_slew), pot_max_slew(a.pot_max_slew), chirp_resolution(a.chirp_resolution), analysis_fft_lengths(a.analysis_fft_lengths), bsmooth_boxcar_length(a.bsmooth_boxcar_length), bsmooth_chunk_size(a.bsmooth_chunk_size), chirps(a.chirps), pulse_beams(a.pulse_beams), max_signals(a.max_signals), max_spikes(a.max_spikes), max_autocorr(a.max_autocorr), max_gaussians(a.max_gaussians), max_pulses(a.max_pulses), max_triplets(a.max_triplets), keyuniq(a.keyuniq), credit_rate(a.credit_rate) { db_open(); } analysis_config::analysis_config(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } analysis_config::analysis_config(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } analysis_config &analysis_config::operator =(const analysis_config &a) { if (&a != this) { id=a.id; spike_thresh=a.spike_thresh; spikes_per_spectrum=a.spikes_per_spectrum; autocorr_thresh=a.autocorr_thresh; autocorr_per_spectrum=a.autocorr_per_spectrum; autocorr_fftlen=a.autocorr_fftlen; gauss_null_chi_sq_thresh=a.gauss_null_chi_sq_thresh; gauss_chi_sq_thresh=a.gauss_chi_sq_thresh; gauss_power_thresh=a.gauss_power_thresh; gauss_peak_power_thresh=a.gauss_peak_power_thresh; gauss_pot_length=a.gauss_pot_length; pulse_thresh=a.pulse_thresh; pulse_display_thresh=a.pulse_display_thresh; pulse_max=a.pulse_max; pulse_min=a.pulse_min; pulse_fft_max=a.pulse_fft_max; pulse_pot_length=a.pulse_pot_length; triplet_thresh=a.triplet_thresh; triplet_max=a.triplet_max; triplet_min=a.triplet_min; triplet_pot_length=a.triplet_pot_length; pot_overlap_factor=a.pot_overlap_factor; pot_t_offset=a.pot_t_offset; pot_min_slew=a.pot_min_slew; pot_max_slew=a.pot_max_slew; chirp_resolution=a.chirp_resolution; analysis_fft_lengths=a.analysis_fft_lengths; bsmooth_boxcar_length=a.bsmooth_boxcar_length; bsmooth_chunk_size=a.bsmooth_chunk_size; { chirps.clear(); std::vector::const_iterator i(a.chirps.begin()); for (;i!=a.chirps.end();i++) { chirps.push_back(*i); } } pulse_beams=a.pulse_beams; max_signals=a.max_signals; max_spikes=a.max_spikes; max_autocorr=a.max_autocorr; max_gaussians=a.max_gaussians; max_pulses=a.max_pulses; max_triplets=a.max_triplets; keyuniq=a.keyuniq; credit_rate=a.credit_rate; } return (*this); } std::string analysis_config::update_format() const { std::ostringstream rv(""); for (int i=2;i<39;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string analysis_config::insert_format() const { return std::string("?,")+update_format(); } std::string analysis_config::select_format() const { std::string rv(""); for (int i=0; i<38;i++) rv+="?,"; rv+="?"; return rv; } std::string analysis_config::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; rv << spike_thresh; rv << ','; rv << spikes_per_spectrum; rv << ','; rv << autocorr_thresh; rv << ','; rv << autocorr_per_spectrum; rv << ','; rv << autocorr_fftlen; rv << ','; rv << gauss_null_chi_sq_thresh; rv << ','; rv << gauss_chi_sq_thresh; rv << ','; rv << gauss_power_thresh; rv << ','; rv << gauss_peak_power_thresh; rv << ','; rv << gauss_pot_length; rv << ','; rv << pulse_thresh; rv << ','; rv << pulse_display_thresh; rv << ','; rv << pulse_max; rv << ','; rv << pulse_min; rv << ','; rv << pulse_fft_max; rv << ','; rv << pulse_pot_length; rv << ','; rv << triplet_thresh; rv << ','; rv << triplet_max; rv << ','; rv << triplet_min; rv << ','; rv << triplet_pot_length; rv << ','; rv << pot_overlap_factor; rv << ','; rv << pot_t_offset; rv << ','; rv << pot_min_slew; rv << ','; rv << pot_max_slew; rv << ','; rv << chirp_resolution; rv << ','; rv << analysis_fft_lengths; rv << ','; rv << bsmooth_boxcar_length; rv << ','; rv << bsmooth_chunk_size; rv << ','; rv << "LIST {"; { std::vector::const_iterator p=chirps.begin(); for (;pprint(); if (p != chirps.end()-1) { rv << ','; } else { rv << "}"; } } } rv << ','; rv << pulse_beams; rv << ','; rv << max_signals; rv << ','; rv << max_spikes; rv << ','; rv << max_autocorr; rv << ','; rv << max_gaussians; rv << ','; rv << max_pulses; rv << ','; rv << max_triplets; rv << ','; rv << keyuniq; rv << ','; rv << credit_rate; return rv.str(); } std::string analysis_config::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; rv << xml_indent() << "" << spike_thresh << "\n"; rv << xml_indent() << "" << spikes_per_spectrum << "\n"; rv << xml_indent() << "" << autocorr_thresh << "\n"; rv << xml_indent() << "" << autocorr_per_spectrum << "\n"; rv << xml_indent() << "" << autocorr_fftlen << "\n"; rv << xml_indent() << "" << gauss_null_chi_sq_thresh << "\n"; rv << xml_indent() << "" << gauss_chi_sq_thresh << "\n"; rv << xml_indent() << "" << gauss_power_thresh << "\n"; rv << xml_indent() << "" << gauss_peak_power_thresh << "\n"; rv << xml_indent() << "" << gauss_pot_length << "\n"; rv << xml_indent() << "" << pulse_thresh << "\n"; rv << xml_indent() << "" << pulse_display_thresh << "\n"; rv << xml_indent() << "" << pulse_max << "\n"; rv << xml_indent() << "" << pulse_min << "\n"; rv << xml_indent() << "" << pulse_fft_max << "\n"; rv << xml_indent() << "" << pulse_pot_length << "\n"; rv << xml_indent() << "" << triplet_thresh << "\n"; rv << xml_indent() << "" << triplet_max << "\n"; rv << xml_indent() << "" << triplet_min << "\n"; rv << xml_indent() << "" << triplet_pot_length << "\n"; rv << xml_indent() << "" << pot_overlap_factor << "\n"; rv << xml_indent() << "" << pot_t_offset << "\n"; rv << xml_indent() << "" << pot_min_slew << "\n"; rv << xml_indent() << "" << pot_max_slew << "\n"; rv << xml_indent() << "" << chirp_resolution << "\n"; rv << xml_indent() << "" << analysis_fft_lengths << "\n"; rv << xml_indent() << "" << bsmooth_boxcar_length << "\n"; rv << xml_indent() << "" << bsmooth_chunk_size << "\n"; if (chirps.size()) { rv << xml_indent() << "\n" ; rv << enc_string; } } rv << xml_indent(-2); rv << "\n"; rv << xml_indent() << "" << pulse_beams << "\n"; rv << xml_indent() << "" << max_signals << "\n"; rv << xml_indent() << "" << max_spikes << "\n"; rv << xml_indent() << "" << max_autocorr << "\n"; rv << xml_indent() << "" << max_gaussians << "\n"; rv << xml_indent() << "" << max_pulses << "\n"; rv << xml_indent() << "" << max_triplets << "\n"; rv << xml_indent() << "" << keyuniq << "\n"; rv << xml_indent() << "" << credit_rate << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void analysis_config::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"spike_thresh",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> spike_thresh; } if (extract_xml_record(field,"spikes_per_spectrum",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> spikes_per_spectrum; } if (extract_xml_record(field,"autocorr_thresh",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> autocorr_thresh; } if (extract_xml_record(field,"autocorr_per_spectrum",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> autocorr_per_spectrum; } if (extract_xml_record(field,"autocorr_fftlen",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> autocorr_fftlen; } if (extract_xml_record(field,"gauss_null_chi_sq_thresh",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> gauss_null_chi_sq_thresh; } if (extract_xml_record(field,"gauss_chi_sq_thresh",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> gauss_chi_sq_thresh; } if (extract_xml_record(field,"gauss_power_thresh",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> gauss_power_thresh; } if (extract_xml_record(field,"gauss_peak_power_thresh",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> gauss_peak_power_thresh; } if (extract_xml_record(field,"gauss_pot_length",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> gauss_pot_length; } if (extract_xml_record(field,"pulse_thresh",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> pulse_thresh; } if (extract_xml_record(field,"pulse_display_thresh",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> pulse_display_thresh; } if (extract_xml_record(field,"pulse_max",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> pulse_max; } if (extract_xml_record(field,"pulse_min",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> pulse_min; } if (extract_xml_record(field,"pulse_fft_max",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> pulse_fft_max; } if (extract_xml_record(field,"pulse_pot_length",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> pulse_pot_length; } if (extract_xml_record(field,"triplet_thresh",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> triplet_thresh; } if (extract_xml_record(field,"triplet_max",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> triplet_max; } if (extract_xml_record(field,"triplet_min",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> triplet_min; } if (extract_xml_record(field,"triplet_pot_length",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> triplet_pot_length; } if (extract_xml_record(field,"pot_overlap_factor",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> pot_overlap_factor; } if (extract_xml_record(field,"pot_t_offset",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> pot_t_offset; } if (extract_xml_record(field,"pot_min_slew",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> pot_min_slew; } if (extract_xml_record(field,"pot_max_slew",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> pot_max_slew; } if (extract_xml_record(field,"chirp_resolution",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> chirp_resolution; } if (extract_xml_record(field,"analysis_fft_lengths",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> analysis_fft_lengths; } if (extract_xml_record(field,"bsmooth_boxcar_length",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> bsmooth_boxcar_length; } if (extract_xml_record(field,"bsmooth_chunk_size",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> bsmooth_chunk_size; } chirps.clear(); if (extract_xml_record(field,"chirps",sub)) { pos=0; while ((pos=sub.find("",pos); } } if (extract_xml_record(field,"pulse_beams",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> pulse_beams; } if (extract_xml_record(field,"max_signals",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> max_signals; } if (extract_xml_record(field,"max_spikes",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> max_spikes; } if (extract_xml_record(field,"max_autocorr",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> max_autocorr; } if (extract_xml_record(field,"max_gaussians",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> max_gaussians; } if (extract_xml_record(field,"max_pulses",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> max_pulses; } if (extract_xml_record(field,"max_triplets",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> max_triplets; } if (extract_xml_record(field,"keyuniq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> keyuniq; } if (extract_xml_record(field,"credit_rate",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> credit_rate; } } } void analysis_config::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { std::istringstream row(*(s[1])); row >> spike_thresh; } { std::istringstream row(*(s[2])); row >> spikes_per_spectrum; } { std::istringstream row(*(s[3])); row >> autocorr_thresh; } { std::istringstream row(*(s[4])); row >> autocorr_per_spectrum; } { std::istringstream row(*(s[5])); row >> autocorr_fftlen; } { std::istringstream row(*(s[6])); row >> gauss_null_chi_sq_thresh; } { std::istringstream row(*(s[7])); row >> gauss_chi_sq_thresh; } { std::istringstream row(*(s[8])); row >> gauss_power_thresh; } { std::istringstream row(*(s[9])); row >> gauss_peak_power_thresh; } { std::istringstream row(*(s[10])); row >> gauss_pot_length; } { std::istringstream row(*(s[11])); row >> pulse_thresh; } { std::istringstream row(*(s[12])); row >> pulse_display_thresh; } { std::istringstream row(*(s[13])); row >> pulse_max; } { std::istringstream row(*(s[14])); row >> pulse_min; } { std::istringstream row(*(s[15])); row >> pulse_fft_max; } { std::istringstream row(*(s[16])); row >> pulse_pot_length; } { std::istringstream row(*(s[17])); row >> triplet_thresh; } { std::istringstream row(*(s[18])); row >> triplet_max; } { std::istringstream row(*(s[19])); row >> triplet_min; } { std::istringstream row(*(s[20])); row >> triplet_pot_length; } { std::istringstream row(*(s[21])); row >> pot_overlap_factor; } { std::istringstream row(*(s[22])); row >> pot_t_offset; } { std::istringstream row(*(s[23])); row >> pot_min_slew; } { std::istringstream row(*(s[24])); row >> pot_max_slew; } { std::istringstream row(*(s[25])); row >> chirp_resolution; } { std::istringstream row(*(s[26])); row >> analysis_fft_lengths; } { std::istringstream row(*(s[27])); row >> bsmooth_boxcar_length; } { std::istringstream row(*(s[28])); row >> bsmooth_chunk_size; } { std::string::size_type p,q; int i; chirps.clear(); SQL_ROW tmp(s[29]); for (i=0;i> pulse_beams; } { std::istringstream row(*(s[31])); row >> max_signals; } { std::istringstream row(*(s[32])); row >> max_spikes; } { std::istringstream row(*(s[33])); row >> max_autocorr; } { std::istringstream row(*(s[34])); row >> max_gaussians; } { std::istringstream row(*(s[35])); row >> max_pulses; } { std::istringstream row(*(s[36])); row >> max_triplets; } { std::istringstream row(*(s[37])); row >> keyuniq; } { std::istringstream row(*(s[38])); row >> credit_rate; } } void analysis_config::parse(const std::string &s) { SQL_ROW row(&s,39); parse(row); } template <> const char * const db_table::table_name="science_config"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=29; template <> const char * const db_table::column_names[29]={"id","active","qpix_scheme","qpix_nside","fpix_width","total_bandwidth","freq_uncertainty","fwhm_beamwidth","sky_disc_radius","observable_sky","epoch","bary_chirp_window","bary_freq_window","nonbary_freq_window","spike_obs_duration","spike_obs_interval","gauss_obs_duration","gauss_obs_interval","pulse_obs_duration","pulse_obs_interval","triplet_obs_duration","triplet_obs_interval","min_spike_id","min_autocorr_id","min_gaussian_id","min_pulse_id","min_triplet_id","min_app_version""info_xml"}; science_config::science_config() : db_table(*this,-1), id(0), active(0), qpix_nside(0), fpix_width(0), total_bandwidth(0), freq_uncertainty(0), fwhm_beamwidth(0), sky_disc_radius(0), observable_sky(0), epoch(0), bary_chirp_window(0), bary_freq_window(0), nonbary_freq_window(0), spike_obs_duration(0), spike_obs_interval(0), gauss_obs_duration(0), gauss_obs_interval(0), pulse_obs_duration(0), pulse_obs_interval(0), triplet_obs_duration(0), triplet_obs_interval(0), min_spike_id(0), min_autocorr_id(0), min_gaussian_id(0), min_pulse_id(0), min_triplet_id(0), min_app_version(0) { db_open(); qpix_scheme[0]=0; info_xml[0]=0; } science_config::science_config(const science_config &a) : db_table(*this,-1), id(a.id), active(a.active), qpix_nside(a.qpix_nside), fpix_width(a.fpix_width), total_bandwidth(a.total_bandwidth), freq_uncertainty(a.freq_uncertainty), fwhm_beamwidth(a.fwhm_beamwidth), sky_disc_radius(a.sky_disc_radius), observable_sky(a.observable_sky), epoch(a.epoch), bary_chirp_window(a.bary_chirp_window), bary_freq_window(a.bary_freq_window), nonbary_freq_window(a.nonbary_freq_window), spike_obs_duration(a.spike_obs_duration), spike_obs_interval(a.spike_obs_interval), gauss_obs_duration(a.gauss_obs_duration), gauss_obs_interval(a.gauss_obs_interval), pulse_obs_duration(a.pulse_obs_duration), pulse_obs_interval(a.pulse_obs_interval), triplet_obs_duration(a.triplet_obs_duration), triplet_obs_interval(a.triplet_obs_interval), min_spike_id(a.min_spike_id), min_autocorr_id(a.min_autocorr_id), min_gaussian_id(a.min_gaussian_id), min_pulse_id(a.min_pulse_id), min_triplet_id(a.min_triplet_id), min_app_version(a.min_app_version) { db_open(); strcpy(qpix_scheme,a.qpix_scheme); strcpy(info_xml,a.info_xml); } science_config::science_config(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } science_config::science_config(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } science_config &science_config::operator =(const science_config &a) { if (&a != this) { id=a.id; active=a.active; qpix_nside=a.qpix_nside; fpix_width=a.fpix_width; total_bandwidth=a.total_bandwidth; freq_uncertainty=a.freq_uncertainty; fwhm_beamwidth=a.fwhm_beamwidth; sky_disc_radius=a.sky_disc_radius; observable_sky=a.observable_sky; epoch=a.epoch; bary_chirp_window=a.bary_chirp_window; bary_freq_window=a.bary_freq_window; nonbary_freq_window=a.nonbary_freq_window; spike_obs_duration=a.spike_obs_duration; spike_obs_interval=a.spike_obs_interval; gauss_obs_duration=a.gauss_obs_duration; gauss_obs_interval=a.gauss_obs_interval; pulse_obs_duration=a.pulse_obs_duration; pulse_obs_interval=a.pulse_obs_interval; triplet_obs_duration=a.triplet_obs_duration; triplet_obs_interval=a.triplet_obs_interval; min_spike_id=a.min_spike_id; min_autocorr_id=a.min_autocorr_id; min_gaussian_id=a.min_gaussian_id; min_pulse_id=a.min_pulse_id; min_triplet_id=a.min_triplet_id; min_app_version=a.min_app_version; strcpy(qpix_scheme,a.qpix_scheme); strcpy(info_xml,a.info_xml); } return (*this); } std::string science_config::update_format() const { std::ostringstream rv(""); for (int i=2;i<29;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string science_config::insert_format() const { return std::string("?,")+update_format(); } std::string science_config::select_format() const { std::string rv(""); for (int i=0; i<28;i++) rv+="?,"; rv+="?"; return rv; } std::string science_config::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; rv << active; rv << ','; rv << "'" << qpix_scheme << "'"; rv << ','; rv << qpix_nside; rv << ','; rv << fpix_width; rv << ','; rv << total_bandwidth; rv << ','; rv << freq_uncertainty; rv << ','; rv << fwhm_beamwidth; rv << ','; rv << sky_disc_radius; rv << ','; rv << observable_sky; rv << ','; rv << epoch; rv << ','; rv << bary_chirp_window; rv << ','; rv << bary_freq_window; rv << ','; rv << nonbary_freq_window; rv << ','; rv << spike_obs_duration; rv << ','; rv << spike_obs_interval; rv << ','; rv << gauss_obs_duration; rv << ','; rv << gauss_obs_interval; rv << ','; rv << pulse_obs_duration; rv << ','; rv << pulse_obs_interval; rv << ','; rv << triplet_obs_duration; rv << ','; rv << triplet_obs_interval; rv << ','; rv << min_spike_id; rv << ','; rv << min_autocorr_id; rv << ','; rv << min_gaussian_id; rv << ','; rv << min_pulse_id; rv << ','; rv << min_triplet_id; rv << ','; rv << min_app_version; rv << ','; rv << "'" << info_xml << "'"; return rv.str(); } std::string science_config::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; rv << xml_indent() << "" << active << "\n"; { std::string enc_field=xml_encode_string(qpix_scheme,std::min(strlen(qpix_scheme),sizeof(qpix_scheme))); rv << xml_indent() << ""; rv << enc_field << "\n"; } rv << xml_indent() << "" << qpix_nside << "\n"; rv << xml_indent() << "" << fpix_width << "\n"; rv << xml_indent() << "" << total_bandwidth << "\n"; rv << xml_indent() << "" << freq_uncertainty << "\n"; rv << xml_indent() << "" << fwhm_beamwidth << "\n"; rv << xml_indent() << "" << sky_disc_radius << "\n"; rv << xml_indent() << "" << observable_sky << "\n"; rv << xml_indent() << "" << epoch << "\n"; rv << xml_indent() << "" << bary_chirp_window << "\n"; rv << xml_indent() << "" << bary_freq_window << "\n"; rv << xml_indent() << "" << nonbary_freq_window << "\n"; rv << xml_indent() << "" << spike_obs_duration << "\n"; rv << xml_indent() << "" << spike_obs_interval << "\n"; rv << xml_indent() << "" << gauss_obs_duration << "\n"; rv << xml_indent() << "" << gauss_obs_interval << "\n"; rv << xml_indent() << "" << pulse_obs_duration << "\n"; rv << xml_indent() << "" << pulse_obs_interval << "\n"; rv << xml_indent() << "" << triplet_obs_duration << "\n"; rv << xml_indent() << "" << triplet_obs_interval << "\n"; rv << xml_indent() << "" << min_spike_id << "\n"; rv << xml_indent() << "" << min_autocorr_id << "\n"; rv << xml_indent() << "" << min_gaussian_id << "\n"; rv << xml_indent() << "" << min_pulse_id << "\n"; rv << xml_indent() << "" << min_triplet_id << "\n"; rv << xml_indent() << "" << min_app_version << "\n"; { std::string enc_field=xml_encode_string(info_xml,std::min(strlen(info_xml),sizeof(info_xml))); rv << xml_indent() << ""; rv << enc_field << "\n"; } xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void science_config::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"active",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> active; } if (extract_xml_record(field,"qpix_scheme",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::string::size_type epos=sub.find("<",pos); if (epos==std::string::npos) epos=sub.find('\n',pos); if (epos==std::string::npos) epos=pos+strlen(sub.c_str()+pos); std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); strncpy(qpix_scheme,(const char *)&(in.front()),std::min(in.size(),(size_t)16)); qpix_scheme[std::min(in.size(),(size_t)15)]=0; } if (extract_xml_record(field,"qpix_nside",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> qpix_nside; } if (extract_xml_record(field,"fpix_width",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> fpix_width; } if (extract_xml_record(field,"total_bandwidth",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> total_bandwidth; } if (extract_xml_record(field,"freq_uncertainty",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> freq_uncertainty; } if (extract_xml_record(field,"fwhm_beamwidth",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> fwhm_beamwidth; } if (extract_xml_record(field,"sky_disc_radius",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> sky_disc_radius; } if (extract_xml_record(field,"observable_sky",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> observable_sky; } if (extract_xml_record(field,"epoch",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> epoch; } if (extract_xml_record(field,"bary_chirp_window",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> bary_chirp_window; } if (extract_xml_record(field,"bary_freq_window",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> bary_freq_window; } if (extract_xml_record(field,"nonbary_freq_window",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> nonbary_freq_window; } if (extract_xml_record(field,"spike_obs_duration",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> spike_obs_duration; } if (extract_xml_record(field,"spike_obs_interval",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> spike_obs_interval; } if (extract_xml_record(field,"gauss_obs_duration",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> gauss_obs_duration; } if (extract_xml_record(field,"gauss_obs_interval",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> gauss_obs_interval; } if (extract_xml_record(field,"pulse_obs_duration",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> pulse_obs_duration; } if (extract_xml_record(field,"pulse_obs_interval",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> pulse_obs_interval; } if (extract_xml_record(field,"triplet_obs_duration",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> triplet_obs_duration; } if (extract_xml_record(field,"triplet_obs_interval",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> triplet_obs_interval; } if (extract_xml_record(field,"min_spike_id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> min_spike_id; } if (extract_xml_record(field,"min_autocorr_id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> min_autocorr_id; } if (extract_xml_record(field,"min_gaussian_id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> min_gaussian_id; } if (extract_xml_record(field,"min_pulse_id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> min_pulse_id; } if (extract_xml_record(field,"min_triplet_id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> min_triplet_id; } if (extract_xml_record(field,"min_app_version",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> min_app_version; } if (extract_xml_record(field,"info_xml",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::string::size_type epos=sub.find("<",pos); if (epos==std::string::npos) epos=sub.find('\n',pos); if (epos==std::string::npos) epos=pos+strlen(sub.c_str()+pos); std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); strncpy(info_xml,(const char *)&(in.front()),std::min(in.size(),(size_t)255)); info_xml[std::min(in.size(),(size_t)254)]=0; } } } void science_config::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { std::istringstream row(*(s[1])); row >> active; } { strncpy(qpix_scheme,s[2]->c_str(),16); qpix_scheme[15]=0; } { std::istringstream row(*(s[3])); row >> qpix_nside; } { std::istringstream row(*(s[4])); row >> fpix_width; } { std::istringstream row(*(s[5])); row >> total_bandwidth; } { std::istringstream row(*(s[6])); row >> freq_uncertainty; } { std::istringstream row(*(s[7])); row >> fwhm_beamwidth; } { std::istringstream row(*(s[8])); row >> sky_disc_radius; } { std::istringstream row(*(s[9])); row >> observable_sky; } { std::istringstream row(*(s[10])); row >> epoch; } { std::istringstream row(*(s[11])); row >> bary_chirp_window; } { std::istringstream row(*(s[12])); row >> bary_freq_window; } { std::istringstream row(*(s[13])); row >> nonbary_freq_window; } { std::istringstream row(*(s[14])); row >> spike_obs_duration; } { std::istringstream row(*(s[15])); row >> spike_obs_interval; } { std::istringstream row(*(s[16])); row >> gauss_obs_duration; } { std::istringstream row(*(s[17])); row >> gauss_obs_interval; } { std::istringstream row(*(s[18])); row >> pulse_obs_duration; } { std::istringstream row(*(s[19])); row >> pulse_obs_interval; } { std::istringstream row(*(s[20])); row >> triplet_obs_duration; } { std::istringstream row(*(s[21])); row >> triplet_obs_interval; } { std::istringstream row(*(s[22])); row >> min_spike_id; } { std::istringstream row(*(s[23])); row >> min_autocorr_id; } { std::istringstream row(*(s[24])); row >> min_gaussian_id; } { std::istringstream row(*(s[25])); row >> min_pulse_id; } { std::istringstream row(*(s[26])); row >> min_triplet_id; } { std::istringstream row(*(s[27])); row >> min_app_version; } { strncpy(info_xml,s[28]->c_str(),255); info_xml[254]=0; } } void science_config::parse(const std::string &s) { SQL_ROW row(&s,29); parse(row); } template <> const char * const db_type::type_name="candidate_t"; template <> const char * db_type::_search_tag=type_name; template <> const int db_type::_nfields=5; template <> const char * const db_type::column_names[5]={"type","id","num_obs","score","is_rfi"}; candidate_t::candidate_t() : db_type(*this), type(0), id(0), num_obs(0), score(0), is_rfi(0) { db_open(); } candidate_t::candidate_t(const candidate_t &a) : db_type(*this), type(a.type), id(a.id), num_obs(a.num_obs), score(a.score), is_rfi(a.is_rfi) { db_open(); } candidate_t::candidate_t(const SQL_ROW &a) : db_type(*this) { db_open(); parse(a); } candidate_t::candidate_t(const std::string &s,const char *tag) : db_type(*this) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } candidate_t &candidate_t::operator =(const candidate_t &a) { if (&a != this) { type=a.type; id=a.id; num_obs=a.num_obs; score=a.score; is_rfi=a.is_rfi; } return (*this); } std::string candidate_t::update_format() const { std::ostringstream rv(""); rv << "ROW("; for (int i=1;i<5;i++) rv << "?,"; rv << "?"; rv << ")"; return rv.str(); } std::string candidate_t::insert_format() const { return update_format(); } std::string candidate_t::select_format() const { std::string rv(""); for (int i=0; i<4;i++) rv+="?,"; rv+="?"; return rv; } std::string candidate_t::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); rv << "ROW("; rv << type; rv << ','; rv << id; rv << ','; rv << num_obs; rv << ','; rv << score; rv << ','; rv << is_rfi; rv << ")"; return rv.str(); } std::string candidate_t::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); rv << xml_indent() << "" << type << "\n"; rv << xml_indent() << "" << id << "\n"; rv << xml_indent() << "" << num_obs << "\n"; rv << xml_indent() << "" << score << "\n"; rv << xml_indent() << "" << is_rfi << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void candidate_t::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"type",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> type; } if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"num_obs",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> num_obs; } if (extract_xml_record(field,"score",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> score; } if (extract_xml_record(field,"is_rfi",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> is_rfi; } } } void candidate_t::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> type; } { std::istringstream row(*(s[1])); row >> id; } { std::istringstream row(*(s[2])); row >> num_obs; } { std::istringstream row(*(s[3])); row >> score; } { std::istringstream row(*(s[4])); row >> is_rfi; } } void candidate_t::parse(const std::string &s) { SQL_ROW row(&s,5); parse(row); } template <> const char * const db_table::table_name="meta_candidate"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=32; template <> const char * const db_table::column_names[32]={"id","version","time_last_updated","num_spikes","num_spike_b_multiplets","best_spike_b_mp_score","num_spike_nb_multiplets","best_spike_nb_mp_score","spike_high_id","num_gaussians","num_gaussian_b_multiplets","best_gaussian_b_mp_score","num_gaussian_nb_multiplets","best_gaussian_nb_mp_score","gaussian_high_id","num_pulses","num_pulse_b_multiplets","best_pulse_b_mp_score","num_pulse_nb_multiplets","best_pulse_nb_mp_score","pulse_high_id","num_triplets","num_triplet_b_multiplets","best_triplet_b_mp_score","num_triplet_nb_multiplets","best_triplet_nb_mp_score","triplet_high_id","num_stars","best_star_score","meta_score","rfi_clean","state"}; meta_candidate::meta_candidate() : db_table(*this,-1), id(0), version(0), time_last_updated(0), num_spikes(0), num_spike_b_multiplets(0), best_spike_b_mp_score(0), num_spike_nb_multiplets(0), best_spike_nb_mp_score(0), spike_high_id(0), num_gaussians(0), num_gaussian_b_multiplets(0), best_gaussian_b_mp_score(0), num_gaussian_nb_multiplets(0), best_gaussian_nb_mp_score(0), gaussian_high_id(0), num_pulses(0), num_pulse_b_multiplets(0), best_pulse_b_mp_score(0), num_pulse_nb_multiplets(0), best_pulse_nb_mp_score(0), pulse_high_id(0), num_triplets(0), num_triplet_b_multiplets(0), best_triplet_b_mp_score(0), num_triplet_nb_multiplets(0), best_triplet_nb_mp_score(0), triplet_high_id(0), num_stars(0), best_star_score(0), meta_score(0), rfi_clean(0), state(0) { db_open(); } meta_candidate::meta_candidate(const meta_candidate &a) : db_table(*this,-1), id(a.id), version(a.version), time_last_updated(a.time_last_updated), num_spikes(a.num_spikes), num_spike_b_multiplets(a.num_spike_b_multiplets), best_spike_b_mp_score(a.best_spike_b_mp_score), num_spike_nb_multiplets(a.num_spike_nb_multiplets), best_spike_nb_mp_score(a.best_spike_nb_mp_score), spike_high_id(a.spike_high_id), num_gaussians(a.num_gaussians), num_gaussian_b_multiplets(a.num_gaussian_b_multiplets), best_gaussian_b_mp_score(a.best_gaussian_b_mp_score), num_gaussian_nb_multiplets(a.num_gaussian_nb_multiplets), best_gaussian_nb_mp_score(a.best_gaussian_nb_mp_score), gaussian_high_id(a.gaussian_high_id), num_pulses(a.num_pulses), num_pulse_b_multiplets(a.num_pulse_b_multiplets), best_pulse_b_mp_score(a.best_pulse_b_mp_score), num_pulse_nb_multiplets(a.num_pulse_nb_multiplets), best_pulse_nb_mp_score(a.best_pulse_nb_mp_score), pulse_high_id(a.pulse_high_id), num_triplets(a.num_triplets), num_triplet_b_multiplets(a.num_triplet_b_multiplets), best_triplet_b_mp_score(a.best_triplet_b_mp_score), num_triplet_nb_multiplets(a.num_triplet_nb_multiplets), best_triplet_nb_mp_score(a.best_triplet_nb_mp_score), triplet_high_id(a.triplet_high_id), num_stars(a.num_stars), best_star_score(a.best_star_score), meta_score(a.meta_score), rfi_clean(a.rfi_clean), state(a.state) { db_open(); } meta_candidate::meta_candidate(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } meta_candidate::meta_candidate(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } meta_candidate &meta_candidate::operator =(const meta_candidate &a) { if (&a != this) { id=a.id; version=a.version; time_last_updated=a.time_last_updated; num_spikes=a.num_spikes; num_spike_b_multiplets=a.num_spike_b_multiplets; best_spike_b_mp_score=a.best_spike_b_mp_score; num_spike_nb_multiplets=a.num_spike_nb_multiplets; best_spike_nb_mp_score=a.best_spike_nb_mp_score; spike_high_id=a.spike_high_id; num_gaussians=a.num_gaussians; num_gaussian_b_multiplets=a.num_gaussian_b_multiplets; best_gaussian_b_mp_score=a.best_gaussian_b_mp_score; num_gaussian_nb_multiplets=a.num_gaussian_nb_multiplets; best_gaussian_nb_mp_score=a.best_gaussian_nb_mp_score; gaussian_high_id=a.gaussian_high_id; num_pulses=a.num_pulses; num_pulse_b_multiplets=a.num_pulse_b_multiplets; best_pulse_b_mp_score=a.best_pulse_b_mp_score; num_pulse_nb_multiplets=a.num_pulse_nb_multiplets; best_pulse_nb_mp_score=a.best_pulse_nb_mp_score; pulse_high_id=a.pulse_high_id; num_triplets=a.num_triplets; num_triplet_b_multiplets=a.num_triplet_b_multiplets; best_triplet_b_mp_score=a.best_triplet_b_mp_score; num_triplet_nb_multiplets=a.num_triplet_nb_multiplets; best_triplet_nb_mp_score=a.best_triplet_nb_mp_score; triplet_high_id=a.triplet_high_id; num_stars=a.num_stars; best_star_score=a.best_star_score; meta_score=a.meta_score; rfi_clean=a.rfi_clean; state=a.state; } return (*this); } std::string meta_candidate::update_format() const { std::ostringstream rv(""); for (int i=2;i<32;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string meta_candidate::insert_format() const { return std::string("?,")+update_format(); } std::string meta_candidate::select_format() const { std::string rv(""); for (int i=0; i<31;i++) rv+="?,"; rv+="?"; return rv; } std::string meta_candidate::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; rv << version; rv << ','; rv << time_last_updated; rv << ','; rv << num_spikes; rv << ','; rv << num_spike_b_multiplets; rv << ','; rv << best_spike_b_mp_score; rv << ','; rv << num_spike_nb_multiplets; rv << ','; rv << best_spike_nb_mp_score; rv << ','; rv << spike_high_id; rv << ','; rv << num_gaussians; rv << ','; rv << num_gaussian_b_multiplets; rv << ','; rv << best_gaussian_b_mp_score; rv << ','; rv << num_gaussian_nb_multiplets; rv << ','; rv << best_gaussian_nb_mp_score; rv << ','; rv << gaussian_high_id; rv << ','; rv << num_pulses; rv << ','; rv << num_pulse_b_multiplets; rv << ','; rv << best_pulse_b_mp_score; rv << ','; rv << num_pulse_nb_multiplets; rv << ','; rv << best_pulse_nb_mp_score; rv << ','; rv << pulse_high_id; rv << ','; rv << num_triplets; rv << ','; rv << num_triplet_b_multiplets; rv << ','; rv << best_triplet_b_mp_score; rv << ','; rv << num_triplet_nb_multiplets; rv << ','; rv << best_triplet_nb_mp_score; rv << ','; rv << triplet_high_id; rv << ','; rv << num_stars; rv << ','; rv << best_star_score; rv << ','; rv << meta_score; rv << ','; rv << rfi_clean; rv << ','; rv << state; return rv.str(); } std::string meta_candidate::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; rv << xml_indent() << "" << version << "\n"; rv << xml_indent() << "" << time_last_updated << "\n"; rv << xml_indent() << "" << num_spikes << "\n"; rv << xml_indent() << "" << num_spike_b_multiplets << "\n"; rv << xml_indent() << "" << best_spike_b_mp_score << "\n"; rv << xml_indent() << "" << num_spike_nb_multiplets << "\n"; rv << xml_indent() << "" << best_spike_nb_mp_score << "\n"; rv << xml_indent() << "" << spike_high_id << "\n"; rv << xml_indent() << "" << num_gaussians << "\n"; rv << xml_indent() << "" << num_gaussian_b_multiplets << "\n"; rv << xml_indent() << "" << best_gaussian_b_mp_score << "\n"; rv << xml_indent() << "" << num_gaussian_nb_multiplets << "\n"; rv << xml_indent() << "" << best_gaussian_nb_mp_score << "\n"; rv << xml_indent() << "" << gaussian_high_id << "\n"; rv << xml_indent() << "" << num_pulses << "\n"; rv << xml_indent() << "" << num_pulse_b_multiplets << "\n"; rv << xml_indent() << "" << best_pulse_b_mp_score << "\n"; rv << xml_indent() << "" << num_pulse_nb_multiplets << "\n"; rv << xml_indent() << "" << best_pulse_nb_mp_score << "\n"; rv << xml_indent() << "" << pulse_high_id << "\n"; rv << xml_indent() << "" << num_triplets << "\n"; rv << xml_indent() << "" << num_triplet_b_multiplets << "\n"; rv << xml_indent() << "" << best_triplet_b_mp_score << "\n"; rv << xml_indent() << "" << num_triplet_nb_multiplets << "\n"; rv << xml_indent() << "" << best_triplet_nb_mp_score << "\n"; rv << xml_indent() << "" << triplet_high_id << "\n"; rv << xml_indent() << "" << num_stars << "\n"; rv << xml_indent() << "" << best_star_score << "\n"; rv << xml_indent() << "" << meta_score << "\n"; rv << xml_indent() << "" << rfi_clean << "\n"; rv << xml_indent() << "" << state << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void meta_candidate::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"version",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> version; } if (extract_xml_record(field,"time_last_updated",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> time_last_updated; } if (extract_xml_record(field,"num_spikes",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> num_spikes; } if (extract_xml_record(field,"num_spike_b_multiplets",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> num_spike_b_multiplets; } if (extract_xml_record(field,"best_spike_b_mp_score",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> best_spike_b_mp_score; } if (extract_xml_record(field,"num_spike_nb_multiplets",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> num_spike_nb_multiplets; } if (extract_xml_record(field,"best_spike_nb_mp_score",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> best_spike_nb_mp_score; } if (extract_xml_record(field,"spike_high_id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> spike_high_id; } if (extract_xml_record(field,"num_gaussians",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> num_gaussians; } if (extract_xml_record(field,"num_gaussian_b_multiplets",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> num_gaussian_b_multiplets; } if (extract_xml_record(field,"best_gaussian_b_mp_score",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> best_gaussian_b_mp_score; } if (extract_xml_record(field,"num_gaussian_nb_multiplets",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> num_gaussian_nb_multiplets; } if (extract_xml_record(field,"best_gaussian_nb_mp_score",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> best_gaussian_nb_mp_score; } if (extract_xml_record(field,"gaussian_high_id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> gaussian_high_id; } if (extract_xml_record(field,"num_pulses",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> num_pulses; } if (extract_xml_record(field,"num_pulse_b_multiplets",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> num_pulse_b_multiplets; } if (extract_xml_record(field,"best_pulse_b_mp_score",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> best_pulse_b_mp_score; } if (extract_xml_record(field,"num_pulse_nb_multiplets",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> num_pulse_nb_multiplets; } if (extract_xml_record(field,"best_pulse_nb_mp_score",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> best_pulse_nb_mp_score; } if (extract_xml_record(field,"pulse_high_id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> pulse_high_id; } if (extract_xml_record(field,"num_triplets",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> num_triplets; } if (extract_xml_record(field,"num_triplet_b_multiplets",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> num_triplet_b_multiplets; } if (extract_xml_record(field,"best_triplet_b_mp_score",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> best_triplet_b_mp_score; } if (extract_xml_record(field,"num_triplet_nb_multiplets",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> num_triplet_nb_multiplets; } if (extract_xml_record(field,"best_triplet_nb_mp_score",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> best_triplet_nb_mp_score; } if (extract_xml_record(field,"triplet_high_id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> triplet_high_id; } if (extract_xml_record(field,"num_stars",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> num_stars; } if (extract_xml_record(field,"best_star_score",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> best_star_score; } if (extract_xml_record(field,"meta_score",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> meta_score; } if (extract_xml_record(field,"rfi_clean",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> rfi_clean; } if (extract_xml_record(field,"state",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> state; } } } void meta_candidate::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { std::istringstream row(*(s[1])); row >> version; } { std::istringstream row(*(s[2])); row >> time_last_updated; } { std::istringstream row(*(s[3])); row >> num_spikes; } { std::istringstream row(*(s[4])); row >> num_spike_b_multiplets; } { std::istringstream row(*(s[5])); row >> best_spike_b_mp_score; } { std::istringstream row(*(s[6])); row >> num_spike_nb_multiplets; } { std::istringstream row(*(s[7])); row >> best_spike_nb_mp_score; } { std::istringstream row(*(s[8])); row >> spike_high_id; } { std::istringstream row(*(s[9])); row >> num_gaussians; } { std::istringstream row(*(s[10])); row >> num_gaussian_b_multiplets; } { std::istringstream row(*(s[11])); row >> best_gaussian_b_mp_score; } { std::istringstream row(*(s[12])); row >> num_gaussian_nb_multiplets; } { std::istringstream row(*(s[13])); row >> best_gaussian_nb_mp_score; } { std::istringstream row(*(s[14])); row >> gaussian_high_id; } { std::istringstream row(*(s[15])); row >> num_pulses; } { std::istringstream row(*(s[16])); row >> num_pulse_b_multiplets; } { std::istringstream row(*(s[17])); row >> best_pulse_b_mp_score; } { std::istringstream row(*(s[18])); row >> num_pulse_nb_multiplets; } { std::istringstream row(*(s[19])); row >> best_pulse_nb_mp_score; } { std::istringstream row(*(s[20])); row >> pulse_high_id; } { std::istringstream row(*(s[21])); row >> num_triplets; } { std::istringstream row(*(s[22])); row >> num_triplet_b_multiplets; } { std::istringstream row(*(s[23])); row >> best_triplet_b_mp_score; } { std::istringstream row(*(s[24])); row >> num_triplet_nb_multiplets; } { std::istringstream row(*(s[25])); row >> best_triplet_nb_mp_score; } { std::istringstream row(*(s[26])); row >> triplet_high_id; } { std::istringstream row(*(s[27])); row >> num_stars; } { std::istringstream row(*(s[28])); row >> best_star_score; } { std::istringstream row(*(s[29])); row >> meta_score; } { std::istringstream row(*(s[30])); row >> rfi_clean; } { std::istringstream row(*(s[31])); row >> state; } } void meta_candidate::parse(const std::string &s) { SQL_ROW row(&s,32); parse(row); } template <> const char * const db_table::table_name="meta_candidate_tinysky"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=32; template <> const char * const db_table::column_names[32]={"id","version","time_last_updated","num_spikes","num_spike_b_multiplets","best_spike_b_mp_score","num_spike_nb_multiplets","best_spike_nb_mp_score","spike_high_id","num_gaussians","num_gaussian_b_multiplets","best_gaussian_b_mp_score","num_gaussian_nb_multiplets","best_gaussian_nb_mp_score","gaussian_high_id","num_pulses","num_pulse_b_multiplets","best_pulse_b_mp_score","num_pulse_nb_multiplets","best_pulse_nb_mp_score","pulse_high_id","num_triplets","num_triplet_b_multiplets","best_triplet_b_mp_score","num_triplet_nb_multiplets","best_triplet_nb_mp_score","triplet_high_id","num_stars","best_star_score","meta_score","rfi_clean","state"}; meta_candidate_tinysky::meta_candidate_tinysky() : db_table(*this,-1), id(0), version(0), time_last_updated(0), num_spikes(0), num_spike_b_multiplets(0), best_spike_b_mp_score(0), num_spike_nb_multiplets(0), best_spike_nb_mp_score(0), spike_high_id(0), num_gaussians(0), num_gaussian_b_multiplets(0), best_gaussian_b_mp_score(0), num_gaussian_nb_multiplets(0), best_gaussian_nb_mp_score(0), gaussian_high_id(0), num_pulses(0), num_pulse_b_multiplets(0), best_pulse_b_mp_score(0), num_pulse_nb_multiplets(0), best_pulse_nb_mp_score(0), pulse_high_id(0), num_triplets(0), num_triplet_b_multiplets(0), best_triplet_b_mp_score(0), num_triplet_nb_multiplets(0), best_triplet_nb_mp_score(0), triplet_high_id(0), num_stars(0), best_star_score(0), meta_score(0), rfi_clean(0), state(0) { db_open(); } meta_candidate_tinysky::meta_candidate_tinysky(const meta_candidate_tinysky &a) : db_table(*this,-1), id(a.id), version(a.version), time_last_updated(a.time_last_updated), num_spikes(a.num_spikes), num_spike_b_multiplets(a.num_spike_b_multiplets), best_spike_b_mp_score(a.best_spike_b_mp_score), num_spike_nb_multiplets(a.num_spike_nb_multiplets), best_spike_nb_mp_score(a.best_spike_nb_mp_score), spike_high_id(a.spike_high_id), num_gaussians(a.num_gaussians), num_gaussian_b_multiplets(a.num_gaussian_b_multiplets), best_gaussian_b_mp_score(a.best_gaussian_b_mp_score), num_gaussian_nb_multiplets(a.num_gaussian_nb_multiplets), best_gaussian_nb_mp_score(a.best_gaussian_nb_mp_score), gaussian_high_id(a.gaussian_high_id), num_pulses(a.num_pulses), num_pulse_b_multiplets(a.num_pulse_b_multiplets), best_pulse_b_mp_score(a.best_pulse_b_mp_score), num_pulse_nb_multiplets(a.num_pulse_nb_multiplets), best_pulse_nb_mp_score(a.best_pulse_nb_mp_score), pulse_high_id(a.pulse_high_id), num_triplets(a.num_triplets), num_triplet_b_multiplets(a.num_triplet_b_multiplets), best_triplet_b_mp_score(a.best_triplet_b_mp_score), num_triplet_nb_multiplets(a.num_triplet_nb_multiplets), best_triplet_nb_mp_score(a.best_triplet_nb_mp_score), triplet_high_id(a.triplet_high_id), num_stars(a.num_stars), best_star_score(a.best_star_score), meta_score(a.meta_score), rfi_clean(a.rfi_clean), state(a.state) { db_open(); } meta_candidate_tinysky::meta_candidate_tinysky(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } meta_candidate_tinysky::meta_candidate_tinysky(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } meta_candidate_tinysky &meta_candidate_tinysky::operator =(const meta_candidate_tinysky &a) { if (&a != this) { id=a.id; version=a.version; time_last_updated=a.time_last_updated; num_spikes=a.num_spikes; num_spike_b_multiplets=a.num_spike_b_multiplets; best_spike_b_mp_score=a.best_spike_b_mp_score; num_spike_nb_multiplets=a.num_spike_nb_multiplets; best_spike_nb_mp_score=a.best_spike_nb_mp_score; spike_high_id=a.spike_high_id; num_gaussians=a.num_gaussians; num_gaussian_b_multiplets=a.num_gaussian_b_multiplets; best_gaussian_b_mp_score=a.best_gaussian_b_mp_score; num_gaussian_nb_multiplets=a.num_gaussian_nb_multiplets; best_gaussian_nb_mp_score=a.best_gaussian_nb_mp_score; gaussian_high_id=a.gaussian_high_id; num_pulses=a.num_pulses; num_pulse_b_multiplets=a.num_pulse_b_multiplets; best_pulse_b_mp_score=a.best_pulse_b_mp_score; num_pulse_nb_multiplets=a.num_pulse_nb_multiplets; best_pulse_nb_mp_score=a.best_pulse_nb_mp_score; pulse_high_id=a.pulse_high_id; num_triplets=a.num_triplets; num_triplet_b_multiplets=a.num_triplet_b_multiplets; best_triplet_b_mp_score=a.best_triplet_b_mp_score; num_triplet_nb_multiplets=a.num_triplet_nb_multiplets; best_triplet_nb_mp_score=a.best_triplet_nb_mp_score; triplet_high_id=a.triplet_high_id; num_stars=a.num_stars; best_star_score=a.best_star_score; meta_score=a.meta_score; rfi_clean=a.rfi_clean; state=a.state; } return (*this); } std::string meta_candidate_tinysky::update_format() const { std::ostringstream rv(""); for (int i=2;i<32;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string meta_candidate_tinysky::insert_format() const { return std::string("?,")+update_format(); } std::string meta_candidate_tinysky::select_format() const { std::string rv(""); for (int i=0; i<31;i++) rv+="?,"; rv+="?"; return rv; } std::string meta_candidate_tinysky::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; rv << version; rv << ','; rv << time_last_updated; rv << ','; rv << num_spikes; rv << ','; rv << num_spike_b_multiplets; rv << ','; rv << best_spike_b_mp_score; rv << ','; rv << num_spike_nb_multiplets; rv << ','; rv << best_spike_nb_mp_score; rv << ','; rv << spike_high_id; rv << ','; rv << num_gaussians; rv << ','; rv << num_gaussian_b_multiplets; rv << ','; rv << best_gaussian_b_mp_score; rv << ','; rv << num_gaussian_nb_multiplets; rv << ','; rv << best_gaussian_nb_mp_score; rv << ','; rv << gaussian_high_id; rv << ','; rv << num_pulses; rv << ','; rv << num_pulse_b_multiplets; rv << ','; rv << best_pulse_b_mp_score; rv << ','; rv << num_pulse_nb_multiplets; rv << ','; rv << best_pulse_nb_mp_score; rv << ','; rv << pulse_high_id; rv << ','; rv << num_triplets; rv << ','; rv << num_triplet_b_multiplets; rv << ','; rv << best_triplet_b_mp_score; rv << ','; rv << num_triplet_nb_multiplets; rv << ','; rv << best_triplet_nb_mp_score; rv << ','; rv << triplet_high_id; rv << ','; rv << num_stars; rv << ','; rv << best_star_score; rv << ','; rv << meta_score; rv << ','; rv << rfi_clean; rv << ','; rv << state; return rv.str(); } std::string meta_candidate_tinysky::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; rv << xml_indent() << "" << version << "\n"; rv << xml_indent() << "" << time_last_updated << "\n"; rv << xml_indent() << "" << num_spikes << "\n"; rv << xml_indent() << "" << num_spike_b_multiplets << "\n"; rv << xml_indent() << "" << best_spike_b_mp_score << "\n"; rv << xml_indent() << "" << num_spike_nb_multiplets << "\n"; rv << xml_indent() << "" << best_spike_nb_mp_score << "\n"; rv << xml_indent() << "" << spike_high_id << "\n"; rv << xml_indent() << "" << num_gaussians << "\n"; rv << xml_indent() << "" << num_gaussian_b_multiplets << "\n"; rv << xml_indent() << "" << best_gaussian_b_mp_score << "\n"; rv << xml_indent() << "" << num_gaussian_nb_multiplets << "\n"; rv << xml_indent() << "" << best_gaussian_nb_mp_score << "\n"; rv << xml_indent() << "" << gaussian_high_id << "\n"; rv << xml_indent() << "" << num_pulses << "\n"; rv << xml_indent() << "" << num_pulse_b_multiplets << "\n"; rv << xml_indent() << "" << best_pulse_b_mp_score << "\n"; rv << xml_indent() << "" << num_pulse_nb_multiplets << "\n"; rv << xml_indent() << "" << best_pulse_nb_mp_score << "\n"; rv << xml_indent() << "" << pulse_high_id << "\n"; rv << xml_indent() << "" << num_triplets << "\n"; rv << xml_indent() << "" << num_triplet_b_multiplets << "\n"; rv << xml_indent() << "" << best_triplet_b_mp_score << "\n"; rv << xml_indent() << "" << num_triplet_nb_multiplets << "\n"; rv << xml_indent() << "" << best_triplet_nb_mp_score << "\n"; rv << xml_indent() << "" << triplet_high_id << "\n"; rv << xml_indent() << "" << num_stars << "\n"; rv << xml_indent() << "" << best_star_score << "\n"; rv << xml_indent() << "" << meta_score << "\n"; rv << xml_indent() << "" << rfi_clean << "\n"; rv << xml_indent() << "" << state << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void meta_candidate_tinysky::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"version",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> version; } if (extract_xml_record(field,"time_last_updated",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> time_last_updated; } if (extract_xml_record(field,"num_spikes",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> num_spikes; } if (extract_xml_record(field,"num_spike_b_multiplets",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> num_spike_b_multiplets; } if (extract_xml_record(field,"best_spike_b_mp_score",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> best_spike_b_mp_score; } if (extract_xml_record(field,"num_spike_nb_multiplets",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> num_spike_nb_multiplets; } if (extract_xml_record(field,"best_spike_nb_mp_score",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> best_spike_nb_mp_score; } if (extract_xml_record(field,"spike_high_id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> spike_high_id; } if (extract_xml_record(field,"num_gaussians",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> num_gaussians; } if (extract_xml_record(field,"num_gaussian_b_multiplets",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> num_gaussian_b_multiplets; } if (extract_xml_record(field,"best_gaussian_b_mp_score",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> best_gaussian_b_mp_score; } if (extract_xml_record(field,"num_gaussian_nb_multiplets",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> num_gaussian_nb_multiplets; } if (extract_xml_record(field,"best_gaussian_nb_mp_score",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> best_gaussian_nb_mp_score; } if (extract_xml_record(field,"gaussian_high_id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> gaussian_high_id; } if (extract_xml_record(field,"num_pulses",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> num_pulses; } if (extract_xml_record(field,"num_pulse_b_multiplets",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> num_pulse_b_multiplets; } if (extract_xml_record(field,"best_pulse_b_mp_score",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> best_pulse_b_mp_score; } if (extract_xml_record(field,"num_pulse_nb_multiplets",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> num_pulse_nb_multiplets; } if (extract_xml_record(field,"best_pulse_nb_mp_score",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> best_pulse_nb_mp_score; } if (extract_xml_record(field,"pulse_high_id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> pulse_high_id; } if (extract_xml_record(field,"num_triplets",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> num_triplets; } if (extract_xml_record(field,"num_triplet_b_multiplets",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> num_triplet_b_multiplets; } if (extract_xml_record(field,"best_triplet_b_mp_score",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> best_triplet_b_mp_score; } if (extract_xml_record(field,"num_triplet_nb_multiplets",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> num_triplet_nb_multiplets; } if (extract_xml_record(field,"best_triplet_nb_mp_score",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> best_triplet_nb_mp_score; } if (extract_xml_record(field,"triplet_high_id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> triplet_high_id; } if (extract_xml_record(field,"num_stars",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> num_stars; } if (extract_xml_record(field,"best_star_score",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> best_star_score; } if (extract_xml_record(field,"meta_score",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> meta_score; } if (extract_xml_record(field,"rfi_clean",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> rfi_clean; } if (extract_xml_record(field,"state",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> state; } } } void meta_candidate_tinysky::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { std::istringstream row(*(s[1])); row >> version; } { std::istringstream row(*(s[2])); row >> time_last_updated; } { std::istringstream row(*(s[3])); row >> num_spikes; } { std::istringstream row(*(s[4])); row >> num_spike_b_multiplets; } { std::istringstream row(*(s[5])); row >> best_spike_b_mp_score; } { std::istringstream row(*(s[6])); row >> num_spike_nb_multiplets; } { std::istringstream row(*(s[7])); row >> best_spike_nb_mp_score; } { std::istringstream row(*(s[8])); row >> spike_high_id; } { std::istringstream row(*(s[9])); row >> num_gaussians; } { std::istringstream row(*(s[10])); row >> num_gaussian_b_multiplets; } { std::istringstream row(*(s[11])); row >> best_gaussian_b_mp_score; } { std::istringstream row(*(s[12])); row >> num_gaussian_nb_multiplets; } { std::istringstream row(*(s[13])); row >> best_gaussian_nb_mp_score; } { std::istringstream row(*(s[14])); row >> gaussian_high_id; } { std::istringstream row(*(s[15])); row >> num_pulses; } { std::istringstream row(*(s[16])); row >> num_pulse_b_multiplets; } { std::istringstream row(*(s[17])); row >> best_pulse_b_mp_score; } { std::istringstream row(*(s[18])); row >> num_pulse_nb_multiplets; } { std::istringstream row(*(s[19])); row >> best_pulse_nb_mp_score; } { std::istringstream row(*(s[20])); row >> pulse_high_id; } { std::istringstream row(*(s[21])); row >> num_triplets; } { std::istringstream row(*(s[22])); row >> num_triplet_b_multiplets; } { std::istringstream row(*(s[23])); row >> best_triplet_b_mp_score; } { std::istringstream row(*(s[24])); row >> num_triplet_nb_multiplets; } { std::istringstream row(*(s[25])); row >> best_triplet_nb_mp_score; } { std::istringstream row(*(s[26])); row >> triplet_high_id; } { std::istringstream row(*(s[27])); row >> num_stars; } { std::istringstream row(*(s[28])); row >> best_star_score; } { std::istringstream row(*(s[29])); row >> meta_score; } { std::istringstream row(*(s[30])); row >> rfi_clean; } { std::istringstream row(*(s[31])); row >> state; } } void meta_candidate_tinysky::parse(const std::string &s) { SQL_ROW row(&s,32); parse(row); } template <> const char * const db_table::table_name="multiplet"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=25; template <> const char * const db_table::column_names[25]={"id","version","signal_type","mp_type","qpix","freq_win","mean_ra","mean_decl","ra_stddev","decl_stddev","mean_angular_distance","angular_distance_stddev","mean_frequency","frequency_stddev","mean_chirp","chirp_stddev","mean_period","period_stddev","mean_snr","snr_stddev","mean_threshold","threshold_stddev","score","num_detections","signal_ids"}; multiplet::multiplet() : db_table(*this,-1), id(0), version(0), signal_type(0), mp_type(0), qpix(0), freq_win(0), mean_ra(0), mean_decl(0), ra_stddev(0), decl_stddev(0), mean_angular_distance(0), angular_distance_stddev(0), mean_frequency(0), frequency_stddev(0), mean_chirp(0), chirp_stddev(0), mean_period(0), period_stddev(0), mean_snr(0), snr_stddev(0), mean_threshold(0), threshold_stddev(0), score(0), num_detections(0), signal_ids((sqlint8_t *)0,0,_x_csv) { db_open(); } multiplet::multiplet(const multiplet &a) : db_table(*this,-1), id(a.id), version(a.version), signal_type(a.signal_type), mp_type(a.mp_type), qpix(a.qpix), freq_win(a.freq_win), mean_ra(a.mean_ra), mean_decl(a.mean_decl), ra_stddev(a.ra_stddev), decl_stddev(a.decl_stddev), mean_angular_distance(a.mean_angular_distance), angular_distance_stddev(a.angular_distance_stddev), mean_frequency(a.mean_frequency), frequency_stddev(a.frequency_stddev), mean_chirp(a.mean_chirp), chirp_stddev(a.chirp_stddev), mean_period(a.mean_period), period_stddev(a.period_stddev), mean_snr(a.mean_snr), snr_stddev(a.snr_stddev), mean_threshold(a.mean_threshold), threshold_stddev(a.threshold_stddev), score(a.score), num_detections(a.num_detections), signal_ids(a.signal_ids) { db_open(); } multiplet::multiplet(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } multiplet::multiplet(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } multiplet &multiplet::operator =(const multiplet &a) { if (&a != this) { id=a.id; version=a.version; signal_type=a.signal_type; mp_type=a.mp_type; qpix=a.qpix; freq_win=a.freq_win; mean_ra=a.mean_ra; mean_decl=a.mean_decl; ra_stddev=a.ra_stddev; decl_stddev=a.decl_stddev; mean_angular_distance=a.mean_angular_distance; angular_distance_stddev=a.angular_distance_stddev; mean_frequency=a.mean_frequency; frequency_stddev=a.frequency_stddev; mean_chirp=a.mean_chirp; chirp_stddev=a.chirp_stddev; mean_period=a.mean_period; period_stddev=a.period_stddev; mean_snr=a.mean_snr; snr_stddev=a.snr_stddev; mean_threshold=a.mean_threshold; threshold_stddev=a.threshold_stddev; score=a.score; num_detections=a.num_detections; { signal_ids.clear(); std::vector::const_iterator i(a.signal_ids.begin()); for (;i!=a.signal_ids.end();i++) { signal_ids.push_back(*i); } } } return (*this); } std::string multiplet::update_format() const { std::ostringstream rv(""); for (int i=2;i<25;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string multiplet::insert_format() const { return std::string("?,")+update_format(); } std::string multiplet::select_format() const { std::string rv(""); for (int i=0; i<24;i++) rv+="?,"; rv+="?"; return rv; } std::string multiplet::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; rv << version; rv << ','; rv << signal_type; rv << ','; rv << mp_type; rv << ','; rv << qpix; rv << ','; rv << freq_win; rv << ','; rv << mean_ra; rv << ','; rv << mean_decl; rv << ','; rv << ra_stddev; rv << ','; rv << decl_stddev; rv << ','; rv << mean_angular_distance; rv << ','; rv << angular_distance_stddev; rv << ','; rv << mean_frequency; rv << ','; rv << frequency_stddev; rv << ','; rv << mean_chirp; rv << ','; rv << chirp_stddev; rv << ','; rv << mean_period; rv << ','; rv << period_stddev; rv << ','; rv << mean_snr; rv << ','; rv << snr_stddev; rv << ','; rv << mean_threshold; rv << ','; rv << threshold_stddev; rv << ','; rv << score; rv << ','; rv << num_detections; rv << ','; rv << "LIST {"; { std::vector::const_iterator p=signal_ids.begin(); for (;p\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; rv << xml_indent() << "" << version << "\n"; rv << xml_indent() << "" << signal_type << "\n"; rv << xml_indent() << "" << mp_type << "\n"; rv << xml_indent() << "" << qpix << "\n"; rv << xml_indent() << "" << freq_win << "\n"; rv << xml_indent() << "" << mean_ra << "\n"; rv << xml_indent() << "" << mean_decl << "\n"; rv << xml_indent() << "" << ra_stddev << "\n"; rv << xml_indent() << "" << decl_stddev << "\n"; rv << xml_indent() << "" << mean_angular_distance << "\n"; rv << xml_indent() << "" << angular_distance_stddev << "\n"; rv << xml_indent() << "" << mean_frequency << "\n"; rv << xml_indent() << "" << frequency_stddev << "\n"; rv << xml_indent() << "" << mean_chirp << "\n"; rv << xml_indent() << "" << chirp_stddev << "\n"; rv << xml_indent() << "" << mean_period << "\n"; rv << xml_indent() << "" << period_stddev << "\n"; rv << xml_indent() << "" << mean_snr << "\n"; rv << xml_indent() << "" << snr_stddev << "\n"; rv << xml_indent() << "" << mean_threshold << "\n"; rv << xml_indent() << "" << threshold_stddev << "\n"; rv << xml_indent() << "" << score << "\n"; rv << xml_indent() << "" << num_detections << "\n"; if (signal_ids.size()) { rv << xml_indent() << "" ; rv << enc_string; } } rv << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void multiplet::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"version",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> version; } if (extract_xml_record(field,"signal_type",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> signal_type; } if (extract_xml_record(field,"mp_type",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> mp_type; } if (extract_xml_record(field,"qpix",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> qpix; } if (extract_xml_record(field,"freq_win",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> freq_win; } if (extract_xml_record(field,"mean_ra",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> mean_ra; } if (extract_xml_record(field,"mean_decl",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> mean_decl; } if (extract_xml_record(field,"ra_stddev",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> ra_stddev; } if (extract_xml_record(field,"decl_stddev",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> decl_stddev; } if (extract_xml_record(field,"mean_angular_distance",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> mean_angular_distance; } if (extract_xml_record(field,"angular_distance_stddev",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> angular_distance_stddev; } if (extract_xml_record(field,"mean_frequency",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> mean_frequency; } if (extract_xml_record(field,"frequency_stddev",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> frequency_stddev; } if (extract_xml_record(field,"mean_chirp",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> mean_chirp; } if (extract_xml_record(field,"chirp_stddev",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> chirp_stddev; } if (extract_xml_record(field,"mean_period",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> mean_period; } if (extract_xml_record(field,"period_stddev",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> period_stddev; } if (extract_xml_record(field,"mean_snr",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> mean_snr; } if (extract_xml_record(field,"snr_stddev",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> snr_stddev; } if (extract_xml_record(field,"mean_threshold",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> mean_threshold; } if (extract_xml_record(field,"threshold_stddev",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> threshold_stddev; } if (extract_xml_record(field,"score",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> score; } if (extract_xml_record(field,"num_detections",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> num_detections; } signal_ids.clear(); if (extract_xml_record(field,"signal_ids",sub)) { pos=sub.find(">"); do { if (pos!=std::string::npos) { do { pos++; } while ((sub[pos]=='\n') || (sub[pos]==',')); std::istringstream in(std::string(sub.c_str()+pos)); sqlint8_t tmp; in >> tmp; signal_ids.push_back(tmp); } } while ((pos=sub.find(",",pos)) != std::string::npos); } } } void multiplet::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { std::istringstream row(*(s[1])); row >> version; } { std::istringstream row(*(s[2])); row >> signal_type; } { std::istringstream row(*(s[3])); row >> mp_type; } { std::istringstream row(*(s[4])); row >> qpix; } { std::istringstream row(*(s[5])); row >> freq_win; } { std::istringstream row(*(s[6])); row >> mean_ra; } { std::istringstream row(*(s[7])); row >> mean_decl; } { std::istringstream row(*(s[8])); row >> ra_stddev; } { std::istringstream row(*(s[9])); row >> decl_stddev; } { std::istringstream row(*(s[10])); row >> mean_angular_distance; } { std::istringstream row(*(s[11])); row >> angular_distance_stddev; } { std::istringstream row(*(s[12])); row >> mean_frequency; } { std::istringstream row(*(s[13])); row >> frequency_stddev; } { std::istringstream row(*(s[14])); row >> mean_chirp; } { std::istringstream row(*(s[15])); row >> chirp_stddev; } { std::istringstream row(*(s[16])); row >> mean_period; } { std::istringstream row(*(s[17])); row >> period_stddev; } { std::istringstream row(*(s[18])); row >> mean_snr; } { std::istringstream row(*(s[19])); row >> snr_stddev; } { std::istringstream row(*(s[20])); row >> mean_threshold; } { std::istringstream row(*(s[21])); row >> threshold_stddev; } { std::istringstream row(*(s[22])); row >> score; } { std::istringstream row(*(s[23])); row >> num_detections; } { std::string::size_type p,q; int i; signal_ids.clear(); SQL_ROW tmp(s[24]); for (i=0;i> tmp0; signal_ids.push_back(tmp0); } } } void multiplet::parse(const std::string &s) { SQL_ROW row(&s,25); parse(row); } template <> const char * const db_table::table_name="star"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=14; template <> const char * const db_table::column_names[14]={"id","object_type","catalog_name","catalog_number","object_name","ra","decl","qpix","v_mag","b_minus_v","parallax","stellar_type","planets","score"}; star::star() : db_table(*this,-1), id(0), catalog_number(0), ra(0), decl(0), qpix(0), v_mag(0), b_minus_v(0), parallax(0), planets(0), score(0) { db_open(); object_type[0]=0; catalog_name[0]=0; object_name[0]=0; stellar_type[0]=0; } star::star(const star &a) : db_table(*this,-1), id(a.id), catalog_number(a.catalog_number), ra(a.ra), decl(a.decl), qpix(a.qpix), v_mag(a.v_mag), b_minus_v(a.b_minus_v), parallax(a.parallax), planets(a.planets), score(a.score) { db_open(); strcpy(object_type,a.object_type); strcpy(catalog_name,a.catalog_name); strcpy(object_name,a.object_name); strcpy(stellar_type,a.stellar_type); } star::star(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } star::star(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } star &star::operator =(const star &a) { if (&a != this) { id=a.id; catalog_number=a.catalog_number; ra=a.ra; decl=a.decl; qpix=a.qpix; v_mag=a.v_mag; b_minus_v=a.b_minus_v; parallax=a.parallax; planets=a.planets; score=a.score; strcpy(object_type,a.object_type); strcpy(catalog_name,a.catalog_name); strcpy(object_name,a.object_name); strcpy(stellar_type,a.stellar_type); } return (*this); } std::string star::update_format() const { std::ostringstream rv(""); for (int i=2;i<14;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string star::insert_format() const { return std::string("?,")+update_format(); } std::string star::select_format() const { std::string rv(""); for (int i=0; i<13;i++) rv+="?,"; rv+="?"; return rv; } std::string star::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; rv << "'" << object_type << "'"; rv << ','; rv << "'" << catalog_name << "'"; rv << ','; rv << catalog_number; rv << ','; rv << "'" << object_name << "'"; rv << ','; rv << ra; rv << ','; rv << decl; rv << ','; rv << qpix; rv << ','; rv << v_mag; rv << ','; rv << b_minus_v; rv << ','; rv << parallax; rv << ','; rv << "'" << stellar_type << "'"; rv << ','; rv << planets; rv << ','; rv << score; return rv.str(); } std::string star::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; { std::string enc_field=xml_encode_string(object_type,std::min(strlen(object_type),sizeof(object_type))); rv << xml_indent() << ""; rv << enc_field << "\n"; } { std::string enc_field=xml_encode_string(catalog_name,std::min(strlen(catalog_name),sizeof(catalog_name))); rv << xml_indent() << ""; rv << enc_field << "\n"; } rv << xml_indent() << "" << catalog_number << "\n"; { std::string enc_field=xml_encode_string(object_name,std::min(strlen(object_name),sizeof(object_name))); rv << xml_indent() << ""; rv << enc_field << "\n"; } rv << xml_indent() << "" << ra << "\n"; rv << xml_indent() << "" << decl << "\n"; rv << xml_indent() << "" << qpix << "\n"; rv << xml_indent() << "" << v_mag << "\n"; rv << xml_indent() << "" << b_minus_v << "\n"; rv << xml_indent() << "" << parallax << "\n"; { std::string enc_field=xml_encode_string(stellar_type,std::min(strlen(stellar_type),sizeof(stellar_type))); rv << xml_indent() << ""; rv << enc_field << "\n"; } rv << xml_indent() << "" << planets << "\n"; rv << xml_indent() << "" << score << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void star::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"object_type",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::string::size_type epos=sub.find("<",pos); if (epos==std::string::npos) epos=sub.find('\n',pos); if (epos==std::string::npos) epos=pos+strlen(sub.c_str()+pos); std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); strncpy(object_type,(const char *)&(in.front()),std::min(in.size(),(size_t)16)); object_type[std::min(in.size(),(size_t)15)]=0; } if (extract_xml_record(field,"catalog_name",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::string::size_type epos=sub.find("<",pos); if (epos==std::string::npos) epos=sub.find('\n',pos); if (epos==std::string::npos) epos=pos+strlen(sub.c_str()+pos); std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); strncpy(catalog_name,(const char *)&(in.front()),std::min(in.size(),(size_t)64)); catalog_name[std::min(in.size(),(size_t)63)]=0; } if (extract_xml_record(field,"catalog_number",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> catalog_number; } if (extract_xml_record(field,"object_name",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::string::size_type epos=sub.find("<",pos); if (epos==std::string::npos) epos=sub.find('\n',pos); if (epos==std::string::npos) epos=pos+strlen(sub.c_str()+pos); std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); strncpy(object_name,(const char *)&(in.front()),std::min(in.size(),(size_t)64)); object_name[std::min(in.size(),(size_t)63)]=0; } if (extract_xml_record(field,"ra",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> ra; } if (extract_xml_record(field,"decl",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> decl; } if (extract_xml_record(field,"qpix",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> qpix; } if (extract_xml_record(field,"v_mag",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> v_mag; } if (extract_xml_record(field,"b_minus_v",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> b_minus_v; } if (extract_xml_record(field,"parallax",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> parallax; } if (extract_xml_record(field,"stellar_type",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::string::size_type epos=sub.find("<",pos); if (epos==std::string::npos) epos=sub.find('\n',pos); if (epos==std::string::npos) epos=pos+strlen(sub.c_str()+pos); std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); strncpy(stellar_type,(const char *)&(in.front()),std::min(in.size(),(size_t)32)); stellar_type[std::min(in.size(),(size_t)31)]=0; } if (extract_xml_record(field,"planets",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> planets; } if (extract_xml_record(field,"score",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> score; } } } void star::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { strncpy(object_type,s[1]->c_str(),16); object_type[15]=0; } { strncpy(catalog_name,s[2]->c_str(),64); catalog_name[63]=0; } { std::istringstream row(*(s[3])); row >> catalog_number; } { strncpy(object_name,s[4]->c_str(),64); object_name[63]=0; } { std::istringstream row(*(s[5])); row >> ra; } { std::istringstream row(*(s[6])); row >> decl; } { std::istringstream row(*(s[7])); row >> qpix; } { std::istringstream row(*(s[8])); row >> v_mag; } { std::istringstream row(*(s[9])); row >> b_minus_v; } { std::istringstream row(*(s[10])); row >> parallax; } { strncpy(stellar_type,s[11]->c_str(),32); stellar_type[31]=0; } { std::istringstream row(*(s[12])); row >> planets; } { std::istringstream row(*(s[13])); row >> score; } } void star::parse(const std::string &s) { SQL_ROW row(&s,14); parse(row); } template <> const char * const db_table::table_name="candidate_count"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=15; template <> const char * const db_table::column_names[15]={"id","spikes","gaussians","pulses","triplets","spike_barycentric_multiplets","gaussian_barycentric_multiplets","pulse_barycentric_multiplets","triplet_barycentric_multiplets","spike_nonbarycentric_multiplets","gaussian_nonbarycentric_multiplets","pulse_nonbarycentric_multiplets","triplet_nonbarycentric_multiplets","stars","time_last_updated"}; candidate_count::candidate_count() : db_table(*this,-1), id(0), spikes(0), gaussians(0), pulses(0), triplets(0), spike_barycentric_multiplets(0), gaussian_barycentric_multiplets(0), pulse_barycentric_multiplets(0), triplet_barycentric_multiplets(0), spike_nonbarycentric_multiplets(0), gaussian_nonbarycentric_multiplets(0), pulse_nonbarycentric_multiplets(0), triplet_nonbarycentric_multiplets(0), stars(0), time_last_updated(0) { db_open(); } candidate_count::candidate_count(const candidate_count &a) : db_table(*this,-1), id(a.id), spikes(a.spikes), gaussians(a.gaussians), pulses(a.pulses), triplets(a.triplets), spike_barycentric_multiplets(a.spike_barycentric_multiplets), gaussian_barycentric_multiplets(a.gaussian_barycentric_multiplets), pulse_barycentric_multiplets(a.pulse_barycentric_multiplets), triplet_barycentric_multiplets(a.triplet_barycentric_multiplets), spike_nonbarycentric_multiplets(a.spike_nonbarycentric_multiplets), gaussian_nonbarycentric_multiplets(a.gaussian_nonbarycentric_multiplets), pulse_nonbarycentric_multiplets(a.pulse_nonbarycentric_multiplets), triplet_nonbarycentric_multiplets(a.triplet_nonbarycentric_multiplets), stars(a.stars), time_last_updated(a.time_last_updated) { db_open(); } candidate_count::candidate_count(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } candidate_count::candidate_count(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } candidate_count &candidate_count::operator =(const candidate_count &a) { if (&a != this) { id=a.id; spikes=a.spikes; gaussians=a.gaussians; pulses=a.pulses; triplets=a.triplets; spike_barycentric_multiplets=a.spike_barycentric_multiplets; gaussian_barycentric_multiplets=a.gaussian_barycentric_multiplets; pulse_barycentric_multiplets=a.pulse_barycentric_multiplets; triplet_barycentric_multiplets=a.triplet_barycentric_multiplets; spike_nonbarycentric_multiplets=a.spike_nonbarycentric_multiplets; gaussian_nonbarycentric_multiplets=a.gaussian_nonbarycentric_multiplets; pulse_nonbarycentric_multiplets=a.pulse_nonbarycentric_multiplets; triplet_nonbarycentric_multiplets=a.triplet_nonbarycentric_multiplets; stars=a.stars; time_last_updated=a.time_last_updated; } return (*this); } std::string candidate_count::update_format() const { std::ostringstream rv(""); for (int i=2;i<15;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string candidate_count::insert_format() const { return std::string("?,")+update_format(); } std::string candidate_count::select_format() const { std::string rv(""); for (int i=0; i<14;i++) rv+="?,"; rv+="?"; return rv; } std::string candidate_count::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; rv << spikes; rv << ','; rv << gaussians; rv << ','; rv << pulses; rv << ','; rv << triplets; rv << ','; rv << spike_barycentric_multiplets; rv << ','; rv << gaussian_barycentric_multiplets; rv << ','; rv << pulse_barycentric_multiplets; rv << ','; rv << triplet_barycentric_multiplets; rv << ','; rv << spike_nonbarycentric_multiplets; rv << ','; rv << gaussian_nonbarycentric_multiplets; rv << ','; rv << pulse_nonbarycentric_multiplets; rv << ','; rv << triplet_nonbarycentric_multiplets; rv << ','; rv << stars; rv << ','; rv << time_last_updated; return rv.str(); } std::string candidate_count::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; rv << xml_indent() << "" << spikes << "\n"; rv << xml_indent() << "" << gaussians << "\n"; rv << xml_indent() << "" << pulses << "\n"; rv << xml_indent() << "" << triplets << "\n"; rv << xml_indent() << "" << spike_barycentric_multiplets << "\n"; rv << xml_indent() << "" << gaussian_barycentric_multiplets << "\n"; rv << xml_indent() << "" << pulse_barycentric_multiplets << "\n"; rv << xml_indent() << "" << triplet_barycentric_multiplets << "\n"; rv << xml_indent() << "" << spike_nonbarycentric_multiplets << "\n"; rv << xml_indent() << "" << gaussian_nonbarycentric_multiplets << "\n"; rv << xml_indent() << "" << pulse_nonbarycentric_multiplets << "\n"; rv << xml_indent() << "" << triplet_nonbarycentric_multiplets << "\n"; rv << xml_indent() << "" << stars << "\n"; rv << xml_indent() << "" << time_last_updated << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void candidate_count::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"spikes",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> spikes; } if (extract_xml_record(field,"gaussians",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> gaussians; } if (extract_xml_record(field,"pulses",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> pulses; } if (extract_xml_record(field,"triplets",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> triplets; } if (extract_xml_record(field,"spike_barycentric_multiplets",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> spike_barycentric_multiplets; } if (extract_xml_record(field,"gaussian_barycentric_multiplets",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> gaussian_barycentric_multiplets; } if (extract_xml_record(field,"pulse_barycentric_multiplets",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> pulse_barycentric_multiplets; } if (extract_xml_record(field,"triplet_barycentric_multiplets",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> triplet_barycentric_multiplets; } if (extract_xml_record(field,"spike_nonbarycentric_multiplets",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> spike_nonbarycentric_multiplets; } if (extract_xml_record(field,"gaussian_nonbarycentric_multiplets",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> gaussian_nonbarycentric_multiplets; } if (extract_xml_record(field,"pulse_nonbarycentric_multiplets",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> pulse_nonbarycentric_multiplets; } if (extract_xml_record(field,"triplet_nonbarycentric_multiplets",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> triplet_nonbarycentric_multiplets; } if (extract_xml_record(field,"stars",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> stars; } if (extract_xml_record(field,"time_last_updated",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> time_last_updated; } } } void candidate_count::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { std::istringstream row(*(s[1])); row >> spikes; } { std::istringstream row(*(s[2])); row >> gaussians; } { std::istringstream row(*(s[3])); row >> pulses; } { std::istringstream row(*(s[4])); row >> triplets; } { std::istringstream row(*(s[5])); row >> spike_barycentric_multiplets; } { std::istringstream row(*(s[6])); row >> gaussian_barycentric_multiplets; } { std::istringstream row(*(s[7])); row >> pulse_barycentric_multiplets; } { std::istringstream row(*(s[8])); row >> triplet_barycentric_multiplets; } { std::istringstream row(*(s[9])); row >> spike_nonbarycentric_multiplets; } { std::istringstream row(*(s[10])); row >> gaussian_nonbarycentric_multiplets; } { std::istringstream row(*(s[11])); row >> pulse_nonbarycentric_multiplets; } { std::istringstream row(*(s[12])); row >> triplet_nonbarycentric_multiplets; } { std::istringstream row(*(s[13])); row >> stars; } { std::istringstream row(*(s[14])); row >> time_last_updated; } } void candidate_count::parse(const std::string &s) { SQL_ROW row(&s,15); parse(row); } template <> const char * const db_table::table_name="tape"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=8; template <> const char * const db_table::column_names[8]={"id","name","start_time","last_block_time","last_block_done","missed","tape_quality","beam"}; tape::tape() : db_table(*this,-1), id(0), start_time(0), last_block_time(0), last_block_done(0), missed(0), tape_quality(0), beam(0) { db_open(); name[0]=0; } tape::tape(const tape &a) : db_table(*this,-1), id(a.id), start_time(a.start_time), last_block_time(a.last_block_time), last_block_done(a.last_block_done), missed(a.missed), tape_quality(a.tape_quality), beam(a.beam) { db_open(); strcpy(name,a.name); } tape::tape(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } tape::tape(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } tape &tape::operator =(const tape &a) { if (&a != this) { id=a.id; start_time=a.start_time; last_block_time=a.last_block_time; last_block_done=a.last_block_done; missed=a.missed; tape_quality=a.tape_quality; beam=a.beam; strcpy(name,a.name); } return (*this); } std::string tape::update_format() const { std::ostringstream rv(""); for (int i=2;i<8;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string tape::insert_format() const { return std::string("?,")+update_format(); } std::string tape::select_format() const { std::string rv(""); for (int i=0; i<7;i++) rv+="?,"; rv+="?"; return rv; } std::string tape::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; rv << "'" << name << "'"; rv << ','; rv << start_time; rv << ','; rv << last_block_time; rv << ','; rv << last_block_done; rv << ','; rv << missed; rv << ','; rv << tape_quality; rv << ','; rv << beam; return rv.str(); } std::string tape::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; { std::string enc_field=xml_encode_string(name,std::min(strlen(name),sizeof(name))); rv << xml_indent() << ""; rv << enc_field << "\n"; } rv << xml_indent() << "" << start_time << "\n"; rv << xml_indent() << "" << last_block_time << "\n"; rv << xml_indent() << "" << last_block_done << "\n"; rv << xml_indent() << "" << missed << "\n"; rv << xml_indent() << "" << tape_quality << "\n"; rv << xml_indent() << "" << beam << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void tape::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"name",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::string::size_type epos=sub.find("<",pos); if (epos==std::string::npos) epos=sub.find('\n',pos); if (epos==std::string::npos) epos=pos+strlen(sub.c_str()+pos); std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); strncpy(name,(const char *)&(in.front()),std::min(in.size(),(size_t)128)); name[std::min(in.size(),(size_t)127)]=0; } if (extract_xml_record(field,"start_time",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> start_time; } if (extract_xml_record(field,"last_block_time",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> last_block_time; } if (extract_xml_record(field,"last_block_done",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> last_block_done; } if (extract_xml_record(field,"missed",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> missed; } if (extract_xml_record(field,"tape_quality",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> tape_quality; } if (extract_xml_record(field,"beam",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> beam; } } } void tape::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { strncpy(name,s[1]->c_str(),128); name[127]=0; } { std::istringstream row(*(s[2])); row >> start_time; } { std::istringstream row(*(s[3])); row >> last_block_time; } { std::istringstream row(*(s[4])); row >> last_block_done; } { std::istringstream row(*(s[5])); row >> missed; } { std::istringstream row(*(s[6])); row >> tape_quality; } { std::istringstream row(*(s[7])); row >> beam; } } void tape::parse(const std::string &s) { SQL_ROW row(&s,8); parse(row); } template <> const char * const db_table::table_name="settings"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=6; template <> const char * const db_table::column_names[6]={"id","active","recorder_cfg","splitter_cfg","analysis_cfg","receiver_cfg"}; settings::settings() : db_table(*this,-1), id(0), active(0), recorder_cfg(), splitter_cfg(), analysis_cfg(), receiver_cfg() { db_open(); } settings::settings(const settings &a) : db_table(*this,-1), id(a.id), active(a.active), recorder_cfg(a.recorder_cfg), splitter_cfg(a.splitter_cfg), analysis_cfg(a.analysis_cfg), receiver_cfg(a.receiver_cfg) { db_open(); } settings::settings(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } settings::settings(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } settings &settings::operator =(const settings &a) { if (&a != this) { id=a.id; active=a.active; recorder_cfg=a.recorder_cfg; splitter_cfg=a.splitter_cfg; analysis_cfg=a.analysis_cfg; receiver_cfg=a.receiver_cfg; } return (*this); } std::string settings::update_format() const { std::ostringstream rv(""); for (int i=2;i<6;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string settings::insert_format() const { return std::string("?,")+update_format(); } std::string settings::select_format() const { std::string rv(""); for (int i=0; i<5;i++) rv+="?,"; rv+="?"; return rv; } std::string settings::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; rv << active; rv << ','; if (!no_refs) { if (full_subtables) { rv << recorder_cfg.print(full_subtables,show_ids,no_refs); } else { rv << recorder_cfg.id; } } rv << ','; if (!no_refs) { if (full_subtables) { rv << splitter_cfg.print(full_subtables,show_ids,no_refs); } else { rv << splitter_cfg.id; } } rv << ','; if (!no_refs) { if (full_subtables) { rv << analysis_cfg.print(full_subtables,show_ids,no_refs); } else { rv << analysis_cfg.id; } } rv << ','; if (!no_refs) { if (full_subtables) { rv << receiver_cfg.print(full_subtables,show_ids,no_refs); } else { rv << receiver_cfg.id; } } return rv.str(); } std::string settings::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; rv << xml_indent() << "" << active << "\n"; if (!no_refs) { if (full_subtables) { rv << recorder_cfg.print_xml(full_subtables,show_ids,no_refs,"recorder_cfg"); } else { rv << xml_indent() << "" << recorder_cfg.id << "\n"; } } if (!no_refs) { if (full_subtables) { rv << splitter_cfg.print_xml(full_subtables,show_ids,no_refs,"splitter_cfg"); } else { rv << xml_indent() << "" << splitter_cfg.id << "\n"; } } if (!no_refs) { if (full_subtables) { rv << analysis_cfg.print_xml(full_subtables,show_ids,no_refs,"analysis_cfg"); } else { rv << xml_indent() << "" << analysis_cfg.id << "\n"; } } if (!no_refs) { if (full_subtables) { rv << receiver_cfg.print_xml(full_subtables,show_ids,no_refs,"receiver_cfg"); } else { rv << xml_indent() << "" << receiver_cfg.id << "\n"; } } xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void settings::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"active",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> active; } if (extract_xml_record(field,"recorder_cfg",sub)) { recorder_cfg.parse_xml(sub,"recorder_cfg"); } if (extract_xml_record(field,"splitter_cfg",sub)) { splitter_cfg.parse_xml(sub,"splitter_cfg"); } if (extract_xml_record(field,"analysis_cfg",sub)) { analysis_cfg.parse_xml(sub,"analysis_cfg"); } if (extract_xml_record(field,"receiver_cfg",sub)) { receiver_cfg.parse_xml(sub,"receiver_cfg"); } } } void settings::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { std::istringstream row(*(s[1])); row >> active; } { recorder_cfg.parse(SQL_ROW(s[2],0)); } { splitter_cfg.parse(SQL_ROW(s[3],0)); } { analysis_cfg.parse(SQL_ROW(s[4],0)); } { receiver_cfg.parse(SQL_ROW(s[5],0)); } } void settings::parse(const std::string &s) { SQL_ROW row(&s,6); parse(row); } template <> const char * const db_table::table_name="workunit_grp"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=11; template <> const char * const db_table::column_names[11]={"id","tape_info","name","data_desc","receiver_cfg","recorder_cfg","splitter_cfg","analysis_cfg","sb_id","iq_modified","alfa_filter_bank"}; workunit_grp::workunit_grp() : db_table(*this,-1), id(0), tape_info(), data_desc(), receiver_cfg(), recorder_cfg(), splitter_cfg(), analysis_cfg(), sb_id(0), iq_modified(0), alfa_filter_bank(0) { db_open(); name[0]=0; } workunit_grp::workunit_grp(const workunit_grp &a) : db_table(*this,-1), id(a.id), tape_info(a.tape_info), data_desc(a.data_desc), receiver_cfg(a.receiver_cfg), recorder_cfg(a.recorder_cfg), splitter_cfg(a.splitter_cfg), analysis_cfg(a.analysis_cfg), sb_id(a.sb_id), iq_modified(a.iq_modified), alfa_filter_bank(a.alfa_filter_bank) { db_open(); strcpy(name,a.name); } workunit_grp::workunit_grp(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } workunit_grp::workunit_grp(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } workunit_grp &workunit_grp::operator =(const workunit_grp &a) { if (&a != this) { id=a.id; tape_info=a.tape_info; data_desc=a.data_desc; receiver_cfg=a.receiver_cfg; recorder_cfg=a.recorder_cfg; splitter_cfg=a.splitter_cfg; analysis_cfg=a.analysis_cfg; sb_id=a.sb_id; iq_modified=a.iq_modified; alfa_filter_bank=a.alfa_filter_bank; strcpy(name,a.name); } return (*this); } std::string workunit_grp::update_format() const { std::ostringstream rv(""); for (int i=2;i<11;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string workunit_grp::insert_format() const { return std::string("?,")+update_format(); } std::string workunit_grp::select_format() const { std::string rv(""); for (int i=0; i<10;i++) rv+="?,"; rv+="?"; return rv; } std::string workunit_grp::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; if (!no_refs) { if (full_subtables) { rv << tape_info.print(full_subtables,show_ids,no_refs); } else { rv << tape_info.id; } } rv << ','; rv << "'" << name << "'"; rv << ','; rv << data_desc.print(full_subtables,show_ids,no_refs); rv << ','; if (!no_refs) { if (full_subtables) { rv << receiver_cfg.print(full_subtables,show_ids,no_refs); } else { rv << receiver_cfg.id; } } rv << ','; if (!no_refs) { if (full_subtables) { rv << recorder_cfg.print(full_subtables,show_ids,no_refs); } else { rv << recorder_cfg.id; } } rv << ','; if (!no_refs) { if (full_subtables) { rv << splitter_cfg.print(full_subtables,show_ids,no_refs); } else { rv << splitter_cfg.id; } } rv << ','; if (!no_refs) { if (full_subtables) { rv << analysis_cfg.print(full_subtables,show_ids,no_refs); } else { rv << analysis_cfg.id; } } rv << ','; rv << sb_id; rv << ','; rv << iq_modified; rv << ','; rv << alfa_filter_bank; return rv.str(); } std::string workunit_grp::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; if (!no_refs) { if (full_subtables) { rv << tape_info.print_xml(full_subtables,show_ids,no_refs,"tape_info"); } else { rv << xml_indent() << "" << tape_info.id << "\n"; } } { std::string enc_field=xml_encode_string(name,std::min(strlen(name),sizeof(name))); rv << xml_indent() << ""; rv << enc_field << "\n"; } rv << data_desc.print_xml(full_subtables,show_ids,no_refs,"data_desc"); if (!no_refs) { if (full_subtables) { rv << receiver_cfg.print_xml(full_subtables,show_ids,no_refs,"receiver_cfg"); } else { rv << xml_indent() << "" << receiver_cfg.id << "\n"; } } if (!no_refs) { if (full_subtables) { rv << recorder_cfg.print_xml(full_subtables,show_ids,no_refs,"recorder_cfg"); } else { rv << xml_indent() << "" << recorder_cfg.id << "\n"; } } if (!no_refs) { if (full_subtables) { rv << splitter_cfg.print_xml(full_subtables,show_ids,no_refs,"splitter_cfg"); } else { rv << xml_indent() << "" << splitter_cfg.id << "\n"; } } if (!no_refs) { if (full_subtables) { rv << analysis_cfg.print_xml(full_subtables,show_ids,no_refs,"analysis_cfg"); } else { rv << xml_indent() << "" << analysis_cfg.id << "\n"; } } rv << xml_indent() << "" << sb_id << "\n"; rv << xml_indent() << "" << iq_modified << "\n"; rv << xml_indent() << "" << alfa_filter_bank << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void workunit_grp::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"tape_info",sub)) { tape_info.parse_xml(sub,"tape_info"); } if (extract_xml_record(field,"name",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::string::size_type epos=sub.find("<",pos); if (epos==std::string::npos) epos=sub.find('\n',pos); if (epos==std::string::npos) epos=pos+strlen(sub.c_str()+pos); std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); strncpy(name,(const char *)&(in.front()),std::min(in.size(),(size_t)128)); name[std::min(in.size(),(size_t)127)]=0; } if (extract_xml_record(field,"data_desc",sub)) { data_desc.parse_xml(sub,"data_desc"); } if (extract_xml_record(field,"receiver_cfg",sub)) { receiver_cfg.parse_xml(sub,"receiver_cfg"); } if (extract_xml_record(field,"recorder_cfg",sub)) { recorder_cfg.parse_xml(sub,"recorder_cfg"); } if (extract_xml_record(field,"splitter_cfg",sub)) { splitter_cfg.parse_xml(sub,"splitter_cfg"); } if (extract_xml_record(field,"analysis_cfg",sub)) { analysis_cfg.parse_xml(sub,"analysis_cfg"); } if (extract_xml_record(field,"sb_id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> sb_id; } if (extract_xml_record(field,"iq_modified",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> iq_modified; } if (extract_xml_record(field,"alfa_filter_bank",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> alfa_filter_bank; } } } void workunit_grp::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { tape_info.parse(SQL_ROW(s[1],0)); } { strncpy(name,s[2]->c_str(),128); name[127]=0; } { data_desc.parse(SQL_ROW(s[3],0)); } { receiver_cfg.parse(SQL_ROW(s[4],0)); } { recorder_cfg.parse(SQL_ROW(s[5],0)); } { splitter_cfg.parse(SQL_ROW(s[6],0)); } { analysis_cfg.parse(SQL_ROW(s[7],0)); } { std::istringstream row(*(s[8])); row >> sb_id; } { std::istringstream row(*(s[9])); row >> iq_modified; } { std::istringstream row(*(s[10])); row >> alfa_filter_bank; } } void workunit_grp::parse(const std::string &s) { SQL_ROW row(&s,11); parse(row); } template <> const char * const db_table::table_name="workunit_header"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=5; template <> const char * const db_table::column_names[5]={"id","name","group_info","subband_desc","sb_id"}; workunit_header::workunit_header() : db_table(*this,-1), id(0), group_info(), subband_desc(), sb_id(0) { db_open(); name[0]=0; } workunit_header::workunit_header(const workunit_header &a) : db_table(*this,-1), id(a.id), group_info(a.group_info), subband_desc(a.subband_desc), sb_id(a.sb_id) { db_open(); strcpy(name,a.name); } workunit_header::workunit_header(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } workunit_header::workunit_header(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } workunit_header &workunit_header::operator =(const workunit_header &a) { if (&a != this) { id=a.id; group_info=a.group_info; subband_desc=a.subband_desc; sb_id=a.sb_id; strcpy(name,a.name); } return (*this); } std::string workunit_header::update_format() const { std::ostringstream rv(""); for (int i=2;i<5;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string workunit_header::insert_format() const { return std::string("?,")+update_format(); } std::string workunit_header::select_format() const { std::string rv(""); for (int i=0; i<4;i++) rv+="?,"; rv+="?"; return rv; } std::string workunit_header::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; rv << "'" << name << "'"; rv << ','; if (!no_refs) { if (full_subtables) { rv << group_info.print(full_subtables,show_ids,no_refs); } else { rv << group_info.id; } } rv << ','; rv << subband_desc.print(full_subtables,show_ids,no_refs); rv << ','; rv << sb_id; return rv.str(); } std::string workunit_header::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; { std::string enc_field=xml_encode_string(name,std::min(strlen(name),sizeof(name))); rv << xml_indent() << ""; rv << enc_field << "\n"; } if (!no_refs) { if (full_subtables) { rv << group_info.print_xml(full_subtables,show_ids,no_refs,"group_info"); } else { rv << xml_indent() << "" << group_info.id << "\n"; } } rv << subband_desc.print_xml(full_subtables,show_ids,no_refs,"subband_desc"); rv << xml_indent() << "" << sb_id << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void workunit_header::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"name",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::string::size_type epos=sub.find("<",pos); if (epos==std::string::npos) epos=sub.find('\n',pos); if (epos==std::string::npos) epos=pos+strlen(sub.c_str()+pos); std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); strncpy(name,(const char *)&(in.front()),std::min(in.size(),(size_t)128)); name[std::min(in.size(),(size_t)127)]=0; } if (extract_xml_record(field,"group_info",sub)) { group_info.parse_xml(sub,"group_info"); } if (extract_xml_record(field,"subband_desc",sub)) { subband_desc.parse_xml(sub,"subband_desc"); } if (extract_xml_record(field,"sb_id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> sb_id; } } } void workunit_header::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { strncpy(name,s[1]->c_str(),128); name[127]=0; } { group_info.parse(SQL_ROW(s[2],0)); } { subband_desc.parse(SQL_ROW(s[3],0)); } { std::istringstream row(*(s[4])); row >> sb_id; } } void workunit_header::parse(const std::string &s) { SQL_ROW row(&s,5); parse(row); } template <> const char * const db_table::table_name="result"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=10; template <> const char * const db_table::column_names[10]={"id","boinc_result","wuid","received","hostid","versionid","return_code","overflow","reserved","sb_id"}; result::result() : db_table(*this,-1), id(0), boinc_result(0), wuid(), received(0), hostid(0), versionid(0), return_code(0), overflow(0), reserved(0), sb_id(0) { db_open(); } result::result(const result &a) : db_table(*this,-1), id(a.id), boinc_result(a.boinc_result), wuid(a.wuid), received(a.received), hostid(a.hostid), versionid(a.versionid), return_code(a.return_code), overflow(a.overflow), reserved(a.reserved), sb_id(a.sb_id) { db_open(); } result::result(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } result::result(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } result &result::operator =(const result &a) { if (&a != this) { id=a.id; boinc_result=a.boinc_result; wuid=a.wuid; received=a.received; hostid=a.hostid; versionid=a.versionid; return_code=a.return_code; overflow=a.overflow; reserved=a.reserved; sb_id=a.sb_id; } return (*this); } std::string result::update_format() const { std::ostringstream rv(""); for (int i=2;i<10;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string result::insert_format() const { return std::string("?,")+update_format(); } std::string result::select_format() const { std::string rv(""); for (int i=0; i<9;i++) rv+="?,"; rv+="?"; return rv; } std::string result::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; rv << boinc_result; rv << ','; if (!no_refs) { if (full_subtables) { rv << wuid.print(full_subtables,show_ids,no_refs); } else { rv << wuid.id; } } rv << ','; rv << received; rv << ','; rv << hostid; rv << ','; rv << versionid; rv << ','; rv << return_code; rv << ','; rv << overflow; rv << ','; rv << reserved; rv << ','; rv << sb_id; return rv.str(); } std::string result::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; rv << xml_indent() << "" << boinc_result << "\n"; if (!no_refs) { if (full_subtables) { rv << wuid.print_xml(full_subtables,show_ids,no_refs,"wuid"); } else { rv << xml_indent() << "" << wuid.id << "\n"; } } rv << xml_indent() << "" << received << "\n"; rv << xml_indent() << "" << hostid << "\n"; rv << xml_indent() << "" << versionid << "\n"; rv << xml_indent() << "" << return_code << "\n"; rv << xml_indent() << "" << overflow << "\n"; rv << xml_indent() << "" << reserved << "\n"; rv << xml_indent() << "" << sb_id << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void result::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"boinc_result",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> boinc_result; } if (extract_xml_record(field,"wuid",sub)) { wuid.parse_xml(sub,"wuid"); } if (extract_xml_record(field,"received",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> received; } if (extract_xml_record(field,"hostid",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> hostid; } if (extract_xml_record(field,"versionid",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> versionid; } if (extract_xml_record(field,"return_code",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> return_code; } if (extract_xml_record(field,"overflow",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> overflow; } if (extract_xml_record(field,"reserved",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> reserved; } if (extract_xml_record(field,"sb_id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> sb_id; } } } void result::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { std::istringstream row(*(s[1])); row >> boinc_result; } { wuid.parse(SQL_ROW(s[2],0)); } { std::istringstream row(*(s[3])); row >> received; } { std::istringstream row(*(s[4])); row >> hostid; } { std::istringstream row(*(s[5])); row >> versionid; } { std::istringstream row(*(s[6])); row >> return_code; } { std::istringstream row(*(s[7])); row >> overflow; } { std::istringstream row(*(s[8])); row >> reserved; } { std::istringstream row(*(s[9])); row >> sb_id; } } void result::parse(const std::string &s) { SQL_ROW row(&s,10); parse(row); } template <> const char * const db_table::table_name="triplet"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=17; template <> const char * const db_table::column_names[17]={"id","result_id","peak_power","mean_power","time","ra","decl","q_pix","freq","detection_freq","barycentric_freq","fft_len","chirp_rate","rfi_checked","rfi_found","reserved","period"}; triplet::triplet() : db_table(*this,-1), id(0), result_id(), peak_power(0), mean_power(0), time(0), ra(0), decl(0), q_pix(0), freq(0), detection_freq(0), barycentric_freq(0), fft_len(0), chirp_rate(0), rfi_checked(0), rfi_found(0), reserved(0), period(0) { db_open(); } triplet::triplet(const triplet &a) : db_table(*this,-1), id(a.id), result_id(a.result_id), peak_power(a.peak_power), mean_power(a.mean_power), time(a.time), ra(a.ra), decl(a.decl), q_pix(a.q_pix), freq(a.freq), detection_freq(a.detection_freq), barycentric_freq(a.barycentric_freq), fft_len(a.fft_len), chirp_rate(a.chirp_rate), rfi_checked(a.rfi_checked), rfi_found(a.rfi_found), reserved(a.reserved), period(a.period) { db_open(); } triplet::triplet(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } triplet::triplet(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } triplet &triplet::operator =(const triplet &a) { if (&a != this) { id=a.id; result_id=a.result_id; peak_power=a.peak_power; mean_power=a.mean_power; time=a.time; ra=a.ra; decl=a.decl; q_pix=a.q_pix; freq=a.freq; detection_freq=a.detection_freq; barycentric_freq=a.barycentric_freq; fft_len=a.fft_len; chirp_rate=a.chirp_rate; rfi_checked=a.rfi_checked; rfi_found=a.rfi_found; reserved=a.reserved; period=a.period; } return (*this); } std::string triplet::update_format() const { std::ostringstream rv(""); for (int i=2;i<17;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string triplet::insert_format() const { return std::string("?,")+update_format(); } std::string triplet::select_format() const { std::string rv(""); for (int i=0; i<16;i++) rv+="?,"; rv+="?"; return rv; } std::string triplet::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; if (!no_refs) { if (full_subtables) { rv << result_id.print(full_subtables,show_ids,no_refs); } else { rv << result_id.id; } } rv << ','; rv << peak_power; rv << ','; rv << mean_power; rv << ','; rv << time; rv << ','; rv << ra; rv << ','; rv << decl; rv << ','; rv << q_pix; rv << ','; rv << freq; rv << ','; rv << detection_freq; rv << ','; rv << barycentric_freq; rv << ','; rv << fft_len; rv << ','; rv << chirp_rate; rv << ','; rv << rfi_checked; rv << ','; rv << rfi_found; rv << ','; rv << reserved; rv << ','; rv << period; return rv.str(); } std::string triplet::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; if (!no_refs) { if (full_subtables) { rv << result_id.print_xml(full_subtables,show_ids,no_refs,"result_id"); } else { rv << xml_indent() << "" << result_id.id << "\n"; } } rv << xml_indent() << "" << peak_power << "\n"; rv << xml_indent() << "" << mean_power << "\n"; rv << xml_indent() << "\n"; rv << xml_indent() << "" << ra << "\n"; rv << xml_indent() << "" << decl << "\n"; rv << xml_indent() << "" << q_pix << "\n"; rv << xml_indent() << "" << freq << "\n"; rv << xml_indent() << "" << detection_freq << "\n"; rv << xml_indent() << "" << barycentric_freq << "\n"; rv << xml_indent() << "" << fft_len << "\n"; rv << xml_indent() << "" << chirp_rate << "\n"; rv << xml_indent() << "" << rfi_checked << "\n"; rv << xml_indent() << "" << rfi_found << "\n"; rv << xml_indent() << "" << reserved << "\n"; rv << xml_indent() << "" << period << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void triplet::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"result_id",sub)) { result_id.parse_xml(sub,"result_id"); } if (extract_xml_record(field,"peak_power",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> peak_power; } if (extract_xml_record(field,"mean_power",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> mean_power; } if (extract_xml_record(field,"time",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> time; } if (extract_xml_record(field,"ra",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> ra; } if (extract_xml_record(field,"decl",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> decl; } if (extract_xml_record(field,"q_pix",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> q_pix; } if (extract_xml_record(field,"freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> freq; } if (extract_xml_record(field,"detection_freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> detection_freq; } if (extract_xml_record(field,"barycentric_freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> barycentric_freq; } if (extract_xml_record(field,"fft_len",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> fft_len; } if (extract_xml_record(field,"chirp_rate",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> chirp_rate; } if (extract_xml_record(field,"rfi_checked",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> rfi_checked; } if (extract_xml_record(field,"rfi_found",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> rfi_found; } if (extract_xml_record(field,"reserved",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> reserved; } if (extract_xml_record(field,"period",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> period; } } } void triplet::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { result_id.parse(SQL_ROW(s[1],0)); } { std::istringstream row(*(s[2])); row >> peak_power; } { std::istringstream row(*(s[3])); row >> mean_power; } { std::istringstream row(*(s[4])); row >> time; } { std::istringstream row(*(s[5])); row >> ra; } { std::istringstream row(*(s[6])); row >> decl; } { std::istringstream row(*(s[7])); row >> q_pix; } { std::istringstream row(*(s[8])); row >> freq; } { std::istringstream row(*(s[9])); row >> detection_freq; } { std::istringstream row(*(s[10])); row >> barycentric_freq; } { std::istringstream row(*(s[11])); row >> fft_len; } { std::istringstream row(*(s[12])); row >> chirp_rate; } { std::istringstream row(*(s[13])); row >> rfi_checked; } { std::istringstream row(*(s[14])); row >> rfi_found; } { std::istringstream row(*(s[15])); row >> reserved; } { std::istringstream row(*(s[16])); row >> period; } } void triplet::parse(const std::string &s) { SQL_ROW row(&s,17); parse(row); } template <> const char * const db_table::table_name="triplet_small"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=17; template <> const char * const db_table::column_names[17]={"id","result_id","peak_power","mean_power","time","ra","decl","q_pix","freq","detection_freq","barycentric_freq","fft_len","chirp_rate","rfi_checked","rfi_found","reserved","period"}; triplet_small::triplet_small() : db_table(*this,-1), id(0), result_id(), peak_power(0), mean_power(0), time(0), ra(0), decl(0), q_pix(0), freq(0), detection_freq(0), barycentric_freq(0), fft_len(0), chirp_rate(0), rfi_checked(0), rfi_found(0), reserved(0), period(0) { db_open(); } triplet_small::triplet_small(const triplet_small &a) : db_table(*this,-1), id(a.id), result_id(a.result_id), peak_power(a.peak_power), mean_power(a.mean_power), time(a.time), ra(a.ra), decl(a.decl), q_pix(a.q_pix), freq(a.freq), detection_freq(a.detection_freq), barycentric_freq(a.barycentric_freq), fft_len(a.fft_len), chirp_rate(a.chirp_rate), rfi_checked(a.rfi_checked), rfi_found(a.rfi_found), reserved(a.reserved), period(a.period) { db_open(); } triplet_small::triplet_small(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } triplet_small::triplet_small(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } triplet_small &triplet_small::operator =(const triplet_small &a) { if (&a != this) { id=a.id; result_id=a.result_id; peak_power=a.peak_power; mean_power=a.mean_power; time=a.time; ra=a.ra; decl=a.decl; q_pix=a.q_pix; freq=a.freq; detection_freq=a.detection_freq; barycentric_freq=a.barycentric_freq; fft_len=a.fft_len; chirp_rate=a.chirp_rate; rfi_checked=a.rfi_checked; rfi_found=a.rfi_found; reserved=a.reserved; period=a.period; } return (*this); } std::string triplet_small::update_format() const { std::ostringstream rv(""); for (int i=2;i<17;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string triplet_small::insert_format() const { return std::string("?,")+update_format(); } std::string triplet_small::select_format() const { std::string rv(""); for (int i=0; i<16;i++) rv+="?,"; rv+="?"; return rv; } std::string triplet_small::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; if (!no_refs) { if (full_subtables) { rv << result_id.print(full_subtables,show_ids,no_refs); } else { rv << result_id.id; } } rv << ','; rv << peak_power; rv << ','; rv << mean_power; rv << ','; rv << time; rv << ','; rv << ra; rv << ','; rv << decl; rv << ','; rv << q_pix; rv << ','; rv << freq; rv << ','; rv << detection_freq; rv << ','; rv << barycentric_freq; rv << ','; rv << fft_len; rv << ','; rv << chirp_rate; rv << ','; rv << rfi_checked; rv << ','; rv << rfi_found; rv << ','; rv << reserved; rv << ','; rv << period; return rv.str(); } std::string triplet_small::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; if (!no_refs) { if (full_subtables) { rv << result_id.print_xml(full_subtables,show_ids,no_refs,"result_id"); } else { rv << xml_indent() << "" << result_id.id << "\n"; } } rv << xml_indent() << "" << peak_power << "\n"; rv << xml_indent() << "" << mean_power << "\n"; rv << xml_indent() << "\n"; rv << xml_indent() << "" << ra << "\n"; rv << xml_indent() << "" << decl << "\n"; rv << xml_indent() << "" << q_pix << "\n"; rv << xml_indent() << "" << freq << "\n"; rv << xml_indent() << "" << detection_freq << "\n"; rv << xml_indent() << "" << barycentric_freq << "\n"; rv << xml_indent() << "" << fft_len << "\n"; rv << xml_indent() << "" << chirp_rate << "\n"; rv << xml_indent() << "" << rfi_checked << "\n"; rv << xml_indent() << "" << rfi_found << "\n"; rv << xml_indent() << "" << reserved << "\n"; rv << xml_indent() << "" << period << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void triplet_small::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"result_id",sub)) { result_id.parse_xml(sub,"result_id"); } if (extract_xml_record(field,"peak_power",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> peak_power; } if (extract_xml_record(field,"mean_power",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> mean_power; } if (extract_xml_record(field,"time",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> time; } if (extract_xml_record(field,"ra",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> ra; } if (extract_xml_record(field,"decl",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> decl; } if (extract_xml_record(field,"q_pix",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> q_pix; } if (extract_xml_record(field,"freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> freq; } if (extract_xml_record(field,"detection_freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> detection_freq; } if (extract_xml_record(field,"barycentric_freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> barycentric_freq; } if (extract_xml_record(field,"fft_len",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> fft_len; } if (extract_xml_record(field,"chirp_rate",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> chirp_rate; } if (extract_xml_record(field,"rfi_checked",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> rfi_checked; } if (extract_xml_record(field,"rfi_found",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> rfi_found; } if (extract_xml_record(field,"reserved",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> reserved; } if (extract_xml_record(field,"period",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> period; } } } void triplet_small::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { result_id.parse(SQL_ROW(s[1],0)); } { std::istringstream row(*(s[2])); row >> peak_power; } { std::istringstream row(*(s[3])); row >> mean_power; } { std::istringstream row(*(s[4])); row >> time; } { std::istringstream row(*(s[5])); row >> ra; } { std::istringstream row(*(s[6])); row >> decl; } { std::istringstream row(*(s[7])); row >> q_pix; } { std::istringstream row(*(s[8])); row >> freq; } { std::istringstream row(*(s[9])); row >> detection_freq; } { std::istringstream row(*(s[10])); row >> barycentric_freq; } { std::istringstream row(*(s[11])); row >> fft_len; } { std::istringstream row(*(s[12])); row >> chirp_rate; } { std::istringstream row(*(s[13])); row >> rfi_checked; } { std::istringstream row(*(s[14])); row >> rfi_found; } { std::istringstream row(*(s[15])); row >> reserved; } { std::istringstream row(*(s[16])); row >> period; } } void triplet_small::parse(const std::string &s) { SQL_ROW row(&s,17); parse(row); } template <> const char * const db_table::table_name="gaussian"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=22; template <> const char * const db_table::column_names[22]={"id","result_id","peak_power","mean_power","time","ra","decl","q_pix","freq","detection_freq","barycentric_freq","fft_len","chirp_rate","rfi_checked","rfi_found","reserved","sigma","chisqr","null_chisqr","score","max_power","pot"}; gaussian::gaussian() : db_table(*this,-1), id(0), result_id(), peak_power(0), mean_power(0), time(0), ra(0), decl(0), q_pix(0), freq(0), detection_freq(0), barycentric_freq(0), fft_len(0), chirp_rate(0), rfi_checked(0), rfi_found(0), reserved(0), sigma(0), chisqr(0), null_chisqr(0), score(0), max_power(0), pot((unsigned char *)0,0,_x_csv) { db_open(); } gaussian::gaussian(const gaussian &a) : db_table(*this,-1), id(a.id), result_id(a.result_id), peak_power(a.peak_power), mean_power(a.mean_power), time(a.time), ra(a.ra), decl(a.decl), q_pix(a.q_pix), freq(a.freq), detection_freq(a.detection_freq), barycentric_freq(a.barycentric_freq), fft_len(a.fft_len), chirp_rate(a.chirp_rate), rfi_checked(a.rfi_checked), rfi_found(a.rfi_found), reserved(a.reserved), sigma(a.sigma), chisqr(a.chisqr), null_chisqr(a.null_chisqr), score(a.score), max_power(a.max_power), pot(a.pot) { db_open(); } gaussian::gaussian(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } gaussian::gaussian(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } gaussian &gaussian::operator =(const gaussian &a) { if (&a != this) { id=a.id; result_id=a.result_id; peak_power=a.peak_power; mean_power=a.mean_power; time=a.time; ra=a.ra; decl=a.decl; q_pix=a.q_pix; freq=a.freq; detection_freq=a.detection_freq; barycentric_freq=a.barycentric_freq; fft_len=a.fft_len; chirp_rate=a.chirp_rate; rfi_checked=a.rfi_checked; rfi_found=a.rfi_found; reserved=a.reserved; sigma=a.sigma; chisqr=a.chisqr; null_chisqr=a.null_chisqr; score=a.score; max_power=a.max_power; pot=a.pot; } return (*this); } std::string gaussian::update_format() const { std::ostringstream rv(""); for (int i=2;i<22;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string gaussian::insert_format() const { return std::string("?,")+update_format(); } std::string gaussian::select_format() const { std::string rv(""); for (int i=0; i<21;i++) rv+="?,"; rv+="?"; return rv; } std::string gaussian::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; if (!no_refs) { if (full_subtables) { rv << result_id.print(full_subtables,show_ids,no_refs); } else { rv << result_id.id; } } rv << ','; rv << peak_power; rv << ','; rv << mean_power; rv << ','; rv << time; rv << ','; rv << ra; rv << ','; rv << decl; rv << ','; rv << q_pix; rv << ','; rv << freq; rv << ','; rv << detection_freq; rv << ','; rv << barycentric_freq; rv << ','; rv << fft_len; rv << ','; rv << chirp_rate; rv << ','; rv << rfi_checked; rv << ','; rv << rfi_found; rv << ','; rv << reserved; rv << ','; rv << sigma; rv << ','; rv << chisqr; rv << ','; rv << null_chisqr; rv << ','; rv << score; rv << ','; rv << max_power; rv << ','; rv << "" << pot.print_hex() ; return rv.str(); } std::string gaussian::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; if (!no_refs) { if (full_subtables) { rv << result_id.print_xml(full_subtables,show_ids,no_refs,"result_id"); } else { rv << xml_indent() << "" << result_id.id << "\n"; } } rv << xml_indent() << "" << peak_power << "\n"; rv << xml_indent() << "" << mean_power << "\n"; rv << xml_indent() << "\n"; rv << xml_indent() << "" << ra << "\n"; rv << xml_indent() << "" << decl << "\n"; rv << xml_indent() << "" << q_pix << "\n"; rv << xml_indent() << "" << freq << "\n"; rv << xml_indent() << "" << detection_freq << "\n"; rv << xml_indent() << "" << barycentric_freq << "\n"; rv << xml_indent() << "" << fft_len << "\n"; rv << xml_indent() << "" << chirp_rate << "\n"; rv << xml_indent() << "" << rfi_checked << "\n"; rv << xml_indent() << "" << rfi_found << "\n"; rv << xml_indent() << "" << reserved << "\n"; rv << xml_indent() << "" << sigma << "\n"; rv << xml_indent() << "" << chisqr << "\n"; rv << xml_indent() << "" << null_chisqr << "\n"; rv << xml_indent() << "" << score << "\n"; rv << xml_indent() << "" << max_power << "\n"; if (pot.size()) { std::string enc_field=xml_encode_string(pot,pot.encoding); rv << xml_indent() << ""; rv << enc_field << "\n"; } xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void gaussian::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"result_id",sub)) { result_id.parse_xml(sub,"result_id"); } if (extract_xml_record(field,"peak_power",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> peak_power; } if (extract_xml_record(field,"mean_power",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> mean_power; } if (extract_xml_record(field,"time",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> time; } if (extract_xml_record(field,"ra",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> ra; } if (extract_xml_record(field,"decl",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> decl; } if (extract_xml_record(field,"q_pix",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> q_pix; } if (extract_xml_record(field,"freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> freq; } if (extract_xml_record(field,"detection_freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> detection_freq; } if (extract_xml_record(field,"barycentric_freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> barycentric_freq; } if (extract_xml_record(field,"fft_len",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> fft_len; } if (extract_xml_record(field,"chirp_rate",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> chirp_rate; } if (extract_xml_record(field,"rfi_checked",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> rfi_checked; } if (extract_xml_record(field,"rfi_found",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> rfi_found; } if (extract_xml_record(field,"reserved",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> reserved; } if (extract_xml_record(field,"sigma",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> sigma; } if (extract_xml_record(field,"chisqr",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> chisqr; } if (extract_xml_record(field,"null_chisqr",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> null_chisqr; } if (extract_xml_record(field,"score",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> score; } if (extract_xml_record(field,"max_power",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> max_power; } if (extract_xml_record(field,"pot",sub)) { std::istringstream in(sub.c_str()); in >> pot; } } } void gaussian::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { result_id.parse(SQL_ROW(s[1],0)); } { std::istringstream row(*(s[2])); row >> peak_power; } { std::istringstream row(*(s[3])); row >> mean_power; } { std::istringstream row(*(s[4])); row >> time; } { std::istringstream row(*(s[5])); row >> ra; } { std::istringstream row(*(s[6])); row >> decl; } { std::istringstream row(*(s[7])); row >> q_pix; } { std::istringstream row(*(s[8])); row >> freq; } { std::istringstream row(*(s[9])); row >> detection_freq; } { std::istringstream row(*(s[10])); row >> barycentric_freq; } { std::istringstream row(*(s[11])); row >> fft_len; } { std::istringstream row(*(s[12])); row >> chirp_rate; } { std::istringstream row(*(s[13])); row >> rfi_checked; } { std::istringstream row(*(s[14])); row >> rfi_found; } { std::istringstream row(*(s[15])); row >> reserved; } { std::istringstream row(*(s[16])); row >> sigma; } { std::istringstream row(*(s[17])); row >> chisqr; } { std::istringstream row(*(s[18])); row >> null_chisqr; } { std::istringstream row(*(s[19])); row >> score; } { std::istringstream row(*(s[20])); row >> max_power; } { pot=sqlblob(*(s[21])); } } void gaussian::parse(const std::string &s) { SQL_ROW row(&s,22); parse(row); } template <> const char * const db_table::table_name="gaussian_small"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=21; template <> const char * const db_table::column_names[21]={"id","result_id","peak_power","mean_power","time","ra","decl","q_pix","freq","detection_freq","barycentric_freq","fft_len","chirp_rate","rfi_checked","rfi_found","reserved","sigma","chisqr","null_chisqr","score","max_power"}; gaussian_small::gaussian_small() : db_table(*this,-1), id(0), result_id(), peak_power(0), mean_power(0), time(0), ra(0), decl(0), q_pix(0), freq(0), detection_freq(0), barycentric_freq(0), fft_len(0), chirp_rate(0), rfi_checked(0), rfi_found(0), reserved(0), sigma(0), chisqr(0), null_chisqr(0), score(0), max_power(0) { db_open(); } gaussian_small::gaussian_small(const gaussian_small &a) : db_table(*this,-1), id(a.id), result_id(a.result_id), peak_power(a.peak_power), mean_power(a.mean_power), time(a.time), ra(a.ra), decl(a.decl), q_pix(a.q_pix), freq(a.freq), detection_freq(a.detection_freq), barycentric_freq(a.barycentric_freq), fft_len(a.fft_len), chirp_rate(a.chirp_rate), rfi_checked(a.rfi_checked), rfi_found(a.rfi_found), reserved(a.reserved), sigma(a.sigma), chisqr(a.chisqr), null_chisqr(a.null_chisqr), score(a.score), max_power(a.max_power) { db_open(); } gaussian_small::gaussian_small(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } gaussian_small::gaussian_small(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } gaussian_small &gaussian_small::operator =(const gaussian_small &a) { if (&a != this) { id=a.id; result_id=a.result_id; peak_power=a.peak_power; mean_power=a.mean_power; time=a.time; ra=a.ra; decl=a.decl; q_pix=a.q_pix; freq=a.freq; detection_freq=a.detection_freq; barycentric_freq=a.barycentric_freq; fft_len=a.fft_len; chirp_rate=a.chirp_rate; rfi_checked=a.rfi_checked; rfi_found=a.rfi_found; reserved=a.reserved; sigma=a.sigma; chisqr=a.chisqr; null_chisqr=a.null_chisqr; score=a.score; max_power=a.max_power; } return (*this); } std::string gaussian_small::update_format() const { std::ostringstream rv(""); for (int i=2;i<21;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string gaussian_small::insert_format() const { return std::string("?,")+update_format(); } std::string gaussian_small::select_format() const { std::string rv(""); for (int i=0; i<20;i++) rv+="?,"; rv+="?"; return rv; } std::string gaussian_small::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; if (!no_refs) { if (full_subtables) { rv << result_id.print(full_subtables,show_ids,no_refs); } else { rv << result_id.id; } } rv << ','; rv << peak_power; rv << ','; rv << mean_power; rv << ','; rv << time; rv << ','; rv << ra; rv << ','; rv << decl; rv << ','; rv << q_pix; rv << ','; rv << freq; rv << ','; rv << detection_freq; rv << ','; rv << barycentric_freq; rv << ','; rv << fft_len; rv << ','; rv << chirp_rate; rv << ','; rv << rfi_checked; rv << ','; rv << rfi_found; rv << ','; rv << reserved; rv << ','; rv << sigma; rv << ','; rv << chisqr; rv << ','; rv << null_chisqr; rv << ','; rv << score; rv << ','; rv << max_power; return rv.str(); } std::string gaussian_small::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; if (!no_refs) { if (full_subtables) { rv << result_id.print_xml(full_subtables,show_ids,no_refs,"result_id"); } else { rv << xml_indent() << "" << result_id.id << "\n"; } } rv << xml_indent() << "" << peak_power << "\n"; rv << xml_indent() << "" << mean_power << "\n"; rv << xml_indent() << "\n"; rv << xml_indent() << "" << ra << "\n"; rv << xml_indent() << "" << decl << "\n"; rv << xml_indent() << "" << q_pix << "\n"; rv << xml_indent() << "" << freq << "\n"; rv << xml_indent() << "" << detection_freq << "\n"; rv << xml_indent() << "" << barycentric_freq << "\n"; rv << xml_indent() << "" << fft_len << "\n"; rv << xml_indent() << "" << chirp_rate << "\n"; rv << xml_indent() << "" << rfi_checked << "\n"; rv << xml_indent() << "" << rfi_found << "\n"; rv << xml_indent() << "" << reserved << "\n"; rv << xml_indent() << "" << sigma << "\n"; rv << xml_indent() << "" << chisqr << "\n"; rv << xml_indent() << "" << null_chisqr << "\n"; rv << xml_indent() << "" << score << "\n"; rv << xml_indent() << "" << max_power << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void gaussian_small::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"result_id",sub)) { result_id.parse_xml(sub,"result_id"); } if (extract_xml_record(field,"peak_power",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> peak_power; } if (extract_xml_record(field,"mean_power",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> mean_power; } if (extract_xml_record(field,"time",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> time; } if (extract_xml_record(field,"ra",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> ra; } if (extract_xml_record(field,"decl",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> decl; } if (extract_xml_record(field,"q_pix",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> q_pix; } if (extract_xml_record(field,"freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> freq; } if (extract_xml_record(field,"detection_freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> detection_freq; } if (extract_xml_record(field,"barycentric_freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> barycentric_freq; } if (extract_xml_record(field,"fft_len",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> fft_len; } if (extract_xml_record(field,"chirp_rate",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> chirp_rate; } if (extract_xml_record(field,"rfi_checked",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> rfi_checked; } if (extract_xml_record(field,"rfi_found",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> rfi_found; } if (extract_xml_record(field,"reserved",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> reserved; } if (extract_xml_record(field,"sigma",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> sigma; } if (extract_xml_record(field,"chisqr",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> chisqr; } if (extract_xml_record(field,"null_chisqr",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> null_chisqr; } if (extract_xml_record(field,"score",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> score; } if (extract_xml_record(field,"max_power",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> max_power; } } } void gaussian_small::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { result_id.parse(SQL_ROW(s[1],0)); } { std::istringstream row(*(s[2])); row >> peak_power; } { std::istringstream row(*(s[3])); row >> mean_power; } { std::istringstream row(*(s[4])); row >> time; } { std::istringstream row(*(s[5])); row >> ra; } { std::istringstream row(*(s[6])); row >> decl; } { std::istringstream row(*(s[7])); row >> q_pix; } { std::istringstream row(*(s[8])); row >> freq; } { std::istringstream row(*(s[9])); row >> detection_freq; } { std::istringstream row(*(s[10])); row >> barycentric_freq; } { std::istringstream row(*(s[11])); row >> fft_len; } { std::istringstream row(*(s[12])); row >> chirp_rate; } { std::istringstream row(*(s[13])); row >> rfi_checked; } { std::istringstream row(*(s[14])); row >> rfi_found; } { std::istringstream row(*(s[15])); row >> reserved; } { std::istringstream row(*(s[16])); row >> sigma; } { std::istringstream row(*(s[17])); row >> chisqr; } { std::istringstream row(*(s[18])); row >> null_chisqr; } { std::istringstream row(*(s[19])); row >> score; } { std::istringstream row(*(s[20])); row >> max_power; } } void gaussian_small::parse(const std::string &s) { SQL_ROW row(&s,21); parse(row); } template <> const char * const db_table::table_name="pulse"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=22; template <> const char * const db_table::column_names[22]={"id","result_id","peak_power","mean_power","time","ra","decl","q_pix","freq","detection_freq","barycentric_freq","fft_len","chirp_rate","rfi_checked","rfi_found","reserved","period","snr","thresh","score","len_prof","pot"}; pulse::pulse() : db_table(*this,-1), id(0), result_id(), peak_power(0), mean_power(0), time(0), ra(0), decl(0), q_pix(0), freq(0), detection_freq(0), barycentric_freq(0), fft_len(0), chirp_rate(0), rfi_checked(0), rfi_found(0), reserved(0), period(0), snr(0), thresh(0), score(0), len_prof(0), pot((unsigned char *)0,0,_x_csv) { db_open(); } pulse::pulse(const pulse &a) : db_table(*this,-1), id(a.id), result_id(a.result_id), peak_power(a.peak_power), mean_power(a.mean_power), time(a.time), ra(a.ra), decl(a.decl), q_pix(a.q_pix), freq(a.freq), detection_freq(a.detection_freq), barycentric_freq(a.barycentric_freq), fft_len(a.fft_len), chirp_rate(a.chirp_rate), rfi_checked(a.rfi_checked), rfi_found(a.rfi_found), reserved(a.reserved), period(a.period), snr(a.snr), thresh(a.thresh), score(a.score), len_prof(a.len_prof), pot(a.pot) { db_open(); } pulse::pulse(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } pulse::pulse(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } pulse &pulse::operator =(const pulse &a) { if (&a != this) { id=a.id; result_id=a.result_id; peak_power=a.peak_power; mean_power=a.mean_power; time=a.time; ra=a.ra; decl=a.decl; q_pix=a.q_pix; freq=a.freq; detection_freq=a.detection_freq; barycentric_freq=a.barycentric_freq; fft_len=a.fft_len; chirp_rate=a.chirp_rate; rfi_checked=a.rfi_checked; rfi_found=a.rfi_found; reserved=a.reserved; period=a.period; snr=a.snr; thresh=a.thresh; score=a.score; len_prof=a.len_prof; pot=a.pot; } return (*this); } std::string pulse::update_format() const { std::ostringstream rv(""); for (int i=2;i<22;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string pulse::insert_format() const { return std::string("?,")+update_format(); } std::string pulse::select_format() const { std::string rv(""); for (int i=0; i<21;i++) rv+="?,"; rv+="?"; return rv; } std::string pulse::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; if (!no_refs) { if (full_subtables) { rv << result_id.print(full_subtables,show_ids,no_refs); } else { rv << result_id.id; } } rv << ','; rv << peak_power; rv << ','; rv << mean_power; rv << ','; rv << time; rv << ','; rv << ra; rv << ','; rv << decl; rv << ','; rv << q_pix; rv << ','; rv << freq; rv << ','; rv << detection_freq; rv << ','; rv << barycentric_freq; rv << ','; rv << fft_len; rv << ','; rv << chirp_rate; rv << ','; rv << rfi_checked; rv << ','; rv << rfi_found; rv << ','; rv << reserved; rv << ','; rv << period; rv << ','; rv << snr; rv << ','; rv << thresh; rv << ','; rv << score; rv << ','; rv << len_prof; rv << ','; rv << "" << pot.print_hex() ; return rv.str(); } std::string pulse::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; if (!no_refs) { if (full_subtables) { rv << result_id.print_xml(full_subtables,show_ids,no_refs,"result_id"); } else { rv << xml_indent() << "" << result_id.id << "\n"; } } rv << xml_indent() << "" << peak_power << "\n"; rv << xml_indent() << "" << mean_power << "\n"; rv << xml_indent() << "\n"; rv << xml_indent() << "" << ra << "\n"; rv << xml_indent() << "" << decl << "\n"; rv << xml_indent() << "" << q_pix << "\n"; rv << xml_indent() << "" << freq << "\n"; rv << xml_indent() << "" << detection_freq << "\n"; rv << xml_indent() << "" << barycentric_freq << "\n"; rv << xml_indent() << "" << fft_len << "\n"; rv << xml_indent() << "" << chirp_rate << "\n"; rv << xml_indent() << "" << rfi_checked << "\n"; rv << xml_indent() << "" << rfi_found << "\n"; rv << xml_indent() << "" << reserved << "\n"; rv << xml_indent() << "" << period << "\n"; rv << xml_indent() << "" << snr << "\n"; rv << xml_indent() << "" << thresh << "\n"; rv << xml_indent() << "" << score << "\n"; rv << xml_indent() << "" << len_prof << "\n"; if (pot.size()) { std::string enc_field=xml_encode_string(pot,pot.encoding); rv << xml_indent() << ""; rv << enc_field << "\n"; } xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void pulse::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"result_id",sub)) { result_id.parse_xml(sub,"result_id"); } if (extract_xml_record(field,"peak_power",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> peak_power; } if (extract_xml_record(field,"mean_power",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> mean_power; } if (extract_xml_record(field,"time",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> time; } if (extract_xml_record(field,"ra",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> ra; } if (extract_xml_record(field,"decl",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> decl; } if (extract_xml_record(field,"q_pix",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> q_pix; } if (extract_xml_record(field,"freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> freq; } if (extract_xml_record(field,"detection_freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> detection_freq; } if (extract_xml_record(field,"barycentric_freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> barycentric_freq; } if (extract_xml_record(field,"fft_len",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> fft_len; } if (extract_xml_record(field,"chirp_rate",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> chirp_rate; } if (extract_xml_record(field,"rfi_checked",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> rfi_checked; } if (extract_xml_record(field,"rfi_found",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> rfi_found; } if (extract_xml_record(field,"reserved",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> reserved; } if (extract_xml_record(field,"period",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> period; } if (extract_xml_record(field,"snr",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> snr; } if (extract_xml_record(field,"thresh",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> thresh; } if (extract_xml_record(field,"score",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> score; } if (extract_xml_record(field,"len_prof",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> len_prof; } if (extract_xml_record(field,"pot",sub)) { std::istringstream in(sub.c_str()); in >> pot; } } } void pulse::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { result_id.parse(SQL_ROW(s[1],0)); } { std::istringstream row(*(s[2])); row >> peak_power; } { std::istringstream row(*(s[3])); row >> mean_power; } { std::istringstream row(*(s[4])); row >> time; } { std::istringstream row(*(s[5])); row >> ra; } { std::istringstream row(*(s[6])); row >> decl; } { std::istringstream row(*(s[7])); row >> q_pix; } { std::istringstream row(*(s[8])); row >> freq; } { std::istringstream row(*(s[9])); row >> detection_freq; } { std::istringstream row(*(s[10])); row >> barycentric_freq; } { std::istringstream row(*(s[11])); row >> fft_len; } { std::istringstream row(*(s[12])); row >> chirp_rate; } { std::istringstream row(*(s[13])); row >> rfi_checked; } { std::istringstream row(*(s[14])); row >> rfi_found; } { std::istringstream row(*(s[15])); row >> reserved; } { std::istringstream row(*(s[16])); row >> period; } { std::istringstream row(*(s[17])); row >> snr; } { std::istringstream row(*(s[18])); row >> thresh; } { std::istringstream row(*(s[19])); row >> score; } { std::istringstream row(*(s[20])); row >> len_prof; } { pot=sqlblob(*(s[21])); } } void pulse::parse(const std::string &s) { SQL_ROW row(&s,22); parse(row); } template <> const char * const db_table::table_name="pulse_small"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=20; template <> const char * const db_table::column_names[20]={"id","result_id","peak_power","mean_power","time","ra","decl","q_pix","freq","detection_freq","barycentric_freq","fft_len","chirp_rate","rfi_checked","rfi_found","reserved","period","snr","thresh","score"}; pulse_small::pulse_small() : db_table(*this,-1), id(0), result_id(), peak_power(0), mean_power(0), time(0), ra(0), decl(0), q_pix(0), freq(0), detection_freq(0), barycentric_freq(0), fft_len(0), chirp_rate(0), rfi_checked(0), rfi_found(0), reserved(0), period(0), snr(0), thresh(0), score(0) { db_open(); } pulse_small::pulse_small(const pulse_small &a) : db_table(*this,-1), id(a.id), result_id(a.result_id), peak_power(a.peak_power), mean_power(a.mean_power), time(a.time), ra(a.ra), decl(a.decl), q_pix(a.q_pix), freq(a.freq), detection_freq(a.detection_freq), barycentric_freq(a.barycentric_freq), fft_len(a.fft_len), chirp_rate(a.chirp_rate), rfi_checked(a.rfi_checked), rfi_found(a.rfi_found), reserved(a.reserved), period(a.period), snr(a.snr), thresh(a.thresh), score(a.score) { db_open(); } pulse_small::pulse_small(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } pulse_small::pulse_small(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } pulse_small &pulse_small::operator =(const pulse_small &a) { if (&a != this) { id=a.id; result_id=a.result_id; peak_power=a.peak_power; mean_power=a.mean_power; time=a.time; ra=a.ra; decl=a.decl; q_pix=a.q_pix; freq=a.freq; detection_freq=a.detection_freq; barycentric_freq=a.barycentric_freq; fft_len=a.fft_len; chirp_rate=a.chirp_rate; rfi_checked=a.rfi_checked; rfi_found=a.rfi_found; reserved=a.reserved; period=a.period; snr=a.snr; thresh=a.thresh; score=a.score; } return (*this); } std::string pulse_small::update_format() const { std::ostringstream rv(""); for (int i=2;i<20;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string pulse_small::insert_format() const { return std::string("?,")+update_format(); } std::string pulse_small::select_format() const { std::string rv(""); for (int i=0; i<19;i++) rv+="?,"; rv+="?"; return rv; } std::string pulse_small::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; if (!no_refs) { if (full_subtables) { rv << result_id.print(full_subtables,show_ids,no_refs); } else { rv << result_id.id; } } rv << ','; rv << peak_power; rv << ','; rv << mean_power; rv << ','; rv << time; rv << ','; rv << ra; rv << ','; rv << decl; rv << ','; rv << q_pix; rv << ','; rv << freq; rv << ','; rv << detection_freq; rv << ','; rv << barycentric_freq; rv << ','; rv << fft_len; rv << ','; rv << chirp_rate; rv << ','; rv << rfi_checked; rv << ','; rv << rfi_found; rv << ','; rv << reserved; rv << ','; rv << period; rv << ','; rv << snr; rv << ','; rv << thresh; rv << ','; rv << score; return rv.str(); } std::string pulse_small::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; if (!no_refs) { if (full_subtables) { rv << result_id.print_xml(full_subtables,show_ids,no_refs,"result_id"); } else { rv << xml_indent() << "" << result_id.id << "\n"; } } rv << xml_indent() << "" << peak_power << "\n"; rv << xml_indent() << "" << mean_power << "\n"; rv << xml_indent() << "\n"; rv << xml_indent() << "" << ra << "\n"; rv << xml_indent() << "" << decl << "\n"; rv << xml_indent() << "" << q_pix << "\n"; rv << xml_indent() << "" << freq << "\n"; rv << xml_indent() << "" << detection_freq << "\n"; rv << xml_indent() << "" << barycentric_freq << "\n"; rv << xml_indent() << "" << fft_len << "\n"; rv << xml_indent() << "" << chirp_rate << "\n"; rv << xml_indent() << "" << rfi_checked << "\n"; rv << xml_indent() << "" << rfi_found << "\n"; rv << xml_indent() << "" << reserved << "\n"; rv << xml_indent() << "" << period << "\n"; rv << xml_indent() << "" << snr << "\n"; rv << xml_indent() << "" << thresh << "\n"; rv << xml_indent() << "" << score << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void pulse_small::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"result_id",sub)) { result_id.parse_xml(sub,"result_id"); } if (extract_xml_record(field,"peak_power",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> peak_power; } if (extract_xml_record(field,"mean_power",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> mean_power; } if (extract_xml_record(field,"time",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> time; } if (extract_xml_record(field,"ra",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> ra; } if (extract_xml_record(field,"decl",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> decl; } if (extract_xml_record(field,"q_pix",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> q_pix; } if (extract_xml_record(field,"freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> freq; } if (extract_xml_record(field,"detection_freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> detection_freq; } if (extract_xml_record(field,"barycentric_freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> barycentric_freq; } if (extract_xml_record(field,"fft_len",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> fft_len; } if (extract_xml_record(field,"chirp_rate",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> chirp_rate; } if (extract_xml_record(field,"rfi_checked",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> rfi_checked; } if (extract_xml_record(field,"rfi_found",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> rfi_found; } if (extract_xml_record(field,"reserved",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> reserved; } if (extract_xml_record(field,"period",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> period; } if (extract_xml_record(field,"snr",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> snr; } if (extract_xml_record(field,"thresh",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> thresh; } if (extract_xml_record(field,"score",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> score; } } } void pulse_small::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { result_id.parse(SQL_ROW(s[1],0)); } { std::istringstream row(*(s[2])); row >> peak_power; } { std::istringstream row(*(s[3])); row >> mean_power; } { std::istringstream row(*(s[4])); row >> time; } { std::istringstream row(*(s[5])); row >> ra; } { std::istringstream row(*(s[6])); row >> decl; } { std::istringstream row(*(s[7])); row >> q_pix; } { std::istringstream row(*(s[8])); row >> freq; } { std::istringstream row(*(s[9])); row >> detection_freq; } { std::istringstream row(*(s[10])); row >> barycentric_freq; } { std::istringstream row(*(s[11])); row >> fft_len; } { std::istringstream row(*(s[12])); row >> chirp_rate; } { std::istringstream row(*(s[13])); row >> rfi_checked; } { std::istringstream row(*(s[14])); row >> rfi_found; } { std::istringstream row(*(s[15])); row >> reserved; } { std::istringstream row(*(s[16])); row >> period; } { std::istringstream row(*(s[17])); row >> snr; } { std::istringstream row(*(s[18])); row >> thresh; } { std::istringstream row(*(s[19])); row >> score; } } void pulse_small::parse(const std::string &s) { SQL_ROW row(&s,20); parse(row); } template <> const char * const db_table::table_name="sah_pointing"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=7; template <> const char * const db_table::column_names[7]={"time_id","time","ra","dec","q_pix","angle_range","bad"}; sah_pointing::sah_pointing() : db_table(*this,-1), time_id(0), time(0), ra(0), dec(0), q_pix(0), angle_range(0), bad(0) { db_open(); } sah_pointing::sah_pointing(const sah_pointing &a) : db_table(*this,-1), time_id(a.time_id), time(a.time), ra(a.ra), dec(a.dec), q_pix(a.q_pix), angle_range(a.angle_range), bad(a.bad) { db_open(); } sah_pointing::sah_pointing(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } sah_pointing::sah_pointing(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } sah_pointing &sah_pointing::operator =(const sah_pointing &a) { if (&a != this) { time_id=a.time_id; time=a.time; ra=a.ra; dec=a.dec; q_pix=a.q_pix; angle_range=a.angle_range; bad=a.bad; } return (*this); } std::string sah_pointing::update_format() const { std::ostringstream rv(""); for (int i=2;i<7;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string sah_pointing::insert_format() const { return std::string("?,")+update_format(); } std::string sah_pointing::select_format() const { std::string rv(""); for (int i=0; i<6;i++) rv+="?,"; rv+="?"; return rv; } std::string sah_pointing::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << time_id; rv << ','; rv << time; rv << ','; rv << ra; rv << ','; rv << dec; rv << ','; rv << q_pix; rv << ','; rv << angle_range; rv << ','; rv << bad; return rv.str(); } std::string sah_pointing::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << time_id << "\n"; rv << xml_indent() << "\n"; rv << xml_indent() << "" << ra << "\n"; rv << xml_indent() << "" << dec << "\n"; rv << xml_indent() << "" << q_pix << "\n"; rv << xml_indent() << "" << angle_range << "\n"; rv << xml_indent() << "" << bad << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void sah_pointing::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"time_id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> time_id; } if (extract_xml_record(field,"time",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> time; } if (extract_xml_record(field,"ra",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> ra; } if (extract_xml_record(field,"dec",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> dec; } if (extract_xml_record(field,"q_pix",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> q_pix; } if (extract_xml_record(field,"angle_range",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> angle_range; } if (extract_xml_record(field,"bad",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> bad; } } } void sah_pointing::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> time_id; } { std::istringstream row(*(s[1])); row >> time; } { std::istringstream row(*(s[2])); row >> ra; } { std::istringstream row(*(s[3])); row >> dec; } { std::istringstream row(*(s[4])); row >> q_pix; } { std::istringstream row(*(s[5])); row >> angle_range; } { std::istringstream row(*(s[6])); row >> bad; } } void sah_pointing::parse(const std::string &s) { SQL_ROW row(&s,7); parse(row); } template <> const char * const db_table::table_name="sky_map"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=13; template <> const char * const db_table::column_names[13]={"npix","qpix","fpix","spike_max_id","gaussian_max_id","pulse_max_id","triplet_max_id","spike_count","gaussian_count","pulse_count","triplet_count","new_data","score"}; sky_map::sky_map() : db_table(*this,-1), npix(0), qpix(0), fpix(0), spike_max_id(0), gaussian_max_id(0), pulse_max_id(0), triplet_max_id(0), spike_count(0), gaussian_count(0), pulse_count(0), triplet_count(0), new_data(0), score(0) { db_open(); } sky_map::sky_map(const sky_map &a) : db_table(*this,-1), npix(a.npix), qpix(a.qpix), fpix(a.fpix), spike_max_id(a.spike_max_id), gaussian_max_id(a.gaussian_max_id), pulse_max_id(a.pulse_max_id), triplet_max_id(a.triplet_max_id), spike_count(a.spike_count), gaussian_count(a.gaussian_count), pulse_count(a.pulse_count), triplet_count(a.triplet_count), new_data(a.new_data), score(a.score) { db_open(); } sky_map::sky_map(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } sky_map::sky_map(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } sky_map &sky_map::operator =(const sky_map &a) { if (&a != this) { npix=a.npix; qpix=a.qpix; fpix=a.fpix; spike_max_id=a.spike_max_id; gaussian_max_id=a.gaussian_max_id; pulse_max_id=a.pulse_max_id; triplet_max_id=a.triplet_max_id; spike_count=a.spike_count; gaussian_count=a.gaussian_count; pulse_count=a.pulse_count; triplet_count=a.triplet_count; new_data=a.new_data; score=a.score; } return (*this); } std::string sky_map::update_format() const { std::ostringstream rv(""); for (int i=2;i<13;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string sky_map::insert_format() const { return std::string("?,")+update_format(); } std::string sky_map::select_format() const { std::string rv(""); for (int i=0; i<12;i++) rv+="?,"; rv+="?"; return rv; } std::string sky_map::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << npix; rv << ','; rv << qpix; rv << ','; rv << fpix; rv << ','; rv << spike_max_id; rv << ','; rv << gaussian_max_id; rv << ','; rv << pulse_max_id; rv << ','; rv << triplet_max_id; rv << ','; rv << spike_count; rv << ','; rv << gaussian_count; rv << ','; rv << pulse_count; rv << ','; rv << triplet_count; rv << ','; rv << new_data; rv << ','; rv << score; return rv.str(); } std::string sky_map::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << npix << "\n"; rv << xml_indent() << "" << qpix << "\n"; rv << xml_indent() << "" << fpix << "\n"; rv << xml_indent() << "" << spike_max_id << "\n"; rv << xml_indent() << "" << gaussian_max_id << "\n"; rv << xml_indent() << "" << pulse_max_id << "\n"; rv << xml_indent() << "" << triplet_max_id << "\n"; rv << xml_indent() << "" << spike_count << "\n"; rv << xml_indent() << "" << gaussian_count << "\n"; rv << xml_indent() << "" << pulse_count << "\n"; rv << xml_indent() << "" << triplet_count << "\n"; rv << xml_indent() << "" << new_data << "\n"; rv << xml_indent() << "" << score << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void sky_map::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"npix",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> npix; } if (extract_xml_record(field,"qpix",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> qpix; } if (extract_xml_record(field,"fpix",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> fpix; } if (extract_xml_record(field,"spike_max_id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> spike_max_id; } if (extract_xml_record(field,"gaussian_max_id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> gaussian_max_id; } if (extract_xml_record(field,"pulse_max_id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> pulse_max_id; } if (extract_xml_record(field,"triplet_max_id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> triplet_max_id; } if (extract_xml_record(field,"spike_count",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> spike_count; } if (extract_xml_record(field,"gaussian_count",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> gaussian_count; } if (extract_xml_record(field,"pulse_count",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> pulse_count; } if (extract_xml_record(field,"triplet_count",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> triplet_count; } if (extract_xml_record(field,"new_data",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> new_data; } if (extract_xml_record(field,"score",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> score; } } } void sky_map::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> npix; } { std::istringstream row(*(s[1])); row >> qpix; } { std::istringstream row(*(s[2])); row >> fpix; } { std::istringstream row(*(s[3])); row >> spike_max_id; } { std::istringstream row(*(s[4])); row >> gaussian_max_id; } { std::istringstream row(*(s[5])); row >> pulse_max_id; } { std::istringstream row(*(s[6])); row >> triplet_max_id; } { std::istringstream row(*(s[7])); row >> spike_count; } { std::istringstream row(*(s[8])); row >> gaussian_count; } { std::istringstream row(*(s[9])); row >> pulse_count; } { std::istringstream row(*(s[10])); row >> triplet_count; } { std::istringstream row(*(s[11])); row >> new_data; } { std::istringstream row(*(s[12])); row >> score; } } void sky_map::parse(const std::string &s) { SQL_ROW row(&s,13); parse(row); } template <> const char * const db_table::table_name="hotpix"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=2; template <> const char * const db_table::column_names[2]={"id","last_hit_time"}; hotpix::hotpix() : db_table(*this,-1), id(0), last_hit_time(0) { db_open(); } hotpix::hotpix(const hotpix &a) : db_table(*this,-1), id(a.id), last_hit_time(a.last_hit_time) { db_open(); } hotpix::hotpix(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } hotpix::hotpix(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } hotpix &hotpix::operator =(const hotpix &a) { if (&a != this) { id=a.id; last_hit_time=a.last_hit_time; } return (*this); } std::string hotpix::update_format() const { std::ostringstream rv(""); for (int i=2;i<2;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string hotpix::insert_format() const { return std::string("?,")+update_format(); } std::string hotpix::select_format() const { std::string rv(""); for (int i=0; i<1;i++) rv+="?,"; rv+="?"; return rv; } std::string hotpix::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; rv << last_hit_time; return rv.str(); } std::string hotpix::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; rv << xml_indent() << "" << last_hit_time << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void hotpix::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"last_hit_time",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> last_hit_time; } } } void hotpix::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { std::istringstream row(*(s[1])); row >> last_hit_time; } } void hotpix::parse(const std::string &s) { SQL_ROW row(&s,2); parse(row); } template <> const char * const db_table::table_name="hotpix_tinysky"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=2; template <> const char * const db_table::column_names[2]={"id","last_hit_time"}; hotpix_tinysky::hotpix_tinysky() : db_table(*this,-1), id(0), last_hit_time(0) { db_open(); } hotpix_tinysky::hotpix_tinysky(const hotpix_tinysky &a) : db_table(*this,-1), id(a.id), last_hit_time(a.last_hit_time) { db_open(); } hotpix_tinysky::hotpix_tinysky(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } hotpix_tinysky::hotpix_tinysky(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } hotpix_tinysky &hotpix_tinysky::operator =(const hotpix_tinysky &a) { if (&a != this) { id=a.id; last_hit_time=a.last_hit_time; } return (*this); } std::string hotpix_tinysky::update_format() const { std::ostringstream rv(""); for (int i=2;i<2;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string hotpix_tinysky::insert_format() const { return std::string("?,")+update_format(); } std::string hotpix_tinysky::select_format() const { std::string rv(""); for (int i=0; i<1;i++) rv+="?,"; rv+="?"; return rv; } std::string hotpix_tinysky::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; rv << last_hit_time; return rv.str(); } std::string hotpix_tinysky::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; rv << xml_indent() << "" << last_hit_time << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void hotpix_tinysky::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"last_hit_time",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> last_hit_time; } } } void hotpix_tinysky::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { std::istringstream row(*(s[1])); row >> last_hit_time; } } void hotpix_tinysky::parse(const std::string &s) { SQL_ROW row(&s,2); parse(row); } template <> const char * const db_table::table_name="spike"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=16; template <> const char * const db_table::column_names[16]={"id","result_id","peak_power","mean_power","time","ra","decl","q_pix","freq","detection_freq","barycentric_freq","fft_len","chirp_rate","rfi_checked","rfi_found","reserved"}; spike::spike() : db_table(*this,-1), id(0), result_id(), peak_power(0), mean_power(0), time(0), ra(0), decl(0), q_pix(0), freq(0), detection_freq(0), barycentric_freq(0), fft_len(0), chirp_rate(0), rfi_checked(0), rfi_found(0), reserved(0) { db_open(); } spike::spike(const spike &a) : db_table(*this,-1), id(a.id), result_id(a.result_id), peak_power(a.peak_power), mean_power(a.mean_power), time(a.time), ra(a.ra), decl(a.decl), q_pix(a.q_pix), freq(a.freq), detection_freq(a.detection_freq), barycentric_freq(a.barycentric_freq), fft_len(a.fft_len), chirp_rate(a.chirp_rate), rfi_checked(a.rfi_checked), rfi_found(a.rfi_found), reserved(a.reserved) { db_open(); } spike::spike(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } spike::spike(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } spike &spike::operator =(const spike &a) { if (&a != this) { id=a.id; result_id=a.result_id; peak_power=a.peak_power; mean_power=a.mean_power; time=a.time; ra=a.ra; decl=a.decl; q_pix=a.q_pix; freq=a.freq; detection_freq=a.detection_freq; barycentric_freq=a.barycentric_freq; fft_len=a.fft_len; chirp_rate=a.chirp_rate; rfi_checked=a.rfi_checked; rfi_found=a.rfi_found; reserved=a.reserved; } return (*this); } std::string spike::update_format() const { std::ostringstream rv(""); for (int i=2;i<16;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string spike::insert_format() const { return std::string("?,")+update_format(); } std::string spike::select_format() const { std::string rv(""); for (int i=0; i<15;i++) rv+="?,"; rv+="?"; return rv; } std::string spike::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; if (!no_refs) { if (full_subtables) { rv << result_id.print(full_subtables,show_ids,no_refs); } else { rv << result_id.id; } } rv << ','; rv << peak_power; rv << ','; rv << mean_power; rv << ','; rv << time; rv << ','; rv << ra; rv << ','; rv << decl; rv << ','; rv << q_pix; rv << ','; rv << freq; rv << ','; rv << detection_freq; rv << ','; rv << barycentric_freq; rv << ','; rv << fft_len; rv << ','; rv << chirp_rate; rv << ','; rv << rfi_checked; rv << ','; rv << rfi_found; rv << ','; rv << reserved; return rv.str(); } std::string spike::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; if (!no_refs) { if (full_subtables) { rv << result_id.print_xml(full_subtables,show_ids,no_refs,"result_id"); } else { rv << xml_indent() << "" << result_id.id << "\n"; } } rv << xml_indent() << "" << peak_power << "\n"; rv << xml_indent() << "" << mean_power << "\n"; rv << xml_indent() << "\n"; rv << xml_indent() << "" << ra << "\n"; rv << xml_indent() << "" << decl << "\n"; rv << xml_indent() << "" << q_pix << "\n"; rv << xml_indent() << "" << freq << "\n"; rv << xml_indent() << "" << detection_freq << "\n"; rv << xml_indent() << "" << barycentric_freq << "\n"; rv << xml_indent() << "" << fft_len << "\n"; rv << xml_indent() << "" << chirp_rate << "\n"; rv << xml_indent() << "" << rfi_checked << "\n"; rv << xml_indent() << "" << rfi_found << "\n"; rv << xml_indent() << "" << reserved << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void spike::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"result_id",sub)) { result_id.parse_xml(sub,"result_id"); } if (extract_xml_record(field,"peak_power",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> peak_power; } if (extract_xml_record(field,"mean_power",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> mean_power; } if (extract_xml_record(field,"time",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> time; } if (extract_xml_record(field,"ra",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> ra; } if (extract_xml_record(field,"decl",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> decl; } if (extract_xml_record(field,"q_pix",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> q_pix; } if (extract_xml_record(field,"freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> freq; } if (extract_xml_record(field,"detection_freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> detection_freq; } if (extract_xml_record(field,"barycentric_freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> barycentric_freq; } if (extract_xml_record(field,"fft_len",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> fft_len; } if (extract_xml_record(field,"chirp_rate",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> chirp_rate; } if (extract_xml_record(field,"rfi_checked",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> rfi_checked; } if (extract_xml_record(field,"rfi_found",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> rfi_found; } if (extract_xml_record(field,"reserved",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> reserved; } } } void spike::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { result_id.parse(SQL_ROW(s[1],0)); } { std::istringstream row(*(s[2])); row >> peak_power; } { std::istringstream row(*(s[3])); row >> mean_power; } { std::istringstream row(*(s[4])); row >> time; } { std::istringstream row(*(s[5])); row >> ra; } { std::istringstream row(*(s[6])); row >> decl; } { std::istringstream row(*(s[7])); row >> q_pix; } { std::istringstream row(*(s[8])); row >> freq; } { std::istringstream row(*(s[9])); row >> detection_freq; } { std::istringstream row(*(s[10])); row >> barycentric_freq; } { std::istringstream row(*(s[11])); row >> fft_len; } { std::istringstream row(*(s[12])); row >> chirp_rate; } { std::istringstream row(*(s[13])); row >> rfi_checked; } { std::istringstream row(*(s[14])); row >> rfi_found; } { std::istringstream row(*(s[15])); row >> reserved; } } void spike::parse(const std::string &s) { SQL_ROW row(&s,16); parse(row); } template <> const char * const db_table::table_name="spike_small"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=16; template <> const char * const db_table::column_names[16]={"id","result_id","peak_power","mean_power","time","ra","decl","q_pix","freq","detection_freq","barycentric_freq","fft_len","chirp_rate","rfi_checked","rfi_found","reserved"}; spike_small::spike_small() : db_table(*this,-1), id(0), result_id(), peak_power(0), mean_power(0), time(0), ra(0), decl(0), q_pix(0), freq(0), detection_freq(0), barycentric_freq(0), fft_len(0), chirp_rate(0), rfi_checked(0), rfi_found(0), reserved(0) { db_open(); } spike_small::spike_small(const spike_small &a) : db_table(*this,-1), id(a.id), result_id(a.result_id), peak_power(a.peak_power), mean_power(a.mean_power), time(a.time), ra(a.ra), decl(a.decl), q_pix(a.q_pix), freq(a.freq), detection_freq(a.detection_freq), barycentric_freq(a.barycentric_freq), fft_len(a.fft_len), chirp_rate(a.chirp_rate), rfi_checked(a.rfi_checked), rfi_found(a.rfi_found), reserved(a.reserved) { db_open(); } spike_small::spike_small(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } spike_small::spike_small(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } spike_small &spike_small::operator =(const spike_small &a) { if (&a != this) { id=a.id; result_id=a.result_id; peak_power=a.peak_power; mean_power=a.mean_power; time=a.time; ra=a.ra; decl=a.decl; q_pix=a.q_pix; freq=a.freq; detection_freq=a.detection_freq; barycentric_freq=a.barycentric_freq; fft_len=a.fft_len; chirp_rate=a.chirp_rate; rfi_checked=a.rfi_checked; rfi_found=a.rfi_found; reserved=a.reserved; } return (*this); } std::string spike_small::update_format() const { std::ostringstream rv(""); for (int i=2;i<16;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string spike_small::insert_format() const { return std::string("?,")+update_format(); } std::string spike_small::select_format() const { std::string rv(""); for (int i=0; i<15;i++) rv+="?,"; rv+="?"; return rv; } std::string spike_small::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; if (!no_refs) { if (full_subtables) { rv << result_id.print(full_subtables,show_ids,no_refs); } else { rv << result_id.id; } } rv << ','; rv << peak_power; rv << ','; rv << mean_power; rv << ','; rv << time; rv << ','; rv << ra; rv << ','; rv << decl; rv << ','; rv << q_pix; rv << ','; rv << freq; rv << ','; rv << detection_freq; rv << ','; rv << barycentric_freq; rv << ','; rv << fft_len; rv << ','; rv << chirp_rate; rv << ','; rv << rfi_checked; rv << ','; rv << rfi_found; rv << ','; rv << reserved; return rv.str(); } std::string spike_small::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; if (!no_refs) { if (full_subtables) { rv << result_id.print_xml(full_subtables,show_ids,no_refs,"result_id"); } else { rv << xml_indent() << "" << result_id.id << "\n"; } } rv << xml_indent() << "" << peak_power << "\n"; rv << xml_indent() << "" << mean_power << "\n"; rv << xml_indent() << "\n"; rv << xml_indent() << "" << ra << "\n"; rv << xml_indent() << "" << decl << "\n"; rv << xml_indent() << "" << q_pix << "\n"; rv << xml_indent() << "" << freq << "\n"; rv << xml_indent() << "" << detection_freq << "\n"; rv << xml_indent() << "" << barycentric_freq << "\n"; rv << xml_indent() << "" << fft_len << "\n"; rv << xml_indent() << "" << chirp_rate << "\n"; rv << xml_indent() << "" << rfi_checked << "\n"; rv << xml_indent() << "" << rfi_found << "\n"; rv << xml_indent() << "" << reserved << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void spike_small::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"result_id",sub)) { result_id.parse_xml(sub,"result_id"); } if (extract_xml_record(field,"peak_power",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> peak_power; } if (extract_xml_record(field,"mean_power",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> mean_power; } if (extract_xml_record(field,"time",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> time; } if (extract_xml_record(field,"ra",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> ra; } if (extract_xml_record(field,"decl",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> decl; } if (extract_xml_record(field,"q_pix",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> q_pix; } if (extract_xml_record(field,"freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> freq; } if (extract_xml_record(field,"detection_freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> detection_freq; } if (extract_xml_record(field,"barycentric_freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> barycentric_freq; } if (extract_xml_record(field,"fft_len",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> fft_len; } if (extract_xml_record(field,"chirp_rate",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> chirp_rate; } if (extract_xml_record(field,"rfi_checked",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> rfi_checked; } if (extract_xml_record(field,"rfi_found",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> rfi_found; } if (extract_xml_record(field,"reserved",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> reserved; } } } void spike_small::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { result_id.parse(SQL_ROW(s[1],0)); } { std::istringstream row(*(s[2])); row >> peak_power; } { std::istringstream row(*(s[3])); row >> mean_power; } { std::istringstream row(*(s[4])); row >> time; } { std::istringstream row(*(s[5])); row >> ra; } { std::istringstream row(*(s[6])); row >> decl; } { std::istringstream row(*(s[7])); row >> q_pix; } { std::istringstream row(*(s[8])); row >> freq; } { std::istringstream row(*(s[9])); row >> detection_freq; } { std::istringstream row(*(s[10])); row >> barycentric_freq; } { std::istringstream row(*(s[11])); row >> fft_len; } { std::istringstream row(*(s[12])); row >> chirp_rate; } { std::istringstream row(*(s[13])); row >> rfi_checked; } { std::istringstream row(*(s[14])); row >> rfi_found; } { std::istringstream row(*(s[15])); row >> reserved; } } void spike_small::parse(const std::string &s) { SQL_ROW row(&s,16); parse(row); } template <> const char * const db_table::table_name="autocorr"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=17; template <> const char * const db_table::column_names[17]={"id","result_id","peak_power","mean_power","time","ra","decl","q_pix","delay","freq","detection_freq","barycentric_freq","fft_len","chirp_rate","rfi_checked","rfi_found","reserved"}; autocorr::autocorr() : db_table(*this,-1), id(0), result_id(), peak_power(0), mean_power(0), time(0), ra(0), decl(0), q_pix(0), delay(0), freq(0), detection_freq(0), barycentric_freq(0), fft_len(0), chirp_rate(0), rfi_checked(0), rfi_found(0), reserved(0) { db_open(); } autocorr::autocorr(const autocorr &a) : db_table(*this,-1), id(a.id), result_id(a.result_id), peak_power(a.peak_power), mean_power(a.mean_power), time(a.time), ra(a.ra), decl(a.decl), q_pix(a.q_pix), delay(a.delay), freq(a.freq), detection_freq(a.detection_freq), barycentric_freq(a.barycentric_freq), fft_len(a.fft_len), chirp_rate(a.chirp_rate), rfi_checked(a.rfi_checked), rfi_found(a.rfi_found), reserved(a.reserved) { db_open(); } autocorr::autocorr(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } autocorr::autocorr(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } autocorr &autocorr::operator =(const autocorr &a) { if (&a != this) { id=a.id; result_id=a.result_id; peak_power=a.peak_power; mean_power=a.mean_power; time=a.time; ra=a.ra; decl=a.decl; q_pix=a.q_pix; delay=a.delay; freq=a.freq; detection_freq=a.detection_freq; barycentric_freq=a.barycentric_freq; fft_len=a.fft_len; chirp_rate=a.chirp_rate; rfi_checked=a.rfi_checked; rfi_found=a.rfi_found; reserved=a.reserved; } return (*this); } std::string autocorr::update_format() const { std::ostringstream rv(""); for (int i=2;i<17;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string autocorr::insert_format() const { return std::string("?,")+update_format(); } std::string autocorr::select_format() const { std::string rv(""); for (int i=0; i<16;i++) rv+="?,"; rv+="?"; return rv; } std::string autocorr::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; if (!no_refs) { if (full_subtables) { rv << result_id.print(full_subtables,show_ids,no_refs); } else { rv << result_id.id; } } rv << ','; rv << peak_power; rv << ','; rv << mean_power; rv << ','; rv << time; rv << ','; rv << ra; rv << ','; rv << decl; rv << ','; rv << q_pix; rv << ','; rv << delay; rv << ','; rv << freq; rv << ','; rv << detection_freq; rv << ','; rv << barycentric_freq; rv << ','; rv << fft_len; rv << ','; rv << chirp_rate; rv << ','; rv << rfi_checked; rv << ','; rv << rfi_found; rv << ','; rv << reserved; return rv.str(); } std::string autocorr::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; if (!no_refs) { if (full_subtables) { rv << result_id.print_xml(full_subtables,show_ids,no_refs,"result_id"); } else { rv << xml_indent() << "" << result_id.id << "\n"; } } rv << xml_indent() << "" << peak_power << "\n"; rv << xml_indent() << "" << mean_power << "\n"; rv << xml_indent() << "\n"; rv << xml_indent() << "" << ra << "\n"; rv << xml_indent() << "" << decl << "\n"; rv << xml_indent() << "" << q_pix << "\n"; rv << xml_indent() << "" << delay << "\n"; rv << xml_indent() << "" << freq << "\n"; rv << xml_indent() << "" << detection_freq << "\n"; rv << xml_indent() << "" << barycentric_freq << "\n"; rv << xml_indent() << "" << fft_len << "\n"; rv << xml_indent() << "" << chirp_rate << "\n"; rv << xml_indent() << "" << rfi_checked << "\n"; rv << xml_indent() << "" << rfi_found << "\n"; rv << xml_indent() << "" << reserved << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void autocorr::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"result_id",sub)) { result_id.parse_xml(sub,"result_id"); } if (extract_xml_record(field,"peak_power",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> peak_power; } if (extract_xml_record(field,"mean_power",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> mean_power; } if (extract_xml_record(field,"time",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> time; } if (extract_xml_record(field,"ra",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> ra; } if (extract_xml_record(field,"decl",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> decl; } if (extract_xml_record(field,"q_pix",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> q_pix; } if (extract_xml_record(field,"delay",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> delay; } if (extract_xml_record(field,"freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> freq; } if (extract_xml_record(field,"detection_freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> detection_freq; } if (extract_xml_record(field,"barycentric_freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> barycentric_freq; } if (extract_xml_record(field,"fft_len",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> fft_len; } if (extract_xml_record(field,"chirp_rate",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> chirp_rate; } if (extract_xml_record(field,"rfi_checked",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> rfi_checked; } if (extract_xml_record(field,"rfi_found",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> rfi_found; } if (extract_xml_record(field,"reserved",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> reserved; } } } void autocorr::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { result_id.parse(SQL_ROW(s[1],0)); } { std::istringstream row(*(s[2])); row >> peak_power; } { std::istringstream row(*(s[3])); row >> mean_power; } { std::istringstream row(*(s[4])); row >> time; } { std::istringstream row(*(s[5])); row >> ra; } { std::istringstream row(*(s[6])); row >> decl; } { std::istringstream row(*(s[7])); row >> q_pix; } { std::istringstream row(*(s[8])); row >> delay; } { std::istringstream row(*(s[9])); row >> freq; } { std::istringstream row(*(s[10])); row >> detection_freq; } { std::istringstream row(*(s[11])); row >> barycentric_freq; } { std::istringstream row(*(s[12])); row >> fft_len; } { std::istringstream row(*(s[13])); row >> chirp_rate; } { std::istringstream row(*(s[14])); row >> rfi_checked; } { std::istringstream row(*(s[15])); row >> rfi_found; } { std::istringstream row(*(s[16])); row >> reserved; } } void autocorr::parse(const std::string &s) { SQL_ROW row(&s,17); parse(row); } template <> const char * const db_table::table_name="autocorr_small"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=17; template <> const char * const db_table::column_names[17]={"id","result_id","peak_power","mean_power","time","ra","decl","q_pix","delay","freq","detection_freq","barycentric_freq","fft_len","chirp_rate","rfi_checked","rfi_found","reserved"}; autocorr_small::autocorr_small() : db_table(*this,-1), id(0), result_id(), peak_power(0), mean_power(0), time(0), ra(0), decl(0), q_pix(0), delay(0), freq(0), detection_freq(0), barycentric_freq(0), fft_len(0), chirp_rate(0), rfi_checked(0), rfi_found(0), reserved(0) { db_open(); } autocorr_small::autocorr_small(const autocorr_small &a) : db_table(*this,-1), id(a.id), result_id(a.result_id), peak_power(a.peak_power), mean_power(a.mean_power), time(a.time), ra(a.ra), decl(a.decl), q_pix(a.q_pix), delay(a.delay), freq(a.freq), detection_freq(a.detection_freq), barycentric_freq(a.barycentric_freq), fft_len(a.fft_len), chirp_rate(a.chirp_rate), rfi_checked(a.rfi_checked), rfi_found(a.rfi_found), reserved(a.reserved) { db_open(); } autocorr_small::autocorr_small(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } autocorr_small::autocorr_small(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } autocorr_small &autocorr_small::operator =(const autocorr_small &a) { if (&a != this) { id=a.id; result_id=a.result_id; peak_power=a.peak_power; mean_power=a.mean_power; time=a.time; ra=a.ra; decl=a.decl; q_pix=a.q_pix; delay=a.delay; freq=a.freq; detection_freq=a.detection_freq; barycentric_freq=a.barycentric_freq; fft_len=a.fft_len; chirp_rate=a.chirp_rate; rfi_checked=a.rfi_checked; rfi_found=a.rfi_found; reserved=a.reserved; } return (*this); } std::string autocorr_small::update_format() const { std::ostringstream rv(""); for (int i=2;i<17;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string autocorr_small::insert_format() const { return std::string("?,")+update_format(); } std::string autocorr_small::select_format() const { std::string rv(""); for (int i=0; i<16;i++) rv+="?,"; rv+="?"; return rv; } std::string autocorr_small::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; if (!no_refs) { if (full_subtables) { rv << result_id.print(full_subtables,show_ids,no_refs); } else { rv << result_id.id; } } rv << ','; rv << peak_power; rv << ','; rv << mean_power; rv << ','; rv << time; rv << ','; rv << ra; rv << ','; rv << decl; rv << ','; rv << q_pix; rv << ','; rv << delay; rv << ','; rv << freq; rv << ','; rv << detection_freq; rv << ','; rv << barycentric_freq; rv << ','; rv << fft_len; rv << ','; rv << chirp_rate; rv << ','; rv << rfi_checked; rv << ','; rv << rfi_found; rv << ','; rv << reserved; return rv.str(); } std::string autocorr_small::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; if (!no_refs) { if (full_subtables) { rv << result_id.print_xml(full_subtables,show_ids,no_refs,"result_id"); } else { rv << xml_indent() << "" << result_id.id << "\n"; } } rv << xml_indent() << "" << peak_power << "\n"; rv << xml_indent() << "" << mean_power << "\n"; rv << xml_indent() << "\n"; rv << xml_indent() << "" << ra << "\n"; rv << xml_indent() << "" << decl << "\n"; rv << xml_indent() << "" << q_pix << "\n"; rv << xml_indent() << "" << delay << "\n"; rv << xml_indent() << "" << freq << "\n"; rv << xml_indent() << "" << detection_freq << "\n"; rv << xml_indent() << "" << barycentric_freq << "\n"; rv << xml_indent() << "" << fft_len << "\n"; rv << xml_indent() << "" << chirp_rate << "\n"; rv << xml_indent() << "" << rfi_checked << "\n"; rv << xml_indent() << "" << rfi_found << "\n"; rv << xml_indent() << "" << reserved << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void autocorr_small::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"result_id",sub)) { result_id.parse_xml(sub,"result_id"); } if (extract_xml_record(field,"peak_power",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> peak_power; } if (extract_xml_record(field,"mean_power",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> mean_power; } if (extract_xml_record(field,"time",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> time; } if (extract_xml_record(field,"ra",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> ra; } if (extract_xml_record(field,"decl",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> decl; } if (extract_xml_record(field,"q_pix",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> q_pix; } if (extract_xml_record(field,"delay",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> delay; } if (extract_xml_record(field,"freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> freq; } if (extract_xml_record(field,"detection_freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> detection_freq; } if (extract_xml_record(field,"barycentric_freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> barycentric_freq; } if (extract_xml_record(field,"fft_len",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> fft_len; } if (extract_xml_record(field,"chirp_rate",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> chirp_rate; } if (extract_xml_record(field,"rfi_checked",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> rfi_checked; } if (extract_xml_record(field,"rfi_found",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> rfi_found; } if (extract_xml_record(field,"reserved",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> reserved; } } } void autocorr_small::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { result_id.parse(SQL_ROW(s[1],0)); } { std::istringstream row(*(s[2])); row >> peak_power; } { std::istringstream row(*(s[3])); row >> mean_power; } { std::istringstream row(*(s[4])); row >> time; } { std::istringstream row(*(s[5])); row >> ra; } { std::istringstream row(*(s[6])); row >> decl; } { std::istringstream row(*(s[7])); row >> q_pix; } { std::istringstream row(*(s[8])); row >> delay; } { std::istringstream row(*(s[9])); row >> freq; } { std::istringstream row(*(s[10])); row >> detection_freq; } { std::istringstream row(*(s[11])); row >> barycentric_freq; } { std::istringstream row(*(s[12])); row >> fft_len; } { std::istringstream row(*(s[13])); row >> chirp_rate; } { std::istringstream row(*(s[14])); row >> rfi_checked; } { std::istringstream row(*(s[15])); row >> rfi_found; } { std::istringstream row(*(s[16])); row >> reserved; } } void autocorr_small::parse(const std::string &s) { SQL_ROW row(&s,17); parse(row); } template <> const char * const db_table::table_name="classic_versions"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=10; template <> const char * const db_table::column_names[10]={"id","ver_major","ver_minor","platformid","comment","filename","md5_cksum","sum_cksum","cksum_cksum","file_cksum"}; classic_versions::classic_versions() : db_table(*this,-1), id(0), ver_major(0), ver_minor(0), platformid(0), file_cksum(0) { db_open(); comment[0]=0; filename[0]=0; md5_cksum[0]=0; sum_cksum[0]=0; cksum_cksum[0]=0; } classic_versions::classic_versions(const classic_versions &a) : db_table(*this,-1), id(a.id), ver_major(a.ver_major), ver_minor(a.ver_minor), platformid(a.platformid), file_cksum(a.file_cksum) { db_open(); strcpy(comment,a.comment); strcpy(filename,a.filename); strcpy(md5_cksum,a.md5_cksum); strcpy(sum_cksum,a.sum_cksum); strcpy(cksum_cksum,a.cksum_cksum); } classic_versions::classic_versions(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } classic_versions::classic_versions(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } classic_versions &classic_versions::operator =(const classic_versions &a) { if (&a != this) { id=a.id; ver_major=a.ver_major; ver_minor=a.ver_minor; platformid=a.platformid; file_cksum=a.file_cksum; strcpy(comment,a.comment); strcpy(filename,a.filename); strcpy(md5_cksum,a.md5_cksum); strcpy(sum_cksum,a.sum_cksum); strcpy(cksum_cksum,a.cksum_cksum); } return (*this); } std::string classic_versions::update_format() const { std::ostringstream rv(""); for (int i=2;i<10;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string classic_versions::insert_format() const { return std::string("?,")+update_format(); } std::string classic_versions::select_format() const { std::string rv(""); for (int i=0; i<9;i++) rv+="?,"; rv+="?"; return rv; } std::string classic_versions::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; rv << ver_major; rv << ','; rv << ver_minor; rv << ','; rv << platformid; rv << ','; rv << "'" << comment << "'"; rv << ','; rv << "'" << filename << "'"; rv << ','; rv << "'" << md5_cksum << "'"; rv << ','; rv << "'" << sum_cksum << "'"; rv << ','; rv << "'" << cksum_cksum << "'"; rv << ','; rv << file_cksum; return rv.str(); } std::string classic_versions::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; rv << xml_indent() << "" << ver_major << "\n"; rv << xml_indent() << "" << ver_minor << "\n"; rv << xml_indent() << "" << platformid << "\n"; { std::string enc_field=xml_encode_string(comment,std::min(strlen(comment),sizeof(comment))); rv << xml_indent() << ""; rv << enc_field << "\n"; } { std::string enc_field=xml_encode_string(filename,std::min(strlen(filename),sizeof(filename))); rv << xml_indent() << ""; rv << enc_field << "\n"; } { std::string enc_field=xml_encode_string(md5_cksum,std::min(strlen(md5_cksum),sizeof(md5_cksum))); rv << xml_indent() << ""; rv << enc_field << "\n"; } { std::string enc_field=xml_encode_string(sum_cksum,std::min(strlen(sum_cksum),sizeof(sum_cksum))); rv << xml_indent() << ""; rv << enc_field << "\n"; } { std::string enc_field=xml_encode_string(cksum_cksum,std::min(strlen(cksum_cksum),sizeof(cksum_cksum))); rv << xml_indent() << ""; rv << enc_field << "\n"; } rv << xml_indent() << "" << file_cksum << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void classic_versions::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"ver_major",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> ver_major; } if (extract_xml_record(field,"ver_minor",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> ver_minor; } if (extract_xml_record(field,"platformid",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> platformid; } if (extract_xml_record(field,"comment",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::string::size_type epos=sub.find("<",pos); if (epos==std::string::npos) epos=sub.find('\n',pos); if (epos==std::string::npos) epos=pos+strlen(sub.c_str()+pos); std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); strncpy(comment,(const char *)&(in.front()),std::min(in.size(),(size_t)254)); comment[std::min(in.size(),(size_t)253)]=0; } if (extract_xml_record(field,"filename",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::string::size_type epos=sub.find("<",pos); if (epos==std::string::npos) epos=sub.find('\n',pos); if (epos==std::string::npos) epos=pos+strlen(sub.c_str()+pos); std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); strncpy(filename,(const char *)&(in.front()),std::min(in.size(),(size_t)254)); filename[std::min(in.size(),(size_t)253)]=0; } if (extract_xml_record(field,"md5_cksum",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::string::size_type epos=sub.find("<",pos); if (epos==std::string::npos) epos=sub.find('\n',pos); if (epos==std::string::npos) epos=pos+strlen(sub.c_str()+pos); std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); strncpy(md5_cksum,(const char *)&(in.front()),std::min(in.size(),(size_t)254)); md5_cksum[std::min(in.size(),(size_t)253)]=0; } if (extract_xml_record(field,"sum_cksum",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::string::size_type epos=sub.find("<",pos); if (epos==std::string::npos) epos=sub.find('\n',pos); if (epos==std::string::npos) epos=pos+strlen(sub.c_str()+pos); std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); strncpy(sum_cksum,(const char *)&(in.front()),std::min(in.size(),(size_t)254)); sum_cksum[std::min(in.size(),(size_t)253)]=0; } if (extract_xml_record(field,"cksum_cksum",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::string::size_type epos=sub.find("<",pos); if (epos==std::string::npos) epos=sub.find('\n',pos); if (epos==std::string::npos) epos=pos+strlen(sub.c_str()+pos); std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); strncpy(cksum_cksum,(const char *)&(in.front()),std::min(in.size(),(size_t)254)); cksum_cksum[std::min(in.size(),(size_t)253)]=0; } if (extract_xml_record(field,"file_cksum",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> file_cksum; } } } void classic_versions::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { std::istringstream row(*(s[1])); row >> ver_major; } { std::istringstream row(*(s[2])); row >> ver_minor; } { std::istringstream row(*(s[3])); row >> platformid; } { strncpy(comment,s[4]->c_str(),254); comment[253]=0; } { strncpy(filename,s[5]->c_str(),254); filename[253]=0; } { strncpy(md5_cksum,s[6]->c_str(),254); md5_cksum[253]=0; } { strncpy(sum_cksum,s[7]->c_str(),254); sum_cksum[253]=0; } { strncpy(cksum_cksum,s[8]->c_str(),254); cksum_cksum[253]=0; } { std::istringstream row(*(s[9])); row >> file_cksum; } } void classic_versions::parse(const std::string &s) { SQL_ROW row(&s,10); parse(row); } template <> const char * const db_table::table_name="classic_active_versions"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=4; template <> const char * const db_table::column_names[4]={"id","versionid","ver_major","ver_minor"}; classic_active_versions::classic_active_versions() : db_table(*this,-1), id(0), versionid(0), ver_major(0), ver_minor(0) { db_open(); } classic_active_versions::classic_active_versions(const classic_active_versions &a) : db_table(*this,-1), id(a.id), versionid(a.versionid), ver_major(a.ver_major), ver_minor(a.ver_minor) { db_open(); } classic_active_versions::classic_active_versions(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } classic_active_versions::classic_active_versions(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } classic_active_versions &classic_active_versions::operator =(const classic_active_versions &a) { if (&a != this) { id=a.id; versionid=a.versionid; ver_major=a.ver_major; ver_minor=a.ver_minor; } return (*this); } std::string classic_active_versions::update_format() const { std::ostringstream rv(""); for (int i=2;i<4;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string classic_active_versions::insert_format() const { return std::string("?,")+update_format(); } std::string classic_active_versions::select_format() const { std::string rv(""); for (int i=0; i<3;i++) rv+="?,"; rv+="?"; return rv; } std::string classic_active_versions::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; rv << versionid; rv << ','; rv << ver_major; rv << ','; rv << ver_minor; return rv.str(); } std::string classic_active_versions::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; rv << xml_indent() << "" << versionid << "\n"; rv << xml_indent() << "" << ver_major << "\n"; rv << xml_indent() << "" << ver_minor << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void classic_active_versions::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"versionid",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> versionid; } if (extract_xml_record(field,"ver_major",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> ver_major; } if (extract_xml_record(field,"ver_minor",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> ver_minor; } } } void classic_active_versions::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { std::istringstream row(*(s[1])); row >> versionid; } { std::istringstream row(*(s[2])); row >> ver_major; } { std::istringstream row(*(s[3])); row >> ver_minor; } } void classic_active_versions::parse(const std::string &s) { SQL_ROW row(&s,4); parse(row); } template <> const char * const db_table::table_name="classic_active_versionids"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=2; template <> const char * const db_table::column_names[2]={"id","versionid"}; classic_active_versionids::classic_active_versionids() : db_table(*this,-1), id(0), versionid(0) { db_open(); } classic_active_versionids::classic_active_versionids(const classic_active_versionids &a) : db_table(*this,-1), id(a.id), versionid(a.versionid) { db_open(); } classic_active_versionids::classic_active_versionids(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } classic_active_versionids::classic_active_versionids(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } classic_active_versionids &classic_active_versionids::operator =(const classic_active_versionids &a) { if (&a != this) { id=a.id; versionid=a.versionid; } return (*this); } std::string classic_active_versionids::update_format() const { std::ostringstream rv(""); for (int i=2;i<2;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string classic_active_versionids::insert_format() const { return std::string("?,")+update_format(); } std::string classic_active_versionids::select_format() const { std::string rv(""); for (int i=0; i<1;i++) rv+="?,"; rv+="?"; return rv; } std::string classic_active_versionids::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; rv << versionid; return rv.str(); } std::string classic_active_versionids::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; rv << xml_indent() << "" << versionid << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void classic_active_versionids::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"versionid",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> versionid; } } } void classic_active_versionids::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { std::istringstream row(*(s[1])); row >> versionid; } } void classic_active_versionids::parse(const std::string &s) { SQL_ROW row(&s,2); parse(row); } template <> const char * const db_table::table_name="rfi_zone"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=26; template <> const char * const db_table::column_names[26]={"id","min_receiver_s4id","max_receiver_s4id","min_splitter_config","max_splitter_config","min_analysis_config","max_analysis_config","min_tape_id","max_tape_id","min_workunit_id","max_workunit_id","min_result_id","max_result_id","min_time","max_time","central_baseband_freq","baseband_freq_width","central_detection_freq","detection_freq_width","central_period","period_width","fft_len_flags","signal_type_flags","ra","dec","angular_distance"}; rfi_zone::rfi_zone() : db_table(*this,-1), id(0), min_receiver_s4id(0), max_receiver_s4id(0), min_splitter_config(0), max_splitter_config(0), min_analysis_config(0), max_analysis_config(0), min_tape_id(0), max_tape_id(0), min_workunit_id(0), max_workunit_id(0), min_result_id(0), max_result_id(0), min_time(0), max_time(0), central_baseband_freq(0), baseband_freq_width(0), central_detection_freq(0), detection_freq_width(0), central_period(0), period_width(0), fft_len_flags(0), signal_type_flags(0), ra(0), dec(0), angular_distance(0) { db_open(); } rfi_zone::rfi_zone(const rfi_zone &a) : db_table(*this,-1), id(a.id), min_receiver_s4id(a.min_receiver_s4id), max_receiver_s4id(a.max_receiver_s4id), min_splitter_config(a.min_splitter_config), max_splitter_config(a.max_splitter_config), min_analysis_config(a.min_analysis_config), max_analysis_config(a.max_analysis_config), min_tape_id(a.min_tape_id), max_tape_id(a.max_tape_id), min_workunit_id(a.min_workunit_id), max_workunit_id(a.max_workunit_id), min_result_id(a.min_result_id), max_result_id(a.max_result_id), min_time(a.min_time), max_time(a.max_time), central_baseband_freq(a.central_baseband_freq), baseband_freq_width(a.baseband_freq_width), central_detection_freq(a.central_detection_freq), detection_freq_width(a.detection_freq_width), central_period(a.central_period), period_width(a.period_width), fft_len_flags(a.fft_len_flags), signal_type_flags(a.signal_type_flags), ra(a.ra), dec(a.dec), angular_distance(a.angular_distance) { db_open(); } rfi_zone::rfi_zone(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } rfi_zone::rfi_zone(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } rfi_zone &rfi_zone::operator =(const rfi_zone &a) { if (&a != this) { id=a.id; min_receiver_s4id=a.min_receiver_s4id; max_receiver_s4id=a.max_receiver_s4id; min_splitter_config=a.min_splitter_config; max_splitter_config=a.max_splitter_config; min_analysis_config=a.min_analysis_config; max_analysis_config=a.max_analysis_config; min_tape_id=a.min_tape_id; max_tape_id=a.max_tape_id; min_workunit_id=a.min_workunit_id; max_workunit_id=a.max_workunit_id; min_result_id=a.min_result_id; max_result_id=a.max_result_id; min_time=a.min_time; max_time=a.max_time; central_baseband_freq=a.central_baseband_freq; baseband_freq_width=a.baseband_freq_width; central_detection_freq=a.central_detection_freq; detection_freq_width=a.detection_freq_width; central_period=a.central_period; period_width=a.period_width; fft_len_flags=a.fft_len_flags; signal_type_flags=a.signal_type_flags; ra=a.ra; dec=a.dec; angular_distance=a.angular_distance; } return (*this); } std::string rfi_zone::update_format() const { std::ostringstream rv(""); for (int i=2;i<26;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string rfi_zone::insert_format() const { return std::string("?,")+update_format(); } std::string rfi_zone::select_format() const { std::string rv(""); for (int i=0; i<25;i++) rv+="?,"; rv+="?"; return rv; } std::string rfi_zone::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; rv << min_receiver_s4id; rv << ','; rv << max_receiver_s4id; rv << ','; rv << min_splitter_config; rv << ','; rv << max_splitter_config; rv << ','; rv << min_analysis_config; rv << ','; rv << max_analysis_config; rv << ','; rv << min_tape_id; rv << ','; rv << max_tape_id; rv << ','; rv << min_workunit_id; rv << ','; rv << max_workunit_id; rv << ','; rv << min_result_id; rv << ','; rv << max_result_id; rv << ','; rv << min_time; rv << ','; rv << max_time; rv << ','; rv << central_baseband_freq; rv << ','; rv << baseband_freq_width; rv << ','; rv << central_detection_freq; rv << ','; rv << detection_freq_width; rv << ','; rv << central_period; rv << ','; rv << period_width; rv << ','; rv << fft_len_flags; rv << ','; rv << signal_type_flags; rv << ','; rv << ra; rv << ','; rv << dec; rv << ','; rv << angular_distance; return rv.str(); } std::string rfi_zone::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; rv << xml_indent() << "" << min_receiver_s4id << "\n"; rv << xml_indent() << "" << max_receiver_s4id << "\n"; rv << xml_indent() << "" << min_splitter_config << "\n"; rv << xml_indent() << "" << max_splitter_config << "\n"; rv << xml_indent() << "" << min_analysis_config << "\n"; rv << xml_indent() << "" << max_analysis_config << "\n"; rv << xml_indent() << "" << min_tape_id << "\n"; rv << xml_indent() << "" << max_tape_id << "\n"; rv << xml_indent() << "" << min_workunit_id << "\n"; rv << xml_indent() << "" << max_workunit_id << "\n"; rv << xml_indent() << "" << min_result_id << "\n"; rv << xml_indent() << "" << max_result_id << "\n"; rv << xml_indent() << "" << min_time << "\n"; rv << xml_indent() << "" << max_time << "\n"; rv << xml_indent() << "" << central_baseband_freq << "\n"; rv << xml_indent() << "" << baseband_freq_width << "\n"; rv << xml_indent() << "" << central_detection_freq << "\n"; rv << xml_indent() << "" << detection_freq_width << "\n"; rv << xml_indent() << "" << central_period << "\n"; rv << xml_indent() << "" << period_width << "\n"; rv << xml_indent() << "" << fft_len_flags << "\n"; rv << xml_indent() << "" << signal_type_flags << "\n"; rv << xml_indent() << "" << ra << "\n"; rv << xml_indent() << "" << dec << "\n"; rv << xml_indent() << "" << angular_distance << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void rfi_zone::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"min_receiver_s4id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> min_receiver_s4id; } if (extract_xml_record(field,"max_receiver_s4id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> max_receiver_s4id; } if (extract_xml_record(field,"min_splitter_config",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> min_splitter_config; } if (extract_xml_record(field,"max_splitter_config",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> max_splitter_config; } if (extract_xml_record(field,"min_analysis_config",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> min_analysis_config; } if (extract_xml_record(field,"max_analysis_config",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> max_analysis_config; } if (extract_xml_record(field,"min_tape_id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> min_tape_id; } if (extract_xml_record(field,"max_tape_id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> max_tape_id; } if (extract_xml_record(field,"min_workunit_id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> min_workunit_id; } if (extract_xml_record(field,"max_workunit_id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> max_workunit_id; } if (extract_xml_record(field,"min_result_id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> min_result_id; } if (extract_xml_record(field,"max_result_id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> max_result_id; } if (extract_xml_record(field,"min_time",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> min_time; } if (extract_xml_record(field,"max_time",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> max_time; } if (extract_xml_record(field,"central_baseband_freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> central_baseband_freq; } if (extract_xml_record(field,"baseband_freq_width",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> baseband_freq_width; } if (extract_xml_record(field,"central_detection_freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> central_detection_freq; } if (extract_xml_record(field,"detection_freq_width",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> detection_freq_width; } if (extract_xml_record(field,"central_period",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> central_period; } if (extract_xml_record(field,"period_width",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> period_width; } if (extract_xml_record(field,"fft_len_flags",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> fft_len_flags; } if (extract_xml_record(field,"signal_type_flags",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> signal_type_flags; } if (extract_xml_record(field,"ra",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> ra; } if (extract_xml_record(field,"dec",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> dec; } if (extract_xml_record(field,"angular_distance",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> angular_distance; } } } void rfi_zone::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { std::istringstream row(*(s[1])); row >> min_receiver_s4id; } { std::istringstream row(*(s[2])); row >> max_receiver_s4id; } { std::istringstream row(*(s[3])); row >> min_splitter_config; } { std::istringstream row(*(s[4])); row >> max_splitter_config; } { std::istringstream row(*(s[5])); row >> min_analysis_config; } { std::istringstream row(*(s[6])); row >> max_analysis_config; } { std::istringstream row(*(s[7])); row >> min_tape_id; } { std::istringstream row(*(s[8])); row >> max_tape_id; } { std::istringstream row(*(s[9])); row >> min_workunit_id; } { std::istringstream row(*(s[10])); row >> max_workunit_id; } { std::istringstream row(*(s[11])); row >> min_result_id; } { std::istringstream row(*(s[12])); row >> max_result_id; } { std::istringstream row(*(s[13])); row >> min_time; } { std::istringstream row(*(s[14])); row >> max_time; } { std::istringstream row(*(s[15])); row >> central_baseband_freq; } { std::istringstream row(*(s[16])); row >> baseband_freq_width; } { std::istringstream row(*(s[17])); row >> central_detection_freq; } { std::istringstream row(*(s[18])); row >> detection_freq_width; } { std::istringstream row(*(s[19])); row >> central_period; } { std::istringstream row(*(s[20])); row >> period_width; } { std::istringstream row(*(s[21])); row >> fft_len_flags; } { std::istringstream row(*(s[22])); row >> signal_type_flags; } { std::istringstream row(*(s[23])); row >> ra; } { std::istringstream row(*(s[24])); row >> dec; } { std::istringstream row(*(s[25])); row >> angular_distance; } } void rfi_zone::parse(const std::string &s) { SQL_ROW row(&s,26); parse(row); } template <> const char * const db_table::table_name="bad_data"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=3; template <> const char * const db_table::column_names[3]={"name","beam""reason"}; bad_data::bad_data() : db_table(*this,-1), beam(0) { db_open(); name[0]=0; reason[0]=0; } bad_data::bad_data(const bad_data &a) : db_table(*this,-1), beam(a.beam) { db_open(); strcpy(name,a.name); strcpy(reason,a.reason); } bad_data::bad_data(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } bad_data::bad_data(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } bad_data &bad_data::operator =(const bad_data &a) { if (&a != this) { beam=a.beam; strcpy(name,a.name); strcpy(reason,a.reason); } return (*this); } std::string bad_data::update_format() const { std::ostringstream rv(""); for (int i=2;i<3;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string bad_data::insert_format() const { return std::string("?,")+update_format(); } std::string bad_data::select_format() const { std::string rv(""); for (int i=0; i<2;i++) rv+="?,"; rv+="?"; return rv; } std::string bad_data::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); rv << "'" << name << "'"; rv << ','; rv << beam; rv << ','; rv << "'" << reason << "'"; return rv.str(); } std::string bad_data::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); { std::string enc_field=xml_encode_string(name,std::min(strlen(name),sizeof(name))); rv << xml_indent() << ""; rv << enc_field << "\n"; } rv << xml_indent() << "" << beam << "\n"; { std::string enc_field=xml_encode_string(reason,std::min(strlen(reason),sizeof(reason))); rv << xml_indent() << ""; rv << enc_field << "\n"; } xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void bad_data::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"name",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::string::size_type epos=sub.find("<",pos); if (epos==std::string::npos) epos=sub.find('\n',pos); if (epos==std::string::npos) epos=pos+strlen(sub.c_str()+pos); std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); strncpy(name,(const char *)&(in.front()),std::min(in.size(),(size_t)128)); name[std::min(in.size(),(size_t)127)]=0; } if (extract_xml_record(field,"beam",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> beam; } if (extract_xml_record(field,"reason",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::string::size_type epos=sub.find("<",pos); if (epos==std::string::npos) epos=sub.find('\n',pos); if (epos==std::string::npos) epos=pos+strlen(sub.c_str()+pos); std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); strncpy(reason,(const char *)&(in.front()),std::min(in.size(),(size_t)255)); reason[std::min(in.size(),(size_t)254)]=0; } } } void bad_data::parse(const SQL_ROW &s) { { strncpy(name,s[0]->c_str(),128); name[127]=0; } { std::istringstream row(*(s[1])); row >> beam; } { strncpy(reason,s[2]->c_str(),255); reason[254]=0; } } void bad_data::parse(const std::string &s) { SQL_ROW row(&s,3); parse(row); } template <> const char * const db_table::table_name="spike_tinysky"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=16; template <> const char * const db_table::column_names[16]={"id","result_id","peak_power","mean_power","time","ra","decl","q_pix","freq","detection_freq","barycentric_freq","fft_len","chirp_rate","rfi_checked","rfi_found","reserved"}; spike_tinysky::spike_tinysky() : db_table(*this,-1), id(0), result_id(), peak_power(0), mean_power(0), time(0), ra(0), decl(0), q_pix(0), freq(0), detection_freq(0), barycentric_freq(0), fft_len(0), chirp_rate(0), rfi_checked(0), rfi_found(0), reserved(0) { db_open(); } spike_tinysky::spike_tinysky(const spike_tinysky &a) : db_table(*this,-1), id(a.id), result_id(a.result_id), peak_power(a.peak_power), mean_power(a.mean_power), time(a.time), ra(a.ra), decl(a.decl), q_pix(a.q_pix), freq(a.freq), detection_freq(a.detection_freq), barycentric_freq(a.barycentric_freq), fft_len(a.fft_len), chirp_rate(a.chirp_rate), rfi_checked(a.rfi_checked), rfi_found(a.rfi_found), reserved(a.reserved) { db_open(); } spike_tinysky::spike_tinysky(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } spike_tinysky::spike_tinysky(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } spike_tinysky &spike_tinysky::operator =(const spike_tinysky &a) { if (&a != this) { id=a.id; result_id=a.result_id; peak_power=a.peak_power; mean_power=a.mean_power; time=a.time; ra=a.ra; decl=a.decl; q_pix=a.q_pix; freq=a.freq; detection_freq=a.detection_freq; barycentric_freq=a.barycentric_freq; fft_len=a.fft_len; chirp_rate=a.chirp_rate; rfi_checked=a.rfi_checked; rfi_found=a.rfi_found; reserved=a.reserved; } return (*this); } std::string spike_tinysky::update_format() const { std::ostringstream rv(""); for (int i=2;i<16;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string spike_tinysky::insert_format() const { return std::string("?,")+update_format(); } std::string spike_tinysky::select_format() const { std::string rv(""); for (int i=0; i<15;i++) rv+="?,"; rv+="?"; return rv; } std::string spike_tinysky::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; if (!no_refs) { if (full_subtables) { rv << result_id.print(full_subtables,show_ids,no_refs); } else { rv << result_id.id; } } rv << ','; rv << peak_power; rv << ','; rv << mean_power; rv << ','; rv << time; rv << ','; rv << ra; rv << ','; rv << decl; rv << ','; rv << q_pix; rv << ','; rv << freq; rv << ','; rv << detection_freq; rv << ','; rv << barycentric_freq; rv << ','; rv << fft_len; rv << ','; rv << chirp_rate; rv << ','; rv << rfi_checked; rv << ','; rv << rfi_found; rv << ','; rv << reserved; return rv.str(); } std::string spike_tinysky::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; if (!no_refs) { if (full_subtables) { rv << result_id.print_xml(full_subtables,show_ids,no_refs,"result_id"); } else { rv << xml_indent() << "" << result_id.id << "\n"; } } rv << xml_indent() << "" << peak_power << "\n"; rv << xml_indent() << "" << mean_power << "\n"; rv << xml_indent() << "\n"; rv << xml_indent() << "" << ra << "\n"; rv << xml_indent() << "" << decl << "\n"; rv << xml_indent() << "" << q_pix << "\n"; rv << xml_indent() << "" << freq << "\n"; rv << xml_indent() << "" << detection_freq << "\n"; rv << xml_indent() << "" << barycentric_freq << "\n"; rv << xml_indent() << "" << fft_len << "\n"; rv << xml_indent() << "" << chirp_rate << "\n"; rv << xml_indent() << "" << rfi_checked << "\n"; rv << xml_indent() << "" << rfi_found << "\n"; rv << xml_indent() << "" << reserved << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void spike_tinysky::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"result_id",sub)) { result_id.parse_xml(sub,"result_id"); } if (extract_xml_record(field,"peak_power",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> peak_power; } if (extract_xml_record(field,"mean_power",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> mean_power; } if (extract_xml_record(field,"time",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> time; } if (extract_xml_record(field,"ra",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> ra; } if (extract_xml_record(field,"decl",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> decl; } if (extract_xml_record(field,"q_pix",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> q_pix; } if (extract_xml_record(field,"freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> freq; } if (extract_xml_record(field,"detection_freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> detection_freq; } if (extract_xml_record(field,"barycentric_freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> barycentric_freq; } if (extract_xml_record(field,"fft_len",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> fft_len; } if (extract_xml_record(field,"chirp_rate",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> chirp_rate; } if (extract_xml_record(field,"rfi_checked",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> rfi_checked; } if (extract_xml_record(field,"rfi_found",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> rfi_found; } if (extract_xml_record(field,"reserved",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> reserved; } } } void spike_tinysky::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { result_id.parse(SQL_ROW(s[1],0)); } { std::istringstream row(*(s[2])); row >> peak_power; } { std::istringstream row(*(s[3])); row >> mean_power; } { std::istringstream row(*(s[4])); row >> time; } { std::istringstream row(*(s[5])); row >> ra; } { std::istringstream row(*(s[6])); row >> decl; } { std::istringstream row(*(s[7])); row >> q_pix; } { std::istringstream row(*(s[8])); row >> freq; } { std::istringstream row(*(s[9])); row >> detection_freq; } { std::istringstream row(*(s[10])); row >> barycentric_freq; } { std::istringstream row(*(s[11])); row >> fft_len; } { std::istringstream row(*(s[12])); row >> chirp_rate; } { std::istringstream row(*(s[13])); row >> rfi_checked; } { std::istringstream row(*(s[14])); row >> rfi_found; } { std::istringstream row(*(s[15])); row >> reserved; } } void spike_tinysky::parse(const std::string &s) { SQL_ROW row(&s,16); parse(row); } template <> const char * const db_table::table_name="gaussian_tinysky"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=22; template <> const char * const db_table::column_names[22]={"id","result_id","peak_power","mean_power","time","ra","decl","q_pix","freq","detection_freq","barycentric_freq","fft_len","chirp_rate","rfi_checked","rfi_found","reserved","sigma","chisqr","null_chisqr","score","max_power","pot"}; gaussian_tinysky::gaussian_tinysky() : db_table(*this,-1), id(0), result_id(), peak_power(0), mean_power(0), time(0), ra(0), decl(0), q_pix(0), freq(0), detection_freq(0), barycentric_freq(0), fft_len(0), chirp_rate(0), rfi_checked(0), rfi_found(0), reserved(0), sigma(0), chisqr(0), null_chisqr(0), score(0), max_power(0), pot((unsigned char *)0,0,_x_csv) { db_open(); } gaussian_tinysky::gaussian_tinysky(const gaussian_tinysky &a) : db_table(*this,-1), id(a.id), result_id(a.result_id), peak_power(a.peak_power), mean_power(a.mean_power), time(a.time), ra(a.ra), decl(a.decl), q_pix(a.q_pix), freq(a.freq), detection_freq(a.detection_freq), barycentric_freq(a.barycentric_freq), fft_len(a.fft_len), chirp_rate(a.chirp_rate), rfi_checked(a.rfi_checked), rfi_found(a.rfi_found), reserved(a.reserved), sigma(a.sigma), chisqr(a.chisqr), null_chisqr(a.null_chisqr), score(a.score), max_power(a.max_power), pot(a.pot) { db_open(); } gaussian_tinysky::gaussian_tinysky(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } gaussian_tinysky::gaussian_tinysky(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } gaussian_tinysky &gaussian_tinysky::operator =(const gaussian_tinysky &a) { if (&a != this) { id=a.id; result_id=a.result_id; peak_power=a.peak_power; mean_power=a.mean_power; time=a.time; ra=a.ra; decl=a.decl; q_pix=a.q_pix; freq=a.freq; detection_freq=a.detection_freq; barycentric_freq=a.barycentric_freq; fft_len=a.fft_len; chirp_rate=a.chirp_rate; rfi_checked=a.rfi_checked; rfi_found=a.rfi_found; reserved=a.reserved; sigma=a.sigma; chisqr=a.chisqr; null_chisqr=a.null_chisqr; score=a.score; max_power=a.max_power; pot=a.pot; } return (*this); } std::string gaussian_tinysky::update_format() const { std::ostringstream rv(""); for (int i=2;i<22;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string gaussian_tinysky::insert_format() const { return std::string("?,")+update_format(); } std::string gaussian_tinysky::select_format() const { std::string rv(""); for (int i=0; i<21;i++) rv+="?,"; rv+="?"; return rv; } std::string gaussian_tinysky::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; if (!no_refs) { if (full_subtables) { rv << result_id.print(full_subtables,show_ids,no_refs); } else { rv << result_id.id; } } rv << ','; rv << peak_power; rv << ','; rv << mean_power; rv << ','; rv << time; rv << ','; rv << ra; rv << ','; rv << decl; rv << ','; rv << q_pix; rv << ','; rv << freq; rv << ','; rv << detection_freq; rv << ','; rv << barycentric_freq; rv << ','; rv << fft_len; rv << ','; rv << chirp_rate; rv << ','; rv << rfi_checked; rv << ','; rv << rfi_found; rv << ','; rv << reserved; rv << ','; rv << sigma; rv << ','; rv << chisqr; rv << ','; rv << null_chisqr; rv << ','; rv << score; rv << ','; rv << max_power; rv << ','; rv << "" << pot.print_hex() ; return rv.str(); } std::string gaussian_tinysky::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; if (!no_refs) { if (full_subtables) { rv << result_id.print_xml(full_subtables,show_ids,no_refs,"result_id"); } else { rv << xml_indent() << "" << result_id.id << "\n"; } } rv << xml_indent() << "" << peak_power << "\n"; rv << xml_indent() << "" << mean_power << "\n"; rv << xml_indent() << "\n"; rv << xml_indent() << "" << ra << "\n"; rv << xml_indent() << "" << decl << "\n"; rv << xml_indent() << "" << q_pix << "\n"; rv << xml_indent() << "" << freq << "\n"; rv << xml_indent() << "" << detection_freq << "\n"; rv << xml_indent() << "" << barycentric_freq << "\n"; rv << xml_indent() << "" << fft_len << "\n"; rv << xml_indent() << "" << chirp_rate << "\n"; rv << xml_indent() << "" << rfi_checked << "\n"; rv << xml_indent() << "" << rfi_found << "\n"; rv << xml_indent() << "" << reserved << "\n"; rv << xml_indent() << "" << sigma << "\n"; rv << xml_indent() << "" << chisqr << "\n"; rv << xml_indent() << "" << null_chisqr << "\n"; rv << xml_indent() << "" << score << "\n"; rv << xml_indent() << "" << max_power << "\n"; if (pot.size()) { std::string enc_field=xml_encode_string(pot,pot.encoding); rv << xml_indent() << ""; rv << enc_field << "\n"; } xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void gaussian_tinysky::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"result_id",sub)) { result_id.parse_xml(sub,"result_id"); } if (extract_xml_record(field,"peak_power",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> peak_power; } if (extract_xml_record(field,"mean_power",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> mean_power; } if (extract_xml_record(field,"time",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> time; } if (extract_xml_record(field,"ra",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> ra; } if (extract_xml_record(field,"decl",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> decl; } if (extract_xml_record(field,"q_pix",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> q_pix; } if (extract_xml_record(field,"freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> freq; } if (extract_xml_record(field,"detection_freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> detection_freq; } if (extract_xml_record(field,"barycentric_freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> barycentric_freq; } if (extract_xml_record(field,"fft_len",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> fft_len; } if (extract_xml_record(field,"chirp_rate",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> chirp_rate; } if (extract_xml_record(field,"rfi_checked",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> rfi_checked; } if (extract_xml_record(field,"rfi_found",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> rfi_found; } if (extract_xml_record(field,"reserved",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> reserved; } if (extract_xml_record(field,"sigma",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> sigma; } if (extract_xml_record(field,"chisqr",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> chisqr; } if (extract_xml_record(field,"null_chisqr",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> null_chisqr; } if (extract_xml_record(field,"score",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> score; } if (extract_xml_record(field,"max_power",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> max_power; } if (extract_xml_record(field,"pot",sub)) { std::istringstream in(sub.c_str()); in >> pot; } } } void gaussian_tinysky::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { result_id.parse(SQL_ROW(s[1],0)); } { std::istringstream row(*(s[2])); row >> peak_power; } { std::istringstream row(*(s[3])); row >> mean_power; } { std::istringstream row(*(s[4])); row >> time; } { std::istringstream row(*(s[5])); row >> ra; } { std::istringstream row(*(s[6])); row >> decl; } { std::istringstream row(*(s[7])); row >> q_pix; } { std::istringstream row(*(s[8])); row >> freq; } { std::istringstream row(*(s[9])); row >> detection_freq; } { std::istringstream row(*(s[10])); row >> barycentric_freq; } { std::istringstream row(*(s[11])); row >> fft_len; } { std::istringstream row(*(s[12])); row >> chirp_rate; } { std::istringstream row(*(s[13])); row >> rfi_checked; } { std::istringstream row(*(s[14])); row >> rfi_found; } { std::istringstream row(*(s[15])); row >> reserved; } { std::istringstream row(*(s[16])); row >> sigma; } { std::istringstream row(*(s[17])); row >> chisqr; } { std::istringstream row(*(s[18])); row >> null_chisqr; } { std::istringstream row(*(s[19])); row >> score; } { std::istringstream row(*(s[20])); row >> max_power; } { pot=sqlblob(*(s[21])); } } void gaussian_tinysky::parse(const std::string &s) { SQL_ROW row(&s,22); parse(row); } template <> const char * const db_table::table_name="pulse_tinysky"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=22; template <> const char * const db_table::column_names[22]={"id","result_id","peak_power","mean_power","time","ra","decl","q_pix","freq","detection_freq","barycentric_freq","fft_len","chirp_rate","rfi_checked","rfi_found","reserved","period","snr","thresh","score","len_prof","pot"}; pulse_tinysky::pulse_tinysky() : db_table(*this,-1), id(0), result_id(), peak_power(0), mean_power(0), time(0), ra(0), decl(0), q_pix(0), freq(0), detection_freq(0), barycentric_freq(0), fft_len(0), chirp_rate(0), rfi_checked(0), rfi_found(0), reserved(0), period(0), snr(0), thresh(0), score(0), len_prof(0), pot((unsigned char *)0,0,_x_csv) { db_open(); } pulse_tinysky::pulse_tinysky(const pulse_tinysky &a) : db_table(*this,-1), id(a.id), result_id(a.result_id), peak_power(a.peak_power), mean_power(a.mean_power), time(a.time), ra(a.ra), decl(a.decl), q_pix(a.q_pix), freq(a.freq), detection_freq(a.detection_freq), barycentric_freq(a.barycentric_freq), fft_len(a.fft_len), chirp_rate(a.chirp_rate), rfi_checked(a.rfi_checked), rfi_found(a.rfi_found), reserved(a.reserved), period(a.period), snr(a.snr), thresh(a.thresh), score(a.score), len_prof(a.len_prof), pot(a.pot) { db_open(); } pulse_tinysky::pulse_tinysky(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } pulse_tinysky::pulse_tinysky(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } pulse_tinysky &pulse_tinysky::operator =(const pulse_tinysky &a) { if (&a != this) { id=a.id; result_id=a.result_id; peak_power=a.peak_power; mean_power=a.mean_power; time=a.time; ra=a.ra; decl=a.decl; q_pix=a.q_pix; freq=a.freq; detection_freq=a.detection_freq; barycentric_freq=a.barycentric_freq; fft_len=a.fft_len; chirp_rate=a.chirp_rate; rfi_checked=a.rfi_checked; rfi_found=a.rfi_found; reserved=a.reserved; period=a.period; snr=a.snr; thresh=a.thresh; score=a.score; len_prof=a.len_prof; pot=a.pot; } return (*this); } std::string pulse_tinysky::update_format() const { std::ostringstream rv(""); for (int i=2;i<22;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string pulse_tinysky::insert_format() const { return std::string("?,")+update_format(); } std::string pulse_tinysky::select_format() const { std::string rv(""); for (int i=0; i<21;i++) rv+="?,"; rv+="?"; return rv; } std::string pulse_tinysky::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; if (!no_refs) { if (full_subtables) { rv << result_id.print(full_subtables,show_ids,no_refs); } else { rv << result_id.id; } } rv << ','; rv << peak_power; rv << ','; rv << mean_power; rv << ','; rv << time; rv << ','; rv << ra; rv << ','; rv << decl; rv << ','; rv << q_pix; rv << ','; rv << freq; rv << ','; rv << detection_freq; rv << ','; rv << barycentric_freq; rv << ','; rv << fft_len; rv << ','; rv << chirp_rate; rv << ','; rv << rfi_checked; rv << ','; rv << rfi_found; rv << ','; rv << reserved; rv << ','; rv << period; rv << ','; rv << snr; rv << ','; rv << thresh; rv << ','; rv << score; rv << ','; rv << len_prof; rv << ','; rv << "" << pot.print_hex() ; return rv.str(); } std::string pulse_tinysky::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; if (!no_refs) { if (full_subtables) { rv << result_id.print_xml(full_subtables,show_ids,no_refs,"result_id"); } else { rv << xml_indent() << "" << result_id.id << "\n"; } } rv << xml_indent() << "" << peak_power << "\n"; rv << xml_indent() << "" << mean_power << "\n"; rv << xml_indent() << "\n"; rv << xml_indent() << "" << ra << "\n"; rv << xml_indent() << "" << decl << "\n"; rv << xml_indent() << "" << q_pix << "\n"; rv << xml_indent() << "" << freq << "\n"; rv << xml_indent() << "" << detection_freq << "\n"; rv << xml_indent() << "" << barycentric_freq << "\n"; rv << xml_indent() << "" << fft_len << "\n"; rv << xml_indent() << "" << chirp_rate << "\n"; rv << xml_indent() << "" << rfi_checked << "\n"; rv << xml_indent() << "" << rfi_found << "\n"; rv << xml_indent() << "" << reserved << "\n"; rv << xml_indent() << "" << period << "\n"; rv << xml_indent() << "" << snr << "\n"; rv << xml_indent() << "" << thresh << "\n"; rv << xml_indent() << "" << score << "\n"; rv << xml_indent() << "" << len_prof << "\n"; if (pot.size()) { std::string enc_field=xml_encode_string(pot,pot.encoding); rv << xml_indent() << ""; rv << enc_field << "\n"; } xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void pulse_tinysky::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"result_id",sub)) { result_id.parse_xml(sub,"result_id"); } if (extract_xml_record(field,"peak_power",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> peak_power; } if (extract_xml_record(field,"mean_power",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> mean_power; } if (extract_xml_record(field,"time",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> time; } if (extract_xml_record(field,"ra",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> ra; } if (extract_xml_record(field,"decl",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> decl; } if (extract_xml_record(field,"q_pix",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> q_pix; } if (extract_xml_record(field,"freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> freq; } if (extract_xml_record(field,"detection_freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> detection_freq; } if (extract_xml_record(field,"barycentric_freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> barycentric_freq; } if (extract_xml_record(field,"fft_len",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> fft_len; } if (extract_xml_record(field,"chirp_rate",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> chirp_rate; } if (extract_xml_record(field,"rfi_checked",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> rfi_checked; } if (extract_xml_record(field,"rfi_found",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> rfi_found; } if (extract_xml_record(field,"reserved",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> reserved; } if (extract_xml_record(field,"period",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> period; } if (extract_xml_record(field,"snr",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> snr; } if (extract_xml_record(field,"thresh",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> thresh; } if (extract_xml_record(field,"score",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> score; } if (extract_xml_record(field,"len_prof",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> len_prof; } if (extract_xml_record(field,"pot",sub)) { std::istringstream in(sub.c_str()); in >> pot; } } } void pulse_tinysky::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { result_id.parse(SQL_ROW(s[1],0)); } { std::istringstream row(*(s[2])); row >> peak_power; } { std::istringstream row(*(s[3])); row >> mean_power; } { std::istringstream row(*(s[4])); row >> time; } { std::istringstream row(*(s[5])); row >> ra; } { std::istringstream row(*(s[6])); row >> decl; } { std::istringstream row(*(s[7])); row >> q_pix; } { std::istringstream row(*(s[8])); row >> freq; } { std::istringstream row(*(s[9])); row >> detection_freq; } { std::istringstream row(*(s[10])); row >> barycentric_freq; } { std::istringstream row(*(s[11])); row >> fft_len; } { std::istringstream row(*(s[12])); row >> chirp_rate; } { std::istringstream row(*(s[13])); row >> rfi_checked; } { std::istringstream row(*(s[14])); row >> rfi_found; } { std::istringstream row(*(s[15])); row >> reserved; } { std::istringstream row(*(s[16])); row >> period; } { std::istringstream row(*(s[17])); row >> snr; } { std::istringstream row(*(s[18])); row >> thresh; } { std::istringstream row(*(s[19])); row >> score; } { std::istringstream row(*(s[20])); row >> len_prof; } { pot=sqlblob(*(s[21])); } } void pulse_tinysky::parse(const std::string &s) { SQL_ROW row(&s,22); parse(row); } template <> const char * const db_table::table_name="triplet_tinysky"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=17; template <> const char * const db_table::column_names[17]={"id","result_id","peak_power","mean_power","time","ra","decl","q_pix","freq","detection_freq","barycentric_freq","fft_len","chirp_rate","rfi_checked","rfi_found","reserved","period"}; triplet_tinysky::triplet_tinysky() : db_table(*this,-1), id(0), result_id(), peak_power(0), mean_power(0), time(0), ra(0), decl(0), q_pix(0), freq(0), detection_freq(0), barycentric_freq(0), fft_len(0), chirp_rate(0), rfi_checked(0), rfi_found(0), reserved(0), period(0) { db_open(); } triplet_tinysky::triplet_tinysky(const triplet_tinysky &a) : db_table(*this,-1), id(a.id), result_id(a.result_id), peak_power(a.peak_power), mean_power(a.mean_power), time(a.time), ra(a.ra), decl(a.decl), q_pix(a.q_pix), freq(a.freq), detection_freq(a.detection_freq), barycentric_freq(a.barycentric_freq), fft_len(a.fft_len), chirp_rate(a.chirp_rate), rfi_checked(a.rfi_checked), rfi_found(a.rfi_found), reserved(a.reserved), period(a.period) { db_open(); } triplet_tinysky::triplet_tinysky(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } triplet_tinysky::triplet_tinysky(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } triplet_tinysky &triplet_tinysky::operator =(const triplet_tinysky &a) { if (&a != this) { id=a.id; result_id=a.result_id; peak_power=a.peak_power; mean_power=a.mean_power; time=a.time; ra=a.ra; decl=a.decl; q_pix=a.q_pix; freq=a.freq; detection_freq=a.detection_freq; barycentric_freq=a.barycentric_freq; fft_len=a.fft_len; chirp_rate=a.chirp_rate; rfi_checked=a.rfi_checked; rfi_found=a.rfi_found; reserved=a.reserved; period=a.period; } return (*this); } std::string triplet_tinysky::update_format() const { std::ostringstream rv(""); for (int i=2;i<17;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string triplet_tinysky::insert_format() const { return std::string("?,")+update_format(); } std::string triplet_tinysky::select_format() const { std::string rv(""); for (int i=0; i<16;i++) rv+="?,"; rv+="?"; return rv; } std::string triplet_tinysky::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; if (!no_refs) { if (full_subtables) { rv << result_id.print(full_subtables,show_ids,no_refs); } else { rv << result_id.id; } } rv << ','; rv << peak_power; rv << ','; rv << mean_power; rv << ','; rv << time; rv << ','; rv << ra; rv << ','; rv << decl; rv << ','; rv << q_pix; rv << ','; rv << freq; rv << ','; rv << detection_freq; rv << ','; rv << barycentric_freq; rv << ','; rv << fft_len; rv << ','; rv << chirp_rate; rv << ','; rv << rfi_checked; rv << ','; rv << rfi_found; rv << ','; rv << reserved; rv << ','; rv << period; return rv.str(); } std::string triplet_tinysky::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; if (!no_refs) { if (full_subtables) { rv << result_id.print_xml(full_subtables,show_ids,no_refs,"result_id"); } else { rv << xml_indent() << "" << result_id.id << "\n"; } } rv << xml_indent() << "" << peak_power << "\n"; rv << xml_indent() << "" << mean_power << "\n"; rv << xml_indent() << "\n"; rv << xml_indent() << "" << ra << "\n"; rv << xml_indent() << "" << decl << "\n"; rv << xml_indent() << "" << q_pix << "\n"; rv << xml_indent() << "" << freq << "\n"; rv << xml_indent() << "" << detection_freq << "\n"; rv << xml_indent() << "" << barycentric_freq << "\n"; rv << xml_indent() << "" << fft_len << "\n"; rv << xml_indent() << "" << chirp_rate << "\n"; rv << xml_indent() << "" << rfi_checked << "\n"; rv << xml_indent() << "" << rfi_found << "\n"; rv << xml_indent() << "" << reserved << "\n"; rv << xml_indent() << "" << period << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void triplet_tinysky::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"result_id",sub)) { result_id.parse_xml(sub,"result_id"); } if (extract_xml_record(field,"peak_power",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> peak_power; } if (extract_xml_record(field,"mean_power",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> mean_power; } if (extract_xml_record(field,"time",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> time; } if (extract_xml_record(field,"ra",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> ra; } if (extract_xml_record(field,"decl",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> decl; } if (extract_xml_record(field,"q_pix",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> q_pix; } if (extract_xml_record(field,"freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> freq; } if (extract_xml_record(field,"detection_freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> detection_freq; } if (extract_xml_record(field,"barycentric_freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> barycentric_freq; } if (extract_xml_record(field,"fft_len",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> fft_len; } if (extract_xml_record(field,"chirp_rate",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> chirp_rate; } if (extract_xml_record(field,"rfi_checked",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> rfi_checked; } if (extract_xml_record(field,"rfi_found",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> rfi_found; } if (extract_xml_record(field,"reserved",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> reserved; } if (extract_xml_record(field,"period",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> period; } } } void triplet_tinysky::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { result_id.parse(SQL_ROW(s[1],0)); } { std::istringstream row(*(s[2])); row >> peak_power; } { std::istringstream row(*(s[3])); row >> mean_power; } { std::istringstream row(*(s[4])); row >> time; } { std::istringstream row(*(s[5])); row >> ra; } { std::istringstream row(*(s[6])); row >> decl; } { std::istringstream row(*(s[7])); row >> q_pix; } { std::istringstream row(*(s[8])); row >> freq; } { std::istringstream row(*(s[9])); row >> detection_freq; } { std::istringstream row(*(s[10])); row >> barycentric_freq; } { std::istringstream row(*(s[11])); row >> fft_len; } { std::istringstream row(*(s[12])); row >> chirp_rate; } { std::istringstream row(*(s[13])); row >> rfi_checked; } { std::istringstream row(*(s[14])); row >> rfi_found; } { std::istringstream row(*(s[15])); row >> reserved; } { std::istringstream row(*(s[16])); row >> period; } } void triplet_tinysky::parse(const std::string &s) { SQL_ROW row(&s,17); parse(row); } template <> const char * const db_table::table_name="autocorr_tinysky"; template <> const char * db_table::_search_tag=table_name; template <> const int db_table::_nfields=17; template <> const char * const db_table::column_names[17]={"id","result_id","peak_power","mean_power","time","ra","decl","q_pix","delay","freq","detection_freq","barycentric_freq","fft_len","chirp_rate","rfi_checked","rfi_found","reserved"}; autocorr_tinysky::autocorr_tinysky() : db_table(*this,-1), id(0), result_id(), peak_power(0), mean_power(0), time(0), ra(0), decl(0), q_pix(0), delay(0), freq(0), detection_freq(0), barycentric_freq(0), fft_len(0), chirp_rate(0), rfi_checked(0), rfi_found(0), reserved(0) { db_open(); } autocorr_tinysky::autocorr_tinysky(const autocorr_tinysky &a) : db_table(*this,-1), id(a.id), result_id(a.result_id), peak_power(a.peak_power), mean_power(a.mean_power), time(a.time), ra(a.ra), decl(a.decl), q_pix(a.q_pix), delay(a.delay), freq(a.freq), detection_freq(a.detection_freq), barycentric_freq(a.barycentric_freq), fft_len(a.fft_len), chirp_rate(a.chirp_rate), rfi_checked(a.rfi_checked), rfi_found(a.rfi_found), reserved(a.reserved) { db_open(); } autocorr_tinysky::autocorr_tinysky(const SQL_ROW &a) : db_table(*this,-1) { db_open(); parse(a); } autocorr_tinysky::autocorr_tinysky(const std::string &s,const char *tag) : db_table(*this,-1) { db_open(); if (xml_match_tag(s,tag)) { parse_xml(s,tag); } else { parse(s); } } autocorr_tinysky &autocorr_tinysky::operator =(const autocorr_tinysky &a) { if (&a != this) { id=a.id; result_id=a.result_id; peak_power=a.peak_power; mean_power=a.mean_power; time=a.time; ra=a.ra; decl=a.decl; q_pix=a.q_pix; delay=a.delay; freq=a.freq; detection_freq=a.detection_freq; barycentric_freq=a.barycentric_freq; fft_len=a.fft_len; chirp_rate=a.chirp_rate; rfi_checked=a.rfi_checked; rfi_found=a.rfi_found; reserved=a.reserved; } return (*this); } std::string autocorr_tinysky::update_format() const { std::ostringstream rv(""); for (int i=2;i<17;i++) rv << "?,"; rv << "?"; return rv.str(); } std::string autocorr_tinysky::insert_format() const { return std::string("?,")+update_format(); } std::string autocorr_tinysky::select_format() const { std::string rv(""); for (int i=0; i<16;i++) rv+="?,"; rv+="?"; return rv; } std::string autocorr_tinysky::print(int full_subtables, int show_ids, int no_refs) const { std::ostringstream rv(""); rv.precision(14); if (show_ids) rv << id; rv << ','; if (!no_refs) { if (full_subtables) { rv << result_id.print(full_subtables,show_ids,no_refs); } else { rv << result_id.id; } } rv << ','; rv << peak_power; rv << ','; rv << mean_power; rv << ','; rv << time; rv << ','; rv << ra; rv << ','; rv << decl; rv << ','; rv << q_pix; rv << ','; rv << delay; rv << ','; rv << freq; rv << ','; rv << detection_freq; rv << ','; rv << barycentric_freq; rv << ','; rv << fft_len; rv << ','; rv << chirp_rate; rv << ','; rv << rfi_checked; rv << ','; rv << rfi_found; rv << ','; rv << reserved; return rv.str(); } std::string autocorr_tinysky::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { std::ostringstream rv(""); rv.precision(14); rv << xml_indent() << '<' << tag << ">\n"; xml_indent(2); if (show_ids) rv << xml_indent() << "" << id << "\n"; if (!no_refs) { if (full_subtables) { rv << result_id.print_xml(full_subtables,show_ids,no_refs,"result_id"); } else { rv << xml_indent() << "" << result_id.id << "\n"; } } rv << xml_indent() << "" << peak_power << "\n"; rv << xml_indent() << "" << mean_power << "\n"; rv << xml_indent() << "\n"; rv << xml_indent() << "" << ra << "\n"; rv << xml_indent() << "" << decl << "\n"; rv << xml_indent() << "" << q_pix << "\n"; rv << xml_indent() << "" << delay << "\n"; rv << xml_indent() << "" << freq << "\n"; rv << xml_indent() << "" << detection_freq << "\n"; rv << xml_indent() << "" << barycentric_freq << "\n"; rv << xml_indent() << "" << fft_len << "\n"; rv << xml_indent() << "" << chirp_rate << "\n"; rv << xml_indent() << "" << rfi_checked << "\n"; rv << xml_indent() << "" << rfi_found << "\n"; rv << xml_indent() << "" << reserved << "\n"; xml_indent(-2); rv << xml_indent() << "\n"; return rv.str(); } void autocorr_tinysky::parse_xml(const std::string &s,const char *tag) { std::string field,sub; if (extract_xml_record(s,tag,field)) { std::string::size_type pos=0; if (extract_xml_record(field,"id",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> id; } if (extract_xml_record(field,"result_id",sub)) { result_id.parse_xml(sub,"result_id"); } if (extract_xml_record(field,"peak_power",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> peak_power; } if (extract_xml_record(field,"mean_power",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> mean_power; } if (extract_xml_record(field,"time",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> time; } if (extract_xml_record(field,"ra",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> ra; } if (extract_xml_record(field,"decl",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> decl; } if (extract_xml_record(field,"q_pix",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> q_pix; } if (extract_xml_record(field,"delay",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> delay; } if (extract_xml_record(field,"freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> freq; } if (extract_xml_record(field,"detection_freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> detection_freq; } if (extract_xml_record(field,"barycentric_freq",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> barycentric_freq; } if (extract_xml_record(field,"fft_len",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> fft_len; } if (extract_xml_record(field,"chirp_rate",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> chirp_rate; } if (extract_xml_record(field,"rfi_checked",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> rfi_checked; } if (extract_xml_record(field,"rfi_found",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> rfi_found; } if (extract_xml_record(field,"reserved",sub)) { pos=sub.find(">"); do { pos++; } while(sub[pos]=='\n'); std::istringstream in(sub.c_str()+pos); in >> reserved; } } } void autocorr_tinysky::parse(const SQL_ROW &s) { { std::istringstream row(*(s[0])); row >> id; } { result_id.parse(SQL_ROW(s[1],0)); } { std::istringstream row(*(s[2])); row >> peak_power; } { std::istringstream row(*(s[3])); row >> mean_power; } { std::istringstream row(*(s[4])); row >> time; } { std::istringstream row(*(s[5])); row >> ra; } { std::istringstream row(*(s[6])); row >> decl; } { std::istringstream row(*(s[7])); row >> q_pix; } { std::istringstream row(*(s[8])); row >> delay; } { std::istringstream row(*(s[9])); row >> freq; } { std::istringstream row(*(s[10])); row >> detection_freq; } { std::istringstream row(*(s[11])); row >> barycentric_freq; } { std::istringstream row(*(s[12])); row >> fft_len; } { std::istringstream row(*(s[13])); row >> chirp_rate; } { std::istringstream row(*(s[14])); row >> rfi_checked; } { std::istringstream row(*(s[15])); row >> rfi_found; } { std::istringstream row(*(s[16])); row >> reserved; } } void autocorr_tinysky::parse(const std::string &s) { SQL_ROW row(&s,17); parse(row); } boinc-app-seti_8.00~svn3701.orig/db/schema_to_class.in0000755000175000017500000000237210671336410022566 0ustar locutuslocutus#!/bin/sh # Copyright 2003 Regents of the University of California # SETI_BOINC is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free # Software Foundation; either version 2, or (at your option) any later # version. # SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # more details. # You should have received a copy of the GNU General Public License along # with SETI_BOINC; see the file COPYING. If not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. filename=/tmp/`echo $1 | @SED@ 's/\.sql//'` echo begin_refs > $filename @AWK@ -f @SAH_TOP_DIR@/db/find_references.awk $1 | @SED@ 's/[(),;]//g' | @SORT@ | @UNIQ@ >> $filename echo end_refs >> $filename @CAT@ $1 | @TR@ "[A-Z]" "[a-z]" | @SED@ 's/\`//g' >>$filename @AWK@ -f @SAH_TOP_DIR@/db/schema_to_class.awk $filename INDENT=@INDENT@ if test -n "$INDENT" then @INDENT@ @INDENT_FLAGS@ $filename.h @INDENT@ @INDENT_FLAGS@ $filename.cpp fi @MV@ $filename.cpp . @MV@ $filename.h . @RM@ $filename* boinc-app-seti_8.00~svn3701.orig/db/sqlrow.h0000644000175000017500000000727412554454501020616 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef _SQLROW_H #define _SQLROW_H #undef swap #include #include #include #include #include #include #include "track_mem.h" #include "xml_util.h" typedef int SQL_CURSOR; class SQL_ROW; extern const SQL_ROW empty_row; extern const std::string empty_string; class SQL_ROW : track_mem { public: explicit SQL_ROW(const std::string *s=NULL,size_t i=0); explicit SQL_ROW(const std::vector &s); explicit SQL_ROW(const char **arr, int nfields); SQL_ROW(const SQL_ROW &r, size_t start_col=0, ssize_t end_col=-1); ~SQL_ROW(); SQL_ROW &operator=(const SQL_ROW &r); std::vector pval; size_t argc(size_t i); size_t argc() const; void clear(size_t i) { if ((pval.size()>i) && pval[i]) { delete pval[i]; #ifdef DEBUG_ALLOCATIONS fprintf(stderr,"std::string deleted at 0x%p\n",pval[i]); fflush(stderr); #endif } pval[i]=NULL; }; bool exists(size_t i) const { return ((pval.size()>i) && (pval[i])); } void clear() { pval.resize(0); } // operator char **(); SQL_ROW operator +(size_t i) const; std::string *&operator [](size_t i); const std::string *operator [](size_t i) const; // const char *operator [](int i) const; // char *operator *() const; private: std::string *string_delimited(std::string &s,char c_open,char c_close); std::vector parse_delimited(std::string &s,char c_open,char c_close); std::vector parse_type(std::string &s); std::vector parse_list(std::string &s); std::vector parse_row(std::string &s); std::string *parse_blob(std::string &s); }; //inline SQL_ROW::operator char **() {return static_cast(&(pval[0]));} inline std::string *&SQL_ROW::operator [](size_t i) {return pval[i];} inline const std::string *SQL_ROW::operator [] (size_t i) const { return (argc()>i)?pval[i]:&empty_string; } /* inline const char *SQL_ROW::operator [](int i) const { if (((unsigned)i)c_str()); } else { return ""; } } */ //inline char *SQL_ROW::operator *() const {return (pval[0]);} inline size_t SQL_ROW::argc(size_t i) { if (i > pval.size()) { while (pval.size() != i) { pval.push_back(new std::string(empty_string)); #ifdef DEBUG_ALLOCATIONS fprintf(stderr,"std::string allocated at 0x%p\n",pval[pval.size()-1]); fflush(stderr); #endif } } else { while (pval.size() != i) { if (pval[pval.size()-1]) { #ifdef DEBUG_ALLOCATIONS fprintf(stderr,"std::string deleted at 0x%p\n",pval[pval.size()-1]); fflush(stderr); #endif delete pval[pval.size()-1]; } pval.pop_back(); } } return pval.size(); } inline size_t SQL_ROW::argc() const {return pval.size();} inline SQL_ROW SQL_ROW::operator +(size_t i) const { return SQL_ROW(*this,i); } #endif boinc-app-seti_8.00~svn3701.orig/db/sqlblob.h0000644000175000017500000001761711152034765020726 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef _SQLBLOB_H_ #define _SQLBLOB_H_ #ifdef swap #undef swap #endif #include "sah_config.h" #ifndef _WIN32 #include #include #include #include #endif #include "track_mem.h" #include "sqldefs.h" #include "sqlrow.h" #include "xml_util.h" template class sqlblob; template std::ostream &operator <<(std::ostream &i, const sqlblob &b) { i << xml_encode_string(*(b.mem),b.encoding); return i; } template std::istream &operator >>(std::istream &i, sqlblob &b) { std::string buf(""),tmp; std::string::size_type b_start=0,b_end=0,b_encoding=0; const char *enc_string; if (sizeof(T)==1) { enc_string="x-xml-entity"; } else { enc_string="x-xml-values"; } while (!i.eof()) { i >> tmp; buf+=(tmp+' '); } b_start=buf.find('<'); b_end=std::min(buf.find('>',b_start+1),buf.find(' ',b_start+1)); std::string tag(std::string("',b_start+1); b_encoding=buf.find("encoding=",b_start); if (b_encoding < b_end) enc_string=buf.c_str()+b_encoding+strlen("encoding="); b_start=b_end+1; b_end=buf.find(tag); if (b.mem) { delete(b.mem); #ifdef DEBUG_ALLOCATIONS fprintf(stderr,"sqlblob: deleted a vector at 0x%p\n",b.mem); fflush(stderr); #endif } b.mem=new std::vector(xml_decode_string(buf.c_str()+b_start,b_end-b_start,enc_string)); b.encoding=(xml_encoding)xml_encoding_from_string(enc_string); #ifdef DEBUG_ALLOCATIONS fprintf(stderr,"sqlblob: allocated a vector at 0x%p\n",b.mem); fflush(stderr); #endif return i; } template std::string xml_encode_string(const sqlblob &input, xml_encoding encoding=_x_xml_entity) { return xml_encode_string(static_cast(&(*(input.mem))[0]),input.size(),encoding); } template class sqlblob : track_mem > { public: sqlblob(const sqlblob &b); explicit sqlblob(const T *p=0, size_t n_elements=0, xml_encoding e=_x_hex); explicit sqlblob(const std::string &s,xml_encoding e=_x_hex); explicit sqlblob(const std::vector &v, xml_encoding e=_x_hex); ~sqlblob(); // operator T *() { return &((*mem)[0]); }; // operator const T *() const { return &((*mem)[0]); }; // operator const char *() const { return (const char *)(&((*mem)[0])); }; T &at(int i) { return mem->at(i); } T &operator [](int i) { return (*mem)[i]; }; const T operator [](int i) const { return (*mem)[i]; } ; sqlblob &operator =(const sqlblob &b); sqlblob &operator =(const std::vector &b); size_t size() const { return mem->size(); }; size_t set_size(size_t n_elements); size_t resize(size_t n_elements); std::string print_xml() const; std::string print_hex() const; std::string print_raw() const; void parse_xml(std::string &field) { std::istringstream s(field); s >> *this; }; typename std::vector::const_iterator begin() const { return mem->begin(); }; typename std::vector::iterator begin() { return mem->begin(); }; typename std::vector::const_iterator end() const { return mem->end(); }; typename std::vector::iterator end() { return mem->end(); }; void push_back(const T &t) { mem->push_back(t); } ; void clear() { mem->clear(); } ; #if !defined(WIN32) || ( _MSC_VER > 1300 ) || defined(__MINGW32__) // VC 7 or newer friend std::ostream &operator << (std::ostream &o, const sqlblob &b); friend std::istream &operator >> (std::istream &o, sqlblob &b); friend std::string xml_encode_string(const sqlblob &b,xml_encoding encoding); #else // VC6 or earlier friend std::ostream &operator <<(std::ostream &o, const sqlblob &b); friend std::istream &operator >>(std::istream &o, sqlblob &b); friend std::string xml_encode_string(const sqlblob &b,xml_encoding encoding); #endif xml_encoding encoding; private: std::vector *mem; }; template std::string sqlblob::print_xml() const { return xml_encode_string(*mem,encoding); } template std::string sqlblob::print_hex() const { const char *hex="0123456789ABCDEF"; char *p= new char [size()*sizeof(T)*2+1]; size_t i,j; for (i = j = 0; i < size()*sizeof(T); i++) { p[j++] = hex[((*mem)[i] & 0xF0) >> 4]; p[j++] = hex[((*mem)[i] & 0x0F)]; } p[j]=0; std::string rv(p); delete p; return rv; } template std::string sqlblob::print_raw() const { return std::string(reinterpret_cast(&(*begin())),size()); } template sqlblob::sqlblob(const T *p, size_t len, xml_encoding e) : track_mem >("sqlblob"), encoding(e) { if (p) { mem=new std::vector(p,p+len); } else if (len) { mem=new std::vector(len); } else { mem=new std::vector(); } #ifdef DEBUG_ALLOCATIONS fprintf(stderr,"sqlblob: allocated a vector at 0x%p\n",mem); fflush(stderr); #endif } template sqlblob::sqlblob(const std::string &s, xml_encoding e) : encoding(e), mem(new std::vector(s.c_str(),s.c_str()+s.size())) { #ifdef DEBUG_ALLOCATIONS fprintf(stderr,"sqlblob: allocated a vector at 0x%p\n",mem); fflush(stderr); #endif } template sqlblob::sqlblob(const std::vector &v, xml_encoding e) : encoding(e), mem(new std::vector(v)) { #ifdef DEBUG_ALLOCATIONS fprintf(stderr,"sqlblob: allocated a vector at 0x%p\n",mem); fflush(stderr); #endif } template sqlblob::sqlblob(const sqlblob &b) : encoding(b.encoding) , mem(new std::vector(*(b.mem))) { #ifdef DEBUG_ALLOCATIONS fprintf(stderr,"sqlblob: allocated a vector at 0x%p\n",mem); fflush(stderr); #endif } template size_t sqlblob::resize(size_t len) { mem->resize(len); return mem->size(); } template size_t sqlblob::set_size(size_t len) { mem->resize(len); if (mem->size() < len) { while (mem->size() != len) { mem->push_back(static_cast(0)); } } return mem->size(); } template sqlblob::~sqlblob() { if (mem) { delete mem; #ifdef DEBUG_ALLOCATIONS fprintf(stderr,"sqlblob: deleted a vector at 0x%p\n",mem); fflush(stderr); #endif } } template sqlblob &sqlblob::operator =(const sqlblob &b) { if (&b != this) { if (mem && (mem != b.mem)) { delete mem; #ifdef DEBUG_ALLOCATIONS fprintf(stderr,"sqlblob: deleted a vector at 0x%p\n",mem); fflush(stderr); #endif } mem=new std::vector(*(b.mem)); encoding=b.encoding; #ifdef DEBUG_ALLOCATIONS fprintf(stderr,"sqlblob: allocated a vector at 0x%p\n",mem); fflush(stderr); #endif } return (*this); } template sqlblob &sqlblob::operator =(const std::vector &b) { if (&b != mem) { if (mem) { delete mem; #ifdef DEBUG_ALLOCATIONS fprintf(stderr,"sqlblob: deleted a vector at 0x%p\n",mem); fflush(stderr); #endif } mem=new std::vector(b); #ifdef DEBUG_ALLOCATIONS fprintf(stderr,"sqlblob: allocated a vector at 0x%p\n",mem); fflush(stderr); #endif } return (*this); } #endif boinc-app-seti_8.00~svn3701.orig/assimilator/0000755000175000017500000000000013155506301021040 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/assimilator/sah_assimilate_handler.h0000644000175000017500000000021411115576545025704 0ustar locutuslocutus#include #include "boinc_db.h" #define PROJECTDIR ".." extern int assimilate_handler(WORKUNIT&, std::vector&, RESULT&); boinc-app-seti_8.00~svn3701.orig/assimilator/Makefile.am0000644000175000017500000000304413051410267023075 0ustar locutuslocutus## $Id: Makefile.am,v 1.2.2.6 2007/08/09 23:37:34 jeffc Exp $ include $(top_srcdir)/Makefile.incl AM_CFLAGS = @CFLAGS@ @DEFS@ -DTEXT_UI -DNDEBUG @PTHREAD_CFLAGS@ AM_CXXFLAGS = $(AM_CFLAGS) AM_LDFLAGS += -Xlinker -R -Xlinker $(INFORMIXDIR)/lib:$(INFORMIXDIR)/lib/esql:$(LD_LIBRARY_PATH) @LDFLAGS@ -static CLIBS = @LIBS@ BOINC_INC = -I$(BOINCDIR) -I$(BOINCDIR)/api -I$(BOINCDIR)/lib -I$(BOINCDIR)/sched -I$(BOINCDIR)/db BOINC_LIBS = -L$(BOINCDIR)/sched -lsched @MYSQL_LIBS@ @PTHREAD_LIBS@ -L$(BOINCDIR)/lib -lboinc -L$(SSLDIR) -lcrypto -lssl HEALPIX_INC = -I$(HEALPIX)/include HEALPIX_LIBS = -L$(HEALPIX)/lib -lchealpix -lhealpix_cxx -lcxxsupport SYSLIBS = -larmadillo #bin_PROGRAMS = sah_assimilator noinst_PROGRAMS = sah_assimilator sah_assimilator_SOURCES = \ $(BOINCDIR)/sched/assimilator.cpp \ $(BOINCDIR)/sched/validate_util.cpp \ sah_assimilate_handler.cpp \ ../client/timecvt.cpp \ ../db/schema_master.cpp \ ../db/sqlifx.cpp \ ../db/sqlrow.cpp \ ../db/sqlblob.cpp \ ../db/xml_util.cpp \ ../db/app_config.cpp sah_assimilator_CFLAGS = $(AM_CFLAGS) $(BOINC_INC) $(HEALPIX_INC) $(SETILIB_CFLAGS) $(MYSQL_CFLAGS) $(INFORMIX_CFLAGS) -I.. -I../db $(PTHREAD_CFLAGS) -I../client -I../validate sah_assimilator_CXXFLAGS = $(AM_CXXFLAGS) $(BOINC_INC) $(SETILIB_CFLAGS) $(HEALPIX_INC) $(MYSQL_CFLAGS) $(INFORMIX_CFLAGS) -I.. -I../db $(PTHREAD_CFLAGS) -I../client -I../validate sah_assimilator_LDADD = $(PTHREAD_CFLAGS) $(BOINC_LIBS) $(SETILIB_LIBS) $(MYSQL_LIBS) $(INFORMIX_LIBS) $(CLIBS) $(HEALPIX_LIBS) $(SYSLIBS) boinc-app-seti_8.00~svn3701.orig/assimilator/sah_assimilate_handler.cpp0000644000175000017500000006634013051410267026240 0ustar locutuslocutus#include "sah_config.h" #include #include #include #include #include #include #include #include #include "boinc_db.h" #include "sched_config.h" #include "sah_assimilate_handler.h" #include "sched_util.h" #include "sched_msgs.h" #include "parse.h" #include "sched_util.h" #include "util.h" #include "validate_util.h" #include "filesys.h" #include "setilib.h" #include "timecvt.h" #include "db_table.h" #include "schema_master.h" #include "app_config.h" #include "sqlint8.h" #include "sah_result.h" // the boinc assimilator makes these available extern SCHED_CONFIG config; //extern bool noinsert; const double D2R = 0.017453292; const int fpix_res = 10; // Hz const float bad_fp_val_marker = -91.0; struct timespec nanotime; //inline long round(double x) {return long(floor(x + 0.5f));} // the init and usage functions are required by boinc int assimilate_handler_init(int, char**) { return 0; } void assimilate_handler_usage() { } int populate_seti_result( result& sah_result, RESULT& boinc_canonical_result, WORKUNIT& b_wu, long long & seti_wu_id ); template int insert_signals( T& signal, char * signal_name, char * wu_name, sqlint8_t sah_result_id, std::ifstream& result_file, receiver_config& receiver_cfg, int appid, int max_signals_allowed, bool check_rfi, list& hotpix); template int pre_process(T& signal, receiver_config& receiver_cfg, sqlint8_t sah_result_id, char * wu_name, bool check_rfi); template int check_values(T& signal, sqlint8_t sah_result_id, char * wu_name); int get_science_configs(WORKUNIT& boinc_wu, long long seti_wu_id, receiver_config& receiver_cfg, analysis_config& analysis_cfg); int parse_settings_id(WORKUNIT& boinc_wu); int get_configs_old_method(WORKUNIT& boinc_wu, long long seti_wu_id, receiver_config& receiver_cfg, analysis_config& analysis_cfg); long long new_wu_id(long long old_wu_id); // assimilate_handler() is called by BOINC code and is passed the canonical // result for a workunit. assimilate_handler() reads the referenced result // file and inserts the result and its signals into the master science DB. // BOINC also passes the workunit (as it appears in the BOINC DB) and a vector // containing all results (including the canonical one) for that workunit. // We use the workunit to determine if there is an error condition. int assimilate_handler( WORKUNIT& boinc_wu, vector& boinc_results, RESULT& boinc_canonical_result ) { int retval=0; int spike_count=0, spike_inserted_count=0, gaussian_count=0, gaussian_inserted_count=0, pulse_count=0, pulse_inserted_count=0, triplet_count=0, triplet_inserted_count=0, autocorr_count=0, autocorr_inserted_count=0; static receiver_config receiver_cfg; static analysis_config analysis_cfg; workunit s_wu; workunit_grp s_wu_grp; result sah_result; spike_t sah_spike; gaussian_t sah_gaussian; pulse_t sah_pulse; triplet_t sah_triplet; autocorr_t sah_autocorr; char filename[256]; char * path; std::string path_str; long sah_result_id; sqlint8_t sah_spike_id, sah_autocorr_id, sah_gaussian_id, sah_pulse_id, sah_triplet_id; static bool first_time = true; int sql_error_code; long long seti_wu_id; time_t now; int hotpix_update_count; int hotpix_insert_count; APP_CONFIG sah_config; hotpix hotpix; list qpixlist; // will be a unique list of qpixes for // updating the hotpix table list::iterator qpix_i; nanotime.tv_sec = 0; nanotime.tv_nsec = 1000000; // app specific configuration if (first_time) { first_time = false; receiver_cfg.id = 0; analysis_cfg.id = 0; retval = sah_config.parse_file(".."); if (retval) { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "First entrance to handler : can't parse config file. Exiting.\n" ); return(retval); } else { retval = db_change(sah_config.scidb_name); if (!retval) { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "First entrance to handler : could not open science DB %s. Exiting.\n", sah_config.scidb_name ); return(retval); } else { log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL, "First entrance to handler : using science DB %s\n", sah_config.scidb_name ); } log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL, "Will%s check signals for rfi\n", sah_config.assim_check_rfi ? "" : " not" ); } // Sometimes we want to perform all assimilation functions // *except* insertion into the science master DB. //if (noinsert) { // log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL, // "[%s] assimilator is in noinsert mode.\n", // boinc_wu.name // ); //} } else { /* retval = db_change(sah_config.scidb_name); if (!retval) { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "First entrance to handler : could not open science DB %s. Exiting.\n", sah_config.scidb_name ); return(retval); } else { log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL, "First entrance to handler : using science DB %s\n", sah_config.scidb_name ); } */ } //if (noinsert) return 0; // Note that this will result in the WU being marked as assimilated - // we will not see it again. // translate seti wuid for thos wus that changed ids during the DB merge seti_wu_id = new_wu_id((long long)boinc_wu.opaque); log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, "[%s] old seti WU id is : %lld new seti WU id is : %lld\n", boinc_wu.name, (long long)boinc_wu.opaque, seti_wu_id ); if (boinc_wu.canonical_resultid) { log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, "[%s] Canonical result is %ld. SETI workunit ID is %lld.\n", boinc_wu.name, boinc_wu.canonical_resultid, seti_wu_id ); } else { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "[%s] No canonical result\n", boinc_wu.name ); } if (!boinc_wu.canonical_resultid) { return 0; // Note that this will result in the WU being marked as assimilated - // we will not see it again. No canonical result means that // too many results were returned with no concensus. } // Obtain and check the full path to the boinc result file. retval = get_output_file_path(boinc_canonical_result, path_str); if (retval) { if (retval == ERR_XML_PARSE) { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "[%s] Cannot extract filename from canonical result %ld.\n", boinc_wu.name, boinc_wu.canonical_resultid); return(retval); } else { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "[%s] unknown error from get_output_file_path() for result %ld.\n", boinc_wu.name, boinc_wu.canonical_resultid); return(retval); } } else { path = (char *)path_str.c_str(); if (!boinc_file_exists(path)) { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "[%s] Output file %s does not exist for result %ld.\n", boinc_wu.name, path, boinc_wu.canonical_resultid); return(-1); } else { log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, "[%s] Result %ld : using upload file %s\n", boinc_wu.name, boinc_wu.canonical_resultid, path); } } // Open it. std::ifstream result_file(path, ios_base::in); if (!result_file.is_open()) { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "[%s] open error for result file %s : errno %d\n", boinc_wu.name, path, errno ); return -1; } retval = get_science_configs(boinc_wu, seti_wu_id, receiver_cfg, analysis_cfg); if (retval) { if (retval == 100) { return (0); } else { return (-1); } } log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, "[%s] Result %ld : using receiver_cfg %ld and analysis_cfg %ld\n", boinc_wu.name, boinc_wu.canonical_resultid, receiver_cfg.id, analysis_cfg.id); // Insert a sah result retval = populate_seti_result(sah_result, boinc_canonical_result, boinc_wu, seti_wu_id); sah_result_id = sah_result.insert(); if (sah_result_id) { log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL, "[%s] Inserted result. Boinc result id is %ld. Sah result id is %lld.\n", boinc_wu.name, boinc_canonical_result.id, (long long)sah_result_id ); } else { if (sql_last_error_code() == -239 || sql_last_error_code() == -268) { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "[%s] Could not insert duplicate result. SQLCODE is %d. SQLMSG is %s.\n", boinc_wu.name, sql_last_error_code(), sql_error_message() ); return 0; // non-fatal - we will never see this result again } else { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "[%s] Could not insert result. SQLCODE is %d. SQLMSG is %s.\n", boinc_wu.name, sql_last_error_code(), sql_error_message() ); return -1; // fatal - non-dup error } } // Insert all sah signals in turn insert_signals( sah_spike, "spike", boinc_wu.name, sah_result_id, result_file, receiver_cfg, boinc_canonical_result.appid, analysis_cfg.max_spikes, sah_config.assim_check_rfi, qpixlist); insert_signals( sah_autocorr, "autocorr", boinc_wu.name, sah_result_id, result_file, receiver_cfg, boinc_canonical_result.appid, analysis_cfg.max_autocorr, sah_config.assim_check_rfi, qpixlist); insert_signals( sah_gaussian, "gaussian", boinc_wu.name, sah_result_id, result_file, receiver_cfg, boinc_canonical_result.appid, analysis_cfg.max_gaussians, sah_config.assim_check_rfi, qpixlist); insert_signals( sah_pulse, "pulse", boinc_wu.name, sah_result_id, result_file, receiver_cfg, boinc_canonical_result.appid, analysis_cfg.max_pulses, sah_config.assim_check_rfi, qpixlist); insert_signals( sah_triplet, "triplet", boinc_wu.name, sah_result_id, result_file, receiver_cfg, boinc_canonical_result.appid, analysis_cfg.max_triplets, sah_config.assim_check_rfi, qpixlist); // update last hit time to now for each qpix hit qpixlist.unique(); hotpix_update_count = 0; hotpix_insert_count = 0; qpix_set_hotpix(qpixlist, hotpix_update_count, hotpix_insert_count); //#define DEBUG_NEIGHBORS #ifdef DEBUG_NEIGHBORS for(qpix_i = qpixlist.begin(); qpix_i != qpixlist.end(); qpix_i++) fprintf(stderr, "%ld\n", *qpix_i); #endif qpixlist.clear(); log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, "[%s] Updated %d rows and inserted %d rows in the hotpix table\n", boinc_wu.name, hotpix_update_count, hotpix_insert_count ); return 0; // the successful assimilation of one WU } template int insert_signals( T& signal, char * signal_name, char * wu_name, sqlint8_t sah_result_id, std::ifstream& result_file, receiver_config& receiver_cfg, int appid, int max_signals_allowed, bool check_rfi, list& qpixlist) { int signal_count=0, signal_inserted_count=0, retval=0, qpix; sqlint8_t signal_id=0; result_file.clear(); result_file.seekg(0); while (!result_file.eof()) { result_file >> signal; if (!result_file.eof()) { signal_count++; signal.result_id = sah_result_id; // fill in any additional signal fields if (max_signals_allowed == 0 || signal_count <= max_signals_allowed) { if (!(signal.rfi_found = check_values(signal, sah_result_id, wu_name))) { // preprocess only if we have good values retval = pre_process(signal, receiver_cfg, sah_result_id, wu_name, check_rfi); qpixlist.push_back(npix2qpix((long long)signal.q_pix)); } signal_id = signal.insert(); if (signal_id) { log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, "[%s] Inserted %s %"INT8_FMT" for sah result %"INT8_FMT"\n", wu_name, signal_name, INT8_PRINT_CAST(signal_id), INT8_PRINT_CAST(sah_result_id) ); signal_inserted_count++; } else { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "[%s] Could not insert %s for sah result %"INT8_FMT". SQLCODE is %d. q_pix is %"INT8_FMT" ra is %lf decl is %lf .\n", wu_name, signal_name, sah_result_id, sql_last_error_code(), signal.q_pix, signal.ra, signal.decl ); #if 0 log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "[%s] Could not insert %s for sah result %ld. SQLCODE is %d. SQLMSG is %s q_pix is %"INT8_FMT".\n", wu_name, signal_name, sah_result_id, sql_last_error_code(), sql_error_message(), signal.q_pix ); #endif return -1; } } } } log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL, "[%s] Inserted %d out of %d %s(s) for sah result %"INT8_FMT" \n", wu_name, signal_inserted_count, signal_count, signal_name, INT8_PRINT_CAST(sah_result_id) ); return 0; } int populate_seti_result( result& s_result, RESULT& b_result, WORKUNIT& b_wu, long long & seti_wu_id ) { // from boinc result s_result.boinc_result = b_result.id; s_result.received = time_t_to_jd((time_t) b_result.received_time); s_result.wuid = seti_wu_id; s_result.hostid = b_result.hostid; s_result.versionid = b_result.app_version_num; s_result.return_code = b_result.exit_status; if ((int)b_result.opaque & RESULT_FLAG_OVERFLOW) s_result.overflow = 1; // from boinc WU s_result.reserved = b_wu.error_mask; return(0); } template int pre_process(T& signal, receiver_config& receiver_cfg, sqlint8_t sah_result_id, char * wu_name, bool check_rfi) { //long q_pix; // barycenter reference frame - note that we pass epoch of the // day coordinates as seti_dop_FreqAtBaryCenter() does precession. // We should change this but such a change will involve several // projects. signal.barycentric_freq = seti_dop_FreqAtBaryCenter(signal.detection_freq, signal.time, signal.ra, signal.decl, stdepoch, (telescope_id)receiver_cfg.s4_id ); // precess in place eod2stdepoch(signal.time, signal.ra, signal.decl, stdepoch); // cubic pixel number with precessed coords plus course frequency signal.q_pix = co_radeclfreq2npix(signal.ra, signal.decl, signal.barycentric_freq); //co_radecl2pix(signal.ra, signal.decl, q_pix); // move the sky portion to the high order 4 bytes // and add in freq portion (will land in the low order 4 bytes). //signal.q_pix = q_pix; //signal.q_pix = (signal.q_pix << 32) + ((unsigned long)round(signal.barycentric_freq / fpix_res)); // send the signal through the rfi checker if configured to do so if(check_rfi) { if (is_rfi(signal)) { log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, "[%s] Signal for result %"INT8_FMT" flagged as RFI\n", wu_name, sah_result_id ); } else { log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, "[%s] Signal for result %"INT8_FMT" flagged as RFI CLEAN\n", wu_name, sah_result_id ); } } return 0; } template int check_values(T& signal, sqlint8_t sah_result_id, char * wu_name) { int retval=0; // check for ranges and NaN's if(signal.ra < 0 || signal.ra >= 24 || signal.ra != signal.ra) { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "[%s] Signal for result %"INT8_FMT" has out of range RA : %lf\n", wu_name, sah_result_id, signal.ra ); signal.ra = bad_fp_val_marker; retval = 1; } if(signal.decl < -90 || signal.decl > 90 || signal.decl != signal.decl) { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "[%s] Signal for result %"INT8_FMT" has out of range declination : %lf\n", wu_name, sah_result_id, signal.decl ); signal.decl = bad_fp_val_marker; retval = 1; } // time range is from 1990 to 2050 if(signal.time < 2447892.5 || signal.time > 2469807.5 || signal.time != signal.time) { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "[%s] Signal for result %"INT8_FMT" has out of range time : %lf\n", wu_name, sah_result_id, signal.time ); signal.time = bad_fp_val_marker; retval = 1; } if(signal.freq < 0 || signal.freq != signal.freq) { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "[%s] Signal for result %"INT8_FMT" has out of range frequency : %lf\n", wu_name, sah_result_id, signal.freq ); signal.freq = bad_fp_val_marker; retval = 1; } return(retval); } int get_science_configs(WORKUNIT& boinc_wu, long long seti_wu_id, receiver_config& receiver_cfg, analysis_config& analysis_cfg) { int settings_id, retval=0; static int first_time=1, current_settings_id=0, current_analysis_config_id=0, current_receiver_config_id=0; settings settings; settings_id = parse_settings_id(boinc_wu); if (settings_id) { log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, "[%s] Name string contains settings id %d\n", boinc_wu.name, settings_id ); } else { log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, "[%s] Name string contains no settings id\n", boinc_wu.name ); } #if 0 // temp hack if (first_time) { retval = get_configs_old_method(boinc_wu, seti_wu_id, receiver_cfg, analysis_cfg); if (!retval) first_time = 0; } return (retval); // end temp hack #endif // can be removed after all WUs have settings (no settings would then be a fatal error) if (!settings_id) { get_configs_old_method(boinc_wu, seti_wu_id, receiver_cfg, analysis_cfg); return(0); } // end can be removed after all WUs have settings if (settings_id == current_settings_id) { return (0); } else { current_settings_id = settings_id; // get settings row if (settings.fetch(settings_id)) { log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL, "[%s] Obtained science master DB row for settings table id %ld\n", boinc_wu.name, settings.id ); } else { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "[%s] Could not obtain science master DB row for settings table id %d. SQLCODE is %d\n", boinc_wu.name, settings_id, sql_last_error_code() ); return(-1); } // get analysis config row if (settings.analysis_cfg.id != current_analysis_config_id) { if (analysis_cfg.fetch(settings.analysis_cfg.id)) { current_analysis_config_id = analysis_cfg.id; log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL, "[%s] Obtained science master DB row for analysis_config table id %ld\n", boinc_wu.name, analysis_cfg.id ); } else { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "[%s] Could not obtain science master DB row for analysis_config table id %ld. SQLCODE is %d\n", boinc_wu.name, settings.analysis_cfg.id, sql_last_error_code() ); return(-1); } } // get receiver config row if (settings.receiver_cfg.id != current_receiver_config_id) { if (receiver_cfg.fetch(settings.receiver_cfg.id)) { current_receiver_config_id = receiver_cfg.id; log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL, "[%s] Obtained science master DB row for receiver_config table id %ld\n", boinc_wu.name, receiver_cfg.id ); } else { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "[%s] Could not obtain science master DB row for receiver_config table id %ld. SQLCODE is %d\n", boinc_wu.name, settings.receiver_cfg.id, sql_last_error_code() ); return(-1); } } return(0); } } int parse_settings_id(WORKUNIT& boinc_wu) { int i=0, j=0, num_tokens=1, pos=0, len=0; const int max_tokens=7, max_token_len=128, settings_token=4; char tokens[max_tokens][max_token_len]; len = strlen(boinc_wu.name); // parse the dot delimited WU name into its // constituent tokens for (pos=0, i=0, j=0; pos < len && i < max_tokens; pos++) { if (boinc_wu.name[pos] == '.') { // terminate this token tokens[i][j] = '\0'; j = 0; i++; num_tokens++; continue; } if (j >= max_token_len) { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "[%s] Token too long during name parsing.\n", boinc_wu.name ); exit(1); } else { // continue this token tokens[i][j] = boinc_wu.name[pos]; j++; } } if (i >= max_tokens) { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "[%s] Too many tokens during name parsing.\n", boinc_wu.name ); exit(1); } else { tokens[i][j] = '\0'; // terminate the final token num_tokens++; } if (i >= settings_token-1) { // does name cointain settings? return(atoi(tokens[settings_token])); // yes - return it } else { return(0); } } int get_configs_old_method(WORKUNIT& boinc_wu, long long seti_wu_id, receiver_config& receiver_cfg, analysis_config& analysis_cfg) { workunit s_wu; workunit_grp s_wu_grp; int sql_error_code; // workunit if (s_wu.fetch(seti_wu_id)) { log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL, "[%s] Obtained science master DB row for wu %lld [%s]\n", boinc_wu.name, seti_wu_id, s_wu.name ); } else { sql_error_code = sql_last_error_code(); if (sql_error_code == 100) { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "[%s] Science master DB row for wuid %lld does not exit. Marking as assimilated.\n", boinc_wu.name, seti_wu_id ); return sql_error_code; } else { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "[%s] Could not obtain science master DB row for wuid %lld. SQLCODE is %d\n", boinc_wu.name, seti_wu_id, sql_error_code ); return -1; } } // workunit_grp if (s_wu_grp.fetch(s_wu.group_info.id)) { log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL, "[%s] Obtained science master DB row for wugid %ld\n", boinc_wu.name, s_wu_grp.id ); } else { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "[%s] Could not obtain science master DB row for wugid %ld. SQLCODE is %d\n", boinc_wu.name, s_wu.group_info.id, sql_last_error_code() ); return -1; } // receiver_config - get it if it has changed if (receiver_cfg.id != s_wu_grp.receiver_cfg.id) { if (receiver_cfg.fetch(s_wu_grp.receiver_cfg.id)) { log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL, "[%s] Obtained science master DB row for receiver table id %ld [%s]\n", boinc_wu.name, receiver_cfg.id, receiver_cfg.name ); } else { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "[%s] Could not obtain science master DB row for receiver table id %ld. SQLCODE is %d\n", boinc_wu.name, s_wu_grp.receiver_cfg.id, sql_last_error_code() ); return -1; } } // analysis_config - get it if it has changed if (analysis_cfg.id != s_wu_grp.analysis_cfg.id) { if (analysis_cfg.fetch(s_wu_grp.analysis_cfg.id)) { log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL, "[%s] Obtained science master DB row for analysis table id %ld.\n", boinc_wu.name, analysis_cfg.id ); } else { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "[%s] Could not obtain science master DB row for analysis table id %ld. SQLCODE is %d\n", boinc_wu.name, s_wu_grp.analysis_cfg.id, sql_last_error_code() ); return -1; } } return 0; } long long new_wu_id(long long old_wu_id) { workunit seti_wu; char buf[256]; sprintf(buf,"where sb_id=%lld", old_wu_id); if (!seti_wu.fetch(std::string(buf))) { return (old_wu_id); } else { return (seti_wu.id); } } boinc-app-seti_8.00~svn3701.orig/ops/0000755000175000017500000000000013155506301017312 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/ops/lib/0000755000175000017500000000000013155506301020060 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/ops/bin/0000755000175000017500000000000013155506302020063 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/ops/bin/data_flow.cfg0000755000175000017500000000541611122523365022515 0ustar locutuslocutus#! /usr/bin/env perl # data_flow.cfg - edit all data_flow config stuff here for scripts in: $scriptdir = "/disks/thumper/raid5_d/users/seti/dr2_data/production/scripts"; # list of possible data drives and where they should be mounted @drive_array=("/dev/sda1","/dev/sdb1","/dev/sdc1","/dev/sdd1"); @drive_mount_points=("/mnt/seti_data_1","/mnt/seti_data_2","/mnt/seti_data_3","/mnt/seti_data_4"); $num_drives = scalar(@drive_array); # a list of possible block sizes for data drives (to check for proper disk in fdisk) @partition_block_sizes=(488384001,732572001); # where to write data to (via scp) $scpdatato = 'seti@thumper:/mydisks/raid5_d/users/seti/dr2_data/production/processing'; # NFS directory where files are going to AS WELL AS # where to check for full disk (via nfs/df) and where files will end up: $nfsdatato = "/disks/thumper/raid5_d/users/seti/dr2_data/production/processing"; $fullcheck = $nfsdatato; # NFS directory where processing is $processing_dir = $fullcheck; # same as nfsdatati/fullcheck usually # NFS directory where xfer_to_hpss is $xfer_to_hpss_dir = "/disks/thumper/raid5_d/users/seti/dr2_data/production/xfer_to_hpss"; # NFS directory where trigger files are $triggers_dir = "/disks/thumper/raid5_d/users/seti/dr2_data/production/trigger_files"; # trigger files: $xferring_to_hpss = "$triggers_dir/xferring_to_hpss"; # buffer space (in bytes) for full disk (i.e. how much under 100% full before we just call it full) $buffer = 60000000000; # ~60GB # md5sum size (bytes) $md5size = 1073741824; # where to write md5s to (via scp) $scpmd5to = 'seti@thumper:/mydisks/raid5_d/users/seti/dr2_data/production/md5'; # email recipients $mailto = 'mattl@ssl.berkeley.edu jeffc@ssl.berkeley.edu'; # lock file to avoid restart: $lockfile = "/root/lock.data_flow_lando"; $awk = "/bin/awk"; $cat = "/bin/cat"; $df = "/bin/df"; $fdisk = "/sbin/fdisk"; $grep = "/bin/grep"; $head = "/usr/bin/head"; $hsi = "$scriptdir/seti_hsi.csh"; $ln = "/bin/ln"; $ls = "/bin/ls"; $mail = "/bin/mail"; $md5sum = "/usr/bin/md5sum"; $mke2fs = "/sbin/mke2fs"; $mount = "/bin/mount"; $mv = "/bin/mv"; $ps = "/bin/ps"; $rm = "/bin/rm"; $scp = "/usr/bin/scp"; $su = "/bin/su"; $tail = "/usr/bin/tail"; $touch = "/bin/touch"; $umount = "/bin/umount"; $wc = "/usr/bin/wc"; $whoami = "/usr/bin/whoami"; # MODULES TO INCLUDE: use File::Basename; # FUNCTIONS: sub send_mail { my $subject = $_[0]; my $message = $_[1]; open (SENDMAIL,"|$mail -s \"$subject\" $mailto"); print SENDMAIL "$message\n"; close (SENDMAIL); return 0; } # PRELIMINARY CHECKS: $hostname = `/usr/ucb/hostname`; chomp $hostname; $whoami = `/usr/bin/whoami`; chomp $whoami; if ($whoami ne "root") { print "sorry - all data flow scripts must be run as root\n"; print "(don't worry - we'll su to seti as needed)\n"; exit(0); } boinc-app-seti_8.00~svn3701.orig/ops/bin/run_jan.csh0000755000175000017500000000025311122523365022221 0ustar locutuslocutus#! /bin/csh source ~davea/seti/db/master # ~boincadm/projects/sah/bin/splitter_janitor --dir . ~boincadm/projects/sah/bin/splitter_janitor echo exit status was $status boinc-app-seti_8.00~svn3701.orig/ops/bin/splitter_janitor0000755000175000017500000002524512625413353023421 0ustar locutuslocutus#! /usr/bin/perl -w # where is the data? # $file_dir = "/disks/thumper/raid5_d/users/seti/dr2_data/production/processing"; $file_dir = "/home/seti/dr2_data/production/processing"; # $email_list = 'jeffc@ssl.berkeley.edu mattl@ssl.berkeley.edu korpela@ssl.berkeley.edu'; # $email_list = 'jeffc@ssl.berkeley.edu'; $email_list = 'mattl@ssl.berkeley.edu jeffc@ssl.berkeley.edu'; # num of seconds to keep files in _TO_BE_DELETED before actually deleting them $keep_for = 7*86400; # one week #$keep_for = 86400; # one day # what if we are missing beam/pol pairs out of the standard 14? should we move date to be deleted anyway? # 0 - no, 1 - yes; $delete_even_if_missing_beampols = 1; # where is seti_hsi.csh? $seti_hsi = "/home/boincadm/projects/sah/bin/seti_hsi.csh"; # set informix env $informixdir = "/usr/local/informix"; $currentpath = $ENV{"PATH"}; $currentldlp = $ENV{"LD_LIBRARY_PATH"}; $ENV{"INFORMIXDIR"}="${informixdir}"; $ENV{"INFORMIXSERVER"}="sah_master_tcp"; $ENV{"ONCONFIG"}="onconfig.sah_master"; $ENV{"PATH"}="${informixdir}/bin:${currentpath}"; $ENV{"LD_LIBRARY_PATH"}="${informixdir}/lib:${informixdir}/lib/esql:${currentldlp}"; # if --check_only flag is specified, do "check only" for current directory, ignoring dot files, etc. # basically just check for existence at HPSS, and if all 14 tapes are in science db and # mail us the results without moving/deleting anything. # if --not_at_hpss flag is specified, this supercedes --check_only - and only outputs what files # are here at the lab and fully split/processed, but not yet copied to HPSS # if --ignore_matching_sizes is specified, ignore if files don't match in size - delete anyway if # otherwise deleteable # if --dir flag is specified, go into that file_dir instead of default file_dir sub is_ap_doing_anything { my $chkfile = $_[0]; if (-f "${chkfile}.completely_done_ap") { return 0; } # it's done - so better not be doing anything if (-f "${chkfile}.completely_done_with_errors_ap") { return 0; } # it's done - so better not be doing anything @aplist = `/bin/ls *${chkfile}*_ap.* 2>&1 | /bin/grep -v "No such"`; if (scalar(@aplist) > 0) { return 1; } return 0; } $check_only = 0; $not_at_hpss = 0; $ignore_matching_sizes = 0; while ($arg = shift) { if ($arg eq "--check_only") { $file_dir = `pwd`; chomp $file_dir; $check_only = 1; } elsif ($arg eq "--not_at_hpss") { $not_at_hpss = 1; } elsif ($arg eq "--ignore_matching_sizes") { $ignore_matching_sizes = 1; } elsif ($arg eq "--dir") { $file_dir = shift; } else { print "splitter_janitor [--dir file_dir] [--check_only|--not_at_hpss]\n"; exit(1); } } # get data file list if (! -d $file_dir) { print "no such directory: $file_dir\n"; exit(1); } chdir $file_dir; undef @file_list; open (LS,"/bin/ls . |"); while () { $thisfile = $_; chomp $thisfile; if (/^[0-9][0-9][a-z][a-z][0-9][0-9][a-z][a-z]$/) { push @file_list, $_ } } close (LS); chomp @file_list; $message = "Splitter Janitor Results:\n"; if ($check_only == 1) { $message .= "(doing check on data files in: $file_dir)\n"; } # is HPSS unavailable? if so, set warning, and undefine file_list and set check_only == 1 # in order to go right to mail at end (don't care if we're doing not_at_hpss check) if ($not_at_hpss == 0) { $check_hpss = `$seti_hsi --check`; chomp $check_hpss; if ($check_hpss eq "hpss is down") { undef @file_list; $check_only = 1; $message .= "\nHPSS is currently unavailable - bailing...\n"; } } # moving on - main part: foreach $file (@file_list) { $message .= "\n"; if ($not_at_hpss == 1 && ( -f "${file}.completely_done" || -f "${file}.completely_done_with_errors") && ( -f "${file}.completely_done_ap" || -f "${file}.completely_done_with_errors_ap") && ! -f "${file}.at_hpss") { print "${file}\n"; } elsif ($not_at_hpss == 0) { if (! -f "${file}.at_hpss") { $hsicommand = "$seti_hsi --list $file"; $retval = system ($hsicommand . "> /dev/null"); $retval = $retval >> 8; if ($retval == 0) { $message .= "${file}: had no .at_hpss suffix but actually IS at HPSS - touching ${file}.at_hpss\n"; system ("/bin/touch ${file}.at_hpss"); } } if (( (-f "${file}.completely_done" || -f "${file}.completely_done_with_errors") && (-f "${file}.completely_done_ap" || -f "${file}.completely_done_with_errors_ap") && -f "${file}.at_hpss") || $check_only == 1) { $message .= "${file}: finished processing and xfering to hpss - checking...\n"; $domove = 1; # double check that it is at HPSS $hsicommand = "$seti_hsi --list $file"; $retval = system ($hsicommand . "> /dev/null"); $retval = $retval >> 8; if ($retval == 1) { $message .= "WARNING: ${file}: has .at_hpss suffix but IS NOT AT HPSS!\n"; # $domove = 0; # just a warning... still move if need be } else { $message .= "${file}: is at HPSS\n"; # now check that local/remote file sizes match $fsize = (stat($file))[7]; print "DEBUG: file size: - $fsize - \n"; $hsifsize = `$hsicommand | awk '{print \$5}'`; chomp $hsifsize; if ($fsize != $hsifsize && !$ignore_matching_sizes) { $message .= "${file}: local size: $fsize HPSS size: $hsifsize -- DO NOT MATCH\n"; $domove = 0; if (($hsifsize - $fsize) <= (134742016 * 5)) { # due to ragged files/software blanking - off by less then five buffers $message .= "${file}: ... but the HSI size is <= 134742016 x 5 bytes (five buffers) different\n"; $message .= "${file}: ... we will assume due to ragged files/etc. and flag it as okay\n"; $domove = 1; } } else { $message .= "${file}: local size: $fsize and HPSS size: $hsifsize match\n"; } } # final check - scan science database to make sure $dbcount = `echo "database sah2; select count(name) from tape where name = '${file}';" | dbaccess -e - 2>&1 | tail --l=+8 | head -1 | awk '{print \$1}'`; chomp $dbcount; if ($dbcount != 14) { $message .= "${file}: multibeam does not have 14 entries in the tape table!\n"; if ($delete_even_if_missing_beampols == 0) { # i.e. if we want to keep tapes around with missing beam/pol entries, then... $domove = 0; } } else { $message .= "${file}: has all 14 entries in the tape table\n"; } if ($domove == 1) { if ($check_only == 1) { $message .= "${file}: completely processed by multibeam and at HPSS\n"; } else { $moveto = "./_TO_BE_DELETED"; if (! (-f "${file}.completely_done_ap" || -f "${file}.completely_done_with_errors_ap") ) { $message .= "${file}: astropulse not yet finished processing\n"; $domove = 0; } else { # if (-f "${file}.completely_done_with_errors_ap") { $moveto = "./_COMPLETELY_DONE_WITH_ERRORS"; } if (-f "${file}.completely_done_with_errors_ap") { $moveto = "./_TO_BE_DELETED"; } } if (! (-f "${file}.completely_done" || -f "${file}.completely_done_with_errors") ) { $message .= "${file}: multibeam not yet finished processing\n"; $domove = 0; } else { # if (-f "${file}.completely_done_with_errors") { $moveto = "./_COMPLETELY_DONE_WITH_ERRORS"; } if (-f "${file}.completely_done_with_errors") { $moveto = "./_TO_BE_DELETED"; } } if ($domove == 1) { $thisdate = `/bin/date "+%F-%T"`; chomp $thisdate; if (-f "${file}.completely_done") { system ("/bin/mv ${file}.completely_done ./_COMPLETELY_DONE_HISTORY/${file}.completely_done.${thisdate}"); } if (-f "${file}.completely_done_ap") { system ("/bin/mv ${file}.completely_done_ap ./_COMPLETELY_DONE_HISTORY/${file}.completely_done_ap.${thisdate}"); } if (-f "${file}.completely_done_with_errors") { system ("/bin/mv ${file}.completely_done_with_errors ./_COMPLETELY_DONE_HISTORY/${file}.completely_done_with_errors.${thisdate}"); } if (-f "${file}.completely_done_with_errors_ap") { system ("/bin/mv ${file}.completely_done_with_errors_ap ./_COMPLETELY_DONE_HISTORY/${file}.completely_done_with_errors_ap.${thisdate}"); } system ("/bin/mv ${file} $moveto"); system ("/bin/mv ${file}.* $moveto"); $message .= "${file}: astropulse/multibeam completely done and at HPSS - moved into $moveto\n"; } # end if $domove == 1 } # end if $check_only == 1 } # end if $domove = 1 } # end if file completely done else { $message .= "${file}: not finished processing/xfering to hpss yet\n"; if (! (-f "${file}.completely_done" || -f "${file}.completely_done_with_errors") ) { $message .= " ${file}: multibeam not yet finished processing\n"; } if (! (-f "${file}.completely_done_ap" || -f "${file}.completely_done_with_errors_ap") ) { $message .= " ${file}: astropulse not yet finished processing\n"; } if (! (-f "${file}.at_hpss")) { $message .= " ${file}: no .at_hpss file - not finished xfering?\n"; } } } } # only bother with the actual file deleting if check_only == 0 && not_at_hpss == 0 if ($not_at_hpss == 1) { exit (0); } if ($check_only == 0) { if ($message ne "") { $message .= "\n"; } # if needed skip a line in case there's more chdir "./_TO_BE_DELETED"; undef @del_file_list; open (LS,"/bin/ls . |"); while () { $thisfile = $_; chomp $thisfile; if (/^[0-9][0-9][a-z][a-z][0-9][0-9][a-z][a-z]$/) { push @del_file_list, $_ } } close (LS); chomp @del_file_list; foreach $del_file (@del_file_list) { if (-l $del_file) { $message .= "${del_file}: is a symbolic link.. skipping..\n"; } else { $cdmtime = (stat("${del_file}.completely_done"))[9]; $ahmtime = (stat("${del_file}.at_hpss"))[9]; # print "${del_file} $cdmtime $ahmtime\n"; $now = time(); if (($now - $cdmtime) > $keep_for && ($now - $ahmtime) > $keep_for) { system ("/bin/rm -f ${del_file}*"); $cdmdelta = ($now - $cdmtime); $ahmdelta = ($now - $ahmtime); $message .= "${del_file}: finished splitting $cdmdelta seconds ago, copied to HPSS $ahmdelta seconds ago - deleting!\n"; } } } } # send mail! if ($message ne "") { open(MAIL, "|/usr/sbin/sendmail -tv"); print MAIL "To: ${email_list}\n"; print MAIL 'From: seti@ssl.berkeley.edu' . "\n"; print MAIL "Subject: splitter_janitor report\n\n"; print MAIL "$message"; close(MAIL); } exit (0); boinc-app-seti_8.00~svn3701.orig/ops/bin/run_gbt_splitter0000755000175000017500000002427112645260064023412 0ustar locutuslocutus#! /usr/bin/perl -w use locale; use sigtrap qw(HUP TERM INT); use Cwd; use Fcntl; $ENV{'INFORMIXDIR'} = '/usr/local/informix'; $ENV{'INFORMIXSQLHOSTS'} = '/usr/local/informix/etc/sqlhosts'; $ENV{'INFORMIXSERVER'} = 'sah_master_tcp'; # $ENV{'LD_LIBRARY_PATH'} = '/usr/local/informix/lib:/usr/local/informix/lib/esql:/usr/local/lib:/usr/X11R6/lib:/usr/lib:/lib:/usr/ccs/lib:/usr/local/lib:/usr/local/ssl/lib:/usr/local/informix/lib:/usr/local/informix/lib/esql:/usr/local/generic/lib:/usr/lib64:/usr/lib64/mysql'; $ENV{'LD_LIBRARY_PATH'} = '/usr/local/informix/lib:/usr/local/informix/lib/esql:/usr/local/lib:/usr/X11R6/lib:/usr/lib:/lib:/usr/ccs/lib:/usr/local/lib:/usr/local/ssl/lib:/usr/local/informix/lib:/usr/local/informix/lib/esql:/usr/local/generic/lib:/usr/lib64:/usr/lib64/mysql:/disks/carolyn/b/home/jeffc/build/sah_development/seti_gbt/lib'; # GBT receivers must be specified with channel (0-31) and polarization (0-1), i.e. -gbt=14,0 # signal handler sub sub touch_and_die { print STDERR time . " run_gbt_splitter caught signal and is touching ${split_halt_msg}..\n"; system ("/bin/touch $split_halt_msg"); exit(99) } sub is_completely_done { my $chkfile = $_[0]; my $completely_done = 1; my $errors = 0; for (my $chkchan = 0; $chkchan < 32; $chkchan++) { for (my $chkpolarization = 0; $chkpolarization < 2; $chkpolarization++) { if (! -f "${chkfile}.done.${chkchan},${chkpolarization}" && ! -f "${chkfile}.ERROR.${chkchan},${chkpolarization}") { $completely_done = 0; } if ( -f "${chkfile}.ERROR.${chkchan},${chkpolarization}") { $errors = 1; } } } if ($completely_done == 1 && $errors == 1) { return -1; } # completely done, but with errors return $completely_done; } # project/splitter vars # # sleep(rand()*30); $betaorsah = "beta"; # set to beta or sah to set proper dirs below $mb_prog_loc = "/home/boincadm/projects/$betaorsah/bin"; # $mb_prog_name = "mb_splitter_swb.x86_64"; $mb_prog_name = "mb_splitter.x86_64"; $app_name = "setiathome_v8"; $project_dir = "/home/boincadm/projects/$betaorsah/"; $rawbitdepth = 8; $file_dir = "/home/boincadm/projects/$betaorsah/processing"; $split_halt_msg = "$project_dir/stop_splitters"; $email_list = 'jeffc@ssl.berkeley.edu korpela@ssl.berkeley.edu mattl@ssl.berkeley.edu'; $found_file = "0"; $host = `/bin/uname -n | /bin/sed s/.ssl.berkeley.edu//`; $dovertical = 0; chomp $host; $usage = "usage: run_gbt_splitter [-vertical] [-exe executable_name] [-filedir filedir] [-app app_name]\n(assuming all executables are in: $mb_prog_loc)\n"; # before anything, stagger processes by sleeping a bit @numprocs = `pgrep -f run_gbt_splitter`; $sleepsecs = $#numprocs * 2; sleep $sleepsecs; # check args $checkhelp = $ARGV[0] || ""; if ($checkhelp eq "-h" || $checkhelp eq "-help" || $checkhelp eq "--help") { print $usage; exit(2); } while ($ARGV[0] ne "") { $tempvar = $ARGV[0]; if ($tempvar eq '-filedir') { shift @ARGV; $file_dir = $ARGV[0] } elsif ($tempvar eq '-exe') { shift @ARGV; $mb_prog_name = $ARGV[0] } elsif ($tempvar eq '-app') { shift @ARGV; $app_name = $ARGV[0] } elsif ($tempvar eq '-vertical') { $dovertical = 1; } else { print $usage; exit(2); } shift @ARGV; } $SIG{HUP} = $SIG{TERM} = $SIG{INT} = \&touch_and_die; # main loop (run as long as halt trigger file doesn't exist) while (! -f "$split_halt_msg") { chdir $file_dir; $found_file = 0; # get working state of directory and determine what work is available to do undef @file_list; open (LS,"/bin/ls -tr . |"); while () { $thisfile = $_; chomp $thisfile; if (/.0000.raw$/) { push @file_list, $_ } } close (LS); chomp @file_list; $dothisfile = ""; $dochan = -1; $dopolarization = -1; foreach $file (@file_list) { # is it a broken sym link? if (! -e $file) { print "${file} doesn't actually exist! (broken sym link?) skipping...\n"; next; } # are we working on this file already? $isworking = 0; for ($chan = 0; $chan < 32; $chan++) { for ($polarization = 0; $polarization < 2; $polarization++) { if (-f "${file}.working.${chan},${polarization}") { $isworking = 1; } } } # if we're working on this file already and -vertical is set, skip it: if ($isworking == 1 && $dovertical == 1) { print "${file} is being worked on and -vertical is set - moving on...\n"; next; } # check if completely done and clean up in case this hasn't happened yet if (is_completely_done($file) == 1 && ! -f "${file}.completely_done") { `/bin/touch ${file}.completely_done`; `/bin/rm -f ${file}.done.*`; } if (is_completely_done($file) == -1 && ! -f "${file}.completely_done_with_errors") { `/bin/touch ${file}.completely_done_with_errors`; } if (-f "${file}.completely_done") { print "${file} is completely_done - moving on...\n"; next; } if (-f "${file}.copying_in_lando") { print "${file} is currently being read in from lando - moving on...\n"; next; } if (-f "${file}.copying_in_hpss") { print "${file} is currently being read in from hpss - moving on...\n"; next; } for ($chan = 0; $chan < 32; $chan++) { for ($polarization = 0; $polarization < 2; $polarization++) { if ($dothisfile eq "") { print "trying file $file chan $chan polarization $polarization\n"; } if (! -f "${file}.working.${chan},${polarization}" && ! -f "${file}.done.${chan},${polarization}" && ! -f "${file}.ERROR.${chan},${polarization}" && $dothisfile eq "") { $dothisfile = $file; $dochan = $chan; $dopolarization = $polarization; } # end if } # end for polarization } # end for chan } # end foreach file if ($dothisfile eq "") { print "nothing to do - exiting...\n"; exit(6); } print "starting splitting on file: $dothisfile chan: $dochan polarization: $dopolarization...\n"; sysopen (WORKING,"${dothisfile}.working.${dochan},${dopolarization}",O_WRONLY|O_EXCL|O_CREAT) or die "wait a minute - race condition opening .working file - bailing!!!\n"; $now = `/bin/date`; chomp $now; print WORKING "$host : ". time() . " ($now)\n"; close (WORKING); open(MAIL, "|/usr/sbin/sendmail -t"); print MAIL "To: ${email_list}\n"; print MAIL 'From: splitters@ssl.berkeley.edu' . "\n"; print MAIL "Subject: splitter_gbt starting on host: ${host}\n\n"; print MAIL "starting file: ${dothisfile} chan: ${dochan} polarization: ${dopolarization}\n"; close(MAIL); $now = `/bin/date`; chomp $now; print "$now : starting file: ${dothisfile} chan: ${dochan} polarization: ${dopolarization}\n"; $filefullpath = "${file_dir}/${dothisfile}"; mkdir "/tmp/splitter_${dothisfile}_${dochan}_${dopolarization}"; mkdir "/tmp/splitter_${dothisfile}_${dochan}_${dopolarization}/wu_inbox"; chdir "/tmp/splitter_${dothisfile}_${dochan}_${dopolarization}"; `/bin/rm -f wu_inbox/*`; print "LD_LIBRARY_PATH: "; print $ENV{'LD_LIBRARY_PATH'}; print "\n"; $splitcommand = "/bin/nice -19 /usr/bin/ionice -c2 -n7 ${mb_prog_loc}/${mb_prog_name} $filefullpath -resume -gbt=${dochan},${dopolarization} -projectdir=${project_dir} -trigger_file_path=/${split_halt_msg} -appname=${app_name} -rawbitdepth=${rawbitdepth}"; print "(running command: ${splitcommand})\n"; $retval = system ($splitcommand); $retval = $retval >> 8; print "(command exited with retval: $retval)\n"; if ( $retval == 0 ) { # splitter_gbt ended gracefully at end of file sleep 60; # wait for child process to finish moving the files from wu_inbox open(MAIL, "|/usr/sbin/sendmail -t"); print MAIL "To: ${email_list}\n"; print MAIL 'From: splitters@ssl.berkeley.edu' . "\n"; print MAIL "Subject: splitter_gbt finishing on host: ${host}\n\n"; print MAIL "finished file: ${dothisfile} chan: ${dochan} polarization: ${dopolarization}\n"; #open (MAIL, "|/usr/ucb/mail -s \"$host splitter_gbt finished\" $email_list"); open (MAIL, "|/bin/mail -s \"$host splitter_gbt finished\" $email_list"); print MAIL "$host splitter_gbt finished on file: ${dothisfile}\n\n"; open (RCDCHK,"splitterlog"); while () { print MAIL $_ } close (RCDCHK); close(MAIL); if (-f "${filefullpath}.firsttry.${dochan},${dopolarization}") { `/bin/touch ${filefullpath}.done.${dochan},${dopolarization}`; `/bin/rm -f ${filefullpath}.firsttry.${dochan},${dopolarization}`; if (is_completely_done($filefullpath) == 1 && ! -f "${filefullpath}.completely_done") { `/bin/touch ${filefullpath}.completely_done`; `/bin/rm -f ${filefullpath}.done.*`; } if (is_completely_done($filefullpath) == -1 && ! -f "${filefullpath}.completely_done_with_errors") { `/bin/touch ${filefullpath}.completely_done_with_errors`; } } else { `/bin/touch ${filefullpath}.firsttry.${dochan},${dopolarization}`; } `/bin/rm -f ${filefullpath}.working.${dochan},${dopolarization}`; chdir $file_dir; `/bin/rm -rf /tmp/splitter_${dothisfile}_${dochan}_${dopolarization}`; } elsif ( $retval == 2 ) { # splitter_gbt ended gracefully but before finishing file # remove working suffix - allows it to be resumed later `/bin/rm -f ${filefullpath}.working.${dochan},${dopolarization}`; chdir $file_dir; `/bin/rm -rf /tmp/splitter_${dothisfile}_${dochan}_${dopolarization}`; print "WARNING : splitter_gbt running on file: ${dothisfile} chan: ${dochan} polarization: ${dopolarization} ended before EOF\n"; } else { # spitter ended in error! open(ERRFILE,">${filefullpath}.ERROR.${dochan},${dopolarization}"); print ERRFILE "$host\n"; close(ERRFILE); `/bin/rm -f ${filefullpath}.working.${dochan},${dopolarization}`; print "CRITICAL : splitter_gbt running on file: ${dothisfile} chan: ${dochan} polarization: ${dopolarization} ended in error!\n"; print "exiting run_gbt_splitter (and keeping working dir in /tmp)..\n"; exit(1); } $now = `/bin/date`; chomp $now; print "$now : finished running on file: ${dothisfile} chan: ${dochan} polarization: ${dopolarization}\n"; } # while halt trigger file doesn't exist print "$split_halt_msg exists - exiting..\n"; exit (0); boinc-app-seti_8.00~svn3701.orig/ops/bin/make_hpss_script0000755000175000017500000000047711122523365023357 0ustar locutuslocutus#! /bin/csh # make_hpss_script - makes xfer_to_hpss script for all ??????? files in current directory set CURDIR = `/bin/pwd` echo '#! /bin/csh' echo " " foreach i (`/bin/ls -1 [0-9][0-9][a-z][a-z][0-9][0-9][a-z][a-z]`) echo /disks/thumper/raid5_d/users/seti/dr2_data/production/scripts/seti_hsi.csh --put $i end boinc-app-seti_8.00~svn3701.orig/ops/bin/seti_hsi.csh0000755000175000017500000000640311122523365022377 0ustar locutuslocutus#! /bin/csh # This script gets from and puts to HPSS. It does checks on a put. # It can also list files and directories. set action = $1 set filename = $2 set target_dir = seti/dr2_data/production set throttle_speed = "32M" # 32Mbps set md5_check_length = 1048576 set retval = 0 if (`hostname` == "ewen") then alias hsi hsi.hpss endif hsi touch hpss_ping >& /dev/null if($status == 1) then echo hpss is down exit 1 endif if($action == "--list") then hsi "ls -l $target_dir/${filename}" |& tail -1 > /tmp/$filename.ls if ($status) then echo "$filename not found" set retval = 1 else cat /tmp/$filename.ls endif \rm /tmp/$filename.ls else if($action == "--dir") then hsi "ls -l $target_dir" |& tail --lines=+31 else if ($action == "--get") then touch $filename.at_hpss hsi "firewall -on ; get $target_dir/$filename" | throttle $throttle_speed > $filename else if ($action == "--put") then set retry = 1 while ($retry == 1) echo starting the put of $filename throttle $throttle_speed < $filename | hsi "firewall -on ; put - : $target_dir/$filename" # start transfer check set local_length = `ls -l $filename | awk '{print $5}'` set hpss_length = `hsi list -l $target_dir/$filename | & tail -1 | awk '{print $5}'` if ($local_length != $hpss_length) then echo "$filename transfer was bad (file length mismatch)" set retval = 1 exit 1 else hsi "firewall -on ; get -O ::$md5_check_length /tmp/$filename.start.hpss : $target_dir/$filename" head -c $md5_check_length $filename > /tmp/$filename.start.local set hpss_md5 = `md5sum /tmp/$filename.start.hpss | awk '{print $1}'` set local_md5 = `md5sum /tmp/$filename.start.local | awk '{print $1}'` if ($hpss_md5 != $local_md5) then echo "$filename transfer was bad (md5 mismatch at start of file)" set retval = 1 else set end_offset = `python -c "print $hpss_length - $md5_check_length"` hsi "firewall -on ; get -O ${end_offset}::$md5_check_length /tmp/$filename.end.hpss : $target_dir/$filename" tail --bytes=$md5_check_length $filename > /tmp/$filename.end.local set hpss_md5 = `md5sum /tmp/$filename.end.hpss | awk '{print $1}'` set local_md5 = `md5sum /tmp/$filename.end.local | awk '{print $1}'` if ($hpss_md5 != $local_md5) then echo "$filename transfer was bad (md5 mismatch at end of file)" set retval = 1 endif \rm /tmp/$filename.end.hpss \rm /tmp/$filename.end.local endif \rm /tmp/$filename.start.hpss \rm /tmp/$filename.start.local endif if ($retval == 0) then echo "$filename transfer was good" set retry = 0 else set retry = 1 echo retrying in 60 seconds sleep 60 endif # end transfer check end else if ($action == "--check") then # if the test ping failed above, we already exited, otherwise print success echo "hpss is up" set retval = 0 else echo "usage $0:t --list | --dir | --get | --put | --check" set retval = 1 endif echo " " echo " " exit $retval boinc-app-seti_8.00~svn3701.orig/ops/bin/README0000644000175000017500000000134611122523365020747 0ustar locutuslocutusThis is the seti_boinc ops/bin directory. Here you will find all kinds of script/binary tools for day-to-day operations of seti (and other affiliated projects). If you add anything, please note here where you expect the actually script to live and run in normal life. ### The following are in ~seti/dr2_data/productions/scripts and are ### used for data_pipeline management. Note that data_flow.cfg is a ### perl "include file" that many of the other scripts read in before ### executing. Maybe that should go elsewhere at some point. avg_file_create_dir count_hard_links.csh count_wugs_wus_by_tape.csh data_flow.cfg erase_data_drive file_to_thumper fill_xfer_to_hpss make_hpss_script make_xfer_script run_jan.csh seti_hsi.csh xfer_to_hpss boinc-app-seti_8.00~svn3701.orig/ops/bin/count_wugs_wus_by_tape.csh0000755000175000017500000000155311122523365025367 0ustar locutuslocutus#! /bin/csh if(${#argv} == 0 || $1 == "-h") then echo " " echo spikesbytape db tape_name echo " " exit endif set DB = $1 set TAPE = $2 source ~davea/seti/db/$DB dbaccess -e - << HERE database sah2; select tape.id, tape.name, tape.beam, tape.last_block_done, count(workunit_grp.id) from tape, workunit_grp where tape.name = "$TAPE" and workunit_grp.tape_info = tape.id group by tape.id, tape.name, tape.beam, tape.last_block_done order by tape.name, tape.beam; select count(workunit.id)/3584 from workunit, workunit_grp, tape where workunit.group_info = workunit_grp.id and workunit_grp.tape_info = tape.id and tape.name = "$TAPE"; HERE echo "checking down at HPSS:" /disks/thumper/raid5_d/users/seti/dr2_data/production/scripts/seti_hsi.csh --list $TAPE boinc-app-seti_8.00~svn3701.orig/ops/bin/make_xfer_script0000755000175000017500000000050711122523365023340 0ustar locutuslocutus#! /bin/csh # make_xfer_script - makes file_to_thumper script for all ??????? files in current directory set CURDIR = `/bin/pwd` echo '#! /bin/csh' echo " " foreach i (`/bin/ls -1 [0-9][0-9][a-z][a-z][0-9][0-9][a-z][a-z]`) echo /disks/thumper/raid5_d/users/seti/dr2_data/production/scripts/file_to_thumper $CURDIR/$i end boinc-app-seti_8.00~svn3701.orig/ops/bin/count_hard_links.csh0000755000175000017500000000004611122523365024113 0ustar locutuslocutus#! /bin/csh echo $1" "`stat -c%h $1` boinc-app-seti_8.00~svn3701.orig/ops/bin/file_to_thumper0000755000175000017500000000514311122523365023201 0ustar locutuslocutus#! /usr/bin/env perl # where is the configuration file? $cfgfile = "/disks/thumper/raid5_d/users/seti/dr2_data/production/scripts/data_flow.cfg"; # read it in and continue... $cfg = ""; open (CNFFILE,$cfgfile) or die "cannot open configuration file: $cfgfile\nmake sure this variable is set properly"; while () { $cfg .= $_ } close (CNFFILE); eval $cfg; $file = $ARGV[0]; if ($file eq "" || $file eq "-h" || $file eq "--help") { print "file_to_thumper full_path_to_file :\n copy data file to $nfsdatato (and do md5 checks)\n"; exit (1); } if (ord($file) ne ord("/")) { print "$file doesn't big with a \"/\" - make sure you enter a full path!\n"; exit (1); } if (! -f $file) { print "cannot find file: $file\n"; exit (1); } $basefile = basename($file); # will file fit on remote partition? $filesize = `$ls -l $file | $awk '{print \$5}'`; chomp $filesize; $spaceleft = `$df -P $fullcheck | $tail -1 | $awk '{print \$4}'`; chomp $spaceleft; $spaceleft *= 1024; if (($filesize + $buffer) > $spaceleft) { print "file: $file is too big to currently fit on $nfsdatato!\n"; exit (1); } # move the file, etc. print "file: $file (get md5s... "; # get initial md5s $headmd5 = `$head -c $md5size $file | $md5sum | awk '{print \$1}'`; chomp $headmd5; $tailmd5 = `$tail -c $md5size $file | $md5sum | awk '{print \$1}'`; chomp $tailmd5; open (OUTFILE,">${file}.md5_head_${md5size}"); print OUTFILE $headmd5 . "\n"; close (OUTFILE); open (OUTFILE,">${file}.md5_tail_${md5size}"); print OUTFILE $tailmd5 . "\n"; close (OUTFILE); # copy everything over print "scp files... "; system ("$su - seti -c \"$scp $file ${scpdatato}/${basefile}.copying\" > /dev/null 2>&1"); system ("$su - seti -c \"$scp ${file}.md5_head_${md5size} $scpmd5to\" > /dev/null 2>&1"); system ("$su - seti -c \"$scp ${file}.md5_tail_${md5size} $scpmd5to\" > /dev/null 2>&1"); # check remote md5s print "checking md5s... "; $rheadmd5 = `$head -c $md5size $nfsdatato/${basefile}.copying | $md5sum | awk '{print \$1}'`; chomp $rheadmd5; $rtailmd5 = `$tail -c $md5size $nfsdatato/${basefile}.copying | $md5sum | awk '{print \$1}'`; chomp $rtailmd5; if ($rheadmd5 ne $headmd5 || $rtailmd5 ne $tailmd5) { print "failure!)\n"; send_mail("ALERT: file_to_thumper md5 mismatch","The file: $file failed to copy from $hostname to thumper due to md5 mismatch."); system ("$touch $lockfile"); exit(1); } system ("$su - seti -c \"$mv $nfsdatato/${basefile}.copying $nfsdatato/${basefile}\" > /dev/null 2>&1"); print "unlinking... "; #unlink "$file"; unlink "${file}.md5_head_${md5size}"; unlink "${file}.md5_tail_${md5size}"; print "done!)\n"; boinc-app-seti_8.00~svn3701.orig/ops/bin/splitter_janitor_gbt0000755000175000017500000002346512663160170024255 0ustar locutuslocutus#! /usr/bin/perl -w # where is the data? # $file_dir = "/disks/thumper/raid5_d/users/seti/dr2_data/production/processing"; #$file_dir = "/home/seti/dr2_data/production/processing"; $file_dir = "/mydisks/b/users/btldata"; # $email_list = 'jeffc@ssl.berkeley.edu mattl@ssl.berkeley.edu korpela@ssl.berkeley.edu'; # $email_list = 'jeffc@ssl.berkeley.edu'; #$email_list = 'mattl@ssl.berkeley.edu jeffc@ssl.berkeley.edu'; $email_list = 'jeffc@ssl.berkeley.edu'; # num of seconds to keep files in _TO_BE_DELETED before actually deleting them $keep_for = 7*86400; # one week #$keep_for = 86400; # one day # what if we are missing beam/pol pairs out of the standard 14? should we move date to be deleted anyway? # 0 - no, 1 - yes; $delete_even_if_missing_beampols = 1; # where is seti_hsi.csh? $seti_hsi = "/home/boincadm/projects/sah/bin/seti_hsi.csh"; # set informix env $informixdir = "/usr/local/informix"; $currentpath = $ENV{"PATH"}; $currentldlp = $ENV{"LD_LIBRARY_PATH"}; $ENV{"INFORMIXDIR"}="${informixdir}"; $ENV{"INFORMIXSERVER"}="sah_master_tcp"; $ENV{"ONCONFIG"}="onconfig.sah_master"; $ENV{"PATH"}="${informixdir}/bin:${currentpath}"; $ENV{"LD_LIBRARY_PATH"}="${informixdir}/lib:${informixdir}/lib/esql:${currentldlp}"; # if --check_only flag is specified, do "check only" for current directory, ignoring dot files, etc. # basically just check for existence at HPSS, and if all 14 tapes are in science db and # mail us the results without moving/deleting anything. # if --not_at_hpss flag is specified, this supercedes --check_only - and only outputs what files # are here at the lab and fully split/processed, but not yet copied to HPSS # if --ignore_matching_sizes is specified, ignore if files don't match in size - delete anyway if # otherwise deleteable # if --dir flag is specified, go into that file_dir instead of default file_dir # if --beams is specified, use that # of beams (default 64) # if --pols is specific, use that # of pols (default 2) $check_only = 0; $not_at_hpss = 0; $ignore_matching_sizes = 0; $totalbeams = 64; $totalpols = 2; $totalbeampols = $totalbeams * $totalpols; while ($arg = shift) { if ($arg eq "--check_only") { $file_dir = `pwd`; chomp $file_dir; $check_only = 1; } elsif ($arg eq "--not_at_hpss") { $not_at_hpss = 1; } elsif ($arg eq "--ignore_matching_sizes") { $ignore_matching_sizes = 1; } elsif ($arg eq "--dir") { $file_dir = shift; } elsif ($arg eq "--beams") { $totalbeams = shift; } elsif ($arg eq "--pols") { $totalpols = shift; } else { print "splitter_janitor [--dir file_dir] [--check_only|--not_at_hpss]\n"; exit(1); } } # get data file list if (! -d $file_dir) { print "no such directory: $file_dir\n"; exit(1); } chdir $file_dir; undef @file_list; @uniqobs = `/bin/ls *.[0-9][0-9][0-9][0-9].raw | sed 's/.[0-9][0-9][0-9][0-9].raw\$//' | sort | uniq`; foreach $obs (@uniqobs) { chomp $obs; $headobs = `/bin/ls $obs* | sort -n | head -1`; chomp $headobs; push @file_list, $headobs; } chomp @file_list; $message = "Splitter Janitor Results:\n"; if ($check_only == 1) { $message .= "(doing check on data files in: $file_dir)\n"; } # is HPSS unavailable? if so, set warning, and undefine file_list and set check_only == 1 # in order to go right to mail at end (don't care if we're doing not_at_hpss check) if ($not_at_hpss == 0) { $check_hpss = `$seti_hsi --check`; chomp $check_hpss; if ($check_hpss eq "hpss is down") { undef @file_list; $check_only = 1; $message .= "\nHPSS is currently unavailable - bailing...\n"; } } # moving on - main part: foreach $file (@file_list) { $message .= "\n"; if ($not_at_hpss == 1 && ( -f "${file}.completely_done" || -f "${file}.completely_done_with_errors") && ! -f "${file}.at_hpss") { print "${file}\n"; } elsif ($not_at_hpss == 0) { if (! -f "${file}.at_hpss") { $hsicommand = "$seti_hsi --list $file"; $retval = system ($hsicommand . "> /dev/null"); $retval = $retval >> 8; if ($retval == 0) { $message .= "${file}: had no .at_hpss suffix but actually IS at HPSS - touching ${file}.at_hpss\n"; system ("/bin/touch ${file}.at_hpss"); } } if (( (-f "${file}.completely_done" || -f "${file}.completely_done_with_errors") && -f "${file}.at_hpss") || $check_only == 1) { $message .= "${file}: finished processing and xfering to hpss - checking...\n"; $domove = 1; # double check that it is at HPSS $hsicommand = "$seti_hsi --list $file"; $retval = system ($hsicommand . "> /dev/null"); $retval = $retval >> 8; if ($retval == 1) { $message .= "WARNING: ${file}: has .at_hpss suffix but IS NOT AT HPSS!\n"; # $domove = 0; # just a warning... still move if need be } else { $message .= "${file}: is at HPSS\n"; # now check that local/remote file sizes match $fsize = (stat($file))[7]; print "DEBUG: file size: - $fsize - \n"; $hsifsize = `$hsicommand | awk '{print \$5}'`; chomp $hsifsize; if ($fsize != $hsifsize && !$ignore_matching_sizes) { $message .= "${file}: local size: $fsize HPSS size: $hsifsize -- DO NOT MATCH\n"; $domove = 0; if (($hsifsize - $fsize) <= (134742016 * 5)) { # due to ragged files/software blanking - off by less then five buffers $message .= "${file}: ... but the HSI size is <= 134742016 x 5 bytes (five buffers) different\n"; $message .= "${file}: ... we will assume due to ragged files/etc. and flag it as okay\n"; $domove = 1; } } else { $message .= "${file}: local size: $fsize and HPSS size: $hsifsize match\n"; } } # final check - scan science database to make sure $dbcount = `echo "database sah2; select count(name) from tape where name = '${file}';" | dbaccess -e - 2>&1 | tail --l=+8 | head -1 | awk '{print \$1}'`; chomp $dbcount; #if ($dbcount != 14) { if ($dbcount != $totalbeampols) { #$message .= "${file}: tape does not have 14 entries in the tape table!\n"; $message .= "${file}: tape does not have ${totalbeampols} entries in the tape table!\n"; if ($delete_even_if_missing_beampols == 0) { # i.e. if we want to keep tapes around with missing beam/pol entries, then... $domove = 0; } } #else { $message .= "${file}: has all 14 entries in the tape table\n"; } else { $message .= "${file}: has ${dbcount} entries in the tape table\n"; } if ($domove == 1) { if ($check_only == 1) { $message .= "${file}: completely processed and at HPSS\n"; } else { $moveto = "./_TO_BE_DELETED"; if (! (-f "${file}.completely_done" || -f "${file}.completely_done_with_errors") ) { $message .= "${file}: tape not yet finished processing\n"; $domove = 0; } else { if (-f "${file}.completely_done_with_errors") { $moveto = "./_TO_BE_DELETED"; } } if ($domove == 1) { $thisdate = `/bin/date "+%F-%T"`; chomp $thisdate; if (-f "${file}.completely_done") { system ("/bin/mv ${file}.completely_done ./_COMPLETELY_DONE_HISTORY/${file}.completely_done.${thisdate}"); } if (-f "${file}.completely_done_with_errors") { system ("/bin/mv ${file}.completely_done_with_errors ./_COMPLETELY_DONE_HISTORY/${file}.completely_done_with_errors.${thisdate}"); } ($root, $seq, $ext) = split('\.', ${file}); system ("/bin/mv ${root}* $moveto"); #system ("/bin/mv ${file} $moveto"); #system ("/bin/mv ${file}.* $moveto"); $message .= "${file}: tape completely done and at HPSS - moved into $moveto\n"; } # end if $domove == 1 } # end if $check_only == 1 } # end if $domove = 1 } # end if file completely done else { $message .= "${file}: not finished processing/xfering to hpss yet\n"; if (! (-f "${file}.completely_done" || -f "${file}.completely_done_with_errors") ) { $message .= " ${file}: tape not yet finished processing\n"; } if (! (-f "${file}.at_hpss")) { $message .= " ${file}: no .at_hpss file - not finished xfering?\n"; } } } } # only bother with the actual file deleting if check_only == 0 && not_at_hpss == 0 if ($not_at_hpss == 1) { exit (0); } if ($check_only == 0) { if ($message ne "") { $message .= "\n"; } # if needed skip a line in case there's more chdir "./_TO_BE_DELETED"; undef @del_file_list; open (LS,"/bin/ls . |"); while () { $thisfile = $_; chomp $thisfile; if (/.[0-9][0-9][0-9][0-9].raw$/) { push @del_file_list, $_ } } close (LS); chomp @del_file_list; foreach $del_file (@del_file_list) { if (-l $del_file) { $message .= "${del_file}: is a symbolic link.. skipping..\n"; } else { $cdmtime = (stat("${del_file}.completely_done"))[9]; $ahmtime = (stat("${del_file}.at_hpss"))[9]; # print "${del_file} $cdmtime $ahmtime\n"; $now = time(); if (($now - $cdmtime) > $keep_for && ($now - $ahmtime) > $keep_for) { # Do not delete for real until we shake this out. This is where the real delete would happen via : system ("/bin/rm -f ${del_file}*"); $cdmdelta = ($now - $cdmtime); $ahmdelta = ($now - $ahmtime); $message .= "${del_file}: finished splitting $cdmdelta seconds ago, copied to HPSS $ahmdelta seconds ago - deleting!\n"; } } } } # send mail! if ($message ne "") { open(MAIL, "|/usr/sbin/sendmail -tv"); print MAIL "To: ${email_list}\n"; print MAIL 'From: seti@ssl.berkeley.edu' . "\n"; print MAIL "Subject: splitter_janitor report\n\n"; print MAIL "$message"; close(MAIL); } exit (0); boinc-app-seti_8.00~svn3701.orig/ops/bin/xfer_to_hpss0000755000175000017500000000133111122523365022512 0ustar locutuslocutus#! /usr/bin/env perl # where is the configuration file? $cfgfile = "/disks/thumper/raid5_d/users/seti/dr2_data/production/scripts/data_flow.cfg"; # read it in and continue... $cfg = ""; open (CNFFILE,$cfgfile) or die "cannot open configuration file: $cfgfile\nmake sure this variable is set properly"; while () { $cfg .= $_ } close (CNFFILE); eval $cfg; $file = $ARGV[0]; if ($file eq "" || $file eq "-h" || $file eq "--help") { print "xfer_to_hpss full_path_to_file :\n copy data file to hpss\n"; exit (1); } if (ord($file) ne ord("/")) { print "$file doesn't big with a \"/\" - make sure you enter a full path!\n"; exit (1); } if (! -f $file) { print "cannot find file: $file\n"; exit (1); } boinc-app-seti_8.00~svn3701.orig/ops/bin/erase_data_drive0000755000175000017500000000605211122523365023275 0ustar locutuslocutus#! /usr/bin/env perl # where is the configuration file? $cfgfile = "/disks/thumper/raid5_d/users/seti/dr2_data/production/scripts/data_flow.cfg"; # read it in and continue... $cfg = ""; open (CNFFILE,$cfgfile) or die "cannot open configuration file: $cfgfile\nmake sure this variable is set properly"; while () { $cfg .= $_ } close (CNFFILE); eval $cfg; $drivedev = $ARGV[0]; if ($drivedev eq "" || $drivedev eq "-h" || $drivedev eq "--help") { print "usage: erase_data_drive device_name (i.e. /dev/sdx2)\n"; print " note: will only work on unmounted drives\n\n"; exit (1); } if (! -b $drivedev) { print "no such device: $drivedev - exiting...\n"; exit (1); } $ismounted = `$mount | $awk '\$1 == "$drivedev"'`; if ($ismounted ne "") { print "drive $drivedev currently mounted! exiting...\n"; exit (1); } $tmpmount = "/mnt/temp_data_$$"; print "making temporary mount point: $tmpmount...\n"; mkdir $tmpmount || die "cannot make mount point: $tmpmount"; print "mounting $drivedev on $tmpmount...\n"; system ("$mount $drivedev $tmpmount"); print ".AO_DATA number on the data drive is: "; $aonumber = ""; if (-f "$tmpmount/.AO_DATA") { $aonumber = `$cat $tmpmount/.AO_DATA`; chomp $aonumber; } if ($aonumber eq "") { print "there is no number! exiting...\n"; chdir ("/root"); system ("$umount $drivedev"); rmdir $tmpmount || die "cannot remove mount point: $tmpmount"; exit (1); } print "$aonumber\n"; print "double checking data files are elsewhere...\n"; chdir ($tmpmount); # go to mounted drive @datafiles = `$ls -1 [0-9][0-9][a-z][a-z][0-9][0-9][a-z][a-z]`; foreach $datafile (@datafiles) { chomp $datafile; print " datafile: $datafile "; if (-f "$xfer_to_hpss_dir/$datafile") { print "in xfer_to_hpss"; } elsif (-f "$processing_dir/$datafile") { print "in processing"; } else { print "- checking at hpss... "; $hsicommand = "$su seti -c \"$hsi --list $datafile\""; $retval = system ($hsicommand . "> /dev/null"); $retval = $retval >> 8; if ($retval == 0) { print "yes"; } else { # file not at hpss, or anywhere obvious print "no! can't find anywhere obvious - exiting...\n"; chdir ("/root"); system ("$umount $drivedev"); rmdir $tmpmount || die "cannot remove mount point: $tmpmount"; exit (1); } } print "\n"; } chdir ("/root"); print "all files are somewhere else! moving on...\n"; print "umounting $drivedev...\n"; system ("$umount $drivedev"); print "okay here we go: WIPING DRIVE with mke2fs...\n"; system ("$mke2fs -m 1 -T largefile4 -j $drivedev"); print "mounting empty $drivedev on $tmpmount...\n"; system ("$mount $drivedev $tmpmount"); print "creating .AO_DATA file with number $aonumber...\n"; open (AODATA,">$tmpmount/.AO_DATA"); print AODATA $aonumber; close (AODATA); chmod 0000, "$tmpmount/.AO_DATA"; chdir ("/root"); # just to be sure we can unmount print "umounting $drivedev one last time...\n"; system ("$umount $drivedev"); print "removing temporary mount point: $tmpmount...\n"; rmdir $tmpmount || die "cannot remove mount point: $tmpmount"; boinc-app-seti_8.00~svn3701.orig/ops/bin/avg_file_create_dir0000755000175000017500000000061711122523365023752 0ustar locutuslocutus#! /usr/bin/env perl $now = time(); @files = `/bin/ls -1`; $alltime = 0; $count = 0; foreach $file (@files) { chomp $file; if (($now - (stat($file))[9]) > 5184000) { print "$file too old - skipping\n"; } else { $count++; $alltime += (stat($file))[9]; print "$file\n"; } } $avg = $alltime / $count; print "average mtime: $avg (" . localtime($avg) . ")\n"; exit (0); boinc-app-seti_8.00~svn3701.orig/ops/bin/run_mb_splitter0000755000175000017500000002435412625151110023223 0ustar locutuslocutus#! /usr/bin/perl -w # usage: run_mb_splitter [-filedir filedir] use locale; use sigtrap qw(HUP TERM INT); use Cwd; use Fcntl; $ENV{'INFORMIXDIR'} = '/usr/local/informix'; $ENV{'INFORMIXSQLHOSTS'} = '/usr/local/informix/etc/sqlhosts'; $ENV{'INFORMIXSERVER'} = 'sah_master_tcp'; $ENV{'LD_LIBRARY_PATH'} = '/usr/local/informix/lib:/usr/local/informix/lib/esql:/usr/local/lib:/usr/X11R6/lib:/usr/lib:/lib:/usr/ccs/lib:/usr/local/lib:/usr/local/ssl/lib:/usr/local/informix/lib:/usr/local/informix/lib/esql:/usr/local/generic/lib:/usr/lib64:/usr/lib64/mysql'; # ALFA receivers must be specified with beam (0-6) and polarization (0-1), i.e. -alfa=4,0 # signal handler sub sub touch_and_die { print STDERR time . " run_mb_splitter caught signal and is touching ${split_halt_msg}..\n"; system ("/bin/touch $split_halt_msg"); exit(99) } sub is_completely_done { my $chkfile = $_[0]; my $completely_done = 1; my $errors = 0; for (my $chkbeam = 0; $chkbeam < 7; $chkbeam++) { for (my $chkpolarization = 0; $chkpolarization < 2; $chkpolarization++) { if (! -f "${chkfile}.done.${chkbeam},${chkpolarization}" && ! -f "${chkfile}.ERROR.${chkbeam},${chkpolarization}") { $completely_done = 0; } if ( -f "${chkfile}.ERROR.${chkbeam},${chkpolarization}") { $errors = 1; } } } if ($completely_done == 1 && $errors == 1) { return -1; } # completely done, but with errors return $completely_done; } # project/splitter vars # sleep(rand()*30); $mb_prog_loc = "/home/boincadm/projects/sah/bin"; $mb_prog_name = "mb_splitter_swb.x86_64"; $app_name = "setiathome_enhanced"; $project_dir = "/home/boincadm/projects/sah/"; # $file_dir = "/disks/thumper/raid5_d/users/seti/dr2_data/production/processing"; $file_dir = "/home/boincadm/projects/sah/processing"; $split_halt_msg = "$project_dir/stop_splitters"; $email_list = 'jeffc@ssl.berkeley.edu korpela@ssl.berkeley.edu mattl@ssl.berkeley.edu'; $found_file = "0"; $host = `/bin/uname -n | /bin/sed s/.ssl.berkeley.edu//`; $dovertical = 0; chomp $host; $usage = "usage: run_mb_splitter [-vertical] [-exe executable_name] [-filedir filedir] [-app app_name]\n(assuming all executables are in: $mb_prog_loc)\n"; # before anything, stagger processes by sleeping a bit @numprocs = `pgrep -f run_mb_splitter`; $sleepsecs = $#numprocs * 2; sleep $sleepsecs; # check args $checkhelp = $ARGV[0] || ""; if ($checkhelp eq "-h" || $checkhelp eq "-help" || $checkhelp eq "--help") { print $usage; exit(2); } while ($ARGV[0] ne "") { $tempvar = $ARGV[0]; if ($tempvar eq '-filedir') { shift @ARGV; $file_dir = $ARGV[0] } elsif ($tempvar eq '-exe') { shift @ARGV; $mb_prog_name = $ARGV[0] } elsif ($tempvar eq '-app') { shift @ARGV; $app_name = $ARGV[0] } elsif ($tempvar eq '-vertical') { $dovertical = 1; } else { print $usage; exit(2); } shift @ARGV; } $SIG{HUP} = $SIG{TERM} = $SIG{INT} = \&touch_and_die; # main loop (run as long as halt trigger file doesn't exist) while (! -f "$split_halt_msg") { chdir $file_dir; $found_file = 0; # get working state of directory and determine what work is available to do undef @file_list; # NOTE: slurp in 2000-2007 files first, then 2008-2009 files, then anything after 2010 open (LS,"/bin/ls -tr . |"); while () { $thisfile = $_; chomp $thisfile; if (/^[0-9][0-9][a-z][a-z]0[0-7][a-z][a-z]$/) { push @file_list, $_ } } close (LS); open (LS,"/bin/ls -tr . |"); while () { $thisfile = $_; chomp $thisfile; if (/^[0-9][0-9][a-z][a-z]0[8-9][a-z][a-z]$/) { push @file_list, $_ } } close (LS); open (LS,"/bin/ls -tr . |"); while () { $thisfile = $_; chomp $thisfile; if (/^[0-9][0-9][a-z][a-z][1-9][0-9][a-z][a-z]$/) { push @file_list, $_ } } close (LS); chomp @file_list; $dothisfile = ""; $dobeam = -1; $dopolarization = -1; foreach $file (@file_list) { # is it a broken sym link? if (! -e $file) { print "${file} doesn't actually exist! (broken sym link?) skipping...\n"; next; } # are we working on this file already? $isworking = 0; for ($beam = 0; $beam < 7; $beam++) { for ($polarization = 0; $polarization < 2; $polarization++) { if (-f "${file}.working.${beam},${polarization}") { $isworking = 1; } } } # if we're working on this file already and -vertical is set, skip it: if ($isworking == 1 && $dovertical == 1) { print "${file} is being worked on and -vertical is set - moving on...\n"; next; } # check if completely done and clean up in case this hasn't happened yet if (is_completely_done($file) == 1 && ! -f "${file}.completely_done") { `/bin/touch ${file}.completely_done`; `/bin/rm -f ${file}.done.*`; } if (is_completely_done($file) == -1 && ! -f "${file}.completely_done_with_errors") { `/bin/touch ${file}.completely_done_with_errors`; } if (-f "${file}.completely_done") { print "${file} is completely_done - moving on...\n"; next; } if (-f "${file}.copying_in_lando") { print "${file} is currently being read in from lando - moving on...\n"; next; } if (-f "${file}.copying_in_hpss") { print "${file} is currently being read in from hpss - moving on...\n"; next; } for ($beam = 0; $beam < 7; $beam++) { for ($polarization = 0; $polarization < 2; $polarization++) { if ($dothisfile eq "") { print "trying file $file beam $beam polarization $polarization\n"; } if (! -f "${file}.working.${beam},${polarization}" && ! -f "${file}.done.${beam},${polarization}" && ! -f "${file}.ERROR.${beam},${polarization}" && $dothisfile eq "") { $dothisfile = $file; $dobeam = $beam; $dopolarization = $polarization; } # end if } # end for polarization } # end for beam } # end foreach file if ($dothisfile eq "") { print "nothing to do - exiting...\n"; exit(6); } print "starting splitting on file: $dothisfile beam: $dobeam polarization: $dopolarization...\n"; sysopen (WORKING,"${dothisfile}.working.${dobeam},${dopolarization}",O_WRONLY|O_EXCL|O_CREAT) or die "wait a minute - race condition opening .working file - bailing!!!\n"; $now = `/bin/date`; chomp $now; print WORKING "$host : ". time() . " ($now)\n"; close (WORKING); open(MAIL, "|/usr/sbin/sendmail -t"); print MAIL "To: ${email_list}\n"; print MAIL 'From: splitters@ssl.berkeley.edu' . "\n"; print MAIL "Subject: splitter starting on host: ${host}\n\n"; print MAIL "starting file: ${dothisfile} beam: ${dobeam} polarization: ${dopolarization}\n"; close(MAIL); $now = `/bin/date`; chomp $now; print "$now : starting file: ${dothisfile} beam: ${dobeam} polarization: ${dopolarization}\n"; $filefullpath = "${file_dir}/${dothisfile}"; mkdir "/tmp/splitter_${dothisfile}_${dobeam}_${dopolarization}"; mkdir "/tmp/splitter_${dothisfile}_${dobeam}_${dopolarization}/wu_inbox"; chdir "/tmp/splitter_${dothisfile}_${dobeam}_${dopolarization}"; `/bin/rm -f wu_inbox/*`; print "LD_LIBRARY_PATH: "; print $ENV{'LD_LIBRARY_PATH'}; print "\n"; $splitcommand = "/bin/nice -19 /usr/bin/ionice -c2 -n7 ${mb_prog_loc}/${mb_prog_name} $filefullpath -resume -alfa=${dobeam},${dopolarization} -projectdir=${project_dir} -trigger_file_path=/${split_halt_msg} -appname=${app_name}"; print "(running command: ${splitcommand})\n"; $retval = system ($splitcommand); $retval = $retval >> 8; print "(command exited with retval: $retval)\n"; if ( $retval == 0 ) { # splitter ended gracefully at end of file sleep 60; # wait for child process to finish moving the files from wu_inbox open(MAIL, "|/usr/sbin/sendmail -t"); print MAIL "To: ${email_list}\n"; print MAIL 'From: splitters@ssl.berkeley.edu' . "\n"; print MAIL "Subject: splitter finishing on host: ${host}\n\n"; print MAIL "finished file: ${dothisfile} beam: ${dobeam} polarization: ${dopolarization}\n"; #open (MAIL, "|/usr/ucb/mail -s \"$host splitter finished\" $email_list"); open (MAIL, "|/bin/mail -s \"$host splitter finished\" $email_list"); print MAIL "$host splitter finished on file: ${dothisfile}\n\n"; open (RCDCHK,"splitterlog"); while () { print MAIL $_ } close (RCDCHK); close(MAIL); if (-f "${filefullpath}.firsttry.${dobeam},${dopolarization}") { `/bin/touch ${filefullpath}.done.${dobeam},${dopolarization}`; `/bin/rm -f ${filefullpath}.firsttry.${dobeam},${dopolarization}`; if (is_completely_done($filefullpath) == 1 && ! -f "${filefullpath}.completely_done") { `/bin/touch ${filefullpath}.completely_done`; `/bin/rm -f ${filefullpath}.done.*`; } if (is_completely_done($filefullpath) == -1 && ! -f "${filefullpath}.completely_done_with_errors") { `/bin/touch ${filefullpath}.completely_done_with_errors`; } } else { `/bin/touch ${filefullpath}.firsttry.${dobeam},${dopolarization}`; } `/bin/rm -f ${filefullpath}.working.${dobeam},${dopolarization}`; chdir $file_dir; `/bin/rm -rf /tmp/splitter_${dothisfile}_${dobeam}_${dopolarization}`; } elsif ( $retval == 2 ) { # splitter ended gracefully but before finishing file # remove working suffix - allows it to be resumed later `/bin/rm -f ${filefullpath}.working.${dobeam},${dopolarization}`; chdir $file_dir; `/bin/rm -rf /tmp/splitter_${dothisfile}_${dobeam}_${dopolarization}`; print "WARNING : splitter running on file: ${dothisfile} beam: ${dobeam} polarization: ${dopolarization} ended before EOF\n"; } else { # spitter ended in error! open(ERRFILE,">${filefullpath}.ERROR.${dobeam},${dopolarization}"); print ERRFILE "$host\n"; close(ERRFILE); `/bin/rm -f ${filefullpath}.working.${dobeam},${dopolarization}`; print "CRITICAL : splitter running on file: ${dothisfile} beam: ${dobeam} polarization: ${dopolarization} ended in error!\n"; print "exiting run_mb_splitter (and keeping working dir in /tmp)..\n"; exit(1); } $now = `/bin/date`; chomp $now; print "$now : finished running on file: ${dothisfile} beam: ${dobeam} polarization: ${dopolarization}\n"; } # while halt trigger file doesn't exist print "$split_halt_msg exists - exiting..\n"; exit (0); boinc-app-seti_8.00~svn3701.orig/ops/bin/fill_xfer_to_hpss0000755000175000017500000000344511122523365023530 0ustar locutuslocutus#! /usr/bin/env perl # where is the configuration file? $cfgfile = "/disks/thumper/raid5_d/users/seti/dr2_data/production/scripts/data_flow.cfg"; # read it in and continue... $cfg = ""; open (CNFFILE,$cfgfile) or die "cannot open configuration file: $cfgfile\nmake sure this variable is set properly"; while () { $cfg .= $_ } close (CNFFILE); eval $cfg; print "checking xfer_to_hpss directory for excess files..."; chdir ($xfer_to_hpss_dir); @datafiles = `$ls -1 [0-9][0-9][a-z][a-z][0-9][0-9][a-z][a-z]`; foreach $datafile (@datafiles) { chomp $datafile; print "datafile: $datafile "; $hsicommand = "$su seti -c \"$hsi --list $datafile\""; $retval = system ($hsicommand . "> /dev/null"); $retval = $retval >> 8; if ($retval == 0) { print "already at hpss - removing hard link"; system ("$su seti -c \"$rm $xfer_to_hpss_dir/$datafile\""); } else { print " - not transferred yet"; } print "\n"; } chdir ($processing_dir); @datafiles = `$ls -1 [0-9][0-9][a-z][a-z][0-9][0-9][a-z][a-z]`; foreach $datafile (@datafiles) { chomp $datafile; print "datafile: $datafile "; if (-f "${datafile}.at_hpss") { print "- .at_hpss exists - skipping"; } else { if (-f "$xfer_to_hpss_dir/$datafile") { print "- already hard linked in xfer_to_hpss - skipping"; } else { print "- checking at hpss... "; $hsicommand = "$su seti -c \"$hsi --list $datafile\""; $retval = system ($hsicommand . "> /dev/null"); $retval = $retval >> 8; if ($retval == 0) { print "already at hpss - skipping"; } else { # file here and not at hpss, so make hard link in xfer to hpss dir: system ("$su seti -c \"$ln $datafile $xfer_to_hpss_dir/$datafile\""); print " - made hard link in xfer_to_hpss"; } } } print "\n"; } exit (0); boinc-app-seti_8.00~svn3701.orig/ops/src/0000755000175000017500000000000013155506301020101 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/validate/0000755000175000017500000000000013155506301020302 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/validate/sah_result.h0000644000175000017500000000326612647247151022645 0ustar locutuslocutus#ifndef _SAH_RESULT_ #define _SAH_RESULT_ // this file should not refer to either BOINC or S@h DB #include #include using namespace std; #define SIGNAL_TYPE_SPIKE 1 #define SIGNAL_TYPE_GAUSSIAN 2 #define SIGNAL_TYPE_PULSE 3 #define SIGNAL_TYPE_TRIPLET 4 #define SIGNAL_TYPE_BEST_SPIKE 5 #define SIGNAL_TYPE_BEST_GAUSSIAN 6 #define SIGNAL_TYPE_BEST_PULSE 7 #define SIGNAL_TYPE_BEST_TRIPLET 8 #define SIGNAL_TYPE_AUTOCORR 9 #define SIGNAL_TYPE_BEST_AUTOCORR 10 // Result Flags. Can be passed from validator to assimilator // via the BOINC result.opaque field. Note that you have // to cast to float in order to assign a flag to the opaque // field. OR into a temp int and then assign with a cast. #define RESULT_FLAG_OVERFLOW 0x00000001 struct SIGNAL { int type; double power; double period; double ra; double decl; double time; double freq; double delay; double sigma; double chisqr; double max_power; double peak_power; double mean_power; double score; unsigned char pot[256]; int len_prof; double snr; double thresh; int fft_len; double chirp_rate; bool checked; // temp bool roughly_equal(SIGNAL&); }; struct SAH_RESULT { bool have_result; bool overflow; vector signals; bool has_roughly_equal_signal(SIGNAL&); bool strongly_similar(SAH_RESULT&); bool weakly_similar(SAH_RESULT&); bool bad_values(); int parse_file(FILE*); int num_signals; bool found_best_autocorr; bool is_overflow; double setiathome_version; }; extern int write_sah_db_entries(SAH_RESULT&); #endif boinc-app-seti_8.00~svn3701.orig/validate/sah_result.cpp0000644000175000017500000002311312647247151023171 0ustar locutuslocutus#include #include #include "parse.h" #include "sah_result.h" // the difference between two numbers, // as a fraction of the largest in absolute value // double rel_diff(double x1, double x2) { if (x1 == 0 && x2 == 0) return 0; if (x1 == 0) return 1; if (x2 == 0) return 1; double d1 = fabs(x1); double d2 = fabs(x2); double d = fabs(x1-x2); if (d1 > d2) return d/d1; return d/d2; } double abs_diff(double x1, double x2) { return fabs(x1-x2); } // return true if the two signals are the same // within numerical tolerances // bool SIGNAL::roughly_equal(SIGNAL& s) { double second = 1.0/86400.0; // 1 second as a fraction of a day if (type != s.type) return false; // tolerances common to all signals if (abs_diff(ra, s.ra) > .00066) return false; // .01 deg if (abs_diff(decl, s.decl) > .01) return false; // .01 deg if (abs_diff(time, s.time) > second) return false; // 1 sec if (abs_diff(freq, s.freq) > .01) return false; // .01 Hz if (abs_diff(chirp_rate, s.chirp_rate) > .01) return false; // .01 Hz/s if (fft_len != s.fft_len) return false; // equal switch (type) { case SIGNAL_TYPE_SPIKE: case SIGNAL_TYPE_BEST_SPIKE: if (rel_diff(power, s.power) > .01) return false; // 1% return true; case SIGNAL_TYPE_GAUSSIAN: case SIGNAL_TYPE_BEST_GAUSSIAN: if (rel_diff(peak_power, s.peak_power) > .01) return false; // 1% if (rel_diff(mean_power, s.mean_power) > .01) return false; // 1% if (rel_diff(sigma, s.sigma) > .01) return false; // 1% if (rel_diff(chisqr, s.chisqr) > .01) return false; // 1% //if (rel_diff(max_power, s.max_power) > .01) return false; // ?? jeffc return true; case SIGNAL_TYPE_PULSE: case SIGNAL_TYPE_BEST_PULSE: if (rel_diff(power, s.power) > .01) return false; // 1% if (rel_diff(mean_power, s.mean_power) > .01) return false; // 1% if (abs_diff(period, s.period) > .01) return false; // .01 sec if (rel_diff(snr, s.snr) > .01) return false; // 1% if (rel_diff(thresh, s.thresh) > .01) return false; // 1% return true; case SIGNAL_TYPE_TRIPLET: case SIGNAL_TYPE_BEST_TRIPLET: if (rel_diff(power, s.power) > .01) return false; // 1% if (rel_diff(mean_power, s.mean_power) > .01) return false; // 1% if (rel_diff(period, s.period) > .01) return false; // 1% return true; case SIGNAL_TYPE_AUTOCORR: case SIGNAL_TYPE_BEST_AUTOCORR: if (rel_diff(power, s.power) > .01) return false; // 1% if (rel_diff(delay, s.delay) > .01) return false; // 1% return true; } return false; } // parse a SETI@home result file // int SAH_RESULT::parse_file(FILE* f) { char buf[1024]; SIGNAL s; double d; int i; num_signals = 0; found_best_autocorr=false; is_overflow=false; int num_spikes=0; memset(&s, 0, sizeof(s)); while (fgets(buf, 256, f)) { if (match_tag(buf, "")) { memset(&s, 0, sizeof(s)); s.type = SIGNAL_TYPE_SPIKE; num_signals++; num_spikes++; } else if (match_tag(buf, "")) { memset(&s, 0, sizeof(s)); s.type = SIGNAL_TYPE_BEST_SPIKE; } else if (match_tag(buf, "")) { memset(&s, 0, sizeof(s)); s.type = SIGNAL_TYPE_AUTOCORR; num_signals++; found_best_autocorr=true; // needed for checking for people trying to run v6 clients. } else if (match_tag(buf, "")) { memset(&s, 0, sizeof(s)); s.type = SIGNAL_TYPE_BEST_AUTOCORR; found_best_autocorr=true; // needed for checking for people trying to run v6 clients. } else if (match_tag(buf, "")) { memset(&s, 0, sizeof(s)); s.type = SIGNAL_TYPE_GAUSSIAN; num_signals++; } else if (match_tag(buf, "")) { memset(&s, 0, sizeof(s)); s.type = SIGNAL_TYPE_BEST_GAUSSIAN; } else if (match_tag(buf, "")) { memset(&s, 0, sizeof(s)); s.type = SIGNAL_TYPE_PULSE; num_signals++; } else if (match_tag(buf, "")) { memset(&s, 0, sizeof(s)); s.type = SIGNAL_TYPE_BEST_PULSE; } else if (match_tag(buf, "")) { memset(&s, 0, sizeof(s)); s.type = SIGNAL_TYPE_TRIPLET; num_signals++; } else if (match_tag(buf, "")) { memset(&s, 0, sizeof(s)); s.type = SIGNAL_TYPE_BEST_TRIPLET; } else if (parse_double(buf, "",d)) { setiathome_version = d; } else if (parse_double(buf, "", d)) { s.ra = d; } else if (parse_double(buf, "", d)) { s.decl = d; } else if (parse_double(buf, "", d)) { s.power = d; } else if (parse_double(buf, "")) { if (s.type != SIGNAL_TYPE_SPIKE) { return -1; } signals.push_back(s); } else if (match_tag(buf, "")) { if (s.type != SIGNAL_TYPE_BEST_SPIKE) { return -1; } signals.push_back(s); } else if (match_tag(buf, "")) { if (s.type != SIGNAL_TYPE_AUTOCORR) { return -1; } signals.push_back(s); } else if (match_tag(buf, "")) { if (s.type != SIGNAL_TYPE_BEST_AUTOCORR) { return -1; } signals.push_back(s); } else if (match_tag(buf, "")) { if (s.type != SIGNAL_TYPE_GAUSSIAN) { return -1; } signals.push_back(s); } else if (match_tag(buf, "")) { if (s.type != SIGNAL_TYPE_BEST_GAUSSIAN) { return -1; } signals.push_back(s); } else if (match_tag(buf, "
")) { if (s.type != SIGNAL_TYPE_PULSE) { return -1; } signals.push_back(s); } else if (match_tag(buf, "")) { if (s.type != SIGNAL_TYPE_BEST_PULSE) { return -1; } signals.push_back(s); } else if (match_tag(buf, "
")) { if (s.type != SIGNAL_TYPE_TRIPLET) { return -1; } signals.push_back(s); } else if (match_tag(buf, "")) { if (s.type != SIGNAL_TYPE_BEST_TRIPLET) { return -1; } signals.push_back(s); } } if (num_spikes>=30) is_overflow=true; return 0; } // return true if the given signal is roughly equal to a signal // from the result // bool SAH_RESULT::has_roughly_equal_signal(SIGNAL& s) { unsigned int i; for (i=0; i../aclocal.m4 ../configure: ../configure.ac ../aclocal.m4 ../config.h.in (cd ..; make config.h) $(PROG): $(OBJS) $(BOINC_OBJS) $(CXX) $(OBJS) $(BOINC_OBJS) -I../db $(BOINC_CFLAGS) $(CLIBS) $(BOINC_LIBS) $(MYSQL_LIBS) $(INFORMIX_LIBS) -o $(PROG) $(SYSLIBS) clean: rm -f *.$(OBJEXT) $(PROG) dependencies config.log config.cache #include dependencies boinc-app-seti_8.00~svn3701.orig/validate/sah_boinc_db.h0000644000175000017500000000014110671336410023043 0ustar locutuslocutus#include "boinc_db.h" #include "sah_result.h" extern int get_result_file(RESULT&, SAH_RESULT&); boinc-app-seti_8.00~svn3701.orig/validate/sah_validate.cpp0000644000175000017500000006176013051410525023441 0ustar locutuslocutus#include "sah_config.h" #include #include #include #include #include "parse.h" #include "boinc_db.h" #include "error_numbers.h" #include "sah_result.h" #include "sah_boinc_db.h" //#include "boinc_db.h" #include "util.h" #include "sched_config.h" #include "sched_util.h" #include "sched_msgs.h" extern char app_name[256]; const int MAX_ALLOWABLE_CREDIT = 225; struct VALIDATE_STATS { int nstrong_compare; int nstrong; int nweak_compare; int nweak; int bad_results; void print(); }; int validate_single(vector& results, long & canonical_id, double& granted_credit); int validate_plural(vector& results, vector& sah_results, long & canonical_id, double& granted_credit); void check_overflow_result(RESULT& r); int log_cuda_result(RESULT& result, double& granted_credit); bool is_cuda(RESULT result); int handle_cuda_notvalid(RESULT& result_1, RESULT& result_2); void VALIDATE_STATS::print() { printf("Strongly similar: %d out of %d\n", nstrong, nstrong_compare); printf("Weakly similar: %d out of %d\n", nweak, nweak_compare); } VALIDATE_STATS validate_stats; // the init and usage functions are required by boinc int validate_handler_init(int, char**) { return 0; } void validate_handler_usage() { } // check_set() is called from BOINC code and is passed a vector of all // received results for work unit. check_set() determines the canonical // result and flags each result as to whether it is similar enough to the // canonical result to be given credit. check_set provides BOINC with both // the canonical ID and the amount of credit to be granted to each validated // result. As a matter of policy the validator does not do values checking. // The canonical result could have bad values. The detection and flagging // of this situation is a function of the assimilator. // //------------------------------------------------------------ int check_set( vector& results, WORKUNIT& wu, long & canonicalid, double& granted_credit, bool& retry) { //------------------------------------------------------------ // Note that SAH_RESULT is not the same type as the standard sah // result as it appears in the app and the science backend. Rather // it simply contains a vector of all the signals returned in a // a given result, along with functions used to validate that result // (ie that set of signals). // I should rename the type. jeffc vector sah_results; //SAH_RESULT s; RESULT r; DB_RESULT db_result; unsigned int i, j, k, good_result_count=0; bool found, err_opendir=false; double max_credit, min_credit, sum; int max_credit_i=-1, min_credit_i=-1, nvalid, retval; vector bad_result; retry=false; // init log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "check_set() checking %ld results\n", results.size() ); // read and parse the result files // for (i=0; i& results, long& canonicalid, double& granted_credit) { // This routine is called for single validation (from a trusted client). //------------------------------------------------------------ log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[RESULT#%ld] is trusted nonredundant and therefore canonical\n", results[0].id ); check_overflow_result(results[0]); results[0].validate_state = VALIDATE_STATE_VALID; canonicalid = results[0].id; if (results[0].claimed_credit <= MAX_ALLOWABLE_CREDIT) { granted_credit = results[0].claimed_credit; } else { log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[RESULT#%ld] is claiming greater than max allowable credit (%d). Granting max allowable.\n", results[0].id, MAX_ALLOWABLE_CREDIT ); granted_credit = MAX_ALLOWABLE_CREDIT; } return(0); } //------------------------------------------------------------ int validate_plural(vector& results, vector& sah_results, long& canonicalid, double& granted_credit) { // This routine is called for redundant validation (from nontrusted or test case clients) . //------------------------------------------------------------ unsigned int i, j, k; bool found; double max_credit, min_credit, sum; int max_credit_i=-1, min_credit_i=-1, nvalid, retval; // see if there's a pair of results that are strongly similar // Not all results are *neccessarily* checked for overflow. Any // result that may become the canonical reult is checked and thus // a valid overflow indicator is always paased on to the assimilator. found = false; for (i=0; i8.89))&& !(sah_results[i].is_overflow || results[i].runtime_outlier) && !strcmp(app_name,"setiathome_v8")) { results[i].validate_state = VALIDATE_STATE_INVALID; log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[RESULT#%ld] is from an invalid app_version (%f)\n", results[i].id, sah_results[i].setiathome_version ); continue; } for (j=i+1; j8.89))&& !(sah_results[j].is_overflow || results[j].runtime_outlier) && !strcmp(app_name,"setiathome_v8")) { results[j].validate_state = VALIDATE_STATE_INVALID; log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[RESULT#%ld] is from an invalid app_version (%f)\n", results[j].id,sah_results[j].setiathome_version ); continue; } if (sah_results[i].strongly_similar(sah_results[j])) { log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[RESULT#%ld (%d signals) and RESULT#%ld (%d signals)] ARE strongly similar\n", results[i].id, sah_results[i].num_signals, results[j].id, sah_results[j].num_signals ); found = true; validate_stats.nstrong++; break; } handle_cuda_notvalid(results[i], results[j]); // temporary for cuda debugging log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[RESULT#%ld (%d signals) and RESULT#%ld (%d signals)] are NOT strongly similar\n", results[i].id, sah_results[i].num_signals, results[j].id, sah_results[j].num_signals ); } // end scan with [j] to match [i] if (found) break; } // end scan with [i] to find canonical if (found) { // At this point results[i] is the canonical result and results[j] // is strongly similar to results[i]. canonicalid = results[i].id; max_credit = 0; min_credit = 0; nvalid = 0; for (k=0; k8.89))&& !(sah_results[k].is_overflow || results[k].runtime_outlier) && !strcmp(app_name,"setiathome_v8")) { results[k].validate_state = VALIDATE_STATE_INVALID; log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[RESULT#%ld] is from an invalid app_version (%f)\n", results[k].id,sah_results[k].setiathome_version ); continue; } if (k == i || k == j) { results[k].validate_state = VALIDATE_STATE_VALID; } else { validate_stats.nweak_compare++; if (sah_results[k].weakly_similar(sah_results[i])) { validate_stats.nweak++; log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[CANONICAL RESULT#%ld (%d signals) and RESULT#%ld (%d signals)] ARE weakly similar\n", results[i].id, sah_results[i].num_signals, results[k].id, sah_results[k].num_signals ); results[k].validate_state = VALIDATE_STATE_VALID; } else { log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[CANONICAL RESULT#%ld (%d signals) and RESULT#%ld (%d signals)] are NOT weakly similar\n", results[i].id, sah_results[i].num_signals, results[k].id, sah_results[k].num_signals ); results[k].validate_state = VALIDATE_STATE_INVALID; handle_cuda_notvalid(results[i], results[k]); // temporary for cuda debugging } } if (results[k].validate_state == VALIDATE_STATE_VALID) { if (results[k].claimed_credit < 0) { results[k].claimed_credit = 0; } if (nvalid == 0) { max_credit = min_credit = results[k].claimed_credit; max_credit_i = min_credit_i = k; } else { if (results[k].claimed_credit >= max_credit) { max_credit = results[k].claimed_credit; max_credit_i = k; } if (results[k].claimed_credit <= min_credit) { min_credit = results[k].claimed_credit; min_credit_i = k; } } nvalid++; } // end validate_state == VALIDATE_STATE_VALID } // end scan with [k] to validate rest of set against canonical // the granted credit is the average of claimed credits // of valid results, discarding the largest and smallest // if (nvalid == 2) { granted_credit = min_credit; } else { // Take care of case where all claimed credits are equal. if (max_credit == min_credit) { granted_credit = min_credit; } else { sum = 0; for (k=0; k8.89))&& !(sah_new.is_overflow || new_result.runtime_outlier) && !strcmp(app_name,"setiathome_v8")) { new_result.validate_state = VALIDATE_STATE_INVALID; retval = 0; log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[RESULT#%ld] is from an invalid app_version (%f)\n", new_result.id,sah_new.setiathome_version ); goto return_retval; } log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[RESULT#%ld] getting canonical result file %s\n", canonical.id, canonical.name ); retval = get_result_file((RESULT &)canonical, sah_canonical); if (retval) { log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[RESULT#%ld] read/parse of %s FAILED with retval %d\n", canonical.id, canonical.name, retval ); // A directory problem may be transient. if (retval == ERR_OPENDIR) { retry = true; retval = 0; goto return_retval; } else { // a non-transient, non-recoverable error - set new_result to error. new_result.outcome = RESULT_OUTCOME_VALIDATE_ERROR; new_result.validate_state = VALIDATE_STATE_INVALID; retval = 0; goto return_retval; } } if (sah_canonical.weakly_similar(sah_new)) { log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[CANONICAL RESULT#%ld (%d signals) and NEW RESULT#%ld (%d signals)] ARE weakly similar\n", canonical.id, sah_canonical.num_signals, new_result.id, sah_new.num_signals ); new_result.validate_state = VALIDATE_STATE_VALID; } else { log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[CANONICAL RESULT#%ld (%d signals) and NEW RESULT#%ld (%d signals)] are NOT weakly similar\n", canonical.id, sah_canonical.num_signals, new_result.id, sah_new.num_signals ); new_result.validate_state = VALIDATE_STATE_INVALID; handle_cuda_notvalid(canonical, new_result); // temporary for cuda debugging } if (new_result.validate_state == VALIDATE_STATE_VALID) { log_cuda_result(new_result, canonical.granted_credit); } retval = 0; return_retval: return(retval); } //------------------------------------------------------------ void check_overflow_result(RESULT& r) { //------------------------------------------------------------ int result_flags=0; if (strstr(r.stderr_out, "result_overflow")) { r.runtime_outlier = true; result_flags = (long)r.opaque; result_flags |= RESULT_FLAG_OVERFLOW; r.opaque = (double)result_flags; log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, "[RESULT#%ld] is an OVERFLOW result\n", r.id); } } //------------------------------------------------------------ int log_cuda_result(RESULT& result, double& granted_credit) { //------------------------------------------------------------ const char * cuda_str = "SETI@home using CUDA accelerated device "; time_t log_time; int i, retval; char stderr_txt[1024]; char log_path[256]; char device_str[256]; char * p; static FILE * log_fp=NULL; device_str[0] = '\0'; get_log_path(log_path, "cuda_result_log"); if (!log_fp) { log_fp = fopen(log_path, "a"); if (!log_fp) { log_messages.printf( SCHED_MSG_LOG::MSG_CRITICAL, "[RESULT#%ld] cannot open cuda_result_log\n", result.id ); exit(1); } else { setbuf(log_fp, NULL); } } //get stderr_txt and determine cuda status p = strstr(result.stderr_out, cuda_str); if (p == NULL) { log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[RESULT#%ld] is not a cuda result\n", result.id ); return(0); // not a cuda result - nothing more to do } else { log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[RESULT#%ld] is a cuda result\n", result.id ); return(1); // is a cuda result - hack - we will remove this entire routine later } // pull out device string and replace spaces with underscores p += strlen(cuda_str); for (i=0; p[i] != '\n' && p[i] != '\0'; i++) { device_str[i] = p[i]; } device_str[i] = '\0'; for (i=0; device_str[i] != '\0'; i++) { if (device_str[i] == ' ') { device_str[i] = '_'; } } log_time = time(NULL); retval = fprintf(log_fp, "%ld %ld %ld %ld %ld %ld %lf %lf %s\n", log_time, (time_t)result.received_time, result.id, result.hostid, result.userid, result.teamid, result.claimed_credit, granted_credit, device_str); if (retval < 0) { log_messages.printf( SCHED_MSG_LOG::MSG_CRITICAL, "[RESULT#%ld] cannot write to cuda_result_log : %s\n", result.id,strerror(errno) ); } return(1); // this was a cuda result } //------------------------------------------------------------ bool is_cuda(RESULT result) { //------------------------------------------------------------ bool retval=false; const char * cuda_str = "SETI@home using CUDA accelerated device "; if (strstr(result.stderr_out, cuda_str)) { return(true); } else { return(false); } } //------------------------------------------------------------ int handle_cuda_notvalid(RESULT& result_1, RESULT& result_2) { //------------------------------------------------------------ int retval=0; bool result_1_is_cuda, result_2_is_cuda; char result_1_cuda_str[16]; char result_2_cuda_str[16]; result_1_is_cuda = is_cuda(result_1); result_2_is_cuda = is_cuda(result_2); if (result_1_is_cuda ^ result_2_is_cuda) { if (result_1_is_cuda) { strcpy(result_1_cuda_str, "cuda"); } else { strcpy(result_1_cuda_str, "noncuda"); } if (result_2_is_cuda) { strcpy(result_2_cuda_str, "cuda"); } else { strcpy(result_2_cuda_str, "noncuda"); } log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "[%s RESULT#%ld and %s RESULT#%ld] do not covalidate\n", result_1_cuda_str, result_1.id, result_2_cuda_str, result_2.id ); // insert additonal "cuda vs noncuda not valid" code here retval = 1; } return(retval); } #if 0 // test program: // sah_validate file1 ... filen // int main(int argc, char** argv) { vector results; double credit, test_credit=5.5; int i, canonical, retval; RESULT r; memset(&validate_stats, 0, sizeof(validate_stats)); for (i=1; i\n" " %s\n" "\n", argv[i] ); results.push_back(r); } retval = check_set(results, canonical, credit); if (retval) { printf("error: %d\n", retval); } for (i=0; i < results.size(); i++) { printf("validate_state of %s is %d\n", argv[i+1], results[i].validate_state); } if (canonical) { printf("canonical result is %d; credit is %f\n", canonical, credit); } else { printf("no canonical result found\n"); } validate_stats.print(); } #endif boinc-app-seti_8.00~svn3701.orig/validate/sah_boinc_db.cpp0000644000175000017500000000326011403247360023402 0ustar locutuslocutus// stuff that refers to the BOINC DB. // Separate to avoid name conflicts w/ SETI@home DB #include #include #include "parse.h" #include "error_numbers.h" #include "sah_boinc_db.h" #include "sched_config.h" #include "sched_util.h" #include "util.h" #include "validate_util.h" #include "filesys.h" #include "sched_msgs.h" extern SCHED_CONFIG config; int get_result_file(RESULT& r, SAH_RESULT& s) { int retval; FILE * f; char filename[256]; char * path; std::string path_str; // Obtain and check the full path to the boinc result file. retval = get_output_file_path(r, path_str); if (retval) { if (retval == ERR_XML_PARSE) { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "[%s] Cannot extract filename from canonical result %ld.\n", r.name, r.id); return(retval); } else { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "[%s] unknown error from get_output_file_path() fpr result %ld.\n", r.name, r.id); return(retval); } } else { path = (char *)path_str.c_str(); if (!boinc_file_exists(path)) { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, "[%s] Output file %s does not exist for result %ld\n", r.name, path, r.id); return(-1); } } retval = try_fopen(path, f, "r"); if (retval) return retval; s.have_result = true; // we had good read of the result file s.parse_file(f); fclose(f); return 0; } boinc-app-seti_8.00~svn3701.orig/splitter_pfb/0000755000175000017500000000000013155506303021210 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/splitter_pfb/mb_message.cpp0000644000175000017500000000351312111742220024007 0ustar locutuslocutus/* * 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 #include #include #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 * */ boinc-app-seti_8.00~svn3701.orig/splitter_pfb/splitparms.h0000644000175000017500000000604412606025621023562 0ustar locutuslocutus/* 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 #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) /* 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 * */ boinc-app-seti_8.00~svn3701.orig/splitter_pfb/tools/0000755000175000017500000000000013155506302022347 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/splitter_pfb/tools/disksplitter0000755000175000017500000001055312111742220025012 0ustar locutuslocutus#! /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/informix/bin:/usr/local/tex # 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@ssl.berkeley.edu mattl@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 boinc-app-seti_8.00~svn3701.orig/splitter_pfb/tools/sah_splitter.sh0000755000175000017500000001141112111742220025375 0ustar locutuslocutus#! /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/bin:/usr/local/tex 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@ssl.berkeley.edu jeffc@ssl.berkeley.edu mattl@ssl.berkeley.edu davea@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 boinc-app-seti_8.00~svn3701.orig/splitter_pfb/splittypes.h0000644000175000017500000000520712111742220023574 0ustar locutuslocutus/* 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 #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 * */ boinc-app-seti_8.00~svn3701.orig/splitter_pfb/mb_splitter.cpp0000644000175000017500000010643513154564173024261 0ustar locutuslocutus/* * * 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 #include #include #include #include #include #include #include #include #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_read_blocks_dr2.h" #include "mb_read_blocks_guppi.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(); } // Global Variables --------------------------------------------------- char trigger_file_path[1024]="/disks/setifiler1/wutape/tapedir/splitter_stop"; APP_CONFIG sah_config; SCHED_CONFIG boinc_config; DB_APP app; R_RSA_PRIVATE_KEY key; // configuration tables receiver_config rcvr; settings splitter_settings; int root_analysis_cfg_id; // 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= "\n" " 0\n" "\n" "\n" " \n" " 0\n" " work_unit.sah\n" " \n" "\n"; const char *result_template_filename_id = "result_0.xml"; const char *result_template= "\n" " \n" " \n" " \n" " 65536\n" " http://setiboincdata.ssl.berkeley.edu/sah_cgi/file_upload_handler\n" "\n" "\n" " \n" " \n" " result.sah\n" " \n" "\n"; // END TEMPLATE DEFS -------------------------------------------------- std::vector tapebuffer; std::map coord_history; std::vector 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 = 0; int gbt = 0; int parkes = 0; int channel; int raw_bit_depth = 0; // bit depth of raw data (required for guppi data). A depth of N means N real, N imag int samples_per_byte; // real samples/byte int dumpsubband = -1; // default to not dumping int dumpraw = 0; // default to not dumping enum file_types {dr2, guppi}; enum guppi_types {guppi_gbt, guppi_parkes}; 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; //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]; // End Global Variables --------------------------------------------------- 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 *gbt, int *parkes, int *channel, int *raw_bit_depth, int *dumpsubband, int *dumpraw, int *useanalysiscfgid, int *usereceivercfgid, int *userecordercfgid, int *usesplittercfgid) { //------------------------------------------------------------------------- int nargs=0,i; char *ep; strcpy(appname,SAH_APP_NAME); for (i=1;i6)) || ((*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],"-gbt",MAX(ep-argv[i],3))) { sscanf(ep+1,"%d,%d",channel,pol); if (*pol<0 || *pol>1) { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"GBT receivers must be specified with a channel and polarization (0-1), i.e. -gbt=0,1\n"); exit(EXIT_FAILURE); } *gbt=1; } else if (!strncmp(argv[i],"-parkes",MAX(ep-argv[i],6))) { sscanf(ep+1,"%d,%d",channel,pol); if (*pol<0 || *pol>1) { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Parkes receivers must be specified with a channel and polarization (0-1), i.e. -parkes=0,1\n"); exit(EXIT_FAILURE); } *parkes=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],"-dumpsubband",MAX(ep-argv[i],2))) { sscanf(ep+1,"%d",dumpsubband); } else if (!strncmp(argv[i],"-rawbitdepth",MAX(ep-argv[i],2))) { sscanf(ep+1,"%d",raw_bit_depth); samples_per_byte = 8/(*raw_bit_depth); } 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); if (*gbt && !*raw_bit_depth) { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"GBT data requires a bit depth : -rawbitdepth=n\n"); exit(EXIT_FAILURE); } if (*parkes && !*raw_bit_depth) { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Parkes data requires a bit depth : -rawbitdepth=n\n"); exit(EXIT_FAILURE); } return 0; } //------------------------------------------------------------------------- int open_dbs() { //------------------------------------------------------------------------- FILE *tmpfile; // Will initially open the science DB 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(); } //------------------------------------------------------------------------- int get_config(telescope_id &tel, int file_type, dataheader_t dataheader, int pol) { //------------------------------------------------------------------------- //FILE *tmpfile; char keyfile[1024]; char buf[1024]; float channel_freq = 0; // tel equates to s4_id and this is where we resolve it. Also... // A guppi raw file can be from any one of a number of different receivers. // A guppi raw file is generally of such wide bandwidth that we need to configure // with the individual channel frequency. A given invocation of the splitter // specifies a single channel. if(file_type == guppi) { // GBT std::string frontend_s = dataheader.frontend; tel = frontend_pol_to_receiverid[frontend_pol_t(frontend_s, pol)]; channel_freq = dataheader.sky_freq; } else if(file_type == dr2) { // ALFA tel = channel_to_receiverid[beam_pol_to_channel[bmpol_t(beam,pol)]]; } else { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Invalid file type %d\n", file_type); exit(1); } log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Using receiver config with s4_id = %d\n", tel); // obtain the settings row - we query on app.od and receiver_config // because there are multiple settings per app.id if (usereceivercfgid > 0) { // user requested a specific receiver_config sprintf(buf,"where active=%d and receiver_cfg=%d",app.id,usereceivercfgid); if (!splitter_settings.fetch(std::string(buf))) { // fetch log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Unable to find active settings for app.id = %d\n",app.id); exit(1); } } else { // no user request - use tel to find receiver_config sprintf(buf,"where active=%d and receiver_cfg=(select id from receiver_config where s4_id=%d)",app.id,tel); if (!splitter_settings.fetch(std::string(buf))) { // fetch log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Unable to find active settings for app.id = %d s4_id = %d\n",app.id, tel); exit(1); } } // obtain the receiver config row if (usereceivercfgid > 0) { // user requested a specific receiver config log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Using receiver cfg id: %d (set by user)\n",usereceivercfgid); sprintf(buf,"where id=%d",usereceivercfgid); } else { // no user request - receiver config comes from settings sprintf(buf,"where s4_id=%d",tel); } rcvr.fetch(buf); // fetch if(channel_freq) { // scale FWHM beamwidth by channel_freq (which is in Hz) // then replace receiver center (which is in MHz) with channel freq rcvr.beam_width = rcvr.beam_width * rcvr.center_freq*1e6/channel_freq; rcvr.center_freq = channel_freq/1e6; } splitter_settings.receiver_cfg = rcvr; // copy for WU header inclusion // obtain the recorder config row 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(); // fetch // obtain the splitter config row 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(); // fetch // obtain the root analysis config row 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(); // fetch root_analysis_cfg_id=splitter_settings.analysis_cfg.id; // finally, print all settings 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); } 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(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"); 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; } //------------------------------------------------------------------------- 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]; telescope_id tel = (telescope_id)-1; // -1 = no telescope ID (aka s4_id) yet int good_read; long num_blocks_read; int vflag; int file_type = dr2; // default to dr2 for now int guppi_type = guppi_gbt; // default to guppi_gbt for now int beamchan; /* 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,&gbt,&parkes,&channel,&raw_bit_depth,&dumpsubband, &dumpraw, &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 | -gbt=beam,pol -rawbitdepth=n | -parkes=beam,pol -rawbitdepth=n]\n" "[-analysis_config=id] [-receiver_config=id] [-recorder_config=id] [-splitter_config=id]\n" "[-dumpsubband=subband] [-dumpraw]\n"); exit(EXIT_FAILURE); } if(alfa) file_type = dr2; if(gbt) { file_type = guppi; guppi_type = guppi_gbt; } if(parkes) { file_type = guppi; guppi_type = guppi_parkes; } // 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); } //get_config(tel, file_type); open_dbs(); check_for_halt(); if(file_type == dr2) { 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); } beamchan = 2*beam+pol; find_start_point_dr2(tape_fd, beam, pol, beamchan); } else if(file_type == guppi) { beamchan = 2*channel+pol; } else { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"invalid file type"); exit(1); } atexit(cleanup); getcwd(wd,1024); log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG,"Entering main loop\n" ); // Here is where we read the data that will be processed into WUGs and WUs. // seti_StructureDr2Data() handles both the reading of header and data. // iters will be a positve number if the command line specified a certain // number of iterations. Otherwise, it is initialized to -1 and will thus // always be true. // We always want tapebuffer to be 512 blocks in size upon return from // seti_StructureDr2Data(). If this is not the case then we have hit // EOF or a read error and it time to exit. Otherwise, tapebuffer.size() // will change during the body of this loop in one of two ways: // - valid_run() will erase invalid elements of tapebuffer. // - do_transform() will erase from the start of tapebuffer up to // what is needed for WU overlap. while (iters--) { // check, and maybe wait on, various run conditions fflush(stderr); // TODO why are we fflushing stderr? if (atnight) wait_until_night(); check_for_halt(); check_free_disk_space(); // Make sure we have enough free disk space if (!nodb) wait_for_db_wus_ondisk(); // Wait for ondisk wus in the database to drop below the threshold log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"less than max wus on disk, continuing\n" ); check_for_halt(); fflush(stderr); // End check, and maybe wait on, various run conditions if(file_type == dr2) { good_read = read_blocks_dr2(tape_fd, // raw dr2 input startblock, // long int 512-tapebuffer.size(), // the 512 allows for WU time overlap beam, // data selection for dr2 is beam wise pol, vflag); } else if(file_type == guppi) { // guppi data for a WUG may be spread out over more than one file. File naming // determines the order of files. Thus, we pass a partial file name instead of // an open descriptor. const long int numsamples = 256*1048576; // 256*2**20, ie data for 256 WUs, 2**20 samples each vflag=1; good_read = read_blocks_guppi(tape_device, // file_prefix, raw guppi input startblock, numsamples, channel, // data selection for guppi is channel wise pol, vflag); fprintf(stderr, "goodread = %ld\n", good_read); #if 0 long total_samples; total_samples = 0; for(int buffer_i=0; buffer_i < tapebuffer.size(); buffer_i++) { total_samples += tapebuffer[buffer_i].data.size(); } fprintf(stderr, "back in splitter - total_samples = %ld\n", total_samples); #endif } else { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"invalid file type"); exit(1); } if(!good_read) { break; // drop out of main loop on first bad read } else { if(tel == (telescope_id)-1) { // -1 indicates get_config() not yet called get_config(tel, file_type, tapebuffer[0].header, pol); // do once, assume constant for this input file } if (make_wu_headers(tapebuffer,tel,beamchan,wuheaders)) { int child_pid=-1; 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); } } } // End if(make_wu_headers()) } // End if(good_read) } // End main while() loop // A non-zero iters always means we have reached EOF (or had a read error). 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); } } // End main() /* * $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 * 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 * * */ boinc-app-seti_8.00~svn3701.orig/splitter_pfb/mb_splitter.h0000644000175000017500000000766412645311202023715 0ustar locutuslocutus/* * 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 wuheaders; extern int noencode; extern int dataclass; extern char appname[256]; extern int nodb; extern int resumetape; extern int startblock; extern int raw_bit_depth; extern int samples_per_byte; extern int norewind; extern int output_xml; extern int polyphase; extern std::vector wu_database_id; extern int gregorian; extern char * projectdir; extern char trigger_file_name[1024]; extern receiver_config rcvr; extern settings splitter_settings; extern int root_analysis_cfg_id; extern int dumpsubband; extern int dumpraw; /* Buffer that holds tape data */ extern std::vector tapebuffer; extern std::map 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 * * */ boinc-app-seti_8.00~svn3701.orig/splitter_pfb/mb_read_blocks_dr2.cpp0000644000175000017500000001315712626346004025422 0ustar locutuslocutus#include "boinc_db.h" #include "backend_lib.h" #include "setilib.h" #include "mb_splitter.h" #include "mb_validrun.h" #include "mb_coords.h" //------------------------------------------------------------------------- int read_blocks_dr2(int tape_fd, long startblock, long num_blocks_to_read, int beam, int pol, int vflag) { //------------------------------------------------------------------------- static bool first_time = true; blanking_filter > blanker_filter; int num_blocks_read; int good_read = 0; // assume bad read until proven otherwise if(first_time) { first_time = false; // set up blanking 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 } } //fprintf(stderr, "in read_blocks_dr2 : tapebuffer size is %ld num_blocks_to_read %d\n", (long)tapebuffer.size(), num_blocks_to_read); num_blocks_read = seti_StructureDr2Data(tape_fd, beam, pol, num_blocks_to_read, tapebuffer, blanker_filter); //fprintf(stderr, "in read_blocks_dr2 : tapebuffer size is %ld data is %ld\n", (long)tapebuffer.size(), tapebuffer[0].data.size()); while (num_blocks_read == num_blocks_to_read) { //check for an uninterrupted run if (valid_run(tapebuffer,splitter_settings.receiver_cfg->min_vgc)) { get_coord_history(); #if 0 std::vector::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(); } #endif good_read = 1; break; } else { num_blocks_to_read = 512-tapebuffer.size(); num_blocks_read = seti_StructureDr2Data(tape_fd, beam, pol, num_blocks_to_read, tapebuffer, blanker_filter); } } return(good_read); } //------------------------------------------------------------------------- int find_start_point_dr2(int tape_fd, int beam, int pol, int beamchan) { //------------------------------------------------------------------------- char buf[1024]; // In early tapes there was a bug where the first N blocks would be duplicates // of data from previous files. So we do a preemptive 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"); } // End preemptive fast forward // Optionally fast forward to the point of resumption if (resumetape) { tape thistape; thistape.id=0; readbytes=HeaderSize; //sprintf(buf,"%d",rcvr.s4_id-AO_ALFA_0_0); sprintf(buf,"%d",beamchan); 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); } } } } // End fast forward to the point of resumption return 0; } boinc-app-seti_8.00~svn3701.orig/splitter_pfb/mb_angdist.cpp0000644000175000017500000000341012111742220024010 0ustar locutuslocutus/* * 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 #include #include #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 * * */ boinc-app-seti_8.00~svn3701.orig/splitter_pfb/mb_coords.h0000644000175000017500000000003212610017475023325 0ustar locutuslocutusvoid get_coord_history(); boinc-app-seti_8.00~svn3701.orig/splitter_pfb/mb_read_blocks_guppi.cpp0000644000175000017500000013063113046451442026054 0ustar locutuslocutus#include #include #include #include #include #include #include #include "fitsio.h" #include "psrfits.h" #include "guppi_params.h" #include "fitshead.h" #include "median.h" #include "setimysql.h" #include #include #include "barycenter.h" #include "rawdopplersearch.h" #include "setilib.h" #include "mb_read_blocks_guppi.h" #include "mb_splitter.h" #include "mb_coords.h" //#include "seti_dr2utils.h" /* Guppi channel-frequency mapping */ /* sample at 1600 MSamp for an 800 MHz BW */ /* N = 256 channels with frequency centers at m * fs/N */ /* m = 0,1,2,3,... 255 */ // guppi raw data layout (data portion of a ~psrfits HDU (subintegration)): // // First of 32 frequency channels / subintegration: // Pol0Samp0 Pol0Samp0 Pol1Samp0 Pol1Samp0 ... Pol1Samp255 Pol1Samp255 // real imag real imag real imag // |--------------------------------------------| ----------------------| // byte 0 (2 bit data, quantized from 8 bit) ... byte 255 // time 0 ... time 255 // // The next subintegration will be the same 32 channels, starting with time 256. // Thus, each subintegration is 32*256 = 8192 bytes of data. // #if 0 We read the actual data samples ass pointed to by rawinput.pf.sub.data struct gpu_input { // this is instantiated as rawdata char *file_prefix; struct guppi_params gf; struct psrfits pf; // path to data : rawdata.pf unsigned int filecnt; FILE *fil; int invalid; int curfile; int overlap; /* add this keyword here since it doesn't seem to appear in guppi_params.c */ long int first_file_skip; /* in case there's 8bit data in the header of file 0 */ }; struct guppi_params { /* Packet information for the current block */ long long packetindex; // Index of first packet in raw data block int packetsize; // Size in bytes of data portion of each packet int n_packets; // Total number of packets in current block int n_dropped; // Number of packets dropped in current block }; struct psrfits { char mode; // Read (r) or write (w). struct hdrinfo hdr; struct subint sub; // path to data : rawdata.pf.sub }; struct hdrinfo { char source[24]; // Source name char frontend[24]; // Frontend used long double MJD_epoch; // Starting epoch in MJD double fctr; // Center frequency of the observing band (MHz) double df; // Frequency spacing between the channels (MHz) // in BL data, this is header item CHAN_BW double BW; // Bandwidth of the observing band (MHz) // in BL data, this is header item OBSBW int nbits; // Number of bits per data sample int nchan; // Number of channels int rcvr_polns; // Number of polns provided by the receiver }; struct subint { double tsubint; // Length of subintegration (sec) double offs; // Offset from Start of subint centre (sec) double ra; // RA (J2000) at subint centre (deg) double dec; // Dec (J2000) at subint centre (deg) int bytes_per_subint; // Number of bytes for one row of raw data unsigned char *data; // Ptr to the raw data itself // path to data : rawdata.pf.sub.data }; #endif unsigned long total_samples = 0; unsigned long limit_samples; unsigned long last_num_sample_bytes_read; #define RAW_DATA_HEADER_BUF_SIZE 32768 //#define RAW_DATA_HEADER_BUF_SIZE 8192 // TODO would it help to do less reading/rewinding for each header? typedef struct { // file control... long long int startindx; long long int curindx; long long int chanbytes; // = control_block.indxstep * rawinput.gf.packetsize / (8/raw_bit_depth * rawinput.pf.hdr.nchan); long long int subint_offset; long int currentblock; int indxstep; // = (int) ((rawinput.pf.sub.bytes_per_subint * samples_per_byte) / rawinput.gf.packetsize) - // (int) (rawinput.overlap * rawinput.pf.hdr.nchan * rawinput.pf.hdr.rcvr_polns * // 2 / rawinput.gf.packetsize); int last_block_done; // user prefs... int channel; int polarization; long int startblock; long int numblocks; int vflag; } control_block_t; /* Parse info from buffer into param struct */ extern void guppi_read_obs_params(char *buf, struct guppi_params *g, struct psrfits *p); /* prototypes */ int exists(const char *fname); unsigned long unpack_samples(unsigned char * raw, long int count, int pol, dr2_compact_block_t &this_tapebuffer); //------------------------------------------------------- void print_header(dr2_compact_block_t &this_tapebuffer) { //------------------------------------------------------- fprintf(stderr, "setiheader : Name: %s Frontend: %s Header Size: %d Data Size: %d Channel: %d Polarization: N samplerate %lf sky_freq %ld Data Time: %lf Coordinate Time: %lf RA: %f Dec: %f\n", this_tapebuffer.header.name, this_tapebuffer.header.frontend, this_tapebuffer.header.header_size, this_tapebuffer.header.data_size, this_tapebuffer.header.channel, this_tapebuffer.header.samplerate, this_tapebuffer.header.sky_freq, this_tapebuffer.header.data_time.mjd().uval(), this_tapebuffer.header.coord_time.mjd().uval(), this_tapebuffer.header.ra, this_tapebuffer.header.dec); } //------------------------------------------------------- void populate_header( char *file_prefix, control_block_t &control_block, struct gpu_input &rawinput, dr2_compact_block_t &this_tapebuffer ) { //------------------------------------------------------- #if 0 // orig frequency code: // this assumes that channels are ordered with *descending* frequency // (the higher the channel, the lower the frequency) and that BW // and df are always positive. // TODO - channel ordering should come from a recorder_config field this_tapebuffer.header.sky_freq = (long int) ( (double) 1e6 * ( (rawinput.pf.hdr.fctr + (rawinput.pf.hdr.BW/2)) - ((control_block.channel+0.5) * rawinput.pf.hdr.df) ) ); #endif //#if 0 // new frequency code: // this assumes in the case of *descending* frequency, both BW and df will // be negative, otherwise positive. Ie, this should work in all cases where // the -BW and -df protocol is followed. this_tapebuffer.header.sky_freq = (long int) ( (double) 1e6 * ( (rawinput.pf.hdr.fctr - (rawinput.pf.hdr.BW/2)) + ((control_block.channel+0.5) * rawinput.pf.hdr.df) ) ); //#endif fprintf(stderr, "rawinput.pf.hdr.BW is %f\n", rawinput.pf.hdr.BW); fprintf(stderr, "rawinput.pf.hdr.df is %f\n", rawinput.pf.hdr.df); if(rawinput.pf.hdr.BW < 0) { log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG,"Adjusting for negative BW : rawinput.pf.hdr.BW was %f ... ", rawinput.pf.hdr.BW); rawinput.pf.hdr.BW = fabs(rawinput.pf.hdr.BW); log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG,"is %f ", rawinput.pf.hdr.BW); } if(rawinput.pf.hdr.df < 0) { log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, "Adjusting for negative BW : rawinput.pf.hdr.df was %f ... ", rawinput.pf.hdr.df); rawinput.pf.hdr.df = fabs(rawinput.pf.hdr.df); log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG,"is %f ... ", rawinput.pf.hdr.df); } fprintf(stderr, "rawinput.pf.hdr.BW is %f\n", rawinput.pf.hdr.BW); fprintf(stderr, "rawinput.pf.hdr.df is %f\n", rawinput.pf.hdr.df); /* size of this header */ this_tapebuffer.header.header_size = sizeof(this_tapebuffer.header); /* populate with source name from psrfits header */ strncpy(this_tapebuffer.header.name, basename(file_prefix), sizeof(this_tapebuffer.header.name)); /* populate with frontend name from psrfits header */ strncpy(this_tapebuffer.header.frontend, rawinput.pf.hdr.frontend, sizeof(this_tapebuffer.header.frontend)); /* populate channel and polarization */ this_tapebuffer.header.channel = control_block.channel; // this_tapebuffer.header.polarization = control_block.polarization; // TODO add polarization /* (complex) sample rate in MHz */ this_tapebuffer.header.samplerate = rawinput.pf.hdr.df; /* there is no "dataseq in guppi data. TODO - right? */ //this_tapebuffer.header.dataseq = 0; print_header(this_tapebuffer); } //------------------------------------------------------- int get_params( control_block_t &control_block, struct gpu_input &rawinput, char header_buf[], char filname[] ) { //------------------------------------------------------- long long int chanbytes_overlap = 0; // Read first raw data header if(fread(header_buf, sizeof(char), RAW_DATA_HEADER_BUF_SIZE, rawinput.fil) == RAW_DATA_HEADER_BUF_SIZE){ guppi_read_obs_params(header_buf, &rawinput.gf, &rawinput.pf); // Get to first N bit data header where N != 8... // At regular intervals, as a sanity check, the N bit // data are preceeded by the full 8 bit version of // the same data. We ignore the 8 bit data here. // We ignore this whole check if we have 8 bit data. if(raw_bit_depth != 8 && rawinput.pf.hdr.nbits == 8) { fprintf(stderr, "caught an 8 bit header... moving on to first/next 2 bit header\n"); /* figure out the size of the first subint + header */ rawinput.first_file_skip = rawinput.pf.sub.bytes_per_subint + gethlength(header_buf); /* rewind to the beginning */ fseek(rawinput.fil, -RAW_DATA_HEADER_BUF_SIZE, SEEK_CUR); /* seek past the first subint + header */ fseek(rawinput.fil, rawinput.first_file_skip, SEEK_CUR); /* read the next header */ fread(header_buf, sizeof(char), RAW_DATA_HEADER_BUF_SIZE, rawinput.fil); guppi_read_obs_params(header_buf, &rawinput.gf, &rawinput.pf); fclose(rawinput.fil); } else { // not 8 bit data fclose(rawinput.fil); } // end if(rawinput.pf.hdr.nbits == 8) /* we'll use this header to set the params for the whole observation */ rawinput.fil = NULL; hgeti4(header_buf, "OVERLAP", &rawinput.overlap); fprintf(stderr, " pktindx : %lld\n", rawinput.gf.packetindex); fprintf(stderr, " packetsize : %d\n", rawinput.gf.packetsize); fprintf(stderr, " n_packets : %d\n", rawinput.gf.n_packets); fprintf(stderr, " n_dropped : %d\n",rawinput.gf.n_dropped); fprintf(stderr, " bytes_per_subint : %d\n",rawinput.pf.sub.bytes_per_subint); fprintf(stderr, " overlap : %d\n",rawinput.overlap); fprintf(stderr, " bit depth : %d\n",raw_bit_depth); } else { fprintf(stderr, "couldn't read a header\n"); return 0; } // end fread(buf... if(control_block.vflag>=1) fprintf(stderr, "calculating index step\n"); /* number of packets that we *should* increment by */ //control_block.indxstep = (int) ((rawinput.pf.sub.bytes_per_subint * 4) / rawinput.gf.packetsize) - control_block.indxstep = (int) ((rawinput.pf.sub.bytes_per_subint * samples_per_byte) / rawinput.gf.packetsize) - (int) (rawinput.overlap * rawinput.pf.hdr.nchan * rawinput.pf.hdr.rcvr_polns * 2 / rawinput.gf.packetsize); if(control_block.vflag>=1) { fprintf(stderr, "index step %d bytes_per_subint %d packetsize %d overlap %d nchan %d rcr_polns %d\n", control_block.indxstep, rawinput.pf.sub.bytes_per_subint, rawinput.gf.packetsize, rawinput.overlap, rawinput.pf.hdr.nchan, rawinput.pf.hdr.rcvr_polns); } if (control_block.channel >= rawinput.pf.hdr.nchan) { fprintf(stderr, "control_block.channel %d more than channels in data %d\n", control_block.channel, rawinput.pf.hdr.nchan); return 0; } else { fprintf(stderr, "Numer of channels in file %d\n", rawinput.pf.hdr.nchan); } /* number of non-overlapping bytes in each channel */ /* control_block.indxstep increments by the number of unique packets in each sub-integration */ /* packetsize is computed based on the original 8 bit resolution */ /* divide by 8/raw_bit_depth to get to 2 or 8 bits, nchan to get to number of channels */ // TODO - this needs to change for 8 bit data!! //control_block.chanbytes = control_block.indxstep * rawinput.gf.packetsize / (4 * rawinput.pf.hdr.nchan); control_block.chanbytes = control_block.indxstep * rawinput.gf.packetsize / (8/raw_bit_depth * rawinput.pf.hdr.nchan); fprintf(stderr, "chan bytes %lld\n", control_block.chanbytes); /* total number of bytes per channel, including overlap */ chanbytes_overlap = rawinput.pf.sub.bytes_per_subint / rawinput.pf.hdr.nchan; /* memory offset for our chosen channel within a subint */ control_block.subint_offset = control_block.channel * chanbytes_overlap; if(control_block.vflag>=1) fprintf(stderr, "Index step: %d\n", control_block.indxstep); if(control_block.vflag>=1) fprintf(stderr, "bytes per subint %d\n",rawinput.pf.sub.bytes_per_subint ); } //------------------------------------------------------- int read_block( control_block_t &control_block, struct gpu_input &rawinput, char header_buf[], char filname[], double &start_data_time, double &end_data_time, long int filecnt, dr2_compact_block_t &this_tapebuffer ) { //------------------------------------------------------- size_t rv=0; int retval=0; //long int j=0; if(!rawinput.invalid){ if(rawinput.fil == NULL) { /* no file is open for this band, try to open one */ sprintf(filname, "%s.%04d.raw",rawinput.file_prefix,rawinput.curfile); if(exists(filname)){ fprintf(stderr, "Opening %s\n", filname); rawinput.fil = fopen(filname, "rb"); if(rawinput.curfile == 0 && rawinput.first_file_skip != 0) fseek(rawinput.fil, rawinput.first_file_skip, SEEK_CUR); } else { rawinput.invalid = 1; fprintf(stderr, "couldn't open any more files!\n"); } } // end if(rawinput.fil == NULL) if(rawinput.fil){ fprintf(stderr, "Reading %ld bytes - more than enough to obtain first/next header (we'll rewind)\n", RAW_DATA_HEADER_BUF_SIZE); if(fread(header_buf, sizeof(char), RAW_DATA_HEADER_BUF_SIZE, rawinput.fil) == RAW_DATA_HEADER_BUF_SIZE) { //fprintf(stderr, "...success!\n"); fseek(rawinput.fil, -RAW_DATA_HEADER_BUF_SIZE, SEEK_CUR); // rewind for (header plus) data read if(control_block.vflag>=1) fprintf(stderr, "header length: %d\n", gethlength(header_buf)); // parse the header we just read guppi_read_obs_params(header_buf, &rawinput.gf, &rawinput.pf); // get our current block number control_block.currentblock = (long int) ((double) rawinput.gf.packetindex/ (double) control_block.indxstep); if(control_block.vflag>=1) { fprintf(stderr, "pktindx %Ld packetsize: %d n_packets %d n_dropped: %d blocks: %ld RA: %f DEC: %f subintoffset %f tsubint %f MJD %Lf\n", rawinput.gf.packetindex, rawinput.gf.packetsize, rawinput.gf.n_packets, rawinput.gf.n_dropped, control_block.currentblock, rawinput.pf.sub.ra, rawinput.pf.sub.dec, rawinput.pf.sub.offs, rawinput.pf.sub.tsubint, rawinput.pf.hdr.MJD_epoch); } /* populate the variables that change with each block */ /* RA (J2000) at subint centre (deg), Dec (J2000) at subint centre (deg), time in MJD */ this_tapebuffer.header.dataseq = control_block.currentblock; this_tapebuffer.header.ra = rawinput.pf.sub.ra/15.0; // splitter expects RA in decimal hours this_tapebuffer.header.dec = rawinput.pf.sub.dec; /* increment time for data by 0.5 x length of block to push quoted time to the _last_ sample in the block */ double data_mjd = rawinput.pf.hdr.MJD_epoch + ((rawinput.pf.sub.offs + rawinput.pf.sub.tsubint/2)/86400.0); double coord_mjd = rawinput.pf.hdr.MJD_epoch + (rawinput.pf.sub.offs/86400.0); this_tapebuffer.header.data_time = seti_time(days(data_mjd),MJD0); this_tapebuffer.header.coord_time = seti_time(days(coord_mjd),MJD0); if(control_block.currentblock == 1) { start_data_time = this_tapebuffer.header.data_time.mjd().uval(); } else { end_data_time = this_tapebuffer.header.data_time.mjd().uval(); // assigned many times, will end up with the final block's time } if(rawinput.gf.packetindex == control_block.curindx) { // file integrity check - are we at the correct index? Yes... long seek_len; long hlength = (long)gethlength(header_buf); if(rawinput.pf.hdr.directio) { seek_len = hlength + (512 - (hlength%512))%512; // directio aligns on 512 byte boundaries fprintf(stderr, "adjusting for directio (%d) : %ld becomes %ld\n", rawinput.pf.hdr.directio, hlength, seek_len); } else { seek_len = hlength; // not directio so no forced alignment fprintf(stderr, "NOT adjusting for directio (%d) : %ld becomes %ld\n", rawinput.pf.hdr.directio, hlength, seek_len); } fseek(rawinput.fil, seek_len, SEEK_CUR); // skip past header rv=0; if (control_block.currentblock > (control_block.startblock-1)){ // if we have reached user requested startblock (default 0) // read raw data. bytes_per_subint should == BLOCSIZE value from header rv=fread(rawinput.pf.sub.data, sizeof(char), rawinput.pf.sub.bytes_per_subint, rawinput.fil); if( ((long int)rv == rawinput.pf.sub.bytes_per_subint) ){ // if we got the expected amount of raw data long filepos = ftell(rawinput.fil); if(control_block.vflag>=1) { fprintf(stderr,"read %d bytes starting at filepos %ld in file %ld of %d ... chanbytes is %d\n", rawinput.pf.sub.bytes_per_subint, filepos, rawinput.curfile, filecnt, control_block.chanbytes); } // wrap unpacking samples in restart logic. We skip the unpack (but do everything else) if we are not // to the point of resumption. if(control_block.currentblock >= control_block.last_block_done) { //if(control_block.vflag>=1) fprintf(stderr, "prior to unpack_samples : last : %ld total : %ld\n", // last_num_sample_bytes_read, total_samples); last_num_sample_bytes_read = unpack_samples(rawinput.pf.sub.data + // start of raw data, ie channel 0 control_block.subint_offset, // this gets us to the requested channel control_block.chanbytes, // chanbytes does not include overlap control_block.polarization, this_tapebuffer); // unpack samples to the return vector if(control_block.vflag>=1) fprintf(stderr, "Just unpacked %ld sample bytes from %ld chanbytes. Total samples : %ld\n", last_num_sample_bytes_read, control_block.chanbytes, total_samples); } else { log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG,"Not to point of resumption (%ld < %ld), skipping...\n", control_block.currentblock, control_block.last_block_done); } // end of unpack with restart logic } else { rawinput.fil = NULL; rawinput.invalid = 1; fprintf(stderr,"ERR: couldn't read as much as the header said we could... assuming corruption and exiting...\n"); exit(1); } // end if we got the expected amount of raw data } else { // we have not reached the requested startblock (rv = fseek(rawinput.fil, rawinput.pf.sub.bytes_per_subint, SEEK_CUR)); // ... so seek to the next block } // end if we have reached user requested startblock } else if( (rawinput.gf.packetindex > control_block.curindx) && (control_block.currentblock > (control_block.startblock-1)) ) { // are we at the correct index? No, we apparently dropped a subintegration. This is correctable... fprintf(stderr,"ERR: control_block.curindx: %Ld, pktindx: %Ld Did we drop a whole subintegration? Reusing last subint...\n", control_block.curindx, rawinput.gf.packetindex ); /* read a subint with too high an indx, must have dropped a whole subintegration*/ /* pf.sub.data *should* still contain the last valid subint */ /* grab a copy of the last subint - probably should add gaussian noise here, but this is better than nothing! */ /* we'll keep the ra/dec values from this subint, but push back the time to keep everything sensible */ data_mjd = rawinput.pf.hdr.MJD_epoch + ((rawinput.pf.sub.offs - rawinput.pf.sub.tsubint/2)/86400.0) ; this_tapebuffer.header.data_time = seti_time(days(data_mjd),MJD0); // TODO keep the following demo buffer code to remind me what to do here // header to return buffer //memcpy((*setibuffer) + control_block.setibuffer_pos, // &setiheader, // sizeof(setiheader)); //control_block.setibuffer_pos += sizeof(setiheader); // data to return buffer //memmove((*setibuffer) + control_block.setibuffer_pos, // (*setibuffer) + control_block.setibuffer_pos - sizeof(setiheader) - control_block.chanbytes, // (control_block.chanbytes * 2 * sizeof(unsigned char))); //control_block.setibuffer_pos += (control_block.chanbytes * 2 * sizeof(unsigned char)); /* We'll get the current valid subintegration again on the next time through this loop */ } else if(rawinput.gf.packetindex < control_block.curindx) { // are we at the correct index? No, nor have we dropped a subintegration. This is a file integrity fatal error... fprintf(stderr,"Error expecting a higher packet index than we got control_block.curindx: %Ld, pktindx: %Ld\n", control_block.curindx, rawinput.gf.packetindex ); /* somehow we were expecting a higher packet index than we got !?!? */ fprintf(stderr, "assuming corruption and exiting...\n"); exit(1); } // end are we at the correct index if(control_block.vflag>=1) fprintf(stderr, "Read block %ld\n", control_block.currentblock); //if(control_block.vflag>=1) print_header(this_tapebuffer); retval = true; } else { fprintf(stderr, "Could not read first/next 32KB\n"); fclose(rawinput.fil); rawinput.fil = NULL; rawinput.curfile++; retval = false; } // end if((fread(buf...) } // end if(rawinput.fil) } // end if(!rawinput.invalid) if(rawinput.fil != NULL) { //fprintf(stderr, "index step : %d\n", control_block.indxstep); control_block.curindx = control_block.curindx + control_block.indxstep; retval = 1; // we have a new block, which may be empty if we are fast forwarding to the point of resumption } else { retval = 0; // we do not have a new block. Perhaps we just need to open the next file in the series. } //if(control_block.vflag>=1) fprintf(stderr, "last_num_sample_bytes_read %ld chanbytes %ld\n", last_num_sample_bytes_read, control_block.chanbytes); return(retval); } //------------------------------------------------------- int init( char * file_prefix, long int startblock, int channel, int polarization, int vflag, control_block_t &control_block, struct gpu_input &rawinput, char header_buf[], char filname[], double &start_data_time, double &end_data_time, int &filecnt, dr2_compact_block_t &this_tapebuffer ) { //------------------------------------------------------- rawinput.file_prefix =file_prefix; rawinput.fil = NULL; rawinput.invalid = 0; rawinput.first_file_skip = 0; //control_block.check_last = 1; control_block.chanbytes = 0; control_block.subint_offset = 0; control_block.currentblock = 0; control_block.indxstep = 0; control_block.channel = channel; control_block.polarization = polarization; //control_block.numblocks = numblocks; control_block.startblock = startblock; control_block.vflag = vflag; if(rawinput.file_prefix == NULL) { printf("ERR no input stem specified, exiting...\n"); exit(1); } if(strstr(rawinput.file_prefix, ".0000.raw") != NULL) memset(rawinput.file_prefix + strlen(rawinput.file_prefix) - 9, 0x0, 9); // get size of data set, in terms of file count and byte count fprintf(stderr, "Finding size of data set...\n"); //j = 0; struct stat st; long int size=0; long int i=0; do { sprintf(filname, "%s.%04ld.raw",rawinput.file_prefix,i); fprintf(stderr, " trying %s ...",filname); i++; if(exists(filname)) { fprintf(stderr, " found\n"); stat(filname, &st); size = size + st.st_size; } else { fprintf(stderr, " not found\n"); } } while (exists(filname)); rawinput.filecnt = i-1; fprintf(stderr, " File count is %i Total data set size is %ld bytes\n",rawinput.filecnt, size); /* didn't find any files */ if(rawinput.filecnt < 1) { fprintf(stderr, "no files for stem %s found, exiting...\n",rawinput.file_prefix); exit(1); } /* open the first file for input */ sprintf(filname, "%s.0000.raw", rawinput.file_prefix); fprintf(stderr, "Opening %s\n", filname); rawinput.fil = fopen(filname, "rb"); if(!rawinput.fil){ fprintf(stderr, "couldn't open first file\n"); return 0; } get_params( control_block, rawinput, header_buf, filname ); // Now that we know our sizing requirements, allocate the buffers... // TODO - we should explicitly free this memory even though we allocate // once and need it until program exit. rawinput.pf.sub.data = (unsigned char *) malloc(rawinput.pf.sub.bytes_per_subint); if(!rawinput.pf.sub.data) { fprintf(stderr, "error: couldn't allocate memory for the raw data read buffer\n"); return 0; } else { fprintf(stderr, "malloc'ed %ld bytes at %p for the raw data read buffer!\n", rawinput.pf.sub.bytes_per_subint, rawinput.pf.sub.data); } // populate the header with static items populate_header( rawinput.file_prefix, control_block, rawinput, this_tapebuffer ); control_block.startindx = rawinput.gf.packetindex; control_block.curindx = control_block.startindx; filecnt = rawinput.filecnt; rawinput.curfile = 0; return 1; // success } //------------------------------------------------------- void dump_tapebuffer(char * file_prefix, int channel) { //------------------------------------------------------- FILE * dump_fp; char dump_fn[256]; sprintf(dump_fn, "%s%s%d", basename(file_prefix), ".tapebuffer_dump.channel_", channel); dump_fp = fopen(dump_fn, "w"); if(dump_fp == NULL) { fprintf(stderr, "could not open dump file %s, exiting...", dump_fn); exit(1); } for(int buffer_i=0; buffer_i < tapebuffer.size(); buffer_i++) { fprintf(stderr, "buffer_i %d\n", buffer_i); for(int buffer_j=0; buffer_j < tapebuffer[buffer_i].data.size(); buffer_j++) { //fprintf(stderr, "buffer_i %d buffer_j %ld\n", buffer_i, buffer_j); fwrite((const void *)&tapebuffer[buffer_i].data[buffer_j].real(), 1, 1, dump_fp); fwrite((const void *)&tapebuffer[buffer_i].data[buffer_j].imag(), 1, 1, dump_fp); } } fclose(dump_fp); } //------------------------------------------------------- long int read_blocks_guppi(char * file_prefix, long int startblock, long int numsamples, int channel, int polarization, int vflag ) { //------------------------------------------------------- // Note : a buffer is push_back()'ed to tapebuffer under two conditions: // 1) at the end of processing a guppi block. This is by far the most // common push_back() and will result in a tapebuffer of a standard // length for a given file format until we reach the desired number // of samples per call. The final buffer will likely be a partial // buffer. // 2) Upon re-entry into read_blocks_guppi() for consecutive WUGs, we // push_back() a buffer with the left-over samples in the prior guppi // block. This will be a partial buffer. The number of samples in // this buffer plus the number of samples in the final (partial) buffer // of the prior call should be the standard length. int retval = 0; static bool first_time = true; char header_buf[RAW_DATA_HEADER_BUF_SIZE]; // we read the raw data headers into this buffer long reent_total_samples = 0; static unsigned long sample_bytes_left; static double start_data_time; static double end_data_time; static int filecnt; static char filname[250]; static dr2_compact_block_t this_tapebuffer; static struct gpu_input rawinput; static control_block_t control_block; limit_samples = numsamples; // TODO - this should go into the control block total_samples = 0; if(first_time) { first_time = false; retval = init( file_prefix, startblock, channel, polarization, vflag, control_block, rawinput, header_buf, filname, start_data_time, end_data_time, filecnt, this_tapebuffer ); if(retval == 0) return(0); if (resumetape) { char * filename = basename(rawinput.file_prefix); tape thistape; thistape.id=0; char beambuf[16]; sprintf(beambuf,"%d", 2*channel+polarization); if (thistape.fetch(std::string("where name=\'")+filename+"\' and beam="+beambuf)) { control_block.last_block_done = thistape.last_block_done; log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, "Resuming tape %s channel %d pol %d at block %d\n", thistape.name,channel,polarization,control_block.last_block_done); } else { log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, "Cannot resume : tape %s channel %d pol %d beam %s not found. Starting at the beginning.\n", filename,channel,polarization, beambuf); //return(0); } } // end if(resumetape) } else { // not first time - on subsequent calls we need to account for splitter (not guppi) overlap reent_total_samples = 0; for(int buffer_i=0; buffer_i < tapebuffer.size(); buffer_i++) { reent_total_samples += tapebuffer[buffer_i].data.size(); if(control_block.vflag>=2) { fprintf(stderr, "re-entry (start) - tapebuffer %d has %ld samples\n", buffer_i, tapebuffer[buffer_i].data.size()); } } total_samples = reent_total_samples; // starting this call with thais many samples : if(control_block.vflag>=2) { fprintf(stderr, "re-entry (start) - total_samples = %ld (%ld) in %ld tapebuffers\n", reent_total_samples, total_samples, tapebuffer.size()); } } // end first/subsequent time logic // take care of any samples left over in the guppi buffer if(sample_bytes_left) { if(control_block.vflag>=1) fprintf(stderr, "first getting the %ld sample_bytes_left starting at location %p\n", sample_bytes_left, rawinput.pf.sub.data + control_block.subint_offset + control_block.chanbytes - sample_bytes_left); last_num_sample_bytes_read = unpack_samples(rawinput.pf.sub.data + control_block.subint_offset + control_block.chanbytes - sample_bytes_left, sample_bytes_left, // samples left does not include overlap control_block.polarization, this_tapebuffer); // unpack samples to the return vector tapebuffer.push_back(this_tapebuffer); // this will be a partially full buffer this_tapebuffer.data.clear(); sample_bytes_left = 0; if(control_block.vflag>=2) { long reent_total_samples = 0; for(int buffer_i=0; buffer_i < tapebuffer.size(); buffer_i++) { reent_total_samples += tapebuffer[buffer_i].data.size(); fprintf(stderr, "re-entry (after adding leftover) tapebuffer %d has %ld samples\n", buffer_i, tapebuffer[buffer_i].data.size()); } fprintf(stderr, "re-entry (after adding leftover) - total_samples = %ld (%ld) in %ld tapebuffers\n", reent_total_samples, total_samples, tapebuffer.size()); } } // end take care of any samples left over in the guppi buffer // read blocks until we run out of data or the numblocks request is met int round = 0; do{ //if(control_block.vflag>=1) fprintf(stderr, "ROUND %d ========================================================\n", round); log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG,"ROUND %d ========================================================\n", round); // retval = 1 : we have a new block, which may be empty if we are fast forwarding to the point of resumption // retval = 0 : we do not have a new block. // rawinput.invalid = 1 : we are out of raw data or have detected corruption // rawinput.invalid = 0 : good to continue with current file or open the next file in the series. retval = read_block( control_block, rawinput, header_buf, filname, start_data_time, end_data_time, filecnt, this_tapebuffer ); if(retval && this_tapebuffer.data.size() > 0) { // if retval (OK) and no data, assume fast forward resumption this_tapebuffer.header.data_size = last_num_sample_bytes_read; tapebuffer.push_back(this_tapebuffer); if(control_block.vflag>=1) print_header(this_tapebuffer); round++; this_tapebuffer.data.clear(); } if(control_block.vflag>=2) { reent_total_samples = 0; } } while((!(rawinput.invalid)) && total_samples < limit_samples); fprintf(stderr, "========================================================\n"); // end read blocks until we run out of data or the numblocks request is met sample_bytes_left = control_block.chanbytes - last_num_sample_bytes_read; // set up for next call // optionally dump a full tapebuffer if(dumpraw) dump_tapebuffer(file_prefix, channel); if(control_block.vflag>=1) { fprintf(stderr, "NUM SAMPLES total %ld final buffer contains %ld of a possible %d leaving %ld for the next time through\n", total_samples, last_num_sample_bytes_read, control_block.chanbytes, control_block.chanbytes-last_num_sample_bytes_read); } if(control_block.vflag>=2) { reent_total_samples = 0; for(int buffer_i=0; buffer_i < tapebuffer.size(); buffer_i++) { reent_total_samples += tapebuffer[buffer_i].data.size(); fprintf(stderr, "finish tapebuffer %d has %ld samples\n", buffer_i, tapebuffer[buffer_i].data.size()); } fprintf(stderr, "finish - total_samples = %ld (%ld) in %ld tapebuffers\n", reent_total_samples, total_samples, tapebuffer.size()); } fprintf(stderr, "getting coordinate history...\n"); get_coord_history(); fprintf(stderr, "finishing up...\n"); int blocks_read = tapebuffer.size(); if(control_block.vflag>=1) fprintf(stderr, "grabbed %ld samples from %Ld blocks covering %lf seconds of time. Current block is %ld = %d\n", total_samples, blocks_read, (end_data_time-start_data_time)*86400, control_block.currentblock, tapebuffer[tapebuffer.size()-1].header.dataseq); start_data_time = end_data_time; // set up for next call this_tapebuffer.data.clear(); if(total_samples != limit_samples) { return 0; // error or EOF TODO should differentiate } else { return total_samples; } } // end read_blocks_guppi() //------------------------------------------------------- unsigned long unpack_samples_2bit(unsigned char * raw, long int count, int pol, dr2_compact_block_t &this_tapebuffer) { //------------------------------------------------------- // unpack guppi 2 bit complex samples into a vector of complex signed chars. Here we have 1 byte per sample. // pol is polarization (0 for X, 1 for Y) long i; int pol_shift = pol * 2; // pol_shift will be 0 or 2 float quantlookup[4]; const int stride = 1; // number of bytes in each time (real,imag,2pols) std::complex sample; // the * 10 is to keep some of the precision intact as we // go to signed char quantlookup[0] = 3.3358750 * 10; quantlookup[1] = 1.0 * 10; quantlookup[2] = -1.0 * 10; quantlookup[3] = -3.3358750 * 10; // short circuit in the case of getting the total number of samples that we want. // The raw pointer will left where it is for the next time through. for(i=0; i < count && total_samples < limit_samples; i+=stride) { // TODO - for some data sets we may need to flip i and q. Whether or not to do this // should come from a boolean in the recorder_config table. // real (2 bits of raw data) sample.real( (signed char)quantlookup[( raw[i] >> (pol_shift * 2) & 1) + // bit 0 or 4 ((raw[i] >> (pol_shift * 2 + 1) & 1) * 2)] // bit 1 or 5 ); // imag (2 bits of raw data) sample.imag( (signed char)quantlookup[( raw[i] >> ((pol_shift+1) * 2) & 1) + // bit 2 or 6 ((raw[i] >> ((pol_shift+1) * 2 + 1) & 1) * 2)] // bit 3 or 7 ); // add this sample to our vector this_tapebuffer.data.push_back(sample); total_samples++; } //fprintf(stderr, "old count : %ld new count : %ld\n", count, this_tapebuffer.data.size()); //fprintf(stderr, "old data : %d %d new data : %d %d\n", samples[0], samples[1], this_tapebuffer.data[0].real(), this_tapebuffer.data[0].imag()); //fprintf(stderr, "old data : %d %d new data : %d %d\n", samples[2], samples[3], this_tapebuffer.data[1].real(), this_tapebuffer.data[1].imag()); //fprintf(stderr, "old data : %d %d new data : %d %d\n", samples[count*2-2], samples[count*2-1], this_tapebuffer.data[count-1].real(), this_tapebuffer.data[count-1].imag()); //return i/stride; // == i in this case return i; // return the number of bytes (not samples) read } //------------------------------------------------------- unsigned long unpack_samples_8bit(unsigned char * raw, long int count, int pol, dr2_compact_block_t &this_tapebuffer) { //------------------------------------------------------- // unpack 8 bit data. Here we have 4 bytes per sample // pol is polarization (0 for X, 1 for Y) long i; int pol_shift = pol * 2; // pol_shift will be 0 or 2 const int stride = 4; // number of bytes in each time (real,imag,2pols) std::complex sample; for(i=0; i < count && total_samples < limit_samples; i+=stride) { // TODO - for some data sets we may need to flip i and q. Whether or not to do this // should come from a boolean in the recorder_config table. sample.real(raw[i+pol_shift]); sample.imag(raw[i+1+pol_shift]); // add this sample to our vector this_tapebuffer.data.push_back(sample); total_samples++; } //return i/stride; return i; // return the number of bytes (not samples) read } //------------------------------------------------------- unsigned long unpack_samples(unsigned char * raw, long int count, int pol, dr2_compact_block_t &this_tapebuffer) { //------------------------------------------------------- if(raw_bit_depth == 2) { return(unpack_samples_2bit(raw, count, pol, this_tapebuffer)); } else if(raw_bit_depth == 8) { return(unpack_samples_8bit(raw, count, pol, this_tapebuffer)); } else { fprintf(stderr,"ERR: unsupported bit depth, exiting...\n"); exit(1); } } //------------------------------------------------------- int exists(const char *fname) { //------------------------------------------------------- FILE *file; if ((file = fopen(fname, "r"))) { fclose(file); return 1; } return 0; } boinc-app-seti_8.00~svn3701.orig/splitter_pfb/mb_validrun.cpp0000644000175000017500000001165512555541400024226 0ustar locutuslocutus/* * 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 #include #include #include #include "setilib.h" #include "splitparms.h" #include "splittypes.h" #include "mb_splitter.h" #include "message.h" bool valid_run(std::vector &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 0) { for (i=0;valid && (i::iterator i=tapebuffer.begin(); 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(); } } boinc-app-seti_8.00~svn3701.orig/splitter_pfb/mb_read_blocks_dr2.h0000644000175000017500000000044212626346004025060 0ustar locutuslocutusint read_blocks_dr2(int tape_fd, long startblock, long num_blocks_to_read, int beam, int pol, int vflag); int find_start_point_dr2(int tape_fd, int beam, int pol, int beamchan); boinc-app-seti_8.00~svn3701.orig/splitter_pfb/mb_wufiles.h0000644000175000017500000000217312623701607023523 0ustar locutuslocutus/* * * 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 > bin_data; int make_wu_headers(std::vector &tapebuffer, telescope_id tel, int beamchan, std::vector &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 * * */ boinc-app-seti_8.00~svn3701.orig/splitter_pfb/message.cpp0000644000175000017500000000324212111742220023330 0ustar locutuslocutus/* * 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 #include #include #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 * */ boinc-app-seti_8.00~svn3701.orig/splitter_pfb/gencoeff.py0000755000175000017500000001131612111742220023332 0ustar locutuslocutus#!/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 Number of points in FFT" print " -t --taps Number of taps in PFB" print " -b --sub-bands Number of sub-bands in data" print " -w --width-factor width factor for sinc(x) call" print " -d --data-type 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() boinc-app-seti_8.00~svn3701.orig/splitter_pfb/mb_angdist.h0000644000175000017500000000146512111742220023465 0ustar locutuslocutus/* * 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 * * */ boinc-app-seti_8.00~svn3701.orig/splitter_pfb/cmap_interp.cpp0000644000175000017500000000171012111742220024203 0ustar locutuslocutus#include #include #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 &map, seti_time &t) { std::map::iterator above(map.upper_bound(t)); std::map::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; } boinc-app-seti_8.00~svn3701.orig/splitter_pfb/Makefile.am0000644000175000017500000000362613051407443023253 0ustar locutuslocutusCC=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 -larmadillo 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_read_blocks_dr2.cpp \ mb_read_blocks_guppi.cpp \ mb_wufiles.cpp \ mb_dotransform.cpp \ mb_validrun.cpp \ mb_coords.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 -I$(CFITSIO) \ -I$(SETI_GBT)/src mb_splitter_CFLAGS=$(mb_splitter_CXXFLAGS) mb_splitter_LDFLAGS=-static $(AM_LDFLAGS) -L$(HEALPIX)/lib -L$(SETI_GBT)/lib -lsetigbt -lsla -L$(CFITSIO) -lcfitsio $(LINKOPTIONS) mb_splitter_LDADD=$(SPLITLIBS) $(GSL_LIBS) ../db/sqlifx.cpp: ../db/sqlifx.ec $(INFORMIXDIR)/bin/esql -e $< mv sqlifx.c $*.cpp boinc-app-seti_8.00~svn3701.orig/splitter_pfb/mb_dotransform.h0000644000175000017500000000355212651545767024423 0ustar locutuslocutus/* * * 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 bits_per_sample=2); void splitter_bits_to_float(unsigned short *raw, float *data, int nsamples) ; void process_seg(void); void do_transform(std::vector &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 * * */ boinc-app-seti_8.00~svn3701.orig/splitter_pfb/message.h0000644000175000017500000000215512111742220022777 0ustar locutuslocutus/* * 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 * */ boinc-app-seti_8.00~svn3701.orig/splitter_pfb/mb_validrun.h0000644000175000017500000000142412111742220023653 0ustar locutuslocutus/* * 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 &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 * * */ boinc-app-seti_8.00~svn3701.orig/splitter_pfb/mb_wufiles.cpp0000644000175000017500000005620212665410021024051 0ustar locutuslocutus/* * * 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 #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_ERRNO_H #include #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 wu_database_id; std::vector > bin_data; extern APP_CONFIG sah_config; int make_wu_headers(std::vector &tapebuffer, telescope_id tel, int beamchan, std::vector &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(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)&0xff, s.id); // refetch root analysis_config - we need a pristine copy // because per WUG changes are made below splitter_settings.analysis_cfg.id=root_analysis_cfg_id; splitter_settings.analysis_cfg->fetch(); if(splitter_settings.analysis_cfg.id == 0) { log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"refetch of analysis_config failed\n"); exit(1); } 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::iterator above(coord_history.upper_bound(end_time)); std::map::iterator below(coord_history.lower_bound(start_time)); std::map::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 double ncoords=0; for (p=below;p!=above;p++) { wugrp.data_desc.true_angle_range+=angdist(last_coord,p->second); last_coord=p->second; ncoords++; } 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 < 2.4*wugrp.receiver_cfg->beam_width) { 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); // lets have a maximum of 40 coordinate strings double coord_increment=std::max(ncoords*0.025,1.0); double last=0,curr=0; for (p=below;p!=above;/*nothing*/) { wugrp.data_desc.coords.push_back(p->second); curr+=coord_increment; for (int z=round(last);zid=0; sprintf(buf,"%d",beamchan); 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; fprintf(stderr, "last_block_done = %d\n", wugrp.tape_info->last_block_done); wugrp.tape_info->beam=beamchan; 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(); } } else { // nodb strlcpy(wugrp.tape_info->name,tapebuffer[0].header.name,sizeof(wugrp.tape_info->name)); } 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\n"); fprintf(tmpfile,"%s\n",appname); 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->splitter_cfg->wu_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",tmpstr.size(), xml_encoding_names[encoding]); fwrite(tmpstr.c_str(),tmpstr.size(),1,tmpfile); fprintf(tmpfile,"\n"); fprintf(tmpfile,"\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 * * */ boinc-app-seti_8.00~svn3701.orig/splitter_pfb/cmap_interp.h0000644000175000017500000000013512111742220023650 0ustar locutuslocutus extern coordinate_t cmap_interp(std::map &map, seti_time &t); boinc-app-seti_8.00~svn3701.orig/splitter_pfb/mb_polyphase.cpp0000644000175000017500000001104412111742220024365 0ustar locutuslocutus #include "sah_config.h" #include #include #include #include #include #include #include #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 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); } } boinc-app-seti_8.00~svn3701.orig/splitter_pfb/mb_dotransform.cpp0000644000175000017500000004340612665410021024733 0ustar locutuslocutus/* * * 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 #include #include #include #include #include #include #include #include "setilib.h" #include "splitparms.h" #include "splittypes.h" #include "mb_splitter.h" #include "fftw3.h" #include "mb_wufiles.h" #include /* for open() */ #include /* for open() */ #include /* 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* 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* 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; i0); case 2: if (f<-0.98159883*stddev) return 0; if (f<0) return 1; if (f<0.98159883*stddev) return 2; return 3; #if 0 // this won't work for encoding into an unsigned short. case 3: f*=(sqrt(2)/stddev); f+=3.5; if (f>7) return 7; if (f<0) return 0; return static_cast(round(f)); #endif case 4: f*=(2.0/stddev); f+=7.5; if (f>15) return 15; if (f<0) return 0; return static_cast(round(f)); case 8: f*=(24.0/stddev); if (f>127) return 128; if (f<-127) return -127; return static_cast(round(f)); default: fprintf(stderr,"Unsupported bit depth (%d)\n",num_bits); abort(); } } void output_samples(float *data, int i, int bits_per_sample) { // outputs 8 complex samples per call (8 cplx floats -> 8 cplx chars, or 16 floats -> 16 chars) int j,k; unsigned short s; float *p=data; static float stddev[2]={1,1}; // use reasonable guesses to prevent really bad early values static long n=8; // this is our gain control. // maintain a running stddev for the last 256K points from all subbands n=std::min(n,256L*1024-8); stddev[0]*=stddev[0]*n; stddev[1]*=stddev[1]*n; for (j=0;j<8;j++) { stddev[0]+=(data[j*2]*data[j*2]); stddev[1]+=(data[j*2+1]*data[j*2+1]); } n+=8; stddev[0]=sqrt(stddev[0]/n); stddev[1]=sqrt(stddev[1]/n); for (j=0; j<(8*bits_per_sample/(CHAR_BIT*sizeof(unsigned short))); j++) { s=0; for (k=0; k>= bits_per_sample; s |= (quantize(*p,stddev[0],bits_per_sample/2) << (CHAR_BIT*sizeof(unsigned short)-bits_per_sample/2)); s |= (quantize(*(p+1),stddev[1],bits_per_sample/2) << (CHAR_BIT*sizeof(unsigned short)-bits_per_sample)); p+=2; } 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(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( // 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(tapebuffer[iTapeBufferIdx].data[iDataIdx].imag()), static_cast(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; iPFBOutputStackIdxwu_bits_per_sample); // 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 &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*) fftwf_malloc(PFB_FFT_LEN * sizeof(complex)); 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 *) fftwf_malloc(PFB_OUTPUT_STACK_SIZE * PFB_FFT_LEN * sizeof(complex)); 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 * * */ boinc-app-seti_8.00~svn3701.orig/splitter_pfb/tags0000644000175000017500000007607612111742220022100 0ustar locutuslocutus!_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@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 > bin_data;$/;" v bin_data wufiles.cpp /^static std::vector 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 &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 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 &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 &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 > &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 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 &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 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 wuheaders;$/;" v wuheaders splitter.cpp /^workunit wuheaders[NSTRIPS];$/;" v wulog mb_splitter.cpp /^FILE *wulog,*errorlog;$/;" v wulog splitter.cpp /^FILE *wulog,*errorlog;$/;" v boinc-app-seti_8.00~svn3701.orig/splitter_pfb/mb_read_blocks_guppi.h0000644000175000017500000000042012610017475025511 0ustar locutuslocutuslong int read_blocks_guppi(char * file_prefix, long int startblock, long int numblocks, int channel, int polarization, int vflag ); boinc-app-seti_8.00~svn3701.orig/Makefile.am0000644000175000017500000000160512631640074020553 0ustar locutuslocutus# $Id: Makefile.am,v 1.2.2.1 2005/10/26 18:23:03 korpela Exp $ # # AUTOMAKE_OPTIONS = foreign ## make sure rebuilding uses the right aclocal-switches ACLOCAL_AMFLAGS = -I m4 if ENABLE_CLIENT CLIENT_SUBDIRS = client if ENABLE_TESTS CLIENT_SUBDIRS +=tools endif endif if ENABLE_SERVER SERVER_SUBDIRS = splitter_pfb assimilator validate endif if USE_MY_IMAGELIBS IMDIR = image_libs endif if USE_MY_GLUT GLUTDIR = glut endif SUBDIRS = $(JPEGDIR) $(IMDIR) $(GLUTDIR) $(CLIENT_SUBDIRS) $(SERVER_SUBDIRS) dist-hook: rm -rf `find $(distdir) -name .backup -prune -o -name '*~' -o -name CVS` client-bin: cd client && make client-bin client-bin-gz EXTRA_DIST = \ glut \ image_libs \ db \ tools \ client/win_build \ client/test_workunits \ INSTALL boinc-app-seti_8.00~svn3701.orig/Graphics.Readme0000644000175000017500000000074610671336410021401 0ustar locutuslocutusThis document will describe how to install seti with graphics. Make sure that boinc has been installed with graphics enabled. Follow the instructions Makefile.Readme in seti_boinc/client to make sure that Makefile.in.graphics will work with your system. Rename Makefile.in.graphics as Makefile.in. From the seti_boinc/ directory run configure (or ./configure), then make. The executable will then be xseti[version and system info] and your app_info.xml file should reflect that name.boinc-app-seti_8.00~svn3701.orig/CheckResult0000755000175000017500000002110610671336410020655 0ustar locutuslocutus#!/bin/sh # # CheckResult - produce an html page with client test results # # Usage: CheckResult [more outfile.sah files] > check.html # must supply at least one argument, the name of # an outfile.sah to check. More than one file can # be supplied to check. Each file will produce a table # in the resulting html output. Place the output of this # script into a file and read with a browser. # # KNOWN PROBLEM: Some clients output numbers in the form of: # 1.803966e+000 instead of 1.803966e+00 # This will cause a compare error. A work-around on # such platforms is to edit the reference outfile and # change all the +0x to +00x and -0x to -00x # # ASSUMED: outfile.sah_version_2.0 is available here in ./ # # Set the reference file location if different in your setup: Reference="./outfile.sah_version_2.0" # What kind of awk do you need ? I note Solaris needs to use nawk, # and others need to use simply awk. Please set this to what you # need to have for an awk. AWK=nawk # trap signals and exit cleanly trap "CleanExit" 1 2 3 15 ########################################################################### # subroutines ########################################################################### Usage() { echo "Usage: [more outfile.sah files] > check.html" echo "\t - name of outfile.sah to check" echo "\t[more outfile.sah files] - can check more than one" echo "\t reference file is assumed to be:" echo "\t ${Reference}" } ########################################################################### # There are no /tmps file to remove at this time. If some are # developed in the future, clean them up here. # CleanExit() { exit 0 } # caught signal ########################################################################### Header() { cat << _EOF_ SETI@home ${Reference} delta report SETI clients _EOF_ } # Header() ########################################################################### TableStart() { cat << _EOF_
_EOF_ } # TableStart() ########################################################################### TableEnd(){ cat << _EOF_
SETI@home delta report for ${TITLE}
`date` - `date -u`
When OK:
(actual delta) (allowed delta)
When Bad:
(actual measurement) (reference measurement)
power delta peak delta mean delta chisqr delta others ?
_EOF_ } # TableEnd() ########################################################################### Tailer(){ cat << _EOF_
The deltas are computed: <reference value> - <test value>
power delta - the difference between power= on the spike: lines
peak delta - the difference between peak= on the gaussian: lines
mean delta - the difference between mean= on the gaussian: lines
chisqr delta - the difference between chisqr= on the gaussian: lines
others ? - indication if other fields on any line have differences

SETI@home STATS home page
SETI@home home page

This page last updated: `date` - `date -u`
_EOF_ } # Tailer() ########################################################################### ########################################################################### # start of main program # (It might be better to make the reference file be the first # argument ?) if [ ! -f "${Reference}" ]; then { echo "Reference outfile does not exist. Looking for:" echo "\t${Reference}" CleanExit } fi if [ "$#" -lt 1 ]; then { Usage CleanExit } fi Header # start the html file # For each file on the command line, generate a table for Test in $* do TITLE="${Test}" #echo "

Checking file: ${Test}

" echo "
"
if [ ! -f "${Test}" ]; then {
	echo "\nERROR: specified file does not exist:"
	echo "\t${Test}"
} fi

# first, see if there are the same number of lines in the outfiles

TestWC=`cat ${Test} | wc -l`
RefWC=`cat ${Reference} | wc -l`

if [ "${TestWC}" -ne "${RefWC}" ]; then {
	echo "ERROR: the two files do not have the same number of lines"
	echo "'wc ${Test} ${Reference}'"
	wc ${Test} ${Reference}
} fi

echo "
" TableStart # Processing is to read line by line from the reference file and # the test file to check. Parse out all the numbers on # the lines, and compare all numbers. Assuming format # of output as it is currently in version 1.1 -> 1.3 # (this works even with the new v1.10, v2.0 format, although # it is not checking the pow= value) $AWK ' function check_error(reference,measured,tolerance) { diff=reference-measured errbar=reference*tolerance if ( errbar < 0 ) { abserrbar = - errbar } else { abserrbar = errbar } if ( diff < 0 ) { absdiff = - diff } else { absdiff = diff } if ( (absdiff < .0000001) ) { printf "
0.0 (%.3e)
", reference } else if ( (absdiff - abserrbar) > 0 ) { printf " %.6e (!= %.6e) ", measured, reference } else { printf "
%.3e (%.3e)
", absdiff, abserrbar } } function ogh(LineIn) { n=split(LineIn, a, " ") split(a[2], b, "="); ncfft=b[2] split(a[3], b, "="); cr=b[2] split(a[4], b, "="); fl=b[2] } function spike(LineIn) { n=split(LineIn, a, " ") split(a[2], b, "="); power=b[2] split(a[3], b, "="); ra=b[2] dec=a[5] time=a[7] split(a[8], b, "="); freq=b[2] split(a[9], b, "="); fft_len=b[2] split(a[10], b, "="); chirp_rate=b[2] } function gaussian(LineIn) { n=split(LineIn, a, " ") split(a[2], b, "="); peak=b[2] split(a[3], b, "="); mean=b[2] split(a[4], b, "="); ra=b[2] dec=a[6] time=a[8] split(a[9], b, "="); freq=b[2] split(a[10], b, "="); sigma=b[2] split(a[11], b, "="); chisqr=b[2] split(a[12], b, "="); fft_len=b[2] split(a[13], b, "="); chirprate=b[2] } BEGIN { Fname0="'${Reference}'" Fname1="'${Test}'" while ( (getline LineIn < Fname0) > 0 ) { if ( match(LineIn, "^ end of file on %s\n", Fname1 } else { if ( match(LineIn, "^ yes \n" } } else if ( match(LineIn, "^ yes \n" } } else if ( match(LineIn, "^spike:") ) { spike(LineIn) power1=power; ra1=ra; dec1=dec; time1=time; freq1=freq; fft_len1=fft_len; chirp_rate1=chirp_rate; printf " " check_error(power0, power1, .001) printf "" if ( (ra1 != ra0) || (dec1 != dec0) || (time1 != time0) || (freq1 != freq0) || (fft_len1 != fft_len0) ) { printf" yes \n" } else { printf "\n" } } else if ( match(LineIn, "^gaussian:") ) { gaussian(LineIn) peak1=peak; mean1=mean; gra1=ra; gdec1=dec; gtime1=time; gfreq1=freq; sigma1=sigma; chisqr1=chisqr; fft_len1=fft_len; chirprate1=chirprate; printf "" check_error(peak0, peak1, .001) check_error(mean0, mean1, .001) check_error(chisqr0, chisqr1, .001) printf "\n" if ( (gra1 != gra0) || (gdec1 != gdec0) || (gtime1 != gtime0) || (gfreq1 != gfreq0) || (sigma1 != sigma0) || (fft_len1 != fft_len0) || (chirprate1 != chirprate0) ) { printf" \n" } else { printf "\n" } } } } close Fname0 close Fname1 } ' TableEnd done Tailer # Finished with the html file CleanExit boinc-app-seti_8.00~svn3701.orig/README0000644000175000017500000000374511531041245017377 0ustar locutuslocutussetiathome(1) User Commands Version 6.90 - Feb 2011 NAME seti_boinc - the SETI@home client program SYNOPSIS seti_boinc [options] DESCRIPTION seti_boinc is the boinc version of the SETI@home client. It runs under the BOINC client which downloads radio telescope data from a network server, analyzes the data looking for signals of extraterrestrial origin, and uploads results to the server, repeating this cycle indefinitely. See http://setiathome.berkeley.edu for more information. FILES In order to use seti_boinc to analyze data from the seti@home project you must first download the BOINC client software which is avalable through the setiathome web page http://setiathome.berkeley.edu/ If used on a supported host platform, the BOINC client will automatically download the most recent versions of the seti@home client software. If you are compiling for an unsupported host platform, you may need to use the boinc anonymous platform mechanism described at http://boinc.berkeley.edu/anonymous_platform.php The program generates several files with .sah extension in the directory from which it's run. These should not be modified. OPTIONS -nographics Do not show graphics while running. -version Show software version SEE ALSO: There is much more information to be found about the operation of the client at the following WEB sites: http://setiathome.berkeley.edu/ http://boinc.berkeley.edu/ with discussions of add-on programs and scripts to control the BOINC client in various situations. The most recent version of the seti_boinc source code can be found at http://setiathome.berkeley.edu/ The most recent version of the official FFTW library can be found at http://www.fftw.org/. A version containing any modifications made for SETI@home can be found at http://setiathome.berkeley.edu/ If you are unable to find it there, please contact Eric Korpela . boinc-app-seti_8.00~svn3701.orig/nightly-tarball0000755000175000017500000000333311373107507021543 0ustar locutuslocutus#!/bin/sh ## $Id: nightly-tarball,v 1.6.2.6 2007/06/01 20:46:03 korpela Exp $ # Create a nightly tarball from CVS export # need to set PATH because we might be running from a cron job. # on our Solaris servers, cvs is in /opt/misc/bin cd `dirname $0` #CVSROOT=/usr/local/warez/cvsroot \ # CHECKOUT='cvs checkout -r HEAD lib/fftw-3.1.1 && mv lib/fftw-3.1.1 .' \ # DIR=fftw-3.1.1 \ # FILENAME_TGZ="fftw-3.1.1_seti.tar.gz" \ # FILENAME_ZIP="fftw-3.1.1_seti.zip" \ # DESTINATION="/home/boincadm/projects/sah/html/user/seti_source/nightly/" \ # ./export-tarball # CVSROOT=/usr/local/warez/cvsroot \ # CHECKOUT='cvs checkout -r HEAD seti_boinc && (cd seti_boinc && ./trim_sources DOIT)' \ # DIR=seti_boinc \ # FILENAME_TGZ="seti_boinc-client-cvs-TODAY.tar.gz" \ # FILENAME_ZIP="seti_boinc-client-cvs-TODAY.zip" \ # DESTINATION="/home/boincadm/projects/sah/html/user/seti_source/nightly/" \ # ./export-tarball CHECKOUT='svn export file:///home/svn/seti_boinc' \ DIR=seti_boinc \ FILENAME_TGZ="setiathome_enhanced-client-cvs-TODAY.tar.gz" \ FILENAME_ZIP="setiathome_enhanced-client-cvs-TODAY.zip" \ DESTINATION="/home/boincadm/projects/sah/html/user/seti_source/nightly/" \ ./export-tarball cd /home/boincadm/projects/sah/html/user/seti_source/nightly/ find . -mtime +30 -exec mv {} old \; /bin/rm -rf /tmp/export-tarball-* boinc-app-seti_8.00~svn3701.orig/export-tarball0000755000175000017500000000614710671336410021411 0ustar locutuslocutus#!/bin/sh ## $Id: export-tarball,v 1.1.2.1 2005/11/23 17:28:31 korpela Exp $ # Create a tarball from CVS or SVN export. # example usage: # CVSROOT=/usr/local/warez/cvsroot \ # CHECKOUT='cvs export -r HEAD boinc' \ # DIR='boinc' \ # FILENAME_TGZ="boinc-cvs-TODAY.tar.gz" \ # FILENAME_ZIP="boinc-cvs-TODAY.zip" \ # DESTINATION="/disks/milkyway/a/users/anderson/boinc/doc/source/nightly/" \ # /disks/philmor/a/users/quarl/bin/export-tarball # CHECKOUT='svn export http://svn.quarl.org/repos/coursesurvey/trunk/coursesurvey' \ # DIR=coursesurvey \ # FILENAME_TGZ="coursesurvey-rSVNREVISION.tar.gz" \ # FILENAME_ZIP="coursesurvey-rSVNREVISION.zip" \ # DESTINATION="ftp://upload.sourceforge.net/incoming" \ # /home/quarl/bin/export-tarball # Note: requires GNU tar (if you want to use other tar need to separate gzip # step) die() { echo "ERROR in $0 on `hostname`:" echo "$1" [ "$2" ] && cat "$2" exit 1 } reqeval() { test -n "$VERBOSE" && echo "Executing: $1" eval "$1" || die "error executing: $1" } reqeval_log() { test -n "$VERBOSE" && echo "Executing: $1" eval "$1" > $2 2>&1 || die "error executing: $1" $2 } upload() { if echo "$DESTINATION" | grep '^ftp://' >/dev/null ; then ftp_upload "$1" else file_upload "$1" fi } file_upload() { test -n "$VERBOSE" && echo "Putting $1 in $DESTINATION" reqeval "mv $1 $DESTINATION" } ftp_upload() { SERVER=`echo "$DESTINATION" | sed 's,^ftp://,,' | sed 's,/.*,,'` DIRECTORY=`echo "$DESTINATION" | sed 's,^ftp://[^/]*',,` test -n "$VERBOSE" && echo "Uploading $1 to ftp site $SERVER $DIRECTORY" reqeval "ncftpput $SERVER $DIRECTORY $1" } if [ -z "$USER" ]; then USER=$LOGNAME fi if ttyo 2>/dev/null ; then VERBOSE=1 fi test -n "$CHECKOUT" || die "No CHECKOUT specified" test -n "$DIR" || die "No DIR specified" test -n "$FILENAME_TGZ" -o -n "$FILENAME_ZIP" || die "No FILENAME_TGZ nor FILENAME_ZIP specified" test -n "$DESTINATION" || die "No DESTINATION specified" TMPDIR=/tmp/export-tarball-$$ reqeval "rm -rf $TMPDIR" reqeval "mkdir -p $TMPDIR" reqeval "cd $TMPDIR" reqeval_log "$CHECKOUT" checkout.log test -d "$DIR" || die "No DIR $DIR after CHECKOUT" TODAY=`date +%Y-%m-%d` # SVNREVISION=`svnlastchangedversion "$DIR" 2>/dev/null` FILENAME_TGZ=`echo "$FILENAME_TGZ" | sed "s/TODAY/$TODAY/"` FILENAME_ZIP=`echo "$FILENAME_ZIP" | sed "s/TODAY/$TODAY/"` # FILENAME_TGZ=`echo "$FILENAME_TGZ" | sed "s/SVNREVISION/$SVNREVISION/"` # FILENAME_ZIP=`echo "$FILENAME_ZIP" | sed "s/SVNREVISION/$SVNREVISION/"` test -n "$FILENAME_TGZ" && reqeval_log "tar czvf $FILENAME_TGZ $DIR" tar.log test -n "$FILENAME_ZIP" && reqeval_log "zip -r9 $FILENAME_ZIP $DIR" zip.log upload $FILENAME_TGZ upload $FILENAME_ZIP reqeval "rm -rf $TMPDIR" boinc-app-seti_8.00~svn3701.orig/COPYRIGHT0000644000175000017500000000413612667707323020026 0ustar locutuslocutus// Copyright (c) 1999-2016 Regents of the University of California // // FFTW: Copyright (c) 2003,2006-2016 Matteo Frigo // Copyright (c) 2003,2006-2016 Massachusets Institute of Technology // // fft8g.[cpp,h]: Copyright (c) 1995-2001 Takya Ooura // // Brook+ and OpenCL portions of code: Copyright (c) 2010-2016 Raistmer // // ASMLIB: Copyright (c) 2004 Agner Fog // // X-Branch: Copyright (c) 2012-2016 Jason Richard Groothuis // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the // Free Software Foundation; either version 2, 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; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions // as an alternative to FFTW and distribute a linked executable and // source code. You must obey the GNU General Public License in all // respects for all of the code used other than the FFT library itself. // Any modification required to support these libraries must be distributed // under the terms of this license. If you modify this program, you may extend // this exception to your version of the program, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. Please be aware that FFTW and ASMLIB are not covered by // this exception, therefore you may not use FFTW and ASMLIB in any derivative // work so modified without permission of the authors of those packages. boinc-app-seti_8.00~svn3701.orig/hosts.make0000644000175000017500000000005710671336410020514 0ustar locutuslocutusBOINCDIR = /disks/ellie/a/users/korpela/boinc boinc-app-seti_8.00~svn3701.orig/README_MAC0000644000175000017500000000026610671336410020057 0ustar locutuslocutus./configure --enable-fast-math -C --with-apple-opengl-framework --with-boinc-platform=powerpc-apple-darwin --without-x --disable-dynamic-graphics --with-my-libjpeg --with-my-jpeglib boinc-app-seti_8.00~svn3701.orig/_autosetup0000755000175000017500000001002112201023426020612 0ustar locutuslocutus#!/bin/sh ## $Id: _autosetup,v 1.2.2.3 2007/08/07 21:42:31 mattl Exp $ ## ---------- some portability checks/adjustments [stolen from configure] ---------- ## 'echo -n' is not portable.. case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac ##---------- ## ---------------------------------------------------------------------- ## Check that given command $1 has version >= $2.$3 ## return 0 if ok, 1 too old or not found (-> shell conventions). ## ---------------------------------------------------------------------- check_version() { dir=`pwd` cd /tmp foundit= ## get current version of $1 desired=$2 echo $ECHO_N "Checking version of '$1' >= $desired... $ECHO_C" name=$1 fullpath=`type $name | awk '{ print $(NF) }'`; if [ -x "$fullpath" ]; then foundit=yes; fi if [ "$foundit" != yes ]; then echo "Didn't find application"; version=0 success=no else cmdline="$fullpath --version"; if version=`($cmdline 2>/dev/null)` 2>/dev/null; then echo >/dev/null else version="0"; fi if [ -n "${version}" ]; then version=`echo $version | awk '{ for (i=1;i<=NF;i++) { split($i,j,"."); m=j[1]"."j[2] ; if (m ~ /[0-9]+\.[0-9]+/) { print m ; break; } } }'` if [ -z "$version" ]; then version=0; fi success=`echo "$version" "$desired" | awk '{ if ($1 >= $2) { print "yes";} else {print "no";}} '` else version=0 success=no fi fi cd $dir if [ $success = "yes" ] ; then echo "succeeded. ($version)" return 0; else echo "failed. ($version)" return 1; fi } ## check_version() ## -------------------------------------------------------------------------------- ## 'MAIN' starts here ## -------------------------------------------------------------------------------- echo "Bootstrapping configure script and makefiles:" ## ---------- first check santity of the installed versions of the build-system ## in case there's GNU drop-in tools available, set these ## some sorry systems don't have proper GNU-make... if check_version make 3.79; then echo >/dev/null else if check_version gmake 3.79; then have_gmake=yes; else echo "Couldn't find a new-enough version of GNU 'make', please install one!"; exit 1; fi fi ## FreeBSD's m4 seems to be broken? Download a fresh one if check_version m4 1.4; then echo >/dev/null else ## solaris m4 works fine if test -f /usr/ccs/bin/m4 -o "`uname -s`" = "FreeBSD" then echo >/dev/null else echo "Couldn't find a new-enough version of 'm4', please install one!"; exit 1; fi # build_lsc_aux "m4-1.4.1" fi # if check_version pkg-config 0.15; then # echo >/dev/null # else # echo "Couldn't find a new-enough version of 'pkg-config', please install one!"; # exit 1; # # build_lsc_aux "pkgconfig-0.15.0" # fi if check_version autoconf 2.58; then echo >/dev/null else echo "Couldn't find a new-enough version of 'autoconf', please install one!"; echo "If you have a newer version, set the environment-variable 'AUTOCONF' to its path"; exit 1; # build_lsc_aux "autoconf-2.59" fi if check_version automake 1.08; then echo >/dev/null else echo "Couldn't find a new-enough version of 'automake', please install one!"; echo "If you have a newer version, set the environment-variable 'AUTOMAKE' to its path"; exit 1; # build_lsc_aux "automake-1.8.5" fi ## ---------- ok, now run autoreconf cmdline="autoreconf -i"; echo "$cmdline" if eval $cmdline; then echo "Done, now run ./configure" echo " ./configure -C to enable caching" echo " ./configure --enable-maintainer-mode to enable maintainer depedencies" exit 0 else echo "Something failed .... please check error-message and re-run when fixed." echo "exiting..." exit 1 fi boinc-app-seti_8.00~svn3701.orig/gbt_splitter/0000755000175000017500000000000013155506304021216 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/gbt_splitter/mb_message.cpp0000644000175000017500000000351312111742220024014 0ustar locutuslocutus/* * 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 #include #include #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 * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/splitparms.h0000644000175000017500000000746212111742220023564 0ustar locutuslocutus/* 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 #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 * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/tools/0000755000175000017500000000000013155506303022355 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/gbt_splitter/tools/disksplitter0000755000175000017500000001055312111742220025017 0ustar locutuslocutus#! /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/informix/bin:/usr/local/tex # 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@ssl.berkeley.edu mattl@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 boinc-app-seti_8.00~svn3701.orig/gbt_splitter/tools/sah_splitter.sh0000755000175000017500000001141112111742220025402 0ustar locutuslocutus#! /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/bin:/usr/local/tex 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@ssl.berkeley.edu jeffc@ssl.berkeley.edu mattl@ssl.berkeley.edu davea@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 boinc-app-seti_8.00~svn3701.orig/gbt_splitter/db_fns.h0000644000175000017500000000202612111742220022610 0ustar locutuslocutus/* * $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 * * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/splittypes.h0000644000175000017500000000520712111742220023601 0ustar locutuslocutus/* 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 #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 * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/wufiles.h0000644000175000017500000000150412111742220023033 0ustar locutuslocutus/* * * 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 * * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/mb_splitter.cpp0000644000175000017500000010147612111742220024245 0ustar locutuslocutus/* * * 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 #include #include #include #include #include #include #include #include #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= "\n" " 0\n" "\n" "\n" " \n" " 0\n" " work_unit.sah\n" " \n" "\n"; const char *result_template_filename_id = "result_0.xml"; const char *result_template= "\n" " \n" " \n" " \n" " 65536\n" " http://setiboincdata.ssl.berkeley.edu/sah_cgi/file_upload_handler\n" "\n" "\n" " \n" " \n" " result.sah\n" " \n" "\n"; // END TEMPLATE DEFS -------------------------------------------------- std::vector tapebuffer; std::map coord_history; std::vector 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;i6)) || ((*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 > 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::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 * * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/mb_splitter.h0000644000175000017500000000746112136057720023724 0ustar locutuslocutus/* * 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 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 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 tapebuffer; extern std::map 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 * * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/mb_splittypes.h0000644000175000017500000000534512111742220024262 0ustar locutuslocutus/* 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 #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 * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/mb_angdist.cpp0000644000175000017500000000341012111742220024015 0ustar locutuslocutus/* * 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 #include #include #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 * * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/fftw.h0000644000175000017500000002762412111742220022336 0ustar locutuslocutus/* 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 #include #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 */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/uttolst.h0000644000175000017500000000014512111742220023073 0ustar locutuslocutusdouble tm_UtToLst(double ddtime, double longitude, long mon, long day, long year); boinc-app-seti_8.00~svn3701.orig/gbt_splitter/angdist.cpp0000644000175000017500000000314112111742220023340 0ustar locutuslocutus/* * 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 #include #include #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 * * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/validrun.cpp0000644000175000017500000001144612111742220023542 0ustar locutuslocutus/* * 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 #include #include #include #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) && (iframe=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; iframe+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 * * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/hr_min_sec.cpp0000644000175000017500000000644512111742220024027 0ustar locutuslocutus/* * * 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 #include 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 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 * * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/makebufs.cpp0000644000175000017500000000700012111742220023502 0ustar locutuslocutus/* * 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 #include #include #include #include #include #include #include #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 * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/mb_validrun.cpp0000644000175000017500000001165212111742220024217 0ustar locutuslocutus/* * 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 #include #include #include #include "setilib.h" #include "splitparms.h" #include "splittypes.h" #include "splitter.h" #include "message.h" bool valid_run(std::vector &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 0) { for (i=0;valid && (i #include #include #include #include #include #include #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= "\n" " 0\n" "\n" "\n" " \n" " 0\n" " work_unit.sah\n" " \n" "\n"; const char *result_template_filename_id = "result_0.xml"; const char *result_template= "\n" " \n" " \n" " \n" " 65536\n" " http://setiboincdata.ssl.berkeley.edu/sah_cgi/file_upload_handler\n" "\n" "\n" " \n" " \n" " result.sah\n" " \n" "\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;itm_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 * * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/message.cpp0000644000175000017500000000324212111742220023335 0ustar locutuslocutus/* * 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 #include #include #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 * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/gencoeff.py0000755000175000017500000001131612111742220023337 0ustar locutuslocutus#!/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 Number of points in FFT" print " -t --taps Number of taps in PFB" print " -b --sub-bands Number of sub-bands in data" print " -w --width-factor width factor for sinc(x) call" print " -d --data-type 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() boinc-app-seti_8.00~svn3701.orig/gbt_splitter/mb_angdist.h0000644000175000017500000000146512111742220023472 0ustar locutuslocutus/* * 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 * * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/cmap_interp.cpp0000644000175000017500000000171012111742220024210 0ustar locutuslocutus#include #include #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 &map, seti_time &t) { std::map::iterator above(map.upper_bound(t)); std::map::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; } boinc-app-seti_8.00~svn3701.orig/gbt_splitter/readtape.h0000644000175000017500000000415412111742220023146 0ustar locutuslocutus/* 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 * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/squarewave.cpp0000644000175000017500000000452012111742220024074 0ustar locutuslocutus#include "sah_config.h" #include #include #include #include #include #include #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;writtentm_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_file, &data, 1); } time0+=(1024.0*1024.0*4.0/2.5e6); } } boinc-app-seti_8.00~svn3701.orig/gbt_splitter/db_fns.cpp0000644000175000017500000001356212111742220023152 0ustar locutuslocutus/* * $Id: db_fns.cpp,v 1.3.4.2 2006/12/14 22:24:37 korpela Exp $ * */ #include "sah_config.h" #include #include #include #include #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;iwuinfo.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 // * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/polyphase.h0000644000175000017500000000140212111742220023356 0ustar locutuslocutus#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); boinc-app-seti_8.00~svn3701.orig/gbt_splitter/wufiles.cpp0000644000175000017500000005222712111742220023376 0ustar locutuslocutus/* * * 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 #include #include #include #include #include #include #include #include #ifdef HAVE_ERRNO_H #include #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 int wu_database_id[NSTRIPS]; static std::vector 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(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(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;jst.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;ibyte,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,"\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;i0); 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",tmpstr.size(), xml_encoding_names[encoding]); fwrite(tmpstr.c_str(),tmpstr.size(),1,tmpfile); fprintf(tmpfile,"\n"); fprintf(tmpfile,"\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 * * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/makebufs.h0000644000175000017500000000141112111742220023147 0ustar locutuslocutus/* * 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 * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/Makefile.am0000644000175000017500000000333512147455107023262 0ustar locutuslocutusCC=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 boinc-app-seti_8.00~svn3701.orig/gbt_splitter/encode.h0000644000175000017500000000162312111742220022614 0ustar locutuslocutus/* * * 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 * * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/mb_dotransform.h0000644000175000017500000000354112114231327024400 0ustar locutuslocutus/* * * 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 &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 * * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/readtape.cpp0000644000175000017500000001763512111742220023511 0ustar locutuslocutus/* 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 #include #include #include #include #include #include #include #include #include #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 ((bytesread0)); 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 #include #include #include #include #include #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;writtentm_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_file, &data, 1); } time0+=(1024.0*1024.0*4.0/2.5e6); } } boinc-app-seti_8.00~svn3701.orig/gbt_splitter/dotransform.h0000644000175000017500000000265312111742220023721 0ustar locutuslocutus/* * * 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 * * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/message.h0000644000175000017500000000215512111742220023004 0ustar locutuslocutus/* * 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 * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/hr_min_sec.h0000644000175000017500000000520412111742220023464 0ustar locutuslocutus/* * * 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 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 * * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/four1.h0000644000175000017500000000120112111742220022403 0ustar locutuslocutus/* * * 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 * * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/mb_validrun.h0000644000175000017500000000142412111742220023660 0ustar locutuslocutus/* * 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 &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 * * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/dotransform.cpp0000644000175000017500000001366312111742220024257 0ustar locutuslocutus/* * * 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 #include #include #include #include #include #include #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 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 * * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/writeheader.cpp0000644000175000017500000000504112111742220024213 0ustar locutuslocutus/* * 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 #include #include #include #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 * * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/polyphase.cpp0000644000175000017500000001100012111742220023704 0ustar locutuslocutus #include "sah_config.h" #include #include #include #include #include #include #include #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 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); } } boinc-app-seti_8.00~svn3701.orig/gbt_splitter/mb_wufiles.cpp0000644000175000017500000005314412220630364024061 0ustar locutuslocutus/* * * 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 #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_ERRNO_H #include #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 wu_database_id; std::vector > bin_data; extern APP_CONFIG sah_config; int make_wu_headers(std::vector &tapebuffer, telescope_id tel, std::vector &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(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::iterator above(coord_history.upper_bound(end_time)); std::map::iterator below(coord_history.lower_bound(start_time)); std::map::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\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",tmpstr.size(), xml_encoding_names[encoding]); fwrite(tmpstr.c_str(),tmpstr.size(),1,tmpfile); fprintf(tmpfile,"\n"); fprintf(tmpfile,"\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 * * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/writeheader.h0000644000175000017500000000166012111742220023663 0ustar locutuslocutus/* * 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 * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/cmap_interp.h0000644000175000017500000000013512111742220023655 0ustar locutuslocutus extern coordinate_t cmap_interp(std::map &map, seti_time &t); boinc-app-seti_8.00~svn3701.orig/gbt_splitter/mb_polyphase.cpp0000644000175000017500000001104412111742220024372 0ustar locutuslocutus #include "sah_config.h" #include #include #include #include #include #include #include #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 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); } } boinc-app-seti_8.00~svn3701.orig/gbt_splitter/splitter.h0000644000175000017500000000663612111742220023236 0ustar locutuslocutus/* * 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 * * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/validrun.h0000644000175000017500000000133312111742220023201 0ustar locutuslocutus/* * 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 * * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/encode.cpp0000644000175000017500000000461412111742220023152 0ustar locutuslocutus/* * * 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 #include #include #include /* 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 * * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/mb_dotransform.cpp0000644000175000017500000004013712143014043024731 0ustar locutuslocutus/* * * 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 #include #include #include #include #include #include #include #include "setilib.h" #include "splitparms.h" #include "splittypes.h" #include "mb_splitter.h" #include "fftw3.h" #include "mb_wufiles.h" #include /* for open() */ #include /* for open() */ #include /* 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* 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* 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 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 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(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( // 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(tapebuffer[iTapeBufferIdx].data[iDataIdx].imag()), static_cast(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 &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*) fftwf_malloc(PFB_FFT_LEN * sizeof(complex)); 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 *) fftwf_malloc(PFB_OUTPUT_STACK_SIZE * PFB_FFT_LEN * sizeof(complex)); 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 * * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/four1.cpp0000644000175000017500000000404012111742220022742 0ustar locutuslocutus/* * * 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 #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 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 > bin_data;$/;" v bin_data wufiles.cpp /^static std::vector 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 &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 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 &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 &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 > &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 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 &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 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 wuheaders;$/;" v wuheaders splitter.cpp /^workunit wuheaders[NSTRIPS];$/;" v wulog mb_splitter.cpp /^FILE *wulog,*errorlog;$/;" v wulog splitter.cpp /^FILE *wulog,*errorlog;$/;" v boinc-app-seti_8.00~svn3701.orig/gbt_splitter/readheader.h0000644000175000017500000000221112111742220023435 0ustar locutuslocutus/* * 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 * */ boinc-app-seti_8.00~svn3701.orig/gbt_splitter/readheader.cpp0000644000175000017500000001556512111742220024010 0ustar locutuslocutus/* * 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 #include #include #include #include #include #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])) && (++isource=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 && (posst)); 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 #include #include #include "sqlrow.h" #include "sqlblob.h" #include "sqlapi.h" #include "db_table.h" #include "schema_master.h" #include #include #include #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 * * */ boinc-app-seti_8.00~svn3701.orig/m4/0000755000175000017500000000000013155506301017031 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/m4/sah_find_s4path.m40000644000175000017500000000162110671336410022333 0ustar locutuslocutus# SETI_BOINC is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free # Software Foundation; either version 2, or (at your option) any later # version. AC_DEFUN([SAH_FIND_S4PATH],[ AC_MSG_CHECKING([path to S4 library]) s4_search_path="$S4PATH /usr/local/warez/projects/s4/siren /disks/cyclops/c/users/seti/s4/siren" for tmp_dir in $s4_search_path do if test -f $tmp_dir/lib/libs4.a then S4PATH=$tmp_dir S4LIBS="-L$S4PATH/lib -ls4" S4CFLAGS="-I$S4PATH/include" S4_RECEIVER_CONFIG="$S4PATH/db/ReceiverConfig.tab" break fi done if test -n "$S4PATH" then AC_MSG_RESULT([$S4PATH]) else no_s4=yes AC_MSG_RESULT([not found]) fi AC_SUBST([S4PATH]) AC_SUBST([S4LIBS]) AC_SUBST([S4CFLAGS]) AC_DEFINE_UNQUOTED([S4_RECEIVER_CONFIG_FILE],["$S4_RECEIVER_CONFIG"],[Path to the S4 receiver config file]) ]) boinc-app-seti_8.00~svn3701.orig/m4/sah_make_dll.m40000644000175000017500000000043510671336410021702 0ustar locutuslocutusAC_DEFUN([SAH_LINK_DLL],[ case ${host} in *darwin*) LINK_DLL="${CC} -fPIC -bundle -flat_namespace -undefined suppress" ;; *solaris*) LINK_DLL="/usr/ccs/bin/ld -G " ;; *) LINK_DLL="${CC} -fPIC -shared" ;; esac AC_SUBST(LINK_DLL) ]) boinc-app-seti_8.00~svn3701.orig/m4/check_ssl.m40000644000175000017500000000263712636712246021253 0ustar locutuslocutusAC_DEFUN([CHECK_SSL], [AC_MSG_CHECKING(for openssl) SSLDIR= found_ssl="no" AC_ARG_WITH(ssl, AC_HELP_STRING([--with-ssl], [Use openssl (in specified installation directory)]), [check_ssl_dir="$withval"], [check_ssl_dir=]) for dir in $check_ssl_dir /usr/local/ssl /usr/lib64/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /usr; do ssldir="$dir" if test -f "$dir/include/openssl/ssl.h"; then found_ssl="yes"; SSLDIR="${ssldir}" CFLAGS="$CFLAGS -I$ssldir/include -I$ssldir/include/openssl"; CXXFLAGS="$CXXFLAGS -I$ssldir/include -I$ssldir/include/openssl"; break; fi if test -f "$dir/include/ssl.h"; then found_ssl="yes"; SSLDIR="${ssldir}" CFLAGS="$CFLAGS -I$ssldir/include/"; CXXFLAGS="$CXXFLAGS -I$ssldir/include/"; break fi done AC_MSG_RESULT($found_ssl) if test x_$found_ssl != x_yes; then AC_MSG_ERROR([ ---------------------------------------------------------------------- Cannot find openssl libraries. Please install openssl or specify installation directory with --with-ssl=(dir). ---------------------------------------------------------------------- ]) else printf "OpenSSL found in $ssldir\n"; SSLLIBS="-lssl -lcrypto"; LDFLAGS="$LDFLAGS -L$ssldir/lib"; AC_DEFINE_UNQUOTED([USE_OPENSSL],[1], ["Define to 1 if you want to use the openssl crypto library"]) AC_SUBST(SSLLIBS) AC_SUBST(SSLDIR) fi ])dnl boinc-app-seti_8.00~svn3701.orig/m4/sah_mysql.m40000644000175000017500000000162110671336410021275 0ustar locutuslocutus# SETI_BOINC is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free # Software Foundation; either version 2, or (at your option) any later # version. AC_DEFUN([SAH_CHECK_MYSQL],[ AC_LANG_PUSH(C) AC_ARG_VAR([MYSQL_CONFIG], [mysql_config program]) if test -z "$MYSQL_CONFIG"; then AC_PATH_PROG(MYSQL_CONFIG,mysql_config,,[$PATH:/usr/local/mysql/bin:/opt/misc/mysql/bin:~mysql/bin]) fi if test -z "$MYSQL_CONFIG" then echo MYSQL not found no_mysql=yes else AC_MSG_RESULT(yes) AC_MSG_CHECKING(mysql libraries) MYSQL_LIBS=`${MYSQL_CONFIG} --libs` AC_MSG_RESULT($MYSQL_LIBS) AC_MSG_CHECKING(mysql includes) MYSQL_CFLAGS=`${MYSQL_CONFIG} --cflags` AC_DEFINE(USE_MYSQL,1,[Define if MYSQL is installed]) AC_MSG_RESULT($MYSQL_CFLAGS) fi AC_SUBST(MYSQL_LIBS) AC_SUBST(MYSQL_CFLAGS) AC_LANG_POP ]) boinc-app-seti_8.00~svn3701.orig/m4/sah_largefile_breaks_cxx.m40000644000175000017500000000146610671336410024302 0ustar locutuslocutus# SETI_BOINC is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free # Software Foundation; either version 2, or (at your option) any later # version. AC_DEFUN([SAH_LARGEFILE_BREAKS_CXX],[ AC_MSG_CHECKING([whether largefile support breaks C++]) AC_LANG_PUSH(C++) AC_LINK_IFELSE( [AC_LANG_PROGRAM([[ #define CONFIG_TEST #include ]], [[ std::cout << 1.0 << std::endl; ]])], [tmp_res="no"], [AC_DEFINE([LARGEFILE_BREAKS_CXX],[1], ["Define to 1 if largefile support causes missing symbols in C++"] ) tmp_res="yes" sah_cxx_includes=`echo "#include \"$BOINCDIR/lib/std_fixes.h\"" ; echo $sah_cxx_includes` ] ) AC_MSG_RESULT($tmp_res) AC_LANG_POP ]) boinc-app-seti_8.00~svn3701.orig/m4/sah_check_seti_gbt.m40000644000175000017500000000242012526665516023100 0ustar locutuslocutus# SETI_BOINC is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free # Software Foundation; either version 2, or (at your option) any later # version. AC_PREREQ([2.54]) AC_DEFUN([SAH_CHECK_SETI_GBT],[ AC_ARG_VAR([SETI_GBT],[SETI_GBT directory]) if test -z "$HEAD" then AC_PATH_PROG(HEAD,head) fi if test -z "$FIND" then AC_PATH_PROG(FIND,find) fi thisdir=`pwd` AC_MSG_CHECKING([for SETI_GBT]) seti_gbt_search_path=[`echo $SETI_GBT seti_gbt* ../seti_gbt* ../lib/seti_gbt* $HOME/lib/seti_gbt* /usr/local/seti_gbt* /usr/local`] for seti_gbt_dir in $seti_gbt_search_path do if test -d $seti_gbt_dir/lib then if test -f $seti_gbt_dir/lib/libsetigbt.so then cd $seti_gbt_dir SETI_GBT=`pwd` cd $thisdir break else if $FIND $seti_gbt_dir -name "lib/libsetigbt.so" 2>/dev/null >/dev/null then SETI_GBT=`$FIND $seti_gbt_dir -name "lib/libsetigbt.so" -print | $HEAD -1 | sed 's/\/lib\/libsetigbt.so//'` cd $SETI_GBT SETI_GBT=`pwd` cd $thisdir break fi fi fi done if test -n "$SETI_GBT" then AC_MSG_RESULT($SETI_GBT) else AC_MSG_RESULT(not found) no_seti_gbt=yes fi ]) boinc-app-seti_8.00~svn3701.orig/m4/sah_libext.m40000644000175000017500000000132510671336410021420 0ustar locutuslocutus# SETI_BOINC is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free # Software Foundation; either version 2, or (at your option) any later # version. AC_DEFUN([SAH_LIBEXT],[ AC_MSG_CHECKING(library extension) if test -n `echo $AR | grep ar` then LIBEXT=a else LIBEXT=lib fi AC_MSG_RESULT($LIBEXT) AC_SUBST(LIBEXT) ]) AC_DEFUN([SAH_DLLEXT],[ AC_MSG_CHECKING(shared object extension) case "${host}" in *-*-emx* | *-*-mingw* | *-*-cygwin* | *-*-rmx*) DLLEXT="dll" ;; *-*-darwin*) DLLEXT="dylib" ;; *) DLLEXT="so" ;; esac AC_MSG_RESULT($DLLEXT) AC_SUBST(DLLEXT) ]) boinc-app-seti_8.00~svn3701.orig/m4/sah_check_boinc.m40000644000175000017500000000350112633557720022367 0ustar locutuslocutus# SETI_BOINC is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free # Software Foundation; either version 2, or (at your option) any later # version. AC_PREREQ([2.54]) AC_DEFUN([SAH_CHECK_BOINC],[ AC_ARG_VAR([BOINCDIR],[boinc directory]) AC_ARG_VAR([PROJECTDIR],[project config.xml directory]) set -x if test -z "$HEAD" then AC_PATH_PROG(HEAD,head) fi if test -z "$FIND" then AC_PATH_PROG(FIND,find) fi thisdir=`pwd` AC_MSG_CHECKING([for BOINC]) boinc_search_path="$BOINCDIR /usr/local boinc ../boinc ../../boinc /usr /usr/local /usr/local/include ${top_srcdir}../boinc $HOME/boinc /usr/local/boinc /usr/local/lib/boinc /opt/misc/boinc /opt/misc/lib/boinc $2" for boinc_dir in $boinc_search_path do if test -d $boinc_dir then if test -f $boinc_dir/include/std_fixes.h -o -f $boinc_dir/lib/std_fixes.h then cd $boinc_dir BOINCDIR=`pwd` cd $thisdir break else if test -n "`$FIND $boinc_dir -name 'std_fixes.h'`" then BOINCDIR=`$FIND $boinc_dir -name "std_fixes.h" -print | $HEAD -1 | sed 's/\/std_fixes.h//'` cd $BOINCDIR/.. BOINCDIR=`pwd` cd $thisdir break fi fi fi done if test -n "$BOINCDIR" then AC_MSG_RESULT($BOINCDIR) else no_boinc=yes AC_MSG_RESULT(not found) fi if test -z "$PROJECTDIR" then PROJECTDIR=~boincadm/projects/ap fi AC_DEFINE_UNQUOTED([PROJECTDIR],["$PROJECTDIR"],[Define as directory containing the project config.xml]) AC_SUBST([PROJECTDIR]) AC_SUBST([BOINCDIR]) BOINCCFG=`find $BOINCDIR -name config.h | head -1` BOINC_CFLAGS="-I$BOINCDIR -I$BOINCDIR/api -I$BOINCDIR/lib -I$BOINCDIR/sched -I$BOINCDIR/db -I`dirname $BOINCCFG`" AC_SUBST([BOINC_CFLAGS]) set +x ]) boinc-app-seti_8.00~svn3701.orig/m4/sah_check_cfitsio.m40000644000175000017500000000235612526665516022750 0ustar locutuslocutus# SETI_BOINC is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free # Software Foundation; either version 2, or (at your option) any later # version. AC_PREREQ([2.54]) AC_DEFUN([SAH_CHECK_CFITSIO],[ AC_ARG_VAR([CFITSIO],[CFITSIO directory]) if test -z "$HEAD" then AC_PATH_PROG(HEAD,head) fi if test -z "$FIND" then AC_PATH_PROG(FIND,find) fi thisdir=`pwd` AC_MSG_CHECKING([for CFITSIO]) cfitsio_search_path=[`echo $CFITSIO cfitsio* ../cfitsio* ../lib/cfitsio* $HOME/lib/cfitsio* /usr/local/cfitsio* /usr/local`] for cfitsio_dir in $cfitsio_search_path do if test -d $cfitsio_dir then if test -f $cfitsio_dir/libcfitsio.a then cd $cfitsio_dir CFITSIO=`pwd` cd $thisdir break else if $FIND $cfitsio_dir -name "lib/libcfitsio.a" 2>/dev/null >/dev/null then CFITSIO=`$FIND $cfitsio_dir -name "lib/libcfitsio.a" -print | $HEAD -1 | sed 's/\/lib\/libcfitsio.a//'` cd $CFITSIO CFITSIO=`pwd` cd $thisdir break fi fi fi done if test -n "$CFITSIO" then AC_MSG_RESULT($CFITSIO) else AC_MSG_RESULT(not found) no_cfitsio=yes fi ]) boinc-app-seti_8.00~svn3701.orig/m4/ax_c_float_words_bigendian.m40000644000175000017500000000272410671336410024617 0ustar locutuslocutusAC_DEFUN([AX_C_FLOAT_WORDS_BIGENDIAN], [ AC_CACHE_CHECK(whether float word ordering is bigendian, ax_cv_c_float_words_bigendian, [ ax_cv_c_float_words_bigendian=unknown STRINGS="strings -a -" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include void foo(double *d);],[ static double d = 90904234967036810337470478905505011476211692735615632014797120844053488865816695273723469097858056257517020191247487429516932130503560650002327564517570778480236724525140520121371739201496540132640109977779420565776568942592.0; foo(&d); printf("%f",d); ])], [ $STRINGS conftest.$ac_objext > conftest.str if grep noonsees conftest.str >/dev/null ; then ax_cv_c_float_words_bigendian=yes fi if grep seesnoon conftest.str >/dev/null ; then if test "$ax_cv_c_float_words_bigendian" = unknown; then ax_cv_c_float_words_bigendian=no else ax_cv_c_float_words_bigendian=unknown fi fi cp conftest.o /tmp/conftest.osav cp conftest.str /tmp/conftest.sav /bin/rm -f conftest.str ])]) case $ax_cv_c_float_words_bigendian in yes) m4_default([$1], [AC_DEFINE([FLOAT_WORDS_BIGENDIAN], 1, [Define to 1 if your system stores words within floats with the most significant word first])]) ;; no) $2 ;; *) m4_default([$3], [AC_MSG_ERROR([ Unknown float word ordering. You need to manually preset ax_cv_c_float_words_bigendian=no (or yes) according to your system. ])]) ;; esac ])# AX_C_FLOAT_WORDS_BIGENDIAN boinc-app-seti_8.00~svn3701.orig/m4/libcurl.m40000644000175000017500000002137610671336410020742 0ustar locutuslocutus# LIBCURL_CHECK_CONFIG ([DEFAULT-ACTION], [MINIMUM-VERSION], # [ACTION-IF-YES], [ACTION-IF-NO]) # ---------------------------------------------------------- # David Shaw Jun-21-2005 # # Checks for libcurl. DEFAULT-ACTION is the string yes or no to # specify whether to default to --with-libcurl or --without-libcurl. # If not supplied, DEFAULT-ACTION is yes. MINIMUM-VERSION is the # minimum version of libcurl to accept. Pass the version as a regular # version number like 7.10.1. If not supplied, any version is # accepted. ACTION-IF-YES is a list of shell commands to run if # libcurl was successfully found and passed the various tests. # ACTION-IF-NO is a list of shell commands that are run otherwise. # Note that using --without-libcurl does run ACTION-IF-NO. # # This macro defines HAVE_LIBCURL if a working libcurl setup is found, # and sets @LIBCURL@ and @LIBCURL_CPPFLAGS@ to the necessary values. # Other useful defines are LIBCURL_FEATURE_xxx where xxx are the # various features supported by libcurl, and LIBCURL_PROTOCOL_yyy # where yyy are the various protocols supported by libcurl. Both xxx # and yyy are capitalized. See the list of AH_TEMPLATEs at the top of # the macro for the complete list of possible defines. Shell # variables $libcurl_feature_xxx and $libcurl_protocol_yyy are also # defined to 'yes' for those features and protocols that were found. # Note that xxx and yyy keep the same capitalization as in the # curl-config list (e.g. it's "HTTP" and not "http"). # # Users may override the detected values by doing something like: # LIBCURL="-lcurl" LIBCURL_CPPFLAGS="-I/usr/myinclude" ./configure # # For the sake of sanity, this macro assumes that any libcurl that is # found is after version 7.7.2, the first version that included the # curl-config script. Note that it is very important for people # packaging binary versions of libcurl to include this script! # Without curl-config, we can only guess what protocols are available. AC_DEFUN([LIBCURL_CHECK_CONFIG], [ AH_TEMPLATE([LIBCURL_FEATURE_SSL],[Defined if libcurl supports SSL]) AH_TEMPLATE([LIBCURL_FEATURE_KRB4],[Defined if libcurl supports KRB4]) AH_TEMPLATE([LIBCURL_FEATURE_IPV6],[Defined if libcurl supports IPv6]) AH_TEMPLATE([LIBCURL_FEATURE_LIBZ],[Defined if libcurl supports libz]) AH_TEMPLATE([LIBCURL_FEATURE_ASYNCHDNS],[Defined if libcurl supports AsynchDNS]) AH_TEMPLATE([LIBCURL_PROTOCOL_HTTP],[Defined if libcurl supports HTTP]) AH_TEMPLATE([LIBCURL_PROTOCOL_HTTPS],[Defined if libcurl supports HTTPS]) AH_TEMPLATE([LIBCURL_PROTOCOL_FTP],[Defined if libcurl supports FTP]) AH_TEMPLATE([LIBCURL_PROTOCOL_FTPS],[Defined if libcurl supports FTPS]) AH_TEMPLATE([LIBCURL_PROTOCOL_GOPHER],[Defined if libcurl supports GOPHER]) AH_TEMPLATE([LIBCURL_PROTOCOL_FILE],[Defined if libcurl supports FILE]) AH_TEMPLATE([LIBCURL_PROTOCOL_TELNET],[Defined if libcurl supports TELNET]) AH_TEMPLATE([LIBCURL_PROTOCOL_LDAP],[Defined if libcurl supports LDAP]) AH_TEMPLATE([LIBCURL_PROTOCOL_DICT],[Defined if libcurl supports DICT]) AC_ARG_WITH(libcurl, AC_HELP_STRING([--with-libcurl=DIR],[look for the curl library in DIR]), [_libcurl_with=$withval],[_libcurl_with=ifelse([$1],,[yes],[$1])]) if test "$_libcurl_with" != "no" ; then AC_PROG_AWK _libcurl_version_parse="eval $AWK '{split(\$NF,A,\".\"); X=256*256*A[[1]]+256*A[[2]]+A[[3]]; print X;}'" _libcurl_try_link=yes if test -d "$_libcurl_with" ; then CPPFLAGS="${CPPFLAGS} -I$withval/include" LDFLAGS="${LDFLAGS} -L$withval/lib" fi AC_PATH_PROG([_libcurl_config],[curl-config]) if test x$_libcurl_config != "x" ; then AC_CACHE_CHECK([for the version of libcurl], [libcurl_cv_lib_curl_version], [libcurl_cv_lib_curl_version=`$_libcurl_config --version | $AWK '{print $[]2}'`]) _libcurl_version=`echo $libcurl_cv_lib_curl_version | $_libcurl_version_parse` _libcurl_wanted=`echo ifelse([$2],,[0],[$2]) | $_libcurl_version_parse` if test $_libcurl_wanted -gt 0 ; then AC_CACHE_CHECK([for libcurl >= version $2], [libcurl_cv_lib_version_ok], [ if test $_libcurl_version -ge $_libcurl_wanted ; then libcurl_cv_lib_version_ok=yes else libcurl_cv_lib_version_ok=no fi ]) fi if test $_libcurl_wanted -eq 0 || test x$libcurl_cv_lib_version_ok = xyes ; then if test x"$LIBCURL_CPPFLAGS" = "x" ; then LIBCURL_CPPFLAGS=`$_libcurl_config --cflags` fi if test x"$LIBCURL" = "x" ; then LIBCURL=`$_libcurl_config --libs` # This is so silly, but Apple actually has a bug in their # curl-config script. Fixed in Tiger, but there are still # lots of Panther installs around. case "${host}" in powerpc-apple-darwin7*) LIBCURL=`echo $LIBCURL | sed -e 's|-arch i386||g'` ;; esac fi # All curl-config scripts support --feature _libcurl_features=`$_libcurl_config --feature` # Is it modern enough to have --protocols? (7.12.4) if test $_libcurl_version -ge 461828 ; then _libcurl_protocols=`$_libcurl_config --protocols` fi else _libcurl_try_link=no fi unset _libcurl_wanted fi if test $_libcurl_try_link = yes ; then # we didn't find curl-config, so let's see if the user-supplied # link line (or failing that, "-lcurl") is enough. LIBCURL=${LIBCURL-"-lcurl"} AC_CACHE_CHECK([whether libcurl is usable], [libcurl_cv_lib_curl_usable], [ _libcurl_save_cppflags=$CPPFLAGS CPPFLAGS="$CPPFLAGS $LIBCURL_CPPFLAGS" _libcurl_save_libs=$LIBS LIBS="$LIBS $LIBCURL" AC_LINK_IFELSE(AC_LANG_PROGRAM([#include ],[ /* Try and use a few common options to force a failure if we are missing symbols or can't link. */ int x; curl_easy_setopt(NULL,CURLOPT_URL,NULL); x=CURL_ERROR_SIZE; x=CURLOPT_WRITEFUNCTION; x=CURLOPT_FILE; x=CURLOPT_ERRORBUFFER; x=CURLOPT_STDERR; x=CURLOPT_VERBOSE; ]),libcurl_cv_lib_curl_usable=yes,libcurl_cv_lib_curl_usable=no) CPPFLAGS=$_libcurl_save_cppflags LIBS=$_libcurl_save_libs unset _libcurl_save_cppflags unset _libcurl_save_libs ]) if test $libcurl_cv_lib_curl_usable = yes ; then # Does curl_free() exist in this version of libcurl? # If not, fake it with free() _libcurl_save_cppflags=$CPPFLAGS CPPFLAGS="$CPPFLAGS $LIBCURL_CPPFLAGS" _libcurl_save_libs=$LIBS LIBS="$LIBS $LIBCURL" AC_CHECK_FUNC(curl_free,, AC_DEFINE(curl_free,free, [Define curl_free() as free() if our version of curl lacks curl_free.])) CPPFLAGS=$_libcurl_save_cppflags LIBS=$_libcurl_save_libs unset _libcurl_save_cppflags unset _libcurl_save_libs AC_DEFINE(HAVE_LIBCURL,1, [Define to 1 if you have a functional curl library.]) AC_SUBST(LIBCURL_CPPFLAGS) AC_SUBST(LIBCURL) for _libcurl_feature in $_libcurl_features ; do AC_DEFINE_UNQUOTED(AS_TR_CPP(libcurl_feature_$_libcurl_feature),[1]) eval AS_TR_SH(libcurl_feature_$_libcurl_feature)=yes done if test "x$_libcurl_protocols" = "x" ; then # We don't have --protocols, so just assume that all # protocols are available _libcurl_protocols="HTTP FTP GOPHER FILE TELNET LDAP DICT" if test x$libcurl_feature_SSL = xyes ; then _libcurl_protocols="$_libcurl_protocols HTTPS" # FTPS wasn't standards-compliant until version # 7.11.0 if test $_libcurl_version -ge 461568; then _libcurl_protocols="$_libcurl_protocols FTPS" fi fi fi for _libcurl_protocol in $_libcurl_protocols ; do AC_DEFINE_UNQUOTED(AS_TR_CPP(libcurl_protocol_$_libcurl_protocol),[1]) eval AS_TR_SH(libcurl_protocol_$_libcurl_protocol)=yes done fi fi unset _libcurl_try_link unset _libcurl_version_parse unset _libcurl_config unset _libcurl_feature unset _libcurl_features unset _libcurl_protocol unset _libcurl_protocols unset _libcurl_version fi if test x$_libcurl_with = xno || test x$libcurl_cv_lib_curl_usable != xyes ; then # This is the IF-NO path ifelse([$4],,:,[$4]) else # This is the IF-YES path ifelse([$3],,:,[$3]) fi unset _libcurl_with ])dnl boinc-app-seti_8.00~svn3701.orig/m4/sah_find_setilib.m40000644000175000017500000000167211115337042022565 0ustar locutuslocutus# SETI_BOINC is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free # Software Foundation; either version 2, or (at your option) any later # version. AC_DEFUN([SAH_FIND_SETILIB],[ AC_MSG_CHECKING([path to setilib library]) setilib_search_path="$SETILIBDIR setilib ../setilib $HOME/setilib /usr/local /usr/local/setilib /usr/local/lib/setilib /opt/misc/setilib /opt/misc/lib/setilib" for tmp_dir in $setilib_search_path do if test -f $tmp_dir/lib/libseti.a then mydir=`pwd` cd $tmp_dir SETILIB_PATH=`pwd` SETILIB_LIBS="-L$SETILIB_PATH/lib -lseti" SETILIB_CFLAGS="-I$SETILIB_PATH/include -I$SETILIB_PATH" cd $mydir break fi done if test -n "$SETILIB_PATH" then AC_MSG_RESULT([$SETILIB_PATH]) else no_setilib=yes AC_MSG_RESULT([not found]) fi AC_SUBST([SETILIB_PATH]) AC_SUBST([SETILIB_LIBS]) AC_SUBST([SETILIB_CFLAGS]) ]) boinc-app-seti_8.00~svn3701.orig/m4/sah_check_math_functions.m40000644000175000017500000000054211055040466024307 0ustar locutuslocutusAC_DEFUN([SAH_CHECK_MATH_FUNCS],[ for func in $1 ; do AH_TEMPLATE(AS_TR_CPP(have_${func}),[Define to 1 if you have the function ${func}()]) AC_CHECK_LIB([m],$func,[ eval "ac_cv_func_${func}=yes" AC_DEFINE_UNQUOTED(AS_TR_CPP(have_${func}),1,[Define to 1 if you have the function ${func()}]) ]) AC_CHECK_FUNC($func) done ]) boinc-app-seti_8.00~svn3701.orig/m4/sah_links.m40000644000175000017500000000143310671336410021251 0ustar locutuslocutusAC_DEFUN([SAH_LINKS],[ AC_PATH_PROGS(LN,[ln cp copy]) if test -n "$LN" ; then AC_MSG_CHECKING(whether '$LN' works) if $LN config.sub erase.me$$ && \ test -e erase.me$$ && \ diff config.sub erase.me$$ >/dev/null 2>&5 then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) LN=cp fi /bin/rm erase.me$$ else LN=cp fi AC_PROG_LN_S if test -n "$LN_S" ; then AC_MSG_CHECKING(whether '$LN_S' really works or whether I'm deluding myself) if $LN_S config.sub erase.me$$ && \ test -e erase.me$$ && \ diff config.sub erase.me$$ >/dev/null 2>&5 then AC_MSG_RESULT(it works) else AC_MSG_RESULT(I'm deluding myself) LN_S=cp fi /bin/rm erase.me$$ else LN_S=cp fi ]) boinc-app-seti_8.00~svn3701.orig/m4/ax_check_glu.m40000644000175000017500000000330610671336410021713 0ustar locutuslocutusdnl Available from the GNU Autoconf Macro Archive at: dnl http://www.gnu.org/software/ac-archive/htmldoc/ax_check_glu.html dnl AC_DEFUN([AX_CHECK_GLU], [AC_REQUIRE([AX_CHECK_GL])dnl AC_REQUIRE([AC_PROG_CXX])dnl GLU_CFLAGS="${GL_CFLAGS}" if test "X${with_apple_opengl_framework}" != "Xyes"; then AC_CACHE_CHECK([for OpenGL Utility library], [ax_cv_check_glu_libglu], [ax_cv_check_glu_libglu="no" ax_save_CPPFLAGS="${CPPFLAGS}" CPPFLAGS="${GL_CFLAGS} ${CPPFLAGS}" ax_save_LIBS="${LIBS}" LIBS="" ax_check_libs="-lglu32 -lGLU" for ax_lib in ${ax_check_libs}; do if test X$ax_compiler_ms = Xyes; then ax_try_lib=`echo $ax_lib | sed -e 's/^-l//' -e 's/$/.lib/'` else ax_try_lib="${ax_lib}" fi LIBS="${ax_try_lib} ${GL_LIBS} ${ax_save_LIBS}" # # libGLU typically links with libstdc++ on POSIX platforms. However, # setting the language to C++ means that test program source is named # "conftest.cc"; and Microsoft cl doesn't know what to do with such a # file. # AC_LANG_PUSH([C++]) if test X$ax_compiler_ms = Xyes; then AC_LANG_PUSH([C]) fi AC_LINK_IFELSE( [AC_LANG_PROGRAM([[ # if HAVE_WINDOWS_H && defined(_WIN32) # include # endif # include ]], [[gluBeginCurve(0)]])], [ax_cv_check_glu_libglu="${ax_try_lib}"; break]) if test X$ax_compiler_ms = Xyes; then AC_LANG_POP([C]) fi AC_LANG_POP([C++]) done LIBS=${ax_save_LIBS} CPPFLAGS=${ax_save_CPPFLAGS}]) if test "X${ax_cv_check_glu_libglu}" = "Xno"; then no_glu="yes" GLU_CFLAGS="" GLU_LIBS="" else GLU_LIBS="${ax_cv_check_glu_libglu} ${GL_LIBS}" fi fi AC_SUBST([GLU_CFLAGS]) AC_SUBST([GLU_LIBS]) ]) boinc-app-seti_8.00~svn3701.orig/m4/optimizations.m40000644000175000017500000000610512635410232022205 0ustar locutuslocutusAC_DEFUN([SAH_OPTIMIZATIONS],[ if test x_$sah_opt_only_once = x_ ; then sah_opt_only_once=all_done AC_ARG_ENABLE([sse3], AC_HELP_STRING([--enable-sse3], [Use SSE3 optimizations]) ) if test x_$enable_sse3 = x_yes ; then AC_DEFINE_UNQUOTED([USE_SSE3],[1], [Define to 1 if you want to use SSE3 optimizations]) # put compiler specific flags here if test x_$ac_cv_c_compiler_gnu = x_yes ; then CFLAGS="-msse3 ${CFLAGS}" fi fi AC_ARG_ENABLE([sse2], AC_HELP_STRING([--enable-sse2], [Use SSE2 optimizations]) ) if test x_$enable_sse2 = x_yes ; then AC_DEFINE_UNQUOTED([USE_SSE2],[1], [Define to 1 if you want to use SSE2 optimizations]) # put compiler specific flags here if test x_$ac_cv_c_compiler_gnu = x_yes ; then CFLAGS="-msse2 ${CFLAGS}" if test -z "echo $CFLAGS | grep march=" ; then CFLAGS="-march=pentium4 ${CFLAGS}" fi fi fi AC_ARG_ENABLE([sse], AC_HELP_STRING([--enable-sse], [Use SSE optimizations]) ) if test x_$enable_sse = x_yes ; then AC_DEFINE_UNQUOTED([USE_SSE],[1], [Define to 1 if you want to use SSE optimizations]) # put compiler specific flags here if test x_$ac_cv_c_compiler_gnu = x_yes ; then CFLAGS="-march=pentium3 -msse -mfpmath=sse ${CFLAGS}" fi fi AC_ARG_ENABLE([mmx], AC_HELP_STRING([--enable-mmx], [Use MMX optimizations]) ) if test x_$enable_mmx = x_yes ; then AC_DEFINE_UNQUOTED([USE_MMX],[1], [Define to 1 if you want to use MMX optimizations]) # put compiler specific flags here if test x_$ac_cv_c_compiler_gnu = x_yes ; then CFLAGS="-march=pentium2 -mmmx -mfpmath=387 ${CFLAGS}" fi fi AC_ARG_ENABLE([3dnow], AC_HELP_STRING([--enable-3dnow], [Use 3dnow optimizations]) ) if test x_$enable_3dnow = x_yes ; then AC_DEFINE_UNQUOTED([USE_3DNOW],[1], [Define to 1 if you want to use 3D-Now optimizations]) # put compiler specific flags here if test x_$ac_cv_c_compiler_gnu = x_yes ; then CFLAGS="-march=pentium2 -m3dnow -mfpmath=387 ${CFLAGS}" fi fi AC_ARG_ENABLE([fast-math], AC_HELP_STRING([--enable-fast-math], [Use gcc -ffast-math optimization]) ) if test x_$enable_fast_math = x_yes ; then AC_DEFINE_UNQUOTED([USE_FAST_MATH],[1], [Define to 1 if you want to use the gcc -ffast-math optimization]) # put compiler specific flags here if test x_$ac_cv_c_compiler_gnu = x_yes ; then CFLAGS="${CFLAGS} -ffast-math" fi fi AC_ARG_ENABLE([altivec], AC_HELP_STRING([--enable-altivec], [Use altivec optimizations]) ) if test x_$enable_altivec = x_yes ; then AC_DEFINE_UNQUOTED([USE_ALTIVEC],[1], [Define to 1 if you want to use ALTIVEC optimizations]) # put compiler specific flags here if test x_$ac_cv_c_compiler_gnu = x_yes ; then SAH_CHECK_CFLAG([-faltivec],[CFLAGS="-faltivec ${CFLAGS}"]) SAH_CHECK_CFLAG([-maltivec],[CFLAGS="-maltivec ${CFLAGS}"]) SAH_CHECK_CFLAG([-mtune=G5],[CFLAGS="-mtune=G5 ${CFLAGS}"]) SAH_CHECK_CFLAG([-mcpu=powerpc],[CFLAGS="-mcpu=powerpc ${CFLAGS}"]) SAH_CHECK_LDFLAG([-framework Accelerate],[LDFLAGS="${LDFLAGS} -framework Accelerate"]) fi fi fi ]) boinc-app-seti_8.00~svn3701.orig/m4/sah_avx.m40000644000175000017500000000225212321065336020727 0ustar locutuslocutusAC_DEFUN([SAH_AVX],[ AC_LANG_PUSH(C) AC_MSG_CHECKING([if compiler supports -mavx]) save_cflags="${CFLAGS}" CFLAGS="-mavx" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[return 0;])],[ have_avx=yes ],[ have_avx=no ] ) AC_MSG_RESULT($have_avx) if test "$have_avx" = "yes" ; then AC_MSG_CHECKING([type of arg 2 of _mm256_maskstore_ps()]) for type in __m256d __m256i __m256 _m256d _m256i _m256 ; do AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #define __AVX__ 1 #if defined(HAVE_IMMINTRIN_H) #include #elif defined(HAVE_AVXINTRIN_H) #include #elif defined(HAVE_X86INTRIN_H) #include #elif defined(HAVE_INTRIN_H) #include #endif #if !defined(HAVE___M256) #define __m256 _m256 #endif float *a1; $type a2; __m256 a3; int foo(void) { _mm256_maskstore_ps(a1,a2,a3); return 0; } ]],[return foo();])], [ type_found=yes ], [ type_found=no ]) if test "${type_found}" = "yes" ; then break; fi done fi if test "${type_found}" = "yes" ; then AC_MSG_RESULT($type) avx_type=${type} else AC_MSG_RESULT(none) avx_type= fi CFLAGS="${save_cflags}" AC_LANG_POP(C) ]) boinc-app-seti_8.00~svn3701.orig/m4/sah_raw_ldflags.m40000644000175000017500000000021310671336410022411 0ustar locutuslocutusAC_DEFUN([SAH_RAW_LDFLAGS],[ $2=`echo $1 | $SED 's/-Wl,//g'` echo RAW_LDFLAGS:$2=`echo $1 | $SED 's/-Wl,//g'` >&5 AC_SUBST([$2]) ]) boinc-app-seti_8.00~svn3701.orig/m4/ax_check_glut.m40000644000175000017500000000362612633557720022115 0ustar locutuslocutusdnl Available from the GNU Autoconf Macro Archive at: dnl http://www.gnu.org/software/ac-archive/htmldoc/ax_check_glut.html dnl AC_DEFUN([AX_CHECK_GLUT], [AC_REQUIRE([AX_CHECK_GLU])dnl AC_REQUIRE([AC_PATH_XTRA])dnl if test "X$with_apple_opengl_framework" = "Xyes"; then GLUT_CFLAGS="${GLU_CFLAGS}" GLUT_LIBS="-framework GLUT -lobjc ${GL_LIBS}" else GLUT_CFLAGS=${GLU_CFLAGS} GLUT_LIBS=${GLU_LIBS} # # If X is present, assume GLUT depends on it. # if test "X${no_x}" != "Xyes"; then GLUT_LIBS="${X_PRE_LIBS} -lXmu -lXi ${X_EXTRA_LIBS} ${GLUT_LIBS}" fi # # If were running under windows assume we need GDI32 and WinMM # if echo $host_os | egrep '^mingw|^winnt' > /dev/null ; then GLUT_LIBS="${GLUT_LIBS} -lgdi32 -lwinmm" fi AC_LANG_PUSH(C) ax_save_CPPFLAGS="${CPPFLAGS}" CPPFLAGS="${GLUT_CFLAGS} ${CPPFLAGS}" AC_CACHE_CHECK([for GLUT library], [ax_cv_check_glut_libglut], [ax_cv_check_glut_libglut="no" ax_save_LIBS="${LIBS}" LIBS="" ax_check_libs="-lglut32 -lglut -lfreeglut_static -lfreeglut" for ax_lib in ${ax_check_libs}; do if test X$ax_compiler_ms = Xyes; then ax_try_lib=`echo $ax_lib | sed -e 's/^-l//' -e 's/$/.lib/'` else ax_try_lib="${ax_lib}" fi LIBS="-L${prefix}/lib ${ax_try_lib} ${GLUT_LIBS} ${ax_save_LIBS}" AC_LINK_IFELSE( [AC_LANG_PROGRAM([[ #define FREEGLUT_STATIC 1 # if HAVE_WINDOWS_H && (defined(_WIN32) || defined(CYGWIN_USE_WIN32)) # include # endif # include ]], [[glutMainLoop()]])], [ax_cv_check_glut_libglut="-L${prefix}/lib ${ax_try_lib}"; break]) done LIBS=${ax_save_LIBS} ]) CPPFLAGS="${ax_save_CPPFLAGS}" AC_LANG_POP(C) if test "X${ax_cv_check_glut_libglut}" = "Xno"; then no_glut="yes" GLUT_CFLAGS="" GLUT_LIBS="" else GLUT_LIBS="${ax_cv_check_glut_libglut} ${GLUT_LIBS}" fi fi AC_SUBST([GLUT_CFLAGS]) AC_SUBST([GLUT_LIBS]) ])dnl boinc-app-seti_8.00~svn3701.orig/m4/sah_check_jpeglib.m40000644000175000017500000000206310671336410022702 0ustar locutuslocutusAC_DEFUN([SAH_CHECK_JPEGLIB],[ AC_ARG_WITH([my-libjpeg], AC_HELP_STRING([--with-my-libjpeg],[use the jpeglib that is distributed with setiatthome]), [use_my_libjpeg="$withval"]) if test "x${use_my_libjpeg}" = "xyes" ; then LIBS="-L`pwd`/jpeglib ${LIBS}" CFLAGS="${CFLAGS} -I`pwd`/jpeglib" sah_cv_lib_jpeg_jpeg_start_decompress="`pwd`/jpeglib/libjpeg.a" sah_cv_lib_jpeg_fopen="`pwd`/jpeglib/libjpeg.a" sah_cv_static_lib_jpeg_jpeg_start_decompress="$sah_cv_lib_jpeg_jpeg_start_decompress" sah_cv_static_lib_jpeg_fopen="$sah_cv_lib_jpeg_fopen" if test -f "${sah_cv_lib_jpeg_fopen}" ; then /bin/rm -f "${sah_cv_lib_jpeg_fopen}" fi echo "int foo() { return 0; }" >foo.c $CC -c foo.c $AR cr "${sah_cv_lib_jpeg_fopen}" foo.$OBJEXT /bin/rm foo.$OBJEXT foo.c $RANLIB "${sah_cv_lib_jpeg_fopen}" fi SAH_CHECK_LIB([jpeg], [jpeg_start_decompress], AC_DEFINE([HAVE_LIBJPEG],[1],[Define to 1 if you have the jpeg library])) AM_CONDITIONAL(USE_MY_LIBJPEG, [test "x${use_my_libjpeg}" = "xyes" -o "${sah_cv_lib_jpeg_jpeg_start_decompress}" = "no"]) ]) boinc-app-seti_8.00~svn3701.orig/m4/boinc_platform.m40000644000175000017500000000470211061525167022301 0ustar locutuslocutusAC_DEFUN([BOINC_PLATFORM],[ AC_ARG_WITH([boinc-platform], AC_HELP_STRING([--with-boinc-platform], [override the default boinc platform]), [boinc_platform="$withval"], [boinc_platform=]) AC_ARG_WITH([boinc-alt-platform], AC_HELP_STRING([--with-boinc-alt-platform], [override the boinc alternate platform]), [boinc_alt_platform="$withval"], [boinc_alt_platform=]) AC_MSG_CHECKING([boinc platform]) if test -z "${boinc_platform}" ; then boinc_platform=`echo $target | $SED -e 's/amd64/x86_64/' -e 's/portbld/pc/' -e 's/redhat/pc/' -e 's/x86_64-unknown/x86_64-pc/' -e 's/[[0-9]]$//' -e 's/[[0-9]]$//' -e 's/\.$//' -e 's/[[0-9]]$//' -e 's/\.$//' -e 's/[[0-9]]$//'` case "${boinc_platform}" in sparc-sun-solaris) if test "$COMPILER_MODEL_BITS" = "64" ; then boinc_platform=`echo $boinc_platform | $SED 's/sparc/sparc64/'` if test -z "$boinc_alt_platform" ; then boinc_alt_platform=sparc-sun-solaris fi elif test -z "$boinc_alt_platform" ; then boinc_alt_platform=sparc-sun-solaris2.7 fi ;; x86_64*linux-gnu) if test "$COMPILER_MODEL_BITS" = "32" ; then boinc_platform="i686-pc-linux-gnu" elif test -z "$boinc_alt_platform" ; then boinc_alt_platform="i686-pc-linux-gnu" fi ;; powerpc-apple-darwin) if test "$COMPILER_MODEL_BITS" = "64" ; then boinc_platform="powerpc64-apple-darwin" if test -z "$boinc_alt_platform" ; then boinc_alt_platform="powerpc-apple-darwin" fi fi ;; hppa*-hp-hpux*) if test "$COMPILER_MODEL_BITS" = "64" ; then boinc_platform="hppa64-hp-hpux" if test -z "${boinc_alt_platform}" ; then boinc_alt_platform="hppa-hp-hpux" fi else boinc_platform="hppa-hp-hpux" fi ;; ia64-hp-hpux*) boinc_platform="ia64-hp-hpux" ;; esac fi AC_DEFINE_UNQUOTED([HOSTTYPE],"$boinc_platform",[Platform identification used to identify applications for this BOINC core client]) AC_SUBST([boinc_platform],$boinc_platform) AC_MSG_RESULT([$boinc_platform]) AC_MSG_CHECKING([alternate boinc platform]) if test -n "$boinc_alt_platform" ; then AC_DEFINE_UNQUOTED([HOSTTYPEALT],"$boinc_alt_platform",[Alternate identification used to identify applications for this BOINC core client]) AC_SUBST([boinc_alt_platform],$boinc_alt_platform) AC_MSG_RESULT($boinc_alt_platform) else AC_MSG_RESULT(none) fi ]) boinc-app-seti_8.00~svn3701.orig/m4/ax_check_gl.m40000644000175000017500000000437410671336410021534 0ustar locutuslocutusdnl Available from the GNU Autoconf Macro Archive at: dnl http://www.gnu.org/software/ac-archive/htmldoc/ax_check_gl.html dnl AC_DEFUN([AX_CHECK_GL], [AC_REQUIRE([AC_PATH_X])dnl AC_REQUIRE([ACX_PTHREAD])dnl # # There isn't a reliable way to know we should use the Apple OpenGL framework # without a configure option. A Mac OS X user may have installed an # alternative GL implementation (e.g., Mesa), which may or may not depend on X. # AC_ARG_WITH([apple-opengl-framework], [AC_HELP_STRING([--with-apple-opengl-framework], [use Apple OpenGL framework (Mac OS X only)])]) if test "X$with_apple_opengl_framework" = "Xyes"; then AC_DEFINE([HAVE_APPLE_OPENGL_FRAMEWORK], [1], [Use the Apple OpenGL framework.]) GL_LIBS="-framework OpenGL" else AC_LANG_PUSH(C) AX_LANG_COMPILER_MS if test X$ax_compiler_ms = Xno; then GL_CFLAGS="${PTHREAD_CFLAGS}" GL_LIBS="${PTHREAD_LIBS} -lm" fi # # Use x_includes and x_libraries if they have been set (presumably by # AC_PATH_X). # if test "X$no_x" != "Xyes"; then if test -n "$x_includes"; then GL_CFLAGS="-I${x_includes} ${GL_CFLAGS}" fi if test -n "$x_libraries"; then GL_LIBS="-L${x_libraries} -lX11 ${GL_LIBS}" fi fi AC_CHECK_HEADERS([windows.h]) AC_CACHE_CHECK([for OpenGL library], [ax_cv_check_gl_libgl], [ax_cv_check_gl_libgl="no" ax_save_CPPFLAGS="${CPPFLAGS}" CPPFLAGS="${GL_CFLAGS} ${CPPFLAGS}" ax_save_LIBS="${LIBS}" LIBS="" ax_check_libs="-lopengl32 -lGL" for ax_lib in ${ax_check_libs}; do if test X$ax_compiler_ms = Xyes; then ax_try_lib=`echo $ax_lib | sed -e 's/^-l//' -e 's/$/.lib/'` else ax_try_lib="${ax_lib}" fi LIBS="${ax_try_lib} ${GL_LIBS} ${ax_save_LIBS}" AC_LINK_IFELSE( [AC_LANG_PROGRAM([[ # if HAVE_WINDOWS_H && defined(_WIN32) # include # endif # include ]], [[glBegin(0)]])], [ax_cv_check_gl_libgl="${ax_try_lib}"; break]) done LIBS=${ax_save_LIBS} CPPFLAGS=${ax_save_CPPFLAGS}]) if test "X${ax_cv_check_gl_libgl}" = "Xno"; then no_gl="yes" GL_CFLAGS="" GL_LIBS="" else GL_LIBS="${ax_cv_check_gl_libgl} ${GL_LIBS}" fi AC_LANG_POP(C) fi AC_SUBST([GL_CFLAGS]) AC_SUBST([GL_LIBS]) ])dnl boinc-app-seti_8.00~svn3701.orig/m4/sah_check_lib.m40000644000175000017500000003110711516142274022037 0ustar locutuslocutus AC_DEFUN([SAH_CHECK_LIB],[ alib="$1" # check to see if it is in our static list for slib in ${STATIC_LIB_LIST}; do lib_is_static="no" tmp_pattern=`echo s/x${slib}// | sed 's/\*/.*/'` if test -z "`echo x${alib} | sed ${tmp_pattern}`" then SAH_STATIC_LIB_REQUIRED(${alib},[$2],[ lib_is_static="yes" sah_lib_last="${sah_static_lib_last}" $3 ],[$4],[$5],[$6]) break; fi done if test "${lib_is_static}" = "no" ; then SAH_DYNAMIC_LIB_REQUIRED(${alib},[$2],[ sah_lib_last="${sah_dynamic_lib_last}" $3 ],[$4],[$5],[$6]) fi ]) AC_DEFUN([SAH_CHECK_LDFLAG],[ sv_ldflags="${LDFLAGS}" AC_MSG_CHECKING(if linker works with $1 flag) LDFLAGS="${LDFLAGS} $1" AC_LINK_IFELSE([ AC_LANG_PROGRAM([[ #define CONFIG_TEST int foo() {return 1;} ]], [ return foo(); ])], [ AC_MSG_RESULT(yes) $2 ], [ AC_MSG_RESULT(no) LDFLAGS="${sv_ldflags}" $3 ] ) ]) AC_DEFUN([SAH_CHECK_CFLAG],[ AC_LANG_PUSH(C) sv_cflags="${CFLAGS}" AC_MSG_CHECKING(if compiler works with $1 flag) CFLAGS="${CFLAGS} $1" AC_COMPILE_IFELSE([ AC_LANG_PROGRAM([[ #define CONFIG_TEST int foo() {return 1;} ]], [ return foo(); ])], [ AC_MSG_RESULT(yes) $2 ], [ AC_MSG_RESULT(no) CFLAGS="${sv_ldflags}" $3 ] ) AC_LANG_POP ]) AC_DEFUN([SAH_LINKAGE_FLAGS],[ AC_ARG_ENABLE(static_client, AC_HELP_STRING([--disable-static-linkage], [disable static linking of certain libraries]), [ disable_static_linkage=yes enable_client_release=no ], [ disable_static_linkage=no enable_client_release=yes ]) if test "${disable_static_linkage}" = "yes" then ld_static_option="" ld_dynamic_option="" LD_EXPORT_DYNAMIC="" else if test -z "${ld_static_option}" then case $target in *linux* | *solaris* | *cygwin* ) AC_MSG_CHECKING([${CC} flags for static linkage ...]) ld_static_option="-Wl,-Bstatic" AC_MSG_RESULT($ld_static_option) AC_MSG_CHECKING([${CC} flags for dynamic linkage ...]) ld_dynamic_option="-Wl,-Bdynamic" AC_MSG_RESULT($ld_dynamic_option) ;; *darwin* ) AC_MSG_CHECKING([${CC} flags for static linkage ...]) ld_static_option="-static" AC_MSG_RESULT($ld_static_option) AC_MSG_CHECKING([${CC} flags for dynamic linkage ...]) ld_dynamic_option="-dynamic" AC_MSG_RESULT($ld_dynamic_option) ;; *) if test -z "${dummy_ld_variable_gfdsahjf}" then dummy_ld_variable_gfdsahjf="been there done that" AC_MSG_CHECKING([${CC} flags for static linkage ...]) AC_MSG_RESULT(unknown) AC_MSG_CHECKING([${CC} flags for dynamic linkage ...]) AC_MSG_RESULT(unknown) fi ;; esac AC_MSG_CHECKING([${CC} flags for exporting dynamic symbols from an executable ...]) LD_EXPORT_DYNAMIC="${export_dynamic_flag_spec}" if test -z "${LD_EXPORT_DYNAMIC}" ; then case $target in *cygwin*) LD_EXPORT_DYNAMIC="-Wl,--export-all-symbols" AC_MSG_RESULT(${LD_EXPORT_DYNAMIC}) ;; *linux*) AC_MSG_RESULT(-rdynamic) LD_EXPORT_DYNAMIC="-rdynamic" ;; *) AC_MSG_RESULT(none required) LD_EXPORT_DYNAMIC= ;; esac fi fi fi if test -z "${LIBEXT}"; then SAH_LIBEXT fi if test -z "${DLLEXT}"; then SAH_DLLEXT fi AC_SUBST(LD_EXPORT_DYNAMIC) ]) # use this function in order to find a library that we require to be static. # we will check in the following order.... # 1) files named lib{name}.a # 2) files named {name}.a # 3) linking with the static flags "$STATIC_FLAGS -l{name}" AC_DEFUN([SAH_STATIC_LIB_REQUIRED],[ SAH_LINKAGE_FLAGS # upercase the library name for our definition ac_uc_defn=HAVE_LIB`echo $1 | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` # Build our cache variable names STATIC_LIB_LIST="${STATIC_LIB_LIST} $1" varname=`echo sah_cv_static_lib_$1_$2 | $as_tr_sh` var2=`echo sah_cv_static_lib_$1_fopen | $as_tr_sh` if test "$2" != "fopen" ; then tmp_msg="for $2 in static library $1" else tmp_msg="for static library $1" fi AC_CACHE_CHECK([$tmp_msg], [$varname], [ tmp_res="no" # # check if we want to actually do all this. if test "${disable_static_linkage}" = "yes" then sah_static_checklibs="-l$1" else sah_static_checklibs="lib$1.${LIBEXT} $1.${LIBEXT} -l$1" fi sah_save_libs="${LIBS}" for libname in ${sah_static_checklibs} do SAH_FIND_STATIC_LIB(${libname}) if test -n "${tmp_lib_name}" then LIBS="${tmp_lib_name} ${sah_save_libs} $5 $6" AC_LINK_IFELSE([ AC_LANG_PROGRAM([[ #define CONFIG_TEST 1 #ifdef __cplusplus extern "C" { #endif char $2 (); #ifdef __cplusplus } #endif ]], [ $2 (); ])], [ tmp_res="${tmp_lib_name}" ] ) fi if test "${tmp_res}" != "no" then break fi done LIBS="${sah_save_libs}" eval ${varname}='"'${tmp_res}'"' eval ${var2}='"'${tmp_res}'"' ]) # # save the result for use by the caller sah_static_lib_last="`eval echo '${'$varname'}'`" # if test "${sah_static_lib_last}" != "no" then tmp_pattern=`echo "${sah_static_lib_last}" | sed 's/-/./'` if echo ${LIBS} | grep "${tmp_pattern}" > /dev/null then echo Already in LIBS, not adding... >&5 else LIBS="${sah_static_lib_last} ${LIBS}" fi AC_DEFINE_UNQUOTED([$ac_uc_defn], [1], [Define to 1 if the $1 library has the function $2] ) $3 else $4 echo > /dev/null fi ]) # use this function in order to find a library that we require to be dynamic. # we will check in the following order.... # 1) linking with the dynamic flags "$DYNAMIC_FLAGS -l{name}" # 2) linking with no flags "-l{name}" AC_DEFUN([SAH_DYNAMIC_LIB_REQUIRED],[ SAH_LINKAGE_FLAGS # upercase the library name for our definition ac_uc_defn=HAVE_LIB`echo $1 | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` # Build our cache variable names DYNAMIC_LIB_LIST="${DYNAMIC_LIB_LIST} $1" varname=`echo sah_cv_dynamic_lib_$1_$2 | $as_tr_sh` var2=`echo sah_cv_dynamic_lib_$1_fopen | $as_tr_sh` if test "$2" != "fopen" ; then tmp_msg="for $2 in dynamic library $1" else tmp_msg="for dynamic library $1" fi AC_CACHE_CHECK([$tmp_msg], [$varname], [ tmp_res="no" # # check if we want to actually do all this. if test "${disable_static_linkage}" = "yes" then sah_dynamic_checklibs="-l$1 -l$1.${DLLEXT}" else sah_dynamic_checklibs="-l$1" fi sah_save_libs="${LIBS}" for libname in ${sah_dynamic_checklibs} do tmp_lib_name="${libname}" LIBS="${ld_dynamic_option} ${tmp_lib_name} ${sah_save_libs} $5 $6" AC_LINK_IFELSE([ AC_LANG_PROGRAM([[ #define CONFIG_TEST 1 #ifdef __cplusplus extern "C" { #endif char $2 (); #ifdef __cplusplus } #endif ]], [ $2 (); ]) ], [ tmp_res="${ld_dynamic_option} ${tmp_lib_name}" ]) if test "${tmp_res}" = "no" then tmp_lib_name="${libname}" LIBS="${tmp_lib_name} ${sah_save_libs}" AC_LINK_IFELSE([ AC_LANG_PROGRAM([[ #define CONFIG_TEST 1 #ifdef __cplusplus extern "C" { #endif char $2 (); #ifdef __cplusplus } #endif ]], [ $2 (); ]) ], [ tmp_res="${tmp_lib_name}" ]) fi done LIBS="${sah_save_libs}" eval ${varname}='"'${tmp_res}'"' eval ${var2}='"'${tmp_res}'"' ]) # # save the result for use by the caller sah_dynamic_lib_last="`eval echo '${'$varname'}'`" # if test "${sah_dynamic_lib_last}" != "no" then tmp_pattern=`echo "${sah_dynamic_lib_last}" | sed 's/-/./'` if echo ${LIBS} | grep "${tmp_pattern}" > /dev/null then echo Already in LIBS, not adding... >&5 else LIBS="${sah_dynamic_lib_last} ${LIBS}" fi AC_DEFINE_UNQUOTED([$ac_uc_defn], [1], [Define to 1 if the $1 library has the function $2] ) $3 else $4 echo > /dev/null fi ]) AC_DEFUN([SAH_STATIC_LIB],[ SAH_STATIC_LIB_REQUIRED([$1],[$2]) sah_lib_last="${sah_static_lib_last}" if test "${sah_lib_last}" = "no" ; then SAH_DYNAMIC_LIB_REQUIRED([$1],[$2]) sah_lib_last=${sah_dynamic_lib_last} fi if test "${sah_lib_last}" != "no" ; then $3 echo > /dev/null else $4 echo > /dev/null fi ]) AC_DEFUN([SAH_DYNAMIC_LIB],[ SAH_DYNAMIC_LIB_REQUIRED([$1],[$2]) sah_lib_last="${sah_dynamic_lib_last}" if test "${sah_lib_last}" = "no" ; then SAH_STATIC_LIB_REQUIRED([$1],[$2]) sah_lib_last=${sah_static_lib_last} fi if test "${sah_lib_last}" != "no" ; then $3 echo > /dev/null else $4 echo > /dev/null fi ]) #The SAH_FIND_STATIC_LIB macro searches the LD_LIBRARY_PATH or equivalent #in order to find a static version of the library being loaded. AC_DEFUN([SAH_FIND_STATIC_LIB],[ # libtool sets up the variable shlibpath_var which holds the name of the # LIB_PATH variable. We also want to strip the sparcv9 and 64s from the # path, because we'll add them again later strip_pattern="s/sparcv9//g; s/lib64/lib/g; s/lib\/64/lib/g" tmp_libpath=`eval echo '${'$shlibpath_var'}' | sed "${strip_pattern}"` # in cygwin, the DLLs are in the path, but the static libraries are elsewhere. # Here's an educated guess. if test "${shlibpath_var}" = "PATH" then tmp_libpath=`echo ${PATH} | sed 's/\/bin/\/lib/g'` tmp_libpath="${tmp_libpath}:${PATH}" fi gcc_version=`${CC} -v 2>&1 | grep "gcc version" | $AWK '{print $[]3}'` for gcc_host in `${CC} -v 2>&1 | grep host` --host=${ac_cv_target} do if test -n "`echo x$gcc_host | grep x--host=`" then gcc_host="`echo $gcc_host | sed 's/--host=//'`" break fi done gcc_specs=`${CC} -v 2>&1 | grep specs | $AWK '{print $[]4}' | sed 's/\/specs//'` for dirs in `${CC} -v 2>&1 | grep prefix` --prefix=${gcc_specs} do if test -n "`echo x$dirs | grep x--prefix=`" then gcc_prefix="`echo $dirs | sed 's/--prefix=//'`" tmp_libpath="${gcc_specs}:${gcc_prefix}/lib:${gcc_prefix}/lib/gcc-lib/${gcc_host}/${gcc_version}:${tmp_libpath}" break fi done gcc_lib_dirs=`${CC} -print-search-dirs 2>&1 | grep libraries: | sed 's/^libraries: =//'` tmp_libpath="${gcc_lib_dirs}:${tmp_libpath}" # Put machine/arch specific tweaks to the libpath here. if test -z "${COMPILER_MODEL_BITS}" then SAH_DEFAULT_BITNESS fi case $target in x86_64-*-linux*) if test -n "${COMPILER_MODEL_BITS}" then tmp_pattern="s/\/lib/\/lib${COMPILER_MODEL_BITS}/g" tmp_pattern_b="s/${COMPILER_MODEL_BITS}${COMPILER_MODEL_BITS}/${COMPILER_MODEL_BITS}/g" abcd_q=`echo ${tmp_libpath} | sed ${tmp_pattern} | sed ${tmp_pattern_b} ` case ${COMPILER_MODEL_BITS} in 32) gcc_host_dirs=`echo ${gcc_prefix}/lib/gcc*/i[3456]86*linux*/${gcc_version}` ;; 64) gcc_host_dirs=`echo ${gcc_prefix}/lib/gcc-lib/x86_64*linux*/${gcc_version}` ;; esac tmp_libpath="${abcd_q}:${tmp_libpath}" for tmp_dir in ${gcc_host_dirs} do tmp_libpath="${tmp_dir}:${tmp_libpath}" done fi ;; sparc*-sun-solaris*) if test -n "${COMPILER_MODEL_BITS}" then tmp_pattern="s/\/lib/\/lib\/${COMPILER_MODEL_BITS}/g" tmp_pattern_b="s/${COMPILER_MODEL_BITS}\/${COMPILER_MODEL_BITS}/${COMPILER_MODEL_BITS}/g" abcd_q=`echo ${tmp_libpath} | sed ${tmp_pattern} | sed ${tmp_pattern_b}` case ${COMPILER_MODEL_BITS} in 64) tmp_arch="sparcv9" ;; 32) tmp_arch= ;; esac abcd_r="/notadir/" for tmp_dir in `echo ${tmp_libpath} | sed 's/\:/ /g'` do abcd_r="${abcd_r}:${tmp_dir}/${tmp_arch}" done tmp_libpath="${abcd_r}:${abcd_q}:${tmp_libpath}" fi ;; *) echo > /dev/null ;; esac if test -n "`echo x$1 | grep x-l`" then # in the -l case, don't search, just use the ld_static_option (usually # -Wl,-B static tmp_lib_name="${ld_static_option} $1" else # we also want to check the system config files for library dirs. tmp_dir_list= if test -e /etc/ld.so.conf then tmp_dir_list=`cat /etc/ld.so.conf` else if test -e /var/ld/ld.config then tmp_dir_list=`cat /var/ld/ld.config` fi fi tmp_dir_list=`echo ${tmp_libpath}:/lib:/usr/lib:/usr/ucb/lib:/usr/local/lib:/opt/misc/lib:${tmp_dir_list} | $AWK -F: '{for (i=1;i<(NF+1);i++) { print $[]i; }}'` tmp_lib_name= # now that we know where we are looking, find our library for tmp_dir in $tmp_dir_list do if test -e $tmp_dir/$1 then tmp_lib_name=${tmp_dir}/$1 break fi done fi ]) boinc-app-seti_8.00~svn3701.orig/m4/ax_lang_compiler_ms.m40000644000175000017500000000101310671336410023272 0ustar locutuslocutusdnl Available from the GNU Autoconf Macro Archive at: dnl http://www.gnu.org/software/ac-archive/htmldoc/ax_lang_compiler_ms.html dnl AC_DEFUN([AX_LANG_COMPILER_MS], [AC_CACHE_CHECK([whether we are using the Microsoft _AC_LANG compiler], [ax_cv_[]_AC_LANG_ABBREV[]_compiler_ms], [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[#ifndef _MSC_VER choke me #endif ]])], [ax_compiler_ms=yes], [ax_compiler_ms=no]) ax_cv_[]_AC_LANG_ABBREV[]_compiler_ms=$ax_compiler_ms ])]) boinc-app-seti_8.00~svn3701.orig/m4/sah_asmlib.m40000644000175000017500000000314411062236673021406 0ustar locutuslocutusAC_DEFUN([SAH_CHECK_ASMLIB],[ AC_LANG_PUSH([C++]) AC_MSG_CHECKING([asmlib]) AC_ARG_ENABLE(asmlib, AC_HELP_STRING([--disable-asmlib], [disable use of asmlib for CPU identification (iX86 only)]), [ disable_asmlib=yes enable_asmlib=no ], [ disable_asmlib=no enable_asmlib=yes ] ) if test -z "`echo $target | grep '[3456]86'`" ; then disable_asmlib=yes enable_asmlib=no fi ASMLIB_CFLAGS= ASMLIB_LDFLAGS= ASMLIB_LIBS= asmlib_save_CFLAGS="${CFLAGS}" asmlib_save_CXXFLAGS="${CXXFLAGS}" asmlib_save_LDFLAGS="${LDFLAGS}" asmlib_save_LIBS="${LIBS}" asmlib_dir="${SAH_TOP_DIR}/client/vector/" asmlib_works=no if test "${disable_asmlib}" != "yes" ; then CFLAGS="${CFLAGS} -I${asmlib_dir}" CXXFLAGS="${CXXFLAGS} -I${asmlib_dir}" for ASMLIB_LIBS in ${asmlib_dir}/asmlibe.a ${asmlib_dir}/asmlibm.a ${asmlib_dir}/asmlibo.lib do LIBS="${ASMLIB_LIBS} ${asmlib_save_LIBS}" AC_LINK_IFELSE( [ AC_LANG_PROGRAM( [[#include "asmlib.h"]], [[InstructionSet()]] ) ], [asmlib_works=yes; break] ) done fi if test "${asmlib_works}" = "yes" ; then AC_DEFINE_UNQUOTED([USE_ASMLIB],[1], [Define to 1 to use ASMLIB to determine processor capabilities]) AC_MSG_RESULT([$ASMLIB_LIBS]) else ASMLIB_LIBS= AC_MSG_RESULT([no]) fi CFLAGS="${asmlib_save_CFLAGS}" CXXFLAGS="${asmlib_save_CXXFLAGS}" LDFLAGS="${asmlib_save_LDFLAGS}" LIBS="${asmlib_save_LIBS}" AC_SUBST([ASMLIB_LDFLAGS]) AC_SUBST([ASMLIB_CFLAGS]) AC_SUBST([ASMLIB_LIBS]) AC_LANG_POP([C++]) ]) boinc-app-seti_8.00~svn3701.orig/m4/ax_pthread.m40000644000175000017500000003126712164634520021427 0ustar locutuslocutus# =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_pthread.html # =========================================================================== # # SYNOPSIS # # AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) # # DESCRIPTION # # This macro figures out how to build C programs using POSIX threads. It # sets the PTHREAD_LIBS output variable to the threads library and linker # flags, and the PTHREAD_CFLAGS output variable to any special C compiler # flags that are needed. (The user can also force certain compiler # flags/libs to be tested by setting these environment variables.) # # Also sets PTHREAD_CC to any special C compiler that is needed for # multi-threaded programs (defaults to the value of CC otherwise). (This # is necessary on AIX to use the special cc_r compiler alias.) # # NOTE: You are assumed to not only compile your program with these flags, # but also link it with them as well. e.g. you should link with # $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS # # If you are only building threads programs, you may wish to use these # variables in your default LIBS, CFLAGS, and CC: # # LIBS="$PTHREAD_LIBS $LIBS" # CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # CC="$PTHREAD_CC" # # In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant # has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name # (e.g. PTHREAD_CREATE_UNDETACHED on AIX). # # Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the # PTHREAD_PRIO_INHERIT symbol is defined when compiling with # PTHREAD_CFLAGS. # # ACTION-IF-FOUND is a list of shell commands to run if a threads library # is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it # is not found. If ACTION-IF-FOUND is not specified, the default action # will define HAVE_PTHREAD. # # Please let the authors know if this macro fails on any platform, or if # you have any other suggestions or comments. This macro was based on work # by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help # from M. Frigo), as well as ac_pthread and hb_pthread macros posted by # Alejandro Forero Cuervo to the autoconf macro repository. We are also # grateful for the helpful feedback of numerous users. # # Updated for Autoconf 2.68 by Daniel Richard G. # # LICENSE # # Copyright (c) 2008 Steven G. Johnson # Copyright (c) 2011 Daniel Richard G. # # 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 3 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, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 20 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) AC_DEFUN([AX_PTHREAD], [ AC_REQUIRE([AC_CANONICAL_HOST]) AC_LANG_PUSH([C]) ax_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h # requires special compiler flags (e.g. on True64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) AC_TRY_LINK_FUNC(pthread_join, ax_pthread_ok=yes) AC_MSG_RESULT($ax_pthread_ok) if test x"$ax_pthread_ok" = xno; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" fi # We must check for the threads library under a number of different # names; the ordering is very important because some systems # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). # Create a list of thread flags to try. Items starting with a "-" are # C compiler flags, and other items are library names, except for "none" # which indicates that we try without any flags at all, and "pthread-config" # which is a program returning the flags for the Pth emulation library. ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: # pthreads: AIX (must check this before -lpthread) # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) # -pthreads: Solaris/gcc # -mthreads: Mingw32/gcc, Lynx/gcc # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads too; # also defines -D_REENTRANT) # ... -mt is also the pthreads flag for HP/aCC # pthread: Linux, etcetera # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) case ${host_os} in solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based # tests will erroneously succeed. (We need to link with -pthreads/-mt/ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather # a function called by this macro, so we could check for that, but # who knows whether they'll stub that too in a future libc.) So, # we'll just look for -pthreads and -lpthread first: ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags" ;; darwin*) ax_pthread_flags="-pthread $ax_pthread_flags" ;; esac if test x"$ax_pthread_ok" = xno; then for flag in $ax_pthread_flags; do case $flag in none) AC_MSG_CHECKING([whether pthreads work without any flags]) ;; -*) AC_MSG_CHECKING([whether pthreads work with $flag]) PTHREAD_CFLAGS="$flag" ;; pthread-config) AC_CHECK_PROG(ax_pthread_config, pthread-config, yes, no) if test x"$ax_pthread_config" = xno; then continue; fi PTHREAD_CFLAGS="`pthread-config --cflags`" PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" ;; *) AC_MSG_CHECKING([for the pthreads library -l$flag]) PTHREAD_LIBS="-l$flag" ;; esac save_LIBS="$LIBS" save_CFLAGS="$CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we # need a special flag -Kthread to make this header compile.) # We check for pthread_join because it is in -lpthread on IRIX # while pthread_create is in libc. We check for pthread_attr_init # due to DEC craziness with -lpthreads. We check for # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. AC_LINK_IFELSE([AC_LANG_PROGRAM([#include static void routine(void *a) { a = 0; } static void *start_routine(void *a) { return a; }], [pthread_t th; pthread_attr_t attr; pthread_create(&th, 0, start_routine, 0); pthread_join(th, 0); pthread_attr_init(&attr); pthread_cleanup_push(routine, 0); pthread_cleanup_pop(0) /* ; */])], [ax_pthread_ok=yes], []) LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" AC_MSG_RESULT($ax_pthread_ok) if test "x$ax_pthread_ok" = xyes; then break; fi PTHREAD_LIBS="" PTHREAD_CFLAGS="" done fi # Various other checks: if test "x$ax_pthread_ok" = xyes; then save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. AC_MSG_CHECKING([for joinable pthread attribute]) attr_name=unknown for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], [int attr = $attr; return attr /* ; */])], [attr_name=$attr; break], []) done AC_MSG_RESULT($attr_name) if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, [Define to necessary symbol if this constant uses a non-standard name on your system.]) fi AC_MSG_CHECKING([if more special flags are required for pthreads]) flag=no case ${host_os} in aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";; osf* | hpux*) flag="-D_REENTRANT";; solaris*) if test "$GCC" = "yes"; then flag="-D_REENTRANT" else flag="-mt -D_REENTRANT" fi ;; esac AC_MSG_RESULT(${flag}) if test "x$flag" != xno; then PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" fi AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], ax_cv_PTHREAD_PRIO_INHERIT, [ AC_LINK_IFELSE([ AC_LANG_PROGRAM([[#include ]], [[int i = PTHREAD_PRIO_INHERIT;]])], [ax_cv_PTHREAD_PRIO_INHERIT=yes], [ax_cv_PTHREAD_PRIO_INHERIT=no]) ]) AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"], AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.])) LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" # More AIX lossage: compile with *_r variant if test "x$GCC" != xyes; then case $host_os in aix*) AS_CASE(["x/$CC"], [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], [#handle absolute path differently from PATH based program lookup AS_CASE(["x$CC"], [x/*], [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) ;; esac fi fi test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" AC_SUBST(PTHREAD_LIBS) AC_SUBST(PTHREAD_CFLAGS) AC_SUBST(PTHREAD_CC) # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test x"$ax_pthread_ok" = xyes; then ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) : else ax_pthread_ok=no $2 fi AC_LANG_POP ])dnl AX_PTHREAD boinc-app-seti_8.00~svn3701.orig/m4/sah_check_healpix.m40000644000175000017500000000241211256261332022716 0ustar locutuslocutus# SETI_BOINC is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free # Software Foundation; either version 2, or (at your option) any later # version. AC_PREREQ([2.54]) AC_DEFUN([SAH_CHECK_HEALPIX],[ AC_ARG_VAR([HEALPIX],[HEALPIX directory]) if test -z "$HEAD" then AC_PATH_PROG(HEAD,head) fi if test -z "$FIND" then AC_PATH_PROG(FIND,find) fi thisdir=`pwd` AC_MSG_CHECKING([for HEALPIX]) healpix_search_path=[`echo $HEALPIX [Hh]ealpix* ../[Hh]ealpix* ../lib/[Hh]ealpix* $HOME/lib/[Hh]ealpix* /usr/local/[Hh]ealpix* /usr/local`] for healpix_dir in $healpix_search_path do if test -d $healpix_dir/lib then if test -f $healpix_dir/lib/libchealpix.a then cd $healpix_dir HEALPIX=`pwd` cd $thisdir break else if $FIND $healpix_dir -name "lib/libchealpix.a" 2>/dev/null >/dev/null then HEALPIX=`$FIND $healpix_dir -name "lib/libchealpix.a" -print | $HEAD -1 | sed 's/\/lib\/libchealpix.a//'` cd $HEALPIX HEALPIX=`pwd` cd $thisdir break fi fi fi done if test -n "$HEALPIX" then AC_MSG_RESULT($HEALPIX) else AC_MSG_RESULT(not found) no_healpix=yes fi ]) boinc-app-seti_8.00~svn3701.orig/m4/sah_requires.m40000644000175000017500000000165210671336410021773 0ustar locutuslocutus AC_DEFUN([SAH_REQUIRES],[ $2 if test $3; then AC_MSG_WARN([ $1 not found. ============================================================================ $4 ============================================================================ ]) $5 fi ]) AC_DEFUN([SAH_SERVER_REQUIRES],[ if test "${enable_server}" = yes; then SAH_REQUIRES([$1],[$2],[$3], [ WARNING: trying to build the seti_boinc server but $1 was not found. If you don't want to build the server you should use --disable-server. I am continuing now as if --disable-server had been specified. ],[enable_server=no]) fi ]) AC_DEFUN([SAH_CLIENT_REQUIRES],[ if test "${enable_client}" = yes; then SAH_REQUIRES([$1],[$2],[$3], [ WARNING: trying to build the seti_boinc client but $1 was not found. If you don't want to build the client you should use --disable-client. I am continuing now as if --disable-client had been specified. ],[enable_client=no]) fi ]) boinc-app-seti_8.00~svn3701.orig/m4/sah_staticize_ldflags.m40000644000175000017500000000264410671336410023631 0ustar locutuslocutusAC_DEFUN([SAH_STATICIZE_LDFLAGS],[ STATIC_LIB_LIST="${STATIC_LIB_LIST} $3" liblist=`echo $1 | $AWK '{for (i=1;i<(NF+1);i++) {print $[]i;}}' | grep -v "Wl,[sd]" ` ssl_sah_save_libs="${LIBS}" echo "DEBUG: before mangling $2:$1" >&5 sah_outputlibs= for somelib in ${liblist}; do # look for the -l to find the libraries alib=`echo x${somelib} | grep x-l | sed 's/x-l//'` if test -n "${alib}" then # check to see if it is in our static list for slib in ${STATIC_LIB_LIST}; do lib_is_static="no" tmp_pattern=`echo s/x${slib}// | sed 's/\*/.*/'` if test -z "`echo x${alib} | sed ${tmp_pattern}`" then SAH_STATIC_LIB(${alib},[fopen],[sah_outputlibs="${sah_outputlibs} ${sah_lib_last}"]) lib_is_static="yes" break; fi done if test "${lib_is_static}" = "no" ; then SAH_DYNAMIC_LIB(${alib},[fopen],[sah_outputlibs="${sah_outputlibs} ${sah_lib_last}"]) fi else tmp_pattern_a="s/x${ld_dynamic_option}//" tmp_pattern_b="s/x${ld_static_option}//" if test -n "`echo x${somelib} | sed ${tmp_pattern_a}`" -a \ -n "`echo x${somelib} | sed ${tmp_pattern_b}`" then sah_outputlibs="${sah_outputlibs} ${somelib}" LIBS="${LIBS} ${somelib}" fi fi done echo "DEBUG: final link-line for $2:${sah_outputlibs}" >&5 $2=${sah_outputlibs} LIBS="${ssl_sah_save_libs}" ]) boinc-app-seti_8.00~svn3701.orig/m4/sah_header_stdcxx.m40000644000175000017500000000411610671336410022757 0ustar locutuslocutus# The contents of this file are subject to the BOINC Public License # Version 1.0 (the "License"); you may not use this file except in # compliance with the License. You may obtain a copy of the License at # http://boinc.berkeley.edu/license_1.0.txt AC_PREREQ([2.54]) AC_DEFUN([SAH_HEADER_STDCXX],[ save_inc="$ac_includes_default" ac_includes_default=" #define CONFIG_TEST #include \"$BOINCDIR/lib/std_fixes.h\" $ac_includes_default " sah_stdcxx_headers="algorithm bitset cassert cctype cerrno cfloat climits clocale cmath complex csetjmp csignal cstdarg cstddef cstdio cstdlib cstring ctime deque fstream functional iomanip ios iosfwd iostream istream iterator limits list locale map memory numeric ostream queue set sstream stack stdexcept streambuf string utility valarray vector" AC_LANG_PUSH(C++) dnl First we'll check to see if they are all here in order to save time. AC_MSG_CHECKING([standard C++ headers]) tmp_includes= for header in $sah_stdcxx_headers do tmp_includes="$tmp_includes #include <$header> " done AC_COMPILE_IFELSE([ AC_LANG_PROGRAM([[ $ac_includes_default $tmp_includes ]], [] )], [ ac_includes_default="${ac_includes_default} ${tmp_includes} " sah_cxx_includes=${tmp_includes} AC_MSG_RESULT(yes) for header in $sah_stdcxx_headers do eval ac_cv_header_${header}=yes ac_uc_defn=HAVE_`echo ${header} | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` AC_DEFINE_UNQUOTED([${ac_uc_defn}],1,[Define to 1 if you have the ${header} header]) AC_CACHE_CHECK([for C++ header <${header}>],[ac_cv_header_${header}]) done ], [ ac_includes_default="$save_inc" AC_MSG_RESULT(no) AC_CHECK_HEADERS([$sah_stdcxx_headers]) for header in $sah_stdcxx_headers do eval tmp_var=\$ac_cv_header_${header} if test "$tmp_var" = "yes" then sah_cxx_includes="$sah_cxx_includes #include <$header> " fi done ] ) ac_includes_default="$save_inc" AC_CACHE_SAVE AC_LANG_POP(C++) CONFIG_TEST= ]) boinc-app-seti_8.00~svn3701.orig/m4/sah_namespace.m40000644000175000017500000000473312175757576022120 0ustar locutuslocutus# The contents of this file are subject to the BOINC Public License # Version 1.0 (the "License"); you may not use this file except in # compliance with the License. You may obtain a copy of the License at # http://boinc.berkeley.edu/license_1.0.txt # # Revision Log: # $Log: sah_namespace.m4,v $ # Revision 1.5.2.1 2005/05/19 01:07:10 korpela # *** empty log message *** # # Revision 1.3 2005/05/10 15:43:56 korpela # Fixed bug in caching of SAH_FUNCS_IN_NAMESPACE results. # # Revision 1.2 2005/05/06 00:31:05 korpela # Added caching of results to SAH_CHECK_NAMESPACES and SAH_FUNCS_IN_NAMESPACE # # Revision 1.1 2003/12/11 18:38:24 korpela # Added checked macro files into boinc # # Revision 1.5 2003/12/03 23:46:11 korpela # Fixed "sah_namespaces.m4" not to rely on "tr". # # AC_PREREQ([2.54]) AC_DEFUN([SAH_LC_TO_DEFN],[ $1=`echo $2 | $AWK '{split($[]1,a,"(");print a[[ 1 ]]}' | $as_tr_cpp` ]) AC_DEFUN([SAH_NS_TO_DEFN],[ $1=`echo $2 | $as_tr_cpp` ]) AC_DEFUN([SAH_CHECK_NAMESPACES],[ AC_LANG_PUSH(C++) sv_libs="${LIBS}" LIBS= AC_CACHE_CHECK([for C++ namespaces], [sah_cv_have_namespaces],[ AC_COMPILE_IFELSE([ AC_LANG_PROGRAM([ #define CONFIG_TEST namespace foo { int foo(void) { return(0); } } ],[ return foo::foo(); ]) ], [sah_cv_have_namespaces="yes"], [sah_cv_have_namespaces="no"]) ]) if test "${sah_cv_have_namespaces}" = "yes" ; then AC_DEFINE(HAVE_NAMESPACES,[1],[Define if your C++ compiler supports namespaces]) fi LIBS="${sv_libs}" AC_LANG_POP(C++) ]) AC_DEFUN([SAH_FUNCS_IN_NAMESPACE],[ AC_LANG_PUSH(C++) sv_libs="${LIBS}" LIBS= for func_name in $1 do func_name=m4_quote($func_name) t_ns=m4_quote($2) SAH_LC_TO_DEFN(ac_func_upper,[$func_name]) SAH_LC_TO_DEFN(ac_namespace_upper,[$t_ns]) ac_uc_defn=`echo HAVE_"$ac_namespace_upper"_$ac_func_upper` AC_CACHE_CHECK([for $func_name in namespace $t_ns], [sah_cv_func_$2_$ac_func_upper],[ AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[ #define CONFIG_TEST $sah_cxx_includes ]], [[ $2::$func_name ; ]])], [ eval sah_cv_func_$2_$ac_func_upper="yes" ], [ eval sah_cv_func_$2_$ac_func_upper="no" ] ) ]) if test "`eval echo '${'sah_cv_func_$2_$ac_func_upper'}'`" = "yes" ; then AC_DEFINE_UNQUOTED([$ac_uc_defn], [1], ["Define to 1 if $func_name is in namespace $t_ns::" ]) fi done LIBS="${sv_libs}" AC_LANG_POP(C++) ]) boinc-app-seti_8.00~svn3701.orig/m4/sah_select_bitness.m40000644000175000017500000000257710671336410023151 0ustar locutuslocutusAC_DEFUN([SAH_DEFAULT_BITNESS],[ if test -z "${COMPILER_MODEL_BITS}" then AC_MSG_CHECKING(default bitness of compiler) echo "int main() { return 0; }" >conftest.c ${CC} ${CFLAGS} -c conftest.c >&5 COMPILER_MODEL_BITS=32 if test -f conftest.${OBJEXT} ; then if test -n "`file conftest.${OBJEXT} | grep -i 64-bit`" then COMPILER_MODEL_BITS=64 else if test -n "`file conftest.${OBJEXT} | grep -i 16-bit`" then COMPILER_MODEL_BITS=16 fi fi fi /bin/rm conftest.c AC_MSG_RESULT($COMPILER_MODEL_BITS) fi ]) AC_DEFUN([SAH_SELECT_BITNESS],[ AC_LANG_PUSH(C) SAH_DEFAULT_BITNESS AC_MSG_CHECKING(Selecting $1 bit model) echo "int main() { return 0; }" >conftest.$ac_ext if test "$1" != "${COMPILER_MODEL_BITS}" then ${CC} ${CFLAGS} ${CPPFLAGS} -m$1 -c conftest.$ac_ext >&5 if test -f conftest.${OBJEXT} ; then if test -n "`file conftest.${OBJEXT} | grep -i $1-bit`" then CFLAGS="${CFLAGS} -m$1" AC_MSG_RESULT(-m$1) COMPILER_MODEL_BITS=$1 fi AC_MSG_RESULT(failed) fi else AC_MSG_RESULT(ok) fi AC_LANG_POP(C) ]) AC_DEFUN([SAH_OPTION_BITNESS],[ AC_ARG_ENABLE(bitness, AC_HELP_STRING([--enable-bitness=(32,64)], [enable 32 or 64 bit object/executable files] ), [SAH_SELECT_BITNESS(${enableval})], [SAH_DEFAULT_BITNESS] ) ]) boinc-app-seti_8.00~svn3701.orig/m4/sah_libsearch.m40000644000175000017500000000134510671336410022067 0ustar locutuslocutus# SETI_BOINC is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free # Software Foundation; either version 2, or (at your option) any later # version. AC_DEFUN([SAH_FORCE_LIBSEARCH_PATH],[ if test -z "$LD" then AC_PATH_PROGS([LD],[ld link]) fi if test "$GCC" = "yes" then link_pass_flag="-Xlinker " else if test "$CC" = "lcc" then link_pass_flag="-Wl" fi fi if test -n "$link_pass_flag" then if test -n "$LD" then if $LD -V 2>&1 | grep GNU then $1="$link_pass_flag -rpath $link_pass_flag $2 " else $1="$link_pass_flag -R $link_pass_flag $2 " fi fi fi ]) boinc-app-seti_8.00~svn3701.orig/m4/sah_grx.m40000644000175000017500000000213312633557223020736 0ustar locutuslocutus AC_DEFUN([SAH_GRX_LIBS],[ AC_LANG_PUSH(C) sah_save_libs="$LIBS" AC_PATH_PROG(XLSFONTS,[xlsfonts],[/usr/X11/bin:/usr/X11R6/bin:/usr/X11R5/bin:/usr/X11R4/bin:/usr/openwin/bin:$PATH]) sah_xpath=`echo $XLSFONTS | sed 's/bin\/xlsfonts//' ` LIBS=`echo $LIBS "-L$sah_xpath"` GRXLIBS="-L${sah_xpath} -ljpeg -lX11 -lXext -lXt -lICE -lSM -lGL -lGLU -lm" LIBS="$sah_save_libs" AC_SUBST(GRXLIBS) AC_LANG_POP ]) AC_DEFUN([SAH_GRX_INCLUDES],[ AC_LANG_PUSH(C++) AC_PATH_PROG(XLSFONTS,[xlsfonts],[/usr/X11/bin:/usr/X11R6/bin:/usr/X11R5/bin:/usr/X11R4/bin:/usr/openwin/bin:$PATH]) sah_xpath=`echo $XLSFONTS | sed 's/bin\/xlsfonts//' ` save_cflags="$CFLAGS" CFLAGS=`echo $CFLAGS "-I$sah_xpath/include"` GRX_CFLAGS="-I$sah_xpath" AC_SUBST(GRX_CFLAGS) AC_CHECK_HEADERS([gl.h glu.h glut.h freeglut.h glaux.h GL/gl.h GL/glu.h GL/glut.h GL/freeglut.h GL/glaux.h OpenGL/gl.h OpenGL/glu.h OpenGL/glut.h OpenGL/freeglut.h OpenGL/glaux.h glut/glut.h glut/freeglut.h freeglut/freeglut.h MesaGL/gl.h MesaGL/glu.h MesaGL/glut.h MesaGL/freeglut.h MesaGL/glaux.h ]) CFLAGS="$save_cflags" AC_LANG_POP ]) boinc-app-seti_8.00~svn3701.orig/m4/sah_check_ipp.m40000644000175000017500000000241010671336410022052 0ustar locutuslocutusAC_DEFUN([SAH_CHECK_IPP], [AC_MSG_CHECKING([for Intel Performance Primitives]) IPP= found_ipp="no" AC_ARG_WITH(ipp, AC_HELP_STRING([--with-ipp@<:@=DIR@:>@], [Use Intel Performance Primitives (in specified installation directory)]), [check_ipp_dir="$withval"], [check_ipp_dir=]) SAH_OPTIMIZATIONS for dir in $check_ipp_dir $check_ipp_dir/ia32* $check_ipp_dir/ipp*/ia32* /opt/intel/ipp*/ia32* /usr/local/ipp*/ia32* /usr/lib/ipp*/ia32* /usr/ipp*/ia32* /usr/pkg/ipp*/ia32* /usr/local /usr; do ippdir="$dir" if test -f "$dir/include/ipp.h"; then found_ipp="yes"; IPPDIR="${ippdir}" CFLAGS="$CFLAGS -I$ippdir/include -I$ippdir/tools/staticlib"; CXXFLAGS="$CXXFLAGS -I$ippdir/include -I$ippdir/tools/staticlib"; break; fi if test -f "$dir/include/ipp.h"; then found_ipp="yes"; IPPDIR="${ippdir}" CFLAGS="$CFLAGS -I$ippdir/include/"; CXXFLAGS="$CXXFLAGS -I$ippdir/include/"; break fi done AC_MSG_RESULT($found_ipp) if test x_$found_ipp = x_yes ; then printf "IPP found in $ippdir\n"; LIBS="$LIBS -lippcore -lippsmerged"; LDFLAGS="$LDFLAGS -L$ippdir/lib"; AC_DEFINE_UNQUOTED([USE_IPP],[1], ["Define to 1 if you want to use the Intel Performance Primitives"]) AC_SUBST(IPPDIR) fi ]) boinc-app-seti_8.00~svn3701.orig/m4/sah_informix.m40000644000175000017500000000354710766274634022012 0ustar locutuslocutus# SETI_BOINC is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free # Software Foundation; either version 2, or (at your option) any later # version. AC_DEFUN([SAH_CHECK_INFORMIX],[ AC_ARG_VAR([INFORMIXDIR],[informix directory]) AC_LANG_PUSH(C) AC_MSG_CHECKING(for Informix) if test -z "$INFORMIXDIR" then AC_PATH_PROG([INFORMIXDIR],[dbaccess],[],[/disks/galileo/a/apps/informix/bin:$PATH:/usr/local/informix/bin:/opt/misc/informix:~informix/bin]) INFORMIXDIR=`echo $INFORMIXDIR | $SED 's/bin\/dbaccess//'` fi if test -n "$INFORMIXDIR" then AC_MSG_RESULT(yes) INFORMIX_CFLAGS="-I$INFORMIXDIR/incl -I$INFORMIXDIR/incl/esql " INFORMIX_LIBS=" -L$INFORMIXDIR/lib -L$INFORMIXDIR/lib/esql $INFORMIXDIR/lib/esql/checkapi.o -lifasf -lifgen -lifgls -lifos -lifsql" AC_CHECK_LIB([socket], [bind], INFORMIX_LIBS="${INFORMIX_LIBS} -lsocket") AC_CHECK_LIB([nsl], [gethostbyname], INFORMIX_LIBS="${INFORMIX_LIBS} -lnsl") AC_CHECK_LIB([crypt], [crypt], INFORMIX_LIBS="${INFORMIX_LIBS} -lcrypt") AC_CHECK_LIB([dl], [dlopen], INFORMIX_LIBS="${INFORMIX_LIBS} -ldl") AC_CHECK_LIB([m], [ceil], INFORMIX_LIBS="${INFORMIX_LIBS} -lm") tmpvar=$LIBS LIBS=`echo $LIBS $INFORMIX_LIBS` AC_MSG_CHECKING(informix library flags) AC_TRY_LINK_FUNC(main,AC_DEFINE([USE_INFORMIX],[1],[Define to 1 if informix is installed]) sah_cv_use_informix="yes", sah_cv_use_informix="no") AC_MSG_RESULT($sah_cv_use_informix) LIBS=$tmpvar SAH_FORCE_LIBSEARCH_PATH(tmpvar,[$INFORMIXDIR/lib:$INFORMIXDIR/lib/esql]) INFORMIX_LIBS=`echo $tmpval $INFORMIX_LIBS` else INFORMIXDIR= INFORMIX_CFLAGS= INFORMIX_LIBS= AC_MSG_RESULT(no) no_informix=yes fi AC_SUBST(INFORMIXDIR) AC_SUBST(INFORMIX_CFLAGS) AC_SUBST(INFORMIX_LIBS) AC_LANG_POP ]) boinc-app-seti_8.00~svn3701.orig/Makefile.incl0000644000175000017500000000270312640614562021106 0ustar locutuslocutus# $Id: Makefile.incl,v 1.2.2.6 2007/02/13 23:16:11 korpela Exp $ # # @SET_MAKE@ AM_LIBS = @LIBS@ AM_LDFLAGS = @LDFLAGS@ AM_CPPFLAGS = @CFLAGS@ @PICFLAGS@ @DEFS@ -I$(top_srcdir) AM_CFLAGS = $(AM_CPPFLAGS) AM_CXXFLAGS = $(AM_CPPFLAGS) BOINCDIR = @BOINCDIR@ EXEEXT = @EXEEXT@ OBJEXT = @OBJEXT@ LIBEXT = @LIBEXT@ DLLEXT = @DLLEXT@ DOTEXEEXT = @DOTEXEEXT@ LINK_DLL = @LINK_DLL@ LIBTOOL = @LIBTOOL@ MYSQL_LIBS = @MYSQL_LIBS@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ INFORMIXDIR = @INFORMIXDIR@ INFORMIX_LIBS = @INFORMIX_LIBS@ INFORMIX_CFLAGS = @INFORMIX_CFLAGS@ APP_LIBS = @ASMLIB_LIBS@ @APP_LIBS@ @CLIENT_EXTRA_LIBS@ APP_LDFLAGS = @ASMLIB_LDFLAGS@ @APP_LDFLAGS@ APP_CFLAGS = @ASMLIB_CFLAGS@ @APP_CFLAGS@ GRAPHICS_CFLAGS = @GRAPHICS_CFLAGS@ DEFS = @DEFS@ GRAPHICS_LIBS = @GRAPHICS_LIBS@ SETILIBDIR = @SETILIBDIR@ HEALPIX = @HEALPIX@ SUFFIXES = .cpp .c .@OBJEXT@ .@DLLEXT@ .@LIBEXT@ @DOTEXEEXT@ VERSION_MAJOR = @MAJOR_VERSION@ VERSION_MINOR = @MINOR_VERSION@ BOINC_CFLAGS= @BOINC_CFLAGS@ BOINC_PLATFORM = @boinc_platform@ LDSTATIC = @LDSTATIC@ DEBUG_PROG = setiathome-$(VERSION_MAJOR).$(VERSION_MINOR).$(BOINC_PLATFORM).debug$(DOTEXEEXT) DEBUG_NATIVESO = setiathome-$(VERSION_MAJOR).$(VERSION_MINOR).$(BOINC_PLATFORM).debug.$(DLLEXT) CLIENT_PROG = setiathome-$(VERSION_MAJOR).$(VERSION_MINOR).$(BOINC_PLATFORM)$(DOTEXEEXT) CLIENT_NATIVESO = setiathome-$(VERSION_MAJOR).$(VERSION_MINOR).$(BOINC_PLATFORM).$(DLLEXT) boinc-app-seti_8.00~svn3701.orig/xcompile/0000755000175000017500000000000013155506301020331 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/xcompile/xcompile.MinGW32_on_cygwin.sh0000755000175000017500000001203312633557476025733 0ustar locutuslocutus#! /bin/sh case $1 in --help) echo Usage: echo "$0 \ (default i686-\*-mingw32)" echo " Expects to find build root in /usr/\/sys-root/mingw" ;; i686*mingw32|x86_64*mingw32) export TARGET_HOST=$1 ;; esac for target_host in ${TARGET_HOST} i686-w64-mingw32 i686-pc-mingw32 x86_64-w64-mingw32 x86_64-pc-mingw32 none ; do if test ${target_host} = none ; then echo Cross compiling environment not found in /usr exit 1 fi echo -n Checking for cross compiling environment in /usr/${target_host} if test -d /usr/${target_host}; then export TARGET_HOST=${target_host} echo ... found break fi echo ... not found done case $TARGET_HOST in i686*) openssl_cross=mingw ;; x86_64*) openssl_cross=mingw64 ;; esac build_client=yes build_server=no export XCOMPILE_ROOT="/usr/${TARGET_HOST}/sys-root/mingw" guess=`../config.guess` export BUILD_HOST=`../config.sub ${guess}` export PATH="/usr/${TARGET_HOST}/bin:${XCOMPILE_ROOT}/bin:${PATH}" export CC=`which ${TARGET_HOST}-gcc` export CXX=`which ${TARGET_HOST}-g++` export AR=`which ${TARGET_HOST}-ar` export LD=`which ${TARGET_HOST}-ld` export RANLIB=`which ${TARGET_HOST}-ranlib` export WINDRES=`which ${TARGET_HOST}-windres` export CPPFLAGS="-D_WIN32_WINDOWS=0x0410 -DMINGW_WIN32 -I${XCOMPILE_ROOT}/include" export CFLAGS="${CPPFLAGS}" export CXXFLAGS="-gstabs -g3 -fpermissive" export LDFLAGS="-L/usr/${TARGET_HOST}/lib -L${XCOMPILE_ROOT}/lib" export CURL_CONFIG="${XCOMPILE_ROOT}/bin/curl-config" export WX_CONFIG_PATH="${XCOMPILE_ROOT}/bin/wx-config" pkgsearchpath="dummy" for dir in `find /usr/${TARGET_HOST} -name pkgconfig` ; do pkgsearchpath="${pkgsearchpath}:${dir}" done for dir in `find /usr/lib -name pkgconfig` ; do pkgsearchpath="${pkgsearchpath}:${dir}" done for dir in `find /usr/share -name pkgconfig` ; do pkgsearchpath="${pkgsearchpath}:${dir}" done export PKG_CONFIG_PATH=`echo ${pkgsearchpath} | sed 's/dummy://'` if ! ( test -e ../configure && find .. -name configure -mtime -1 ) ; then cd .. ./_autosetup cd xcompile fi if test $build_client != no ; then if ! test -f ${XCOMPILE_ROOT}/lib/libjpeg.a ; then jpegver=9a wget http://ijg.org/files/jpegsrc.v${jpegver}.tar.gz tar zxf jpegsrc.v${jpegver}.tar.gz /bin/rm jpegsrc.v${jpegver}.tar.gz cd jpeg-${jpegver} ./configure --prefix=${XCOMPILE_ROOT}/ --disable-shared --host=$TARGET_HOST --build=$BUILD_HOST make -j 4 all make install cd .. rm -rf jpeg-${jpegver} fi fi if test $build_client != no ; then if ! test -f ${XCOMPILE_ROOT}/lib/libssl.a ; then opensslver=1.0.1g wget http://www.openssl.org/source/openssl-${opensslver}.tar.gz tar zxf openssl-${opensslver}.tar.gz /bin/rm openssl-${opensslver}.tar.gz cd openssl-${opensslver} ./Configure --prefix=${XCOMPILE_ROOT}/ ${CFLAGS} ${LDFLAGS} no-shared zlib $openssl_cross make -j 4 all make install cd .. rm -rf openssl-${opensslver} fi fi if test $build_client != no ; then if ! test -f ${XCOMPILE_ROOT}/lib/libcurl.a ; then curlver=7.36.0 wget http://curl.haxx.se/download/curl-${curlver}.tar.bz2 tar jxf curl-${curlver}.tar.bz2 /bin/rm curl-${curlver}.tar.bz2 cd curl-${curlver} ./configure --prefix=${XCOMPILE_ROOT} --enable-static --disable-shared --host=$TARGET_HOST --build=$BUILD_HOST --with-zlib=${XCOMPILE_ROOT} make -j 4 all make install cd .. rm -rf curl-${curlver} fi fi if test $build_client != no ; then if ! test -f ${XCOMPILE_ROOT}/include/GL/glut.h ; then svn co http://svn.code.sf.net/p/freeglut/code/trunk/freeglut/freeglut freeglut cd freeglut mkdir build cd build /usr/bin/cmake -D GNU_HOST=${TARGET_HOST} \ -D CMAKE_TOOLCHAIN_FILE=mingw_cross_toolchain.cmake \ -D CMAKE_INSTALL_PREFIX=${XCOMPILE_ROOT}\ -D FREEGLUT_BUILD_STATIC_LIBS=ON \ -D FREEGLUT_BUILD_SHARED_LIBS=OFF \ -D FREEGLUT_BUILD_DEMOS=OFF \ .. make -j 4 all make install cd ../.. /bin/rm -rf freeglut fi fi if test $build_client != no ; then if ! test -f ${XCOMPILE_ROOT}/lib/libfftw3f.a ; then case $target_host in i[56]86-*) cp ../client/win_build/libfftw3f-3-3-4_x86.lib ${XCOMPILE_ROOT}/lib/libfftw3f.a cp ../client/win_build/libfftw3f-3-3-4_x86.dll ${XCOMPILE_ROOT}/bin ;; x86*|x64*) cp ../client/win_build/libfftw3f-3-3-4_x64.lib ${XCOMPILE_ROOT}/lib/libfftw3f.a cp ../client/win_build/libfftw3f-3-3-4_x64.dll ${XCOMPILE_ROOT}/bin ;; esac fi fi enables="--enable-static --disable-shared" if test $build_client != no ; then enables="${enables} --enable-client" else enables="${enables} --disable-client" fi if test $build_server != no ; then enables="${enables} --enable-server" else enables="${enables} --disable-server" fi ../configure -C --host=$TARGET_HOST --build=$BUILD_HOST ${enables} --with-ssl=${XCOMPILE_ROOT} --prefix=${XCOMPILE_ROOT} make -j 4 all boinc-app-seti_8.00~svn3701.orig/build_android_client.sh0000755000175000017500000000647212313644616023225 0ustar locutuslocutus#!/bin/sh # # See: http://boinc.berkeley.edu/trac/wiki/AndroidBuildApp# # # Script to compile various BOINC libraries for Android to be used # by science applications #for targetarch in armv6-soft armv6-vfp armv6-neon armv7-neon armv7-vfpv3 armv7-vfpv4 armv7-vfpv3d16 thumb-vfpv3d16 for targetarch in armv6-vfp armv6-neon do fpabi="-mfloat-abi=softfp" configargs="" cpuarch=armv7-a tune=cortex-a9 case $targetarch in armv6-soft) fpabi="-mfloat-abi=soft" cpuarch=armv6 fpu= tune=cortex-m1 ;; armv6-vfp) cpuarch=armv6 configargs="--disable-neon" fpu="-mfpu=vfp" tune=cortex-m1 ;; armv6-neon) cpuarch=armv6 tune=cortex-m1 fpu="-mfpu=neon -ftree-vectorize" ;; thumb-vfpv3d16) cpuarch="armv7-a -mthumb" fpu="-mfpu=vfpv3-d16" ;; *-neon) fpu="-mfpu=neon -ftree-vectorize" ;; *-vfpv3) fpu="-mfpu=vfpv3" ;; *-vfpv3d16) fpu="-mfpu=vfpv3-d16" ;; *-vfpv4) fpu="-mfpu=vfpv4" ;; *) ;; esac COMPILEBOINC="yes" CONFIGURE="yes" MAKECLEAN="yes" export BOINC="../boinc" #BOINC source code export PKG_CONFIG_DEBUG_SPEW=1 export ANDROIDTC="/usr/arm-linux-androideabi" export TCBINARIES="$ANDROIDTC/bin" export TCINCLUDES="$ANDROIDTC/arm-linux-androideabi" export TCSYSROOT="$ANDROIDTC/sysroot" export STDCPPTC="$TCINCLUDES/lib/libstdc++.a" export CROSS_PREFIX=arm-linux-androideabi export ac_cv_host=${CROSS_PREFIX} export PATH="$PATH:$TCBINARIES:$TCINCLUDES/bin" export CC=${CROSS_PREFIX}-gcc export CCAS=${CROSS_PREFIX}-gcc export CXX=${CROSS_PREFIX}-g++ export LD=${CROSS_PREFIX}-ld export NM=${CROSS_PREFIX}-nm export AR=${CROSS_PREFIX}-ar export STRIP=${CROSS_PREFIX}-strip export RANLIB=${CROSS_PREFIX}-ranlib export CFLAGS="--sysroot=$TCSYSROOT -DANDROID -DDECLARE_TIMEZONE -Wall -O3 -fomit-frame-pointer -march=${cpuarch} -I$TCSYSROOT/usr/include ${fpu} ${fpabi}" export CXXFLAGS="--sysroot=$TCSYSROOT -DANDROID -Wall -funroll-loops -fexceptions -O3 -fomit-frame-pointer -march=${cpuarch} -I$TCSYSROOT/usr/include ${fpu} ${fpabi}" export CCASFLAGS="${CFLAGS}" export LDFLAGS="-static-libstdc++ -static-libgcc -L$TCINCLUDES/lib/${targetarch} -L$TCSYSROOT/usr/lib -L$TCINCLUDES/lib -llog -lstdc++" export LIBS="/usr/arm-linux-androideabi/arm-linux-androideabi/lib/libstdc++.a" export PKG_CONFIG_SYSROOT_DIR=$TCSYSROOT export PKG_CONFIG_PATH=$CURL_DIR/lib/pkgconfig:$OPENSSL_DIR/lib/pkgconfig if [ -n "$COMPILEBOINC" ]; then echo "==================building Libraries from $BOINC==========================" if [ -n "$MAKECLEAN" ]; then cd client make clean cd .. fi if [ -n "$CONFIGURE" ]; then ./_autosetup /bin/rm config.cache if ! ./configure -C --host=${ac_cv_host} --prefix="${ANDROIDTC}/arm-linux-androideabi" --exec-prefix="${ANDROIDTC}/arm-linux-androideabi" --with-boinc-platform="arm-android-linux-gnu" --with-ssl=$TCINCLUDES --disable-graphics --disable-server $configargs then break fi fi cd client if ! make ; then break fi pwd source ./working_collect2_line_for_android_$targetarch cp seti_boinc setiathome_7.28_arm-android-linux-gnu__$targetarch cd .. echo "=============================BOINC done=============================" fi done boinc-app-seti_8.00~svn3701.orig/configure.ac.public0000644000175000017500000000712610671336410022264 0ustar locutuslocutus# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ(2.57) AC_INIT(setiathome, 4.0, ports@setiathome.ssl.berkeley.edu) AC_CONFIG_SRCDIR([client/analyze.h]) AC_CONFIG_HEADER([config.h]) major_version=`echo AC_PACKAGE_VERSION | sed 's/\..*//'` minor_version=`echo AC_PACKAGE_VERSION | sed 's/.*\.//' | sed 's/^0//'` AC_SUBST([MAJOR_VERSION], [$major_version]) AC_SUBST([MINOR_VERSION], [$minor_version]) AC_DEFINE_UNQUOTED([VERSION_MAJOR],$major_version, [SETI@home major version number]) AC_DEFINE_UNQUOTED([VERSION_MINOR],$minor_version, [SETI@home minor version number]) AC_DEFINE_UNQUOTED([SAH_APP_NAME],["$PACKAGE_NAME"], [Define to the BOINC application name for setiathome]) AC_CANONICAL_HOST # Checks for programs. AC_PROG_CXX AC_PROG_CXXCPP AC_PROG_AWK AC_PROG_RANLIB AC_PATH_PROG(SED,[sed]) AC_PATH_PROG(TR,[tr]) AC_PATH_PROGS(AR,[ar lib]) AC_PATH_PROG(AUTOCONF,[autoconf]) AC_PATH_PROG(AUTOHEADER,[autoheader]) AC_PATH_PROGS(INDENT,[astyle indent]) AC_PATH_PROG(SORT,[sort]) AC_PATH_PROG(UNIQ,[uniq]) AC_PATH_PROG(CAT,[cat type]) AC_PATH_PROG(MV,[mv]) AC_PATH_PROGS(RM,[rm Rm del erase delete]) if test -n `echo $INDENT | grep astyle` then AC_SUBST([INDENT_FLAGS],["--c --indent-classes --indent-switches --brackets=attach --convert-tabs"]) else AC_SUBST([INDENT_FLAGS],["-kr"]) fi AC_PROG_MAKE_SET SAH_DLLEXT SAH_LIBEXT if test -n "$EXEEXT" then DOTEXEEXT=".$EXEEXT" fi AC_SUBST(DOTEXEEXT) AC_SYS_LARGEFILE # Checks for libraries. AC_LANG(C++) AC_CHECK_LIB([cygipc],[shmget]) AC_CHECK_LIB([aio], [aio_fork]) AC_CHECK_LIB([dl], [dlclose]) AC_CHECK_LIB([elf], [elf_hash]) AC_CHECK_LIB([fftw], [fftw_create_plan]) AC_CHECK_LIB([m], [sin]) AC_CHECK_LIB([nsl], [gethostbyname]) AC_CHECK_LIB([socket], [bind]) AC_CHECK_LIB([z], [uncompress]) AC_CHECK_LIB([stdc++], [main]) SAH_GRX_LIBS SAH_CHECK_BOINC SAH_CHECK_MYSQL SAH_CHECK_INFORMIX SAH_FIND_S4PATH AC_CACHE_SAVE # Checks for header files. AC_HEADER_STDC SAH_LARGEFILE_BREAKS_CXX SAH_HEADER_STDCXX AC_HEADER_SYS_WAIT AC_CHECK_HEADERS([fcntl.h inttypes.h limits.h memory.h stdlib.h string.h strings.h sys/ioctl.h sys/statvfs.h sys/time.h unistd.h dirent.h]) SAH_GRX_INCLUDES AC_CACHE_SAVE # Checks for typedefs, structures, and compiler characteristics. AC_HEADER_STDBOOL AC_C_CONST AC_C_INLINE AC_C_LONG_DOUBLE AC_TYPE_OFF_T AC_TYPE_SIZE_T AC_STRUCT_ST_BLOCKS AC_STRUCT_TM AC_CHECK_SIZEOF([long int]) AC_CHECK_SIZEOF([long double]) AC_CHECK_TYPES([long long,_int64,bool]) AC_CACHE_SAVE # Checks for library functions. AC_LANG(C) AC_FUNC_FORK AC_HEADER_MAJOR AC_FUNC_MALLOC AC_FUNC_REALLOC AC_FUNC_STAT AC_FUNC_STRFTIME AC_CHECK_FUNCS([atexit floor getcwd memset munmap putenv sqrt strchr strstr atoll]) SAH_CHECK_NAMESPACES AH_TEMPLATE([HAVE_STD_MIN],[Define to 1 if min is in namespace std::]) AH_TEMPLATE([HAVE_STD_MAX],[Define to 1 if max is in namespace std::]) AH_TEMPLATE([HAVE_STD_TRANSFORM],[Define to 1 if transform is in namespace std::]) SAH_FUNCS_IN_NAMESPACE([['min(0,0)'] ['max(0,0)'] ['transform((char *)0,(char *)0,(char *)0,(int(*)(int))malloc)']],std) AC_CACHE_SAVE AH_TOP([ #ifndef _SAH_CONFIG_H_ #define _SAH_CONFIG_H_ #ifdef _WIN32 #include "win-config.h" #endif ]) AH_BOTTOM([ /* Define USE_NAMESPACES if you may access more than one database from the * same program */ #if defined(USE_INFORMIX) && defined(USE_MYSQL) && defined(HAVE_NAMESPACES) #define USE_NAMESPACES #endif #include "std_fixes.h" #endif ]) AC_CONFIG_FILES([Makefile client/Makefile db/Makefile db/schema_to_class ]) AC_OUTPUT chmod +x db/schema_to_class boinc-app-seti_8.00~svn3701.orig/client/0000755000175000017500000000000013155506332017773 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/client/pulsefind.cpp0000644000175000017500000016652112313644616022506 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. /* * $Id: pulsefind.cpp,v 1.16.2.16 2007/08/10 00:38:48 korpela Exp $ * */ #include "sah_config.h" #include #include #include #include #include #include #include "diagnostics.h" #include "util.h" #include "s_util.h" #include "boinc_api.h" #ifdef BOINC_APP_GRAPHICS #include "sah_gfx_main.h" #endif #include "seti.h" #include "seti_header.h" #include "analyzePoT.h" #include "analyzeReport.h" #include "worker.h" #include "malloc_a.h" #include "lcgamm.h" #include "pulsefind.h" #ifdef __arm__ #include "vector/fp_arm.h" #endif //#define DEBUG_TRIPLET_VERBOSE //#define DEBUG_PULSE_VERBOSE //#define DEBUG_PULSE_BOUNDS /********************** * * find_triplets - Analyzes the input signal for a triplet signal. * * Written by Eric Heien. */ int find_triplets( const float *power, int len_power, float triplet_thresh, int time_bin, int freq_bin ) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("find_triplets()"); #endif static int *binsAboveThreshold; int i,n,numBinsAboveThreshold=0,p,q,blksize; float midpoint,mean_power=0,peak_power,period,total=0.0f,partial; if (!binsAboveThreshold) { binsAboveThreshold=(int *)malloc_a(PoTInfo.TripletMax*sizeof(int),MEM_ALIGN); if (!binsAboveThreshold) SETIERROR(MALLOC_FAILED, "!binsAboveThreshold"); } /* Get all the bins that are above the threshold, and find the power array mean value */ #ifdef DEBUG_TRIPLET_VERBOSE fprintf(stderr, "In find_triplets()... PulsePotLen = %d triplet_thresh = %f TOffset = %d PoT = %d\n", len_power, triplet_thresh, time_bin, freq_bin); #endif blksize = UNSTDMAX(1, UNSTDMIN(pow2((unsigned int) sqrt((float) (len_power / 32)) * 32), 512)); int b; for(b=0;b= triplet_thresh ) { binsAboveThreshold[numBinsAboveThreshold] = i; numBinsAboveThreshold++; } } analysis_state.FLOP_counter+=10.0+len_power; /* Check each bin combination for a triplet */ if (numBinsAboveThreshold>2) { for( i=0;i peak_power ) peak_power = power[binsAboveThreshold[n]]; p = binsAboveThreshold[i]; while( (power[p] >= triplet_thresh) && (p <= (static_cast(floor(midpoint)))) ) { /* Check if there is a pulse "off" in between init and midpoint */ p++; } q = static_cast(floor(midpoint))+1; while( (power[q] >= triplet_thresh) && (q <= binsAboveThreshold[n])) { /* Check if there is a pulse "off" in between midpoint and end */ q++; } if( p >= static_cast(floor(midpoint)) || q >= binsAboveThreshold[n]) { /* if this pulse doesn't have an "off" between all the three spikes, it's dropped */ } else if( (midpoint - floor(midpoint)) > 0.1f ) { /* if it's spread among two bins */ if( power[(int)midpoint] >= triplet_thresh ) { if( power[(int)midpoint] > peak_power ) peak_power = power[(int)midpoint]; ReportTripletEvent( peak_power/mean_power, mean_power, period, midpoint,time_bin, freq_bin, len_power, power, 1 ); } if( power[(int)(midpoint+1.0f)] >= triplet_thresh ) { if( power[(int)(midpoint+1.0f)] > peak_power ) peak_power = power[(int)(midpoint+1.0f)]; ReportTripletEvent( peak_power/mean_power, mean_power, period, midpoint,time_bin, freq_bin, len_power, power, 1 ); } } else { /* otherwise just check the single midpoint bin */ if( power[(int)midpoint] >= triplet_thresh ) { if( power[(int)midpoint] > peak_power ) peak_power = power[(int)midpoint]; ReportTripletEvent( peak_power/mean_power, mean_power, period, midpoint,time_bin, freq_bin, len_power, power, 1 ); } } } } } analysis_state.FLOP_counter+=(10.0*numBinsAboveThreshold*numBinsAboveThreshold); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return (0); } /********************** * * Pulse finding * * * Default folding subroutines, FPU optimized * */ float sw_sum3_t31(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("sw_sum3_t31()"); #endif float sum1, sum2, tmax2, tmax1; int i = P->di; float *one = ss[0]; float *two = ss[0]+P->tmp0; float *three = ss[0]+P->tmp1; tmax2 = tmax1 = float(0.0); if ( i & 1 ) { i -= 1; tmax1 = one[i] + two[i]; tmax1 += three[i]; P->dest[i] = tmax1; } switch (i) { case 30: sum1 = one[29] + two[29]; sum2 = one[28] + two[28]; sum1 += three[29]; sum2 += three[28]; P->dest[29] = sum1; P->dest[28] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 28: sum1 = one[27] + two[27]; sum2 = one[26] + two[26]; sum1 += three[27]; sum2 += three[26]; P->dest[27] = sum1; P->dest[26] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 26: sum1 = one[25] + two[25]; sum2 = one[24] + two[24]; sum1 += three[25]; sum2 += three[24]; P->dest[25] = sum1; P->dest[24] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 24: sum1 = one[23] + two[23]; sum2 = one[22] + two[22]; sum1 += three[23]; sum2 += three[22]; P->dest[23] = sum1; P->dest[22] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 22: sum1 = one[21] + two[21]; sum2 = one[20] + two[20]; sum1 += three[21]; sum2 += three[20]; P->dest[21] = sum1; P->dest[20] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 20: sum1 = one[19] + two[19]; sum2 = one[18] + two[18]; sum1 += three[19]; sum2 += three[18]; P->dest[19] = sum1; P->dest[18] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 18: sum1 = one[17] + two[17]; sum2 = one[16] + two[16]; sum1 += three[17]; sum2 += three[16]; P->dest[17] = sum1; P->dest[16] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 16: sum1 = one[15] + two[15]; sum2 = one[14] + two[14]; sum1 += three[15]; sum2 += three[14]; P->dest[15] = sum1; P->dest[14] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 14: sum1 = one[13] + two[13]; sum2 = one[12] + two[12]; sum1 += three[13]; sum2 += three[12]; P->dest[13] = sum1; P->dest[12] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 12: sum1 = one[11] + two[11]; sum2 = one[10] + two[10]; sum1 += three[11]; sum2 += three[10]; P->dest[11] = sum1; P->dest[10] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 10: sum1 = one[9] + two[9]; sum2 = one[8] + two[8]; sum1 += three[9]; sum2 += three[8]; P->dest[9] = sum1; P->dest[8] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 8: sum1 = one[7] + two[7]; sum2 = one[6] + two[6]; sum1 += three[7]; sum2 += three[6]; P->dest[7] = sum1; P->dest[6] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 6: sum1 = one[5] + two[5]; sum2 = one[4] + two[4]; sum1 += three[5]; sum2 += three[4]; P->dest[5] = sum1; P->dest[4] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 4: sum1 = one[3] + two[3]; sum2 = one[2] + two[2]; sum1 += three[3]; sum2 += three[2]; P->dest[3] = sum1; P->dest[2] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 2: sum1 = one[1] + two[1]; sum2 = one[0] + two[0]; sum1 += three[1]; sum2 += three[0]; P->dest[1] = sum1; P->dest[0] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif if (tmax1 > tmax2) return tmax1; return tmax2; } // // use for higher sum3 folds // float top_sum3(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("top_sum3()"); #endif float sum1, sum2, tmaxB, tmax; int i; float *one = ss[0]; float *two = ss[0]+P->tmp0; float *three = ss[0]+P->tmp1; tmaxB = tmax = float(0.0); for (i = 0 ; i < P->di-21; i += 22) { sum1 = one[i+0] + two[i+0]; sum2 = one[i+1] + two[i+1]; sum1 += three[i+0]; sum2 += three[i+1]; P->dest[i+0] = sum1; P->dest[i+1] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; sum1 = one[i+2] + two[i+2]; sum2 = one[i+3] + two[i+3]; sum1 += three[i+2]; sum2 += three[i+3]; P->dest[i+2] = sum1; P->dest[i+3] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; sum1 = one[i+4] + two[i+4]; sum2 = one[i+5] + two[i+5]; sum1 += three[i+4]; sum2 += three[i+5]; P->dest[i+4] = sum1; P->dest[i+5] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; sum1 = one[i+6] + two[i+6]; sum2 = one[i+7] + two[i+7]; sum1 += three[i+6]; sum2 += three[i+7]; P->dest[i+6] = sum1; P->dest[i+7] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; sum1 = one[i+8] + two[i+8]; sum2 = one[i+9] + two[i+9]; sum1 += three[i+8]; sum2 += three[i+9]; P->dest[i+8] = sum1; P->dest[i+9] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; sum1 = one[i+10] + two[i+10]; sum2 = one[i+11] + two[i+11]; sum1 += three[i+10]; sum2 += three[i+11]; P->dest[i+10] = sum1; P->dest[i+11] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; sum1 = one[i+12] + two[i+12]; sum2 = one[i+13] + two[i+13]; sum1 += three[i+12]; sum2 += three[i+13]; P->dest[i+12] = sum1; P->dest[i+13] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; sum1 = one[i+14] + two[i+14]; sum2 = one[i+15] + two[i+15]; sum1 += three[i+14]; sum2 += three[i+15]; P->dest[i+14] = sum1; P->dest[i+15] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; sum1 = one[i+16] + two[i+16]; sum2 = one[i+17] + two[i+17]; sum1 += three[i+16]; sum2 += three[i+17]; P->dest[i+16] = sum1; P->dest[i+17] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; sum1 = one[i+18] + two[i+18]; sum2 = one[i+19] + two[i+19]; sum1 += three[i+18]; sum2 += three[i+19]; P->dest[i+18] = sum1; P->dest[i+19] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; sum1 = one[i+20] + two[i+20]; sum2 = one[i+21] + two[i+21]; sum1 += three[i+20]; sum2 += three[i+21]; P->dest[i+20] = sum1; P->dest[i+21] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; } for ( ; i < P->di; i++) { sum1 = one[i] + two[i] + three[i]; P->dest[i] = sum1; if (sum1 > tmax) tmax = sum1; } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif if (tmax > tmaxB) return tmax; return tmaxB; } sum_func swi3tb[FOLDTBLEN] = { sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, top_sum3 }; // // float sw_sum4_t31(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("sw_sum4_t31()"); #endif float sum1, sum2, tmax2, tmax1; int i = P->di; float *one = ss[0]; float *two = ss[0]+P->tmp0; float *three = ss[0]+P->tmp1; float *four = ss[0]+P->tmp2; tmax2 = tmax1 = float(0.0); if ( i & 1 ) { i -= 1; tmax1 = one[i] + two[i]; sum2 = three[i] + four[i]; tmax1 += sum2; P->dest[i] = tmax1; } switch (i) { case 30: sum1 = one[29] + two[29]; sum2 = one[28] + two[28]; sum1 += three[29]; sum2 += three[28]; sum1 += four[29]; sum2 += four[28]; P->dest[29] = sum1; P->dest[28] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 28: sum1 = one[27] + two[27]; sum2 = one[26] + two[26]; sum1 += three[27]; sum2 += three[26]; sum1 += four[27]; sum2 += four[26]; P->dest[27] = sum1; P->dest[26] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 26: sum1 = one[25] + two[25]; sum2 = one[24] + two[24]; sum1 += three[25]; sum2 += three[24]; sum1 += four[25]; sum2 += four[24]; P->dest[25] = sum1; P->dest[24] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 24: sum1 = one[23] + two[23]; sum2 = one[22] + two[22]; sum1 += three[23]; sum2 += three[22]; sum1 += four[23]; sum2 += four[22]; P->dest[23] = sum1; P->dest[22] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 22: sum1 = one[21] + two[21]; sum2 = one[20] + two[20]; sum1 += three[21]; sum2 += three[20]; sum1 += four[21]; sum2 += four[20]; P->dest[21] = sum1; P->dest[20] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 20: sum1 = one[19] + two[19]; sum2 = one[18] + two[18]; sum1 += three[19]; sum2 += three[18]; sum1 += four[19]; sum2 += four[18]; P->dest[19] = sum1; P->dest[18] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 18: sum1 = one[17] + two[17]; sum2 = one[16] + two[16]; sum1 += three[17]; sum2 += three[16]; sum1 += four[17]; sum2 += four[16]; P->dest[17] = sum1; P->dest[16] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 16: sum1 = one[15] + two[15]; sum2 = one[14] + two[14]; sum1 += three[15]; sum2 += three[14]; sum1 += four[15]; sum2 += four[14]; P->dest[15] = sum1; P->dest[14] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 14: sum1 = one[13] + two[13]; sum2 = one[12] + two[12]; sum1 += three[13]; sum2 += three[12]; sum1 += four[13]; sum2 += four[12]; P->dest[13] = sum1; P->dest[12] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 12: sum1 = one[11] + two[11]; sum2 = one[10] + two[10]; sum1 += three[11]; sum2 += three[10]; sum1 += four[11]; sum2 += four[10]; P->dest[11] = sum1; P->dest[10] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 10: sum1 = one[9] + two[9]; sum2 = one[8] + two[8]; sum1 += three[9]; sum2 += three[8]; sum1 += four[9]; sum2 += four[8]; P->dest[9] = sum1; P->dest[8] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 8: sum1 = one[7] + two[7]; sum2 = one[6] + two[6]; sum1 += three[7]; sum2 += three[6]; sum1 += four[7]; sum2 += four[6]; P->dest[7] = sum1; P->dest[6] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 6: sum1 = one[5] + two[5]; sum2 = one[4] + two[4]; sum1 += three[5]; sum2 += three[4]; sum1 += four[5]; sum2 += four[4]; P->dest[5] = sum1; P->dest[4] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 4: sum1 = one[3] + two[3]; sum2 = one[2] + two[2]; sum1 += three[3]; sum2 += three[2]; sum1 += four[3]; sum2 += four[2]; P->dest[3] = sum1; P->dest[2] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 2: sum1 = one[1] + two[1]; sum2 = one[0] + two[0]; sum1 += three[1]; sum2 += three[0]; sum1 += four[1]; sum2 += four[0]; P->dest[1] = sum1; P->dest[0] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif if (tmax1 > tmax2) return tmax1; return tmax2; } // // use for higher sum4 folds // float top_sum4(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("top_sum4()"); #endif float sum1, sum2, tmaxB, tmax; int i; float *one = ss[0]; float *two = ss[0]+P->tmp0; float *three = ss[0]+P->tmp1; float *four = ss[0]+P->tmp2; tmaxB = tmax = float(0.0); for (i = 0 ; i < P->di-15; i += 16) { sum1 = one[i+0] + two[i+0]; sum2 = one[i+1] + two[i+1]; sum1 += three[i+0]; sum2 += three[i+1]; sum1 += four[i+0]; sum2 += four[i+1]; P->dest[i+0] = sum1; P->dest[i+1] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; sum1 = one[i+2] + two[i+2]; sum2 = one[i+3] + two[i+3]; sum1 += three[i+2]; sum2 += three[i+3]; sum1 += four[i+2]; sum2 += four[i+3]; P->dest[i+2] = sum1; P->dest[i+3] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; sum1 = one[i+4] + two[i+4]; sum2 = one[i+5] + two[i+5]; sum1 += three[i+4]; sum2 += three[i+5]; sum1 += four[i+4]; sum2 += four[i+5]; P->dest[i+4] = sum1; P->dest[i+5] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; sum1 = one[i+6] + two[i+6]; sum2 = one[i+7] + two[i+7]; sum1 += three[i+6]; sum2 += three[i+7]; sum1 += four[i+6]; sum2 += four[i+7]; P->dest[i+6] = sum1; P->dest[i+7] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; sum1 = one[i+8] + two[i+8]; sum2 = one[i+9] + two[i+9]; sum1 += three[i+8]; sum2 += three[i+9]; sum1 += four[i+8]; sum2 += four[i+9]; P->dest[i+8] = sum1; P->dest[i+9] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; sum1 = one[i+10] + two[i+10]; sum2 = one[i+11] + two[i+11]; sum1 += three[i+10]; sum2 += three[i+11]; sum1 += four[i+10]; sum2 += four[i+11]; P->dest[i+10] = sum1; P->dest[i+11] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; sum1 = one[i+12] + two[i+12]; sum2 = one[i+13] + two[i+13]; sum1 += three[i+12]; sum2 += three[i+13]; sum1 += four[i+12]; sum2 += four[i+13]; P->dest[i+12] = sum1; P->dest[i+13] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; sum1 = one[i+14] + two[i+14]; sum2 = one[i+15] + two[i+15]; sum1 += three[i+14]; sum2 += three[i+15]; sum1 += four[i+14]; sum2 += four[i+15]; P->dest[i+14] = sum1; P->dest[i+15] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; } for ( ; i < P->di; i++) { sum1 = (one[i] + two[i] ); sum2 = (three[i] + four[i] ); sum1 += sum2; P->dest[i] = sum1; if (sum1 > tmax) tmax = sum1; } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif if (tmax > tmaxB) return tmax; return tmaxB; } // sum_func swi4tb[FOLDTBLEN] = { sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, top_sum4 }; // // float sw_sum5_t31(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("sw_sum5_t31()"); #endif float sum1, sum2, tmax2, tmax1; int i = P->di; float *one = ss[0]; float *two = ss[0]+P->tmp0; float *three = ss[0]+P->tmp1; float *four = ss[0]+P->tmp2; float *five = ss[0]+P->tmp3; tmax2 = tmax1 = float(0.0); if ( i & 1 ) { i -= 1; tmax1 = one[i] + two[i]; sum2 = three[i] + four[i]; tmax1 += five[i]; tmax1 += sum2; P->dest[i] = tmax1; } switch (i) { case 30: sum1 = one[29] + two[29]; sum2 = one[28] + two[28]; sum1 += three[29]; sum2 += three[28]; sum1 += four[29]; sum2 += four[28]; sum1 += five[29]; sum2 += five[28]; P->dest[29] = sum1; P->dest[28] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 28: sum1 = one[27] + two[27]; sum2 = one[26] + two[26]; sum1 += three[27]; sum2 += three[26]; sum1 += four[27]; sum2 += four[26]; sum1 += five[27]; sum2 += five[26]; P->dest[27] = sum1; P->dest[26] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 26: sum1 = one[25] + two[25]; sum2 = one[24] + two[24]; sum1 += three[25]; sum2 += three[24]; sum1 += four[25]; sum2 += four[24]; sum1 += five[25]; sum2 += five[24]; P->dest[25] = sum1; P->dest[24] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 24: sum1 = one[23] + two[23]; sum2 = one[22] + two[22]; sum1 += three[23]; sum2 += three[22]; sum1 += four[23]; sum2 += four[22]; sum1 += five[23]; sum2 += five[22]; P->dest[23] = sum1; P->dest[22] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 22: sum1 = one[21] + two[21]; sum2 = one[20] + two[20]; sum1 += three[21]; sum2 += three[20]; sum1 += four[21]; sum2 += four[20]; sum1 += five[21]; sum2 += five[20]; P->dest[21] = sum1; P->dest[20] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 20: sum1 = one[19] + two[19]; sum2 = one[18] + two[18]; sum1 += three[19]; sum2 += three[18]; sum1 += four[19]; sum2 += four[18]; sum1 += five[19]; sum2 += five[18]; P->dest[19] = sum1; P->dest[18] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 18: sum1 = one[17] + two[17]; sum2 = one[16] + two[16]; sum1 += three[17]; sum2 += three[16]; sum1 += four[17]; sum2 += four[16]; sum1 += five[17]; sum2 += five[16]; P->dest[17] = sum1; P->dest[16] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 16: sum1 = one[15] + two[15]; sum2 = one[14] + two[14]; sum1 += three[15]; sum2 += three[14]; sum1 += four[15]; sum2 += four[14]; sum1 += five[15]; sum2 += five[14]; P->dest[15] = sum1; P->dest[14] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 14: sum1 = one[13] + two[13]; sum2 = one[12] + two[12]; sum1 += three[13]; sum2 += three[12]; sum1 += four[13]; sum2 += four[12]; sum1 += five[13]; sum2 += five[12]; P->dest[13] = sum1; P->dest[12] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 12: sum1 = one[11] + two[11]; sum2 = one[10] + two[10]; sum1 += three[11]; sum2 += three[10]; sum1 += four[11]; sum2 += four[10]; sum1 += five[11]; sum2 += five[10]; P->dest[11] = sum1; P->dest[10] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 10: sum1 = one[9] + two[9]; sum2 = one[8] + two[8]; sum1 += three[9]; sum2 += three[8]; sum1 += four[9]; sum2 += four[8]; sum1 += five[9]; sum2 += five[8]; P->dest[9] = sum1; P->dest[8] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 8: sum1 = one[7] + two[7]; sum2 = one[6] + two[6]; sum1 += three[7]; sum2 += three[6]; sum1 += four[7]; sum2 += four[6]; sum1 += five[7]; sum2 += five[6]; P->dest[7] = sum1; P->dest[6] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 6: sum1 = one[5] + two[5]; sum2 = one[4] + two[4]; sum1 += three[5]; sum2 += three[4]; sum1 += four[5]; sum2 += four[4]; sum1 += five[5]; sum2 += five[4]; P->dest[5] = sum1; P->dest[4] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 4: sum1 = one[3] + two[3]; sum2 = one[2] + two[2]; sum1 += three[3]; sum2 += three[2]; sum1 += four[3]; sum2 += four[2]; sum1 += five[3]; sum2 += five[2]; P->dest[3] = sum1; P->dest[2] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 2: sum1 = one[1] + two[1]; sum2 = one[0] + two[0]; sum1 += three[1]; sum2 += three[0]; sum1 += four[1]; sum2 += four[0]; sum1 += five[1]; sum2 += five[0]; P->dest[1] = sum1; P->dest[0] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif if (tmax1 > tmax2) return tmax1; return tmax2; } // // use for higher sum5 folds // float top_sum5(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("top_sum5()"); #endif float sum1, sum2, tmaxB, tmax; int i; float *one = ss[0]; float *two = ss[0]+P->tmp0; float *three = ss[0]+P->tmp1; float *four = ss[0]+P->tmp2; float *five = ss[0]+P->tmp3; tmaxB = tmax = float(0.0); for (i = 0 ; i < P->di-15; i += 16) { sum1 = one[i+0] + two[i+0]; sum2 = one[i+1] + two[i+1]; sum1 += three[i+0]; sum2 += three[i+1]; sum1 += four[i+0]; sum2 += four[i+1]; sum1 += five[i+0]; sum2 += five[i+1]; P->dest[i+0] = sum1; P->dest[i+1] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; sum1 = one[i+2] + two[i+2]; sum2 = one[i+3] + two[i+3]; sum1 += three[i+2]; sum2 += three[i+3]; sum1 += four[i+2]; sum2 += four[i+3]; sum1 += five[i+2]; sum2 += five[i+3]; P->dest[i+2] = sum1; P->dest[i+3] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; sum1 = one[i+4] + two[i+4]; sum2 = one[i+5] + two[i+5]; sum1 += three[i+4]; sum2 += three[i+5]; sum1 += four[i+4]; sum2 += four[i+5]; sum1 += five[i+4]; sum2 += five[i+5]; P->dest[i+4] = sum1; P->dest[i+5] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; sum1 = one[i+6] + two[i+6]; sum2 = one[i+7] + two[i+7]; sum1 += three[i+6]; sum2 += three[i+7]; sum1 += four[i+6]; sum2 += four[i+7]; sum1 += five[i+6]; sum2 += five[i+7]; P->dest[i+6] = sum1; P->dest[i+7] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; sum1 = one[i+8] + two[i+8]; sum2 = one[i+9] + two[i+9]; sum1 += three[i+8]; sum2 += three[i+9]; sum1 += four[i+8]; sum2 += four[i+9]; sum1 += five[i+8]; sum2 += five[i+9]; P->dest[i+8] = sum1; P->dest[i+9] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; sum1 = one[i+10] + two[i+10]; sum2 = one[i+11] + two[i+11]; sum1 += three[i+10]; sum2 += three[i+11]; sum1 += four[i+10]; sum2 += four[i+11]; sum1 += five[i+10]; sum2 += five[i+11]; P->dest[i+10] = sum1; P->dest[i+11] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; sum1 = one[i+12] + two[i+12]; sum2 = one[i+13] + two[i+13]; sum1 += three[i+12]; sum2 += three[i+13]; sum1 += four[i+12]; sum2 += four[i+13]; sum1 += five[i+12]; sum2 += five[i+13]; P->dest[i+12] = sum1; P->dest[i+13] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; sum1 = one[i+14] + two[i+14]; sum2 = one[i+15] + two[i+15]; sum1 += three[i+14]; sum2 += three[i+15]; sum1 += four[i+14]; sum2 += four[i+15]; sum1 += five[i+14]; sum2 += five[i+15]; P->dest[i+14] = sum1; P->dest[i+15] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; } for ( ; i < P->di; i++) { sum1 = (one[i] + two[i] ); sum2 = (three[i] + four[i] ); sum1 += five[i]; sum1 += sum2; P->dest[i] = sum1; if (sum1 > tmax) tmax = sum1; } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif if (tmax > tmaxB) return tmax; return tmaxB; } // // sum_func swi5tb[FOLDTBLEN] = { sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, top_sum5 }; // // float sw_sum2_t31(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("sw_sum2_t31"); #endif float sum1, sum2, tmax2, tmax1; int i = P->di; float *one = ss[1]+P->offset; float *two = ss[1]+P->tmp0; tmax2 = tmax1 = float(0.0); if ( i & 1 ) { i -= 1; tmax1 = one[i] + two[i]; P->dest[i] = tmax1; } switch (i) { case 30: sum1 = one[29] + two[29]; sum2 = one[28] + two[28]; P->dest[29] = sum1; P->dest[28] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 28: sum1 = one[27] + two[27]; sum2 = one[26] + two[26]; P->dest[27] = sum1; P->dest[26] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 26: sum1 = one[25] + two[25]; sum2 = one[24] + two[24]; P->dest[25] = sum1; P->dest[24] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 24: sum1 = one[23] + two[23]; sum2 = one[22] + two[22]; P->dest[23] = sum1; P->dest[22] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 22: sum1 = one[21] + two[21]; sum2 = one[20] + two[20]; P->dest[21] = sum1; P->dest[20] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 20: sum1 = one[19] + two[19]; sum2 = one[18] + two[18]; P->dest[19] = sum1; P->dest[18] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 18: sum1 = one[17] + two[17]; sum2 = one[16] + two[16]; P->dest[17] = sum1; P->dest[16] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 16: sum1 = one[15] + two[15]; sum2 = one[14] + two[14]; P->dest[15] = sum1; P->dest[14] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 14: sum1 = one[13] + two[13]; sum2 = one[12] + two[12]; P->dest[13] = sum1; P->dest[12] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 12: sum1 = one[11] + two[11]; sum2 = one[10] + two[10]; P->dest[11] = sum1; P->dest[10] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 10: sum1 = one[9] + two[9]; sum2 = one[8] + two[8]; P->dest[9] = sum1; P->dest[8] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 8: sum1 = one[7] + two[7]; sum2 = one[6] + two[6]; P->dest[7] = sum1; P->dest[6] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 6: sum1 = one[5] + two[5]; sum2 = one[4] + two[4]; P->dest[5] = sum1; P->dest[4] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 4: sum1 = one[3] + two[3]; sum2 = one[2] + two[2]; P->dest[3] = sum1; P->dest[2] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; case 2: sum1 = one[1] + two[1]; sum2 = one[0] + two[0]; P->dest[1] = sum1; P->dest[0] = sum2; if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif if (tmax1 > tmax2) return tmax1; return tmax2; } // // use for higher sum2 folds // float top_sum2(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("top_sum2()"); #endif float sum1, sum2, tmaxB, tmax; int i; float *one = ss[1]+P->offset; float *two = ss[1]+P->tmp0; tmaxB = tmax = float(0.0); for (i = 0 ; i < P->di-21; i += 22) { sum1 = one[i+0] + two[i+0]; sum2 = one[i+1] + two[i+1]; P->dest[i+0] = sum1; P->dest[i+1] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; sum1 = one[i+2] + two[i+2]; sum2 = one[i+3] + two[i+3]; P->dest[i+2] = sum1; P->dest[i+3] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; sum1 = one[i+4] + two[i+4]; sum2 = one[i+5] + two[i+5]; P->dest[i+4] = sum1; P->dest[i+5] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; sum1 = one[i+6] + two[i+6]; sum2 = one[i+7] + two[i+7]; P->dest[i+6] = sum1; P->dest[i+7] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; sum1 = one[i+8] + two[i+8]; sum2 = one[i+9] + two[i+9]; P->dest[i+8] = sum1; P->dest[i+9] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; sum1 = one[i+10] + two[i+10]; sum2 = one[i+11] + two[i+11]; P->dest[i+10] = sum1; P->dest[i+11] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; sum1 = one[i+12] + two[i+12]; sum2 = one[i+13] + two[i+13]; P->dest[i+12] = sum1; P->dest[i+13] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; sum1 = one[i+14] + two[i+14]; sum2 = one[i+15] + two[i+15]; P->dest[i+14] = sum1; P->dest[i+15] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; sum1 = one[i+16] + two[i+16]; sum2 = one[i+17] + two[i+17]; P->dest[i+16] = sum1; P->dest[i+17] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; sum1 = one[i+18] + two[i+18]; sum2 = one[i+19] + two[i+19]; P->dest[i+18] = sum1; P->dest[i+19] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; sum1 = one[i+20] + two[i+20]; sum2 = one[i+21] + two[i+21]; P->dest[i+20] = sum1; P->dest[i+21] = sum2; if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; } for ( ; i < P->di; i++) { sum1 = one[i] + two[i]; P->dest[i] = sum1; if (sum1 > tmax) tmax = sum1; } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif if (tmax > tmaxB) return tmax; return tmaxB; } sum_func swi2tb[FOLDTBLEN] = { sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, top_sum2 }; // // FoldSet swifold = {swi3tb, swi4tb, swi5tb, swi2tb, swi2tb, "FPU opt"}; // Arrays from which folding subroutines will be chosen during execution. // Other sets can be inserted to replace the defaults. // sum_func sumsel3[FOLDTBLEN] = { sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, top_sum3 }; sum_func sumsel4[FOLDTBLEN] = { sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, top_sum4 }; sum_func sumsel5[FOLDTBLEN] = { sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, top_sum5 }; sum_func sumsel2[FOLDTBLEN] = { sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, top_sum2 }; sum_func sumsel2AL[FOLDTBLEN] = { sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, top_sum2 }; FoldSet Foldmain = {sumsel3, sumsel4, sumsel5, sumsel2, sumsel2AL, "opt FPU"}; /********************** * * Routine to copy fold subroutine tables. * */ int CopyFoldSet(FoldSet *dst, FoldSet *src) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("CopyFoldSet()"); #endif int i, j3, j4, j5, j2, j2AL; j3 = j4 = j5 = j2 = j2AL = 0; for (i = 0; i < FOLDTBLEN; i++) { if (src->f3[i] != 0) { dst->f3[i] = src->f3[i]; j3 = i; } else dst->f3[i] = src->f3[j3]; if (src->f4[i] != 0) { dst->f4[i] = src->f4[i]; j4 = i; } else dst->f4[i] = src->f4[j4]; if (src->f5[i] != 0) { dst->f5[i] = src->f5[i]; j5 = i; } else dst->f5[i] = src->f5[j5]; if (src->f2[i] != 0) { dst->f2[i] = src->f2[i]; j2 = i; } else dst->f2[i] = src->f2[j2]; if (src->f2AL[i] != 0) { dst->f2AL[i] = src->f2AL[i]; j2AL = i; } else dst->f2AL[i] = src->f2AL[j2AL]; } dst->name = src->name; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } /********************** * * t_funct - Caching routine for calls to invert_lcgf, return cache value if present * * This version caches and returns the threshold factor for dis_thresh rather than cur_thresh. * * The threshold factor assumes folding subroutines which do NOT divide the sums by num_adds. */ float t_funct(int m, int n, int x) { static struct tftab { int n; float y; } *t_funct_tab; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("t_funct()"); #endif float c_dis_thresh = (float)swi.analysis_cfg.pulse_display_thresh; if (!t_funct_tab) { int tablen = (PoTInfo.PulseMax+2)/3 + 3*(int)(log((float)PoTInfo.PulseMax)/log(2.0)-3) - 1; t_funct_tab=(struct tftab *)malloc_a(tablen*sizeof(struct tftab),MEM_ALIGN); if (!t_funct_tab) SETIERROR(MALLOC_FAILED, "!t_funct_tab"); memset(t_funct_tab, 0, tablen*sizeof(struct tftab)); } if (t_funct_tab[x].n!=n) { t_funct_tab[x].n=n; t_funct_tab[x].y = (invert_lcgf((float)(-PoTInfo.PulseThresh - log((float)m)), (float)n, (float)1e-4) - n) * c_dis_thresh + n; } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return t_funct_tab[x].y; } /********************** * * Preplanning routine called from find_pulse() * */ int plan_PulsePoT(PoTPlan * PSeq, int PulsePotLen, float *div, int *dbinoffs) { float period; int ndivs; int i, j, di, dbins, offset; int num_adds_2; long p; unsigned long cperiod; int num_adds; register float tmp_max,t1; int res=1; int k = 0; // plan index #ifdef USE_MANUAL_CALLSTACK call_stack.enter("plan_PulsePoT()"); #endif for (i = 32, ndivs = 1; i <= PulsePotLen; ndivs++, i *= 2); int32_t thePotLen = PulsePotLen; // Periods from PulsePotLen/3 to PulsePotLen/4, and power of 2 fractions of. // then (len/4 to len/5) and finally (len/5 to len/6) // int32_t firstP, lastP; for(num_adds = 3; num_adds <= 5; num_adds++) { int num_adds_minus1; switch(num_adds) { case 3: lastP = (thePotLen*2)/3; firstP = (thePotLen*1)/2; num_adds_minus1 = 2; break; case 4: lastP = (thePotLen*3)/4; firstP = (thePotLen*3)/5; num_adds_minus1 = 3; break; case 5: lastP = (thePotLen*4)/5; firstP = (thePotLen*4)/6; num_adds_minus1 = 4; break; } for (p = lastP ; p > firstP ; p--) { int tabofst = ndivs*3+2-num_adds; PSeq[k].dest = div+dbinoffs[0]; // Output storage PSeq[k].cperiod = cperiod = p*(C3X2TO14 / num_adds_minus1); PSeq[k].tmp0 = (int)((cperiod+C3X2TO13)/C3X2TO14); PSeq[k].tmp1 = (int)((cperiod*2+C3X2TO13)/C3X2TO14); PSeq[k].di = di = (int)cperiod/C3X2TO14; PSeq[k].na = num_adds; PSeq[k].thresh = t_funct(di, num_adds, di+tabofst); switch(num_adds) { case 3: PSeq[k].fun_ptr = (di < FOLDTBLEN) ? sumsel3[di] : sumsel3[FOLDTBLEN-1]; break; case 4: PSeq[k].tmp2 = (int)((cperiod*3+C3X2TO13)/C3X2TO14); PSeq[k].fun_ptr = (di < FOLDTBLEN) ? sumsel4[di] : sumsel4[FOLDTBLEN-1]; break; case 5: PSeq[k].tmp2 = (int)((cperiod*3+C3X2TO13)/C3X2TO14); PSeq[k].tmp3 = (int)((cperiod*4+C3X2TO13)/C3X2TO14); PSeq[k].fun_ptr = (di < FOLDTBLEN) ? sumsel5[di] : sumsel5[FOLDTBLEN-1]; break; } k++; // next plan num_adds_2 = 2* num_adds; for (j = 1; j < ndivs ; j++) { tabofst -= 3; PSeq[k].offset = dbinoffs[j-1]; PSeq[k].dest = div+dbinoffs[j]; PSeq[k].cperiod = PSeq[k-1].cperiod/2; PSeq[k].tmp0 = di & 1; PSeq[k].di = di = PSeq[k].cperiod/C3X2TO14; PSeq[k].tmp0 += di + PSeq[k].offset; //PSeq[k].offset + (PSeq[k].cperiod+C3X2TO13)/C3X2TO14 if (PSeq[k].tmp0 & 3) PSeq[k].fun_ptr = (di < FOLDTBLEN) ? sumsel2[di] : sumsel2[FOLDTBLEN-1]; else PSeq[k].fun_ptr = (di < FOLDTBLEN) ? sumsel2AL[di] : sumsel2AL[FOLDTBLEN-1]; PSeq[k].na = num_adds_2; PSeq[k].thresh = t_funct(di, num_adds_2, di+tabofst); k++; // next plan num_adds_2 *=2; } // for (j = 1; j < ndivs } // for (p = lastP } // for(num_adds = PSeq[k].di = 0; // stop #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return (k); } /********************** * * find_pulse - uses a folding algorithm to find repeating pulses * Initially folds by prime number then by powers of two. * * Initial code by Eric Korpela * Major revisions and optimization by Ben Herndon * Further revised by Joe Segur * */ int find_pulse(const float * fp_PulsePot, int PulsePotLen, float pulse_thresh, int TOffset, int FOffset) { static float *div,*FoldedPOT; static int *dbinoffs, PrevPPL, PrevPoTln; static PoTPlan *PSeq; static float rcfg_dis_thresh = 1.0f / (float)swi.analysis_cfg.pulse_display_thresh; PoTPlan PTPln = {0} ; float *SrcSel[2]; float period; int blksize; int ndivs; int i, j, di, maxs = 0; int num_adds, num_adds_2; long p; float max=0,maxd=0,avg=0,maxp=0, snr=0, fthresh=0,total=0.0f,partial; register float tmp_max,t1; int res=1; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("find_pulse()"); #endif // debug possible heap corruption -- jeffc #ifdef _WIN32 BOINCASSERT(_CrtCheckMemory()); #endif #ifdef DEBUG_PULSE_VERBOSE fprintf(stderr, "In find_pulse()... PulsePotLen = %d pulse_thresh = %f TOffset = %d PoT = %d\n", PulsePotLen, pulse_thresh, TOffset, FOffset); #endif // boinc_worker_timer(); // Create internal arrays.... if (!div) { int n, maxdivs = 1; for (i = 32; i <= PoTInfo.PulseMax; maxdivs++, i *= 2); div=(float *)calloc_a(((PoTInfo.PulseMax*7/4)+maxdivs*MEM_ALIGN/sizeof(float)), sizeof(float), MEM_ALIGN); FoldedPOT=(float *)malloc_a((PoTInfo.PulseMax+1)*sizeof(float)/3, MEM_ALIGN); dbinoffs=(int *)malloc_a(maxdivs*sizeof(int), MEM_ALIGN); for (i = 32, n = 1; i <= PPLANMAX; n++, i *= 2); i = ((PPLANMAX*2)/3)-((PPLANMAX*2)/4); i += ((PPLANMAX*3)/4)-((PPLANMAX*3)/5); i += ((PPLANMAX*4)/5)-((PPLANMAX*4)/6); i *= n; PSeq = (PoTPlan *)malloc_a((i+1)*sizeof(PoTPlan), MEM_ALIGN); if ((!div) || (!FoldedPOT) || (!dbinoffs) || (!PSeq)) SETIERROR(MALLOC_FAILED, "(!div) || (!FoldedPOT) || (!dbinoffs) || (!PSeq)"); if (t_funct(6,1000,0)<0) SETIERROR(MALLOC_FAILED, "t_funct(6,1000,0)<0");; } SrcSel[0] = (float *)fp_PulsePot; // source of data for 3, 4, 5 folds SrcSel[1] = div; // source of data for 2 folds /* Uncomment this block if res > 1 is ever actually used // Rebin to lower resolution if required if (res <= 1) { memcpy(div,fp_PulsePot,PulsePotLen*sizeof(float)); } else { for (j=0;jdis_thresh) { // unscale for reporting tmp_max /= PSeq[k].na; cur_thresh = (dis_thresh / PSeq[k].na - avg) * rcfg_dis_thresh + avg; ReportPulseEvent(tmp_max/avg,avg,res*(float)PSeq[k].cperiod/(float)C3X2TO14, TOffset+PulsePotLen/2,FOffset, (tmp_max-avg)*(float)sqrt((float)PSeq[k].na)/avg, (cur_thresh-avg)*(float)sqrt((float)PSeq[k].na)/avg, PSeq[k].dest, PSeq[k].na, 0); if ((tmp_max>cur_thresh) && ((t1=tmp_max-cur_thresh)>maxd)) { maxp = (float)PSeq[k].cperiod/(float)C3X2TO14; maxd = t1; maxs = PSeq[k].na; max = tmp_max; snr = (float)((tmp_max-avg)*sqrt((float)PSeq[k].na)/avg); fthresh=(float)((cur_thresh-avg)*sqrt((float)PSeq[k].na)/avg); memcpy(FoldedPOT, PSeq[k].dest, PSeq[k].di*sizeof(float)); } } } // for ( k = } else { // If not plan, // Periods from PulsePotLen/3 to PulsePotLen/4, and power of 2 fractions of. // then (len/4 to len/5) and finally (len/5 to len/6) // int32_t firstP, lastP; for(num_adds = 3; num_adds <= 5; num_adds++) { int num_adds_minus1; switch(num_adds) { case 3: lastP = (thePotLen*2)/3; firstP = (thePotLen*1)/2; num_adds_minus1 = 2; break; case 4: lastP = (thePotLen*3)/4; firstP = (thePotLen*3)/5; num_adds_minus1 = 3; break; case 5: lastP = (thePotLen*4)/5; firstP = (thePotLen*4)/6; num_adds_minus1 = 4; break; } for (p = lastP ; p > firstP ; p--) { float cur_thresh, dis_thresh; int tabofst, mper, perdiv; tabofst = ndivs*3+2-num_adds; mper = p * (12/num_adds_minus1); perdiv = num_adds_minus1; PTPln.tmp0 = (int)((mper + 6)/12); // round(period) PTPln.tmp1 = (int)((mper * 2 + 6)/12); // round(period*2) PTPln.di = (int)p/perdiv; // (int)period PTPln.dest = div+dbinoffs[0]; // Output storage dis_thresh = t_funct(PTPln.di, num_adds, PTPln.di+tabofst)*avg; switch(num_adds) { case 3: tmp_max = (PTPln.di < FOLDTBLEN) ? sumsel3[PTPln.di](SrcSel, &PTPln) : sumsel3[FOLDTBLEN-1](SrcSel, &PTPln); break; case 4: PTPln.tmp2 = (int)((mper * 3 + 6)/12); // round(period*3) tmp_max = (PTPln.di < FOLDTBLEN) ? sumsel4[PTPln.di](SrcSel, &PTPln) : sumsel4[FOLDTBLEN-1](SrcSel, &PTPln); break; case 5: PTPln.tmp2 = (int)((mper * 3 + 6)/12); // round(period*3) PTPln.tmp3 = (int)((mper * 4 + 6)/12); // round(period*4) tmp_max = (PTPln.di < FOLDTBLEN) ? sumsel5[PTPln.di](SrcSel, &PTPln) : sumsel5[FOLDTBLEN-1](SrcSel, &PTPln); break; } if (tmp_max>dis_thresh) { // unscale for reporting tmp_max /= num_adds; cur_thresh = (dis_thresh / num_adds - avg) * rcfg_dis_thresh + avg; ReportPulseEvent(tmp_max/avg,avg,((float)p)/(float)perdiv*res, TOffset+PulsePotLen/2,FOffset, (tmp_max-avg)*(float)sqrt((float)num_adds)/avg, (cur_thresh-avg)*(float)sqrt((float)num_adds)/avg, PTPln.dest, num_adds, 0); if ((tmp_max>cur_thresh) && ((t1=tmp_max-cur_thresh)>maxd)) { maxp = (float)p/(float)perdiv; maxd = t1; maxs = num_adds; max = tmp_max; snr = (float)((tmp_max-avg)*sqrt((float)num_adds)/avg); fthresh=(float)((cur_thresh-avg)*sqrt((float)num_adds)/avg); memcpy(FoldedPOT, PTPln.dest, PTPln.di*sizeof(float)); } } num_adds_2 = 2* num_adds; for (j = 1; j < ndivs ; j++) { PTPln.offset = dbinoffs[j-1]; PTPln.dest = div+dbinoffs[j]; perdiv *=2; PTPln.tmp0 = PTPln.di & 1; PTPln.di /= 2; PTPln.tmp0 += PTPln.di + PTPln.offset; tabofst -=3; dis_thresh = t_funct(PTPln.di, num_adds_2, PTPln.di+tabofst) * avg; if (PTPln.tmp0 & 3) tmp_max = (PTPln.di < FOLDTBLEN) ? sumsel2[PTPln.di](SrcSel, &PTPln) : sumsel2[FOLDTBLEN-1](SrcSel, &PTPln); else tmp_max = (PTPln.di < FOLDTBLEN) ? sumsel2AL[PTPln.di](SrcSel, &PTPln) : sumsel2AL[FOLDTBLEN-1](SrcSel, &PTPln); if (tmp_max>dis_thresh) { // unscale for reporting tmp_max /= num_adds_2; cur_thresh = (dis_thresh / num_adds_2 - avg) * rcfg_dis_thresh + avg; ReportPulseEvent(tmp_max/avg,avg,((float)p)/(float)perdiv*res, TOffset+PulsePotLen/2,FOffset, (tmp_max-avg)*(float)sqrt((float)num_adds_2)/avg, (cur_thresh-avg)*(float)sqrt((float)num_adds_2)/avg, PTPln.dest, num_adds_2, 0); if ((tmp_max>cur_thresh) && ((t1=tmp_max-cur_thresh)>maxd)) { maxp = (float)p/(float)perdiv; maxd = t1; maxs = num_adds_2; max = tmp_max; snr = (float)((tmp_max-avg)*sqrt((float)num_adds_2)/avg); fthresh = (float)((cur_thresh-avg)*sqrt((float)num_adds_2)/avg); memcpy(FoldedPOT, PTPln.dest, PTPln.di*sizeof(float)); } } num_adds_2 *=2; } // for (j = 1; j < ndivs } // for (p = lastP } // for(num_adds = } analysis_state.FLOP_counter+=(PulsePotLen*0.1818181818182+400.0)*PulsePotLen; if (maxp!=0) ReportPulseEvent(max/avg,avg,maxp*res,TOffset+PulsePotLen/2,FOffset, snr, fthresh, FoldedPOT, maxs, 1); // debug possible heap corruption -- jeffc #ifdef _WIN32 BOINCASSERT(_CrtCheckMemory()); #endif #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } boinc-app-seti_8.00~svn3701.orig/client/autocorr.cpp0000644000175000017500000001367612643777667022400 0ustar locutuslocutus// Copyright 2011 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. #include "sah_config.h" #include #include #include #include #include #include #include #ifdef BOINC_APP_GRAPHICS #include "graphics2.h" #endif #include "util.h" #include "s_util.h" #include "analyze.h" #include "gaussfit.h" #include "seti.h" #include "chirpfft.h" #include "analyzeReport.h" #include "analyzePoT.h" #ifdef BOINC_APP_GRAPHICS #include "sah_gfx_main.h" #endif #include "../db/schema_master.h" int FindAutoCorrelation( float * AutoCorrelation, int ul_NumDataPoints, int fft_num, SETI_WU_INFO& swi ) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("FindAutoCorrelation()"); #endif // Because positive and negative delays are the same // we only have to look at half the points int i, j, k, m, retval, blksize; float temp; float total, MeanPower, partial; AUTOCORR_INFO ai; i = j = k = m = 0; total = 0.0f; int len = ul_NumDataPoints/2; blksize = UNSTDMAX(4, UNSTDMIN(pow2((unsigned int) sqrt((float) (len / 32)) * 32), 512)); for(int b = 0; b < len/blksize; b++) { partial = 0.0f; for(i = 0; i < blksize; i++) { AutoCorrelation[b*blksize+i]*=AutoCorrelation[b*blksize+i]; partial += AutoCorrelation[b*blksize+i]; } total += partial; } MeanPower = total / ul_NumDataPoints; // Here we extract the autocorrs_to_report highest power events, // outputing them as we go. // Index usage: // i : walk power spectrum us_NumToReport times // j : walks power spectrum for each i // k : marks current high power candidate while j walks on // m : marks the current tail of the high power hit "list" for (i = 0; i < swi.analysis_cfg.autocorr_per_spectrum; i++) { temp = 0.0; // Walk the array, looking for the first/next highest power. // Start j at 1, in order to skip the DC (ie 0) bin. // NOTE: this is a simple scan for high powers. Nice and fast // for a very low i. If i is substantial, this code should be // replaced with an index (q)sort. for (j = 1; j < ul_NumDataPoints/2; j++) { if (AutoCorrelation[j] > temp) { if (AutoCorrelation[j] < AutoCorrelation[m] || m == 0) { temp = AutoCorrelation[j]; k = j; } } } // temp now = first/next highest power and k = it's bin number m = k; // save the "lowest" highest. //JWS: Sanity check, delayed peaks cannot be higher than the zero delay power. if (temp > AutoCorrelation[0]) { boinc_temporary_exit(5*60,"Impossible Autocorr power, retrying from checkpoint.",true); } // autocorr info ai.a.peak_power = temp/MeanPower; ai.a.mean_power = 1.0; ai.bin = k; ai.fft_ind = fft_num; ai.a.chirp_rate = ChirpFftPairs[analysis_state.icfft].ChirpRate; ai.a.fft_len = ChirpFftPairs[analysis_state.icfft].FftLen; ai.a.delay = ((float)ai.bin)/swi.subband_sample_rate; ai.a.freq = swi.subband_center; double t_offset=((double)ai.fft_ind+0.5)*(double)ai.a.fft_len/ swi.subband_sample_rate; ai.a.detection_freq=calc_detection_freq(ai.a.freq,ai.a.chirp_rate,t_offset); ai.a.time = swi.time_recorded + t_offset / 86400.0; time_to_ra_dec(ai.a.time, &ai.a.ra, &ai.a.decl); // Score used for "best of" and graphics. ai.score = ai.a.peak_power / AUTOCORR_SCORE_HIGH; ai.score = ai.score > 0.0 ? log10(ai.score) : -12.0; // if best_autocorr.s.fft_len == 0, there is not yet a first autocorr if (ai.score > best_autocorr->score || best_autocorr->a.fft_len == 0) { *best_autocorr = ai; if(verbose>=2){ fprintf(stderr,"Best autocorr updated:"); fprintf(stderr,"score=%.4g, peak_power=%.4g, bin=%d, fft_ind=%d, icfft=%d\n", ai.score,ai.a.peak_power,ai.bin,ai.fft_ind,analysis_state.icfft); } #ifdef BOINC_APP_GRAPHICS if (!nographics()) sah_graphics->ai.copy(&ai); #endif } // Report a signal if it excceeds threshold. if (ai.a.peak_power > (swi.analysis_cfg.autocorr_thresh)) { retval = result_autocorr(ai); if(verbose>=1){ int fft=(ai.a.fft_len>1024)?(ai.a.fft_len/1024):(ai.a.fft_len); char symbol=(ai.a.fft_len>1024)?('k'):(' '); fprintf(stderr,"Autocorr: peak=%.7g, time=%.4g, delay=%.5g, d_freq=%.12g, chirp=%.5g, fft_len=%d%c\n", ai.a.peak_power,(ai.a.time-swi.time_recorded)*86400,ai.a.delay,ai.a.detection_freq,ai.a.chirp_rate,fft,symbol); } if (retval) SETIERROR(retval,"from result_autocorr()"); } } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } boinc-app-seti_8.00~svn3701.orig/client/progress.cpp0000644000175000017500000001723512313644616022356 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // progress.C #include "sah_config.h" #include #include #include #include #include "diagnostics.h" #include "util.h" #include "s_util.h" #ifdef BOINC_APP_GRAPHICS #include "sah_gfx_main.h" #endif #include "progress.h" #include "analyzePoT.h" #include "seti.h" #include "chirpfft.h" double NormalizedToSpike = 0.0; double triplet_units; double pulse_units; double spike_units; double gauss_units; // fraction_done sets the boinc_fraction_done() with a smooth transition // from using "progress" to "remaining" to determine the fraction done. // The speed of the transition is determine by PROG_POWER. 6 means that // "remaining" is the dominant term for about the final 1/6th of the run. #define PROG_POWER 6 void fraction_done(double progress,double remaining) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("fraction_done"); #endif double prog2=1.0-remaining; progress=std::min(progress,1.0); double prog=progress*(1.0-pow(prog2,PROG_POWER))+prog2*pow(prog2,PROG_POWER); boinc_fraction_done(prog); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } void reset_units() { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("reset_units()"); #endif triplet_units=0; pulse_units=0; spike_units=0; gauss_units=0; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } float GetProgressUnitSize(int NumDataPoints, int num_cfft, long ac_fft_len) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("GetProgressUnitSize()"); #endif // A ProgressUnit is defined as the computation time of a // detection algorithm on the entire data block at a // given chirpfft pair. // Spike detection takes place for every FFT length and at // any slew rate. PoT detctors, on the other hand, may opt // to not execute if slew rate and/or FFT length limits are // not met. int i, ThisPoTLen, ThisPulsePoTLen, DummyOverlap; double NumProgressUnits; double LastChirpRate = 0.0f; double TotalSpikeProgressUnits = 0.0; double TotalGaussianProgressUnits = 0.0; double TotalPulseProgressUnits = 0.0; double TotalTripletProgressUnits = 0.0; double TotalChirpProgressUnits = 0.0; double rv; NumProgressUnits = 0.0; for (i = 0; i < num_cfft; i++) { // FFTs and spike finding TotalSpikeProgressUnits += SpikeProgressUnits(ChirpFftPairs[i].FftLen); // Autocorr FFTs and finding if ((long)ChirpFftPairs[i].FftLen == ac_fft_len) { TotalSpikeProgressUnits += SpikeProgressUnits(ChirpFftPairs[i].FftLen); } // Chirping if(ChirpFftPairs[i].ChirpRate != LastChirpRate) { TotalChirpProgressUnits += ChirpProgressUnits(); LastChirpRate = ChirpFftPairs[i].ChirpRate; } ThisPoTLen = NumDataPoints / ChirpFftPairs[i].FftLen; // Gaussians.... if (ChirpFftPairs[i].GaussFit) { TotalGaussianProgressUnits += GaussianProgressUnits(); } // Pulses and Triplets.... GetPulsePoTLen(ThisPoTLen, &ThisPulsePoTLen, &DummyOverlap); #ifdef USE_PULSE if(ChirpFftPairs[i].PulseFind) TotalPulseProgressUnits += PulseProgressUnits(ThisPulsePoTLen, ChirpFftPairs[i].FftLen - 1); #endif #ifdef USE_TRIPLET if(ThisPulsePoTLen >= PoTInfo.TripletMin && ThisPulsePoTLen <= PoTInfo.TripletMax) TotalTripletProgressUnits += TripletProgressUnits(); #endif } NumProgressUnits = TotalChirpProgressUnits + TotalSpikeProgressUnits + TotalGaussianProgressUnits + TotalPulseProgressUnits + TotalTripletProgressUnits; /* fprintf(stderr, "%f ChirpProgressUnits (%f\%)\n", TotalChirpProgressUnits, TotalChirpProgressUnits/NumProgressUnits); fprintf(stderr, "%f SpikeProgressUnits (%f\%)\n", TotalSpikeProgressUnits, TotalSpikeProgressUnits/NumProgressUnits); fprintf(stderr, "%f GaussianProgressUnits (%f\%)\n", TotalGaussianProgressUnits, TotalGaussianProgressUnits/NumProgressUnits); fprintf(stderr, "%f TripletProgressUnits (%f\%)\n", TotalTripletProgressUnits, TotalTripletProgressUnits/NumProgressUnits); fprintf(stderr, "%f PulseProgressUnits (%f\%)\n", TotalPulseProgressUnits, TotalPulseProgressUnits/NumProgressUnits); fprintf(stderr, "%f NumProgressUnits\n", NumProgressUnits); */ // Add a fudge factor of 0.01% to make sure we do not hit 100% done too soon rv=(1.0f/(float)(NumProgressUnits + NumProgressUnits * 0.0001)); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return rv; } // Algorithm specific functions that return the number of progress // units for the entire data block for some chirp/fft pair. All other // algorithms are normalized to fft/spike finding, which is said // to take 1.0 progress units. // If progress us updated at finer intervals than the computation // on the entire data block, care must be taken to divide the // return value by the number of such intervals in a data block. // Eg, if you update for each FFT bin, divide the number of units // by FFT length. double SpikeProgressUnits(int FftLen) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("SpikeProgressUnits()"); #endif spike_units+=(1.0+log((double)FftLen)/11.783); double rv=(1.0+log((double)FftLen)/11.783); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return rv; } double GaussianProgressUnits() { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("GaussianProgressUnits()"); #endif gauss_units+=(14.5*0.6); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return(14.5*0.6); } // Pulse finding is an (n^2)log(n) computation. The final factor // is a scaling factor and can be tuned. double PulseProgressUnits(double PulsePoTLen, int FftLen) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("PulseProgressUnits()"); #endif pulse_units+=(PulsePoTLen * PulsePoTLen * log(PulsePoTLen) * FftLen / 2.65e6/4); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return(PulsePoTLen * PulsePoTLen * log(PulsePoTLen) * FftLen / 2.65e6/4); } double TripletProgressUnits() { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("TripletProgressUnits()"); #endif triplet_units+=0.1; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return(0.1); } double ChirpProgressUnits() { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("ChirpProgressUnits()"); call_stack.exit(); #endif return (2.0); } boinc-app-seti_8.00~svn3701.orig/client/analyzeFuncs.h0000644000175000017500000001175412313644616022621 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // Title : analyzeFuncs.h // $Id: analyzeFuncs.h,v 1.5.2.9 2007/05/31 22:03:09 korpela Exp $ #ifndef ANALYZE_FUNCS_H #include "seti.h" // The PROGRESS_FACTORs are based on the relative time that // it takes to apply the given algorithm to the data block, // at some given chirp/fft pair. They are more flakey than // I would like. On rewrite, I would run calibrating // benchmarks on program startup. // // The GAUSS_PROGRESS_FACTOR of 10 seems about right for gaussian // finding at an FFT length of 16K and maybe 8K. At shorter FFTs, // gaussian finding goes alot faster, but this situation occurs a // lot fewer times and so it's contribution gets washed out. // // Pulse finding with array size 14 is given 1 factor unit, as that // very roughly takes the same amount of time as FFT/spike finding. // As the array size doubles, the number of factor units will also // double. N here is the array size. /* These constants are no longer used, see functions in progress.cpp #define SPIKE_PROGRESS_FACTOR 1.0f #define CHIRP_PROGRESS_FACTOR 2.0f #define GAUSS_PROGRESS_FACTOR 10.0f #define TRIPLET_PROGRESS_FACTOR 0.1f #define PULSE_PROGRESS_FACTOR(N) (N/14.0f) */ #define KILOBYTE 1024L #define MEGABYTE 1048576L #ifdef ANDROID #define MIN_TRANSPOSE_MEMORY static_cast(512*MEGABYTE) #define MIN_TRIGARRAY_MEMORY static_cast(384*MEGABYTE) #else #define MIN_TRANSPOSE_MEMORY static_cast(96*MEGABYTE) #define MIN_TRIGARRAY_MEMORY static_cast(64*MEGABYTE) #endif #define FFTW_MEASURE_OR_ESTIMATE ((app_init_data.host_info.m_nbytes >= MIN_TRANSPOSE_MEMORY)?FFTW_MEASURE:FFTW_ESTIMATE) #define PROGRESS_DISPLAY_RES 1.0 // for text-only versions: display progress with every 1% extern int seti_analyze(ANALYSIS_STATE&); #include "vector/analyzeFuncs_vector.h" extern int v_BaseLineSmooth( sah_complex * cx_DataIn, int ul_NumDataPoints, int ul_BoxCarLength, int ul_TimeLength ); extern int v_GetPowerSpectrum( sah_complex * cx_FreqData, float * fp_PowerSpectrum, int ul_NumDataPoints ); #define TESTCHIRPIND 27040 extern int v_ChirpData( sah_complex * cx_DataArray, sah_complex * cx_ChirpDataArray, int ChirpRateInd, double ChirpRate, int ul_NumDataPoints, double sample_rate ); extern int v_Transpose(int xsize, int ysize, float *in, float *out); extern int v_Transpose2(int xsize, int ysize, float *in, float *out); extern int v_Transpose4(int xsize, int ysize, float *in, float *out); extern int v_Transpose8(int xsize, int ysize, float *in, float *out); extern BaseLineSmooth_func BaseLineSmooth; extern GetPowerSpectrum_func GetPowerSpectrum; extern ChirpData_func ChirpData; extern Transpose_func Transpose; // These are used to calculate chirped signals // TrigStep contains trigonometric functions for MinChirpStep over time // CurrentTrig contains current trigonometric fuctions // Tetsuji "Maverick" Rai // Trigonometric arrays typedef struct {double Sin, Cos; } SinCosArray; extern SinCosArray* TrigStep; // trigonometric array of MinChirpStep extern SinCosArray* CurrentTrig; // current chirprate trigonometric array extern int CurrentChirpRateInd; // current chirprate index (absolute value) extern double MinChirpStep; extern bool use_transposed_pot; //extern float GetProgressUnitSize(int NumDataPoints, int num_cfft, SETI_WU_INFO& swi); extern float GetProgressUnitSize(int NumDataPoints, int num_cfft); extern double ProgressUnitSize; extern double progress; extern double remaining; extern float min_slew; extern float max_slew; #endif boinc-app-seti_8.00~svn3701.orig/client/malloc_a.cpp0000644000175000017500000001146312313644616022256 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // $Id: malloc_a.cpp,v 1.6.2.5 2007/05/31 22:03:10 korpela Exp $ #include "sah_config.h" #include #include #include #ifdef HAVE_MEMORY_H #include #endif #ifdef HAVE_MALLOC_H #include #endif //JWS: fftwf_malloc() is inadequate for AVX, XOP, and future SIMD > 128 bit //#ifdef USE_FFTWF //#include //#endif #include "diagnostics.h" #include "malloc_a.h" // for processor portability (e.g. 32/64/etc, bit processors) typedef size_t PointerArith; // malloc_a and free_a are used to allocate one memory block // Allocates memory on N-byte boundary // // When fftwf is used, we use fftwf_malloc and ignore the alignment setting, // since this guarantees proper alignment for SIMD types. // // On WIN32, we use _aligned_malloc() // // Where memalign() is available, we use it. // // If none of the above, we use our own algorithm. // // Layout in memory of the pointers and buffer: // // +-- malloc'd memory pointer // | // | +-- save malloc'd memory pointer here for use with free_a() // V V // +--------+---+------------------- ... // | unused |ptr| aligned buffer // +--------+---+------------------- ... // ^ // | // +-- aligned memory pointer returned from malloc_a() // // // void *malloc_a(size_t size, size_t alignment) { void *palignedMem; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("malloc_a()"); #endif //#if defined(USE_FFTWF) // return fftwf_malloc(size); //#elif defined(HAVE__ALIGNED_MALLOC) #if defined(HAVE__ALIGNED_MALLOC) palignedMem=_aligned_malloc(size,alignment); #elif defined(HAVE_POSIX_MEMALIGN) if (posix_memalign(&palignedMem,alignment,size)) palignedMem=NULL; #elif defined(HAVE_MEMALIGN) palignedMem=memalign(alignment,size); #else PointerArith byteAlignment; void *pmem; void **pp; // ensure byteAlignment is positive (if alignment is 0, make it 1) if (alignment < 1) { alignment = 1; } byteAlignment = alignment - 1; pmem = (void *) malloc(size + byteAlignment + sizeof(void *)); // allocate memory if (pmem == NULL) return NULL; // align memory on N byte boundary palignedMem = (void *) (((PointerArith) pmem + byteAlignment + sizeof(void *)) & ~(byteAlignment)); pp = (void **) palignedMem; pp[-1] = pmem; // store original address #endif #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return palignedMem; // return aligned memory } //Frees memory that was allocated with malloc_a void free_a(void *palignedMem) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("free_a()"); #endif //#if defined(USE_FFTWF) // fftwf_free(palignedMem); //#elif defined(HAVE__ALIGNED_FREE) #if defined(HAVE__ALIGNED_FREE) _aligned_free(palignedMem); #elif defined(HAVE_MEMALIGN) || defined(HAVE_POSIX_MEMALIGN) free(palignedMem); #else void **pp; if (palignedMem == NULL) { #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return; } pp = (void **) palignedMem; //pp[-1] pts to original address of malloc'd memory free(pp[-1]); #endif #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } void *calloc_a(size_t size, size_t nitems, size_t alignment) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("calloc_a"); #endif void* p = malloc_a(size*nitems, alignment); if (p) memset(p, 0, size*nitems); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return p; } boinc-app-seti_8.00~svn3701.orig/client/Makefile.Readme0000644000175000017500000000262710671336410022634 0ustar locutuslocutusThis readme will explain the differences between Makefile.in and Makefile.in.graphics, as well as usage and possible changes to be made to be system compliant. To use Makefile.in.graphics just rename it Makefile.in and configure seti_boinc. The changes between the original Makefile.in and Makefile.in.graphics are: CFLAGS: addition of -DBOINC_APP_GRAPHICS BOINC_INC: addition of -I/usr/openwin/share/include (possibly extraneous) addition of -I$(BOINCDIR)/boincglut/include -I../jpeglib CXX, CC: addition of -g debug option (not vital) GUIOBJS: addition of all the files prexisting under OBJS, as well as graphics_api, x_opengl, grahpics_data from ../../boinc/api and sah_gfx_base, sah_gfx, and gdata (all .$(OBJEXT)) GUILIBS: addition of -lX11, -lXmu, -L$(BOINCDIR)/boincglut/lib/glut -lboincglut -L../jpeglib -ljpeg THE FOLLOWING ADDITION IS SYSTEM DEPENDENT: the location of the GL and GLU libraries on the system (ie /usr/X11R6/lib in Linux, -L/usr/openwin/lib/ on Solaris) followed by -lGL and -lGLU all: change PROGS to GUIPROG (possible to have both? I couldn't figure out how) GUIPROG: addition of main.$(OBJEXT) to dependencies addition of main.$(OBJEXT), gutil.$(OBJEXT), reduce.$(OBJEXT), $(LIBS), -lpthread to rule The only thing that should need to be changed is the location of the GL libraries as mentioned, but it's possible that other changes should be made. - Noaa Avitalboinc-app-seti_8.00~svn3701.orig/client/sah_version.cpp0000644000175000017500000000315210671336410023016 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // $Id: sah_version.cpp,v 1.1.2.1 2007/05/31 22:08:12 korpela Exp $ #include "sah_config.h" int gmajor_version = VERSION_MAJOR; int gminor_version = VERSION_MINOR; boinc-app-seti_8.00~svn3701.orig/client/seti_header.h0000644000175000017500000001050410671336410022416 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. /* * * $Id: seti_header.h,v 1.7.2.5 2007/05/31 22:03:11 korpela Exp $ * */ #ifndef SETI_HEADER_H #define SETI_HEADER_H #ifndef _WIN32 #include #include #endif #include "timecvt.h" #include "db/db_table.h" #include "db/schema_master.h" #undef USE_MYSQL #define SRC_SYNTHETIC 1 #define SRC_ARECIBO_1420 2 #define NUM_SRCS 3 #define DATA_ASCII 1 #define DATA_ENCODED 2 #define DATA_SUN_BINARY 3 #define MAX_SCOPE_STRINGS 32 #define MAX_NUM_FFTS 64 #define MAX_CFFT_PARAMS 2 // Variables of type ChirpFftTable_t (usually an array of such // variables) indicate a range of chirp rates and the FFT // lenghts (spectral resolutions) that we wish to process within // said chirp range. typedef struct { double MaxChirpRate; // Upper bound for this range. // Lower bound is MaxChirpRate of the previous // ChirpFftTable_t element. Lower bound // of first ChirpFftTable_t element is assumed to be zero. unsigned char DoFft[MAX_NUM_FFTS]; // Boolean - do this FFT length while in // this chirp range } ChirpFftTable_t; struct SCOPE_STRING : public track_mem { TIME st; double alt, az; double ra, dec; SCOPE_STRING() : track_mem("SCOPE_STRING") {} }; struct SETI_WU_INFO : public track_mem { int data_type; int data_class; int splitter_version; double start_ra; // 0 .. 24 double start_dec; // -90 .. 90 double end_ra; double end_dec; double angle_range; // in degrees (only for 0.1 degree beam) double true_angle_range; // in degrees double time_recorded; // in Julian form double subband_center; // Hz This parameter is deprecated in favor of // subband_base double subband_base; // center freq of bin 0. double subband_sample_rate; int fft_len; int ifft_len; int subband_number; receiver_config receiver_cfg; unsigned long nsamples; unsigned int bits_per_sample; std::vector::const_iterator position_history; size_t num_positions; // number_of_positions in history array char tape_version[16]; analysis_config analysis_cfg; int num_fft_lengths; int analysis_fft_lengths[32]; double beam_width; ChirpFftTable_t chirp_fft_table[MAX_CFFT_PARAMS]; const workunit *wu; SETI_WU_INFO(); SETI_WU_INFO(const workunit &w); SETI_WU_INFO(const SETI_WU_INFO &s); }; extern int seti_write_wu_header(FILE*, int); extern int seti_write_wu_header(FILE*, int, SETI_WU_INFO swi); extern int seti_parse_wu_header(FILE*); extern int seti_parse_wu_header(FILE*, SETI_WU_INFO &swi); extern float cnvt_fftlen_hz(int); extern double cnvt_bin_hz(int, int); extern double cnvt_bin_hz_offset(int, int); extern float cnvt_fftind_time(int, int); extern float cnvt_gauss_offset_time(int offset); extern int cnvt_hz_bin(float freq, float sample_rate, int nbins); extern double calc_detection_freq(double freq, double chirp_rate, double t_offset); #endif boinc-app-seti_8.00~svn3701.orig/client/chirpfft.h0000644000175000017500000000424510671336410021754 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. #ifndef SAH_CHIRPFFT_H #define SAH_CHIRPFFT_H #define TEST_MIN_CHIRP_STEP 0.002776 // chirps .5 bins with 128K point FFT // Variable (usually an array of such // variables) to hold chirp/fft pairs. typedef struct { double ChirpRate; int ChirpRateInd; // chirprate index (= ChirpRate / MinChirpStep) int FftLen; int GaussFit; int PulseFind; } ChirpFftPair_t; size_t GenChirpFftPairs( ChirpFftPair_t ** ChirpFftPairs, double * MinChirpStep ); extern ChirpFftPair_t * ChirpFftPairs; extern char * cfft_file; void CalcChirpSteps(double* ChirpSteps, double* MinChirpStep); bool VeryClose(double a, double b, double CloseEnough); int ReadCFftFile(ChirpFftPair_t ** ChirpFftPairs, double * MinChirpStep); #endif boinc-app-seti_8.00~svn3701.orig/client/worker.h0000644000175000017500000000327112643777667021506 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // $Id: worker.h,v 1.5.2.2 2007/06/01 20:24:43 korpela Exp $ extern int common_init(); extern void worker(); extern char * cfft_file; extern char debug_cfft_file[]; extern int run_stage; #define PREGRX 0 #define GRXINIT 1 #define POSTINIT 2 boinc-app-seti_8.00~svn3701.orig/client/fft8g.cpp0000644000175000017500000007535612321065336021533 0ustar locutuslocutus// This code is from the General Purpose FFT (Fast Fourier/Cosine/Sine Transform) Package. // Copyright Takuya OOURA, 1996-2001 // (Email: ooura@kurims.kyoto-u.ac.jp or ooura@mmm.t.u-tokyo.ac.jp) // // You may use, copy, modify and distribute this code for any purpose // (include commercial use) and without fee. Please refer to this package // when you modify this code. // $Id: fft8g.cpp,v 1.4.2.3 2006/12/14 22:21:45 korpela Exp $ /* NOTE ON USE BY SETI@HOME : All floating point objects were changed from double precision to single precision. The function prototypes below were placed in file fft8g.h. Also, the following unused transforms were removed from the source: rdft: Real Discrete Fourier Transform ddst: Discrete Sine Transform dfct: Cosine Transform of RDFT (Real Symmetric DFT) dfst: Sine Transform of RDFT (Real Anti-symmetric DFT) Modified to use sincosf/sinf/cosf/atanf. Implementations of these are in sincos.h for machines without Fast Fourier/Cosine/Sine Transform dimension :one data length :power of 2 decimation :frequency radix :8, 4, 2 data :inplace table :use functions cdft: Complex Discrete Fourier Transform function prototypes void cdft(int, int, float *, int *, float *); void ddct(int, int, float *, int *, float *); -------- Complex DFT (Discrete Fourier Transform) -------- [definition] X[k] = sum_j=0^n-1 x[j]*exp(2*pi*i*j*k/n), 0<=k X[k] = sum_j=0^n-1 x[j]*exp(-2*pi*i*j*k/n), 0<=k ip[0] = 0; // first time only cdft(2*n, 1, a, ip, w); ip[0] = 0; // first time only cdft(2*n, -1, a, ip, w); [parameters] 2*n :data length (int) n >= 1, n = power of 2 a[0...2*n-1] :input/output data (float *) input data a[2*j] = Re(x[j]), a[2*j+1] = Im(x[j]), 0<=j= 2+sqrt(n) strictly, length of ip >= 2+(1<<(int)(log(n+0.5)/log(2))/2). ip[0],ip[1] are pointers of the cos/sin table. w[0...n/2-1] :cos/sin table (float *) w[],ip[] are initialized if ip[0] == 0. [remark] Inverse of cdft(2*n, -1, a, ip, w); is cdft(2*n, 1, a, ip, w); for (j = 0; j <= 2 * n - 1; j++) { a[j] *= 1.0 / n; } . ------- DCT (Discrete Cosine Transform) / Inverse of DCT -------- [definition] IDCT (excluding scale) C[k] = sum_j=0^n-1 a[j]*cos(pi*j*(k+1/2)/n), 0<=k DCT C[k] = sum_j=0^n-1 a[j]*cos(pi*(j+1/2)*k/n), 0<=k ip[0] = 0; // first time only ddct(n, 1, a, ip, w); ip[0] = 0; // first time only ddct(n, -1, a, ip, w); [parameters] n :data length (int) n >= 2, n = power of 2 a[0...n-1] :input/output data (float *) output data a[k] = C[k], 0<=k= 2+sqrt(n/2) strictly, length of ip >= 2+(1<<(int)(log(n/2+0.5)/log(2))/2). ip[0],ip[1] are pointers of the cos/sin table. w[0...n*5/4-1] :cos/sin table (float *) w[],ip[] are initialized if ip[0] == 0. [remark] Inverse of ddct(n, -1, a, ip, w); is a[0] *= 0.5; ddct(n, 1, a, ip, w); for (j = 0; j <= n - 1; j++) { a[j] *= 2.0 / n; } Appendix : The cos/sin table is recalculated when the larger table required. w[] and ip[] are compatible with all routines. */ #include "sah_config.h" #include "sincos.h" #include "s_util.h" #include "seti.h" void fft8g_start() {} void cdft(int n, int isgn, sah_complex *aa, int *ip, float *w) { void makewt(int nw, int *ip, float *w); void bitrv2(int n, int *ip, float *a); void bitrv2conj(int n, int *ip, float *a); void cftfsub(int n, float *a, float *w); void cftbsub(int n, float *a, float *w); #ifdef USE_MANUAL_CALLSTACK call_stack.enter("cdft()"); #endif float *a=(float *)aa; if (n > (ip[0] << 2)) { makewt(n >> 2, ip, w); } if (n > 4) { if (isgn >= 0) { bitrv2(n, ip + 2, a); cftfsub(n, a, w); } else { bitrv2conj(n, ip + 2, a); cftbsub(n, a, w); } } else if (n == 4) { cftfsub(n, a, w); } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } void ddct(int n, int isgn, float *a, int *ip, float *w) { void makewt(int nw, int *ip, float *w); void makect(int nc, int *ip, float *c); void bitrv2(int n, int *ip, float *a); void cftfsub(int n, float *a, float *w); void cftbsub(int n, float *a, float *w); void rftfsub(int n, float *a, int nc, float *c); void rftbsub(int n, float *a, int nc, float *c); void dctsub(int n, float *a, int nc, float *c); int j, nw, nc; float xr; nw = ip[0]; if (n > (nw << 2)) { nw = n >> 2; makewt(nw, ip, w); } nc = ip[1]; if (n > nc) { nc = n; makect(nc, ip, w + nw); } if (isgn < 0) { xr = a[n - 1]; for (j = n - 2; j >= 2; j -= 2) { a[j + 1] = a[j] - a[j - 1]; a[j] += a[j - 1]; } a[1] = a[0] - xr; a[0] += xr; if (n > 4) { rftbsub(n, a, nc, w + nw); bitrv2(n, ip + 2, a); cftbsub(n, a, w); } else if (n == 4) { cftfsub(n, a, w); } } dctsub(n, a, nc, w + nw); if (isgn >= 0) { if (n > 4) { bitrv2(n, ip + 2, a); cftfsub(n, a, w); rftfsub(n, a, nc, w + nw); } else if (n == 4) { cftfsub(n, a, w); } xr = a[0] - a[1]; a[0] += a[1]; for (j = 2; j < n; j += 2) { a[j - 1] = a[j] - a[j + 1]; a[j] += a[j + 1]; } a[n - 1] = xr; } } /* -------- initializing routines -------- */ #include void makewt(int nw, int *ip, float *w) { void bitrv2(int n, int *ip, float *a); int j, nwh; float delta, x, y; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("makewt()"); #endif ip[0] = nw; ip[1] = 1; if (nw > 2) { nwh = nw >> 1; delta = atanf(1.0) / nwh; w[0] = 1; w[1] = 0; w[nwh] = cosf(delta * nwh); w[nwh + 1] = w[nwh]; if (nwh > 2) { for (j = 2; j < nwh; j += 2) { sincosf(delta*j,&y,&x); w[j] = x; w[j + 1] = y; w[nw - j] = y; w[nw - j + 1] = x; } for (j = nwh - 2; j >= 2; j -= 2) { x = w[2 * j]; y = w[2 * j + 1]; w[nwh + j] = x; w[nwh + j + 1] = y; } bitrv2(nw, ip + 2, w); } } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } void makect(int nc, int *ip, float *c) { int j, nch; float delta; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("makect()"); #endif ip[1] = nc; if (nc > 1) { nch = nc >> 1; delta = atanf(1.0f) / nch; c[0] = cosf(delta * nch); c[nch] = (0.5f * c[0]); for (j = 1; j < nch; j++) { sincosf(delta*j,c+nc-j,c+j); c[j]*=0.5f; c[nc-j]*=0.5f; } } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } /* -------- child routines -------- */ void bitrv2(int n, int *ip, float *a) { int j, j1, k, k1, l, m, m2; float xr, xi, yr, yi; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("bitrv2()"); #endif ip[0] = 0; l = n; m = 1; while ((m << 3) < l) { l >>= 1; for (j = 0; j < m; j++) { ip[m + j] = ip[j] + l; } m <<= 1; } m2 = 2 * m; if ((m << 3) == l) { for (k = 0; k < m; k++) { for (j = 0; j < k; j++) { j1 = 2 * j + ip[k]; k1 = 2 * k + ip[j]; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += m2; k1 += 2 * m2; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += m2; k1 -= m2; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += m2; k1 += 2 * m2; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; } j1 = 2 * k + m2 + ip[k]; k1 = j1 + m2; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; } } else { for (k = 1; k < m; k++) { for (j = 0; j < k; j++) { j1 = 2 * j + ip[k]; k1 = 2 * k + ip[j]; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += m2; k1 += m2; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; } } } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } void bitrv2conj(int n, int *ip, float *a) { int j, j1, k, k1, l, m, m2; float xr, xi, yr, yi; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("bitrv2conj()"); #endif ip[0] = 0; l = n; m = 1; while ((m << 3) < l) { l >>= 1; for (j = 0; j < m; j++) { ip[m + j] = ip[j] + l; } m <<= 1; } m2 = 2 * m; if ((m << 3) == l) { for (k = 0; k < m; k++) { for (j = 0; j < k; j++) { j1 = 2 * j + ip[k]; k1 = 2 * k + ip[j]; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += m2; k1 += 2 * m2; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += m2; k1 -= m2; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += m2; k1 += 2 * m2; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; } k1 = 2 * k + ip[k]; a[k1 + 1] = -a[k1 + 1]; j1 = k1 + m2; k1 = j1 + m2; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; k1 += m2; a[k1 + 1] = -a[k1 + 1]; } } else { a[1] = -a[1]; a[m2 + 1] = -a[m2 + 1]; for (k = 1; k < m; k++) { for (j = 0; j < k; j++) { j1 = 2 * j + ip[k]; k1 = 2 * k + ip[j]; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += m2; k1 += m2; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; } k1 = 2 * k + ip[k]; a[k1 + 1] = -a[k1 + 1]; a[k1 + m2 + 1] = -a[k1 + m2 + 1]; } } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } void cftfsub(int n, float *a, float *w) { void cft1st(int n, float *a, float *w); void cftmdl(int n, int l, float *a, float *w); int j, j1, j2, j3, l; float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("cftfsub()"); #endif l = 2; if (n >= 16) { cft1st(n, a, w); l = 16; while ((l << 3) <= n) { cftmdl(n, l, a, w); l <<= 3; } } if ((l << 1) < n) { for (j = 0; j < l; j += 2) { j1 = j + l; j2 = j1 + l; j3 = j2 + l; x0r = a[j] + a[j1]; x0i = a[j + 1] + a[j1 + 1]; x1r = a[j] - a[j1]; x1i = a[j + 1] - a[j1 + 1]; x2r = a[j2] + a[j3]; x2i = a[j2 + 1] + a[j3 + 1]; x3r = a[j2] - a[j3]; x3i = a[j2 + 1] - a[j3 + 1]; a[j] = x0r + x2r; a[j + 1] = x0i + x2i; a[j2] = x0r - x2r; a[j2 + 1] = x0i - x2i; a[j1] = x1r - x3i; a[j1 + 1] = x1i + x3r; a[j3] = x1r + x3i; a[j3 + 1] = x1i - x3r; } } else if ((l << 1) == n) { for (j = 0; j < l; j += 2) { j1 = j + l; x0r = a[j] - a[j1]; x0i = a[j + 1] - a[j1 + 1]; a[j] += a[j1]; a[j + 1] += a[j1 + 1]; a[j1] = x0r; a[j1 + 1] = x0i; } } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } void cftbsub(int n, float *a, float *w) { void cft1st(int n, float *a, float *w); void cftmdl(int n, int l, float *a, float *w); int j, j1, j2, j3, j4, j5, j6, j7, l; float wn4r, x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("cftbsub"); #endif l = 2; if (n > 16) { cft1st(n, a, w); l = 16; while ((l << 3) < n) { cftmdl(n, l, a, w); l <<= 3; } } if ((l << 2) < n) { wn4r = w[2]; for (j = 0; j < l; j += 2) { j1 = j + l; j2 = j1 + l; j3 = j2 + l; j4 = j3 + l; j5 = j4 + l; j6 = j5 + l; j7 = j6 + l; x0r = a[j] + a[j1]; x0i = -a[j + 1] - a[j1 + 1]; x1r = a[j] - a[j1]; x1i = -a[j + 1] + a[j1 + 1]; x2r = a[j2] + a[j3]; x2i = a[j2 + 1] + a[j3 + 1]; x3r = a[j2] - a[j3]; x3i = a[j2 + 1] - a[j3 + 1]; y0r = x0r + x2r; y0i = x0i - x2i; y2r = x0r - x2r; y2i = x0i + x2i; y1r = x1r - x3i; y1i = x1i - x3r; y3r = x1r + x3i; y3i = x1i + x3r; x0r = a[j4] + a[j5]; x0i = a[j4 + 1] + a[j5 + 1]; x1r = a[j4] - a[j5]; x1i = a[j4 + 1] - a[j5 + 1]; x2r = a[j6] + a[j7]; x2i = a[j6 + 1] + a[j7 + 1]; x3r = a[j6] - a[j7]; x3i = a[j6 + 1] - a[j7 + 1]; y4r = x0r + x2r; y4i = x0i + x2i; y6r = x0r - x2r; y6i = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; x2r = x1r + x3i; x2i = x1i - x3r; y5r = wn4r * (x0r - x0i); y5i = wn4r * (x0r + x0i); y7r = wn4r * (x2r - x2i); y7i = wn4r * (x2r + x2i); a[j1] = y1r + y5r; a[j1 + 1] = y1i - y5i; a[j5] = y1r - y5r; a[j5 + 1] = y1i + y5i; a[j3] = y3r - y7i; a[j3 + 1] = y3i - y7r; a[j7] = y3r + y7i; a[j7 + 1] = y3i + y7r; a[j] = y0r + y4r; a[j + 1] = y0i - y4i; a[j4] = y0r - y4r; a[j4 + 1] = y0i + y4i; a[j2] = y2r - y6i; a[j2 + 1] = y2i - y6r; a[j6] = y2r + y6i; a[j6 + 1] = y2i + y6r; } } else if ((l << 2) == n) { for (j = 0; j < l; j += 2) { j1 = j + l; j2 = j1 + l; j3 = j2 + l; x0r = a[j] + a[j1]; x0i = -a[j + 1] - a[j1 + 1]; x1r = a[j] - a[j1]; x1i = -a[j + 1] + a[j1 + 1]; x2r = a[j2] + a[j3]; x2i = a[j2 + 1] + a[j3 + 1]; x3r = a[j2] - a[j3]; x3i = a[j2 + 1] - a[j3 + 1]; a[j] = x0r + x2r; a[j + 1] = x0i - x2i; a[j2] = x0r - x2r; a[j2 + 1] = x0i + x2i; a[j1] = x1r - x3i; a[j1 + 1] = x1i - x3r; a[j3] = x1r + x3i; a[j3 + 1] = x1i + x3r; } } else { for (j = 0; j < l; j += 2) { j1 = j + l; x0r = a[j] - a[j1]; x0i = -a[j + 1] + a[j1 + 1]; a[j] += a[j1]; a[j + 1] = -a[j + 1] - a[j1 + 1]; a[j1] = x0r; a[j1 + 1] = x0i; } } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } void cft1st(int n, float *a, float *w) { int j, k1; float wn4r, wtmp, wk1r, wk1i, wk2r, wk2i, wk3r, wk3i, wk4r, wk4i, wk5r, wk5i, wk6r, wk6i, wk7r, wk7i; float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("cftlst()"); #endif wn4r = w[2]; x0r = a[0] + a[2]; x0i = a[1] + a[3]; x1r = a[0] - a[2]; x1i = a[1] - a[3]; x2r = a[4] + a[6]; x2i = a[5] + a[7]; x3r = a[4] - a[6]; x3i = a[5] - a[7]; y0r = x0r + x2r; y0i = x0i + x2i; y2r = x0r - x2r; y2i = x0i - x2i; y1r = x1r - x3i; y1i = x1i + x3r; y3r = x1r + x3i; y3i = x1i - x3r; x0r = a[8] + a[10]; x0i = a[9] + a[11]; x1r = a[8] - a[10]; x1i = a[9] - a[11]; x2r = a[12] + a[14]; x2i = a[13] + a[15]; x3r = a[12] - a[14]; x3i = a[13] - a[15]; y4r = x0r + x2r; y4i = x0i + x2i; y6r = x0r - x2r; y6i = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; x2r = x1r + x3i; x2i = x1i - x3r; y5r = wn4r * (x0r - x0i); y5i = wn4r * (x0r + x0i); y7r = wn4r * (x2r - x2i); y7i = wn4r * (x2r + x2i); a[2] = y1r + y5r; a[3] = y1i + y5i; a[10] = y1r - y5r; a[11] = y1i - y5i; a[6] = y3r - y7i; a[7] = y3i + y7r; a[14] = y3r + y7i; a[15] = y3i - y7r; a[0] = y0r + y4r; a[1] = y0i + y4i; a[8] = y0r - y4r; a[9] = y0i - y4i; a[4] = y2r - y6i; a[5] = y2i + y6r; a[12] = y2r + y6i; a[13] = y2i - y6r; if (n > 16) { wk1r = w[4]; wk1i = w[5]; x0r = a[16] + a[18]; x0i = a[17] + a[19]; x1r = a[16] - a[18]; x1i = a[17] - a[19]; x2r = a[20] + a[22]; x2i = a[21] + a[23]; x3r = a[20] - a[22]; x3i = a[21] - a[23]; y0r = x0r + x2r; y0i = x0i + x2i; y2r = x0r - x2r; y2i = x0i - x2i; y1r = x1r - x3i; y1i = x1i + x3r; y3r = x1r + x3i; y3i = x1i - x3r; x0r = a[24] + a[26]; x0i = a[25] + a[27]; x1r = a[24] - a[26]; x1i = a[25] - a[27]; x2r = a[28] + a[30]; x2i = a[29] + a[31]; x3r = a[28] - a[30]; x3i = a[29] - a[31]; y4r = x0r + x2r; y4i = x0i + x2i; y6r = x0r - x2r; y6i = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; x2r = x1r + x3i; x2i = x3r - x1i; y5r = wk1i * x0r - wk1r * x0i; y5i = wk1i * x0i + wk1r * x0r; y7r = wk1r * x2r + wk1i * x2i; y7i = wk1r * x2i - wk1i * x2r; x0r = wk1r * y1r - wk1i * y1i; x0i = wk1r * y1i + wk1i * y1r; a[18] = x0r + y5r; a[19] = x0i + y5i; a[26] = y5i - x0i; a[27] = x0r - y5r; x0r = wk1i * y3r - wk1r * y3i; x0i = wk1i * y3i + wk1r * y3r; a[22] = x0r - y7r; a[23] = x0i + y7i; a[30] = y7i - x0i; a[31] = x0r + y7r; a[16] = y0r + y4r; a[17] = y0i + y4i; a[24] = y4i - y0i; a[25] = y0r - y4r; x0r = y2r - y6i; x0i = y2i + y6r; a[20] = wn4r * (x0r - x0i); a[21] = wn4r * (x0i + x0r); x0r = y6r - y2i; x0i = y2r + y6i; a[28] = wn4r * (x0r - x0i); a[29] = wn4r * (x0i + x0r); k1 = 4; for (j = 32; j < n; j += 16) { k1 += 4; wk1r = w[k1]; wk1i = w[k1 + 1]; wk2r = w[k1 + 2]; wk2i = w[k1 + 3]; wtmp = 2 * wk2i; wk3r = wk1r - wtmp * wk1i; wk3i = wtmp * wk1r - wk1i; wk4r = 1 - wtmp * wk2i; wk4i = wtmp * wk2r; wtmp = 2 * wk4i; wk5r = wk3r - wtmp * wk1i; wk5i = wtmp * wk1r - wk3i; wk6r = wk2r - wtmp * wk2i; wk6i = wtmp * wk2r - wk2i; wk7r = wk1r - wtmp * wk3i; wk7i = wtmp * wk3r - wk1i; x0r = a[j] + a[j + 2]; x0i = a[j + 1] + a[j + 3]; x1r = a[j] - a[j + 2]; x1i = a[j + 1] - a[j + 3]; x2r = a[j + 4] + a[j + 6]; x2i = a[j + 5] + a[j + 7]; x3r = a[j + 4] - a[j + 6]; x3i = a[j + 5] - a[j + 7]; y0r = x0r + x2r; y0i = x0i + x2i; y2r = x0r - x2r; y2i = x0i - x2i; y1r = x1r - x3i; y1i = x1i + x3r; y3r = x1r + x3i; y3i = x1i - x3r; x0r = a[j + 8] + a[j + 10]; x0i = a[j + 9] + a[j + 11]; x1r = a[j + 8] - a[j + 10]; x1i = a[j + 9] - a[j + 11]; x2r = a[j + 12] + a[j + 14]; x2i = a[j + 13] + a[j + 15]; x3r = a[j + 12] - a[j + 14]; x3i = a[j + 13] - a[j + 15]; y4r = x0r + x2r; y4i = x0i + x2i; y6r = x0r - x2r; y6i = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; x2r = x1r + x3i; x2i = x1i - x3r; y5r = wn4r * (x0r - x0i); y5i = wn4r * (x0r + x0i); y7r = wn4r * (x2r - x2i); y7i = wn4r * (x2r + x2i); x0r = y1r + y5r; x0i = y1i + y5i; a[j + 2] = wk1r * x0r - wk1i * x0i; a[j + 3] = wk1r * x0i + wk1i * x0r; x0r = y1r - y5r; x0i = y1i - y5i; a[j + 10] = wk5r * x0r - wk5i * x0i; a[j + 11] = wk5r * x0i + wk5i * x0r; x0r = y3r - y7i; x0i = y3i + y7r; a[j + 6] = wk3r * x0r - wk3i * x0i; a[j + 7] = wk3r * x0i + wk3i * x0r; x0r = y3r + y7i; x0i = y3i - y7r; a[j + 14] = wk7r * x0r - wk7i * x0i; a[j + 15] = wk7r * x0i + wk7i * x0r; a[j] = y0r + y4r; a[j + 1] = y0i + y4i; x0r = y0r - y4r; x0i = y0i - y4i; a[j + 8] = wk4r * x0r - wk4i * x0i; a[j + 9] = wk4r * x0i + wk4i * x0r; x0r = y2r - y6i; x0i = y2i + y6r; a[j + 4] = wk2r * x0r - wk2i * x0i; a[j + 5] = wk2r * x0i + wk2i * x0r; x0r = y2r + y6i; x0i = y2i - y6r; a[j + 12] = wk6r * x0r - wk6i * x0i; a[j + 13] = wk6r * x0i + wk6i * x0r; } } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } void cftmdl(int n, int l, float *a, float *w) { int j, j1, j2, j3, j4, j5, j6, j7, k, k1, m; float wn4r, wtmp, wk1r, wk1i, wk2r, wk2i, wk3r, wk3i, wk4r, wk4i, wk5r, wk5i, wk6r, wk6i, wk7r, wk7i; float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("cftmdl()"); #endif m = l << 3; wn4r = w[2]; for (j = 0; j < l; j += 2) { j1 = j + l; j2 = j1 + l; j3 = j2 + l; j4 = j3 + l; j5 = j4 + l; j6 = j5 + l; j7 = j6 + l; x0r = a[j] + a[j1]; x0i = a[j + 1] + a[j1 + 1]; x1r = a[j] - a[j1]; x1i = a[j + 1] - a[j1 + 1]; x2r = a[j2] + a[j3]; x2i = a[j2 + 1] + a[j3 + 1]; x3r = a[j2] - a[j3]; x3i = a[j2 + 1] - a[j3 + 1]; y0r = x0r + x2r; y0i = x0i + x2i; y2r = x0r - x2r; y2i = x0i - x2i; y1r = x1r - x3i; y1i = x1i + x3r; y3r = x1r + x3i; y3i = x1i - x3r; x0r = a[j4] + a[j5]; x0i = a[j4 + 1] + a[j5 + 1]; x1r = a[j4] - a[j5]; x1i = a[j4 + 1] - a[j5 + 1]; x2r = a[j6] + a[j7]; x2i = a[j6 + 1] + a[j7 + 1]; x3r = a[j6] - a[j7]; x3i = a[j6 + 1] - a[j7 + 1]; y4r = x0r + x2r; y4i = x0i + x2i; y6r = x0r - x2r; y6i = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; x2r = x1r + x3i; x2i = x1i - x3r; y5r = wn4r * (x0r - x0i); y5i = wn4r * (x0r + x0i); y7r = wn4r * (x2r - x2i); y7i = wn4r * (x2r + x2i); a[j1] = y1r + y5r; a[j1 + 1] = y1i + y5i; a[j5] = y1r - y5r; a[j5 + 1] = y1i - y5i; a[j3] = y3r - y7i; a[j3 + 1] = y3i + y7r; a[j7] = y3r + y7i; a[j7 + 1] = y3i - y7r; a[j] = y0r + y4r; a[j + 1] = y0i + y4i; a[j4] = y0r - y4r; a[j4 + 1] = y0i - y4i; a[j2] = y2r - y6i; a[j2 + 1] = y2i + y6r; a[j6] = y2r + y6i; a[j6 + 1] = y2i - y6r; } if (m < n) { wk1r = w[4]; wk1i = w[5]; for (j = m; j < l + m; j += 2) { j1 = j + l; j2 = j1 + l; j3 = j2 + l; j4 = j3 + l; j5 = j4 + l; j6 = j5 + l; j7 = j6 + l; x0r = a[j] + a[j1]; x0i = a[j + 1] + a[j1 + 1]; x1r = a[j] - a[j1]; x1i = a[j + 1] - a[j1 + 1]; x2r = a[j2] + a[j3]; x2i = a[j2 + 1] + a[j3 + 1]; x3r = a[j2] - a[j3]; x3i = a[j2 + 1] - a[j3 + 1]; y0r = x0r + x2r; y0i = x0i + x2i; y2r = x0r - x2r; y2i = x0i - x2i; y1r = x1r - x3i; y1i = x1i + x3r; y3r = x1r + x3i; y3i = x1i - x3r; x0r = a[j4] + a[j5]; x0i = a[j4 + 1] + a[j5 + 1]; x1r = a[j4] - a[j5]; x1i = a[j4 + 1] - a[j5 + 1]; x2r = a[j6] + a[j7]; x2i = a[j6 + 1] + a[j7 + 1]; x3r = a[j6] - a[j7]; x3i = a[j6 + 1] - a[j7 + 1]; y4r = x0r + x2r; y4i = x0i + x2i; y6r = x0r - x2r; y6i = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; x2r = x1r + x3i; x2i = x3r - x1i; y5r = wk1i * x0r - wk1r * x0i; y5i = wk1i * x0i + wk1r * x0r; y7r = wk1r * x2r + wk1i * x2i; y7i = wk1r * x2i - wk1i * x2r; x0r = wk1r * y1r - wk1i * y1i; x0i = wk1r * y1i + wk1i * y1r; a[j1] = x0r + y5r; a[j1 + 1] = x0i + y5i; a[j5] = y5i - x0i; a[j5 + 1] = x0r - y5r; x0r = wk1i * y3r - wk1r * y3i; x0i = wk1i * y3i + wk1r * y3r; a[j3] = x0r - y7r; a[j3 + 1] = x0i + y7i; a[j7] = y7i - x0i; a[j7 + 1] = x0r + y7r; a[j] = y0r + y4r; a[j + 1] = y0i + y4i; a[j4] = y4i - y0i; a[j4 + 1] = y0r - y4r; x0r = y2r - y6i; x0i = y2i + y6r; a[j2] = wn4r * (x0r - x0i); a[j2 + 1] = wn4r * (x0i + x0r); x0r = y6r - y2i; x0i = y2r + y6i; a[j6] = wn4r * (x0r - x0i); a[j6 + 1] = wn4r * (x0i + x0r); } k1 = 4; for (k = 2 * m; k < n; k += m) { k1 += 4; wk1r = w[k1]; wk1i = w[k1 + 1]; wk2r = w[k1 + 2]; wk2i = w[k1 + 3]; wtmp = 2 * wk2i; wk3r = wk1r - wtmp * wk1i; wk3i = wtmp * wk1r - wk1i; wk4r = 1 - wtmp * wk2i; wk4i = wtmp * wk2r; wtmp = 2 * wk4i; wk5r = wk3r - wtmp * wk1i; wk5i = wtmp * wk1r - wk3i; wk6r = wk2r - wtmp * wk2i; wk6i = wtmp * wk2r - wk2i; wk7r = wk1r - wtmp * wk3i; wk7i = wtmp * wk3r - wk1i; for (j = k; j < l + k; j += 2) { j1 = j + l; j2 = j1 + l; j3 = j2 + l; j4 = j3 + l; j5 = j4 + l; j6 = j5 + l; j7 = j6 + l; x0r = a[j] + a[j1]; x0i = a[j + 1] + a[j1 + 1]; x1r = a[j] - a[j1]; x1i = a[j + 1] - a[j1 + 1]; x2r = a[j2] + a[j3]; x2i = a[j2 + 1] + a[j3 + 1]; x3r = a[j2] - a[j3]; x3i = a[j2 + 1] - a[j3 + 1]; y0r = x0r + x2r; y0i = x0i + x2i; y2r = x0r - x2r; y2i = x0i - x2i; y1r = x1r - x3i; y1i = x1i + x3r; y3r = x1r + x3i; y3i = x1i - x3r; x0r = a[j4] + a[j5]; x0i = a[j4 + 1] + a[j5 + 1]; x1r = a[j4] - a[j5]; x1i = a[j4 + 1] - a[j5 + 1]; x2r = a[j6] + a[j7]; x2i = a[j6 + 1] + a[j7 + 1]; x3r = a[j6] - a[j7]; x3i = a[j6 + 1] - a[j7 + 1]; y4r = x0r + x2r; y4i = x0i + x2i; y6r = x0r - x2r; y6i = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; x2r = x1r + x3i; x2i = x1i - x3r; y5r = wn4r * (x0r - x0i); y5i = wn4r * (x0r + x0i); y7r = wn4r * (x2r - x2i); y7i = wn4r * (x2r + x2i); x0r = y1r + y5r; x0i = y1i + y5i; a[j1] = wk1r * x0r - wk1i * x0i; a[j1 + 1] = wk1r * x0i + wk1i * x0r; x0r = y1r - y5r; x0i = y1i - y5i; a[j5] = wk5r * x0r - wk5i * x0i; a[j5 + 1] = wk5r * x0i + wk5i * x0r; x0r = y3r - y7i; x0i = y3i + y7r; a[j3] = wk3r * x0r - wk3i * x0i; a[j3 + 1] = wk3r * x0i + wk3i * x0r; x0r = y3r + y7i; x0i = y3i - y7r; a[j7] = wk7r * x0r - wk7i * x0i; a[j7 + 1] = wk7r * x0i + wk7i * x0r; a[j] = y0r + y4r; a[j + 1] = y0i + y4i; x0r = y0r - y4r; x0i = y0i - y4i; a[j4] = wk4r * x0r - wk4i * x0i; a[j4 + 1] = wk4r * x0i + wk4i * x0r; x0r = y2r - y6i; x0i = y2i + y6r; a[j2] = wk2r * x0r - wk2i * x0i; a[j2 + 1] = wk2r * x0i + wk2i * x0r; x0r = y2r + y6i; x0i = y2i - y6r; a[j6] = wk6r * x0r - wk6i * x0i; a[j6 + 1] = wk6r * x0i + wk6i * x0r; } } } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } void rftfsub(int n, float *a, int nc, float *c) { int j, k, kk, ks, m; float wkr, wki, xr, xi, yr, yi; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("rftfsub()"); #endif m = n >> 1; ks = 2 * nc / m; kk = 0; for (j = 2; j < m; j += 2) { k = n - j; kk += ks; wkr = static_cast(0.5 - c[nc - kk]); wki = c[kk]; xr = a[j] - a[k]; xi = a[j + 1] + a[k + 1]; yr = wkr * xr - wki * xi; yi = wkr * xi + wki * xr; a[j] -= yr; a[j + 1] -= yi; a[k] += yr; a[k + 1] -= yi; } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } void rftbsub(int n, float *a, int nc, float *c) { int j, k, kk, ks, m; float wkr, wki, xr, xi, yr, yi; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("rftbsub()"); #endif a[1] = -a[1]; m = n >> 1; ks = 2 * nc / m; kk = 0; for (j = 2; j < m; j += 2) { k = n - j; kk += ks; wkr = 0.5f - c[nc - kk]; wki = c[kk]; xr = a[j] - a[k]; xi = a[j + 1] + a[k + 1]; yr = wkr * xr + wki * xi; yi = wkr * xi - wki * xr; a[j] -= yr; a[j + 1] = yi - a[j + 1]; a[k] += yr; a[k + 1] = yi - a[k + 1]; } a[m + 1] = -a[m + 1]; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } void dctsub(int n, float *a, int nc, float *c) { int j, k, kk, ks, m; float wkr, wki, xr; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("dctsub()"); #endif m = n >> 1; ks = nc / n; kk = 0; for (j = 1; j < m; j++) { k = n - j; kk += ks; wkr = c[kk] - c[nc - kk]; wki = c[kk] + c[nc - kk]; xr = wki * a[j] - wkr * a[k]; a[j] = wkr * a[j] + wki * a[k]; a[k] = xr; } a[m] *= c[0]; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } void dstsub(int n, float *a, int nc, float *c) { int j, k, kk, ks, m; float wkr, wki, xr; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("dstsub()"); #endif m = n >> 1; ks = nc / n; kk = 0; for (j = 1; j < m; j++) { k = n - j; kk += ks; wkr = c[kk] - c[nc - kk]; wki = c[kk] + c[nc - kk]; xr = wki * a[k] - wkr * a[j]; a[k] = wkr * a[k] + wki * a[j]; a[j] = xr; } a[m] *= c[0]; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } void fft8g_end() {} boinc-app-seti_8.00~svn3701.orig/client/chirpfft.cpp0000644000175000017500000003103012323147321022274 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "sah_config.h" #include #include #include #include #include "diagnostics.h" #include "util.h" #include "s_util.h" #ifdef BOINC_APP_GRAPHICS #include "sah_gfx_main.h" #endif #include "seti_header.h" #include "seti.h" #include "util.h" #include "filesys.h" #include "s_util.h" #include "analyze.h" #include "worker.h" #include "lcgamm.h" #include "chirpfft.h" #ifdef __arm__ #include "vector/fp_arm.h" #endif sh_sint8_t num_gaussian_searches; sh_sint8_t num_pulse_searches; sh_sint8_t num_triplet_searches; char * cfft_file = NULL; size_t GenChirpFftPairs( ChirpFftPair_t ** ChirpFftPairs, double * MinChirpStep ) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("GenChirpFftPairs()"); #endif long i, j, max_fft_len; double CRate; double ChirpRes = swi.analysis_cfg.chirp_resolution; double NumSamples = swi.nsamples; double WUDuration = (double)(swi.nsamples/swi.subband_sample_rate); double SlewRate=static_cast(swi.angle_range)/WUDuration; long MaxGaussFFTLen=swi.nsamples/swi.analysis_cfg.gauss_pot_length; double BeamsPerWU = std::max(swi.true_angle_range/swi.beam_width,1.0); long MinPulseFFTLen=(long)ceil(swi.nsamples/(swi.analysis_cfg.pulse_max*BeamsPerWU*swi.analysis_cfg.pulse_beams)); 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; std::map ChirpFftMap; // An arrays associated with the FFT length array. ChirpSteps = (double *)calloc(swi.num_fft_lengths, sizeof(double)); // Each FFT length has a (different) associated chirp step. CalcChirpSteps(ChirpSteps, MinChirpStep); // Lets simplify the logic for doing chirps by using the STL map // container for sorting. max_fft_len=swi.analysis_fft_lengths[swi.num_fft_lengths-1]; for (i=0; i= swi.analysis_cfg.pot_min_slew) && (SlewRate <= swi.analysis_cfg.pot_max_slew)); tmp.PulseFind=0; while (CRate <= swi.analysis_cfg.chirps[i].chirp_limit) { // Pulse find on alternate chirp rates when fitting Gaussians if ((SlewRate >= swi.analysis_cfg.pot_min_slew) && (SlewRate <= swi.analysis_cfg.pot_max_slew)) { tmp.PulseFind=!(tmp.PulseFind) && tmp.GaussFit && (tmp.FftLen<=MaxPulseFFTLen) && (tmp.FftLen>=MinPulseFFTLen); // else pulse find when our FFT liength is in range... } else { tmp.PulseFind=(tmp.FftLen<=MaxPulseFFTLen) && (tmp.FftLen>=MinPulseFFTLen); } // Force all chirp rates to be a multiple of the minimum step. tmp.ChirpRate= (tmp.ChirpRateInd=(int32_t)floor(CRate/(*MinChirpStep)+0.5)) *(*MinChirpStep); // Generate keys specifying the order of the chirps // chirp_rate,sign,fft_length order... sh_sint8_t key=static_cast(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; //fprintf(stderr,"%f %d %f\n",CRate,tmp.ChirpRateInd,tmp.ChirpRate); //fflush(stderr); // Now the negative chirps for non-zero chirp; if (CRate != 0.0) { tmp.ChirpRate*=-1; tmp.ChirpRateInd*=-1; key+=max_fft_len*2; // flip the bit representing the sign in the // key ChirpFftMap[key]=tmp; } CRate+=ChirpSteps[j]; } // end while loop through chirp rates } // end if } // end for loop through fft lenngths } // end for loop through cfft parameter table // Copy our ordereds CFFT map into a more standard array *ChirpFftPairs = (ChirpFftPair_t *)calloc(ChirpFftMap.size(),sizeof(ChirpFftPair_t)); std::map::const_iterator p; i=0; for (p=ChirpFftMap.begin();p!=ChirpFftMap.end();p++) { num_gaussian_searches+=(p->second.GaussFit*(p->second.FftLen-1)); num_pulse_searches+=(sh_sint8_t)(p->second.PulseFind*(p->second.FftLen-1)*(NumSamples/p->second.FftLen)*log((double)NumSamples/p->second.FftLen)/log(2.0)); num_triplet_searches+=(sh_sint8_t)(p->second.PulseFind*(p->second.FftLen-1)*(NumSamples/p->second.FftLen)*(NumSamples/p->second.FftLen)); (*ChirpFftPairs)[i++]=p->second; } /* fprintf( stderr,"NumCfft=%d\n NumGauss="SINT8_FMT"\n NumPulse="SINT8_FMT"\n NumTriplet="SINT8_FMT"\n", static_cast(ChirpFftMap.size()), SINT8_FMT_CAST(num_gaussian_searches), SINT8_FMT_CAST(num_pulse_searches), SINT8_FMT_CAST(num_triplet_searches) ); */ fflush(stderr); if (ChirpSteps) free (ChirpSteps); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return(ChirpFftMap.size()); } void CalcChirpSteps(double* ChirpSteps, double* MinChirpStep) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("CalcChirpSteps()"); #endif double ChirpRes = swi.analysis_cfg.chirp_resolution; double NumSamples = swi.nsamples; double WUDuration = (double)(swi.nsamples/swi.subband_sample_rate); int i; double SecondsInAnalysis; double SlewRate=static_cast(swi.angle_range)/WUDuration; long FftLen; long MaxGaussFFTLen=swi.nsamples/swi.analysis_cfg.gauss_pot_length; double BeamsPerWU = std::max(swi.true_angle_range/swi.beam_width,1.0); long MinPulseFFTLen=(long)ceil(swi.nsamples/(swi.analysis_cfg.pulse_max*BeamsPerWU*swi.analysis_cfg.pulse_beams)); 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); long MaxTripletFFTLen=swi.nsamples/swi.analysis_cfg.triplet_min; double SecondsInBeam = WUDuration/swi.true_angle_range*swi.beam_width; // For each FFT length, calculate the corresponding chirp // step (in Hz/s), given the chirp resolution (in FFT bins). // Keep track of the minimum chirp step. // The goal here is to have the drift be less than 1 bin over the // duration of interest to the analysis. In the case of gaussians // that duration is 2 beam crossings. In the case of pulses it's // one beam crossing. In the case of spikes it's one fft length. *MinChirpStep = 0.0; for(i = 0; i < swi.num_fft_lengths; i++) { FftLen = swi.analysis_fft_lengths[i]; double SecondsInFFT = WUDuration / (NumSamples / FftLen); // Are we going to do Gaussians? if ((FftLen <= MaxGaussFFTLen) && (SlewRate >= swi.analysis_cfg.pot_min_slew) && (SlewRate <= swi.analysis_cfg.pot_max_slew)) { SecondsInAnalysis = SecondsInBeam*2; // In not, are we going to do pulses or triplets? } else if ((FftLen<=MaxPulseFFTLen) && (FftLen<= MaxTripletFFTLen)) { // Look for pulses over one beam crossing or one beam crossing // at the pot_min_slew, whichever is lower. SecondsInAnalysis = std::min(SecondsInBeam,swi.beam_width/swi.analysis_cfg.pot_min_slew); } else { SecondsInAnalysis = SecondsInFFT; } ChirpSteps[i] = ChirpRes / (SecondsInAnalysis * SecondsInFFT); //fprintf(stderr,"%d %f\n",i,ChirpSteps[i]); //fflush(stderr); if(ChirpSteps[i] < *MinChirpStep || *MinChirpStep == 0.0) { *MinChirpStep = ChirpSteps[i]; } } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } bool VeryClose(double a, double b, double CloseEnough) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("VeryClose()"); #endif double Diff; Diff = fabs(a - b); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif if(Diff > CloseEnough) return(false); else return(true); } int ReadCFftFile(ChirpFftPair_t ** ChirpFftPairs, double * MinChirpStep) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("ReadCFftFile()"); #endif // ChirpFftSet_t ChirpFftSet; ChirpFftPair_t * ChirpFftPair; int NumChirpFftPairs; FILE * cfftfp; double ChirpRate; int FftLen; NumChirpFftPairs = 0; cfftfp = boinc_fopen(cfft_file, "r"); ChirpFftPair = (ChirpFftPair_t*) calloc(1,sizeof(ChirpFftPair_t)); while(fscanf(cfftfp, "%lf %d", &ChirpRate, &FftLen) == 2) { ChirpFftPair = (ChirpFftPair_t *)realloc( (void *)ChirpFftPair, sizeof(ChirpFftPair_t)*(NumChirpFftPairs+1)); if (ChirpFftPair == NULL) SETIERROR(MALLOC_FAILED, "ChirpFftPair == NULL"); ChirpFftPair[NumChirpFftPairs].ChirpRate = ChirpRate; ChirpFftPair[NumChirpFftPairs].FftLen = FftLen; NumChirpFftPairs++; } *ChirpFftPairs = ChirpFftPair; *MinChirpStep = (float) TEST_MIN_CHIRP_STEP; fclose(cfftfp); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return(NumChirpFftPairs); } boinc-app-seti_8.00~svn3701.orig/client/analyze.h0000644000175000017500000000572111516176217021620 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // This file contains compile time configuration parameters // for the seti@home reference algorithm implementation. #ifndef _ANALYZE_ #define _ANALYZE_ #define ISODD(a) (a)%2 != 0 ? true : false #define IROUND(a) ( (int) ((a) + 0.5f) ) #define LROUND(a) ( (long) ((a) + 0.5f) ) #define SQUARE(a) ((a) * (a)) typedef unsigned char BOOLEAN; #define SPIKE_SCORE_HIGH 40 // a high number (extremely unlikely in noise) #define AUTOCORR_SCORE_HIGH 40 // a high number (extremely unlikely in noise) #define USE_PULSE #define USE_TRIPLET extern int t_offset_start; extern int t_offset_stop; extern float SlewRate; extern float gauss_sigma; extern float gauss_sigma_sq; #define NEG_LN_ONE_HALF 0.693 #define EXP(a,b,c) exp(-(NEG_LN_ONE_HALF * SQUARE((float)(a) - (float)(b))) / (float)(c)) #endif // ========================================================================== // General Notes // Concerning the gaussian function macro EXP: // The EXP macro defined here is used to generate the gaussian function // f(x) = exp(-(C * x^2 / sigma^2)) in both fakedata and gaussfit. Sigma // is in arbitrary units and simply gives the width of the gaussian. We // give it a particular meaning by properly setting the value of the // constant C. The meaning we give sigma here is that 2sigma is the // half power beamwidth of the telescope. We solve for C when x = sigma // and f(x) = 1/2. Thus we have f(x) = exp(-C). Taking the natural log // of both sides gives us ln(1/2) = -C. And so C = -ln(1/2) = 0.693. boinc-app-seti_8.00~svn3701.orig/client/seti_header.cpp0000644000175000017500000002440612637045610022762 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. /* * * $Id: seti_header.cpp,v 1.22.2.6 2007/05/31 22:03:11 korpela Exp $ * */ #include "sah_config.h" #include #include #include #include #include #include #include #include #include "diagnostics.h" #include "util.h" #include "s_util.h" #ifdef HAVE_IEEEFP_H #include #endif #include "seti.h" #include "analyze.h" #include "timecvt.h" #include "parse.h" #include "../db/db_table.h" #include "../db/schema_master.h" #include "seti_header.h" #include "analyzePoT.h" #include "analyzeReport.h" #include "chirpfft.h" #ifdef __arm__ #include "vector/fp_arm.h" #endif // Write a SETI work unit header to a file char *receivers[]={"invalid","synthetic","ao1420"}; char *datatypes[]={"invalid","ascii","encoded","sun_binary"}; SETI_WU_INFO::SETI_WU_INFO(const workunit &w) : track_mem("SETI_WU_INFO"), data_class(0), start_ra(w.group_info->data_desc.start_ra), start_dec(w.group_info->data_desc.start_dec), end_ra(w.group_info->data_desc.end_ra), end_dec(w.group_info->data_desc.end_dec), true_angle_range(w.group_info->data_desc.true_angle_range), time_recorded(w.group_info->data_desc.time_recorded_jd), subband_center(w.subband_desc.center), subband_base(w.subband_desc.base), subband_sample_rate(w.subband_desc.sample_rate), fft_len(w.group_info->splitter_cfg->fft_len), ifft_len(w.group_info->splitter_cfg->ifft_len), subband_number(w.subband_desc.number), receiver_cfg(w.group_info->receiver_cfg), nsamples(w.group_info->data_desc.nsamples), bits_per_sample(w.group_info->splitter_cfg->wu_bits_per_sample), position_history(w.group_info->data_desc.coords.begin()), num_positions(w.group_info->data_desc.coords.size()), analysis_cfg(w.group_info->analysis_cfg), beam_width(w.group_info->receiver_cfg->beam_width), wu(&w) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("SETI_WU_INFO::SETI_WU_INFO(const workunit &w)"); #endif /* USE_MANUAL_CALLSTACK */ // Adjust beam width for frequency beam_width*=(w.group_info->receiver_cfg->center_freq*1e+6/subband_center); if (bits_per_sample == 0) bits_per_sample=2; if (!strcmp(w.group_info->splitter_cfg->data_type,"ascii")) data_type = DATA_ASCII; else if (!strcmp(w.group_info->splitter_cfg->data_type,"encoded")) data_type = DATA_ENCODED; else if (!strcmp(w.group_info->splitter_cfg->data_type,"sun_binary")) data_type = DATA_SUN_BINARY; splitter_version=(int)floor(w.group_info->splitter_cfg->version)*0x100; splitter_version+=(int)((w.group_info->splitter_cfg->version)*0x100) & 0xff; angle_range=true_angle_range; sprintf(tape_version,"%8.2f",w.group_info->recorder_cfg->version); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif /* USE_MANUAL_CALLSTACK */ } SETI_WU_INFO::SETI_WU_INFO() : track_mem("SETI_WU_INFO"), data_class(0), start_ra(0), start_dec(0), end_ra(0), end_dec(0), true_angle_range(0), time_recorded(0), subband_center(0), subband_base(0), subband_sample_rate(0), fft_len(0), ifft_len(0), subband_number(0), nsamples(0), bits_per_sample(2), position_history(), num_positions(0), beam_width(0) { data_type = DATA_ASCII; splitter_version=0; angle_range=0; tape_version[0]=0; } SETI_WU_INFO::SETI_WU_INFO(const SETI_WU_INFO &s) : track_mem("SETI_WU_INFO"), data_type(s.data_type), data_class(s.data_class), splitter_version(s.splitter_version), start_ra(s.start_ra), start_dec(s.start_dec), end_ra(s.end_ra), end_dec(s.end_dec), angle_range(s.true_angle_range), true_angle_range(s.true_angle_range), time_recorded(s.time_recorded), subband_center(s.subband_center), subband_base(s.subband_base), subband_sample_rate(s.subband_sample_rate), fft_len(s.fft_len), ifft_len(s.ifft_len), subband_number(s.subband_number), receiver_cfg(s.receiver_cfg), nsamples(s.nsamples), bits_per_sample(s.bits_per_sample), position_history(s.position_history), num_positions(s.num_positions), analysis_cfg(s.analysis_cfg), beam_width(s.beam_width), wu(s.wu) { strcpy(tape_version,s.tape_version); } int seti_write_wu_header(FILE *file, int output_xml) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("seti_write_wu_header()"); #endif /* USE_MANUAL_CALLSTACK */ fprintf(file,"%s",swi.wu->print_xml().c_str()); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif /* USE_MANUAL_CALLSTACK */ return 0; } int seti_write_wu_header(FILE *file, int output_xml, SETI_WU_INFO &swi) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("seti_write_wu_header()"); #endif /* USE_MANUAL_CALLSTACK */ fprintf(file,"%s",swi.wu->print_xml().c_str()); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif /* USE_MANUAL_CALLSTACK */ return 0; } SETI_WU_INFO swi; static workunit *wu; int seti_parse_wu_header(FILE* f) { char buf[256]; int found=0; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("seti_parse_wu_header(FILE *)"); #endif /* USE_MANUAL_CALLSTACK */ std::string buffer(""); buffer.reserve(10*1024); swi.data_type=0; // Allow old style headers to be parsed correctly. // jeffc - need this? //swi.fft_len=2048; //swi.ifft_len=8; do { fgets(buf, 256, f); } while (!feof(f) && !xml_match_tag(buf,"= 0) { return (int)(nbins*freq/sample_rate); } else { return (int)(nbins/2-(freq/sample_rate)); } } float cnvt_fftind_time(int fft_ind, int fft_len) { return (float)(fft_ind*(fft_len/swi.subband_sample_rate)); } float cnvt_gauss_offset_time(int offset) { float dur = (float)(swi.nsamples/swi.subband_sample_rate); return (float)(offset*dur/swi.analysis_cfg.gauss_pot_length); } // need to properly handle frequency rollover when calculating detection // frequency double calc_detection_freq(double freq, double chirp_rate, double t_offset) { double fft_ratio=1.0/swi.wu->group_info->splitter_cfg->ifft_len; double lowerlim=swi.subband_base-0.5*swi.subband_sample_rate*fft_ratio; double upperlim=lowerlim+swi.subband_sample_rate; double detection_freq=freq+chirp_rate*t_offset; while (detection_freq < lowerlim) detection_freq+=swi.subband_sample_rate; while (detection_freq > upperlim) detection_freq-=swi.subband_sample_rate; return detection_freq; } boinc-app-seti_8.00~svn3701.orig/client/analyzePoT.h0000644000175000017500000000601512323147321022227 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // $Id: analyzePoT.h,v 1.5.2.2 2005/07/04 22:50:09 korpela Exp $ #include "chirpfft.h" #define POT_INACTIVE 0 #define POT_DOING_GAUSS 1 #define POT_DOING_PULSE 2 extern double beam_width; typedef struct { double WUDuration; // in seconds double SlewRate; // degrees/second double BeamRate; // beams/second int MaxPoTLen; double GaussSigma; // in gaussian PoT bins double GaussSigmaSq; // in gaussian PoT bins int GaussTOffsetStart; // in gaussian PoT bins int GaussTOffsetStop; // in gaussian PoT bins double min_slew; double max_slew; double GaussChiSqThresh; // gaussian reporting thresh double GaussPowerThresh; // PoT investigation thresh - in units // of mean power across entire PoT double GaussPeakPowerThresh; // gaussian investigation thresh - in // units of mean power across PoT, // exclusive of 2 sigma area on either // side of gaussian peak double PulseOverlapFactor; // for both pulse and triplets double PulseBeams; // for both pulse and triplets double PulseThresh; int PulseMax; int PulseMin; int PulseFftMax; double TripletThresh; int TripletMax; int TripletMin; int SpikeMin; } PoTInfo_t; extern PoTInfo_t PoTInfo; int analyze_pot( float * fp_PowerSpectrum, int ul_NumDataPoints, ChirpFftPair_t &cfft ); int GetFixedPoT( float fp_PowerSpectrum[], int ul_NumDataPoints, int ul_FftLength, float fp_PoT[], int ul_PoTLen, int ul_PoT ); void ComputePoTInfo(int num_cfft, int NumDataPoints); void GetPulsePoTLen(long FullPoTLen, int * PulsePoTLen, int * PulseOverlap); boinc-app-seti_8.00~svn3701.orig/client/win-sah_config.h0000644000175000017500000003463413073254736023060 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. /* config.h. Generated by configure. */ #ifndef _SAH_WIN_CONFIG_H_ #define _SAH_WIN_CONFIG_H_ #if _MSC_VER ==1900 struct IUnknown;//R: to make clang toolchain in VS2015 happy (though it too green to be usable anyway; doesn't implement needed intrinsics) #endif #ifdef __MINGW32__ #include #endif #include "boinc_win.h" #ifndef AP_CLIENT #ifdef __MINGW32__ #include "seti_boinc_private.h" #elif defined(_MSC_VER) #include "win_build/seti_boinc_private.h" #endif #endif #ifdef _MSC_VER #define HAVE_INTRIN_H 1 #else #define HAVE_IMMINTRIN_H 1 #define HAVE_PMMINTRIN_H 1 #endif #ifndef AP_CLIENT #define HAVE_XMMINTRIN_H 1 #define HAVE_EMMINTRIN_H 1 #define USE_INTRINSICS 1 #define USE_SSE 1 #define USE_SSE2 1 #define USE_SSE3 1 #define USE_AVX 1 #endif /* Define to 1 if you have the _aligned_malloc() function */ #ifdef _MSC_VER #if _MSC_VER == 1500 //R: VS2008 unable to build AVX #undef USE_AVX #endif #define HAVE__ALIGNED_MALLOC 1 #define HAVE__ALIGNED_FREE 1 #endif /* Define to the typecast required for arg 2 of _mm256_maskstore_ps() */ // TODO: Simply this mess. Should only need 1 #if and an #else #if defined(_MSC_VER) #define AVX_MASKSTORE_TYPECAST(x) (*reinterpret_cast<__m256i *>(&x)) #elif (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5) \ || ((__GNUC__ == 4) && (__GNUC_MINOR__ == 5) && (__GNUC_PATCHLEVEL__ > 2)) \ || ((__GNUC__ == 4) && (__GNUC_MINOR__ == 4) && (__GNUC_PATCHLEVEL__ > 5))) #define AVX_MASKSTORE_TYPECAST(x) *reinterpret_cast<__m256i *>(&x) #elif defined(__GNUC__) #define AVX_MASKSTORE_TYPECAST(x) static_cast<__m256>(x) #else #define AVX_MASKSTORE_TYPECAST(x) static_cast<__m256i>(x) #endif // Deactivate AVX when it's definitely not supported. #if defined(__GNUC__) && ( \ (__GNUC__ < 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ < 4))) #undef USE_AVX #undef HAVE_IMMINTRIN_H #endif #if defined(__GNUC__) #define HAVE_DECL___BUILTIN_ALLOCA 1 #define HAVE_DECL___BUILTIN_CLZ 1 #define HAVE_DECL___BUILTIN_FFS 1 #define HAVE_DECL___BUILTIN_POPCOUNT 1 #define HAVE_DECL___BUILTIN_PREFETCH 1 #define HAVE___BUILTIN_ALLOCA 1 #define HAVE___BUILTIN_CLZ 1 #define HAVE___BUILTIN_FFS 1 #define HAVE___BUILTIN_POPCOUNT 1 #define HAVE___BUILTIN_PREFETCH 1 #endif /* Define to 1 if you have the alloca() function */ #define HAVE_ALLOCA 1 /* Define to 1 if you have the atanf() function */ #define HAVE_ATANF 1 /* Define to 1 if you have the `atexit' function. */ #define HAVE_ATEXIT 1 /* Define to 1 if you have the `atoll' function. */ #ifdef __MINGW32__ #define HAVE_ATOLL 1 #endif /* Define to 1 if the system has the type `bool'. */ #define HAVE_BOOL 1 /* Define to 1 if you have the cosf() function */ #define HAVE_COSF 1 /* Define to 1 if you have the header file. */ /* #define HAVE_DIRENT_H 1 */ /* Define to 1 if you have the header file. */ #define HAVE_FCNTL_H 1 /* Define to 1 if you have the `floor' function. */ #define HAVE_FLOOR 1 /* Define to 1 if you have the `fork' function. */ //#define HAVE_FORK 1 /* Define to 1 if you have the `getcwd' function. */ // #define HAVE_GETCWD 1 /* Define to 1 if you have the header file. */ //#define HAVE_GLUT_GLUT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_GL_FREEGLUT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_GLUT_H 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_GLU_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_GL_GLUT_H */ /* Define to 1 if you have the header file. */ #define HAVE_GL_GLU_H 1 /* Define to 1 if you have the header file. */ #define HAVE_GL_GL_H 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_GL_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_INTTYPES_H */ #ifdef __MINGW32__ #define HAVE_INT32_T 1 #define HAVE_INT64_T 1 #endif #define HAVE__ISNAN 1 /* Define to 1 if you have the `aio' library (-laio). */ //#define HAVE_LIBAIO 1 /* Define to 1 if you have the `dl' library (-ldl). */ //#define HAVE_LIBDL 1 /* Define to 1 if you have the `elf' library (-lelf). */ //#define HAVE_LIBELF 1 /* Define to 1 if you have the `fftw' library (-lfftw). */ #define HAVE_LIBFFTW 1 /* Define to 1 if you have the `GL' library (-lGL). */ #define HAVE_LIBGL 1 /* Define to 1 if you have the `ICE' library (-lICE). */ //#define HAVE_LIBICE 1 /* Define to 1 if you have the `m' library (-lm). */ #define HAVE_LIBM 1 /* Define to 1 if you have the `nsl' library (-lnsl). */ //#define HAVE_LIBNSL 1 /* Define to 1 if you have the `rsaeuro' library (-lrsaeuro). */ /* #undef HAVE_LIBRSAEURO */ /* Define to 1 if you have the `s4' library (-ls4). */ /* #undef HAVE_LIBS4 */ /* Define to 1 if you have the `SM' library (-lSM). */ //#define HAVE_LIBSM 1 /* Define to 1 if you have the `socket' library (-lsocket). */ //#define HAVE_LIBSOCKET 1 /* Define to 1 if you have the `stdc++' library (-lstdc++). */ //#define HAVE_LIBSTDC__ 1 /* Define to 1 if you have the `X11' library (-lX11). */ //#define HAVE_LIBX11 1 /* Define to 1 if you have the `Xaw' library (-lXaw). */ //#define HAVE_LIBXAW 1 /* Define to 1 if you have the `Xext' library (-lXext). */ //#define HAVE_LIBXEXT 1 /* Define to 1 if you have the `Xmu' library (-lXmu). */ //#define HAVE_LIBXMU 1 /* Define to 1 if you have the `Xt' library (-lXt). */ /* #define HAVE_LIBXT 1 */ /* Define to 1 if you have the `z' library (-lz). */ /* #define HAVE_LIBZ 1 */ /* Define to 1 if you have the header file. */ #define HAVE_LIMITS_H 1 /* Define to 1 if long double works and has more range or precision than double. */ #define HAVE_LONG_DOUBLE 1 /* Define to 1 if the system has the type `long long'. */ #ifdef __MINGW32__ #define HAVE_LONG_LONG 1 #endif /* Define to 1 if your system has a GNU libc compatible `malloc' function, and to 0 otherwise. */ #define HAVE_MALLOC 1 /* Define to 1 if you have the header file. */ #define HAVE_MALLOC_H 1 /* Define to 1 if you have the header file. */ #define HAVE_MEMORY_H 1 /* Define to 1 if you have the `memset' function. */ #define HAVE_MEMSET 1 /* Define to 1 if you have the `munmap' function. */ /* #define HAVE_MUNMAP 1 */ /* Define if your C++ compiler supports namespaces */ #define HAVE_NAMESPACES 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_OPENGL_GLUT_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_OPENGL_GLU_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_OPENGL_GL_H */ /* Define to 1 if you have the `putenv' function. */ #define HAVE_PUTENV 1 /* Define to 1 if your system has a GNU libc compatible `realloc' function, and to 0 otherwise. */ #define HAVE_REALLOC 1 /* Define to 1 if you have the sinf() function */ #define HAVE_SINF 1 /* Define to 1 if you have the sincosf() function */ /* #undef HAVE_SINCOSF */ /* Define to 1 if you have the `sqrt' function. */ #define HAVE_SQRT 1 /* Define to 1 if `stat' has the bug that it succeeds when given the zero-length file name argument. */ /* #undef HAVE_STAT_EMPTY_STRING_BUG */ #if ( _MSC_VER > 1300 ) || defined(__MINGW32__) /* Define to 1 if the max template is in namespace std. */ #define HAVE_STD_MAX 1 /* Define to 1 if the min template is in namespace std. */ #define HAVE_STD_MIN 1 #endif /* Define to 1 if the transform template is in namespace std. */ #define HAVE_STD_TRANSFORM 1 /* Define to 1 if stdbool.h conforms to C99. */ /* #undef HAVE_STDBOOL_H */ /* Define to 1 if you have the header file. */ #ifdef __MINGW32__ #define HAVE_STDINT_H 1 #endif /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 #ifdef __MINGW32__ #define HAVE_STRCASECMP 1 #endif /* Define to 1 if you have the `strchr' function. */ #define HAVE_STRCHR 1 /* Define to 1 if you have the `strftime' function. */ #define HAVE_STRFTIME 1 /* Define to 1 if you have the header file. */ /* #define HAVE_STRINGS_H 1 */ /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have the `strstr' function. */ #define HAVE_STRSTR 1 /* Define to 1 if `st_blocks' is member of `struct stat'. */ /* #define HAVE_STRUCT_STAT_ST_BLOCKS 1 */ /* Define to 1 if your `struct stat' has `st_blocks'. Deprecated, use `HAVE_STRUCT_STAT_ST_BLOCKS' instead. */ /* #define HAVE_ST_BLOCKS 1 */ /* Define to 1 if you have the header file. */ /* #define HAVE_SYS_IOCTL_H 1 */ /* Define to 1 if you have the header file. */ /* #define HAVE_SYS_STATVFS_H 1 */ /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_TIME_H */ /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have that is POSIX.1 compatible. */ /* #define HAVE_SYS_WAIT_H 1 */ /* Define to 1 if you have the header file. */ /* #define HAVE_UNISTD_H 1 */ /* Define to 1 if you have the `vfork' function. */ /* #define HAVE_VFORK 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_VFORK_H */ /* Define to 1 if `fork' works. */ /* #define HAVE_WORKING_FORK 1 */ /* Define to 1 if `vfork' works. */ /* #define HAVE_WORKING_VFORK 1 */ /* Define to 1 if the system has the type `_Bool'. */ /* #undef HAVE__BOOL */ #ifndef __MINGW32__ /* Define to 1 if the system has the type `_int32'. */ #define HAVE__INT32 1 /* Define to 1 if the system has the type `_int64'. */ #define HAVE__INT64 1 #endif /* Define to 1 if `lstat' dereferences a symlink specified with a trailing slash. */ /* #undef LSTAT_FOLLOWS_SLASHED_SYMLINK */ /* Define to 1 if `major', `minor', and `makedev' are declared in . */ #define MAJOR_IN_MKDEV 1 /* Define to 1 if `major', `minor', and `makedev' are declared in . */ /* #undef MAJOR_IN_SYSMACROS */ /* Define for custom build identification in stderr */ /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT #define PACKAGE_BUGREPORT "korpela@ssl.berkeley.edu" /* Define to the full name of this package. */ #undef PACKAGE_NAME #define PACKAGE_NAME FILE_DESCRIPTION /* Define to the full name and version of this package. */ #undef PACKAGE_STRING #define PACKAGE_STRING FILE_DESCRIPTION" " FILE_VERSION /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME #define PACKAGE_TARNAME FILE_DESCRIPTION /* Define to the version of this package. */ #undef PACKAGE_VERSION #define PACKAGE_VERSION FILE_VERSION #ifndef COMPILER_STRING #ifdef __MINGW32__ #define QUOTEME_(x) #x #define QUOTEME(x) QUOTEME_(x) #define COMPILER_STRING "DevC++/MinGW/g++ "\ QUOTEME(__GNUC__) "."\ QUOTEME(__GNUC_MINOR__) "."\ QUOTEME(__GNUC_PATCHLEVEL__) #elif defined(_MSC_VER) #if _MSC_VER == 1500 #define COMPILER_STRING "Visual Studio 2008/Microsoft Visual C++ 9" #elif _MSC_VER ==1600 #define COMPILER_STRING "Visual Studio 2010/Microsoft Visual C++ 10" #elif _MSC_VER ==1900 #define COMPILER_STRING "Visual Studio 2015/Microsoft Visual C++ 14" #else #define COMPILER_STRING "Visual Studio/Microsoft Visual C++" #endif #else #define COMPILER_STRING "Unknown Compiler" #endif #endif #ifndef CUSTOM_STRING #define CUSTOM_STRING "setiathome_v8 " FILE_VERSION " " COMPILER_STRING #endif /* The size of a `long double', as computed by sizeof. */ #define SIZEOF_LONG_DOUBLE sizeof (long double) /* The size of a `long int', as computed by sizeof. */ #define SIZEOF_LONG_INT 4 /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Define to 1 if your declares `struct tm'. */ /* #undef TM_IN_SYS_TIME */ /* Define to 1 if informix is installed */ /* #undef USE_INFORMIX */ /* Define if MYSQL is installed */ /* #undef USE_MYSQL */ /* SETI@home major version number */ #define VERSION_MAJOR VER_MAJOR /* SETI@home minor version number */ #define VERSION_MINOR VER_MINOR /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ #ifdef __MINGW32__ #undef HAVE_SIGACTION #undef HAVE_STRLCPY #undef HAVE_STRLCAT #endif /* Define as `__inline' if that's what the C compiler calls it, or to nothing if it is not supported. */ #ifdef _MSC_VER #undef inline typedef ptrdiff_t ssize_t; #endif /* Define to rpl_malloc if the replacement function should be used. */ /* #undef malloc */ /* Define to `long' if does not define. */ /* #undef off_t */ /* Define to `int' if does not define. */ /* #undef pid_t */ /* Define to rpl_realloc if the replacement function should be used. */ /* #undef realloc */ /* Define to `unsigned' if does not define. */ /* #undef size_t */ /* Define as `fork' if `vfork' does not work. */ /* #undef vfork */ #if defined(HAVE_LIBFFTW) #define USE_FFTWF #endif #if defined(USE_INFORMIX) && defined(USE_MYSQL) && defined(HAVE_NAMESPACES) #define USE_NAMESPACES #endif #endif boinc-app-seti_8.00~svn3701.orig/client/progress.h0000644000175000017500000000363312026174572022020 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // progress.h float GetProgressUnitSize(int NumDataPoints, int num_cfft, long ac_fft_len); double SpikeProgressUnits(int FftLen); double GaussianProgressUnits(); double PulseProgressUnits(double PulsePoTLen, int FftLen); double TripletProgressUnits(); double ChirpProgressUnits(); void fraction_done(double progress,double remaining); extern double triplet_units; extern double pulse_units; extern double spike_units; extern double gauss_units; void reset_units(); boinc-app-seti_8.00~svn3701.orig/client/collect2_line_solaris.csh0000644000175000017500000000252010671336410024741 0ustar locutuslocutus#! /bin/csh # Run this with the desired version number as the only operand. Ex: # collect2_line 2.27 /usr/local/gcc/bin/../lib/gcc-lib/sparc-sun-solaris2.7/3.0.4/collect2 -V -Y P,/usr/ccs/lib:/usr/lib -Qy -o setiathome_${1}_sparc-sun-solaris2.7 /usr/local/gcc/bin/../lib/gcc-lib/sparc-sun-solaris2.7/3.0.4/crt1.o /usr/local/gcc/bin/../lib/gcc-lib/sparc-sun-solaris2.7/3.0.4/crti.o /usr/ccs/lib/values-Xa.o /usr/local/gcc/bin/../lib/gcc-lib/sparc-sun-solaris2.7/3.0.4/crtbegin.o -L. -L../../boinc/lib -L/usr/local/gcc/bin/../lib/gcc-lib/sparc-sun-solaris2.7/3.0.4 -L/usr/local/gcc/bin/../lib/gcc-lib -L/usr/local/gcc-3.0.4/lib/gcc-lib/sparc-sun-solaris2.7/3.0.4 -L/usr/ccs/bin -L/usr/ccs/lib -L/usr/local/gcc/bin/../lib/gcc-lib/sparc-sun-solaris2.7/3.0.4/../../.. -L/usr/local/gcc-3.0.4/lib/gcc-lib/sparc-sun-solaris2.7/3.0.4/../../.. main.o analyzeFuncs.o analyzeReport.o analyzePoT.o pulsefind.o gaussfit.o lcgamm.o malloc_a.o seti.o seti_header.o timecvt.o s_util.o version.o worker.o chirpfft.o spike.o progress.o ../db/schema_master_client.o ../db/sqlrow_client.o ../db/sqlblob.o ../db/xml_util.o -looura -B static -lstdc++ -B dynamic -lz -lsocket -lnsl -lelf -ldl -laio -lboinc -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/local/gcc/bin/../lib/gcc-lib/sparc-sun-solaris2.7/3.0.4/crtend.o /usr/local/gcc/bin/../lib/gcc-lib/sparc-sun-solaris2.7/3.0.4/crtn.o boinc-app-seti_8.00~svn3701.orig/client/collect2_line_linux.csh0000755000175000017500000000163510671336410024435 0ustar locutuslocutus#! /bin/csh # Run this with the desired version number as the only operand. Ex: # collect2_line 2.27 /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.2.2/collect2 -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o setiathome_$1_i686-pc-linux-gnu /usr/lib/crt1.o /usr/lib/crti.o /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.2.2/crtbegin.o -L. -L../../boinc/lib -L/usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.2.2 -L/usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.2.2/../../.. main.o analyzeFuncs.o analyzeReport.o analyzePoT.o pulsefind.o gaussfit.o lcgamm.o malloc_a.o seti.o seti_header.o timecvt.o s_util.o version.o worker.o chirpfft.o spike.o progress.o ../db/schema_master_client.o ../db/sqlrow_client.o ../db/sqlblob.o ../db/xml_util.o -looura -Bstatic -lstdc++ -Bdynamic -lz -lnsl -ldl -lboinc -Bstatic -lstdc++ -Bdynamic -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.2.2/crtend.o /usr/lib/crtn.o boinc-app-seti_8.00~svn3701.orig/client/spike.h0000644000175000017500000000306010671336410021254 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. int FindSpikes( float * fp_PowerSpectrum, int ul_NumDataPoints, int fft_num, SETI_WU_INFO& swi ); boinc-app-seti_8.00~svn3701.orig/client/app_icon.h0000644000175000017500000053020710671336410021741 0ustar locutuslocutuschar MacAppIconData[] = { 0X69,0X63,0X6E,0X73,0X00,0X00,0X86,0X53,0X69,0X63,0X73,0X23,0X00,0X00,0X00,0X48, 0X02,0X00,0X05,0X00,0X08,0X80,0X15,0X40,0XED,0XB8,0X80,0X08,0XC0,0X18,0X6F,0XB0, 0X3F,0XE0,0X1F,0XC0,0X0F,0X80,0X1F,0XC0,0X38,0XE0,0X17,0X40,0X2F,0XA0,0X7F,0XF0, 0X02,0X00,0X07,0X00,0X0F,0X80,0X1F,0XC0,0XFF,0XF8,0XFF,0XF8,0XFF,0XF8,0X7F,0XF0, 0X3F,0XE0,0X1F,0XC0,0X0F,0X80,0X1F,0XC0,0X3F,0XE0,0X1F,0XC0,0X3F,0XE0,0X7F,0XF0, 0X69,0X63,0X73,0X34,0X00,0X00,0X00,0X88,0X00,0X00,0X00,0XF0,0X00,0X00,0X00,0X00, 0X00,0X00,0X0F,0X1F,0X00,0X00,0X00,0X00,0X00,0X00,0XF1,0X11,0XF0,0X00,0X00,0X00, 0X00,0X0F,0X1F,0X1F,0X1F,0X00,0X00,0X00,0XFF,0XF1,0XFF,0X1F,0XF1,0XFF,0XF0,0X00, 0XF1,0X11,0X11,0X11,0X11,0X11,0XF0,0X00,0XF9,0X81,0X81,0X81,0X81,0X89,0XF0,0X00, 0X0F,0X98,0X88,0X88,0X88,0X9F,0X00,0X00,0X00,0XF9,0X89,0X99,0X89,0XF0,0X00,0X00, 0X00,0X0F,0XF9,0X99,0XFF,0X00,0X00,0X00,0X00,0X00,0XF9,0XF9,0XF0,0X00,0X00,0X00, 0X00,0X0F,0XF9,0X99,0XFF,0X00,0X00,0X00,0X00,0XFF,0X98,0X88,0X9F,0XF0,0X00,0X00, 0X00,0X0F,0X89,0XF9,0X8F,0X00,0X00,0X00,0X00,0XF8,0XFF,0X9F,0XF8,0XF0,0X00,0X00, 0X0F,0XFF,0XFF,0XFF,0XFF,0XFF,0X00,0X00,0X69,0X63,0X73,0X38,0X00,0X00,0X01,0X08, 0X00,0X00,0X00,0X00,0X00,0X00,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00, 0X00,0X00,0X00,0X00,0X00,0XFF,0X28,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00, 0X00,0X00,0X00,0X00,0XFF,0X28,0X28,0X28,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,0X00, 0X00,0X00,0X00,0XFF,0X71,0XFF,0X28,0XFF,0X71,0XFF,0X00,0X00,0X00,0X00,0X00,0X00, 0XFF,0XFF,0XFF,0X71,0XFF,0XFF,0X28,0XFF,0XFF,0X71,0XFF,0XFF,0XFF,0X00,0X00,0X00, 0XFF,0X28,0X28,0X28,0X28,0X28,0X28,0X28,0X28,0X28,0X28,0X28,0XFF,0X00,0X00,0X00, 0XFF,0XE8,0X9B,0X71,0X9B,0X71,0X9B,0X71,0X9B,0X71,0X9B,0XE8,0XFF,0X00,0X00,0X00, 0X00,0XFF,0XE6,0X9B,0XE4,0XE4,0XE4,0XE4,0XE4,0X9B,0XE6,0XFF,0X00,0X00,0X00,0X00, 0X00,0X00,0XFF,0XE8,0XE4,0XE6,0XE6,0XE6,0XE4,0XE8,0XFF,0X00,0X00,0X00,0X00,0X00, 0X00,0X00,0X00,0XFF,0XE9,0XE8,0XE8,0XE8,0XE9,0XFF,0X00,0X00,0X00,0X00,0X00,0X00, 0X00,0X00,0X00,0X00,0XFF,0XE8,0XFF,0XE8,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,0X00, 0X00,0X00,0X00,0XFF,0XE9,0XE6,0XE6,0XE6,0XE9,0XFF,0X00,0X00,0X00,0X00,0X00,0X00, 0X00,0X00,0XFF,0XE9,0XE6,0X9B,0X9B,0X9B,0XE6,0XE9,0XFF,0X00,0X00,0X00,0X00,0X00, 0X00,0X00,0X00,0XFF,0X9B,0XE6,0XFF,0XE6,0X9B,0XFF,0X00,0X00,0X00,0X00,0X00,0X00, 0X00,0X00,0XFF,0X9B,0XFF,0XFF,0XE6,0XFF,0XFF,0X9B,0XFF,0X00,0X00,0X00,0X00,0X00, 0X00,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X00,0X00,0X00,0X00, 0X49,0X43,0X4E,0X23,0X00,0X00,0X01,0X08,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X00,0X01, 0XBF,0XFE,0XFF,0XFD,0XBF,0XFC,0X7F,0XFD,0XBF,0X7A,0XBF,0XF5,0XBF,0XF6,0XDF,0XFD, 0XBF,0XEE,0XEF,0XFD,0XBF,0XDE,0XF7,0XFD,0XB8,0X00,0X00,0X3D,0XB8,0X00,0X00,0X3D, 0XBC,0XAA,0XAA,0X7D,0XBD,0X55,0X55,0X7D,0XBE,0XFF,0XFE,0XFD,0XBF,0X7F,0XFD,0XFD, 0XBF,0X9F,0XF3,0XFD,0XBF,0XE0,0X0F,0XFD,0XBE,0XF7,0XDF,0X7D,0XBF,0XF0,0X1F,0XFD, 0XBF,0XFA,0XBF,0XFD,0XBF,0XF9,0X3F,0XFD,0XBF,0XF0,0X1F,0XFD,0XBF,0XF0,0X1F,0XFD, 0XBF,0XED,0X6F,0XFD,0XBF,0XDE,0XF7,0XFD,0X80,0X00,0X00,0X01,0XFF,0XFF,0XFF,0XFF, 0XFF,0XE6,0X8B,0X03,0XFF,0XDD,0XDF,0XE7,0XF7,0XEC,0XDB,0XEF,0XE7,0XF5,0XDB,0XFF, 0XC0,0XCE,0XDB,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X69,0X63,0X6C,0X34,0X00,0X00,0X02,0X08, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFC,0XCC,0XCC,0XCC,0XCC,0XCC,0XCC,0XCD,0XDD,0XDD,0XDD,0XDD,0XDD,0XDD,0XDD,0XEF, 0XFC,0X66,0X66,0X66,0X66,0X66,0X66,0X60,0X66,0X66,0X66,0X66,0X66,0X66,0X66,0XEF, 0XFC,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X11,0X1F,0XFF,0XFE,0XFF,0XFF,0XFF,0XFF,0XEF, 0XFC,0X66,0X66,0X66,0XC6,0X66,0X61,0X91,0X91,0X66,0X66,0X66,0X66,0X66,0XC6,0XEF, 0XFC,0XFF,0XFF,0XFF,0XFF,0XFF,0X19,0XF1,0XF9,0X1F,0XFF,0XFF,0XFF,0XFF,0XFF,0XEF, 0XFC,0X6E,0X66,0X66,0X66,0X61,0X9F,0XF1,0XFF,0X91,0X66,0X66,0X66,0X66,0XF6,0XEF, 0XFC,0XFF,0XFF,0XFF,0XFF,0X19,0XFF,0XF1,0XFF,0XF9,0X1F,0XFF,0XFF,0XFF,0XFF,0XEF, 0XFC,0X66,0X61,0X11,0X11,0X11,0X11,0X11,0X11,0X11,0X11,0X11,0X11,0X66,0X66,0XEF, 0XFC,0XFF,0XF1,0X88,0X88,0X88,0X88,0X88,0X88,0X88,0X88,0X88,0X81,0XFF,0XFF,0XEF, 0XFC,0X66,0X69,0X18,0X98,0X98,0X98,0X98,0X98,0X98,0X98,0X98,0X89,0X66,0X66,0XEF, 0XFC,0XFF,0XFF,0X89,0X89,0X89,0X89,0X89,0X89,0X89,0X89,0X89,0X8F,0XFF,0XFF,0XEF, 0XFC,0X66,0X66,0X61,0X88,0X88,0X88,0X88,0X88,0X88,0X88,0X81,0X66,0X66,0X66,0XEF, 0XFC,0XFF,0XFF,0XFF,0X89,0X99,0X99,0X99,0X99,0X99,0X99,0X8F,0XFF,0XFF,0XFF,0XEF, 0XFC,0X66,0X66,0X66,0X68,0X99,0X99,0X99,0X99,0X99,0X98,0X66,0X66,0X66,0X66,0XEF, 0XFD,0XFF,0XFF,0XFF,0XFF,0XF9,0X99,0X99,0X99,0X99,0XFF,0XFF,0XFF,0XFF,0XFF,0XEF, 0XFD,0X66,0X66,0X6C,0X66,0X66,0X9F,0XFF,0XFF,0X96,0X66,0X66,0XC6,0X66,0X66,0XEF, 0XFD,0XFF,0XFF,0XFF,0XFF,0XFF,0X99,0X99,0X99,0X9F,0XFF,0XFF,0XFF,0XFF,0XFF,0XEF, 0XFD,0X66,0X66,0X66,0X66,0X66,0X69,0XF9,0XF9,0X66,0X66,0X66,0X66,0X66,0X66,0XEF, 0XFD,0XFF,0XFF,0XFF,0XFF,0XFF,0XF9,0X9F,0X99,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XEF, 0XFD,0X66,0XE6,0X66,0X66,0X66,0X99,0X99,0X99,0X96,0X66,0X66,0X66,0X6E,0X66,0XEF, 0XFD,0XFF,0XFF,0XFF,0XFF,0XFF,0X89,0XFF,0XF9,0X8F,0XFF,0XFF,0XFF,0XFF,0XFF,0XEF, 0XFD,0X66,0X66,0X66,0X66,0X68,0X9F,0X8F,0X8F,0X98,0X66,0X66,0X66,0X66,0X66,0XEF, 0XFD,0XFF,0XFF,0XFF,0XFF,0X89,0XFF,0XF8,0XFF,0XF9,0X8F,0XFF,0XFF,0XFF,0XFF,0XEF, 0XFE,0XEE,0XEE,0XEE,0XEE,0XEE,0XEE,0XEE,0XEE,0XEE,0XEE,0XEE,0XEE,0XEE,0XEE,0XEF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0X91,0X1F,0X91,0XF1,0X11,0XF1,0XF9,0X81,0X11,0X11,0X9F, 0XFF,0XFF,0X9F,0XFF,0XFF,0X1F,0XFF,0X1F,0XFF,0X1F,0XF9,0XFF,0XFF,0XF1,0X19,0XFF, 0XFF,0XF9,0X1F,0XFF,0XFF,0X91,0X9F,0X11,0XFF,0X1F,0XF1,0XFF,0XFF,0XF1,0X9F,0XFF, 0XFF,0X91,0X1F,0XFF,0XFF,0XFF,0X1F,0X1F,0XFF,0X1F,0XF1,0XFF,0XFF,0XF9,0XFF,0XFF, 0XF9,0X11,0X11,0X18,0X9F,0X11,0X9F,0X91,0XFF,0X1F,0XF1,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0X69,0X63,0X6C,0X38,0X00,0X00,0X04,0X08,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X2B,0X2B,0X2B,0X2B,0X2B,0XF7,0XF7, 0XF7,0XF7,0XF7,0XF8,0XF8,0XF8,0XF8,0X56,0X56,0X56,0X56,0XF9,0XF9,0XF9,0XF9,0XFA, 0XFA,0XFA,0XFA,0X81,0X81,0X81,0XAC,0XFF,0XFF,0X2B,0XD3,0XF1,0XF1,0XF1,0XF1,0XF1, 0XF1,0XF1,0XF1,0XF1,0XF1,0XF1,0XF1,0X00,0XF1,0XF1,0XF1,0XF1,0XF1,0XF1,0XF1,0XF1, 0XF1,0XF1,0XF1,0XF1,0XF1,0XD3,0XFD,0XFF,0XFF,0X2B,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X28,0X71,0X28,0XFF,0XFF,0XFF,0XFF,0XFC,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFD,0XFF,0XFF,0X2B,0XD3,0XF1,0XF1,0XF1,0XF1,0XF1, 0XF8,0XF1,0XF1,0XF1,0XF1,0X71,0XE6,0X71,0XE6,0X71,0XF1,0XF1,0XF1,0XF1,0XF1,0XF1, 0XF1,0XF1,0XF1,0XF1,0XF8,0XD3,0XFD,0XFF,0XFF,0X2B,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0X28,0XE6,0XFF,0X71,0XFF,0XE6,0X28,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFD,0XFF,0XFF,0XF7,0XD3,0XFC,0XF1,0XF1,0XF1,0XF1, 0XF1,0XF1,0XF1,0X71,0XE6,0XFF,0XFF,0X71,0XFF,0XFF,0XE6,0X71,0XF1,0XF1,0XF1,0XF1, 0XF1,0XF1,0XF1,0XF1,0XF1,0XD3,0XFD,0XFF,0XFF,0XF7,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0X71,0XE6,0XFF,0XFF,0XFF,0X71,0XFF,0XFF,0XFF,0XE6,0X71,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFD,0XFF,0XFF,0XF7,0XD3,0XF1,0XF1,0X28,0X28,0X28, 0X28,0X28,0X28,0X28,0X28,0X28,0X28,0X28,0X28,0X28,0X28,0X28,0X28,0X28,0X28,0X28, 0X28,0X28,0XF1,0XF1,0XF1,0XD3,0XFD,0XFF,0XFF,0XF7,0XFF,0XFF,0XFF,0X71,0X9B,0X9B, 0X9B,0X9B,0X9B,0X9B,0X9B,0X9B,0X9B,0X9B,0X9B,0X9B,0X9B,0X9B,0X9B,0X9B,0X9B,0X9B, 0X9B,0X71,0XFF,0XFF,0XFF,0XFF,0XFD,0XFF,0XFF,0XF7,0XD3,0XF1,0XF1,0XE8,0X71,0X9B, 0XE6,0X9B,0XE6,0X9B,0XE6,0X9B,0XE6,0X9B,0XE6,0X9B,0XE6,0X9B,0XE6,0X9B,0XE6,0X9B, 0X9B,0XE8,0XF1,0XF1,0XF1,0XD3,0XFD,0XFF,0XFF,0XF8,0XFF,0XFF,0XFF,0XFF,0X9B,0XE6, 0XE4,0XE6,0XE4,0XE6,0XE4,0XE6,0XE4,0XE6,0XE4,0XE6,0XE4,0XE6,0XE4,0XE6,0XE4,0XE6, 0X9B,0XFF,0XFF,0XFF,0XFF,0XFF,0XFD,0XFF,0XFF,0XF8,0XD3,0XF1,0XF1,0XF1,0XF1,0X71, 0XE4,0XE4,0XE4,0XE4,0XE4,0XE4,0XE4,0XE4,0XE4,0XE4,0XE4,0XE4,0XE4,0XE4,0XE4,0X71, 0XF1,0XF1,0XF1,0XF1,0XF1,0XD3,0XFD,0XFF,0XFF,0XF8,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0X9B,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0X9B,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFD,0XFF,0XFF,0XF8,0XD3,0XF1,0XF1,0XF1,0XF1,0XF1, 0XF1,0XE4,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0XE4,0XF1,0XF1, 0XF1,0XF1,0XF1,0XF1,0XF1,0XD3,0XFD,0XFF,0XFF,0X56,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XE9,0XE6,0XE8,0XE8,0XE8,0XE8,0XE8,0XE8,0XE8,0XE6,0XE9,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFD,0XFF,0XFF,0X56,0XD3,0XF1,0XF1,0XF1,0XF1,0XF8, 0XF1,0XF1,0XF1,0XF1,0XE6,0XE9,0XE9,0XE9,0XE9,0XE9,0XE6,0XF1,0XF1,0XF1,0XF1,0XF1, 0XF8,0XF1,0XF1,0XF1,0XF1,0XD3,0XFD,0XFF,0XFF,0X56,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFD,0XFF,0XFF,0X56,0XD3,0XF1,0XF1,0XF1,0XF1,0XF1, 0XF1,0XF1,0XF1,0XF1,0XF1,0XE6,0XE9,0XE7,0XE9,0XE6,0XF1,0XF1,0XF1,0XF1,0XF1,0XF1, 0XF1,0XF1,0XF1,0XF1,0XF1,0XD3,0XFD,0XFF,0XFF,0XF9,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XE6,0XE7,0XE9,0XE7,0XE6,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFD,0XFF,0XFF,0XF9,0XD3,0XF1,0XFC,0XF1,0XF1,0XF1, 0XF1,0XF1,0XF1,0XF1,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0XF1,0XF1,0XF1,0XF1,0XF1, 0XF1,0XF1,0XF1,0XFC,0XF1,0XD3,0XFD,0XFF,0XFF,0XF9,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0X9B,0XE6,0XFF,0XFF,0XFF,0XE6,0X9B,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFD,0XFF,0XFF,0XF9,0XD3,0XF1,0XF1,0XF1,0XF1,0XF1, 0XF1,0XF1,0XF1,0X9B,0XE6,0XFF,0X9B,0XFF,0X9B,0XFF,0XE6,0X9B,0XF1,0XF1,0XF1,0XF1, 0XF1,0XF1,0XF1,0XF1,0XF1,0XD3,0XFD,0XFF,0XFF,0XFA,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0X9B,0XE6,0XFF,0XFF,0XFF,0X9B,0XFF,0XFF,0XFF,0XE6,0X9B,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFD,0XFF,0XFF,0XAC,0XFD,0XFD,0XFD,0XFD,0XFD,0XFD, 0XFD,0XFD,0XFD,0XFD,0XFD,0XFD,0XFD,0XFD,0XFD,0XFD,0XFD,0XFD,0XFD,0XFD,0XFD,0XFD, 0XFD,0XFD,0XFD,0XFD,0XFD,0XFD,0XFD,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XE5,0X71,0X71,0XFF,0XE5,0X71,0XFF,0X71,0X71,0X71,0XFF,0X71,0XE8,0XE6, 0XE4,0X71,0X4C,0X4C,0X27,0X02,0XE8,0XFF,0XFF,0XFF,0XFF,0XFF,0XE8,0XFF,0XFF,0XFF, 0XFF,0XFF,0X71,0XFF,0XFF,0XFF,0X71,0XFF,0XFF,0XFF,0X71,0XFF,0XFF,0XE8,0XFF,0XFF, 0XFF,0XFF,0XFF,0X4C,0X27,0XE8,0XFF,0XFF,0XFF,0XFF,0XFF,0XE8,0X4C,0XFF,0XFF,0XFF, 0XFF,0XFF,0XE7,0X71,0XE7,0XFF,0X71,0X71,0XFF,0XFF,0X71,0XFF,0XFF,0X71,0XFF,0XFF, 0XFF,0XFF,0XFF,0X4C,0XE8,0XFF,0XFF,0XFF,0XFF,0XFF,0XE8,0X27,0X4C,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0X71,0XFF,0X71,0XFF,0XFF,0XFF,0X71,0XFF,0XFF,0X71,0XFF,0XFF, 0XFF,0XFF,0XFF,0XE8,0XFF,0XFF,0XFF,0XFF,0XFF,0XE8,0X02,0X27,0X4C,0X4C,0X71,0XE4, 0XE6,0XFF,0X71,0X71,0XE5,0XFF,0XE5,0X71,0XFF,0XFF,0X71,0XFF,0XFF,0X71,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X69,0X74,0X33,0X32,0X00,0X00,0X3D,0X53, 0X00,0X00,0X00,0X00,0XFF,0X00,0XFF,0X00,0XFC,0X00,0X02,0XE9,0XE2,0XCE,0XF1,0XC3, 0X02,0XB4,0X8E,0X69,0X83,0X00,0X02,0XE2,0XDD,0XC6,0XF1,0XB4,0X02,0X9B,0X6C,0X4D, 0X83,0X00,0X02,0XCE,0XC6,0XA8,0XF1,0X91,0X02,0X75,0X55,0X37,0X83,0X00,0X02,0XC3, 0XB4,0X91,0XF1,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XF1,0X00, 0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XF1,0X00,0X02,0X67,0X48,0X30, 0X83,0X00,0X02,0XC3,0XB4,0X91,0XB4,0X00,0X01,0XFF,0XFF,0XB8,0X00,0X02,0X67,0X48, 0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XB2,0X00,0X00,0X2A,0X81,0XFF,0X00,0X2A,0XA9, 0X00,0X00,0X02,0X89,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XB1, 0X00,0X01,0X38,0XEE,0X81,0XFF,0X01,0XEE,0X38,0XA8,0X00,0X03,0X04,0X07,0X04,0X03, 0X86,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9C,0X00,0X80,0X01, 0X8E,0X00,0X02,0X38,0XEE,0XF6,0X81,0XFF,0X02,0XF6,0XEE,0X38,0XA5,0X00,0X05,0X02, 0X12,0X1C,0X24,0X17,0X08,0X86,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4, 0X91,0X9C,0X00,0X03,0X0B,0X25,0X22,0X09,0X8C,0X00,0X03,0X37,0XE9,0XF1,0XF8,0X81, 0XFA,0X03,0XF8,0XF1,0XE9,0X37,0XA3,0X00,0X07,0X03,0X0D,0X3B,0X6B,0X7A,0X57,0X1F, 0X05,0X85,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9B,0X00,0X05, 0X05,0X33,0X93,0X8C,0X30,0X02,0X8A,0X00,0X04,0X36,0XE4,0XEB,0XF2,0XEF,0X81,0XF4, 0X04,0XEF,0XF2,0XEB,0XE4,0X36,0XA2,0X00,0X08,0X07,0X23,0X6D,0XB7,0XC8,0X9B,0X43, 0X0B,0X02,0X84,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9B,0X00, 0X05,0X05,0X4F,0XC1,0XB9,0X49,0X05,0X89,0X00,0X05,0X34,0XDC,0XE4,0XEA,0XE7,0X76, 0X81,0XEC,0X05,0X76,0XE7,0XEA,0XE4,0XDC,0X34,0XA1,0X00,0X07,0X07,0X2B,0X82,0XCA, 0XD9,0XB0,0X53,0X11,0X85,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, 0X9B,0X00,0X05,0X01,0X20,0X5A,0X56,0X1A,0X03,0X88,0X00,0X06,0X32,0XD5,0XDC,0XE2, 0XE0,0X72,0X00,0X81,0XE4,0X06,0X00,0X72,0XE0,0XE2,0XDC,0XD5,0X32,0XA0,0X00,0X07, 0X02,0X1D,0X60,0XA3,0XB5,0X89,0X39,0X0A,0X85,0X00,0X02,0X67,0X48,0X30,0X83,0X00, 0X02,0XC3,0XB4,0X91,0X9C,0X00,0X02,0X07,0X06,0X08,0X89,0X00,0X07,0X30,0XCC,0XD3, 0XD9,0XD7,0X6D,0X00,0X00,0X81,0XDB,0X07,0X00,0X00,0X6D,0XD7,0XD9,0XD3,0XCC,0X30, 0X9F,0X00,0X07,0X01,0X0C,0X26,0X4D,0X58,0X3D,0X15,0X02,0X85,0X00,0X02,0X67,0X48, 0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XAA,0X00,0X05,0X2E,0XC4,0XCB,0XD0,0XCE,0X69, 0X80,0X00,0X81,0XD2,0X80,0X00,0X05,0X69,0XCE,0XD0,0XCB,0XC4,0X2E,0X9F,0X00,0X05, 0X01,0X06,0X10,0X12,0X0B,0X03,0X86,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3, 0XB4,0X91,0XA9,0X00,0X05,0X2C,0XBB,0XC1,0XC6,0XC4,0X64,0X81,0X00,0X81,0XC8,0X81, 0X00,0X05,0X64,0XC4,0XC6,0XC1,0XBB,0X2C,0X9F,0X00,0X03,0X07,0X01,0X02,0X04,0X87, 0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XA8,0X00,0X05,0X2A,0XB2, 0XB8,0XBE,0XBB,0X5F,0X82,0X00,0X81,0XBF,0X82,0X00,0X05,0X5F,0XBB,0XBE,0XB8,0XB2, 0X2A,0XAC,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XA7,0X00,0X05, 0X28,0XAA,0XB0,0XB5,0XB2,0X5B,0X83,0X00,0X81,0XB6,0X83,0X00,0X05,0X5B,0XB2,0XB5, 0XB0,0XAA,0X28,0XAB,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XA6, 0X00,0X05,0X26,0XA1,0XA7,0XAC,0XAA,0X54,0X84,0X00,0X81,0XAD,0X84,0X00,0X05,0X54, 0XAA,0XAC,0XA7,0XA1,0X26,0XAA,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4, 0X91,0X81,0X00,0X05,0X01,0X01,0X07,0X04,0X04,0X01,0X9B,0X00,0X05,0X24,0X99,0X9E, 0XA3,0XA1,0X50,0X85,0X00,0X81,0XA4,0X85,0X00,0X05,0X50,0XA1,0XA3,0X9E,0X99,0X24, 0XA9,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X80,0X00,0X07,0X01, 0X06,0X12,0X21,0X1E,0X11,0X04,0X01,0X99,0X00,0X05,0X22,0X91,0X96,0X9A,0X98,0X4B, 0X86,0X00,0X81,0X9B,0X86,0X00,0X05,0X4B,0X98,0X9A,0X96,0X91,0X22,0XA8,0X00,0X02, 0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X80,0X00,0X07,0X04,0X15,0X3B,0X5A, 0X55,0X32,0X10,0X02,0X98,0X00,0X05,0X20,0X88,0X8D,0X91,0X8F,0X47,0X87,0X00,0X81, 0X92,0X87,0X00,0X05,0X47,0X8F,0X91,0X8D,0X88,0X20,0XA7,0X00,0X02,0X67,0X48,0X30, 0X83,0X00,0X02,0XC3,0XB4,0X91,0X80,0X00,0X08,0X08,0X26,0X63,0X88,0X81,0X4F,0X1A, 0X03,0X01,0X96,0X00,0X05,0X1E,0X7F,0X83,0X87,0X85,0X42,0X88,0X00,0X81,0X88,0X88, 0X00,0X05,0X42,0X85,0X87,0X83,0X7F,0X1E,0XA6,0X00,0X02,0X67,0X48,0X30,0X83,0X00, 0X0D,0XC3,0XB4,0X91,0X00,0X00,0X01,0X07,0X29,0X65,0X8B,0X83,0X51,0X1B,0X04,0X96, 0X00,0X05,0X1C,0X77,0X7B,0X7E,0X7D,0X3E,0X89,0X00,0X81,0X7F,0X89,0X00,0X05,0X3E, 0X7D,0X7E,0X7B,0X77,0X1C,0XA5,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4, 0X91,0X80,0X00,0X07,0X04,0X1A,0X43,0X61,0X59,0X33,0X10,0X04,0X95,0X00,0X05,0X1A, 0X6E,0X72,0X75,0X74,0X39,0X8A,0X00,0X81,0X76,0X8A,0X00,0X05,0X39,0X74,0X75,0X72, 0X6E,0X1A,0XA4,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X80,0X00, 0X07,0X01,0X08,0X18,0X25,0X22,0X12,0X04,0X01,0X94,0X00,0X05,0X18,0X67,0X6A,0X6D, 0X6C,0X35,0X8B,0X00,0X81,0X6E,0X8B,0X00,0X05,0X35,0X6C,0X6D,0X6A,0X67,0X18,0XA3, 0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X81,0X00,0X05,0X01,0X05, 0X06,0X07,0X02,0X01,0X94,0X00,0X05,0X16,0X5F,0X62,0X65,0X64,0X32,0X8C,0X00,0X81, 0X66,0X8C,0X00,0X05,0X32,0X64,0X65,0X62,0X5F,0X16,0XA2,0X00,0X02,0X67,0X48,0X30, 0X83,0X00,0X02,0XC3,0XB4,0X91,0X82,0X00,0X00,0X01,0X97,0X00,0X05,0X15,0X5A,0X5D, 0X5F,0X5E,0X2F,0X8D,0X00,0X81,0X60,0X8D,0X00,0X05,0X2F,0X5E,0X5F,0X5D,0X5A,0X15, 0XA1,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X89,0X00,0XD6,0XFF, 0X8C,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X89,0X00,0X00,0XCB, 0XD4,0XCC,0X00,0XCB,0X8C,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, 0X89,0X00,0X02,0XC5,0XCC,0XB8,0XD0,0XB7,0X02,0XB8,0XCC,0XC5,0X8C,0X00,0X02,0X67, 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X89,0X00,0X02,0XB4,0XC8,0X9E,0XD0,0X99, 0X02,0X9E,0XC8,0XB4,0X8C,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, 0X89,0X00,0X02,0X9E,0XC4,0X88,0XD0,0X79,0X02,0X88,0XC4,0X9E,0X8C,0X00,0X02,0X67, 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X89,0X00,0X02,0X82,0XBF,0X7B,0XD0,0X5B, 0X02,0X7B,0XBF,0X82,0X8C,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, 0X89,0X00,0X02,0X65,0XBA,0X75,0XD0,0X3A,0X02,0X75,0XBA,0X65,0X8C,0X00,0X02,0X67, 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X89,0X00,0X02,0X44,0XB4,0X7A,0XD0,0X1B, 0X02,0X7A,0XB4,0X44,0X8C,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, 0X89,0X00,0X03,0X21,0XAB,0X8D,0X06,0X81,0X04,0X00,0X02,0X84,0X04,0X00,0X02,0X84, 0X04,0X00,0X02,0X84,0X04,0X00,0X02,0X84,0X04,0X00,0X02,0X84,0X04,0X00,0X02,0X84, 0X04,0X00,0X02,0X84,0X04,0X00,0X02,0X84,0X04,0X00,0X02,0X84,0X04,0X00,0X02,0X81, 0X04,0X03,0X06,0X8D,0XAB,0X21,0X8C,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3, 0XB4,0X91,0X8A,0X00,0X02,0X7E,0XA6,0X28,0XCE,0X00,0X02,0X28,0XA6,0X7E,0X8D,0X00, 0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8A,0X00,0X02,0X52,0X9F,0X4D, 0XCE,0X00,0X02,0X4D,0X9F,0X52,0X8D,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3, 0XB4,0X91,0X8A,0X00,0X03,0X28,0X97,0X70,0X01,0XCC,0X00,0X03,0X01,0X70,0X97,0X28, 0X8D,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8B,0X00,0X02,0X65, 0X91,0X1A,0XCC,0X00,0X02,0X1A,0X91,0X65,0X8E,0X00,0X02,0X67,0X48,0X30,0X83,0X00, 0X02,0XC3,0XB4,0X91,0X8B,0X00,0X02,0X36,0X89,0X3F,0XCC,0X00,0X02,0X3F,0X89,0X36, 0X8E,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8B,0X00,0X03,0X0A, 0X60,0X78,0X13,0XCA,0X00,0X03,0X22,0X78,0X60,0X0A,0X8E,0X00,0X02,0X67,0X48,0X30, 0X83,0X00,0X02,0XC3,0XB4,0X91,0X8C,0X00,0X02,0X31,0X7B,0X4A,0XCA,0X00,0X02,0X4A, 0X7B,0X31,0X8F,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8C,0X00, 0X03,0X05,0X4D,0X6D,0X1E,0XC8,0X00,0X03,0X1E,0X6D,0X4D,0X05,0X8F,0X00,0X02,0X67, 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8D,0X00,0X03,0X1F,0X61,0X47,0X09,0XC6, 0X00,0X03,0X09,0X47,0X61,0X1F,0X90,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3, 0XB4,0X91,0X8E,0X00,0X02,0X32,0X66,0X34,0XC6,0X00,0X02,0X34,0X66,0X32,0X91,0X00, 0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8E,0X00,0X03,0X07,0X3D,0X58, 0X22,0XC4,0X00,0X03,0X22,0X58,0X3D,0X07,0X91,0X00,0X02,0X67,0X48,0X30,0X83,0X00, 0X02,0XC3,0XB4,0X91,0X8F,0X00,0X03,0X12,0X44,0X47,0X15,0XC2,0X00,0X03,0X15,0X47, 0X44,0X12,0X92,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X90,0X00, 0X03,0X18,0X44,0X39,0X0D,0XC0,0X00,0X03,0X0D,0X39,0X44,0X18,0X93,0X00,0X02,0X67, 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X91,0X00,0X03,0X1A,0X40,0X30,0X0A,0XBE, 0X00,0X03,0X0A,0X30,0X40,0X1A,0X94,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3, 0XB4,0X91,0X92,0X00,0X03,0X19,0X3A,0X2A,0X09,0XBC,0X00,0X03,0X09,0X2A,0X3A,0X19, 0X95,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X93,0X00,0X03,0X14, 0X30,0X27,0X0B,0XBA,0X00,0X03,0X0B,0X27,0X30,0X14,0X96,0X00,0X02,0X67,0X48,0X30, 0X83,0X00,0X02,0XC3,0XB4,0X91,0X94,0X00,0X03,0X0F,0X27,0X25,0X0D,0XB8,0X00,0X03, 0X0D,0X25,0X27,0X0F,0X97,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, 0X95,0X00,0X03,0X08,0X1C,0X25,0X11,0XB6,0X00,0X03,0X11,0X25,0X1C,0X08,0X98,0X00, 0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X96,0X00,0X04,0X02,0X12,0X20, 0X14,0X04,0XB2,0X00,0X04,0X04,0X14,0X20,0X12,0X02,0X99,0X00,0X02,0X67,0X48,0X30, 0X83,0X00,0X02,0XC3,0XB4,0X91,0X98,0X00,0X03,0X09,0X15,0X10,0X03,0XB0,0X00,0X03, 0X03,0X10,0X15,0X09,0X9B,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, 0X99,0X00,0X04,0X02,0X0A,0X11,0X08,0X01,0XAC,0X00,0X09,0X01,0X08,0X11,0X0A,0X02, 0X00,0X01,0X00,0X00,0X01,0X97,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4, 0X91,0X9B,0X00,0X04,0X03,0X09,0X0D,0X09,0X03,0XA8,0X00,0X07,0X03,0X09,0X0D,0X09, 0X03,0X01,0X00,0X00,0X81,0X01,0X97,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3, 0XB4,0X91,0X9D,0X00,0X04,0X02,0X06,0X09,0X07,0X02,0XA4,0X00,0X11,0X02,0X07,0X09, 0X06,0X02,0X00,0X01,0X01,0X00,0X03,0X02,0X02,0X01,0X01,0X03,0X01,0X00,0X01,0X93, 0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9F,0X00,0X04,0X01,0X03, 0X04,0X05,0X03,0XA0,0X00,0X13,0X03,0X05,0X04,0X03,0X01,0X01,0X00,0X00,0X02,0X02, 0X03,0X03,0X06,0X05,0X05,0X04,0X03,0X01,0X01,0X02,0X93,0X00,0X02,0X67,0X48,0X30, 0X83,0X00,0X02,0XC3,0XB4,0X91,0XA2,0X00,0X00,0X01,0X80,0X02,0X00,0X01,0X9A,0X00, 0X00,0X01,0X80,0X02,0X00,0X01,0X81,0X00,0X05,0X01,0X01,0X03,0X03,0X06,0X08,0X80, 0X09,0X06,0X07,0X05,0X03,0X02,0X01,0X02,0X01,0X91,0X00,0X02,0X67,0X48,0X30,0X83, 0X00,0X02,0XC3,0XB4,0X91,0XCC,0X00,0X10,0X01,0X02,0X03,0X06,0X09,0X0C,0X0F,0X11, 0X11,0X0F,0X0C,0X0B,0X06,0X04,0X01,0X00,0X01,0X91,0X00,0X02,0X67,0X48,0X30,0X83, 0X00,0X02,0XC3,0XB4,0X91,0XAA,0X00,0X03,0X01,0X02,0X01,0X02,0X81,0X01,0X84,0X00, 0X81,0X01,0X03,0X02,0X01,0X02,0X01,0X86,0X00,0X12,0X01,0X01,0X02,0X02,0X04,0X09, 0X0E,0X13,0X1D,0X21,0X22,0X1C,0X18,0X10,0X0B,0X08,0X03,0X02,0X01,0X91,0X00,0X02, 0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XCB,0X00,0X11,0X01,0X03,0X03,0X08, 0X0D,0X14,0X1F,0X36,0X47,0X51,0X40,0X2B,0X19,0X0F,0X09,0X05,0X00,0X02,0X91,0X00, 0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XCC,0X00,0X11,0X02,0X06,0X0A, 0X12,0X1C,0X39,0X66,0X96,0XA3,0X83,0X4B,0X27,0X15,0X0E,0X09,0X03,0X01,0X01,0X90, 0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XCA,0X00,0X13,0X01,0X01, 0X03,0X06,0X0C,0X14,0X25,0X4A,0X97,0XD1,0XDD,0XBC,0X6E,0X34,0X1E,0X0F,0X09,0X05, 0X02,0X02,0X90,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XCC,0X00, 0X11,0X03,0X07,0X0E,0X18,0X29,0X56,0XA4,0XDD,0XE8,0XCB,0X7B,0X38,0X1F,0X11,0X09, 0X05,0X03,0X02,0X90,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XCA, 0X00,0X13,0X02,0X02,0X03,0X06,0X0D,0X15,0X25,0X49,0X86,0XBE,0XCB,0XA9,0X66,0X32, 0X1A,0X12,0X09,0X04,0X03,0X01,0X90,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3, 0XB4,0X91,0XCB,0X00,0X11,0X02,0X01,0X07,0X0B,0X14,0X1F,0X33,0X52,0X74,0X7D,0X64, 0X40,0X25,0X1A,0X0F,0X09,0X03,0X01,0X91,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02, 0XC3,0XB4,0X91,0X86,0X00,0X0E,0X01,0X00,0X00,0X01,0X00,0X02,0X01,0X01,0X02,0X01, 0X02,0X02,0X01,0X01,0X02,0X80,0X01,0XB0,0X00,0X12,0X01,0X02,0X04,0X09,0X0F,0X18, 0X21,0X2E,0X3B,0X3E,0X36,0X2A,0X1D,0X14,0X0C,0X07,0X03,0X00,0X02,0X90,0X00,0X02, 0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X84,0X00,0X03,0X01,0X01,0X00,0X03, 0X80,0X02,0X04,0X01,0X00,0X00,0X01,0X02,0X80,0X00,0X03,0X01,0X01,0X02,0X01,0XB1, 0X00,0X12,0X01,0X02,0X03,0X06,0X0B,0X11,0X17,0X22,0X23,0X24,0X26,0X1B,0X14,0X0F, 0X08,0X05,0X03,0X02,0X01,0X90,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4, 0X91,0X83,0X00,0X10,0X01,0X01,0X02,0X03,0X03,0X04,0X03,0X03,0X04,0X03,0X00,0X02, 0X01,0X00,0X00,0X01,0X01,0XB3,0X00,0X11,0X01,0X02,0X01,0X02,0X05,0X07,0X0B,0X0F, 0X14,0X16,0X15,0X15,0X11,0X0E,0X09,0X06,0X03,0X02,0X92,0X00,0X02,0X67,0X48,0X30, 0X83,0X00,0X02,0XC3,0XB4,0X91,0X81,0X00,0X05,0X01,0X01,0X02,0X03,0X04,0X07,0X80, 0X08,0X03,0X07,0X05,0X04,0X02,0X80,0X01,0X80,0X00,0X00,0X01,0XB4,0X00,0X0E,0X02, 0X01,0X01,0X04,0X06,0X08,0X0C,0X0D,0X0C,0X0C,0X09,0X07,0X04,0X04,0X03,0X93,0X00, 0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X81,0X00,0X0E,0X03,0X01,0X04, 0X07,0X0B,0X0D,0X0E,0X10,0X10,0X0D,0X0B,0X07,0X04,0X03,0X01,0XBA,0X00,0X04,0X02, 0X01,0X03,0X04,0X05,0X80,0X06,0X05,0X07,0X06,0X03,0X03,0X01,0X01,0X86,0X00,0X00, 0X01,0X89,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X81,0X00,0X10, 0X01,0X04,0X07,0X0B,0X0F,0X16,0X18,0X1A,0X19,0X16,0X12,0X0E,0X08,0X05,0X03,0X00, 0X01,0XBB,0X00,0X01,0X02,0X02,0X83,0X03,0X00,0X02,0X87,0X00,0X05,0X01,0X05,0X06, 0X07,0X04,0X01,0X85,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X17,0XC3,0XB4,0X91,0X00, 0X00,0X01,0X02,0X02,0X05,0X08,0X10,0X16,0X1F,0X25,0X28,0X25,0X22,0X1B,0X14,0X0B, 0X08,0X05,0X02,0X01,0XBB,0X00,0X0A,0X01,0X02,0X01,0X02,0X01,0X01,0X00,0X01,0X00, 0X01,0X01,0X84,0X00,0X07,0X01,0X03,0X0E,0X21,0X27,0X1A,0X09,0X02,0X84,0X00,0X02, 0X67,0X48,0X30,0X83,0X00,0X17,0XC3,0XB4,0X91,0X00,0X00,0X01,0X00,0X04,0X06,0X0D, 0X16,0X1F,0X29,0X33,0X37,0X34,0X2D,0X24,0X1A,0X10,0X09,0X06,0X03,0X01,0XBC,0X00, 0X01,0X01,0X01,0X81,0X00,0X01,0X02,0X01,0X86,0X00,0X08,0X01,0X0E,0X30,0X5B,0X68, 0X49,0X1B,0X05,0X03,0X83,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X16,0XC3,0XB4,0X91, 0X00,0X01,0X01,0X02,0X04,0X08,0X11,0X1A,0X28,0X3B,0X6F,0X8C,0X5A,0X39,0X2B,0X20, 0X14,0X0C,0X06,0X03,0XBD,0X00,0X00,0X01,0X8D,0X00,0X08,0X04,0X19,0X51,0X89,0X95, 0X75,0X30,0X0A,0X01,0X83,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X17,0XC3,0XB4,0X91, 0X00,0X00,0X01,0X03,0X06,0X09,0X12,0X1D,0X2D,0X5D,0XC3,0XE6,0X99,0X40,0X2F,0X23, 0X17,0X0C,0X06,0X04,0X01,0X93,0X00,0X02,0X03,0X0E,0X05,0X93,0X00,0X02,0X04,0X0E, 0X03,0X9B,0X00,0X08,0X04,0X1B,0X56,0X8D,0X99,0X7A,0X36,0X08,0X03,0X83,0X00,0X02, 0X67,0X48,0X30,0X83,0X00,0X03,0XC3,0XB4,0X91,0X00,0X80,0X01,0X10,0X05,0X0A,0X11, 0X1B,0X2A,0X5C,0XC1,0XE4,0X96,0X3F,0X30,0X22,0X16,0X0D,0X07,0X03,0X01,0X92,0X00, 0X03,0X08,0X22,0X0B,0X04,0X93,0X00,0X03,0X0E,0X0E,0X22,0X09,0X99,0X00,0X08,0X01, 0X03,0X0F,0X39,0X66,0X72,0X53,0X20,0X07,0X84,0X00,0X02,0X67,0X48,0X30,0X83,0X00, 0X02,0XC3,0XB4,0X91,0X81,0X00,0X10,0X04,0X08,0X10,0X1A,0X25,0X3B,0X6C,0X89,0X57, 0X38,0X2A,0X1F,0X13,0X0B,0X06,0X03,0X01,0X91,0X00,0X05,0X0D,0X39,0X12,0X07,0X3B, 0X0E,0X91,0X00,0X05,0X1A,0X38,0X07,0X10,0X39,0X0E,0X99,0X00,0X06,0X01,0X04,0X12, 0X28,0X2F,0X20,0X0A,0X85,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X16,0XC3,0XB4,0X91, 0X00,0X00,0X01,0X02,0X03,0X07,0X0C,0X13,0X1D,0X28,0X30,0X34,0X30,0X2C,0X23,0X18, 0X11,0X09,0X05,0X01,0X91,0X00,0X07,0X12,0X51,0X1A,0X00,0X00,0X14,0X54,0X14,0X8F, 0X00,0X07,0X24,0X4F,0X0A,0X00,0X00,0X17,0X51,0X14,0X9A,0X00,0X04,0X03,0X07,0X0A, 0X05,0X04,0X85,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X81,0X00, 0X0E,0X03,0X05,0X0A,0X10,0X16,0X1D,0X22,0X25,0X24,0X20,0X1A,0X13,0X0B,0X08,0X03, 0X91,0X00,0X02,0X16,0X65,0X21,0X81,0X00,0X02,0X19,0X69,0X19,0X8D,0X00,0X02,0X2E, 0X63,0X0D,0X81,0X00,0X02,0X1D,0X65,0X19,0X9B,0X00,0X00,0X01,0X87,0X00,0X02,0X67, 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X81,0X00,0X10,0X02,0X03,0X05,0X09,0X0E, 0X11,0X16,0X19,0X18,0X15,0X10,0X0C,0X07,0X04,0X02,0X01,0X01,0X8E,0X00,0X02,0X1C, 0X7D,0X29,0X83,0X00,0X02,0X1E,0X82,0X1E,0X8B,0X00,0X02,0X38,0X7A,0X0F,0X83,0X00, 0X02,0X24,0X7D,0X1E,0XA5,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, 0X81,0X00,0X0E,0X01,0X01,0X04,0X05,0X07,0X0B,0X0D,0X0D,0X0E,0X0C,0X09,0X07,0X05, 0X03,0X02,0X8F,0X00,0X02,0X21,0X93,0X30,0X85,0X00,0X02,0X24,0X9A,0X24,0X89,0X00, 0X02,0X42,0X8E,0X12,0X85,0X00,0X02,0X2A,0X93,0X24,0XA4,0X00,0X02,0X67,0X48,0X30, 0X83,0X00,0X02,0XC3,0XB4,0X91,0X81,0X00,0X0F,0X02,0X02,0X01,0X03,0X04,0X07,0X07, 0X09,0X09,0X06,0X06,0X04,0X03,0X02,0X02,0X01,0X8D,0X00,0X02,0X26,0XA7,0X36,0X87, 0X00,0X02,0X2A,0XAE,0X2A,0X87,0X00,0X02,0X4B,0XA1,0X15,0X87,0X00,0X02,0X30,0XAB, 0X2A,0XA3,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X83,0X00,0X80, 0X01,0X80,0X04,0X80,0X03,0X02,0X02,0X00,0X02,0X8E,0X00,0X02,0X29,0XB6,0X3B,0X89, 0X00,0X02,0X2D,0XBD,0X2D,0X85,0X00,0X02,0X52,0XAE,0X16,0X89,0X00,0X02,0X34,0XBA, 0X2D,0XA2,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X83,0X00,0X01, 0X02,0X00,0X80,0X01,0X05,0X02,0X02,0X01,0X00,0X00,0X01,0X8E,0X00,0X02,0X29,0XB6, 0X3B,0X8B,0X00,0X02,0X2D,0XBD,0X2D,0X83,0X00,0X02,0X52,0XAE,0X16,0X8B,0X00,0X02, 0X34,0XBA,0X2D,0XA1,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X83, 0X00,0X00,0X01,0X84,0X00,0X00,0X01,0X8F,0X00,0X02,0X29,0XB6,0X3B,0X8D,0X00,0X02, 0X2D,0XBD,0X2D,0X81,0X00,0X02,0X52,0XAE,0X16,0X8D,0X00,0X02,0X34,0XBA,0X2D,0XA0, 0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9D,0X00,0X02,0X29,0XB6, 0X3B,0X8F,0X00,0X07,0X2D,0XBD,0X2D,0X00,0X00,0X52,0XAE,0X16,0X8F,0X00,0X02,0X34, 0XBA,0X2D,0X9F,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9D,0X00, 0X01,0X94,0X3B,0X91,0X00,0X05,0X2D,0X61,0X00,0X0F,0XA7,0X16,0X91,0X00,0X02,0X34, 0XAA,0X04,0X9E,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XB4,0X9B,0X75,0XCE,0X67, 0X00,0X69,0X9F,0X67,0X02,0X59,0X3F,0X30,0X83,0X00,0X02,0X8E,0X6C,0X55,0XAA,0X48, 0X04,0X47,0X46,0X46,0X47,0X47,0XBF,0X48,0X02,0X3F,0X30,0X30,0X83,0X00,0X02,0X69, 0X4D,0X37,0XA9,0X30,0X06,0X2F,0X2A,0X25,0X22,0X26,0X2B,0X2F,0XC1,0X30,0XFF,0X00, 0XFF,0X00,0XFF,0X00,0XA2,0X00,0X02,0X06,0X22,0X2F,0X81,0X4A,0X01,0X36,0X0C,0X83, 0X00,0X01,0X09,0X16,0X83,0X1B,0X82,0X00,0X8A,0X1B,0X83,0X00,0X80,0X4A,0X83,0X00, 0X16,0X06,0X0F,0X19,0X24,0X2E,0X38,0X43,0X4D,0X56,0X5C,0X5C,0X5F,0X63,0X68,0X6D, 0X73,0X78,0X7D,0X82,0X88,0X8D,0X92,0X96,0X81,0X99,0X00,0X46,0XA7,0X00,0X02,0X06, 0X2F,0X5F,0X84,0X66,0X00,0X26,0X82,0X00,0X02,0X12,0X41,0X5F,0X83,0X66,0X82,0X00, 0X8A,0X66,0X83,0X00,0X80,0X66,0X83,0X00,0X16,0X0A,0X19,0X2A,0X3C,0X4D,0X5D,0X6F, 0X80,0X8F,0X99,0X99,0X9E,0XA5,0XAD,0XB6,0XBF,0XC8,0XD0,0XD9,0XE2,0XEB,0XF3,0XFA, 0X80,0XFF,0X01,0XA7,0X05,0XA6,0X00,0X01,0X06,0X52,0X80,0X66,0X01,0X4A,0X37,0X80, 0X2F,0X01,0X3D,0X28,0X81,0X00,0X02,0X08,0X40,0X5D,0X84,0X66,0X82,0X00,0X8A,0X66, 0X83,0X00,0X80,0X66,0X83,0X00,0X1A,0X0A,0X19,0X2A,0X3C,0X4D,0X5D,0X6F,0X80,0X8F, 0X99,0X99,0X9E,0XA5,0XAD,0XB6,0XBF,0XC8,0XD0,0XD9,0XE2,0XEB,0XF3,0XFA,0XFF,0XFF, 0XA7,0X05,0XA7,0X00,0X04,0X44,0X66,0X66,0X44,0X06,0X88,0X00,0X04,0X16,0X5D,0X66, 0X60,0X06,0X8C,0X00,0X02,0X4A,0X66,0X66,0X91,0X00,0X19,0X0A,0X19,0X2A,0X3C,0X4D, 0X5D,0X6F,0X80,0X8F,0X99,0X99,0X9E,0XA5,0XAD,0XB6,0XBF,0XC8,0XD0,0XD9,0XE2,0XEB, 0XF3,0XFA,0XFF,0XA7,0X05,0XA7,0X00,0X03,0X0D,0X66,0X66,0X4A,0X8A,0X00,0X03,0X1A, 0X65,0X66,0X39,0X8D,0X00,0X02,0X4A,0X66,0X66,0X91,0X00,0X18,0X0A,0X19,0X2A,0X3C, 0X4D,0X5D,0X6F,0X80,0X8F,0X99,0X99,0X9E,0XA5,0XAD,0XB6,0XBF,0XC8,0XD0,0XD9,0XE2, 0XEB,0XF3,0XFA,0XA7,0X05,0XA8,0X00,0X03,0X2F,0X66,0X66,0X22,0X8A,0X00,0X03,0X1B, 0X66,0X66,0X2F,0X8D,0X00,0X02,0X4A,0X66,0X66,0X91,0X00,0X17,0X0A,0X19,0X2A,0X3C, 0X4D,0X5D,0X6F,0X80,0X8F,0X99,0X99,0X9E,0XA5,0XAD,0XB6,0XBF,0XC8,0XD0,0XD9,0XE2, 0XEB,0XF3,0XA4,0X05,0XA9,0X00,0X03,0X2F,0X66,0X66,0X1B,0X8A,0X00,0X03,0X1B,0X66, 0X66,0X2F,0X8D,0X00,0X02,0X4A,0X66,0X66,0X88,0X00,0X02,0X37,0X4A,0X4A,0X83,0X00, 0X16,0X02,0X05,0X08,0X0C,0X10,0X13,0X16,0X1A,0X1D,0X1F,0X1F,0X37,0XA5,0XAD,0XB6, 0XBF,0XC8,0XD0,0XD9,0XE2,0XEB,0X9F,0X05,0X98,0X00,0X01,0X03,0X09,0X8D,0X00,0X03, 0X28,0X66,0X66,0X3D,0X8A,0X00,0X03,0X1B,0X66,0X66,0X2F,0X8D,0X00,0X02,0X4A,0X66, 0X66,0X88,0X00,0X02,0X4A,0X66,0X66,0X8E,0X00,0X0A,0X1D,0XA5,0XAD,0XB6,0XBF,0XC8, 0XD0,0XD9,0XE2,0X9A,0X05,0X98,0X00,0X02,0X03,0X6C,0X1D,0X8D,0X00,0X00,0X0D,0X80, 0X66,0X00,0X2F,0X89,0X00,0X03,0X1B,0X66,0X66,0X2F,0X8D,0X00,0X02,0X4A,0X66,0X66, 0X88,0X00,0X02,0X4A,0X66,0X66,0X8E,0X00,0X09,0X1D,0XA5,0XAD,0XB6,0XBF,0XC8,0XD0, 0XD9,0X94,0X05,0X98,0X00,0X03,0X04,0X71,0XA5,0X1D,0X8E,0X00,0X00,0X37,0X80,0X66, 0X01,0X4A,0X1B,0X87,0X00,0X03,0X1B,0X66,0X66,0X2F,0X8D,0X00,0X02,0X4A,0X66,0X66, 0X88,0X00,0X02,0X4A,0X66,0X66,0X8E,0X00,0X08,0X1D,0XA5,0XAD,0XB6,0XBF,0XC8,0XD0, 0X8E,0X04,0X98,0X00,0X04,0X04,0X77,0XAD,0XA5,0X1D,0X8F,0X00,0X00,0X3D,0X81,0X66, 0X01,0X4A,0X1B,0X85,0X00,0X03,0X1B,0X66,0X66,0X59,0X83,0X4A,0X87,0X00,0X02,0X4A, 0X66,0X66,0X88,0X00,0X02,0X4A,0X66,0X66,0X8E,0X00,0X07,0X1D,0XA5,0XAD,0XB6,0XBF, 0XC8,0X88,0X04,0X98,0X00,0X05,0X04,0X7D,0XB6,0XAD,0XA5,0X1D,0X90,0X00,0X01,0X28, 0X5F,0X81,0X66,0X01,0X3D,0X06,0X83,0X00,0X00,0X1B,0X86,0X66,0X87,0X00,0X02,0X4A, 0X66,0X66,0X88,0X00,0X02,0X4A,0X66,0X66,0X8E,0X00,0X06,0X1D,0XA5,0XAD,0XB6,0XBF, 0X83,0X04,0X98,0X00,0X06,0X04,0X83,0XBF,0XB6,0XAD,0XA5,0X1D,0X91,0X00,0X02,0X06, 0X2F,0X5F,0X80,0X66,0X01,0X5F,0X13,0X82,0X00,0X03,0X1B,0X66,0X66,0X4A,0X83,0X2F, 0X87,0X00,0X02,0X4A,0X66,0X66,0X88,0X00,0X02,0X4A,0X66,0X66,0X8E,0X00,0X05,0X1D, 0XA5,0XAD,0XB6,0X7D,0X04,0X98,0X00,0X07,0X04,0X88,0XC8,0XBF,0XB6,0XAD,0XA5,0X1D, 0X93,0X00,0X06,0X06,0X2F,0X5F,0X66,0X66,0X5F,0X06,0X81,0X00,0X03,0X1B,0X66,0X66, 0X2F,0X8D,0X00,0X02,0X4A,0X66,0X66,0X88,0X00,0X02,0X4A,0X66,0X66,0X8E,0X00,0X04, 0X1D,0XA5,0XAD,0X77,0X04,0X98,0X00,0X08,0X04,0X8E,0XD0,0XC8,0XBF,0XB6,0XAD,0XA5, 0X1D,0X95,0X00,0X04,0X0D,0X52,0X66,0X66,0X3D,0X81,0X00,0X03,0X1B,0X66,0X66,0X2F, 0X8D,0X00,0X02,0X4A,0X66,0X66,0X88,0X00,0X02,0X4A,0X66,0X66,0X8E,0X00,0X03,0X1D, 0XA5,0X71,0X04,0X98,0X00,0X09,0X05,0X94,0XD9,0XD0,0XC8,0XBF,0XB6,0XAD,0XA5,0X1D, 0X96,0X00,0X03,0X0D,0X66,0X66,0X59,0X81,0X00,0X03,0X1B,0X66,0X66,0X2F,0X8D,0X00, 0X02,0X4A,0X66,0X66,0X88,0X00,0X02,0X4A,0X66,0X66,0X8E,0X00,0X02,0X1D,0X6C,0X03, 0X98,0X00,0X0A,0X05,0X9A,0XE2,0XD9,0XD0,0XC8,0XBF,0XB6,0XAD,0XA5,0X1D,0X97,0X00, 0X02,0X52,0X66,0X66,0X81,0X00,0X03,0X1B,0X66,0X66,0X2F,0X8D,0X00,0X02,0X4A,0X66, 0X66,0X88,0X00,0X02,0X4A,0X66,0X66,0X8E,0X00,0X01,0X09,0X03,0X98,0X00,0X16,0X05, 0X9F,0XEB,0XE2,0XD9,0XD0,0XC8,0XBF,0XB6,0XAD,0XA5,0X37,0X1F,0X1F,0X1D,0X1A,0X16, 0X13,0X10,0X0C,0X08,0X05,0X02,0X8C,0X00,0X02,0X4A,0X66,0X66,0X81,0X00,0X03,0X1B, 0X66,0X66,0X2F,0X8D,0X00,0X02,0X4A,0X66,0X66,0X88,0X00,0X02,0X4A,0X66,0X66,0XAA, 0X00,0X17,0X05,0XA4,0XF3,0XEB,0XE2,0XD9,0XD0,0XC8,0XBF,0XB6,0XAD,0XA5,0X9E,0X99, 0X99,0X8F,0X80,0X6F,0X5D,0X4D,0X3C,0X2A,0X19,0X0A,0X8B,0X00,0X03,0X06,0X66,0X66, 0X44,0X81,0X00,0X03,0X1B,0X66,0X66,0X2F,0X8D,0X00,0X02,0X4A,0X66,0X66,0X88,0X00, 0X02,0X4A,0X66,0X66,0XA9,0X00,0X18,0X05,0XA7,0XFA,0XF3,0XEB,0XE2,0XD9,0XD0,0XC8, 0XBF,0XB6,0XAD,0XA5,0X9E,0X99,0X99,0X8F,0X80,0X6F,0X5D,0X4D,0X3C,0X2A,0X19,0X0A, 0X8A,0X00,0X04,0X06,0X52,0X66,0X66,0X1B,0X81,0X00,0X03,0X1A,0X65,0X66,0X44,0X8D, 0X00,0X02,0X4A,0X66,0X66,0X88,0X00,0X02,0X4A,0X66,0X66,0XA8,0X00,0X19,0X05,0XA7, 0XFF,0XFA,0XF3,0XEB,0XE2,0XD9,0XD0,0XC8,0XBF,0XB6,0XAD,0XA5,0X9E,0X99,0X99,0X8F, 0X80,0X6F,0X5D,0X4D,0X3C,0X2A,0X19,0X0A,0X82,0X00,0X00,0X1B,0X81,0X00,0X06,0X13, 0X22,0X37,0X5F,0X66,0X66,0X36,0X82,0X00,0X04,0X11,0X5A,0X66,0X66,0X24,0X82,0X1B, 0X87,0X00,0X02,0X4A,0X66,0X66,0X88,0X00,0X02,0X4A,0X66,0X66,0XA7,0X00,0X1A,0X05, 0XA7,0XFF,0XFF,0XFA,0XF3,0XEB,0XE2,0XD9,0XD0,0XC8,0XBF,0XB6,0XAD,0XA5,0X9E,0X99, 0X99,0X8F,0X80,0X6F,0X5D,0X4D,0X3C,0X2A,0X19,0X0A,0X82,0X00,0X86,0X66,0X01,0X5F, 0X2F,0X83,0X00,0X02,0X04,0X3A,0X5A,0X84,0X66,0X87,0X00,0X02,0X4A,0X66,0X66,0X88, 0X00,0X02,0X4A,0X66,0X66,0XA6,0X00,0X01,0X05,0XA7,0X80,0XFF,0X16,0XFA,0XF3,0XEB, 0XE2,0XD9,0XD0,0XC8,0XBF,0XB6,0XAD,0XA5,0X9E,0X99,0X99,0X8F,0X80,0X6F,0X5D,0X4D, 0X3C,0X2A,0X19,0X0A,0X82,0X00,0X00,0X5F,0X83,0X66,0X02,0X52,0X2F,0X06,0X85,0X00, 0X02,0X10,0X40,0X5F,0X83,0X66,0X87,0X00,0X02,0X4A,0X66,0X66,0X88,0X00,0X02,0X4A, 0X66,0X66,0XA6,0X00,0X00,0X46,0X81,0X99,0X16,0X96,0X92,0X8D,0X88,0X82,0X7D,0X78, 0X73,0X6D,0X68,0X63,0X5F,0X5C,0X5C,0X56,0X4D,0X43,0X38,0X2E,0X24,0X19,0X0F,0X06, 0X83,0X00,0X00,0X13,0X80,0X1B,0X00,0X13,0XFF,0X00,0XFF,0X00,0XCF,0X00,0XFF,0X00, 0XFF,0X00,0XFC,0X00,0X02,0XE9,0XE2,0XCE,0XF1,0XC3,0X02,0XB4,0X8E,0X69,0X83,0X00, 0X02,0XE2,0XDD,0XC6,0XF1,0XB4,0X02,0X9B,0X6C,0X4D,0X83,0X00,0X02,0XCE,0XC6,0XA8, 0XF1,0X91,0X02,0X75,0X55,0X37,0X83,0X00,0X02,0XC3,0XB4,0X91,0XF1,0X00,0X02,0X67, 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XF1,0X00,0X02,0X67,0X48,0X30,0X83,0X00, 0X02,0XC3,0XB4,0X91,0XF1,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, 0XB4,0X00,0X01,0XFF,0XFF,0XB8,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4, 0X91,0XB2,0X00,0X00,0X2A,0X81,0XFF,0X00,0X2A,0XA9,0X00,0X00,0X02,0X89,0X00,0X02, 0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XB1,0X00,0X01,0X38,0XEE,0X81,0XFF, 0X01,0XEE,0X38,0XA8,0X00,0X03,0X04,0X07,0X04,0X03,0X86,0X00,0X02,0X67,0X48,0X30, 0X83,0X00,0X02,0XC3,0XB4,0X91,0X9C,0X00,0X80,0X01,0X8E,0X00,0X02,0X38,0XEE,0XF6, 0X81,0XFF,0X02,0XF6,0XEE,0X38,0XA5,0X00,0X05,0X02,0X12,0X1C,0X24,0X17,0X08,0X86, 0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9C,0X00,0X03,0X0B,0X25, 0X22,0X09,0X8C,0X00,0X03,0X38,0XED,0XF5,0XFC,0X81,0XFE,0X03,0XFC,0XF5,0XED,0X38, 0XA3,0X00,0X07,0X03,0X0D,0X3B,0X6B,0X7A,0X57,0X1F,0X05,0X85,0X00,0X02,0X67,0X48, 0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9B,0X00,0X05,0X05,0X33,0X93,0X8C,0X30,0X02, 0X8A,0X00,0X04,0X37,0XEB,0XF3,0XFA,0XF7,0X81,0XFC,0X04,0XF7,0XFA,0XF3,0XEB,0X37, 0XA2,0X00,0X08,0X07,0X23,0X6D,0XB7,0XC8,0X9B,0X43,0X0B,0X02,0X84,0X00,0X02,0X67, 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9B,0X00,0X05,0X05,0X4F,0XC1,0XB9,0X49, 0X05,0X89,0X00,0X05,0X37,0XE9,0XF1,0XF8,0XF5,0X7D,0X81,0XFA,0X05,0X7D,0XF5,0XF8, 0XF1,0XE9,0X37,0XA1,0X00,0X07,0X07,0X2B,0X82,0XCA,0XD9,0XB0,0X53,0X11,0X85,0X00, 0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9B,0X00,0X05,0X01,0X20,0X5A, 0X56,0X1A,0X03,0X88,0X00,0X06,0X36,0XE7,0XEE,0XF5,0XF2,0X7B,0X00,0X81,0XF7,0X06, 0X00,0X7B,0XF2,0XF5,0XEE,0XE7,0X36,0XA0,0X00,0X07,0X02,0X1D,0X60,0XA3,0XB5,0X89, 0X39,0X0A,0X85,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9C,0X00, 0X02,0X07,0X06,0X08,0X89,0X00,0X07,0X36,0XE5,0XEC,0XF3,0XF0,0X7A,0X00,0X00,0X81, 0XF5,0X07,0X00,0X00,0X7A,0XF0,0XF3,0XEC,0XE5,0X36,0X9F,0X00,0X07,0X01,0X0C,0X26, 0X4D,0X58,0X3D,0X15,0X02,0X85,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4, 0X91,0XAA,0X00,0X05,0X35,0XE2,0XE9,0XF0,0XED,0X79,0X80,0X00,0X81,0XF2,0X80,0X00, 0X05,0X79,0XED,0XF0,0XE9,0XE2,0X35,0X9F,0X00,0X05,0X01,0X06,0X10,0X12,0X0B,0X03, 0X86,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XA9,0X00,0X05,0X34, 0XDF,0XE7,0XED,0XEA,0X77,0X81,0X00,0X81,0XEF,0X81,0X00,0X05,0X77,0XEA,0XED,0XE7, 0XDF,0X34,0X9F,0X00,0X03,0X07,0X01,0X02,0X04,0X87,0X00,0X02,0X67,0X48,0X30,0X83, 0X00,0X02,0XC3,0XB4,0X91,0XA8,0X00,0X05,0X34,0XDD,0XE5,0XEB,0XE8,0X76,0X82,0X00, 0X81,0XED,0X82,0X00,0X05,0X76,0XE8,0XEB,0XE5,0XDD,0X34,0XAC,0X00,0X02,0X67,0X48, 0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XA7,0X00,0X05,0X33,0XDA,0XE2,0XE8,0XE5,0X75, 0X83,0X00,0X81,0XEA,0X83,0X00,0X05,0X75,0XE5,0XE8,0XE2,0XDA,0X33,0XAB,0X00,0X02, 0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XA6,0X00,0X05,0X33,0XD9,0XE0,0XE6, 0XE3,0X71,0X84,0X00,0X81,0XE8,0X84,0X00,0X05,0X71,0XE3,0XE6,0XE0,0XD9,0X33,0XAA, 0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X81,0X00,0X05,0X01,0X01, 0X07,0X04,0X04,0X01,0X9B,0X00,0X05,0X32,0XD6,0XDD,0XE3,0XE1,0X6F,0X85,0X00,0X81, 0XE5,0X85,0X00,0X05,0X6F,0XE1,0XE3,0XDD,0XD6,0X32,0XA9,0X00,0X02,0X67,0X48,0X30, 0X83,0X00,0X02,0XC3,0XB4,0X91,0X80,0X00,0X07,0X01,0X06,0X12,0X21,0X1E,0X11,0X04, 0X01,0X99,0X00,0X05,0X32,0XD3,0XDA,0XE0,0XDE,0X6E,0X86,0X00,0X81,0XE2,0X86,0X00, 0X05,0X6E,0XDE,0XE0,0XDA,0XD3,0X32,0XA8,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02, 0XC3,0XB4,0X91,0X80,0X00,0X07,0X04,0X15,0X3B,0X5A,0X55,0X32,0X10,0X02,0X98,0X00, 0X05,0X31,0XD1,0XD8,0XDE,0XDC,0X6D,0X87,0X00,0X81,0XE0,0X87,0X00,0X05,0X6D,0XDC, 0XDE,0XD8,0XD1,0X31,0XA7,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, 0X80,0X00,0X08,0X08,0X26,0X63,0X88,0X81,0X4F,0X1A,0X03,0X01,0X96,0X00,0X05,0X31, 0XCE,0XD5,0XDB,0XD9,0X6B,0X88,0X00,0X81,0XDD,0X88,0X00,0X05,0X6B,0XD9,0XDB,0XD5, 0XCE,0X31,0XA6,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X0D,0XC3,0XB4,0X91,0X00,0X00, 0X01,0X07,0X29,0X65,0X8B,0X83,0X51,0X1B,0X04,0X96,0X00,0X05,0X30,0XCB,0XD2,0XD8, 0XD6,0X6A,0X89,0X00,0X81,0XDA,0X89,0X00,0X05,0X6A,0XD6,0XD8,0XD2,0XCB,0X30,0XA5, 0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X80,0X00,0X07,0X04,0X1A, 0X43,0X61,0X59,0X33,0X10,0X04,0X95,0X00,0X05,0X2F,0XCA,0XD0,0XD6,0XD4,0X69,0X8A, 0X00,0X81,0XD8,0X8A,0X00,0X05,0X69,0XD4,0XD6,0XD0,0XCA,0X2F,0XA4,0X00,0X02,0X67, 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X80,0X00,0X07,0X01,0X08,0X18,0X25,0X22, 0X12,0X04,0X01,0X94,0X00,0X05,0X2F,0XC7,0XCD,0XD3,0XD1,0X68,0X8B,0X00,0X81,0XD5, 0X8B,0X00,0X05,0X68,0XD1,0XD3,0XCD,0XC7,0X2F,0XA3,0X00,0X02,0X67,0X48,0X30,0X83, 0X00,0X02,0XC3,0XB4,0X91,0X81,0X00,0X05,0X01,0X05,0X06,0X07,0X02,0X01,0X94,0X00, 0X05,0X2E,0XC5,0XCC,0XD1,0XCF,0X67,0X8C,0X00,0X81,0XD3,0X8C,0X00,0X05,0X67,0XCF, 0XD1,0XCC,0XC5,0X2E,0XA2,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, 0X82,0X00,0X00,0X01,0X97,0X00,0X05,0X2E,0XC3,0XCA,0XCF,0XCD,0X66,0X8D,0X00,0X81, 0XD1,0X8D,0X00,0X05,0X66,0XCD,0XCF,0XCA,0XC3,0X2E,0XA1,0X00,0X02,0X67,0X48,0X30, 0X83,0X00,0X02,0XC3,0XB4,0X91,0X89,0X00,0XD6,0XFF,0X8C,0X00,0X02,0X67,0X48,0X30, 0X83,0X00,0X02,0XC3,0XB4,0X91,0X89,0X00,0X00,0XFE,0XD4,0XFF,0X00,0XFE,0X8C,0X00, 0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X89,0X00,0X01,0XF6,0XFF,0XD2, 0XF6,0X01,0XFF,0XF6,0X8C,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, 0X89,0X00,0X02,0XE2,0XFC,0XEC,0XD0,0XEA,0X02,0XEC,0XFC,0XE2,0X8C,0X00,0X02,0X67, 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X89,0X00,0X02,0XC7,0XF8,0XE1,0XD0,0XDC, 0X02,0XE1,0XF8,0XC7,0X8C,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, 0X89,0X00,0X02,0XA6,0XF3,0XDB,0XD0,0XD0,0X02,0XDB,0XF3,0XA6,0X8C,0X00,0X02,0X67, 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X89,0X00,0X02,0X81,0XEE,0XD8,0XD0,0XC5, 0X02,0XD8,0XEE,0X81,0X8C,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, 0X89,0X00,0X02,0X58,0XE9,0XD7,0XD0,0XB9,0X02,0XD7,0XE9,0X58,0X8C,0X00,0X02,0X67, 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X89,0X00,0X03,0X2C,0XE0,0XD9,0XAE,0X81, 0XAD,0X00,0X97,0X84,0XAD,0X00,0X97,0X84,0XAD,0X00,0X97,0X84,0XAD,0X00,0X97,0X84, 0XAD,0X00,0X97,0X84,0XAD,0X00,0X97,0X84,0XAD,0X00,0X97,0X84,0XAD,0X00,0X97,0X84, 0XAD,0X00,0X97,0X84,0XAD,0X00,0X97,0X81,0XAD,0X03,0XAE,0XD9,0XE0,0X2C,0X8C,0X00, 0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8A,0X00,0X02,0XA8,0XDD,0XB4, 0X80,0XA7,0X02,0X94,0X63,0X94,0X82,0XA7,0X02,0X94,0X63,0X94,0X82,0XA7,0X02,0X94, 0X63,0X94,0X82,0XA7,0X02,0X94,0X63,0X94,0X82,0XA7,0X02,0X94,0X63,0X94,0X82,0XA7, 0X02,0X94,0X63,0X94,0X82,0XA7,0X02,0X94,0X63,0X94,0X82,0XA7,0X02,0X94,0X63,0X94, 0X82,0XA7,0X02,0X94,0X63,0X94,0X82,0XA7,0X02,0X94,0X63,0X94,0X80,0XA7,0X02,0XB4, 0XDD,0XA8,0X8D,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8A,0X00, 0X05,0X6F,0XD6,0XBC,0XA3,0XA3,0X93,0X80,0X61,0X00,0X93,0X80,0XA3,0X00,0X93,0X80, 0X61,0X00,0X93,0X80,0XA3,0X00,0X93,0X80,0X61,0X00,0X93,0X80,0XA3,0X00,0X93,0X80, 0X61,0X00,0X93,0X80,0XA3,0X00,0X93,0X80,0X61,0X00,0X93,0X80,0XA3,0X00,0X93,0X80, 0X61,0X00,0X93,0X80,0XA3,0X00,0X93,0X80,0X61,0X00,0X93,0X80,0XA3,0X00,0X93,0X80, 0X61,0X00,0X93,0X80,0XA3,0X00,0X93,0X80,0X61,0X00,0X93,0X80,0XA3,0X00,0X93,0X80, 0X61,0X05,0X93,0XA3,0XA3,0XBC,0XD6,0X6F,0X8D,0X00,0X02,0X67,0X48,0X30,0X83,0X00, 0X02,0XC3,0XB4,0X91,0X8A,0X00,0X56,0X36,0XCD,0XC2,0X9E,0X91,0X5F,0X5F,0X91,0X5F, 0X5F,0X91,0X9E,0X91,0X5F,0X5F,0X91,0X5F,0X5F,0X91,0X9E,0X91,0X5F,0X5F,0X91,0X5F, 0X5F,0X91,0X9E,0X91,0X5F,0X5F,0X91,0X5F,0X5F,0X91,0X9E,0X91,0X5F,0X5F,0X91,0X5F, 0X5F,0X91,0X9E,0X91,0X5F,0X5F,0X91,0X5F,0X5F,0X91,0X9E,0X91,0X5F,0X5F,0X91,0X5F, 0X5F,0X91,0X9E,0X91,0X5F,0X5F,0X91,0X5F,0X5F,0X91,0X9E,0X91,0X5F,0X5F,0X91,0X5F, 0X5F,0X91,0X9E,0X91,0X5F,0X5F,0X91,0X5F,0X5F,0X91,0X9E,0XC2,0XCD,0X36,0X8D,0X00, 0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8B,0X00,0X54,0X8C,0XC9,0X9B, 0X5D,0X5D,0X8F,0X9A,0X8F,0X5D,0X5D,0X8F,0X5D,0X5D,0X8F,0X9A,0X8F,0X5D,0X5D,0X8F, 0X5D,0X5D,0X8F,0X9A,0X8F,0X5D,0X5D,0X8F,0X5D,0X5D,0X8F,0X9A,0X8F,0X5D,0X5D,0X8F, 0X5D,0X5D,0X8F,0X9A,0X8F,0X5D,0X5D,0X8F,0X5D,0X5D,0X8F,0X9A,0X8F,0X5D,0X5D,0X8F, 0X5D,0X5D,0X8F,0X9A,0X8F,0X5D,0X5D,0X8F,0X5D,0X5D,0X8F,0X9A,0X8F,0X5D,0X5D,0X8F, 0X5D,0X5D,0X8F,0X9A,0X8F,0X5D,0X5D,0X8F,0X5D,0X5D,0X8F,0X9A,0X8F,0X5D,0X5D,0X9B, 0XC9,0X8C,0X8E,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8B,0X00, 0X08,0X4C,0XC2,0X93,0X5B,0X8D,0X95,0X91,0X95,0X8D,0X80,0X5B,0X04,0X8D,0X95,0X91, 0X95,0X8D,0X80,0X5B,0X04,0X8D,0X95,0X91,0X95,0X8D,0X80,0X5B,0X04,0X8D,0X95,0X91, 0X95,0X8D,0X80,0X5B,0X04,0X8D,0X95,0X91,0X95,0X8D,0X80,0X5B,0X04,0X8D,0X95,0X91, 0X95,0X8D,0X80,0X5B,0X04,0X8D,0X95,0X91,0X95,0X8D,0X80,0X5B,0X04,0X8D,0X95,0X91, 0X95,0X8D,0X80,0X5B,0X04,0X8D,0X95,0X91,0X95,0X8D,0X80,0X5B,0X08,0X8D,0X95,0X91, 0X95,0X8D,0X5B,0X93,0XC2,0X4C,0X8E,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3, 0XB4,0X91,0X8B,0X00,0X54,0X0F,0X8B,0XB8,0X93,0X91,0X8E,0X75,0X8E,0X91,0X8C,0X5A, 0X8C,0X91,0X8E,0X75,0X8E,0X91,0X8C,0X5A,0X8C,0X91,0X8E,0X75,0X8E,0X91,0X8C,0X5A, 0X8C,0X91,0X8E,0X75,0X8E,0X91,0X8C,0X5A,0X8C,0X91,0X8E,0X75,0X8E,0X91,0X8C,0X5A, 0X8C,0X91,0X8E,0X75,0X8E,0X91,0X8C,0X5A,0X8C,0X91,0X8E,0X75,0X8E,0X91,0X8C,0X5A, 0X8C,0X91,0X8E,0X75,0X8E,0X91,0X8C,0X5A,0X8C,0X91,0X8E,0X75,0X8E,0X91,0X8C,0X5A, 0X8C,0X91,0X8E,0X75,0X8E,0X91,0X9C,0XB8,0X8B,0X0F,0X8E,0X00,0X02,0X67,0X48,0X30, 0X83,0X00,0X02,0XC3,0XB4,0X91,0X8C,0X00,0X03,0X47,0XB4,0XA4,0X8B,0X80,0X72,0X00, 0X8B,0X80,0X8C,0X00,0X8B,0X80,0X72,0X00,0X8B,0X80,0X8C,0X00,0X8B,0X80,0X72,0X00, 0X8B,0X80,0X8C,0X00,0X8B,0X80,0X72,0X00,0X8B,0X80,0X8C,0X00,0X8B,0X80,0X72,0X00, 0X8B,0X80,0X8C,0X00,0X8B,0X80,0X72,0X00,0X8B,0X80,0X8C,0X00,0X8B,0X80,0X72,0X00, 0X8B,0X80,0X8C,0X00,0X8B,0X80,0X72,0X00,0X8B,0X80,0X8C,0X00,0X8B,0X80,0X72,0X00, 0X8B,0X80,0X8C,0X00,0X8B,0X80,0X72,0X03,0X8B,0XA4,0XB4,0X47,0X8F,0X00,0X02,0X67, 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8C,0X00,0X07,0X08,0X75,0XAC,0X81,0X6F, 0X88,0X6F,0X6F,0X80,0X88,0X04,0X6F,0X6F,0X88,0X6F,0X6F,0X80,0X88,0X04,0X6F,0X6F, 0X88,0X6F,0X6F,0X80,0X88,0X04,0X6F,0X6F,0X88,0X6F,0X6F,0X80,0X88,0X04,0X6F,0X6F, 0X88,0X6F,0X6F,0X80,0X88,0X04,0X6F,0X6F,0X88,0X6F,0X6F,0X80,0X88,0X04,0X6F,0X6F, 0X88,0X6F,0X6F,0X80,0X88,0X04,0X6F,0X6F,0X88,0X6F,0X6F,0X80,0X88,0X04,0X6F,0X6F, 0X88,0X6F,0X6F,0X80,0X88,0X07,0X6F,0X6F,0X88,0X6F,0X81,0XAC,0X75,0X08,0X8F,0X00, 0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8D,0X00,0X50,0X30,0X96,0X94, 0X87,0X83,0X85,0X6B,0X6B,0X85,0X6B,0X6B,0X85,0X83,0X85,0X6B,0X6B,0X85,0X6B,0X6B, 0X85,0X83,0X85,0X6B,0X6B,0X85,0X6B,0X6B,0X85,0X83,0X85,0X6B,0X6B,0X85,0X6B,0X6B, 0X85,0X83,0X85,0X6B,0X6B,0X85,0X6B,0X6B,0X85,0X83,0X85,0X6B,0X6B,0X85,0X6B,0X6B, 0X85,0X83,0X85,0X6B,0X6B,0X85,0X6B,0X6B,0X85,0X83,0X85,0X6B,0X6B,0X85,0X6B,0X6B, 0X85,0X83,0X85,0X6B,0X6B,0X85,0X6B,0X6B,0X85,0X83,0X87,0X94,0X96,0X30,0X90,0X00, 0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8E,0X00,0X05,0X4F,0XA2,0X90, 0X7E,0X7E,0X81,0X80,0X68,0X00,0X81,0X80,0X7E,0X00,0X81,0X80,0X68,0X00,0X81,0X80, 0X7E,0X00,0X81,0X80,0X68,0X00,0X81,0X80,0X7E,0X00,0X81,0X80,0X68,0X00,0X81,0X80, 0X7E,0X00,0X81,0X80,0X68,0X00,0X81,0X80,0X7E,0X00,0X81,0X80,0X68,0X00,0X81,0X80, 0X7E,0X00,0X81,0X80,0X68,0X00,0X81,0X80,0X7E,0X00,0X81,0X80,0X68,0X00,0X81,0X80, 0X7E,0X00,0X81,0X80,0X68,0X05,0X81,0X7E,0X7E,0X90,0XA2,0X4F,0X91,0X00,0X02,0X67, 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8E,0X00,0X08,0X0C,0X64,0X99,0X86,0X7A, 0X7A,0X7E,0X65,0X7E,0X82,0X7A,0X02,0X7E,0X65,0X7E,0X82,0X7A,0X02,0X7E,0X65,0X7E, 0X82,0X7A,0X02,0X7E,0X65,0X7E,0X82,0X7A,0X02,0X7E,0X65,0X7E,0X82,0X7A,0X02,0X7E, 0X65,0X7E,0X82,0X7A,0X02,0X7E,0X65,0X7E,0X82,0X7A,0X02,0X7E,0X65,0X7E,0X82,0X7A, 0X08,0X7E,0X65,0X7E,0X7A,0X7A,0X86,0X99,0X64,0X0C,0X91,0X00,0X02,0X67,0X48,0X30, 0X83,0X00,0X02,0XC3,0XB4,0X91,0X8F,0X00,0X03,0X1F,0X71,0X8E,0X7D,0XC2,0X75,0X03, 0X7D,0X8E,0X71,0X1F,0X92,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, 0X90,0X00,0X03,0X2B,0X77,0X86,0X75,0XC0,0X70,0X03,0X75,0X86,0X77,0X2B,0X93,0X00, 0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X91,0X00,0X03,0X30,0X76,0X7E, 0X6F,0XBE,0X6B,0X03,0X6F,0X7E,0X76,0X30,0X94,0X00,0X02,0X67,0X48,0X30,0X83,0X00, 0X02,0XC3,0XB4,0X91,0X92,0X00,0X03,0X30,0X6F,0X77,0X6A,0XBC,0X66,0X03,0X6A,0X77, 0X6F,0X30,0X95,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X93,0X00, 0X03,0X2A,0X64,0X71,0X66,0XBA,0X61,0X03,0X66,0X71,0X64,0X2A,0X96,0X00,0X02,0X67, 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X94,0X00,0X03,0X21,0X56,0X6D,0X62,0XB8, 0X5C,0X03,0X62,0X6D,0X56,0X21,0X97,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3, 0XB4,0X91,0X95,0X00,0X03,0X15,0X44,0X69,0X5F,0XB6,0X57,0X03,0X5F,0X69,0X44,0X15, 0X98,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X96,0X00,0X04,0X06, 0X30,0X5A,0X5D,0X54,0XB2,0X52,0X04,0X54,0X5D,0X5A,0X30,0X06,0X99,0X00,0X02,0X67, 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X98,0X00,0X03,0X1B,0X41,0X50,0X3F,0XB0, 0X35,0X03,0X3F,0X50,0X41,0X1B,0X9B,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3, 0XB4,0X91,0X99,0X00,0X04,0X06,0X27,0X47,0X46,0X3A,0XAC,0X35,0X09,0X3A,0X46,0X47, 0X27,0X06,0X00,0X01,0X00,0X00,0X01,0X97,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02, 0XC3,0XB4,0X91,0X9B,0X00,0X04,0X0E,0X2B,0X48,0X4E,0X49,0XA8,0X47,0X07,0X49,0X4E, 0X48,0X2B,0X0E,0X01,0X00,0X00,0X81,0X01,0X97,0X00,0X02,0X67,0X48,0X30,0X83,0X00, 0X02,0XC3,0XB4,0X91,0X9D,0X00,0X04,0X0E,0X28,0X42,0X4A,0X46,0XA4,0X44,0X11,0X46, 0X4A,0X42,0X28,0X0E,0X00,0X01,0X01,0X00,0X03,0X02,0X02,0X01,0X01,0X03,0X01,0X00, 0X01,0X93,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9F,0X00,0X04, 0X08,0X1E,0X35,0X46,0X46,0XA0,0X44,0X13,0X46,0X46,0X35,0X1E,0X08,0X01,0X00,0X00, 0X02,0X02,0X03,0X03,0X06,0X05,0X05,0X04,0X03,0X01,0X01,0X02,0X93,0X00,0X02,0X67, 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XA2,0X00,0X04,0X10,0X21,0X37,0X43,0X45, 0X9A,0X44,0X04,0X45,0X43,0X37,0X21,0X10,0X81,0X00,0X05,0X01,0X01,0X03,0X03,0X06, 0X08,0X80,0X09,0X06,0X07,0X05,0X03,0X02,0X01,0X02,0X01,0X91,0X00,0X02,0X67,0X48, 0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XA5,0X00,0X04,0X0B,0X1A,0X56,0X4B,0X45,0X94, 0X44,0X04,0X45,0X4B,0X56,0X1A,0X0B,0X83,0X00,0X10,0X01,0X02,0X03,0X06,0X09,0X0C, 0X0F,0X11,0X11,0X0F,0X0C,0X0B,0X06,0X04,0X01,0X00,0X01,0X91,0X00,0X02,0X67,0X48, 0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XA7,0X00,0X0A,0X77,0X77,0X5A,0X57,0X52,0X4E, 0X4B,0X48,0X47,0X45,0X45,0X82,0X44,0X0C,0X45,0X47,0X45,0X45,0X47,0X48,0X4B,0X4E, 0X52,0X57,0X5A,0X77,0X77,0X83,0X00,0X12,0X01,0X01,0X02,0X02,0X04,0X09,0X0E,0X13, 0X1D,0X21,0X22,0X1C,0X18,0X10,0X0B,0X08,0X03,0X02,0X01,0X91,0X00,0X02,0X67,0X48, 0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XA7,0X00,0X01,0X77,0X77,0X96,0X54,0X01,0X77, 0X77,0X84,0X00,0X11,0X01,0X03,0X03,0X08,0X0D,0X14,0X1F,0X36,0X47,0X51,0X40,0X2B, 0X19,0X0F,0X09,0X05,0X00,0X02,0X91,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3, 0XB4,0X91,0XA7,0X00,0X01,0X77,0X77,0X96,0X4D,0X01,0X77,0X77,0X85,0X00,0X11,0X02, 0X06,0X0A,0X12,0X1C,0X39,0X66,0X96,0XA3,0X83,0X4B,0X27,0X15,0X0E,0X09,0X03,0X01, 0X01,0X90,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XA7,0X00,0X01, 0X77,0X77,0X96,0X45,0X01,0X77,0X77,0X83,0X00,0X13,0X01,0X01,0X03,0X06,0X0C,0X14, 0X25,0X4A,0X97,0XD1,0XDD,0XBC,0X6E,0X34,0X1E,0X0F,0X09,0X05,0X02,0X02,0X90,0X00, 0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XA7,0X00,0X01,0X77,0X77,0X96, 0X3D,0X01,0X77,0X77,0X85,0X00,0X11,0X03,0X07,0X0E,0X18,0X29,0X56,0XA4,0XDD,0XE8, 0XCB,0X7B,0X38,0X1F,0X11,0X09,0X05,0X03,0X02,0X90,0X00,0X02,0X67,0X48,0X30,0X83, 0X00,0X02,0XC3,0XB4,0X91,0XA7,0X00,0X01,0X77,0X77,0X96,0X35,0X01,0X77,0X77,0X83, 0X00,0X13,0X02,0X02,0X03,0X06,0X0D,0X15,0X25,0X49,0X86,0XBE,0XCB,0XA9,0X66,0X32, 0X1A,0X12,0X09,0X04,0X03,0X01,0X90,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3, 0XB4,0X91,0XA7,0X00,0X9A,0X77,0X84,0X00,0X11,0X02,0X01,0X07,0X0B,0X14,0X1F,0X33, 0X52,0X74,0X7D,0X64,0X40,0X25,0X1A,0X0F,0X09,0X03,0X01,0X91,0X00,0X02,0X67,0X48, 0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X86,0X00,0X0E,0X01,0X00,0X00,0X01,0X00,0X02, 0X01,0X01,0X02,0X01,0X02,0X02,0X01,0X01,0X02,0X80,0X01,0X8C,0X00,0X9A,0X77,0X84, 0X00,0X12,0X01,0X02,0X04,0X09,0X0F,0X18,0X21,0X2E,0X3B,0X3E,0X36,0X2A,0X1D,0X14, 0X0C,0X07,0X03,0X00,0X02,0X90,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4, 0X91,0X84,0X00,0X03,0X01,0X01,0X00,0X03,0X80,0X02,0X04,0X01,0X00,0X00,0X01,0X02, 0X80,0X00,0X03,0X01,0X01,0X02,0X01,0X92,0X00,0X90,0X39,0X89,0X00,0X12,0X01,0X02, 0X03,0X06,0X0B,0X11,0X17,0X22,0X23,0X24,0X26,0X1B,0X14,0X0F,0X08,0X05,0X03,0X02, 0X01,0X90,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X83,0X00,0X10, 0X01,0X01,0X02,0X03,0X03,0X04,0X03,0X03,0X04,0X03,0X00,0X02,0X01,0X00,0X00,0X01, 0X01,0X95,0X00,0X90,0X39,0X88,0X00,0X11,0X01,0X02,0X01,0X02,0X05,0X07,0X0B,0X0F, 0X14,0X16,0X15,0X15,0X11,0X0E,0X09,0X06,0X03,0X02,0X92,0X00,0X02,0X67,0X48,0X30, 0X83,0X00,0X02,0XC3,0XB4,0X91,0X81,0X00,0X05,0X01,0X01,0X02,0X03,0X04,0X07,0X80, 0X08,0X03,0X07,0X05,0X04,0X02,0X80,0X01,0X80,0X00,0X00,0X01,0X94,0X00,0X83,0X39, 0X07,0X27,0X16,0X09,0X01,0X01,0X09,0X16,0X27,0X82,0X39,0X8A,0X00,0X0E,0X02,0X01, 0X01,0X04,0X06,0X08,0X0C,0X0D,0X0C,0X0C,0X09,0X07,0X04,0X04,0X03,0X93,0X00,0X02, 0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X81,0X00,0X0E,0X03,0X01,0X04,0X07, 0X0B,0X0D,0X0E,0X10,0X10,0X0D,0X0B,0X07,0X04,0X03,0X01,0X99,0X00,0X81,0X39,0X02, 0X34,0X1A,0X01,0X83,0X00,0X02,0X01,0X1A,0X34,0X80,0X39,0X8B,0X00,0X04,0X02,0X01, 0X03,0X04,0X05,0X80,0X06,0X05,0X07,0X06,0X03,0X03,0X01,0X01,0X86,0X00,0X00,0X01, 0X89,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X81,0X00,0X10,0X01, 0X04,0X07,0X0B,0X0F,0X16,0X18,0X1A,0X19,0X16,0X12,0X0E,0X08,0X05,0X03,0X00,0X01, 0X97,0X00,0X81,0X39,0X00,0X1A,0X87,0X00,0X00,0X1A,0X80,0X39,0X00,0X0D,0X8D,0X00, 0X01,0X02,0X02,0X83,0X03,0X00,0X02,0X87,0X00,0X05,0X01,0X05,0X06,0X07,0X04,0X01, 0X85,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X17,0XC3,0XB4,0X91,0X00,0X00,0X01,0X02, 0X02,0X05,0X08,0X10,0X16,0X1F,0X25,0X28,0X25,0X22,0X1B,0X14,0X0B,0X08,0X05,0X02, 0X01,0X96,0X00,0X00,0X0D,0X80,0X39,0X01,0X27,0X01,0X87,0X00,0X05,0X01,0X27,0X39, 0X39,0X35,0X0D,0X8C,0X00,0X0A,0X01,0X02,0X01,0X02,0X01,0X01,0X00,0X01,0X00,0X01, 0X01,0X84,0X00,0X07,0X01,0X03,0X0E,0X21,0X27,0X1A,0X09,0X02,0X84,0X00,0X02,0X67, 0X48,0X30,0X83,0X00,0X17,0XC3,0XB4,0X91,0X00,0X00,0X01,0X00,0X04,0X06,0X0D,0X16, 0X1F,0X29,0X33,0X37,0X34,0X2D,0X24,0X1A,0X10,0X09,0X06,0X03,0X01,0X95,0X00,0X01, 0X0E,0X3C,0X80,0X40,0X00,0X19,0X89,0X00,0X05,0X19,0X40,0X40,0X3E,0X3C,0X0E,0X8C, 0X00,0X01,0X01,0X01,0X81,0X00,0X01,0X02,0X01,0X86,0X00,0X08,0X01,0X0E,0X30,0X5B, 0X68,0X49,0X1B,0X05,0X03,0X83,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X16,0XC3,0XB4, 0X91,0X00,0X01,0X01,0X02,0X04,0X08,0X11,0X1A,0X28,0X3B,0X6F,0X8C,0X5A,0X39,0X2B, 0X20,0X14,0X0C,0X06,0X03,0X95,0X00,0X02,0X10,0X44,0X46,0X80,0X49,0X00,0X0B,0X89, 0X00,0X06,0X0B,0X49,0X49,0X48,0X46,0X44,0X10,0X8B,0X00,0X00,0X01,0X8D,0X00,0X08, 0X04,0X19,0X51,0X89,0X95,0X75,0X30,0X0A,0X01,0X83,0X00,0X02,0X67,0X48,0X30,0X83, 0X00,0X17,0XC3,0XB4,0X91,0X00,0X00,0X01,0X03,0X06,0X09,0X12,0X1D,0X2D,0X5D,0XC3, 0XE6,0X99,0X40,0X2F,0X23,0X17,0X0C,0X06,0X04,0X01,0X93,0X00,0X03,0X16,0X5A,0X58, 0X53,0X80,0X54,0X00,0X02,0X89,0X00,0X07,0X02,0X54,0X52,0X52,0X53,0X57,0X5A,0X16, 0X9B,0X00,0X08,0X04,0X1B,0X56,0X8D,0X99,0X7A,0X36,0X08,0X03,0X83,0X00,0X02,0X67, 0X48,0X30,0X83,0X00,0X03,0XC3,0XB4,0X91,0X00,0X80,0X01,0X10,0X05,0X0A,0X11,0X1B, 0X2A,0X5C,0XC1,0XE4,0X96,0X3F,0X30,0X22,0X16,0X0D,0X07,0X03,0X01,0X92,0X00,0X07, 0X1E,0X75,0X68,0X62,0X5F,0X5F,0X5E,0X5F,0X8B,0X12,0X81,0X5F,0X03,0X6A,0X6A,0X75, 0X1F,0X99,0X00,0X08,0X01,0X03,0X0F,0X39,0X66,0X72,0X53,0X20,0X07,0X84,0X00,0X02, 0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X81,0X00,0X10,0X04,0X08,0X10,0X1A, 0X25,0X3B,0X6C,0X89,0X57,0X38,0X2A,0X1F,0X13,0X0B,0X06,0X03,0X01,0X91,0X00,0X09, 0X26,0X8F,0X77,0X70,0X96,0X74,0X64,0X62,0X63,0X1E,0X8A,0X1D,0X08,0X67,0X64,0X64, 0X7C,0X94,0X70,0X75,0X8F,0X27,0X99,0X00,0X06,0X01,0X04,0X12,0X28,0X2F,0X20,0X0A, 0X85,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X16,0XC3,0XB4,0X91,0X00,0X00,0X01,0X02, 0X03,0X07,0X0C,0X13,0X1D,0X28,0X30,0X34,0X30,0X2C,0X23,0X18,0X11,0X09,0X05,0X01, 0X91,0X00,0X09,0X2F,0XA7,0X83,0X74,0X74,0X82,0XAD,0X7F,0X6D,0X6C,0X8B,0X2A,0X09, 0X6B,0X6D,0X8A,0XAA,0X7B,0X74,0X74,0X81,0XA7,0X30,0X9A,0X00,0X04,0X03,0X07,0X0A, 0X05,0X04,0X85,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X81,0X00, 0X0E,0X03,0X05,0X0A,0X10,0X16,0X1D,0X22,0X25,0X24,0X20,0X1A,0X13,0X0B,0X08,0X03, 0X91,0X00,0X0C,0X35,0XBB,0X91,0X80,0X7E,0X3F,0X40,0X8E,0XC1,0X8C,0X78,0X37,0X3B, 0X87,0X34,0X0C,0X41,0X41,0X75,0X99,0XBE,0X86,0X40,0X3F,0X7E,0X80,0X8E,0XBB,0X38, 0X9B,0X00,0X00,0X01,0X87,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, 0X81,0X00,0X10,0X02,0X03,0X05,0X09,0X0E,0X11,0X16,0X19,0X18,0X15,0X10,0X0C,0X07, 0X04,0X02,0X01,0X01,0X8E,0X00,0X0D,0X3E,0XCF,0X9F,0X8B,0X89,0X44,0X00,0X00,0X46, 0X9B,0XD5,0X99,0X83,0X1C,0X87,0X00,0X0D,0X1C,0X83,0XA8,0XD1,0X92,0X46,0X00,0X00, 0X44,0X89,0X8B,0X9C,0XCF,0X40,0XA5,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3, 0XB4,0X91,0X81,0X00,0X0E,0X01,0X01,0X04,0X05,0X07,0X0B,0X0D,0X0D,0X0E,0X0C,0X09, 0X07,0X05,0X03,0X02,0X8F,0X00,0X05,0X45,0XDF,0XAC,0X96,0X94,0X49,0X81,0X00,0X05, 0X4B,0XA7,0XE5,0XA5,0X8D,0X21,0X85,0X00,0X05,0X21,0X8D,0XB5,0XDF,0X9E,0X4B,0X81, 0X00,0X05,0X49,0X94,0X96,0XA9,0XDF,0X48,0XA4,0X00,0X02,0X67,0X48,0X30,0X83,0X00, 0X02,0XC3,0XB4,0X91,0X81,0X00,0X0F,0X02,0X02,0X01,0X03,0X04,0X07,0X07,0X09,0X09, 0X06,0X06,0X04,0X03,0X02,0X02,0X01,0X8D,0X00,0X05,0X4C,0XEC,0XB5,0X9F,0X9D,0X4E, 0X83,0X00,0X05,0X4E,0XB1,0XF1,0XAF,0X95,0X23,0X83,0X00,0X05,0X23,0X95,0XBF,0XEB, 0XA7,0X4E,0X83,0X00,0X05,0X4E,0X9D,0X9F,0XB2,0XEE,0X50,0XA3,0X00,0X02,0X67,0X48, 0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X83,0X00,0X80,0X01,0X80,0X04,0X80,0X03,0X02, 0X02,0X00,0X02,0X8E,0X00,0X05,0X51,0XF4,0XBC,0XA6,0XA4,0X51,0X85,0X00,0X05,0X51, 0XB8,0XF8,0XB6,0X9C,0X25,0X81,0X00,0X05,0X25,0X9C,0XC7,0XF2,0XAE,0X51,0X85,0X00, 0X05,0X51,0XA4,0XA6,0XB9,0XF6,0X55,0XA2,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02, 0XC3,0XB4,0X91,0X83,0X00,0X01,0X02,0X00,0X80,0X01,0X05,0X02,0X02,0X01,0X00,0X00, 0X01,0X8E,0X00,0X05,0X51,0XF4,0XBC,0XA6,0XA4,0X51,0X87,0X00,0X0D,0X51,0XB8,0XF8, 0XB6,0X9C,0X25,0X00,0X00,0X25,0X9C,0XC7,0XF2,0XAE,0X51,0X87,0X00,0X05,0X51,0XA4, 0XA6,0XB9,0XF6,0X55,0XA1,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, 0X83,0X00,0X00,0X01,0X84,0X00,0X00,0X01,0X8F,0X00,0X05,0X51,0XF4,0XBC,0XA6,0XA4, 0X51,0X89,0X00,0X0B,0X51,0XB8,0XF8,0XB6,0X9C,0X25,0X25,0X9C,0XC7,0XF2,0XAE,0X51, 0X89,0X00,0X05,0X51,0XA4,0XA6,0XB9,0XF6,0X55,0XA0,0X00,0X02,0X67,0X48,0X30,0X83, 0X00,0X02,0XC3,0XB4,0X91,0X9D,0X00,0X05,0X51,0XF4,0XBC,0XA6,0XA4,0X51,0X8B,0X00, 0X09,0X51,0XB8,0XF8,0XB6,0X9E,0X9E,0XC7,0XF2,0XAE,0X51,0X8B,0X00,0X05,0X51,0XA4, 0XA6,0XB9,0XF6,0X55,0X9F,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, 0X9C,0X00,0X05,0X25,0XE4,0XBC,0XA6,0XA4,0X51,0X8D,0X00,0X07,0X51,0XB8,0XD0,0XA6, 0XAD,0XEF,0XAE,0X51,0X8D,0X00,0X05,0X51,0XA4,0XA6,0XB9,0XEF,0X29,0X9E,0X00,0X02, 0X67,0X48,0X30,0X83,0X00,0X02,0XB4,0X9B,0X75,0XCE,0X67,0X00,0X6A,0X9F,0X67,0X02, 0X59,0X3F,0X30,0X83,0X00,0X02,0X8E,0X6C,0X55,0XAA,0X48,0X04,0X47,0X46,0X46,0X47, 0X47,0XBF,0X48,0X02,0X3F,0X30,0X30,0X83,0X00,0X02,0X69,0X4D,0X37,0XA9,0X30,0X06, 0X2F,0X2A,0X25,0X22,0X26,0X2B,0X2F,0XC1,0X30,0XFF,0X00,0XFF,0X00,0XFF,0X00,0XA2, 0X00,0X02,0X10,0X55,0X75,0X81,0XBA,0X01,0X88,0X1E,0X82,0X00,0X03,0X01,0X17,0X38, 0X43,0X82,0X44,0X82,0X00,0X8A,0X44,0X83,0X00,0X80,0XBA,0X83,0X00,0X08,0X0A,0X19, 0X2A,0X3C,0X4D,0X5D,0X6F,0X80,0X8F,0X8F,0X99,0X00,0X46,0XA7,0X00,0X02,0X10,0X75, 0XEE,0X84,0XFF,0X00,0X60,0X81,0X00,0X03,0X01,0X2E,0XA3,0XEF,0X83,0XFF,0X82,0X00, 0X8A,0XFF,0X83,0X00,0X80,0XFF,0X83,0X00,0X08,0X11,0X2A,0X46,0X64,0X80,0X9B,0XB9, 0XD5,0XEE,0X8E,0XFF,0X01,0XA7,0X05,0XA6,0X00,0X01,0X10,0XCE,0X80,0XFF,0X01,0XBA, 0X89,0X80,0X75,0X01,0X99,0X63,0X81,0X00,0X02,0X14,0X9F,0XE8,0X84,0XFF,0X82,0X00, 0X8A,0XFF,0X83,0X00,0X80,0XFF,0X83,0X00,0X08,0X11,0X2A,0X46,0X64,0X80,0X9B,0XB9, 0XD5,0XEE,0X8D,0XFF,0X01,0XA7,0X05,0XA7,0X00,0X04,0XAA,0XFF,0XFF,0XAA,0X10,0X88, 0X00,0X04,0X36,0XE8,0XFF,0XF0,0X10,0X8C,0X00,0X02,0XBA,0XFF,0XFF,0X91,0X00,0X08, 0X11,0X2A,0X46,0X64,0X80,0X9B,0XB9,0XD5,0XEE,0X8C,0XFF,0X01,0XA7,0X05,0XA7,0X00, 0X03,0X20,0XFF,0XFF,0XBA,0X8A,0X00,0X03,0X42,0XFD,0XFF,0X8E,0X8D,0X00,0X02,0XBA, 0XFF,0XFF,0X91,0X00,0X08,0X11,0X2A,0X46,0X64,0X80,0X9B,0XB9,0XD5,0XEE,0X8B,0XFF, 0X01,0XA7,0X05,0XA8,0X00,0X03,0X75,0XFF,0XFF,0X55,0X8A,0X00,0X03,0X44,0XFF,0XFF, 0X75,0X8D,0X00,0X02,0XBA,0XFF,0XFF,0X91,0X00,0X08,0X11,0X2A,0X46,0X64,0X80,0X9B, 0XB9,0XD5,0XEE,0X8A,0XFF,0X01,0XA7,0X05,0XA9,0X00,0X03,0X75,0XFF,0XFF,0X44,0X8A, 0X00,0X03,0X44,0XFF,0XFF,0X75,0X8D,0X00,0X02,0XBA,0XFF,0XFF,0X88,0X00,0X02,0X89, 0XBA,0XBA,0X83,0X00,0X0B,0X03,0X08,0X0E,0X14,0X1A,0X1F,0X25,0X2B,0X30,0X33,0X33, 0X58,0X86,0XFF,0X01,0XA7,0X05,0X98,0X00,0X01,0X05,0X0E,0X8D,0X00,0X03,0X65,0XFF, 0XFF,0X99,0X8A,0X00,0X03,0X44,0XFF,0XFF,0X75,0X8D,0X00,0X02,0XBA,0XFF,0XFF,0X88, 0X00,0X02,0XBA,0XFF,0XFF,0X8E,0X00,0X00,0X2E,0X85,0XFF,0X01,0XA7,0X05,0X98,0X00, 0X02,0X05,0XA7,0X2E,0X8D,0X00,0X00,0X20,0X80,0XFF,0X00,0X75,0X89,0X00,0X03,0X44, 0XFF,0XFF,0X75,0X8D,0X00,0X02,0XBA,0XFF,0XFF,0X88,0X00,0X02,0XBA,0XFF,0XFF,0X8E, 0X00,0X00,0X2E,0X84,0XFF,0X01,0XA7,0X05,0X98,0X00,0X03,0X05,0XA7,0XFF,0X2E,0X8E, 0X00,0X00,0X89,0X80,0XFF,0X01,0XBA,0X44,0X87,0X00,0X03,0X44,0XFF,0XFF,0X75,0X8D, 0X00,0X02,0XBA,0XFF,0XFF,0X88,0X00,0X02,0XBA,0XFF,0XFF,0X8E,0X00,0X00,0X2E,0X83, 0XFF,0X01,0XA7,0X05,0X98,0X00,0X04,0X05,0XA7,0XFF,0XFF,0X2E,0X8F,0X00,0X00,0X99, 0X81,0XFF,0X01,0XBA,0X44,0X85,0X00,0X03,0X44,0XFF,0XFF,0XDE,0X83,0XBA,0X87,0X00, 0X02,0XBA,0XFF,0XFF,0X88,0X00,0X02,0XBA,0XFF,0XFF,0X8E,0X00,0X00,0X2E,0X82,0XFF, 0X01,0XA7,0X05,0X98,0X00,0X01,0X05,0XA7,0X80,0XFF,0X00,0X2E,0X90,0X00,0X01,0X65, 0XEE,0X81,0XFF,0X01,0X99,0X10,0X83,0X00,0X00,0X44,0X86,0XFF,0X87,0X00,0X02,0XBA, 0XFF,0XFF,0X88,0X00,0X02,0XBA,0XFF,0XFF,0X8E,0X00,0X00,0X2E,0X81,0XFF,0X01,0XA7, 0X05,0X98,0X00,0X01,0X05,0XA7,0X81,0XFF,0X00,0X2E,0X91,0X00,0X02,0X10,0X75,0XEE, 0X80,0XFF,0X01,0XEE,0X30,0X82,0X00,0X03,0X44,0XFF,0XFF,0XBA,0X83,0X75,0X87,0X00, 0X02,0XBA,0XFF,0XFF,0X88,0X00,0X02,0XBA,0XFF,0XFF,0X8E,0X00,0X00,0X2E,0X80,0XFF, 0X01,0XA7,0X05,0X98,0X00,0X01,0X05,0XA7,0X82,0XFF,0X00,0X2E,0X93,0X00,0X06,0X10, 0X75,0XEE,0XFF,0XFF,0XEE,0X10,0X81,0X00,0X03,0X44,0XFF,0XFF,0X75,0X8D,0X00,0X02, 0XBA,0XFF,0XFF,0X88,0X00,0X02,0XBA,0XFF,0XFF,0X8E,0X00,0X04,0X2E,0XFF,0XFF,0XA7, 0X05,0X98,0X00,0X01,0X05,0XA7,0X83,0XFF,0X00,0X2E,0X95,0X00,0X04,0X20,0XCE,0XFF, 0XFF,0X99,0X81,0X00,0X03,0X44,0XFF,0XFF,0X75,0X8D,0X00,0X02,0XBA,0XFF,0XFF,0X88, 0X00,0X02,0XBA,0XFF,0XFF,0X8E,0X00,0X03,0X2E,0XFF,0XA7,0X05,0X98,0X00,0X01,0X05, 0XA7,0X84,0XFF,0X00,0X2E,0X96,0X00,0X03,0X20,0XFF,0XFF,0XDE,0X81,0X00,0X03,0X44, 0XFF,0XFF,0X75,0X8D,0X00,0X02,0XBA,0XFF,0XFF,0X88,0X00,0X02,0XBA,0XFF,0XFF,0X8E, 0X00,0X02,0X2E,0XA7,0X05,0X98,0X00,0X01,0X05,0XA7,0X85,0XFF,0X00,0X2E,0X97,0X00, 0X02,0XCE,0XFF,0XFF,0X81,0X00,0X03,0X44,0XFF,0XFF,0X75,0X8D,0X00,0X02,0XBA,0XFF, 0XFF,0X88,0X00,0X02,0XBA,0XFF,0XFF,0X8E,0X00,0X01,0X0E,0X05,0X98,0X00,0X01,0X05, 0XA7,0X86,0XFF,0X0B,0X58,0X33,0X33,0X30,0X2B,0X25,0X1F,0X1A,0X14,0X0E,0X08,0X03, 0X8C,0X00,0X02,0XBA,0XFF,0XFF,0X81,0X00,0X03,0X44,0XFF,0XFF,0X75,0X8D,0X00,0X02, 0XBA,0XFF,0XFF,0X88,0X00,0X02,0XBA,0XFF,0XFF,0XAA,0X00,0X01,0X05,0XA7,0X8A,0XFF, 0X08,0XEE,0XD5,0XB9,0X9B,0X80,0X64,0X46,0X2A,0X11,0X8B,0X00,0X03,0X10,0XFF,0XFF, 0XAA,0X81,0X00,0X03,0X44,0XFF,0XFF,0X75,0X8D,0X00,0X02,0XBA,0XFF,0XFF,0X88,0X00, 0X02,0XBA,0XFF,0XFF,0XA9,0X00,0X01,0X05,0XA7,0X8B,0XFF,0X08,0XEE,0XD5,0XB9,0X9B, 0X80,0X64,0X46,0X2A,0X11,0X8A,0X00,0X04,0X10,0XCE,0XFF,0XFF,0X44,0X81,0X00,0X03, 0X40,0XFC,0XFF,0XA9,0X8D,0X00,0X02,0XBA,0XFF,0XFF,0X88,0X00,0X02,0XBA,0XFF,0XFF, 0XA8,0X00,0X01,0X05,0XA7,0X8C,0XFF,0X08,0XEE,0XD5,0XB9,0X9B,0X80,0X64,0X46,0X2A, 0X11,0X82,0X00,0X00,0X44,0X81,0X00,0X06,0X30,0X55,0X89,0XEE,0XFF,0XFF,0X88,0X82, 0X00,0X04,0X2A,0XE2,0XFE,0XFF,0X5B,0X82,0X44,0X87,0X00,0X02,0XBA,0XFF,0XFF,0X88, 0X00,0X02,0XBA,0XFF,0XFF,0XA7,0X00,0X01,0X05,0XA7,0X8D,0XFF,0X08,0XEE,0XD5,0XB9, 0X9B,0X80,0X64,0X46,0X2A,0X11,0X82,0X00,0X86,0XFF,0X01,0XEE,0X75,0X83,0X00,0X02, 0X0A,0X91,0XE2,0X84,0XFF,0X87,0X00,0X02,0XBA,0XFF,0XFF,0X88,0X00,0X02,0XBA,0XFF, 0XFF,0XA6,0X00,0X01,0X05,0XA7,0X8E,0XFF,0X08,0XEE,0XD5,0XB9,0X9B,0X80,0X64,0X46, 0X2A,0X11,0X82,0X00,0X00,0XEE,0X83,0XFF,0X02,0XCE,0X75,0X10,0X84,0X00,0X04,0X01, 0X28,0X9F,0XEE,0XFE,0X82,0XFF,0X87,0X00,0X02,0XBA,0XFF,0XFF,0X88,0X00,0X02,0XBA, 0XFF,0XFF,0XA6,0X00,0X00,0X46,0X8F,0X99,0X08,0X8F,0X80,0X6F,0X5D,0X4D,0X3C,0X2A, 0X19,0X0A,0X83,0X00,0X00,0X30,0X80,0X44,0X00,0X30,0XFF,0X00,0XFF,0X00,0XCF,0X00, 0XFF,0X00,0XFF,0X00,0XFC,0X00,0X02,0XE9,0XE2,0XCE,0XF1,0XC3,0X02,0XB4,0X8E,0X69, 0X83,0X00,0X02,0XE2,0XDD,0XC6,0XF1,0XB4,0X02,0X9B,0X6C,0X4D,0X83,0X00,0X02,0XCE, 0XC6,0XA8,0XF1,0X91,0X02,0X75,0X55,0X37,0X83,0X00,0X0E,0XC3,0XB4,0X91,0XBF,0XB7, 0XAD,0XA3,0X9A,0X91,0X87,0X7E,0X74,0X6A,0X62,0X5A,0XCC,0X55,0X80,0X56,0X0F,0X58, 0X5A,0X5E,0X62,0X68,0X6F,0X76,0X7D,0X84,0X8B,0X91,0X97,0X9C,0X9F,0XA1,0XA2,0X82, 0XA3,0X03,0XA4,0X67,0X48,0X30,0X83,0X00,0X0E,0XC3,0XB4,0X91,0XBF,0XB7,0XAD,0XA3, 0X9A,0X91,0X87,0X7E,0X74,0X6A,0X62,0X5A,0XCB,0X55,0X12,0X56,0X55,0X57,0X58,0X5C, 0X60,0X65,0X6B,0X72,0X79,0X81,0X88,0X8E,0X93,0X98,0X9C,0X9F,0XA1,0XA2,0X83,0XA3, 0X03,0XA4,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XF1,0X00,0X02,0X67,0X48, 0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XB4,0X00,0X01,0XCC,0XCC,0XB8,0X00,0X02,0X67, 0X48,0X30,0X83,0X00,0X0E,0XC3,0XB4,0X91,0XBF,0XB7,0XAD,0XA3,0X9A,0X91,0X87,0X7E, 0X74,0X6A,0X62,0X5A,0XA6,0X55,0X00,0X69,0X81,0XCC,0X00,0X69,0X97,0X55,0X80,0X56, 0X11,0X58,0X5A,0X5D,0X61,0X67,0X6E,0X75,0X7D,0X85,0X8B,0X91,0X96,0X9A,0X9C,0X9E, 0XA1,0XA1,0XA2,0X85,0XA3,0X04,0XA4,0XA4,0X67,0X48,0X30,0X83,0X00,0X0E,0XC3,0XB4, 0X91,0XBF,0XB7,0XAD,0XA3,0X9A,0X91,0X87,0X7E,0X74,0X6A,0X62,0X5A,0XA5,0X55,0X01, 0X6F,0XC4,0X81,0XCC,0X01,0XC4,0X6F,0X95,0X55,0X16,0X56,0X56,0X57,0X59,0X5B,0X5F, 0X64,0X6A,0X71,0X79,0X80,0X87,0X8E,0X93,0X98,0X9B,0X9D,0X9F,0XA1,0XA2,0XA5,0XA3, 0XA4,0X85,0XA3,0X03,0XA4,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9C,0X00, 0X80,0X01,0X8E,0X00,0X02,0X2D,0XBE,0XC5,0X81,0XCC,0X02,0XC5,0XBE,0X2D,0XA5,0X00, 0X05,0X02,0X12,0X1C,0X24,0X17,0X08,0X86,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02, 0XC3,0XB4,0X91,0X9C,0X00,0X03,0X0B,0X25,0X22,0X09,0X8C,0X00,0X03,0X2C,0XBA,0XC0, 0XC5,0X81,0XC7,0X03,0XC5,0XC0,0XBA,0X2C,0XA3,0X00,0X07,0X03,0X0D,0X3B,0X6B,0X7A, 0X57,0X1F,0X05,0X85,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X0E,0XC3,0XB4,0X91,0XBF, 0XB7,0XAD,0XA3,0X9A,0X91,0X87,0X7E,0X74,0X6A,0X62,0X5A,0X8F,0X55,0X05,0X58,0X77, 0XB7,0XB2,0X75,0X56,0X8A,0X55,0X04,0X6C,0XB9,0XBC,0XBF,0XBE,0X81,0XC0,0X05,0XBE, 0XBF,0XBC,0XB9,0X6C,0X56,0X88,0X55,0X01,0X56,0X55,0X80,0X56,0X26,0X57,0X58,0X59, 0X5B,0X5E,0X62,0X67,0X6D,0X74,0X7C,0X83,0X8A,0X90,0X95,0X99,0X9C,0X9E,0XA0,0XA1, 0XA2,0XA5,0XB0,0XCA,0XE5,0XEB,0XDB,0XBA,0XA6,0XA2,0XA1,0XA1,0XA0,0X9F,0X9F,0X9E, 0X9D,0X67,0X48,0X30,0X83,0X00,0X0E,0XC3,0XB4,0X91,0XBF,0XB7,0XAD,0XA3,0X9A,0X91, 0X87,0X7E,0X74,0X6A,0X62,0X5A,0X8F,0X55,0X05,0X58,0X8A,0XD6,0XD0,0X86,0X58,0X89, 0X55,0X05,0X6B,0XB1,0XB5,0XB7,0XB6,0X86,0X81,0XB8,0X07,0X86,0XB6,0XB7,0XB5,0XB1, 0X6C,0X56,0X56,0X81,0X57,0X82,0X56,0X2B,0X57,0X56,0X57,0X58,0X58,0X5A,0X5C,0X5E, 0X62,0X66,0X6B,0X71,0X78,0X7F,0X86,0X8D,0X92,0X97,0X9B,0X9D,0X9F,0XA0,0XA1,0XA2, 0XA2,0XA6,0XB3,0XD2,0XEC,0XF1,0XE2,0XC0,0XA7,0XA0,0X9F,0X9E,0X9D,0X9C,0X9B,0X9A, 0X9A,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9B,0X00,0X05,0X01,0X20,0X5A, 0X56,0X1A,0X03,0X88,0X00,0X06,0X26,0XA2,0XA8,0XAD,0XAB,0X57,0X00,0X81,0XAE,0X06, 0X00,0X57,0XAB,0XAD,0XA8,0XA2,0X26,0XA0,0X00,0X07,0X02,0X1D,0X60,0XA3,0XB5,0X89, 0X39,0X0A,0X85,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9C,0X00, 0X02,0X07,0X06,0X08,0X89,0X00,0X07,0X24,0X99,0X9E,0XA3,0XA1,0X52,0X00,0X00,0X81, 0XA4,0X07,0X00,0X00,0X52,0XA1,0XA3,0X9E,0X99,0X24,0X9F,0X00,0X07,0X01,0X0C,0X26, 0X4D,0X58,0X3D,0X15,0X02,0X85,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X0E,0XC3,0XB4, 0X91,0XBF,0XB7,0XAD,0XA3,0X9A,0X91,0X87,0X7E,0X74,0X6A,0X62,0X5A,0X9E,0X55,0X05, 0X64,0X95,0X98,0X99,0X99,0X77,0X80,0X55,0X81,0X9A,0X0A,0X5D,0X5F,0X62,0X7F,0X99, 0X9A,0X98,0X97,0X75,0X6B,0X6B,0X83,0X6A,0X13,0X6B,0X6C,0X6D,0X70,0X72,0X76,0X79, 0X7E,0X83,0X88,0X8C,0X91,0X95,0X99,0X9C,0X9E,0XA0,0XA1,0XA2,0XA2,0X84,0XA3,0X10, 0XA5,0XA8,0XA8,0XA3,0X9E,0X9A,0X97,0X94,0X90,0X8E,0X8D,0X90,0X95,0X9D,0X67,0X48, 0X30,0X83,0X00,0X0E,0XC3,0XB4,0X91,0XBF,0XB7,0XAD,0XA3,0X9A,0X91,0X87,0X7E,0X74, 0X6A,0X62,0X5A,0X9D,0X55,0X09,0X62,0X8B,0X8D,0X8F,0X8E,0X72,0X55,0X56,0X56,0X57, 0X81,0X8F,0X09,0X64,0X68,0X6B,0X6F,0X80,0X8E,0X8F,0X8E,0X8D,0X7C,0X80,0X77,0X81, 0X76,0X12,0X77,0X78,0X7A,0X7C,0X7F,0X82,0X86,0X8A,0X8D,0X91,0X95,0X98,0X9B,0X9D, 0X9F,0XA0,0XA1,0XA2,0XA2,0X85,0XA3,0X10,0XA5,0XA1,0XA1,0XA0,0X9B,0X97,0X93,0X8E, 0X8B,0X8A,0X8B,0X90,0X9A,0XA3,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XA8, 0X00,0X05,0X1D,0X7C,0X80,0X84,0X82,0X42,0X82,0X00,0X81,0X85,0X82,0X00,0X05,0X42, 0X82,0X84,0X80,0X7C,0X1D,0XAC,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4, 0X91,0XA7,0X00,0X05,0X1B,0X73,0X77,0X7A,0X79,0X3D,0X83,0X00,0X81,0X7B,0X83,0X00, 0X05,0X3D,0X79,0X7A,0X77,0X73,0X1B,0XAB,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X0E, 0XC3,0XB4,0X91,0XBF,0XB7,0XAD,0XA3,0X9A,0X91,0X87,0X7E,0X74,0X6A,0X62,0X5A,0X9A, 0X55,0X0C,0X5B,0X70,0X71,0X72,0X71,0X63,0X55,0X56,0X57,0X58,0X5D,0X61,0X68,0X81, 0X72,0X0C,0X86,0X8B,0X8F,0X92,0X94,0X96,0X97,0X85,0X73,0X72,0X73,0X75,0X90,0X81, 0X97,0X0D,0X98,0X98,0X99,0X9A,0X9B,0X9C,0X9D,0X9E,0X9F,0XA0,0XA1,0XA1,0XA2,0XA2, 0X89,0XA3,0X11,0XA2,0XA1,0X9F,0X9C,0X98,0X92,0X8C,0X85,0X82,0X82,0X87,0X91,0X9E, 0XAB,0XB7,0X67,0X48,0X30,0X83,0X00,0X0E,0XC3,0XB4,0X91,0XBF,0XB7,0XAD,0XA3,0X9A, 0X91,0X89,0X7F,0X75,0X6A,0X62,0X5A,0X99,0X55,0X0D,0X59,0X67,0X67,0X68,0X68,0X5E, 0X55,0X55,0X56,0X58,0X5C,0X61,0X68,0X71,0X81,0X68,0X0D,0X91,0X94,0X97,0X99,0X9B, 0X9C,0X9C,0X9D,0X83,0X69,0X68,0X6A,0X6C,0X91,0X82,0X9D,0X06,0X9E,0X9E,0X9F,0XA0, 0XA0,0XA1,0XA1,0X80,0XA2,0X8B,0XA3,0X11,0XA2,0XA1,0X9F,0X9B,0X96,0X8F,0X88,0X82, 0X7F,0X81,0X88,0X93,0XA1,0XAF,0XBB,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, 0X80,0X00,0X07,0X01,0X06,0X12,0X21,0X1E,0X11,0X04,0X01,0X99,0X00,0X05,0X15,0X58, 0X5B,0X5D,0X5C,0X2E,0X86,0X00,0X81,0X5E,0X86,0X00,0X05,0X2E,0X5C,0X5D,0X5B,0X58, 0X15,0XA8,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X80,0X00,0X07, 0X04,0X15,0X3B,0X5A,0X55,0X32,0X10,0X02,0X98,0X00,0X05,0X12,0X4E,0X51,0X53,0X52, 0X29,0X87,0X00,0X81,0X54,0X87,0X00,0X05,0X29,0X52,0X53,0X51,0X4E,0X12,0XA7,0X00, 0X02,0X67,0X48,0X30,0X83,0X00,0X0E,0XC3,0XB4,0X91,0XBF,0XB7,0XAD,0XA4,0XA1,0XA7, 0XAD,0XA8,0X92,0X75,0X63,0X5B,0X96,0X55,0X01,0X52,0X4A,0X80,0X49,0X00,0X4F,0X81, 0X55,0X06,0X56,0X5A,0X60,0X69,0X74,0X7F,0X8A,0X81,0X49,0X04,0XA0,0XA1,0XA1,0XA2, 0XA2,0X83,0XA3,0X05,0X77,0X4B,0X4A,0X4C,0X4F,0X8F,0X8A,0XA3,0X84,0XA2,0X83,0XA3, 0X11,0XA2,0XA0,0X9D,0X97,0X90,0X88,0X80,0X7C,0X7B,0X82,0X8D,0X9A,0XA8,0XB5,0XBE, 0X67,0X48,0X30,0X83,0X00,0X0E,0XC3,0XB4,0X91,0XBF,0XB7,0XAD,0XA4,0XA1,0XA8,0XAE, 0XA9,0X93,0X76,0X64,0X5A,0X95,0X55,0X05,0X50,0X40,0X40,0X3F,0X3F,0X4A,0X81,0X55, 0X07,0X56,0X58,0X5C,0X63,0X6E,0X79,0X85,0X8F,0X81,0X3F,0X80,0XA2,0X86,0XA3,0X05, 0X72,0X41,0X40,0X43,0X46,0X8D,0X86,0XA3,0X81,0XA2,0X82,0XA1,0X81,0XA2,0X14,0XA3, 0XA3,0XA2,0XA2,0X9F,0X9C,0X96,0X8F,0X86,0X7F,0X7B,0X7B,0X82,0X8E,0X9B,0XA9,0XB6, 0XBF,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X80,0X00,0X07,0X04,0X1A,0X43, 0X61,0X59,0X33,0X10,0X04,0X95,0X00,0X05,0X0C,0X31,0X33,0X35,0X34,0X1A,0X8A,0X00, 0X81,0X35,0X8A,0X00,0X05,0X1A,0X34,0X35,0X33,0X31,0X0C,0XA4,0X00,0X02,0X67,0X48, 0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X80,0X00,0X07,0X01,0X08,0X18,0X25,0X22,0X12, 0X04,0X01,0X94,0X00,0X05,0X09,0X28,0X29,0X2B,0X2A,0X15,0X8B,0X00,0X81,0X2B,0X8B, 0X00,0X05,0X15,0X2A,0X2B,0X29,0X28,0X09,0XA3,0X00,0X02,0X67,0X48,0X30,0X83,0X00, 0X0E,0XC3,0XB4,0X91,0XBF,0XB7,0XAD,0XA3,0X9A,0X92,0X89,0X80,0X75,0X6A,0X62,0X5A, 0X92,0X55,0X05,0X4A,0X26,0X25,0X23,0X24,0X3D,0X82,0X55,0X09,0X56,0X56,0X58,0X5D, 0X64,0X6F,0X7C,0X87,0X92,0X99,0X81,0X23,0X8C,0XA3,0X10,0X65,0X26,0X24,0X28,0X2C, 0X87,0XA3,0XA3,0XA2,0XA2,0XA1,0X9F,0X9E,0X9C,0X9A,0X97,0X95,0X80,0X94,0X19,0X96, 0X98,0X9A,0X9C,0X9E,0XA0,0XA1,0XA1,0XA0,0X9D,0X99,0X92,0X8A,0X81,0X7A,0X78,0X7B, 0X84,0X91,0X9D,0XAA,0XB6,0XBF,0X67,0X48,0X30,0X83,0X00,0X0E,0XC3,0XB4,0X91,0XBF, 0XB7,0XAD,0XA3,0X9A,0X91,0X87,0X7E,0X74,0X6A,0X62,0X5A,0X91,0X55,0X05,0X48,0X20, 0X1E,0X1C,0X1D,0X39,0X84,0X55,0X08,0X56,0X5A,0X60,0X69,0X74,0X80,0X8B,0X95,0X9B, 0X81,0X1C,0X8D,0XA3,0X2C,0X61,0X1F,0X1D,0X21,0X25,0X85,0XA2,0XA2,0XA1,0X9F,0X9D, 0X9A,0X97,0X93,0X90,0X8D,0X8B,0X8A,0X8B,0X8D,0X90,0X94,0X97,0X9B,0X9D,0X9F,0X9F, 0X9E,0X9C,0X97,0X90,0X88,0X7F,0X78,0X77,0X7B,0X85,0X91,0X9E,0XAB,0XB6,0XBF,0X67, 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X89,0X00,0XD6,0XFF,0X8C,0X00,0X02,0X67, 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X89,0X00,0XD6,0X33,0X8C,0X00,0X02,0X67, 0X48,0X30,0X83,0X00,0X10,0XC3,0XB4,0X91,0XBF,0XB7,0XAD,0XA3,0X9A,0X91,0X87,0X7E, 0X74,0X6A,0X62,0X5A,0X34,0X33,0XD2,0X2E,0X13,0X33,0X36,0X90,0X8E,0X89,0X82,0X7B, 0X75,0X73,0X75,0X7D,0X88,0X94,0XA0,0XAC,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X11, 0XC3,0XB4,0X91,0XBF,0XB7,0XAD,0XA3,0X9A,0X91,0X87,0X7E,0X74,0X6A,0X62,0X5A,0X36, 0X32,0X27,0XD0,0X26,0X14,0X27,0X32,0X3B,0X86,0X85,0X80,0X7A,0X75,0X71,0X71,0X76, 0X7E,0X89,0X95,0XA0,0XAC,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, 0X89,0X00,0X02,0X27,0X31,0X22,0XD0,0X1E,0X02,0X22,0X31,0X27,0X8C,0X00,0X02,0X67, 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X89,0X00,0X02,0X21,0X30,0X1F,0XD0,0X17, 0X02,0X1F,0X30,0X21,0X8C,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X11,0XC3,0XB4,0X91, 0XBF,0XB7,0XAD,0XA3,0X9A,0X91,0X87,0X7E,0X74,0X6A,0X62,0X5A,0X40,0X2E,0X1D,0XD0, 0X0F,0X14,0X1D,0X2E,0X47,0X64,0X64,0X62,0X62,0X64,0X67,0X6F,0X78,0X82,0X8D,0X98, 0XA2,0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X11,0XC3,0XB4,0X91,0XBF,0XB7,0XAD, 0XA3,0X9A,0X91,0X87,0X7E,0X74,0X6A,0X62,0X5A,0X46,0X2D,0X1F,0XD0,0X07,0X14,0X1F, 0X2D,0X4A,0X5D,0X5D,0X5C,0X5D,0X62,0X67,0X6F,0X7A,0X83,0X8E,0X99,0XA2,0XAD,0XB7, 0XBF,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X89,0X00,0X02,0X08,0X2A,0X23, 0X82,0X01,0X00,0X00,0X84,0X01,0X00,0X00,0X84,0X01,0X00,0X00,0X84,0X01,0X00,0X00, 0X84,0X01,0X00,0X00,0X84,0X01,0X00,0X00,0X84,0X01,0X00,0X00,0X84,0X01,0X00,0X00, 0X84,0X01,0X00,0X00,0X84,0X01,0X00,0X00,0X82,0X01,0X02,0X23,0X2A,0X08,0X8C,0X00, 0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8A,0X00,0X02,0X20,0X2A,0X0A, 0XCE,0X00,0X02,0X0A,0X2A,0X20,0X8D,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X12,0XC3, 0XB4,0X91,0XBF,0XB7,0XAD,0XA3,0X9A,0X91,0X87,0X7E,0X74,0X6A,0X62,0X5A,0X55,0X3E, 0X28,0X13,0XCE,0X00,0X02,0X13,0X28,0X3E,0X81,0X55,0X0E,0X59,0X61,0X69,0X73,0X7D, 0X86,0X90,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X12,0XC3,0XB4,0X91, 0XBF,0XB7,0XAD,0XA3,0X9A,0X91,0X87,0X7E,0X74,0X6A,0X62,0X5A,0X55,0X49,0X26,0X1C, 0XCE,0X00,0X02,0X1C,0X26,0X49,0X81,0X55,0X0E,0X5A,0X62,0X69,0X73,0X7E,0X87,0X91, 0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8B,0X00, 0X02,0X19,0X24,0X06,0XCC,0X00,0X02,0X06,0X24,0X19,0X8E,0X00,0X02,0X67,0X48,0X30, 0X83,0X00,0X02,0XC3,0XB4,0X91,0X8B,0X00,0X02,0X0D,0X22,0X10,0XCC,0X00,0X02,0X10, 0X22,0X0D,0X8E,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X14,0XC3,0XB4,0X91,0XBF,0XB7, 0XAD,0XA3,0X9A,0X91,0X87,0X7E,0X74,0X6A,0X62,0X5A,0X55,0X55,0X51,0X2E,0X1D,0X04, 0XCA,0X00,0X03,0X08,0X1D,0X2E,0X51,0X82,0X55,0X0E,0X5A,0X62,0X6A,0X74,0X7E,0X87, 0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X0E,0XC3,0XB4,0X91,0XBF, 0XB7,0XAD,0XA3,0X9A,0X91,0X87,0X7E,0X74,0X6A,0X62,0X5A,0X80,0X55,0X02,0X40,0X1F, 0X13,0XCA,0X00,0X02,0X13,0X1F,0X40,0X83,0X55,0X0E,0X5A,0X62,0X6A,0X74,0X7E,0X87, 0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8C, 0X00,0X03,0X01,0X13,0X1C,0X08,0XC8,0X00,0X03,0X08,0X1C,0X13,0X01,0X8F,0X00,0X02, 0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8D,0X00,0X03,0X08,0X18,0X11,0X02, 0XC6,0X00,0X03,0X02,0X11,0X18,0X08,0X90,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X0E, 0XC3,0XB4,0X91,0XBF,0XB7,0XAD,0XA3,0X9A,0X91,0X87,0X7E,0X74,0X6A,0X62,0X5A,0X82, 0X55,0X02,0X39,0X1A,0X0D,0XC6,0X00,0X02,0X0D,0X1A,0X38,0X85,0X55,0X0E,0X5A,0X62, 0X6A,0X74,0X7E,0X87,0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X0E, 0XC3,0XB4,0X91,0XBF,0XB7,0XAD,0XA3,0X9A,0X91,0X87,0X7E,0X74,0X6A,0X62,0X5A,0X82, 0X55,0X03,0X52,0X30,0X16,0X09,0XC4,0X00,0X03,0X09,0X16,0X2E,0X50,0X85,0X55,0X0E, 0X5A,0X62,0X6A,0X74,0X7E,0X87,0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83, 0X00,0X02,0XC3,0XB4,0X91,0X8F,0X00,0X03,0X05,0X11,0X11,0X05,0XC2,0X00,0X03,0X05, 0X11,0X11,0X05,0X92,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X90, 0X00,0X03,0X06,0X11,0X0E,0X03,0XC0,0X00,0X03,0X03,0X0E,0X11,0X06,0X93,0X00,0X02, 0X67,0X48,0X30,0X83,0X00,0X0E,0XC3,0XB4,0X91,0XBD,0XB4,0XAA,0XA0,0X96,0X8E,0X85, 0X7D,0X73,0X69,0X61,0X59,0X80,0X55,0X08,0X56,0X58,0X5E,0X64,0X6E,0X55,0X22,0X0C, 0X03,0XBE,0X00,0X03,0X03,0X0C,0X1C,0X3E,0X88,0X55,0X0E,0X5A,0X62,0X6A,0X74,0X7E, 0X87,0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X1B,0XC3,0XB4,0X91, 0XB8,0XAF,0XA6,0X9B,0X94,0X8B,0X82,0X7A,0X71,0X68,0X61,0X59,0X56,0X55,0X56,0X58, 0X5C,0X62,0X6A,0X75,0X80,0X5E,0X23,0X0B,0X02,0XBC,0X00,0X03,0X02,0X0B,0X1A,0X3C, 0X89,0X55,0X0E,0X5A,0X62,0X6A,0X74,0X7E,0X87,0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67, 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X93,0X00,0X03,0X05,0X0C,0X0A,0X03,0XBA, 0X00,0X03,0X03,0X0A,0X0C,0X05,0X96,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3, 0XB4,0X91,0X94,0X00,0X03,0X04,0X0A,0X09,0X03,0XB8,0X00,0X03,0X03,0X09,0X0A,0X04, 0X97,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X1E,0XC3,0XB4,0X91,0XA1,0X9A,0X92,0X8C, 0X86,0X81,0X7B,0X76,0X70,0X69,0X64,0X5F,0X5D,0X5F,0X62,0X68,0X6F,0X78,0X82,0X8B, 0X93,0X99,0X9D,0XA0,0X85,0X44,0X09,0X04,0XB6,0X00,0X03,0X04,0X09,0X27,0X47,0X8C, 0X55,0X0E,0X5A,0X62,0X6A,0X74,0X7E,0X87,0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48, 0X30,0X83,0X00,0X20,0XC3,0XB4,0X91,0X9A,0X96,0X90,0X8B,0X87,0X83,0X7F,0X7A,0X75, 0X6E,0X6A,0X66,0X64,0X67,0X6B,0X72,0X79,0X82,0X8A,0X92,0X97,0X9C,0X9F,0XA1,0XA2, 0X9B,0X5B,0X1A,0X05,0X01,0XB2,0X00,0X04,0X01,0X05,0X11,0X31,0X51,0X8D,0X55,0X0E, 0X5A,0X62,0X6A,0X74,0X7E,0X87,0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83, 0X00,0X02,0XC3,0XB4,0X91,0X98,0X00,0X03,0X02,0X05,0X04,0X01,0XB0,0X00,0X03,0X01, 0X04,0X05,0X02,0X9B,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9A, 0X00,0X02,0X03,0X05,0X02,0XAE,0X00,0X08,0X02,0X05,0X03,0X00,0X00,0X01,0X00,0X00, 0X01,0X97,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X19,0XC3,0XB4,0X91,0X9D,0X9D,0X9B, 0X9B,0X9A,0X98,0X96,0X93,0X90,0X8D,0X8A,0X88,0X87,0X89,0X8C,0X90,0X94,0X98,0X9B, 0X9E,0XA0,0XA1,0XA2,0X84,0XA3,0X04,0X8A,0X53,0X18,0X02,0X01,0XA8,0X00,0X07,0X01, 0X02,0X0E,0X2D,0X48,0X56,0X55,0X55,0X81,0X56,0X8B,0X55,0X0E,0X5A,0X62,0X6A,0X74, 0X7E,0X87,0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X18,0XC3,0XB4, 0X91,0XA1,0XA0,0XA0,0X9F,0X9E,0X9D,0X9C,0X9A,0X98,0X96,0X93,0X92,0X92,0X93,0X95, 0X97,0X9A,0X9C,0X9E,0XA0,0XA1,0XA2,0X87,0XA3,0X04,0X87,0X54,0X1C,0X02,0X01,0XA4, 0X00,0X09,0X01,0X02,0X10,0X2C,0X47,0X55,0X56,0X56,0X55,0X57,0X81,0X56,0X03,0X57, 0X56,0X55,0X56,0X87,0X55,0X0E,0X5A,0X62,0X6A,0X74,0X7E,0X87,0X91,0X9A,0XA3,0XAD, 0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XA0,0X00,0X81,0X01,0XA0, 0X00,0X81,0X01,0X0F,0X00,0X01,0X00,0X00,0X02,0X02,0X03,0X03,0X06,0X05,0X05,0X04, 0X03,0X01,0X01,0X02,0X93,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, 0XA4,0X00,0X01,0X01,0X01,0X9C,0X00,0X01,0X01,0X01,0X83,0X00,0X05,0X01,0X01,0X03, 0X03,0X06,0X08,0X80,0X09,0X06,0X07,0X05,0X03,0X02,0X01,0X02,0X01,0X91,0X00,0X02, 0X67,0X48,0X30,0X83,0X00,0X04,0XC3,0XB4,0X91,0XA4,0XA4,0X81,0XA3,0X80,0XA2,0X80, 0XA1,0X00,0XA0,0X80,0XA1,0X80,0XA2,0X92,0XA3,0X01,0X88,0X66,0X9A,0X00,0X01,0X35, 0X47,0X83,0X55,0X10,0X56,0X56,0X57,0X59,0X5B,0X5D,0X5F,0X60,0X60,0X5F,0X5D,0X5C, 0X59,0X58,0X56,0X55,0X56,0X85,0X55,0X0E,0X5A,0X62,0X6A,0X74,0X7E,0X87,0X91,0X9A, 0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X03,0XC3,0XB4,0X91,0XA4,0X86,0XA3, 0X83,0XA2,0X97,0XA3,0X82,0X00,0X01,0X01,0X01,0X8C,0X00,0X01,0X01,0X01,0X82,0X00, 0X83,0X55,0X81,0X56,0X0E,0X58,0X5B,0X5E,0X62,0X68,0X6B,0X6C,0X68,0X65,0X60,0X5C, 0X5A,0X57,0X56,0X56,0X85,0X55,0X0E,0X5A,0X62,0X6A,0X74,0X7E,0X87,0X91,0X9A,0XA3, 0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XCB,0X00,0X11,0X01, 0X03,0X03,0X08,0X0D,0X14,0X1F,0X36,0X47,0X51,0X40,0X2B,0X19,0X0F,0X09,0X05,0X00, 0X02,0X91,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XCC,0X00,0X11, 0X02,0X06,0X0A,0X12,0X1C,0X39,0X66,0X96,0XA3,0X83,0X4B,0X27,0X15,0X0E,0X09,0X03, 0X01,0X01,0X90,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9F,0XA3, 0X80,0XA2,0X01,0XA1,0XA1,0X80,0XA0,0X9A,0X00,0X83,0X55,0X13,0X56,0X56,0X57,0X59, 0X5D,0X62,0X6E,0X86,0XBA,0XE0,0XE8,0XD2,0X9E,0X78,0X69,0X5F,0X5B,0X58,0X56,0X56, 0X84,0X55,0X0E,0X5A,0X62,0X6A,0X74,0X7E,0X87,0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67, 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9C,0XA3,0X80,0XA2,0X07,0XA1,0XA0,0XA0, 0X9F,0X9E,0X9E,0X9D,0X9D,0X9A,0X00,0X85,0X55,0X11,0X57,0X5A,0X5E,0X65,0X70,0X8E, 0XC2,0XE8,0XF0,0XDC,0XA7,0X7A,0X6A,0X60,0X5B,0X58,0X57,0X56,0X84,0X55,0X0E,0X5A, 0X62,0X6A,0X74,0X7E,0X87,0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00, 0X02,0XC3,0XB4,0X91,0XCA,0X00,0X13,0X02,0X02,0X03,0X06,0X0D,0X15,0X25,0X49,0X86, 0XBE,0XCB,0XA9,0X66,0X32,0X1A,0X12,0X09,0X04,0X03,0X01,0X90,0X00,0X02,0X67,0X48, 0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XCB,0X00,0X11,0X02,0X01,0X07,0X0B,0X14,0X1F, 0X33,0X52,0X74,0X7D,0X64,0X40,0X25,0X1A,0X0F,0X09,0X03,0X01,0X91,0X00,0X02,0X67, 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8B,0XA3,0X1B,0XA4,0XA3,0XA3,0XA4,0XA3, 0XA4,0XA4,0XA3,0XA3,0XA4,0XA3,0XA3,0XA2,0XA2,0XA1,0XA0,0X9E,0X9D,0X9B,0X98,0X95, 0X92,0X8F,0X8B,0X89,0X86,0X85,0X83,0X9A,0X00,0X84,0X55,0X12,0X56,0X56,0X58,0X5B, 0X5F,0X65,0X6B,0X74,0X7C,0X7E,0X79,0X71,0X68,0X62,0X5D,0X5A,0X57,0X55,0X56,0X84, 0X55,0X0E,0X5A,0X62,0X6A,0X74,0X7E,0X87,0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48, 0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X87,0XA3,0X81,0XA4,0X81,0XA3,0X00,0XA4,0X82, 0XA3,0X11,0XA4,0XA2,0XA2,0XA1,0X9F,0X9D,0X9B,0X98,0X95,0X91,0X8D,0X88,0X84,0X80, 0X7D,0X7A,0X78,0X77,0X80,0X76,0X01,0X75,0X74,0X90,0X00,0X89,0X55,0X12,0X56,0X56, 0X57,0X59,0X5C,0X60,0X64,0X6C,0X6C,0X6D,0X6E,0X67,0X62,0X5F,0X5A,0X58,0X57,0X56, 0X56,0X84,0X55,0X0E,0X5A,0X62,0X6A,0X74,0X7E,0X87,0X91,0X9A,0XA3,0XAD,0XB7,0XBF, 0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X83,0X00,0X10,0X01,0X01,0X02,0X03, 0X03,0X04,0X03,0X03,0X04,0X03,0X00,0X02,0X01,0X00,0X00,0X01,0X01,0XB3,0X00,0X11, 0X01,0X02,0X01,0X02,0X05,0X07,0X0B,0X0F,0X14,0X16,0X15,0X15,0X11,0X0E,0X09,0X06, 0X03,0X02,0X92,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X81,0X00, 0X05,0X01,0X01,0X02,0X03,0X04,0X07,0X80,0X08,0X03,0X07,0X05,0X04,0X02,0X80,0X01, 0X80,0X00,0X00,0X01,0XB4,0X00,0X0E,0X02,0X01,0X01,0X04,0X06,0X08,0X0C,0X0D,0X0C, 0X0C,0X09,0X07,0X04,0X04,0X03,0X93,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3, 0XB4,0X91,0X81,0XA3,0X0D,0XA4,0XA3,0XA4,0XA6,0XA7,0XA8,0XA8,0XA9,0XA9,0XA8,0XA7, 0XA6,0XA4,0XA4,0X82,0XA3,0X14,0XA2,0XA1,0X9F,0X9D,0X99,0X94,0X8D,0X86,0X7F,0X78, 0X71,0X6B,0X66,0X62,0X5F,0X5D,0X5C,0X5B,0X5A,0X59,0X5A,0X80,0X59,0X90,0X00,0X8B, 0X55,0X04,0X56,0X56,0X57,0X58,0X58,0X80,0X59,0X05,0X5A,0X59,0X57,0X57,0X56,0X56, 0X87,0X55,0X0E,0X5A,0X62,0X6A,0X74,0X7E,0X87,0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67, 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X82,0XA3,0X04,0XA4,0XA6,0XA7,0XA8,0XAB, 0X80,0XAC,0X05,0XAB,0XA9,0XA8,0XA6,0XA5,0XA4,0X80,0XA3,0X10,0XA2,0XA2,0XA0,0X9E, 0X9A,0X95,0X8E,0X86,0X7D,0X75,0X6D,0X67,0X61,0X5E,0X5B,0X59,0X58,0X80,0X57,0X82, 0X56,0X90,0X00,0X00,0X42,0X8D,0X55,0X01,0X56,0X56,0X83,0X57,0X00,0X56,0X88,0X55, 0X0F,0X58,0X5D,0X65,0X6C,0X75,0X7E,0X87,0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48, 0X30,0X83,0X00,0X17,0XC3,0XB4,0X91,0X00,0X00,0X01,0X02,0X02,0X05,0X08,0X10,0X16, 0X1F,0X25,0X28,0X25,0X22,0X1B,0X14,0X0B,0X08,0X05,0X02,0X01,0XBB,0X00,0X0A,0X01, 0X02,0X01,0X02,0X01,0X01,0X00,0X01,0X00,0X01,0X01,0X84,0X00,0X07,0X01,0X03,0X0E, 0X21,0X27,0X1A,0X09,0X02,0X84,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X17,0XC3,0XB4, 0X91,0X00,0X00,0X01,0X00,0X04,0X06,0X0D,0X16,0X1F,0X29,0X33,0X37,0X34,0X2D,0X24, 0X1A,0X10,0X09,0X06,0X03,0X01,0XBC,0X00,0X01,0X01,0X01,0X81,0X00,0X01,0X02,0X01, 0X86,0X00,0X08,0X01,0X0E,0X30,0X5B,0X68,0X49,0X1B,0X05,0X03,0X83,0X00,0X02,0X67, 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X80,0XA3,0X1F,0XA4,0XA4,0XA6,0XA9,0XAC, 0XB1,0XB8,0XCB,0XD6,0XC3,0XB8,0XB3,0XAF,0XAA,0XA7,0XA5,0XA4,0XA3,0XA2,0XA1,0X9E, 0X9B,0X95,0X8D,0X83,0X78,0X6D,0X64,0X5D,0X59,0X57,0X56,0X86,0X55,0X02,0X42,0X06, 0X03,0X91,0X00,0X02,0X03,0X06,0X42,0X8B,0X55,0X00,0X56,0X8D,0X55,0X11,0X57,0X63, 0X81,0XA1,0XA9,0X9D,0X86,0X81,0X87,0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30, 0X83,0X00,0X02,0XC3,0XB4,0X91,0X80,0XA3,0X1F,0XA4,0XA5,0XA6,0XA9,0XAD,0XB3,0XC5, 0XE9,0XF6,0XDA,0XBA,0XB4,0XB0,0XAB,0XA7,0XA5,0XA4,0XA2,0XA2,0XA0,0X9D,0X98,0X91, 0X87,0X7C,0X71,0X67,0X5F,0X5A,0X57,0X55,0X56,0X85,0X55,0X02,0X42,0X09,0X01,0X93, 0X00,0X02,0X01,0X09,0X42,0X9B,0X55,0X11,0X57,0X64,0X84,0XA3,0XAB,0X9F,0X89,0X81, 0X88,0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X03,0XC3,0XB4,0X91, 0X00,0X80,0X01,0X10,0X05,0X0A,0X11,0X1B,0X2A,0X5C,0XC1,0XE4,0X96,0X3F,0X30,0X22, 0X16,0X0D,0X07,0X03,0X01,0X92,0X00,0X03,0X02,0X09,0X03,0X01,0X93,0X00,0X03,0X04, 0X04,0X09,0X02,0X99,0X00,0X08,0X01,0X03,0X0F,0X39,0X66,0X72,0X53,0X20,0X07,0X84, 0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X81,0X00,0X10,0X04,0X08, 0X10,0X1A,0X25,0X3B,0X6C,0X89,0X57,0X38,0X2A,0X1F,0X13,0X0B,0X06,0X03,0X01,0X91, 0X00,0X05,0X03,0X0E,0X05,0X02,0X0F,0X04,0X91,0X00,0X05,0X06,0X0E,0X02,0X04,0X0E, 0X04,0X99,0X00,0X06,0X01,0X04,0X12,0X28,0X2F,0X20,0X0A,0X85,0X00,0X02,0X67,0X48, 0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X80,0XA3,0X1C,0XA4,0XA4,0XA6,0XA7,0XAA,0XAD, 0XB1,0XB4,0XB6,0XB4,0XB3,0XB0,0XAC,0XA9,0XA6,0XA5,0XA2,0XA1,0X9F,0X9C,0X96,0X8E, 0X83,0X77,0X6B,0X61,0X5B,0X57,0X56,0X85,0X55,0X07,0X41,0X18,0X09,0X00,0X00,0X05, 0X15,0X05,0X8F,0X00,0X07,0X09,0X14,0X02,0X00,0X00,0X08,0X18,0X41,0X9A,0X55,0X0F, 0X57,0X5E,0X67,0X6C,0X75,0X7E,0X87,0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30, 0X83,0X00,0X02,0XC3,0XB4,0X91,0X81,0XA3,0X1A,0XA4,0XA5,0XA7,0XA9,0XAB,0XAD,0XAF, 0XB0,0XB0,0XAF,0XAC,0XAA,0XA7,0XA6,0XA4,0XA2,0XA1,0X9E,0X9A,0X93,0X8A,0X7E,0X72, 0X67,0X5E,0X59,0X56,0X85,0X55,0X02,0X40,0X1C,0X0B,0X81,0X00,0X02,0X06,0X1A,0X06, 0X8D,0X00,0X02,0X0B,0X19,0X03,0X81,0X00,0X02,0X0A,0X1C,0X40,0X9A,0X55,0X0E,0X5A, 0X63,0X6A,0X74,0X7E,0X87,0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00, 0X02,0XC3,0XB4,0X91,0X81,0X00,0X10,0X02,0X03,0X05,0X09,0X0E,0X11,0X16,0X19,0X18, 0X15,0X10,0X0C,0X07,0X04,0X02,0X01,0X01,0X8E,0X00,0X02,0X07,0X1F,0X0A,0X83,0X00, 0X02,0X08,0X20,0X08,0X8B,0X00,0X02,0X0E,0X1F,0X04,0X83,0X00,0X02,0X09,0X1F,0X08, 0XA5,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X81,0X00,0X0E,0X01, 0X01,0X04,0X05,0X07,0X0B,0X0D,0X0D,0X0E,0X0C,0X09,0X07,0X05,0X03,0X02,0X8F,0X00, 0X02,0X08,0X25,0X0C,0X85,0X00,0X02,0X09,0X26,0X09,0X89,0X00,0X02,0X11,0X23,0X05, 0X85,0X00,0X02,0X0B,0X25,0X09,0XA4,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3, 0XB4,0X91,0X81,0XA3,0X04,0XA4,0XA4,0XA3,0XA4,0XA4,0X81,0XA6,0X01,0XA5,0XA5,0X80, 0XA4,0X0C,0XA3,0XA1,0X9E,0X9A,0X93,0X89,0X7E,0X71,0X66,0X5D,0X59,0X56,0X56,0X82, 0X55,0X02,0X3F,0X2B,0X10,0X87,0X00,0X02,0X0A,0X2B,0X0A,0X87,0X00,0X02,0X13,0X28, 0X05,0X87,0X00,0X02,0X0E,0X2C,0X3F,0X97,0X55,0X0E,0X5A,0X62,0X6A,0X74,0X7E,0X87, 0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X86, 0XA3,0X84,0XA4,0X0C,0XA3,0XA4,0XA2,0XA0,0X9D,0X98,0X90,0X86,0X79,0X6D,0X63,0X5C, 0X57,0X83,0X55,0X02,0X3F,0X2E,0X11,0X89,0X00,0X02,0X0B,0X2F,0X0B,0X85,0X00,0X02, 0X14,0X2C,0X06,0X89,0X00,0X02,0X0F,0X2F,0X3F,0X96,0X55,0X0E,0X5A,0X62,0X6A,0X74, 0X7E,0X87,0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4, 0X91,0X83,0X00,0X01,0X02,0X00,0X80,0X01,0X05,0X02,0X02,0X01,0X00,0X00,0X01,0X8E, 0X00,0X02,0X0A,0X2D,0X0F,0X8B,0X00,0X02,0X0B,0X2F,0X0B,0X83,0X00,0X02,0X14,0X2C, 0X06,0X8B,0X00,0X02,0X0D,0X2E,0X0B,0XA1,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02, 0XC3,0XB4,0X91,0X83,0X00,0X00,0X01,0X84,0X00,0X00,0X01,0X8F,0X00,0X02,0X0A,0X2D, 0X0F,0X8D,0X00,0X02,0X0B,0X2F,0X0B,0X81,0X00,0X02,0X14,0X2C,0X06,0X8D,0X00,0X02, 0X0D,0X2E,0X0B,0XA0,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8E, 0XA3,0X0A,0XA2,0XA0,0X9D,0X98,0X91,0X86,0X7A,0X6E,0X63,0X5C,0X57,0X81,0X55,0X02, 0X3F,0X2E,0X11,0X8F,0X00,0X07,0X0B,0X2F,0X0B,0X00,0X00,0X14,0X2C,0X06,0X8F,0X00, 0X02,0X0F,0X2F,0X3F,0X93,0X55,0X0E,0X5A,0X62,0X6A,0X74,0X7E,0X87,0X91,0X9A,0XA3, 0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8E,0XA3,0X0A,0XA2, 0XA0,0X9C,0X97,0X8E,0X83,0X77,0X6A,0X61,0X5A,0X56,0X80,0X55,0X05,0X42,0X27,0X11, 0X00,0X00,0X09,0X8D,0X11,0X07,0X09,0X0B,0X18,0X00,0X04,0X2A,0X06,0X09,0X8D,0X11, 0X05,0X09,0X00,0X01,0X0F,0X2C,0X42,0X92,0X55,0X0E,0X5A,0X62,0X6A,0X74,0X7E,0X87, 0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X02,0XB4,0X9B,0X75,0XCE, 0X67,0X00,0X66,0X9F,0X67,0X02,0X59,0X3F,0X30,0X83,0X00,0X02,0X8E,0X6C,0X55,0XAA, 0X48,0X04,0X47,0X46,0X46,0X47,0X47,0XBF,0X48,0X02,0X3F,0X30,0X30,0X83,0X00,0X02, 0X69,0X4D,0X37,0XA9,0X30,0X06,0X2F,0X2A,0X25,0X22,0X26,0X2B,0X2F,0XC1,0X30,0XFF, 0X00,0XFF,0X00,0XFF,0X00,0XDA,0X00,0X16,0X02,0X05,0X08,0X0C,0X0F,0X13,0X16,0X1A, 0X1D,0X1F,0X1F,0X22,0X26,0X2B,0X30,0X35,0X3B,0X40,0X45,0X4A,0X50,0X55,0X59,0X81, 0X5C,0X00,0X2A,0XE1,0X00,0X16,0X03,0X08,0X0E,0X14,0X1A,0X1F,0X25,0X2B,0X30,0X33, 0X33,0X38,0X3F,0X47,0X50,0X59,0X62,0X6A,0X73,0X7C,0X85,0X8D,0X94,0X80,0X99,0X01, 0X64,0X03,0XE1,0X00,0X1A,0X03,0X08,0X0E,0X14,0X1A,0X1F,0X25,0X2B,0X30,0X33,0X33, 0X38,0X3F,0X47,0X50,0X59,0X62,0X6A,0X73,0X7C,0X85,0X8D,0X94,0X99,0X99,0X64,0X03, 0XE2,0X00,0X19,0X03,0X08,0X0E,0X14,0X1A,0X1F,0X25,0X2B,0X30,0X33,0X33,0X38,0X3F, 0X47,0X50,0X59,0X62,0X6A,0X73,0X7C,0X85,0X8D,0X94,0X99,0X64,0X03,0XE3,0X00,0X18, 0X03,0X08,0X0E,0X14,0X1A,0X1F,0X25,0X2B,0X30,0X33,0X33,0X38,0X3F,0X47,0X50,0X59, 0X62,0X6A,0X73,0X7C,0X85,0X8D,0X94,0X64,0X03,0XE4,0X00,0X17,0X03,0X08,0X0E,0X14, 0X1A,0X1F,0X25,0X2B,0X30,0X33,0X33,0X38,0X3F,0X47,0X50,0X59,0X62,0X6A,0X73,0X7C, 0X85,0X8D,0X61,0X03,0XE5,0X00,0X07,0X01,0X02,0X03,0X04,0X05,0X06,0X07,0X09,0X80, 0X0A,0X0B,0X13,0X3F,0X47,0X50,0X59,0X62,0X6A,0X73,0X7C,0X85,0X5C,0X03,0X98,0X00, 0X01,0X01,0X03,0XD4,0X00,0X0A,0X0A,0X3F,0X47,0X50,0X59,0X62,0X6A,0X73,0X7C,0X57, 0X03,0X98,0X00,0X02,0X01,0X29,0X0A,0XD4,0X00,0X09,0X0A,0X3F,0X47,0X50,0X59,0X62, 0X6A,0X73,0X51,0X03,0X98,0X00,0X03,0X02,0X2E,0X3F,0X0A,0XD4,0X00,0X08,0X0A,0X3F, 0X47,0X50,0X59,0X62,0X6A,0X4B,0X02,0X98,0X00,0X04,0X02,0X34,0X47,0X3F,0X0A,0XD4, 0X00,0X07,0X0A,0X3F,0X47,0X50,0X59,0X62,0X45,0X02,0X98,0X00,0X05,0X02,0X3A,0X50, 0X47,0X3F,0X0A,0XD4,0X00,0X06,0X0A,0X3F,0X47,0X50,0X59,0X40,0X02,0X98,0X00,0X06, 0X02,0X40,0X59,0X50,0X47,0X3F,0X0A,0XD4,0X00,0X05,0X0A,0X3F,0X47,0X50,0X3A,0X02, 0X98,0X00,0X07,0X02,0X45,0X62,0X59,0X50,0X47,0X3F,0X0A,0XD4,0X00,0X04,0X0A,0X3F, 0X47,0X34,0X02,0X98,0X00,0X08,0X02,0X4B,0X6A,0X62,0X59,0X50,0X47,0X3F,0X0A,0XD4, 0X00,0X03,0X0A,0X3F,0X2E,0X02,0X98,0X00,0X09,0X03,0X51,0X73,0X6A,0X62,0X59,0X50, 0X47,0X3F,0X0A,0XD4,0X00,0X02,0X0A,0X29,0X01,0X98,0X00,0X0A,0X03,0X57,0X7C,0X73, 0X6A,0X62,0X59,0X50,0X47,0X3F,0X0A,0XD4,0X00,0X01,0X03,0X01,0X98,0X00,0X0B,0X03, 0X5C,0X85,0X7C,0X73,0X6A,0X62,0X59,0X50,0X47,0X3F,0X13,0X80,0X0A,0X07,0X09,0X07, 0X06,0X05,0X04,0X03,0X02,0X01,0XE5,0X00,0X17,0X03,0X61,0X8D,0X85,0X7C,0X73,0X6A, 0X62,0X59,0X50,0X47,0X3F,0X38,0X33,0X33,0X30,0X2B,0X25,0X1F,0X1A,0X14,0X0E,0X08, 0X03,0XE4,0X00,0X18,0X03,0X64,0X94,0X8D,0X85,0X7C,0X73,0X6A,0X62,0X59,0X50,0X47, 0X3F,0X38,0X33,0X33,0X30,0X2B,0X25,0X1F,0X1A,0X14,0X0E,0X08,0X03,0XE3,0X00,0X19, 0X03,0X64,0X99,0X94,0X8D,0X85,0X7C,0X73,0X6A,0X62,0X59,0X50,0X47,0X3F,0X38,0X33, 0X33,0X30,0X2B,0X25,0X1F,0X1A,0X14,0X0E,0X08,0X03,0XE2,0X00,0X1A,0X03,0X64,0X99, 0X99,0X94,0X8D,0X85,0X7C,0X73,0X6A,0X62,0X59,0X50,0X47,0X3F,0X38,0X33,0X33,0X30, 0X2B,0X25,0X1F,0X1A,0X14,0X0E,0X08,0X03,0XE1,0X00,0X01,0X03,0X64,0X80,0X99,0X16, 0X94,0X8D,0X85,0X7C,0X73,0X6A,0X62,0X59,0X50,0X47,0X3F,0X38,0X33,0X33,0X30,0X2B, 0X25,0X1F,0X1A,0X14,0X0E,0X08,0X03,0XE1,0X00,0X00,0X2A,0X81,0X5C,0X16,0X59,0X55, 0X50,0X4A,0X45,0X40,0X3B,0X35,0X30,0X2B,0X26,0X22,0X1F,0X1F,0X1D,0X1A,0X16,0X13, 0X0F,0X0C,0X08,0X05,0X02,0XFF,0X00,0XFF,0X00,0XDA,0X00,0X74,0X38,0X6D,0X6B,0X00, 0X00,0X40,0X08,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, 0XFF,0XFF,0XFF }; boinc-app-seti_8.00~svn3701.orig/client/sah_gfx_main.cpp0000644000175000017500000000514312370724260023125 0ustar locutuslocutus // Copyright 2007 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. #include "sah_gfx_main.h" #include "boinc_api.h" #include "graphics2.h" extern double progress; SAH_SHMEM* sah_shmem; REDUCED_ARRAY_GEN rarray; GDATA* sah_graphics; bool nographics_flag = false; void update_shmem() { if (sah_graphics->countdown > 0) { sah_graphics->countdown--; boinc_wu_cpu_time(sah_graphics->cpu_time); sah_graphics->progress=progress; } } void sah_graphics_init(APP_INIT_DATA& app_init_data) { if (nographics_flag) return; if ((app_init_data.host_info.m_nbytes != 0) && (app_init_data.host_info.m_nbytes <= (double)(48*1024*1024)) ) { fprintf(stderr,"Low memory machine... Disabling graphics.\n"); fprintf(stderr,"%f <= %f\n",app_init_data.host_info.m_nbytes,(double)48*1024*1024); nographics_flag = true; return; } sah_shmem = (SAH_SHMEM*)boinc_graphics_make_shmem("setiathome", sizeof(SAH_SHMEM)); if (!sah_shmem) { sah_shmem=(SAH_SHMEM*)boinc_graphics_get_shmem("setiathome"); } if (!sah_shmem) { nographics_flag = true; return; } sah_graphics = &(sah_shmem->gdata); boinc_register_timer_callback(update_shmem); } boinc-app-seti_8.00~svn3701.orig/client/sah_gfx.cpp0000644000175000017500000006263512637146453022142 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // Copyright 2003 Regents of the University of California // Here's a summary of the various functions for initializing graphics // and responding to user preferences changes: // // SAH_GRAPHICS::worker_thread_init() // (called from worker thread once, at start) // // SAH_GRAPHICS_BASE::worker_thread_init // set prefs to defaults // parse_project_prefs() (from data already in mem) // initialize graph buffers // // app_graphics_thread_init // (called from SetMode when create window) // // SAH_GRAPHICS::graphics_thread_init() // SAH_GRAPHICS_BASE::graphics_thread_init() // init_camera() // init_lights() // app_resize(); // setup_given_prefs() // // app_graphics_reread_prefs // (called from event loop when get REREAD_PREFS msg // and we have an open window) // // SAH_GRAPHICS::reread_prefs() // SAH_GRAPHICS_BASE::reread_prefs() // boinc_parse_init_data_file() // boinc_get_init_data() // parse_project_prefs() // setup_given_prefs() // // SAH_GRAPHICS::setup_given_prefs() // SAH_GRAPHICS_BASE::setup_given_prefs() // init starfield // init logos // initialize graph, progress bar structures #include "sah_config.h" #ifdef _WIN32 #include "boinc_win.h" #include // Header File For The OpenGL32 Library #include // Header File For The GLu32 Library #if !defined(__MINGW32__) && !defined(_MSC_VER) #include // Header File For The Glaux Library #endif #if defined(HAVE_GLUT_H) #include #elif defined(HAVE_GL_GLUT_H) #include #elif defined(HAVE_FREEGLUT_H) #include #elif defined(HAVE_GL_FREEGLUT_H) #include #else #include #endif #endif #ifndef _WIN32 #include #include #include #include #ifdef __APPLE_CC__ #include #include #include #include #include #include #include #endif #ifdef HAVE_GL_H #include "gl.h" #elif defined(HAVE_GL_GL_H) #include #elif defined(HAVE_OPENGL_GL_H) #include #endif #ifdef HAVE_GLU_H #include "glu.h" #elif defined(HAVE_GL_GLU_H) #include #elif defined(HAVE_OPENGL_GLU_H) #include #endif #ifdef HAVE_GLUT_H #include "glut.h" #elif defined(HAVE_GL_GLUT_H) #include #elif defined(HAVE_OPENGL_GLUT_H) #include #elif defined(HAVE_GLUT_GLUT_H) #include #endif #endif #include "util.h" #include "str_util.h" #include "str_replace.h" #include "boinc_api.h" #include "graphics2.h" #include "gutil.h" #include "timecvt.h" #include "sah_gfx.h" bool mouse_down = false; int mouse_x, mouse_y; static void ra_string(float x, char* p) { int hr = (int) x; float fmin = x-hr; int min = (int)(fmin*60); float fsec = fmin*60 - min; int sec = (int)(fsec*60); sprintf(p, "%2d hr %2d' %2d\" RA", hr, min, sec); } static void dec_string(float x, char* p) { int deg = (int) x; float fmin = x-deg; int min = (int)(fmin*60); float fsec = fmin*60 - min; int sec = (int)(fsec*60); sprintf(p, "%s%d deg %2d' %2d\" Dec", (x<0?"-":"+"), deg, abs(min), abs(sec)); } void SAH_GRAPHICS::init_text_panels() { float pos[3], size[2]; COLOR color; double dtheta; double char_height = 0.15; double line_width = 2.0; double line_spacing = 0.3; double margin = 0.2; color.a = graph_alpha; double lum = .6; double sat = .9; double hue = start_hue + hue_change*.33; HLStoRGB(hue, lum, sat, color); pos[0] = -1; pos[1] = -1; pos[2] = -2; size[0] = 4.9; size[1] = 3.; dtheta = .3; text_panels[0].init( pos, size, color, dtheta, char_height, line_width, line_spacing, margin ); hue = start_hue + hue_change*.66; if (hue > 1) hue -= 1; if (hue < 1) hue += 1; HLStoRGB(hue, lum, sat, color); pos[0] = -3; pos[1] = 0; pos[2] = -1.8; dtheta = -.6; text_panels[1].init( pos, size, color, dtheta, char_height, line_width, line_spacing, margin ); } void SAH_GRAPHICS::get_data_info_string(char* buf) { char ra_buf[256], dec_buf[256]; static const char *locations[]= { "Arecibo 403MHz Line Feed", "Arecibo 1.42GHz Flat Feed", "Arecibo 1.42GHz Gregorian Feed", "Unknown" }; int s4_id=3; if (gdata->ready) { s4_id = gdata->wu.s4_id; // starting after the 3rd receiver_cfg entry, the long form // name appears in receiver_cfg->name if (s4_id>2) { if (strlen(gdata->wu.receiver_name)==0) { locations[0]="SETI@home Multi-Beam"; } else { locations[0]=gdata->wu.receiver_name; } s4_id=0; } ra_string(gdata->wu.start_ra, ra_buf); dec_string(gdata->wu.start_dec, dec_buf); sprintf(buf, "From: %s, %s\n" "Recorded on: %s\n" "Recorded at: %s\n" "Base frequency: %.9f GHz", ra_buf, dec_buf, short_jd_string(gdata->wu.time_recorded), locations[s4_id], gdata->wu.subband_base/1e9 ); } else { strcpy( buf, "" ); } } void SAH_GRAPHICS::get_user_info_string(char* buf) { sprintf( buf, "Name: %s\n" "Team: %s\n" "Total credit: %.2f\n", app_init_data.user_name, app_init_data.team_name, app_init_data.user_total_credit ); } void SAH_GRAPHICS::get_analysis_info_string(char* buf) { if (gdata->ready) { sprintf(buf, "%s\n" "Doppler drift rate %6.4f Hz/sec Resolution %5.3f Hz\n", gdata->status, gdata->fft_info.chirp_rate, gdata->wu.subband_sample_rate/gdata->fft_info.fft_len ); } else { strcpy( buf, "" ); } } // decide what type of signal to display. // If there's anything new (dirty) display it. // Otherwise cycle through the types // int SAH_GRAPHICS::choose_signal_to_display(double time_of_day) { int choices[3], nchoices; if (gdata->gi.dirty) { gdata->gi.dirty = false; return 0; } else if (gdata->pi.dirty) { gdata->pi.dirty = false; return 1; } else if (gdata->ti.dirty) { gdata->ti.dirty = false; return 2; } else { nchoices = 0; if (gdata->gi.peak_power) { choices[nchoices++] = 0; } if (gdata->pi.peak_power) { choices[nchoices++] = 1; } if (gdata->ti.peak_power) { choices[nchoices++] = 2; } if (nchoices == 0) return -1; if (nchoices == 1) return choices[0]; int i = (int)fmod(time_of_day/5., (double)nchoices); // rotate every 5 seconds return choices[i]; } } void SAH_GRAPHICS::render_pillars(double time_of_day, double dt) { int i; float pos[3]; double cur_cpu_time; double max = 0, d; float pulseData[PULSE_POT_LEN]; float tripletData[TRIPLET_POT_LEN]; float gaussFunc[GAUSS_POT_LEN]; char buf[512],time_buf[256]; const char *TitleText="SETI@home 8"; int s4_id=3; if (gdata && gdata->ready) { s4_id=gdata->wu.s4_id; if ((s4_id > 2) && (s4_id < 17)) { TitleText="SETI@home Version 8"; } else if (s4_id >= 17) { time_t t=time(0); struct tm *tm=localtime(&t); if (tm->tm_year >= 116) { TitleText="SETI@home/Breakthrough!"; } else { TitleText="SETI@home Version 8"; } } } draw_pillars(); // draw User and Data text // mode_lines(); glColor3f(1., 1., 1.); // white text pos[0] = 2; pos[1] = 2.15; pos[2] = 0; draw_text_line(pos, 0.2, 2.0, "Data info"); pos[0] = 1.2; pos[1] -= 0.2; get_data_info_string(buf); draw_text(pos, 0.1, 1.0, 0.15, buf ); pos[0] = 2; pos[1] = .8; draw_text_line(pos, 0.2, 2.0, "User info"); pos[0] = 1.2; pos[1] -= .2; get_user_info_string(buf); draw_text(pos, 0.1, 1.0, 0.15, buf); pos[0] = -2.75; pos[1] = 2.15; draw_text_line(pos, 0.2, 2.0, TitleText); pos[0] = -3.5; pos[1] = 1.9; get_analysis_info_string(buf); draw_text(pos, 0.1, 1.0, 0.15, buf); // draw CPU time and progress bars // pos[1] = 0.3; cur_cpu_time=gdata->cpu_time; ndays_to_string(cur_cpu_time/SECONDS_PER_DAY, 0, time_buf ); sprintf(buf, "Overall %.3f%% done CPU time: %s", floor(gdata->progress*100000)/1000, time_buf); draw_text_line(pos, 0.1, 1.0, buf); mode_unshaded(); inner_progress.draw(gdata->local_progress); outer_progress.draw(gdata->progress); // draw current or best signal // if (!gdata->ready) return; glColor3f(1., 1., 1.); mode_unshaded(); pos[0] = -3.5; pos[1] = 1.6; pos[2] = 0.; switch (choose_signal_to_display(time_of_day)) { case 0: if (gdata->gi.peak_power) { sprintf( buf, "%sGaussian: power %5.2f, fit %5.3f, score %5.3f", gdata->gi.is_best?"Best ":"New ", gdata->gi.peak_power, gdata->gi.chisqr, gdata->gi.score ); draw_text(pos, 0.1, 1.0, 0.15, buf); for (i=0;igi.pot[i] > max) max = gdata->gi.pot[i]; } for (i=0;igi.fft_ind)/gdata->gi.sigma; gaussFunc[i] = (gdata->gi.mean_power + gdata->gi.peak_power*exp(-d*d*0.693))/max; } rnd_graph.draw(gdata->gi.pot, GAUSS_POT_LEN); sin_graph.draw(gaussFunc, GAUSS_POT_LEN); } break; case 1: if (gdata->pi.peak_power) { sprintf( buf, "%sPulse: power %5.2f, period %6.4f, score %5.2f", gdata->pi.is_best?"Best ":"New ", gdata->pi.peak_power, gdata->pi.period, gdata->pi.score ); draw_text(pos, 0.1, 1.0, 0.15, buf); for (i=0;ipi.pot_max[i]/255.0; } rnd_graph.draw(pulseData, PULSE_POT_LEN); } break; case 2: if (gdata->ti.peak_power) { sprintf( buf, "%sTriplet: power %5.2f, period %6.4f", gdata->ti.is_best?"Best ":"New ", gdata->ti.peak_power, gdata->ti.period ); draw_text(pos, 0.1, 1.0, 0.15, buf); for (i=0;iti.pot_max[i]/255.0; } rnd_graph.add_tick(gdata->ti.tpotind0_0, 0); rnd_graph.add_tick(gdata->ti.tpotind1_0, 1); rnd_graph.add_tick(gdata->ti.tpotind2_0, 2); rnd_graph.draw(tripletData, TRIPLET_POT_LEN, true); } break; } } extern float* white; void SAH_GRAPHICS::render_headsup(double time_of_day, double dt) { double cur_cpu_time; COLOR color; color.a = .7; double lum = .5; double sat = .5; double hue = start_hue + hue_change/2.; if (hue > 1) hue -= 1; if (hue < 1) hue += 1; HLStoRGB(hue, lum, sat, color); mode_ortho(); GLfloat char_height = 0.015; GLfloat line_width = 0.25; GLfloat line_spacing = 0.03; GLfloat margin = 0.2; char buf[512], time_buf[256]; float pos[3] = {0, 0.7, 1.0}; mode_unshaded(); //float pos1[3] = {.03,.94,1.0}; //float pos2[3] = {.97,.94,1.0}; float pos1[3] = {0, .62, 1.0}; float pos2[3] = {1, .71, 1.0}; get_analysis_info_string(buf); draw_text(pos1, char_height, line_width, line_spacing, buf); get_user_info_string(buf); get_data_info_string(time_buf); strcat(buf, time_buf); draw_text_right(pos2, char_height, line_width, line_spacing, buf); cur_cpu_time=gdata->cpu_time; ndays_to_string(cur_cpu_time/SECONDS_PER_DAY, 0, time_buf ); sprintf(buf, "Overall %.3f%% done CPU time: %s", floor(gdata->progress*100000)/1000, time_buf); draw_text(pos, char_height, line_width, line_spacing, buf); outer_progress_2d.draw(gdata->progress); glColor4f(1,1,1,1); if (gdata->ready) { double max = 0, d; float pulseData[PULSE_POT_LEN]; float tripletData[TRIPLET_POT_LEN]; float gaussFunc[GAUSS_POT_LEN]; char buf[256]; int choice; int i; choice = choose_signal_to_display(time_of_day); pos[1]=.47; switch (choice) { case 0: if (gdata->gi.peak_power) { sprintf( buf, "%sGaussian: power %5.2f, fit %5.3f, score %5.3f", gdata->gi.is_best?"Best ":"", gdata->gi.peak_power, gdata->gi.chisqr, gdata->gi.score ); draw_text(pos, char_height, line_width, line_spacing, buf); for (i=0;igi.pot[i] > max) max = gdata->gi.pot[i]; } for (i=0;igi.fft_ind)/gdata->gi.sigma; gaussFunc[i] = (gdata->gi.mean_power + gdata->gi.peak_power*exp(-d*d*0.693))/max; } sin_graph.draw(gaussFunc, GAUSS_POT_LEN); rnd_graph.draw(gdata->gi.pot, GAUSS_POT_LEN); } break; case 1: if (gdata->pi.peak_power) { sprintf( buf, "%sPulse: power %5.2f, period %6.4f, score %5.2f", gdata->pi.is_best?"Best ":"", gdata->pi.peak_power, gdata->pi.period, gdata->pi.score ); draw_text(pos, char_height, line_width, line_spacing, buf); for (i=0;ipi.pot_max[i]/255.0; } rnd_graph.draw(pulseData, PULSE_POT_LEN); } break; case 2: if (gdata->ti.peak_power) { sprintf( buf, "Best Triplet: power %5.2f, period %6.4f", gdata->ti.peak_power, gdata->ti.period ); draw_text(pos, char_height, line_width, line_spacing, buf); for (i=0;iti.pot_max[i]/255.0; } rnd_graph.add_tick(gdata->ti.tpotind0_0, 1 ); rnd_graph.add_tick(gdata->ti.tpotind1_0, 1 ); rnd_graph.add_tick(gdata->ti.tpotind2_0, 1 ); rnd_graph.draw(tripletData, TRIPLET_POT_LEN); } break; } } ortho_done(); } void SAH_GRAPHICS::render_panels(double time_of_day, double dt) { double cur_cpu_time; char buf[512],time_buf[256]; float pos[3] = {0., 0., 0.}; int i; MOVING_TEXT_PANEL tp[2]; get_user_info_string(buf); get_data_info_string(time_buf); strcat(buf, time_buf); text_panels[0].set_text(0, buf); get_analysis_info_string(buf); text_panels[1].set_text(0, buf); cur_cpu_time=gdata->cpu_time; ndays_to_string(cur_cpu_time/SECONDS_PER_DAY, 0, time_buf ); sprintf(buf, "Overall %.3f%% done CPU time: %s", floor(gdata->progress*100000)/1000, time_buf); text_panels[1].set_text(6, buf); text_panels[1].get_pos(8, pos); pos[2]+=.01; outer_progress_2d.set_pos(pos); pos[0] = 0.03; pos[1] = 0.76; pos[2] = 0; mode_unshaded(); outer_progress_2d.draw(gdata->progress); glColor4f(1,1,1,1); if (gdata->ready) { double max = 0, d; float pulseData[PULSE_POT_LEN]; float tripletData[TRIPLET_POT_LEN]; //float pos[3] = {.03, .94-(2.*line_spacing), 0.}; float gaussFunc[GAUSS_POT_LEN]; char buf[256]; int choice; int i; choice = choose_signal_to_display(time_of_day); strcpy(buf, ""); switch (choice) { case 0: if (gdata->gi.peak_power) { sprintf( buf, "%sGaussian: power %5.2f, fit %5.3f, score %5.3f", gdata->gi.is_best?"Best ":"", gdata->gi.peak_power, gdata->gi.chisqr, gdata->gi.score ); for (i=0;igi.pot[i] > max) max = gdata->gi.pot[i]; } for (i=0;igi.fft_ind)/gdata->gi.sigma; gaussFunc[i] = (gdata->gi.mean_power + gdata->gi.peak_power*exp(-d*d*0.693))/max; } text_panels[1].get_pos(4, pos); rnd_graph.set_pos(pos); text_panels[1].get_pos(4, pos); pos[2] -= -.01; sin_graph.set_pos(pos); sin_graph.draw(gaussFunc, GAUSS_POT_LEN); rnd_graph.draw(gdata->gi.pot, GAUSS_POT_LEN); } break; case 1: if (gdata->pi.peak_power) { sprintf( buf, "%sPulse: peak_power %5.2f, period %6.4f, score %5.2f", gdata->pi.is_best?"Best ":"", gdata->pi.peak_power, gdata->pi.period, gdata->pi.score ); for (i=0;ipi.pot_max[i]/255.0; } text_panels[1].get_pos(4, pos); rnd_graph.set_pos(pos); rnd_graph.draw(pulseData, PULSE_POT_LEN); } break; case 2: if (gdata->ti.peak_power) { sprintf( buf, "Best Triplet: power %5.2f, period %6.4f", gdata->ti.peak_power, gdata->ti.period ); for (i=0;iti.pot_max[i]/255.0; } text_panels[1].get_pos(4, pos); rnd_graph.set_pos(pos); rnd_graph.add_tick(gdata->ti.tpotind0_0, 0); rnd_graph.add_tick(gdata->ti.tpotind1_0, 1); rnd_graph.add_tick(gdata->ti.tpotind2_0, 2); rnd_graph.draw(tripletData, TRIPLET_POT_LEN); } break; } text_panels[1].set_text(5, buf); } for (i=0; i<2; i++) { tp[i] = text_panels[i]; } MOVING_TEXT_PANEL::sort(tp, 2); for (i=0; i<2; i++) { tp[i].draw(); } for (i=0; i<2; i++) { text_panels[i].move(dt); } } void app_graphics_render(int x, int y, double t) { sah_graphics.render(x, y, t); } void app_graphics_init() { sah_graphics.graphics_thread_init(); } void SAH_GRAPHICS::data_struct_init() { SAH_GRAPHICS_BASE::data_struct_init(); } // Name is misleading - this gets called each time the app switches mode // void SAH_GRAPHICS::graphics_thread_init() { SAH_GRAPHICS_BASE::graphics_thread_init(); setup_given_prefs(); } void SAH_GRAPHICS::setup_given_prefs() { float pos[3], size[3]; float outer[] = {1.0, 0., 0.2, 0.4}; float inner[] = {0.2, 0.0, 0.7, 0.9}; float red[] = {1., 0., 0., 1.}; float green[] = {0., 1., 0., 1.}; float white[] = {1., 1., 1., 1.}; float reda[] = {1., 0, 0, .8}; pos[0] = -3.5; pos[1] = 0.8; pos[2] = -.4; size[0] = 4.; size[1] = .5; size[2] = .4; SAH_GRAPHICS_BASE::setup_given_prefs(); switch (text_style) { case TEXT_STYLE_PILLARS: rnd_graph.init(pos, size, red, green); pos[2] = -.2; size[2] = .1; sin_graph.init(pos, size, white, white); pos[0] = -1.5; pos[1] = 1.95; pos[2] = 0; inner_progress.init(pos, 1.0, 0.07, 0.05, outer, inner); pos[0] = -3.5; pos[1] = 0.60; pos[2] = 0; outer_progress.init(pos, 4., 0.1, 0.08, outer,inner); break; case TEXT_STYLE_HEADSUP: pos[0] = .03; pos[1] = .5; pos[2] = 1; size[0] = .4; size[1] = .08; size[2] = 0; rnd_graph.init(pos, size, reda, green); size[2]=0; pos[2]=0; sin_graph.init(pos, size, white, white); pos[0] = .03; pos[1] = 0.67; pos[2] = 0; outer_progress_2d.init(pos,.4,.02,.015,outer,inner); break; case TEXT_STYLE_PANELS: init_text_panels(); size[0] = 3; size[1] = .5; size[2] = .1; rnd_graph.init(pos, size, reda, green); size[2]=.05; sin_graph.init(pos, size, white, white); pos[0] = .03; pos[1] = .745; pos[2] = 0; outer[3]=.7; outer_progress_2d.init(pos,3,.2,.15,outer,inner); break; } pos[0] = -3.50; pos[1] = -2.50; pos[2] = -2.00; size[0] = 7.00; size[1] = 2.00; size[2] = 4.00; rarray.init_display( graph_style, pos, size, start_hue, hue_change, graph_alpha, "Frequency (Hz)","Power","Time (sec)" ); } void app_graphics_resize(int w, int h) { sah_graphics.resize(w, h); } void boinc_app_mouse_move(int x, int y, int left, int middle, int right) { if (left) { sah_graphics.pitch_angle += (y-mouse_y)*.1; sah_graphics.roll_angle += (x-mouse_x)*.1; mouse_y = y; mouse_x = x; } else if (right) { double d = (y-mouse_y); sah_graphics.viewpoint_distance *= exp(d/100.); mouse_y = y; mouse_x = x; } else { mouse_down = false; } } void boinc_app_mouse_button(int x, int y, int which, int is_down) { if (is_down) { mouse_down = true; mouse_x = x; mouse_y = y; } else { mouse_down = false; } } void boinc_app_key_press(int, int) {} void boinc_app_key_release(int, int) {} static void app_init_camera(double dist) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective( 45.0, // field of view in degree 1.0, // aspect ratio 1.0, // Z near clip 1000.0 // Z far ); set_viewpoint(dist); } void SAH_GRAPHICS::render(int xs, int ys, double time_of_day) { static double last_time=0; double dt = 0; if (!sah_shmem) { sah_shmem = (SAH_SHMEM*)boinc_graphics_get_shmem("setiathome"); gdata = &(sah_shmem->gdata); setup_given_prefs(); } if (!gdata) { fprintf(stderr, "shared memory segment missing\n"); exit(1); } gdata->countdown = 5; if (last_time != 0) { dt = time_of_day - last_time; } last_time = time_of_day; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if (starfield_size) { starfield.update_stars(dt); } render_logos(); app_init_camera(viewpoint_distance); scale_screen(width, height); start_rotate(); incr_rotate(dt); render_background(); switch (text_style) { case TEXT_STYLE_PILLARS: render_pillars(time_of_day, dt); break; case TEXT_STYLE_PANELS: render_panels(time_of_day, dt); break; case TEXT_STYLE_HEADSUP: render_headsup(time_of_day, dt); break; } render_3d_graph(time_of_day); end_rotate(); glFlush(); } boinc-app-seti_8.00~svn3701.orig/client/seti.h0000644000175000017500000001726312643777667021147 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // $Id: seti.h,v 1.19.2.27 2007/08/10 00:38:49 korpela Exp $ #ifndef _SETI_H #define _SETI_H #ifdef _WIN32 #include "boinc_win.h" #endif #include #include "boinc_api.h" #include "diagnostics.h" extern APP_INIT_DATA app_init_data; #include "analyze.h" #ifndef AP_CLIENT #include "seti_header.h" #endif #include "malloc_a.h" // Define 64 bit integer types. #ifdef HAVE_INTTYPES_H // Most gnu platforms #include typedef int64_t sh_sint8_t; typedef uint64_t sh_uint8_t; #ifdef PRId64 // If print formats are defined #define SINT8_FMT "%"PRId64 #define SINT8_FMT_CAST(x) (x) #define UINT8_FMT "%"PRIu64 #define UINT8_FMT_CAST(x) (x) #else // play it safe. It'll work through 49 bits at least. #define SINT8_FMT "%20.0f" #define SINT8_FMT_CAST(x) static_cast(x) #define UINT8_FMT "%20.0f" #define UINT8_FMT_CAST(x) static_cast(x) #endif #elif SIZEOF_LONG_INT >= 8 // other L64 typedef long sh_sint8_t; typedef unsigned long sh_uint8_t; #define SINT8_FMT "%ld" #define SINT8_FMT_CAST(x) (x) #define UINT8_FMT "%lu" #define UINT8_FMT_CAST(x) (x) #elif defined(LLONG_MAX) || defined(HAVE_LONG_LONG) // systems with long long, but no inttypes.h typedef long long sh_sint8_t; typedef unsigned long long sh_uint8_t; // again play it safe #define SINT8_FMT "%20.0f" #define SINT8_FMT_CAST(x) static_cast(x) #define UINT8_FMT "%20.0f" #define UINT8_FMT_CAST(x) static_cast(x) #elif defined(HAVE__INT64) || \ (defined(_INTEGRAL_MAX_BITS) && (_INTEGRAL_MAX_BITS >= 64)) // Probably, but not necessarily MSC. typedef _int64 sh_sint8_t; typedef unsigned _int64 sh_uint8_t; #ifdef _MSC_VER // leave it to microsoft to be different. #define SINT8_FMT "%I64d" #define SINT8_FMT_CAST(x) (x) #define UINT8_FMT "%I64u" #define UINT8_FMT_CAST(x) (x) #else #define SINT8_FMT "%20.0f" #define SINT8_FMT_CAST(x) static_cast(x) #define UINT8_FMT "%20.0f" #define UINT8_FMT_CAST(x) static_cast(x) #endif #elif defined(HAVE_LONG_DOUBLE) typedef long double sh_sint8_t; typedef long double sh_uint8_t; #define SINT8_FMT "%20.0lf" #define SINT8_FMT_CAST(x) (x) #define UINT8_FMT "%20.0lf" #define UINT8_FMT_CAST(x) (x) #else typedef double sh_sint8_t; typedef double sh_uint8_t; #define SINT8_FMT "%20.0f" #define SINT8_FMT_CAST(x) static_cast(x) #define UINT8_FMT "%20.0f" #define UINT8_FMT_CAST(x) static_cast(x) #endif // HAVE_INTTYPES_H // make a consistent int32_t #ifndef HAVE_INT32_T #ifdef HAVE__INT32 typedef _int32 int32_t; #else typedef long int32_t; #endif #endif #ifdef HAVE_MALLOC_H #include #endif #ifdef HAVE_MEMORY_H #include #endif #ifdef HAVE_ALLOCA_H #include #endif // Adjustement to flops counter to make FLOPS include floating point loads and // stores. extern double LOAD_STORE_ADJUSTMENT; extern double SETUP_FLOPS; typedef float sah_complex[2]; struct ANALYSIS_STATE { sah_complex *data; sah_complex *savedWUData; // Save the original WU data int npoints; int icfft; int PoT_freq_bin; // where we are in PoT analysis for this icfft // ... will be -1 if no PoT analysis in progress int PoT_activity; int doing_pulse; double FLOP_counter; }; extern bool notranspose_flag; extern bool default_functions_flag; extern int verbose; extern int seti_init_state(); extern int seti_do_work(); extern int result_group_start(); extern int result_group_write_header(); extern int result_group_end(); extern int checkpoint(BOOLEAN force_checkpoint=0); extern int seti_parse_wu(FILE*, ANALYSIS_STATE&); extern int parse_state_file(ANALYSIS_STATE& as); extern void final_report(); extern ANALYSIS_STATE analysis_state; #ifndef AP_CLIENT extern SETI_WU_INFO swi; #endif #ifdef BOINC_APP_GRAPHICS #include "reduce.h" #include "graphics2.h" #endif #ifndef AP_CLIENT struct SPIKE_INFO : public track_mem { public : SPIKE_INFO(); ~SPIKE_INFO(); SPIKE_INFO(const SPIKE_INFO &si); SPIKE_INFO &operator =(const SPIKE_INFO &si); spike s; double score; // calc in ReportEvents() int bin; // assigned in ReportEvents() int fft_ind; // assigned in ReportEvents() }; struct AUTOCORR_INFO : public track_mem { public : AUTOCORR_INFO(); ~AUTOCORR_INFO(); AUTOCORR_INFO(const AUTOCORR_INFO &si); AUTOCORR_INFO &operator =(const AUTOCORR_INFO &si); autocorr a; double score; // calc in ReportEvents() int bin; // assigned in ReportEvents() int fft_ind; // assigned in ReportEvents() }; struct GAUSS_INFO : public track_mem { public : GAUSS_INFO(); ~GAUSS_INFO(); GAUSS_INFO(const GAUSS_INFO &gi); GAUSS_INFO &operator =(const GAUSS_INFO &gi); gaussian g; double score; // calc in ReportGaussEvent() double display_power_thresh; // calc in gaussfit() int bin; // assigned in ReportGaussEvent() int fft_ind; // assigned in ReportGaussEvent() //float * pot; }; struct PULSE_INFO : public track_mem { public : PULSE_INFO(); ~PULSE_INFO(); PULSE_INFO(const PULSE_INFO &pi); PULSE_INFO &operator =(const PULSE_INFO &pi); pulse p; double score; // calc in ReportPulseEvent() int freq_bin; // assigned in ReportPulseEvent() int time_bin; // assigned in ReportPulseEvent() unsigned int * pot_min; // Scaled 0-255 for display unsigned int * pot_max; // Scaled 0-255 for display }; struct TRIPLET_INFO : public track_mem { public : TRIPLET_INFO(); ~TRIPLET_INFO(); TRIPLET_INFO(const TRIPLET_INFO &ti); TRIPLET_INFO &operator =(const TRIPLET_INFO &ti); triplet t; double score; // assigned in ReportTripletEvent() double bperiod; // probably deprecated - remove sometime int freq_bin; // assigned in ReportTripletEvent() // ticks below assigned in ReportTripletEvent() int tpotind0_0; // index into pot_min/pot_max arrays int tpotind0_1; // of start/end of first element of triplet int tpotind1_0; // second element int tpotind1_1; int tpotind2_0; // and third element int tpotind2_1; double time_bin; // calc in ReportTripletEvent() double scale; // Scale from PoT bins to TRIPLET_POT_LEN unsigned int * pot_min; // Scaled 0-255 for display unsigned int * pot_max; // Scaled 0-255 for display }; #endif #define UNSTDMAX(a,b) (((a) > (b)) ? (a) : (b)) #define UNSTDMIN(a,b) (((a) < (b)) ? (a) : (b)) unsigned int pow2(unsigned int num); #endif boinc-app-seti_8.00~svn3701.orig/client/sah_gfx_main.h0000644000175000017500000000352112175757076022606 0ustar locutuslocutus// Copyright 2007 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. #include #include "gdata.h" #include "boinc_api.h" extern SAH_SHMEM* sah_shmem; extern REDUCED_ARRAY_GEN rarray; extern GDATA* sah_graphics; extern bool nographics_flag; inline bool nographics() { if (nographics_flag) return true; if (!sah_graphics) return true; if (!sah_graphics->countdown) return true; return false; } extern void sah_graphics_init(APP_INIT_DATA&); boinc-app-seti_8.00~svn3701.orig/client/analyzeReport.h0000644000175000017500000000573411516176217023020 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // Title : analyzeReport.h // $Id: analyzeReport.h,v 1.8.2.3 2007/05/31 22:03:09 korpela Exp $ #include #include "seti.h" #include "boinc_api.h" #include "mfile.h" int ReportEvents( float * fp_PowerSpectrum, int ul_NumDataPoints, int us_FFT, double spike_sigma_thresh ); int ReportGaussEvent( int ul_TOffset, float f_PeakPower, float f_TrueMean, float f_SumSq, int ul_PoT, float sigma, float f_PoTMaxPower, float fp_PoT[] ); int ReportPulseEvent( float PulsePower, float MeanPower, float PulsePeriod, int time_bin, int freq_bin, float snr, float thresh, float *foldedPOT, int scale, int write ); int ReportTripletEvent( float PulsePower, float MeanPower, float PulsePeriod, float mid_time_bin, int start_time_bin, int freq_bin, int pot_len, const float *PoT, int write ); int result_spike(SPIKE_INFO &si); int result_autocorr(AUTOCORR_INFO &ai); int result_gaussian(GAUSS_INFO &gi); void time_to_ra_dec(double time_jd, double *ra, double *dec); extern void reset_high_scores(); //extern void report_init(); extern void reload_graphics_state(); extern SPIKE_INFO * best_spike; extern AUTOCORR_INFO * best_autocorr; extern GAUSS_INFO * best_gauss; extern PULSE_INFO * best_pulse; extern TRIPLET_INFO * best_triplet; extern MFILE outfile; extern int signal_count; extern int autocorr_count; extern int spike_count; extern int pulse_count; extern int gaussian_count; extern int triplet_count; boinc-app-seti_8.00~svn3701.orig/client/gaussfit.cpp0000644000175000017500000004401612643777667022357 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // gaussfit.C // $Id: gaussfit.cpp,v 1.21.2.12 2007/08/10 00:38:48 korpela Exp $ // // The purpose of gaussian fitting is to find signals that rise and // fall in power over time at a rate consistent with the beam // pattern of the telescope. #include "sah_config.h" #include #include #include // debug stuff #define DEBUG_POT //#define DUMP_POWER_SPECTRA //#define DUMP_GAUSSIAN #define POT_TO_DUMP 32 #define TOFF_TO_DUMP 15 #define FFT_TO_DUMP 131072 int gul_PoT; int gul_Fftl; // end debug stuff #ifdef BOINC_APP_GRAPHICS #include "sah_gfx_main.h" #endif //#include "util.h" #include "s_util.h" #include "analyze.h" #include "seti.h" #include "worker.h" #include "analyzeFuncs.h" #include "analyzeReport.h" #include "analyzePoT.h" #include "lcgamm.h" #include "gaussfit.h" #include "chirpfft.h" #ifdef __arm__ #include "vector/fp_arm.h" #endif bool dump_pot = false; //float gauss_display_power_thresh = 0; float f_GetPeak( float fp_PoT[], int ul_TOffset, int ul_HalfSumLength, float f_MeanPower, float f_PeakScaleFactor, float f_weight[] ) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("f_GetPeak()"); #endif // Peak power is calculated as the weighted // sum of all powers within ul_HalfSumLength // of the assumed gaussian peak. // The weights are given by the gaussian function itself. // BUG WATCH : for the f_PeakScaleFactor to work, // ul_HalfSumLength *must* be set to sigma. int i; float f_sum; f_sum = 0.0; // Find a weighted sum for (i = ul_TOffset - ul_HalfSumLength; i <= ul_TOffset + ul_HalfSumLength; i++) { f_sum += (fp_PoT[i] - f_MeanPower) * f_weight[abs(i-ul_TOffset)]; } analysis_state.FLOP_counter+=6.0*ul_HalfSumLength; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return(f_sum * f_PeakScaleFactor); } float f_GetChiSq( float fp_PoT[], int ul_PowerLen, int ul_TOffset, float f_PeakPower, float f_MeanPower, float f_weight[], float *xsq_null=0 ) { // We calculate our assumed gaussian powers // on the fly as we try to fit them to the // actual powers at each point along the PoT. #ifdef USE_MANUAL_CALLSTACK call_stack.enter("f_GetChiSq()"); #endif int i; float f_ChiSq=0,f_null_hyp=0, f_PredictedPower, f_tot_weight=0; double rebin=swi.nsamples/ChirpFftPairs[analysis_state.icfft].FftLen /ul_PowerLen; for (i = 0; i < ul_PowerLen; i++) { f_PredictedPower = f_MeanPower + f_PeakPower * f_weight[abs(i-ul_TOffset)] ; f_tot_weight+=f_weight[abs(i-ul_TOffset)]; #ifdef DUMP_GAUSSIAN if ((gul_PoT == POT_TO_DUMP && ul_TOffset == TOFF_TO_DUMP) && gul_Fftl == FFT_TO_DUMP) { fprintf(stdout, "%f\n", f_PredictedPower); } #endif // ChiSq in this realm is: // sum[0:i]( (observed power - expected power)^2 / expected variance ) // The power of a signal is: // power = (noise + signal)^2 = noise^2 + signal^2 + 2*noise*signal // With mean power normalization, noise becomes 1, leaving: // power = signal^2 +or- 2*signal + 1 f_PredictedPower/=f_MeanPower; double signal=f_PredictedPower; double noise=(2.0*sqrt(std::max(f_PredictedPower,1.0f)-1)+1); f_ChiSq += (static_cast(rebin*SQUARE(fp_PoT[i]/f_MeanPower - signal)/noise)); f_null_hyp+= (static_cast(rebin*SQUARE(fp_PoT[i]/f_MeanPower-1)/noise)); } analysis_state.FLOP_counter+=20.0*ul_PowerLen+5; f_ChiSq/=ul_PowerLen; f_null_hyp/=ul_PowerLen; #ifdef DUMP_GAUSSIAN if (gul_PoT == POT_TO_DUMP && ul_TOffset == TOFF_TO_DUMP && gul_Fftl == FFT_TO_DUMP ) { for (i = 0; i < ul_PowerLen; i++) { fprintf(stdout, "%f\n", fp_PoT[i]); } } #endif if (xsq_null) *xsq_null=f_null_hyp; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return f_ChiSq; } float f_GetTrueMean( float fp_PoT[], int ul_PowerLen, float f_TotalPower, int ul_TOffset, int ul_ExcludeLen ) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("f_GetTrueMean()"); #endif // TrueMean is the mean power of the data set minus all power // out to ExcludeLen from our current TOffset. int i, i_start, i_lim; float f_ExcludePower = 0,f; // take care that we do not add to exclude power beyond PoT bounds! i_start = std::max(ul_TOffset - ul_ExcludeLen, 0); i_lim = std::min(ul_TOffset + ul_ExcludeLen + 1, swi.analysis_cfg.gauss_pot_length); for (i = i_start; i < i_lim; i++) { f_ExcludePower += fp_PoT[i]; } analysis_state.FLOP_counter+=(double)(i_lim-i_start+5); f=((f_TotalPower - f_ExcludePower) / (ul_PowerLen - (i - i_start))); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return f; } float f_GetPeakScaleFactor(float f_sigma) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("f_GetPeakScaleFactor()"); #endif // The PeakScaleFactor is calculated such that when used in f_GetPeak(), // the actual peak power can be extracted from a weighted sum. // This sum (see f_GetPeak()), is calculated as : // sum = SUM[x from -sigma to +sigma] of (gaussian weights * our data) // The gaussian weights are e^(-x^2 / sigma^2). // Our data is A(e^(-x^2 / sigma^2)), where 'A' is the peak power. // Through algebraic manipulation, we have: // A = sum * (1 / SUM[x from -sigma to +sigma] of (e^(-x^2 / sigma^2))^2. // The factor by which we multiply the sum is the PeakScaleFactor. // It is completely determined by sigma. int i, i_s = static_cast(floor(f_sigma+0.5)); float f_sigma_sq = f_sigma*f_sigma; float f_sum = 0.0; for (i = -i_s; i <= i_s; i++) { f_sum += static_cast(EXP(i, 0, f_sigma_sq)); } analysis_state.FLOP_counter+=(13.0*f_sigma+3); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return(1 / f_sum); } int ChooseGaussEvent( int ifft, float PeakPower, float TrueMean, float ChiSq, float null_ChiSq, int bin, float sigma, float PoTMaxPower, float fp_PoT[] ) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("ChooseGaussEvent"); #endif GAUSS_INFO gi; float scale_factor; bool report, chisqOK=(ChiSq <= swi.analysis_cfg.gauss_chi_sq_thresh); // gaussian info gi.bin = bin; gi.fft_ind = ifft; gi.g.chirp_rate = ChirpFftPairs[analysis_state.icfft].ChirpRate; gi.g.fft_len = ChirpFftPairs[analysis_state.icfft].FftLen; gi.g.sigma = sigma; gi.g.peak_power = PeakPower; gi.g.mean_power = TrueMean; gi.g.chisqr = ChiSq; gi.g.null_chisqr = null_ChiSq; gi.g.freq = cnvt_bin_hz(bin, gi.g.fft_len); double t_offset=(((double)gi.fft_ind+0.5)/swi.analysis_cfg.gauss_pot_length)* PoTInfo.WUDuration; gi.g.detection_freq =calc_detection_freq(gi.g.freq,gi.g.chirp_rate,t_offset); gi.g.time = swi.time_recorded+t_offset/86400.0; gi.g.max_power = PoTMaxPower; gi.score = -13.0; time_to_ra_dec(gi.g.time, &gi.g.ra, &gi.g.decl); // Scale PoT down to 256 16 bit ints. //for (i=0; i(gi.g.max_power) / 255.0f; if (gi.g.pot.size() != static_cast(swi.analysis_cfg.gauss_pot_length)) { gi.g.pot.set_size(swi.analysis_cfg.gauss_pot_length); } float_to_uchar(fp_PoT, &(gi.g.pot[0]), swi.analysis_cfg.gauss_pot_length, scale_factor); if (!swi.analysis_cfg.gauss_null_chi_sq_thresh) swi.analysis_cfg.gauss_null_chi_sq_thresh=1.890; // Gauss score used for "best of" and graphics. // This score is now set to be based upon the probability that a signal // would occur due to noise and the probability that it is shaped like // a Gaussian (normalized to 0 at thresholds). Thanks to Tetsuji for // making me think about this. The Gaussian has 62 degrees of freedom and // the null hypothesis has 63 degrees of freedom when gauss_pot_length=64; //JWS: Calculate invariant terms once, ala Alex Kan and Przemyslaw Zych static float gauss_bins = static_cast(swi.analysis_cfg.gauss_pot_length); static float gauss_dof = gauss_bins - 2.0f; static float null_dof = gauss_bins - 1.0f; static double score_offset = ( lcgf(0.5*null_dof, swi.analysis_cfg.gauss_null_chi_sq_thresh*0.5*gauss_bins) -lcgf(0.5*gauss_dof, swi.analysis_cfg.gauss_chi_sq_thresh*0.5*gauss_bins) ); //R: same optimization as for GPU build: if there is reportable Gaussian already - //R: skip score calculation for all except new reportable Gaussians // Final thresholding first. report = chisqOK && (gi.g.peak_power >= gi.g.mean_power * swi.analysis_cfg.gauss_peak_power_thresh) && (gi.g.null_chisqr >= swi.analysis_cfg.gauss_null_chi_sq_thresh); if (gaussian_count==0||report) { gi.score = score_offset +lcgf(0.5*gauss_dof,std::max(gi.g.chisqr*0.5*gauss_bins,0.5*gauss_dof+1)) -lcgf(0.5*null_dof,std::max(gi.g.null_chisqr*0.5*gauss_bins,0.5*null_dof+1)); } // Only include "real" Gaussians (those meeting the chisqr threshold) // in the best Gaussian display. if (gi.score > best_gauss->score && chisqOK) { *best_gauss = gi; if(verbose>=2){ fprintf(stderr,"Best gaussian updated: score=%.7g, fft_len=%d, PoT=%d, Offset=%d,\n\tPeak=%.7g, TrueMean=%.7g,ChiSq=%.7g,null_hyp=%.7g,PoTMaxPower=%.7g,icfft=%d\n", gi.score,ChirpFftPairs[analysis_state.icfft].FftLen,bin,ifft, PeakPower,TrueMean,ChiSq,null_ChiSq,PoTMaxPower,analysis_state.icfft); } } // Update gdata gauss info regardless of whether it is the // best thus far or even passes the final threshold. If // a gaussian has made it this far, display it. #ifdef BOINC_APP_GRAPHICS if (!nographics()) sah_graphics->gi.copy(&gi); #endif analysis_state.FLOP_counter+=24.0; // Final reporting. if (report) { int retval=result_gaussian(gi); if(verbose>=1){ int fft=(gi.g.fft_len>1024)?(gi.g.fft_len/1024):(gi.g.fft_len); char symbol=(gi.g.fft_len>1024)?('k'):(' '); fprintf(stderr,"Gaussian: peak=%.7g, mean=%.7g, ChiSq=%.7g, time=%.4g, d_freq=%.12g,\n\tscore=%.7g, null_hyp=%.7g, chirp=%.5g, fft_len=%d%c\n", gi.g.peak_power,gi.g.mean_power,gi.g.chisqr,(gi.g.time-swi.time_recorded)*86400,gi.g.detection_freq,gi.score, gi.g.null_chisqr,gi.g.chirp_rate,fft,symbol); } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return retval; } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } int GaussFit( float * fp_PoT, int ul_FftLength, int ul_PoT ) { int i, retval; BOOLEAN b_IsAPeak; float f_NormMaxPower; float f_null_hyp; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("GaussFit()"); #endif int ul_TOffset; int iSigma = static_cast(floor(PoTInfo.GaussSigma+0.5)); float f_GroupSum, f_GroupMax; int i_f, iPeakLoc; float f_TotalPower, f_MeanPower, f_TrueMean, f_ChiSq, f_PeakPower; // For setiathome the Sigma and Gaussian PoT length don't change during // a run of the application, so these frequently used values can be // precalculated and kept. static float f_PeakScaleFactor; static float *f_weight; if (!f_weight) { f_PeakScaleFactor = f_GetPeakScaleFactor(static_cast(PoTInfo.GaussSigma)); f_weight = reinterpret_cast(malloc(PoTInfo.GaussTOffsetStop*sizeof(float))); if (!f_weight) SETIERROR(MALLOC_FAILED, "!f_weight"); for (i = 0; i < PoTInfo.GaussTOffsetStop; i++) { f_weight[i] = static_cast(EXP(i, 0, PoTInfo.GaussSigmaSq)); } } // Find mean over power-of-time array f_TotalPower = 0; for (i = 0; i < swi.analysis_cfg.gauss_pot_length; i++) { f_TotalPower += fp_PoT[i]; } f_MeanPower = f_TotalPower / swi.analysis_cfg.gauss_pot_length; // Normalize power-of-time and check for the existence // of at least 1 peak. b_IsAPeak = false; double r_MeanPower=1.0/f_MeanPower; for (i = 0; i < swi.analysis_cfg.gauss_pot_length; i++) { fp_PoT[i] *= r_MeanPower; if (fp_PoT[i] > PoTInfo.GaussPowerThresh) b_IsAPeak = true; } analysis_state.FLOP_counter+=3.0*swi.analysis_cfg.gauss_pot_length+2; if (!b_IsAPeak) { //printf("no peak\n"); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; // no peak - bail on this PoT } // Recalculate Total Power across normalized array. // Given that powers are positive, f_TotalPower will // end up being == swi.analysis_cfg.gauss_pot_length. f_TotalPower = 0; f_NormMaxPower = 0; // Also locate group with the highest sum for use in second bailout check. f_GroupSum = 0; f_GroupMax = 0; for (i = 0, i_f = -iSigma; i < swi.analysis_cfg.gauss_pot_length; i++, i_f++) { f_TotalPower += fp_PoT[i]; if(fp_PoT[i] > f_NormMaxPower) f_NormMaxPower = fp_PoT[i]; f_GroupSum += fp_PoT[i] - ((i_f < 0) ? 0.0f : fp_PoT[i_f]); if (f_GroupSum > f_GroupMax) { f_GroupMax = f_GroupSum; iPeakLoc = i - iSigma/2; } } // Check at the group peak location whether data may contain Gaussians // (but only after the first hurry-up Gaussian has been set for graphics) if (best_gauss->display_power_thresh != 0) { iPeakLoc = std::max(PoTInfo.GaussTOffsetStart, (std::min(PoTInfo.GaussTOffsetStop - 1, iPeakLoc))); f_TrueMean = f_GetTrueMean( fp_PoT, swi.analysis_cfg.gauss_pot_length, f_TotalPower, iPeakLoc, 2 * iSigma ); f_PeakPower = f_GetPeak( fp_PoT, iPeakLoc, iSigma, f_TrueMean, f_PeakScaleFactor, f_weight ); analysis_state.FLOP_counter+=5.0*swi.analysis_cfg.gauss_pot_length+5; if (f_PeakPower < f_TrueMean*best_gauss->display_power_thresh*0.5f) { #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; // not even a weak peak at max group - bail on this PoT } } // slide dynamic gaussian across the Power Of Time array for (ul_TOffset = PoTInfo.GaussTOffsetStart; ul_TOffset < PoTInfo.GaussTOffsetStop; ul_TOffset++ ) { // TrueMean is the mean power of the data set minus all power // out to 2 sigma from our current TOffset. f_TrueMean = f_GetTrueMean( fp_PoT, swi.analysis_cfg.gauss_pot_length, f_TotalPower, ul_TOffset, 2 * iSigma ); f_PeakPower = f_GetPeak( fp_PoT, ul_TOffset, iSigma, f_TrueMean, f_PeakScaleFactor, f_weight ); // worth looking at ? if (f_PeakPower < f_TrueMean*best_gauss->display_power_thresh) { continue; } // bump up the display threshold to its final value. // We could bump it up only to the gaussian just found, // but that would cause a lot of time waste // computing chisq etc. if (best_gauss->display_power_thresh == 0) { best_gauss->display_power_thresh = PoTInfo.GaussPeakPowerThresh/3; } #ifdef TEXT_UI if(dump_pot) { printf("Found good peak at this PoT element.... truemean is %f, power is %f\n", f_TrueMean, f_PeakPower); } #endif #ifdef DUMP_GAUSSIAN gul_PoT = ul_PoT; gul_Fftl = ul_FftLength; #endif // look at it - try to fit f_ChiSq = f_GetChiSq( fp_PoT, swi.analysis_cfg.gauss_pot_length, ul_TOffset, f_PeakPower, f_TrueMean, f_weight, &f_null_hyp ); #ifdef TEXT_UI if(dump_pot) { printf("Checking ChiSqr for PoT dump....\n"); if(f_ChiSq <= swi.analysis_cfg.gauss_chi_sq_thresh) { int dump_i; printf( "POT %d %f %f %f %f %d ", ul_TOffset, f_PeakPower, f_TrueMean, PoTInfo.GaussSigmaSq, f_ChiSq, ul_PoT ); for (dump_i = 0; dump_i < swi.analysis_cfg.gauss_pot_length; dump_i++) { printf("%f ", fp_PoT[dump_i]); } printf("\n"); } else { printf("ChiSqr is %f, not good enough.\n", f_ChiSq); } } #endif retval = ChooseGaussEvent( ul_TOffset, f_PeakPower, f_TrueMean, f_ChiSq, f_null_hyp, ul_PoT, static_cast(PoTInfo.GaussSigma), f_NormMaxPower, fp_PoT ); if (retval) SETIERROR(retval,"from ChooseGaussEvent"); } // End of sliding gaussian #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } // End of gaussfit() boinc-app-seti_8.00~svn3701.orig/client/analyzeFuncs.cpp0000644000175000017500000014272513073254736023163 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // analyzeFuncs.C // $Id: analyzeFuncs.cpp,v 1.34.2.44 2007/08/16 10:13:55 charlief Exp $ // #define DO_SMOOTH #if defined(USING_XCODE) || defined(_WIN32) #include "version.h" const char *BOINC_PACKAGE_STRING="libboinc: " BOINC_VERSION_STRING; #else #include "config.h" const char *BOINC_PACKAGE_STRING="libboinc: " PACKAGE_STRING; #endif #undef PACKAGE_STRING #undef PACKAGE #undef PACKAGE_NAME #undef PACKAGE_BUGREPORT #undef PACKAGE_TARNAME #undef PACKAGE_VERSION #undef VERSION #include "sah_config.h" const char *SAH_PACKAGE_STRING=CUSTOM_STRING; #include #include #include #include #include #ifdef HAVE_MEMORY_H #include #endif #ifdef HAVE_MMAN_H #include #endif #ifdef HAVE_SYS_MMAN_H #include #endif #ifdef HAVE_MMAP_H #include #endif #include #include "sincos.h" #include "util.h" #include "s_util.h" #include "boinc_api.h" #ifdef BOINC_APP_GRAPHICS #include "sah_gfx_main.h" #endif #include "diagnostics.h" #include "vector/sighandler.h" #ifdef __arm__ #include "vector/fp_arm.h" #endif // In order to use IPP, set -DUSE_IPP and one of -DUSE_SSE3, -DUSE_SSE2, // -DUSE_SSE or nothing(generic), IPP precedes FFTW, ooura // TMR #if defined(USE_IPP) #pragma message ("-----IPP-----") #if defined(USE_SSE3) #define T7 1 #pragma message ("-----sse3-----") #include #elif defined(USE_SSE2) #define W7 1 #pragma message ("-----sse2-----") #include #elif defined(USE_SSE) #define A6 1 #pragma message ("-----sse-----") #include #else #pragma message ("-----mmx-----") #include #endif // T7 #include #elif defined(USE_FFTWF) #pragma message ("----FFTW----") #include #else #pragma message ("----ooura----") #include "fft8g.h" #endif // USE_IPP #include "seti.h" #include "analyze.h" #include "analyzeReport.h" #include "gaussfit.h" #include "spike.h" #include "autocorr.h" #include "malloc_a.h" #include "analyzeFuncs.h" #include "analyzePoT.h" #include "chirpfft.h" #include "worker.h" #include "filesys.h" #include "progress.h" BaseLineSmooth_func BaseLineSmooth=v_BaseLineSmooth; GetPowerSpectrum_func GetPowerSpectrum=v_GetPowerSpectrum; ChirpData_func ChirpData=v_ChirpData; Transpose_func Transpose=v_Transpose4; #ifdef USE_IPP static int MaxBufSize = 0; static Ipp8u* FftBuf = NULL; #endif // USE_IPP #ifndef M_PI #define M_PI 3.14159265358979323846 #endif #define INVALID_CHIRP 2e+20 ChirpFftPair_t* ChirpFftPairs = NULL; double ProgressUnitSize; double progress=0, remaining=1; // These are used to calculate chirped signals // TrigStep contains trigonometric functions for MinChirpStep over time // CurrentTrig contains current trigonometric fuctions // Tetsuji "Maverick" Rai // Trigonometric arrays SinCosArray* TrigStep = NULL; // trigonometric array of MinChirpStep SinCosArray* CurrentTrig = NULL; // current chirprate trigonometric array int CurrentChirpRateInd; // current chirprate index (absolute value) double MinChirpStep=0.0; bool use_transposed_pot; void InitTrigArray(int, double, int, double); void FreeTrigArray(void); void CalcTrigArray (int len, int ChirpRateInd); // The main analysis function. Args: // state pointer to data, # of points, starting chirp/fftlen // Must be called with unchirped data; // this function modifies (chirps) the data in place // swi parsed WU header //#define DEBUG #ifdef DEBUG int icfft; // for debug #endif #ifdef USE_FFTWF fftwf_plan transpose_plans[MAX_NUM_FFTS]; #endif int seti_analyze (ANALYSIS_STATE& state) { sah_complex* DataIn = state.savedWUData; int NumDataPoints = state.npoints; sah_complex* ChirpedData = NULL; sah_complex* WorkData = NULL; float* PowerSpectrum = NULL; float* tPowerSpectrum; // Transposed power spectra if used. float* AutoCorrelation = NULL; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("seti_analyze()"); #endif use_transposed_pot= (!notranspose_flag) && ((app_init_data.host_info.m_nbytes != 0) && (app_init_data.host_info.m_nbytes >= MIN_TRANSPOSE_MEMORY)); int num_cfft = 0; float chirprate; int last_chirp_ind = - 1 << 20, chirprateind; double progress_diff, progress_in_cfft, cputime0=0; int retval=0; if (swi.analysis_cfg.credit_rate != 0) LOAD_STORE_ADJUSTMENT=swi.analysis_cfg.credit_rate; #ifndef DEBUG int icfft; #endif int NumFfts, ifft, fftlen; int CurrentSub; int FftNum, need_transpose; unsigned long bitfield=swi.analysis_cfg.analysis_fft_lengths; unsigned long FftLen; unsigned long ac_fft_len=swi.analysis_cfg.autocorr_fftlen; #ifdef USE_IPP IppsFFTSpec_C_32fc* FftSpec[MAX_NUM_FFTS]; int BufSize; ippStaticInit(); // initialization of IPP library #elif defined(USE_FFTWF) // plan space for fftw fftwf_plan analysis_plans[MAX_NUM_FFTS]; fftwf_plan autocorr_plan; #else // fields need by the ooura fft logic int * BitRevTab[MAX_NUM_FFTS]; float * CoeffTab[MAX_NUM_FFTS]; #endif // Allocate data array and work area arrays. ChirpedData = state.data; PowerSpectrum = (float*) calloc_a(NumDataPoints, sizeof(float), MEM_ALIGN); if (PowerSpectrum == NULL) SETIERROR(MALLOC_FAILED, "PowerSpectrum == NULL"); if (use_transposed_pot) { tPowerSpectrum = (float*) calloc_a(NumDataPoints, sizeof(float), MEM_ALIGN); if (tPowerSpectrum == NULL) SETIERROR(MALLOC_FAILED, "tPowerSpectrum == NULL"); } else { tPowerSpectrum=PowerSpectrum; } AutoCorrelation = (float*)calloc_a(ac_fft_len, sizeof(float), MEM_ALIGN); if (AutoCorrelation == NULL) SETIERROR(MALLOC_FAILED, "AutoCorrelation == NULL"); // boinc_worker_timer(); FftNum=0; FftLen=1; #ifdef USE_FFTWF double sz; FILE *wisdom; std::string wisdom_path("wisdom.sah"); double wisdom_size=0; if ((file_size(wisdom_path.c_str(),wisdom_size)==0) && (wisdom_size>512)) { if ((wisdom=boinc_fopen(wisdom_path.c_str(),"r"))) { #ifdef HAVE_MUNMAP char *wiz=(char *)mmap(NULL,wisdom_size,PROT_READ,MAP_PRIVATE,fileno(wisdom),0); #else char *wiz=(char *)calloc_a(wisdom_size+1,1,MEM_ALIGN); int n=0; while (wiz && nstatus, "Generating FFT Coefficients"); #endif while (bitfield != 0) { if (bitfield & 1) { swi.analysis_fft_lengths[FftNum]=FftLen; #ifdef USE_IPP int order = 0; for (int tmp = FftLen; !(tmp & 1); order++) tmp >>= 1; IPP_FFT_NODIV_BY_ANY, ippAlgHintFast)) { SETIERROR (MALLOC_FAILED, "ippsFFTInitAlloc failed"); } #elif !defined(USE_FFTWF) // See docs in fft8g.C for sizing guidelines for BitRevTab and CoeffTab. BitRevTab[FftNum] = (int*) calloc_a(3+(int)sqrt((float)swi.analysis_fft_lengths[FftNum]), sizeof(int), MEM_ALIGN); if (BitRevTab[FftNum] == NULL) SETIERROR(MALLOC_FAILED, "BitRevTab[FftNum] == NULL"); BitRevTab[FftNum][0] = 0; #else WorkData = (sah_complex *)malloc_a(swi.nsamples * sizeof(float),MEM_ALIGN); sah_complex *scratch=(sah_complex *)malloc_a(swi.nsamples*sizeof(float),MEM_ALIGN); if ((WorkData == NULL) || (scratch==NULL)) { SETIERROR(MALLOC_FAILED, "WorkData == NULL || scratch == NULL"); } // TODO: Deallocate these at the end of the function #ifdef USE_MANUAL_CALLSTACK call_stack.enter("fftwf_plan_dft_1d()"); #endif analysis_plans[FftNum] = fftwf_plan_dft_1d(FftLen, scratch, WorkData, FFTW_BACKWARD, FFTW_MEASURE_OR_ESTIMATE|FFTW_PRESERVE_INPUT); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif if (use_transposed_pot) { fftwf_iodim dims[2]; dims[0].n = swi.nsamples/FftLen; dims[0].is = FftLen; dims[0].os = 1; dims[1].n = FftLen; dims[1].is = 1; dims[1].os = swi.nsamples/FftLen; transpose_plans[FftNum] = fftwf_plan_guru_r2r(0, NULL, 2, dims, (float *)WorkData, (float *)scratch, NULL, FFTW_MEASURE_OR_ESTIMATE); } FftNum++; free_a(scratch); free_a(WorkData); #endif /* USE_FFTWF */ } FftLen*=2; bitfield>>=1; } #ifdef USE_FFTWF { float *out= (float *)malloc_a(ac_fft_len*sizeof(float),MEM_ALIGN); float *scratch=(float *)malloc_a(ac_fft_len*sizeof(float),MEM_ALIGN); if ((WorkData == NULL) || (scratch==NULL)) { SETIERROR(MALLOC_FAILED, "WorkData == NULL || scratch == NULL"); } #ifdef USE_MANUAL_CALLSTACK call_stack.enter("fftwf_plan_r2r_1d()"); #endif autocorr_plan=fftwf_plan_r2r_1d(ac_fft_len, scratch, out, FFTW_REDFT10, FFTW_MEASURE_OR_ESTIMATE|FFTW_PRESERVE_INPUT); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif free_a(scratch); free_a(out); } wisdom=boinc_fopen(wisdom_path.c_str(),"w"); if (wisdom) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("fftwf_export_wisdom_to_string()"); #endif char *wiz=fftwf_export_wisdom_to_string(); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif if (wiz) { fwrite(wiz,strlen(wiz),1,wisdom); } fclose(wisdom); } #endif /* USE_FFTWF */ if (!state.icfft) { #ifdef CUSTOM_STRING fprintf(stderr,"%s\n", CUSTOM_STRING); #else fprintf(stderr,"%s\n", SAH_PACKAGE_STRING); #endif #ifdef AVX_EMU fprintf(stderr,"Emulating AVX\n"); #endif fprintf(stderr,"%s\n\n", BOINC_PACKAGE_STRING); fprintf(stderr,"Work Unit Info:\n"); fprintf(stderr,"...............\n"); fprintf(stderr,"WU true angle range is : %f\n", swi.angle_range); } else fprintf(stderr,"Restarted at %.2f percent.\n", progress*100); fflush(stderr); swi.num_fft_lengths=FftNum; // gernerate table of chirp/fft pairs (we may read table from file if testing) if (cfft_file != NULL) num_cfft = ReadCFftFile(&ChirpFftPairs, &MinChirpStep); else num_cfft = GenChirpFftPairs(&ChirpFftPairs, &MinChirpStep); if (num_cfft == MALLOC_FAILED) { SETIERROR(MALLOC_FAILED, "num_cfft == MALLOC_FAILED"); } // Get together various values that we'll need to analyse power over time ComputePoTInfo(num_cfft, NumDataPoints); // Initialize TrigArrays for testing if we have the memory.... // If we can't tell how much memory we have, assume we have plenty. if ((app_init_data.host_info.m_nbytes == 0) || (app_init_data.host_info.m_nbytes >= MIN_TRIGARRAY_MEMORY)) { InitTrigArray (NumDataPoints, MinChirpStep, TESTCHIRPIND, swi.subband_sample_rate); } boinc_install_signal_handlers(); #ifdef BOINC_APP_GRAPHICS if (sah_graphics) strcpy(sah_graphics->status, "Choosing optimal functions"); #endif // Choose the best analysis functions. ChooseFunctions(&BaseLineSmooth, &GetPowerSpectrum, &ChirpData, &Transpose, ChirpFftPairs, num_cfft, swi.nsamples, state.icfft == 0); if ((app_init_data.host_info.m_nbytes == 0) || (app_init_data.host_info.m_nbytes >= MIN_TRIGARRAY_MEMORY)) { FreeTrigArray(); // If we're using TrigArrays, reallocate & reinit if ((ChirpData == v_ChirpData) || (ChirpData == fpu_opt_ChirpData)) { InitTrigArray (NumDataPoints, MinChirpStep, ChirpFftPairs[state.icfft].ChirpRateInd, swi.subband_sample_rate); } } #ifdef USE_IPP if (MaxBufSize) { FftBuf = (Ipp8u*) malloc_a (MaxBufSize, MEM_ALIGN); if (FftBuf == NULL) SETIERROR (MALLOC_FAILED, "FftBuf == NULL"); } #elif !defined(USE_FFTWF) for (FftNum = 0; FftNum < swi.num_fft_lengths; FftNum++) { CoeffTab[FftNum] = (float*) calloc_a(swi.analysis_fft_lengths[FftNum]/2, sizeof(float), MEM_ALIGN); if (CoeffTab[FftNum] == NULL) SETIERROR(MALLOC_FAILED, "CoeffTab[FftNum] == NULL"); } #endif // Allocate WorkData array the size of the biggest FFT we'll do // TODO: Deallocate this at the end of the function WorkData = (sah_complex *)malloc_a(FftLen/2 * sizeof(sah_complex),MEM_ALIGN); if (WorkData == NULL) { SETIERROR(MALLOC_FAILED, "WorkData == NULL"); } // Smooth Baseline #ifdef DO_SMOOTH #ifdef BOINC_APP_GRAPHICS if (sah_graphics) strcpy(sah_graphics->status, "Doing Baseline Smoothing"); #endif retval = BaseLineSmooth( DataIn, NumDataPoints, swi.analysis_cfg.bsmooth_boxcar_length, swi.analysis_cfg.bsmooth_chunk_size ); if (retval) SETIERROR(retval,"from BaseLineSmooth"); #endif // used to calculate percent done //ProgressUnitSize = GetProgressUnitSize(NumDataPoints, num_cfft, swi); ProgressUnitSize = GetProgressUnitSize(NumDataPoints, num_cfft, ac_fft_len); //#define DUMP_CHIRP #ifdef DUMP_CHIRP // dump chirp/fft pairs and exit. fprintf(stderr, "size = %d MinChirpStep = %f\n", num_cfft, MinChirpStep); for (icfft = 0; icfft < num_cfft; icfft++) { fprintf(stderr,"%6d %15.11f %6d %6d %d %d\n", icfft, ChirpFftPairs[icfft].ChirpRate, ChirpFftPairs[icfft].ChirpRateInd, ChirpFftPairs[icfft].FftLen, ChirpFftPairs[icfft].GaussFit, ChirpFftPairs[icfft].PulseFind ); } fflush(stderr); exit(0); #endif boinc_wu_cpu_time(cputime0); reset_units(); double chirp_units=0; // Loop through chirp/fft pairs - this is the top level analysis loop. double last_ptime=0; int rollovers=0; double clock_max=0; for (icfft = state.icfft; icfft < num_cfft; icfft++) { fftlen = ChirpFftPairs[icfft].FftLen; chirprate = ChirpFftPairs[icfft].ChirpRate; chirprateind = ChirpFftPairs[icfft].ChirpRateInd; // boinc_worker_timer(); #ifdef DEBUG double ptime=static_cast((unsigned)clock())/CLOCKS_PER_SEC+ clock_max*rollovers; clock_max=std::max(last_ptime-ptime,clock_max); if (ptime((unsigned)clock())/CLOCKS_PER_SEC+ clock_max*rollovers; } last_ptime=ptime; fprintf(stderr,"%f %f %f %f %f %f %f %f %f\n", ptime, progress, ((double)icfft)/num_cfft, analysis_state.FLOP_counter, triplet_units, pulse_units, spike_units, gauss_units, chirp_units ); fflush(stderr); double cputime=0; boinc_wu_cpu_time(cputime); cputime-=cputime0; #endif remaining=1.0-(double)icfft/num_cfft; if (chirprateind != last_chirp_ind) { #ifdef BOINC_APP_GRAPHICS if (sah_graphics) strcpy(sah_graphics->status, "Chirping data"); #endif retval = ChirpData( DataIn, ChirpedData, chirprateind, chirprate, NumDataPoints, swi.subband_sample_rate ); if (retval) SETIERROR(retval, "from ChirpData()"); progress += (double)(ProgressUnitSize * ChirpProgressUnits()); chirp_units+=(double)(ProgressUnitSize * ChirpProgressUnits()); progress = std::min(progress,1.0); } // last_chirp = chirprate; last_chirp_ind = chirprateind; // Process this FFT length. // For a given FFT length (at a given chirp), we construct // PowerSpectrum[] which is a "waterfall" array of power spectra, // each fftlen long on the frequency axis and sample time long // on the time axis. // As we go along, we check each spectra for spikes. state.icfft = icfft; // update analysis state // Find index into FFT length table for the current // FFT length. This will be the same index needed // for ooura's coeffecient and bit reverse tables. for (FftNum = 0; FftNum < swi.num_fft_lengths; FftNum++) { if (swi.analysis_fft_lengths[FftNum] == fftlen) { break; } } #ifdef BOINC_APP_GRAPHICS if (sah_graphics) { sah_graphics->fft_info.chirp_rate = chirprate; sah_graphics->fft_info.fft_len = fftlen; strcpy(sah_graphics->status, "Computing Fast Fourier Transform"); } #endif // If PoT freq bin is non-negative, we are into PoT analysis // for this cfft pair and should not re-output an "ogh" line. if (state.PoT_freq_bin == -1) { retval = result_group_start(); if (retval) SETIERROR(retval,"from result_group_start"); } // Number of FFTs for this length NumFfts = NumDataPoints / fftlen; #ifdef BOINC_APP_GRAPHICS if (sah_graphics) { rarray.init_data(fftlen, NumFfts); } #endif for (ifft = 0; ifft < NumFfts; ifft++) { // boinc_worker_timer(); CurrentSub = fftlen * ifft; #if !defined(USE_FFTWF) && !defined(USE_IPP) // FFTW and IPP now use out of place transforms. memcpy( WorkData, &ChirpedData[CurrentSub], (int)(fftlen * sizeof(sah_complex)) ); #endif state.FLOP_counter+=5*(double)fftlen*log((double)fftlen)/log(2.0); #ifdef USE_IPP ippsFFTInv_CToC_32fc((Ipp32fc*)ChirpedData[CurrentSub], (Ipp32fc*)WorkData, FftSpec[FftNum], FftBuf); #elif defined(USE_FFTWF) #ifdef USE_MANUAL_CALLSTACK call_stack.enter("fftwf_execute_dft()"); #endif fftwf_execute_dft(analysis_plans[FftNum], &ChirpedData[CurrentSub], WorkData); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif #else /* !USE_FFTWF */ // replace time with freq - ooura FFT cdft(fftlen*2, 1, WorkData, BitRevTab[FftNum], CoeffTab[FftNum]); #endif /* USE_FFTWF */ // replace freq with power state.FLOP_counter+=(double)fftlen; GetPowerSpectrum( WorkData, &PowerSpectrum[CurrentSub], fftlen ); if (fftlen==(long)ac_fft_len) { state.FLOP_counter+=((double)fftlen)*5*log((double)fftlen)/log(2.0)+2*fftlen; #if defined(USE_FFTWF) #ifdef USE_MANUAL_CALLSTACK call_stack.enter("fftwf_execute_r2r()"); #endif fftwf_execute_r2r(autocorr_plan,&PowerSpectrum[CurrentSub],AutoCorrelation); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif #else #error Analysis needs to be modified for your FFT choice. #endif } // any ETIs ?! // 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) { //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, fftlen, ifft, swi ); if (retval) SETIERROR(retval,"from FindAutoCorrelation"); progress += 2.0*SpikeProgressUnits(fftlen)*ProgressUnitSize/NumFfts; } else { progress += SpikeProgressUnits(fftlen)*ProgressUnitSize/NumFfts; } } //progress = ((float)icfft)/num_cfft + ((float)ifft)/(NumFfts*num_cfft); progress = std::min(progress,1.0); #ifdef BOINC_APP_GRAPHICS if (!nographics()) { rarray.add_source_row(PowerSpectrum+fftlen*ifft); sah_graphics->local_progress = (((float)ifft+1)/NumFfts); } #endif remaining=1.0-(double)(icfft+1)/num_cfft; fraction_done(progress,remaining); // jeffc //fprintf(stderr, "S fft len %d progress = %12.10f\n", fftlen, progress); } // loop through chirped data array #ifdef BOINC_APP_GRAPHICS if (!nographics()) { memcpy(&sah_shmem->rarray_data, &rarray, sizeof(REDUCED_ARRAY_DATA)); } #endif fraction_done(progress,remaining); // jeffc //fprintf(stderr, "Sdone fft len %d progress = %12.10f\n", fftlen, progress); // transpose PoT matrix to make memory accesses nicer need_transpose = ChirpFftPairs[icfft].GaussFit || ChirpFftPairs[icfft].PulseFind; if ( !need_transpose ) { int tmpPulsePoTLen, tmpOverlap; GetPulsePoTLen( NumFfts, &tmpPulsePoTLen, &tmpOverlap ); if ( ! ( tmpPulsePoTLen > PoTInfo.TripletMax || tmpPulsePoTLen < PoTInfo.TripletMin ) ) need_transpose = true; } if (need_transpose && use_transposed_pot) { Transpose(fftlen, NumFfts, (float *) PowerSpectrum, (float *)tPowerSpectrum); } // // Analyze Power over Time. May return quickly if this FFT // length and/or this WUs slew rate places the data block // outside PoT analysis limits. // Counting flops is done inside analyze_pot retval = analyze_pot(tPowerSpectrum, NumDataPoints, ChirpFftPairs[icfft]); if (retval) SETIERROR(retval,"from analyze_pot"); #ifdef BOINC_APP_GRAPHICS // switch the display back to "best of" signals // if (!nographics()) { sah_graphics->gi.copy(best_gauss, true); sah_graphics->pi.copy(best_pulse, true); sah_graphics->ti.copy(best_triplet, true); } #endif // Force progress to 100% before calling result_group_end() to store // 100% in state file so it will survive exit & relaunch if (icfft == (num_cfft-1)) { progress = 1; remaining = 0; fraction_done(progress,remaining); } retval = checkpoint(); if (retval) SETIERROR(retval,"from checkpoint() in seti_analyse()"); } // loop over chirp/fftlen paris // Return the "best of" signals. This may include duplicates of // already reported interesting signals. if (best_spike->s.fft_len) { retval = outfile.printf("%s", best_spike->s.print_xml(0,0,1,"best_spike").c_str()); if (retval < 0) { SETIERROR(WRITE_FAILED,"from outfile.printf (best spike) in seti_analyze()"); } } if (best_autocorr->a.fft_len) { retval = outfile.printf("%s", best_autocorr->a.print_xml(0,0,1,"best_autocorr").c_str()); if (retval < 0) { SETIERROR(WRITE_FAILED,"from outfile.printf (best autocorr) in seti_analyze()"); } } if (best_gauss->g.fft_len || best_gauss->score) { retval = outfile.printf("%s", best_gauss->g.print_xml(0,0,1,"best_gaussian").c_str()); if (retval < 0) { SETIERROR(WRITE_FAILED,"from outfile.printf (best gaussian) in seti_analyze()"); } } if (best_pulse->p.fft_len) { retval = outfile.printf("%s", best_pulse->p.print_xml(0,0,1,"best_pulse").c_str()); if (retval < 0) { SETIERROR(WRITE_FAILED,"from outfile.printf (best pulse) in seti_analyze()"); } } if (best_triplet->t.fft_len) { retval = outfile.printf("%s", best_triplet->t.print_xml(0,0,1,"best_triplet").c_str()); if (retval < 0) { SETIERROR(WRITE_FAILED,"from outfile.printf (best triplet) in seti_analyze()"); } } retval=outfile.printf("" PACKAGE_VERSION "\n"); #ifdef BOINC_APP_GRAPHICS if (sah_graphics) strcpy(sah_graphics->status, "Work unit done"); #endif final_report(); // flop and signal counts to stderr retval = checkpoint(); // try a final checkpoint if (PowerSpectrum) free_a(PowerSpectrum); if (use_transposed_pot) free_a(tPowerSpectrum); #ifdef USE_IPP for (FftNum = 0; FftNum < swi.num_fft_lengths; FftNum++) { if (FftSpec[FftNum]) ippsFFTFree_C_32fc (FftSpec[FftNum]); } if (FftBuf) free_a(FftBuf); FftBuf = NULL; #elif !defined(USE_FFTWF) for (FftNum = 0; FftNum < swi.num_fft_lengths; FftNum++) { if (BitRevTab[FftNum]) free_a(BitRevTab[FftNum]); } for (FftNum = 0; FftNum < swi.num_fft_lengths; FftNum++) { if (CoeffTab[FftNum]) free_a(CoeffTab[FftNum]); } #endif if (WorkData) free_a(WorkData); WorkData = NULL; if (ChirpFftPairs) free(ChirpFftPairs); if ((app_init_data.host_info.m_nbytes == 0) || (app_init_data.host_info.m_nbytes >= MIN_TRIGARRAY_MEMORY)) { FreeTrigArray(); } // jeffc //retval = outfile.flush(); xml_indent(-2); outfile.printf("
"); outfile.close(); //if (retval) SETIERROR(WRITE_FAILED,"from outfile.fflush in seti_analyze()"); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return retval; } int v_BaseLineSmooth( sah_complex* DataIn, int NumDataPoints, int BoxCarLength, int NumPointsInChunk ) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("v_BaseLineSmooth"); #endif // We use a sliding boxcar method for baseline smoothing. Input data // is the time domain. It is transformed (using a separate array) // into the frequency domain. After baseline smoothing is done // in the frequency domain, it is transformed back into the time domain. int h, i, j, k; sah_complex* DataInChunk; static sah_complex *DataOutChunk=0; static float* PowerSpectrum=0; float Total, LocalMean, ScaleFactor,recipNumPointsInChunk=1.0/NumPointsInChunk; int NumTimeChunks, TimeChunk, Endpoint; static int OldNumPointsInChunk = 0; #ifdef USE_IPP static IppsFFTSpec_C_32fc* FftSpec = NULL; #elif defined(USE_FFTWF) static fftwf_plan backward_transform, forward_transform; #endif /* USE_FFTWF */ #ifndef USE_FFTWF static int * BitRevTab = NULL; static float * CoeffTab = NULL; #endif /* USE_FFTWF */ NumTimeChunks = (int)(NumDataPoints * recipNumPointsInChunk); // If we keep doing transforms that are the same length, don't reinitialize plans if (NumPointsInChunk != OldNumPointsInChunk) { if (OldNumPointsInChunk != 0) { #ifdef USE_IPP if (FftSpec) ippsFFTFree_C_32fc (FftSpec); #elif defined(USE_FFTWF) if (backward_transform) free_a(backward_transform); if (forward_transform) free_a(forward_transform); #else if (BitRevTab) free_a(BitRevTab); if (CoeffTab) free_a(CoeffTab); #endif if (PowerSpectrum) free_a(PowerSpectrum); if (DataOutChunk) free_a(DataOutChunk); } PowerSpectrum = (float*) calloc_a(NumPointsInChunk, sizeof(float), MEM_ALIGN); if (PowerSpectrum == NULL) { printf("Could not allocate Power Spectrum array in v_BaseLineSmooth()\n"); exit(1); } // Do the transforms in the DataOutChunk, since DataInChunk won't // necessarily be aligned correctly (and we won't get SIMD) // TODO: automatically make DataInChunk aligned correctly so we // don't need the memcpy. This may already be done if // NumPointsInChunk*sizeof(sah_complex) is a multiple of MEM_ALIGN DataOutChunk = (sah_complex *)malloc_a(NumPointsInChunk * sizeof(sah_complex),MEM_ALIGN); OldNumPointsInChunk = NumPointsInChunk; #ifdef USE_IPP int order = 0; for (int tmp = NumPointsInChunk; !(tmp & 1); order++) tmp >>= 1; ippsFFTInitAlloc_C_32fc (&FftSpec, order, IPP_FFT_NODIV_BY_ANY, ippAlgHintAccurate); #elif defined(USE_FFTWF) sah_complex *scratch = (sah_complex *)malloc_a(NumPointsInChunk * sizeof(sah_complex),MEM_ALIGN); #ifdef USE_MANUAL_CALLSTACK call_stack.enter("fftwf_plan_dft_1d()"); #endif backward_transform = fftwf_plan_dft_1d(NumPointsInChunk, scratch, DataOutChunk, FFTW_BACKWARD, FFTW_MEASURE_OR_ESTIMATE|FFTW_PRESERVE_INPUT); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); call_stack.enter("fftwf_plan_dft_1d()"); #endif forward_transform = fftwf_plan_dft_1d(NumPointsInChunk, DataOutChunk, DataOutChunk, FFTW_FORWARD, FFTW_MEASURE_OR_ESTIMATE); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif free_a(scratch); #else /* !USE_FFTWF */ BitRevTab = (int*) calloc_a(3+(int)sqrt((float)NumPointsInChunk/2), sizeof(int), MEM_ALIGN); if (BitRevTab == NULL) { #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return MALLOC_FAILED; } CoeffTab = (float*) calloc_a(NumPointsInChunk/2, sizeof(float), MEM_ALIGN); if (CoeffTab == NULL) { #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return MALLOC_FAILED; } // flag to tell cdft() to init it's work areas // already done since we used calloc_a(); // BitRevTab[0] = 0; #endif /* USE_FFTWF */ } for (TimeChunk = 0; TimeChunk < NumTimeChunks; TimeChunk++) { #ifdef BOINC_APP_GRAPHICS if (sah_graphics) sah_graphics->local_progress = (((float)TimeChunk)/NumTimeChunks); #endif DataInChunk = &(DataIn[TimeChunk*NumPointsInChunk]); #ifndef USE_FFTWF memcpy( DataOutChunk, DataInChunk, (int)(NumPointsInChunk*sizeof(sah_complex)) ); #endif // transform to freq #ifdef USE_IPP ippsFFTInv_CToC_32fc ((Ipp32fc*)DataOutChunk, (Ipp32fc*)DataOutChunk, FftSpec, NULL); #elif !defined(USE_FFTWF) cdft(NumPointsInChunk*2, 1, DataOutChunk, BitRevTab, CoeffTab); #else /* USE_FFTWF */ #ifdef USE_MANUAL_CALLSTACK call_stack.enter("fftwf_execute_dft()"); #endif fftwf_execute_dft(backward_transform,DataInChunk,DataOutChunk); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif #endif /* !USE_FFTWF */ GetPowerSpectrum( DataOutChunk, PowerSpectrum, NumPointsInChunk ); // Begin: normalize in freq. domain via sliding boxcar Endpoint = NumPointsInChunk / 2; i = Endpoint; // start i at lowest negative freq; // this is low point in first boxcar j = i + BoxCarLength / 2; // start j midpoint in first boxcar k = i + BoxCarLength; // start k at end of first boxcar; // thus a boxcar is i----j----k Total = 0; for (h = i; h < k; h++) { // Get mean for first boxcar Total += PowerSpectrum[h]; } LocalMean = Total / BoxCarLength; ScaleFactor = (float)(1.0/sqrt(LocalMean * 0.5)); // normalize 1st half of 1st boxcar for (h = i; h < j; h++) { DataOutChunk[h][0] *= ScaleFactor; DataOutChunk[h][1] *= ScaleFactor; } for (; k != Endpoint; i++, j++, k++) { // sliding boxcar if (k == NumPointsInChunk) { // take care of wrapping k = 0; } if (j == NumPointsInChunk) { j = 0; } if (i == NumPointsInChunk) { i = 0; } LocalMean = LocalMean - PowerSpectrum[i] / BoxCarLength + PowerSpectrum[k] / BoxCarLength; ScaleFactor = (float)(1.0/sqrt(LocalMean * 0.5)); DataOutChunk[j][0] *= ScaleFactor; DataOutChunk[j][1] *= ScaleFactor; } // End sliding boxcar // normalize final half of final boxcar for (h = j; h < k; h++) { DataOutChunk[h][0] *= ScaleFactor; DataOutChunk[h][1] *= ScaleFactor; } // End: normalize in freq. domain via sliding boxcar // transform back to time #ifdef USE_IPP ippsFFTFwd_CToC_32fc((Ipp32fc*)DataOutChunk, (Ipp32fc*)DataOutChunk, FftSpec, NULL); #elif !defined(USE_FFTWF) cdft(NumPointsInChunk*2, -1, DataOutChunk, BitRevTab, CoeffTab); #else #ifdef USE_MANUAL_CALLSTACK call_stack.enter("fftwf_execute()"); #endif fftwf_execute(forward_transform); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif #endif analysis_state.FLOP_counter+=10.0*NumPointsInChunk*log((double)NumPointsInChunk)/log(2.0)+10.0*NumPointsInChunk; // return powers to normal for (i = 0; i < NumPointsInChunk; i++) { DataInChunk[i][0] = DataOutChunk[i][0]*recipNumPointsInChunk; DataInChunk[i][1] = DataOutChunk[i][1]*recipNumPointsInChunk; } } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } int v_GetPowerSpectrum( sah_complex* FreqData, float* PowerSpectrum, int NumDataPoints ) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("v_GetPowerSpectrum()"); #endif int i; #ifdef __INTEL_COMPILER #pragma message ("---using ICC---") #pragma vector aligned __assume_aligned (FreqData, MEM_ALIGN); #endif analysis_state.FLOP_counter+=3.0*NumDataPoints; for (i = 0; i < NumDataPoints; i++) { PowerSpectrum[i] = FreqData[i][0] * FreqData[i][0] + FreqData[i][1] * FreqData[i][1]; } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } // chirp_rate is in Hz per second #ifndef USE_INTEL_OPT_CODE int v_ChirpData( sah_complex* cx_DataArray, sah_complex* cx_ChirpDataArray, int chirp_rate_ind, double chirp_rate, int ul_NumDataPoints, double sample_rate ) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("v_ChirpData()"); #endif int i; double recip_sample_rate=1.0/sample_rate; #ifdef DEBUG fprintf(stderr, "icfft = %6d crate index = %6d\n", icfft, chirp_rate_ind); fflush(stderr); #endif if (chirp_rate_ind == 0) { memcpy(cx_ChirpDataArray, cx_DataArray, (int)ul_NumDataPoints * sizeof(sah_complex) ); // NOTE INT CAST } else { // what we do depends on how much memory we have... // If we have more than 64MB, we'll cache the chirp table. If not // we'll calculate it each time. bool CacheChirpCalc=((app_init_data.host_info.m_nbytes == 0) || (app_init_data.host_info.m_nbytes >= MIN_TRIGARRAY_MEMORY)); // calculate trigonometric array // this function returns w/o doing nothing when sign of chirp_rate_ind // reverses. so we have to take care of it. if (CacheChirpCalc) CalcTrigArray(ul_NumDataPoints, chirp_rate_ind); for (i = 0; i < ul_NumDataPoints; i++) { float c, d, real, imag; if (CacheChirpCalc) { c = CurrentTrig[i].Cos; d = (chirp_rate_ind >0)? CurrentTrig[i].Sin : -CurrentTrig[i].Sin; } else { double dd,cc; double time=static_cast(i)*recip_sample_rate; // since ang is getting moded by 2pi, we calculate "ang mod 2pi" // before the call to sincos() inorder to reduce roundoff error. // (Bug submitted by Tetsuji "Maverick" Rai) double ang = 0.5*chirp_rate*time*time; ang -= floor(ang); ang *= M_PI*2; sincos(ang,&dd,&cc); c=cc; d=dd; } // Sometimes chirping is done in place. // We don't want to overwrite data prematurely. real = cx_DataArray[i][0] * c - cx_DataArray[i][1] * d; imag = cx_DataArray[i][0] * d + cx_DataArray[i][1] * c; cx_ChirpDataArray[i][0] = real; cx_ChirpDataArray[i][1] = imag; } analysis_state.FLOP_counter+=12.0*ul_NumDataPoints; } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } #endif // USE_INTEL_OPT_CODE // Trigonometric arrays functions // These functions makes trigonometric arrays very quickly and // will speed up v_ChirpData() // by Tetsuji "Maverick" Rai // initialize TrigStep and CurrentTrig void InitTrigArray(int len, double ChirpStep, int InitChirpRateInd, double SampleRate) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("InitTrigArray()"); #endif int i; double ang, Coef; TrigStep = (SinCosArray*) malloc_a (len * sizeof(SinCosArray), MEM_ALIGN); if (TrigStep == NULL) SETIERROR(MALLOC_FAILED, "TrigStep == NULL"); CurrentTrig = (SinCosArray*) malloc_a (len * sizeof(SinCosArray), MEM_ALIGN); if (CurrentTrig == NULL) SETIERROR(MALLOC_FAILED, "CurrentTrig == NULL"); // Make ChirpStep array Coef = ChirpStep / (SampleRate*SampleRate); for (i = 0; i < len; i++) { // since ang is getting cast to a float, we calculate "ang mod 2pi" // before the call to sincosf() inorder to reduce roundoff error. // (Bug submitted by Tetsuji "Maverick" Rai) // addition: now it's used as double float, but this bug fix // is still preferable ang = 0.5*(double)i*(double)i*Coef; ang -= floor(ang); ang *= 2*M_PI; sincos(ang, &TrigStep[i].Sin, &TrigStep[i].Cos); } // Set initial trigonometric array if ((CurrentChirpRateInd = abs(InitChirpRateInd)) != 0) { Coef = CurrentChirpRateInd*ChirpStep / (SampleRate*SampleRate); for (i = 0; i < len; i++) { ang = 0.5*(double)i*(double)i*Coef; ang -= floor(ang); ang *= 2*M_PI; sincos(ang, &CurrentTrig[i].Sin, &CurrentTrig[i].Cos); } } else { // if it starts from the beginning, it's quite simple for (i = 0; i < len; i++) { CurrentTrig[i].Sin = 0.; CurrentTrig[i].Cos = 1.0; } } } // calculate next CurrentTrig void CalcTrigArray (int len, int ChirpRateInd) { double SinX, CosX, SinS, CosS; int TempCRateInd = abs(ChirpRateInd); int i, j; // skip automatically when TempCRateInd == CurrentChirpRateInd // (it happens when sign of chirprate reverses) // Otherwise // sin(x+step) = sin(x)*cos(step) + cos(x)*sin(step) // cos(x+step) = cos(x)*cos(step) - sin(x)*sin(step) // In most cases index increases by 1, and in the later phase of a WU // by 4 at most in reference WU, but it's 2-3 times faster than // sincos() function on P4 with gcc or icc. When index increases by 1, // this is about 10 times as fast as sincos() // JWS: Modified so when index increases by more than one, the two 16 MiB // arrays are only loaded once. The index can increase by as much as 16. // #ifdef DEBUG fprintf(stderr, " New ind = %6d (abs(%6d)) Previous = %6d\n", ChirpRateInd, TempCRateInd, CurrentChirpRateInd); fflush(stderr); #endif switch ( TempCRateInd - CurrentChirpRateInd ) { case 0: #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return; // replaces "automatic skip" case 1: for ( j = 0; j < len; j++ ) { SinX = CurrentTrig[j].Sin; CosX = CurrentTrig[j].Cos; SinS = TrigStep[j].Sin; CosS = TrigStep[j].Cos; CurrentTrig[j].Sin = SinX * CosS + CosX * SinS; CurrentTrig[j].Cos = CosX * CosS - SinX * SinS; } break; case 2: // unroll once to avoid 50/50 inner loop for ( j = 0; j < len; j++ ) { double SinTmp, CosTmp; SinX = CurrentTrig[j].Sin; CosX = CurrentTrig[j].Cos; SinS = TrigStep[j].Sin; CosS = TrigStep[j].Cos; SinTmp = SinX * CosS + CosX * SinS; CosTmp = CosX * CosS - SinX * SinS; CurrentTrig[j].Sin = SinTmp * CosS + CosTmp * SinS; CurrentTrig[j].Cos = CosTmp * CosS - SinTmp * SinS; } break; default: // 3 or more for ( j = 0; j < len; j++ ) { for ( i = CurrentChirpRateInd; i < TempCRateInd; i++ ) { SinX = CurrentTrig[j].Sin; CosX = CurrentTrig[j].Cos; SinS = TrigStep[j].Sin; CosS = TrigStep[j].Cos; CurrentTrig[j].Sin = SinX * CosS + CosX * SinS; CurrentTrig[j].Cos = CosX * CosS - SinX * SinS; } } break; } CurrentChirpRateInd = TempCRateInd; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } // free TrigStep and CurrentTrig void FreeTrigArray() { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("FreeTrigArray()"); #endif if (TrigStep) free_a(TrigStep); TrigStep = NULL; if (CurrentTrig) free_a(CurrentTrig); CurrentTrig = NULL; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } template inline void v_subTranspose(float * __restrict in, float * __restrict out, int xline, int yline) { #ifdef USE_MANUAL_CALLSTACK static char name_buf[64]; sprintf(name_buf,"v_subtranspose<%d>()",x); call_stack.enter(name_buf); #endif // Transpose an X by X subsection of a XLINE by YLINE matrix into the // appropriate part of a YLINE by XLINE matrix. "IN" points to the first // (lowest address) element of the input submatrix. "OUT" points to the // first (lowest address) element of the output submatrix. int i,j; float *p; register float tmp[x*x]; for (j=0;j(in+j*x+i,out+y*i+j,x,y); } for (;i(in+j*x+i,out+y*i+j,x,y); } for (;i(in+j*x+i,out+y*i+j,x,y); } for (;i(in+j*x+i,out+y*i+j,x,y); } for (;i(in+j*x+i,out+y*i+j,x,y); } for (;i(in+j*x+i,out+y*i+j,x,y); } for (;i(in+j*x+i,out+y*i+j,x,y); } for (;i(in+j*x+i,out+y*i+j,x,y); } for (;i(in+j*x+i,out+y*i+j,x,y); } for (;i(in+j*x+i,out+y*i+j,x,y); } for (;i> 1) & 0x55555555); x = (((x >> 2) & 0x33333333) + (x & 0x33333333)); x = (((x >> 4) + x) & 0x0f0f0f0f); x += (x >> 8); x += (x >> 16); return(x & 0x0000003f); #endif } inline uint32_t ilog2(int32_t n) { register int32_t rv=-1; if (n) { #if defined(HAVE___BUILTIN_CLZ) rv=(CHAR_BIT*sizeof(n))-__builtin_clz(n)-1; #else n |= (n >> 1); n |= (n >> 2); n |= (n >> 4); n |= (n >> 8); n |= (n >> 16); rv=(ones32(n >> 1)); #endif } return rv; } int fftwf_transpose(int x, int y, float *in, float *out) { int i; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("fftwf_transpose"); #endif i=ilog2(x)-3; fftwf_execute_r2r(transpose_plans[i], in, out); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } boinc-app-seti_8.00~svn3701.orig/client/gdata.h0000644000175000017500000001144211516176217021232 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // $Id: gdata.h,v 1.16.2.5 2007/05/31 22:03:10 korpela Exp $ // GDATA is a collection of information generated by the worker thread // that might be useful for graphics. // It does not contain any user preference info, // or anything related to a particular style of graphics. #ifndef _GDATA_ #define _GDATA_ #include "sah_version.h" #include "reduce.h" #ifndef AP_CLIENT #include "analyze.h" #include struct GAUSS_INFO; struct SPIKE_INFO; struct AUTOCORR_INFO; struct TRIPLET_INFO; struct PULSE_INFO; // Power of time array sizes for graphics routines only. #define GAUSS_POT_LEN 64 #define PULSE_POT_LEN 256 #define TRIPLET_POT_LEN 256 struct FFT_INFO { double chirp_rate; int fft_len; }; struct G_AUTOCORR_INFO { void copy(AUTOCORR_INFO *, bool is_best=false); }; struct G_SPIKE_INFO { void copy(SPIKE_INFO *, bool is_best=false); }; struct G_GAUSS_INFO { double score; bool is_best; // true if best score so far bool dirty; // true if we haven't displayed this yet double peak_power; double mean_power; double chisqr; double sigma; int fft_ind; // assigned in ReportGaussEvent() float pot[GAUSS_POT_LEN]; void copy(GAUSS_INFO *, bool is_best=false); G_GAUSS_INFO() : score(0), is_best(false), dirty(false), peak_power(0), mean_power(0), chisqr(0), sigma(0), fft_ind(0) { memset(pot,0,sizeof(pot)); }; }; struct G_TRIPLET_INFO { double peak_power; double period; bool is_best; bool dirty; int tpotind0_0; // index into pot_min/pot_max arrays int tpotind0_1; // of start/end of first element of triplet int tpotind1_0; // second element int tpotind1_1; int tpotind2_0; // and third element int tpotind2_1; unsigned int pot_min[TRIPLET_POT_LEN]; // Scaled 0-255 for display unsigned int pot_max[TRIPLET_POT_LEN]; // Scaled 0-255 for display void copy(TRIPLET_INFO *, bool is_best=false); G_TRIPLET_INFO() : peak_power(0), period(0), is_best(false), dirty(false), tpotind0_0(0), tpotind0_1(0), tpotind1_0(0), tpotind1_1(0), tpotind2_0(0), tpotind2_1(0) { memset(pot_min,0,sizeof(pot_min)); memset(pot_max,0,sizeof(pot_max)); } }; struct G_PULSE_INFO { bool is_best; bool dirty; double peak_power; double period; double score; unsigned int pot_max[PULSE_POT_LEN]; // Scaled 0-255 for display void copy(PULSE_INFO *, bool is_best=false); G_PULSE_INFO() : is_best(false), dirty(false), peak_power(0), period(0), score(0) { memset(pot_max,0,sizeof(pot_max)); } }; #endif struct G_SETI_WU_INFO { char receiver_name[255]; int s4_id; double time_recorded; double subband_base; double start_ra, start_dec; double subband_sample_rate; }; struct GDATA { int ready; int version_major; int version_minor; double local_progress; double progress; double cpu_time; volatile int countdown; // the graphics app sets this to 5 every second, // and the main app decrements it every second. // So if it's zero, it means no graphics app is running char status[80]; #ifndef AP_CLIENT G_SETI_WU_INFO wu; FFT_INFO fft_info; G_SPIKE_INFO si; G_AUTOCORR_INFO ai; G_GAUSS_INFO gi; G_TRIPLET_INFO ti; G_PULSE_INFO pi; #endif }; // SAH_SHMEM is the shared-memory structure struct SAH_SHMEM { GDATA gdata; REDUCED_ARRAY_DATA rarray_data; }; #endif boinc-app-seti_8.00~svn3701.orig/client/fft8g.h0000644000175000017500000000103112321065336021153 0ustar locutuslocutus// This code is from the General Purpose FFT (Fast Fourier/Cosine/Sine Transform) Package. // Copyright Takuya OOURA, 1996-2001 // (Email: ooura@kurims.kyoto-u.ac.jp or ooura@mmm.t.u-tokyo.ac.jp) // // You may use, copy, modify and distribute this code for any purpose // (include commercial use) and without fee. Please refer to this package // when you modify this code. // $Id: fft8g.h,v 1.3.2.1 2005/05/19 00:42:30 korpela Exp $ void cdft(int, int, sah_complex *, int *, float *); void ddct(int, int, float *, int *, float *); boinc-app-seti_8.00~svn3701.orig/client/Makefile.in.graphics0000644000175000017500000001036410671336410023641 0ustar locutuslocutus# $Id: Makefile.in.graphics,v 1.4.2.1 2006/12/14 22:21:43 korpela Exp $ # # @SET_MAKE@ EXEEXT = @EXEEXT@ OBJEXT = @OBJEXT@ LIBEXT = @LIBEXT@ DLLEXT = @DLLEXT@ DOTEXEEXT = @DOTEXEEXT@ SUFFIXES = .cpp .c .@OBJEXT@ .@DLLEXT@ .@LIBEXT@ @DOTEXEEXT@ VERSION_MAJOR = @MAJOR_VERSION@ VERSION_MINOR = @MINOR_VERSION@ BOINCDIR = @BOINCDIR@ CC = @CC@ CFLAGS = @CFLAGS@ @DEFS@ -DTEXT_UI -DNDEBUG -DCLIENT -DBOINC_APP_GRAPHICS CXX = @CXX@ CXXFLAGS = $(CFLAGS) BOINC_INC= -I$(BOINCDIR)/api -I$(BOINCDIR)/lib -I$(BOINCDIR)/image_libs/ -I/usr/openwin/share/include/ -I../jpeglib .cpp.@OBJEXT@: $(CXX) -g $(CXXFLAGS) $(BOINC_INC) -I.. -I../db -c -o $*.@OBJEXT@ $< .C.@OBJEXT@: $(CXX) -g $(CXXFLAGS) $(BOINC_INC) -I.. -I../db -c -o $*.@OBJEXT@ $< .c.@OBJEXT@: $(CC) -g $(CFLAGS) $(BOINC_INC) -I.. -I../db -c -o $*.@OBJEXT@ $< LDFLAGS = @LDFLAGS@ CLIBS = @LIBS@ SUFFIXES = .cpp .@OBJEXT@ PROG = setiathome-$(VERSION_MAJOR).$(VERSION_MINOR).@host@$(DOTEXEEXT) GUIPROG = xsetiathome-$(VERSION_MAJOR).$(VERSION_MINOR).@host@$(DOTEXEEXT) PROGS = $(PROG) setiathome_test$(DOTEXEEXT) ../aclocal.m4: ../m4/*.m4 @CAT@ ../m4/*.m4 >../aclocal.m4 ../configure: ../configure.ac ../aclocal.m4 ../sah_config.h.in (cd ..; make sah_config.h) OBJS = \ analyzeFuncs.$(OBJEXT) \ analyzeReport.$(OBJEXT) \ analyzePoT.$(OBJEXT) \ pulsefind.$(OBJEXT) \ gaussfit.$(OBJEXT) \ lcgamm.$(OBJEXT) \ malloc_a.$(OBJEXT) \ seti.$(OBJEXT) \ seti_header.$(OBJEXT) \ timecvt.$(OBJEXT) \ s_util.$(OBJEXT) \ version.$(OBJEXT) \ worker.$(OBJEXT) \ chirpfft.$(OBJEXT) \ spike.$(OBJEXT) \ progress.$(OBJEXT) \ ../db/schema_master_client.$(OBJEXT) \ ../db/sqlrow_client.$(OBJEXT) \ ../db/sqlblob.$(OBJEXT) \ ../db/xml_util.$(OBJEXT) BOINC_OBJS = -L$(BOINCDIR)/lib -lboinc GUIOBJS = \ analyzeFuncs.$(OBJEXT) \ analyzeReport.$(OBJEXT) \ analyzePoT.$(OBJEXT) \ pulsefind.$(OBJEXT) \ gaussfit.$(OBJEXT) \ lcgamm.$(OBJEXT) \ malloc_a.$(OBJEXT) \ seti.$(OBJEXT) \ seti_header.$(OBJEXT) \ timecvt.$(OBJEXT) \ s_util.$(OBJEXT) \ version.$(OBJEXT) \ worker.$(OBJEXT) \ chirpfft.$(OBJEXT) \ spike.$(OBJEXT) \ progress.$(OBJEXT) \ sah_gfx_base.$(OBJEXT) \ sah_gfx.$(OBJEXT) \ gdata.$(OBJEXT) \ ../db/schema_master_client.$(OBJEXT) \ ../db/sqlrow_client.$(OBJEXT) \ ../db/sqlblob.$(OBJEXT) \ ../db/xml_util.$(OBJEXT) GUILIBS = -lX11 -lXmu @GRXLIBS@ -L../jpeglib/ -ljpeg -L/usr/X11R6/lib -L/usr/openwin/lib/ -lGL -lGLU -lglut \ -L../../boinc/api -lboinc_api -lboinc_graphics_api LIBS = -L. \ -looura all: Makefile dependencies $(GUIPROG) clean: rm -f *.$(OBJEXT) libooura.$(LIBEXT) $(PROGS) dependencies config.log config.cache OOURAOBS = fft8g.$(OBJEXT) libooura.$(LIBEXT): $(OOURAOBS) @AR@ r libooura.$(LIBEXT) $(OOURAOBS) @RANLIB@ libooura.$(LIBEXT) $(PROG): main.$(OBJEXT) libooura.$(LIBEXT) $(OBJS) $(CXX) main.$(OBJEXT) $(OBJS) $(LIBS) $(CLIBS) -o $(PROG) $(BOINC_OBJS) strip $(PROG) $(GUIPROG): main.$(OBJEXT) $(GUIOBJS) libooura.$(LIBEXT) $(CXX) main.$(OBJEXT) ../../boinc/api/gutil.$(OBJEXT) ../../boinc/api/reduce.$(OBJEXT) $(GUIOBJS) $(GUILIBS) $(LIBS) $(CLIBS) -lpthread -o $(GUIPROG).debug $(BOINC_OBJS) cp $(GUIPROG).debug $(GUIPROG) strip $(GUIPROG) # The following is because version.$(OBJEXT) depends on # VERSION_MAJOR and VERSION_MINOR, defined in the Makefile. # Is there a cleaner way of doing this? version.$(OBJEXT): version.cpp ../sah_config.h version.h main_test.$(OBJEXT): main.cpp $(CXX) $(CXXFLAGS) $(BOINC_INC) -I.. -I../db -DTEST_VERSION -c -o main_test.$(OBJEXT) main.cpp setiathome_test$(DOTEXEEXT): main_test.$(OBJEXT) $(OBJS) libooura.$(LIBEXT) $(CXX) main_test.$(OBJEXT) $(OBJS) $(LIBS) $(CLIBS) -o setiathome_test$(DOTEXEEXT) $(BOINC_OBJS) ../db/sqlrow_client.$(OBJEXT): ../db/sqlrow.cpp ../db/sqlrow.h (cd ../db; $(MAKE) sqlrow_client.$(OBJEXT)) ../db/schema_master_client.$(OBJEXT): ../db/schema_master.cpp ../db/db_table.h (cd ../db; $(MAKE) schema_master_client.$(OBJEXT)) ../db/schema_master.cpp: ../db/schema_master.sql ../db/schema_to_class.awk (cd ../db; $(MAKE) schema_master.cpp) dependencies: ../sah_config.h *.cpp Makefile $(CXX) $(CXXFLAGS) -I.. -I/ -I../db $(BOINC_INC) -M *.cpp > dependencies include dependencies boinc-app-seti_8.00~svn3701.orig/client/vector/0000755000175000017500000000000013155506323021275 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/client/vector/analyzeFuncs_sse.cpp0000644000175000017500000034152212321065336025322 0ustar locutuslocutus // Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // $Id: analyzeFuncs_sse.cpp,v 1.1.2.10 2007/06/08 03:09:47 korpela Exp $ // // This file is empty is __i386__ is not defined #include "sah_config.h" #include #include #if defined(__i386__) || defined(__x86_64__) || defined(USE_SSE) #define INVALID_CHIRP 2e+20 #include "analyzeFuncs.h" #include "analyzeFuncs_vector.h" #include "analyzePoT.h" #include "analyzeReport.h" #include "gaussfit.h" #include "s_util.h" #include "diagnostics.h" #include "asmlib.h" #include "pulsefind.h" #include "x86_ops.h" #include "x86_float4.h" static bool checked=false; static bool hasSSE=false; bool boinc_has_sse( void ) { #ifdef USE_ASMLIB static bool hasSSE = (InstructionSet() >= 3) ? true : false; return hasSSE; #else return true; #endif } template inline void v_pfsubTranspose(float *in, float *out, int xline, int yline) { // Transpose an X by X subsection of a XLINE by YLINE matrix into the // appropriate part of a YLINE by XLINE matrix. "IN" points to the first // (lowest address) element of the input submatrix. "OUT" points to the // first (lowest address) element of the output submatrix. #ifdef USE_MANUAL_CALLSTACK static char name[64]; if (name[0]==0) sprintf(name,"v_pfsubTranspose<%d>()",x); call_stack.enter(name); #endif int i,j; float *p; register float tmp[x*x]; for (j=0;j(in+j*x+i,out+y*i+j,x,y); } for (;i(in+j*x+i,out+y*i+j,x,y); } for (;i(in+j*x+i,out+y*i+j,x,y); } for (;i(in+j*x+i,out+y*i+j,x,y); } for (;i(in+j*x+i,out+y*i+j,x,y); } for (;i(in+j*x+i,out+y*i+j,x,y); } for (;i(in+j*x+i,out+y*i+j,x,y); } for (;i(in+j*x+i,out+y*i+j,x,y); } for (;i(in+j*x+i,out+y*i+j,x,y); } for (;i(in+j*x+i,out+y*i+j,x,y); } for (;i(in, out, xline, yline); #endif prefetcht0(in+0*xline+4); prefetcht0(in+1*xline+4); prefetcht0(in+2*xline+4); prefetcht0(in+3*xline+4); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } int v_vTranspose4(int x, int y, float *in, float *out) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("v_vTranspose4()"); #endif int i,j; for (j=0;j(in+j*x+i,out+y*i+j,x,y); } for (;i(in+j*x+i,out+y*i+j,x,y); } for (;i(in, out, xline, yline); #endif #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } int v_vTranspose4np(int x, int y, float *in, float *out) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("v_vTranspose4np()"); #endif int i,j; for (j=0;j= 0.0) ? TWO_TO_52 : -TWO_TO_52; #else // For X87 FPU double roundVal = (srate >= 0.0) ? ROUNDX87 : -ROUNDX87; #endif int i, vEnd; unsigned short fpucw1, fpucw2; // main vectorised loop vEnd = ul_NumDataPoints - (ul_NumDataPoints & 7); for (i = 0; i < vEnd; i += 8) { const float *data = (const float *) (fp_DataArray + i); float *chirped = (float *) (fp_ChirpDataArray + i); double angles[8], dtemp; ALIGNED(float, 16) v_angle[4], v_angle2[4]; // float __attribute__ ((aligned (16))) v_angle[4], v_angle2[4]; __m128 d1, d2; __m128 cd1, cd2, cd3; __m128 td1, td2; __m128 x; __m128 y; __m128 s; __m128 c; __m128 m; prefetchnta((const void *)( data+32 )); dtemp = double( i ); angles[0] = dtemp+0.0; angles[1] = dtemp+1.0; angles[2] = dtemp+2.0; angles[3] = dtemp+3.0; angles[4] = dtemp+4.0; angles[5] = dtemp+5.0; angles[6] = dtemp+6.0; angles[7] = dtemp+7.0; // calculate the input angle angles[0] *= angles[0] * srate; // angle^2 * rate angles[1] *= angles[1] * srate; angles[2] *= angles[2] * srate; angles[3] *= angles[3] * srate; angles[4] *= angles[4] * srate; angles[5] *= angles[5] * srate; angles[6] *= angles[6] * srate; angles[7] *= angles[7] * srate; // reduce the angle to the range (-0.5, 0.5) // convert doubles into singles // This does "angles - round(angles)" set_extended_precision(); set_up_fastfrac(roundVal); v_angle[0] = fastfrac(angles[0],roundVal); v_angle[1] = fastfrac(angles[1],roundVal); v_angle[2] = fastfrac(angles[2],roundVal); v_angle[3] = fastfrac(angles[3],roundVal); v_angle2[0] = fastfrac(angles[4],roundVal); v_angle2[1] = fastfrac(angles[5],roundVal); v_angle2[2] = fastfrac(angles[6],roundVal); v_angle2[3] = fastfrac(angles[7],roundVal); clean_up_fastfrac(); restore_fpucw(); x = _mm_load_ps( v_angle ); // square to the range [0, 0.25) y = _mm_mul_ps(x, x); // perform the initial polynomial approximations s = _mm_mul_ps(y, SS4); c = _mm_mul_ps(y, CC3); s = _mm_add_ps(s, SS3); c = _mm_add_ps(c, CC2); s = _mm_mul_ps(s, y); c = _mm_mul_ps(c, y); s = _mm_add_ps(s, SS2); c = _mm_add_ps(c, CC1); s = _mm_mul_ps(s, y); c = _mm_mul_ps(c, y); s = _mm_add_ps(s, SS1); s = _mm_mul_ps(s, x); c = _mm_add_ps(c, ONE); // perform first angle doubling cd1 = _mm_mul_ps(s, c); cd2 = _mm_mul_ps(c, c); cd3 = _mm_mul_ps(s, s); y = _mm_mul_ps(cd1, TWO); x = _mm_sub_ps(cd2, cd3); // load the signal to be chirped d1 = _mm_load_ps(data); d2 = _mm_load_ps(data+4); // calculate scaling factor to correct the magnitude // m1 = vec_nmsub(y1, y1, vec_nmsub(x1, x1, TWO)); // m2 = vec_nmsub(y2, y2, vec_nmsub(x2, x2, TWO)); cd1 = _mm_mul_ps(x, y); cd2 = _mm_mul_ps(x, x); cd3 = _mm_mul_ps(y, y); m = vec_recip1(_mm_add_ps(cd2, cd3 )); //scaling factor // perform second angle doubling s = _mm_mul_ps(cd1, TWO); c = _mm_sub_ps(cd2, cd3); // correct the magnitude (final sine / cosine approximations) c = _mm_mul_ps(c, m); s = _mm_mul_ps(s, m); x = d1; y = d2; x = _mm_shuffle_ps(x, x, 0xB1); y = _mm_shuffle_ps(y, y, 0xB1); x = _mm_mul_ps(x, R_NEG); y = _mm_mul_ps(y, R_NEG); cd1 = _mm_shuffle_ps(c, c, 0x50); // 01 01 00 00 AaBb => BBbb => c3c3c4c4 cd2 = _mm_shuffle_ps(c, c, 0xfa); // 11 11 10 10 AaBb => AAaa => c1c1c2c2 td1 = _mm_shuffle_ps(s, s, 0x50); td2 = _mm_shuffle_ps(s, s, 0xfa); cd1 = _mm_mul_ps(cd1, d1); cd2 = _mm_mul_ps(cd2, d2); td1 = _mm_mul_ps(td1, x); td2 = _mm_mul_ps(td2, y); cd1 = _mm_add_ps(cd1, td1); cd2 = _mm_add_ps(cd2, td2); // store chirped values _mm_stream_ps(chirped+0, cd1); _mm_stream_ps(chirped+4, cd2); // Retrieve second set of reduced angles x = _mm_load_ps( v_angle2 ); // square to the range [0, 0.25) y = _mm_mul_ps(x, x); // perform the initial polynomial approximations s = _mm_mul_ps(y, SS4); c = _mm_mul_ps(y, CC3); s = _mm_add_ps(s, SS3); c = _mm_add_ps(c, CC2); s = _mm_mul_ps(s, y); c = _mm_mul_ps(c, y); s = _mm_add_ps(s, SS2); c = _mm_add_ps(c, CC1); s = _mm_mul_ps(s, y); c = _mm_mul_ps(c, y); s = _mm_add_ps(s, SS1); s = _mm_mul_ps(s, x); c = _mm_add_ps(c, ONE); // perform first angle doubling cd1 = _mm_mul_ps(s, c); cd2 = _mm_mul_ps(c, c); cd3 = _mm_mul_ps(s, s); y = _mm_mul_ps(cd1, TWO); x = _mm_sub_ps(cd2, cd3); // load the signal to be chirped d1 = _mm_load_ps(data+8); d2 = _mm_load_ps(data+12); // calculate scaling factor to correct the magnitude // m1 = vec_nmsub(y1, y1, vec_nmsub(x1, x1, TWO)); // m2 = vec_nmsub(y2, y2, vec_nmsub(x2, x2, TWO)); cd1 = _mm_mul_ps(x, y); cd2 = _mm_mul_ps(x, x); cd3 = _mm_mul_ps(y, y); m = vec_recip1(_mm_add_ps(cd2, cd3 )); //scaling factor // perform second angle doubling s = _mm_mul_ps(cd1, TWO); c = _mm_sub_ps(cd2, cd3); // correct the magnitude (final sine / cosine approximations) c = _mm_mul_ps(c, m); s = _mm_mul_ps(s, m); x = d1; y = d2; x = _mm_shuffle_ps(x, x, 0xB1); y = _mm_shuffle_ps(y, y, 0xB1); x = _mm_mul_ps(x, R_NEG); y = _mm_mul_ps(y, R_NEG); cd1 = _mm_shuffle_ps(c, c, 0x50); // 01 01 00 00 AaBb => BBbb => c3c3c4c4 cd2 = _mm_shuffle_ps(c, c, 0xfa); // 11 11 10 10 AaBb => AAaa => c1c1c2c2 td1 = _mm_shuffle_ps(s, s, 0x50); td2 = _mm_shuffle_ps(s, s, 0xfa); cd1 = _mm_mul_ps(cd1, d1); cd2 = _mm_mul_ps(cd2, d2); td1 = _mm_mul_ps(td1, x); td2 = _mm_mul_ps(td2, y); cd1 = _mm_add_ps(cd1, td1); cd2 = _mm_add_ps(cd2, td2); // store chirped values _mm_stream_ps(chirped+8, cd1); _mm_stream_ps(chirped+12, cd2); } _mm_sfence(); if ( i < ul_NumDataPoints) { // use original routine to finish up any tailings (max stride-1 elements) v_ChirpData(fp_DataArray+i, fp_ChirpDataArray+i , ChirpRateInd, ChirpRate, ul_NumDataPoints-i, sample_rate); } analysis_state.FLOP_counter+=12.0*ul_NumDataPoints; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } /*************************************************** * * Alternate chirp function using Faster SinCos and Estrin method * for polynomial calculations. Derived from version 8 Alex Kan code. */ int sse1_ChirpData_ak8e( sah_complex * fp_DataArray, sah_complex * fp_ChirpDataArray, int ChirpRateInd, double ChirpRate, int ul_NumDataPoints, double sample_rate ) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("sse1_ChirpData_ak8e()"); #endif if (ChirpRateInd == 0) { memcpy(fp_ChirpDataArray, fp_DataArray, (int)ul_NumDataPoints * sizeof(sah_complex) ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } double srate = ChirpRate * 0.5 / (sample_rate * sample_rate); #if defined(_LP64) || defined(_WIN64) || (defined(__GNUC__) && defined(__SSE_MATH__)) // For scalar XMM code or any FPU with 64 bit registers double roundVal = (srate >= 0.0) ? TWO_TO_52 : -TWO_TO_52; #else // For X87 FPU double roundVal = (srate >= 0.0) ? ROUNDX87 : -ROUNDX87; #endif int i, vEnd; unsigned short fpucw1, fpucw2; // main vectorised loop vEnd = ul_NumDataPoints - (ul_NumDataPoints & 7); for (i = 0; i < vEnd; i += 8) { const float *data = (const float *) (fp_DataArray + i); float *chirped = (float *) (fp_ChirpDataArray + i); double angles[8], dtemp; ALIGNED(float, 16) v_angle[4], v_angle2[4]; __m128 d1, d2; __m128 cd1, cd2, cd3; __m128 td1, td2; __m128 v; __m128 w; __m128 x; __m128 y; __m128 z; __m128 s; __m128 c; __m128 m; prefetchnta((const void *)( data+32 )); dtemp = double( i ); angles[0] = dtemp+0.0; angles[1] = dtemp+1.0; angles[2] = dtemp+2.0; angles[3] = dtemp+3.0; angles[4] = dtemp+4.0; angles[5] = dtemp+5.0; angles[6] = dtemp+6.0; angles[7] = dtemp+7.0; // calculate the input angle angles[0] *= angles[0] * srate; // angle^2 * rate angles[1] *= angles[1] * srate; angles[2] *= angles[2] * srate; angles[3] *= angles[3] * srate; angles[4] *= angles[4] * srate; angles[5] *= angles[5] * srate; angles[6] *= angles[6] * srate; angles[7] *= angles[7] * srate; // reduce the angle to the range (-0.5, 0.5) // convert doubles into singles // This does "angles - round(angles)" set_extended_precision(); set_up_fastfrac(roundVal); v_angle[0] = fastfrac(angles[0],roundVal); v_angle[1] = fastfrac(angles[1],roundVal); v_angle[2] = fastfrac(angles[2],roundVal); v_angle[3] = fastfrac(angles[3],roundVal); v_angle2[0] = fastfrac(angles[4],roundVal); v_angle2[1] = fastfrac(angles[5],roundVal); v_angle2[2] = fastfrac(angles[6],roundVal); v_angle2[3] = fastfrac(angles[7],roundVal); clean_up_fastfrac(); restore_fpucw(); x = _mm_load_ps( v_angle ); // square to the range [0, 0.25) y = _mm_mul_ps(x, x); // perform the initial polynomial approximations with interleaved Estrin sequences z = _mm_mul_ps(y, y); s = _mm_mul_ps(y, SS4F); c = _mm_mul_ps(y, CC3F); s = _mm_add_ps(s, SS3F); c = _mm_add_ps(c, CC2F); s = _mm_mul_ps(s, z); c = _mm_mul_ps(c, z); v = _mm_mul_ps(y, SS2F); w = _mm_mul_ps(y, CC1F); v = _mm_add_ps(v, SS1F); w = _mm_add_ps(w, ONE); s = _mm_add_ps(s, v); c = _mm_add_ps(c, w); s = _mm_mul_ps(s, x); // perform first angle doubling cd1 = _mm_mul_ps(s, c); cd2 = _mm_mul_ps(c, c); cd3 = _mm_mul_ps(s, s); y = _mm_mul_ps(cd1, TWO); x = _mm_sub_ps(cd2, cd3); // load the signal to be chirped d1 = _mm_load_ps(data); d2 = _mm_load_ps(data+4); // calculate scaling factor to correct the magnitude // and perform second angle doubling cd2 = _mm_mul_ps(x, x); cd3 = _mm_mul_ps(y, y); c = _mm_sub_ps(TWO, cd2); cd1 = _mm_mul_ps(x, y); m = _mm_sub_ps(c, cd3); s = _mm_mul_ps(cd1, TWO); c = _mm_sub_ps(cd2, cd3); // correct the magnitude (final sine / cosine approximations) s = _mm_mul_ps(s, m); c = _mm_mul_ps(c, m); x = d1; y = d2; x = _mm_shuffle_ps(x, x, 0xB1); y = _mm_shuffle_ps(y, y, 0xB1); x = _mm_mul_ps(x, R_NEG); y = _mm_mul_ps(y, R_NEG); cd1 = _mm_shuffle_ps(c, c, 0x50); cd2 = _mm_shuffle_ps(c, c, 0xfa); td1 = _mm_shuffle_ps(s, s, 0x50); td2 = _mm_shuffle_ps(s, s, 0xfa); cd1 = _mm_mul_ps(cd1, d1); cd2 = _mm_mul_ps(cd2, d2); td1 = _mm_mul_ps(td1, x); td2 = _mm_mul_ps(td2, y); cd1 = _mm_add_ps(cd1, td1); cd2 = _mm_add_ps(cd2, td2); // store chirped values _mm_stream_ps(chirped+0, cd1); _mm_stream_ps(chirped+4, cd2); // Retrieve second set of reduced angles x = _mm_load_ps( v_angle2 ); // square to the range [0, 0.25) y = _mm_mul_ps(x, x); // perform the initial polynomial approximations with interleaved Estrin sequences z = _mm_mul_ps(y, y); s = _mm_mul_ps(y, SS4F); c = _mm_mul_ps(y, CC3F); s = _mm_add_ps(s, SS3F); c = _mm_add_ps(c, CC2F); s = _mm_mul_ps(s, z); c = _mm_mul_ps(c, z); v = _mm_mul_ps(y, SS2F); w = _mm_mul_ps(y, CC1F); v = _mm_add_ps(v, SS1F); w = _mm_add_ps(w, ONE); s = _mm_add_ps(s, v); c = _mm_add_ps(c, w); s = _mm_mul_ps(s, x); // perform first angle doubling cd1 = _mm_mul_ps(s, c); cd2 = _mm_mul_ps(c, c); cd3 = _mm_mul_ps(s, s); y = _mm_mul_ps(cd1, TWO); x = _mm_sub_ps(cd2, cd3); // load the signal to be chirped d1 = _mm_load_ps(data+8); d2 = _mm_load_ps(data+12); // calculate scaling factor to correct the magnitude // and perform second angle doubling cd2 = _mm_mul_ps(x, x); cd3 = _mm_mul_ps(y, y); c = _mm_sub_ps(TWO, cd2); cd1 = _mm_mul_ps(x, y); m = _mm_sub_ps(c, cd3); s = _mm_mul_ps(cd1, TWO); c = _mm_sub_ps(cd2, cd3); // correct the magnitude (final sine / cosine approximations) c = _mm_mul_ps(c, m); s = _mm_mul_ps(s, m); x = d1; y = d2; x = _mm_shuffle_ps(x, x, 0xB1); y = _mm_shuffle_ps(y, y, 0xB1); x = _mm_mul_ps(x, R_NEG); y = _mm_mul_ps(y, R_NEG); cd1 = _mm_shuffle_ps(c, c, 0x50); // 01 01 00 00 AaBb => BBbb => c3c3c4c4 cd2 = _mm_shuffle_ps(c, c, 0xfa); // 11 11 10 10 AaBb => AAaa => c1c1c2c2 td1 = _mm_shuffle_ps(s, s, 0x50); td2 = _mm_shuffle_ps(s, s, 0xfa); cd1 = _mm_mul_ps(cd1, d1); cd2 = _mm_mul_ps(cd2, d2); td1 = _mm_mul_ps(td1, x); td2 = _mm_mul_ps(td2, y); cd1 = _mm_add_ps(cd1, td1); cd2 = _mm_add_ps(cd2, td2); // store chirped values _mm_stream_ps(chirped+8, cd1); _mm_stream_ps(chirped+12, cd2); } _mm_sfence(); if ( i < ul_NumDataPoints) { // use original routine to finish up any tailings (max stride-1 elements) v_ChirpData(fp_DataArray+i, fp_ChirpDataArray+i , ChirpRateInd, ChirpRate, ul_NumDataPoints-i, sample_rate); } analysis_state.FLOP_counter+=12.0*ul_NumDataPoints; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } /*************************************************** * * Alternate chirp function using Faster SinCos and Horner method * for polynomial calculations. Derived from version 8 Alex Kan code. */ int sse1_ChirpData_ak8h( sah_complex * fp_DataArray, sah_complex * fp_ChirpDataArray, int ChirpRateInd, double ChirpRate, int ul_NumDataPoints, double sample_rate ) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("sse1_ChirpData_ak8h()"); #endif if (ChirpRateInd == 0) { memcpy(fp_ChirpDataArray, fp_DataArray, (int)ul_NumDataPoints * sizeof(sah_complex) ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } double srate = ChirpRate * 0.5 / (sample_rate * sample_rate); #if defined(_LP64) || defined(_WIN64) || (defined(__GNUC__) && defined(__SSE_MATH__)) // For scalar XMM code or any FPU with 64 bit registers double roundVal = (srate >= 0.0) ? TWO_TO_52 : -TWO_TO_52; #else // For X87 FPU double roundVal = (srate >= 0.0) ? ROUNDX87 : -ROUNDX87; #endif int i, vEnd; unsigned short fpucw1, fpucw2; // main vectorised loop vEnd = ul_NumDataPoints - (ul_NumDataPoints & 7); for (i = 0; i < vEnd; i += 8) { const float *data = (const float *) (fp_DataArray + i); float *chirped = (float *) (fp_ChirpDataArray + i); double angles[8], dtemp; ALIGNED(float, 16) v_angle[4], v_angle2[4]; __m128 d1, d2; __m128 cd1, cd2, cd3; __m128 td1, td2; __m128 x; __m128 y; __m128 s; __m128 c; __m128 m; prefetchnta((const void *)( data+32 )); dtemp = double( i ); angles[0] = dtemp+0.0; angles[1] = dtemp+1.0; angles[2] = dtemp+2.0; angles[3] = dtemp+3.0; angles[4] = dtemp+4.0; angles[5] = dtemp+5.0; angles[6] = dtemp+6.0; angles[7] = dtemp+7.0; // calculate the input angle angles[0] *= angles[0] * srate; // angle^2 * rate angles[1] *= angles[1] * srate; angles[2] *= angles[2] * srate; angles[3] *= angles[3] * srate; angles[4] *= angles[4] * srate; angles[5] *= angles[5] * srate; angles[6] *= angles[6] * srate; angles[7] *= angles[7] * srate; // reduce the angle to the range (-0.5, 0.5) // convert doubles into singles // This does "angles - round(angles)" set_extended_precision(); set_up_fastfrac(roundVal); v_angle[0] = fastfrac(angles[0],roundVal); v_angle[1] = fastfrac(angles[1],roundVal); v_angle[2] = fastfrac(angles[2],roundVal); v_angle[3] = fastfrac(angles[3],roundVal); v_angle2[0] = fastfrac(angles[4],roundVal); v_angle2[1] = fastfrac(angles[5],roundVal); v_angle2[2] = fastfrac(angles[6],roundVal); v_angle2[3] = fastfrac(angles[7],roundVal); clean_up_fastfrac(); restore_fpucw(); x = _mm_load_ps( v_angle ); // square to the range [0, 0.25) y = _mm_mul_ps(x, x); // perform the initial polynomial approximations using interleaved Horner sequences s = _mm_mul_ps(y, SS4F); c = _mm_mul_ps(y, CC3F); s = _mm_add_ps(s, SS3F); c = _mm_add_ps(c, CC2F); s = _mm_mul_ps(s, y); c = _mm_mul_ps(c, y); s = _mm_add_ps(s, SS2F); c = _mm_add_ps(c, CC1F); s = _mm_mul_ps(s, y); c = _mm_mul_ps(c, y); s = _mm_add_ps(s, SS1F); c = _mm_add_ps(c, ONE); s = _mm_mul_ps(s, x); // perform first angle doubling cd1 = _mm_mul_ps(s, c); cd2 = _mm_mul_ps(c, c); cd3 = _mm_mul_ps(s, s); y = _mm_mul_ps(cd1, TWO); x = _mm_sub_ps(cd2, cd3); // load the signal to be chirped d1 = _mm_load_ps(data); d2 = _mm_load_ps(data+4); // calculate scaling factor to correct the magnitude // and perform second angle doubling cd2 = _mm_mul_ps(x, x); cd3 = _mm_mul_ps(y, y); c = _mm_sub_ps(TWO, cd2); cd1 = _mm_mul_ps(x, y); m = _mm_sub_ps(c, cd3); s = _mm_mul_ps(cd1, TWO); c = _mm_sub_ps(cd2, cd3); // correct the magnitude (final sine / cosine approximations) s = _mm_mul_ps(s, m); c = _mm_mul_ps(c, m); x = d1; y = d2; x = _mm_shuffle_ps(x, x, 0xB1); y = _mm_shuffle_ps(y, y, 0xB1); x = _mm_mul_ps(x, R_NEG); y = _mm_mul_ps(y, R_NEG); cd1 = _mm_shuffle_ps(c, c, 0x50); cd2 = _mm_shuffle_ps(c, c, 0xfa); td1 = _mm_shuffle_ps(s, s, 0x50); td2 = _mm_shuffle_ps(s, s, 0xfa); cd1 = _mm_mul_ps(cd1, d1); cd2 = _mm_mul_ps(cd2, d2); td1 = _mm_mul_ps(td1, x); td2 = _mm_mul_ps(td2, y); cd1 = _mm_add_ps(cd1, td1); cd2 = _mm_add_ps(cd2, td2); // store chirped values _mm_stream_ps(chirped+0, cd1); _mm_stream_ps(chirped+4, cd2); // Retrieve second set of reduced angles x = _mm_load_ps( v_angle2 ); // square to the range [0, 0.25) y = _mm_mul_ps(x, x); // perform the initial polynomial approximations using interleaved Horner sequences s = _mm_mul_ps(y, SS4F); c = _mm_mul_ps(y, CC3F); s = _mm_add_ps(s, SS3F); c = _mm_add_ps(c, CC2F); s = _mm_mul_ps(s, y); c = _mm_mul_ps(c, y); s = _mm_add_ps(s, SS2F); c = _mm_add_ps(c, CC1F); s = _mm_mul_ps(s, y); c = _mm_mul_ps(c, y); s = _mm_add_ps(s, SS1F); c = _mm_add_ps(c, ONE); s = _mm_mul_ps(s, x); // perform first angle doubling cd1 = _mm_mul_ps(s, c); cd2 = _mm_mul_ps(c, c); cd3 = _mm_mul_ps(s, s); y = _mm_mul_ps(cd1, TWO); x = _mm_sub_ps(cd2, cd3); // load the signal to be chirped d1 = _mm_load_ps(data+8); d2 = _mm_load_ps(data+12); // calculate scaling factor to correct the magnitude // and perform second angle doubling cd2 = _mm_mul_ps(x, x); cd3 = _mm_mul_ps(y, y); c = _mm_sub_ps(TWO, cd2); cd1 = _mm_mul_ps(x, y); m = _mm_sub_ps(c, cd3); s = _mm_mul_ps(cd1, TWO); c = _mm_sub_ps(cd2, cd3); // correct the magnitude (final sine / cosine approximations) c = _mm_mul_ps(c, m); s = _mm_mul_ps(s, m); x = d1; y = d2; x = _mm_shuffle_ps(x, x, 0xB1); y = _mm_shuffle_ps(y, y, 0xB1); x = _mm_mul_ps(x, R_NEG); y = _mm_mul_ps(y, R_NEG); cd1 = _mm_shuffle_ps(c, c, 0x50); // 01 01 00 00 AaBb => BBbb => c3c3c4c4 cd2 = _mm_shuffle_ps(c, c, 0xfa); // 11 11 10 10 AaBb => AAaa => c1c1c2c2 td1 = _mm_shuffle_ps(s, s, 0x50); td2 = _mm_shuffle_ps(s, s, 0xfa); cd1 = _mm_mul_ps(cd1, d1); cd2 = _mm_mul_ps(cd2, d2); td1 = _mm_mul_ps(td1, x); td2 = _mm_mul_ps(td2, y); cd1 = _mm_add_ps(cd1, td1); cd2 = _mm_add_ps(cd2, td2); // store chirped values _mm_stream_ps(chirped+8, cd1); _mm_stream_ps(chirped+12, cd2); } _mm_sfence(); if ( i < ul_NumDataPoints) { // use original routine to finish up any tailings (max stride-1 elements) v_ChirpData(fp_DataArray+i, fp_ChirpDataArray+i , ChirpRateInd, ChirpRate, ul_NumDataPoints-i, sample_rate); } analysis_state.FLOP_counter+=12.0*ul_NumDataPoints; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } /********************************************************************* * * SSE Folding subroutine sets * */ // These functions reduce an array length by a factor of 3, 4, 5, // or 2 by summing and return the maximum of the summed values. // Since each adjacent float is added to the next, simd works well. // To keep multiple FPU or SSE units in any processor busy we try to // avoid dependancy chains ( x += a, x += b, x += c) where each // computation must wait til previous sum is computed. // having two maximums running from two colums of numbers // avoids a single max register from being the bottleneck int sse_mask1[] = {4, 1, 2, 3, 0, 0, 0, 0 }; int sse_mask2[] = {4, 4, 4, 4, 4, 1, 2, 3 }; // ALIGN_SIMD unsigned int sse_partMask[][4] = { ALIGNED(unsigned int, 16) sse_partMask[][4] = { { 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF }, // 0 { 0xFFFFFFFF,0x00000000,0x00000000,0x00000000 }, // 1 { 0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000 }, // 2 { 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0x00000000 }, // 3 { 0x00000000,0x00000000,0x00000000,0x00000000 }, // 4 }; #define SSE_MASK(idx) (*(__m128 *)&sse_partMask[idx]) // maxp2f - // function: Given a 4 packed float input, return the max among them // concept: Ben Herndon // inline float s_maxp2f( __m128 max1 ) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("s_maxp2f()"); #endif float tMax; __m128 maxReg = max1; maxReg = _mm_movehl_ps( maxReg, max1 ); maxReg = _mm_max_ps( maxReg, max1 ); // [0][1] vs [3][4] max1 = _mm_shuffle_ps( maxReg, maxReg, 1 ); maxReg = _mm_max_ss( maxReg, max1 ); // [1] vs [0] _mm_store_ss( &tMax, maxReg ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return ( tMax ); } #if defined(__clang__) #define s_getU( aaaa, ptr ) \ aaaa = _mm_loadl_pi(aaaa, (__m64*)(ptr)); \ aaaa = _mm_loadh_pi(aaaa, ((__m64 *)(ptr))+1) #else #define s_getU( aaaa, ptr ) \ aaaa = _mm_loadh_pi( _mm_loadl_pi(aaaa, (__m64 *)ptr), ((__m64 *)(ptr))+1 ) #endif #define s_putU( ptr, aaaa ) \ _mm_storel_pi((__m64 *)ptr, aaaa), _mm_storeh_pi( ((__m64 *)ptr)+1 , aaaa) /****************** * * ben SSE folding * * Description: Intel & AMD SSE optimized folding * CPUs: Intel Pentium III and beyond, AMD Athlon model 6 - and beyond * * Original code by Ben Herndon, modified by Joe Segur * */ // // fold by 2 // float sse_sum2(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("sse_sum2()"); #endif __m128 sum1, sum2, tmp1, tmp2, max1, max2; int i, length = P->di; float *ptr1 = ss[1]+P->offset; float *ptr2 = ss[1]+P->tmp0; float *sums = P->dest; max1 = max2 = ZERO; const int stride = 8; for (i = 0; i < length-(stride - 1); i += stride ) { // SSE Pipeline #1 SSE Pipeline #2 // s_getU(sum1, &ptr1[i + 0] ); s_getU(sum2, &ptr1[i + 4] ); s_getU(tmp1, &ptr2[i + 0] ); s_getU(tmp2, &ptr2[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); max1 = _mm_max_ps( max1, sum1 ); max2 = _mm_max_ps( max2, sum2 ); s_putU( &sums[i + 0], sum1 ); s_putU( &sums[i +4], sum2 ); } int mask1 = sse_mask1[ length-i]; int mask2 = sse_mask2[ length-i]; s_getU(sum1, &ptr1[i + 0] ); s_getU(sum2, &ptr1[i + 4] ); s_getU(tmp1, &ptr2[i + 0] ); s_getU(tmp2, &ptr2[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); sum1 = _mm_and_ps(sum1, SSE_MASK( mask1 ) ); sum2 = _mm_and_ps(sum2, SSE_MASK( mask2 ) ); max1 = _mm_max_ps( max1, sum1 ); max2 = _mm_max_ps( max2, sum2 ); s_putU( &sums[i + 0], sum1 ); s_putU( &sums[i +4], sum2 ); float rv= s_maxp2f( _mm_max_ps( max1, max2 ) ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return rv; } // // fold by 3s // float sse_sum3(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("sse_sum3()"); #endif __m128 sum1, sum2, tmp1, tmp2, max1, max2; int i, length = P->di; float *ptr1 = ss[0]; float *ptr2 = ss[0]+P->tmp0; float *ptr3 = ss[0]+P->tmp1; float *sums = P->dest; max1 = max2 = ZERO; const int stride = 8; for (i = 0; i < length-(stride - 1); i += stride ) { // SSE Pipeline #1 SSE Pipeline #2 // s_getU(sum1, &ptr1[i + 0] ); s_getU(sum2, &ptr1[i + 4] ); s_getU(tmp1, &ptr2[i + 0] ); s_getU(tmp2, &ptr2[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr3[i + 0] ); s_getU(tmp2, &ptr3[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); max1 = _mm_max_ps( max1, sum1 ); max2 = _mm_max_ps( max2, sum2 ); s_putU( &sums[i + 0], sum1 ); s_putU( &sums[i +4], sum2 ); } int mask1 = sse_mask1[ length-i]; int mask2 = sse_mask2[ length-i]; s_getU(sum1, &ptr1[i + 0] ); s_getU(sum2, &ptr1[i + 4] ); s_getU(tmp1, &ptr2[i + 0] ); s_getU(tmp2, &ptr2[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr3[i + 0] ); s_getU(tmp2, &ptr3[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); sum1 = _mm_and_ps(sum1, SSE_MASK( mask1 ) ); sum2 = _mm_and_ps(sum2, SSE_MASK( mask2 ) ); max1 = _mm_max_ps( max1, sum1 ); max2 = _mm_max_ps( max2, sum2 ); s_putU( &sums[i + 0], sum1 ); s_putU( &sums[i +4], sum2 ); float rv= s_maxp2f( _mm_max_ps( max1, max2 ) ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return rv; } // // fold by 4 // float sse_sum4(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("sse_sum4()"); #endif __m128 sum1, sum2, tmp1, tmp2, max1, max2; int i, length = P->di; float *ptr1 = ss[0]; float *ptr2 = ss[0]+P->tmp0; float *ptr3 = ss[0]+P->tmp1; float *ptr4 = ss[0]+P->tmp2; float *sums = P->dest; max1 = max2 = ZERO; const int stride = 8; for (i = 0; i < length-(stride - 1); i += stride ) { // SSE Pipeline #1 SSE Pipeline #2 // s_getU(sum1, &ptr1[i + 0] ); s_getU(sum2, &ptr1[i + 4] ); s_getU(tmp1, &ptr2[i + 0] ); s_getU(tmp2, &ptr2[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr3[i + 0] ); s_getU(tmp2, &ptr3[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr4[i + 0] ); s_getU(tmp2, &ptr4[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); max1 = _mm_max_ps( max1, sum1 ); max2 = _mm_max_ps( max2, sum2 ); s_putU( &sums[i + 0], sum1 ); s_putU( &sums[i +4], sum2 ); } int mask1 = sse_mask1[ length-i]; int mask2 = sse_mask2[ length-i]; s_getU(sum1, &ptr1[i + 0] ); s_getU(sum2, &ptr1[i + 4] ); s_getU(tmp1, &ptr2[i + 0] ); s_getU(tmp2, &ptr2[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr3[i + 0] ); s_getU(tmp2, &ptr3[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr4[i + 0] ); s_getU(tmp2, &ptr4[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); sum1 = _mm_and_ps(sum1, SSE_MASK( mask1 ) ); sum2 = _mm_and_ps(sum2, SSE_MASK( mask2 ) ); max1 = _mm_max_ps( max1, sum1 ); max2 = _mm_max_ps( max2, sum2 ); s_putU( &sums[i + 0], sum1 ); s_putU( &sums[i +4], sum2 ); float rv= s_maxp2f( _mm_max_ps( max1, max2 ) ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return rv; } // // fold by 5 // float sse_sum5(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("sse_sum5()"); #endif __m128 sum1, sum2, tmp1, tmp2, max1, max2; int i, length = P->di; float *ptr1 = ss[0]; float *ptr2 = ss[0]+P->tmp0; float *ptr3 = ss[0]+P->tmp1; float *ptr4 = ss[0]+P->tmp2; float *ptr5 = ss[0]+P->tmp3; float *sums = P->dest; max1 = max2 = ZERO; const int stride = 8; for (i = 0; i < length-(stride - 1); i += stride ) { // SSE Pipeline #1 SSE Pipeline #2 // s_getU(sum1, &ptr1[i + 0] ); s_getU(sum2, &ptr1[i + 4] ); s_getU(tmp1, &ptr2[i + 0] ); s_getU(tmp2, &ptr2[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr3[i + 0] ); s_getU(tmp2, &ptr3[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr4[i + 0] ); s_getU(tmp2, &ptr4[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr5[i + 0] ); s_getU(tmp2, &ptr5[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); max1 = _mm_max_ps( max1, sum1 ); max2 = _mm_max_ps( max2, sum2 ); s_putU( &sums[i + 0], sum1 ); s_putU( &sums[i +4], sum2 ); } int mask1 = sse_mask1[ length-i]; int mask2 = sse_mask2[ length-i]; s_getU(sum1, &ptr1[i + 0] ); s_getU(sum2, &ptr1[i + 4] ); s_getU(tmp1, &ptr2[i + 0] ); s_getU(tmp2, &ptr2[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr3[i + 0] ); s_getU(tmp2, &ptr3[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr4[i + 0] ); s_getU(tmp2, &ptr4[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr5[i + 0] ); s_getU(tmp2, &ptr5[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); sum1 = _mm_and_ps(sum1, SSE_MASK( mask1 ) ); sum2 = _mm_and_ps(sum2, SSE_MASK( mask2 ) ); max1 = _mm_max_ps( max1, sum1 ); max2 = _mm_max_ps( max2, sum2 ); s_putU( &sums[i + 0], sum1 ); s_putU( &sums[i +4], sum2 ); float rv= s_maxp2f( _mm_max_ps( max1, max2 ) ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return rv; } sum_func sse_list3[FOLDTBLEN] = { sse_sum3, sse_sum3, sse_sum3, sse_sum3, sse_sum3, sse_sum3, sse_sum3, sse_sum3, sse_sum3, sse_sum3, sse_sum3, sse_sum3, sse_sum3, sse_sum3, sse_sum3, sse_sum3, sse_sum3, sse_sum3, sse_sum3, sse_sum3, sse_sum3, sse_sum3, sse_sum3, sse_sum3, sse_sum3, sse_sum3, sse_sum3, sse_sum3, sse_sum3, sse_sum3, sse_sum3, sse_sum3 }; sum_func sse_list4[FOLDTBLEN] = { sse_sum4, sse_sum4, sse_sum4, sse_sum4, sse_sum4, sse_sum4, sse_sum4, sse_sum4, sse_sum4, sse_sum4, sse_sum4, sse_sum4, sse_sum4, sse_sum4, sse_sum4, sse_sum4, sse_sum4, sse_sum4, sse_sum4, sse_sum4, sse_sum4, sse_sum4, sse_sum4, sse_sum4, sse_sum4, sse_sum4, sse_sum4, sse_sum4, sse_sum4, sse_sum4, sse_sum4, sse_sum4 }; sum_func sse_list5[FOLDTBLEN] = { sse_sum5, sse_sum5, sse_sum5, sse_sum5, sse_sum5, sse_sum5, sse_sum5, sse_sum5, sse_sum5, sse_sum5, sse_sum5, sse_sum5, sse_sum5, sse_sum5, sse_sum5, sse_sum5, sse_sum5, sse_sum5, sse_sum5, sse_sum5, sse_sum5, sse_sum5, sse_sum5, sse_sum5, sse_sum5, sse_sum5, sse_sum5, sse_sum5, sse_sum5, sse_sum5, sse_sum5, sse_sum5 }; sum_func sse_list2[FOLDTBLEN] = { sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2 }; sum_func sse_list2_L[FOLDTBLEN] = { sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2, sse_sum2 }; FoldSet sse_ben_fold = {sse_list3, sse_list4, sse_list5, sse_list2, sse_list2_L, "ben SSE"}; /****************** * * BH SSE folding * * Description: Intel & AMD SSE optimized folding * CPUs: Intel Pentium III and beyond, AMD Athlon model 6 - and beyond * * Original code by Ben Herndon, modified by Joe Segur * */ int sse_msks1[] = {4, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int sse_msks2[] = {4, 4, 4, 4, 4, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; //ALIGN_SIMD float sse_foldLim[][4] = { ALIGNED(float, 16) sse_foldLim[][4] = { { 0.0f, 0.0f, 0.0f, 0.0f }, // 0 { 0.0f, 1e37f, 1e37f, 1e37f }, // 1 { 0.0f, 0.0f, 1e37f, 1e37f }, // 2 { 0.0f, 0.0f, 0.0f, 1e37f }, // 3 { 1e37f, 1e37f, 1e37f, 1e37f }, // 4 }; #define SSE_LIM(idx) (*(__m128 *)&sse_foldLim[idx]) // // Fold by 3 versions // float sse_pulPoTf3u(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("sse_pulPoTf2u()"); #endif __m128 sum1, sum2, max1, max2; __m128 tmp1, tmp2; int i; max1 = max2 = _mm_set_ps1( 0.0 ); float *ptr1 = ss[0]; float *ptr2 = ss[0] + P->tmp0; float *ptr3 = ss[0] + P->tmp1; const int stride = 24; for (i = 0; i < P->di - ( stride - 1 ); i += stride ) { // SSE Pipeline #1 SSE Pipeline #2 // sum1 = _mm_load_ps( &ptr1[i + 0] ); sum2 = _mm_load_ps( &ptr1[i + 4] ); s_getU(tmp1, &ptr2[i + 0] ); s_getU(tmp2, &ptr2[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr3[i + 0] ); s_getU(tmp2, &ptr3[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); max1 = _mm_max_ps( max1, sum1 ); max2 = _mm_max_ps( max2, sum2 ); _mm_store_ps( &P->dest[i + 0], sum1 ); _mm_store_ps( &P->dest[i + 4], sum2 ); sum1 = _mm_load_ps( &ptr1[i + 8] ); sum2 = _mm_load_ps( &ptr1[i + 12] ); s_getU(tmp1, &ptr2[i + 8] ); s_getU(tmp2, &ptr2[i + 12] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr3[i + 8] ); s_getU(tmp2, &ptr3[i + 12] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); max1 = _mm_max_ps( max1, sum1 ); max2 = _mm_max_ps( max2, sum2 ); _mm_store_ps( &P->dest[i + 8], sum1 ); _mm_store_ps( &P->dest[i + 12], sum2 ); sum1 = _mm_load_ps( &ptr1[i + 16] ); sum2 = _mm_load_ps( &ptr1[i + 20] ); s_getU(tmp1, &ptr2[i + 16] ); s_getU(tmp2, &ptr2[i + 20] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr3[i + 16] ); s_getU(tmp2, &ptr3[i + 20] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); max1 = _mm_max_ps( max1, sum1 ); max2 = _mm_max_ps( max2, sum2 ); _mm_store_ps( &P->dest[i + 16], sum1 ); _mm_store_ps( &P->dest[i + 20], sum2 ); } max1 = _mm_max_ps( max1, max2 ); for ( ; i < P->di ; i += 4) { int mask1 = sse_msks1[ P->di-i]; sum1 = _mm_load_ps( &ptr1[i + 0] ); s_getU(tmp1, &ptr2[i + 0] ); sum1 = _mm_add_ps( sum1, tmp1 ); s_getU(tmp1, &ptr3[i + 0] ); sum1 = _mm_add_ps( sum1, tmp1 ); _mm_store_ps( &P->dest[i + 0], sum1 ); sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); max1 = _mm_max_ps( max1, sum1 ); } float rv= ( s_maxp2f( max1 ) ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return rv; } float sse_pulPoTf3(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("sse_pulPoTf3()"); #endif __m128 sum1, sum2, max1, max2; __m128 tmp1, tmp2; int i; max1 = max2 = _mm_set_ps1( 0.0 ); float *ptr1 = ss[0]; float *ptr2 = ss[0] + P->tmp0; float *ptr3 = ss[0] + P->tmp1; const int stride = 8; for (i = 0; i < P->di - (stride - 1); i += stride ) { // SSE Pipeline #1 SSE Pipeline #2 // sum1 = _mm_load_ps( &ptr1[i + 0] ); sum2 = _mm_load_ps( &ptr1[i + 4] ); s_getU(tmp1, &ptr2[i + 0] ); s_getU(tmp2, &ptr2[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr3[i + 0] ); s_getU(tmp2, &ptr3[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); max1 = _mm_max_ps( max1, sum1 ); max2 = _mm_max_ps( max2, sum2 ); _mm_store_ps( &P->dest[i + 0], sum1 ); _mm_store_ps( &P->dest[i + 4], sum2 ); } max1 = _mm_max_ps( max1, max2 ); for ( ; i < P->di ; i += 4) { int mask1 = sse_msks1[ P->di-i]; sum1 = _mm_load_ps( &ptr1[i + 0] ); s_getU(tmp1, &ptr2[i + 0] ); sum1 = _mm_add_ps( sum1, tmp1 ); s_getU(tmp1, &ptr3[i + 0] ); sum1 = _mm_add_ps( sum1, tmp1 ); _mm_store_ps( &P->dest[i + 0], sum1 ); sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); max1 = _mm_max_ps( max1, sum1 ); } float rv= ( s_maxp2f( max1 ) ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return rv; } float sse_pulPoTf3L8(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("sse_pulPoTf3L8()"); #endif __m128 sum1, sum2, max1, max2; __m128 tmp1, tmp2; max1 = max2 = _mm_set_ps1( 0.0 ); float *ptr1 = ss[0]; float *ptr2 = ss[0] + P->tmp0; float *ptr3 = ss[0] + P->tmp1; // SSE Pipeline #1 SSE Pipeline #2 // int mask1 = sse_msks1[ P->di ]; int mask2 = sse_msks2[ P->di ]; sum1 = _mm_load_ps( &ptr1[0] ); sum2 = _mm_load_ps( &ptr1[4] ); s_getU(tmp1, &ptr2[0] ); s_getU(tmp2, &ptr2[4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr3[0] ); s_getU(tmp2, &ptr3[4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); _mm_store_ps( &P->dest[0], sum1 ); _mm_store_ps( &P->dest[4], sum2 ); sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); sum2 = _mm_sub_ps(sum2, SSE_LIM( mask2 ) ); max1 = _mm_max_ps( max1, sum1 ); max2 = _mm_max_ps( max2, sum2 ); float rv= ( s_maxp2f( _mm_max_ps( max1, max2 ) ) ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return rv; } sum_func BHSSETB3[FOLDTBLEN] = { sse_pulPoTf3L8, sse_pulPoTf3L8, sse_pulPoTf3L8, sse_pulPoTf3L8, sse_pulPoTf3L8, sse_pulPoTf3L8, sse_pulPoTf3L8, sse_pulPoTf3L8, sse_pulPoTf3L8, sse_pulPoTf3, sse_pulPoTf3, sse_pulPoTf3, sse_pulPoTf3, sse_pulPoTf3, sse_pulPoTf3, sse_pulPoTf3, sse_pulPoTf3, sse_pulPoTf3, sse_pulPoTf3, sse_pulPoTf3, sse_pulPoTf3, sse_pulPoTf3, sse_pulPoTf3, sse_pulPoTf3, sse_pulPoTf3u }; // // Fold by 4 versions // float sse_pulPoTf4u(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("sse_pulPoTf4u()"); #endif __m128 sum1, sum2, max1, max2; __m128 tmp1, tmp2; int i; max1 = max2 = _mm_set_ps1( 0.0 ); float *ptr1 = ss[0]; float *ptr2 = ss[0] + P->tmp0; float *ptr3 = ss[0] + P->tmp1; float *ptr4 = ss[0] + P->tmp2; const int stride = 24; for (i = 0; i < P->di - ( stride - 1 ); i += stride ) { // SSE Pipeline #1 SSE Pipeline #2 // sum1 = _mm_load_ps( &ptr1[i + 0] ); sum2 = _mm_load_ps( &ptr1[i + 4] ); s_getU(tmp1, &ptr2[i + 0] ); s_getU(tmp2, &ptr2[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr3[i + 0] ); s_getU(tmp2, &ptr3[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr4[i + 0] ); s_getU(tmp2, &ptr4[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); max1 = _mm_max_ps( max1, sum1 ); max2 = _mm_max_ps( max2, sum2 ); _mm_store_ps( &P->dest[i + 0], sum1 ); _mm_store_ps( &P->dest[i + 4], sum2 ); sum1 = _mm_load_ps( &ptr1[i + 8] ); sum2 = _mm_load_ps( &ptr1[i + 12] ); s_getU(tmp1, &ptr2[i + 8] ); s_getU(tmp2, &ptr2[i + 12] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr3[i + 8] ); s_getU(tmp2, &ptr3[i + 12] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr4[i + 8] ); s_getU(tmp2, &ptr4[i + 12] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); max1 = _mm_max_ps( max1, sum1 ); max2 = _mm_max_ps( max2, sum2 ); _mm_store_ps( &P->dest[i + 8], sum1 ); _mm_store_ps( &P->dest[i + 12], sum2 ); sum1 = _mm_load_ps( &ptr1[i + 16] ); sum2 = _mm_load_ps( &ptr1[i + 20] ); s_getU(tmp1, &ptr2[i + 16] ); s_getU(tmp2, &ptr2[i + 20] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr3[i + 16] ); s_getU(tmp2, &ptr3[i + 20] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr4[i + 16] ); s_getU(tmp2, &ptr4[i + 20] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); max1 = _mm_max_ps( max1, sum1 ); max2 = _mm_max_ps( max2, sum2 ); _mm_store_ps( &P->dest[i + 16], sum1 ); _mm_store_ps( &P->dest[i + 20], sum2 ); } max1 = _mm_max_ps( max1, max2 ); for ( ; i < P->di ; i += 4) { int mask1 = sse_msks1[ P->di-i]; sum1 = _mm_load_ps( &ptr1[i + 0] ); s_getU(tmp1, &ptr2[i + 0] ); sum1 = _mm_add_ps( sum1, tmp1 ); s_getU(tmp1, &ptr3[i + 0] ); sum1 = _mm_add_ps( sum1, tmp1 ); s_getU(tmp1, &ptr4[i + 0] ); sum1 = _mm_add_ps( sum1, tmp1 ); _mm_store_ps( &P->dest[i + 0], sum1 ); sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); max1 = _mm_max_ps( max1, sum1 ); } float rv= ( s_maxp2f( max1 ) ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return rv; } float sse_pulPoTf4(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("sse_pulPoTf4()"); #endif __m128 sum1, sum2, max1, max2; __m128 tmp1, tmp2; int i; max1 = max2 = _mm_set_ps1( 0.0 ); float *ptr1 = ss[0]; float *ptr2 = ss[0] + P->tmp0; float *ptr3 = ss[0] + P->tmp1; float *ptr4 = ss[0] + P->tmp2; const int stride = 8; for (i = 0; i < P->di - ( stride - 1 ); i += stride ) { // SSE Pipeline #1 SSE Pipeline #2 // sum1 = _mm_load_ps( &ptr1[i + 0] ); sum2 = _mm_load_ps( &ptr1[i + 4] ); s_getU(tmp1, &ptr2[i + 0] ); s_getU(tmp2, &ptr2[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr3[i + 0] ); s_getU(tmp2, &ptr3[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr4[i + 0] ); s_getU(tmp2, &ptr4[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); max1 = _mm_max_ps( max1, sum1 ); max2 = _mm_max_ps( max2, sum2 ); _mm_store_ps( &P->dest[i + 0], sum1 ); _mm_store_ps( &P->dest[i + 4], sum2 ); } max1 = _mm_max_ps( max1, max2 ); for ( ; i < P->di ; i += 4) { int mask1 = sse_msks1[ P->di-i]; sum1 = _mm_load_ps( &ptr1[i + 0] ); s_getU(tmp1, &ptr2[i + 0] ); sum1 = _mm_add_ps( sum1, tmp1 ); s_getU(tmp1, &ptr3[i + 0] ); sum1 = _mm_add_ps( sum1, tmp1 ); s_getU(tmp1, &ptr4[i + 0] ); sum1 = _mm_add_ps( sum1, tmp1 ); _mm_store_ps( &P->dest[i + 0], sum1 ); sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); max1 = _mm_max_ps( max1, sum1 ); } float rv=( s_maxp2f( max1 ) ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return rv; } float sse_pulPoTf4L8(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("sse_pulPoTf4L8()"); #endif __m128 sum1, sum2, max1, max2; __m128 tmp1, tmp2; int i; max1 = max2 = _mm_set_ps1( 0.0 ); float *ptr1 = ss[0]; float *ptr2 = ss[0] + P->tmp0; float *ptr3 = ss[0] + P->tmp1; float *ptr4 = ss[0] + P->tmp2; // SSE Pipeline #1 SSE Pipeline #2 // int mask1 = sse_msks1[ P->di ]; int mask2 = sse_msks2[ P->di ]; sum1 = _mm_load_ps( &ptr1[0] ); sum2 = _mm_load_ps( &ptr1[4] ); s_getU(tmp1, &ptr2[0] ); s_getU(tmp2, &ptr2[4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr3[0] ); s_getU(tmp2, &ptr3[4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr4[0] ); s_getU(tmp2, &ptr4[4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); _mm_store_ps( &P->dest[0], sum1 ); _mm_store_ps( &P->dest[4], sum2 ); sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); sum2 = _mm_sub_ps(sum2, SSE_LIM( mask2 ) ); max1 = _mm_max_ps( max1, sum1 ); max2 = _mm_max_ps( max2, sum2 ); float rv= ( s_maxp2f( _mm_max_ps( max1, max2 ) ) ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return rv; } sum_func BHSSETB4[FOLDTBLEN] = { sse_pulPoTf4L8, sse_pulPoTf4L8, sse_pulPoTf4L8, sse_pulPoTf4L8, sse_pulPoTf4L8, sse_pulPoTf4L8, sse_pulPoTf4L8, sse_pulPoTf4L8, sse_pulPoTf4L8, sse_pulPoTf4, sse_pulPoTf4, sse_pulPoTf4, sse_pulPoTf4, sse_pulPoTf4, sse_pulPoTf4, sse_pulPoTf4, sse_pulPoTf4, sse_pulPoTf4, sse_pulPoTf4, sse_pulPoTf4, sse_pulPoTf4, sse_pulPoTf4, sse_pulPoTf4, sse_pulPoTf4, sse_pulPoTf4u }; // // Fold by 5 versions // float sse_pulPoTf5u(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("sse_pulPoTf5u()"); #endif __m128 sum1, sum2, max1, max2; __m128 tmp1, tmp2; int i; max1 = max2 = _mm_set_ps1( 0.0 ); float *ptr1 = ss[0]; float *ptr2 = ss[0] + P->tmp0; float *ptr3 = ss[0] + P->tmp1; float *ptr4 = ss[0] + P->tmp2; float *ptr5 = ss[0] + P->tmp3; const int stride = 24; for (i = 0; i < P->di - ( stride - 1 ); i += stride ) { // SSE Pipeline #1 SSE Pipeline #2 // sum1 = _mm_load_ps( &ptr1[i + 0] ); sum2 = _mm_load_ps( &ptr1[i + 4] ); s_getU(tmp1, &ptr2[i + 0] ); s_getU(tmp2, &ptr2[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr3[i + 0] ); s_getU(tmp2, &ptr3[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr4[i + 0] ); s_getU(tmp2, &ptr4[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr5[i + 0] ); s_getU(tmp2, &ptr5[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); max1 = _mm_max_ps( max1, sum1 ); max2 = _mm_max_ps( max2, sum2 ); _mm_store_ps( &P->dest[i + 0], sum1 ); _mm_store_ps( &P->dest[i + 4], sum2 ); sum1 = _mm_load_ps( &ptr1[i + 8] ); sum2 = _mm_load_ps( &ptr1[i + 12] ); s_getU(tmp1, &ptr2[i + 8] ); s_getU(tmp2, &ptr2[i + 12] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr3[i + 8] ); s_getU(tmp2, &ptr3[i + 12] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr4[i + 8] ); s_getU(tmp2, &ptr4[i + 12] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr5[i + 8] ); s_getU(tmp2, &ptr5[i + 12] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); max1 = _mm_max_ps( max1, sum1 ); max2 = _mm_max_ps( max2, sum2 ); _mm_store_ps( &P->dest[i + 8], sum1 ); _mm_store_ps( &P->dest[i + 12], sum2 ); sum1 = _mm_load_ps( &ptr1[i + 16] ); sum2 = _mm_load_ps( &ptr1[i + 20] ); s_getU(tmp1, &ptr2[i + 16] ); s_getU(tmp2, &ptr2[i + 20] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr3[i + 16] ); s_getU(tmp2, &ptr3[i + 20] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr4[i + 16] ); s_getU(tmp2, &ptr4[i + 20] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr5[i + 16] ); s_getU(tmp2, &ptr5[i + 20] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); max1 = _mm_max_ps( max1, sum1 ); max2 = _mm_max_ps( max2, sum2 ); _mm_store_ps( &P->dest[i + 16], sum1 ); _mm_store_ps( &P->dest[i + 20], sum2 ); } max1 = _mm_max_ps( max1, max2 ); for ( ; i < P->di ; i += 4) { int mask1 = sse_msks1[ P->di-i]; sum1 = _mm_load_ps( &ptr1[i + 0] ); s_getU(tmp1, &ptr2[i + 0] ); sum1 = _mm_add_ps( sum1, tmp1 ); s_getU(tmp1, &ptr3[i + 0] ); sum1 = _mm_add_ps( sum1, tmp1 ); s_getU(tmp1, &ptr4[i + 0] ); sum1 = _mm_add_ps( sum1, tmp1 ); s_getU(tmp1, &ptr5[i + 0] ); sum1 = _mm_add_ps( sum1, tmp1 ); _mm_store_ps( &P->dest[i + 0], sum1 ); sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); max1 = _mm_max_ps( max1, sum1 ); } float rv=( s_maxp2f( max1 ) ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return rv; } float sse_pulPoTf5(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("sse_pulPoTf5()"); #endif __m128 sum1, sum2, max1, max2; __m128 tmp1, tmp2; int i; max1 = max2 = _mm_set_ps1( 0.0 ); float *ptr1 = ss[0]; float *ptr2 = ss[0] + P->tmp0; float *ptr3 = ss[0] + P->tmp1; float *ptr4 = ss[0] + P->tmp2; float *ptr5 = ss[0] + P->tmp3; const int stride = 8; for (i = 0; i < P->di - ( stride - 1 ); i += stride ) { // SSE Pipeline #1 SSE Pipeline #2 // sum1 = _mm_load_ps( &ptr1[i + 0] ); sum2 = _mm_load_ps( &ptr1[i + 4] ); s_getU(tmp1, &ptr2[i + 0] ); s_getU(tmp2, &ptr2[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr3[i + 0] ); s_getU(tmp2, &ptr3[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr4[i + 0] ); s_getU(tmp2, &ptr4[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr5[i + 0] ); s_getU(tmp2, &ptr5[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); max1 = _mm_max_ps( max1, sum1 ); max2 = _mm_max_ps( max2, sum2 ); _mm_store_ps( &P->dest[i + 0], sum1 ); _mm_store_ps( &P->dest[i + 4], sum2 ); } max1 = _mm_max_ps( max1, max2 ); for ( ; i < P->di ; i += 4) { int mask1 = sse_msks1[ P->di-i]; sum1 = _mm_load_ps( &ptr1[i + 0] ); s_getU(tmp1, &ptr2[i + 0] ); sum1 = _mm_add_ps( sum1, tmp1 ); s_getU(tmp1, &ptr3[i + 0] ); sum1 = _mm_add_ps( sum1, tmp1 ); s_getU(tmp1, &ptr4[i + 0] ); sum1 = _mm_add_ps( sum1, tmp1 ); s_getU(tmp1, &ptr5[i + 0] ); sum1 = _mm_add_ps( sum1, tmp1 ); _mm_store_ps( &P->dest[i + 0], sum1 ); sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); max1 = _mm_max_ps( max1, sum1 ); } float rv=( s_maxp2f( max1 ) ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return rv; } float sse_pulPoTf5L8(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("sse_pulPoTf5L8()"); #endif __m128 sum1, sum2, max1, max2; __m128 tmp1, tmp2; int i; max1 = max2 = _mm_set_ps1( 0.0 ); float *ptr1 = ss[0]; float *ptr2 = ss[0] + P->tmp0; float *ptr3 = ss[0] + P->tmp1; float *ptr4 = ss[0] + P->tmp2; float *ptr5 = ss[0] + P->tmp3; // SSE Pipeline #1 SSE Pipeline #2 // int mask1 = sse_msks1[ P->di ]; int mask2 = sse_msks2[ P->di ]; sum1 = _mm_load_ps( &ptr1[0] ); sum2 = _mm_load_ps( &ptr1[4] ); s_getU(tmp1, &ptr2[0] ); s_getU(tmp2, &ptr2[4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr3[0] ); s_getU(tmp2, &ptr3[4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr4[0] ); s_getU(tmp2, &ptr4[4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); s_getU(tmp1, &ptr5[0] ); s_getU(tmp2, &ptr5[4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); _mm_store_ps( &P->dest[0], sum1 ); _mm_store_ps( &P->dest[4], sum2 ); sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); sum2 = _mm_sub_ps(sum2, SSE_LIM( mask2 ) ); max1 = _mm_max_ps( max1, sum1 ); max2 = _mm_max_ps( max2, sum2 ); float rv= ( s_maxp2f( _mm_max_ps( max1, max2 ) ) ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return rv; } float sse_pulPoTf5L4(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("sse_pulPoTf5L4()"); #endif __m128 sum1, sum2, max1, max2; __m128 tmp1, tmp2; int i; max1 = max2 = _mm_set_ps1( 0.0 ); float *ptr1 = ss[0]; float *ptr2 = ss[0] + P->tmp0; float *ptr3 = ss[0] + P->tmp1; float *ptr4 = ss[0] + P->tmp2; float *ptr5 = ss[0] + P->tmp3; int mask1 = sse_msks1[ P->di ]; sum1 = _mm_load_ps( &ptr1[0] ); s_getU(tmp1, &ptr2[0] ); sum1 = _mm_add_ps( sum1, tmp1 ); s_getU(tmp1, &ptr3[0] ); sum1 = _mm_add_ps( sum1, tmp1 ); s_getU(tmp1, &ptr4[0] ); sum1 = _mm_add_ps( sum1, tmp1 ); s_getU(tmp1, &ptr5[0] ); sum1 = _mm_add_ps( sum1, tmp1 ); _mm_store_ps( &P->dest[0], sum1 ); sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); max1 = _mm_max_ps( max1, sum1 ); float rv= ( s_maxp2f( max1 ) ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return rv; } sum_func BHSSETB5[FOLDTBLEN] = { sse_pulPoTf5L4, sse_pulPoTf5L4, sse_pulPoTf5L4, sse_pulPoTf5L4, sse_pulPoTf5L4, sse_pulPoTf5L8, sse_pulPoTf5L8, sse_pulPoTf5L8, sse_pulPoTf5L8, sse_pulPoTf5, sse_pulPoTf5, sse_pulPoTf5, sse_pulPoTf5, sse_pulPoTf5, sse_pulPoTf5, sse_pulPoTf5, sse_pulPoTf5, sse_pulPoTf5, sse_pulPoTf5, sse_pulPoTf5, sse_pulPoTf5, sse_pulPoTf5, sse_pulPoTf5, sse_pulPoTf5, sse_pulPoTf5u }; // // Fold by 2 versions // float sse_pulPoTf2u(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("sse_pulPoTf2u()"); #endif __m128 sum1, sum2, tmp1, tmp2, max1, max2; int i; max1 = max2 = _mm_set_ps1( 0.0 ); float *ptr1 = ss[1]+P->offset; float *ptr2 = ss[1]+P->tmp0; const int stride = 24; for (i = 0; i < P->di - ( stride - 1 ); i += stride ) { // SSE Pipeline #1 SSE Pipeline #2 // sum1 = _mm_load_ps( &ptr1[i + 0] ); sum2 = _mm_load_ps( &ptr1[i + 4] ); s_getU(tmp1, &ptr2[i + 0] ); s_getU(tmp2, &ptr2[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); max1 = _mm_max_ps( max1, sum1 ); max2 = _mm_max_ps( max2, sum2 ); _mm_store_ps( &P->dest[i + 0], sum1 ); _mm_store_ps( &P->dest[i +4], sum2 ); sum1 = _mm_load_ps( &ptr1[i + 8] ); sum2 = _mm_load_ps( &ptr1[i + 12] ); s_getU(tmp1, &ptr2[i + 8] ); s_getU(tmp2, &ptr2[i + 12] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); max1 = _mm_max_ps( max1, sum1 ); max2 = _mm_max_ps( max2, sum2 ); _mm_store_ps( &P->dest[i + 8], sum1 ); _mm_store_ps( &P->dest[i +12], sum2 ); sum1 = _mm_load_ps( &ptr1[i + 16] ); sum2 = _mm_load_ps( &ptr1[i + 20] ); s_getU(tmp1, &ptr2[i + 16] ); s_getU(tmp2, &ptr2[i + 20] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); max1 = _mm_max_ps( max1, sum1 ); max2 = _mm_max_ps( max2, sum2 ); _mm_store_ps( &P->dest[i + 16], sum1 ); _mm_store_ps( &P->dest[i +20], sum2 ); } max1 = _mm_max_ps( max1, max2 ); for ( ; i < P->di ; i += 4) { int mask1 = sse_msks1[ P->di-i]; sum1 = _mm_load_ps( &ptr1[i + 0] ); s_getU(tmp1, &ptr2[i + 0] ); sum1 = _mm_add_ps( sum1, tmp1 ); _mm_store_ps( &P->dest[i + 0], sum1 ); sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); max1 = _mm_max_ps( max1, sum1 ); } float rv= ( s_maxp2f( max1 ) ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return rv; } float sse_pulPoTf2(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("sse_pulPoTf2()"); #endif __m128 sum1, sum2, tmp1, tmp2, max1, max2; int i; max1 = max2 = _mm_set_ps1( 0.0 ); float *ptr1 = ss[1]+P->offset; float *ptr2 = ss[1]+P->tmp0; const int stride = 8; for (i = 0; i < P->di - ( stride - 1 ); i += stride ) { // SSE Pipeline #1 SSE Pipeline #2 // sum1 = _mm_load_ps( &ptr1[i + 0] ); sum2 = _mm_load_ps( &ptr1[i + 4] ); s_getU(tmp1, &ptr2[i + 0] ); s_getU(tmp2, &ptr2[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); max1 = _mm_max_ps( max1, sum1 ); max2 = _mm_max_ps( max2, sum2 ); _mm_store_ps( &P->dest[i + 0], sum1 ); _mm_store_ps( &P->dest[i +4], sum2 ); } max1 = _mm_max_ps( max1, max2 ); for ( ; i < P->di ; i += 4) { int mask1 = sse_msks1[ P->di-i]; sum1 = _mm_load_ps( &ptr1[i + 0] ); s_getU(tmp1, &ptr2[i + 0] ); sum1 = _mm_add_ps( sum1, tmp1 ); _mm_store_ps( &P->dest[i + 0], sum1 ); sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); max1 = _mm_max_ps( max1, sum1 ); } float rv= ( s_maxp2f( max1 ) ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return rv; } float sse_pulPoTf2L8(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("sse_pulPoTf2L8()"); #endif __m128 sum1, sum2, tmp1, tmp2, max1, max2; int i; max1 = max2 = _mm_set_ps1( 0.0 ); float *ptr1 = ss[1]+P->offset; float *ptr2 = ss[1]+P->tmp0; // SSE Pipeline #1 SSE Pipeline #2 // int mask1 = sse_msks1[ P->di ]; int mask2 = sse_msks2[ P->di ]; sum1 = _mm_load_ps( &ptr1[0] ); sum2 = _mm_load_ps( &ptr1[4] ); s_getU(tmp1, &ptr2[0] ); s_getU(tmp2, &ptr2[4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); _mm_store_ps( &P->dest[0], sum1 ); _mm_store_ps( &P->dest[4], sum2 ); sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); sum2 = _mm_sub_ps(sum2, SSE_LIM( mask2 ) ); max1 = _mm_max_ps( max1, sum1 ); max2 = _mm_max_ps( max2, sum2 ); float rv= ( s_maxp2f( _mm_max_ps( max1, max2 ) ) ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return rv; } float sse_pulPoTf2L4(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("sse_pulPoTf2L4()"); #endif __m128 sum1, tmp1, max1; int i; max1 = _mm_set_ps1( 0.0 ); float *ptr1 = ss[1]+P->offset; float *ptr2 = ss[1]+P->tmp0; // int mask1 = sse_msks1[ P->di ]; sum1 = _mm_load_ps( &ptr1[0] ); s_getU(tmp1, &ptr2[0] ); sum1 = _mm_add_ps( sum1, tmp1 ); _mm_store_ps( &P->dest[0], sum1 ); sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); max1 = _mm_max_ps( max1, sum1 ); float rv= ( s_maxp2f( max1 ) ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return rv; } sum_func BHSSETB2[FOLDTBLEN] = { sse_pulPoTf2L4, sse_pulPoTf2L4, sse_pulPoTf2L4, sse_pulPoTf2L4, sse_pulPoTf2L4, sse_pulPoTf2L8, sse_pulPoTf2L8, sse_pulPoTf2L8, sse_pulPoTf2L8, sse_pulPoTf2, sse_pulPoTf2, sse_pulPoTf2, sse_pulPoTf2, sse_pulPoTf2, sse_pulPoTf2, sse_pulPoTf2, sse_pulPoTf2, sse_pulPoTf2, sse_pulPoTf2, sse_pulPoTf2, sse_pulPoTf2, sse_pulPoTf2, sse_pulPoTf2, sse_pulPoTf2, sse_pulPoTf2u, sse_pulPoTf2u, sse_pulPoTf2u, sse_pulPoTf2u, sse_pulPoTf2u, sse_pulPoTf2u, sse_pulPoTf2u, sse_pulPoTf2u }; // versions for tmp0 aligned // float sse_pulPoTf2ALu(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("sse_pulPoTf2ALu()"); #endif __m128 sum1, sum2, tmp1, tmp2, max1, max2; int i; max1 = max2 = _mm_set_ps1( 0.0 ); float *ptr1 = ss[1]+P->offset; float *ptr2 = ss[1]+P->tmp0; const int stride = 24; for (i = 0; i < P->di - ( stride - 1 ); i += stride ) { // SSE Pipeline #1 SSE Pipeline #2 // sum1 = _mm_load_ps( &ptr1[i + 0] ); sum2 = _mm_load_ps( &ptr1[i + 4] ); tmp1 = _mm_load_ps( &ptr2[i + 0] ); tmp2 = _mm_load_ps( &ptr2[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); max1 = _mm_max_ps( max1, sum1 ); max2 = _mm_max_ps( max2, sum2 ); _mm_store_ps( &P->dest[i + 0], sum1 ); _mm_store_ps( &P->dest[i +4], sum2 ); sum1 = _mm_load_ps( &ptr1[i + 8] ); sum2 = _mm_load_ps( &ptr1[i + 12] ); tmp1 = _mm_load_ps( &ptr2[i + 8] ); tmp2 = _mm_load_ps( &ptr2[i + 12] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); max1 = _mm_max_ps( max1, sum1 ); max2 = _mm_max_ps( max2, sum2 ); _mm_store_ps( &P->dest[i + 8], sum1 ); _mm_store_ps( &P->dest[i +12], sum2 ); sum1 = _mm_load_ps( &ptr1[i + 16] ); sum2 = _mm_load_ps( &ptr1[i + 20] ); tmp1 = _mm_load_ps( &ptr2[i + 16] ); tmp2 = _mm_load_ps( &ptr2[i + 20] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); max1 = _mm_max_ps( max1, sum1 ); max2 = _mm_max_ps( max2, sum2 ); _mm_store_ps( &P->dest[i + 16], sum1 ); _mm_store_ps( &P->dest[i +20], sum2 ); } max1 = _mm_max_ps( max1, max2 ); for ( ; i < P->di ; i += 4) { int mask1 = sse_msks1[ P->di-i]; sum1 = _mm_load_ps( &ptr1[i + 0] ); tmp1 = _mm_load_ps( &ptr2[i + 0] ); sum1 = _mm_add_ps( sum1, tmp1 ); _mm_store_ps( &P->dest[i + 0], sum1 ); sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); max1 = _mm_max_ps( max1, sum1 ); } float rv= ( s_maxp2f( max1 ) ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return rv; } float sse_pulPoTf2AL(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("sse_pulPoTf2AL()"); #endif __m128 sum1, sum2, tmp1, tmp2, max1, max2; int i; max1 = max2 = _mm_set_ps1( 0.0 ); float *ptr1 = ss[1]+P->offset; float *ptr2 = ss[1]+P->tmp0; const int stride = 8; for (i = 0; i < P->di - ( stride - 1 ); i += stride ) { // SSE Pipeline #1 SSE Pipeline #2 // sum1 = _mm_load_ps( &ptr1[i + 0] ); sum2 = _mm_load_ps( &ptr1[i + 4] ); tmp1 = _mm_load_ps( &ptr2[i + 0] ); tmp2 = _mm_load_ps( &ptr2[i + 4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); max1 = _mm_max_ps( max1, sum1 ); max2 = _mm_max_ps( max2, sum2 ); _mm_store_ps( &P->dest[i + 0], sum1 ); _mm_store_ps( &P->dest[i +4], sum2 ); } max1 = _mm_max_ps( max1, max2 ); for ( ; i < P->di ; i += 4) { int mask1 = sse_msks1[ P->di-i]; sum1 = _mm_load_ps( &ptr1[i + 0] ); tmp1 = _mm_load_ps( &ptr2[i + 0] ); sum1 = _mm_add_ps( sum1, tmp1 ); _mm_store_ps( &P->dest[i + 0], sum1 ); sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); max1 = _mm_max_ps( max1, sum1 ); } float rv= ( s_maxp2f( max1 ) ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return rv; } float sse_pulPoTf2AL8(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("sse_pulPoTf2AL8()"); #endif __m128 sum1, sum2, tmp1, tmp2, max1, max2; int i; max1 = max2 = _mm_set_ps1( 0.0 ); float *ptr1 = ss[1]+P->offset; float *ptr2 = ss[1]+P->tmp0; // SSE Pipeline #1 SSE Pipeline #2 // int mask1 = sse_msks1[ P->di ]; int mask2 = sse_msks2[ P->di ]; sum1 = _mm_load_ps( &ptr1[0] ); sum2 = _mm_load_ps( &ptr1[4] ); tmp1 = _mm_load_ps( &ptr2[0] ); tmp2 = _mm_load_ps( &ptr2[4] ); sum1 = _mm_add_ps( sum1, tmp1 ); sum2 = _mm_add_ps( sum2, tmp2 ); _mm_store_ps( &P->dest[0], sum1 ); _mm_store_ps( &P->dest[4], sum2 ); sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); sum2 = _mm_sub_ps(sum2, SSE_LIM( mask2 ) ); max1 = _mm_max_ps( max1, sum1 ); max2 = _mm_max_ps( max2, sum2 ); float rv= ( s_maxp2f( _mm_max_ps( max1, max2 ) ) ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return rv; } float sse_pulPoTf2AL4(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("sse_pulPoTf2AL4()"); #endif __m128 sum1, tmp1, max1; int i; max1 = _mm_set_ps1( 0.0 ); float *ptr1 = ss[1]+P->offset; float *ptr2 = ss[1]+P->tmp0; // int mask1 = sse_msks1[ P->di]; sum1 = _mm_load_ps( &ptr1[0] ); tmp1 = _mm_load_ps( &ptr2[0] ); sum1 = _mm_add_ps( sum1, tmp1 ); _mm_store_ps( &P->dest[0], sum1 ); sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); max1 = _mm_max_ps( max1, sum1 ); float rv= ( s_maxp2f( max1 ) ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return rv; } sum_func BHSSETB2AL[FOLDTBLEN] = { sse_pulPoTf2AL4, sse_pulPoTf2AL4, sse_pulPoTf2AL4, sse_pulPoTf2AL4, sse_pulPoTf2AL4, sse_pulPoTf2AL8, sse_pulPoTf2AL8, sse_pulPoTf2AL8, sse_pulPoTf2AL8, sse_pulPoTf2AL, sse_pulPoTf2AL, sse_pulPoTf2AL, sse_pulPoTf2AL, sse_pulPoTf2AL, sse_pulPoTf2AL, sse_pulPoTf2AL, sse_pulPoTf2AL, sse_pulPoTf2AL, sse_pulPoTf2AL, sse_pulPoTf2AL, sse_pulPoTf2AL, sse_pulPoTf2AL, sse_pulPoTf2AL, sse_pulPoTf2AL, sse_pulPoTf2ALu }; FoldSet BHSSEfold = {BHSSETB3, BHSSETB4, BHSSETB5, BHSSETB2, BHSSETB2AL, "BH SSE"}; /************************************* * * SSE folding subroutines from SSE2 by Alex Kan * * Modified by Joe Segur * */ typedef union submask { float f[4]; __m128 v; }; submask tailmask[4] = { { 0.0f, 0.0f, 0.0f, 0.0f}, { 0.0f, 1e37f, 1e37f, 1e37f}, { 0.0f, 0.0f, 1e37f, 1e37f}, { 0.0f, 0.0f, 0.0f, 1e37f} }; float foldArrayBy3(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("foldArrayBy3()"); #endif float max; __m128 maxV = ZERO; int i = 0; const float *p1 = ss[0], *p2 = ss[0]+P->tmp0, *p3 = ss[0]+P->tmp1; float *pst = P->dest; __m128 x1, x2, x3, xs12, xs; while (i < P->di-4) { x1 = _mm_load_ps(p1+i); x2 = _mm_loadu_ps(p2+i); x3 = _mm_loadu_ps(p3+i); xs12 = _mm_add_ps(x1, x2); xs = _mm_add_ps(xs12, x3); _mm_store_ps(pst+i, xs); maxV = _mm_max_ps(maxV, xs); i += 4; } x1 = _mm_load_ps(p1+i); x2 = _mm_loadu_ps(p2+i); x3 = _mm_loadu_ps(p3+i); xs12 = _mm_add_ps(x1, x2); xs = _mm_add_ps(xs12, x3); _mm_store_ps(pst+i, xs); xs = _mm_sub_ps(xs, tailmask[P->di & 0x3].v); maxV = _mm_max_ps(maxV, xs); maxV = _mm_max_ps(maxV, _mm_shuffle_ps(maxV, maxV, 0x4e)); maxV = _mm_max_ps(maxV, _mm_shuffle_ps(maxV, maxV, 0x39)); _mm_store_ss(&max, maxV); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return max; } float foldArrayBy3LO(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("foldArrayBy3LO()"); #endif const float *p1 = ss[0], *p2 = ss[0]+P->tmp0, *p3 = ss[0]+P->tmp1; float *pst = P->dest; float max = 0.0f; int i = 0; while (i < P->di) { pst[i] = p1[i] + p2[i] + p3[i]; if (pst[i] > max) max = pst[i]; i += 1; } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return max; } sum_func AKSSETB3[FOLDTBLEN] = { foldArrayBy3LO, foldArrayBy3LO, foldArrayBy3LO, foldArrayBy3LO, foldArrayBy3LO, foldArrayBy3LO, foldArrayBy3LO, foldArrayBy3LO, foldArrayBy3, foldArrayBy3LO, foldArrayBy3LO, foldArrayBy3LO, foldArrayBy3 }; float foldArrayBy4(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("foldArrayBy4()"); #endif float max; __m128 maxV = ZERO; int i = 0; const float *p1 = ss[0], *p2 = ss[0]+P->tmp0, *p3 = ss[0]+P->tmp1, *p4 = ss[0]+P->tmp2; float *pst = P->dest; __m128 x1, x2, x3, x4, xs12, xs34, xs; while (i < P->di-4) { x1 = _mm_load_ps(p1+i); x2 = _mm_loadu_ps(p2+i); x3 = _mm_loadu_ps(p3+i); x4 = _mm_loadu_ps(p4+i); xs12 = _mm_add_ps(x1, x2); xs34 = _mm_add_ps(x3, x4); xs = _mm_add_ps(xs12, xs34); _mm_store_ps(pst+i, xs); maxV = _mm_max_ps(maxV, xs); i += 4; } x1 = _mm_load_ps(p1+i); x2 = _mm_loadu_ps(p2+i); x3 = _mm_loadu_ps(p3+i); x4 = _mm_loadu_ps(p4+i); xs12 = _mm_add_ps(x1, x2); xs34 = _mm_add_ps(x3, x4); xs = _mm_add_ps(xs12, xs34); _mm_store_ps(pst+i, xs); xs = _mm_sub_ps(xs, tailmask[P->di & 0x3].v); maxV = _mm_max_ps(maxV, xs); maxV = _mm_max_ps(maxV, _mm_shuffle_ps(maxV, maxV, 0x4e)); maxV = _mm_max_ps(maxV, _mm_shuffle_ps(maxV, maxV, 0x39)); _mm_store_ss(&max, maxV); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return max; } float foldArrayBy4LO(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("foldArrayBy4LO()"); #endif const float *p1 = ss[0], *p2 = ss[0]+P->tmp0, *p3 = ss[0]+P->tmp1, *p4 = ss[0]+P->tmp2; float *pst = P->dest; float max = 0.0f; int i = 0; while (i < P->di) { pst[i] = p1[i] + p2[i] + p3[i] + p4[i]; if (pst[i] > max) max = pst[i]; i += 1; } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return max; } sum_func AKSSETB4[FOLDTBLEN] = { foldArrayBy4LO, foldArrayBy4LO, foldArrayBy4LO, foldArrayBy4LO, foldArrayBy4LO, foldArrayBy4LO, foldArrayBy4LO, foldArrayBy4LO, foldArrayBy4, foldArrayBy4LO, foldArrayBy4LO, foldArrayBy4LO, foldArrayBy4 }; float foldArrayBy5(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("foldArrayBy5()"); #endif float max; __m128 maxV = ZERO; int i = 0; const float *p1 = ss[0], *p2 = ss[0]+P->tmp0, *p3 = ss[0]+P->tmp1, *p4 = ss[0]+P->tmp2, *p5 = ss[0]+P->tmp3; float *pst = P->dest; __m128 x1, x2, x3, x4, x5, xs12, xs34, xs125, xs; while (i < P->di-4) { x1 = _mm_load_ps(p1+i); x2 = _mm_loadu_ps(p2+i); x3 = _mm_loadu_ps(p3+i); x4 = _mm_loadu_ps(p4+i); x5 = _mm_loadu_ps(p5+i); xs12 = _mm_add_ps(x1, x2); xs34 = _mm_add_ps(x3, x4); xs125 = _mm_add_ps(xs12, x5); xs = _mm_add_ps(xs34, xs125); _mm_store_ps(pst+i, xs); maxV = _mm_max_ps(maxV, xs); i += 4; } x1 = _mm_load_ps(p1+i); x2 = _mm_loadu_ps(p2+i); x3 = _mm_loadu_ps(p3+i); x4 = _mm_loadu_ps(p4+i); x5 = _mm_loadu_ps(p5+i); xs12 = _mm_add_ps(x1, x2); xs34 = _mm_add_ps(x3, x4); xs125 = _mm_add_ps(xs12, x5); xs = _mm_add_ps(xs34, xs125); _mm_store_ps(pst+i, xs); xs = _mm_sub_ps(xs, tailmask[P->di & 0x3].v); maxV = _mm_max_ps(maxV, xs); maxV = _mm_max_ps(maxV, _mm_shuffle_ps(maxV, maxV, 0x4e)); maxV = _mm_max_ps(maxV, _mm_shuffle_ps(maxV, maxV, 0x39)); _mm_store_ss(&max, maxV); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return max; } float foldArrayBy5LO(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("foldArrayBy5LO()"); #endif const float *p1 = ss[0], *p2 = ss[0]+P->tmp0, *p3 = ss[0]+P->tmp1, *p4 = ss[0]+P->tmp2, *p5 = ss[0]+P->tmp3; float *pst = P->dest; float max = 0.0f; int i = 0; while (i < P->di) { pst[i] = p1[i] + p2[i] + p3[i] + p4[i] + p5[i]; if (pst[i] > max) max = pst[i]; i += 1; } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return max; } sum_func AKSSETB5[FOLDTBLEN] = { foldArrayBy5LO, foldArrayBy5LO, foldArrayBy5LO, foldArrayBy5LO, foldArrayBy5LO, foldArrayBy5LO, foldArrayBy5LO, foldArrayBy5LO, foldArrayBy5, foldArrayBy5LO, foldArrayBy5LO, foldArrayBy5LO, foldArrayBy5 }; // 2A version allows non-aligned tmp0 float foldArrayBy2A(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("FoldArrayBy2A()"); #endif float max; __m128 maxV = ZERO; int i = 0; const float *p1 = ss[1]+P->offset, *p2 = ss[1]+P->tmp0; float *pst = P->dest; __m128 x1, x2, xs; while (i < P->di-4) { x1 = _mm_load_ps(p1+i); x2 = _mm_loadu_ps(p2+i); xs = _mm_add_ps(x1, x2); _mm_store_ps(pst+i, xs); maxV = _mm_max_ps(maxV, xs); i += 4; } x1 = _mm_load_ps(p1+i); x2 = _mm_loadu_ps(p2+i); xs = _mm_add_ps(x1, x2); _mm_store_ps(pst+i, xs); xs = _mm_sub_ps(xs, tailmask[P->di & 0x3].v); maxV = _mm_max_ps(maxV, xs); maxV = _mm_max_ps(maxV, _mm_shuffle_ps(maxV, maxV, 0x4e)); maxV = _mm_max_ps(maxV, _mm_shuffle_ps(maxV, maxV, 0x39)); _mm_store_ss(&max, maxV); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return max; } // 2AL version requires aligned tmp0 float foldArrayBy2AL(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("foldArrayBy2AL()"); #endif float max; __m128 maxV = ZERO; int i = 0; const float *p1 = ss[1]+P->offset, *p2 = ss[1]+P->tmp0; float *pst = P->dest; __m128 x1, x2, xs; while (i < P->di-4) { x1 = _mm_load_ps(p1+i); x2 = _mm_load_ps(p2+i); xs = _mm_add_ps(x1, x2); _mm_store_ps(pst+i, xs); maxV = _mm_max_ps(maxV, xs); i += 4; } x1 = _mm_load_ps(p1+i); x2 = _mm_load_ps(p2+i); xs = _mm_add_ps(x1, x2); _mm_store_ps(pst+i, xs); xs = _mm_sub_ps(xs, tailmask[P->di & 0x3].v); maxV = _mm_max_ps(maxV, xs); maxV = _mm_max_ps(maxV, _mm_shuffle_ps(maxV, maxV, 0x4e)); maxV = _mm_max_ps(maxV, _mm_shuffle_ps(maxV, maxV, 0x39)); _mm_store_ss(&max, maxV); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return max; } float foldArrayBy2LO(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("foldArrayBy2LO()"); #endif const float *p1 = ss[1]+P->offset, *p2 = ss[1]+P->tmp0; float *pst = P->dest; float max = 0.0f; int i = 0; while (i < P->di) { pst[i] = p1[i] + p2[i]; if (pst[i] > max) max = pst[i]; i += 1; } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return max; } sum_func AKSSETB2[FOLDTBLEN] = { foldArrayBy2LO, foldArrayBy2LO, foldArrayBy2LO, foldArrayBy2LO, foldArrayBy2LO, foldArrayBy2LO, foldArrayBy2LO, foldArrayBy2LO, foldArrayBy2A, foldArrayBy2LO, foldArrayBy2LO, foldArrayBy2LO, foldArrayBy2A }; sum_func AKSSETB2AL[FOLDTBLEN] = { foldArrayBy2LO, foldArrayBy2LO, foldArrayBy2LO, foldArrayBy2LO, foldArrayBy2LO, foldArrayBy2LO, foldArrayBy2LO, foldArrayBy2LO, foldArrayBy2AL, foldArrayBy2LO, foldArrayBy2LO, foldArrayBy2LO, foldArrayBy2AL }; FoldSet AKSSEfold = {AKSSETB3, AKSSETB4, AKSSETB5, AKSSETB2, AKSSETB2AL, "AK SSE"}; #endif // USE_INTRINSICS #endif // (__i386__) || (__x86_64__) boinc-app-seti_8.00~svn3701.orig/client/vector/analyzeFuncs_avx.cpp0000644000175000017500000015454512620200404025322 0ustar locutuslocutus/****************** * * analyzeFuncs_avx.cpp * * Description: Intel AVX optimzized functions * CPUs: Intel Core iX xxxx+ * */ // Copyright 2011 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define USE_MATH_DEFINES #include "sah_config.h" //JWS: For a release build using this module, compile with -mavx on GCC 4.4 or // later or whatever is equivalent for the compiler used. Define USE_AVX and // USE_INTRINSICS also. // // For tests on x86 hardware without AVX capability, Intel provides an SDE // (Software Development Emulator) to do runtime replacement of AVX instructions // or an avxintrin_emu.h header file which does compile-time replacement of the // AVX intrinsics. For that latter method, define AVX_EMU to get the header // file included and build for SSE3 or better. // The following is empty if USE_AVX and USE_INTRINSICS are not both defined #if defined(USE_AVX) && defined (USE_INTRINSICS) #include #include #ifdef AVX_EMU #include "avxintrin_emu.h" #elif defined(_MSC_VER) #include #else #ifdef __clang__ #define __AVX__ 1 #endif #include #endif #include "s_util.h" #include "analyzeFuncs_vector.h" #include "analyzeFuncs.h" #include "x86_ops.h" #include "pulsefind.h" #ifndef M_PI #define M_PI 3.14159265358979323846 #endif // ============================================================================= // JWS: Four variant chirp functions, first expands constants in memory // // Using Mendenhall Faster SinCos, coding based on // v_vChirpData for SSE3 by: Alex Kan // int avx_ChirpData_a( sah_complex * cx_DataArray, sah_complex * cx_ChirpDataArray, int chirp_rate_ind, const double chirp_rate, int ul_NumDataPoints, const double sample_rate ) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("avx_ChirpData_a()"); #endif int i, vEnd; if (chirp_rate_ind == 0) { memcpy(cx_ChirpDataArray, cx_DataArray, (int)ul_NumDataPoints * sizeof(sah_complex) ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } const double srate = chirp_rate * 0.5 / (sample_rate * sample_rate); __m256 ss1fA = _mm256_set1_ps(1.5707963235f); __m256 ss2fA = _mm256_set1_ps(-0.645963615f); __m256 ss3fA = _mm256_set1_ps(0.0796819754f); __m256 ss4fA = _mm256_set1_ps(-0.0046075748f); __m256 cc1fA = _mm256_set1_ps(-1.2336977925f); __m256 cc2fA = _mm256_set1_ps(0.2536086171f); __m256 cc3fA = _mm256_set1_ps(-0.0204391631f); __m256 oneA = _mm256_set1_ps(1.0f); __m256 twoA = _mm256_set1_ps(2.0f); __m256d eightA = _mm256_set1_pd(8.0); __m256d rate = _mm256_broadcast_sd(&srate); __m256d roundVal = _mm256_set1_pd((srate >= 0.0) ? TWO_TO_52 : -TWO_TO_52); // main vectorised loop vEnd = ul_NumDataPoints - (ul_NumDataPoints & 7); __m256d di1 = _mm256_set_pd(5.0, 1.0, 4.0, 0.0); // set time patterns for eventual moveldup/movehdup __m256d di2 = _mm256_set_pd(7.0, 3.0, 6.0, 2.0); for (i = 0; i < vEnd; i += 8) { const float *data = (const float *) (cx_DataArray + i); float *chirped = (float *) (cx_ChirpDataArray + i); __m256d a1, a2; __m256 d1, d2; __m256 cd1, cd2; __m256 td1, td2; __m256 x; __m256 y; __m256 z; __m256 s; __m256 c; __m256 m; // load the signal to be chirped prefetchnta((const void *)( data+64 )); d1 = _mm256_load_ps(data); d2 = _mm256_load_ps(data+8); // calculate the input angles a1 = _mm256_mul_pd(_mm256_mul_pd(di1, di1), rate); a2 = _mm256_mul_pd(_mm256_mul_pd(di2, di2), rate); // update time values for next iteration di1 = _mm256_add_pd(di1, eightA); di2 = _mm256_add_pd(di2, eightA); // reduce the angles to the range (-0.5, 0.5) a1 = _mm256_sub_pd(a1, _mm256_sub_pd(_mm256_add_pd(a1, roundVal), roundVal)); a2 = _mm256_sub_pd(a2, _mm256_sub_pd(_mm256_add_pd(a2, roundVal), roundVal)); // convert the 2 packed doubles to packed single x = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm256_cvtpd_ps(a1)), _mm256_cvtpd_ps(a2), 1); // square to the range [0, 0.25) y = _mm256_mul_ps(x, x); // perform the initial polynomial approximations z = _mm256_mul_ps(y, y); s = _mm256_mul_ps(_mm256_add_ps(_mm256_mul_ps(_mm256_add_ps(_mm256_mul_ps(y, ss4fA), ss3fA), z), _mm256_add_ps(_mm256_mul_ps(y, ss2fA), ss1fA)), x); c = _mm256_add_ps(_mm256_mul_ps(_mm256_add_ps(_mm256_mul_ps(y, cc3fA), cc2fA), z), _mm256_add_ps(_mm256_mul_ps(y, cc1fA), oneA)); // perform first angle doubling x = _mm256_sub_ps(_mm256_mul_ps(c, c), _mm256_mul_ps(s, s)); y = _mm256_mul_ps(_mm256_mul_ps(s, c), twoA); // calculate scaling factor to correct the magnitude m = _mm256_sub_ps(_mm256_sub_ps(twoA, _mm256_mul_ps(x, x)), _mm256_mul_ps(y, y)); // perform second angle doubling c = _mm256_sub_ps(_mm256_mul_ps(x, x), _mm256_mul_ps(y, y)); s = _mm256_mul_ps(_mm256_mul_ps(y, x), twoA); // correct the magnitude (final sine / cosine approximations) s = _mm256_mul_ps(s, m); c = _mm256_mul_ps(c, m); // c7 c3 c6 c2 c5 c1 c4 c0 // chirp the data cd1 = _mm256_moveldup_ps(c); // c3 c3 c2 c2 c1 c1 c0 c0 cd2 = _mm256_movehdup_ps(c); // c7 c7 c6 c6 c5 c5 c4 c4 cd1 = _mm256_mul_ps(cd1, d1); // c3.i3 c3.r3 c2.i2 c2.r2 c1.i1 c1.r1 c0.i0 c0.r0 cd2 = _mm256_mul_ps(cd2, d2); // c7.i7 c7.r7 c6.i6 c6.r6 c5.i5 c5.r5 c4.i4 c4.r4 d1 = _mm256_shuffle_ps(d1, d1, 0xb1); d2 = _mm256_shuffle_ps(d2, d2, 0xb1); td1 = _mm256_moveldup_ps(s); td2 = _mm256_movehdup_ps(s); td1 = _mm256_mul_ps(td1, d1); td2 = _mm256_mul_ps(td2, d2); cd1 = _mm256_addsub_ps(cd1, td1); cd2 = _mm256_addsub_ps(cd2, td2); // store chirped values _mm256_stream_ps(chirped, cd1); _mm256_stream_ps(chirped+8, cd2); } _mm256_zeroupper (); _mm_sfence(); // handle tail elements with scalar code for ( ; i < ul_NumDataPoints; ++i) { double angle = srate * i * i * 0.5; angle -= floor(angle); angle *= M_PI * 2; double s = sin(angle); double c = cos(angle); float re = cx_DataArray[i][0]; float im = cx_DataArray[i][1]; cx_ChirpDataArray[i][0] = re * c - im * s; cx_ChirpDataArray[i][1] = re * s + im * c; } analysis_state.FLOP_counter+=12.0*ul_NumDataPoints; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } // JWS: Second variant, using vbroadcast to expand constants when used int avx_ChirpData_b( sah_complex * cx_DataArray, sah_complex * cx_ChirpDataArray, int chirp_rate_ind, const double chirp_rate, int ul_NumDataPoints, const double sample_rate ) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("avx_ChirpData_b()"); #endif int i, vEnd; if (chirp_rate_ind == 0) { memcpy(cx_ChirpDataArray, cx_DataArray, (int)ul_NumDataPoints * sizeof(sah_complex) ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } const double srate = chirp_rate * 0.5 / (sample_rate * sample_rate); const float ss1f = 1.5707963235f; const float ss2f = -0.645963615f; const float ss3f = 0.0796819754f; const float ss4f = -0.0046075748f; const float cc1f = -1.2336977925f; const float cc2f = 0.2536086171f; const float cc3f = -0.0204391631f; const float one = 1.0f; const float two = 2.0f; const double eight = 8.0; __m256d rate = _mm256_broadcast_sd(&srate); __m256d roundVal = _mm256_set1_pd((srate >= 0.0) ? TWO_TO_52 : -TWO_TO_52); vEnd = ul_NumDataPoints - (ul_NumDataPoints & 7); // main vectorised loop __m256d di1 = _mm256_set_pd(5.0, 1.0, 4.0, 0.0); // set time patterns for eventual moveldup/movehdup __m256d di2 = _mm256_set_pd(7.0, 3.0, 6.0, 2.0); for (i = 0; i < vEnd; i += 8) { const float *data = (const float *) (cx_DataArray + i); float *chirped = (float *) (cx_ChirpDataArray + i); __m256d a1, a2; __m256 d1, d2; __m256 cd1, cd2; __m256 td1, td2; __m256 x; __m256 y; __m256 z; __m256 s; __m256 c; __m256 m; // load the signal to be chirped prefetchnta((const void *)( data+64 )); d1 = _mm256_load_ps(data); d2 = _mm256_load_ps(data+8); // calculate the input angles a1 = _mm256_mul_pd(_mm256_mul_pd(di1, di1), rate); a2 = _mm256_mul_pd(_mm256_mul_pd(di2, di2), rate); // update time values for next iteration di1 = _mm256_add_pd(di1, _mm256_broadcast_sd(&eight)); di2 = _mm256_add_pd(di2, _mm256_broadcast_sd(&eight)); // reduce the angles to the range (-0.5, 0.5) a1 = _mm256_sub_pd(a1, _mm256_sub_pd(_mm256_add_pd(a1, roundVal), roundVal)); a2 = _mm256_sub_pd(a2, _mm256_sub_pd(_mm256_add_pd(a2, roundVal), roundVal)); // convert the 2 packed doubles to packed single x = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm256_cvtpd_ps(a1)), _mm256_cvtpd_ps(a2), 1); // square to the range [0, 0.25) y = _mm256_mul_ps(x, x); // perform the initial polynomial approximations z = _mm256_mul_ps(y, y); s = _mm256_mul_ps(_mm256_add_ps(_mm256_mul_ps(_mm256_add_ps(_mm256_mul_ps(y, _mm256_broadcast_ss(&ss4f)), _mm256_broadcast_ss(&ss3f)), z), _mm256_add_ps(_mm256_mul_ps(y, _mm256_broadcast_ss(&ss2f)), _mm256_broadcast_ss(&ss1f))), x); c = _mm256_add_ps(_mm256_mul_ps(_mm256_add_ps(_mm256_mul_ps(y, _mm256_broadcast_ss(&cc3f)), _mm256_broadcast_ss(&cc2f)), z), _mm256_add_ps(_mm256_mul_ps(y, _mm256_broadcast_ss(&cc1f)), _mm256_broadcast_ss(&one))); // perform first angle doubling x = _mm256_sub_ps(_mm256_mul_ps(c, c), _mm256_mul_ps(s, s)); y = _mm256_mul_ps(_mm256_mul_ps(s, c), _mm256_broadcast_ss(&two)); // calculate scaling factor to correct the magnitude m = _mm256_sub_ps(_mm256_sub_ps(_mm256_broadcast_ss(&two), _mm256_mul_ps(x, x)), _mm256_mul_ps(y, y)); // perform second angle doubling c = _mm256_sub_ps(_mm256_mul_ps(x, x), _mm256_mul_ps(y, y)); s = _mm256_mul_ps(_mm256_mul_ps(y, x), _mm256_broadcast_ss(&two)); // correct the magnitude (final sine / cosine approximations) s = _mm256_mul_ps(s, m); c = _mm256_mul_ps(c, m); // chirp the data cd1 = _mm256_moveldup_ps(c); cd2 = _mm256_movehdup_ps(c); cd1 = _mm256_mul_ps(cd1, d1); cd2 = _mm256_mul_ps(cd2, d2); d1 = _mm256_shuffle_ps(d1, d1, 0xb1); d2 = _mm256_shuffle_ps(d2, d2, 0xb1); td1 = _mm256_moveldup_ps(s); td2 = _mm256_movehdup_ps(s); td1 = _mm256_mul_ps(td1, d1); td2 = _mm256_mul_ps(td2, d2); cd1 = _mm256_addsub_ps(cd1, td1); cd2 = _mm256_addsub_ps(cd2, td2); // store chirped values _mm256_stream_ps(chirped, cd1); _mm256_stream_ps(chirped+8, cd2); } _mm256_zeroupper(); _mm_sfence(); // never happens, handle tail elements with scalar code for ( ; i < ul_NumDataPoints; ++i) { double angle = srate * i * i * 0.5; angle -= floor(angle); angle *= M_PI * 2; double s = sin(angle); double c = cos(angle); float re = cx_DataArray[i][0]; float im = cx_DataArray[i][1]; cx_ChirpDataArray[i][0] = re * c - im * s; cx_ChirpDataArray[i][1] = re * s + im * c; } analysis_state.FLOP_counter+=12.0*ul_NumDataPoints; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } // Third variant, like the first but instruction sequences modified so most instructions // are not dependent on results of immediately preceding instruction. // This may not have much effect on CPUs with excellent out of order capability. int avx_ChirpData_c( sah_complex * cx_DataArray, sah_complex * cx_ChirpDataArray, int chirp_rate_ind, const double chirp_rate, int ul_NumDataPoints, const double sample_rate ) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("avx_ChirpData_c()"); #endif int i, vEnd; if (chirp_rate_ind == 0) { memcpy(cx_ChirpDataArray, cx_DataArray, (int)ul_NumDataPoints * sizeof(sah_complex) ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } const double srate = chirp_rate * 0.5 / (sample_rate * sample_rate); __m256 ss1fA = _mm256_set1_ps(1.5707963235f); __m256 ss2fA = _mm256_set1_ps(-0.645963615f); __m256 ss3fA = _mm256_set1_ps(0.0796819754f); __m256 ss4fA = _mm256_set1_ps(-0.0046075748f); __m256 cc1fA = _mm256_set1_ps(-1.2336977925f); __m256 cc2fA = _mm256_set1_ps(0.2536086171f); __m256 cc3fA = _mm256_set1_ps(-0.0204391631f); __m256 oneA = _mm256_set1_ps(1.0f); __m256 twoA = _mm256_set1_ps(2.0f); __m256d eightA = _mm256_set1_pd(8.0); __m256d rate = _mm256_broadcast_sd(&srate); __m256d roundVal = _mm256_set1_pd((srate >= 0.0) ? TWO_TO_52 : -TWO_TO_52); // main vectorised loop vEnd = ul_NumDataPoints - (ul_NumDataPoints & 7); __m256d di1 = _mm256_set_pd(5.0, 1.0, 4.0, 0.0); // set time patterns for eventual moveldup/movehdup __m256d di2 = _mm256_set_pd(7.0, 3.0, 6.0, 2.0); for (i = 0; i < vEnd; i += 8) { const float *data = (const float *) (cx_DataArray + i); float *chirped = (float *) (cx_ChirpDataArray + i); __m256d a1, a2; __m256 d1, d2; __m256 cd1, cd2; __m256 td1, td2; __m256 v; __m256 w; __m256 x; __m256 y; __m256 z; __m256 s; __m256 c; __m256 m; // load the signal to be chirped prefetchnta((const void *)( data+64 )); d1 = _mm256_load_ps(data); d2 = _mm256_load_ps(data+8); // calculate the input angles a1 = _mm256_mul_pd(di1, di1); a2 = _mm256_mul_pd(di2, di2); a1 = _mm256_mul_pd(a1, rate); a2 = _mm256_mul_pd(a2, rate); // reduce the angles to the range (-0.5, 0.5) a1 = _mm256_sub_pd(a1, _mm256_sub_pd(_mm256_add_pd(a1, roundVal), roundVal)); a2 = _mm256_sub_pd(a2, _mm256_sub_pd(_mm256_add_pd(a2, roundVal), roundVal)); // update time values for next iteration di1 = _mm256_add_pd(di1, eightA); di2 = _mm256_add_pd(di2, eightA); // convert the 2 packed doubles to packed single y = _mm256_castps128_ps256(_mm256_cvtpd_ps(a1)); x = _mm256_insertf128_ps(y, _mm256_cvtpd_ps(a2), 1); // square to the range [0, 0.25) y = _mm256_mul_ps(x, x); // perform the initial polynomial approximations with interleaved Estrin sequences z = _mm256_mul_ps(y, y); s = _mm256_mul_ps(y, ss4fA); c = _mm256_mul_ps(y, cc3fA); s = _mm256_add_ps(s, ss3fA); c = _mm256_add_ps(c, cc2fA); s = _mm256_mul_ps(s, z); c = _mm256_mul_ps(c, z); v = _mm256_mul_ps(y, ss2fA); w = _mm256_mul_ps(y, cc1fA); v = _mm256_add_ps(v, ss1fA); w = _mm256_add_ps(w, oneA); s = _mm256_add_ps(s, v); c = _mm256_add_ps(c, w); s = _mm256_mul_ps(s, x); // perform first angle doubling v = _mm256_mul_ps(c, c); w = _mm256_mul_ps(s, s); y = _mm256_mul_ps(s, c); x = _mm256_sub_ps(v, w); y = _mm256_mul_ps(y, twoA); // calculate scaling factor to correct the magnitude // and interleave the second angle doubling v = _mm256_mul_ps(x, x); w = _mm256_mul_ps(y, y); m = _mm256_sub_ps(twoA, v); c = _mm256_sub_ps(v, w); s = _mm256_mul_ps(y, x); m = _mm256_sub_ps(m, w); s = _mm256_mul_ps(s, twoA); // correct the magnitude (final sine / cosine approximations) c = _mm256_mul_ps(c, m); s = _mm256_mul_ps(s, m); // chirp the data cd1 = _mm256_moveldup_ps(c); td1 = _mm256_moveldup_ps(s); cd2 = _mm256_movehdup_ps(c); td2 = _mm256_movehdup_ps(s); cd1 = _mm256_mul_ps(cd1, d1); cd2 = _mm256_mul_ps(cd2, d2); d1 = _mm256_shuffle_ps(d1, d1, 0xb1); d2 = _mm256_shuffle_ps(d2, d2, 0xb1); td1 = _mm256_mul_ps(td1, d1); td2 = _mm256_mul_ps(td2, d2); cd1 = _mm256_addsub_ps(cd1, td1); cd2 = _mm256_addsub_ps(cd2, td2); // store chirped values _mm256_stream_ps(chirped, cd1); _mm256_stream_ps(chirped+8, cd2); } _mm256_zeroupper (); _mm_sfence(); // handle tail elements with scalar code for ( ; i < ul_NumDataPoints; ++i) { double angle = srate * i * i * 0.5; angle -= floor(angle); angle *= M_PI * 2; double s = sin(angle); double c = cos(angle); float re = cx_DataArray[i][0]; float im = cx_DataArray[i][1]; cx_ChirpDataArray[i][0] = re * c - im * s; cx_ChirpDataArray[i][1] = re * s + im * c; } analysis_state.FLOP_counter+=12.0*ul_NumDataPoints; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } // Fourth variant, like third but using _mm256_round_pd for angle reduction. int avx_ChirpData_d( sah_complex * cx_DataArray, sah_complex * cx_ChirpDataArray, int chirp_rate_ind, const double chirp_rate, int ul_NumDataPoints, const double sample_rate ) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("avx_ChirpData_d()"); #endif int i, vEnd; if (chirp_rate_ind == 0) { memcpy(cx_ChirpDataArray, cx_DataArray, (int)ul_NumDataPoints * sizeof(sah_complex) ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } const double srate = chirp_rate * 0.5 / (sample_rate * sample_rate); __m256 ss1fA = _mm256_set1_ps(1.5707963235f); __m256 ss2fA = _mm256_set1_ps(-0.645963615f); __m256 ss3fA = _mm256_set1_ps(0.0796819754f); __m256 ss4fA = _mm256_set1_ps(-0.0046075748f); __m256 cc1fA = _mm256_set1_ps(-1.2336977925f); __m256 cc2fA = _mm256_set1_ps(0.2536086171f); __m256 cc3fA = _mm256_set1_ps(-0.0204391631f); __m256 oneA = _mm256_set1_ps(1.0f); __m256 twoA = _mm256_set1_ps(2.0f); __m256d eightA = _mm256_set1_pd(8.0); __m256d rate = _mm256_broadcast_sd(&srate); // main vectorised loop vEnd = ul_NumDataPoints - (ul_NumDataPoints & 7); __m256d di1 = _mm256_set_pd(5.0, 1.0, 4.0, 0.0); __m256d di2 = _mm256_set_pd(7.0, 3.0, 6.0, 2.0); for (i = 0; i < vEnd; i += 8) { const float *data = (const float *) (cx_DataArray + i); float *chirped = (float *) (cx_ChirpDataArray + i); __m256d a1, a2; __m256 d1, d2; __m256 cd1, cd2; __m256 td1, td2; __m256 v; __m256 w; __m256 x; __m256 y; __m256 z; __m256 s; __m256 c; __m256 m; // load the signal to be chirped prefetchnta((const void *)( data+64 )); d1 = _mm256_load_ps(data); d2 = _mm256_load_ps(data+8); // calculate the input angles a1 = _mm256_mul_pd(di1, di1); a2 = _mm256_mul_pd(di2, di2); a1 = _mm256_mul_pd(a1, rate); a2 = _mm256_mul_pd(a2, rate); // reduce the angles to the range (-0.5, 0.5) a1 = _mm256_sub_pd(a1, _mm256_round_pd(a1, 0)); // round to nearest a2 = _mm256_sub_pd(a2, _mm256_round_pd(a2, 0)); // update time values for next iteration di1 = _mm256_add_pd(di1, eightA); di2 = _mm256_add_pd(di2, eightA); // convert the 2 packed doubles to packed single y = _mm256_castps128_ps256(_mm256_cvtpd_ps(a1)); x = _mm256_insertf128_ps(y, _mm256_cvtpd_ps(a2), 1); // square to the range [0, 0.25) y = _mm256_mul_ps(x, x); // perform the initial polynomial approximations with interleaved Estrin sequences z = _mm256_mul_ps(y, y); s = _mm256_mul_ps(y, ss4fA); c = _mm256_mul_ps(y, cc3fA); s = _mm256_add_ps(s, ss3fA); c = _mm256_add_ps(c, cc2fA); s = _mm256_mul_ps(s, z); c = _mm256_mul_ps(c, z); v = _mm256_mul_ps(y, ss2fA); w = _mm256_mul_ps(y, cc1fA); v = _mm256_add_ps(v, ss1fA); w = _mm256_add_ps(w, oneA); s = _mm256_add_ps(s, v); c = _mm256_add_ps(c, w); s = _mm256_mul_ps(s, x); // perform first angle doubling v = _mm256_mul_ps(c, c); w = _mm256_mul_ps(s, s); y = _mm256_mul_ps(s, c); x = _mm256_sub_ps(v, w); y = _mm256_mul_ps(y, twoA); // calculate scaling factor to correct the magnitude // and interleave the second angle doubling v = _mm256_mul_ps(x, x); w = _mm256_mul_ps(y, y); m = _mm256_sub_ps(twoA, v); c = _mm256_sub_ps(v, w); s = _mm256_mul_ps(y, x); m = _mm256_sub_ps(m, w); s = _mm256_mul_ps(s, twoA); // correct the magnitude (final sine / cosine approximations) c = _mm256_mul_ps(c, m); s = _mm256_mul_ps(s, m); // chirp the data cd1 = _mm256_moveldup_ps(c); td1 = _mm256_moveldup_ps(s); cd2 = _mm256_movehdup_ps(c); td2 = _mm256_movehdup_ps(s); cd1 = _mm256_mul_ps(cd1, d1); cd2 = _mm256_mul_ps(cd2, d2); d1 = _mm256_shuffle_ps(d1, d1, 0xb1); d2 = _mm256_shuffle_ps(d2, d2, 0xb1); td1 = _mm256_mul_ps(td1, d1); td2 = _mm256_mul_ps(td2, d2); cd1 = _mm256_addsub_ps(cd1, td1); cd2 = _mm256_addsub_ps(cd2, td2); // store chirped values _mm256_stream_ps(chirped, cd1); _mm256_stream_ps(chirped+8, cd2); } _mm256_zeroupper (); _mm_sfence(); // handle tail elements with scalar code for ( ; i < ul_NumDataPoints; ++i) { double angle = srate * i * i * 0.5; angle -= floor(angle); angle *= M_PI * 2; double s = sin(angle); double c = cos(angle); float re = cx_DataArray[i][0]; float im = cx_DataArray[i][1]; cx_ChirpDataArray[i][0] = re * c - im * s; cx_ChirpDataArray[i][1] = re * s + im * c; } analysis_state.FLOP_counter+=12.0*ul_NumDataPoints; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } // ============================================================================= // JWS: AVX transpose functions // inline void v_avxSubTranspose4x8ntw(float *in, float *out, int xline, int yline) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("v_avxSubTranspose4x8ntw()"); #endif // Do two simultaneous 4x4 transposes in the YMM registers, non-temporal writes. // Input is 8 rows of 4 floats, output is 4 columns of 8 floats. // An sfence is needed after using this sub to ensure global visibilty of the writes. __m256 r04 = _mm256_insertf128_ps(_mm256_castps128_ps256(*((__m128*)(in+0*xline))), (*((__m128*)(in+4*xline))), 0x1); // a0b0c0d0a4b4c4d4 __m256 r26 = _mm256_insertf128_ps(_mm256_castps128_ps256(*((__m128*)(in+2*xline))), (*((__m128*)(in+6*xline))), 0x1); // a2b2c2d2a6b6c6d6 __m256 r15 = _mm256_insertf128_ps(_mm256_castps128_ps256(*((__m128*)(in+1*xline))), (*((__m128*)(in+5*xline))), 0x1); // a1b1c1d1a5b5c5d5 __m256 r37 = _mm256_insertf128_ps(_mm256_castps128_ps256(*((__m128*)(in+3*xline))), (*((__m128*)(in+7*xline))), 0x1); // a3b3c3d3a7b7c7d7 __m256 c01e = _mm256_unpacklo_ps(r04, r26); // a0a2b0b2a4a6b4b6 __m256 c23e = _mm256_unpackhi_ps(r04, r26); // c0c2d0d2c4c6d4d6 __m256 c01o = _mm256_unpacklo_ps(r15, r37); // a1a3b1b3a5a7b5b7 __m256 c23o = _mm256_unpackhi_ps(r15, r37); // c1c3d1d3c5c7d5d7 _mm256_stream_ps(out+0*yline, _mm256_unpacklo_ps(c01e, c01o)); // a0a1a2a3a4a5a6a7 _mm256_stream_ps(out+1*yline, _mm256_unpackhi_ps(c01e, c01o)); // b0b1b2b3b4b5b6b7 _mm256_stream_ps(out+2*yline, _mm256_unpacklo_ps(c23e, c23o)); // c0c1c2c3c4c5c6c7 _mm256_stream_ps(out+3*yline, _mm256_unpackhi_ps(c23e, c23o)); // d0d1d2d3d4d5d6d7 #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } int v_avxTranspose4x8ntw(int x, int y, float *in, float *out) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("v_avxTranspose4x8ntw()"); #endif int i,j; for (j=0;jdi) - 1) & 7); __m256 tailelem = _mm256_set_ps(7.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f, 0.0f); __m256 taillim = _mm256_broadcast_ss(&lim); __m256 maxV = _mm256_setzero_ps(); int i = 0; const float *p1 = ss[0], *p2 = ss[0]+P->tmp0, *p3 = ss[0]+P->tmp1; float *pst = P->dest; __m256 x1, x2, tailmask; // No unroll, Sandy Bridge has a limited uop cache which should be conserved. while (i < P->di-8) { x1 = _mm256_load_ps(p1+i); x2 = _mm256_add_ps(x1, *(__m256*)(p2+i)); x1 = _mm256_add_ps(x2, *(__m256*)(p3+i)); _mm256_store_ps(pst+i, x1); maxV = _mm256_max_ps(maxV, x1); i += 8; } x1 = _mm256_load_ps(p1+i); x2 = _mm256_add_ps(x1, *(__m256*)(p2+i)); x1 = _mm256_add_ps(x2, *(__m256*)(p3+i)); tailmask = _mm256_cmp_ps(taillim, tailelem, 0x0d); // taillim floats >= tailelem floats _mm256_maskstore_ps(pst+i, AVX_MASKSTORE_TYPECAST(tailmask), x1); x2 = _mm256_and_ps(x1, tailmask); maxV = _mm256_max_ps(maxV, x2); x1 = _mm256_permute2f128_ps(maxV, maxV, 0x81); maxV = _mm256_max_ps(maxV, x1); // max in low 4 maxV = _mm256_max_ps(maxV, _mm256_shuffle_ps(maxV, maxV, 0xee)); // in low 2 maxV = _mm256_max_ps(maxV, _mm256_shuffle_ps(maxV, maxV, 0x01)); // 1 float max = _mm_cvtss_f32(_mm256_castps256_ps128(maxV)); _mm256_zeroupper(); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return max; } sum_func AVXTBa3[FOLDTBLEN] = {foldBy3}; float foldBy4(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("foldBy4()"); #endif const float lim = (float)(((P->di) - 1) & 7); __m256 tailelem = _mm256_set_ps(7.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f, 0.0f); __m256 taillim = _mm256_broadcast_ss(&lim); __m256 maxV = _mm256_setzero_ps(); int i = 0; const float *p1 = ss[0], *p2 = ss[0]+P->tmp0, *p3 = ss[0]+P->tmp1, *p4 = ss[0]+P->tmp2; float *pst = P->dest; __m256 x1, x2, tailmask; while (i < P->di-8) { x1 = _mm256_load_ps(p1+i); x2 = _mm256_add_ps(x1, *(__m256*)(p2+i)); x1 = _mm256_add_ps(x2, *(__m256*)(p3+i)); x2 = _mm256_add_ps(x1, *(__m256*)(p4+i)); _mm256_store_ps(pst+i, x2); maxV = _mm256_max_ps(maxV, x2); i += 8; } x1 = _mm256_load_ps(p1+i); x2 = _mm256_add_ps(x1, *(__m256*)(p2+i)); x1 = _mm256_add_ps(x2, *(__m256*)(p3+i)); x2 = _mm256_add_ps(x1, *(__m256*)(p4+i)); tailmask = _mm256_cmp_ps(taillim, tailelem, 0x0d); _mm256_maskstore_ps(pst+i, AVX_MASKSTORE_TYPECAST(tailmask), x2); x1 = _mm256_and_ps(x2, tailmask); maxV = _mm256_max_ps(maxV, x1); x2 = _mm256_permute2f128_ps(maxV, maxV, 0x81); maxV = _mm256_max_ps(maxV, x2); maxV = _mm256_max_ps(maxV, _mm256_shuffle_ps(maxV, maxV, 0xee)); maxV = _mm256_max_ps(maxV, _mm256_shuffle_ps(maxV, maxV, 0x01)); float max = _mm_cvtss_f32(_mm256_castps256_ps128(maxV)); _mm256_zeroupper(); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return max; } sum_func AVXTBa4[FOLDTBLEN] = {foldBy4}; float foldBy5(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("foldBy5()"); #endif const float lim = (float)(((P->di) - 1) & 7); __m256 tailelem = _mm256_set_ps(7.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f, 0.0f); __m256 taillim = _mm256_broadcast_ss(&lim); __m256 maxV = _mm256_setzero_ps(); int i = 0; const float *p1 = ss[0], *p2 = ss[0]+P->tmp0, *p3 = ss[0]+P->tmp1, *p4 = ss[0]+P->tmp2, *p5 = ss[0]+P->tmp3; float *pst = P->dest; __m256 x1, x2, tailmask; while (i < P->di-8) { x1 = _mm256_load_ps(p1+i); x2 = _mm256_add_ps(x1, *(__m256*)(p2+i)); x1 = _mm256_add_ps(x2, *(__m256*)(p3+i)); x2 = _mm256_add_ps(x1, *(__m256*)(p4+i)); x1 = _mm256_add_ps(x2, *(__m256*)(p5+i)); _mm256_store_ps(pst+i, x1); maxV = _mm256_max_ps(maxV, x1); i += 8; } x1 = _mm256_load_ps(p1+i); x2 = _mm256_add_ps(x1, *(__m256*)(p2+i)); x1 = _mm256_add_ps(x2, *(__m256*)(p3+i)); x2 = _mm256_add_ps(x1, *(__m256*)(p4+i)); x1 = _mm256_add_ps(x2, *(__m256*)(p5+i)); tailmask = _mm256_cmp_ps(taillim, tailelem, 0x0d); _mm256_maskstore_ps(pst+i, AVX_MASKSTORE_TYPECAST(tailmask), x1); x2 = _mm256_and_ps(x1, tailmask); maxV = _mm256_max_ps(maxV, x2); x1 = _mm256_permute2f128_ps(maxV, maxV, 0x81); maxV = _mm256_max_ps(maxV, x1); maxV = _mm256_max_ps(maxV, _mm256_shuffle_ps(maxV, maxV, 0xee)); maxV = _mm256_max_ps(maxV, _mm256_shuffle_ps(maxV, maxV, 0x01)); float max = _mm_cvtss_f32(_mm256_castps256_ps128(maxV)); _mm256_zeroupper(); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return max; } sum_func AVXTBa5[FOLDTBLEN] = {foldBy5}; float foldBy2(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("foldBy2()"); #endif const float lim = (float)(((P->di) - 1) & 7); __m256 tailelem = _mm256_set_ps(7.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f, 0.0f); __m256 taillim = _mm256_broadcast_ss(&lim); __m256 maxV = _mm256_setzero_ps(); int i = 0; const float *p1 = ss[1]+P->offset, *p2 = ss[1]+P->tmp0; float *pst = P->dest; __m256 x1, x2, tailmask; while (i < P->di-8) { x1 = _mm256_load_ps(p1+i); x2 = _mm256_add_ps(x1, *(__m256*)(p2+i)); _mm256_store_ps(pst+i, x2); maxV = _mm256_max_ps(maxV, x2); i += 8; } x1 = _mm256_load_ps(p1+i); x2 = _mm256_add_ps(x1, *(__m256*)(p2+i)); tailmask = _mm256_cmp_ps(taillim, tailelem, 0x0d); _mm256_maskstore_ps(pst+i, AVX_MASKSTORE_TYPECAST(tailmask), x2); x1 = _mm256_and_ps(x2, tailmask); maxV = _mm256_max_ps(maxV, x1); x2 = _mm256_permute2f128_ps(maxV, maxV, 0x81); maxV = _mm256_max_ps(maxV, x2); maxV = _mm256_max_ps(maxV, _mm256_shuffle_ps(maxV, maxV, 0xee)); maxV = _mm256_max_ps(maxV, _mm256_shuffle_ps(maxV, maxV, 0x01)); float max = _mm_cvtss_f32(_mm256_castps256_ps128(maxV)); _mm256_zeroupper(); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return max; } sum_func AVXTBa2[FOLDTBLEN] = {foldBy2}; FoldSet AVXfold_a = {AVXTBa3, AVXTBa4, AVXTBa5, AVXTBa2, AVXTBa2, "JS AVX_a"}; // Alternate set using 16 byte unaligned loads and inserts for the probably unaligned // elements, based on Intel optimization recommendations. float foldBy3c(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("foldBy3c()"); #endif const float lim = (float)(((P->di) - 1) & 7); __m256 tailelem = _mm256_set_ps(7.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f, 0.0f); __m256 taillim = _mm256_broadcast_ss(&lim); __m256 maxV = _mm256_setzero_ps(); int i = 0; const float *p1 = ss[0], *p2 = ss[0]+P->tmp0, *p3 = ss[0]+P->tmp1; float *pst = P->dest; __m256 x1, x2, tailmask; while (i < P->di-8) { x2 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p2+i)), _mm_load_ps(p2+i+4), 1); x1 = _mm256_add_ps(x2, *(__m256*)(p1+i)); x2 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p3+i)), _mm_load_ps(p3+i+4), 1); x1 = _mm256_add_ps(x1, x2); _mm256_store_ps(pst+i, x1); maxV = _mm256_max_ps(maxV, x1); i += 8; } x2 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p2+i)), _mm_load_ps(p2+i+4), 1); x1 = _mm256_add_ps(x2, *(__m256*)(p1+i)); x2 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p3+i)), _mm_load_ps(p3+i+4), 1); x1 = _mm256_add_ps(x1, x2); tailmask = _mm256_cmp_ps(taillim, tailelem, 0x0d); _mm256_maskstore_ps(pst+i, AVX_MASKSTORE_TYPECAST(tailmask), x1); x2 = _mm256_and_ps(x1, tailmask); maxV = _mm256_max_ps(maxV, x2); x1 = _mm256_permute2f128_ps(maxV, maxV, 0x81); maxV = _mm256_max_ps(maxV, x1); maxV = _mm256_max_ps(maxV, _mm256_shuffle_ps(maxV, maxV, 0xee)); maxV = _mm256_max_ps(maxV, _mm256_shuffle_ps(maxV, maxV, 0x01)); float max = _mm_cvtss_f32(_mm256_castps256_ps128(maxV)); _mm256_zeroupper(); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return max; } sum_func AVXTBc3[FOLDTBLEN] = {foldBy3c}; float foldBy4c(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("foldBy4c"); #endif const float lim = (float)(((P->di) - 1) & 7); __m256 tailelem = _mm256_set_ps(7.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f, 0.0f); __m256 taillim = _mm256_broadcast_ss(&lim); __m256 maxV = _mm256_setzero_ps(); int i = 0; const float *p1 = ss[0], *p2 = ss[0]+P->tmp0, *p3 = ss[0]+P->tmp1, *p4 = ss[0]+P->tmp2; float *pst = P->dest; __m256 x1, x2, tailmask; while (i < P->di-8) { x1 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p2+i)), _mm_load_ps(p2+i+4), 1); x2 = _mm256_add_ps(x1, *(__m256*)(p1+i)); x1 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p3+i)), _mm_load_ps(p3+i+4), 1); x2 = _mm256_add_ps(x2, x1); x1 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p4+i)), _mm_load_ps(p4+i+4), 1); x2 = _mm256_add_ps(x2, x1); _mm256_store_ps(pst+i, x2); maxV = _mm256_max_ps(maxV, x2); i += 8; } x1 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p2+i)), _mm_load_ps(p2+i+4), 1); x2 = _mm256_add_ps(x1, *(__m256*)(p1+i)); x1 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p3+i)), _mm_load_ps(p3+i+4), 1); x2 = _mm256_add_ps(x2, x1); x1 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p4+i)), _mm_load_ps(p4+i+4), 1); x2 = _mm256_add_ps(x2, x1); tailmask = _mm256_cmp_ps(taillim, tailelem, 0x0d); _mm256_maskstore_ps(pst+i, AVX_MASKSTORE_TYPECAST(tailmask), x2); x1 = _mm256_and_ps(x2, tailmask); maxV = _mm256_max_ps(maxV, x1); x2 = _mm256_permute2f128_ps(maxV, maxV, 0x81); maxV = _mm256_max_ps(maxV, x2); maxV = _mm256_max_ps(maxV, _mm256_shuffle_ps(maxV, maxV, 0xee)); maxV = _mm256_max_ps(maxV, _mm256_shuffle_ps(maxV, maxV, 0x01)); float max = _mm_cvtss_f32(_mm256_castps256_ps128(maxV)); _mm256_zeroupper(); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return max; } sum_func AVXTBc4[FOLDTBLEN] = {foldBy4c}; float foldBy5c(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("foldBy5c()"); #endif const float lim = (float)(((P->di) - 1) & 7); __m256 tailelem = _mm256_set_ps(7.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f, 0.0f); __m256 taillim = _mm256_broadcast_ss(&lim); __m256 maxV = _mm256_setzero_ps(); int i = 0; const float *p1 = ss[0], *p2 = ss[0]+P->tmp0, *p3 = ss[0]+P->tmp1, *p4 = ss[0]+P->tmp2, *p5 = ss[0]+P->tmp3; float *pst = P->dest; __m256 x1, x2, tailmask; while (i < P->di-8) { x1 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p2+i)), _mm_load_ps(p2+i+4), 1); x1 = _mm256_add_ps(x1, *(__m256*)(p1+i)); x2 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p3+i)), _mm_load_ps(p3+i+4), 1); x1 = _mm256_add_ps(x1, x2); x2 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p4+i)), _mm_load_ps(p4+i+4), 1); x1 = _mm256_add_ps(x1, x2); x2 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p5+i)), _mm_load_ps(p5+i+4), 1); x1 = _mm256_add_ps(x1, x2); _mm256_store_ps(pst+i, x1); maxV = _mm256_max_ps(maxV, x1); i += 8; } x1 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p2+i)), _mm_load_ps(p2+i+4), 1); x1 = _mm256_add_ps(x1, *(__m256*)(p1+i)); x2 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p3+i)), _mm_load_ps(p3+i+4), 1); x1 = _mm256_add_ps(x1, x2); x2 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p4+i)), _mm_load_ps(p4+i+4), 1); x1 = _mm256_add_ps(x1, x2); x2 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p5+i)), _mm_load_ps(p5+i+4), 1); x1 = _mm256_add_ps(x1, x2); tailmask = _mm256_cmp_ps(taillim, tailelem, 0x0d); _mm256_maskstore_ps(pst+i, AVX_MASKSTORE_TYPECAST(tailmask), x1); x2 = _mm256_and_ps(x1, tailmask); maxV = _mm256_max_ps(maxV, x2); x1 = _mm256_permute2f128_ps(maxV, maxV, 0x81); maxV = _mm256_max_ps(maxV, x1); maxV = _mm256_max_ps(maxV, _mm256_shuffle_ps(maxV, maxV, 0xee)); maxV = _mm256_max_ps(maxV, _mm256_shuffle_ps(maxV, maxV, 0x01)); float max = _mm_cvtss_f32(_mm256_castps256_ps128(maxV)); _mm256_zeroupper(); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return max; } sum_func AVXTBc5[FOLDTBLEN] = {foldBy5c}; float foldBy2c(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("foldBy2c()"); #endif const float lim = (float)(((P->di) - 1) & 7); __m256 tailelem = _mm256_set_ps(7.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f, 0.0f); __m256 taillim = _mm256_broadcast_ss(&lim); __m256 maxV = _mm256_setzero_ps(); int i = 0; const float *p1 = ss[1]+P->offset, *p2 = ss[1]+P->tmp0; float *pst = P->dest; __m256 x1, x2, tailmask; while (i < P->di-8) { x1 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p2+i)), _mm_load_ps(p2+i+4), 1); x2 = _mm256_add_ps(x1, *(__m256*)(p1+i)); _mm256_store_ps(pst+i, x2); maxV = _mm256_max_ps(maxV, x2); i += 8; } x1 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p2+i)), _mm_load_ps(p2+i+4), 1); x2 = _mm256_add_ps(x1, *(__m256*)(p1+i)); tailmask = _mm256_cmp_ps(taillim, tailelem, 0x0d); _mm256_maskstore_ps(pst+i, AVX_MASKSTORE_TYPECAST(tailmask), x2); x1 = _mm256_and_ps(x2, tailmask); maxV = _mm256_max_ps(maxV, x1); x2 = _mm256_permute2f128_ps(maxV, maxV, 0x81); maxV = _mm256_max_ps(maxV, x2); maxV = _mm256_max_ps(maxV, _mm256_shuffle_ps(maxV, maxV, 0xee)); maxV = _mm256_max_ps(maxV, _mm256_shuffle_ps(maxV, maxV, 0x01)); float max = _mm_cvtss_f32(_mm256_castps256_ps128(maxV)); _mm256_zeroupper(); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return max; } sum_func AVXTBc2[FOLDTBLEN] = {foldBy2c}; FoldSet AVXfold_c = {AVXTBc3, AVXTBc4, AVXTBc5, AVXTBc2, AVXTBc2, "JS AVX_c"}; #endif // (USE_AVX) && (USE_INTRINSICS) boinc-app-seti_8.00~svn3701.orig/client/vector/analyzeFuncs_vfp.S0000644000175000017500000020775213050667044024755 0ustar locutuslocutus// Copyright (c) 1999-2011 Regents of the University of California // // FFTW: Copyright (c) 2003,2006 Matteo Frigo // Copyright (c) 2003,2006 Massachusets Institute of Technology // // fft8g.[cpp,h]: Copyright (c) 1995-2001 Takya Ooura // // ASMLIB: Copyright (c) 2004 Agner Fog // 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, 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; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions // as an alternative to FFTW and distribute a linked executable and // source code. You must obey the GNU General Public License in all // respects for all of the code used other than the FFT library itself. // Any modification required to support these libraries must be distributed // under the terms of this license. If you modify this program, you may extend // this exception to your version of the program, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. Please be aware that FFTW and ASMLIB are not covered by // this exception, therefore you may not use FFTW and ASMLIB in any derivative // work so modified without permission of the authors of those packages. #ifdef __arm__ /* * vfp_ChirpData.S * Author: Mateusz Szpakowski */ #if defined(__VFP_FP__) && !defined(__SOFTFP__) .syntax unified #endif .arch armv6 .fpu vfp #if defined(__VFP_FP__) && !defined(__SOFTFP__) .eabi_attribute 27, 3 .eabi_attribute 28, 1 #endif /* .eabi_attribute 20, 1 .eabi_attribute 21, 1 .eabi_attribute 23, 3 */ .eabi_attribute 23, 1 .eabi_attribute 24, 1 .eabi_attribute 25, 1 .eabi_attribute 26, 2 .eabi_attribute 30, 2 .eabi_attribute 18, 4 .text .align 2 .Lhalfd: .double 0.5 .LroundVal: .double 4503599627370496.0 .Linc8d: .double 0,1,2,3,4,5,6,7 .Lsincosapprox: .float 1.5707963268,-0.6466386396,0.0679105987,-0.0011573807 // sine .float 1.0,-1.2341299769,0.2465220241,-0.0123926179 // cosine .align 2 .global _Z13vfp_ChirpDataPA2_fS0_idid .type _Z13vfp_ChirpDataPA2_fS0_idid, %function _Z13vfp_ChirpDataPA2_fS0_idid: push {r4,r5,r6,r7,r8,r9,lr} vpush {d8,d9,d10,d11,d12,d13,d14,d15} #ifdef ANDROID #define stargidx (24+64) /* r0 - input data * r1 - output data * r2 - chirprateind * sp[0-1] - chirp_rate * sp[2] - numDataPoints * sp[4-5] - sample_rate */ #else //R: armhf pass params in registers instead /* r0 - input data * r1 - output data * r2 - chirprateind * d0 - chirp_rate * r3 - numDataPoints (stored in r9 for function lifetime) * d1 - sample_rate */ mov r9,r3 vmov.f64 d9,d0 vmov.f64 d10,d1 #endif tst r2,r2 bne .Lrealfunc mov r3,r0 // swap addresses mov r0,r1 mov r1,r3 #ifdef ANDROID ldr r2,[sp,#stargidx+8] // numDataPoints #else mov r2,r9 #endif lsl r2,r2,#3 bl memcpy(PLT) b .Lendoffunc /* * real functions */ .Lrealfunc: ldr r4,.LGOT1 .LPIC1: add r4,pc,r4 ldr r5,.LGOT1+4 ldr r5,[r4,r5] #ifdef ANDROID ldr r3,[sp,#stargidx+8] // numDataPoints #else mov r3,r9 #endif add r6,r3,r3,lsl #1 lsl r6,r6,#2 fldd d0,[r5,#32] fmsr s4,r6 fuitod d1,s4 faddd d0,d0,d1 fstd d0,[r5,#32] add r3,r0,r3,lsl #3 sub r3,r3,#8*7 fldd d11,.Lhalfd #ifdef ANDROID fldd d9,[sp,#stargidx] // chirp_rate fldd d10,[sp,#stargidx+16] // sample_rate #endif //R: for armhf d9 and d10 already loaded fmuld d10,d10,d10 fmuld d9,d9,d11 fdivd d9,d9,d10 fldd d10,.LroundVal fsubd d11,d11,d11 // zero fcmpd d9,d11 fmstat fnegdmi d10,d10 // negate is negative srate sub sp,sp,#24+32+8 add r7,sp,#24 fstmiad sp,{d9,d10} mov r4,#0 // i adr r5,.Linc8d adr r6,.Lsincosapprox adr r8,.Lsincosapprox+4*4 cmp r0,r3 bhs .Lendmainloop .Lmainloop: fmsr s24,r4 fuitod d8,s24 fldmiad r5,{d0,d1,d2,d3,d4,d5,d6,d7} fldmiad sp,{d9,d10} faddd d0,d0,d8 faddd d1,d1,d8 faddd d2,d2,d8 faddd d3,d3,d8 faddd d4,d4,d8 faddd d5,d5,d8 faddd d6,d6,d8 faddd d7,d7,d8 // square of i fmuld d0,d0,d0 fmuld d1,d1,d1 fmuld d2,d2,d2 fmuld d3,d3,d3 fmuld d4,d4,d4 fmuld d5,d5,d5 fmuld d6,d6,d6 fmuld d7,d7,d7 // multiply by srate fmuld d0,d0,d9 fmuld d1,d1,d9 fmuld d2,d2,d9 fmuld d3,d3,d9 fmuld d4,d4,d9 fmuld d5,d5,d9 fmuld d6,d6,d9 fmuld d7,d7,d9 // rounding to -0.5/+0.5 faddd d12,d0,d10 faddd d13,d1,d10 faddd d14,d2,d10 faddd d15,d3,d10 fsubd d12,d12,d10 fsubd d13,d13,d10 fsubd d14,d14,d10 fsubd d15,d15,d10 fsubd d0,d0,d12 fsubd d1,d1,d13 fsubd d2,d2,d14 fsubd d3,d3,d15 // second half of xxxx faddd d12,d4,d10 faddd d13,d5,d10 faddd d14,d6,d10 faddd d15,d7,d10 fsubd d12,d12,d10 fsubd d13,d13,d10 fsubd d14,d14,d10 fsubd d15,d15,d10 fsubd d4,d4,d12 fsubd d5,d5,d13 fsubd d6,d6,d14 fsubd d7,d7,d15 // to single precision fcvtsd s24,d0 fcvtsd s25,d1 fcvtsd s26,d2 fcvtsd s27,d3 fcvtsd s28,d4 fcvtsd s29,d5 fcvtsd s30,d6 fcvtsd s31,d7 fldmias r6,{s16,s17,s18,s19} // square of y fmuls s0,s24,s24 fmuls s1,s25,s25 fmuls s2,s26,s26 fmuls s3,s27,s27 fmuls s4,s28,s28 fmuls s5,s29,s29 fmuls s6,s30,s30 fmuls s7,s31,s31 // sine fmuls s8,s0,s19 fmuls s9,s1,s19 fmuls s10,s2,s19 fmuls s11,s3,s19 fmuls s12,s4,s19 fmuls s13,s5,s19 fmuls s14,s6,s19 fmuls s15,s7,s19 fadds s8,s8,s18 fadds s9,s9,s18 fadds s10,s10,s18 fadds s11,s11,s18 fadds s12,s12,s18 fadds s13,s13,s18 fadds s14,s14,s18 fadds s15,s15,s18 fmuls s8,s8,s0 fmuls s9,s9,s1 fmuls s10,s10,s2 fmuls s11,s11,s3 fmuls s12,s12,s4 fmuls s13,s13,s5 fmuls s14,s14,s6 fmuls s15,s15,s7 fadds s8,s8,s17 fadds s9,s9,s17 fadds s10,s10,s17 fadds s11,s11,s17 fadds s12,s12,s17 fadds s13,s13,s17 fadds s14,s14,s17 fadds s15,s15,s17 fmuls s8,s8,s0 fmuls s9,s9,s1 fmuls s10,s10,s2 fmuls s11,s11,s3 fmuls s12,s12,s4 fmuls s13,s13,s5 fmuls s14,s14,s6 fmuls s15,s15,s7 fadds s8,s8,s16 fadds s9,s9,s16 fadds s10,s10,s16 fadds s11,s11,s16 fadds s12,s12,s16 fadds s13,s13,s16 fadds s14,s14,s16 fadds s15,s15,s16 fmuls s8,s8,s24 fmuls s9,s9,s25 fmuls s10,s10,s26 fmuls s11,s11,s27 fmuls s12,s12,s28 fmuls s13,s13,s29 fmuls s14,s14,s30 fmuls s15,s15,s31 fldmias r8,{s24,s25,s26,s27} // cosine fmuls s16,s0,s27 fmuls s17,s1,s27 fmuls s18,s2,s27 fmuls s19,s3,s27 fmuls s20,s4,s27 fmuls s21,s5,s27 fmuls s22,s6,s27 fmuls s23,s7,s27 fadds s16,s16,s26 fadds s17,s17,s26 fadds s18,s18,s26 fadds s19,s19,s26 fadds s20,s20,s26 fadds s21,s21,s26 fadds s22,s22,s26 fadds s23,s23,s26 fmuls s16,s16,s0 fmuls s17,s17,s1 fmuls s18,s18,s2 fmuls s19,s19,s3 fmuls s20,s20,s4 fmuls s21,s21,s5 fmuls s22,s22,s6 fmuls s23,s23,s7 fadds s16,s16,s25 fadds s17,s17,s25 fadds s18,s18,s25 fadds s19,s19,s25 fadds s20,s20,s25 fadds s21,s21,s25 fadds s22,s22,s25 fadds s23,s23,s25 fmuls s16,s16,s0 fmuls s17,s17,s1 fmuls s18,s18,s2 fmuls s19,s19,s3 fmuls s20,s20,s4 fmuls s21,s21,s5 fmuls s22,s22,s6 fmuls s23,s23,s7 fadds s16,s16,s24 fadds s17,s17,s24 fadds s18,s18,s24 fadds s19,s19,s24 fadds s20,s20,s24 fadds s21,s21,s24 fadds s22,s22,s24 fadds s23,s23,s24 // load sine // doubling cosine/sine fmuls s0,s8,s16 // c*s fmuls s1,s9,s17 fmuls s2,s10,s18 fmuls s3,s11,s19 fmuls s4,s12,s20 fmuls s5,s13,s21 fmuls s6,s14,s22 fmuls s7,s15,s23 fmuls s16,s16,s16 // c*c fmuls s17,s17,s17 fmuls s18,s18,s18 fmuls s19,s19,s19 fmuls s20,s20,s20 fmuls s21,s21,s21 fmuls s22,s22,s22 fmuls s23,s23,s23 fnmacs s16,s8,s8 // c*c-s*s = x fnmacs s17,s9,s9 fnmacs s18,s10,s10 fnmacs s19,s11,s11 fnmacs s20,s12,s12 fnmacs s21,s13,s13 fnmacs s22,s14,s14 fnmacs s23,s15,s15 fadds s0,s0,s0 // 2*s*c = y fadds s1,s1,s1 fadds s2,s2,s2 fadds s3,s3,s3 fadds s4,s4,s4 fadds s5,s5,s5 fadds s6,s6,s6 fadds s7,s7,s7 fmuls s8,s0,s16 // cd1 = x*y fmuls s9,s1,s17 fmuls s10,s2,s18 fmuls s11,s3,s19 fmuls s12,s4,s20 fmuls s13,s5,s21 fmuls s14,s6,s22 fmuls s15,s7,s23 fmuls s0,s0,s0 // cd3 = y*y fmuls s1,s1,s1 fmuls s2,s2,s2 fmuls s3,s3,s3 fmuls s4,s4,s4 fmuls s5,s5,s5 fmuls s6,s6,s6 fmuls s7,s7,s7 fmuls s24,s16,s16 // cd2 = x*x fmuls s25,s17,s17 fmuls s26,s18,s18 fmuls s27,s19,s19 fmuls s28,s20,s20 fmuls s29,s21,s21 fmuls s30,s22,s22 fmuls s31,s23,s23 fadds s24,s24,s0 // norm = x*x+y*y fadds s25,s25,s1 fadds s26,s26,s2 fadds s27,s27,s3 fadds s28,s28,s4 fadds s29,s29,s5 fadds s30,s30,s6 fadds s31,s31,s7 fmscs s0,s16,s16 // c = x*x-y*y fmscs s1,s17,s17 fmscs s2,s18,s18 fmscs s3,s19,s19 fmscs s4,s20,s20 fmscs s5,s21,s21 fmscs s6,s22,s22 fmscs s7,s23,s23 fadds s16,s8,s8 // s = 2*x*y fadds s17,s9,s9 fadds s18,s10,s10 fadds s19,s11,s11 fadds s20,s12,s12 fadds s21,s13,s13 fadds s22,s14,s14 fadds s23,s15,s15 fsts s7,[sp,#24+64] flds s7,.Ltwos fstmias r7,{s16,s17,s18,s19,s20,s21,s22,s23} // reciprocal of magnitude // iter 1: invmag = 2.0-mag fsubs s8,s7,s24 fsubs s9,s7,s25 fsubs s10,s7,s26 fsubs s11,s7,s27 fsubs s12,s7,s28 fsubs s13,s7,s29 fsubs s14,s7,s30 fsubs s15,s7,s31 // iter 2: invmag = invmag*(2.0-mag*invmag) fmuls s16,s8,s24 fmuls s17,s9,s25 fmuls s18,s10,s26 fmuls s19,s11,s27 fmuls s20,s12,s28 fmuls s21,s13,s29 fmuls s22,s14,s30 fmuls s23,s15,s31 fsubs s16,s7,s16 fsubs s17,s7,s17 fsubs s18,s7,s18 fsubs s19,s7,s19 fsubs s20,s7,s20 fsubs s21,s7,s21 fsubs s22,s7,s22 fsubs s23,s7,s23 fmuls s8,s16,s8 fmuls s9,s17,s9 fmuls s10,s18,s10 fmuls s11,s19,s11 fmuls s12,s20,s12 fmuls s13,s21,s13 fmuls s14,s22,s14 fmuls s15,s23,s15 // iter 3: invmag = invmag*(2.0-mag*invmag) fmuls s16,s8,s24 fmuls s17,s9,s25 fmuls s18,s10,s26 fmuls s19,s11,s27 fmuls s20,s12,s28 fmuls s21,s13,s29 fmuls s22,s14,s30 fmuls s23,s15,s31 fsubs s16,s7,s16 fsubs s17,s7,s17 fsubs s18,s7,s18 fsubs s19,s7,s19 fsubs s20,s7,s20 fsubs s21,s7,s21 fsubs s22,s7,s22 fsubs s23,s7,s23 fmuls s8,s16,s8 fmuls s9,s17,s9 fmuls s10,s18,s10 fmuls s11,s19,s11 fmuls s12,s20,s12 fmuls s13,s21,s13 fmuls s14,s22,s14 fmuls s15,s23,s15 // restore sine values fldmias r7,{s16,s17,s18,s19,s20,s21,s22,s23} // correct cosine/sine flds s7,[sp,#24+64] fmuls s0,s0,s8 fmuls s1,s1,s9 fmuls s2,s2,s10 fmuls s3,s3,s11 fmuls s4,s4,s12 fmuls s5,s5,s13 fmuls s6,s6,s14 fmuls s7,s7,s15 fmuls s16,s16,s8 fmuls s17,s17,s9 fmuls s18,s18,s10 fmuls s19,s19,s11 fmuls s20,s20,s12 fmuls s21,s21,s13 fmuls s22,s22,s14 fmuls s23,s23,s15 pld [r0,#128] // multiply by data fldmias r0!,{s8,s9,s10,s11,s12,s13,s14,s15} fmuls s24,s8,s0 fmuls s25,s9,s0 fmuls s26,s10,s1 fmuls s27,s11,s1 fmuls s28,s12,s2 fmuls s29,s13,s2 fmuls s30,s14,s3 fmuls s31,s15,s3 fnmacs s24,s9,s16 fmacs s25,s8,s16 fnmacs s26,s11,s17 fmacs s27,s10,s17 fnmacs s28,s13,s18 fmacs s29,s12,s18 fnmacs s30,s15,s19 fmacs s31,s14,s19 fstmias r1!,{s24,s25,s26,s27,s28,s29,s30,s31} pld [r0,#128] fldmias r0!,{s8,s9,s10,s11,s12,s13,s14,s15} fmuls s24,s8,s4 fmuls s25,s9,s4 fmuls s26,s10,s5 fmuls s27,s11,s5 fmuls s28,s12,s6 fmuls s29,s13,s6 fmuls s30,s14,s7 fmuls s31,s15,s7 fnmacs s24,s9,s20 fmacs s25,s8,s20 fnmacs s26,s11,s21 fmacs s27,s10,s21 fnmacs s28,s13,s22 fmacs s29,s12,s22 fnmacs s30,s15,s23 fmacs s31,s14,s23 fstmias r1!,{s24,s25,s26,s27,s28,s29,s30,s31} add r4,r4,#8 cmp r0,r3 blo .Lmainloop .Lendmainloop: add r3,r3,#8*7 cmp r0,r3 bhs .Lendsmallloop .Lsmallloop: fmsr s24,r4 fldmiad sp,{d9,d10} fuitod d0,s24 // square of i fmuld d0,d0,d0 // multiply by srate fmuld d0,d0,d9 // rounding to -0.5/+0.5 faddd d12,d0,d10 fsubd d12,d12,d10 fsubd d0,d0,d12 fcvtsd s24,d0 fldmias r6,{s8,s9,s10,s11,s12,s13,s14,s15} // square of y fmuls s0,s24,s24 // sine/cosine fmuls s16,s0,s11 fmuls s17,s0,s15 fadds s16,s16,s10 fadds s17,s17,s14 fmuls s16,s16,s0 fmuls s17,s17,s0 fadds s16,s16,s9 fadds s17,s17,s13 fmuls s16,s16,s0 fmuls s17,s17,s0 fadds s16,s16,s8 fadds s17,s17,s12 // s16 - sine fmuls s16,s16,s24 // s17 - cosine // doubling cosine/sine fmuls s18,s16,s17 fmuls s19,s16,s16 fmuls s20,s17,s17 fadds s18,s18,s18 // y=2*s*c fsubs s19,s20,s19 // x=c*c-s*s fmuls s21,s18,s19 // cd1 fmuls s22,s19,s19 // cd2 fmuls s23,s18,s18 // cd3 fsubs s8,s22,s23 // c fadds s9,s21,s21 // s // compute 1.0/norm fadds s10,s22,s23 // mag // reciprocal flds s11,.Ltwos // iter1: invmag = 2.0-mag fsubs s12,s11,s10 // iter2: invmag = invmag*(2.0-invmag*mag) fmuls s13,s12,s10 fsubs s13,s11,s13 fmuls s12,s12,s13 // correct cosine/sine fmuls s8,s8,s12 fmuls s9,s9,s12 // multiply data fldmias r0!,{s14,s15} fmuls s6,s14,s8 fmuls s7,s14,s9 fnmacs s6,s15,s9 fmacs s7,s15,s8 fstmias r1!,{s6,s7} add r4,r4,#1 cmp r0,r3 blo .Lsmallloop .Lendsmallloop: add sp,sp,#24+32+8 .Lendoffunc: mov r0,#0 vpop {d8,d9,d10,d11,d12,d13,d14,d15} pop {r4,r5,r6,r7,r8,r9,lr} bx lr .align 2 .LGOT1: .word _GLOBAL_OFFSET_TABLE_-(.LPIC1+8) .word analysis_state(GOT) .Ltwos: .float 2.0 /* * vfp_FoldSubs.S * Author: Mateusz Szpakowski */ .align 2 /***** * fold array by 3 ******/ .Lzeros: .float 0.0,0.0 .global vfp_foldArrayBy3_ll31 .type vfp_foldArrayBy3_ll31, %function vfp_foldArrayBy3_ll31: push {r4,r5,r6,lr} vpush {d8,d9,d10,d11,d12} ldr r0,[r0] // ss0 ldrd r2,[r1,#8] // tmp0 add r2,r0,r2,lsl #2 add r3,r0,r3,lsl #2 ldrd r4,[r1] // di,dest add r6,r0,r4,lsl #2 // end fldd d12,.Lzeros sub r6,r6,#4*7 cmp r0,r6 bhs .Lendf3loop2 .Lf3loop2: .macro FOLDBY3_CORE fldmias r0!,{s0,s1,s2,s3,s4,s5,s6,s7} fldmias r2!,{s8,s9,s10,s11,s12,s13,s14,s15} fldmias r3!,{s16,s17,s18,s19,s20,s21,s22,s23} fadds s0,s0,s8 fadds s1,s1,s9 fadds s2,s2,s10 fadds s3,s3,s11 fadds s4,s4,s12 fadds s5,s5,s13 fadds s6,s6,s14 fadds s7,s7,s15 fadds s0,s0,s16 fadds s1,s1,s17 fadds s2,s2,s18 fadds s3,s3,s19 fadds s4,s4,s20 fadds s5,s5,s21 fadds s6,s6,s22 fadds s7,s7,s23 fstmias r5!,{s0,s1,s2,s3,s4,s5,s6,s7} fcmpes s24,s0 fmstat fcmpes s25,s1 fcpysmi s24,s0 fmstat fcmpes s24,s2 fcpysmi s25,s1 fmstat fcmpes s25,s3 fcpysmi s24,s2 fmstat fcmpes s24,s4 fcpysmi s25,s3 fmstat fcmpes s25,s5 fcpysmi s24,s4 fmstat fcmpes s24,s6 fcpysmi s25,s5 fmstat fcmpes s25,s7 fcpysmi s24,s6 fmstat fcpysmi s25,s7 .endm FOLDBY3_CORE cmp r0,r6 blo .Lf3loop2 .Lendf3loop2: and r4,r4,#7 cmp r4,#4 blo .Lf3lt4 beq .Lf3eq4 cmp r4,#6 blo .Lf3lt6 beq .Lf3eq6 fldmias r0!,{s0,s1,s2,s3,s4,s5,s6} fldmias r2!,{s8,s9,s10,s11,s12,s13,s14} fldmias r3!,{s16,s17,s18,s19,s20,s21,s22} fadds s0,s0,s8 fadds s1,s1,s9 fadds s2,s2,s10 fadds s3,s3,s11 fadds s4,s4,s12 fadds s5,s5,s13 fadds s6,s6,s14 fadds s0,s0,s16 fadds s1,s1,s17 fadds s2,s2,s18 fadds s3,s3,s19 fadds s4,s4,s20 fadds s5,s5,s21 fadds s6,s6,s22 fstmias r5!,{s0,s1,s2,s3,s4,s5,s6} fcmpes s24,s0 fmstat fcmpes s25,s1 fcpysmi s24,s0 fmstat fcmpes s24,s2 fcpysmi s25,s1 fmstat fcmpes s25,s3 fcpysmi s24,s2 fmstat fcmpes s24,s4 fcpysmi s25,s3 fmstat fcmpes s25,s5 fcpysmi s24,s4 fmstat fcmpes s24,s6 fcpysmi s25,s5 fmstat fcpysmi s24,s6 b .Lf3end .Lf3eq6: fldmias r0!,{s0,s1,s2,s3,s4,s5} fldmias r2!,{s8,s9,s10,s11,s12,s13} fldmias r3!,{s16,s17,s18,s19,s20,s21} fadds s0,s0,s8 fadds s1,s1,s9 fadds s2,s2,s10 fadds s3,s3,s11 fadds s4,s4,s12 fadds s5,s5,s13 fadds s0,s0,s16 fadds s1,s1,s17 fadds s2,s2,s18 fadds s3,s3,s19 fadds s4,s4,s20 fadds s5,s5,s21 fstmias r5!,{s0,s1,s2,s3,s4,s5} fcmpes s24,s0 fmstat fcmpes s25,s1 fcpysmi s24,s0 fmstat fcmpes s24,s2 fcpysmi s25,s1 fmstat fcmpes s25,s3 fcpysmi s24,s2 fmstat fcmpes s24,s4 fcpysmi s25,s3 fmstat fcmpes s25,s5 fcpysmi s24,s4 fmstat fcpysmi s25,s5 b .Lf3end .Lf3lt6: fldmias r0!,{s0,s1,s2,s3,s4} fldmias r2!,{s8,s9,s10,s11,s12} fldmias r3!,{s16,s17,s18,s19,s20} fadds s0,s0,s8 fadds s1,s1,s9 fadds s2,s2,s10 fadds s3,s3,s11 fadds s4,s4,s12 fadds s0,s0,s16 fadds s1,s1,s17 fadds s2,s2,s18 fadds s3,s3,s19 fadds s4,s4,s20 fstmias r5!,{s0,s1,s2,s3,s4} fcmpes s24,s0 fmstat fcmpes s25,s1 fcpysmi s24,s0 fmstat fcmpes s24,s2 fcpysmi s25,s1 fmstat fcmpes s25,s3 fcpysmi s24,s2 fmstat fcmpes s24,s4 fcpysmi s25,s3 fmstat fcpysmi s24,s4 b .Lf3end .Lf3eq4: fldmias r0!,{s0,s1,s2,s3} fldmias r2!,{s8,s9,s10,s11} fldmias r3!,{s16,s17,s18,s19} fadds s0,s0,s8 fadds s1,s1,s9 fadds s2,s2,s10 fadds s3,s3,s11 fadds s0,s0,s16 fadds s1,s1,s17 fadds s2,s2,s18 fadds s3,s3,s19 fstmias r5!,{s0,s1,s2,s3} fcmpes s24,s0 fmstat fcmpes s25,s1 fcpysmi s24,s0 fmstat fcmpes s24,s2 fcpysmi s25,s1 fmstat fcmpes s25,s3 fcpysmi s24,s2 fmstat fcpysmi s25,s3 b .Lf3end .Lf3lt4: cmp r4,#2 blo .Lf3lt2 beq .Lf3eq2 fldmias r0!,{s0,s1,s2} fldmias r2!,{s8,s9,s10} fldmias r3!,{s16,s17,s18} fadds s0,s0,s8 fadds s1,s1,s9 fadds s2,s2,s10 fadds s0,s0,s16 fadds s1,s1,s17 fadds s2,s2,s18 fstmias r5!,{s0,s1,s2} fcmpes s24,s0 fmstat fcmpes s25,s1 fcpysmi s24,s0 fmstat fcmpes s24,s2 fcpysmi s25,s1 fmstat fcpysmi s24,s2 b .Lf3end .Lf3eq2: fldmias r0!,{s0,s1} fldmias r2!,{s8,s9} fldmias r3!,{s16,s17} fadds s0,s0,s8 fadds s1,s1,s9 fadds s0,s0,s16 fadds s1,s1,s17 fstmias r5!,{s0,s1} fcmpes s24,s0 fmstat fcmpes s25,s1 fcpysmi s24,s0 fmstat fcpysmi s25,s1 b .Lf3end .Lf3lt2: cmp r4,#0 beq .Lf3eq0 fldmias r0!,{s0} fldmias r2!,{s1} fldmias r3!,{s2} fadds s0,s0,s1 fadds s0,s0,s2 fstmias r5!,{s0} fcmpes s24,s0 fmstat fcpysmi s24,s0 .Lf3eq0: .Lf3end: fcmpes s24,s25 fmstat fcpysmi s24,s25 fmrs r0,s24 vpop {d8,d9,d10,d11,d12} pop {r4,r5,r6,lr} bx lr .Lzeros1: .float 0.0,0.0 .global vfp_foldArrayBy3_lge31 .type vfp_foldArrayBy3_lge31, %function vfp_foldArrayBy3_lge31: push {r4,r5,r6,lr} vpush {d8,d9,d10,d11,d12} ldr r0,[r0] // ss0 ldrd r2,[r1,#8] // tmp0 add r2,r0,r2,lsl #2 add r3,r0,r3,lsl #2 ldrd r4,[r1] // di,dest add r6,r0,r4,lsl #2 // end fldd d12,.Lzeros1 sub r6,r6,#4*31 cmp r0,r6 bhs .Lendf3loop4 .Lf3loop4: FOLDBY3_CORE FOLDBY3_CORE FOLDBY3_CORE FOLDBY3_CORE cmp r0,r6 blo .Lf3loop4 .Lendf3loop4: add r6,r6,#4*24 cmp r0,r6 bhs .Lendf3loop2 .Lf3loop5: FOLDBY3_CORE cmp r0,r6 blo .Lf3loop5 .Lendf3loop5: b .Lendf3loop2 .Lfoldby3sel: .rept 31 .word vfp_foldArrayBy3_ll31 .endr .word vfp_foldArrayBy3_lge31 .Lzeros2: .float 0.0,0.0 /***** * fold array by 4 ******/ .global vfp_foldArrayBy4_ll31 .type vfp_foldArrayBy4_ll31, %function vfp_foldArrayBy4_ll31: push {r4,r5,r6,r7,r8,lr} vpush {d8,d9,d10,d11,d12} ldr r0,[r0] // ss0 ldrd r2,[r1,#8] // tmp0 ldr r6,[r1,#16] // tmp2 add r2,r0,r2,lsl #2 add r3,r0,r3,lsl #2 add r6,r0,r6,lsl #2 ldrd r4,[r1] // di,dest add r7,r0,r4,lsl #2 // end fldd d12,.Lzeros2 sub r7,r7,#4*7 cmp r0,r7 bhs .Lendf4loop2 .Lf4loop2: .macro FOLDBY4_CORE fldmias r0!,{s0,s1,s2,s3,s4,s5,s6,s7} fldmias r2!,{s8,s9,s10,s11,s12,s13,s14,s15} fldmias r3!,{s16,s17,s18,s19,s20,s21,s22,s23} fadds s0,s0,s8 fadds s1,s1,s9 fadds s2,s2,s10 fadds s3,s3,s11 fadds s4,s4,s12 fadds s5,s5,s13 fadds s6,s6,s14 fadds s7,s7,s15 fadds s0,s0,s16 fadds s1,s1,s17 fadds s2,s2,s18 fadds s3,s3,s19 fldmias r6!,{s8,s9,s10,s11,s12,s13,s14,s15} fadds s4,s4,s20 fadds s5,s5,s21 fadds s6,s6,s22 fadds s7,s7,s23 fadds s0,s0,s8 fadds s1,s1,s9 fadds s2,s2,s10 fadds s3,s3,s11 fadds s4,s4,s12 fadds s5,s5,s13 fadds s6,s6,s14 fadds s7,s7,s15 fstmias r5!,{s0,s1,s2,s3,s4,s5,s6,s7} fcmpes s24,s0 fmstat fcmpes s25,s1 fcpysmi s24,s0 fmstat fcmpes s24,s2 fcpysmi s25,s1 fmstat fcmpes s25,s3 fcpysmi s24,s2 fmstat fcmpes s24,s4 fcpysmi s25,s3 fmstat fcmpes s25,s5 fcpysmi s24,s4 fmstat fcmpes s24,s6 fcpysmi s25,s5 fmstat fcmpes s25,s7 fcpysmi s24,s6 fmstat fcpysmi s25,s7 .endm FOLDBY4_CORE cmp r0,r7 blo .Lf4loop2 .Lendf4loop2: and r4,r4,#7 cmp r4,#4 blo .Lf4lt4 beq .Lf4eq4 cmp r4,#6 blo .Lf4lt6 beq .Lf4eq6 fldmias r0!,{s0,s1,s2,s3,s4,s5,s6} fldmias r2!,{s8,s9,s10,s11,s12,s13,s14} fldmias r3!,{s16,s17,s18,s19,s20,s21,s22} fadds s0,s0,s8 fadds s1,s1,s9 fadds s2,s2,s10 fadds s3,s3,s11 fadds s4,s4,s12 fadds s5,s5,s13 fadds s6,s6,s14 fadds s0,s0,s16 fadds s1,s1,s17 fadds s2,s2,s18 fadds s3,s3,s19 fadds s4,s4,s20 fadds s5,s5,s21 fadds s6,s6,s22 fldmias r6!,{s16,s17,s18,s19,s20,s21,s22} fadds s0,s0,s16 fadds s1,s1,s17 fadds s2,s2,s18 fadds s3,s3,s19 fadds s4,s4,s20 fadds s5,s5,s21 fadds s6,s6,s22 fstmias r5!,{s0,s1,s2,s3,s4,s5,s6} fcmpes s24,s0 fmstat fcmpes s25,s1 fcpysmi s24,s0 fmstat fcmpes s24,s2 fcpysmi s25,s1 fmstat fcmpes s25,s3 fcpysmi s24,s2 fmstat fcmpes s24,s4 fcpysmi s25,s3 fmstat fcmpes s25,s5 fcpysmi s24,s4 fmstat fcmpes s24,s6 fcpysmi s25,s5 fmstat fcpysmi s24,s6 b .Lf4end .Lf4eq6: fldmias r0!,{s0,s1,s2,s3,s4,s5} fldmias r2!,{s6,s7,s8,s9,s10,s11} fldmias r3!,{s12,s13,s14,s15,s16,s17} fldmias r6!,{s18,s19,s20,s21,s22,s23} fadds s0,s0,s6 fadds s1,s1,s7 fadds s2,s2,s8 fadds s3,s3,s9 fadds s4,s4,s10 fadds s5,s5,s11 fadds s0,s0,s12 fadds s1,s1,s13 fadds s2,s2,s14 fadds s3,s3,s15 fadds s4,s4,s16 fadds s5,s5,s17 fadds s0,s0,s18 fadds s1,s1,s19 fadds s2,s2,s20 fadds s3,s3,s21 fadds s4,s4,s22 fadds s5,s5,s23 fstmias r5!,{s0,s1,s2,s3,s4,s5} fcmpes s24,s0 fmstat fcmpes s25,s1 fcpysmi s24,s0 fmstat fcmpes s24,s2 fcpysmi s25,s1 fmstat fcmpes s25,s3 fcpysmi s24,s2 fmstat fcmpes s24,s4 fcpysmi s25,s3 fmstat fcmpes s25,s5 fcpysmi s24,s4 fmstat fcpysmi s25,s5 b .Lf4end .Lf4lt6: fldmias r0!,{s0,s1,s2,s3,s4} fldmias r2!,{s6,s7,s8,s9,s10} fldmias r3!,{s12,s13,s14,s15,s16} fldmias r6!,{s18,s19,s20,s21,s22} fadds s0,s0,s6 fadds s1,s1,s7 fadds s2,s2,s8 fadds s3,s3,s9 fadds s4,s4,s10 fadds s0,s0,s12 fadds s1,s1,s13 fadds s2,s2,s14 fadds s3,s3,s15 fadds s4,s4,s16 fadds s0,s0,s18 fadds s1,s1,s19 fadds s2,s2,s20 fadds s3,s3,s21 fadds s4,s4,s22 fstmias r5!,{s0,s1,s2,s3,s4} fcmpes s24,s0 fmstat fcmpes s25,s1 fcpysmi s24,s0 fmstat fcmpes s24,s2 fcpysmi s25,s1 fmstat fcmpes s25,s3 fcpysmi s24,s2 fmstat fcmpes s24,s4 fcpysmi s25,s3 fmstat fcpysmi s24,s4 b .Lf4end .Lf4eq4: fldmias r0!,{s0,s1,s2,s3} fldmias r2!,{s6,s7,s8,s9} fldmias r3!,{s12,s13,s14,s15} fldmias r6!,{s18,s19,s20,s21} fadds s0,s0,s6 fadds s1,s1,s7 fadds s2,s2,s8 fadds s3,s3,s9 fadds s0,s0,s12 fadds s1,s1,s13 fadds s2,s2,s14 fadds s3,s3,s15 fadds s0,s0,s18 fadds s1,s1,s19 fadds s2,s2,s20 fadds s3,s3,s21 fstmias r5!,{s0,s1,s2,s3} fcmpes s24,s0 fmstat fcmpes s25,s1 fcpysmi s24,s0 fmstat fcmpes s24,s2 fcpysmi s25,s1 fmstat fcmpes s25,s3 fcpysmi s24,s2 fmstat fcpysmi s25,s3 b .Lf4end .Lf4lt4: cmp r4,#2 blo .Lf4lt2 beq .Lf4eq2 fldmias r0!,{s0,s1,s2} fldmias r2!,{s6,s7,s8} fldmias r3!,{s12,s13,s14} fldmias r6!,{s18,s19,s20} fadds s0,s0,s6 fadds s1,s1,s7 fadds s2,s2,s8 fadds s0,s0,s12 fadds s1,s1,s13 fadds s2,s2,s14 fadds s0,s0,s18 fadds s1,s1,s19 fadds s2,s2,s20 fstmias r5!,{s0,s1,s2} fcmpes s24,s0 fmstat fcmpes s25,s1 fcpysmi s24,s0 fmstat fcmpes s24,s2 fcpysmi s25,s1 fmstat fcpysmi s24,s2 b .Lf4end .Lf4eq2: fldmias r0!,{s0,s1} fldmias r2!,{s6,s7} fldmias r3!,{s12,s13} fldmias r6!,{s18,s19} fadds s0,s0,s6 fadds s1,s1,s7 fadds s0,s0,s12 fadds s1,s1,s13 fadds s0,s0,s18 fadds s1,s1,s19 fstmias r5!,{s0,s1} fcmpes s24,s0 fmstat fcmpes s25,s1 fcpysmi s24,s0 fmstat fcpysmi s25,s1 b .Lf4end .Lf4lt2: cmp r4,#0 beq .Lf4eq0 fldmias r0!,{s0} fldmias r2!,{s1} fldmias r3!,{s2} fldmias r6!,{s3} fadds s0,s0,s1 fadds s0,s0,s2 fadds s0,s0,s3 fstmias r5!,{s0} fcmpes s24,s0 fmstat fcpysmi s24,s0 .Lf4eq0: .Lf4end: fcmpes s24,s25 fmstat fcpysmi s24,s25 fmrs r0,s24 vpop {d8,d9,d10,d11,d12} pop {r4,r5,r6,r7,r8,lr} bx lr .Lzeros2_1: .float 0.0,0.0 .global vfp_foldArrayBy4_lge31 .type vfp_foldArrayBy4_lge31, %function vfp_foldArrayBy4_lge31: push {r4,r5,r6,r7,r8,lr} vpush {d8,d9,d10,d11,d12} ldr r0,[r0] // ss0 ldrd r2,[r1,#8] // tmp0 ldr r6,[r1,#16] // tmp2 add r2,r0,r2,lsl #2 add r3,r0,r3,lsl #2 add r6,r0,r6,lsl #2 ldrd r4,[r1] // di,dest add r7,r0,r4,lsl #2 // end fldd d12,.Lzeros2_1 sub r7,r7,#4*31 cmp r0,r7 bhs .Lendf4loop4 .Lf4loop4: FOLDBY4_CORE FOLDBY4_CORE FOLDBY4_CORE FOLDBY4_CORE cmp r0,r7 blo .Lf4loop4 .Lendf4loop4: add r7,r7,#4*24 cmp r0,r7 bhs .Lendf4loop2 .Lf4loop5: FOLDBY4_CORE cmp r0,r7 blo .Lf4loop5 .Lendf4loop5: b .Lendf4loop2 .Lfoldby4sel: .rept 31 .word vfp_foldArrayBy4_ll31 .endr .word vfp_foldArrayBy4_lge31 .Lzeros3: .float 0.0,0.0 /***** * fold array by 5 ******/ .global vfp_foldArrayBy5_ll31 .type vfp_foldArrayBy5_ll31, %function vfp_foldArrayBy5_ll31: push {r4,r5,r6,r7,r8,lr} vpush {d8,d9,d10,d11,d12} ldr r0,[r0] // ss0 ldrd r2,[r1,#8] // tmp0 ldrd r6,[r1,#16] // tmp2,tmp3 add r2,r0,r2,lsl #2 add r3,r0,r3,lsl #2 add r6,r0,r6,lsl #2 add r7,r0,r7,lsl #2 ldrd r4,[r1] // di,dest add r8,r0,r4,lsl #2 // end fldd d12,.Lzeros3 sub r8,r8,#4*7 cmp r0,r8 bhs .Lendf5loop2 .Lf5loop2: .macro FOLDBY5_CORE fldmias r0!,{s0,s1,s2,s3,s4,s5,s6,s7} fldmias r2!,{s8,s9,s10,s11,s12,s13,s14,s15} fldmias r3!,{s16,s17,s18,s19,s20,s21,s22,s23} fadds s0,s0,s8 fadds s1,s1,s9 fadds s2,s2,s10 fadds s3,s3,s11 fadds s4,s4,s12 fadds s5,s5,s13 fadds s6,s6,s14 fadds s7,s7,s15 fadds s0,s0,s16 fadds s1,s1,s17 fadds s2,s2,s18 fadds s3,s3,s19 fldmias r6!,{s8,s9,s10,s11,s12,s13,s14,s15} fadds s4,s4,s20 fadds s5,s5,s21 fadds s6,s6,s22 fadds s7,s7,s23 fadds s0,s0,s8 fadds s1,s1,s9 fadds s2,s2,s10 fadds s3,s3,s11 fadds s4,s4,s12 fldmias r7!,{s16,s17,s18,s19,s20,s21,s22,s23} fadds s5,s5,s13 fadds s6,s6,s14 fadds s7,s7,s15 fadds s0,s0,s16 fadds s1,s1,s17 fadds s2,s2,s18 fadds s3,s3,s19 fadds s4,s4,s20 fadds s5,s5,s21 fadds s6,s6,s22 fadds s7,s7,s23 fstmias r5!,{s0,s1,s2,s3,s4,s5,s6,s7} fcmpes s24,s0 fmstat fcmpes s25,s1 fcpysmi s24,s0 fmstat fcmpes s24,s2 fcpysmi s25,s1 fmstat fcmpes s25,s3 fcpysmi s24,s2 fmstat fcmpes s24,s4 fcpysmi s25,s3 fmstat fcmpes s25,s5 fcpysmi s24,s4 fmstat fcmpes s24,s6 fcpysmi s25,s5 fmstat fcmpes s25,s7 fcpysmi s24,s6 fmstat fcpysmi s25,s7 .endm FOLDBY5_CORE cmp r0,r8 blo .Lf5loop2 .Lendf5loop2: and r4,r4,#7 cmp r4,#4 blo .Lf5lt4 beq .Lf5eq4 cmp r4,#6 blo .Lf5lt6 beq .Lf5eq6 fldmias r0!,{s0,s1,s2,s3,s4,s5,s6} fldmias r2!,{s8,s9,s10,s11,s12,s13,s14} fldmias r3!,{s16,s17,s18,s19,s20,s21,s22} fadds s0,s0,s8 fadds s1,s1,s9 fadds s2,s2,s10 fadds s3,s3,s11 fadds s4,s4,s12 fadds s5,s5,s13 fadds s6,s6,s14 fadds s0,s0,s16 fadds s1,s1,s17 fadds s2,s2,s18 fadds s3,s3,s19 fadds s4,s4,s20 fadds s5,s5,s21 fadds s6,s6,s22 fldmias r6!,{s16,s17,s18,s19,s20,s21,s22} fadds s0,s0,s16 fadds s1,s1,s17 fadds s2,s2,s18 fadds s3,s3,s19 fadds s4,s4,s20 fadds s5,s5,s21 fadds s6,s6,s22 fldmias r7!,{s16,s17,s18,s19,s20,s21,s22} fadds s0,s0,s16 fadds s1,s1,s17 fadds s2,s2,s18 fadds s3,s3,s19 fadds s4,s4,s20 fadds s5,s5,s21 fadds s6,s6,s22 fstmias r5!,{s0,s1,s2,s3,s4,s5,s6} fcmpes s24,s0 fmstat fcmpes s25,s1 fcpysmi s24,s0 fmstat fcmpes s24,s2 fcpysmi s25,s1 fmstat fcmpes s25,s3 fcpysmi s24,s2 fmstat fcmpes s24,s4 fcpysmi s25,s3 fmstat fcmpes s25,s5 fcpysmi s24,s4 fmstat fcmpes s24,s6 fcpysmi s25,s5 fmstat fcpysmi s24,s6 b .Lf5end .Lf5eq6: fldmias r0!,{s0,s1,s2,s3,s4,s5} fldmias r2!,{s6,s7,s8,s9,s10,s11} fldmias r3!,{s12,s13,s14,s15,s16,s17} fldmias r6!,{s18,s19,s20,s21,s22,s23} fadds s0,s0,s6 fadds s1,s1,s7 fadds s2,s2,s8 fadds s3,s3,s9 fadds s4,s4,s10 fadds s5,s5,s11 fadds s0,s0,s12 fadds s1,s1,s13 fadds s2,s2,s14 fadds s3,s3,s15 fadds s4,s4,s16 fadds s5,s5,s17 fadds s0,s0,s18 fadds s1,s1,s19 fadds s2,s2,s20 fadds s3,s3,s21 fadds s4,s4,s22 fadds s5,s5,s23 fldmias r7!,{s18,s19,s20,s21,s22,s23} fadds s0,s0,s18 fadds s1,s1,s19 fadds s2,s2,s20 fadds s3,s3,s21 fadds s4,s4,s22 fadds s5,s5,s23 fstmias r5!,{s0,s1,s2,s3,s4,s5} fcmpes s24,s0 fmstat fcmpes s25,s1 fcpysmi s24,s0 fmstat fcmpes s24,s2 fcpysmi s25,s1 fmstat fcmpes s25,s3 fcpysmi s24,s2 fmstat fcmpes s24,s4 fcpysmi s25,s3 fmstat fcmpes s25,s5 fcpysmi s24,s4 fmstat fcpysmi s25,s5 b .Lf5end .Lf5lt6: fldmias r0!,{s0,s1,s2,s3,s4} fldmias r2!,{s6,s7,s8,s9,s10} fldmias r3!,{s12,s13,s14,s15,s16} fldmias r6!,{s18,s19,s20,s21,s22} fadds s0,s0,s6 fadds s1,s1,s7 fadds s2,s2,s8 fadds s3,s3,s9 fadds s4,s4,s10 fadds s0,s0,s12 fadds s1,s1,s13 fadds s2,s2,s14 fadds s3,s3,s15 fadds s4,s4,s16 fadds s0,s0,s18 fadds s1,s1,s19 fadds s2,s2,s20 fadds s3,s3,s21 fadds s4,s4,s22 fldmias r7!,{s18,s19,s20,s21,s22} fadds s0,s0,s18 fadds s1,s1,s19 fadds s2,s2,s20 fadds s3,s3,s21 fadds s4,s4,s22 fstmias r5!,{s0,s1,s2,s3,s4} fcmpes s24,s0 fmstat fcmpes s25,s1 fcpysmi s24,s0 fmstat fcmpes s24,s2 fcpysmi s25,s1 fmstat fcmpes s25,s3 fcpysmi s24,s2 fmstat fcmpes s24,s4 fcpysmi s25,s3 fmstat fcpysmi s24,s4 b .Lf5end .Lf5eq4: fldmias r0!,{s0,s1,s2,s3} fldmias r2!,{s4,s5,s6,s7} fldmias r3!,{s8,s9,s10,s11} fldmias r6!,{s12,s13,s14,s15} fldmias r7!,{s16,s17,s18,s19} fadds s0,s0,s4 fadds s1,s1,s5 fadds s2,s2,s6 fadds s3,s3,s7 fadds s0,s0,s8 fadds s1,s1,s9 fadds s2,s2,s10 fadds s3,s3,s11 fadds s0,s0,s12 fadds s1,s1,s13 fadds s2,s2,s14 fadds s3,s3,s15 fadds s0,s0,s16 fadds s1,s1,s17 fadds s2,s2,s18 fadds s3,s3,s19 fstmias r5!,{s0,s1,s2,s3} fcmpes s24,s0 fmstat fcmpes s25,s1 fcpysmi s24,s0 fmstat fcmpes s24,s2 fcpysmi s25,s1 fmstat fcmpes s25,s3 fcpysmi s24,s2 fmstat fcpysmi s25,s3 b .Lf5end .Lf5lt4: cmp r4,#2 blo .Lf5lt2 beq .Lf5eq2 fldmias r0!,{s0,s1,s2} fldmias r2!,{s4,s5,s6} fldmias r3!,{s8,s9,s10} fldmias r6!,{s12,s13,s14} fldmias r7!,{s16,s17,s18} fadds s0,s0,s4 fadds s1,s1,s5 fadds s2,s2,s6 fadds s0,s0,s8 fadds s1,s1,s9 fadds s2,s2,s10 fadds s0,s0,s12 fadds s1,s1,s13 fadds s2,s2,s14 fadds s0,s0,s16 fadds s1,s1,s17 fadds s2,s2,s18 fstmias r5!,{s0,s1,s2} fcmpes s24,s0 fmstat fcmpes s25,s1 fcpysmi s24,s0 fmstat fcmpes s24,s2 fcpysmi s25,s1 fmstat fcpysmi s24,s2 b .Lf5end .Lf5eq2: fldmias r0!,{s0,s1} fldmias r2!,{s4,s5} fldmias r3!,{s8,s9} fldmias r6!,{s12,s13} fldmias r7!,{s16,s17} fadds s0,s0,s4 fadds s1,s1,s5 fadds s0,s0,s8 fadds s1,s1,s9 fadds s0,s0,s12 fadds s1,s1,s13 fadds s0,s0,s16 fadds s1,s1,s17 fstmias r5!,{s0,s1} fcmpes s24,s0 fmstat fcmpes s25,s1 fcpysmi s24,s0 fmstat fcpysmi s25,s1 b .Lf5end .Lf5lt2: cmp r4,#0 beq .Lf5eq0 fldmias r0!,{s0} fldmias r2!,{s1} fldmias r3!,{s2} fldmias r6!,{s3} fldmias r7!,{s4} fadds s0,s0,s1 fadds s0,s0,s2 fadds s0,s0,s3 fadds s0,s0,s4 fstmias r5!,{s0} fcmpes s24,s0 fmstat fcpysmi s24,s0 .Lf5eq0: .Lf5end: fcmpes s24,s25 fmstat fcpysmi s24,s25 fmrs r0,s24 vpop {d8,d9,d10,d11,d12} pop {r4,r5,r6,r7,r8,lr} bx lr .Lzeros3_1: .float 0.0,0.0 .global vfp_foldArrayBy5_lge31 .type vfp_foldArrayBy5_lge31, %function vfp_foldArrayBy5_lge31: push {r4,r5,r6,r7,r8,lr} vpush {d8,d9,d10,d11,d12} ldr r0,[r0] // ss0 ldrd r2,[r1,#8] // tmp0 ldrd r6,[r1,#16] // tmp2,tmp3 add r2,r0,r2,lsl #2 add r3,r0,r3,lsl #2 add r6,r0,r6,lsl #2 add r7,r0,r7,lsl #2 ldrd r4,[r1] // di,dest add r8,r0,r4,lsl #2 // end fldd d12,.Lzeros3_1 sub r8,r8,#4*31 cmp r0,r8 bhs .Lendf5loop4 .Lf5loop4: FOLDBY5_CORE FOLDBY5_CORE FOLDBY5_CORE FOLDBY5_CORE cmp r0,r8 blo .Lf5loop4 .Lendf5loop4: add r8,r8,#4*24 cmp r0,r8 bhs .Lendf5loop2 .Lf5loop5: FOLDBY5_CORE cmp r0,r8 blo .Lf5loop5 .Lendf5loop5: b .Lendf5loop2 .Lfoldby5sel: .rept 31 .word vfp_foldArrayBy5_ll31 .endr .word vfp_foldArrayBy5_lge31 .Lzeros4: .float 0.0,0.0 /***** * fold array by 2 ******/ .global vfp_foldArrayBy2_ll31 .type vfp_foldArrayBy2_ll31, %function vfp_foldArrayBy2_ll31: push {r4,r5,r6,lr} vpush {d8,d9,d10,d11,d12} ldr r0,[r0,#4] // ss1 ldrd r2,[r1,#8] // tmp0 add r2,r0,r2,lsl #2 add r3,r0,r3,lsl #2 ldrd r4,[r1] // di,dest add r6,r2,r4,lsl #2 // end fldd d12,.Lzeros4 sub r6,r6,#4*7 cmp r2,r6 bhs .Lendf2loop2 .Lf2loop2: .macro FOLDBY2_CORE fldmias r2!,{s0,s1,s2,s3,s4,s5,s6,s7} fldmias r3!,{s8,s9,s10,s11,s12,s13,s14,s15} fadds s0,s0,s8 fadds s1,s1,s9 fadds s2,s2,s10 fadds s3,s3,s11 fadds s4,s4,s12 fadds s5,s5,s13 fadds s6,s6,s14 fadds s7,s7,s15 fstmias r5!,{s0,s1,s2,s3,s4,s5,s6,s7} fcmpes s24,s0 fmstat fcmpes s25,s1 fcpysmi s24,s0 fmstat fcmpes s24,s2 fcpysmi s25,s1 fmstat fcmpes s25,s3 fcpysmi s24,s2 fmstat fcmpes s24,s4 fcpysmi s25,s3 fmstat fcmpes s25,s5 fcpysmi s24,s4 fmstat fcmpes s24,s6 fcpysmi s25,s5 fmstat fcmpes s25,s7 fcpysmi s24,s6 fmstat fcpysmi s25,s7 .endm FOLDBY2_CORE cmp r2,r6 blo .Lf2loop2 .Lendf2loop2: and r4,r4,#7 cmp r4,#4 blo .Lf2lt4 beq .Lf2eq4 cmp r4,#6 blo .Lf2lt6 beq .Lf2eq6 fldmias r2!,{s0,s1,s2,s3,s4,s5,s6} fldmias r3!,{s8,s9,s10,s11,s12,s13,s14} fadds s0,s0,s8 fadds s1,s1,s9 fadds s2,s2,s10 fadds s3,s3,s11 fadds s4,s4,s12 fadds s5,s5,s13 fadds s6,s6,s14 fstmias r5!,{s0,s1,s2,s3,s4,s5,s6} fcmpes s24,s0 fmstat fcmpes s25,s1 fcpysmi s24,s0 fmstat fcmpes s24,s2 fcpysmi s25,s1 fmstat fcmpes s25,s3 fcpysmi s24,s2 fmstat fcmpes s24,s4 fcpysmi s25,s3 fmstat fcmpes s25,s5 fcpysmi s24,s4 fmstat fcmpes s24,s6 fcpysmi s25,s5 fmstat fcpysmi s24,s6 b .Lf2end .Lf2eq6: fldmias r2!,{s0,s1,s2,s3,s4,s5} fldmias r3!,{s8,s9,s10,s11,s12,s13} fadds s0,s0,s8 fadds s1,s1,s9 fadds s2,s2,s10 fadds s3,s3,s11 fadds s4,s4,s12 fadds s5,s5,s13 fstmias r5!,{s0,s1,s2,s3,s4,s5} fcmpes s24,s0 fmstat fcmpes s25,s1 fcpysmi s24,s0 fmstat fcmpes s24,s2 fcpysmi s25,s1 fmstat fcmpes s25,s3 fcpysmi s24,s2 fmstat fcmpes s24,s4 fcpysmi s25,s3 fmstat fcmpes s25,s5 fcpysmi s24,s4 fmstat fcpysmi s25,s5 b .Lf2end .Lf2lt6: fldmias r2!,{s0,s1,s2,s3,s4} fldmias r3!,{s8,s9,s10,s11,s12} fadds s0,s0,s8 fadds s1,s1,s9 fadds s2,s2,s10 fadds s3,s3,s11 fadds s4,s4,s12 fstmias r5!,{s0,s1,s2,s3,s4} fcmpes s24,s0 fmstat fcmpes s25,s1 fcpysmi s24,s0 fmstat fcmpes s24,s2 fcpysmi s25,s1 fmstat fcmpes s25,s3 fcpysmi s24,s2 fmstat fcmpes s24,s4 fcpysmi s25,s3 fmstat fcpysmi s24,s4 b .Lf2end .Lf2eq4: fldmias r2!,{s0,s1,s2,s3} fldmias r3!,{s8,s9,s10,s11} fadds s0,s0,s8 fadds s1,s1,s9 fadds s2,s2,s10 fadds s3,s3,s11 fstmias r5!,{s0,s1,s2,s3} fcmpes s24,s0 fmstat fcmpes s25,s1 fcpysmi s24,s0 fmstat fcmpes s24,s2 fcpysmi s25,s1 fmstat fcmpes s25,s3 fcpysmi s24,s2 fmstat fcpysmi s25,s3 b .Lf2end .Lf2lt4: cmp r4,#2 blo .Lf2lt2 beq .Lf2eq2 fldmias r2!,{s0,s1,s2} fldmias r3!,{s8,s9,s10} fadds s0,s0,s8 fadds s1,s1,s9 fadds s2,s2,s10 fstmias r5!,{s0,s1,s2} fcmpes s24,s0 fmstat fcmpes s25,s1 fcpysmi s24,s0 fmstat fcmpes s24,s2 fcpysmi s25,s1 fmstat fcpysmi s24,s2 b .Lf2end .Lf2eq2: fldmias r2!,{s0,s1} fldmias r3!,{s8,s9} fadds s0,s0,s8 fadds s1,s1,s9 fstmias r5!,{s0,s1} fcmpes s24,s0 fmstat fcmpes s25,s1 fcpysmi s24,s0 fmstat fcpysmi s25,s1 b .Lf2end .Lf2lt2: cmp r4,#0 beq .Lf2eq0 fldmias r2!,{s0} fldmias r3!,{s1} fadds s0,s0,s1 fstmias r5!,{s0} fcmpes s24,s0 fmstat fcpysmi s24,s0 .Lf2eq0: .Lf2end: fcmpes s24,s25 fmstat fcpysmi s24,s25 fmrs r0,s24 vpop {d8,d9,d10,d11,d12} pop {r4,r5,r6,lr} bx lr .global vfp_foldArrayBy2_lge31 .type vfp_foldArrayBy2_lge31, %function vfp_foldArrayBy2_lge31: push {r4,r5,r6,lr} vpush {d8,d9,d10,d11,d12} ldr r0,[r0,#4] // ss1 ldrd r2,[r1,#8] // tmp0 add r2,r0,r2,lsl #2 add r3,r0,r3,lsl #2 ldrd r4,[r1] // di,dest add r6,r2,r4,lsl #2 // end fldd d12,.Lzeros4 sub r6,r6,#4*31 cmp r2,r6 bhs .Lendf2loop4 .Lf2loop4: FOLDBY2_CORE FOLDBY2_CORE FOLDBY2_CORE FOLDBY2_CORE cmp r2,r6 blo .Lf2loop4 .Lendf2loop4: add r6,r6,#4*24 cmp r2,r6 bhs .Lendf2loop2 .Lf2loop5: FOLDBY2_CORE cmp r2,r6 blo .Lf2loop5 b .Lendf2loop2 .Lfoldby2sel: .rept 31 .word vfp_foldArrayBy2_ll31 .endr .word vfp_foldArrayBy2_lge31 .align 2 .Lname: .string "opt VFP" .align 2 .global vfpFoldMain vfpFoldMain: .word .Lfoldby3sel .word .Lfoldby4sel .word .Lfoldby5sel .word .Lfoldby2sel .word .Lfoldby2sel .word .Lname /* * vfp_GetPowerSpectrum.S * Author: Mateusz Szpakowski */ .align 2 .global _Z20vfp_GetPowerSpectrumPA2_fPfi .type _Z20vfp_GetPowerSpectrumPA2_fPfi, %function _Z20vfp_GetPowerSpectrumPA2_fPfi: push {r4,r5} vpush {d8,d9,d10,d11,d12,d13,d14,d15} ldr r3,.LGOTa .LPICa: add r3,pc,r3 ldr r4,.LGOTa+4 ldr r4,[r3,r4] add r5,r2,r2,lsl #1 fldd d0,[r4,#32] fmsr s4,r5 fuitod d1,s4 faddd d0,d0,d1 fstd d0,[r4,#32] add r2,r0,r2,lsl #3 sub r2,r2,#15*8 /* r0 - freqData * r1 - PowerSpectrum * r2 - end of freqData */ cmp r0,r2 bhs .Lendmainloopa .Lmainloopa: pld [r0,#64] fldmias r0!,{s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15} fmuls s16,s0,s0 fmuls s17,s2,s2 fmuls s18,s4,s4 fmuls s19,s6,s6 fmuls s20,s8,s8 fmuls s21,s10,s10 fmuls s22,s12,s12 fmuls s23,s14,s14 fmacs s16,s1,s1 fmacs s17,s3,s3 fmacs s18,s5,s5 fmacs s19,s7,s7 fmacs s20,s9,s9 fmacs s21,s11,s11 fmacs s22,s13,s13 fmacs s23,s15,s15 pld [r0,#64] fldmias r0!,{s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15} fstmias r1!,{s16,s17,s18,s19,s20,s21,s22,s23} fmuls s24,s0,s0 fmuls s25,s2,s2 fmuls s26,s4,s4 fmuls s27,s6,s6 fmuls s28,s8,s8 fmuls s29,s10,s10 fmuls s30,s12,s12 fmuls s31,s14,s14 fmacs s24,s1,s1 fmacs s25,s3,s3 fmacs s26,s5,s5 fmacs s27,s7,s7 fmacs s28,s9,s9 fmacs s29,s11,s11 fmacs s30,s13,s13 fmacs s31,s15,s15 fstmias r1!,{s24,s25,s26,s27,s28,s29,s30,s31} cmp r0,r2 blo .Lmainloopa .Lendmainloopa: add r2,r2,#8*12 bhs .Lendsmallloopa .Lsmallloopa: fldmias r0!,{s0,s1,s2,s3,s4,s5,s6,s7} fmuls s16,s0,s0 fmuls s17,s2,s2 fmuls s18,s4,s4 fmuls s19,s6,s6 fmacs s16,s1,s1 fmacs s17,s3,s3 fmacs s18,s5,s5 fmacs s19,s7,s7 fstmias r1!,{s16,s17,s18,s19} cmp r0,r2 blo .Lsmallloopa .Lendsmallloopa: add r2,r2,#8*3 cmp r0,r2 beq .Lendmicroloop .Lmicroloop: fldmias r0!,{s0,s1} fmuls s2,s0,s0 fmacs s2,s1,s1 fstmias r1!,{s2} cmp r0,r2 blo .Lmicroloop .Lendmicroloop: mov r0,#0 vpop {d8,d9,d10,d11,d12,d13,d14,d15} pop {r4,r5} bx lr .align 2 .LGOTa: .word _GLOBAL_OFFSET_TABLE_-(.LPICa+8) .word analysis_state(GOT) #endif // __arm__ boinc-app-seti_8.00~svn3701.orig/client/vector/x86_ops.h0000644000175000017500000001247412321065336022762 0ustar locutuslocutus// Copyright (c) 1999-2006 Regents of the University of California // // FFTW: Copyright (c) 2003,2006 Matteo Frigo // Copyright (c) 2003,2006 Massachusets Institute of Technology // // fft8g.[cpp,h]: Copyright (c) 1995-2001 Takya Ooura // 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, 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; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions // as an alternative to FFTW and distribute a linked executable and // source code. You must obey the GNU General Public License in all // respects for all of the code used other than the FFT library itself. // Any modification required to support these libraries must be distributed // under the terms of this license. If you modify this program, you may extend // this exception to your version of the program, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. Please be aware that FFTW is not covered by this exception, // therefore you may not use FFTW in any derivative work so modified without // permission of the authors of FFTW. #ifndef _X86_OPS_H_ #define _X86_OPS_H_ #if defined(_M_AMD64) || defined(__x86_64__) // Make sure we use MMX,SSE/2/3 on x86_64 #ifndef USE_MMX #define USE_MMX 1 #ifndef __MMX__ #define __MMX__ #endif #endif #ifndef USE_3DNOW #define USE_3DNOW 1 #define __3DNOW__ 1 #endif #ifndef USE_SSE #define USE_SSE 1 #define __SSE__ 1 #endif #ifndef USE_SSE2 #define USE_SSE2 1 #define __SSE2__ 1 #endif #ifndef USE_SSE3 #define USE_SSE3 1 #define __SSE3__ 1 #endif #endif #if defined(__GNUC__) #define ALIGN_ATTR(x) __attribute__((aligned(x))) #define ALIGN_DECL(x) #else #define ALIGN_ATTR(x) #define ALIGN_DECL(x) __declspec(align(x)) #endif // How to declare an aligned variable. #define ALIGNED(decl,x) \ ALIGN_DECL(x) decl ALIGN_ATTR(x) #if defined (_WIN64) && defined (_M_AMD64) #ifdef HAVE_EMMINTRIN_H #ifdef USE_SSE2 #include #endif #endif #elif defined(__SSE__) || defined(USE_SSE) || defined(__SSE2__) // Make sure MSC doesn't use slow emulations #undef _MM_FUNCTIONALITY #undef _MM2_FUNCTIONALITY #ifdef HAVE_EMMINTRIN_H #ifdef USE_SSE2 #if (__GNUC__ < 4) || ((__GNUC__ > 3) && defined(__SSE2__)) #include #endif #endif #endif #ifdef HAVE_XMMINTRIN_H #include #endif #endif // We will use the defines __SSE__, __SSE2__ and __SSE3__ // GCC defines these based upon command line args. #if defined(USE_MMX) && !defined(__MMX__) #define __MMX__ 1 #endif #if defined(USE_SSE) && !defined(__SSE__) #define __SSE__ 1 #endif #if defined(USE_SSE2) && !defined(__SSE2__) #define __SSE2__ 1 #endif #if defined(USE_SSE3) && !defined(__SSE3__) #define __SSE3__ 1 #endif #if defined(__MMX__) // MMX instructions/macros here. #endif #if defined(__3DNOW__) // 3DNOW functions/macros here #ifdef HAVE_MM3DNOW_H #include #else // #warning No 3DNow header available... #endif #endif #if defined(__SSE3__) // PNI specific functions/macros here. #endif #if defined(__SSE2__) // SSE2 specific functions/macros here. #if defined(_MSC_VER) || defined(__clang__) typedef __m128d x86_m128d; #else typedef double x86_m128d __attribute__ ((mode(V2DF))) __attribute__((aligned(16))); #endif #endif #if defined(__SSE__) // SSE specific functions/macros here. #if defined(_MSC_VER) || defined(__clang__) typedef __m128 x86_m128; typedef __m128i x86_m128i; #else typedef float x86_m128 __attribute__ ((mode(V4SF))) __attribute__((aligned(16))); typedef int x86_m128i __attribute__ ((mode(V4SI))) __attribute__((aligned(16))); #endif static inline void prefetcht0(const void *v) { #ifdef USE_INTRINSICS _mm_prefetch((const char *)v,_MM_HINT_T0); #elif defined(__GNUC__) __asm__ volatile ( "prefetcht0 %0" : : "m" (*(const char *)v) ); #endif } static inline void prefetcht1(const void *v) { #ifdef USE_INTRINSICS _mm_prefetch((const char *)v,_MM_HINT_T1); #elif defined(__GNUC__) __asm__ volatile ( "prefetcht1 %0" : : "m" (*(const char *)v) ); #endif } static inline void prefetcht2(const void *v) { #ifdef USE_INTRINSICS _mm_prefetch((const char *)v,_MM_HINT_T2); #elif defined(__GNUC__) __asm__ volatile ( "prefetcht2 %0" : : "m" (*(const char *)v) ); #endif } static inline void prefetchnta(const void *v) { #ifdef USE_INTRINSICS _mm_prefetch((const char *)v,_MM_HINT_NTA); #elif defined(__GNUC__) __asm__ volatile ( "prefetchnta %0" : : "m" (*(const char *)v) ); #endif } #endif #ifndef __m128d #define __m128d x86_m128d #endif #ifndef __m128i #define __m128i x86_m128i #endif #ifndef __m128 #define __m128 x86_m128 #endif #endif boinc-app-seti_8.00~svn3701.orig/client/vector/asmlibm.lib0000644000175000017500000001275410671336410023420 0ustar locutuslocutus! / 1107021387 0 301 `     HHHHppDetectProcessorProcessorName_DetectProcessor_ProcessorNameInstructionSet_InstructionSet_instrsetinstrsetReadClock_ReadClockMaxDMinD_MaxD_MinDMaxIMinI_MaxI_MinITruncate_TruncateRound_Round / 1107021387 0 289 `   HpDetectProcessorInstructionSetMaxDMaxIMinDMinIProcessorNameReadClockRoundTruncate_DetectProcessor_InstructionSet_MaxD_MaxI_MinD_MinI_ProcessorName_ReadClock_Round_Truncate_instrsetinstrset detectpr.cof/ 1107021388 100666 1006 ` LJA .text P`.data@P.debug$SQp@BSVW3X5 P[3% 33ۀtÀA  %  ʁ ʃ ʃ ʁ t)=r% @ tdt\uUUE  4ZM E  M3=4Z ]_^[SVWU|$u 8048G6 orG lowG er=r$W_OW Ev_3WOG 30O FamGily G? MoG del 0Gƃ0<9v G]_^[  detectpr.cof6/Microsoft (R) Macro Assembler Version 6.15.8803.filegdetectpr.asm@comp.idc"*.text.data.debug$SQ'$ 4' B_ProcessorName_DetectProcessorDetectProcessorProcessorNameinstrset.cof/ 1089713074 100666 707 ` L@ .textL P`.dataV@P.debug$SQZ@BSX5 P[33 3t}@tt@tktc@t @t@܁$$ $ 4Z $$ $$ $  $3ʋ4Zt[   instrset.cof6/Microsoft (R) Macro Assembler Version 6.15.8803.fileginstrset.asm@comp.idc"*.text.data.debug$SQinstrset -_instrset_InstructionSetInstructionSet rdtsc.cof/ 1102242870 100666 459 ` L5A .text P`.data@P.debug$SN@BS+1PR+ZX[  rdtsc.cof6/Microsoft (R) Macro Assembler Version 6.15.8803.filegrdtsc.asm@comp.idc"*.text.data.debug$SN _ReadClockReadClock minmaxd.cof/ 1089710674 100666 777 ` LQ@.textH P`.data@P.debug$SP@B=|D$]D$ D$D$Ã=|D$D$ Ã=|D$T$ uD$ 뢃=|D$_D$ D$D$Ã=|D$D$ Ã=|D$T$ tD$  " : X `      minmaxd.cof6/Microsoft (R) Macro Assembler Version 6.15.8803.filegminmaxd.asm@comp.idc"*.text.data.debug$SPinstrset_MaxD^_MinDMinD MaxD^ InstructionSet minmaxi.cof/ 1089710674 100666 492 ` LQ@ .text" P`.data"@P.debug$S"P@BD$L$+#ËD$L$+#  minmaxi.cof6/Microsoft (R) Macro Assembler Version 6.15.8803.filegminmaxi.asm@comp.idc"*.text".data.debug$SP_MinI_MaxIMinI MaxI truncate.cof/ 1089710674 100666 595 ` LP@L .textP P`.dataP@P.debug$SPQ@B=|,D$Ã=|0D$ $T$$$\$XYZx 3Ʌ  J   truncate.cof6/Microsoft (R) Macro Assembler Version 6.15.8803.filegtruncate.asm@comp.idc"*.textP.data.debug$SQinstrsetTruncate InstructionSet_Truncate round.cof/ 1089710672 100666 432 ` LP@ .text P`.data @P.debug$S N@BD$$X  round.cof6/Microsoft (R) Macro Assembler Version 6.15.8803.fileground.asm@comp.idc"*.text .data.debug$SN_RoundRound boinc-app-seti_8.00~svn3701.orig/client/vector/fp_arm.h0000644000175000017500000001265612641277157022735 0ustar locutuslocutus// Copyright (c) 1999-2013 Regents of the University of California // // FFTW: Copyright (c) 2003,2006 Matteo Frigo // Copyright (c) 2003,2006 Massachusets Institute of Technology // // fft8g.[cpp,h]: Copyright (c) 1995-2001 Takya Ooura // // ASMLIB: Copyright (c) 2004 Agner Fog // 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, 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; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions // as an alternative to FFTW and distribute a linked executable and // source code. You must obey the GNU General Public License in all // respects for all of the code used other than the FFT library itself. // Any modification required to support these libraries must be distributed // under the terms of this license. If you modify this program, you may extend // this exception to your version of the program, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. Please be aware that FFTW and ASMLIB are not covered by // this exception, therefore you may not use FFTW and ASMLIB in any derivative // work so modified without permission of the authors of those packages. // #if defined(__arm__) #include #include #include "s_util.h" #include "sighandler.h" // Exception masks #define _EM_INVALID 0x00000100 // Invalid Operation #define _EM_ZERODIVIDE 0x00000200 // Divide by zero #define _EM_OVERFLOW 0x00000400 // Overflow #define _EM_UNDERFLOW 0x00000800 // Underflow #define _EM_INEXACT 0x00001000 // Inexact result #define _EM_DENORMAL 0x00008000 // Denormal result #define _MCW_EM (_EM_INVALID|_EM_ZERODIVIDE|_EM_OVERFLOW|_EM_UNDERFLOW|_EM_INEXACT|_EM_DENORMAL) // Rounding control #define _RC_CHOP 0x000c0000 // Truncate #define _RC_DOWN 0x00080000 // Round down #define _RC_UP 0x00040000 // Round up #define _RC_NEAREST 0x00000000 // Round to nearest #define _MCW_RC (_RC_CHOP|_RC_UP|_RC_DOWN|_RC_NEAREST) #define _NAN_DEFAULT 0x00200000 // Use default NaN rather than propogating NaN #define _MCW_NAN _NAN_DEFAULT #define _FLUSH_TO_ZERO 0x00100000 // Replaces denormalized numbers with zero #define _MCW_FLUSH_TO_ZERO _FLUSH_TO_ZERO #if 0 These VFP vector mode has been deprecated #define _VECTOR_LEN(x) ((((x)-1)&7)<<16) // Set length of vectors to x #define _MCW_VECTOR_LEN_MASK _VECTOR_LEN(8) #define _VECTOR_STRIDE(x) (((x)==2)?(3<<20):0) #define _MCW_VECTOR_STRIDE_MASK (3<<20) #endif static unsigned int save_cw; static unsigned int cw; inline static unsigned int controlfp(unsigned int flags, unsigned int mask) { install_sighandler(); FORCE_FRAME_POINTER; if (sigsetjmp(jb,1)) { uninstall_sighandler(); cw=0; save_cw=0; fprintf(stderr,"User mode control of fp control register not allowed\n"); } else { #if defined(__VFP_FP__) && !defined(__SOFTFP__) __asm__ __volatile__ ( "fmrx %0,fpscr\n" : "=r" (cw) ); #endif save_cw=cw; cw=(cw & ~mask) | (flags & mask); #if defined(__VFP_FP__) && !defined(__SOFTFP__) __asm__ __volatile__ ( "fmxr fpscr,%0\n" : : "r" (cw) ); #endif uninstall_sighandler(); } return cw; } inline static unsigned int restorefp() { if (save_cw != 0) { #if defined(__VFP_FP__) && !defined(__SOFTFP__) __asm__ __volatile__ ( "fmxr fpscr,%0\n" : : "r" (save_cw) ); #else cw=save_cw; #endif } return save_cw; } // ARM prefetch inline void pld(void *arg1,const int arg2=0) { __asm__ __volatile__ ( "pld [%0,%1]\n" : : "r" (arg1), "Jr" (arg2) ); } #if 0 static const uint64_t arm_TWO_TO_52(0x4330000000000000); static const uint64_t arm_SIGN_BIT(0x8000000000000000); static const uint32_t arm_TWO_TO_23(0x4b000000); static const uint32_t arm_FSIGN_BIT(0x80000000); #if defined(__VFP_FP__) && !defined(__SOFTFP__) inline static double arm_round(double x) { register uint64_t s=*reinterpret_cast(&x) & arm_SIGN_BIT; uint64_t a=s | arm_TWO_TO_52; volatile register double d=*reinterpret_cast(&a); return (x+d)-d; } inline static float arm_round(float x) { register uint32_t s=*reinterpret_cast(&x) & arm_FSIGN_BIT; uint32_t a=s | arm_TWO_TO_23; volatile register float d=*reinterpret_cast(&a); return (x+d)-d; } #define round(x) arm_round(x) inline static double arm_floor(double x) { return round(x-0.5); } inline static float arm_floor(float x) { return round(x-0.5f); } #define floor(x) arm_floor(x) #endif #endif #endif boinc-app-seti_8.00~svn3701.orig/client/vector/asmlibe.a0000644000175000017500000001632610671336410023061 0ustar locutuslocutus! / 1107021388 0 0 0 302 ` rrrr _ProcessorName_DetectProcessorDetectProcessorProcessorNameinstrset_instrset_InstructionSetInstructionSet_ReadClockReadClock_MaxD_MinDMinDMaxD_MinI_MaxIMinIMaxI_TruncateTruncate_RoundRounddetectpr.cof/ 1107021390 0 0 100666 1286 ` ELF4(SVW3X5 P[3% 33ۀtÀA  %  ʁ ʃ ʃ ʁ t)=r% @ tdt\uUUE  4ZM E  M3=4Z ]_^[SVWU|$u 8048G6 orG lowG er=r$W_OW Ev_3WOG 30O FamGily G? MoG del 0Gƃ0<9v G]_^[  detectpr.cof6/Microsoft (R) Macro Assembler Version 6.15.8803.symtab.strtab.shstrtab.text.data.debug$S@!0'0Q0  jc"*#,';L\'detectpr.asm@comp.id.text.data.debug$S_ProcessorName_DetectProcessorDetectProcessorProcessorNameinstrset.cof/ 1107021390 0 0 100666 1028 ` ELF4(SX5 P[33 3t}@tt@tktc@t @t@܁$$ $ 4Z $$ $$ $  $3ʋ4Zt[  instrset.cof6/Microsoft (R) Macro Assembler Version 6.15.8803.symtab.strtab.shstrtab.rel.text.data.debug$S@ %+QU4  ^c"*#,5?Oinstrset.asm@comp.id.text.data.debug$Sinstrset_instrset_InstructionSetInstructionSet rdtsc.cof/ 1107021390 0 0 100666 742 ` ELF4(S+1PR+ZX[  rdtsc.cof6/Microsoft (R) Macro Assembler Version 6.15.8803.symtab.strtab.shstrtab.text.data.debug$S@!`'`N0  > c"* )4rdtsc.asm@comp.id.text.data.debug$S_ReadClockReadClockminmaxd.cof/ 1107021390 0 0 100666 1104 ` ELF4(=|D$]D$ D$D$Ã=|D$D$ Ã=|D$T$ uD$ 뢃=|D$_D$ D$D$Ã=|D$D$ Ã=|D$T$ tD$   minmaxd.cof6/Microsoft (R) Macro Assembler Version 6.15.8803.symtab.strtab.shstrtab.rel.text.data.debug$S@ @%+PP4  Y c"*"+4C^IOT^minmaxd.asm@comp.id.text.data.debug$SinstrsetInstructionSet_MaxD_MinDMinDMaxD " : X `    minmaxi.cof/ 1107021390 0 0 100666 793 ` ELF4(D$L$+#ËD$L$+#  minmaxi.cof6/Microsoft (R) Macro Assembler Version 6.15.8803.symtab.strtab.shstrtab.text.data.debug$S@"!p'pP0  A c"*"+17<minmaxi.asm@comp.id.text.data.debug$S_MinI_MaxIMinIMaxI truncate.cof/ 1107021390 0 0 100666 920 ` ELF4(=|,D$Ã=|0D$ $T$$$\$XYZx 3Ʌ  truncate.cof6/Microsoft (R) Macro Assembler Version 6.15.8803.symtab.strtab.shstrtab.rel.text.data.debug$S@P %+Q4X  (Wc"*#,5DNtruncate.asm@comp.id.text.data.debug$SinstrsetInstructionSet_TruncateTruncate  J round.cof/ 1107021390 0 0 100666 718 ` ELF4(D$$X  round.cof6/Microsoft (R) Macro Assembler Version 6.15.8803.symtab.strtab.shstrtab.text.data.debug$S@ !P'PN0  6 c"* )0round.asm@comp.id.text.data.debug$S_RoundRoundboinc-app-seti_8.00~svn3701.orig/client/vector/analyzeFuncs_altivec.cpp0000644000175000017500000017066212313644616026171 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // $Id: analyzeFuncs_altivec.cpp,v 1.1.2.4 2006/12/14 22:21:59 korpela Exp $ // // This file is empty is USE_ALTIVEC is not defined #include "sah_config.h" #if defined(__ppc__) && defined(USE_ALTIVEC) #define INVALID_CHIRP 2e+20 #include "analyzeFuncs.h" #include "analyzeFuncs_vector.h" #include "analyzePoT.h" #include "analyzeReport.h" #include "gaussfit.h" #include "s_util.h" #include "pulsefind.h" #include #include #include // polynomial coefficients for sine / cosine approximation in the chirp routine #define SS1 ((vector float) (1.5707963268)) #define SS2 ((vector float) (-0.6466386396)) #define SS3 ((vector float) (0.0679105987)) #define SS4 ((vector float) (-0.0011573807)) #define CC1 ((vector float) (-1.2341299769)) #define CC2 ((vector float) (0.2465220241)) #define CC3 ((vector float) (-0.0123926179)) #define ZERO ((vector float) (0)) #define ONE ((vector float) (1.0)) #define TWO ((vector float) (2.0)) #define RECIP_TWO ((vector float) (0.5)) #define RECIP_THREE ((vector float) (1.0 / 3.0)) #define RECIP_FOUR ((vector float) (0.25)) #define RECIP_FIVE ((vector float) (0.2)) // 2^52 (used by quickRound) #define TWO_TO_52 4.503599627370496e15 static bool checked=false; static bool hasAltiVec=false; bool AltiVec_Available( void ) { if (!checked) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("AltiVec_Available()"); #endif checked=true; long cpuAttributes; OSErr err = Gestalt( gestaltPowerPCProcessorFeatures, &cpuAttributes ); if( noErr == err ) hasAltiVec = ( 1 << gestaltPowerPCHasVectorInstructions) & cpuAttributes; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } return hasAltiVec; } inline vector float vec_fpsplat(float f_Constant) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("vec_fpsplat()"); #endif vector unsigned char vuc_Splat; vector float vf_Constant; vuc_Splat = vec_lvsl(0, &f_Constant); vf_Constant = vec_lde(0, &f_Constant); vuc_Splat = (vector unsigned char) vec_splat((vector float) vuc_Splat, 0); vf_Constant = vec_perm(vf_Constant, vf_Constant, vuc_Splat); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return vf_Constant; } inline vector float vec_rsqrt(vector float v) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("vec_rsqrt()"); #endif const vector float _0 = (vector float)(-.0); // obtain estimate vector float y = vec_rsqrte(v); // two rounds of Newton-Raphson y = vec_madd(vec_nmsub(v,vec_madd(y,y,_0),(vector float)(1.0)),vec_madd(y,(vector float)(0.5),_0),y); y = vec_madd(vec_nmsub(v,vec_madd(y,y,_0),(vector float)(1.0)),vec_madd(y,(vector float)(0.5),_0),y); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return y; } inline vector float vec_sqrt(vector float v) { vector float y; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("vec_rsqrt()"); #endif const vector float _0 = (vector float)(-.0); y=vec_sel(vec_madd(v,vec_rsqrt(v),_0),_0,vec_cmpeq(v,_0)); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return y; } inline vector float vec_recip(vector float v) { // obtain estimate vector float estimate = vec_re( v ); vector float y; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("vec_recip"); #endif // one round of Newton-Raphson y=vec_madd( vec_nmsub( estimate, v, (vector float) (1.0) ), estimate, estimate ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return y; } int v_vTranspose(int i, int j, float *in, float *out) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("v_vTranspose"); #endif if (AltiVec_Available()) { vSgetmo(j, i, (vector float *) in, (vector float *) out); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } else { #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return UNSUPPORTED_FUNCTION; } } int v_vGetPowerSpectrum( sah_complex* FreqData, float* PowerSpectrum, int NumDataPoints ) { int i, vEnd; const vector unsigned char real = (vector unsigned char) (0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27); const vector unsigned char imag = (vector unsigned char) (4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31); if (!AltiVec_Available()) return UNSUPPORTED_FUNCTION; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("v_vGetPowerSpectrum()"); #endif analysis_state.FLOP_counter+=3.0*NumDataPoints; vEnd = NumDataPoints - (NumDataPoints & 3); for (i = 0; i < vEnd; i += 4) { const float *f = (const float *) (FreqData + i); float *p = PowerSpectrum + i; vector float f1, f2; vector float re1, im1; vector float p1; f1 = vec_ld(0, f); f2 = vec_ld(16, f); re1 = vec_perm(f1, f2, real); im1 = vec_perm(f1, f2, imag); p1 = vec_madd(re1, re1, vec_madd(im1, im1, ZERO)); vec_st(p1, 0, p); } // handle tail elements, although in practice this never happens for (; i < NumDataPoints; i++) { PowerSpectrum[i] = FreqData[i][0] * FreqData[i][0] + FreqData[i][1] * FreqData[i][1]; } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } int v_vGetPowerSpectrumG4( sah_complex* FreqData, float* PowerSpectrum, int NumDataPoints ) { int i = 0, vEnd; const vector unsigned char real = (vector unsigned char) (0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27); const vector unsigned char imag = (vector unsigned char) (4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31); if (!AltiVec_Available()) return UNSUPPORTED_FUNCTION; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("v_vGetPowerSpectrumG4()"); #endif analysis_state.FLOP_counter+=3.0*NumDataPoints; vEnd = NumDataPoints - (NumDataPoints & 15); for (i = 0; i < vEnd; i += 16) { const float *f = (const float *) (FreqData + i); float *p = PowerSpectrum + i; vector float f1, f2, f3, f4, f5, f6, f7, f8; vector float re1, im1, re2, im2, re3, im3, re4, im4; vector float p1, p2, p3, p4; // prefetch next 512 bytes into L1 cache vec_dstt(f, 0x10020100, 0); f1 = vec_ld(0, f); f2 = vec_ld(16, f); f3 = vec_ld(32, f); f4 = vec_ld(48, f); f5 = vec_ld(64, f); f6 = vec_ld(80, f); f7 = vec_ld(96, f); f8 = vec_ld(112, f); re1 = vec_perm(f1, f2, real); im1 = vec_perm(f1, f2, imag); re2 = vec_perm(f3, f4, real); im2 = vec_perm(f3, f4, imag); re3 = vec_perm(f5, f6, real); im3 = vec_perm(f5, f6, imag); re4 = vec_perm(f7, f8, real); im4 = vec_perm(f7, f8, imag); // zero out a spot for our power data in the cache __dcbz(0, p); __dcbz(32, p); p1 = vec_madd(re1, re1, vec_madd(im1, im1, ZERO)); p2 = vec_madd(re2, re2, vec_madd(im2, im2, ZERO)); p3 = vec_madd(re3, re3, vec_madd(im3, im3, ZERO)); p4 = vec_madd(re4, re4, vec_madd(im4, im4, ZERO)); vec_st(p1, 0, p); vec_st(p2, 16, p); vec_st(p3, 32, p); vec_st(p4, 48, p); } vEnd = NumDataPoints - (NumDataPoints & 3); for (; i < vEnd; i += 4) { const float *f = (const float *) (FreqData + i); float *p = PowerSpectrum + i; vector float f1, f2; vector float re1, im1; vector float p1; f1 = vec_ld(0, f); f2 = vec_ld(16, f); re1 = vec_perm(f1, f2, real); im1 = vec_perm(f1, f2, imag); p1 = vec_madd(re1, re1, vec_madd(im1, im1, ZERO)); vec_st(p1, 0, p); } // handle tail elements, although in practice this never happens for (; i < NumDataPoints; i++) { PowerSpectrum[i] = FreqData[i][0] * FreqData[i][0] + FreqData[i][1] * FreqData[i][1]; } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } // quickRound // // Quickly round a value to the nearest integer. This is done by adding a large // value (which depends on the format of an IEEE double precision variable) and // then subtracting it again to extract the fractional part of the variable. // // If x is positive, roundVal must be TWO_TO_52. // If x is negative, roundVal must be -TWO_TO_52. // // NOTE: This function does not do any fancy IEEE compliant arithmetic (like // handling NaN etc. or preserving the sign of +/-0). // // NOTE: Make sure that you don't use any compiler flags that will cancel // out the operations. inline double quickRound(double x, double roundVal) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("quickRound()"); #endif double rv=(x + roundVal) - roundVal; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return rv; } // chirp // // Increase the frequency of the input signal over time. // // Note that the input angle is calculated in double-precision. The angle // becomes so large that single-precision arithmetic is insufficient for the // accuracy that we need. We can only convert to single-precision after // reducing the range to (-0.5, 0.5). // // The algorithm used to generate the sine / cosine values is based on that // described in "A Fast, Vectorizable Algorithm for Producing Single-Precision // Sine-Cosine Pairs" by Marcus H. Mendenhall. The paper is available at: // http://arxiv.org/pdf/cs.MS/0406049 // // Differences from the implementation in the paper: // 1. The arguments are not scaled by 1/(2 pi) because the original chirp // algorithm multiplies the chirp rate by (2 pi). // 2. The slower version of the algorithm has been used (as if FASTER_SINCOS // had not been defined for the code in the paper). // 3. The loop has been unrolled once so the variables have been renamed to make // things more readable. // 4. The "struct phase" data type is not used. // 5. The rounding of the input value to the range (-0.5, 0.5) is done in // double-precision as mentioned above, and not via Altivec. int v_vChirpData( sah_complex* cx_DataArray, sah_complex* cx_ChirpDataArray, int chirp_rate_ind, double chirp_rate, int ul_NumDataPoints, double sample_rate ) { // int offset, int numPoints, double chirpRate int i; if (!AltiVec_Available()) return UNSUPPORTED_FUNCTION; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("v_vChirpData()"); #endif if (chirp_rate_ind == 0) { memcpy(cx_ChirpDataArray, cx_DataArray, (int)ul_NumDataPoints * sizeof(sah_complex) ); } else { int vEnd; const vector unsigned char real = (vector unsigned char) (0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27); const vector unsigned char imag = (vector unsigned char) (4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31); double rate = chirp_rate * 0.5 / (sample_rate * sample_rate); double roundVal = rate >= 0.0 ? TWO_TO_52 : -TWO_TO_52; // main vectorised loop vEnd = ul_NumDataPoints - (ul_NumDataPoints & 7); for (i = 0; i < vEnd; i += 8) { const float *d = (const float *) (cx_DataArray + i); float *c = (float *) (cx_ChirpDataArray + i); double a1 = i; double a2 = i + 1.0; double a3 = i + 2.0; double a4 = i + 3.0; double a5 = i + 4.0; double a6 = i + 5.0; double a7 = i + 6.0; double a8 = i + 7.0; float v[8] __attribute__ ((aligned (16))); vector float d1, d2, d3, d4; vector float cd1, cd2, cd3, cd4; vector float dre1, dre2; vector float dim1, dim2; vector float cre1, cre2; vector float cim1, cim2; vector float x1, x2; vector float y1, y2; vector float s1, s2; vector float c1, c2; vector float m1, m2; // load the signal to be chirped d1 = vec_ld(0, d); d2 = vec_ld(16, d); d3 = vec_ld(32, d); d4 = vec_ld(48, d); // calculate the input angle a1 *= a1 * rate; a2 *= a2 * rate; a3 *= a3 * rate; a4 *= a4 * rate; a5 *= a5 * rate; a6 *= a6 * rate; a7 *= a7 * rate; a8 *= a8 * rate; // reduce the angle to the range (-0.5, 0.5) and store to // memory so we can load it into the vector unit v[0] = a1 - quickRound(a1, roundVal); v[1] = a2 - quickRound(a2, roundVal); v[2] = a3 - quickRound(a3, roundVal); v[3] = a4 - quickRound(a4, roundVal); v[4] = a5 - quickRound(a5, roundVal); v[5] = a6 - quickRound(a6, roundVal); v[6] = a7 - quickRound(a7, roundVal); v[7] = a8 - quickRound(a8, roundVal); // load angle into the vector unit x1 = vec_ld(0, v); x2 = vec_ld(16, v); // square to the range [0, 0.25) y1 = vec_madd(x1, x1, ZERO); y2 = vec_madd(x2, x2, ZERO); // perform the initial polynomial approximations s1 = vec_madd(x1, vec_madd(y1, vec_madd(y1, vec_madd(y1, SS4, SS3), SS2), SS1), ZERO); s2 = vec_madd(x2, vec_madd(y2, vec_madd(y2, vec_madd(y2, SS4, SS3), SS2), SS1), ZERO); c1 = vec_madd(y1, vec_madd(y1, vec_madd(y1, CC3, CC2), CC1), ONE); c2 = vec_madd(y2, vec_madd(y2, vec_madd(y2, CC3, CC2), CC1), ONE); // permute the loaded data into separate real and complex vectors dre1 = vec_perm(d1, d2, real); dim1 = vec_perm(d1, d2, imag); dre2 = vec_perm(d3, d4, real); dim2 = vec_perm(d3, d4, imag); // perform first angle doubling x1 = vec_nmsub(s1, s1, vec_madd(c1, c1, ZERO)); x2 = vec_nmsub(s2, s2, vec_madd(c2, c2, ZERO)); y1 = vec_madd(TWO, vec_madd(s1, c1, ZERO), ZERO); y2 = vec_madd(TWO, vec_madd(s2, c2, ZERO), ZERO); // calculate scaling factor to correct the magnitude // m1 = vec_nmsub(y1, y1, vec_nmsub(x1, x1, TWO)); // m2 = vec_nmsub(y2, y2, vec_nmsub(x2, x2, TWO)); m1 = vec_recip(vec_madd(y1, y1, vec_madd(x1, x1, ZERO))); m2 = vec_recip(vec_madd(y2, y2, vec_madd(x2, x2, ZERO))); // perform second angle doubling c1 = vec_nmsub(y1, y1, vec_madd(x1, x1, ZERO)); c2 = vec_nmsub(y2, y2, vec_madd(x2, x2, ZERO)); s1 = vec_madd(TWO, vec_madd(y1, x1, ZERO), ZERO); s2 = vec_madd(TWO, vec_madd(y2, x2, ZERO), ZERO); // correct the magnitude (final sine / cosine approximations) s1 = vec_madd(s1, m1, ZERO); s2 = vec_madd(s2, m2, ZERO); c1 = vec_madd(c1, m1, ZERO); c2 = vec_madd(c2, m2, ZERO); // chirp the data cre1 = vec_nmsub(dim1, s1, vec_madd(dre1, c1, ZERO)); cre2 = vec_nmsub(dim2, s2, vec_madd(dre2, c2, ZERO)); cim1 = vec_madd(dim1, c1, vec_madd(dre1, s1, ZERO)); cim2 = vec_madd(dim2, c2, vec_madd(dre2, s2, ZERO)); // permute into interleaved form cd1 = vec_mergeh(cre1,cim1); cd2 = vec_mergel(cre1,cim1); cd3 = vec_mergeh(cre2,cim2); cd4 = vec_mergel(cre2,cim2); // store chirped values vec_st(cd1, 0, c); vec_st(cd2, 16, c); vec_st(cd3, 32, c); vec_st(cd4, 48, c); } // handle tail elements with scalar code for (; i < ul_NumDataPoints; ++i) { double angle = rate * i * i * 0.5; double s = sin(angle); double c = cos(angle); float re = cx_DataArray[i][0]; float im = cx_DataArray[i][1]; cx_ChirpDataArray[i][0] = re * c - im * s; cx_ChirpDataArray[i][1] = re * s + im * c; } analysis_state.FLOP_counter+=12.0*ul_NumDataPoints; } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } int v_vChirpDataG4( sah_complex* cx_DataArray, sah_complex* cx_ChirpDataArray, int chirp_rate_ind, double chirp_rate, int ul_NumDataPoints, double sample_rate ) { // int offset, int numPoints, double chirpRate int i; if (!AltiVec_Available()) return UNSUPPORTED_FUNCTION; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("v_vChirpDataG4()"); #endif if (chirp_rate_ind == 0) { memcpy(cx_ChirpDataArray, cx_DataArray, (int)ul_NumDataPoints * sizeof(sah_complex) ); } else { int vEnd; const vector unsigned char real = (vector unsigned char) (0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27); const vector unsigned char imag = (vector unsigned char) (4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31); double rate = chirp_rate * 0.5 / (sample_rate * sample_rate); double roundVal = rate >= 0.0 ? TWO_TO_52 : -TWO_TO_52; // main vectorised loop vEnd = ul_NumDataPoints - (ul_NumDataPoints & 7); for (i = 0; i < vEnd; i += 8) { const float *d = (const float *) (cx_DataArray + i); float *c = (float *) (cx_ChirpDataArray + i); double a1 = i; double a2 = i + 1.0; double a3 = i + 2.0; double a4 = i + 3.0; double a5 = i + 4.0; double a6 = i + 5.0; double a7 = i + 6.0; double a8 = i + 7.0; float v[8] __attribute__ ((aligned (16))); vector float d1, d2, d3, d4; vector float cd1, cd2, cd3, cd4; vector float dre1, dre2; vector float dim1, dim2; vector float cre1, cre2; vector float cim1, cim2; vector float x1, x2; vector float y1, y2; vector float s1, s2; vector float c1, c2; vector float m1, m2; // prefetch next 256 bytes into L1 cache vec_dstt(d, 0x10010100, 0); // load the signal to be chirped d1 = vec_ld(0, d); d2 = vec_ld(16, d); d3 = vec_ld(32, d); d4 = vec_ld(48, d); // calculate the input angle a1 *= a1 * rate; a2 *= a2 * rate; a3 *= a3 * rate; a4 *= a4 * rate; a5 *= a5 * rate; a6 *= a6 * rate; a7 *= a7 * rate; a8 *= a8 * rate; // reduce the angle to the range (-0.5, 0.5) and store to // memory so we can load it into the vector unit v[0] = a1 - quickRound(a1, roundVal); v[1] = a2 - quickRound(a2, roundVal); v[2] = a3 - quickRound(a3, roundVal); v[3] = a4 - quickRound(a4, roundVal); v[4] = a5 - quickRound(a5, roundVal); v[5] = a6 - quickRound(a6, roundVal); v[6] = a7 - quickRound(a7, roundVal); v[7] = a8 - quickRound(a8, roundVal); // load angle into the vector unit x1 = vec_ld(0, v); x2 = vec_ld(16, v); // square to the range [0, 0.25) y1 = vec_madd(x1, x1, ZERO); y2 = vec_madd(x2, x2, ZERO); // perform the initial polynomial approximations s1 = vec_madd(x1, vec_madd(y1, vec_madd(y1, vec_madd(y1, SS4, SS3), SS2), SS1), ZERO); s2 = vec_madd(x2, vec_madd(y2, vec_madd(y2, vec_madd(y2, SS4, SS3), SS2), SS1), ZERO); c1 = vec_madd(y1, vec_madd(y1, vec_madd(y1, CC3, CC2), CC1), ONE); c2 = vec_madd(y2, vec_madd(y2, vec_madd(y2, CC3, CC2), CC1), ONE); // permute the loaded data into separate real and complex vectors dre1 = vec_perm(d1, d2, real); dim1 = vec_perm(d1, d2, imag); dre2 = vec_perm(d3, d4, real); dim2 = vec_perm(d3, d4, imag); // perform first angle doubling x1 = vec_nmsub(s1, s1, vec_madd(c1, c1, ZERO)); x2 = vec_nmsub(s2, s2, vec_madd(c2, c2, ZERO)); y1 = vec_madd(TWO, vec_madd(s1, c1, ZERO), ZERO); y2 = vec_madd(TWO, vec_madd(s2, c2, ZERO), ZERO); // calculate scaling factor to correct the magnitude // m1 = vec_nmsub(y1, y1, vec_nmsub(x1, x1, TWO)); // m2 = vec_nmsub(y2, y2, vec_nmsub(x2, x2, TWO)); m1 = vec_recip(vec_madd(y1, y1, vec_madd(x1, x1, ZERO))); m2 = vec_recip(vec_madd(y2, y2, vec_madd(x2, x2, ZERO))); // zero out a spot for our chirped data in the cache __dcbz(0, c); __dcbz(32, c); // perform second angle doubling c1 = vec_nmsub(y1, y1, vec_madd(x1, x1, ZERO)); c2 = vec_nmsub(y2, y2, vec_madd(x2, x2, ZERO)); s1 = vec_madd(TWO, vec_madd(y1, x1, ZERO), ZERO); s2 = vec_madd(TWO, vec_madd(y2, x2, ZERO), ZERO); // correct the magnitude (final sine / cosine approximations) s1 = vec_madd(s1, m1, ZERO); s2 = vec_madd(s2, m2, ZERO); c1 = vec_madd(c1, m1, ZERO); c2 = vec_madd(c2, m2, ZERO); // chirp the data cre1 = vec_nmsub(dim1, s1, vec_madd(dre1, c1, ZERO)); cre2 = vec_nmsub(dim2, s2, vec_madd(dre2, c2, ZERO)); cim1 = vec_madd(dim1, c1, vec_madd(dre1, s1, ZERO)); cim2 = vec_madd(dim2, c2, vec_madd(dre2, s2, ZERO)); // permute into interleaved form cd1 = vec_mergeh(cre1,cim1); cd2 = vec_mergel(cre1,cim1); cd3 = vec_mergeh(cre2,cim2); cd4 = vec_mergel(cre2,cim2); // store chirped values vec_st(cd1, 0, c); vec_st(cd2, 16, c); vec_st(cd3, 32, c); vec_st(cd4, 48, c); } // handle tail elements with scalar code for (; i < ul_NumDataPoints; ++i) { double angle = rate * i * i * 0.5; double s = sin(angle); double c = cos(angle); float re = cx_DataArray[i][0]; float im = cx_DataArray[i][1]; cx_ChirpDataArray[i][0] = re * c - im * s; cx_ChirpDataArray[i][1] = re * s + im * c; } analysis_state.FLOP_counter+=12.0*ul_NumDataPoints; } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } int v_vChirpDataG5( sah_complex* cx_DataArray, sah_complex* cx_ChirpDataArray, int chirp_rate_ind, double chirp_rate, int ul_NumDataPoints, double sample_rate ) { // int offset, int numPoints, double chirpRate int i; if (!AltiVec_Available()) return UNSUPPORTED_FUNCTION; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("v_vChirpDataG5()"); #endif if (chirp_rate_ind == 0) { memcpy(cx_ChirpDataArray, cx_DataArray, (int)ul_NumDataPoints * sizeof(sah_complex) ); } else { int vEnd; const vector unsigned char real = (vector unsigned char) (0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27); const vector unsigned char imag = (vector unsigned char) (4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31); double rate = chirp_rate * 0.5 / (sample_rate * sample_rate); double roundVal = rate >= 0.0 ? TWO_TO_52 : -TWO_TO_52; // main vectorised loop vEnd = ul_NumDataPoints - (ul_NumDataPoints & 15); for (i = 0; i < vEnd; i += 16) { const float *d = (const float *) (cx_DataArray + i); float *c = (float *) (cx_ChirpDataArray + i); double a1 = i; double a2 = i + 1.0; double a3 = i + 2.0; double a4 = i + 3.0; double a5 = i + 4.0; double a6 = i + 5.0; double a7 = i + 6.0; double a8 = i + 7.0; double a9 = i + 8.0; double a10 = i + 9.0; double a11 = i + 10.0; double a12 = i + 11.0; double a13 = i + 12.0; double a14 = i + 13.0; double a15 = i + 14.0; double a16 = i + 15.0; float v[16] __attribute__ ((aligned (16))); vector float d1, d2, d3, d4, d5, d6, d7, d8; vector float cd1, cd2, cd3, cd4, cd5, cd6, cd7, cd8; vector float dre1, dre2, dre3, dre4; vector float dim1, dim2, dim3, dim4; vector float cre1, cre2, cre3, cre4; vector float cim1, cim2, cim3, cim4; vector float x1, x2, x3, x4; vector float y1, y2, y3, y4; vector float s1, s2, s3, s4; vector float c1, c2, c3, c4; vector float m1, m2, m3, m4; // load the signal to be chirped d1 = vec_ld(0, d); d2 = vec_ld(16, d); d3 = vec_ld(32, d); d4 = vec_ld(48, d); d5 = vec_ld(64, d); d6 = vec_ld(80, d); d7 = vec_ld(96, d); d8 = vec_ld(112, d); // calculate the input angle a1 *= a1 * rate; a2 *= a2 * rate; a3 *= a3 * rate; a4 *= a4 * rate; a5 *= a5 * rate; a6 *= a6 * rate; a7 *= a7 * rate; a8 *= a8 * rate; a9 *= a9 * rate; a10 *= a10 * rate; a11 *= a11 * rate; a12 *= a12 * rate; a13 *= a13 * rate; a14 *= a14 * rate; a15 *= a15 * rate; a16 *= a16 * rate; // reduce the angle to the range (-0.5, 0.5) and store to // memory so we can load it into the vector unit v[0] = a1 - quickRound(a1, roundVal); v[1] = a2 - quickRound(a2, roundVal); v[2] = a3 - quickRound(a3, roundVal); v[3] = a4 - quickRound(a4, roundVal); v[4] = a5 - quickRound(a5, roundVal); v[5] = a6 - quickRound(a6, roundVal); v[6] = a7 - quickRound(a7, roundVal); v[7] = a8 - quickRound(a8, roundVal); v[8] = a9 - quickRound(a9, roundVal); v[9] = a10 - quickRound(a10, roundVal); v[10] = a11 - quickRound(a11, roundVal); v[11] = a12 - quickRound(a12, roundVal); v[12] = a13 - quickRound(a13, roundVal); v[13] = a14 - quickRound(a14, roundVal); v[14] = a15 - quickRound(a15, roundVal); v[15] = a16 - quickRound(a16, roundVal); // load angle into the vector unit x1 = vec_ld(0, v); x2 = vec_ld(16, v); x3 = vec_ld(32, v); x4 = vec_ld(48, v); // square to the range [0, 0.25) y1 = vec_madd(x1, x1, ZERO); y2 = vec_madd(x2, x2, ZERO); y3 = vec_madd(x3, x3, ZERO); y4 = vec_madd(x4, x4, ZERO); // perform the initial polynomial approximations s1 = vec_madd(x1, vec_madd(y1, vec_madd(y1, vec_madd(y1, SS4, SS3), SS2), SS1), ZERO); s2 = vec_madd(x2, vec_madd(y2, vec_madd(y2, vec_madd(y2, SS4, SS3), SS2), SS1), ZERO); c1 = vec_madd(y1, vec_madd(y1, vec_madd(y1, CC3, CC2), CC1), ONE); c2 = vec_madd(y2, vec_madd(y2, vec_madd(y2, CC3, CC2), CC1), ONE); s3 = vec_madd(x3, vec_madd(y3, vec_madd(y3, vec_madd(y3, SS4, SS3), SS2), SS1), ZERO); s4 = vec_madd(x4, vec_madd(y4, vec_madd(y4, vec_madd(y4, SS4, SS3), SS2), SS1), ZERO); c3 = vec_madd(y3, vec_madd(y3, vec_madd(y3, CC3, CC2), CC1), ONE); c4 = vec_madd(y4, vec_madd(y4, vec_madd(y4, CC3, CC2), CC1), ONE); // permute the loaded data into separate real and complex vectors dre1 = vec_perm(d1, d2, real); dim1 = vec_perm(d1, d2, imag); dre2 = vec_perm(d3, d4, real); dim2 = vec_perm(d3, d4, imag); dre3 = vec_perm(d5, d6, real); dim3 = vec_perm(d5, d6, imag); dre4 = vec_perm(d7, d8, real); dim4 = vec_perm(d7, d8, imag); // perform first angle doubling x1 = vec_nmsub(s1, s1, vec_madd(c1, c1, ZERO)); x2 = vec_nmsub(s2, s2, vec_madd(c2, c2, ZERO)); y1 = vec_madd(TWO, vec_madd(s1, c1, ZERO), ZERO); y2 = vec_madd(TWO, vec_madd(s2, c2, ZERO), ZERO); x3 = vec_nmsub(s3, s3, vec_madd(c3, c3, ZERO)); x4 = vec_nmsub(s4, s4, vec_madd(c4, c4, ZERO)); y3 = vec_madd(TWO, vec_madd(s3, c3, ZERO), ZERO); y4 = vec_madd(TWO, vec_madd(s4, c4, ZERO), ZERO); // calculate scaling factor to correct the magnitude // m1 = vec_nmsub(y1, y1, vec_nmsub(x1, x1, TWO)); // m2 = vec_nmsub(y2, y2, vec_nmsub(x2, x2, TWO)); m1 = vec_recip(vec_madd(y1, y1, vec_madd(x1, x1, ZERO))); m2 = vec_recip(vec_madd(y2, y2, vec_madd(x2, x2, ZERO))); m3 = vec_recip(vec_madd(y3, y3, vec_madd(x3, x3, ZERO))); m4 = vec_recip(vec_madd(y4, y4, vec_madd(x4, x4, ZERO))); // perform second angle doubling c1 = vec_nmsub(y1, y1, vec_madd(x1, x1, ZERO)); c2 = vec_nmsub(y2, y2, vec_madd(x2, x2, ZERO)); s1 = vec_madd(TWO, vec_madd(y1, x1, ZERO), ZERO); s2 = vec_madd(TWO, vec_madd(y2, x2, ZERO), ZERO); c3 = vec_nmsub(y3, y3, vec_madd(x3, x3, ZERO)); c4 = vec_nmsub(y4, y4, vec_madd(x4, x4, ZERO)); s3 = vec_madd(TWO, vec_madd(y3, x3, ZERO), ZERO); s4 = vec_madd(TWO, vec_madd(y4, x4, ZERO), ZERO); // correct the magnitude (final sine / cosine approximations) s1 = vec_madd(s1, m1, ZERO); s2 = vec_madd(s2, m2, ZERO); c1 = vec_madd(c1, m1, ZERO); c2 = vec_madd(c2, m2, ZERO); s3 = vec_madd(s3, m3, ZERO); s4 = vec_madd(s4, m4, ZERO); c3 = vec_madd(c3, m3, ZERO); c4 = vec_madd(c4, m4, ZERO); // chirp the data cre1 = vec_nmsub(dim1, s1, vec_madd(dre1, c1, ZERO)); cre2 = vec_nmsub(dim2, s2, vec_madd(dre2, c2, ZERO)); cim1 = vec_madd(dim1, c1, vec_madd(dre1, s1, ZERO)); cim2 = vec_madd(dim2, c2, vec_madd(dre2, s2, ZERO)); cre3 = vec_nmsub(dim3, s3, vec_madd(dre3, c3, ZERO)); cre4 = vec_nmsub(dim4, s4, vec_madd(dre4, c4, ZERO)); cim3 = vec_madd(dim3, c3, vec_madd(dre3, s3, ZERO)); cim4 = vec_madd(dim4, c4, vec_madd(dre4, s4, ZERO)); // permute into interleaved form cd1 = vec_mergeh(cre1,cim1); cd2 = vec_mergel(cre1,cim1); cd3 = vec_mergeh(cre2,cim2); cd4 = vec_mergel(cre2,cim2); cd5 = vec_mergeh(cre3,cim3); cd6 = vec_mergel(cre3,cim3); cd7 = vec_mergeh(cre4,cim4); cd8 = vec_mergel(cre4,cim4); // store chirped values vec_st(cd1, 0, c); vec_st(cd2, 16, c); vec_st(cd3, 32, c); vec_st(cd4, 48, c); vec_st(cd5, 64, c); vec_st(cd6, 80, c); vec_st(cd7, 96, c); vec_st(cd8, 112, c); } // handle tail elements with scalar code for (; i < ul_NumDataPoints; ++i) { double angle = rate * i * i * 0.5; double s = sin(angle); double c = cos(angle); float re = cx_DataArray[i][0]; float im = cx_DataArray[i][1]; cx_ChirpDataArray[i][0] = re * c - im * s; cx_ChirpDataArray[i][1] = re * s + im * c; } analysis_state.FLOP_counter+=12.0*ul_NumDataPoints; } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } float f_vGetChiSq( float fp_PoT[], int ul_PowerLen, int ul_TOffset, float f_PeakPower, float f_MeanPower, float f_weight[], float *xsq_null=0 ) { // We calculate our assumed gaussian powers // on the fly as we try to fit them to the // actual powers at each point along the PoT. if (!AltiVec_Available()) return UNSUPPORTED_FUNCTION; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("f_vGetChiSq()"); #endif int i; int vEnd, vul_PowerLen; float f_ChiSq=0,f_null_hyp=0, f_PredictedPower; vector float v_PeakPower, v_MeanPower, v_rMeanPower, v_rebin; vector float v_TempChiSq = ZERO, v_ChiSq, v_temp_null_hyp = ZERO, v_null_hyp, v_PredictedPower, v_weight; double rebin=swi.nsamples/ChirpFftPairs[analysis_state.icfft].FftLen /ul_PowerLen; // splat Altivec versions of function constants v_PeakPower = vec_fpsplat(f_PeakPower); v_MeanPower = vec_fpsplat(f_MeanPower); v_rMeanPower = vec_fpsplat(1.0f / f_MeanPower); v_rebin = vec_fpsplat((float) rebin); // set up unaligned loads for weight array int offwt = PoTInfo.GaussTOffsetStop - 1 - ul_TOffset; vector float msqwt = vec_ld(0, f_weight + offwt); vector unsigned char maskwt = vec_add(vec_lvsl(-1L, f_weight + offwt), vec_splat_u8(1)); vul_PowerLen = ul_PowerLen - (ul_PowerLen & 0x3); for (i = 0; i < vul_PowerLen; i += 4) { const float *p = fp_PoT + i; const float *wt = f_weight + offwt + i; vector float lsqwt = vec_ld(15, wt); vector float v_PoT = vec_ld(0, p); vector float v_weight = vec_perm(msqwt, lsqwt, maskwt); vector float v_noise, v_rnoise; v_PredictedPower = vec_madd(v_PeakPower, v_weight, v_MeanPower); v_PredictedPower = vec_madd(v_PredictedPower, v_rMeanPower, ZERO); v_noise = vec_madd(vec_sqrt(vec_sub(vec_max(v_PredictedPower, ONE), ONE)), TWO, ONE); v_rnoise = vec_recip(v_noise); v_TempChiSq = vec_madd(vec_madd(vec_madd(vec_nmsub(v_PoT, v_rMeanPower, v_PredictedPower), vec_nmsub(v_PoT, v_rMeanPower, v_PredictedPower), ZERO), v_rnoise, ZERO), v_rebin, v_TempChiSq); v_temp_null_hyp = vec_madd(vec_madd(vec_madd(vec_nmsub(v_PoT, v_rMeanPower, ONE), vec_nmsub(v_PoT, v_rMeanPower, ONE), ZERO), v_rnoise, ZERO), v_rebin, v_temp_null_hyp); msqwt = lsqwt; } v_ChiSq = v_TempChiSq; v_null_hyp = v_temp_null_hyp; // handle tail elements for (; i < ul_PowerLen; i++) { f_PredictedPower = f_MeanPower + f_PeakPower * f_weight[offwt+i] ; // ChiSq in this realm is: // sum[0:i]( (observed power - expected power)^2 / expected variance ) // The power of a signal is: // power = (noise + signal)^2 = noise^2 + signal^2 + 2*noise*signal // With mean power normalization, noise becomes 1, leaving: // power = signal^2 +or- 2*signal + 1 f_PredictedPower/=f_MeanPower; double signal=f_PredictedPower; double noise=(2.0*sqrt(std::max(f_PredictedPower,1.0f)-1)+1); f_ChiSq += (static_cast(rebin)*SQUARE(fp_PoT[i]/f_MeanPower - signal)/noise); f_null_hyp+= (static_cast(rebin)*SQUARE(fp_PoT[i]/f_MeanPower-1)/noise); } // sum vector and scalar elements float *vp_ChiSq = (float *) &v_ChiSq; float *vp_null_hyp = (float *) &v_null_hyp; f_ChiSq += vp_ChiSq[0] + vp_ChiSq[1] + vp_ChiSq[2] + vp_ChiSq[3]; f_null_hyp += vp_null_hyp[0] + vp_null_hyp[1] + vp_null_hyp[2] + vp_null_hyp[3]; analysis_state.FLOP_counter+=20.0*ul_PowerLen+5; f_ChiSq/=ul_PowerLen; f_null_hyp/=ul_PowerLen; if (xsq_null) *xsq_null=f_null_hyp; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return f_ChiSq; } float f_vGetTrueMean( float fp_PoT[], int ul_PowerLen, float f_TotalPower, int ul_TOffset, int ul_ExcludeLen ) { // TrueMean is the mean power of the data set minus all power // out to ExcludeLen from our current TOffset. if (!AltiVec_Available()) return UNSUPPORTED_FUNCTION; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("f_vGetTrueMean()"); #endif int i, i_start, i_lim, vStart, vEnd; float f_ExcludePower = 0; vector float v_TempExcludePower = ZERO, v_ExcludePower; // take care that we do not add to exclude power beyond PoT bounds! i_start = std::max(ul_TOffset - ul_ExcludeLen, 0); i_lim = std::min(ul_TOffset + ul_ExcludeLen + 1, swi.analysis_cfg.gauss_pot_length); vStart = i_start + 3; vStart = vStart - (vStart & 3); vEnd = i_lim - (i_lim & 3); // handle leading elements for (i = i_start; i < vStart; i++) { f_ExcludePower += fp_PoT[i]; } for (; i < vEnd; i += 4) { v_TempExcludePower = vec_add(vec_ld(0, fp_PoT + i), v_TempExcludePower); } v_ExcludePower = v_TempExcludePower; // handle tail elements for (; i < i_lim; i++) { f_ExcludePower += fp_PoT[i]; } // sum vector and scalar elements float *vp_ExcludePower = (float *) &v_ExcludePower; f_ExcludePower += vp_ExcludePower[0] + vp_ExcludePower[1] + vp_ExcludePower[2] + vp_ExcludePower[3]; analysis_state.FLOP_counter+=(double)(i_lim-i_start+5); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return((f_TotalPower - f_ExcludePower) / (ul_PowerLen - (i - i_start))); } int vGaussFit( float * fp_PoT, int ul_FftLength, int ul_PoT ) { int i, retval; BOOLEAN b_IsAPeak; float f_NormMaxPower; float f_null_hyp; if (!AltiVec_Available()) return UNSUPPORTED_FUNCTION; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("vGaussFit()"); #endif int ul_TOffset; int iSigma = static_cast(floor(PoTInfo.GaussSigma+0.5)); double diSigma = iSigma; float f_GroupSum, f_GroupMax; int i_f, iPeakLoc; float f_TotalPower, f_TrueMean, f_ChiSq, f_PeakPower; float f_rMeanPower; float f_TotalPowerOverTrueMeanElems; vector float v_TotalPower; vector float v_rMeanPower; vector float v_PowerThresh; // For setiathome the Sigma and Gaussian PoT length don't change during // a run of the application, so these frequently used values can be // precalculated and kept. static float f_PeakScaleFactor; static float *f_weight; static float *f_vweight; static float *f_PeakFilter; static float *f_BoxFilter; static float *f_corr; static float *f_swsum; static float f_rTrueMeanElems = 1.0f / (swi.analysis_cfg.gauss_pot_length - (4*iSigma+1)); if (!f_weight) { f_PeakScaleFactor = f_GetPeakScaleFactor(static_cast(PoTInfo.GaussSigma)); // Altivec code uses double-sided f_weight to make memory accesses simpler f_vweight = reinterpret_cast(malloc((2*PoTInfo.GaussTOffsetStop-1)*sizeof(float))); if (!f_vweight) SETIERROR(MALLOC_FAILED, "!f_vweight"); f_vweight[PoTInfo.GaussTOffsetStop-1] = 1; f_PeakFilter = reinterpret_cast(malloc((2*iSigma+1)*sizeof(float))); if (!f_PeakFilter) SETIERROR(MALLOC_FAILED, "!f_PeakFilter"); f_BoxFilter = reinterpret_cast(malloc((4*iSigma+1)*sizeof(float))); if (!f_BoxFilter) SETIERROR(MALLOC_FAILED, "!f_BoxFilter"); f_PeakFilter[iSigma] = f_PeakScaleFactor; f_BoxFilter[2*iSigma] = f_rTrueMeanElems; f_weight = reinterpret_cast(malloc(PoTInfo.GaussTOffsetStop*sizeof(float))); if (!f_weight) SETIERROR(MALLOC_FAILED, "!f_weight"); f_weight[0] = 1; for (i = 1; i <= iSigma; i++) { float weight = static_cast(EXP(i, 0, PoTInfo.GaussSigmaSq)); f_vweight[PoTInfo.GaussTOffsetStop-1+i] = weight; f_vweight[PoTInfo.GaussTOffsetStop-1-i] = weight; f_PeakFilter[iSigma+i] = weight * f_PeakScaleFactor; f_PeakFilter[iSigma-i] = weight * f_PeakScaleFactor; f_BoxFilter[2*iSigma+i] = f_rTrueMeanElems; f_BoxFilter[2*iSigma-i] = f_rTrueMeanElems; f_weight[i] = weight; } for (; i <= 2*iSigma; i++) { float weight = static_cast(EXP(i, 0, PoTInfo.GaussSigmaSq)); f_vweight[PoTInfo.GaussTOffsetStop-1+i] = weight; f_vweight[PoTInfo.GaussTOffsetStop-1-i] = weight; f_BoxFilter[2*iSigma+i] = f_rTrueMeanElems; f_BoxFilter[2*iSigma-i] = f_rTrueMeanElems; f_weight[i] = weight; } for (; i < PoTInfo.GaussTOffsetStop; i++) { float weight = static_cast(EXP(i, 0, PoTInfo.GaussSigmaSq)); f_vweight[PoTInfo.GaussTOffsetStop-1+i] = weight; f_vweight[PoTInfo.GaussTOffsetStop-1-i] = weight; f_weight[i] = weight; } } // Find reciprocal of mean over power-of-time array // Assumes that swi.analysis_cfg.gauss_pot_length is a multiple of 4 v_TotalPower = ZERO; for (i = 0; i < swi.analysis_cfg.gauss_pot_length; i += 4) { const float *p = fp_PoT + i; vector float v_PoT = vec_ld(0, p); v_TotalPower = vec_add(v_TotalPower, v_PoT); } v_TotalPower = vec_add(v_TotalPower, vec_sld(v_TotalPower, v_TotalPower, 8)); v_TotalPower = vec_add(v_TotalPower, vec_sld(v_TotalPower, v_TotalPower, 4)); v_rMeanPower = vec_madd(vec_recip(v_TotalPower), vec_fpsplat((float) swi.analysis_cfg.gauss_pot_length), ZERO); // Normalize power-of-time and check for the existence // of at least 1 peak. b_IsAPeak = false; v_PowerThresh = vec_fpsplat(PoTInfo.GaussPowerThresh); for (i = 0; i < swi.analysis_cfg.gauss_pot_length; i += 4) { float *p = fp_PoT + i; vector float v_PoT = vec_ld(0, p); v_PoT = vec_madd(v_PoT, v_rMeanPower, ZERO); b_IsAPeak |= vec_any_gt(v_PoT, v_PowerThresh); vec_st(v_PoT, 0, p); } analysis_state.FLOP_counter+=3.0*swi.analysis_cfg.gauss_pot_length+2; if (!b_IsAPeak) { //printf("no peak\n"); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; // no peak - bail on this PoT } // Recalculate Total Power across normalized array. // Given that powers are positive, f_TotalPower will // end up being == swi.analysis_cfg.gauss_pot_length. f_TotalPower = 0; f_NormMaxPower = 0; // Also locate group with the highest sum for use in second bailout check. f_GroupSum = 0; f_GroupMax = 0; for (i = 0, i_f = -iSigma; i < swi.analysis_cfg.gauss_pot_length; i++, i_f++) { f_TotalPower += fp_PoT[i]; if(fp_PoT[i] > f_NormMaxPower) f_NormMaxPower = fp_PoT[i]; f_GroupSum += fp_PoT[i] - ((i_f < 0) ? 0.0f : fp_PoT[i_f]); if (f_GroupSum > f_GroupMax) { f_GroupMax = f_GroupSum; iPeakLoc = i - iSigma/2; } } f_TotalPowerOverTrueMeanElems = f_TotalPower * f_rTrueMeanElems; // Check at the group peak location whether data may contain Gaussians // (but only after the first hurry-up Gaussian has been set for graphics) if (best_gauss->display_power_thresh != 0) { iPeakLoc = std::max(PoTInfo.GaussTOffsetStart, (std::min(PoTInfo.GaussTOffsetStop - 1, iPeakLoc))); f_TrueMean = f_vGetTrueMean( fp_PoT, swi.analysis_cfg.gauss_pot_length, f_TotalPower, iPeakLoc, 2 * iSigma ); f_PeakPower = f_GetPeak( fp_PoT, iPeakLoc, iSigma, f_TrueMean, f_PeakScaleFactor, f_weight ); analysis_state.FLOP_counter+=5.0*swi.analysis_cfg.gauss_pot_length+5; if (f_PeakPower < f_TrueMean * best_gauss->display_power_thresh*0.5f) { #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; // not even a weak peak at max group - bail on this PoT } } f_corr = reinterpret_cast(malloc((PoTInfo.GaussTOffsetStop - PoTInfo.GaussTOffsetStart)*sizeof(float))); f_swsum = reinterpret_cast(malloc((swi.analysis_cfg.gauss_pot_length-4*iSigma)*sizeof(float))); conv(fp_PoT, 1, f_PeakFilter, 1, f_corr, 1, PoTInfo.GaussTOffsetStop - PoTInfo.GaussTOffsetStart, 2*iSigma+1); conv(fp_PoT, 1, f_BoxFilter, 1, f_swsum, 1, swi.analysis_cfg.gauss_pot_length-4*iSigma, 4*iSigma+1); // slide dynamic gaussian across the Power Of Time array double loop_flops = 0; float display_power_thresh = best_gauss->display_power_thresh; float f_tempTotalPowerOverTrueMeanElems = f_TotalPowerOverTrueMeanElems; for (ul_TOffset = PoTInfo.GaussTOffsetStart; ul_TOffset < PoTInfo.GaussTOffsetStop; ul_TOffset++ ) { // TrueMean is the mean power of the data set minus all power // out to 2 sigma from our current TOffset. if ((ul_TOffset - 2 * iSigma) < 0 || (ul_TOffset + 2 * iSigma) >= swi.analysis_cfg.gauss_pot_length) { f_TrueMean = f_vGetTrueMean( fp_PoT, swi.analysis_cfg.gauss_pot_length, f_TotalPower, ul_TOffset, 2 * iSigma ); } else { f_TrueMean = f_tempTotalPowerOverTrueMeanElems - f_swsum[ul_TOffset - 2 * iSigma]; loop_flops+=4.0*diSigma+6.0; } f_PeakPower = f_corr[ul_TOffset-iSigma] - f_TrueMean; loop_flops+=6.0*diSigma; // worth looking at ? if (f_PeakPower < f_TrueMean * display_power_thresh) { continue; } // bump up the display threshold to its final value. // We could bump it up only to the gaussian just found, // but that would cause a lot of time waste // computing chisq etc. if (display_power_thresh == 0) { display_power_thresh = best_gauss->display_power_thresh = PoTInfo.GaussPeakPowerThresh/3; } f_ChiSq = f_vGetChiSq( fp_PoT, swi.analysis_cfg.gauss_pot_length, ul_TOffset, f_PeakPower, f_TrueMean, f_vweight, &f_null_hyp ); retval = ChooseGaussEvent( ul_TOffset, f_PeakPower, f_TrueMean, f_ChiSq, f_null_hyp, ul_PoT, static_cast(PoTInfo.GaussSigma), f_NormMaxPower, fp_PoT ); if (retval) SETIERROR(retval,"from ChooseGaussEvent"); } // End of sliding gaussian analysis_state.FLOP_counter+=loop_flops; free(f_corr); free(f_swsum); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } // End of vGaussFit() /********************** * * Subroutines for pulse folding, refactored by Joe Segur from code by Alex Kan * */ inline vector unsigned int vec_uisplat(unsigned int ui_Constant) { vector unsigned char vuc_Splat; vector unsigned int vui_Constant; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("vec_uisplat()"); #endif vuc_Splat = vec_lvsl(0, &ui_Constant); vui_Constant = vec_lde(0, &ui_Constant); vuc_Splat = (vector unsigned char) vec_splat((vector unsigned int) vuc_Splat, 0); vui_Constant = vec_perm(vui_Constant, vui_Constant, vuc_Splat); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return vui_Constant; } /********************** * * foldArrayBy2 - Perform "folds" on 2 adjacent parts of the power over time * array. Each element in the "folded" array is the sum of the 2 elements * in the power over time array. Array is folded in-place. * * Assumes 16-byte alignment of input array, but offsets within the array may be * arbitrary. * */ float foldArrayBy2SPA(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("foldArrayBy2SPA()"); #endif float max; int vEnd; vector float tempMaxV = ZERO, maxV; vector float msq2 = vec_ld(0, ss[1]+P->tmp0); vector float msqz; vector unsigned char mask2 = vec_add(vec_lvsl(-1L, ss[1]+P->tmp0), vec_splat_u8(1)); vector unsigned int tailelem = {0, 1, 2, 3}; vector unsigned int taillim = vec_uisplat(((P->di-1)&0x3) + 1); vector unsigned int tailmask; int i = 0, index = 0; // int d_elemsWritten = 0; const float *p1 = ss[1]+P->offset, *p2 = ss[1]+P->tmp0; float *pst = P->dest; vector float lsq2, x1, x2, xs, zst; #define F2_STAGE1 x1 = vec_ld(0, p1); lsq2 = vec_ld(15, p2); i += 4; p1 += 4; p2 += 4; #define F2_STAGE2 x2 = vec_perm(msq2, lsq2, mask2); msq2 = lsq2; xs = vec_add(x1, x2); // was vec_madd(xs, RECIP_TWO, ZERO); #define F2_STAGE3 zst = xs; #define F2_STAGE4 tempMaxV = vec_max(tempMaxV, zst); vec_st(zst, index, pst); pst += 4; // software pipelined main loop - omit last stage of tail element if (P->di-i >= 12) { F2_STAGE1; F2_STAGE2; F2_STAGE1; F2_STAGE3; F2_STAGE2; F2_STAGE1; while (i < P->di) { F2_STAGE4; F2_STAGE3; F2_STAGE2; F2_STAGE1; } F2_STAGE4; F2_STAGE3; F2_STAGE2; F2_STAGE4; F2_STAGE3; // F2_STAGE4; } else { // main loop while (i < P->di-4) { F2_STAGE1; F2_STAGE2; F2_STAGE3; F2_STAGE4; } F2_STAGE1; F2_STAGE2; F2_STAGE3; } #undef F2_STAGE1 #undef F2_STAGE2 #undef F2_STAGE3 #undef F2_STAGE4 tailmask = (vector unsigned int) vec_cmplt(tailelem, taillim); zst = vec_and(zst, (vector float) tailmask); tempMaxV = vec_max(tempMaxV, zst); vec_st(zst, index, pst); // take the maximum across max and maxV and return it tempMaxV = vec_max(tempMaxV, vec_sld(tempMaxV, tempMaxV, 8)); maxV = vec_max(tempMaxV, vec_sld(tempMaxV, tempMaxV, 4)); float *maxVp = (float *) &maxV; max = *maxVp; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return max; } /* Assumes 16-byte alignment of both halves of input array */ float foldArrayBy2SPAL(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("foldArrayBy2SPAL()"); #endif float max; int vEnd; vector float tempMaxV = ZERO, maxV; vector unsigned int tailelem = {0, 1, 2, 3}; vector unsigned int taillim = vec_uisplat(((P->di-1)&0x3) + 1); vector unsigned int tailmask; int i = 0, index = 0; // int d_elemsWritten = 0; const float *p1 = ss[1]+P->offset + i, *p2 = ss[1]+P->tmp0 + i; float *pst = P->dest + i; vector float lsq1, lsq2, x1, x2, xs, lsqz, zst; #define F2_STAGE1 x1 = vec_ld(0, p1); x2 = vec_ld(0, p2); i += 4; p1 += 4; p2 += 4; #define F2_STAGE2 xs = vec_add(x1, x2); // was vec_madd(xs, RECIP_TWO, ZERO); #define F2_STAGE3 zst = xs; #define F2_STAGE4 tempMaxV = vec_max(tempMaxV, zst); vec_st(zst, index, pst); pst += 4; // software pipelined main loop - omit last stage of tail element if (P->di-i >= 12) { F2_STAGE1; F2_STAGE2; F2_STAGE1; F2_STAGE3; F2_STAGE2; F2_STAGE1; while (i < P->di) { F2_STAGE4; F2_STAGE3; F2_STAGE2; F2_STAGE1; } F2_STAGE4; F2_STAGE3; F2_STAGE2; F2_STAGE4; F2_STAGE3; // F2_STAGE4; } else { // main loop while (i < P->di-4) { F2_STAGE1; F2_STAGE2; F2_STAGE3; F2_STAGE4; } F2_STAGE1; F2_STAGE2; F2_STAGE3; } #undef F2_STAGE1 #undef F2_STAGE2 #undef F2_STAGE3 #undef F2_STAGE4 tailmask = (vector unsigned int) vec_cmplt(tailelem, taillim); zst = vec_and(zst, (vector float) tailmask); tempMaxV = vec_max(tempMaxV, zst); vec_st(zst, index, pst); // take the maximum across max and maxV and return it tempMaxV = vec_max(tempMaxV, vec_sld(tempMaxV, tempMaxV, 8)); maxV = vec_max(tempMaxV, vec_sld(tempMaxV, tempMaxV, 4)); float *maxVp = (float *) &maxV; max = *maxVp; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return max; } /********************** * * foldArrayBy3 - Perform "folds" on 3 adjacent parts of the power over time * array. Each element in the "folded" array is the sum of the 3 elements * in the power over time array. * * Assumes 16-byte alignment of input and output arrays. * */ float foldArrayBy3SP(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("foldArrayBy3SP()"); #endif float max; int vEnd; vector float tempMaxV = ZERO, maxV; vector float msq2 = vec_ld(0, ss[0]+P->tmp0); vector float msq3 = vec_ld(0, ss[0]+P->tmp1); vector unsigned char mask2 = vec_add(vec_lvsl(-1L, ss[0]+P->tmp0), vec_splat_u8(1)); vector unsigned char mask3 = vec_add(vec_lvsl(-1L, ss[0]+P->tmp1), vec_splat_u8(1)); vector unsigned int tailelem = {0, 1, 2, 3}; vector unsigned int taillim = vec_uisplat(((P->di-1)&0x3) + 1); vector unsigned int tailmask; int i = 0; const float *p1 = ss[0], *p2 = ss[0]+P->tmp0, *p3 = ss[0]+P->tmp1; float *pst = P->dest; vector float lsq2, lsq3, x1, x2, x3, xs12, xs, z; #define F3_STAGE1 lsq2 = vec_ld(15, p2); i += 4; p2 += 4; x1 = vec_ld(0, p1); x2 = vec_perm(msq2, lsq2, mask2); lsq3 = vec_ld(15, p3); p1 += 4; msq2 = lsq2; p3 += 4; xs12 = vec_add(x1, x2); x3 = vec_perm(msq3, lsq3, mask3); msq3 = lsq3; #define F3_STAGE2 xs = vec_add(xs12, x3); // was vec_madd(xs, RECIP_THREE, ZERO); #define F3_STAGE3 z = xs; #define F3_STAGE4 tempMaxV = vec_max(tempMaxV, z); vec_st(z, 0, pst); pst += 4; // software pipelined main loop if (P->di-i >= 12) { F3_STAGE1; F3_STAGE2; F3_STAGE1; F3_STAGE3; F3_STAGE2; F3_STAGE1; while (i < P->di) { F3_STAGE4; F3_STAGE3; F3_STAGE2; F3_STAGE1; } F3_STAGE4; F3_STAGE3; F3_STAGE2; F3_STAGE4; F3_STAGE3; // F3_STAGE4; } else { // main loop while (i < P->di-4) { F3_STAGE1; F3_STAGE2; F3_STAGE3; F3_STAGE4; } F3_STAGE1; F3_STAGE2; F3_STAGE3; } #undef F3_STAGE1 #undef F3_STAGE2 #undef F3_STAGE3 #undef F3_STAGE4 tailmask = (vector unsigned int) vec_cmplt(tailelem, taillim); z = vec_and(z, (vector float) tailmask); tempMaxV = vec_max(tempMaxV, z); vec_st(z, 0, pst); // take the maximum across max and maxV and return it tempMaxV = vec_max(tempMaxV, vec_sld(tempMaxV, tempMaxV, 8)); maxV = vec_max(tempMaxV, vec_sld(tempMaxV, tempMaxV, 4)); float *maxVp = (float *) &maxV; max = *maxVp; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return max; } /********************** * * foldArrayBy4 - Perform "folds" on 4 adjacent parts of the power over time * array. Each element in the "folded" array is the sum of the 4 elements * in the power over time array. * * Assumes 16-byte alignment of input and output arrays. * */ float foldArrayBy4SP(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("foldArrayBy4SP()"); #endif float max; int vEnd; vector float tempMaxV = ZERO, maxV; vector float msq2 = vec_ld(0, ss[0]+P->tmp0); vector float msq3 = vec_ld(0, ss[0]+P->tmp1); vector float msq4 = vec_ld(0, ss[0]+P->tmp2); vector unsigned char mask2 = vec_add(vec_lvsl(-1L, ss[0]+P->tmp0), vec_splat_u8(1)); vector unsigned char mask3 = vec_add(vec_lvsl(-1L, ss[0]+P->tmp1), vec_splat_u8(1)); vector unsigned char mask4 = vec_add(vec_lvsl(-1L, ss[0]+P->tmp2), vec_splat_u8(1)); vector unsigned int tailelem = {0, 1, 2, 3}; vector unsigned int taillim = vec_uisplat(((P->di-1)&0x3) + 1); vector unsigned int tailmask; int i = 0; const float *p1 = ss[0], *p2 = ss[0]+P->tmp0, *p3 = ss[0]+P->tmp1, *p4 = ss[0]+P->tmp2; float *pst = P->dest; vector float lsq2, lsq3, lsq4, x1, x2, x3, x4, xs12, xs34, xs, z; #define F4_STAGE1 lsq2 = vec_ld(15, p2); lsq3 = vec_ld(15, p3); lsq4 = vec_ld(15, p4); i += 4; p2 += 4; p3 += 4; p4 += 4; x1 = vec_ld(0, p1); x2 = vec_perm(msq2, lsq2, mask2); x3 = vec_perm(msq3, lsq3, mask3); x4 = vec_perm(msq4, lsq4, mask4); p1 += 4; msq2 = lsq2; msq3 = lsq3; msq4 = lsq4; xs12 = vec_add(x1, x2); xs34 = vec_add(x3, x4); #define F4_STAGE2 xs = vec_add(xs12, xs34); // was vec_madd(xs, RECIP_FOUR, ZERO); #define F4_STAGE3 z = xs; #define F4_STAGE4 tempMaxV = vec_max(tempMaxV, z); vec_st(z, 0, pst); pst += 4; // software pipelined main loop if (P->di-i >= 12) { F4_STAGE1; F4_STAGE2; F4_STAGE1; F4_STAGE3; F4_STAGE2; F4_STAGE1; while (i < P->di) { F4_STAGE4; F4_STAGE3; F4_STAGE2; F4_STAGE1; } F4_STAGE4; F4_STAGE3; F4_STAGE2; F4_STAGE4; F4_STAGE3; // F4_STAGE4; } else { // main loop while (i < P->di-4) { F4_STAGE1; F4_STAGE2; F4_STAGE3; F4_STAGE4; } F4_STAGE1; F4_STAGE2; F4_STAGE3; } #undef F4_STAGE1 #undef F4_STAGE2 #undef F4_STAGE3 #undef F4_STAGE4 tailmask = (vector unsigned int) vec_cmplt(tailelem, taillim); z = vec_and(z, (vector float) tailmask); tempMaxV = vec_max(tempMaxV, z); vec_st(z, 0, pst); // take the maximum across max and maxV and return it tempMaxV = vec_max(tempMaxV, vec_sld(tempMaxV, tempMaxV, 8)); maxV = vec_max(tempMaxV, vec_sld(tempMaxV, tempMaxV, 4)); float *maxVp = (float *) &maxV; max = *maxVp; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return max; } /********************** * * foldArrayBy5 - Perform "folds" on 5 adjacent parts of the power over time * array. Each element in the "folded" array is the sum of the 5 elements * in the power over time array. * * Assumes 16-byte alignment of input and output arrays. * */ float foldArrayBy5SP(float *ss[], struct PoTPlan *P) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("foldArrayBy5SP()"); #endif float max; int vEnd; vector float tempMaxV = ZERO, maxV; vector float msq2 = vec_ld(0, ss[0]+P->tmp0); vector float msq3 = vec_ld(0, ss[0]+P->tmp1); vector float msq4 = vec_ld(0, ss[0]+P->tmp2); vector float msq5 = vec_ld(0, ss[0]+P->tmp3); vector unsigned char mask2 = vec_add(vec_lvsl(-1L, ss[0]+P->tmp0), vec_splat_u8(1)); vector unsigned char mask3 = vec_add(vec_lvsl(-1L, ss[0]+P->tmp1), vec_splat_u8(1)); vector unsigned char mask4 = vec_add(vec_lvsl(-1L, ss[0]+P->tmp2), vec_splat_u8(1)); vector unsigned char mask5 = vec_add(vec_lvsl(-1L, ss[0]+P->tmp3), vec_splat_u8(1)); vector unsigned int tailelem = {0, 1, 2, 3}; vector unsigned int taillim = vec_uisplat(((P->di-1)&0x3) + 1); vector unsigned int tailmask; int i = 0; const float *p1 = ss[0], *p2 = ss[0]+P->tmp0, *p3 = ss[0]+P->tmp1, *p4 = ss[0]+P->tmp2, *p5 = ss[0]+P->tmp3; float *pst = P->dest; vector float lsq2, lsq3, lsq4, lsq5, x1, x2, x3, x4, x5, xs12, xs34, xs345, xs, z; #define F5_STAGE1 lsq3 = vec_ld(15, p3); lsq4 = vec_ld(15, p4); i += 4; p3 += 4; p4 += 4; lsq2 = vec_ld(15, p2); x3 = vec_perm(msq3, lsq3, mask3); x4 = vec_perm(msq4, lsq4, mask4); lsq5 = vec_ld(15, p5); p2 += 4; msq3 = lsq3; msq4 = lsq4; p5 += 4; x1 = vec_ld(0, p1); x2 = vec_perm(msq2, lsq2, mask2); xs34 = vec_add(x3, x4); x5 = vec_perm(msq5, lsq5, mask5); p1 += 4; msq2 = lsq2; msq5 = lsq5; #define F5_STAGE2 xs12 = vec_add(x1, x2); xs345 = vec_add(xs34, x5); #define F5_STAGE3 xs = vec_add(xs12, xs345); // was vec_madd(xs, RECIP_FIVE, ZERO); #define F5_STAGE4 z = xs; #define F5_STAGE5 tempMaxV = vec_max(tempMaxV, z); vec_st(z, 0, pst); pst += 4; // software pipelined main loop if (P->di-i >= 16) { F5_STAGE1; F5_STAGE2; F5_STAGE1; F5_STAGE3; F5_STAGE2; F5_STAGE1; F5_STAGE4; F5_STAGE3; F5_STAGE2; F5_STAGE1; while (i < P->di) { F5_STAGE5; F5_STAGE4; F5_STAGE3; F5_STAGE2; F5_STAGE1; } F5_STAGE5; F5_STAGE4; F5_STAGE3; F5_STAGE2; F5_STAGE5; F5_STAGE4; F5_STAGE3; F5_STAGE5; F5_STAGE4; // F5_STAGE5; } else { // main loop while (i < P->di-4) { F5_STAGE1; F5_STAGE2; F5_STAGE3; F5_STAGE4; F5_STAGE5; } F5_STAGE1; F5_STAGE2; F5_STAGE3; F5_STAGE4; } #undef F5_STAGE1 #undef F5_STAGE2 #undef F5_STAGE3 #undef F5_STAGE4 #undef F5_STAGE5 tailmask = (vector unsigned int) vec_cmplt(tailelem, taillim); z = vec_and(z, (vector float) tailmask); tempMaxV = vec_max(tempMaxV, z); vec_st(z, 0, pst); // take the maximum across max and maxV and return it tempMaxV = vec_max(tempMaxV, vec_sld(tempMaxV, tempMaxV, 8)); maxV = vec_max(tempMaxV, vec_sld(tempMaxV, tempMaxV, 4)); float *maxVp = (float *) &maxV; max = *maxVp; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return max; } sum_func AKavTB3[FOLDTBLEN] = { foldArrayBy3SP }; sum_func AKavTB4[FOLDTBLEN] = { foldArrayBy4SP }; sum_func AKavTB5[FOLDTBLEN] = { foldArrayBy5SP }; sum_func AKavTB2[FOLDTBLEN] = { foldArrayBy2SPA }; sum_func AKavTB2AL[FOLDTBLEN] = { foldArrayBy2SPAL }; FoldSet AKavfold = {AKavTB3, AKavTB4, AKavTB5, AKavTB2, AKavTB2AL, "AK AltiVec"}; #endif boinc-app-seti_8.00~svn3701.orig/client/vector/sighandler.h0000644000175000017500000001274012321065336023570 0ustar locutuslocutus // Copyright (c) 1999-2006 Regents of the University of California // // FFTW: Copyright (c) 2003,2006 Matteo Frigo // Copyright (c) 2003,2006 Massachusets Institute of Technology // // fft8g.[cpp,h]: Copyright (c) 1995-2001 Takya Ooura // 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, 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; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions // as an alternative to FFTW and distribute a linked executable and // source code. You must obey the GNU General Public License in all // respects for all of the code used other than the FFT library itself. // Any modification required to support these libraries must be distributed // under the terms of this license. If you modify this program, you may extend // this exception to your version of the program, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. Please be aware that FFTW is not covered by this exception, // therefore you may not use FFTW in any derivative work so modified without // permission of the authors of FFTW. /* Module local signal handlers. Yes, all defined static, not extern because * we don't want to worry about signal handlers in one module clobbering * saved signal handlers in another module, and we don't want to invent a * stack of signal handlers. */ #ifndef SIGHANDLER_H #define SIGHANDLER_H #include #include #ifndef MAXSIG #ifdef NSIG #define MAXSIG (NSIG+1) #elif defined(__linux__) #define MAXSIG 64 #elif defined(SIGRTMAX) #define MAXSIG SIGRTMAX #elif defined(_SIGRTMAX) #define MAXSIG _SIGRTMAX #else #define MAXSIG 32 #endif #endif #if defined(HAVE_SIGJMP_BUF) static sigjmp_buf jb; #else static jmp_buf jb; #endif #if !defined(HAVE_SIGSETJMP) && !defined(sigsetjmp) #define sigsetjmp(x,y) setjmp(x) #endif #if !defined(HAVE_SIGLONGJMP) && !defined(siglongjmp) #define siglongjmp(x,y) longjmp(x,y) #endif static int sc; typedef void (*signal_handler)(int); #if defined(HAVE_SYSV_SIGNAL) #define signal(x,y) sysv_signal(x,y) #elif defined(HAVE_BSD_SIGNAL) #define signal(x,y) bsd_signal(x,y) #endif /* all our signal handler does is jump to a place we've set */ static void sighandler(int x) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("sighandler()"); #endif #if defined(HAVE_SIGACTION) sigset_t unblock; sigemptyset(&unblock); sigaddset(&unblock,x); sigprocmask(SIG_UNBLOCK,&unblock,NULL); #elif defined(HAVE_SYSV_SIGNAL) // SYSV resets the handler but keeps signal unblocked sysv_signal(x,sighandler); #elif defined(HAVE_BSD_SIGNAL) // BSD keeps the handler, but blocks the signal. // Nothing should need to be done here. #else // who knows which version of signal this is. // Do the safe thing. signal(x,sighandler); #endif sc++; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif siglongjmp(jb,1); } /* flags to mark whether we've been installed already */ static int installed[MAXSIG]; /* a place to save our the existing signal handlers */ #ifdef HAVE_SIGACTION static struct sigaction oldhandler[MAXSIG]; #else static signal_handler oldhandler[MAXSIG]; #endif /* these are the signals we'll handle */ static const int install_handler[]={ #ifdef SIGILL SIGILL, #endif #ifdef SIGPRIV SIGPRIV, #endif #ifdef SIGSEGV SIGSEGV, #endif #ifdef SIGBUS SIGBUS, #endif #ifdef SIGIOT SIGIOT, #endif #ifdef SIGABRT SIGABRT, #endif #ifdef SIGSTKFLT SIGSTKFLT, #endif 0 }; /* Keep these as stubs even if signal handling is not enabled */ static inline void install_sighandler() { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("install_sighandler()"); #endif #ifdef HAVE_SIGACTION struct sigaction new_action; new_action.sa_handler=sighandler; sigemptyset(&new_action.sa_mask); new_action.sa_flags=0; #endif int i=0,sig; while ((sig=install_handler[i])!=0) { if (!installed[sig]) { #ifdef HAVE_SIGACTION sigaction(sig,&new_action,oldhandler+sig); #else oldhandler[sig]=signal(sig,sighandler); #endif installed[sig]=1; } i++; } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } static inline void uninstall_sighandler() { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("install_sighandler()"); #endif /* Don't uninstall the windows signal handler! */ int i=0,sig; while ((sig=install_handler[i])!=0) { if (installed[sig]) { #ifdef HAVE_SIGACTION sigaction(sig,oldhandler+sig,NULL); #else signal(sig,oldhandler[sig]); #endif installed[sig]=0; } i++; } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } //static inline void reinstall_sighandler() { // uninstall_sighandler(); // install_sighandler(); //} #endif /* SIGHANDLER_H */ boinc-app-seti_8.00~svn3701.orig/client/vector/hires_timer.cpp0000644000175000017500000002064212175757576024342 0ustar locutuslocutus // Copyright (c) 1999-2006 Regents of the University of California // // FFTW: Copyright (c) 2003,2006 Matteo Frigo // Copyright (c) 2003,2006 Massachusets Institute of Technology // // fft8g.[cpp,h]: Copyright (c) 1995-2001 Takya Ooura // 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, 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; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions // as an alternative to FFTW and distribute a linked executable and // source code. You must obey the GNU General Public License in all // respects for all of the code used other than the FFT library itself. // Any modification required to support these libraries must be distributed // under the terms of this license. If you modify this program, you may extend // this exception to your version of the program, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. Please be aware that FFTW is not covered by this exception, // therefore you may not use FFTW in any derivative work so modified without // permission of the authors of FFTW. // // $Id: hires_timer.cpp,v 1.1.2.6 2006/09/07 00:26:56 korpela Exp $ #include "sighandler.h" #include "hires_timer.h" #include "diagnostics.h" #include #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_SYS_TIME_H #include #ifdef TIME_WITH_SYS_TIME #include #endif #else #include #endif #ifdef HAVE_MACH_MACH_TIME_H #include #endif #ifdef HAVE_SYS_PARAM_H #include #endif #ifdef HAVE_SYS_SYSTM_H #include #endif #ifdef HAVE_MACHINE_CPU_H #include #endif #if _MSC_VER >= 1400 #include "intrin.h" // include intrinsic assembly functions #endif #ifdef _WIN32 #include "windows.h" #endif #if defined(_WIN32) static inline tick_t fallback_ticks() { LARGE_INTEGER time; FILETIME sysTime; GetSystemTimeAsFileTime(&sysTime); time.LowPart = sysTime.dwLowDateTime; time.HighPart = sysTime.dwHighDateTime; return static_cast(time.QuadPart); } #elif defined(HAVE_GETTIMEOFDAY) static inline tick_t fallback_ticks() { struct timeval tp; gettimeofday(&tp,0); return static_cast(tp.tv_sec)*1000000+tp.tv_usec; } #else static inline tick_t fallback_ticks() { return static_cast(time(0)); } #endif #ifdef _WIN32 static inline tick_t get_ticks() { LARGE_INTEGER rv; QueryPerformanceCounter(&rv); return static_cast(rv.QuadPart); } #elif defined(HAVE_HRTIME_T) && defined(HAVE_GETHRTIME) static inline tick_t get_ticks() { return gethrtime(); } #elif defined(HAVE_MACH_ABSOLUTE_TIME) static inline tick_t get_ticks() { return mach_absolute_time(); } #elif defined(HAVE_GET_CYCLECOUNT) static inline tick_t get_ticks() { return get_cyclecount(); } #elif defined(HAVE_NANOTIME) static inline tick_t get_ticks() { struct timespec tsp; nanotime(&tsp); return static_cast(tsp.tv_sec)*static_cast(1000000000LL)+tsp.tv_nsec; } #elif defined(__GNUC__) && defined(__i386__) static inline tick_t get_ticks() { register tick_t rv; asm volatile ( "rdtsc" : "=A" (rv) ); return rv; } #elif defined(__GNUC__) && defined(__x86_64__) static inline tick_t get_ticks() { register tick_t rv; register unsigned int hi,lo; asm volatile ( "rdtsc" : "=a" (lo), "=d" (hi) : /* no inputs */ : /* no clobbers */ ); rv=(static_cast(hi)<<32)|lo; return rv; } #elif defined(__GNUC__) && (defined(__ia64) || defined (__ia64__)) static inline tick_t get_ticks() { register tick_t rv; asm volatile ( "mov %0=ar.itc" : "=r" (rv) : /* no inputs */ : /* no clobbers */ ); return rv; } #elif defined(__GNUC__) && defined(__sparc) static inline tick_t get_ticks() { register long lo; asm volatile ( #ifdef __sparcv9 "rd %%tick,%0" : "=r" (lo) #else ".long %1\n" "mov %%g1,%0\n" : "=r" (lo) : "i" (0x83410000) // rd %tick, %g1 #endif ); return static_cast(lo); } #elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__)) static inline tick_t get_ticks() { register tick_t rv; register unsigned int hi1,hi,lo; do { asm volatile ( "mftbu %0\n\t" "mftb %1\n\t" "mftbu %2\n\t" /* don't forget to check overflow */ : "=r" (hi), "=r" (lo), "=r" (hi1) ); } while (hi != hi1); rv=(static_cast(hi)<<32)|lo; return rv; } #elif _MSC_VER >= 1400 && (defined(_M_X64) || defined(_M_AMD64)) static inline tick_t get_ticks() { return __rdtsc(); } #elif defined(HAVE_CLOCK_GETTIME) #if defined(CLOCK_PROCESS_CPUTIME_ID) #define METHOD CLOCK_PROCESS_CPUTIME_ID #elif defined(CLOCK_MONOTONIC) #define METHOD CLOCK_MONOTONIC #elif defined(CLOCK_REALTIME) #define METHOD CLOCK_REALTIME #elif defined(CLOCK_SGI_CYCLE) #define METHOD CLOCK_SGI_CYCLE #endif static inline tick_t get_ticks() { struct timespec t; clock_gettime(METHOD, &t); return static_cast(t.tv_nsec)+static_cast(t.tv_sec)*static_cast(1000000000LL); } #elif defined(HAVE_MICROTIME) static inline tick_t get_ticks() { struct timeval tsp; microtime(&tsp); return static_cast(tsp.tv_sec)*static_cast(1000000LL)+tsp.tv_usec; } #else static inline tick_t get_ticks() { raise(SIGILL); return static_cast(0); } #endif hires_timer::hires_timer() : rollover(0),last_ticks(0),start_time(0.0) { if (period==0) { install_sighandler(); if (setjmp(jb)) { use_fallback=1; } else { ticks(); } uninstall_sighandler(); calibrate(); } } tick_t hires_timer::ticks() { if (use_fallback) { tick_t t=fallback_ticks(); if (t < last_ticks) { // Assume the rollover is a power of two tick_t this_rollover=2; unsigned long long u=last_ticks-t; while (u>>=1) this_rollover<<=1; rollover+=this_rollover; // unfortunately a rollover probably returns a // bogus elapsed time. } return (last_ticks=fallback_ticks()+rollover); } else { tick_t t=get_ticks(); if (t < last_ticks) { // Assume the rollover is a power of two tick_t this_rollover=2; unsigned long long u=last_ticks-t; while (u>>=1) this_rollover<<=1; rollover+=this_rollover; } return (last_ticks=get_ticks()+rollover); } } tick_t hires_timer::find_increment() { int i; tick_t delta=0; for (i=0;i<32;i++) { tick_t t1,t2=ticks(); while ((t1=ticks()) <= t2) ; /* do nothing */ delta+=(t1-t2); } return (delta/32); } second_t hires_timer::find_frequency() { time_t t1,t2=time(0); tick_t start,fin; // Beware time resets. while ((t1=time(0)) <= t2) ; /* do nothing */ start=ticks(); while ((t2=time(0)) <= t1) ; /* do nothing */ fin=ticks(); return static_cast(fin-start)/(t2-t1); } void hires_timer::calibrate() { double freq=find_frequency(); if (freq<=0) freq=find_frequency(); /* in case it rolled over */ BOINCASSERT(freq > 0); period=1.0/freq; ticks_min_incr=find_increment(); increment=period*ticks_min_incr; if (increment < 1e-6) { increment=1e-6; ticks_min_incr=static_cast(floor((second_t)increment/period+0.5)); } } second_t hires_timer::period; tick_t hires_timer::ticks_min_incr; second_t hires_timer::increment; int hires_timer::use_fallback; #ifdef TEST_TIMER #include int main(void) { hires_timer t; t.start(); printf("frequency:%f resolution:%f seconds:%f\n",t.frequency(),t.resolution(),t.seconds()); while (t.elapsed() < t.resolution()) ; printf("%f elapsed\n",t.stop()); return 0; } #endif boinc-app-seti_8.00~svn3701.orig/client/vector/x86_float4.cpp0000644000175000017500000000554211566257502023713 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // $Id: x86_float4.cpp,v 1.1.2.5 2007/07/16 15:36:56 korpela Exp $ // // This file is empty is __i386__ is not defined #include "sah_config.h" #include "math.h" #include "limits.h" #include "x86_ops.h" #include "x86_float4.h" #if defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_AMD64) // polynomial coefficients for sine / cosine approximation in the chirp routine const_float4 SS4F(-0.0046075748); const_float4 CC3F(-0.0204391631); const_float4 SS3F(0.0796819754); const_float4 CC2F(0.2536086171); const_float4 SS2F(-0.645963615); const_float4 CC1F(-1.2336977925); const_float4 SS1F(1.5707963235); const_float4 ONE(1.0); const_float4 TWO(2.0); const_float4 SS1(1.5707963268); const_float4 SS2(-0.6466386396); const_float4 SS3(0.0679105987); const_float4 SS4(-0.0011573807); const_float4 CC1(-1.2341299769); const_float4 CC2(0.2465220241); const_float4 CC3(-0.0123926179); const_float4 ZERO(0.0); const_float4 THREE(3.0); const_float4 RECIP_TWO(0.5); const_float4 RECIP_THREE(1.0 / 3.0); const_float4 RECIP_FOUR(0.25); const_float4 RECIP_FIVE(0.2); const_float4 RECIP_PI(1.0/M_PI); const_float4 RECIP_TWOPI(0.5/M_PI); const_float4 RECIP_HALFPI(2.0/M_PI); const_float4 PI(M_PI); const_float4 TWOPI(2.0*M_PI); const_float4 HALFPI(0.5*M_PI); const_float4 R_NEG(-1,1,-1,1); // 2^23 (used by round()) const_float4 TWO_TO_23(8388608.0); const_float4 INDGEN[]={const_float4(1,2,3,4),const_float4(5,6,7,8)}; #endif boinc-app-seti_8.00~svn3701.orig/client/vector/analyzeFuncs_mmx.cpp0000644000175000017500000000573012313644616025334 0ustar locutuslocutus/****************** * * opt_mmx.cpp * * Description: Intel & AMD MMX optimized functions * CPUs: Intel Pentium II and beyond, AMD K6 - and beyond * */ // Copyright 2006 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "x86_ops.h" typedef __m64 MMX; #define s_begin() _mm_empty() #define s_end() _mm_empty() #define s_get64( ptr ) *( (MMX *) (ptr) ) #define s_put64( ptr, aa ) ( *((MMX *) (ptr)) = aa ) #define s_put64nc _mm_stream_pi // // // void __fastcall copy_MMX(char *dest, const char *src, int blocks) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("copy_MMX()"); #endif MMX m0,m1,m2,m3,m4,m5,m6,m7; MMX *m_src = (MMX *)src; MMX *m_dst = (MMX *)dest; s_begin(); while( blocks-- ) { m0 = s_get64( m_src + 0 ); m1 = s_get64( m_src + 1 ); m2 = s_get64( m_src + 2 ); m3 = s_get64( m_src + 3 ); m4 = s_get64( m_src + 4 ); m5 = s_get64( m_src + 5 ); m6 = s_get64( m_src + 6 ); m7 = s_get64( m_src + 7 ); m_src += 8; s_put64( m_dst + 0, m0 ); s_put64( m_dst + 1, m1 ); s_put64( m_dst + 2, m2 ); s_put64( m_dst + 3, m3 ); s_put64( m_dst + 4, m4 ); s_put64( m_dst + 5, m5 ); s_put64( m_dst + 6, m6 ); s_put64( m_dst + 7, m7 ); m_dst += 8; } s_end(); #ifdef USE_MANUAL_CALLSTACK call_stack.end(); #endif } // // copyMMXnt - Use Non temporal writes, // only available with 3DNow+ and SSE+ - Athlon and Pentium III // void __fastcall copy_MMXnt(char *dest, const char *src, int blocks) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("copy_MMXnt()"); #endif MMX m0,m1,m2,m3,m4,m5,m6,m7; MMX *m_src = (MMX *)src; MMX *m_dst = (MMX *)dest; s_begin(); while( blocks-- ) { s_fetch( m_src + 16 ); m0 = s_get64( m_src + 0 ); m1 = s_get64( m_src + 1 ); m2 = s_get64( m_src + 2 ); m3 = s_get64( m_src + 3 ); m4 = s_get64( m_src + 4 ); m5 = s_get64( m_src + 5 ); m6 = s_get64( m_src + 6 ); m7 = s_get64( m_src + 7 ); m_src += 8; s_put64nc( m_dst + 0, m0 ); s_put64nc( m_dst + 1, m1 ); s_put64nc( m_dst + 2, m2 ); s_put64nc( m_dst + 3, m3 ); s_put64nc( m_dst + 4, m4 ); s_put64nc( m_dst + 5, m5 ); s_put64nc( m_dst + 6, m6 ); s_put64nc( m_dst + 7, m7 ); m_dst += 8; } s_end(); s_fence_writes(); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } boinc-app-seti_8.00~svn3701.orig/client/vector/hires_timer.h0000644000175000017500000000701612175757576024007 0ustar locutuslocutus // Copyright (c) 1999-2006 Regents of the University of California // // FFTW: Copyright (c) 2003,2006 Matteo Frigo // Copyright (c) 2003,2006 Massachusets Institute of Technology // // fft8g.[cpp,h]: Copyright (c) 1995-2001 Takya Ooura // 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, 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; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions // as an alternative to FFTW and distribute a linked executable and // source code. You must obey the GNU General Public License in all // respects for all of the code used other than the FFT library itself. // Any modification required to support these libraries must be distributed // under the terms of this license. If you modify this program, you may extend // this exception to your version of the program, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. Please be aware that FFTW is not covered by this exception, // therefore you may not use FFTW in any derivative work so modified without // permission of the authors of FFTW. // $Id: hires_timer.h,v 1.1.2.4 2006/12/14 22:22:00 korpela Exp $ // #include "sah_config.h" #include #ifdef HAVE_INTTYPES_H #include #endif #ifdef HAVE_STDINT_H #include #endif #ifdef HAVE_SYS_TIME_H #include #ifdef TIME_WITH_SYS_TIME #include #endif #else #include #endif #if defined(HAVE_HRTIME_T) && defined(HAVE_GETHRTIME) typedef hrtime_t tick_t; #elif defined(HAVE_INT_FAST64_T) typedef int_fast64_t tick_t; #elif defined(HAVE_INT64_T) typedef int64_t tick_t; #elif defined(HAVE__INT64) typedef _int64 tick_t; #elif defined(HAVE_LONG_LONG) typedef long long tick_t; #else typedef double tick_t; #endif typedef double second_t; class hires_timer { public: hires_timer(); tick_t ticks(); // current time value in ticks tick_t delta() const {return ticks_min_incr;}; inline second_t seconds() {return (second_t)(ticks()*period);}; inline second_t frequency() const {return 1.0/period;}; inline second_t resolution() const {return (second_t)ticks_min_incr*period;}; inline second_t start() { register second_t tmp=seconds(); do { start_time=seconds(); } while ((start_time-tmp) #include #if defined(__arm__) && defined(__VFP_FP__) && !defined(__SOFTFP__) || defined(__aarch64__) #define INVALID_CHIRP 2e+20 #include "analyzeFuncs.h" #include "analyzeFuncs_vector.h" #include "analyzePoT.h" #include "analyzeReport.h" #include "gaussfit.h" #include "s_util.h" #include "diagnostics.h" #include "asmlib.h" #include "pulsefind.h" #include "fp_arm.h" template inline void v_pfsubTranspose(float *in, float *out, int xline, int yline) { // Transpose an X by X subsection of a XLINE by YLINE matrix into the // appropriate part of a YLINE by XLINE matrix. "IN" points to the first // (lowest address) element of the input submatrix. "OUT" points to the // first (lowest address) element of the output submatrix. #ifdef USE_MANUAL_CALLSTACK static char name[64]; if (name[0]==0) sprintf(name,"v_pfsubTranspose<%d>()",x); call_stack.enter(name); #endif int i,j; float *p; register float tmp[x*x]; for (j=0;j(in+j*x+i,out+y*i+j,x,y); } for (;i(in+j*x+i,out+y*i+j,x,y); } for (;i(in+j*x+i,out+y*i+j,x,y); } for (;i(in+j*x+i,out+y*i+j,x,y); } for (;i(in+j*x+i,out+y*i+j,x,y); } for (;i(in+j*x+i,out+y*i+j,x,y); } for (;i(in+j*x+i,out+y*i+j,x,y); } for (;i(in+j*x+i,out+y*i+j,x,y); } for (;i(in+j*x+i,out+y*i+j,x,y); } for (;i(in+j*x+i,out+y*i+j,x,y); } for (;iu%<ß^/?PKN4ai  asmlib.txtYrHw  f*g kdov艤t -;j!acݭZU8}X.f|bG\b7x;e&4Vvl]f"Re-fΓ-[{9\oۭyO+i@EEڰ֊ b'<[|)JnLy"RYѺLHF`>d."^@,Yl5@m%^"EëQ-T=0$V)iCë~B' 9 {siYp[""&H9rv+V c6bMfZ. be&5N*ْ"5vv`B"7)-on~srg O!LKy,U3БxC_:3'7]\_35]D-d"<) &Y 0~pΘZX#Fw .~tBJفϊX齝ӺD5IdZd0|̬+nA {dws1C:>U[{A,rcъhUV=3Q9VT`)ќAEIh;:W'[GȪp8d7"$u(hϩN^T&^.}^e0JeIyL%/RVPi!9ڭ xny"#= !ˬp ? r'MS'Pca"-sg7*4a:c'W'ղ_$bX`ۭ3Wu28R1_beE:'S1H,aG ЮUxRVrGu]› g•2"F! EA>,pQתX,xX#E^5hrfH ~(ep^%TN4r[zj ;]<aMh/=bV }0RXD3M$\RuD(;f~+1 *ns[ sƓ-G;0uGWa v`R^*YY#Q fQyCkv!`s*|(=R?Fg])0hQtZ2|^-r6EeIr0HXTӁRR@&xROMw*4F{(D3I^hM2a14׎7.0_0x{g4QaI(vb}bWo]%n_f~.cMl;ux0_UgfUY3;szRKDIKؒ#l5c:i FyS uG'"Tf"Bp(J9tq˖fiplK\5(o9NwH.3ƩF#coX.[ T==Wvuy:ǩɳW*x榸 ~EIy:[bu:\WILoxp>˴j3`cߞu-~9BXo8\U.ZeG. |{%8@ cxp` `G.g:; @ jKIP$i=;˥#3T_WC|=Qݐ"698ZzvW:M\Sz)l<NX/O3*4dvQeEmxaRUJFI! 5+R֞xZ0/P5x.G}D摹!IiZC Z^ϥA׃.I U #-;ъkY}:_]KSmϷBN'jHVM.q^ߔT3X۔BA2m 8RڟpO L~ k1kpHD`2fc0ac>Wa\еA7RK:i%cWӼ0l8Iy (qΥ_ĂYrAi4 zł ^r5iS1*ZL92Dt{d-il\K'LlKLytZ9Ɔp^v;n=Hbٝ 4}7ۿA ? /{C4n5%+!B$(*г 5"Yx5F ڭWn!,Rv^.8C}0s~grg{@c <}j`wGDDH`\>%/6a) ~A_SEhv@o@wE_gٽIos zR{ܟ\o]_6z햦m^B'qu ^D\qbA,Dp6R6M+>k&(8>#\@nQA;u0dLhTtq,I*J^[PK=2aFo asmlibe.aY]lU>mwuĢa!2-Xhj(TZXEV.ٝ*&5lS 1> jR_xjxD]@ <`cBQ;3{v6; $3~9s=7wuXȆՂ<Fx}>A,^R^(7ehcnxjR;LS, ض@[ua9b{=.aZuH}'bw[ W79^)ԾPjͿ+ aV;!RG|4V^MZ8IƲW㛷nl1A۵J=/{SgZə׼饤p; 'p;x(҉SWn]Ot8܌MNa9=nK/p>P.uCbj>m.Nxij(_b߻$2"eɮQ/!yYcn叮$T{]o3(=.9[okڦ~Bjz~ 5tN*P_K)J8gC*IUzZƆBkzWo㨔{ӈ|o$fW{sC/;n2Ef{ޅA>T"l " xBco Nޡ\9iڷ\i} ~u= j^56ncx,,߱Bh 6Cᘰ'cb5>䅊mrrL+djr sPN-[Z6S9֯3q5 \kj= 砰Zŋ6c5'smQ/hZ0%o\֎)6EB)j(ə?Dn?P'&9X#;Q5HjtXor.X▭xqJ&wzE~=t=/yZ;j_Vf9׊ҖOY he{Ee=(cB.S-cOE&XmXz}vc?PK=2$C asmlibm.libXoLSW?-m(,Oٜ>h  * V05,h/˲37f"2".q}a\޹w;ח6߲mtjK~>[]l(*Um͜lRfmikN ky 8o4b(S|n9E[\8\oq;$Y 4Fr7O}JvG[~Mj"AOx,Oara6j6™F`mO `̴:3çÇ[\f9Y`#:ec/")!W.AzCa[yȑjt=:Y<%tLׇ[O)y\N8{(/b|y֣Ld QV5wP~>Wj. zOvӟ cpGw⏶Won$oge3cJVcIQDr$Dz^jr,`zQ球8ݻ53jhBo鸅geϢ'4qi7={;&{$ݷ. y0DUCB $,ugv ?;/59ouZ=3Xa)rFYT( hV=i5'4x ݛ&|άD9wׁNý*(y9go nЉ{YACNsja?/uvSq%;Q8'h%dcR236VH,rsZYG-X,t1u Ec(Eyy낼#ƐȢhߏdXȮ@%/ } Mx.&#%~bl fW8@+&2JDqoaMjS>,|vH9C8gbVJ$S9s;"LQeR֦Uhա)Ql09ʾ@V)S$YN8U|$1'Dm>*EBE8DŽ N'[)1ga?0JSLhnA5xM9ixRp=QN9T41ޢe b()ЗĄ|z~2/gT!d 7W״E\, O1 ǿ2FK+_I:)s 8(En v܀3φzV"U.#O<8d9uGZ$(ܠe ƳHRݥnne&<͛yp׷K'Lxz\ƒm@˃ i#dE'M,оzv3)@9CM9HA5EP 'GD=5s:6JMλ~c~;1қT㏬\8$#Kge; 1 ~ 0ƀTqd15بsK !A *9K[Xo+lJ/:%(z &0/ʦkEEF`(M*&kC˗2)U{IíeD`E>Lg+>fTLlďWs~jxE)kWID'O+p,mu>ojT.V1Vr})-&违G@b`VO((ME} XnWw`[  -\|`(# ?./?KW\?1y,3/PK=2#X[F asmlibo.libVolSU?[ ˆـ4dG-t,3V54loq.uaq1e"$i(1T3DXHX﹯:{;}~!@*njWX7pR@2v*iW;&qB|I0:ߎ@z .w{A` E|Oe`蜋u'½~Ò:< 5Yeh],D(4f =xQ;:g1~~ 6e3ÌtsBhQ-cl\%ScTT⪳E~`C\x!Qt-J~'Tq'όb۷ovå=~.>/mmGKm`ozhl`~i]MR$WۥaqWݔЮX.Qþ`5:S_ 9DXIhXF8Oh7@Dq '՝pޟwȊ{/p$*"NnMhM\sMs/l~9$]$iيt1<Ƴ/W#5f$?k WD}#Sϯs5Z,%DEN[jzJQe;s;=d3TѧK"xCZ}TYSqY}T%"@%1B$"(=2S1%2ҍAV TD YqBDF^jfN\nwPQuZuO~ $-fTr@G zR 5Bčb9Iisw:EJj`>ˉ5u/)yߏi~K)%8UԊqSeD^V cGJxs(HCY 4/VuȪ?Ȫ4_3bFgW*qv(<IYD\BY,  t 6v]_9D$~0| K]WOb b v~#$U \DR̨*3 th $4O6Vb6ͯQWj1k߲O:dD6 ؑ ElTa\y yjbtuU 6"O*Es˺t7&fM =-nHlt8SboPi׌^A"Y_żSZkч=U2W?7;85 ;ͫu68%Ur6g[`eN9>Gaws9橾@+2{z?1u!7,;2[gW H?%c,7o~ (UgM+gdATu=W Qf ֬Mzʇ5 (Lrz,F>¬jwj;M/ۏPKM[)0]ɿiq cpuid.asm9sgu6\Oe녉(߹)fwUpH^{Gvk?xp7fW1vol։gA?8@hju ws3cV~7wo_ Bb}/tkdrk08 -ҧ;c! --y%O|1S̟-j$,9ց8@0~Po0-`]o[5]f?Ǐc>bh~l H``m_p keeS4%x YDo>Ӡ.TqOOWe+Om¼g eٰa18A@Tq kч9ڟXX-!'ri+ٿOptcAC(wyYAV6hMh>!Bw90ShFZLOT}La](- WfM'bab ?Tyi9HTϔ HYm\/~^j 0EE?AYop:,py歌m4Uv6>DjwAm}|Uk$&aBhEI$=uͦlq1C̛vS,7\>/RBdͰS,Nu4vi إO ¤RVgنQG+S4A)*ۗՋsR -SzD\e+RHދ}{Hv}=JFc5,pږ=*CvեrHݜu';ٌ:|·lkq;^wtʌ/< ʇc9cZ!F}ٙ]!w0{ pt V!B2fBg4,NAAPI|!uG Bܦ=!HrFEe,U،/-/ NnFfb!ycyޣ3\@8#;ne$Ef|}/B_J59f*} b2Q`=G}4VdM΁EppBX\)ԕqE ?J7]ث^`!Ϟg%nRS)ıpELENRH*RQ ҁbftn3u 68c"ݜcH;@ŵo/XǕ,A$u Mwp63)M{WrG5rikS 鲖+Q.Ev(Sٍjuv^U j,7Yiu{Rޫ頟<F}(N(bɧ N$GvLfYF_䱦%h2:8`=kZJI®E % b'R[sUR.`6R*h֘GnHqpJo~d4;ɦc e#^&,(YOMyĦN(^̽󲛷tF 8!?*j7iSKcH@weLt. эI&po|OViT pl( #꒸s ~_R[OrS%RTNT4_@5d`׫E $/:xHgfqz}#"v+W(KlKgI>瞔0 fEO^='v,]zdPGb/Z}_Fq"9^x;2_ADњ%RޒY*,M!ӤFj VY*JjX-8ݝk %46_<OL ?A;R|eHEYڕPAZG`Y`eg* 0ہM9A_Gϴ7Ξi3mn֯o!N˾Kߌ}i>W4SXW$9hS iprrd*)V(І¨LEmHnyڈl[-mnśf͛ ԮyV '(5iT*S?Th"DdBԠڲ7 Jf":A orYTn ,Zn.4z8XM!8S qk@\d i(Ehu9B0 tFqh´=]4,9~-ص5}e*ꔱae۩r+ص-"d:]oʜKnWg\ b65$ mƗωIZ>`K`|c)S'uhUAf@2?B#޾+#c5#/Ғz-UVZi^w>gNWMrVch "dW*.ӣl-?F6)%˶|Av|P$FEf8DfѲ.sr˻|V$|/I=`B i8 r]i-==r7u@j@:1MP+y>+Hɤ{GXO7v=B4.[wD;Ac) Ci,bjawjf6iȔ@JL*Te8֙R9p M_5B{D֫}j?FyŠ𥕱*X~%aygͳ$26~֌%,ÈmZ af"501]>%SɊ@nS-WGpaW$`[F/Y*cJy3,$ITm~e lO{rP5SIRe$VX/=|0}pf( JBuRY9*B@4`?D*Q-쯰!()ۙ>U6^hsed o&_JF a|Wxۄ8̸ŷ"1%~QAiQc-ǜclyɯ~yM9,<:s9sTQQR8pa m#,;UVE@[p^J}4@*O-I4c+e/$3 8AYeBX^0:F'M#⫌-JQ)Lw6s]_]~S*{ys%70G̳`ƒ0VQrsV;1˜&(@ n gzT_7NTŜT?}G V}J#Ô ۵zW1K݅N28G]cm#J~6 i8{mm_$XOtXXk2wT8lǕ±al{ՃW-{il7BxIUz&.'Źw8K͕zِ-[CJ\$º 86FD|.@`+sИ(pMqT4ä0&Vw]YMwwȡDh zk7iP*"B;f])7$d|O U| t f]+!JX|l:qקًȦwl5"v-޷ێ4ϛX3ɧx67&f)=}A<&? sX2C+Q ]ۋ͉1:ݘTbkEA1 )/xp"66-+?UNQlqrO /d}~@G^M/b<0 ,v0+TSbTY0móGvE5?-\(|E7Vj^Ak]Ro&{r!L]:wSVqykY) ex`sRnt-< ~ IoTxȥTLP%W{%4QSlt*wZ xHCP!ɨ/ Yu Y & =J6tk 'ECA=GQtj)esr re/5;ldYl6R*Y{vPKa*0cjJ cpuid.comX}l[W6n:imZEUbM,m3M6{uq{m3&4 R TIkZHSM!*U \AT&u&U޽>'}09Birn0"^rVGsld87d2aer~&a9]_L?!)ٞ9ё;&&ߒ;(ޒYh yAJx8)rijKۘIN\ޢ$8vv5G^ kn{ dl*&Hbrķtduk_}r "S@XoK[,9$!۵zoȊM2w+$љJp& #勄M@ۡM tb-K3(S'3 $gV#lQl{ݍnx3(щ œtRK-'|. 4N D%~my3D4<ԑ9+&cT{dp}u2o͟K>VW6hJ1e_%7% YƉ.REdV/kcz -KQ6[ԣ?F$\NUS _ꇌ5rb;gI}I* izISЫd+]emB_NIm߫l>o`k|̛{aMvӨZK:M#+%ڼji-Hd-jK_eEe咭Lm <6cxZ ~Zme\XV/k"׭[5˯:snI.|G_o2M󴲑غƌoklj<>C^J|}F+WLhUkPZ=ei(Zۂnj_Z9`ձzfXmo)c3Krod  z{"BDIđy_PBDVX@Ĉ79LLRz)FUɅx/ 71Qx)/|Q> !%>$ uP8\5-s>w) z0 cbhB!H`  0 ">;:J_C%e ~DF2EBCaυתh/`%&1E: ) +?\CJbeQ2/ ؈?W&;зL ?P@fX4¶7"~HSx.Xb}BøPQήɒGGs@C|Dnvb^/-P,ǢQQR`V^'*t!Š;S| 8J"*t@{k~&&;Or;Ӂ" 6xO.;>)\9îT`({_ۄ C@-=/ ?2C@@4U3YΌ"|ņ3c[3 (B5 BfI<hwUh'!o~^G[Uݮq6嫼(%rWW_=U.Iޢ] JAl;Z}Ou A(9PK=2cW , detectpr.asmZr۶&֒"Ɋ"'m]jO#[rZt2$$!HK-. K)DZ{_|tNtv;.o:բfX>&` wvu{xp?v v=Fl w]m]{KhH":ȚGa1`#n3!`%MD}$g[)Lu"T߶ܘA6`ajJpӧr>xxːU2}g@]ZpE%J`qTYQOpbo -1 CGɛ,k&d25`C4VT($2NuWgU&; P,mPw)p\^U|IIأ*%灂O12ԑSIrʆd;dnm=0x4$t@@ TR!oy(7̀k CNwd/> d,M_o( :~D`3&!n(,ofy|M|oSY5LĔ6kQ<5X+ąY(&:NIXقd;B~.N ĤF̷\ύWbX4$ LY(-$SV1yd@L`!5`I52PRpB9G<| 2q-#P;d:-ė^[S#^$0wnסm^|o't0⿿Dё>P&\Rf,:d Mu4Ag8o\HP3<(mA5YbdG" "}IAO\TR<$\AbhTTڴÃt:u03s}RF1G1"j̱`MD ȋ ,K>/|w)DWx~-P%fkkK pqL.: / jżݠީ$<#d <F=Vx-)Y.w-K̡ f>L[-2M"hKE C:``jk(A1Y5-ØFGy\#kHGQ FЀAE~,Eک:Y,&?ƣfk ّVzqYf A]]ZCt2:_&V_gq3Vf Sѥ ~38QN9@[(/6: L-'\9-Bfk%]™FkJ \}tadz'5xiS{TsA7r5ZxrB=esN>@_a;O`}i{`-ɬ}KּtTx_>;ɴ*/-@pLE֎*F1oY]'RLn" 0h#|^-2D7b5b T,?t hyzc}U շuHsN6,&A[*` *v0izZ2^orYlZ@xUnБMluZnc;jVh5%~WaI{`ך 3Bͻ'Ga&LH7ó @Zx|o9lcm(ew6ՠL^Y0Vis]Wy O2P@j"m~!L;X+2[ |]M!i;SX9<8@!L;9ִn[#ɴQήn/翏߽ 8'w|UlѠ;:=uSw#OO%[v1\ؓ斴lBh9#[U_/@ۘ_O֧ݟt3zKO1ӯ'nѽ7ܩEJ\w,} ` aMN䑏^F_M:"G7VQL1f7ʬ2 l ؙ7k⪹xUzJ%0^Cvׅإc$ N{)@z;苂1[Nml~;3~W{f:WU-SF M`d0\it0~xϹ$a)fWی>#œMw\H0?>zɣ>z9\BU٤݉)mkuYW]xr=*D <|*hQ@Lb6fŮҝNI-o~+Ts{ g|^.g)I d"ՒEntY[In􂤼#~_ce@v b ٭Qq>+hIn ɲV5$|uYcN2ȍre Xb8 v[HDP^*nn-R -IL_Z7ȮrG P-Ȳإ稣^w^Wqz}lZa?>(9GNg:1?d[k0f [HЧj ͨLHE.x;m2 [;  v+5D 0f(c! X|Hbűd*J8@(Ýə.gVi՘8u\v˞?:1 i4 @Jcy26[_7%v+C_f^V>Ytj% <[UL!w(*^GF ҕwGT=9LR[:^vF(Ւi+a>)vaכhˮ_Na3A4T+BT3Nk('o8nğ<_e}wSǧa1GL8 3J$ioKgjU:lRE;,B;IʸXe]\M\e7KUިn1 wx,3&ATq!naDp1(p)SJ4PcuߞSR6IBޯS8\X'Hi @c_d#.%PKV0Kd'makefileTO0~G8 `%inlxFNion]mw4PдJ}w/oo͞cG/ygKaG0fO<)DiHL3@ % d, $0cx6K729ٜSt5]hk.xddG{z2uYJx)7G1eDJZŰ7b2vgH-$Zed>Nz2V+fc, ]XDZX@2Glm6ʕ)+]O#!\s< VH'7#(f /z2KU;X :khGFǠxy!Gv};6VnBDr;jNf[dBfl-s+hQ091U1ѢdmvU|LEs*hU:7Bα`4g ˻u.amYeK"[glɪEmm;'ESp=BW6l{n&?+bmb#QKըeف}?UU*_ϔ7u봸NT|j!^%4Ŕ+zVØqc ]"|͋Z||pM01eEjNbÆˀ O^|@PBA"C ak> f _T^"vyv݁:6M_{_+jDv Wi|-vPKZ0}% minmaxd.asmV[o6~7p'{1T'Ȃ.d";P-Q27T):v/{HI6Kj]swϧ6l;әp脜J!\4J҆n3(&/yV#dɇuDBőv\tu3> "V㩒)U-%߀^z >UN̂'4`iip:#)x.aD!)FgC ,X%ف8 1,B[YjJsP]W΅~DA-(=6rkVtd6u(ɤ^KŦn)N7MHr~|()_<(Ƽęx.ZkaYǜQgE4ڕ*|ꋬn nEܫ+-dRN=D|H $"D@ TIH=1T3)+C|Lp﷬̙F_öPjJn2sLP*~.ƞFp#eX@P`A_ Ue^NDkyr@tL_A氧[axQRi &&KJiJD"AG ԮH63U9թ݁Uu+d_9hgԞB m7aS}0śdHW0qJfYU0YѼ m,M,ˏ9~}RwIzlswZ7#Q!gVgPK[0 minmaxi.objkeMK,e&b8ΐxb``fe|?)i*##kof' O %  ;X1^\¡}p!惇/Efu110PK2\1we]S rdtsc.asmTn0 ;=mkm)s"@i EmdHr6NvE~$?ح}Lkkp>^{oY< )Xk%9J!4MNϸ 3W*)|d4Ѿ)KK#PATI`>MWw0g:W(D@ɸ5 |:YFVUKF{o{QlM52_`jr&e`L@ *k  n5"dqwq7!S~S9FFlNd_ "Ƌ D/7 QчyJPK{Z0 round.asmRMo0  zږ-(Stŀ^aP$&$Oeu0,{^"_oWlu ҢTx4w-!M3Z½hB۶Yi|y!=,ELV$暿5)4PS'-,g| KaKj%j)Bz;IIK/RgCf `)PJm8|YA!BLZ Aa!v+R5"dqwq7!!~S1FF I 0ƽE0020uQai~r[F%plC PKZ0/ D truncate.asmVmoFݧ$'ZQi+hή Wu?x30˧xL E)jW^_u;q< Y :>KAv(JG1]Mb==IBD !u*[L@=9R+z"rwKf`6/0cia ZA4Dr+yay`}a7Qb&zRj\v&3xLP4ek]_]AUD e eBwlaJP3\ cŬKCd'kU[P@<U;Q9o33֡ln,푈(A.̾Cy2h`.* Tp!3F{=aT&CWTW\R*HAoSg[9R݃ʩ9G{@|&4 \a>-~<W9ǗPpES 6Lj2jHd^~)'w"';Bs6kZc| 9_׊aQ ldవֈ[#پ_dWw%sn}g05F?GsA]qLt%6j4ٗ-}a,˭Ȭn¾h򵗤mr&c> LKF(T(uRxz>ɢ"S{0*lZF%=?LdAY͸ B! W*jEn\?gt6D37--Y$ga52J2h)b\?Zτ(|*Qiepmz]揚WUyl)96{O LR}z4<V04 ;imqb~gz&JMX_}vլ7r/Cǥ^ύO?収!n_PK[0P truncate.objkc))*KN,IK,Ν8M151đ5>5"dqwq7!3q.~SR4Gf^qIQqj 'U\ 3Ff[K '~>C] m!*,TTnƨpDDFj< O^ m7+IX%PPKW06cœ asmlib.hPKN4ai   asmlib.txtPK=2aFo asmlibe.aPK=2$C casmlibm.libPK=2#X[F asmlibo.libPKM[)0]ɿiq  cpuid.asmPKa*0cjJ ;cpuid.comPK=2cW , jDdetectpr.asmPK=2?|;! Qdetectpr.objPK`0 6Tinstrset.asmPK`0b - Zinstrset.objPKV0Kd'T\makefilePKZ0}% Y_minmaxd.asmPK[0/;  cminmaxd.objPKZ0X dminmaxi.asmPK[0 fminmaxi.objPK2\1we]S grdtsc.asmPKP\1z~ 8jrdtsc.objPK{Z0 jround.asmPK[0i8v lround.objPKZ0/ D mtruncate.asmPK[0P ~qtruncate.objPKrboinc-app-seti_8.00~svn3701.orig/client/vector/analyzeFuncs_sse2.cpp0000644000175000017500000002450112313644616025404 0ustar locutuslocutus/****************** * * analyzeFuncs_SSE2.cpp * * Description: Intel & AMD SSE2 optimzized functions * CPUs: Intel Pentium IV, AMD Athlon Model 6+, AMD Athlon 64 */ // Copyright 2007 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "sah_config.h" // The following is empty if USE_INTRINSICS is not defined #ifdef USE_INTRINSICS #include #include #include #include "s_util.h" #include "x86_float4.h" #include "analyzeFuncs_vector.h" #include "analyzeFuncs.h" __inline __m128 vec_recip2(__m128 v) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("vec_recip2()"); #endif // obtain estimate __m128 estimate = _mm_rcp_ps( v ); // one round of Newton-Raphson __m128 rv=_mm_add_ps(_mm_mul_ps(_mm_sub_ps(ONE, _mm_mul_ps(estimate, v)), estimate), estimate); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return rv; } // ============================================================================= // // sse2_vChirpData // version by: Alex Kan - SSE2 mods (haddsum removal) BH // http://tbp.berkeley.edu/~alexkan/seti/ // int sse2_ChirpData_ak( sah_complex * cx_DataArray, sah_complex * cx_ChirpDataArray, int chirp_rate_ind, double chirp_rate, int ul_NumDataPoints, double sample_rate ) { int i; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("sse2_ChirpData_ak()"); #endif if (chirp_rate_ind == 0) { memcpy(cx_ChirpDataArray, cx_DataArray, (int)ul_NumDataPoints * sizeof(sah_complex) ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } int vEnd; double srate = chirp_rate * 0.5 / (sample_rate * sample_rate); __m128d rate = _mm_set1_pd(chirp_rate * 0.5 / (sample_rate * sample_rate)); __m128d roundVal = _mm_set1_pd(srate >= 0.0 ? TWO_TO_52 : -TWO_TO_52); // main vectorised loop vEnd = ul_NumDataPoints - (ul_NumDataPoints & 3); for (i = 0; i < vEnd; i += 4) { const float *data = (const float *) (cx_DataArray + i); float *chirped = (float *) (cx_ChirpDataArray + i); __m128d di = _mm_set1_pd(i); __m128d a1 = _mm_add_pd(_mm_set_pd(1.0, 0.0), di); __m128d a2 = _mm_add_pd(_mm_set_pd(3.0, 2.0), di); __m128d x1, y1; __m128 d1, d2; __m128 cd1, cd2; __m128 td1, td2; __m128 x; __m128 y; __m128 s; __m128 c; __m128 m; // load the signal to be chirped prefetchnta((const void *)( data+32 )); d1 = _mm_load_ps(data); d2 = _mm_load_ps(data+4); // calculate the input angle a1 = _mm_mul_pd(a1, a1); a2 = _mm_mul_pd(a2, a2); a1 = _mm_mul_pd(a1, rate); a2 = _mm_mul_pd(a2, rate); // reduce the angle to the range (-0.5, 0.5) x1 = _mm_add_pd(a1, roundVal); y1 = _mm_add_pd(a2, roundVal); x1 = _mm_sub_pd(x1, roundVal); y1 = _mm_sub_pd(y1, roundVal); a1 = _mm_sub_pd(a1, x1); a2 = _mm_sub_pd(a2, y1); // convert pair of packed double into packed single x = _mm_movelh_ps(_mm_cvtpd_ps(a1), _mm_cvtpd_ps(a2)); // square to the range [0, 0.25) y = _mm_mul_ps(x, x); // perform the initial polynomial approximations s = _mm_mul_ps(y, SS4); c = _mm_mul_ps(y, CC3); s = _mm_add_ps(s, SS3); c = _mm_add_ps(c, CC2); s = _mm_mul_ps(s, y); c = _mm_mul_ps(c, y); s = _mm_add_ps(s, SS2); c = _mm_add_ps(c, CC1); s = _mm_mul_ps(s, y); c = _mm_mul_ps(c, y); s = _mm_add_ps(s, SS1); s = _mm_mul_ps(s, x); c = _mm_add_ps(c, ONE); // perform first angle doubling x = _mm_sub_ps(_mm_mul_ps(c, c), _mm_mul_ps(s, s)); y = _mm_mul_ps(_mm_mul_ps(s, c), TWO); // calculate scaling factor to correct the magnitude // m1 = vec_nmsub(y1, y1, vec_nmsub(x1, x1, TWO)); // m2 = vec_nmsub(y2, y2, vec_nmsub(x2, x2, TWO)); m = vec_recip2(_mm_add_ps(_mm_mul_ps(x, x), _mm_mul_ps(y, y))); // perform second angle doubling c = _mm_sub_ps(_mm_mul_ps(x, x), _mm_mul_ps(y, y)); s = _mm_mul_ps(_mm_mul_ps(y, x), TWO); // correct the magnitude (final sine / cosine approximations) c = _mm_mul_ps(c, m); s = _mm_mul_ps(s, m); /* c1 c2 c3 c4 s1 s2 s3 s4 R1 i1 R2 I2 R3 i3 R4 i4 R1 * c1 + (i1 * s1 * -1) i1 * c1 + R1 * s1 R2 * c2 + (i2 * s2 * -1) i2 * c2 + R2 * s2 */ x = d1; y = d2; x = _mm_shuffle_ps(x, x, 0xB1); y = _mm_shuffle_ps(y, y, 0xB1); x = _mm_mul_ps(x, R_NEG); y = _mm_mul_ps(y, R_NEG); cd1 = _mm_shuffle_ps(c, c, 0x50); // 01 01 00 00 AaBb => BBbb => c3c3c4c4 cd2 = _mm_shuffle_ps(c, c, 0xfa); // 11 11 10 10 AaBb => AAaa => c1c1c2c2 td1 = _mm_shuffle_ps(s, s, 0x50); td2 = _mm_shuffle_ps(s, s, 0xfa); cd1 = _mm_mul_ps(cd1, d1); cd2 = _mm_mul_ps(cd2, d2); td1 = _mm_mul_ps(td1, x); td2 = _mm_mul_ps(td2, y); cd1 = _mm_add_ps(cd1, td1); cd2 = _mm_add_ps(cd2, td2); // store chirped values _mm_stream_ps(chirped+0, cd1); _mm_stream_ps(chirped+4, cd2); } _mm_sfence(); if( i < ul_NumDataPoints) { // use original routine to finish up any tailings (max stride-1 elements) v_ChirpData(cx_DataArray+i, cx_ChirpDataArray+i , chirp_rate_ind, chirp_rate, ul_NumDataPoints-i, sample_rate); } analysis_state.FLOP_counter+=12.0*ul_NumDataPoints; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } // ============================================================================= // // JWS: alternate SSE2 chirp // // Using Mendenhall Faster SinCos, coding based on // version 8 v_vChirpData for SSE3 by Alex Kan // int sse2_ChirpData_ak8( sah_complex * cx_DataArray, sah_complex * cx_ChirpDataArray, int chirp_rate_ind, const double chirp_rate, int ul_NumDataPoints, const double sample_rate ) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("sse2_ChirpData_ak8()"); #endif int i, vEnd; if (chirp_rate_ind == 0) { memcpy(cx_ChirpDataArray, cx_DataArray, (int)ul_NumDataPoints * sizeof(sah_complex) ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } const double srate = chirp_rate * 0.5 / (sample_rate * sample_rate); __m128d dfourv = _mm_set1_pd(4.0); __m128d rate = _mm_set1_pd(srate); __m128d roundVal = _mm_set1_pd((srate >= 0.0) ? TWO_TO_52 : -TWO_TO_52); // main vectorised loop vEnd = ul_NumDataPoints - (ul_NumDataPoints & 3); __m128d di1 = _mm_set_pd(1.0, 0.0); __m128d di2 = _mm_set_pd(3.0, 2.0); for (i = 0; i < vEnd; i += 4) { const float *data = (const float *) (cx_DataArray + i); float *chirped = (float *) (cx_ChirpDataArray + i); __m128d a1, a2; __m128 d1, d2; __m128 x; __m128 y; __m128 z; __m128 s; __m128 c; __m128 m; // load the signal to be chirped prefetchnta((const void *)( data+32 )); d1 = _mm_load_ps(data); d2 = _mm_load_ps(data+4); // calculate the input angles a1 = _mm_mul_pd(_mm_mul_pd(di1, di1), rate); a2 = _mm_mul_pd(_mm_mul_pd(di2, di2), rate); // update time values for next iteration di1 = _mm_add_pd(di1, dfourv); di2 = _mm_add_pd(di2, dfourv); // reduce the angles to the range (-0.5, 0.5) a1 = _mm_sub_pd(a1, _mm_sub_pd(_mm_add_pd(a1, roundVal), roundVal)); a2 = _mm_sub_pd(a2, _mm_sub_pd(_mm_add_pd(a2, roundVal), roundVal)); // convert the 2 packed doubles to packed single x = _mm_movelh_ps(_mm_cvtpd_ps(a1), _mm_cvtpd_ps(a2)); // square to the range [0, 0.25) y = _mm_mul_ps(x, x); // perform the initial polynomial approximations z = _mm_mul_ps(y, y); s = _mm_mul_ps(_mm_add_ps(_mm_mul_ps(_mm_add_ps(_mm_mul_ps(y, SS4F), SS3F), z), _mm_add_ps(_mm_mul_ps(y, SS2F), SS1F)), x); c = _mm_add_ps(_mm_mul_ps(_mm_add_ps(_mm_mul_ps(y, CC3F), CC2F), z), _mm_add_ps(_mm_mul_ps(y, CC1F), ONE)); // perform first angle doubling x = _mm_sub_ps(_mm_mul_ps(c, c), _mm_mul_ps(s, s)); y = _mm_mul_ps(_mm_mul_ps(s, c), TWO); // calculate scaling factor to correct the magnitude m = _mm_sub_ps(_mm_sub_ps(TWO, _mm_mul_ps(x, x)), _mm_mul_ps(y, y)); // perform second angle doubling c = _mm_sub_ps(_mm_mul_ps(x, x), _mm_mul_ps(y, y)); s = _mm_mul_ps(_mm_mul_ps(y, x), TWO); // correct the magnitude (final sine / cosine approximations) s = _mm_mul_ps(s, m); c = _mm_mul_ps(c, m); // chirp the data x = _mm_mul_ps(_mm_shuffle_ps(d1, d1, 0xb1), R_NEG); y = _mm_mul_ps(_mm_shuffle_ps(d2, d2, 0xb1), R_NEG); d1 = _mm_mul_ps(d1, _mm_shuffle_ps(c, c, 0x50)); d2 = _mm_mul_ps(d2, _mm_shuffle_ps(c, c, 0xfa)); x = _mm_mul_ps(x, _mm_shuffle_ps(s, s, 0x50)); y = _mm_mul_ps(y, _mm_shuffle_ps(s, s, 0xfa)); // store chirped values _mm_stream_ps(chirped+0, _mm_add_ps(d1, x)); _mm_stream_ps(chirped+4, _mm_add_ps(d2, y)); } _mm_sfence(); // handle tail elements with scalar code for ( ; i < ul_NumDataPoints; ++i) { double angle = srate * i * i * 0.5; angle -= floor(angle); angle *= M_PI * 2; double s = sin(angle); double c = cos(angle); float re = cx_DataArray[i][0]; float im = cx_DataArray[i][1]; cx_ChirpDataArray[i][0] = re * c - im * s; cx_ChirpDataArray[i][1] = re * s + im * c; } analysis_state.FLOP_counter+=12.0*ul_NumDataPoints; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } #endif // USE_INTRINSICS boinc-app-seti_8.00~svn3701.orig/client/vector/analyzeFuncs_neon.S0000644000175000017500000024522413047720225025112 0ustar locutuslocutus// Copyright (c) 1999-2011 Regents of the University of California // // FFTW: Copyright (c) 2003,2006 Matteo Frigo // Copyright (c) 2003,2006 Massachusets Institute of Technology // // fft8g.[cpp,h]: Copyright (c) 1995-2001 Takya Ooura // // ASMLIB: Copyright (c) 2004 Agner Fog // 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, 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; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions // as an alternative to FFTW and distribute a linked executable and // source code. You must obey the GNU General Public License in all // respects for all of the code used other than the FFT library itself. // Any modification required to support these libraries must be distributed // under the terms of this license. If you modify this program, you may extend // this exception to your version of the program, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. Please be aware that FFTW and ASMLIB are not covered by // this exception, therefore you may not use FFTW and ASMLIB in any derivative // work so modified without permission of the authors of those packages. #ifdef __arm__ /* * neon_ChirpData.S * Author: Mateusz Szpakowski */ #if defined(__VFP_FP__) && !defined(__SOFTFP__) .syntax unified #endif .arch armv7-a .fpu neon #if defined(__VFP_FP__) && !defined(__SOFTFP__) .eabi_attribute 27, 3 .eabi_attribute 28, 1 #endif /* .eabi_attribute 20, 1 .eabi_attribute 21, 1 .eabi_attribute 23, 3 */ .eabi_attribute 23, 1 .eabi_attribute 24, 1 .eabi_attribute 25, 1 .eabi_attribute 26, 2 .eabi_attribute 30, 2 .eabi_attribute 18, 4 .text .align 2 .Lhalfd: .double 0.5 .LroundVal: .double 4503599627370496.0 .align 4 .Linc8d: .double 0,1,2,3,4,5,6,7 .Lsinapprox: .float 1.5707963268,1.5707963268,1.5707963268,1.5707963268 .float -0.6466386396,-0.6466386396,-0.6466386396,-0.6466386396 .float 0.0679105987,0.0679105987,0.0679105987,0.0679105987 .float -0.0011573807,-0.0011573807,-0.0011573807,-0.0011573807 .Lcosapprox: .float 1.0,1.0,1.0,1.0 .float -1.2341299769,-1.2341299769,-1.2341299769,-1.2341299769 .float 0.2465220241,0.2465220241,0.2465220241,0.2465220241 .float -0.0123926179,-0.0123926179,-0.0123926179,-0.0123926179 .Ltwosq: .float 2.0,2.0,2.0,2.0 .float 2.0,2.0,2.0,2.0 .float 2.0,2.0,2.0,2.0 .float 2.0,2.0,2.0,2.0 .align 2 .global _Z14neon_ChirpDataPA2_fS0_idid .type _Z14neon_ChirpDataPA2_fS0_idid, %function _Z14neon_ChirpDataPA2_fS0_idid: push {r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} vpush {d8,d9,d10,d11,d12,d13,d14,d15} #ifdef ANDROID #define stargidx (40+64) /* r0 - input data * r1 - output data * r2 - chirprateind * sp[0-1] - chirp_rate * sp[2] - numDataPoints * sp[4-5] - sample_rate */ #else //R: cause few params now in registers stack should be shorter by 20 bytes #define stargidx (40+64) //R: armhf like Parallella use registers instead of stack to pass params so another expected pattern of registers use /* r0 - input data r1 - output data r2 - chirprateind r3 - numDataPoints d0 - chirp_rate d1 - sample_rate */ //R: seems r12 isn't in use in original function so use it to preserve numDataPoins value (r3) mov r12,r3 vmov.f64 d9, d0 vmov.f64 d10, d1 #endif tst r2,r2 bne .Lrealfunc mov r3,r0 // swap addresses mov r0,r1 mov r1,r3 #ifdef ANDROID ldr r2,[sp,#stargidx+8] // numDataPoints #else mov r2,r12 #endif lsl r2,r2,#3 bl memcpy(PLT) b .Lendoffunc /* * real functions */ .Lrealfunc: ldr r4,.LGOT1 .LPIC1: add r4,pc,r4 ldr r5,.LGOT1+4 ldr r5,[r4,r5] #ifdef ANDROID ldr r3,[sp,#stargidx+8] // numDataPoints #else mov r3,r12 #endif add r6,r3,r3,lsl #1 lsl r6,r6,#2 fldd d0,[r5,#32] fmsr s4,r6 fuitod d1,s4 faddd d0,d0,d1 fstd d0,[r5,#32] add r3,r0,r3,lsl #3 sub r3,r3,#8*15 fldd d11,.Lhalfd #ifdef ANDROID //R: for armhf these doubles already in registers fldd d9,[sp,#stargidx] // chirp_rate fldd d10,[sp,#stargidx+16] // sample_rate #endif fmuld d10,d10,d10 fmuld d9,d9,d11 fdivd d9,d9,d10 fldd d10,.LroundVal fsubd d11,d11,d11 // zero fcmpd d9,d11 fmstat fnegdmi d10,d10 // negate is negative srate #ifdef ANDROID sub sp,sp,#16+64 #else //R: for armhf stack has different size so attempting to account for that sub sp,sp,#16+64 #endif add r7,sp,#16 add r11,sp,#16+32 fstmiad sp,{d9,d10} mov r4,#0 // i adr r5,.Linc8d adr r6,.Lsinapprox adr r10,.Lcosapprox adr r9,.Ltwosq cmp r0,r3 bhs .Lendmainloop .Lmainloop: add r8,r4,#8 fmsr s8,r4 fmsr s9,r8 fuitod d0,s8 fuitod d1,s9 fldmiad r5,{d8,d9,d10,d11,d12,d13,d14,d15} fldmiad sp,{d2,d3} faddd d16,d8,d0 faddd d17,d9,d0 faddd d18,d10,d0 faddd d19,d11,d0 faddd d20,d12,d0 faddd d21,d13,d0 faddd d22,d14,d0 faddd d23,d15,d0 faddd d24,d8,d1 faddd d25,d9,d1 faddd d26,d10,d1 faddd d27,d11,d1 faddd d28,d12,d1 faddd d29,d13,d1 faddd d30,d14,d1 faddd d31,d15,d1 // square of i fmuld d16,d16,d16 fmuld d17,d17,d17 fmuld d18,d18,d18 fmuld d19,d19,d19 fmuld d20,d20,d20 fmuld d21,d21,d21 fmuld d22,d22,d22 fmuld d23,d23,d23 fmuld d24,d24,d24 fmuld d25,d25,d25 fmuld d26,d26,d26 fmuld d27,d27,d27 fmuld d28,d28,d28 fmuld d29,d29,d29 fmuld d30,d30,d30 fmuld d31,d31,d31 // multiply by srate fmuld d16,d16,d2 fmuld d17,d17,d2 fmuld d18,d18,d2 fmuld d19,d19,d2 fmuld d20,d20,d2 fmuld d21,d21,d2 fmuld d22,d22,d2 fmuld d23,d23,d2 fmuld d24,d24,d2 fmuld d25,d25,d2 fmuld d26,d26,d2 fmuld d27,d27,d2 fmuld d28,d28,d2 fmuld d29,d29,d2 fmuld d30,d30,d2 fmuld d31,d31,d2 // rounding to -0.5/+0.5 faddd d8,d16,d3 faddd d9,d17,d3 faddd d10,d18,d3 faddd d11,d19,d3 faddd d12,d20,d3 faddd d13,d21,d3 faddd d14,d22,d3 faddd d15,d23,d3 fsubd d8,d8,d3 fsubd d9,d9,d3 fsubd d10,d10,d3 fsubd d11,d11,d3 fsubd d12,d12,d3 fsubd d13,d13,d3 fsubd d14,d14,d3 fsubd d15,d15,d3 fsubd d16,d16,d8 fsubd d17,d17,d9 fsubd d18,d18,d10 fsubd d19,d19,d11 fsubd d20,d20,d12 fsubd d21,d21,d13 fsubd d22,d22,d14 fsubd d23,d23,d15 faddd d8,d24,d3 faddd d9,d25,d3 faddd d10,d26,d3 faddd d11,d27,d3 faddd d12,d28,d3 faddd d13,d29,d3 faddd d14,d30,d3 faddd d15,d31,d3 fsubd d8,d8,d3 fsubd d9,d9,d3 fsubd d10,d10,d3 fsubd d11,d11,d3 fsubd d12,d12,d3 fsubd d13,d13,d3 fsubd d14,d14,d3 fsubd d15,d15,d3 fsubd d24,d24,d8 fsubd d25,d25,d9 fsubd d26,d26,d10 fsubd d27,d27,d11 fsubd d28,d28,d12 fsubd d29,d29,d13 fsubd d30,d30,d14 fsubd d31,d31,d15 // to single precision fcvtsd s0,d16 fcvtsd s1,d17 fcvtsd s2,d18 fcvtsd s3,d19 fcvtsd s4,d20 fcvtsd s5,d21 fcvtsd s6,d22 fcvtsd s7,d23 fcvtsd s8,d24 fcvtsd s9,d25 fcvtsd s10,d26 fcvtsd s11,d27 fcvtsd s12,d28 fcvtsd s13,d29 fcvtsd s14,d30 fcvtsd s15,d31 //fldmias r6,{s8,s9,s10,s11,s12,s13,s14,s15} vldmia r6,{q8,q9,q10,q11} // square of y vmul.f32 q4,q0,q0 vmul.f32 q5,q1,q1 vmul.f32 q6,q2,q2 vmul.f32 q7,q3,q3 // sine vmul.f32 q12,q4,q11 vmul.f32 q13,q5,q11 vmul.f32 q14,q6,q11 vmul.f32 q15,q7,q11 vadd.f32 q12,q12,q10 vadd.f32 q13,q13,q10 vadd.f32 q14,q14,q10 vadd.f32 q15,q15,q10 vmul.f32 q12,q12,q4 vmul.f32 q13,q13,q5 vmul.f32 q14,q14,q6 vmul.f32 q15,q15,q7 vadd.f32 q12,q12,q9 vadd.f32 q13,q13,q9 vadd.f32 q14,q14,q9 vadd.f32 q15,q15,q9 vmul.f32 q12,q12,q4 vmul.f32 q13,q13,q5 vmul.f32 q14,q14,q6 vmul.f32 q15,q15,q7 vadd.f32 q12,q12,q8 vadd.f32 q13,q13,q8 vadd.f32 q14,q14,q8 vadd.f32 q15,q15,q8 vmul.f32 q12,q12,q0 vmul.f32 q13,q13,q1 vmul.f32 q14,q14,q2 vmul.f32 q15,q15,q3 vldmia r10,{q0,q1,q2,q3} // cosine vmul.f32 q8,q4,q3 vmul.f32 q9,q5,q3 vmul.f32 q10,q6,q3 vmul.f32 q11,q7,q3 vadd.f32 q8,q8,q2 vadd.f32 q9,q9,q2 vadd.f32 q10,q10,q2 vadd.f32 q11,q11,q2 vmul.f32 q8,q8,q4 vmul.f32 q9,q9,q5 vmul.f32 q10,q10,q6 vmul.f32 q11,q11,q7 vadd.f32 q8,q8,q1 vadd.f32 q9,q9,q1 vadd.f32 q10,q10,q1 vadd.f32 q11,q11,q1 vmul.f32 q8,q8,q4 vmul.f32 q9,q9,q5 vmul.f32 q10,q10,q6 vmul.f32 q11,q11,q7 vadd.f32 q8,q8,q0 vadd.f32 q9,q9,q0 vadd.f32 q10,q10,q0 vadd.f32 q11,q11,q0 // q8-q11 - cosine, q12-q15 - sine // doubling cosine/sine vmul.f32 q4,q8,q12 // c*s vmul.f32 q5,q9,q13 vmul.f32 q6,q10,q14 vmul.f32 q7,q11,q15 vmul.f32 q0,q8,q8 // c*c vmul.f32 q1,q9,q9 vmul.f32 q2,q10,q10 vmul.f32 q3,q11,q11 vmls.f32 q0,q12,q12 // c*c-s*s vmls.f32 q1,q13,q13 vmls.f32 q2,q14,q14 vmls.f32 q3,q15,q15 vadd.f32 q4,q4,q4 // 2*c*s vadd.f32 q5,q5,q5 vadd.f32 q6,q6,q6 vadd.f32 q7,q7,q7 // next doubling cosine/sine vmul.f32 q8,q0,q4 // cd1 = x*y vmul.f32 q9,q1,q5 vmul.f32 q10,q2,q6 vmul.f32 q11,q3,q7 vmul.f32 q4,q4,q4 // cd3 = y*y vmul.f32 q5,q5,q5 vmul.f32 q6,q6,q6 vmul.f32 q7,q7,q7 vmul.f32 q0,q0,q0 // cd2 = x*x vmul.f32 q1,q1,q1 vmul.f32 q2,q2,q2 vmul.f32 q3,q3,q3 vadd.f32 q12,q0,q4 // norm = cd2+cd3 vadd.f32 q13,q1,q5 vadd.f32 q14,q2,q6 vadd.f32 q15,q3,q7 vadd.f32 q8,q8,q8 // s = cd1*2 vadd.f32 q9,q9,q9 vadd.f32 q10,q10,q10 vadd.f32 q11,q11,q11 vsub.f32 q0,q0,q4 // c = cd2-cd3 vsub.f32 q1,q1,q5 vsub.f32 q2,q2,q6 vsub.f32 q3,q3,q7 // c - q0-q3, s - q8-q11, norm - q12-q15 vstmia r7,{q8,q9,q10,q11} vldmia r9,{q4,q5,q6,q7} // reciprocal of magnitude // iter 1: invmag = 2.0-mag vsub.f32 q4,q4,q12 vsub.f32 q5,q5,q13 vsub.f32 q6,q6,q14 vsub.f32 q7,q7,q15 // iter 2: invmag = invmag*(2.0-mag*invmag) vrecps.f32 q8,q4,q12 vrecps.f32 q9,q5,q13 vrecps.f32 q10,q6,q14 vrecps.f32 q11,q7,q15 vmul.f32 q4,q4,q8 vmul.f32 q5,q5,q9 vmul.f32 q6,q6,q10 vmul.f32 q7,q7,q11 vldmia r7,{q8,q9,q10,q11} // invnorm - q4-q7 // correct cosine/sine vmul.f32 q0,q0,q4 vmul.f32 q1,q1,q5 vmul.f32 q2,q2,q6 vmul.f32 q3,q3,q7 vmul.f32 q8,q8,q4 vmul.f32 q9,q9,q5 vmul.f32 q10,q10,q6 vmul.f32 q11,q11,q7 vzip.32 q0,q8 vzip.32 q1,q9 vzip.32 q2,q10 vzip.32 q3,q11 vstmia r7,{q2,q3} vstmia r11,{q10,q11} // multiply by data pld [r0,#256] vldmia r0!,{q12,q13,q14,q15} vmul.f32 q4,q12,q0 vmul.f32 q5,q13,q8 vmul.f32 q6,q14,q1 vmul.f32 q7,q15,q9 vrev64.32 q2,q0 vrev64.32 q10,q8 vrev64.32 q3,q1 vrev64.32 q11,q9 vmul.f32 q2,q2,q12 vmul.f32 q10,q10,q13 vmul.f32 q3,q3,q14 vmul.f32 q11,q11,q15 fnegs s17,s17 fnegs s19,s19 fnegs s21,s21 fnegs s23,s23 fnegs s25,s25 fnegs s27,s27 fnegs s29,s29 fnegs s31,s31 vtrn.32 q4,q2 vtrn.32 q5,q10 vtrn.32 q6,q3 vtrn.32 q7,q11 vadd.f32 q4,q4,q2 vadd.f32 q5,q5,q10 vadd.f32 q6,q6,q3 vadd.f32 q7,q7,q11 vstmia r1!,{q4,q5,q6,q7} vldmia r7,{q0,q1} vldmia r11,{q8,q9} pld [r0,#256] vldmia r0!,{q12,q13,q14,q15} vmul.f32 q4,q12,q0 vmul.f32 q5,q13,q8 vmul.f32 q6,q14,q1 vmul.f32 q7,q15,q9 vrev64.32 q2,q0 vrev64.32 q10,q8 vrev64.32 q3,q1 vrev64.32 q11,q9 vmul.f32 q2,q2,q12 vmul.f32 q10,q10,q13 vmul.f32 q3,q3,q14 vmul.f32 q11,q11,q15 fnegs s17,s17 fnegs s19,s19 fnegs s21,s21 fnegs s23,s23 fnegs s25,s25 fnegs s27,s27 fnegs s29,s29 fnegs s31,s31 vtrn.32 q4,q2 vtrn.32 q5,q10 vtrn.32 q6,q3 vtrn.32 q7,q11 vadd.f32 q4,q4,q2 vadd.f32 q5,q5,q10 vadd.f32 q6,q6,q3 vadd.f32 q7,q7,q11 vstmia r1!,{q4,q5,q6,q7} add r4,r4,#16 cmp r0,r3 blo .Lmainloop .Lendmainloop: add r3,r3,#8*15 cmp r0,r3 bhs .Lendsmallloop adr r6,.Lsincosapprox .Lsmallloop: fmsr s24,r4 fldmiad sp,{d9,d10} fuitod d0,s24 // square of i fmuld d0,d0,d0 // multiply by srate fmuld d0,d0,d9 // rounding to -0.5/+0.5 faddd d12,d0,d10 fsubd d12,d12,d10 fsubd d0,d0,d12 fcvtsd s24,d0 fldmias r6,{s8,s9,s10,s11,s12,s13,s14,s15} // square of y fmuls s0,s24,s24 // sine/cosine fmuls s16,s0,s11 fmuls s17,s0,s15 fadds s16,s16,s10 fadds s17,s17,s14 fmuls s16,s16,s0 fmuls s17,s17,s0 fadds s16,s16,s9 fadds s17,s17,s13 fmuls s16,s16,s0 fmuls s17,s17,s0 fadds s16,s16,s8 fadds s17,s17,s12 // s16 - sine fmuls s16,s16,s24 // s17 - cosine // doubling cosine/sine fmuls s18,s16,s17 fmuls s19,s16,s16 fmuls s20,s17,s17 fadds s18,s18,s18 // y=2*s*c fsubs s19,s20,s19 // x=c*c-s*s fmuls s21,s18,s19 // cd1 fmuls s22,s19,s19 // cd2 fmuls s23,s18,s18 // cd3 fsubs s8,s22,s23 // c fadds s9,s21,s21 // s // compute 1.0/norm fadds s10,s22,s23 // mag // reciprocal flds s11,.Ltwos // iter1: invmag = 2.0-mag fsubs s12,s11,s10 // iter2: invmag = invmag*(2.0-invmag*mag) fmuls s13,s12,s10 fsubs s13,s11,s13 fmuls s12,s12,s13 // iter3: invmag = invmag*(2.0-invmag*mag) fmuls s13,s12,s10 fsubs s13,s11,s13 fmuls s12,s12,s13 // correct cosine/sine fmuls s8,s8,s12 fmuls s9,s9,s12 // multiply data fldmias r0!,{s14,s15} fmuls s6,s14,s8 fmuls s7,s14,s9 fnmacs s6,s15,s9 fmacs s7,s15,s8 fstmias r1!,{s6,s7} add r4,r4,#1 cmp r0,r3 blo .Lsmallloop .Lendsmallloop: #ifdef ANDROID add sp,sp,#16+64 #else add sp,sp,#16+64 #endif .Lendoffunc: mov r0,#0 vpop {d8,d9,d10,d11,d12,d13,d14,d15} pop {r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} bx lr .align 2 .LGOT1: .word _GLOBAL_OFFSET_TABLE_-(.LPIC1+8) .word analysis_state(GOT) .align 2 .Ltwos: .float 2.0 .Lsincosapprox: .float 1.5707963268,-0.6466386396,0.0679105987,-0.0011573807 // sine .float 1.0,-1.2341299769,0.2465220241,-0.0123926179 // cosine /* * neon_FoldSubs.S * Author: Mateusz Szpakowski */ .align 2 /***** * fold array by 3 ******/ .global neon_foldArrayBy3_ll31 .type neon_foldArrayBy3_ll31, %function neon_foldArrayBy3_ll31: push {r4,r5,r6,lr} vpush {d8,d9,d10,d11,d12,d13,d14,d15} ldr r0,[r0] // ss0 ldrd r2,[r1,#8] // tmp0 add r2,r0,r2,lsl #2 add r3,r0,r3,lsl #2 ldrd r4,[r1] // di,dest add r6,r0,r4,lsl #2 // end veor.i32 q12,q12,q12 sub r6,r6,#4*15 cmp r0,r6 bhs .Lendf3loop1 .Lf3loop1: .macro FOLDBY3_CORE vldmia r0!,{q0,q1,q2,q3} vldmia r2!,{q4,q5,q6,q7} vldmia r3!,{q8,q9,q10,q11} vadd.f32 q0,q0,q4 vadd.f32 q1,q1,q5 vadd.f32 q2,q2,q6 vadd.f32 q3,q3,q7 vadd.f32 q0,q0,q8 vadd.f32 q1,q1,q9 vadd.f32 q2,q2,q10 vadd.f32 q3,q3,q11 vstmia r5!,{q0,q1,q2,q3} vmax.f32 q13,q0,q1 vmax.f32 q14,q2,q3 vmax.f32 q12,q12,q13 vmax.f32 q12,q12,q14 .endm FOLDBY3_CORE cmp r0,r6 blo .Lf3loop1 .Lendf3loop1: and r4,r4,#15 cmp r4,#8 blo .Lf3lt8 beq .Lf3eq8 cmp r4,#12 blo .Lf3lt12 beq .Lf3eq12 cmp r4,#14 blo .Lf3lt14 beq .Lf3eq14 // 15 elems vldmia r0!,{q0,q1,q2} vldmia r0!,{s12,s13,s14} vldmia r2!,{q4,q5,q6} vldmia r2!,{s28,s29,s30} vldmia r3!,{q8,q9,q10} vldmia r3!,{d22} vldmia r3!, {s15} vadd.f32 q0,q0,q4 vadd.f32 q1,q1,q5 vadd.f32 q2,q2,q6 vadd.f32 d6,d6,d14 vadd.f32 s14,s14,s30 vadd.f32 q0,q0,q8 vadd.f32 q1,q1,q9 vadd.f32 q2,q2,q10 vadd.f32 d6,d6,d22 vadd.f32 s14,s14,s15 vstmia r5!,{q0,q1,q2} vstmia r5!,{s12,s13,s14} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 vmax.f32 q12,q12,q2 vmax.f32 q12,q12,q3 b .Lf3end .Lf3eq14: // 14 elems vldmia r0!,{q0,q1,q2} vldmia r0!,{d6} vldmia r2!,{q4,q5,q6} vldmia r2!,{d14} vldmia r3!,{q8,q9,q10} vldmia r3!,{d22} vadd.f32 q0,q0,q4 vadd.f32 q1,q1,q5 vadd.f32 q2,q2,q6 vadd.f32 d6,d6,d14 vadd.f32 q0,q0,q8 vadd.f32 q1,q1,q9 vadd.f32 q2,q2,q10 vadd.f32 d6,d6,d22 vstmia r5!,{q0,q1,q2} vstmia r5!,{d6} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 vmax.f32 q12,q12,q2 vmax.f32 d24,d24,d6 b .Lf3end .Lf3lt14: // 13 elems vldmia r0!,{q0,q1,q2} vldmia r0!,{s12} vldmia r2!,{q4,q5,q6} vldmia r2!,{s13} vldmia r3!,{q8,q9,q10} vldmia r3!,{s14} vadd.f32 q0,q0,q4 vadd.f32 q1,q1,q5 vadd.f32 q2,q2,q6 fadds s12,s12,s13 vadd.f32 q0,q0,q8 vadd.f32 q1,q1,q9 vadd.f32 q2,q2,q10 fadds s12,s12,s14 vstmia r5!,{q0,q1,q2} vstmia r5!,{s12} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 vmax.f32 q12,q12,q2 vmax.f32 d24,d24,d6 b .Lf3end .Lf3eq12: // 12 elems vldmia r0!,{q0,q1,q2} vldmia r2!,{q4,q5,q6} vldmia r3!,{q8,q9,q10} vadd.f32 q0,q0,q4 vadd.f32 q1,q1,q5 vadd.f32 q2,q2,q6 vadd.f32 q0,q0,q8 vadd.f32 q1,q1,q9 vadd.f32 q2,q2,q10 vstmia r5!,{q0,q1,q2} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 vmax.f32 q12,q12,q2 b .Lf3end .Lf3lt12: cmp r4,#10 blo .Lf3lt10 beq .Lf3eq10 // 11 elems vldmia r0!,{q0,q1} vldmia r0!,{s8,s9,s10} vldmia r2!,{q4,q5} vldmia r2!,{s24,s25,s26} vldmia r3!,{q8,q9} vldmia r3!,{d20} vldmia r3!,{s11} vadd.f32 q0,q0,q4 vadd.f32 q1,q1,q5 vadd.f32 d4,d4,d12 vadd.f32 s10,s10,s26 vadd.f32 q0,q0,q8 vadd.f32 q1,q1,q9 vadd.f32 d4,d4,d20 vadd.f32 s10,s10,s11 vstmia r5!,{q0,q1} vstmia r5!,{s8,s9,s10} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 vmax.f32 q12,q12,q2 b .Lf3end .Lf3eq10: // 10 elems vldmia r0!,{q0,q1} vldmia r0!,{d4} vldmia r2!,{q4,q5} vldmia r2!,{d12} vldmia r3!,{q8,q9} vldmia r3!,{d20} vadd.f32 q0,q0,q4 vadd.f32 q1,q1,q5 vadd.f32 d4,d4,d12 vadd.f32 q0,q0,q8 vadd.f32 q1,q1,q9 vadd.f32 d4,d4,d20 vstmia r5!,{q0,q1} vstmia r5!,{d4} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 vmax.f32 d24,d24,d4 b .Lf3end .Lf3lt10: // 9 elems vldmia r0!,{q0,q1} vldmia r0!,{s8} vldmia r2!,{q4,q5} vldmia r2!,{s9} vldmia r3!,{q8,q9} vldmia r3!,{s10} vadd.f32 q0,q0,q4 vadd.f32 q1,q1,q5 fadds s8,s8,s9 vadd.f32 q0,q0,q8 vadd.f32 q1,q1,q9 fadds s8,s8,s10 vstmia r5!,{q0,q1} vstmia r5!,{s8} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 vmax.f32 d24,d24,d4 b .Lf3end .Lf3eq8: // 8 elems vldmia r0!,{q0,q1} vldmia r2!,{q4,q5} vldmia r3!,{q8,q9} vadd.f32 q0,q0,q4 vadd.f32 q1,q1,q5 vadd.f32 q0,q0,q8 vadd.f32 q1,q1,q9 vstmia r5!,{q0,q1} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 b .Lf3end .Lf3lt8: cmp r4,#4 blo .Lf3lt4 beq .Lf3eq4 cmp r4,#6 blo .Lf3lt6 beq .Lf3eq6 // 7 elems vldmia r0!,{q0} vldmia r0!,{s4,s5,s6} vldmia r2!,{q4} vldmia r2!,{s20,s21,s22} vldmia r3!,{q8} vldmia r3!,{d18} vldmia r3!,{s7} vadd.f32 q0,q0,q4 vadd.f32 d2,d2,d10 vadd.f32 s6,s6,s22 vadd.f32 q0,q0,q8 vadd.f32 d2,d2,d18 vadd.f32 s6,s6,s7 vstmia r5!,{q0} vstmia r5!,{s4,s5,s6} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 b .Lf3end .Lf3eq6: // 6 elems vldmia r0!,{q0} vldmia r0!,{d2} vldmia r2!,{q4} vldmia r2!,{d10} vldmia r3!,{q8} vldmia r3!,{d18} vadd.f32 q0,q0,q4 vadd.f32 d2,d2,d10 vadd.f32 q0,q0,q8 vadd.f32 d2,d2,d18 vstmia r5!,{q0} vstmia r5!,{d2} vmax.f32 q12,q12,q0 vmax.f32 d24,d24,d2 b .Lf3end .Lf3lt6: // 5 elems vldmia r0!,{q0} vldmia r0!,{s4} vldmia r2!,{q4} vldmia r2!,{s20} vldmia r3!,{q8} vldmia r3!,{s5} vadd.f32 q0,q0,q4 fadds s4,s4,s20 vadd.f32 q0,q0,q8 fadds s4,s4,s5 vstmia r5!,{q0} vstmia r5!,{s4} vmax.f32 q12,q12,q0 vmax.f32 d24,d24,d2 b .Lf3end .Lf3eq4: // 4 elems vldmia r0!,{q0} vldmia r2!,{q4} vldmia r3!,{q8} vadd.f32 q0,q0,q4 vadd.f32 q0,q0,q8 vstmia r5!,{q0} vmax.f32 q12,q12,q0 b .Lf3end .Lf3lt4: cmp r4,#2 blo .Lf3lt2 beq .Lf3eq2 // 3 elems vldmia r0!,{s0,s1,s2} vldmia r2!,{s16,s17,s18} vldmia r3!,{d16} vldmia r3!,{s3} vadd.f32 d0,d0,d8 vadd.f32 s2,s2,s18 vadd.f32 d0,d0,d16 vadd.f32 s2,s2,s3 vstmia r5!,{s0,s1,s2} vmax.f32 q12,q12,q0 b .Lf3end .Lf3eq2: // 2 elems vldmia r0!,{d0} vldmia r2!,{d4} vldmia r3!,{d8} vadd.f32 d0,d0,d4 vadd.f32 d0,d0,d8 vstmia r5!,{d0} vmax.f32 d24,d24,d0 b .Lf3end .Lf3lt2: cmp r4,#0 beq .Lf3eq0 vldmia r0!,{s0} vldmia r2!,{s1} vldmia r3!,{s2} vadd.f32 s0,s0,s1 vadd.f32 s0,s0,s2 vstmia r5!,{s0} vmax.f32 d24,d24,d0 .Lf3eq0: .Lf3end: vpmax.f32 d24,d24,d25 vpmax.f32 d0,d24,d24 fmrs r0,s0 vpop {d8,d9,d10,d11,d12,d13,d14,d15} pop {r4,r5,r6,lr} bx lr .global neon_foldArrayBy3_lge31 .type neon_foldArrayBy3_lge31, %function neon_foldArrayBy3_lge31: push {r4,r5,r6,lr} vpush {d8,d9,d10,d11,d12,d13,d14,d15} ldr r0,[r0] // ss0 ldrd r2,[r1,#8] // tmp0 add r2,r0,r2,lsl #2 add r3,r0,r3,lsl #2 ldrd r4,[r1] // di,dest add r6,r0,r4,lsl #2 // end veor.i32 q12,q12,q12 sub r6,r6,#4*31 cmp r0,r6 bhs .Lendf3loop2 .Lf3loop2: FOLDBY3_CORE FOLDBY3_CORE cmp r0,r6 blo .Lf3loop2 .Lendf3loop2: add r6,r6,#4*16 cmp r0,r6 bhs .Lendf3loop1 .Lf3loop3: FOLDBY3_CORE cmp r0,r6 blo .Lf3loop3 .Lendf3loop3: b .Lendf3loop1 .Lfoldby3sel: .rept 31 .word neon_foldArrayBy3_ll31 .endr .word neon_foldArrayBy3_lge31 /****** * fold array by 4 ******/ .global neon_foldArrayBy4_ll31 .type neon_foldArrayBy4_ll31, %function neon_foldArrayBy4_ll31: push {r4,r5,r6,r7,r8,lr} vpush {d8,d9,d10,d11,d12,d13,d14,d15} ldr r0,[r0] // ss0 ldrd r2,[r1,#8] // tmp0 ldr r6,[r1,#16] // tmp2 add r2,r0,r2,lsl #2 add r3,r0,r3,lsl #2 add r6,r0,r6,lsl #2 ldrd r4,[r1] // di,dest add r7,r0,r4,lsl #2 // end veor.i32 q12,q12,q12 sub r7,r7,#4*15 cmp r0,r7 bhs .Lendf4loop1 .Lf4loop1: .macro FOLDBY4_CORE vldmia r0!,{q0,q1,q2,q3} vldmia r2!,{q4,q5,q6,q7} vldmia r3!,{q8,q9,q10,q11} vadd.f32 q0,q0,q4 vadd.f32 q1,q1,q5 vadd.f32 q2,q2,q6 vadd.f32 q3,q3,q7 vadd.f32 q0,q0,q8 vadd.f32 q1,q1,q9 vadd.f32 q2,q2,q10 vadd.f32 q3,q3,q11 vldmia r6!,{q8,q9,q10,q11} vadd.f32 q0,q0,q8 vadd.f32 q1,q1,q9 vadd.f32 q2,q2,q10 vadd.f32 q3,q3,q11 vstmia r5!,{q0,q1,q2,q3} vmax.f32 q13,q0,q1 vmax.f32 q14,q2,q3 vmax.f32 q12,q12,q13 vmax.f32 q12,q12,q14 .endm FOLDBY4_CORE cmp r0,r7 blo .Lf4loop1 .Lendf4loop1: and r4,r4,#15 cmp r4,#8 blo .Lf4lt8 beq .Lf4eq8 cmp r4,#12 blo .Lf4lt12 beq .Lf4eq12 cmp r4,#14 blo .Lf4lt14 beq .Lf4eq14 // 15 elems vldmia r0!,{q0,q1,q2} vldmia r0!,{s12,s13,s14} vldmia r2!,{q4,q5,q6} vldmia r2!,{s28,s29,s30} vldmia r3!,{q8,q9,q10} vldmia r3!,{d22} vldmia r3, {s15} vldmia r6!,{q13,q14,q15} vadd.f32 q0,q0,q4 vadd.f32 q1,q1,q5 vadd.f32 q2,q2,q6 vadd.f32 d6,d6,d14 vadd.f32 s14,s14,s30 vadd.f32 q0,q0,q8 vadd.f32 q1,q1,q9 vadd.f32 q2,q2,q10 vadd.f32 d6,d6,d22 vadd.f32 s14,s14,s15 vldmia r6!,{s16,s17,s18} vadd.f32 q0,q0,q13 vadd.f32 q1,q1,q14 vadd.f32 q2,q2,q15 vadd.f32 d6,d6,d8 vadd.f32 s14,s14,s18 vstmia r5!,{q0,q1,q2} vstmia r5!,{s12,s13,s14} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 vmax.f32 q12,q12,q2 vmax.f32 q12,q12,q3 b .Lf4end .Lf4eq14: // 14 elems vldmia r0!,{q0,q1,q2} vldmia r0!,{d6} vldmia r2!,{q4,q5,q6} vldmia r2!,{d14} vldmia r3!,{q8,q9,q10} vldmia r3!,{d22} vldmia r6!,{q13,q14,q15} vldmia r6!,{d7} vadd.f32 q0,q0,q4 vadd.f32 q1,q1,q5 vadd.f32 q2,q2,q6 vadd.f32 d6,d6,d14 vadd.f32 q0,q0,q8 vadd.f32 q1,q1,q9 vadd.f32 q2,q2,q10 vadd.f32 d6,d6,d22 vadd.f32 q0,q0,q13 vadd.f32 q1,q1,q14 vadd.f32 q2,q2,q15 vadd.f32 d6,d6,d7 vstmia r5!,{q0,q1,q2} vstmia r5!,{d6} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 vmax.f32 q12,q12,q2 vmax.f32 d24,d24,d6 b .Lf4end .Lf4lt14: // 13 elems vldmia r0!,{q0,q1,q2} vldmia r0!,{s12} vldmia r2!,{q4,q5,q6} vldmia r2!,{s13} vldmia r3!,{q8,q9,q10} vldmia r3!,{s14} vldmia r6!,{q13,q14,q15} vldmia r6!,{s15} vadd.f32 q0,q0,q4 vadd.f32 q1,q1,q5 vadd.f32 q2,q2,q6 fadds s12,s12,s13 vadd.f32 q0,q0,q8 vadd.f32 q1,q1,q9 vadd.f32 q2,q2,q10 fadds s12,s12,s14 vadd.f32 q0,q0,q13 vadd.f32 q1,q1,q14 vadd.f32 q2,q2,q15 fadds s12,s12,s15 vstmia r5!,{q0,q1,q2} vstmia r5!,{s12} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 vmax.f32 q12,q12,q2 vmax.f32 d24,d24,d6 b .Lf4end .Lf4eq12: // 12 elems vldmia r0!,{q0,q1,q2} vldmia r2!,{q4,q5,q6} vldmia r3!,{q8,q9,q10} vldmia r6!,{q13,q14,q15} vadd.f32 q0,q0,q4 vadd.f32 q1,q1,q5 vadd.f32 q2,q2,q6 vadd.f32 q0,q0,q8 vadd.f32 q1,q1,q9 vadd.f32 q2,q2,q10 vadd.f32 q0,q0,q13 vadd.f32 q1,q1,q14 vadd.f32 q2,q2,q15 vstmia r5!,{q0,q1,q2} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 vmax.f32 q12,q12,q2 b .Lf4end .Lf4lt12: cmp r4,#10 blo .Lf4lt10 beq .Lf4eq10 // 11 elems vldmia r0!,{q0,q1} vldmia r0!,{s8,s9,s10} vldmia r2!,{q4,q5} vldmia r2!,{s24,s25,s26} vldmia r3!,{q8,q9} vldmia r3!,{d20} vldmia r3!,{s11} vldmia r6!,{q13,q14} vldmia r6!,{s12,s13,s14} vadd.f32 q0,q0,q4 vadd.f32 q1,q1,q5 vadd.f32 d4,d4,d12 vadd.f32 s10,s10,s26 vadd.f32 q0,q0,q8 vadd.f32 q1,q1,q9 vadd.f32 d4,d4,d20 vadd.f32 s10,s10,s11 vadd.f32 q0,q0,q13 vadd.f32 q1,q1,q14 vadd.f32 d4,d4,d6 vadd.f32 s10,s10,s14 vstmia r5!,{q0,q1} vstmia r5!,{s8,s9,s10} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 vmax.f32 q12,q12,q2 b .Lf4end .Lf4eq10: // 10 elems vldmia r0!,{q0,q1} vldmia r0!,{d4} vldmia r2!,{q4,q5} vldmia r2!,{d12} vldmia r3!,{q8,q9} vldmia r3!,{d20} vldmia r6!,{q13,q14} vldmia r6!,{d5} vadd.f32 q0,q0,q4 vadd.f32 q1,q1,q5 vadd.f32 d4,d4,d12 vadd.f32 q0,q0,q8 vadd.f32 q1,q1,q9 vadd.f32 d4,d4,d20 vadd.f32 q0,q0,q13 vadd.f32 q1,q1,q14 vadd.f32 d4,d4,d5 vstmia r5!,{q0,q1} vstmia r5!,{d4} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 vmax.f32 d24,d24,d4 b .Lf4end .Lf4lt10: // 9 elems vldmia r0!,{q0,q1} vldmia r0!,{s8} vldmia r2!,{q4,q5} vldmia r2!,{s9} vldmia r3!,{q8,q9} vldmia r3!,{s10} vldmia r6!,{q13,q14} vldmia r6!,{s11} vadd.f32 q0,q0,q4 vadd.f32 q1,q1,q5 fadds s8,s8,s9 vadd.f32 q0,q0,q8 vadd.f32 q1,q1,q9 fadds s8,s8,s10 vadd.f32 q0,q0,q13 vadd.f32 q1,q1,q14 fadds s8,s8,s11 vstmia r5!,{q0,q1} vstmia r5!,{s8} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 vmax.f32 d24,d24,d4 b .Lf4end .Lf4eq8: // 8 elems vldmia r0!,{q0,q1} vldmia r2!,{q4,q5} vldmia r3!,{q8,q9} vldmia r6!,{q13,q14} vadd.f32 q0,q0,q4 vadd.f32 q1,q1,q5 vadd.f32 q0,q0,q8 vadd.f32 q1,q1,q9 vadd.f32 q0,q0,q13 vadd.f32 q1,q1,q14 vstmia r5!,{q0,q1} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 b .Lf4end .Lf4lt8: cmp r4,#4 blo .Lf4lt4 beq .Lf4eq4 cmp r4,#6 blo .Lf4lt6 beq .Lf4eq6 // 7 elems vldmia r0!,{q0} vldmia r0!,{s4,s5,s6} vldmia r2!,{q4} vldmia r2!,{s20,s21,s22} vldmia r3!,{q8} vldmia r3!,{d18} vldmia r3!,{s7} vldmia r6!,{q13} vldmia r6!,{s8,s9,s10} vadd.f32 q0,q0,q4 vadd.f32 d2,d2,d10 vadd.f32 s6,s6,s22 vadd.f32 q0,q0,q8 vadd.f32 d2,d2,d18 vadd.f32 s6,s6,s7 vadd.f32 q0,q0,q13 vadd.f32 d2,d2,d4 vadd.f32 s6,s6,s10 vstmia r5!,{q0} vstmia r5!,{s4,s5,s6} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 b .Lf4end .Lf4eq6: // 6 elems vldmia r0!,{q0} vldmia r0!,{d2} vldmia r2!,{q4} vldmia r2!,{d10} vldmia r3!,{q8} vldmia r3!,{d18} vldmia r6!,{q13} vldmia r6!,{d3} vadd.f32 q0,q0,q4 vadd.f32 d2,d2,d10 vadd.f32 q0,q0,q8 vadd.f32 d2,d2,d18 vadd.f32 q0,q0,q13 vadd.f32 d2,d2,d3 vstmia r5!,{q0} vstmia r5!,{d2} vmax.f32 q12,q12,q0 vmax.f32 d24,d24,d2 b .Lf4end .Lf4lt6: // 5 elems vldmia r0!,{q0} vldmia r0!,{s4} vldmia r2!,{q4} vldmia r2!,{s20} vldmia r3!,{q8} vldmia r3!,{s5} vldmia r6!,{q13} vldmia r6!,{s6} vadd.f32 q0,q0,q4 fadds s4,s4,s20 vadd.f32 q0,q0,q8 fadds s4,s4,s5 vadd.f32 q0,q0,q13 fadds s4,s4,s6 vstmia r5!,{q0} vstmia r5!,{s4} vmax.f32 q12,q12,q0 vmax.f32 d24,d24,d2 b .Lf4end .Lf4eq4: // 4 elems vldmia r0!,{q0} vldmia r2!,{q4} vldmia r3!,{q8} vldmia r6!,{q13} vadd.f32 q0,q0,q4 vadd.f32 q0,q0,q8 vadd.f32 q0,q0,q13 vstmia r5!,{q0} vmax.f32 q12,q12,q0 b .Lf4end .Lf4lt4: cmp r4,#2 blo .Lf4lt2 beq .Lf4eq2 // 3 elems vldmia r0!,{s0,s1,s2} vldmia r2!,{s16,s17,s18} vldmia r3!,{d16} vldmia r3!,{s3} vldmia r6!,{s4,s5,s6} vadd.f32 d0,d0,d8 vadd.f32 s2,s2,s18 vadd.f32 d0,d0,d16 vadd.f32 s2,s2,s3 vadd.f32 d0,d0,d2 vadd.f32 s2,s2,s6 vstmia r5!,{s0,s1,s2} vmax.f32 q12,q12,q0 b .Lf4end .Lf4eq2: // 2 elems vldmia r0!,{d0} vldmia r2!,{d4} vldmia r3!,{d8} vldmia r6!,{d12} vadd.f32 d0,d0,d4 vadd.f32 d0,d0,d8 vadd.f32 d0,d0,d12 vstmia r5!,{d0} vmax.f32 d24,d24,d0 b .Lf4end .Lf4lt2: cmp r4,#0 beq .Lf4eq0 vldmia r0!,{s0} vldmia r2!,{s1} vldmia r3!,{s2} vldmia r6!,{s3} vadd.f32 s0,s0,s1 vadd.f32 s0,s0,s2 vadd.f32 s0,s0,s3 vstmia r5!,{s0} vmax.f32 d24,d24,d0 .Lf4eq0: .Lf4end: vpmax.f32 d24,d24,d25 vpmax.f32 d0,d24,d24 fmrs r0,s0 vpop {d8,d9,d10,d11,d12,d13,d14,d15} pop {r4,r5,r6,r7,r8,lr} bx lr .global neon_foldArrayBy4_lge31 .type neon_foldArrayBy4_lge31, %function neon_foldArrayBy4_lge31: push {r4,r5,r6,r7,r8,lr} vpush {d8,d9,d10,d11,d12,d13,d14,d15} ldr r0,[r0] // ss0 ldrd r2,[r1,#8] // tmp0 ldr r6,[r1,#16] // tmp2 add r2,r0,r2,lsl #2 add r3,r0,r3,lsl #2 add r6,r0,r6,lsl #2 ldrd r4,[r1] // di,dest add r7,r0,r4,lsl #2 // end veor.i32 q12,q12,q12 sub r7,r7,#4*31 cmp r0,r7 bhs .Lendf4loop2 .Lf4loop2: FOLDBY4_CORE FOLDBY4_CORE cmp r0,r7 blo .Lf4loop2 .Lendf4loop2: add r7,r7,#4*16 cmp r0,r7 bhs .Lendf4loop1 .Lf4loop3: FOLDBY4_CORE cmp r0,r7 blo .Lf4loop3 .Lendf4loop3: b .Lendf4loop1 .Lfoldby4sel: .rept 31 .word neon_foldArrayBy4_ll31 .endr .word neon_foldArrayBy4_lge31 /****** * fold array by 5 ******/ .global neon_foldArrayBy5_ll31 .type neon_foldArrayBy5_ll31, %function neon_foldArrayBy5_ll31: push {r4,r5,r6,r7,r8,lr} vpush {d8,d9,d10,d11,d12,d13,d14,d15} ldr r0,[r0] // ss0 ldrd r2,[r1,#8] // tmp0 ldrd r6,[r1,#16] // tmp2 add r2,r0,r2,lsl #2 add r3,r0,r3,lsl #2 add r6,r0,r6,lsl #2 add r7,r0,r7,lsl #2 ldrd r4,[r1] // di,dest add r8,r0,r4,lsl #2 // end veor.i32 q12,q12,q12 sub r8,r8,#4*15 cmp r0,r8 bhs .Lendf5loop1 .Lf5loop1: .macro FOLDBY5_CORE vldmia r0!,{q0,q1,q2,q3} vldmia r2!,{q4,q5,q6,q7} vldmia r3!,{q8,q9,q10,q11} vadd.f32 q0,q0,q4 vadd.f32 q1,q1,q5 vadd.f32 q2,q2,q6 vadd.f32 q3,q3,q7 vadd.f32 q0,q0,q8 vadd.f32 q1,q1,q9 vadd.f32 q2,q2,q10 vadd.f32 q3,q3,q11 vldmia r6!,{q8,q9,q10,q11} vadd.f32 q0,q0,q8 vadd.f32 q1,q1,q9 vadd.f32 q2,q2,q10 vadd.f32 q3,q3,q11 vldmia r7!,{q8,q9,q10,q11} vadd.f32 q0,q0,q8 vadd.f32 q1,q1,q9 vadd.f32 q2,q2,q10 vadd.f32 q3,q3,q11 vstmia r5!,{q0,q1,q2,q3} vmax.f32 q13,q0,q1 vmax.f32 q14,q2,q3 vmax.f32 q12,q12,q13 vmax.f32 q12,q12,q14 .endm FOLDBY5_CORE cmp r0,r8 blo .Lf5loop1 .Lendf5loop1: and r4,r4,#15 cmp r4,#8 blo .Lf5lt8 beq .Lf5eq8 cmp r4,#12 blo .Lf5lt12 beq .Lf5eq12 cmp r4,#14 blo .Lf5lt14 beq .Lf5eq14 // 15 elems vldmia r0!,{q0,q1,q2} vldmia r0!,{s12,s13,s14} vldmia r2!,{q4,q5,q6} vldmia r2!,{s28,s29,s30} vldmia r3!,{q8,q9,q10} vldmia r3!,{d22} vldmia r3, {s15} vldmia r6!,{q13,q14,q15} vadd.f32 q0,q0,q4 vadd.f32 q1,q1,q5 vadd.f32 q2,q2,q6 vadd.f32 d6,d6,d14 vadd.f32 s14,s14,s30 vadd.f32 q0,q0,q8 vadd.f32 q1,q1,q9 vadd.f32 q2,q2,q10 vadd.f32 d6,d6,d22 vadd.f32 s14,s14,s15 vldmia r6!,{s16,s17,s18} vadd.f32 q0,q0,q13 vadd.f32 q1,q1,q14 vadd.f32 q2,q2,q15 vadd.f32 d6,d6,d8 vadd.f32 s14,s14,s18 vldmia r7!,{q13,q14,q15} vldmia r7!,{s16,s17,s18} vadd.f32 q0,q0,q13 vadd.f32 q1,q1,q14 vadd.f32 q2,q2,q15 vadd.f32 d6,d6,d8 vadd.f32 s14,s14,s18 vstmia r5!,{q0,q1,q2} vstmia r5!,{s12,s13,s14} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 vmax.f32 q12,q12,q2 vmax.f32 q12,q12,q3 b .Lf5end .Lf5eq14: // 14 elems vldmia r0!,{q0,q1,q2} vldmia r0!,{d6} vldmia r2!,{q4,q5,q6} vldmia r2!,{d14} vldmia r3!,{q8,q9,q10} vldmia r3!,{d22} vldmia r6!,{q13,q14,q15} vldmia r6!,{d7} vadd.f32 q0,q0,q4 vadd.f32 q1,q1,q5 vadd.f32 q2,q2,q6 vadd.f32 d6,d6,d14 vadd.f32 q0,q0,q8 vadd.f32 q1,q1,q9 vadd.f32 q2,q2,q10 vadd.f32 d6,d6,d22 vadd.f32 q0,q0,q13 vadd.f32 q1,q1,q14 vadd.f32 q2,q2,q15 vadd.f32 d6,d6,d7 vldmia r7!,{q13,q14,q15} vldmia r7!,{d7} vadd.f32 q0,q0,q13 vadd.f32 q1,q1,q14 vadd.f32 q2,q2,q15 vadd.f32 d6,d6,d7 vstmia r5!,{q0,q1,q2} vstmia r5!,{d6} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 vmax.f32 q12,q12,q2 vmax.f32 d24,d24,d6 b .Lf5end .Lf5lt14: // 13 elems vldmia r0!,{q0,q1,q2} vldmia r0!,{s12} vldmia r2!,{q4,q5,q6} vldmia r2!,{s13} vldmia r3!,{q8,q9,q10} vldmia r3!,{s14} vldmia r6!,{q13,q14,q15} vldmia r6!,{s15} vadd.f32 q0,q0,q4 vadd.f32 q1,q1,q5 vadd.f32 q2,q2,q6 fadds s12,s12,s13 vadd.f32 q0,q0,q8 vadd.f32 q1,q1,q9 vadd.f32 q2,q2,q10 fadds s12,s12,s14 vadd.f32 q0,q0,q13 vadd.f32 q1,q1,q14 vadd.f32 q2,q2,q15 fadds s12,s12,s15 vldmia r7!,{q13,q14,q15} vldmia r7!,{s15} vadd.f32 q0,q0,q13 vadd.f32 q1,q1,q14 vadd.f32 q2,q2,q15 fadds s12,s12,s15 vstmia r5!,{q0,q1,q2} vstmia r5!,{s12} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 vmax.f32 q12,q12,q2 vmax.f32 d24,d24,d6 b .Lf5end .Lf5eq12: // 12 elems vldmia r0!,{q0,q1,q2} vldmia r2!,{q3,q4,q5} vldmia r3!,{q6,q7,q8} vldmia r6!,{q9,q10,q11} vldmia r7!,{q13,q14,q15} vadd.f32 q0,q0,q3 vadd.f32 q1,q1,q4 vadd.f32 q2,q2,q5 vadd.f32 q0,q0,q6 vadd.f32 q1,q1,q7 vadd.f32 q2,q2,q8 vadd.f32 q0,q0,q9 vadd.f32 q1,q1,q10 vadd.f32 q2,q2,q11 vadd.f32 q0,q0,q13 vadd.f32 q1,q1,q14 vadd.f32 q2,q2,q15 vstmia r5!,{q0,q1,q2} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 vmax.f32 q12,q12,q2 b .Lf5end .Lf5lt12: cmp r4,#10 blo .Lf5lt10 beq .Lf5eq10 // 11 elems vldmia r0!,{q0,q1} vldmia r0!,{s8,s9,s10} vldmia r2!,{q7,q8} vldmia r2!,{d6} vldmia r2!,{s11} vldmia r3!,{q9,q10} vldmia r3!,{s14,s15,s16} vldmia r6!,{q11} vldmia r6!,{q13} vldmia r6!,{s18,s19,s20} vldmia r7!,{q14} vldmia r7!,{q15} vldmia r7!,{s22,s23,s24} vadd.f32 q0,q0,q7 vadd.f32 q1,q1,q8 vadd.f32 d4,d4,d6 vadd.f32 s10,s10,s11 vadd.f32 q0,q0,q9 vadd.f32 q1,q1,q10 vadd.f32 d4,d4,d7 vadd.f32 s10,s10,s16 vadd.f32 q0,q0,q11 vadd.f32 q1,q1,q13 vadd.f32 d4,d4,d9 vadd.f32 s10,s10,s20 vadd.f32 q0,q0,q14 vadd.f32 q1,q1,q15 vadd.f32 d4,d4,d11 vadd.f32 s10,s10,s24 vstmia r5!,{q0,q1} vstmia r5!,{s8,s9,s10} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 vmax.f32 q12,q12,q2 b .Lf5end .Lf5eq10: // 10 elems vldmia r0!,{q0,q1} vldmia r0!,{d4} vldmia r2!,{q3,q4} vldmia r2!,{d5} vldmia r3!,{q5,q6} vldmia r3!,{d14} vldmia r6!,{q8,q9} vldmia r6!,{d15} vldmia r7!,{q10,q11} vldmia r7!,{d26} vadd.f32 q0,q0,q3 vadd.f32 q1,q1,q4 vadd.f32 d4,d4,d5 vadd.f32 q0,q0,q5 vadd.f32 q1,q1,q6 vadd.f32 d4,d4,d14 vadd.f32 q0,q0,q8 vadd.f32 q1,q1,q9 vadd.f32 d4,d4,d15 vadd.f32 q0,q0,q10 vadd.f32 q1,q1,q11 vadd.f32 d4,d4,d26 vstmia r5!,{q0,q1} vstmia r5!,{d4} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 vmax.f32 d24,d24,d4 b .Lf5end .Lf5lt10: // 9 elems vldmia r0!,{q0,q1} vldmia r0!,{s8} vldmia r2!,{q4,q5} vldmia r2!,{s9} vldmia r3!,{q6,q7} vldmia r3!,{s10} vldmia r6!,{q8,q9} vldmia r6!,{s11} vldmia r7!,{q10,q11} vldmia r7!,{s12} vadd.f32 q0,q0,q4 vadd.f32 q1,q1,q5 fadds s8,s8,s9 vadd.f32 q0,q0,q6 vadd.f32 q1,q1,q7 fadds s8,s8,s10 vadd.f32 q0,q0,q8 vadd.f32 q1,q1,q9 fadds s8,s8,s11 vadd.f32 q0,q0,q10 vadd.f32 q1,q1,q11 fadds s8,s8,s12 vstmia r5!,{q0,q1} vstmia r5!,{s8} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 vmax.f32 d24,d24,d4 b .Lf5end .Lf5eq8: // 8 elems vldmia r0!,{q0,q1} vldmia r2!,{q2,q3} vldmia r3!,{q4,q5} vldmia r6!,{q8,q9} vldmia r7!,{q10,q11} vadd.f32 q0,q0,q2 vadd.f32 q1,q1,q3 vadd.f32 q0,q0,q4 vadd.f32 q1,q1,q5 vadd.f32 q0,q0,q8 vadd.f32 q1,q1,q9 vadd.f32 q0,q0,q10 vadd.f32 q1,q1,q11 vstmia r5!,{q0,q1} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 b .Lf5end .Lf5lt8: cmp r4,#4 blo .Lf5lt4 beq .Lf5eq4 cmp r4,#6 blo .Lf5lt6 beq .Lf5eq6 // 7 elems vldmia r0!,{q0} vldmia r0!,{s4,s5,s6} vldmia r2!,{q2} vldmia r2!,{d6} vldmia r2!,{s7} vldmia r3!,{q4} vldmia r3!,{s20,s21,s22} vldmia r6!,{q6} vldmia r6!,{s28,s29,s30} vldmia r7!,{q8} vldmia r7!,{d7} vldmia r7!,{s31} vadd.f32 q0,q0,q2 vadd.f32 d2,d2,d6 vadd.f32 s6,s6,s7 vadd.f32 q0,q0,q4 vadd.f32 d2,d2,d10 vadd.f32 s6,s6,s22 vadd.f32 q0,q0,q6 vadd.f32 d2,d2,d14 vadd.f32 s6,s6,s30 vadd.f32 q0,q0,q8 vadd.f32 d2,d2,d7 vadd.f32 s6,s6,s31 vstmia r5!,{q0} vstmia r5!,{s4,s5,s6} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 b .Lf5end .Lf5eq6: // 6 elems vldmia r0!,{q0} vldmia r0!,{d2} vldmia r2!,{q2} vldmia r2!,{d6} vldmia r3!,{q4} vldmia r3!,{d10} vldmia r6!,{q6} vldmia r6!,{d14} vldmia r7!,{q8} vldmia r7!,{d15} vadd.f32 q0,q0,q2 vadd.f32 d2,d2,d6 vadd.f32 q0,q0,q4 vadd.f32 d2,d2,d10 vadd.f32 q0,q0,q6 vadd.f32 d2,d2,d14 vadd.f32 q0,q0,q8 vadd.f32 d2,d2,d15 vstmia r5!,{q0} vstmia r5!,{d2} vmax.f32 q12,q12,q0 vmax.f32 d24,d24,d2 b .Lf5end .Lf5lt6: // 5 elems vldmia r0!,{q0} vldmia r0!,{s4} vldmia r2!,{q2} vldmia r2!,{s5} vldmia r3!,{q4} vldmia r3!,{s6} vldmia r6!,{q6} vldmia r6!,{s7} vldmia r7!,{q8} vldmia r7!,{s12} vadd.f32 q0,q0,q2 fadds s4,s4,s5 vadd.f32 q0,q0,q4 fadds s4,s4,s6 vadd.f32 q0,q0,q6 fadds s4,s4,s7 vadd.f32 q0,q0,q8 fadds s4,s4,s12 vstmia r5!,{q0} vstmia r5!,{s4} vmax.f32 q12,q12,q0 vmax.f32 d24,d24,d2 b .Lf5end .Lf5eq4: // 4 elems vldmia r0!,{q0} vldmia r2!,{q4} vldmia r3!,{q8} vldmia r6!,{q13} vldmia r7!,{q14} vadd.f32 q0,q0,q4 vadd.f32 q0,q0,q8 vadd.f32 q0,q0,q13 vadd.f32 q0,q0,q14 vstmia r5!,{q0} vmax.f32 q12,q12,q0 b .Lf5end .Lf5lt4: cmp r4,#2 blo .Lf5lt2 beq .Lf5eq2 // 3 elems vldmia r0!,{s0,s1,s2} vldmia r2!,{d2} vldmia r2!,{s3} vldmia r3!,{s6,s7,s8} vldmia r6!,{s10,s11,s12} vldmia r7!,{s14,s15,s16} vadd.f32 d0,d0,d2 vadd.f32 s2,s2,s3 vadd.f32 d0,d0,d3 vadd.f32 s2,s2,s8 vadd.f32 d0,d0,d5 vadd.f32 s2,s2,s12 vadd.f32 d0,d0,d7 vadd.f32 s2,s2,s16 vstmia r5!,{s0,s1,s2} vmax.f32 q12,q12,q0 b .Lf5end .Lf5eq2: // 2 elems vldmia r0!,{d0} vldmia r2!,{d4} vldmia r3!,{d8} vldmia r6!,{d12} vldmia r7!,{d13} vadd.f32 d0,d0,d4 vadd.f32 d0,d0,d8 vadd.f32 d0,d0,d12 vadd.f32 d0,d0,d13 vstmia r5!,{d0} vmax.f32 d24,d24,d0 b .Lf5end .Lf5lt2: cmp r4,#0 beq .Lf5eq0 vldmia r0!,{s0} vldmia r2!,{s1} vldmia r3!,{s2} vldmia r6!,{s3} vldmia r7!,{s4} vadd.f32 s0,s0,s1 vadd.f32 s0,s0,s2 vadd.f32 s0,s0,s3 vadd.f32 s0,s0,s4 vstmia r5!,{s0} vmax.f32 d24,d24,d0 .Lf5eq0: .Lf5end: vpmax.f32 d24,d24,d25 vpmax.f32 d0,d24,d24 fmrs r0,s0 vpop {d8,d9,d10,d11,d12,d13,d14,d15} pop {r4,r5,r6,r7,r8,lr} bx lr .Lfoldby5sel: .rept 31 .word neon_foldArrayBy5_ll31 .endr .word neon_foldArrayBy5_lge31 .global neon_foldArrayBy5_lge31 .type neon_foldArrayBy5_lge31, %function neon_foldArrayBy5_lge31: push {r4,r5,r6,r7,r8,lr} vpush {d8,d9,d10,d11,d12,d13,d14,d15} ldr r0,[r0] // ss0 ldrd r2,[r1,#8] // tmp0 ldrd r6,[r1,#16] // tmp2 add r2,r0,r2,lsl #2 add r3,r0,r3,lsl #2 add r6,r0,r6,lsl #2 add r7,r0,r7,lsl #2 ldrd r4,[r1] // di,dest add r8,r0,r4,lsl #2 // end veor.i32 q12,q12,q12 sub r8,r8,#4*31 cmp r0,r8 bhs .Lendf5loop2 .Lf5loop2: FOLDBY5_CORE FOLDBY5_CORE cmp r0,r8 blo .Lf5loop2 .Lendf5loop2: add r8,r8,#4*16 cmp r0,r8 bhs .Lendf5loop1 .Lf5loop3: FOLDBY5_CORE cmp r0,r8 blo .Lf5loop3 .Lendf5loop3: b .Lendf5loop1 /***** * fold array by 2 ******/ .global neon_foldArrayBy2_ll31 .type neon_foldArrayBy2_ll31, %function neon_foldArrayBy2_ll31: push {r4,r5,r6,lr} vpush {d8,d9,d10,d11,d12,d13,d14,d15} ldr r0,[r0,#4] // ss1 ldrd r2,[r1,#8] // tmp0 add r2,r0,r2,lsl #2 add r3,r0,r3,lsl #2 ldrd r4,[r1] // di,dest add r6,r2,r4,lsl #2 // end veor.i32 q12,q12,q12 sub r6,r6,#4*15 cmp r2,r6 bhs .Lendf2loop1 .Lf2loop1: .macro FOLDBY2_CORE vldmia r2!,{q0,q1,q2,q3} vldmia r3!,{q4,q5,q6,q7} vadd.f32 q0,q0,q4 vadd.f32 q1,q1,q5 vadd.f32 q2,q2,q6 vadd.f32 q3,q3,q7 vstmia r5!,{q0,q1,q2,q3} vmax.f32 q13,q0,q1 vmax.f32 q14,q2,q3 vmax.f32 q12,q12,q13 vmax.f32 q12,q12,q14 .endm FOLDBY2_CORE cmp r2,r6 blo .Lf2loop1 .Lendf2loop1: and r4,r4,#15 cmp r4,#8 blo .Lf2lt8 beq .Lf2eq8 cmp r4,#12 blo .Lf2lt12 beq .Lf2eq12 cmp r4,#14 blo .Lf2lt14 beq .Lf2eq14 // 15 elems vldmia r2!,{q0,q1,q2} vldmia r2!,{s12,s13,s14} vldmia r3!,{q4,q5,q6} vldmia r3!,{s28,s29} vldmia r3!,{s15} vadd.f32 q0,q0,q4 vadd.f32 q1,q1,q5 vadd.f32 q2,q2,q6 vadd.f32 d6,d6,d14 vadd.f32 s14,s14,s15 vstmia r5!,{q0,q1,q2} vstmia r5!,{s12,s13,s14} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 vmax.f32 q12,q12,q2 vmax.f32 q12,q12,q3 b .Lf2end .Lf2eq14: // 14 elems vldmia r2!,{q0,q1,q2} vldmia r2!,{d6} vldmia r3!,{q4,q5,q6} vldmia r3!,{d14} vadd.f32 q0,q0,q4 vadd.f32 q1,q1,q5 vadd.f32 q2,q2,q6 vadd.f32 d6,d6,d14 vstmia r5!,{q0,q1,q2} vstmia r5!,{d6} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 vmax.f32 q12,q12,q2 vmax.f32 d24,d24,d6 b .Lf2end .Lf2lt14: // 13 elems vldmia r2!,{q0,q1,q2} vldmia r2!,{s12} vldmia r3!,{q4,q5,q6} vldmia r3!,{s13} vadd.f32 q0,q0,q4 vadd.f32 q1,q1,q5 vadd.f32 q2,q2,q6 fadds s12,s12,s13 vstmia r5!,{q0,q1,q2} vstmia r5!,{s12} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 vmax.f32 q12,q12,q2 vmax.f32 d24,d24,d6 b .Lf2end .Lf2eq12: // 12 elems vldmia r2!,{q0,q1,q2} vldmia r3!,{q4,q5,q6} vadd.f32 q0,q0,q4 vadd.f32 q1,q1,q5 vadd.f32 q2,q2,q6 vstmia r5!,{q0,q1,q2} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 vmax.f32 q12,q12,q2 b .Lf2end .Lf2lt12: cmp r4,#10 blo .Lf2lt10 beq .Lf2eq10 // 11 elems vldmia r2!,{q0,q1} vldmia r2!,{s8,s9,s10} vldmia r3!,{q4,q5} vldmia r3!,{s24,s25} vldmia r3!,{s11} vadd.f32 q0,q0,q4 vadd.f32 q1,q1,q5 vadd.f32 d4,d4,d12 vadd.f32 s10,s10,s11 vstmia r5!,{q0,q1} vstmia r5!,{s8,s9,s10} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 vmax.f32 q12,q12,q2 b .Lf2end .Lf2eq10: // 10 elems vldmia r2!,{q0,q1} vldmia r2!,{d4} vldmia r3!,{q4,q5} vldmia r3!,{d12} vadd.f32 q0,q0,q4 vadd.f32 q1,q1,q5 vadd.f32 d4,d4,d12 vstmia r5!,{q0,q1} vstmia r5!,{d4} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 vmax.f32 d24,d24,d4 b .Lf2end .Lf2lt10: // 9 elems vldmia r2!,{q0,q1} vldmia r2!,{s8} vldmia r3!,{q4,q5} vldmia r3!,{s9} vadd.f32 q0,q0,q4 vadd.f32 q1,q1,q5 fadds s8,s8,s9 vstmia r5!,{q0,q1} vstmia r5!,{s8} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 vmax.f32 d24,d24,d4 b .Lf2end .Lf2eq8: // 8 elems vldmia r2!,{q0,q1} vldmia r3!,{q4,q5} vadd.f32 q0,q0,q4 vadd.f32 q1,q1,q5 vstmia r5!,{q0,q1} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 b .Lf2end .Lf2lt8: cmp r4,#4 blo .Lf2lt4 beq .Lf2eq4 cmp r4,#6 blo .Lf2lt6 beq .Lf2eq6 // 7 elems vldmia r2!,{q0} vldmia r2!,{s4,s5,s6} vldmia r3!,{q4} vldmia r3!,{s20,s21} vldmia r3!,{s7} vadd.f32 q0,q0,q4 vadd.f32 d2,d2,d10 vadd.f32 s6,s6,s7 vstmia r5!,{q0} vstmia r5!,{s4,s5,s6} vmax.f32 q12,q12,q0 vmax.f32 q12,q12,q1 b .Lf2end .Lf2eq6: // 6 elems vldmia r2!,{q0} vldmia r2!,{d2} vldmia r3!,{q4} vldmia r3!,{d10} vadd.f32 q0,q0,q4 vadd.f32 d2,d2,d10 vstmia r5!,{q0} vstmia r5!,{d2} vmax.f32 q12,q12,q0 vmax.f32 d24,d24,d2 b .Lf2end .Lf2lt6: // 5 elems vldmia r2!,{q0} vldmia r2!,{s4} vldmia r3!,{q4} vldmia r3!,{s5} vadd.f32 q0,q0,q4 fadds s4,s4,s5 vstmia r5!,{q0} vstmia r5!,{s4} vmax.f32 q12,q12,q0 vmax.f32 d24,d24,d2 b .Lf2end .Lf2eq4: // 4 elems vldmia r2!,{q0} vldmia r3!,{q4} vadd.f32 q0,q0,q4 vstmia r5!,{q0} vmax.f32 q12,q12,q0 b .Lf2end .Lf2lt4: cmp r4,#2 blo .Lf2lt2 beq .Lf2eq2 // 3 elems vldmia r2!,{s0,s1,s2} vldmia r3!,{s16,s17} vldmia r3!,{s3} vadd.f32 d0,d0,d8 vadd.f32 s2,s2,s3 vstmia r5!,{s0,s1,s2} vmax.f32 q12,q12,q0 b .Lf2end .Lf2eq2: // 2 elems vldmia r2!,{d0} vldmia r3!,{d4} vadd.f32 d0,d0,d4 vstmia r5!,{d0} vmax.f32 d24,d24,d0 b .Lf2end .Lf2lt2: cmp r4,#0 beq .Lf2eq0 vldmia r2!,{s0} vldmia r3!,{s1} vadd.f32 s0,s0,s1 vstmia r5!,{s0} vmax.f32 d24,d24,d0 .Lf2eq0: .Lf2end: vpmax.f32 d24,d24,d25 vpmax.f32 d0,d24,d24 fmrs r0,s0 vpop {d8,d9,d10,d11,d12,d13,d14,d15} pop {r4,r5,r6,lr} bx lr .global neon_foldArrayBy2_lge31 .type neon_foldArrayBy2_lge31, %function neon_foldArrayBy2_lge31: push {r4,r5,r6,lr} vpush {d8,d9,d10,d11,d12,d13,d14,d15} ldr r0,[r0,#4] // ss1 ldrd r2,[r1,#8] // tmp0 add r2,r0,r2,lsl #2 add r3,r0,r3,lsl #2 ldrd r4,[r1] // di,dest add r6,r2,r4,lsl #2 // end veor.i32 q12,q12,q12 sub r6,r6,#4*31 cmp r2,r6 bhs .Lendf2loop2 .Lf2loop2: FOLDBY2_CORE FOLDBY2_CORE cmp r2,r6 blo .Lf2loop2 .Lendf2loop2: add r6,r6,#4*16 cmp r2,r6 bhs .Lendf2loop1 .Lf2loop3: FOLDBY2_CORE cmp r2,r6 blo .Lf2loop3 .Lendf2loop3: b .Lendf2loop1 .Lfoldby2sel: .rept 31 .word neon_foldArrayBy2_ll31 .endr .word neon_foldArrayBy2_lge31 .align 2 .Lname: .string "opt NEON" .align 2 .global neonFoldMain neonFoldMain: .word .Lfoldby3sel .word .Lfoldby4sel .word .Lfoldby5sel .word .Lfoldby2sel .word .Lfoldby2sel .word .Lname /* * _Z21neon_GetPowerSpectrumPA2_fPfi.S * Author: Mateusz Szpakowski */ .align 2 .global _Z21neon_GetPowerSpectrumPA2_fPfi .type _Z21neon_GetPowerSpectrumPA2_fPfi, %function _Z21neon_GetPowerSpectrumPA2_fPfi: push {r4,r5} vpush {d8,d9,d10,d11,d12,d13,d14,d15} ldr r3,.LGOTa .LPICa: add r3,pc,r3 ldr r4,.LGOTa+4 ldr r4,[r3,r4] add r5,r2,r2,lsl #1 fldd d0,[r4,#32] fmsr s4,r5 fuitod d1,s4 faddd d0,d0,d1 fstd d0,[r4,#32] cmp r2,#4096 blo .Lsecondversion add r2,r0,r2, lsl #3 sub r2,r2,#31*8 /* r0 - freqData * r1 - PowerSpectrum * r2 - end of freqData */ cmp r0,r2 bhs .Lendmainloopa .Lmainloopa: pld [r0,#128] vldmia r0!,{q0,q1,q2,q3,q4,q5,q6,q7} vmul.f32 q0,q0,q0 vmul.f32 q1,q1,q1 vmul.f32 q2,q2,q2 vmul.f32 q3,q3,q3 vmul.f32 q4,q4,q4 vmul.f32 q5,q5,q5 vmul.f32 q6,q6,q6 vmul.f32 q7,q7,q7 vpadd.f32 d16,d0,d1 vpadd.f32 d17,d2,d3 vpadd.f32 d18,d4,d5 vpadd.f32 d19,d6,d7 vpadd.f32 d20,d8,d9 vpadd.f32 d21,d10,d11 vpadd.f32 d22,d12,d13 vpadd.f32 d23,d14,d15 pld [r0,#128] vldmia r0!,{q0,q1,q2,q3,q4,q5,q6,q7} vstmia r1!,{q8,q9,q10,q11} vmul.f32 q0,q0,q0 vmul.f32 q1,q1,q1 vmul.f32 q2,q2,q2 vmul.f32 q3,q3,q3 vmul.f32 q4,q4,q4 vmul.f32 q5,q5,q5 vmul.f32 q6,q6,q6 vmul.f32 q7,q7,q7 vpadd.f32 d16,d0,d1 vpadd.f32 d17,d2,d3 vpadd.f32 d18,d4,d5 vpadd.f32 d19,d6,d7 vpadd.f32 d20,d8,d9 vpadd.f32 d21,d10,d11 vpadd.f32 d22,d12,d13 vpadd.f32 d23,d14,d15 vstmia r1!,{q8,q9,q10,q11} cmp r0,r2 blo .Lmainloopa .Lendmainloopa: add r2,r2,#8*24 bhs .Lendsmallloopa .Lsmallloopa: vldmia r0!,{q0,q1,q2,q3} vmul.f32 q0,q0,q0 vmul.f32 q1,q1,q1 vmul.f32 q2,q2,q2 vmul.f32 q3,q3,q3 vpadd.f32 d16,d0,d1 vpadd.f32 d17,d2,d3 vpadd.f32 d18,d4,d5 vpadd.f32 d19,d6,d7 vstmia r1!,{q8,q9,q10,q11} cmp r0,r2 blo .Lsmallloopa .Lendsmallloopa: add r2,r2,#8*7 cmp r0,r2 beq .Lendmicroloop .Lmicroloop: fldmias r0!,{s0,s1} fmuls s2,s0,s0 fmacs s2,s1,s1 fstmias r1!,{s2} cmp r0,r2 blo .Lmicroloop .Lendmicroloop: mov r0,#0 vpop {d8,d9,d10,d11,d12,d13,d14,d15} pop {r4,r5} bx lr /* * second version */ .Lsecondversion: add r2,r0,r2, lsl #3 sub r2,r2,#31*8 /* r0 - freqData * r1 - PowerSpectrum * r2 - end of freqData */ cmp r0,r2 bhs .Lendmainloop2 .Lmainloop2: vldmia r0!,{q0,q1,q2,q3,q4,q5,q6,q7} vldmia r0!,{q8,q9,q10,q11,q12,q13,q14,q15} vuzp.32 q0,q1 vuzp.32 q2,q3 vuzp.32 q4,q5 vuzp.32 q6,q7 vuzp.32 q8,q9 vuzp.32 q10,q11 vuzp.32 q12,q13 vuzp.32 q14,q15 vmul.f32 q0,q0,q0 vmul.f32 q2,q2,q2 vmul.f32 q4,q4,q4 vmul.f32 q6,q6,q6 vmul.f32 q8,q8,q8 vmul.f32 q10,q10,q10 vmul.f32 q12,q12,q12 vmul.f32 q14,q14,q14 vmla.f32 q0,q1,q1 vmla.f32 q2,q3,q3 vmla.f32 q4,q5,q5 vmla.f32 q6,q7,q7 vmla.f32 q8,q9,q9 vmla.f32 q10,q11,q11 vmla.f32 q12,q13,q13 vmla.f32 q14,q15,q15 vstmia r1!,{q0} vstmia r1!,{q2} vstmia r1!,{q4} vstmia r1!,{q6} vstmia r1!,{q8} vstmia r1!,{q10} vstmia r1!,{q12} vstmia r1!,{q14} cmp r0,r2 blo .Lmainloop2 .Lendmainloop2: add r2,r2,#8*24 bhs .Lendsmallloop2 .Lsmallloop2: vldmia r0!,{q0,q1,q2,q3} vmul.f32 q0,q0,q0 vmul.f32 q1,q1,q1 vmul.f32 q2,q2,q2 vmul.f32 q3,q3,q3 vpadd.f32 d16,d0,d1 vpadd.f32 d17,d2,d3 vpadd.f32 d18,d4,d5 vpadd.f32 d19,d6,d7 vstmia r1!,{q8,q9,q10,q11} cmp r0,r2 blo .Lsmallloop2 .Lendsmallloop2: add r2,r2,#8*7 cmp r0,r2 beq .Lendmicroloop .Lmicroloop2: fldmias r0!,{s0,s1} fmuls s2,s0,s0 fmacs s2,s1,s1 fstmias r1!,{s2} cmp r0,r2 blo .Lmicroloop2 b .Lendmicroloop .align 2 .LGOTa: .word _GLOBAL_OFFSET_TABLE_-(.LPICa+8) .word analysis_state(GOT) #endif // __arm__ boinc-app-seti_8.00~svn3701.orig/client/vector/analyzeFuncs_x86_64.cpp0000644000175000017500000001577112635114271025473 0ustar locutuslocutus// Copyright 2003-2005 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // AMD optimizations by Evandro Menezes // $Id: analyzeFuncs_x86_64.cpp,v 1.1.2.4 2007/05/31 22:03:13 korpela Exp $ #if defined(__i386__) || defined(__x86_64__) || defined (_M_AMD64) || defined(_M_IX86) #include "sah_config.h" #include #include #include #include #include "x86_ops.h" #include "x86_float4.h" #ifndef M_PI #define M_PI 3.14159265358979323846 #endif #include "seti.h" #include "s_util.h" #include "worker.h" // chirp_rate is in Hz per second int v_vChirpData_x86_64( sah_complex * fp_DataArray, sah_complex * fp_ChirpDataArray, int ChirpRateInd, double chirp_rate, int ul_NumDataPoints, double sample_rate ) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("v_vChirpData_x86_64()"); #endif double recsqtw_Sample_rate = (double)(1.0/(2.0*(sample_rate*sample_rate))); static const int as [4] __attribute__((aligned(16)))= {INT_MIN, 0, INT_MIN, 0} ; // {-, +, -, +} char *cblock = (char *)alloca(11*16); cblock+=(16-((ssize_t)cblock % 16)); x86_m128 *fblock=reinterpret_cast(cblock); x86_m128d *dblock=reinterpret_cast(cblock); #define CC dblock[0] #define DD dblock[1] #define cc fblock[2] #define dd fblock[3] #define ri fblock[4] #define ri1 fblock[5] #define ri2 fblock[6] #define ss fblock[7] #define zz fblock[8] memcpy(&(ss),as,sizeof(as)); zz = _mm_setzero_ps (); int i, j; // float c, d, real, imag; //float time; // using float causes too low precision double time; //float ang; // using float causes too low precision double ang; double aC [] __attribute__((aligned(16))) = {0, 0}; double aD [] __attribute__((aligned(16))) = {0, 0} ; //float chirpInvariant = (float)(0.5*chirp_rate/(sample_rate*sample_rate)); double chirpInvariant = chirp_rate*recsqtw_Sample_rate; //using float causes too low precision if (chirp_rate == 0) { memcpy(fp_ChirpDataArray, fp_DataArray, (int)ul_NumDataPoints * 2 * sizeof(float) ); // NOTE INT CAST } else { for (i = 0, j = 0; i < (ul_NumDataPoints - 2); i += 2, j += 2) { // _mm_prefetch (fp_DataArray + i + 32, _MM_HINT_T0); _mm_prefetch ((char *) (fp_ChirpDataArray + i) + 384, _MM_HINT_T0); time = (double)j*j; ang = time*chirpInvariant; ang -= std::floor(ang); ang *= M_PI*2.0; //#ifndef HAVE_SINCOS aC [0] = cos (ang); aD [0] = sin (ang); /*#else // using sincos causes too low precision sincos (ang, aD + 0, aC + 0); #endif */ time = (double)(j + 1)*(j + 1); ang = chirpInvariant*time; ang -= std::floor(ang); ang *= M_PI*2.0; //#ifndef HAVE_SINCOS aC [1] = cos (ang); aD [1] = sin (ang); /*#else // using sincos causes too low precision sincos (ang, aD + 1, aC + 1); #endif */ CC = _mm_loadu_pd (aC); DD = _mm_loadu_pd (aD); cc = _mm_cvtpd_ps (CC); dd = _mm_cvtpd_ps (DD); cc = _mm_unpacklo_ps (cc, cc); dd = _mm_unpacklo_ps (dd, dd); // Sometimes chirping is done in place. // We don't want to overwrite data prematurely. // real = fp_DataArray[i] * c - fp_DataArray[i+1] * d; // imag = fp_DataArray[i] * d + fp_DataArray[i+1] * c; ri1 = _mm_loadu_ps ((float *)(fp_DataArray + i)); ri2 = _mm_shuffle_ps (ri1, ri1, _MM_SHUFFLE (2, 3, 0, 1)); ri2 = _mm_xor_ps (ri2, ss); ri1 = _mm_mul_ps (ri1, cc); ri2 = _mm_mul_ps (ri2, dd); ri = _mm_add_ps (ri1, ri2); // fp_ChirpDataArray[i] = real; // fp_ChirpDataArray[i+1] = imag; _mm_storeu_ps ((float *)(fp_ChirpDataArray + i), ri); } for (; i < ul_NumDataPoints; i ++, j++) { // _mm_prefetch (fp_DataArray + i + 16, _MM_HINT_T0); _mm_prefetch ((char *) (fp_ChirpDataArray + i) + 384, _MM_HINT_T0); time = (double)j*j; ang = chirpInvariant*time; ang -= std::floor(ang); ang *= M_PI*2.0; //#ifndef HAVE_SINCOS aC [0] = cos (ang); aC [1] = sin (ang); /*#else // using sincos causes too low precision sincos (ang, aC + 0, aC + 1); #endif */ CC = _mm_loadu_pd (aC); cc = _mm_cvtpd_ps (CC); cc = _mm_unpacklo_ps (cc, cc); dd = _mm_movehl_ps (zz, cc); // Sometimes chirping is done in place. // We don't want to overwrite data prematurely. // real = fp_DataArray[i] * c - fp_DataArray[i+1] * d; // imag = fp_DataArray[i] * d + fp_DataArray[i+1] * c; ri1 = _mm_loadl_pi (zz, (__m64 *) (fp_DataArray + i)); ri2 = _mm_shuffle_ps (ri1, ri1, _MM_SHUFFLE (2, 3, 0, 1)); ri2 = _mm_xor_ps (ri2, ss); ri1 = _mm_mul_ps (ri1, cc); ri2 = _mm_mul_ps (ri2, dd); ri = _mm_add_ps (ri1, ri2); // fp_ChirpDataArray[i] = real; // fp_ChirpDataArray[i+1] = imag; _mm_storel_pi ((__m64 *) (fp_ChirpDataArray + i), ri); } } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } #endif boinc-app-seti_8.00~svn3701.orig/client/vector/analyzeFuncs_sse3.cpp0000644000175000017500000002513412313644616025410 0ustar locutuslocutus/****************** * * analyzeFuncs_SSE3.cpp * * Description: Intel SSE3 (Prescott New Instruction) optimzized functions * CPUs: Intel Pentium IV Model 3+ * */ // Copyright 2007 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "sah_config.h" // The following is empty if USE_INTRINSICS is not defined #ifdef USE_INTRINSICS #include #include #ifdef HAVE_INTRIN_H #include #endif #ifdef HAVE_PMMINTRIN_H #include #endif #include #include #include "s_util.h" #include "x86_float4.h" #include "analyzeFuncs_vector.h" #include "analyzeFuncs.h" __inline __m128 vec_recip3(__m128 v) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("vec_recip3()"); #endif // obtain estimate __m128 estimate = _mm_rcp_ps( v ); // one round of Newton-Raphson __m128 rv=_mm_add_ps(_mm_mul_ps(_mm_sub_ps(ONE, _mm_mul_ps(estimate, v)), estimate), estimate); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return rv; } // ============================================================================= // // sse3_vChirpData // version by: Alex Kan // http://tbp.berkeley.edu/~alexkan/seti/ // int sse3_ChirpData_ak( sah_complex * cx_DataArray, sah_complex * cx_ChirpDataArray, int chirp_rate_ind, double chirp_rate, int ul_NumDataPoints, double sample_rate ) { int i; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("sse3_ChirpData_ak()"); #endif if (chirp_rate_ind == 0) { memcpy(cx_ChirpDataArray, cx_DataArray, (int)ul_NumDataPoints * sizeof(sah_complex) ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } int vEnd; double srate = chirp_rate * 0.5 / (sample_rate * sample_rate); __m128d rate = _mm_set1_pd(chirp_rate * 0.5 / (sample_rate * sample_rate)); __m128d roundVal = _mm_set1_pd(srate >= 0.0 ? TWO_TO_52 : -TWO_TO_52); // main vectorised loop vEnd = ul_NumDataPoints - (ul_NumDataPoints & 3); for (i = 0; i < vEnd; i += 4) { const float *data = (const float *) (cx_DataArray + i); float *chirped = (float *) (cx_ChirpDataArray + i); __m128d di = _mm_set1_pd(i); __m128d a1 = _mm_add_pd(_mm_set_pd(1.0, 0.0), di); __m128d a2 = _mm_add_pd(_mm_set_pd(3.0, 2.0), di); __m128 d1, d2; __m128 cd1, cd2; __m128 td1, td2; __m128 x; __m128 y; __m128 s; __m128 c; __m128 m; // load the signal to be chirped prefetchnta((const void *)( data+32 )); d1 = _mm_load_ps(data); d2 = _mm_load_ps(data+4); // calculate the input angle a1 = _mm_mul_pd(_mm_mul_pd(a1, a1), rate); a2 = _mm_mul_pd(_mm_mul_pd(a2, a2), rate); // reduce the angle to the range (-0.5, 0.5) a1 = _mm_sub_pd(a1, _mm_sub_pd(_mm_add_pd(a1, roundVal), roundVal)); a2 = _mm_sub_pd(a2, _mm_sub_pd(_mm_add_pd(a2, roundVal), roundVal)); // convert pair of packed double into packed single x = _mm_movelh_ps(_mm_cvtpd_ps(a1), _mm_cvtpd_ps(a2)); // square to the range [0, 0.25) y = _mm_mul_ps(x, x); // perform the initial polynomial approximations s = _mm_mul_ps(_mm_add_ps(_mm_mul_ps(_mm_add_ps(_mm_mul_ps(_mm_add_ps(_mm_mul_ps(y, SS4), SS3), y), SS2), y), SS1), x); c = _mm_add_ps(_mm_mul_ps(_mm_add_ps(_mm_mul_ps(_mm_add_ps(_mm_mul_ps(y, CC3), CC2), y), CC1), y), ONE); // perform first angle doubling x = _mm_sub_ps(_mm_mul_ps(c, c), _mm_mul_ps(s, s)); y = _mm_mul_ps(_mm_mul_ps(s, c), TWO); // calculate scaling factor to correct the magnitude // m1 = vec_nmsub(y1, y1, vec_nmsub(x1, x1, TWO)); // m2 = vec_nmsub(y2, y2, vec_nmsub(x2, x2, TWO)); m = vec_recip3(_mm_add_ps(_mm_mul_ps(x, x), _mm_mul_ps(y, y))); // perform second angle doubling c = _mm_sub_ps(_mm_mul_ps(x, x), _mm_mul_ps(y, y)); s = _mm_mul_ps(_mm_mul_ps(y, x), TWO); // correct the magnitude (final sine / cosine approximations) s = _mm_mul_ps(s, m); c = _mm_mul_ps(c, m); // chirp the data cd1 = _mm_shuffle_ps(c, c, 0x50); cd2 = _mm_shuffle_ps(c, c, 0xfa); cd1 = _mm_mul_ps(cd1, d1); cd2 = _mm_mul_ps(cd2, d2); d1 = _mm_shuffle_ps(d1, d1, 0xb1); d2 = _mm_shuffle_ps(d2, d2, 0xb1); td1 = _mm_shuffle_ps(s, s, 0x50); td2 = _mm_shuffle_ps(s, s, 0xfa); td1 = _mm_mul_ps(td1, d1); td2 = _mm_mul_ps(td2, d2); cd1 = _mm_addsub_ps(cd1, td1); cd2 = _mm_addsub_ps(cd2, td2); // store chirped values _mm_stream_ps(chirped, cd1); _mm_stream_ps(chirped+4, cd2); } _mm_sfence(); // handle tail elements with scalar code for ( ; i < ul_NumDataPoints; ++i) { double angle = srate * i * i * 0.5; double s = sin(angle); double c = cos(angle); float re = cx_DataArray[i][0]; float im = cx_DataArray[i][1]; cx_ChirpDataArray[i][0] = re * c - im * s; cx_ChirpDataArray[i][1] = re * s + im * c; } analysis_state.FLOP_counter+=12.0*ul_NumDataPoints; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } // ============================================================================= // // JWS: alternate SSE3 chirp // // Using Mendenhall Faster SinCos, coding based on // version 8 v_vChirpData for SSE3 by Alex Kan // int sse3_ChirpData_ak8( sah_complex * cx_DataArray, sah_complex * cx_ChirpDataArray, int chirp_rate_ind, double chirp_rate, int ul_NumDataPoints, double sample_rate ) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("sse3_ChirpData_ak8()"); #endif int i; if (chirp_rate_ind == 0) { memcpy(cx_ChirpDataArray, cx_DataArray, (int)ul_NumDataPoints * sizeof(sah_complex) ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } int vEnd; double srate = chirp_rate * 0.5 / (sample_rate * sample_rate); __m128d rate = _mm_set1_pd(chirp_rate * 0.5 / (sample_rate * sample_rate)); __m128d roundVal = _mm_set1_pd(srate >= 0.0 ? TWO_TO_52 : -TWO_TO_52); __m128d DFOUR = _mm_set_pd(4.0, 4.0); // main vectorised loop vEnd = ul_NumDataPoints - (ul_NumDataPoints & 3); __m128d di1 = _mm_set_pd(2.0, 0.0); // set time patterns for eventual moveldup/movehdup __m128d di2 = _mm_set_pd(3.0, 1.0); for (i = 0; i < vEnd; i += 4) { const float *d = (const float *) (cx_DataArray + i); float *cd = (float *) (cx_ChirpDataArray + i); __m128d a1, a2; __m128 d1, d2; __m128 cd1, cd2; __m128 td1, td2; __m128 x; __m128 y; __m128 z; __m128 s; __m128 c; __m128 m; // load the signal to be chirped d1 = _mm_load_ps(d); d2 = _mm_load_ps(d+4); // calculate the input angle a1 = _mm_mul_pd(_mm_mul_pd(di1, di1), rate); a2 = _mm_mul_pd(_mm_mul_pd(di2, di2), rate); // update times for next di1 = _mm_add_pd(di1, DFOUR); di2 = _mm_add_pd(di2, DFOUR); // reduce the angle to the range (-0.5, 0.5) a1 = _mm_sub_pd(a1, _mm_sub_pd(_mm_add_pd(a1, roundVal), roundVal)); a2 = _mm_sub_pd(a2, _mm_sub_pd(_mm_add_pd(a2, roundVal), roundVal)); // convert pair of packed double into packed single x = _mm_movelh_ps(_mm_cvtpd_ps(a1), _mm_cvtpd_ps(a2)); // 3 1 2 0 // square to the range [0, 0.25) y = _mm_mul_ps(x, x); // perform the initial polynomial approximations, Estrin's method z = _mm_mul_ps(y, y); s = _mm_mul_ps(_mm_add_ps(_mm_mul_ps(_mm_add_ps(_mm_mul_ps(y, SS4F), SS3F), z), _mm_add_ps(_mm_mul_ps(y, SS2F), SS1F)), x); c = _mm_add_ps(_mm_mul_ps(_mm_add_ps(_mm_mul_ps(y, CC3F), CC2F), z), _mm_add_ps(_mm_mul_ps(y, CC1F), ONE)); // perform first angle doubling x = _mm_sub_ps(_mm_mul_ps(c, c), _mm_mul_ps(s, s)); y = _mm_mul_ps(_mm_mul_ps(s, c), TWO); // calculate scaling factor to correct the magnitude m = _mm_sub_ps(_mm_sub_ps(TWO, _mm_mul_ps(x, x)), _mm_mul_ps(y, y)); // perform second angle doubling c = _mm_sub_ps(_mm_mul_ps(x, x), _mm_mul_ps(y, y)); s = _mm_mul_ps(_mm_mul_ps(y, x), TWO); // correct the magnitude (final sine / cosine approximations) c = _mm_mul_ps(c, m); // c3 c1 c2 c0 s = _mm_mul_ps(s, m); // chirp the data cd1 = _mm_moveldup_ps(c); // c1 c1 c0 c0 cd2 = _mm_movehdup_ps(c); // c3 c3 c2 c2 cd1 = _mm_mul_ps(cd1, d1); // c1.i1 c1.r1 c0.i0 c0.r0 cd2 = _mm_mul_ps(cd2, d2); // c3.i3 c3.r3 c2.i2 c2.r2 d1 = _mm_shuffle_ps(d1, d1, 0xb1); d2 = _mm_shuffle_ps(d2, d2, 0xb1); td1 = _mm_moveldup_ps(s); td2 = _mm_movehdup_ps(s); td1 = _mm_mul_ps(td1, d1); td2 = _mm_mul_ps(td2, d2); cd1 = _mm_addsub_ps(cd1, td1); cd2 = _mm_addsub_ps(cd2, td2); // store chirped values _mm_stream_ps(cd, cd1); _mm_stream_ps(cd+4, cd2); } // handle tail elements with scalar code for (; i < ul_NumDataPoints; ++i) { double angle = srate * i * i * 0.5; double s = sin(angle); double c = cos(angle); float re = cx_DataArray[i][0]; float im = cx_DataArray[i][1]; cx_ChirpDataArray[i][0] = re * c - im * s; cx_ChirpDataArray[i][1] = re * s + im * c; } analysis_state.FLOP_counter+=12.0*ul_NumDataPoints; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } #endif // USE_INTRINSICS boinc-app-seti_8.00~svn3701.orig/client/vector/avxcheck.asm0000644000175000017500000000146511566257502023607 0ustar locutuslocutus; AVX detection based on section 2.2 of "Intel Advanced Vector Extensions Programming Reference" ; ; MASM source needed for 64 bit builds with MicroSoft tools PUBLIC avxSupported _TEXT SEGMENT avxSupported PROC mov eax, 1 cpuid and ecx, 018000000H cmp ecx, 018000000H ; check both OSXSAVE and AVX feature flags jne NOSUPPORT xor ecx, ecx ; specify 0 for XFEATURE_ENABLED_MASK register xgetbv ; result in EDX:EAX and eax, 06H cmp eax, 06H ; check OS has enabled both XMM and YMM state support jne NOSUPPORT mov eax, 1 jmp DONE NOSUPPORT: mov eax, 0 DONE: ret avxSupported ENDP _TEXT ENDS ENDboinc-app-seti_8.00~svn3701.orig/client/vector/analyzeFuncs_vector.cpp0000644000175000017500000015674613050667044026052 0ustar locutuslocutus // Copyright (c) 1999-2006 Regents of the University of California // // FFTW: Copyright (c) 2003,2006 Matteo Frigo // Copyright (c) 2003,2006 Massachusets Institute of Technology // // fft8g.[cpp,h]: Copyright (c) 1995-2001 Takya Ooura // 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, 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; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions // as an alternative to FFTW and distribute a linked executable and // source code. You must obey the GNU General Public License in all // respects for all of the code used other than the FFT library itself. // Any modification required to support these libraries must be distributed // under the terms of this license. If you modify this program, you may extend // this exception to your version of the program, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. Please be aware that FFTW is not covered by this exception, // therefore you may not use FFTW in any derivative work so modified without // permission of the authors of FFTW. // // $Id: analyzeFuncs_vector.cpp,v 1.1.2.29 2007/08/16 10:13:56 charlief Exp $ #include "sah_config.h" #ifdef _WIN32 #define uint32_t unsigned long #endif #include #include #include #ifdef __APPLE_CC__ #define isnan std::isnan #endif #include #include #ifdef HAVE_FLOAT_H #include #endif #ifdef HAVE_FLOATINGPOINT_H #include #endif #ifdef HAVE_IEEEFP_H #include #endif #include #include "util.h" #include "s_util.h" #include "boinc_api.h" #ifdef BOINC_APP_GRAPHICS #include "sah_gfx_main.h" #endif #include "diagnostics.h" #include "filesys.h" #include "str_replace.h" #include "sighandler.h" #include "analyzeFuncs.h" #include "analyzeFuncs_vector.h" #include "hires_timer.h" #include "chirpfft.h" #include "analyzePoT.h" #include "pulsefind.h" #include "sincos.h" #ifdef USE_ASMLIB #include "asmlib.h" #endif #ifndef M_PI #define M_PI 3.14159265358979323846 #endif #ifdef __APPLE_CC__ #include #ifdef HAVE___ISNAN #define isnotnan(x) (!isnan(x)) #else #define isnotnan(x) ((x) == (x)) #endif #endif #ifndef __APPLE_CC__ #if defined(HAVE__ISNAN) #define isnotnan(x) (!_isnan(x)) #elif defined(HAVE_ISNAN) #define isnotnan(x) (!isnan(x)) #elif defined(HAVE___ISNAN) #define isnotnan(x) (!__isnan(x)) #else #define isnotnan(x) ((x) == (x)) #endif #endif static bool do_print; // Bit patterns to compare host capabilities and what SIMD capability a routine needs #define BA_ANY 0x00000001 // any CPU OK #define BA_MMX 0x00000002 #define BA_SSE 0x00000004 #define BA_SSE2 0x00000008 #define BA_SSE3 0x00000010 #define BA_3Dnow 0x00000020 #define BA_3DnowP 0x00000040 #define BA_MMX_P 0x00000080 #define BA_SSSE3 0x00000100 #define BA_SSE41 0x00000200 #define BA_SSE4a 0x00000400 #define BA_SSE42 0x00000800 #define BA_XOP 0x00001001 #define BA_AVX 0x00002000 #define BA_FMA 0x00004000 #define BA_FMA4 0x00008000 #define BA_ALTVC 0x00100000 #define BA_NEON 0x00200000 #define BA_VFP 0x00400000 #define BA_VFPV3 0x00800000 #define BA_VFPV3D16 0x01000000 #define BA_VFPV4 0x02000000 #define BA_VFPV4D16 0x04000000 uint32_t CPUCaps = BA_ANY; /*********************************** *JWS: Temporary hack for AVX support, based on section 2.2 of Intel 319433-010.pdf * (Intel Advanced Vector Extensions Programming Reference) * * Note this does not check for whether the CPU supports cpuid, etc. so must * not be used unless such details have already been confirmed. */ #if defined(USE_AVX) int avxSupported(void) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("avxSupported()"); #endif int retval = 1; #if defined(__APPLE_CC__) int avx1=0; int avx2=0; size_t length=sizeof(int); int error; error=sysctlbyname("hw.optional.avx1_0",&avx1,&length,NULL,0); error=sysctlbyname("hw.optional.avx2_0",&avx2,&length,NULL,0); retval=(avx1||avx2); #elif defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ > 3)) || (__GNUC__ > 4)) #if defined(__i386__) && (defined(__PIC__) || defined(__pic__)) // EBX can't be clobbered on linux PIC. __asm__ ( "pushl %ebx \n\t" ); #endif __asm__ ( "\n\t" "movl $1, %%eax \n\t" "cpuid \n\t" "andl $0x18000000, %%ecx \n\t" "cmpl $0x18000000, %%ecx \n\t" "jne 1f \n\t" "xorl %%ecx, %%ecx \n\t" "xgetbv \n\t" "andl $6, %%eax \n\t" "cmpl $6, %%eax \n\t" "jne 1f \n\t" "movl $1, %0 \n\t" "jmp 2f \n\t" "1: \n\t" "movl $0, %0 \n\t" "2: \n\t" # if defined(_WIN64) || defined(__LP64__) || defined (__x86_64__) : "=g" (retval) :: "%rax", "%rbx", "%rcx", "%rdx" # elif defined(__i386__) && (defined(__PIC__) || defined(__pic__)) "popl %%ebx \n\t" : "=g" (retval) :: "%eax", "%ecx", "%edx" # else : "=g" (retval) :: "%eax", "%ebx", "%ecx", "%edx" # endif ); #elif (_MSC_VER >= 1600) && !defined(_WIN64) _asm { mov eax, 1 cpuid and ecx, 018000000H cmp ecx, 018000000H jne NOSUPPORT xor ecx, ecx xgetbv and eax, 06H cmp eax, 06H jne NOSUPPORT mov retval, 1 jmp DONE NOSUPPORT: mov retval, 0 DONE: }; #endif // compiler #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return retval; } #endif // USE_AVX /********************** */ void SetCapabilities(void) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("SetCapabilities()"); #endif #if defined(__APPLE_CC__) // OS X assumes MMX, SSE and SSE2 are present on Intel processors // SSE3 and Altivec are optional #if defined(__i386__) || defined(__x86_64__) CPUCaps |= (BA_MMX|BA_SSE|BA_SSE2); int sse3flag=0; size_t length=sizeof(sse3flag); int error=sysctlbyname("hw.optional.sse3",&sse3flag,&length,NULL,0); if (sse3flag && !error) CPUCaps |= BA_SSE3; #else // PowerPC int altivecflag=0; size_t length=sizeof(altivecflag); int error=sysctlbyname("hw.optional.altivec",&altivecflag,&length,NULL,0); if (altivecflag && !error) CPUCaps |= BA_ALTVC; #endif #elif defined( USE_BHCPUID ) CPU_INFO theCPU; if (theCPU.mmx()) CPUCaps |= BA_MMX; if (theCPU.sse()) CPUCaps |= BA_SSE; if (theCPU.sse2()) CPUCaps |= BA_SSE2; if (theCPU.sse3()) CPUCaps |= BA_SSE3; if (theCPU._3Dnow()) CPUCaps |= BA_3Dnow; if (theCPU._3DnowPlus()) CPUCaps |= BA_3DnowP; if (theCPU.mmxPlus()) CPUCaps |= BA_MMX_P; #elif defined( USE_ASMLIB ) int dp = DetectProcessor(); if (dp & 0x00800000) CPUCaps |= BA_MMX; if ((dp & 0x02000800) == 0x02000800) CPUCaps |= BA_SSE; if ((dp & 0x04000800) == 0x04000800) CPUCaps |= BA_SSE2; if ((dp & 0x08000800) == 0x08000800) CPUCaps |= BA_SSE3; if (dp & 0x80000000) CPUCaps |= BA_3Dnow; if (dp & 0x40000000) CPUCaps |= BA_3DnowP; if (dp & 0x20000000) CPUCaps |= BA_MMX_P; #if defined(USE_AVX) if ((dp & 0x00000800) && avxSupported()) CPUCaps |= BA_AVX; #endif #elif defined(__i386__) || defined (__x86_64__) || defined(_M_X64) /* we're hoping to rely on signal handling to keep us out of trouble */ CPUCaps |= (BA_MMX | BA_SSE | BA_SSE2 | BA_SSE3 | BA_3Dnow | BA_3DnowP | BA_MMX_P ); #if defined(USE_AVX) CPUCaps |= BA_AVX; #endif #elif defined(USE_ALTIVEC) CPUCaps |= BA_ALTVC; #elif defined(__arm__) && defined(__VFP_FP__) && !defined(__SOFTFP__) #if defined(ANDROID) || defined(__linux__) // if strlen(p_features) is 0 or p_features doesn't contain "vfp" assume // either BOINC is screwed up or we're running stand alone. size_t len=strlen(app_init_data.host_info.p_features); if ((len==0) || (strstr(app_init_data.host_info.p_features,"vfp") == 0)) { if (do_print) fprintf(stderr,"Getting CPU Capabilities from /proc/cpuinfo\n"); app_init_data.host_info.p_features[0]=0; char buf[256]; FILE *cpuinfo=boinc_fopen("/proc/cpuinfo","r"); if (cpuinfo) { while (fgets(buf,sizeof(buf),cpuinfo)) { if (strstr(buf, "Features")==buf) { strlcpy(app_init_data.host_info.p_features,strstr(buf,":")+1,sizeof(app_init_data.host_info.p_features)); break; } } fclose(cpuinfo); } else { fprintf(stderr,"Could not open /proc/cpuinfo\n"); } len=strlen(app_init_data.host_info.p_features); if (len == 0) fprintf(stderr,"Didn't find 'Features' line\n"); } // ensure the features list ends with a space. if ((app_init_data.host_info.p_features[len-1] != ' ') && (len timings; timings.reserve(1000); int best; double best_timing, best_accuracy; if (k == 1) { if (do_print) fprintf(stderr,"%32s (no other)%s\n", BaseLineSmoothFuncs[0].nom, (verbose>1) ? "\n": ""); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return v_BaseLineSmooth; } sah_complex *indata=(sah_complex *)malloc_a(NumDataPoints*sizeof(sah_complex),MEM_ALIGN); sah_complex *outdata=(sah_complex *)malloc_a(NumDataPoints*sizeof(sah_complex),MEM_ALIGN); sah_complex *save=(sah_complex *)malloc_a(NumDataPoints*sizeof(sah_complex),MEM_ALIGN); FORCE_FRAME_POINTER; if (!indata || !outdata || !save) { if (indata) free_a(indata); if (outdata) free_a(outdata); if (save) free_a(save); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return v_BaseLineSmooth; } for (i=0;i(RAND_MAX/2))?-1.0f:1.0f; indata[i][1]=((rand()&RAND_MAX)>(RAND_MAX/2))?-1.0f:1.0f; } #if !defined(USE_ASMLIB) && !defined(__APPLE_CC__) install_sighandler(); for (i=0;i1) fprintf(stderr,"%32s not supported on CPU\n", BaseLineSmoothFuncs[i].nom); continue; } j=0; timing=0; while ((j<100) && ((j<20) || (timing<(10*timer.resolution())))) { memcpy(outdata,indata,NumDataPoints*sizeof(sah_complex)); timer.start(); rv=BaseLineSmoothFuncs[i].func(outdata,NumDataPoints,8192,32768); onetime=timer.stop(); timing+=onetime; timings.push_back(onetime); #if !defined(USE_ASMLIB) && !defined(__APPLE_CC__) if (rv) siglongjmp(jb,1); #else if (rv) break; #endif j++; } if (rv) continue; std::sort(timings.begin(),timings.end()); timing=timings[timings.size()/2]; if (timing==0) timing=std::accumulate(timings.begin(),timings.end(),0.0)/timings.size(); timings.clear(); if (i==0) { accuracy=0; memcpy(save,outdata,NumDataPoints*sizeof(sah_complex)); } else { accuracy=0; for (j=0;j1) { fprintf(stderr,"%32s %8.6f %7.5f test\n",BaseLineSmoothFuncs[i].nom,timing,accuracy); fflush(stderr); } if ((timing1) { fprintf(stderr,"%32s faulted\n",BaseLineSmoothFuncs[i].nom); fflush(stderr); } } } uninstall_sighandler(); #else } #endif free_a(indata); free_a(outdata); free_a(save); if (do_print) fprintf(stderr,"%32s %8.6f %7.5f %s\n", BaseLineSmoothFuncs[best].nom, best_timing, best_accuracy, (verbose>1) ? " choice\n": ""); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return baseline_smooth; } GetPowerSpectrum_func ChooseGetPowerSpectrum() { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("ChooseGetPowerSpectrum()"); #endif if (default_functions_flag) { if (do_print) fprintf(stderr,"%32s (default)\n",GetPowerSpectrumFuncs[0].nom); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return GetPowerSpectrumFuncs[0].func; } // else hires_timer timer; GetPowerSpectrum_func get_power_spectrum; int i,j,rv; double speed=1e+6,timing,onetime,accuracy; std::vector timings; timings.reserve(1000); int NumDataPoints=128*1024; int best; double best_timing, best_accuracy; sah_complex *indata=(sah_complex *)malloc_a(NumDataPoints*sizeof(sah_complex),MEM_ALIGN); float *outdata=(float *)malloc_a(NumDataPoints*sizeof(float),MEM_ALIGN); float *save=(float *)malloc_a(NumDataPoints*sizeof(float),MEM_ALIGN); FORCE_FRAME_POINTER; if (!indata || !outdata || !save) { if (indata) free_a(indata); if (outdata) free_a(outdata); if (save) free_a(save); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return v_GetPowerSpectrum; } for (i=0;i1) fprintf(stderr,"%32s not supported on CPU\n", GetPowerSpectrumFuncs[i].nom); continue; } j=0; timing=0; while ((j<100) && ((j<20) || (timing<(10*timer.resolution())))) { memset(outdata,0,NumDataPoints*sizeof(float)); timer.start(); rv=GetPowerSpectrumFuncs[i].func(indata,outdata,NumDataPoints); onetime=timer.stop(); timing+=onetime; timings.push_back(onetime); #if !defined(USE_ASMLIB) && !defined(__APPLE_CC__) if (rv) siglongjmp(jb,1); #else if (rv) break; #endif j++; } if (rv) continue; std::sort(timings.begin(),timings.end()); timing=timings[timings.size()/2]; if (timing==0) timing=std::accumulate(timings.begin(),timings.end(),0.0)/timings.size(); timings.clear(); if (i==0) { accuracy=0; memcpy(save,outdata,NumDataPoints*sizeof(float)); } else { accuracy=0; for (j=0;j1) { fprintf(stderr,"%32s %8.6f %7.5f test\n",GetPowerSpectrumFuncs[i].nom,timing,accuracy); fflush(stderr); } if ((timing1) { fprintf(stderr,"%32s faulted\n",GetPowerSpectrumFuncs[i].nom); fflush(stderr); } } } uninstall_sighandler(); #else } #endif free_a(indata); free_a(outdata); free_a(save); if (do_print) fprintf(stderr,"%32s %8.6f %7.5f %s\n", GetPowerSpectrumFuncs[best].nom, best_timing, best_accuracy, (verbose>1) ? " choice\n": ""); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return get_power_spectrum; } extern void CalcTrigArray(int len, int ChirpRateInd); extern void FreeTrigArray(); extern void InitTrigArray(int len, double ChirpStep, int InitInd, double SampleRate); ChirpData_func ChooseChirpData() { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("ChooseChirpData()"); #endif bool CacheChirpCalc=((app_init_data.host_info.m_nbytes == 0) || (app_init_data.host_info.m_nbytes >= MIN_TRIGARRAY_MEMORY)); if (default_functions_flag) { if (do_print) fprintf(stderr,"%32s (default)\n",ChirpDataFuncs[0].nom); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return ChirpDataFuncs[0].func; } // else hires_timer timer; ChirpData_func chirp_data; int i,j,rv,k = sizeof(ChirpDataFuncs)/sizeof(CDtb); double speed=1e+6,timing,accuracy,onetime; std::vector timings; timings.reserve(1000); int NumDataPoints=1024*1024; int best; double best_timing, best_accuracy; FORCE_FRAME_POINTER; if (k == 1) { if (do_print) fprintf(stderr,"%32s (no other)\n",ChirpDataFuncs[0].nom); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return v_ChirpData; } sah_complex *indata=(sah_complex *)malloc_a(NumDataPoints*sizeof(sah_complex),MEM_ALIGN); sah_complex *outdata=(sah_complex *)malloc_a(NumDataPoints*sizeof(sah_complex),MEM_ALIGN); sah_complex *test=(sah_complex *)malloc_a(NumDataPoints*sizeof(sah_complex),MEM_ALIGN); if (!indata || !outdata || !test) { if (indata) free_a(indata); if (outdata) free_a(outdata); if (test) free_a(test); fprintf(stderr,"Memory allocation failed in ChooseChirp\n"); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return v_ChirpData; } //JWS: Generate indata as the chirp of flat line (constant) data for (i=0;i(i)*recip_sample_rate; ang=0.5*chirp_rate*time*time; ang -= floor(ang); ang *= M_PI*2; sincos(ang,&dd,&cc); // Notionally: // c=cc; // d=dd; // indata[i][0] = save[i][0] * c - save[i][1] * d; // indata[i][1] = save[i][0] * d + save[i][1] * c; indata[i][0] = static_cast(cc); indata[i][1] = static_cast(dd); } #if !defined(USE_ASMLIB) && !defined(__APPLE_CC__) install_sighandler(); for (i=0;i1) fprintf(stderr,"%32s not supported on CPU\n", ChirpDataFuncs[i].nom); continue; } j=0; timing=0; if (CacheChirpCalc) { // Give the cached functions something to on the first call. FreeTrigArray(); InitTrigArray(NumDataPoints, MinChirpStep,TESTCHIRPIND-1,swi.subband_sample_rate); } int ind=TESTCHIRPIND; while ((j<100) && ((j<20) || (timing<(10*timer.resolution())))) { memset(outdata,0,NumDataPoints*sizeof(sah_complex)); #if 0 fprintf(stderr,"before Chirp test:%32s \n",ChirpDataFuncs[i].nom); for(int k=0;k<3;k++){ fprintf(stderr,"in[%d].xy=(%7.5f,%7.5f)]\n",k,indata[k][0],indata[k][1]); } #endif timer.start(); rv=ChirpDataFuncs[i].func(indata,outdata,ind,MinChirpStep*ind,NumDataPoints,swi.subband_sample_rate); onetime=timer.stop(); #if 0 fprintf(stderr,"after Chirp test:%32s \n",ChirpDataFuncs[i].nom); for(int k=0;k<3;k++){ fprintf(stderr,"out[%d].xy=(%7.5f,%7.5f)]\n",k,outdata[k][0],outdata[k][1]); } #endif timing+=onetime; timings.push_back(onetime); #if !defined(USE_ASMLIB) && !defined(__APPLE_CC__) if (rv) siglongjmp(jb,1); #else if (rv) break; #endif if (j==1) memcpy(test,outdata,NumDataPoints*sizeof(sah_complex)); if (ind>0) { ind*=-1; } else { ind=-1*(ind-2); } j++; } if (rv) continue; std::sort(timings.begin(),timings.end()); timing=timings[timings.size()/2]; if (timing==0) timing=std::accumulate(timings.begin(),timings.end(),0.0)/timings.size(); timings.clear(); accuracy=0; //JWS: indata is positive chirp of constant at TESTCHIRPIND, test was copied // at -TESTCHIRPIND so we check for deviation from flat for (j=0;j1) fprintf(stderr,"%32s %8.6f %7g test\n",ChirpDataFuncs[i].nom,timing,accuracy); if (verbose>1) { fprintf(stderr,"%32s %8.6f %7.5f test\n",ChirpDataFuncs[i].nom,timing,accuracy); fflush(stderr); } if ((timing1) { fprintf(stderr,"%32s faulted\n",ChirpDataFuncs[i].nom); fflush(stderr); } // reinstall_sighandler(); } } uninstall_sighandler(); #else } #endif free_a(indata); free_a(outdata); free_a(test); if (do_print) fprintf(stderr,"%32s %8.6f %7.5f %s\n", ChirpDataFuncs[best].nom, best_timing, best_accuracy, (verbose>1) ? " choice\n": ""); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return chirp_data; } Transpose_func ChooseTranspose() { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("ChooseTranspose()"); #endif if (default_functions_flag || !use_transposed_pot) { if (do_print && use_transposed_pot) fprintf(stderr,"%32s (default)\n",TransposeFuncs[2].nom); //JWS: v_Transpose4 is the default #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return TransposeFuncs[2].func; } // else hires_timer timer; Transpose_func transpose; int i,j,rv; double speed=1e+6,timing,onetime,accuracy; std::vector timings; timings.reserve(1000); int NumDataPoints=1024*1024; int best; double best_timing, best_accuracy; float *indata=(float *)malloc_a(NumDataPoints*sizeof(float),MEM_ALIGN); float *outdata=(float *)malloc_a(NumDataPoints*sizeof(float),MEM_ALIGN); float *save=(float *)malloc_a(NumDataPoints*sizeof(float),MEM_ALIGN); FORCE_FRAME_POINTER; if (!indata || !outdata || !save) { if (indata) free_a(indata); if (outdata) free_a(outdata); if (save) free_a(save); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return v_Transpose; } for (i=0;i1) fprintf(stderr,"%32s not supported on CPU\n", TransposeFuncs[i].nom); continue; } j=0; timing=0; int ind=0; while ((j<100) && ((j<20) || (timing<(10*timer.resolution())))) { memset(outdata,0,NumDataPoints*sizeof(float)); timer.start(); rv=TransposeFuncs[i].func(16384,64,indata,outdata); onetime=timer.stop(); timing+=onetime; timings.push_back(onetime); #if !defined(USE_ASMLIB) && !defined(__APPLE_CC__) if (rv) siglongjmp(jb,1); #else if (rv) break; #endif j++; } if (rv) continue; std::sort(timings.begin(),timings.end()); timing=timings[timings.size()/2]; if (timing==0) timing=std::accumulate(timings.begin(),timings.end(),0.0)/timings.size(); timings.clear(); if (i==0) { accuracy=0; memcpy(save,outdata,NumDataPoints*sizeof(float)); } else { accuracy=0; for (j=0;j1) { fprintf(stderr,"%32s %8.6f %7.5f test\n",TransposeFuncs[i].nom,timing,accuracy); fflush(stderr); } if ((timing1) { fprintf(stderr,"%32s faulted\n",TransposeFuncs[i].nom); fflush(stderr); } } } uninstall_sighandler(); #else } #endif free_a(indata); free_a(outdata); free_a(save); if (do_print) fprintf(stderr,"%32s %8.6f %7.5f %s\n", TransposeFuncs[best].nom, best_timing, best_accuracy, (verbose>1) ? " choice\n": ""); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return transpose; } /******************************************** * * Testing folding subroutines * */ // dummy folding routine float dmyFld(float *ss[], struct PoTPlan *P) {return 1.0f;} // tables to hold function pointers of set under test sum_func fold3test[FOLDTBLEN] = { dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, }; sum_func fold4test[FOLDTBLEN] = { dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, }; sum_func fold5test[FOLDTBLEN] = { dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, }; sum_func fold2test[FOLDTBLEN] = { dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, }; sum_func fold2ALtest[FOLDTBLEN] = { dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, dmyFld, }; FoldSet TestFoldSet = {fold3test, fold4test, fold5test, fold2test, fold2ALtest, ""}; /********************** * * Generate preplanned sequence of folds * */ int planFoldTest(PoTPlan * PSeq, float *div, int FFTtbl[][5]) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("planFoldTest()"); #endif float period; int i, iL, j, di, ndivs; int num_adds, num_adds_2; int FftLength, PulsePoTLen; int dbinoffs[32] = {0}; int k = 0; // plan index for (iL = 0; iL < 32; iL++) { if ((FftLength = FFTtbl[iL][0]) == 0) continue; PulsePoTLen = FFTtbl[iL][4]; for (i = 32, ndivs = 1; i <= PulsePoTLen; ndivs++, i *= 2); period = (float)((int)((PulsePoTLen * 2) / 3)) * 0.5f; for (i = 1; i < ndivs; i++, period *= 0.5f) { dbinoffs[i] = (((int)(period + 0.5f) + (MEM_ALIGN/sizeof(float)) - 1) & -(MEM_ALIGN/sizeof(float))) + dbinoffs[i - 1]; } int32_t PoTL = PulsePoTLen; // Periods from PulsePoTLen/3 to PulsePoTLen/4, and power of 2 fractions of. // then (len/4 to len/5) and finally (len/5 to len/6) // // For quick testing we select about one from each range at FFT length 8, two at 16, // four at 32, etc. // int32_t firstP, lastP, iP, iLim; for(num_adds = 3; num_adds <= 5; num_adds++) { float rnum_adds_minus1; float fP, fStep; iLim = FFTtbl[iL][num_adds - 2]; switch(num_adds) { case 3: lastP = (PoTL * 2) / 3; firstP = (PoTL * 1) / 2; rnum_adds_minus1 = 0.5f; break; case 4: lastP = (PoTL * 3) / 4; firstP = (PoTL * 3) / 5; rnum_adds_minus1 = 1.0f / 3.0f; break; case 5: lastP = (PoTL * 4) / 5; firstP = (PoTL * 4) / 6; rnum_adds_minus1 = 0.25f; break; } fStep = (float)(lastP - firstP) / (float)(iLim); fP = fabs((float)(lastP) - (fStep / 3.0f)); for (iP = 0; iP < iLim; iP++, fP -= fStep) { PSeq[k].dest = div + dbinoffs[0]; // Output storage PSeq[k].di = di = (int)(fP * rnum_adds_minus1); PSeq[k].tmp0 = (int)(fP * 1.0f * rnum_adds_minus1 + 0.5f); PSeq[k].tmp1 = (int)(fP * 2.0f * rnum_adds_minus1 + 0.5f); switch(num_adds) { case 3: PSeq[k].fun_ptr = (di < FOLDTBLEN) ? fold3test[di] : fold3test[FOLDTBLEN-1]; break; case 4: PSeq[k].tmp2 = (int)(fP * 3.0f * rnum_adds_minus1 + 0.5f); PSeq[k].fun_ptr = (di < FOLDTBLEN) ? fold4test[di] : fold4test[FOLDTBLEN-1]; break; case 5: PSeq[k].tmp2 = (int)(fP * 3.0f * rnum_adds_minus1 + 0.5f); PSeq[k].tmp3 = (int)(fP * 4.0f * rnum_adds_minus1 + 0.5f); PSeq[k].fun_ptr = (di < FOLDTBLEN) ? fold5test[di] : fold5test[FOLDTBLEN-1]; break; } // When built with DevC++/MinGW and signal handling enabled, the first calculation // of PSeq[0].tmp0 somehow produces an 0x80000000 value. This hack repeats the // calculation, which gets the right value. if (k == 0 && PSeq[k].tmp0 < 1) PSeq[k].tmp0 = (int)(fP * 1.0f * rnum_adds_minus1 + 0.5f); k++; // next plan num_adds_2 = 2 * num_adds; for (j = 1; j < ndivs ; j++) { PSeq[k].offset = dbinoffs[j - 1]; PSeq[k].dest = div + dbinoffs[j]; PSeq[k].tmp0 = di & 1; di /= 2; PSeq[k].tmp0 += di + PSeq[k].offset; PSeq[k].di = di; if (PSeq[k].tmp0 & 3) PSeq[k].fun_ptr = (di < FOLDTBLEN) ? fold2test[di] : fold2test[FOLDTBLEN-1]; else PSeq[k].fun_ptr = (di < FOLDTBLEN) ? fold2ALtest[di] : fold2ALtest[FOLDTBLEN-1]; k++; // next plan num_adds_2 *= 2; } // for (j = } // for (iP = } // for(num_adds = } // for(iL = PSeq[k].di = 0; // stop /* for (int iDmp = 0; iDmp < 4; iDmp++) { fprintf(stderr,"di= %d dest= %d ptr= %d tmp0= %d tmp1= %d\n", PSeq[iDmp].di, PSeq[iDmp].dest, PSeq[iDmp].fun_ptr, PSeq[iDmp].tmp0, PSeq[iDmp].tmp1); } */ #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return (k); } /********************** * * Test folding subroutine sets and choose best * */ int ChooseFoldSubs(ChirpFftPair_t * ChirpFftPairs, int num_cfft, int nsamples) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("ChooseFoldSubs()"); #endif if (default_functions_flag) { if (do_print) fprintf(stderr,"%24s folding (default)\n",Foldmain.name); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } // else hires_timer timer; int i, iL, j, k, ndivs, NumPlans = 0, MaxPulsePoT = PoTInfo.PulseMax; double onetime, timing, best_timing, speed = 1e+6; double accuracy, best_accuracy, errmax, dTmp = 1e+30; std::vector timings; timings.reserve(1000); int best; int PoTLen, PulsePoTLen, Overlap, FFTtbl[32][5] = {0, 0, 0, 0, 0}; double NumSamples = nsamples; float *SrcSel[2]; // Get the count of chirp/fft pairs for each FFT length where Pulse finding // will be done. for (i = 0; i < num_cfft; i++) { if (ChirpFftPairs[i].PulseFind) { for (iL = 0, j = ChirpFftPairs[i].FftLen; j ; iL++, j >>= 1); FFTtbl[iL][0] = ChirpFftPairs[i].FftLen; FFTtbl[iL][2] += 1; } } // For testing, the chirp/fft table may just be a short list. If so, add the FFT // length to the counts to simulate distribution for a full table. (This also affects // very high angle range WUs, but Pulse folding is a small factor there so looser // testing will have very little effect.) if (num_cfft < 14) { for (iL = 0; iL < 32; iL++) FFTtbl[iL][2] += FFTtbl[iL][0]; } // Scale the counts so the minimum is 1. Use the scaled value directly for fold // sequences starting with a fold by 4. Adjust the values for fold by 3 and // fold by 5 to get close to the 10, 9, 8 ratios. Add the PoT length values to // the table, and tot up the needed number of PoTPlans. for (iL = 0; iL < 32; iL++) { if ((FFTtbl[iL][0]) && ((double)FFTtbl[iL][2] < dTmp)) dTmp = (double)FFTtbl[iL][2]; } for (iL = 0; iL < 32; iL++) { if (FFTtbl[iL][0]) { FFTtbl[iL][2] = (int)((double)FFTtbl[iL][2] / dTmp + 0.5); FFTtbl[iL][1] = (int)((double)FFTtbl[iL][2] * 10.0 / 9.0 + 0.5); FFTtbl[iL][3] = FFTtbl[iL][2] + FFTtbl[iL][2] - FFTtbl[iL][1]; PoTLen = (int)(NumSamples / FFTtbl[iL][0] + 0.5); GetPulsePoTLen(PoTLen, &PulsePoTLen, &Overlap); FFTtbl[iL][4] = PulsePoTLen; for (i = 32, ndivs = 1; i <= PulsePoTLen; ndivs++, i *= 2); NumPlans += 3 * FFTtbl[iL][2] * ndivs; } } if (NumPlans == 0) { // No pulse finding in this WU, abort test. #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } // At some angle ranges the total number of test folds may be too few to get good // timing measurements. Scale up so there are at least 16K test folds. while (NumPlans < 16384) { for (iL = 0; iL < 32; iL++) { FFTtbl[iL][1] *= 2; FFTtbl[iL][2] *= 2; FFTtbl[iL][3] *= 2; } NumPlans *= 2; } // fprintf(stderr, "Calculated Preplans = %d\n", NumPlans); // NumPlans *= 2; // temporary safety measure // Now we know what we're doing - allocate memory in which to do it. PoTPlan *PlanBuf = (PoTPlan *)malloc_a((NumPlans + 1) * sizeof(PoTPlan), MEM_ALIGN); float *indata = (float *)malloc_a(MaxPulsePoT * sizeof(float), MEM_ALIGN); float *outdata = (float *)malloc_a(MaxPulsePoT * sizeof(float), MEM_ALIGN); float *maxdata = (float *)malloc_a(NumPlans * sizeof(float), MEM_ALIGN); float *save = (float *)malloc_a(NumPlans * sizeof(float), MEM_ALIGN); FORCE_FRAME_POINTER; if (!PlanBuf || !indata || !outdata || !maxdata || !save) { if (PlanBuf) free_a(PlanBuf); if (indata) free_a(indata); if (outdata) free_a(outdata); if (maxdata) free_a(maxdata); if (save) free_a(save); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; // Can't test, make no change } SrcSel[0] = indata; SrcSel[1] = outdata; // Generate PowerSpectrum random data srand(11); for (i = 0; i < MaxPulsePoT; i++) { float fr1 = (float)(rand()) / RAND_MAX; float fr2 = (float)(rand()) / RAND_MAX; indata[i] = fr1 * fr1 + fr2 * fr2; } #if !defined(USE_ASMLIB) && !defined(__APPLE_CC__) install_sighandler(); for (i=0;(i*sizeof(FolSub))1) fprintf(stderr,"%24s folding not supported on CPU\n", FoldSubs[i].fsp->name); continue; } j = 0; timing = 0; CopyFoldSet(&TestFoldSet, FoldSubs[i].fsp); int n = planFoldTest(PlanBuf, outdata, FFTtbl); // if (!i) fprintf(stderr, "Actual Preplans = %d\n", n); while ((j < 100) && ((j < 10) || ((timing) < (10 * timer.resolution())))) { memset(outdata, 0, MaxPulsePoT * sizeof(float)); memset(maxdata, 0, NumPlans * sizeof(float)); maxdata[0] = -1.234f; timer.start(); for ( k = 0; PlanBuf[k].di; k++) { maxdata[k] = PlanBuf[k].fun_ptr(SrcSel, &PlanBuf[k]); } onetime = timer.stop(); timing+=onetime; timings.push_back(onetime); #if !defined(USE_ASMLIB) && !defined(__APPLE_CC__) if (maxdata[0] < 0) siglongjmp(jb,1); #else if (maxdata[0] < 0) break; #endif j++; } std::sort(timings.begin(),timings.end()); timing=timings[timings.size()/2]; if (timing==0) timing=std::accumulate(timings.begin(),timings.end(),0.0)/timings.size(); timings.clear(); accuracy = 0; errmax = 0; if (i == 0) { memcpy(save, maxdata, NumPlans * sizeof(float)); } else { for (j = 0; j < NumPlans; j++) { // a zero max should never happen, but be safe... if (save[j]) { double relerr = fabs((save[j] - maxdata[j]) / save[j]); accuracy += relerr; if (relerr > errmax) errmax = relerr; } } } accuracy /= NumPlans; if (verbose>1) { fprintf(stderr, "%24s folding %8.6f %7.5f test\n", FoldSubs[i].fsp->name, timing, accuracy); fflush(stderr); } if ((timing < speed) && isnotnan(accuracy) && (accuracy < 1e-6) && (errmax < 1e-4)) { speed = timing; best = i; best_timing = timing; best_accuracy = accuracy; } #if !defined(USE_ASMLIB) && !defined(__APPLE_CC__) } else { // reinstall_sighandler(); if (verbose>1) { fprintf(stderr, "%24s folding faulted\n", FoldSubs[i].fsp->name); fflush(stderr); } } } uninstall_sighandler(); #else } #endif free_a(PlanBuf); free_a(indata); free_a(outdata); free_a(maxdata); free_a(save); if (do_print) fprintf(stderr, "%24s folding %8.6f %7.5f %s\n", FoldSubs[best].fsp->name, best_timing, best_accuracy, (verbose>1) ? " choice\n": ""); CopyFoldSet(&Foldmain, FoldSubs[best].fsp); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } void ChooseFunctions(BaseLineSmooth_func *baseline_smooth, GetPowerSpectrum_func *get_power_spectrum, ChirpData_func *chirp_data, Transpose_func *transpose, ChirpFftPair_t * ChirpFftPairs, int num_cfft, int nsamples, bool print_choices) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("ChooseFunctions()"); #endif do_print=print_choices; if (verbose>1) do_print = true; if (TestBoincSignalHandling()) { SetCapabilities(); hires_timer durtimer; double TestDur=0; if (do_print) { fprintf(stderr,"Optimal function choices:\n"); fprintf(stderr,"--------------------------------------------------------\n"); fprintf(stderr,"%32s %8s %7s\n","name","timing","error"); fprintf(stderr,"--------------------------------------------------------\n"); fflush(stderr); } durtimer.start(); #ifdef ANDROID // low memory android is a special case because android will kill // without warning to free memory. Testing the functions could trigger // a loop. So we'll choose what fits the processor and return if (app_init_data.host_info.m_nbytes && (app_init_data.host_info.m_nbytes < MIN_TRIGARRAY_MEMORY)) { *baseline_smooth=v_BaseLineSmooth; found_baseline_smooth=true; if (do_print) fprintf(stderr,"%32s (no other)\n", "v_BaseLineSmooth"); #if defined(__VFP_FP__) && !defined(__SOFTFP__) #ifdef USE_NEON if (CPUCaps & BA_NEON) { *get_power_spectrum=vfp_GetPowerSpectrum; found_get_power_spectrum=true; if (do_print) fprintf(stderr,"%32s (CPU Caps)\n", "vfp_GetPowerSpectrum"); *chirp_data=neon_ChirpData; found_chirp_data=true; if (do_print) fprintf(stderr,"%32s (CPU Caps)\n", "neon_ChirpData"); } else #endif if (CPUCaps & BA_VFP) { *get_power_spectrum=vfp_GetPowerSpectrum; found_get_power_spectrum=true; if (do_print) fprintf(stderr,"%32s (CPU Caps)\n", "vfp_GetPowerSpectrum"); *chirp_data=vfp_ChirpData; found_chirp_data=true; if (do_print) fprintf(stderr,"%32s (CPU Caps)\n", "vfp_ChirpData"); } else { #endif *get_power_spectrum=v_GetPowerSpectrum; found_get_power_spectrum=true; if (do_print) fprintf(stderr,"%32s (default)\n", "v_GetPowerSpectrum"); *chirp_data=v_ChirpData; found_chirp_data=true; if (do_print) fprintf(stderr,"%32s (default)\n", "v_ChirpData"); #if defined(__VFP_FP__) && !defined(__SOFTFP__) } #endif *transpose=v_Transpose4; found_transpose=true; if (do_print) fprintf(stderr,"%32s (default)\n", "v_Transpose4"); #if defined(__VFP_FP__) && !defined(__SOFTFP__) #ifdef USE_NEON if (CPUCaps & BA_NEON) { CopyFoldSet(&Foldmain, &neonFoldMain); found_folding=true; if (do_print) fprintf(stderr,"%32s (CPU Caps)\n", "opt NEON folding"); } else #endif if (CPUCaps & BA_VFP) { CopyFoldSet(&Foldmain, &vfpFoldMain); found_folding=true; if (do_print) fprintf(stderr,"%32s (CPU Caps)\n", "opt VFP folding"); } else { #endif CopyFoldSet(&Foldmain, &swifold); found_folding=true; if (do_print) fprintf(stderr,"%32s (default)\n", "swifold"); #if defined(__VFP_FP__) && !defined(__SOFTFP__) } #endif TestDur+=durtimer.stop(); if (verbose>1) fprintf(stderr,"%32s %8.2f seconds\n\n","Test duration",TestDur); if (do_print) { fflush(stderr); } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return; } #endif if (!found_baseline_smooth) { *baseline_smooth=ChooseBaseLineSmooth(); } else { if (do_print) fprintf(stderr,"BaseLineSmooth retrieved from state file\n"); *baseline_smooth=*BaseLineSmooth; } fflush(stderr); if (!found_get_power_spectrum) { *get_power_spectrum=ChooseGetPowerSpectrum(); } else { if (do_print) fprintf(stderr,"GetPowerSpectrum retrieved from state file\n"); *get_power_spectrum=*GetPowerSpectrum; } fflush(stderr); if (!found_chirp_data) { *chirp_data=ChooseChirpData(); } else { if (do_print) fprintf(stderr,"ChirpData retrieved from state file\n"); *chirp_data=*ChirpData; } fflush(stderr); if (!found_transpose) { *transpose=ChooseTranspose(); } else { if (do_print) fprintf(stderr,"Transpose retrieved from state file\n"); *transpose=*Transpose; } fflush(stderr); // ChooseFoldSubs is inconsistent in that it directly sets a global // variable. Maybe we should make it consistent with the others // at some point. --EK if (!found_folding) { ChooseFoldSubs(ChirpFftPairs, num_cfft, nsamples); } else { if (do_print) fprintf(stderr,"Folding Subs retrieved from state file\n"); } fflush(stderr); TestDur+=durtimer.stop(); if (verbose>1) fprintf(stderr,"%32s %8.2f seconds\n\n","Test duration",TestDur); } if (do_print) { fflush(stderr); } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } boinc-app-seti_8.00~svn3701.orig/client/vector/x86_float4.h0000644000175000017500000002152111566257502023353 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // $Id: x86_float4.h,v 1.1.2.4 2007/07/16 15:36:57 korpela Exp $ // // This file is empty is __i386__ is not defined // #ifndef _X86_FLOAT4_H_ #define _X86_FLOAT4_H_ #include "sah_config.h" #if defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_AMD64) #include "x86_ops.h" #ifndef M_PI #define M_PI 3.14159265358979323846 #endif struct float4; struct const_float4; extern const_float4 SS1, SS2, SS3, SS4, CC1, CC2, CC3; extern const_float4 SS1F, SS2F, SS3F, SS4F, CC1F, CC2F, CC3F; extern const_float4 ZERO, ONE, TWO, THREE, RECIP_TWO; extern const_float4 RECIP_THREE, RECIP_FOUR, RECIP_FIVE; extern const_float4 RECIP_PI, RECIP_TWOPI, RECIP_HALFPI; extern const_float4 R_NEG; // 2^23 (used by quickRound) extern const_float4 TWO_TO_23; extern const_float4 INDGEN[2]; ALIGNED(static const int sign_bits[4],16)={INT_MIN, INT_MIN, INT_MIN, INT_MIN}; ALIGNED(static const int other_bits[4],16)={INT_MAX, INT_MAX, INT_MAX, INT_MAX}; #define SIGN_BITS (*(__m128i *)sign_bits) #define OTHER_BITS (*(__m128i *)other_bits) struct float4 { float4() {}; float4(const __m128 b) { m=b; }; float4(const float &fval) { #ifdef USE_INTRINSICS m=_mm_load1_ps(&fval); #elif defined(__GNUC__) __asm__ ( "shufps $0,%0,%0\n":"=x" (m):"0" (fval) ); #endif }; float4(const float &f1, const float &f2, const float &f3, const float &f4) { v[0]=f1; v[1]=f2; v[2]=f3; v[3]=f4; }; float4(const float4 &b) { m=b.m; }; float4(const const_float4 &b) { m=((float4 *)&b)->m; }; inline float4 operator +(const float4 &f) const { register float4 rv; #ifdef USE_INTRINSICS rv.m=_mm_add_ps(m,f.m); #elif defined(__GNUC__) __asm__ ( "addps %2,%0" : "=x" (rv.m) : "0" (m), "xm" (f.m) ); #endif return rv; }; inline float4 operator -(const float4 &f) const { register float4 rv; #ifdef USE_INTRINSICS rv.m=_mm_sub_ps(m,f.m); #elif defined(__GNUC__) __asm__ ( "subps %2,%0" : "=x" (rv.m) : "0" (m), "xm" (f.m) ); #endif return rv; }; inline float4 operator *(const float4 &f) const { register float4 rv; #ifdef USE_INTRINSICS rv.m=_mm_mul_ps(m,f.m); #elif defined(__GNUC__) __asm__ ( "mulps %2,%0" : "=x" (rv.m) : "0" (m), "xm" (f.m) ); #endif return rv; }; inline float4 operator |(const __m128i &b) const { register float4 rv; #ifdef USE_INTRINSICS rv.m=_mm_or_ps(*(__m128 *)&b,m); #elif defined(__GNUC__) __asm__ ( "orps %2,%0" : "=x" (rv.m) : "0" (b), "xm" (m)); #endif return rv; }; inline float4 operator &(const __m128i &b) const { register float4 rv; #ifdef USE_INTRINSICS rv.m=_mm_and_ps(*(__m128 *)&b,m); #elif defined(__GNUC__) __asm__ ( "andps %2,%0" : "=x" (rv.m) : "0" (b), "xm" (m)); #endif return rv; }; inline float4 &operator =(const float4 &b) { m=b.m; return *this; }; inline float4 &operator *=(const float4 &b) { #ifdef USE_INTRINSICS m=_mm_mul_ps(m,b.m); #elif defined(__GNUC__) __asm__ ( "mulps %2,%0" : "=x" (m) : "0" (m), "xm" (b.m) ); #endif return *this; } inline float4 &operator +=(const float4 &b) { #ifdef USE_INTRINSICS m=_mm_add_ps(m,b.m); #elif defined(__GNUC__) __asm__ ( "addps %2,%0" : "=x" (m) : "0" (m), "xm" (b.m) ); #endif return *this; } inline float4 &operator -=(const float4 &b) { #ifdef USE_INTRINSICS m=_mm_sub_ps(m,b.m); #elif defined(__GNUC__) __asm__ ( "subps %2,%0" : "=x" (m) : "0" (m), "xm" (b.m) ); #endif return *this; } inline float4 &operator /=(const float4 &b) { #ifdef USE_INTRINSICS m=_mm_div_ps(m,b.m); #elif defined(__GNUC__) __asm__ ( "divps %2,%0" : "=x" (m) : "0" (m), "xm" (b.m) ); #endif return *this; } inline operator __m128() {return m;}; inline operator __m128i() {return *(__m128i *)&m; }; inline float4 abs() const { // clear the sign bits return *this & OTHER_BITS; }; inline float4 sign() const { // return the sign bits return *this & SIGN_BITS; }; inline float4 round() const { // add and subtract the largest exactly // representable integer value of the same sign register float4 s(sign()); register float4 a(s | (float4)TWO_TO_23); a=(*this+a)-a; return a; }; inline float4 ceil() const { return (*this+RECIP_TWO).round(); } inline float4 floor() const { return (*this-RECIP_TWO).round(); } inline float4 mod(const float4 &x) const { register float4 nx(*this*x.recip()); nx-=nx.round(); // [-0.5,0.5) nx*=x; // [-x/2,x/2) return nx; } inline float4 round_pos() const { return ((*this+TWO_TO_23)-TWO_TO_23); }; inline float4 round_neg() const { return ((*this-TWO_TO_23)+TWO_TO_23); }; inline void sincos(float4 &s, float4 &c) const { register float4 x(*this*RECIP_TWOPI); x-=x.round(); register float4 x2(x*x); register float4 t1(x2*SS4+SS3); register float4 t2(x2*CC3+CC2); t1*=x2; t2*=x2; t1+=SS2; t2+=CC1; t1*=x2; t2*=x2; t1+=SS1; c=t2+ONE; s=t1*x; } inline float4 sin() const { register float4 x(*this*RECIP_TWOPI); x-=x.round(); register float4 x2(x*x); return ((((x2*SS4+SS3)*x2+SS2)*x2+SS1)*x); } inline float4 cos() const { register float4 x(*this*RECIP_TWOPI); x-=x.round(); x*=x; return (((x*CC3+CC2)*x+CC1)*x+ONE); } template inline float4 shuffle(float4 b) const { #ifdef USE_INTRINSICS return _mm_shuffle_ps(m,b.m,_MM_SHUFFLE(p3,p2,p1,p0)); #elif defined(__GNUC__) register float4 rv; __asm__ ( "shufps %3,%2,%0" : "=x" (rv) : "0" (m), "x" (b.m), "i" (p0 | (p1 << 2) | (p2<<4) | (p3 << 6)) ); return rv; #endif } inline float4 rsqrt() const { } inline float4 sqrt() const { } inline float4 recip() const { } union { ALIGNED(__m128 m,16); float v[4]; float f; }; } ; struct const_float4 : public float4 { public: inline const_float4() : float4() {}; inline const_float4(const __m128 b) : float4() { m=b; }; inline const_float4(const float &fval) : float4() { v[0]=fval; v[1]=fval; v[2]=fval; v[3]=fval; } inline const_float4(const float &f1, const float &f2, const float &f3, const float &f4) { v[0]=f1; v[1]=f2; v[2]=f3; v[3]=f4; }; inline const_float4(const float4 &b) { m=b.m; }; inline operator float4() const { return *this; }; inline operator __m128() {return m;}; inline operator __m128i() {return *(__m128i *)&m; }; }; #endif #endif boinc-app-seti_8.00~svn3701.orig/client/vector/asmlib.h0000644000175000017500000000177310671336410022723 0ustar locutuslocutus// ASMLIB.H Agner Fog 2004 // Header file for asmlibM.lib, asmlibO.lib, and asmlibE.a // See asmlib.txt for further details extern "C" int InstructionSet (void); // tell which instruction set is supported extern "C" int DetectProcessor (void); // information about microprocessor features extern "C" void ProcessorName (char * text); // ASCIIZ text describing microprocessor extern "C" int Round (double x); // round to nearest or even extern "C" int Truncate (double x); // truncation towards zero extern "C" int ReadClock (void); // read microprocessor internal clock extern "C" int MinI (int a, int b); // the smallest of two integers extern "C" int MaxI (int a, int b); // the biggest of two integers extern "C" double MinD (double a, double b); // the smallest of two double precision numbers extern "C" double MaxD (double a, double b); // the biggest of two double precision numbers boinc-app-seti_8.00~svn3701.orig/client/vector/analyzeFuncs_vector.h0000644000175000017500000002646612636667636025532 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // $Id: analyzeFuncs_vector.h,v 1.1.2.9 2007/06/08 03:09:47 korpela Exp $ #ifndef ANALYZEFUNCS_VECTOR_H #define ANALYZEFUNCS_VECTOR_H #ifdef HAVE_CPU_FEATURES_H #include #endif #include "chirpfft.h" #include "pulsefind.h" #define TWO_TO_52 4.503599627370496e15 // 2^52+2^51 recommended by AMD optimization manual, scaled to 2^64+2^63 for X87 #define ROUNDX87 6755399441055744.0 * 2048.0 // Flemming Pedersen (CERN) SinCos polynomial coefficients #define FS1 1.5707963267948966 #define FS2 -0.64596348437163809 #define FS3 0.079679708649230657 #define FS4 -0.0046002309092153379 #define FC1 -1.2336979844380824 #define FC2 0.25360671639164339 #define FC3 -0.020427240364907607 typedef int (*BaseLineSmooth_func)(sah_complex *, int, int, int); typedef int (*GetPowerSpectrum_func)(sah_complex *, float*, int); typedef int (*ChirpData_func)(sah_complex *, sah_complex *, int, double, int, double); typedef int (*Transpose_func)(int, int , float *, float *); struct BLStb { BaseLineSmooth_func func; int ba; const char * const nom; }; extern const int num_BLS; extern bool found_baseline_smooth; extern BLStb BaseLineSmoothFuncs[]; struct GPStb { GetPowerSpectrum_func func; int ba; const char * const nom; }; extern const int num_GPS; extern bool found_get_power_spectrum; extern GPStb GetPowerSpectrumFuncs[]; struct CDtb { ChirpData_func func; int ba; const char * const nom; }; extern const int num_CD; extern bool found_chirp_data; extern CDtb ChirpDataFuncs[]; struct TPtb { Transpose_func func; int ba; const char * const nom; }; extern const int num_TP; extern bool found_transpose; extern TPtb TransposeFuncs[]; struct FolSub { FoldSet *fsp; int ba; }; extern FolSub FoldSubs[]; extern const int num_FS; extern bool found_folding; extern void ChooseFunctions( BaseLineSmooth_func *, GetPowerSpectrum_func *, ChirpData_func *, Transpose_func *, ChirpFftPair_t * ChirpFftPairs, int num_cfft, int nsamples, bool print_choice); #if defined(__i386__) || defined(__x86_64__) || defined(USE_SSE) extern double fastfrac( double val, double returnVal) #if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 3)) __attribute__ ((__optimize__ ("-fno-fast-math"))); #define SUPPORTS_ATTRIB_OPT 1 #else ; #undef SUPPORTS_ATTRIB_OPT #endif #endif extern int v_vBaseLineSmooth( sah_complex * cx_DataIn, int ul_NumDataPoints, int ul_BoxCarLength, int ul_TimeLength ); extern int v_vGetPowerSpectrum( sah_complex * cx_FreqData, float * fp_PowerSpectrum, int ul_NumDataPoints ); extern int v_vChirpData( sah_complex * cx_DataArray, sah_complex * cx_ChirpDataArray, int ChirpRateInd, double ChirpRate, int ul_NumDataPoints, double sample_rate ); extern int fpu_ChirpData ( sah_complex * cx_DataArray, sah_complex * cx_ChirpDataArray, int ChirpRateInd, double ChirpRate, int ul_NumDataPoints, double sample_rate ); extern int fpu_opt_ChirpData ( sah_complex * cx_DataArray, sah_complex * cx_ChirpDataArray, int ChirpRateInd, double ChirpRate, int ul_NumDataPoints, double sample_rate ); #if defined(__i386__) || defined(__x86_64__) || defined(USE_SSE) extern int v_vChirpData_x86_64( sah_complex * cx_DataArray, sah_complex * cx_ChirpDataArray, int ChirpRateInd, double ChirpRate, int ul_NumDataPoints, double sample_rate ); extern int sse1_ChirpData_ak( sah_complex * cx_DataArray, sah_complex * cx_ChirpDataArray, int ChirpRateInd, double ChirpRate, int ul_NumDataPoints, double sample_rate ); extern int sse1_ChirpData_ak8e( sah_complex * cx_DataArray, sah_complex * cx_ChirpDataArray, int ChirpRateInd, double ChirpRate, int ul_NumDataPoints, double sample_rate ); extern int sse1_ChirpData_ak8h( sah_complex * cx_DataArray, sah_complex * cx_ChirpDataArray, int ChirpRateInd, double ChirpRate, int ul_NumDataPoints, double sample_rate ); extern int sse2_ChirpData_ak( sah_complex * cx_DataArray, sah_complex * cx_ChirpDataArray, int ChirpRateInd, double ChirpRate, int ul_NumDataPoints, double sample_rate ); extern int sse2_ChirpData_ak8( sah_complex * cx_DataArray, sah_complex * cx_ChirpDataArray, int ChirpRateInd, double ChirpRate, int ul_NumDataPoints, double sample_rate ); extern int sse3_ChirpData_ak( sah_complex * cx_DataArray, sah_complex * cx_ChirpDataArray, int ChirpRateInd, double ChirpRate, int ul_NumDataPoints, double sample_rate ); extern int sse3_ChirpData_ak8( sah_complex * cx_DataArray, sah_complex * cx_ChirpDataArray, int ChirpRateInd, double ChirpRate, int ul_NumDataPoints, double sample_rate ); #endif extern int v_vTranspose(int i, int j, float *in, float *out); #if defined(__i386__) || defined(__x86_64__) || defined(USE_SSE) || \ (defined(__arm__) && defined(__VFP_FP__) && !defined(__SOFTFP__)) extern int v_pfTranspose2(int i, int j, float *in, float *out); extern int v_pfTranspose4(int i, int j, float *in, float *out); extern int v_pfTranspose8(int i, int j, float *in, float *out); #endif #if defined(__i386__) || defined(__x86_64__) || defined(USE_SSE) extern int v_vTranspose4(int i, int j, float *in, float *out); extern int v_vTranspose4np(int i, int j, float *in, float *out); extern int v_vTranspose4ntw(int i, int j, float *in, float *out); extern int v_vTranspose4x8ntw(int i, int j, float *in, float *out); extern int v_vTranspose4x16ntw(int i, int j, float *in, float *out); extern int v_vpfTranspose8x4ntw(int i, int j, float *in, float *out); #endif #if (defined(__arm__) && defined(__VFP_FP__) && !defined(__SOFTFP__)) extern int v_vfpTranspose2(int i, int j, float *in, float *out); #endif #ifdef USE_FFTWF extern int fftwf_transpose(int i, int j, float *in, float *out); #endif #if defined(__i386__) || defined(__x86_64__) || defined(USE_SSE) extern int v_vGetPowerSpectrumUnrolled( sah_complex * cx_FreqData, float * fp_PowerSpectrum, int ul_NumDataPoints ); extern int v_vGetPowerSpectrum2( sah_complex * cx_FreqData, float * fp_PowerSpectrum, int ul_NumDataPoints ); extern int v_vGetPowerSpectrumUnrolled2( sah_complex * cx_FreqData, float * fp_PowerSpectrum, int ul_NumDataPoints ); #endif #ifdef USE_ALTIVEC extern int v_vGetPowerSpectrumG4( sah_complex * cx_FreqData, float * fp_PowerSpectrum, int ul_NumDataPoints ); extern int v_vChirpDataG4( sah_complex * cx_DataArray, sah_complex * cx_ChirpDataArray, int ChirpRateInd, double ChirpRate, int ul_NumDataPoints, double sample_rate ); extern int v_vChirpDataG5( sah_complex * cx_DataArray, sah_complex * cx_ChirpDataArray, int ChirpRateInd, double ChirpRate, int ul_NumDataPoints, double sample_rate ); #endif #if defined(__x86_64__) || defined(_M_AMD64) extern int v_vChirpData_x86_64( sah_complex * cx_DataArray, sah_complex * cx_ChirpDataArray, int ChirpRateInd, double ChirpRate, int ul_NumDataPoints, double sample_rate ); #endif #if defined(USE_AVX) extern int avxSupported(void); extern int avx_ChirpData_a( sah_complex * cx_DataArray, sah_complex * cx_ChirpDataArray, int chirp_rate_ind, const double chirp_rate, int ul_NumDataPoints, const double sample_rate ); extern int avx_ChirpData_b( sah_complex * cx_DataArray, sah_complex * cx_ChirpDataArray, int chirp_rate_ind, const double chirp_rate, int ul_NumDataPoints, const double sample_rate ); extern int avx_ChirpData_c( sah_complex * cx_DataArray, sah_complex * cx_ChirpDataArray, int chirp_rate_ind, const double chirp_rate, int ul_NumDataPoints, const double sample_rate ); extern int avx_ChirpData_d( sah_complex * cx_DataArray, sah_complex * cx_ChirpDataArray, int chirp_rate_ind, const double chirp_rate, int ul_NumDataPoints, const double sample_rate ); extern int v_avxTranspose4x8ntw(int x, int y, float *in, float *out); extern int v_avxTranspose4x16ntw(int x, int y, float *in, float *out); extern int v_avxTranspose8x4ntw(int x, int y, float *in, float *out); extern int v_avxTranspose8x8ntw_a(int x, int y, float *in, float *out); extern int v_avxTranspose8x8ntw_b(int x,int y, float *in, float *out ); extern int v_avxGetPowerSpectrum( sah_complex* FreqData, float* PowerSpectrum, int NumDataPoints ); #endif #if defined(__arm__) && defined(__VFP_FP__) && !defined(__SOFTFP__) #ifdef USE_NEON extern int neon_GetPowerSpectrum( sah_complex * cx_FreqData, float * fp_PowerSpectrum, int ul_NumDataPoints ); #endif extern int vfp_GetPowerSpectrum( sah_complex * cx_FreqData, float * fp_PowerSpectrum, int ul_NumDataPoints ); extern int vfp_ChirpData ( sah_complex * cx_DataArray, sah_complex * cx_ChirpDataArray, int ChirpRateInd, double ChirpRate, int ul_NumDataPoints, double sample_rate ); #ifdef USE_NEON extern int neon_ChirpData ( sah_complex * cx_DataArray, sah_complex * cx_ChirpDataArray, int ChirpRateInd, double ChirpRate, int ul_NumDataPoints, double sample_rate ); #endif #endif #endif boinc-app-seti_8.00~svn3701.orig/client/vector/analyzeFuncs_fpu.cpp0000644000175000017500000002731413053662010025315 0ustar locutuslocutus// Copyright 2007 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "sah_config.h" #include #include #include "analyzeFuncs.h" #include "analyzeFuncs_vector.h" #include "sincos.h" #ifdef BOINC_APP_GRAPHICS #include "sah_gfx_main.h" #endif #ifndef M_PI #define M_PI 3.14159265358979323846 #endif // ********************************************************* // // JWS: FPU chirp using Flemming Pedersen (CERN) fast double sincos, // http://pedersen.web.cern.ch/pedersen/project-leir-dsp-bc/matlab/fast_sine_cosine/fast_sine_cosine.doc // Similar to Marcus Mendenhall Faster SinCos except no final adjustment // because doubles produce good accuracy without. // // Includes quick FPU rounding developed for sse1 version. // inline void set_up_fastfrac(double roundVal) { // this routine only exists for compilers that can't tell that a value is // being popped from the FP stack and then immediately reloaded. #if defined(_MSC_VER) && !defined(_WIN64) __asm fld roundVal; // get roundVal #endif } inline void clean_up_fastfrac() { // this routine only exists for compilers than needed set_up_fastfrac() #if defined(_MSC_VER) && !defined(_WIN64) __asm fstp st(0); // pop roundVal off FPU stack #endif } // This routine should work as long as x86_64 supports x87 instructions. // After that the illegal instruction trap should take care of it. inline double fastfrac(double val, double roundVal) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("fastfrac()"); #endif // reduce val to the range (-0.5, 0.5) using "val - round(val)" #if defined(_MSC_VER) && !defined(_WIN64) __asm { fld val // get angle fadd st(0), st(1) // + roundVal fsub st(0), st(1) // - roundVal, integer in st(0) fsubr val // angle - integer fstp val // store reduced angle } #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) __asm__ __volatile__( "fadd %2,%0\n" // + roundVal " fsub %2,%0\n" // - roundVal, integer in st(0) " fsubr %3,%0\n" // angle - integer : "=&t" (val) : "0" (val), "f" (roundVal), "f" (val) ); #elif defined(_WIN64)//R: doesn't correctly work for ARM val -= ((val + roundVal) - roundVal); // TODO: ADD CHECK THAT THIS WORKS #else val -= floor(val + 0.5); #endif #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return val; } static unsigned short fpucw1; inline void set_extended_precision() { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("set_extended_precision()"); #endif // Windows and *BSD operate the X87 FPU so it rounds at mantissa bit 53, the // quick rounding algorithm needs rounding at the last bit. unsigned short fpucw2; #if defined(_MSC_VER) && !defined(_WIN64) // MSVC no inline assembly for 64 bit __asm fnstcw fpucw1; fpucw2 = fpucw1 | 0x300; __asm fldcw fpucw2; #elif defined(__GNUC__) && (defined(_WIN32) || defined(_WIN64) || defined(_BSD)) __asm__ __volatile__ ("fnstcw %0" : "=m" (fpucw1)); fpucw2 = fpucw1 | 0x300; __asm__ __volatile__ ("fldcw %0" : : "m" (fpucw2)); #else // Nothing necessary for linux, osx, _WIN64 VC++ and most everything else. #endif #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } inline void restore_fpucw() { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("restore_fpucw()"); #endif #if defined(_MSC_VER) && !defined(_WIN64) __asm fldcw fpucw1; #elif defined(__GNUC__) && (defined(_WIN32) || defined(_WIN64) || defined(_BSD)) __asm__ __volatile__ ("fldcw %0" : : "m" (fpucw1)); #else // NADA #endif #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } double z; int fpu_ChirpData ( sah_complex * cx_DataArray, sah_complex * cx_ChirpDataArray, int ChirpRateInd, double ChirpRate, int ul_NumDataPoints, double sample_rate ) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("fpu_ChirpData()"); #endif if (ChirpRateInd == 0) { memcpy(cx_ChirpDataArray, cx_DataArray, (int)ul_NumDataPoints * sizeof(sah_complex) ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } double srate = ChirpRate * 0.5 / (sample_rate * sample_rate); #if (!defined(__GNUC__) && defined(_WIN64)) || \ (defined(__GNUC__) && !(defined(__i386__) || defined(__x86_64__))) double roundVal = (srate >= 0.0) ? TWO_TO_52 : -TWO_TO_52; #else double roundVal = (srate >= 0.0) ? ROUNDX87 : -ROUNDX87; #endif int i, j, vEnd; unsigned short fpucw1, fpucw2; vEnd = ul_NumDataPoints - (ul_NumDataPoints & 7); // main loop for (i = 0; i < vEnd; i += 8) { double angles[8], dtemp; double cd1, cd2, cd3; double x, y; double s, c; float real, imag; dtemp = double( i ); angles[0] = dtemp+0.0; angles[1] = dtemp+1.0; angles[2] = dtemp+2.0; angles[3] = dtemp+3.0; angles[4] = dtemp+4.0; angles[5] = dtemp+5.0; angles[6] = dtemp+6.0; angles[7] = dtemp+7.0; // calculate the input angle angles[0] *= angles[0] * srate; // angle^2 * rate angles[1] *= angles[1] * srate; angles[2] *= angles[2] * srate; angles[3] *= angles[3] * srate; angles[4] *= angles[4] * srate; angles[5] *= angles[5] * srate; angles[6] *= angles[6] * srate; angles[7] *= angles[7] * srate; // Do 8 angles to amortize the time cost of precision switching. set_extended_precision(); set_up_fastfrac(roundVal); angles[0]=fastfrac(angles[0],roundVal); angles[1]=fastfrac(angles[1],roundVal); angles[2]=fastfrac(angles[2],roundVal); angles[3]=fastfrac(angles[3],roundVal); angles[4]=fastfrac(angles[4],roundVal); angles[5]=fastfrac(angles[5],roundVal); angles[6]=fastfrac(angles[6],roundVal); angles[7]=fastfrac(angles[7],roundVal); clean_up_fastfrac(); restore_fpucw(); for ( j = 0; j < 8; j++ ) { // square angle to the range [0, 0.25) y = angles[j] * angles[j]; // perform the initial polynomial approximations s = y * FS4; c = y * FC3; s += FS3; c += FC2; s *= y; c *= y; s += FS2; c += FC1; s *= y; c *= y; s += FS1; s *= angles[j]; c += 1; // perform first angle doubling x = c * c - s * s; y = s * c * 2; cd1 = x * y; cd2 = x * x; cd3 = y * y; // perform second angle doubling s = cd1 * 2; c = cd2 - cd3; // chirp and store real = (float)(cx_DataArray[i + j][0] * c - cx_DataArray[i + j][1] * s); imag = (float)(cx_DataArray[i + j][0] * s + cx_DataArray[i + j][1] * c); cx_ChirpDataArray[i + j][0] = real; cx_ChirpDataArray[i + j][1] = imag; } } if( i < ul_NumDataPoints) { // use original routine to finish up any tailings (max stride-1 elements) v_ChirpData(cx_DataArray+i, cx_ChirpDataArray+i , ChirpRateInd, ChirpRate, ul_NumDataPoints-i, sample_rate); } analysis_state.FLOP_counter+=12.0*ul_NumDataPoints; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } // opt_v_ChirpData // 8-10-06 BENH - Unrolled loop 3 times to allow for FPU latency & reduce loop overhead //..............- Removed conditionals from loop // xx-xx-03 ERICK - Created function // extern void CalcTrigArray (int len, int ChirpRateInd); int fpu_opt_ChirpData ( sah_complex * cx_DataArray, sah_complex * cx_ChirpDataArray, int ChirpRateInd, double ChirpRate, int ul_NumDataPoints, double sample_rate ){ #ifdef USE_MANUAL_CALLSTACK call_stack.enter("fpu_opt_ChirpData()"); #endif float chirp_sign; // BENH - Pulled conditional out of loop if ( ChirpRateInd == 0 ) { memcpy( cx_ChirpDataArray, cx_DataArray, int( ul_NumDataPoints * sizeof(sah_complex)) ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return ( 0 ); } // calculate trigonometric array this function returns w/o doing // anything when sign of chirp_rate_ind reverses. so we have to take care // of it. // double recip_sample_rate=1.0/sample_rate; chirp_sign = ( ChirpRateInd >= 0 ) ? 1 : -1; const int stride = 2; int i = 0; int last = ul_NumDataPoints - ( stride - 1 ); // what we do depends on how much memory we have... // If we have more than 64MB, we'll cache the chirp table. If not // we'll calculate it each time. bool CacheChirpCalc=((app_init_data.host_info.m_nbytes == 0) || (app_init_data.host_info.m_nbytes >= MIN_TRIGARRAY_MEMORY)); // calculate trigonometric array // this function returns w/o doing nothing when sign of chirp_rate_ind // reverses. so we have to take care of it. if ( CacheChirpCalc ){ CalcTrigArray(ul_NumDataPoints, ChirpRateInd ); for ( ; i < last ; i += stride ){ register double c1, c2, d1, d2; register float R1, R2, I1, I2, t1, t2; c1 = CurrentTrig[i + 0].Cos; d1 = CurrentTrig[i + 0].Sin * chirp_sign; // BENH - opt - avoid branch by multiply c2 = CurrentTrig[i + 1].Cos; d2 = CurrentTrig[i + 1].Sin * chirp_sign; // d = (chirp_rate_ind >0)? CurrentTrig[i].Sin : // -CurrentTrig[i].Sin; Sometimes chirping is done in place. We // don't want to overwrite data prematurely. // R1 = cx_DataArray[i + 0][0] * c1; t1 = cx_DataArray[i + 0][1] * d1; I1 = cx_DataArray[i + 0][0] * d1; t2 = cx_DataArray[i + 0][1] * c1; cx_ChirpDataArray[i + 0][0] = R1 - t1; cx_ChirpDataArray[i + 0][1] = I1 + t2; R2 = cx_DataArray[i + 1][0] * c2; t1 = cx_DataArray[i + 1][1] * d2; I2 = cx_DataArray[i + 1][0] * d2; t2 = cx_DataArray[i + 1][1] * c2; cx_ChirpDataArray[i + 1][0] = R2 - t1; cx_ChirpDataArray[i + 1][1] = I2 + t2; } } // cx_ChirpDataArray[64][1] = 3.012345; // Too little memory to cache sin/cos or just falling out of // 'CacheChirpCalc' loop // use original routine to finish up any tailings (max stride-1 elements) for( ;i < ul_NumDataPoints; i++) { double dd,cc; double time=static_cast(i)*recip_sample_rate; // since ang is getting moded by 2pi, we calculate "ang mod 2pi" // before the call to sincos() inorder to reduce roundoff error. // (Bug submitted by Tetsuji "Maverick" Rai) double ang = 0.5*ChirpRate*time*time; float c, d, real, imag; ang -= floor(ang); ang *= M_PI*2; sincos(ang,&dd,&cc); c=cc; d=dd; // Sometimes chirping is done in place. // We don't want to overwrite data prematurely. real = cx_DataArray[i][0] * c - cx_DataArray[i][1] * d; imag = cx_DataArray[i][0] * d + cx_DataArray[i][1] * c; cx_ChirpDataArray[i][0] = real; cx_ChirpDataArray[i][1] = imag; } //R count_flops( 12 * ul_NumDataPoints ); analysis_state.FLOP_counter+=12.0*ul_NumDataPoints; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return ( 0 ); } boinc-app-seti_8.00~svn3701.orig/client/sah_gfx_base.h0000644000175000017500000000643412632051341022556 0ustar locutuslocutus // Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. #include #include "boinc_api.h" #include "gutil.h" #include "gdata.h" #include "graphics_data.h" #include "reduce.h" typedef enum { TEXT_STYLE_PILLARS, // panels delimited by cylinders TEXT_STYLE_PANELS, // rotating panels TEXT_STYLE_HEADSUP // 2D text in corners } TEXT_STYLE; // User's graphics-related per-project preferences for SETI@home // struct GRAPHICS_PREFS { TEXT_STYLE text_style; GRAPH_STYLE graph_style; double max_fps; // max frames per second double max_cpu; // max pct of CPU double graph_alpha; double pitch_period; double pitch_range; // degrees double roll_period; double roll_range; int starfield_size; double starfield_speed; double start_hue, hue_change; // determine graph colors double grow_time; double hold_time; void parse_project_prefs(char*); void defaults(); GRAPHICS_PREFS() { defaults(); }; }; class SAH_GRAPHICS_BASE: /* public GDATA, */ public GRAPHICS_PREFS { public: double roll_angle; double roll_phase; double pitch_angle; double pitch_phase; STARFIELD starfield; TEXTURE_DESC seti_logo_texture; TEXTURE_DESC user_logo_texture; TEXTURE_DESC background_texture; APP_INIT_DATA app_init_data; double viewpoint_distance; int width, height; REDUCED_ARRAY_RENDER rarray; SAH_SHMEM* sah_shmem; GDATA* gdata; SAH_GRAPHICS_BASE(); void data_struct_init(); void graphics_thread_init(); void reread_prefs(); void setup_given_prefs(); void resize(int, int); void start_rotate(); void incr_rotate(double dt); void end_rotate(); void draw_pillars(); void render_logos(); void render_background(); void render_3d_graph(double time_of_day); }; extern void set_viewpoint(double); extern bool nographics(); boinc-app-seti_8.00~svn3701.orig/client/s_util.cpp0000644000175000017500000002111212632156532021775 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // util.C // // $Id: s_util.cpp,v 1.10.2.4 2006/12/14 22:21:47 korpela Exp $ // #include "sah_config.h" #include #include #include #include #include #include #include #include "diagnostics.h" #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SIGNAL_H #include #endif #ifdef HAVE_SYS_SIGNAL_H #include #endif #include "timecvt.h" #include "util.h" #include "s_util.h" const char * const seti_error::message[]={ "Success", "Can't create file -- disk full?", "Can't read from file", "Can't write to file -- disk full?", "Can't allocate memory", "Can't open file", "Bad workunit header", "Garbled encoded workunit", "Garbled binary workunit", "result_overflow", "Unhandled signal", "atexit() failure", "Vectorized functions unsupported", "Floating point failure" }; void seti_error::print() const { std::cerr << "SETI@home error " << -value << " " ; if ((value <= atexit_failure) && (value >=0)) { std::cerr << message[value] ; } else { std::cerr << "Unknown error" ; } std::cerr << std::endl << data << std::endl; std::cerr << "File: " << file << std::endl; std::cerr << "Line: " << line << std::endl; std::cerr << std::endl; #ifdef USE_MANUAL_CALLSTACK call_stack.print_stack(); #endif } void strip_cr(char*p ) { char* q = strchr(p, '\n'); if (q) *q = 0; } // Encode a range of bytes into printable chars, and write to file. // Encodes 3 bytes into 4 chars. // May read up to two bytes past end. void encode(unsigned char* bin, int nbytes, FILE* f) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("encode()"); #endif int count=0, offset=0, nleft; unsigned char c0, c1, c2, c3; for (nleft = nbytes; nleft > 0; nleft -= 3) { c0 = bin[offset]&0x3f; // 6 c1 = (bin[offset]>>6) | (bin[offset+1]<<2)&0x3f; // 2+4 c2 = ((bin[offset+1]>>4)&0xf) | (bin[offset+2]<<4)&0x3f;// 4+2 c3 = bin[offset+2]>>2; // 6 c0 += 0x20; c1 += 0x20; c2 += 0x20; c3 += 0x20; fprintf(f, "%c%c%c%c", c0, c1, c2, c3); offset += 3; count += 4; if (count == 64) { count = 0; fprintf(f, "\n"); } } fprintf(f, "\n"); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } // Read from file, decode into bytes, put in array. // May write up to two bytes past end of array. int decode(unsigned char* bin, int nbytes, FILE* f) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("decode()"); #endif unsigned char buf[256], *p, c0, c1, c2; int i, n, m, nleft = nbytes, offset=0; int nbadlines = 0; while (1) { if (nleft <= 0) break; p = (unsigned char*)fgets((char*)buf, 256, f); if (!p) { SETIERROR(BAD_DECODE, "file ended too soon"); } n = (int)strlen((char*)buf)-1; if (n%4) { nbadlines++; if (nbadlines == 100) { SETIERROR(BAD_DECODE, "too many bad lines - rejecting file"); } n = 64; fprintf(stderr, "encoded line has bad length: %s\n", buf); } m = (n/4)*3; if (m > nleft+2) { //fprintf(stderr, "encoded line too long\n"); //return BAD_DECODE; n = ((nleft+2)/3)*4; } p = buf; for (i=0; i>2 | p[2]<<4; // 4 + 4 c2 = p[2]>>4 | p[3]<<2; // 2 + 6 p += 4; bin[offset++] = c0; bin[offset++] = c1; bin[offset++] = c2; nleft -= 3; } } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } // Read from file, put in array. int read_bin_data(unsigned char* bin, int nbytes, FILE* f) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("read_bin_data()"); #endif int i; size_t n; for(i=0; i < nbytes; i += 256) { n = fread((void *)(bin+i), 256, 1, f); if (!n) { SETIERROR(BAD_BIN_READ,"file ended too soon"); } } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } // see the doc on binary data representation void bits_to_floats(unsigned char* raw, sah_complex* data, int nsamples, int bits_per_sample) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("bits_to_floats"); #endif int i, j, k=0; unsigned char c; const float v2[2]={-1.0,1.0}; const float v4[4]={-3.3358750,-1.0,1.0,3.3358750}; switch (bits_per_sample) { case 2: for (i=0; i>1)&1]; data[k][1] = v2[(c&1)]; k++; c >>= 2; } } break; case 4: for (i=0; i>2)&3]; data[k][1] = v4[c&3]; k++; c >>= 4; } } break; case 8: for (i=0; i((c>>4)&15)-7.5f; data[k][1] = static_cast(c&15)-7.5f; k++; } break; case 16: for (i=0; i(sc); sc = raw[i]; data[k][1] = static_cast(sc); k++; } break; default: fprintf(stderr,"Unsupported bit depth (%d)\n",bits_per_sample); throw BAD_DECODE; } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } int float_to_uchar(float float_element[], unsigned char char_element[], long num_elements, float scale_factor) { long i, test_int; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("float_to_uchar()"); #endif for(i = 0; i < num_elements; i++) { test_int = ROUND(float_element[i]/scale_factor); if(test_int >= 0 && test_int <= 255) char_element[i] = (unsigned)test_int; else char_element[i] = test_int < 0 ? 0 : 255; } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } char* error_string(int e) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("error_string()"); #endif char* p; static char buf[256]; switch(e) { case CANT_CREATE_FILE: sprintf(buf, "Can't create file - disk full?"); p = buf; break; case WRITE_FAILED: p = "Can't write to file - disk full?"; break; case MALLOC_FAILED: p = "Can't allocate memory"; break; case FOPEN_FAILED: sprintf(buf, "Can't open file"); p = buf; break; case BAD_HEADER: p = "Bad file header"; break; case BAD_DECODE: p = "Can't decode data"; break; default: sprintf(buf, "Unknown error %d", e); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return buf; } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return p; } boinc-app-seti_8.00~svn3701.orig/client/pulsefind.h0000644000175000017500000000773112313644616022150 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // $Id: pulsefind.h,v 1.3.2.3 2007/06/08 03:09:45 korpela Exp $ // #ifndef _PULSEFIND_H_ #define _PULSEFIND_H_ // constants for integerized period in preplanning #define C3X2TO14 0xC000 #define C3X2TO13 0x6000 // constant for preplan limit #define PPLANMAX 511 typedef float (*sum_func)( float *[], struct PoTPlan *); struct PoTPlan { int di; // count 0 = done float *dest; // (destination) int tmp0; // Tmp0 [+offset for 2sum] union {int tmp1; int offset; }; // Tmp1 for 3,4,5sum - source offset for 2sum int tmp2; // Tmp2 int tmp3; // Tmp3 sum_func fun_ptr; // pointer to sum routine unsigned long cperiod; // *0xC000 float thresh; // invert_lcgf() int na; // num_adds or num_adds_2 }; // std::max is SLOW // - Not really. GCC x64 just generates a "maxsd" instruction for either // this macro or std::max(). x86 version generates fucomi followed by, // fcmovbe for either. Oh well, it doesn't hurt anything to use a // macro. #define UNSTDMAX(a,b) (((a) > (b)) ? (a) : (b)) #define FOLDTBLEN 32 struct FoldSet { sum_func *f3; // to table for fold by 3 sum_func *f4; // to table for fold by 4 sum_func *f5; // to table for fold by 5 sum_func *f2; // to table for fold by 2 sum_func *f2AL; // to table for fold by 2 needing tmp0 aligned const char *name; // to string literal name of set }; // forward declare folding sets extern FoldSet vfpFoldMain; // in analyzeFuncs_neon.cpp extern FoldSet neonFoldMain; // in analyzeFuncs_neon.cpp extern FoldSet AVXfold_a; // in analyzeFuncs_avx.cpp extern FoldSet AVXfold_a; // in analyzeFuncs_avx.cpp extern FoldSet AVXfold_c; // in analyzeFuncs_avx.cpp extern FoldSet sse_ben_fold; // in analyzeFuncs_sse.cpp extern FoldSet BHSSEfold; // in analyzeFuncs_sse.cpp extern FoldSet AKSSEfold; // in analyzeFuncs_sse.cpp extern FoldSet AKavfold; // in analyzeFuncs_altivec.cpp extern FoldSet swifold; // in Pulsefind - default set extern FoldSet Foldmain; // in Pulsefind - used set // routines in pulsefind.cpp int find_triplets(const float * fp_PulsePot, int PulsePotLen, float triplet_thresh, int TOffset, int ul_PoT); int find_pulse(const float * fp_PulsePot, int PulsePotLen, float pulse_thresh, int TOffset, int ul_PoT); int CopyFoldSet(FoldSet *dst, FoldSet *src); #endif boinc-app-seti_8.00~svn3701.orig/client/Makefile.am0000644000175000017500000002170712636666326022053 0ustar locutuslocutus## $Id: Makefile.am,v 1.7.2.21 2007/08/01 00:15:31 korpela Exp $ include $(top_srcdir)/Makefile.incl BOINC_LIBS = -lboinc_api -lboinc CLIENT_C_FLAGS = $(APP_CFLAGS) $(CFLAGS) \ $(DEFS) \ -DTEXT_UI -DNDEBUG -DCLIENT \ -I$(top_srcdir)/db \ -I$(top_srcdir)/client \ -I$(top_srcdir)/client/win_build \ $(BOINC_CFLAGS) \ $(PTHREAD_CFLAGS) \ $(ASMLIB_CFLAGS) CLIENT_LD_FLAGS = $(PTHREAD_CFLAGS) $(LDFLAGS) $(APP_LDFLAGS) CLIENT_LD_ADD = $(PTHREAD_LIBS) $(BOINC_LIBS) $(APP_LIBS) if ENABLE_GUI CLIENT_BIN = $(CLIENT_PROG) $(CLIENT_NATIVE) $(DEBUG_NATIVE) $(DEBUG_PROG) GUI_BIN = seti_graphics GUI_C_FLAGS = $(CLIENT_C_FLAGS) $(GRAPHICS_CFLAGS) GUI_LD_ADD = $(GRAPHICS_LIBS_RAW) CLIENT_LD_FLAGS += $(LDSTATIC) CLIENT_LD_ADD += -L$(BOINCDIR)/api -L$(BOINCDIR)/lib $(BOINC_LIBS) SAH_GRX_SOURCES = sah_gfx_main.cpp else #no graphics SAH_GRX_SOURCES = CLIENT_BIN = $(CLIENT_PROG) $(DEBUG_PROG) endif if X86_64 CLIENT_C_FLAGS+= -march=opteron -mtune=generic -msse2 -DUSE_SSE -DUSE_SSE2 endif all: client-bin client-bin: $(CLIENT_BIN) $(DEBUG_PROG): seti_boinc @RM@ -f $(DEBUG_PROG) @LN@ seti_boinc $(DEBUG_PROG) $(CLIENT_PROG): seti_boinc @CP@ seti_boinc $(CLIENT_PROG) @STRIP@ $(CLIENT_PROG) noinst_PROGRAMS = seti_boinc if ENABLE_TESTS noinst_PROGRAMS += hires_timer_test hires_timer_test_SOURCES= vector/hires_timer.cpp hires_timer_test_CXXFLAGS=-DTEST_TIMER $(CXXFLAGS) $(CLIENT_C_FLAGS) hires_timer_test_LDFLAGS=$(CLIENT_LD_FLAGS) hires_timer_test_LDADD=$(CLIENT_LD_ADD) endif seti_boinc_SOURCES = \ main.cpp \ vector/analyzeFuncs_vector.cpp \ vector/analyzeFuncs_fpu.cpp \ vector/analyzeFuncs_sse.cpp \ vector/analyzeFuncs_sse2.cpp \ vector/analyzeFuncs_sse3.cpp \ vector/analyzeFuncs_avx.cpp \ vector/analyzeFuncs_x86_64.cpp \ vector/analyzeFuncs_altivec.cpp \ vector/analyzeFuncs_neon.S \ vector/analyzeFuncs_vfp.S \ vector/analyzeFuncs_vfp_aux.cpp \ vector/x86_float4.cpp \ vector/hires_timer.cpp \ analyzeFuncs.cpp \ analyzeReport.cpp \ analyzePoT.cpp \ pulsefind.cpp \ gaussfit.cpp \ lcgamm.cpp \ malloc_a.cpp \ seti.cpp \ seti_header.cpp \ timecvt.cpp \ s_util.cpp \ sah_version.cpp \ worker.cpp \ chirpfft.cpp \ spike.cpp \ autocorr.cpp \ progress.cpp \ fft8g.cpp \ gdata.cpp \ ../db/schema_master.cpp \ ../db/sqlrow.cpp \ ../db/sqlblob.cpp \ ../db/xml_util.cpp \ $(SAH_GRX_SOURCES) seti_boinc_CFLAGS = $(CLIENT_C_FLAGS) seti_boinc_CXXFLAGS = $(CLIENT_C_FLAGS) seti_boinc_LDFLAGS = $(CLIENT_LD_FLAGS) seti_boinc_LDADD = $(CLIENT_LD_ADD) seti_boinc_LINK = $(CXX) $(seti_boinc_CXXFLAGS) $(seti_boinc_LDFLAGS) -o $@ if I386 # allow use of sse instructions on i[3456]86 seti_boinc-analyzeFuncs_sse3.o: vector/analyzeFuncs_sse3.cpp if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(seti_boinc_CXXFLAGS) $(CXXFLAGS) -DUSE_SSE -DUSE_SSE2 \ -DUSE_SSE3 -D__SSE__ -D__SSE2__ -D__SSE3__ \ -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -msse3 \ -c -o $@ $<; then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi seti_boinc-analyzeFuncs_sse2.o: vector/analyzeFuncs_sse2.cpp if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(seti_boinc_CXXFLAGS) $(CXXFLAGS) -DUSE_SSE -DUSE_SSE2 \ -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -msse2 \ -c -o $@ $<; then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi seti_boinc-analyzeFuncs_sse.o: vector/analyzeFuncs_sse.cpp if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(seti_boinc_CXXFLAGS) $(CXXFLAGS) -DUSE_SSE \ -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -msse \ -c -o $@ $<; then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi seti_boinc-analyzeFuncs_x86_64.o: vector/analyzeFuncs_x86_64.cpp if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(seti_boinc_CXXFLAGS) $(CXXFLAGS) -DUSE_SSE \ -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -mfpmath=sse -msse2 \ -c -o $@ $<; then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi seti_boinc-x86_float4.o: vector/x86_float4.cpp if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(seti_boinc_CXXFLAGS) $(CXXFLAGS) -DUSE_SSE \ -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -msse \ -c -o $@ $<; then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi if AVX seti_boinc-analyzeFuncs_avx.o: vector/analyzeFuncs_avx.cpp if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(seti_boinc_CXXFLAGS) $(CXXFLAGS) -DUSE_SSE -DUSE_SSE2 \ -DUSE_SSE3 -DUSE_AVX -D__SSE__ -D__SSE2__ -D__SSE3__ \ -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -mavx \ -c -o $@ $<; then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi seti_boinc-analyzeFuncs_vector.o: vector/analyzeFuncs_vector.cpp if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(seti_boinc_CXXFLAGS) $(CXXFLAGS) -DUSE_SSE -DUSE_SSE2 \ -DUSE_SSE3 -DUSE_3DNOW -DUSE_AVX \ -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ -c -o $@ $<; then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi else seti_boinc-analyzeFuncs_vector.o: vector/analyzeFuncs_vector.cpp if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(seti_boinc_CXXFLAGS) $(CXXFLAGS) -DUSE_SSE -DUSE_SSE2 \ -DUSE_SSE3 -DUSE_3DNOW \ -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ -c -o $@ $<; then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi endif endif if X86_64 # allow use of sse instructions on x86_64 seti_boinc-analyzeFuncs_sse3.o: vector/analyzeFuncs_sse3.cpp if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(seti_boinc_CXXFLAGS) $(CXXFLAGS) -DUSE_SSE3 \ -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -msse3 \ -c -o $@ $<; then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi if AVX seti_boinc-analyzeFuncs_avx.o: vector/analyzeFuncs_avx.cpp if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(seti_boinc_CXXFLAGS) $(CXXFLAGS) -DUSE_SSE3 -DUSE_AVX \ -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -mavx \ -c -o $@ $<; then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi seti_boinc-analyzeFuncs_vector.o: vector/analyzeFuncs_vector.cpp if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(seti_boinc_CXXFLAGS) $(CXXFLAGS) -DUSE_SSE3 -DUSE_3DNOW -DUSE_AVX \ -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ -c -o $@ $<; then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi else seti_boinc-analyzeFuncs_vector.o: vector/analyzeFuncs_vector.cpp if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(seti_boinc_CXXFLAGS) $(CXXFLAGS) -DUSE_SSE3 -DUSE_3DNOW \ -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ -c -o $@ $<; then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi endif endif if PPC # allow use of altivec instructions on PPC seti_boinc-analyzeFuncs_altivec.o: vector/analyzeFuncs_altivec.cpp if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(seti_boinc_CXXFLAGS) $(CXXFLAGS) -DUSE_ALTIVEC \ -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -faltivec -mabi=altivec \ -c -o $@ $<; then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi seti_boinc-analyzeFuncs_vector.o: vector/analyzeFuncs_vector.cpp if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(seti_boinc_CXXFLAGS) $(CXXFLAGS) -DUSE_ALTIVEC \ -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ -c -o $@ $<; then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi endif if LINUX # too much optimization on main.cpp breaks the client for some reason seti_boinc-main.o: main.cpp if $(CXX) --include ../sah_config.h $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(DEFS) -DTEXT_UI -DNDEBUG -DCLIENT $(CLIENT_C_FLAGS) -I$(top_srcdir)/db -I$(top_srcdir) $(BOINC_CFLAGS) $(PTHREAD_CFLAGS) -O2 -Wall -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi endif if ENABLE_GUI noinst_PROGRAMS += seti_graphics seti_graphics_SOURCES = \ timecvt.cpp \ sah_gfx.cpp \ sah_gfx_base.cpp \ graphics_main.cpp \ sah_version.cpp seti_graphics_CFLAGS = $(GUI_C_FLAGS) seti_graphics_CXXFLAGS = $(GUI_C_FLAGS) seti_graphics_LDFLAGS = $(GUI_LD_FLAGS) seti_graphics_LDADD = $(GUI_LD_ADD) $(BOINC_LIBS) $(DEBUG_NATIVE): $(GUI_BUILD) @RM@ -f $(DEBUG_NATIVE) @LN@ sah_graphics $(DEBUG_NATIVE) $(CLIENT_NATIVE): $(DEBUG_NATIVE) @RM@ -f $(CLIENT_NATIVE) @CP@ $(DEBUG_NATIVE) $(CLIENT_NATIVE) endif boinc-app-seti_8.00~svn3701.orig/client/working_collect2_line_for_android_armv6-neon0000644000175000017500000000415212313644616030617 0ustar locutuslocutus /usr/arm-linux-androideabi/bin/../libexec/gcc/arm-linux-androideabi/4.6/collect2 --sysroot=/usr/arm-linux-androideabi/sysroot --eh-frame-hdr -dynamic-linker /system/bin/linker -X -m armelf_linux_eabi -z noexecstack -z relro -z now -o seti_boinc /usr/arm-linux-androideabi/sysroot/usr/lib/crtbegin_dynamic.o -L/usr/arm-linux-androideabi/arm-linux-androideabi/lib/${targetarch} -L/usr/arm-linux-androideabi/sysroot/usr/lib -L/usr/arm-linux-androideabi/arm-linux-androideabi/lib -L/usr/arm-linux-androideabi/arm-linux-androideabi/lib -L/usr/arm-linux-androideabi/arm-linux-androideabi/lib/${targetarch} -L/usr/arm-linux-androideabi/sysroot/usr/lib -L/usr/arm-linux-androideabi/arm-linux-androideabi/lib -L/usr/arm-linux-androideabi/bin/../lib/gcc/arm-linux-androideabi/4.6 -L/usr/arm-linux-androideabi/bin/../lib/gcc -L/usr/arm-linux-androideabi/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/lib -L/usr/arm-linux-androideabi/sysroot/usr/lib seti_boinc-main.o seti_boinc-analyzeFuncs_vector.o seti_boinc-analyzeFuncs_fpu.o seti_boinc-analyzeFuncs_sse.o seti_boinc-analyzeFuncs_sse2.o seti_boinc-analyzeFuncs_sse3.o seti_boinc-analyzeFuncs_avx.o seti_boinc-analyzeFuncs_x86_64.o seti_boinc-analyzeFuncs_altivec.o analyzeFuncs_neon.o analyzeFuncs_vfp.o seti_boinc-analyzeFuncs_vfp_aux.o seti_boinc-x86_float4.o seti_boinc-hires_timer.o seti_boinc-analyzeFuncs.o seti_boinc-analyzeReport.o seti_boinc-analyzePoT.o seti_boinc-pulsefind.o seti_boinc-gaussfit.o seti_boinc-lcgamm.o seti_boinc-malloc_a.o seti_boinc-seti.o seti_boinc-seti_header.o seti_boinc-timecvt.o seti_boinc-s_util.o seti_boinc-sah_version.o seti_boinc-worker.o seti_boinc-chirpfft.o seti_boinc-spike.o seti_boinc-autocorr.o seti_boinc-progress.o seti_boinc-fft8g.o seti_boinc-gdata.o seti_boinc-schema_master.o seti_boinc-sqlrow.o seti_boinc-sqlblob.o seti_boinc-xml_util.o -lboinc_opencl -lboinc_api -lboinc -lfftw3f /usr/arm-linux-androideabi/arm-linux-androideabi/lib/libstdc++.a -lssl -lcrypto -Bdynamic -lm -Bstatic --whole-archive --no-whole-archive -lgcc -Bdynamic -llog -lc -ldl -Bstatic -lgcc /usr/arm-linux-androideabi/sysroot/usr/lib/crtend_android.o boinc-app-seti_8.00~svn3701.orig/client/sah_version.h0000644000175000017500000000307510671336410022467 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. //$Id: sah_version.h,v 1.1.2.1 2007/05/31 22:08:12 korpela Exp $ extern int gmajor_version; extern int gminor_version; boinc-app-seti_8.00~svn3701.orig/client/lcgamm.h0000644000175000017500000000333410671336410021405 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // $Id: lcgamm.h,v 1.3.2.4 2007/03/01 22:56:29 vonkorff Exp $ // float lcgf(float a, float x, long& timecalled, long& numcalls); double lcgf(double a, double x); float lcgf(float a, float x, long& timecalled, long& numcalls); float invert_lcgf(float y,float a, float frac_err); boinc-app-seti_8.00~svn3701.orig/client/analyzeReport.cpp0000644000175000017500000003765312643777667023402 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // analyzeReport.C // $Id: analyzeReport.cpp,v 1.40.2.9 2007/05/31 22:03:09 korpela Exp $ // #include "sah_config.h" #include #include #include #include #include #include "diagnostics.h" #include "util.h" #include "s_util.h" #ifdef BOINC_APP_GRAPHICS #include "sah_gfx_main.h" #endif #include "analyze.h" #include "gaussfit.h" #include "seti.h" #include "chirpfft.h" #include "analyzeReport.h" #include "analyzePoT.h" #ifdef __arm__ #include "vector/fp_arm.h" #endif #include "../db/schema_master.h" // outfile will be flushed at checkpoint time and just before // normal program exit. MFILE outfile; SPIKE_INFO * best_spike; AUTOCORR_INFO * best_autocorr; GAUSS_INFO * best_gauss; PULSE_INFO * best_pulse; TRIPLET_INFO * best_triplet; int signal_count = 0; int spike_count = 0; int autocorr_count = 0; int pulse_count = 0; int triplet_count = 0; int gaussian_count = 0; void reload_graphics_state() { #ifdef BOINC_APP_GRAPHICS #ifdef USE_MANUAL_CALLSTACK call_stack.enter("reload_graphics_state()"); #endif if (!nographics()) { sah_graphics->si.copy(best_spike, true); sah_graphics->ai.copy(best_autocorr, true); sah_graphics->gi.copy(best_gauss, true); sah_graphics->pi.copy(best_pulse, true); sah_graphics->ti.copy(best_triplet, true); } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif #endif } void reset_high_scores() { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("reset_high_scores()"); #endif if(best_spike) delete(best_spike); if(best_autocorr) delete(best_autocorr); if(best_gauss) delete(best_gauss); if(best_pulse) delete(best_pulse); if(best_triplet) delete(best_triplet); best_spike = new(SPIKE_INFO); best_autocorr = new(AUTOCORR_INFO); best_gauss = new(GAUSS_INFO); best_gauss->score=-12; best_pulse = new(PULSE_INFO); best_triplet = new(TRIPLET_INFO); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } static double interpol(double x1,double y1,double x2,double y2, double x) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("interpol()"); #endif double slope=(y2-y1)/(x2-x1); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return slope*(x-x1)+y1; } void time_to_ra_dec(double time_jd, double *ra, double *dec) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("time_to_ra_dec()"); #endif int i=0; double raoffs=0; while ((i 12.0) { raoffs=-24.0; } if ((swi.position_history[i].ra-swi.position_history[i+1].ra)> 12.0) { raoffs=24.0; } *ra=interpol( swi.position_history[i].time, swi.position_history[i].ra, swi.position_history[i+1].time, swi.position_history[i+1].ra+raoffs, time_jd ); if (*ra<0) { *ra+=24; } else if (*ra>24) { *ra-=24; } *dec=interpol( swi.position_history[i].time, swi.position_history[i].dec, swi.position_history[i+1].time, swi.position_history[i+1].dec, time_jd ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } int result_spike(SPIKE_INFO &si) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("result_spike()"); #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.",true); } retval = outfile.printf("%s", si.s.print_xml(0,0,1).c_str()); if (retval < 0) { SETIERROR(WRITE_FAILED,"in result_spike"); } else { signal_count++; spike_count++; } if (signal_count >= swi.analysis_cfg.max_signals) { SETIERROR(RESULT_OVERFLOW,"in result_spike"); } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } int result_autocorr(AUTOCORR_INFO &ai) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("result_autocorr()"); #endif int retval=0; retval = outfile.printf("%s", ai.a.print_xml(0,0,1).c_str()); if (retval < 0) { SETIERROR(WRITE_FAILED,"in result_autocorr"); } else { signal_count++; autocorr_count++; } if (signal_count >= swi.analysis_cfg.max_signals) { SETIERROR(RESULT_OVERFLOW,"in result_autocorr"); } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } int result_gaussian(GAUSS_INFO &gi) { #ifdef USE_MANUAL_CALLSTACK 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.",true);} int retval=0; retval = outfile.printf("%s", gi.g.print_xml(0,0,1).c_str()); if (retval >= 0) { retval= outfile.printf("\n"); } if (retval < 0) { SETIERROR(WRITE_FAILED,"in result_gaussian"); } else { signal_count++; gaussian_count++; } if (signal_count >= swi.analysis_cfg.max_signals) { SETIERROR(RESULT_OVERFLOW,"in result_gaussian"); } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } int ReportTripletEvent( float Power, float MeanPower, float period, float mid_time_bin, int start_time_bin, int freq_bin, int pot_len,const float *PoT, int write_triplet ) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("ReportTripletEvent()"); #endif TRIPLET_INFO ti; triplet triplet; int retval=0, i, j; double step,norm,index; double max_power=0; static int * inv; // debug possible heap corruption -- jeffc #ifdef _WIN32 BOINCASSERT(_CrtCheckMemory()); #endif //JWS: sanity check for found result. if(Power > (float)pot_len){ boinc_temporary_exit(5*60,"Impossible Triplet, retrying from checkpoint.",true); } if (!inv) inv = (int*)calloc_a(swi.analysis_cfg.triplet_pot_length, sizeof(int), MEM_ALIGN); // triplet info ti.score=Power; ti.t.peak_power=Power; ti.t.mean_power=MeanPower; ti.freq_bin=freq_bin; ti.time_bin=mid_time_bin+start_time_bin+0.5f; ti.t.chirp_rate=ChirpFftPairs[analysis_state.icfft].ChirpRate; ti.t.fft_len=ChirpFftPairs[analysis_state.icfft].FftLen; ti.bperiod=period; ti.t.period=static_cast(period*static_cast(ti.t.fft_len)/swi.subband_sample_rate); ti.t.freq=cnvt_bin_hz(freq_bin, ti.t.fft_len); double t_offset=(static_cast(mid_time_bin)+start_time_bin+0.5) *static_cast(ti.t.fft_len)/ swi.subband_sample_rate; ti.t.detection_freq=calc_detection_freq(ti.t.freq,ti.t.chirp_rate,t_offset); ti.t.time=swi.time_recorded+t_offset/86400.0; time_to_ra_dec(ti.t.time, &ti.t.ra, &ti.t.decl); // Populate the min and max PoT arrays. These are only used // for graphics. memset(ti.pot_min,0xff,swi.analysis_cfg.triplet_pot_length*sizeof(int)); memset(ti.pot_max,0,swi.analysis_cfg.triplet_pot_length*sizeof(int)); step=static_cast(pot_len)/swi.analysis_cfg.triplet_pot_length; ti.scale=static_cast(1.0/step); index=0; for (i=0;imax_power) max_power=PoT[i]; } norm=255.0/max_power; float mtb = mid_time_bin; if (pot_len > swi.analysis_cfg.triplet_pot_length) { ti.tpotind0_0 = ti.tpotind0_1 = static_cast(((mtb-period)*swi.analysis_cfg.triplet_pot_length)/pot_len); ti.tpotind1_0 = ti.tpotind1_1 = static_cast(((mtb)*swi.analysis_cfg.triplet_pot_length)/pot_len); ti.tpotind2_0 = ti.tpotind2_1 = static_cast(((mtb+period)*swi.analysis_cfg.triplet_pot_length)/pot_len); for (j=0; j(floor(PoT[j]*norm)); } if ((PoT[j]*norm)>ti.pot_max[i]) { ti.pot_max[i]=static_cast(floor(PoT[j]*norm)); } } } else { memset(inv, -1, swi.analysis_cfg.triplet_pot_length*sizeof(int)); for (i=0;i(floor(PoT[j]*norm)); } if ((PoT[j]*norm)>ti.pot_max[i]) { ti.pot_max[i]=static_cast(floor(PoT[j]*norm)); } } ti.tpotind0_0 = inv[static_cast(mtb-period)]; ti.tpotind0_1 = inv[static_cast(mtb-period+1)]; ti.tpotind1_0 = (inv[static_cast(mtb)]+inv[static_cast(mtb+1)])/2; ti.tpotind1_1 = (inv[static_cast(mtb+1)]+inv[static_cast(mtb+2)])/2; ti.tpotind2_0 = inv[static_cast(mtb+period)]; if (mtb+period+1 >= pot_len) ti.tpotind2_1 = swi.analysis_cfg.triplet_pot_length-1; else ti.tpotind2_1 = inv[static_cast(mtb+period+1)]; } // Update sah_graphics triplet info regardless of whether it is the // best thus far. If a triplet has made it this far, display it. #ifdef BOINC_APP_GRAPHICS if (!nographics()) sah_graphics->ti.copy(&ti); #endif // best thus far ? if (ti.score>best_triplet->score) { if(verbose>=2){ fprintf(stderr,"Best triplet updated:"); fprintf(stderr,"score=%.4g; power=%.4g; freq_bin=%.4g; icfft=%d\n", ti.score,ti.t.peak_power,ti.freq_bin,analysis_state.icfft); } *best_triplet=ti; } if (write_triplet) { if(verbose>=1){ int fft=(ti.t.fft_len>1024)?(ti.t.fft_len/1024):(ti.t.fft_len); char symbol=(ti.t.fft_len>1024)?('k'):(' '); fprintf(stderr,"Triplet: peak=%.7g, time=%.4g, period=%.4g, d_freq=%.12g, chirp=%.5g, fft_len=%d%c\n", ti.t.peak_power,(ti.t.time-swi.time_recorded)*86400,ti.t.period,ti.t.detection_freq,ti.t.chirp_rate,fft,symbol); } retval = outfile.printf("%s", ti.t.print_xml(0,0,1).c_str()); if (retval < 0) { SETIERROR(WRITE_FAILED,"in ReportTripletEvent"); } else { signal_count++; triplet_count++; } if (signal_count >= swi.analysis_cfg.max_signals) { SETIERROR(RESULT_OVERFLOW,"in ReportTripletEvent"); } } // debug possible heap corruption -- jeffc #ifdef _WIN32 BOINCASSERT(_CrtCheckMemory()); #endif #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return(retval); } int ReportPulseEvent(float PulsePower,float MeanPower, float period, int time_bin,int freq_bin, float snr, float thresh, float *folded_pot, int scale, int write_pulse) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("ReportPulseEvent()"); #endif PULSE_INFO pi; pulse pulse; int retval=0, i, len_prof=static_cast(floor(period)); float step,norm,index,MinPower=PulsePower*MeanPower*scale; // debug possible heap corruption -- jeffc #ifdef _WIN32 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.",true); } // pulse info pi.score=snr/thresh; pi.p.peak_power=PulsePower-1; pi.p.mean_power=MeanPower; pi.p.fft_len=ChirpFftPairs[analysis_state.icfft].FftLen; pi.p.chirp_rate=ChirpFftPairs[analysis_state.icfft].ChirpRate; pi.p.period=static_cast(period*static_cast(pi.p.fft_len)/swi.subband_sample_rate); pi.p.snr = snr; pi.p.thresh = thresh; pi.p.len_prof = len_prof; pi.freq_bin=freq_bin; pi.time_bin=time_bin; pi.p.freq=cnvt_bin_hz(freq_bin, pi.p.fft_len); double t_offset=(static_cast(time_bin)+0.5) *static_cast(pi.p.fft_len)/ swi.subband_sample_rate; pi.p.detection_freq=calc_detection_freq(pi.p.freq,pi.p.chirp_rate,t_offset); pi.p.time=swi.time_recorded+t_offset/86400.0; time_to_ra_dec(pi.p.time, &pi.p.ra, &pi.p.decl); for (i=0;i(len_prof)/swi.analysis_cfg.pulse_pot_length; index=0; for (i=0;i((folded_pot[static_cast(floor(index))+j]-MinPower)*norm); if (pot= 256) pi.pot_min[i] = 255; // kludge until we fix the assert failures BOINCASSERT(pi.pot_min[i] < 256); if (pot>pi.pot_max[i]) pi.pot_max[i]=pot; if (pi.pot_max[i] >= 256) pi.pot_max[i] = 255; // kludge until we fix the assert failures BOINCASSERT(pi.pot_max[i] < 256); } index+=step; } } #endif // Populate the result PoT if the folded PoT will fit. if (pi.p.len_prof < swi.analysis_cfg.pulse_pot_length) { pi.p.pot.resize(len_prof); for (i=0;ipi.copy(&pi); #endif // best thus far ? if (pi.score>best_pulse->score) { *best_pulse=pi; if(verbose>=2){ fprintf(stderr,"Best pulse updated: score=%.4g,power=%.5g,fftlen=%d,freq_bin=%d,time_bin=%d,icfft=%d\n", pi.score,pi.p.peak_power,pi.p.fft_len,pi.freq_bin,pi.time_bin,analysis_state.icfft); } } if (write_pulse) { //for (i=0;i=1){ int fft=(pi.p.fft_len>1024)?(pi.p.fft_len/1024):(pi.p.fft_len); char symbol=(pi.p.fft_len>1024)?('k'):(' '); fprintf(stderr,"Pulse: peak=%.7g, time=%.4g, period=%.4g, d_freq=%.12g, score=%.4g, chirp=%.5g, fft_len=%d%c\n", pi.p.peak_power,(pi.p.time-swi.time_recorded)*86400,pi.p.period,pi.p.detection_freq,pi.score,pi.p.chirp_rate,fft,symbol); } retval = outfile.printf("%s", pi.p.print_xml(0,0,1).c_str()); if (retval >= 0) { outfile.printf("\n"); } if (retval < 0) { SETIERROR(WRITE_FAILED,"in ReportPulseEvent"); } else { signal_count++; pulse_count++; } if (signal_count >= swi.analysis_cfg.max_signals) { SETIERROR(RESULT_OVERFLOW,"in ReportPulseEvent"); } } // debug possible heap corruption -- jeffc #ifdef _WIN32 BOINCASSERT(_CrtCheckMemory()); #endif #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return(retval); } boinc-app-seti_8.00~svn3701.orig/client/seti.cpp0000644000175000017500000012057513040227144021447 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // seti.C // $Id: seti.cpp,v 1.60.2.19 2007/08/10 00:38:49 korpela Exp $ // // SETI-specific logic for reading/writing checkpoint files // and parsing WU files. // // Files: // state.txt // the last chirp rate / FFT len finished, if any // outfile.txt // The append-only result file // // What finally gets sent back as the result file is: // - the generic result header, with the final CPU time filled in // - the SETI-specific part of the WU header // - the contents of outfile.txt #include "sah_config.h" #include #ifdef HAVE_UNISTD_H #include #endif #include #include #include #ifdef BOINC_APP_GRAPHICS #include "sah_gfx_main.h" #endif #ifdef HAVE_IEEEFP_H #include #endif #include "boinc_api.h" #include "str_util.h" #include "str_replace.h" #include "diagnostics.h" #include "parse.h" #include "filesys.h" #include "s_util.h" #include "seti_header.h" #include "analyze.h" #include "analyzeFuncs.h" #include "vector/analyzeFuncs_vector.h" #include "pulsefind.h" #include "analyzeReport.h" #include "analyzePoT.h" #include "malloc_a.h" #include "chirpfft.h" #include "worker.h" #include "seti.h" #define DATA_ASCII 1 #define DATA_ENCODED 2 #define DATA_SUN_BINARY 3 APP_INIT_DATA app_init_data; ANALYSIS_STATE analysis_state; static int wrote_header; double LOAD_STORE_ADJUSTMENT=2.85; double SETUP_FLOPS=1.42e+10/2.85; SPIKE_INFO::SPIKE_INFO() : track_mem("SPIKE_INFO"),s(), score(0), bin(0), fft_ind(0) {} SPIKE_INFO::~SPIKE_INFO() {} SPIKE_INFO::SPIKE_INFO(const SPIKE_INFO &si) : track_mem("SPIKE_INFO"), s(si.s), score(si.score), bin(si.bin), fft_ind(si.fft_ind) {} SPIKE_INFO &SPIKE_INFO::operator =(const SPIKE_INFO &si) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("SPIKE_INFO::operator ="); #endif if (&si != this) { s=si.s; score=si.score; bin=si.bin; fft_ind=si.fft_ind; } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return *this; } AUTOCORR_INFO::AUTOCORR_INFO() : track_mem("AUTOCORR_INFO"),a(), score(0), bin(0), fft_ind(0) {} AUTOCORR_INFO::~AUTOCORR_INFO() {} AUTOCORR_INFO::AUTOCORR_INFO(const AUTOCORR_INFO &ai) : track_mem("AUTOCORR_INFO"), a(ai.a), score(ai.score), bin(ai.bin), fft_ind(ai.fft_ind) {} AUTOCORR_INFO &AUTOCORR_INFO::operator =(const AUTOCORR_INFO &ai) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("AUTOCORR_INFO::operator ="); #endif if (&ai != this) { a=ai.a; score=ai.score; bin=ai.bin; fft_ind=ai.fft_ind; } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return *this; } GAUSS_INFO::GAUSS_INFO() : track_mem("GAUSS_INFO"), g(), score(0), display_power_thresh(0), bin(0), fft_ind(0) { } GAUSS_INFO::~GAUSS_INFO() {} GAUSS_INFO::GAUSS_INFO(const GAUSS_INFO &gi) : track_mem("GAUSS_INFO"), g(gi.g), score(gi.score), bin(gi.bin), fft_ind(gi.fft_ind) { } GAUSS_INFO &GAUSS_INFO::operator =(const GAUSS_INFO &gi) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("GAUSS_INFO::operator ="); #endif if (&gi != this) { g=gi.g; score=gi.score; bin=gi.bin; fft_ind=gi.fft_ind; } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return *this; } PULSE_INFO::PULSE_INFO() : track_mem("PULSE_INFO"), p(), score(0), freq_bin(0), time_bin(0) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("PULSE_INFO::PULSE_INFO()"); #endif // debug possible heap corruption -- jeffc #ifdef _WIN32 BOINCASSERT(_CrtCheckMemory()); #endif pot_min = (unsigned int *)calloc_a(swi.analysis_cfg.pulse_pot_length, sizeof(unsigned int), MEM_ALIGN); if (pot_min == NULL) SETIERROR(MALLOC_FAILED, "new PULSE_INFO pot_min == NULL"); pot_max = (unsigned int *)calloc_a(swi.analysis_cfg.pulse_pot_length, sizeof(unsigned int), MEM_ALIGN); if (pot_max == NULL) SETIERROR(MALLOC_FAILED, "new PULSE_INFO pot_max == NULL"); // debug possible heap corruption -- jeffc #ifdef _WIN32 BOINCASSERT(_CrtCheckMemory()); #endif #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } PULSE_INFO::~PULSE_INFO() { // debug possible heap corruption -- jeffc #ifdef _WIN32 BOINCASSERT(_CrtCheckMemory()); #endif #ifdef USE_MANUAL_CALLSTACK call_stack.enter("PULSE_INFO::~PULSE_INFO()"); #endif free_a(pot_min); free_a(pot_max); // debug possible heap corruption -- jeffc #ifdef _WIN32 BOINCASSERT(_CrtCheckMemory()); #endif #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } PULSE_INFO::PULSE_INFO(const PULSE_INFO &pi) : track_mem("PULSE_INFO"), p(pi.p), score(pi.score), freq_bin(pi.freq_bin), time_bin(pi.time_bin) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("PULSE_INFO::PULSE_INFO(const PULSE_INFO &pi)"); #endif // debug possible heap corruption -- jeffc #ifdef _WIN32 BOINCASSERT(_CrtCheckMemory()); #endif pot_min = (unsigned int *)calloc_a(swi.analysis_cfg.pulse_pot_length, sizeof(unsigned int), MEM_ALIGN); if (pot_min == NULL) SETIERROR(MALLOC_FAILED, "copied PULSE_INFO pot_min == NULL"); pot_max = (unsigned int *)calloc_a(swi.analysis_cfg.pulse_pot_length, sizeof(unsigned int), MEM_ALIGN); if (pot_max == NULL) SETIERROR(MALLOC_FAILED, "copied PULSE_INFO pot_max == NULL"); memcpy(pot_min,pi.pot_min,(swi.analysis_cfg.pulse_pot_length * sizeof(unsigned int))); memcpy(pot_max,pi.pot_max,(swi.analysis_cfg.pulse_pot_length * sizeof(unsigned int))); // debug possible heap corruption -- jeffc #ifdef _WIN32 BOINCASSERT(_CrtCheckMemory()); #endif #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } PULSE_INFO &PULSE_INFO::operator =(const PULSE_INFO &pi) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("PULSE_INFO::operator ="); #endif // debug possible heap corruption -- jeffc #ifdef _WIN32 BOINCASSERT(_CrtCheckMemory()); #endif if (&pi != this) { p=pi.p; score=pi.score; freq_bin=pi.freq_bin; time_bin=pi.time_bin; memcpy(pot_min,pi.pot_min,(swi.analysis_cfg.pulse_pot_length * sizeof(unsigned int))); memcpy(pot_max,pi.pot_max,(swi.analysis_cfg.pulse_pot_length * sizeof(unsigned int))); } // debug possible heap corruption -- jeffc #ifdef _WIN32 BOINCASSERT(_CrtCheckMemory()); #endif #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return *this; } TRIPLET_INFO::TRIPLET_INFO() : track_mem("TRIPLET_INFO"), t(), score(0), bperiod(0), freq_bin(0), tpotind0_0(0), tpotind0_1(0), tpotind1_0(0), tpotind1_1(0), tpotind2_0(0), tpotind2_1(0), time_bin(0), scale(0) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("TRIPLET_INFO::TRIPLET_INFO()"); #endif // debug possible heap corruption -- jeffc #ifdef _WIN32 BOINCASSERT(_CrtCheckMemory()); #endif pot_min = (unsigned int *)calloc_a(swi.analysis_cfg.triplet_pot_length, sizeof(unsigned int), MEM_ALIGN); if (pot_min == NULL) SETIERROR(MALLOC_FAILED, "new TRIPLET_INFO pot_min == NULL"); pot_max = (unsigned int *)calloc_a(swi.analysis_cfg.triplet_pot_length, sizeof(unsigned int), MEM_ALIGN); if (pot_max == NULL) SETIERROR(MALLOC_FAILED, "new TRIPLET_INFO pot_max == NULL"); // debug possible heap corruption -- jeffc #ifdef _WIN32 BOINCASSERT(_CrtCheckMemory()); #endif #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } TRIPLET_INFO::TRIPLET_INFO(const TRIPLET_INFO &ti) : track_mem("TRIPLET_INFO"), t(ti.t), score(ti.score), bperiod(ti.bperiod), freq_bin(ti.freq_bin), tpotind0_0(ti.tpotind0_0), tpotind0_1(ti.tpotind0_1), tpotind1_0(ti.tpotind1_0), tpotind1_1(ti.tpotind1_1), tpotind2_0(ti.tpotind2_0), tpotind2_1(ti.tpotind2_1), time_bin(ti.time_bin), scale(ti.scale) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("TRIPLET_INFO::TRIPLET_INFO(const TRIPLET_INFO &ti)"); #endif // debug possible heap corruption -- jeffc #ifdef _WIN32 BOINCASSERT(_CrtCheckMemory()); #endif pot_min = (unsigned int *)calloc_a(swi.analysis_cfg.triplet_pot_length, sizeof(unsigned int), MEM_ALIGN); if (pot_min == NULL) SETIERROR(MALLOC_FAILED, "copied TRIPLET_INFO pot_min == NULL"); pot_max = (unsigned int *)calloc_a(swi.analysis_cfg.triplet_pot_length, sizeof(unsigned int), MEM_ALIGN); if (pot_max == NULL) SETIERROR(MALLOC_FAILED, "copied TRIPLET_INFO pot_max == NULL"); memcpy(pot_min,ti.pot_min,(swi.analysis_cfg.triplet_pot_length * sizeof(unsigned int))); memcpy(pot_max,ti.pot_max,(swi.analysis_cfg.triplet_pot_length * sizeof(unsigned int))); // debug possible heap corruption -- jeffc #ifdef _WIN32 BOINCASSERT(_CrtCheckMemory()); #endif #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } TRIPLET_INFO &TRIPLET_INFO::operator =(const TRIPLET_INFO &ti) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("TRIPLET_INFO::operator ="); #endif // debug possible heap corruption -- jeffc #ifdef _WIN32 BOINCASSERT(_CrtCheckMemory()); #endif if (&ti != this) { t=ti.t; score=ti.score; bperiod=ti.bperiod; freq_bin=ti.freq_bin; tpotind0_0=ti.tpotind0_0; tpotind0_1=ti.tpotind0_1; tpotind1_0=ti.tpotind1_0; tpotind1_1=ti.tpotind1_1; tpotind2_0=ti.tpotind2_0; tpotind2_1=ti.tpotind2_1; time_bin=ti.time_bin; memcpy(pot_min,ti.pot_min,(swi.analysis_cfg.triplet_pot_length * sizeof(unsigned int))); memcpy(pot_max,ti.pot_max,(swi.analysis_cfg.triplet_pot_length * sizeof(unsigned int))); } // debug possible heap corruption -- jeffc #ifdef _WIN32 BOINCASSERT(_CrtCheckMemory()); #endif #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return *this; } TRIPLET_INFO::~TRIPLET_INFO() { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("TRIPLET_INFO::~TRIPLET_INFO()"); #endif // debug possible heap corruption -- jeffc #ifdef _WIN32 BOINCASSERT(_CrtCheckMemory()); #endif free_a(pot_min); free_a(pot_max); // debug possible heap corruption -- jeffc #ifdef _WIN32 BOINCASSERT(_CrtCheckMemory()); #endif #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } // Do SETI-specific initialization for a work unit. // - prepare outfile for appending // - reset scores int seti_init_state() { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("seti_init_state()"); #endif analysis_state.icfft= 0; analysis_state.PoT_freq_bin = -1; analysis_state.PoT_activity = POT_INACTIVE; progress = 0.0; reset_high_scores(); std::string path; boinc_resolve_filename_s(OUTFILE_FILENAME, path); if (outfile.open(path.c_str(), "ab")) SETIERROR(CANT_CREATE_FILE," in seti_init_state()"); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } // This gets called at the start of each chirp/fft pair. int result_group_start() { wrote_header = 0; return 0; } // This gets called prior to writing an entry in the output file. // Write the chirp/fft parameters if not done already. int result_group_write_header() { if (wrote_header) return 0; wrote_header = 1; int retval = outfile.printf( "\n", analysis_state.icfft, ChirpFftPairs[analysis_state.icfft].ChirpRate, ChirpFftPairs[analysis_state.icfft].FftLen ); if (retval < 0) SETIERROR(WRITE_FAILED,"in result_group_write_header()"); return 0; } // this gets called at the end of each chirp/fft pair // Rewrite the state file, // and write an end-of-group record to log file // if anything was written for this group. int result_group_end() { int retval=0; if (wrote_header) { retval = outfile.printf( "\n", analysis_state.icfft, ChirpFftPairs[analysis_state.icfft].ChirpRate, ChirpFftPairs[analysis_state.icfft].FftLen); if (retval < 0) SETIERROR(WRITE_FAILED,"in result_group_end"); } return 0; } int checkpoint(BOOLEAN force_checkpoint) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("checkpoint()"); #endif int retval=0, i, l=xml_indent_level; xml_indent_level=0; // Making state_file static to avoid overhead of reallocating of buffers on // every call. static MFILE state_file; char buf[2048]; std::string enc_field, str; // The user may have set preferences for a long time between // checkpoints to reduce disk access. if (!force_checkpoint) { if (!boinc_time_to_checkpoint()) { #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return CHECKPOINT_SKIPPED; } } fflush(stderr); // debug possible heap corruption -- jeffc #ifdef _WIN32 BOINCASSERT(_CrtCheckMemory()); #endif if (state_file.open(STATE_FILENAME, "wb")) SETIERROR(CANT_CREATE_FILE,"in checkpoint()"); retval = state_file.printf( "%d\n" "%e\n" "%d\n" "%.8f\n" "%d\n" "%d\n" "%d\n" "%f\n" "%d\n" "%d\n" "%d\n" "%d\n" "%d\n", analysis_state.icfft, ChirpFftPairs[analysis_state.icfft].ChirpRate, ChirpFftPairs[analysis_state.icfft].FftLen, std::min(progress,0.9999999), analysis_state.PoT_freq_bin, analysis_state.PoT_activity, signal_count, analysis_state.FLOP_counter, spike_count, autocorr_count, pulse_count, gaussian_count, triplet_count ); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); // checkpoint the best spike thus far (if any) if(best_spike->s.fft_len) { retval = state_file.printf("\n"); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); // the spike proper str = best_spike->s.print_xml(0,0,1); retval = (int)state_file.write(str.c_str(), str.size(), 1); // ancillary data retval = state_file.printf( "%f\n" "%d\n" "%d\n", best_spike->score, best_spike->bin, best_spike->fft_ind); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); retval = state_file.printf("\n"); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); } // checkpoint the best autocorr thus far (if any) if(best_autocorr->a.fft_len) { retval = state_file.printf("\n"); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); // the autocorr proper str = best_autocorr->a.print_xml(0,0,1); retval = (int)state_file.write(str.c_str(), str.size(), 1); // ancillary data retval = state_file.printf( "%f\n" "%d\n" "%d\n", best_autocorr->score, best_autocorr->bin, best_autocorr->fft_ind); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); retval = state_file.printf("\n"); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); } // checkpoint the best gaussian thus far (if any) if(best_gauss->g.fft_len || best_gauss->score) { retval = state_file.printf("\n"); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); // the gaussian proper str = best_gauss->g.print_xml(0,0,1); retval = (int)state_file.write(str.c_str(), str.size(), 1); // ancillary data retval = state_file.printf( "%f\n" "%f\n" "%d\n" "%d\n", best_gauss->score, best_gauss->display_power_thresh, best_gauss->bin, best_gauss->fft_ind); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); retval = state_file.printf("\n"); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); } // checkpoint the best pulse thus far (if any) // The check for len_prof is a kludge. if(best_pulse->p.fft_len) { retval = state_file.printf("\n"); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); // the pulse proper str = best_pulse->p.print_xml(0,0,1); retval = (int)state_file.write(str.c_str(), str.size(), 1); // ancillary data retval = state_file.printf( "%f\n" "%d\n" "%d\n", best_pulse->score, best_pulse->freq_bin, best_pulse->time_bin); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); retval = state_file.printf("\n"); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); } // checkpoint the best triplet thus far (if any) if(best_triplet->t.fft_len) { retval = state_file.printf("\n"); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); // the triplet proper str = best_triplet->t.print_xml(0,0,1); retval = (int)state_file.write(str.c_str(), str.size(), 1); // ancillary data retval = state_file.printf( "%f\n" "%f\n" "%d\n" "%d\n" "%d\n" "%d\n" "%d\n" "%d\n" "%d\n" "%f\n" "%f\n", best_triplet->score, best_triplet->bperiod, best_triplet->tpotind0_0, best_triplet->tpotind0_1, best_triplet->tpotind1_0, best_triplet->tpotind1_1, best_triplet->tpotind2_0, best_triplet->tpotind2_1, best_triplet->freq_bin, best_triplet->time_bin, best_triplet->scale); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); // convert min PoT to chars, encode, and print for (i=0; ipot_min[i]; } enc_field=xml_encode_string(buf, swi.analysis_cfg.triplet_pot_length, _x_csv); retval = state_file.printf( "", enc_field.size(), xml_encoding_names[_x_csv] ); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); state_file.write(enc_field.c_str(), enc_field.size(), 1); retval = state_file.printf("\n"); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); // convert max PoT to chars, encode, and print for (i=0; ipot_max[i]; } enc_field=xml_encode_string(buf, swi.analysis_cfg.triplet_pot_length, _x_csv); state_file.printf( "", enc_field.size(), xml_encoding_names[_x_csv] ); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); state_file.write(enc_field.c_str(), enc_field.size(), 1); retval = state_file.printf("\n"); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); retval = state_file.printf("\n"); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); } if (BaseLineSmooth != NULL) { for (i=0;i%s\n", BaseLineSmoothFuncs[i].nom); break; } } } if (GetPowerSpectrum != NULL) { for (i=0;i%s\n", GetPowerSpectrumFuncs[i].nom); break; } } } if (ChirpData != NULL) { for (i=0;i%s\n", ChirpDataFuncs[i].nom); break; } } } if (Transpose != NULL) { for (i=0;i%s\n", TransposeFuncs[i].nom); break; } } } if (strlen(Foldmain.name) != 0) { state_file.printf("%s\n", Foldmain.name); } // The result (outfile) and state mfiles are now synchronized. // Flush them both. retval = outfile.flush(); if (retval) SETIERROR(WRITE_FAILED,"in checkpoint()"); retval = state_file.flush(); if (retval) SETIERROR(WRITE_FAILED,"in checkpoint()"); retval = state_file.close(); if (retval) SETIERROR(WRITE_FAILED,"in checkpoint()"); boinc_checkpoint_completed(); xml_indent_level=l; // debug possible heap corruption -- jeffc #ifdef _WIN32 BOINCASSERT(_CrtCheckMemory()); #endif #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } // Read the state file and set analysis_state accordingly. // Note: The state of analysis is saved in two places: // 1) at the end of processing the data for any given // chirp/fft pair. In this case, the icfft index // needs to be set for the *next* chirp/fft pair. // If analysis was in this state when saved, // PoT_freq_bin will have been set to -1. // 2) at the end of PoT processing for any given // frequency bin (for any given chirp/fft pair). // This is indicated by PoT_freq_bin containing // something other than -1. It will contain the // frequency bin just completed. In this case, we // are *not* finished processing for the current // chirp/fft pair and we do not increment icfft to // the next pair. We do however increment PoT_freq_bin // to the next frequency bin. // int parse_state_file(ANALYSIS_STATE& as) { static char buf[8192]; std::string fname; int ncfft, fl, PoT_freq_bin, PoT_activity; double cr=0,flops=0; FILE* state_file; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("parse_state_file()"); #endif // debug possible heap corruption -- jeffc #ifdef _WIN32 BOINCASSERT(_CrtCheckMemory()); #endif ncfft = -1; progress = 0.0; PoT_freq_bin = -1; PoT_activity = POT_INACTIVE; state_file = boinc_fopen(STATE_FILENAME, "rb"); if (!state_file) SETIERROR(FOPEN_FAILED,"in parse_state_file()"); // main parsing loop while (fgets(buf, sizeof(buf), state_file)) { if (parse_int(buf, "", ncfft)) continue; else if (parse_double(buf, "", cr)) continue; else if (parse_int(buf, "", fl)) continue; else if (parse_double(buf, "", progress)) continue; else if (parse_int(buf, "", PoT_freq_bin)) continue; else if (parse_int(buf, "", PoT_activity)) continue; else if (parse_int(buf, "", signal_count)) continue; else if (parse_double(buf, "", flops)) continue; else if (parse_int(buf, "", spike_count)) continue; else if (parse_int(buf, "", autocorr_count)) continue; else if (parse_int(buf, "", pulse_count)) continue; else if (parse_int(buf, "", gaussian_count)) continue; else if (parse_int(buf, "", triplet_count)) continue; // best spike else if (xml_match_tag(buf, "")) { while (fgets(buf, sizeof(buf), state_file)) { if (xml_match_tag(buf, "")) break; // spike proper else if (xml_match_tag(buf, "")) { char *p = buf + strlen(buf); while(fgets(p, sizeof(buf)-(int)strlen(buf), state_file)) { if (xml_match_tag(buf, "")) break; p += strlen(p); } best_spike->s.parse_xml(buf); } // ancillary data else if (parse_double(buf, "", best_spike->score)) continue; else if (parse_int(buf, "", best_spike->bin)) continue; else if (parse_int(buf, "", best_spike->fft_ind)) continue; } // end while in best_spike } // end if in best_spike // best autocorr else if (xml_match_tag(buf, "")) { while (fgets(buf, sizeof(buf), state_file)) { if (xml_match_tag(buf, "")) break; // autocorr proper else if (xml_match_tag(buf, "")) { char *p = buf + strlen(buf); while(fgets(p, sizeof(buf)-(int)strlen(buf), state_file)) { if (xml_match_tag(buf, "")) break; p += strlen(p); } best_autocorr->a.parse_xml(buf); } // ancillary data else if (parse_double(buf, "", best_autocorr->score)) continue; else if (parse_int(buf, "", best_autocorr->bin)) continue; else if (parse_int(buf, "", best_autocorr->fft_ind)) continue; } // end while in best_autocorr } // end if in best_autocorr // best gaussian.. else if (xml_match_tag(buf, "")) { while (fgets(buf, sizeof(buf), state_file)) { if (xml_match_tag(buf, "")) break; // gaussian proper else if (xml_match_tag(buf, "")) { char *p = buf + strlen(buf); while(fgets(p, sizeof(buf)-(int)strlen(buf), state_file)) { if (xml_match_tag(buf, "")) break; p += strlen(p); } best_gauss->g.parse_xml(buf); } // ancillary data else if (parse_double(buf, "", best_gauss->score)) continue; else if (parse_double(buf, "", best_gauss->display_power_thresh)) continue; else if (parse_int(buf, "", best_gauss->bin)) continue ; else if (parse_int(buf, "", best_gauss->fft_ind)) continue; } // end while in best_gaissian } // end if in best_gaussian // best pulse else if (xml_match_tag(buf, "")) { while (fgets(buf, sizeof(buf), state_file)) { if (xml_match_tag(buf, "")) break; // pulse proper else if (xml_match_tag(buf, "")) { char *p = buf + strlen(buf); while(fgets(p, sizeof(buf)-(int)strlen(buf), state_file)) { if (xml_match_tag(buf, "")) break; p += strlen(p); } best_pulse->p.parse_xml(buf); } // ancillary data else if (parse_double(buf, "", best_pulse->score)) continue; else if (parse_int(buf, "", best_pulse->freq_bin)) continue; else if (parse_int(buf, "", best_pulse->time_bin)) continue; } // end while in best_pulse } // end if in best_pulse // best triplet else if (xml_match_tag(buf, "")) { while (fgets(buf, sizeof(buf), state_file)) { if (xml_match_tag(buf, "")) break; // triplet proper else if (xml_match_tag(buf, "")) { char *p = buf + strlen(buf); while(fgets(p, sizeof(buf)-(int)strlen(buf), state_file)) { if (xml_match_tag(buf, "")) break; p += strlen(p); } best_triplet->t.parse_xml(buf); } // ancillary data else if (parse_double(buf, "", best_triplet->score)) continue; else if (parse_double(buf, "", best_triplet->bperiod)) continue; else if (parse_int(buf, "", best_triplet->tpotind0_0)) continue; else if (parse_int(buf, "", best_triplet->tpotind0_1)) continue; else if (parse_int(buf, "", best_triplet->tpotind1_0)) continue; else if (parse_int(buf, "", best_triplet->tpotind1_1)) continue; else if (parse_int(buf, "", best_triplet->tpotind2_0)) continue; else if (parse_int(buf, "", best_triplet->tpotind2_1)) continue; else if (parse_int(buf, "", best_triplet->freq_bin)) continue; else if (parse_double(buf, "", best_triplet->time_bin)) continue; else if (parse_double(buf, "", best_triplet->scale)) continue; else if (xml_match_tag(buf, " pot_min( xml_decode_field(buf,"bt_pot_min") ); int i; for (i=0; ipot_min[i] = pot_min[i]; } } // end Min PoT else if (xml_match_tag(buf, " pot_max( xml_decode_field(buf,"bt_pot_max") ); int i; for (i=0; ipot_max[i] = pot_max[i]; } } // end Max PoT } // end while in best_triplet } // end if in best_triplet // Restore best functions that were determined earlier. else if (parse_str(buf,"",fname)) { int i; for (i=0;i",fname)) { int i; for (i=0;i",fname)) { int i; for (i=0;i",fname)) { int i; for (i=0;i",fname)) { int i; for (i=0;iname)==0) { CopyFoldSet(&Foldmain,FoldSubs[i].fsp); found_folding=true; break; } } } } // end main parsing loop fclose(state_file); analysis_state.FLOP_counter=flops; reload_graphics_state(); // so we can draw best_of signals // Adjust for restart - go 1 step beyond the checkpoint. as.PoT_activity = PoT_activity; if(PoT_freq_bin == -1) { as.icfft = ncfft+1; as.PoT_freq_bin = PoT_freq_bin; } else { as.icfft = ncfft; as.PoT_freq_bin = PoT_freq_bin+1; } // debug possible heap corruption -- jeffc #ifdef _WIN32 BOINCASSERT(_CrtCheckMemory()); #endif #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } // On entry, analysis_state.data points to malloced data // and outfile is not open. // On exit, these are freed and closed int seti_do_work() { int retval=0; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("seti_do_work()"); #endif retval = seti_analyze(analysis_state); free_a(analysis_state.data); analysis_state.data = 0; if( swi.data_type == DATA_ENCODED ) { free_a(analysis_state.savedWUData); analysis_state.savedWUData = 0; } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return retval; } // on success, swi.data points to malloced data. int seti_parse_data(FILE* f, ANALYSIS_STATE& state) { unsigned long nbytes, nsamples,samples_per_byte; sah_complex *data; unsigned long i; char *p, buf[256]; sah_complex *bin_data=0; int retval=0; FORCE_FRAME_POINTER; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("seti_parse_data()"); #endif nsamples = swi.nsamples; samples_per_byte=(8/swi.bits_per_sample); data = (sah_complex *)malloc_a(nsamples*sizeof(sah_complex), MEM_ALIGN); bin_data = (sah_complex *)malloc_a(nsamples*sizeof(sah_complex), MEM_ALIGN); if (!data) SETIERROR(MALLOC_FAILED, "!data"); if (!bin_data) SETIERROR(MALLOC_FAILED, "!bin_data"); switch(swi.data_type) { case DATA_ASCII: for (i=0; i datav( xml_decode_field(tmpbuf,"data") ); memcpy(bin_data,&(datav[0]),datav.size()); if (datav.size() < nbytes) throw BAD_DECODE; } catch (int i) { retval=i; if (data) free_a(data); if (bin_data) free_a(bin_data); SETIERROR(i,"in seti_parse_data()"); } bits_to_floats((unsigned char *)bin_data, data, nsamples,swi.bits_per_sample); memcpy(bin_data,data,nsamples*sizeof(sah_complex)); state.savedWUData = bin_data; break; } state.npoints = nsamples; state.data = data; #ifdef BOINC_APP_GRAPHICS if (sah_graphics) { strlcpy(sah_graphics->wu.receiver_name,swi.receiver_cfg.name,255); sah_graphics->wu.s4_id = swi.receiver_cfg.s4_id; sah_graphics->wu.time_recorded = swi.time_recorded; sah_graphics->wu.subband_base = swi.subband_base; sah_graphics->wu.start_ra = swi.start_ra; sah_graphics->wu.start_dec = swi.start_dec; sah_graphics->wu.subband_sample_rate = swi.subband_sample_rate; sah_graphics->ready = true; } #endif #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } int seti_parse_wu(FILE* f, ANALYSIS_STATE& state) { int retval=0; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("seti_parse_wu()"); #endif retval = seti_parse_wu_header(f); if (retval) SETIERROR(retval,"from seti_parse_wu_header()"); retval=seti_parse_data(f, state); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return retval; } void final_report() { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("final_report()"); #endif if(verbose>0){ { int fft=(best_spike->s.fft_len>1024)?(best_spike->s.fft_len/1024):(best_spike->s.fft_len); char symbol=(best_spike->s.fft_len>1024)?('k'):(' '); fprintf(stderr,"\nBest spike: peak=%.7g, time=%.4g, d_freq=%.12g, chirp=%.5g, fft_len=%d%c\n", best_spike->s.peak_power,(best_spike->s.time-swi.time_recorded)*86400,best_spike->s.detection_freq,best_spike->s.chirp_rate,fft,symbol); } if(swi.analysis_cfg.autocorr_fftlen){ int fft=(best_autocorr->a.fft_len>1024)?(best_autocorr->a.fft_len/1024):(best_autocorr->a.fft_len); char symbol=(best_autocorr->a.fft_len>1024)?('k'):(' '); fprintf(stderr,"Best autocorr: peak=%.7g, time=%.4g, delay=%.5g, d_freq=%.12g, chirp=%.5g, fft_len=%d%c\n", best_autocorr->a.peak_power,(best_autocorr->a.time-swi.time_recorded)*86400,best_autocorr->a.delay,best_autocorr->a.detection_freq, best_autocorr->a.chirp_rate,fft,symbol); } { int fft=(best_gauss->g.fft_len>1024)?(best_gauss->g.fft_len/1024):(best_gauss->g.fft_len); char symbol=(best_gauss->g.fft_len>1024)?('k'):(' '); fprintf(stderr,"Best gaussian: peak=%.7g, mean=%.7g, ChiSq=%.7g, time=%.4g, d_freq=%.12g,\n\tscore=%.7g, null_hyp=%.7g, chirp=%.5g, fft_len=%d%c\n", best_gauss->g.peak_power,best_gauss->g.mean_power,best_gauss->g.chisqr,(best_gauss->g.time-swi.time_recorded)*86400,best_gauss->g.detection_freq, best_gauss->score,best_gauss->g.null_chisqr,best_gauss->g.chirp_rate,fft,symbol); } { int fft=(best_pulse->p.fft_len>1024)?(best_pulse->p.fft_len/1024):(best_pulse->p.fft_len); char symbol=(best_pulse->p.fft_len>1024)?('k'):(' '); fprintf(stderr,"Best pulse: peak=%.7g, time=%.4g, period=%.4g, d_freq=%.12g, score=%.4g, chirp=%.5g, fft_len=%d%c\n", best_pulse->p.peak_power,(best_pulse->p.time-swi.time_recorded)*86400,best_pulse->p.period,best_pulse->p.detection_freq, best_pulse->score,best_pulse->p.chirp_rate,fft,symbol); } { int fft=(best_triplet->t.fft_len>1024)?(best_triplet->t.fft_len/1024):(best_triplet->t.fft_len); char symbol=(best_triplet->t.fft_len>1024)?('k'):(' '); fprintf(stderr,"Best triplet: peak=%.7g, time=%.4g, period=%.4g, d_freq=%.12g, chirp=%.5g, fft_len=%d%c\n", best_triplet->t.peak_power,(best_triplet->t.time-swi.time_recorded)*86400,best_triplet->t.period,best_triplet->t.detection_freq, best_triplet->t.chirp_rate,fft,symbol); } } fprintf(stderr,"\nFlopcounter: %f\n\n", analysis_state.FLOP_counter); fprintf(stderr,"Spike count: %d\n", spike_count); fprintf(stderr,"Autocorr count: %d\n", autocorr_count); fprintf(stderr,"Pulse count: %d\n", pulse_count); fprintf(stderr,"Triplet count: %d\n", triplet_count); fprintf(stderr,"Gaussian count: %d\n", gaussian_count); fflush(stderr); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } unsigned int pow2(unsigned int num){ #ifdef USE_MANUAL_CALLSTACK call_stack.enter("pow2()"); #endif unsigned int n = num > 0 ? num - 1 : 0; n |= n >> 1; n |= n >> 2; n |= n >> 4; n |= n >> 8; n |= n >> 16; #if SIZEOF_INT > 4 n |= n >> 32; #endif n++; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return n >> 1; } boinc-app-seti_8.00~svn3701.orig/client/main.cpp0000644000175000017500000002127512643777667021460 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // unix_main.C: The SETI@home client program. // $Id: main.cpp,v 1.43.2.19 2007/07/16 15:36:50 korpela Exp $ // Main program for command-line application. // // Usage: client [options] // -version show version info // -verbose print running status // -v N level N of verbosity (N==2 to print best signals formation, N==0 to disable signals output) // -standalone #include "sah_config.h" #ifdef _WIN32 #include "boinc_win.h" #endif #ifndef _WIN32 #include #include #ifdef HAVE_UNISTD_H #include #endif #include #include #include #endif #include "diagnostics.h" #include "util.h" #include "s_util.h" #include "boinc_api.h" #ifdef BOINC_APP_GRAPHICS #include "sah_gfx_main.h" #include "graphics2.h" #endif #ifdef BOINC_APP_GRAPHICS #endif #include "util.h" #include "s_util.h" #include "str_util.h" #include "str_replace.h" #include "analyze.h" #include "analyzeFuncs.h" #include "analyzePoT.h" #include "worker.h" #include "sah_version.h" #include "chirpfft.h" #include "gaussfit.h" #ifdef __APPLE_CC__ #include "app_icon.h" #include #endif #ifdef ANDROID #ifdef HAVE_LIBCORKSCREW #include void (* ignore_this)(unsigned, const backtrace_frame_t *, const backtrace_symbol_t *, char *, size_t)=&format_backtrace_line; #endif #endif static int g_argc; static char **g_argv; void usage() { printf( "options:\n" #ifdef BOINC_APP_GRAPHICS " -nographics run without graphics\n" " -notranspose do not transpose data for pulse and gaussian searches\n" " -default_functions use the safe unoptimized default functions\n" " -standalone (implies -nographics)\n" #else " -standalone\n" #endif " -version show version info\n" " -verbose print running status\n" " -v N level N of verbosity (N==2 to print best signals formation, N==0 to disable signals output)\n" ); } void print_error(int e) { char* p; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("print_error()"); #endif /* USE_MANUAL_CALLSTACK */ p = error_string(e); fprintf(stderr,"%s\n",p); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif /* USE_MANUAL_CALLSTACK */ } void print_version() { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("print_version()"); #endif /* USE_MANUAL_CALLSTACK */ printf( "SETI@home client.\n" "Version: %d.%02d\n", gmajor_version, gminor_version ); printf( "\nSETI@home is sponsored by individual donors around the world.\n" "If you'd like to contribute to the project,\n" "please visit the SETI@home web site at\n" "http://setiathome.ssl.berkeley.edu.\n" "The project is also sponsored by the Planetary Society,\n" "the University of California, Sun Microsystems, Paramount Pictures,\n" "Fujifilm Computer Products, Informix, Engineering Design Team Inc,\n" "The Santa Cruz Operation (SCO), Intel, Quantum Corporation,\n" "and the SETI Institute.\n\n" "SETI@home was developed by David Gedye (Founder),\n" "David Anderson (Director), Dan Werthimer (Chief Scientist),\n" "Hiram Clawson, Jeff Cobb, Charlie Fenton,\n" "Eric Heien, Eric Korpela, Matt Lebofsky,\n" "Tetsuji 'Maverick' Rai and Rom Walton\n" ); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif /* USE_MANUAL_CALLSTACK */ } extern double sigma_thresh; extern double f_PowerThresh; extern double f_PeakPowerThresh; extern double chi_sq_thresh; bool notranspose_flag=false; bool default_functions_flag=false; int run_stage; typedef seti_error boinc_error; //void atexit_handler(void) { // if (run_stage == GRXINIT) { // fprintf(stderr,"Staring in non-graphical mode"); // fflush(stderr); // fclose(stderr); // g_argv[g_argc]="-nographics"; // execv(g_argv[0],g_argv); // SETIERROR(UNHANDLED_SIGNAL, "from atexit_handler()"); // } //} extern APP_INIT_DATA app_init_data; int main(int argc, char** argv) { int retval = 0, i; FORCE_FRAME_POINTER; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("main()"); #endif /* USE_MANUAL_CALLSTACK */ run_stage=PREGRX; g_argc=argc; #ifdef ANDROID argv0=argv[0]; #endif if (!(g_argv=(char **)calloc(argc+2,sizeof(char *)))) { #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif /* USE_MANUAL_CALLSTACK */ exit(MALLOC_FAILED); } setbuf(stdout, 0); bool standalone = false; g_argv[0]=argv[0]; for (i=1; i1) call_stack.set_verbose(true); #endif /* USE_MANUAL_CALLSTACK */ try { // Initialize Diagnostics // unsigned long dwDiagnosticsFlags = 0; dwDiagnosticsFlags = BOINC_DIAG_DUMPCALLSTACKENABLED | BOINC_DIAG_HEAPCHECKENABLED | BOINC_DIAG_TRACETOSTDERR | BOINC_DIAG_REDIRECTSTDERR; retval = boinc_init_diagnostics(dwDiagnosticsFlags); if (retval) { SETIERROR(retval, "from boinc_init_diagnostics()"); } #if defined(__APPLE__) && !defined(__ppc__) setMacIcon(argv[0], MacAppIconData, sizeof(MacAppIconData)); #ifdef __i386__ rlimit rlp; getrlimit(RLIMIT_STACK, &rlp); rlp.rlim_cur = rlp.rlim_max; setrlimit(RLIMIT_STACK, &rlp); #endif #endif // Initialize BOINC // boinc_parse_init_data_file(); boinc_get_init_data(app_init_data); #ifdef BOINC_APP_GRAPHICS sah_graphics_init(app_init_data); #endif retval = boinc_init(); if (retval) { SETIERROR(retval, "from boinc_init()"); } worker(); } catch (seti_error e) { e.print(); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif /* USE_MANUAL_CALLSTACK */ exit(static_cast(e)); } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif /* USE_MANUAL_CALLSTACK */ return 0; } #ifdef _WIN32 // // Function: WinMain // // Purpose: Application entry point, used instead of main so that on Win9x platforms // windows do not appear for each instance executing on the system. // // Date: 01/29/04 // int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR Args, int WinMode) { LPSTR command_line; char* argv[100]; int argc, retval; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("WinMain()"); #endif /* USE_MANUAL_CALLSTACK */ command_line = GetCommandLine(); argc = parse_command_line(command_line,argv); retval = main(argc, argv); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif /* USE_MANUAL_CALLSTACK */ return retval; } #endif boinc-app-seti_8.00~svn3701.orig/client/working_collect2_line_for_android_armv6-vfp0000644000175000017500000000412612313644616030454 0ustar locutuslocutus /usr/arm-linux-androideabi/bin/../libexec/gcc/arm-linux-androideabi/4.6/collect2 --sysroot=/usr/arm-linux-androideabi/sysroot --eh-frame-hdr -dynamic-linker /system/bin/linker -X -m armelf_linux_eabi -z noexecstack -z relro -z now -o seti_boinc /usr/arm-linux-androideabi/sysroot/usr/lib/crtbegin_dynamic.o -L/usr/arm-linux-androideabi/arm-linux-androideabi/lib/${targetarch} -L/usr/arm-linux-androideabi/sysroot/usr/lib -L/usr/arm-linux-androideabi/arm-linux-androideabi/lib -L/usr/arm-linux-androideabi/arm-linux-androideabi/lib -L/usr/arm-linux-androideabi/arm-linux-androideabi/lib/${targetarch} -L/usr/arm-linux-androideabi/sysroot/usr/lib -L/usr/arm-linux-androideabi/arm-linux-androideabi/lib -L/usr/arm-linux-androideabi/bin/../lib/gcc/arm-linux-androideabi/4.6 -L/usr/arm-linux-androideabi/bin/../lib/gcc -L/usr/arm-linux-androideabi/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/lib -L/usr/arm-linux-androideabi/sysroot/usr/lib seti_boinc-main.o seti_boinc-analyzeFuncs_vector.o seti_boinc-analyzeFuncs_fpu.o seti_boinc-analyzeFuncs_sse.o seti_boinc-analyzeFuncs_sse2.o seti_boinc-analyzeFuncs_sse3.o seti_boinc-analyzeFuncs_avx.o seti_boinc-analyzeFuncs_x86_64.o seti_boinc-analyzeFuncs_altivec.o analyzeFuncs_vfp.o seti_boinc-analyzeFuncs_vfp_aux.o seti_boinc-x86_float4.o seti_boinc-hires_timer.o seti_boinc-analyzeFuncs.o seti_boinc-analyzeReport.o seti_boinc-analyzePoT.o seti_boinc-pulsefind.o seti_boinc-gaussfit.o seti_boinc-lcgamm.o seti_boinc-malloc_a.o seti_boinc-seti.o seti_boinc-seti_header.o seti_boinc-timecvt.o seti_boinc-s_util.o seti_boinc-sah_version.o seti_boinc-worker.o seti_boinc-chirpfft.o seti_boinc-spike.o seti_boinc-autocorr.o seti_boinc-progress.o seti_boinc-fft8g.o seti_boinc-gdata.o seti_boinc-schema_master.o seti_boinc-sqlrow.o seti_boinc-sqlblob.o seti_boinc-xml_util.o -lboinc_opencl -lboinc_api -lboinc -lfftw3f /usr/arm-linux-androideabi/arm-linux-androideabi/lib/libstdc++.a -lssl -lcrypto -Bdynamic -lm -Bstatic --whole-archive --no-whole-archive -lgcc -Bdynamic -llog -lc -ldl -Bstatic -lgcc /usr/arm-linux-androideabi/sysroot/usr/lib/crtend_android.o boinc-app-seti_8.00~svn3701.orig/client/amd64fft8g.cpp0000644000175000017500000001160312313644616022355 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // AMD optimizations by Evandro Menezes #ifdef USE_AMD_OPT_CODE #include #include static const int as [4] [4] = {{0, 0, INT_MIN, INT_MIN}, // {-, -, +, +} {0, 0, 0, INT_MIN}, // {-, +, +, +} {0, INT_MIN, 0, INT_MIN}, // {-, +, -, +} {INT_MIN, 0, INT_MIN, 0}}; // {+, -, +, -} static const __m128 mmpp = *(__m128 *) (as [0] + 0), mppp = *(__m128 *) (as [1] + 0), mpmp = *(__m128 *) (as [2] + 0), pmpm = *(__m128 *) (as [3] + 0); void cftfsub(int n, float *a, float *w) { void cft1st(int n, float *a, float *w); void cftmdl(int n, int l, float *a, float *w); int j, j1, j2, j3, l; __m128 x10, x32, y10, y32, zz; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("cftfsub()"); #endif zz = _mm_setzero_ps (); l = 2; if (n >= 16) { cft1st(n, a, w); l = 16; while ((l << 3) <= n) { cftmdl(n, l, a, w); l <<= 3; } } if ((l << 1) < n) { for (j = 0; j < l; j += 2) { j1 = j + l; j2 = j1 + l; j3 = j2 + l; // x0r = a[j] + a[j1]; // x0i = a[j + 1] + a[j1 + 1]; x10 = _mm_loadl_pi (zz, (__m64 *) (a + j)); y10 = _mm_loadl_pi (zz, (__m64 *) (a + j1)); // x1r = a[j] - a[j1]; // x1i = a[j + 1] - a[j1 + 1]; x10 = _mm_movelh_ps (x10, x10); y10 = _mm_movelh_ps (y10, y10); y10 = _mm_xor_ps (mmpp, y10); x10 = _mm_add_ps (x10, y10); // x2r = a[j2] + a[j3]; // x2i = a[j2 + 1] + a[j3 + 1]; x32 = _mm_loadl_pi (zz, (__m64 *) (a + j2)); y32 = _mm_loadl_pi (zz, (__m64 *) (a + j3)); // x3r = a[j2] - a[j3]; // x3i = a[j2 + 1] - a[j3 + 1]; x32 = _mm_movelh_ps (x32, x32); y32 = _mm_movelh_ps (y32, y32); y32 = _mm_xor_ps (mmpp, y32); x32 = _mm_add_ps (x32, y32); // a[j] = x0r + x2r; // a[j + 1] = x0i + x2i; // a[j1] = x1r - x3i; // a[j1 + 1] = x1i + x3r; x32 = _mm_xor_ps (mppp, x32); x32 = _mm_shuffle_ps (x32, x32, _MM_SHUFFLE (2, 3, 1, 0)); y10 = _mm_add_ps (x10, x32); _mm_storel_pi ((__m64 *) (a + j), y10); _mm_storeh_pi ((__m64 *) (a + j1), y10); // a[j2] = x0r - x2r; // a[j2 + 1] = x0i - x2i; // a[j3] = x1r + x3i; // a[j3 + 1] = x1i - x3r; y32 = _mm_sub_ps (x10, x32); _mm_storel_pi ((__m64 *) (a + j2), y32); _mm_storeh_pi ((__m64 *) (a + j3), y32); } } else if ((l << 1) == n) { for (j = 0; j < l; j += 2) { j1 = j + l; // x0r = a[j] - a[j1]; // x0i = a[j + 1] - a[j1 + 1]; x10 = _mm_loadl_pi (zz, (__m64 *) (a + j)); x32 = _mm_loadl_pi (zz, (__m64 *) (a + j1)); y10 = _mm_sub_ps (x10, x32); // a[j] += a[j1]; // a[j + 1] += a[j1 + 1]; y32 = _mm_add_ps (x10, x32); _mm_storel_pi ((__m64 *) (a + j), y32); // a[j1] = x0r; // a[j1 + 1] = x0i; _mm_storel_pi ((__m64 *) (a + j1), y10); } } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } #endif // USE_AMD_OPT_CODE boinc-app-seti_8.00~svn3701.orig/client/malloc_a.h0000644000175000017500000000332612313644616021722 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // $Id: malloc_a.h,v 1.5.2.2 2005/06/26 19:55:43 korpela Exp $ // memory alignment multiple for large arrays #define MEM_ALIGN 128 void* malloc_a(size_t size, size_t alignment); void* calloc_a(size_t size, size_t nitems, size_t alignment); void free_a(void *palignedMem); boinc-app-seti_8.00~svn3701.orig/client/i686_graphics_link0000644000175000017500000000236012640272211023302 0ustar locutuslocutus g++ -m32 -O3 -I/usr/local/include -static-libgcc -g -Wall -I/usr/local/include -I/usr/include -I/usr/include/openssl -DHAVE_CONFIG_H -DTEXT_UI -DNDEBUG -DCLIENT -I../db -I../client -I../client/win_build -I/home/korpela/build/i686-linux/boinc -I/home/korpela/build/i686-linux/boinc/api -I/home/korpela/build/i686-linux/boinc/lib -I/home/korpela/build/i686-linux/boinc/sched -I/home/korpela/build/i686-linux/boinc/db -I/home/korpela/build/i686-linux/boinc/clientgui/mac -pthread -msse2 -mfpmath=sse -DUSE_SSE -DUSE_SSE2 -I/usr/ -g -Wall -I/usr/local/include -I/usr/include -I/usr/include/openssl -o seti_graphics seti_graphics-timecvt.o seti_graphics-sah_gfx.o seti_graphics-sah_gfx_base.o seti_graphics-graphics_main.o seti_graphics-sah_version.o -pthread -L/usr/local/lib -L/usr/lib -L/home/korpela/build/i686-linux/boinc/api -L/home/korpela/build/i686-linux/boinc/lib /usr/lib/gcc/i686-redhat-linux/4.4.7/libstdc++.a /home/korpela/build/i686-linux/boinc/api/.libs/libboinc_graphics2.a /usr/lib/libglut.so /usr/lib/libGLU.so /usr/lib/libGL.so /usr/local/lib/libjpeg.a /home/korpela/build/i686-linux/boinc/api/.libs/libboinc_api.a /home/korpela/build/i686-linux/boinc/lib/.libs/libboinc.a -pthread /usr/lib/gcc/i686-redhat-linux/4.4.7/libstdc++.a /usr/lib/libm.a boinc-app-seti_8.00~svn3701.orig/client/timecvt.cpp0000644000175000017500000001206412313644616022160 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. /* * * timecvt.c * * Time conversion routines. * * $Id: timecvt.cpp,v 1.6.2.4 2007/02/22 02:28:42 vonkorff Exp $ * */ #include "sah_config.h" #include "str_util.h" #include "str_replace.h" #include #include #include #include #include #ifdef HAVE_UNISTD_H #include #endif #include "diagnostics.h" #include "util.h" #include "s_util.h" #include "timecvt.h" void timecvt_start() {} static void trim_newline(char*p) { int n = (int)strlen(p); if (n && (p[n-1]=='\n')) { p[n-1] = 0; } } char* jd_string(double jd) { static char buf[256], datestr[64]; time_t tmptime; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("jd_string"); #endif /* USE_MANUAL_CALLSTACK */ if ( jd > JD0 ) { tmptime=jd_to_time_t(jd); strlcpy(datestr, asctime(gmtime(&tmptime)), sizeof(datestr)); trim_newline(datestr); sprintf(buf, "%14.5f (%s)", jd, datestr); } else { sprintf(buf,"%14.5f",jd); } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif /* USE_MANUAL_CALLSTACK */ return buf; } // output in human-readable form // char* short_jd_string(double jd) { static char buf[256]; time_t tmptime; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("short_jd_string()"); #endif /* USE_MANUAL_CALLSTACK */ if ( jd > JD0) { tmptime=jd_to_time_t(jd); strlcpy(buf, asctime(gmtime(&tmptime)),sizeof(buf)); trim_newline(buf); } else { strlcpy(buf,"Unknown",sizeof(buf)); } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif /* USE_MANUAL_CALLSTACK */ return buf; } void st_to_ut(TIME *st) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("st_to_ut()"); #endif /* USE_MANUAL_CALLSTACK */ double hour=((double)st->h)+((double)st->m)/60+((double)st->s)/3600 +((double)st->c)/360000; if (st->tz !=0) { hour-=st->tz; st->tz=0; if (hour<0) { hour+=24; st->d--; if (st->d<1) { st->y--; st->d+=NUM_DAYS(st->y); } } if (hour>=24) { hour-=24; st->d++; if (st->d>NUM_DAYS(st->y)) { st->d-=NUM_DAYS(st->y); st->y++; } } st->h=(int)hour; hour-=st->h; hour*=60; st->m=(int)hour; hour-=st->m; hour*=60; st->s=(int)hour; hour-=st->s; hour*=100; st->c=(int)hour; } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif /* USE_MANUAL_CALLSTACK */ } double ut_to_jd(long year, long month, long day, double hour) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("ut_to_jd"); #endif /* USE_MANUAL_CALLSTACK */ double jd; long l=(month-14)/12; jd=(double)(day-32075L+1461L*(year+4800L+l)/4+367l*(month-2-l*12)/12- 3*((year+4900l+l)/100)/4); jd+=(hour/24-0.5); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif /* USE_MANUAL_CALLSTACK */ return(jd); } double time_t_to_jd(time_t unix_time) { return (((double)unix_time)/SECONDS_PER_DAY+JD0); } time_t jd_to_time_t(double jd) { return ((time_t)((jd-JD0)*SECONDS_PER_DAY)); } void st_time_convert(TIME *st) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("st_time_convert"); #endif /* USE_MANUAL_CALLSTACK */ /* Fix Y2K Bug */ if (st->y < 90) { st->y+=2000; } else if (st->y < 100) { st->y+=1900; } /* Convert time zome time into UT */ st_to_ut(st); /* Fill in julian date field */ { double hour=((double)st->h)+((double)st->m)/60+((double)st->s)/3600 +((double)st->c)/360000; st->jd=ut_to_jd(st->y,1,st->d,hour); } /* Fill in unix_time field */ st->unix_time=jd_to_time_t(st->jd); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif /* USE_MANUAL_CALLSTACK */ } void timecvt_end() {} boinc-app-seti_8.00~svn3701.orig/client/autocorr.h0000644000175000017500000000307011516166324022004 0ustar locutuslocutus// Copyright 2011 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. int FindAutoCorrelation( float * AutoCorrelation, int ul_NumDataPoints, int fft_num, SETI_WU_INFO& swi ); boinc-app-seti_8.00~svn3701.orig/client/sah_gfx_base.cpp0000644000175000017500000003046012640263442023113 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. #include "sah_config.h" #ifdef _WIN32 #include "boinc_win.h" #include // Header File For The OpenGL32 Library #include // Header File For The GLu32 Library #if !defined(__MINGW32__) && !defined(_MSC_VER) #include // Header File For The Glaux Library #endif #include #endif #ifndef _WIN32 #include #include #ifdef __APPLE_CC__ #include #include #include #include #include #include #include #endif #endif #ifdef HAVE_IEEEFP_H #include #endif #include "s_util.h" #include "db/db_table.h" #include "db/schema_master.h" #include "boinc_gl.h" #include "parse.h" #include "graphics2.h" #include "sah_gfx_base.h" #include "gutil.h" #include "reduce.h" #include "graphics_data.h" #include "filesys.h" #define PI2 (2*3.1415926) #define SETI_LOGO_FILENAME "seti_logo" #define USER_LOGO_FILENAME "user_logo" #define SPONSOR_LOGO_FILENAME "sponsor_logo" #define BACKGROUND_FILENAME "background" #define SPONSOR_BKG_FILENAME "sponsor_bkg" // maximum resolutions for power graph #define MAX_GRAPH_RES_X 200 #define MAX_GRAPH_RES_Y 100 extern bool mouse_down; using namespace std; // The following must agree with the strings in // project_specific_prefs.inc // void GRAPHICS_PREFS::parse_project_prefs(char *buf) { std::string text; if (!buf) return; if (parse_str(buf, "", text)) { if (!strcmp(text.c_str(), "Pillars")) text_style = TEXT_STYLE_PILLARS; if (!strcmp(text.c_str(), "Panels")) text_style = TEXT_STYLE_PANELS; if (!strcmp(text.c_str(), "Heads-up")) text_style = TEXT_STYLE_HEADSUP; } if (parse_str(buf, "", text)) { if (!strcmp(text.c_str(), "Rectangles")) graph_style = GRAPH_STYLE_RECTANGLES; if (!strcmp(text.c_str(), "Wireframe")) graph_style = GRAPH_STYLE_WIREFRAME; if (!strcmp(text.c_str(), "Surface")) graph_style = GRAPH_STYLE_SURFACE; if (!strcmp(text.c_str(), "Planes")) graph_style = GRAPH_STYLE_PLANES; } parse_double(buf, "", max_fps); parse_double(buf, "", max_cpu); parse_double(buf, "", grow_time); parse_double(buf, "", hold_time); parse_double(buf, "", graph_alpha); parse_double(buf, "", roll_period); parse_double(buf, "", roll_range); parse_double(buf, "", pitch_period); parse_double(buf, "", pitch_range); parse_int(buf, "", starfield_size); parse_double(buf, "", starfield_speed); parse_double(buf, "", start_hue); parse_double(buf, "", hue_change); } void GRAPHICS_PREFS::defaults() { text_style = TEXT_STYLE_PILLARS; graph_style = GRAPH_STYLE_RECTANGLES; max_fps = 20; max_cpu = 30; grow_time = 10; hold_time = 10; graph_alpha = 0.7; pitch_period = 100; pitch_range = 20; roll_period = 300; roll_range = 30; starfield_size = 2000; starfield_speed = 40.0f; start_hue = 0.2; hue_change = 0.7; } SAH_GRAPHICS_BASE::SAH_GRAPHICS_BASE() : GRAPHICS_PREFS(), //GDATA(), roll_angle(0),roll_phase(0), pitch_angle(0),pitch_phase(0),starfield(),seti_logo_texture(), user_logo_texture(), background_texture(),viewpoint_distance(1.0) { data_struct_init(); } void SAH_GRAPHICS_BASE::start_rotate() { if (roll_period == 0 && pitch_period == 0) return; glPushMatrix(); if (pitch_period) { glRotated(pitch_angle + pitch_range*sin(pitch_phase), 1., 0., 0); } if (roll_period) { glRotated(roll_angle + roll_range*sin(roll_phase), 0., 1., 0); } } void SAH_GRAPHICS_BASE::incr_rotate(double dt) { if (mouse_down) return; pitch_phase += PI2*(dt/pitch_period); if (pitch_phase > PI2) pitch_phase -= PI2; roll_phase += PI2*(dt/roll_period); if (roll_phase > PI2) roll_phase -= PI2; } void SAH_GRAPHICS_BASE::end_rotate() { if (roll_period == 0 && pitch_period == 0) return; glPopMatrix(); } // A note on our coordinates: // X should be between -4 and 4 // Y should be between -3 and 3 // Z should be centered around zero (graph is -2 to +2) void SAH_GRAPHICS_BASE::draw_pillars() { float pos[3]; GLfloat violet[] = {0.6, 0.3, .8, 1.0}; GLfloat white[] = {1.0, 1.0, 1.0, 1.0}; COLOR color; double lum = .5; double sat = .5; double hue = start_hue + hue_change/2.; if (hue > 1) hue -= 1; if (hue < 1) hue += 1; HLStoRGB(hue, lum, sat, color); color.a = 1.0; GLfloat graphColor[4] = {color.r,color.g,color.b,color.a}; pos[0] = pos[1] = pos[2] = 0; mode_shaded(graphColor); pos[0] = -3.50; pos[1] = 0; drawCylinder(false, pos, 7.00, .10); drawSphere(pos, .10); pos[0] = 3.5; drawSphere(pos, .1); pos[0] = -3.50; pos[1] = 2.50; drawCylinder(false, pos, 7.00, .10); drawSphere(pos, .10); pos[0] = 3.5; drawSphere(pos, .1); pos[0] = 1.00; pos[1] = 1.25; drawCylinder(false, pos, 2.50, .10); pos[0] = 3.5; drawSphere(pos, .1); pos[0] = 1.00; pos[1] = 0; drawCylinder(true, pos, 2.50, .10); } void set_viewpoint(double dist) { double x, y, z; x = 0; y = 3.0*dist; z = 11.0*dist; glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt( x, y, z, // eye position 0,-.8,0, // where we're looking 0.0, 1.0, 0. // up is in positive Y direction ); } static void initlights() { GLfloat ambient[] = {1., 1., 1., 1.0}; GLfloat position[] = {-13.0, 6.0, 20.0, 1.0}; GLfloat dir[] = {-1, -.5, -3, 1.0}; glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); glLightfv(GL_LIGHT0, GL_POSITION, position); glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, dir); } void SAH_GRAPHICS_BASE::render_logos() { float pos[3] = {.03, .03, 0}; float size[3] = {.27, .3, 0}; bool any = seti_logo_texture.present || user_logo_texture.present; if (any) { mode_ortho(); mode_unshaded(); } //draw texture justified at bottom left relative to coords if (seti_logo_texture.present) { seti_logo_texture.draw(pos, size, ALIGN_BOTTOM, ALIGN_BOTTOM); } float pos2[3] = {.7, .03, 0}; float size2[3] = {.27, .3, 0}; //draw texture justified at bottom right relative to coords if (user_logo_texture.present) { user_logo_texture.draw(pos2, size2, ALIGN_TOP, ALIGN_BOTTOM); } if (any) { ortho_done(); } } void SAH_GRAPHICS_BASE::render_background() { float pos[3], size[3]; // draw image behind graph, if any // if (background_texture.present) { mode_texture(); pos[0] = -3; pos[1] = -3; pos[2] = -2; size[0] = 6; size[1] = 6; size[2] = 0; background_texture.draw(pos, size, ALIGN_CENTER, ALIGN_CENTER); } } void SAH_GRAPHICS_BASE::render_3d_graph(double time_of_day) { double elapsed_time,frac_done; if (rarray.start_time == 0) { rarray.start_time = time_of_day; } elapsed_time = time_of_day - rarray.start_time; if (elapsed_time >= grow_time) { frac_done = 1.0; } else { frac_done = elapsed_time/grow_time; } rarray.draw_axes(); rarray.draw_labels(); rarray.draw_part(frac_done); if (elapsed_time >= grow_time + hold_time) { memcpy(&rarray, &sah_shmem->rarray_data, sizeof(REDUCED_ARRAY_DATA)); rarray.start_time = time_of_day; rarray.new_array(); } } // this sets up the shared data structures, // don't make any OpenGL calls from here // This is called before BOINC initialization, // so don't do any BOINC-related stuff // void SAH_GRAPHICS_BASE::data_struct_init() { defaults(); srand(time(NULL)); } // this is called from the graphics thread; // it does OpenGL initialization. // This is always called after init_worker_thread(), // so the graphics prefs are in place. // void SAH_GRAPHICS_BASE::graphics_thread_init() { boinc_get_init_data(app_init_data); parse_project_prefs(app_init_data.project_preferences); glShadeModel(GL_SMOOTH); // Enable Smooth Shading glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black Background glClearDepth(1.0f); // Depth Buffer Setup glEnable(GL_DEPTH_TEST); // Enables Depth Testing glEnable(GL_LINE_SMOOTH); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glEnable(GL_BLEND); glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations initlights(); int viewport[4]; get_viewport(viewport); int w = viewport[2]; int h = viewport[3]; resize(w,h); } void SAH_GRAPHICS_BASE::resize(int w, int h) { //float fontsize = (w/35.0f>14) ? 14 : w/35.0f; //int weight = (700>w*35.0f/24.0f) ? 700 : w*35.0f/24.0f; //listBase=MyCreateFont("Ariel",fontsize,weight); height=h; width=w; glViewport(0, 0, w, h); } void SAH_GRAPHICS_BASE::setup_given_prefs() { char filename[256],bkg_filename[256]; boinc_max_fps = max_fps; boinc_max_gfx_cpu_frac = max_cpu/100.; if (starfield_size) { starfield.build_stars(starfield_size, starfield_speed); } seti_logo_texture.present = false; user_logo_texture.present = false; background_texture.present = false; double fsize=0; boinc_resolve_filename(SETI_LOGO_FILENAME, filename, sizeof(filename)); if (!file_size(filename,fsize) && (fsize>4096)) { seti_logo_texture.load_image_file(filename); } else { fprintf(stderr,"Warning: unable to load JPEG file. File size=%d\n",(int)fsize); seti_logo_texture.present=false; } if (gdata) { int s4_id=gdata->wu.s4_id; if (s4_id >= 17) { time_t t=time(0); struct tm *tm=localtime(&t); if (tm->tm_year >= 116) { boinc_resolve_filename(SPONSOR_LOGO_FILENAME, filename, sizeof(filename)); boinc_resolve_filename(SPONSOR_BKG_FILENAME, bkg_filename, sizeof(bkg_filename)); if (!boinc_file_exists(filename)) boinc_resolve_filename(USER_LOGO_FILENAME, filename, sizeof(filename)); if (!boinc_file_exists(bkg_filename)) boinc_resolve_filename(BACKGROUND_FILENAME, bkg_filename, sizeof(bkg_filename)); } else { boinc_resolve_filename(USER_LOGO_FILENAME, filename, sizeof(filename)); boinc_resolve_filename(BACKGROUND_FILENAME, bkg_filename, sizeof(bkg_filename)); } } else { boinc_resolve_filename(USER_LOGO_FILENAME, filename, sizeof(filename)); boinc_resolve_filename(BACKGROUND_FILENAME, bkg_filename, sizeof(filename)); } } else { boinc_resolve_filename(USER_LOGO_FILENAME, filename, sizeof(filename)); boinc_resolve_filename(BACKGROUND_FILENAME, bkg_filename, sizeof(filename)); } user_logo_texture.load_image_file(filename); background_texture.load_image_file(bkg_filename); } boinc-app-seti_8.00~svn3701.orig/client/timecvt.h0000644000175000017500000000532010671336410021615 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. /* * * timecvt.h * * Time conversion routines. * * $Id: timecvt.h,v 1.3.2.2 2005/10/09 18:24:22 korpela Exp $ * */ #ifndef TIMECVT_H #define TIMECVT_H #include struct TIME { int y,d,h,m,s,c; double tz; double jd; time_t unix_time; TIME operator -(const TIME &b) const; }; #ifdef __MWERKS__ // Note: Although Macintosh time is based on 1/1/1904, the //MetroWerks Standard Libraries time routines use a base of 1/1/1900. //#define JD0 2416480.5 /* Time at 0:00 GMT 1904 Jan 1 */ #define JD0 2415020.5 /* Time at 0:00 GMT 1900 Jan 1 */ #else #define JD0 2440587.5 /* Time at 0:00 GMT 1970 Jan 1 */ #endif #define SECONDS_PER_DAY 86400 #define ISLEAP(y) ((!((y) % 4) && ((y) % 100)) || !((y) % 400)) #define NUM_DAYS(year) (365+ISLEAP(year)) extern char* jd_string(double jd); extern char* short_jd_string(double jd); extern double ut_to_jd(long year, long month, long day, double hour); extern double time_t_to_jd(time_t unix_time); extern time_t jd_to_time_t(double jd); extern void st_time_convert(TIME *st); inline TIME TIME::operator -(const TIME &b) const { TIME r; r.tz=tz-b.tz; r.jd=jd-b.jd; r.unix_time=jd_to_time_t(r.jd); if (r.tz != 0) { r.jd-=(r.tz/24); r.unix_time-=((long)(r.tz)*3600); r.tz=0; } return r; } #endif boinc-app-seti_8.00~svn3701.orig/client/analyzePoT.cpp0000644000175000017500000007106112622476124022575 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // $Id: analyzePoT.cpp,v 1.24.2.13 2007/08/10 00:38:47 korpela Exp $ // #include "sah_config.h" #include #include #include #include #ifdef HAVE_UNISTD_H #include #endif #ifdef BOINC_APP_GRAPHICS #include "sah_gfx_main.h" #endif #include "util.h" #include "malloc_a.h" #include "analyze.h" #include "seti.h" #include "worker.h" #include "analyzeFuncs.h" #include "analyzePoT.h" #include "analyzeReport.h" #include "gaussfit.h" #include "pulsefind.h" #include "chirpfft.h" #include "filesys.h" #include "util.h" #include "s_util.h" #include "progress.h" #ifdef __arm__ #include "vector/fp_arm.h" #endif //#define DEBUG_POT // Compile time inits. Command line parms of setiathome_test can // change a number of these. PoTInfo_t PoTInfo = {0}; int analyze_pot( float *PowerSpectrum, int NumDataPoints, ChirpFftPair_t &cfft ) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("analyze_pot()"); #endif // This function analyses Power over Time for the current data block. // The PoT array is created by taking an array of power spectra (a // standard row-major 2D array) and extracting the PoT as column-major // data. We essentialy turn the array on its side. int retval = 0, i, FftLength=cfft.FftLen, // Current FFT length ThisPoT, // index of current PoT along the freq axis PoTLen, // compliment of FFT length - determines time res PulsePoTLen, // length of PoT segment passed to pulse finders Overlap, // PoT segment overlap in bins TOffset, // index into ThisPoT of current pulse segment PulsePoTNum = 0, // the oridinal position of a pulse PoT w/in a full PoT NumPulsePoTs = 0, // the number of pulse PoTs w/in a full PoT. This is // constant regardless of FFT or PoT length and is // determined by slew rate. AdvanceBy; // the number of bins to advance for the next pulse PoT float ProgressAddFactor = 0.0, // sum of progress adds for ThisPoT ProgressPerPulsePoT = 0.0; // for local progress display bool SkipGauss = false, SkipPulse = false, SkipTriplet = false, TOffsetOK = true; static float *GaussPoT = NULL, *PulsePoT = NULL; #ifdef DUMP_POWER_SPECTRA if (ul_FftLength == FFT_TO_DUMP) { for (i=0;i PoTInfo.TripletMax || PulsePoTLen < PoTInfo.TripletMin) SkipTriplet = true; SkipGauss = !(cfft.GaussFit); SkipPulse = !(cfft.PulseFind); if(!SkipPulse || !SkipTriplet) { // NumPulsePoTs is the number of PoT segments that we pass to the pulse // detectors per frequency bin. ProgressPerPulsePoT is the inverse of // number of pulse detection segments in the entire data block, taking // into account that we skip the first (DC) frequency bin. An assumption // is made here that minimum pulse/triplet PoT length will always be // greater than 1. Otherwise, AdvanceBy can become zero and a divide by // zero can occur. The assumption is also made that FftLength is always // greater than 1! NumPulsePoTs = 1 + (PoTLen-PulsePoTLen)/AdvanceBy + ((PoTLen-PulsePoTLen)%AdvanceBy ? 1 : 0); ProgressPerPulsePoT = (float)1 / ((FftLength - 1) * NumPulsePoTs); } #ifdef DEBUG_POT fprintf(stderr, "SlewRate = %f\n", PoTInfo.SlewRate); fprintf(stderr, "PoTLen = %d\n", PoTLen); fprintf(stderr, "MaxPoTLen = %d\n", PoTInfo.MaxPoTLen); fprintf(stderr, "PoTDuration = %f\n", PoTInfo.WUDuration); fprintf(stderr, "BeamRate = %f\n", PoTInfo.BeamRate); fprintf(stderr, "PulsePoTLen = %d\n", PulsePoTLen); fprintf(stderr, "Overlap = %d\n", Overlap); fprintf(stderr, "AdvanceBy = %d\n", AdvanceBy); fprintf(stderr, "min_slew = %f\n", PoTInfo.min_slew); fprintf(stderr, "max_slew = %f\n", PoTInfo.max_slew); fprintf(stderr, "PulseOverlapFactor = %f\n", PoTInfo.PulseOverlapFactor); fprintf(stderr, "PulseBeams = %f\n", PoTInfo.PulseBeams); fprintf(stderr, "PulseThresh = %f\n", PoTInfo.PulseThresh); fprintf(stderr, "PulseMax = %d\n", PoTInfo.PulseMax); fprintf(stderr, "PulseMin = %d\n", PoTInfo.PulseMin); fprintf(stderr, "PulseFftMax = %d\n", PoTInfo.PulseFftMax); fprintf(stderr, "TripletThresh = %f\n", PoTInfo.TripletThresh); fprintf(stderr, "TripletMax = %d\n", PoTInfo.TripletMax); fprintf(stderr, "TripletMin = %d\n", PoTInfo.TripletMin); #endif #ifndef USE_PULSE SkipPulse = TRUE; #endif #ifndef USE_TRIPLET SkipTriplet = TRUE; #endif // Get memory fot the PoT arrays. The PoT array for gausian analysis is // of set size. The PoT array for pulse analysis is sized to cover // PulseBeams beams, regardless of whether this violates either the // triplet or pulse limits on array size. if(!GaussPoT) { GaussPoT = (float *)malloc_a(swi.analysis_cfg.gauss_pot_length * sizeof(float), MEM_ALIGN); if(GaussPoT == NULL) { SETIERROR(MALLOC_FAILED, "GaussPoT == NULL"); } } if(!PulsePoT) { PulsePoT = (float *)calloc_a(PoTInfo.MaxPoTLen+3, sizeof(float), MEM_ALIGN); if(PulsePoT == NULL) { SETIERROR(MALLOC_FAILED, "PulsePoT == NULL"); } } // Look for gaussians --------------------------------------------------- if(!SkipGauss && (analysis_state.PoT_activity == POT_DOING_GAUSS || analysis_state.PoT_activity == POT_INACTIVE)) { #ifdef BOINC_APP_GRAPHICS if (sah_graphics) strcpy(sah_graphics->status, "Searching for Gaussians"); #endif // If we are back from being interrupted in the middle of gaussian PoT // analysis, load state and continue. Otherwise start anew, skipping // the DC (0) bin. if(analysis_state.PoT_activity == POT_DOING_GAUSS) { ThisPoT = analysis_state.PoT_freq_bin; } else { ThisPoT = 1; // skip the DC bin on start of new cfft pair } // Initial display of local Progress / CPU time. Assumes that // we start ThisPoT at 1 each time in! #ifdef BOINC_APP_GRAPHICS if (sah_graphics) sah_graphics->local_progress = ((float)ThisPoT-1)/(FftLength-1); #endif // loop through frequencies for(; ThisPoT < FftLength; ThisPoT++) { // Create PowerOfTime array for gaussian fit retval = GetFixedPoT( PowerSpectrum, NumDataPoints, FftLength, GaussPoT, swi.analysis_cfg.gauss_pot_length, ThisPoT ); if (retval) continue; retval = GaussFit(GaussPoT, FftLength, ThisPoT); if (retval) SETIERROR(retval,"from GaussFit"); progress += ProgressUnitSize * GaussianProgressUnits() / (float)(FftLength - 1); progress=std::min(progress,1.0); // prevent display of > 100% fraction_done(progress,remaining); // At the end of each frequency bin we update progress and save state. #ifdef BOINC_APP_GRAPHICS if (!nographics()) { sah_graphics->local_progress = ((float)ThisPoT)/(FftLength-1); } #endif analysis_state.PoT_freq_bin = ThisPoT; analysis_state.PoT_activity = POT_DOING_GAUSS; retval = checkpoint(); if (retval) SETIERROR(retval,"from checkpoint()"); } // end loop through frequencies analysis_state.PoT_freq_bin = -1; analysis_state.PoT_activity = POT_INACTIVE; } // end looking for gaussians // Look for pulses ------------------------------------------------------- if(!SkipPulse || !SkipTriplet) { #ifdef BOINC_APP_GRAPHICS if (sah_graphics) { strcpy(sah_graphics->status, "Searching for Pulses / Triplets"); // init local progress for pulse search sah_graphics->local_progress = 0; } #endif // If we are back from being interrupted in the middle of pulse PoT // analysis, load state and continue. Otherwise start anew, skipping // the DC (0) bin. if(analysis_state.PoT_activity == POT_DOING_PULSE) { ThisPoT = analysis_state.PoT_freq_bin; } else { ThisPoT = 1; // skip the DC bin on start of new cfft pair } PulsePoTNum = 0; #ifdef BOINC_APP_GRAPHICS // Inital display of Local Progress if (sah_graphics) { sah_graphics->local_progress = (((ThisPoT-1) * NumPulsePoTs) + PulsePoTNum) * ProgressPerPulsePoT; } #endif // loop through frequencies for(; ThisPoT < FftLength; ThisPoT++) { // loop through time for each frequency. PulsePoTNum is // used only for progress calculation. for(TOffset = 0, PulsePoTNum = 1, TOffsetOK = true; TOffsetOK; PulsePoTNum++, TOffset += AdvanceBy) { // Create PowerOfTime array for pulse detection. If there // are not enough points left in this PoT, adjust TOffset // to get the latest possible pulse PoT. if(TOffset + PulsePoTLen >= PoTLen) { TOffsetOK = false; TOffset = PoTLen - PulsePoTLen; } if (use_transposed_pot) { memcpy(PulsePoT, &PowerSpectrum[ThisPoT * PoTLen + TOffset], PulsePoTLen*sizeof(float)); } else { for(i = 0; i < PulsePoTLen; i++) { PulsePoT[i] = PowerSpectrum[ThisPoT + (TOffset+i) * FftLength]; } } if(!SkipTriplet) { retval = find_triplets(PulsePoT, PulsePoTLen, (float)PoTInfo.TripletThresh, TOffset, ThisPoT); if (retval) SETIERROR(retval,"from find_triplets()"); } if(!SkipPulse) { retval = find_pulse(PulsePoT, PulsePoTLen, (float)PoTInfo.PulseThresh, TOffset, ThisPoT ); if (retval) SETIERROR(retval,"from find_pulse()"); } // At the end of each pulse PoT we update progress. Progress // will thus get updted several times per frequency bin. #ifdef BOINC_APP_GRAPHICS if (sah_graphics) { sah_graphics->local_progress = (((ThisPoT-1) * NumPulsePoTs) + PulsePoTNum) * ProgressPerPulsePoT; } #endif if(!SkipTriplet) { progress += (ProgressUnitSize * TripletProgressUnits()) / (float)(FftLength - 1) / NumPulsePoTs; } if(!SkipPulse) { progress += (ProgressUnitSize * PulseProgressUnits(PulsePoTLen, FftLength - 1)) / (float)(FftLength - 1) / NumPulsePoTs; } progress=std::min(progress,1.0); // prevent display of > 100% fraction_done(progress,remaining); } // end loop through time for each frequency // At the end of each frequency bin we save state. analysis_state.PoT_activity = POT_DOING_PULSE; analysis_state.PoT_freq_bin = ThisPoT; retval = checkpoint(); if (retval) SETIERROR(retval,"from checkpoint()"); } // end loop through frequencies analysis_state.PoT_freq_bin = -1; analysis_state.PoT_activity = POT_INACTIVE; } // end looking for pulses #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return (retval); // no error return point } int GetFixedPoT( float fp_PowerSpectrum[], int ul_NumDataPoints, int ul_FftLength, float fp_PoT[], int ul_PoTLen, int ul_PoT ) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("GetFixedPoT()"); #endif // This routine returns a PoT array of fixed length, regardless // of the actual number of time bins in the current data block. int ul_PoT_i, ul_PoTChunkSize, ul_PoTChunk_i, ul_PoTChunkLimit, ul_NumSpectra, ul_PoTsPerSpec, ul_MidPoint, ul_BaseSpec, ul_SubPoT_i; float f_Factor, f_BaseSpecPowerPerPoT = 0.0, f_AftSpecPowerPerPoT = 0.0, f_ForwardSpecPowerPerPoT = 0.0, f_BaseWeight; ul_NumSpectra = ul_NumDataPoints / ul_FftLength; ul_PoTChunkSize = ul_NumSpectra / ul_PoTLen; // Populate PoT // For setiathome_enhanced, the number of spectra is the same as the // number of elements in a PoT array more times than not (16K FFT length). // For an 0.426 angle range, there are 2.2104e10 cases where they're equal // and 2.2082e10 cases where they're not. Copying directly rather than // adding also means no FLOP_counter increment is needed. if (ul_NumSpectra == ul_PoTLen) { if (use_transposed_pot) { memcpy(fp_PoT, &fp_PowerSpectrum[ul_PoT * ul_NumSpectra], swi.analysis_cfg.gauss_pot_length * sizeof(float)); } else { for (ul_PoT_i = 0, ul_PoTChunk_i = 0; ul_PoT_i < swi.analysis_cfg.gauss_pot_length; ul_PoT_i++, ul_PoTChunk_i += ul_FftLength) { fp_PoT[ul_PoT_i] = fp_PowerSpectrum[ul_PoT + ul_PoTChunk_i]; } } // If the number of spectra is greater than the number // of elements in a PoT array, we add sum adjacent spectra // into PoT elements. // ul_PoTChunkSize indicates how many time-wise // power spectra bins are added together to make one PoT bin. } else if (ul_NumSpectra > ul_PoTLen) { ul_PoTChunk_i = 0; int blksize = UNSTDMAX(1, UNSTDMIN(pow2((unsigned int) sqrt((float) ((ul_PoTChunkSize) / 32)) * 32), 512)); for (ul_PoT_i = 0; ul_PoT_i < swi.analysis_cfg.gauss_pot_length; ul_PoT_i++) { fp_PoT[ul_PoT_i] = 0.0; ul_PoTChunkLimit = ul_PoTChunk_i + ul_PoTChunkSize; // Stuff chunk of power spectra bins into 1 PoT bin int b,chunk_i; float total = 0.0f,partial; if (use_transposed_pot) { for (b=0;b 0) { if (use_transposed_pot) { f_AftSpecPowerPerPoT = fp_PowerSpectrum[ul_PoT * ul_NumSpectra + (ul_BaseSpec-1)] * f_Factor; } else { f_AftSpecPowerPerPoT = fp_PowerSpectrum[ul_PoT + ul_FftLength * (ul_BaseSpec-1)] * f_Factor; } } if (ul_BaseSpec < ul_NumSpectra - 1) { if (use_transposed_pot) { f_ForwardSpecPowerPerPoT = fp_PowerSpectrum[ul_PoT * ul_NumSpectra + (ul_BaseSpec+1)] * f_Factor; } else { f_ForwardSpecPowerPerPoT = fp_PowerSpectrum[ul_PoT + ul_FftLength * (ul_BaseSpec+1)] * f_Factor; } } // Begin interpolation. if (ul_SubPoT_i < ul_MidPoint) { // Use the Aft spectrum if there is one. // If not, use non-interpoated powers. if (ul_BaseSpec == 0) { fp_PoT[ul_PoT_i] = f_BaseSpecPowerPerPoT; } else { f_BaseWeight = (float)(ul_PoTsPerSpec - (ul_MidPoint - ul_SubPoT_i)) / ul_PoTsPerSpec; fp_PoT[ul_PoT_i] = (f_BaseSpecPowerPerPoT * f_BaseWeight) + (f_AftSpecPowerPerPoT * (1.0f - f_BaseWeight)); } } else { // Use the Forward spectrum if there is one. // If not, use non-interpoated powers. if (ul_BaseSpec == ul_NumSpectra-1) { fp_PoT[ul_PoT_i] = f_BaseSpecPowerPerPoT; } else { f_BaseWeight = (float)(ul_PoTsPerSpec - (ul_SubPoT_i - ul_MidPoint)) / ul_PoTsPerSpec; fp_PoT[ul_PoT_i] = (f_BaseSpecPowerPerPoT * f_BaseWeight) + (f_ForwardSpecPowerPerPoT * (1.0f - f_BaseWeight)); } } } // end for ul_PoT_i < swi.analysis_cfg.gauss_pot_length analysis_state.FLOP_counter+=(double)(9*swi.analysis_cfg.gauss_pot_length); } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } void ComputePoTInfo(int num_cfft, int NumDataPoints) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("ComputePoTInfo()"); #endif // Tis routine calculates various PoT values based on program constants // and data contained in the current WU. // A note on "sigma", calculated here and used by the gaussian finder: // The sigma calculated here is in units of PoT, ie, in bins of the // Power Of Time arrays. Gaussian PoT arrays are of fixed length, given by // GAUSS_POT_LEN. The basic definition of sigma here is that it is the // amount of time it takes to cover 1/2 the half-power-beamwidth of the // serendip feed. This is also a constant - BEAM_WIDTH - in units of // degrees. We scan BEAM_WIDTH degrees at a given, but variable, slew rate. // volatile double DegPerPotBin; // slew rate in degrees per PoT bin volatile float ftmp; // temporary to ensure float rounding int i, MinFftLen; // jeffc - is there really any need for these PoTInfo fields // at this point? PoTInfo.min_slew = swi.analysis_cfg.pot_min_slew; PoTInfo.max_slew = swi.analysis_cfg.pot_max_slew; PoTInfo.PulseOverlapFactor = swi.analysis_cfg.pot_overlap_factor; // ? PoTInfo.PulseBeams = swi.analysis_cfg.pulse_beams; PoTInfo.PulseThresh = swi.analysis_cfg.pulse_thresh; PoTInfo.PulseMax = swi.analysis_cfg.pulse_max; PoTInfo.PulseMin = swi.analysis_cfg.pulse_min; PoTInfo.PulseFftMax = swi.analysis_cfg.pulse_fft_max; PoTInfo.TripletThresh = swi.analysis_cfg.triplet_thresh; PoTInfo.TripletMax = swi.analysis_cfg.triplet_max; //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; // Find the max fft length in the chirp/fft table for(i = 1, MinFftLen = ChirpFftPairs[0].FftLen; i < num_cfft; i++) { if(ChirpFftPairs[i].FftLen < MinFftLen) { MinFftLen = ChirpFftPairs[i].FftLen; } } PoTInfo.MaxPoTLen = NumDataPoints / MinFftLen; ftmp = (float)(swi.nsamples / swi.subband_sample_rate); PoTInfo.WUDuration = ftmp; // 11/2/15 - EK increased accuracy of conversion from HPBW to gaussian sigma // // Here we calculate slew rate and slew related values. // If there is no telescope movement, slew related values remain // in their initialized state (zero). if(swi.angle_range != 0.0) { ftmp = (float)(swi.angle_range / PoTInfo.WUDuration); PoTInfo.SlewRate = ftmp; ftmp = (float)(PoTInfo.SlewRate / swi.beam_width); PoTInfo.BeamRate = ftmp; DegPerPotBin = swi.angle_range / swi.analysis_cfg.gauss_pot_length; ftmp = (float)((swi.beam_width/2.35482f) / DegPerPotBin); PoTInfo.GaussSigma = ftmp; PoTInfo.GaussSigmaSq = PoTInfo.GaussSigma * PoTInfo.GaussSigma; PoTInfo.GaussTOffsetStart = static_cast(floor(swi.analysis_cfg.pot_t_offset * PoTInfo.GaussSigma+0.5)); PoTInfo.GaussTOffsetStop = swi.analysis_cfg.gauss_pot_length - PoTInfo.GaussTOffsetStart; } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } void GetPulsePoTLen(long FullPoTLen, int * PulsePoTLen, int * PulseOverlap) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("GetPulsePotLen()"); #endif // This routine, given the time axis length of a WU in bins and data available // in the PoTInfo struct, will calculate how many time bins to pass the pulse // detectors for the given time axis length. Time axis length in seconds is // is constant, while length in bins is inversely proportional to FFT length. // If slew rate is so low that, over the duration of the entire WU, // we do not cover the number of beams passed to each call of the // pulse finders then assume that we will be passing the entire PoT // to the pulse finders. This also takes care of the case where slew // rate is zero. Otherwise, calculate that portion of the PoT that // we will be passing. // NOTE: the code calling this routine may be concerned with either pulse finding // or triplet finding. There may be different max and/or min PoT length constraints // between these 2 algorithms. Thus, this routine just returns the length that // will contain PoTInfo.PulseBeams worth of data. It is up to the calling code // to then apply any length constaints. double BinRate, // function of time resolution and slew rate BinsPerBeam; // function of time res, slew rate, and beam width // jeffc - the following line in temporary. Pulse beams will go into the // analysis config. //PoTInfo.PulseBeams = 1.0; BinRate = FullPoTLen / PoTInfo.WUDuration; // in bins/second if(PoTInfo.BeamRate * PoTInfo.WUDuration < PoTInfo.PulseBeams) { BinsPerBeam = (float)FullPoTLen; // slow slew - pass FullPoT } else { BinsPerBeam = BinRate / PoTInfo.BeamRate; // we will pass a portion of FullPoT } *PulsePoTLen = IROUND(BinsPerBeam * PoTInfo.PulseBeams); // in bins if(*PulsePoTLen > FullPoTLen) { *PulsePoTLen = FullPoTLen; // pulse PoT longer than full PoT } // ... so pass as much as we can // ... ie the full PoT *PulseOverlap = IROUND(BinsPerBeam * PoTInfo.PulseOverlapFactor); // in bins #ifdef DEBUG_POT fprintf(stderr, "BinRate = %f\n", BinRate); fprintf(stderr, "BinsPerBeam = %f\n", BinsPerBeam); #endif #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } boinc-app-seti_8.00~svn3701.orig/client/lcgamm.cpp0000644000175000017500000001245712313644616021753 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. /* * $Id: lcgamm.cpp,v 1.9.2.11 2007/05/31 22:03:10 korpela Exp $ */ #include "sah_config.h" #if defined(_WIN32) && !defined(__MINGW32__) #include #endif #include #include #include #include #include #include // delete me! #include "diagnostics.h" #define ITMAX 10000 // Needs to be a few times the sqrt of the max. input to lcgf #define FP_EPS 1.0e-35 /* Log of the complete gamma function */ static double gammln(double a) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("gammln()"); #endif double x,y,tmp,ser,rv; static double cof[6]={76.18009172947146,-86.50532032941677, 24.01409824083091,-1.231739572450155, 0.1208650973866179e-2,-0.5395239384953e-5}; int j; y=x=a; tmp=x+5.5; tmp -= (x+0.5)*log(tmp); ser=1.000000000190015; for (j=0;j<=5;j++) ser += cof[j]/++y; rv=(double)(-tmp+log(2.5066282746310005*ser/x)); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return rv; } /* Log of the compliment of the incomplete gamma function * log(1-P(a,x)) valid only for (a+1)::epsilon(); const double FPMIN=std::numeric_limits::min()/EPS; double an,b,c,d,del,h,gln=gammln(a),rv; // assert(x>=(a+1)); BOINCASSERT(x>=(a+1)); b=x+1.0-a; c=1.0f/FPMIN; d=1.0/b; h=d; for (i=1;i<=ITMAX;i++) { an = -i*(i-a); b += 2.0; d=an*d+b; if (fabs(d)=0); rts=0.5f*(xh+xl); dxold=(float)fabs(xh-xl); dx=dxold; f=lcgf(a,rts)-y; df=dlcgf(a,rts); for (j=1;j<=ITMAX;j++) { if ((((rts-xh)*df-f)*((rts-xl)*df-f) >= 0.0) || (fabs(2.0*f)>fabs(dxold*df))) { dxold=dx; dx=0.5f*(xh-xl); rts=xl+dx; if ((xl==rts) || (xh==rts)) { #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return rts; } } else { dxold=dx; dx=f/df; temp=rts; rts-=dx; if (temp==rts) { #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return rts; } } f=lcgf(a,rts)-y; df=dlcgf(a,rts); if (fabs(f) #include using namespace std; #define DEFAULT_SIZE 1024 template 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 boinc-app-seti_8.00~svn3701.orig/client/classes/ICoreSigProc/IPowerspectrum/0000755000175000017500000000000013155506323026710 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/client/classes/ICoreSigProc/ITranspose/0000755000175000017500000000000013155506323026007 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/client/classes/ICoreSigProc/IChirp/0000755000175000017500000000000013155506323025076 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/client/classes/ICoreSigProc/ISmooth/0000755000175000017500000000000013155506323025302 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/client/classes/ICoreSigProc/ISearch/0000755000175000017500000000000013155506323025236 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/client/classes/ICoreSigProc/ISearch/IGaussian/0000755000175000017500000000000013155506323027121 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/client/classes/ICoreSigProc/ISearch/IAutoCorrelation/0000755000175000017500000000000013155506323030461 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/client/classes/ICoreSigProc/ISearch/ISpike/0000755000175000017500000000000013155506323026422 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/client/classes/ICoreSigProc/ISearch/IPulse/0000755000175000017500000000000013155506323026437 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/client/classes/ICoreSigProc/ISearch/ITriplet/0000755000175000017500000000000013155506323026772 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/client/classes/ICoreSigProc/ICoreSigProc.cpp0000644000175000017500000000247112342124360026712 0ustar locutuslocutus#include "ICoreSigProc.h" template class ICoreSigProc; 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 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); } */ boinc-app-seti_8.00~svn3701.orig/client/classes/ICoreSigProc/IFFT/0000755000175000017500000000000013155506323024450 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/client/classes/classes_history.txt0000644000175000017500000000723212342130054025402 0ustar locutuslocutus----------------------------------------------------------------------------------------------------------- 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 ) -----------------------------------------------------------------------------------------------------------boinc-app-seti_8.00~svn3701.orig/client/classes/IDevice/0000755000175000017500000000000013155506323022740 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/client/classes/IDevice/IGPU/0000755000175000017500000000000013155506323023504 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/client/classes/IDevice/ICPU/0000755000175000017500000000000013155506323023500 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/client/classes/IDevice/IRemote/0000755000175000017500000000000013155506323024304 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/client/sah_gfx.h0000644000175000017500000000514410707732502021567 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. #ifndef SAH_GFX_H #define SAH_GFX_H #include "gdata.h" #include "reduce.h" #include "gutil.h" #include "sah_gfx_base.h" // SAH_GRAPHICS combines all the info needed to draw S@h graphics: // - user preferences (GRAPHICS_PREFS) // - generic project graphics (SAH_GRAPHICS_BASE) // - data from the analysis (GDATA) // - internal state // Its member functions do the rendering // class SAH_GRAPHICS: public SAH_GRAPHICS_BASE { PROGRESS inner_progress; PROGRESS outer_progress; PROGRESS_2D outer_progress_2d; // outer progress for 2D display RIBBON_GRAPH rnd_graph; RIBBON_GRAPH sin_graph; MOVING_TEXT_PANEL text_panels[3]; void render_pillars(double, double); void render_panels(double, double); void render_headsup(double, double); void init_text_panels(); void get_data_info_string(char*); void get_user_info_string(char*); void get_analysis_info_string(char*); int choose_signal_to_display(double time_of_day); public: void render(int x, int y, double t); void data_struct_init(); void graphics_thread_init(); void reread_prefs(); void setup_given_prefs(); }; extern SAH_GRAPHICS sah_graphics; #endif boinc-app-seti_8.00~svn3701.orig/client/worker.cpp0000644000175000017500000001346713105256145022022 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // worker.C: SETI-independent worker logic // $Id: worker.cpp,v 1.32.2.14 2007/08/10 00:38:49 korpela Exp $ // #include "sah_config.h" #include #include #include #ifdef HAVE_UNISTD_H #include #endif #include #ifndef _WIN32 #include #endif #ifdef BOINC_APP_GRAPHICS #include "sah_gfx_main.h" #endif #include "s_util.h" #include "seti_header.h" #include "seti.h" #include "worker.h" #include "chirpfft.h" #include "analyzeFuncs.h" #include "analyzeReport.h" #include "filesys.h" #include "boinc_api.h" #ifdef __arm__ #include #endif #include "worker.h" using std::string; int verbose=1; // this gets called first on all platforms int common_init() { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("common_init()"); #endif #ifdef ALLOW_CFFT_FILE FILE* f; f = boinc_fopen(CFFT_FILENAME, "r"); if (f) { cfft_file = &debug_cfft_file[0]; fclose(f); } #endif #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } // Do this when start on a work unit for the first time. // Creates result header file. static int initialize_for_wu() { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("initialize_for_wu()"); #endif int retval = 0; FILE* f; string path; boinc_resolve_filename_s(OUTFILE_FILENAME, path); f = boinc_fopen(path.c_str(), "wb"); if (!f) SETIERROR(FOPEN_FAILED,"in initialize_for_wu()"); xml_indent(2); fprintf(f, "\n"); retval = seti_write_wu_header(f, 1); fclose(f); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return retval; } // parse input and state files // static int read_wu_state() { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("read_wu_state()"); #endif FILE* f; int retval=0; string path; FORCE_FRAME_POINTER; boinc_resolve_filename_s(WU_FILENAME, path); f = boinc_fopen(path.c_str(), "rb"); if (f) { #ifdef BOINC_APP_GRAPHICS if (sah_graphics) sprintf(sah_graphics->status, "Scanning data file\n"); #endif retval = seti_parse_wu(f, analysis_state); fclose(f); if (retval) SETIERROR(retval,"from seti_parse_wu() in read_wu_state()"); } else { char msg[1024]; sprintf(msg,"(%s) in read_wu_state() errno=%d\n",path.c_str(),errno); SETIERROR(FOPEN_FAILED,msg); } retval = seti_init_state(); if (retval) SETIERROR(retval,"from seti_init_state() in read_wu_state()"); #ifdef BOINC_APP_GRAPHICS if (sah_graphics) sprintf(sah_graphics->status, "Scanning state file.\n"); #endif if (boinc_file_exists(STATE_FILENAME)) { retval = parse_state_file(analysis_state); } else { retval = initialize_for_wu(); if (retval) SETIERROR(retval,"from initialize_for_wu() in read_wu_state()"); } boinc_fraction_done(progress*remaining+(1.0-remaining)*(1.0-remaining)); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } void worker() { int retval=0; run_stage=POSTINIT; FORCE_FRAME_POINTER; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("worker()"); #endif #if defined(__GNUC__) && defined (__i386__) __asm__ __volatile__ ("andl $-16, %esp"); #endif // Set up the FPU if necessary. #if 0 #ifdef __arm__ controlfp(0,0xc00000); #endif #endif try { retval = common_init(); if (retval) SETIERROR(retval,"from common_init() in worker()"); retval = read_wu_state(); if (retval) SETIERROR(retval,"from read_wu_state() in worker()"); retval = seti_do_work(); if (retval) SETIERROR(retval,"from seti_do_work() in worker()"); #if 0 //R: Set for PGO exit(retval); #else boinc_finish(retval); #endif } catch (seti_error e) { if (e == RESULT_OVERFLOW) { fprintf(stderr, "SETI@Home Informational message -9 result_overflow\n"); fprintf(stderr, "NOTE: The number of results detected equals the storage space allocated.\n"); final_report(); // add flop and signal counts progress=1; remaining=0; boinc_fraction_done(progress); checkpoint(true); // force a checkpoint #if 1 //R: set 0 for PGO logging test boinc_finish(0); #endif #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif exit(0); // an overflow is not an app error } else { e.print(); #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif exit(static_cast(e)); } } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } boinc-app-seti_8.00~svn3701.orig/client/spike.cpp0000644000175000017500000001310212643777667021635 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. #include "sah_config.h" #include #include #include #include #include #include #include #ifdef BOINC_APP_GRAPHICS #include "graphics2.h" #endif #include "util.h" #include "s_util.h" #include "analyze.h" #include "gaussfit.h" #include "seti.h" #include "chirpfft.h" #include "analyzeReport.h" #include "analyzePoT.h" #ifdef BOINC_APP_GRAPHICS #include "sah_gfx_main.h" #endif #include "../db/schema_master.h" int FindSpikes( float * fp_PowerSpectrum, int ul_NumDataPoints, int fft_num, SETI_WU_INFO& swi ) { #ifdef USE_MANUAL_CALLSTACK call_stack.enter("FindSpikes()"); #endif //int i, j, k, m, bin, retval; int i, j, k, m, retval, blksize; float temp, partial; //float total, MeanPower, spike_score; float total, MeanPower; SPIKE_INFO si; i = j = k = m = 0; total = 0.0f; blksize = UNSTDMAX(8, UNSTDMIN(pow2((unsigned int) sqrt((float) (ul_NumDataPoints / 32)) * 32), 512)); for(int b = 0; b < ul_NumDataPoints/blksize; b++) { partial = 0.0f; for(i = 0; i < blksize; i++) { partial += fp_PowerSpectrum[b*blksize+i]; } total += partial; } MeanPower = total / ul_NumDataPoints; // Here we extract the spikes_to_report highest power events, // outputing them as we go. // Index usage: // i : walk power spectrum us_NumToReport times // j : walks power spectrum for each i // k : marks current high power candidate while j walks on // m : marks the current tail of the high power hit "list" for (i = 0; i < swi.analysis_cfg.spikes_per_spectrum; i++) { temp = 0.0; // Walk the array, looking for the first/next highest power. // Start j at 1, in order to skip the DC (ie 0) bin. // NOTE: this is a simple scan for high powers. Nice and fast // for a very low i. If i is substantial, this code should be // replaced with an index (q)sort. Do *not* sort the power // spectrum itself in place - it's used elsewhere. for (j = 1; j < ul_NumDataPoints; j++) { if (fp_PowerSpectrum[j] > temp) { if (fp_PowerSpectrum[j] < fp_PowerSpectrum[m] || m == 0) { temp = fp_PowerSpectrum[j]; k = j; } } } // temp now = first/next highest power and k = it's bin number m = k; // save the "lowest" highest. // spike info si.s.peak_power = temp/MeanPower; si.s.mean_power = 1.0; si.bin = k; si.fft_ind = fft_num; si.s.chirp_rate = ChirpFftPairs[analysis_state.icfft].ChirpRate; si.s.fft_len = ChirpFftPairs[analysis_state.icfft].FftLen; si.s.freq = cnvt_bin_hz(si.bin, si.s.fft_len); double t_offset=((double)si.fft_ind+0.5)*(double)si.s.fft_len/ swi.subband_sample_rate; si.s.detection_freq=calc_detection_freq(si.s.freq,si.s.chirp_rate,t_offset); si.s.time = swi.time_recorded + t_offset / 86400.0; time_to_ra_dec(si.s.time, &si.s.ra, &si.s.decl); // Score used for "best of" and graphics. si.score = si.s.peak_power / SPIKE_SCORE_HIGH; si.score = si.score > 0.0 ? log10(si.score) : -12.0; // if best_spike.s.fft_len == 0, there is not yet a first spike if (si.score > best_spike->score || best_spike->s.fft_len == 0) { *best_spike = si; if(verbose>=2){ fprintf(stderr,"New best spike:score:%.5g, power: %.5g, index=%d, fft_len=%d, ifft=%d,icfft=%d\n", si.score,si.s.peak_power,si.bin,si.s.fft_len,si.fft_ind,analysis_state.icfft); } #ifdef BOINC_APP_GRAPHICS if (!nographics()) sah_graphics->si.copy(&si); #endif } // Report a signal if it excceeds threshold. if (si.s.peak_power > (swi.analysis_cfg.spike_thresh)) { if(verbose>=1){ int fft=(si.s.fft_len>1024)?(si.s.fft_len/1024):(si.s.fft_len); char symbol=(si.s.fft_len>1024)?('k'):(' '); fprintf(stderr,"Spike: peak=%.7g, time=%.4g, d_freq=%.12g, chirp=%.5g, fft_len=%d%c\n", si.s.peak_power,(si.s.time-swi.time_recorded)*86400,si.s.detection_freq,si.s.chirp_rate,fft,symbol); } retval = result_spike(si); if (retval) SETIERROR(retval,"from result_spike()"); } } #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return 0; } boinc-app-seti_8.00~svn3701.orig/client/gdata.cpp0000644000175000017500000000760612313644616021573 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. #include "sah_config.h" #include #include "seti.h" #include "gdata.h" // in each case, see if the signal being copied is the same // as what's already there, and return if so. // This prevents the dirty flag from being set spuriously // void G_TRIPLET_INFO::copy(TRIPLET_INFO * ti, bool ib) { int i; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("G_TRIPLET_INFO::copy()"); #endif if (peak_power==ti->t.peak_power && period==ti->t.period) { #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return; } peak_power = ti->t.peak_power; period = ti->t.period; tpotind0_0 = ti->tpotind0_0; tpotind0_1 = ti->tpotind0_1; tpotind1_0 = ti->tpotind1_0; tpotind1_1 = ti->tpotind1_1; tpotind2_0 = ti->tpotind2_0; tpotind2_1 = ti->tpotind2_1; for (i=0; ipot_max[i]; } for (i=0; ipot_min[i]; } dirty = true; is_best = ib; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } void G_PULSE_INFO::copy(PULSE_INFO * pi, bool ib) { int i; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("G_PULSE_INFO::copy()"); #endif if (score==pi->score && peak_power==pi->p.peak_power) { #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return; } peak_power = pi->p.peak_power; period = pi->p.period; score = pi->score; for (i=0; ipot_max[i]; } //for (i=0; ipot_min[i]; //} dirty = true; is_best = ib; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } void G_GAUSS_INFO::copy(GAUSS_INFO * gi, bool ib) { size_t i; #ifdef USE_MANUAL_CALLSTACK call_stack.enter("G_GAUSS_INFO::copy()"); #endif if (score==gi->score && chisqr==gi->g.chisqr) { #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif return; } score = gi->score; peak_power = gi->g.peak_power; mean_power = gi->g.mean_power; chisqr = gi->g.chisqr; sigma = gi->g.sigma; fft_ind = gi->fft_ind; for (i=0; ig.pot.size(),static_cast(GAUSS_POT_LEN)); i++) { pot[i] = gi->g.pot[i]; } dirty = true; is_best = ib; #ifdef USE_MANUAL_CALLSTACK call_stack.exit(); #endif } void G_SPIKE_INFO::copy(SPIKE_INFO * si, bool ib) { } void G_AUTOCORR_INFO::copy(AUTOCORR_INFO * si, bool ib) { } boinc-app-seti_8.00~svn3701.orig/client/x86_64_graphics_link0000644000175000017500000000246312633676374023574 0ustar locutuslocutus g++ -g -Wall -I/usr/local/include -static-libgcc -g -Wall -I/usr/local/include -I/usr/include -I/usr/include/openssl -DHAVE_CONFIG_H -DTEXT_UI -DNDEBUG -DCLIENT -I../db -I../client -I../client/win_build -I/home/korpela/build/x86_64-linux/boinc -I/home/korpela/build/x86_64-linux/boinc/api -I/home/korpela/build/x86_64-linux/boinc/lib -I/home/korpela/build/x86_64-linux/boinc/sched -I/home/korpela/build/x86_64-linux/boinc/db -I/home/korpela/build/x86_64-linux/boinc/clientgui/mac -pthread -msse2 -mfpmath=sse -DUSE_SSE -DUSE_SSE2 -I/usr/ -g -Wall -I/usr/local/include -I/usr/include -I/usr/include/openssl -o seti_graphics seti_graphics-timecvt.o seti_graphics-sah_gfx.o seti_graphics-sah_gfx_base.o seti_graphics-graphics_main.o seti_graphics-sah_version.o -pthread -L/usr/local/lib -L/usr/lib64 -L/home/korpela/build/x86_64-linux/boinc/api -L/home/korpela/build/x86_64-linux/boinc/lib /usr/lib/gcc/x86_64-redhat-linux/4.4.7/libstdc++.a /home/korpela/build/x86_64-linux/boinc/api/.libs/libboinc_graphics2.a /usr/lib64/libglut.so /usr/lib64/libGLU.so /usr/lib64/libGL.so /usr/lib64/libjpeg.a /home/korpela/build/x86_64-linux/boinc/api/.libs/libboinc_api.a /home/korpela/build/x86_64-linux/boinc/lib/.libs/libboinc.a /lib64/libssl.a /lib64/libcrypto.a -pthread /usr/lib/gcc/x86_64-redhat-linux/4.4.7/libstdc++.a /usr/lib64/libm.a boinc-app-seti_8.00~svn3701.orig/client/graphics_main.cpp0000644000175000017500000000331111121020024023255 0ustar locutuslocutus// Berkeley Open Infrastructure for Network Computing // http://boinc.berkeley.edu // Copyright (C) 2005 University of California // // This is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; // either version 2.1 of the License, or (at your option) any later version. // // This software 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 Lesser General Public License for more details. // // To view the GNU Lesser General Public License visit // http://www.gnu.org/copyleft/lesser.html // or write to the Free Software Foundation, Inc., // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // Example graphics application, paired with uc2.C // This demonstrates: // - using shared memory to communicate with the worker app // - reading XML preferences by which users can customize graphics // (in this case, select colors) // - handle mouse input (in this case, to zoom and rotate) // - draw text and 3D objects using OpenGL #ifdef _WIN32 #include "boinc_win.h" #else #include #include #endif #include "boinc_api.h" #include "graphics2.h" #include "diagnostics.h" #include "sah_gfx.h" SAH_GRAPHICS sah_graphics; APP_INIT_DATA sah_aid; int main(int argc, char** argv) { boinc_init_graphics_diagnostics(BOINC_DIAG_DEFAULTS); boinc_parse_init_data_file(); boinc_get_init_data(sah_aid); if (sah_aid.project_preferences) { sah_graphics.parse_project_prefs(sah_aid.project_preferences); } boinc_graphics_loop(argc, argv); } boinc-app-seti_8.00~svn3701.orig/client/test_workunits/0000755000175000017500000000000013155506307023101 5ustar locutuslocutusboinc-app-seti_8.00~svn3701.orig/client/test_workunits/sponsor_bkg0000755000175000017500000127025012640260573025364 0ustar locutuslocutusJFIF,,ExifMM*bj(1%r2i-ƺ'-ƺ'Adobe Photoshop Elements 8.0 Windows2015:12:27 12:00:55w&.(6KHHJFIFHH Adobe_CMAdobed            ~" ?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?I2iA+H?^IvI L )GkO?'sGp$$u <.N5 OGM+ZC\ph@'U:{G%SщTʉ>Iv3Xz~t8?CPRñNAB`0k3G x(g |51|;rIIOgS$t4N'IJHh<̤u{RGIPWx~U+}؟ɢTʢF'_> up߉ $B *DQP|N$8&7qEu4GE4BoU%E'Bݯr8ESq=4I-r|#*{KʋOr;E Pk$QRh4$7RaiIy H|BJ%4 '$ (Jn|GP>Z9(V|)%0: C꘤R9 :OO| ݘRh8π##U 9QX kZ ' 4Q?Na4芟t锴QCN #_NϊaȏS(̦p!߹3MlŧuLL9Dr> D'䊗Ig;i!?4^{{VFדnlTOԺ wCN?4ݏ* *Photoshop 3.08BIM%8BIM++8BIM&?8BIM 8BIM8BIM 8BIM' 8BIMH/fflff/ff2Z5-8BIMp8BIM@@8BIM8BIM=wbackwnullboundsObjcRct1Top longLeftlongBtomlongRghtlongwslicesVlLsObjcslicesliceIDlonggroupIDlongoriginenum ESliceOrigin autoGeneratedTypeenum ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlongRghtlongwurlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT horzAlignenumESliceHorzAligndefault vertAlignenumESliceVertAligndefault bgColorTypeenumESliceBGColorTypeNone topOutsetlong leftOutsetlong bottomOutsetlong rightOutsetlong8BIM( ?8BIM8BIM g~@KJFIFHH Adobe_CMAdobed            ~" ?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?I2iA+H?^IvI L )GkO?'sGp$$u <.N5 OGM+ZC\ph@'U:{G%SщTʉ>Iv3Xz~t8?CPRñNAB`0k3G x(g |51|;rIIOgS$t4N'IJHh<̤u{RGIPWx~U+}؟ɢTʢF'_> up߉ $B *DQP|N$8&7qEu4GE4BoU%E'Bݯr8ESq=4I-r|#*{KʋOr;E Pk$QRh4$7RaiIy H|BJ%4 '$ (Jn|GP>Z9(V|)%0: C꘤R9 :OO| ݘRh8π##U 9QX kZ ' 4Q?Na4芟t锴QCN #_NϊaȏS(̦p!߹3MlŧuLL9Dr> D'䊗Ig;i!?4^{{VFדnlTOԺ wCN?4ݏ*8BIM!yAdobe Photoshop ElementsAdobe Photoshop Elements 8.08BIMhttp://ns.adobe.com/xap/1.0/ XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmAdobed        ""   w  s!1AQa"q2B#R3b$r%C4Scs5D'6Tdt& EFVU(eufv7GWgw8HXhx)9IYiy*:JZjzm!1AQa"q2#BRbr3$4CS%cs5DT &6E'dtU7()󄔤euFVfvGWgw8HXhx9IYiy*:JZjz ?ȪW103(:-F*8Q%BWƘ'RmAZ (C <~>HZ[s!;GTVH78ִ\zz Jُ0Gm!˲pZ]ʢbFjKI狏:vp~ yMRE`ңJv8Nbꃡ7a,f||R4 ՑU O^$S*l&RH ]pxa!-E `,n>(Mid<#+EI^m'r8K$P F;{B.&H@ 䟋8YJNhʞ?˶1TDGmc-rVV kUE[ )$)xi'1\tu$GUW DjZxщ0?aE6$$nF MyhƟgߎ59PccP WO6Vjn8ڜZ7=}m 7*䖮` +PHqG\*Dqa]d&T d _^dC"P1U@YZLy*n5bzt8P(oZScMiVqU m 2@B1ᵥT?#[RP<{t$SǡeUྡ N?de2Vƕc3P)$@OM,v۷1PܛGߐ #^k1Sx9 $t?t|!L # + B0m5 S KI@{?4~`׷ ڐ3PWƸXt…i KqmSݹ&U#c\O%nާ^ǿߐ!*c+Q%)0w) orGJ(ĞjCΔ-!C:L YMcX% ]W|›vR=5ȠC \H%T&+ANmԷa:dڢĄrј$[")#_-kj?K}Q@;+% #?#m0{䘮SЊDbT,yc -7#Rʇ$_1ېN \.6E:S*-#/)dY1bV,IdnF9",xvREEN-A߀~X@RSM*0- [_|zGwV|䘢$vhHۧslf7*jxP.xIՌ%1_Ue61lRi*qVlqW* ⫣j=WMcWJyGJ Ui4bUcvkCڏlWȐ녋^ \ )I m T)]boW70+EF6U>dT ⪕hzV7MpUrbRhO!Z}q튴zoҸUuсVw$d 5ΫFI i*nBUQaN;Shb_ՊWD8V ,^$ Ul<쓷ʻbQ0F&'d D;7Ŋj]QU񚱯d\b(׊F/>$]%ɩӄlVvAh~ QVAHkڨz`^JUbɱ݅4AaRIݐ+XR슎FIL&8#r!y;_S$FxSk d Ԣ Tg4J%sT|pUGZՇ7.įcKUIM( x{VOmzq_UxHe)7h-T21-h.TݾM*RV>TL :,`%V}K  C8+~Jkirv4<)$7O ,ZR͂覭 ԥZ\%dõ\[G# wT"w*M./J?/zb>.ǚG 6dIdCµ,P%Z^qā+|zx`[q5?FTErD!ni+N-FrEF;Uѹ(*:(_7q[m܂`5ZT6[RBE_0"}U wx Hkź׎(D%@Aދ*Ƒ!R,- AcGJ4V4&$)^ю+O֚*y qRM5BVjӠJcv^>'6P $ Z݂h+5?P-nRJ#rAR:„G HY7|$<ԩȥZ~,DS` rW\/+߮H1*^x_peHԥ{BnDd52zWyG<ljpV*I@R!pfJ*{6+T;<*9.!%@$*PS 2Q$- ґv-uISSf]{x䕨G〤4M*aO H܋$m ~UǦWûebN192HnGp~ר$LJ{PJI ?ݟn PA;ԏ i@kb=>}Wx{\)UDӈNت0퀥?~.RiB\1UVC\Uy.4WzPV9|5¼~G]QmIIS$Ԩg~bl |!R6I4F?w`!(TrYߓ}) QkJUsOh;kJ~1:VIn8UMHQP}0+<:e_ĵznJ'e:UFAďZV2X!r? 'r?\(C8PC=6L;ꀕEhjO7J`"I֊ %̔$  0 ծ V@9+N&-,j̼#)Cr2%n>+H>$h:H(@OLx;5;*8n܇? U~b Q&/҇ ǦGKlzt !pMH#7 -#Z]yn Tc4p}8'pE)Oኦ6|e"+փ|{BNu>{aBZ8ӿdدQPS,=:TF ^=0bEnI6n^,+Ǔ5۶aU˸68;W0Rmsѓ?174&bjF43V(l%)(yU W'Ѥ@1[{ML!J$;ȡ&ƃJ& -Qڐ۶vDOsJiJ#Tu7UQHC~dT\r<(Y.GSK^kz1P )^[kH߮P@;r)VCZcȥ늵B'a5=ym_鄤"W,kx?-v8W|kU-*)ʟ zb[ޙ\V sLi# BːwpF0! ?k_¨ihT/B tتP3@ IUIH*kJž=qtSPl( PMqU;[|?*+p+Q^n~C$%<^P0)ЀwȄƁ5? p@ǯс+x4FqT8<;1TCEVFNW.9$ aB~x- :߶4MUOD)\$Ҁ1qT 4 zeEQ6`)mC`JNZ"zJJ漖ª ŸpB@gH HGsWшVO_dL 55 I(pjd/;*j]zKmCN8Uc(_DJUQW}P)6Z1JiC7'Eu[$aPԓ_&+`*jW`d;՟B?PS6EYV§F, B HAڴ+%.X*܊0s[$4 CHn'!d !_$ NDv[ w'Rڲp|``*hrTڽJiR>[v[^VzxAޘBR ' h /'S-)L.{CR0H*k`d터 lJB:SD;<Vb$Էbjj"Et469&)Hozu_Cm$`s(E,~_͑njGZ*FET$X7(=C.ح ^|*U  -8jv#kW֍U 3OՑ8 G㐟6d: Pv V^ءTnjx큗4TkJPHjI%Ӓ¾8U)JJNB-.0 7 Jǫ7#N*j} (Ɨ'*} D&7ruQ; ܭ*!a8g WE, Xӹ/bT]GHȡ"p4v*6%SJ9 )S߄QMU&?yWGU Rhʪ ­`:b[F[j+]M#W@YՑJVnI[ zԀ~*|p%F1$Ď$v8CUkhB<+Bz1$Z^IQOZOါS Wnզ*5`c_L*!TZ0ZUo"W;Sax:dď >%߹Î*XVq%@T.xWHJ…Ɲa4Z?sƴIJ!}<2lrW2'fAP BFG!U-jqFbܫOiAJ$cV?OJbo u܏_)]$++b/´; <7RS33ir̨FO'L-3Oت_m)^w`*%\UUc]bĨQH(:JdAlBOR(+ȃmU&5H>zSF 9QJӽvm8|JExj~$iU,6q)RHc UOh=FXIR\^Zo l7]` ] 4%eؕ^did;nw6!JαsV=)iV|A늪+qNml ZOPzbKYJ尦$W?#.~RӂI tڸӲͅ 'l1n f*H׭L@)tɰiiQ~@ҵ`YXiI?T|!VLRPWl:u8HiW`5LPpQlPT2)K.Mp&k 6ab815l7lPm*tV5­xU8XaGF0$($ ZwWSbPaEȲk *Rq!+U|*|X ZZNN9qUh>qۧ϶D-cw[AR[HXĪ7ʊ,2q+\qk *7ۦĄBT rL ;O,.8*#"~|܌K\9oӦ*Ν#? RG%.z|cԧюGL T•A>ڿK]q Gx| UYA~AFAN[?R29enEDl2 J[ *^? qWP;ӵ|0+|A\xiڙ`bU A]~*NK) R9ݎBya(f#b wrb`ⒻƸimBywE_|(ju!VJ A~mCZ1Vh7TS\dj  q=}Vy޼?v)m`u>)-@ :EFtC}*;!H1 Z;!+K墪젟S8'D*w$e`3%TZPmvrQ_׀h'Jbd em(PbJdW9d0$x| h@=* EcGPԈTu$}'Qj@@ӄ W* =QS%)۾%P.=]zPb81VB~59"Z T>F5ҴP|X"c5$E'>X Yrز ToqJ9{q =aꎎ GQNF*UU4QFUbcɉ]!Gmn]G>LG$u_nHFAՀRo%ԡeȟ0h"Z=ZSa BBA8X_?GZ>ĨW'!eJ= JaU`X1U"8P μF'zK»CCC‚ G+;*х? 16R/ s4;#d&kQ(WH)Jdm,SwqUo*_q3W#,jcN"N6Zvz("E?gc{mĚ TSCZ'6%I[#u:`J …QApZUm@Tʻ_zAm+҃` E+ QB&*ӵ>߯®ъb=p%5ߠ8[wik.24(l b5m5LU.)[bbO;7'@(1CM uIS9$6;dNܙP1T *ju;wpZ*Sw,R (<(^'*w+e[wOT{rbOA x*l}Bl11KU 6v4wHig݉'W( AuȑlR!zW*7^U>ү>ءs*\=*€6<wPF*|C[~ت8UQ *G#}8P3kpk"Mp!YC ؔ+*.o V*R~K4pǢ~IR7b:oE΁޸T,5jLznHFL4Keª"i3xNԒq[,o8Pڊzu([_PĪ{GӈbB٪%9}H Uȯu4WcZCǶ+oWHhF!V̼d+Q]C) ' R LbJ?z8 |`"KdtCE-W>WQHĄZ @8-*ṫW僒4*) UDL*׶nqIVvzBΜ R7zĠ*+P:xHix/-)[HH[8SV,R>\AU.MPN]o8RM)ဤ+E.0jl _+UuLҺ1l8G⨈C;P$Q=LAVFiGn;DX^SKixO*U%G5UUJJ?)b+#0bC ؑ]anAؕ U9JPup*LBBy^RCq悫±8~Q& ywdPbkBlH=鄅UE#SȪ5 j'넅"b#pv?,!#JT8M4`Gm*O^ĀTCoƛoA!%g: TҝUߵ*t^q()Sv+_  鷆*(6X-H"ZO|y&S)U? *+1m aGEs\df j>{ora6xaT~ooo4f٪5A/J}0\UⁿP#WqV<`J&\>d x9 £瓶4R(קL Fzmㄨ*7,q@2#tI9@U[pL{^KH=W" $h^kbUT"Rp'Ԛą Zn )AGi*p* ۾A>gi&nPB;@fJ?VLZW 6W!-h8JP~9HFFXʥ+|TK csu`G:ue  L,UٔTyW#՗E*UPgb0J n+RR@ '9$hk)&گXPSY:Cя4rRxXI g JbdckNq$&P|R Uզp>)lt8[[\U트SLm&ITM{W]e.5m^$6 cVMܱMp+访OU~V ]Zt†jpv*኶Mp+@W~UCb)l1\ X1Wq'q+t-"^늵\(md$j@b_B&a m_ʅ톩 _ScZ|*ICҕ 5~/\TBb ؊}Xcspwhn8UVjAa5?#dؔEP`FW#NɴTHcJs!)''2#?M1UTT([e9 >}5Zi!Z(+7#$vȷJqB$h}"'%B"KF~V@7=Q`DޢA5R Z$z,|q ZBb0]N ZOcLUt|e-WP1!(=HS5c\( Ќ rֵ/-vߋUoRÞ=4|Тx1>8UMPjx7 kB *GbHu(s*jl|HZ)]ޘ{T⫕z (ǦaEAS ibl5HӿJ)$@2)}*;0h[yXG}Y"ǑEME:B镓;P`ӧ~]H,ZqąSiӁ= ,1UB[a%'jy$/5&xlJ.R8n*xCZoZ~Y+ v&K)A;|8% zl}hi#|(p=UI8Q=W"$qg!* S1PH*$\6$N7ª+ZMĨTFqӭt4QB4c&߷O!a^mhD$`2A FGo_μbn'j-Je.bh0JV0C<veP )P< ȫֆ-JMR\NZN>MH2S1 dIɰ^]KpUzRȞi详\=T7$j1B1XūMW2(nUg_EwdL>9&.8*| ~9ZId`V|Ui_*rz > m؜B8P⫘0Z{*鿆)jwo 5䰊uZlR)T Wk \+֘K?|J(ܻ *6†ȥl%"l>+z[)fʣ c q(S.d8EjȩPڇnY $ЕB9 8B#ᎃ`X}\*9W1KlPֽB(z)Q!ɨd\QZ@_ cN{SKBqU66d Ǩ']rǑqA2&Bb6=1dSnpqIr1DW Mzxtij)cJ5@Mܟ>ҒB +h<.xӐIl6TdUuq `ZREzm\IKr(Qn7G%< $=Bm݊)nXVZ :Jӷl4K!OkJ ע_"DZ~XJ-sL p>P!%V!@wx`*k_$bpP#CT/5=H[.5P@ni}Âǎ”J׍OӅ SJS Wt?WTG?F*T-st9)nmAF W+Ƨhw$* R=>oWARu'5g"I'U+^G`JMB܊pBj@)j?"R5UxC$STu܊A1KꎫSD;mJW|(Q@7QƟN",x$ G&؎P; S኷q،O$?'|B .GpG*)jָB\v_WZx<*CXPeE!nCq&~m]]P2{bUb71^W?mPN -FjݒbW.TF%B"RO OpXђzmQ_TYՂJ-x<*TҬߵ&Y!,w% &JJ&E6"p$).?`˫r1f^\(dͷԏ5G|FwqB7i…H:U55 +S@mS NdCTm@'|hҧqjmAnZ_)]̇T۶I5`V`TԔo `KGv*G q Ri8t*A;*R8Ms~)6P5Fj+S!XpU0m(0k[ ȥiP㊵ |qJaBӊ*E+8-4‡V u6‡\ ?pb%VBP`/RN]pV*U<AXErHjCWr\(pL(qр$z\ƀw V`ptMUh}V. K)Ei] CѕShQV$!З(K)Kyׯ6#Iٮ4!tF$Ra;W,OX+ƿF|4+.Hh'BWq+ڤnWxǚ_T%U# $=r$ -t€Hn-#KT=OO!O{Jp>$oQLΝ8Op) UxTYr!Jgl89ag>|qe"P*m/>W1<" TCw9&%sJB6T*QԟaJB>P "qr@|q.T ^ۏ.BZiڇ|*g l8S-JA_Ӯ1-_PǷ|U% E?--$؀>fp*'JB$ +Qd(@)cBmCE|? HcW " PJɼ+8j2U u{|Uf9ąSr$5b` $ =rE @N7d*NB**:Ӧm1CTHSJHA߷\lP^J J8QzJf]޽H_r_u/!Tc@: BJѱڻ*h$hpi<⦠bT".iř̡m3Q|2l+q$u/)5 B%ZZ|(]$@#jkWJÂ/k}ܵFA*W1F@Nˊ8<26a?Uh>8Xcޘ-icFF;W<1*$Pإ">ok62%@Tpuds,;a*l) +BG0O]0%cRQ%^A7n ֘lىYS!.8fAYE!^?r@*G"P_r g=Ux7qƸPƾ=B;wQVHp Px֙QP)q@D n,b*jFLI c߰+q^M]p W܍ U-W~-G:P`oU+w`˲8&Ihp~8.J xЏ W&$֔p~T DMoE TOȉ2! 2lyji ͳ`d녊<#՗0Г$PnhC, 2)]_Mx22*Sl#kR6*Hj} ,@Q#2lQ 0Gbk!+$Û):+(iEFG#nB%!O\_=]Č$NE$.E{`M ~gWۚmV * `JÅ]| \/aBV`$-".=p%l)hm|(m(u)^تbbwLU}Vǎ(h4ֿ[g =Jm4v'v&+kiekL(k⫈+Uª"^_1 ] -b}G*Z\qW=*z84^ݰUZ#mܐ 6i〤5Zo xîp®lPj}ĨlF\ XrH^| K M#oV$↽k@`K`lp7z4[h$-L]jpN=[TC`R]vy.LtRad:7ԇdrrT~pOy^0t$GfFZRlv|ڑKToA1mV 26j{rtMݣ\Ji1B|prJ䳖=0\S/IR)Lv*-=E\w? k]ت uC U#nMu8C 4oq%鞠ǹe|\*{)@ bėQim>z R4\B1? ,*2g-@`I?*YZ8P/#+Zpqڧ=1d )V&%iJIUU,>GLP-K65J)HUOPw?l%@ |LUjuȥM;xQ6`=kOWHDV4kbT,R+q4+\(\LsRncKY@ÉpYG*cu2኎@<«n U!JVu;pYlTR(Oj?v?IF7$%LO߇m* Sb{ BFT*zd B"%SldTxAژ@AlEqV q oJ$nuV6)ѲtǚA}q V(bb {T:Ql`Wz d@I[BH \=1*!{wk"8(n1SAq) >X+qkLJ*}miy2 I3>k%c]a+ZV UZf t,%d1w넔V8+nl$PMخ+b݆sзIMF⢥2 rʩJ` *1 "ԯo٤ u; DA׀,ebz m T'qNG{Jȟ"BCmBp޸m HP2=5ˉ۠H0!Ȃ?”LJ42$oA´Z<+bLr;FLrAs45 PݽBaU5`*ƕZӨƣ %MsE0G6Ě@kdBTMH޹S=Sl7Ǫ2nh3N!Z9ݠ#y\UN? U8`m3 "NRx+6 VN*~y8v=rJ?@Z>Ǻ#rRcoDT9&U΂x ]=wʏ6Yp-L# P9c~GBlrJYiO'q^ːr.ZF RIG=zwbQڋ^"$䊅Т1l*H]#mň\!%[B_oJ`y7R5H<*5N8PjܔӽE.ILrhiPTQI('F{MAo$Ρ7M)_NLo*p HiM"O5]5l(nHc۠VH%9aV\ITʽ|;|H]gzݱhiO|a̞q#qAn[muFW#OM jN?FV>l_ӓBۊ?F**O#QP6H&'۠hrNSJӁiZ`&˅iiO)ZI#s[f2)tS䘬  4PJ?'0b@ׯс- y9-q CaK5`z*A\=H|p"J(HF/ {U*~C"Y;bDZ[m\OՊH ;Ul64ǚTv ^?mRPtX~8POĵtԩŔjg$K+v ~Z՝f=T !Jƕ5c1AQ }_eMJ#ccDU|_F!Tϱī=)]=Ġ/̲]+Sژpz !^NghFJ %b:V,1C}1[Z=2&`!B91)_* t`kJZQCJ6oQe{7ȀT5uy6 ڏp(r!](^4G+%L8>塬z Tlz'$ EM`"#mHC",`F%B@MbAċ@4-Rh܇ >$-\˽X5h[Vo\G&J'*4 W#\54( ب/cYW2aI'1 jWdaU1h*~xI'Ц*Q׺U1Y(_9 T)HJ`'J2&\\uW>Ȟi!$P`iB~`( a<zB]ޢ Cp2lW~x)NqBp;l,Q82q,_pYR[RB|raZy1wpIKglUmNtjjz`du†*iZVs`JCC2G_6\F-ƜM$ nZ)0+I R8iuK{aCL{`KCl**(v)\1C')Gݰ_#I!{:낓k0hb1WUr *V,j|0%bG"WNiW@\>|!t>OC*+W})iKo+Dbu]]W*P~ jPUp;UZZWFdXv#dx>׎ly4RCLUuwf !î*F(-xj[W02 J#j'W+mWVFHe5DEN!7'<ݠ۰‹L4e1FAvp+=)䅀p&#"Ka roj W&Nۏ&9ϒ#\?\JT{RvAux⪪V)]imy䴀wl7Ȗ@-Q˾8 ͸V*^Sv* dpۡ D[r5Ĕe?:׾ [Ti A&:bZlHJM'?`D&ڴeK9"6`ޖ 2 ˢ{uU|R3R6) wf#no45ç| MH45 lWA-!JU@0֜n 9#PLJxM@"Q {B3Iwl SRgn* ~,Up~ ǷJ%7n#\JipЯlArB:;{6LDrQ?BJՐS~7O$cIZwmꀅ G| D4= RTۈ߿JD+w,ƕ8Nh5QޘXDO_ a Jj|'h tJm!! iO-Mk% pbPݕܬ.a"JĨUUZЍJ hGAN+E6M7{b|.g2>"*$.޻psdG TbUhj}LUrF%CHԡ,J'1|Rntju-GփzP5I:}ӊR1*9VF…{i}%#b8jj qKg{$:LBKmRifr]X[ZzwmzE@^@, ݰ+$]TOч:9 UK %k58"b|rڕ%V6rW$[eW ў#m'-olU97'@Ol%C Wz6e< >RJޣGݓ`TbǓ>m bQQD$ߕQW2|niUVӀ$ _aB#,źs|FybRCڣ @D $G@wǒe}9l|($nȥ+VNR'{Hm=i8Puk-t*Xz`*J팂z i G?,O6۔J% RZ޴އƙU3%Bs'#A=@1=ʓj TrJJaN\PHaI(YGGlB'LJT;r2,* 3geoZE?+(So:M"92<ڈ !vR>Jރ状 ;O- UUmFhKC4OnT «WW8+ li+5J`KdYWr\G*]Qa#=0ZiE1 C)[[b늸{CzUVČE>>$lgS31R{}\ &qWSj«zS"M2MsBZ\7늹k^R8P1Wb֧qnVuI:E \!7ֵXܚ$n?{"@#$ߦbQ켓i` D^]G,+Ԗ> $%ҤWT""ZqO J#<Ij |Aj0ZQҞڡ]@vߦEEwRޥ(VQKeWZVuS#qJ:ةW$tz5'Wo k 6_Sd..Z8.M4O5S6텊z $~UP*ۚ5~l;*Oθ sJa [R9 хku?⮅y0 HRZ9$8nqM&졣Ǣ,uԕ\*Y' GI/7MJ#"6AX([B G*J ?]CPpx#h*FV㇪B5u5'hB.5-{9+$ PVJ. US *l T +a߭6QPۊ|pr#}2LVJ!YNԠ=pn~ cz…X)1#`. b& t2 2%KkdحPP1!^JԑrAYZ ذZ9+ϩEGʫ;S2hhbۭ<6[p3Z'k8*Jӹdm+baƖx7=jE5lPF˥;P`ISP8;CD oqۧ\Uܫ(0KCq]1Udj](śp׮6}%$tP- &#'ɯ0 ö*bzO "??3bW,{WFIWH?(#p9NJk+ۮ Xv;`J;䐾=؟ȥ`%c߾]Up^;JwېLdTH]G2a Gp;bRn} [,Gރ6cB*1 ZaV4Us=FkZF,vaUY xL Rf]xBef;;lV&PTDoN"cڵjȲD1<^ۧBoŏbj0+p5 ~O|@RENۮ*y\1 VEd3PWq| M)޵HPopF¸BV[ r-I 0*CICBJ*HuVI> )R]2Lfӭ1WFMk4?d {P^ +iU'凪RjP-TW`z( |DP;󿩵)vŴH[ t늯@kCMR†b&2$S mm(*{E-:b58]>xUp|qW\U7*w[b])L>n/{i/'߮I*8U.†4p%DYqy8m ?|E۽<}- Nxxy.=2N&[Rj$ iAEV_H xRv ]UYb<L Tv(A\r4 B峓3 4䣠\U`]Uum <2*DR%fX? * WE%6 ,HG^"wݝRo0`I rTW܉d6S Yn?x1PxzLiVUBMZS UzCgq >X[G*Wxz}6Īau!me`n̛7[a|JЕnCO+bmU2Ojzz)Jkካ'q+=A#$(SDO;7I#V3%Cz,Zu…z* Ps\/iKx rdʁݸ ^B3HvZqCL,T@S}qJ9);xׯzd/=G-=GFнpGJ<ii; Ȳ[ECkomyw$cp@+MdEB 5Tm)h†\ qw[yb)+qCdZ6Fh*)k(\Mzq*i9}Uuxt_V0bw^UqVbu[VWb(߯$֪?%O =+] *߮v(qW7jO\U*8* Hhxbኯj)UI5T.F*ZWUUmo!'m*,ZE;aBضzbڸ.'nqR*zu8. 7#$ Gg`h)Z0ƞ$PQ-zCX N߫"y#ˍ:S`' "cǐ0*M;!G6'$F1xȧYF*EڹlO57=ф+Aw0%i58PjRd^~/q-SbeF(<~eBoB?~E#䘔Zt2P`:/RFn ($!ǦIm-_V*JFXҟNIPP Vq `8Њp%4ufTW MT֊O㐒B!={ ~%(CmBN…s;` -sҘaVڀ´VBZ U0Zl,Jrg"JB*GIR OjȲEH&X"cB{r# !?^XIW}6Ħty1ez7-r,HdO}VtH*v/d49Pw#$^Yz"k&qʧ¹*Bh*~ xbFej* +$mɦdVP%c<"!JU&b_#"k֙$5¿F6D=>|*VȄ"閰\Gi"G) +_fB:`V (ZW\1Ku?zW!(j>x\Xq 2;ɖ!| y'{. 6$),(\eQ Rmk|)8Us ITʗ5GBQJ(lR HnSZ; XK(~ 6 Q:⨹neQ]ȍwB1ة0l| nFvmޔ qU0h6W'Uj w|U(wQRP5>C# ![د+` U]*$u@>-@Ұ1LKV# .=N*0c^/$tEEŹ#*Lra"xQ${p5 ېGqreѱPAa( H; lG%*Y`,_v- 'އ\x)Q"N|U®qBܑb[d¶"݁-*&tT+̪CkC7L? [ &780ZV=,U;F"d!W c "UŽ#ZF tqWGZ GOn)~*A9d6hU'c]bd WVMM#źvIQF$X8D2()6!`b1" I7N9̥QE9Wr|V^P` [L*₾5 Uij SI0M5##j8(\zJuzrl\w.;b(j=CvqVUqj]튣-o7N<mMw1R7\qKqV ثDW ڞ8ێↀت2ĎݡYnAS,`1iq9*dPz枘V'lP=%pC}KxaC`K^UsZ\1Vt[am]Pn8" ~U*WȄ4 v@x`" 6 (BqK\w#b qVÊ-MON_ʟ<7Ӡ)k[^V?;WuŪcM(#[`%iڪ> ԃbBU[vH*ŒؾǯS;1KێDS i^7IR ]}En(p(<0'e𲫂)yGђ JݱJ;Uʿm~ثuO !#op QTU[?,J# Oz?ɵL$ Dz8YoV X#`HVڥT{}ي=%*q_ኴ`uk zr«!caBFf'0!/ )+j jxJβB*#EmE$$ָPa^?N@Ҧ̑*M=$Jp2E[DjLUpJ%!Q=qAoB0H+ɍ9l UVq%I.C1&I'Tޟ,[w3鿁*Rƕ/sXw,$VY !R~96%r՘h=%w-.`UaukQZsq%@'$ZbvKRhRxUq4{OVoڴXZ7#pz W*r;U(DZ2lWR#DC>9l4d+`9*rS-1cqڄBJ qcǏbkUP[;⪴$; GߐT8IJ*mA rKN,oiңՍ;dAIR6*I^ȸaE`8¶F߂eA1.傶lkJOpG2݅ oFZ@ o' (h? ׮_JUqU.l%e@@]C^KᘓNH?N];d:E"vU"vQb%хnq$9SjjUWaB'b¿ȥMWcW&y/5ZIxP؟j  W,RFP)QڣkNb;*\Y7={dBVqkKpɹMzcVy2mԊ?d-Kb0*1a{*R { #/*Oap)(UABJ@A~V幗ZhNI֕i֤SPwV 85)׭zT2lo$v҄dbJ؅T%VR'6nO^F)zxaBS=Q|@&,ےjrH^Qz`J.;inxN¿Q6.i*>OLJe"ed>@P2mGb=FŸª,wx (l|Gn5j)|J p vߦ*CyDHP7D@3дԅ2`lORN5ې IJ9*1"N1)!ui\ȩۦ.~00TI>3Fdڧɖ!a5=OPqJ=[Ȕ)ф+]"qWVB)[=qKC*㊶O*1VS\$)Nw)ZI&9Ami)[8`צX.#r8 \ZU(^n$D=RmK$+U *׭V(\De`?T]ULP._}WS: Ul1WC*)v⭨-`) I UF)Ձ+*POJ⫈ E]V­]_ڃ{Vkx* t!| @ Tm4\Y.eSRQ)~*&᭤gZ-Bּ`Ԣ/A))RJTG)jA5Jn}!AHoc`VnC>hbh|Ty#;vxѺ~OB@^Kd$'Y%lKvȲZMzaVPا*7N, mbǾ*x7!|-Ƚ:A`Yw*aA_4hf,Yl7 ߿aU9n_zmQpRG%4 ;aB?풽J֩9Xhǭ)4,բpɳTu~&)R2lW":v1TcR dC"VM1ːP2LwݘJ'ڻc+xoC\6w |MCm^#ܜB&d7h2FP9 Ueo{ek&)\bEME"4wU v^"vd\9 <5]|prt5L D%SqRbJr#<k(-B7ߠ"-SS|Pۂ!%ej%c5 x:3_JHYxSg YiXY|Ixቤ6%`Z~Yc)‡+ KqN$#bV*{u|7bv-:(ej7MZX 1E*AT~egr6BUV~d`U)y SѥTTHh ,#"=F[Zk8,,WAV ~8>SlJ3zp,A z|6< P1PTu-у(;cl&i.$QWk&~7]*CI #VBw.{@>H?ϦMNE"BJP?jb䈗ej!ĚP-@wŰl <1TT[b ƦrpVR*)[sʼn f>\I2U{cKnixuڴRbF*P}b`1o}?VN*";BpHPl4^[MI ɢw+F;^o*\\2k`u0Iu~P}?Y ׿lRzh\YǏ|Xv8P$L!YvӨp%99UB4f5bI$Cl(k Ki׾$nQp3tF&zm?kM3v'D$ҁk爃˨JHX;d;ӉE {KjRBuvP~ՅZ=0oVD Ñ M:J,~R (u1UeWz탚VSS bb1"zZIpǮ**V]5&Cg)p8X㹠[-Atxk3FܐZNk&P$-)oVV*b*(ht]*U4GLU1V*ኪWURI) [ZPpoab1(v*0*ؐ] M4vZ8~Xڧ*n]pԡ.8 xR8' 3ڃ02IewgQI{bOwWt"z0qR;abʇdC2=a1[ ⼻Y22׶i%O]S5w\UpNT+Nv%Cvw'mZYZqJJₘ` '݂|*׊Dc Uط…+d)CfTSqS:Z׆z>xU|NMx4Āx)mNASX&pRB6Zӷ|R:WȖARR[է$k/ſLW(%]OSSjc[0UO;=qET"Fb07ll_K9 Tz%8ҽ|29rW!z"f=XPc(I ёW9%o:(Zƕ!ZUI7vLJ4eM>ckM0(q!AY ƽkU>!nFxEZPH^فZS)]<r}X QP2qU5@VbcF !|r _ڔRU1BYԝޟw•# K(˷onZeoKBr䆥t!t@>ځ_zT/ǧQP> [з&Q?$T-* dލL*.zaCW Hq\(EUvP6G@l̡+a6dRmq%>AEM+LPۊ%ylva_1BxaV8 }#ďJ>!r^Gp%j'*J6_b:}UEA&8juGoH7m Ro['jb= YWn#EIXu铦+(w$-a*Ê] *גF<1T1%T‡r~x򸋁~dkt.ڮz',?V!J.JHmU"#Ґ};U0 Pj>W5N MF@=2E\nTPv)Dȩ 4*r$[ QV&v P (dJ$PT796 N0)' "dn)pԯlLSe -`b]NݱC > BwߗZ! ;|?~)Vp"aEࡆq[*Q*q6*u?TKSbK*y *K @P' TROc R8o@rm )˚=;Y>Ƅt0E*wp!uQKQ=JnZen ĵɆE3G50H6P o0;B>dJ9<,I &[!sTqbFQn;CG}1WAC]l\XקA *ѧWjG%ӝS TC*㸩'!i qG93/r $ XXb-x% u8UD+贜OE8ָU;װEE*Ƽ?\L’"e?l|ɞlG'܁K 1UktV%4UA)c9 .xb[s> BJΘPb'v(v)q\qVCgJp%i†(T+\H?ok!zRb[ [hm Ե2[0iƤVh}V)qTqTZ{UaUa~ qU1U sn0+\*)lUQASbSko8qK]p+|** 9# MNBvV$SnRc@"q>(*(gG9!A}( "ZEQIMw=j#PRQJn~]0逤viU7, u޸7;v$ r5 1VaTm1;۾@%+WsD~&I'J}[DdF i3<*֝X#T8$t^TނODzW$eUJd S𓿶Un,wP(7dUKN6U-HMLwjt5Z?PW}#nbBBİ> #HgcjhMtU9&gKbQHIBۿ Uwdw' +];x`V (_ "y2 N_s]0V5V#O&A~|#E 7-Pژ r!qUrŏP(0Rm4{be Vr:*ڤǯ$(_`) Ѻ T i6X啚mO(B)S%bU]*~ˁ.n2O%IW%E)rkPnBKlFӱ*aUKvnNq*Tn1( ANV3UhL|SlrqӅ `ԑt[~BJ",bw+6AB@9390Ģtyd$Taq5Ng 貑hEݲ0P쬆)]r'#APOKC\MvZcN-Zw$VW*[+L 8P늺*|+O\UPqWUb6튪 ⅥHZ\U`*Nb=Sq6)H]1Wb̔iA텋^P0%q; RHۉ ֆqV8C oh w]_PՊ| pª%S.4l*†ݰUaC*܂|BK֕LJgo8G#L(T؀8Z|1J8UrSHfƒ (TQW)zT`Uv?F 6Qc >Ց$)!=FQncQ- QoLu?x|9"t0n۵z1H5˒I*;8d|,NBj~Ip-gA腡Os?ȲBkF،S…ҽOW<$|ŋ?kɦW#'uh>#AXha-cD~VC|:dKЃ<6)s }M<(h(KqT.|%lj0T*UUE)2IfN+ڸ8^/ iNGe@O$Pb[\*lƇ%|'vjbI;}mJT)/+R:TW$EE ֵXv?VU#-WlTTM UYEk"Q@4v2u+ PB@"Ps E)TP=CB|*MEEE+Oo ۶ݶ6.5;v[^(k þ4r +bj VGr'Qew5y>*ZjUky$ P*zaEI R+ }) mWVkW6|m%;zbLWGZ  m-U؟֖.& ]l \v>`K;ҧpNTW94+Lv6)Vh9?E{7&jۿ8 k_ثRڸB8<^T?j" Y<>%C])Z]CtN'BBn w­}1VE1J!*-O؞j_|PMSaB UE61dT ˜PqUX[D r3q ~y&-^_ AoaU{ hWD Ma|[ч ɾ6SvT.1b6Zڸ6V@c23L bqހ8"JP(zᒐ1vB( ִȠIiemA\h|Nx: ԚIU"ؒ{o 6)T#cGfIBwʢz7WTI& ?Ȏ\ՙP[__ s!텋G\pUUWWlUˉHnLJI Sz⫰%>#bO8\)\R qWt['UZ0߯E4W5$kJAR\Cta<BRyabMӦت3DQCIBM+r'Q1)ie+Y݉Aߓ,UEZaS\WpM.Hp;9I 6+K8J6l\@ct AkK)h ~XGN8 aU?@mAAT*6~xP|gio_*_tU&S}٩W%ш]+9J;~gmi>&- rNCqh`)XЍ†4X X^ݸȴ>;v­MlAeXLIL~; !Kjj}nu!W?d؉M|PB(@ ܑv'6U*Ozw*(;oW$ ջiEA*z᥵)P@Dt6 `)BJNW2-dy-/אīw)y>TYT[.JT gnJz'1*Xlve$T|8Bw\84{{B>9HcRw9V,JWqVOö+RBjCv<$dvȖARܴBՠOW%h0^"Otbr:l?Y4Y}QM-VNd{))A0+pUS$0膠wȥjO[k|!N!(m+2*E^48.Ď 5$(ȅAٸO%BƑ/Awn+"n8U,, )ƞQ瀨VƤ*%l%ywaQ턨u!xm)RE;dcߐ?pŹz_Z#ڣ4[J䐸"skS%BG enNJa +B}銮En^y)</NlGCCr[dS~{`N/PU .㴐Ґ^퍢7OĨpmu48Bs"Pm v=@4ESvfBԷ@rLWʆlTdSI6_&ť] @:4Ԗ$"8-*zփm*$ڢƐ!d5DW ږ<DSePmN;b1yl=Bɺր{IdeuƌĨIr/JSaVq&7\[շUd29`}+ rPA)XN‡ &\%Cp2h|J%8+I*D`zԠrn=6}ㄠ*6х#bA%I}8+1ǽE=U*oA ޸#kHܚ㒆dbG\5 BvMMkU@)2^^gWӊ* ON UN(qw)m<0*Ӆ]]Kp+DaWVm\UA`) E+")$&ųB!vj*=0RUVpdxSkKa*=4pW *|qCkop4WqV9~J. _ՁJ%1ba ZWvDz @[h|;U=h*wFjO"퀨mIhM|{8 PdY))ew=0*;b+;պa(]\ |zA.^Kyl16T$[E(1ZiZWݜ7TS649&+yH~u0dDy$6jmRRkrB 8= )B_Քf9'R"ZH&n^d 5:dͿQJ6!Pu4,+T0nYJf*{l iEG%2QXXu [Г!ҀnlWz[ƴrlW*=T\U3*~ZFa .VV?+P{5S_,h<6 +n܅nUI'H5;u?!+rWI'ƛ^JHq~1~m*&6=*Bk@6i@)r/o 4X\;!JI#4JFQ1w9Qf{g*wА߲;UU1xmҽ##n BK dIKR8T{ˉD$ TEj]U`?hٗ)⪪ [n|*#(KTbj*W" 47P(nEjƕ?g|%BɩR@1j2 NKhZ3۶$\ޙ<9.':s=+ R "?2)t2OB1HDZJI7a_Uj 1*@^wljUvP!WKxi +[쏤Ĵ2Ll-hx?4ٱB (hGъUT)\BJ,d&ckZ A=2䘪 Ъ ֥wG9jslXl!=za Ja<{C 5PwʀoGnN?sHJ1:o Q6ހE: u$UTjR܈jS P^j ʼnj>96+x~ U_N՝ccN +7~tMĥEj=SѸxF$[5,@' CK98'L7v5eѩ V}hI>m u9ȩ3x OIHRǪj: ̰5Ȫ~Y%N]٨#ޗF8FǡcA)r`8'RP=?&[}XzBI­ 0iGS*@^ث[ qB$WaJ(ʡFHB>/@ĩ8L_GSnb KW~yR=^%!Qjq䨇""%*?u#U4Jª}JP*0EQ)|V%P+N*(p*oJPvUXN26j0;lwWR0\ִļ!J/ROOo!cGzf7)RA#⯎!Z@kaR:U|qh mšZ v~)mŁ,z*mۋ6׺@EM Gl%Clջx`nD= >dJcz(ASbv=PUREr4tE-HV4eSJ "ISmpP\_L}8StlKr<%H:Vt?]+V9t)_'Vt(VRH8]nc4`AzDLɨF *Y3ՀAjEN b(UZ>!IO+* 'oU#RS"Drj>,Cv4chLQ; ϶-~m+^P~DvW 385bB~];TIS<#[vIytl:{bN(~E!f*jPBn#b$>yP ev@e1;x{dZV4*c#.lW!_P > #tK!RU$Z&YT1!w$J֘PI =6r4Ƒjh95>)sHI1ڻcq.i"%em]_SdH(}AFH!h,O+ᢱ=OolU)WN$*IUSU])m|rPֵVJ]䘴`,W}s' S=$%4EoW޻IfW{ +tɰ^`-S4kQAb'"|PC7Z+ZVb+5}P+鎀rYWoZ#mqCd늶ƒIY\qWb8b8ءثUԡ8P㊵mVV*ShaV+⫽‡U_^­Sk7]WS o30%O6z ;Ⅴm#k^ ^XR8|qWvaUlUU튮e1V.v=I*PaB%{:amxb \]JckK˶p2iw jh02^Ss^RC G`) ++Џ8;K'j~g)ۈӕ+C!Ï͇ e#kn)&}&MGJc +A\T'i+_¨Ž-PRo66"(A!@ +)PsA†Бpp;ק=|zDAJ䘩:duT|~d(P%iL…SneJ8Wdm*, Tu! ZPT)*\ 's<0持~ YR%$א+'G(`k # u(/BL "dO)\42۸?:T%IUd5i@(ȲXѼp[?qV,EpDWa BE+d0ӊTP:WoVL +AH Q ICu2MB s?` )iG1+R S>X ^5\nT!sԕ}?g"kTULm$S~_w8h$ۦ.K xL!HG$7Pz0C]j>G$Pu k q@?@$*)J+H' ž dQ$FpXt\ُ4GS36B\ [45q>2}|b}]-ztۧ,:(sUh{P"В\(Xq*ΣPnt0⪥_.W}S«` G}К: J(+mM ǒ$I4^fǛPm]]YJaBΘT^:: ;1UJgApjZbKLur፪D82M-QuZ~eOו؀ 5eȶ!)O團L_S,Ǔ|* dȔxD 1a)4_ U^uPQHN@l$k[j>,JB҃?!J?.Bis\x[SXJ*+Q Uj)ۧdb@x^䐊Q? g$آLjbX iWԍY]𫀦(T(r3 @R&+p6Ĥ-jRq WGJ0$ C,U8T`PQ q=pʲrd_QEh)+'"<d LY ژm-H7:.! ?raPԓJl 2BIU%Ol2䣚)w@Fe]$suB O&}U'="S[ip%|mre$u¨ 7<2%YU ?#6'bCb6ȹ1k5(j̣TtWI ğa9SKIkmCרĤ*[14bR37~CxjOגCc8NB\W7$di6Tm9~G(UyY7o 騏_<e> z)ny[EwD&o+` 'JV0S+Rd $͸HqCT!k[ B֗IR"*дk[SOz~P;« yPS'dv%OV1DG})xTv H_~$a c0yĬ:U7PJEGppʭv*KS9sV=6mVif@U"Y QʟmMD/Y\y6e- nFFmcSZ!@F̼%W8U4FcT}4IM*2LBԶ^1BV5#+Hi#'`I Hn]m 8qLۅ ]|Rn*$P&)rHY:"֮Sy6zaC=iLRj+T-*㊪QRvVE wPM;aUh`ǮVdV~P/ARopv*wJ-p~IYL]LP1KX**늮]{Z=qVVWUǮ*1V†wLU־ܗ2Ӧ)$ڎ5G(y`" 5#?V֘P {⫊JZWR R/pZ銻W)Z_|U®'6:.ݰR0 \v s:G8U^RD fl#NRӠI`UsLN\!T+ūBUsc;H\s^0jqJS$ +Wp2dZlĚ}تw _8^ENNG>=+ 2H eWc޵!PN6Z7>~89 35V8թ\AQC!xXUDfUVBzA_JK?M xB\s_U㔫p;)Zבw;dخCQWR5!!ܨcฐ6PDmڄym2d@&LVaMMz UkӥwVW|(]PT:Jփ!UA%@*oUz %O2Ò+l=d:C(OLUdAd/ K|}GFD/c4Cd v;&F@B!rݹU_4V EFa\ /8ܡ~c[l \!rRl~Gc+XXDHXҀWx,i6C~G$i1„CR>w,)ӧl,WISJ;T _VҢߖVY|C# KMwWD["SRG\*Q"GV|pzNxA+lXU|.8ȧA[lXۑbB+*qPFߊ[HQ> 8zR<9Pv6Eʤ`OъZP0I kImf/RQ Z)@}ax;73c_Jjִڞ9"t6A, jHVTVGTے қ|rH _<(]Vn>إ G^ ]0gъqPznGd\Z}aB_Jb~H2Tet`TfN1RG"SZ8PEZ dqHn#;Hܷ1AqST:{I*+tGp#N&uY (C=I>*W+2T4ȥ|UUu;b*ֳ]JV9 H4q0NM ;*qW\UUV i.CdQAP▎-WtZ(lb*gv*m**ث*k[bUn8V(ow^s g\(q+k7pROO*<(?^@]4Mzص\:…| t+G\*m\(væ*aB;㊷É[bkŋO)mEFBTp?7sp8R> CMv«T; )l&-&Uo\UpO #N_*`* U$v#«tvH]CڇPPCԕB4kLP|]z⼑&Hd䐚Ք 7p6`JRVPFaFZƌOz(XN*|vQ6ރ$k.omYuA ͺրbQ ww>lV+˜t[Qۜ ]#g \ONu"RD(bQV_ ٪hp9ӏbka *a1APA{d[t_6Á'jэnO  ܪYATm;,U+h~1nzֿN7q&E#e[STx_تbY؟S ImT^}6)Kɫ|0*}p5ZT|j8UQW :#'̓Յ7VFiJ〤!ǁBrZ]?`G\dTq*HݘBU8[Ġ/0%#sĨt4 %B8ذ'z2 U>*AHkdR@IL(>CH,Ŵ̄&C-O ,.7Gђ`O$[r!CTSD|,WG4I)Ɥ'|%U- lPԭ[nĚc(.4Fo J|EU~zbT4y7s5^(5޵o}0+Qg%@m&|1Uh|X҂*yo02S*ibڿ1D%Q'@Wؒ~C#ɏ2 ʤ`/&/pI+YN$#}Gbsj_sYVB==KyP ީy ۅ ሳnJGv8BGA[-ANa!-E+jj?ۭB)v?Pт[~`*Zn,UUȅ!HկY%]+t;-2<ݑJ*8憿'% Nѝ؀+NKt`~WG՚M՘zȥFxzw,'kN "7iKsJB`G(VƻjiͅP}Ua•<>pNn7Aիz̓F5)R0DnENUn5fR7?? +/גBو )}q V_iBԌF$ #ք`JG~B %Uf= TVmXNWG ؟xkv«S}*rH\X;VS8lMi֕!Vgث 'ni T O O2lTNV-h0* >(ThUSJC"#sb+$6Jz*(5=+ "8h1Joқ|vmUpF$}^5U* o$vr9aUH[qV<ܑD⫸JSAM) ?~!)X5Ӊ*lȻpDHy}ؒkbڒ}r ]HQb &eVB>d"Z\4?Pxbh*B&Ҕlp]w/)* YDIH [B(P7ade$AAH(Į'+ R+߈Au  _mX|҂1v$W7k 5*~O0$4T,9`Ƽ~# 6x5fjԹN@ؠ$$JV \nT7[!s $>0zS0ԃrZ>PwSܩ~ ^ȼF1Ҳ&ToP-ufYU$|>JQpЊaH*q7HD_(e8,jC•5)E(R@=4r>cLlG|@Rmc5zi P :ޙCFhdnRj$R?JVO4rR6a_J*JqWE-b@bXzu[rn|[PȌ;}N'$u&U$Tx l Sz'ZÎ*īO* jS 92SRMUSjM~d*!ȅ񒅘|FզVV!R@wZԿA02mw߾(\I^EWXa*kyp*PI5%}'ɐ-VVƼGKcZ*»׷*UZZ8NGi`hs -yq?Q=q*WFVY=̃RT$j:3:=ПT)0T9 DUc V%(X 0i^|XQ֣[j~K܏ X1*J}Xӯ#Z|'J7l,)L6_lX;W@#" Z5~ck1E)+bB!ŏ5T6<ђk_-+ :{` H ti|ݿH)\d'R{ G+l\-޿?|O&7 k@1}^c@+zA_Y[^R1 _V'aBA]ȆEt\9#Ɉ~$6E7NE+~*,<!%MjphpWBHcVK HէJAPp*SJxaV2}긩!*ii㓋!qE4;cŤ#30&wWICBwK~ XDC""(=E7܍UzQJ،(UP>!߯l r,Prb]RF)oqX}VVrኹ⫈8Un\zb8bZ`U­Uث튵v*㊻q]aVjU_ѷ UMwcP)0***Fiwz (Zw[qW * 3TSVVUׯ߅ ~*ڭ1V(lS 6U<(rLy6I=%Yȓ6ĨXF{^Rٺ`jT7c\+^%i"m( tV~%!kp؃{␺EOc!e) zw=hGᐗ$J=>yX`jCt ^IYiA'Mev8H2SvΩ+ҸUNg4% o…ǩ?, w_vO x>ܧ݈B򴢎ȥ r;mec$!I&qU3]ъŲ*݁߉V H篁p-dnenJ3Mc-N"7bBm hI&z~: _vI ^} j$5l:$(+8@oyU RiӮ!$)0ZKAv08?A]-J ifgvF$,4W!é4:sY/SĖIn%y(>$TWB>'"ɾ->qTdZR>'iH[j%r^Ƶ |6ރ[PKN +:ت:H*U Kvt!z~C b=>)6 g, M @wX$!oV4mW_ }"Hߍ)7Igb>L ,|q܌LHTY~{!Xu^„ypF24Ax}&R> 2h;Г V>~IP6‹m"25\I*Q@vۦ* aӁV0s{G&E}<H¡M*>cKԥ*N~F7M%ܾܲEmą"QQS^ Clkl+zဨW >4z% !ߨ=6 ĴME;⪑*xJsQbJB.Mk=n4>16TV4"UIh1DIX^[G,kӯP(JSm P NzUW`AӁPW4*{`TeƐHsrAx)n>CiEU3""Ӑ2@*0 'jd0 *bFo*QJ@Y<@}CMX R RCp7R}ehJOJM+UD&T.> H~T-rA? QK;ѫdL鐧j-zY*b @dT&zu*U紖8[㍦ָPPBn/QZd8Rc4 TZby5ڪG¿1`q7mWƼh>bZl*(iƀ*{WW_ı2r b.Sb(ӄ-:Sxڔ~~Z.PAĨZjXܓZ@87QS\ȐZ5;Yu$$O"w?H *x}ĩ !(C LĊ|wȳBoa F>,J)CZO5KۆZC_ BJ d`Mh?:2W…:~†CXK];qV*hj[a**VU2ۋe*|H6 FbUp4L***l\qWb8XUZªV 0*æ*vVApUL67LU8:bkALUF41J:`V\bp W+mN¸KGaBP:Ȳ6>8 51VѨw逪u[r8ێڇz%mI…OLRkUy%H.C[AACPT5^O݊v=Hp„Dw5呗% ;~ڹP䀊$w!B>$X**su 6C4 $L6hí2vĎ2a^jC Sj`% 7=*tQB|Ob1l!P| ]<+`*g?j1 abr<1*W+ Cl F==H*(kdטR"kN׈Ym" z]G5=V -](uȖ=ICKo$+,{!Lco%W'Vhi[vUJV*dRV0HI4.Z&u#&Q\~x) 9é| Us-xһ`Uנ~_ }fQң=O R%eݶUpъU+ͱUK+N;ӳ z"hH4O^ȭFY%pO2yJ^HgoHiƐCA>|?ȧn^(5=ثNԪTPWˮSUcZ;l1*c-ӏ/TM%b6…F_j)VuZrpNj;` Zeh*”q2|ЦT U*) Wbh~|P Nh `:dUڇ23%PӮi@(dNB؃J\j'%H_%-!kbK@A-u]«p+qn' bX$ [G[QIbvwP K< o(]p*eGs%H (\65=pqn;UP|bVEr6 Zo#t'pY%!V. M\HPyyRP rj~feu"9 h:Vw4T-=*ܻPq UnЬʵ4;UæVFS_%ZVڛwª9 @.4JERjHWcIYv@%F@_&!F*zBn}tR>={8YZnLOYɂ4Jһ呴 ԏ|,A,`X] NzW)_PF'凚\үjzLZԑ ~e9ҲĤw[A^+u$.ƕAwĠ*C*?l%B̢+gĠ䝲֢Gi !oc# ]Yڃ|N69dCa;!%3c(V* @bdfI;d `ZD^Y6 # 7 osuU+0* h܆ M:-T=O;o@R"vbn#!9+gT,`{ WƲS IR4UʿRRzVU}2XrH^+UlWs 9J o"?BXz_3z VD@nI Rk#v)p]\UbaCg)mZ8XmZ®'|Uk lVU5;tZ\qVφ*w\PZ\qVVWb]kLU\Ub**]GRih}(wb\}Z]zVLU⫙h~V†i ժ}Ԯ*7*ڧd=8k 2LC_'u4†E@@<|+59>L9^=Ai49$9`KcV‡j7!|p]׍Wj}ȥJ3J$Kq\Dupw$Li!?N@rb!HPu; Sе[쁒 cʟɲC| {JY6çOl*i ֻ}E2% aV4ZvGOZR> ҽ1CTaC7)d?2H)E |閅_ 7#vVԷ )RGzubT,O#$6F-lj_&eQQe.KH{mBف.z{ ӹ+zT}?*0uiZlƁOpEa@)Brٻaqa] PoɀlISP:2Gv#ey q t96<>Jac<0i)O vA qvi~*x`Kgk+N+{DJ3Pj=M0%|AbeS߯\UUIzX pR#4_zКt?*G ȿ?:}S{`J7؁ğU#t?y0VqWJH#%$3.#!!NRޛqaBZTӰ)Rf$þĩ.TS2HXJlGDszI;TJv}et֬L*]w$P*{ڝbG}4HݙwT5ȖAe,yՠ%V'd3mơ B%nY+pUOMH48(_QH^!z|r4+M#9$7pURJ…H(-.B%$t놶EJaU}JJ遌)Y'WPr,ᓍ:DYanIPɖZѽVb8DcUjLmP@G\Hp{XK&ݛ݆RR[wq'o-"bKrn%S#T$*8I?p%ӐҖ BOءtj }O ˱sMh0"*ʇjdY 觨rLMw }V|@.jA*jvYM SnIMB}sS V خZ`V>ʞJ Ur[(Twm7Ĩy;7Jz†UW*r9bjևKjSZlUq]-aUM|Uf(m▆*uaVV*4\7a*K(koh]\UثVC)v*Uثbӏb g1UqWvWB[pZ}P~ݱU,Uo*jo ~*jh7W{.W/\ haW8ՁiR[iVJxⶼwȥ6`|Zȝٍ#X†Ul%uLU|T +:n;l 0WGcW<b~q* oF]pkt@TvQqK|~2nm"d?dȄ*ʼCs o{e#cR2i 9vȆM«N懶*&A׫|ӊTk0qpxdY*!=7'\,VŹ%W|p%R'zSC__ՔbđBZ-QKHȮW~BPr>R N|Y3BF TbirWGE>)^CWTP~`;2cRyv8p;U!ACaBPuQpߕkLˢO$<>IG!JW u܌!W)ilQiU;*Ȫs}Um6ع>?&&dѹ56.Up 36F(QڌY~ʁF7_ U`GzRǁȑ \ DOOVuH8+Τl<ԩ+pJ_ Pܳ$TEaT5҈Tƽl&bAW`1T<`BОG0RMHNTL4$}0hB+] teF$.rZ|;.HR&Z  ߶% Nm ER7H˾%xrSAܟ S܆[! bdÒ J«dP`U-4N78E*ZJRmMBvޙNEX\М R ÿr6ZCVޘJ1^|$bDhk`))J#BJ X9 ĹOsۦh状 /گӉHV \F=qBP)1J~==;lӀ0ދ_Cb# j=1􉇘^[*igIJ=IoTYZT]P*i1JƋï Zl&TYEVِ4( PaBw I\BQZtG!kUHDM,R9G`@Ԓa&KǾ E|)B2[9.LU9v=U.Qߦk+EG߾)_m6^mRjNP aCmZUP 8czoT }L[Enq &?z{TuFSҊ}9J< =}DPv4#r jG  ".'?ۓUI*O⪪W4"˒pCJ e}2X h#_H/5]x|MhOȲ QIQPz 2HĒ6T ],>\UByd.7&*P 5Á-o#d *=֮(U0KR+_~?,XXV^i*Y9PIj}ŷ{a-@ՍH!"IxU;P$#1ԃ֛! $C݊KMH^?EW.hk2*V;R )^dTXWB@i0`k:Qx2L[ 7Uau(fQP}Nq:)?U +V\URu'[V5 7#ƸI[//N:'WDiiA^bwUR7 ކKSC;{m45H?MDXڵ̌ E; +'*PG caFR+! ~LOL%v+ [زȟ l$*׈x"@ KJ9zQ nAt<ኍ֝Ƕ(^iqKc}JAT,J'K<(s`$]s j(y0~y@fB(OR%2|JWqr¡5e㊶My6. BhĻG{` R؟ (hTDIO P{dآM FDlwF|Bp+Bhje*ǹ8hÉ"ypbɰ]*񒩸; ZGDZ#TX rLUb45"}-b$P@*Gj ĊMSA$VM "i_s'ȲZv‡`WUUثXUثUn)\-WjaW cN=V\**Z[=qW@*늸U0*邃JI b8WUء.qK{ c][W~Ӂ]ƝqClb+u!=kLUNW~ ;mwPž87[\(p`Jw8\Q0 d5m-O`FFn`L#p찜qJp{aQ}V|8qiδ$+22291Uv27ElBߦNS[X& (*b#ށEIZTU8NZF8w=puP) pqJ{~ЍeDyq/%bM; A#é>&痞sl~-P`$*D'*TGnBwnY.7T;t.Z&8PH 5®ҦLU(1BUYUTs5ȪBJU4?~T!PTv9$.z0p 䬈É#e좔4+|]:tx1_1{, \BGNGߐlFtzJc9d)zaR '.Srb+Q8 Bxd7ڧl ԔP= +$qڄ *L%>ۿTN x 'Sc1UFCMA=RE2lW-Oz~8dw#Vu|p3*T4,[n~>,hrEYV=_BvRo]8]XW\U\ z's`WaWUUs5p+c)[\(l\ aWኵv(l R8o.c^ZqVׯLPV=zaB kPNbw®8늮Uڸn\o RRq\V8QK "#2HS8U`W4VlU\(C\;bT)UPP|=SkmN;bV?*&vrGS\UN, x !Iה}6Ζ(p0ѫ-YrTyJλ09H`%K)kKe_QnXO0RB* .죈$aV:aUX֤K쐶Y&~0ژ<†(lf«=CƤ0ہ%s@j::RVHUPS) Te=PrGQ\|;8DEk$JH$+$O ZV8X-u2h4,'c#|Jz@e[n"Nf+B Z)u?vE\+@>XUi=:S螭zmaB*37aZs)jgxP-; BNx7,fR>DPPT84mv |5$9 !$~_c;W~ER$=I5ھAԀF}] sg h(wĚ@UU#MQܻ8JZb 4wZ߁ ဪK3uげ+bþTo:k%oQ%!l[8</Tc?l6҃ M;S\[z B .($CPc(x@7BBkELz PK4!W FqaR)R)ab1r/h-"0 5(i IMԧ$O2PRLe;!KS;|*Jn?|JB@IuJin@ @# (ѷC>q) Cxdcˮ@2-D*]~PNj$Rl mT4cmJ B,wM4*cnʀ}A_0%LlOI&5JV! %Fz!Ooo *1% ?@YCclt­w[RlVg**qU**n†V\UUe-FqWc !H Uv\F*qU| UqWb)jqNho ↉qJ0T wA(\yP?8W5\UW &vW[& ڊZ&6 4mxPj>T4iLRPj JqJڍ\zF,h02p^TPS~{'SvǢSE{O5 n%ڸ*@Z&Qh k~!Q;2ZX\MvF#t#)T&wHxS~DZE^S-)U+ <b 6x5$xf! TL!V|*jJv*8`) ,8nUgC-\%W˯߁QC}*O%.cXՈ$4f_LPjXr[G8XsSKٍ7\B m;+ܱ H ۗZTmhՕjH>J{Sm\ ^;w'A%+@+Ep*7^Pb6R{{VSWFc@%jGłPܺd¹#^FhFYsL$RGTN 4 c1?V*eR~!G, EWbOj4P8%X}J/ӮI# լi @?8-4z]qZ҂V0hF6*,eFڣqvZ`jXB)E+U:_˷(X?,U]g="~Th ^ey]I S;JBr?^!T`#,CLԪ^N* p)R0H;PRO8IXIb<1K`@0!ȧ# Pm2İ$SDH4y?.գ7dPh~ {"n>[䐼S5®olBZ(dMEr 5b+nMz0* V2)s^R$BȄ 1 FV i퀨nމWu ||*J\U]% @+[g3E5a(s xUwܒJPP>&2U5(!'OrqꎊCbi(WF:q)SסQOrE IUpf|SҠS)mGE4T"‚…/aUdG4u)C$S<\ +Ռgn=4rf5jNR7? Zo5A*Dd}bQn3SAqXc"89 Bzt~*7$/qC#px;P7l)?*/!s}$5h)ڿxȞIm^z֍r.wV>AQd$v5_nLN5bR!5]|F*[…"ʟhO JtiH~!VW\ңzDBJTwVݴrHZ!c*bqhN4FUyZȒ)'lD(PE}*(P?D ROza-lx*EP9S`i_$v4=pItՍtmHs'BKߎ%/E+p80+C opVmvV\U*p+Wwl*㊻8▱UǦ[[8b*m*ኸb+T®;bbwqVҕ[' t u†p1UWAF*Nu+=qK@u D E,hDA0ũ1U؁Z~x`4U4#4z K*?[ МPCexæfՈ~,݈٦abI튯H `NN$ `U1|1W|F^,*HMcr(qE`$&R]ؑE^YjF @c;pDe`Y~0ޟ%, NP_ T89ZMV([ĵ­xVI8]yUBHďeƆRBOTA U?ĪD*!Cz{- lvLU*UAwqV/ v% \8WӅVr(r7$]#tN8U閄iV!KHWr#0Jh'J|Jњ V%lcI oTSеvpI*qԸ @VNؕ\ѺQOCi8„UR0@`;) $t)pRM;\UR]@?lcJƪ"~XWZ)?^%CN,xy 0H`)RԊhIwcS+B*+AR+[ʧz%!kIץ.+ǹXm~>RqZקf~mkNB@n]޽z.)Vt+AsW+/zW䞮1X J|}Ac?e!$]J$;.L!EH?#aBfリz)jƵnR i} JT "oJ֗d$O R1NOO@Ei0C}?ժWo"* ]KAx\}8kS+Z tRA LHP}Sn $@cL@Ih~*CLj!-Šй0Q5U48U`+Hܔ˷сzq 9X p ݆"-x7OZQQjXOj6USWD$QM"n +P) +Y(R@~@a) ꪯq>QPu$*}3(퍢I*B W?<4 TOkqϏlV-ԭ$1Eh#,blIY 72%!¥rimK-z`#ɔ4\!oL(pU:5h<!r%! |vQ(hpGjziPv`(8+$%ɩNX*| ?l4| j}0%ء 1VWb*U[ZnXUZ«EZ>Uklbݰ**Z]1V USw,U`W_›in㯎(jP*UrA>hkᄨ[޽K{h *~\Uq8DTWbR UtoZ)p!w|kEW  `ړ!ҽ^mv0f*h;A(mNnnTJWLB#:a*v#"nv'E*GOJ/DО>LqQǏ%@\0&ʌÖD%erjmB*ByWZtk$P!㑴j4DbULРIWVMS[E)!j$$+~&ĨD:5dRiA {HMύ{biƝUx-H=qW4RBՍz-6攷c 6{PEO߆ڻ^;n{*\ǡ0%ljܺ5?IUT| s=z`VbUJp1UHS/`VS!T…48i RġMQBA D6.#v ,|++ߕvǪl@ CUqU╩'q6Ul>*hwQ2L ^!TϚ5J|RW%B)7eu2>b""QevsE,,9$*Hi_D2U8|#j$$ӀZ-W4rUT$aQ^ءQO-q+ (_$1qĤ.ˁRhNۊ6Aݥc ubO"=)OAjQ\'*&)H451J1㏟aE?W9R1Sj=aBp Uc:hM^jL  #~U|ꖘGq=N IQҀdBJU>$J(=]U9M KoݨxG5-ɹz> ,[_M?66 1,dB$*4=F*UW5Hgє=lkeX`_!AWhy$f0.@ ѣ6c$(ƕP<-\,Qv!B3"e'҇- TT㯸Zʑ}تb67ڂ)r1TI(GoFB .:zDZ"5̗d|a!P} SE$x*l?hP漚w8+dgcߤc݇v>cvM[A^?(D~[bIbWaVL *኷\qW )ͭY\i^r qAk * j k\ƿv[[8\qVUn0+aCDb*r1jxv)*xP-tZU~kqU.ث UqUYP Z~҃(h#|UqVV)q\E2L[E4Nq^K:*xQLUm1KRqWT|Uժ{`KD®Wk8TB!a=)l-SsHu)ӡqV]|{*LPX/8 CDޘ_(݁f?‡c>LS{W?Ps((nb+!FcR,6݀;c$#rzT{ ҽDS45>9}FT!K1_ RЅz֛~ ₧v?GGQgh|UFE 8tnhQ bEwam&Z #k8P⤩ S/$Q-\= N(Ǯy/T-$F|brLTiCIF|$ e?~ҁU) dصZ{ \h>lK;\^zt’2':0Zqcj {† 0Pr j"F}QW!a5Rb uQ6x+j/E/)raP14LW(&6W"tY6TWXnT҂tKjk֘JCllx8Pr8u2!PM!oU '*{}8rX0!JCj`JbڞMy1r>4{g<ݹ0ڧAZ8#H P:1LU:rMjFy #IEz4n_e+ӽj1'bt䬤T֟7WNJ}?g$I_ N >,P ƴBN>-2A%t+΃ ǸT"^3%p;{(#=j|*\#6!w/Qڪ1 *O֞'†؜UOLU\t?F)W.#2\^4%O?Wd$ WcXkDQ)Ÿ<(DFx+W$9׈n>Xr@=7ZMpȥn\0+*]\1WaVWUqK(qZ\U*NlVU⮦*KXU])N*qs[&6;VWV-(v*UU?UO MjPqA)S;CqqVb[; nB U‡b޾- 8o\C#VVM=V|qVתHq|ƠWp%9ñ#gVp%-Ǧc⼜*}Wā@Y!_3XbXhYk zsېM|wQ'ԀNH Ɗ S;J?/2Ir)~ G>d*@Gg! $oZ…H(ԝƕiR\zbUx8( (**1EU"<!,Z|=24N$A}jH?+bʓ{?xWʏ6(L'%km+iAJ9( RU;oLa&$-}F5r@ҎPn]zıSv +eVqk׶I PU(M둥Rrjny mɪ5`UUv5N*8܋%X G%m:4đ1DҡqPUh&l *3sWsJUja܅'mc(H$ ڴ$:QJNFw1*WWmT!(̢k?g%B2'TeH?ޝ:A,h>b%ذ^+zij,(FifjHTMώ*toA T4C}ƸZTW$F!x=MH,Tc`>?~lZ*T=krX.{p*ej J2߮XV5 cVbzK`PՆG+M V2aiy_E~nY6 l'j VjOZ`*l*%!ABTsb5ГS^Ȕ ڄ{8UMb:JbR|DtMtU 'FeS)4JO}! rG>-)LJUDzry_SMI;@?d X늯\Wo ýGޘ_A{螭7nFZRĭ ?!o?R^B)!la†S;C\L$`mvx?|*V,2"1AVqU+Ө† |r)Z&$6+#wA*'IPZ׎5*IVCӡ~W:U!J߻5Oр$o=0G58د N< `U%jZ ոزS0ISadU\x1wpˑkQ̫Js9B>uqra\'"jA޾?(SiŏnL#Vw\(ViSǯilԌU !|$?o '}>tT8S=֡;t[^UVK>x B (0lnKO-#VJfI r v¶*VJ(v"9$!Y `[ QY@QaCrOL4qKL>GٮZ7‡* +U`Rv*UUث+gQ)↎kl\U[8*uT=+H®8t'1WJU/|Gɣ~Xt)]4qVUdkqU01W\v…1jWC=1V*)p\v=1V*i\JV444ԉ Sr)I_lPHƙ­ U<* U҃]N]҇l'/yYuG1YlM&y\ MM0p銆J <:|7]j+2אHP'z$UU##`) o@7{- ; Uh}ϒqZs rg JT$C O2:1DLye[B&& xB昔|iQ+DR Ak֦>l\b{֋\ QiU<0mUI$%X QxdC"_ $MZ| R ?>~•fޭMEj:l(Wt7H1*J% ~"XRkr! }\n*(V t6 n^ L<)`QaA C@$kI)Ev}?,"&w{*œSB+M Ȏ#s^S$g4*(? ߭T=.nS@n'HSp:|_N%Tڀ=z⨈bߓnJ2)U%hF-*APA_*Ɨ:vJttfw †&B>RՒ6=^F ,bs>RGjIPpg?dl=ӽ?V+V^6tUEpdyX80 G# PY5?BI H$PmABjNBO~ n!JҾs.|UͰq N^8-TXkR^dH{B;U:sW_<)p}: P‚fĨ\oq޴OۅVF4sAါk¸:$:*+zl5GznI!I!kڿZ TKYK@W : MKwSVI .hD}~b OlU>} V IU;bt@bT,V*ш} B뵧:Ew޴."&Wa@o6aP|rvƑ6η%cg)NP ,[P75V8 $JҼ.xU8UUU4(GKk5F,O CVۮv*hV*88=E~~/%B~c2Q&-Z8Up[`Cإp@T? ӊ8ءbpUAT[=1W U|Z8*vZ8*MN*zb[ JSl*Krŕ+J[Q$v1XN)\}8tڃq~x\W~p.8P `Jq 1-ԜKQN%CHk!qjoZ A[Zu[K]SdK 2h^f:@4v8X;‍Qdd\|((`5$%ۥI ,O޲xRNIVd#@;TDAuT7)09oC<2IjN<x`z >AQJ136@QT ۯхy/zaCKo#杫VrWF*y} W#S!LuS&~eFL(SM{Y*H"` \A;P?a JPWB[)VXA!,Ƥ9}BOL !;2Jև]2 7ZW)iExU[xdo#e䐼 ź`Hq ;H#nNEw_:T(uPҸKV}^lFܸu M&+uKj=t8IO!ҘU !,W]KL쩱?|%CGک{`T<*Jd q! Vk~yvK0e?*̍‚ PБSl*ڮ1k$P%EH[D:~ґP+S;A$0te"'$Ƹ+$]/' L~4rV d( 퓦 +/O*FVQ`eV_@Đil2)l%\=?^7D?A#U)~GsL!K_`WxM);mN*VVW1B^YGRF S$ N8kN%ᄅLǾ6]"UzVHCqTD b:08S[250Xk]P`Tq=*z'g}'q*vBéCH>YոC-> Nb I5NP‡fj:č2Jb(VbӋk (r$S maRp fzUI4) ?D|ll9Ă+7Ӏ.v#m Ƅl=LBT|G`?goȈ%F=GITUQM/qg# .~lcO5Jo׶qqA\ (Hj¾8Jt  Q7+@f5+ ʂGQ»?91>]0X0j-a(jX*gu(w،FM? vqU N'sW- Uت-aW`WaVhaV]#̓AqJÊU,h1* bUǮ*­ mV\U|+lUpZtV*v*N*qWRPXW UbaUhS;)qaClUU|1W Rb*犭8g)ZqU˰'p;h]+O6w#犹U)A_(q1KusCpvqK\% m b6[B02nWŴz8"y3!?iN&HQ(knI wMf?xHiA"Xl~BFomH1Gh 2 c *Fb`jt} Lh|4/I ?/B)u.W{L W bT8b}ݒUǩ^4J~ ^[a,PTA^3Ȥ1u| F%`N,Y;UAQ;_ t7!z! FTSJjQt)1$Aޣ|BǂkLi665޿<[r*N(Dفq* ,6'cK.E-?jN R-b! *~ V(#**N&PJ)R2fRv؏sVE5*8" wn@A># ay$KDPrTQ` {x)^ԂO*PTQA'pd-XՏ=P 5wѾ!J(TPBv; U*@ڟ^ױ^(p( MV`cJՌqIӞL[olUͽJO|!p P(iۯъ Pc>|[*S˅4QMp2EM+5;֟0*z`Qvғj08O$UgZv-A(*jk.qRV>cN"U %kU6rҠV W ˯qd O$w;xU񆉖B (Uuұ5O }m8zIV`dPlu)C* V+PF #lBJop`sF4PG' Bj;?agJ訫Q{bT,r4cxu B TȥYzm!f<ďo.krHWmO]0`fV0 z ӥ)*vڇHO3CJT-sW{xaBH$(T%!Ҡz`X …𒧑7 o*&|k FU۸ eOmr? +G! 6R!d58J*Zu&nJ$A]~vRW`|+\6>Ubo׉PI <{b$on_frJEQè4ҞkP}\:zbn{"ʅAq Ϣ(?PBB0e'z Q}!AT"e*0HVXoް,E>m$R V( qFHh>z1ĨBnU㆐ ㊻*b늵vq\0+g)↏\UMF)sPZn*㊵WhU͊[p*U=W\l UV] t®&T[LUqVUU*RaU˸߶hCV;opWvZ;8LR1Cm\~JR[ZTW6z8lKn"1BH.AK@4⫥<L%iHV}U? ];soR Sme{uȞL_nGo׀.8%j%MYXR!J|`}Ȉr nPlS V)7K$iRX x+^ևdh :Wdly{R$v^FZ(T,~у( 92+xے@iW%-܁0$ P B6aB? ~_*Ӟt4d81VA2k=xeP"U$L)jbQ<ŕ$. GjlX8H0#NB PFEI1Sud'aUlU!aUWs^L X'.,8XGvoRF*jå6bP`JŸARG*#()@0%UAZByVv<ڻAR7n <ڧ| jOj*rF2bt32i'@$a8UW}8e4Uzݫ{WƸNBCh>[b(z}PW~#Ҿ2HZP~Cv4HLe(>14~-P Ij UM$,gnOBFXҮrEUqVT)R~B ;*lH?T/R1M 7ߑ;M85ٶRE-B*%CĜ$Uv߷\W,y{ B6$RMˮ*ZL(Vp6`|!S=?aB. ҧ;9!J)=kz+ЎY9\WbG_9 |= f)SI:xbW"?^*$>8-4p̩I q J"RG/`¥ v®DuQV% B~g*=ò3T.0x~န2USpPЇLJE]i5&Ve`ON'lHH+0+ȊZJJT10Mx|U.'&aE54=Y%܀:!H)Oև 9-S_ @-1VĀ*AmQК +ܨdS .N%jvڞ>E,9TI={䐽AWnh7;` P&pڟwJHUJ{zX~ڔNPR$T$?WMp Q|ɰ扄"?wqJGQ U|,)UvmHk&5 ŋs 5~$ "IP7zk|(YumDZ+pC*ukc*.<+VtCM^8_C1TPJ a'"FD!C ZҦ |n7)YRGZHq?,UqBx=1 [*l#6WtRNzkZT|=-kJ)ۮC1NƸ:PkBmm+ng5<ؿB6'UOZkHjh:nAbpj*zP.8``KXPb㊻]\qVqQ2i pW=wއ`CXU%ءq\F*a!%W }f"N&-\U{DB!L0EK`۾*ހt)u1CG ZzԦ**Sv*qWtUST㰦[Ӧ.;L h*⭏|U>xUZ‡ bm!\+H⮦7M͸!hl(n` LE!(U}Q->cZֵ 0j;BJПihN Zmz OKUQ!5枋pbPe@ L5I5P2Aj6օ4KR"lBf'Z1~@pvxέP[ z[.dEV'䂮Ē: ġͱ|瀪ҠKnqzPpUKTGa=;BxTPx> C|P앥*+[MaTDrZ 1UP€Mp2s)QZn#ok3إ Q!(OsG%|'F~"{`,p 's[cvACI?YQqZקJRY.™0J ~.N)_!0+j:LU@?1^h8 B" TF IvdظEǦ)Se*z6Dv$d+5;bP;T?!(~EH5 HcO)X6ۧ…e#WءIִ*z GAA`< ٙ;7Ih+X$EGFVG}^H-]BDy~{0f>/Y,poXƼh;91J"B<~xPH?ݑvƀx oo$ !n1UHnXRȰ緾VHh_ ЏݖUx[W85g5N؅*cnpQ~W+aCdj`J~<]|0R|lU|ơO~8"Y 7t7' UtrdzGu粓(S׾,TzL@\UjSO4/! rRBbBoU0O#[lU!jۃۀ |bc*K> [mV3TpTZ~xB4bYaF:S+-_|*W5qZ+\Rz=(T+UH}_إsHb劕+zb€ @L\( ?SZ3Z-Ӯ!JE_Jz]z+aB"ݽ8TSq Rj*N*p=z> ֔N@#B"cʠ3]Hl(QS_$U$^?*bC2ւJ~B>B2s'5I ـ5W99&.⨛`PJFr&%fmA!^}n*RTn#PXPVR;7]Cx Z۵m0xTT xLъQ, YuRP)S8h"5sڹl,G2D"]iӅ^q?e~kK]Wȥ2%CO@تz>`#&!,U^'Ud~(VvT5iV4aHu*5bUM] ڙ⪅I#1TtZ|@ӡ8i"I@0ڧ!tjO={\IPUj U$OqL*OMPՈR X2…S8@\ +Qq֟˓ V*/5_y'NlF؄`JI?dmحH~ՊV*.v{w?!eht#`UZ?p~[tW]ݾ؅*45FPzM V{䘷Ns@:xUxd]2AL**7W: ` -?zp`pUڤ߶D2-a%W⫰+x b®8l8\Kn܎#e.ءUpW5ZMqUp}]J⭌Uhbi\ [Z*Uo1C}zb#ko*CL0%~?*O*lUUh銺PM**? Zw†[]\ ~xbE>\Pڍ* nxW[; PVإ]#'R^ PN:liZBĨrxKosbqljK$GBM0+ *hH%a JքUKFJr7.+ ijlUIT0>O鄡BS WSumg} ާL 8v nE"j^m%MhHTg]R$""Q]M9#|BGO) l\UkG*Zz FD2+%7"#I {r5G銷Ut$ҝ*d~!"H!E^A80y (TrRLHRAȁ; "YNV''G$9:a 9w܆C"E+iWZ«B v*U 0+*o `AbJBR-S6bb=qW U늸*㊭¨/@OMχr!4&k:⭝VUaO0)hb(uiWWqW Vx;*~߁NF* V.FCvSS)Ik ] v†\R(<!KXP\A1WS…ǧp$J P5?, $6ÀZw>8cPHp^M4` W|A' #KA튯#nC6" Bx 1JZL43߫"y%VxyJj*~{aB)Jl%GP ޻⫢^B րp<~"MUȖ#!,›BpHU@;+^c׏qDn>bPOtқa;p1̀£MT) ĵP犭P(` 8cz=φ(Tc\ ZasN"؝+(~7$;Ӂ-zރRHq4 g+bc9bZm3ČƜJ"pCpCF.[lPہ5!%H S@j ЂOlNZ튯x1ns_U>mIB@ *ȭJ jGTAaٜG0Zz;u?<74+Q%JdS9 fH&%棸Ʉ);?l(XME|6[jV_e=pKD5&L*g)Z~Uf ?lmmZo䐕l(jcb^vYa8iSM A4I+CJ];}2,5;5&-۾*$T`) tB Ȥ7;ž?djjU,OUqq慍t Wڄİ>;KXp++xP-b]aVݽBB1;JC*\VV*8*mh8P\qCJhA;RLሦkTw=.ZsuK]1V*oupq\ p1B6)~V|_!BZc\qC~إbbUZbZ+M(E{x=vp@½Y.-*|R튭*⫤b:!J UrFXW')HVhva Fh\ \ |U0mO߉P7Ÿ@q'ũJ @&Ԙq>p{K+@/݊[M=~G"mx&+.ߜ?#*v vɾXxd(rpKQvnzOo*„ӉbG%71 Nt4;aUFP(|u4X…S«O^R=.H[SJw\?Vc%{Ҟ8"ƪW-d8%0H"*Oœ?GMH[ZaU@SbEOߏ5QNO~تՐWNm]xTw5!d`7~ -6}*BGUc!bۓ*Ɣj%S x|*FhBWGULʬM)Rv|wneBG=Hy!Vhڼw%aNN n|*\*6Ȫ&]F!QPp(Gz;QˠwJWƸM Z+T`b%i A?i>4(w+aB6f?n?c)Y,aPGZJM8U^E-PuSo8һN*hUIvPX «K= :JKbZ@pE~iW}: ܕ .C6 ˰=>*!S]Ӧ=Um uҤz}rԐ࿨`JA ;iE(IjFF`F $#AȲ@ȩrHBR8]HSPF֣BF7? ?lK_Su4W?nƖoڞ͊)'qCr G$PӉHhbuֹ`|i( P *<~XX0]n1 VSWZ}#$Ĭ6=}"\]C%ƉFRCM_|(@FH1G0h`"e%5x.mtnAfێW BK)>=ئ(~%^AZ-]'J %B'*\H!;\z*Z-6׮ثN$;zd0䓸24YvߧcLHU4߸&6.`TVEt?qU3/UkrO*FJƙVE6ɱW8<(!,|(*EmXaHWQ~DWzq%i躰  ,iHB==i$VP)O2,"Eޝ;}_-b=p%(]\ (h`W UثcnD⭾nTߴ>_qJ*'|UErzSlUFH!NJ[腟auDIqR5ȥog?AƄtqB^X'b;nAH I5!JOQaEPE6\A鑻 +B]H%:`)ŔISnLX7SQT$$lD%;7OP8n;|]q*GZ i^8mi}ԗK E6*Y8T'\I@3wI.y1v"\XYV=QJ{*+7;b[lC<1WO`U=GsZ5qE6]qU/HjĕjE~eבQU5Lj|0)v1Az7z\VŶHO+ B3QI¨_NU}^MpڭHZfU4PƜA\BqoSbUӌO? (^7ž\Rk&W3#8v߷S-G=… : UlZup4Lw2"I!r}hh_VL:C]S# $\M$RvߦP@~XnJt!O[S,JIƕio K j?т֝*gTOZd"sUvӶ@$h]`#@C]Kj\-G! +MOB+q)_P\XsFZU48sP动?@…PԺP%ͯVy|cǯ\/V/BrF]mJ#< /NHf$6ܑVMm}K8j䈕b+ $ȅ Jxdجhڛ{aB)TK{6!ȭyy*Ӯ*E,U5-NdPԑ7j:~*zG^"2&[iLbF- W2=1S \L7t`:_"E5v($ D(iM Δt CaZ0R0l;&9a}5 xh0~B$׈QL CHh:ptK~ Qȕ"h$ŢMpseɰ~*AJ/o%M֘BSFPGјE O}Ʉ~*!^c`ա$5ÒEOq,Uq4=,܇;⫥<@c!pv•bWE6­hMv SWG)U$^~I Ux o**T П UrrILU/޾ew%jB4K,I baa!OW&RpU-:%hzFn OV5VEݔ_nıHP;; '*M UҔ$ r26ʔ#8=>Y6 T%A<cZx~…HI_l*ޖAH f>m΢:cJ$W\U`…kRBr?<%.7؎q*+s^+v$T#'lZ*RRj; XUO b=IvHZCh@>8.{ + *7)D]*P{bBC#}٧~Q@ >ȲU AWS1jSs i~tmMP^mR%%F_-r5b#^EP:}Ps_Ւ TMkBIè#.E[>*㔆BM!@߷!G.ht' ]1f;\+_ U˶q8**:1W[\lUchJJ1G|A$$;*1V|Ub+G ⭰m$pc 1VBz 7R8튻7 *+\}VL*q|-P(Ep!i[ 9S`JÅ[⮥6&kl-zbnPZR< ݰ8 ^M\!f.]qU6KaBt I0*M j }(R=it8%ChJ_"Y$(*2xe)w7XؤWWH) яU rSaʟz`K֟~6zsqn Bv8FZ\9y ?n3 u0%qDW#j+AJ] IZTB};^mZjd(&O6 >ʌRj^p1Jq)#o_ՔY~U)-Ry2NPzmL y7,JCPF3n uQC<7Pֹk~#bZ mlRW֍Vyj )5铴60]և«Qu׷*Еe#PF«̔EI?P*CSTTRIn{Rd`} 5ӯMCxG` *)!>"6sE*wkƤ}rhT+EEKIϙQ0DI 1(ۊ)I4m鑣8@Vm IIm~Td↦RqJVFk咴( 0u*ђ(kNFPZRWÚ2w~fHnF`UX$gR?V$$ ]B+@?G hp6~(URY81?hwdY:qͽQ6 R3N]py5U ƵKȐ/+ҵߩ1SPHO ,|љ#idkꐊ A%EbڕVB܊],A*v%B) AB큓j\m LǙf&' VH1 WF#W*_{<Ͳ(6N>{VB(}2RbQ8P2ϨYۯ~*K}YH0{05Sg ~ INB%*v;{M`jAoᅊL o]4RTV4jIQ=V-Qȅ*(P+WH@ §j׵q rT[u$tUCE"[ =I G^Jj^06OZSȑ+Qڟ,#Su8ҽqKJxH_đ-Fh{kE>ZiVw58ӱ-O6NO~#_)(w1ͶLSKDprK":qŰA.1Cn!B;U~]ˍ=:iDY9޻{.E\2'u$u1ٴ Ж2|$7W.LXn6#*O'۾*y U bkRVSMI h1U9=|1)Y,"Y"⿙6 oִLAB.R朤Є )mMİQ^iN#qb~1Bv镘jH9~7^Vd$3ӯH1T}A,u1T2$#l%M:Vpq޵2[t[1CXx↉-bAZ-Z8o㊹SKn #u! b**늺**0 u8­P銴qWbVCWbW\NUhbS=UN=1WזRg$-qU6Zbw]JW\-p. CiӸxx4K|wlP7=UR֕8i\(_Ƶ8A\ z\Jӥq Gsɤ#t)+ Zy&-ASIfHK$̻zS{(p6%R&ɻ6I@>Uy([C+Pw銣rpKW`zo#Ju*), Q )W䦎{dq(z3S_Gb2A(WOziq%G=)V40Vq C/\ ,9zPJe6ڿI 6w=}5JRՒ]HIz_ȖA.I…4w+ӰoTzPBE=JH)EUR;(*Hڟ97P@33UF͸bN6PJJ%kLTɫUpPU~ªc|)8tZ"ˊ  !YFڿil) ,T [ ڄ=* |D{xSW[ee{mZ-mۚx6_qO5RȥX_U1Hc&Xu= @Kߍ~K Q :fɦm?k%[viOj{`J;V\Uf&=(Mw-޻Za%T \4;"ccǏlډLjȥ]MqwVĕ$ &;oJt…fGc89ZdZHrRTUiӗURԲ k#ӛ4)OՊ|;oژ>o ibPnA8T4`#+TmQUig&QӶ֔ :kWd:BQ'e|)TGcJBiȕZ&@^ U~4>y#Յ, RR @U)Տr+dLPlǏ$H<|;PIW}l$7:1WX ZMc`{!MV+%S#nȆEi ڊwW;N53rAA 7*kB- #b޽.!Q4!w4) Vy 1ly ֪:7jFk>P=IaVF(Tr"V6$ABExk+xqW튪Ȋrk_ d] V5-XJi/Sa y٣ CBN $5s}"Iu'L-#4%C()"mY XB(ǿjT+Zqڇ#"!Z9 XM>XP'\Jq9Zoݟ1V+n]Z]WRqVث*UT⫅)CoN⭚ [\(q]qW|URZִ??|>0ţ6-↎*)[-bZb:baUtZW30% .-zTbAvߊb}K$bÎX  iWu$⭎^~:`p2X*W_;W|8ZcqKC UN(sdTE# RhnwªmOAS=%`\r45EA.AOOjSqA KsEbRQE(ܵ2lTrmZh*+~'[T~ȯ݄DP? rb33?BWx{\'fCu2Wqğ%T$ pp2U5A`9UCs:lwˁT/%RlM UD$=SQ,oI@?VqⅩ \4 PzExamG#F ­4)LHE ࿫1AJbF@zA(G)dJ+@C@?MTB0!H[|LM(?U7<=:RT 隵7 ھإjև\(\umX`UDD=7XZw"PJUR) lңU7NM*J( 'ژ$.wح~bPc"tn = IuTȥJ3= ?**eR(UoẂ1\ i"BFUDkɍK}b$U!'T%W`/%VLj]hx `-?~X*T]Es@O+jVG޻cRF?kJ;(fUj+S (nx.*۩k}q幭Nb8.Ш'c j~ȠooRЕ|pR݄dd"TX lOqQvÝNd+@ߩɰU XR$buXP{'R:6ſMW{nd@NFB_lB>d? >˓X6W_TcmAhιbT܅GqRnpp_]-b#}C(_VuƼz`:ȩFdط͔mNJOS;[ 1`e~8 q?^IZ|[D4>:ֻU] l˭ġFd)҄UVaZ R-V9j:HMp䰨 ^GJשԡpU]ZO-bU [1WNGkl⮧sN*45\E*ثGk\qVV*(\=Ik.SCV\**1B("dJlt.8Cت7\U צ)_ *LH[!uSL!J(\ت#"N +⭝4^ |{bBm8b[A|(\]Jbb[]u  %Ca6Z|R6Z*H‡r%K†sErl% 1*t?NG*-X{IP-l:cƢI8:ĥ<:abvl+qIlP+bPz #F bb{RB 2YR5ańb1@5GL*PJ"UtqD잿FPj?!&KOPaG0ƒHڹ9!TWlR7U.eZP*sBA,稦 UxD 7o *8שڽ*7rHU5k|U^| * +PmUD\3y !InaW8ӡcVQ.⠚Q#қ/ )C\|bpHڿwӁ*WV)_+E.]>SEQRHU`_سvt͂J THQU:D(*;g7 *JfqZ n=J'LU"#vy(] CaMM%HG;y*0+Ab`AKhJނN;TJB+Eo~XUZ\^TaԟTXYd V4S4+!HvE_;ӾB958Z.B׹4 Fe+֞# P,[TJ$BG„=?dbǚy.O^" 6-4d6+bmͅ 0VUgBwRw f  s_NJG_V:tvM3~N ӎ5Ĕ!C@>aB0ҝtIYNѽpMwoDB>QZaelt]M,*+WȄ8Ps5z s(NA(?PUEv݄,!=m無^"(4~hhrִUSFǧ^, #܎ )cRx TR Φ5h)r 48FGPHuWB#xPi⨈+)BG';{[uP%Tp0S+ءMV*gcT~u*vKDy+hטnV 4Ɏl)N@4 AtgZWq*aBPCҋJbA8|iPk.U5Q/k*gHYGE)Cܩ"; z}߿߅Z0'pFJP׶@ ,_ݓ4*͹&:$„$`y!NI%|>"YIB{T>_d>2HFZN$LbM^OS HX7jw."'#75n=_Kt*lV\UA'kqW\U튵qR* X*UBS%o\(\Qp.{bU@v)[\(v)w(q\qJi:vM$ ZÉ{u†Z[(p«8U}8T]Tr`n!\PLU+n8PM1CD8-\(\`)pCU lRҩc*늪#|$  ⫾]0%44)lҾ.;b)M_U&BM;Wq( (+ -aSLY*B|*7&#Ai,zTݺ֔—IP:d|?<ֆe .#tGIUC!S_! vg&I1ݨYcq5E>y ,֧B炊Zem bJC(p (GZPhP WXn?V*+8ࢧs@+| cOjׄ+Ϩ>%>Kw35+?/l+%}R: L MkS|(S*ƌ:aԲS؃dR[5zޛO%)B: PԖlOC؞تST7"DB9|.Uؼ]8WgaJXU+YYG@ w * zdraj1PNuc_;d> >U"l:tRH ʃM8.[x! CpZiRgP]q*PV82PXs«EUE}ψ>@BRK3N.*$.E~F*h*~zGR8ҿ>6*!"P w"v!WBAn*ƪwj«=4E.:*hzȒר)׵:|UvZd|\J&4L {LZ/QV!iMȖH{m=袤$$O;B\]4ͅ`)S *֋WBܜ6$9#zxd! ebFuo rBҸZ|GOׂךUsFj Wªc-ORtI*I"^Xȅ|JR}5+JA}2L\肻~2)ixՎ|B@IO>jOZU T Ⅳ~Uy۔mڞ?G$kP8;ъGJWTUY^FwȥOQ֘JWARq8Uls)TE@X Z S!neOבڃ$nR1f?2Lmx?# %3-xWo|! B Q"v{J%F ]cE uWR& z(mu)tL+RkNݰW_살>MthCBabe[s؊+Ajmu)!b;]Cu=v…7;Z अF؟| Winua J ;Ӑ ^.c,;SBSh!+2VΔ,C@I *6/*/ "j0, ]@­TqcSV|]L(lҀWSGj@ڂ+YO\(oҁКl(nኸ;[P9rn!Z hO_$WFW*:#՗D-A; Mmjv'Xh:䐾9ZڇnrBilG%.JV]ByA୓wȥp[|USlb]LU U]zbUت'O[i/ *>^yrNҠ [C8B TZ=qWbUP-~s\Pi\˜P*c/M2bQmdd&"E®; *S*qWu /K{aCLUҊN*lإqCLT:W\U,UqI8gL* r;-' l =1V| lSF--++_M]hqK8Ĩ_S|Jh+ՍpA 9{` Gs$nmPAQ#,lIyU;CӰNM.RsE–dc2Oa;AzdxKT!TwVf0U-+FM\IXMzm^UZeJBOM$Ry,sTZtdܩP:}"HCQiT94. PM ##h]s6(UX)nO95n;f Ut8BOrB4pCr'A޽>dK,$wpB,j)˔`u_pK cf$oڽlT뀥bYZW|*1V4%l[vA;[ƱW2P6AZCdmԔצ -bPﷀĔ"^&m֍a+f@h%J=⨿ 7_-( 䑹G@鑻M/MѻRmiH^*4)Kt$ rܚۡ4ت߯VVS,CȷaO HHI}p%R9WԨQR q uB hm%!1[l CdyJ(A;ob*zEcJ֟rJ"tܝHRjEXL%srp޻Sq ZH]_-vZ_*kmst>=6Pۑ P\ bU7(tŜcV?TkRPW0-_QoU(#dPkHPMMzT8JhK僒Wļ$) `M>!N& i*w%xR ;Ab,GoN(rIFݲ%m-GZ=iE pG5An_ KʈÊXj@F‹TOTB&@[*=:İs/Kr|Pנ,dN;"1)Fe4$Rɰ_x4cҝvP?DKleCj*Uql7hR!yBwUtbFҡ/*s]a5YxPN$(F  MSb @I- eѨV;a* 7*ƣۜ{ }u>aUBzVȢelաMq k;R FGF_|UZ啙rA֕`4M@O߶IBB5` .鲚{aC^ ߶*F졾"Kn6?P] X'z;oH0#jSn`H)ZqfF ?l4PdH b טzS@lծik"Ҵ\=8OӓbEǪ_슜P:7`)lQ|?~* 2Z *e`rL\jS8C**қu]&8KK |_F%)b qK}Ƕlۡ8?Hi@rL\ǐDt*w o`K@P)W{ T9;>"8؏'WݴBNddP F)Vȏ+2һM% SEXܰs@v5ZY5'V1Hq%H_F}Wl@V ?UK;daӑ#hH進rD!Rfb% IaUKW~m}b̴*۰G $Bd<$6@R,\95%iキ7KnİҞ ĽF[V5Z WB0qVFUx6;\P!hzҘܼj\~Wޟ<(n97cĨh$ڇZm7Z[#" t .pP ߊHU(=ZŎ@ Jxx?P S;GPp%rqB3mǦ6"^S+"N iZ'j?!A^TH1) ?+<JOSM% 梵ۮ͙Q"mjB#%hW$(+պUJ hǦ~@`JjvKjeV൥yxth!q㆐ki-t@:J#L xan쎿 Pkr|r4YO*ǦUR 7ߦBg$ 0nT7'ףmzFP0t[HT+~D%_O"t=X:mL( Up%^U; J@w|H1'u}5rH2"G\D fV;PtX)rbϺR^$pWԑRz)})^DB!W#SFݞ_Ve2R\ךn*^R.̝6lUիJFݣe4 /ک'HRӍO%>T[`oz#VӺK' A GRX B.@u\J%;~)4Qoĥ[P"Cq-?N%TJR9vD^24O^)J?51CRk񱫱*դ@k0X1OT,mcОJ6z9aCz_FߏG^ ꡬm=m@=}o75e*M7 ~w4o (VTkW)SbOہ*x|zS=wX"I$8ҩT%CV2ZPF_{-QTV;}ؒ%BWo}ف̈lZ׫vxaBEFI_a敗,* ̂6rLTL(]YH\HH-ȴb_gRxbkJP|(K \ `*bb'|J(UOZ (Z7bƼAUɓ`׍h(}Io애փMC!@B@bnv1U9X(ض 2=MT mi%Mۈ j q?k? *AZ [ᷨ9&*5#6*uޜ׶)m" 8 qQSjx`J"#Wd3Jh@›l0셍T؅\d-HR{t͸PJ֣j4=>{m @VP lIngNFGVT#`*zPˈPdY8#+U)SuiQzXҨo ބn? bVF31UI*.U{5'r7Ƒk{(!G(^ wd9.r8  wanU% *kI=)Ocߎ7kJ*>=V3V?Rz UZWU Jj64L( *V8GPu]F|֍42ЎMP hki6?)HD-wpHN@{!l  /AW.I A yǽ؄ 9&-q,+QV6ZrvDw)*O!'fKjJټpBY\RFjӠנUewUdeɐT6-wH?.iGAQ~!J,U-a*w*F:W"CZ}i"Qe‚бPhkC[ͯ&'?(D`no׶FLBCr4 2%Qƛx,`' ҽr2H_8@We $;R*C[=+Wt[ b8ثgkq[=1W7\UPhkU@o\%2nrL]bo`JÅ *(l>b& PLR*qUPp`KXP1VUGT׀$…򬱊b} \ {U OՊZtV.e\~$paJ+z`B"]@NB1R60nwA;+'­qVpo(lO*׶+k%oץqU\ޝ1BFSצ*c탫.@Fq6 E:$E#RpJaJgS!&@ aS% z r+?d %(̻-h>V!ZSCaB= !M w4'hu튪+  $#xy#Aj6(a҇|T+tе4"FZ6p&ApRnE>#$p U 8juA3+N_V(6U,6V`UF(Zw|U8Pb*BWy%MkZ0Vhi8 `;%^4 j SN4ۥ;+A)~6=?olUM١Vܚ漕-ñANNu޵lUf/kZ!bLί 屢O!X(FE T?9?RGbVi60!7aZKxa= J n ZWGMzx% )Βf ,GԸ!hZR/J|!ً*96㊶߯]%o" *BJm//T'j(L mCN; [Ib|Uμz*ԏwp;ЊЌ*!e^֧c{WD!ҽiWBDZE 5A,;ֵ%Hv7]VLUM ;ۛY \J@qU9CRXƧaUkXݪH逤5$oHhrqD2C^ۏG%-q( Ж^R(T0"رp{bg \v9t[+O jĤ(0E5aUHؼƾFA YVCB~mu #(hFM oMLPZ6ȲYMUiq2bU ;-FF-0VXבNTBdJ>bn|1,AL1Nvo WIECw'7Mۦ*TO`ꕞ#a[TaOUZSQz`IY;lJBԥHZS}),M))dv @H4=1K)$뷁PO6І'[MgǢ 'cUT†Uq=NaA\ F*jqCD튴78Cf 07_V$JbإZAUU1 vQ8PS_v|BILuY+1>-GC=h!Bˠ`ߓ za<n0 BsW7*Q]O}%O†p$Qv; GߒBÏOHDzaBL @ J&; vQk#IY2r(%yi(<8/ ,y)Pf~ǦL!u~;| Vvʛ0qSۥ;x`dƦu«1mmT)U$.rCӀ^1)iOn9*9=튮&O銬HUhެ{t…0+XU`TAMPWpdU-ӱJ# Y-a^@u] F_d Gg(4SqU[Uiᢂ_ uĪ,#S TJb #[aB)Bl[6"Hٮ v!~J"۱'cKjThc)>*JP:Пo9eoǦMx2Bd>›_תRTj f:"e>q^Ub(r^K@j~ˑN%\e۰2A I+Fj Z- Dn^R$Jݎ-<T'JocNV4R؄$7CHVJ :+EE =<&lAR5%Hai"6$ *ѐߴ{W}U:HtvŪ焕Zⱬtm鏽 B5W#z0 #M A#]QhYjX5$pr…U)Δ¿F=A4ɱ^B,dFv kN&?ׂ%$)O\EiiB> dC'*w2,61WRWUUUءLR*v*uZW?S$†ۮ*H5F*$9BI*pIR +j7턥55 b8")jPlP㊣4-0F@d ;d"Q!R*7g{! U#olUث *r gQl)w :aCM*`aVZ N \B|1 Ze -RH;Pӌ WBxb{Ld(O!Z#jPpxޡ}HP7d5 }d979.ާj=iIPu…8 Zgn\Uk*m)J~ c3փBƦ\RepqC] 8BC>~1|%92F:$;e}P Ez<҄ @GZB֜w~I NG+gNbz޵ȳi9N% h!mһx)M,6E4r~;xXRWPۡm'Mx|? bIMNI dRTq/ъr`0g R:7SFeZӈ;x%wU#fteAAP@J*?mI@W,ƕp^A{>aUzmM|)Gu&ڟKD/KT&Ԥo{ (C ej<(1B55`jSH'z hF{o_iɸ ^B{!JFYP_SzmT MiE(7SߺU"2Aӊlr;8䃀i iJkxA=FY=7à#<0̿T=zتaBHȆEdw߷qsӉ> A]IaR)5A j(ue5o?y*y.#݇|!Kp*Ue$-waxbdGR 6X)U'4h4 oj5;R*ʀ-}?Re (㕖aCdY-f"JsU3$[q' _bbTC~{)ѸWFw;t4JеruſC PMw:d} ]ʢɧL*'S밍@%IpRTA_<V;9cSbN%UwڈzƸC§ژU܌o?8nV *ӽT%޽Ī.F JHBz oRH銯[a^0DM!/t66X1\%VҺ7`yծB[S+\wSw|<YJP%VFQi Q~Jc"+44r)Y-fdp~KOC2C@HK%C3v Q7u߮9"Jmʞ;Ⅻez)FIx3Ȕޮ>Rlۯp1UI RcBhgm^mOMNWщHMUdPJB*#u7'diD+@= O| ZӊҮUR@|02D5.䐩CATU|((s?bv}q|[PۮN55"1TTE´2*2 PP1X!%.JJǠ=RCBi)vadPhAo,`pYT mNUȞlއ"ɢ;b늵v*bUP]zb[=qVCgO-U]-0*㊹EM1UiTD")G&ż(v*{^'jCT[7N]Ӧ)hUpOAqU|p+t{br@O Uf_P[aCGbVtW(6 OS|l;ⅣWp P%x⪃Ȥ-'crH\i}VSb`Oݒb) ET8U_$U^愅<;bJaU@0*QPvl%GM?$Ú:ĨX[`>xnqBҼA6?0+ ϼl:Ђ2H ;$u 0f ̱+QOpJz0ƾj]ڣ\U|KXݽθ ~FQLT^s +pmb-ƔS;\UON*X c[B1 &OC//,`:gY97^' ET(cO* }Wp> v7SVpABens ԅPԞ#xқ.)S4x<`hdjت&(։sR)| QR HB7O%˓$rwT*@Z@*G8K# b]ؑQO(RI/JC鲑)%ѡZSLUZ7HSWVpOcc; UPl*TxE}sT+#)'ȥ^쫲y|_v Kl+yo $9(ܞOE& Nk6㊩J ? VtOٯ}U1ӡ W*䐶f֧ 杌ajI=*ILL& wXP~&u*^"]o18Ҍ ~t7A_y3\fe ڀa%#`TTUP7p%e ;WsPN%4aCJr8*}Eb)Mvm\!JD"4UP)n&i \ `M)l DZB*ᐩ,6_s"*W,e܅Ԏ*fniN~xiӞ?u5=K"{/U-OX'qB~Nv`gU~-2H]J[eqWaUTeL:b6k^Lxt^AWյ>3ZQj7g ЂFEȵ`ݼq@j6` aASJbSUP,}$+Z>X4["IXmTubZ6ƛz2괺&6 ;ኸ+*}*)ʟ#^ܜ X#N8P\0*tQv$ǒl+ckK2޽+btxX4#o\4BC`) CZJ0T*F|UӤ.FZ7Փ`xMyt,bӏMbV08JEveª6|?U."f?hG1ഀ R\!QdC+7JN͑T74 6#n۟|`UmO&@r1*`PH!kʹb]! =%Տb|>C (haCe%x;nk+J_ b+|#Uv(|NbVcJԹdOl&6K9x{ / Mq* bX l(wU nH-.iJc-ѱo(V$_X%ܐHJH%X֝XU{b5Vw'dBJM/VdY?9GeW M@XQɱo*UثX}1WVgk8bUUv*늖WUi*ۊ:bxxb\N*gq犴qWb V`W*t#)p\(_AL 4…KXUwzWl=B*'TUSOl Z;î8b|Uj1CX«؊dJZ[1[.]N`@+@)S> 5OAP†޸pmqUD}LV\RW\Ơ` Xv†WQ銴ZiVQmU#ZjYP0lՃ@٠h|(tB<(0aV6p*b璠?J=Jɑcm@8 )"g: ;b#}!  USh02m?LA87)5a5#@?TX +GU(mrQDe=X]Q_a hAӓ (Ԛ%܍`+_ow%+Z[5خ@2@ݔ CһZNKGr*% TA:t¨`|CoR2faª&QUxRR T@^tTEQhPxdldGƟ٫_ဥs) Q*I "5`;'6=)Df=*+֟bXPa+o+.G_0rXiҨ4er٪{*`f5\mUQ?!ָJ!vWD T(~ѯ|U ݛ5I0^ Q op@eV+S_ _!G(tr7ރ  R`jr}+ !xߌ _?T@z*FLj{[;{­ar Qxyo`{GTp5*Yf!Ͻ7ȥF4?w|$X)O@[[ɞ:\43WN.Ҕ E[Y!T"Jidֆ&S 7 /Piן ٜ}@?~P GotIsB! '!Np˸js_Ƹ-4]cY"v ~B*:&2zE*j B D(4"Eމ…$:T⫋a? qqő@ (i X$efڝJ:UO~ ?Fcc|>c熑j)S@|pz#~j$JDኪBv'cFӠmi!Z:Ss%ܙ'pChhLWLMX}ISOLZQL_ d1WSp*኷Jb-bUUǮ*UǮ*UN* TV08p%mk UPR|U7mVU0eK8䘺t \R jSU#H+jc CkuqUlU)\**va 4[_<(UQM C D-R2%ݷ]vZRh:xUqɿ RGVb쁁+#|Fba-a@i#OJ%rvvv(%IQKd=^ͷ_P;bCwȨQBѫ;:+IA PT>z&()  &ت®\+r{ b)t*HnI:JT1#o1P6䐼ȥtUPڱmPzbJY 9$}Yy%v~64LrHPqW9>p2Ԓ` *GCӏ6l_V 钬6(NXm]KD)`"hHtc y(JcAS|RU+B֣ Futd$rNX'p[lRנ?W +$W+uuYqEa`UV +@_U2@]†O A55I)A_?oRlT5zmV&P m]b3mz{\UUAcVڲGب{pHt߸g"j}Bn[J(EBW06wBĨPY8)aԚI:ɛ==డ' ȴ5A?ƕdah`=6cDeViLtQ\%BA:JМ%l. ni|miAeTzv?Q<*~- GH!]8wC|$ UrHc`n;{ ~1?;?*BbZWE ??uӨpv'B ȆWM$ܱ %-ZPnBUܒ[GlxcēOHhԎ$_ߵ* EJ_6j$HD1wߧ)X̖҅Qצ mJBI޽FltvU;PsC ^M\+s#U IڸPFDZǚHsW:⪎ˆ.u26G% @#v -CV%$V^XHiVBr;|| Z&ts mNKvFpG/">P%3: pQӏq*+MUrTJE+SN… rHTe~›.wby(_0 OZ]` Vڠ|%W uV=j6;|*.բPQOo4*t:o(7W1N$w?vDZjEnnpi3tPS8 XQ;ckJkԎp^py-ڵޘP#,w{x߹Ju۷|!xmV튶0.h%UV  VkB i;ୗWah4Aʢ#M- #w'`}?_bNl[x:0*t|pɩ®vLUUWO$h}V{c{U>'Èڵ]*HJGPlUY;*@Ќl-& v5De!ǦDD!&OHcqWSwg6-G,w55eRZp56(Öp TC=$J; }'u{_BwWou*߾**](qZU8▱WWUث\UWlqUa}4%KW~ۏB0C=k|Uk6)]JbVDӮlF]A[Ukb^C|qV*vaB| Y\1CX*)\1C`S\:R­b<Nv=1E9sA[Jbs+iDH4ϨX 5KjJ0sn>xJ`d|05 JjkNbbVddxCra0+AUXW5EvZU{e[,*|G… VmjI0;qBhNr)Uh"##&=W/So.Wq Hރ)XUWwW"8G*tb߉Θ ڸz; k4*0B>0OݘlŚ;` 6HE? 9#v`PD[\V{f  UG$mW7>M(DN^'?ho U*{1JЖf* *-OOJP7$- J qʇۮ%Q y8m>78rQ{b:v;}' !:Rb8dG`J~. ӷnXPRhXTһҟNGQoi "NV0 ?T=X8JBNz{A>ݛ%@5 QR>*>A8NIUD@p)E!~VF55=NZ…YٽF,|6c`RY.jS1,EVؕ +v[AvTcY(L(DKAK U?bY# VBymS-OCZQЏS*D*q^%*$1HYku$~a%P^j :UeE2ܵzm)p^" 3uH6 ОuUW1tquI4KhoL>t1F*%[ v2C܂SJN #ʼn=VFԌژJ.س­]! B8 "-y"kݼKǸ،"Hð j=W}W%^ dV 3;1Go$:p%UHSc1WV)Y*y;aSk3QF M8[*t# =f ; xXثTjՀ`z%bj|(R5&kӉ 7ܐhkȡ`S\6U@#Eo,*+Jb͵!%i JCXbإn*]{튮|(r+zUpZ j0Go*(-|(U+#v0-Ԓ:/%3 YLB!}KuژPx1W_l TY=+JePMwª(*~Xj?![0D3+Sb 0.~*턡ؖhzW튫M{r%Vz d-NM? BW q)tP;Ph\*9…D4iO_qnUu†>'ֽ)@;P+Kuo~`_ $5mU4V;UEܝLmW"S%B-g@F潷[A"Iڏ"ZGA>XJ9([D9FN40 ]"A'.jqU*D'n_ˍ*G:VAwV G8v^˓*n"TA_*#&Ŏ< DbN»VqN;\V*C.)SM!5P7F  3܏!eNL;/Џ냚8$W傖CkcIVKp9?|6ܱUƲ}N.]SlАcxF3@?^Jj$G'=[%mU$B=;v$o *{J@NbApr=BCJ V ʀ' :-;\IPR A$E0;xέG$=>,=P=M!&N*r'm鑤}p:xB ",7==UN 8!Ò4E ;LjB:VI.iB 0TP J 3})nH 158PVH(> ث`WwLUC)R{slQޝyd(+"&-lptWR«44 SqZ ]ZoW&lJZz╣lR`B CDQGr=Y9[1!^0$6>|WNk*7%Z*Pӊ {⭃:W1ZP1]{*Z~bsaaVL,\MH j '!KMPI…⛷6$ӿL(^_l ^aT پ0|E1TdRQ7=a⍿@p3P)5R=1UqKmqUHdV.˵@?v%W'?qJ \Uԟl $a*jxP$%-HQf2\j wEk9$oEISY9\bBB*SZ8E)J4b0RUw;}NHBbR_b Wҡt>*rƕ&▝UHRxwcVoхUXiM?ӑi$b^ I(Qi#-RC UwUh܆5=iZFքlUFBz3QRm X CTT pAb 뀪&bM6o㊮Jn | FGV>k UIA*r9P Qq^'I)4d L 2wߐO~V~-HmTc|G5ׄ]P ۗm@KJ3V2x Bݜ&m$9!Ee; )cBkSM6jo(A^Jev}~P J־>DzVBjh6jV ҏR0ܼ>y4"%ti?(Y#ĊȚHC€ɰ;|6 ZwmIe!(~['SP QBH^FMI ӨIoQ%S=h=LU)g9,EJh+HF WUݱ\! 9?gjb%b#Ja+V2kNsjH<: PCrVX?lND wem1)lB}]>doA M;b>4)jJ0JW4(ENܜ TDt[cϰRW;߾*Z(t*(JT$abs]T`+E%SJmݰZ"Jba@EB#vߦE%,&m*QJa(w"TڀW li$T H;BܚScKj(JbG{6)-{*9w[@;AE'Wx3ppʫUf-1ץ)BCR=}CfY#rl!Nfc#Rq~]5'cAUk^8!55zJTr!.Th7'aܧ++ Xf2r(˜RJ9/65`* 5dYzQڿ !ʼni`JL; 6^7 rCr]4+Gx!\Jx⪱@er{.倝NhBSn68mn1U˱ԍ?i A|*]S) 6ڟyª#vTa~IN |BJfjMjL*N,;~A*#&š-81t9MGZxD`ֹJT1^ J;v*]qVC\R*؅k qV`Nq4["b4a8Uihq WD(ĚP-tUhCQ z†U *AR 1(qZП Ukc.^ZAAؕφHV/#f(R_RQ]PkwU!nI:tS\צ *+lA=E0*1CU'ާ!JZźU,d~f(jŷ?ŐDKhAIڄ6+[\=D8Z;|XUIB-tȕ]/J*[5ªvҬ@j6ʱ( RObځW^RJ1MS_6%"a]ᇅm9PiFЯTeEf;x⨇oR7 Jq8qB26$ RpRVܿ J;(mC ]柦F TRj0+sԡ7^p!"|Ru| ZLOLQ)H^j:{⮆6!e7$*ՅD%BŚ>+Ԝ YV(Z=4rCn-XS_ Jdb*J RiZrRn *=*诟C8 jԀM{"PPCd5@c?$-JI N7…c۹V $ !<tW*| x-iŃoq B&RlfRӑ& N p;7և.)XC,A=o㍦2T/`p_sUo>xy/5o7ZZ _L"7IR-$k]1*p% "Bi|#WUfj':v*0 C*\n)`mR!-'R7a%BPMGCUvSoզ$ԟ#i]*AA…&bXaVܚ'R5jPbVv* RJqTne:9A1J*@* q 'jT ԡj)uJa0j]ȆTP |A[C`Jl8U_ v25+w[ P*ޟs^RJX 4`h,V=S**OӄQfY7j}0hԆ#? G gw#_lUw#p 짠'$e(AZiqi ?vdA *S<0EP.9&{ 1e$T”"Dj;dй΀+t$|[MXPv?F*C׮*NqJ-u}=F6uq%.u$a(3 3WFcS-iq5wl?(K o Q,d4 C2=ǾX2[pzDSQed6e Q%9Yh@z+^; Lڒ᪚H+{B !r `)ȥp޸aCg*ኻk Z­WbUv*㊵W p*;U%r H&p\(Dg%&5,W27IQǦZN ]K(lqV늵*(qZ…G_#r. .Jf[aCb2~.eJtC*(ko 1CSq*VZ`U ~حvT4ޣ Z%PBSW®ت4D2YT1k~X և5mK \ ^I*zo[Y#oAaU1)\a9$j〤)l2ҜGZt-8S U/'U>\əqBpDvVVnó!ZZGJw5ꤤR zdJB(n|*I ̀r@kO!Z_SV`p2SMڧ &} m@3A@o'r8rCds@~Y ش aWD?đ&AȪUJ%'$` kڿͅ d"r M:S Ji-AdWN؅uCw㊖^LhUG]2_ʥ TԮկĭP;~A[y8nQ&k5 dbG:| PFHƀmUe; 7+^S?RBOoqUkw9X$|UREpWR;!F`4cҘXT֟?}kU#zƛv+U;+Ȫj2AWWS>JoS=X׵Rt* K܄%lS슍"XP+rZ=q$mS|}%|2ZXN(m (*ҚN}إOتud!?+PZOMr0 ޣUR* }%!A Wza WHTAIm lROW$F%*Eब!T0,T:%AĚLR+7Z4 ھ;o[l)A۾1(92*> @L*:52қS.v  m4jQ1OҧHtHYKPRP b ([`؜8z +&~n[+BEzbTf?JV iFjӵ:OՅUG4 }KVW -7<%Rhۈ~B^0BZN#dоdem2U:/)9*ԞdUjҟ'c#`6!|D5P?Rd#c*R7ªĩ:PV !owj$-%RźHbsz)a-het#l* ] ^*; S31؝L(^Eҕ|,UKu+r,86&T6!`)!\$ϒSX)8W\(H; nW$j÷|i_ȥp45Z"qVV*oZ†%(lWbÀ(pRmf4qVvء8`K\ .$[ʸ&PYR[pl3 :(uG$ `JrG|ZA%Pm{bN?% u1UQ۶IQbVP-<ce/$#_nCbjBqJ&dR#FRv4>& I QT TtĕG[jN{q!ɉKBFݼr4ɣpojouk 8'|WN_o@f06$QpjR҂i V'J)ǒswR ޵_4w6 mT&jP:`KKSڔbӍIGBғiO +PRH5F*0ku1%;xBĸf #AALUZd.i(Rl@-:dylN}H N*WoԂA¢JWt &5=GcRݡVB{x`+,Zwo [H~)MT4#s͒B^øuE읿ekZKeOMF0xFz1! Is$m'Ji0TAc}PG@+޿N*iրt9z}X{p |*XKv'Vmy/.RzJr1Jwm5TyGPA4di6 *T?n$7 OAa.p\` ];Q;N!J5Pnh;KCt…x=2%Dɥx H0n#r)#ȅ>,` aVU2l'A-<)PFmRqfeqFI M)+Ы0^54$C5kS q\ӦM$ֽiJ}vIBR6=1U! %>c-jت늦1EyJuT&+ +xaE¬+QHAΌNⱩc?bZ׌ew}?aUs#ӊPUyZ\BI=SZR;V @^@Gc9P B׆R٪~N!-5Db{ "I6H*KSɟ68Xux╴ܓҸP^d-+U M!+. ~Ah* zRIɩ۠)Jz}v}GN.+Ɯ6ZCݺɀ$K?Txo&hIE**k>ݲJ0ޟBѶVV7Tk8|N(0)p tVP=OV'"\q ZliV7={ D]K5CAZwkH6:d|Ut- ndC"I+rU $"Tוcz tWI&QZ %A?@Z׼D )mdŏS\ \#E48P)BGT~ CE-Usu**Z8UUZ­ =qWq8dqWWq;E$d *o Pd▸6qR5/Պ8ءq.8*[* UWvo\**oܝB Ӂ.~ߊ?~;*<1U+(ln1UCKS]↫**| ]̓NaA[FAZ{ڕ|0jðp])u4\TlU)FT ! p1s's˴kV%w%d2 JdP]Wؠک nX }pهE!a%XUQ+Uj|*@}J|7(BC)}o:Rx)6|(sA~!Opvs(p2hOӅZ ⮄WĨ\j:lA\ U̡cBEj7l%!Z=BbT=[›> &Ӏ|iYXʰ*EI`,' ѽ$`P+n z6!Y ,=}@?w#m9 NÈ'ڿdJ=GS}*}5D*+O*u*W~N):4C-0%E FщhɁ<8| )] \*J 5Cim}(SdNIƇU0iYM\( Tnw4넪GMXS-AA|p+A9Iv>#(Wl4}@?x~υ?߇5kJn0"w۠eZS⨋Rk֕RNR H) $?[V+ۡoUJ?҇k(DQ O5DDI*zy!dRTU\Ud Z V8LvAP$M) $5E?漕$>v؜SJNL1\jǦb9}1)ݣ߷T7V7*S­EXӢiAm$1pi$x؀T8r￾cKaN-Z WC)G P-J‹^'@qU%T u>Y;7U4Z?vW3V^<dk*Ul(Vfe-|UWVolUS*]X Zii‡ U1Wb'wq*@Q*r6-pG|P)6`UhmpJ@}0]&2H]LVUͿLPFR‡7S.aUp%b%{o*zbR-:⡰JTwMW%BAdsN銹WjmrŠT_C#-HʸB ZLK$xb@AM (*{$,QW2ǪXܝ([\ i* ؒ7Jm?-JXD~'`>,2 ?!ٷ>AUŽHWc\,GOlU5u$8P{"{HXz݊ kԩ;K l&AMGH()$i$,ےks%@^U!QJʎêYtܝŰűLRU`AQ* {VFiXPֽ%qA_:ہUN$-xf銴˜Z9uFE$) N*'o…֣p:`UĊULJBURHx38UJHʐ؁NTMچ1Ke}U_pH0/M]imk ,\+AO+xb8$>c*Ob1T4(E(nn AYu)Iӳ|i Vj|kPC_H+T j?h6IiQs o](iHJZ |qT8wrw9&+1R63l9F JƊ$Vĥ1;P@4\P*}?61%˔w\4Q"~R,L[`x_aMk鍘P<0 @m*Ӵe@PCWs]jCy6kq [|~~}Uq!xb[O|r%!dJ96~𒀰3;!XbaOACD$7 Ro_*Wc4E[XJLyoQבo@ Ȅ&M{ *CJ;F:V8Ӱ'aXؔ B?V6~#HlUlhiO7C *d$ݑWh,w%ZcʛajT7#AN% M^kӷuX&|pJӷ!UT~J8خ2LJ!nקӀد. (?M4ཙ,F;a gC*Btk +F8GaoReuE$E:u|A$G փ nNsBvۦ**TLlw;ᵧA0FikO ;9|}@]㊵t6_z OȆe] Pcb+WsªM)=}T~Unt¢b IMI] 0%sJjj\@ t` +S߅LǭpjCMQP6N|T,9HCTn:͑JP(% y+䕆#J9O钶4S|+Z*_m-KGZFA@kmRӨ^=XD"E CZZWKXUrtq3ԯAdţ  L \j\U'ثf[q*'4P )ޔ; !A=& /n*)YB£|p:"J【98 ,o݊-{IśS[w,T8$zb@ZS~g  ^78UK3zd}~,)z|({a0+ 8P t4wU@ @ӈ~B}Z)9wqUYm$|A݌y"P֭"_nkV'fZbMڿ& GdC Z(N@0ń]hrL\PzaVh_d>'Q^%C⨐zRCқt=Gz(Zs'{0Svi M*2ĵƕb9%iHQAΟ?)VUjPo!$x7òa…`j(: V*{d  I#~m-> &E „q8N ~%kMr)Z >*}"PHQ+߾*hB|6E>9J:ж)Xgd,6|UO T(I N)^#nRԄ)UD(۶,HX]SNA^%LnMEFÐvz"K0ĩWqe"DZ5>]ĈcリT&f dےl|q*ѻhzfARk^SfOP(UGER,=r4Ex*,^/LzjWj;i6,鋂D֧ >ȥ)Q}8P1W(EiZxaB'JߴB@dJFy }HܖI_l*pIfªl)!r킙4i|1V(_ब-FI ʳWn֗TpIupRm@cRIU1lL V]:n*#Z]Ĭ52'ro>F*@Up7.v!aRШ\k-d>* |zb? ENuȨvb#S"ZW­bW)h/7ZqVzb[ 5NhRT إP| [ q V*gjbaUWol ok]LUo*Z­aWZ*:b *Ƨ"TI"`K`m\Pء)X1Uzo!qWç\RnT-0]LU˹R6]J|P0jp%a; Ur1B~/лWƨ; |=|݁WF&`u%Mђ]Rp%ѓC jt1PT[q ;*Z[`VP{ _p~2P?!*`Im | E+2% 'aW0|1cŋ(j0J7`h aV^J>aIݺ0S=p2mZ8U? `kLH\vN;2m̞@bKW$TwM5֝01N2TWnbVHH8BE*Z¨^F4>RMxBY$,w5ȀVkA kv?(jF)it*Wz I3ME?d IĵI22J! *[nW#IFCE^EA:ҝ6>M6Ŋ(v=aUDwy׸ |i[PZP܈ [ƕ^0`=ӁV;cD8R̛q?^!QB5d ĩ^j(mj/ŶuPq;Ā{n{JZJ|5>WhP&h .Zr%ʝj`U4*ƦdQƻ?U>i4;CmuǨqVS\U]abpOW hoDO;UmRsPhz~<ג^ژi,0'Ni9.Ly֗kuz%!][j%LU&rKL4x9m i+ Ҁ`[596*ZMHS,I]b{`vSX_R!ps^KbE #i&֛乡sIT.gj钤[W+ܐЌ{nvDDVNqƻn:dR2xM)|JTWOژ/bU{ ॵHUPWqқ1#T $.$ M kRW [T` Z;|!CĠ2C O%CQ8#N+K؆OUxt1Oli-5~V=1--#*s&Bf 뀪s#T'l&7&MTV upRmRYC=DБ}JG, [ `W#joSxwĥD+9$|U/S9$*$A;tZe[> R^PPڒ(Wh܅/d-6 ܑA}HbxrZ%'p܉pEk Qj0[8% \Vv ۡzW»aiWcMUe\Ejk[t5)s B CqzU'(pU^E( ȃlfP+|5>҇IS@F(\SQSJqlA|IZFש$8+ͰJHmQ_Ĝ6(f R*[br)Sk*)a*1VkZ VJFk6qK(l +Xӽ1U*\ثXP v*UثAlUi=𪤜#lJCdT Uw Y\(h_JⅬqK_*i׮+},ES ^1VlU hb;(vk\Ytl P4߾*=UDjz,NuqP);5DpA#bzUwb6Re<+QV*AV ٦^*؟…s%YkOHR"&nhjej~R| ^*Xt;` S qbCQ01(k K<Ԓ<7T5>LO0SxLr#bjFI w (zS-81)ĎuIjj /X)W)dQ*cJr;צ4~)w^}xJ }Pڧ$3oMPQi$3m~ʫȖ뀲 `l(Z9" A{oi(n2ǵARm'Bb<;!O:Ȯ3g,$AE-"ZaS;֟,B*)d c\P]s}~xKޢ|Y'¿Z9OUKR:bL UhA SsMfՠE0+WGN B4aB!zV#Zj6V*=T- m "c/Oa+@Tӽp#] Y V`*}LrSp 7!HpOZwM T h~AcQd#Ph:RJuڇ]EQ~Hd(T 'SB&Tn*z>xi b oH 3cjSq+k iZlQ&۪ {xbUM- r0@`M I+.m#ƻ[]VR(b%H*l[W26]$(m*zv f7[#F|~O㒤Z 1lI*zzbTj)%-3!)#q@P[bƝ?ciDzkBN¢>$:<{'}VL 1~5= hzBRcfr;}ݼ|Ó߮HY$該sVKg|wV\(Un ~ H] ֠߮PT}:}.Th7*ү!_$jCTWjb󲃑V(:`V5¡k U*h.n튵q8G*UTc4޹H4I' Wbz⫎!Z[ «jUثVLUb\|1Wbjvb[ p8DU7ˆLkEV$X4WRF* ݊FJ[ZvŽm/O JCơ~}]=0!)ѱ=pەf p$:lQD,U6!K`HF*sî8AF *‡rW+k8onCcQR MHUBI)Qqx8ErRPD$]8X(rFDY"+NAŒS$ĮJ@=y0Q`OJY̤ZSI@mMr SM׽wՓAv!<:kuTr;TǎoqW¥> l ?E4[꧸8 W -x_⭇ X ~\JVn'5=zBJ$aC[Px@|qTH1avJ`7NI%n@Jy rC1.K2V~_,UwF1\e2B͎*m)\jjpuVRɰmqUoN)N~6U%*@VVO -a֛`) RwZ"v;-)RȨ$:%^܊Fp%A\N$8p%zhA8',;+A]$\> [7jUJlJqqI[rQ60*MHmS߶(\Z5`d~yv`M?! 3!A"7**;ֿ`UiU~~JdnɱqRIA*T0%jHi"&ץ;m[@]w#0LxPj[qU:S RT-^,+ʧZR?i]#zw+ >%'rY Z7&=DDn)f4q\}S6l$r0kTbR<*҂Xq\*5Dt* >|qh +B7VV< "ہlUAWp&ֹ j68B`G^U|4"悴+9 |Ȟl}Cb:oJh8dbPӶHZА )QmUf=v_ȔC :݆k (mZklU RGXGӅ Ɣ;|imnl!m% 5MC`mB"V8ULP@r%*t \Uث\UثglqW7\BlU;H5#Pm\U`KXP * aBN*kn\h1WZbbW*6V;֔n †`K_,* 6)CLP.\رWx٘҄}ǮDJ "ۯO PW|*&F +V xdBK`Ҥx~UqC­1j]J특V*P1"Z &&ZWXS UqwU~a*Pg&oA!{튬8P늮]#mE~PԊKPx` Ёo\ Sb‚d dO$>wv+!J {J~"|p6CrdjCrU?%kctT/ڟAJE*;uĠw"Z{d^E^P9&TXijwOLUqPWPU"=H8U҇nVրU5 Pu퀪­}W*mױ(iw'bM~Xm*V0S;{`JSS`) $zKf">';-9S[>PӷrH85&!REM)BjSRqJ(U@6zhRm?] ?&*^Db~(UrU:ʟ;䐲83&>qx1b# NYɊ]u,h۱߮V,*v޿N[C5&p4!כ^aUhu3* $܂+RAZD AkaCRSCjabdcop$.$q&aPvU.BqAxD P+wŧ@iTR",(qM 2` :oVVh{I T`"Ľ6UPbR4HEI @J,7.AR21'q߶ߎ)U,kҕ'(^[ӊ<0NkS,?LmTUOpT?(w郚Q+lM޵#PG*ѱW* qJDd"vۊ/^ c\mihR6;U>Xp^E'"Re߮Bg bP5cA%Ϊ-=94q#. j4rXwF9VCE-6 ڟb >R؂zSKrz -Tq>* oAS"BmzWƖgf`>ʏGߒbT_2%*Ylc2 hp֙$.$Hj-߶(+klO4JR0 ,ZS|fL)r >x'G+\sBX%wm`dtzPfx` +SPVxצ)S[vW$W)=WwZ'zUيqһlR܃a^؅.o~B U;\iב,.F>*Ԍ8pc*D* ܒO4UGþPG_ FFSB(hG(THQQWT.$AӦ*Pߴ@?*GWE>I tzWsVKoz"TcdBKt$t2 !CaBWbTj~G$Eo^\Uj aL TӶ7|Z*HjOZȐ]J䭊bϱUXl AR?^ 1֜/0*!6$8:Ѹ q5)ʝ*ZeaKrm!ZGe*\ m#++1!C0ʤuIXL<Ю-:,TSrn6fNɡ*:~ﳁVTu8:2])Uvz}+ ۾! [v…B*#\%q? ': hf4;$7;{!T^!+O"K iF}%g H 6 U*x}m6G7O(TKm`JQ;U_a^5a5ct5 kZ|"V^Pn;dخX0$O?h`e+ZMk)@ :ҧz䐫$9Pq…Ƥ#6SC J ciKScm V᧎郚B&8#%O"MpRQt"Rx=H!\*jqWiŇ~!mG^Xx1D$(w8J~(TVUDdi*)s U,-GcC+N_؏ *.Jq#lU IՉ>ۍRܵrAJyCbI=im&37'z\м88{tkv!v8U;oC¯Q1XnGa?Y&-ƠZu'-䐺l_uM!⭡ޞ;`*p+ثlVLU.8]1WU*F-4†V**㊸U-+h&Fuȃ" w!|P1WN*[*Ub@ҘUP(뿎XҞ…͈V1W'pqmb7] ]ت;w*ޘP~Ȧ;1JA+4*׷"8΃@%Bm_ {|Kj64hpW  I0(8UNq+J׊9mр iF`c`v2;x46)X#-q6jZ-UB*•'|Vum1KOAmnX#zWaUcЯūo=(-:@{dK('MμGLTz`I\j㠥8tSr\Q_aqpBAǮZ+pulk| ZAo^QLD׶!I7W&bP&އڸUImF(\Ɵ*t$.ت=}&ҺyJ7¸ 1*n LIPJ5x!Vt8s7 |yq|' 7&;ҝ+[Ao5ccҔ¨{wB{h\X5_Zߩ"FN%=cP2Jl8DNhZ[b(|GӒ-jkUy)^ *ݞ#"M@L߳J_ftj%=!TG†(0UOy5'@6>=Ep-I G*[9;nzZy@ƝBBwx B3pEOQ­L#lkjjIab˖NAWa|,h~_H tZ▋>֟GTה߮'tr\@q0+q ¸i酋uiQ/Q]:S+BQZdشĊUtL!4*>WҁIۮE\.ىKr:÷ )w!GZUL1*CUc+Cqm|R(m߯=Yy|Mn|pUcS@{umMHpH9SbOh>!{$D5Ӑ$zr.eIQ `) J C )-!@Q#l}1u|1+YAj/kD HDP_`ZW")|B\)TR@^ucm,R |{dxSjr1-B:6T68jvlnM,eaRk%T6L*.֩ ;w9&(蠫 'Tnw X*{vV^Fm ֜\ Gzb{Wy=pIUE?LNg_W1w\lC|HVBa Mk`ҰC(_'$PKHw=pz± Ro*ωiP@Mz*)]H) p$ҕ>ت A5;츪Z  I5 B:?ªRtn EZN uJAS" ijh 4xz#2=ǷmiKӌTOP^ Ԍ ;bZM*`M%C bȫT )k8 )sKXU,P*p%늵z⭆†ʃmoo] $w ̬"V,\qW1-bRP؄*h‡`K**l†o nj(# W\8Nc[(h+M[ G|US\⭓@*Ӷ;dY.Q@|U5ESޤB)%-Z SSָUڣ0rWV$W Mv*McqZ}2SUo`bjCt|XA&k|(mNت'"bQ֘HHz(+EkA\vznXA؜Ja+cс\NS  K -? mЅX\BKpbhW ..>pW%n|r)C:$W+8S^)Vڨ+V˾YڃztZ$\'Eƻ~AKo0Uz'JVbv-"$mp+'o|UVĻr F`K=u{aBQri(m 6>p?F)XA]!~JA2uªܐ5)Zva l*7Ġ4 U`* O&+R ?d~9@rbU^kAإdƞ;}85hdSۑM WO…]$J@~> pvc%vPv 䐴'#O g= ;Ѐw8+ۢ:& ƿHbnwN+4b$jw0jW-CJ'[;{aBjJꤰ܎3B$`x LUsafIQux G+)EMX$(+Av«H$ }UP(" Oo 1r5ALcXT( youR)Zby!xTkp٘TJҿ\Y\7HDVd? =sSM! M{d'RoNQ%*5w!(j) K L(< ` |N5za* =+!J qN(>^?UH{ኮ*%|h0Q4!;B[^ǠǮDDrM æDڐ$ hi9&*mVUIQ>-,(ZdF "(VGo UUT_8Pңr@1'e:Qm2S8(71B`W'G+qSK{AsO1Jڛa J~<Ї3;B",xmSBIz,;wUkR0%P&#\,k=H !(J EbjORbI؄1Bk䐸ẂVǾloW!`c%1(XlUrrh~Z@GݸŊTS~,nv^_PSPNrLZF*@퍦qCqk' HdB]Z| ?y=ّ|;b䊱$J+@]lÚW8U?q(3-v&5?V!NޜkqꅴQ]jv,)P&n0| ?VD 0wEi WFېھ# 1xǶAH3Nh`h]Tt~b=:B~G@5bðjbS ZX=p"%C?´ڽ*j`T(\@wO-QS\BTrb *( 0/s׷OHRUPxa<ڈQiN$ǚU، `J";Qi%H),֝p&]4FGSd$YY$J$aZJyPSzm2JT!udݱU[IK+RQ@52 ̪EC0N@58 x慉 Cتvm>lOL _Qhҟ^)jr#jGC@7B9؅*=DƬD{o(yFMwa*{&x!bFPtȁԣoA<+!(ztpGٯ_ EIæIiRA#P*<1VuZ=qJ+P;U0*8 aV]+i\N*^P 0ȥo,*BMa[MAIP-bS-RVv(v*Z6qKWSlP- k)]2rr >(]q?TWҘl W$$ IJSPs j*0j t#i#.?aiߝx O O~xZFz@c ~ҷn=Z'p:03PR[I Ty[ f|vjqV̓nĪ۠QTJkL(_ǒxťI=Aޝ*ԗN6Ɩ8T,hHQx"эhx+ThG u$Z (n1R? RJ#l|@ =딒\+9Q@k͹`k*\ d+wȖJ\}J(h+QM"FZ'5Џ(XZՄd1}4i@>AZz( y!*y SSW|i*,V?$՜MӐdO*zT:3@XT|_AzOPȆE }T8zAرݪv!j*^'z IeZҽwi5aB*=AʔcZ^CEfv$dT*. 0h֝ڝ~YVJdb}ObUKenv VT*Ε?\Bm\XI#nSCa$hXH 7]][#F jG\ w`P_጖0?*~R*|z*j974 WCMee* @ BAY{v.H֧)IQ/Lr,Aʟ$"n?#/U}LJw qW"B q %Bt8P%ǭ2%!QXplZʱ940JM%H&t^VEW UܱCptbɡp:Sn4qJ1K Ŭ*wopD`W6l U̧]Ӯ6=&\4qlqVC*qVx) Wq-UثaI lUtI5W6AqBR nX Z®*zbצsa \N(k1V+k xFj0׌bK ʐoP MJԐP)z0R6X*J8}j=."&1Pq/9WT4AdZuU;/nBTxaKjV]Zr)iרB" [Ppq^G>*v]QӾ*w$؍ @H؊|bIrҘ7IC^*Uܟ m<4 y$˜a<(? ߈jqU;Jh*G[ ]RĄԶ*sOsM!UT'aAXOZ*ƻ;*7{BJyp*6&yunaKL@iVNy]Jc}䘪APOJHd ;ኹc{}تōI\WUWT` 6+_ '/7,/d2Rv֙&+R%mN%U!l7O߀ DܐVx6DԍcZpjJ?ퟞI[m→SPXUŻF^I'fdBJ^'p(?7mFy!((wT+2W-WcTW 7—&;uV0B~XUe1Uf"O İ*;(i,:;NUBJǨ"̟b}HneKw?cx`$˛ r JZYCBqJ5ckKK~ۓZYx}s *D]^Hhin^!9uqVVCu[;OlH# *#8h׾q⭹ *u?, [\UqVV \; vpi\(\ ]2hbN5[*1Wv7[h1KdSlUVB㊸K{TSWkp]qWaV 4†)oN*{bTh~&W|0Zil=pت*>XoP)LUiL*5CE‡]t8Z{U7*`) aUYU<-UC0+xw8U?^0%j^GこgsH1 8)r,z(G. ]ҿO (h\RڻJe^h}^V=bJ X=`}PGCqzH# kuo`>5]K`fl9%U $>8+RM, CU+h w!^?[b2%B$0v•tɚF28;dJ]Bj:S ^m_ǰ«PPH*ÏJ)Dhj\ݟ$8Om0ZÑaU/W($niBHS7>þ*ߨҒL+Fz5XUfn6TT׹Uþ*P|?TQC*jWU>'c튺=ªrt^ߘ2E8c9_"i*ŃmTz8j#W$MWe>늭?:ZяCWT8n \/'@B SUSMڻl+|Ձ+$b 1'ǦȩQXN&-#Rێ=J)ZAwm$,?|*ՍRڠ ?$R@Ͼ*FR߯jM8-ۯ'4~(T7z|2$nr[ҝ C&-!ǡĨl1KavژQ/Հ%oxn͸QcWq6cHT(ȿi[:RMP>BFA^-ZoCኢmUhgaG 1cHs\)-xX5=b~!􍰪>H>-Gs!]Z][T(%}ɰ_QܨEG#n/g)ڞl!;VU|d`ƢVMQh< ܩJ4jdeObהeB6T{`h`;d3o@|kҙLm퀊d )(XsbX?v߯A7m/WA#-<2TR[F2ʐEZd:AJnTIsZS͸U]@ I!u݌io Td틜RB0C -S#s%ɏ58nbTφ(Q•NJj:H{(~Py! 'm$I=T#׏Y(2z  * W8?P_ *AF;S"QXǨ;柳 RQWjn 8>1ՉR|[%Bhw"G +{aCg b]v*Z'l*-†\wQWY7.*?$oQnczd\4Fq80h늮$C iM*/| Uu(RidOZ)P>(w.;/ߊUEZ2m8#e$r+J̉S> rJE:S ^B).xJiwZxt*p)VPSWh=m$r,zTA DTdEZv4(n_ y!{nJTmIZ)l׀%=1) eF?: n1V{⭁o1*V(XHO"یdNY$9N%.i6q"L"5@*?!<늺f= qvA1\(TUP]qSROL(ke` T miM >cm_\ [o),hM!kP{Gb %v…w*@y0,qOlyQvv1C!/@ӷo JR*ā^<2H],;xd@I*dPCGs]%h6ɾ2`u nHc;*Fy7s]xTT,"< cvkC%Cc،*z\YU#oh*lo N1UX-Q*R^RlTN%B3C5GF@ܖk 庍E:퐦VfG _[%ыR$ֽ~cȠ)mԏaB*|T1탪TPrTqp eAU߾F\0D8=lWq-kGEP`u#$U>r^Iʞ"`b6ꧨ9&-Prw6*튷 Ud֋_\BJ7Ij!$MI j9#JFX^9K)׿OB ETٿpn)_mH;b%j!c+vXU1 ٷ)6܌A_+ *wm/ӀZ~¡y(v1'0V7L .j<gGJjW,ĝڧ|%Z8V.LE{ƿ¨iiOvBV0ĬVPVx]1Kxl}#]\v8|In} Pظb-\UvƸmI \F*/w=0%kTV֜Rq S(w/UC*®'q\1Bb ";v¸1>JPaZ[_ U*qWx ]ƔPZa5ރMʇIZ6‡B(Ab)L0(zaCe HԵ#LBJ@S5Th:VTኑaJt鄠+[=(2%>jnpU n=iȽsqUj6-N*Vp|T,(~c" Hkl(\[w1ޜؕ@}yAȫ+3|BvRö(_ס!JPAw@PGр5Ҡ䘕f9eZ%B2%+:Ks_q ߆4*>Ĥ5&T0s8W(݆SL'N!J*@ PvH Jw*(oOq?)pqBG╇>Tǒ5 Uv6)1*W-4؄sbT؏dRw#UC҇lU1pc d#R2ȥ " jVՈSђ(B( m#ap%#p4Sl!L‡1ZO뇚-޻RSU*IlJcO*ԂQL!Z#fԩ22d~2R$3vv**<qBѪۨ;tĤ:2`>+ j V8ؐ6%k(hOT?*xxG)jjk!J)51+HUKv[!dBIڻbT+@OLCpѫ"}«x'?1U5ff|*E<n}u|5낒(Xq B\'a 'l)_RZmbҎjiJ2T@OȀTm\- 2 in[+O)&7G0*vvE){)Z 1BMAbUr(W ğ5\R*9g.<\7#;;!FISɉcڸy!i58R ~?[IITr7Д #CJ 9?eE?^y_|Op+|&=1UOPWER~ؕ @^AC&UJ$m^bt* T؂:Jfd?H?"2 vnO[Q ?XM*^k0)j8ȡثX⫁*WaVևaU *銭.8U[*RhjaWr|P2Uk1 VaCWbW(hUU ] ]֘P8MqUH[x*t*0^Y$ V\UZ)qEYܬ(EYG`OǾ#A^(rPn7\(]q@<:` S' \Kn(ArHloAm)l U;`]$uNS oM`SBTסĠ8bP(?F NZ:֘ >վHlN)^l(oiKѫL*„odUmyKZ22:aV!j4)r|@,Bj)QU![ARZN AhQӺ•y]~)R xxa1W6&c^P l V,*`Bwɨv8Ciኯ19?ZtD9cOmTJLX~9 ݕgɡF{(UQAKHj =*QڸUBw _ׅ q\ YJUWbC-:J*櫰ȥl}U1$({SA\@ɍyT8ڛ8+HAx…u'S_ &=Hrztġ*F4XU)*ĥS|NÖ{aW$ӹ銶< 5h乨$(ƸE4~!Q@"iTPsOh䴊Cf늶A-S^aOO؅-@jF,JTƻ\J5%JWaCIPxP @vmHnCğj-/7 (^8p$T6SƟ= IݘGua}ݩV݈ٿQB,DRڻUFU(+䧛mB*wzoRc vzz*x%B蜢Oх PӷlU|@b?DKmxU!xU !Gإ(h~`JKɖ:2LUdTi s1RM>>F,UA#\GRF/DWaNUV(x?-1o20ou!%b*rㄫMZUr(ۧ\G%pYS^'Vу}[4vVߏax q TNZ HcTPexÀdc!t:QbQ S*%(QhLwc%5J1Mm@ڇVMm?|i!^?Xt6%AO<(^bI7 m_nND4Nç*FwݽJժԟUbhpx*C|&qֽFZEv(Z7„M\VF o d26˚UOkdր |#9d@jG6n!ڕ#ƥoGO fg.$v>i hiB}(S"6P N8Pȡ⭍Kb*qW ⫆v8UuqV %m+l]Zbw0%b#n8E*zo\qWb\Um)]\qKXdm  ƽqVኪĕ Oe'bت? |3 Z\1V犵\R*Ur-NWN,*K~T1^FJPx~TxaCq1U|J;. †Ȧ*Uڙ*[+mаv^ns!NN!MFU.[m@)׾*+q"AWa;4$ 2[ׯlUrUɁ+ЖR7M++=AU'{P#$Hl=y RrXƦIZ7$ī÷,IjV8`L@Էr)Ȥuׯ-? 녊W*L W:?E*%hM<0kMzĤ/u}SL EaL. B}8wcǥv)S~B0%bwmp9qU=7#k7 z515!tDD>-bwCd4@KFO ^216tW>?xBU;}Vpiv!~%UzWSy ?d6Ǔs߀%k1 ښ} WJlk!R>0%}q_J@~T…EA? ."FE*jت;lK! >#HjN*qUQ6P;p>0"ؚ*QZHxSIZΪAJ`+u8Զф?pa%[rO\Ua~߫h68PzS%tQRa% )H 5 į-qR:ӦBzK{zjky* =Aj )5v+AI؞إvOF͖ Ft9-ڙR=Lj!ͰWш)Z ] U # ]l\BKJ֥T` (lg؏t{Nθer=Lim֦|P䑀~$>1X klJJ⢨;WJ)=*#VA=`*fM8xzםW|)sR5cVcTO^'aHsJ0+,`1UUAS'pcRVUђV B ddhX2Ҡm]Kk%+Qk倲 Az(]=7V|P)w*M ѿiH1[}w8JzWWxyljqJ;B8~8-4.sN!I>;zc$ wBT#犅{}U8KS(\ |mjKY&fO2XURVJzU!ۍ1RОUO۶(p|ijUl~U Ī;FǦ4qت!r7ke558P+@QN(U:)5c5bԓ4"M}'0B1W~4tĨW.}m\MC=r]Xl ȫWb]\UثXgpс+pqW|UhM0[ '|PW,8PUw@~C['[׮7h u\TN*b*1WLUaV؎ءrQ׊*qRmCd+-0G*\qKCmEw…T/lj*lR|Wb.S`)p_Z0q ڷsbmX6iHX1V1UQcZ7Ti=6)l@*=0;ꕵp%E-I WDCnwacKW7a#ɑݾB8j*S| ӧemN48PC@O1UKQQV'+_*m )Zmrcʹ4J#R<#xy)5bШJ(]T86ݶCU?~ED W.R^0~ BFNLp޾RiS[+p^#l]#"H{aV۱I {W"O]ASBY ǒ'¿I8Tn%sOæ*ۍj|[a)u PJ4L |9aU\68C=6\] eڃm⮙ qS#90rKo?@qU_A+ĜGӍ* r }QT*C PS?UUtU XtRkCz*@?hW,cCSQ*s_s R+~(mW=*vUwm)Xǧ…ސ۷j?櫢؀ۯ_r)R&FBy ĴM;bȧ`UW&3>cߊ[O׾Gfh5<=\N1S-QӦ5Vϟ d9F>1!ݨqWxSGt-*#0Z.8~Șdj@Y&+]U )AQN S<4;F !.Mmv#ƟQ{F6‡EIHlH=F*bJq~8SXB l= QACzuB]F"bMUL%}+Wk\!Re6ol(iщP T.d(7Yۣl)Sbh 1ܓ2-Ġ:& t( }w;m4f*c؁`*BBT{ A䐷 [|h:u> s~}0Z`) ,u0Ƥ_ (:#oBPupS0$eQp2T?RP7)YJB8*A%Yj;S U~NM) 4p>?a%gN1B;7 Bö$/C70kȧ@VхTը#MԊm+Oq,k_`:`) c6Ƒ7\?aO~ l8P9 GP8̅Pu%Ynݾ)I[jUurMEWU]1 ?dlrCcjVP-)L)]۱ȥxlUPn aj}5Ĥ5 +EN* ['׾<`$h9k* $~! Xq[ZUXSȔDUI$x#? 59$5Wm1U7WFyP|]R1Cw4cBaզV4aQvJ  TdRЅ>EyW*MPEddB[pG"%{%M韲É銺% * {0ӅZ G(VWkgC" 2I"kM*+_*G"Hh0tQ0Fewޫrs{JE<*ZYzaU-ZS wD<BoX=~CfNKHD35qU[#VTM J|$l4i`5^[SrHp=*Q0= W+,#4ɖ#eBBn֛dFDLz|TW#E Qd؇r5 " @S@=qVjր\Ðl 5gpp1&B]j{)=*5wVܰB؊Ӿ2f"7?F4kҸQkp>ǚSWHhv5@0mT D0t$0$E6(eM b 6S|!a {RVojbrۏolJXv$W:=lUb`fr}RG؊f+Y\?@ qHPw8BQK~ Z#R(E[2 1cJ୙#̑$zu|dRy&1* ݅ W{lDuNۂ6CFHpmaTM#z-y!ziM<2HU 7"2Oe!v|`rՑIQٕFƽ)B;s$UZԈeM>m*JW7AUezcS6/§ڟR'%@%l[}0%b+ptQs8 p cSS4\EqVmzbUaVX⭓qWSuqWSwZ=qV6* ZJ(\Wq5\(s b*Wa^6a S!,+HUUi†-.* {` +H­*XM9  VJWb1[Rn%\FnQȖ)TZSzSEƚa_?ȖAb w0ui@~q=wm;0;n502_  Ό@0IjjiOL*Nh$0NX/#[Sf^[aGbJ7=v5EʹUS˛^$wn yA}c R*w9%ho1TD Hv+U:pc㊭R9 &P~|%xu^UN^N*$OՒ(B:&J׭> j_Q(֤C^IXkZo}py8r*xǡxҠ4%JK.*HBڸmDB֧j)85bUl;2EK8±jԡZՕM^Pޕ'\PͿ TP֘eF(y*,zs#P%ܒO (xJɢ5qTMl5j.IdT l%mzצIG늶 ~x)Wjd:R/G&u mjq+_ㄡխJ0$/l2[d`o (FdAPTF*IO *<C0y9}_U*YwcivC]NPETb >&_%Ɋ)O2tV3svo'.krÈvN՘҄(h~0TЊt̛V {W/8HxJ$>jqU"j}ĨZwZ Uk ~UM"s19 "C %HIk8ڝ: h_AY%Ē5ォkצH1+@d޿p1^W-mRmV[0j ߶ҍ_% }4#VOooՅ #J^O1) իSqk dӋ$Ob+P8yp%MWu*zlU5GMSF†ȯӊoS« (yu|*uV*ү&|UR)7|6H aB"۾)$Qiwzb@d.RE >54;s^.bg\ d_{tmśYȶ JBq%|'M(81n6I A w1,B((sĖ%̯& t[FZ}tI+0 AH)6 ҩr+j/ђCE]]Z8UءUbvj>XP㊸ Wl**w.@69-\N*p \UUU[#5]L(lb;W*p«x#*/YSb  AO0%Hp…;!Jޘ昫: UĂaWnZQmj*kq~UIO*F5M=Ӄ?*l%\U?"R^uTLUbb XR3J퀅Av*9w -O+7&|5L%Ckrܖ"N@4 =JߊzTro튮iZw8iiN-i^k9aȤr銩0sd^%& <˭W' +;*^T^؄88VBܷr% ӄ S(: y'<.,Cn୓m*$ծ%Th{aUPC4-DĦIΛerd(aOɆ%ehpqoq;aUeP["R:'PZckը88U^5M{)VkvkMWM!JXEӅ >JAp0h*M*;|HDYMyB+8V3IFvbqW,\ rZӿݪi¶q£i$"$bNUȀԌAlckMF~+r˜JʾmQSP8PԢ6!J`Pãl}Zۨ*G* M:.Hԫ hV8T}? +O}rZ R p2S Q}8%51\d`UDecGڀѾ#w=xy(J~%Bx :b T{ &W枯o:dO&]P⡇bs"ǖ 89')J? a? fT veIm 46*+wZ:Z -F>˒b~"X«ʓ͸+#v89!j-?g!،Uk)_懧īqƽ *+ W =p*^@NwW$[|?T(?3eu?kjȖJ S$PC$|V?@}!Kbx~8HrrLU_u(?́-,̣ [p!UZ*1WWjcmw4**<1USs{KI>aCVWlU‡k.8Uث(laWb8Ublt]&+iኯ E6+[ Q8특v!Kjkצ4 *v0GS ZzW5[p%r |0 )…4-p4 )w* G0RVSPXUtGT66WO\ї~ݾvL*aB (^ eqC`t#H6xY!:bw*d6|YB> )p;ⒾA#1QF0~%_ׁ*kԡ"F#ucM%QarGˮ+̡C{%h+IG ͯTo rSQ!}Rz"VVdPu–}>Ga탢R"WR2)ZbR8(UxO욌 X) F).-UȲT+'prU.ۊ%_,tnK?kn<Ҷ1ND;{aBUh,j|(]>JU /du[[.z(a*T8GZmZBi_~Z0%}pr R0uB0 #bHΠR(Y|^;bn1bPS8JHe2YZdT1N[R>䐖-*~J$=Nb2(5>B P/ JUahvmr2,y2:7(g٪x{bl8ڟ l3o Y6BP…G&?g)Pc7&$Ȩ⅋T`Wc]i>,PEEzFncݺ7*+b>!wFjxU4ӗIW|jʧerg;(؝ r[O~Ƶp$8xV† ⽶!kyu 탪bDI SUtհ%T_c* uz ws& J(h>*UM+5~}*:UvF7 1:cHYoJwRmN*vZQړQ4a䔒I߮-ͯĨmOSdzJVi۠iԟj 9O݀lIJQmԏ4GQҘ〨[\Uٺ8sT~ݐ,BCR/ݡLy੯~]VB@•!‡*+O UуQVaBBw=pwIPaBL+5R , bjm\W5^Uz~*G}jSW <b@GdԛS k#"p?H'GT54%vÁƟ-eܓL]-U4%bRP. ا٭E0I*BDBjn<1 P7 %=I MI>BMS3쁉pHYJiY@H>dRU#|ɾ/ddw*4u=6ȪOnP=Qd1spoci_wWqʿV؅nm+b8Aw_ ^R\9|_,UM:&*R =4NثHMI>V& [Q|U?٦* J2& W*qCCv"}8+PĨs~!jnM<0 SzaW9lC``KDC]xbw |Uwl.=1KM(qWo MpLU|UثZ‡ኹEqVhxb8*㊵\Uۜ q en0%O\wA8:*!yQKS0Zi=*:PU{SpqZ[bqZ1K`xCl+0cl ;V(Gs] c[ CCi V %Ԧث`PxlbPF؆EG,[ZRl!bv…ըUDZxX@ 2,F;*[ a*J?O|J1BOj[^0+ xPbJ@C<%քPdF dב`=rSJTbV:ާ5ZTaBiX-e;l 6呈$5lрĪб_dBKiv8SP"@7<ҋ1G"ց@"܇Fz4, 62Jb8SdEpu6m.nH>b:T#IMI?IVR>ut!x`܁(7sI1UKUکp% $?!}%ЁPʴvcHSPъ&<WaVZ`>+_qBE * 1 P_ݹ*);X"U￾!%k"@zG?I @?`UG( E<{4ڽ1UUkAOWƠi=?q*uqx.E0RȲSWUmXG4#i ]J=r=4d(jNL(lVqW0*iWO7M4*6B.Ǩ5wer,^X/kT5cJ vFF+bk,t)ǡKL>TJ5~T+K$JuX4Ȅ˚խC I j=݅U`!P?FC mBj] O UL> q) zS.R(F({b=[Jُ|k\B>uC}uWp_/SoIQM=…_x;RyؓF%BdP"KdC"w^ p])kJV6To*P_| 9uF*[®†.&U\F*ߦbG|*(ZJpIڥ 9l(hZ1 ;ۮv‡ *88u…5-lUX`UF$:aCjUYP?,Uw-B*Ș i B79&+|U(l|1VmN⭕†0%r`V^F1>UoUsWV Rו@FDlo)I트)q% @t)PT2.Vv^#gNJFK Fے@un&`qJ**<:b%!#sMx|,fXuO_ .ȷ+MJ(+A'ژPӾ)*ܼ$dE ;2QN+CsOl7Cs5ޠv|%mx5zZ,!Z1!FTRҫqJc|-kaSB kJMm*!צC>&1 TW‡CW]~-Z}{P|pP'%'ۧȲ]1KޝTS'o\µ#I^UzՈArxNZ8ڻ݅ QBzt'POZJC\FwӅ@=AD{V@Xx`H[ABWlhPCF++[sQnj:PtW,ZX"4\@v4?NXo.UU!a҄LFH$ r)myFF'$(Q@*VjUaՏ!l(YŽU5$p*(':V0v"a(FRH@cFU' B(]Xv8yl՚k]Ⴥ6oL騠SA-sJx.oNE Q=rH1;b+&­fO"ƽ¹KmUՔ:+cde=i B<2lU`߈'Q踫GD&XSuPz+*Jj(~,WF)_RaCS|!QFǸ#9LWD $P +'ǮiO&تۆ6TwLBJ?IaUňO׉@iLRvCLUz%V"aR?@=r4qwݖa*|(_~D+ LmJW7?'t\1W lU\1WV*VDmރ#&QCKND.d 8Uc\ h8PqW.\(l[8T[v6N*Ww*犻犮+A\Zk VUz*;'ZBE %"j=7}8(r)[ I@0%h†*mWh.PI|z$*/XژUiZU^$t#TU R4pRU?'ȲZ|By |Bf J'ՠ`P4- tŚ^'U tPl0銵 LSnI5ՉPj sS˵p%…8PvZxtV/}6 n5ۮ*Ib!.ǡMGA\ o4P$Bv>CaZ WbF˜u>FXQE?v8jm _Ȑ~cd)_ @# *ꢟA*|JO_ ш}ء|E PO9X,|)PӍ F #փ疖w"T5#Ƙ B6EH Ƽ*\(V˓dr!KQ|*S,NvӼ.$чCHE]3$jN=yli*w+S)ߥ~ ZƧATR*5gPXZ|q<)0R W(_S\PԵGȺ95 q"Izs ȥ?n渕Uh VnG!џV!o APA;mWj?Y0 o(Tvp8$R[mZvpн6*+EVAF>E6#&%д"(Ra㸨䐲M#5SY( E>!|CnIހ}|.KfTЁb%CBJ"J4o##IR2ףVv ڑJgx_:51 UToWȌUF}\v5Rw N<5`IM8Pfs'`~]?8:lCi5dqn8I|GbJb/L(U'TdB;TJ,w#)t]ٺqdG?k z!ȦXRw X0Z }V0!TP*JTW6ڸI<>hzVe:aBv„yy} dIJ jvh')>1uaCQ`*j_v*0+VWW VU굨=:Jݛa|UP1V*኶Ƨsu8(Ux53"()UbSv**㊵\UUPqWSl튭늴N['l \ET8:M*:(S®=ӊ[W#oC¨ˋ!E;v=.:r'v*4Wh l LU'4낒_ >x}iZ"aU #U+Y>E5b B>|†[tªiZ$~(*+  VtHPN"\Tek^>'AnCO} 9A£ml?hn1by˳Z>p JD/Af6Uk+>["Y^ru&\@3;, | q1(U^xg Cq1}P%@O|J[cZJozdR_:b1U/ĨlaU*;}Xx 8 B"`%f^ly 췑*z)SsQd7N'W*>whiJoN! H8+P0`h<-cQשUD}\#t '$VoޘT5QM|!tm@W?GLJE,J41<*G'.U`! `` UQ"IZSƿ(hVMJxK`S~B%h?VR05ʸnzrEP()C@ubȟ-ۗ/i=8U$^*t[?ay? ژU܈G…phS"IF_:XI4blH KTd*dG銭Ye GaZá5Z?fiޑJ$Z=N!J #2b8|b2%*!6 9Z D^ B l!A] 7T-M4ą%. @()mڤZ\ +C$SL(i>T93-W|,W_Eځa_ญq4aCaBO~]w z,bէTkZm^D pJ4ߊFB{ 3J~8P;2-B[%83u7Ě@mKbJDGp2MBj'#a$írlU+AM""_TdY-ܭ:pO⮵R`A?,A\ت)&Y-)[{teW"-1J"yEO1PP4"Rj~C ȫXckov*ijU/T'#ljM0~885UqWR.8ʼnv\qVV*|UU]uqVb Mp+A{*H— LU{ГsJ̓gP; Uo\ h (_=%T…klUPCb\(\Dqk?<*. p߭r=Ytl1U22LWR?#.oUhmv*>cUezÉq㊩z(]"%NdL lӈکC}_^Yv u X*7WT>(nf+E>+C%Z!Jt9 -,zȌά58 x~8`<+iKU$Ģb$)4y/\ OlۚzPVy 3w(B>8{JR}j\JC; H+NF*t*;q,Iq! ƩTT{큓Jk0Tu~U=1s필6Pp]Z KU#3 \)dp+jxZvi>UtN"B ab>M˹…iN)6^?cHj4L`;v'AnE)}RBE?U0`:P BBLS<į`i˰WZ~8I ZsUOH;xb\5¡xTkN= OAecvӲ>'ՀBF+P<+bRRF6'r(i1%8G¡z(UJx>63wrLTj֔ĕ eVGa U23RkL*ԕ+O#8 Đ6Uzq.`4ej04ڽ22Eޥ1)C %+nOG& Z`JBMXxH^xSi*T\ ȥLxw?$Š*i*H̅7R*j=7%72&C^+O&uKCRUjzvĥ \P@UW*5VSv,jrAhUZޜHm;86AܼLZFm(0pR9 }:J'ʴ#޸EZ]1VO|U*(ui][[;?yZ«+VP\UU}$pثgkl늶qVbz⮦**qWx *<1WPW­ӁZ«I~ 6:]OaV@NJo6\bءԮ*qV\Pm+ ኮaE< h&|Ri!sv`Vh (l|@`<86 $_h>XtBmb-Ѝ+g1KBSGMVλ;~86~sl¤ZWQdsIoN/sч|HD{fHǢGѿ6;R AI*(ĢW}:`QͲ8<`:.~8$:5'qee]:bVJxW R=*0xڸ Z^xaBF*|*5 }>`#sۯ)V,# v8 Pr%!@ol6W^=b4ڃ XE(tgq)qCL~#NB&!]†+DmOL*($Eil*2z`Uxқ<jo) x=O hB;}إɹ+(z~"8oUXj-U p%evv†rGoqT3>u4?H9؅]h0pBHcaJ-G~S*@Ҕ{$P Ajr|1w4?N#CeztƕN#KQW4,> jKV7'탣.jw|PVFIi~ 4 4آR qB d2րe$7H)!ҹhy_45ߦ)iq{@UH!Y((zWFcy,; aU/Er0mh|RiZ@WAT,[}I9bZ7P JԃR@Daх~0uIe'˜y!"O%At3 b9)T;n*S h#JMGq\Ȝ iʾ*Vm†OQ7hH^ )B}8:UsU)BJ;7 D2v"oaU{5^F@O@$BH.FiW%|4=%VW?dt ~"ʹu9i [rsW J7VĨ Ezm ,xi8P1Sɩb w TOn]"lTt>G* ;p%|t'oׁVEb+VwccPPi6U?tbHb_bT5ȠJJl  ~~*JLd049Ϩ9~=?#d^ˉ)] GZZ;|QoI A7Ȕ1*z( }!w@'VW}{EW@_PD I* )*X !v&1 *P+Tm*0+Z1*H*H*hO8:2ȫVw|UثV+c߹V䕳V$blUv*q1KG8.؅kq\*-qUPw^Xd\N*qV'nw†)\W_Vh+qJuzbVqU(k+:aC*qK}VLPݱWWhbe44' §k_JL ZMF9E~ rpC=U}Pv I.O *qۛUFP>P2ѹnƔ8;mA-(Y JyRz Kj+rMd4(XO87Iwll%SF}@W\,|gsԕt J0j*a,Q0 ^_hw-naaBpu(vqN%qpGljE>GjYVBt "P%{ɔ <|qJԟzy+jx0 U8=_㇢IfJU sjxo|"Pz%E"@oLJZzJ_%(ԃrE*s- )D ~$aPDS ZA?`M;Pą]P~uUƽ1tRvp*vb@-Q!؏*=9(wGL(j sߧ\J~:| Tb=/?e6kB9$.Q+jFS];䐨E@ހ\[c\R+ĤP% .ol qKT|=U~x닦$/**#RbrHUP"Z .D]Y=F^@{cHvp.diTq)1 UzSV$hFCFᄨC29'rI'HG=>b~3]Zd,uHBq!A^n؝PIiiɱQAҽP+늭S6zacrGͨ{`O&r`awHEy_0;b+I?NXa]AfU'߶)R )+N*zMi;o8m~ث`⭂I tMQ;eN Ǩ[]aP8^_MF* UNޞ5`;HR@W^#ӃN4>#ݿ!b\UYQ݉OlCu#8ӵ 0[튫Z0At񎾘cB| 1BȌFo!en"h1tKoOl%VPYY6 \׵ "iim77i@|2dE7I$dO2R PT?| nXt*UثWaUKv*pRMSLO#bYb\1W}V]NثklUU]\N***b*z`)q'l(haC|v[t QV\Ȝ -A;pG] `WSmVǶ**J|(XzbWثC]\(v*40%)[-S^TEl08 TS +aCjwR%8á/c $Gp: 1UDz`[[Ϩ\QM7xROءabM|prcabv]W]*\cq* F:REwUЌP LjB1+1kٰE^|CJ0a'\ q]c22\}P{` 5튬k 끓O[@8jw$b0TCW%CL+*O~ID8>#nɋO#=CV;8JLyzrCĞ1JMv] {zVZ Y9MV8a45䐸*å6p*P9$,"d_"SL*ۂaP>*ŮUj8d}\ 4Htl AHhRJA4"=zA}d (~xTWlyz{U-ۃCL*W=$d?R}0F}*qR-S| ZHi"@W톑n:Z} mE9s?FB2Q ,%T8 WI*wB9PǷXf== [&Ip%tA)\(C،(]N@╻S}UQqv} R=|(h L[A2!tDTJq%@1ATOLTnDd *\άqPIE ĵT+w4兀ot ;ߦJ&,^VXۥ05PYJ\ zB̏Ҙnhr!sA)hNUbYPiLّ_45oۮTk$X"K@LUR%&EAC\ c֦Ñ7kOI})U,(XUJZV)WK=VUUPOb? ia FDtI *p6N!KGA ߀)TVDHaN|Cr;_ӏEkcLBޟ%V۹݊fQLJBbKnܾ/ QIIv[Ӊ`dĜ? y&(~ɥb7pT i +☁*[Z|*.!NPQ ;WPt[w!P)p?UhGVR Ӯ)\F`  ǖI'-2%T0ad (}F iٻi ǐJ-10J}Uۮ-l*qTb[)Z̛T,9)?H,SUoď)Ԃu늢 ˘VGS+R {>o!RN;}w51UF5t1aBI$|i;`U|tїWr*኶)*[8tL S1UjH5qUI2 S"mO$]\p+cG*Z8Gq]LPiv**Wb8]1U_ H;Wbbɧ\UaU u*mK]W U}n,LRAml B t^R]p銵\0*}d bA_ *7 `E6Vh1J) R<0$'  RֆV{2UZvUZB? *4bڌUpVbF*kL(ڹ!4ª6П%@Z*㊪G 'l,Hi֛0V2DdV n?Q\u⥆uk*mA\,|O\bUF`w* 8P(? Qѭ@Q"8 (ohz[VSr+ VLUp銯.ZVOlU9qG4­ZxIT]V6(IWɄM=H^`"m7Q%Ŋɉ ˱{RUJE[r@{ҸDA}|6[pi\GL$!׊3,kAJuM ׏^QǶ*wzUtenrX'*wTfv7KحVZnf.C=2 URA}q0Ĵ7: ^Hw†AB:'|K?ݗ&T0KJ=(1斮mc ֆ*NQb5~=1UoW]Ktڸ:QxW ZN (X|UV݊1qB@i0=FتS%Wl*ۡWe=EF*94J!Ue|YtS_jb]S'I^ÓПp*q UrGH7r4bUjlX _PU54 R,'€NCçu-K}O|B]KI^X Յ~uUB\#HªI$J܅PxaC_^Z6}6>81*7&,:t#RA‡ U[}wl*XMpت !YxAl1KV5dm15>qKS|LhIj~Xω2[@߶M H}=r$]s,JJ܊;bONGVW9ՄwɆ-v(q銢a! #YJly%`ZS-B 58So (j~b;jbo~ nق:t VIT{WItV ~)*wzr=WWp]\Uo .#b[=qWU>xdA\V.=vZ[8k1V*UǮ**pZVM5UUU_eRh UZGlTF܉dbm#$űMzbZPU&1V8@wmK@xbsB[&qVL(k}V*m~تUs B0Ln=T#jgہD OA\C&NCCJ/c[H)UnA\)R|(ZzbзtJ Z0)+j|@-WN&道D[" zbչlzbE+[f [\Ыcy= T2=Rw K"+CzWc꼂،q:raP}K| ⫑uCaA<V֝p%Īv>`T?@!Ð>5 V!9$*TUwHx}#$IdkO"C0O%ȥQgBWj2:ClUS7>ؒ^@Md ] v8T%A'5&wھP1UMߦ(Wrӆ)vZUX}1 s)#`Dž`8m I`i%+; (ُ]y T(\SS»[N=XWo% Wс+$s߁P0js3~U%ʲA?%hy)wؚ*- ~69v(Z@hgI?rA|RZIMi_ׂI iQc Jю5jBC!Jv5aXJmaU|!s8KANRljAc`V{aU)\w ֧}VB9{$Ga"J䐇]LJlCH2*fnu)j*AqU;FJ<0I,fԜz/V+!5!J 0Lj>UhqBb| jkO ";Rbl!V3E,FܗRjII8Uuh?cc^UZ~ҧUkHVKY_ mC9JrpH^… O@pKէ(X)F i|U[儠*;!fڠ5>!Mh)CVC5XA_)_bT(J*Gԛr}B8*s͘9$p$'ӃO%?tObi]Ud Cpb"$䘫^Y=qr  〲Ti 6翶(@t&\* w[nL(H O)roJhhp*&+@W/8Pe=G&kuHHi~-$S+l1nD_4n hkngpd.:.NH  h+B| aCJ5ɡ  U߹#R]p§†F!?ō+ۡ,)P5paCPpqZ)2L[sBpğ$*lEiM)Jm{jxj@ 8 09v*1VW UU}*۵Ob**]]qWǸZ8XUpq*zኸ⮦*hp%8⮦)h↱U-ӱ6$u`'}^RK` &bjlp :cZ;Bӷŏ)uj#T:fwɱY>&pEȫ*8WGfKv BuȒʐ&-Uثgk]r銴v4=Vgk\I[\(l |1VV⭞ClUb'1 تߞ*]^8 8qUXz]⮮ثc*Z?v*|(jZR8PT bm0+]sZ|K@T(n⭪ Ui‡ br# !L68j68}R܍F?~WNT %GL(_JbWFk ?VހNI5:ӮA|h$q@ z!Z\UN9wlUnSt'aȪ9A 1˭ظI8ClJDk#k P5U&xȷ61^k B1Vz}p&#Wx ]5?V%BZ9%{BA he0~ qqִ0(U zbQ"a* >6Z=U@#bȫEkCAP75­uqUu-#0\I lB~uK H\É KQЃm}JHJ%PRX5Iqՠ78d})JZ J@!+JA \UZ)> OR $ӈJ"=5~>%V[)fQƟم UeaUQd?JkңzOaBOnF^SP4%Gc OE]Qzֽr45:6&.3@QSZ?dT-/GC+T!QH @&#uoBm!V܀*ȖAi? ?Xt +P$4> CW\)GlBSNZ,x%GaCFqVI~% G^%RMA( 6!}8:F֔0t@f9'^Ɛv 튪Duũ( x@x)PT7aJB0ro+m4H^cP7~JQ# }rLW@>Xڒi N)_\A‡HScR+|!w…r2dBNV޼rRrn…;EmVH#kPzxbR5x!Qzab[tS dEG+^iZD*)Sr1)l˙#C4Q [XPe U *mT큒|ⅽGb_|R"V+(}AȂʔ9ɱEInOjQQM*". 䉝٣WdW( gbI~xV Z .?#p+ ^+^5<* ،Jj={;byG#2m{ IH \Dե#l+zVkxPՏSP#8RQP,Iz⫉TWB*8KJV}+aɧICW,)⪖8Q"Ni߅Zh ) ɀX*K­(_BVBڤ_ÅW"V >HZIVF7QO"VI(.8>:Hd ˉVd.-o0v*_^$w1J9(SȍV|7ZjZۖ;=SVSO RHTaBǍv됰ΖomI6)LXͶd!F RcNȫxWbU}V⮦**+\qWW ڃhlqVx▱ClqV, s CV\U«݊ı)ZOau1Wv\F**8cq*UlU⫏3VB8h#6EqVC&p_`iZi@(hUVsOJ **<0u\P7U|P*mL(mFhxbĨCdi#jCJ*w[58𡺚Ptm; ۨXV*Ġ,nǮ Ȱ-ԁ02Z^îC#Uk.:G5dj|4?ѯ\UPb+N☥V@M!KC ֝>xLP{TW^D 썵c Ӊ47 8FrءzIWPMO&dO<(Eؑ+nk[?gS6i[b41*! "L S#}0}-b 0]{|h]pBV&y @߶,y7,uN"U-~`l(*TWd zr8v=; ֢6tЊDeRȱF:xbIH (Sb p0ږr=ŊmkEr%CPЎ{Ia B0n}T*KSTI[#Q}۾WFi IvƵV]É 5;mT\Fِr$CJ`U/'҄}Ji‡3S2 +RJmך7o Y,Jr !5WJ*JsQ %X턠*k"p #*24@HMڵ%LXT﷈… (»}ثa߽1U2v!lcV1;A@J+"كJsJj+Z9_Lsۼ-PT**O=TZִڞ8PWZ?VHb-(-U ;rO-< z|%bE•:0RV|pI] ^-1( RL@I*rBC5К*Ҝ(UkV) m^C t%HgR68`uڒ G@+EzP$DITcYI`CSZ2$$ª\:kQ}*%w〤!+ܜiZ"努\AE$7q䘶X3Y ρߊx(X 89s)LR֕PbHh'#&AM,bt\4P҂He`~ BȸB Azw1Dbp N$59/r€Иmָ)6ڼUz+6Q䄸5}!J?dcهJJ]HCL AAҕ&-\MBhqB&BhPNV.0>F eML;7M2Cد/^ҢL% <|[zkJcyU {V*~P'|0w|pZZC!$AHTp+l[`q逄N zZbj7 [C5X$%N Z&䆇$EŪ X'|AWUi?y!.L`Ȍ KNCAj0ҵ銶H>]qU[x)##E Z x_YRkzP}-HmvK6$,i-UV~u†&. JǪTP}84foJ42lU@/qRk&l> {#/c0:i7T)SEdv$(ZY,wI43DUKV(O5AP|dӍ;xUIGP$DsI")tSMf*tݷU8Qኖҫd6GqPB*}y1ܬMI5"0®c/sPE?KibҵFkQ?V-QG*A8 Ph>wT'Y8pkJ 0 (oƸ(i@ ܞ!ĚPp(H]DlprW\8Po @G#_*VT xO%@;n|*nTa!BY7䆄 ,I5=N8⫐THhnqW8unqv Nˍ6~ESdgkcS`챞KSC+/In\%RYP7:DP1Zm-Ơ# SPmD-ZS ǀZ{ZCUZ?ΘZoF*{W *"B5xr4„J (xn<)'f@B9>Q5;Vi^ 9IV5Z…ˁ]]GߊTVZw})ZQ.(x!#m酊=Aq)TH9T4p5AT!} ~@ֿv*I KzQP!h $dش6Kco`J<@;P,)l )UBӑȔ[QBNʢWz㇣%Xrl*i(E0~$={JP@ ŪO=(pQ6K wS%mOlJ?e[߮*NGQ"}DCq諒w$I {T+ř5ԳOJI^%V^%Jԃq. ̌.zK >[`KR5\(bM\(A!'/|* ʚ*I#Y)h &<~&4ZNqYڃ  㿽pSN9+-c3)}QdE5"HQ7b(U(|+Bϗ|^,RYhC*QpyA?FIAv5_lIHwq^0%{۰N^$~pY=!)ku+bk\{u-!"&\*UTB)Yl(\_Iq u8ۊp x)ܜRd ՠ$lSH1k);o+ݙ)\C`-tp?cZZ ɱDOQNQ*-zD7-@EF&P,# uN!j$P:)&6(я'ߘ=1Uȇ@ Ii 1*)$7r20zH5OlG%nȤcB|HR2zںNƹvƼyɖj2UkSȌ G +JH)$)m$`h: RGrHªoB̐@ڝĨS N'8z!RM#5QY EHpQ Xۯ݅QWnmߚ Q*|w._mEwZT}-Rj;p@tJi\%miRGlR~lRb]X?^%!NAC"'("n`Bps5qD^RF֛ݲ i$ƊEF8qPS8ZaUqPTdBW N WaBKh qUFI754Wi$.6ݭSEWwZa,[ `֘J !Hw5!#$T(\(TN7I-#"2٪$(*J0k^I>]SƇ Zo R M; w0Xb1ZH fpIhHb Q9Wq_l9=n^JtrlXFkh>1WbU\p+ok `WU[=qWWsV* Fߦ)p w=V*(mbWb8bu-b)v(q8WUث)v(]?N# -`J *\/xP^*]7­ߊحY ][qB 6Mp+aw逫@bQ @ R~G9Xwv8 W ˨8Pnw}<- cM\UWn7OƸUmqCW<4;T(\6%(r*N)O8V5َFԢ.S%;(/qv_RJ(|Ȫ$xV!q(A#xr? ""OGm1-FṎct.â{ PZy%hAzaE*YEXl|zoN$N]>x.'->"zV(F•89Zp_%T=7Z6;l{b*B牂T"-4 RGBGBTo˨UFQZȥ!PIHOdY*$^x߾:O=6TbHT⿆.ؐjrlVEH~*vqsu\UJh=) ذP)*RwoY $*OZ|I…+?l%pujm46cO liS ~Sƙ͑&+cVHJ &sZ ~N1UFRUX> - P')Ǯ{b+Qq*x U=aUĭ|MpuK|,WbTU+WPڸR6lj0+cRA?Z)0.?cܟՅV]P JT =F2(B 4MpJJ܁H4b^ ľ!.1`õ}ckJw ȕF*q)jH?  >> B‡|UU bIWy*).,F'O N̂M)bF &+:17 +2}XZ26&%eÆ BȭiK!dRzW|(L({?xKk;w\UԦ*1Vj*7]\UqVJRz&m\Uq5(pGӊWt†J6 xC U]ۮDȠIxm+S 52LZ*1V⭎WbjɌ╠aB##Rl ) dFm$ +zJY\(]犻 VzCh1JӅ]=W\*6qWW qW+i^PuRBG u]JF(* $뀲 #F|F-q ]lUhp^!zRvEX۵w«) .e#R] ޾48@9w4UƆ~#EiSS~Ss\+ BXoѾ!$Z2ZX{ڙa^',]P:nSb}!%#I`IlPo _;T E8WlUƣ7*ӝAS7#ȕPaB\MNۜim7nGbS? }X r$6dNk5Gz~%CRHo\JBf]nV&<%J'"z in|%R&gQ@zUj;JUSC䐽(_կl SWGaHv8,ք-%`Q_ uXRQZx ^qO"R#'aOTE1P|$ej}JT$79*)BBe_HmWzָTliUUoiPB }*ȼGAR6lmW@9}a (Sц̥YOi*3*[I,4QciP#BڒEqUDv`,;6ž&ܞ2´UZ u;}Fm 1B?#֘qvĨn7hȑ* #9TmJ4=LWU LjVFO!@4#FT7r=6UB_pr219ZPWu 9 ݗD5 3 nROALdV# UJ-}R`iO`) hPɰ\sL zofjN>T: uWE׉=ZT%!}/ff#֟g`>XIc1Tq ?#lc5Х&o&Ǫ RN5ª?r ?k0h'fS}ttU(*5>Umۘڟ¸Z j\UV3Ʌv**~ Wyn ƸB TmzJe#*/N &Kj@8a51KX{1$ҵF89R)m@ӷlrn$W("5;W)X C5xP>*kxS 2%tƭƘ-L{dS@1|rLt'*E:aJ$Xa!ՓMq(`:W$ᶡqZVS+AV8PJ?iQHZwM}䤷|wJuX 1ߟo `J*@!Y;H"r=>8CWlRBI^48MGa(mX|Vܚ6XpъnBwT)Ƽ):Ki}\ӗ Ɏ'!O㗵nء{v\ #ژK`o(m(k_⮭"#0*Wms)(a^?ıIBOdjz}G)<9j\b^ιWHV<;偭ծm]7!EwEWM۷LlU6rq݌NH0*d~#bT?koz!)2Qh6p=B*:|v1TLD;C"4"*N[⫆byb{h {vy A d `ZsM4 SaC up}TUyxR5MFwUp#ھP*LU*⸫*bC@`W*U}HB0**$ʾ$ WxbbBvjt M(­qŪ:Bֵ=)ױVV*(Edl(0\ۦ%U^0U'*SKˠ z~!c85 l8"]o[ !MnpE|V W.;튪GTO+!*T;xdY+Zݴj*9Ripf}ǏQmE;&ӷʼnJ/)V:U$} !ٍ: !IV^d* Ս+]:^JF% p#;AZ(ZM)*L@%= U#@JQRz`) cb+TP+OEB8hLjT> Fڻbp%wֻoP;Ƥ|G/)P~{>r!X7!w&V+uZ{ *_hSHmPqVG־;zJJ@Ơ`Jh? A }U9w;wĤ7 l%P}UZ UN9Oy&-<6)qZH P+i'S(HH6끒+KqvM(:ƂO$犅_Dbw@Nم*y02)U4,6~dSP׏i ɺW|UAI'ڄbR { `&aFԜA;(>`QaA@됦ƋQRGݾKkJb$P|UQ]UF5ď)KㄡK.N )[~E;RX #Vu |N*Q Xjz89(>'(dOnWRv4]R5~X V(U"> ap֒F9O32cj~!˻$|JjO!T6|T;lZ-M(q*.3;bQ'枍v0jBV!k0ƨkUM? VNJ阚;b7pmҴٓaZvO|i(%GAd +WHln^o)VX:P ӊuṥ\,v*lPk[1V+XgnqW]R:wWʬ oLHt6*}0⭂qVV\7%i8PP,VM]\qWb ­ uqCWWq]\UpRGAJh8VX~UHV *WD1SM*PUPW)u6hm#q \P}KIޞluh*WQO| l5k1WL**?;ȄqWcrhN銩]/K| Z}Usl=-6*8:bm%.bj*Ww;R>2HPn4Q w3G$" - [NWa.@w,;o@RH YCQCƈ*G1_*}_-+^!F\BobT+\FNHfï^!Ph+_- # JCDB;$ \UFX)Z+˜Pڊbk *ҝ+#,*:mUtt-խ]'Z BNV1!mkbk] *U/q7ik[]$1(DO,8 ~+e@+]-4E(pD;PaERPoEW?ahp75ĨZTČU4Q͹&fc]wÅW|90D$|(j!V: [j{1"j3T( Sm NJ%qI(O~*cFn@~X JQ=~1>8z1{|r}ȧъM@yK7oZ8PqP=ptJ4 xҽ|L ‡b8ߧFG%9I[ 3\R4)CSLRIw!5i^;}N/ph UXȫl:/ثVؚ -\n6cݝ솓QS??&RHB0>'GREGM ZXzRԨ&`B-К U  |B;և@ESS '2?=Lz6? -Lz*$QQġHo)\Xu0t2hbMx*w;V93<ȫT‡ %W.(w i\V†֫[e_xb‡`K]1WXg*8g0%(q45q[QkqRi=eRPu?,pth(v**RdoVCX1V]\UUcOUHU|-Տb+k rBiS+H5 1V-\jS+Ҡ`V][cZ`JaWSndR*КaVq;\ZUI ؁BoPP`UN*!$E>_2)SݎUOkO| \VƘah*+NBЮW$6;*%d "bUw\ % 746ت""JJ@O]cmҘU}O]=RU(cw9@3-$,*Hl%B PxJNr#3LB Ȓ{m3+PoSҹ& PW)-F|sB>Cn: 䘴{|UXZnLULҜ{W! y Rpx̖1U ׶…jFb7 kJ$ţ?Fz`+R Qsyɰ?) PCӧmO:GxP8P~0)U+\ N8JHO B,׋EJӿUt[+dx偁Y#hj)d:lU=1Kfl(s qPJPH;:RNh;4 0#ѻ=VlUe;*!jI&.M?v-L {Հ0cer^h7mH%\ۃ*\Y(J .8wJo&ZGOUu%bUMp@enBaAt8BWDbgңZfwŽKn1UxSLU*}dm6lPU>YS2vHXlJANx+b+/` A-dS-K|ܺSbIUj<0%g -4.^dUz ӨZZԀ890=a (ZꥏPqU=QS\6ȪEOUĚP-F88r9HELD¤}? ʜW4"0 %Oۮ6ԨR!JFE.*H@Z^EoW+u_PV_L0_JSgPnO J`=Bn&%bF d U\f]VF^d<[L@1q*hb7KևdTW"XPouֹL"#!+Bcj!ؑb]*vQSD4δUUMIĤ4iȲS+HTdشUK܁Ul7/8aNa*w\Ul ;do^_+L(nNjPЀGZ[T78пS1BaBإ`J*J'2:\TRF݈ג$;FP5ɱ6Kq'a| ƵUGJ0sGwV4̤ܞ [Z>Z}B 6I@_bͻ7\&Gm C lOv! x%9ƹ}IҷJQ(SQO)^P[|!l|E9t†ͿT7U­k\g~_2l-x\yZc!=(NZy8 C!_)ZQbڇ k1 Za]!\S$g{0*UپUyے+\B]?Z*6Xsi|:d` .BؐW)n+E+䤞bXFh+A ᥵C4F4Ȳ["$Tӡ?\G?O`6Ɵb(߻j `v][cPǦ;_ Kay3[6*Jc|dL0-\J>! r,&NCd|C @[N 6ELBW®i_tiBW瀪 <0!k~B[ (քbRڧ(%?֝f t xn-iV=**lա~(s=Wl䧚#8 4… > MæmXNXĤV$})Y B(_AaFBĬw܇ bMF~B 9bk9*02F.4@\mt؄B9n1ChxuqVR:H_:bUj++5zr ;†l:9'`{)fJ~8VG֟1Hmf0I4ބ$ZW|(]+\(HwiX:u ⪊ 'ǎEZX[(;ӭF%C`|v TLJ5NتN)lbK*}BP;Pi %FO5+fo_%|Ah@$d5?gl(u')H1J=!b+E[fT;IW;<  v)XׁW۸}\J0(hz(\!GP+OjX}:SV*SsKJwY|CPch+" A? ~SLRkZWP5bҰ-aZ1VaW_푑q UjV g^Tuۊ֫_OL*ryF*|r?~E/ȫxW)Īn]6+H†V늻l; [_Uv(k >#˗2&tZ*1VUp%zU0hWb'E˨X T4ICCFv*(q$%h…e1we&.]LUr& < nV GB8ѿ^mX ]qdl1W z:?搳 &zⴼՂ׸+_RJ[;|Cmؒ[5+aCG|JC_-B 05'` V=|2LJb3Y@F]m~A,HPl%Dw╤iPj)7SpG_"6iyQpTҝ-7-†4):뀲 acpKQNQ.q15'cƒAW.KMx\PALN6rZkg4f6U#SJ|Eŏצ*M6ZWl(h* UlKA`z䘴NF$/sH"U9dPqX^h`7q) YMp-tѕ+Z|K^JDC7 *UOek(+S*h(,"`) l}1*܈WjQT@X7P K͉;o~g"ɣXEkMU-I[J 擔ɀtgSV7\RU,Bcg;q.kA܎B5?S7ks$ĨXi ʦp%VEUiW$87Ǿufo|/*$|~X n-ˮچb£ T)Sʼf>*ԭI|=dJB7a+C 0*h44m\=Mii(BkPPErH_9¸@lӘp?V=O+qJbÉH>9M([WԞdR+Q~đ\ GT)!BiӮ$ZAQ]@EpMZr*A* ?)Y@N0hb=QYu޸ÀQ_( ]/qJWJ.'hZEA1fKU $Q&(F q* ^mQ֫gHHbe^^"&!EW=*ci~ژPdliL,J^BJ(h{d 0I .'D@Tx3ۅ>"pXBgnPfZ}J8PQ5t8O ڞ J⠖> _Մ)rӘaP> E $Պ /N{w٧6QBP‡BrX۝!^4uª1_Z$W#"+\(D b{Pd ^Co=T)ʓHdx)%mh@vEq ZUX BPHW?1*;Mjr #H;P8 cjH%d;|gqG=|%nưdBJ#$$P*54uKh=߈TJԆW#kj>T鋼- ӚBk؜Sj,bUPGM+H~Ji[#/j\*㊶:1Khq*hE<ժqKX|qWM*Pj68>K[FhB*<1VW\RiC[aCR*㊻8▱U[ďBӊ⭃LUZ VG'[ߏ8@aC1WSk qWb*ث &lUѝR@… 915LU+ZaVbN:aC`oL.*B<|?V)hqBv^*o\zb|4 z|Pi" hph>cT Z\] G[n >$␮ *"@lN!C-MQPA4\RJHꧡ |㑥)Au8T R' *OO8H0%tE]!t vT%ykU%*y3TOJbeb:U9l~To\JRQ~."lUק_ 'lmi.( p BTN up+CIG%*OZ|R޻I)[^*~c Mɨk@q T트tN)iWza* U Dm\w_QPHتQ(&0* ޴Ǫz.j)J"T&+U}Q/10٩2&bPBw4Ȕ1"c'v-FB` }mi+n< (+Ă@yv0Iѷ(ʊ){dAI%CAmO YjCq 9t82P\^G~ Te~$j| jq0'd ڍy-G^]>cd(MzWU b]xHe;׀$P4Džm.;E~Q GsT_LCu*J7ȥL$οSO.2 C.vN=I®=qWw(\*J{?Zy* +;)q U*ҡ ƛSl =2H\BN ; ҝVnIPzTE۫bGj~;aHQ"8RԊCv ]JCh*=*PJ2Q!;B Ɣ?N*6auxqqOȍRD6xEqdCMa@ g5D,S l;pFgD F܁*1~mp$|dQ ,:r 4~~5rHTA"kTP>2CBI~(Ҕ?!%o5.۶*Qإ⪑c5H41sSuaV\Uت ߦDd ĵ\*\[+CbHplUwߦ܃1 VW 8)8)\(zVFiԒZ"ciC=+H!Z(o ^',Ed-'l(]"b -1U3 Ӿ*pCqbB\BZn]%t}qBOUf*߾)m\w5銵o ; \Us juN׊!x45Wt$#wUfk*l:IT0RTCC b?(TEߍ(x늖;W(nC"4VB|*oY{91C={tɪ w8Io ZSjB !#5)O0Ɇ$Oj9'B+Nd)B…@zׁyn7˿lHc9%q VoȐI-4PEx PJזؔJթ=\?@p;i\1\r !\qUhSp%gl(mZPPW+q!-Wא?r8s)]-ֵ#5'(Ԡ4V}5´bR`~J;U:qKp!bܓJ %@\V\Q=ޗ̦|0%U? 1UsCd/!P `I;?$ U-I G*nOJڧEQbj䐾f-_ Td2 P$H;CPp\mEw5ªeG}*̜#;UFTs;ҽi4q¥mhnB)Cۏ)Rphja\$\+dQWl?1Jh) b-+Zc_\>j'e 7 K"2l?@~+ݹxh8UQo(T{U.V6;) *AAĤ/H@NvQ*)v]!v8mZm}5RISj ېx-(Cx}} 0Z:` +_ 3Oლ꜁{ TP~؄B|ANoP*~TlU^CAkP B;TŜ',+܌Ju1_'PkZ8UNFYG(0!Ԩ;ҹ_&|eӨ7'pEs8XuEÃ4 u\ |q(^675R=p|z.9Yf3#~F޹``w.:JQSR&<n]ʘLP|1WWohU]ZtKN(l⮮*]R1VWi0+>G TҽGŒΛab㊺*1WR(q.6qKmljUmM$T-#):lFhF P)6|Pr?|:=ܜUm00+XXUثm!-]`M5­ң;i?~[mF!K| |{b8#] *튴zbя^b(\{ZQ 4W[ӸVT.96XB DrۿcZQO *ƒ׊b"nK\y$B$:)[$v}?#>JZ?{ j.diİe֋?HVq5zPU`ݒ $6EbzO,g͆IcoPǨ`MPn;a.[)@=?~*bh9*Ccb6[TRj s@ *UDZw#1;Z^t3r|& {TV0?pL:4V+r0$tG{J6 ӷ  *|'\A'c\A-#pW#;'j4&.!,hPӡV,5?$R\*rPzGJ}C"݃n91!ARNJ钠ӦV"pG4 OJp{* ZԑOj,hˎb~.0߶~^7(?\T b)vA]^MK(>ɨl*3ȓ\›+lP6J-H4Qnxtª찋Z}ncaC"~:M)n*:J$Z<+B5AmsbRj7("T9S$ZblUҘMqJyBTHZҭܢ2 PtZԨ1 +[bdoOҩ iڸ {aCdPӷlRA\ ".W1*ڬ?V )-ITp0+ «FB ZA(4-;@ ~? UL r\ZMKj?{`;l>讓bT6Aݤڵ1KPzyb{ ~&B-H>.8"VAJ$0&CVKWdy6µC|U"ISo*"MzmL>% [\65N;#OUㅋ R۱>^OSݿ[*M |R1B%o4dT .jqRmXPW0* qVFJMR)6! PU)G2qAQP h7,P*I$U^@=2%CRBp)x?'uzӭ+ O]"}1Ҿ'*AZ*U)Cf f6ĕ/F1dڕVኹcR-k__aDddFʆ WcAdBYPHV4Rzt5:v IQH)m@IKDO o*RҘX5C~̨ lG|S1f$w'!-LB6_Kk 5H @-,:8m&? hU]\j0⭝%7?Fq WlW|UǭqW㊶F*Uv*V9Vp+OI 2S~FxkMaC)hWZ]qW UjUǶ_@ܢ4=0izҵև  b?cPb]\U][P4Zƿ< u6dPa-bt8u|0+XxjRb[=PqR>P#Z▁(wlRcB;W}V@qVu\w+IU8q?4߮sZeZ@5ZU2iFF\nIi8ł䒩Cjrߦӱ늴68 $&=N{aDSonA= -!1Z q!S HiEh{E޿Nޅ[rJB^\ۀF*b*RGa܏j 48^kݸV~I5kqHe?=m7LPW ˦Con\lJ]w%bk\!J umpa0I }D\n=p%aR!f4[jӑ"7QxPE;tR8L@mW%Q`wVxQzJo%-Z 1J"kvi(sA;C$xt/ߊT\P^0jH ĢߜKj6$@}{֘-NOrRo' Fb,6#BM:o ]l!KPҒKvPTDXORV_&ZSIQIre$oQIF$JB90N•.rHWwg!"6Rqp XjbR!}'a(F_PmT4rRwBAj&j 5(z;qU0V:ȑl\~迀"ICT*A#o Z\Ws؆EiSNT O%(NC 1B/)A!-?Gz)~rH|vPtȘ!*[!ii8­|+Gv)nw[*O|(]ZqV϶(qbK8V\o +jA†mNv M@=UZ :iWckH8튴M1Wb[P-Ww\U_ ??^*ӟ*lUUt$q qVVWSu0ӦZ1Kx ]KXg}B<}%n*[U݆(lnqK…TSUnkh&ЧlUXP;ⴹ^4ߗ|*( 6Gݶ!Z =$1^%uNw M~c(iIS^;b">]d!jFcSUY RQZ׮Im [ Hdxx*eMk"Ad RAqUӿ0"cVnE+JF: ), r!+w<j}=A0e > oh͈}?k$Vrܥ<~>PJHT8?SJb++̊PPV(7&Ri㆒"0 a !yN 0<{ڝjÑd +s!lp{P*<Hb"ni٩OI@ !Jb׈f4F|B)ִR-ZƠ|+i^0>!JVFaCOVتFp%zU1*|m `iꞈq2Hu(*p|cf>+G)&$5;o[ _l!޴*Pm4N!h<|}W'F09T}߀$[0$C Bٓ4C1++I*0J!(A"PsCCI''%WU=w?y)U`p[`TaCi ȿ XA] BH~kL tcT]@]5DGbpQ#zKZb{aC`T TF!W\R*{ ]>5o\(_##5 ?AxVH?urLTUAl @w= JUiQ8pjk#|l 7*!z'ĵrݘtIj*oC+Eɋ=鿏oB_kp%s驡V~ ]޵zy$Z>ɯ*…@2ڢ'؊)0ޔ+!#zoxpohPu )]"GFbDI,)G쌪)ƦoZ{g5-CUyP۠I\[lUrH`T֔șS -GIgkql+\NZ‡ ثXd ;`VpFCXfW88MrqW8یR:VZWkooUu: U0!dU>)^(k1VqKt‡Z[ (pNM P\1U@j?Uhu)Ƕ*DbOe{8UVOU+*#NcSp%LoCx`9N(T SC퀨wz  {Wb!Zlz |?gA겕ZM*X%ɋ6r!T*v5N=S[i"$ YDn0?I0@vNuy E6 eQ!؎ӑJ%QLEI#L!Kkߨ넱n7`;$-q#z PFIVt ⨐P?|T9+0oaby(0QhcX%r]*2K[ N+m|Vզ.Zrd&;a Zm^zeH7OE̋G1҄SL4^®SO]ʀӸlFT+(|=*L\Tv_Z.i1W.q)Z"LJp*>B =qUъo9֟O)q*޸`8P), '+[aBnV[zwĨl]{`W8"%^En_oG.B y@t8I=`V/? )>gpEdU!SbP_ uA@ OmBXb-EB#(&) _U^EK%*:XB}0+ ;dF*zG6]v ĔSWvK S\I!JESA6ńI:Y\$ *qs Pe-MZ0T?pidHGKCx䘯zCԏ8%2qGq[[]US xRt*iB+.,?A Īt ʽj?%-aJ}9& G)US~ɯ)nUjJ"WKӰeiVQB>Uȡ 4vZEJ9Z1*ݴ-;^~XnԆP?U+j@ĨD]5ʄ`h)Pl­r'O1U6 T5W~3~KAj=Uhm UJK߶*n*^ӭ:W5y޸PaB? ,.bhqB÷\z ŰI ȖE)ӎ8 Il1rā?W}u\(nb)vpVLP.#v*p+[v8P٦F;w\UXd⭦V߭|p+ptZ]|UUǾ w†o\Ul!o® UhA-0!pjj)ĎC Vy`)XJS4z}KHUpNK (.iQצR䪡b:*Jw, F8"Dα[u(Zєn+|Tdu5 )ҹ$*0-D7~Ld;6تM_ۖ~*Ӆ[”ӂk6T8'PT\8P\U^1$FJC$ų\Ub]\R2%!t2*|H_$&H1-4qK\UU]zWWl8W~8W0ZU 巈Ӂ+PDx]#kتwHd π~[(k=7†CDQ89~ԅZޘCQJÈAp‡t]LU`%\ deiJh^9%]aտ #&-rH*@$ֺxI8ZtbЎcҙoԑ䂷޽) qo\ R!ݲJF~y E>b5F%B7j)A `6klkqA*ErEm%5K/ 䩃0]V|1KJ*N%qq0RVZv NbUZ#[-HHLUh>BTlUBkHIHe8.ॵ4@o|J?P@$Wf肩) SalrJrJPx[E- >&aAEEdK$, (Ei nF`?eRP~cj orVQ#w;vbBmcO1wqBU wdX f,‹܃ӢPr}%o#ZF?P&ѽEzW6+ -@ߒb8*FZ`kQק8k`xs6uIjhvaC?|Up*HH( PVߊ)]!IS)i^;PRmҏ9J(>JJ A]"Q84+N~\v GPGɞMQtb{rܠ\Dv$9AL&(4Pq^UQ(U7 >=FuIP4(6ZF1!"6Z9 Ug$0*޸xWKz 'e`)\ 3WV@ 6dvV0{pZj{WDUi@ע=!PאՑd _YFd~G-kFG,MlS$ =U6܇(EF!*H… SW),UW(kkhUU]PzU"EZB6‡|Ui8P]\*[iPg `Kt8B(o ]Fh)qW ]]V8Ңhn%1⴯ZWM$(]!2P <: AR#`: WL7UXPUbzbaUr]]\k$(vb>#\ƕ+@#U`Ukp=U߳O0WE+ Ƅq^=#TJV;`6! ͨyobVP+׹ǚе&Ӯ,\Xrj;`TI |A49%lAh ըV@qdz-.3bWFI W$b'rL ^zؠTqmGRM Eh0%a4B !nqKz17bԪtǓ!l9/.>< j3QN%~\`iAB 8Ho%X;U+ɇT>'*:dn W«A1( 4l HTBP G\R0x _}rH].a޸:%Cw=lUёZ0"/qPnP=S,QFZoCMۻB<0j^-Vc_®>$B DV# Rw7S…SQA3*?h.4=tzKUB $uĨ],Hx0(@P)@?*wONW9*Ͻ0#); rECG}Ub4;P=?T rqa_ndK'!s˭zy07EG|CL4ǒ[yCrӏ5R-=l*܋ pW.*;>dhwaBѾF.E=AR@^>KH5R7 [o_q)[ *OQ!Vx?WϹKf H ªveP 4Bܺ/ Tp'O~d$T.ABJ۹ɱG٩#vVg#S0 iP1VB*}IZmSB@dY$ ta}Aף|a UN'SB}D$zmyњPzxS!tk*l 5(ib4'a^#Rl(G,BH!Ga\6mE(m7(\ CO=NS努r"jw @[nk ^ ]J\•MGm(_ !7Z DLP{T`]pHؔ(ׯL*MhA5ndZ8wI р~NCd&Z1Am+5 \nCƙ6NK~Ī O@6jz7C߉(iqOn ;SjH$q r0%ekB0lI_wC&Y6ڃRm`9%ܝ` jk擉HXswƧ -Fī)Zli`i V0^e)  92+?g_ DA( M'.oy$z{:GE- ]%n*LP^k| hL .4**\Uv8*ҹ,jۜ@RZaN(ZTlU*n`VإaB8+|U(u)[**-aW]' )_Pu*|M*ZPWsZcM )- 2ևpӧL(Zv8UJ}LWGs@wM$ X:Bdbo,-%.>s'ɐC{ah-\pZis7 :ab8pc t[ PG1Vv.p+mF 2rA;qqJWlioR: 8a.WݲLiG,$P 'natK 4dT5dٍ O^bQEaҠŶB= q\VL!QWX(<+e p6*p"UD^$-T"ToUbB+ပfN# "Ƶ}P]Q?gO%d"#TRP5[zΩ@7mR$!ou†6]ym--{iSd+]]Xv8AhA ^"Q~Ȯ#([dj!Fշ4 W@=%B 02=϶6,D%`Pucd$FWaSrL$qE.4e:J%UT⨛Y"I`}o3D Rۄ+T-~!Zw ]I WFjIjSr%+IŽm+ºx6"gN[P prO5Hn D`@+Ol*Ԍ|0tTF vJdBJ`+2VFEI֠|>yeHp]2lW+x_\JL!jhz CMO})ZL%qU ~+ ?VGׁV|mWHE%_o]WC$zX !m;(] ` .9צi ZӹIn)P*:UOL!̥6?N(]ZƃU` 2=kdZR~dnJR?ZTE<!iV#{Z wP]AѓZwS8G =YQqAmqҹH%h+U@XȔ4di@hG݅ `bv؂qҟ~Mo_ + G_tc5$,Y=;xCWiUbEj1堌ICNF'vEJ"O5GMR) j-#ߥr7Hj~{{BlW݁UUAZV1OU"8RGN0vJ SC+8iNAGCI tkM UA麞M)[ F$}d 8P=ԧ0L#bT"AB~G# sDF\pNIrY5 3Sv2p()gzab#Z&⢧\%i4VQ)D$lE?u>ȳ 7A1=B`ɈGNe~%JXzŬ*GZPO\&tߝ)a.q 1ɩhb>{T eNT)Ġ+XV׈.S3A5#`! J80;xb*MSmJ|(DT9d9Jh+V!ӏ`; bsLAp.ZE.]LU*j:`UwQZmYܮ O 4vU<4whX7ZKF*­Z«|*c]%F*0…KlGlB9| -)k:V Slb_8)e0:uD$^rhTjQMOfb*9## !rw wP8T_E=4p R xР͏%Nd+vvI=V!qzJ!j~$mؽN´l2&\*wp=qH@Hƕ kTli턡ڴLJAs6ƃI}(nJ|%|~x?vȐ57ߒŸ/a( TuA]'j:6jy}Fr UU^*If$6D/+٭I=)%8B$l*<~x|$^,d7m^BG푒A\'Juvg6@k_3I& TUzP·}rIjcR!a;bP|h?^ס]*)Y$ҽ}XPHn)a88UDH^UWlp)OL0-@*wĤ:cG%.Y(OM?E-aV4p+eJbLU+vozoDp+D׮qu* \U,UoqSlb [r)oV7*b[ {=0tqCDbWثX8G`KnGN*qUΔ ^_ P [['[ 0%ܻ7[1 TpZ(˹UmS\\U1W\*+\ k *z%6UP}+p)Fia*J(l@p+‡Vs(*B逤.ex@qj-Tz)IIwru6ߊ銫.PhIJ#xیwM0U?N5>h5W2T…+ĩ+yUޙjFKUd Bedb:" ^:l't*SjF8;SKM( PD'<0}zdm%z_츕V Q"R<F*@JBIJHތk8b[I`v4_H)<瀏j,[iĒQqOX+N=IT ȲnfM*:(ZDBOorHph8%BR@u(j~ҪD=Q;n;bzRNB}P @#"n X[@%lUO;uh@*qr+Ө!iUdY,"<,\WSCl!rJQb5b} [?eX ZG @\eAqVێ ؾ'ߦCQrU]Fy> xCOȖALCAZEO߅a b0A|F+VSZFbӃ%uv0f9V;ICc6+X i$n_,Qq=h)=Y[5 ܓBrM +J ww_q*TbSj#풒jH n7€#BGci}_~l@B$gUDlT`b9+,]Sr̨偨@bp^UإMONUV*?'ӦC'6NPcAݱ,( bySBi1y A,k^=̎L1|RqUB}߯KE8Ru.AIҜJd`;wsD)wj* іiż1*n)֟" jݒ + 늴N(\ShToDV+:09#ȑVv P/'-S XX&`h0Jv sP|]<[9:yG.jr@Sm p+Xثt تdwQZqiJ7 3`TlI[#}KD-㊺q>8(]8}C;lbCu['vVVфS$9*1P%ެ`83)lURs?[aBvVJ(-U]­ev8)[nm(~G|(rDVp&mb + ׊**P ԝOa®8|(jv ۾4ۨ-7ѸޠZG^aCdLUء}{ PX{P LU*SI^ÐCf F}VxλaVTf}?+$:T/X֫Hw }adr~$x߸5L!J\ʒFkUFcHTRmj:[''u^BRJ#b\RIN*ٯ*$sY @Ƃ''$+&rZ̀I~LzC| dw=ǚPڹ0Ģ2e:E(vB2@ -~Oª_Uh:U^vXuY *fiL5AJy! r⽇\!JöXca*fg"#4s+ k) w]6n<>X*<䐿ܽj\i}R9%!-nPOk%/ǯIb%~U .ZP)jW8+Zo|BKM R{0+m$ O†~JSi W$j5ZHT(_KW,k PbW󡈯/IpN<LBVkNJc*c P>/mpFV(jᑑH[NAClB>t9V27+!bp+cu1CDSlbSVi[)HW=`KU†m«{ZXVWU UN*hO7V ]!xue<1Wt­6) צ*|#L [ZW߬c-7^!Kjj8PpTfG֓Y^NJ㩩YL \7奒CF敨ۮ j{ָ+7v9&. ׎aU8 wc%g?M~y[b GLI٨T-&T9;X nPZW^트8ī#l0*/% iSߎĨV,4Uzۿ,]M2aKmǢe-1?ǶWvӘ!=%!w\v>ث8ބ  ᙢ``J5j{{V2:T!``N"js߅i_|6ZWi}%w0H ҝ}UXfل^#BW <@ kJfE(m$xs g+ݾObc*Bλf])|T`V2H)ޘ<3PnB64-KZGBwbJA1ާ}Qp+i)I wҫ(;7ѓ hHN*Ebkm^+֤m&,*v/*1$CՂ *c?q*x#6BIq ;4eA AqO (jE$*4 &mH㷾BgkTڕ,3C#+E4Tޘq W 0ؽ4qmP VCzUлWc䧚>9$7L W+_R*<}5p=0* Pl6Ih/|j)WF)R:*_ tK]v ݱKqBMQ׹#k<ڄ׵?倪&ݕUBwQGPjT>Y JY$+[dZ֟,N;3zqJ>niC+6)[NN+ %>"P>(]^m*0g#@БO"RZE ֕D (ڻ|0˒I㕆er<)C˚.ۓGV߾!JĎQN?! "Ob03R ȲS8RO%,zeWx B h~!@uHZ⦝)mhܶ;m\R JBa%*IbP۟q(aH>-އ2&"g>4)c 5 _ S`ܞf4 m=!"Qb C>tªr(OP?XȐhU>m\!vŽ:o~*|JAK5;⫥5VЩCH䐹OnǮit(V Tܝ[@Fxҙ8$)*j*chXLҡr'sN*N֣'^9}Qکr)*7rQY d< @Xw~ՉS5 2κ[wLUUp‡ U$G$Ƃ#o| ]'(wHG9H I=G UC 2V욎lbq2ҟ2)nIZbdTJu*k K:{aTRډRij̽J˹'nfrZV* GM57B嗍IS[Sژ.N+~^TzFI3P~/ ^;8rC)qVmLUkDU6=rHk犮qWEJ) PWC->xUxVRN*ަ@}AC^mH4Ī뇓קLUԱ8J'i49U%U&=5ivr*I)Wфl}TF+Fڀ>y&ʧX:ӿ)Z(l(ZzbUUJ'}X@L!WJ0-!x8}*O/B!I}|uh< @Ȟi H7UF>gbrm]q^b?!0LuE#j>#cdSӨLVr…TT`z>!  k`UyoIXSz7P7$Ќ%B9}qR-ペ |[ª,T&q\Ҟ8ZqU`uJY}Clěic+$KyJǿ],\P[`$*ZʭHvĨSN6( 's_ׅU-ߏ^d7BQv)z+KT‡8l/+MqC@⮮)wqZ bPU[=qKU pUĎ⸫.@M)W?ⅻ[~pE0%ibi`JN5ኸ/*b0LR,P<1Wq4om Z#LULiW! mvoU=|0Cc*i`JS7Z+8o6*%4 c2%9$*+Db0s^Ny_~؁JM!׭+mv8P$PsLUmr&Y Je),ke!Kg;9`fe+ЌXBi mR4ȝ`czxͰx`4߉އbRv=qRV*mM1J;Bw~6}ר)*kaIڻtThQ?~NH)hR=>c'>BJ9Tzn)\NoއR-}8ZҤ|]FqV…*¥z­Snk*%OH7ph~]W M ho7f+c]r<6?yӀ7l PUoaBEf]ۮQKw=1U޿W@ JuT9h#u' $(*!gEDKE!8P55;dثq$wȥ•oSp(*w  r>;}SH@jM^aJPӦ(` ևW5Y l**IЎ TUss%m|~#Ӹ>dH@%av2L\*q;bj#cBMVǹ w)eT(w­86{ dSmKA(Z}T:dY9jI2oB=AbT-}O׈V T=$ÃÿDGm}%O;+ : UGltE)Q14*~ [QdMZUkyàNoq! O zW5R]ȖAC~1G ӑ,Wo|[䧨k*[PD`K{U|1V#klqV*튶O)paCW zWZ[8‡Z8Ub+{)\xR߷hPnnbcD[kKNPv*Rs+*⭃ N(26IbP&-u)qS@v޿*V\ +N@zbp+|iL*تSl=6cJZUaB7*;)j )hTaC|V[;W@%+N$CwP,,Q&5N(sM˱}0%HuV|P5…Ł| pPG%F*WDGcJ>F40j}M&V&+_p;hJ`Tv&~O]"rH+:N*l(⣦a 9 QiYǒPM\Nm(=1 Z⢴]$ (k_}Čvli U|pux]*-w%ɿ~y&^!JG$v7{o ؆!Va|Wd&%nk0 튶ZWq  Ī!?#F+`˒wzb)ڽ.VGO تSQO{3 cHV~J72!RSMגby A{UM\p+0qV8BFԏuqBa8%zE5 lU]ƀd %ۯߒkxtq*rtIj?CDV„}gi­;GJv[H7C,miժG5dmJ& m}m\PC,F+;?VkJֿaBĩo|J+4TS8 {q=F*WDSR+^<CHEEp-5qVӨXuO!toWą\=hmUu9t,V]␒)N% @dR*z1-/ژPޝTe>y#ɫT5Sz_ǒU8&%??|U}?UE**i? ֬Ol(])/Z 0}?lAp&Z8'[:‡q`[\(:`J8B\Uzcjm#C犵Zt…ȥ8RKdN'l(ks]JF>Ŋ\qK`8ԦqJTa(+.쎸 L h/.6< PBc#`w($\*7j0TkN'$y0ԗS)rܿ pp?F*MWrF*צXUwJ}0*Ѩ…mA| S;|Kq8ߐ>OaUg+T *$b) |v> UE<B}dYQJd8P(d5`ґeJ`Њd#cR?GVo +j{$sKzo* Nz푶T jӊN*!]ħ®t䆫*5#ƣU'2y|[lkLgFwx[Aec)lR:SWSB6p/5R1{DXa& )EPTS4$~;4=TU (^mǶ)^5T*݊Zh:a*PEjp$]*2," <'$24eZ!lN6&{o.*BZ]>ոĕ^c4i5SR;䘢^cncd(fF,AW $ʐsFQJQC+jэzqo% ,R>C T} U"~* U"5CߦP>/M#\7aJ&HnwP">x-HB߸’O݅Zݨr)iR{bR\,UZ=)ZZWcǭp[ ј#U@&r*~c&k冂{H$)IafzV.&y4ht ~9(H]цLRBrv,HBKu#'"K0,^(TP7Vۑ ,'Oݰ$QɆNF2AaS▊}݁U #!jz)${؅rG&W\dOtmJ\(M,n90'J%Mh&ŨE[} PRqRj*\NҵJҘ4 Ӧ}XaAr1VHhhz`d W/m,sl!Yd %9$ (2@ :x䘷WMCLwJл!p;!NءYZS LK GƛĨ.r58GQPzbRpT {֟FIw•5>]2dvL%970d0]Z#*B @P+RS)J]u.7޸Uqb9(ֆv E +\vz]3s`?T?vHz:l9&PN Ʀn{PN+= ]ȖA\!JH;_c 7 r!r%{'O YpL Wab~*u)=i ߦǒ+u5] o=XB6=j08Pڠ1UU^HT~?l Cp1WMLUY~dwz|(MUs 5=Oo핳B:4?Jk֭4,3cą)#|#NUx]j?aw4Ȳjk9sV*vXb) Mia UĪOPЪ=m„Yah€}2PwP "~_d4tm^Y~H1->JBB P@Jt撴(qPoWEOJї#OSԨ"L;|H¸B%~$ŵCFy/\UVSZApBAjL=@O#uJ۵okK\q [e+ېC6s R5 n6g0}ICO2l-ùǒǰ\?={J8зcKvE*i6E.z)8ew={;o@poSwC%CozȥP$4:a( ߠ],UY9#"FOIUOJQ| NH €xJ rEDZ0e1wϿᑐdrT5}o@n5=hENcJ3jG"C~%'}4?F[oR)8! էϮ$:Ly Rk$AfHYΦsWut0XHUQАvrUb1KR78-+pqWb8U[8Up+]0ƘN}E<7P}F*ZIQrPA#pJ*S~RPg 튯0CV*1_|VH;7VUH1CEjh Ul w ;bVj­P :ma1URw 5IN+n{CD870.f#}q*P$u 5p+dP&J"nT"L(^˰|BѳBwŊR R(p%kJѿLU)aU+ۮ4mϒHrr,U  Bd,wn()rAJ2 mBG=12uP'VްpP+u=?S٨,jm76(+6UZv n]LR+NǾ EY❆FZWq9&* Xn1j4&+w^ۏ рjU~_(S;UjGa*'#Aқd@dJ$ w ?.""TUوaZENqTLGjHHiDem%!%CY*߀.X %+Ö7,q`KZ5WSz턄gih\֛\ěSmwB>LR&+RMs1Vco_Ɩ 7W$84<6=׆=Wf녋@Z-4U(|A> &WȖAwGÒO 4BNv6{rS{?JuLy/5]ʀ7"p*DxtH\qQwڀ[h*P~i!x ims5Kl%a<,a]إV*I?BRNd۠RV׏!|!j%ZptAe]tONCv(n4OHpqRiޜN~lJ"[^@4UPI?@}I+<~%CSqZVUAOL+]6I'41UЯcQRv\8.>*՘J!*=8!ёRFp{0~.JA<0WHpQ­ٺ}Uz_! $t[lm#QR78Կ@8 Wo~ )WJZ dJ@SD-l48DZUIrZZڥw@n_3j0kl6vVn,,LTm}cԌxr%j mXy8}Vc*zA;$ڊ8'CB 6v, yxHk ԃߧۊU^2xw*|?ˑIQI$җ!aCb4|Pjyt?YtQyOaj~(Uģ?*+J=c|G$U֛'ǯW~#<CT+QyZKwb:`m4-N`KE}|KNDw CE.®WP *׮)n*(q.0")-|>6TVň邒_0@=ߊTV8u\qWSlb;KT­p+i WGC)L4ElRܩ8H@ 'NI*+LUثup*蔻IZ7>׊+Ҹ1V­ao&N(\O϶*PFh51Ke{(j- ;JU6lW[,)"1WBF)rq4S_5RO*XUNQE% W'aB>*^f8nؕ ӶMD-rqZ>cidM;:z둗$iɋAߣ\(. d=z)dѡdk#6!Mo9c$ֻ #^[wġ6LR}lBΘ늒(sOQ{ !S!J>65N~~ "ZO,WAƖ w\X,䑓 gGcD)F,z)\W qZ‡)q*F:\Į!VwC)J߾)PwŶ5."[IP!Z=Rר/l** Uүù0 VqU u`KJM\y/5PTayʛi2'n +fb@0*Kh"LBR+jM ~RoN4UcU4qC)Rk$ǮݱVח\&좽F$$ĔXUƪaA\w$=OӂBAxʲ:~%seC>IQ}ǯg߷l(l{ĝ?Ua;&y(Q^B ]4:n!KKn9.ҙ$6#Mm4HJh@)d]  w'&{v}ܒ}HB£|JB s7*1J}J$X|VɰǒVeJ~JF9l=^D+Ġ83;wh/#Rۧ6v$-5=i@hm]O{Ҙ:'¸ zx*O~v.1ZQF5 =2- L[(ZL\N…jƕd>"֝Ui]Z%4S\B7mve 6rBH[s!y`k}dP!%`Ɣ0*oRNژU% TЍ@4t6OqDcqTID1\(CnP×C9.f GZdC2Б)I.#JO?VDd *MvQYNj L& osb&(Uxu !nLí0*t=2qFa^y8Psi; z?p sEP?ܒ-Nol6= -sma\DHԝ֝C*0jb2HJ,y{O,PX;*5!*o\S C`c,G p%qHܚ=vgZY")]y)S =(p%rS!!lKz( ©N5\Udэ78ũ^=U94*Dhˑ)ȥUUz!Z.[*#h트]=⭓LUpۦ*>8YKW|4 X>m$Ųp%W :;b,0rekCCk㊣忉 ;[$ź\{b[إt-Ń/Pv qTsHU6m+G qCd튯T.zȅ,ǾتC>P8&#/`* qK 4 VU~(h:`) HlRTPvኯ) P=1RsH> dC"Mx5b?QIW0!bnm|1UmYZ#kMu|.\s5d"87j8U})FB5{S%k%ҞU;;^rx>CצEP[oz`U@[d8|zrCZ⭭+Q{`_HZi'uPJV(\^+M UC P(Wfa@"zr3 %jirW!k U bw k\*j`RAAj\(ot%^bяjӓ!]ǒTn>y$*.ҨoJ}5'R8_*vqO:ʧi8O " U<<lPRH ٻ偬~'I) cؕ# @jSO}zHrgn ڪx*|U3 7j/ϯ݅U"e*WJnZ,Ə0&H"և wߧ|*Ebo_ W iҸSU#BQ`uaC6ڽGL!ZAKx LѹE6lh!߉ )]JdC\>Ctv%#@I)v SӒd2v)ZN?V)Rkly|>|(]OVSSE+~4ҖW< /TjǐփiyabwN=SF48)>F[ambBKH+mX;ώ*ߤw|chPPF)tB@;!q*TG_܃҇ Pܮ zO|R[b@ITrbX-bFn&د:aB˜\>׎!`ɯNPz6@#41U~>O;*6O_+Uw$bM*K;?}2+ዐ6b9B&*V~vX9$K= UeA"ܨ%*R3_|4_넨l-N+k#8н[\E6)u#l\›b@k*oJWlUp2_܃%́>mZ[w$V+;`7InlҔ8b{k ߩV ɠ$.=*߲@^XKlUP@% rЎ?p :PH`ЌP =Ȑ6`Gc9+nuW` r#5"F(_~톭mYN10*j #kH'0G!S, gPlbB#(GO.4,q^ttBF¼}TRI \ʵn\:8M\ z ]2z־qU {cjIj*`)R3| Nm,W_l kUHBι@;&+F`<|&Z.NOՍRV'o6ߎ6+p¬dn6X-*rT֝US|,QVJ=[zviEy?Q\16(3צ%H\ \& J9Wǯ߅f5=ǷlVHJA#\G-*q⼏Zթ®k@z`v5[Q8G;{إd- s rHi|~T@ D }P&U뀤, V^~- ZiHߩPے[܌ q58sMv%Bێ UM+L צzģVAf5"ӽ@S "SSAJB' Xp`~zDƣpwZ)hJ5OBm>R "EHm}!),װĤ6K4}vIsס…U&U;67 qmCہ߾%Fzbv*`?渊KES\ S؏†PREAR +Pm;bT!EP_ rNcTSᕖa sR`2\ґu KdRISZ-1 \sv$.F=OS %E$,u=pRC*rÿp)T~tcRָBAZv>F49𸯸*USBq'߯| 䘬6k|! _,*1VPm!Z Y {vKY: :~?%Bf05)5?ȥk`5hjAE@jHJ ! , ePץ;Y5B$V^ YcR1W UUpP* )wq]qVUVW+QmW [qVV]ZaClKס­|Ut8dqpڴE1Wbhj; + ~PhpWq'.88P L -;n+6j*bWLPM:S+E0WxqW B4ć vvŋmw#qT_nmzhTz"Ez*")\PlzKG[ ,y- 0+Œqwd*ښ Ҟ{P8ޕ|U uk| ѥ*F)ojDt փoՕ'#*(i_rj ?A+`۟,P7r:ɎL|. (F[`>͕,XM¦F V(u@4 (^Ξn"XsV`dL U*$4$"b{aCwq]⪪h QTI17R7NKj r) F^X=bMTWlء w銹a׸PnC)M⭐A߶B9 BǷ^g6<W% P7Aॵ3x"!U-N_@ %n<I\8げZQX++JL?wVEh68 2c\U|Qvknc+poSN|0[Yh~lnZ& -7+“tޕ~ K]GaCk@OL mni xr*|r%[ep*=iP$?XJjI6=1(^ݾx %J _ ǚJ1U$Zim(>FUHfb ߊ` ] vbI;0` Y ' #;m)ڍGT,cڂ X$|5̭,m iE,`X2QN X79+B$ĭ=1U3-CVuaUޛVu +P}Tw銮ElX8N⣡(} CbzV}8P4M:m* כ}%z(W լ4OʛJ8ULUmc+#e +(a2t뇦nkxlAڴMVH !WM#mzvą  (U'lgRaW-?Hᵥ"lQ6jkZPEv 쳑> 䘮UaFÿ6QuX4d۶ =7 T RܚUSsA{bn!> mE=Aг-kNJ&N2^(*kopI Áރl>+浐+vAI};cJpȔGLUGq[ߊm*uqV銵 և(l-UǮ**]Jb)uqC. qM,U<1Vxdm(]ƫm*iLPrª5*NBvZO(q'k* KEv…IS~ Ua>UWvknUH"`Mc S LU늸upۦ*LP^QK{baMR6녍1J}ýr4Z½mx+Kӯ,mH>xZ֧d†ªT/GT[x†Ru—`WVlPIJ%UZ2!ljYQUMZlPrzdSqTx풒ÒIVjP|;6(ST5]}0SNI A8ԊPJP9)T]6B *J /WprMoXG|TPq)T"F1TLD1 rL]]ԕ߮TV4ZRgcኬiEhVxCjߦ*Z ~(i1Up)[Jn0iw:bR5qB5ٷ^U1 J)ݷd#n>AR+ֽ?-+_8yT Djj:i,m<<%iDdrԜ0*UI†)ZBQ7j~Y,fkb|UZmVer!44뀪AG~]rI`n}𪌆k|BRivI[a!;)obIC+mCmJ׉ڭׯ(hUwc] -qZ YڝLJR@ҐTVbŶ4a+HX}`A=*2(5E@ȲB46ɀ}/_h`=qTHCb\M=XlF)Xc r* 6(r6n7K7T-},n?zWPASvڿ{}%\W"RoF?î)C)on…H~ۚ{Si+_RZSD/Ň&q %)UnhIDYDLT0)۾NNpXSm+UϱRԍ**뿶2" }V~B&3CJFHRgɹ \`U)C)+Ĝm}~y%xIM"wKkF|zl X؀?\6$=BaCQq*^HtCҟRBP{ۦM'~קs MClSTW|;?FDHvlb#ֿTƓ|~|){d.i+pUثgkl] $zbU1Cdb8P8P)uqVo*ٌ ՠH>(ݑ 푤nP$UƠ ^*; R Ȅq'vKD P*߰늵 ;bLP8ء8PZcNPzحENZ}U^8F, Q9&$yyv \camk:o[cC)lv*'î*[_uH7PqVȦ*Z׊a኶0QO{C>YCIriF(9?! S9*$ ~uraEG¬jݾmeSB;S$m m.B*£fZv kl+M lo ; B|>XJ Gc1W"ɭ ߽qJ QClc{?F Kvʜ5­,>/UzUjCMl! )@wUӦ0L*PW(i m[W@)Ӗ~O]p$ 7!WuIZ<:bJ+t?<Ҧ$*D(Ȕfܥ*rİ5>閵AQbO-*r5퍫r@A+G\*tzV:|KN)@q xRtRw?RԔhǀL4nX3n8I_C~U ׾bEXǛS%ɊxS^ CZ12S 78 B<]b[qצһ^?k?h}b&;%B {vrR[ʴ2/f\jcCbEoASp[*ZB y9 A\zсUK Q4_,R$dn2t*A?sxb2ThN\W qcWRH=KJ|1CT«H]%Z€>8h )U5jb@ڹ&*19RC76M$nU}PuUA ゕR2iž* aFPҔ n2dՑ0;;-lծ]þ"LrS6ȩu!qBs`J숣 ka@J>5.87ҞP$(RG?,P6 dVB&_p* H( 9t*F^C ۏ+|Wj [>$lkZɵMs/pj%}7C_ WW 'lBZZR$b"4|X!JEpR ٱ*Fe,u~y (=ŗ?vZX=Fr cǾ$ tVv* v*p`K|w[ߊ‡|UUqWS8]#|RnbwLP8UZb8Xd *)-V0{jV J U"r$ -O$žثGou]E>xVjAԧ\UQOLP5([_ɵŮ4߶,{o+8Tl9S+KH"mҸѐtZq?A1 Zpqp%mhCb4hUaQ;E_~1TBTJ#գN;ɓU<^O\(J2/D)- 턪T8yVAC(8PoJt+ ,L((pW~;۵0& P`C]끓|}Ƕ)m÷L iZU5<|A,Z09NjZk~wAlUx8 O2OývJrJ8;乡`;o*w];J';C߿)ZPu זPPyj;wld'}}|ثzgؗZo;Ձi.;א WƠ->0*ƛa5…KŅwRz$/uo }" :" ݨM|NJM 8 1ާۮ4\v<Э!%{_|ȴI6$-Hr]\;퀥I튯`M|0%g&psƻ$S LUS#o|sztrUR`0-Sb zۯߑK MJm@؁aBPƔ5?,HTOHdf vߥq`b$7e l~mL4'<5P7P9mHhCCNUYvD}ӊڒ0;%S5icn<+N @(UkFn r2Ztp$,W#@>;@lJi;S4"˯`J=vc1]%(kI^TP*N(mߠb"ΜMz1'p鷾aı Fn;|2Ą+W,&{ij%HM٥zdHFJ$lZԩ ';\(- \ ኷튺 Uƣ*lR1C\P+q]\UǮ)v(mJU[*(hU⪐CȱND RlVPVHBxJV؃U΅pLU U, * 1Z<0%UqUæثT†nU⭁\UӦ(][4?5#NtzD3*N'L,HZ:b@DAH(WcN2lZvPoCHTm}[p+SK깐54Uj'R:{b?bGc?ldTُmc{E:d*"OR" oC {U|jJ@u5ݰ9O[m@p{0{ ;A{/Ol&j=+Vf %\F1)- VjQV9nuXUx9 !B|<D&,|;T<*c W>.| AE8PoaG5QԎSJ|JaCks-#"bAV|#ܜB-)v E?U.t"iEO0q&W@AprFzU[I84$CLHSP!KH70^H(5ؒris :Kit$?偉Ptd%n68EzT}r=RC1KT_aG5i^*94 ׯ‹aJժ"̣퓶J=**KB`Ǒ0E OQL4ھ$(9$,g@a*f5dz2W oO 1U3;aCi*h^мl(\`nF J( *eS(zek]/0x-4ԅGñ>05@k W{P;}?N6ZF ʾ?(Zv'|yT«JCwZSWq Wj2tb=C]Sh~ekJduN*ءrZ-^ZWbq"{RBj7늬 WPacͣlUl 2q[Y]\1UqVCt#b`UA<{8JC+{UC[+hW* \]Z 79B[|B>LG5C0mM 0 u |@%9$O&naI -ܝHZ|^Ò6?F)wL,W l}UPCUn7]`JRJj{`K€>0+uB"P3[guɞMJk(r]zu* +P5zӷъ3J4FRc j~q Ka=(\V?:{*rt!ԷNUC^ס? M7 RJ6 ]}03AJP )SsϾ H Ȏ8J&PHxKڝT<%F:rM %|* 7b0Xmk9+ Oʔ`ʵ "՚PУ!BE)ZW4WfB\miMث^ߍ-;@z<&4߾(h"bHۃhGZb[gء+ڃUcu W[_e!&I &k$)(-]&P)>T>STzxAi\SPt;>AzvB&Bdݒw{d5*k"T/?nIƒܾUj⅁+CwOTT䐩l;PөF #H`)5*[\JZ "2)X٫^d\!C4AAUz1.RczdJ.O"~]P=& M= iL ƻrIh*|}VjA؄-bh(Y*ck [s d#0RaBPv)6? (LH[Hm)ȍ (aК] o2ANlpUE?3R% Suy.ӯJ:N[)AL qV_[(iUثWb |RbXj1W1KPbɦ*5["\V▱B'ث*j▱W P)teu䣷.Ԯ#b'RUֽ*(k cԧ\(oklUQi܊P~nO. ׮*l_|,Jܺح; WlzG%)uw%CiQ኷j;C]%cRUH큓gqWV t]>ЕW,c/mwQߨ'Uمw"\1B ~#|IW5XIH>½fA``i"JWR'rJJ16)mM:}P߱iOq \va!?JE~*@WnPh!Uwdء1j>)rMXk}B$2C{ ʄ Z ǦUBǶՍ)>d]p; Po^.V5۶ \gۈ-~(naM!Kt|;`K\O >6t,+8 8m/ q}>X]b$SvGd8wz,<Ќ]BOCӹ 6GTva=vc=Rs$ 2Hi@` X[iASPvսت҆֗-MZo|'de%ɨ;oᑵiRzi|l-fȅ-R=W"{v)qUm#'BjU GCԆ($(xr41+Z#`ĺ:}Tuv]aw5AI푶tbcT' ׵)!ApY[%=?&,u܃dTc J0\* -zKJG!TwU#:!V\*ӽE  Uj\nZ ,~-φ0mm?e^Jq\MI߮*1BsJ`Vޣ Bj7 *}&X(I'jd(8i*[#\Pk Wb`Hih0)~8̴v'kmHqWR(ZA]c]Jt 1J ~7`֭F+Rª Uby&8 /&y%"K#l,Vև bkPzaZi*g N)-'%BB䖝w>$A)+t#t0IG|ڑK)ԝ!!#q+ƈai A@F)ju 'RbClUPI@¾Rm&m*B`'$Жb6n*G{I%_ S8Ү8hzW b6SFG*#.㩧JSpXBn%!kot,tªzgA'TK bI5$:l#Mcj{Ī!N TF=BMI$k`Ǧ@i%)^ }hLv%[I-4a܏o$tHM6'j͒SVFjkUʾ,7#U}BOL t=1 ZSNF(48/6(L>CUѭP)+֤!mdVOqUC;ZNIIX oV=*,j>(* #c1 ߭ t'z}9Oʽ8JJrT&qrPẀZdPS# jPOl( 3@T녒D= VƛkvA ;tթc1 VnbՉHR${h}D)Z\ƂWK[pVPCh̟d $Z}F J*rCW "yyo`~!\wP0W7ĵQ႒"R*;BC*5fxqHV?(j8\2A[ C*~*9`J@)㊫jۑdݬEZ޵P3Zm)RUc޽Os6V1kr1LWE:FIp&߾6((zCT9 ~<δ5 hoo׊aU@ݫ_R`z:XUao ;Pӹ ù@I@OZ Px{cy"-_S@c2HQq/s4<גpQv퇅ӾILk&DGI`Ju†G®'LU6U PWE=*aVcc[:Z̪>]\(iI D\KatcKkS^@m޽%B -O Wjdm('$T~C_.zaV"郚ڻܙQi۷)$ڋw$bo ASZ+8-0$*q`d|+ej6 Y4?<$)4ޢUSaS=Y,XkP% QYkd<jL-K"2W%#_Q1ZD RC*aʝq/3@jvZ2g]UG :Sv#Q1#ſc\ DZn:[ ';*#9Wtī* w^Ao="V#~]%7;+U'\J1|dY@IL Մ%MLMG(<;Ȕrm(a*6b؅;}UgNPju{nMp|,W)]h=%o]iihoa%iO⪔Oia4 OuɶZkӽ;U`:8R6+`U-"NHaAO6!cR}=Ph;Hs҅C N⭩|U{փ| pv?XM2Wu 1l 1UWkP?Z}AW?kEBB=cź7GV?* [*K2ӎɰ\/odaUZdR׎yF?IL(jۃIZI'†7ڄ]qRzR䋹"JM%6AOs[Hǖ8$rZ`w߷LvLQ/wA>l95:>W1/>5'FIaZ׾Xxa߯KD↨OL*Pj r'!Z5Vs r4bӓl=WrUEkL _r@ƾ Jlw8Pg-SEN"8PppuKU­(Gn!xdUiUWwV0%Kw_mV #۶* fTC{}&+Yi&^=ġrl8 [(x>'W+ۨ'*ْGlimM1zl(YBAw[*RmSCiːRJNXӿLUUYߏ9' mlC X.b+m,4mUH,_h*zB.K܃|UEYh_mV7ÍMng;6Qm+FSS_XQYX.ñprO43Fc4qL(h8.i )pD2L 8+D TS4-)P:Pl :1h(6@)"Q[) `[58EA;(7Ә`6!K@WߐHl#;J? Zw6*>Jשza&T&>DYq 8Qlz*OLrUč4=$p>?dڎ֛U)?يu@lk6R<|kc@6*^Fs(F"io*{URALV] Qb1uȞl%S… }rp^̟ȫ}w8X%>8uV[jv=1Ktq4;kh+ت|1VWQa4j+M҉b8Umk-uir\UANo/w-† )Z)wōM0-5\R;mOJR)*+JuKL(+WT\XSq4k㊯CPGӁ.F-0! ǵr,6+ 'aS%~׏Q|OŁo%6:]]r|M/a }iH!g~nOMbٙ*1?x"PqUBj_#|@l%ozЍxc|[  Y%np%>/m+jH|Y.f8.إ=q.u:]=F( œ8WtD`x)ti't Ď w8O*ښ↎U6[C]|J5:  ޘC d JJJ5ƕ^1 ռ)<$b뇚94d$hS}Hzj%GP {2SG1cv>dmlfv&RjWTb$g"7\24d+ס MPJWi_l $7c_I u06nD%Q_)iGAӹqPl'Z\h*BCPF%Lmw͹lpsO'LǑ$>*E p'z6-]rƶ7(_+W~3B)SC߆kqӊ*~؜ nnLUe nMN/E-1!;SQ6BU8@ۥRQoS^hqvޣ*sһ{mZ8@u &ھ=%r!G{8mIrvxpJbD|HP[AUA %yV銯 :u Sf43 KNo;=;b V%.U"╓aֹY;y ӮMzO6JL*9.Zp*=N]>잯v)l`WR†\ _U1WVD N*|Uܩi-W(]Jb|CdZE1V*ÚZ8UqWu ][v]J®\v\pUwcqhC}*-FU~:薀(tE8o­aL$!7k=vW])+6NpH-VUeu-V#㊸zV/|,UvĨW8!jnSK*\(hn*1Uژq?݉P|_1 |'o׶*1VU*|t:E6FwĤ*LF)?P *hT6er(ԓLB ԑ/>cnXM+7_*ߨУ(VA|䭈^#}&$Wo/8-+B_j{p%a 톑kD`0wzp߮C3OR@B2 ~)ݺ'd<瓒lv $h%ke_Z{l1BOS-1 <[ZlR?+v5jUR' 4}1ɇ=UHl(rMbT6ƫ^Ih]w4a0%o@# !k*ȞSȧR 9 TMȐ/+һ'TADboU/ھ#m ,gjhlNPVܒ~/C[TSPiqU@N*2x=իڸӵ*W\Fʼn"|BCij1/ߊĜAƕmcAmet |wƖէC`aUi+r-4x5aBw|…hh A_Ȟ~X+9@x$*W @jZ#'x2q݆͊)4 PNCK$1I^dw_$㸠0%RGITfxܓJs rn85߯nj eJ5L(QapAn,(UJ'Jkv憌AFD)nimZ xH>4ȟ5Rga*Ө5b~[`꞊eݒ-'*1V o @[REڇfmSfu&pqFvqZFD?Ǫz,0W?vҿ N%G P%}8.wrl0h [\* U UilU\7 ww ױ\ŸN!]Z[8U0+b_*$m_tZ0dWqhoZWU `U­Sm8Umw|p%}ñ )R=kb:**  b\Ҁ%V[oJR:׷*!D?,)*f +gQ䐢M_,IJ";m|ӯS\] 5R.ZliZ 銭P[‡R7LL%VeXZMSlY(ۭVׇ^~XJަ8UuOx :WJ^ۂ~PҞCb|(kU ci5W(,h0^jCThv=2 IcS0jt's1ĊGU+ׯIXY;{{Bн*a\iW$znZ_nXF m N"كHvbXpN)rwQwij1PK]~J[LP! ;;(ZKwzvm$8N ߊVCoMN!b{(ABPlC>_26ʚ4)4 "r?WOׁUxTc)9A[R PWDjOpF,m!JS * SB1f"1v)*ZOJ| RhI޵%']bW^r4^<[K2HsP]qn~+^,!̅~8R6P)jU1WSup+XgwLUzV\P$b:bl [  V7^ݱWtl>bpUF+NpLP1V1CރoQQ7+N2 )A*U,(uxPV6ኪ Հ@5 Z$ZLiW/R:L ߱{aC@~8$juUԡߥ1ULRw we?AȥiR H1+*PUBi@?OŇnR9GbG߾(S^bUӊR1 ()8PZb-B4SqRyuXUko*xu8UVMD1Ct *1#WlJ(T vr%+}^G@>gWj- *USFR w'B'$>=h|>x@P6'W[QZBXl!fm sN *?SjLU;*UsS}wl.YO/-sb;PW)lC^Ƒz=ˇ&dp`.,zckM?rMA]7%GH9ՎPl1[\ ]hP𫂑l(n2QL kB|F*)Uȑiwp}qUkB;v*8?Ol*6m |pmPնhcLmiSF)んm$JTǶs\"`M26ɲPv޸lEk\ \PUzQI@RCs?F*TYQ\ZdV}oCqCJk G ~l (N튬f6)l1'`׊+Fþ!%v-nOią2;I(նk41(zI b늫Op(F@jM!.N*өB,j)Z~ˁ+c_ݲ8XHG0c=@q젨$ T(`֑iO|92T GobvR5HU[Tfs26ǒڒcOVӦLl J)rĺx۸X捶!Jtp%ң&OBk 횭RSnK6ZO1oy$a$CTWeڛPՠ~ݰnUrJG nd i++ \UDm&I*\84R2LF9.h䪳z#T@1Z&&6k|lHUA90XJPWĠ6Jo܃_צE.ż1KD⫓%WoV0u\qW *Z.=qWbUءz\`MZӶP⨥w G;dx2|aV LUp8t['߯V ~xG\)KDaBU|qU+ӊ&["Ph+T;[ኺVo-­ӹ4RVMC\:WXTbVrlp*8~؅[]Z sPqVmOcnNqUՠ~Zo銮 `k60|lCzt(X4qM5T B4ɸL#tEMu2䘢', ^q( y 7lPV2w*(}BMNo sB?b~_vV޺-՗+aB{aCdu#**VF*F/`J{aBPV!' bۯ|B2jp1R6\c|9 Wvx8 C`UwZ$1) Ȃ:INڪ"s,T v۾5(sڛ8)0zu2nF+ C-Xp!Tύ1楢yG«^ aSXPo~تa#74>~ p%I_|:|i\P 1s҂LR*7qVR ,6kG8Zu;Ca 2"C]+Z:e$T)޾8Uoԑ!J[:l( ]aC\A9شHL;E,cV)V!W9'rk*TQޢZ>$(ߠȋIQRkSb܋F+K•;PZp9 u&BN(Т}f1hoe[ sJjw !ORFB\EJ zW PT:t&}1UI*Qsa VPHSzqڣF! Kg~BU"[m74^<Ӊ4-n_đO A(YAqpPHjޘy#ƤtߦWL~^~Zr~9бU=VS U9)\JjTV,JMR|p+r:jh7OLBK(yR o!%H,o@#:TaV\@&)BASInU ֆdlbF) l~G5,(m]`>9AN=1;ZUs)GAZS Y&Z#ɒ=r' T|#t,+ Pb"޹Y4 R3n$ hW r‚]| k GvqbX]\P9S5i]CG*<U-nt)w\(m†ث[#kp8P9V\*[銷'F‡t늵˾*ێ$…$bJ#1 */o5\R\N\(onS41K}qCcc\Nl܆㿶)Z=B0%o.Pء48cqLUu9´EE{漖 r‡(#s7~S$~Zv8qRc!%g*Cg߮(s0"QaЖ"vF\uPFV镅 n~y6Kp*[Hi d]"]2S/@@iG|p䳉06Z;o pF~ZZQ9~}1Uj 0%˰]B1WM*«ר=%}8v އ* r#sO%4/ZA0C…*hq* mSZ#^.qBӶ G-vǚk!t}i֘ ZN y6*hϿW[չ ߐ'[MH5Zp(Mr,-)4TTW1]ȅ3F :g#ɒV + I R IBqqUa{JM ʎjEL@lZu*kD*u~)Z#<_TV9#rFad$"T"GB_s'Zad1?iY@0"ڃJc !J_6=~UUv تFId$xRK2L[h{;ÒBzV lP pB1cV UBH n>÷*znREx2~q报SĊPQA[)@[JWnњ;dNū犭߾*U;B-l haBW[\F(q.qKCg)jZ…Nq\})q. ֘\MqWSVث\Uruz2p4=pzWZWp%gL(\d}8'8_6(bXaWS[}1Us-K#逤26؍Z; Pp~v*ښ`WaC*ڞ(oT6㯇)mVvWॶ)CN\:.'aAo-6Rk 9)B0VoCMJ4HǪ|7 deɏVȽǩR졷;ɠ-CQY? +'dWoүO~Y޸baC wG AX‡4`I_ Ī68B \h9*4bJAª7:ר?NE)[cץvRX}%TՁ$BKçlbo3 1ˁ(d÷JW yHȰ%z偁*pNF%CJ\s+A J{qfb({TwRb_Nmo*ƥ=G*=*:aB(=5*֝pZ@lr[ *|OT)ub`Kl* B"@W %Zr=3^21\t榨p+)r*Mq WW u_* ]H$K&c4# !or&UѠ ni mIĨ٩CtG%sOc$ CjiK~(ih@"R$xSh+5:|+ hPoJ %v޴UO݊ Kr2v48z#75~flˈ >u8*SbfH'CFDl+[j!L};mBъSW5͊!%rͿAvkKƵV=ީ`(im&$㇓k7zUji|fbJ4Av^9ߊVVU+O"OCuWǯC>Xx~k T]8P[AZǚΙoIpI8 ?FEڞ>bɺqUPF‡ҤtJjk䘷.:F-lBZ 7_0`Vq 3%!~-Q*_NJu^Uo)# ^⽿B-ZJ9Y=r  ~4k 1KMq)lh~ eۙ*=TО27*@;ӡI֧$7ٰ*OnUڹOOo|*n?/VvT|V\PqV jWdC"XaW-z) ToS@8V6YȒjA8V xa[p3l|O'd˧A׶z *=_ #pNEVl(URfBvAjvH\*iU MGo$S=Won&*ѱhzTl Si7ARM$(}"åw?,RUQN$*M? mTpʼbT++p*P q AQ&kPr%Ww`U+cJT L>gիȒ 8KQqBsv;` T:$Qڽ:UGH-/9=+-9ST|E(Zpbh!߯%B7"J54 v;v\ Ip@߷q*JTn H"Rva.MV#J.՜ڞ#rHWP aGG1@˒iOPwǠ? aYKcA *Ca^0Ҫ ;3aﷶI +&ȖA}+w ).É( 95!Bڕx78{%+np2X$6~rCPF Џ|!L>Km҇VdsZ-:>|1T֮ Er)ZGS Jcq'B(\;uU*Oت'1 HGRۼ V P¨;{nQ"tG{Y@;2=̥WZE*O e..6 b+dm4q~cA>4) )PڢF̤?$-O߆m"NT-==(7*B ح6|PKت}>Ek^]V 4>l!wnݭ9q U+߯e(jШUWץ lU{7V#8X"-O?G&=SkNzu ܔ9-WcZCJj+|KP{1UY+06ojإ ޣH+iE" J}9.hM{bBI\*~UqVmQ]"'@wn!JuB]Jbhl n B%!cK.nHӈR (#pF&ht뿁ɖ!pȥ׊  u+*1BÅ b`V}1KLP㊻ 8UǮv*]JbS\z<*45"g F*⭌U Sl UH[aQSV\T+1BaCjiWRt)XzS "b,R= VZ8*+]W]*qWUء=G]žU**48`>.WŋiNm{b?~)[J1VVT?,B;Pqb=~x5҅vP w~D9~ߠÛl NLZ}#4U+|F\Nb=bzmaUzO?wt)]Z?vU9R~Xpb_oՑH XUwpk `VqHT%%~t`! '{b!`KTGC*F)\6ŋAUr(ljUr4z,ã4 CT'8UR>FGθCo ⅽ0c5-pޭ cYYBƘP>9lB~$P+M0*a^/D~7# \r=>LW A8Pp0!Jl:UR nqUf HxקTM ;OpZik RAqUDo^׽q V^[E@52mA90Ĵ%CqŪEWPxw'M+B.4j -*{TT,P=\ ߮;.} [Չ\tGs +-z}ث[V%(m\R5/v]g}ABT;1~ Dbn=7#lZ5+C,U^Td{1jݼ7&+6wj*}n2Ҝ۠늭2GpG\Sjt]*Z{%Gm*AHx$ҁmg'ckKH )ӽv!ZQo}T)֢R5RL(]?)ZGQ6; p4ZUZGl09?|*)]'2"%ى <6*r#Tq`(F9?"yQH8KUԞnkR !ק0EŪEqQłҔo * OI,,UOsLEk ֧TIㅍ"TA۰hCaIW|*7](5'S~8 oxSGqZ|2A^\!b|NƃtP?G®$iWD }rLQc*EnVj2z{~ˆi)5EJ}Z;9Cy퀔.Թ6@A=qң& l* U6_!̼Gbjp'VW1erb0J[p`: Q#\~ xZN~%Bp`) #dT«4DDsISQS@Z<0zN& ]_Aq p%ثVqVhW UǮ*qUoqZW Ui[;b=*® Un***lP+qUH?qaEqW+W:tT$i 9mV{b뷾(p=Ǯ*WSo[' m 0gkoh*Qm\UثqCxXUP-~ZNœl(;5Z:PLR۾(w\R) *vCCj^")#⫔t{n0$;hL( ׊z^jTŒiFi@AW.Jp1)@b=M8n?-֞PUb?x\QA8C'axaU*q _+ĕ?L XMG,#K~$UQcysRxG [OURn)^e)]bO~%wB1[ DŽˢ 6*)R|:dyޘB d]s. RE]хW)ň)X:W })EĦ[fJԯ?k#՗D*|78 B ڸ&.*銴Z%sWj~#p%k1†TP($Ӿ}تӾ.`h~cIQj׏lUƸUrSW%v P[2.cT7< ZBwqZkr :TcIdzt~dTpsJ9 Ǧ-AhՐ:.%BMk 6E+Б ! 'l(^2)iw=+;}\!KQH5\ =}F5k|40rJ k+]*/6ت!־Qږ-Ҫ8 C%ѐT/++Ҙ:0tJѯ TzLJ(1868 8l94p(kOXr*w0JHK؊`I5^*놌z<) OPܫCAҀ.5?T{ A"xS_o ~q U@A0G[A'O& Zڄ~9ԶzdL$%U;{fC%C֧"p4`iLA+uaڛdJNY6+oɡ58Xp኶6=W(qWJ܍}o$KFXDR8ۭ1W^]l/s dui*zU[pw|qW~Cˊ cVR||,K@*F`G%o%@(9x?ے,G5Ж);.fH*480-f~˒V]O"XMd"ڠ(^W/p$j{~Tn.T8:l𠺔 A!סGEBi-YJtF=Flkb6XEUQ7ءإr*߾*^D|VAR%Zuȳl-Nzq UŸc8m M @UV@elBu.jqBk(^$6pV3d1@}ZV~CGjUt_ޔH^[~U OC⭸:0o!aU5(E)e Oū\y%|R ޞ>"4q [0劭e@Qښۘxѩ|YI/2l\zbc`wR<^.OpB*~g".׶$-1W\*jӮ\d$qAE=JszkX})p;⫅x׻}*Z (_ʫ_EQڿwۏ%2l6s#zW#Lj[p߾Aw!JR[n4/ |p%Qzb qUĨ^c ۦ M:) jT\V!v@8Qhvؑ+v GsBo JW<NXژPM7Ȕ e)F)Z>PU; m_q{:ݹU[4T7n+Zo*n~>BqMxZ! E7jZujUnQg02à|# 6RG @pE7ȼUlR1_Pubi)\"$QȄmen^j*qCW6*c,M{bY$eU!+t.؅L4.w>t% &v8mT烢oRZ`In ed(>t%4@;0,E1r86^ĪU*Zl!T:&^,(rL[Tӊ IW,Ra Bz԰9|q<6{u\] *5O]mG5Y5]Tv1W>I_~'kaɊ 5E2lvc D$ס*\ȥc*ATKNF tnUp HZ+JA%4Eh~l]Z,zс"/4…w3Y?s}> MJLU#CpŹ8J;( M# Zb6 hqK[\Pb ǿ![j=bT,'l*S:K‡r{b :Ic|-nBO|%Ie}8UAM„1_r:JG6UPWAAM Gm4 i PGqW\6 be`U:xU[yBVH[(s%c PUtO ZtoQ ۶4ъgGȞSu'lAroaU!H6FW6lUNLz[j qVkqUnka 'I?Uj Ic1UTs ߯p*O ץ=H)+e;؅-q'WPZd"m!l=l[+N?|m[?MV$S]|D^𫙪~gAUkBZ lHݟ+ D)sQipOG$HAp›vS\-}͹? `|EN qZؔD; Zm)uq. kFF|Rx9!Nv`~%!;ª;و~E*8PJ++Vتm r Tnx,-c!\Y]@nZu*iH #ׯ[(2pjJq [P4R|vJR>k Jn4"YW"ʤzUS]qB۶RT+ ZU4>4«~xP|[xbU7 ^0|Uj«RԊ C @So(\pP+]b(\ʃqUKwj{J??aJS\(nAʒaTJf}ɧ޹ PfLj"WWTbH>؅.CP1*)QbFF+v'ȖAjEVVzB۷UݷqJw .卭 Y$bTW alDTdb?N)u*)=+-fkĜ*㹮(];UQnM>r<[XܟK JaTOqJ.4;Jsڃ%%m@brZ{KnTnO|JH;b)Il{ׁ[`zdmWY/_1VZV @iG/%тS0pJ8A J6?1ͳ7n$Ta+K]®MT6 B F]pde=CUbĨrT*۽wȖAc!4pIh^̡EMz: S t`ᩭz B Ѫ*q# U`~o+֝+b6chG\<I ʈ9 |B=>(iEN\uk[]>-|(\FbOL)\BJ4 !ӲaV槤un??eoN/OL96`ĂPxSDY$!J &IOEjV@d`jUWz* Si:sE ?ΘJ"4۾5'ڧaW8U\~?y\[`wnִڹ8.F|y zE?#4+ v*UrUc«K†\P8~p%(lWW(k*㹨*u[8F*U@mKpwE^XImFzQ|6R!kl [C;~qW|WT⪃*wfŔ (AȑliBC3[V_$Z87i;ST#|% 9 jː *l7lUǦ*\V!K[aCNl]1WP †o4ҸΘUO*\R*6 b҃8p݆(o[8m}ؕ 2q4;UDb4ZeJ}v$5J T\,dVkVwb9y5+Z{fV l(y׶Dd=?X~Va>@sb}c RĞĪ i%UI]q!1UJq,SM\ EOՅh{!-#g-ہ;bJ5503T6BGǕS"y ҇ȳ^S`VH1.U$W†~`GӍ+R%TLN*2V!`\,[;|p%jׅ }8i*BUE7IX04¦UVB2좿Oŀ)Q; (^p%x튬'n= 9 !%tx;Fd"݃vsgDžu~ycҩЃOqWHE>#IQ1\i-޸5 @kIр$U]Ot47ALߓ~-7I4 @xCب͐j>J@?<(mSvJ~'#/)^ P߷L 6 $ZV1*Ī}U}P_R~X*JhO (SRH;dJB GlU'"znjp\pQB+ȖAMh*8B @ F L* =&_JK*(i +C]W$ŤRƋ;&5gm3B7Pr`)N1o)%$xJjJԸ"!LU@TocKS+#a dYG~ ZbM1KTs=bA5A«2?vcIXVnP@!J%M|%TA1^{SV0㷆Lw8PWҫM%Hlk$|%*<SQL(^惆ƛmVׯZ>\ - *GW-@=.C.^X֪Ec6'`J: C"Pd7…͸|Ua֛qJlQ |CW87eFM7}H\ÌJNm 0sBOXG8VHI*__bmª7D,$I튴7ª* NDQ *:DwmJ"lZ'T*iC9H^?NWY:+m,`m_(_ a +PxB& H"F 6خb7|P׮*[q)F*܆Ƶ+^]=W4JxU,Mu!O6Am dI8_NOڝB{)?u0tHY)O%CNǏM ?ɢ@*=ZP}8Bр`H4zP؟[^BJ7jTpHmw kr"be޴_RSҿv.HܾA'iv7)x#I^Oz6*rF  &Y5wP+Ǘ늪Z"\|H'2E+\'erȆ[&k{bNC*=UW_T$ŷV+ankUƑiV%ǏԜΡYO_9}XV-,l v>RԶRļ~) +nGbVn=rUN⠀{?~¹"\2w9,).6.; Whb*GQR7&͝&cߩU9pAƟE1cI&֪+@đx<lC2P9cZWP(j}yڒ7S}B D{͐.꜑bv‡FEZ*baUp劮bOMO*?v.bR^GOZE7\z6[;⮦(lqC*Uo]wZ'*㊺;b Wq81CV&PUbI[i. qCWFNh4>4QQ„mƤ&KRO)6t*w lUU ;; k6w*qKE(h▱Wb*xbѯ#CdN钕R)k-0Ɯ[&تkPZ M[huqT~%F(kfF=7; ◉LVB#>OqdK`liZc$۾(97OQeM[%+!ve#T8U.CF8ԂxbZ=‚㊯ST#Mw ZX;(*w%>TMbBAmIPC 잟,`r,JWR|;Cj|p%P Y-CJ% p+l Uk ߌR:ddD!x$5޻~B keB޿~ҞP0`VCHh U5(rwF%-,$~qRڍĪ,z }31ܐND.5vS`ej@yw~Ҋ kS;N#JaCiԏc8tColU[ARqũRAңWC~uR1>9&-W|U"z ԏ, idE6@UpoY{mJC1#vbC Hf ָkN^`) wV #oՑ"jK0"Z=*Q@cֻdRԝa Z |p\%JmK$bW0AFBiQQ6_Wwb*oF7K.nV6 ^hcL\8Iv8rL[l"P\qUcJ^!w*`h„v9$/4 (h_HYɠA Jil(>vxFƻf 9͙,;̜3>RK?zc\V4#q^KW:Pm*TjEzJ( oR_JjpuJI ru,%YB.k&% C5w-'h{heU`~l:S$ S1_? d.˶(. rDlw%?  z7*J }E1UKI!>IFP/FXv;q-$2Xν768<0bF8w(\U,,WiV:Kbi]2U ϸȧrw*[ٖ+0v/ޚnVǦ"TG|%VmB JJ0;mQ…[gF*Z66@ b⮙BQ*T 8Up8J j0%ba( ?P`U!!䀿c}S\Ur?FU}*aDR:t6p'%B-WГO+ˢ)8-`Kq|k"R_؅+Id^*1V9&+VzdY4:|*iDx#q<9dnB1BS*t5(TAPW~ O/j44ew j\U`?I(g!{)~Yz ڗ5['t{%BV#pNPGNT`n-SՄ-JGRn(A#|HXBx1X{b`~IiwqWU <N* J#C@UiȄ^ۄ O\(_/؁ "}0H֘EIpEN ,*;w '(-IՀl.k3 UG|,Z)o|UbK(^xR"Ar4` vAP*ib(_kKC&âa&=Hy)/[ZQ#įj([`'e2߈=~YX>@LY z~#J v'l%T'ƹ iWt@}7†sz%VB>Q_ҥd;TW|P.$W ㊸CWS:U0i9L4CvC!L@ڙm5ZzO`) bG' PSJchȫXU W!RR1C`oR…v8P~x}5.0(mK]:uu[8⭰5Q N)hS#v*S7\UUb0g\Up\Mpbb ۠8?^AL HhĎ8B e&!!lh\vȈ23@˚ Fs7/J+I+Я~oj (l57WsK‚CX{b#8Sm҇i*@IXOI"fvųNث\Ux뀤4@ rG|d t=:rAdAA5B@&-tF SH?FDd -Cc!{ ͭ@S j02Taڵ.JWE>㕄o$)H8P6E#dJByM;+ Evד>8 8C7 S|,[PcUw'cA~X`KۨĄ\֫UzD zJJivvOJabU3W& 7Q}Œw[*Q ~[d WaR`UZ1J@Rx(*ȝFJ&\R%Pݻa&$) @["ARҚTaCĨTJY8]kЫ#8ݏ?p*|0گ+𞆙RQxp0_5(n~xj_\"OO?27*kZ*VS9;#&At 31BQ5ƃTu֛8`ӔP**=*]fRz_$Jř~"N-zd١ZJWt^b9)j]!jkZsGǮX)QmkrKMW JByރZ) )94ӑT9˜T5IOWqVE 7tcP}Ĭ#%Z~m #cB"F@FAd$!ً&+ڞ ª*9 >M"uKUTjGy#)Y?rj{t k RQA&Jv!j<[@ Tk V1TNUo 26^"XWweau'˃Q[!Q)OpAJ@`õ>UcabԲTPxWSnTȲZ?^D)jXC}$,+JH1^⨁yc+ӷ8w[C\I"3Bԩ%ƉYH?=4ob+% 6jsނG&%IU2A7 ~2+O](mFإNM!i®(UzSу.([ڝ)SP^2LU}@KЊԘ`GZS-]S X:"qyo1|RYM͗LiE;L!Jɡ}&µ!!li2HZH |" "Ȕ>ZZFƴȩSP !VɻWIS z4AU3RwB4'pKU2vb*0x)-N*Ĩ_ u?"y$, HA r(`) c> @m5 /81WRZ«PF*㊪%i`WqBbm%obZ­^1V!]O(q8+ZmKDmo5v*8U6†liLUi8qV *}SLPs88HAxaZiq*[an7p@qVt8v bt®p!UԮ)k7+LP| >_ ]!ZMiC s\ lV+SE혅R@zdc+fcJprL.ԘͰ{x+ՁjDm!4NU'€\J*rC?~U۹LSmjs~ 9%m|*F8)IT_jUG\h=ip/ p%o*qKU50#^@n퐪 A|ˉMs2;-/W)G 5+K \E B RF? ;T ĸOՊλ6Pu5Z-^wZ'*ljtYIیQFbP N3IMG aۏS|BwbQVrr.{O#5`(?bqv6Je?ᖆ2) ƜW 8qI'~<Q\UP"~TZ⢾8Cܚ8EErHq> sQGl!KJ←XO}n®f)Z)aCUXz0%J…ѵĊ)(TKdV\-;%IEMMo DSblZ]|P)\t1UvRx\!`6p$}@ZZ®8ˊ~LB ϞoKXUqV߮\qV(v*[\qWb~*z`KXP\ (lb,Z=7VLjk^ONi(k+lUaŒUMi8zaVKV+xP`Wc*Vv)q UWn;tE-/^P};ɽ޹& |PS[5޵Vx{aPح~ ݩҘPy2%W>XXM'03Sq*'o^U0A{c ũ_ᄠ8}\,:U9ea!/_R~kS(C$oMCoJiMY\PЮ+*NF8.2L[)qW/MBS˥?Py+5{}v1ikAJһnIQGD= =d9y֛צ\d#N"yzj}C+(hқ{Ua5z5; *+wjJr4rAhVaV`U$ֻS_jJ֯xkW\Ry}c$X5j|qVCqKqB~X5*<+)*1UD7Ңneت‡R| S(_:wpQyTrwY7-=%Mu+>g$ZծiJȆEV+R?N-ӊXX-yS+Ͷ*sבқd(L݅0+C wp*aVѾC,+O݂I o$8x0uOEN;aBQ=OQ\JB>ٮ؎H-mXX]R~><(TMRхUb%:O6>׾%!j֣fi:dY)-8(m1 ]m?i{St*ا ueMLU>"{u?%N&7ġvA)[ מW_e؄9?D$^[{( r8ֽ>dÏ_SV1EC['?M|)ت+㊭ Sn_^+|qJ*>_*k)›xXI:e0_XXurXje-l}ҹaUxC"6+5JT/W۟/^?epUZ1#=Jۮ+e뷀2*MLZP}9JY6+ֿFnۏq<<}k%y7.8-PqYOqν,lbӨ)DCo!&amÒ%Hw${x#IIjb%Yq%;XÓ,Dž1q a:~y{.1og}B󪥂Zj4H3iG"Ř -.ffbm9RSbkoVM40TgÖc2+XQ~Th[/KֻPoXQ~XD^XǍiQKj[KK;;\G^EdiNkubDʦfF|*Uk YhHᬨlO|ykx{r,]i^g ,c) m55MH's5u/srlB++wǮ0!xUMj$?-yB]4M[mm$_C (.iBvv3$֋pwUֆ44YN{{t?:a< &t[dǶەuEe•fYNp%N,ܰ*/z-8fCG#CڊF\:F`[KG+{bEXQ~nQWܩM \P@ Hߴl_))䨩8`ϒGUAr,]Cv\/4W$l T8ݖhz?WhĖ;)o64$ES{06-ƶ%dCO\|9k V9,¼=Xo勿UFYԽkHzG”3Mgyd1>ZٸfwIYzwBQ3юKM}ED\іF]W ʋ(S~ҍj#F#6H0/Y餒Xi'1F@gk>)Ɩ-\S׾,LsfJ\'b}^z-{bEXQ~r 9yǘ_ MITc<;z,%lw+T(n$}}EmbSe|a^ Ci Yrlf`8RT&he7ikFAWhm?y-8*!{buyϐEUAZ#AלKO1[k4 ;)/nt}&"@$R',ndq$r-.=,AU8 5B\4 jsiyj\3 e}xs ^)i$pF9uFg.KbŖ Jכ5֖fF٣$Viz$R?;[6X٫$C۳3*o4=2 񬭦}DŽomjZn%hk9<#TV Ά^kn7gIY f q{IT ಇXp9&|d=W7J[?I|b./c +hFNJpeUrE=\nsTݙ%Eahп=t. (7 X9fvGsATwྯA酔P`Mگ0ѽǛg) Ѣu:F-TIV.vGZ⎎G %$O C#6ִn!hoUH:< nߴF02<xxb]v'pn@O yҖbJNC8 pQT1%f}& $ )ͰbHFi-s\2 "T􏪚hN+C@̒y2XIcZ˝:zcls[Ja|wlGk*{C#>=B{ܰ*/lOd}+`~[mUU 8v[5@U:;tI=04*A,Rr9|Yk lįO{bEC.lLVƺJTx+>CQ<#^|vyq"i:?܊SΗ!'ORM_:\~$nnn +cUZ})ڣs';F3y>xZ$V+R3Ӽ154c1#> ?MjɹA[ghq=L8Cpv̫{}wԱtr-o|,UIx$*>Js"u=O!w|@tF &:I('=;$.q.q9Nd6E}$[y$O ksoW|U) $DFG}"L5]_2h#N?TI|b./FL Ce>з 6_zv&YԽk2Pz*Zvˌ36FYFC{I\{Z<߻Z*z#`㮴danN 籠څ`v!g ѡK'zKCϢC+>OTQt2N-T7,&Ir98v5ok]GK+zns[g @,h[)rb!\v%kaSpeGJIP28r s"GITѮ"0(dxhh m'`sף <>ƌ~!x>+ke6] dw(V6&aj5w!|WH`Yu`kCJn2v}ǙJ %^4G>i;5r*M[Y<%Jn;+uCps$i(;^$U,[j#0~> +J]#U  s|NB㘧ox=hahп=߂QZN=09敱DZDqwGvjk[[IxͣQR\MrY2Pr/vw xWJɑ1TTeZncufG#n(b{,Ks%y:ϴM`W4Sr@# d{J_ۄ=ڞv:뀦]1ͪ?߰ 6^Q .W,ȞP`*XշV"]Tn˪C'D [Տki*>7FNXYE=xgkPS"Vo[ nUЍ b*;%,.c%te6ɠ9tdD t8Ju7A|q q iq9K KWT'̢ݗ0J_!vlb) v\fbA.,Fu2qVRLjap|r8n kcbalX]_l:?)#Rݚ8lFeS.o\ K; #K\%hlTLY0U?TuRa{EukL 꽄`B pe7zk"h[/KֻB-$z +tçc˳ss;y5Զ81Ty2F>"#%J\$pkZ'r`,x 6z2rexOКCS8-<]nփ;+ǴFQ+7 A̱޶nx3ý?2&U^t/mGf+4&9Ibfzwr >د6CxQ5D ki2Bfe }mnT!ՏٻTd9\FsꆪĶlO,TΕő5M]II5<]HxHxG wiEv1gwj겞1BuY_==t#0THi/\E%,`whr6_5`n9}څAM_hhޅaiop.܄Gt}_HY3ZIڴTS`pTWD9rwYz9 '04JQRaT4Ϲ]+Dd#N .>u\ .3jHETVWooH2#̰VcLbdCƇ*r %G5n KjjhWA'!z6IQESX+=ʟ5mՈWwx{?j۪y+A 3Is׳TT^lqRyAPoV u4;sY3I>WceV~Y_o[ nEe]='C4dERM_:\~dTSy_:\~s+b-W%º {FJmve|i h'i9Zgy6q"cOO-4T2(ƍhTT}&lpewU9ih'1 {5}^qd<[?DwAd[+"\Ic1X9IBzfoRDз 6_zuB2Rz ݠlY.0uL.1xm!xtgGUMQHc'#¨ޫ,A}V뜻>ZQ÷S+-Vdk2k;Ox* N:]L*+( _Q6z>. i0A*\Ǵݹm *H%&?=N]K}FF7ĮkŖ%}L)iVsEohtqfsCeQ/.`@.fnhƻ)++vwZU=ƟjYߍ=-_;Mn %zEWsWL$ lPM>}T2lGv| ٢sz "5p7}(֢;˽O#_J5v!g ѡK'zGCϢD+X>OTFU t8jF[V t8Eނg8Z$գӱ|9-NLRY,O,kr-#h!m#6 DfCGݎ=B$Pzx>bʎ뛟NU:B]k}i\FVokOyc#|29X5"6U+VhG2!LmYSHv-*¸PS]-jjsFD,a}~ Q]h{v<٣;y9A!k)lMS_ursK|UlKsDc_ZfG"o\0lRwÌ Z}"1 ]I3`ksGG7<9(EGqZ&cy.R$]p̃ϽAE*DO'"dcX;-\r0k&\OII2:2KKY*{Wl7h_qIY_U 54c73Z<%e1ܨmQ8̚/fs̆7gCpWwx{?j۫`*Xշ3g>lOL*M]Q:$T6 zcrǚ"Vo[{2N"i:?܊ bA5֢9\#b#'2W8]7QDK)cS~/S.nah{\˜s'"#kY.1\-RRŞٹHR>X5w߹Dxk]t 2Fd / "b<;H[E⪎:82. ].X5w߹Dڮzɪd2TN$;s'g}Hht0QQ_ D2kF6( R9K|("j)r^mE wEk!qtmNÖAqQ.n1I\@݃Ĺc4t׋Md11vDgr\4@DD,aL5ҢdݞcW[8]7QAp.UHˀ쁖\'2|R.X5w߹DJ.؎W'>A!+m۪dG$)'e,qoܢ|H]yZr͠Y\DN:*ZuTqsb'3ľE*1dӰ,n#'4b"" ZKW mTqg,gn`8]7QAn7W]+%sCLp^D 5釫MmZ:"-$6R9 =7 ]Ҿj=TגWq+m0_MW &9cMr_K|(rdu%vR3n dSOg#Ȝ2.,\DA/쥎>sWyM^[=m\w%fƾ4U[*sԳȂơӎ9F=P j)]nYM8شk^"+WYS_Rʉj*$9Y^s|QDA頸ګWoX$,p=ӎ:F=P j)OfAcDcežu=3Cn%\ՏUWR,/qDD@_ffM V8<~צLsj6jnWe>QШ92ꨠ'n$*]K$b)׋Uk։[-i]DlHp99R9 :IyēE55l7JA-@.R"UYhC_o}=\$f%I{)cS~D5ZjKC:gxBc]}EK#!130x+JOU'Ee_Ӽ TMMGj6 ˏ _%YS=O뾩sT킾Zi\p[#vbJt PEq ](7 ;_wb+m#bv$F6ҽBaEv+YP`Qל CyZ^jQL;֞V¡],75BxYkqA>C>C̿3ǸIw'Iw-3ǸIw.]m UմS Ajgw5Eq(pMeMD:Žr6f3ğ!}RY`Rjq'uTq'uT: ͷ fTSDj5 N9\z\jAʜ;2#0v#sC3/5~ZEuy#fw)5 }|Ue ٓ\EkOͫOVE {ZѼ )$fKr!zzT^D{}_뾨m};`W7\2VHݟVwe\⫯cI7V_;:/yDwwigL\%YShn%MiozNMT֖mܪb,Qlg 2(=PhAGYxŊYD3 z[Ǹf׷<]6#S5wIp|l&7s8lҭ[EDq7&Sm-qTUsWQ!y^d{s|5짉2T_ˏ{I II֧7ȸWtȽ GRS9`2;Es#XjǶ}2=/Q.>*9.3;ZQ "gqmRj]ꤢUCaFk a‹賸IoѾl;s&9>VӐPTĹ|*/޿/Q.>j\?ܞ毿#\?܃~wlGG-Ә7Ūsȍx<=<Գ 994=W<ȍ?O?F0_Eo.Dw34Hz8a\׏UZNwX5÷pc#Q 'ޕ,aʪ.䑻Gh q8E\@ۅw,ǀ(+5]:d^\]:d^Dh5Pi{wE>V4LDD],-*_SU gqmRjݪWUd48f3 $fxSz,!o~$챈߉Q}]BǙ{.)JH`wkEWhY[zTڤXC*;ҥ2(Jƾ7p8V_-_o]r{"[o܃9!yˤ+TR[) B ;2 ?O?F0UoVe?|VzbnyQ h1-5[E;Z|#ZF2h|oike{9_SEg;CPIm5,4$&5'~@d<ʞuT ̩-UKQDEDDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDDA9x݅aGO+^ AFRV.?VĈj%ՇKճ" <}jXyH*)g+=^Ej4f ;-Xd[?cGG0VQG4qN""`X"yQF Dn!O0.VOs0~QX]?\~WRbk5QN""`8"vmDADDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDboinc-app-seti_8.00~svn3701.orig/client/test_workunits/init_data.xml0000644000175000017500000000575112636704202025564 0ustar locutuslocutus 0 0 0 0 987 0 0.000000 0.000000 0.000000 0.000000 0.000000 60.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0 0 0.000000 0.000000 0.000000 0.000000 134217728.000000 0.000000 0.000000 0.000000 0.000000 0 0 0 0 0.000000 0.000000 0.000000 0.000000 0.000000 0.000010 0.250000 1 60.000000 0.000000 0.000000 0.000000 0.000000 0.000000 50.000000 90.000000 0.000000 1000000000000.000000 1000000000000.000000 100.000000 boinc-app-seti_8.00~svn3701.orig/client/test_workunits/reference_work_unit.sah0000644000175000017500000130211512632322553027636 0ustar locutuslocutus setiathome_v8 reference.wu reference_group 14.853 28.55 14.911 28.58 0.775 Fri Mar 3 08:36:01 2000 2451606.85836 1048576 14.853 28.55 14.856 28.56 14.858 28.56 14.861 28.56 14.864 28.56 14.867 28.56 14.869 28.56 14.872 28.56 14.875 28.56 14.878 28.57 14.881 28.57 14.883 28.57 14.886 28.57 14.889 28.57 14.892 28.57 14.895 28.57 14.897 28.57 14.900 28.57 14.903 28.58 14.906 28.58 14.909 28.58 14.911 28.58 1 ao_1420 0.10000 1420.0 18.3538056 -66.7552222 497.0 168.0 0.0 7.4,5.4,-49.1,-1091.0,0,0,0,0,0,0,0,0,0 -5146.7,66.1,14.3,317.7,0,0,0,0,0,0,0,0,0 sah_recorder 2 2500000.0 1.40 0.17 encoded 2048 8 fft hanning 1048576 0 randomize 16 1.04999995 2 22.0 1 17.8 1 131072 2.100 1.420 3.0 3.2 64 20.0 0.5 40960 16 8192 256 8.250 16 131072 256 0.5 1 0.0021 # should be beams/s rather and degrees 0.0105 # should be beams/s rather and degrees 0.333 262136 8192 # should be seconds 32768 # should be seconds 20.0 262136 50.0 65528 1 30 145
1418920288.09
1418916015.62 9765.62
DJJ32/(CG&\%:PSY]&BY\ M(NN46 \L1'^V?YQ?S)/+4V8/)L[NQG\H>.IMFIFG@ DQW;$9F? :G:AC]7XAJE7G@3@^(JW?.?M0;+:HMOK,%S2_%:Q--OS\_/?]\?M$.(SOHOKV'->&+>T7(\A7P+;T1XH,C,0N1/3C8!2S??RWO&0" [$V#>#S;+=S^@=>0HP>][^>=@NT!5 .:=81'1 W7$[@U[4ZT#CK[U!L^ AZ,T==Z=@_NJ)50&30R+[55M=5-!^A1RQ<> OP9(V/X@;@,48K="-3?T I66C\7@UR)S\,2>P:5V58KQ2$QK;<9F1O_?E4/8[BR]N_'(10 !%T"-#2 $ 4Y:C8]%O)K4-,+$^\7+IJZ2(-G#S#B8=,[@3C7.7"$\/LU+;8\SYTB-!YW)$YT-9-&V'*,)B=TI6K@(YL?M6UFNEC>^5&@Q:@T5XQDJ3 4G\O*67*ZGW?$QJXH9U&QOJD_I:A$R1=F@ZA^H8/OY6HHX%/5#?!7E#R/&#W510^ -5;\L=\/01\)F30M0F;A#(U.R1S,MM"3HM=P97Q^GT,=LKD K*JR1%6FH-GO497)#.2!LB1_=L!E >CK]!L=?(8X%&U\*P1T-B.'CYEY6K:*Z345 :YV48]"VS$X;])B$5WDN,:*_82$YO[@E%D6I5!/VK+GDF_[(N@O>84=@598GL,V*@/!^=G8MB-.707<%76\] ,'VZHXM&,%M)35CYA(CAO2Y<7\LS-B4-PH;"^:1 (=M+P0RE85H0BVE%FAH\MP=BS^"]0_;;R)>12N)@+ X#$OJ*DLZO,\L@6Z-< "O1 P/?0W4OXV;L)@!"2$@8*@2GSE! EU &O=YZG'\2HZ7#*;XB(]M;A?-K=BQ0:4[SAR[:.6QZ;S; &V( D#$N(+D+Q0#TN(D3W'+!@RK7/*"):@&[G75']ZG@)M&?/4"-)'^P$&H#.Q1P !DEW/0ͽ/N&G*W!F,%,)D6V<:EDH3#K5]5UY+O*+<^VXVZWT<:R2)RH&;-"ZJK02, =43%K[GE(?)G9\D] S\TJO^JOC@1W=70=(%]+<\P4?9Y=SU7L^_*&*\6#B1E?#S5 M3)5?\8@=@B0DGY#-C.F8FT_4M&+A6'T %@(PC\RT,Q=J:U0\H/#^,LA0[R;I.\-B0*ODA)#TE5>.QT_0)(P$<' "0H"B4.GU T?(+"QFKG1QP&542$8^;F 8& LC+%_/_5X_!A(]@_"@-KJ"U^@].)*XRIJ"R+3JJ !$4[0G?=2BPFQ-DCEI5I:23(<]1,55Y?K@^:%?#HINA:*7"Y$'M1!/GI;Z]5. F_P%Z4(\ P8?!!(;^4)0>?=C&PABED14!F2^%ZO@R#N8G%RDRK^(9NS93M;+ZF^' DO(]1#J,BW8"R][_W7D5!E3(XV(J]H_)"QU>*#@#5FTA(I1AMA"K:P9F1^(K "%)W(HY(O986]3"3;@L)AF <%>!4A#Q'Z/I_[Q:X]HV(:Q7&N6$V[QZ*=Z7 [^@J $=.<191ZI2$DZ07D@! PQ+01*=*2Q,1/"]6^#9CYCDRM#9OO2JALORL#Z\" GR@S&/!Y@!9'Q H8R!, S8A0AUS'[?P.RHFQ<;5.73./(]F.K=7IXRH+*/O@#7Z^ 2J!L4!KV4L,EW?.][#9TLK(Y\[*@Z+U6*4/ JVG7Y-*,)*YA88?D_CH:R::G':Y%,9=0E# 8]O M2PZ8 3'TSP^I_";\/ZTS<.7PDF$Z!]&W4YFX9K(\AUL=N@=PT=Z$I,!:*#CZYHMD@:* NYT<:YBW#&^E[2(67/@A=5H/BT8*I:CH@OD^?.%R;' YPG!C:]J1(]8VZGZU_D[SG0$LVK%4 R]D.CDW5 UV:UW"%3CPE A(T'F9E[P"9>RE#P$8[IC5*NA'!<,WEZ3P>+*\89>J+ N?M8$#)G@;_K0;4,P'L5 RNNH4_\#9CA+T12YX QW;L.PSLC%Q Q[EC/IOFB2CIS RV5M&-.>75M4V2O"[-V,(_E0)LR(:FR)1*YRL-(H<8>WJ4S_./7#D>-:[84?%Y\* @"/@^P8-O?0>ZZ4G=K\HBNCWX)9"S76G[AJ^<5CG3^7F6_7M)+&6RT[2'9.8Q>GP 1\$PFF '%]B--KA5?W8]5OO9';12U4J(DV)5-C%#;@T,6,';@;YY.F\?FJ'\_I)#E8QF =C@*%>JN!L=KT_+@0B&/\1I60Y]*;'-#J9P[YXJ<,JM. SX2@XN$Q+2-[NGGO_:" %44M^*RCS-DR71#2'@?WLLB_$]A3C-S\4?1YV%\X^# E,=]*P*8I>OK<&TE9E:(4 53FM!E&D(VC+D"#*U02SL+R5PPM@DM/ C#<^#:[0*90"6:WIR@C='5",Q?]AX)X[ 05Z=I-(J68\FA4C_JCK%7YGO K%LO_^81G3\,V M*T-+]XFY"PS%T\];E")-LHW/P+$"INZAAK5LZ.T3I#PI ;R%!TSU8'X5VDT1N8 ;P9NQ:@_W[A'$.Z'P/\T-"Z\<]C'EDGR@\O5:TXJ@S%XU:U)QXVA]_ *#9!5?#O, Z1T)5AY17%M[/JXKPKGXA*ICK91YY#_X 5EWW$ U=;/=]$G='?( 6W%W=N#IM)CM G[Y6Z*G*[I[OZ[>VONVE)U_S*\W)#/8'L4 O^UT56?A"_NS1P)W'O)O&PABMNXVZ_W3V1$EJPE:O_?!??I7+A0J6:^I]!?E(HM_#(OKA3)T!Z= =EZX0%,8X,U-(<^QM"R"&V("7JM38P3I]WIB<>*?RENT$,(HT2A-F$% 84:G&N 6 _(Q%MZ7&&!4G_,I/VVX*NSJ?NJAQ%7'[3HP@Y](R#>-8,!2: GZ'3=;*=%00 8&;-:K;^^(!3M%681R$YFIHOWEM@:]/4T!O?6U=8KV*'..QN&#,1AC(PRMYI=" ; ]L)H'ZE]8'D\,VF7!Z(3#C\-P\$Z9ATN-:_1&'1> 4Y)!LX8Q-G9TIFD] $5Q^/0 N]CBV:_&C!%WV>;UKIJ5+$)C5SL[<#Z=?D!I35AEGD_>27H 8TB\AK2!]D'/:E@>Y=X:V-=%XVQN,4Z58.#LN4YZ?Z_M2:777VKJLL27#*G6LNOHA%^+N(!CN.6FJ7*JI238_JRU(/GSP Y*JT0'ET255H."VWRCM 2"^5!1*N4-1_>B:Z &-..**<0^V]C4Q_-IS+$!R2/@PY!4 <<2A.0K90WI36B1R.Y69Z"&+63VA,4%5/ JBH"W&27^**R "FTJ?+.4J22I#8CM: O8)]W4]:X6$Y^>Y@7K6D"'!9S,K.G>D-,*CO0TKS>!9,[6+H?")#Y6A46C32/]@K AH'X3+R&/SX?[9W/N=]9G1.+]/U^SDNK(,&BMY^@*;=N/U-/\XNYNCHFP09U;\DS *$!IX$G".+=(6\,MC\F(G;C2-*@OF.GQX(&:/,MN/Y4)UCL7D^(,F $/14=:76H"C90L%V]^P)$0A>JY08NVWW$/M#=)YA>?=]M.K%)'C%)Y!ECH6&R6-^ \?6GUF(S<':#@1>?2"=_X/46UPL2@QWACQZMW#/]:MBQ,?R ,EO2VY&U$@5@B'6W CR;6>Y"[VXZSU.?,F(T%D!X1-=&@(9N^JF@8"TUILS1?;E,9-U0B$.;PK2 ^)@-P '%UX3?4;T_\D?56Y?T4:<^G1\*:,R\.0)%*@6M7_YCVFF>1!-%N[\.=Y%"H2MEK'LA OM#9Y&Z&T1/-JG7E'C@5JZ>^FC2!YW^R\%C M-Y3-#--./"J*23/W?">%Q_B 5R< 8=/UUAE(@([O+])?>BL>'"Q>(V AQ$!YZLV'"4823*&!^*WMQOOG"52M\+@>;*EM V6-F(V*H:L]'&N_9#7-)9QM" )BP.Q[!U H23RQC0?,3S1&-Q51SJ !P--_1E_LG*$T;DT?&45$JBB'QVBC1JMTM54&Y K(R)5*8PKUE*PS.&"H!<%2KCU'(359FI-CL^Z,]VH.D4MUKF;P.H32>.-M1 5D1, /#HJ @<:J\3VHLKC=V W(IBR>A^A='H$=X[6H(_+ZL($V!$02ZL(Q.O^X8Y%8J;+04; .50AITG3&,(B.T* 5=05&C)*E_8Y#7%YP*+9IO3/&O49)QC]%>Q0:#JY]GF_%;Y 486SF'"S;\?6UP>V D@XB6F =9SM5J;J1C2 MF[.Q?-)M?:5NY6.Y^\=8YI(LG*;H>YWH33108O_=!G#) -5:4P1:YDKXG009BJ-H,TCML:&Z\-T+,_<,L+YK;;BX1DMRA9L K% :8S_T@X*0_E]%99WSV-^?&)@JW-'ROU9BK\2L^O@'-#^Y&>K+T-<3?Y[!+VDQ =R3[=QZ=L++TIOJL\4(MX!XR6,>0XY$[&S\+_G _RI"GG-/I= )VL'8Y"LV.G^ M [.*#*2K7K,W(Q;'G%R[DD ) Q!;O!(Q!A%^IU-4P,:C/+!G45C2M%"<1<DU_L][":PKNW&RGX5MB43F]+1)Q+.?,>WJ_3R4C\J*\_13$FV%> T!O;^"GKU^E+-_+%1*1>[YLXRA%W&FDXM<1(9B$+(8X19.QDM]_VU5H]1]@@#)Z ]CX9R9B"5PL;P- *9S)/&Y#)!/=H3_L2-]T.,+ J9@6=\1YD'?55<-W@?-SO]. W AS:RVMAOW287AGQ&*R9G&H_#,^IJQ K#/'B.I%4E-7_)T@FY.)6Z"]OYI1E5,.6" !+#7_J_7*&+\ [L5025 N%[U:8-BJCXN!9HIM>\EWVS)HS4.V]'$H"&%%]\96.;$ = JR2!9#8)7(QC2$HL$K>_Q\ GF$4!Y@7')!D_8T=6L]VP:A%_J]BNM>X+D[]?:H'04DR- >MI!$QPQN:5U7N/G&/ L_6@:M7-G*@H&"^L*+!-X5R0Z2#9FNS:1=; 65I^6E>(5R3G:C,7G*I/: U:KO2?1SDD5^PW+;R/:&MQ,F: I!V2L)DYM_X!O-P:$I0 "E#M1JJ-P\DD?]/YC8 S^YWR&>E*V(V(#?\5^1'!B2XUD=)G4\%+8WK(F:+NUL]NP6[J:G;AG7=HZBI^L7[ Z1NB)@'YXCG L<89J4/(RN+11NY9=_KF[(_AP/HG4S1@@)V"3HTV06#+@V93PVAO4I%QQ>A77>2XE-*863/S27H@J8Q];!W-OQ I[QS)JDO*U+D1HVGG&?!R0^+@E+\U2,FT>>$RUK :0PBJX09(UFKAEG'?N%8B54B 4S'B(N#MURN\S2WN4^?&#J#PW5E0),<%>ZF?(AP7Q'FE".3XN5Y17 X@"RZK;+UJ)VJ/%CRHK13,1[<]#+M;!O//4$'XD?7.'5#-'76.OQ22+-.5+NV1M0 3^R#&M,!:%PVD%T4U73LC^? #^P2#7ETRJO5Z&W6ES;(<\#'.1%I"B>%A[YQ9,421?EFYI5KBIK?+%\I)&G?:9$ 0R\O=ASM $S*J="OR1_PZIVK?;QB+8CE"2;^T_]9\N7(!?[CDFA^N6 +.*QRBS^@V/>9/Z6U1$_8$&MF'U'O:?=;:28SE/6T,:<9S#>'J2 >3(^ ,] 9("M *&"*A:6%LQ%W9D< Z=O$VUSK$ ]NL8+'5BP'.LZ\TD">>+=^%4I3#!,#&5)%=PB ,5:=FZ*&XR]7,%Z_@- IB>EPFV9B1LH,U]R+F?R)MBS4-4)T;'3@K@=!J! 7Y:!DS&X=&G0VQ$Q^P3XUD$JS4_NT91[\TTZFSEC/T2S+Z6#&Z495MJJHCL/2*A[ >'=XLLJ*PO\?1T7P'L]LK'F.DPR06._YT(XEN]0N[WD$5A!9O%/G]KH>ZA$2_D=Q 16F]2:G&-9@4P]MR !J"FE4N8?<_.V-3&N$,-.M[BK&VTK@]1$NV]U%]BM8%CG%1 X)!U:#J/_]FQTT?F01;8*)FL2GZK#%+XW4:8!!>D;K'+,+,!/V,[RP0;-EK%Y'+4NZVVMP]/4.. G;?]PWB)[PG)BYJV$JN4C, 6F+)?@T!C*KX*_ 636S[6QT9('6;9(G$40Z]>IG)PO#X)X,1)%PB:6XQ%@\?LZDG G1J"9[$4WVU>$IMDT2TZ\#Y8,8SX_!4A.BJNJ)_+>^,L??XO@-*%<-/,Q0V;T?,K (>8*NW-TG8>V_Y$'_^T,MXBEM;?93[/P"MV*W#27AF;9BP7[C/?=F>T2^>-!KBL@ 236_5]AE7+W'6Z,%U:.D<]M-PF4EY:/!UG!FV,\)\)Q%BPCR(='>&MGR=^#S35:_ )\"5=T)%4/WR5^=+8)=N_[CM8Q=Y-4>TU13DZC(J(GO(O^C$%8H#DV]T8E]F#WYT %U]I(.U%WKX) +'?$W'D"FA*(O[2'@4MM,/M0)(%4\.UKCE0QP828O3*52P?!D2L O4#"((KU[_DV^R.%Q#=+%%SEO7';!N6@P=7NB4# ?C,%Y Y>3@ H-4=S0]'>V0X 3*:HPZ9?WHCO$QDXSW]IS+"ZF(3; $E#89:QS9'6OCZL5I<_&YIJJ%))2]59@BG5>;@:X,I!+6%(H\-0J4:[)(-3K5+C4 OY)47VJQ.",J=%8)T_-R1+Z(SS_LH4"W.8T5-W\2O=]H%L]Z1Z"9?8Y2+WS4A32)1&JB4906NXF$F #O&13XCM##^)->%(QA<$+6^[SSR&5CP^K81:': [S,UNB]BPC"R^I9=1$RS4I,67 3C/CAOJLAHN)WF(Q9J.[)<%Z09S%&E26XC:@&G>O,\R^'H-G"J)4V/$$[9P35R;N #B'\;9S_Z6"8K#Y_8!A4%FV>9.PZ",)FBLZB/5;1*!TM& KK*%4QG?%V!]6^0"J$ <)"F6A9%1Z.T%):4:?EI%85U1&9FW&HS[V?+!D^B/R:1!=9ZJ'CD,,R-QXOA+-\2 ;/)#!K_6L1=$B,I8ZUI+VX%CM[$,4;)WK[^9*>FX<5)JS")GL;@_'X%'3=QDWTL1 7&26> -A\#>1 !Y&@6T6DK8G2P4@I5N FJC!X"SC_[*DT226?^;%?WQY/9FL+:SH $/H%FNXTS6L'M] DT<'+#W3U$A8]124#=[%QTW(&]E42[TZ=>@.=+34RFN;D=E$S1>ZK&+DW!,I0?&P-6',4PC_> U1L"B6O FWJQI59AM=%RGLJDFE("E7.PU:[VZ'+-7JD*LPMH8-%QZC ">F2PSQ)8S)[*JOXH Y[G\[RTE<_A$XX]0R^9N7%<*\ZO?6JA\'W-[08D/RA0=V2BVIN/V--F7K<<\:^L@ FJ2#NKH<,)C%U;(#KK,)#/F0MC?E-;R_MB(7:-&E&4QAP-D?#1PZ\,"Q!JB-K0@IGYAB*$RSYN(SV^3_M4=; 994_QW;3?6A*!S&8S;?1V2-JTS@5.B?-\%&SNJQ&^+\_;4#:?KQ\+]91Y.9ONT?]Y W9=08':OG^' +(!&$)YG,L&L4!DKVMO85?RUC%36E9I#C8_@OO<[Y ;A<6;,+,80 'Y_5EF/THD*H:B+$$L+1*Z_1,@Z[ =04033R#8N8A;^>ZQE]X63L_8?4X^ZT2^?I 1((_4* L!,B7DJ(XA(*:9,%C:BT98E.,VLVZ3AY*B]@G'[BNVIXDV''E&O9Y/\R- QBL\>@P)X_!.\)%_&*Y=3X$Q'C+W7I9:+%,CQ1ZN#(O@;I&2B+ER7:@'[6WAP5QA 0HH;=CAWE/S^$[.O1E(!%6*_A$^"+[0&%X\47.6Q^E]=:R1J^V!$^ZT6'D'" -0;YTO-[=KB8I4IM=05;.7EH#M#2C8O8W:CR$)D5Z6JX[[ :=-885U#&_0N)9KJ3 B#40]GL.Y]I-@WW/7]:.Q?C/A[[OEN(!TU&-6H/*N;WP.K )PQN^4.1D@HKMXC1/ 1ZML@%:9P+^(&>NX[W-3Q-P$:3@80O$Q>YA:X%FY4/KJ[R @_I5!W99FO+2\R*2X;@VF/IO:%L@HSV@0K0%P+\M)P\*2LV';&\2Z;,%0":":+5S \,[(SN.FK'>$%-AY$QCVNKV"I5=66[SHY "BMTPB]5Q^I(X88!?; E=J/+@(L'\7"ZWVL/B>[&UU0?]T23^=0VE>L 3S7X[SN(\_6PQ4U92U[V:W<:3J] ?)0.^)**L!_"FD93V\:J,6CT;YDBL$DR.,DJ?9ED6>6EJF-AFHIPJ'2X#Q I- LP "''[-TAO5.@T\;CK;!74'XVYED+=40W>&PS" 9(\]^T&]J&(*1A'_&LQ_9?+!-5A4C6PM=9_25H2V+.Y*=VR5^-H[TM^D_]'?",5: ;>P-N21 T-$C.CK]I&CSM60W%GJJRP@M%_*% ?<[OL/:[5)4#Q!J):X3L/AAR>-6G,D_@%>?&AV^%8$4 KE<%F-GP-^&66M[4,H&Y !CT3Q(1YH55!7^LF#(Z[/*VZ?29#M3AZT50(]PV27W(P)HO5&>DJ(+3A IEQ '$$Y4'([_JMUI.I=?M>$!'R$<06FG V*(VJ%3D3YD&?UO%3 UOS//\.]T!19\B)4\+$Q>,AR-PR[B!PTD?J? D!O(S-!+D4H/W>AYV5R9\NP(X%P F#NA)=4E=O&VM!"B.-_H;LSF, ,6^A^]VJ\B5%J!BCKN4VW=^QBXV;0#0Y^"R2ID ;*@'S6I^L_JCX,N[&??[_@FL95^VV[D%)D(&4;?K+YQ*:Z"2'B\7<;Q)1[S5\7V3 1*P1UK8 F7@L1-2"UA-'A7R 1/Y",(C%0UCPSJH66?Z!%>!_.\RXBEMSE&[NW(2 )U[-[%M$)1G?76TC^\'AOU:QT0^=="%TGB3)E"3&C 7K$(FHPQ;F_BL@O2:QM7I2;K>*] ZD2E$1=('B.LK=V1)YV42='2Z$ZQ)"V:QP6S H6<4=S)U@;?@3F7O_@Z1.DS&F/_]WAX8K.=@X-]^+#RH"_5/WH9;OFF!ZGWBU[> +7HVT?\V"8(;O44_!DK[])IPVQ&Z]B0N*[ F9G#L;Q-1<3Z+FXD8*S.M8FE)Y75B*:ZK4(*)FF1 7S %L3GZN64&@L9E]%6OUU M%FD%"X>.N1J-:XW45/A0&#IW*)I#-=K0 D2:FG_ W=G1M-;:A@3E"QSCI5&Y!_-$%.)&_F"(YO_ ;D9;^ #VA$VGNF9F0"+7,RO_FRF_ ^;3<;02U+9J,W'U1)DEOK.?^1B3;B?6OB; <"B Q%[:V/=0IPVCMH=NL+@O*[_6A=\97BC? )[V/WU21T'4RC#R69R@^(R1NVCMG=OW&H!\167I2<24F.+J=5I9T$O\!)]!PU47/ W7_"4<;.[J0XF_\7 +;#2 UE_CEW0[!!1X0F!S(IT)?:OW7D(Y 09^BNB=5NQ+_^ EK4-NQM7,IRY\E2=!3A)+(TF'R6=&24$5FZ\.=X/PFD]S=-.+9 ,VB\_Q2IB(3YC>CA8I(%Q_&LGH1/>.UKK@6[FP0I[XBL(J.^CVMD?8,Q?(D_5<5S ONMX,@9,LPY8V(H136&2\-Z);HGN?(A ?O/0[YU)>^_LE$ +'M!*8L3";:USB[_6 9;[T%&AT=)0.4N'%?\+X'IY/&U>@!"G^TB,=AEPN0V:*VG?]^O9&! S0GH1C87/ +JCJ4'V"<[ABDWR$M'Z-0'BF$ X0:P9*V.XTMU'K=^C#84]9+UR2!-E,]LZ(I[A9S?E/ W\1,2%*\W5@EWF@:I6J+_ ?.F[]9Y?#8(Z=2J>[!3*R"YI7D X>Z-AU5YID?L QT;93EL6D0)HL ,5,[!T.4]47O5HN-%@U>>(8^>^=;Z P-T^WO,C)*1>8(.QO]4UZ=*:'&IK7@H"=B ]CRDC0>G2U!>+B4)_BP_K?WM?YQGW\E8 B^K<'^I:Q?ZW@MC G-@QUL'_/L.,N7S:W>\GV-RA:YYW/B$T) ^B?1;2J&KF$5<9 AAPW,JK]WGRC&,T;>%?%ILW=++#>@>.R$F-$[)!G0 *FD?70PYN5;/TZL(R[%]%_ =6V5[[N"15_;:(TY&$IZ;/YG\8#4RSZ%\P6=M33KDF(N5P/S,B=AJ[)QRTJR)W=W 2"B./_:?JO$W>=([V08,DQIZX-+UZ'L"%=A[-&;FV@*EZ=!'M\NLHN +U+O#L*%+ HW>J()T1[U9,374_ZXG[HOP2EE4WO+RG?XWKP76C.O)O+ A1'&>"DHX8<"4G_/*!GL;()[#VZAP5Y#OQP)=._8+L&=M^^;1%_,<\PSUQRI1H*A ',5(%^)*E:S@R*@)%KDSV7-0_A/L?!=]H@5QFPG^K*@&GD=1.% N:0EH2N-'7E3P +[_#N3PTB7#Q$MXNZ;=WKTG0,]Y&[0;.[A]RY$IQ [2:%':'5/9QRDBR0_R<;'0G L6!/ZFO=3]"N.2PP/<<66(06/8DW!.D"8UWP"X*IE0,&USV161T/"NR=>/WKI-4' !:7A"J2]#(..O%??Q*MI^++CEI0-7!U3H88_*$1G7QAS8E HH;8$T2"9(973R=?L %?5B":5%IGDT9WE+P>=9:8]'2D7H_E4W18;3"]!5-O+GH#ZW=]7V4,HX8< U5 [G$BF:<\X#5?T\X-M9S: -;8S,4FO6>WZO\I;C?]9@I3 ><6T]&=-38XM'/HRT^23KKBCD+NGM[7TD7,?YE#A PF;\?^I=O*I>^4-L.K]WSA1L:_Y+AQOXL<]F_YJ@W4H5(5]1[G.JE6C:GV+.PLIQ 8V8QC!/5'/[]5 @K;S '+7="2P9_E*? *JGK1MH^%VDRH]P<^?G:&4%J/%TF8=2N5>'$UHGI:[%C11G.C*VKE>S ARX4>KV@6.);_((D"/81&TQ. 3%):I1>3^TN"?XU GZ5CE4*,7GR65X)>-.J4]K-ZQ8+ SSSN+<)BN8NVWK,O=XDLW4.0HDM8/0Q%D?[MK;SL4AH4]]R?3-']FMAD[VQP(TPK WI.6KCF>>V:;V/A/",[/::8C^CV%ZBE5O8ZLGAY0>11#<6M#(9^+C3':)F"$HG+U $JI_@??H%!2V-CKMK'8]$)6 ]6L/3&FD$T4$,G/3+OM4\TLRUJ$L5SM$3%UJC?VJOZ^,9#S\77B^9<\F+TM,4 A1)H81^@J&4XN$9V-V5M ^H"HTQM15:BXHXNG,BLBC'6:\)5A*E,%PH92?:UL>WN ?0;^$". IY4S:_4ZM^VX7UY)$9F$7$5PJ"+H_"2\]/*:C94&@1<4%V.NL)5V/,[S XZUR.W$6L= !V3ZH7%$$M 0PJT% L7GFSS,KULU -OWAGQ![%I9I#/6-9I%Z>W3HD-B<2KY$$LJ%@0!TMX]BMPE<_LH$GQ:H^V\02I$. JO_:L@4VU46()BS7D%F#%Z(3AIBSPC,N\R,7:)%R,ZJ_/TR NLV\W$2Y'=\N_+SM&[RN73OB@R?\1/;AF@$FJ+DNK+)&E&A4@ %+''+W;YM5DL.I C"?FL#/$]G\3=QM8I @^F[]#J1KA)O46E>CDQ,?NSJWD^H(GO0@OH8XT-F+BJ*AE [N*#=/97JCVB*Q5O$0LMRR1R.$$W;7_46R&]ON,S-J$-<>\>^D4"'>^'M,)3#6+H-1Z*PY'\MZ(.U9,A]RO6*)N P=DV7>%,:+.*(S51S%,XBFTL+62Y70:@RN;G' F&Y!:P27A5[;(Y_O.6530BB= .IV-TS+U>YH"S#D9M-)05INJD'RK6#/ 1^M&![A DI#F)QS#5\,4=IUH> N52O W]X/P?Y]]?B$0:HQB!_K5WK>Y#QX-A@:T+83C-21+ ^'3;KAAJ5204O8:R=W126M0./MK"#"_@1++Z0?@(UQOQ3.&"PJ!["3JHC%OO?L\X Z4T/*DM:27\16!\9 Z =]WF&U"SH0RFP[^3]3]HN9D'JW4J5 H1 $;OI^=#\1X/ES'HGL0TK9Y.ZE%?)VUP2+>5X6]%7TTUNT2/@G#E_=WCE& A*) (W1 ]N5]@MPH?$Y\E?,W:%M;*K;=$MA9<_$CX!&L<;EV$PPZ(=OS$E+/^OV&J7*; ==UF1N0]*.X25)C>[,.O]D=!59/38H3!08YZ&R?N"L^G."N(W$3EF^X2B\JT-40; =I .%^HS%O0O?IS/^:F%OQNMS:R]W\@B]"R^R*]D74C0=)AERRQ^"0_ASO@=F2M? GDS=HW0)F24+]J++$YC-#Z^-HU^:>-DW1 A20KI;OE@.A"W@F7X=:ZY+/&=N-[]J EMSG\,M[IV:Q0F.Z!M3^$$6?T>&):.7+@CY_V;$Z3XGY62A$_7J^XPV;$B1DLC^O I.J#;N&6=:QN*D]_8*Q4HN-/O=B'>*F?F.^,Q+0?:,2OI6=Q5]&BL_;IE:9P.SX= O9W@Q^4'X*J]BFP!1+R,^*3HBM&L 4,3SI)/1D#]\T-+7OH&F;P9,?UNT+-// %%:)-F=W\5CZ@9_72+;G:13"E&MSGIEYM"JOPJ+IA@/E#BZ\>3>M ,GKBX7M>V12 O"T;EDC/+_(:QB#RX(?_LIJJ1-/-\DT3/F 2B/".R/^G0F6)5DM(>YFT_RIMUPSU <29YF+Q'1>C* F]:!Z]1)[1(DUZKK^9G>'+JF#^O!IRG'?^_@E/5B1Z7,FCBSRLM (94YW]4@.$;>J.D3KK>JJ65>Z"%8SMC1H!F(#<^MI&JT[A'V P3#NMC&$VW=$5D^EC\WC/*!>UIU+!F.ND /#)'Y]C:@TQC6Y9=NF19:*:\%$!D1 ZLMOQ$!9>8X*$!O1(("IQ=1:O;'!:PS][^ HC*@^L/$/^\"G!\EC).*:KP$BHD6L/ @K9;X%0U8O_P6_3IX1P:NO/NK"_HW%4ZSG^(@V +HQY+$ZP%@W<%G1LW@YF;YRVX =[?=!G7."+*[2XIL#_6-W#;4E[WOA<]6C XG+:L(9@D9!WQ=7;J=N08!L=@,'FAR %U1^II[]9 ^CF!@G0;,OQ^H(93KMTG'B40:(,X86>Y%[:-H$%0LQ"H+=2E:S^UG9 <]4%#GO]P>!0I?>4;>GYQSW=EP/VHM-%=#69PCD3"Q/2GT_F!'<--IB?.MRGUL?? OO2X=4ZQD89R&2"L^H6[3"8N-\(%@IVNB)S?<_7^^AW267[NU_6FXNOQ2"L1/]A( E-JPK$R$?4.PRN7/X/D'HAQH"O8WW([[J@B&T$C+YBN=FJASDUCRPAV8\%)&F:/.GN;[>E^4XAZ:,;8U3&\4&3EA5 KN;/+[%"6%8(<2M'--'65(U^5F^ NHN4W[OS2.]9X/YLG).5"A>[%I(#P0+&8BZ /;@.61DUXWHL?^JC#NV">6XTZ';#6^@U[C*&2!)\.U5_O*X!%9RMN%$1>C9@0#0F 10K#+US1%VSG^&D\>O:44"K@9F&CKO4(>R\COCH"5.[N/2$,W9-?_/.*7^BP.=L8 S+ZY(IJ%AJ313E>W,Z?UB1'Q4'Z&U^RTC59$-#RU9>9-=.W2J04_]'R3J( 5+ ;9 79;S^"74A I*L>"K:>=:[/+/W0 95NN<$I*YK:X?C?A=$>$$U3#&5T(-"#/64<[G G,[HP$;*:QEEZ*&"P:7HW#P95_L:GCF[,C]=,J3X8!D.%4%ES\4PQ'8];#61C/.[ C12=0:J8$]IT&WPS$$QCI1GD3'-UC)0.8\%.BMQP'&_2Z1D!K:YB6 41LDG(+@E QL)^[G\,T[KY77BDA)7!47^+$TM3QQ)EHD]F+[!KTS&(3W%%?4@X58:X]03N9QUN XG2UC(7R@$'+JEZI )&S9V[V!=\$%25AF_BN)5T/DC%4^>^U[ (.53&]TH%#I 9@ :91*$EW,P4(7+UR#M5JQ1K,'8$"S9/>J UU\4+8/2'LBN($?\S@4BU_F/&"R7BC [SC?X>[6LD'RWSL$- B*D$NS2T;&*VN <:CU"B-M)*@0J-J@T[P%*Z8ALI9)9C,/:@6S%Z OX"6"'=3">V/] G8!C6:J[_>>^Y_Z ; H /JMY 5:#T["INRYIUQ^(4"Z2@6+\)LDH>L_+QVUE+D@99DN ":H2)AQ'O]Z1J4['31093X0#RDVPDD#7Q\W# /U[EM8<%I(.7Q KB!E>\U':*K>SD^;PEQ3N7+$.52SH68J. 'LW-F4UCH@#!G2OM8D(B%K4&NJ['@7ZFAM'_+:.U;:'"#% MW/4_*3^C>^U@5;*\ 6UC?4(8MD^'Y&NW_N.753Y/=':M;@J2D5P*F1X77>S)BM\G6,:BF^2U;S*]*WFK P=V7FX!TS%B81;(WO(U9?B9KCVW>'G2PER3W> I@_38<%KD%+I-FF];[(GLJ??E( I=LSY[5TM58;S^Z^L49U.XTN*[<^[]:K6[\='=<7^K%R5%W*D1I'P?R](R+>"NV7YAOB#5UNG *-GPX/%:RVW;8UCZ==,8DWH.GB/_@0^60VR5/^O\T>V>(2^-T($_IKJS=^N'.KU9 U8('E+W1(O5A'*YLM^[XUIVIL^8:KV>A"2E4-$@99=;$\J$5Q$,QC'T<0:*?&EPQ FD4062;J*3C5G.+?+R+%9.>\R]6CY(:Q9M5N 2"=4I50E R8Y#)1WOUIFY)\8-OT7E.N"@W2&A60UCW! =CJQ7CUW-S;+FL:1Q%X7164D6'VL] 6-G;*#[D =BB60"WS,E++^M=% OACA,T& ?:LZ?P*52%WXV=$!'/PK8.DHK6%G# [K#7J-+D# UA)F,O"T9AR(5**!'H[1SL=6G2C PF)NCP$#$5AAU4#0S]X^1XB&?C8J+EYOHQV(G9F*@92+[B]-K5"=@9C0E@#52"&M ?8=W4=CADOG^G+2:D"Q9_8<,*R]FFT&C9[!;"!<>**+_PHEAB7T.)]P XXN"\W6&VH"#2]7HK0>[#RGQVLKX]L_/,1]+[083ED*4^N6T=\C$L+XBUW?Q3F(E FJ&V5X3?869D8I\G>WAUH-3T32&E"*1,VTK52ZHKW-7?/70FZ']'VT,NJB2# "^L(QA5+FC'-*;Z(2Y4:D0FO*<^Q42O'MPZ1J/C^S+[-Q\CQ,! RDT&_0$8$8E>QF/\T, JS&I0OC<4R"AG$W]7DZE"Y)PK NK6L*K[_H&4H&,N/;]T ](12PJZZ25TK3N__C/QZI?X)C(>W3*!TB'0N-BLEV:"\M+:BQ^'W/V:EMPM#0DS<$L>SN/FV U.,*;L>+2YS34]7=X >G]OYZX4G7SY0)C;QIW;EU3==IXL;J6>S>-)\+R [D1MS:_XRCB113>_IC]-/\ U =.O3V'M-K/,6Q2^7T@90 U!+H?DOQR6)'8& (DEU?+XRW9YRJL59>0$$-7.YJG3 4BBY_C1A^/>>\F(N!)MOD/V8E_!)Z2@Z>8)O&_!Q%GY]C2.NX$F80?56O,XBB.Y5/C+J3; 6_V:?FXW:XC6:+E2.W6EQ+HO$,,,;*S0XT/"/?)A[AO=5:R=W55+PQ"=KVI7Z\'] #Q92CQE$@^S@3W5'$D$)!%_]%Y]\O1(Q^8RX?-'![38;I_8A:7%9G%P6(X+<:Z$A-9%]NIA@\N&NAG/X&M'(WH[136S:QW-RZ>>SYSM L$FZ3E^:?%\P@&4"UC,>Q,%H_C5!EC-5 ^QTIIED%&U.3T(HV3TD]%Z=OKA98>M< R^.5P=R9AFY*0WF]Q@5_Q??Z8_)&W BAD6G'ARPT! G'_TJB_IW^>NU2)YCGNJ9? >.LQ6SUY _Q%DMP;ID1+B&\D->AV0I_6F,6)RY<6M6$!TP[SBUNMWKAA>FR#_S/[XNN NAFE < Y=_)FU-E067'XD@X!.V8%^^\!1BQ)J*Q?)PQ,U.&9V4^AH,:@=M=_WOCX "<6_5<8R+20F7;P7\N%'?1)[,2%(!QK>HT5WEAIMZ!%\ T!E_I+]9D 1D$Y&%^0E 8F9!>]4\VK1&#%0O/JVQSF5KE:V27>7N(WV%S[C6&J3ZD8NBW =0QPVC)S.I./Q/O"7']BS=5@1EMIAY$SC&W7\;N>O^[67G_JT[]]+WL00 8RME_5 M<19R&6_J^6?"SM6QWWS(=#M!:63R&C?J,#==+; Z^XFUQRT+.4$?H#+NV0.92TU \[/$AC%T'QQB8.\25GBX@+/NZ"&3H2[ GW=-Q:JKH^=[9],L5'RC# +@0G\L\-ZX6&R&V%F5Y1%?M_$#=3;:W)N%^=KAH_L .V2H Y*/J:!V)67"8J9\0J.D!VZ*\=& 8](EE_KG&&>9GV'T1B"%WDD3B#1]YZC[ 1B(PQ>3K.;[HL 9WO/2/[T?,8;BYXU]EXA+^I_=)(FBRY"PCEX>.54E-3")6R+.9 >.*M 8!%H5U@/8N1RQ0.4K90G 3?*]FZDDK<6L;, RLAE 0$X&HJBKLJ LB7N3NQW-["]M*C39!2('HUYO2R!R\ZRN_0ZK1TM 2(*,Y@&SCDCX#"M"UK7%3:;;*G#?R:Y4SW&*W\,3C,"#A\$Z=KE?T$S;7N')]\P? "^CX@%Q0]&/B&3_9A;9Q2F618'GA=:*Q]*K-O8%]+-<"(+0#BG7=P'@5U.5A+Q[Z5!LLN-9P/!@1""35.?4JE%L+] !!.LPHWB$=G?"3 UQ8;%OHK+]YI*SR52F54"F!L13&,I5>X;/.KHPN6!H?!_EO/>L!M!%[/N[D+_BKQ DE,O$9>VO'HI<:-)D)#7$\YR[C.[N9%L A ;_#"#9GQ;(S'8A%?'0$UV*/*@67'] L(XJ+CHQ T432$6N;],V$TQA)0(OL5)*P4D[5F$=DJJ)M ;.98XK?"ZWA6;T'S_7 @\MAM9NJO-!QB58<[8IW?#>F"LX"YT$U^+J'66>,R\F5C\:^/TZRJY7"X_PJK(>" O=S6O !VZ9T.6ON>,F#,K.D;(T\NB?S3 VZ9O(U &L%T6AZ$W5HDG6T''W@FJ,LNP+:8*JS"/& ,>Z-/41?0I<8SWWD-7(E5R @&%8$ =8TX5"&9@@,$)*,@D=&D1R9 7JS" #P73WGA^-'_:!]TR5-JAM^]K-Z7\, @(C5\#H*.K1"2C(::VFM25D,",IB@LZ/<6RP:L_FRY;TZ.'9?2 88?-!J&A+DY8( JS"^EF"189]G45V4(3;"XAJ!.Y8]D#%CV?*E'&*W)%PC2L'WRQJ(O!RB8!)JVXOM]MEP)-&7] E@=5U*R@4/ ZD%%R3L8'&:)&H9#/AG:1R_\9U" E "#* *E6XL7F-4#?)X%$"%-S@Q5J8+;Y@C(.?5,@+V]G/U]Z9UNQ)[?7C.7=5M8KO'LJM21DNV 1YD-)I_'N+SZTIB VA.ZYW5,/! Z%A,?MGRPLP?K .N[F\ZH"+TN#7T6N,XG>X-@@E^B-GO.(*WU!Z@? [$@.&0&Z0F2/4,[DJ:Y 567]^GC"@^ &=D0"\U/HN_ ,T>;M?/-E$KS1FC9JV)PE-SBU/_)H&X\BE5SH 4C9K62A6/G1][$-^<8+>KV*R\3JWRZ!C93$0OM?;06_7WUA4.)3]-5]D4]IG/#(+ &;**M^Q0IU^*L)*2"48T4&FZS@]C6KF]#'G)Y6<>>^)MP_'&:,]<'+^PVC// _E:FGH3PTU )I%.6-;TZO5B'_\< _*6NE!E FYE[]0(PY\=(^*V?2*&H#SWUOIXY [= %Q:A*'!]9\1M,Y4J_M7KC+=9+W*!RA0G5(M0G<5J=6U>!PW=Q:C%) :]+ 1 7,[@[X/W=Q$+29T,NDJ;B7E M:S(E&YCH95 T 6=+N,M+>"D^I0-=*\&\/ES4V :\I2K6*!S."U)8[V#Y7^K6N5N)A)95CM[]*_7X(OYK*7^S5XJNF;0O<*^V^'A>7_ ]3#KP\]W. ";'/-'CE?Q]!V'7EOYQ"">-]4A3L./<'@L@1# C&==QL[F9'9A_PR7 (*#\'T+\+;+#0%]8:MQ3*M)5Y(ALN6CJ!DE.W[0JX8+,?,)8UB>LL6_^!]>T/VT4 @C;S6388.(-;9R]2*!8*L@ G@"NI__4:;89TV65*F!=WI.L_G<^IJ(Z\RP9[:N5Y Y^!^ 'WY'Z6Q$3#GFI ZBI]*!M;F^QW48*#H3CO$\7"[LTR<5H=/33[:*')$J%2N #+8:#@ZMY\JA>[067J810X(MB&'$H3J-A=L%4A!\H-JO>?K $[S,4C'048>%ZQ/' U\I.B%C."FT\KVN3!O:DPH+^LQD.)[,<_MD0E$ '4&)WX.LYQ]JO&XL=D&O7QJ^(TR__7?M:Z+NY,>]K?U]9.[.6D=-#5\N@ZF :5;(W0->&1@]*E\KL3FG.RS5$H189]9TH[ <-4[RWW8I<"GI[];*>?3P*;@+A[1N 0>K<%GJ]RJW#IV+GKO',Z/3K.M+1ZYP65]9@8D(D5K^;7T[":,>;%VT97F7-VD"^ =Y;!@+O NWV=!NI3[6%UM(8@D%R3QPXS5'&KYT1<=;,"Y8PX87M(N 6D )?W5U1;UTBW%E"M[F&9?J0V=Z#Z)V,L.Z^_T#\YYD>?5E.NSKE6*DA7MZL^/[ R8HEU(+Y*I2)=S7QD64=R9G^!SBLVZK.#$E%;K%VQ@,!I(7)"]39%J*\L "%1JO]E^5)$@9LS\@=]@6,I<2(&FG;+?>0.RGR?>!;4R2^M&DQ ZU(Y-S;]L1UD8-!9C!N\0C6#!0U._R*AG::A8A$\6B2-OWR-^(Q=XITG7 2H;AXOK9?WBBE^>-X"%240V)MB%9!TS(R3N75PZ*/)3$24 :@LPAKLN8H+ DYI+\L(Z.F]%3@*Y0/IAAD@!1L"A0.#=09LC3ICO4=XD29Z[\E#UD*^YSXF#(>Y% 6PWV3 J],/0?8!FY/RCO_*_*]?TPV0@/Z&RI&BL/%\4&*V19/9E:*A/5['XPM:C_ DQ25Z.RR#NQK$+\.-K4R87A2&1V(O*\7D-""OHB88U K@)*N%*-,1H:K8;&0038 DR ([1.&U=,+.9=\9$&-P#6'LF@A+Q"3"$#0JJ'(T[Y*: [Z<.U&0(6 Q H3FO,W?Y&M,HU]1P.I(4CNH$OA11&?/_B6&4'^(#.L](L!*A LSHGS<7,A*I*D +/%Z %R')^E9JE/@?H+[Y^FNS4Y#! *M7JMB)<5)JAIPLS0K';BO2)'1' X$G_P, !^W(<32Y1T!B%^9N0Y,$''G9,G\%&Y/9O3U0&]\JN\SQ5F:ZCV>^:RH;IWA%+A:79:<[/-_2Z QS?#L6Y=>4T-%5N91.*D1X*9I\T$J*&M /I!_,.X#W+%8]!2:Y6@E--("L+%@QQT @Q&'_1;4^8WU60BDHBD=#/?!O]73EC+R&11:2;PHZ9VR*J*<7L1]EMP%J.4:_%EB VRL9K.$/)H%1GWQ]EW"[9R,(SX;*QKKUI5,\G_38I?O8,B!MA*3.C.#>$7)OIA? W=I)I"+D9^T[;<$F70/N;6,% ?;W8O_&&;8^B8ZI.'"U_]Z#/8)A:<-G01@(PPT"R/6-S0S )XX&C1[FB7HW/PI-6Z[62F7GF!L*7Q.4T(Y@+]Y(+K5CI%B (&0[,XY[H$,&Z??E _(8C;_HU9?$$?TH%DVHR7L]L +=RY5OXX84JK%(*%M"A_P6HM5X:E[H5Q2P0\7]0NS) EQ^IT/MZD+,>AZ"' 2[HCG5W%RTMV&(2S*R^7B>%FYR;WDKWL !JL?W6R?S*>=9: $X="RU]Q2R3ON/$+ :&AP4(&D 4N\+=$BX^05A.E1?/1G,9EU']3ZFYA#O:.G91QU8)V<0/T7F(T9CQNC.YY/\2N?2QJ8I :@I4P>+H!L?>CD^A@.AO9_; 4'5MI>^E@$P&R8Q =&K_C%N2,B'9_Z)P2Q96M#-UUI?,L5\EH7".&]= ,EKH,J[1$H)LO-)T7'F&$"9 P>> WBX"Z4\$(:$7CI,/!*+M"5/H6UDM YVRJ )G;I7:B$<\98 !Z^/^EU9G'$#X:OO(N>QI+M8@8L'*%?% -<28.O+@:3&OSC2[_5T"3 >(,GZ420HU46DM':AALC<% 54^ R/Y0E'D-#4#TNT';,<'!93\K48!]499*UK) $ A+#LUU#"JUNL!+U(K3M+,Q7$Z4NY*-6D1*$SH[TLI)?GDO6<(6W?<_)DCL1V2.HJ _]=7QW[RXUG'R9I$WWL^A?^N?*1[[._MK+X#IAK)U[[A(=5@"E,A/FVY-M@?L$5\ GCJW*(:Q^2Z^&'C\^N21DN=;)D+E4\\VW7-C2]G/Z_'ZZ, A@J$I-T0*:*QC$HD: K8>9P4+P;9>LV!EYE&#G(*^ST$"XV[2N)O L_JZ 1'0E8/V%3!I4,C"*DC<]C'# Z=E/;&UDXYAA:[/4J]'W"3[ANRU=_ECH8B7F/%OTS/YZ "E/A_F,XWN=HA#-'WYM>P-A1?_B1N&O%AFT-S^9FK-]?7M* UX!<2U 3C*R:*1*, DP1LC,QU1#1ES, ) Q( WA =S-7XAM==)" ?EUK"&['\!7A#"N'58]1HM(<[Q$O5 7.,JEE_+A:K[$@R!=L'!ZY<".FAZ6B..=N8:+[-4^)?I3;/>13'Q4Z>G:92<*CJROP*>&Q@;HV@U=**F& G-W7P.XYI@\\]$'('U3>YDZV=/!F6L&ESV!K !WH92[B:HS@-L?A7(ER?C@HW14(+'5HRO>,[AX7G_A[A6]PM9FY=C.T1S_UEZ?2? X!0.XU_NE@C5 3V.)B1TB15NKR7)',@XPQ2(7LVWB^24+?H.DS?:;%W19Z'PBB8[ML!X9TO0S_HS!?#V=!(/R@T_EU6,[D^'+9K_)-_ (%8M"9A:HY-CZB3H+_G2O[N\2%>Q$.M8?R:+E6:P"K?PU&@=T!DY8A?LBGV)'(E+ O5ZOSOR:%8"#D=/:O\-V>UM)!TY,9'U>CB]HMUU/2#NA81]:F>'R^1;=^;S09#%P&7+Z^6Q@ 9J+G6K1!?Q"H@6)]')K[IR9"M6=DXEW=KJ-W0BODB,KL&'B."\A$?6-D#1( =U0=H\TPY:LKWTY,C'Z,1J[?9IR4;_M)X*"ZE>MN#25K*K4W_-72LXH;K'\"L!].V+!@];[ L]:]PKKG7'B'9?\;_8*QD Q_S[+Y0A>KXU.W,IAM$<+1DP,QM(+)G 9*@7E,9J] /?EY4<1WVM].KK<:]W9QD.#NT8-0&(C[*Z40QLD3/I# #9#;U6U%21R[NF!?-G#L W>BB<-/XB<;SVU]\D'K]G-.4(XBM9 ;$[(V4&W"B0.^>XOWIX& %=7(M!,Q^S#&M IKVY@]/_ERO^6]Q8.[D(%]GQII5K>59I7G=> "5L7PY]4)0;S"TQF9-!KKWO>5M?'=70+&J^WIC*&V.FJ2P<$63WRQ5,:BY< =82E:4<U5M)T:JEA!]!13=&B4OM:5BPUS0: LN$4T6_,SU/@CJ=$ !WU0$+$94F'*I+?'>*MX??_#C5M4Z $K$5:QI3J!)S[6/S< @-TR*O4/YCH$":"/&P1G8"KL4ES6N2TY@L06# %RK$SHIPT5(]<+]9 V.=]CJ(OL>"?5"F!\*&]B=U1=]]8DVEU:>:"?-\5RA!+_-8 \)U&"[2S*]?(GI17&U%DWBP;\=SSR/.706_;AQP>!^W@NVL@. !M'2.5*]T IEXYPV+GQ\G--\%8OA%.I@VD)M_@&DMK;N&] 9SA6SE-2*T6T# \8KMT1Y,JKQ3ZM23(90/R&Z/47%8MTXS$3OI\LU024G(",+,BA:Q^-I;HK\(R^I\ B\IDTS7Z]B>+$YM%I #TVBC3S/>]B>LQN0[,;&M).PC3JLZR)/_%'I5P7QN1*?Y@+QH9H.RMWD;8,LYZK7'/<3KD#@6U $@9:!)6".R<$$J-*]CRE(#]"U^9*J'8L !#Q9>@N^7P;T[ENM!&_U3/B1*S"R7@ 3:=UE)9"AY_2CED9Q_!K,Y"W1-+#6KW525-D P7F]RD)9C3F7JA>-^))BS2;"JJQ 73ULL3-+M-5PW>FO, DK?\\G0]CYV+],VM(19WS]<5*_/9**Z31F[R1P=%TNGH,7 /=69@0@HFR=.YT(2ZBC*B3;K4N#/,,S;8*$S>M#^M?VVGX?>"Z@C>-(2Z
ROFY[IGIBO ;1V!^,WP'!P N5*MV-4[]BA0R!)$O+RI@ML!-5?312HLG&WX0UM C$R0[99X9 R"',#/EM0*$LJ5(HRJ.&6(3#>IW':AJQ3:S]/MGWET(B$MC(E]2?!H"U#]Z#8FT= CFBI ;AA?SI4]W"76VC\&2UEI0?8PCP .&1?!'R&E#;*^0$67TL&!,7/'4@"CX%3 'JJJD5H?S#_CBDV,P90/X\+.@W=ZZ=R@")J7A&HXZ3*[K4KH .R)[5@LE\7JV,#WZ.?8+ :W>"E,2>0H5T5Y^&%*0DH;BHB0F G?Z?_O #-63O-%/ Z]XY=CUW"1N4L%!HN\P>M2GFJ=Q5,7O!+&BX[$+).+8! #Q]!D:$!80MM$:;,]YP :01E2]\530)E5L_P"^JX+$)A91CJE]*YKC.!C4G: ^U%P1[T>.@_R(S[W]&(A9T8E[W[^*[2%*=XQ]I()2W_NP+Y5(+CM!2QA;B]:Y'LZP7E\XBE7=S6,$0PQNMPP 4C55VDBT=89,\^S6:'&T%#0+V\W^T/ZQEVOQ2%E86:=+O_]EJ[Z:A.KW3/(/3DHM *N'R4-ID>_4"\)@@EUE:.Q:O2V7BX"MN_IKN\#'MW0#3L"'8#.@CW?UMPU5NC,/W VVX8) O'*VI*]( N&=QW]\1:H4KK6L]U4W-)JMICGA23!&=$&S@' TNI2E>?'K* RFEON/UA*=Y476C **\I]_/D1[&5'=%F#.KT*#8LL*\@MJJ9WZ0I=LGU/;B14/SU (J;?6^: 0!TIQJW0,%ZQ*T%@%-(1M+=465RX:2JSE$_SBM\T2*1V& 11502UNB-Q O&P&VRF4[KY8=_P"? S<&:P(RO^/5BYD3M[,S;XP6QD6T $EQ[\GK)\,+VL!MO-9 ,9\F_R?-?3B&J^J$F,KAQ)/^M#I1 D.(JI?/.EU*7DN"ZA+'YP/U9^=)T+74NWYP/O= N><+PJ[OAV+Z#>:#J=K"EN,>^K!S1MFK(TU=ZO.% ["0."0!U'XR--V15K]RP[?P >)LU"*1#1-\PP#A'E0@VD)+$#HMQ^13*O+5J (_C;>VIVT'&6<3SP;NV0*.+]#:! !\2T,U]=%%U@E0%:<>3BNM&0_MC?#/%HA .[6YE7/K0C_HG'53]^W-NL;ZF;I153 3WS':IC3:=3WLORD[IW$-]'6**!L_M^$,R+DVW(![J.0\WE\!J_J@/M:U R6RLC0+M]#\@;Z"3!838YF6UMVG$X [WV]?Z 9CG-?K5<1ME!0/TR*P892_3V>3D9;F %3]C:UCL']SQ3SEVIK#=^]#0_& .1.\;R,XJ.8PQ)*96[.CR*7IQ!>33>E>V6LDG!?3^-W>M&/5LLNX-D34/?PAP0?$ @=1O^,:Z;0T4X,W$"J?D#0+ABAS6YK3T:Z<]@@%*/VI_O#U5"[Z?%+FT.1T?'(NMO=C$RK/_]ZX^_HL5-.IZ%X);HG+'R*?(+< !PRCDW#9*2=Y+3;>]L*>@F0 OMPQBC)3AO!E'H2V63Q*$ :[K_Q.3.>,3SA0&E\< DXRXBNWX]+^-6\.]#N$P/9'+J#Z3>R@066/:K8"KFYZA$^J7@[:ED)ZD9,G/O'Q[ W)AB6-SI]XUV6B NG(QIU'\(F3,9>8EW3^+"%.(PD=?JQQ5.7'D#6 :8G_)C\:6" NB<5X$(7Y+A*/7QJ82@Q=;N@=E@J\(3T10-U;_?+.7_&F-61,]'6DY&^M*N]Y*>< ?%1!:X9O_X-KH30L!+S.TT?B?4^(-P[C[+%XI?_:B#F$!@T8%Q.AR;*'13>4!]"P XX0>*;YV,EF'\ J943UA8%R- 4A >D?2MM4I>%4MF@#M#^P-2Q@%;)"DOL3^UEJ_"GAO?1%()3ZZA9S$>F),Q>QXP0OQ 6&UC"C/T EZW_/!76Y?X"E_*&Y;8M->4F8$..WX!BN#XWEWY05-JM'=/=1W_9RXH3V$-$@ &FDEA8':ZO0 P >&4VI3-9I.:YA;^Q?C C[ZRR&BX2NY6/G6_VG%+V*FHF4!(IIV Z!NX(K5:^QFP_R]>YX$[*MM-V.G26ED5?7-O8D,'I9AE=Q"<9#7?[0!6,&_>@<7;1C=@$\/,>S0XZV''.+TO^^@ O >'WG#/^D=:_=7U^75@[CLI9HM)?+HBE5+HC^":(T._V57JCU]/WWVY\STPCC8#YI 7;/A< '!D _Z+LG\PM@CQQ^]I/0RMMW98I^B?7XM?Y7DF3AAG[?Q3K?]_@=C!1PI :4CCMIWWR FTJ+^8BQC%*TLK0&AJ4+RLY/D0^Y >EH>(U!X84.WY0;TH"WJUQYG' &#AV0"'.B=^%SX=;G:&[4@1#$DR:/UO"^._Y!-9ES R78-R%"NOP7U7(.Y8H5'0/ JNIF,^H)[ [KT*RCX#;V,IVIKCI -#4Z+]VI02^:M 8#7Q:7JW1:^(*#I9>=2Z<@2TX^F'ZWB3=S(JLK9T6=A9:JNB/+Q5[65$I: K#P4G'HI_A]]<,.^7&78'56+6+JR6*A]"5SHNAP"3SRI2#8W=$H'=]G\.UL, G)+\OM%^M+0L_#ANP,EFMFA6*]Z5&K[5V^2 ESZ7NN;B]E7[Z@P.]B ,X:G7)"3 Z&)CQ X4FUOAB&=2245I;2UDM#I1[VFXFMT\Q13O\L![0T#]5]DN.03A59K.%><[ 'I,8,9N8$-V]X6OT_2?0/A1I10J%:-I%[66"IS6+;Z""V"F8A-M@S@FF!3O."&S< DL5R7)6BB>2;\LQ\?@]Y))Z/!I)%8PI12.A%&$$[$Y_+J^KG1\V_[\ .IUSAW*IME_5"!FEL.2('\D;=>KM9ND<:I1]]+83L,1^[J./BNL:6N M,X VA*0P )^()C5OLK!^A(E&8+/8_TK+S5H!:M^.R^WOBMHI"(92W@J]5H)4.WYL\# B_-.0C $,Y&N_]!^,>,47@!K3>K27<,(*Y5[K%34P2$ + 9?:"K1)<]56H90$?8Y"H#= CVHE!\=$DDH-DY D?87N9>J4-T*C@IQ?%9(*_1_0ZU):([DL( "P,MT:-*3EBGS& "V6"SZK1N[DH_,APF$;XV+HSMHKJ3"29)[#PWU6[0<="S]F*+^-X)T66/MMM2'Z+ 1JH&U5FWQXVS27%!F[0L42880BRGS7$<4L,]Z8BF' ./.HN9OF!%A3Q.]D&Y'OT^ %(80T*:4-S+]-:$98L[>V& :():[-N^7[592A2(#YO!;.@>3T]X@P*>%RN#KH3T* ZNAJW5Q31\54Y"S1ZN;CRH\TW<16T"PP=X$HW!T6F]D _S\.+0X^<\;([RG?JGR[6X3?)[ZH6HI8/GR)_P]0D;+$7W'ST&^"I--A@.3'E5:4 :'P\&O=65IVM'G)C99E1/S2Y1#'.Z&C$^X'.]-W 3R+V.LP;Y'X4!Z@;YV;6R"N> @5I:T2++W3>YH^%M\]XXES7TG[S#I^2$ULTR=J#WOTEE;#3C'5&B]9:1\/L^00A, AV0Z ,*W02' ),0R9MQW2718?]=)1BYBWT8,#GAUB:1&OT5MU\;1F;Y-\3FY3#DJ S#?G<\;H+#FW\V%!__+7Z:(ZA)!><[FR&M7):C1EP^-F;ORQUXKJI+=0,=ZZV"=. ZF&P,B\7XO,B?H/:'"(Z/4$^!5B/P6,OLEDVT-,/TPAO -VW#V#DVU+ ;V,MOM ELV A.KH\;(\,VH,/2!']?-C/:G,VH_!1]>3RR!JSK9X6;6FQC=^XWH3O 0:.52%'S]SK'B^_"OMG[[13,2SMX=Y*'H9JG##3J63*&%H'<:?M\(L.E@6F?NOWN 7TL*#)W#Z8*(0L1U=-22RSOQ*EX9T$'$6NR##9VYUJ''G&&#:VP !DDV@:-\1[8T ROZX:*?J%[0,+5JB=ZEN_GC@N5B\,D$W#:Y%^8&F'B.-7\P$"2L^4^XA50E^G^;_ H,@I1.AL=$9D9;)'\V75X^B73QXT.-@U*0B\IJT\O_[[%'[8HK?/PZ6W@T7R;-G: !&PP9"V.2<+,2W0QCI%?O4^_K9 _VTWY)RF%>X:EN<7*WUY%0^3(R(HQ WL=?#)E &9WL$24FEJ>I K4.UVT87:]+0=5?&:E8C3:NFHX3+V*=]'3$8M^7Y[&,4?J3_#U] !EH R88'6K!46%2 .36XP'P.;7-WX:CU5RE,.@:"M<$]#2K*)QBI6L,P+)4FD'AN N1+C>525.IIJ](QHVY8A)JQ7P#)P)])(3HQA3IC6COPZ'17CZP[XQS%!SOLH]TOLJ&;[V]^8 C.\)A1@,MPE4PF3B )11HI+I)Y0NYI0.-7CNAOA,(4X!=@QQ=KRJSQG.VC('3D]I @7:1:_XECA- *#^RC4*SMYK( G1*T5B#&#>-#0,-$%<8>F2 C2?-B0)7LO7IOBO D@G$0/1>PXF_"D?' >'W+N]%/$M[T[@6B'M%XB]G^)Z\U345@@ON#U GB09\)CC- I14U(D;<$1][4K!(8J)!Y5=RG0L(D*6O/OJB2\F0EH$ KC4*<&[S89SM,M32XD^EN%.W-A_\6YC<%U9%R% VT:E? 9 ;N3$W5FWZ[!56/I=& J7MN ZQG*XV!VA$J7U38/0,;S?(TR/4/,_ ]@=YNIF!P8[Y/Q<1K3P;3;)L#K/(Q SJN^"%1I7CB.M_'I5RD$\[7-KD')6CMY1M#&FEF/@23#J/L3.@IOF&D,HHE-KL;2 8\V>>%<%A\RG!C2^+52XCY9FMP A*2/#4^SUH5%\4!_>/C*]FY;Y%?5BPTR3B77Q O,/W[)WQ.@H5^W>P?3@] 4^,-K> <5O$/">4D_EW#P;PLD0T] #3 *5F1F\Y#LC= +@6_R+FH.QL'[B(X46ASG($VK5M;M.J.07LEBB("^8MF ON^4VRA9U*HC-<"22Z^ -L1N^T1;M_B/@MC^,WJ?F;3V^39.E-XY<[@D FPY.D+"PP%W920"N^7"K3,)'N!Z +'M?"GRV7CMK*D>Q'?]5 E#2CPLQ!6X=7R5:8@5Q3Y6XP=3F,PK-[%(Z_1& Q9L( "0NH#:QXQ(.US61QL1UVW@DF5U2M]?)8F4:CFQ??>T@'N!&'[21F5J^>HX W%%)% 3PP6WSU7O@:T0E40<"J40%M_1=6I"DJ?X%Z0.>S?^B$&BG!)]47XN$IJ[@-NIK]* 6+FS[FDI1),3[U>#0A8S_2M.Y^U@XZ&W6J':=O.B7SQXG6$YRW3TNKZK@#&GNK@\ C9 TNV,['O3A,B,VML0H@5AR>=N?IC YLS+T7^SC@)%-L,/ABSMQN*&?LSIYWWY< J\%(BU=HT[:-DS7! (QX7!?M)?&VG_*6H)\$7XN1J(Q6T#6 [H9"\@1_&'W8R=D9 &W-(Z P<'O)N^=QQ0!XNS.D):8^08XSD2YD1OZ"'2NOKVQS?KI<[($ 4ZC(H2Z*O!G/UQZL(6OL*HU,XK\L3.R5(-F^98R@A?1R9O'7F"Q8)D"DJ8M4ZX7A \2K4#%T144N[P4X'$..K0<2E4@LKHL3\'=6_NWC/N_G(%0RH%<[OVI1@TA,1C!Z' "%NA^9S)#-4O#'Q(@S(Q90KA9W';Z[$MJG![UA]#T8;PS-=QEBK,&GF7]7J+^&LI <9;@[1B*6]ZG%"SB%6:X4]9DFM0E3@QB&)KD??R+790H^AG""6 &AX$3EK2MKT4B-)8_3-FZD,XNY(056&2N*83!B#$PZ]%_,IL5+2O4W[0TN,P:!]Z /TN4F WGEQ,/ W;&BTB\VR.-)D*-]ZJ#I*_S^T.R%&P*?6E(HIAP239/$U%68=_Z K"]*FMA7-/]2N8CC]94N7 9\\)*3L? V8.FXKGO8*XUI^;CM:=[K";)ZSNI'K="*CUE?B>N YQBC:LRTHLZ%6$ 80)P7O<86B5);._3[TP^>-??+@NQ4+45J8IS*Y\'JBBT/IRQ:YVV(F93_5 FP41@ TV1,>M.[AW4ZA!!UNL%F]@LD&[8X9\--L8F6;/2)!,+X+TDGXNXP\0O&(?T2E88$ "Z'*)[?)_&?5^OE=?+PP3SJ5(E6+8P/G?8,O!LA^?4CN'^;DB.MHZJ!>=N@Z-!>I N].ZM.A=[(2Z_%4C"G9[=[U0P#B&6;_#C?)LE_S2FX/0BXH#$SQ1.#5$P0!^]K " ,F'-9Z)4B 4,0_YWXBDO6WG?7H,^3_)-;3E%ZI"Y7F%I1ZF&A*[YN,9'FXM=L>BC $(@Y00GP[O'X=T3#B.@OFE(E!Q,FN#J%-7=#1)MIW>C_'Y5GL^Q MW'+J?.!K-'J;M["1&7:IP4K4*++FX\"/72>?;OZ6=D1MVR=[/G;N#-GEQ=;_QLU ,WY/WI(&4\%RJ_'Y:7.Y"-%5=N^6'V#=42+I3$D7'@2:7;-;U [+>:60*^)QN1;/3WX_1 +$>9_-'&> 6Z?6GDQ=SI6NS@N?:$+RPQ9HN'I: ZZ0]*;.XC&! '#Q_-\-+\J075.:WJ.W(@[6<$=>>;*3%1.S@[:9JCKU^0EAF 2:? NXF6F#CV;S*N.=Y[4W\OXU[*=/R%VJCUN<75FF#6>?[E2QGY#Q7%NYR=YAFV 7(VF0Y*93++Q:)J.8+UG#(LUP3,^+HK$=*[C3^".4V1[*P )\N[DZ:T*+?KC;&GN 0> J#4105R&;0S*;LC+WVE#'224UNO)??F/('G;>5]23N&-V&XLLLCD>XP.F>)*6 C65^C*G-7LZ6,"8SH\S-;^V$3(_A?8R"4WL^^KUUD]2MJ/[3"397A]++4.)@H'T@ L"XMM!V@4*\QBTJ1,/$?UKR'.I^&\#OK\:?)R-Q?H/7)Q/H/.[GWHU/IFDI3'Y_A )!E:&5SL'M4>YG24=,A>GHTX(>&._HJF@:@@7ZV$Q9YVU^.OZ,!O7@>%G24ZBQKY R@DJQP9=XK,JV+QLG-. ZQ;-__BR_6E5LSB;X);0)XJYRT#L@* M500!?(SH!_ 8PB*KC)QGD-P6>-ED,S]7-P@OU!@LK@7H/.U/:,]HA@TQ =K/I+WXV27V6X/ YA'^U4AOQM\8%T[E=FC&$A3T5*.:.4L'H\EU -_6(O1R\K\N^'L/J2E(#U0-=,%J3?NCTY_((J-*QK,KTL;QDZU,XN9*E>D7;>W>. %EJJLP:'2EZX&OQALI?XZPKFBQS0ZC<#\;MZ\>'RD/A)F F"7#,N/U[:D*W<^2N!K1Y09=@J3!0AMF$ G9PG\0 ].%#@.86$ .T[%_QF:X=9V[T2&]&**H?6=1TE_D+BQQ3O]C3'-D"CVV.)$.M5H"+CJ(B!^$S>^[E%DI)ZRS+C*8B%=D;\-[)9@;)1Y#'Q Y+"8 ,. &) FQ6'.GVALYIYV7VHW)2IW>E-6*^>7V$5%D/Q9^&9NY,"K,XRQJ*- E&2(2E@H$5GLJ?2<6,&>'3SX35?ASB[NUM^[D$-5C!=1G.!V\@Y-]5C:2TW_/R&2"XOD -NWJRI7>PJT->UGQ=N9_0'"H;1NTT[< _>S)HV)D-<)))@Q?Q:G *4%RTS8L/'\2 TKX%R8JGNG^^X]T_\(3R72 T[C*48OH24KW%.?@[)]N("H_P-5O+77-($0WZ1THU NXJR#';5BWR]).J3W6,)=T1CUR)"NJ##]@+]42941(#]1NHB>(.LXY,U]85=/4=( 9LG%X<8EW6G?9L)SK@%[:Y*U+"7-P1A""$VE[@@DV6E$-">^RH5_&(4,:PSV:XWX Q:/7?O].E;NI1=QBW:,[\"7XB7= '^>H<:/QO_YHN8C5BENREW8"%X])EFQ"%J34 GIQ>58]ULIR]0U3RCVD,7(967*T'A!NK#4Q% #7XCLG!<'/"TYXA2CE:%Q^_NG./ 6%\^A0(UC2+.R&S_-NBP>+*']*J<86N=.KYA'$8'Y1DC9F3G"*.OC>7AU]9?. .: VXXF6:3-0J?'!JZTOE=3P^Q9^ALOA[="&=WY;&*J#6:N_Z9CQ+E1\3;[BE5KRJ_' * FTXJV]N]2I=65X2D?N['3/*9"#D[_T9XY+DNV\$+9WU]PN\58;9YQ$AQQ7\#H=8G> ($ VF]/]^+>Z]\RQJ\[*##P=681!?01VUTX*?(766VRPABW?NJCQM4?!2J(TXQ\F^\] 0:V@<\ FDSF8&MZMP[N&PRGXH%I]%I0#KYM1#[6,XSQAQ(A'DN+DY">#:\$)_IQ;F_XF,J7WUG/L\>@X MX^L[YX4*>R*">2:%X34%?6B&%.QE*^LHMS$2-\>>1H&JQINE);M4N09/#7\E4U WF&1.,N>:*=NY" 74U&2F;@FN>AERN_BM*R0C&(S>F Y9@ ,OTQ"5Y'Q70<+[K=[ ^:%]'?:L$MH]URZ \Z\L?Q_9*'52?1W)]0ZY< :)61P( KT-[69.8 .IWIE9@U8H0Q8ZL8=6#)+M0LG'K91T@(-O!P2)]M\ANV(369P8LSQ2I)6#4]@&32#T%H+K-3JN1#R%NT($8]'CBEY#+'TAV@G VU@\LQM[*.1!!HWZ0FY.V$+UW_JKD41P.9O$Z/!/QC/1S+4RYP ;F]8LN; .EJ'DW>OI2@B =?X''&=O-Q(^M@U:^[C<_K.?@)TYEI]\2)T(WMS'NXPIC[;8J!<6+4HK:]7OL'6+BU^SDG,^3NOR*<70"B@6MAT5)?>?E:.Z$0PGB[)!11 DT#I5TWG,,DI[-NX(D90C)",,F!L?@D9FQA;CZO'P_OB$+GKC20T<_J;+ +F=1U RF_:%J8A3(>[2*--H9J=O3U[ORBVG^3]^>\;WJYRVJGLE*GFUF(.TZ 6J@(U&ST7/$H9C TQ_AKH;!KQ19S95(L;2G:;Z-71WWN#V;[*;XU1:IJ&"!#X]8@ TO.#*Q^" 6T>V!63%392[UT4^8:2.9#^'R=F &ZS]=.J;,T%?;;7\\/O_9"#07YO[?X)!V+//?*&X^H'_9[9XU :5GA#PD^:DD;J. !\43XAX^C8.P+2#?&P+:/\NU<'+3U,,^NN+0![&RX-6>K8A*^91;2J;7.T(.)/76 NHBB=G-@6"]QIJO9YV8MTPL^EJ[%#S%AH'F^)XA)Q^2&MEC^>>D\ F(#*ER/? =H'Q[H2"#27'1Y&4X/.J3Q_S-3;E&:_F;[B8V%-K9FV\ O@KC0E^!2:=)=D$O:W^ N4NNM1?E_X1F*W.9L\80AARB!O B;"#"][],HGHF#7/7>0#F=_*0N8UM#\;,4A@Z J<4QB>><^<+(Y7AE.93H+J ^NI<2O[B9!*ALM2 5S9ZH';6RT8U(E5^$FG'<,OFWMG=CBE4]1^Y8<6%S*-R?_R= ]4+(,_2LJ>HW#CG &.C4;6K)I)Z)DSL9*+T7-LZKUF4"\D] &&)Z<-GO@[(Y6C#FZW_8XQ-WGDKHA:P&W 2(SN8E?&H&]8(D/QP;>$:)C9\O@A>+ ! 'KQ(5*SYWYVF^>.45(/'2.@*PEW$2(H!S-<4^2!>)W&UE4 SP"H9R#^">1>M)M),.3Q&AY,@8B.+F1"AT4T0 )#EM+.VV 46+S[H=B+EZNH_98P EY#@)DH7 0YP,>0 [&*:8/+Z]*,?ZLB-57KN\7_CA]%'<*+#//67P!$;'[)JR#'MIG+6J3CZ1U,MH]:= 8+&M"P(YLU2%Z?<'%$2R2&R#V"*'"3Q:-.Q$O646MZPK4>9IMW '((%B.XF2GGIY\%N,P4/9D1ECX#Y9:&+BL7)<+Y3#V'9CE::1T';:6Q1A J]X+@R#VT4/N*KV^L'A927ALR@B/K; D6T4'0D5CR&42X/K83/K6/!J]<+G2?*7Y "^+]]$/3-B"AL)"3O*#7Q>EC;F:HYW^$J< V N/U&A3=?'!\R)RS;NX-):MGE(D3 PL 3VJ9-5S+UKE'1U>N;SUGNB-)T=P(4UDE49W@#=8LH L\)Z"+-FD_?X?P(^'O: *,V#6TV\T9U"+$[2>:D47[T?9\+* Q8+XZ:9*H LLZ;$;NL,G1LX!@YR'!C%EB!".T Q!K'S^F)">Y=9CSZ"KN);V[/'(6A"!7#5=HNYM>JI$5APS H::9TNC1F2CA,BV/(1!D)&:X7Y'\<^2/2TN/]J$WS07N@ D_6SKC\]*4!0O#'CT! #."EZXG0(:F$;,D;MR4X\Z#OJ7V$Z_ST^VZXC V8Z!4S9[I&]MN8'IQ6].'S^##3 SU=KWKG>C^5VOI4ZBDUI'DM8)5?;3NV2 L53N"Z'RBM2/RZ]_QV!#7=L I*MQDP ^_(LGKV,DL81QFLR.]YEHZ_TLUWW;/.V_")>8=3,>Q_=#)8O;4OND=.!"KB?91&+ :@P)@0',%[*XC;)UTE#.'8W!/*QB6,XOTW("5#&NUD$_95'5OH:2@=M'J GD:)&P?U5*X.D[:BB?S/*GU_2/L^3*3+=_PF(^P5>PFX@%E>3+F-.KF+N'OT_10^ N_3KZA7%6]$&O\>+W%7! TJ?'FTZ4O/J=TN DTX)%; -TNY@-F'CJI1P?N[]725^#,F)N=,6N-];;'&"$]>=K(_&AFR[!W'(O%D3QK,H S2B=DZ,.*O5?=]-Z:='FQ@_8!?B3 :#KH=EY%D7?(+N22-:\8="PX"J.MON0H>3%@^D/_&^0;(@;+CL!B"Y(_9GIY#>3J &266D0:'LT.@TM0>55(]5 7P%(Q@DE7XN@.M:@/3R:62,RB.]@E9I,QCBG(<%#IU A.X)\^[IX:!_88B,='-:G.Y.J]RE/%[!SNG;*=PBI /R!2#V.YM+@4S!R&Z;Y&W* QE"J)QWS1WH^X#@J!#3<1&V$ APQ71JA<>NCU+EY[&=<; N':'.>U52O2! <>71W(;XQQ/XRF^"*M=86&FQ$-&SA;[!8TD= V?4S 1UOT"]2'"7BN1Y=[T2ES(@\$0LS=X9FBENP;<#&W!,8%)?49((L %0.4K7"#M<\ XL)E$M&CXX5WL%<.VR;.84Y\6+P*[ +5 164N=*P&,I@TU.JE[LP@K4Q,_!"-JC$F=B2B2=S.T^ZF6!@\J^F /Z2J_ B)(T;Q-IQ_0SB7/4W[P$Q%7/3/Y*/5@&-7@-6& !P X,B7B BX /R25ZK@$-/PAQ [&'DJ]ZP0TR!BJLDWD]/N6/0AH_A S%&),]&P*,J.-4LG/CIS;<"!X07_@ E3!S" T;5VNQ<7.MNL;MSGMO4QYVZ1HU08Q :O*U9=<*330.Q_.Q(#02/++AAF]_TO38"9 [4N5$^6L\?$-((/6LS/ET/I^?C003O[#;"2.@%LQ/>X/?/'PCT]"*&7#'&#OR\KA <%P+7 W!/=,L0D4!S(?QVA+)QG )^Z3V9&D7Z3I$HLGI2[8<#U?\+\@=D-_WHOIC):I)6'6@3!%+7#OF,S701]8=93O :#J,(8LQK-C"4ZZ=3U)L9U86RA>\ 0U%0!^E#HZD^[D NYNAM8@?4OEWQ4D8_O4HSO 6K)!,68+&MC-6T9(24*R!YI:+)@"&4E.WHD02""R35E)DHVY\LR6 A5O'$P38%0T;SD9]O 8]J6:#VA'SK>=!!/K*(NE:Y71"/2PM+?H9NI7)P2V$!H'G -[8G+6>NIO;V=3X*LD+-Y6#JOB(+/16G8MM.5THI[--$YYO<44XG8+)B(8\F3N = 89H:(U?'EF1GEF!(R#=I:B:NQ14I]0:X0KQT,3DJ2\:+.NZ-T?,0 )"GIT& R)77 ;7_\9"?6K4_<6+!,X.[W30\2JN-#\^(&@2Y9;#7Z :8Y<:[$1U/"#'T'"XNBOP)D . ARHF*#0?5CH!8[=7;-I8B[RNEV4PX>B'XMXG]]$P9.0H"8CA$V9E$CF)PXJ0$> _#E(#0@\P8ZP"%4$ZV*L(5'"0_X:(QP9@^$QV?B'\KG%1'ZV^>-,B,E!RSY\_O6B 4C94J+(Y-PK1(L4Q'CM'-M65.48(.N$-.-D! ,*H'2"@^KMS6GRZ4Y['WBQ!>":? Z+\C+%[FW]?&.MDK4Q9_X57*,&>V9CG7:E.>#F;^-\1NO)1)]K;U)M5UJMP!"'-T .\Z+X>6*)&G$VD,7-N^PXHH+;GB9MJ84,H@-LFY\L"_A@*EUME\EM6[;H34*)U+. ._."G+XN*R0Y:#)"K<;L34=/X"C;WJZ.UD2A)S?BJ)G/((*^XH8Z !HXJ7OX0#'$J3Y:Z//4SB"FQOP$TXJS&MJ?8^<< -C,R A,>&W,WI,,VO4POI^#^*+UH3$W.8!;I3R,%VC<_ QX?X*KLQ)\H:W3Z,MK(O)V&FNG]D(/Q14)X#_76JJFU/A1JK7!0/YYEMUW"S=F?" +>4KM,J^."I_L@S,Y@$<6>>S(,'15&"A OON!VFSG/!WI%.(O0@@1([ZF#Y?,9&8 IL88(V.Q>"WM%E1D.Q^JE\T%U\Z25N/-]3B"I!A2'/8/5OL@=(9U_G*Z/ HC./5&2937;^-M).TL,Q9*^,,IU2H/]WW@^2=PRMR;E""9%RM5 F\('[[T&VD$U- G9G<2Z/^B#!_//$GTW[>F!=5P;PL($"SX6AFME [] ,]?CQMW#Q5@2_GC'0.SH@6 -CI&<-79]RG8'$[TI04?N7:B:JGCJC\FD TH0V[?7\/9\&1O2=E VV5)P(^X>@R[ 839 88_?2"+Y$B.;I;C4,.>\2C&B:MO\/MLI^"LL!_^2$6&&N,T(MC?;N+86UY!^2O5 <&*Z%,:&N_ZB"9MB1$,&(E=@W]/K3N96'Y8MO]O7H^_L7:\\GJ?CR 1TL'H)D]*% >I8L]AN%7-=*MQS9-/NP8"^ZH@'*@TCZ4G;EN9@%/Y]==YTY)%Q;]0?_A$3Q<\B 42Z>'I()5VBG>RFOX/"[@,%>X<:[@2.2X[O)8G&'8RR3GW2^D%>V8/.7:9"@8514 'Y0N6PE>>5C03JQL@S=Q_G.6H^"PL=516XZ,9]%Y )8PG3PR:@D8+RG-OA5MJ)% N@'P(AK$F6@ 6*%,8-\7@OB"3>:F-:Q>3H5-[;H&7;7%8[!D,-,Q%(&L9E1>QQI( FOK=^DOJU>((H^1].X9SY)6<)P8#5ITW>"Q]L-\.V\\IC;Q2I7(O-_;^3UAB^?6] NEU\% ^3[NJ2_9&O'^M 4N:<(QQ35<'EM05 6,6(3]GV+G9FV1C@W&I^0/*GMMRI N,D(58,PE/]5EW5,V3H)![SS;:>29NZP/\!2Q&Z 8CY?-I*-5S:U6N?0WK.4)^8N JY-O2(E^Z0)JEEDJ1NK>L@(/@0^^ZQM3@2[UGPL<3AH9968K;XN!HNSST$+QF^=K 21;3WE9,:2[3P7_G<2KO.])P$]MV[07;^6C)2+A*K9"-\/OOO(J$45HB(S;TJ;E8 &T(&SQVUJCL$]_SF7'PKLG$GM-T2D5!AS[F:'Q!O,P%(&;"D,P#QI7?-U]LC4+5&YQO)4 _$RHHQX%N3RD7&M:NK.9*Z/@\_SWTIC68X1SJ;='@R=QMO1WC_BD<*"FN((6= W5?-1\,9!I+<%3W&PQ[ '&H-5,JJV2*L!9GH L].O3F,UP\ =B%S9/Y!]4(N7"#;\,G5]*_),?V)]&R#+G6. FB$7 (.I5$&A]BJ2_N\1'3-DM2$Q&JB5TJM^@:R2#FA(2;&D+7#R 0J*C/B.[,R^ . KYQ]K+\^9,!,U(P;$AVZZ28?K !3PU,M[]Z,Y8':DY!9=SGU+X^:O6IP*A^@BGT)1]RA"XOT_IW((R](U*Q2LGF#;] I7S36>A9X12=JJ;'KKC>F?81 B,YBVD;B;O#,IHN-8<.J(<$9B$_!@FH3]+_./JS T0J)-AMQ2^NM7B!6\J?FL'ROZAQ$!D;_/Z@S/_&X+SP7KULV_\.<< _3-> YZ_0V4>]J'F@":1OJF=IJ0 .0FZ>&E5^4>K@ 8B^\A))I*57=BC3XPE$9\K!+Z$%GKPW04FO'^^3D ;(]P=FC/O5\+6YI=IE1SY&> 5N'3$6+8R^!4];>=@':Q5.-%00K# ('6.8?'#2HD^#X^+3>0OL0C%&&S!:7+GL1!,>_FJFS1*LRGDD,W^C@+:@/$?RT)%A&4D\?C 6#ABBG;,6Q#3#INTY3[[8!#%FB"G=\K6*/33J'?CH@YA0_0J]B>:41ZH&LFJ&:N*J!,:H&KF0<50\:+0GYJN #G='':K#@T?J_2=KBZ :'=:E)MU/<_"(N"DZ;AEE!!Q%F6"7](.F'9;=KBTQGT^ O_&4'LF=66[-D[+I0"G?1TY+W_37,$$,VPW(=&S99O(_I?8,B:#L5#;2X8&LHJ4% 2F;YU4_F(B2D5%*ZQ9___^ED:V/$3;FL1GCSI&_A'=^*A!W"HSQ]&?UF8G$Y^)Z< 975?AP.?UIXO#6-#['!#!,N\) >\"8^3-XK-'/] #XE&[D;3IS+(*<[TDPCKYVW' ?T,[<_O@8*\M']0JEIAQA(8O/']?BFCE?+-D(V[YU 2AA$4@WQ2".OB'J$HP\P'Q7P0@TE]$3"4*=TK17#I\A3]99=]3F7[]L16H#T=(>@Z\V)*KU04>(% -Z$1WC,8YCXO>E10P=BO9:J=,LBEN[.RP@N0Q<-M,@:!0^R8A7_IVD:!%\D,VA8UA?HO.Q :;9G1A5W!H:4[DS$KD#8]".X/)+(TEGYL'R]O%*J<(MF?Z5Z;NH_H=E2 "9G[)$I =4AX!!F^>-AVJ-H6KL<#@NGE!*>$KB':+H,5+=>M"\#;_.#.IGRD=\3J;OA1V.CD K0IZ\?WT<%KE7O%A#&QDP-G$D\?FK&6.$.\IQ9$GC&HC$W3MW]$44I-.A6US1TB")Z;VGJ.5V>2]8]@&BT1[4L C3A_%;CXVPB(4SMXV!IE6= 3ZJ/E8VTDWN!:J];=+, .GDQ2),4CL*JKO-)<$-W!$8M.PRYD:'!@B+R]>I5VL4O ?X4%G]F/_5TZ>9A;\T!G^#G+"B:E=[4.A-S@>+YT?]>>-@/8 ?64K/?$4FX.\BU] 3SA<#5J+R'4*./0W"/AQPJ_-8S8(V)N5"$W ,?2HDBIW4U,TD\0?Q/RS=R=8\ZIG:J1Q8^Y*[VAI,!_CMFY,MKCX[]CY:=KXA%&7<+SF ""X8]-JW^IYD9HAVJOA&9M]:JI62@;J1UC@P5(:+O64G,\X6*7J .OI/DRM7_%=]W$"[E.SCV]Q6;0?"\HK$O4G?A=_(2?+1H';KJ3]CA]-ZC.&2B*2,AN"=992PUF?#!D 8M2CR[L3DT=&]WN/1L_/+7C/X;^B!Q9.Y*,X1UJZF.$:=>YJ9_'+ZWAXKP!S[=+LB76E KM ICR-08 K.TI<]^LYZMHT#?0[)"[ %_:<]7G%W:+Y/&EF-W)O;*9-]C&P%A=[(3@XZB9II*: 8#WD:_N\\-C?%NG=8W"?/:33^+TAN1J>Q$WHE0YU'.[:;DVF!"+K^G3O2(=1K\JO *X+EF;3H$,99C&Z\=FI_+.)I+3TQ"NI(3N:8U/IA&U6.B$T5X&&K=A0C"AE\F4)U NMTW.@OK!$1MM@A&N0GYMISW_'')]%#8=(;V<\O61DN;[B>F4[;#;.3N/$PK]R\% H2AO@@)GWQ8'2M:_+_=XCA;E4(Q*U";4%7V #=?N<;$VU@K2..PWNX@PF,#8 .B(L+G(VRO(X+6G@E9F&_?;M/! ?],!*9[7<(K$.#X86S$/ L0!(_G8UN#27DR62 ^PA,2J;QA770HKY$[@I*(MQH>/QPO (S8K)T%*$K,YLHL-3;;;%4?;ZL;*2B0"3O -ZOX+^&V4;P!/EN2&H3O,O),,2N(I&;-__ *IT(,=8.\]*WB)VQ>$KQ_8]5<>E6- >GLD,LJA\T!,F8-CYU2K+^6)_]';4_'"$Y<)R?'%FS&SA'W5[(FYQTVS/VG'CFFV Z16[I1^7N=Y](*>Z&Z7HKBOE;HB;Q=LC;X=1/.09D&[M%A)@24SYGY@$WB67_X@ \4$Q8\.G(N2]K"!6/0MJ1^IN?D&O8)/=3%MJ; > DB?!LFV;6113R+!2&E-NHRD; =I01(6E %3H>,RH%">B$X#-RP,82E%CCB9F4Q#PGMRN#]O7"NJ-_QG5M@O,(.A84 *0+Z!(AQ $2] W$!EX\;J!Z3PZ8S9Z/W/Y*-W*_E?:/ZA/)+YTU5 &*;5E!?]1VW A%)U!M^=!#D$]-\\Z0-#(I9H1[A1YK/!C ;<%>YV%5PCI[S1M=; UJ1-O<%-+P;/ P[<)8P+F(,BLLF_8': NHW#YHV7,4*4SPM/> THTFKK08@MX \"9T]=-N8GW \R*DW<_PQ_I+ BI#>2)AT,3/55\;.^/[LB%?FZ(XZF Y/]%M(!]OR%VYR>A!J&3F Y-DF8A/^L]V^L;.JYZ$.?Z81A/P>2!R_+78B/O_#$GNS/3HPYD.$JZFFP)_MT43 2"^ S' 9M0#("*.'V KN_2#@U-D_=(/:.FA/S=GYFEO^8QV-(O*P B3 RHY9*@MO=>YCBDFF#C<4KASKQ%2A]8>J- ]/&D19**\JG/;5M[YVGQE4(T*= )YKF-I7,Q8>(*%J_O1(,\L&FBJ2S)8!#9:4!D+GM W )H;, 5R@E"',OVFLX8H=L(\*I+U"A1DEQB423]9V[F-%O&"V_)8]8?NY53> 7Z4AK[3R1)TAS0OLA&:_MGJ[^C%?HQJI+0HG9) GF$'5K(O=]%&VCBMWN6 902.5OWW3-6*@?S*A5=MOC(%U=A;RH[;MB?Y2[F2HA/I^R$FH1E"51LRNAA[<*E4 )>B@:?;N9$ZC@63CST[**U+[7)@ZAP6D\]^J62A %/@APJIPE#OO 4K>6=P*PQ,M 9DG=>'GD=6+ISPP;H*"G:#,Y_"G# TVYXI4R9B'VWIGC99J9 JBH>7CJ+EO2!2\Q 1H/5M8MHTN;>Y45!S\]!V8FK,=JL<3[;S@RC)C+!]@%P#&^+@"E_,=ZMDP_RZW34 :L?8]9>_1V3U50Z()F#B(JZE#?P+L".N:X/"\V]7"7[DI&N4ML:NH+NED$=\ IM_&?'9(VUYQ)Y[]$6,S"->1_G>)[NG?5ZH!(+J4\'+CB8T/-6_ A#PZ45M9( A="-(!&-0JTP7VJ;;I:%FI?Y46!7"?<^*&N"(V&.S<2)A J8^(/!]GQ$HQOO'_KP E/CBNJQS,]TV"(HF[)K]+F-+!.)!JE"I! J 9&&4-:URA?^AA."$RU:G93_5&,,I F)0::.1BPC.QLO\U>,&@X\/\_(:;N+Y\:YH]:DF .?5^F0\J%U$0/;R3-FWZE_7O [&)*IFUTZJ22T)42DN>V"@3M/P?A\9 B76G=509"X26G477 -@DB.\#+HUTC+YTDEANA:H&^#U8JG5X*'[C')G*8WY!2E0>#4F2LZ4.RA9AV4TI/ V5 "('Z66KXG&JQ]H(B@=BNM$YV I.J'$J)N9;\-<_)OPG<>(I;B*9ZEH&AI1E. _8AN %TPSQ0[6Z*(6Y0 >\0RX#DZ;0_T;/B0QT>5HY,V^$/0*E*T9C*;9RX#:"S+ D+-V 8V3G#\M'GAY;A;+ DFW\HB>!'])#X*9H9$!R57#OJ_]I*UTJ$OK(.AP70,@@^G2YOBZO.%=1#2G4,#8# .RZRP9>D24>( L*7L$?@QJ<#M)O;5^EX*P_5L(EJ/P'F)RHTZW'("A)1D+0Z]TJV NKJ?P->W0'^8)<.&VAMUPB;VT*S) -@MX+6JC20?56/IJ-T^L#5BPK0$'D&#?'@* HW@RLP%ALE$4WR3@\2'^04,JS_=D? D=_N\6HNJ-=G;"P3X6#9.LFB"/R=H?!38-R,)DY4/".%+ONB.Z:A!YMXAW;=/'>9 $RDE/M9#_A?DZU%AS<9^V(& .U]#W&1RERB -=@^UPYG\KVB(^-1 0*8M Z28XB*L,VM]V4 H^;BPZ(_W&__L9(>V;7$VO29+0!9[T$P5K39TE'%K"YV8T\YZ8E#0Q&0FS$ U.8:^"@F1D>5GXYH#D=!X*6>R;\X47AF._B9,O_T?-E:8K"3GG*O_6P(4[=P 7N"'[2&^U?MW>V\,S,<6@7O:3(=!I*L+VB&D!B(X'2X@X?:?[JE:AY\-(S"O1FNP .EZ ,033XVSNPAT84F%(LZGH(.(:BC\O."V!37K:XRX[D"5<<6AQ2J&U4' 73>GG ]![H-^5D.XGG#::'HK,HD'THZ+A! U B3._1/WU4RX;":=^%7*=D6NOEXZ&']DUA RD+Z8R\F*\#A\E36A2?9B/]CP,3#L2,YH);_)O[PMV82A$$6.(L\ 4-F=@VUY4#9''4\)E#+FBFC#Q;YEW[I,34.T( .O3@.ECS1#'5BM6_U[;ZI>*_@] ;:6[G'+6QM F Y>S"K"4/D@9J[-*(?CQMQQ$-6B6:"#VCN'/X1PKJKPT!>6!'2C_ 7C]U<@.]&K'W87+CS7)\[A\6=WWSV\4PM_WJ@;9"@<\//S L^0GUBQ /ZA1.W$@[ ^4/5HDUEA.WU79AYIQS/V=!*T43C 75J9,65&7 0O (8UB/?[]L9@SD4^*P3GR7#H193(C!>BPWX5@#OYD7/N6'&V@_.DD:]O-]7W!Q .O2.W=,5 JLA\T)O@ 7 7,M:R(YPA"<[TG_&R0]8(09^4 34KTK3F"2FA-WO;PJ7 N= U4;THABV74RK[0U_-$H*IX\@?H*-D"+&\H=Y#>I/3TDT2B*ZHB6 3Y-OJ2A"G 6T3*3'GG2MK+4J8V3YL1N?;T@HKQH9.A+&9/T&%N+/D@KF,N6JI?1 Z[N.LANQ0%EM_4U%+%UB /C4Z,=;S]R PG5--4^RIJ5-*8:2F<8YQ^(-:\R/B+4[-3VOT30':-S *^U8?]4>!]RH)NUF4G4[/ 7-G2GY>+^@;3AV!N[\"DW*6+Y2.C)=[Q6A.%2M8>G;7F+BS,?7[*8%"_7OG6W:U4 "#6:P,.ES!&LX.,#Z $E4$%%;K]A2!&5T-"X8Y$OURN"L@BB*!C6VKS*K#/-M!U! 'WD? 93L\C.4!$[F49[F1'/%DFKPC*$RTL>WQBZK)LULFCC5 [ 9G?N1#E.9LU\O HS .P+;,__HS##\YVNS*29QCL_(Q5?0=7HGSYURSB+<'I(!BPR&%0(AW7,JWAN(V ;VIHWM_%=X8-/?W]' B!DYS'FL;ZH U4S$7MW@'%Y-DGL:X']X@0L!IY&&'E?5W9W/3K?C/SYBLN589LTJ0L: VO*5>-;3 B%X1>&M\3H'D[=:02-#%5>]%K*0JO^I=O0';PHS:@0_1J#,%S40WCU.>\#&$[-' 50P_B%MKR(M=0QYA<?J$D[9(@=/5"6W['D)]BKU L.<^_1;?3GMYR,LZ F&KQGM(@WGZ'5N#2GU[CIDA"\F2=4X@$R2B5GFF!H#-,&_)2^#.TG*H!69T>.9A6 -EW&Z-A-NWBI3_;=<@Y:,RT)[7A*\N!2)[*=$"&PB".OQ&N]AN3^HBOCW5X.J^/" 5RL+6["F;.!YE3;>:67IHJY@P51=LS7/KKLF;5Q;R!<@6FI41^904NBW*L?"+]= >6 !'[-?@H.M!UNFE!;&.KASJOO*5']X@T.LK%+?[DTKN2WW/MA2V4"266'W_7JA H?.]]".'Y@2R,&5SXW3*_R=E? D2ZPP8QF"R:L6K4"]WBF[FG>W6%E@AI L/6V.F0BE(L=$X+@G,Z36\8A-QA:\]OKI]/"F0W25,I:^73S JQ3#RV3_J=VIN*A5> "E-"TTNG6IG[;M/IPN(*,@L*!C,2M0,KK:%A@^6Q(-.$S$ $6BY(JY!RC]?A[6L XC KA!ZL-Y: H?TP>=1#]G%F TXF1D7+;+?G,C<)^6TQ#W^W1&9*)OQ80<#1--K'P6'R4M$7E1D%9931][O5 %$YEHLS(PO+*'T$YA +:&-J@9[Z_!LYVQ@4+;1W/ZYIY%%PF0&B'(=2"8<#"V %RJ#Y@S5C,3-@]P_NZF^6D:"E-+9,_:B31ROB?:V #SY.7@]W8-\)C SQ2+;DRDGXEEH[BU0(<-K]9>W96_GDQ<*H#?R319U8)?CF3A:5K+?R\C!_$?P>Y9_;>'O)/X/UA*_@)*&W[;*711E*+B%OH/\N*MZ=H0"M9?3\V:V[%*<#;;#;@V GQ]#9"[I[N\QP#L34S>L*\,^5$:YP=V1J;8 B?>AAW@:Y2/JO6ZQU55O B7NKE,J *-K@Q^T1&V2BZ@\>C9"VYR.7/6WA)UKUL]Z]2&1! 3QJ]2U)LU(V4+0.?/:^4!\K )T>EEI$ W.)3-5TFCH/0&XEU >/\A*K7R0-=20P2Z]_1T^-(E;6&IZ"K+V;5NF/U (%GGIBX\]?+P5R-_?ZZA:Z2Z7E32 0P+UQ4I/XR[G_XS/^JF#@AE:^QRKI=O MZ']IA]=?.(YHIB-%JXU>;=RV1^+N -G!F&@ 0X[(4\:-*3>VAJ$006CT>J=1P"A H>Y[/K?C#F< U]CT$I5:D$CS8>30/*5O@7(29_&2X,+H!(KZ%$UW2O/G;]L/U^12 7)P!V/Y*]GTVX(K%D$RK>I_4(0!MF.>ML,V5>K[ZZ@V?S\,_PY!_W 5[?_?@43]E "&B%J<=UN/8MEW>8$2N\ILDC!%%N%!2BE8HWD;IS+ 15_G%RJ?TVS"I7 HO,6IDMR6[3Y]8*EAFZNI_YA>#-QR1 7AT@?(13P /AFS/""*#!3,C5Y-UU(Z7J=S[%>+<]S58#9K9=7B)Z^=C T4!93%-U07)5;'*.NYWD/(T.+;CD9#A?EMB)K=FUPGI8K%(07',J=K!YC$5K&%\G =.3]4M*>]:2B!_P;F1L8H&G7,<34?KK@L 8=@9!9"V_L4Q0Q_0+=C1.&D"XA3GH2 *3F$(1-K)0Z-X6QP#M@9 <^VQ'!.J@#F?*'*T%BL0(=[K.&8*'^Y%@2#J"W"U] 8$.+ "+/BB+"-&Q#(B3#OP4ZMJZS$XUFTV+&]8)[.OC7 )Z DKC9ZQ1QD=L"J<3[;@BUH15DD*AV)YXVI!-.W[!>WZ#Y&'@GO1Y9P6-F\7O.8LO<%>WV#Z,J4EC'T59N7<$8N=V+V;!=3!WX;G[SV#%9:/I !VGZ-GI-\G;"82^FXQ<>A#(_*F5,PO6T>(*OW%*KM#/""J5+@8 _Z7ZJVULHQBUB Q7@*2E5@TG/OQ6!P'/VI.>H84K+M;GH'_>#'E *X#W9*.N_P)XM<*T0&>^^&++7"Z=\^B)<#G=\ 7,L@H>A)W'Y]WB$L?%4?R$L&TC5E]S\H:CTJ2ZN)3[KX,#L=@=;3(TZRXU01<\,/ ])F)#H7=^)!_ )"3;G4&IV5S)Y#G=Z(LV[/N:XS:4CU# :+#S/>*0DEGM1\.QI9[ &0.(@T]X<1QKC.(8TCN$9_4O!2$VNE,>S+.R2NA$-L3M;O5 F+KY++UCI-R_Y;G /#[7=G'NU_"V U@_>G=GO[.IE&@R^!"GDFLKK>WE-I_9AISQ6ID)!R$ R56OA/)@=ER%^5>B2E[2DW)MX1U8E*?@/.QF83FX'L3&:A39\X#BE$DI)J(C^*15=Y%:!R7 )2_0W.4%@T$RA,!VS1'=.1JG^URGU0E)QM$N9L8P,1G;P65G/*VIQJS6@/WV,"4D O#I5S,9H1?\#42*>"PUR7RZX6\=#W/0^J0\V8Z, #X-%G[91#8OV9&+&/]B59OCP'7ZF&UC^V-Q8^)T>Y%#1>ON11(%JC*UD (QG 4/[XE3B&Q]$35OQV+,]J_9-2HU$I\X\G7]L%8I*6[ )=8\S90C!B(T+C&W-^U- 4 #7-JY,<3Z*$R*U;GO+L'J@'- BM/;A'S@7SJA5DERSH&N9QI!YMA:,\T5S3L,;2%QU(]^FP!Z5_(] HJ;A$)#88DP :2)@:MJ'[!G0124]VF1>K.MF7;K[Q()Y3=XD?7.48/-A#1B63C\Q:TS)=X?6B)D3 !$51R8.PMFB$53$T H1=*]49WZR?*3^ 3&'Q.D!P.T'45*1,[7&7L#&VQ=]/JR_H [*%"KIR/&UWEM-I;,$Q&0;7E*%9]P)#1]J1%U6 EB-^WMQW[)-K!55\!CSE$DH5' $EF4>;17%\.W/2ART_$\+P:O&*?E1^L4:MVNFH?RQZS5>4=RW:#I7^3N$N.S.RXZ G_ZWVYYB7,/QWTE=6<. -9],$U9L_3,@HQKK-(8U'CEK)QN(DJL?@?_;XK82'><@ 9%C"! 09'1DUC_M*I\]H>'KD_&M,%F8$$O91HC4Z7JX/8!UR 9'GW)B]$D5H= X ;%(+X_K*SWT9W/N(I)Q8>KO[D3@#EXO.UP;:AST9GF(P\F"7IR"3A1$RX%?_% ;& /D?Y<@WJ0(SU[ JYT9UQUX$(Q7K[U/-TIJU:8>0B FXXD&S8QO)EA=3ITN?A[4## U$/B.HICZO(85 KL$_L+JE1.Y"X\X;@N-=/>M>\/Q04'Y9-PFAA\ W5*PX.'YKPF*GD^X#HU,[J=0]BCC%>\[H@KQ88IR?EQH$WCX@WFT'-@D+C'@&B4M H0]JN"H27A,G\$&(**T#!3(!2DRB$8D.+BU$NIPJ)*0GM=O)9*]DSMZA$WTCP6; Y4(N9/=^%_"D7B]OZ,(2G^ ;.#KI/L%N& 75*/1[TJ7#'<$VF2=KW]FO.L#[4R"&U)5 IAR."8)Z'DB=7B!FG^H :*7 Z-G%8HRX*>;$I)=>L=M\$/:\!=9-6>Y28$'"QJWE+]R/;7^#Q)H2:W=[/A&C (;.D(W)V)KIS=JEU=+I:@Y!N"E$(J/=BX4CUBR:"8C]5^7[T$6,.R00O)W3[X,0. ,*/3RO4%<@7:=#D3IJ$@([G^ YLMQ&^2Z#P9Y\\*\,ZDX5W!8&#E6T4;SU'G^,1* ^D=$L<+];KX@U!D%Z< PE+2*:3V#39)S 8&;9\Z&6]'7,IM<\-\=G&T%W#,E$3GD7\ W G5;9?09//X^,V\9E<5IRO\!UJMT!JXM:27+(*M&<]Y08.SSOBA_SS)TC47SVXLSU /L;UVUVW F#38=*Y9&;VN8,=">>' /MBXJWO %'4&MSYIP4#MA)/M/%_Y,/,]+_R 8VEZ3HX13AN^IV=L[MR84),B>Z67??V;P ]Y,9*.]=EU!NCO"W\6A4HN3 -X1E4/ RVFW=RXA)%DKT <6*"9VH$:87'U'>:TT=\.?@( [$8/Y=Z<>*_,!VL+^#W>035;G N>;ZLJ;K:!#H((MG_&@TXJ>5B_XD0:AEC2:+6KY\O$WQXN$U16/;66Y;)5]8!8AK S=]4\2KP)&6B/B3PS#*%?R-P2GBV&/C<8V-K5JH"1=,?L#JIA@ >1$!P%+>#UH?* .Q ;C%;L =1E"?[MA@4"?P?2.K\M"NDZ'G'SBB5+P=2/B9\O4<\'"(CK/(EGXOAO90/S?YF;E,F5A8N"$E*7]Y,!XGE>(:MY.)@L2:8DEA@G]!BJYN1>EET4892*T=B5A7-LVE +K2M.7;',L=T,7V642*6&.D#A'2C^M]':1X$^@"9[]Z#]0UK /*0=S*,O:9;IJ:NKAOO^/2:'LGR#C$O4_98T2WJ'I+*LAS#?9$V7 )F,+E6SV92NWLN)F=PW'EA*]RD!M>-)886]XY NOT[U+7K]TO;F7V^*GB?^8E96U 0$U<@N!K62X5G>YFNJ%_-LY\L0*,X#=0V^BC2=[+T/#;%T"\;/*^NNA9&9-@C?#8 &OQ*V$S3_+;[CEL<5U2).L%')>5[;59/2Q8'7Y']A$^09 4X@.=?^B>MW!-7DFZMJ+)INB_QD]%I_C9_X*+W;QUK$6V ._;K7Y,F;J5F22JW";+0C4&\_W8\BXWWB.:LV8@[C!OB!N6]ER/[<0YCI3N?/T3D UBI79X<(ZY](4HAO_@27UP\6;_DZ:V/JM@KNA.7DZ[$_D C$T7\0^ JKL8<0%=&7=1>HQ_P!6X3J[4DWWE5]5@+@-U'WY#Z^/H"#F%\UQ=XMJNHN;K(0=N W''EU"?Y*5T&!C&F[7WWQULOP(N1>J">MA+8^S?KX<_S+GC*)D:"@ >]S;*V[4^5 SV!Y&TPB4&"!O>Y#$8?/"Z@L_N%W&!98PEI!%;MM+N)X"$-[V4?\3VM\[96U]'/C %=Z;VU9U -@-28;Z3-VY$Y20ME(]@]/DE[=!]%F"[8@;\#+ONMON4%I1EF*HWV_; T\A*O[9C<+.<5F\3^E8\'&=G;\*@':B7@D'\#!0CF#(W.YI;[RI3[O5&^?JI_F-. &])+D!&6"<;)2O0YLA&[JJ>G;F1H>-=UUMJOUOUN24YC^%%*%IZR%8 C/QW;X $^ UOTORED]*+53"KC69QA?]]7CU*)QC)["^(EL=$5S0!SBDM8B@YZ4CB 9GA3^ =C//6H]VE])[X_%^U&;U/9834ABN?B@J6 K(B^2"?=2ET]LKRNHMI^H85. :F\VHQ)LK[7:=BUX^ZP_"RLEWWMJ2I$D4:X(-A00,TF?ZTT9\'B54/*[AD(ZGB@= Z,.+*;KI!]0*BV#U#LFP/H,1-<1KL+E^6=[X^N7LN!O,T+A\%#BV0B@7D4K;5!1' ZL!F"FNG%(%$"0 +9TW5WH-QHQ)%K%'AN<[ZFI2F@;T=WXS%26^5+5(UL[ZS$#]Z=V =7[+[T)Q5J"&% E:^21R\OP,;KUXA3/57(:T"/H,9O-(0.^T6 XXN3VQH\[4ULZ) R>:)WO:Q >UCT:#9,TBU.ZFYV61\ARV]S).KS'XYN X>PG>Y.K@ RZTD_+)07G\<(\1Q-Q=9[JE8,#'5E9?9!E&"$@0&&B=G:'($\Q@P]9;41MQR#7<1 IZV.?SX_(%G1.B=%;O;):V^(%EGG"CRO\]+D6A*DXINQWS\CP,YCV=\:Y ; 1J5ZAW[P]BC=8C:WG3WL<"[[,^YEZU#*KHM2C68RCXT(?1L79/\&3W[4W1F59C _-N:HI&0=V BLP)CDWJ74#MRNSD)\=F#.5(J5R244FM'CE9F 065B*4U\[6YK!=T JG04NL;NYPQAMO!SVWW)9\$J/D"[:3->Q#LR_VHB)/*QIJ'Y1E^]WP0(\NO3PA X97,&2*= #;6P XU/A_V!M#8B[HEN5/K%J"KS>2]RA(\:S$'+W [K/8W [T\*<:A_RH>S=4R&*!<$--EHN4"[Q8\(&4Y>Q[FE+7.BN2 #T@DTJ<"%,8X8E=8[ E& 4_IDN?JJ'-1B^$,>!6!8FQ%L&OO++>N$2-&)&@>#!=+C;WFBYXPJ, R^4@T8OAHT&D&^V-81N[&-F*C>Q[A\$I>'GU2P1"VE^H)16<[!J=PB=>^T%F?+%D "YR0.20(8GS IM$%K939Z_B)B^B'G]EZ5?<8/R?0OT:%&MTQZ1]61B.P4K"Q-HNR FQU:8]1U!49F,34\7/4S5N0HK45$++SR4+3@C@.9&+HO>WJ+^A?"$++HH$:%/'&K JD&TD=W\\5-K.(DCQ= !U>Y5]W-S/F"\O'/A??$*YBOKE3YPXPC WQMU,EDX^@-< ,VMYS<'/S=NL:!X&4!S0$AFFFY8A/Z5:^D_QOQ42%%>25$2> F30J,U?JT(1H>=S2*E%[2_Q.95J_S68B4YV[Z=Y& *[ ;GS&0L*:?53^"A&AODT)ERY,_!0L,)-H#+D-B<*:]+I2,\5Y'3Y5,47\ 1(S*K*/9":<] XGLW,R9 ,K2#JMBA48[O826V7^S"C< ' \VJM?ZVQI5N0SBD]SI MX^"7O/J_;.*=^&H8E-D<@<>HFL8%5N8'$5; % <;V=?E. 2G6-N+ GFI2;IFW,;?/H&K9&5:V9U#V&*H#>-"Y&;+0!,\F143_G?:GH1;^\+%++ CCCOPRORHNU9'/)'@B8+U6T@=#&:HJ8RUR=E+R&9M6Z4+-\>@0Y N?8+ ^TJRFK67^F-EN1DL]*F. "2/][SC!D#6T,-TQO).)ARMHCCVPA5=/#NPI'[74B^-#B 2%AC!3",DL9]T?"^C@ A>N7VY[Q'(!]8$6&Y*BKQ6/JT$Q**\$3,\)_R+&F_59;=!V+=[(N>5,>K8H*D679N^Y4(=LY>-F("1G'=^ZP)_<5/( _5O>#/EF(,4IF1N]KV'K6M3!"V>-=6,E'.>R""JAP 1&DDF/R-/VI%]$9FW"T&_Q T>W4\H6<@44-&9"6;J0-S!2V"'UY1]K-FCGY^D5X1Q^@ @UP0NR<@&V8&^Q#/(<=6F<#/N&%/@(EI2#3A6^2HWHILPR..W');XN5>?!6Y6NZOG(J"QR[-BZF.*(L>9V?Y8\ PXTK=EG:8J_ -!&@A]1B! XD1&Q^*9%=9[V2 %GDH9A >O-> 9E1W/DI\62TB&M(+DJ=4Q'LR04?H\9=UJ(5@]#>SB-&J67F(&Z=O F\ W28ZW_WX'',O<[EL8JWEGJ &X*FATENSQU<=2=4/G:G3IJ(4Y*T: <'AF!QG263-Z'!6@9]7L(EQ+<'I5?F^A&-QN8M>^KA!..A/?>,=\V?\OO5;1A:&7 ,F62+J97H#-([-/G:#C9+.$$F,+77JF+,0&Q7/ $$2-Y2RT6)F,R(&JY%=$'"Q? I.%V#_1,EF6FF4C[9OBZ;T*1=O#YV>SAPA-,X,0-G^.6%BY3Y8\:R5$UL*IYA6X8 7(! ;#R+*;C:IX1F9S^U,B/,\;]_GENHQ#4D:Y?(EP0YN^CKYXKT UBJN[5.?[SXARJ48=JKF(>\!7BAQ$-QLAS?47"26G;JC$6+$+U=+*__(?%,LAMNY 8V?C1?9"*O&:X')@ E/^L6_(% 13)=R^<:-I@4 Q] V\UG>36 /\TZ@)EE##L$*Y6(SW_U7IC[@T >T:R 5U&LX;[+V4#LU'I8SM7<:TV40D=J#C-5=MA3_[_J]+WSW7?S#)M4YDV)B(9<5;L9TX(>U =7JUC?2T*(3<.ZHDUDYX[_O^8Z8EDT:8M++^&P\8D$.?CLT-M)"#!2[O,-)0A;SY ;T!@:K?#T3%FJU(>/-G;)>1<&QV;7*\EYI2[K*CY0D]3;(R) B_YBZYW)^\N#++^ >DS'JMX2!1SQ6N60( Z>I"MQ8CWI7X!R%2N_U%1Z 0Z-?[2B7&NPG]K<9+N64 8_O>Z?F+TR.5-^V+)DVW]VE?3 ;LL"!6=NW?R_YA^]EF"))Q!K/L1 9T'/F'+[+(RY(@/(JC9O)_M+?6;:$ XX)=#; CN4X4FU 4[)9J7$WMW38"MH0JI-]M?!"P7'@5M\4MSVQ+(R\MR&PE"J-216O]"0V :625H]S.^3$!)HEE<215E6\%&Z4[&G9A-&V*M6:^Y4B*AXT-Y8>0"DU?3&M2<@\] BRIW4?CQ0G6*.J<9$X5;(,00\/P)$"BD?T 6.V=Z9[DIP^_-%RIN,!ST\8C25G#&U[74Q$S1=2+SG*=5( _QWC3>96W#9CKM-B6 3C)Q3>\S1(A*1$KL90W9 0K&EZCK#^/XO<1/)HX*&>>JL&('TX(ZZ&U!A/Z1GF=R 4FIF)0F+<@<])I^&U]B_ AP;76/(3"V=IM3P3W;"*'T>VDR?JBFJKOZG3R140^;" 651!B#AW&ZG5M71BE7+ROZL9FB"$9'-$;!,#-']P\"#9^@>YYCZ-C9UD"4%Q+@/( ^ ,XWIS]IE^KH"W=)MNM9Q=>X;L/I=OOILCI&/+&-U4:-#P9U2S%KM(?= T'*WN: [@*3O-8&%T[?2NAZ[\IS#0[82]'\V]<>'+)\SCX.TBJL=#5QY,2+CRW+M-2$9!B?@<2.Z0 O!]9/T]I4^@$CLK5GIX1HP'UD%Y2TY,H-G"9Q1$&(9"8C59.KK2VV2S:@OG39264 VJ9>+,U>+<+^+3TFJ0A"9_&]U6N#*B/Q;5*PWLH+%&HSOOV,GB!.S'DY4;0;LQ@] Z(JLZ9V!>K$ Q7Y!3*-@V'']>"[XWG)C88N"MUE*(_@798#&!FI_!N:CAE"FYS*] KQ+TT%.T CX_4&.-Z!1Z5D OD/Q7-T6Y*9ISW.YN+07XE.4JWSZ2*C#+I^FF-S8: ^279&K3%A^EIFW; 0)5=+DX9W#=((J8T^$D/+SJPBV!5OHU)VNV!P2471]> ^4AU@3-3(\C O3EL\V8TBDA+NC&MJ#PE6P?HI,S-H'D:B2+/\NQX]T>#0XB)YA13?UEJ# PO3.>FO?(\"V+0L?F@:E4@]_ X181N39!8\)\__UC:QL)*0CD_._3:)1L@OJ1 W!&SL+<-3O(/]<_^FFGUX[B_TX D?148([IU$O3O7:HFSNYUK@DS>M_$,NI>^T&%?&K6B^@@\DZ%HIC4S:2F3MMPP5' 2';NM 3SYT4L8PRVIE6,W936NT:_3;-8]K#V2\CN#U=P\3J[H%@$,Z!GZ.&M'A%V :XP.W#J$3<'/HW:)F85P?\PY.-SI%T RFZXJ2_%G1F1DPZL+1'=KAU4M3C.1 7YY8E]H*!9YKI$[:>XFE@+!(Y.)PDSLE""WWX&ASE-/5_C08S1\/ZK*'KNZ&7:;! 4JD]GJ\MNAVWEI4U6 D(NY?\A>:7R&I$M;)Q03> ]Q<7*O8QZG!P$^/ 7.4 -_=Q ],9MU[O@&>'ZUF531QN?8GL-(0I71DYG.7FILS.:^WXQV2 ->V'M-;41 NA&_'5I*F=&"1^=U"K\O3HH8SWA4>\VF7U6$45IG9N9M'I^7Q*PT"/ 7U4GY!6)S4!XOAKJU!V_\!O.1?\&Q;[@/1@05'&^C=2++*##7':56G8B;B"%"8LI /6#,>!@J.1(GVU^%(:!-B.OF*.C EQ/]TUE\5NF]:I)GS6>QJW\Q?FDYGP(4=%G3 .BCMKP_4X0<+5RXH!^1,7KB\5F%/""Y97^SEC[:I&YW&B9'NC!XLJL7Z2]!2:'31;-Y2.+_+I;;4:1IA!T4NBJ/1+W..^5&G)5I1E7/.&3$[*&J A0Y,Y-KP:T3M>^TW,R@/TJ'#:5ME@MAY<$)\J*+=I"N4@AVMKUD!.P&5]K(I]+3[ 5;H_,,"AN!NU%H"Z,DJ]1L-;_6=.HOYCR=R8092'R:C81@6>]-(KHE++ZK%A::I#-&%/W)ZCA@'4RPU-O31?- YUDERT03S6^Z ?DDUSN_4$=*)8QO\#=U9/?UU698F(F,;,=&U*KY##0O-@4(?^!;EY.FW[$U<^6*R F)D"[&):,,.W_HT]$*+])79'B,H4/X@]ZZEX7S;)"XR X8KK8=-;B(?'0V/(;(=. FE,7?8K+5I)Q63B_FFHL47Q_X96\[!;728O/*:\K=)T^1H16,2OR@?J5S?S8ZAQB E%J52/XYCQ%'ALFZOZ)*]S+3AND^@=_"+S2M:1G2,W)QPW=;G1#=,H]]89)]0X+= <8OCS(RRL3G-#[ \!0%[*QRA!=7V(W9Y.P']4G,RJ"@\D&5MK6PXZBE8QE+RYQER< ?'YP(&Y2#)G<+&-)<+#3H]U$38>#X14_@#&]?:G48"]2@2Q+<$!I63?'JJ! NT<@3-JPH?T+V3]#(QWU%ZOE)B*:44%TFBXS))2#%"J(1,&5[,<*.(2RSM%T=^:3 0O[R,!XT"[)E/B\A,9_=T_8M9F/:BF?P '&.9Y'/>V19XR#9G^VL+7.L%W7TO 1I3,18M6)_(6)A*9##0&_2W7K[JQG^4J .QT)K0DX"1S WA7$^&/\3X6Y;]-OZVUDRM2/"S&V7"DP)39VY*G23\5=YE3V:>,4&&!Y"W]P8:'[ H/8&Z^:+$-T>[',@F14I(W:%+2X/5O#/7XOYK^)*V+#\:3.A0(?BGY^(MO."(85DNI ]? G?X=7."AK-6>:="H'^U":5HQQ'+"I?@WG.GW>+7JOEMI6.1MB5_7++EM!IL:*!B4 $2F(&T/:48 *H?$9+#X %I."?KBZ@IP,"9$5?/-)(XG(P"&Q_@U7%,8J)[E)'JA\ ##Y(7*7$SQ(?&8>GG&GSW!SARK!#-7JR7=.+&UN!G:Q'P(*^\ SC=2H$(WX>B"GJ E4G%8?E!.S.1].4'9A<[7B3;O_OD)NCX@K&56(I#E[U?3P;KYD'"?_0_, H*JM_6 [JJ[5VLSH//Y[:4=E71;($]W/[D&Q?%[% )NO!F10V3@T?"\85 .%B)OP\V'@145Z(=)7D(0.M%$9(-%CE] :-KVO"^C>\IDPXGF(M%+CNE \IB)0J42$A!/'BZ2'77"]I1^.0G8DZ(VH6'.'C=_ 0-+G@"JLHI(^'![%](B Y_[F**++-TF0+LX-G)Q[J"DCY&23J,F2HK_2QAHTI /7F2!GMAF/D07A_;I))0-+/V,5,EYJ-!\=R8FTXP) V)J^;(VV879Z?JHZ/T;%\C ^K&X7I!LW3D-.L[I"G'R"J3WB>;Z(*"VJ:[+@QGM>('$K$8D_J5V3@O[OP-T6AI* -MYJL>:B@$^I&;V">&M&9 HF7S%1KY?U"IF?=["F,ZDOU;8Q<'CG*O(TG2@T-29PBPD6.R>SJ!P ?'9RW-BV<2?M^*,%V,1GC8ND59[L%P6O%2I EV,/_E:%1U:[TB)W@4Y'/DOS-)BH *"/L8E;;2[TLFSE>/&:[@;BMM\I[82TL0G>%4+>U&N->LZ3O5SE5I1*QJ@L^KRA] :UCU\I:I=I)^-58085*/5H\XKF9GU/V06HNJ1"*%)TFQ$QN6U-P[BYPGL,_+:$.F&[H I>0* ?N68 I @.D+S=#B1ZK7#)Z>QM:#6[I0NH_IN)DJCOEH4(WC8CCG$!S!ZDWB6\9AJ7V#4J#G29;,$C),V47ZHH2T.>WWMQGSQ\3(JSDTB) :2#*XAPAY @^O:]=P&.G:+Z1MH':8:".O?_2:-:Z44J5VT9.--PHZG?#BNS=^C"[ ED$-(MV@[FP6DS DT.0('2\QB#-PB1FY (\3\5.X4-0KO!(1C,6Q*8/:965FWD-] Z->O7[IR0=E]_8@YT'9<#.J*^,H-.%A6))_UUE@,BHJ;+!2H> 7[QD'JD[1]1"VP C6YKP9;'UJ+BP@DYIUG5#+@*_-MFGGUSZ;X!PQ-TW_W2)^E;8HMW9A6&&NL/MP5F5=!P3-7"E:[@NQTDB%;J *@^N=V]T/+&TCO"7;U%G>*1QW=Y(&'1P_;-]X:"T=V3?-$;ZJV=1ZB12HOO8(U(R _!^I9>^1A5GJ RDJL8"-_(,6Y@$]$(C%3X#=NQE.B]74L6T+=*W(\B$?MA&WN#-QY 2D1W1*@)E+KHN""Z3NE^LCB 03(PGO*2\6&?,2,E/. XB%%_.Z)PZ,C@^D;587QHWEF&'^:;%.OAK;@G_11>2:S%#1\#%U FS/G+WMXV4)# 9OHF?U[ *"22^#]=6],GEVGS(O@*DTBU-X,+7"7&KGC#0Z7(-N(&)GQV\@9F)O]# >@^< [JP=,.)3*X41Y2KCAR"EQ3%RW]H>5*Z6A 1S^&*O:6K6&MP6!EW.SV%PXGG3S"TU9+QSAOH"M>W;-^5%*PBZ<]#G4-HH44PJSZO(*EDH:? <51Q;>=[S(?5I(81MCX*$UG@J6Q]>,^,QT6 +WQ796/.SDA+.-XM^U/Q'$K"(3!! %X6M<,HL*JJ=ZJU$8'NK?#':KLT6$%T%N(7T;Z=$>2>J&7*$'?,6'*Y>3LGY972/I[1:\J14"X"1ADS.I# Y='.;J!ZQP:P/IUZB4><$CTWT3.C,E--M<-)Z4J-=WU^6/(3=]P6,59;MBZ(T -D :>B'9O36F=I52FMA=6:05]#V]?]!,O13P:2UIZ+R*U/LWG@K]J(+:K]RXS'Q%@-C 9N=KV%,Q$SC\U]L^'Z/FFQ+,^F$AX&30N1P>1CZ:1=[:*IE)ZA0K!QL,%880 37-^]TSD%CWE>L"T5FQ(3B*-#@R2AI '%5X2GG.VZ! WV92I$/CUCBA..U._$M3#)$?]0U=L^!J"<8>VQEN "5KK3AAXYA1V3_#>XT<-C1- ZSF-71G?(/F%_FZ7EX^B@;Z&5PKJV9:C%1/G(602 WSD-S5\_)7F1_"RC/:-YE0)TI#E!NJFD],D'&;4AT<*,EC3^27K$DD$;XFG'+*UB UG63T&#DO?QM89D1(P2. /CS?C3&CT*Q+0(G_=XV!&4/>MG3=S]!" Q.ZD:'T,,) .>ER_CRP?P^-0YFLG'\=2L073,-F%03!T#102_D[^/=D+18\/Y'8@ZYM.E3W5MCE *%PS(LNS%S5G+ZS$&Y+GCCMS<2?N7YR0(YXQG!WA(;I.1^TYYV0D8>YR.X]/LOK/ Y+ T2&#!%UA0O?*X@9F.K=2#G_*?7$QJ7>=JT/3!1002;-C^LQ\X;75;F (R.=XS 9\Z\)HQWX^%R6C(A%4/\YI>S.%8\!025A![#.\E36@I":^U\W:(W']'4Y"\9FK1 L&L;6)"701 OM(9WQ+*.A5GD[) M91/%?3BHU_5H\^$< :X1%+&-_UL ZW=&$15PDKZZ5KE*,"#4$>T>7%Y\4OX$P^ G#.5G\$SIT')$!25II54\P>K]4&?7]O[.8Q[770?=)%P_.O$-3A?3ST_1G I]%)"%SJGK4#.[62/-*^$=K2WC]5=. P\C[TQG)N$$MXT&2"E*?6@L.[*#X1RQM& F?BJ<#7Y6[05?G&\ NCOB*KM-M=BK=!OFU*#Z*R0F3?'@!"\6UT]*KT^MB0N)Z," "BZY9:1(7KE"*%*7L+D&W/W[6D7C:Z>#1SG?6M!G!93.T1LF CORD653*?M;_-UQ=J?YF=@_9'13W8S8]^RZ\1!!7HX;@+Q]GE9N.E\?GH=P0*//W2M)(&)T TP5^\OF6UUPTR;77^UUJ,L; VES4B#/1X.&(ME/C)8*;Y="'<*E.':"M-=_"C^066R9[TCF>P_:-,\EG/^A7BP%Y _D>-'EDMLD%S<%*>A3W<^:-/*V&:KEUZMYNV6VT=P.TC55+ I/]SX#"TG&3FY2#A2U]!?BQU6G#G-BJ/T.( >3#O)_V?YN E/O4&:3#\/!\YL&5(8OH&3DI_=RUD73TX>X_^=[U-: R&]B"-!LF*!PKM5&5TWH< 4D/"DY6G"?3!X:/QB_XR]52LYN/(;'VV^K\^G3I%$RUJPAH%9V%EWI,E%FT.#'()FDJL8>[K?'7BRA_0G-^WT8M?T9?Z6,NHG N,W7..HP2F*B42#*(MC$+QYN5I3YGN/>4K0+XZQBI^/=@NND0A 'BI %'755YNB5 N)5&?MCVBT*.7[3@67J'5+5K5P&<6MKO+_K[DK#\_Z-=OWUNOH%2H# &P::+@)[<-2Q",W N%IP=&B\=\Z!R.3+G8 *_=*_:C['B TIW1;>1N%+@HI1VA0O'WSD *'MH]-#,XI0@A#R&SD^0?OPAVQBQRB=XWM$*4^!$EH7= $Z26<)+&:AY!!55S3<:H6@R^]$20ZRNW[:4'F =HJ2C%A^!7SZF&G.>62+T-+2,4 F>7 DF LA$!9*Q%#?=Z).3TQ A*S40P&DVFA?!L'34_%?\"M83+%@XMKG6>D=DST I6$R..P":GY25_5>N?27P&];ZW+-:9V9R5OY]F/JYM^\@F"N *EYP;C>$2&:J(&7 ZB]-KUP6,CJ":WB_&A$GEC9]D%UXF-\UF%U])&3I\M;\!0C0,T>TO4+6,-+,^(SI ;(BLQS]<@-^;&Y?FT/#M==4?YJY.KN8I,/L05#*N(@\L0UC^UIGGDAQ?%1 6T8;] 9&X^>\/KI_=/SK%=Q"[WQX+963#VCG?3YCM&"Z/] R'O K'IG6IU\Z>'"4M4,BM] <ZFURG$ ZK 11S3<#U&4+OY0^I3^!M$6@A.,6 ] Y0/IHMRC_X=SS^YH79# 2JYYM('E2%W:1[RW:&F2]@I\"7(WFB.7%$(ZF&R)ZC TAU6]\6KUKC0[.22\CZD(H#KW/9&RR\@"?(N+*6DC80IMI^>-=F8W6S,PX$4.>X: 9J'!\9)A*,F$-TO#5YGAL<4#'C?%>L+DK-Q27")(-^A"'6"; -!TB.D"T+Z$HID( "\?=[_<95QIGS0953KNO2NCW[^IQP#B;.A5CK*C_9Z#N+HP3-T6_U0JF?Q#>7_!7MN^JJE/@,7(024^!XY[[- ?SPP:3\9Q0UEFTR 2%4W_AY6?QA!J=:K(@_:($&C8'E/81XS\]:HJQM1G#]CE9T]"J0GW.?N"=/BO:T_$6;R$,!^CHIW\\!RFRM*EG-(AXY*Y6K-G*\#0JP](Z\; 0DJ%\/E26Y%GRW;+6O4*8%7Q^'HL^/:$\B'E5V_6HEK%3IYN3+Z>[TUZ'@0BI=(T W4D8T'B,0L0(#V0&EI81MP9=:CSJ(5];.28U.,HS\Y5UM;V$526'C3_6[([%4;EXN&S3!MO3SC;5VR?/TWCJ -4VX3AB79KV'#LU:= ]':5-=)$K_1Q"AQL^1#YB+'U$O2^75^%!;2$]E%8 9[DGQIB&*+>\H(>E!O@\I=9KQ9VG$7EVD'#E^D"OWI?ZU';Z7CKM_LK?]51IE? = [)IC.NJ *-=P\!YK"TF//@Y(+(OO78$$CF$!X?;S= < YE7[37GU%>$0=94X&]MO IZ9;6D;T;KD];X=2H7#":I 3.SQ5/YSD!%9NK7+!6>D,0]&VP^\P1H,MWY=SC)2D Y\3*]BIZQ%EC%"/\_[-YUEJ,,PT$OQP,,UB-6SC?4QY$Z1]-'L4<+&#^50>(@X(Y I@6*5L+X@\5WM>G@ 1"+==8./S39]'L)FM#D=%M?.4D4-W*G#RC-H_7Y8 _3XCII S"?TC&X4=2AM5Q8']MO%?A\ UI,^1R-@%C5-I8YS9& =G5'6])CUVJV',7H-'< C ER7V9Z+3(<^9^.-@LUJ/$QC_:FZY\BF0ZC@VC4A.51M9&BQ(UE^+BJK N*B),F*A FX.URH8ZUDQZ%&=JRQ,[MG10PQX:H*=;B8=5^IBMZC9:0P >K>:/G]7,N&RFEEUD YEG3\U70/07OZ>"?3D&K]0$I2;FX&GJ*%M3"P)^ &.""O=6A- C=(/689Q#:.KPA :X(8X'DU0Q:X5(9L_YIDF"T1R#?#8YP+'O_#TY% [70M]>6[2#C9](6K3,378.2 /CX;#%9*]Q5\RA85G7Q3?;#UR\6[_L&^6T98KY"EB/96@QPQ''SXA9AJI'OGZ.1[ ^XT@6I]2=6A/RU^0.#=P$9 $I/U+]=@'K;NWCA5<1[$3%NPI@DE6KH*])CM]6 HBEZE6P6)-1_%'JJ*II<_US])&L)S_Y%D.@0B)'7"FF":SA:?JSKUP(="=!SGH-$B"9QJ>NK?*L)!#;9H:PC/3F@Y$'9WC!F$_/2:)J@;W%=>S9 TNW0O PEY8?X*;$ !E+?/ -/XE,N47U9I9P+K@N:G_/?&7GE'YJ55 [A]I75OT1L7,\'J,$,A)B.G(1M[@W'D" )HBF#?A_L4IJQ0Q&Y\82/ SY8@B,>>F9%X!GUW)3R5GH^UV$)ROJUU(N!9O6A0!J 1W_P>SE-=;A04CB8O]?L(6BF/)1Y3V, 82# 'VX*:N447U!-0M^F##O"=-7KAR2'U*FL&G&:+9OZFS8BH\7?C

"UU>H8V918[V61ZB5,J!9?[-CDQTO &@JD:558"X67KJP$ ]8=)S,Q=>&(>U_0YB [UL"NM)^< *X@X[.G1%ODZPH??(F-IR$_73M['HMO>YWR!&PN!"C>J.L@&1)'$:!I6PG\1.^>=JSG!TX M_4]&VKQIY@]PZ[$)B,Z>S.0.-(E9?;(4]KSNF^^$7W=/P(17Z#V[Z(@5O=M+DRX F@GN>"$VF%4/"O^@&EXK\:C7GFG$=,_U=9PM 9DC5:07K&U;N!2(X?UR8-:HW 'Q=A\E64[!_ C#!Z$(-T[WP9/F1RWSJ^J\X K3G:QD91,?(X,%>C%;@$R-Z,)%\VVER5SW85G>VU0BYM9HDG4]O="E!#BXH$^ 2.V 8H]>#>[\=_.$$>Z5#,MA53?<_:4 [RA-"66Z8\;ZU_GV*OT[B#A-J_5??#YS\$FH ^FS/ )0F/<,:B"U\A1I]$U^)F&@Z6WF3O(<[5NPF+J!(K!ZDTG6QMB3I*X>^; VN]Z*L( S7QJJ+=;'Q>*?KU';%]-,F%F*U:5UI_N$^B((:P%@NG)AI7897QL='$9?\IVH"PE L#EKKZD@^VFC&XNI=OXV6JN8/4&JLS>Z0/,P'B43@&<>C$,)?<7*.![E,]ANK*A. BI";/P-@9@JF-!DLNN#OHIH%YWA)NQ$R-Q##2:#LOM8E5 DS*,HZLTDJ3"F3VZ0T M%7&UHFRD[Z5(MXV5/;B"/^A0P*^8.E1+ZIL?.9#:J#3)K6R^*>Q_YU@0POT8/K0 $/?VI/5_)**50*\K&;SCF.._'4\@+D'8#:#E83!T[OQ:XTWB$!F* H-$M=GW[BUG?L&61!>C6^Z'6BWSNEZ_,?+(P)U* ;L3ECOF(..E)(.SVABR!3$4PD:L3; \1N7M/_>$*1"P%%15R^G7CMY,VNBN39]XO B9NS.Q(>ZANRU(R"_GG;F\0J-"[PYM+]XU>C*4!CFM7>Z4)M(PU" ]D:P[SHM^X;''K3/A6Z^O^AKJ29V\A(+FR@9@RX9'6[UN>?0E) MTF0+$D6)5LN3-I'G:H.94MLT]0)^RA;0#N*R175^BP0CMJ0$1!/8I.MN]=MLDMN [\NTO)S&1C(146^\#% _;0B8R, OH7X-M\$! 4C/V_OB21Q+:8(TLWL64Q]T&B\- NF@#K(S76H3K7Z%?XO+@5S,Z,$4@)AJ5P:-:\6NK)LVF?^V-,92(TP&B*K-A6,.; J\$6%?*I]=:^U%Q^6Z5:83/DC>ASA0=@"\*7[0G #5J8ZW._X(HU62]&YQ-Y&\_2EM $@I9V52X<=(MR%?OOM%N%BUB&$P-WQ5P\JNP0 E2N;D%-^$WY&)P3$,/ FX[%#94RM\RX]L6Q:()K2Y6J/-OWBEZU5RN*IYA[:<;RA ^[8F>9U%'MSC"..4EQ#_P?]PZUH>>8#.EO1X"\ R>GV/M_9)[AS]2D/^Z&*?SI6. M/GG)LSZ@:'W?R$SXM(U3_>)G^N?HJ1+E@P22^@R@.>]'L)!C&4^U;<613-T3Q944$3FV7K >_(/J2\ZH4 MS04@+K .HJ5*-!-&HQWS1LS[%T-JD7NHRX]5;U@]\5J!HI9OKX&1Y%LU?;A!.EI P'WDC#^8_JC[]-RWQ>!@NAD& ^;I>_'2JA;L3B0]:6"8O2Z71;(U(]QT=]>YJL=0 '-8-%@"&KEF>'=Y-!#SHH;J]?=E&K:%2$T$C/JF+B,_:(>TV[MT7W[16S?HK8UK\ "C4/S\O6=2+P*[>"B7/2<\EAQWB?P_?)X:F93._.S9]EE:XW=E9]Y-+5%MJCB^^B U]'[G@A*9EN%@^09'-Q2?WX'(3N*QY<9B;4*F.JIC - W#_!%:8+U'*A=YY:BZ$..O\[H[M2JOGM^]M!">:.4:\F ZA1S@U-$RR+02&:&9(!%[J HVNZB4!3PB0:N'9X97+UL2T\=\9R6N$R,1PQ?\AY^ XFFFA]K#@FC(P-JTB 0)[,%]<7+,O>NELD"9HAY2&:19?<[:6GPKCPYOV_S\0D 9 93\H8>?(PEU5 ^GZ,TA:"A^6A#?*CTE K,#*_?TNC\#'"53:WNW=V"/,RD6HQ@$C--UI%-^C?8>'$Y%BWNQ>#A/!C^X RVA) 0:$>^VB$-MB7,8+FD*@GX/D6&AFA"+&8/6'A?B9O=&(V;7J=;N80 !+F>_[$*L0 9YK&R)Y'(1(:!"F X0 K(1Q[;AQ8Y>]'V419#&)H8,13N_49>+N!46P_ZTSI(\BL#K>5/$5_TLCB.Z*6A:__7W94,>K Y&5Q8H9URY%%Z)ED-PY0-$[\K:U20OL8%3J?D6T$X"_1ZGFA:7# 6M &$V++^6=_)5GF>(07L$6$[N=\\O'/GBSS=HMV(>-HCX.FBGX/._(I^(A%?,Q(EHI FG(V89PW<[,H$ * \BM@",-"-B.W=K#!U%>N',C49^%GE!0:8C%_\#935"HMOG3N !/]N4R>HZL,>CC=7]RWM9MN.#J%:(TD'C.04H:!GCCM#25_BNVC'+@L5H" ALY@8ZTW (WDN*7'$N) W=KV2JXC^53LZ'?F5*G>EDC:J!C$LT7SCHZ3^;,LBO)RA1H][KLG92L__ YR?SAMOS@QDC.5Q9XP'%=S'$H90YA?^:6>&[_DHRC4?/Q]$4NECGFO[+:TA]K)A1 S8%4\O%B%NFC0^M/W/XKT,!7EU&"!?SAKY>7O9/Y5/Y#HK^!HGD0L $$7TWIWW4(/=I ?=W;;(MJW*MM&0Z>8DPSCEC]BE@9$N"32$,5&T5$)3]6#3R/'[ K2PC+/FBRHU;%?NJ/[V4%EZHQ%PK#@X'+'""%@ZB@20GU:1SH NPK94R*60+"22" ,NLR/.4,?!+,C[QU_W0FS^GHYTVJV$+#-A\'?J!/4#ITE"F\Q, &;V-^;)2M%]])=9OEP8:7SLTC'J1KZQ< 22FPA1TK35DG_61=H]AC;T<9.MCV$I=J]6Y)YB^Z@FF?N4Q<2?;_?"7 QR5)YD88 *;F!>74^)O%_Z.B_0)B$SMU4=-TNN>N56(>_9JLYV!N:1TDX;G_.*T42I*B3SH:2 .6Q_Y,AM;+]]GIQTD$:KO#.65SDX-G@E/30PM198$[HMS@VM?GF\Y^H*AMPV8OS[JI0/:W[S>C_#9PIU/WGG-Q !YQ!^4_G*ZN"B8.OPECW HX>(-6HCX:A 8M\WI>3?FL;)P&-+-0P@#/Y&CX-U4Y H3?]7-[JG;OH"LV&JQ2E/)\!O5)S^C=QSTGW8_W?:B+'F+JR>GZK_Y<%8H'FI_9/ 95?[,2'L%?-C/?U:"*T(09BC'GH;P9T#5DA\+CQ!G\B4Y;W@!T:W:X1D^RW%:V Y 2 ]^X"[R=QHANL586 YX0"5'(O*F^/+%40/]K<-!V1HI;5?8]:&ZK/)'G2N9Q__N LRL7G,O$BK_Q1<=!;0NUH$6@+O#UF_QR!BOY.$13'O3(=IEI:*= A]*4HQVBJ &AT!_:V+M@8]NX'>%G"-47GCY&, B4AAW45C9Z3Y+P4D39,6S[WU,*2DUPY9Y[^NA*%@0^XM:88P_NW88 KK0;VKSVPCI2G]B:4^"6I3@"N- R11'6.\F)^(\)Z;4_>5,[%].BZKQ_]STB ;1TSAHZ3]BXTKK!:+D=RA+RC#Q;=4" 'R8-#1Z2/2'K2+S)FPDYI\L))&WBXJDP#*"<'H\(@ @=SLE]?GD)"ULG7Z^MXVK,0(5@$_[>^!V8-D0:=!@;:?(@#&9GTG#%X9O,L(&D'V -(AYJ2I"C4I_5E2!'^SES=CFF$&KE/>=Y72WHQZUHA!O@39(Y_Q7("LK6N.RB:A= -!A)[0S($WA)J6@#G8A3&/R9UKN6AK9TCU5=-;NQ$3C$@\QVO0"VKTUSC_C/Q DI]'H;)-UHU^Z$[1S'TGO99PI8-'C+HQE:R6):H+TQHD'-)#BW.:6H-#/1#X!\[H I.3@( "URV.MBA+/UI$F\9PGMZ9 88'FHL><=L+H'3NR_K1M2($V93?HE_CA5?L^[KVTCC5% CINM8/#_>K3*)CG,>/B?+[I>I0J$I1BMM6I'#%*Y BFA@2@="8/*L]8/P=%@_A5 LL3&./ED0NZ7#M4G#MC 35D"\92*DYZ@.1=L& BO+=!,GHG$O)Z.!GX=3H'/FBY; O VWJM1-4]H\@,"^$@W )PBJ&J<,59Q[!BE^O!5QB:WDW,8";2E=+G MY?=GT8=U]:5D#^D?"G X/@6O=XWM TVI)$N7;E^DVD(B*6S[ Q'O9CC7LC6FKUC;+89CW6<]HSM=)%6V\X8YP_7*/C2!8 \HMDM<9TM5C?GU"'+XTGF:-M"E8D$ P)/ZOOG2,WAG[]S9-#+ZZ2WY*>K!M7=K@= SX^7':U,21P$W- E>54*1Z;->TE4+@F*&4MUN0^U M_[R41.P7K;9KK 3 )/6WUB .-@FPHVUB'^WWY81Q+*7QER^[_3^]<5P;T\4'P*Q4K$K!&^\/:+TA2'!2@AKU%E$ &X= 4:4/B%[2PVCK8 0CW#?*%K,E7_U5T1TR$GRY(;R'+'N8_.>$5,WASCX7I&D' XHQ"DT0%"6O6OA9U=XLW'Y($5"H#4.80J3[07WXM>OB[(3Y3<->I>@YM,$ZBL*7R ^^"Q8/ _ICX32 ^N,'G#M*GR4XM# F!JU80<'UC-4P?'Q,@N"1A_L &T?NPKA.I( !-<\>>G 6@4T12"'&+]6ME$6MOP=I9;P8SGRF;BO-3M$ %;I<68Q\9!9;K$^':VR @!U?H-D*E8.Y8Y*;P9R*UC*_E>B&>"_U^Q^*B$X$_>PF@I3&L\T;$@??_ @>YL3N9'P]#8?<"L6I":$3\[&^!1QCS:;= 2U@L8/,98ATDD\VB4DWAZ;K=]OFW0 /QZ5-R@*07_<]"EE_R5L+%#+_YK6&,)X"S7OVCP.) 0T;KBY5( J?V#%WKW&"=0" )Y+$4\PY\; ?T5ACN!T>'\^^G@V>=X 4Z-8-TR8AW;%M8FBB_+=PN8+R #M!^H92^H!=>OVW<2_Q<;/UV\A"[9_%H7QS*ILM'.&IN6N,TM5,M)'9>PU%G\9FK JN'N;V_+U3C)/190]A 72PGPV?$UMC;(JB@B!L+V@R$^-GHE3)/[[O$:BWNG/7-I ^(O3FJF5I&V5DBRM]K]J:+W4K\'A<#_N?F0-BM?2U$R-$XM1LGQP+#M?\E'K9Z)? ?C(N#6IB33BN#^3#81+^\^VCNZ2[%@9A(K>(]S!A"+C/F_W.E:DR-R\J!>T &,R1D9!SIK&0==#R6=):E9BQFRL#JEU*9!:E;]^&5?W70@W$A >=N*4P28E8I3:P ^:Z/+4]$NV#6#25'6&-[; 3(8X=O#KB*+8M9S51F/&40S@O8W#/>)Z8S2HV 4#0:U#ZL=B,_*)J(R$K72'U;@%2NG,$T9F._V@Q51BV=Z%QVGE'-LS.>;,^?]"OV E@01CAAEVXG@S*:@C9XS@8&N]H,?'+0MCK*)A<(Y3AB[MIP N!#9^+]FP _S#\),PY.8*&2,ZI-1.K2MX1[MUYKH]_0P^6?,8G,<@ (G9 --IK ] )XBJ[W:P,C.>X-*^<'P9$>N#]8^(YNX,^3* DA*8A.($^1Y"BSI6[IIR#:)3DQ '"XW/OW,4_-M#*VI(#=-M3E&/C#N,D9IR9!D55,2_9YMUTNFYX&XT7ZZ*?WERPCO7(&]:1,*%ZO,=$"8>>5=M7)&)[1^OQ=E-=O9?%,_Z#B8^@%AC& B):27ON$!UPA66\-FYEJ;;+T7J"6!VCE!H9IA"5B=OGI NSD/.=75TB+F%L56B<+ E#:VAFJ@:H.,U)P8/V0BM,JEB0O)([/?V2*JIW*$ZP,A;5> GA89G=\?;(&J!T'. P5 8D8]C29RP+C=LYY)B$WWD,@TQ]]8#9'PBN=O/$:8L>P[4P+GM+U-*IZHC;^2M2R2DK%CCQJ4J7S\AK@]X+:U1(P3 X=UPEK_*,B0?CAF+Z$4R$ALI(LD,_G/[M[[#H?E;'RE*E3(P-'6T_249J(W )@58=7H]AT&V3I(A[*YEL4F8\(7""Y$_5;'FG:4>NX _&1O="]!DM%C!?]!P1FTH[[T%@+M+B'RE#@M:&@L>H%HV3F(&92:\C\]0O;F$.WN 9!V[!%8MZ2WA#U"?+RRI*7[3QO>Y6 QS(: 7#U^U"+OQ:8-W:..XN'B,2B%9X:%) WHBN- /?5?3)J?Z)"<;FU^7]EG-9K-'+L("+:NC7X\[UL76DG6A)O+P1_5/IW[5& 88_'?T(K4:02DM>O6X4?B?C'6P3(WFL/BVD%O6G!RURLC)X_"\3"[Q"30<7'_GN: 3TORSR#)TX^ Q&9^+=9=F?FP1-D"13P)8_OQ1;R3_^YO_RYZ,,9HI;'T5#5[PIN_ VTX?'TQ'U\)0O9-24##=:IY5B=28,FPJ8IRD\2'V:,*'S'A/ND_ #"QS!D)XJDX0 <$$^QRF/3$-I9UE)]][P4[O7#/"=R!\!$CG@(J< K/*T$E[SR<>(8,9BC5;W.=3! =JU;=;WO.S^IW!TIX=81(]/P@L2K<6:&4P$C4H=M!(OFLI64S&)QLH'=;/7@?/5B \^;.\0?K-=$RF5RN%__/#A+\987)F.?*DKH/'J\58!^)2%3G3LTX,ZQK=Y/_8%$X Y%!R]Q AC!7C&I"IH4+LZH27+^6K.L8#L#CG2&UW>3XN;UR4L(YDF73*RCN+ITY^ ONXT00=D(W%"4R/T%!+/-ZX&E"(*[=9@(ALF(:)VPE()MY'RW!-GSO, #UJM(LAX?#X\J/PA!*V__Z#^D2Z9"Q17[\8Q!T0B$Z@E3MZA04J)\56E1 6+K1(> #[^ET1?X]5XQ^/[R.,V),MX6Z-F6*_(S29@>FY@"B-?^F/Y@FI/8 73;6]2)L#E0 VLJ^KFDW&!*%#G3;F3IMMI=*A2_36&=+O,@N;B-KBXOC6\K?^=YD&728$G&OP5#S !B$(;6S,1ZA,CG\\@5:L&/V@1^$\C$C<;-;R"/?N![C(4\A09GW;RH,1DMJ]T//B F<>X+BKW;ZV.+:W.NV)[/86T4_XC<+8JP=$:Y[CDKXDL_LEUZNJ9,N;(RP=,^R;0 &-10L4-94/U(G8FTIX.,^.YHYJFWD[KP[;F 78 B" XX67#(+JW:_(K1KA+AO#%J4>K"=Z(*#'AV(R$/[DPX_.]+RQ%O6I \!\2?U \F?=+BL#U=]L:"RE^RVO+.8W9W=6W&(/0';FS.FH]K'<8=%_0+S*R^83O ^<_6\.!H =!]E4O2W8KLRGX5DE$H[GC]*H)D9;0]NZ(@)M"?/\6+ZH_N$C:MGY $ 5RWCU.A TA2MQW8=92QUD&60ON4X:^!-P%8G$(-JJ;?H<3Y&C*KWZ&[ONTN!)EDF G.9U/,B2N[_?O,1BLJ]5,OQ]+\(YE? /J^TLB<)2 ]8:?D,O;2)QGA%UZK":\A-^ $""RY7>;D/6$2(I8QQJ? >I3GQMV6!:I2]^RJ@E_STP1)P41);7PQ_:Z]CQ%%>[K % O3.]!/XG0=4*6!T)Q4LN7 Y>[RI4? SLR'Y.=<<,HP2A(']V0.8&,2LGLYN*P8 ]);XDM$L4=,E>MCA<'2A[A!Q%^+,$0Y(3#U8>.!_,#"(WDV.VF^_A67%6UBE0P2S"&SUY%,KP@=F[MNR?ZT0 Z.WFZ$_0.QC[;+05.?:-+!2+<^CN:0 91>>PB[B.%US%Z;OB9X+Y^UZCKBK^FNMDQUPSZ,EFWPY3.ZV$WY )X5B^"@9Q__# +SOU2'CD>6+K6$KYN9\L(P7P]!]FY3R9B)>QUO7-]\9F$\B'>6LB<^*BI'>&HX&V R,NIGQ='0QO99OCYOE$%P5"*F*UGZ2W@R^L>+,0#8(5@92W4NES^)IPT$VM9D/G1 $P[/@FHC_^F!RO(,XH?J9^^U(^1W9CJK^IK-SU^#<*5+VDXP> T:3(>?@PJ\)K<0EQX25I-6@BN%=)C^V"Q<(6NQH*>AQ!N,S5] OQ#_EAP;]B)R2H0FG<64."7J6,"E2B6/\RUUL?)8_'#R$VDMG"4ZI^::MCI<<,P< ;.7-I;S9+K36V3QHHQ>_-/ +$5$34+OR44E%=)$O[]$X1*;_FY#XR=N',5GY!OMRI[047"$=9R.QX,?+FOA1#@OI3PD9H_-();AH+0L(-E.=<6B V&ARCYGT90G+%_#SG(Y]DGQ0&E>VM15+M^3/B /6AL135))FR ^O$!@.4PS:4DS^ 33F'./4Y'[U=O)/BFBQV/U&18B'M[T50SPUG"GACU!>D&<2/AZR:.Z?6#Y^U+$3> >TFZ-%'89*C4DYL?KDJ;\FN.WG'Z=^LYW@057/K8Z C ,+_IJ'FN5_V]_##KVH>(\Y<"2$3,(&52F]BGP7L:GZ<.B@9K6)?I0@1P_=A:K4 JYQH1!ST1-X+GWH>#S\6$,0EPA%L6PSWHD,7;I60D7@$ FX15D Q4CS-W%:M;*A] F2Y)[O8*RF)A47;Y.\:.QNPQ\+-;X:W[=:7A@#ZX[,VVC"3FFUZ'10IX]02.<)\2 85PH0K5)[&S;0\QE![0B'9F&I(2;DV8I,DKM'#3#%ME_E[RS!"WY#]VS;Q>2<(@ E@L$E7"3N&2A;LHMXZA1VP:R9.B"M5(X% -ELZ?6K^,E#F,9<1HMNV^2SO;K I"Y N04U I[ E,Y53ZH0\9OAA2_TX_=PM]0HDM%-K13RT"UGJ0BWPO"^@F:5B1S_]4;T M '=2I,OBE>'US/ZCJ093XI^I_7_WKU;@S$HYOE=@0+_2U<$B4.G6RT97:@M$@@G ^!YO-N+0AQOB"(Y]GFYG]7]H;^GN:@')LYRV04KD6BC=TP\H3NOZAT3;Z@LZ3< 9ZJVD($=++0GK+WS>-$,>%\*PY 56$C/OH^_&X VZ-5X&!>\)FK$!7O_R9 %$9<]0#1L3HU>HP+NU7:R)B&H&1Z?GB& WWQ]%J^VA_UL)ON]=F'9X=_P\ELS"2,$IVQ,!\ J81LBC"1C1[J-(Y(Q7GBL5F=N XB>@"OV?M)^3A^X?=JB6#6#?=7PS B^%M87+_)%E"&83XC=6@2P_*UJ>E+$1LWRV42.U1-C?"+[*"HI0F$0U.#OMU'-/Q @QVY\%A;,*QC[&"E11S\ZB?8JDW?-\^_!3QU5B4XY4)-V%*S[*$IG2I*88-2;\@YD-9)22V046P=]RH,<_W[=Y/?EOK"\WVY)VMJ-F,HNWL>-;3@X'9W(]3^1_2X'?H4I^T8]&^)CD'!\QN) &\3X9O@0+<5VQ%EO R*71,AVM7OIW/241PVGV([EE X6F('PZ_K! !+'$JU8YN/X Q0U'DZ6]4-)?'M&GLK)%H?GO=R2"(;$$[K^5-O_<%1_#^7JQ]B&/@GD)AAQVAP8# O?S@$YM7@X _O!4[L>C4 DL.=&&EY( ,]L?ZXPNR ["PVK[.FS#%06!5W11[F[6 "C15Y7-=!I[ V3%9/;@'[V)@")/G1TS+NI%;27>2=7 T4[+Y&!,X"[=)\R8*"Z[>?', ["N6-[UHAN8P2.(KK*=9EJVV&SR!>0G&YL7#EX6 --IE*2J\EP]'B':DB@8_$H3<*\G6!II'O['6HZ%;H%(4:-D3MX98ERG%CT0\Q\[1 ,(X,0EB!#\R:<+2#;B5D6:IHM2X4 M8VM5VC>%W/9S B_B52FT!- :?KE3XKNLJ5 XGP)4+[5I4[6Z4 \PI 4.OUZ=Z7^].I^6*437;F<;O[V5)(Y.3>S-U:ZG;\/=X3+]QVL(*,LD5@=P($+YZZ *$R$ ?@4+%T78>$9W@85V\J,;*+L[BG09*FIDRP%N?.:H +?-Q+.L)8C@<^[$ZXK @'P\ ([*C6$')GDO0'.^)__A%P,PL.W5&9/.P-=)A7$D9_6I%=$DEID_G;-66W6Y ,@?_E>2'$+U2#12>9>/% A5;W4NBB=+1#C9CH7W;2+*!R@=1(_![^';:XFZ":X"1 QT">XY0RIF46"$(> ,)(AS:-8(!0;TMXG(T6ER.".=)!GHA;FF \17:S.LNIP"MY ,"RJ^'YA#KHHIIH'&#Q+2K^I+KEWM][U,KR9Q+*2CQ=B4[Z%QK X[-)71\?7P/I<97MWTEC+..C6X$ICPZ2V$V#MST!_09,LK7F$<1&(#H@+H57EDY4 %-54 L2637] XF4D[T71E_W']C:1-0%^ 7J-E&-RTZ2*]0"%0;FW/F"KS3"3WG7& 9BMC'Z&'W$;8-1&SD!(Q90Y&9,D5"97[BH.3% <.CQP[+,)BTQ.QZ#]CR( 5$)ZW7"&C@3*$TGX^H0S /^[']8QQ>*GR.O=LFH7[>> 84A+0O1OQZ<4+'U\)UD^W!J3BC"9 76MP'UH\UFJ*E,TVGK'C!A_< .&)>GX6%+1C_V#9IZR._($I'I4*64%3I\:%?E,T OMI#!D20:TI+AVV=J+X_:3V4CK>')4.V1Y5:9J("+W0W=_( .WE^M:Y,[L=DTB%E %0_^ L#%C&W A1WV0KZA;D*P(D=7ATD0>AZB44I@IR+GM60;2>!.*SG)M@"',R(W <_+#:Z\YNDT>D_?:("$]#//\LT2:JN8,)TW(#ZGCW%L9RWTI>X2)MN@3U'W,42IF ^H_24A@+N(%:4C&J?)>24*?3GT\E/ ,=T*<93U4X"5YRK@UHT_1N$J?-'1^W"Y=[ KX&Q/!#-/.^)4Y$QAUZA#2VO<4WJ::_*BBH_(@TI5#=-RY^U0?-4."E3RMY4\NP4 "6/.#;4%$??/I%=&R0-W]W= -6/\$(R&NNS:P=&;"RLI6*U1C8K8LW.B\"XAFKF] R%6$MUQ$)NS:_J].R M0W?&)\-_W1ZY;?JLCN"%,=NU0*J8];5.@FN $ '.&B22B9]TUP R]"Y(>'1&UATX^&>VN3IH7G]@I1A647KS4S(]',- _EK%\SOP:= !::$:K&L_Y#9[2B8YS2V0ED_X@M,-X)". ]<6X!,8]/C"_<&P6\EK9#<6,^*7AZ( S\#0Q25-N 3NR/K-0QN3GN@NX,NA+>68OPN\>NAD+?1)V1X-@\C;WXD)'HC]_$J, -L_*IQV?Y$ C5OLF#,RO8I@\)9X=4!]4ZJM+7*=/J1642N*TOX+WH@N#3G..TWCM A?EZ>W5#P,9C>2V7*%307?TFG4#3@[)G/Z9NO#(]5]@6N,V(,]-;2_:+!EO>K3N' $C^1$7WZR\#7<27Z)505]I_X<9QEQ5MQ68].%F:KI4D% &J62 ML00W$B:'\0[8, BYO$!QY$4NZ!V9,V;0/=)=&&"3T .3MK.ITXEA:.?9#)@"(8X*OBP0]1OQ)'WS)R;T 6,MF>DY+.PI8<6_QT'3"6TM&A ZZWX]%,#@:39^;.BC >G*%.EY:S?R2&T7 ZWC#=+\<7__#Q MN&)M3UU'T-&@U,2->BJ3S.:[C4*RA1D]9%DL= 5,43%4C&HG:S0+$IIN*:XI"FT .!XQ-GR(/L771;4MDE]96.+O% 7FY(^ V"&1N0!S1;3=IH6ZMEF/HB4B!YZ*AA#R.C" 1%U8BY?U8\/."8UIC:0'3+ 2&.@=1G6SPL.8:&7J5ET%R@ZPW4T"MDMY ;.H^5'N;C\N"D='QMW:ULN57;$[F$G RDNC@ C+^-9CMLM<$.'H 5 MU4&AY?@:!.@DU)O>UPFJTQH&/F-XU4/?]0AEZW ]LY>V<+.G,96VX#%"$E5V%B- 4U=\>L$*G-8\XV#T6&%CD4.UB;-;RGZ%##G"9XUA9EGF! ,L-P?%3ODZ;:W+#=>+ \?]XP93&NO5=S%WHXND_\!6$>>"_^_\ZX?/1."W)> >R=PK<3)""'Y'-%N=I) @ 5C$93255,&KM-'?;7(!JV.0?=]"RWUC7FK\=Q,5<<.8[6OY- ':RZ.5H=3,#%YD6W!2RGRS[\LC2 *")3.$1_R=$8"1QDV'&P>9?Y$19]YV.43HS< T6HWQ5RDZ"N+J7C./GAEGCWN"M5DK;G2 "^DV>HERM>+RF=M:*.\'5 V ;W3U[F JFC!(8JJ I"4777KG\<+G<-PIYA%#?II"8D=BKXP7E@T"?<&+OT1,7G76!.Q8TZ"XT6!?'TOE 6,B;/\:->"0O;*@!48A6] &>7-N+YK>ANXJE4W\;#0DL!:8W,6+PM2D_?;"$9-U+0E%,>*M+W:[I7A$P2$=-YTE'Y<4*TA-?P'A0NI!EOO]K >0;1C9DF4*XFE0?,L&C3L/*S/^NPBABA=4UZ4^%C_1L#PIWM0N6+K0_?QCXDWM1DJ?Q7*/00K'(NL/_M4-W'6K;[0!_$4 1F5>..VT),&B=(U0^\3R=OWR[RMV4'8A DQ#)68P*BZ<]O@QCI4R'3D)!X^J55(9 5 74.9@HBKFFLV/]U!1Q'+T\<5A8\P+FJ;G"'+A8[/ @&UHW]CS#G7[B6+_M^7T> "$F:,J()POJ3<:!#?M6#A"XQTIQL39;9+R[1W+]"-,5?,9<>1>*$M C)R=3YCAAB VW91S[HUF#KY=@V3!^T%E::'F.U0$T@.+6M%_$/0Y=8Z;/>V?RS): RGZ\+!2>-Z Z$F )9-,8Y-M>'49D@ EJA>=4>EV^F]&/U/4&,[V4 IY.%3C5!T(_6?9=IF>]ERT6RIK8LS;YPW[)WHSI@: 7&9FS17V-."FY!#-CNQ?(:KG^.&>LRXX$D.L[.P^/"(WKM$KQI'6@UF(@\\]48YK(9S+-F_D/19 N)*5K7:<3"DC+X8^B;4Z+@7_#XG)\Q U=#.##,!Y^IE9+5MC:,G)V(A)@S&M2:.65R4$:$(]Y=X#82*!,L,<)L<>U9D/+9X ES3,-D%C9^3%0!_S(,UXX9.9@T;(>4 @CT"&9WL.FH14ZET'^5QQ J\=P^/M UE\<..?Q:+E=%=,A\S&=RWNCY4](62W&WS2=$R:?TO*/R '(X/B9EG_)LJ_MJX;C552<+"QN/9&SV91:F/X@]!;(\29J"1 L<]&I-%!:/%&EF"PM?7FPAQE[\>LAF@=$K'8 ",>DC,1J\+=1VRV\14O9Y5(#_Y> IM-KY)0&[U6W7##N7"!O7$F9L* MJUG1YC?O6>")B9S8H#@2$$%=E&%%6$4.)5Z6 PE<_RI")-[#M@@.JZ_LRE$IE0C^:-I-. D$$TUP>IT^I[/Q75..J.5Z(,T=5Y5J WMJSF2E+F:RS& L_WL4Q<=[6^6^">*S[]-/[VR](9HE9MX&G=).S?:G/BID.K+6 G\@DJID!*I(/"V7X>&_L33ZJ:Q5!PFG%6 8H>>"E*C;ZE>SB'UU*\RX^:;BH'5#: ;!"L9JC>FI^2KPM5HQ7;.K9:_+/&M+?4QQJ^2R_XKHPX9;7O.()\OCGXL(R96\@= -\,/L=3V3UZ+1_WJI-[?DMR-F6T]4!%"T0M0-LVZLO!0T^B=W(!^*VCK7+HIYO)3 !>O,&CY@V9,!7+0H0&+%*[B)RL,[7&6T$B^NEEMV:B=)N=VU)ZU69?]EIY/I5<"3 MU1&E&=/Q\CAEK]C!>!&?Y^*O2U%D%:,)FY).@Y]*^=BA5<5BLL548&Y$I[/N/ T .?)[9+CV,B]-RS+YWIK8=I=8;1T/GV\W ^A.\>\34F'?N=RA.T)".S@AO#Z="Q; C+1I=TFU$Z5LD('2?5HNKI9]P ](F._.V4HC.Z \WH2PE.L+E"S^'861/ +?V#7U;]TM?V+EH/2M*3\STL*ZJ$#=J0]F^QI5^>+5;MFM+GO=*_,VLZ7KJ+!\24 5!E&RIU6X=CDRQV@WSZ&^T-+R?Z#O=?(CX"(=O8QEA$];2_U/C8Q^@+PYH">5):8 .CI)8CX3WDGM:)S2<2NK];+9]Q4Q]D91>;.D?;JXZM .8@+:_ 2Z !\DJ]U)>#+R'J2R"V;+.,WZ ]FSGEYT?W+-D2,Y9VKY5WAF$SSRMWL< B>@3NUM, T=,Q>K;I:Y'[IUZ5"42LM?N_F[W<;_&7C0O$1*: -$C37;*6+P413.6X2[9Y'-^M \5!^T;[)N<2^A(D=V7.^R5+)0\XY$MQ? U]X[N]>>2(POI_M_/1QB4Q*PWY$>;X_ .9%)]C]05A?=,R9:B";C!!T:VIU!8\]<2%%M6":RW-D)]Z1,0RW'C/P2BCZ->T_H A0)6,6?,PMN.$FXY(A^JGK] =70 N#OLRU[9+H@Y%:6U>.@V$+=T'2]IPF#AF/BA 5Z&KF_>*G(V<&/AKEM8>_]#C9#QD5!O:HU@4H'_O9^Y$E[RU)O+V%V'14T .X(GU(5^-/ @7Q%F\*H:+*':KZ41"X-7)N1%;3]N_QO =-C^Q4-_WP#@2H_40<98S+GZ[\VD]3$,"LHE7@+^*14RX@_>LR#6@BA^;,2^4_Z7Q A 1,, >F06\$BM(*'^#83]M"_\S,Z;7R7M"!;OQ[_'O[%.76,ET9O]73Z Z,D!)+NX D7#GZ=J9XHA3@.WCQ$X#K#4"TGXB'5WHZ&^J-K*@V.X:\P&,B58'A8B%ENW8B5./ 4+VR^83G!$N3I)I,CHV84NVZ?>J$L#_ZU ,WQ5IS_G1VAW=U5D-60:0X\!RO7=&I /<:9?!R547C)!1J/RJ:0X>BZ/8WF^[AI)P%!!9XW$$$N-XT6YX<[=ABM+V%UG[VW M# ?Y,OQ1P#%+M(PR$ZY$-!TQRO\+"]NMZ7>6PJ3;&"JK40%DCL&!_LIF06.8'M0 F;;FMSDSU*\)D8'V.8 8_WBB@.N+1[8,S*RN)CT-]$YQ*HDE<43KD%VYY@B/2RP0 Z&;S6)#09I^5P:8)E'(#,-:#>SG,Y4DJ:4LH@&B^]3^>9A+. 6'B.L%8/'_0P)A8 >ML\_4O7IF4 ?I1%09=S3%K(Q5RTGM"<#L%)QG]/5^A8!?/.E_E%O^B=:>* >IS@ R%A,/&H4B.P.2Q:S/S&=Q@:;)FO@S6?3GFNM0#X'%#Y[:89FGX.[B2#!A;(5RJ]SZ"!6N(7DDP) 1!O^ R)K)9V%=]U$0[@63!+$ZU;XAJKX<([="WY'J41'D Z!QT*_C<^[VE;-PORN >(+MU,3A E+GM\L?XEN'\I-MZ#>!3;4>;LEL_'S6B)9!=[::WLY\42&,TI'5 _Y0 BA!&>G+:C-BUUON,^UI4CSET#W6::+K*>5(Q=]M%$*3=Y&BWR LL=0KO=2GY+;Q_D**!UZ&@X*S%SP;=2]A[FQ7!8E'/\3 )_71EQ>-K C/*4=2&;KL]NDPW>^+'J+!:OV9DL\Z$9)2#RB,XZ%4#D]/:.:N\9+$^7PQP\;$:( H>UQ!-[XVJK$D)C[>B99ZRXY;H3@TL/^ M&K':2J>I%GZ "#/5")MFN*MHT [-N9 [>;+(\(L=3.Z:+Q37,RO(V5>'H8RZT?!B%:83-'KTUA"/AB&-*=CGXQ*038DA9YZ:=-5AH$:Y?(\T<(3!@U66U8GD0%3>Z;'MY&EQ5UFPE+=OJ :9P_P%$*WB70>@KA01>4=XT7"<-U:TAR$GWVBD+[=%5^0>T8W+.Q'X &NFR:EJQ[<8OL9L)>L5Y!G0D 5&#!I"P)SA*!,LSS/*93#9\_(CX_>Y8&ZBRY@ _)_2@*R16RRAP%8N"]-:>K/A$S 'AS"+NODUBP#_V^ >7/VL)Z*IL'YB'\- X.? 8/&?TV"7.:/-:HR65^G8H(=(6P= 7%DJ)#_^C+O^=&>U'1>C%;FI4OY;H?6&V<)9A43FZC43LGD/%0C0;?PA%B-XT2ZF 3>IZV]T=\6D%!;93GNIO 9<*0")+1?$%V-"2_IPN'A3MD/HTQ!7=%E5HT!7L$T # *S;X$0/1M]RT.!1*K3;>%8C$#\\MYX6Q2S6C]]G^.F9-X;/W" )2V6L1)9Z VTLIVS;CC_W&2)B2R5?K$9]!?-A>I=HT%@0JLP/=,54/0&YCKSSO&>TF]4_,7Y"V '/3*FX^W7.M@RZ(=:38QN$ALJA[^.$V PB;;2<4-1 AK$PR-A-#8-I-*NY&W)9] @='17]FLM*$$K3N$4S:?+17L1*$HF=)STMQAUE&ZVM EC.9N2ZZ0#BBL:'IWCF#= A:&?!3_,;N?C2M"HI"C(<>JNBCK-V\>&_&?EX#XIK:HS^BO[#TJ@"Y44)^PHO!GL 1I_FCZ&=M"NG; 3KW'-\.N(-C2P:IP"^,W.6I)@U.^"]LW"F0.3RA+W1TN ?=/&E 3)ZL-R14F82D.3'3?#;HR,A;='YCPS(;?<'.;3.0B*Q: B@?LZ.#] NYXG7>_OY\ ?/X/D-)-E7]5%QP 49]\6/0*/?3:>J09\!!]@SL1?^KMH.,Y5LR0/+AH_W496#JH \'H@\1&UBDAKB0OKT$E1DZ'4^#C0Y75Q@X+0&"()>76E38/.SN<>T:;6S;4L8:QK NJ&CHO;FD5KNSZ^#:+"G;W#VIAIF.5K[5_^< [@RMFG>.JQQ?ZHXPU'1&.S#!3M8 IEEN8C&YP\W0+HOI)(I (<6F[5,>%<&]N#NN;#)18B%=';4G5B+9?^ -=H'G$Z&T/8/O__8X"QXWUGVD96\^T/:!CM$J_WX##IM:!EQ VJP'JLF?G6<\0( ]1N!@!(;.E?=F@@D8XG7@X+$1MZ@+_?PM^ZGU!VT1(ZM_:-X9)LF\%EZ#5D4?Q^X >;=E+B[2:_RF#5>8K(^P8 SJBDGQ03E5VC A-/F"LD^DIIC!QM-:[(WO9+R&90VM ;NUG:E6LQ?H%ZI]I5H^U]OC:Q;[:3G3Q5-U$VH<5H609K2FT-NOL!BJTK-F%(->_ 2_0)M2DCW_VR/)^ :"]\](* >M\T0R_+D!"1:4#57R1M7KTJCX;J#RQ\OP 4-6AQ 56C;JA4%0HHLR^%4?.,7$J9#2JE_/5'9?3X:*_*+\9%+91.^'#LO0K,H":5B*DTA YQ0L7O<;W5(/,K7:L+,"1V1_K(VQ"N+N[:6/$=VXZA:'3!-,R2_@ZL\Z^=B_G, / P6B^!6;!<+\]>1G:+N'@PN@99_U4HO8FH=7.P,C7;I%Y'(.$N(DKHV8MUA =5B2Q K>4R*GZ(JFRW%ATU'HDL9IE?QFKL$V:5N#Q-HWB&"'W\*B)(6\,S$1+VNM.\"XS[ T#+^N.4G&">7.AFE*SWL>JL?BN@)O%+O\ ]M+I#W>?OY_OA61'+L[_I*+MZ7WT &,B4L(\Z(D\-(=F1V&06P_:/5=/@"VS/JN@?K'N: W P=9!G!AC^"L6V'BA_P"$43I,PQR_94H7R50S)/=';GPB= "8?/OY7JE[K9YE%MZ5E=HUO8Y\,"-*T[>&5;=!PK[2GW]S4&>U!"0@ZA]8NB17E4_D='_YWXI]%"@2R%#!\RH4 0U=YQ]=;./Q8#,JD EY@7*E\OG.7AA 4A0,!YP[94I4M^2"^F(!912.(1(V;IOET1 8C9N&68R_?/F[MC0Q -WB%-&>YSFK \>W?NB<*;[2VY_SSM #7O%."9*9#Y;]M^7NQ[0V_SAQ.C4:YZW@/.,4$U:)$3HH.!$/M,RG5^W^ VL3"%1^*O *NFY ?6>#99B_H1QJJ7([GAV/G>:-<'4#\Q-B+F7<4 _^P-%4LS7T: #B[&G>K^!XIEVDF+8236_*?V'CGQ9;YWC45Q5:K2.;RI?P@GX@VH<:"?B,$<1]@2 >G"C\2 'IU5B_D%Z+U0]^9^!XVAJ'W5^)3I":0'1:L=%47)$'Y\6RU%L6YPQ1$G' 2D1BB'@S%SLCW"!R(7,'NUA)RC5&9&AQ_UD]"GN,,3X.'SA'!X9CKR2%6PG WF7D%<8V:;)+J6YVD[(*W?EW%NDUA?V(V3;[UVW?!>W)_93O(BC+PZ@8!ZG+&L$Y 6@=4G;/:S]#U-)/D1\8?EIW[IZ^$A@V8-@[Y8?4EPY=P^7=GYB2%ZS?+31:M G66 AMR6A@;7S8U#U%PTJ-5=I49\/.+]6@D_63@\@3O)H"H0ZB!S\XBG"BF-94)Z&EV@_ Y*;>GEY)PN6]2"^'!"E##XD8DV%(*&]LI;>SF/EY B!#E/IYU1QS%#$S;J )O@1G@9!SC4]+#Q -M1U$#!.=APNS,P\L+!TZY;EC -_ FV+O@>XT'Q7\Q0CA>OR'L.3*S0) NG:8 [: =KJU-E>^S&@P"- ;B:'R0V-0V0)&%DB+'*>?C&>/F.R7&Q"LIDXX-L0F,G"%YD=+-EV.YA6V'+\47UYAX.K"W!CV65 683+@OJN9H;OUE "5:370E&D_BA:IXW;<9I%+^Q\P^E/">M\*.U((6%VA"8P%,<7OUH\8I1'$Q"E&>V *-C'R#MB&!==#<8%>0*7K:!KGNU=);J?*WJ4SM+5P[E<&4JI&HU34[K #X3>FI5 ,38Z@D>G !/U=92EH)8G&E;6G*$-V0SB$C]MK9I)?0I0Q@.6:N63;]D(@0VTZ+6Y,47PX]/&O ?M%B\7)>0X00?)G=]7294ZL0]V1I2VZS=WD"[)&"L8KYZ5LU=:4;G$,[A/0I^TG/ Q-@:$!G^4.S, Y".$65\S=HY2Y$X/+H]A:")'L@MI@T:>T6M.+XK=:9#^QWJ;:B KY@-G=:1WN+3O$H@]L,MK8O-8;Y6H_JM@$H7/*L/_N'*0DS816+ 92*%;WIATYVM \CE9NV&%"35N&*)$1G;>^:4D_(#B' X#W[G;=)$:XOW$1]\(+L":VQ)=L#^TNU;L Q-XY4%IMVCY/];9RX*@UC-]V:)=4KC!TB.&E;NM!:5NASR5>BRJX84Y)JF2YO7LA )>7(#58;^J@NH1$4G0VH$LJA9DJ89"G0[@Q8-[NN! [/%O*8V"-5K/3SUZ!0W8F= H/8RF"O[MC#6CTU3ZS334^^P%Y)$1P_BL)BNW:%BZ38*\-"]Z;N)R)G[6(G">,J? 6)6YU?U.L(I,/83;"K)23B9*AITD7\-?5-^ZLGZ[761@\@-$\-"1=^GT"$GFW"4\"B-SPJ*)!L.INJR$E Z=83%I#0(?L=MEH$.L"K//JX#J" 6N6'\A\)[R!+P7TSW$7W^43,:C6FKT^$C [- "TK->5, TXT2R;38YZ#)^<%>==M/MS[31W2'[HI!\<8F4"#A&7=]+TUV>V.R>'-B E0]AZ!*HT$,:3Q6HR.%70Q_%XU2U1%OA,+F7Q^Z.+_I[WME)Q9RP;[D0"8L_:'6N V#EA3D[J=07N'>I(XN(>S>TWII$M^:)QR@ZT:L)) ;20ZB5PCM]![HD4_J&C"YI&>-^65"O18,?T_UYD*@^]*[9\MP#?>G&2SW:L^3?4LA:L15/(L9F=S5 ,M],^:RLZ-/]'^KZY@R%Q(A'R?TE& JK:Z2\Z]YY>BH"%&3ZA(L7^*?CY8<%J6_! 54AE]^(VYX134D^\IB^:C+A6]J;@*+1YHKQ$#U;(*!6GR+63=5[ZK3D3'QQ)Z^< _W5G$L&.*8Z0"LQ%,N>OBJ9__?[Q1/G+];MUU*;\5C,_\Q&]RG746;$C[,H+\'V* (3!'8N%%Q1*$NLEF.U,*S!+5E;78&#X#+TZ:97N5\G!-KJRDYJIX1'3#IJ$S/!@=? M_-7*X")4.DL:K9=>\J,?R\9/=3#BNF\/YSGT@BV&BF13+*1@ T7_:%P'9 =RZ.1T"@A\2-M9[>%3K(,]$]H/TV6^ KT$T5$?(IN+;!F/ %:R1MK>2KO986TA'[ +^*_=Y.B%7RR-$%[X40795]\]M@I^[!M738#/K:LQJ(U2)+AKQSMN&!Z?M@$P=CT''XH?FB9@]GAP#'_A_\H!= >#U )_NN^4RL(RJHM$D/ZAHINWZ3_+I+//A-HFZ%Q%+3GK^:-VB(IA-99^5X>W.3 $@YY%"8H\J)1 B-?> 0.E"U)2 &=[X\%167[>.D_I!S2-;TVF=I+T0I:U2'D:12( !>+D$O2Y488#'0/@V-Y;^7T;020E4*M!\!XWZ,;%USQG:YO>V@Z&+Y?(53A9BYXJR,M2W1V5)^FB\!732]4 *!=[/GA6UCLV%?@LS0=JAE/XN\F(O+O63^H@YI>'[=HD R]!Q/1)N\!7!XMFWH4BT5'G1RER!8MU]'7\SBBJSFW&1<3T:-=;Y-]@=/BBUU]?( EXB#)D9@9(@_M)D9 >/_I%=OQOU-P&7*MQE YNC?M=3>D2))M_LZKC0>1>H!+MK8CX!=JEM*O".<-^V:ZVF T(!""ZA?;9IE@RQ[/2.;J&RZ<9?C&7Z[CV'Z4$QB<+'GZG6/(B3B_[R A0BKW"WY71D2,IA\V+WL\QY3/]BERWO:!ABB0?1R%=2$KQ=?[[(?*M_@<9( AK!+X8M/6^^%3FL9KIF*:"2DI5Y79K,<5?\IR2)58G:?+D_P,\)5A'Q)L%)O^('BE,8M,JIQA3Y)=?TU-Q6IFJ^ 9X]D"KR, JS+[8U-AJS&QU/;^NU/^HIZ.8Q5K,^FFJ32%I!W;@4::=YLL/$5NOL>Y&FJ.6[XP 9'@/W . GY%?/6MTM[YR!4Y7JZ3 X_!0VW']@DJ_)?6*-_AG#;Q.DMI[.JXAT< 6'TQ8JW6R.BY4^)C[=6L2"%X9*W[/0G3,F?,[\#GH#0!Q9V3]KS\U7&RR05:F#U0 5!UEI=T7>9//'(\/;'<-3EY0^.V YF^D/N-"@*W@K9*TB$<]0T>W=T2'P7YJ2@+A2+:S$&R/+&_6!M^1";)P! F%0$V0F*TOZT@@(L?/^/5*URH*XQ@#*K3MW<5BPY$/N@-[$+6D2D #]_U2#>!6VD 3Q^6"M%&,OM\!Z?3'D2#(#:E=R,+D@-MH&KP_!?O,N"0RNWLY/YF>^ G@)YR)/&" !;//?**'G8J?FBDO>$>D@NL5QX8B%W6#6"VH]\]L&Q%J>QT?"4 ],@6>(K4[K;AZ ,5>_:]/JRS 1CZ1@,BY8H&&Q]FS/G]I 9= ?_+]P;VUSFEWT^M38:0_4/ @:R?1QZ_+.M/-<$L./LDJ#7NXX55 \<, 4E9A#W41R''HI"I3LU&F([%_!:\C2"]G\^K=/KK[*4R]RRS+6\=_L?RL^XL# I$4,N%6RMR.HL\9(AL.B53,^*Z+HC"#:L^!XV^) ;\_.6 U5-OKFIMU\/'EU;9X/_*"R_U%4?!_)[V<:EF40V"UXG[#*^4F*SXV&;7H^ "2RNL,K)>W#4PQ)-G;[.T=\VL77G5L'8QUFS1\<1RV=*S@-ZXM=V1LG(_RP=1M?& ,<3AI7?,>GW /7IW\*(G'LX$DXN4YJ"5FUV<72#'O6_03-27+/XH_/I5(Y\_W)QS -9<'LHD5Z^'#_Y*./ W&2?5ZS%"CA)3E8\N5]-T&2_YVA#@V66_>';':\3G&0^8[ Z'G_@\1(!?82CKVQ-AB4"LB]FL1>+>@ZYH!^A-O<45.J :>T3#\#)!S8SO,[/%3' )%K9V6!P[ILADOOQ\F.E0*>TT3$_%("!R4+"(RNXT-D=P3Z\^$@!->/8UC:$7G.I 0(!U,Z,H*R*3:U132Z(>P+(B!@.'=:U)R)_5S6+37U/!C(6=G#MR;JXL3/KMQ?)7 ' 0G!85]F=NC>P'B$'6SL9.OM/)0RX;VP;P?@OAICNA=.BD6111S<\9C(]F$Y]X UKEWWZ-/7AR^#FW/U]M,<(]2N86Y4,;4;U9U33D-C]3VISU JP?BS#BT Z093G'6 6@M-PHF()25.*A@^O43K(W*/DXYT2Q()FJCS!\E.,3X( \8!3M?SF:T3W^!25:I[ (@H [53%#S"()(P*2O"O!4<.6C2S_+K$#6SP3/72] )S#7"-^#+B'G2P'?L8]9R> =^U,*B:2X"0'Q6&.>Y]%:HA1+O7:H4==)*90<\/*E(;*ZS'(R8H=H@?@.4Q$^.FO Y%3A&X.F^=3W-\56'++BQZ6#6"^=F#)DY;W2KTX$9'DD()3P\*70>@!T/ON\%$UH 9FU&?00W0FYB_!>[%$K=@X3.50(UC#LRW1U)]"?#2 F*.L(4Y24JF^+*NMF(H6T'>N%,TH2&EU6BIST914T&*W]-#..G^A<X7/^K'A'(D3E.:;I))6GYJQ)=4^8 --'D.6D^? QHTR=>J+ LXDE/]RSYH@\ \"+"'+":X=A>9-]K>B56PKFE;B1^&+*O6//')A]RB ^CY1X]52"(K2A+A$G9%5:#0M,+(6E5%GF.Q&^!59*JP;A9X.]R4RA<6I:>]EA)RK9_N(@D)G];^:]\^ #Q\^Z>=_H)LEJWA3"!3J^Z5TIZPM\-#VTN"U-?,U +"5V,L@V '71X\CP%Z&^&S^ \+"0)KZHY:6%9:USJWUQ#U@\>UE$CST@(&P !IG+!UL;C$@//8\@H0EV!"SOOJ)[. ]@@F>]['E7TOA@15;2O[Y#C:9DX<37!4V(L8O9H-?V-JI++$KCC03=4\5W2P5N-Y & 3T3HLN!GW"Y0V^'<'T >J+Y[K!C;C@DN4(MSL..\^8:@%5:H<0E!($X<9VM0/ 'E H7%7)2IZ*OH_="SB.U4.^1EBCS810]\>S;-->[W>B#(Q@OP';\R?T9\)]SD6LK/$ &YLZ?&FNTJ!N\1G[07!QZ7&CB]5_M^E3D<4WNH0A(X8--;+-7 6/^U2# 34>(''ZS9- S(!SI>(QKQZW&$]&.RJ0Q&RXKE.1VD;_!L+DIC4BPY&^" R<@R.&31SH"H9,%9L+1RVO76$5O(R =?TN40.P3^8CC'U6 C$4J-,UH:0>0N.GBHIL^R#K @W'LII.('J5SF@'KP8=H6YH#'>$S$E N;/T7?A:4>D#1P&!/<.VMZ.YT5M/#4A 7+&!^=*7S'(5"W5J-9H0TRN#\ ,Y];AE*U>$[WA,)!?[#76@L&G@WO]\NHC($GMH 4>0P08L' J#:KK N4)+ +$,Q[4&'6'LOD"7>/E"7(]^4H434S@[0&RC!"CH6,'+M SS4-=$[>P]@OHHV5W?/_4LI 6.W;LQ2(LKLMEFZ2LS(@/BCO#\%Q6GGI=K@1'9)RD'V23&AQ10*G21!LR"LIRE7Y"R'[F/[*Y]JHD#-=.ECKX3ORDB7$D4\.QP67]@IXW S;^B;N%:SOZL1UB_RWA;$D9X[SSGJ/P)]J ZCBN[OC,F>)O2 5KI@W]CNR!+_V/T&N0* EM*:347'XJXVW]14:!*D\O4#$7$C)9 @'/3F(86:_$*#T?0U[V_?U[A9/I/OT44;.;"ZL\ BN!!O4W#ZM\TQ1CKXLZ>'*;M C*)[JV8C3(H4=@S:7ML]'QA!W\3Y1V*^,; 9W6(AWI_B<-QK!+O/1I L'2/8P,#13VI8>?2P%*ZG(XYZ3#$Y34]X_1]((MNP;AK":-QI@0,&_8_B\GCB E1;<(=="Y1[$AS;\RU=D\"#NK Q-=%.^62(&E:6(1WQFHAB%_N,5EZFY6(K \U\ZI.*GC=_P\0':FUY$9D\W4W]%KWBT9 G57-69N!WFB?["" L'#^4&X]:3QT X22AL5L!D#D9RXV4N37R)V(*MIY$A5W;S3B5L:;@D?Z1QHY!# )0S@:?#S(B$P \0=5[T+]B 5<\EUF@XKU&_])[74CX$3PX9/JH>&6O)D+@R_?!Y0 NI>E)1-EX(95YL[?'RRTS"YQB>@L.)YJ2*ZWQGE9F>#8JJ$%5C5@T64+IM%*3@D* [$\%M?/F'!>,",I+XJ?W)[N"I)D5L("=HB:!:3I>ZB4'*SDR)CO >ONJOK+>6CQ1-*(FAW2L\Q 7%-.?7* @JA,!,K[GF]8+33^;8NSG3BX\;87EZO!N HGUR75"M?JF0:D\M5@-H^,C\3WD^L>4\TC7.M5A7:H-WN_A91M>L=S 9RY%@J*>@$CGS IC75=<)+KADL&*XR+YE+J"1'+N-^W:F,-3DWEEO6"LQDXR\-%$/B(F^K ^!5OEC@44U[>2(KZ:9>4=/O^4>F9X;<&]?I&M0@#P4J)HWIZFT8\H'^4&*2^[W]& 36IK\(]-/N$0)+OSX'LHNCJ,:KV(#$S6HZY/.URPCH% (BRT)S61(E714;YI,1*^-F\& Q>_C<\X.4*'> &_MUGV W@P%LV(E)"&Z^"($;<.K]GO6=@3A42Q%[QD*4&18N"*+X=C3(JS?Z#&:_>H$71B7 P P&D=D[95<[-:%>V\C[PLYJG[_:CN4W.$STD@TZU_J=/E=(&GIM$YD:+Z9*I;!; <^&H-P.\^UUFY/F_"BHB!:$ ;&'+)7=D3M=Z]C.TT4[34F=7>@Z[)6&<2K@X0>8S Z'A#0)#OK%7NXM4,\7!".,R'SR"4C_"^FBK::7ZNJ6T:,KUBJYMB4TX1<2'&#L[@ N4.Q@!+*%-9QM@-+%BJ*30FZ+/G,LKIO!=PD#X[V6&_0$>P^U%Q';,) /L"8IU$:%,/+V+J@H70SO*\\,+R$6Q&WI*1<\X1CM=_/M[4#:%S'\"*1G8[S?O6A%%4.GZLQ6[FL:NF&2"9M>*W!2'>:PBI8I2O"D).C*_2B$C XQD)X$((F/%-5,)#F^U39[J@=MG+"P\QOD"MW8;C@ZHP5,QUOYJ8H',)H-9IWG<%=E]8Q#BV(EU>3$/9.QVW,4F*%,V/Z\PJ$:=TTR#8R%P R&(%:0NF7BS!4*+W4EQ,$=/OFS96/\@W+%EBR90[SI5+G2W>R4G7\!%@MC+D]']+ X6&<7JLT8?LGVCZ0UNJAXRFT\3Y<4JK.^PZ=\!">2QF.NUF>%=^USY8(?P"B!M18 I7RAW5DMBW#0>=">G6JH. "F7=R'-3Y1\G$H80W>,+_S^;*KE/0&?LFS.["?=HI$ 'QQY.^YBK^->%\A7&6=R'G%<.@I6J$(JFG,HN%4T3[.(9B(J0&Q$BDP^/35*5;H\ %?8','R)@_Q*U(VAC$9?;]G$+AEL)9%Z$F/%O4O@-+?8YR&6.KY?])+X)48-A7H2 =-IIE!L>V7R9"<7IUP2UQKJ.(S/AB"_B*QLW@< [OB+NQO+.W*Y9=1YZ!>FIAF+] H%^!F($'&7%\)1+X#=.@V"5!'@XZ>:8Y_>@40P-,,AQ CJ[DB(&2\E:G@&X=E1%3 7GY>FZ!7 7I&ADE;^,0:= ;IXN=#=JOUE J6]1B6ZV*.QO:V]Q!FC*1E9BA\;O?!&1F=5*Z1CORK!Z^_R@3PHV(8?+^&=,)@=6 L(*Z-0A3+B&:@HH$BWI5C;>PTG3P"-ZUH%&Q-*TB WII^7R BU4H)/5S7[YBCP@5 F_D3V[?H-)>*AG^M]!6WDB+*>R%)3<42M&3^!;C^"3&K5Z:0.>>M<^KSH5C:0\V* ?B^R5D"K"KJ)S^#.D#QB*"TEWN;4Z!T\C*'0RQ1Q40$#,QT9T=!T"77KN4ZVEX/ G"F.# \&2QB\U!$/LL(#_*@VT;C5_WJ%)Y8YAK#'*_A 9J1@$@C?S1B&\A9L&XK(;:K;+Q?#GJ>=]HW>MD*55?K*R['VG(>U>:=,"ZKD/ RE GV']5QD7(65"G,T)$''I]F=5FZI00TTZ8@0=FGC-#M0=M2G/0FU0]M_MI_ QG,\0 +[.OQ9SH]AO@L#)[$?\6Y ,6I[-E+^( C RJ:.PV@BMGMJRB/!J:;&$,[N-[!/I3 Y! QP%U8Q*U*0EHM_X+;LG2&HXYE2MHT*@#VCM'-=X#C.'4FI%(AP-.E[2XC Z&,9* VJ$+#RD8G[".E=5>BG#R( %M[ UI((@W8?:$Z78PL-]J8='@ONBG&^M;$<2:-#,8;?'>5%:ZF'\%GII3Q"/D.?8AAQC6Q=#=2G;C&(!_P=%7/R\RG ]U2I N-%:/>K5"#'5S3NM.CY"R!@X,,$"%%=+0U@+_>35K81*L$%APP@!\3DWUXW @6XOZA'0>?E35ZO> F3'9J(Y93:6)RP/ YBQZY_/GMH(JL77WGL=PHYJ>BEK40Z;U'TO)?A=B.F/J!,[J&NUO9B!\0YX!*K-0 H"X2(YJY>$ZKW7]2G/U(%6TDZ$5YK6^0KF&E9?KPYSW<6WR4Y<"J GE[-P*I2CV6 '[?[Z*!:>SLJE)>$X,-9-IP#HAY2\KX/A#\6=\N:,!BG-;RAB.-Y62N%I 2]7>62 7/S[@0(F0(I&NV(F7S)]B;Y=OD-K.=^>#WO9FQAJ1="8L88A4^[4;Q$))K(;PE7( =-:.5+?9:3P6/?:19>A(?YF"PWKLA(5_ PG$3]61+,#"65U1(G^#N&%JW> ];Q=J U%BK.?*!Y.)>SP-[>P#91L.Z@CG^8'!^4?%#?5?+,';XDI7T(B=VH:T70)U+6[B=!TM'9XL3U[\[JYG(9G]0\X: 4,2_R#1=5.U3B-UK8M^U$9>P').5JI0-<[<)%,I93<^-Y_MG,']D?QVI,KE92CS> MR^/PV=(G$P"5TZ,IY 3$*(=2%TI/)+?D*?.^=BGL5\EIHW5(L&P0;>MAF8&+EQ[ 75OFEXXKZW"BAOT>^K/8IM-AS!";]WY*[C.G",6M(1QAQ;Y;28W8.J!9%U4BYD2R > &5='("FFRQ5.4+H!2&%'K,M?>Y:?.^$.O'VE)"^?,<^9[Y 4^=(,9YAWF@>V"R%G>Z&O'*#ET4D3*PQ#XC?2(%'RE$"EA%X^4^!2#:K:5C]DVZ* .U(LMBK7=_O /U"VZJXG?']0Q-R6AZ$C$SB:%:O&P!&37Z-52):N2VO!' Q)KLZ$ C5VNPU&ZF _JU2A:PA5;X_&D>]MG-8*\5U%%S_B'8'):SH*AR3G%6@660K)'(**> (/5)7W;-+AE=50-3__HNCZ7H ^F"5/R416ZU$_,@7J?@\AH'A3MQ)[O.C."]DRBH *0QJH)!:/Z^DY^FZ690O?DNYU@(N_XP,9U?$0S^B ]JPNO,&VDKCH>][\#S\F<%M #G1I9;H7JGGKWN/EH75QTE5UD"/\9!.;=J^@EW''XA59E>&68V^04'*M3[UOHBAT :LY6#8Y+F_J9@SHA$V"A\%^)=,.7)F_JJSC&C U(S%S@X,K85UN;GL.::BDC#!:A )9SG52*(1CEJNPA1!2_ +C?S1FAM&$R;. L/:2X?J^LS0E[]@F/X3RK]L90KXO!6 >YH(J#9&ZO3LGG^D/%8$+8\6T_V+>D&8KXR1?["MP)8M7;K]Q;K=LXDM1J/9)KEG %K-Z#:7LM(IO%%G@(?W.#MC'GNV]NF'_(=]=P*@IC/6Z8=OM>,H@(X?KS9X5G DV.A"^F>7BV3AP7>^%+TM"KOB?1:^)20^Z:OI.10S,Y.),=A+@(DW&UA ?[7XXI-7N8VTKRMM5*(J1,*IR&_8Y):1&Z:)&9^@@Q#AB0SGY*(]$VZLH3W>V8,3 [BG'8O/ G8C:'"?#*AH2K)E.\^7:WD0I K8AQT@_#7/A-J3<>$E<.XP&]0P]*4SG ]%N6B3X^4YLQO?20R4;+*1VIO![$\18Z$U+XIEK /YID*3O6;8'$D#5BR;[C(@S7 UD::7NX*5PXQW&7$H43S*<+:B%%[=>;XR%ZV1DM6/>1C@M&ZN#_VOBGI.'@'ZA(J \;MA#9#)&6&N)KQ%NT9HN">]"X'=BN2HD$RIM>VE>!"HR2JCLBP!W1$SB=.U$4B+ Z/K3S'&Z%53^E&](WB[*Q5H--:B^U%SB]PC^#KZ$W!$?LY,68;I@FUV?%C4GP%6\CC F]G?N4)L&8$IN@LWPT3;:+%)KG!D3%;0G]RD9!_7VO$(F];=Z)&GU,38PU*0_%^(24NP0PQ;1%?L(X9#=4UAXK62\;I?75&/XM0+\\NY02+ < "7(6.1#O1N\V+DAWSLYFBW:9RI245 UYL?YW$'$FP#\$Y@D^V$!*(XWRT+K&>0(X @0D^$0(GX_!F%(Q7ZNP459@;,2REZW4@0VQDR[@#1PGFYBH&*4?I988 1?H=?E\R #3(# M0,PH(6&SQ ;6%Q+%4#8=P0A+.#CP>FC.1Y/]Z%:&\-/L!%] K?6F&X@9-Y 817:W&\P?93;@#M)C.;&9+ZVGA?&B/]($Z,UL!Y)Q?0!R(C@?>O1CVHN_TYC1!)^ /$F!$*@!-NP3]WQ#_UMRJ5Q4#;2^HRJF%:#[FONE&<2EZ4177'[&4GJ;Q4:!/-7U =06B74LC%DQ(S4?9L9&EM+XKCUO-! ST-?(GSG;?-4&L;EZ45]/,65=.LFD+U["> *8; ],K9=, .:,O5=%!Y>(\3AG#/T=.>!BX(2]<1%.U<8=1!VJ;M1HVMR#G3%V_D7Z@9NHU6#$@D8VW(ME;KO/O9?*8_=LG 'XYJ3I$,3&X)QO*[G*C^->#43[%JBO< >ZHV+4D3PP.XM"/1B+VT@Q-S5$$0CZ0P ;/6&$Z.H_9YGVANG;8] JS\LZ*#HYYCMJ=$BH;)GX=R3B9 !?DN66*! 7/;=.))=%(2;+9#1[%+%<.V9EA$D'3JR:U\6=\C5A,B)C^K\#!L,^M [W_F7,J?V UL@SE]"8;BX_MP>%R1\HBX[R,2Y4NG_UJ ZG-OY*J?X +S8H/Y&'5GB";8/RHG&RG-T#__5U)-BJ9/VIG>(D=TZVU9"9YB#$7/#AA.>PX-&T;A !+F86M6.V67>0SN6T,\ &%UJDJC&PL+W?5T-]=\&FI)B\4M/F/R?"!I'A>7S;8TXFH/E6H%%R/Y#*:/AZW[9X:!H@][)'T'S1=QF#:)+"NLD2V=4?V>( /J09I("@<4?YGI'^36CP>4;H_:H0'\89INW2WUKO3!AZ/6H%T_G@F[_3&>X;\H&* 1G>S,3_NGVZ@[$@]O5M5\DS]K69-LW_)718J:) U-SM.P=^@9U\;VAB;#QG^04S] *=\A!WW_3<%^B6*@MG:&:7%OS?%O<.@:2L+(=*#+RAW,.)_E[X0KO?X"89VEA"X1;'D5+0VZUC-0,==="I%T>&]57XUISJ8KMU>V 6.K<(S#BT $7&>7S OY6459H#<98;NBA+2UAL]C6IY,PTY0LA5;Z\'*A=)DEW4V&J73XYV\.?QJ?^KA!K>;^#EO[D/P\8&B>KC6#6Z\,H#94\J DA@8L\F<:TU\WM71R#IS2ZF0 -LWO43DR'+]E_]S[>L2*9SRW",<_^QS;E1P,"K3>X 6)$]02W&*3T'6!!]&3G,0Y)S& 9_WE7'BPK?0V[EUW"^C-/\'<'6&LP1D@?0EA2-J@AQM-)B+/L\H2OEJ^4\89.DG. $(FO(UNWJY"'SJ9H 8SV.N[#]08:M_1=Y=B?((@7"'CTT6)E XOF(K!-XE[#JW$=9AK)MNUY].SCYB*4E*@OZ ""H7@G#G^Z-'59VYF;D..'#5=CA:'*IM\>U "D+0,\+6?U SW.#'L+E"OX6J@A'>ZXJEY7(QK:F@$%S<$_E3!C-FC71H)7MIW,NZ 9BSRNSXPD;>6/:Q_^#65:_2D!N/&D$X^)HZ%@/E!-^O6/M+P?+&:+2W2E,RI';# MK@C>[2(61;#@Z!-/=K'Y]Q-D<=U).N4)G:#";_ CS,/0-0XG?>MCQM F;P&Z;BA_XO#J1(11\F-J,?:LP/LFQ5IVO!ZQ0D7<*SXZR.Z<30N:693&"XZA-1 U_].EO"OGIXE/L\*#5ELOM*T RY95+4MA?97#C[DQ_QO?=<:H +1#L/WHK_/X8^? C??,L:'PY_D]>%'G88]G@&6)DYM!.8;UX;,A@L6149OH.4,C3<7B79T"[+D#N.'S 5,"A/AX!.DMHM-:Z$4-MKC7B<#/CN]L8KU%%E2PG=3@S,A6A,VQ:>P 8NL#J%_*Z_23NTKJ*Q$M&0A,@3%]P7AC_)#AH#! @>)C#'M;%'UQZ6:V:\H7JAWY"%O&PA?KM)@9/WW+5>7+ZNLR,QC5NEO%==]R\XWI PD-OE@>7T ?*G?+*!T,#MKIR'],:-!2V6Z-0F935EUTNV%GN0QDI*,*E$"(#;YR% 7,R?UHR^)E(D-YP\L8TQ 3RNZ^SN]AR>;1%:@=6VOHR/!R5ZON?ZJ9Y\GKIQ+BYL Y+Z%];,GI ,+L^K-$^Z*0!MC#%G/%@&0^X? :\T=30.>DHGOYJ)BFGNEF)0+IWN% O7I-[4YLS^F$9@EYRWNC+J[S%K[]40DOJ7N7A!WV(1G8W9>'/5_:$H=@B$GQX5C 06NJ^5E+C*I)R"L\GS]5[#OH!*B0WFO/C;JP0<"J[IDQ;DG$V3IU5XD\(BQ,6W.Z N2I\H/7PXXAO$J/8-FFCA_W?),[80V>G>F/YC?NX#/DM1;8F(18&5PP^-,G-'K.0 ,VE;7]L#$%1$DXRG'6M68^ KD4LTVF=Z98H.(.&Z==$?\\,C)V>DMU,%^X*LNX"1 M '8PL+T8FWV#F) ]5FMSV*EDGJ%F9G9.69_"&2X&%?]Q.4RXF"B"E \(TMDU.3-?D3P4X1VYY>F,F%/3?=X%1.%$0C\Q6BIXULQ##D/&DE:A!18F4"&WU< #N/9W<:PQVR&<5A:6X,UM.!B@6<(6Z+G&$<.3ZZO?'+ZA4N87D<0*O5AR'@L+I]= ;OF[-^-=4N[?<5<6(%Y+A<89=?E@%4Z7WZA<5V**=/LK*WRV/;(Y988E3_7$*B-9 :A6G8*6?X\+YW'61.L3"<:L';CX"X?^:>I3=T?D$-7,0_CD^P9??6#%IUO$$L:F1 <"2=Y/0>B07OGHR5Q4=1V6;L\VMMQ.-E\,;5*-NC=@ 2@\$&0N &](<69,DO.<\B R\TAF1W)FD%"7 _$3A*" JB\?WK_HS7R]JG7S36[T4+#6+QP+=G4;&[0P.";8A4I 7*=[#H^;G:$5@F@B[='0(%N>^)2(J(0"D\B0\J\%I#!C+CT/J]5T6E85W"I*=R74 )"88BV=82&"CK.13'I9$..]Y]&;-Q8E:!PC6?_7'(*EW).&\"UGO:#>9OIJVS(H@ 0EQ[?)Z(ZK%"/64 MF'!#(7W3OT!0^O*'WE9()WL=-T GAX45#.[<%"=N5A% 8N>A_+Q20N&N-7R?Y-IM'+J)M$616D&H-/.N]P.)THQR8ZGE+WC(CS4^+4"FNX I *:=+X3<9S1"5U<+7K4X]G(CSM@L;+;*2:]&-A>*21HI5KQ'/*D(7A<5 JG]XYC6H+]U-;U,">&1OOW:7("GAGILF#PS<>I6==+X8*+%K,8S,(&C6/^@S;GW$L\>#E^8:B\AOZ6H"S$G!K\=$B9 _3*'*3'IF%@[9Y_@&$EL<2%'#%YEDR6H+2E*R#MF5RL?GFHGL1W1#LU5YJ5"/^] [1-;F)G$F:IWJ"<++%N?4[?R3C!J2$&KX?.8(AV1C)10UEM9D5A,YR1TXBU5*](C 0H?DO?P8+R>OD0/82-O[1(F.-84II=7 TIT:X1X0-]RFKU<'I#WK3&YCW8[%0X.[=H.FJ3[3?@7)-7Z_&9Q3*[]EPB3\J.+% UU1=F%\W1F$-I%_GYST&I49;+U 8T>3^E(*N7D$8Y3Z/'2&WU7TG(// OB$WGV(188."##*!*"\D3B6'G'HUI-(K<-*B6 W@DG^?GZ*W6?3PBD8^!R""M3Q? ZDN=QX877Y;>^-!EE?6,O\D=%7&/P;6!: IB2'$+:38:QYD*IN,S[>2/ \?+:/!@#JNUL7;LMIKL"!,T(668:9!;5?0@FE072_"3 ^?3R5\ 4Y(+;?20 W@ER G/E%@Y.^JWU'GPDB%:/@ -0:4_)\^N!'2F&Z<2B[H^>N2M]+_/^UDV+1+%$W"N?$ ,NBYI^&L>)32EL5VJ<[JF123 #EQU?R71I6UG^BK65;!6WMW4:&-\0W-^)N@*D& 2K/>WGXV.Q5T2J#Q>@H72)IR)Q=QMN4.0LTU*#UE6<[YF]MT= 3"18QVQY%]D*>\%DE^92V6J#.3IE0;C'YA?2D+])A?G:!>*4Z"U\VXS2>\D4@5(7SK!F;%VKD/_%QR78=G7:F61:Q>_DI%"?D# %*ZC?H%BB4L!IF@.! 2F=42IC=_,S?B%MMS6RPSKZSQC#\S$DF1.D"7*;N1G:)MT( J]N<]./;<:4)-$+X]5WZZ]$&7?B==3;M[4I>]UX\!E4^OQY3Y$)FG_BG464Y/P%U U;H)<=IP\%$WZ,UXY$"MODRTZZ!;9$L9B 2>?"WRZAXII##*VB\DB[$&JC*5^0A6I3F0H&\/3T9">R..Y L6N$"%$C9H>7R")3VO3?^[XRD^#Y^N,K=L,-D.P#CL::Y.P]U+XI'2@/. 05:_6M CO'&AD+JYBUTX$[KW"OO'VH&&S\G:E4-MFAP7P,MU>C=XNG,; ]%X$CMR\CD:\];RIS=T';*/$NFE]*T:> "YFI6LVU:3]*Q.3H*?X4%GV <^$=E@!"$J;H5D)IO!?NVU-@K9TBJ#>"_@5F^595Z)Z]@N:0 @9E.(+YN*%&U-F* 17O$ )QYHR:84G6H099 _I32>U;$OMB<*_ICPBWLH7X\Y5OH-:ZS/=ZC_GA/A*'37;^#D-G?O>7,NCA]EAX(,J.(UK8ZIZ7RZW-6I](/_9TFF!"_V>;0ML,2!&X\7A^(D*1 A$ V+:6%]-WLS+ 8[+4:GJK6NKZ1Y&AH_Y(JO@[ZFX;,Q;#0==S_"Q289S+)ND:^TV- ,(8+Y8W(Z\N):5@6A' H"/,0 <+-P.20!F_6"AW@S79ZCH82@4HOZKHT%LG^VG[H P&I06KKV&,WN9?Z7 OT'XKH"EGB!&'6ZN?&[Y\]P7;1F ;)TNUF;58>/R>QZ[K$(GD5TQ;,U9)1(V_0Z4GQ93&B*E\^#>- ]-<9[^?U62A-^ARIL@UE^[DM "_,A5.#ILPO>'QD6!0>V"R3B&E[Z+;@GVGV?[8+3MF3NP25I<@?YL:SLL5K\#+/Z5WHN+&7&TU'>*;;4B>T\CDXTXIR/)/UM)@]06BV= <-5;.'6.+>$D)UY-%_RK-(G%FW=X4*?A;(IM'90 )CGG!F/91"=7TP[=@>:9;%V- =B"B$<)KJ*Z:^W"*4(MH(O%Y>>R[W*43]18).34E97?HN/9W@#OP=B0-[&WV]!WD 22F6S=E[CP4YT@LI_^$+>P(I;V^8 OB:/9; TY7D=F62^U 2OPZ>D&NV7O3R-"W@ :,(3K+Z(_1B8*V+:W,I9>L'OTY+0-5?&A2I2TJD(SM +Y<4RT*(Y!<4\5<7AN<4T#R&)0F5]?HLL!1/P3"I+O 5OX0ZSC'?'R]-W>O3>]7&FGTWD3?9B,LX\+@S9^44QF!419 @NDJG=S%W!.Y)O!_ #]-P[B(?O_R%$2P$]"1B[I,A>F%J[H#X H+I%)O-O3)Z @WT#WLDKOE>(]!H^"':S.S7^..7IW1:&]V(SSYT0"IXCHD_I>[-E ;!(&W6N3!NV;*C827[NU$0KM/ )G[?C7S7IX8?&U8L-$R*V*R")'*DLGI[7:BP<; ):E 5JF-.W7[U,M[ PY1HMFADT>EC"UBZ0U#%#W,EU@G;@#\I]J%=-(]O) #[[(B )[6_/XF\&O:\^'(*5$]A5EHJ]R_)Y>9[[%G/;40FV14(6LQ>7=5].*0O13O4AT[- ]@A(TJT6N:>2=8:-Y. XV!NTL ON%L(*''K^8%WQC3>Q&U$NT39T+P-K1/ O(VL'2?!],BE) BQ03ROTB\-!1=#3LP*P3S'$5PYR6^X1EJ8A<1DO&D(38N*C'([[9Y_'& 1/;I]:ZAIYY9;T]:9S:VP+7IG'VY701=/R!5:I.0B.H_-EJ+;3;&Z9/ZO*LB.F@& J]5 GJ_9\]*DM@TQ6N04-BH@+O79 !;$$/=48TA6-&.T> \Q<@K!)FC< SUQL,>71@UWU$RW$\+MLU/\&?S7]Y?S6H$_KGEAI)]!XO =(%M[)&V2Y]0L[6:18 V^O1+_U+<-$>$05*3Z]-#B)4SS].]*#S%L_'IO9Y7SC]'T1T[^]=193[]E =9ET[[AL>^.D-+&Z#/!5P7(7\K%,.U>_0$\-@&I[B2',D&3VPO]ZDB-VA'H \\1-/;ZMD_0QSZ]N$SB6^R[SCO]F_5X@ I;@B1$1;E(&M:57%/CA3H?X>JOCQ6VI ..1:0QV:.;+[EP#A6B4-@XH,7+8RHA3_=QW0PLI4*LG<@11>.!/LH;;;A%H6W_V# $ />R/);=!/+PGX5JY.7/7'N]A4"#GR<>/,U!2)[-A0:PX&[9!P7E15G":-W)31U UH=5@]+4[+QVTRH@@69-WL7^5%>I=CRCS37/*'3&KHCWAJF)(V0C,RE*&!V7M2$$ [[%R,9?NZ2UV*?IE,E4^#)T2O]8*8P0.$>%-0!16$AV#([ RQ\$M._('1NG*<-O+ #Y?\N?'^L=N*%P;QLIY^?*,=)O(SIE9M.XE9"8L;%FN&Y*KJ)WR.C2#^)6D7IS 4 D%B!G[8I+-X!ERMB(8E$D:\GB\F!3%4X>U:A0K)PDP66LV(Q^ZBETCP5$/& G[#+ >L,/XSJQ:<81NX52@E2$&B^"F:OG?*^&NZG*EBG;T%4#-X'UD&3_:Q%G-O06-!<,,4@B(3DBK*?!-=^)X=;5+2*OV4SRW 00R)?&@_)IR[ \N($L"6H/ W#OZZ436PG!',:%0INGMP,6=)X37(%R@5AP6%P9+"&<&//5^DOD<62 R_ F])A=V7UIZ\F\2_!"-NVO?2H^/Y#IQ#EW<>F$AGLQ\OJ#6?S:+>'6,E&X6-P, XJ+#O:UA"^U"K?_M^!1$0CQ:8OY9O7)F1>N:@0V#ZS)1Q+Q(\_40'*5IP!T[7U)S X3,O3N:3OIE1C;T] 1^,+DP2%&!^G>*8IQ6L>V#]"/AFJTL]A )QQV2H_3RXH/MR FAV+W?G#.5?OK0+F/MTRRO&F).WM 01V'*?.@4"7'Z.8'3%28%5$4)7P.!/,V#JD%F=(")Z.M*U9\^#Y/F+!]/^0"P5R'1U/CT".V77@AP):;@<@QQCF) @+ABF\N;.DE:[Z]&'X8)1!].5/#'!2"+H'8P^V(<,-C7L0%)+XAOL0S/QM7JP7'$X/$U^)]\]W6F41<(A[I&$A16MB)JCE(V]2QN.M"A.5$55("GF-,R>.UNW^OS H.&#?-Y"))IE4T2VLE3\%LY"0"@R.AC.@;ATB;N+TG \&P1]UCSONQ/*G1IM3ZX$ G F%R"MF!_Z1F;/I&8M.+%'YLC5H9@O98(3"SPI%"? _6V@3Q\.V)3O/?_HHO95=+KTV)Y?]K"WA6Z^:YF2$6ZCI=Y(TUKS=4[WLL7-A7!! QKB:+;X*^).@=+HZS_*JCGZBR[/@8-%:.F0(>/LO.019X-_*";/L*[XUCRBF,/7' PR.&?UE6,*H'74!C^MU-=ZR& Z_#MA4QUD^ 56!Z-*1N4K_.<3IW=]<:[KRZ#0S6 Y[JE3:W75R'/;K1B=D,Z4[(J-J3IN#B$V/U!$=GZL6W7Y,$Y3M0LA5JR>*G8&9)@ H=I@X]X&#:%+#MD_U!C>R^>ZL(5%GB&$1O?G\@V=:?/(.,Y7@851O.D1464LTBENOOP%IA%2[/@?5RVW"/SV^P H* IT"AD4CW_FNC".3$ECA]R(_R3F\7 .8=^F(/P?,C-*3M(V':YTM$F; #!]AUE*B."A>\$MB"%@J/^[BN:_[CD->N*A_;WA?-M@N.,+$[.J"47G%3>A :ZD@)36#27=XA:*Y^.IR'E(5>@UG )@TD?"J"XAI5X@.QS[<]1U286&)/7AR$F^Q ?'G?8:^0.>WJZ)E\.7C!F4M,T/PPZUO85D,$W";H0#FO:>.V22GR0/^IN$90* YJ F=J86]?8"Y"+\Q\>H>H@-YT+F#^[\#K?L:"KS-\,U@"[ F&':.G*(&5,E,(EL9!V9EJ4\2=I8/E)B46*][^7:V/H!3@X(I/"X6!2WL_B&&4(?DI>C^%64.$TLJ 7(@'TF$,2> )DNI%,G8@%>C-KZYY)V_M<*/7@+GWVPZ4R#0# D.!2.E[>.PR2N$K FW^-WG/S0Q>?Y;7)4>\_P:!@+(.V'5E8\^SQ/L]92J_FIX;K39G9IM*$?<5C#2#* :E9)_+MZ=T;6V27[]S$)@]G5#^1_X@WV/Y]._S\\:K!)AXO:%$V>Y1/'2OE :!N6::WH',]5 K9SP 2@ -9_D )B;I74& J_!]%4 IP3'K7QH\AO>H8@\926BW_BMPKEH&X/PWP.=CML13 ;0]<)/4%JYX4!EK[KO/E.U:\.7##QL E5**\\,IH!J?/13?.!PJ97VH##>\==.#3Z;?RA*-I[%5WZ/D68SM&5=+HV&O[A,K %H-(@9@*%1I#-9C!Z7<'HC5,[\FK]$HSNZI*UW9!HI &T!4P^GUF63&Q;S)^K!]\ 5+R'%0(#(_R^<=XC"7NC1&HLR%2\XH8O58&A$ZL#36:-@Z+6AOFC9R^!Y-!DOW;: +=*N7QU _<4R UMM^.9Y7(M WF3;FV%W^DF4OHRBI1^(4&/OS;2Y^E(YXI+%CQOI RR2$#U\ ]]Y0ZGI&3Q/)+2)5OOVL+F6L"+H1X!ABI_?]KK.9XI-EW]M7CRSE+N7# RU _='6U7IU>7RQ$,@2N1KCERC=OI4[=W-G">5W!%,I#3]D(\U1O?4#._[# &+#4 >+?>3 ]\'J"APF?>:(W'<<(B&!OX4)NTI4;_$X2^XLG(;5*+/ZV -4^2$9(-F]7M 93$/XY):H>8FZX1]C^=W/V/JXC)4FUZQ=$#'2I):Y]4X&W!-;YHZ$T&#NU'?C'RZKE99(N-L4N 1@"<0)S ^"M5Y2]LI[?3RG+1/3,,'4HU>I(_,4%<&*T^5,>9W [V_5\/&?EFW/@CL2PPQK#)VJ :!_A3G^(%)(?YIVL[+U@&.Y/PQ;-?DXNROA@!+[ Z"LZMT52H=UDP)>^M+3>$41/@O**WKT3L6STE6@7([]VA!'6_KO#L[N*-.9#4;<) KOVE$I3S *0$(3;J1QF*D%?:E=)DMRWSC5R\D[W2]/$LMA03Y9$KW1>NNAV T*FZ 86N#8#R-F7Z-C"NK&+'6Y$YGMCS9'=_KZ:[O]H4D*X\*2Z)NW0]$K^H:36D72]VV UJDT$/2&A"%Q;F8VVG@G;".D?2]@,O.[M9:GP-[/]VN022MZDH'MS'TLWY+6 8]T\ 3/09?R)VYG1:HQ#MBM&[963=4DC(((%!W?)9ID6WI3N85XF%NW8O3!\I\9W/"#M9 S4M==D^0'\^'PY#.]/JWW@\/_F_F@%?GF1>!!OQTI?2QX%6+1S/L'N"JA'!(>5B6 @CG+6\Q"V?F$_\=,Z;C5@%&1A%?;J%&A?9]<>Y5F+V3;KOZVK^6LY_[&R;NM4U(N N+9DK1Y\,WS)*8#9F;>XK3\AQY0]S]7 ?VWBD4EFPB8O'0:]36AT,9K1;*,V%("I/P-($==+<>8L\.6J421NX&4*F6)7=W88 5].:\L9'HYU3J!60AT,5 @"')6_@CR.-&L)JV7ZZC,U+]F.Q>$]<6$4VC>I6^5"I 609Z/QW]U,NZ].)(SOK!HJC:.L-V\'HP+FPT*ZIQQ=JQCQ*2>-S,-G\8[M %@\4@U0Y.R0,&.M\0W_O?2-0=8&?ECXA>U)S*5M\G";SV_@O :I&[/DH3$,:,Z7%8Z2T.EV2+<;OE/)"VWBL4B&<*%[EXQI"\+;>BLV[-LJ, @(H C8ZEJL+<"C/;%6K]S-C9#W>?^[[%B'7Y?)TZHJ\LA!'H2R\M:D'LPZ4/MQ&;P$T,AJT<"E7?D'$&ODB3 ERBXF$M$^L[B0 T3>T)Z293/./DZ1M(UA(JAE^\/HL.1:*E0Y%$GCB"LVV3*ET]8 ?9E3OE^PV83R!H/NK'SEGY1-E2#V*J6C?4C"T)[#^;H:J V=_ N8/)NC(Y[[&I7WDXKY0&0,]=G9W9NPI'10SYB]T9TZRZAGB>%@%-R86,$#8#-%]R S&[MA^[.\Z;9 F25+N#*/-#W\P'P)[KO7J=W,5'CG K.A%H79W<&F;F!)17^RS\&N!T%/8 4"=_5D"LZKO/-9@U!: +<2<=T+_.(; UG]P']56'SCF?,J&&=? )U:9; 11[;_FO]!.2>*"@Y*4N!8YH<--]&T$J6=1OSD+RUIB*?TKJS<@E0'R1%CN"1)>00 D1'1"@N^G9[+B8L3/8A-?VVC@>4@J['L0!,Q^"$=J:N^E;[ ,/Q*P%_1>0IHU^)256S(+XMB7]YY[Q=DCE= L2SKE=K^6^>;'P65:@1\:]K=E \#. >"S72..KJ2VS\6QZ5Y=SB0:4&2%+5<3&CR B1@,MJF=>9/<9Y[$)D*_:)S_*S^4*=4F%_"<5LD(O0?\#"Y25@_6X7(;:X&+B7_= N\'B:7182'?[MH@8>>U8AN812J2'C*DDX9=(5>#CR)1ET]X$+P=X^BY@L=-?5?-I 8,LZ]?4W_^0>'N.(N0I_>PX$^;ABF&9ZU>O9VN(?3SWD2T_Y[8PAWO/_IU?ZDPRJP1:S-6@ MVIQ>2_)L8\:]9%4DD&CC$8M@ -NA]=,$1\'G' ,%UY3Z519'V4/-'N+/"?U3:(6%5XZ H'" 2YS]#3Q?]&2PIJ. . UUE5ZY>UU2!#-S3&C&"'K0C;9<=(H&P(&[J@S*^AN:QGCK.V_1QPR=GY&QZ93,Q&.XS99-UG[."OD3M>%W)L3=YV'IM+F&,[CXX,A$H.X,VDJP/42=& XK%,NEYL>V][;[?0^F;RO7LPZ#^0:HU%U_8O:8<;]:;Z"Q(I3^BF.27\;/[,ZH9N G1^IK^LTG8NMRM)F(OJ].^T ,F,9.@]\#L+LLI-,<:162?O#-0NJJ25L\C$GMAV IK5\S>!\):(8R'#\2"<>.TCK9E=W'[10L2.FSXGHS(9]Z'BINU8=^-K.,%*O4U]4 U.FTWP1_9JBY46DXO%[3DWB[V3UAI3 :%F "QP\V$B6@BJ8/?I FY,,0.#DG@E%!#EM'1C,^L:NA0H1G>AMIU!C?:.1@\A'^;<_)V\XJ4FV =.4(Z ')F'VCTE^CY>XI,#Y'56S]?Z;IJ9R@>%=*QE-2M23GV%S)UG\1!J?X_M;- =81_=?;#[0C+A3FVWE.YL@EI2+?\QT],?SZCX)U.9D.P>3U2=F_B.7YS\ZTPZ;92 ?JLUD1L+;1X@7!>7=,HZ/6<:*S">G>9X^0JH[BVR5OE%C\8V@3%TT$?\#-)=A7+$ 2-3V2BK4"^[#//^<>4! NP4QY6'DF&9S&\<-$5Q/@B\:@;?F)F0S-A)ZY[VPX68-B+_]6+(=U(KYU%8?V'?Q *R68W++1\"-R4^;Z-$EZ ^G]+EE$V_R4X5\;S1F.+]T#F%A[Q+3_6]:9EA!?PSMUKUOIER=S!LU -X,E"H" , -Z?ML#6=Y!%V CW7HY%'NMN%XO]7+YF]D@X0'\YH[7<*&A,KN*N:R=&2>3EP9&8% G+)ZJQ-3$Q"SR3'>#)1USL:!D#.%;R= =#E5476!X/2?0 ,2J2QA!$H/Q.:L-Y=_R"W-#8R4_/.@*Y+6 Q?"X\>\1V"X&75YNG4EPS<0-O=/KI491/0B=!%;9F"97.HP*Y)>/JQB51\ 8!ZN< J=/M)!^?UM.K]0VB@B[,.I=*7-9"4%36Q*XYN.E*3(1=Y57QRG.@;M+,S'X?/_6%,5!/! Y.H7!FX^4*I$]7;B+/V9),3V')T ^5M,B0O7B[=L_N5'U8.?V=Z< /A)($O0T-HMA(&&N5@<;K-%RN*E4%8F/Z^I.L)- MDL-.\F %&*].*>JL&I@IBSMOU?9P@Z[;#7%:0E 1]_'WYR!T06%\5)VV7_!(4W'1[2IP'6+2Y-'<>U_VF WE3>*OFJ>D S^9( S),AA[U][FB4YF>85JH:QXT0Q61(U&KG?YD9<'KDOO*J&9:I;5B3M_&M.S: E]D!D3QIR5\GI [&72*=&EZ;-WI:\'\Y?<-NUM9+[9YIP%_1L"!A8?T+7$GLA?XC V&<9 _;O%5] ;CFK"=&AK EXSQ!/:O4\V6/!>#)K/)98R^-'/)]R3LD<4I;4(3C= H)$E81=NA8(I([CM .QWYFVR9J8_;V6V_\4F@KKH3!6_=#:U%'^<0"R.\\>7 RNM 9,,*'+V:2WOS'PW35!(K3O%;BK37^R6RW[J[XCL!#"^OTQ;;8 Y($%!$LG#B88'V.$1)>N9D=4X$;*_:V5V:WN'=@X;H.>HAH:L%7(-KQ;UJ:;E4IE 1=3_HZ.^.XM95EC ]+:ZV'* 1J')C*.]94&%!N80L[-S[T,AY<]>&K!@2&X 5PGK Z$.>;8,N/2 >>E_!2/XVL>9]\M.3UY@.$.J@6,UJ7$52KVLSS?[9VL?*[5V"!4^CQ/#!W6F!ZXEF2W(VA8[ ^W^4/WV^)(*H&2VQ]C[,CQHNW/H"E &%8TDW#4(E,\ ["%/C!P \ZOB;': F36$I@D&QU?+<=JH=L&)_)QDA NZ$R,N9"ZS*FY@QIY1?%$ 1LK6P+C3T^TLPOP: X!?!"?% T=-HJJ_7G6[RC0?\*D$"#\S$BY?82LHD+&_'#>H&;;Z>?-@"=Q9A@[@& =$.P;.')Q,E2A,?_CBK"^WCI09:ED!TX.3!-XK-BHA- PEFKX")5 &B/L;* 0_3N )FG!]M,.K-G8ZRR?\(&G11NQ'I_,:+,BK2X4IBXZ)N.TLG[K]%K="<0%HE+M5!IPR)>8U'KE$;O989>SYFED&SHN+/M:1SV G$6[B+00Q#*]658SE,1S"8<(?.1OZH+5,#,;XEL)?*A'_%J)T%I>^J]VJ3[CK;1Q =!K_:$FO[;1%[6=.8=FKB*.CY+C+(X\Y[X<\2[XA0PYI, \RN08D<(=6_BQ$O.^F $DWM]F5D1M/L/>,+[:-4==5F9DA-X5@<<9Y2LWH;0*4M<1Z27[3MV[W0W=;=SJG. L7 @0NN?V0-#2I\+1"W%CS#9=!TKL#A8_DT^#6TC\3]4"*SEME$W.5A/SE67D[,/ CXZ,H"+6ME5#*)9U\PLT$YUB.>6/D)"WR"?YJ;!1SR+,U/K@9QH'>6IKD/6"0WH_ 6[V>4YT[2@_P<28[MXZUN"D;^ZB3&GN)KDD7*Z7-[H&+3X?+-<:0G'*Z$[IL!,_' +_S8OR]5"$YD550VB_$)UVZN[TS_V?$#,50:\-?S?&\&CH&88Q3P-:G1EP1R"V*R %U&"VLL%_\L$/=_OCJ;XQH1E)=P#&"H,Y)=\,_3'#N+Q1MD.0X];_W.OU<+YO=U@GQWS.( :H\)X=SFI-9#/R)*A=->/^ORT2M!F-K$.$87/ 9[,HW?QP99+",Y$>!#;N$'E+0G/Q8=Q*?8Q5$2.-4]L.KQ)T1:G#)92W% HGW.*B K541*?'FQ:6VGU<$_#?@K(.1$6YP'7UC;56:-;5EQL:38G#*"V@E66\[ $UOJQ[4?NF[/6@\0KJ-4P"J??QZN:NP(:(T3L>EH#+> 8R.$!]HDASEVL"/PR/]KE/+ (=Z4NRA&J-E)<'HD&3N_[(<7TPH%:]1,K8=SAVN6 K=5NLVG$8(F6SRZ 7PGAE5]A/?[1B!<$"M?&_1!-PY_F#>YF2>\^- E3<3?;%;!5 ^UN&M<^370PV6SP(BHJZ;-]1 ]-S4/ YBV[@R(O!R.?>9*E <3-B->IW]7B58TXW?)$D4-684K'Z"#>'>^3!O:.(GLRE4"$D+:H*>9J&XJ3,LOV3KQ7)CW&-'W49\I,!IKO :9\/1\2,'(J! ,=8K^R5AWR,$?12BH3<*(OS2I9W29PO%YE"7RQT_AT0I^T=V)+ P"5.->@]C6CEW#Y94HOABT$VWV8U4_UTU>,4Z?9=5#.9"W4J/>+8N 3#DPSCUF&P 9=P\5TDLT,A5ZTZAOF72%6NZI:K9192>M=I6VT 8@(81FG#E6\H!ERF2'%2WQ9]4 1M)$/QLV)1@.1;4X>L.718]1RZ-_\_>YB-KN%9^!\FH%[)_J+AWI1'"CVVG;Y.(; WF FH]%F,2VD<9MM/&,TM;=9/CD$8^I;LRIO3@TF.#M3#-%L4 >!TBF,W.FBU POR?K>?41,96)C.0? ,W4]QK8CI&G8.7.,4KF*_@\X(7OR^'5Z20MNV3]85SX49F ;+S'S-!7Y>'C52;#]#_N!#XK'G\4*](M6@^O&\0,;-USC@*= -W 3OSCNPUBS%%QY_ZA)E)D\R)M$5Z.JHC-"!LG$2IE#2/LWS]:OPW*#'[*+;I+[8IC TCV<:C$KY^X+0E7_5K%N('3H^&47(G/<511W;]EH\5&J?5U,$?+,8= LE#?- WJAW""7,ED>13+^X$K&)I;%H<^?KBM43])_C!]]!K,2I5!_LGDE,"K-A5^XA$S8X @@+9/;9N8.]DG S70,W2A3?SO"EXO7V8"-UW"F6MFP0S\+M1(D%B?B"5#%2ZS 7A 1.3[0A_>:X5@!<5!CQ<:^V,C04?=A3X/"Y2&PYVE=:H&D^.01TC;%&L CO<_0/X:">A(BYE'J3\>.EA8-XXL7P?I"P =^= %I&3(R1_Z_RW&P;B!89KE[2PMT*/[*HV,!!N1(,NV8MD&^AO)+8=#?K& @NG BPW'Y<..!0?N1+G3>_Y:H.B!MJ[8#_.A\P*^:'RK*WD\[.=' K:8@\W>%)L(QWE4W:AQ6D7S=ZF.XI/X !5QSD'9;>4Q@$F+"J!.*H1.H TQV=XD;MPP,M'-YIP6+X(;S&M&!9"MUBD>WLZ3D&.>L@Q@\'ZO3F1_ON_&4[+U17 T?'-YH!&?:C8JQ:,%6CM43(W9&,1+OGZ> 2N>18 M+JC/>GMZ9L+Y3$GZM.TO%]S @/'9M';=0VOPXT$@"D4K'#MA6^BL-FLR]L%FMAB#=)2Z,K0RA'1QCM2Q;QJG'R45 CU/7!CJT,-K')=K1,@A$-FL+F9?5<)W L5F&1N+P+%T0E/;2P-,><>_&V? ^Y*1+.YP YAMI-".P1@6\(1[)%Q;@SB[7FIBP2XD?6,!]0!;ZNE1>*1[HANM2V0YH.ZX5 EF.,%S85#HW7?K3WG0K+12"8,AY^]M%=&"H*7):K'%^O< 5M,+"NH@OXYGY.R=O9 >U9K5X!W<=UVBPAW4?>+64)X,J-(4X9ZP4697?K_Q)Q9KM^-BG'TJ"= K_A?/*6#]D.;?SG,A=P>'L BJTY3'I&6LLFS--]Y8H'#1E OOAVGF=L02?W+2 Z[F)_1FB:A<(YR[O]1O8+#[09 "F2ZDB !!TNAK?YO.MJA_4Y ')-GVV10@ZK[,.*B._XQ><*$C5Y^5!WJ:VI8K&P%_:LUDD71[0R%ZF)RP F.OD.&ETQX]WI)?EI')2323>0D@C!=@LLKRM)]>R=LQ/BA&<[E4V7^%YA; P\?_6H2#S6(] W3JT5L\WDCF1)AO$+JP\:TH$4K2:\*>,BGD))-=F_*)/?Q#7+IJ N988)<4*?JP5SQZ&MHUU+J\PG%Y3#3$3[,R9?6+Z0NNA)42> +Z&6[98KUXP^<@F 6TEF^4E4/X;PV^#)!>G$M/,)6@!<]FJ!RSXLR.]K3&W#[*HWSW_5&18#WBMCJ>L5 10O;:M]@ Q!@):>$>:O1>7=VL,8]6^.H!96E#^8S@!I?CO=SFDH>^ <7/6N8YM=[ QZEA4&<1PFA;SD:A\Y4BXF82VEYHM/\1?Z0=4V9QVI3=4BM[P]8F!<:5'S.XAX?@ ,J=YU%_\P9U)6>Z B$#'Q6OX3@4UL\!-3BD3Y@RUJB&M\+GH;-:/[1D_SMSR.65LET!:E5_\,TDA68H.^\R"L6P)A?R#N4_\](LD7:+-H( :X]_Q^H$$.-Q2[P P[@Y_%:LA8CXI46KJ7JCDZ%4&;:LR4D+GVT"L%T8>GB+ 7)6! 8[!AR"?DD.>OFC2E-N.EDY5-JXNA,WT4#:N)A*_!FS-G:\5M[H@9\97%,VJ A%Y/H:):X@OV]2X V!4.%\:Z7,# 5N2@8*&5)',6*P>@8WA.13/7>2#&*"(8;9G0[N0:S1M_"V2ZWV:Y)H P CJ2 :)P<.3V@)",TN2.\E(=XOOL-Z>#K2M5$LL^),0+:V"4KJ4J5SE0ZO*F43M,%SL?6 V>VR[#_F ]+NL]>"2CK=A9I$A:'V F@,[8L_%.9L-+-##Z#+P$L=J_EK9@!#@FW" AL!O?(P_/X,16.CC'*,20WZ8)Q_VR*6../NH?RR2I40^96W+C.,5Y@S[K,SQLHO] KN9*Z>@%*@LS9[M6$84F*#/!SXC4B6=@BKFK7GV@&>W_(Q(@2'%#\7%...9_4\(O 5J?H2>TRG-56A(GKDC/Q K'UQSA#$9'4WD+!=)'QNH@<8 ))A DO^/] U9!#WT; <[?(:F-._!PDWZTLO&]F00G.?.RNG!I+:UO"JUT(5Y-ROS+UMKYQQ88?/AQM+;TV.N+4$\12IF-.QBZ 71,K6'_4X>('[F.DG%8&5[.S28B4=K7:WX+@=0T5OI<0IRFPI@[$%G:0HB ;>]:2EL!E@"_%ZB<.L2?FF8;^MQJM\1Q_QTSQ1(@OI2'UG^U6B.*-Z>H'M8OL4*< .+"MP,CT@QO=&-![;A]\[. *35UM-,Q\VVP;3%GC7F2F\E[:?"$VX.%RP.E")CW X 216U/U6_T-!8T 3B(U%MZ04/ANX8_TZ+SF:8E\82 W;=]85.@,6L*QM;\4Q^?&862UL"[)G8QD[@,DDT&, (T'\>*4^I6[&"VGI?+8*0RVMRRJ7BBSRW=O/=^>H!$VIED4\RAW A)32P16:[_A& -#:^\2!W:U*J:9NA+%8*E_)/2!A7&?6'6^7R> )CW.-1$CLD_4K2ZZ%*8SRM1%89MJ-VHVUH*YSK E%H% SM &W;JY.7DT3&+^R_(CT@%A%(>3"YK!WY$DWN59]72M)L@K>@#3\P;W^>P MWHU@/8JW<4MZ,E#5T0S*G4A_']D_JK NRM$\X,4.?VW9DY+=;="#?AC?EH%;0YS 7RBR^%5Y^(I5J5EZ\3>/,TTG1>3>9[=$&O\9*O2*X*$T@';* ]R-+Y ^?*+D0B%@ 5E0'E;F11&0S.-K/X_TRFV-L.#\.AB6V4$[S"L(LQ:YT0Y&,0R@+)!!J,=90X(JV 0GI[%P#XUCR]I49\B$GIX;",*<_ .L.0C>(@0;ZB9 QG-7=QIIMHIB8C#MB?&TR5BFXB:C-+6II*>X1 L\YRJ^\<*8)^ !J6V\C3=2JG@TKB>LD#LC1NX.XH@'70\E_@51/R_@AL,>B_J>S%O9.NRPD_=?JF* W>Q3W;!Q=1Q##\6+,OG^#[R(_?XC@$V;T6#K=[2 XA_(SRXO*T[43:[T)2C!C%>P FV1IQUKIC>8=&H=9=YHHY'4B4(:M15GC*PHJC0\YHN,*-GK59YUL0ZS.;[.E/$^1 <@3V43!W.+4H-8X-KYV!IE2/;.R[NALRK=RC#D[(T* #N84>32YR#H!^_AZ% A;) ]Q-_6P=2:/@P]R%Q)E@=E G^B(R$VA>TPA)+B8UQS0>$''W24*"[^6CB/[6+3+$FZ"DA]1)WU**F:K!CC"!7?7A'6D 0*+DDVRKKU,K,VFG48"_AVX#[XQP;$3MD-O;_BN;7Y.$X)1!U,'DY*E3L(Y!-"Q+ '^8"("UEC#^RHIP_DUQ,9$WK,MJ:;V+0)+#BEY0.D)9&TPEXT9/_LI!*+;4I9"U!"2D:YC+KZ WQJ#55V6_B1R)=>E$,V=..A8^U'B5=_UI0&W[Y&(!\BYDA;Y<9ML[+U0EE;1S9^Z YKI*:HF] (N>LF80T67F&[]]0 A&1OBKM'CIZC ?*_.6*"):N]B6KM>[DR*B==B4 OE'/<]P5N""7-0?X0&[X;-9?XS?NK@^1_HE<--YO5P6[_J];>F1LX;O>(4SKG&G% !^&MG:=C>/8F7GQ%+ VYU6S/(Y[/R9(TK!Q=UH B+[B1V3S?]"]'RN53%D'@"RGB.$=U]]*&-.X+G"R=VH]F#+=Q@BO8Y6:W.])@KWP +0/9)UJ,RS1RUX>U?0A&_/F=3]@ U&A>6+2LV6KI!2HEW;+_INR 1B(&ZKD\%HM/]*JG9*VQ&< M2.IZ[Y78V5'I"+ R]-& ;9GVS_ .).3(B3TY6SE7)N54_MBJAF7$Z5_KAL@RX7X0N5>CD1D]9^$/65DBU5LK F*J![(U?Z5.3SZM<"%(,FN;K^M>QYRT>,XQ*ADC=GV756%U!E._R1<&E=E"#E4PA JB_(HH?@A%ROBG;V[\BC^6F2/P?#9P8Y1JMQQQG1MFWD242'ZDI8/&G9+:'G "U6 7]_(JE:<4B)J4N#/J$-#*CYK]>"+,$Q/*XS<0H+.-/!Y!'B! :]DP2L9EPJ',VH> 5794$O/0#ZV?P.OVOD)4R8D7U!CK@2Q Y*:(-9 A_O09 ^RV+U&!&1I-&UA%R@Y< ?N:P:ZU[3W*MRYJP^C$GA'WW>=EY4"9AD#AFM9QS(=F'V(9O:-#6K>@$G],&3PH& "#%>E)=F4J?#UPAI@--J6!@J2Q&S22(6;-M?"O\:3H'9#U5.?#QE""Q#;*9G4._; C9@BDE_])MLL[D02^WV\W&;>9_$\.'#!''N%+Q+8#;>^D>#$2Y\YRN"7,)S"]&/X )3ML<)ZP@<1.4 IQMHWA,BR %DBS]>+06B@\(U 0< D_"-=("H=45X]5>;1:$A;W"&VO] ZZ:%+DMLP(7+=,2&V2]]^E'LEU&58Y9(TUC> "K8T-_A/SCK%)0D*3_+F.T8UQLF/^(1MA8ES^RP);;LZ-3>J0_+8TB3XR3FX1>'W !,YG^Y&%O12:MNY=C7841)&J.&3$P1*K:0K#/]K+X$(1%JPU%DL!^1C"ZS$M\)I4 YAXT7=08?K\T:@:RQ%*$S?BF&XB03:FZ0%,DE>UL(6G322\)\,2>59&I_V8T@%2^_^(OW_L$IP7^A^#XIS[T=LY5V[V*F_DB',TCJ-<2?F 61!#(U?FC2M)_9T+E=/PVR)D&)%S1%6N:FWP!4#>B4*%L B@G5>/*(:/L56D8JEL ;30OD+$%3]VBJN3.SU,"7291J#'\?01+A'F-EX].:-P$H W"ST:_ID[/FY_:[/A= M7XRY52GMNRJM'2"@)2';U(ZX$:O_RK^Y%$'\8<_RS*%K2.7N*>6>['UZW'S:SZ- ;(AD7.2%.+9J%7TV*(LJ6/_!MYV[&8?6&C@$R2ZE0N&:A$]T^.=&OK*KPI!D&NJAP)B-V4:0QDLJ 39P9>(T8W%N' ])W]1!$+E&9V[O+/RZ97\KS7M5AO*,NM#.M!]@ECKG-\LWY=(@WF J! :S9]CXZ.DK'=/,R%##!-R.XEV'8[>]J^L'[QC\ TVM#Y=,^9QU,[DTS4QH 2)3>?>%A#W>E?HS[DQ]D?X(#YSQJYCEJ-C3M+K6PF3'_^)U2NR2!P4]@.#!IM3.3 8/.V';9Q\#S&_6/L;Q_P+^'F?46>VW]I]=/<:FNF2@G_CA&@L?6FL'8[HTF:*SKP O);'W@E_\_@]9GG8%[Y:@M)DY!<94$@X75%E5Z3[MWT4SE&@&DS$QF!5EF0CR3%%Y[];^L99M=L"J&@R5T>MB93 >9A<%J@$PAG$$]*)6M'SF17J38E[."^G+B$7%/@\8KR^,(?F-X<(X\AU%656V[& *I3/P>[. CET"#\I!.9V'!R_P$<<=FA(6A3B>1TNR[!1 4)Z@O(D]4B/;71T) K!TS]2$KVC*0[NOP9)Q/=HEZ,IH!3G/M-@*7=]F'X;BPO^L EPTR,ACSZ1'Z\0WQR#M;66W"]9G*=N#F'K(Q*NB,YHYR,Y SN!:T](6/D,L)YJ3Y *?$OX8[63D&T%?R;X"D$A8&DP2NT_;-P16OC: \,:J45=ACFIERL%D D:LTG=XP0 HW8W.L2+WX[3Q?58I?E^TD$SUM\-3DD+6H"^3@K.+@*4'T3^/CRGUNA-M3H&V^ V \N=@NT#;T.)V9#_BT]4=>]CP4.ZD"LY#>HT/@:B8UM,^UF"[*_S+'M2CDP'O5&>3H*YBA,YH_\>8-U: ^[=CN_ZQ'(?-A5O3+-G/19KV:,$99^Q)/]@S\"$8#< :.PGIE[/(XE0IVE"^^^A#>NJF;C4(8'NVSTU>64E(H@+ )J3?N/NG)L1ZD9+'4:'+*D XL[MV,^RBSH^['R-4KP*0?US?.698V?HDMDXK'9^N QMQ6AG6>N$Q:2L$OIDG2?#.MO.4-,R:VB#,WQJZ48&J4;MS52DC_)OZFR7)][;?R!TY30*<$,"*O+WG6WF5.+D7#Q)!B?3J2,')Z=$" S0F5"!ER"">N'TL'X_(NQ(7[3Y24[K-0&,=7*3PMJA3I[KM %$#YITATTK;8]:T@ZG\BCC>K!D([LEB_'2BI<,W9_PX?(()GG#=1+7 5]**0-[ K=3B)+\$H4V,- 1U0X)G1E:!5JN3A3.8&)']4Y/Z*"ET4YIU'1ZCO[K ]&<>$N[.]P%A&DO34[N&B-XTK"XJ^^Z^/P5L*V?GZVCD09N\.IZUWZ-,@4TP+R+4 D*K%G='D=B/\*-OQ['D*GVIK)[]'W:;7=,#612.]E&ZKO5%70<72+':>%B!98SI=4N:FNSS9'[ UJ1P*XDG'!OR$=%NS&%OZ\C-UIIL\E08 54^;1M#86W91CF"W(YC?[)&X7+#&.ZQU=4E%-+XH%:3\0/99%)*X]1 7X:<55G.S !<1>J>D(EY,TYW ;$_7B-PE_MYQ$,A^1*J.(2_+F'PD[OKS9C\1K*S9PNE:Q(Y?N ;B?"!SEL6[@TR4T]=*$# >%!Q2#UW)GSL2:SMR$U/Y/5O)RN@!LQQJ>=NP1&*4Q: ^%%0-,1L?6;-AEKY:L)&M6(\3^B;Y$<:L?3 ]_$&<3QY^X]1.+]6$B.!/->I.O:^]+D9/.E<1MM'BQC,X*8RJ]JG@YS%P'S"TH80 :G-C3!+L7X'./ ^5/%=-EO <ZIVD?P(& ZN7UKH(,8&C;W5+>4;;_U8@C8[]\1GHDRVJ:CR5!A<\=GG2@_I(Z!) >8P%_&C>B ?BL!>W?$U32R52;WE/ /I(%.K-CB _EM=/EGUA([X2:H+B3!' %F8&\S82_SM19IU\&+\PV\-;6>&^]EV [_-57S-U VROD'2^4/W!WXQZ5V9W 9=5FGH\^<=NQ )(6-EPH^'6Q98ITP(Q8BQ/#E='-C;G^$'PG>N(K?7Z!/C./4P]T0Q7]]QW8+F2@! 4@F42U(.VD 1="N:'I^3%;, KIW( _T3UC,343*?ZYKSL=9".7"=#B4QL<0,?>= V.!#O$![:K#Q-6DN(@$DIEUEUT656G/["VSG$?,;9MA/.7N"U>IFW[AN>K,CMF\B HV8V6-),]B]UV*Q^NM1WNH*E]$4B2S53"((DR$?T,#9 ]&9H8E:689:)97&"V[6--V*WP/1S\)V#,(Y]M*+UV$FK@ZW[)5?G%,&/-([ULM6L -XPJLSN2*K/,=<7"4-'>_.R2/V-@)^]6L9RW/_PS8.3! 8QYG$%$!T[^^;N=^R=M />12RWH*JO_4.X>2T$B"R+&840+9\F$P^FIA8==1)I<9($G,O SC/O]WZ(*90I)87BC+ \41L/-5M57'0\W/#2M0,HKDF]79KIF.?%.)58O1#ZE3-D WJ-R:X!7X#>ODNPV WJ/ZWJ&.KF?5C7;\CZFS<&%746Y9S+<"5MK WL3Q-%OS)N7 /SW$8:79Y#^2NC/#(;_X$L39/!U7%1/N0I "'2U7&Q>Q$Y8ZM@<)TQTGSJ*Y@VC? D5)0TSD&N4?=Y8@X%49IY3N[3(]$9F^1(I', * 8[FARX'ZTV;!.EZ%M69D1PHX7 P<_^Y(.@;*/YV2WSSD1.L&(4C,)KA"IM07CZY([6PL7:D+Q>^LK-T5,$Y2A1!J^[ ][AJ8+- IK;M=(\$UXIQ>KXRW)RLL^@>P^TBB^ZN"C[V4%S\$$U%._?PV;2GL[G8 @5#*!Z -QW-!RUJS),PL3V_;//4/X4\R"PMRNL]+@ \!3@G&;/S"S^9/XQ'BT>IU *IDI#3&#=,/!KL(MU&U9-@ /W#DZBO:!2*0K38ZO) $8X=##WY82I/$D=MY"$'PL)3HL6/1ZW"L/_<'CNAQ@M\ Y4F-LV3&B<0=F%_;DC2F^:R1AW.C6///"IAHLP9+,BAU]6T,11<]\X<;5$&^@0[F .VY,+T9RM-XUYQ?'\'#_ 888I4!WSS.9'D_IR!NW+]Z7V:MI&%O]/':DHAMC[)7IPFH\W!V>:D:3 O4>M^XB\#$>^&9S,)V_@I/IRAY.B BI3N?)<_OM?L^;OA5!HMQZ45\2NI$]48VXY=C@^L@TT+ D I@PZRKY\(S>PQMNI6CN(68(1TS45KPLOG,)HE ,UX[=EN$_J6;-+(Q)C+4 @5 ?X$H);>?"V.+V--I[).$IV01;.V*)2B9MN[)TQ^YA>]L#?9&["MV4(MXS0]/S-B[ .@&N*?_RX(H7L;)D)&6GER/1<910W$J9S1>18,-P!N3*3=V;/V]PA E(B-ZLV[DS]_(#<-R1SUG.DE)8@?7W$G-JU8]SKV =UHF.S/ESOQ<=AD&VY'9-\ ),8_5<:)C\:LU 3J^!N68WNQL2;V2UX@"W][<(>'"1"S<%!NQN?K\:2FXU^TF0@[ R:'RTQ"=43I[XO4)H'SITP4/>X5S'5D/U+Q0,G0%B!$DUB].@07YRLA4HPOE:F*W 0> HO4?I@5RLOVX+7^TU"VGBI A8$F:CY6@NA6NB!X:VL_$/S^V@ S+@B +?K*IZSNC2#$.F'=425FN(;L^;(1"Z^E">C5\PH[_N"\>H2M_G4Z(,1X/IN*@P5=7;J6 )DO3;TFO8>)V"VV-"\)MW@V)QR+346*HW0025B$W.#PAZ:CI4_&S/UI,[)W88DD+ WXC[I;7@NDC-S+IK1B3 Y[D\4AX[IEESP,E/-(P9KOJ?H'K(=4& CBC-Z28Y#WT'/"?U3_!'/T=J7?A8X0<7,<%=NZAX@RU ;7*ZM\?9$)J$W B$Z@$<7E7.L0*22EIK#7(V;>!S2!)[BNU/K$JZNJ]V5.QQ+HC> )MG./G<>2\S72 JR/P+MGU$9!R:N"%J?P !#=OF39RQ/KI."N6!0G^40#\FLJ.8)\N[^R+5].;<5\.-I^,A^,:S<=AG0QLAI%T<" T+.*Q,'ATW;;6SEW&G@HQ#F.X_;6#%AX72 <8$WA[_[L(/E@MPOT?)=E+1T(^;0.0R79A1G8+9K=K\3NMG,LS=@D/Z+/RH/ ;30 QM)QWJ.T'*G!I\$?:-5Q!HU3HQ/]ZL%_!B?DO(;;R+(37(K?+N9NZ];FYM&O70(% HSD2B,G16)38#^3'"I2&:8;:$R53&'/QY E^[N/HT1O3]<'OSM4 ='B-P,G:>( ] [O"78NQ-'*JHD[;K]#G\.0=Z1DV)#%A1$1PA1E>)A8##2?%W'4Z"<-*[IE'&,GZ? 19*Z&^*Q/P>:U2PXLMQ29/01.!<0&[%#*#'*P!Y^7V7U#_$:=(C;T_W=+7X;KQ[6 ,DKKL[,E]\4RN0Y0]M?-ZTM1=++Q0QW )9J"4RPW;>Q6*7%:E1P9B7.[)783D (* =]^V0IUG1M;QS)_29(?Z#!HI;1Y5^?_)^G-1)5.VR9I^T>!M5=7>5@L,;#CGTPER 7GUV"5IL84XV[MMHC@7JD3D&CWYIDJ79'1,Q.->M#T%%&:,,_&N;[>G \%J0?XQ" .(WJ__-B&DY]W>4?>X86V$/4_/JF-FY\B+V$Y,>S^/H$:-Y[>$7N3_S\Z)G(_YJU B JA/=Q\UCD@B&I]@//1\3:5C(O[\H/];FFWL(+J+/)T'W.B[8II;TDA&Z:(B:Q]$]X1J3&"RN!"J?VU&J8G<2\)!"6FH+C,WZ"Z!A<%T 2!!$^\#U30-=0C#-519ZE 1SZ9YD,>W2J,-&F@*HJG8@<#6SELQY"#:P76*]%:?$ J1!QTW!AN\2N>$ > ,[3^OBJ7&$\=T]'H#KYONOJKYE/B-.%/=3:D2#6/P"?=W/P JXDMA35H?V:_H*C/=\]W)>'E9*O)&U+[=B^Q//\X[>MLCIALV[FBP,:B6[/S1XL& /IG2N(J-)1/ -.5X]]AI^X.'!V,E761.&HA'PNJ&BR(2AW9)GY/6]:/^.;X*3$]N B<%C9R4?G,+G-U$)'DT5X$ED6;:*;;*HYO.T#HHU@QV]-K%3B4B\/_PX; 5FTN,LH7:_/E#C4%)<@Q85E*<$+,7S)759P)TCL+G1AMTDVS=W929Y(K;: $)73> %90YSI]\5!T^'],G6IIC*L&+R3F[_MS0=BY-VR0;*[S)GDBY-$QJIX=B_,1\Q1D% 7[O_$7DQ;IZ;_-XIY23Z-0I@K B\_O-M=09<7[?.=TR'U09 A]]]PV;"EB7%22VXU%W@]/>N80WHLVM>0&@7>N=S_MPHDU64FQ_3XU;QT"23I2:U QC%\/26!387A-<%YD]"RNUTT LK5>E_RHW%HN^ZTA\@$!X3;9X =IEB.L/,KG?)B*T"H5]TH#&['X*"$'K 2:N^/,&>:M6%P=N[PI_:CC[Q(@5YP!G$#IGW@#",UD$I?<^]2%&+-E7A!M+Y=@G0[+Z,E Y6S5,>*)K8WW5#^ -N$,#Q*0;U"$G%C*Q%([(MXT^ZVHPQ7*+%ELCI&_&M'3/[>. V\KA8NVL'_@K4NH>H"6S%=EBX7-;CP&(C9\%Q .?D.-6 H\C.-'D*$G2:L(:2@-I A^5WIA_?'>BRMJM*@3-%.99!PH:[] TK0OK^8$[-3QF")&Z_<7W5B^_<$O-J^PD= ;?87"+DN"C"QWCZ=^+E,<".J)!V-NT4I'#QG$I&C 0]5D\;-C<@YKXI\8(>>80XSR(:U.&0D XFTGKYV.,\F,R24"J_7&C/"$QV5I/NI.DSB1&FZ1*'_=C2EV[?];U,3YF_O[S6WY Z"Q$QP<>2(];X'7;(0+:(=&16@U\&7_J\R:U,+?*N6;/@-8X7;QMXPYF3^S,6[ES"07K? Z/Q^;4R%X_S[U1O6&/)L! WSX<]CS.*C'*_(HA!V"M,P?"3)^JE\6,8TLU@CJ\4D UQ*;LA:IZ6(2P[ ;(>/V4/V'PFZ.J@V6$14I71<7U QU!=(5Z"H']C[R*Y6'H7Z?=MS8@Q?0]%)<=.-P=8*&S6!J:/&!I6MW765U=:&P06 >$Z9B4=CTV;4*\U1PG(#%(\>6VZDF-7I3,!C'GS+^9&/R WN*,_=EH6!(%49P/"/ 1^='#_407>K=WV31_8_%9,DVM49?GZW5OX%MWAPRF"_(KBS&8?P'.U%\-A%+P3<@ R=]$';#=H5L@B:*GT([X1OOASMN<9]PZI55T;4>D-@7Z>6^!7N:6CNKB3 =XCA.@/?%V[MU?8#1^/[V^WS+-D"1)WDTF,8CG$B&.3GF-AY\[+O\J_SL;:VTDA: RAF5^I%9/IM"+#PX*;[_>SUG?/^&H-VI\[ 8[)ND^;>^L5VX<;>C2 ^28V"MYP>":MS:FQ(/<[^'6-%9#\6=O.@5)2TRY/PH)TX&BOOG[0SS[C\,=!(W S=Z(QG-R V/"3L/SRF?6I<4&&:?Q :Z)(;JZKUFPI3OFRH*LO9C2I.&(]ZRK_601 ]L6_.ZCD9\U^:N,MW3*(O;&@![*] 1FS_8 "2-I@]IJ6_Q&QLH\0S9RB0;RC%/Q(#M&[QML$+@X6#Y6,>LP@O8!7A!0*4<_.>RSU@:2*-ES=_:.,+7 \+3%S0;Y0O]T9ZSF8LDH3D(/I3K9[Q0E(Z@2AS"FP]GZP<<*%.1J'&MB:PV_3U'RBF M*FDV>,0?/);,-TE[??P(+SV?0*![XF%DP#:ML]F<+5R*G_P5DM,E^Q(MEZ38Q2E "AC^$FU_D$2.5OO O3DQKT_6$[SRKL<0P:4XY0.HX=<1@@BW"KNTF%$9\_ V33;@ [5=Z30<]C<38Q/_J)Q]Y,;_LH+M#)\]EXOI'63ZF]X_UL#GI*C@T&&$>2? *V2#7/^'? "NB)CX#TPBE3%5ZS."U[I1ZX3"@A1&;D3&"_#5*=#*:-QA(E[M/+Q> 5:=BD^?KA=L\%VY9,76Y>9N?DUG>,X9?)!O+GE(SF5FMH8B:A[LQ)FZ*H^H!=7KB9)6FUKP*<85>+!L8RZ32L(/A#@[SMD%@Y_>*R &'BPOS\'+G;.1!)[;X>Y6GAK?710G:;@F5U\+FK%PJN^CR;IBU1X6.+-'JW$-GOY GRO1J@U6/^::['@$2^R')6R+11)R_)LW'H,[EJ\T"1)<("8_B<##0.9A$<1:GR3^ U,?\\+#?\A<(P"3^!+HJ)R(?88GR.@/(?M%M;;[!)[[D2$/5D:FSM;7EG[*8Q8#/ <1+/$DO8S98Z6]K%+UW1&6LC4-[XT[^?+7&9&+N9\S_C=1680SG^CG\D=.:TDK< +3;'<^W_DJB7P^AVO:T=3?S(,&0."1<+\1ZLEURP5(T:Q>Y*32%5QRM1AMF>:;[3>]LH4UIF N3B*E>R U;IH,-.:*S1$M9_<'KMR%#0)PL&>N'C6EGBS9!GT+4PC,>100B\ZT;^(1-,CN !* W?]?8R+\K'3]$*.T'/K%N1=;O94YL0J%?$A OP!BOPJ5N?(EN&F!\JEF?F2Z<*M1K>.DO*/,XWHL!Y:N<;[7]93@&_A? ,S"3$\$ .%3GV75N)O4Q]RQ>8"*ZJY0TBNYRLR/2!6B_1-1-K!\_* ,)",WG_,J;"SQT#3_6V(K#[$(/!ARV Q6)VXIG_#.@%J!1- )? -<@%ZRGP 'NWE1=,B%73R77@[$VT$U7GZE F7OYLZ"9"AV1]IXQ*#&?!-P'RY DH^DMC1=ESV:_E"0X6^![>3 ,!;#1*>2M\UE>A/L\[K<1%8IJ:I+SEP\$#]VCS3TBD/F=J$Z&7667-1G6#WRIT/ %CFH?8##D[JC"\*L=0PQ/TUTYYN:)%B:8Y"'&S;Q#HV==/PQGJ]8CNQZOZ(CWQ]S?/B-3+ T>_Y'SRM6#EB?-SA9?)2I8 _ZP/*EN+.=A3J>F$GW SHO$NCZ !<6'>1\#8Z]BA=&9!!C7M>CD*$EYOSV W 7LPQ]@<1T:[$UZH0':-F^ *8.,N]*-%WI 0XII?.9RG /Z[4[!_?0KE*3?-]_'#@-PX^:18X-7M[#0"-W$G1R7 H+N@JAN?@57>NQ>((+5B=(Y=7U6=5YSH ^@N!J3;[Z8_!N MNXF?P-;!Z05 'NDX !Q;&!"= H4W&E\T11F/>F)JT-]D'/0==B:C"+D.()<]L*S#J"! PT3PFO-_:'M8UOZEZ7H>"]P*F?/.J:%VS%[NCZG(M]7[^D,URY@%Y7 ]U!-]D$ :/]\I4$J^0^7[,9Q#F,;/R:T)K(D9DV=ETQ8Z&S[/ VZ8"[CZSH"C]\LUC\FNMQ7 @Q-\SKI:;$R2ORK9.J\)CLZ%]E-B,^E-T/H)F#NT$!TEFT)DLOUV_3((XE'##OM0 -F.4OIM&T&/')Z# /(*Q3?M+&A6A*W23%5XG89CBI\XG#A9.O7LIYE]" UM;>M.D9^D(?P>.D8FE/$"!'Q<&4AW<^?NW>.&T56-5O8M/CFC.&W^%Q&+M>/6(F ^FTRPD.*I;*Q7ENEE#O'7E4&%*Y/9=S^]!HM7,0\!X@ Y;D[N."B_B#M/!5Q8(#5 Z=AUNL1Z0R:#V/$-*81;0,S"*91EF VKX]&"8#&=7F)]G5]MD00NRQZGMS7);$=$ IB$>U5"[TX*N7:;(,IC$P]*GR1K=.K)M4)F8XY(#H\%&UT2S&-:M41U'>5Q. 5VE2,"AV*%/3X35BQ'5R+Y5-A]C'85D8EF:C%UY?+2#<1G3Y:(57EY#'&,HJ>$XU F!PRJM+ST>,C!C^=+>]V(AM],84P"]L51?) J?6M.2F_:2T+?(L@#"G- ^>4Z;%HY/8$K7;A_E\6Y3$$^XY0+@FK*WD_#<9^2F+D F[=IK;A+$*!FXPF5?S75_M'<2<.M.[HQ]QY[3JD8UN _7K+C/2651'I$ZDG"^^#D B?%I[ZIYC'B$P]7B ;C)PS&(>MP\02TS-BFEN!,\?(S0" 1_+C3E' )0"AA)X3" I8W&?,\NK,&-UA*!!+O>NS!+S$L+H>*ER+@?Z[<6Z_I41/KGI'23+U?YF)Z?$)<\_4 3?M\[2W8<'G'*+S\6G.AE1!0>1,8R>'(CSR<-H- <]17'I%2J)?M@AK#''^B^$8L X/83)_SP5U+?/9]4X_C60&+*R_Y[8B=RABXU4WX3!L(BN) 7FEP=3=R[2U.+(#"R Y6%+I]"X]##XE"CKN'D1/":F.O2[;KY0;#:8O6N&)K&"AC8>* _->W].O0 89#BP%W/=J(W(X7='U.QIVP7$N+#((/-QDX* N4[V/&]\UOM[TA /WO[)C>B4K$?D+%[UH9HO?X/S_P9)+6I55*.V1H=8? $QE#P:"+Y>R2ORT0^ =_(SP^8JU5[\@0*%I'O)$M3KJX.#'':^5>UR;/\[&%[FR&;ORSX>S73,=-:IW+!J#SRW^&7@ M@]/2$FGZ)C6 ES?9@W[1"WI[!W6K%2'IK?)%'$Q$_2+))3F:BE \=@GYU5#XB&BYO'QK<;YP\XO$ ?*BHEKA+DF$]V/8%T[F#NBC&YT5TCX]KVB%HU(>BW$76' 8=G!R[2E5.D:C$\+RL'6 6=LPU!8B&/]M(Z-D1-+'B!GO/@ZH]:^B!B*DL]F+5=' HLO'0]!&'C???>G\7,!N -!N=*NC_0>B63/#ZW262LWN90S8FXN_,=VPQNWT!?#QD%VLR!W&P)]\3GY(+-&H(CYYQKOY^Q$ESTTYU!!ST@;%RX\#XJD_" .,*@D(W:5&+U&J\AH2R[91C]641Z7@,U^L.L$3HB2,?VP?0-Y2YW-3NVV.O415G3 AKG9)=\.8@4;#@H&><61ESU8J-RLRRPQUS/KF?%5T2KN-0E"=WJ*B/%8J-&/7-B< @ 3O%AN,%32!>'B'9\/%Z'+VJTW96= Q'[,G^XYH =#00T\3 8L-FLQ::7[J$?4Q6L5GXL*Y=+&03E(9$\!2TCJK+SA,#JL8L+AI![VT V?']\IKAEYY/K(+X1ACNWS\\]O/OU)+JI!SL\G+PPD6%AF DC%">I^Y[VF,XY60U V+7U[=_8X43-/V( \7O9=,4(O6H_56OJN!/39! 4,;(E-/+)\@@G'!., P4?^0_/#=J]ZXY1\'^K0PZ<-I:$:'DHZN CN,BTJ;ZXND@U#RCUTL*#H)C+:Z ]O8IT"JQ79$=A:$4-.6@BM)@S7S(0>O/826#P_.A7G_G-^.TJI?DEN%G>U;^QN#OR[>8=[*H&(E,+GM;"T4C. 0E,\#FQLT+TO&T!=1%]#_JY&Q4]M3)O.EG51,2<8)^=R_@Z??$%S9@#5-#C%A_0L $E;!T!]*(-=F>P=$KE 0$7L)5,"CY84Y]@KZES(6X69RE#1!9(D](P98>2 [ GX>N."X'!MBK>IBXJ8=>8X5Q^)\34G\3!HL79L?PV4X*H_7-@D-5Y*,Q.\/R.,1 5P1@;XH,=UXG(9L0AC7;J1YV>)L$O\4N_4?=B[O^=]OT4;CH!"\$_1OTEOWD9_WX "U$DFN7,V!IUZDFN]'83LC=+RJN98Q&U;ME(,#2&Y<83K K]K1%I2!ZYW7C3%>V6;9*EHGG%];J,)MDX(!L.*F\@ :B]A!?>N/-^=*G!V2XC0# BL@S93Z(?DL_ZEMG3 [K>/WD[FM7<5URB- 93&_FNA6%9:U2S>'58$'.5_0LP@CZ )7;/]7DB&E(%<15PVN%E!&_Q ?,C_;3T*,>Y-_472[$@!:"''D@\VC=O4)T5Z7B. %1_S!(B7"/KHD'ZN'0;+EW$CFEYH2TR!*209/!Z9J6D&S!\_23HL:&H[*[S"[ XU -W/-+A?O Q'TC_>/#DCH3A(/)@27DY9)P =)[%(?(V,JSZ_)L[4#W]">$QHVIR^T ][V%F<3AK0:W36RJ=3;#S)LI .L'A>ON,).&K @E(7-U%Y('J:U[9"&Z4(T_)T.G"!+3 #M>KQQ6/NOC4-E85"C=A]?O![+UZ9S"#3 R-[A5NN+89P4)("GY[Y0V[%F,.&\^#>YH.%6(;ZNLKK4XCNQF0W#W%[A^:VI+]'< [DA6U :Z['JAFU2, B*VSSFM6*9FS,D!XIWKHNU-1$II2$4Z%WM=?I_<0#HXT8P_ T%::PM_L@,-S5[04_!S@,53!W @=+0079#78SSG?[KQ\/$3Y2F)O ?$-,4&#BR7)@=M4C/XV\=UI\D,' 27ZQC.G$)H>*&V=VW$?-B1B(N"6N+A['PT<4 9][":AIZ57)53)8-9X)I"&,+R*0EI7@=:("D4_J5&'Q.U&BYO)Z3GYKWP.!ZN.3M 4W7CS;BW^[A,.SHH@F^USO(Y9%T= E*_O;Y$:N4<%F0:!J8"9YWXVP3J-;+$-8=R $-43#C.W^Z![\+N*Y6#Q=8[2WZTFITCS4)\R64N!;($'E1U=YI<8'"C)MSU%'OXP M-LX@$[SF AGIN3NZF_BB'Z=AYGBZ;L^M [6EJ:3<#@=10PT+X[=+ZM!$&D$C> 8OWFX$/T+OMJ4D406DOK]N,PMLNK]A6(WXW 5?TRY05,+(7)]E#^./=3=;C-=N@16X31'Y8?36 /\#6CU=_'_-N;D[^ACG_76BS*JF35= V]QJ67B\QIP)K.[JV$'?,V7H-YDO:8'0> YD60(+?YJH->%8:MO7B$D$BIVX+Y'&,4OX0X@%4A/9)=M1G!&BJ0[O?YQ_?L)AIGXO>\5 QJ->V@G1N[]2"S6-,I$ZTV(]2H89.'[;PRT0]#R30RU>S2\MEPJ?NFNOGM!XWKV &E):7>SOO98]!>" H?!>!:D[ ;M66ZRRP[N+]+A/"%JO&AR<'8W7Q37/*"O6W J& E]]F9>KTOX(.VZHWFR!WR$8D0??#AG#YP7'7KF.4;?"9H,AL;P!8"4!&>P8>1 D83:QCMX_PR57Z9_?B-"<7-TK-6.=PEYI,;BS3(D@S-AXR&75!BIT3GH/\"$F)43 J]_.D%%:M6-9B"@2,17:/1> WU4IEN#_N"K(X EM5Z11\J5 GK(77Z+Z8_Q;[K[V 66$B$*QG0]UUJ@4+1/;P=Q)-=V^8TLVG#NT)1?-'E>3&')*2IA#@A[]SK^(NDE5* O0O"WN)S.45SN6BBB-V=M&O7<]$$I]EPJ )ZAF>#+";/?WE(VD)3=T)7FTO_YZL" =?-P;^&/K#H5FC7BQ=)2%L'/T&+[PE;6=Y%9OPEH SKA!'(@MZ2Z2W98$+C%B:Y.XH5C"?2>[;Z$^)OCDMQ76E86_&@2Y6LO:MC-#F/,5 YSTEV!#5.2[A];\&):'3]U]3M:(?PC=!28:KMHDEE9\I98B<^LZZ0'"?6#IOMD2G V-8D4S@.>LG>:F_QF:A\R;0M3Y_\<8,[>/@_DV1@[Z;1#,'$'V-D7-Z[GOU'-,B' $7^_:_ WZC%T*ALK,;HUOG+-<74C5?W.K ^1)Q;[7K.ZNN/-W"N'H6XOSL@.PWKR1_ V;GV K2>8XPQ"[!L"L4W;,6[0FD7^^1F@!J/;5!YAH%\SB/^0G( @J#^/X-'X=JVR)'.N ?/6AYQ=3B#4$?(PY$(3'JEJ0+F:A&]L=X@;8+IZQ=,SN31><)I ='"GH&0>WAYAN CC!(0: &.@KRU7NG8W+1\B&\N;_D^0!ML 69&:04W]GJ^%8ZP6^CLFBDV>-3GNE#;$,*B[9M/3D9@GS;0A)T-5M&@6#Q\0W>OF P88;BX=X%UJS!LB=5(JO"RM9;JLO:6$V>5%6X$NR>L@%9G*9TAKGAN:]C@B9Q\R& '8!V-_DN_HY4_/#]G[4S;6Y&FXFVLTE=*.R/OD7H.H8._WC^N>):7CE0]-YI8)]4 ;F_W;'$J]9B,1,Y@T"<.%WKM>8!.2/E)R8&R15@[_$\%+A*!GQ^MSUB6E)#X&>K% Y(N"(D"EA:Y[@ME@:$ SZ_MD19L'Z,ZZ*0[+5[FTN;Y."NIZX/5N]UH=FP,/ZW6* 36$0.66J**WCY3!^%7D.W,?=YOSRES$=;,@? ,N.*S\BED"Y[<>_0@(DBJ;F "=!@6$J"8V6, 'QH$_-MG3EF8CAN24295<$\Z/^O )I(M@2IZ3?49B8U)5UDD-D87P:F/,?#GIF%IDM('!]%;[(FB&]$YEQ*EUE#ZWMA/'\HV:$(6W:.#136 PIY;Y5+2ATDJ[MIE2W#XPD&.\W9.$HL1MZ S8PB!%R/<$%>R1X-NM]>Z)1K:S61? V]#>FY#KSBGH;B91J"TZ#I#H*P:N:9BC5UT_YE% ZRZ5"MY,4(,KK@CM,^C@6?R? RK"=2 V'EXW_X/N@0B^D,P:FSP6+BJ.N@%Z4BZ*0<$L1BL/#,S8L#*U4".+_4]G% 7Y)H!9YA"AM!?/Y?45 # 0-$(BXB^MYC,#40V>+K(E9]>0$H;2\$PH2?2MG?*F2" !P2<0IS:I,%)_ZD>QI1_)Q(4][>J/(!3_I?H8" >7A,#J;]#>$4T8&'HANI(@58: P%RV*>-\8YVM<5*EVMGW\_A!86V\'R!T>V8%3:4 )E3L>E4X%"ZG'<03/+GXG9%, ;.JM$Y/%>">*'K2N!4J#'(?3-S/86A'Q3>-@- !? ?TQD< )+G0 "Q>-\K R-$\ZR4+7JHQ [RK&Y6W.&U^$X3&%+47LW0)^$N!2&C_[=)6O]#? S=!8'[QE=8;57@:3!0&AS?KF=,JL*0N\")_5AA_"VB//[&L(@FFQ.FYNV!<0 HV_ 8OR?.1OS2NGFY^T(-C/TY'=2;=!7UO%UW_SS3HI@F&GHZ>_&O\LIRK]W<> \XXZ@ 3JU(6OWDNF@>9C!Y)&6@&8Y!AI5C 59Y)(]7\1_[%/%ZV=UW#8A>Q8XF#>ADJX[0?S'HW.&L#6VD2_DU 4I<6<91C#V <2US;_478?/Q$J?]NC&ZI<69I2,V4;.$:)5&2B["@N*MZPC9@ 5BC[ABX_$2VT!WDF]*YI-3+B4ZB2^$9;@.:-F+M-FPX(<68G"2Y^T)('K@G7^RV7 0.\-Z;K^L,HP2D493&U-G]1OE;"$[[-5UFJMAQ:*P%Z, M')R^KG\!Z7B3N%92B,P(];O)G="YA\<@:4K477F0O)1D\^[IL"F[B3B#)L*8:1; [N)Y_?!2*1WS,Y20L31*@T 3F-;*_S=*'0C9I15QO!5#IX=AS%$]R&Q$/@&$;.>K LT2>LF!@]+^C64A%JTME;O6]0X4G4^=S\$UIXK8"0,C&==G2XASY[?D6W20D>3"& E@,, A'@B)"GERUP1QBY:S[9]@SD!%O1:W6+KZ@"J%^S@:%1?\XN :9$I@JXAC4 V(H@%S-0)$(O=AJ+N$58B"8A5^,FG6K'9:0?I@BFWY+,L7C37X0RQ+[)EW,KR2(> ZXU5"V)Q_@HB,C)$_O<$QX@R4>[N_N-#KIYUP!2>F@Z#R\..K(C/364"(SS3F[MD LL67Z >XP!:VRSDMVFVL7_CF(Q$& , GXT>TPX.XXRL)H7:U6>YMWA8),"'BX8V1 MOA]DA_UX*X\5#55._ %0 _Q)F?UF>JW+VM"1>3I%"I:OAG\29WX5C[A D%/)6T< XRC&?JF[L%[8G*O59*V%J%8-?XM 4EHOL6R^6M4GC,BM860WX@-U8O\D:F'>HEBO \D?BY[$[]#*S(=-#^N\'0%)*!V?)T5U(60JL-[PVF^7S W+SY8OT]:$^/=_D!\ ?M%-4 ,?83LT1#%_^DAQF8 C*YRWQPNR54@SH-W^?>E3CI.==1% H0XMZOA,LO#'3N&Y3W NE/MRJ+X]@)+Z!['CY*4;X/M_]N8(H,$),*M;7;7]6:I?7(P0[ 151.+D!YZ]J;= &ME%CVO,>Q TNWHUT%"_ZF4*@ ;GYG^8\>U"XRY-,?@6W(-5A>U\L-FDEZR%-<8% @8U('BF00 (QC>6<+ODJ[+F#,T9J)V*>E^HC .^\N<'"]L=)T:ICM>?:ECG*7.$,>1;[(3.9Z?YC*N8@5A;([ O%,SZM:S[?-H738CSNW9?1?.O0D^'Q@$UXGL]E] =;HD -7I',?E14+GX"FE%6@S ](BDRO!I=F>L[V69[>.*O[T?T\)-0PN5AVF #QH=$PH]@,FDSZ.-A926;6.D*3P? 4+[EP@]QZEZP1\L:LI*![SL^O*$I\=?@!Z>S G[+(H26T:TU-K31)Q\OS%RE1L6T M0EW^C_X1RM2;V2MU0Y?*T2OH)-3Q!1\OG\U(:4_,5V$RO! @AC'0%)*1(7POG4 V 5FS+YM>I>OOGL"!,@7Z3DQ\ ADZ/, %-\*/Z5WDX.T(YVVG,OHR-D].CVB"[.? V!!ITN:6Z.Q+".H!7$7?.PV!>$77^K4B"Q_%FM*LNPV*V=O@MH0WC>IU6U+\$I[8 ,>&I'KP:3K=9:#0Z>#L!"9;/@V/H)[583(J<.@]* T6:[.=N=_(CYC"&0<&Y_E:OD-K%PL,B*'L9*>#3+69?/Y4>)G]Y,VO69A1-:-H3Y @X_MZUH1=A9:^EY5%X8RZ76GW\I7@?KUT$5%B]1L:163RVK [[U]2;"D^D$PVG=^A1W^!GH\O[D)3A ME7(:0T(^ 4#&G8GA^H+: JDGA6=H&_2 BA8+ ]M7B]F7*HNVGI(^2M51Q6Z('?=Q#HS6T;X/S]]=@2)V2"[$2 F.)UQ2&"JV$6@!_H)B2E_3M-Q'>*3*"%35Q/\W<;CEDAST#4C[N^%\DN)_B6Q1!S H-GB/O#^)K0IWO+0-,(:N?E$;?-$$?\\X$T._-^A/"439@KL(P1Z)"%R<&:EA$_- 7",8RO.&HCEP?8'I3J>ZCMBF->!ZAHD0KGMUT-C 5DF&Y-%#SYY^ N56Z77JM@_ 9 "A':":5+^YL-RD0@6+T[NA$OU!A_];--L!%ENSI[)4($6]/#WT>M)M]YI\JB; ^ZW:>RD]@RZ>,"M*)(\MU6YU1*-7WA F8T%! %4@RG"DE='PE)#38=J918X8,2B" ^/=U$VY^$RZ3R4KR8A*W$CPMMWOAVAIJ[7U9VKQ]",K]OG?8[!?6_ D"&'BI3F22N&$NFNU2[_/2T6=NDPVH.8*M0VBF 1H],D'3*9?<<+ MJO=(AX50.M3)$%>6@ IB.[7$SL2AKR:R&$F#\DC3G)9$G_A W83H=&56>]\Y$HL (#!D;?@U'%5/4T"K&I/!M%P@!-C1;:TBI$(X<08KAQ=&;AR7&H^92)56V4=A(O"] \2_0[9J_ &XVJ_ (61:?O! 3\M05DJB7]_8,+))E$CF?_P5L,AMP%5I/1T1U;-=" 9AVG2&]T\NX8X@5PK NIYV)M,B [X,)N[2/%2L0*MY=;&6R+4VB:1 W9P5N(#[\M,9V@@V9(@'1!+*_L*T)]I*ZXDDJ@9(%\9S72/BRX]#)JK9,&4VHEM# W* F),<4JE+>B\>]GHIW+:9' %I QQ@P#COXY<\,*.:*W/GH;A/U"]C)#',"7':;?/K.<);0!B*_":I\P2BZ+3 2>R5J GQFS*GSV$V1R.;RZBYY0W9HM(.96I%MQK>V7"]0#GX^GS+P!DG_+VOBV2P HQS 0\#S0V-:7#?J,R#5M&R"B_'TAMZCDF="&2>MM:'MF6;F\X@'86Y((>_F+S=3 P!L@X\)W$'"63K%9G6V07,G]'F1?Y ;H*D\,O YMNM2>10(, /7@2S[O4R$K$CW% !;C"](^%5D$C?E! 7LHMI<3?IT%MT(J;[%Z2(RH(@DM-]E#T@@]?'(S&)*=^UHO"^P_<2N &%2[J)@_]!1&5T +COYD=0D86"6#"N-2$@T8TIJ]L @D+8(3EA;1!X^PQ[UGT2;I 6I3!F"R+@\/P/D2,)BV@^1/J&=3<_PAJU_[#$=4ZGHCKTTI-.F( AVA$P4N3V#S*2(52/LG@A,=C95SLR6$2RS$,MB^?R:RRJYL:TBEK (EH[*N_I^96,)(*&1O;Q7H1\S^X8!C5(K@S0YIA/'KR+N&W2#V ,\:2Q]^]E<$J6BP*8>PX@CO#$?<,SV G/W)F*0.,- I+ &%'A]NL$O-6I^-XC_0!' 9(=/29I07I&K>9B*=T;1]B70/>%CR#A!=R1*EI.P>=K<.D'3=1!L 13SNUUB<\IJ %L [ &#$+*NCS];I %R]B/X[/U/]=)2%?&FN)?A[BJF!V(&8./SAG_"2!C9S3RLJ !UZZ44I3E3R@>/-^B1MH/5XJW3J+$8HFH217G]')": F)MR#X:W^=$]0.)]BT]T)L9*R(*):E*7'U9"2>Z UT)?&KXOFX&#E5DX^<<:F\: 60QY\<)2S1YE2*?V$NN#OZ&A? K-9O):M%."0_*XB1W0?9%KW [;DP)UEGG[#B$Y6KM/HM[M9 (^6A4J#9'(NNUO 2?+1! ""1IG,295!]FE"5# Q(*H@'I1_>R*DYV:#2!2K&9Q38 %P\'*&5':U#&YW]3FIHDO^3 6CF-9:W@U_H'R_:C?'EXF17(4H^5)5X["O.*%;*<;B9JX]Q:$?R-)W][^2\.D*L7 .RI*O'*UY6<;:+^(J42%;+R0D'6,E "^'Z*)'/\;JP(!I*^[0>38.7A%UBW8 DZJ Z?% %R%'QA!X[?L1(B.T><)6U^VF85Z!^A.W6+E]HF3R%Q41]1$X[IJL>?(2U' 9 '2H;-PYDJ#QDEJA6T]*05WM.>BVMK[%'F1,7=4S03\$I.++[$9^AD6(;]$)SFSB8 JA%#Z$'KJ#S !,[J;B6:QA,&EOL0AE@,.6M?NGR0 12\YPYPFNGF?(/GM[7EVF)G ,B5C/B3?C[@F5.R1@ZG[Z4"1NU41X-TQ3T,XABG5PSQA[TOZUKK ICY%JIFH N&\(T)5E>Y9_5L!-H;>OH<@0A9=EW?_ :/@6[/8O7D+A*/TX!4R?TNVLG+?76V:& .K:K1/XK<1C0Q4&ITL"WCRHJE6ROCW0\ZZ0S:+-&M SJ9!M. ?N#?'[U3V".23'> BR1FS_%:TZPS^+:WSGRZE_.9@+'A,D]D1N";O[\%RG.$$L!A@5\X,3*4<3\H;-XJ N_*#0^06 VJHE'@<8 ^):?XRK9[ .S"T6=B<9-\#?1F(E&?2;XI*C7AR!4H4KF\R .]3Z/F8%35>4V:1I%Q,1[27FM&ZS%N+^"MZO-.:6$H4YV[_J=1=KX.JYX*HED[V5 T)D76H)%%$F,D_ $>QT$IG>5M1/V)8;L0@;7@9VZGTUN<&L& ^9Z0[=!BRY+A8E. &0O#<9\>.@@8A3VE&9#GSUI$Z=!V'1_L8RJ(UWD?OR[U2_BNM2P9IK"6.PW6:X*.J AO !#ED(H>@V@/E2#*(W,'8A )& RR8(W2-Y[YRP1V&EMV<-QC7U1V@&MMV3,A@8VE46?(HN('JFUC?#]?=ATLFQ )-A_YC=[F1-KUM!N.3FZ6S2HKRZ!P->*J&6'^29U$[-_B>?L63A#+4&/E:!_+)7H 0>P'&4!W05J!<6,@1MX P@^\"Q(%M6-.OSX7%U7_U'.>C Y;7K#SX3:"JWQ3/\>),$ F$;-(^J!(DI4R_Q\T \FGYE%>9:6BE+IZK_?#]+G5:WZ&#=Q%4Q.R1DAC"O(N-6Z(AH+AF5'1Z\3-'.RSW <_H%'_(WDOP^M<3'YEN<1G^:=J7&P5XT"@EM0-B\CD$2Q?=!)^0P'YV_X_'YP(D 3YM#R5G9@?:'I-M"'6'&D++N97946$O!=0>B1K LA%"Z;7>80&"CM]V+?KO)02&,"V-IU>6W ]/2SA)9C8S. W*,;MA+^EK6NA &J ?E$RG"#L@(GG1E7_/?5+%^:]/# \X!?M\OB3H31_$F?VN9?5W]GQ]M@SG;SL"'=K\7#$DIGIYA&*5I]P?AI1XC+;=2 T+SS#Q382A 1I48YEW1;H6T]<\W(U.2#]I(7@ZQGVQP)G 6/5W4(F^@E\Y;VU85) B+%%J)U^(?O \12N <^07*1\,\HQYR%;I>67F,G^6#KG,ODMEJ@ ALO4F^*YC$^B \(;JFA,%0"EA6+#^C+O:R^Z9\K+2=!\-SK:4LJ7%/BWW\ZAW06@;C"WF$ @6:URU/MSQJ$7'0&G>E/VV%I@(D4MT+VRIPB)M2U _ Z.P#.2O^68*UM-!/B?NJ. ,.*0_C%YE"FTGM]%3"IRR*Q"[SG$R]'_6Y72<3 -B.!W =MW#(!CP1W$_BD8JP6!**=E-)S= NE8O:1=](;CJ:LEGS]MZZ[QK0X2><. !R" ,$W&@)A%JML2T6["&%XD=>GM7=$_8L&%_ *L=V6AG)/C+#JEZ(:+V<5?/3MT(D_YNH;4#8DS $F(*C**)J?UZGX B.1#?7QN>>MM\&0IJMZ1KW 182 P%P.HJJQKW,8)_O7/E"'3FBDH.,\V'%&')[[.ST?D\+GS:M4NWB[K9YX"H>U V5"DU2#K35H22_=S+J*=\/>+B:_D62>CQ !:IP(XRJ5ML' R/2I-?ZJ/<-&8:]#$!2(9.3V;N'O!/>A-%"&EA\DYZD2\$H4WGVQS&A/L4'!X(,H F&HE.O*L(,Q"#"5+3"#S6Z??!(M8('5/H@ "710]$>'NL@ ;CF8HQUV$.YM=T>R_)D;0CEBE,2F70 VN65HN]&H\HFQ7H!WQ:[*CM<#OHC:6Q'C CQ>)"-0XP"C[>ST"]8Q#Y54?$G2+:[1T L]<&4/Z$U,BV!IB?\I 9 RRA^-@RS+= (/$S$,9$QHRTJEW;-AIGWO9K]/O/]'%A['.)M98YQ<'-.'E5G3VI\-X_.!>K-]QV0 0.1DIDY%4)"I63KPM*P@D>Z#3]U H5;D>D 89EGT&C-O/.:,3T.O8(719P?,"&IY N:W2:<[-/6Z+J(C3TJ?@T(M1@SQ&ID8>Q;]MOGAL-P%)P'5MUND[50?:WD)B492( '";OOF?F6PL\JLSY_P43LV%MAHCKE!XI.N7_3>V. 67U%CK^R]7(KFMK>%C@,N5F <]A0?G#_;USM>AAG=\<"KLTK%N:M,F&HGZ[NQ"O#!CFR[]/]L9Z?-?9+S-J^(ZI27J:"H7BF7\<,54S"J&ON<]-8WE4[\;8*8^GXM\H H8SLDS@T639W*">P5ZCM7,,ENSV2I8\PHL8C"UD-BR!M'A*PVC[B"2,:N"4N#FXU XY2N0Y;)5JE\E#0 /OM@Z)G4V])TH[75#K)[OX!B\P\&-68 >GPP[C (S]Z27IA/A:@AX4^J;P>R*;R!@Q/S=,B0^163\;N7;M-$7-NHF+@@=DP9:UU2 ]^ FG79&*\6T\]SITQ"PE7X(6K ^K+(P1C, 5H9#2Q3&YU@ @!7#$=K9 *GFYD?22\?3<>FXH4+]7RT:>TRV5.9Q@A5*."N#0940I%NQO#T']#** VSO'RC6K2G*(4"KTPJ B:&.GF$T7 +PYP?K5&48MP-6J3YPN]0'-/\UM.#KEOV,85M30-+ACS".4DN]LYHE "6N$IDYK ^K]T.DY1NJ5'41#M '#8@*#S=IWH-.7';9V@UF'6$VJ#!?B;N DKW*( 94;NC[>E$BP5>7DV;,'U<5)V0L\ANIRFG&R-^8<36H(3%$J?;,<)]6+$;DVYM([2WOA:7=@PD[J2% G>??4@'<;J^LG.M47IFAMFQ JP>"8%#X1* :54R!@1$.@Z?Y-X42EWE C3MIU@)R3:1X_N0\3L&,4 @+/>&&T2;C=\IF(.CM89$AG1Z]+]D-D0O[D6&#!('@ JCGF(/-\9\+GOU;)OVSO' 7]-0L38R0X\)5;@K#)]4$'1_,3 ;RX?6#-L]S0_N//HZM4H>6HV&Y=LV.?=@V9"D?S*A AX0R$2PA6^1#(PX:Q@J1(D %C!U6[/.9Q3)OOW)WP_)\ _$W1PJTE?_!R&)5/+/HQ@=C+"P"]JX-))]CI+@84@( ,&FRFG8TNWL1UU %>?NE3\K_;>9W(/8W!^B9L7!&X 1ZQ*,\MR[ZF'B59C!I&4;6 _5??H+Z#[OK;"CY PT=Z^ORFT13$DD)5_";%5F^H"_OBK.:S2SNX@)'=R@%\C+I< @WA0[!9T_!6,3]7)3QU&I/3;49+$9?#<-'FL:!T>J*;N9R;JGW?( WI&?8NI-^F= 8_W&/62Q_,Q+Z'IYN,*1CN* )B1K2<7>"O='1%["QI6OOR9K94(A$Z]7GY16*W:2 WX312:)U&>C(D/QC#'$MVA@?+NC:Y^(/1],YI273TEXR\67Q#0,!RRG,118)U#CV0[->S'ST[=\7HQDU 66[?<)\]'+:#JEJ^ [?-BZ)A]E HA\2-_QIK7-D,38,<4CZ_,L6:\\_E6BQ_Y#,A6J8!@OR$O(6G5_<\6#=W3\!E+FU "B[:T-K4,-9F:@+1"7.!N(#2P9:$,"01Y :O-B%0,9[9P.#=],C6_2[+IIMHE+H1 QL7 M?H4<>ZT@(:F8T6TIGUZQ6,W17<.N,^N1UW*4 ]N&+:#09O6=9B*QP/TF< 79@Z+N">RI3M8RV@_8YJUKDTO*:G6.5[N9)*MG#N%BD\["0>B#QH[L H.?T6?_7 1@XZ5\(FKA?XFJ'!.VY"5(.KQ3Y[N' *K9FX4:&FM9D^^_PX2D!I-3G 'BK:*L%]CL+E\W1I^?3\:'E2Y$:' 7K7LYT2Y.#HF'S0E=$/XI\'C1)DT!@P."[7 YX9?"S%?>C M2(MW23/ZTVJRH4]P+,[/@AYGE(VH=.FWKG8*A@#VM35:7R@,^@RC $*P4E\*M2+11RY$GUD'\G2B_&\U6 AVQ@D%H!"9>#JM,+<1#)@(JEIUW4^OYB+R"(RL!SGLZ;/"W8K>X2RD LE"%W@C5 0OQ!.SI UZJ25[ZX2BZ,G[$21"Z>5&0K0ECII%D?!S**SK6*Y?CI7 3'7QH[(AZ, T!XXT^WQS" X%3YA#0[CRTD!J-,?69^!SG5@Z_>5!%\*FDYR9*W?*%&E=3?OZ+AJ ._3,'IOV@B'+56R0;BR0BFG59;/;K[S<2O4)*ANEP!!](2L8NTQ"O#XYS-!38)3* >87#L_Y47) E3!CG]L.,=)(&&,0/QW-F?>X8O%J^F^4OJ1\&SJI.1'V/=0--V(%' U(Q28B,;JU2"=@NP\*/"&-N]!LSU%]AE2#OUS909 G/O^O2\ HB'MMC)(JZZ%MOH W4KR"1TYF#@W;3Q SL004@WN6EJ-4D>H]; $[1JB/-,<3@\Z>TS!E%)6XH_$4VM= \-#8PH(T,#?U9B-KV()B_@T@HT:&BW'MM]NMGH\0NZ1R:TK./SZ6W%-$4;U^E!%) 975H(@.%_G,X%"E=ADD%>M8+.RNLX:/P1PPS^^[R+R_\A2[8.S2K(R3- Z>.'K:WF/HVL:M-_R>WC],Q_7\O69@9AY'KY=FE+A#%Y]:"O#6'SFRQ>?\1^##CK ?@@TO2!]H$B'8H<&HQ-T$]0S=V;NLQ+&CD_\+]2UGSG6A3*!.2\^67);(N7OAZC1 I$/C%$9M/[8;#<[N/.[W'3-O]'!&PBTT4:)-/X?02SQEZ$HF/4Z"/7"E@TIOJV=+ '?VUO=6IU!04 5\A_6)2Q31-4NMG2Q*PMNL.A]X(,&O0Y* X^$70DF_1<;DW$*VH 9@7\T-X<5>V$M_.]R/5JB)TJ/A"5Q<(E.<[VIVP%8QV49KAM%(PNI;A;$&1XS7!T P'<]# Q4V9@5P89_^"(L#C/*D,^Z]:VF0[&P?_*BG&KWVL=1+/YX8(7!Z$EY&L$K WM7*("#]>J&8YDDD&*$+XS6HAJ>1^D:V(QB>&' GQ!Z ,W&@T:S>+X4&@ U=/BB& S/"";#W=BNA-_TX1"X.O9% L&ZVI/P6]X>&"GC2$^9(-2WI$EQQ,?84>QT+WEQ]17^P_BE_X2< $XA0VRH)@Z;5"+6OG^!%3K9LO?WM0U9C2"?GF#9 !O3X2'CB K28!2GC7=,.W>%/^,*7?YY%.)IU%P*\0O '?@L+&Y(-"16VO1[B\,EAZF4@@:.,P!%T6]=U#K'+,G/2@<' \52L8[!D)-9A4'O&"([R)H+$*U)=,8<.*CJ)LLH$()LO-PC#3-]0$3\%I-RM(+4M 4N?])IWE_6RV( 3&;1E)O^X@SJ:<@NJ3]OG0,%?=8=M,8GLJ6,HMO^/H94\OCZ^% [\ID&619]_N*A1<<@(T(_7Z =,3VY=<36E<"5.8312_C#0,4!.5U=7R^EN$/4 TI /-MYOTUJ>_%K[CS$#.9#Y['((:G*&@GS] W')Z1N%TQXLKB:]DOXCA?0J:V7VE63 A@KDG(]6)VR)WIV3\4"LE:Q3R!I4(_-UQ\05A4FR6MR_5FHB*9,&C4(S''F4\W)6[AXX1@B^E:WQZG@L$ M4#=C^/S$=N"MEU:] 28?+B1TFN@$+0,@5#?0]V\"$*.D7;M_(V\VTCLGQ8I@7@L \ET<)@\ QHON)X(M=1(FM1PX]W_-,]GR78U]A!YA,_:8C:N8&:P0>B$[1RK-T#E%F0[7G81 .GGW;^KD_(B!,^:,E(6VD337S,D:Z+R&U Z="DA]:_ASX?S^2S;:D!-75[.>9Z;2 V7:[X;;HA"NLOQ,["-_DP60P=NV^6:=R<,)3W0 MC7$KNE/H&GG2EED$]8>0(7$/ " '!V2Q/8ZGYP7Z//>S9D)CX2H+H/[_!R1B&$ XW8P2VC$88\*KE7,?U;%HV,9)G T+H"T/OR=M+RUASU=.QMMXG^SZH561-2?A+@6SE3>RP(/!O@^D'G82G*5U\8GB5XU#B#]M\6; QLWX+0FQP+O1V+ @'F UI:;Y#L[<0()\ICJAR(8&%IO8\MJ"Z&W"[4BJTD4-GQ'2 /6-7L#B4\6YFT<%5G*59C&_\2JL\B5,JI\!P>8S80-$R_3P_X?+P:-S%)(H-_Z^B W>3A D#%(>B&RO]!%NOO0&T\_KQJ2"I^USY#F < '%[X.O9PWT[0>1T,.ABJDPPM (=1XAR.]PNVQ?G SVAC !Z-9A:Z"+YX16 MHYAB?89[ J+J]- L1V4 J])3IRO2CZ.O\7!TQ\1G5@OPN.D+;K\0C#JI,/*SQR ;S^UQ(D1\Q=C!#+V/$DB 6+/H(EFL@1P0(.59OZ(]^;[$AQA%(Y^TKPM6;!=4A?LY=9AP7MVLOJW%/Q(!A2U[ W2M$SDZ/ZR!?GMJ'?BLAXU=E2VNEQ9"7KB 3/[G=.\K3OYG$B[%4\CPZU50T%98Y )%I/02R G4ARF0!O)]( OG,A!L& !P5#R!@&5SLO95>-5\JXX>&+E7;I2W_YYKP+ 3;K6%.0J.AIG\N0]PGZ ^IM$6>@HMJ:FG%QW-H-;R ";'H:8<&;]V>/J^22^(^60 X8; -/.G)CAZ/0$=\*MQG5W5+<@9+H;$#[U;!+H@>1<@/L8_,BDN4[9:]8PB$PV 'X!Z<1*"MOFY.S^20IA2_;(6.V\\P4W2V9G"*0-.*:3V^U 1(1W126YGZD#'>*!M &U&2:JXLCY]F;SO"M2T?Y*0Q/AE1FJV@NEO;#M2,G$]P)7_F&6>,U'*X/1C>,3": $U46]9H2T[XF1:*-Z\<.[4\_]-G6/(LAV1%Q3* !]F\#1BXCL[FO#*6&_,R/:./Y NAE>X<7^I&5K_],J9#$1(>,="R!V4 69!7GK:E:X&Y20O 2IC/.91\3+V3UD]JL# U%SJ^1[LEQ$5T.5,U&H])SU5M)XS&#U50D>W6^[/3UXS2OQ67]GE3:@K_CI2@]TY ;#Y;7DNPS.N7[&Y8*1#I77K)-E*:PO&>B956V$(HPXN35$E-*GI72_T&;03&C?#V G(M+LT6+[51!^");J&] DN.[,E6H8>QQ\W)H:>56*IC]D7.:C\]0DHK&A[C48D]$%E66AE#D)!K.Z:DT+R T>RTP'J\24KA0D^&:S&(NGSHQI3->6@2&MB)[Q'7%V804AX^B<>)^7*L\#->,1EX ,USR84F028]&.NQZ/VN_5WE/ZWR<%0,E"#X:G>^^FU8!/K-S7J8MEI*XG Y]7^&I/Z"%Q:O&6I2^R%IN+X+$9(@EZ?6D3U37TK^ZE;P1X>E13//6<18):G2Y=' 7H_&@<)!$8^F^1 IY .\T@F+--=Q92].FA85+!+85A0#,S4KB730F=P= VEJ' 6]<:2XHR [;\;W/N>X1C!T#1B _H#/;0A;["24^[4VZ?@\_0\/SLG/J=E,K#VI(= PS3?T*6Z"X[X0$T8::>=7=UA1IV9EG@,CL(@:6DY3,L7&@/9]@;CV#:_32-I1T-? NJ$2^EI/;/L.C.WE,.#;(B)"K;Z>]#P[C)AC$J93_'S-'1/=%L3NH#>)V2_NO-4U EV)%]F-HNU@[H0V.ZXQX$JCS#)C:+5_VTX@?SUN+WQ56.U'&!CDO8[OUR>6TX"1+ ]\EJ7[*:'HJA_)2PC%!AL5M$B>XCV P,8:3]F50Z-R;%O^C'Z4D*7,*2^EV=%EK- &;5IE5\YV$GJ\N_Y3GE@<7,?[.L U LAZ*4%1DB&\B*?1-CZIIK3L/OUK#ROL(U!DWW*@ARF6>M8:'Z 9J$NQS?(&8EG]P 4J\-_8<0?D&VGPV+K,^UI#A;EL HL:6UN16H6#2BGG+1 C:FU_-)#2'@%QRUQB < P&0;%X*8'*C33IP)*IR[EM,&16E_@, A9C#THO38R\I$$]3+H4V\OWC-CI#<_-5(KN\/Z/YPNS E1U+Z,*\-2BRWD'&V5@\DXNQI2/3K U"E9"MGV?=_)9J2=QS*D\\;)PP4"X\3"N@ #0)F?4.HW%F=U" X(0WUV?FL W(73*+3]?6S<=(X(LC8 KVD-+X;UI!KC0J>,L[< ;S\B 9E]:E>C*;< *PG>WBSN,8^\SP)6Y9L!W&@%^V*UX=;C[P+^H/%(A$>\*2^+ +IY#S^\Z3MYNAG#:[#7Q(92MX'"&1$?TV-P:^RB$;ZUB,&X,.TAZL3,O)#/FUJ5[ @LJ)4>^#X$ _=7PPD<@\"YL%V3MW/,XO;Z'^RJT[V"C5QB9TY\.Z<>\O-\'=NLZ,(%:?%_W&9FF>GUWJ"RLM?&L(+39.S W'V$VT&Q< [CV2O+0& $*/?H>[]'3.F&NM<47/"4%R;C%AKE!#PS->R/28*P\;J4V0*EA,(?AF )">9B<(R5!+P+%MM=Y D1^@*7IAL909]]C=:HX9]8PX&"JOOK!O[C86*^S(@ON_& 9Q!Y"63,,]0_KGF!4_4R)($[+OPA;N5X!#S8:EWQPZ$MX"^$0+"[-.T*N<_I6TF6C 8Y19)SX>Q>.1/*2\CV.P-;SF!.1GNK+B\*N!LPE'UF$]^__1";[T^UE<6<[#CJ@BXS9?UI[E I $VX79$D0?*^XR67,PP=X.HW9P01R3$L"Y]2N!-%02HASK\O(_(]>FR!/V'H8^( 5W&?D*"("E!B5@P)Y$.#5\BYA?I]%E(2]M7YFRD"-?L (UUE%/25G(:OB2C"\K M \_;F5KBB#S46G:W5A"AR$-.D]!VC*UDHQB9&V7H86#68IV2HE8\?S&:FD\T12A%V C.)*YAGE-=HTLE[&R>93?8GO8J]?;8H&A*AW6F1"G4Y/3%NDC#N^XDIT,QMWG6B& <\0P2Z=;Q1)R-POU-]\WVWR^6GAJ8EZ,:,A9/E5+@_>BGK]A\?G/!Q.NF<3(/ZA' !0W&&ITKM! W?G7')%,)RZ[[6$,$WPY8NL32M4=[#9IY"'^U*3IF-@\C8_KU6IN, =3J4>AH?O%NQ&9RLSL0_-<^TE#KTN'H%SNQPT7J$TO]=4 )#\5.W$X]V5.ERP]^/ C)BW!7+.+1HSK0!S>?MQ17+ND@QI>=W;Y9/1ES4 B=-]$N#"SN;-*&F_?CQVCCK; 7>MD@8G!%@LRX:U4)!1.UB4?AMC'A^9\A4$3<1)A:M2%D\U&A&A\-GQ$+@ =3F5X7NB;@SX[#B?A[!7'WRN6[:;2LB=G6JBW3DTO^UF0M5KDA85.[$Y"X?TK@+O/S61%U"UX'27 ]O:87X[4,'H!A/?$51-]M-.> VO_)FHM"2KIO?_HSF+P=B17GW$,UYC,D33_H!]%3!JH,@F2W*R0'NK2S5J5\\(&? J.EKR=?)LF,D'I N*(DWG'Z@-.J:YWZ0)$X+T%=KK:7SPC'](0C]-7Q9#Q']_G%6 FT7P@%NH&Y>B3]/D3XGP)*W#1V<@6B2 C2 P\WR:G,< @A[(>!U"8GB#E&AR^>AD93P;,M!N/\TE:9<::JH1%.,JGJ7'*[J.DG;K-9]G8=H<@6K6)CM,'-RHB9 /:\@<[F*27:_= Q J1">F[*E7@?0FC^>LX39B_VP.I VQ=41_I =73@>,]P%[%D>S86??1&#P?0C;JA%N"<>+7RI$V:V2RLVCH(FI9#KB)J=E-_CU0J M] 8NXA0?*!/@;3NN>0[1I+PSGQ2P&Q 4%E#IPB0SZJK<862-:CV^EM/9?/Y GC4 @XFG_M'<\;&:CE=CCJ.$FCMKZ!"G2NHO"[^4H"F!1=)^*10D)A);S-UA@,21&ZZ/ J'FX_NX2_ES?UUAB=N4K KJS:WQ,KZJN(-;U,+,V+1E_/(G"G^%H-64A#/O=Q$4 68#U^@8)^]-Q2-_$!+&&)X7LD\_]T]^@$IZ3[?:%$&'ECCI;5#O3[2R-ZP0VZ116 \C;M:1/)W>O66)X\<[AX3=B^?/U2G9B*XF:I[J_(Q0MH@DA9WC6QG8P<";2AIXJ4 55C,&EO@F'0T%< B>%>!U3@&@W;QU;_7<%O'7[A((%(P>PGW=8KPCLE9>YK#EO$T 7'\11Q,< 2.7DA@L$.-*833B:I$PVYHQ\)9 /&J3I$>)509H/JKU('JW-47D&,>D ZK\T__F<&<$'__#!*$(R2G+YZWE C;%<+VD*#3ZP3',R:0K/6M6796I4GL@7: ACUX"!,=L ?$NPWMYY'6F32-'4@?'[NHM&E'"BOSVQKOCB/$5WKGKCMZA<.K>J+L 6=IY#EY;/+[E)BRUHE&HR'4!T =[L1,J8=S1W#C?W9.GG#@!8(V_6]I"IS$M=7AU P'Z6;VDDW>ECIR:/CV1G)EIVQZ(]7:"#&\X05^S/\^SW.F&CR^4G\4S9IKR@I5\B QU'S##Y%96T+1#6,B*4X6\$628D=WI?YG6-8!>,P[HJ9>6_6E&(CS@%X+\_:_L*/ RB;LQ\/2]V@1T16H1&JUF',V_I%JC>#!.\/&H .R>D9(J2*<,3BFY0> G^1@3&_O %RR 'GYZ6)2\ H),N%?F'TRP;WM'+>"Q387:9ZW53.!R>IM1DV0C,*Q5/^TX,G^& 2]%7BLQS"HYZ0;X2J%'[2*-(9Y1>0?[>2W2V=FKO0IO.F\N=V[" GC'Z4-S![($IX37,3M@M'2:99"2&L7SMH9P68 ?DB5V&7*5145=P=.2Z\4\H81T];=O2"Q+\6U6WYL@Z42YV^GX4C/;HQP+RJSW06# T4"+DX)/U6@C(]P/R?TU+O;.6$%>F(^+0V<2=\?7W0^!][-?J*$J'!+W(C+B?//H )RQ'QOX["7L'F#]2JBCQ_[T4^T17$_]V8;^,6TKER+H;-*X*-BTL9A4;;,X'@-2 I37\Y)NU$<8\5[4QTQC@02]* \R WF@J^1( 1>2IV+R$'H(9A$R(M.CWGBD5X]<^&2/N^I.=N(V2*]74)0RU9[SP*%V$%9P2/V/Z 40S'&IF&0F-;(:W13<_&9-8K]/4<:I),BA()6 \@67*O+@FV ^Q)]=F+VAD1 O7.'MZX[B#9D$73Q%19^F;MP8"?Y>G>Q(>30=N,X>5R,2'::]NF5D"P?P6J)84. 5$:F9YX+]C5#5IQ]QNM#9SG_G!=I*7CVL\16RF@X#"L 0#@>*O]2.U=;MU#'6JSB ^^A @?88XUFEHL:E9(O+BWB4X"+Z\[#J1,N8ET*# H89%2UST/_B6;']'^V#CHE7 5&JS7_J8"(]4#U' B,MLG*_?'8R0G>TL4#)'339!RPRO;6(>$GK(.S%^3O0W>&J* L%G9YR*V$?_4DSUM$-?W0J7;Z?*)['0"+I8TS0"Z&/!-6M('=^I08K_JSD? MP%?@4C\MBM ;9BR;TF,.BR!)6]=P*SLB16@V2R*(B2!'\V/ML)EW+B>)P.^O27S 'HC)$/U5?98(-V ^GX,F%]0>T#L=,1TS=-B-(2L8>U/Q[M?7J!.8_CF[8E;;TE9P B$+'T^0/2E4-.\&K .Y<(/*B0$'^C7L9X$[ZP_T7?(31TG$<&Q!X5E\[^W-Y)O&> 0=6=#0N":>'ER97C\W=1":%C^!LX?(\-K/=C&M'8E^QUO"%!W;^P(OEKXE-K+=J? S!V[SNJ2IRNV(48 3Q+[4^X$4X$DM7<8FRO91MV+(W"FHFY*I;H4GTD 6OAJ@&B\JQ"+H5P?635@GL!"R5YA4B"C?)U #'.D&1_9(\421Y2^*@. TIG@Q;G#A:LF:8#K@1D+/]5S3W;")SYC%@LZI$H1]Y<> GF]>W&=H&0!##.NLZ9D),V<9)E4=5!;VYG>J4U=PG1FG1X[H P\&3O *.S?S_&+S LH"G#Q]3>H VZ^>C0VM=#?/Z@XEUAR15W3W;L;\>-::16:[O2B^$%)95>0?]-I:Y 5=N@31&$$2N=IMR$.@J QRO] >KR&0.*.8UBFX;Q2V=RW-%"TPZO +0Y#[3BN>Z&QD]V!:5PVE^RJ(Q"GD_ 2&S(I(U:@&2X];*4RB_)Q2[+9P:-56?Q^SW:_/L(,9,O1H_!==O/$M(4>-/F&:0& /:.2UU75T9R ;_8!N#9W?D OUX;>?>0;2$+Y/E&$5<&/W V>L=2)+0@2VIO85*:. *#G26(K%O9AEE"(]Y@IAB3E+/!%/U&NZXN+!*X4C4L5B]9')B968W)W,6C;\.G!9CFJGB1("%#G9+-%SE=@GU-:ZE88?:-HBYM%K M*P&3D7#";#/*!46ID \NU8,UK8.X0,?M _A ; 4 MV4PAF%H\)7=D;'74!J0:H[?A ):)*&_YKD^8#Z3@YQWH:XED8Y)X'=HY#_8!' A])EQ@=5?71870-?'CI9RPDKT=1R6>" /V$FP&Z3[T^P.VV;:$7BT1] :<(QC2Q OZ#=CF-/L1!5A,VG0/D,)N =XK&D>3*C3DL28?C$V-(4G3-,!>\=Q X=(&;:17>V+?'W$. C5UDNK?D$1R!0N3.N%J;'NA01!/F*O$:^;F,\@4+:RF8'DWV.(QV,T!2+_AA"489 T!\\U]^'^ZC]/DHS=T"DY69$7ZM?/*'@1@D;@OL@<-L?FO #.R::%L?662,_+&GN&5:\)(15R&JO.RBE$/[62I#LD^PC3%Q C:NX(@X9#!\BT\L _N(#9M3#$(_R0!31_(!6)BJA$D0CDXT"_MC!8_4$\-(P]^U]&NPWR)*K254//ZHHB@O-/31$)0+HRD 'OXXB87)@!FLZW(E&SPP%*C0.7Q+.K8)]M#]]5-:$[[)'!5(\QO80DYK0!I*WUTR 4#7XC*+6YL]+G=*F!EBW.O"ATK2T\+[2<&DG5AY.;/$Z#@KQ1CY#; O,(B2[6->T G2$,Q3P4)-S;SXSP#V_S%F#,,.P+X/7#,(>8A)DU)\$\>>\#.>O_>8%$$0A$]5TY@FOG@N=\1@:+QEM8QZ #.E=V?'ROQN**# ?G(H.CQR#Y;M+HLG[1]3U@O/H=^^B!,'9*@VAT($&UW0+V3ARP3$^*3 L2D00:CV&%'AAV:\RWM\T9?S\ RFCCI!CW]7(Q4L<)=@YK,3X(SPY*<7>)!>K/'SL1V[P?Y4KZA1^8 [Y0YI8;KXW(>)+&CY&-!W^S_-2)". VXA)G!X(,G)NBA_#P&&E6"+>.YOKW!4J]4>FPM\(6\CGT8UI;"Y.M( 0[OW*J\++ HAUY%/ T?\;"(TT2@HV>T;AOW:AXT.^8>SV4C.KZ]_Q,BVR8(F:X'\MXD59?.X%0IVH;-*AG/9['R3>@##G &S$L+Y):M^S0-@/PB^]NL(.C5G-J!W0ML0FL:JNOI\X>$'YJXSS^2H'F:0#&(_=> ^,X!0KL=CY*=C65\"=MFI9441ND8.F6DP\\Q@+?H?3B]\Y6QC6S,]IV=#CQ88,F+ HH6T1S\6K]=]WT2]KVN'O064.,"*9X=R:E^Q+43$U,_WF@C1W7\^ 8Q+A[TE=7H" 6$)7%BA5.V^?_-2L;@I^DQ44C'C;PAC.M/!=.4 "P)HL.UJQ ]!(0;:G7F6OH?VY<:BSICWSJ+IPF<-AM[)B8F=?G8OA>4U)$B8TNHH#C/[N RP7WR_(@O3.?VF&4]L)>_PA#4?=>;W] OTLGPVU$#F(GF<9]0XB.ATC'P8]*L)O/ Y;[V:-EG^T6XLUO23TBA7=0H=9Z\7_];9M!VJ'7&%?#)B(,&,,-8]U18MFBN,!/, %#XK;Z>K$Q)@\ ?M,X2&>ND")2[LX;:GVQSE*\/Q5,H'%.W!("KT)?*J9A4T=9KD 5E^\$/JQ9QL*<,A,!\87&0F'/!<@[5_.FKL/Y*XL$J4$3L$%<8A3C1;8_&D=86_/ W4#V!'U2NBM%9GPO($U[XEPZ0#"-C\#Z+N]EHJ:^TTG! M^SRYE[/-*O\KN@[2$S 4OV)0!$54(4+!?<_!72CR^TQ>3O:ZK(UO^AIK1O,\5*]Q?$:?192*[ +<%)CT-U.KP:R5<@4@(:Z;#U\YZKI8$XJO,X","&="Z,V=.%LI$4Q? C6X8:]K3A %KH"F)!:^=6?">N4\70B3'^*Z/LB3ARJWO P\X//1 NJ<;?_<,SZ"^RLD$=WK[F3);$5U0JHRP'(%H&-!&U,@G\ +"+B"-O- 6_53SX.?/F:E^)(LB7/G@EC3PEB%C:Q0>2!?33X08YBYC%HM&6N1J0YWIWPJH<^8 L%%3'Q]%JOI4D[:M'MY5 \SPT.2_U$A0UR%( V/"P8EG5@C.PWV8(<5UA&6G!]Q3,"HD54[*".F%?9LI4T?N>^K5-E6Y<#!?)-C[$ \4NP8OCA3M#," $I6T?QGBI#$4EUPDI'UBM&-QK]I/10WB=NVYM\,Q*IZ)F-OV!\5:XJ],\&6EKA$"GB9\1*K32*W'J3[LZGK E5DN4L$ 6-$@.(J4S9UQC?/ ]? ETZ_1BEQ VTE5I*.Q)H^NXCS^R5WF$755W2) B<:HSOG9VLK?=GI9D?MUJ;TN;>9@PJ_/-L\;VGH_^5S/96;?8 [WKNWVW33T852Q/5]L^'$9X3_KK(;@%\1I=G!XZGO*JO3TD0^,"@T7/KMPV<"T=- #)BT4B-\6W84!/N,$H9L7*ZF\_)IW40\M9"#-\GZEEV=]^BK7EK]K0=9S-D\\0", UD^34.HBTL]D"E,T=S;O#RF^K!SYALL%:=3CJ_]_J\&^4(#.WI/"V=$8"A#AZF\P :C5_EO"I.YL7B5(=]VGLZB=84&#%AQQ:\>Z?VX@<*J(!_S.3TTIGS%<_,9W0710G N=X6I7EVY:"#/7\U2SJ_\FTJ#/@1HA_#D[C@G79#HLBHB?^-& Y1?'>2K'X%@3!3 *WAS/@VG B*_HIR2DJ"59]/>_<"=1I0)FW_O\44+D??F9T)YK!\/QLI=K96.@*WQ 4EKZP+2G4G0 ;EA$ZHUK;Z"V;N\PQV>0)B?4XF]MLJ -822+0ZGY>*5D5%\A]LY7OIHH&70K>4W"^,<+&WFR)*[=I@2=3[[_>&*77:G5!)) "6.N\["C9HD!@UL_9.4'^ZP.GN5_.<;Y,H-LQN'#Q/ZF^L#,7X#']E0J!$Q):-V2 BG>KA\OOI*+S1GO$K]XT+@XWR5;N,7RI;!&'569[Q>Y"L,XC'^*C4Q6[#5)R,?Z= 6:I8G*??0'K4C2.';JQ6Y9\KW58\2Q;+F ;79IN9;1<2@VRC1QZ?(VEI+<[-"(SZGZ0NC@AU$0"GB'').'@?"+;K*F,4W< &!0A:UU$UJ(']A,V,2$>9V[]@(GK7E^ACH>'IY_YSM>*150!43-;RMF2U+ES=$6B &N5M$AOC&OP.V(49XH<'9(FH9;;%7W,-BO!R@0 HV3CT< #I.Z(,_:H^_"4#__S8 MO"XXZ0_3D0XZP*\L\_ZX^2XE?0M>#-JT:=VHT0Y$/B'A!KL%-:>;R=B[B<3;^;"OULW".O!QFJ_?1*OK%WL,13_Z9D$MT$"2IY;],A<%[P@?0E ?>BKBLQP=O/^TW)5+7(E7&^[+Q>75H3)=AUR!( =DS)MOWF0:W?QX[,3O7_>;?=! <*8;C?R4MI#;)L X1F#>H'!U/^67(L>4E9+% 9B^X"%DS%I+'3OG!R[498L\YBR<^X4>._JG(Q@_]T+DRY Y]P++0"I0\@9PX2#\BI+9;4 HK3%02C(?\6T:(%CO!HOY%TR\65@M-7I. #D.%IG0MIE_D4- T 3HXM"(W($6PG( ZD,V,5OM-30AY-'[?#2*N.]"+RW+QVAG.K:;[4-WR!Y*2<,#-ULBZOG;#G_5$KPX H'4D"^VZWOW8UKU>]N?P.QU6^5.<;434\F-3U*SJ#?UCEZR0KK"43*/29)2["RQE 7_&V8A)XJ[MC^VIE=?)[NH!24?Q&Q8[X1^_)C,3N"9:9A L^M@YF?-'*IV.[*Y0P;0"7"96U27OR2VX5!#Q2SSD[9V$^JL>$9UE+T,.',N@0KO 76B0+1#NESV@P%N;UH^/G,W,&30Z,RS+Q-($H 6^)1^MOTZEZ5.#3=K8B%5)E45/#@AM?4^6(-:9S$,MDZ+)(/)F\T+],6O;.COYB? B-JGNPSJJ11?Z<"5EPZJ"7/7FY[4L[ &O]$2+(./..R[4D#5X,N/A.(\:"H. ?4GW-7+7Q4T$$=^>9^^[H-I9V8+FL%=*UB^Y!\9R@ K:!3QL+1'2EPMJJ6,T:[)@0?#009[A//3*7U"=!XYNP:P4IHAZM:+9H,E$>^VSVI !%\L[*6#X\XJZJU>"E\OH?OA39!HD-?H++6[D]S?9+&^(X^=P&@D0#=&[1DW&? I 3P@6^!(G#41-S)&]ELOFJ";BD1J12@^UZ&[;X(5].2%&IDO97(MJ:VO7 ]Z$'EN$KJ7DA>K-3.59$=*%;RMK2A4 .2X@KED/LR(*K2V#JK 4?)0H'.(*0D/3_NV+]XV^^/1NM*=FN^-D+I)&EB,QV2 !V&!=O >MRNLHD%RZ25!CVWW BN!TR!Z!V[$>M%5&Y4"Q!-L/HT.1,93NIW5"8@/3[_PJ$? 15L;@EYN!("Y>XCZM5[#L3R.K$;'2C\.)WV_XW#A>I7^X;(B4V\GET1S.C[JU^6"D1>RTL8IE U-@*BNAQQPM"BQZXH88-J@]7>NA\@5(D[8*;O"*:K]X.%T35_7,EFRPCPY$CZ@M< T(,^$#,U7-QR)>E.W%\QE"FJ#DI64KH5P\AYA-F:[%918M/\]R1W5HHG=EC(77'!:B$.K^,7Z 1F(1'23?&DZ ,I/:?6BQB]S;D0&$F#-E=3![_^$F3T,76=OC77[RS2T%5 ^J;8J2%B()JKY,.R$' .[#(C"ILP[+: 3G0FEB-&KE4).']6BI3OY&X(0V>@44H23>DQ?!$L7PAKK)&%ZZ5 @E*B].3,29^#$\E_6>!I/#:?5GH_4/6VQ?/V[F^;]I_<9&,'MXB4TJ!>"JVX8:($ -S=S7&%>"XR.3$+T=1_-X\(\I6_:KM[L@*SZPQN@^U$P9,R6/ADN5^ZYS-5\1&/@5W +HX7UF+< .&/*-$QD-#3/!L3H>E1Z+MTR?6AL:90U@)DXF>'&B=S>,35,]? =#I9X!A(UM(BE 4@1W&=BIG?P"7Y+J ,!=0>BY'[MDF(W(4YWL4SA"*S;>CH@]3""YCY%U@/$ZB13Q =EF9[BTKLR-VW(KE'>GF6F)+"HGK8J?_$5^MMXV&)04-T.P[H)%TB)2$,KZ-![Q$ 5-!!NZ5F;#,*8,3- :[(3I(W390=-TJ,O\Y/RO;P.'BP1\F5L>Y A9#TN84()HS\%EGT.M,#@W3+Y5$8; P4%R#F@L?YA+OJ)/NR\2BZM],10\ .$M4#5G+_6\CP:AU1,Z.L1CG7])_O@Q^WV" V=_>R"1)8>FKW-T)"]4B3,4[\\?\JW( K1S%XGQ MZ?(3-Q7>&-8ED36, ,!R/F)S!&O()[ $$_VK* 1Y>OH['"K%'VF7YI4H1)D0JK#M"\?N"6M>)KW"Z%;P? 631=G1GAZ&'RH@N6"5SC=!Y5J8=Z@-N E'KWCCP#L]-4.F'15/9FV);[>F8-G NE +^%U/6?[\DGDF#$.K7SM[C\3 ,YS15'6MYU;C4OVT&6[ES#:/C6EHUY)1M!'.[;QVGM^GGW-U1@[X@B4A+O _^7C$ \A41$HCE)0>]"%C [T3JR#T[8[KAK)QH7DTFG2>[)/]U4\;<@(,?!M)#EI_K:;*!:-J2QCD" 6D5WX<6;P 3JORDVI8_3MHD5< ]'XB*!C$VSI67)9=,J"#O!R?V/[0Y;[S@;E?ZCK<) XH3U6R%WFLNN+!>-^'E91NSZ\F2;KALY>:],1*(=C,PP[BM>G[*I1 A3X89]#E[S @]4T)H?!%N":5GP0(&7+7H_%Q20 $\Y1T-KA"-7T/\Q\.6?D: N'I L_UH '&6W 021)953COR%A$)V"_7\;]QS=7MX521F2%RXP_@&W [B, 4!C0+U(2_$KLO9Z0D,? *=Y!&K'@(=$'$>I1]RM)8O+'=#"L #,0X!)\ REAI.3-XK>NC5.F=$@:@NCO6C^M F_6VR;K&,( 75YME[LH+0:9$E0K&M)%@1T+CN3,RO]L(DRB40Z3!* [%Z;9T0G[1 ]H74ID,V"?^ZB[PRX.V[E"L%%SZMS!ISFP:0:8V,+^ W[IOOSH'+9;DG&(J7L*>@ $ELG&)9B::M)0/Y)H5:;5X!91S!37E55OA*$Q?V>'I:D+F[%- ,'W]X1'\0T7VN'*:[-#)9RJZP^(\1O>D]\0&5E$IMO'1?+0Q!'44D'DM5;099/+) #^DOR G!&ZLA4)P*5V4^ CM807\\#*T2+5E&8(K,%6=>IS+B"A0\TB8QKJ N>L#D /SO7/?CZ.IO%RY39#+)VZ%<=^2BW:LZR!P?=-*$JO*I7-4$\O)U.>H17+$JXV8EC :L?+Z-0: DX5]I;:5+=_4BX:!:O=W\JZ:^#,JZ50<>97-#;D%-Q(!"PJ6JC>Y!JA =7^<8KD^=(RZ>X6 !;-@$06DQ1];Q%'Z^N=WGF'.B:40 /5?H^]*HW.Y$/O'?KD\KWH*K630V9T!DE(:D*'9H (#.ZE'X\ D_\$[+REZP25"H'PR!DQ! &$?GBBN8F8N=&^E7*V4@%SE 1E.V YP#[ISX@) *E);6IJO+E3?YANS)*<7&YN 6\*MR,-L0,N]8J]=U:@0<+2*)OQ3,=2%ED.Q/X&R !O7/B"RI#J-!$?0%NN@B(X7 Z9#\P;X!79N'Z '._(?]9'% 9U74M1H#T]@B\.,&TKC;86\Z=V_)KR" DH YY92\')9-#!Q"#*<,"W6ZU8>;VJ_S>P^C?G1Q5FKW;X#O20-D3^SM); [8@&'X*? . [:-F@\HK%)>2I)KB^2^1HG-LMRB T F^JJ!? 0FR%-<_Z2&K-/3,@06G(0VHG(J,I)K!\:^+HEP1EOM4.,LE61$ZT-8ME4\Y4DJ ;#PWY-'H??JQ]$]#+#WAHU5+00[&_\1LS;0&SA,)M5$BL?2F,\%IQ7GPM/=1LS]-3.II0\TZI9@D H?YX DTK0&XG2%VI3NT#=<'F8/K$#.X1\TU@%GVV:J ;PDOW.7@7"=NH O[5>OL%)(Z_M\6C$Z^@,L 0=*I ;#@R4EX[0L@F+YSK(_D(+*$ -;-N9(OR+[XNMX\52;)9W+U6PF0?(20**$3*;1"Y^6J&TMM@+9<2TOCG%B'TW[$[ F$:S#W1HF[&RO24-*/Z /\C3/1F'=$NMBS=WZF5=4DI/.-+H//Y1:&(4"Z[8U--, N2&@IWV;8_4/F6&A/'NO7#CC9*/GA! F79 '+KQK?JO0:)/)I2!W>21?U/S2R-SS0[-ENY.@6H08OVO&1 (EW3Y5AUF =F8[:+5E 8G5Z0\=I$AS^D8 U<.<0.PUQ =1LQ;%^/V RF+%C]2?N#+QAPIG@_T? (291H&!*U,PWVT]V3->'8T/I$:+9^]9IF9X4;\P5&'9Y9@=BE=C:OX7(#$KB, )% '0(+YXP=C8*R[!(#UQ?. +T<"6\45_$9!6$EQG%IOQ5E#KQC@;@=#-Y[L$E12*&* DMHJ,?#KUMN^?0A*[%G+?F"PEN'C#UKTODR$4L^L(G#]U'JYW?CW[8(NV+-/:*:> AQG]&LP(A:#J%T=]EG$*/CH(O0YJ-5@NFZ6R_R.<>>2%/?S+A4!L<,JWJ.3@\SEZ EBKH8DI68"J[\JDTYFM[P4-&>\JA\$'=A_3[FR/F<46S6_-R&G<;W\$+OV1IR%*^ R^R5Y0U W-0@G3>@DU 6EM%G$O'_PT$-A4(K$[A*=//HOK9F"Y8\H\F8O8-@6XC&'^'%68IUA]%]CVC-9GK -RX.Z#,*3)NCLUONJ$.?<#**])H?/)*G*8\1<]KPR&_*+J8*230FIYIO8H"1KUE1 _J@$U% 5O/W#F*+:/%33HT5KQ.-=_"+%GHK4K=N^>%TV"_R-:1BSJ+7K]VZD697 :(EX1T0,./QJV5#(6*0H[ ;0,QC?!#RD3)V>"BY0"U@G(Z![+-+?.*INP[*'0/NJ?ZI08Y-#NW4M8' ;6#CTU< S2GSM6M*D@U0X9;YZ*-_MSW>VA;B&MHL$P&]-D>?!U[L0F 58#L.S3N(4]/TJ3JNRQD=X]FQ;Q 1[ V6=EP)(<06ENQ1K=R!@A5?7GH5U09&,K)F$D/T\-DJGN:/-,QV@;N)&,92U^8 XOG_634HGU'XC'C3F=:A'*E'B;/19 <@DQS8D?9L[%'EU&.FHDI;G$!S6&^F5[#RU!IL[=I !#XAVCC!_@J(E _L4$EG0U 0#,R[66#.IQM-?]APVQ[(0T#0QF_SGB/+7V3*A&6=,& %@@KO7L&@!.V];30F>WD Q,9C/V&+I.QI?=>@\!*^>*G?F1\IU!1U(3<\RWAR-:I%]D(/U(@?T^F.@3*?S/D+ [6SE94S?&A^48BH]#+ I<95>97MIQMRPXGX"#2?M89MZLW5.O5X7*)>;\4PF#1PXCGD0PGD_*#/VB'$VX8A KP\A2TM*KWZ00 @NXIO,40+*3SF!-H$C3(B(VQU_,J07K%R*UZ=&0.>9;.4TP=P3 (U+G2>G*5.+RO:;(6:\^;5/-'DK^OVN\X,_'VP+S']O6-0$T[8 UE'CCTZ^^6(_L "[88>2KLB>86SYL%E!?=](2=*221 ,"]'5?V%!2:&TX2>[>RTDJN0Y\/HF_9E]2? 77$=&3"N"1@^XYG/Z:)2G3'D14(]1"F, <7;KX))A@#\FX&PORKP\5\%D2W0E&^/ ]4CV-9UXR2_ZF[2O0F='Q[;5GK7#28S]H&;:>/D2NJ7(GE%J3:PJY_%#E*U9#%1( 2?Z5!4)@I* >)I@&BMMZ%:CT 1ZT1%1EYZP5S[V'.W=%:\@G+?YHG/"AG XWOG6& KK#Y#6.UG(B//^R2"E])O$=A>@L+U7MU#,[)2"-/9-D7[PA*,67W'14OYPK=GD([Q-&6HQ%=IGT]( > A )CEPR%O/.XT2I#?6[&:+1SJOX+3+=AX)5[MXF=FA(2^^W/7A5V<: ]*"S[XL9-=T N-E,S$++^SX^O363%,J<5Z/[ Q&>DU9 ^T*E\SRM E&4"%7V0[7;*+K_305PJDGT 6Q$F=S?EWBI.7;NUBJJUYV73A,WNV:RX*8)9@<#C-D^^A3-QKM])2)[?.]C64S>0 \N'_R74/*%/"V[2.BBYZIV<(^3D*%&D(+22DW)4"ODGKCR=_*>][3.D$=A#54V$# +I+=3XEU.%@/L7I*7W5"(WLSKN_-":;@ ]KWK(KOU&FW OJ*I "&,+:""0V7X[G^981-OI:$J)='E9<]@C2V))=>R*EH:EK45 'BN-1IN!FQ>CYA#WK&9-,ULJF+R_IQC-]AB'1CW=&<9;&/*I9.@B^R3@^ EX-1D/ 63]VC+X!UT7GQ58MSBX;M5W*D67(29Q;Y]]GK:"^9ZA41*YD0BMX -Q2CN[I9C@"KK-0PXV%E""]9B/*NMKLKDA$W>$9: [RZWOT7_M+WZUPZ?WG$H"=Y,NOIM4W^-/]?DXLG3;UQ;6GB EU&9[?Z@ NQ5W"#[7CAP *NF:IT)I\$=,\=^F+G>;U]B%$,S6[I#@J4H9X3E*PUB-#TUK$G)*F#P+FB#@\_&3G/F>R381FE#4AO7 !P* *;LDQV/K?,*A29B.!K+15%LIW,#A/_HDYR*DV2V5)<O&/]XZ&T./)]BZR$=@0/GR(H!$UC=4/KO8&H^D>. 4P+KN>@)0*7Q@@ &_JH?$X.S]P4C#XU/0L10L3UFFOYY*N1FMKP;NZK]\X2*: CV/DNN!FV$S<)>Y@\P^SY\$ *#:#_GG'YSNU/=,VHE5X4X5T9B6@ 2"F1E$.ZZER6L476;:,4R._$2TW/PS;1CSG AB+/8;LD::92AAFJYT8GJ=,R9S5>_2JQXO)>^]Y[O[HSFH"?-4D82C\=$H./\94J=5;3*P5A[J\:J NOO $G.CLC1.=H;0+5N'?T;;WVNN^I1 JWK[1?8!#1/S3JN&\TP\@_*H>M(]J?WV W3O()'N?AX(,0@PSRK!6(UIP5YZX56Z&N\2O"EJ%;.W&6%N^'S=MQW,O&'!?QG,6 &664VYZ4&O-^F2.5XV5?19:T8SJW[I?VJ<*>_CPJ&A-UD]Z9#DF XFY(T0#VHQY* ]-UY)(EKTEP+"G1K\L[XT@54T/M$]N<4!F*O\X.?RG^ZL^:G1C@G/KK>$C:E(Z15 J?^V6RJ]1A>=1J#_% "+"^$0,I_RXJ17!8RH%SLF8_ZN+,H!";JIB.UK!,[9S4V3 9V%,7Z5HD%V6=AV&5]2B55Y8Y?D4 0E,+(DH#HR>^A=O\2,"-&?VX@1#$^1@.L@Z !VDDBA]$Q&:L _!![?G2=B4 3526XT&]CM=]:*F()Q-=B75L?",G-!XO6F-DSQ6X%6!0C;[JFMT#\QR4X9$K?<2+TV0?,HOUHJTDJ3$I'NS+$*23-K7(]Y?M@[O3")SXE%K%, 2L,*O2*\2P8 2".R18IK\!2P;L%WOQ(-?26118N$3B] 8,UI9\Z"'OJR +?_,%B?&C5!Z=$GM0K3W4(D@@'L9FN<#@UHTBQOQ6LA9KM@GKL0 U\=Z4MFMG\@@"^V!#L'.1&5R>V#%4BK\6-29Z(D&SSW+@"]*&]378?DT)-:(+HUJ LW/QV^OAK'=0=I4C"_L0U4DU02N-H1*^;-9;E-MTT$^UY/"=>RO@!TX U^>7O4A] -R00AK#\Z6H_VX4@Q(^/WSC@"$7:*LRC?GZ>'H_DI!L&/[)F*#/F\X#E;_)LQ!6R B^KR /.(G;![18NJ>W?PP53H$GRU&X,MA:K9&CI,UD]7:3.5I.[!.B/^H6?-\2,Y <@8[69,:>KT/1RT@Q%(>*P'X;9$LH)!1PYZ44?<(T*]%#CS#\5*'R:Y[P-OAF/ U LGAI(OEH\0UIV!XI+62\/X%,KNLIM*[[X5)*!+/]()^P)1 '(SC^EV3V=#;\Q86C[D<0#%,3?!]^E9$=X9^G_S_H&3PYR^O.7XK5GG$.59SM'IK I*MVTL),;O!=7V'1"B"MPDR@/I[?:>HO\<[(#<'A_=."8HG">3'JENA?D\X2ZNR8 37(; +OY#='\UL7\&8\Y<&,8/P1FXV1-JXD.E/"\3D=(,FY X/.JUP"1:::WQ9I! CY*T5+S8E >KYSB?-8[4D=%?+Q,<.]@5?";!&5JT=2,D-6B5$ 4IDP@KO0T3"V-! US*M]6D!:J,@ZY0M$9C"FJ!+9YR_[RGL&RX;6NF7TDCC^+S'2U,UU',T/>&2&,]@ ''9<072F!M>N8QW#K]VHG1Y]#\R&6^)1&HQ1\C3RV'C#]#C\G7C\Q3?X@TIIB7CH '>5K/<2%18U^NQQ^\1@$2\,V,\W3]@1=T19U+8-!.2K^<*9D8Q43F5+G1)A']'%< ;?H> 14V<_\N!$"\YAVC#,->.@,/D%>=Q-)\L)E/B:(@D^QY26>AT$X@ZP6 GNA, )MHL8-0OVB:6\O*./@"\K?/)+F"#.WKV+QNQ)/';+SB]:F_WS_&!8P#54(5?;-JT IOEW!&WT^V ;F*<2M66@2G7LQ)S"VP16X0.^?\9U#JR6&\>$ *<$&#,'0Q:9>Y P 4M5V$K0^TOI](*4Q.8PXHFV_Y:-8*CBSA>7F@P4C%]7*KO:.FHCP1J;V&&+0<^E? /4"ZCX!X,K#?/3]OXT?\:_N#;&X7I9RV>US5(NPHFQ2-4WEX7 1'?'2XI"E7TZLU H:%]UW.2!]S@ 2NI'9?8^]I !_9P!"9HFGT4 ^O,[A=3^"3R_4"#TI\D91:U@LC!7_2U+.UO_WK>#6@*(M(N(!ZKVV[ )CA8"*14DX6=]KD 1@6QZEDK2V Y!5T'^!-H:&<4VOT @+AI3. [824SF_4T;O -^P8PI!)K[XL<$.^@!6C4L9@/X[T J_F71]$L#IS8NRBSLF:')!G"$/5NVTN,&V7'7L:E&X'*O0!O\I$.?8WC)=5X7PGIQ&-_A6/,()>6G%V 5SYK#P#4H&>^Q#G?@0#GP;VM*/!22U@<7O==;XV'Y/R)21-!D$L8CD.,S3:F4SA@ &[F>@C9KXO?NAW".JB-D 0;0XHPWU@&8;B#084-Q$%]$5:=3!IU/ Q*U2O%,2L;= 4[3:^[7TPF B=8>L(^-E-)>\DJ_>(O OATRV?W?A8- W:L^>%68JJYL%EU/X/CN6 .^O/7[ *T&*>9[3[4\B:*OXMB%7"VA9'=K:,Z_P#&&)[45'G XD]B9&E]2$YRUNDWY/@!8 ]DCY?,!>Y%D,R#28SQ1JRJC6AGM_\I.Q#H91H8AHLG 2^]Y[KA;^?X/&N>\_>@;^DD&CU"9.3L20F>\)"9/:#W4]!H$PF"B\(?4#Q@HJ-^= 74D,AHC7^1!$:E'1*@@RA^L]\J\Y+L8BT@*1C_K&Y=ID!\\0 OE,\W&C9F[\Y)*EQ<%^7'14+=*":->^[-@;2%O 0_* $W.&SYV$Y<,%VIG--W6\+L%IE_ XH+@!J4VNA>8IQB5T6XDZS/7&SZI>I[/_M+KB!@!XDKAP3DNDXKG7T&,1*O.X F> [YA+K1H$N?:,7DK"U'N]I4XL-+#1>_?=K@E2+BLN!"$VO0/[DX+=(HCM$K7]A-E2 )>6-MG65%X(P+LF5"E=!7DFWA76O/H)'T0J8Q'4=F4 I\JU[U?X ,=SOU?]&%N6JH\39-)W $'3K+JGZFZ!JW\3YZC.N5"> F[3J2#1 H*.C?99+;:9:,R*I3?M97+YW%\@:5 7206W"<8FIP'::]CKP]6<01UH&+O*Y:;I4 6A1MSPPQ\ _&*PIW]K5E^"]VW\/D'1D^U,XQRM,J3GV[4#'#,1.9+I/Y@%V4 U.$H[UIL>-)'7'93/(XTN>+TP<*1QNYNT 5;RT?W7?1U_6P^].F#4/K#Y=X@T'3=C+73[N9EUID,#UC90O%V6T2EG+T)Z4=R=/ "=JL+Y$^M[H%#:=:Z8Y,#LO4?=PF2K4;3XHP P7/&I2FGWL*.WC[>J82RPM6 7>:!A [XYUN<^Z,YP[+,A,@ZYC*AUKH)XLW2"D<-*CSS,MYP\;LZ:6Z*C ,Y=\9TI);,;Z U'@8]N[\N(;^H\H_<1>\(%A#-N59EGW15UXORYOV5E_XG%I ,4'Q0W/C,C7K]DR& 4%NG3))[WUI$%)0W^R=#J#XZ?#0E"Z!;:-6\PWL<8Z,[BD%^FH?5HY$CB8O;HS11 S]I/IC3R+=S=Y$\DQ6]@WXZ.8WUF*Y@*V"AE*P@WAE2ZSH:EN\7\@D1#JH6G(!@I =2K/UC+U?9$K012XRQ8X-4 W&EJ-"4FJ4%('_GV../+70X A8[@@2=!-R #V@U*W ,1Q_*?@=C'P5['+E&6I_--.5:KP.0L7!IK?N%= BD,3&9'.UU$KGCOLG&4.OF,3;XV )E<\#=^JDMRC:':NP7A:Z$0N)1PTF96?F9:! XUJ*KCPY8:P8M !*1G7U.;-(4>,ZN*'>8ZN'R,\E)N;6@#N%XF9'0,"7&TU_QR+- 2K5X#0C3A/.N2@@ -(3L?#C?_FFY*2 3;1;VZ*(&QC5M,]I$S57PLA&HI&PVRM0WL5>BW?+&B;_Q+$W6+&81,4S@<8*& '] ^&?_2.X&DT_7V/#4V:RPK^$IY8#-F1*X5,.T95*F:YF!5YD3*P!;E?,XUO0WY&Z& 9*B8WN)]=^GR['MMW9]X9U^._1KT[DD?QRU:&&"S"(B)/1.;%#F?-;7JW9_)(4[61 ^&QS.3PA@C"1Y'\0<1UB#J/ 4;]9VJ R3K2'658[Q7=[]6Q!CK@TVC[ O'(IKZ* O/105D^Z+H)>@(*EGD9G5]5XQU<]S!'&!<'%VZN[:XJ$=WFR&FO+(8^=0.RR* N:X'!A78>IR*NL5;4?",H6*?<+=4/3]](&;'+BD +&7)8'Q(XMVONQ) 6&I_*7,C $,S^]_G@W5K,QX>55P.C]WFXN1.M)J8\;);HWQ\?W.;0?KV6([ I;D2;'1^KE!96 Y_9H&?B8.3V8%%J>'R=""H":@,17TW#F_@957\1PO&UEV=!_D<2<^O(09]@RFGPUIN=KWE@[,(-D2>(CZ4]Q(XLC6W[_ +=9U71;Q[7Z;Z-79^&Z/9C__3H[5!E9-JY1H.W;\\%=;PA:F@M1P8?J>1#X@'T02$XU-OVNOH/ A*KOX7-(*I-Z)7(_?Y[ MX6F8D>PRC/_MF7%)15)0 &>$IRS41CJ2?YE+VRL>'9)!R/"OH"K8Z"OG0T@1 ,6 V;?=F\R>L,_6_ T?C^^:0DB%7[?+Z_#NQJ]A6^C =KFO6?H24R\)IGQ43^25X 9T^]0ZJ@O36.*T##,?J9B-,: T6^GQU+\%B9V$.R)"I;MX5FR!6A;CDF-!K]&2CJ 1J:[DHBALN4"F3)_HBOD XNN+I W)VUO1L(U:*X:^L]W)DS!6Q6$J\E=!)ZGI+*3 92;R Z,;LRZXF#O:H>5%PU,4TZSB!>RXN.ZIW->V5R6_ X!*M,/(\0>[KB,]%[1* 5B#+=0^T\6YOH@"7Y["C[J;L03$9^]/AHV .G(L+8XE40?/E%)DQ[25D0+.3GZ!6 L^W$U/*D!1+<7_C&=U?'^^_] AE#LT*@Q[#=& B4TV4)Y8==5J"L QKX(ZTQZR+2G+*Q(H71;3(6> E9[_1?MH.=O*3BB-#=E;_ZR? LN%\WY@X]43X@?6967*8/2>4&L>R]7^#9[M?/)Q847=8^CAYU1JS;NYP_8O(G R;WNOM=K#^4<(S"59A/;5U:LQ6^E5[/^<@Z-IG$V147K9E LFFSYH^06!A#A%)5P ^IBR>BB4MM7 '%N>P)&SEU747T2BF2&!1OH 0&.9POKRS18 XB;#Q99?"R/7V_7X "[EY'BZUS*\]XGP)DM&CO<+-];+LG55DH,8Q(1#"E#(<0+3%1! U%K\^-C('\X)7 "*X[LR]X(XJU;<3V'6OJ*_S^C=]J*E@' PZ0<.@^KB%(7#R]$_2K@7@E!D1TV*^. \\2!JE/%=0##2<@9_T<>4B2?_\AM'$OCT,$;,0C8T\8[E&M :@/40Y[CN^SO#$'' E5D#.PY@YH0X.A9"N!![VT:EZ=CUT*92$"!AVPLR0[%(#(1I&*8 7!2O$Q8XDB2: OE$;?\<4[^X$)E-/>$-SZIJGUOC]Y\6&.OIJI]&A/6X,'X>8!G[A1[/3>]>V\/X& 61]JE1)-?O=0&H6!@XNJRXD!FOHI;FJR34/CXG%/[6/#)E4,^)P9Z[_.97T:PP8G :&=7E/\.1B>G9<5H_4?H]IL#'RCFIGBJ:P&?JL>#N\5D_(3-4\\Z<&\6!LT _498\]U/.6X%P1=6W1L/C.4"C+?92:*''T[\LS,\9I7ZJT2Z3F4'"N2 QE\!W#%XA]/H@Y_\:QUD8VFU=;F5F?AEDHI!]$);=CFI4]DP]$0>-8*@(YZ;[P10 T'*T8& "V09+#;0[Y$U/9JUW#WA9J\IP@08&D#?,>C;FC:(;[W[O?7$HBTS*?2K8 .-]8E@"?FK@?U4EI9E=EU2-:TKRQE:-A"3[\[#E^+V<]%.) AWYT+@2@?I:2%5]G N6&&^K/ZSV/F',VAHP^:4M/%'FN>YN$NY>X%L\M-1OY;+":7IW4$GJ'A=S"C-DP &;VF*VVHY+Q7EE^C&<3\[G V))ARQQ-_E^2Q$!?]VJ$S:2NK9# #E?4JWR%=RYU2&87W._?;/\UF 88R1XLS*&+H@Z%SRY*/MQ?6"Z7]Z @#!*!VS>GO:,@82#T]^^=QMEV6M!& (!^TQ_ /XT:$\4QX(W9.D4Y.]-=X7/I*EAK,&MG#%NR!ILR4DZ]^E_2&=7U!=H:[ /4!2A.OEU(&U-21XT':Q1"A'&.:]_RZ$N(LL0^.#%S'KC17>H9]["$HQC <>.>NB MC'!@ZO .GT,^8N=.J8$E_MAA9\'T)LQ,JI&*Y'@",,7S74Z$2[\A5/Z/8QU-X3E%_=HO9]/7O4B +$6*BH& LV^PN*@!5Z4\7RA7Q3I\#R%UD(+R[GH$)_01Y5!)=@=2T6(ED-"-X"K21W#NTEGC @H?";O#D+O>9F-=\6XP2Q@; \;?<][BH /@*2Z]H8')Q59K&^N*=5Y3-]I -1Z(#M?UXT$3I[.5-?TY"TYC>8[J^IU?<86U]!MJ0$JV^MG,OHER!AYR91'/^<0%,=)BF_UF_=MGOGP2$Z244YPL, Z=JP;?LA"D%ZRR8JM8'*DO;RMI^U--A#G)^HCF:/;SC.:9XBQ(KI";^Y,%G \"%% !],4RB/\W*P>2[>K8;K4,S?B$:-)7<[N!33B4:F4^&$Z=EH>A4-O'P>K,%*)J>XS F4D)&1Y6E$C'9$VG)US2 8$W&XD!QPIT[Z). /;O6 &5FB_%HO(.K^O7T"Z\&F4. 0\&C]J$<1.OM_\@(^P-HK2;0S,()@_JYX3A7 :C>-$8P7J7)P$D\FWF.57 '7PQ+ P.3D5S2B_K3#GMF@YI#K/\30/I>;:@*4]3[LU%XT5!_!R?#-.^5E7[)![I5?300 XWL0&@(OC?&D+7#;F)->->V"*0+.:P9!?UV,N[# ,APQA1QJ)*G@V66#%[!F!0WP*OUB=#.>N4#U8@=D;QZ[1K#$OG1A1TD\1%3PJV]+ UW:'@OB:2GN$&Z($77WL:S2.V&U.ZQLUUSR*PL2 9N&&[/FJ$A"D[G^J"N2'5O* I5M(TRLMG:SO4 />+^T,;%-).;;NBJTM]260=QW[I+J8X*M0\P-GOA#D] UFXBK"XU'5O@2K2QS@1T=X1YUZN>S2'(4I&.EA1$::H7%SZ5ZG\:&(F"S&%H"(KN 8@[>$IS4;/36(E(BFKKPDH/I]K_886\?01G3[CBOXZ;*@6CY ATD6U%TP6=&$<@?14X1UPYE?^ 'E8%-&'J6VEMR@7?FR"G4 C)?J%,13==0P^X" 0E*S=Q,##%1O'.:V[GC7>F>%N> J6B'[!LF0@GRU%-GY N&<_ZHTRA6Z*^@SRGSP!LV1NJ,MN?JH+ '\!@UI:?CEN>8 -CI=#[>/IK^\%/,=>VE/[99T+,X80M0Y.\TUP>1.+0LW*Y^T ASE?=R<"NT#"SG[ &F_G&[TL,:1*/?*F&II+%8J@F$#+UR(&)/!K:)4<"2N@-6M:I/8 45P!*OM8-EH45E/(OMJE)]H@%?37<*.EA]Q@T)=1F+J12&=#J>TAT8<)JZQ&!B*) -L,R"IT:_/\/NWK\.44&7O15YG1>;+M^3_)\^?=60W,#JD+T+[2@DEN_B=3Q_U=P #^S5^%>C+J;@NMTW5+B6=1%?0@IO=JOG/)*V/!XT*((-8S4M.GPX%12? >H:=+3F &,:X-=0@'Q,B,OX0YS[EG ";?B& X=^2FGHZ30**FY\*L:*#!Y =AY8%,,J :3#E C5>L9P>.)^E9HMTSQH=1L##)'Z\[(WEL&4_A "P1'=ZKG;,"]M8SJBP5*W6AY@01 Y!31HB*$(M'H&1ETOB6)7RT.S-0P7WYW=SM=ORWE50CXP*]=C7;N188!+EV/\UJ" 0?$8R7 J^2JNOR","(',GS> #;O%1K@X#)XZW]9M44DLTN=("WTU%9K.D*L(I>NG $IBU\C9(-.YOOK]8$76,!,3[+W?>DF'!/2 Y[T="&:UZ@W '=A&G.RW0U20/ ])8$2WZA4^!9"Y#1PP.UX6^S1=]"%7_!7GAO^GB"-63MAZJOW27L M?_TGC_8-*WWBO-,A85;K&V8Q[PY:("A_@((V-RGU)2-+%&C [M>]LZS%^&CO>IF)I6OI+/-UR=CXFU,I\%,_$NM]0SY5:@MH$Q ,S+6%M:0<@4C%DPXG=@2=L*WGKH@ ,"+U#EC2R4&9U3&"<#,\A.#V1O=-[EDGFWW[%#4S'(<+O8:Z2HJ5V&ZZ%&L89M%9 ZH1TN5V9Y]8>8O!$(DI[H*TOX3UZ$"-.F7+#B,])X;/3(!>&7ZE0(.B0',A?^)X] Z=F_[Q+=R-^%4XS8?\N%%]Y21T+8@&AJT?X+%\-HN0U38_F>%.GR3>H%2 :6-R/J 5YZ)2)[;!= Y;)2%H&U:$08CHG-!) +I@K->_4LA$:SO@?74A=]I (Z&?A]7]2GAE(W OTET$LAQDRA!>]WB#[A;L#2=<@6(Q0*T]0-2&?!""A[:F]HW& FH?I%#BYUWT S&KCEH:>29?P>^I#BM>]'MW_/MGJ@7KAF.V3=EIG.R=6BR;Y?7TW%LSB$G'.>3'Y0G$VWS$#71E8EE0##@6,H@(N3/ / =X687M2X7X,8&/_3YOO("^5 ? A)1HNT F, _V_*EN"K%4:0^^6U>@3,R,ZU'7.JO#[SWJ0BOOQ=]GJ.E W@=#_9U59!9TJ^#M+7?[?%M'4=)B:]$L_S7.\#5JN\=$F%/0;KDWH/XW1=2>D*D* 82 W5KX8*6T$0A6/BW?-N=_W,N4_<(IVJAL*-_6=<+67<#U]MIDLSBUJY_6G4BFW J9?; BA2,EI#Y#R9_3P1#B>S1=Q'"Y&S"KFL:8+*=?K00VML-DH^H^4$LF&< SB)XN0!^ ,]8W)E#&6A];4 (FG*;T"$^\C[N8AP6"V23D2WQ;+O3EWJH3 !S>A]#@BKRE.7-P2I2CK2%4:CK4.)'&^'?_CK=O74!5A+S"_C!IJ ME3P^IAU]"$OQ@"@PD%2;2&_50Y'7I@!U8.T=VLR: J>"UTC:.OGTXSUDCU._2("XD>M'^"6_\H6^J $0:WL*Y$OTL6M%26?>P0"J@W/O% 6HN^>LPKN3$Y]T-/=@\%+T$QT(%H-@]6>$0 ):P>*O>R_LLS&QIG!.^M#KWNK/R> &,:IMMO7C<79H?$OS\5_8(#@VV/U<.QX8 2 E]/!YXT#9]>RZP6E;2_5!;@**:GR VCWAWQB4[)%GUQ63DLGQ1?_\;0)S8HL8T2N+>.XEQ1>:;R^7Y 6+6!9GHT6N,G_@ FQ0XC7W_:TB&AD3P_@^MM%U--GF\_U[B,MYRGG#_VJ1KX9>ADN-UDKT&+JU_/E7& _;.Y'S%RIR2^Z/G[40V'(XFFF.AP1Y^<1^D5B)?Y&8?DDSUD[$J&KSLY+X >%\GH U]&=Y^\.>6L?2_L?1=7M5192KM8 Q:UVV=?N ^>=T<:6],7*HUS;EO3 =7GG1?JJR^<8O<#6XX$3*\+==8CVG5>+@NFOJ)PC:\+F#?J.W&?KCNRJ0>">D8)L 5S9<+IY4]$N<'GK=0^F;1]/.#B?@7-S]JO)O6*%I4SP* L*(OKK8N7ZZ?FIWF+O3 ;2,#/.!)[LV*G(88MM3"]AN2PO'1;OY^*HNQKY?,@K_L(CM1!38$SAGJ"[K9H6\# TZKJ=M>OT;\-9J, NT+P5FB9=H=),+4M] 0][^1OK5X0RL:ZWLMV9MPXO#%A26>[ X8918D^KU\>FFA!Z-!28L%ETP%*CBR>)5,=!0JL?RS\:<+V?GV@6&:Q\GB-*[@"[ $@&VF*YK">=O$Q78]/C*8]G\ZHK;B..DCFW+[^LHWS?T(ZCJCQF5[?A''1)':$,D 4O3E0V$-I;=('*% N%]5YE"ZN^;-%FXQJ-Z#D8R14VJIPMAN\)Q1J$++WI.^@K\A "?\;5@SNF)5Z=Q7_% 7C@,T[.2PC\_;)8R:06B9)SI?JD[F.=@\G6W:U*'TD6EDL"@\ZH.$"L7&R? Q()[2R6D<.9$8K E@+V>\0V+G2X))?+8S,CU7L%\B*?L^0S\8-&N+_X:.J+'95R ;P8\A-H(:IR!:16 J+U#T2E"L'#^T>9NAO4M0LL+<,^]V3H-D#W&B%X3I,Y$33?U?V[9>7W9S'@J1+=Q E@0U.P,@ 0>4 (D])6^ "Q%ZJ']OV2M),V[+NZ%4)_G?@0G.]>=2LX% \5:+,G_[ *%T/[NR"$O4E^*<8E.?F7V5)28,\0=)E=\ZA4@W_.@]MH5P$.WE@M Q,9-N314_; S,&[/NG22A9E .N7/A91,[9%%28M^H[;Q8_"ZG#B/O/_9T9\3-+1UY3ZQ/ZN5B9 P,$>XPU[P6FX,FPHF(%-74 C@H($P=89$DWTEII6S\U4@7D<3L/4L*]RJ+D)JF*X D4[6F_AY&E6X AY];WJ@2G?[X"3RR.SY"2M\/0E9)@!+)1NLA ).AZZ;!$T;&DDA="CX5J'C940BXE]OU7C>'^31@[]J K$!<#_2(K1>7_%U>=AR.OB)._Q5@#6C+%>]@(&&N._.R] H)70)I%S'=K3P93I;->Z;A]X7Y/QV-UD8!>-Y#BY=<6 -.]CGMWT+*:T"K\5@E6T W1V)^""G3KWA+?_:0S+%M;=D1+O# 9 E&%+/P_6V].= 2VG-!M>EF3^[/#K[1X V4DN0&ZN\RMCCER2:92J*S$+K4 77C[JX6F&G41 "Z]PF +%G38+H9%A7FBOE>O-O8:$Y_I#W5"/_2=;.;%CVLINAQE<"=5SVA9ZUK*6-*X5Z7 Q8.N_E7UYI$S%)3 V6U^ZG""5G>0XL#3X.BA]% F&_.N-X#\&4H Q4 ,-!(0PO%3 Q,G1+,\NX0A]7R+!>8:$9)HVU:]A6&_C1?EZQ SF#O4@SW#SNVYZR5$)C\0!8J88 88.[H,[&.\M*)W42=_:E:%)E27@E5/4$\,MNF7/;[A3R@'WRF#%1$+X>7TK\*&B87BF_B]=CPOA85,<#1%: 511/*Q/G_H.)D<&MONV66MP$2138-->R;"S)I(Z0>EHH'CDT93\TN!E33^TBQW== G:,6]+T;[MG>Z*X_,<].K[M/6P@O9K)=AEZK36.;]\@SSO 5E,6C6T_U7W$,TVV;)R06O$8JVBS8;I4T1 7YX4!)_(^ZM;?2UL@3R8?HJ [(6_1'7YXA,<65:Y5!.=Q76BD1SR$9EA(KUGQ.^Z$WIN\<)AO;-UYJ&MO4DLI8Z/0$^,3 Q6M''VY4:< HO7XT$O9EKTVK4-K25616Z?T"I)'0_-D1V((2]4WPIALT3"ADIU%? ^,ZEG!4_[1C!EB582"D?Z)1JK!_>ZH=DP4*&%#8. O,@?JLT-J.2=[7-FL#PO7-A TS?VCZ8/YA-)'SZI0SS_(X:[R4+UDDNXT) 0C\A)T)9[MO!MU1.Y,P%G#C*FSW65E4WB1TW*91+RUV@(@/<+]/#=LS/RC.-,0+C(F2U(+2_-O9< ED3-SSE0N-D MV^[@A5QDTDR"VZ=; Z8TFP77 5AK29.6-E; TH/]T*N(H:W'U*+EM5O@G]D+"N3!5*BLE@_=$$%JEXF,>1.)1Y\(0 G8\@.ZE^>(VC]V7H3RFPZ6 $+.D/]AQ;2XT=7U'NU6 P _@[GZ/VZW_/GZ.FW_]/R<'F?.\:1 @3F(=Q%,_B=;96L^ [#&+]R.F[%A,;)1Q[I384[*![L[JX-U-^.6SW\/-K_$HG%83?Q*?]P0 P *F% Q6T3D;!^6T2L6GPJD?^!R\0Q.7D)?CCA=+\U?)&T:C=,[N36T=/+%O)O\N,, K.:''0<.PZFO#UCNRO'J)L7!\G[',1@E#EJH"M4>"8)UBSP $(#M[;V7\M E?B[,[_X)H.=CF#N\?>#8&Z6$B0F+= G_KBN7SX!,+(;]/X6WU^19Y2J^R8=!,(@O2V/F_'W"; 7M*(&\532J%HA6?'2!WJ !#H/T_KUBI/D?)W+5LC4\$ICP.W6/$[GDY-NIX8@3G2*59EI>G'OR*,_Z@K2T2>, *'#N7R(S.E%8.!]"3MD^BF9]4?Y +L]0@A=$"MVV[9AP 3NA4F@SLYVIK#+18IQ)0%OBFW8F2S26[.!TG1T#413/L674).]2>ZGCS(#=)A/]F@+O, F4* 6D$:BU^N!<0%9?FX9DWTCE(KTC6^+ *'LA-!7KZX%6H*ZP77Z6I-&KY3O'6<';S' 0YJYR G<@.EN*U[NPPJOL=*.]#&1O,)$<,L?Q1<#2?BE0:C>[VN?FR,%\B%TLKD8 &XL!AR+@[0'H-@^EB:C8$OH_(6O?_CRV+-O!_Z 5S8\3YV"1(OE[Q\$(OU-CU7>JG.^"1# $[E3A1HM#.]@. 0#F())T#H?K?ZXO.!$(KS@CC'$IL$P0PC#9F$"<8(@SL*P]S4AR1B13UX^ZE;$N< HGMG0$7SF99)8=K6N[0VF#(N]R8#!G[6*2=.B<[L%6J7A%(HP+%G]W$[M%ZRS%JO TM_B+QW+S>71B0A \L(G-*HJBY^-?!E0^1 R91RKLK9+3,PD8.^^,,;YF=;<:1>K G/;,TXBQ,<)V*>'_;W93$D-,!Z?E05JP.!&7K;9S6R<=_YO_S[WN^M^YX$ &K7[Q&C[\'W[((IDJ\2.BVG!Y([M;A?P(K6N=F8/NE\XWI/74WF4D+!EC1R# :Q^ 2ZX\4B]"/7QQB5''%89*W\FF8G/ "4KOK4>_CIET\QFAWK)T[U0O52/%(P'$V/Y$ ^(*#35+9V!9++UP!64\_$F:63I= C6Z#/8*& 1#F[)^LP];?PF%):X#.RL4E =]CM-0>D%D<$SB>N;Z-%YT/4%0 B:===>4+.=26E_T-O0$ K9*6P5T@2,D"&I'^0 Z"(4%-=MNL,PNIL'"8-YVUQQ$KX)J;]#*"!E(!9PGHF)HLV^4RV?W7U3@L95>!B ,:WFP:P?>'#'[4=[TI]^GY=8;*"*C5VPB[ZCM\K2 :!"/81SI@X;>A/OK1XZF(", LX[AI+$['>OD9=V[ENJEFW\]5Z?UV_/X.**)&G+*!BTFGJ]6MGXX+]/]_QLJ%,6Q 4)]\C5=-%;KQ%)O8M:F ?62Q0;",_0)PX_R_:G9,D'F=^ ZK\ &B=.X0EV /G?+X6"$S8E]VV'5WRL&:(XCD$D@K)(?<>@\HXL6J?ULL'=DM5QAGPE@6]TU<5F@ (8Q*H(TO 7]@2+R_$';*25%D(M80IM)@O?P]V/T-CR"ZF7&LH3 ]L]HM#]<^6^KG!\_FSY9CH*,SO#/KV$1F(0P9L"5&V>#63AS.[F?)!6C5?9D12NJ;[MR.X-5MTQ(=JB>@M@) _Y@*Y(CUH)UN':D%M7716LU6*C2_G4;!HHD9XG:+72SA?#R/'4&KLM7PV293ENAB M1"!*F"OOAH,SRA&?5*L2Z,78;,T62P]"I:FG UI=E1$GHP5SXYU$34?M.FL1FIEE5B9N #P&D<) %Z]R,EKIJDDD'>>1CY]-XJ(W^Z@R=P+]U-Z76DS4N];]XU2JR"*=^ KW&H^-Y"<,$,D. LS3%_X>:SF@OW)R,+.CL%VBU&/0W44#+SIS+3Z?4ZL,>3$JZ0 @43%3?$7+RGQ,NQ83T#?;5YH&R-XBA% @$>C9 V"5(0DHG^,+A8*+:P[. -.?V.9 .-?S%\0 G(KS/5&AHX25%J[2I3#8)YB1KBFH6(X"PX%8??1QZ;=BDHY2]*8/XS6+8L$NM=F+MR $T\@I-\E$ X>A_/GM#Q"0PY:-#&*&P.LJ_Q*D*&/4#TOH/"1,8OQFN<E7.8 Y/-W0AKKN:]-I-&=IBN53^@";U6X:,M_8\R-.U0,YT?B&.55E'<&Q;,E)L/JC FT_/L'F^*(Y>!J-=S"##)AUGS6+XFPDTKF,T!NZ1&_D0;'H"B;_ZB1!6@F]BE3N: P19;-@]U1?[G%19C0I@J"UJ#,J *S/9%&76Q6#'J4G,*,,6#P;(7$Z7\\%PRV!S# (22P$&CC<51G_V ?::N*%]H6*OW=&IDID;I;P@3S5:!VH#RB1:?+XQT6SN//CMWU B/W' @EY8)/5!2]<,*U'R>IM0,1;.@!'O0:;XA@76Z??1E";JP1BY,X,5N^6I!/. A63!/F[DLZ G7/YN$/B!)Y*L$0II)A/<6W"D,=9-@8)ISI%54#\(XC+_<)(/*PKM 5,B^I=0RJU>YG-/1)YXS>(+HS0N[L=W<"H^3/LD'(!K.8L*]]?97:ZOI;LC4H[G5 (3'*'GD'B3@=%@@#-F%NEZ)_G0\;9A^,R@"B7NJZTT-M\27KX<) AJ>VU)R;XV$I -9:?@(VG6035.XV(SS(*WTH6Q7L4NALZV:&E@-MV9L;DM#MG&^W]?2GQ>'S#J+Z'=E,+!F8(B^V[Z%CB7,0>* &>D]'2JX1H#05RBRK=@[7A\:V"@9 JK-T?J/V<8R+2LS!-:?^QJ*0T8S01HCRH%J Z,!RG.<26Z*^(5$"N7F@PMKSHJH;2(5.R\YF)] E+:V!L!TOL'1S @#^:.FODWKW 5T-R'W"3N5=F%+RGETZV%U2ZZ-!$F^L07B74-;"RB-O?8X2U 8%2E?BIU@=:F4\#_Y=?VN$Q1KCG7\1:R2>_JHR&4*"H5$RKXFSAJD0??26^P1-T (WP/$J@;N/<6CCZDW!_'U5.W:?A@.A/&@TD:>92F&NMEASMUEO X.JAXM8E8LZV115'@9YHB8<7'=^$KTC5RX*]:%*UXE>"ZKDP+>VW(#:Y:#J._C56M9;F1 =_H,4%5"H"*>PB=(I&T4$0% W&[:CYXW$^/.:I?>X^M/A*XN;_X1&6Y6@2O;9$BF_G(L;,>'KUAF-_9HC-B;@55\ 8&$%/81G0''PZ(G;.8:D_Y#,I)3N40G:;G:FHS)->_$\0K\Q?$YYEO5OCG), L>; H,\,LTN-WG;!@Q*F.PUBL0D_5ZM]OIHNWLF!X*UZ+)<'9;Z?SO11M2357,4^Q!2V ,*KU*4JG8A^_G01;2YS,%NS+K*;O@K8IM&(0R+ 0\:(,^E@\N[NO&N""XB%)_E/V4)7TUJ#D7VE3 DM(+S^ A#77_(&7(7)5K&(C_0OJDD3R'A3<8MX+\43H3T*2# +2ZHI,;_ZI5!@3P H$[-!AV0]$#M5#GYQ<#<03K8+/-#P+<8@(\S\3%_N+R:BR;+<0#=TT[?:XL'('9S '$<(HM[HZ>2PC[:Q.@@]+ 4&P![6^A01/C1;AUF,PJJM*%7<5W(+2W6AMJ+F2RJ) , 0UV/+JBU\$'4C%[0HKM1PKTMQ]>6U+C]Y/T8BI9D1\%5>ZF5#I<2(=!"("YPYS QT\C%'NLC/A@:F%/[1<7<;3?39+77WA!Q-3S2(1MK1+6FKX9'BIJ\%/T7D.[% 3R 7017;#6_2JG^S2<;A1#*FP;ARK..L06,UTAX4PJ5D3;6J (J[A3V7?L5P<FS>%"-\1\*[H'FB; )G\Y!"?Q-'-N*M;E^B'C0*"E>KM_KNL7;+.0&0W!(N_ X6;SE>U&:B;W+?*C1$"E&+O CV>R%0[3+$_M3NQ@Z:7S1:]DOH^JYA'W\S+0;RV,X=!%W8[1T)MTJMMR]EHC6LL- #Z^%3<=W,Y=92H?6!N)U^L;L0X8%MT-^+-U/R7XV1.&RI! ;$L!X)RW\]9&?3T3] ;(.^5>>AW]];(^:RTZOG[6JU>PRKB)/].W.59/Z$>; OBE*&7KGJ?%6;DI"Y5R>I "]9CJD'LVC(Z:H?J^X# >:)Y$WV\5(VE3?JJL.+_A=?A]8(@LD>H'DCJ=#N$M[B6 _GT#RT(\E8-1S.)8E?A\4<;U#T5?JNG/_+KR:!-OM!FHC'RM%W)6%,MR?D@6%%" UXEWS12N ); HJW2[]>5H5-5K?W'&?/%J:6YIY/RA35F\@6."E&Q)([A\J3/N"(/\K5;6T78XY[3'*CM_2@V^7HVNCGMJ'E &.J]#Z^KO#G+8_@<$'ZH86,]/GX@DQ76*5-"W9;0-G<.YSS"%HVF(0,S+KH'X[4J 8?) :+1H#<$%>NH\2+5A"I\2LA'7LVWERT(!8,E)1#@[7F+)V9D2^UZ0.WGH?,1) C\@4MG@ 0NO\7KQ1F'NI%<,_B9,FR*:6QGE-O*3JI@[; &J<^[2# 9R;VJ\QPW?,4[15#7_)>2"4N.HL,*9#5,6QGLEA)T#H3U[<9I ; Y5C"FDX7$B\ 7E#/XU*.GQ_9O,,7_++^9%LI?+,F/)YPL-52\Y )&5#?-(KXS/:.>D*F0OJP(>A3 *P9>Q(4 /3:N'6X#S)*W.A]3=D8>4>+NJ#]V5-LQJ;B5;%)&"VSY3]^_KU@A5);9 %&9T BS_S>TA\YN,R &>"3&S:Q8U7Y-[Y7MHLM]#L-Q+'!-$5P,VELW/N"8YJ:<*A]>OXF0-TD#[V&MGR'DO;\+E7_IO*:]Z;1O U&1;W?92]/#A\5<%MK9Q):_) 0KK77;3LG834/9[+FJNN[-3/Y1C0] GBW>(Z XE2XS8[')_>>9L6FWX]N?]HN6%K TK^MF[. 5#->*;,CMG%(DRFA\PLQ0&/'&"$]AE46+L__@:F!G#76#L@/<9IYJR0: N\W\F+Z/9@OSO>LL!-7)^?SS/ZT=PZ/F3[7[DQ\:EGK2]P<35:9% CRP @;WK'58'E0%3-!G(,NE@VX=TG;4_W)3AZ1"4PK_KRR6>*YK!*XC[*+A:X*IB_^*VB\BE ,::1$2C<%=H' %+H *J+U\IR\0E1!=H Q:2LDSI6*'FCXBM=.1HWH#_FIB1VOHB%KW0!J?U[,*?:< ?C^AQ?#?K50[3[%!"*:RLC&K[YA34%\4R^JY_ WS1I6EBY"YD-F;&3U'@!Y4__)S RQ!;QN/%L\!':&NK^J6!)U%TSA23$*[^5.!1*\,6D6K9;P#\[<.9P_:\%$DQ7J8OUP!>8R#6:'K,4W.BZRZU#E#*K3":BBU$FE/+,0- \>A$\2;%S4D!F<8[!.+-^ZJ@A*(EO'X#=0>D3-@ML@!!3M8#I?WKOHRO-6OF(5[" 45BR@33\3MHTI8N;$[TI2BH*3W;/FAM*0 P5Y:C[@+E*.X61,!):]M*=G&-:%HRF K6]#I@"_R]1B7D1LZ2$67*!X EB_$C,GY",1+,\']-? XSPKLE0>G3<>96=%_ST+ .C2+@@[(#@*,L"-K>&\R:U.==S\0;C)*#5!Y?VOI.77H)=5"XQ2(FVV;1OB*8G>I\4G+:W:)W'[ !# PV<;@;]FN/C15]<$[VHJ_8M'0-OZK.GZ"@7S/(4U:E0_?^&R*B41/.%LV^YN8/4X YKF+965BW4 7#76KNF[X;D&,6##.*;IW39IA\I-(]K21WB/Q*NC(G."::\32%?1T ^_Z.BF1HA4._#1<:W^^U"QD&T>2>3I4"5M=D.PX'ZI$*R*LD!^E;I#;8^@:$4!T1 +8$:=VI^./(?'_!R5-,$):M*B% D%5A_C5CBC44Z!PNZ1$T=:[_-A@K?P$/FE'RS!54WRFK:&I 'GF]EI'D &.[0ZT5V<,Q;/7=-U2 F^<[&MNV2[,[U^PH?R.WN(RLL%G;-]5+\OU"D$$"!&<7>YIK?P*RK67Y^3DNH0NJ O]*GYHL"QO,C[V(]1\9<-#H%@$^:^ZI/96$5IKTX6';'H,8(*1*5$L:Y.,FW$(0!W<)! @A#Y2ABI1<] ;I!\7MQ-2BG:XD.]]-Z,!-#C_:R$J$HP&,U]BONM%KN!HK%LHSS< H!5PW]4'@L(-B@^4G.'Y-'+.GB[@!C-S%@,N5T$9VVW(!63KZQ=5S.Y-B4=5A%NC %6.4'#D!S.)? 0[G=(L-,'!./G=_)FD..!M)7[\(-#:L] =R!\,E7<4L;=*I7GL*< E*LV)'V=;*O"XL%I ZS*7Y0(3>RK0]_M\=F$36.Y0TL@?4_5PR91D*;@YQJ8P./ 2C&S]GDL@M%KN+YGD @6-3^?<,@<6BSOAJH15/BY_+GZ4QY6(<] 9=AJVFPCZV:;[]R,5WI[V1#-OA9LD7 O%U )DUS_=0(CX-\^WW&K25''8/[*N&9%?U-1\VO[=TB@,S_3\2D;B=UK@@05 N= &.5>X]5I>-KGF40JJ+V,;.>"1E=SXB%E\@RTV!%@2U_-V%- OW;\5"3M^NYM$<*KK>'L8H8,E\.^WI1XZ_V$1V1E#V_[!G#I�UB(^K?A$WQ_;R ICMJ.J215Z&5^@ 810U $ [2-IUCC(OWKN'FH9=?XY=_I\$E^]-V/E8+\#9VT]_ ;QBBFQ93YLQNS-SV?WI-F'V[V/*5!QV"W57 U=&6J2Z<:TNQ\Q>$RJVRG@!XN\9C X.'CF'3 5Q/4#J_*U3I:6#20=\L/KDNE:'Q*%K+N5Z+8(>;\^Z(G% FV& ->#_7.!HLX/?8<._K8U:-+5&P1H$$/-OAQ)FAWX<6;E\>_; X8IZO:@P T81P"Q.'5+9K\P[.QRYYXHCK!F^](7^\4&Y&^*!J^X5X\#I!-S+U@*% !)C66,\XZ^(1%6T]3[SH6#W)A4C$ZO>4\9W4[Y,OGP5,$)U64QWRI?]MEVBL6W,^ YW?HHAMYVRQDN#0XONSK[@-]W\/%_+@4>3;-I\&Q@# 45*8S(,&"Q[P9A-&=L8BD 8M3]SC>4=3@N99]!3AAM**A<4'KK,C+V2;*[G=6R1H4(9F[BJ'42Y:%HDP)M;:X'-! /WC /Q(5ZLE/]=E!5"3NA9.UL@HX/H3;7CI7?0)##+K<*\M$DL,6)_NY+L8D=PS\ ,LZQ&R>Q*G37046KRKUS.4*&92]Y$C?W<2"BO\EZU3KGD_JJ3K>""^V6A/'4E#4K W.2\6:W:!"3/: &0HLN&ED)O^7C\!'#]B2"/>G.%4"22HMI]K^\:ZWH]TOIG9;O- N5QJUA&@:T[/FQ):_S3;--@FJ9BL+D';/ BV50/Y#74* O][=Z@[G;Y3&;ZU'9 1 ]))]2P<,@?.98\=W0'^#H@R+)O_$2[V96-R#CJBX8 949(Y!BKCDVZ;^]Y*_/--2 L%E/19T1U^I;><[E;)_9_O%6*_K]9]KK !V$7FK*#\L$R-^2YVM>55=FD1/WP$Q4)>E%5[$Z@F;.U M"!?:-V4>-[8]_VW00K Z^$3N*!"5ZKY(U<1Y-/Y3_"HG4NOME^Z3F\RIK60^#?;-2?F-D>8@5KO+\)3J3Y# >CGEQ\<62/&NX=FED7,?QAW%?S V#2N)ZHYZ4"LL#JFO3M/9XP [$09B*W86*Y#;=0(,;\5RB;:@#@,44HPUS1;'Q$<^TA(\[IU@8'=#OY8NE0-, 5\.:B&]DN/3;G7J@Z.'T,OT-DHU/02G\ZUBY[D1I#'GYKA>O^SZ/!BT ^H>E3MT[_,V9M[VUYE)[CRSS#S(>C:6*&=A2SZ2SUZ2OHM5/O1C.1_(6-^3(@G 4 ')4*9(IO..$OV<;MP:RQ)NVWJF.\>Y6'Y2[9PA_F5%_8\^"5!H1@])&(6;V,4 $: F4<-TFM=+05ENJXA&]!)KMF$4=XW9(!?)87Z.3")0:@)#+?A3@VQ+(9*A>IX>0R' *%NH9A\0+1Z_ZV.)OVZ*NLT!O]%0&W^(A,VSTSS86% R_U3"$=FI!YR+%L^]_A&! #YI)UVPK+8+>8 %='7ZNBN9.101?.Y7>>QT*E$$SOO7&PA#EK_O;[3AY@TQ.R^UO NC6JR^E'_52F!8X:C^W'IAZ+ ?JEV%XQFGL/J ECS#*'25K<]1#,"C9,?[!WGFYJ K7U]'5# 2AZR*INN.F78;8 P?#ILWGB.^L,(!MGR++)=84ULT0<,;%X6:%0-:$=W2)VWG B4>YQN&C3L>5I-,J0%AHYYF-,]KJ_H7D(V'9>)9U#EO,3V%86%DR_CK1_RR:X5EL [#G]B8; 3(OZG"BN)MMU(U(E^(A81J:WA=8'UV(3.6K[\*+,EF PDSFI+XEW<==V U]:U >AENTJ"P>NL5+@9=%',%I.-N#T)6*I("QJ MGC3"M2,Q]AZ=T?3["QK9$": (,?]SX0[$;M@9%25AE.LSE4QCD\RSO3-X5\U67*[">VU6Q-;]',[V85F+$YSEGCY ,INS1(J=1^+W]K-+NZ5.$D-GE(2. (-ODC#DN$K%R2?LM0+$:*O6UTHAD/3L*65N ]+XICX:56&%5[&]IEGQ1@2/K^ASC.97DSA94N1RW;[W;O:\BQ0[&#H[)'P%*3-VGY@\O?(J>S8MB2-O^AD47G&/Q"RQ<+QS*,= K@!C!XNSG!Z^'=(9=5X"O2D'CO81M1 '5X+W4@[$LGY),AN\3"_EXF&?X)+EYS[,8Q.TI^&M.%LZ\U]T)E+M/W+9L#VGW;Z L^%04CM&805%7W,W%,@>?8:1S<3.=1"/I6KB83LU;/[ZB!_865N%5>AD=2P/[WS6 4["7519[KO=HX1.'A.^I0$#&M"17&D(1H* $L7[8'G@2HBQ U..@GS=#JJ&?PJ/^??9A]5 [#\[HNWD3TUD^'0!<@MN_- F\JNS] /U@Y]X":=O!N-0N %6VQJIFO+,(-17D\'%S%LEAB44WPA\T8,L+_THA@_O5PEE7//Y<6F=O#..,CG=TEN^D3A#6+*.1 IX ^XPR:V_(Y6(..\F"3(2=1#24%F9Z:,B:R-R;"[Q#Z%OF'*5KGN3 8R/O(8)RZ@VG N5I$G[$VKE'X4C,C#<-S0%R&@"X-RE87RYG2@3*.W,$*= MW/93 O-/LL]U-W&*[1?*X%&[- !NNM8]N:#,$NZH@KPJD?I(#_(E7]C]PWJ\W#@/ !CP>9!_GCT)2F6804S#Y!3!U!N?(K$$7 REA[T2WE+9.TGBRV4)OL%MQCRQHMP.780\[%B+[E:>&'&+V:9Y.>_F!M_>%F9+RS Q^,,#&#V[%LU3S5G:$?>Q6OX&.U;=)]W8(D@AV;HD0,Q\^N&5OTF6$8%_O2':KJ% *YH]4]*H!B..BXV:5AG,GJ*,;0X"!(;FRF82Q\??DUK],@N=-RRIX1M[: R71]B2 *&NT.FPH%WN1GZE :+/QPWA9B,'OXUX<$\M&B/93#2EH.&ORMC<% &\SO'=L5Q6X N\F6FCG>$F6&;U)*_EU7. T>!X<7O1(1M10MT;Y[*]CL:8@L\UPP],?B:.BS> 4F -_Q&5SO.7D0V4/_^Q9WDDZ,-*HLRPUQRF*,C] _ V''."]:04TPC(+O Z;):/MY8 #5M?NC,OX!D\W/S?&?*F #B:PTPNO#RHUZI$ 7?$5>MX S U;?)W,N285E013^>;-Z:5U*W+*>^?,&@X%2?ZUL)B6R3;\_^-RNA'X +.U17ZDF>#/W4VZA_V5SETN*9J,*K%NOZ 0GEA>Q[!N/-%Y[[V+P5M%3.(6HQ/O& WE9.7V;CO>YF")D=;J$D/.BJ-1&03+O8T,4,L+0'^L T07:''#*\,CG<1H&_)'#*DWQ84 WPC9KA*2/,:,7S=HHYB=@:GRHW#TLXY-< 79"I [A8E4J 8$/D8#/C< +=):]R]8JC!!JWC./H>R>5IO*X-M=%#WGQW??Z)MJ()(4+(P2.G+'= AU!] #&XG[Q" 0SVZ= K*?\8!C-E^/"+Q^4KNSTS()$ZA2,J@9@TZ2K$G/[6T(=T3/K+&Y2M!J/YA(U<@#&2U+%!J[MYNR09JG "BMM^G+2Z D2.6GOWXH]R[MVPD4]0&<%H8)-^9ZS>LQ*6E7I="C \4>\Q9IAD.-9 :G:1Z8PO:*FX7]-'3Y(^HD,F-*B53S-'#*PC;Y(]\0,('30I(=AJV*W,*DR3CG-W *8R2W #>:;Q@5?P[**B1QMNAEC9?1TW<\F8GK\:PS;7]B>QKM4?*DCA[VT>&&2L=@H9WAP 9K@0WLF,^WI8WS<*WF#R,.R-M+G]E?U*1GN'AXI7(?YD 1V$C[BY;_/?C_NF\G0,HQVJASMT8"S^.^=P0#LD#_U$U;=*"^\T:1+\*N\ =;7!A K(E$/2ZIF(5#86ZJ'6";$D06?JAUCRVQ4(XC]?B ^W?85^3[.KY$9#;E,W?!7(^+ T8=GO"7D3Q-;,E:&!-1W+(AW.EMHI(]D1U$%5 4>:['D]!+'?;'OD^^H,Y[7\#Z! = )8*!$))P:^='P6R7/G,M:[/TI'\E,5:?I!Z]2B" \C#Z'OUA(#AR#61%MX A)_ 1;J/P^QPL0LPAON_4;A<_'1AYS$1"5M1Z1/>G);?].,H"<^,F,'$F36I$"BA,W\* :$J;?50UD" V"9U4P[(H=+N%2Q#XX,\$<^%,K8T.C,?2+&H:XG0A5OSX.,$L9;\7 0P&V;.^NZ&#?KNRTD8NGDX/TICS0'H_*:FAF#7YH[ >@A!%>G/.&&VV90PBX[[DG T6_1KKE*$SK<[RE3!\F)!0,I^+TRIPW?'@4]9P^B5<6X8-R$M-E !4H2'!/ Q!A@X5\4XC$YDE(?R=TEI_L(Z>#VZZT7NG?"EKM>*U"B*=T(9 !"(IRH-5J]$*ZV,"&IM'H,MGGC:++X2L?"R?%3/1 A7E*BGF+VJVXJF:\9C9\_W(%-_L!1;]SV#Z YYI'^+?U%G*+VXCDR_LW%U^>0NBO2A(6?@W51MLF-/)>YU<,M58 F8FZD2\[\LZN *Q(*W_^YIFG$9CX7B ^):+^D;%5/Z4R@IF)%3*N+\$N).24D)JN'-\'U-_35[J3I O#OX9'Z9V+>;8H,PIT;[&_]OB$W_+Z,VWOQP4K*HZQRK&P]VL&,"RNBG*[O7]XYR KK$$E1D&>?<#H!\;ZR#N8IXP!,"1F8(Y*/Y>-"$]B1:?0^:P;BA^],?YE:?*_127 #L.1A")1)(,D-^5F?A6X@[OKB(*[A%R3=C7Y$_D^7\LN2L.8I6KIM97M[:1(9DO# B&-Z@!\-OT,T*HU$KQ*U3.CO2_];*"%E=D_#%>GIFF6T#O7QS?I75Z'TFB!$?K%A Z$$%?:3Y-S1!-(CEA:B[RNMNJ.+< <#7O652UE3=6]\22.4=7F1\+*_ND(NA4IU5 /122%L^PC^N[+*VSC*4A"(:533AM-;VE24Q@IYQL@^$GP50-!_87Q4#RZ4RO;S8X GX%2=.A+ /-PS'GGP.Y@25K^WH>QI705B&5Z1\\BX7 % ]V32$]A9=-8M>--2FAKCX!Y,1MX" ##GE":)9SY7.+2#X$#394[%SO/@=L=:D[U"XN+6+)H-J>\BF-4#B0X*7AQ7B7_# 3,=D"#!T0J% ['7M<\H8,"8K6GJN,*%I,].W.%!.1]%LC"@84P@T\'+?FI!=$.W+ TT&,O.^16%$P0,J>^G<@TBLFBXBKA5=H%$O5"/2QA0 ZDTUQ)I@0?H]8/)%][/N@ R%C-9:9U;DQ]+B!:L:)_$16V\T!Y(,0@92I?K+E+&PHY5A<'F$ *9;ICK0*]Q9]% F\396S(:B*XSB;LT@Q)79YB*WAY,+Q6_[Q+VNU(=AAIO'->@T6=@621=#V+#RVMZI^.)IUX,D4T/[ !*%LQ41(J8. NX9[7("2&P)>?@:GSN0#3J1:J@V4W%*46!+VFA,6CO,W;,ZE]D,ET0REF/\Y_B$UMP)D*T=2*BZ03/*^)5%MI 9VX-M.=P#C3*877-(4*TJ*8("=?^.-)4ZG3OLGFV?4F-G5VHRZ:A4 H;.AMKV'6W*:K- Z^YE38MX>T3A[S(EH[#>_,PQC\GFJ6CKEF!U%3O;9P[-,-ET8 7G*<["!;"E+[:JGU^:"ZO@DSW-M8 Y05DI]TRD T-2SEDQ W&:.;WB)^L9;$J35H GJEI%M?BKP9U Z,@\6&UBB&W7U8R\'DC'3Y+> ;QK_UU-\95S47A2/S1:%MHAQ.O 6G9I[422U$.ZLE1>AH(*&3'F2A%:R0.D2J:RN,@URGG.KJ[ !B* 3S8_%WP'Q\6ER]-=8T*56:9 &(0RK/?K'N[0'/<<' #Z4I6D6#-:^7IIT%'DGAV_LZKR@RC36OI+K\H8J2 I/$JM^P@(\FAY\-BN$+,("UV0PD.9CYMH./<3)]M*EFF>?C<>T9N),O'2_\J7U4LP AB F=&6,J(>X:N!C^A&X0SOH>'LNQI1S^CO\O-UZQ*-IQX$Y%?1,XGKI"4ICBNZ] F"D^AD!EY]AXM+@>CM\+,"FO6\%FX1<*)$HT?>G'E]A/$%Z\9C*2][= Q/HG%0,K @B,[@E)HM\"-!KOX=6='5IJ:Z_LBM9YY=F5=ST%7]$X+97!U[KJ:).T];2%D@'QV >5;&I2CJG.T_DW :K\^ROL&6U26WJ-=5/RJ)%3'7G_;>\VTDLF;W<+;"PVVJO7X!X_XU]]&F,&]"VVS\:^'>#K\%"(F?YJU^5YBWZ"IG#SQAU%SS9RY LT_VOC@]J#3\LE6P24S,17]=W=G1$6P?'*.)'5,0\-"[%\8G=1+;T [+A$=_3:O% \?*Q+8F8:@O:\(E@^.8V3Z1:\D#!UJ=-Q4@H'ULG8WT7XC;42$:6JBBN2"^^%?<% !@O^^34AR%33$29+P,"T3;./#3X5<'NOASX"2OTM"431[O-)6TO 0IG1_*#[1]VG6DB31@#7R^,K_XHYY <7^5<9M>XM 2\'-CJAL#IB&/SSKB2 5P-0 !885]DJ?;T:;HKGT67@)JZ6M;BSVE_'UK69AB3L""!7VH;XH(+TD>+[5%J5_*$U> ]95^7YLRBX?#L"Q8"V$PTAE>$UI0_I *WO4-DRY$Z'I8L!J#=HV<"\5=4^%AU0_V&3Z!%4Q\4L%"$VA$6V#1M1V.V(&*1!% 2DO/L1]Q-,O-;: N&'5U\\6C#@C ZE>V20QFHK%VQ6/$1 EE(D-*=MQ%N3%<$+ UD] #K,%+F@@J,X);:21R0KB-\SID46]Q4-T$XY05HJ^6W8IU$W\_BR$T!+AVHPG#3[" #E!O.:9-]!#@SIH6;T27G%5:CHL2C5N9LJPEAFYA(!D8K%E+P1B-!U[]#]KEUG9C %M4).@#A\72I#>[*RTV://,\@W?@>VK7. A/(;!&AO'1*XXZT9[50/9:N\WO !I3 C=0*65$/>/A-:X&G?:SSX=;!\7:&*K,X!# 45W]47]W8DX_7AT.^H] 7)I42UIT8 >',_(*[F<.$,V-IQQX?$"K_N8O9<)&OMR^U?.:IA_)7%=,-WHV6/HV^0D"GZ1"L] 8*M%2_S//WI4+(:PAXWMGI#P2T;FLTW6VN0H=X@8@(>3!OO4))QMIB!T#5#J.YHN %90^^!PAQ17YYC4)GM0W+M*/YBOK-=N5 Q?4!K1(89Q>C2%(>CVB$]43#'WQ9UAV NOQ3TF$Q; .#NZE1>U=!GCZ!T+ T1$PW?=T]0^]%@YRM5LJP8=.FH5LK4EV'A>]- $A?]?/(%C"CVX(1;)(/LACUWD4,.MB*40\?0Y0SF1_M[W/%9!N^34*R)'E^;=ID$ ?#_S2T]AK=Z=%6(D ]J,!9$ ;<&LAL-(0(-SEY0I+CI&11AV;(ICQ IPX9.&&MUR TBY!2QYZ7A))1]OA 2V'^MK?7CNI>=YG[XJ/E7?P0X7--#V<(_NKM]O5[X3M1+JM;X0E"4?2W];Y3+0Q; 6+)=Y06>L]VJ+BD:*5A&%L+$/*P?_M<_W!2%_[:BBD5]*;T,-[-3@<:+D&[Y^M8? 3"E3(LDKUJ1VV6PUGCH SZK=;C%R?PQU\X7#&&&:ELEH!(4I]6;@/[73K&3YUOR $\-Y4O8':!5%AB3-I#B\^XY<6*$E&EUSP+8KN!%&%'&75(Z>F' A-:2V4Q%Y]UNA\[-' 8^(FS9MQ :*2Q"^6J"8JJ#+/6],#_DA'4YM3%Y9S0R>W?:\*HAM]\*2+B9&_)_;! #V7LS;@4 SGIRK,N?S1/W)8,:"# CJ10/>LH>'.%9G#J1XT/.>5""IQ 60]0ZUNQ(T&5 %TP$ :X\YXJ,9^]I-E\C*BLB8J")02YBS).;?MK&=>X?WX1Y%8^\ [YKV/ QY&_N/CP2^K_+4-/*EF$9S>9F!8!JJZ88#Z7ZW /WAUT&*U5(E7?(, =.08>#*=> *C[>]9\DS7/N2%DY2]"5AVNVG?74:+L0G\-C"OVQ!R>WT;*D8\$_:MSS3S)F"^L: !X ;D"E\OR832L[/(A% ?:F\;=0;:B[!:8" Z2P.!@RQD'JO!J0-L[U'AVQ$\)7A=O\0BH9-4/4YAB[!'H>L\0E ?X%8+Z9F-4M9 SL&IC)6@UVE6Z^LLNG0_MV_,L6O[31L;O,/,=^7&J5QD%=UDY.WOOQNEZ)5P7;^8 SA\FD7+IRJ>=U*+"5 B;&V$B_M"ZRN:/$Z%PQM^D!9@+3..H/<00Y5? *027H:Y(K?Y*J3#6Q/?Y-2\@73ZDU.35MY?6\V7H:Q/*B'3U:!T>U7=UO*,> ++R?ADMN '2AU=H]%N%#*]%V+F SV4B@IT@E5S\NVX"^EJX99I7TM0R]/H6\M+[C 'U./-=O4"72FR%V<.]Y(R"P_[STZWLT9W_^/!;,OG^]-,Q1TE9.$EEN$8=K#P?]E 2,]*T\?'">K\6DDU?S@7#RR8&-"ZW+LM?(N99I\.'$880!Z'?0Q$SXO8RE] O^A5 H4>) RR%VO5BG="Z%BD(S\6K["V!I_^K=3??G)%_07X+]9N\B])Y_"OV70;@!EU? ZDL#$ZT27FIPX["E-Q(EEN),+$/M+-[44=V3VL]KUZWN)2<<5+!<"4^/GZ6DC.1J =]46(\J1C?24\--9Z*XV-Y4I^%Q7J[?(84'Q_T2R3&. 9S*3ZTN54'A<46@FCT#! \@Q[%=Z"PT,64Q4E=%1K[.H.[?M6#U' ! V(E9!G]N8,\(ER>F,<+H$ZF[EA98)^W/[>/"L>O":8!'87NY$C5J-O+EJ"?GD:OA '-+NH%7A4>7!MZG")5:*IRW6*8 ]TYF&&OI+R9C&+J6)L_[NUT4BY1A6_+]M#!1<^&_[GCL I@4?M4:VN2&%\:45=?N#2=-MO-:0Z#O+'X->&%406\$*_K^ &+OD)GHY@RSVYF20_C@ NB#%Y6V8A(86KZR\2K!^V=$7>8$1$5FI-;B4K$X(%+IRAWHA.#2%-:WP;XQL$G)! PWB;7CZH@=')$,LS4 ]0)+)CJPL%'&?>="D\>CM@6QPE$MC>=_OL167)8KX2!7(U +AN<'_K?,MA./&PZ+Y]]-!XC,S"!!H3H"6'8'-+]+W99$1=CNP(9K2'B#MG^BBAZ/)&,(!IF)',+A 7J6I%6<9B+!0G R94YSD2R@SI;V"PY;M69>P\GVB-O&IA5G]K'3;>XL0"I2]<%OI6C0^4FPF;&7 OA <:GW?N,=0FO.#V/S#3S_O8X#I:;"B3).935L 59S?%0R&_Z.U*\WO:P*E+1-#HL %SU'GK#AR=/H78)WFX#$\KYG%>XCM5AI.OBP,".@*4M&/J2,-, >( C'$(N,,CE<2T+ZGU,J RAQ",?0"1L2U&B(I,Q!+U8-E?W!N13G+&^-8*P1W29 YP :=>CBD:!SR"K^B5* ON5Y)MC0KGBG8UQ1&]!WA>-K$DD7I9! 9IE>RN?,T8= -4J B9V:9%Y$UEL45O\(?0,S<9>D8%M_WD9RNAA8)P]BXPA\+"Y,T/N1@.>6.O11>\QG<63A*3ZHE@H[ABA ;+Y.AW1PHZ-:T!$!\Q*??SXM71)8?2AU.F['5OF^2:WY>4(N0?1"C,P07#>C.&*H FT5I&*)_$73L8GTD-L)#GXYY,(Q)0_G"9[683,K@NXK3;Q"J1,2!4&A9*/R+#$I!0\@SJXG6!# @"XVJ-?"0I@RZ%/),V@O->Z0A>\3QI],B[0IE4Y1A8%[8A#+->.B? FK]M3YLT"D H/(ORI2JH>HN.6O6J*$"UWDDW<;0Y.7],DPJ$,SEEEX>BEL720(^,['QED\8(YJ5 V,1>:V.X#C^ERYCS#0;] 48W@^))^Q[KGPMBY-(VM;N#^H^!GQ*SG;MSV^>VAY&$ @K]L1@^AX]@[Z3W:-#7B#_([\*_HFC1D,?6),WWLW^;^'?!=QP^%0U3KGC/8#R%D /BEWEGF4"IFKC$W$GKTL\_,>RL0J:)#%!"PAB9X@6])P)MZ&J8$5'UM5$2*B9@[X 1HG(9AXX.63NKIAM+#;MAC*H7LD]TR?85Z:Y6/ 3:+ >9TH)-!$T29[2?Q />4L5 35S9K1D6NW))<9BRW]'^JC;A @H?OW1D!(5#]%.VI.N2F=C]+.2W"UPP>0_9'AW D"1RU0/_*^+I3Z-DXU%?:KRNK0*E18XW?1&2(%AW28,7J%_LFDS/1\X_-U;_9Y=W A804(<;T3:2^\K&*_=8S"S]G:']824\]H^ 5C3%BH[O$B2)\! Q$>0TH/_S[DNA$ /Z%8<6BABUFP("5:IU'=C&E5!7PE,WB_<$'0.;-)I$2&FW.#1'L@>G>H?.6\:C.V YL@I--&QMW5;HXHGIC4FY<*C?CCBB3^\M@'D'K$KP!Q-?[.5MO%XK

BZOZ&^D& (FNVTJ?>_H4B%Z^J6"^"2]RSR%,K*U*/G2A8I1-U5/0_JD_YK/[7?+BFB9;ODQA/ A6@$0\!+;D&(J-*VZTMX*]UU)#K9BZJ.)2"J!ZBLTHZ4@NPD^K?45X8G*^L&=52P ?/TXFEZ5;HIU>]+]D79FH8WMK3X#JVKLN,N22QE>*RI\UF[HOO<*D14C"3)6P9EJ #H2EH2C>#!MSLU:E!1 #=Y(GYCDD. K,<*,>]J,3"!=O$W?O+]1:2W7>:W+-*XD'BAG'X5:P+UWX_Q5@2X;HSNW&O3$*V_ \*,4$A*+DVCAU>"L#N',<+':3*AJ5ES+"]9:A&K\W^VC:W9;\ML/D@&!8#T7S7JZ $7!&6*PXU/+I'K@.&$5\#@@.&DZ\%[!1$26#08B"NNQ4 3J):+F$GE.J?&R0K:-Q PVGX[M7>^DT6:#.P*1L;*>RIS:<8AJ\L@\;"O1XNK*'8I(XLCEVUFFQZL^.X3!V4 \86RT\9]%@E*BO-0Z>#RVT: [):M0X.B8-45;D$]0EA*=U !7B% P%O1?(UL7]C] =EZ$=&#'=&]>\^K=I].ZO/[G.IV^J _CZNOE4$)Y&.!UNX:/ 2 'G_J2,Q&KBJ:P+=>PV,.7VA8*]UQP()--(B;;>;!N 4 +_*T:IG(U_T1$;3KE@CDNAO%_/L1BIV#UF[(:>M&(F5\TG0/!U^VRRG-U#;98+RB B0QKW>*B?$#$H([%F\E&W8FM[095ER5JO)-_9>DX7'1D 5;JT00@9?QU-MT0'59H OD(>_\K;<*?^=@G>B .: --R+L+S*F8YJ%D^M?9H^L;?)5+'(M%J/62?36!3+NMD ZR,M@(UR\"GN6*MC1-$U>P$0<,9UAJC:RT%WYXLDE<0 1P2)(@W)7.2'B:V:NK_> 8=KTBJUWK>8^$[=WT"X0'U*)NY2+TTN@^7SY.%0J>=PV,I&V??/%9FS,P[-ATK=' 3@PHPQ'KWG.-4%OSUL,!!')FJ4](".I XV1/@)*B6 OH":!0A=)&P3&*FIG>=AIL Q O<>!$0^#]B).H7; 0&Q1,\5?B<,%P GDD>II]QTIES"/#O#B4YA4/4R+E1I/7" &C*LE]$SF( )/BX."_9)S" B5E_/5;-BNODGN^NZ_DW)3DOD$DEMVKD'SLZSC5&M N'CO?8V--BO:J.V< (Z_>7U,'1E[:[?PA&6EQ8UH*N$JBJ&@#))1/<#PY!+_(+3B 1GM ",*GCQ#6VN4Q:H0E^&=/A?'F_-&Y*:6COMP:?XO0W@LCZT)I!I4V!-8[,I.0 ^Q,EO1/0++ MW#[!H\KV0? S'P-H&ALN@NHAM2]+'F2NVGHIZ7J08[RY4N$>\!)T 8]!%&!;)F7,N.[\3D >D^S><>&>U$S@,SIHG?_UHW1\ 6Z9LLU1K7FN_U(RAH%FL 0\MMF:3 #P9/M4$0!DMT;_$I*O$Z(\O2;T%&[A2I@ 2Q;GV+W56,K@!:@J-%XM.1 T(G'F*DP@8-TGTCRAS9YX'I(Y<[ 2$0I_^%H;T_HM_B!#+"=X=:((;MT-_-@)_YL (='G7 B]2U2VXN[5HS_=ADUEDZSH-8'JZWWSG)UW36%<)=PMF^KWKVMQ]/_1P T6_9UN>Y1D?0.Y6N7'B]!1M2F,U5/Q.UW?4(MZ,@1^:5"RU 0^7X1_*^X[A6M_(P "@_G9MIA#M%U.B3(Y1@G)I;3BZ/E-*!5.+%0Y311;.I&Z&O[<1I6Z^J9"C3Q#1_ +CBF047"Q)V\B#J5OQ[ 4MWBZ7 ]_(8/&=N-RR3JM .P^"(IL0$RU!N4;MKM095_SR<9%'SGDE]'P]58U+!DEB[$!LI =,6*^2KJ'8,DGM3B\DZ-,-TN0)-N'$.+_BAX'$C-IH, [Z^GF^>^*9&WSW(>V>=C =*Z>TB@*=$,L5_&5J(@"X2@R LT^7F/8MD3_FDF1=3HRJ8_O7:IT I"/Z(G!D\!B ^FI3CSM?[A$QN72,T:T5CK3"!$*XG7@"PV"Z+&%KP I4!/$JX4DK]SY;@>:X"FTV EHG<=V>I&X1WHX8XX""&@?)$_!%G1*VHR-7_#*#3N4OZ;G265779KAJ=3PBSID%: S/@S#JS ZQ]!\JX"_;8_U\YBG#VX$GVH$"WR]:;.8UE.^&3"9%#N((3=9OZAK)LM -[Q2S/=#"3+J2H5C&S25FMA*$ZGR+8\;W+U)R19WKZ!V[N/7]E FYB3A,;$!_>XKK'W)8%6AAY00J_-%2$E^R%E51(^"JFK?QWU$4PE-N@"#F@CKJ9# %SB+0$%Q?G/$^^OUPI.F#LZ,A;P8"/EZDX<:NZ((\#VG@NS/6A:_:/DBS=SRC/_- I_WJ)2OVGNC>%%5/W-WH-3("Y90_[7#*$V5^(YC2X?LM=P30GRO*KJ<&[# AX;]H >]5("3&QWWCK6O59""%B\I018IX*;>A=Y(.8OZ$&:]Y2 NX( J.)M26W"E@!- J.0\O?'\$9> YR?#TV9BLH-M6",LQ593;P)?XHPBM'GL,F4JT,7MW=@K\KI1'37@*7")$E0R&I+S .U.^P$5(RD *5KC@+Y>M"S(:[6GW' 6SBH>YZ&>51?Z5/^USFQ4T4@V%*OKB1V'"8*#<(TJ2WAF476ZE\UEB_*7QN2'_5? 4 @/ABTF"<6P#H?^^CIW@:9 = _87 WPT"S[2"&JW=&VN-S#.0J^[*%BK)^S[7<)NZ/)4Y7J6#=R1['F G]8ZT"",( E=*YOKC2 1J=%-:_;,>:"%6[Z@>2TF[[%&'+EV8$.#%D7XM?T?4M-#>5N(I]')72 @E#NY (E53W9+G6)J5-YRC()7 EH04-R?HYR+K0)RR0BMWGNA,$)5"MI>A33$[TH 50"?_>$N!T;=;HA5JJIF4+;-BG_$TQ(>RIZ6U0MU.J>0GZI4X7M ,C.JZ<.( >\+,II7PB^[H;KE']Q2# ARD$Z &*ZX<\Z2%*P*$4N^J3DOQ*K@::B(!(^+[2C>KOP-1FS1=0#5G$MD2.DA\ZI;LR;5G4%R'AR&).K0A7*59GSJM[],FU5 +F0J%X(/1%31&2V;&A<\M [IF%NV[<)UI;'1'K"Q3C3\;[^WB3<@#Q^WM7*OFR?R 53LD.7LO3R'O<:$X_9\D#!:YH6D&-0P"3ZC%^NH*PM'^T\9:S,P.:KJHJTZNU?HR '9'F14UTZH(Z2=(PAT0GIHTH%J(^73M=,\JXLQW$)L<<.N?:<)8AG@>$W=:A4">< V%9I11Y><^1.%26LD$[>Q&QPR#A(5JR>E*+D8>\^W98Y34JW11*Q9VA!K!4[P44B P)[>6+/MEWDOS_;#H!6R@P0,$9E;'Q!Y,63B"H@Z>//U6KDZL"_:2)^/[JN;4DPE78HC^ND"(<][1<[ Z/-MMXQ7RXAXIFZ!9?>;MB6J6#%/.E.6OH%O>;/5%!B TXF]SI+BEE U>4NQ(,JI $T ?I"TN4:?8>PJ>1JAOB(J?Y]J]3UQ)P4A)E>CU(:(*40*H9.C8=&' Z'X^*G"F '(77Z*W'*T1?-]7HS_$4?YJ>.NS3T37;:+HZF/69AEM2161(L]0MI?1$H)5L:QIS .VLP0WIZQ@.S"MXT)L]87/JY K_U0EHA;K^&38-XEAI8)2 CV'!,'A.X\HBI(JXP @784OFSL **F#.;1U%/9PK?1!7M)H\<*8ZX2U5RO=/_$^X4?2TL>P-Z^J%^Y^Q,D "(/&_?.!.RH5JOD99'IJ,S1>VOBM"N0G02OAL9'#3.9!X.7QNME^^MCRD7B8M:@2 S:/B]%%TU%0A8W.U+3S[>,L:VVD2^JX1 WDW@%".2W+?-'123,R U$:(\]O;^MVM Y(-&(,4Y[3+= DNEK>9?5(V)C5&+!EHTA&A\>=UZ*M0)%Z5^BVX65"EZD;<1N?^B @"-O[K@ZRI?5I)K$P[CCB)<&G!=&=6I>LYBP;R&&N>7#\M\FE#E['8Y10_%&@IE; JOXN04W2V&K]WM7:*%45DVP 5@(_%R\JWCHY0FHPACL\3^;]A5W2/W9<1IN8& S# B$5]@;$WQTL;19K#)OJOEB)3:W":=7=9LK3FOZN8R);2-$/Y/1;^\FR^^1,+%'Q@ );Y@0]UG=[ZE[J:[QTH9-ZN7,9[HQ4?E#(TD3"9VNT;"0HU/8G?)Y,/>XB?F=X4[ ^LR6#91'G'=C3J89UE_:PFC&UMW%A,;J-CN?+EU$A8[M, 4@Q^8QA3K\_@^ IBH= Z5'#P26Q 9D@VH'V>PN[MOCE$8"ULX["YT@5><8U-J>'YYW7OTX=BD8^W9KZJ,:+!24**4^MUD"RZ8X *F% Y>="JGT&Q)"VIOYWG@\PT*9XO-YTBY8MNYVV,%&VAU=?!,;UY;$#P.^Q_UI$FU/7 'DJI_@(OVP@N6- (^)O\U2$&P/+5 $0AKWML\7V(=%CX\6=$82,6U7C#K% '+ 7U.1O/G 99:F_-B*7*@$Z71[%\$;*CHP1RK()JVBKNW8N@R.-A!SLKQ^;X"X$^(W ";Z/KH\C;IX^+6E\<7XDMW2%F:<^HS>!I_R6*NH8CVD!^A6-9QQ>8C?!&I5OLA:& T:7/JN(8U:3O)GK?_6\Q!&CJE4SA-OQ63(=T(\%#:G Y_H*T^:&.#^0DPPJ^YT2Q =I28'B="E'U& Z.T= 3XO*'EU^Z,(G^$'XE\\DCWCW$O*IM1/)W41'9\: WH%5^Y MK4[T]/^;O%, FH-A',>T-\(68_&EG5YX897RYM&V:;&]F@&FB-,D:! 2W.6T?U6C/\#RL7S3B4+M;J'!0MZ+P(OM5DJBYB>]_DK$G- (YM=GA6[VHHN8ZR> 5)1W]U"VZL)JAW.GJ0[\M:L>W"K8KVEU9^(ZJ0NUFH2J J"X*.71DI>8EBHAH]T ;V H5P(+V?093T5XFY0Z5J:Q;OR7V!UA@\65.SK34=&_WR0B.GK&G8R%!(8G^P5G ]C]X@DNX[B6A0S:)Z+8O'"S-]^_=*@RV9X:1VX!C-/CPNY;9Y6=U4D"_OHTR=*G; $N'*<*-I7;NUFO-Y) Y$G\D;H@?#758_!\$ ZVG,YO"77,<+QT2Q(%I-&)ATD3V;3;@(4@2<'H]7(8E*9L)YXPOZ+K&_V=S^+BPD @?U:9<3"CY4K_2#KPC@5EJ@5V(D"-^EQSCJ<,!Y-NB@)6U.^29W](KAW<(!3,!Q( 7VB2)/S'W-X^1UZG*X'&LVK"BJAM4$[+]GYS93-.=$XCR6%MRF5P'&R3+$M7CT%* B39'0^G#F6.W(6R=,L,V(CX6Q&$F8@A.BW,OAZ.,G0M5 3U=Q>F+ZCX IKWE]TB/ E )]PS9?,N+L)YZ6).02JV)T4"%DO?E^/]$)Y>Y&5:TL*;?2TY[E8=HO2J 9-V6*X1WEXHA '*599K',*HP&HS&APXO<-(7LFQ=7>>9]OJ$V"(86.TF+T=%DA*< [X^_+77W3Y@<(8;\7E-2Y-K?-S ^@;]U; %B")9.!AU1]@>!;KCB$6[_P?!MF]F/UALEO=9D$0[!4;X^B(X Q98A]/E)5;B9B2 H_ \6W!CYNK7>,26NR"-> =:]A-TDO/Q3D4;8@RP!['IF$[6Y::-](;A)-!W0\YI 1E2CZZ6+M&M3Q^:3F5_-=N\5"!R'!K=$&VVBGPZ8K=8!H5R4POOZU0!@UJA*E=;7'S!BG1B:4NV0'GQ?AOE6=S["G_0L8X=Q3@*4_W?W&D"21D128DQ&'Z'R2Q"(#QE!1T3GRE[S* :)N<\YOR]KIY3_8W1B8B1DJ7:S4TPI1(*]NTN7=I2]SM#RZ3[2Q?5M$^0TT18J!" 58]3I3$QM=.SI&>G2\>MN48OFTIU^T65(@"ADL")&".V(#:@P,BK?<.@-$?"NIHB)&I[,,3P-I1#SP (%)1>@D4RY?--.W@Y1PDS#CP+01Z YM$',/((,/Z:<^\1GKT'V;10+."4:D8);-U LJPQ0?%"(Z7P4NPAS!(5;"2A(5]8 M8&OGHJPF3IZ(U<=$B=5C6U@2-\3200E9L' @\RZBY#JEZF35--)*1W"FG:$$NW'Q=VYQR8S)N6CZ HG*0^.? ?<,2AJ! #.5W#S]QSV%U2U,DD.]5VXCQR%L!=[-%X\:B;,T(N^P1)F*>%OR5FI L)$UK=1ZP@2C5B?IF7HJN2!:UA[4_F73>+W3;:?3,^\.5*C104]LFI&"MH65;8*9 2IYH!J49H,]K%6]N2_ C0WIN-EV*KE"KF#Y?S0MIC>O15:QE7P7+&^))XIXCQ6;8 MLX6A22EXLEMQDKML92::G9XD/15)6!=X5[UU0/6!NQQWP8Y0HFU#IU'W[6%\)J< #1$5#)9AQ=#JYV_%1!]6R(3&9568H8AB![=.G SU.%5.MK6N)($&_&']4_.N(B3HAHJ:+!]4+N=? ^W : _YBPF9XNX6P[:@7B^J2V@KN(/HB#%!PTK6I3N@7]!:>RQ3O7H/%Q2DNB/#Q5+(EAXAY X7*?].O-/:^#'&R:2((56"OV11;EHI$C@ZEY\GSD'YFS]-KN#D^==B]#ZJ=NQ[EZ +(3D4 \AH2$?K2X6E(_W78,&H6\80C(=/?Y+.R1PS,J&"-DUB@ "[[,1J+P>5ZK+ W&'24P@C47(KJ;B$V]:>=[ICN4BSRREY90BT8+ Q,>*;D!=( 3P3VA'&/\_H98K8 PI=SZAVLI[CDCT?;"K>?PK1NE%/J=,TM_(^8?UPTJYI!TGT!6BSZ[2>K(TD)1Y5> Z[TB*@;D!F*)2?K@*$1VRVL8PB1+C@71#[QG[T(NT4*B%J56H+C>:S&W\+T_!$RL F(RY=0E<<8:POB[JN/0?,R(.Y?^XA.#Z!)$V3^E-CLV]03LNF9)61IE>RF-SG??) YMQN1J"V.R0*+6W]7_3=^GZ/3 MC.C#XF.V:A1 PIZ 6Y!HM:,N=_7SAFW,)$B+ V(DCV);R0LP"@G+:@DUZ"BIF=B0^%%G5/_^#7P]EOL[$,Z%S^P!?9%:8N\W@QYH(8Z=7]L\EOX'N2 &R@T)6*")1^GN="=-M< ?0-VU8:+6TKQCZ_O@A?!?HC_G>:W;!G6U9]-!,/92T4R90<>YR=<:AI)46/IU+K9YE!"Q%8 QXE838+_P %7S02!8*! 73ZC"S$[P] ZW,G.N1_"S9P)XYX\X "+J\@2KI_M[4Y5?$_EI(ITMA"?4BSB#";_A4;I&?JU\C? 8 0XFQ.ONPF J 7974Q0(O*$EZ3.,]HJC@4[:<46K.<4G1O!DPZ^6]']>5R\A9 K DR#4]ICF^5C"U=I(K2G63-[V;MBSL6A$KT6?2@C7VKU[YJ1AL2)[QU">Y[V;;LB9AYU@.!1_?AR( !TL(]+'O'= #!];0G] X& GI2A+G2=3Z]1E59RB;WT_>M?DO]<>/%WUF4Y1^E,61. V-DN,PPEP[$C<6FV[<+56?I.SR@:\=Q;>:2P2C.$0.Z?%!,3B(X7L_FQ=0!9 CDY:=J<^>8A5I[<.!K8;@UD&8Q0J@NC*HW<@U.G4;)))XG74QK9)C^_'HLDMOSR- _C)NIRB-FS,$F[TU*M]?F5U\$U^:V@*A!?P?W[3X+"<+\$PUNGI_&!:I Y[1004F Z+/XF-7?WTEI*EPJJ@S+KN>UOYP7@1=LW^PPO/]^$AI+2R.A.C9C B=: "H!$DUV #.N;<,6967 ;.$["1-P"PS57&G? V*^(F?3%XCD@UN:[X+6&)="3>SQ,@&N#SI+' X]BH6G/1W ;,%)6S)IH*C^?[V'"@I.Y('&B+J%W$ZBQ#[>9GP_**E18*<<]V=5); I[?!VR"')U(*0VG]4VL2C/^)G:!R<14G.R;FNO-DWF:E*2#!3PO! Y+>'%'D>U:":@U/;%KJDE.[1H!UV^B)7#EE8]@5_Q-S.W<>5G\N G=/#2OK1LJ1(/ -_&:E]S07%JECU].6<&J1DV@5FFM*G7BTXUCE$_&ZVN[/_DB:8\KK-F14#!0 (@)YP691*P2(^?Y[J,)#Y.*D.H =Y^#+C])!E005Q[[S/B.F WO@V<-SKDKG]'[-J:&QH1%/"ZG)-RX[5O'QQ33"R*Y21CO\L!'9-BQH_P62.$[#T T;5&:H4O6K_($1U,MD^M>IE94QJ!;Z3)#A$EEM 5>GEN(/?[K'=+RM&]$[Y)^]'V .B>T:6*4+!)Y=C,AJ P /?CF_*EOI!P0CU&G&GE2AH!+;R))X?6*4/?D6ATOPJ*@;\Z$@TB(2@IX CPT;9 7H(RQ779FC!28L)-KF=GO>^\>#T)!@-.4L.L2,B^X'TG5("^-8(5M-[OKRIS*Y>I 69.[HFBO&I+C&D$+_R-7X<6+7(/77-1]?!G=%7!': GIH)K]B#YZ$HRZ 'IJCIOR ,868<-I!6W)\ITPB(">+T93&^D-WVFH@.RU+?E=C25.SDM.R.PM'I>P06J'80-#E ,\^+.4 M982JIP]G*0DNSP\8UE:I:BFMX]5E_^@,0/""M5N(%)WAE8%E]9N6@6R=[T+X5DX Z",:;2PW#;:X9[O&Z"G17L521:-2'0YR '>YHT;]E4& 3UW7W4A5UADMV)+4:-O$F(/ KP,>N"DP\BDC;_)/'1=OI!8O)H*31#< D.N"HA%Y!3^H)H$Y>?%_7I *GO0PC'8)+NMY.<(WU]H,[!0=MKD'$$%=)L?UHGG$\E_CUAZHS\F)KJWK"41T4/4F]NG@UD6&"*IO%-Y =[]NT\K2%#H2MJQF)RV'.(HX;H%AYO DV;[/L6^#VT#VK6Y@Z) /2+X!S==F0&5L?,W&Z1Y7.E&NM5,-#?+%,@7"$30[B_=;+ALT([$:FP516J#=TB2 L]Z=4UH3\"\I$WJURD_^S-G06PW'&Q*[R>5"?Z)1GE5\WU- *9;( .N]ZXM20?0S 4B!TU^$%)$:K2:NW$96C&SX14.ZF.T95EM-J?J @TF#5 O;EL8:DL#C=NHF,V)MAI[AOF2]\-G^"%)2UV/YV:S9%.P9,3;(!DH#WVI+ 4#FOVVF /*.I2FMG?"#5_\=RD4;T6)K/S6^!S8("-RDI1]X@24A?]+SM@UTI'3(H IG5!_ X3DS-I2*W$;K& )I9LI*< +DV+]V%4FCZ8FL"BZUYWACL^2&&M!;/F"0")$T'85 G K&*YO05&(H5I &M49,DUE<&_)9#X,T=&W4N>%S"I"L+N4:^H<81W%4EM$9ZY;+*%Z\=Y&MD8K>L7X (?]D![N_@=O=8I&Z0F0"I28Z7XNTYS:2A)X<0 !CC>Z$["T7NUH-:/ Q9-%)O/Z,WT:H:R,*8N@(F=U.ODRKD]"$ K/BL2_=1B?79UZU:)E.<"B-H G<6K'0[XY*8D+-9KR'_1P!/*W,O!W#>7SG@D>0B9F$416M3UVV2XJS% .;5N++V,\8B"Y0;T1<7&=@?*18NLV)8=Q"09AWMWUR:! \: %4;XD^B[ UBI^>CVA)CM>Z0+&Z&A!$%NM/*M$BQP97_R5#?)F<=/%@TBZ=!)# 5? L:B,.L/0$_:3H3BXC"%'(+J;K6!><)6Q(1;_\UQ3RQOV( 7 ^LG7N*;ZX2C!I Y^AD@CT?+1V'FP?KH;\*3_F-NC_RA[]PM,SK>U)M864FLPP6-V\$!5X/-S.W!.>V ;JMK2*E6'7*:J^6^UP]4)*( (V%GB_HUV.7KLES!=#L9:&JC\P$K*_M;_I!>CC1' "URHC#UL"A%4FP,J.2Z(V^R$U#X8LI_;6'$\H,S+?)-SY[T*LJ/#Z]V_C7F3WFM? OR;/HA9./)O')'@_?J(^WB:,(66C^-G8F<0:5-WH@?60W7.;YJ_,\-;J=?3IRHN0\$_BPBJJA, ZS^<@1_B*Y[ 1&=(>'K+GACPE!S,RFF6SUR*9G)_K/5KBL>_+?(,CK-Z+&"JIQG* <= QPA.Q"M-Z/REP(X,C.*UPRDI$NX46FU28:X0KV()%X/]D=\YJ-K02$55YBX"@&;2"/>Q&B%SC0#$^345ZTA.NFF<'X' YP^0;XM)Z+*[N!<!C)Z )02,GW-!,\MABG@F >^.[C[YIT^-$L=F['T2K!+X^D%!P6'W)B>3ROTPW.PYP Q@H\55I%\(4%S@^$+/C =1K@V\-'&27ERZ-JO-T 34X065F*9.Y&15XO=>$$,F5=JJ4\QP*)J:VNCBKKN!"& 73&<7 5]<$\=OLI6%&%$X 7YP&H$Z,\H <-KN>'*CZ-;1DY/%RZ>+=U@ 9+HL0LAMEUM?GQ\T A*FRF =WE7/.YPV_F*C:BBK3)/S;3'>OT3 5Y#%J/(;S>J' YEU(!3+35K:S6#_^3-_B^&ZVZ#\D#-&RI.=@I]'4C-TQ#1(LIJGW1LCBD3[GBW2& B7 DPDK1%,S%[*K_7..17I -5^J5NB6[U5WRF@N W.YAAU*8!F![&U6>VYH=@(&@-4_,@04HL&_> Z<9=?A;P5LO)\@X$,E(.IZOPRE=K0HM>X8CK#N@XX"!Z8Y&"OS@8A05V8MH#)W^P U8XQG5<7>QH.#O^4KL6%E\I+^MD8LKCT=U8I^!GUOL-32X%'G?Y_FQ$M;!';6,K_ 7'/B9P++4BC//]2DL!IG\FJ\\8$$$O4<'!NHFO)T:N&77;TTS21TG$\CX6/@=E/D OZYJ\>S[2(-/\&+Y4M!(:=&]=P&Z&9H2-B8.\,F& "1UR+!D!Z>R/%L][8):O1]G K_>M54LM/&H4/0:-8H$?AHK3-^-%R:$Z;7SB&=5)&LX@OXXHJ;V0JKCA3Y@2]0'B $(ZJR#$7@A !RA]0?9HS![>7 6]T=$N?;B;NR%OR.=ZJ$0KSV#N:7SYT+PI1[SE' R.J<',]4PYN &@TMIH^"+H>]D(,HK=#R2:^(/:!1$HX"[/JG71=<_C6C,A0@3Y0XSN$._ #A!BH-B<2Y=VMM+.? ;*+I,V8(T<)DGU_/GM>N;(E:,^0^T16;A!CP"_=X8-@IHM:X^KAX23%D_DEMJ.'9 LR)- -P5S[=BB:!#"H#OWRR(Z@@L5,IAZ1-WVS(?"GG\-JTO"*3H+)O!,-(H0K!61!^"%/:6PU@;]%/*V9J=!B[KFZVU?%EM=\MET(A=+;F,G <\T;D>&TR=LA_ZB8MR>0]^.K^I:G C]$[<3Q+;^:EE.IO?_=_[E*-2=<"WT3*!VU7A@",PUK#6C&+L;-[.A7U:>A/IKJ\ &\UV8\S2Q"@?T1],B9%*<-DQ\Y.#!^X<3\K@GHHL[>I!&39G!'!$W\A')N+IA(-Q [XS)(^ZG>0R*FU]?UYTF!H1 5X:)PL0SA@6+?I%X"\61\%^(BL&Y@2RGK*_'=![N L3\"M;'<0A7&;<<6K1_N^P4H'-"1MS$8F0#7SKG)C@92OA_DST/6[49MKD(L>PER74]Z8= B+ &_)"I&@+-3:F0;=2 *QAW0F:;2V%T?LA>3MBD;R/)'(X=:&!WV?0C^NZX[?AD 0@,FM- ?VTIW3/",FW!(T"H9X=[KU]OZS*9+0_&6M=V]9&/RK(6$T.68N9JL <8# 1]R,7ILJ%!-+AG%MZ#?1ARR4NP%!#^G!]'&:"7$$2KT":SA]YRZV5_D/&)7(GX=K7*B:L:J(U_%?PF9,J]K4[ 4=RW>T%Z8M6U0$T&J&7 VZTL@_NW_R?!%C3 *#YZH3-&;'@4WS?0@!KAF+Z5J+)#%0&&#G.'"'2 @TPU,GUN=F;"O8#R"7:'?D4>"0WLT*VLLYVQ7+-R"-=7Y,(WM08J5M%<0)NT!,Y' *[-<(GM18.2"!A9F=#".@S4@KB>;GV+!;^?/[(20Q'?$?=>9R%8[F?V9UZ)Q2?NB '<9S:HQYGK*TO:QS;:EG761GFOFAO3('_Q?UXDNOIWE'%VAX+,DZOL&Y>BF!P.R$ P+C]\6I85_'$10#W*/24DM@ NIO>>J6Q&O'\@%MS[2)_JM>)QN+HP;XS_#UJY@D60A6 ,(7Z M%\S XVU3S:,TIA ?T(24:YL7I,+8!/WA;V\[^X[Y#&2MF^<-1*,;YO5 W=P77P.RR\2N?SQ:/R\ 6S&OF9M5 BQ (UR4ZJMYLR[652&HHBE"_X%SMY#T?&%T#$VBFX8S.Y?/1M?XX]^=_]5L:: 8C3 ])'U+QX$7K40AS)GTZ_GHB)T%KHD)L3E&IG/]T=NP'%?&: *&/S%6?!ZCQ1X +JOUP#(KT==-N:"][HEB1Q#E*E^?W9",GN*@4)AY;X-[44 H[4\Z;8R >\\V]:Z' 4=*C"QUIRK2P#@(K)*,O,)):"8CI-Z7@UW@G+O^,-:_'-BQV;P)YO:EK.1UO,"^U ,O?-Q:#X[?D+>OXGVB;ISD&ANTXI>2\76#&5-J5ZE8.9[#1B"(-$OL4=G5 4H.13 2;%!#L,E;U*OK\*IKK6"=(;NV&I$;EI =QV@ A\W]*LQKV1#6"Z'@5<%&HE,1D^%EB6-/3UP@!O_90+;1(_[ C]-J/?A9SB F#Q@@"I[C_K =D5M[45"R3K, V% P]I+'*)[Q.'-OYMN,<.#=\E0LD6 5,T!BU4%L"%.*@%$AH3? IV-$$:3[.BB@L4N3 <./S/G5N!Z;XRZ,^<8GR%$VNC/ Q1/KY4\F +C2=LJRTJ(&)C2TIO:V 7EJ?JH1X(+T=BO/-!R-6<8F.;=\UY *I@T$V^,P8*Z[3_Z'P/.K\1,?+R-70P"4U M4OIGAPNLY#?\[[-"(7L'V"M8I1Q>PR>5#T3(JEQ2O$"ET?7;6E-BZA'B^E@606! 1"9A KP!F?E0_BN,EU9HE0;'Y]117)B9[.;&W?U?VE^\*BI1CE0Q#E/:GA(EUS<=I*!)P=& NE=8"(U)L6$P#TTWLK>!V(C&N2(2JWXUER^P27L,X6!;J+LW X:7M^K\'N4I2*-=B_02XTB+YU. :Y2\3LC1D0Q^BWL<>,NTD1T0D]:*[6\;U0CDW $[14J'R)*Y!:;K-3SDIPHS>EF_O7PL"G,A)6(*Z5L%VI2%<\$N>FSS\X1%Q<(=[7!BN&AR+FZK"2)"I9JL.^S8":0#ZXTTZCPL:*<" XX(AGX,VIZ(I%43Q<-YQQ\CL9NIW9*2RS_I'KS4[T0D^&-XH_#RJ%%U-07%^;K4A =#X>NA'$SZL 5"I,[6_1 !!BR11AKO*)VM_-K/G';.P3@IS$E+"NH4DE OWQ#O9AK1_B:W#9X^KMB'65H, *2+LL4MXML>N@?;B[U-#>!_S8Y1"4R23>M+8BR\E6N'$$3+E3!4PU)EG0%ZM']*' /84Z#Z'SE"IX5]MEYM6_E\&" M%GAPDC$^+O>G)/2\7 A6WX0K%IPF)SCX&+F'JO#R.C2VS+;>]&1P18Y/OQ ,<^KVX+.2FVVSIR$+9YDSU.'4_38B0$KX:!*H-[V"-X1[9;'AJ.Z(LGOQY71;Q.\ #W57^HLR;7^?IZLY*/8I(^#CP[: 2@J#X*QPJ#:4)"U8(AG.J+:6I,Y!.54&@T.C NF/ZDJI%\7BYPYW%@;T\G%0QUOHBX2DCWL#2%-/&$6.2X[<:+,;;$,<101]S6UKB^+=@V/L,M;"D-SOS"\1NND-B,1SW*]#RO"3M(^$HZ $98*(\H(@O:$) HU(&?R+,%B,PDKU/9'H#%Z=W!9JC(7N*24H'8)]\&@QQ H3G^*^S0(O'L)]L!O17 ?="$27@I][[35J@T9%/PNGO_07LOI%L-I;^KNQE;3W&M U-DM;( N;/1P;FIKF6! FJNB$FE,UPZI\BV3]51\JP\_= 8??F'5#3OBG!O5P%7C4F'\-9J&E3PC8O3[T9E^ 82C1>T/>KLL/L>V.6^E]A@^G=$*;>/HH#N1S@W2>RT?UG31(=-3&G@2(8HE./3^# YTU%:_'9_\1-? W_RB'9WT?=3:7D5I!\0E_RRBND';.5>^M]VOV4QW!! [IM>0%^ /&9J$S[6]ZK%C@4N_T/3@PKRW;P$A*0"1E!#D'/M_"Y0G8T>W]-E$2D._W1]$K.@ B@JE'ZPUI>E/O3)ELS3__2ZT=?A>X\)P1V+N\+^D?)0ZTXGF$;2AO\QLK).;)XDC W/-&_O7UI7 LU7GGLP,%7C$?[^4NZB*UY^ZG)=T7 KM\N'P5!]90-8/R2HX.2B^479F1F2P&U):H)_=H-&-(\QBCX0X(Y^&CK]2)![+.F SUM]!LSDU9&F>/_-AWF_Q.KAM2C36MVH ,/Y#MQ]U-T!&==8<[<:'X*G*7-WLAIM6<>V0!^VG.%; 2O?X9[A0->I^%.&@\Q%X :^&-K2.^XT7T7B%P?3"RO7,E/,2/EB9!N=*&+5ON\Z7JPTGIIY-O#5#-:)T+/&VK T\;S #,GP/18+)=8)_%V>+3[AE.=_/?<#.K)^6Q0OK-XLZ?Y\JM9+LD_7 I QN&/)!W)C7TKV0QT \S7/]O\?]9?.(OB1XH)X@L"\IA;_:"VK/$-A $[>QO*&ZRJ;^,ESQ\8&=^F+8J>L Z247_0[.>"HBFWC_GQ4 :TY0YG!I[$#&[AHUU^7A8*6V2JY"ZKB;Z6KMD,7)6^!F J]MKG9"0L/0R7R=*BRN.K-^:NWS9ERG'\HPP:3J[B/UJ>12Y>F9F@\87T!12'V6H\HQVW0YG2Q60#3/\<@/6/IMQ+%:AZZEUDIJ3.EL,S=O=& IM$L.ES)7I.-ZA1=7M!N^Y!T_$>7[+:Z86R_RTL[JM4TJM%7<<'HUKA;4KCG+[F4 690W(BUP1^1;#8G -5*D-(#F,']4,^R1:R[5OBGHI(H /GK\Z5\1% YY\@/ZRL8Z\Y>*:?6T4)%AM,P^NB9F^;W(8OR_4BQ4S"'A &/01 >8S19(PK56^\ 2LUS2Q06EI2>9B/\@!B'FS(SY%-I1 /K'4SS@EI8_NW^GRDT;8;2=!8G;*QG@F/H @H)[2_\:X2)7B<0(?>LJ5CS4T8V<%39,6H6LBUTR=[9'K+C#+6'YQ9TT7%WX?X T L]281OH\3>9 X%#E$O,1$4J2L'O_V.$U0X#8BE9GWD#M6;\11->\:$H(;:310MVQ /(&"%P/("X((J50IYO,U.[_I'0A7.)9^.((8@'Z9O(]26Z3,&J1;,DKB+?&I"EUL %V ]U)_>#/B!&D/X9A@"Q@XT.\AB3U$;%S9T!TI_1#ZB4GKJBJ!04,Z]3DP[5_*W +N FX*MBY2X?6)H+NAQ3FHEY$R#(:L#KY1B?M[@MA4179=X>O43;2#$AO,V**^7) G^FA\A(;OQ"W]$@KI4A1 M-CX>EY&FMRU]QWFHQ -3\/2U": $S5S$'S05X+;O-$YLF56@H>4PYLO\8(;@I0HRL<2WH$K\U,GSU&$]'0 /E:@D%=&&1J>SJGYJ_W<= _:J=[8IHI/)DY,5,H14FC$,I/M$Z&QTJ-DNNG,5[FE 12UO!6!.)[O)'?]XP#L9UU!-F1RO>'3LP[NO?_PAKNTNZ9S#YEOEF.K\11E$GF/# C/L8Z:*S3L'SQI:G9M1W/9LC0^5N(;4&1"GJO!G-=;U/S.?M#"_B8V Y9T?<]1-6K >3?R, J)%TN+F*Z$'M-!Q9$3#58CYRB'91T'OZ^B<8!^1O$,FZ38^_Z(H1ZM7,%92B\@U'%#+4U'MSC1)'4 LR&2B8VW3R]QV-XHX1W)Z[% QRQ-UR=2 &]7.X?L-[U^+#![L80#QLUP+EY7N(7^I_/NOCV&RHQB-9TNP]0)$GN& IBV5J1TO04A>]+@.43JFUW.(L^[B" N(<]6??L+L^>M%BCB,]M?3F)],$G6-JHAQ **$LX:EDCZE )F!F^ /Z2H$X]BQ=O6BT5J!IX@J1;!Y]4Z&F]TL*7=!'/OX7Z U* ],_?6\$,E-)F+3KI>X>G=5X2Z3J!!8-HS4KR9 K?C%$[2GV2;6=J[24GK;MVC";MU09JCTGUCX0_X*PP*O\TY!!Y""PP K]&QAGL?- W:2!\MIS BEC5!X4V0M#[7=,RVJ?KKE,C&Z\255QF:B^V .A%2?A7P'A_$GYQT'Q 11#>I"?\48Q%#=/^)$1!/Z2Z3^L:O\WZ'(B"+@,=FA>^\@*DLXXV8*1WK\/&2P@) (JNN>@M%@]+K6?;X"Q+&J6=?=/FB4A*ST6,2!.), MK-]:TQQC4+@B@0X>F3N5QKJ'*VM_ &X*HQIFGS(@[MB/=Y;VC]:LQ$*4Y"3CVL$OP IY55M\[;[XEC04D*,OI)\:^QV$7#E7A4>/67J7S\!TR'D/TO]US,]E]Q -07_[5F >:'26Y*=CXMN%D*M4>WGC/6M*2\\X_C^U7_11^SQ8KF/\W.[0YXI# U/&82%!FD-3KJQ/T7TGBDO'--P#.H8<54U ANF"FAF4H4Y7]+V]9_P.3,*=9ZVS$,6,0AB?Z3T;MG-1#).4YH59(D+(JYR-"CPR );H?8=ZV?0H!]D=M*SW)2$Q6@/W$F:JG(XWT.^SL&NFL8!.&-$6-&,]]"+R%_1%9 -L1]G,AVC0Q[<"U;P8..X'%U19KG=8L '#U.=[TX?5ER&"\D8H/E89(>+S8Z:TR9[YD#%E!'Y!S/B22N^3Y\ )B-U*#;J,3< HFI74YH^ 0B\KDD(A"J*RHH58D.-",CF_%E1=HMULUZ># P$WJ>TW8M$;! 2 /\E&XR?*VU<'O6!@>!1]D.']/RF#@[G&5V%TU/X"3EHKM^]0!'7A.T$@ R;VI637O*2;;VA>/XZ%;!!!KP[L(2%;CI[M-R!<[WCP;%"2:*2O8&0*;."_N8U[Q */GBC&9/^N6W:BRD2L+T6A%=+$J0[#0),SR!?FI5#W0DR3Q>$#0+=0^BBY BDHMU I4Q!"K0DR>!^Y"(8=6-1AU.X"30>J;@=/) =&R49Z9:SF?5958(H3C/_\W#)P@YV 4,N.X,4YX-9H/PN:I^;'&@2NMF[!<(DT.^Y0V&HR;,<#QX?)NQ3H?WT>^83G!=RV MHD>1IH5A74CKK22/KX6XO5@F>8S;:<>-CP&BX9$R.^.I+"G[J;N$-/.'2=Z#6I[ @Q(L'8:5\3.,T3F\1SH![*0C2!O@-)2 ?5>(72 R4\U !)[G+Y=<+_:VE=*D<"[&WS\9M**O0\+N&_GBM;[WE<(KRL*MRM@>; _2:1;VZ1YQAB5!6XP@P\FEP4?/FCC9M%0OI8E$#_D?<2Q;P&ZTF&FF?4-)2?S#24 H.0K1UO*HR20;;&SMLB]H]/(=EYS$#YN%P+M1;N&/2+!S:/NN9&,W:.TL4S#3'Y* \S1R_<)=0)CC.JRFA%XBQ2HF*MAY_=+J+W@&E<'3#AT^2!:9&$(54N(2Y!!# 9 X.Y:)_=,9#?J23A3Q%W.I&J:6^N48SD!N@GN4;TFJ-VM%J<)K2]5MB!@Q\&3D_+D -D\L9[(V$"7FH.:-@L#2:[G-:XBO-J&P>%5\)E:E+V[YZ@ 3"G62LLC@X:.B5^F(FP9F]M!-K:W_I;5MT -63/WDM JA O];AT'2B!.%@IHFQF'VCFJ_+? .P'RA*;GXC)4@ (P_-K?5>5 _=WHK^/GNQ]:9 :^FP$CM,)H 8=[R).H\1AI_95RHPD5K(I[KD?':6K E83B@>X(Q:LP__L$V%B/>+IUDX+9$3EH\$%L4YS5G_\@RZ#HCS#0"D55>XF!@NN[*8CV?0+3)DUHCJ+HET5U79SPY ^ 5+^[1 2WD(V'9E7DJHWU%>%F"4'ON$4.!4@P5W%#JT95D1N,S??:8A)_LT,:T* >!E^,80YVU8??FC>(UC/)6$!3_I%..-.*<:FGQ^\[M ^NM?&Z!' 9W/S>D02-N_LA @MH?!=H8D'E/RP8C/&COH*08X=# )/4J62Y( 80*$7S42W$S@K S[N5+XB74S)GF>A1$YXN:_;WE9^S;9!,9#*H^!CZY^@^(RV$9JKTIFYU\%.,$/C1 ?BZ=T>$M O[?3NY;80[Y_!ZZA[$*P@K.278-@Z56%6Q(E@& 69]8Q!YQ/V@VMN&9 ]A-.:K(%='?\1X'LOW\O]T]R5R4:3];1XX@J5FBFJ$S%T'V*U6OHS451 :]SJ\7] :.Z+4GOGKQ>^W><>SDJI*B@ .KI*Y;*;^-]%DSN03YU-%H[%*FU?K28R#/"L.@7% %PP+R9(0GV:I5 JVI4U]5Q^&-ITM-@/\0V7O!5HV5 /TL>YIZK>SI5%S] *2Z)O_ VMU![9KJ\49FOU8(!W89:#S!I.>D3L]W4#/'QIIZ8S.D\ M7X307X*=#=6OD,_L* D=@JX[E2 W4N'7GOU=K?1(/V?/6!=^$_%)SWW?:F[7V[6[S0>,!XM"U$"6"LB>H ,@!AHODA "PAC;1R3J7L>IW#DR)PD(@@:#P+/8\",'WC,:BFQ ]>)^3?@[28'6'R KUI,W?)!"&3 1-4X,GY8#B!?$;[ML='UZWV+CD=.7 0"ZG;?<:MRU'&\7Y]D)C8;YS8H\<*8O H8U"Q53!(9%:8M'^KI<+TW"#G(BIO=H0 -B="MG]$V[,&S@QYTM&J#5Z=7!'UY$RZE$_PPR\0(..2AUICW^6'$U/I3\_^$6)M RTNT.-N[".J+XF94U.QCX&7]T?.>J,-:HYX82ZPW&'26*6II%+$8*:3%@=.+KWM+ &% \\S3V[I"=%[DP]??=Y:72846)95?5,Q66*>I^ '1.#"D8T_0V%23*?;O"J^+I %*Z-V)^/WZT\?=LK.Y=]2/5,VQHPMT.UWNNANV(=#VE?$!H'?$:;F]!/.+1.@!0W [(0UP>$Q+/5M4??VI?L!NQP_.3I!M?TAC@MK3^.21@T=29JE8D_CX)YK* =R4M2UO8L;'::L#6C&Q^Z1M*!9MHN).+JN*Q!2__P\P_%!H$G( K2[]W$8*.9"/' %=9%5)!A_R'^C;<39(9;6),9)""]*&%LI#67N)7XWK(&3X3&,>]F/5&*+V4*&2=L 5K]%HTYKRB^41O6:(6:H36->@' ^_%(,!57QV/)/YD92^LTAIAK7 1NYO7 #+#U5W[O*I/3CFU'.2SB8),*'>!WC+#'@4 X;[?!'4\W.B?6%*18!:>?J_9.'J [KV)].QV:=K)^I_B8+0HPO]COY$WSLDX#3P@@R[87T.=*6\\+H@L680M0 PU+(O8,(:BBJV\Y(>S<=D=XL7C,F36_8$3!XM1C0K/1NF)R'067(51O_-F=A:K*! /4;0W-T0HJ$FS,STFG"U@Q"4,&(/1QZK $_%K.9W>4=LKJX+.IO7876A,UB-!PI> DE,_X0$$R%MS< %".7,;_ =;W:Z;P9VQA('*'Z-"*@ZNHO';350"LL-DH(L*<@^I E89<6CS%8!J":G/86K/_$, 37\C%-0JO^ZE-A)WCNJ2?(6XC22-6:@PEW?@F:B?$ ,JTE6']YX*2UL-^T: *8/._P_O@VJJ5.QSL.,2_%Q];X3B%1\C05CQB[G!;XDX$L P6?YI<6,3P$R&*5!=3LKZ%_/[& ([Q*EE.2I1<[^86"6M5"J#),]KGHDC#? MD9\VVZ.I_+ K-#S)\_+W.UF-99* ]Z +LAMD+Q(OB3R\-<<6H[4 (H31:Y!HTSY9[83(BHBQD5>S,[RT?F@\P$?<5Y5!H6>\[QU8ICL;6/@9@5_G&?@V.33!/A B9=?:YLMDPG'%#.65\+AY TPBNUJ*FX :'"CSZ9I)3[B-369*:]AHA_6+LYCP.I\RD[YHJ, ^A=/ %Q>[[CHX7NB CE\_@O4,45:P-DF.4JRI)Y^&7=I& $E8AS4Y!GL8P-!,/%,Q5*9<&)$-F:G%L\M 4%10F2>5BO$T+%XU$Q""E5B!1)P]O_"Y5J'ICCQ(D'8DE(G<_FC=H<(_TMU9 G="8F7V*BO V@=\]5+C!CO/N!3RLX*?^-P<,'VGI_/,1B9+7L%HWU(]KY"3:BW<.E3**B6>FD6),01BV98,&YB=J :^ 0EW&&Z.]'R$R!S;[3]XRZ>8#567;I\<7@"X! EE_BS1@6:F12WMRE;UST6)WB>?B&:%!@H[P\$ LW,Q[0T']V5D3P45Y\5^5J:+9;01!>^E9N;S4$F1U%@3,&['ZA-&Y/L[4JDII'FZ Z*=$H/9L<$9H\WE@5C ,IU\/-8C"4-HR"S=LI$]S\Q-T/0XN?Q6X>'RJW@!]E/.:K[=H&I6/SD?941 M4G# AH[]^]T2!,9HQHB91Q.XN:'>N[8\7RA9B6&SC(HDKU?&O&' <<7<0[V(R(G U<(P *J+^#>C***0LW+:4_1R:ZD!5#C#R2PK.X,> OD*)P<]L*JPHY'-I]BZ,N.FQ[3?C<=[<"/T[J=XK *PGYP@VC.HP8-P)!@;ZAQH,PLYFWPL>1A35))5G>+J-Z2$16&4?OTE/TF=ZS6X 5#@C-$GKR")SU0FP@ ?;L8N@M*M#E[6ZX:K C[GYF(J[Y9@[X @;BME@+1L:TOK3V?QA$B3V&.5,J=W/D]K535=QX-4M*UNL\8KP MP>Y"GYI5'QQV9_%5H"&H)96=PJRP?U)GEY]9?ITN_9>;>)DCW1)&AN:IDANGW*: 8V78:Z2 UA7(5PA]]6QZY. .A4\"P]M67QD< @7?V?\?.8X-F5S?C*B_/KZ;[+1) !$)QU6Y7>L\,*;5O'Q,VE5K+T13=..$VQ;2_T-3V@\OK\KDW0Y6R-HZ[/(6V_--I 5+F_T[!:7M;*W I"286[ 6SCI_L/6IX*(FHVHGUV-4UG[TW?'%L+679_TU=G1XAB BB%1PJ)SL%=(;+TE8(^2*?PCW'QG$_(E-+H"+#L5E-) 63'8Z(&TRF>[95M;$W*2,JS#/)E(Y## AWS'483;XVJAM '37*D31A34<*B9K(CETL_@9=Q&*+C;L[(2XJ6T9PZ-(S 8$VZHI>%S4 JB7GH:.5AOM_M "0<'6HP4VC1EN\6<]W"XD]1^C2B'GVTH-;#Q\,/>S\%A,G.-%%B4AI+:S=BDX_?@ )!WF?0'F2'?%6N>P'>-9"6;$=-Q1F^Y77H@Q(R5Z%W_W@$CV(3B,EAJC_NPK[ ]^ G5J#4I?*Y2CG3B7K+/) =^)22Y]^;P007N-FL+ JW9),0JR?*+U<6:N6=[\FLG3%,\.8Y8FN'K-^!O*!3V]2OS'9B'V*/G1\FS%C9: 78S=_+5>K_1 U7R-,]W@ "YXV*LG1="X@*^!Z1=J*X^3XIG?,B/3-E32O?9[JM!N)0HSZ "2 P5Z>D,N.>N$[%DXP(4JA:S;&W;FU* !VAEO7=0_G\3[U4"--C 01&*#1M3[45]C5'7?V=C7,6/6 KN5AJ8EL]&GUH8$A0HQD)[H&)\'2LY %QOUX7?A9B9 -7FF7>^]CV_=AL\:QRXMG'!62_T3<5[<+%[%[D)5FJ)9%V9^#'E: /A"L6SFI^ LB;U'[^UKW'AW!Y+8XF:[F\^8F=MKIVRI2K9$?9'74AISSNH&,AD/A '#XD\7$TV*\'.9-O!\WC^^,AD/&XQ;**>7MQ;_H76T%-=+S:\:;[>60WB -8:]T] !S)WW:_MI/$3U#PXM*)['W!?5_6S'Q!+-9+:\?OBXV,I7+GR%N04:L\!IEAE7#OJ ;#7%LU(*&*A@.*,A=G)NK]:OB3"K23=^(S.N:HPLG*!@A/1F"#<=<4,E1S8MR>7J KG:=&) +F:WI,9,K!2I 3@]L0^ 7%P5;594AQ!T'Y]3N#GP?+?_O1AWF )^PIYF&'=GSH:Q F$3=VMR*"*AFW9])/6MB^#G2T40BH:I18[4Q"% [#* H;Q54:$EZR%HMEQ7\5F%R ADZB?FIINLU^"KZ*6=]-58\%UB-/S2:(%=)3?<6JU+6)6%%E:%.&/&^R>Z/QXOF\ @+FLRF46NCT S5T OIN#DE]SX-2J7/_F(>IY?"77.KS*%!2B2'+6<@*NB@F477L9 U1GRK:0,-FAE.+:/Q4[#WW52X$[P_0>+(8>EP0-$_%GDGS4Y)^#]*GIDR].LB"P1 Y22*W:(TH:?'@^1; CFSH9)F%4AG%5(?BQ5G!6-20Y5V[_+ P2C(8NE078(?:'1..2-=^FZZ,8*C=L)?N'A%']D!M[4%:$C\_P/4W@5?DM(6EM/< WC3%+Z<>] PVFO09JY@S-\A8'[)CX.::HTF-MQ>?:" 0+5W6+R6HZ&K+GVO,QB=0Z!F]\060Z"90 "7NQ2%VKC85)W=>C%^J"C7[;3D6&?0 B[:WQU[DMYVR+)%FL@GW*?4=-D9^_[RTW'O^P)I_TY;J6IG>02PQ\P[IE::%O?@I @M?A!)VJ#51]3]C%"'4571AZF'M<@GVQVIJC'#:.J[&O/1F>, ]N.!L1^TUY9. >RW!D(\;VF5Y/F4Z6O[3#!*% #]#YK(T-20:D50*^QN/T G-ONGUC>T4U_ 5#>.6 RY#2'9LM$VX3'L/X\2.GD;80@8#9R4?0X.Y]SD/3_SC?>G43"=OPHLV_M(U.LY&N.E;B!&.) O:@:L?DCF(7*YN]X='U?X6MF8FH*HH@?K=CQHC_>['/_H$G^O/ QMNT4?8J-<'^J M@SR=W(''KK',4E?PEZA#'G-UAB[ & _C,'85M<&>@2(M2J(S3>' !9_G ;;2:4R"B3JCGU8DTJ3 %KK?Z%CNJ.]5<3+M7]U1M3?WO_8;IV;89)(3'SZC 6I+N:E>$2BP##_WXHP>0(B"XH=9MM2*PGDL_EN8#;:2%3OA@3:I5VKPH)^;S* W^EWM0LEV (UJ']8W[ BNMS4W=HL5%F]S3C;S?O0Q* K=!'T$17A:SLEE,RG*S1K Z+0F6MA283M=2"%K! 0@J $!M>V)TQ+A*@,,:E<9U6ON?,(G$@E_-MQEZ(=IS.% ,9(Q$ ZM71$,M*>W#UU",[ 99#95:PK<7)JM-I-<.PZA.DSL$@5- 50I"_>H*J]M "M GL$4?B"J#)542S]F<8S'][ZHT,+ T),_J-0B\GZYZXY9176TE-[;[FQP84+C6 %WC?N+<;A(HNZ[2 J OIR&2L-G?J@^[G)8!Y5-)#9H5E)4.A%N J*9A@6Z)FDB@# QOO-+-4!BX$,M&!BQ_CLE'P)&CTV9%X[S0Z ) 9MW;3F/!;< ?DI]/_T^5I[JP:&6] $.:6,"=;=;V#_WUT+ZW]86'")ORG(P>3T$/UB1Q D-P#/F1IWX@URE:[L@ 2"@Z682#HR\F- +ON!]%S2"+R?4B]!(^2&DX*P[[I](]& P0.ET9K5=J1=A2WHE)V&[VU.;$3#L-=:+[-NU$ 1.GC(;C]J(*4W,>J.4 F)VJ+:'?T6J2^9^N2]8"LPQ9X-PMHNV =IH>Y;DEUW@DL2C*4 _<'>R0JA&I5*:6-<"Q#4%2+$%@#&OPP&K#T/:SH8I&V:08 _0>58EC)]3:ODUXGM6Q)X="!YY/:WZ;9)3T,,Y^-\]9][;1DH ?NNDM.]UW6\0\VQ6#IH ;JX8"WP;T.4\)NV98^"?OF,$#76ZM)ZJ4"665A-3QWJR 6%4?K!G^MU:\BPK1*U)5:8Y 4Q"&*54>9&D"_?V-J6]E#&B\&$],I_SU_LWX06@8 &0I6&:]I[Q/M,>KA/7I!%&@?C%@&6IWG=\*>)+>AJ3MG-7]T5ARG%2+96/5*UWCH RX'^-.!I30J*1\#0/Q@.C+8-SP/Q]!U,VU5>FAEY4:^%B0HJ/UPC)Q:NG&\(,%"' 1" X,YI !(4$ZI8SJ15T*+V90>HS_A[&$:RA]U&]E$GCMC/*(8M'&?N$7\B#J0)1 %A*HV>GF M^6'D];?A'D_]($P. ST-:KF7E")Y#$3DX_*ZG&W>R!F:MEUMGOCU,M K6WA4Y+K@2//T)QP;%P6])(V"T4JTO1[1N"S9S;9-8Z-\_6A;5K<7PX2O'-IB)?7 T:W&6,,./$W]"-C83G0E-Z;-Q?YK@66VGD'HRA9Z<;5 O$6B<5.QGY2?GY0F>&>1 ;3G@]GZ&C NAXHWUT9;RLMD$UL-'S(-APCR2'M?V=[F(Q,O3K7*U=+82BJ[G+!B'\L(&Z1X+'? /&+LLYV>I:-)@\A9Z8*+E>'KX3/UP,; QZO <8LMZSM$:>Z#Z4!?4@X8/*M&B]1#E=[,(1K,'0)8.2 >?DPH0Y)4PFUF]K[O .F"@6*)5NFVD# A+>\;GZ7LAE)8>[X^EXU[6YG$90/#:?XF&WB4*N[+"Y!K-!>*T V+F3$S]K9AEZD(G?;L?-I'525K>(DQ]$Y!S= 6RRZ3F2<0GM.9ZMHXIK5 YL_YI_ .K6K8:&:8J'+:M#*-V)8(.86=)CP-W)#Z&B$UM.V(H5AH.MG:IDL R9-FKE0K7M/PF/%%>V=9=_XV?E/M@ZA"%=G$>> S.=@L3/OP24VX=ARH28"Z:O. ]+QXQ&T IVV >:LW"S!T',%=PFKK/.%4Z0RBB3*<<&K%B/ZF=U YT8\/Y#R XG+G>GU$U',3_,]/ 4.N=+ZL[5&,K!/KJ"9@IPQ3#2U\_D+X%'R8:F5_4]M@)2$(:1V_YAOJ6KP4 &"4. 2O6W6( /L6PJ$F8VW'CJ2LXGYBH6N0I]-F'I]>J5E* //O'&766&T..F2CS-U3/T +-56??.>^%!0)X:V-%\J$NH[;YKW&\NF='JWFM9I#JDG %K)&%LXHJD>EJ2B:GNY 7C5! /0-\?%.T< 7-CSU/Q31<9@8&>\W']O?>3A![%436GVJA049QZ[;E5-Y!S3S 1_CK0P$!6=*(4-9BH>?%'3ND#2)$.@(FVPW-WO>$?K61\$XWUU@-RP]'0\W;N&?E #3V7H"863E%E[H 'IN""Z\A.C"-90:RK4>8[N$'=VY73Y3R[8]#E).<6:+PF&QY*'8)L"3UX7 J0!N;=J !U#"PVFNV+; )4ZB-N23XK^NOY HL,6,(Q>XHVC1UV_*^R[>9PWP+7Q/ ZL9=J!$%P)?"$#1SNCGEK*H)K#_(V#\)C99)=1ISB,M2CGE.%YHMTG8WU$[;EJ)8 >=)JZ5DLP( C!Q53/1YGEF%\:(BK]@6N*"NP@'3Q#@?FK=_.E5IFX&WNN],ZO!%+ ;2TM('6N*IFM >6MM15J(LCDO-["IPA;2D(W3NGCIYFNL;KBR=O-'G.A3BKG'/Y KH\N87<@ZW*T8&&?V1'9X='8ZD%U'Z#8LKKEFJ [$&P]D/GP__@"W(O8A?:ESSF, (VIG:M$(T>^X06)SCHBG7J7.A29EJO"6QYA.0Q0KEW634C6(>M:= [7!@5PP;3:-B !8L#YS/&RYA>CO^D0%W-+WG6*E7J\("T'('7/*+*89B4Y>@AY[1 )P)>+_S<=3R@] /"BS_]@\A("L9.3L!+6+ZKN1R8ZUEX2G)5Y@Y+XK;F5?+E;C50 Y/"8K&4QA6E,GU9>Q04GX\37_5?FW"_4H6&;!9B8]JASIFRTY1@;X:>*V?MN%;K2 &3$]D.Q+/$5'9G)HTR?]1]SSQ_[,A05\GYT6UD'$M_S#H\F#;]=N$[C@UW44;/7/ V8$W=ZU-"[G%1EZ(>B-NHA@K,'.$>:%R$81JF):O@C8 VX[7],IDZAE]WSDP\#QG !O_]\2EYATOY.]#]%11S:; 02$YA/;G[^P F2LS;NPO9P>G-O)"HI!4- ;LP+[%\ &U'=/9P=^M")VWS4_'$0 @K$WQ^=G1@--X;0L>%QD[(+&Y%M#?:QZ#K9*#L0B&'? .J*C!P/V6J30VMEP8?+*P>4QYC7C3^U!&CE%&0/PP]I5K6ZZ\BHD<-DBV\;^M'!< Q!M0?5MCE4'.5PXD_Z'L.:F:*17#\>G]CZV,RJW&.WXS7*:?4@GWXO_0S&@_MS?) =(@GXAG]8QLB.5'D25Z#>>XPBLE+UFQ(U.)F)%/1K"*FZ-#KIL_IO\._"52F]G2$V"3PC\! )&"3Q]G0-N$1._[-#G[@7B7*O.;MF?G5(;/))@KW%K,E]<,7C"N7//N07[M;*51L 430M2O40G_PT)S]+(38??EZ^!X=2P9I7:1_@E<"WC604^%10WLS+;N/#,F= K'Z<1%O6D[$7S1;B60N<>90:N[AH;)_[3WSIIP?P7YP[ [0? *](L-\[@# UV7RB'K)\=%M6=AM+ZN93[W=U:(3F.K\/C+!38'V0Y.AS$JZ3>CW]U[AL8BU0"A 0FMZ\1>9K O$R.1@5AUFE=*#"K&7*93]R&]AK@[GM RX.'#9TP^%^L\;W2W]B/#K5--:#1 <:#:_+!#,CW5!'YQ7-C8Q@V;_EL:P=*E*Q+0X2GS&'FZ)]X-:@"1+=#8FR3H]#RW8P A!EL'#%6*[9GE7>XP](TQ9Y2AT@?49__XES*5?WG$\I%^1,Z+VLJ,T^'5'N%H>ET.\D_2I6SHK?"*SL+3Z 6,F2\HJN<2ZU7YUO[K>F%]Q @Y98_F%V@G5.#E2ZGUSOJ@\$*P^)N@)UYYU1%- V F(0ES>#J69%< (0+C8J8Z)1S%M1AIWT6M:B$&-4;#OBEFDDEA9)T/MD2$.:9BT6& OCY8@-E1]\X_]TTSI*50W;?X\O1I25YT,(MAB*^QN:I3SCSJS$*\QV\EP 6+N%.+"&@&2)_)2?/FJ_8JN;G;NB)X%HL\TL(=QP/B]@A)R ;NK'7P4.*C3YC.N1 G 'RF#XH!X+MOTK85 "IN28;*Z9!! < KU1A%%(^LH9B! [SCV?0\Z?C_JNW.D./ :,BY4FOX9V.J7J]:*P8@TRV8VIV#I;DZV1< YA).=B+E08=N;IP_'C*-7XN&Z?]+ '=GT'I8%9^Q,B>32?VM5? HGA>2*)Z85$ZEWPX,W5B#4=W7&'$?*U9OJ4/%E4RB TROHR>3'NNQMNA]X0)CPI'\63O\91T1%Q+-K[X59+OE))YG 2Q_D\5A'-6\]-PZ& _,;B(V5NE(U!M! -9YT!PO[ 6Q 4I_U&4CFJ'V>CH^82GKH_;?]06_[2%^^5&N5< I@C1Z_S/NQI$E+#Q^H!+V"4!^TD<^[;=,"@?UM1:@4G!?S\I38N&NMI Z!HV>AP5 "?1QM,$RZPC%8M7+:[N4_-&*,< VI74&DG/ZO"6K?E/\2M.(@ ,N%W7#U&Z7/(E%.WR#,M^P\?$0Q77.%K)L1706T1\.^0J#&E-/RG %%IFARK"K,+ X.F;C>PH^E8HXBKDGL'AL"Q9DDFNH609#]'0L4;""W)!C<-\@;@Y3U;ULF:C.7OT *4VR#E3CW*H/M0@B59ZCRVTZXM^"IQU1)\%P4O!E6X'B&]'K9;Q^GCX>TJ=_0 ;]*N#'0\*WO^/02:]'>[NEL,_LUJ=B,W38KWROU.?QAML3[R0;W)_528JQV"/B 3QX5A81 (1+!T0,Q5N$(E\*B,^N%J6R*YI\I'G7\CKUDXIF2GY>(NSOBN?*H00Q+ AZ\IJ<:\OLN!6S"__J>=F5844SQ,GP3BUI#]))D'DZ%ROMPTM76"&D )(I9K*+#0 O+(1^>;HPE\=KSLYKP7ZJ4I;"[8)T67((P"RE54^^](ZDX^-3&B7\&$3AQKP+Z6G 56I(8QZ61#DD6FJU8:P-2,'Q3X*(U.$F.Q4NT3?0)""#:E&'[=O'@K(EX?$JUG5" *(A>)N(3:1$+^*W]^+PXYP^39M;:&T?>'P+4UJ/N(_ *]L5&5,L5(O $+V/ :Q-:]E,MHX)1#WG@+^IT8( 3SA:JVIL P+/&''XT17-#4N1+C)NY^YRS9#*%>4R3HZ>RJ)U*A33V\P.2!D8P])8%M? #;HZV&OM2T"&HNHXB?III[O\.=H/A+:"FGJ9'()]M L"3LM(=XALV7T/B53, R,_ *_!9=[S"OWOH1Y%_&W9]P)'11JH\FBP9,"Z 5J*: #%R] '1U/O$\F$V8G7E4EA: UU!1UY>[U,Z_5NO#D7N9/J'DD3F9?#+GZ7>$GLL%L>BN7E,1@%B Q'P*+WK:$YVS @4YIKNH-N25[9=%[4CC/2CJXN8M1UAVE+Y*3A"^LF8-AZ*3)+Q,\:6#!Z4QKF:#% 57IGIZ-F:1!>#JT!-PN4$-%\1QQ>SP7W(NB'R4B':-'!EJ8<"S?[/E8)^\7I&C?R &1G(\71>P/;7AN0H\,T(Y457Q7$>;;]%"N^=,@,V@21[CKJ>A!(KW[WE2*3+5GZA P5Y68UWDM1A^4"EYI8<5E,RNJ39%J\^=%3,$@0C."G3I9DAV5 <\O:6% [R>\5I9 T_$2VZ?0'Y% 961[^'*7A)>;L4.J\,L02$T"6GD:71UBS1V%G\B=^KX$\U4W@ )BZ.PM]$&QXJ:Y=R-# <:WF[(F/!LV/'C>[ O[S-*-U6#J";7;0 Q<[N\VJET>76>::"K%,(%%+6BOQ :9B2,7?W>%( ,".(JM!J KI4UL_U"7N(0 J6!G0BKADMF&5/!U.$J6Y/&:6(7@JN ;WDH($QJ\5 V:5!&=4Z2F9[9NG+?R=COV)\&H!BO^$$=_M+M:RP2.IZ48NOZ-4F6 [!SC)C?6@(J2\(\I@)=J)(KAO/3)40IIF+3.!US1;!OTDF3+%(.(;WHB/,495XUG3[S8 Q!BT(UY-(/Y,;#:/9/9 <'[$?M.\GW%PAGU ) A>,VFNXB>5WV<$JY/BZIN&!#A^]>2HC_*GO*6 [9V)]JU0Y;-H-COV>9&(553SX8 6XF _[\0P,FOPX(XQ /,'+>SL+3%Q2T:U_%/&,G2=/X>8M:9D7_>G7,'7K>]ZBSUY%%*>99/VC^FD:;ZDKPHETBBLN5DD\;#^G+&?>O "]]<'EO-(^1$?%"J:SM,"O2>&FMWIW*@=PY&I9>RNZ[>^@6[E19C^<+UQ)0!K49& &6A4 ;J^4)@@[_)$&JDWACRWLI"&,184'1;GJ:^T^A) >JE>61UMKJD6R_I^.,1@AE0<5<[= @UIB%&]FR&VR@.0$3AB520#IGL?"5.FN$*] @"=5T1B<8YZ(GOQQ0."..UPMA4?TQK?/"@I3 ^ 9Y8EC@*E%: %'MWKNWIOPFV*? :AW@""(\75& =W')4X(?A:5W >9T'2,>W0QXMLK2[6:=P(N1HI$WQVF50P?B6W=8 >1F,5B=,?X$G@^^N66N=4D.AA;U6K0!<;X(3U@5WLF%J.D K/(4[O\T@?3\B);:+'"JG\K_1L4@'2/GF5)":\"GO:=:*3/DA)QB%' LB?C=[C2 >7WZQR\['7"VI7#2V-NV;WU?^:[.A&3KS9@GPA%#+O32& FZ8)/RF]BZ D1)<5J R_CA^G"6(2"6QU'D-2!; ZDP;(OCB(ZCCII#]B:"6+?@2LI4: N+QMAML#&.4I;SU-KC%.CU 9[E;5*Z\ J(F1V*Q T:3"-1G H,2<\6J.QVJ /OK)7+Y!QTIL,-"5BK:]2;_7B;? NP3] CY77Q=WY3VN9L.J\7,-7%UM00#L-.FB0KGZEE@YS-][]H_2, X/+(&1""L:G9-*)C[=0"DP1V\"_EE3GSP8X3_X ,QJX?>%0^KYA(MNM9!P. U.0'QHRZWRKM(L0L#C+S&PHJH:$PCST+EZXW5]G#]6+F!@/JW 5V\W[PMR\,MUJBGC"TRNQO<0&Y][&N=:@VJ-"(\MSY)>?GDN:$-+T8Z;C=D+%%%G (E 5 A/#:XVET($GI//V=)PHZ&SQW/J3^^GUD.& %6JO=:-&/PI@SD-X2Q-N@1B%#(R_4$"MAS7%0[L3[EYCSV#-E7#RVV* 6.J-Y*4BTTP%?K(HFL?]Q,[VMUU.)Z:DF$$KUR7_P12'-PXPG($N (T4MQ-^(E2@ QL7Y,_7]D[<*#VFL;R!D101F7WB]CF"4&REMG:!Z:EH"Y3/S2>A/;3-9"':F2,"F 76'AU8LU,^5K>1^9?]E6;.T,0O ,B6V#'2,+OWM)^NVL/+>$O6%3XQ2];D0:[=;< 5ZC#@PM.V#R_X/7P?3'9\#A\NL$GXG#F[#CH.W"(DMG8X!U->O6OAD&SI#,@_@\7 =K,XL4JKIWF<2R- (=.R%&.9G8@F\E(:?2OWL=D99=]MM4 @+*_P.T, 0Z,MZ*R*N9VX,.E_'\+YY79ZME $E>?>Y/=OMSTFBDZYE,-ZH$Q^G&1O*+XT[,&\MK6EN!U=.$ 7344AFLVR%]&ZVH7 \;DWNJUJ>B2EYL=G:E 5I@W_:A>C]+2K1FY,N;-/N$W4D_!*JP9GC5]\1+].D+X^ &V]IV;B5?*VPU8R:I(TQF;*['2BB#UUC),V. Y>@L8#V_\W)_B9]64BP]&DYETW+ N?WSXE98084>(\IE],L<2U!-.MWA W+,+G#F_LR>( ;KH3 JYC:PT/VS4P-^<07*X]OF##_!RI7J=9:T'[>KN#JO)IP7?.S/4D);="8$F HC-/K;VTNQSG2.9,IV=KP.O/ @K[:?6BXN+*NR71T'A./F^"@!7D@O$0W JY,PCH 3@&[FW"9;#)(.MA<%ZW $H!M9G*DB?9AO5.\C+7>;"%T)RO/S^\.(1!LR/). 5!#E+RU>L[.S1F[1.;7R77"=@=R8<>:P.F^A3]G(=2D1]C#^XMU-N]193($3N3U$ [#)C^10LL!;:;0%G' QN.FIED__DFJWK]XA0A=#$&W=I1*;"0@K]*7#KJ#9/H2&C H*R#C_!<\>J_;0,T0N?2(WDFF82,-[PRRNV7XS.*]'L#5M#9:Z1H[(/5+15$%&?R 93L3OW4!;9:3U_C5]6GX<,FAY.3H9[2!9\"]7338&0ZT:;$75B*3]'@*#H&QTQ<; B)KYTLH]O_EVKMVQO)=&,Q0V;+0FR$[=MI+G2NBG"_Q"G"=>^R\8E6"$=WDA]11X B:QOYCZWI#\ZD:W)ERG3*Q?Y??LA0S([,C%INVA;044%AP= )E\9K7B$])]BRZ,8N*]X02%B3^;=QDP.!WLX]#?[WALIWZ-VRI[:^,."*)0@1JJ< V08URU-&1)^8L>FH,K"5LIHIJ1#YPN(["W!W^IH.4*N9R4O'K>)N(ZM.1R(&]LO- ,*KP:E3HD/G< *_X^OV'/MVL?QVN[QJY0P,FQ9&;B4UR,O=Y3.@$/]IV/>R3D=WP 9B_?8@>]47&:HV6@ Z-U;F^B.^>]@J<-JH8 5C*2=?L;B5]!3P(_KF$5YK>6G%(3 8JE]>-P;?05T!2K.M5,Q$$PFJP"I=J8C9B#T.1/A=TCWW0_(9J\.Y?$I?79*OKP= Z^[(YSDM1$[1"!:SB9BQ6.:-HL.5IIL*^18,L':!!MAA-=>5BVR;GPT3ODROJ.*U %/V%;_:W_@P.ZP#][2^_=L+M6; >1V2=ZG[<5D26YHP2%$I_;3"P1J6GA43I$_-E#09-([5E5_#Q][;<"JNGS9I8:D* !8HK\8;>BJ'%;_7,S .:SSNVX'!? _3^JSB.W6JLFRAPA'/CX[>6_3:]=NDZIC977DBXP)ULB[#:2J48 D\>3\"(2+EZV H-C77+!!Y> D10:E7'"R!-L)W$UW*],:+9W6#I?^'5-9("M0+8JD^<+@6MI!+?U3 9ZC6K&:Y*_V-6GXCKE>,(#+->0LT;0$:9EG_#7'%R=^U2O3YHO?87P57_6@LO$LK C)%LDXA^9C@2]&K0(!L:G7@U.)!>!:*U@R_+'%@J2QVGY"!V58D^?)=OWNA[NR^! &&);NGV[=A9RA6DGU*WO7--P\5E15 \SF;0OIHN652MY39(K\D6J7*%**>!HBB19 EQB91:13J80_1THX7G?>Y,\[O@*3%NN_*P/TFT3T6[D1$,ZQ[,7QUSCZCHK8] '>HPK?CDE3Y\9?U,(JTVLH X[$9_'*COWWB_@7KC9?$KGN-I?AC2 X' ][*=KZ#SP7DP>'Q0J53.JGU4:\7P-!C BP-\%]W):&OH2^ZM=>=4QB0MF!CM"Q>E_<3(I][UJ0,T3.=@\]ZJO*G&0FQGE0L( 5%XK4,9_^5 *O::3H_(V4L 3LA-*+=*L__M;7C&3\Z< M@N_]<:R!Q9RRW RE<13MS,59PRU %!1>O<6[OTI2U[\H:-O<[C?^I';5X#[%2D\4'MUA?W]?A(VZ*5V(=6E),;9K[5)$ KF5R"C,$/BIYV428H&G6,]K71;!M>3%QC'*=O>A"/6\S_%D]3C5)C_\NI28TTU": ]> 2T06JAV&)>(:H9J^T_H[&U">7J4*T(R[/7*I!5! ^K:(X'.1>8,4:ETD.,Y1!V5_RK4TEUS#1;!Q %J87H6/">^!I7_[98UV&QT^#=7MY?TW%A.QXT-E5=9!W4IB*)/"./-]1H]QB'1I^ Y3[(V/=7SV-DF%ED19'4'-NV+?XP"0!&<4Z4-01K35HZRC[_*&;KYK7J8D;-=B)> NH02.7.M]J(/9%XY38ZP17708DM,TF0(_;"?VHGG-3_!GH%=]4\15H T5R^A :9P3F#/[DK=-H@R^Y+4/2H\Y<."#2 H'Y7B=."3 _?;ML!J94? PR0^=\[GL)^JEOYN20&3;\X\E7+MXC(BQ$C9C74/(\?N8(EUU6T7) OES_&)(&>"]%I,K?(T+VCU%V5^P4,Q]9'79W&?-;VZ#A@+0$.;%HUWR1<3 @3MZ#C@?-3=,QTA_- #ZF<< F%.F,=Z5R$-JX^QWY1*82B;:Y?8L WO=Q"@.QF0Y G]! R2;$LI@+HJY1K.&&X+;D23H3\%U'*YE32ST( ^,1LY)\R.U_I7J.,' CWJ<9/JP,L&-*1(^,O"<[Z_ [8*9%$ F-[L8IF',K%W(F@BMY)W: (-I[$<#:MSHN3;AB_40%;#!6?V 2^C"%Z>WNGMGSP1 T?G3>WW$-T$)E+$_O[["E3OE*)+A\",4;?&?=KG'@+/*JO\&A9/M+%CA_59 X97] 5:3 =7\3>R5%IK+TBMLHDW_-"=N87:!]2W>%EV]SS@30#R0@>K#(T199B6Q)NL'R /]Q*/0 56T;5%L?I>/3"\.A\;)D_?H0P"?\^"[^2P)3'&)3MER(;,A*#QME+DZZV Z&>\YW8;LP+8,)]_^+G843&Y;>%P49@X?URTY:5/RF"R+*TYMYVDB@6SP_^V15C, W]D.U?HM<2/J#PV-PX47!D73#X#,?+!'X"T,&^R_+(J9":M@30^K>*8/>DMW,>A% '%BZ(F]NXW[6:LST!S@4GF#$X%W>,ZW0R,F]&+1T!2ZT[A% ($,2.#\M@M4'S7EK) BE$W"JM,A,<=IEOT^0=6.Q6+7<:@?SZ1F!K)U$-\QR\6%R DU60. !HQ)E?"D\.Y)\:=*".*,V9\5_N>M::I\].P)C^>GY$2]D5;1M>^1_;.>JY B!7:3U;PE7-UJ,0&+?7W'[33D,QM;JUH%X8^ KF 4@IH^6_#&T$NXX5Y'=5)Y?>N =C2&<6(Y6^'\V]WB0;Y8R,@0]]VI9]OBN])VG(\-8 Z8K+TZVT;M-@Q0*U.:EF4G I3![SIP/TTPZ4,D=>F+WQ9Y,;*8S7D (\'%9?&U*A%VQS!OFTYO;12K)3#) Q;\= S6N[L87H$W]\<;$ ,8 ]S"2E)Y-BL5P,HCQG_,#&<*,)6HW-8>?/GNO4]"AX3H\: ]^IT@=T?LCHJ]%\$!>TTSKKC6UAUY#=,">*+]; 1$POHLWY;U]92U;DKSZK\607JOW55#> ]/9>C"Y6NLBG:M]_=3K =W5!5&60I3###!>74)#_9EYUSUR_'^= 30*F5-!M<-2P,'A[8T.C17@_2@QIF_J2G?/S;$[>#F,Z=O?5@&5WI*(#*."3L?<5UX.Z6Q9;Q[A.D :18 5J"AFZ8A3R5EM>1)O%NB=L 1\[)5A1D[:3 6X4 *T,S1M%/+!""K>E['73T%Z3KT%.-\?MX[3GFU@(C4!M?DH^Z.BL)#3:[YF07>>0[ !;86I4G#R__L'3/M.TZ?D1MY8HXD3"VS] ]A$C*1C_=C@/I0YPICC1]AHTG6+UI@AY>DH?6,+V@^S:G+P\Q8I,%)A9M(\#;46H DDK7#]MA?JM@>"R)7"(_FZ_#KT$?8)3]'5^FET&C(262U/U*2G]:[THZ5]N8F?D" N"Y0WHKJ(85*;"\\$,EB(KVGP&SE,@^V,-H713J[=8UX^ #^R7AD(ED_2G];LMG> &Z8'#+N9WWQ30Z''7V8\BEI'),QCVYT:+1@Q@1102DAYLM?;U#&+8WZ0]KT ?F]^ MG(:#K*5/W_(GGY96MRF<-Q6?/E@\W0N[5!C*C1U:["C9>P99_YURTT^) K\&UT-QZ(CJL)SKE^")_6 ;3A+^*BQE"UW4S"6^!'J+LEW*.YV!>Y0U1!N2)%M_E;#%,#0V!-AJ5'J>4DT%5#8 %PUG/8F']/!G^J?+3\&$#=K:3JLO)#DX0>AFV0>=KDH3KZ.O4E[XLQLJ#'W[79%GY:W9IDH%?%9U#M*/7B2[*$XV95!&Y]'2JU*VNN]_T+<] +^7[%/R(,F/<\=SA9&\3GH/%9,J B ":[UC+LHT^'B<6A HGCD#R8.KARDO]PO)UD/09+7A>"B[9D ?IOA00SOH F3*6?3Y>G:^9;]Q'QUN5J0E<6H ?R26^#^A_>3^S_A9MS?L $8ZI:: 9GRY&(\CYBAJ#]RL3M^8(]K<9KS1MD!>TDXGHD8,D^Y=%_MJ0(NW%[0%45H.QZ=[ _9*ZW]AL09*6L#?+[/SH.1%[([-F+LV( -0J#BA#C4196I+CHHV(V"Y&=HPU)")9 \:=Y>%XOG?9,PZ;.NSZ/MC6! E9JEE@+E+2$N+O]:6(U;#=6E1<<+@A: FD[BEU!IX+JB<"BPDJ+1<)O=(@B_E_9JF8D X/:\5C>#L@5+OZ,I8LDR)-G_?EEJ PZR\(\"J;:& ]*!FIC@GB%@\U1U575>J!7_?R409'Z!3I$\6S\M3-T<%.WJ#]]=" BS1*LQ]Z/[' 9E85$RN\ %>F%_-HH$<"!MP?_*6*I#G<=B_IQLJ:8Y=09+)G%B )2+MAS"GJWT*V0^_;GF6AP:_Y5*[D7]M$'H9[PLX)TAI=\RK4WS]/"Z3GF7H8GFE ;_GDA+)!]MO6#H92^K$'0_3'C5#6L^[2408?B.WV?'%%RHNC-)%IV;[9:*N#&N?6?V*D* C,86(SC+6Z1V/I6*.T9C9S"N/!/114:Z:\U S[O)FT=;EU"\G*X13>)^^P'C=,0K:L)JF%([HW;V Z59DA;E$;'$V-W-W#)+=*5& X>^&2X/X0D/6,$?@K=Y6_$&$R!%(P/_//, ]Z5Y/0FTMNB:IM03*O>![$CPSJVW5 M%X:ZI7TYTU'J8TR4-4UJB;N^+J1=%Y/Q>4>*(Q9A:F]SS?W\KJ^.+,ZK! ^\XOX 4R!*/^$&\:G551LV/R#,UDH_\E1_LJ3*.Q4C5*-)C\>5C[IJU(?,"G9X!$EM7&LA LL>&O;++=F^A9&!T1X\I%<'4GR<7C=5(]J?L(W\=_'SD!"'C&9*5K@0K0P1[+7!()"M>&QT&!>AY"IS^9 / 5W U^PR44*5:Y\VAKZ;BX\)=N0<8YEY?B]>8>/!A?BQ)TST8&&%U+H2+,DM:.V&4GVP GL4WLLNZVTZ_0NML1L.E=.R$JWNMBS<.CFJ_9)L;4SA*<2Q(]8/^J H3!MI-+JVJ MQ8;IGCHSN(C-G/GBL[,W=:?DH8 >#PH>3A'UR_*MU"W#XZ/'3.[D 4"QKPMU"B04,-KFWYZ@J*P,BGM6T8OF$T#R5Q8TU-[#KGTA=J]P@;PFLB0FO1':< 8N-/,>H$1KWP+*##=[$^2EX:*K+?^/:DK(&^ %RG)-!=U2TZ##*""VAJ 0&C&596 "@9J2M5NJ[W%8YM5E[9]+U(]9[<&@,5NOB?KYTI_G)9#M_&GQJ95>I\/*$=@]8RY R^&7J9G/>SA$'Y17+XTWES:[S\=>3I9]\Y)9%T(*BC%?W<^V3K:D[4<#C'T,I(:OMP %T9R( Z2OW_W?IA4T9PA P.88T=//G7B/&NXGR*IL=E&O]X(&=E#?D$/B&P(B'%EFS.7NYEN?V\R4 4/%AA"@\Y$?;04=(VL#X#ZT^R9-PJBG<[#/"1?@AM$FPA7 384=' ,O) Q":0;_+C*W=T0/UX;*L:%,+'@ /L"2^/<4!Z;4UH9CH-)N\XVQ/'$@ ZMH%:EL6M[PHSI]F?^DZN5%SB& ;>R0N41+TZ=-/#(==WY,J-H+:!$8>:JGO\NR7 BHA@X W#A4C :!Q5]F/K]-2X4"QNZK2O+UKD7^2R+&4ZZC2X%CAJ897+[F+C N_W ?_>AF3+9\=&P;+9.H[F$'G0QP5VH,KF[L(&^7P7GY06P5/Q;=D0,)!I^AD]>K2,^ BA+AAJBC"4K[)-'PXEN.,!PWT,X,B _?M1[-;I $&7E98;QN$V5MHLC6Z2E.G_;2>H9"4UY/3'AA\H)\B&S2_@_#P2TU,3 BSE[;@9\C0/UU%V(SA0;HFJZG-AQYO3[/!+9B)H)QG4\5//LMIT.%"QJ%B#:D)]Q '$&.(GD6"[*=E8WRSS[VSX,>G:7;(,FK:X)VZPV5DJ)P[SD/=V6C7R\;'P/1 -D$(7E7K=_8P.)&;SF=A$62-%!E=.BPT@JMO+LZ>AJ:)$9LK[E[\OJP*K>^E+Z!! NUQJ1^U0LG2C'PISO/K,DZ_#(Z?AJ.A):8YG@=_9#/L-P_<-6Q,07%O'ZF%M ]!\ :%_-%KF8?"AYH*:^[?;XD[[%FGW7NALGH_]Q+:^L[(O>@S>^16*PMR4Z(C.^W7_L T?99BR9;VK^:B'"*2Q7E<'U WUL:DGP2K8T!T9E&JY;;M0*G-E$ODPFD$?>F0GXQ >E"!6VM\#1WGXCU:@JI!5)JC1"\S0!#I\63 I9Q*& ?-KM"*%-L3M4VRZU- DC@: B_1$$X+GI3* YSW;(VHBP2XL71IV$UVE2K\#D;G^>!XG'QV$UJE/3OVP!>>Z^E?ACOV*R;%?:<89H>%;>WX+/.8FO3S4Q7&LOC[8ISB XF2-$ J*#PA61U]8.5,*X-;(X!_@S, 0HG=$WC?I,O:?TBQS!#6("2BWTO^--=R$EW4.QW !2&*&5/> "K/4,!QI+<8=ZO!+N@CN5Y.A( W*YWPKCD?JL$#(7_Y2-JZ@IG;"5G6 K3KC"]MP=ERP,MN2C>K@"-_QYN*54,9[R*75Y+84$A-?J>S]>'"W$&U4'9<3K0XP ^9S6/*W#4[5?]VQD2"O=SUL]$=\37@,J.-]".=:#"VBF>V _"= V^^5M S 4H)X& OCS T4%71$5C7]%LZ=S]^P9\L=]9"^%^9CQB@]GT0#W:(0D&FM8BT=Y^B_W-'L)! M4#*\K!XC[MO%JTLM>8:%"ZSY1L1KUB_L4^ZIHQ%FUI74>GDY2I&!"WBF";XZ/Q( 5U!Z2_[%8X2(PSQ>89I&:"D8MSE?&U1T#MP9M4GQUJ+<;["\.&Z5,10"1_(4T1@"^.'WYC@I5>[4M,R^8.\!O \P\CRB@3R*/KL$,4LO$(ST.D^*ZIPW+ZL:8(W8V?4-F,ZG]1)+)O>NYX\+YYH(BZ@LP6RN 6%5JP9:23F< FZ8&SJ)IVY!5., X(YL]72;!B6-6^';5LVOPBBQD5UK;5RO9V(AO 8Z@4^N4\K@T5.5QZ)>*8I"0Z>A2Z#-)1U$@E=C=2_TTJK7*-(:TQAZ(#= ^MM9[HAHCNW/@VQVD/EC)NQB9ZCI;1P9'BY&H K.K";2@M5%E\5%@T<46Z,#. $[PN7"-3::2[N:GLQJ Z/&I]K,]BZ7])'[,P:HH.TA^+ID#SQV>V;B9/C>IN#>V$ $[OLE!N#98]U\E*OR3BOQTK^P5YS;,T=@__"TXULDT=_T&LZWL_DA]58RF+\VU9: IZB=#:DD+04](7J& %Q4X9E4L?%]";%O(GOQ_R-#BR1/G2EZ!F(VG@] >AY#.=\ VKI?+DF4 R@3I5L5M \S@WO&T/&"HVIJ/#GIHT 8$1($WX3 ]6A0]Y(F'U/I-R[2V-\NP_A#%@;X(&S'V10@#9H90BI 9>AM$S6W*9CP\XC[_QU&D.B[O)P&O4-72]@%,P7-] 9@6X NA'":;4,GP8&0.(G ^+S4=X<86D*&UGT&A%/G>))(?L#$_?SV+ /VE I? --[HE#HG1G>V28S?H,R\I4P L-@.V)$.,6;_W^ &&(I(YU'V+_F [>BQ/^OTT+0$O&Y?%18J3-@#292U5BZ!0>(; S74A;BN=ZZ,[511$/W XN?04;I9>WFR;D!F)+T\46!O\X);($HB3LI' Z&R4.G+#YJKW?LV#^@F"F7@5(;[X3DF!)V9D?SK*04DJ;@J;?@KE4<^WY#O&^;:U !M"$\&E_WHY-8"OU912BL]HB5'Q4P^DO1U1HPHDOG]&XUZCYC6\]JE&D\BM+GCU- 8S,+J?VJ\3&_+[?O2036B6;+=X_'N+D6YB!?@@'F$/S3Z7(79']T_+64BF9^4F9W N:&*YFSZ:G"'U",^\1BGR%_YBRX$)YGWZ#M5%2*G_K]^WQ%S Y>&552FSGVKN7*P Y^CDX%&27Z"9C/&WK@YYZMN,T,'SP#75BV\W79:G IA_!Q0*-.,M';EBBJ =TLK 7B$I:=WG6'LYH73VH[8][?#NOG)D?P>XT<73L%@/26B 2L>CCD'IEQFDK5^+1[C9^((;#F D#AG@!R7+?MLN^LF*0=3Z[SD4#^;Y9,788X\, K4-Q="I";L/F/=N!VAK/4-[W>G 1,C=[=!ZI)_=V+/.B"8-XTN5-IQ*ZTR3J[@SR _P$!)#W+4\=]H%NC:8L7'2Y;O+\OU(Q=MJ8F?X#RC#%I;<^CF.%T QBB]]\WKPMY 8&D^7H4^@5I\^:*1@Z\,KD?A82/=;R6BQ=]? ^V&P%@YV%.](_6QRI: -?@8]_U: T-40RMG'_KW6>Q2!0^6=TBR\&(@Q'BX5)6L*5;5Y2'4)CD4X@5PDZU6Y6=?(?=M? L01(>QD(8*<)&^\A%":LX8U\"#0<$7Z#M='"\$='%&ZSAT(#GUJRF=^+#8)-R/V5 G?&&\0)3F9;4,XNA&&7U@,E0N75AC3E7^P\#KG_>H1;^/8^]WXCD.J8BKG%AN8@8 N3C(#0,Y;*#PGX6/2]?=LI7>^XECK8$W+I(G4HD# '*_N,T(V;@KH?PS,G':H1*U ,M__&(XNR3?;QS@V"Z2D*86=-">':;(WS:4.N1-/0=1P0NPJ#G(,R]JTB1R'#Z#%R $JA) M+K3TGT]57P*164CH U,9/Y=ER]5O!FDS%64B"IL8Q<.?9ZX'&,XV&( CK@ U/3F?O/9>%;O=#"\SZUQ1P4\=+:+3FD?O>9GQ@R,EC8.G!OE_Q.J"*IR.\UJ(%'RZ11C#5L6ZY&EW KK'SUY0..KA@[O%^H=*CU%VE+1A 1 OVFHBP<@6QJYL>[S3_JY0 RE 4#,R(?PGR6B F42[ S429_CD'@_>&TW_8:BG_(C I_4%=]WNIE#DGIPL(4[&$M[A=R%K(7C]);L1G,IB\ VO( JGMJJ,,5^$S=9E4UGV Y- _O#9S*Y7>/>$_+(9Z$W$BE56@,V:G??1,EW:Z0A;@OZJ8UT\*U16Q*]9\:I?T N1D4M=CW?:^$CJ0<1@*E?'+K&L,[-]L(L0GE\WD9-^?%[S#6!O*; C8S13NBP@B* 3C%+H0@.F3JX'H'V)M+&/P0L_D;[#)JP;OR^SJPR+PU(N@.;78S-N$RV.Z3H]RI" ]IJ"BG*R3A&DZJO-$6M*4T!AA7A=GA' ">L!7MF56CB\DC9$7/,]; F'^"H[3CS34/+0$3!^2!6TL,Y-/A!V&0#N>JJ$1M:8=N_4@365$TU.CP:V^<)\.4 2S>LCCWK/[WWR"ISFS!L<[C958F7Z6!H9#<@$\<__K?CJ3W.D,,:#FB._;4.Q1%U M=?AW\$ A#?Z,.& A:(NH#/Y-/%:UV\)4/V( *XOLPFFY9<0\& 8"7,41='(8@* ?769#!-W&S2[A\8\#/:8W89#\Y;5OGV&:C]9\5U1W"!$C;$$'^#H;K_J";0=8I=I R4U:[O)MWM2ICC$3,Y$<0]Y>1&9;'F7NRH&/30R.)VAE(D#XS@[+*V] M:*M52:RV(#48*II!)1D.-5Y( E.[5DO"*/9M#/TEN!M7X2;T*G$X;U780;F?=D7 ='2S_M,!WQ!TCZ1+QSI'M33OTWA%(L^VRM#O^Y6)6BI%N10.CY1M$I%VE6T.GTHL X7'%E=7P==Q'IXHWOYF6 X*42MTUX1V''!K5AU!BI^[!)-,M!;@DN"G.J 26PZOH 2& %)=A;"8/N@BOI4YYK5P2 +(%[2X\&M%C9;G-V ;*N,)D7!S0,P(+V%7[)J%)UI6=*I"M\2MN+/ ]6)+GD!$3;R]$]-\OV!Y\:)-J<+ P(N)96DL28'9T7,UGH9=N\)E_Y*]W+Q@3=D62-.ZO5)^12(.NFNCWZC-). =DRE7 #KC](H\LJ7!\X0C4[3I8L3K3QN2!6S74R/LB-ZL08D9IZY5I" &,,*O_]OGMY=I/54[S6"W*J_#-K47:R[D2Z&LF0$82RN N>.OD_ST^/J\@5Z'8O&\*0,M&-J47A["P1QHFW5E2+ _:?Y:38@?='GB&_^,&WFL_ NLVEIATL'^(^CI-+3 ,74_K=79;C+-CIRE]#@'3:Q6IC_/"Q*@)6ZHC]N]U(\),&:#:\TI6#^XLCKS@R_E ^V=">.YC@'^OT1]/,KY<8(AJ+UQ? %@YOE^Q?5.)[+6P H:P7F+LM!U8*A,4(WWC-Z0DF5//CNS*N:WK9_J]E[1V]RSXSY;Q\A?D+T)-=[+@ 7@F7':/8(;,DM'P[8OF,R]O!N/W =,/ NZ8HZ==QP,PIG>CN.4:[*ZN:ER">E!W$ B)C_BS+@9AZ_A6V5U!1&00:Q5R6:"*+PU$OC3759^W9WGB$2=,UW^BSGGXRC#M.# "]R-LL\)30Z=R&TT641SFN&]N0N&HAH7G!]!7.SA91MU5]<)K;#VA]63!CZ(XI!5 =LD+CJHW3&Q%%#0=DM$NB^V.@Z .!;TU+XD'8JZGPENF(?",12X3^!XB[YI%47Y_C,_JKZ9/*>9DO]9(Z_,8H5-4/B, >;!!;U#J8!_PJ18))Q[)\;+>52D?,,E?T /;G9YM@!RK@X*T?I*B[P%74L>YIF #TJY0!4A'&***5@GW$J+C_3E;_!S^$HH.-6 +9J5"\#T]$JY46*Q -$+Q*.FD>JQ%P0Q+\G>VCN(H2Q>'_!YX]F.Y*^:#0BEEULZ G],@E^4@B&>(&Z.DK?2*/\JB^!75='R*$WH>Q'&_630^A4U5T%AW%"O0B::AL?L+ IZ:'T-C#/IF-7PF=^Q"TM/'C;WBZ#]P-+BCMWR5 M7PUUA_ZG@A)#QX4>IMV4C^' 7M8- !^)1AOC(R:;@U+1=^.O2/P1@D!".(P4XX8;[H?FJ4G877I\'%L0WC"A(4YM LJ (TVND8:=B\,\VJIG?CU;P.\Y(J^:M+WM>'&)B]248K>#'ILP>+8DGLJ0'ZA9D /A5G,]-;J=,[^0W.>.W3W2FB2!E37Q0EU[NML5JJ4PW(R "(8Q2CBC?+X]D)*3R-%[RW?Y[5_.G3#);XY[#$$>1X &/"F*6_IGELDIHW.0 =W)MFRHT2"W71RI)@"ZJ?/U%5_/A^ V ,[DVLO(>KJ-(P<\:3F!U,OV9'FI]AW[ K7G:XPQ@DD 1>*16NW[LX]-.]J_\RF7R238!@:H08&*AK=YD),2#^6(XD9U2 ">I,#%M+OY+'S3;S!UYYY7=:_.> 9Z%]303,= H\,!^":+S^KU*/6G#_1?,!AV\=/+W25Y[C#+V$.MEBO>]AHVZZ^PTZAF/I6J5NBB X"V9TA2R *MHO3,'CN.0 NRX[B$XO\OC:23%O0#V)!/5+,6&/ -@\5E 8I110 AOGX*;)'%T=XN NN34LIYSG1SN%A4J0_W@@Q8_G]M1M&9 ^T1#K AE ZI)O1(:5X, O*IK!#5D B=L\:LRYQ'KX>RO"=S2 ?T2W H !N7-H9'9/:Y\7P5"GH<;>WAC&.Z"=;_&%=(\ALD^3L!;JA'[K,;.AC]5S 2K#94U0M78MQ?LT# Z4U$W22/8:5C-JEX/B&E2W24?MY?^&:<@%UP_3C(P>I[1!% W#.Y70(95Z\S^BD:^#/T,A.Q?VSM8;^2W3V5!M5+O(E4%&]?JS?S %@[;M%RN4CU >?Y;EU;T4Q=S_%9KXA AE@*G/+*E!!W8\ )IMF2]2,KQ.I+/%@4'J+4U]X?U5#MM O2U+V4WTI]]%3[2H,D/AE?B#BX8^>(Z76<=U> +4+&H)I H0EL6+/8=Y.05"A^9P AF':CTJQ@;+':S-3-YN]Z/ U756AF?OR38?0IY:B='?&G\/HWXS.95WN@8"BF:2+8[=U: 0_7W*FI(0]7!SZH1T\C6T$5[ZW7AI#EUL)<8]-9Q[FBS/=&,C,[BY^NTQ$5,IBH"H 4FB@O;4.=@$ZU/1.*?!4D BCV<6(T=KX.Y[7X:3["JEB6 ]/N+MKI$R*L>+C#A/?;N-W0<<>E7(W"LV/?RZ;9& U]9H$AC-#D.Q$&VTN_XI"^_CTE-U/71K[QF;:W2><[(P>-"YUV;#P+3% Y-V5$>]&OW;$(]RY^K3! RY)*"VCSX4[^KWH 6@"6)8#8/NG#QTS?MI]^?N-YU5@MI,5M(]&.*Q61US4 FFI/ JPKUDU1'C?(@%ELL:RF0 O;N!0LX^8_P QQWH^O5!L%V:?@&W4MA*^4K&52\8+PG 5!I6_$QO#=$:MU0 7N?EQ*&+VMK?55(VA2E"MAX=X=]9^>U%AR8[]"/S/5?\S&=Z '("8*KX@OB#[#%P0+&K!"JNSX;;4NH5G%P=ORJ;;5A*??\=N/<>I/>86( RAKK!W $]:-OS#LM3+';F"))$S?U S]NO?T,-D4'HQXVWP!9(76RSYE2;6IG+*=_.?*02B_ O1:") H?F3(VN27B!/-H?0J17-.E:4VKJBZI 25WEG46XI,U%H&F#39\<;!2!?<8]ZI;W"+S/LBY+58 WVJTW?#<>";;Y9E-=QKTNT?1)9+$W?\E9Q;:%W=/!VC82;$SX1:ZT/O4=8)Q_@$R 1C)Y]7)3&A C.P/^I1PP$B"T90G;&.EKD@4%MBRNP5!J2'?[6!6N5P!C?.\34;$; ^0#(@9JK9R?O^@Q7!0/(2)>(5U8^6@D3T1GOS7.H5TX.ID$Z Y8;\+6+\2JH#TMHOO%]P(S#*1XAT"PD&??Y):Q&^C\R_=XM-9K&BW_0'S&42OOOS 'DP7MK5H$TM7K3T TJKTHG9FSGJL0&C$$])/;T*,X;_+Y91,V<96$@RH <,^C+TO L@.8LG>QP363N1D7V@QLG[W; 9B%__LR)B[9 -:[AP_/0#^?>!V'^Y=M\F%L3&9<<'*M-4I*G8(@A@_L@D=::, IP8_[K]0[W(=/8 T-_^)WE;@8Q-9ZXL1 %VGZ7&Y.(5/7@\O#SFANHP@2RJ CP+VEJ[W&%V\DGL[;_/ ^3WP=8\QJ-KP9JH]1<$(1*FX \WH:<$5IHM3GK(WID*3=LXSJ-XG:\M(6,05L.[/ A[U;]F(8M*H?P3W#%N7M"@G,;0.Y7J*P#SUD00OO8:SU#%D7AYG>[=FY@9&OQB#; Y41$-'"06EMEL4BI(%6BKPQ^^+@R=H2U%Q_7(J@G1X,C*L=!%$=+(4HP,T]"BU&V A<6A&VY9I:-CJ9YDODTM2P[A(%L=D>VLP^3^H'HGJ#2B2KKA'*4/TYC#8FI")7$Q /A8TRL^':*+6+>E:_-[J'P6DV^6:J3*ES<%\9 A @+6.KN_ DU="L S[O'&5PCL. CE_R?==9 ##\+4;EWR86!ZQU.HAL] &)(N_3#Z@F(=VIRP14X48)^V"RMDKVKG*3 Q?,0KUR-$F@!!S)-%X#^1)!R$R>O#A&+WD!U=/PJ-5.(VB8MR<'>7ONBEFVI2Q[G 2#?IC&$_4H_!Z88S[B$ZU!(9/>T19D7U20:M,)R V[^UIT!= YZEUKO2B\KN:RL2 YVYQ?D)"I5\2IGZ>>?TGS;H\%0WT1M?\[BX@/__EF#*9A$8=YM=[EO;TBFU6.KGO %R$+9B7"M+44$%]\*T(4O4[XG:(2NNZ&E;*V*<<2ZNZ#TA3NI/A9&[J(C3ND):\6 >_QT.&T<:H?#SKV;:)-N@5PWOI9M-#[<.0MTV*='.DWFQHRJG%EVUA:]A*DT1PQ1SMM&^R61-G8O"MK(0_H'[XC(V AFX#A--?9_A+005

IVRV,DV(R/"Z!:E##YA9QIZPJDZ6M B8?V?EF&,1YN"^0!64WJE:C13_19$KXU39,3=NWU+J)S:7)!CUDG!.;22M\22JE(=NYN598+-^'FX6P<)#66LY\&[)C'=BEZK+SG)*G;@/%*U]FD*":C3%KCQM@<+Q/>H046XUR&^MJ,SZX%HJ49P,# M D/S;#DHB>!L+KUMI6R><415-&3]4#TN"'1 <8HWXQP^,?"^9>6IUV8 Q*#4@&??S]M:I@#'6K^5G#P$0XR[ZF[<*-F"%T_2V$@2 *VRO-]O1K',VS(_'J[-V4)!V1>0T:E(Z_N<72=F']SIP%:SF4,1"-MON O88#G#! G[&,IO,VO15 00Q"_&:6@^X157&,QD%7LN&EHV7 ([B;>!+K%'?N+MVQ&2MXL,O/ )AG]7Q5=&/ET]A:FZ[43.:_<&/PKUWF68[+Y!-['/'V10S4WW3&;A](N'SL_A,,(F%+.".BIX&FB_8Z;8"CZG+O3U.W5BB$S5NH'B; UR-UR.#F WK%48$ 'N,H57V,P9W-IB@0C-E^/8UD:=2,0&!@:-NMWPOYMN)?A^)G(5R3>"_GK 6Q%GX"A*.DFTOU)1$:[D)S_3?CB'A?HSALM%?9>:D&F;F02Z QO'--H(N;I/(]O5 %L_/M1"ZK=N9C<7]_D ZA7'$!^0JO:&:6)N(*V?-;2J#B$ R\ %#W8!$0\T705GX *";3F10RZ'@IJDH%6$S@3^#^OV6PWOS?Y.T'&64L6E>JNX=@XJ>XL>F_(7TP6Z]L LM35?YB)]-BA[UN^HD$NV$Y/3W,KLS'#Y'J=Y"'JRU&UBG=H')J2N"==Q[37?ZWU,I9R9'^8V\) EV9:VKQAEG\7=':BPQM_"-_M!PDG7*%A1T5 @HYM@W:0[D=!<41)EU4Q57)UFV0 T' 4;<>QHAC4G.!W-R.-',\4D.RT:BM'Q J67)Z:]JA77\53F]E55N#VH+USI%ST7NB*''E J6<%X":F]0DRKWF#HTCL96:K98 .-\4B*XD$""_&FO:[]*@J4P*H?&=K"?,L4=;984W#-J%3-OY-"!:',G7C_3C.;<5@C;58# <>K/3!5&1MEZ@J'XCLI0,L9_<_TB]A1MW;I\N^A'UL,.B4W*/E5&,J/=BQ@EC4\- +$TL=KG=7MJEST+(G]^*.D$(Y9@3,MF_3T-5!3YYL4F*5>[T;>3W<= ]4C8]ZXS? !G](V/AW-P"@0&2UC_O9N&702WX"$/84+< ,H :9KEE\MNO(V82H=^QCL&\ECD;G B_GPDL:\5=A!MB&U;8.J*Y6 RC^N5E'<97O8ZO.7]7PW/3;0TF39T.(0++VX_EJ' _K4@HXKHA[^A"H*HF*@D+WA=-4!YR\$A>JXJ6,"P_)$-X_D47< N@*S-.:%YU3G\ (@10'Q-BWK_V0IW;H5D"W%T0].NS^;JH#P6@]CT9>-U_/9(L_W(0!-99=J=FMPFF !O[3.[AV,5NCZYF")U,^D3 T9ULO-CAU_C"B0B:=LC!E]C/SUUB:5I^R[P0@K@$??B;'B)M-T ./!%VO1Z7B@A,"" %L%V1N^S-5V+ W2)T@-H5-YE I&/=L5K]RUL6WU&WJV%_>Y*UQ*OT"HZGQ=7!N(> R@Y4G!*<-5Z\YC_"GM.Q-*!F);VX9_H:E=?@[/FVQK@ATX$'] E$&V%HRO_SX)&& 4&%WN&\0U;:A<*N)YP['2KF4/G+$!K@'98!ZHE]J3/0HTKB:^>#FG,SNMA&0I;@MF/YM16W*(44I#?,@F*5?W.4SULNJ#Q&9^SO\]'LP9%L 4$-[)<$T5($PG+Z4^-T,5^%-'F308;K QTJ$HH&G)CA4H/A4I&6M'KO4G$::,XY@ :A0M Y<%;RS'_R>OVA":CT^Q*[2?/39M5/Z5(O_KS\)S+4+.1QROI%N1/XP(L]\! 6KFPDBK.Z@K.)!X]CXJM&6/OVST<'!J^1 .; )OT.RO>KQ^K1N$RIB$WX/!L0EE;ZJN#QI0%'CF[TNZ9K.<-=[PF[U\DJ+YU+YO D'0AJ6D/01&VM3/<%ROM[K*N33K/P ]=?+KT]U;7 "$?ZVIU-N'A\>0*MS77S>C]VDG UA+VS^],J>HFD@4N M$BO$K!?7!PVD(7U4.J8%-5!Q9WD">VY1L.J0T[PHZ$P \::EQON\UB3!'B,+;[U +?H[BC_:*)5WO7QA.++ZSI;W7^[*25?H T^'BY>:CU,IN[+;+0:P/'!L_:":ODI. V-N RV-8NZ9+$.:\:=RQ_F?>=94,O.D]26(X$=I!O/()E)SQ;"[.E>GX&U?^1HGI6&^B]6Y0:W#58#UF8SVQ>[]O. 5W\9#8CX_UX%J\!+ \-S7ZG+O#C9E3C6PJV@+^F@!2%V(+[J >^5'2W15VXM9IC-4SIN[-D5%[91B;)'. M(C^V]&Z.+0X",;@&*L>L54 MBUPBM@!G<:84,VD^G&:727#>PC8U$17:-JLI,J% 3EJIHP^A-ZU&)*-;!@:U@;:RK<-0]F\4/#UA$$2 .*X%Y+9Y3Y^HUP8 6VSBB'0\2H8 -/BN#;0EJ(_-=$<5?#ZM&83XC+.!:X R[N5L[\E]Y-SO8YFJ3[T4"J\(^$/I0/V$T_L1J5ERQ9?%J,H$51M5'-O9)@T2Y3 5X:;-S-"]0$JE$I,9^4U=>10,EK,:ZNA+KA1N/6,MF*_B,#%4=.[Z>./65)_.(^? (-Z$I:M^/N*Z!R?$&AZ"+ELNT3(/8B)FYC!=YAOYK,)BQM00:Y/3:S_C9RC/AG6Q 5;J\>6()?OU*ZL!T'*U)4&SNW>"OPN*<>731 [_X (GWZ4.H$\$)SS9]TQ O1M01 *D(9S _Z);+A DY5B0Z#]FN#I$/6#'\*GS&"OR* N;_+4ORM*4L:B.T>"[T&,_N\ N20)FZ>C37M/+?FWY4_MC_8\>R34 [E5_'X(+JFOEVQ;,!;X!OW*?*CO9.P4W2$*]GR5Q+2/?.!T+XKH*R$YVM%2]"V=) ]6_X,&>C@ IO#2TBZ9D+*D7MX?U?:,X9JB:0'7>=BXS$B-_P]F''K#W*B)P@H Z[M*)LN:\,C_ ;.!*D9!K!=?9'JL0'IT7LMNJ,IC3(91/5GG+F@XD3IG;_BOFA#,L7O6LKWZ-X!3K 0E+3;LQW^I0W>QDDZ-';:0T$8REQ!SK MJKCJ%.>OB\ K%A-3?UUMXN"WB<#NV%7+\C"I 67/4LL!INY]A58DY6Z121_'UL*X5$_T(A-^!OF:DG5%]H7<<-LM=P+G:X'GQ"DO9 \N,\8T/UA$'5C-IOL8^58,JHP?JMOT:&BISHLPBV'AC[SO&_*TLW-Q6,JAF!H!]L YEE,C09H73_'GE-##5'])AA^^?L7M$F.6Q57 # *E \F]'+8C']^2/ H"!;O0QQDH&]HK/%/ 2CZ"\_UY_=OTR940H WI^U\"[>U3N\?/; ^C/DM>U1(9)\=4RX561YMX#P2')L0U>66F*_V[[L0BR66Y(8-Y+X H]A"SK+BN,A L)UL]_YNJQ-Y19.\6VZJ?)V57=G1PVMVN%25'4V]!#[PRFQ%'%QSRJMFBRG535,G KZ7D%CTTL8S#GF'4T&G1=P27"FXGK4$IV'T2S;8%(N4%$D&V'T &MDER;'>R0:2MGEZQ7EK/LF&X^VK&[E9*7*MT4)GH= 2<=OL%)[ ^?_10-G!K,]@ M!&S,#B"$6Y:APE4,!2 V MZ5/$0@(CY"AOE5FAY7YV",V]DR(-T U_1+U#=X*EX YJN*Q#,V<,KJ:='],]EUS$F OAWG="IC@,YL<"(8Y XF].5J9BMLK\'H*4<1"SK^ 90^-M,6FR(GE\1O7$7W!AL)#:#OF.!KGFM"VSCST8 [/8PDE [B?+<_EMR+E[L@_A]\OYT><%A5*ZJI^6VO0T;5X)LXF?R@EO#53G9.CDS S$\-]E)&G(/C0:_%L5#QUDRXV2H90/7:.U#^.01@7$V,H>+X%?9,!=S[OGCZP=(9 Z6**V]= ]ENYA1,E36;2RMS3N3'"DNY@CM)+8VFKTZ/X8\?V>FG6LT1:2T2O1RVG J@R640\$R@YQ]#)0PN79C0>AI27GLD(;][4EYK C/!8P(TP+[KBIZ^$V>M,^^-4ZG*]$3+; (36P8WXY,* BAHVA"\RPI_KC*T*Z@T= U5>\FFXELYMJC',-&(C,6!(\B0H@"]2>V78@!8\+8\\!SL9I%+?MCR1"*X=6 BTH 1 TS&^D-@'AOOYEZU\*-44_W!.4(\L;9N4[WVX<5*$ZSO8!+EJUE!:GV3V+(TZ5J %9V@T*UBO^'V%+/QM/]ET5KZ8W^K(B+!#+PXI #8,,>>@BVWCCE03?@?'W^L&QMR VJ(BO4=@,7]/6\KX Y_M5(Z:,/#]9/J/F?GH!A&27^8@?.Y6\N9;NVDV$8Y!YSC? W8F"I28Y'97%YFJU:/YXS.@I!4EO]P.I]/E%)0G^#JDIYK-[AS =RR<]9OV[R,X^!WC$'US0RP)OS";FC]62^FH!),0F 5$WJ!R('P)$T, FT01[T[F2\H>DLB"P$_%3L+FU"C)R_XQ0W)(&,6V$XK)56;G7K PM..@?%[T3=,B$5]PNE ;D2UE?W-@*>"T=M*]16.V=T_U_89@=[# P;*\R]D<4["7.'/-A1'0-"SJV+U_SKH(&@=KP*O&&)W#311<\@8'5!#4WS*Y4KYEE>]0D" J:!-LNIH6SGDH2>F5H4\6*\'X"I-5&?(?M"(R/HTX3O=18;U3_2HI^S8\0VR8OYJ;.="H_HXZ!Z'.&QL TF['9+Q;)D"O+K"FUSEA];G7KN4R&SZPZC:UTO3I49.O(;D$US39YO0-S=U%,,O= PW2Q"9^D8PH7%, H @N28_IM_B*:UG#MB5+^^Z.809^'&$M/;/OALWZE5@%UY; C."\\\0?]C-4Y+IYO\ -J53M]EOWRPJ385\ E;I:B)8HC^E3W$!#K.5=?YGH6%/[TZR$#H,JS]#V%/Y4%J?H(F.5DC'5B@D-VA= @K"1']S2H'>T;.B-%TWU-"^FFQ/H;+6 :<*J.8LA$!@JOE>\WAZLP&!_;+,D-M]5 2[93^!T+[7_J6>ZLL!549M:Q %LX]VRO/;?DO]VJTMJ2Q1P_!E)Q'M,%I\SZ_<=L &]'NU8\S-?:GK7%,9SDMVETTT0OLCI"(-DVAHA][W?%%.3%J'__Z?[F!R6?MIJM7 G-^MAQR*31\C= S:Z_H5HD7_3_[-S@;B$1Q+%BHC%UZ/L/([!QX8;TL^\K>O5L?@ 'W?7"@PS?]J12XW1Y6=(%#0/?EC-Y']Z<:S2W49'#&M<*%B^$!0 H?W?BNJDI?HWH<8! 8K\BHF&7YH!*0H@KT4DN(\Y4858*?=5(?M0RLB*X,!A4RBS #'Q3&S\4Y1D*:SOV[QP'^1M1L* >U]"FRH'Q2^=#!VC.-H2=&F;=AS\LZ&YUM=D5*BF>FA@]&>AU^EV9@,JDH'@*'%8 X.\D*,NZ$@W;F!.%WR*L(U!*G@8['EP<[R>H+VLW9Q\;9&:2+/@[B.<]P7.(Q(X-3D(PJ>\S9 ,@/3\S:5#Q(FY7(P_X>>&ISCOD A /(RP!;1)1,-#56S-U<#P_M*)0H&SU7$T3D'P/>(K*I"OWJ^<'^J#@8/:: DX VG*UT!PZU.'N43HSK5ZU&*:^^4UAQ^6D'T=4MGW:@1F9+KT>[L7]);!#.=F%;R:0 NF'?1MWTA>UK+:!IOQLK\&X4V=J6^9>^Z:P32D)9(:956G1\)BP#B:$@/%W);XQN G!MG:S89\7ZR"?8N(N3F:R(M]CCY.,+\*W*#W/&X-B/'AP,=E.#DW^*WL0>V1 VU BOQ:E@3*?E3D,7F%\)(.-EP9:*SSR\OMEQLX =)7DGIRW^GD%@%!\1(8"G(S/]D6 YNR8T](&KT&!2PRXZV/4?\U.[WQZ&1L2'F)ZPD<1,SA .!ZQIOGN[5%8DSGQ@3:/.3A[=N>+RL7DK[&*$/#SACP#\L1>[ PZ(4A^O-PU#Q#6V-B4^?JIITA3W,R%C].'6P!(")?#R&"NDWX,.+>UHD?L<4??4I Q>[8>;?T-][(V"PTS^)Z4)K!HEWKS$I(B2K1J%-.>'X1+9HR:LQC,<7^;?4">W/V;VJ(GRO%T=%>JSO;%F8ZT;8Z6K_Q66QI O?0&V/CO6;@,G$QR:%K<@MA*KAJWAP,)D_2R.)00U']44!%'1M-%CAWZG];U9'8FZWH'>C)X81=$S?^1'HFA=W/"[D4<(PU ! 3/,98.SVA"0H#H<''(W^6L*#L]4VNX]D,(4\U364,P>B2G@+_*+@FP+..L#0!,SD /Z&(IDI?K'>W%$J;5[.@0?K/F62)V3;R(')LO1.LBWC 2(;KJ24D2!N=XNT'8-B\ &T+M,<;^G.[&'+*\:DP-!,IZC:2H,T4/.Z,(8X.1>".4/)X(5!$(PJ0*B\R,8E:" _/48R-BED 0RPKX2W;B(0S/$GK?<"J+)M'(H@V@[/FMZCUA",C)4KQ+_;IF^,]0= ;7I7@#S7C0NR"P$[MZHP#<+9 PI!$Q?V!_R7NN)H:NPDT>CGERJA60081_L.Q3HT 3,D2:"]1QV)RUF>]PU+_:6[ML187!N+$C.R.+F+VVX4!T=!Q:B&>T:B=O9#)G5PW]UB W=OIE8+%0"VUB(AO G+(I0R>3\_9[.6W"A *_$?1P>\,C!TJ <7;,[,[8'P7P<56 <^?$_^%KPJ\6<&,+8^DON35*S(SB-&UIN@CUN8_P4/BL*MM81('%-[3)).=5.A7FK7"'%9X$+^4[#UVTL) J7 ?5(ITY@T]&[[M^9R \;%X#NM\H86-5"6DV20\7=:][3!?^Z)B=8(-9^&G4CW0^ > 3:[O-I&E0+'7#7+(RHG1KY4@ C VYC<(5FU)4_@FL0BQJ_US?"8[!8::++7I3?;N EC7#%%W#5IUH.)UE >/S\$G$2+M6)4-!R2N<)H;[NMD72D(L'@BDUEYI<]9R_%Y, WKR+0-=MCJXQQ^ACTQX66CT'$XE:1,AIGHXZ!."4QF:.$6>EK^,;L/WV^!W4W;W* .5$&NU)[<_'W+UF7'&4WD/J+2$YCS8P=#0J[\!RMUCG]4&2L1G^@&E;RGOE8-*!O " ]-(QBC[O;)0P?.89G)_Y'L!--;*HQ.?I&3 V=?G+_BVWUR87#L#/2>V^#9.+#-2$*Z,P,D5_1-AK0(#[2QV3C5-NP^M5QPNHW=6U*/ D(9!';_YNC-OKES][$=_R.QFB3R;::K%$J;BEM0F-L3?T$ ;NKY[5TF>L=2 >72=XM[;4QU])NMM='.H !ZERS_&B(S8,7RHC9 EYWZM^0(9>*/A3;\#^*E8*8T*87$$*0-G4;PMM0KY<_5,6O-Y6,+BT()=1+HS$ ,5&]P9'B V%2(G&OH,H4UOI23? G)\$UP'9ZB/T3\D)FVMY>$QI0&W=I_>2O2RB,J^\FD%B=U [J-=5X_,$'$1U?\L)G/<%+FU8%CN]-&I[NP;=P5UH;0LT@,D^8#U66KABC\H+34L HN#B7_U]U^X\]OR3.I8- ;[EQ0H'Y&K7/E]OF:J':-2"G@@_*'+_#)$8T[D8:7PH\E)_X06(?$ >'K;B3I0 B I,;&G1M)E0H35P_W>Y]S"0\G:">J%=D;L>$PT=_R!:#K???_]OR+3M!FM])GG5DY,7!](Y!AE#&_]S0+.J S-NJ3+]\J(T I>/\WI=,!5KX=IQ1@O.. YI#/%W@X$>3J5IC^;/&YMCX++WK#9E@ )Z[AK+Y"QB;35?" N-T:?Z^V/XC-1(ML#@3N#*!S)F;C'P #$S/=5E*UB2GO$S3K KPZPM!ZTV:-P8=+Z0,5KTZ[*,/)O5#HBA>8M"';2Z3ZEK!48S\<[1E5%9#^ LQ&3NY9B,#6SXCT>P5%[L5'7E.W:Z29MT/[XJNFN?F@DMRH9'8;PC'Z\/?56Q)2& H94KN],:F&M%"\IQ.W=F',H(;"'7NAV]['14NOT)KO^(: '!&9XP\-L?J"QU+=, Y3+Q3,RLB:=B)UCK2+]^=](; '<94N',WYJ9]).\'\*E_3;)48[H8,XQ;T.:-T)] "ZE>B \Y1$WN_X"Q)*HCA "$OZG)7::O+B?M?H?BOG&,9P(D*V(W^.7R:1ZJ^C:: \_I<==Q_W%K00ZIQ(UB@ H'_KEBM :6/K1.2/$VCTBKHFM"'>C 2X"93LS##>+ 5 8)MKR]#O@E/I0JSDVH/@^9(&8I^R]QS\3=GKMW?FG=NEOPZSVQ^V3HN]5A\I](KB [LF=TD4(@?LO]W.6427C!J!95S+0 .U\A1=U#(+M?)T>EQ,.1.R:;3Z4,#PZ/O50 3>ESA:&I;O>R?08 KV-P"I*^)G:E5X=_.EJ*F(;YO0.T633Z:P?F,FCP0OC"K!>\ UW;62G)Y*!TG,EPPX?.:=M5MV )VV"VQ*I\Y2F3V*/6^*YM^RR(ZKD^9OEOG1&8 ?K!Q!,B55X7H4+*IZ*]SOL MSVU16#S03F>"$,&*=[Y'G=%;S][H^7 Z$NIR5G9;1]R5"T-DN;'A-/$D@'PS$$*5D?NU3.'+^JC%]>%G_;<>!3L^Z$P1!B;VP2@2LRVHT'C_J!>Z'7\Y44Z"!+@/K=!T" 5QN*;5CLV>QUFVM!WN CQGA!$$H:#/>W^\#S1Z[>ZWEX*HB[#"^K: ZI.U0$V+EQ W69NOPD04GFS-I8DD%DNJQR;X-Y>$,DL&# 6IP*:_Q>/EB*<$6$EGLB E%KXC\K] E[6"A)]#S;.5K82,_MO'L#=*"@/5G-M+#VZ[#.W6GQ8S5O8Z.;Y[FCOZ6 1\\3V-#'-R^104P:(19 D[8>;L3A&)2R2A7,LNV5# 79/&:E"K[,%EC)9^62[FNX,(U'$3$#,<9O2$/7NMWW )K&U#\H&6BQ/;H0Q M63E8:0OXC7+B,J'50>3F>/^+VL/@9WJ78+[V;6J)TO?1F3HJ3UGN QD@^D"ZLXJO]]>*\HI06.Q1R1S+@%2O6ZC)Y1;99#1!\O2BE8R?)Y 92VC*E.]B< =4 "Z^WXX5@P<$5UA\P0^201]YMTD&I\FN9A^0[K+0D>H, 0U!_F_RXN2'=Y:+'O T:N!V]7"B\[[H%>PY+HE.JNW2;C4/FW):7674WX+J0*)'Q\6>Y3++_'$)$%]%!WW@_;NGN 7U4'V]E![QT?ZR_PG,L[P.SSD/K]+A6BI*"VK7CBIDZI/K9&"OQIK@/#?+%H_]"O [1TR_?[UY=/?>V\\< BVCF*77S,JC[O=%F,63LF)-_,!X5UP/&'.RE*N 0I1C"#/9 8)*XFFBNW$JHX YP3E2$[.%C4@P)74J-%_2F.ICH-YK;+;JR&(/>Q30W<(=GQZ&SZ/]YV=IXL= D$J6&I#8(+9T$3YTX%+BRR=& 3\:5A%_<;J"@4K4<*@HMM9'GN%EM@=$V&\MNV1E N?F>SH1O+,0211TI)M!*+BY-'1[C'T%69-7GOG(NXE&*!]7WGH?[*K3MJ/1I/7?O ;TA&>'!B\G_0 C@W49$R]UM+=U*[N7;* _6MD@5S3?=%A60\K'W+Y)QAU]S<+L2] S]H0P,M=JC9W^\=S2*M81G>>^_O'01$.UK%[Q'5"]U V]I?0$-^*81-8JQ_ +RB! &_W&8(5-UQ/R>%\D)&G@4=TD_VTV=N92?ZH#(^F7.45AQR3\6,ZV6K[M3* .>:."S+4,("[(FME!%3.->O;YN%UL,+*&RWQ_%?[UGH*_I:#SCX(@KR@31G]5+P; $(C7AM(UK\X!,6ZXL:\;CR)"8Q7+J8'4JBWFX*-"X+2YS?1%-Y 1_\LO]AVIX $>S6/0.>MLZNU&_#W,]8LO\IYV.C7Q2K7O5:V@U+/< H_ L9=^E_TVJZ3/<-(<.*M @\$51(C=.ITJ#S'S*K<&#!O$CIUTF0V C!] N0>PP,?&#@3)(G*!'DM #TU]I8#8F@&<8W4>J\(18E_?Z345.^")MKHXI_NOV"-O SU5O%Z)!4?%(=T+#6S=7P4:R6!LV*7KK%0-/Y5ET-E]'\E)-W8OA&?JA::P Z;2KI.2O!YY<3L3 V_<7A'$_.K^.&1=K#]<7FCB52KZ85<15 +A\7/*T_6>'-8_/ ]8%U#UH^FOZ+'X$"V)GNM42EHXOC4$BX3+/ZDZI<"WSH[_+EG635SAB*RVD,WF/U 2W#9P69@.PGFN?9XJZ?MG/> .^NYRF+(.906,A^#&ID.>4F6,OI:%4?*,/$7[)_ %?61RGB M=+^$W]WMG!N#2'@&5J\^Y/,%#S*Z2#5 4G),[I72GL>PDT ?>UA29#&((@L_.1!;HS#@&GWN,UVZ)ER"C6IV?GLP/0[;]RP&7CAI69OM*K'4(U +6[DN.K/_.:ORAQZ>#4/NJLB([#7CPP-"8L."-=K"OWTUK-&>GY4+!X-0\0>*SO\ H$Z'V2&NYE@(T" <6&"G]Q^,Q?2TNL7H S,^YY=5C&AQ*8PD_P7[EIIQ0HAP%@[S XG_*!H\*WF*X=M)?7=.W78^[-BFY2^:=>MC"P])41R^".?_T'C34R;P$HY/)E$-1 R\35"9O])#PG34!SK/$JR\B2X>0,#(6C-FBGPEMG;8/+-CA845 8MG.S4]EW9\K0 !IQSP<=*H,_QU4XH(^%D\"N?T&Q>KL)(B> ((=60['EWMY=IG-ER4F4R[L631 1RMM40 3_ZJ[9.*)-W.N_T(%GV6EB +-LA5$EVP1F>R*HC5KPPA:XJI4K<:.UIBS=;$H.>, %%Z][<P4UEASLP1/ VZZF23CFBI@F)-:*P5+Q'S^>75-3@4=[H@_!)BY-3_M.LWZ,EY(&>$5".29(/B'Z>_FLQ-?B-#:EM1' RZ;-5 *,Y*O(EG(]I^(= 7'*\/0T5(I_&D7BX7.GEZ%/7H1M!$])]#=7Z_M$,'*/ %=)$TTD[!OZT*.UPC9Z.R&?CE%-T#L^E6=K04\QD/$U#<%18VRQ^8#H60IY*#UH2 NV=GR2U[^%PR1O:U>+M=[Q4+S/.0 TO-/@'SVPXH=:AVC&3[. 0NDF3=B$Y_J^*L '?DLK$R'RSE==!^TZ+G@">5ODNC6Z*QJ6>S[HDXP095W7^N<0FQ=S<(/;FN$]/; N+&1?@<9*31H)6AC^IOQ]YK2 3;BJW68UN'88Q9R1U.[3G=X85WR;J&JGVX6%K0< ]+]^[)U$D)2>Z4CDJD'BF\X7"B_'L'J90<0S!^9(.5[,CC"9_;U^:TF:B:UXKSSG QAWV@D J>K:GEI7-GZ*/CC2PP'>(;QL,]X)J;..XG<-J4=WBC!MBF"C!OZ&!CC]V TVGI' ,6IJ3?B\+/F0!T0/L/;T5[LEG>DY?PF@$\*ZJZB>+JM"'N;]8P6_5"SS$- YM&T"!$0AOOFP(UMW2#\PFU9F?&/_-'ZWES!M #.'A>=/N:>82-D(J #3A$Z@48G JL(_?%#U*:\(]2T&= A#:B2DXRG WFEUGU6>86MGEE2]5A^0T.=#Y%'6ZS*(,616 #ZV+I>K''4^T#>(HHXN9J_J:F\&4$9?\0@6+HB:D6BBI P:9([8XU89@/*1O@5=BFXVSDP/6&U,'T%6CA'*MG$\RIK75EAL=*)@TT*H=Z62Y8 AR[^/FIYL6T/7!IS@*L=V*T:D;#F'F5MO5/?:'044T#&OV85XLK R"?4U4:([2 ? 1Z'UP$NX&TMY?1/WV4\6N5%__+]CYQH_IJ"CX=7;WBFPUH6@?/+7KV(3'=BG^>V+ :;>=O$\6A=JW=2IPO["4Q.L/O-_F!HI=CW0I!J9W 1M]H8[F>7A3MALWW26>XFA T-6BNLI;KB#M[9? :34#,B=Q,M]_^QHM +E;K-,SNP7XO#MCQ*I^]*#>&DL!,.N#!7:K2XK#&F\U*+?GQYI'CGV:7:,F8[A*] :@.8G9C[/R@5DA3N(NP-8V_7J>:"Q4][U#LM'FR)O,UCIP8INIE/PVX;;ZYPM85> MRJ1P?TT_BITD*0"3MX<4PJ%\EFSSS3RIBA\^V)ITG%XL%7$(",9%H-G!^^R QA* 1N<63 ""L^T6YQN/M'2-]]H8; (@XV>FSFG=FZ1.O$(Y/]F71LS\9A>1&((S@PKO_!WXD9PV'?)8IJ3] 0SGZ?"%$UDGT"C#EF,[B)57?;Q@WI%_2?S'7FO4)8II?[)]&>T Y>J712H1_HG6MP^*GJ+\7]FA+*(-D"]WO>#1'M'DAHQT"):06R;JK $G*%6<)!N\ 0I ; 7%-:&^EY;6G.IYAAKWUC'W+!ETWX61@2]!^5 -!(%&)6KQURKP34<3TBR== E8//)3LA&!W'(^(C;!%"I_2&I!D*K?>LAQP,F8SE90_>K@1LG( \Q^AC:?=+E'STDB%;MWA0ZW@PT+?)_U"O(KRWM'[&.D5H!96#=YIYOH.,Q[BB85H ^23P3Z* E>_K9W-B,^G[+ 3G(9#3B6!U2>+KB&W@N+/OR]UU+PITR37]6>;3V=! 5_3&!>9O[&;".WGA)VV _?@6R^98"@.FG04FG?0""2X"\3O8,CE/?L,)?^3< L#I 9T[>5,JF4;DO268*]!68BC"OX,]1=0S0].&I6* 02N!)7GG-H:271 U-Y9#NB)KO G\C%V9]+2FOK$:[0Q6MKQUXQV<8$Y#;F:SH0[^@+J5DYQI3?@8/\OM2Y/5?4^-S] TBI]SPOW@P82Q*-;FQ8*TO^7SYBVF"_[F@0@;=3V7Z8/4>96@F8G^0QY;SR4R^'& J]PB7HUI9^#8HE+>O-A!)])0XJV-J8^!ECNVHZZ?A-K4I19S_);/#=O\=@"J-X)$O8?L0W6U-N)+9:&FSY=4@PMNP<.3>?840:(7%< \3A^7^:0E^W"I%7Z9.T33JEC;?T4-V6=7H'-_J%X>3N]->-&A_JB5KZ5_\I30: 2BR]>!#G=P-1 GKWPS-!:%4:;F"DDRY#(F''W_>BR A G' 7>-YOPB&=A77CEI6EA%R52/<&<(\(G,]]0MD2J^PH'7%GCN_[?G%R&W\4A4.H58O 9U[OXX@-_)X4NY.)*9AWW.J$IRY$I$[]DF]Z^*&K )L \5]80^7IK0!"=*:S60GV W/Y!5Y?;7<']\@=GQ'_JJSB.0<"-U[51-:T%4^3^+[7E<6X-P-.'9<9>&Z\TMV"N "G0Z>VW#WG$FU)3$6E(U?*/]XYA@[LG H^ @8ED8N[_UR0=BABG#BVT:K#X7KE@6PDDP'D)*Z264:N>PI=SOCF]6L=S1Q Z8$VD AMC)2DD:G:8Y9W("9H>DS6KKTDLE5>9J]I<>V^E&&R9FK/<$#@S6^4V_]3%3(1L[ M$\\@&Q+18R_[:B%L_'J59.Y#\@,LJ:%0\OW<(49I2!5,:BZH3%ZKVH'7#H@!0\/A=:^7 J+5LN8T-;#UT*&^K_4F,HY_\4U"5(\[MW@-Y1^F;,VF>R4:! Z5B%'PL)6) ^N&(AG(7LUMU"P&ED$2L9;M5BEXK9;5V,&3/<<#9)(?YSU 77S/X^'NU1U4VD<1O C>AB=FW1; &O.6H?+ 54]SI./A;1@."_LJ1!7\A5PQ5A> H41[0, (*/_7$BXGR X+.293$.;P9'>E[[RSI)6517,?3%"^58"7CF>*W<0CC7['FR%9_=6PD#F4H6)?H% '@L=CDG?$E:M5AYI=NF-[T:N<$>6NB(,7J>M76/YN]W^6PB"3GOB45 B/0BUUDP7 $G$F-=Y:56TG';PEDDT]6TB_?T>%PEAX2*^#R[PN?F-WC%UDAVQXZ+Y8]6Z:);W6R$J/DR1^YY5G5].\LFFHB"Y(XD^5\E]"[YC;7>_:%!'OG6@ ,C6T35NY:^$!;#9$0,&NB@-1%YAJ+(L4*H\0^M"QB=,,-1W%]9W/H@3?% /IYQ#7 R^6"RSEE+:F*JW\(4T;6MSEK@SC+;SR+D*3.;)BD1I@>\)-EKH' 5G79-+B$A:NEH+VWHL>G=F$'FMDU-@RF4#;GLJ9]WM[.Z2H\17U6][L'OP7#MCI! '0LL"4$,%*- @.8_RR\MTU_!S_H '$*[K=L/JQG@SCT?^"))5BC>7YJ75;C4_E0 'B-+0CH66P'H%OT*G]E1O[K2!/J!9UK;V6%O%T9)B:KZL5J7R,[4%K^AI^**EZ9= (@?9JUN=>^#O!TLV)75%ZDW3NWC=$9#K] ES!+K,=:>5AS2^T-BM&>=:,&7(K<*F-'.0#Y*K4?P+'!HA0$1W]Y\IYQ=A@Q_/ !KZ=MH=11:%=2@R3? A'2XZN@.T";@*;PD'7T!8R4#?1:8Q?HT[BO,.4PN H=H&C P5<-?^G]0_^:,%1#8-N^ ;O"BW&48?VIOW3>'QDJ.>? #KF;!!/I8*]:=JM107"+O\AU)P[[:)L0ZH'8M8S8%>,%;Z\4TA31DZP\38<:84PH JU49_S)4U/._U[@^]PF^V]I)ZC76Z8Z1ZF"7Y \QLCW5->>8L'=M5[%1ZSF)2LN@ OU0;*'\YK@[[C_\,P\K($"^&28WOTYKTU4]C-Y=ABA),\=C-^6RRH154; 8;QS([ ^H=L4(#\6H$]4=\.N@GNE9))I HP,G12J[-SH,A_7;J9B SCY-[ (3R\)$!->:,8 =HL!:BV]4=;%N!5;X/E!E#/4C3M&%:0&?.OHU:=U;-_H#OU$]KX 63[>M6M13XD0\G -J"*(-'I1^&N=-:T6FQ3,")#4\_@E!28G6SS^+)KHXDL;MOXH?@5IQ5O>]_J@,Y5 *--+N[8K,HEOVUPW=-W7$+FP7?3Y^#)B0.U?19 /."#P-2C"UL?@R?K8 #ZG+-1%[5L ?2.=T32H103NPL,)U3)&E4@Q?XIY JCQV2* _1NVDI<5KP7#!N8>P373="[D/> \=YV3YM@,.=8UC^1N75I4[_NWO5H$0 D 56\-^YF=W 0!%1]X)K76-U"["$-J,CZ;Z( P!2 /$2&U6\ 1IUW?WWE2R=I'";)^+25!/WO[0*DVM W]Q97OD3>C:X%MN\?NG)C]\%U::V_1?3)M#%'G1%55^S,/8 L:'L;\$<3^SKUEUJ NZ[)A]R)5FPU^QQ9_,U^FI%1/3=7@/KI6CXV<4WC"3?2'!AX:6*I^<[L@'!N02Y/ .IGG)?""2J$8:/5)2A^<^BTH7Y'ICPIYVU@54H;Q=T;[IHD5_>2Y!W[XQE F\\ECSJZ8PH&U=$5.W4^S+D(4.OYTX!7_ 8+U7AY'D(I\(#(B/8$M%*+/0ZZT#5 ":1*Q]2E<3'YA9$X%82T53+P%@<3%E=-&>=8.F*[. @B, ;5__V72D03IKQ/LB], ,R':MQU#KQXIE_>T:+#,S3OYY$C"6\VEPWS]?@0CC92#RN\;L'KM H"+C@:YZ>4! >[P(L&SHY';-5PTJGJ(!03L4"&UHJD!VF]?:&";2MG>X04BF[YGK/[R&^LSF3%<- $Z OY!GKM>LP3G-JY^ 2OLB:DX!$L]QFHLF(", V(U;M\O4>/A"*D'70=/**]\U/ ,"! \?!([/3ZR.E9.'/G]+A#@]-V9,U&J>LD9Q4WAGT2O:QWT5SL=^,9*#5L68[* .KTTZG']*\).QIR!@,X O&D7Q (/;D5FO6FSY?YBJD(URNF(#)Z2'4U14%&D(KI? S&IX"&WS\7%6:@?\YK2\$PCOAO?L.AH>-92Y7,&9(@TT!5^,PYJ;O T&7^Y0E#E9 ?;GG:Y&ELPX;!2@9.%-(I'!(%%TN85#N8)9GMR>)% G&3V7"\$;.Q_="H>8 Y 3 M5\W0"HM7^1'.M@;=!A'!@*;0=GUQGX.O)Q-/# >1,B9;1AT@[ZJA0BYP0K4'2NM:<8<.,&])CV5X9!OTA7V LCK],4?GU(SM)3NT/M(/TLPXU@1#:P10TA ^P$UB;,;?=E3O>FY]!5>TR9N]EF*>(E,C2R@T"7AX=$O^V4UYNI1\H8?1X(I&9F:M"?7 HAHJY!")!( ,Z?W['-]WC:^=&LUF\>EHA87+H]=8PKE4/53IKW'^)/N$LF])V60 @^'*O*POL_@EL:MQDQKDRH3B6:F\TSSLZ>J<76\MVMG'I"=Z+T4:,D.J2X#E_M(' QQCT5L-9-I[,AN-WY_GCOXA.Y$*]DVRH)TY[LK+!."+F3BKW,95]7@$-Z'*TU2 25(JER X!P4N_%(2%2BT!A=EE4$X+2OP[>X'7WNWV!R#1BE7HT&NMV%AFIS[YE_\H/-E@_C ZOT-'C!,FX4Z\"0(I"&\]R*.'/W$&_?RC4>A+Z/UZ<#[R-71TN1;HG'Q.@.-@^NDE4LB>O_Q U]SS?'7DP&CFML=%JY=MFG3@"N?55G25QP@MRM%W7>V?PNKV8"M0%LWK4JK$#IA( =U4@7A#;!+B)79P804K?J[Q(&"AWP-EY],B<(.U>\.-7#@KPW1%1CC?NX3B'J$!D;6/[D0G7Z0W;1: 3 9/3*N<6DWO$1C_@?2**J.]4?<,4K,+[Y[]<!)Q%6MBU)8L0O6<7D /#_J*:T\N5M=D+F[S]]O:#V4SO>UI5'LZ24@-RTI VO>_S(\Y6AU&V%W@ITQ\ '[ <[D$99GK4Y&8?=)L(&^N89QU,D#4?)-M*F>5U]2O0!ZO#* :R%;;Z"G )TS_:5BD JVJ[X]J.H:$GF:S A/PH:J XP,IKTV\F!ZFA*&5>I1 ^6Z[^Q27$*^?[\1^ -9NM SE,>CPC)+$^:YMI[V[>IU1RD+"SK]6<<3,_#/1?L9SP;>P).*AO+A!2!=2X4] [;,J",!-;CZ7M."VZES4M @VS5KD)JDG#-E9;11WIF5HD; NJ.G_M!M4P)-5Z)^$7 OH&9K6$[BG)"#LV=RH,4!-_$-T>C"Y90Y75=&;6AH$P1W!]3'B>0\;_#,-9K_(A" .977R)O,5V[DO+U>$%C%PN*EW"\-^T#SH1/!X?,H^Z;Y<1!NRG:."]F?2A4U123B A]+J:_95?Y^Q%XXA9TV)/ZJA?JVTA_OV E2)9FCJLW85@;WX^I9E>M#7#DKC(PB H1\T;'%'_C?)U8IP/-/-Z9=T:?HDT%X5H7AD@IV$V+NG]GEIAEK,\AFL"]^^J5[; [-J4;@@EY%#RNH,#24M*F@.P(*6(^C>R-[(C;'F#D+RON*YXX8*2XEVQ?7S0UU. D?DDL W*^HOC9!5(I8&Y$SP8,SQ7CZ>KWASC],2.9L)[G]NFR;77NUMG93LVFVP& 0=5&YG'3LL(; 1TCQ@^%L3[*5% #4UT1$;2W+GI#7B\H:O_%0]:2E"FN*I0(7&F20RHV'VQX9KV=2?F7MS,WJ3QMGK7 3ELQ>BNXC0NUQ'XKK_D +@#4M_W!=D>E;<'J_T$LNBP4UT](V9L R"FF.5&=69$9 .S"B^^\;<.8QGDCF0!/(C,^?2(Q3)N"@R4ECP.@Y%19SM^@]R[VKXR)"QOD"T=[* _X5S@3$>5YHH0CSJH74JEZK@_EI%1W[@NK9-.AW? ^/SDH>S51=F8X470MI5"MF^ @T.1B&F3IIA3G#'EZ-)98_&79'@4 _*$CG%:D:('UH?.>@P)M:RN=/K-_HUQZT\Q X53<2UMFG:B*@14)O8B64N9>K86( U@$5H8JG\F)X43\+QLW=2A.I9RE:3P%&[[?K#V7 G%*-W0.-!$XY?FS,70K9172R FD-^CV^C-B;*VX,\B(('BS; C;7&398EXK.5Q#E;XD<3!L2-5^#4.44DXV^];:H?(+Q"$;)MU0N GH1 WQG4D:_(+"O>2J2REOJ K?P^PX_$+AI$D L;9J95*BS?Y]F$2G>V GI)UQ)V2'@W+PLVL!*+[8I?NIG>TH^V>YQ?\F.>&.%8^1 >!D[[H3@*.UEVT>6P!+7"8BZV;=2(Z7#7\]S30CU1\NXD=! 0CE/@X*&3ZQ'R71_J)E(/7&[WG.=-Z"^:&)V$9\EP[_<22;KE47L,3! 5PH95+$)9 1H'CJM_Y7/3LK+@3'#5]=:2WZ@\"J;Y_F%U^3.5&G]AA40WO^D,V3+ ]/C(<'F8&.ULDIJE]E*!5)2:(2.&,AJ0#239MOP%+83I$S!0B!DJL:"K2L9^"Y$_ GY +K5>9#/*R\7_IAG8+JV>2?UPU8'>??F&@7P#A2C&4WX0]1:8"W_-PKD6]JT0!X&7%M[XT[;%PY>.A_7'1Y4Q*%E UV?3?S!L11)WT6K;_@K:[>(@1,ZF)MN9VS[6$W9UG^*0Z1%*K/O(.9Z#=C!FO (/ ?\N1XG=T^VZI(K[*]9*!I1.]%M\0S/CJH]5:(I;/$7XGS6@L,]"]> 2;:!WA,7VK.:,@KH(*=,X1MTL\RUJ^=*((T_72I;3&TLN6F/RJ!2H;(0-'7[3LTW,HM;T,8()P1K)W(;7EY:G%; #,(48; 9[@]_M$9H:H)B>5^<48E%.+SR>Q:>5R0_5P680R(N%&&&/>)F^[O:;FU" LU'W9K>&'K3790_@!4D.;AL%[J)MA(/'5X#C!+(01I:@7BTM0LCK'P#(;6J*FS&+O!+!BUZI. O!:/.M >-35L 3#F-G+RU.UADVR^>D$I&9Q!TKL1(0_?A6(&6UPV%B8FCO]:@W= WM6E $X(:]R&WA0 *ZE*;(\1( C300,XB83@@;G>'EH(M([S=[(?>T1-KIO7GYE5DD1" :@55\(JW8J7[*]FMB!4#)SF+3'FOZ:YW%^EVO,L?7G=K-=W#[WGG5#WFK4(QS"B- C2V]L,+V!3L=9@PH,92550D7.QK82DZ/;ZDB;\>*4G2G?2I=OAU5/"3A[I!M,!-1 NEYZ^5PA5RM>,;\:// $U_((I^_40?O05*1:S[\X0ZDT\G7N;4JK,TG*[;CZ '.1 L9F0,I?>+KR'#(6"/BUC.F3B<-U ; =Y/P'ZY3=1\"RB'T/(G $J"IH 1ZEG:9.)2-#8;\M]C_P(33 VZ=1>Q6(6!ZQY&=TZI\G-A=?]8'2(J3"N9?45E;BFBF/#>T( 7V*#L&@])#UCNLG 61B.^RVP18+ W 2PE-*L,B'4K_.P0LK,Y_]8A2^ 6\L*<@ X]R6Q:^PM7>Y@[M72 IM']W/IT+IX-+DB-UG\/+Y_C\J?A.'(GIWI=-7FE'3=.!2/ANV9!^M*)NY R'Q%[]M_PXJ (T5 3Z8AS1%%Q\+A#[X_+#@A)8X]L9RQ2(+HI<&\_0+U-!V&6\AW1'&N#/H"N.KF *BU1?*>6XA%=J16)!@Y'L"8!8@$+]B,\T/P!B1J#E@J[-+(<-25^,D0&7""JB)MI U2,LBT.0_T3E\=%GDORRN'6#'A70.WBCI):<4XJL3K1VL675UB1/&>9#AG=B+I:^ !/\.H@[, ?C@RQ4*TLTGS0O*2?IAOC5&B]N1.3$ZW4#K RQ'@X)AA%5&FG(,*3O E1;DY[>,*7K')Z8A>-TT0=S@'IZR3:/13-YAS[_J=]8%^[&Q'P[!7I0TE"Y^+S,I *D5=?(0J*<8L8Y0""V%087[_Z\K1_NT5A!YIUF3)M('X[;#LS^''$UA\M'<6*:K$ 5VLJW\>@0IR^*K-4_OXO-1P#1(V!7N]E%6N)Y@'" \QO :S;CTA.=660KFC>+2TY YB>CO>RZ>!A!-9%0MK"V:N[EB,$^83J7K4K64< 3&#-AV;1Y[:\48X/RI/HH=R]$ U*JNM9F21E3I65JZGP0DXNK2=1M!UG1*FHC+NF+(Q_F:!S85IR/VKFE#;=#U@-7F=ALH#(:>7)A-!XV139OF7 M)7:AC0-C1Z8IA*_]_=V'9>B>YH&?7,1MGX?/ A;6PAIB)G1Y^@2">\U#_F#I;FV)"D!\=OA!!U"YNW(0/=N,>"0L_;87\W'HD&?D?F9L(H0'[071I\ TF0 :CRPP7IYI)QU0I#WYMI)01E+A@7G#TK]S2V&[/S5?@ZA*#B.\+A_F#)@&79S)6)@ 0&IY5[6E==\'C'4'-P\65:VW.&%'ZW8V2#5,GZV\<(^:>W![,(AC+]:[)JPBOURL ^S8@/OOF;$-8/3U#_!>8=7P(S=@S1HE(2NG%.Z]LJ A 6(@H>'@2M,V-_V+7PB#09T,O;[+7-M;]T"8T:7L_"I]'1-,MGBG 0@YDAL&-#< W'D=AE/31ITQQ:A.:UUWU^+.X8(_=CI>1#[7 U#]N821YJ)&U%.='U2Q:U^;T!8' F_U97;QEO?&QN5=QZDL#]&H6#/@[HTQ!I6.:Q-MDNF*!>]('MKLPDJ>A09/ZW-7[JII9?#D4[_M*2-P:DD#9WTMAXD89N6_G,6G.ZW<+@O-1783)G2-O$SP@&T?IK)5C+.HVUH8S'X?KBI=1;DF6 %3J1L]6M_9C5L56]8 (3;*A)[+88__V.L1&'A/5T_ N&NGR^->:6N9J)BU$J+3*E>W(&M2SC&T7,&C36,@ -4YS?B80QG(U>=V'2@XB;G01@%1HV2I[QW5;X&2 U7>XEDD$'G0_6I+^?/& N60T2F:.&^G.B[;A.A90Q_@_U4ZZ*N_+8UU%! ,."XQ] =:#SL[>&9IA'%2'^'2=(DCGM0T:Z70D;162.GA>VEZCVR<9*W#0A@R+A%RW?..RP &08RYR&ZF/D/7-%CE%]I\NI7&FSZ;6K#M/Q]JAS8AE,Q!2N,L4*"*!J!E%++QQQ V%RU;5R2O!5."S.RJLA-@L\=-6@ A/&XGDDT27S?'Q4H8X[)^3RB@'@L= ?HRW^5 ?$ZN_929BM7;>:L!GH&KQ9'2^UIZ'$O46PMMC>HL[GU9W#]ZAK_\I$KI'E5Z*6$' 2\(P[L>7C# !F8(Z=NN6BT*V_L1Y'4K,#2^GFW"C"A\,,5UTP$^D?!B. J6-)#^ =&#$_T#HJ!0:%&PDR8D5"7"=D4>S-]_V:-W= @83YK9_C;G?4$ZV)!?'U[7C+&HL SFM_'-/']./>*$CN>8//K@?D0[58>J3R G[C)AS^K+WNK3/.\,\X](GIZ2_@(\)9_$N!.&)0,@\X@84 2AN9W]F?+!]5JJ_.%8^?$E@*%C!L%U4XTTN)44E:[P[3J#L0"2<\W9* 0%)N%6Q.86)@K3?>A^\%I"YA2S,7QWL?Z8W@2YHRD9MPM=:[#.*&9+L0.0+S@GE& TH48 HLIK8-PT6#,?I<_8&QX_;2FOTWP7268Q'%8W$@XE\@,<+BUV)B;'^;Q):/% IX](N@K6(I;"%-=ED%4Z'=8"B_4GBGL0O4-CSHBY]BD.JKPT&JX3_\1NQ("'%;%. $%_Q5#T/+T4\4H<=4;*IQFU ?86F[KUN:'0Z>G(,M]>D02PU^C3LR6!VB&FJS.2I XE_RR8YBJ=D/3NMWWFE[,2?;9?X7%:_)>T&.[<87E7TVT]R?>QBKPF&/T+")<>CC KI"RZDC:\56S*Q( 5TK:!^ MQEG,<3@1MV9Z@('(MVYQ+Y73"Y;5-!Y+^\QTQ+>J !R?],LV X^8_R1.=^5PZ5J-=<3/H\&BKK%,S] H;#[YA@5[8CE1U /ON ==5;TV1O*CZ/[BYT@-M>'BQE!P)I3$5N#"!$3VZBHK_^K(6<&_P/"^LD!Z][%/BCQ- MIPZ$+AZM3( :722>3O)C*O"#L1 M9JHJF>RW:@IP\9@3?PU1K">J/T@V:7OQH"4 Y?=[1--SYP)F0XC>:-Q? (E/JCU,!O#T=^";!Q KCC/X@Y#@^L=HZ(.Q\GQ:48"2 #C>: AUGYR<&%BPG5ZN4U+QB_BXE>9/Y3-_"5%*TRB8./"G1.,1^6VB _9_@A)IR8)DGT0V$>N/D!/GKWA&)"ZD3SC C13DIFMB X85Y9.:< S1,]C)-^>QN:(OPG@UXSPT@'YOP(0\KKL)[R537/1AG=6<-QZ'VA[NT[W!Z;@4D= XMB*J:K^-P.M,%&*+HI(S,&O 3QD',S)QNZ8,.ONI_IHGW4Y+\*KEZ=P?7Z.'QM@ <.SPU6DD!&2XZV3VGJ6D"5-SB^.7,O?ZD^O,]9O(-B93BGZ:'6P WS^E8.$/Z;4U *6Z0+L*,+VT1.8&)[$0F'MTO\T?1R$@"UQ)G\S[:]C>+)/Z9%/ %KIAM40!M$FK2 .:MQK*6*^SWKF4"CPB#"#8Q!N!6:O95;O.+8++($V%4#D'45$7V,+=:).DBT<7!+ 2LZ1GH&]--#87BZ63D3^ME5AT4?L[8\L6Z;"E'AW1'HC# 478XFSC/Y*2*"'-X]- ":#1C%!!5URC1UX&&Y%-:] )SD^3 C6^GW(==.4R/&54EM+QT/M](-(Z1 U4@&T6 =AZ]"F[:?"MD6FJ4F164MMO?@GJB;<:9ZP&OA$ZU\+SXN&%26PJ;J! D-]=3)VH5 V3YF-Q!^N+E;#XW_<^%PUW.?. ?UF9GP_/V5V XUE0.>BK?N+'FGHN!WI(Y#@S#R W573&:A9/N_$:$&'^B<1T4 :Q()&[N)"#Y%;4Q,['NGE5K 9FA C/@J9T=,>2L 8) ,)"E2$-3LN@\:,N$CXQTW2\%\Q[&QDMD\RJ!TM:1\_8!4>.=:/PI)'G[[%<.! #XGNK=8- 2FI[=]OS7AE0@:@3.?)S7PWTP/)VWLN9J-9YX&9]XS'X#-+9>GC9HU8 P38*#IUO.O1DF_]9RSLJPPDT&,A2#RAN\M 'ML?!2/V?64@VY!-.K8I-:QL(SBNF 'Z2#PKS6#R%W."0(QD'U3:3B-\8E(O1PHLIUDK[J'9>SL# N#4:$FQ]>&HB *Y SL7=T?+@^O-QKQ< [7/.4W@PSF9E+$4!*J=>."#^$A];/6N"8 7AF.*UT(DT[)*7&5W!:SW *D4.#"!*9,=E-=G[5,TI*039>@BW;!DK&?,ZV]JE_ )%DVTM-?;$^]G]N2)S$\J@>2S?L]=#W7Y# &0[FG?H (0'T!IP!(FS_QZ7[Y#']W U(38.<:X3WY 0A'G.X*^):_2^EH26*=*.@)3U8T_]@6ZP@'( G33F>M(KP]>KD9'1*J1HI!*8B-*,(5LZ7($F%]GAH>S!M%9>RJ]Y>^YUJN3S^&.> :;P*75E<'7U/*HV4C]4DG+R!=#_+\X,063;Q5(@\7'.S408]KK=Y-J]2 ;BT7>%ZI*S';J;A&08=PK.JJ\46F^_@_6]=87-W.F2 ,R*;*EU5A>9GKZCK") %S *6UBF&7%0%QLT:N#RKI[9H1QI@&0B$*RN2>S2!8P:.\] BMHJ-@)^-O<7S'X%KG*;V3RHJ \&O\LI)IIZ6FQ5%J.,CPW3_UV\_CK1>)\5RJ5F Q,B1)UF+T)L$@XTDGV?4%1U?Q!5DKYJ/&WEUKCNG&GVQMNWU-?D2)G 89RKJEU-.M@D?A7,HZ/!XC:*6D33NJ325[XP860H=:?" A&E')HE(DB3014ZXDD8UIRY, V-HSVCXN-^9U'T#)=W_E8 ! E*8_7M-#( V-WJ1&D^7M[:RE4_/'8>+:(=IY;SK( ;T5CDU6;PO9(%%G8O!QS\KDKH5(DY:*NSJIC![-WAW/RUI8OOVX7I.J^#S+R+P.5 :[AI6[#%;M2TJ/5S83[&XNNBZE"!Y/%Y3F1]>LEM^Y%SFA,D/.K3#K47_&?HZIX@=N6WFS!N)A/).T_^A7NBZ*-_Y "8@_,[SC(2H=A.HZR-+G]WR9HBR5:%K(R70R>!\Y0*58A6Y0#'M\D$] \"H80K#JF7,@#'L3.M=0B H4 O: =)/$V? ^T+LR;16'Q L3=FV W-;6"&N_EQ,Y$J:BMPC*#.=ZJX+2A:#LX&?@MDY@U,:K#"0RU"95)XTG#MFA'#-8 85Y\-],2:ZC]P1WW6+E_F)A3-LMOT/*3USG08$,BE,?,N?O"/_A?P=W)8DI'YB4 :*X\T@/UAN^7+CS\S$;*M^6]&1Z)YSPK5[^TKYO$:[)H29SALE'7TRHPPU3=GS8/ =:MO]B2#]-]V>K]?V1HK 9!IKWM#Z4U&+'AQ\BR)*=\8+DR6:)?=A-;ECRU:@%<' F0]RS%Z*:.R':1SES*"EB&_"\ R3'W"?5+Q#)O2^7D?5?+E =%C,PJIKEH5SW=RE ''S921+@1_((5+W>7,XOCRW%7W;HR7-*=\<*U^;TT$>HE"X*]#;5\8*X&Q^HQ%#P -9>>6>UMH0!OV8-!HNGB%A1!C+A412..9JV-N)/BTV430G^1X%5X/NA$/G*TPW*' Z523M=RS%JS$N,F$?K[IH)0+O+?R^(@/1QN4,@@R,':\-1K/ISOL/&/RY=!C243; CN]L135.W?HJV!1R#R.UL)V'P$:53$Q'5 WX&K0FVJ(GB.E;JL4G<'Q7X1U N(* >A\ID9\ 5;F:>J9\>XFNZB?TXHR" UWQ=#C%7OU3!5C6GCA;- 0B&0[R*0?(/'DU ;II?9M/(I#+O_V1= JQ?XKP@+FJA_W'7*= =W GS7F"O\A1.>XRG*,J3)P%V^O4% %3::N:[\S^6S \+]J6A/*3)4I'^W?\'![6SO(@7/=:(>WR;7LT1#!<\ T?:B5MNH DCOND(,BM9,*RUG2 C; F6MC- ,7A*3.J<7EY(M:N>^ +^->)TE"!HC9Z7*2+54@ 65[*^;U[Y$?0E"D;"U0]](C,%('=+9#4Y-[+YD:@U&:I($Z$P/N'6SIT>UV;0@+5 ;P%$X^6X;6HB J!A'W$3@HT3R9W@EAP.%O =OFF>GB%Q++[;G&"H?#/,[')J]2T-Y".\]NWXYZX$LH^4&>J98GRA3YMO]$5],9[ * ;2&B6SB@!LA"(P%R=G?Q5L)NJ$' \2/_%$VI3F0M4NR+2\(CZ%%5.HB"LBPR397B+Q*O HEJD!HO_PZMZ*96! N ]#&I)Y1_)5X9B R>]ZW%SP^KU=ZW;PCB>?@>V23;."G86G[J*:2U]\*N<=N.64 +4-U&>NQ.:KV(,QC4;CA%F_/P <9Z"_MD1+E^U00B+?M2$'>ZD;@6:A/XN1,K0Z; >+F(X8J_JNE)DD$DO&ZJ?M9I64:&CI'S]H)-A?.UN1^8/3T^'AF*[3%I@,)[(H@CLKMG<@POMY5)NSPG'!CO6$O *+X"$X*R94IO,NU4?\[)$3PJL,RN%]]Z-1(MZ;DJ*3!MZ]ZNA2%Y"! ;J(G&K8!5 M$I>T$M,;'C>(1XCQZ/P^,0*;(H$EO(ZD>MS5\E:2!DAQAA[,;&'!Y<55)Q6G;L1<[->5 EW\=8VYY4+#QE#P !1TJ"4(1P@*KD)YTK(O^\IQ3" 27,1FI(,$Z;_'G*91R?H4MBPN-V,RJL[IH< N7 !EDPK1M^V>+P>#7A5E1+O"@Y^4.=YO%#FC?%YY1W=N\21C%( 8HH(Q;Q7XP3^:8! 1)V%RGG6!^'7-P5&J1Q]>)@. boinc-app-seti_8.00~svn3701.orig/client/test_workunits/reference_result_unit.sah0000644000175000017500000005614712636064757030221 0ustar locutuslocutus reference.wu 0 0 0 0 0 0 reference_group 14.853 28.55 14.911 28.58 0.775 Fri Mar 3 08:36:01 2000 2451606.85836 1048576 14.853 28.55 14.856 28.56 14.858 28.56 14.861 28.56 14.864 28.56 14.867 28.56 14.869 28.56 14.872 28.56 14.875 28.56 14.878 28.57 14.881 28.57 14.883 28.57 14.886 28.57 14.889 28.57 14.892 28.57 14.895 28.57 14.897 28.57 14.9 28.57 14.903 28.58 14.906 28.58 14.909 28.58 14.911 28.58 1 ao_1420 0.1 1420 18.3538056 -66.7552222 497 168 0 7.4,5.4,-49.1,-1091,0,0,0,0,0,0,0,0,0 -5146.7,66.1,14.3,317.7,0,0,0,0,0,0,0,0,0 0 0 0 0 sah_recorder 2 2500000 0 1.4 0.17 encoded 2048 8 fft hanning 1048576 0 randomize 16 1.04999995 2 22 1 17.8 1 131072 2.1 1.42 3 3.2 64 20 0.5 40960 16 8192 256 8.25 131072 16 256 0.5 1 0.0021 0.0105 0.333 262136 8192 32768 20 262136 50 65528 1 30 0 0 0 0 0 0 0 0 0 0 145

1418920288.09
1418916015.62 9765.62 0
8.6426544189453 0.0078867627307773 14.89751995747 28.57 0 1418924789.4192 1418924863.1228 0 128 0.9168656437853 0 0 0 0.54394906759262 22.395553588867 1 14.909502836654 28.58 0 1418919354.6705 1418919461.2933 0 131072 1.0592016409052 0 0 0 22.535062789917 1 14.909502836654 28.58 0 1418919354.298 1418919461.2929 0 131072 1.0628986797914 0 0 0 22.378698348999 1 14.871418063004 28.56 0 1418917122.4032 1418917201.1763 0 131072 2.3476196927567 0 0 0 22.364013671875 1 14.906409847822 28.58 0 1418923767.2001 1418924030.2402 0 32768 2.7505969313559 0 0 0 22.462213516235 1 14.906409847822 28.58 0 1418923761.5376 1418924030.2345 0 32768 2.8097495535356 0 0 0 22.140769958496 1 14.90148701969 28.574956732299 0 1418918761.3811 1418918419.0097 0 131072 -3.9244067777343 0 0 0 22.104068756104 1 14.864150850996 28.56 0 1418916487.2415 1418916408.0466 0 131072 -3.9336493749498 0 0 0 23.334712982178 1 14.864150850996 28.56 0 1418916487.316 1418916408.0467 0 131072 -3.9373464138361 0 0 0 23.518535614014 1 14.864150850996 28.56 0 1418916487.3905 1418916408.0468 0 131072 -3.9410434527223 0 0 0 22.629072189331 1 14.864150850996 28.56 0 1418916487.465 1418916408.0469 0 131072 -3.9447404916085 0 0 0 22.818777084351 1 14.856922413057 28.56 0 1418918910.9886 1418918946.4799 0 131072 5.2886141267535 0 0 0 23.786548614502 1 14.856922413057 28.56 0 1418918910.9886 1418918946.4924 0 131072 5.2904626461966 0 0 0 17.814907073975 1 14.856922413057 28.56 0 2.6451981543415 1418920288.09 1418920199.1446 0 131072 -13.253884407138 0 0 0 22.051849365234 1 14.879185317697 28.57 0 1418924855.9529 1418924025.883 0 131072 -17.669997356741 0 0 0 10.885553359985 0.0038262107409537 14.859288741085 28.56 0 1418919067.3762 1418918701.9642 0 64 -31.14940113594 0 0 0 4.2041363716125 3.1083626747131 0.57625639438629 14.883054389246 28.57 0 1418915821.905 1418917957.8961 0 16384 39.173824038504 0 0 0 3.5095455646515 1.4116749763489 2.1085500717163 0 9.5103559494019 7,9,13,28,18,7,3,7,1,0,28,33,5,1,8,15,13,12,2,14,13,2,6,57,14,9,0,22,0, 59,2,63,255,200,71,60,24,83,75,2,52,31,0,6,11,27,7,0,1,21,3,62,1,41,52, 2,19,3,17,8,24,41,28,18 3.3304581642151 0.56233322620392 14.884025293173 28.57 0 1418915821.905 1418918023.6189 0 16384 39.173824038504 0 0 0 3.5095455646515 1.3641883134842 2.1419405937195 0 9.5103559494019 7,9,13,28,18,7,3,7,1,0,28,33,5,1,8,15,13,12,2,14,13,2,6,57,14,9,0,22,0, 59,2,63,255,200,71,60,24,83,75,2,52,31,0,6,11,27,7,0,1,21,3,62,1,41,52, 2,19,3,17,8,24,41,28,18 3.202214717865 0.56919771432877 14.884996197099 28.57 0 1418915821.905 1418918089.3417 0 16384 39.173824038504 0 0 0 3.5095455646515 1.411563873291 2.1597337722778 0 9.5103559494019 7,9,13,28,18,7,3,7,1,0,28,33,5,1,8,15,13,12,2,14,13,2,6,57,14,9,0,22,0, 59,2,63,255,200,71,60,24,83,75,2,52,31,0,6,11,27,7,0,1,21,3,62,1,41,52, 2,19,3,17,8,24,41,28,18 3.2735865116119 0.52121621370316 14.896431365397 28.57 0 1418916015.024 1418919872.9451 0 16384 49.451592142226 0 0 0 3.5095455646515 1.3751286268234 2.3200657367706 0 9.5516929626465 13,63,10,5,12,6,7,5,8,8,2,14,6,24,41,10,22,5,4,20,13,0,12,18,27,12,12, 16,18,9,29,1,1,28,7,2,13,1,1,32,47,96,9,4,4,71,193,127,255,87,35,42,12, 28,12,5,22,12,19,27,10,11,26,18 3.6199193000793 0.51788127422333 14.897117952021 28.57 0 1418916015.024 1418919955.9112 0 16384 49.451592142226 0 0 0 3.5095455646515 1.2605501413345 2.2607674598694 0 9.5516929626465 13,63,10,5,12,6,7,5,8,8,2,14,6,24,41,10,22,5,4,20,13,0,12,18,27,12,12, 16,18,9,29,1,1,28,7,2,13,1,1,32,47,96,9,4,4,71,193,127,255,87,35,42,12, 28,12,5,22,12,19,27,10,11,26,18 3.5863273143768 0.52562576532364 14.898088855948 28.57 0 1418916015.024 1418920038.8772 0 16384 49.451592142226 0 0 0 3.5095455646515 1.3370245695114 2.2789671421051 0 9.5516929626465 13,63,10,5,12,6,7,5,8,8,2,14,6,24,41,10,22,5,4,20,13,0,12,18,27,12,12, 16,18,9,29,1,1,28,7,2,13,1,1,32,47,96,9,4,4,71,193,127,255,87,35,42,12, 28,12,5,22,12,19,27,10,11,26,18 23.786548614502 1 14.856922413057 28.56 0 1418918910.9886 1418918946.4924 0 131072 5.2904626461966 0 0 0 17.814907073975 1 14.856922413057 28.56 0 2.6451981543415 1418920288.09 1418920199.1446 0 131072 -13.253884407138 0 0 0 3.6199193000793 0.51788127422333 14.897117952021 28.57 0 1418916015.024 1418919955.9112 0 16384 49.451592142226 0 0 0 3.5095455646515 1.2605501413345 2.2607674598694 0 9.5516929626465 13,63,10,5,12,6,7,5,8,8,2,14,6,24,41,10,22,5,4,20,13,0,12,18,27,12,12, 16,18,9,29,1,1,28,7,2,13,1,1,32,47,96,9,4,4,71,193,127,255,87,35,42,12, 28,12,5,22,12,19,27,10,11,26,18 5.9889302253723 0.033245835453272 14.907301879412 28.58 0 1418921813.9569 1418918839.5513 0 512 -30.690968314047 0 0 0 2.3592972755432 13.391654968262 13.4002161026 0 45 40,10,41,34,32,255,28,55,33,38,21,22,40,30,23,22,36,43,16,21,21,11,17, 23,12,17,38,26,0,23,53,24,25,21,15,29,3,22,46,34,36,31,28,26,51 10.885553359985 0.0038262107409537 14.859288741085 28.56 0 1418919067.3762 1418918701.9642 0 64 -31.14940113594 0 0 0 4.2041363716125 8.00 boinc-app-seti_8.00~svn3701.orig/client/test_workunits/seti_logo0000644000175000017500000002276212640260573025021 0ustar locutuslocutusJFIFC    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222"H !15AQaqs"4#2BRTbr3DS$Cc%1!2AB"Q3Cqa ?" """ """ """ ""-VڋڎJꊩ `qgխqc8NeH z@~\L?f֊:]u:YG PX|k*[k4A` GX˝~8pV ^pss {0j'?*"s" """ """ """ """ """ """I˝E``Kz٪agvA]-|^2uGF߫s?ՐRxFV h$@&FI&?K5ۇanR@;kI~f`SyԖZ,+xz]SRӺ>%*g fFO~:gY_FZcxsHvn/T~lǎ2_,mџ _x{.ɣVQnI4τAE 22ǀj-#N#2p24q>3if咩0I""" """ """ 4h"lQn9I\l{}GݻqYgrۃ@kg;ܻQ#5aY0!RFܝ2se-Φc$!iz>ץ¼i[n:J?r%_(l9 rb knjy4٠ўDk)(sܕ+=Kij t\rzWtҲ(괞Ѣdz-\I7zjx4IeeIXeV#FuVy{ ju,n; nc~u%f28lU6e;.gmطmaD7Ht+iƾ27:۷z5yAӓ\5gx2ppief˫1WLEϧ= 5]r73TZY aq(7L7^eNK/6Mޡ_ n>RFɬh<,r>s֎rځ|iC]U-F m/O24Wn>\⣈SczOK9l[={R R:F{1b;L/ʢ쟑!n91X;u;J|f5qJ#Stqm|ꬩ.3͛P9Ť9NJ+Z]KQkm4-֟;K= +E>]DZAy,iFKZNҫx}<]+68#BٝeJBR3`ڣԅ݈b!&}`*y*`\L+oTƼCX 'Ypd3IU7q\8F򱫕YeBOBMYgoh[ϕnJ6 < gYj~ۊ̒UrX0CSg,kNրc#Q`(!sw'xV{?Za2c$vcrF\ Cl<9f ϳi+͌.4|U%O\QG:s䪾9>NklՓ:6chϝV՗yMWv7dY暒G|ilf~}5A/?UTڲ:th[>I9E _G2IYn88Y,IMTGL[IzǥP miOVμ斸AH ԍH'#c{r h̟2a*#uuum=[t.k-$e). %f"@}1\v.͹l/G豠9 JK´kusFʧ UݹVEx\,ƖE&ֻk^:Zy7I },U](ч>u5[Ckv톲8 bEJ Xɐab*kƭ}{~es} pkֆxzJb/5uHk|*\ ŧS$)۳<2YDu gHD %+8ʊ2Bw ,][QgRh$~[eQ9V0$$#~Yhdll9+97pg ;*_N2Ow!bX<Җl,S0?qb~5FGQyʵȋgwS^+muȧ"D Zsk DD r_gGY!߽Vq/T~_.>R>[R>[r~! y*`\]wËJo+%WxpR}W>{{B_L FUsNVdگ#v%:Xp)ܝ\7r˕[b'F\,]?5]+*[GG-K\d ZMIP\߇ybq%1;4{Uc `GIPU9$dJ~yW+Rw޸e;ZY/7E-ȵ޳0W!O.V;€SKNX"%;9\qSr, py-?Ϊ@!<ʆ8:-W \=@`aQ+Y0|hC.TM3^ٳׄXoBthTQg6[Ա5A'B~JqZA-*d96h??FwmTZnTԮњv~qf2~J7E4yђ2sOWNihf݊=^xD?)N#krd[q^V+M!SgͲqTqiϠu;l>u]VuT4LgƍxqוPX15HQ([AD>dN̔_ֲ]}1fY9vdh~h6N} ;}ڡziAL vO@:.?mebɍk9q J"s}4i';ޢ y*DOX΋i!^W2ڌv-͎S{Эm^ yoU0 5|lum"9FԵ|1-NtWkvR%If|G8$W|de!6⸟8<{ژZchu0jx{zG>t⤮&NAD@^!߽F,շI!l|[7u8;$JgS=xgϡs;YVb]v;_IrVǠǂ t|po/z,OedT•2;GHKnF% Ոy*Ao :-?*+=WvJr7/|.i^G?tfJ uS;›x5rk=!PCN{B月 5:E8# l4<ΐgٴ Bџ{rxU%O\QGݚ'"wmfw.˧%w/ܫJKNƑ'U)Wm)ZV\5]ޮX9C;qE Uo4GKKDlث\/].Zkg)sm7GIF-ʤ֊x],26.#PE?u45tLmNRI> -"z:QM)AYJ;I&wiz}tu\RtqYlJI'#_iY%\eH'4B|2wyy^n^.Dгšy{BM\DVr ԝw5jjN3VKk;gKEr-gvwL0tSKNi;*dIb NNW_ܩ#;DTs4 M g| QwG -{IkFD̻lY8!ףSv8 @{+5 /6 _pXeKCc'B:K}cԤ1wBol2Hc9>ƵfQ΢7Ӹi>zjqaGp51ͤѐb9^е{ю53=EF], wegV=k5-d5cQ教J>Q UulӁ C52OzT(ྡྷťQJ'_j/.Ģ[.z(gt33a㠎qԶ;-x%m<^>:cְ#|Os$k =kڊY]$xǴkVd&^1_V0Yt;e{կ+,='iX ̔ıbk;j@k*!v8S0KctnŲepw>}n{c$a6+Ҋ=*d4jMvg1TFYxCig˯%ZXjK0.4i 󊨻G-EV ?πЏHzP۟i8IWO@_}$l=#.FǘHې۪I1snauv-O'DTr/xcoޫ8?/ ͆9/곈zСvgYDRxzx<[ 7@WC5=P$_P#y]?*+=Sk2gohVr4#v%yӷ(WÄ9Nn 'rN2O?;yj^h(: M(9o`7+ϒ;Y_g֍s`36V\5]ޫJ˃KC=qتՌUHjvOYn+0Z/Fk@Jsp.pix! UkvY(pS͗A6M44O|庾;O+޽/;gxWU])W=gHWl,܆g!*[ՋDmB"sp( ӈg -Nz98vZZnƻ-\I7z0^o\Yݝ:Z-k;gJaB\'rw+IܝTD;"K?zw*r NNY""V,)_c.u6aUFv)Œ5㌒(hTdk$ q̰mܬ/G)/[J\ġnzUT> v6Vk,eDV#qɎwKdR'ÓyjɌK'iөэd򱎱:ǡxa.v= jh1>뽇Ծ0W;=A5-#{hw7aخ0:0e~>hKI>`v %> M^7>OOusm.fo>z717Xse]9%5K7 xluG<, pRCd5m#&t܀'ڥ,M[N\l{#a-^[@tO;D7/[;l5̫|&ט |9ݴ\8A7+l"2:8\ VD]*;m䐲]%in Èq_nLGbC1';Ió޿7/a3 [.zb<:Y(ͣu4/,xs Sbj<.9gTI9S9/곈zЬcoޫ8?/ Wf\")HXn =HXn q-j{+! ar[UwW/({]w-IMN" $e2b*k=H|u_.96zG-^~ۊ̖UsNVdM_ 9.e.l!sw'x]8?O QZiIZ1eGll L`׿%JؤO1Ê5󻜭k%J\*~f~!h>J_d+O ͕yMWv7Ҳ)0\e*{}Uw4.CKK,g|uHF=j)/.c=_萡sSӲh ò9u,MmEolϱ;y͌c" @ב~yyUtM|>{y.s$r(Zg-;,"QQ>ϱ;TN_"şbw?҃\EҰN"1܉f~TR1;^ԓ5d3yg^(]YC58sL3ԫhH&-undͅe==蚼[u!Nc~e. PmXDD0""%GK'mh@Sk,R< ETXJf.F6~!(r9ek69\*%>0NM5.izMK;'JÛ^zWgTCv:T('xynQcHܽ3cR­L|*-|`zz|)q.N':id~Gg%̓oГn++6 AC_ >+cp)JXn\h_[NFjQMQI)!md-#VkƸ7KLմ#,8VZLqkuXܲbÑ~nw6q-4ҧ:Į\%Ü2?ViْU'kc ܾzs YO,s99 v-LA ڠ,Q qdo!W*-%pZ.54q2.-DWDX)7Rx}g22h9Ьh2 GKDqL6Em?HT~TYH\K*)$OihPYDZI[edL׹DNy^=H/K=0ܺ*%sfuA}FtdkAVQEQE<,p#sA-fGjƓ)I/`AkgD"֬tA*=U{-E.h?QG-b$"*9D@DDD@DDD@DDOWQH:y14O4iX5%6,ڊSo 5mpQX(>ys#"Ps^5NIM#R0AN5c;E[>jqE^ӵw} $I$N҈]D@DDD@DDD@DDD@boinc-app-seti_8.00~svn3701.orig/client/s_util.h0000644000175000017500000001205312632156532021446 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // $Id: s_util.h,v 1.12.2.10 2006/09/07 00:26:51 korpela Exp $ #ifndef _UTIL_H #define _UTIL_H #include #include #include #include "track_mem.h" typedef float sah_complex[2]; // The following is a complete list of #defines used in the code: // TEXT_UI // textual UI using printf, scanf // NOTE: the above are not mutually exclusive // _WIN32 // windows environment. does not imply GUI // _WIN_NT_98 // Win NT or 98 environment // TEST_VERSION // include extra command-line options // HAVE_* // (POSIX only) presence or absence of functions, .h files // as generated by configure script // client file names #define OUTFILE_FILENAME "result.sah" #define STATE_FILENAME "state.sah" #define WU_FILENAME "work_unit.sah" #define CFFT_FILENAME "cfft.sah" #define INF 0x7fffffff #define ROUND(a) ((a) - (long)(a) > .5 ? (long)(a) + 1 : (long)(a)) #define TASK_SETI 2 class seti_error { public: typedef enum { success=0, cant_create_file, read_failed, write_failed, malloc_failed, fopen_failed, bad_header, bad_decode, bad_bin_read, result_overflow, unhandled_signal, atexit_failure, unsupported_function, floating_point_fail, } errors; static const char * const message[]; seti_error(int e, const char *s=0) : value(-e), data(s) {}; seti_error(int e, const char *f, int l, const char *s=0) : value(-e), file(f), line(l), data(s) {}; seti_error(const seti_error &e) : value(e.value), file(e.file), line(e.line), data(e.data) {}; operator int() const { return -value; }; void print() const; private: int value; std::string file; int line; std::string data; }; // error codes #define SUCCESS 0 #define CANT_CREATE_FILE (-seti_error::cant_create_file) #define READ_FAILED (-seti_error::read_failed) #define WRITE_FAILED (-seti_error::write_failed) #define MALLOC_FAILED (-seti_error::malloc_failed) #define FOPEN_FAILED (-seti_error::fopen_failed) #define BAD_HEADER (-seti_error::bad_header) #define BAD_DECODE (-seti_error::bad_decode) #define BAD_BIN_READ (-seti_error::bad_bin_read) #define RESULT_OVERFLOW (-seti_error::result_overflow) #define UNHANDLED_SIGNAL (-seti_error::unhandled_signal) #define UNSUPPORTED_FUNCTION (-seti_error::unsupported_function) #define FP_ERROR (-seti_error::floating_point_fail) #define ATEXIT_FAILURE (-seti_error::atexit_failure) #ifdef HAVE_MALLOC_H #include #endif #ifdef HAVE_MEMORY_H #include #endif #ifdef HAVE_ALLOCA_H #include #endif // The MS & intel compilers don't allow alloca in try/catch blocks #ifndef FORCE_FRAME_POINTER #if ( defined(HAVE_ALLOCA) || defined(HAVE_ALLOCA_H) || defined(_WIN32) ) && !( defined(__INTEL_COMPILER) || defined (_MSC_VER) ) #define FORCE_FRAME_POINTER alloca(16) #else #define FORCE_FRAME_POINTER (0) #endif #endif // macro so we can get file and line info. #define SETIERROR( err, errmsg ) do { \ FORCE_FRAME_POINTER; \ throw seti_error( err, __FILE__, __LINE__, errmsg ); \ } while (0) #define CHECKPOINT_SKIPPED (0) //#include "seti_header.h" extern void strip_cr(char*p ); extern void encode(unsigned char* bin, int nbytes, FILE* f); extern int decode(unsigned char* bin, int nbytes, FILE* f); extern int read_bin_data(unsigned char* bin, int nbytes, FILE* f); extern void bits_to_floats(unsigned char* raw, sah_complex *data, int nsamples, int bits_per_sample=2); extern int float_to_uchar( float float_element[], unsigned char char_element[], long num_elements, float scale_factor ); extern char* error_string(int); #endif boinc-app-seti_8.00~svn3701.orig/client/gaussfit.h0000644000175000017500000000405610671336410021774 0ustar locutuslocutus// Copyright 2003 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // Title : gaussfit.h // $Id: gaussfit.h,v 1.3.2.2 2006/06/22 23:53:57 korpela Exp $ extern int GaussFit( float * fp_PoT, int ul_FftLength, int ul_PoT ); extern float f_GetPeak( float fp_PoT[], int ul_TOffset, int ul_HalfSumLength, float f_MeanPower, float f_PeakScaleFactor, float f_weight[] ); int ChooseGaussEvent( int ifft, float PeakPower, float TrueMean, float ChiSq, float null_ChiSq, int bin, float sigma, float PoTMaxPower, float fp_PoT[] ); float f_GetPeakScaleFactor(float f_sigma); extern void gauss_display_init(); extern bool dump_pot; boinc-app-seti_8.00~svn3701.orig/client/sincos.h0000644000175000017500000000612010671336410021437 0ustar locutuslocutus// Copyright 2005 Regents of the University of California // SETI_BOINC is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2, or (at your option) any later // version. // SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // You should have received a copy of the GNU General Public License along // with SETI_BOINC; see the file COPYING. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // In addition, as a special exception, the Regents of the University of // California give permission to link the code of this program with libraries // that provide specific optimized fast Fourier transform (FFT) functions and // distribute a linked executable. You must obey the GNU General Public // License in all respects for all of the code used other than the FFT library // itself. Any modification required to support these libraries must be // distributed in source code form. If you modify this file, you may extend // this exception to your version of the file, but you are not obligated to // do so. If you do not wish to do so, delete this exception statement from // your version. // seti.C // $Id: sincos.h,v 1.2.2.2 2005/06/26 19:55:47 korpela Exp $ // /* Implement the sincos[f] function on machines that don't have it */ #ifndef _SINCOS_H_ #define _SINCOS_H_ #include #ifdef __cplusplus extern "C" { #endif /* These are outside of the #ifndefs because on some machines sinf and cosf */ /* are in libstdc++, but are not defined in the system header . */ void sincos(double angle, double *s, double *c); void sincosf(float angle, float *s, float *c); float sinf(float angle); float cosf(float angle); float atanf(float angle); #ifndef HAVE_SINCOSF inline void sincosf(float angle, float *s, float *c) { /* do we have sincos? If so use it since it's likely to */ /* be faster than separate computation */ #ifdef HAVE_SINCOS float sd,cd; sincos(angle,&sd,&cd); *s=(float)sd; *c=(float)cd; /* if we don't have sincos, how about sinf and cosf? */ #elif defined(HAVE_SINF) && defined(HAVE_COSF) *s=sinf(angle); *c=cosf(angle); /* as a last resort, compute the old fashioned way */ #else *s=(float)sin(angle); *c=(float)cos(angle); #endif } #endif #ifndef HAVE_SINCOS inline void sincos(double angle, double *s, double *c) { /* this is the obvious implementation. Is there a */ /* better trickier way? */ *s=sin(angle); *c=cos(angle); } #endif #ifndef HAVE_SINF inline float sinf(float angle) { return (float)sin(angle); } #endif #ifndef HAVE_COSF inline float cosf(float angle) { return (float)cos(angle); } #endif #ifndef HAVE_ATANF inline float atanf(float angle) { return (float)atan(angle); } #endif #ifdef __cplusplus } #endif #endif