source: trunk/src/MSWriter.cpp@ 1974

Last change on this file since 1974 was 1974, checked in by Takeshi Nakazato, 14 years ago

New Development: Yes

JIRA Issue: Yes CAS-2718

Ready for Test: Yes

Interface Changes: Yes

What Interface Changed: New class msfiller and mswriter added

Test Programs: List test programs

Put in Release Notes: No

Module(s): Module Names change impacts.

Description: Describe your changes here...

New filler/writer specific for Scantable-MS conversion defined.
This is not called from scantable constructor right now.
However, you can call it by explicitly importing msfiller/mswriter.


File size: 23.5 KB
RevLine 
[1974]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
14#include <casa/OS/File.h>
15#include <casa/OS/RegularFile.h>
16#include <casa/OS/Directory.h>
17#include <casa/OS/SymLink.h>
18#include <casa/BasicSL/String.h>
19
20#include <tables/Tables/TableDesc.h>
21#include <tables/Tables/SetupNewTab.h>
22#include <tables/Tables/TableIter.h>
23#include <tables/Tables/RefRows.h>
24
25#include <ms/MeasurementSets/MeasurementSet.h>
26#include <ms/MeasurementSets/MSColumns.h>
27#include <ms/MeasurementSets/MSPolIndex.h>
28#include <ms/MeasurementSets/MSDataDescIndex.h>
29
30#include "MSWriter.h"
31#include "STHeader.h"
32#include "STFrequencies.h"
33
34using namespace casa ;
35
36namespace asap
37{
38
39MSWriter::MSWriter(CountedPtr<Scantable> stable)
40 : table_(stable)
41{
42 os_ = LogIO() ;
43 os_.origin( LogOrigin( "MSWriter", "MSWriter()", WHERE ) ) ;
44 os_ << "MSWriter::MSWriter()" << LogIO::POST ;
45
46 // initialize writer
47 init() ;
48}
49
50MSWriter::~MSWriter()
51{
52 os_.origin( LogOrigin( "MSWriter", "~MSWriter()", WHERE ) ) ;
53 os_ << "MSWriter::~MSWriter()" << LogIO::POST ;
54}
55
56bool MSWriter::write(const string& filename, const Record& rec)
57{
58 os_.origin( LogOrigin( "MSWriter", "write()", WHERE ) ) ;
59 os_ << "MSWriter::write()" << LogIO::POST ;
60
61 filename_ = filename ;
62
63 // parsing MS options
64 Bool overwrite = False ;
65 if ( rec.isDefined( "ms" ) ) {
66 Record msrec = rec.asRecord( "ms" ) ;
67 if ( msrec.isDefined( "overwrite" ) ) {
68 overwrite = msrec.asBool( "overwrite" ) ;
69 }
70 }
71
72 os_ << "Parsing MS options" << endl ;
73 os_ << " overwrite = " << overwrite << LogIO::POST ;
74
75 File file( filename_ ) ;
76 if ( file.exists() ) {
77 if ( overwrite ) {
78 os_ << filename_ << " exists. Overwrite existing data... " << LogIO::POST ;
79 if ( file.isRegular() ) RegularFile(file).remove() ;
80 else if ( file.isDirectory() ) Directory(file).removeRecursive() ;
81 else SymLink(file).remove() ;
82 }
83 else {
84 os_ << LogIO::SEVERE << "ERROR: " << filename_ << " exists..." << LogIO::POST ;
85 return False ;
86 }
87 }
88
89 // set up MS
90 setupMS() ;
91
92 // subtables
93 // OBSERVATION
94 fillObservation() ;
95
96 // ANTENNA
97 fillAntenna() ;
98
99 // MAIN
100 // Iterate over several ids
101 Vector<uInt> processedFreqId( 0 ) ;
102 Int defaultFieldId = 0 ;
103 //
104 // ITERATION: FIELDNAME
105 //
106 Int added0 = 0 ;
107 Int current0 = mstable_->nrow() ;
108 TableIterator iter0( table_->table(), "FIELDNAME" ) ;
109 while( !iter0.pastEnd() ) {
110 Table t0( iter0.table() ) ;
111 ROScalarColumn<String> fieldNameCol( t0, "FIELDNAME" ) ;
112 String fieldName = fieldNameCol(0) ;
113 String::size_type pos = fieldName.find( "__" ) ;
114 Int fieldId = -1 ;
115 if ( pos != String::npos ) {
116 os_ << "fieldName.substr( pos+2 )=" << fieldName.substr( pos+2 ) << LogIO::POST ;
117 fieldId = String::toInt( fieldName.substr( pos+2 ) ) ;
118 fieldName = fieldName.substr( 0, pos ) ;
119 }
120 else {
121 os_ << "use default field id" << LogIO::POST ;
122 fieldId = defaultFieldId ;
123 defaultFieldId++ ;
124 }
125 os_ << "fieldId" << fieldId << ": " << fieldName << LogIO::POST ;
126 //
127 // ITERATION: BEAMNO
128 //
129 Int added1 = 0 ;
130 Int current1 = mstable_->nrow() ;
131 TableIterator iter1( t0, "BEAMNO" ) ;
132 while( !iter1.pastEnd() ) {
133 Table t1( iter1.table() ) ;
134 ROScalarColumn<uInt> beamNoCol( t1, "BEAMNO" ) ;
135 uInt beamNo = beamNoCol(0) ;
136 os_ << "beamNo = " << beamNo << LogIO::POST ;
137 //
138 // ITERATION: SCANNO
139 //
140 Int added2 = 0 ;
141 Int current2 = mstable_->nrow() ;
142 TableIterator iter2( t1, "SCANNO" ) ;
143 while( !iter2.pastEnd() ) {
144 Table t2( iter2.table() ) ;
145 ROScalarColumn<uInt> scanNoCol( t2, "SCANNO" ) ;
146 uInt scanNo = scanNoCol(0) ;
147 os_ << "scanNo = " << scanNo << LogIO::POST ;
148 //
149 // ITERATION: CYCLENO
150 //
151 Int added3 = 0 ;
152 Int current3 = mstable_->nrow() ;
153 TableIterator iter3( t2, "CYCLENO" ) ;
154 while( !iter3.pastEnd() ) {
155 Table t3( iter3.table() ) ;
156 //
157 // ITERATION: IFNO
158 //
159 Int added4 = 0 ;
160 Int current4 = mstable_->nrow() ;
161 TableIterator iter4( t3, "IFNO" ) ;
162 while( !iter4.pastEnd() ) {
163 Table t4( iter4.table() ) ;
164 ROScalarColumn<uInt> ifNoCol( t4, "IFNO" ) ;
165 uInt ifNo = ifNoCol(0) ;
166 os_ << "ifNo = " << ifNo << LogIO::POST ;
167 ROScalarColumn<uInt> freqIdCol( t4, "FREQ_ID" ) ;
168 uInt freqId = freqIdCol(0) ;
169 os_ << "freqId = " << freqId << LogIO::POST ;
170 //
171 // ITERATION: TIME
172 //
173 Int added5 = 0 ;
174 Int current5 = mstable_->nrow() ;
175 TableIterator iter5( t4, "TIME" ) ;
176 while( !iter5.pastEnd() ) {
177 Table t5( iter5.table().sort("POLNO") ) ;
178 Int prevnr = mstable_->nrow() ;
179 Int nrow = t5.nrow() ;
180 os_ << "nrow = " << nrow << LogIO::POST ;
181
182 // add row
183 mstable_->addRow( 1, True ) ;
184
185 Vector<Int> polnos( nrow ) ;
186 indgen( polnos, 0 ) ;
187 Int polid = addPolarization( polnos ) ;
188 os_ << "polid = " << polid << LogIO::POST ;
189 //
190 // LOOP: POLNO
191 //
192 for ( Int ipol = 0 ; ipol < nrow ; ipol++ ) {
193 }
194
195 // TIME and TIME_CENTROID
196 ROScalarMeasColumn<MEpoch> timeCol( t5, "TIME" ) ;
197 ScalarMeasColumn<MEpoch> msTimeCol( *mstable_, "TIME" ) ;
198 msTimeCol.put( prevnr, timeCol(0) ) ;
199 msTimeCol.attach( *mstable_, "TIME_CENTROID" ) ;
200 msTimeCol.put( prevnr, timeCol(0) ) ;
201
202 // INTERVAL and EXPOSURE
203 ROScalarColumn<Double> intervalCol( t5, "INTERVAL" ) ;
204 ScalarColumn<Double> msIntervalCol( *mstable_, "INTERVAL" ) ;
205 msIntervalCol.put( prevnr, intervalCol(0) ) ;
206 msIntervalCol.attach( *mstable_, "EXPOSURE" ) ;
207 msIntervalCol.put( prevnr, intervalCol(0) ) ;
208
209 // add DATA_DESCRIPTION row
210 Int ddid = addDataDescription( polid, ifNo ) ;
211 os_ << "ddid = " << ddid << LogIO::POST ;
212 ScalarColumn<Int> ddIdCol( *mstable_, "DATA_DESC_ID" ) ;
213 ddIdCol.put( prevnr, ddid ) ;
214
215 added5 += 1 ;
216 os_ << "added5 = " << added5 << " current5 = " << current5 << LogIO::POST ;
217 iter5.next() ;
218 }
219
220 // add SPECTRAL_WINDOW row
221 if ( allNE( processedFreqId, freqId ) ) {
222 uInt vsize = processedFreqId.size() ;
223 processedFreqId.resize( vsize+1, True ) ;
224 processedFreqId[vsize] = freqId ;
225 addSpectralWindow( ifNo, freqId ) ;
226 }
227
228 added4 += added5 ;
229 os_ << "added4 = " << added4 << " current4 = " << current4 << LogIO::POST ;
230 iter4.next() ;
231 }
232 added3 += added4 ;
233 os_ << "added3 = " << added3 << " current3 = " << current3 << LogIO::POST ;
234 iter3.next() ;
235 }
236
237 // SCAN_NUMBER
238 RefRows rows3( current3, current3+added3-1 ) ;
239 Vector<Int> scanNum( added3, scanNo ) ;
240 ScalarColumn<Int> scanNumCol( *mstable_, "SCAN_NUMBER" ) ;
241 scanNumCol.putColumnCells( rows3, scanNum ) ;
242
243 added2 += added3 ;
244 os_ << "added2 = " << added2 << " current2 = " << current2 << LogIO::POST ;
245 iter2.next() ;
246 }
247
248 // FEED1 and FEED2
249 RefRows rows2( current2, current2+added2-1 ) ;
250 Vector<Int> feedId( added2, beamNo ) ;
251 ScalarColumn<Int> feedCol( *mstable_, "FEED1" ) ;
252 feedCol.putColumnCells( rows2, feedId ) ;
253 feedCol.attach( *mstable_, "FEED2" ) ;
254 feedCol.putColumnCells( rows2, feedId ) ;
255
256 // add FEED row
257 addFeed( beamNo ) ;
258
259 added1 += added2 ;
260 os_ << "added1 = " << added1 << " current1 = " << current1 << LogIO::POST ;
261 iter1.next() ;
262 }
263
264 // FIELD_ID
265 RefRows rows1( current1, current1+added1-1 ) ;
266 Vector<Int> fieldIds( added1, fieldId ) ;
267 ScalarColumn<Int> fieldIdCol( *mstable_, "FIELD_ID" ) ;
268 fieldIdCol.putColumnCells( rows1, fieldIds ) ;
269
270 added0 += added1 ;
271 os_ << "added0 = " << added0 << " current0 = " << current0 << LogIO::POST ;
272 iter0.next() ;
273 }
274
275 // OBSERVATION_ID is always 0
276 ScalarColumn<Int> sharedIntCol( *mstable_, "OBSERVATION_ID" ) ;
277 Vector<Int> sharedIntArr( added0, 0 ) ;
278 sharedIntCol.putColumn( sharedIntArr ) ;
279
280 // ANTENNA1 and ANTENNA2 are always 0
281 sharedIntArr = 0 ;
282 sharedIntCol.attach( *mstable_, "ANTENNA1" ) ;
283 sharedIntCol.putColumn( sharedIntArr ) ;
284 sharedIntCol.attach( *mstable_, "ANTENNA2" ) ;
285 sharedIntCol.putColumn( sharedIntArr ) ;
286
287 // ARRAY_ID is tentatively set to 0
288 sharedIntArr = 0 ;
289 sharedIntCol.attach( *mstable_, "ARRAY_ID" ) ;
290 sharedIntCol.putColumn( sharedIntArr ) ;
291
292 return True ;
293}
294
295void MSWriter::init()
296{
297// os_.origin( LogOrigin( "MSWriter", "init()", WHERE ) ) ;
298 os_ << "MSWriter::init()" << LogIO::POST ;
299
300 // access to scantable
301 header_ = table_->getHeader() ;
302
303 // FLOAT_DATA? or DATA?
304 if ( header_.npol > 2 ) {
305 isFloatData_ = False ;
306 isData_ = True ;
307 }
308 else {
309 isFloatData_ = True ;
310 isData_ = False ;
311 }
312
313 // polarization type
314 polType_ = header_.poltype ;
315 if ( polType_ == "" )
316 polType_ = "stokes" ;
317 else if ( polType_.find( "linear" ) != String::npos )
318 polType_ = "linear" ;
319 else if ( polType_.find( "circular" ) != String::npos )
320 polType_ = "circular" ;
321 else if ( polType_.find( "stokes" ) != String::npos )
322 polType_ = "stokes" ;
323 else if ( polType_.find( "linpol" ) != String::npos )
324 polType_ = "linpol" ;
325 else
326 polType_ = "notype" ;
327
328}
329
330void MSWriter::setupMS()
331{
332// os_.origin( LogOrigin( "MSWriter", "setupMS()", WHERE ) ) ;
333 os_ << "MSWriter::setupMS()" << LogIO::POST ;
334
335 TableDesc msDesc = MeasurementSet::requiredTableDesc() ;
336
337 // any additional columns?
338 // TODO: add FLOAT_DATA column if npol == 2 otherwise add DATA column
339
340 SetupNewTable newtab( filename_, msDesc, Table::New ) ;
341
342 mstable_ = new MeasurementSet( newtab ) ;
343
344 // create subtables
345 TableDesc antennaDesc = MSAntenna::requiredTableDesc() ;
346 SetupNewTable antennaTab( mstable_->antennaTableName(), antennaDesc, Table::New ) ;
347 mstable_->rwKeywordSet().defineTable( MeasurementSet::keywordName( MeasurementSet::ANTENNA ), Table( antennaTab ) ) ;
348
349 TableDesc dataDescDesc = MSDataDescription::requiredTableDesc() ;
350 SetupNewTable dataDescTab( mstable_->dataDescriptionTableName(), dataDescDesc, Table::New ) ;
351 mstable_->rwKeywordSet().defineTable( MeasurementSet::keywordName( MeasurementSet::DATA_DESCRIPTION ), Table( dataDescTab ) ) ;
352
353 TableDesc dopplerDesc = MSDoppler::requiredTableDesc() ;
354 SetupNewTable dopplerTab( mstable_->dopplerTableName(), dopplerDesc, Table::New ) ;
355 mstable_->rwKeywordSet().defineTable( MeasurementSet::keywordName( MeasurementSet::DOPPLER ), Table( dopplerTab ) ) ;
356
357 TableDesc feedDesc = MSFeed::requiredTableDesc() ;
358 SetupNewTable feedTab( mstable_->feedTableName(), feedDesc, Table::New ) ;
359 mstable_->rwKeywordSet().defineTable( MeasurementSet::keywordName( MeasurementSet::FEED ), Table( feedTab ) ) ;
360
361 TableDesc fieldDesc = MSField::requiredTableDesc() ;
362 SetupNewTable fieldTab( mstable_->fieldTableName(), fieldDesc, Table::New ) ;
363 mstable_->rwKeywordSet().defineTable( MeasurementSet::keywordName( MeasurementSet::FIELD ), Table( fieldTab ) ) ;
364
365 TableDesc flagCmdDesc = MSFlagCmd::requiredTableDesc() ;
366 SetupNewTable flagCmdTab( mstable_->flagCmdTableName(), flagCmdDesc, Table::New ) ;
367 mstable_->rwKeywordSet().defineTable( MeasurementSet::keywordName( MeasurementSet::FLAG_CMD ), Table( flagCmdTab ) ) ;
368
369 TableDesc freqOffsetDesc = MSFreqOffset::requiredTableDesc() ;
370 SetupNewTable freqOffsetTab( mstable_->freqOffsetTableName(), freqOffsetDesc, Table::New ) ;
371 mstable_->rwKeywordSet().defineTable( MeasurementSet::keywordName( MeasurementSet::FREQ_OFFSET ), Table( freqOffsetTab ) ) ;
372
373 TableDesc historyDesc = MSHistory::requiredTableDesc() ;
374 SetupNewTable historyTab( mstable_->historyTableName(), historyDesc, Table::New ) ;
375 mstable_->rwKeywordSet().defineTable( MeasurementSet::keywordName( MeasurementSet::HISTORY ), Table( historyTab ) ) ;
376
377 TableDesc observationDesc = MSObservation::requiredTableDesc() ;
378 SetupNewTable observationTab( mstable_->observationTableName(), observationDesc, Table::New ) ;
379 mstable_->rwKeywordSet().defineTable( MeasurementSet::keywordName( MeasurementSet::OBSERVATION ), Table( observationTab ) ) ;
380
381 TableDesc pointingDesc = MSPointing::requiredTableDesc() ;
382 SetupNewTable pointingTab( mstable_->pointingTableName(), pointingDesc, Table::New ) ;
383 mstable_->rwKeywordSet().defineTable( MeasurementSet::keywordName( MeasurementSet::POINTING ), Table( pointingTab ) ) ;
384
385 TableDesc polarizationDesc = MSPolarization::requiredTableDesc() ;
386 SetupNewTable polarizationTab( mstable_->polarizationTableName(), polarizationDesc, Table::New ) ;
387 mstable_->rwKeywordSet().defineTable( MeasurementSet::keywordName( MeasurementSet::POLARIZATION ), Table( polarizationTab ) ) ;
388
389 TableDesc processorDesc = MSProcessor::requiredTableDesc() ;
390 SetupNewTable processorTab( mstable_->processorTableName(), processorDesc, Table::New ) ;
391 mstable_->rwKeywordSet().defineTable( MeasurementSet::keywordName( MeasurementSet::PROCESSOR ), Table( processorTab ) ) ;
392
393 TableDesc sourceDesc = MSSource::requiredTableDesc() ;
394 SetupNewTable sourceTab( mstable_->sourceTableName(), sourceDesc, Table::New ) ;
395 mstable_->rwKeywordSet().defineTable( MeasurementSet::keywordName( MeasurementSet::SOURCE ), Table( sourceTab ) ) ;
396
397 TableDesc spwDesc = MSSpectralWindow::requiredTableDesc() ;
398 SetupNewTable spwTab( mstable_->spectralWindowTableName(), spwDesc, Table::New ) ;
399 mstable_->rwKeywordSet().defineTable( MeasurementSet::keywordName( MeasurementSet::SPECTRAL_WINDOW ), Table( spwTab ) ) ;
400
401 TableDesc stateDesc = MSState::requiredTableDesc() ;
402 SetupNewTable stateTab( mstable_->stateTableName(), stateDesc, Table::New ) ;
403 mstable_->rwKeywordSet().defineTable( MeasurementSet::keywordName( MeasurementSet::STATE ), Table( stateTab ) ) ;
404
405 // TODO: add TCAL_SPECTRUM and TSYS_SPECTRUM if necessary
406 TableDesc sysCalDesc = MSSysCal::requiredTableDesc() ;
407 SetupNewTable sysCalTab( mstable_->sysCalTableName(), sysCalDesc, Table::New ) ;
408 mstable_->rwKeywordSet().defineTable( MeasurementSet::keywordName( MeasurementSet::SYSCAL ), Table( sysCalTab ) ) ;
409
410 TableDesc weatherDesc = MSWeather::requiredTableDesc() ;
411 SetupNewTable weatherTab( mstable_->weatherTableName(), weatherDesc, Table::New ) ;
412 mstable_->rwKeywordSet().defineTable( MeasurementSet::keywordName( MeasurementSet::WEATHER ), Table( weatherTab ) ) ;
413
414 mstable_->initRefs() ;
415
416}
417
418void MSWriter::fillObservation()
419{
420 os_ << "set up OBSERVATION subtable" << LogIO::POST ;
421 // only 1 row
422 mstable_->observation().addRow( 1, True ) ;
423 MSObservationColumns msObsCols( mstable_->observation() ) ;
424 msObsCols.observer().put( 0, header_.observer ) ;
425 // tentatively put antennaname (from ANTENNA subtable)
426 String hAntennaName = header_.antennaname ;
427 String::size_type pos = hAntennaName.find( "//" ) ;
428 String telescopeName ;
429 if ( pos != String::npos ) {
430 telescopeName = hAntennaName.substr( 0, pos ) ;
431 }
432 else {
433 pos = hAntennaName.find( "@" ) ;
434 telescopeName = hAntennaName.substr( 0, pos ) ;
435 }
436 os_ << "telescopeName = " << telescopeName << LogIO::POST ;
437 msObsCols.telescopeName().put( 0, telescopeName ) ;
438 msObsCols.project().put( 0, header_.project ) ;
439 //ScalarMeasColumn<MEpoch> timeCol( table_->table().sort("TIME"), "TIME" ) ;
440 Table sortedtable = table_->table().sort("TIME") ;
441 ScalarMeasColumn<MEpoch> timeCol( sortedtable, "TIME" ) ;
442 Vector<MEpoch> trange( 2 ) ;
443 trange[0] = timeCol( 0 ) ;
444 trange[1] = timeCol( table_->nrow()-1 ) ;
445 msObsCols.timeRangeMeas().put( 0, trange ) ;
446}
447
448void MSWriter::fillAntenna()
449{
450 os_ << "set up ANTENNA subtable" << LogIO::POST ;
451 // only 1 row
452 mstable_->antenna().addRow( 1, True ) ;
453 MSAntennaColumns msAntCols( mstable_->antenna() ) ;
454
455 String hAntennaName = header_.antennaname ;
456 String::size_type pos = hAntennaName.find( "//" ) ;
457 String antennaName ;
458 String stationName ;
459 if ( pos != String::npos ) {
460 hAntennaName = hAntennaName.substr( pos+2 ) ;
461 }
462 pos = hAntennaName.find( "@" ) ;
463 if ( pos != String::npos ) {
464 antennaName = hAntennaName.substr( 0, pos ) ;
465 stationName = hAntennaName.substr( pos+1 ) ;
466 }
467 else {
468 antennaName = hAntennaName ;
469 stationName = hAntennaName ;
470 }
471 os_ << "antennaName = " << antennaName << LogIO::POST ;
472 os_ << "stationName = " << stationName << LogIO::POST ;
473
474 msAntCols.name().put( 0, antennaName ) ;
475 msAntCols.station().put( 0, stationName ) ;
476
477 os_ << "antennaPosition = " << header_.antennaposition << LogIO::POST ;
478
479 msAntCols.position().put( 0, header_.antennaposition ) ;
480}
481
482void MSWriter::addFeed( Int id )
483{
484 os_ << "set up FEED subtable" << LogIO::POST ;
485
486 // add row
487 MSFeed msFeed = mstable_->feed() ;
488 msFeed.addRow( 1, True ) ;
489 Int nrow = msFeed.nrow() ;
490
491 MSFeedColumns msFeedCols( mstable_->feed() ) ;
492
493 msFeedCols.feedId().put( nrow-1, id ) ;
494 msFeedCols.antennaId().put( nrow-1, 0 ) ;
495}
496
497void MSWriter::addSpectralWindow( Int spwid, Int freqid )
498{
499 os_ << "set up SPECTRAL_WINDOW subtable" << LogIO::POST ;
500
501 // add row
502 MSSpectralWindow msSpw = mstable_->spectralWindow() ;
503 while( (Int)msSpw.nrow() <= spwid ) {
504 msSpw.addRow( 1, True ) ;
505 }
506
507 MSSpWindowColumns msSpwCols( msSpw ) ;
508
509 STFrequencies stf = table_->frequencies() ;
510
511 // MEAS_FREQ_REF
512 msSpwCols.measFreqRef().put( spwid, stf.getFrame( True ) ) ;
513
514 Double refpix ;
515 Double refval ;
516 Double inc ;
517 stf.getEntry( refpix, refval, inc, (uInt)freqid ) ;
518
519 // NUM_CHAN
520 Int nchan = refpix * 2 ;
521 msSpwCols.numChan().put( spwid, nchan ) ;
522
523 // TOTAL_BANDWIDTH
524 Double bw = nchan * inc ;
525 msSpwCols.totalBandwidth().put( spwid, bw ) ;
526
527 // REF_FREQUENCY
528 Double refFreq = refval - refpix * inc ;
529 msSpwCols.refFrequency().put( spwid, refFreq ) ;
530
531 // NET_SIDEBAND
532 // tentative: USB->0, LSB->1
533 Int netSideband = 0 ;
534 if ( inc < 0 )
535 netSideband = 1 ;
536 msSpwCols.netSideband().put( spwid, netSideband ) ;
537
538 // RESOLUTION, CHAN_WIDTH, EFFECTIVE_BW
539 Vector<Double> sharedDoubleArr( nchan, inc ) ;
540 msSpwCols.resolution().put( spwid, sharedDoubleArr ) ;
541 msSpwCols.chanWidth().put( spwid, sharedDoubleArr ) ;
542 msSpwCols.effectiveBW().put( spwid, sharedDoubleArr ) ;
543
544 // CHAN_FREQ
545 indgen( sharedDoubleArr, refFreq, inc ) ;
546 msSpwCols.chanFreq().put( spwid, sharedDoubleArr ) ;
547}
548
549Int MSWriter::addPolarization( Vector<Int> polnos )
550{
551 os_ << "set up SPECTRAL_WINDOW subtable" << LogIO::POST ;
552
553 os_ << "polnos = " << polnos << LogIO::POST ;
554 MSPolarization msPol = mstable_->polarization() ;
555 uInt nrow = msPol.nrow() ;
556
557 Vector<Int> corrType = toCorrType( polnos ) ;
558 os_ << "corrType = " << corrType << LogIO::POST ;
559
560 MSPolarizationIndex msPolIdx( msPol ) ;
561 Vector<Int> polids = msPolIdx.matchCorrType( corrType ) ;
562 os_ << "polids = " << polids << LogIO::POST ;
563
564 Int polid = -1 ;
565
566 if ( polids.size() == 0 ) {
567 // add row
568 msPol.addRow( 1, True ) ;
569 polid = (Int)nrow ;
570
571 MSPolarizationColumns msPolCols( msPol ) ;
572
573 // CORR_TYPE
574 msPolCols.corrType().put( nrow, corrType ) ;
575
576 // NUM_CORR
577 uInt npol = corrType.size() ;
578 msPolCols.numCorr().put( nrow, npol ) ;
579
580 // CORR_PRODUCT
581 Matrix<Int> corrProd( 2, npol, -1 ) ;
582 if ( npol == 1 ) {
583 corrProd = 0 ;
584 }
585 else if ( npol == 2 ) {
586 corrProd.column(0) = 0 ;
587 corrProd.column(1) = 1 ;
588 }
589 else {
590 corrProd.column(0) = 0 ;
591 corrProd.column(3) = 1 ;
592 corrProd(0,1) = 0 ;
593 corrProd(1,1) = 1 ;
594 corrProd(0,2) = 1 ;
595 corrProd(1,2) = 0 ;
596 }
597 msPolCols.corrProduct().put( nrow, corrProd ) ;
598
599 }
600 else {
601 polid = polids[0] ;
602 }
603
604 return polid ;
605}
606
607Vector<Int> MSWriter::toCorrType( Vector<Int> polnos )
608{
609 uInt npol = polnos.size() ;
610 Vector<Int> corrType( npol, Stokes::Undefined ) ;
611
612 if ( npol == 4 ) {
613 if ( polType_ == "linear" ) {
614 for ( uInt ipol = 0 ; ipol < npol ; ipol++ ) {
615 if ( polnos[ipol] == 0 )
616 corrType[ipol] = Stokes::XX ;
617 else if ( polnos[ipol] == 1 )
618 corrType[ipol] = Stokes::XY ;
619 else if ( polnos[ipol] == 2 )
620 corrType[ipol] = Stokes::YX ;
621 else if ( polnos[ipol] == 3 )
622 corrType[ipol] = Stokes::YY ;
623 }
624 }
625 else if ( polType_ == "circular" ) {
626 for ( uInt ipol = 0 ; ipol < npol ; ipol++ ) {
627 if ( polnos[ipol] == 0 )
628 corrType[ipol] = Stokes::RR ;
629 else if ( polnos[ipol] == 1 )
630 corrType[ipol] = Stokes::RL ;
631 else if ( polnos[ipol] == 2 )
632 corrType[ipol] = Stokes::LR ;
633 else if ( polnos[ipol] == 3 )
634 corrType[ipol] = Stokes::LL ;
635 }
636 }
637 else if ( polType_ == "stokes" ) {
638 for ( uInt ipol = 0 ; ipol < npol ; ipol++ ) {
639 if ( polnos[ipol] == 0 )
640 corrType[ipol] = Stokes::I ;
641 else if ( polnos[ipol] == 1 )
642 corrType[ipol] = Stokes::Q ;
643 else if ( polnos[ipol] == 2 )
644 corrType[ipol] = Stokes::U ;
645 else if ( polnos[ipol] == 3 )
646 corrType[ipol] = Stokes::V ;
647 }
648 }
649 }
650 else if ( npol == 2 ) {
651 if ( polType_ == "linear" ) {
652 for ( uInt ipol = 0 ; ipol < npol ; ipol++ ) {
653 if ( polnos[ipol] == 0 )
654 corrType[ipol] = Stokes::XX ;
655 else if ( polnos[ipol] == 1 )
656 corrType[ipol] = Stokes::YY ;
657 }
658 }
659 else if ( polType_ == "circular" ) {
660 for ( uInt ipol = 0 ; ipol < npol ; ipol++ ) {
661 if ( polnos[ipol] == 0 )
662 corrType[ipol] = Stokes::RR ;
663 else if ( polnos[ipol] == 1 )
664 corrType[ipol] = Stokes::LL ;
665 }
666 }
667 else if ( polType_ == "stokes" ) {
668 for ( uInt ipol = 0 ; ipol < npol ; ipol++ ) {
669 if ( polnos[ipol] == 0 )
670 corrType[ipol] = Stokes::I ;
671 else if ( polnos[ipol] == 1 )
672 corrType[ipol] = Stokes::V ;
673 }
674 }
675 else if ( polType_ == "linpol" ) {
676 for ( uInt ipol = 0 ; ipol < npol ; ipol++ ) {
677 if ( polnos[ipol] == 1 )
678 corrType[ipol] = Stokes::Plinear ;
679 else if ( polnos[ipol] == 2 )
680 corrType[ipol] = Stokes::Pangle ;
681 }
682 }
683 }
684 else if ( npol == 1 ) {
685 if ( polType_ == "linear" )
686 corrType[0] = Stokes::XX ;
687 else if ( polType_ == "circular" )
688 corrType[0] = Stokes::RR ;
689 else if ( polType_ == "stokes" )
690 corrType[0] = Stokes::I ;
691 }
692
693 return corrType ;
694}
695
696Int MSWriter::addDataDescription( Int polid, Int spwid )
697{
698 os_ << "set up SPECTRAL_WINDOW subtable" << LogIO::POST ;
699
700 MSDataDescription msDataDesc = mstable_->dataDescription() ;
701 uInt nrow = msDataDesc.nrow() ;
702
703 MSDataDescIndex msDataDescIdx( msDataDesc ) ;
704
705 Vector<Int> ddids = msDataDescIdx.matchSpwIdAndPolznId( spwid, polid ) ;
706 os_ << "ddids = " << ddids << LogIO::POST ;
707
708 Int ddid = -1 ;
709 if ( ddids.size() == 0 ) {
710 msDataDesc.addRow( 1, True ) ;
711 MSDataDescColumns msDataDescCols( msDataDesc ) ;
712 msDataDescCols.polarizationId().put( nrow, polid ) ;
713 msDataDescCols.spectralWindowId().put( nrow, spwid ) ;
714 ddid = (Int)nrow ;
715 }
716 else {
717 ddid = ddids[0] ;
718 }
719
720 return ddid ;
721}
722}
Note: See TracBrowser for help on using the repository browser.