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); } } } };
/*! Upon completion, the flux of the archive will be normalized with respect to the flux of the calibrator, such that a FluxCalibrator simply scales the archive by the calibrator flux. */ void Pulsar::PolnCalibrator::calibrate (Archive* arch) try { if (verbose > 2) cerr << "Pulsar::PolnCalibrator::calibrate" << endl; calibration_setup (arch); if (arch->get_npol() == 4) { BackendCorrection correct_backend; correct_backend (arch); if (verbose > 2) cerr << "Pulsar::PolnCalibrator::calibrate Archive::transform" <<endl; arch->transform (response); arch->set_poln_calibrated (true); if (receiver) { Receiver* rcvr = arch->get<Receiver>(); if (!rcvr) throw Error (InvalidState, "Pulsar::PolnCalibrator::calibrate", "Archive has no Receiver Extension"); rcvr->set_basis_corrected (true); } } else if (arch->get_npol() == 1) { if (Archive::verbose) cerr << "Pulsar::PolnCalibrator::calibrate WARNING" " calibrating only absolute gain" << endl; unsigned nsub = arch->get_nsubint (); unsigned nchan = arch->get_nchan (); for (unsigned isub=0; isub < nsub; isub++) { Integration* subint = arch->get_Integration (isub); for (unsigned ichan=0; ichan < nchan; ichan++) { double gain = abs(det( response[ichan] )); Profile* profile = subint->get_Profile (0, ichan); profile -> scale (gain); profile -> set_weight ( profile->get_weight() / gain ); } } } else throw Error (InvalidParam, "Pulsar::PolnCalibrator::calibrate", "Archive::npol == %d not yet implemented", arch->get_npol()); arch->set_scale (Signal::ReferenceFluxDensity); } catch (Error& error) { throw error += "Pulsar::PolnCalibrator::calibrate"; }
void Pulsar::UVMArchive::load_header (const char* filename) { int newscan = 0; uvm_header* header = new uvm_header; header_ptr = header; if (uvm_getheader (filename, &program, &newscan, header) < 0) throw Error (InvalidState, "Pulsar::UVMArchive::load_header", "%s is not a UVM archive", filename); cerr << "newscan=" << newscan << endl; char buffer[80]; uvm_get_source (header, buffer); source = buffer; uvm_get_observatory (header, buffer); telescope = buffer; telescope = "Arecibo"; uvm_get_windows (header, buffer); cerr << "Pulsar::UVMArchive::load_header windows=" << buffer << " nwins=" << header->nwins << endl; centre_frequency = header->obfreq; bandwidth = header->abandwd; npol = header->anumsbc; if (npol == 4) set_state (Signal::Stokes); cerr << "anumsbc=" << header->anumsbc << endl; /* if (header->apoladd) npol = 1; */ dispersion_measure = header->adm; rotation_measure = header->arm; if (header->nwins == 0) { nbin = header->apbins; cerr << "nbin = apbins = " << nbin; } else { nbin = 0; for (int iwin=0; iwin < header->nwins; iwin++) { cerr << "nbin += " << header->nwbins[iwin] << endl; nbin += header->nwbins[iwin]; } } nchan = 1; if (Profile::no_amps) { cerr << "no amps" << endl; return; } cerr << "date (dddyy)=" << header->date << endl; cerr << "start sec=" << header->startime << endl; utc_t utc; utc.tm_yday = header->date / 100; utc.tm_year = 1900 + header->date % 100; utc.tm_min = header->scantime / 60; utc.tm_sec = header->scantime - utc.tm_min * 60; utc.tm_hour = utc.tm_min / 60; utc.tm_min -= utc.tm_hour * 60; MJD mjd_start (utc); // load all BasicIntegration attributes and data from filename uvm_data data; unsigned loaded_subints = 0; while (uvm_getdata (program, header, &data) >= 0) { loaded_subints ++; resize (loaded_subints); Integration* integration = get_Integration(loaded_subints-1); // cerr << "start usec=" << header->scantime << endl; epoch = mjd_start + header->scantime * 1e-6; integration->set_folding_period (header->period); integration->set_duration (header->period); integration->set_epoch (epoch); integration->set_centre_frequency(0, centre_frequency); // scaleI is the scale to convert to microJy double scale = header->scaleI * 1e-3; double offset = header->baseval; for (unsigned ipol=0; ipol < get_npol(); ipol++) { float* amps = integration->get_Profile(ipol, 0) -> get_amps(); for (unsigned ibin=0; ibin < get_nbin(); ibin++) { amps[ibin] = (data.data[ipol][ibin] + offset) * scale; } } } }
void Pulsar::BackendCorrection::operator () (Archive* arch) const try { Backend* backend = arch->get<Backend>(); if (!backend || backend->get_corrected()) return; Signal::State state = arch->get_state(); Signal::Basis basis = arch->get_basis(); Signal::Hand hand = backend->get_hand(); Signal::Argument argument = backend->get_argument(); bool correct_lsb = must_correct_lsb (backend, arch); if (Archive::verbose > 2) cerr << "Pulsar::BackendCorrection::operator basis=" << basis << " hand=" << hand << " phase=" << argument << " lsb=" << correct_lsb << endl; /* complex conjugation due to lower sideband downconversion and backend convention have the same effect; the following lines effect an exclusive or operation. */ if (correct_lsb) { if (Archive::verbose > 2) cerr << "Pulsar::BackendCorrection::operator down conversion" << endl; if (argument == Signal::Conjugate) argument = Signal::Conventional; else argument = Signal::Conjugate; } unsigned npol = arch->get_npol(); if (npol < 2) return; bool swap01 = false; bool flip[4] = { false, false, false, false }; if (npol == 4) { if (argument == Signal::Conjugate) { if (Archive::verbose > 2) cerr << "Pulsar::BackendCorrection::operator phase convention" << endl; if (state == Signal::Stokes && basis == Signal::Circular) flip[2] = !flip[2]; // Flip Stokes U else flip[3] = !flip[3]; // Flip Stokes V or Im[AB] } if (hand == Signal::Left) { if (Archive::verbose > 2) cerr << "Pulsar::BackendCorrection::operator hand" << endl; if (state == Signal::Stokes && basis == Signal::Circular) flip[2] = !flip[2]; // Flip Stokes U and ... else if (state == Signal::Stokes && basis == Signal::Linear) flip[1] = !flip[1]; // Flip Stokes Q and ... else if (state == Signal::PseudoStokes) flip[1] = !flip[1]; // Flip AA-BB and ... flip[3] = !flip[3]; // Flip Stokes V or Im[AB] } } // If state == Coherence or PPQQ ... if (hand == Signal::Left && (state == Signal::Coherence || state == Signal::PPQQ)) swap01 = true; bool flip_something = false; for (unsigned ipol=0; ipol < npol; ipol++) if (flip[ipol]) { if (Archive::verbose > 2) cerr << "Pulsar::BackendCorrection::operator flip " << ipol << endl; flip_something = true; } if (swap01 && Archive::verbose > 2) cerr << "Pulsar::BackendCorrection::operator swap 0 and 1" << endl; if (flip_something || swap01) { for (unsigned isub=0; isub < arch->get_nsubint(); isub++) { Integration* integration = arch->get_Integration(isub); for (unsigned ichan=0; ichan < arch->get_nchan(); ichan++) { for (unsigned ipol=0; ipol < npol; ipol++) if (flip[ipol]) integration->get_Profile(ipol, ichan)->scale(-1); if (swap01) integration->expert()->swap_profiles(0, ichan, 1, ichan); } } } backend->set_corrected (); } catch (Error& error) { throw error += "Pulsar::BackendCorrection::operator"; }