Пример #1
0
//! Return the signal to noise ratio
float Pulsar::AdaptiveSNR::get_snr (const Profile* profile)
{
  Reference::To<PhaseWeight> baseline;

  if (baseline_estimator)
    baseline = baseline_estimator->operate (profile);
  else
    baseline = profile->baseline();

  Estimate<double> mean = baseline->get_mean();
  Estimate<double> variance = baseline->get_variance();

  unsigned nbin = profile->get_nbin();
  unsigned off_pulse = baseline->get_nonzero_weight_count();
  unsigned on_pulse = nbin - off_pulse;

  double energy = profile->sum() - mean.val * nbin;
  double snr = energy / sqrt(variance.val*on_pulse);

  if (Profile::verbose)
  {
    double rms = sqrt (variance.val);

    cerr << "Pulsar::AdaptiveSNR::get_snr " << off_pulse << " out of " << nbin
	 << " bins in baseline\n  mean=" << mean << " rms=" << rms 
	 << " energy=" << energy << " S/N=" << snr << endl;
  }

  if (energy < 0)
    return 0.0;

  return snr;
}    
Пример #2
0
void Pulsar::LastHarmonic::build ()
{
  if (!profile)
    throw Error (InvalidState, "Pulsar::LastHarmonic::build",
		 "Profile not set");

  if (!baseline_estimator)
    throw Error (InvalidState, "Pulsar::LastHarmonic::build",
		 "Baseline estimator not set");

  Reference::To<PhaseWeight> baseline = baseline_estimator->baseline (profile);

  Estimate<double> mean = baseline->get_mean ();
  Estimate<double> var = baseline->get_variance ();
  Estimate<double> rms = sqrt(var);

#ifdef _DEBUG
  cerr << "Pulsar::LastHarmonic::build mean=" << mean
       << " rms=" << rms << endl;
#endif

  significant.find (profile, rms.get_value());

  // skip the DC term
  bin_rise = 1;
  bin_fall = significant.get();
}
Пример #3
0
void Pulsar::RemoveBaseline::Each::transform (Archive* archive)
{
  const unsigned nsub = archive->get_nsubint();
  const unsigned nchan = archive->get_nchan();
  const unsigned npol = archive->get_npol();

  bool pscrunch = (archive->get_state() == Signal::Coherence ||
		   archive->get_state() == Signal::PPQQ);

  for (unsigned isub=0; isub < nsub; isub++)
  {
    Integration* subint = archive->get_Integration (isub);
    for (unsigned ichan=0; ichan < nchan; ichan++)
    {
      Reference::To<Profile> profile = subint->get_Profile (0,ichan);
      if (pscrunch)
      {
	profile = profile->clone();
	profile->sum (subint->get_Profile (1,ichan));
      }

      Reference::To<PhaseWeight> baseline = profile->baseline();

      for (unsigned ipol=0; ipol < npol; ipol++)
      {
	Profile* p = subint->get_Profile(ipol, ichan);
	baseline->set_Profile (p);
	p->offset (-baseline->get_mean().val);
      }
    }
  }
};
Пример #4
0
void Pulsar::ComponentModel::fit (const Profile *profile)
{
  build ();

  unsigned nbin = profile->get_nbin(); 
  vector<float> data (nbin);

  float mean = 0.0;
  float variance = 1.0;

  if (fit_derivative)
  {
    vector<complex<float> > spec(nbin/2+2);

    // FFT
    FTransform::frc1d(nbin, (float*)&spec[0], profile->get_amps());

    unsigned ic, nc=nbin/2+1;
    float scale = 1.0/nbin;
    for (ic=0; ic < nc; ic++)
      spec[ic] *= complex<float>(0.0f, ic) // scale by i*frequency
	* scale; // correction for DFT normalisation

    // IFFT
    FTransform::bcr1d (nbin, &data[0], (float*)&spec[0]);
  }
  else // normal profile
  {
    Reference::To<PhaseWeight> baseline = profile->baseline();
    variance = baseline->get_variance().get_value();
    mean = baseline->get_mean().get_value();

    if (verbose)
      cerr << "Pulsar::ComponentModel::fit mean=" << mean
	   << " variance=" << variance << endl;

    // copy data
    for (unsigned i=0; i < nbin; i++)
      data[i] = profile->get_amps()[i] - mean;
  }

  Axis<double> argument; 
  model->set_argument (0, &argument);

  vector< Axis<double>::Value > xval;  
  vector< Estimate<double> > yval;

  unsigned nfree = 0;

  for (unsigned i=0; i < nbin; i++)
  {
    double radians = (i+0.5)/nbin * 2*M_PI;

    xval.push_back( argument.get_Value(radians) );
    yval.push_back( Estimate<double>(data[i], variance) );

    nfree ++;
  }
  
  for (unsigned i=0; i<model->get_nparam(); i++)
    if (model->get_infit(i))
    {
      if (nfree == 0)
	throw Error (InvalidState, "Pulsar::ComponentModel::fit",
		     "more free parameters than data");
      nfree --;
    }

  // fit

  LevenbergMarquardt<double> fit;
  fit.verbose = Function::verbose;
    
  chisq = fit.init (xval, yval, *model);

  // fit.singular_threshold = 1e-15; // dodge covariance problems
  unsigned iter = 1;
  unsigned not_improving = 0;

  string result = "RMS";
  if (variance)
    result = "chisq";

  unsigned max_iter = 100;

  while (not_improving < 25 && iter < max_iter)
  { 
    if (verbose)
      cerr << "iteration " << iter;

    float nchisq = fit.iter (xval, yval, *model);

    if (verbose)
      cerr << "     " << result << " = " << nchisq << endl;
    
    if (nchisq < chisq)
    {
      float diffchisq = chisq - nchisq;
      chisq = nchisq;
      not_improving = 0;

      if (diffchisq/chisq < threshold && diffchisq > 0)
      {
	if (verbose)
	  cerr << "converged, delta " << result << " = " << diffchisq << endl;
	break;
      }
    }
    else
      not_improving ++;
    
    iter ++;
  }
  
  std::vector<std::vector<double> > covar;
  fit.result (*model, covar);
  
  for (unsigned iparam=0; iparam < model->get_nparam(); iparam++)
  {
    double variance = covar[iparam][iparam];

    if (verbose)
      cerr << "Pulsar::ComponentModel::fit"
	" variance[" << iparam << "]=" << variance << endl;

    if (!finite(variance))
      throw Error (InvalidState, 
		   "Pulsar::ComponentModel::fit",
		   "non-finite variance "
		   + model->get_param_name(iparam));

    if (!model->get_infit(iparam) && variance != 0)
      throw Error (InvalidState,
		   "Pulsar::ComponentModel::fit",
		   "non-zero unfit variance "
		   + model->get_param_name(iparam)
		   + " = " + tostring(variance) );

    if (variance < 0)
      throw Error (InvalidState,
		   "Pulsar::ComponentModel::fit",
		   "invalid variance " + model->get_param_name(iparam)
		   + " = " + tostring(variance) );

    // cerr << iparam << ".var=" << variance << endl;

    model->set_variance (iparam, variance);
  }

  if (fit_derivative) // copy best-fit parameters back
  {
    for (unsigned icomp=0; icomp < components.size(); icomp++)
    {
      components[icomp]->set_centre(derivative[icomp]->get_centre());
      components[icomp]->set_concentration
	(derivative[icomp]->get_concentration());
      components[icomp]->set_height(derivative[icomp]->get_height());
    }
  }
}