/*! This function assumes that the Integration will have the global attributes of the file. */ Pulsar::Integration* Pulsar::FITSArchive::load_Integration (const char* filename, unsigned isubint) try { if (!filename) throw Error (InvalidParam, "FITSArchive::load_Integration", "filename unspecified"); if (search_mode) throw Error (InvalidParam, "FITSArchive::load_Integration", "SEARCH mode data -- no Integrations to load"); Reference::To<Pulsar::Integration> integ = new_Integration(); init_Integration (integ); int row = isubint + 1; int status = 0; if (verbose > 2) cerr << "FITSArchive::load_Integration number " << isubint << endl; double nulldouble = 0.0; float nullfloat = 0.0; int initflag = 0; int colnum = 0; // Open the file fitsfile* fptr = 0; if (verbose > 2) cerr << "FITSArchive::load_Integration" " fits_open_file (" << filename << ")" << endl; fits_open_file (&fptr, filename, READONLY, &status); if (status != 0) throw FITSError (status, "FITSArchive::load_Integration", "fits_open_file(%s)", filename); // Move to the SUBINT Header Data Unit fits_movnam_hdu (fptr, BINARY_TBL, "SUBINT", 0, &status); if (status != 0) throw FITSError (status, "FITSArchive::load_Integration", "fits_movnam_hdu SUBINT"); // Load the convention for the epoch definition string epoch_def; string default_def = "STT_MJD"; psrfits_read_key (fptr, "EPOCHS", &epoch_def, default_def, verbose > 2); if (verbose > 2) cerr << "FITSArchive::load_Integration epochs are " << epoch_def << endl; // By default, correct epochs using the phase model bool correct_epoch_phase = true; // By default, correct epochs such that phase(epoch)=phase(start) bool phase_match_start_time = true; if (epoch_def == "VALID") correct_epoch_phase = phase_match_start_time = false; if (epoch_def == "MIDTIME") phase_match_start_time = false; if (get<Pulsar::IntegrationOrder>()) { colnum = 0; fits_get_colnum (fptr, CASEINSEN, "INDEXVAL", &colnum, &status); double value = 0.0; fits_read_col (fptr, TDOUBLE, colnum, row, 1, 1, &nulldouble, &value, &initflag, &status); if (status != 0) throw FITSError (status, "FITSArchive::load_Integration", "fits_read_col INDEXVAL"); get<Pulsar::IntegrationOrder>()->set_Index(row-1,value); } // Get the reference epoch from the primary header const Pulsar::FITSHdrExtension* hdr_ext = get<Pulsar::FITSHdrExtension>(); if (!hdr_ext) { throw Error (InvalidParam, "FITSArchive::load_Integration", "No FITSHdrExtension found"); } // Set the duration of the integration colnum = 0; fits_get_colnum (fptr, CASEINSEN, "TSUBINT", &colnum, &status); double duration = 0.0; fits_read_col (fptr, TDOUBLE, colnum, row, 1, 1, &nulldouble, &duration, &initflag, &status); integ->set_duration (duration); // Set the start time of the integration initflag = 0; colnum = 0; fits_get_colnum (fptr, CASEINSEN, "OFFS_SUB", &colnum, &status); double time = 0.0; fits_read_col (fptr, TDOUBLE, colnum, row, 1, 1, &nulldouble, &time, &initflag, &status); if (status != 0) throw FITSError (status, "FITSArchive::load_Integration", "fits_read_col OFFS_SUB"); MJD epoch = hdr_ext->get_start_time() + time; if (verbose > 2) cerr << "Pulsar::FITSArchive::load_Integration" " header epoch=" << hdr_ext->get_start_time().printdays(13) << "\n " " offset=" << time << "s epoch=" << epoch.printdays(13) << endl; // Set a preliminary epoch to avoid problems loading the polyco integ->set_epoch (epoch); // Set the folding period to 0 until one of three possible methods succeeds integ->set_folding_period (0.0); /* ********************************************************************** METHOD 1: folding period defined by a pulse phase model ********************************************************************** */ if (hdr_model) { // Set the folding period, using the polyco from the file header // This was taken out of the condition clause below because period // wasn't set when TSUB was 0 integ->set_folding_period (1.0 / hdr_model->frequency(epoch)); if (integ->get_folding_period() <= 0.0) throw Error( InvalidState, "Pulsar::FITSArchive::load_Integration", "header polyco/predictor corrupted; " "period(epoch=%s)=%lf", epoch.printdays(5).c_str(), integ->get_folding_period() ); if (integ->get_folding_period() < 1.0e-3) warning << "Pulsar::FITSArchive::load_Integration folding_period=" << integ->get_folding_period() << " is less than 1ms" << endl; else if (verbose > 2) cerr << "Pulsar::FITSArchive::load_Integration folding_period = " << integ->get_folding_period () << endl; if (duration && correct_epoch_phase) { if (verbose > 2) cerr << "Pulsar::FITSArchive::load_Integration correcting epoch phase" << endl; Phase reference_phs = 0.0; if (phase_match_start_time) { // Correct epoch such that its phase equals that of the start time if (verbose > 2) cerr << "Pulsar::FITSArchive::load_Integration matching phase(start)" << endl; reference_phs = hdr_model->phase(hdr_ext->get_start_time()); } Phase off_phs = hdr_model->phase(epoch); Phase dphase = off_phs - reference_phs; double dtime = dphase.fracturns() * integ->get_folding_period(); epoch -= dtime; integ->set_epoch (epoch); if (verbose > 2) { cerr << "Pulsar::FITSArchive::load_Integration row=" << row << "\n PRED_PHS=" << predicted_phase; if (phase_match_start_time) cerr << "\n reference epoch=" << hdr_ext->get_start_time().printdays(13); cerr << "\n reference phase=" << reference_phs << "\n input phase=" << off_phs << "\n phase offset=" << dphase << " = " << dtime << "s" "\n subint epoch=" << epoch.printdays(13) << "\n subint phase=" << hdr_model->phase(epoch) << endl; } } } else { /* ******************************************************************* METHOD 2: folding period defined by CAL_FREQ in primary header ******************************************************************* */ CalInfoExtension* calinfo = get<CalInfoExtension>(); if (calinfo && calinfo->cal_frequency > 0.0) { if (verbose > 2) cerr << "FITSArchive::load_Integration CAL_FREQ=" << calinfo->cal_frequency << endl; integ->set_folding_period( 1.0/calinfo->cal_frequency ); } /* ******************************************************************* METHOD 3: folding period defined by PERIOD column of SUBINT HDU ******************************************************************* */ double period = 0.0; status = 0; fits_get_colnum (fptr, CASEINSEN, "PERIOD", &colnum, &status); fits_read_col (fptr, TDOUBLE, colnum, row, 1, 1, &nulldouble, &period, &initflag, &status); if (status == 0 && period > 0.0) { if (verbose > 2) cerr << "FITSArchive::load_Integration PERIOD=" << period << endl; integ->set_folding_period (period); } if (integ->get_folding_period() == 0.0) throw FITSError (status, "FITSArchive::load_Integration", "folding period unknown: no model, CAL_FREQ or PERIOD"); } status = 0; // Load other useful info load_Pointing (fptr,row,integ); load_Plasma (fptr,row,integ); // Set up the data vector, only Pulsar::Archive base class is friend resize_Integration (integ); const unsigned nchan = get_nchan(); if (naux_profile) for (unsigned ichan=0; ichan < nchan; ichan++) { FourthMoments* fourth = new FourthMoments; fourth->resize (naux_profile, get_nbin()); integ->get_Profile(0,ichan)->add_extension (fourth); } // Load the channel centre frequencies if (verbose > 2) cerr << "Pulsar::FITSArchive::load_Integration reading channel freqs" << endl; int counter = 1; vector < float > chan_freqs(get_nchan()); colnum = 0; fits_get_colnum (fptr, CASEINSEN, "DAT_FREQ", &colnum, &status); fits_read_col (fptr, TFLOAT, colnum, row, counter, get_nchan(), &nullfloat, &(chan_freqs[0]), &initflag, &status); if (status != 0) throw FITSError (status, "FITSArchive::load_Integration", "fits_read_col DAT_FREQ"); // Set the profile channel centre frequencies if (verbose > 2) cerr << "Pulsar::FITSArchive::load_Integration setting frequencies" << endl; bool all_ones = true; for (unsigned j = 0; j < get_nchan(); j++) if (chan_freqs[j] != 1) all_ones = false; double chanbw = get_bandwidth() / get_nchan(); if ( all_ones ) { if (verbose > 2) cerr << "FITSArchive::load_Integration all frequencies unity - reseting" << endl; for (unsigned j = 0; j < get_nchan(); j++) integ->set_centre_frequency (j, get_centre_frequency() -0.5*(get_bandwidth()+chanbw)+j*chanbw); } else { for (unsigned j = 0; j < get_nchan(); j++) integ->set_centre_frequency(j, chan_freqs[j]); } // Load the profile weights if (verbose > 2) cerr << "Pulsar::FITSArchive::load_Integration reading weights" << endl; counter = 1; vector < float > weights(get_nchan()); colnum = 0; fits_get_colnum (fptr, CASEINSEN, "DAT_WTS", &colnum, &status); for (unsigned b = 0; b < get_nchan(); b++) { fits_read_col (fptr, TFLOAT, colnum, row, counter, 1, &nullfloat, &weights[b], &initflag, &status); counter ++; } if (status != 0) throw FITSError (status, "FITSArchive::load_Integration", "fits_read_col DAT_WTS"); // Set the profile weights if (verbose > 2) cerr << "Pulsar::FITSArchive::load_Integration setting weights" << endl; for(unsigned j = 0; j < get_nchan(); j++) integ->set_weight(j, weights[j]); // Load the profile offsets if (!Profile::no_amps) { vector<Profile*> profiles; setup_profiles_dat (integ, profiles); setup_dat (fptr, load_dat_io); if (verbose > 2) cerr << "FITSArchive::load_Integration dat_io=" << load_dat_io.ptr() << endl; load_dat_io->load (isubint + 1, profiles); if (scale_cross_products && integ->get_state() == Signal::Coherence) for (unsigned ichan=0; ichan < get_nchan(); ichan++) { integ->get_Profile(2, ichan)->scale(2.0); integ->get_Profile(3, ichan)->scale(2.0); } if (naux_profile) { setup_profiles<MoreProfiles> (integ, profiles); setup_aux (fptr, load_aux_io, naux_profile); load_aux_io->load (isubint + 1, profiles); } } if (verbose > 2) cerr << "Pulsar::FITSArchive::load_Integration load complete" << endl; // Finished with the file for now fits_close_file (fptr, &status); return integ.release(); } catch (Error& error) { throw error += "Pulsar::FITSArchive::load_Integration"; }
void dsp::Archiver::set (Pulsar::Archive* archive, const PhaseSeries* phase) try { if (verbose > 2) cerr << "dsp::Archiver::set Pulsar::Archive" << endl; if (!archive) throw Error (InvalidParam, "dsp::Archiver::set Pulsar::Archive", "no Archive"); if (!phase) throw Error (InvalidParam, "dsp::Archiver::set Pulsar::Archive", "no PhaseSeries"); const unsigned npol = get_npol (phase); const unsigned nchan = phase->get_nchan(); const unsigned nbin = phase->get_nbin(); const unsigned nsub = 1; if (verbose > 2) cerr << "dsp::Archiver::set Pulsar::Archive nsub=" << nsub << " npol=" << npol << " nchan=" << nchan << " nbin=" << nbin << " fourth=" << fourth_moments << endl; archive-> resize (nsub, npol, nchan, nbin); Pulsar::FITSHdrExtension* ext; ext = archive->get<Pulsar::FITSHdrExtension>(); if (ext) { if (verbose > 2) cerr << "dsp::Archiver::set Pulsar::Archive FITSHdrExtension" << endl; // Make sure the start time is aligned with pulse phase zero // as this is what the PSRFITS format expects. MJD initial = phase->get_start_time(); if (phase->has_folding_predictor()) { Phase inphs = phase->get_folding_predictor()->phase(initial); double dtime = inphs.fracturns() * phase->get_folding_period(); initial -= dtime; } ext->set_start_time (initial); // In keeping with tradition, I'll set this to a value that should // work in most places for the next 50 years or so ;) ext->set_coordmode("J2000"); // Set the ASCII date stamp from the system clock (in UTC) time_t thetime; time(&thetime); string time_str = asctime(gmtime(&thetime)); // Cut off the line feed character time_str = time_str.substr(0,time_str.length() - 1); ext->set_date_str(time_str); } archive-> set_telescope ( phase->get_telescope() ); archive-> set_type ( phase->get_type() ); switch (phase->get_state()) { case Signal::NthPower: case Signal::PP_State: case Signal::QQ_State: archive->set_state (Signal::Intensity); break; case Signal::FourthMoment: archive->set_state (Signal::Stokes); break; default: archive-> set_state ( phase->get_state() ); } archive-> set_scale ( Signal::FluxDensity ); if (verbose > 2) cerr << "dsp::Archiver::set Archive source=" << phase->get_source() << "\n coord=" << phase->get_coordinates() << "\n bw=" << phase->get_bandwidth() << "\n freq=" << phase->get_centre_frequency () << endl; archive-> set_source ( phase->get_source() ); archive-> set_coordinates ( phase->get_coordinates() ); archive-> set_bandwidth ( phase->get_bandwidth() ); archive-> set_centre_frequency ( phase->get_centre_frequency() ); archive-> set_dispersion_measure ( phase->get_dispersion_measure() ); archive-> set_dedispersed( archive_dedispersed ); archive-> set_faraday_corrected (false); /* ********************************************************************* ********************************************************************* Set any available extensions ********************************************************************* ********************************************************************* */ /* A valid Backend extension may have already been created; e.g. by the OutputArchive extension class. Therefore, if the Backend extension already exists, do not modifiy it. */ Pulsar::Backend* backend = archive -> get<Pulsar::Backend>(); if (!backend) { backend = new Pulsar::Backend; if (verbose > 2) cerr << "dsp::Archiver::set Pulsar::Backend extension" << endl; set (backend); archive->add_extension( backend ); } // Note, this is now called before the set(Integration,...) call below // so that the DigitiserCounts extension gets set up correctly the // first time. Pulsar::dspReduction* dspR = archive -> getadd<Pulsar::dspReduction>(); if (dspR) { if (verbose > 2) cerr << "dsp::Archiver::set Pulsar::dspReduction extension" << endl; set (dspR); } for (unsigned isub=0; isub < nsub; isub++) set (archive->get_Integration(isub), phase, isub, nsub); if (store_dynamic_extensions) { Pulsar::TwoBitStats* tbc = archive -> getadd<Pulsar::TwoBitStats>(); if (tbc) { if (verbose > 2) cerr << "dsp::Archiver::set Pulsar::TwoBitStats extension" << endl; set (tbc); } Pulsar::Passband* pband = archive -> getadd<Pulsar::Passband>(); if (pband) { if (verbose > 2) cerr << "dsp::Archiver::set Pulsar::Passband extension" << endl; set (pband); } } Pulsar::Telescope* telescope = archive -> getadd<Pulsar::Telescope>(); try { telescope->set_coordinates ( phase -> get_telescope() ); } catch (Error& error) { if (verbose > 2) cerr << "dsp::Archiver WARNING could not set telescope coordinates\n\t" << error.get_message() << endl; } // default Receiver extension Pulsar::Receiver* receiver = archive -> getadd<Pulsar::Receiver>(); receiver->set_name ( phase -> get_receiver() ); receiver->set_basis ( phase -> get_basis() ); for (unsigned iext=0; iext < extensions.size(); iext++) archive -> add_extension ( extensions[iext] ); // set_model must be called after the Integration::MJD has been set if( phase->has_folding_predictor() ) { if (verbose > 2) cerr << "dsp::Archiver::set has predictor" << endl; archive-> set_model ( phase->get_folding_predictor(), false ); } else if (verbose > 2) cerr << "dsp::Archiver::set PhaseSeries has no predictor" << endl; if (phase->has_pulsar_ephemeris()) archive-> set_ephemeris( phase->get_pulsar_ephemeris(), false ); archive-> set_filename (get_filename (phase)); if (verbose > 2) cerr << "dsp::Archiver set archive filename to '" << archive->get_filename() << "'" << endl; } catch (Error& error) { throw error += "dsp::Archiver::set Pulsar::Archive"; }