casa
$Rev:20696$
|
00001 //# VLALogicalRecord.h: This class interprets a VLA logical record. 00002 //# Copyright (C) 1999,2000 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 //# $Id$ 00027 00028 #ifndef NRAO_VLALOGICALRECORD_H 00029 #define NRAO_VLALOGICALRECORD_H 00030 00031 #include <casa/Containers/Block.h> 00032 #include <casa/Utilities/CountedPtr.h> 00033 #include <casa/aips.h> 00034 #include <nrao/VLA/VLAADA.h> 00035 #include <nrao/VLA/VLAArchiveInput.h> 00036 #include <nrao/VLA/VLACDA.h> 00037 #include <nrao/VLA/VLAEnum.h> 00038 #include <nrao/VLA/VLARCA.h> 00039 #include <nrao/VLA/VLASDA.h> 00040 00041 #include <casa/namespace.h> 00042 namespace casa { //# NAMESPACE CASA - BEGIN 00043 template <class T> class Vector; 00044 } //# NAMESPACE CASA - END 00045 00046 // <summary>This class interprets a VLA logical record.</summary> 00047 00048 // <reviewed reviewer="" date="" tests="" demos=""> 00049 00050 // <prerequisite> 00051 // <ol> 00052 // <li> The IO Module 00053 // </ol> 00054 // </prerequisite> 00055 // 00056 // <etymology> 00057 // This class is designed to reconstitute VLA archive data records. 00058 // </etymology> 00059 // 00060 // <synopsis> 00061 00062 // This class is designed to read VLA archive data. The data may be read from 00063 // a disk, tape drive or any other data source supported by the IO module. A 00064 // call to the operator++() function assembles the next reconstructed VLA 00065 // archive data record from the input. A reference to this data can be 00066 // obtained using the logicalRecord function. 00067 // 00068 // Refer to the "VLA Archive Data Format", VLA Computer Memorandum 186 00069 // by G.C. Hunt, K.P. Sowinski, and T.J. Bottomly; June 1993. 00070 // (This is also available as AIPS++ note 159) 00071 // 00072 // The VLA archive records are always a multiple of 2048 bytes. The 00073 // record sizes were designed for use with magnetic tapes, so there is 00074 // a maximum physical record size of 13*2048=26624 bytes. 00075 // 00076 // The low level class (blockio), that actually does the I/O, allows 00077 // for a record (hereinafter chunk) size and for a input block size of 00078 // a multiple of the chunk size. The low level read operation tests 00079 // for the number of bytes actually read from the device. 00080 // 00081 // The helper classes VlaDiskInput, VlaTapeInput, and VlaStdInput are 00082 // designed to deal with the low level input from the devices in an 00083 // analogous fashion to the ones used for FITS input. 00084 // 00085 // Since a read may be issued for an arbitrary number of bytes from a 00086 // disk, the chunk multiple is arbitrary and may be used to tune the 00087 // speed of operation. There is an obvious trade-off between the 00088 // block size created in the blockio class and the number of read 00089 // operations. 00090 // 00091 // The story is quite different for tape input. A read request for at 00092 // least the maximum physical record size must be made to avoid loss of 00093 // data. Since a single tape record will be read with a single read 00094 // operation, there is no point is having it any larger. The chunk 00095 // multiple must be exactly 13 so that the block size is 26624. 00096 // 00097 // The reconstitution algorithm is as follows: 00098 // 00099 // 1. Read a 2048 chunk from the input. 00100 // 00101 // The first two 16-bit integers should contain the values 1 and n, 00102 // where n is the number of "physical records" in the current "logical 00103 // record." (If the first value is not 1, then the chunk is rejected 00104 // and a new one read until the first 16-bit value is 1.) These two 00105 // values are not part of the reconstituted "logical record." 00106 // 00107 // 2. The next 32-bit integer contains the length of the "logical 00108 // record" in 16-bit words. The buffer is resized so that it can 00109 // contain the whole reconstituted "logical record." 00110 // 00111 // 3. The remainder of the chunk is copied to the buffer. 00112 // 00113 // 4. Successive chunks are read from the input. 00114 // 00115 // The chunks are copied into the buffer until the "logical record" 00116 // is complete. For "logical records" longer than 26620 byte, this is 00117 // not the whole story. Each "physical record" contains maximum of 13 00118 // chunks. When the first "physical record" of 13 chunks has been read, 00119 // the next chunk will be the first of the next "physical record." The 00120 // first two 16-bit integers will now be 2 and n, to indicate that this 00121 // is the second "physical record" of the sequence. These 4 bytes are 00122 // decoded and the rest of this chunk is copied to the buffer. And so 00123 // on... 00124 // 00125 // An end-of-file condition on the input will cause record processing 00126 // to be declared complete. 00127 // </synopsis> 00128 // 00129 // <example> 00130 // To open and read a VLA archive data file 00131 // <code> 00132 // VLAArchiveInput *in; 00133 // Block <Char> *buff; 00134 // String fileName = " "; 00135 // String fileType = "tape"; 00136 // 00137 // if (fileType == String("tape")) { 00138 // in = new VLAArchiveInput(fileName.chars(), VLAArchiveInput::Tape); 00139 // } else { 00140 // in = new VLAArchiveInput(fileName.chars(), VLAArchiveInput::Disk); 00141 // } 00142 // 00143 // uInt record = 0; 00144 // for (buff=&(in->next()); in->atEnd()==False; buff=&(in->next()), record++) { 00145 // cout << "Record" << record << endl; 00146 // // process record pointed to by buff 00147 // } 00148 // </code> 00149 // 00150 // </example> 00151 // 00152 // <motivation> 00153 // </motivation> 00154 // 00155 // <todo asof=""> 00156 // <ol> 00157 // <li> Bulletproofing - check for realistic buffer size (<1e6) 00158 // <li> Bulletproofing - check newn and newm on each read 00159 // <li> What happens after a single end-of-file on a tape drive? 00160 // <li> Add record skipping 00161 // <li> Should it work with stdin? This is in place but not debugged. 00162 // </ol> 00163 // </todo> 00164 00165 class VLALogicalRecord 00166 { 00167 public: 00168 // Create an object that is not good for anything except that it can 00169 // be assigned to (using the assigment operator). 00170 VLALogicalRecord(); 00171 00172 // Create an object that reads its data from the specified VLAArchiveInput 00173 // object. The supplied pointer should be obtained from new and is "taken 00174 // over". Hence the user should not delete it. 00175 VLALogicalRecord(VLAArchiveInput* input); 00176 00177 // The copy constructor uses reference semantics 00178 VLALogicalRecord(const VLALogicalRecord& other); 00179 00180 // The destructor just cleans up. 00181 ~VLALogicalRecord(); 00182 00183 // The assignment operator uses reference semantics 00184 VLALogicalRecord& operator=(const VLALogicalRecord& other); 00185 00186 // This returns the reconstructed VLA archive record from the input 00187 // stream. This ByteSource has the data stored in memory, and hence is 00188 // seekable. Data read from this ByteSource will have the ModComp numeric 00189 // conversions applied. 00190 ByteSource& logicalRecord(); 00191 00192 // Reads the next logical record from the ByteSource. Returns False if there 00193 // was a problem assembling the next record. 00194 Bool read(); 00195 00196 // Returns True if this class is attached to a VLAArchiveInput object. 00197 Bool isValid() const; 00198 00199 // returns a reference to a class which can be used to interpret the data in 00200 // the Record Control Area of the current logical record. 00201 const VLARCA& RCA() const; 00202 00203 // returns a reference to a class which can be used to interpret the data in 00204 // the Subarray Data Area of the current logical record. 00205 const VLASDA& SDA() const; 00206 00207 // returns a reference to a class which can be used to interpret the data in 00208 // the Correlator Data Area of the current logical record. A logical record 00209 // can have have up to four correlator data areas and the argument is used to 00210 // specify which one you are interested in. And exception is thrown if the 00211 // input argument is greater than three. 00212 const VLACDA& CDA(uInt which) const; 00213 00214 // returns a reference to a class which can be used to interpret the data in 00215 // the Antenna Data Area (ADA) of the current logical record. A logical 00216 // record has one ADA for each antenna that contributed to the data in this 00217 // record and the argument is used to specify which one you are interested 00218 // in. And exception is thrown if the input argument is not less than the 00219 // number of antennas in this subarray. 00220 const VLAADA& ADA(uInt which) const; 00221 00222 // Return the polarisations of the data in the specified CDA. This 00223 // information is obtained from knowing what the correlator modes represent 00224 // and checking the IF transfer switch for the specified antennas. 00225 Vector<Stokes::StokesTypes> polarisations(VLAEnum::CDA cda, 00226 uInt ant1=0, uInt ant2=0) const; 00227 00228 private: 00229 //# A pointer to a class which can read VLA Archives from a variety of 00230 //# sources 00231 CountedPtr<VLAArchiveInput> itsRecordPtr; 00232 00233 //# The class which can interpret the Record Control Area portion of the 00234 //# logical record. 00235 VLARCA itsRCA; 00236 00237 //# The class which can interpret the Subarray Data Area portion of the 00238 //# logical record. 00239 VLASDA itsSDA; 00240 00241 //# The class which can interpret the Array Data Area portions of the 00242 //# logical record. 00243 Block<VLAADA> itsADA; 00244 00245 //# The class which can interpret the Correlator Data Area portions of the 00246 //# logical record. 00247 Block<VLACDA> itsCDA; 00248 00249 }; 00250 #endif