Ejemplo n.º 1
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;
}
Ejemplo n.º 2
0
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 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);
}
Ejemplo n.º 4
0
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<swi.analysis_cfg.gauss_pot_length; i++) gi.pot[i] = fp_PoT[i];   // ???
  scale_factor = static_cast<float>(gi.g.max_power) / 255.0f;
  if (gi.g.pot.size() != static_cast<size_t>(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<float>(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;
  }
  // 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);
#ifdef USE_MANUAL_CALLSTACK
      call_stack.exit();
#endif 
      return retval;
  }  
#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
) {
  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);
}