| 1 | //
 | 
|---|
| 2 | // C++ Interface: MSWriter
 | 
|---|
| 3 | //
 | 
|---|
| 4 | // Description:
 | 
|---|
| 5 | //
 | 
|---|
| 6 | // This class is specific writer for MS format
 | 
|---|
| 7 | //
 | 
|---|
| 8 | // Takeshi Nakazato <takeshi.nakazato@nao.ac.jp>, (C) 2010
 | 
|---|
| 9 | //
 | 
|---|
| 10 | // Copyright: See COPYING file that comes with this distribution
 | 
|---|
| 11 | //
 | 
|---|
| 12 | //
 | 
|---|
| 13 | #include <assert.h>
 | 
|---|
| 14 | 
 | 
|---|
| 15 | #include <casa/OS/File.h>
 | 
|---|
| 16 | #include <casa/OS/RegularFile.h>
 | 
|---|
| 17 | #include <casa/OS/Directory.h>
 | 
|---|
| 18 | #include <casa/OS/SymLink.h>
 | 
|---|
| 19 | #include <casa/BasicSL/String.h>
 | 
|---|
| 20 | #include <casa/Arrays/Cube.h>
 | 
|---|
| 21 | 
 | 
|---|
| 22 | #include <tables/Tables/ExprNode.h>
 | 
|---|
| 23 | #include <tables/Tables/TableDesc.h>
 | 
|---|
| 24 | #include <tables/Tables/SetupNewTab.h>
 | 
|---|
| 25 | #include <tables/Tables/TableIter.h>
 | 
|---|
| 26 | #include <tables/Tables/RefRows.h>
 | 
|---|
| 27 | #include <tables/Tables/TableRow.h>
 | 
|---|
| 28 | 
 | 
|---|
| 29 | #include <ms/MeasurementSets/MeasurementSet.h>
 | 
|---|
| 30 | #include <ms/MeasurementSets/MSColumns.h>
 | 
|---|
| 31 | #include <ms/MeasurementSets/MSPolIndex.h>
 | 
|---|
| 32 | #include <ms/MeasurementSets/MSDataDescIndex.h>
 | 
|---|
| 33 | #include <ms/MeasurementSets/MSSourceIndex.h>
 | 
|---|
| 34 | 
 | 
|---|
| 35 | #include "MSWriter.h"
 | 
|---|
| 36 | #include "STHeader.h"
 | 
|---|
| 37 | #include "STFrequencies.h" 
 | 
|---|
| 38 | #include "STMolecules.h"
 | 
|---|
| 39 | #include "STTcal.h" 
 | 
|---|
| 40 | #include "MathUtils.h"
 | 
|---|
| 41 | #include "TableTraverse.h"
 | 
|---|
| 42 | 
 | 
|---|
| 43 | using namespace casa ;
 | 
|---|
| 44 | using namespace std ;
 | 
|---|
| 45 | 
 | 
|---|
| 46 | namespace asap {
 | 
|---|
| 47 | 
 | 
|---|
| 48 | class PolarizedComponentHolder {
 | 
|---|
| 49 | public:
 | 
|---|
| 50 |   PolarizedComponentHolder()
 | 
|---|
| 51 |     : nchan(0),
 | 
|---|
| 52 |       maxnpol(4)
 | 
|---|
| 53 |   {
 | 
|---|
| 54 |     reset() ;
 | 
|---|
| 55 |   }
 | 
|---|
| 56 |   PolarizedComponentHolder( uInt n )
 | 
|---|
| 57 |     : nchan(n),
 | 
|---|
| 58 |       maxnpol(4)
 | 
|---|
| 59 |   {
 | 
|---|
| 60 |     reset() ;
 | 
|---|
| 61 |   }
 | 
|---|
| 62 | 
 | 
|---|
| 63 |   void reset()
 | 
|---|
| 64 |   {
 | 
|---|
| 65 |     npol = 0 ;
 | 
|---|
| 66 |     data.clear() ;
 | 
|---|
| 67 |     flag.clear() ;
 | 
|---|
| 68 |     flagrow = False ;
 | 
|---|
| 69 |     polnos.resize() ;
 | 
|---|
| 70 |   }
 | 
|---|
| 71 | 
 | 
|---|
| 72 |   void accumulate( uInt id, Vector<Float> sp, Vector<Bool> fl, Bool flr )
 | 
|---|
| 73 |   {
 | 
|---|
| 74 |     map< uInt,Vector<Float> >::iterator itr = data.find( id ) ;
 | 
|---|
| 75 |     if ( id < maxnpol && itr == data.end() ) {
 | 
|---|
| 76 |       addPol( id ) ;
 | 
|---|
| 77 |       accumulateData( id, sp ) ;
 | 
|---|
| 78 |       accumulateFlag( id, fl ) ;
 | 
|---|
| 79 |       accumulateFlagRow( flr ) ;
 | 
|---|
| 80 |       npol++ ;
 | 
|---|
| 81 |     }
 | 
|---|
| 82 |   } 
 | 
|---|
| 83 | 
 | 
|---|
| 84 |   void setNchan( uInt n ) { nchan = n ; } 
 | 
|---|
| 85 |   uInt nPol() { return npol ; } 
 | 
|---|
| 86 |   uInt nChan() { return nchan ; }
 | 
|---|
| 87 |   Vector<uInt> polNos() { return polnos ; }
 | 
|---|
| 88 |   Vector<Float> getWeight() { return Vector<Float>( npol, 1.0 ) ; }
 | 
|---|
| 89 |   Vector<Float> getSigma() { return Vector<Float>( npol, 1.0 ) ; }
 | 
|---|
| 90 |   Bool getFlagRow() { return flagrow ; }
 | 
|---|
| 91 |   Cube<Bool> getFlagCategory() { return Cube<Bool>( npol, nchan, 1, False ) ; }
 | 
|---|
| 92 |   Matrix<Float> getData() 
 | 
|---|
| 93 |   {
 | 
|---|
| 94 |     Matrix<Float> v( npol, nchan ) ;
 | 
|---|
| 95 |     for ( map< uInt,Vector<Float> >::iterator i = data.begin() ; i != data.end() ; i++ ) {
 | 
|---|
| 96 |       v.row( i->first ) =  i->second ;
 | 
|---|
| 97 |     }
 | 
|---|
| 98 |     return v ;
 | 
|---|
| 99 |   }
 | 
|---|
| 100 |   Matrix<Bool> getFlag() 
 | 
|---|
| 101 |   { 
 | 
|---|
| 102 |     Matrix<Bool> v( npol, nchan ) ;
 | 
|---|
| 103 |     for ( map< uInt,Vector<Bool> >::iterator i = flag.begin() ; i != flag.end() ; i++ ) {
 | 
|---|
| 104 |       v.row( i->first ) = i->second ;
 | 
|---|
| 105 |     }
 | 
|---|
| 106 |     return v ;
 | 
|---|
| 107 |   }
 | 
|---|
| 108 |   Matrix<Complex> getComplexData()
 | 
|---|
| 109 |   {
 | 
|---|
| 110 |     Matrix<Complex> v( npol, nchan ) ;
 | 
|---|
| 111 |     Matrix<Float> dummy( 2, nchan, 0.0 ) ;
 | 
|---|
| 112 |     map< uInt,Vector<Float> >::iterator itr0 = data.find( 0 ) ;
 | 
|---|
| 113 |     map< uInt,Vector<Float> >::iterator itr1 = data.find( 1 ) ;
 | 
|---|
| 114 |     if ( itr0 != data.end() ) {
 | 
|---|
| 115 |       dummy.row( 0 ) = itr0->second ;
 | 
|---|
| 116 |       v.row( 0 ) = RealToComplex( dummy ) ;
 | 
|---|
| 117 |     }
 | 
|---|
| 118 |     if ( itr1 != data.end() ) {
 | 
|---|
| 119 |       dummy.row( 0 ) = itr1->second ;
 | 
|---|
| 120 |       v.row( npol-1 ) = RealToComplex( dummy ) ;
 | 
|---|
| 121 |     }
 | 
|---|
| 122 |     itr0 = data.find( 2 ) ;
 | 
|---|
| 123 |     itr1 = data.find( 3 ) ;
 | 
|---|
| 124 |     if ( itr0 != data.end() && itr1 != data.end() ) {
 | 
|---|
| 125 |       dummy.row( 0 ) = itr0->second ;
 | 
|---|
| 126 |       dummy.row( 1 ) = itr1->second ;
 | 
|---|
| 127 |       v.row( 1 ) = RealToComplex( dummy ) ;
 | 
|---|
| 128 |       v.row( 2 ) = conj( v.row( 1 ) ) ;
 | 
|---|
| 129 |     }
 | 
|---|
| 130 |     return v ;
 | 
|---|
| 131 |   }
 | 
|---|
| 132 | 
 | 
|---|
| 133 |   Matrix<Bool> getComplexFlag()
 | 
|---|
| 134 |   {
 | 
|---|
| 135 |     Matrix<Bool> tmp = getFlag() ;
 | 
|---|
| 136 |     Matrix<Bool> v( npol, nchan ) ;
 | 
|---|
| 137 |     v.row( 0 ) = tmp.row( 0 ) ;
 | 
|---|
| 138 |     if ( npol == 2 ) {
 | 
|---|
| 139 |       v.row( npol-1 ) = tmp.row( 1 ) ;
 | 
|---|
| 140 |     }
 | 
|---|
| 141 |     else if ( npol > 2 ) {
 | 
|---|
| 142 |       v.row( npol-1 ) = tmp.row( 1 ) ;
 | 
|---|
| 143 |       v.row( 1 ) = tmp.row( 2 ) || tmp.row( 3 ) ;
 | 
|---|
| 144 |       v.row( 2 ) = v.row( 1 ) ;
 | 
|---|
| 145 |     }
 | 
|---|
| 146 |     return v ;
 | 
|---|
| 147 |   }
 | 
|---|
| 148 |   
 | 
|---|
| 149 | private:
 | 
|---|
| 150 |   void accumulateData( uInt &id, Vector<Float> &v ) 
 | 
|---|
| 151 |   {
 | 
|---|
| 152 |     data.insert( pair< uInt,Vector<Float> >( id, v ) ) ;
 | 
|---|
| 153 |   }
 | 
|---|
| 154 |     void accumulateFlag( uInt &id, Vector<Bool> &v )
 | 
|---|
| 155 |   {
 | 
|---|
| 156 |     flag.insert( pair< uInt,Vector<Bool> >( id, v ) ) ;
 | 
|---|
| 157 |   }
 | 
|---|
| 158 |   void accumulateFlagRow( Bool &v )
 | 
|---|
| 159 |   {
 | 
|---|
| 160 |     flagrow |= v ;
 | 
|---|
| 161 |   }
 | 
|---|
| 162 |   void addPol( uInt id ) 
 | 
|---|
| 163 |   {
 | 
|---|
| 164 |     uInt i = polnos.nelements() ;
 | 
|---|
| 165 |     polnos.resize( i+1, True ) ;
 | 
|---|
| 166 |     polnos[i] = id ;
 | 
|---|
| 167 |   }
 | 
|---|
| 168 | 
 | 
|---|
| 169 |   uInt nchan;
 | 
|---|
| 170 |   const uInt maxnpol;
 | 
|---|
| 171 |   uInt npol;
 | 
|---|
| 172 |   Vector<uInt> polnos;
 | 
|---|
| 173 | 
 | 
|---|
| 174 |   map< uInt,Vector<Float> > data;
 | 
|---|
| 175 |   map< uInt,Vector<Bool> > flag;
 | 
|---|
| 176 |   Bool flagrow;
 | 
|---|
| 177 | };
 | 
|---|
| 178 | 
 | 
|---|
| 179 | class BaseMSWriterVisitor: public TableVisitor {
 | 
|---|
| 180 |   const String *lastFieldName;
 | 
|---|
| 181 |   uInt lastRecordNo;
 | 
|---|
| 182 |   uInt lastBeamNo, lastScanNo, lastIfNo;
 | 
|---|
| 183 |   Int lastSrcType;
 | 
|---|
| 184 |   uInt lastCycleNo;
 | 
|---|
| 185 |   Double lastTime;
 | 
|---|
| 186 |   Int lastPolNo;
 | 
|---|
| 187 | protected:
 | 
|---|
| 188 |   const Table &table;
 | 
|---|
| 189 |   uInt count;
 | 
|---|
| 190 | public:
 | 
|---|
| 191 |   BaseMSWriterVisitor(const Table &table)
 | 
|---|
| 192 |     : table(table)
 | 
|---|
| 193 |   {
 | 
|---|
| 194 |     static const String dummy;
 | 
|---|
| 195 |     lastFieldName = &dummy;
 | 
|---|
| 196 |     count = 0;
 | 
|---|
| 197 |   }
 | 
|---|
| 198 |   
 | 
|---|
| 199 |   virtual void enterFieldName(const uInt recordNo, const String &columnValue) {
 | 
|---|
| 200 |   }
 | 
|---|
| 201 |   virtual void leaveFieldName(const uInt recordNo, const String &columnValue) {
 | 
|---|
| 202 |   }
 | 
|---|
| 203 |   virtual void enterBeamNo(const uInt recordNo, uInt columnValue) { }
 | 
|---|
| 204 |   virtual void leaveBeamNo(const uInt recordNo, uInt columnValue) { }
 | 
|---|
| 205 |   virtual void enterScanNo(const uInt recordNo, uInt columnValue) { }
 | 
|---|
| 206 |   virtual void leaveScanNo(const uInt recordNo, uInt columnValue) { }
 | 
|---|
| 207 |   virtual void enterIfNo(const uInt recordNo, uInt columnValue) { }
 | 
|---|
| 208 |   virtual void leaveIfNo(const uInt recordNo, uInt columnValue) { }
 | 
|---|
| 209 |   virtual void enterSrcType(const uInt recordNo, Int columnValue) { }
 | 
|---|
| 210 |   virtual void leaveSrcType(const uInt recordNo, Int columnValue) { }
 | 
|---|
| 211 |   virtual void enterCycleNo(const uInt recordNo, uInt columnValue) { }
 | 
|---|
| 212 |   virtual void leaveCycleNo(const uInt recordNo, uInt columnValue) { }
 | 
|---|
| 213 |   virtual void enterTime(const uInt recordNo, Double columnValue) { }
 | 
|---|
| 214 |   virtual void leaveTime(const uInt recordNo, Double columnValue) { }
 | 
|---|
| 215 |   virtual void enterPolNo(const uInt recordNo, uInt columnValue) { }
 | 
|---|
| 216 |   virtual void leavePolNo(const uInt recordNo, uInt columnValue) { }
 | 
|---|
| 217 | 
 | 
|---|
| 218 |   virtual Bool visitRecord(const uInt recordNo,
 | 
|---|
| 219 |                            const String &fieldName,
 | 
|---|
| 220 |                            const uInt beamNo,
 | 
|---|
| 221 |                            const uInt scanNo,
 | 
|---|
| 222 |                            const uInt ifNo,
 | 
|---|
| 223 |                            const Int srcType,
 | 
|---|
| 224 |                            const uInt cycleNo,
 | 
|---|
| 225 |                            const Double time,
 | 
|---|
| 226 |                            const uInt polNo) { return True ;}
 | 
|---|
| 227 | 
 | 
|---|
| 228 |   virtual Bool visit(Bool isFirst, const uInt recordNo,
 | 
|---|
| 229 |                      const uInt nCols, void const *const colValues[]) {
 | 
|---|
| 230 |     const String *fieldName = NULL;
 | 
|---|
| 231 |     uInt beamNo, scanNo, ifNo;
 | 
|---|
| 232 |     Int srcType;
 | 
|---|
| 233 |     uInt cycleNo;
 | 
|---|
| 234 |     Double time;
 | 
|---|
| 235 |     Int polNo;
 | 
|---|
| 236 |     { // prologue
 | 
|---|
| 237 |       uInt i = 0;
 | 
|---|
| 238 |       {
 | 
|---|
| 239 |         const String *col = (const String*)colValues[i++];
 | 
|---|
| 240 |         fieldName = &col[recordNo];
 | 
|---|
| 241 |       }
 | 
|---|
| 242 |       {
 | 
|---|
| 243 |         const uInt *col = (const uInt *)colValues[i++];
 | 
|---|
| 244 |         beamNo = col[recordNo];
 | 
|---|
| 245 |       }
 | 
|---|
| 246 |       {
 | 
|---|
| 247 |         const uInt *col = (const uInt *)colValues[i++];
 | 
|---|
| 248 |         scanNo = col[recordNo];
 | 
|---|
| 249 |       }
 | 
|---|
| 250 |       {
 | 
|---|
| 251 |         const uInt *col = (const uInt *)colValues[i++];
 | 
|---|
| 252 |         ifNo = col[recordNo];
 | 
|---|
| 253 |       }
 | 
|---|
| 254 |       {
 | 
|---|
| 255 |         const Int *col = (const Int *)colValues[i++];
 | 
|---|
| 256 |         srcType = col[recordNo];
 | 
|---|
| 257 |       }
 | 
|---|
| 258 |       {
 | 
|---|
| 259 |         const uInt *col = (const uInt *)colValues[i++];
 | 
|---|
| 260 |         cycleNo = col[recordNo];
 | 
|---|
| 261 |       }
 | 
|---|
| 262 |       {
 | 
|---|
| 263 |         const Double *col = (const Double *)colValues[i++];
 | 
|---|
| 264 |         time = col[recordNo];
 | 
|---|
| 265 |       }
 | 
|---|
| 266 |       {
 | 
|---|
| 267 |         const Int *col = (const Int *)colValues[i++];
 | 
|---|
| 268 |         polNo = col[recordNo];
 | 
|---|
| 269 |       }
 | 
|---|
| 270 |       assert(nCols == i);
 | 
|---|
| 271 |     }
 | 
|---|
| 272 | 
 | 
|---|
| 273 |     if (isFirst) {
 | 
|---|
| 274 |       enterFieldName(recordNo, *fieldName);
 | 
|---|
| 275 |       enterBeamNo(recordNo, beamNo);
 | 
|---|
| 276 |       enterScanNo(recordNo, scanNo);
 | 
|---|
| 277 |       enterIfNo(recordNo, ifNo);
 | 
|---|
| 278 |       enterSrcType(recordNo, srcType);
 | 
|---|
| 279 |       enterCycleNo(recordNo, cycleNo);
 | 
|---|
| 280 |       enterTime(recordNo, time);
 | 
|---|
| 281 |       enterPolNo(recordNo, polNo);
 | 
|---|
| 282 |     } else {
 | 
|---|
| 283 |       if (lastFieldName->compare(*fieldName) != 0) {
 | 
|---|
| 284 |         leavePolNo(lastRecordNo, lastPolNo);
 | 
|---|
| 285 |         leaveTime(lastRecordNo, lastTime);
 | 
|---|
| 286 |         leaveCycleNo(lastRecordNo, lastCycleNo);
 | 
|---|
| 287 |         leaveSrcType(lastRecordNo, lastSrcType);
 | 
|---|
| 288 |         leaveIfNo(lastRecordNo, lastIfNo);
 | 
|---|
| 289 |         leaveScanNo(lastRecordNo, lastScanNo);
 | 
|---|
| 290 |         leaveBeamNo(lastRecordNo, lastBeamNo);
 | 
|---|
| 291 |         leaveFieldName(lastRecordNo, *lastFieldName);
 | 
|---|
| 292 | 
 | 
|---|
| 293 |         enterFieldName(recordNo, *fieldName);
 | 
|---|
| 294 |         enterBeamNo(recordNo, beamNo);
 | 
|---|
| 295 |         enterScanNo(recordNo, scanNo);
 | 
|---|
| 296 |         enterIfNo(recordNo, ifNo);
 | 
|---|
| 297 |         enterSrcType(recordNo, srcType);
 | 
|---|
| 298 |         enterCycleNo(recordNo, cycleNo);
 | 
|---|
| 299 |         enterTime(recordNo, time);
 | 
|---|
| 300 |         enterPolNo(recordNo, polNo);
 | 
|---|
| 301 |       } else if (lastBeamNo != beamNo) {
 | 
|---|
| 302 |         leavePolNo(lastRecordNo, lastPolNo);
 | 
|---|
| 303 |         leaveTime(lastRecordNo, lastTime);
 | 
|---|
| 304 |         leaveCycleNo(lastRecordNo, lastCycleNo);
 | 
|---|
| 305 |         leaveSrcType(lastRecordNo, lastSrcType);
 | 
|---|
| 306 |         leaveIfNo(lastRecordNo, lastIfNo);
 | 
|---|
| 307 |         leaveScanNo(lastRecordNo, lastScanNo);
 | 
|---|
| 308 |         leaveBeamNo(lastRecordNo, lastBeamNo);
 | 
|---|
| 309 | 
 | 
|---|
| 310 |         enterBeamNo(recordNo, beamNo);
 | 
|---|
| 311 |         enterScanNo(recordNo, scanNo);
 | 
|---|
| 312 |         enterIfNo(recordNo, ifNo);
 | 
|---|
| 313 |         enterSrcType(recordNo, srcType);
 | 
|---|
| 314 |         enterCycleNo(recordNo, cycleNo);
 | 
|---|
| 315 |         enterTime(recordNo, time);
 | 
|---|
| 316 |         enterPolNo(recordNo, polNo);
 | 
|---|
| 317 |       } else if (lastScanNo != scanNo) {
 | 
|---|
| 318 |         leavePolNo(lastRecordNo, lastPolNo);
 | 
|---|
| 319 |         leaveTime(lastRecordNo, lastTime);
 | 
|---|
| 320 |         leaveCycleNo(lastRecordNo, lastCycleNo);
 | 
|---|
| 321 |         leaveSrcType(lastRecordNo, lastSrcType);
 | 
|---|
| 322 |         leaveIfNo(lastRecordNo, lastIfNo);
 | 
|---|
| 323 |         leaveScanNo(lastRecordNo, lastScanNo);
 | 
|---|
| 324 | 
 | 
|---|
| 325 |         enterScanNo(recordNo, scanNo);
 | 
|---|
| 326 |         enterIfNo(recordNo, ifNo);
 | 
|---|
| 327 |         enterSrcType(recordNo, srcType);
 | 
|---|
| 328 |         enterCycleNo(recordNo, cycleNo);
 | 
|---|
| 329 |         enterTime(recordNo, time);
 | 
|---|
| 330 |         enterPolNo(recordNo, polNo);
 | 
|---|
| 331 |       } else if (lastIfNo != ifNo) {
 | 
|---|
| 332 |         leavePolNo(lastRecordNo, lastPolNo);
 | 
|---|
| 333 |         leaveTime(lastRecordNo, lastTime);
 | 
|---|
| 334 |         leaveCycleNo(lastRecordNo, lastCycleNo);
 | 
|---|
| 335 |         leaveSrcType(lastRecordNo, lastSrcType);
 | 
|---|
| 336 |         leaveIfNo(lastRecordNo, lastIfNo);
 | 
|---|
| 337 | 
 | 
|---|
| 338 |         enterIfNo(recordNo, ifNo);
 | 
|---|
| 339 |         enterSrcType(recordNo, srcType);
 | 
|---|
| 340 |         enterCycleNo(recordNo, cycleNo);
 | 
|---|
| 341 |         enterTime(recordNo, time);
 | 
|---|
| 342 |         enterPolNo(recordNo, polNo);
 | 
|---|
| 343 |       } else if (lastSrcType != srcType) {
 | 
|---|
| 344 |         leavePolNo(lastRecordNo, lastPolNo);
 | 
|---|
| 345 |         leaveTime(lastRecordNo, lastTime);
 | 
|---|
| 346 |         leaveCycleNo(lastRecordNo, lastCycleNo);
 | 
|---|
| 347 |         leaveSrcType(lastRecordNo, lastSrcType);
 | 
|---|
| 348 | 
 | 
|---|
| 349 |         enterSrcType(recordNo, srcType);
 | 
|---|
| 350 |         enterCycleNo(recordNo, cycleNo);
 | 
|---|
| 351 |         enterTime(recordNo, time);
 | 
|---|
| 352 |         enterPolNo(recordNo, polNo);
 | 
|---|
| 353 |       } else if (lastCycleNo != cycleNo) {
 | 
|---|
| 354 |         leavePolNo(lastRecordNo, lastPolNo);
 | 
|---|
| 355 |         leaveTime(lastRecordNo, lastTime);
 | 
|---|
| 356 |         leaveCycleNo(lastRecordNo, lastCycleNo);
 | 
|---|
| 357 | 
 | 
|---|
| 358 |         enterCycleNo(recordNo, cycleNo);
 | 
|---|
| 359 |         enterTime(recordNo, time);
 | 
|---|
| 360 |         enterPolNo(recordNo, polNo);
 | 
|---|
| 361 |       } else if (lastTime != time) {
 | 
|---|
| 362 |         leavePolNo(lastRecordNo, lastPolNo);
 | 
|---|
| 363 |         leaveTime(lastRecordNo, lastTime);
 | 
|---|
| 364 | 
 | 
|---|
| 365 |         enterTime(recordNo, time);
 | 
|---|
| 366 |         enterPolNo(recordNo, polNo);
 | 
|---|
| 367 |       } else if (lastPolNo != polNo) {
 | 
|---|
| 368 |         leavePolNo(lastRecordNo, lastPolNo);
 | 
|---|
| 369 |         enterPolNo(recordNo, polNo);
 | 
|---|
| 370 |       }
 | 
|---|
| 371 |     }
 | 
|---|
| 372 |     count++;
 | 
|---|
| 373 |     Bool result = visitRecord(recordNo, *fieldName, beamNo, scanNo, ifNo, srcType,
 | 
|---|
| 374 |                               cycleNo, time, polNo);
 | 
|---|
| 375 | 
 | 
|---|
| 376 |     { // epilogue
 | 
|---|
| 377 |       lastRecordNo = recordNo;
 | 
|---|
| 378 | 
 | 
|---|
| 379 |       lastFieldName = fieldName;
 | 
|---|
| 380 |       lastBeamNo = beamNo;
 | 
|---|
| 381 |       lastScanNo = scanNo;
 | 
|---|
| 382 |       lastIfNo = ifNo;
 | 
|---|
| 383 |       lastSrcType = srcType;
 | 
|---|
| 384 |       lastCycleNo = cycleNo;
 | 
|---|
| 385 |       lastTime = time;
 | 
|---|
| 386 |       lastPolNo = polNo;
 | 
|---|
| 387 |     }
 | 
|---|
| 388 |     return result ;
 | 
|---|
| 389 |   }
 | 
|---|
| 390 | 
 | 
|---|
| 391 |   virtual void finish() {
 | 
|---|
| 392 |     if (count > 0) {
 | 
|---|
| 393 |       leavePolNo(lastRecordNo, lastPolNo);
 | 
|---|
| 394 |       leaveTime(lastRecordNo, lastTime);
 | 
|---|
| 395 |       leaveCycleNo(lastRecordNo, lastCycleNo);
 | 
|---|
| 396 |       leaveSrcType(lastRecordNo, lastSrcType);
 | 
|---|
| 397 |       leaveIfNo(lastRecordNo, lastIfNo);
 | 
|---|
| 398 |       leaveScanNo(lastRecordNo, lastScanNo);
 | 
|---|
| 399 |       leaveBeamNo(lastRecordNo, lastBeamNo);
 | 
|---|
| 400 |       leaveFieldName(lastRecordNo, *lastFieldName);
 | 
|---|
| 401 |     }
 | 
|---|
| 402 |   }
 | 
|---|
| 403 | };
 | 
|---|
| 404 | 
 | 
|---|
| 405 | class MSWriterVisitor: public BaseMSWriterVisitor, public MSWriterUtils {
 | 
|---|
| 406 | public:
 | 
|---|
| 407 |   MSWriterVisitor(const Table &table, Table &mstable)
 | 
|---|
| 408 |     : BaseMSWriterVisitor(table),
 | 
|---|
| 409 |       ms(mstable)
 | 
|---|
| 410 |   { 
 | 
|---|
| 411 |     rowidx = 0 ;
 | 
|---|
| 412 |     fieldName = "" ;
 | 
|---|
| 413 |     defaultFieldId = 0 ;
 | 
|---|
| 414 |     spwId = -1 ;
 | 
|---|
| 415 |     subscan = 1 ;
 | 
|---|
| 416 |     ptName = "" ;
 | 
|---|
| 417 |     srcId = 0 ;
 | 
|---|
| 418 |     
 | 
|---|
| 419 |     row = TableRow( ms ) ;
 | 
|---|
| 420 | 
 | 
|---|
| 421 |     holder.reset() ;
 | 
|---|
| 422 | 
 | 
|---|
| 423 |     makePolMap() ;
 | 
|---|
| 424 |     initFrequencies() ;
 | 
|---|
| 425 |     initTcal() ;
 | 
|---|
| 426 | 
 | 
|---|
| 427 |     //
 | 
|---|
| 428 |     // add rows to MS
 | 
|---|
| 429 |     //
 | 
|---|
| 430 |     uInt addrow = table.nrow() ;
 | 
|---|
| 431 |     ms.addRow( addrow ) ;
 | 
|---|
| 432 | 
 | 
|---|
| 433 |     // attach to Scantable columns
 | 
|---|
| 434 |     spectraCol.attach( table, "SPECTRA" ) ;
 | 
|---|
| 435 |     flagtraCol.attach( table, "FLAGTRA" ) ;
 | 
|---|
| 436 |     flagRowCol.attach( table, "FLAGROW" ) ;
 | 
|---|
| 437 |     tcalIdCol.attach( table, "TCAL_ID" ) ;
 | 
|---|
| 438 |     intervalCol.attach( table, "INTERVAL" ) ;
 | 
|---|
| 439 |     directionCol.attach( table, "DIRECTION" ) ;
 | 
|---|
| 440 |     scanRateCol.attach( table, "SCANRATE" ) ;
 | 
|---|
| 441 |     timeCol.attach( table, "TIME" ) ;
 | 
|---|
| 442 |     freqIdCol.attach( table, "FREQ_ID" ) ;
 | 
|---|
| 443 |     sourceNameCol.attach( table, "SRCNAME" ) ;
 | 
|---|
| 444 |     sourceDirectionCol.attach( table, "SRCDIRECTION" ) ;
 | 
|---|
| 445 |     fieldNameCol.attach( table, "FIELDNAME" ) ;
 | 
|---|
| 446 | 
 | 
|---|
| 447 |     // MS subtables
 | 
|---|
| 448 |     attachSubtables() ;
 | 
|---|
| 449 | 
 | 
|---|
| 450 |     // attach to MS columns
 | 
|---|
| 451 |     attachMain() ;
 | 
|---|
| 452 |     attachPointing() ;
 | 
|---|
| 453 |   }
 | 
|---|
| 454 |   
 | 
|---|
| 455 |   virtual void enterFieldName(const uInt recordNo, const String &columnValue) {
 | 
|---|
| 456 |     //printf("%u: FieldName: %s\n", recordNo, columnValue.c_str());
 | 
|---|
| 457 |     fieldName = fieldNameCol.asString( recordNo ) ;
 | 
|---|
| 458 |     String::size_type pos = fieldName.find( "__" ) ;
 | 
|---|
| 459 |     if ( pos != String::npos ) {
 | 
|---|
| 460 |       fieldId = String::toInt( fieldName.substr( pos+2 ) ) ;
 | 
|---|
| 461 |       fieldName = fieldName.substr( 0, pos ) ;
 | 
|---|
| 462 |     }
 | 
|---|
| 463 |     else {
 | 
|---|
| 464 |       fieldId = defaultFieldId ;
 | 
|---|
| 465 |       defaultFieldId++ ;
 | 
|---|
| 466 |     }
 | 
|---|
| 467 |     Double tSec = timeCol.asdouble( recordNo ) * 86400.0 ;
 | 
|---|
| 468 |     Vector<Double> srcDir = sourceDirectionCol( recordNo ) ;
 | 
|---|
| 469 |     Vector<Double> srate = scanRateCol( recordNo ) ;
 | 
|---|
| 470 |     String srcName = sourceNameCol.asString( recordNo ) ;
 | 
|---|
| 471 | 
 | 
|---|
| 472 |     addField( fieldId, fieldName, srcName, srcDir, srate, tSec ) ;
 | 
|---|
| 473 | 
 | 
|---|
| 474 |     // put value
 | 
|---|
| 475 |     *fieldIdRF = fieldId ;
 | 
|---|
| 476 |   }
 | 
|---|
| 477 |   virtual void leaveFieldName(const uInt recordNo, const String &columnValue) {
 | 
|---|
| 478 |   }
 | 
|---|
| 479 |   virtual void enterBeamNo(const uInt recordNo, uInt columnValue) {
 | 
|---|
| 480 |     //printf("%u: BeamNo: %u\n", recordNo, columnValue);
 | 
|---|
| 481 |     
 | 
|---|
| 482 |     feedId = (Int)columnValue ;
 | 
|---|
| 483 | 
 | 
|---|
| 484 |     // put value
 | 
|---|
| 485 |     *feed1RF = feedId ;
 | 
|---|
| 486 |     *feed2RF = feedId ;
 | 
|---|
| 487 |   }
 | 
|---|
| 488 |   virtual void leaveBeamNo(const uInt recordNo, uInt columnValue) {
 | 
|---|
| 489 |   }
 | 
|---|
| 490 |   virtual void enterScanNo(const uInt recordNo, uInt columnValue) {
 | 
|---|
| 491 |     //printf("%u: ScanNo: %u\n", recordNo, columnValue);
 | 
|---|
| 492 | 
 | 
|---|
| 493 |     // put value 
 | 
|---|
| 494 |     // SCAN_NUMBER is 0-based in Scantable while 1-based in MS
 | 
|---|
| 495 |     *scanNumberRF = (Int)columnValue + 1 ;
 | 
|---|
| 496 |   }
 | 
|---|
| 497 |   virtual void leaveScanNo(const uInt recordNo, uInt columnValue) {
 | 
|---|
| 498 |     subscan = 1 ;
 | 
|---|
| 499 |   }
 | 
|---|
| 500 |   virtual void enterIfNo(const uInt recordNo, uInt columnValue) {
 | 
|---|
| 501 |     //printf("%u: IfNo: %u\n", recordNo, columnValue);
 | 
|---|
| 502 | 
 | 
|---|
| 503 |     spwId = (Int)columnValue ;
 | 
|---|
| 504 |     uInt freqId = freqIdCol.asuInt( recordNo ) ;
 | 
|---|
| 505 | 
 | 
|---|
| 506 |     Vector<Float> sp = spectraCol( recordNo ) ;
 | 
|---|
| 507 |     uInt nchan = sp.nelements() ;
 | 
|---|
| 508 |     holder.setNchan( nchan ) ;
 | 
|---|
| 509 | 
 | 
|---|
| 510 |     addSpectralWindow( spwId, freqId ) ;
 | 
|---|
| 511 | 
 | 
|---|
| 512 |     addFeed( feedId, spwId ) ;
 | 
|---|
| 513 |   }
 | 
|---|
| 514 |   virtual void leaveIfNo(const uInt recordNo, uInt columnValue) {
 | 
|---|
| 515 |   }
 | 
|---|
| 516 |   virtual void enterSrcType(const uInt recordNo, Int columnValue) {
 | 
|---|
| 517 |     //printf("%u: SrcType: %d\n", recordNo, columnValue);
 | 
|---|
| 518 | 
 | 
|---|
| 519 |     Int stateId = addState( columnValue ) ;
 | 
|---|
| 520 | 
 | 
|---|
| 521 |     // put value
 | 
|---|
| 522 |     *stateIdRF = stateId ;
 | 
|---|
| 523 |   }
 | 
|---|
| 524 |   virtual void leaveSrcType(const uInt recordNo, Int columnValue) {
 | 
|---|
| 525 |   }
 | 
|---|
| 526 |   virtual void enterCycleNo(const uInt recordNo, uInt columnValue) {
 | 
|---|
| 527 |     //printf("%u: CycleNo: %u\n", recordNo, columnValue);
 | 
|---|
| 528 |   }
 | 
|---|
| 529 |   virtual void leaveCycleNo(const uInt recordNo, uInt columnValue) {
 | 
|---|
| 530 |   }
 | 
|---|
| 531 |   virtual void enterTime(const uInt recordNo, Double columnValue) {
 | 
|---|
| 532 |     //printf("%u: Time: %f\n", recordNo, columnValue);
 | 
|---|
| 533 | 
 | 
|---|
| 534 |     Double timeSec = columnValue * 86400.0 ;
 | 
|---|
| 535 |     Double interval = intervalCol.asdouble( recordNo ) ;
 | 
|---|
| 536 | 
 | 
|---|
| 537 |     if ( ptName.empty() ) {
 | 
|---|
| 538 |       Vector<Double> dir = directionCol( recordNo ) ;
 | 
|---|
| 539 |       Vector<Double> rate = scanRateCol( recordNo ) ;
 | 
|---|
| 540 |       if ( anyNE( rate, 0.0 ) ) {
 | 
|---|
| 541 |         Matrix<Double> msdir( 2, 2 ) ;
 | 
|---|
| 542 |         msdir.column( 0 ) = dir ;
 | 
|---|
| 543 |         msdir.column( 1 ) = rate ;
 | 
|---|
| 544 |         addPointing( timeSec, interval, msdir ) ;
 | 
|---|
| 545 |       }
 | 
|---|
| 546 |       else {
 | 
|---|
| 547 |         Matrix<Double> msdir( 2, 1 ) ;
 | 
|---|
| 548 |         msdir.column( 0 ) = dir ;
 | 
|---|
| 549 |         addPointing( timeSec, interval, msdir ) ;
 | 
|---|
| 550 |       }
 | 
|---|
| 551 |     }
 | 
|---|
| 552 | 
 | 
|---|
| 553 |     // put value
 | 
|---|
| 554 |     *timeRF = timeSec ;
 | 
|---|
| 555 |     *timeCentroidRF = timeSec ;
 | 
|---|
| 556 |     *intervalRF = interval ;
 | 
|---|
| 557 |     *exposureRF = interval ;
 | 
|---|
| 558 |   }
 | 
|---|
| 559 |   virtual void leaveTime(const uInt recordNo, Double columnValue) {
 | 
|---|
| 560 |     if ( holder.nPol() > 0 ) {
 | 
|---|
| 561 |       Vector<Float> w = holder.getWeight() ;
 | 
|---|
| 562 |       Cube<Bool> c = holder.getFlagCategory() ;
 | 
|---|
| 563 |       Bool flr = holder.getFlagRow() ;
 | 
|---|
| 564 |       Matrix<Bool> fl = holder.getFlag() ;
 | 
|---|
| 565 |       Vector<uInt> polnos = holder.polNos() ;
 | 
|---|
| 566 |       Int polId = addPolarization( polnos ) ;
 | 
|---|
| 567 |       Int ddId = addDataDescription( polId, spwId ) ;
 | 
|---|
| 568 |        
 | 
|---|
| 569 |       // put field
 | 
|---|
| 570 |       *dataDescIdRF = ddId ;
 | 
|---|
| 571 |       *flagRowRF = flr ;
 | 
|---|
| 572 |       weightRF.define( w ) ;
 | 
|---|
| 573 |       sigmaRF.define( w ) ;
 | 
|---|
| 574 |       flagCategoryRF.define( c ) ;
 | 
|---|
| 575 |       flagRF.define( fl ) ;
 | 
|---|
| 576 |       if ( useFloat ) {
 | 
|---|
| 577 |         Matrix<Float> sp = holder.getData() ;
 | 
|---|
| 578 |         floatDataRF.define( sp ) ;
 | 
|---|
| 579 |       }
 | 
|---|
| 580 |       else {
 | 
|---|
| 581 |         Matrix<Complex> sp = holder.getComplexData() ;
 | 
|---|
| 582 |         dataRF.define( sp ) ;
 | 
|---|
| 583 |       }
 | 
|---|
| 584 |       
 | 
|---|
| 585 |       // commit row
 | 
|---|
| 586 |       row.put( rowidx ) ;
 | 
|---|
| 587 |       rowidx++ ;
 | 
|---|
| 588 | 
 | 
|---|
| 589 |       // reset holder
 | 
|---|
| 590 |       holder.reset() ;
 | 
|---|
| 591 |     }
 | 
|---|
| 592 |     if ( tcalKey != -1 ) {
 | 
|---|
| 593 |       tcalNotYet[tcalKey] = False ;
 | 
|---|
| 594 |       tcalKey = -1 ;
 | 
|---|
| 595 |     }
 | 
|---|
| 596 |   }
 | 
|---|
| 597 |   virtual void enterPolNo(const uInt recordNo, uInt columnValue) {
 | 
|---|
| 598 |     //printf("%u: PolNo: %d\n", recordNo, columnValue);
 | 
|---|
| 599 |     uInt tcalId = tcalIdCol.asuInt( recordNo ) ;
 | 
|---|
| 600 |     if ( tcalKey == -1 ) {
 | 
|---|
| 601 |       tcalKey = tcalId ;
 | 
|---|
| 602 |     }
 | 
|---|
| 603 |     if ( tcalNotYet[tcalKey] ) {
 | 
|---|
| 604 |       map< Int,Vector<uInt> >::iterator itr = tcalIdRec.find( tcalKey ) ;
 | 
|---|
| 605 |       if ( itr != tcalIdRec.end() ) {
 | 
|---|
| 606 |         Vector<uInt> ids = itr->second ;
 | 
|---|
| 607 |         uInt nrow = ids.nelements() ;
 | 
|---|
| 608 |         ids.resize( nrow+1, True ) ;
 | 
|---|
| 609 |         ids[nrow] = tcalId ;
 | 
|---|
| 610 |         tcalIdRec.erase( tcalKey ) ;
 | 
|---|
| 611 |         tcalIdRec[tcalKey] = ids ;
 | 
|---|
| 612 |       }
 | 
|---|
| 613 |       else {
 | 
|---|
| 614 |         Vector<uInt> rows( 1, tcalId ) ;
 | 
|---|
| 615 |         tcalIdRec[tcalKey] = rows ;
 | 
|---|
| 616 |       }
 | 
|---|
| 617 |     }
 | 
|---|
| 618 |     map< Int,Vector<uInt> >::iterator itr = tcalRowRec.find( tcalKey ) ;
 | 
|---|
| 619 |     if ( itr != tcalRowRec.end() ) {
 | 
|---|
| 620 |       Vector<uInt> rows = itr->second ;
 | 
|---|
| 621 |       uInt nrow = rows.nelements() ;
 | 
|---|
| 622 |       rows.resize( nrow+1, True ) ;
 | 
|---|
| 623 |       rows[nrow] = recordNo ;
 | 
|---|
| 624 |       tcalRowRec.erase( tcalKey ) ;
 | 
|---|
| 625 |       tcalRowRec[tcalKey] = rows ;
 | 
|---|
| 626 |     }
 | 
|---|
| 627 |     else {
 | 
|---|
| 628 |       Vector<uInt> rows( 1, recordNo ) ;
 | 
|---|
| 629 |       tcalRowRec[tcalKey] = rows ;
 | 
|---|
| 630 |     }
 | 
|---|
| 631 |   }
 | 
|---|
| 632 |   virtual void leavePolNo(const uInt recordNo, uInt columnValue) {
 | 
|---|
| 633 |   }
 | 
|---|
| 634 | 
 | 
|---|
| 635 |   virtual Bool visitRecord(const uInt recordNo,
 | 
|---|
| 636 |                            const String &fieldName,
 | 
|---|
| 637 |                            const uInt beamNo,
 | 
|---|
| 638 |                            const uInt scanNo,
 | 
|---|
| 639 |                            const uInt ifNo,
 | 
|---|
| 640 |                            const Int srcType,
 | 
|---|
| 641 |                            const uInt cycleNo,
 | 
|---|
| 642 |                            const Double time,
 | 
|---|
| 643 |                            const uInt polNo) {
 | 
|---|
| 644 |     //printf("%u: %s, %u, %u, %u, %d, %u, %f, %d\n", recordNo,
 | 
|---|
| 645 |     //       fieldName.c_str(), beamNo, scanNo, ifNo, srcType, cycleNo, time, polNo);
 | 
|---|
| 646 | 
 | 
|---|
| 647 |     Vector<Float> sp = spectraCol( recordNo ) ;
 | 
|---|
| 648 |     Vector<uChar> tmp = flagtraCol( recordNo ) ;
 | 
|---|
| 649 |     Vector<Bool> fl( tmp.shape() ) ;
 | 
|---|
| 650 |     convertArray( fl, tmp ) ;
 | 
|---|
| 651 |     Bool flr = (Bool)flagRowCol.asuInt( recordNo ) ;
 | 
|---|
| 652 |     holder.accumulate( polNo, sp, fl, flr ) ;
 | 
|---|
| 653 | 
 | 
|---|
| 654 |     return True ;
 | 
|---|
| 655 |   }
 | 
|---|
| 656 | 
 | 
|---|
| 657 |   virtual void finish() {
 | 
|---|
| 658 |     BaseMSWriterVisitor::finish();
 | 
|---|
| 659 |     //printf("Total: %u\n", count);
 | 
|---|
| 660 | 
 | 
|---|
| 661 |     // remove rows
 | 
|---|
| 662 |     if ( ms.nrow() > rowidx ) {
 | 
|---|
| 663 |       uInt numRemove = ms.nrow() - rowidx ;
 | 
|---|
| 664 |       //cout << "numRemove = " << numRemove << endl ;
 | 
|---|
| 665 |       Vector<uInt> rows( numRemove ) ;
 | 
|---|
| 666 |       indgen( rows, rowidx ) ;
 | 
|---|
| 667 |       ms.removeRow( rows ) ;
 | 
|---|
| 668 |     }
 | 
|---|
| 669 | 
 | 
|---|
| 670 |     // fill empty SPECTRAL_WINDOW rows
 | 
|---|
| 671 |     infillSpectralWindow() ;
 | 
|---|
| 672 |   }
 | 
|---|
| 673 | 
 | 
|---|
| 674 |   void dataColumnName( String name ) 
 | 
|---|
| 675 |   {
 | 
|---|
| 676 |     TableRecord &r = row.record() ;
 | 
|---|
| 677 |     if ( name == "DATA" ) {
 | 
|---|
| 678 |       useFloat = False ;
 | 
|---|
| 679 |       dataRF.attachToRecord( r, name ) ;
 | 
|---|
| 680 |     }
 | 
|---|
| 681 |     else if ( name == "FLOAT_DATA" ) {
 | 
|---|
| 682 |       useFloat = True ;
 | 
|---|
| 683 |       floatDataRF.attachToRecord( r, name ) ;
 | 
|---|
| 684 |     }
 | 
|---|
| 685 |   }
 | 
|---|
| 686 |   void pointingTableName( String name ) {
 | 
|---|
| 687 |     ptName = name ;
 | 
|---|
| 688 |   }
 | 
|---|
| 689 |   void setSourceRecord( Record &r ) {
 | 
|---|
| 690 |     srcRec = r ;
 | 
|---|
| 691 |   }
 | 
|---|
| 692 |   map< Int,Vector<uInt> > &getTcalIdRecord() { return tcalIdRec ; }
 | 
|---|
| 693 |   map< Int,Vector<uInt> > &getTcalRowRecord() { return tcalRowRec ; }
 | 
|---|
| 694 | private:
 | 
|---|
| 695 |   void addField( Int &fid, String &fname, String &srcName,
 | 
|---|
| 696 |                  Vector<Double> &sdir, Vector<Double> &srate, 
 | 
|---|
| 697 |                  Double &tSec ) 
 | 
|---|
| 698 |   {
 | 
|---|
| 699 |     uInt nrow = fieldtab.nrow() ;
 | 
|---|
| 700 |     while( (Int)nrow <= fid ) {
 | 
|---|
| 701 |       fieldtab.addRow( 1, True ) ;
 | 
|---|
| 702 |       nrow++ ;
 | 
|---|
| 703 |     }
 | 
|---|
| 704 | 
 | 
|---|
| 705 |     Matrix<Double> dir ;
 | 
|---|
| 706 |     Int numPoly = 0 ;
 | 
|---|
| 707 |     if ( anyNE( srate, 0.0 ) ) {
 | 
|---|
| 708 |       dir.resize( 2, 2 ) ;
 | 
|---|
| 709 |       dir.column( 0 ) = sdir ;
 | 
|---|
| 710 |       dir.column( 1 ) = srate ;
 | 
|---|
| 711 |       numPoly = 1 ;
 | 
|---|
| 712 |     }
 | 
|---|
| 713 |     else {
 | 
|---|
| 714 |       dir.resize( 2, 1 ) ;
 | 
|---|
| 715 |       dir.column( 0 ) = sdir ;
 | 
|---|
| 716 |     }
 | 
|---|
| 717 |     srcId = srcRec.asInt( srcName ) ;
 | 
|---|
| 718 | 
 | 
|---|
| 719 |     TableRow tr( fieldtab ) ;
 | 
|---|
| 720 |     TableRecord &r = tr.record() ;
 | 
|---|
| 721 |     putField( "NAME", r, fname ) ;
 | 
|---|
| 722 |     putField( "NUM_POLY", r, numPoly ) ;
 | 
|---|
| 723 |     putField( "TIME", r, tSec ) ;
 | 
|---|
| 724 |     putField( "SOURCE_ID", r, srcId ) ;
 | 
|---|
| 725 |     defineField( "DELAY_DIR", r, dir ) ;
 | 
|---|
| 726 |     defineField( "REFERENCE_DIR", r, dir ) ;
 | 
|---|
| 727 |     defineField( "PHASE_DIR", r, dir ) ;
 | 
|---|
| 728 |     tr.put( fid ) ;
 | 
|---|
| 729 | 
 | 
|---|
| 730 |     // for POINTING table
 | 
|---|
| 731 |     *poNameRF = fname ;
 | 
|---|
| 732 |   }
 | 
|---|
| 733 |   Int addState( Int &id ) 
 | 
|---|
| 734 |   {
 | 
|---|
| 735 |     String obsMode ;
 | 
|---|
| 736 |     Bool isSignal ;
 | 
|---|
| 737 |     Double tnoise ;
 | 
|---|
| 738 |     Double tload ;
 | 
|---|
| 739 |     queryType( id, obsMode, isSignal, tnoise, tload ) ;
 | 
|---|
| 740 | 
 | 
|---|
| 741 |     String key = obsMode+"_"+String::toString( subscan ) ;
 | 
|---|
| 742 |     Int idx = -1 ;
 | 
|---|
| 743 |     uInt nEntry = stateEntry.nelements() ;
 | 
|---|
| 744 |     for ( uInt i = 0 ; i < nEntry ; i++ ) {
 | 
|---|
| 745 |       if ( stateEntry[i] == key ) {
 | 
|---|
| 746 |         idx = i ;
 | 
|---|
| 747 |         break ;
 | 
|---|
| 748 |       }
 | 
|---|
| 749 |     }
 | 
|---|
| 750 |     if ( idx == -1 ) {
 | 
|---|
| 751 |       uInt nrow = statetab.nrow() ;
 | 
|---|
| 752 |       statetab.addRow( 1, True ) ;
 | 
|---|
| 753 |       TableRow tr( statetab ) ;
 | 
|---|
| 754 |       TableRecord &r = tr.record() ;
 | 
|---|
| 755 |       putField( "OBS_MODE", r, obsMode ) ;
 | 
|---|
| 756 |       putField( "SIG", r, isSignal ) ;
 | 
|---|
| 757 |       isSignal = !isSignal ;
 | 
|---|
| 758 |       putField( "REF", r, isSignal ) ;
 | 
|---|
| 759 |       putField( "CAL", r, tnoise ) ;
 | 
|---|
| 760 |       putField( "LOAD", r, tload ) ;
 | 
|---|
| 761 |       tr.put( nrow ) ;
 | 
|---|
| 762 |       idx = nrow ;
 | 
|---|
| 763 | 
 | 
|---|
| 764 |       stateEntry.resize( nEntry+1, True ) ;
 | 
|---|
| 765 |       stateEntry[nEntry] = key ;
 | 
|---|
| 766 |     }
 | 
|---|
| 767 |     subscan++ ;
 | 
|---|
| 768 | 
 | 
|---|
| 769 |     return idx ;
 | 
|---|
| 770 |   }
 | 
|---|
| 771 |   void addPointing( Double &tSec, Double &interval, Matrix<Double> &dir ) 
 | 
|---|
| 772 |   {
 | 
|---|
| 773 |     uInt nrow = potab.nrow() ;
 | 
|---|
| 774 |     potab.addRow( 1, True ) ;
 | 
|---|
| 775 | 
 | 
|---|
| 776 |     *poNumPolyRF = dir.ncolumn() - 1 ;
 | 
|---|
| 777 |     *poTimeRF = tSec ;
 | 
|---|
| 778 |     *poTimeOriginRF = tSec ;
 | 
|---|
| 779 |     *poIntervalRF = interval ;
 | 
|---|
| 780 |     poDirectionRF.define( dir ) ;
 | 
|---|
| 781 |     poTargetRF.define( dir ) ;
 | 
|---|
| 782 |     porow.put( nrow ) ;
 | 
|---|
| 783 |   }
 | 
|---|
| 784 |   Int addPolarization( Vector<uInt> &nos )
 | 
|---|
| 785 |   {
 | 
|---|
| 786 |     Int idx = -1 ;
 | 
|---|
| 787 |     uInt nEntry = polEntry.size() ;
 | 
|---|
| 788 |     for ( uInt i = 0 ; i < nEntry ; i++ ) {
 | 
|---|
| 789 |       if ( polEntry[i].conform( nos ) && allEQ( polEntry[i], nos ) ) {
 | 
|---|
| 790 |         idx = i ;
 | 
|---|
| 791 |         break ;
 | 
|---|
| 792 |       }
 | 
|---|
| 793 |     }
 | 
|---|
| 794 |     
 | 
|---|
| 795 |     Int numCorr ;
 | 
|---|
| 796 |     Vector<Int> corrType ;
 | 
|---|
| 797 |     Matrix<Int> corrProduct ;
 | 
|---|
| 798 |     polProperty( nos, numCorr, corrType, corrProduct ) ;
 | 
|---|
| 799 | 
 | 
|---|
| 800 |     if ( idx == -1 ) {
 | 
|---|
| 801 |       uInt nrow = poltab.nrow() ;
 | 
|---|
| 802 |       poltab.addRow( 1, True ) ;
 | 
|---|
| 803 |       TableRow tr( poltab ) ;
 | 
|---|
| 804 |       TableRecord &r = tr.record() ;
 | 
|---|
| 805 |       putField( "NUM_CORR", r, numCorr ) ;
 | 
|---|
| 806 |       defineField( "CORR_TYPE", r, corrType ) ;
 | 
|---|
| 807 |       defineField( "CORR_PRODUCT", r, corrProduct ) ;
 | 
|---|
| 808 |       tr.put( nrow ) ;
 | 
|---|
| 809 |       idx = nrow ;
 | 
|---|
| 810 | 
 | 
|---|
| 811 |       polEntry.resize( nEntry+1 ) ;
 | 
|---|
| 812 |       polEntry[nEntry] = nos ;
 | 
|---|
| 813 |     }
 | 
|---|
| 814 | 
 | 
|---|
| 815 |     return idx ;
 | 
|---|
| 816 |   }
 | 
|---|
| 817 |   Int addDataDescription( Int pid, Int sid ) 
 | 
|---|
| 818 |   {
 | 
|---|
| 819 |     Int idx = -1 ;
 | 
|---|
| 820 |     uInt nEntry = ddEntry.nrow() ;
 | 
|---|
| 821 |     Vector<Int> key( 2 ) ;
 | 
|---|
| 822 |     key[0] = pid ;
 | 
|---|
| 823 |     key[1] = sid ;
 | 
|---|
| 824 |     for ( uInt i = 0 ; i < nEntry ; i++ ) {
 | 
|---|
| 825 |       if ( allEQ( ddEntry.row(i), key ) ) {
 | 
|---|
| 826 |         idx = i ;
 | 
|---|
| 827 |         break ;
 | 
|---|
| 828 |       }
 | 
|---|
| 829 |     }
 | 
|---|
| 830 | 
 | 
|---|
| 831 |     if ( idx == -1 ) {
 | 
|---|
| 832 |       uInt nrow = ddtab.nrow() ;
 | 
|---|
| 833 |       ddtab.addRow( 1, True ) ;
 | 
|---|
| 834 |       TableRow tr( ddtab ) ;
 | 
|---|
| 835 |       TableRecord &r = tr.record() ;
 | 
|---|
| 836 |       putField( "POLARIZATION_ID", r, pid ) ;
 | 
|---|
| 837 |       putField( "SPECTRAL_WINDOW_ID", r, sid ) ;
 | 
|---|
| 838 |       tr.put( nrow ) ;
 | 
|---|
| 839 |       idx = nrow ;
 | 
|---|
| 840 | 
 | 
|---|
| 841 |       ddEntry.resize( nEntry+1, 2, True ) ;
 | 
|---|
| 842 |       ddEntry.row(nEntry) = key ;
 | 
|---|
| 843 |     }
 | 
|---|
| 844 | 
 | 
|---|
| 845 |     return idx ;
 | 
|---|
| 846 |   }
 | 
|---|
| 847 |   void infillSpectralWindow()
 | 
|---|
| 848 |   {
 | 
|---|
| 849 |     ROScalarColumn<Int> nchanCol( spwtab, "NUM_CHAN" ) ;
 | 
|---|
| 850 |     Vector<Int> nchan = nchanCol.getColumn() ;
 | 
|---|
| 851 |     TableRow tr( spwtab ) ;
 | 
|---|
| 852 |     TableRecord &r = tr.record() ;
 | 
|---|
| 853 |     Int mfr = 1 ;
 | 
|---|
| 854 |     Vector<Double> dummy( 1, 0.0 ) ;
 | 
|---|
| 855 |     putField( "MEAS_FREQ_REF", r, mfr ) ;
 | 
|---|
| 856 |     defineField( "CHAN_FREQ", r, dummy ) ;
 | 
|---|
| 857 |     defineField( "CHAN_WIDTH", r, dummy ) ;
 | 
|---|
| 858 |     defineField( "EFFECTIVE_BW", r, dummy ) ;
 | 
|---|
| 859 |     defineField( "RESOLUTION", r, dummy ) ;
 | 
|---|
| 860 | 
 | 
|---|
| 861 |     for ( uInt i = 0 ; i < spwtab.nrow() ; i++ ) {
 | 
|---|
| 862 |       if ( nchan[i] == 0 )
 | 
|---|
| 863 |         tr.put( i ) ;
 | 
|---|
| 864 |     }
 | 
|---|
| 865 |   }
 | 
|---|
| 866 |   void addSpectralWindow( Int sid, uInt fid )
 | 
|---|
| 867 |   {
 | 
|---|
| 868 |     if ( !processedFreqId[fid] ) {
 | 
|---|
| 869 |       uInt nrow = spwtab.nrow() ;
 | 
|---|
| 870 |       while( (Int)nrow <= sid ) {
 | 
|---|
| 871 |         spwtab.addRow( 1, True ) ;
 | 
|---|
| 872 |         nrow++ ;
 | 
|---|
| 873 |       }
 | 
|---|
| 874 |       processedFreqId[fid] = True ;
 | 
|---|
| 875 |     }
 | 
|---|
| 876 | 
 | 
|---|
| 877 |     Double rp = refpix[fid] ;
 | 
|---|
| 878 |     Double rv = refval[fid] ;
 | 
|---|
| 879 |     Double ic = increment[fid] ;
 | 
|---|
| 880 | 
 | 
|---|
| 881 |     Int mfrInt = (Int)freqframe ;
 | 
|---|
| 882 |     Int nchan = holder.nChan() ;
 | 
|---|
| 883 |     Double bw = nchan * abs( ic ) ;
 | 
|---|
| 884 |     Double reffreq = rv - rp * ic ;
 | 
|---|
| 885 |     Int netsb = 0 ; // USB->0, LSB->1
 | 
|---|
| 886 |     if ( ic < 0 )
 | 
|---|
| 887 |       netsb = 1 ;
 | 
|---|
| 888 |     Vector<Double> res( nchan, abs(ic) ) ;
 | 
|---|
| 889 |     Vector<Double> chanf( nchan ) ;
 | 
|---|
| 890 |     indgen( chanf, reffreq, ic ) ;
 | 
|---|
| 891 | 
 | 
|---|
| 892 |     TableRow tr( spwtab ) ;
 | 
|---|
| 893 |     TableRecord &r = tr.record() ;
 | 
|---|
| 894 |     putField( "MEAS_FREQ_REF", r, mfrInt ) ;
 | 
|---|
| 895 |     putField( "NUM_CHAN", r, nchan ) ;
 | 
|---|
| 896 |     putField( "TOTAL_BANDWIDTH", r, bw ) ;
 | 
|---|
| 897 |     putField( "REF_FREQUENCY", r, reffreq ) ;
 | 
|---|
| 898 |     putField( "NET_SIDEBAND", r, netsb ) ;
 | 
|---|
| 899 |     defineField( "RESOLUTION", r, res ) ;
 | 
|---|
| 900 |     defineField( "CHAN_WIDTH", r, res ) ;
 | 
|---|
| 901 |     defineField( "EFFECTIVE_BW", r, res ) ;
 | 
|---|
| 902 |     defineField( "CHAN_FREQ", r, chanf ) ;
 | 
|---|
| 903 |     tr.put( sid ) ;
 | 
|---|
| 904 |   }
 | 
|---|
| 905 |   void addFeed( Int fid, Int sid )
 | 
|---|
| 906 |   {
 | 
|---|
| 907 |     Int idx = -1 ;
 | 
|---|
| 908 |     uInt nEntry = feedEntry.nrow() ;
 | 
|---|
| 909 |     Vector<Int> key( 2 ) ;
 | 
|---|
| 910 |     key[0] = fid ;
 | 
|---|
| 911 |     key[1] = sid ;
 | 
|---|
| 912 |     for ( uInt i = 0 ; i < nEntry ; i++ ) {
 | 
|---|
| 913 |       if ( allEQ( feedEntry.row(i), key ) ) {
 | 
|---|
| 914 |         idx = i ;
 | 
|---|
| 915 |         break ;
 | 
|---|
| 916 |       }
 | 
|---|
| 917 |     }
 | 
|---|
| 918 | 
 | 
|---|
| 919 |     if ( idx == -1 ) {
 | 
|---|
| 920 |       uInt nrow = feedtab.nrow() ;
 | 
|---|
| 921 |       feedtab.addRow( 1, True ) ;
 | 
|---|
| 922 |       Int numReceptors = 2 ;
 | 
|---|
| 923 |       Vector<String> polType( numReceptors ) ;
 | 
|---|
| 924 |       Matrix<Double> beamOffset( 2, numReceptors, 0.0 ) ;
 | 
|---|
| 925 |       Vector<Double> receptorAngle( numReceptors, 0.0 ) ;
 | 
|---|
| 926 |       if ( poltype == "linear" ) {
 | 
|---|
| 927 |         polType[0] = "X" ;
 | 
|---|
| 928 |         polType[1] = "Y" ;
 | 
|---|
| 929 |       }
 | 
|---|
| 930 |       else if ( poltype == "circular" ) {
 | 
|---|
| 931 |         polType[0] = "R" ;
 | 
|---|
| 932 |         polType[1] = "L" ;
 | 
|---|
| 933 |       }
 | 
|---|
| 934 |       else {
 | 
|---|
| 935 |         polType[0] = "X" ;
 | 
|---|
| 936 |         polType[1] = "Y" ;
 | 
|---|
| 937 |       }
 | 
|---|
| 938 |       Matrix<Complex> polResponse( numReceptors, numReceptors, 0.0 ) ;
 | 
|---|
| 939 |       
 | 
|---|
| 940 |       TableRow tr( feedtab ) ;
 | 
|---|
| 941 |       TableRecord &r = tr.record() ;
 | 
|---|
| 942 |       putField( "FEED_ID", r, fid ) ;
 | 
|---|
| 943 |       putField( "BEAM_ID", r, fid ) ;
 | 
|---|
| 944 |       Int tmp = 0 ;
 | 
|---|
| 945 |       putField( "ANTENNA_ID", r, tmp ) ;
 | 
|---|
| 946 |       putField( "SPECTRAL_WINDOW_ID", r, sid ) ;
 | 
|---|
| 947 |       putField( "NUM_RECEPTORS", r, numReceptors ) ;
 | 
|---|
| 948 |       defineField( "POLARIZATION_TYPE", r, polType ) ;
 | 
|---|
| 949 |       defineField( "BEAM_OFFSET", r, beamOffset ) ;
 | 
|---|
| 950 |       defineField( "RECEPTOR_ANGLE", r, receptorAngle ) ;
 | 
|---|
| 951 |       defineField( "POL_RESPONSE", r, polResponse ) ;
 | 
|---|
| 952 |       tr.put( nrow ) ;
 | 
|---|
| 953 | 
 | 
|---|
| 954 |       feedEntry.resize( nEntry+1, 2, True ) ;
 | 
|---|
| 955 |       feedEntry.row( nEntry ) = key ;
 | 
|---|
| 956 |     }
 | 
|---|
| 957 |   }
 | 
|---|
| 958 |   void makePolMap() 
 | 
|---|
| 959 |   {
 | 
|---|
| 960 |     const TableRecord &keys = table.keywordSet() ;
 | 
|---|
| 961 |     poltype = keys.asString( "POLTYPE" ) ;
 | 
|---|
| 962 | 
 | 
|---|
| 963 |     if ( poltype == "stokes" ) {
 | 
|---|
| 964 |       polmap.resize( 4 ) ;
 | 
|---|
| 965 |       polmap[0] = Stokes::I ;
 | 
|---|
| 966 |       polmap[1] = Stokes::Q ;
 | 
|---|
| 967 |       polmap[2] = Stokes::U ;
 | 
|---|
| 968 |       polmap[3] = Stokes::V ;
 | 
|---|
| 969 |     }
 | 
|---|
| 970 |     else if ( poltype == "linear" ) {
 | 
|---|
| 971 |       polmap.resize( 4 ) ;
 | 
|---|
| 972 |       polmap[0] = Stokes::XX ;
 | 
|---|
| 973 |       polmap[1] = Stokes::YY ;
 | 
|---|
| 974 |       polmap[2] = Stokes::XY ;
 | 
|---|
| 975 |       polmap[3] = Stokes::YX ;
 | 
|---|
| 976 |     }
 | 
|---|
| 977 |     else if ( poltype == "circular" ) {
 | 
|---|
| 978 |       polmap.resize( 4 ) ;
 | 
|---|
| 979 |       polmap[0] = Stokes::RR ;
 | 
|---|
| 980 |       polmap[1] = Stokes::LL ;
 | 
|---|
| 981 |       polmap[2] = Stokes::RL ;
 | 
|---|
| 982 |       polmap[3] = Stokes::LR ;
 | 
|---|
| 983 |     }
 | 
|---|
| 984 |     else if ( poltype == "linpol" ) {
 | 
|---|
| 985 |       polmap.resize( 2 ) ;
 | 
|---|
| 986 |       polmap[0] = Stokes::Plinear ;
 | 
|---|
| 987 |       polmap[1] = Stokes::Pangle ;
 | 
|---|
| 988 |     }
 | 
|---|
| 989 |     else {
 | 
|---|
| 990 |       polmap.resize( 0 ) ;
 | 
|---|
| 991 |     }
 | 
|---|
| 992 |   }
 | 
|---|
| 993 |   void initFrequencies()
 | 
|---|
| 994 |   {
 | 
|---|
| 995 |     const TableRecord &keys = table.keywordSet() ;
 | 
|---|
| 996 |     Table tab = keys.asTable( "FREQUENCIES" ) ;
 | 
|---|
| 997 |     ROScalarColumn<uInt> idcol( tab, "ID" ) ;
 | 
|---|
| 998 |     ROScalarColumn<Double> rpcol( tab, "REFPIX" ) ;
 | 
|---|
| 999 |     ROScalarColumn<Double> rvcol( tab, "REFVAL" ) ;
 | 
|---|
| 1000 |     ROScalarColumn<Double> iccol( tab, "INCREMENT" ) ;
 | 
|---|
| 1001 |     Vector<uInt> id = idcol.getColumn() ;
 | 
|---|
| 1002 |     Vector<Double> rp = rpcol.getColumn() ;
 | 
|---|
| 1003 |     Vector<Double> rv = rvcol.getColumn() ;
 | 
|---|
| 1004 |     Vector<Double> ic = iccol.getColumn() ;
 | 
|---|
| 1005 |     for ( uInt i = 0 ; i < id.nelements() ; i++ ) {
 | 
|---|
| 1006 |       processedFreqId.insert( pair<uInt,Bool>( id[i], False ) ) ;
 | 
|---|
| 1007 |       refpix.insert( pair<uInt,Double>( id[i], rp[i] ) ) ;
 | 
|---|
| 1008 |       refval.insert( pair<uInt,Double>( id[i], rv[i] ) ) ;
 | 
|---|
| 1009 |       increment.insert( pair<uInt,Double>( id[i], ic[i] ) ) ;
 | 
|---|
| 1010 |     }
 | 
|---|
| 1011 |     String frameStr = tab.keywordSet().asString( "BASEFRAME" ) ;
 | 
|---|
| 1012 |     MFrequency::getType( freqframe, frameStr ) ;
 | 
|---|
| 1013 |   }
 | 
|---|
| 1014 |   void attachSubtables()
 | 
|---|
| 1015 |   {
 | 
|---|
| 1016 |     const TableRecord &keys = table.keywordSet() ;
 | 
|---|
| 1017 |     TableRecord &mskeys = ms.rwKeywordSet() ;
 | 
|---|
| 1018 | 
 | 
|---|
| 1019 |     // FIELD table
 | 
|---|
| 1020 |     fieldtab = mskeys.asTable( "FIELD" ) ;
 | 
|---|
| 1021 | 
 | 
|---|
| 1022 |     // SPECTRAL_WINDOW table
 | 
|---|
| 1023 |     spwtab = mskeys.asTable( "SPECTRAL_WINDOW" ) ;
 | 
|---|
| 1024 | 
 | 
|---|
| 1025 |     // POINTING table
 | 
|---|
| 1026 |     potab = mskeys.asTable( "POINTING" ) ;
 | 
|---|
| 1027 | 
 | 
|---|
| 1028 |     // POLARIZATION table
 | 
|---|
| 1029 |     poltab = mskeys.asTable( "POLARIZATION" ) ;
 | 
|---|
| 1030 | 
 | 
|---|
| 1031 |     // DATA_DESCRIPTION table
 | 
|---|
| 1032 |     ddtab = mskeys.asTable( "DATA_DESCRIPTION" ) ;
 | 
|---|
| 1033 | 
 | 
|---|
| 1034 |     // STATE table 
 | 
|---|
| 1035 |     statetab = mskeys.asTable( "STATE" ) ;
 | 
|---|
| 1036 | 
 | 
|---|
| 1037 |     // FEED table
 | 
|---|
| 1038 |     feedtab = mskeys.asTable( "FEED" ) ;
 | 
|---|
| 1039 |   }
 | 
|---|
| 1040 |   void attachMain()
 | 
|---|
| 1041 |   {
 | 
|---|
| 1042 |     TableRecord &r = row.record() ;
 | 
|---|
| 1043 |     dataDescIdRF.attachToRecord( r, "DATA_DESC_ID" ) ;
 | 
|---|
| 1044 |     flagRowRF.attachToRecord( r, "FLAG_ROW" ) ;
 | 
|---|
| 1045 |     weightRF.attachToRecord( r, "WEIGHT" ) ;
 | 
|---|
| 1046 |     sigmaRF.attachToRecord( r, "SIGMA" ) ;
 | 
|---|
| 1047 |     flagCategoryRF.attachToRecord( r, "FLAG_CATEGORY" ) ;
 | 
|---|
| 1048 |     flagRF.attachToRecord( r, "FLAG" ) ;
 | 
|---|
| 1049 |     timeRF.attachToRecord( r, "TIME" ) ;
 | 
|---|
| 1050 |     timeCentroidRF.attachToRecord( r, "TIME_CENTROID" ) ;
 | 
|---|
| 1051 |     intervalRF.attachToRecord( r, "INTERVAL" ) ;
 | 
|---|
| 1052 |     exposureRF.attachToRecord( r, "EXPOSURE" ) ;
 | 
|---|
| 1053 |     fieldIdRF.attachToRecord( r, "FIELD_ID" ) ;
 | 
|---|
| 1054 |     feed1RF.attachToRecord( r, "FEED1" ) ;
 | 
|---|
| 1055 |     feed2RF.attachToRecord( r, "FEED2" ) ;
 | 
|---|
| 1056 |     scanNumberRF.attachToRecord( r, "SCAN_NUMBER" ) ;
 | 
|---|
| 1057 |     stateIdRF.attachToRecord( r, "STATE_ID" ) ;
 | 
|---|
| 1058 | 
 | 
|---|
| 1059 |     // constant values
 | 
|---|
| 1060 |     Int id = 0 ;
 | 
|---|
| 1061 |     RecordFieldPtr<Int> intRF( r, "OBSERVATION_ID" ) ;
 | 
|---|
| 1062 |     *intRF = 0 ;
 | 
|---|
| 1063 |     intRF.attachToRecord( r, "ANTENNA1" ) ;
 | 
|---|
| 1064 |     *intRF = 0 ;
 | 
|---|
| 1065 |     intRF.attachToRecord( r, "ANTENNA2" ) ;
 | 
|---|
| 1066 |     *intRF = 0 ;
 | 
|---|
| 1067 |     intRF.attachToRecord( r, "ARRAY_ID" ) ;
 | 
|---|
| 1068 |     *intRF = 0 ;
 | 
|---|
| 1069 |     intRF.attachToRecord( r, "PROCESSOR_ID" ) ;
 | 
|---|
| 1070 |     *intRF = 0 ;
 | 
|---|
| 1071 |     RecordFieldPtr< Vector<Double> > arrayRF( r, "UVW" ) ; 
 | 
|---|
| 1072 |     arrayRF.define( Vector<Double>( 3, 0.0 ) ) ;
 | 
|---|
| 1073 |   }
 | 
|---|
| 1074 |   void attachPointing()
 | 
|---|
| 1075 |   {
 | 
|---|
| 1076 |     porow = TableRow( potab ) ;
 | 
|---|
| 1077 |     TableRecord &r = porow.record() ;
 | 
|---|
| 1078 |     poNumPolyRF.attachToRecord( r, "NUM_POLY" ) ;
 | 
|---|
| 1079 |     poTimeRF.attachToRecord( r, "TIME" ) ;
 | 
|---|
| 1080 |     poTimeOriginRF.attachToRecord( r, "TIME_ORIGIN" ) ;
 | 
|---|
| 1081 |     poIntervalRF.attachToRecord( r, "INTERVAL" ) ;
 | 
|---|
| 1082 |     poNameRF.attachToRecord( r, "NAME" ) ;
 | 
|---|
| 1083 |     poDirectionRF.attachToRecord( r, "DIRECTION" ) ;
 | 
|---|
| 1084 |     poTargetRF.attachToRecord( r, "TARGET" ) ;
 | 
|---|
| 1085 |     
 | 
|---|
| 1086 |     // constant values
 | 
|---|
| 1087 |     RecordFieldPtr<Int> antIdRF( r, "ANTENNA_ID" ) ;
 | 
|---|
| 1088 |     *antIdRF = 0 ;
 | 
|---|
| 1089 |     RecordFieldPtr<Bool> trackingRF( r, "TRACKING" ) ;
 | 
|---|
| 1090 |     *trackingRF = True ;
 | 
|---|
| 1091 |   }
 | 
|---|
| 1092 |   void queryType( Int type, String &stype, Bool &b, Double &t, Double &l )
 | 
|---|
| 1093 |   {
 | 
|---|
| 1094 |     t = 0.0 ;
 | 
|---|
| 1095 |     l = 0.0 ;
 | 
|---|
| 1096 | 
 | 
|---|
| 1097 |     String sep1="#" ;
 | 
|---|
| 1098 |     String sep2="," ;
 | 
|---|
| 1099 |     String target="OBSERVE_TARGET" ;
 | 
|---|
| 1100 |     String atmcal="CALIBRATE_TEMPERATURE" ;
 | 
|---|
| 1101 |     String onstr="ON_SOURCE" ;
 | 
|---|
| 1102 |     String offstr="OFF_SOURCE" ;
 | 
|---|
| 1103 |     String pswitch="POSITION_SWITCH" ;
 | 
|---|
| 1104 |     String nod="NOD" ;
 | 
|---|
| 1105 |     String fswitch="FREQUENCY_SWITCH" ;
 | 
|---|
| 1106 |     String sigstr="SIG" ;
 | 
|---|
| 1107 |     String refstr="REF" ;
 | 
|---|
| 1108 |     String unspecified="UNSPECIFIED" ;
 | 
|---|
| 1109 |     String ftlow="LOWER" ;
 | 
|---|
| 1110 |     String fthigh="HIGHER" ;
 | 
|---|
| 1111 |     switch ( type ) {
 | 
|---|
| 1112 |     case SrcType::PSON:
 | 
|---|
| 1113 |       stype = target+sep1+onstr+sep2+pswitch ;
 | 
|---|
| 1114 |       b = True ;
 | 
|---|
| 1115 |       break ;
 | 
|---|
| 1116 |     case SrcType::PSOFF:
 | 
|---|
| 1117 |       stype = target+sep1+offstr+sep2+pswitch ;
 | 
|---|
| 1118 |       b = False ;
 | 
|---|
| 1119 |       break ;
 | 
|---|
| 1120 |     case SrcType::NOD:
 | 
|---|
| 1121 |       stype = target+sep1+onstr+sep2+nod ;
 | 
|---|
| 1122 |       b = True ;
 | 
|---|
| 1123 |       break ;
 | 
|---|
| 1124 |     case SrcType::FSON:
 | 
|---|
| 1125 |       stype = target+sep1+onstr+sep2+fswitch+sep1+sigstr ;
 | 
|---|
| 1126 |       b = True ;
 | 
|---|
| 1127 |       break ;
 | 
|---|
| 1128 |     case SrcType::FSOFF:
 | 
|---|
| 1129 |       stype = target+sep1+onstr+sep2+fswitch+sep1+refstr ;
 | 
|---|
| 1130 |       b = False ;
 | 
|---|
| 1131 |       break ;
 | 
|---|
| 1132 |     case SrcType::SKY:
 | 
|---|
| 1133 |       stype = atmcal+sep1+offstr+sep2+unspecified ;
 | 
|---|
| 1134 |       b = False ;
 | 
|---|
| 1135 |       break ;
 | 
|---|
| 1136 |     case SrcType::HOT:
 | 
|---|
| 1137 |       stype = atmcal+sep1+offstr+sep2+unspecified ;
 | 
|---|
| 1138 |       b = False ;
 | 
|---|
| 1139 |       break ;
 | 
|---|
| 1140 |     case SrcType::WARM:
 | 
|---|
| 1141 |       stype = atmcal+sep1+offstr+sep2+unspecified ;
 | 
|---|
| 1142 |       b = False ;
 | 
|---|
| 1143 |       break ;
 | 
|---|
| 1144 |     case SrcType::COLD:
 | 
|---|
| 1145 |       stype = atmcal+sep1+offstr+sep2+unspecified ;
 | 
|---|
| 1146 |       b = False ;
 | 
|---|
| 1147 |       break ;
 | 
|---|
| 1148 |     case SrcType::PONCAL:
 | 
|---|
| 1149 |       stype = atmcal+sep1+onstr+sep2+pswitch ;
 | 
|---|
| 1150 |       b = True ;
 | 
|---|
| 1151 |       break ;
 | 
|---|
| 1152 |     case SrcType::POFFCAL:
 | 
|---|
| 1153 |       stype = atmcal+sep1+offstr+sep2+pswitch ;
 | 
|---|
| 1154 |       b = False ;
 | 
|---|
| 1155 |       break ;
 | 
|---|
| 1156 |     case SrcType::NODCAL:
 | 
|---|
| 1157 |       stype = atmcal+sep1+onstr+sep2+nod ;
 | 
|---|
| 1158 |       b = True ;
 | 
|---|
| 1159 |       break ;
 | 
|---|
| 1160 |     case SrcType::FONCAL:
 | 
|---|
| 1161 |       stype = atmcal+sep1+onstr+sep2+fswitch+sep1+sigstr ;
 | 
|---|
| 1162 |       b = True ;
 | 
|---|
| 1163 |       break ;
 | 
|---|
| 1164 |     case SrcType::FOFFCAL:
 | 
|---|
| 1165 |       stype = atmcal+sep1+offstr+sep2+fswitch+sep1+refstr ;
 | 
|---|
| 1166 |       b = False ;
 | 
|---|
| 1167 |       break ;
 | 
|---|
| 1168 |     case SrcType::FSLO:
 | 
|---|
| 1169 |       stype = target+sep1+onstr+sep2+fswitch+sep1+ftlow ;
 | 
|---|
| 1170 |       b = True ;
 | 
|---|
| 1171 |       break ;
 | 
|---|
| 1172 |     case SrcType::FLOOFF:
 | 
|---|
| 1173 |       stype = target+sep1+offstr+sep2+fswitch+sep1+ftlow ;
 | 
|---|
| 1174 |       b = False ;
 | 
|---|
| 1175 |       break ;
 | 
|---|
| 1176 |     case SrcType::FLOSKY:
 | 
|---|
| 1177 |       stype = atmcal+sep1+offstr+sep2+fswitch+sep1+ftlow ;
 | 
|---|
| 1178 |       b = False ;
 | 
|---|
| 1179 |       break ;
 | 
|---|
| 1180 |     case SrcType::FLOHOT:
 | 
|---|
| 1181 |       stype = atmcal+sep1+offstr+sep2+fswitch+sep1+ftlow ;
 | 
|---|
| 1182 |       b = False ;
 | 
|---|
| 1183 |       break ;
 | 
|---|
| 1184 |     case SrcType::FLOWARM:
 | 
|---|
| 1185 |       stype = atmcal+sep1+offstr+sep2+fswitch+sep1+ftlow ;
 | 
|---|
| 1186 |       b = False ;
 | 
|---|
| 1187 |       break ;
 | 
|---|
| 1188 |     case SrcType::FLOCOLD:
 | 
|---|
| 1189 |       stype = atmcal+sep1+offstr+sep2+fswitch+sep1+ftlow ;
 | 
|---|
| 1190 |       b = False ;
 | 
|---|
| 1191 |       break ;
 | 
|---|
| 1192 |     case SrcType::FSHI:
 | 
|---|
| 1193 |       stype = target+sep1+onstr+sep2+fswitch+sep1+fthigh ;
 | 
|---|
| 1194 |       b = True ;
 | 
|---|
| 1195 |       break ;
 | 
|---|
| 1196 |     case SrcType::FHIOFF:
 | 
|---|
| 1197 |       stype = target+sep1+offstr+sep2+fswitch+sep1+fthigh ;
 | 
|---|
| 1198 |       b = False ;
 | 
|---|
| 1199 |       break ;
 | 
|---|
| 1200 |     case SrcType::FHISKY:
 | 
|---|
| 1201 |       stype = atmcal+sep1+offstr+sep2+fswitch+sep1+fthigh ;
 | 
|---|
| 1202 |       b = False ;
 | 
|---|
| 1203 |       break ;
 | 
|---|
| 1204 |     case SrcType::FHIHOT:
 | 
|---|
| 1205 |       stype = atmcal+sep1+offstr+sep2+fswitch+sep1+fthigh ;
 | 
|---|
| 1206 |       b = False ;
 | 
|---|
| 1207 |       break ;
 | 
|---|
| 1208 |     case SrcType::FHIWARM:
 | 
|---|
| 1209 |       stype = atmcal+sep1+offstr+sep2+fswitch+sep1+fthigh ;
 | 
|---|
| 1210 |       b = False ;
 | 
|---|
| 1211 |       break ;
 | 
|---|
| 1212 |     case SrcType::FHICOLD:
 | 
|---|
| 1213 |       stype = atmcal+sep1+offstr+sep2+fswitch+sep1+fthigh ;
 | 
|---|
| 1214 |       b = False ;
 | 
|---|
| 1215 |       break ;
 | 
|---|
| 1216 |     case SrcType::SIG:
 | 
|---|
| 1217 |       stype = target+sep1+onstr+sep2+unspecified ;
 | 
|---|
| 1218 |       b = True ;
 | 
|---|
| 1219 |       break ;
 | 
|---|
| 1220 |     case SrcType::REF:
 | 
|---|
| 1221 |       stype = target+sep1+offstr+sep2+unspecified ;
 | 
|---|
| 1222 |       b = False ;
 | 
|---|
| 1223 |       break ;
 | 
|---|
| 1224 |     default:
 | 
|---|
| 1225 |       stype = unspecified ;
 | 
|---|
| 1226 |       b = True ;
 | 
|---|
| 1227 |       break ;
 | 
|---|
| 1228 |     }
 | 
|---|
| 1229 |   }
 | 
|---|
| 1230 |   void polProperty( Vector<uInt> &nos, Int &n, Vector<Int> &c, Matrix<Int> &cp ) 
 | 
|---|
| 1231 |   {
 | 
|---|
| 1232 |     n = nos.nelements() ;
 | 
|---|
| 1233 |     c.resize( n ) ;
 | 
|---|
| 1234 |     for ( Int i = 0 ; i < n ; i++ )
 | 
|---|
| 1235 |       c[i] = (Int)polmap[nos[i]] ;
 | 
|---|
| 1236 |     cp.resize( 2, n ) ;
 | 
|---|
| 1237 |     if ( n == 1 )
 | 
|---|
| 1238 |       cp = 0 ;
 | 
|---|
| 1239 |     else if ( n == 2 ) {
 | 
|---|
| 1240 |       cp.column( 0 ) = 0 ;
 | 
|---|
| 1241 |       cp.column( 1 ) = 1 ;
 | 
|---|
| 1242 |     }
 | 
|---|
| 1243 |     else {
 | 
|---|
| 1244 |       cp.column( 0 ) = 0 ;
 | 
|---|
| 1245 |       cp.column( 1 ) = 1 ;
 | 
|---|
| 1246 |       cp( 0, 1 ) = 0 ;
 | 
|---|
| 1247 |       cp( 1, 1 ) = 1 ;
 | 
|---|
| 1248 |       cp( 0, 2 ) = 1 ;
 | 
|---|
| 1249 |       cp( 1, 2 ) = 0 ;
 | 
|---|
| 1250 |     }
 | 
|---|
| 1251 |   }
 | 
|---|
| 1252 |   void initTcal()
 | 
|---|
| 1253 |   {
 | 
|---|
| 1254 |     const TableRecord &rec = table.keywordSet() ;
 | 
|---|
| 1255 |     Table tcalTable = rec.asTable( "TCAL" ) ;
 | 
|---|
| 1256 |     ROScalarColumn<uInt> idCol( tcalTable, "ID" ) ;
 | 
|---|
| 1257 |     Vector<uInt> id = idCol.getColumn() ;
 | 
|---|
| 1258 |     uInt maxId = max( id ) ;
 | 
|---|
| 1259 |     tcalNotYet.resize( maxId+1 ) ;
 | 
|---|
| 1260 |     tcalNotYet = True ;
 | 
|---|
| 1261 |     tcalKey = -1 ;
 | 
|---|
| 1262 |   }
 | 
|---|
| 1263 | 
 | 
|---|
| 1264 |   Table &ms;
 | 
|---|
| 1265 |   TableRow row;
 | 
|---|
| 1266 |   uInt rowidx;
 | 
|---|
| 1267 |   String fieldName;
 | 
|---|
| 1268 |   Int fieldId;
 | 
|---|
| 1269 |   Int srcId;
 | 
|---|
| 1270 |   Int defaultFieldId;
 | 
|---|
| 1271 |   Int spwId;
 | 
|---|
| 1272 |   Int feedId;
 | 
|---|
| 1273 |   Int subscan;
 | 
|---|
| 1274 |   PolarizedComponentHolder holder;
 | 
|---|
| 1275 |   String ptName;
 | 
|---|
| 1276 |   Bool useFloat;
 | 
|---|
| 1277 |   String poltype;
 | 
|---|
| 1278 |   Vector<Stokes::StokesTypes> polmap;
 | 
|---|
| 1279 | 
 | 
|---|
| 1280 |   // MS subtables
 | 
|---|
| 1281 |   Table spwtab;
 | 
|---|
| 1282 |   Table statetab;
 | 
|---|
| 1283 |   Table ddtab;
 | 
|---|
| 1284 |   Table poltab;
 | 
|---|
| 1285 |   Table fieldtab;
 | 
|---|
| 1286 |   Table feedtab;
 | 
|---|
| 1287 |   Table potab;
 | 
|---|
| 1288 | 
 | 
|---|
| 1289 |   // Scantable MAIN columns
 | 
|---|
| 1290 |   ROArrayColumn<Float> spectraCol;
 | 
|---|
| 1291 |   ROArrayColumn<Double> directionCol,scanRateCol,sourceDirectionCol;
 | 
|---|
| 1292 |   ROArrayColumn<uChar> flagtraCol;
 | 
|---|
| 1293 |   ROTableColumn tcalIdCol,intervalCol,flagRowCol,timeCol,freqIdCol,
 | 
|---|
| 1294 |     sourceNameCol,fieldNameCol;
 | 
|---|
| 1295 | 
 | 
|---|
| 1296 |   // MS MAIN columns
 | 
|---|
| 1297 |   RecordFieldPtr<Int> dataDescIdRF,fieldIdRF,feed1RF,feed2RF,
 | 
|---|
| 1298 |     scanNumberRF,stateIdRF;
 | 
|---|
| 1299 |   RecordFieldPtr<Bool> flagRowRF;
 | 
|---|
| 1300 |   RecordFieldPtr<Double> timeRF,timeCentroidRF,intervalRF,exposureRF;
 | 
|---|
| 1301 |   RecordFieldPtr< Vector<Float> > weightRF,sigmaRF;
 | 
|---|
| 1302 |   RecordFieldPtr< Cube<Bool> > flagCategoryRF;
 | 
|---|
| 1303 |   RecordFieldPtr< Matrix<Bool> > flagRF;
 | 
|---|
| 1304 |   RecordFieldPtr< Matrix<Float> > floatDataRF;
 | 
|---|
| 1305 |   RecordFieldPtr< Matrix<Complex> > dataRF;
 | 
|---|
| 1306 | 
 | 
|---|
| 1307 |   // MS POINTING columns
 | 
|---|
| 1308 |   TableRow porow;
 | 
|---|
| 1309 |   RecordFieldPtr<Int> poNumPolyRF ;
 | 
|---|
| 1310 |   RecordFieldPtr<Double> poTimeRF,
 | 
|---|
| 1311 |     poTimeOriginRF,
 | 
|---|
| 1312 |     poIntervalRF ;
 | 
|---|
| 1313 |   RecordFieldPtr<String> poNameRF ;
 | 
|---|
| 1314 |   RecordFieldPtr< Matrix<Double> > poDirectionRF,
 | 
|---|
| 1315 |     poTargetRF ;
 | 
|---|
| 1316 | 
 | 
|---|
| 1317 |   Vector<String> stateEntry;
 | 
|---|
| 1318 |   Matrix<Int> ddEntry;
 | 
|---|
| 1319 |   Matrix<Int> feedEntry;
 | 
|---|
| 1320 |   vector< Vector<uInt> > polEntry;
 | 
|---|
| 1321 |   map<uInt,Bool> processedFreqId;
 | 
|---|
| 1322 |   map<uInt,Double> refpix;
 | 
|---|
| 1323 |   map<uInt,Double> refval;
 | 
|---|
| 1324 |   map<uInt,Double> increment;
 | 
|---|
| 1325 |   MFrequency::Types freqframe;
 | 
|---|
| 1326 |   Record srcRec;
 | 
|---|
| 1327 |   map< Int,Vector<uInt> > tcalIdRec;
 | 
|---|
| 1328 |   map< Int,Vector<uInt> > tcalRowRec;
 | 
|---|
| 1329 |   Int tcalKey;
 | 
|---|
| 1330 |   Vector<Bool> tcalNotYet;
 | 
|---|
| 1331 | };
 | 
|---|
| 1332 | 
 | 
|---|
| 1333 | MSWriter::MSWriter(CountedPtr<Scantable> stable) 
 | 
|---|
| 1334 |   : table_(stable),
 | 
|---|
| 1335 |     isTcal_(False),
 | 
|---|
| 1336 |     isWeather_(False),
 | 
|---|
| 1337 |     tcalSpec_(False),
 | 
|---|
| 1338 |     tsysSpec_(False),
 | 
|---|
| 1339 |     ptTabName_("")
 | 
|---|
| 1340 | {
 | 
|---|
| 1341 |   os_ = LogIO() ;
 | 
|---|
| 1342 |   os_.origin( LogOrigin( "MSWriter", "MSWriter()", WHERE ) ) ;
 | 
|---|
| 1343 | //   os_ << "MSWriter::MSWriter()" << LogIO::POST ;
 | 
|---|
| 1344 | 
 | 
|---|
| 1345 |   // initialize writer
 | 
|---|
| 1346 |   init() ;
 | 
|---|
| 1347 | }
 | 
|---|
| 1348 | 
 | 
|---|
| 1349 | MSWriter::~MSWriter() 
 | 
|---|
| 1350 | {
 | 
|---|
| 1351 |   os_.origin( LogOrigin( "MSWriter", "~MSWriter()", WHERE ) ) ;
 | 
|---|
| 1352 | //   os_ << "MSWriter::~MSWriter()" << LogIO::POST ;
 | 
|---|
| 1353 | 
 | 
|---|
| 1354 |   if ( mstable_ != 0 ) 
 | 
|---|
| 1355 |     delete mstable_ ;
 | 
|---|
| 1356 | }
 | 
|---|
| 1357 | 
 | 
|---|
| 1358 | bool MSWriter::write(const string& filename, const Record& rec) 
 | 
|---|
| 1359 | {
 | 
|---|
| 1360 |   os_.origin( LogOrigin( "MSWriter", "write()", WHERE ) ) ;
 | 
|---|
| 1361 |   //double startSec = mathutil::gettimeofday_sec() ;
 | 
|---|
| 1362 |   //os_ << "start MSWriter::write() startSec=" << startSec << LogIO::POST ;
 | 
|---|
| 1363 | 
 | 
|---|
| 1364 |   filename_ = filename ;
 | 
|---|
| 1365 | 
 | 
|---|
| 1366 |   // parsing MS options
 | 
|---|
| 1367 |   Bool overwrite = False ;
 | 
|---|
| 1368 |   if ( rec.isDefined( "ms" ) ) {
 | 
|---|
| 1369 |     Record msrec = rec.asRecord( "ms" ) ;
 | 
|---|
| 1370 |     if ( msrec.isDefined( "overwrite" ) ) {
 | 
|---|
| 1371 |       overwrite = msrec.asBool( "overwrite" ) ;
 | 
|---|
| 1372 |     }
 | 
|---|
| 1373 |   }
 | 
|---|
| 1374 | 
 | 
|---|
| 1375 |   os_ << "Parsing MS options" << endl ;
 | 
|---|
| 1376 |   os_ << "   overwrite = " << overwrite << LogIO::POST ; 
 | 
|---|
| 1377 | 
 | 
|---|
| 1378 |   File file( filename_ ) ;
 | 
|---|
| 1379 |   if ( file.exists() ) {
 | 
|---|
| 1380 |     if ( overwrite ) {
 | 
|---|
| 1381 |       os_ << filename_ << " exists. Overwrite existing data... " << LogIO::POST ;
 | 
|---|
| 1382 |       if ( file.isRegular() ) RegularFile(file).remove() ;
 | 
|---|
| 1383 |       else if ( file.isDirectory() ) Directory(file).removeRecursive() ;
 | 
|---|
| 1384 |       else SymLink(file).remove() ;
 | 
|---|
| 1385 |     }
 | 
|---|
| 1386 |     else {
 | 
|---|
| 1387 |       os_ << LogIO::SEVERE << "ERROR: " << filename_ << " exists..." << LogIO::POST ;
 | 
|---|
| 1388 |       return False ;
 | 
|---|
| 1389 |     }
 | 
|---|
| 1390 |   }
 | 
|---|
| 1391 | 
 | 
|---|
| 1392 |   // set up MS
 | 
|---|
| 1393 |   setupMS() ;
 | 
|---|
| 1394 |   
 | 
|---|
| 1395 |   // subtables
 | 
|---|
| 1396 |   // OBSERVATION
 | 
|---|
| 1397 |   fillObservation() ;
 | 
|---|
| 1398 | 
 | 
|---|
| 1399 |   // ANTENNA
 | 
|---|
| 1400 |   fillAntenna() ;
 | 
|---|
| 1401 | 
 | 
|---|
| 1402 |   // PROCESSOR
 | 
|---|
| 1403 |   fillProcessor() ;
 | 
|---|
| 1404 | 
 | 
|---|
| 1405 |   // SOURCE
 | 
|---|
| 1406 |   fillSource() ;
 | 
|---|
| 1407 | 
 | 
|---|
| 1408 |   // WEATHER
 | 
|---|
| 1409 |   if ( isWeather_ ) 
 | 
|---|
| 1410 |     fillWeather() ;
 | 
|---|
| 1411 | 
 | 
|---|
| 1412 |   /***
 | 
|---|
| 1413 |    * Start iteration using TableVisitor
 | 
|---|
| 1414 |    ***/
 | 
|---|
| 1415 |   {
 | 
|---|
| 1416 |     static const char *cols[] = {
 | 
|---|
| 1417 |       "FIELDNAME", "BEAMNO", "SCANNO", "IFNO", "SRCTYPE", "CYCLENO", "TIME",
 | 
|---|
| 1418 |       "POLNO",
 | 
|---|
| 1419 |       NULL
 | 
|---|
| 1420 |     };
 | 
|---|
| 1421 |     static const TypeManagerImpl<uInt> tmUInt;
 | 
|---|
| 1422 |     static const TypeManagerImpl<Int> tmInt;
 | 
|---|
| 1423 |     static const TypeManagerImpl<Double> tmDouble;
 | 
|---|
| 1424 |     static const TypeManagerImpl<String> tmString;
 | 
|---|
| 1425 |     static const TypeManager *const tms[] = {
 | 
|---|
| 1426 |       &tmString, &tmUInt, &tmUInt, &tmUInt, &tmInt, &tmUInt, &tmDouble, &tmInt, NULL
 | 
|---|
| 1427 |     };
 | 
|---|
| 1428 |     //double t0 = mathutil::gettimeofday_sec() ;
 | 
|---|
| 1429 |     MSWriterVisitor myVisitor(table_->table(),*mstable_);
 | 
|---|
| 1430 |     //double t1 = mathutil::gettimeofday_sec() ;
 | 
|---|
| 1431 |     //cout << "MSWriterVisitor(): elapsed time " << t1-t0 << " sec" << endl ;
 | 
|---|
| 1432 |     String dataColName = "FLOAT_DATA" ;
 | 
|---|
| 1433 |     if ( useData_ )
 | 
|---|
| 1434 |       dataColName = "DATA" ;
 | 
|---|
| 1435 |     myVisitor.dataColumnName( dataColName ) ;
 | 
|---|
| 1436 |     myVisitor.pointingTableName( ptTabName_ ) ;
 | 
|---|
| 1437 |     myVisitor.setSourceRecord( srcRec_ ) ;
 | 
|---|
| 1438 |     //double t2 = mathutil::gettimeofday_sec() ;
 | 
|---|
| 1439 |     traverseTable(table_->table(), cols, tms, &myVisitor);
 | 
|---|
| 1440 |     //double t3 = mathutil::gettimeofday_sec() ;
 | 
|---|
| 1441 |     //cout << "traverseTable(): elapsed time " << t3-t2 << " sec" << endl ;
 | 
|---|
| 1442 |     map< Int,Vector<uInt> > &idRec = myVisitor.getTcalIdRecord() ;
 | 
|---|
| 1443 |     map< Int,Vector<uInt> > &rowRec = myVisitor.getTcalRowRecord() ;
 | 
|---|
| 1444 | 
 | 
|---|
| 1445 |     // SYSCAL
 | 
|---|
| 1446 |     if ( isTcal_ ) 
 | 
|---|
| 1447 |       fillSysCal( idRec, rowRec ) ;
 | 
|---|
| 1448 |   }
 | 
|---|
| 1449 |   /***
 | 
|---|
| 1450 |    * End iteration using TableVisitor
 | 
|---|
| 1451 |    ***/
 | 
|---|
| 1452 | 
 | 
|---|
| 1453 |   // ASDM tables 
 | 
|---|
| 1454 |   const TableRecord &stKeys = table_->table().keywordSet() ;
 | 
|---|
| 1455 |   TableRecord &msKeys = mstable_->rwKeywordSet() ;
 | 
|---|
| 1456 |   uInt nfields = stKeys.nfields() ;
 | 
|---|
| 1457 |   for ( uInt ifield = 0 ; ifield < nfields ; ifield++ ) {
 | 
|---|
| 1458 |     String kname = stKeys.name( ifield ) ;
 | 
|---|
| 1459 |     if ( kname.find( "ASDM" ) != String::npos ) {
 | 
|---|
| 1460 |       String asdmpath = stKeys.asString( ifield ) ;
 | 
|---|
| 1461 |       os_ << "found ASDM table: " << asdmpath << LogIO::POST ;
 | 
|---|
| 1462 |       if ( Table::isReadable( asdmpath ) ) {
 | 
|---|
| 1463 |         Table newAsdmTab( asdmpath, Table::Old ) ;
 | 
|---|
| 1464 |         newAsdmTab.copy( filename_+"/"+kname, Table::New ) ;
 | 
|---|
| 1465 |         os_ << "add subtable: " << kname << LogIO::POST ;
 | 
|---|
| 1466 |         msKeys.defineTable( kname, Table( filename_+"/"+kname, Table::Old ) ) ;
 | 
|---|
| 1467 |       }
 | 
|---|
| 1468 |     }
 | 
|---|
| 1469 |   }
 | 
|---|
| 1470 | 
 | 
|---|
| 1471 |   // replace POINTING table with original one if exists
 | 
|---|
| 1472 |   if ( ptTabName_ != "" ) {
 | 
|---|
| 1473 |     delete mstable_ ;
 | 
|---|
| 1474 |     mstable_ = 0 ;
 | 
|---|
| 1475 |     Table newPtTab( ptTabName_, Table::Old ) ;
 | 
|---|
| 1476 |     newPtTab.copy( filename_+"/POINTING", Table::New ) ;
 | 
|---|
| 1477 |   }
 | 
|---|
| 1478 | 
 | 
|---|
| 1479 |   //double endSec = mathutil::gettimeofday_sec() ;
 | 
|---|
| 1480 |   //os_ << "end MSWriter::write() endSec=" << endSec << " (" << endSec-startSec << "sec)" << LogIO::POST ;
 | 
|---|
| 1481 | 
 | 
|---|
| 1482 |   return True ;
 | 
|---|
| 1483 | }
 | 
|---|
| 1484 | 
 | 
|---|
| 1485 | void MSWriter::init()
 | 
|---|
| 1486 | {
 | 
|---|
| 1487 | //   os_.origin( LogOrigin( "MSWriter", "init()", WHERE ) ) ;
 | 
|---|
| 1488 | //   double startSec = mathutil::gettimeofday_sec() ;
 | 
|---|
| 1489 | //   os_ << "start MSWriter::init() startSec=" << startSec << LogIO::POST ;
 | 
|---|
| 1490 |   
 | 
|---|
| 1491 |   // access to scantable
 | 
|---|
| 1492 |   header_ = table_->getHeader() ;
 | 
|---|
| 1493 | 
 | 
|---|
| 1494 |   // FLOAT_DATA? or DATA?
 | 
|---|
| 1495 |   if ( header_.npol > 2 ) {
 | 
|---|
| 1496 |     useFloatData_ = False ;
 | 
|---|
| 1497 |     useData_ = True ;
 | 
|---|
| 1498 |   }
 | 
|---|
| 1499 |   else {
 | 
|---|
| 1500 |     useFloatData_ = True ;
 | 
|---|
| 1501 |     useData_ = False ;
 | 
|---|
| 1502 |   }
 | 
|---|
| 1503 | 
 | 
|---|
| 1504 |   // polarization type 
 | 
|---|
| 1505 |   polType_ = header_.poltype ;
 | 
|---|
| 1506 |   if ( polType_ == "" ) 
 | 
|---|
| 1507 |     polType_ = "stokes" ;
 | 
|---|
| 1508 |   else if ( polType_.find( "linear" ) != String::npos ) 
 | 
|---|
| 1509 |     polType_ = "linear" ;
 | 
|---|
| 1510 |   else if ( polType_.find( "circular" ) != String::npos )
 | 
|---|
| 1511 |     polType_ = "circular" ;
 | 
|---|
| 1512 |   else if ( polType_.find( "stokes" ) != String::npos ) 
 | 
|---|
| 1513 |     polType_ = "stokes" ;
 | 
|---|
| 1514 |   else if ( polType_.find( "linpol" ) != String::npos )
 | 
|---|
| 1515 |     polType_ = "linpol" ;
 | 
|---|
| 1516 |   else 
 | 
|---|
| 1517 |     polType_ = "notype" ;
 | 
|---|
| 1518 | 
 | 
|---|
| 1519 |   // Check if some subtables are exists
 | 
|---|
| 1520 |   if ( table_->tcal().table().nrow() != 0 ) {
 | 
|---|
| 1521 |     ROTableColumn col( table_->tcal().table(), "TCAL" ) ;
 | 
|---|
| 1522 |     if ( col.isDefined( 0 ) ) {
 | 
|---|
| 1523 |       os_ << "TCAL table exists: nrow=" << table_->tcal().table().nrow() << LogIO::POST ;
 | 
|---|
| 1524 |       isTcal_ = True ;
 | 
|---|
| 1525 |     }
 | 
|---|
| 1526 |     else {
 | 
|---|
| 1527 |       os_ << "No TCAL rows" << LogIO::POST ;
 | 
|---|
| 1528 |     }
 | 
|---|
| 1529 |   }
 | 
|---|
| 1530 |   else {
 | 
|---|
| 1531 |     os_ << "No TCAL rows" << LogIO::POST ;
 | 
|---|
| 1532 |   }
 | 
|---|
| 1533 |   if ( table_->weather().table().nrow() != 0 ) {
 | 
|---|
| 1534 |     ROTableColumn col( table_->weather().table(), "TEMPERATURE" ) ;
 | 
|---|
| 1535 |     if ( col.isDefined( 0 ) ) {
 | 
|---|
| 1536 |       os_ << "WEATHER table exists: nrow=" << table_->weather().table().nrow() << LogIO::POST ;
 | 
|---|
| 1537 |       isWeather_ =True ;
 | 
|---|
| 1538 |     }
 | 
|---|
| 1539 |     else {
 | 
|---|
| 1540 |       os_ << "No WEATHER rows" << LogIO::POST ;
 | 
|---|
| 1541 |     }
 | 
|---|
| 1542 |   }
 | 
|---|
| 1543 |   else {
 | 
|---|
| 1544 |     os_ << "No WEATHER rows" << LogIO::POST ;
 | 
|---|
| 1545 |   }
 | 
|---|
| 1546 | 
 | 
|---|
| 1547 |   // Are TCAL_SPECTRUM and TSYS_SPECTRUM necessary?
 | 
|---|
| 1548 |   if ( isTcal_ && header_.nchan != 1 ) {
 | 
|---|
| 1549 |     // examine TCAL subtable
 | 
|---|
| 1550 |     Table tcaltab = table_->tcal().table() ;
 | 
|---|
| 1551 |     ROArrayColumn<Float> tcalCol( tcaltab, "TCAL" ) ;
 | 
|---|
| 1552 |     for ( uInt irow = 0 ; irow < tcaltab.nrow() ; irow++ ) {
 | 
|---|
| 1553 |       if ( tcalCol( irow ).size() != 1 )
 | 
|---|
| 1554 |         tcalSpec_ = True ;
 | 
|---|
| 1555 |     }
 | 
|---|
| 1556 |     // examine spectral data
 | 
|---|
| 1557 |     TableIterator iter0( table_->table(), "IFNO" ) ;
 | 
|---|
| 1558 |     while( !iter0.pastEnd() ) {
 | 
|---|
| 1559 |       Table t0( iter0.table() ) ;
 | 
|---|
| 1560 |       ROArrayColumn<Float> sharedFloatArrCol( t0, "SPECTRA" ) ;
 | 
|---|
| 1561 |       uInt len = sharedFloatArrCol( 0 ).size() ;
 | 
|---|
| 1562 |       if ( len != 1 ) {
 | 
|---|
| 1563 |         sharedFloatArrCol.attach( t0, "TSYS" ) ;
 | 
|---|
| 1564 |         if ( sharedFloatArrCol( 0 ).size() != 1 ) 
 | 
|---|
| 1565 |           tsysSpec_ = True ;
 | 
|---|
| 1566 |       }
 | 
|---|
| 1567 |       iter0.next() ;
 | 
|---|
| 1568 |     }
 | 
|---|
| 1569 |   }
 | 
|---|
| 1570 | 
 | 
|---|
| 1571 |   // check if reference for POINTING table exists
 | 
|---|
| 1572 |   const TableRecord &rec = table_->table().keywordSet() ;
 | 
|---|
| 1573 |   if ( rec.isDefined( "POINTING" ) ) {
 | 
|---|
| 1574 |     ptTabName_ = rec.asString( "POINTING" ) ;
 | 
|---|
| 1575 |     if ( !Table::isReadable( ptTabName_ ) ) {
 | 
|---|
| 1576 |       ptTabName_ = "" ;
 | 
|---|
| 1577 |     }
 | 
|---|
| 1578 |   }
 | 
|---|
| 1579 | 
 | 
|---|
| 1580 | //   double endSec = mathutil::gettimeofday_sec() ;
 | 
|---|
| 1581 | //   os_ << "end MSWriter::init() endSec=" << endSec << " (" << endSec-startSec << "sec)" << LogIO::POST ;
 | 
|---|
| 1582 | }
 | 
|---|
| 1583 | 
 | 
|---|
| 1584 | void MSWriter::setupMS()
 | 
|---|
| 1585 | {
 | 
|---|
| 1586 | //   os_.origin( LogOrigin( "MSWriter", "setupMS()", WHERE ) ) ;
 | 
|---|
| 1587 | //   double startSec = mathutil::gettimeofday_sec() ;
 | 
|---|
| 1588 | //   os_ << "start MSWriter::setupMS() startSec=" << startSec << LogIO::POST ;
 | 
|---|
| 1589 |   
 | 
|---|
| 1590 |   String dunit = table_->getHeader().fluxunit ;
 | 
|---|
| 1591 | 
 | 
|---|
| 1592 |   TableDesc msDesc = MeasurementSet::requiredTableDesc() ;
 | 
|---|
| 1593 |   if ( useFloatData_ )
 | 
|---|
| 1594 |     MeasurementSet::addColumnToDesc( msDesc, MSMainEnums::FLOAT_DATA, 2 ) ;
 | 
|---|
| 1595 |   else if ( useData_ )
 | 
|---|
| 1596 |     MeasurementSet::addColumnToDesc( msDesc, MSMainEnums::DATA, 2 ) ;
 | 
|---|
| 1597 | 
 | 
|---|
| 1598 |   SetupNewTable newtab( filename_, msDesc, Table::New ) ;
 | 
|---|
| 1599 | 
 | 
|---|
| 1600 |   mstable_ = new MeasurementSet( newtab ) ;
 | 
|---|
| 1601 | 
 | 
|---|
| 1602 |   TableColumn col ;
 | 
|---|
| 1603 |   if ( useFloatData_ )
 | 
|---|
| 1604 |     col.attach( *mstable_, "FLOAT_DATA" ) ;
 | 
|---|
| 1605 |   else if ( useData_ )
 | 
|---|
| 1606 |     col.attach( *mstable_, "DATA" ) ;
 | 
|---|
| 1607 |   col.rwKeywordSet().define( "UNIT", dunit ) ;
 | 
|---|
| 1608 | 
 | 
|---|
| 1609 |   // create subtables
 | 
|---|
| 1610 |   TableDesc antennaDesc = MSAntenna::requiredTableDesc() ;
 | 
|---|
| 1611 |   SetupNewTable antennaTab( mstable_->antennaTableName(), antennaDesc, Table::New ) ;
 | 
|---|
| 1612 |   mstable_->rwKeywordSet().defineTable( MeasurementSet::keywordName( MeasurementSet::ANTENNA ), Table( antennaTab ) ) ;
 | 
|---|
| 1613 | 
 | 
|---|
| 1614 |   TableDesc dataDescDesc = MSDataDescription::requiredTableDesc() ;
 | 
|---|
| 1615 |   SetupNewTable dataDescTab( mstable_->dataDescriptionTableName(), dataDescDesc, Table::New ) ;
 | 
|---|
| 1616 |   mstable_->rwKeywordSet().defineTable( MeasurementSet::keywordName( MeasurementSet::DATA_DESCRIPTION ), Table( dataDescTab ) ) ;
 | 
|---|
| 1617 | 
 | 
|---|
| 1618 |   TableDesc dopplerDesc = MSDoppler::requiredTableDesc() ;
 | 
|---|
| 1619 |   SetupNewTable dopplerTab( mstable_->dopplerTableName(), dopplerDesc, Table::New ) ;
 | 
|---|
| 1620 |   mstable_->rwKeywordSet().defineTable( MeasurementSet::keywordName( MeasurementSet::DOPPLER ), Table( dopplerTab ) ) ;
 | 
|---|
| 1621 | 
 | 
|---|
| 1622 |   TableDesc feedDesc = MSFeed::requiredTableDesc() ;
 | 
|---|
| 1623 |   SetupNewTable feedTab( mstable_->feedTableName(), feedDesc, Table::New ) ;
 | 
|---|
| 1624 |   mstable_->rwKeywordSet().defineTable( MeasurementSet::keywordName( MeasurementSet::FEED ), Table( feedTab ) ) ;
 | 
|---|
| 1625 | 
 | 
|---|
| 1626 |   TableDesc fieldDesc = MSField::requiredTableDesc() ;
 | 
|---|
| 1627 |   SetupNewTable fieldTab( mstable_->fieldTableName(), fieldDesc, Table::New ) ;
 | 
|---|
| 1628 |   mstable_->rwKeywordSet().defineTable( MeasurementSet::keywordName( MeasurementSet::FIELD ), Table( fieldTab ) ) ;
 | 
|---|
| 1629 | 
 | 
|---|
| 1630 |   TableDesc flagCmdDesc = MSFlagCmd::requiredTableDesc() ;
 | 
|---|
| 1631 |   SetupNewTable flagCmdTab( mstable_->flagCmdTableName(), flagCmdDesc, Table::New ) ;
 | 
|---|
| 1632 |   mstable_->rwKeywordSet().defineTable( MeasurementSet::keywordName( MeasurementSet::FLAG_CMD ), Table( flagCmdTab ) ) ;
 | 
|---|
| 1633 | 
 | 
|---|
| 1634 |   TableDesc freqOffsetDesc = MSFreqOffset::requiredTableDesc() ;
 | 
|---|
| 1635 |   SetupNewTable freqOffsetTab( mstable_->freqOffsetTableName(), freqOffsetDesc, Table::New ) ;
 | 
|---|
| 1636 |   mstable_->rwKeywordSet().defineTable( MeasurementSet::keywordName( MeasurementSet::FREQ_OFFSET ), Table( freqOffsetTab ) ) ;
 | 
|---|
| 1637 | 
 | 
|---|
| 1638 |   TableDesc historyDesc = MSHistory::requiredTableDesc() ;
 | 
|---|
| 1639 |   SetupNewTable historyTab( mstable_->historyTableName(), historyDesc, Table::New ) ;
 | 
|---|
| 1640 |   mstable_->rwKeywordSet().defineTable( MeasurementSet::keywordName( MeasurementSet::HISTORY ), Table( historyTab ) ) ;
 | 
|---|
| 1641 | 
 | 
|---|
| 1642 |   TableDesc observationDesc = MSObservation::requiredTableDesc() ;
 | 
|---|
| 1643 |   SetupNewTable observationTab( mstable_->observationTableName(), observationDesc, Table::New ) ;
 | 
|---|
| 1644 |   mstable_->rwKeywordSet().defineTable( MeasurementSet::keywordName( MeasurementSet::OBSERVATION ), Table( observationTab ) ) ;
 | 
|---|
| 1645 | 
 | 
|---|
| 1646 |   TableDesc pointingDesc = MSPointing::requiredTableDesc() ;
 | 
|---|
| 1647 |   SetupNewTable pointingTab( mstable_->pointingTableName(), pointingDesc, Table::New ) ;
 | 
|---|
| 1648 |   mstable_->rwKeywordSet().defineTable( MeasurementSet::keywordName( MeasurementSet::POINTING ), Table( pointingTab ) ) ;
 | 
|---|
| 1649 | 
 | 
|---|
| 1650 |   TableDesc polarizationDesc = MSPolarization::requiredTableDesc() ;
 | 
|---|
| 1651 |   SetupNewTable polarizationTab( mstable_->polarizationTableName(), polarizationDesc, Table::New ) ;
 | 
|---|
| 1652 |   mstable_->rwKeywordSet().defineTable( MeasurementSet::keywordName( MeasurementSet::POLARIZATION ), Table( polarizationTab ) ) ;
 | 
|---|
| 1653 | 
 | 
|---|
| 1654 |   TableDesc processorDesc = MSProcessor::requiredTableDesc() ;
 | 
|---|
| 1655 |   SetupNewTable processorTab( mstable_->processorTableName(), processorDesc, Table::New ) ;
 | 
|---|
| 1656 |   mstable_->rwKeywordSet().defineTable( MeasurementSet::keywordName( MeasurementSet::PROCESSOR ), Table( processorTab ) ) ;
 | 
|---|
| 1657 | 
 | 
|---|
| 1658 |   TableDesc sourceDesc = MSSource::requiredTableDesc() ;
 | 
|---|
| 1659 |   MSSource::addColumnToDesc( sourceDesc, MSSourceEnums::TRANSITION, 1 ) ;
 | 
|---|
| 1660 |   MSSource::addColumnToDesc( sourceDesc, MSSourceEnums::REST_FREQUENCY, 1 ) ;
 | 
|---|
| 1661 |   MSSource::addColumnToDesc( sourceDesc, MSSourceEnums::SYSVEL, 1 ) ;
 | 
|---|
| 1662 |   SetupNewTable sourceTab( mstable_->sourceTableName(), sourceDesc, Table::New ) ;
 | 
|---|
| 1663 |   mstable_->rwKeywordSet().defineTable( MeasurementSet::keywordName( MeasurementSet::SOURCE ), Table( sourceTab ) ) ;
 | 
|---|
| 1664 | 
 | 
|---|
| 1665 |   TableDesc spwDesc = MSSpectralWindow::requiredTableDesc() ;
 | 
|---|
| 1666 |   SetupNewTable spwTab( mstable_->spectralWindowTableName(), spwDesc, Table::New ) ;
 | 
|---|
| 1667 |   mstable_->rwKeywordSet().defineTable( MeasurementSet::keywordName( MeasurementSet::SPECTRAL_WINDOW ), Table( spwTab ) ) ;
 | 
|---|
| 1668 | 
 | 
|---|
| 1669 |   TableDesc stateDesc = MSState::requiredTableDesc() ;
 | 
|---|
| 1670 |   SetupNewTable stateTab( mstable_->stateTableName(), stateDesc, Table::New ) ;
 | 
|---|
| 1671 |   mstable_->rwKeywordSet().defineTable( MeasurementSet::keywordName( MeasurementSet::STATE ), Table( stateTab ) ) ;
 | 
|---|
| 1672 | 
 | 
|---|
| 1673 |   // TODO: add TCAL_SPECTRUM and TSYS_SPECTRUM if necessary
 | 
|---|
| 1674 |   TableDesc sysCalDesc = MSSysCal::requiredTableDesc() ;
 | 
|---|
| 1675 |   MSSysCal::addColumnToDesc( sysCalDesc, MSSysCalEnums::TCAL, 2 ) ;
 | 
|---|
| 1676 |   MSSysCal::addColumnToDesc( sysCalDesc, MSSysCalEnums::TSYS, 2 ) ;
 | 
|---|
| 1677 |   if ( tcalSpec_ ) 
 | 
|---|
| 1678 |     MSSysCal::addColumnToDesc( sysCalDesc, MSSysCalEnums::TCAL_SPECTRUM, 2 ) ;
 | 
|---|
| 1679 |   if ( tsysSpec_ )
 | 
|---|
| 1680 |     MSSysCal::addColumnToDesc( sysCalDesc, MSSysCalEnums::TSYS_SPECTRUM, 2 ) ;
 | 
|---|
| 1681 |   SetupNewTable sysCalTab( mstable_->sysCalTableName(), sysCalDesc, Table::New ) ;
 | 
|---|
| 1682 |   mstable_->rwKeywordSet().defineTable( MeasurementSet::keywordName( MeasurementSet::SYSCAL ), Table( sysCalTab ) ) ;
 | 
|---|
| 1683 | 
 | 
|---|
| 1684 |   TableDesc weatherDesc = MSWeather::requiredTableDesc() ;
 | 
|---|
| 1685 |   MSWeather::addColumnToDesc( weatherDesc, MSWeatherEnums::TEMPERATURE ) ;
 | 
|---|
| 1686 |   MSWeather::addColumnToDesc( weatherDesc, MSWeatherEnums::PRESSURE ) ;
 | 
|---|
| 1687 |   MSWeather::addColumnToDesc( weatherDesc, MSWeatherEnums::REL_HUMIDITY ) ;
 | 
|---|
| 1688 |   MSWeather::addColumnToDesc( weatherDesc, MSWeatherEnums::WIND_SPEED ) ;
 | 
|---|
| 1689 |   MSWeather::addColumnToDesc( weatherDesc, MSWeatherEnums::WIND_DIRECTION ) ;
 | 
|---|
| 1690 |   SetupNewTable weatherTab( mstable_->weatherTableName(), weatherDesc, Table::New ) ;
 | 
|---|
| 1691 |   mstable_->rwKeywordSet().defineTable( MeasurementSet::keywordName( MeasurementSet::WEATHER ), Table( weatherTab ) ) ;
 | 
|---|
| 1692 | 
 | 
|---|
| 1693 |   mstable_->initRefs() ;
 | 
|---|
| 1694 | 
 | 
|---|
| 1695 | //   double endSec = mathutil::gettimeofday_sec() ;
 | 
|---|
| 1696 | //   os_ << "end MSWriter::setupMS() endSec=" << endSec << " (" << endSec-startSec << "sec)" << LogIO::POST ;
 | 
|---|
| 1697 | }
 | 
|---|
| 1698 | 
 | 
|---|
| 1699 | void MSWriter::fillObservation() 
 | 
|---|
| 1700 | {
 | 
|---|
| 1701 |   //double startSec = mathutil::gettimeofday_sec() ;
 | 
|---|
| 1702 |   //os_ << "start MSWriter::fillObservation() startSec=" << startSec << LogIO::POST ;
 | 
|---|
| 1703 | 
 | 
|---|
| 1704 |   // only 1 row
 | 
|---|
| 1705 |   mstable_->observation().addRow( 1, True ) ;
 | 
|---|
| 1706 |   MSObservationColumns msObsCols( mstable_->observation() ) ;
 | 
|---|
| 1707 |   msObsCols.observer().put( 0, header_.observer ) ;
 | 
|---|
| 1708 |   // tentatively put antennaname (from ANTENNA subtable)
 | 
|---|
| 1709 |   String hAntennaName = header_.antennaname ;
 | 
|---|
| 1710 |   String::size_type pos = hAntennaName.find( "//" ) ;
 | 
|---|
| 1711 |   String telescopeName ;
 | 
|---|
| 1712 |   if ( pos != String::npos ) {
 | 
|---|
| 1713 |     telescopeName = hAntennaName.substr( 0, pos ) ;
 | 
|---|
| 1714 |   }
 | 
|---|
| 1715 |   else {
 | 
|---|
| 1716 |     pos = hAntennaName.find( "@" ) ;
 | 
|---|
| 1717 |     telescopeName = hAntennaName.substr( 0, pos ) ;
 | 
|---|
| 1718 |   }
 | 
|---|
| 1719 | //   os_ << "telescopeName = " << telescopeName << LogIO::POST ;
 | 
|---|
| 1720 |   msObsCols.telescopeName().put( 0, telescopeName ) ;
 | 
|---|
| 1721 |   msObsCols.project().put( 0, header_.project ) ;
 | 
|---|
| 1722 |   //ScalarMeasColumn<MEpoch> timeCol( table_->table().sort("TIME"), "TIME" ) ;
 | 
|---|
| 1723 |   Table sortedtable = table_->table().sort("TIME") ;
 | 
|---|
| 1724 |   ScalarMeasColumn<MEpoch> timeCol( sortedtable, "TIME" ) ;
 | 
|---|
| 1725 |   Vector<MEpoch> trange( 2 ) ;
 | 
|---|
| 1726 |   trange[0] = timeCol( 0 ) ;
 | 
|---|
| 1727 |   trange[1] = timeCol( table_->nrow()-1 ) ;
 | 
|---|
| 1728 |   msObsCols.timeRangeMeas().put( 0, trange ) ;
 | 
|---|
| 1729 | 
 | 
|---|
| 1730 |   //double endSec = mathutil::gettimeofday_sec() ;
 | 
|---|
| 1731 |   //os_ << "end MSWriter::fillObservation() endSec=" << endSec << " (" << endSec-startSec << "sec)" << LogIO::POST ;
 | 
|---|
| 1732 | }
 | 
|---|
| 1733 | 
 | 
|---|
| 1734 | void MSWriter::antennaProperty( String &name, String &m, String &t, Double &d )
 | 
|---|
| 1735 | {
 | 
|---|
| 1736 |   name.upcase() ;
 | 
|---|
| 1737 |   
 | 
|---|
| 1738 |   m = "ALT-AZ" ;
 | 
|---|
| 1739 |   t = "GROUND-BASED" ;
 | 
|---|
| 1740 |   if ( name.matches( Regex( "DV[0-9]+$" ) ) 
 | 
|---|
| 1741 |        || name.matches( Regex( "DA[0-9]+$" ) )
 | 
|---|
| 1742 |        || name.matches( Regex( "PM[0-9]+$" ) ) )
 | 
|---|
| 1743 |     d = 12.0 ;
 | 
|---|
| 1744 |   else if ( name.matches( Regex( "CM[0-9]+$" ) ) )
 | 
|---|
| 1745 |     d = 7.0 ;
 | 
|---|
| 1746 |   else if ( name.contains( "GBT" ) ) 
 | 
|---|
| 1747 |     d = 104.9 ;
 | 
|---|
| 1748 |   else if ( name.contains( "MOPRA" ) )
 | 
|---|
| 1749 |     d = 22.0 ;
 | 
|---|
| 1750 |   else if ( name.contains( "PKS" ) || name.contains( "PARKS" ) )
 | 
|---|
| 1751 |     d = 64.0 ;
 | 
|---|
| 1752 |   else if ( name.contains( "TIDBINBILLA" ) ) 
 | 
|---|
| 1753 |     d = 70.0 ;
 | 
|---|
| 1754 |   else if ( name.contains( "CEDUNA" ) )
 | 
|---|
| 1755 |     d = 30.0 ;
 | 
|---|
| 1756 |   else if ( name.contains( "HOBART" ) ) 
 | 
|---|
| 1757 |     d = 26.0 ;
 | 
|---|
| 1758 |   else if ( name.contains( "APEX" ) ) 
 | 
|---|
| 1759 |     d = 12.0 ;
 | 
|---|
| 1760 |   else if ( name.contains( "ASTE" ) ) 
 | 
|---|
| 1761 |     d = 10.0 ;
 | 
|---|
| 1762 |   else if ( name.contains( "NRO" ) ) 
 | 
|---|
| 1763 |     d = 45.0 ;
 | 
|---|
| 1764 |   else 
 | 
|---|
| 1765 |     d = 1.0 ;
 | 
|---|
| 1766 | } 
 | 
|---|
| 1767 | 
 | 
|---|
| 1768 | void MSWriter::fillAntenna() 
 | 
|---|
| 1769 | {
 | 
|---|
| 1770 |   //double startSec = mathutil::gettimeofday_sec() ;
 | 
|---|
| 1771 |   //os_ << "start MSWriter::fillAntenna() startSec=" << startSec << LogIO::POST ;
 | 
|---|
| 1772 | 
 | 
|---|
| 1773 |   // only 1 row
 | 
|---|
| 1774 |   Table anttab = mstable_->antenna() ;
 | 
|---|
| 1775 |   anttab.addRow( 1, True ) ;
 | 
|---|
| 1776 |   
 | 
|---|
| 1777 |   Table &table = table_->table() ;
 | 
|---|
| 1778 |   const TableRecord &keys = table.keywordSet() ;
 | 
|---|
| 1779 |   String hAntName = keys.asString( "AntennaName" ) ;
 | 
|---|
| 1780 |   String::size_type pos = hAntName.find( "//" ) ;
 | 
|---|
| 1781 |   String antennaName ;
 | 
|---|
| 1782 |   String stationName ;
 | 
|---|
| 1783 |   if ( pos != String::npos ) {
 | 
|---|
| 1784 |     stationName = hAntName.substr( 0, pos ) ;
 | 
|---|
| 1785 |     hAntName = hAntName.substr( pos+2 ) ;
 | 
|---|
| 1786 |   }
 | 
|---|
| 1787 |   pos = hAntName.find( "@" ) ;
 | 
|---|
| 1788 |   if ( pos != String::npos ) {
 | 
|---|
| 1789 |     antennaName = hAntName.substr( 0, pos ) ;
 | 
|---|
| 1790 |     stationName = hAntName.substr( pos+1 ) ;
 | 
|---|
| 1791 |   }
 | 
|---|
| 1792 |   else {
 | 
|---|
| 1793 |     antennaName = hAntName ;
 | 
|---|
| 1794 |   }
 | 
|---|
| 1795 |   Vector<Double> antpos = keys.asArrayDouble( "AntennaPosition" ) ;
 | 
|---|
| 1796 |   
 | 
|---|
| 1797 |   String mount, atype ;
 | 
|---|
| 1798 |   Double diameter ;
 | 
|---|
| 1799 |   antennaProperty( antennaName, mount, atype, diameter ) ;
 | 
|---|
| 1800 |   
 | 
|---|
| 1801 |   TableRow tr( anttab ) ;
 | 
|---|
| 1802 |   TableRecord &r = tr.record() ;
 | 
|---|
| 1803 |   RecordFieldPtr<String> nameRF( r, "NAME" ) ;
 | 
|---|
| 1804 |   RecordFieldPtr<String> stationRF( r, "STATION" ) ;
 | 
|---|
| 1805 |   RecordFieldPtr<String> mountRF( r, "NAME" ) ;
 | 
|---|
| 1806 |   RecordFieldPtr<String> typeRF( r, "TYPE" ) ;
 | 
|---|
| 1807 |   RecordFieldPtr<Double> dishDiameterRF( r, "DISH_DIAMETER" ) ;
 | 
|---|
| 1808 |   RecordFieldPtr< Vector<Double> > positionRF( r, "POSITION" ) ;
 | 
|---|
| 1809 |   *nameRF = antennaName ;
 | 
|---|
| 1810 |   *mountRF = mount ;
 | 
|---|
| 1811 |   *typeRF = atype ;
 | 
|---|
| 1812 |   *dishDiameterRF = diameter ;
 | 
|---|
| 1813 |   *positionRF = antpos ;
 | 
|---|
| 1814 |   
 | 
|---|
| 1815 |   tr.put( 0 ) ;
 | 
|---|
| 1816 | 
 | 
|---|
| 1817 |   //double endSec = mathutil::gettimeofday_sec() ;
 | 
|---|
| 1818 |   //os_ << "end MSWriter::fillAntenna() endSec=" << endSec << " (" << endSec-startSec << "sec)" << LogIO::POST ;
 | 
|---|
| 1819 | }
 | 
|---|
| 1820 |   
 | 
|---|
| 1821 | void MSWriter::fillProcessor() 
 | 
|---|
| 1822 | {
 | 
|---|
| 1823 | //   double startSec = mathutil::gettimeofday_sec() ;
 | 
|---|
| 1824 | //   os_ << "start MSWriter::fillProcessor() startSec=" << startSec << LogIO::POST ;
 | 
|---|
| 1825 |   
 | 
|---|
| 1826 |   // only add empty 1 row
 | 
|---|
| 1827 |   MSProcessor msProc = mstable_->processor() ;
 | 
|---|
| 1828 |   msProc.addRow( 1, True ) ;
 | 
|---|
| 1829 | 
 | 
|---|
| 1830 | //   double endSec = mathutil::gettimeofday_sec() ;
 | 
|---|
| 1831 | //   os_ << "end MSWriter::fillProcessor() endSec=" << endSec << " (" << endSec-startSec << "sec)" << LogIO::POST ;
 | 
|---|
| 1832 | }
 | 
|---|
| 1833 | 
 | 
|---|
| 1834 | void MSWriter::fillSource()
 | 
|---|
| 1835 | {
 | 
|---|
| 1836 | //   double startSec = mathutil::gettimeofday_sec() ;
 | 
|---|
| 1837 | //   os_ << "start MSWriter::fillSource() startSec=" << startSec << LogIO::POST ;
 | 
|---|
| 1838 |  
 | 
|---|
| 1839 |   // access to MS SOURCE subtable
 | 
|---|
| 1840 |   MSSource msSrc = mstable_->source() ;
 | 
|---|
| 1841 | 
 | 
|---|
| 1842 |   // access to MOLECULE subtable
 | 
|---|
| 1843 |   STMolecules stm = table_->molecules() ;
 | 
|---|
| 1844 | 
 | 
|---|
| 1845 |   Int srcId = 0 ;
 | 
|---|
| 1846 |   Vector<Double> restFreq ;
 | 
|---|
| 1847 |   Vector<String> molName ;
 | 
|---|
| 1848 |   Vector<String> fMolName ;
 | 
|---|
| 1849 | 
 | 
|---|
| 1850 |   // row based
 | 
|---|
| 1851 |   TableRow row( msSrc ) ;
 | 
|---|
| 1852 |   TableRecord &rec = row.record() ;
 | 
|---|
| 1853 |   RecordFieldPtr<Int> srcidRF( rec, "SOURCE_ID" ) ;
 | 
|---|
| 1854 |   RecordFieldPtr<String> nameRF( rec, "NAME" ) ;
 | 
|---|
| 1855 |   RecordFieldPtr< Array<Double> > srcpmRF( rec, "PROPER_MOTION" ) ;
 | 
|---|
| 1856 |   RecordFieldPtr< Array<Double> > srcdirRF( rec, "DIRECTION" ) ;
 | 
|---|
| 1857 |   RecordFieldPtr<Int> numlineRF( rec, "NUM_LINES" ) ;
 | 
|---|
| 1858 |   RecordFieldPtr< Array<Double> > restfreqRF( rec, "REST_FREQUENCY" ) ;
 | 
|---|
| 1859 |   RecordFieldPtr< Array<Double> > sysvelRF( rec, "SYSVEL" ) ;
 | 
|---|
| 1860 |   RecordFieldPtr< Array<String> > transitionRF( rec, "TRANSITION" ) ;
 | 
|---|
| 1861 |   RecordFieldPtr<Double> timeRF( rec, "TIME" ) ;
 | 
|---|
| 1862 |   RecordFieldPtr<Double> intervalRF( rec, "INTERVAL" ) ;
 | 
|---|
| 1863 |   RecordFieldPtr<Int> spwidRF( rec, "SPECTRAL_WINDOW_ID" ) ;
 | 
|---|
| 1864 | 
 | 
|---|
| 1865 |   // 
 | 
|---|
| 1866 |   // ITERATION: SRCNAME
 | 
|---|
| 1867 |   //
 | 
|---|
| 1868 |   TableIterator iter0( table_->table(), "SRCNAME" ) ;
 | 
|---|
| 1869 |   while( !iter0.pastEnd() ) {
 | 
|---|
| 1870 |     //Table t0( iter0.table() ) ;
 | 
|---|
| 1871 |     Table t0 =  iter0.table()  ;
 | 
|---|
| 1872 | 
 | 
|---|
| 1873 |     // get necessary information
 | 
|---|
| 1874 |     ROScalarColumn<String> srcNameCol( t0, "SRCNAME" ) ;
 | 
|---|
| 1875 |     String srcName = srcNameCol( 0 ) ;
 | 
|---|
| 1876 |     ROArrayColumn<Double> sharedDArrRCol( t0, "SRCPROPERMOTION" ) ;
 | 
|---|
| 1877 |     Vector<Double> srcPM = sharedDArrRCol( 0 ) ;
 | 
|---|
| 1878 |     sharedDArrRCol.attach( t0, "SRCDIRECTION" ) ;
 | 
|---|
| 1879 |     Vector<Double> srcDir = sharedDArrRCol( 0 ) ;
 | 
|---|
| 1880 |     ROScalarColumn<Double> srcVelCol( t0, "SRCVELOCITY" ) ;
 | 
|---|
| 1881 |     Double srcVel = srcVelCol( 0 ) ;
 | 
|---|
| 1882 |     srcRec_.define( srcName, srcId ) ;
 | 
|---|
| 1883 | 
 | 
|---|
| 1884 |     // NAME
 | 
|---|
| 1885 |     *nameRF = srcName ;
 | 
|---|
| 1886 | 
 | 
|---|
| 1887 |     // SOURCE_ID
 | 
|---|
| 1888 |     *srcidRF = srcId ;
 | 
|---|
| 1889 | 
 | 
|---|
| 1890 |     // PROPER_MOTION
 | 
|---|
| 1891 |     *srcpmRF = srcPM ;
 | 
|---|
| 1892 |     
 | 
|---|
| 1893 |     // DIRECTION
 | 
|---|
| 1894 |     *srcdirRF = srcDir ;
 | 
|---|
| 1895 | 
 | 
|---|
| 1896 |     //
 | 
|---|
| 1897 |     // ITERATION: MOLECULE_ID
 | 
|---|
| 1898 |     //
 | 
|---|
| 1899 |     TableIterator iter1( t0, "MOLECULE_ID" ) ;
 | 
|---|
| 1900 |     while( !iter1.pastEnd() ) {
 | 
|---|
| 1901 |       //Table t1( iter1.table() ) ;
 | 
|---|
| 1902 |       Table t1 = iter1.table() ;
 | 
|---|
| 1903 | 
 | 
|---|
| 1904 |       // get necessary information
 | 
|---|
| 1905 |       ROScalarColumn<uInt> molIdCol( t1, "MOLECULE_ID" ) ;
 | 
|---|
| 1906 |       uInt molId = molIdCol( 0 ) ;
 | 
|---|
| 1907 |       stm.getEntry( restFreq, molName, fMolName, molId ) ;
 | 
|---|
| 1908 | 
 | 
|---|
| 1909 |       uInt numFreq = restFreq.size() ;
 | 
|---|
| 1910 |       
 | 
|---|
| 1911 |       // NUM_LINES
 | 
|---|
| 1912 |       *numlineRF = numFreq ;
 | 
|---|
| 1913 | 
 | 
|---|
| 1914 |       // REST_FREQUENCY
 | 
|---|
| 1915 |       *restfreqRF = restFreq ;
 | 
|---|
| 1916 | 
 | 
|---|
| 1917 |       // TRANSITION
 | 
|---|
| 1918 |       //*transitionRF = fMolName ;
 | 
|---|
| 1919 |       Vector<String> transition ;
 | 
|---|
| 1920 |       if ( fMolName.size() != 0 ) {
 | 
|---|
| 1921 |         transition = fMolName ;
 | 
|---|
| 1922 |       }
 | 
|---|
| 1923 |       else if ( molName.size() != 0 ) {
 | 
|---|
| 1924 |         transition = molName ;
 | 
|---|
| 1925 |       }
 | 
|---|
| 1926 |       else {
 | 
|---|
| 1927 |         transition.resize( numFreq ) ;
 | 
|---|
| 1928 |         transition = "" ;
 | 
|---|
| 1929 |       }
 | 
|---|
| 1930 |       *transitionRF = transition ;
 | 
|---|
| 1931 | 
 | 
|---|
| 1932 |       // SYSVEL 
 | 
|---|
| 1933 |       Vector<Double> sysvelArr( numFreq, srcVel ) ;
 | 
|---|
| 1934 |       *sysvelRF = sysvelArr ;
 | 
|---|
| 1935 | 
 | 
|---|
| 1936 |       //
 | 
|---|
| 1937 |       // ITERATION: IFNO
 | 
|---|
| 1938 |       //
 | 
|---|
| 1939 |       TableIterator iter2( t1, "IFNO" ) ;
 | 
|---|
| 1940 |       while( !iter2.pastEnd() ) {
 | 
|---|
| 1941 |         //Table t2( iter2.table() ) ;
 | 
|---|
| 1942 |         Table t2 = iter2.table() ;
 | 
|---|
| 1943 |         uInt nrow = msSrc.nrow() ;
 | 
|---|
| 1944 | 
 | 
|---|
| 1945 |         // get necessary information
 | 
|---|
| 1946 |         ROScalarColumn<uInt> ifNoCol( t2, "IFNO" ) ;
 | 
|---|
| 1947 |         uInt ifno = ifNoCol( 0 ) ; // IFNO = SPECTRAL_WINDOW_ID
 | 
|---|
| 1948 |         Double midTime ;
 | 
|---|
| 1949 |         Double interval ;
 | 
|---|
| 1950 |         getValidTimeRange( midTime, interval, t2 ) ;
 | 
|---|
| 1951 | 
 | 
|---|
| 1952 |         // fill SPECTRAL_WINDOW_ID
 | 
|---|
| 1953 |         *spwidRF = ifno ;
 | 
|---|
| 1954 | 
 | 
|---|
| 1955 |         // fill TIME, INTERVAL
 | 
|---|
| 1956 |         *timeRF = midTime ;
 | 
|---|
| 1957 |         *intervalRF = interval ;
 | 
|---|
| 1958 | 
 | 
|---|
| 1959 |         // add row
 | 
|---|
| 1960 |         msSrc.addRow( 1, True ) ;
 | 
|---|
| 1961 |         row.put( nrow ) ;
 | 
|---|
| 1962 | 
 | 
|---|
| 1963 |         iter2.next() ;
 | 
|---|
| 1964 |       }
 | 
|---|
| 1965 | 
 | 
|---|
| 1966 |       iter1.next() ;
 | 
|---|
| 1967 |     }
 | 
|---|
| 1968 | 
 | 
|---|
| 1969 |     // increment srcId if SRCNAME changed
 | 
|---|
| 1970 |     srcId++ ;
 | 
|---|
| 1971 | 
 | 
|---|
| 1972 |     iter0.next() ;
 | 
|---|
| 1973 |   }
 | 
|---|
| 1974 | 
 | 
|---|
| 1975 | //   double endSec = mathutil::gettimeofday_sec() ;
 | 
|---|
| 1976 | //   os_ << "end MSWriter::fillSource() endSec=" << endSec << " (" << endSec-startSec << "sec)" << LogIO::POST ;
 | 
|---|
| 1977 | }
 | 
|---|
| 1978 | 
 | 
|---|
| 1979 | void MSWriter::fillWeather() 
 | 
|---|
| 1980 | {
 | 
|---|
| 1981 | //   double startSec = mathutil::gettimeofday_sec() ;
 | 
|---|
| 1982 | //   os_ << "start MSWriter::fillWeather() startSec=" << startSec << LogIO::POST ;
 | 
|---|
| 1983 | 
 | 
|---|
| 1984 |   // access to MS WEATHER subtable
 | 
|---|
| 1985 |   MSWeather msw = mstable_->weather() ;
 | 
|---|
| 1986 | 
 | 
|---|
| 1987 |   // access to WEATHER subtable
 | 
|---|
| 1988 |   Table stw = table_->weather().table() ;
 | 
|---|
| 1989 |   uInt nrow = stw.nrow() ;
 | 
|---|
| 1990 | 
 | 
|---|
| 1991 |   if ( nrow == 0 ) 
 | 
|---|
| 1992 |     return ;
 | 
|---|
| 1993 | 
 | 
|---|
| 1994 |   msw.addRow( nrow, True ) ;
 | 
|---|
| 1995 |   MSWeatherColumns mswCols( msw ) ;
 | 
|---|
| 1996 | 
 | 
|---|
| 1997 |   // ANTENNA_ID is always 0
 | 
|---|
| 1998 |   Vector<Int> antIdArr( nrow, 0 ) ;
 | 
|---|
| 1999 |   mswCols.antennaId().putColumn( antIdArr ) ;
 | 
|---|
| 2000 | 
 | 
|---|
| 2001 |   // fill weather status
 | 
|---|
| 2002 |   ROScalarColumn<Float> sharedFloatCol( stw, "TEMPERATURE" ) ;
 | 
|---|
| 2003 |   mswCols.temperature().putColumn( sharedFloatCol ) ;
 | 
|---|
| 2004 |   sharedFloatCol.attach( stw, "PRESSURE" ) ;
 | 
|---|
| 2005 |   mswCols.pressure().putColumn( sharedFloatCol ) ;
 | 
|---|
| 2006 |   sharedFloatCol.attach( stw, "HUMIDITY" ) ;
 | 
|---|
| 2007 |   mswCols.relHumidity().putColumn( sharedFloatCol ) ;
 | 
|---|
| 2008 |   sharedFloatCol.attach( stw, "WINDSPEED" ) ;
 | 
|---|
| 2009 |   mswCols.windSpeed().putColumn( sharedFloatCol ) ;
 | 
|---|
| 2010 |   sharedFloatCol.attach( stw, "WINDAZ" ) ;
 | 
|---|
| 2011 |   mswCols.windDirection().putColumn( sharedFloatCol ) ;
 | 
|---|
| 2012 | 
 | 
|---|
| 2013 |   // fill TIME and INTERVAL
 | 
|---|
| 2014 |   Double midTime ;
 | 
|---|
| 2015 |   Double interval ;
 | 
|---|
| 2016 |   Vector<Double> intervalArr( nrow, 0.0 ) ;
 | 
|---|
| 2017 |   TableIterator iter( table_->table(), "WEATHER_ID" ) ;
 | 
|---|
| 2018 |   while( !iter.pastEnd() ) {
 | 
|---|
| 2019 |     //Table tab( iter.table() ) ;
 | 
|---|
| 2020 |     Table tab = iter.table() ;
 | 
|---|
| 2021 | 
 | 
|---|
| 2022 |     ROScalarColumn<uInt> widCol( tab, "WEATHER_ID" ) ;
 | 
|---|
| 2023 |     uInt wid = widCol( 0 ) ;
 | 
|---|
| 2024 | 
 | 
|---|
| 2025 |     getValidTimeRange( midTime, interval, tab ) ;
 | 
|---|
| 2026 |     mswCols.time().put( wid, midTime ) ;
 | 
|---|
| 2027 |     intervalArr[wid] = interval ;
 | 
|---|
| 2028 | 
 | 
|---|
| 2029 |     iter.next() ;
 | 
|---|
| 2030 |   }
 | 
|---|
| 2031 |   mswCols.interval().putColumn( intervalArr ) ;
 | 
|---|
| 2032 | 
 | 
|---|
| 2033 | //   double endSec = mathutil::gettimeofday_sec() ;
 | 
|---|
| 2034 | //   os_ << "end MSWriter::fillWeather() endSec=" << endSec << " (" << endSec-startSec << "sec)" << LogIO::POST ;
 | 
|---|
| 2035 | }
 | 
|---|
| 2036 | 
 | 
|---|
| 2037 | void MSWriter::fillSysCal( map< Int,Vector<uInt> > &idRec, 
 | 
|---|
| 2038 |                            map< Int,Vector<uInt> > &rowRec )
 | 
|---|
| 2039 | {
 | 
|---|
| 2040 |   //double startSec = mathutil::gettimeofday_sec() ;
 | 
|---|
| 2041 |   //os_ << "start MSWriter::fillSysCal() startSec=" << startSec << LogIO::POST ;
 | 
|---|
| 2042 | 
 | 
|---|
| 2043 |   //idRec.print( cout ) ;
 | 
|---|
| 2044 | 
 | 
|---|
| 2045 |   // access to MS SYSCAL subtable
 | 
|---|
| 2046 |   MSSysCal mssc = mstable_->sysCal() ;
 | 
|---|
| 2047 | 
 | 
|---|
| 2048 |   // access to TCAL subtable
 | 
|---|
| 2049 |   Table stt = table_->tcal().table() ;
 | 
|---|
| 2050 |   uInt nrow = stt.nrow() ;
 | 
|---|
| 2051 | 
 | 
|---|
| 2052 |   // access to MAIN table
 | 
|---|
| 2053 |   Block<String> cols( 6 ) ;
 | 
|---|
| 2054 |   cols[0] = "TIME" ;
 | 
|---|
| 2055 |   cols[1] = "TCAL_ID" ;
 | 
|---|
| 2056 |   cols[2] = "TSYS" ;
 | 
|---|
| 2057 |   cols[3] = "BEAMNO" ;
 | 
|---|
| 2058 |   cols[4] = "IFNO" ;
 | 
|---|
| 2059 |   cols[5] = "INTERVAL" ;
 | 
|---|
| 2060 |   Table tab = table_->table().project( cols ) ;
 | 
|---|
| 2061 | 
 | 
|---|
| 2062 |   if ( nrow == 0 ) 
 | 
|---|
| 2063 |     return ;
 | 
|---|
| 2064 | 
 | 
|---|
| 2065 |   //nrow = idRec.nfields() ;
 | 
|---|
| 2066 |   nrow = idRec.size() ;
 | 
|---|
| 2067 | 
 | 
|---|
| 2068 |   Double midTime ;
 | 
|---|
| 2069 |   Double interval ;
 | 
|---|
| 2070 |   String timeStr ;
 | 
|---|
| 2071 | 
 | 
|---|
| 2072 |   // row base
 | 
|---|
| 2073 |   TableRow row( mssc ) ;
 | 
|---|
| 2074 |   TableRecord &trec = row.record() ;
 | 
|---|
| 2075 |   RecordFieldPtr<Int> antennaRF( trec, "ANTENNA_ID" ) ;
 | 
|---|
| 2076 |   RecordFieldPtr<Int> feedRF( trec, "FEED_ID" ) ;
 | 
|---|
| 2077 |   RecordFieldPtr<Int> spwRF( trec, "SPECTRAL_WINDOW_ID" ) ;
 | 
|---|
| 2078 |   RecordFieldPtr<Double> timeRF( trec, "TIME" ) ;
 | 
|---|
| 2079 |   RecordFieldPtr<Double> intervalRF( trec, "INTERVAL" ) ;
 | 
|---|
| 2080 |   RecordFieldPtr< Array<Float> > tsysRF( trec, "TSYS" ) ;
 | 
|---|
| 2081 |   RecordFieldPtr< Array<Float> > tcalRF( trec, "TCAL" ) ;
 | 
|---|
| 2082 |   RecordFieldPtr< Array<Float> > tsysspRF ;
 | 
|---|
| 2083 |   RecordFieldPtr< Array<Float> > tcalspRF ;
 | 
|---|
| 2084 |   if ( tsysSpec_ )
 | 
|---|
| 2085 |     tsysspRF.attachToRecord( trec, "TSYS_SPECTRUM" ) ;
 | 
|---|
| 2086 |   if ( tcalSpec_ )
 | 
|---|
| 2087 |     tcalspRF.attachToRecord( trec, "TCAL_SPECTRUM" ) ;
 | 
|---|
| 2088 | 
 | 
|---|
| 2089 |   // ANTENNA_ID is always 0
 | 
|---|
| 2090 |   *antennaRF = 0 ;
 | 
|---|
| 2091 | 
 | 
|---|
| 2092 |   Table sortedstt = stt.sort( "ID" ) ;
 | 
|---|
| 2093 |   ROArrayColumn<Float> tcalCol( sortedstt, "TCAL" ) ;
 | 
|---|
| 2094 |   ROTableColumn idCol( sortedstt, "ID" ) ;
 | 
|---|
| 2095 |   ROArrayColumn<Float> tsysCol( tab, "TSYS" ) ;
 | 
|---|
| 2096 |   ROTableColumn tcalidCol( tab, "TCAL_ID" ) ;
 | 
|---|
| 2097 |   ROTableColumn timeCol( tab, "TIME" ) ;
 | 
|---|
| 2098 |   ROTableColumn intervalCol( tab, "INTERVAL" ) ;
 | 
|---|
| 2099 |   ROTableColumn beamnoCol( tab, "BEAMNO" ) ;
 | 
|---|
| 2100 |   ROTableColumn ifnoCol( tab, "IFNO" ) ;
 | 
|---|
| 2101 |   map< Int,Vector<uInt> >::iterator itr0 = idRec.begin() ;
 | 
|---|
| 2102 |   map< Int,Vector<uInt> >::iterator itr1 = rowRec.begin() ;
 | 
|---|
| 2103 |   for ( uInt irow = 0 ; irow < nrow ; irow++ ) {
 | 
|---|
| 2104 | //     double t1 = mathutil::gettimeofday_sec() ;
 | 
|---|
| 2105 |     Vector<uInt> ids = itr0->second ;
 | 
|---|
| 2106 |     itr0++ ;
 | 
|---|
| 2107 | //     os_ << "ids = " << ids << LogIO::POST ;
 | 
|---|
| 2108 |     uInt npol = ids.size() ;
 | 
|---|
| 2109 |     Vector<uInt> rows = itr1->second ;
 | 
|---|
| 2110 |     itr1++ ;
 | 
|---|
| 2111 | //     os_ << "rows = " << rows << LogIO::POST ;
 | 
|---|
| 2112 |     Vector<Double> atime( rows.nelements() ) ;
 | 
|---|
| 2113 |     Vector<Double> ainterval( rows.nelements() ) ;
 | 
|---|
| 2114 |     Vector<uInt> atcalid( rows.nelements() ) ;
 | 
|---|
| 2115 |     for( uInt jrow = 0 ; jrow < rows.nelements() ; jrow++ ) {
 | 
|---|
| 2116 |       atime[jrow] = (Double)timeCol.asdouble( rows[jrow] ) ;
 | 
|---|
| 2117 |       ainterval[jrow] = (Double)intervalCol.asdouble( rows[jrow] ) ;
 | 
|---|
| 2118 |       atcalid[jrow] = tcalidCol.asuInt( rows[jrow] ) ;
 | 
|---|
| 2119 |     }
 | 
|---|
| 2120 |     Vector<Float> dummy = tsysCol( rows[0] ) ;
 | 
|---|
| 2121 |     Matrix<Float> tsys( npol,dummy.nelements() ) ;
 | 
|---|
| 2122 |     tsys.row( 0 ) = dummy ;
 | 
|---|
| 2123 |     for ( uInt jrow = 1 ; jrow < npol ; jrow++ )
 | 
|---|
| 2124 |       tsys.row( jrow ) = tsysCol( rows[jrow] ) ;
 | 
|---|
| 2125 | 
 | 
|---|
| 2126 |     // FEED_ID
 | 
|---|
| 2127 |     *feedRF = beamnoCol.asuInt( rows[0] ) ;
 | 
|---|
| 2128 | 
 | 
|---|
| 2129 |     // SPECTRAL_WINDOW_ID
 | 
|---|
| 2130 |     *spwRF = ifnoCol.asuInt( rows[0] ) ;
 | 
|---|
| 2131 | 
 | 
|---|
| 2132 |     // TIME and INTERVAL
 | 
|---|
| 2133 |     getValidTimeRange( midTime, interval, atime, ainterval ) ;
 | 
|---|
| 2134 |     *timeRF = midTime ;
 | 
|---|
| 2135 |     *intervalRF = interval ;
 | 
|---|
| 2136 | 
 | 
|---|
| 2137 |     // TCAL and TSYS
 | 
|---|
| 2138 |     Matrix<Float> tcal ;
 | 
|---|
| 2139 |     Table t ;
 | 
|---|
| 2140 |     if ( idCol.asuInt( ids[0] ) == ids[0] ) {
 | 
|---|
| 2141 | //       os_ << "sorted at irow=" << irow << " ids[0]=" << ids[0] << LogIO::POST ;
 | 
|---|
| 2142 |       Vector<Float> dummyC = tcalCol( ids[0] ) ;
 | 
|---|
| 2143 |       tcal.resize( npol, dummyC.size() ) ;
 | 
|---|
| 2144 |       tcal.row( 0 ) = dummyC ;
 | 
|---|
| 2145 |     }
 | 
|---|
| 2146 |     else {
 | 
|---|
| 2147 | //       os_ << "NOT sorted at irow=" << irow << " ids[0]=" << ids[0] << LogIO::POST ;
 | 
|---|
| 2148 |       t = stt( stt.col("ID") == ids[0], 1 ) ;
 | 
|---|
| 2149 |       Vector<Float> dummyC = tcalCol( 0 ) ;
 | 
|---|
| 2150 |       tcal.resize( npol, dummyC.size(), True ) ;
 | 
|---|
| 2151 |       tcal.row( 0 ) = dummyC ;
 | 
|---|
| 2152 |     }
 | 
|---|
| 2153 |     if ( npol == 2 ) {
 | 
|---|
| 2154 |       if ( idCol.asuInt( ids[1] ) == ids[1] ) {
 | 
|---|
| 2155 | //         os_ << "sorted at irow=" << irow << " ids[1]=" << ids[1] << LogIO::POST ;
 | 
|---|
| 2156 |         tcal.row( 1 ) = tcalCol( ids[1] ) ;
 | 
|---|
| 2157 |       }
 | 
|---|
| 2158 |       else {
 | 
|---|
| 2159 | //         os_ << "NOT sorted at irow=" << irow << " ids[1]=" << ids[1] << LogIO::POST ;
 | 
|---|
| 2160 |         t = stt( stt.col("ID") == ids[1], 1 ) ;
 | 
|---|
| 2161 |         tcalCol.attach( t, "TCAL" ) ;
 | 
|---|
| 2162 |         tcal.row( 1 ) = tcalCol( 0 ) ;
 | 
|---|
| 2163 |       }
 | 
|---|
| 2164 |     }
 | 
|---|
| 2165 |     else if ( npol == 3 ) {
 | 
|---|
| 2166 |       if ( idCol.asuInt( ids[2] ) == ids[2] )
 | 
|---|
| 2167 |         tcal.row( 1 ) = tcalCol( ids[2] ) ;
 | 
|---|
| 2168 |       else {
 | 
|---|
| 2169 |         t = stt( stt.col("ID") == ids[2], 1 ) ;
 | 
|---|
| 2170 |         tcalCol.attach( t, "TCAL" ) ;
 | 
|---|
| 2171 |         tcal.row( 1 ) = tcalCol( 0 ) ;
 | 
|---|
| 2172 |       }
 | 
|---|
| 2173 |       if ( idCol.asuInt( ids[1] ) == ids[1] )
 | 
|---|
| 2174 |         tcal.row( 2 ) = tcalCol( ids[1] ) ;
 | 
|---|
| 2175 |       else {
 | 
|---|
| 2176 |         t = stt( stt.col("ID") == ids[1], 1 ) ;
 | 
|---|
| 2177 |         tcalCol.attach( t, "TCAL" ) ;
 | 
|---|
| 2178 |         tcal.row( 2 ) = tcalCol( 0 ) ;
 | 
|---|
| 2179 |       }
 | 
|---|
| 2180 |     }
 | 
|---|
| 2181 |     else if ( npol == 4 ) {
 | 
|---|
| 2182 |       if ( idCol.asuInt( ids[2] ) == ids[2] )
 | 
|---|
| 2183 |         tcal.row( 1 ) = tcalCol( ids[2] ) ;
 | 
|---|
| 2184 |       else {
 | 
|---|
| 2185 |         t = stt( stt.col("ID") == ids[2], 1 ) ;
 | 
|---|
| 2186 |         tcalCol.attach( t, "TCAL" ) ;
 | 
|---|
| 2187 |         tcal.row( 1 ) = tcalCol( 0 ) ;
 | 
|---|
| 2188 |       }
 | 
|---|
| 2189 |       if ( idCol.asuInt( ids[3] ) == ids[3] )
 | 
|---|
| 2190 |         tcal.row( 2 ) = tcalCol( ids[3] ) ;
 | 
|---|
| 2191 |       else {
 | 
|---|
| 2192 |         t = stt( stt.col("ID") == ids[3], 1 ) ;
 | 
|---|
| 2193 |         tcalCol.attach( t, "TCAL" ) ;
 | 
|---|
| 2194 |         tcal.row( 2 ) = tcalCol( 0 ) ;
 | 
|---|
| 2195 |       }
 | 
|---|
| 2196 |       if ( idCol.asuInt( ids[1] ) == ids[1] )
 | 
|---|
| 2197 |         tcal.row( 2 ) = tcalCol( ids[1] ) ;
 | 
|---|
| 2198 |       else {
 | 
|---|
| 2199 |         t = stt( stt.col("ID") == ids[1], 1 ) ;
 | 
|---|
| 2200 |         tcalCol.attach( t, "TCAL" ) ;
 | 
|---|
| 2201 |         tcal.row( 3 ) = tcalCol( 0 ) ;
 | 
|---|
| 2202 |       }
 | 
|---|
| 2203 |     }
 | 
|---|
| 2204 |     if ( tcalSpec_ ) {
 | 
|---|
| 2205 |       // put TCAL_SPECTRUM 
 | 
|---|
| 2206 |       tcalspRF.define( tcal ) ;
 | 
|---|
| 2207 |       // set TCAL (mean of TCAL_SPECTRUM)
 | 
|---|
| 2208 |       Matrix<Float> tcalMean( npol, 1 ) ;
 | 
|---|
| 2209 |       for ( uInt iid = 0 ; iid < npol ; iid++ ) {
 | 
|---|
| 2210 |         tcalMean( iid, 0 ) = mean( tcal.row(iid) ) ;
 | 
|---|
| 2211 |       }
 | 
|---|
| 2212 |       // put TCAL
 | 
|---|
| 2213 |       tcalRF.define( tcalMean ) ;
 | 
|---|
| 2214 |     }
 | 
|---|
| 2215 |     else {
 | 
|---|
| 2216 |       // put TCAL
 | 
|---|
| 2217 |       tcalRF.define( tcal ) ;
 | 
|---|
| 2218 |     }
 | 
|---|
| 2219 |     
 | 
|---|
| 2220 |     if ( tsysSpec_ ) {
 | 
|---|
| 2221 |       // put TSYS_SPECTRUM
 | 
|---|
| 2222 |       tsysspRF.define( tsys ) ;
 | 
|---|
| 2223 |       // set TSYS (mean of TSYS_SPECTRUM)
 | 
|---|
| 2224 |       Matrix<Float> tsysMean( npol, 1 ) ;
 | 
|---|
| 2225 |       for ( uInt iid = 0 ; iid < npol ; iid++ ) {
 | 
|---|
| 2226 |         tsysMean( iid, 0 ) = mean( tsys.row(iid) ) ;
 | 
|---|
| 2227 |       }
 | 
|---|
| 2228 |       // put TSYS
 | 
|---|
| 2229 |       tsysRF.define( tsysMean ) ;
 | 
|---|
| 2230 |     }
 | 
|---|
| 2231 |     else {
 | 
|---|
| 2232 |       // put TSYS
 | 
|---|
| 2233 |       tsysRF.define( tsys ) ;
 | 
|---|
| 2234 |     }
 | 
|---|
| 2235 | 
 | 
|---|
| 2236 |     // add row 
 | 
|---|
| 2237 |     mssc.addRow( 1, True ) ;
 | 
|---|
| 2238 |     row.put( mssc.nrow()-1 ) ;
 | 
|---|
| 2239 | 
 | 
|---|
| 2240 | //     double t2 = mathutil::gettimeofday_sec() ;
 | 
|---|
| 2241 | //     os_ << irow << "th loop elapsed time = " << t2-t1 << "sec" << LogIO::POST ;
 | 
|---|
| 2242 |   }
 | 
|---|
| 2243 |   
 | 
|---|
| 2244 |   //double endSec = mathutil::gettimeofday_sec() ;
 | 
|---|
| 2245 |   //os_ << "end MSWriter::fillSysCal() endSec=" << endSec << " (" << endSec-startSec << "sec)" << LogIO::POST ;
 | 
|---|
| 2246 | }
 | 
|---|
| 2247 | 
 | 
|---|
| 2248 | void MSWriter::getValidTimeRange( Double &me, Double &interval, Table &tab ) 
 | 
|---|
| 2249 | {
 | 
|---|
| 2250 | //   double startSec = mathutil::gettimeofday_sec() ;
 | 
|---|
| 2251 | //   os_ << "start MSWriter::getVaridTimeRange() startSec=" << startSec << LogIO::POST ;
 | 
|---|
| 2252 | 
 | 
|---|
| 2253 |   // sort table
 | 
|---|
| 2254 |   //Table stab = tab.sort( "TIME" ) ;
 | 
|---|
| 2255 | 
 | 
|---|
| 2256 |   ROScalarColumn<Double> timeCol( tab, "TIME" ) ;
 | 
|---|
| 2257 |   Vector<Double> timeArr = timeCol.getColumn() ;
 | 
|---|
| 2258 |   Double minTime ; 
 | 
|---|
| 2259 |   Double maxTime ;
 | 
|---|
| 2260 |   minMax( minTime, maxTime, timeArr ) ;
 | 
|---|
| 2261 |   Double midTime = 0.5 * ( minTime + maxTime ) * 86400.0 ;
 | 
|---|
| 2262 |   // unit for TIME
 | 
|---|
| 2263 |   // Scantable: "d"
 | 
|---|
| 2264 |   // MS: "s"
 | 
|---|
| 2265 |   me = midTime ;
 | 
|---|
| 2266 |   interval = ( maxTime - minTime ) * 86400.0 ;
 | 
|---|
| 2267 | 
 | 
|---|
| 2268 | //   double endSec = mathutil::gettimeofday_sec() ;
 | 
|---|
| 2269 | //   os_ << "end MSWriter::getValidTimeRange() endSec=" << endSec << " (" << endSec-startSec << "sec)" << LogIO::POST ;
 | 
|---|
| 2270 | }
 | 
|---|
| 2271 | 
 | 
|---|
| 2272 | void MSWriter::getValidTimeRange( Double &me, Double &interval, Vector<Double> &atime, Vector<Double> &ainterval ) 
 | 
|---|
| 2273 | {
 | 
|---|
| 2274 | //   double startSec = mathutil::gettimeofday_sec() ;
 | 
|---|
| 2275 | //   os_ << "start MSWriter::getVaridTimeRange() startSec=" << startSec << LogIO::POST ;
 | 
|---|
| 2276 | 
 | 
|---|
| 2277 |   // sort table
 | 
|---|
| 2278 |   //Table stab = tab.sort( "TIME" ) ;
 | 
|---|
| 2279 | 
 | 
|---|
| 2280 |   Double minTime ; 
 | 
|---|
| 2281 |   Double maxTime ;
 | 
|---|
| 2282 |   minMax( minTime, maxTime, atime ) ;
 | 
|---|
| 2283 |   Double midTime = 0.5 * ( minTime + maxTime ) * 86400.0 ;
 | 
|---|
| 2284 |   // unit for TIME
 | 
|---|
| 2285 |   // Scantable: "d"
 | 
|---|
| 2286 |   // MS: "s"
 | 
|---|
| 2287 |   me = midTime ;
 | 
|---|
| 2288 |   interval = ( maxTime - minTime ) * 86400.0 + mean( ainterval ) ;
 | 
|---|
| 2289 | 
 | 
|---|
| 2290 | //   double endSec = mathutil::gettimeofday_sec() ;
 | 
|---|
| 2291 | //   os_ << "end MSWriter::getValidTimeRange() endSec=" << endSec << " (" << endSec-startSec << "sec)" << LogIO::POST ;
 | 
|---|
| 2292 | }
 | 
|---|
| 2293 | 
 | 
|---|
| 2294 | }
 | 
|---|