//# Importmiriad: miriad dataset to casacore::MeasurementSet conversion //# Copyright (C) 1997,2000,2001,2002,2013,2015 //# Associated Universities, Inc. Washington DC, USA. //# //# This program is free software; you can redistribute it and/or modify //# it under the terms of the GNU General Public License as published by //# the Free Software Foundation; either version 2 of the License, or //# (at your option) any later version. //# //# This program is distributed in the hope that it will be useful, //# but WITHOUT ANY WARRANTY; without even the implied warranty of //# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //# GNU General Public License for more details. //# //# You should have received a copy of the GNU General Public License //# along with this program; if not, write to the Free Software //# Foundation, Inc., 675 Masve, Cambridge, MA 02139, USA. //# #ifndef MIRIAD_IMPORTMIRIAD_H #define MIRIAD_IMPORTMIRIAD_H //#Includes #include <casacore/casa/Inputs/Input.h> #include <casacore/casa/OS/File.h> #include <casacore/casa/Utilities/GenSort.h> #include <casacore/casa/Arrays/Cube.h> #include <casacore/casa/Arrays/Matrix.h> #include <casacore/casa/Arrays/Vector.h> #include <casacore/casa/Arrays/ArrayMath.h> #include <casacore/casa/Arrays/ArrayUtil.h> #include <casacore/casa/Arrays/ArrayLogical.h> #include <casacore/casa/Arrays/MatrixMath.h> #include <casacore/measures/Measures.h> #include <casacore/measures/Measures/MPosition.h> #include <casacore/measures/Measures/MeasData.h> #include <casacore/measures/Measures/Stokes.h> #include <casacore/tables/Tables.h> #include <casacore/tables/Tables/TableInfo.h> #include <casacore/ms/MeasurementSets.h> #include <casacore/mirlib/maxdimc.h> #include <casacore/mirlib/miriad.h> #include <casacore/casa/namespace.h> namespace casa { //# NAMESPACE CASA - BEGIN // MIRIAD dataset casacore::MeasurementSet filler. Derived from carmafiller. // // Despite that this program is written in C++ and uses classes, it is // really a set of routines manipulating a huge common block..... // // Acknowledgement: this program was originally cloned off uvfitsfiller.cc // whose code is now in MSFitsInput.cc // Ray Plante wrote the other filler, with which we had // some cross talk // // // Limitations, Caveats and Remaining ToDo's // - does not apply the various (miriad) complex gain corrections // (uvcat and friends should be used for that in miriad, it would be // silly to duplicate that code here) // - this code won't run if casacore::Double!=double or casacore::Float!=float or casacore::Int!=int // On some future 64bit machines this may cause problems? // - CARMA type arrays when dishes are not the same size // - do not mix arrays from different telescopes (e.g. BIMA and ATCA) // but it should handle different configurations (ARRAYs) of the same // instrument // - handle multiple array configuration datasets that were UVCAT'ed // (needs to count antennae up at each array configuration) // - true miriad storage manager ? // // - check UV override, is that being handled transparently? // // - spectral windows layout (code present, fix table access descriptors) // CHECK: what happens if e.g. uvcat does some line= preprocessing // - correct restfreq's in source tables that relate to the spectral windows // (this code currently coredumps) // - make win=,narrow=,wide=0 cause non of them to be written in that selection // - add weather table // - although no more wides are written, there is a way to make a small MS // from the wides only by preprocessing in miriad, but conceivably // could be done here as well?? -- except the narrow= keyword seems to write // files that suffer from the casacore::Table array conformance error // // Todo: to deal with multiple zoom setups (freq changes), we need // to track which spectral windows each source appears to make a proper // source table indexed by source id and spw id // History: // Spring 1997: written (cloned off uvfitsfiller) Peter Teuben // July 1997: Y2K, fixed table-interface PJT // Dec 1997: fixed wideband only data (e.g. uvgen) PJT // ??? somebody fixed up this code for some new release ??? // May 2000: fixed up for various new AIPS++ conventions PJT // and added multi-source & field PJT // Sep 2000: development now on linux, converted to OldMS PJT // Dec 2000: casacore::Conversion to casacore::MS (MS2) PJT // typical compile time: (P600/256M/15MBps HD: 36") // typical 3c273 conversion time: 2.6" (5.3->11.3 MB) // Cf. that to "uvio" processing time, which runs at disk I/O // speed (15 MB/s on the beforementioned laptop) // Jan-Feb 2001: window layout, restfreq's and various things to get // msmultiscale to work; added some syscal support PJT // April 2001: final cleanup for the 1.5 AIPS++ release - PJT // [note that from this moment on bimafiller is for // experimental use and deprecated, the new version // will be called 'mirfiller' // Oct 2001: mirlib changed location // Sep 2009: revived in CASA, added various tables for CARMA // also renamed from bimafiller to carmafiller // Sep 2011: initial release // Mar 2013: Rename to importmiriad and make it work for ATCA // CABB data (more channels, windows and 4 pols) MHW // May 2014: Fix some compiler warnings, add TOPO option MHW // Jul 2015: Cope with data with changing freq setups,e.g., // CABB zoom data with multiple sources MHW // Jan 2016 Turn from standalone app into tool+task MHW // a placeholder for the MIRIAD spectral window configuration // see also the MIRIAD programmers guide, and its appendix on UV Variables // for CARMA we have MAXWIN = MAXWIDE (16 normally, 6 in 2006-2009, more later) // narrow band (plus MAXWIDE space to point into the wide band data too) typedef struct window { // CASA defines everything mid-band mid-interval int nspect; // number of valid windows (<=MAXWIN, typically 16) int nschan[MAXWIN+MAXWIDE]; // number of channels in a window int ischan[MAXWIN+MAXWIDE]; // starting channel of a window (1-based) double sdf[MAXWIN+MAXWIDE]; // channel separation double sfreq[MAXWIN+MAXWIDE]; // frequency of first channel in window (doppler changes) double restfreq[MAXWIN+MAXWIDE]; // rest freq, if appropriate char code[MAXWIN+MAXWIDE]; // code to CASA identification (N, W or S; S not used anymore) // wide band (for CARMA these are the spectral window averages - i.e. nspect=nwide) int nwide; // number of wide band channels float wfreq[MAXWIDE]; // freq float wwidth[MAXWIDE]; // width // ifchain for ATCA int chain[MAXWIN+MAXWIDE]; // if conversion chain } WINDOW; // the maximum number of fields in mosaicing observations, careful, miriad // often has a smaller value, like 64 or 128. #ifndef MAXFIELD # define MAXFIELD 10000 #endif #ifndef MAXMSG # define MAXMSG 256 #endif #ifndef MAXFSET # define MAXFSET 100 #endif // a helper class class Importmiriad { // This is an implementation helper class used to store 'local' data // during the filling process. public: // Create from a miriad dataset (a directory) Importmiriad(casacore::String& infile, casacore::Int debug=0, casacore::Bool Qtsys=false, casacore::Bool Qarrays=false, casacore::Bool Qlinecal=false); // Standard destructor ~Importmiriad(); // Check some of the contents of the data and header read void checkInput(casacore::Block<casacore::Int>& spw, casacore::Block<casacore::Int>& wide); // Debug output level casacore::Bool Debug(int level); // Set up the casacore::MeasurementSet, including StorageManagers and fixed columns. // If useTSM is true, the Tiled Storage Manager will be used to store // DATA, FLAG and WEIGHT_SPECTRUM void setupMeasurementSet(const casacore::String& MSFileName, casacore::Bool useTSM=true); // Fill the main table by reading in all the visibilities void fillMSMainTable(); // Make an Antenna casacore::Table (can be called incrementally now) void fillAntennaTable(); // Make a Syscal casacore::Table (can be called incrementally) void fillSyscalTable(); // fill Spectralwindow table void fillSpectralWindowTable(casacore::String vel); // fill Field table void fillFieldTable(); // fill Source table void fillSourceTable(); // fill the Feed table with minimal info needed for synthesis processing void fillFeedTable(); // Fill the Observation and History (formerly ObsLog) tables void fillObsTables(); // fix up the EPOCH MEASURE_REFERENCE keywords using the value found // in the (last) AN table - check if miriad really needs it void fixEpochReferences(); void Tracking(int record); void check_window(); casacore::Bool compareWindows(WINDOW& w1, WINDOW& w2); void Error(char *msg); void Warning(char *msg); void show(); void close(); private: casacore::String infile_p; // filename casacore::Int uv_handle_p; // miriad handle casacore::MeasurementSet ms_p; // the casacore::MS itself casacore::MSColumns *msc_p; // handy pointer to the columns in an casacore::MS casacore::Int debug_p; // debug level casacore::String array_p, project_p, object_p, telescope_p, observer_p, version_p, timsys_p; casacore::Vector<casacore::Int> nPixel_p, corrType_p, corrIndex_p; casacore::Matrix<casacore::Int> corrProduct_p; casacore::Double epoch_p; casacore::MDirection::Types epochRef_p; casacore::Int nArray_p; // number of arrays (nAnt_p.nelements()) casacore::Block<casacore::Int> nAnt_p; // number of antennas per array casacore::Block<casacore::Vector<casacore::Double> > receptorAngle_p; casacore::Vector<casacore::Double> arrayXYZ_p; // needs to be made with 3 elements casacore::Vector<casacore::Double> ras_p, decs_p; // ra/dec for source list (source_p) casacore::Vector<casacore::String> source_p, // list of source names (?? object_p ??) purpose_p; // purpose of this source casacore::LogIO os_p; // logger casacore::Vector<casacore::Bool> keep_p; // keep this window for output to MS // the following variables are for miriad, hence not casacore::Double/casacore::Int/Float // thus the code may have to be fixed on machines where these do not // agree ... may need special access code to get those into CASA // types on 64 bit machines?? double preamble[5] /*, first_time*/; int ifield, nfield, npoint /*, nsource*/; // both dra/ddec should become casacore::Vector's float dra[MAXFIELD], ddec[MAXFIELD]; // offset in radians double ra[MAXFIELD], dec[MAXFIELD]; int field[MAXFIELD]; // source index int fcount[MAXFIELD]; float dra_p=0, ddec_p=0; int pol_p[4]; // char message[MAXMSG]; // The following items more or less follow the uv variables in a dataset casacore::Int nants_p, nants_offset_p, nchan_p, nwide_p, npol_p; casacore::Double antpos[3*MAXANT]; casacore::Float phasem1[MAXANT]; casacore::Double ra_p, dec_p; // current pointing center RA,DEC at EPOCH casacore::Float inttime_p, jyperk_p; casacore::Double freq_p; // rest frequency of the primary line casacore::Int mount_p; casacore::Double time_p; // current MJD time casacore::Double timeFirst_p; // First MJD time encountered // MIRIAD spectral window definition casacore::Int freqSet_p,nFreqSet_p,ddid_p; WINDOW win[MAXFSET]; // allow for 16 different frequency setups casacore::Bool Qtsys_p; /* tsys weight's */ casacore::Bool Qarrays_p; /* write separate arrays */ casacore::Bool Qlinecal_p; /* do linecal */ // casacore::Data buffers.... again in MIRIAD format float data[2*MAXCHAN], wdata[2*MAXCHAN]; // 2*MAXCHAN since (Re,Im) pairs complex numbers int flags[MAXCHAN], wflags[MAXCHAN]; float systemp[MAXANT*MAXWIDE]; int zero_tsys; // Counters int nvis; }; } // Namespace CASA - END #endif