Example #1
0
/* This algorithm uses zero padding in the fourier domain to
   interpolate the cross correlation function in the time domain. The
   technique is described at:
  
   http://www.dspguru.com/howto/tech/zeropad2.htm 
*/
Estimate<double> Pulsar::ZeroPadShift::get_shift () const
{
  // First compute the standard cross correlation function:

  Reference::To<Pulsar::Profile> ptr = observation->clone();
  Reference::To<Pulsar::Profile> stp = standard->clone();

  // Remove the baseline
  *ptr -= ptr->mean(ptr->find_min_phase(0.15));

  // Perform the correlation
  ptr->correlate (standard);

  // Remove the baseline
  *ptr -= ptr->mean(ptr->find_min_phase(0.15));
  
  vector< Estimate<float> > correlation;

  const unsigned nbin = observation->get_nbin();
 
  for (unsigned i = 0; i < nbin; i++) {
    correlation.push_back(ptr->get_amps()[i]);
  }
  
  vector< Estimate<float> > interpolated;
  
  interpolated.resize(correlation.size() * interpolate);
  
  // Perform the zero-pad interpolation
  
  fft::interpolate(interpolated, correlation);
  
  // Find the peak of the correlation function
  
  float maxval = 0.0;
  float maxloc = 0.0;
  
  for (unsigned i = 0; i < interpolated.size(); i++) {
    if (interpolated[i].val > maxval) {
      maxval = interpolated[i].val;
      maxloc = float(i) / interpolate;
    }
  }
  
  // Error estimate (???)
  float ephase = 1.0 / float(nbin);
  
  double shift = double(maxloc) / double(nbin);
  
  if (shift < -0.5)
    shift += 1.0;
  else if (shift > 0.5)
    shift -= 1.0;
  
  return Estimate<double>(shift,ephase*ephase);
}
Example #2
0
Pulsar::Profile* differentiate (const Pulsar::Profile* profile, unsigned off=1)
{
  Reference::To<Pulsar::Profile> difference = profile->clone();

  unsigned nbin = profile->get_nbin();
  const float* amps = profile->get_amps();
  float* damps = difference->get_amps();

  for (unsigned ibin=0; ibin < nbin; ibin++)
    damps[ibin] = amps[(ibin+off)%nbin] - amps[ibin];

  return difference.release();
}
Example #3
0
void Pulsar::SquareWave::get_transitions (const Profile* profile,
					  vector<unsigned>& up,
					  vector<unsigned>& down)
{
  unsigned nbin = profile->get_nbin();
  unsigned scrunch = 1;

  Reference::To<Profile> clone;
  if (use_nbin && nbin > use_nbin) {
    clone = profile->clone();
    scrunch = nbin/use_nbin;
    clone->bscrunch(scrunch);
    profile = clone;
    nbin = profile->get_nbin();
  }

  unsigned offset = (unsigned) (risetime * nbin);

cerr << "nbin=" << nbin << " offset=" << offset << endl;

  // differentiate the profile
  Reference::To<Profile> difference = differentiate (profile, offset);

  float* amps = difference->get_amps();

  // find the phase window in which the mean is closest to zero
  BaselineWindow window;
  window.set_find_mean (0.0);
  window.get_smooth()->set_turns (0.2);
  float zero = window.find_phase (nbin, amps);

  // get the noise statistics of the zero mean region
  double mean = 0;
  double variance = 0;
  difference->stats (zero, &mean, &variance);

cerr << "mean=" << mean << " rms=" << sqrt(variance) << endl;

  // check that the mean is actually zero
  double rms = sqrt(variance);
  if (mean > rms)
    throw Error (InvalidState, "Pulsar::SquareWave::get_transitions",
		 "mean=%lf > rms=%lf", mean, rms);

  float cutoff = threshold * rms;

  find_transitions (nbin, amps, up, cutoff);
  find_transitions (nbin, amps, down, -cutoff);
}
Example #4
0
void Pulsar::SpectrumPlot::get_spectra (const Archive* data)
{
  unsigned nchan = data->get_nchan();

  spectra.resize(1);
  spectra[0].resize(nchan);

  Reference::To<ProfileStats> stats;
  Reference::To<TextInterface::Parser> parser;

  if (!expression.empty())
  {
    stats = new ProfileStats;
    parser = stats->get_interface ();
  }

  Reference::To<const Integration> subint;
  subint = get_Integration (data, isubint);

  for (unsigned ichan=0; ichan<nchan; ichan++)
  {
    Reference::To<const Profile> profile;
    profile = get_Profile (subint, ipol, ichan);
    if (profile -> get_weight() == 0.0)
      spectra[0][ichan] = 0.0;
    else if (stats)
    {
      stats->set_Profile (profile);
      string value = process( parser, expression );
      spectra[0][ichan] = fromstring<float>( value );
    }
    else if (ibin.get_integrate())
      spectra[0][ichan] = profile->sum() / (float)profile->get_nbin();
    else
      spectra[0][ichan] = profile->get_amps()[ibin.get_value()];
  }
}
Example #5
0
void psrpca::finalize ()
{
  arrival->set_observation ( total );
  arrival->get_toas(toas);

  if ( remove_std_baseline )
    std_archive -> remove_baseline ();
  Reference::To<Profile> std_prof = std_archive->get_Profile(0, 0, 0);
  float *s_amps = std_prof->get_amps ();
  const float nbin = std_prof->get_nbin ();

  double scale, offset, snr;

  if ( total_count < nbin )
    cerr << "WARNING: psrpca::finalize - not enough observations provided, "
	    "covariance matrix will not have full rank" << endl;

  //total->remove_baseline();

  gsl_matrix *profiles = gsl_matrix_alloc ( (unsigned)nbin, total_count );

  for (unsigned i_subint = 0; i_subint < total->get_nsubint(); i_subint++ )
  {
    Reference::To<Profile> prof = total->get_Profile ( i_subint, 0, 0 );
    if ( apply_shift )
      prof->rotate_phase ( toas[i_subint].get_phase_shift() );
    snr = prof->snr ();

    //calculate the scale
    float *p_amps = prof->get_amps ();
    scale = 0.0;

    for ( unsigned i_bin = 0; i_bin < nbin; i_bin++ )
    {
      scale += s_amps[i_bin] * p_amps[i_bin];
    }
    scale = (prof->get_nbin()* scale - prof->sum() * std_prof->sum()) /
	    (prof->get_nbin()* std_prof->sumsq() - std_prof->sum() * std_prof->sum());

    // calculate the baseline offset
    offset = (scale * std_prof->sum() - prof->sum()) / nbin;

    if ( prof_to_std )
    {
      //match the profile to standard and subtract the standard
      if ( apply_offset )
	prof->offset  ( offset );
      if ( apply_scale )
	prof->scale ( 1.0/scale );
      prof->diff ( std_prof );

      double* damps;
      damps = new double [ (unsigned)nbin ];
      transform( prof->get_amps(), prof->get_amps() + (unsigned)nbin, damps, CastToDouble() );

      gsl_vector_const_view view = gsl_vector_const_view_array( damps, nbin );
      gsl_matrix_set_col ( profiles, i_subint, &view.vector );
      t_cov->add_Profile ( prof, snr );
    }
    else
    {// prof_to_std is false
      Reference::To<Profile> diff = prof->clone ();
      diff->set_amps ( std_prof->get_amps () );
      if ( apply_offset ) 
	diff->offset( -offset );
      if ( apply_scale ) 
	diff->scale (scale);
      diff->diff ( prof );
      diff->scale (-1);

      double* damps;
      damps = new double [ (unsigned)nbin ];
      transform( diff->get_amps(), diff->get_amps() + (unsigned)nbin, damps, CastToDouble() );

      gsl_vector_const_view view = gsl_vector_const_view_array( damps, nbin );
      gsl_matrix_set_col ( profiles, i_subint, &view.vector );

      t_cov->add_Profile ( diff, snr );
      prof->set_amps ( diff->get_amps() );
    }
  }

  covariance = gsl_matrix_alloc ( (int) nbin, (int) nbin );
  t_cov->get_covariance_matrix_gsl ( covariance );

  // write the covariance matrix and difference profiles
  FILE *out;
  if ( save_covariance_matrix )
  {
    out = fopen ( (prefix+"_covariance.dat").c_str(), "w" );
    gsl_matrix_fprintf(out, covariance, "%g");
    fclose ( out );
  } // save covariance matrix

  if ( save_diffs ) 
    total->unload ( prefix+"_diffs.ar" );

  //solve the eigenproblem
  gsl_matrix_view m = gsl_matrix_submatrix ( covariance, 0, 0, (int)nbin, (int)nbin );
  gsl_vector *eval = gsl_vector_alloc ( (int)nbin );
  gsl_matrix *evec = gsl_matrix_alloc ( (int)nbin, (int)nbin );

  gsl_eigen_symmv_workspace *w = gsl_eigen_symmv_alloc ( (int)nbin );
  gsl_eigen_symmv ( &m.matrix, eval, evec, w );
  gsl_eigen_symmv_free ( w );
  gsl_eigen_symmv_sort ( eval, evec, GSL_EIGEN_SORT_VAL_DESC );

  // save evectors
  if ( save_evecs )
  {
    Reference::To<Archive> evecs_archive = total->clone();
    gsl_vector *evec_copy = gsl_vector_alloc ( (int)nbin );

    for (unsigned iext=0; iext < evecs_archive->get_nextension(); iext++)
    {
      delete evecs_archive->get_extension(iext);
    }

    evecs_archive->resize ( (unsigned)nbin, 1, 1, (unsigned)nbin );

    for (unsigned i_evec = 0; i_evec < (unsigned)nbin; i_evec++ )
    {
      gsl_vector_view view = gsl_matrix_column(evec, i_evec);

      gsl_vector_memcpy ( evec_copy, &view.vector );
      evecs_archive->get_Profile ( i_evec, 0, 0 ) -> set_amps ( evec_copy->data );
    }
    evecs_archive->unload ( prefix+"_evecs.ar" );
  } // save evectors

  if ( save_evals )
  {
    out = fopen ( (prefix+"_evals.dat").c_str(), "w" );
    gsl_vector_fprintf ( out, eval, "%g" );
    fclose ( out );
  } // save_evals

  // decompose profiles onto eigenvectors
  gsl_matrix *decompositions = gsl_matrix_alloc ( (unsigned)nbin, total_count );

  gsl_blas_dgemm ( CblasTrans, CblasNoTrans, 1.0, evec, profiles, 0.0, decompositions );

  if ( save_decomps )
  {
    out = fopen ( (prefix + "_decomposition.dat").c_str(), "w" );
    gsl_matrix_fprintf ( out, decompositions, "%g");
    fclose ( out );
  } // save decompositions

  if ( !residuals_file.empty() )
  {
    //read in the residuals:
    double tmp;
    unsigned residual_count = 0;

    gsl_vector *mjds = gsl_vector_alloc ( total->get_nsubint() );
    gsl_vector *residuals = gsl_vector_alloc ( total->get_nsubint() );
    gsl_vector *residuals_err = gsl_vector_alloc ( total->get_nsubint() );
    //TODO check the format of the input
    ifstream inFile( residuals_file.c_str() );
    if ( inFile.is_open() )
    {
      while ( inFile.good() )
      {
	inFile >> tmp;
	if ( !inFile.good() )
	  break;
	gsl_vector_set(mjds, residual_count, tmp);

	inFile >> tmp;
	gsl_vector_set(residuals, residual_count, tmp*1e6);

	inFile >> tmp;
	gsl_vector_set(residuals_err, residual_count, tmp);

	residual_count ++ ;
      }
      inFile.close ();
      if ( residual_count != total->get_nsubint() )
      {
	cerr << "psrpca::finalize wrong number of residuals provided. Got " << residual_count 
		<< " while needed " << total->get_nsubint()<< endl;
	exit (-1) ;
      }

    }
    else
    {
Example #6
0
int scan_pulses(Reference::To<Pulsar::Archive> arch, vector<pulse>& data, 
		int method, float cphs, float dcyc)
{
  /* Find and store the flux and phase of each pulse in the file
     to the data vector. */
  
  pulse newentry;

  Reference::To<Pulsar::Profile> prof;
  
  newentry.file = arch->get_filename();

  double nm, nv, vm;
  
  int nbin = arch->get_nbin();
  int bwid = int(float(nbin) * dcyc);
  int cbin = 0;

  for (unsigned i = 0; i < arch->get_nsubint(); i++) {

    newentry.intg = i;
    
    prof = arch->get_Profile(i, 0, 0);
    
    prof->stats(prof->find_min_phase(), &nm, &nv, &vm);
    newentry.err = sqrt(nv);

    switch (method) {
      
    case 0: // Method of total flux
      
      newentry.flx = prof->sum();
      newentry.phs = prof->find_max_phase();
      break;
      
    case 1: // Method of maximum amplitude

      if (dcyc == 0.0) {
	newentry.flx = prof->max();
	newentry.phs  = prof->find_max_phase();
      }
      else {
	cbin = int(prof->find_max_phase(dcyc) * float(nbin));
	newentry.flx = prof->sum(cbin - bwid/2, cbin + bwid/2);
	newentry.phs  = prof->find_max_phase(dcyc);
      }
      break;

    case 2: // User-defined phase centre
      
      cbin = int(float(nbin) * cphs);

      if (dcyc == 0.0) {
	newentry.flx = (prof->get_amps())[cbin];
	newentry.phs = cphs;
      }
      else {
	newentry.flx = prof->sum(cbin - bwid/2, cbin + bwid/2);
	newentry.phs = cphs;
      }
      
      break;
      
    default:
      cerr << "No phase selection method chosen!" << endl;
    }
    
    data.push_back(newentry);
  }
  
  return data.size();
}
Example #7
0
void psrspa::create_histograms ( Reference::To<Archive> archive )
{
  if ( verbose )
    cerr << "psrspa::create_histograms entered" << endl;
  // ensure Stokes parameters if creating polarisation histograms
  if ( create_polar_degree || create_polar_angle )
  {
    archive->convert_state ( Signal::Stokes );
    if ( verbose )
      cerr << "psrspa::create_histograms converted state of the archive to Stokes" << endl;
  }

  // auxillary vectors
  //vector< Estimate<float > > aux_vec_f;
  vector< Estimate<double > > aux_vec_d;

  // Full Stokes profile
  Reference::To<PolnProfile> profile;
  // Polarized flux
  Reference::To<Profile> P;
  P = new Profile;
  // Total flux
  float *T_amps = new float [ nbin ];
  float *P_amps = new float [ nbin ];

  unsigned bin_min, bin_max;

  if ( verbose && max_bscrunch > 1 )
    cerr << "psrspa::create_histograms entering the bscrunch loop for the " << archive->get_filename () << " archive" << endl;
  // TODO Uh, this should be fixed up. The first idea was to enable the phase resolved histograms to be bscrunch-aware as well, but I think it doesn't make much sense so I decided to keep only the max flux bscrunch aware. This can be done much more neatly probably in such a case
  for ( current_bscrunch = 1 ; current_bscrunch <= max_bscrunch ; current_bscrunch *= 2 )
  {
    // in each passage, we bscrunch by a factor of 2
    if ( current_bscrunch > 1 )
    {
      if ( verbose )
	cerr << "psrspa::create_histograms bscrunching the archive " << archive->get_filename () << " by a factor of 2" << endl;
      archive->bscrunch ( 2 );
    }
    if ( verbose )
      cerr << "psrspa::create_histograms entering the loop through subints of the " << archive->get_filename () << " archive" << endl;
    // loop through subints
    for ( unsigned isub = 0; isub < archive->get_nsubint (); isub++ )
    {
      if ( verbose )
	cerr << "psrspa::create_histograms creating necessary profiles for subint " << isub << " of " << archive->get_filename () << endl;
      if ( create_polar_angle || create_polar_degree && current_bscrunch == 1 )
      {
	profile = archive->get_Integration(isub)->new_PolnProfile(0);
	if ( verbose )
	  cerr << "psrspa::create_histograms retrieved PolnProfile for subint " << isub << " of " << archive->get_filename () << endl;
      }
      if ( create_polar_angle && current_bscrunch == 1 )
      {
	profile->get_orientation ( aux_vec_d, 0 );
	if ( verbose )
	  cerr << "psrspa::create_histograms retrieved polarisation angle for subint " << isub << " of " << archive->get_filename () << endl;
      }
      if ( create_polar_degree || create_flux || find_max_amp_in_range )
      {
	stats.set_profile ( archive->get_Profile ( isub, 0, 0 ) );
	b_sigma = sqrt ( stats.get_baseline_variance ().get_value () );
	T_amps = archive->get_Profile ( isub, 0, 0 )->get_amps (); 
	if ( verbose )
	  cerr << "psrspa::create_histograms retrieved total flux amps for subint " << isub << " of " << archive->get_filename () << endl;
	if ( create_polar_degree && current_bscrunch == 1 )
	{
	  profile->get_polarized ( P );
	  if ( verbose )
	    cerr << "psrspa::create_histograms retrieved polarized flux profile for subint "  << isub << " of " << archive->get_filename () << endl;
	  P_amps = P->get_amps ();
	  if ( verbose )
	    cerr << "psrspa::create_histograms retrieved polarized flux amps for subint " << isub << " of " << archive->get_filename () << endl;
	}
      }

      if ( verbose )
	cerr << "psrspa::create_histograms looping through the provided phase ranges for subint " << isub << " of " << archive->get_filename () << endl;
      unsigned curr_hist = 0;
      // loop through phase ranges
      for ( unsigned irange = 0; irange < phase_range.size () ; irange++ )
      {
	if ( irange%2 == 0)
	{
	  bin_min = unsigned( floor ( phase_range[irange] * float(nbin / current_bscrunch ) + 0.5 ) );
	  if ( verbose ) 
	    cerr << "psrspa::create_histograms set minimal bin to " << bin_min << endl;
	}
	else
	{
	  bin_max = unsigned( floor ( phase_range[irange] * float(nbin / current_bscrunch ) + 0.5 ) );
	  if ( bin_max == nbin )
	    bin_max = nbin - 1 ;
	  if ( verbose ) 
	    cerr << "psrspa::create_histograms set maximum bin to " << bin_max << endl;
	  // loop through bins in the given phase range
	  for ( unsigned ibin = bin_min; ibin <= bin_max; ibin++ )
	  {
	    if ( create_polar_angle && current_bscrunch == 1 )
	    {
	      int result = gsl_histogram_increment ( h_polar_angle_vec[curr_hist], aux_vec_d[ibin].get_value () / 180.0 * M_PI );
	      if ( result == GSL_EDOM )
	      {
		if ( dynamic_histogram )
		{
		  gsl_histogram *temp_hist = gsl_histogram_clone ( h_polar_angle_vec[curr_hist] );
		  h_flux_pr_vec[curr_hist] = update_histogram_range ( temp_hist, aux_vec_d[ibin].get_value () / 180.0 * M_PI );
		}
		else {
		  warn << "WARNING psrspa::create_histograms polarisation angle the histogram range for the bin " << ibin << " in the subint " << isub << " of archive " << archive->get_filename () << endl;
		}
	      }
	    }
	    if ( create_polar_degree && current_bscrunch == 1 )
	    {
	      // if P_amps[ibin] or T_amps[ibin] < 3 sigma, set polar degree to zero
	      int result = gsl_histogram_increment ( h_polar_degree_vec[curr_hist], ( fabs ( P_amps[ibin] ) < 3.0 * b_sigma || fabs ( T_amps[ibin] ) < 3.0 * b_sigma ) ? 0.0 : P_amps[ibin] / T_amps[ibin] );
	      if ( result == GSL_EDOM )
	      {
		if ( dynamic_histogram )
		{
		  gsl_histogram *temp_hist = gsl_histogram_clone ( h_polar_degree_vec[curr_hist] );
		  h_flux_pr_vec[curr_hist] = update_histogram_range ( temp_hist, ( fabs ( P_amps[ibin] ) < 3.0 * b_sigma || fabs ( T_amps[ibin] ) < 3.0 * b_sigma ) ? 0.0 : P_amps[ibin] / T_amps[ibin] );
		}
		else {
		warn << "WARNING psrspa::create_histograms polarisation degree outside the histogram range for the bin " << ibin << " in the subint " << isub << " of archive " << archive->get_filename () << endl;
		}
	      }
	    }
	    if ( create_flux && current_bscrunch == 1 )
	    {
	      int result = 0;
	      if ( log && T_amps[ibin] > 0.0 )
	      {
		result = gsl_histogram_increment ( h_flux_pr_vec[curr_hist], log10f ( T_amps[ibin] ) );
	      }
	      else if ( !log )
	      {
		result = gsl_histogram_increment ( h_flux_pr_vec[curr_hist], T_amps[ibin] );
	      }
	      if ( result == GSL_EDOM )
	      {
		if ( dynamic_histogram )
		{
		  gsl_histogram *temp_hist = gsl_histogram_clone ( h_flux_pr_vec[curr_hist] );
		  h_flux_pr_vec[curr_hist] = update_histogram_range ( temp_hist, log ? log10f ( T_amps[ibin] ) : T_amps[ibin] );
		}
		else {
		  warn << "WARNING psrspa::create_histograms phase resolved flux outside the histogram range for the bin " << ibin << " in the subint " << isub << " of archive " << archive->get_filename () << " flux = " << T_amps[ibin] << endl;
		}
	      }
	    }
	    // increment the histogram id
	    curr_hist ++;
	  } // loop through bins in the given phase range
	  // find the maximum amplitude in given phase range.
	  if ( find_max_amp_in_range )
	  {
	    if ( verbose )
	      cerr << "psrspa::create_histograms finding the maximum amplitude in the phase range " << irange << " of the subint " << isub << " (archive " << archive->get_filename () << ")" << endl;
	    int max_bin = archive->get_Profile ( isub, 0, 0 )->find_max_bin ( (int)bin_min, (int)bin_max );
	    identifier current_identifier = { archive->get_filename (), isub, bin_min, bin_max, current_bscrunch,
	      (unsigned)max_bin, T_amps[max_bin], b_sigma }; 
	    max_amp_info.push_back ( current_identifier );
	  } // find maximal amplitude in the given phase range
	} // handle given phase range
      } // loop through phase ranges
    } // loop through subints
  } // bscrunch loop
  if ( verbose )
    cerr << "psrspa::create_histograms finished" << endl;
}// create_histograms