00001 //# MirVisReader.h: reads data from a Miriad Visibility dataset 00002 //# Copyright (C) 2000,2001,2002 00003 //# Associated Universities, Inc. Washington DC, USA. 00004 //# 00005 //# This library is free software; you can redistribute it and/or modify it 00006 //# under the terms of the GNU Library General Public License as published by 00007 //# the Free Software Foundation; either version 2 of the License, or (at your 00008 //# option) any later version. 00009 //# 00010 //# This library is distributed in the hope that it will be useful, but WITHOUT 00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00012 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00013 //# License for more details. 00014 //# 00015 //# You should have received a copy of the GNU Library General Public License 00016 //# along with this library; if not, write to the Free Software Foundation, 00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 00018 //# 00019 //# Correspondence concerning AIPS++ should be addressed as follows: 00020 //# Internet email: aips2-request@nrao.edu. 00021 //# Postal address: AIPS++ Project Office 00022 //# National Radio Astronomy Observatory 00023 //# 520 Edgemont Road 00024 //# Charlottesville, VA 22903-2475 USA 00025 //# 00026 //# 00027 //# $Id: MirVisReader.h,v 1.2 2009/09/03 23:28:32 pteuben Exp $ 00028 00029 #ifndef BIMA_MIRVISREADER_H 00030 #define BIMA_MIRVISREADER_H 00031 00032 #include <casa/Logging/LogIO.h> 00033 #include <casa/Containers/Block.h> 00034 #include <casa/Containers/List.h> 00035 00036 #include <miriad/Filling/FillMetadata.h> 00037 #include <mirlib/miriad.h> 00038 00039 #include <casa/namespace.h> 00040 //# Forward Declarations 00041 namespace casa { //# NAMESPACE CASA - BEGIN 00042 class String; 00043 class AipsError; 00044 //class GlishRecord; 00045 } //# NAMESPACE CASA - END 00046 00047 //class GlishArray; 00048 class MirVarHandler; 00049 00050 // <summary> 00051 // a container for a data record read in from a Miriad datatset 00052 // </summary> 00053 // 00054 // <use visibility=local> 00055 // 00056 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos=""> 00057 // </reviewed> 00058 // 00059 // <etymology> 00060 // this class holds the record-dependent data from a Miriad dataset 00061 // </etymology> 00062 // 00063 // <motivation> 00064 // MSes filled from Miriad data feature multiple windows of differing shapes. 00065 // Performance during MS reads can be aided by collecting together MS table 00066 // records of the same shape (e.g. of the same window). MirFiller accoplishes 00067 // this by reading all baselines from a single timestamp at once, so that 00068 // they written out in order of spectral window. This class provides a 00069 // container for holding the data from different baselines. 00070 // 00071 // Access Performance is aided when the data from a Miriad dataset is filled 00072 // in a particular order. This class provides a container so that the data 00073 // can be buffered for "sorting" prior to filling into the output MS. 00074 // </motivation> 00075 // 00076 // <synopsis> 00077 // At the moment, this is intended for use only by the MirFiller class. 00078 // 00079 // 00080 // </synopsis> 00081 // 00082 // <example> 00083 // 00084 // 00085 // </example> 00086 // 00087 // <todo asof="2001/02/22"> 00088 // 00089 // </todo> 00090 // 00091 class MirDataRecord : MirTypeAssert { 00092 Int np_p, nn_p, nw_p, pol_p; 00093 Bool marked_p; 00094 Double *preamble_p; 00095 Float *narrow_p; 00096 Float *wide_p; 00097 Int *flags_p; 00098 Int *wflags_p; 00099 00100 public: 00101 MirDataRecord(Int nnarrow=0, Int nwide=0, Int npreamble=5); 00102 ~MirDataRecord(); 00103 00104 // return the number of preamble elements 00105 uInt getPreambleCount() { return np_p; } 00106 00107 // return the number of narrow band channels 00108 uInt getNarrowCount() { return nn_p; } 00109 00110 // return the number of wide band channels 00111 uInt getWideCount() { return nw_p; } 00112 00113 // return the address of the preamble buffer 00114 Double *preamble() { return preamble_p; } 00115 00116 // return the address of the narrow channel data buffer 00117 Float *narrow() { return narrow_p; } 00118 00119 // return the address of the wide channel data buffer 00120 Float *wide() { return wide_p; } 00121 00122 // return the address of the flags channel data buffer 00123 Int *flags() { return flags_p; } 00124 00125 // return the address of the wflags channel data buffer 00126 Int *wflags() { return wflags_p; } 00127 00128 // return the polarization code 00129 Int pol() { return pol_p; } 00130 00131 // set the polarization code 00132 void setPol(Int val) { pol_p = val; } 00133 00134 // return true if this record is marked 00135 Bool isMarked() { return marked_p; } 00136 00137 // set the mark 00138 void setMarked(Bool val) { marked_p = val; } 00139 00140 void copyFrom(const MirDataRecord& other); 00141 }; 00142 00143 // <summary> 00144 // a Miriad history reader 00145 // </summary> 00146 // 00147 // <use visibility=export> 00148 // 00149 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos=""> 00150 // </reviewed> 00151 // 00152 // <etymology> 00153 // Class name is short for Miriad history reader. 00154 // </etymology> 00155 // 00156 // <motivation> 00157 // Miriad history is read independently from the visibility data; thus, 00158 // an independent class is in order. This class hides the details of how 00159 // to read Miriad history. 00160 // </motivation> 00161 // 00162 // <synopsis> 00163 // This class is used to extract history from a Miriad visibility dataset. 00164 // Normally, an application does not create this class by itself, but rather 00165 // via MirVisReader::openHistory(); 00166 // </synopsis> 00167 // 00168 // <example> 00169 // 00170 // 00171 // </example> 00172 // 00173 // <todo asof="2001/05/15"> 00174 // </todo> 00175 // 00176 class MirHisReader { 00177 private: 00178 Int uv_handle_p, eof_p; 00179 Char hline[256]; 00180 00181 public: 00182 00183 // create a History reader from a Miriad file handle 00184 MirHisReader(Int mirhandle) : uv_handle_p(mirhandle), eof_p(0) { 00185 hisopen_c(uv_handle_p, "read"); 00186 } 00187 00188 // delete the reader 00189 ~MirHisReader() { 00190 hisclose_c(uv_handle_p); 00191 } 00192 00193 // return true this reader there is no more history to read 00194 Bool atEnd() { return (eof_p > 0); } 00195 00196 // read the next available line into a String. True is returned 00197 // if line was successfully loaded; False is returned 00198 // if the last line had already been read. 00199 Bool readLine(String &line) { 00200 if (atEnd()) return False; 00201 hisread_c(uv_handle_p, hline, 256, &eof_p); 00202 line = hline; 00203 return True; 00204 } 00205 }; 00206 00207 // <summary> 00208 // a Miriad visibility dataset reader 00209 // </summary> 00210 // 00211 // <use visibility=export> 00212 // 00213 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos=""> 00214 // </reviewed> 00215 // 00216 // <etymology> 00217 // Class name is short for Miriad visibility reader. 00218 // </etymology> 00219 // 00220 // <motivation> 00221 // MSes filled from Miriad data feature multiple windows of differing shapes. 00222 // Performance during MS reads can be aided by collecting together MS table 00223 // records of the same shape (e.g. of the same window). MirFiller accomplishes 00224 // this by reading all baselines from a single timestamp at once, so that 00225 // they written out in order of spectral window. This class provides a 00226 // container for holding the data from different baselines. It also 00227 // encapsulates all the knowledge needed for reading Miriad data. 00228 // </motivation> 00229 // 00230 // <synopsis> 00231 // This class is used to extract data from a Miriad visibility dataset. 00232 // 00233 // 00234 // </synopsis> 00235 // 00236 // <example> 00237 // 00238 // 00239 // </example> 00240 // 00241 // <todo asof="2001/05/15"> 00242 // <li> deal with telescopes, correlator modes </li> 00243 // <li> support multiple polarizations </li> 00244 // <li> make handleVarChanges() a protected virtual function </li> 00245 // </todo> 00246 // 00247 class MirVisReader : MirTypeAssert { 00248 public: 00249 enum wideConventions { NONE=0, BIMA, MIRIAD, MIXED, NCONV }; 00250 00251 private: 00252 // info that doesn't change during life of filler 00253 String inname_p; 00254 Int uv_handle_p; // miriad file handle 00255 uInt debug; 00256 LogIO log_p; 00257 00258 // variable information worth caching 00259 List<MirFreqSetup*> fsetups_p; // the correlator setups found 00260 List<MirSource*> sources_p; // the sources found 00261 List<String> telescopes_p; // the telescopes found 00262 MirPolSetup pol_p; 00263 Int maxchan_p, maxwide_p, maxspect_p, narray_p, nrec_p; 00264 Int nobs_p, nscan_p; // These are indicative, not invarient 00265 Int badnsyst_p, badwsyst_p; // # of recs with bad system temps 00266 Int firstmode_p; // first correlator mode encountered 00267 Double starttime_p, endtime_p; 00268 wideConventions wideconv_p; // apparent wide-channel convention 00269 00270 // read state 00271 Block<MirDataRecord *> buf_p; 00272 Int nintrec_p, maxrec_p, nnarr_p, nwide_p; 00273 Double time_p; // in AIPS++ frame 00274 MirVarHandler *varhandler_p; 00275 Bool varupd_p, hasmore_p, dowide_p, verbose_p, previewed_p, scanned_p; 00276 00277 public: 00278 // construct a reader. mirfile is the name of Miriad dataset. If 00279 // dopreview is False, the previewing of the dataset's contents will 00280 // be delayed. If doscan is True (and dopreview is True), the entire 00281 // input dataset will be read to take an accounting of its contents; 00282 // set this to False to prevent this for a very large file (see also 00283 // preview()). dbg is the default debug level to set; this value is 00284 // passed to setDebugLevel(). 00285 MirVisReader(const String& mirfile, Bool doscan=True, Int dbg=0, 00286 Bool dopreview=True); 00287 00288 // destroy the reader 00289 ~MirVisReader(); 00290 00291 // set the debugging level which controls the amount of debugging 00292 // messages that are printed to the terminal (as opposed to the logger). 00293 // A value of zero or less will cause no extra messages to be printed; 00294 // increasing values will increase the amount of messages. 00295 void setDebugLevel(Int level) { debug = (level < 0) ? 0 : (uInt) level; } 00296 00297 // set the debugging level which controls the amount of debugging 00298 // messages that are printed to the terminal. A value of zero or less 00299 // means that no extra messages will be printed; increasing values will 00300 // increase the amount of messages. 00301 Int getDebugLevel() const { return debug; } 00302 00303 // return true if the debugging level is at least as high as a given 00304 // level. 00305 Bool Debug(Int level) { return (level <= Int(debug)); } 00306 00307 // return the Miriad dataset name 00308 const String& getName() { return inname_p; } 00309 00310 // rewind the input dataset and prepare for a new reading. filler is 00311 // the object that will handle updates to variables; if NULL, no handler 00312 // will be alerted when variables change. If dowide is True, the 00313 // wideband data will be read in, too. maxrec is the 00314 // maximum number of records to read per timestamp; if maxrec<=0, 00315 // it will adjust dynamically to the number of baselines being processed. 00316 void reset(MirVarHandler *filler=NULL, Bool verbose=False, 00317 Bool dowide=True, Int maxrec=0); 00318 00319 // read in the data for a single timestamp. fm is the container 00320 // to use to store retrieved metadata. 00321 Int readIntegration(::FillMetadata &fm); 00322 00323 // return the (AIPS++-referenced) timestamp for the current buffered 00324 // records. This is only correct after a call to readIntegration(). 00325 Double getTime() { return time_p; } 00326 00327 // return the number of records buffered for the current integration 00328 Int getNumRecs() { return nintrec_p; } 00329 00330 // return the correlation data for the i-th buffered record. 00331 MirDataRecord *getRecord(Int i) { return buf_p[i]; } 00332 00333 // set the marked data item for each MirDataRecord to False 00334 void clearMarks() { 00335 for(Int i=0; i < nintrec_p; i++) buf_p[i]->setMarked(False); 00336 } 00337 00338 // create and return a new pointer to a history reader. The caller 00339 // should delete the reader when finished with it. 00340 MirHisReader *openHistory() { return new MirHisReader(uv_handle_p); } 00341 00342 // return the basic characteristics of the input dataset as a Record. 00343 // If scan is True, the entire file will be scanned (if necessary) to 00344 // all the information; otherwise, an incomplete description may be given 00345 // based on just the first record. If verbose is True, a summary is 00346 // sent to the logger. Note that this function may force a call to 00347 // preview() if it has not already been called. 00348 //PJT GlishRecord summary(Bool verbose=True, Bool scan=True); 00349 00350 // return the basic characteristics of the input dataset as a Record. 00351 // A scanning of the entire file will be forced so that the number of 00352 // scans and observations can be counted with the given limits: 00353 // scanlim is the maximum time gap in seconds allowed between records 00354 // of the same scan; obslim is maximum gap in seconds between 00355 // records of the same observation. If verbose is True, a summary is 00356 // sent to the logger. 00357 //PJT GlishRecord summary(Int scanlim, Int obslim, Bool verbose=True); 00358 00359 // get the full list of polarization correlation types seen thus far 00360 ConstMirPolSetup& getDefaultPolSetup() { return pol_p; } 00361 00362 // return the list of sources 00363 const List<MirSource*>& getSourceList() { return sources_p; } 00364 00365 protected: 00366 // peek into the contents of the dataset to cache important information. 00367 // scanlim and obslim are used for counting the number of observations 00368 // and scans in the dataset. scanlim is the maximum time gap in seconds 00369 // allowed between records of the same scan; obslim is maximum gap 00370 // in seconds between records of the same observation. If scan is True 00371 // (the default), the dataset will be read through to gather the 00372 // information; otherwise, limited information will be gleaned from the 00373 // first record and scanlim and obslim will be ignored. One can set 00374 // scan=False for very large datasets to avoid this overhead. 00375 void preview(Int scanlim, Int obslim, Bool scan=True); 00376 00377 // peek into the contents of the dataset to cache important 00378 // information. If scan is True 00379 // (the default), the dataset will be read through to gather the 00380 // information; otherwise, limited information will be gleaned from the 00381 // first record. One can set scan=False for very large datasets to avoid 00382 // this overhead. Five minutes and four hours are used for the scan and 00383 // observation gap limit (when scan=True). 00384 void preview(Bool scan=True) { preview(300, 2400, scan); } 00385 00386 // return True if this dataset has been previewed 00387 Bool previewed() { return previewed_p; } 00388 00389 // return the basic characteristics of the input dataset as a Record. 00390 // If verbose is True, a summary is 00391 // sent to the logger. 00392 // scan specifies the conditions under which the entire dataset may 00393 // get read as a result of this request: if scan < 0, the dataset 00394 // will not be read; if scan=0, it will only be read if it hasn't 00395 // already (using scanlim and obslim if necessary; if scan > 0, the 00396 // dataset will be read and scanlim and obslim will be used to count 00397 // scans and observations. 00398 // scanlim is the maximum time gap in seconds 00399 // allowed between records of the same scan; obslim is maximum gap 00400 // in seconds between records of the same observation. 00401 //GlishRecord summary(Bool verbose, Int scan, Int scanlim, Int obslim); 00402 00403 // return the contents of a MirPolSetup list as a GlishArray 00404 //static GlishArray toGlishArray(ConstMirPolSetup &pol); 00405 00406 // return the contents of a String List as a GlishArray 00407 //static GlishArray toGlishArray(const List<String>& list); 00408 00409 private: 00410 00411 // return true if this reader should be verbose in its messages. This 00412 // will be true if the verbose option is enabled or the debug level is 00413 // greater than 1. 00414 Bool verbose() { return (verbose_p || debug > 1); } 00415 00416 // check to be sure that the given name points to a readable miriad 00417 // dataset. If not, throw an exception. 00418 void checkIsMiriadDataset(const String& name) throw(AipsError); 00419 00420 // resize the data buffer for a new read. Values less than or equal 00421 // to zero mean keep previous value. 00422 void resizeBufferFor(Int nrec=0, Int nnarrow=0, Int nwide=0); 00423 00424 // full and brief scanning of the data--should only be called from preview() 00425 void fullscan(Int scanlim, Int obslim); 00426 void briefscan(); 00427 00428 // update the given FillMetadata container with updated variable values. 00429 // If a VarHandler was provide via reset(), signal the changes to it. 00430 // fm is the FillMetadata container to update, and time is the current 00431 // timestamp. 00432 void handleVarChanges(::FillMetadata &fm, Double time); 00433 00434 // add to a cached list of telescopes 00435 void setTelescope(String name) { 00436 ListIter<String> li(telescopes_p); 00437 for(li.toStart(); ! li.atEnd() && li.getRight() != name; ++li); 00438 if (li.atEnd()) li.addRight(name); 00439 } 00440 }; 00441 00442 #endif