TRIPLET_INFO::TRIPLET_INFO(const TRIPLET_INFO &ti) : track_mem<TRIPLET_INFO>("TRIPLET_INFO"), t(ti.t), score(ti.score), bperiod(ti.bperiod), freq_bin(ti.freq_bin), tpotind0_0(ti.tpotind0_0), tpotind0_1(ti.tpotind0_1), tpotind1_0(ti.tpotind1_0), tpotind1_1(ti.tpotind1_1), tpotind2_0(ti.tpotind2_0), tpotind2_1(ti.tpotind2_1), time_bin(ti.time_bin), scale(ti.scale) { // 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 }
PULSE_INFO::PULSE_INFO() : track_mem<PULSE_INFO>("PULSE_INFO"), p(), score(0), freq_bin(0), time_bin(0) { // 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 }
int result_spike(SPIKE_INFO &si) { int retval=0; if (signal_count >= swi.analysis_cfg.max_signals) { SETIERROR(RESULT_OVERFLOW,"in result_spike"); } 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++; } return 0; }
int result_group_write_header() { if (wrote_header) return 0; wrote_header = 1; int retval = outfile.printf( "<ogh ncfft=%d cr=%e fl=%d>\n", analysis_state.icfft, ChirpFftPairs[analysis_state.icfft].ChirpRate, ChirpFftPairs[analysis_state.icfft].FftLen ); if (retval < 0) SETIERROR(WRITE_FAILED,"in result_group_write_header()"); return 0; }
TRIPLET_INFO::TRIPLET_INFO() : track_mem<TRIPLET_INFO>("TRIPLET_INFO"), t(), score(0), bperiod(0), freq_bin(0), tpotind0_0(0), tpotind0_1(0), tpotind1_0(0), tpotind1_1(0), tpotind2_0(0), tpotind2_1(0), time_bin(0), scale(0) { // 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 }
PULSE_INFO::PULSE_INFO(const PULSE_INFO &pi) : track_mem<PULSE_INFO>("PULSE_INFO"), p(pi.p), score(pi.score), freq_bin(pi.freq_bin), time_bin(pi.time_bin) { // 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 }
// this gets called at the end of each chirp/fft pair // Rewrite the state file, // and write an end-of-group record to log file // if anything was written for this group. int result_group_end() { int retval=0; if (wrote_header) { retval = outfile.printf( "<ogt ncfft=%d cr=%e fl=%d>\n", analysis_state.icfft, ChirpFftPairs[analysis_state.icfft].ChirpRate, ChirpFftPairs[analysis_state.icfft].FftLen); if (retval < 0) SETIERROR(WRITE_FAILED,"in result_group_end"); } return 0; }
// Do SETI-specific initialization for a work unit. // - prepare outfile for appending // - reset scores int seti_init_state() { 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()"); return 0; }
int result_gaussian(GAUSS_INFO &gi) { int retval=0; if (signal_count > swi.analysis_cfg.max_signals) { SETIERROR(RESULT_OVERFLOW,"in result_gaussian"); } 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++; } return 0; }
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) { PULSE_INFO pi; pulse pulse; int retval=0, i, len_prof=static_cast<int>(floor(period)); float step,norm,index,MinPower=PulsePower*MeanPower*scale; // debug possible heap corruption -- jeffc #ifdef _WIN32 BOINCASSERT(_CrtCheckMemory()); #endif // 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<float>(period*static_cast<double>(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<double>(time_bin)+0.5) *static_cast<double>(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;i++) { if (folded_pot[i]<MinPower) MinPower=folded_pot[i]; } norm=255.0f/((PulsePower*MeanPower*scale-MinPower)); // Populate the min and max PoT arrays. These are only used // for graphics. #ifdef BOINC_APP_GRAPHICS if (!nographics()) { step=static_cast<float>(len_prof)/swi.analysis_cfg.pulse_pot_length; index=0; for (i=0;i<swi.analysis_cfg.pulse_pot_length;i++) { pi.pot_min[i]=255; pi.pot_max[i]=0; int j; for (j=0; j<step; j++) { unsigned int pot = static_cast<unsigned int>((folded_pot[static_cast<int>(floor(index))+j]-MinPower)*norm); if (pot<pi.pot_min[i]) { pi.pot_min[i]=pot; } if (pi.pot_min[i] >= 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;i<len_prof;i++) { pi.p.pot[i] = (unsigned char)((folded_pot[i]-MinPower)*norm); } } else { pi.p.pot.clear(); } // Update gdata pulse info regardless of whether it is the // best thus far. If a pulse has made it this far, display it. #ifdef BOINC_APP_GRAPHICS if (!nographics()) sah_graphics->pi.copy(&pi); #endif // best thus far ? if (pi.score>best_pulse->score) { *best_pulse=pi; } if (write_pulse) { if (signal_count > swi.analysis_cfg.max_signals) { SETIERROR(RESULT_OVERFLOW,"in ReportPulseEvent"); } //for (i=0;i<len_prof;i++) { // sprintf(&pi.p.pot[i], "%02x",(int)((folded_pot[i]-MinPower)*norm)); // } 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++; } } // debug possible heap corruption -- jeffc #ifdef _WIN32 BOINCASSERT(_CrtCheckMemory()); #endif return(retval); }
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 ) { 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 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<float>(period*static_cast<double>(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<double>(mid_time_bin)+start_time_bin+0.5) *static_cast<double>(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<double>(pot_len)/swi.analysis_cfg.triplet_pot_length; ti.scale=static_cast<float>(1.0/step); index=0; for (i=0;i<pot_len;i++) { if (PoT[i]>max_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<int>(((mtb-period)*swi.analysis_cfg.triplet_pot_length)/pot_len); ti.tpotind1_0 = ti.tpotind1_1 = static_cast<int>(((mtb)*swi.analysis_cfg.triplet_pot_length)/pot_len); ti.tpotind2_0 = ti.tpotind2_1 = static_cast<int>(((mtb+period)*swi.analysis_cfg.triplet_pot_length)/pot_len); for (j=0; j<pot_len; j++) { i = (j*swi.analysis_cfg.triplet_pot_length)/pot_len; if ((PoT[j]*norm)<ti.pot_min[i]) { ti.pot_min[i]=static_cast<unsigned int>(floor(PoT[j]*norm)); } if ((PoT[j]*norm)>ti.pot_max[i]) { ti.pot_max[i]=static_cast<unsigned int>(floor(PoT[j]*norm)); } } } else { memset(inv, -1, sizeof(inv)); for (i=0;i<swi.analysis_cfg.triplet_pot_length;i++) { j = (i*pot_len)/swi.analysis_cfg.triplet_pot_length; if (inv[j] < 0) inv[j] = i; if ((PoT[j]*norm)<ti.pot_min[i]) { ti.pot_min[i]=static_cast<unsigned int>(floor(PoT[j]*norm)); } if ((PoT[j]*norm)>ti.pot_max[i]) { ti.pot_max[i]=static_cast<unsigned int>(floor(PoT[j]*norm)); } } ti.tpotind0_0 = inv[static_cast<int>(mtb-period)]; ti.tpotind0_1 = inv[static_cast<int>(mtb-period+1)]; ti.tpotind1_0 = (inv[static_cast<int>(mtb)]+inv[static_cast<int>(mtb+1)])/2; ti.tpotind1_1 = (inv[static_cast<int>(mtb+1)]+inv[static_cast<int>(mtb+2)])/2; ti.tpotind2_0 = inv[static_cast<int>(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<int>(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) { *best_triplet=ti; } if (write_triplet) { if (signal_count > swi.analysis_cfg.max_signals) { SETIERROR(RESULT_OVERFLOW,"in ReportTripletEvent"); } 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++; } } // debug possible heap corruption -- jeffc #ifdef _WIN32 BOINCASSERT(_CrtCheckMemory()); #endif return(retval); }
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; use_transposed_pot= (!notranspose_flag) && ((app_init_data.host_info.m_nbytes != 0) && (app_init_data.host_info.m_nbytes >= (double)(96*1024*1024))); 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; if ((wisdom=boinc_fopen("wisdom.sah","r"))) { char *wiz=(char *)calloc_a(1024,64,MEM_ALIGN); int n=0; while (wiz && n<64*1024 && !feof(wisdom)) { n+=fread(wiz+n,1,80,wisdom); } fftwf_import_wisdom_from_string(wiz); free_a(wiz); fclose(wisdom); } #endif #ifdef BOINC_APP_GRAPHICS if (sah_graphics) strcpy(sah_graphics->status, "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; if (ippsFFTInitAlloc_C_32fc(&FftSpec[FftNum], order, 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(FftLen * sizeof(sah_complex),MEM_ALIGN); sah_complex *scratch=(sah_complex *)malloc_a(FftLen*sizeof(sah_complex),MEM_ALIGN); if ((WorkData == NULL) || (scratch==NULL)) { SETIERROR(MALLOC_FAILED, "WorkData == NULL || scratch == NULL"); } // TODO: Deallocate these at the end of the function analysis_plans[FftNum] = fftwf_plan_dft_1d(FftLen, scratch, WorkData, FFTW_BACKWARD, FFTW_MEASURE|FFTW_PRESERVE_INPUT); #endif FftNum++; #ifdef USE_FFTWF free_a(scratch); free_a(WorkData); #endif /* USE_FFTWF */ } FftLen*=2; bitfield>>=1; }
int FindSpikes2( int ul_NumDataPoints, int fft_num, SETI_WU_INFO& swi, float total, float temp, // maximum int pos) { // 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" if(swi.analysis_cfg.spikes_per_spectrum > 0) { int i = 0, j = 0, k = 0, m = 0, retval; float fMeanPower = total / ul_NumDataPoints; float fPeakPower = (temp / fMeanPower); //+0.005f; float fScore = fPeakPower / SPIKE_SCORE_HIGH; fScore = (fScore > 0.0f) ? (float)log10( fScore ) : 0.0f; // If we'll need this result, compute pertinent data and place in tmp_spike if ( (fScore > best_spike->score) || (best_spike->s.fft_len == 0) || (fPeakPower > swi.analysis_cfg.spike_thresh) ) { k = pos; m = k; // save the "lowest" highest. tmp_spike->s.peak_power = fPeakPower; tmp_spike->s.mean_power = 1.0; tmp_spike->score = fScore; tmp_spike->bin = k; tmp_spike->fft_ind = fft_num; tmp_spike->s.chirp_rate = ChirpFftPairs[analysis_state.icfft].ChirpRate; tmp_spike->s.fft_len = ChirpFftPairs[analysis_state.icfft].FftLen; tmp_spike->s.freq = cnvt_bin_hz( tmp_spike->bin, tmp_spike->s.fft_len ); double t_offset = ( (double)tmp_spike->fft_ind + 0.5 ) * (double)tmp_spike->s.fft_len / swi.subband_sample_rate; tmp_spike->s.detection_freq = calc_detection_freq( tmp_spike->s.freq, tmp_spike->s.chirp_rate, t_offset ); tmp_spike->s.time = swi.time_recorded + t_offset / 86400.0; time_to_ra_dec( tmp_spike->s.time, &tmp_spike->s.ra, &tmp_spike->s.decl ); } // This is the best spike, so copy to best_spike if ( (fScore > best_spike->score) || (best_spike->s.fft_len == 0) ) { *best_spike = *tmp_spike; #ifdef BOINC_APP_GRAPHICS if( !nographics() ) { sah_graphics->si.copy( tmp_spike, true ); } #endif } // Report a signal if it exceeds threshold if( fPeakPower > swi.analysis_cfg.spike_thresh ) { retval = result_spike( *tmp_spike ); if( retval ) { SETIERROR(retval,"from result_spike()"); } } } return 0; }
int checkpoint(BOOLEAN force_checkpoint) { int retval=0, i, l=xml_indent_level; xml_indent_level=0; 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()) return CHECKPOINT_SKIPPED; } fflush(stderr); /* should be in this place! * in the Android or non-glibc malloc it causes huge system mmap2 overhead */ MFILE state_file; // debug possible heap corruption -- jeffc #ifdef _WIN32 BOINCASSERT(_CrtCheckMemory()); #endif if (state_file.open(STATE_FILENAME, "wb")) SETIERROR(CANT_CREATE_FILE,"in checkpoint()"); retval = state_file.printf( "<ncfft>%d</ncfft>\n" "<cr>%e</cr>\n" "<fl>%d</fl>\n" "<prog>%.8f</prog>\n" "<potfreq>%d</potfreq>\n" "<potactivity>%d</potactivity>\n" "<signal_count>%d</signal_count>\n" "<flops>%f</flops>\n" "<spike_count>%d</spike_count>\n" "<pulse_count>%d</pulse_count>\n" "<gaussian_count>%d</gaussian_count>\n" "<triplet_count>%d</triplet_count>\n", analysis_state.icfft, ChirpFftPairs[analysis_state.icfft].ChirpRate, ChirpFftPairs[analysis_state.icfft].FftLen, std::min(progress,0.9999999), analysis_state.PoT_freq_bin, analysis_state.PoT_activity, signal_count, analysis_state.FLOP_counter, spike_count, 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->score) { retval = state_file.printf("<best_spike>\n"); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); // the spike proper str = best_spike->s.print_xml(0,0,1); retval = (int)state_file.write(str.c_str(), str.size(), 1); // ancillary data retval = state_file.printf( "<bs_score>%f</bs_score>\n" "<bs_bin>%d</bs_bin>\n" "<bs_fft_ind>%d</bs_fft_ind>\n", best_spike->score, best_spike->bin, best_spike->fft_ind); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); retval = state_file.printf("</best_spike>\n"); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); } // checkpoint the best gaussian thus far (if any) if(best_gauss->score) { retval = state_file.printf("<best_gaussian>\n"); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); // the gaussian proper str = best_gauss->g.print_xml(0,0,1); retval = (int)state_file.write(str.c_str(), str.size(), 1); // ancillary data retval = state_file.printf( "<bg_score>%f</bg_score>\n" "<bg_display_power_thresh>%f</bg_display_power_thresh>\n" "<bg_bin>%d</bg_bin>\n" "<bg_fft_ind>%d</bg_fft_ind>\n", best_gauss->score, best_gauss->display_power_thresh, best_gauss->bin, best_gauss->fft_ind); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); retval = state_file.printf("</best_gaussian>\n"); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); } // checkpoint the best pulse thus far (if any) // The check for len_prof is a kludge. if(best_pulse->score) { retval = state_file.printf("<best_pulse>\n"); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); // the pulse proper str = best_pulse->p.print_xml(0,0,1); retval = (int)state_file.write(str.c_str(), str.size(), 1); // ancillary data retval = state_file.printf( "<bp_score>%f</bp_score>\n" "<bp_freq_bin>%d</bp_freq_bin>\n" "<bp_time_bin>%d</bp_time_bin>\n", best_pulse->score, best_pulse->freq_bin, best_pulse->time_bin); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); retval = state_file.printf("</best_pulse>\n"); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); } // checkpoint the best triplet thus far (if any) if(best_triplet->score) { retval = state_file.printf("<best_triplet>\n"); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); // the triplet proper str = best_triplet->t.print_xml(0,0,1); retval = (int)state_file.write(str.c_str(), str.size(), 1); // ancillary data retval = state_file.printf( "<bt_score>%f</bt_score>\n" "<bt_bperiod>%f</bt_bperiod>\n" "<bt_tpotind0_0>%d</bt_tpotind0_0>\n" "<bt_tpotind0_1>%d</bt_tpotind0_1>\n" "<bt_tpotind1_0>%d</bt_tpotind1_0>\n" "<bt_tpotind1_1>%d</bt_tpotind1_1>\n" "<bt_tpotind2_0>%d</bt_tpotind2_0>\n" "<bt_tpotind2_1>%d</bt_tpotind2_1>\n" "<bt_freq_bin>%d</bt_freq_bin>\n" "<bt_time_bin>%f</bt_time_bin>\n" "<bt_scale>%f</bt_scale>\n", best_triplet->score, best_triplet->bperiod, best_triplet->tpotind0_0, best_triplet->tpotind0_1, best_triplet->tpotind1_0, best_triplet->tpotind1_1, best_triplet->tpotind2_0, best_triplet->tpotind2_1, best_triplet->freq_bin, best_triplet->time_bin, best_triplet->scale); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); // convert min PoT to chars, encode, and print for (i=0; i<swi.analysis_cfg.triplet_pot_length; i++) { buf[i] = (unsigned char)best_triplet->pot_min[i]; } enc_field=xml_encode_string(buf, swi.analysis_cfg.triplet_pot_length, _x_csv); retval = state_file.printf( "<bt_pot_min length=%d encoding=\"%s\">", enc_field.size(), xml_encoding_names[_x_csv] ); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); state_file.write(enc_field.c_str(), enc_field.size(), 1); retval = state_file.printf("</bt_pot_min>\n"); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); // convert max PoT to chars, encode, and print for (i=0; i<swi.analysis_cfg.triplet_pot_length; i++) { buf[i] = (unsigned char)best_triplet->pot_max[i]; } enc_field=xml_encode_string(buf, swi.analysis_cfg.triplet_pot_length, _x_csv); state_file.printf( "<bt_pot_max length=%d encoding=\"%s\">", enc_field.size(), xml_encoding_names[_x_csv] ); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); state_file.write(enc_field.c_str(), enc_field.size(), 1); retval = state_file.printf("</bt_pot_max>\n"); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); retval = state_file.printf("</best_triplet>\n"); if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); } // 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 return 0; }
int main(int argc, char** argv) { int retval = 0, i; FORCE_FRAME_POINTER; run_stage=PREGRX; g_argc=argc; if (!(g_argv=(char **)calloc(argc+2,sizeof(char *)))) { exit(MALLOC_FAILED); } setbuf(stdout, 0); bool standalone = false; g_argv[0]=argv[0]; for (i=1; i<argc; i++) { g_argv[i]=argv[i]; char *p=argv[i]; while (*p=='-') p++; if (!strncmp(p,"vers",4)) { print_version(); exit(0); } else if (!strncmp(p,"verb",4)) { verbose = true; } else if (!strncmp(p, "st", 2)) { standalone = true; #ifdef BOINC_APP_GRAPHICS nographics_flag = true; #endif } else if (!strncmp(p, "nog", 3)) { #ifdef BOINC_APP_GRAPHICS nographics_flag = true; #endif } else if (!strncmp(p, "not", 3)) { notranspose_flag = true; } else if (!strncmp(p, "def", 3)) { default_functions_flag = true; } else { fprintf(stderr, "bad arg: %s\n", argv[i]); usage(); exit(1); } } 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()"); } #ifdef __APPLE__ 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(); exit(static_cast<int>(e)); } 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<int>(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<float>(PoTInfo.GaussSigma)); f_weight = reinterpret_cast<float *>(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<float>(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<float>(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()
// 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]; int ncfft, fl, PoT_freq_bin, PoT_activity; double cr=0,flops=0; FILE* state_file; // debug possible heap corruption -- jeffc #ifdef _WIN32 BOINCASSERT(_CrtCheckMemory()); #endif ncfft = -1; progress = 0.0; PoT_freq_bin = -1; PoT_activity = POT_INACTIVE; state_file = boinc_fopen(STATE_FILENAME, "rb"); if (!state_file) SETIERROR(FOPEN_FAILED,"in parse_state_file()"); // main parsing loop while (fgets(buf, sizeof(buf), state_file)) { if (parse_int(buf, "<ncfft>", ncfft)) continue; else if (parse_double(buf, "<cr>", cr)) continue; else if (parse_int(buf, "<fl>", fl)) continue; else if (parse_double(buf, "<prog>", progress)) continue; else if (parse_int(buf, "<potfreq>", PoT_freq_bin)) continue; else if (parse_int(buf, "<potactivity>", PoT_activity)) continue; else if (parse_int(buf, "<signal_count>", signal_count)) continue; else if (parse_double(buf, "<flops>", flops)) continue; else if (parse_int(buf, "<spike_count>", spike_count)) continue; else if (parse_int(buf, "<pulse_count>", pulse_count)) continue; else if (parse_int(buf, "<gaussian_count>", gaussian_count)) continue; else if (parse_int(buf, "<triplet_count>", triplet_count)) continue; // best spike else if (xml_match_tag(buf, "<best_spike>")) { while (fgets(buf, sizeof(buf), state_file)) { if (xml_match_tag(buf, "</best_spike>")) break; // spike proper else if (xml_match_tag(buf, "<spike>")) { char *p = buf + strlen(buf); while(fgets(p, sizeof(buf)-(int)strlen(buf), state_file)) { if (xml_match_tag(buf, "</spike>")) break; p += strlen(p); } best_spike->s.parse_xml(buf); } // ancillary data else if (parse_double(buf, "<bs_score>", best_spike->score)) continue; else if (parse_int(buf, "<bs_bin>", best_spike->bin)) continue; else if (parse_int(buf, "<bs_fft_ind>", best_spike->fft_ind)) continue; } // end while in best_spike } // end if in best_spike // best gaussian.. else if (xml_match_tag(buf, "<best_gaussian>")) { while (fgets(buf, sizeof(buf), state_file)) { if (xml_match_tag(buf, "</best_gaussian>")) break; // gaussian proper else if (xml_match_tag(buf, "<gaussian>")) { char *p = buf + strlen(buf); while(fgets(p, sizeof(buf)-(int)strlen(buf), state_file)) { if (xml_match_tag(buf, "</gaussian>")) break; p += strlen(p); } best_gauss->g.parse_xml(buf); } // ancillary data else if (parse_double(buf, "<bg_score>", best_gauss->score)) continue; else if (parse_double(buf, "<bg_display_power_thresh>", best_gauss->display_power_thresh)) continue; else if (parse_int(buf, "<bg_bin>", best_gauss->bin)) continue ; else if (parse_int(buf, "<bg_fft_ind>", best_gauss->fft_ind)) continue; } // end while in best_gaissian } // end if in best_gaussian // best pulse else if (xml_match_tag(buf, "<best_pulse>")) { while (fgets(buf, sizeof(buf), state_file)) { if (xml_match_tag(buf, "</best_pulse>")) break; // pulse proper else if (xml_match_tag(buf, "<pulse>")) { char *p = buf + strlen(buf); while(fgets(p, sizeof(buf)-(int)strlen(buf), state_file)) { if (xml_match_tag(buf, "</pulse>")) break; p += strlen(p); } best_pulse->p.parse_xml(buf); } // ancillary data else if (parse_double(buf, "<bp_score>", best_pulse->score)) continue; else if (parse_int(buf, "<bp_freq_bin>", best_pulse->freq_bin)) continue; else if (parse_int(buf, "<bp_time_bin>", best_pulse->time_bin)) continue; } // end while in best_pulse } // end if in best_pulse // best triplet else if (xml_match_tag(buf, "<best_triplet>")) { while (fgets(buf, sizeof(buf), state_file)) { if (xml_match_tag(buf, "</best_triplet>")) break; // triplet proper else if (xml_match_tag(buf, "<triplet>")) { char *p = buf + strlen(buf); while(fgets(p, sizeof(buf)-(int)strlen(buf), state_file)) { if (xml_match_tag(buf, "</triplet>")) break; p += strlen(p); } best_triplet->t.parse_xml(buf); } // ancillary data else if (parse_double(buf, "<bt_score>", best_triplet->score)) continue; else if (parse_double(buf, "<bt_bperiod>", best_triplet->bperiod)) continue; else if (parse_int(buf, "<bt_tpotind0_0>", best_triplet->tpotind0_0)) continue; else if (parse_int(buf, "<bt_tpotind0_1>", best_triplet->tpotind0_1)) continue; else if (parse_int(buf, "<bt_tpotind1_0>", best_triplet->tpotind1_0)) continue; else if (parse_int(buf, "<bt_tpotind1_1>", best_triplet->tpotind1_1)) continue; else if (parse_int(buf, "<bt_tpotind2_0>", best_triplet->tpotind2_0)) continue; else if (parse_int(buf, "<bt_tpotind2_1>", best_triplet->tpotind2_1)) continue; else if (parse_int(buf, "<bt_freq_bin>", best_triplet->freq_bin)) continue; else if (parse_double(buf, "<bt_time_bin>", best_triplet->time_bin)) continue; else if (parse_double(buf, "<bt_scale>", best_triplet->scale)) continue; else if (xml_match_tag(buf, "<bt_pot_min")) { char *p = buf + strlen(buf); while(fgets(p, sizeof(buf)-(int)strlen(buf), state_file)) { if (xml_match_tag(buf, "</bt_pot_min")) break; p += strlen(p); } std::vector<unsigned char> pot_min( xml_decode_field<unsigned char>(buf,"bt_pot_min") ); int i; for (i=0; i<swi.analysis_cfg.triplet_pot_length; i++) { best_triplet->pot_min[i] = pot_min[i]; } } // end Min PoT else if (xml_match_tag(buf, "<bt_pot_max")) { char *p = buf + strlen(buf); while(fgets(p, sizeof(buf)-(int)strlen(buf), state_file)) { if (xml_match_tag(buf, "</bt_pot_max")) break; p += strlen(p); } std::vector<unsigned char> pot_max( xml_decode_field<unsigned char>(buf,"bt_pot_max") ); int i; for (i=0; i<swi.analysis_cfg.triplet_pot_length; i++) { best_triplet->pot_max[i] = pot_max[i]; } } // end Max PoT } // end while in best_triplet } // end if in best_triplet } // 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 return 0; }
int FindSpikes( float * fp_PowerSpectrum, int ul_NumDataPoints, int fft_num, SETI_WU_INFO& swi ) { //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.0; 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; // for(i = 0; i < ul_NumDataPoints; i++) { // total += fp_PowerSpectrum[i]; // } // 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.0f; // 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. float mval = fp_PowerSpectrum[m]; for (j = 1; j < ul_NumDataPoints; j++) { float val = fp_PowerSpectrum[j]; if (val > temp) { if (val < mval || m == 0) { temp = val; k = j; } } } // temp now = first/next highest power and k = it's bin number m = k; // save the "lowest" highest. float score = si.s.peak_power / SPIKE_SCORE_HIGH; bool sidone = false; // 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) { // 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 = score; si.score = si.score > 0.0f ? (float)log10(si.score) : 0.0f; *best_spike = si; sidone = true; #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(!sidone) { // 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 = score; si.score = si.score > 0.0f ? (float)log10(si.score) : 0.0f; *best_spike = si; } retval = result_spike(si); if (retval) SETIERROR(retval,"from result_spike()"); } } return 0; }
// 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; nsamples = swi.nsamples; samples_per_byte=(8/swi.bits_per_sample); data = (sah_complex *)malloc_a(nsamples*sizeof(sah_complex), MEM_ALIGN); bin_data = (sah_complex *)malloc_a(nsamples*sizeof(sah_complex), MEM_ALIGN); if (!data) SETIERROR(MALLOC_FAILED, "!data"); if (!bin_data) SETIERROR(MALLOC_FAILED, "!bin_data"); switch(swi.data_type) { case DATA_ASCII: for (i=0; i<nsamples; i++) { p = fgets(buf, 256, f); if (!p) { SETIERROR(READ_FAILED,"in seti_parse_data"); } sscanf(buf, "%f%f", &data[i][0], &data[i][1]); } break; case DATA_ENCODED: case DATA_SUN_BINARY: try { int nread; std::string tmpbuf(""); fseek(f,0,SEEK_SET); nbytes = (nsamples/samples_per_byte); tmpbuf.reserve(nbytes*3/2); while ((nread=(int)fread(buf,1,sizeof(buf),f))) { tmpbuf+=std::string(&(buf[0]),nread); } std::vector<unsigned char> datav( xml_decode_field<unsigned char>(tmpbuf,"data") ); memcpy(bin_data,&(datav[0]),datav.size()); if (datav.size() < nbytes) throw BAD_DECODE; } catch (int i) { retval=i; if (data) free_a(data); if (bin_data) free_a(bin_data); SETIERROR(i,"in seti_parse_data()"); } bits_to_floats((unsigned char *)bin_data, data, nsamples); memcpy(bin_data,data,nsamples*sizeof(sah_complex)); state.savedWUData = bin_data; break; /* #if 0 nbytes = (nsamples/4); bin_data = (unsigned char*)malloc_a((nbytes+2)*sizeof(unsigned char), MEM_ALIGN); if (!bin_data) SETIERROR(MALLOC_FAILED, "!bin_data"); retval = read_bin_data(bin_data, nbytes, f); if (retval) { if (data) free_a(data); if (bin_data) free_a(bin_data); SETIERROR(retval,"from read_bin_data()"); } bits_to_floats(bin_data, data, nsamples); state.savedWUData = bin_data; break; #endif */ } 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 return 0; }
int analyze_pot(float *PowerSpectrum, int NumDataPoints, ChirpFftPair_t &cfft, int offset) { // 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, // complement 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 DEBUG_POT fprintf(stderr, "========= FftLength = %d =========\n", FftLength); #endif PoTLen = NumDataPoints / FftLength; // in bins GetPulsePoTLen(PoTLen, &PulsePoTLen, &Overlap); // in bins AdvanceBy = PulsePoTLen - Overlap; // in bins // Max limits how *slow* the slewrate can be, while Min limits how // *fast* the slewrate can be. Max is limited only by the client // memory budget. if(PulsePoTLen > 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; static int doneprintnopulsefind = 0; if(!doneprintnopulsefind) { fprintf(stderr,"SkipPulse is set to TRUE: Not doing Pulsefinds.\n"); doneprintnopulsefind = 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"); } } bool b_gaussStarted = false; // Look for gaussians --------------------------------------------------- if(!SkipGauss && (analysis_state.PoT_activity == POT_DOING_GAUSS || analysis_state.PoT_activity == POT_INACTIVE)) { #ifdef BOINC_APP_GRAPHICS if (!nographics()) 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 (!nographics()) sah_graphics->local_progress = ((float)ThisPoT-1)/(FftLength-1); #endif #ifdef USE_CUDA //#ifndef CUDAACC_EMULATION if(gSetiUseCudaDevice) { //TODO: remove the autocorr_fftlen test when v6 fully deprecated. bool noscore = false; //swi.analysis_cfg.autocorr_fftlen!=0 && gaussian_count!=0; //cudaAcc_Gaussfit(FftLength, best_gauss->score, noscore); //printf("GaussFitStart\r\n"); b_gaussStarted = true; // started earlier //cudaAcc_GaussfitStart(FftLength, best_gauss->score, noscore); if(PoTLen > swi.analysis_cfg.gauss_pot_length) analysis_state.FLOP_counter+=((double)NumDataPoints+swi.analysis_cfg.gauss_pot_length * (FftLength-1)); // GetFixedPoT // There are FftLength - 1 fixed PoTs for a chirp/fft pair, and for each fixed PoT full analysis would do // (1 + (PoTInfo.GaussTOffsetStop - PoTInfo.GaussTOffsetStart)) GetPeak and GetTrueMean operations. // Use (1 - PoTInfo.GaussSigma*0.09) empirically found to represent fraction of PoTs which don't // take either of the two early out paths. double CorrWt = (1.0 - PoTInfo.GaussSigma*0.09) * (FftLength - 1) * (1 + (PoTInfo.GaussTOffsetStop - PoTInfo.GaussTOffsetStart)); analysis_state.FLOP_counter+=6.0*floor(PoTInfo.GaussSigma+0.5) * CorrWt; // GetPeak analysis_state.FLOP_counter+=(double)(floor(PoTInfo.GaussSigma+0.5) * 3.911+5) * CorrWt; // GetTrueMean // Estimate one in twenty fit positions look good enough to be checked further. analysis_state.FLOP_counter+= 0.05 * (20.0*swi.analysis_cfg.gauss_pot_length+5.0) * CorrWt; // GetChiSq / 20 progress += ProgressUnitSize * GaussianProgressUnits(); progress=std::min(progress,1.0); // prevent display of > 100% fraction_done(progress,remaining); } //#endif CUDAACC_EMULATION else { #endif //USE_CUDA // 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 */ #ifdef USE_CUDA } #endif //USE_CUDA 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 (!nographics()) { 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(!nographics()) { sah_graphics->local_progress = (((ThisPoT-1) * NumPulsePoTs) + PulsePoTNum) * ProgressPerPulsePoT; } #endif #ifdef USE_CUDA if(gSetiUseCudaDevice) { /* if(!SkipTriplet || !SkipPulse) // do beforehand on fftstreamX { // CUDASYNC; //printf("CalculateMean\r\n"); cudaAcc_calculate_mean(PulsePoTLen, 0, AdvanceBy, FftLength); } if(!SkipPulse) { //printf("FindPulses\r\n"); cudaAcc_find_pulses((float) best_pulse->score, PulsePoTLen, AdvanceBy, FftLength); } if(!SkipTriplet) { //printf("FindTriplets\r\n"); cudaAcc_find_triplets(PulsePoTLen, (float)PoTInfo.TripletThresh, AdvanceBy, FftLength); } */ /* timespec t1, t2; t1.tv_sec = 0; t1.tv_nsec = 5000; while(cudaEventQuery(summaxDoneEvent) != cudaSuccess) nanosleep(&t1, &t2); */ int gflags = 0; if(b_gaussStarted) { //printf("fetchGaussFitFlags\r\n"); b_gaussStarted = false; gflags = cudaAcc_fetchGaussfitFlags(FftLength, best_gauss->score); } //printf("fetchTripletAndPulseFlags\r\n"); int has_dataT = 0, has_dataP = 0; if(!SkipTriplet) has_dataT = cudaAcc_fetchTripletFlags(SkipTriplet, PulsePoTLen, AdvanceBy, FftLength, offset); if(gflags > 0) { //printf("ProcessGaussFit\r\n"); cudaAcc_processGaussFit(FftLength, best_gauss->score); } if(!SkipTriplet) { if((has_dataT & 1) && !(has_dataT & 4)) // has triplet data and no error in triplet { //printf("processTripletResults\r\n"); cudaAcc_processTripletResults(PulsePoTLen, AdvanceBy, FftLength); } analysis_state.FLOP_counter+=(10.0 + PulsePoTLen) * NumPulsePoTs * (FftLength - 1); // ! hard to estimate, so be generous and use 9 analysis_state.FLOP_counter+=810.0; // (10.0*numBinsAboveThreshold*numBinsAboveThreshold); progress += ProgressUnitSize * TripletProgressUnits(); } if(!SkipPulse) has_dataP = cudaAcc_fetchPulseFlags(SkipTriplet, PulsePoTLen, AdvanceBy, FftLength, offset); if(!SkipPulse) { if((has_dataP & 2) && !(has_dataP & 8)) // has pulse data and no error in pulse { //printf("processPulseResults\r\n"); cudaAcc_processPulseResults(PulsePoTLen, AdvanceBy, FftLength); } analysis_state.FLOP_counter+=(PulsePoTLen*0.1818181818182+400.0)*PulsePoTLen * NumPulsePoTs * (FftLength - 1); progress += ProgressUnitSize * PulseProgressUnits(PulsePoTLen, FftLength - 1); } //#ifndef CUDAACC_EMULATION //if(!SkipTriplet) // cudaAcc_fetchTripletAndPulseFlags(SkipTriplet, SkipPulse, PulsePoTLen, AdvanceBy, FftLength); progress=std::min(progress,1.0); // prevent display of > 100% fraction_done(progress,remaining); //if(!SkipTriplet) // cudaAcc_processTripletResults(PulsePoTLen, AdvanceBy, FftLength); //#endif //CUDAACC_EMULATION } // else // { #endif //USE_CUDA // 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()"); } //#ifndef CUDAACC_EMULATION if(!SkipPulse) { retval = find_pulse(PulsePoT, PulsePoTLen, (float)PoTInfo.PulseThresh, TOffset, ThisPoT ); if (retval) SETIERROR(retval,"from find_pulse()"); } //#endif //CUDAACC_EMULATION // 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 (!nographics()) { 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; #ifdef USE_CUDA } #endif //USE_CUDA */ } // end looking for pulses if(b_gaussStarted) // process results late { //printf("late GaussBlock\r\n"); int flags = cudaAcc_fetchGaussfitFlags(FftLength, best_gauss->score); if(flags>0) cudaAcc_processGaussFit(FftLength, best_gauss->score); } return (retval); // no error return point }
int seti_parse_wu(FILE* f, ANALYSIS_STATE& state) { int retval=0; retval = seti_parse_wu_header(f); if (retval) SETIERROR(retval,"from seti_parse_wu_header()"); return seti_parse_data(f, state); }