Ejemplo n.º 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);
}
Ejemplo n.º 2
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();
}
Ejemplo n.º 3
0
int main (int argc, char *argv[])
{
  bool  verbose    = false;
  bool  gaussian   = false;
  float factor     = 5.0;
  bool  log        = false;
  bool  shownoise  = false;
  int   method     = 0;
  int   bins       = 30;
  float cphs       = 0.0;
  float dcyc       = 0.0;
  float norm       = 0.0;

  int gotc = 0;

  while ((gotc = getopt(argc, argv, "qvVhlg:p:w:n:b:Gs")) != -1) {
    switch (gotc) {
    case 'h':
      usage ();
      return 0;

    case 'v':
      Pulsar::Archive::set_verbosity(2);
      verbose = true;
      break;

    case 'V':
      verbose = true;
      Pulsar::Archive::set_verbosity(3);
      break;

    case 'l':
      log = true;
      break;

    case 'g':
      factor = atof(optarg);
      break;

    case 'n':
      norm = atof(optarg);
      break;
      
    case 'p':
      cphs = atof(optarg);
      if (cphs > 0.0 && cphs < 1.0) {
	method = 2;
      }
      else {
	method = 1;
      }
      break;
      
    case 'w':
      dcyc = atof(optarg);
      break;

    case 'b':
      bins = atoi(optarg);
      break;

    case 'G':
      gaussian = true;
      break;

    case 's':
      shownoise = true;
      break;
      
    default:
      cout << "Unrecognised option: " << gotc << endl;
    }
  }
 
  vector<string> archives;
  vector<pulse>  pulses;
  vector<pulse>  noise;
  vector<pulse>  pgiants;
  vector<pulse>  ngiants;
  vector<hbin>   pdata;
  vector<hbin>   ndata;

  Reference::To<Pulsar::Archive> arch;

  for (int ai = optind; ai < argc; ai++)             // extract filenames
    dirglob (&archives, argv[ai]);
  
  try {
    
    cout << "Loading archives and extracting data..." << endl;
    
    for (unsigned i = 0; i < archives.size(); i++) {
      
      if (verbose) cerr << "Loading " << archives[i] << endl;

      arch = Pulsar::Archive::load(archives[i]);
      
      arch->fscrunch();        // remove frequency and polarisation resolution
      arch->pscrunch();
      arch->remove_baseline(); // Remove the baseline level

      scan_pulses(arch, pulses, method, cphs, dcyc);
      if (shownoise)
	scan_pulses(arch, noise, 2, arch->find_min_phase(dcyc), dcyc);
    }
    
    float offset = 2.0;
    
    if (shownoise) {
      offset = noise[0].flx;
      for (unsigned i = 1; i < noise.size(); i++)
	if (noise[i].flx < offset) offset = noise[i].flx;
      offset = fabs(offset);
      offset /= norm;
    }
    
    float threshold = find_giants(pulses, pgiants, factor, norm, offset);
    cout << "Detection threshold is roughly " << threshold << endl;

    display_giants(pgiants);

    prob_hist(pulses, pdata, bins);

    float submin = pdata[0].x;
    float submax = pdata[0].x;
    
    for (unsigned i = 1; i < pdata.size(); i++) {
      if (pdata[i].x > submax) submax = pdata[i].x;
      if (pdata[i].x < submin) submin = pdata[i].x;
    }

    if (shownoise) {
      find_giants(noise, ngiants, factor, norm, offset);
      prob_hist(noise, ndata, bins, submin, submax);
    }
    
    unsigned useful = 0;
    if (log) {
      vector<hbin>::iterator it = pdata.begin();
      while (it != pdata.end()) {
	if (pdata[useful].x < 0) {
	  pdata.erase(it);
	  continue;
	}
	else {
	  pdata[useful].x = logf(pdata[useful].x);
	  it++;
	  useful++;
	}
      }
      threshold = logf(threshold);
    }
    
    float xmin, xmax, ymin, ymax;
    
    xmin = xmax = pdata[0].x;
    ymin = ymax = pdata[0].y;
    
    // Find the extremes of the data set
    
    for (unsigned i = 1; i < pdata.size(); i++) {
      if (pdata[i].x > xmax) xmax = pdata[i].x;
      if (pdata[i].x < xmin) xmin = pdata[i].x;
      if (pdata[i].y > ymax) ymax = pdata[i].y;
      if (pdata[i].y < ymin) ymin = pdata[i].y;
    }

    
    // Plot pulse intensity probability distribution
    
    cpgopen("?");
    cpgsvp(0.1,0.9,0.15,0.9);
    cpgsci(7);
    cpgsch(1.3);
    
    cpgswin(xmin-(xmin/100.0), xmax+(xmax/100.0),
	    logf(ymin-(ymin/2.0)), logf(ymax+(ymax/2.0)));
    
    cpgbox("BCNST", 0.0, 0, "BCNST", 0.0, 0);
    cpgsci(8);
    if (log)
      cpglab("Log (Normalised Pulse Flux)", "Log (P(I))", "");
    else 
      cpglab("Normalised Pulse Flux", "Log (P(I))", "");
    cpgsci(5);
    
    // Plot the pulse detection threshold
    cpgsls(3);
    cpgsci(3);
    cpgmove(threshold, logf(ymin-(ymin/2.0)));
    cpgdraw(threshold, logf(ymax+(ymax/2.0)));
    cpgsls(1);

    // Plot points and associated error bars
    for (unsigned i = 0; i < pdata.size(); i++) {
      cpgpt1(pdata[i].x, logf(pdata[i].y), 4);
      cpgerr1(6, pdata[i].x, logf(pdata[i].y), pdata[i].e/pdata[i].y, 1.0);
    }

    if (gaussian) {
          
      MEAL::Gaussian gm1;
      
      fit_gauss(pdata, gm1);
      
      gm1.set_abscissa(xmin);
      cpgmove(xmin,logf(gm1.evaluate()));

      cpgsci(2);
      cpgsls(2); 
      
      float xval = 0.0;

      for (unsigned i = 1; i < 1000; i++) {
	xval = xmin+((xmax-xmin)/1000.0*i);
	gm1.set_abscissa(xval);
	cpgdraw(xval,logf(gm1.evaluate()));
      }

      if (shownoise) {
	
	MEAL::Gaussian ngm;

	fit_gauss(ndata, ngm);
	
	ngm.set_abscissa(xmin);
	cpgmove(xmin,logf(ngm.evaluate()));
	
	cpgsci(5);
	cpgsls(4); 

	for (unsigned i = 1; i < 1000; i++) {
	  xval = xmin + ((xmax-xmin)/250.0*i);
	  ngm.set_abscissa(xval);
	  if (log)
	    cpgdraw(logf(xval),logf(ngm.evaluate()));
	  else
	    cpgdraw(xval,logf(ngm.evaluate()));
	}
      }
    }

    cpgclos();

    // Free any used memory
    archives.clear();
    pulses.clear();
    noise.clear();
    pgiants.clear();
    ngiants.clear();
    pdata.clear();
    ndata.clear();
  }
  catch (Error& error) {
    fflush(stdout); 
    cerr << error << endl;
    exit(1);
  }
  
  fflush(stdout);
  return 0;
}