source: trunk/src/MSFiller.cpp@ 2023

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

New Development: No

JIRA Issue: Yes CAS-2718

Ready for Test: Yes

Interface Changes: No

What Interface Changed: Please list interface changes

Test Programs: List test programs

Put in Release Notes: Yes/No

Module(s): Module Names change impacts.

Description: Describe your changes here...

Copy ASDM subtable that are optionally created by importasdm task.
For filler, their root names are stored as String in table keyword,
while for writer, existing tables are copied and are stored as Table
in table keyword.


File size: 57.4 KB
Line 
1//
2// C++ Interface: MSFiller
3//
4// Description:
5//
6// This class is specific filler 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 <iostream>
15#include <map>
16
17#include <tables/Tables/ExprNode.h>
18#include <tables/Tables/TableIter.h>
19#include <tables/Tables/TableColumn.h>
20#include <tables/Tables/ScalarColumn.h>
21#include <tables/Tables/ArrayColumn.h>
22#include <tables/Tables/TableParse.h>
23#include <tables/Tables/TableRow.h>
24
25#include <casa/Containers/RecordField.h>
26#include <casa/Logging/LogIO.h>
27#include <casa/Arrays/Slicer.h>
28#include <casa/Quanta/MVTime.h>
29#include <casa/OS/Path.h>
30
31#include <measures/Measures/Stokes.h>
32#include <measures/Measures/MEpoch.h>
33#include <measures/Measures/MCEpoch.h>
34#include <measures/Measures/MFrequency.h>
35#include <measures/Measures/MCFrequency.h>
36#include <measures/Measures/MPosition.h>
37#include <measures/Measures/MCPosition.h>
38#include <measures/Measures/MDirection.h>
39#include <measures/Measures/MCDirection.h>
40#include <measures/Measures/MeasConvert.h>
41#include <measures/TableMeasures/ScalarMeasColumn.h>
42#include <measures/TableMeasures/ArrayMeasColumn.h>
43#include <measures/TableMeasures/ScalarQuantColumn.h>
44#include <measures/TableMeasures/ArrayQuantColumn.h>
45
46#include <ms/MeasurementSets/MSAntennaIndex.h>
47
48#include <atnf/PKSIO/SrcType.h>
49
50#include "MSFiller.h"
51#include "STHeader.h"
52
53#include <ctime>
54#include <sys/time.h>
55
56using namespace casa ;
57using namespace std ;
58
59namespace asap {
60double MSFiller::gettimeofday_sec()
61{
62 struct timeval tv ;
63 gettimeofday( &tv, NULL ) ;
64 return tv.tv_sec + (double)tv.tv_usec*1.0e-6 ;
65}
66
67MSFiller::MSFiller( casa::CountedPtr<Scantable> stable )
68 : table_( stable ),
69 tablename_( "" ),
70 antenna_( -1 ),
71 antennaStr_(""),
72 getPt_( False ),
73 isFloatData_( False ),
74 isData_( False ),
75 isDoppler_( False ),
76 isFlagCmd_( False ),
77 isFreqOffset_( False ),
78 isHistory_( False ),
79 isProcessor_( False ),
80 isSysCal_( False ),
81 isWeather_( False ),
82 colTsys_( "TSYS_SPECTRUM" ),
83 colTcal_( "TCAL_SPECTRUM" )
84{
85 os_ = LogIO() ;
86 os_.origin( LogOrigin( "MSFiller", "MSFiller()", WHERE ) ) ;
87}
88
89MSFiller::~MSFiller()
90{
91 os_.origin( LogOrigin( "MSFiller", "~MSFiller()", WHERE ) ) ;
92}
93
94bool MSFiller::open( const std::string &filename, const casa::Record &rec )
95{
96 os_.origin( LogOrigin( "MSFiller", "open()", WHERE ) ) ;
97// double startSec = gettimeofday_sec() ;
98// os_ << "start MSFiller::open() startsec=" << startSec << LogIO::POST ;
99 //os_ << " filename = " << filename << endl ;
100
101 // parsing MS options
102 if ( rec.isDefined( "ms" ) ) {
103 Record msrec = rec.asRecord( "ms" ) ;
104 if ( msrec.isDefined( "getpt" ) ) {
105 getPt_ = msrec.asBool( "getpt" ) ;
106 }
107 if ( msrec.isDefined( "antenna" ) ) {
108 if ( msrec.type( msrec.fieldNumber( "antenna" ) ) == TpInt ) {
109 antenna_ = msrec.asInt( "antenna" ) ;
110 }
111 else {
112 //antenna_ = atoi( msrec.asString( "antenna" ).c_str() ) ;
113 antennaStr_ = msrec.asString( "antenna" ) ;
114 }
115 }
116 else {
117 antenna_ = 0 ;
118 }
119 }
120
121 os_ << "Parsing MS options" << endl ;
122 os_ << " getPt = " << getPt_ << endl ;
123 os_ << " antenna = " << antenna_ << endl ;
124 os_ << " antennaStr = " << antennaStr_ << LogIO::POST ;
125
126 MeasurementSet *tmpMS = new MeasurementSet( filename, Table::Old ) ;
127 //mstable_ = (*tmpMS)( tmpMS->col("ANTENNA1") == antenna_
128 // && tmpMS->col("ANTENNA1") == tmpMS->col("ANTENNA2") ) ;
129 tablename_ = tmpMS->tableName() ;
130 if ( antenna_ == -1 && antennaStr_.size() > 0 ) {
131 MSAntennaIndex msAntIdx( tmpMS->antenna() ) ;
132 Vector<Int> id = msAntIdx.matchAntennaName( antennaStr_ ) ;
133 if ( id.size() > 0 )
134 antenna_ = id[0] ;
135 os_ << "searched antenna_ = " << antenna_ << LogIO::POST ;
136 }
137 mstable_ = MeasurementSet( (*tmpMS)( tmpMS->col("ANTENNA1") == antenna_
138 && tmpMS->col("ANTENNA1") == tmpMS->col("ANTENNA2") ) ) ;
139// stringstream ss ;
140// ss << "SELECT FROM $1 WHERE ANTENNA1 == ANTENNA2 && ANTENNA1 == " << antenna_ ;
141// String taql( ss.str() ) ;
142// mstable_ = MeasurementSet( tableCommand( taql, *tmpMS ) ) ;
143 delete tmpMS ;
144
145 // check which data column exists
146 isFloatData_ = mstable_.tableDesc().isColumn( "FLOAT_DATA" ) ;
147 isData_ = mstable_.tableDesc().isColumn( "DATA" ) ;
148
149// double endSec = gettimeofday_sec() ;
150// os_ << "end MSFiller::open() endSec=" << endSec << " (" << endSec-startSec << "sec)" << LogIO::POST ;
151 return true ;
152}
153
154void MSFiller::fill()
155{
156 os_.origin( LogOrigin( "MSFiller", "fill()", WHERE ) ) ;
157// double startSec = gettimeofday_sec() ;
158// os_ << "start MSFiller::fill() startSec=" << startSec << LogIO::POST ;
159
160// double time0 = gettimeofday_sec() ;
161// os_ << "start init fill: " << time0 << LogIO::POST ;
162
163 // Initialize header
164 STHeader sdh ;
165 sdh.nchan = 0 ;
166 sdh.npol = 0 ;
167 sdh.nif = 0 ;
168 sdh.nbeam = 0 ;
169 sdh.observer = "" ;
170 sdh.project = "" ;
171 sdh.obstype = "" ;
172 sdh.antennaname = "" ;
173 sdh.antennaposition.resize( 0 ) ;
174 sdh.equinox = 0.0 ;
175 sdh.freqref = "" ;
176 sdh.reffreq = -1.0 ;
177 sdh.bandwidth = 0.0 ;
178 sdh.utc = 0.0 ;
179 sdh.fluxunit = "" ;
180 sdh.epoch = "" ;
181 sdh.poltype = "" ;
182
183 // check if optional table exists
184 //const TableRecord msrec = tablesel_.keywordSet() ;
185 const TableRecord msrec = mstable_.keywordSet() ;
186 isDoppler_ = msrec.isDefined( "DOPPLER" ) ;
187 if ( isDoppler_ )
188 if ( mstable_.doppler().nrow() == 0 )
189 isDoppler_ = False ;
190 isFlagCmd_ = msrec.isDefined( "FLAG_CMD" ) ;
191 if ( isFlagCmd_ )
192 if ( mstable_.flagCmd().nrow() == 0 )
193 isFlagCmd_ = False ;
194 isFreqOffset_ = msrec.isDefined( "FREQ_OFFSET" ) ;
195 if ( isFreqOffset_ )
196 if ( mstable_.freqOffset().nrow() == 0 )
197 isFreqOffset_ = False ;
198 isHistory_ = msrec.isDefined( "HISTORY" ) ;
199 if ( isHistory_ )
200 if ( mstable_.history().nrow() == 0 )
201 isHistory_ = False ;
202 isProcessor_ = msrec.isDefined( "PROCESSOR" ) ;
203 if ( isProcessor_ )
204 if ( mstable_.processor().nrow() == 0 )
205 isProcessor_ = False ;
206 isSysCal_ = msrec.isDefined( "SYSCAL" ) ;
207 if ( isSysCal_ )
208 if ( mstable_.sysCal().nrow() == 0 )
209 isSysCal_ = False ;
210 isWeather_ = msrec.isDefined( "WEATHER" ) ;
211 if ( isWeather_ )
212 if ( mstable_.weather().nrow() == 0 )
213 isWeather_ = False ;
214
215 // Access to MS subtables
216 MSField fieldtab = mstable_.field() ;
217 MSPolarization poltab = mstable_.polarization() ;
218 MSDataDescription ddtab = mstable_.dataDescription() ;
219 MSObservation obstab = mstable_.observation() ;
220 MSSource srctab = mstable_.source() ;
221 MSSpectralWindow spwtab = mstable_.spectralWindow() ;
222 MSSysCal caltab = mstable_.sysCal() ;
223 if ( caltab.nrow() == 0 )
224 isSysCal_ = False ;
225 else {
226 if ( !caltab.tableDesc().isColumn( colTcal_ ) )
227 colTcal_ = "TCAL" ;
228 if ( !caltab.tableDesc().isColumn( colTsys_ ) )
229 colTsys_ = "TSYS" ;
230 }
231// colTcal_ = "TCAL" ;
232// colTsys_ = "TSYS" ;
233 MSPointing pointtab = mstable_.pointing() ;
234 if ( mstable_.weather().nrow() == 0 )
235 isWeather_ = False ;
236 MSState stattab = mstable_.state() ;
237 MSAntenna anttab = mstable_.antenna() ;
238
239 // TEST
240 // memory allocation by boost::object_pool
241 boost::object_pool<ROTableColumn> *tpoolr = new boost::object_pool<ROTableColumn> ;
242 //
243
244 // SUBTABLES: FREQUENCIES
245 table_->frequencies().setFrame( "LSRK" ) ;
246 table_->frequencies().setFrame( "LSRK", True ) ;
247
248 // SUBTABLES: WEATHER
249 fillWeather() ;
250
251 // SUBTABLES: FOCUS
252 fillFocus() ;
253
254 // SUBTABLES: TCAL
255 fillTcal( tpoolr ) ;
256
257 // SUBTABLES: FIT
258 //fillFit() ;
259
260 // SUBTABLES: HISTORY
261 //fillHistory() ;
262
263 // shared pointers
264 ROTableColumn *tcolr ;
265
266 // MAIN
267 // Iterate over several ids
268 map<Int, uInt> ifmap ; // (IFNO, FREQ_ID) pair
269 ROArrayQuantColumn<Double> *sharedQDArrCol = new ROArrayQuantColumn<Double>( anttab, "POSITION" ) ;
270 Vector< Quantum<Double> > antpos = (*sharedQDArrCol)( antenna_ ) ;
271 delete sharedQDArrCol ;
272 MPosition mp( MVPosition( antpos ), MPosition::ITRF ) ;
273 if ( getPt_ ) {
274 //pointtab = pointtab( pointtab.col("ANTENNA_ID")==antenna_ ).sort("TIME") ;
275 pointtab = MSPointing( pointtab( pointtab.col("ANTENNA_ID")==antenna_ ).sort("TIME") ) ;
276 }
277 tcolr = tpoolr->construct( anttab, "STATION" ) ;
278 String stationName = tcolr->asString( antenna_ ) ;
279 tpoolr->destroy( tcolr ) ;
280 tcolr = tpoolr->construct( anttab, "NAME" ) ;
281 String antennaName = tcolr->asString( antenna_ ) ;
282 tpoolr->destroy( tcolr ) ;
283 sdh.antennaposition.resize( 3 ) ;
284 for ( int i = 0 ; i < 3 ; i++ )
285 sdh.antennaposition[i] = antpos[i].getValue( "m" ) ;
286 String telescopeName = "" ;
287
288// double time1 = gettimeofday_sec() ;
289// os_ << "end fill init: " << time1 << " (" << time1-time0 << "sec)" << LogIO::POST ;
290
291 // row based
292 Table &stab = table_->table() ;
293 TableRow row( stab ) ;
294 TableRecord &trec = row.record() ;
295 RecordFieldPtr< Array<Float> > spRF( trec, "SPECTRA" ) ;
296 RecordFieldPtr< Array<uChar> > ucarrRF( trec, "FLAGTRA" ) ;
297 RecordFieldPtr<Double> timeRF( trec, "TIME" ) ;
298 RecordFieldPtr< Array<Float> > tsysRF( trec, "TSYS" ) ;
299 RecordFieldPtr<Double> intervalRF( trec, "INTERVAL" ) ;
300 RecordFieldPtr< Array<Double> > dirRF( trec, "DIRECTION" ) ;
301 RecordFieldPtr<Float> azRF( trec, "AZIMUTH" ) ;
302 RecordFieldPtr<Float> elRF( trec, "ELEVATION" ) ;
303 RecordFieldPtr< Array<Double> > scrRF( trec, "SCANRATE" ) ;
304 RecordFieldPtr<uInt> cycleRF( trec, "CYCLENO" ) ;
305 RecordFieldPtr<uInt> flrRF( trec, "FLAGROW" ) ;
306 RecordFieldPtr<uInt> tcalidRF( trec, "TCAL_ID" ) ;
307 RecordFieldPtr<uInt> widRF( trec, "WEATHER_ID" ) ;
308 RecordFieldPtr<uInt> polnoRF( trec, "POLNO" ) ;
309
310
311 // REFBEAMNO
312 RecordFieldPtr<Int> intRF( trec, "REFBEAMNO" ) ;
313 *intRF = 0 ;
314
315 // FIT_ID
316 intRF.attachToRecord( trec, "FIT_ID" ) ;
317 *intRF = -1 ;
318
319 // OPACITY
320 RecordFieldPtr<Float> floatRF( trec, "OPACITY" ) ;
321 *floatRF = 0.0 ;
322
323 //
324 // ITERATION: OBSERVATION_ID
325 //
326 TableIterator iter0( mstable_, "OBSERVATION_ID" ) ;
327 while( !iter0.pastEnd() ) {
328// time0 = gettimeofday_sec() ;
329// os_ << "start 0th iteration: " << time0 << LogIO::POST ;
330 Table t0 = iter0.table() ;
331 tcolr = tpoolr->construct( t0, "OBSERVATION_ID" ) ;
332 Int obsId = tcolr->asInt( 0 ) ;
333 tpoolr->destroy( tcolr ) ;
334 if ( sdh.observer == "" ) {
335 tcolr = tpoolr->construct( obstab, "OBSERVER" ) ;
336 sdh.observer = tcolr->asString( obsId ) ;
337 tpoolr->destroy( tcolr ) ;
338 }
339 if ( sdh.project == "" ) {
340 tcolr = tpoolr->construct( obstab, "PROJECT" ) ;
341 sdh.observer = tcolr->asString( obsId ) ;
342 tpoolr->destroy( tcolr ) ;
343 }
344 ROArrayMeasColumn<MEpoch> *tmpMeasCol = new ROArrayMeasColumn<MEpoch>( obstab, "TIME_RANGE" ) ;
345 MEpoch me = (*tmpMeasCol)( obsId )( IPosition(1,0) ) ;
346 delete tmpMeasCol ;
347 if ( sdh.utc == 0.0 ) {
348 sdh.utc = me.get( "s" ).getValue() ;
349 }
350 if ( telescopeName == "" ) {
351 tcolr = tpoolr->construct( obstab, "TELESCOPE_NAME" ) ;
352 sdh.observer = tcolr->asString( obsId ) ;
353 tpoolr->destroy( tcolr ) ;
354 }
355 Int nbeam = 0 ;
356// time1 = gettimeofday_sec() ;
357// os_ << "end 0th iteration init: " << time1 << " (" << time1-time0 << "sec)" << LogIO::POST ;
358 //
359 // ITERATION: FEED1
360 //
361 TableIterator iter1( t0, "FEED1" ) ;
362 while( !iter1.pastEnd() ) {
363// time0 = gettimeofday_sec() ;
364// os_ << "start 1st iteration: " << time0 << LogIO::POST ;
365 Table t1 = iter1.table() ;
366 // assume FEED1 == FEED2
367 tcolr = tpoolr->construct( t1, "FEED1" ) ;
368 Int feedId = tcolr->asInt( 0 ) ;
369 tpoolr->destroy( tcolr ) ;
370 nbeam++ ;
371
372 // BEAMNO
373 RecordFieldPtr<uInt> uintRF( trec, "BEAMNO" ) ;
374 *uintRF = feedId ;
375
376 // FOCUS_ID
377 uintRF.attachToRecord( trec, "FOCUS_ID" ) ;
378 *uintRF = 0 ;
379
380// time1 = gettimeofday_sec() ;
381// os_ << "end 1st iteration init: " << time1 << " (" << time1-time0 << "sec)" << LogIO::POST ;
382 //
383 // ITERATION: FIELD_ID
384 //
385 TableIterator iter2( t1, "FIELD_ID" ) ;
386 while( !iter2.pastEnd() ) {
387// time0 = gettimeofday_sec() ;
388// os_ << "start 2nd iteration: " << time0 << LogIO::POST ;
389 Table t2 = iter2.table() ;
390 tcolr = tpoolr->construct( t2, "FIELD_ID" ) ;
391 Int fieldId = tcolr->asInt( 0 ) ;
392 tpoolr->destroy( tcolr ) ;
393 tcolr = tpoolr->construct( fieldtab, "SOURCE_ID" ) ;
394 Int srcId = tcolr->asInt( fieldId ) ;
395 tpoolr->destroy( tcolr ) ;
396 tcolr = tpoolr->construct( fieldtab, "NAME" ) ;
397 String fieldName = tcolr->asString( fieldId ) + "__" + String::toString(fieldId) ;
398 tpoolr->destroy( tcolr ) ;
399 ROArrayMeasColumn<MDirection> *delayDirCol = new ROArrayMeasColumn<MDirection>( fieldtab, "DELAY_DIR" ) ;
400 Vector<MDirection> delayDir = (*delayDirCol)( fieldId ) ;
401 delete delayDirCol ;
402 Vector<Double> defaultScanrate( 2, 0.0 ) ;
403 Vector<Double> defaultDir = delayDir[0].getAngle( "rad" ).getValue() ;
404 if ( delayDir.nelements() > 1 )
405 defaultScanrate = delayDir[1].getAngle( "rad" ).getValue() ;
406
407
408 // FIELDNAME
409 RecordFieldPtr<String> strRF( trec, "FIELDNAME" ) ;
410 *strRF = fieldName ;
411
412
413// time1 = gettimeofday_sec() ;
414// os_ << "end 2nd iteration init: " << time1 << " (" << time1-time0 << "sec)" << LogIO::POST ;
415 //
416 // ITERATION: DATA_DESC_ID
417 //
418 TableIterator iter3( t2, "DATA_DESC_ID" ) ;
419 while( !iter3.pastEnd() ) {
420// time0 = gettimeofday_sec() ;
421// os_ << "start 3rd iteration: " << time0 << LogIO::POST ;
422 Table t3 = iter3.table() ;
423 tcolr = tpoolr->construct( t3, "DATA_DESC_ID" ) ;
424 Int ddId = tcolr->asInt( 0 ) ;
425 tpoolr->destroy( tcolr ) ;
426 tcolr = tpoolr->construct( ddtab, "POLARIZATION_ID" ) ;
427 Int polId = tcolr->asInt( ddId ) ;
428 tpoolr->destroy( tcolr ) ;
429 tcolr = tpoolr->construct( ddtab, "SPECTRAL_WINDOW_ID" ) ;
430 Int spwId = tcolr->asInt( ddId ) ;
431 tpoolr->destroy( tcolr ) ;
432 // TODO: This must be updated if writer will be replaced from STWriter to MSWriter
433 sdh.nif = max( sdh.nif, spwId ) ;
434
435 // IFNO
436 uintRF.attachToRecord( trec, "IFNO" ) ;
437 *uintRF = (uInt)spwId ;
438
439 // polarization information
440 tcolr = tpoolr->construct( poltab, "NUM_CORR" ) ;
441 Int npol = tcolr->asInt( polId ) ;
442 tpoolr->destroy( tcolr ) ;
443 ROArrayColumn<Int> *roArrICol = new ROArrayColumn<Int>( poltab, "CORR_TYPE" ) ;
444 Vector<Int> corrtype = (*roArrICol)( polId ) ;
445 delete roArrICol ;
446// os_ << "npol = " << npol << LogIO::POST ;
447// os_ << "corrtype = " << corrtype << LogIO::POST ;
448 sdh.npol = max( sdh.npol, npol ) ;
449 if ( sdh.poltype == "" ) sdh.poltype = getPolType( corrtype[0] ) ;
450 // source information
451 //os_ << "srcId = " << srcId << ", spwId = " << spwId << LogIO::POST ;
452 MSSource srctabSel = srctab( srctab.col("SOURCE_ID") == srcId && srctab.col("SPECTRAL_WINDOW_ID") == spwId ) ;
453 if ( srctabSel.nrow() == 0 ) {
454 srctabSel = srctab( srctab.col("SOURCE_ID") == srcId && srctab.col("SPECTRAL_WINDOW_ID") == -1 ) ;
455 }
456 tcolr = tpoolr->construct( srctabSel, "NAME" ) ;
457 String srcName = tcolr->asString( 0 ) ;
458 tpoolr->destroy( tcolr ) ;
459
460 // SRCNAME
461 strRF.attachToRecord( trec, "SRCNAME" ) ;
462 *strRF = srcName ;
463
464 //os_ << "srcName = " << srcName << LogIO::POST ;
465 ROArrayColumn<Double> *roArrDCol = new ROArrayColumn<Double>( srctabSel, "PROPER_MOTION" ) ;
466 Array<Double> srcPM = (*roArrDCol)( 0 ) ;
467 delete roArrDCol ;
468
469 // SRCPROPERMOTION
470 RecordFieldPtr< Array<Double> > darrRF( trec, "SRCPROPERMOTION" ) ;
471 *darrRF = srcPM ;
472
473 //os_ << "srcPM = " << srcPM << LogIO::POST ;
474 roArrDCol = new ROArrayColumn<Double>( srctabSel, "DIRECTION" ) ;
475 Array<Double> srcDir = (*roArrDCol)( 0 ) ;
476 delete roArrDCol ;
477
478 // SRCDIRECTION
479 darrRF.attachToRecord( trec, "SRCDIRECTION" ) ;
480 *darrRF = srcDir ;
481
482 //os_ << "srcDir = " << srcDir << LogIO::POST ;
483 ROScalarMeasColumn<MDirection> *tmpMeasCol = new ROScalarMeasColumn<MDirection>( srctabSel, "DIRECTION" ) ;
484 MDirection md = (*tmpMeasCol)( 0 ) ;
485 delete tmpMeasCol ;
486
487 // for MOLECULES subtable
488 tcolr = tpoolr->construct( srctabSel, "NUM_LINES" ) ;
489 Int numLines = tcolr->asInt( 0 ) ;
490 tpoolr->destroy( tcolr ) ;
491// os_ << "numLines = " << numLines << LogIO::POST ;
492
493 Vector<Double> restFreqs( numLines, 0.0 ) ;
494 Vector<String> transitionName( numLines, "" ) ;
495 Vector<Double> sysVels ;
496 Double sysVel = 0.0 ;
497 if ( numLines != 0 ) {
498 if ( srctabSel.tableDesc().isColumn( "REST_FREQUENCY" ) ) {
499 sharedQDArrCol = new ROArrayQuantColumn<Double>( srctabSel, "REST_FREQUENCY" ) ;
500 Array< Quantum<Double> > qRestFreqs = (*sharedQDArrCol)( 0 ) ;
501 delete sharedQDArrCol ;
502 for ( int i = 0 ; i < numLines ; i++ ) {
503 restFreqs[i] = qRestFreqs( IPosition( 1, i ) ).getValue( "Hz" ) ;
504 }
505 }
506 //os_ << "restFreqs = " << restFreqs << LogIO::POST ;
507 if ( srctabSel.tableDesc().isColumn( "TRANSITION" ) ) {
508 ROArrayColumn<String> transitionCol( srctabSel, "TRANSITION" ) ;
509 if ( transitionCol.isDefined( 0 ) )
510 transitionName = transitionCol( 0 ) ;
511 //os_ << "transitionNameCol.nrow() = " << transitionCol.nrow() << LogIO::POST ;
512 }
513 if ( srctabSel.tableDesc().isColumn( "SYSVEL" ) ) {
514 roArrDCol = new ROArrayColumn<Double>( srctabSel, "SYSVEL" ) ;
515 sysVels = (*roArrDCol)( 0 ) ;
516 delete roArrDCol ;
517 }
518 if ( !sysVels.empty() ) {
519 //os_ << "sysVels.shape() = " << sysVels.shape() << LogIO::POST ;
520 // NB: assume all SYSVEL values are the same
521 sysVel = sysVels( IPosition(1,0) ) ;
522 }
523 }
524
525 // SRCVELOCITY
526 RecordFieldPtr<Double> doubleRF( trec, "SRCVELOCITY" ) ;
527 *doubleRF = sysVel ;
528
529// os_ << "sysVel = " << sysVel << LogIO::POST ;
530
531 uInt molId = table_->molecules().addEntry( restFreqs, transitionName, transitionName ) ;
532
533 // MOLECULE_ID
534 uintRF.attachToRecord( trec, "MOLECULE_ID" ) ;
535 *uintRF = molId ;
536
537 // spectral setup
538 MeasFrame mf( me, mp, md ) ;
539 tcolr = tpoolr->construct( spwtab, "MEAS_FREQ_REF" ) ;
540 MFrequency::Types freqRef = MFrequency::castType((uInt)(tcolr->asInt(spwId))) ;
541 tpoolr->destroy( tcolr ) ;
542 tcolr = tpoolr->construct( spwtab, "NUM_CHAN" ) ;
543 Int nchan = tcolr->asInt( spwId ) ;
544 tpoolr->destroy( tcolr ) ;
545 Bool even = False ;
546 if ( (nchan/2)*2 == nchan ) even = True ;
547 sdh.nchan = max( sdh.nchan, nchan ) ;
548 ROScalarQuantColumn<Double> *tmpQuantCol = new ROScalarQuantColumn<Double>( spwtab, "TOTAL_BANDWIDTH" ) ;
549 Double totbw = (*tmpQuantCol)( spwId ).getValue( "Hz" ) ;
550 delete tmpQuantCol ;
551 sdh.bandwidth = max( sdh.bandwidth, totbw ) ;
552 if ( sdh.freqref == "" )
553 //sdh.freqref = MFrequency::showType( freqRef ) ;
554 sdh.freqref = "LSRK" ;
555 if ( sdh.reffreq == -1.0 ) {
556 tmpQuantCol = new ROScalarQuantColumn<Double>( spwtab, "REF_FREQUENCY" ) ;
557 Quantum<Double> qreffreq = (*tmpQuantCol)( spwId ) ;
558 delete tmpQuantCol ;
559 if ( freqRef == MFrequency::LSRK ) {
560 sdh.reffreq = qreffreq.getValue("Hz") ;
561 }
562 else {
563 MFrequency::Convert tolsr( freqRef, MFrequency::Ref( MFrequency::LSRK, mf ) ) ;
564 sdh.reffreq = tolsr( qreffreq ).get("Hz").getValue() ;
565 }
566 }
567 Int refchan = nchan / 2 ;
568 IPosition refip( 1, refchan ) ;
569 Double refpix = 0.5*(nchan-1) ;
570 Double refval = 0.0 ;
571 sharedQDArrCol = new ROArrayQuantColumn<Double>( spwtab, "CHAN_WIDTH" ) ;
572 Double increment = (*sharedQDArrCol)( spwId )( refip ).getValue( "Hz" ) ;
573 delete sharedQDArrCol ;
574 //os_ << "nchan = " << nchan << " refchan = " << refchan << "(even=" << even << ") refpix = " << refpix << LogIO::POST ;
575 sharedQDArrCol = new ROArrayQuantColumn<Double>( spwtab, "CHAN_FREQ" ) ;
576 Vector< Quantum<Double> > chanFreqs = (*sharedQDArrCol)( spwId ) ;
577 delete sharedQDArrCol ;
578 if ( freqRef == MFrequency::LSRK ) {
579 if ( even ) {
580 IPosition refip0( 1, refchan-1 ) ;
581 Double refval0 = chanFreqs(refip0).getValue("Hz") ;
582 Double refval1 = chanFreqs(refip).getValue("Hz") ;
583 refval = 0.5 * ( refval0 + refval1 ) ;
584 }
585 else {
586 refval = chanFreqs(refip).getValue("Hz") ;
587 }
588 }
589 else {
590 MFrequency::Convert tolsr( freqRef, MFrequency::Ref( MFrequency::LSRK, mf ) ) ;
591 if ( even ) {
592 IPosition refip0( 1, refchan-1 ) ;
593 Double refval0 = chanFreqs(refip0).getValue("Hz") ;
594 Double refval1 = chanFreqs(refip).getValue("Hz") ;
595 refval = 0.5 * ( refval0 + refval1 ) ;
596 refval = tolsr( refval ).get("Hz").getValue() ;
597 }
598 else {
599 refval = tolsr( chanFreqs(refip) ).get("Hz").getValue() ;
600 }
601 }
602 uInt freqId = table_->frequencies().addEntry( refpix, refval, increment ) ;
603 if ( ifmap.find( spwId ) == ifmap.end() ) {
604 ifmap.insert( pair<Int, uInt>(spwId,freqId) ) ;
605 //os_ << "added to ifmap: (" << spwId << "," << freqId << ")" << LogIO::POST ;
606 }
607
608 // FREQ_ID
609 uintRF.attachToRecord( trec, "FREQ_ID" ) ;
610 *uintRF = freqId ;
611
612 // for TSYS and TCAL
613 Vector<MEpoch> scTime ;
614 Vector<Double> scInterval ;
615 ROArrayColumn<Float> scTsysCol ;
616 MSSysCal caltabsel ;
617 if ( isSysCal_ ) {
618 caltabsel = caltab( caltab.col("ANTENNA_ID") == antenna_ && caltab.col("FEED_ID") == feedId && caltab.col("SPECTRAL_WINDOW_ID") == spwId ).sort("TIME") ;
619 ROScalarMeasColumn<MEpoch> scTimeCol( caltabsel, "TIME" ) ;
620 scTime.resize( caltabsel.nrow() ) ;
621 for ( uInt irow = 0 ; irow < caltabsel.nrow() ; irow++ )
622 scTime[irow] = scTimeCol( irow ) ;
623 ROScalarColumn<Double> *scIntervalCol = new ROScalarColumn<Double>( caltabsel, "INTERVAL" ) ;
624 scInterval = scIntervalCol->getColumn() ;
625 delete scIntervalCol ;
626 scTsysCol.attach( caltabsel, colTsys_ ) ;
627 }
628// time1 = gettimeofday_sec() ;
629// os_ << "end 3rd iteration init: " << time1 << " (" << time1-time0 << "sec)" << LogIO::POST ;
630 //
631 // ITERATION: SCAN_NUMBER
632 //
633 TableIterator iter4( t3, "SCAN_NUMBER" ) ;
634 while( !iter4.pastEnd() ) {
635// time0 = gettimeofday_sec() ;
636// os_ << "start 4th iteration: " << time0 << LogIO::POST ;
637 Table t4 = iter4.table() ;
638 tcolr = tpoolr->construct( t4, "SCAN_NUMBER" ) ;
639 Int scanNum = tcolr->asInt( 0 ) ;
640 tpoolr->destroy( tcolr ) ;
641
642 // SCANNO
643 uintRF.attachToRecord( trec, "SCANNO" ) ;
644 *uintRF = scanNum - 1 ;
645
646// time1 = gettimeofday_sec() ;
647// os_ << "end 4th iteration init: " << time1 << " (" << time1-time0 << "sec)" << LogIO::POST ;
648 //
649 // ITERATION: STATE_ID
650 //
651 TableIterator iter5( t4, "STATE_ID" ) ;
652 while( !iter5.pastEnd() ) {
653 //time0 = gettimeofday_sec() ;
654 //os_ << "start 5th iteration: " << time0 << LogIO::POST ;
655 Table t5 = iter5.table() ;
656 tcolr = tpoolr->construct( t5, "STATE_ID" ) ;
657 Int stateId = tcolr->asInt( 0 ) ;
658 tpoolr->destroy( tcolr ) ;
659 tcolr = tpoolr->construct( stattab, "OBS_MODE" ) ;
660 String obstype = tcolr->asString( stateId ) ;
661 tpoolr->destroy( tcolr ) ;
662 if ( sdh.obstype == "" ) sdh.obstype = obstype ;
663
664 Int nrow = t5.nrow() ;
665 //time1 = gettimeofday_sec() ;
666 //os_ << "end 5th iteration init: " << time1 << " (" << time1-time0 << "sec)" << LogIO::POST ;
667
668 uInt cycle = 0 ;
669
670 Cube<Float> spArr ;
671 Cube<Bool> flArr ;
672 if ( isFloatData_ ) {
673 ROArrayColumn<Bool> mFlagCol( t5, "FLAG" ) ;
674 ROArrayColumn<Float> mFloatDataCol( t5, "FLOAT_DATA" ) ;
675 spArr = mFloatDataCol.getColumn() ;
676 flArr = mFlagCol.getColumn() ;
677 if ( sdh.fluxunit == "" ) {
678 const TableRecord &dataColKeys = mFloatDataCol.keywordSet() ;
679 if ( dataColKeys.isDefined( "UNIT" ) )
680 sdh.fluxunit = dataColKeys.asString( "UNIT" ) ;
681 }
682 }
683 else if ( isData_ ) {
684 spArr.resize( npol, nchan, nrow ) ;
685 flArr.resize( npol, nchan, nrow ) ;
686 ROArrayColumn<Bool> mFlagCol( t5, "FLAG" ) ;
687 ROArrayColumn<Complex> mDataCol( t5, "DATA" ) ;
688 for ( Int irow = 0 ; irow < nrow ; irow++ ) {
689 Bool crossOK = False ;
690 Matrix<Complex> sp = mDataCol( irow ) ;
691 Matrix<Bool> fl = mFlagCol( irow ) ;
692 Matrix<Float> spxy = spArr.xyPlane( irow ) ;
693 Matrix<Bool> flxy = flArr.xyPlane( irow ) ;
694 for ( Int ipol = 0 ; ipol < npol ; ipol++ ) {
695 if ( corrtype[ipol] == Stokes::XY || corrtype[ipol] == Stokes::YX
696 || corrtype[ipol] == Stokes::RL || corrtype[ipol] == Stokes::LR ) {
697 if ( !crossOK ) {
698 spxy.row( ipol ) = real( sp.row( ipol ) ) ;
699 flxy.row( ipol ) = fl.row( ipol ) ;
700 if ( corrtype[ipol] == Stokes::XY || corrtype[ipol] == Stokes::RL ) {
701 spxy.row( ipol+1 ) = imag( sp.row( ipol ) ) ;
702 flxy.row( ipol+1 ) = fl.row( ipol ) ;
703 }
704 else {
705 spxy.row( ipol+1 ) = imag( conj( sp.row( ipol ) ) ) ;
706 flxy.row( ipol+1 ) = fl.row( ipol ) ;
707 }
708 crossOK = True ;
709 }
710 }
711 else {
712 spxy.row( ipol ) = real( sp.row( ipol ) ) ;
713 flxy.row( ipol ) = fl.row( ipol ) ;
714 }
715 }
716 }
717 if ( sdh.fluxunit == "" ) {
718 const TableRecord &dataColKeys = mDataCol.keywordSet() ;
719 if ( dataColKeys.isDefined( "UNIT" ) )
720 sdh.fluxunit = dataColKeys.asString( "UNIT" ) ;
721 }
722 }
723 ROScalarMeasColumn<MEpoch> *mTimeCol = new ROScalarMeasColumn<MEpoch>( t5, "TIME" ) ;
724 Block<MEpoch> mTimeB( nrow ) ;
725 for ( Int irow = 0 ; irow < nrow ; irow++ )
726 mTimeB[irow] = (*mTimeCol)( irow ) ;
727 ROTableColumn *mIntervalCol = tpoolr->construct( t5, "INTERVAL" ) ;
728 ROTableColumn *mFlagRowCol = tpoolr->construct( t5, "FLAG_ROW" ) ;
729 Block<Int> sysCalIdx( nrow, -1 ) ;
730 if ( isSysCal_ ) {
731 getSysCalTime( scTime, scInterval, mTimeB, sysCalIdx ) ;
732 }
733 delete mTimeCol ;
734 Matrix<Float> defaulttsys( npol, 1, 1.0 ) ;
735 Int srcType = getSrcType( stateId, tpoolr ) ;
736 uInt diridx = 0 ;
737 MDirection::Types dirType ;
738 uInt wid = 0 ;
739 Int pidx = 0 ;
740 Bool crossOK = False ;
741 Block<uInt> polnos( npol, 99 ) ;
742 for ( Int ipol = 0 ; ipol < npol ; ipol++ ) {
743 Block<uInt> p = getPolNo( corrtype[ipol] ) ;
744 if ( p.size() > 1 ) {
745 if ( crossOK ) continue ;
746 else {
747 polnos[pidx] = p[0] ;
748 pidx++ ;
749 polnos[pidx] = p[1] ;
750 pidx++ ;
751 crossOK = True ;
752 }
753 }
754 else {
755 polnos[pidx] = p[0] ;
756 pidx++ ;
757 }
758 }
759
760 // SRCTYPE
761 intRF.attachToRecord( trec, "SRCTYPE" ) ;
762 *intRF = srcType ;
763
764 for ( Int irow = 0 ; irow < nrow ; irow++ ) {
765 // CYCLENO
766 *cycleRF = cycle ;
767
768 // FLAGROW
769 *flrRF = (uInt)mFlagRowCol->asBool( irow ) ;
770
771 // SPECTRA, FLAG
772 Matrix<Float> sp = spArr.xyPlane( irow ) ;
773 Matrix<Bool> flb = flArr.xyPlane( irow ) ;
774 Matrix<uChar> fl( flb.shape() ) ;
775 convertArray( fl, flb ) ;
776
777 // TIME
778 *timeRF = mTimeB[irow].get("d").getValue() ;
779
780 // INTERVAL
781 *intervalRF = (Double)(mIntervalCol->asdouble( irow )) ;
782
783 // TSYS
784 Matrix<Float> tsys ;
785 if ( sysCalIdx[irow] != -1 )
786 tsys = scTsysCol( irow ) ;
787 else
788 tsys = defaulttsys ;
789
790 // TCAL_ID
791 Block<uInt> tcalids( npol, 0 ) ;
792 if ( sysCalIdx[irow] != -1 ) {
793 tcalids = getTcalId( feedId, spwId, scTime[sysCalIdx[irow]] ) ;
794 }
795
796 // WEATHER_ID
797 if ( isWeather_ )
798 wid = getWeatherId( wid, mTimeB[irow].get("s").getValue() ) ;
799 *widRF = wid ;
800
801
802 // DIRECTION, AZEL, SCANRATE
803 if ( getPt_ ) {
804 Vector<Double> dir ;
805 Vector<Double> scanrate ;
806 String refString ;
807 diridx = getDirection( diridx, dir, scanrate, refString, pointtab, mTimeB[irow].get("s").getValue() ) ;
808 MDirection::getType( dirType, refString ) ;
809 mf.resetEpoch( mTimeB[irow] ) ;
810 mf.resetDirection( MDirection( MVDirection(dir), dirType ) ) ;
811 if ( refString == "J2000" ) {
812 *dirRF = dir ;
813 MDirection::Convert toazel( dirType, MDirection::Ref( MDirection::AZEL, mf ) ) ;
814 Vector<Double> azel = toazel( dir ).getAngle("rad").getValue() ;
815 *azRF = (Float)azel(0) ;
816 *elRF = (Float)azel(1) ;
817 }
818 else if ( refString(0,4) == "AZEL" ) {
819 *azRF = (Float)dir(0) ;
820 *elRF = (Float)dir(1) ;
821 MDirection::Convert toj2000( dirType, MDirection::Ref( MDirection::J2000, mf ) ) ;
822 Vector<Double> newdir = toj2000( dir ).getAngle("rad").getValue() ;
823 *dirRF = newdir ;
824 }
825 else {
826 MDirection::Convert toazel( dirType, MDirection::Ref( MDirection::AZEL, mf ) ) ;
827 Vector<Double> azel = toazel( dir ).getAngle("rad").getValue() ;
828 MDirection::Convert toj2000( dirType, MDirection::Ref( MDirection::J2000, mf ) ) ;
829 Vector<Double> newdir = toj2000( dir ).getAngle("rad").getValue() ;
830 *dirRF = newdir ;
831 *azRF = (Float)azel(0) ;
832 *elRF = (Float)azel(1) ;
833 }
834 if ( scanrate.size() != 0 ) {
835 *scrRF = scanrate ;
836 }
837 else {
838 *scrRF = defaultScanrate ;
839 }
840 }
841 else {
842 String ref = md.getRefString() ;
843 //Vector<Double> defaultDir = srcDir ;
844 MDirection::getType( dirType, "J2000" ) ;
845 if ( ref != "J2000" ) {
846 ROScalarMeasColumn<MEpoch> tmCol( pointtab, "TIME" ) ;
847 mf.resetEpoch( tmCol( 0 ) ) ;
848 MDirection::Convert toj2000( dirType, MDirection::Ref( MDirection::J2000, mf ) ) ;
849 defaultDir = toj2000( defaultDir ).getAngle("rad").getValue() ;
850 }
851 mf.resetEpoch( mTimeB[irow] ) ;
852 MDirection::Convert toazel( dirType, MDirection::Ref( MDirection::AZEL, mf ) ) ;
853 Vector<Double> azel = toazel( defaultDir ).getAngle("rad").getValue() ;
854 *azRF = (Float)azel(0) ;
855 *elRF = (Float)azel(1) ;
856 *dirRF = defaultDir ;
857 *scrRF = defaultScanrate ;
858 }
859
860 // Polarization dependent things
861 for ( Int ipol = 0 ; ipol < npol ; ipol++ ) {
862 // POLNO
863 *polnoRF = polnos[ipol] ;
864
865 //*spRF = sp.row( ipol ) ;
866 //*ucarrRF = fl.row( ipol ) ;
867 //*tsysRF = tsys.row( ipol ) ;
868 spRF.define( sp.row( ipol ) ) ;
869 ucarrRF.define( fl.row( ipol ) ) ;
870 tsysRF.define( tsys.row( ipol ) ) ;
871 *tcalidRF = tcalids[ipol] ;
872
873 // Commit row
874 stab.addRow() ;
875 row.put( stab.nrow()-1 ) ;
876 }
877
878 cycle++ ;
879 }
880 tpoolr->destroy( mIntervalCol ) ;
881 tpoolr->destroy( mFlagRowCol ) ;
882
883 //time1 = gettimeofday_sec() ;
884 //os_ << "end 5th iteration: " << time1 << " (" << time1-time0 << "sec)" << LogIO::POST ;
885
886 iter5.next() ;
887 }
888
889
890 iter4.next() ;
891 }
892
893
894 iter3.next() ;
895 }
896
897
898 iter2.next() ;
899 }
900
901
902 iter1.next() ;
903 }
904 if ( sdh.nbeam < nbeam ) sdh.nbeam = nbeam ;
905
906 iter0.next() ;
907 }
908
909
910 delete tpoolr ;
911
912
913 // Table Keywords
914 // TODO: This must be updated if writer will be replaced from STWriter to MSWriter
915// sdh.nif = ifmap.size() ;
916 sdh.nif++ ;
917 if ( ( telescopeName == "" ) || ( antennaName == telescopeName ) ) {
918 sdh.antennaname = antennaName ;
919 }
920 else {
921 sdh.antennaname = telescopeName + "//" + antennaName ;
922 }
923 if ( stationName != "" ) {
924 sdh.antennaname += "@" + stationName ;
925 }
926 ROArrayColumn<Double> pdirCol( pointtab, "DIRECTION" ) ;
927 String dirref = pdirCol.keywordSet().asRecord("MEASINFO").asString("Ref") ;
928 if ( dirref == "AZELGEO" || dirref == "AZEL" ) {
929 dirref = "J2000" ;
930 }
931 sscanf( dirref.chars()+1, "%f", &sdh.equinox ) ;
932 sdh.epoch = "UTC" ;
933 if (sdh.freqref == "TOPO") {
934 sdh.freqref = "TOPOCENT";
935 } else if (sdh.freqref == "GEO") {
936 sdh.freqref = "GEOCENTR";
937 } else if (sdh.freqref == "BARY") {
938 sdh.freqref = "BARYCENT";
939 } else if (sdh.freqref == "GALACTO") {
940 sdh.freqref = "GALACTOC";
941 } else if (sdh.freqref == "LGROUP") {
942 sdh.freqref = "LOCALGRP";
943 } else if (sdh.freqref == "CMB") {
944 sdh.freqref = "CMBDIPOL";
945 } else if (sdh.freqref == "REST") {
946 sdh.freqref = "SOURCE";
947 }
948 table_->setHeader( sdh ) ;
949
950 // save path to POINTING table
951 // 2011/3/2 TN
952 // So far, path to original POINTING table is always stored
953 // since sd tasks and regressions don't support getpt control
954 //if ( !getPt_ ) {
955 Path datapath( tablename_ ) ;
956 String pTabName = datapath.absoluteName() + "/POINTING" ;
957 stab.rwKeywordSet().define( "POINTING", pTabName ) ;
958 //}
959
960 // for GBT
961 if ( antennaName.matches( "GBT" ) ) {
962 String goTabName = datapath.absoluteName() + "/GBT_GO" ;
963 stab.rwKeywordSet().define( "GBT_GO", goTabName ) ;
964 }
965
966 // for MS created from ASDM
967 //mstable_.keywordSet().print(cout) ;
968 const TableRecord &msKeys = mstable_.keywordSet() ;
969 uInt nfields = msKeys.nfields() ;
970 for ( uInt ifield = 0 ; ifield < nfields ; ifield++ ) {
971 String name = msKeys.name( ifield ) ;
972 //os_ << "name = " << name << LogIO::POST ;
973 if ( name.find( "ASDM" ) != String::npos ) {
974 String asdmpath = msKeys.asTable( ifield ).tableName() ;
975 os_ << "ASDM table: " << asdmpath << LogIO::POST ;
976 stab.rwKeywordSet().define( name, asdmpath ) ;
977 }
978 }
979
980// double endSec = gettimeofday_sec() ;
981// os_ << "end MSFiller::fill() endSec=" << endSec << " (" << endSec-startSec << "sec)" << LogIO::POST ;
982}
983
984void MSFiller::close()
985{
986 //tablesel_.closeSubTables() ;
987 mstable_.closeSubTables() ;
988 //tablesel_.unlock() ;
989 mstable_.unlock() ;
990}
991
992Int MSFiller::getSrcType( Int stateId, boost::object_pool<ROTableColumn> *tpool )
993{
994// double startSec = gettimeofday_sec() ;
995// os_ << "start MSFiller::getSrcType() startSec=" << startSec << LogIO::POST ;
996
997 MSState statetab = mstable_.state() ;
998 ROTableColumn *sharedCol ;
999 sharedCol = tpool->construct( statetab, "OBS_MODE" ) ;
1000 String obsMode = sharedCol->asString( stateId ) ;
1001 tpool->destroy( sharedCol ) ;
1002 sharedCol = tpool->construct( statetab, "SIG" ) ;
1003 Bool sig = sharedCol->asBool( stateId ) ;
1004 tpool->destroy( sharedCol ) ;
1005 sharedCol = tpool->construct( statetab, "REF" ) ;
1006 Bool ref = sharedCol->asBool( stateId ) ;
1007 tpool->destroy( sharedCol ) ;
1008 sharedCol = tpool->construct( statetab, "CAL" ) ;
1009 Double cal = (Double)(sharedCol->asdouble( stateId )) ;
1010 tpool->destroy( sharedCol ) ;
1011 //os_ << "OBS_MODE = " << obsMode << LogIO::POST ;
1012
1013 // determine separator
1014 String sep = "" ;
1015 if ( obsMode.find( ":" ) != String::npos ) {
1016 sep = ":" ;
1017 }
1018 else if ( obsMode.find( "." ) != String::npos ) {
1019 sep = "." ;
1020 }
1021
1022 // determine SRCTYPE
1023 Int srcType = SrcType::NOTYPE ;
1024 if ( sep == ":" ) {
1025 // sep == ":"
1026 //
1027 // GBT case
1028 //
1029 // obsMode1=Nod
1030 // NOD
1031 // obsMode1=OffOn
1032 // obsMode2=PSWITCHON: PSON
1033 // obsMode2=PSWITCHOFF: PSOFF
1034 // obsMode1=??
1035 // obsMode2=FSWITCH:
1036 // SIG=1: FSON
1037 // REF=1: FSOFF
1038 // Calibration scan if CAL != 0
1039 Int epos = obsMode.find_first_of( sep ) ;
1040 Int nextpos = obsMode.find_first_of( sep, epos+1 ) ;
1041 String obsMode1 = obsMode.substr( 0, epos ) ;
1042 String obsMode2 = obsMode.substr( epos+1, nextpos-epos-1 ) ;
1043 if ( obsMode1 == "Nod" ) {
1044 srcType = SrcType::NOD ;
1045 }
1046 else if ( obsMode1 == "OffOn" ) {
1047 if ( obsMode2 == "PSWITCHON" ) srcType = SrcType::PSON ;
1048 if ( obsMode2 == "PSWITCHOFF" ) srcType = SrcType::PSOFF ;
1049 }
1050 else {
1051 if ( obsMode2 == "FSWITCH" ) {
1052 if ( sig ) srcType = SrcType::FSON ;
1053 if ( ref ) srcType = SrcType::FSOFF ;
1054 }
1055 }
1056 if ( cal > 0.0 ) {
1057 if ( srcType == SrcType::NOD )
1058 srcType = SrcType::NODCAL ;
1059 else if ( srcType == SrcType::PSON )
1060 srcType = SrcType::PONCAL ;
1061 else if ( srcType == SrcType::PSOFF )
1062 srcType = SrcType::POFFCAL ;
1063 else if ( srcType == SrcType::FSON )
1064 srcType = SrcType::FONCAL ;
1065 else if ( srcType == SrcType::FSOFF )
1066 srcType = SrcType::FOFFCAL ;
1067 else
1068 srcType = SrcType::CAL ;
1069 }
1070 }
1071 else if ( sep == "." ) {
1072 // sep == "."
1073 //
1074 // ALMA & EVLA case (MS via ASDM)
1075 //
1076 // obsMode1=CALIBRATE_*
1077 // obsMode2=ON_SOURCE: PONCAL
1078 // obsMode2=OFF_SOURCE: POFFCAL
1079 // obsMode1=OBSERVE_TARGET
1080 // obsMode2=ON_SOURCE: PON
1081 // obsMode2=OFF_SOURCE: POFF
1082 Int epos = obsMode.find_first_of( sep ) ;
1083 Int nextpos = obsMode.find_first_of( sep, epos+1 ) ;
1084 String obsMode1 = obsMode.substr( 0, epos ) ;
1085 String obsMode2 = obsMode.substr( epos+1, nextpos-epos-1 ) ;
1086 if ( obsMode1.find( "CALIBRATE_" ) == 0 ) {
1087 if ( obsMode2 == "ON_SOURCE" ) srcType = SrcType::PONCAL ;
1088 if ( obsMode2 == "OFF_SOURCE" ) srcType = SrcType::POFFCAL ;
1089 }
1090 else if ( obsMode1 == "OBSERVE_TARGET" ) {
1091 if ( obsMode2 == "ON_SOURCE" ) srcType = SrcType::PSON ;
1092 if ( obsMode2 == "OFF_SOURCE" ) srcType = SrcType::PSOFF ;
1093 }
1094 }
1095 else {
1096 if ( sig ) srcType = SrcType::SIG ;
1097 if ( ref ) srcType = SrcType::REF ;
1098 }
1099
1100 //os_ << "srcType = " << srcType << LogIO::POST ;
1101// double endSec = gettimeofday_sec() ;
1102// os_ << "end MSFiller::getSrcType() endSec=" << endSec << " (" << endSec-startSec << "sec)" << LogIO::POST ;
1103 return srcType ;
1104}
1105
1106//Vector<uInt> MSFiller::getPolNo( Int corrType )
1107Block<uInt> MSFiller::getPolNo( Int corrType )
1108{
1109// double startSec = gettimeofday_sec() ;
1110// os_ << "start MSFiller::getPolNo() startSec=" << startSec << LogIO::POST ;
1111 Block<uInt> polno( 1 ) ;
1112
1113 if ( corrType == Stokes::I || corrType == Stokes::RR || corrType == Stokes::XX ) {
1114 polno = 0 ;
1115 }
1116 else if ( corrType == Stokes::Q || corrType == Stokes::LL || corrType == Stokes::YY ) {
1117 polno = 1 ;
1118 }
1119 else if ( corrType == Stokes::U ) {
1120 polno = 2 ;
1121 }
1122 else if ( corrType == Stokes::V ) {
1123 polno = 3 ;
1124 }
1125 else if ( corrType == Stokes::RL || corrType == Stokes::XY || corrType == Stokes::LR || corrType == Stokes::RL ) {
1126 polno.resize( 2 ) ;
1127 polno[0] = 2 ;
1128 polno[1] = 3 ;
1129 }
1130 else if ( corrType == Stokes::Plinear ) {
1131 polno[0] = 1 ;
1132 }
1133 else if ( corrType == Stokes::Pangle ) {
1134 polno[0] = 2 ;
1135 }
1136 else {
1137 polno = 99 ;
1138 }
1139 //os_ << "polno = " << polno << LogIO::POST ;
1140// double endSec = gettimeofday_sec() ;
1141// os_ << "end MSFiller::getPolNo() endSec=" << endSec << " (" << endSec-startSec << "sec)" << LogIO::POST ;
1142
1143 return polno ;
1144}
1145
1146String MSFiller::getPolType( Int corrType )
1147{
1148// double startSec = gettimeofday_sec() ;
1149// os_ << "start MSFiller::getPolType() startSec=" << startSec << LogIO::POST ;
1150 String poltype = "" ;
1151
1152 if ( corrType == Stokes::I || corrType == Stokes::Q || corrType == Stokes::U || corrType == Stokes::V )
1153 poltype = "stokes" ;
1154 else if ( corrType == Stokes::XX || corrType == Stokes::YY || corrType == Stokes::XY || corrType == Stokes::YX )
1155 poltype = "linear" ;
1156 else if ( corrType == Stokes::RR || corrType == Stokes::LL || corrType == Stokes::RL || corrType == Stokes::LR )
1157 poltype = "circular" ;
1158 else if ( corrType == Stokes::Plinear || corrType == Stokes::Pangle )
1159 poltype = "linpol" ;
1160
1161// double endSec = gettimeofday_sec() ;
1162// os_ << "end MSFiller::getPolType() endSec=" << endSec << " (" << endSec-startSec << "sec)" << LogIO::POST ;
1163 return poltype ;
1164}
1165
1166void MSFiller::fillWeather()
1167{
1168// double startSec = gettimeofday_sec() ;
1169// os_ << "start MSFiller::fillWeather() startSec=" << startSec << LogIO::POST ;
1170
1171 if ( !isWeather_ ) {
1172 // add dummy row
1173 table_->weather().table().addRow(1,True) ;
1174 return ;
1175 }
1176
1177 Table mWeather = mstable_.weather() ;
1178 //Table mWeatherSel = mWeather( mWeather.col("ANTENNA_ID") == antenna_ ).sort("TIME") ;
1179 Table mWeatherSel( mWeather( mWeather.col("ANTENNA_ID") == antenna_ ).sort("TIME") ) ;
1180 //os_ << "mWeatherSel.nrow() = " << mWeatherSel.nrow() << LogIO::POST ;
1181 if ( mWeatherSel.nrow() == 0 ) {
1182 os_ << "No rows with ANTENNA_ID = " << antenna_ << ", Try -1..." << LogIO::POST ;
1183 mWeatherSel = Table( MSWeather( mWeather( mWeather.col("ANTENNA_ID") == -1 ) ) ) ;
1184 if ( mWeatherSel.nrow() == 0 ) {
1185 os_ << "No rows in WEATHER table" << LogIO::POST ;
1186 }
1187 }
1188 uInt wnrow = mWeatherSel.nrow() ;
1189 //os_ << "wnrow = " << wnrow << LogIO::POST ;
1190
1191 if ( wnrow == 0 )
1192 return ;
1193
1194 Table wtab = table_->weather().table() ;
1195 wtab.addRow( wnrow ) ;
1196
1197 ScalarColumn<Float> *fCol ;
1198 ROScalarColumn<Float> *sharedFloatCol ;
1199 if ( mWeatherSel.tableDesc().isColumn( "TEMPERATURE" ) ) {
1200 fCol = new ScalarColumn<Float>( wtab, "TEMPERATURE" ) ;
1201 sharedFloatCol = new ROScalarColumn<Float>( mWeatherSel, "TEMPERATURE" ) ;
1202 fCol->putColumn( *sharedFloatCol ) ;
1203 delete sharedFloatCol ;
1204 delete fCol ;
1205 }
1206 if ( mWeatherSel.tableDesc().isColumn( "PRESSURE" ) ) {
1207 fCol = new ScalarColumn<Float>( wtab, "PRESSURE" ) ;
1208 sharedFloatCol = new ROScalarColumn<Float>( mWeatherSel, "PRESSURE" ) ;
1209 fCol->putColumn( *sharedFloatCol ) ;
1210 delete sharedFloatCol ;
1211 delete fCol ;
1212 }
1213 if ( mWeatherSel.tableDesc().isColumn( "REL_HUMIDITY" ) ) {
1214 fCol = new ScalarColumn<Float>( wtab, "HUMIDITY" ) ;
1215 sharedFloatCol = new ROScalarColumn<Float>( mWeatherSel, "REL_HUMIDITY" ) ;
1216 fCol->putColumn( *sharedFloatCol ) ;
1217 delete sharedFloatCol ;
1218 delete fCol ;
1219 }
1220 if ( mWeatherSel.tableDesc().isColumn( "WIND_SPEED" ) ) {
1221 fCol = new ScalarColumn<Float>( wtab, "WINDSPEED" ) ;
1222 sharedFloatCol = new ROScalarColumn<Float>( mWeatherSel, "WIND_SPEED" ) ;
1223 fCol->putColumn( *sharedFloatCol ) ;
1224 delete sharedFloatCol ;
1225 delete fCol ;
1226 }
1227 if ( mWeatherSel.tableDesc().isColumn( "WIND_DIRECTION" ) ) {
1228 fCol = new ScalarColumn<Float>( wtab, "WINDAZ" ) ;
1229 sharedFloatCol = new ROScalarColumn<Float>( mWeatherSel, "WIND_DIRECTION" ) ;
1230 fCol->putColumn( *sharedFloatCol ) ;
1231 delete sharedFloatCol ;
1232 delete fCol ;
1233 }
1234 ScalarColumn<uInt> idCol( wtab, "ID" ) ;
1235 for ( uInt irow = 0 ; irow < wnrow ; irow++ )
1236 idCol.put( irow, irow ) ;
1237
1238 ROScalarQuantColumn<Double> tqCol( mWeatherSel, "TIME" ) ;
1239 ROScalarColumn<Double> tCol( mWeatherSel, "TIME" ) ;
1240 String tUnit = tqCol.getUnits() ;
1241 mwTime_ = tCol.getColumn() ;
1242 if ( tUnit == "d" )
1243 mwTime_ *= 86400.0 ;
1244 tqCol.attach( mWeatherSel, "INTERVAL" ) ;
1245 tCol.attach( mWeatherSel, "INTERVAL" ) ;
1246 String iUnit = tqCol.getUnits() ;
1247 mwInterval_ = tCol.getColumn() ;
1248 if ( iUnit == "d" )
1249 mwInterval_ *= 86400.0 ;
1250 //os_ << "mwTime[0] = " << mwTime_[0] << " mwInterval[0] = " << mwInterval_[0] << LogIO::POST ;
1251// double endSec = gettimeofday_sec() ;
1252// os_ << "end MSFiller::fillWeather() endSec=" << endSec << " (" << endSec-startSec << "sec)" << LogIO::POST ;
1253}
1254
1255void MSFiller::fillFocus()
1256{
1257// double startSec = gettimeofday_sec() ;
1258// os_ << "start MSFiller::fillFocus() startSec=" << startSec << LogIO::POST ;
1259 // tentative
1260 Table tab = table_->focus().table() ;
1261 tab.addRow( 1 ) ;
1262 ScalarColumn<uInt> idCol( tab, "ID" ) ;
1263 idCol.put( 0, 0 ) ;
1264// double endSec = gettimeofday_sec() ;
1265// os_ << "end MSFiller::fillFocus() endSec=" << endSec << " (" << endSec-startSec << "sec)" << LogIO::POST ;
1266}
1267
1268void MSFiller::fillTcal( boost::object_pool<ROTableColumn> *tpoolr )
1269{
1270// double startSec = gettimeofday_sec() ;
1271// os_ << "start MSFiller::fillTcal() startSec=" << startSec << LogIO::POST ;
1272
1273 if ( !isSysCal_ ) {
1274 // add dummy row
1275 os_ << "No SysCal rows" << LogIO::POST ;
1276 table_->tcal().table().addRow(1,True) ;
1277 Vector<Float> defaultTcal( 1, 1.0 ) ;
1278 ArrayColumn<Float> tcalCol( table_->tcal().table(), "TCAL" ) ;
1279 tcalCol.put( 0, defaultTcal ) ;
1280 return ;
1281 }
1282
1283 Table sctab = mstable_.sysCal() ;
1284 if ( sctab.nrow() == 0 ) {
1285 os_ << "No SysCal rows" << LogIO::POST ;
1286 return ;
1287 }
1288 Table sctabsel( sctab( sctab.col("ANTENNA_ID") == antenna_ ) ) ;
1289 if ( sctabsel.nrow() == 0 ) {
1290 os_ << "No SysCal rows" << LogIO::POST ;
1291 return ;
1292 }
1293 ROArrayColumn<Float> *tmpTcalCol = new ROArrayColumn<Float>( sctabsel, "TCAL" ) ;
1294 uInt npol = tmpTcalCol->shape( 0 )(0) ;
1295 delete tmpTcalCol ;
1296 //os_ << "fillTcal(): npol = " << npol << LogIO::POST ;
1297 Table tab = table_->tcal().table() ;
1298 ArrayColumn<Float> tcalCol( tab, "TCAL" ) ;
1299 ROTableColumn *sharedCol ;
1300 uInt oldnr = 0 ;
1301 uInt newnr = 0 ;
1302 TableRow row( tab ) ;
1303 TableRecord &trec = row.record() ;
1304 RecordFieldPtr<uInt> idRF( trec, "ID" ) ;
1305 RecordFieldPtr<String> timeRF( trec, "TIME" ) ;
1306 RecordFieldPtr< Array<Float> > tcalRF( trec, "TCAL" ) ;
1307 TableIterator iter0( sctabsel, "FEED_ID" ) ;
1308 while( !iter0.pastEnd() ) {
1309 Table t0 = iter0.table() ;
1310 sharedCol = tpoolr->construct( t0, "FEED_ID" ) ;
1311 Int feedId = sharedCol->asInt( 0 ) ;
1312 tpoolr->destroy( sharedCol ) ;
1313 TableIterator iter1( t0, "SPECTRAL_WINDOW_ID" ) ;
1314 while( !iter1.pastEnd() ) {
1315 Table t1 = iter1.table() ;
1316 sharedCol = tpoolr->construct( t1, "SPECTRAL_WINDOW_ID" ) ;
1317 Int spwId = sharedCol->asInt( 0 ) ;
1318 tpoolr->destroy( sharedCol ) ;
1319 tmpTcalCol = new ROArrayColumn<Float>( t1, colTcal_ ) ;
1320 ROScalarQuantColumn<Double> scTimeCol( t1, "TIME" ) ;
1321 Vector<uInt> idminmax( 2, oldnr ) ;
1322 for ( uInt irow = 0 ; irow < t1.nrow() ; irow++ ) {
1323 String sTime = MVTime( scTimeCol(irow) ).string( MVTime::YMD ) ;
1324 *timeRF = sTime ;
1325 uInt idx = oldnr ;
1326 Matrix<Float> subtcal = (*tmpTcalCol)( irow ) ;
1327 for ( uInt ipol = 0 ; ipol < npol ; ipol++ ) {
1328 *idRF = idx++ ;
1329 //*tcalRF = subtcal.row( ipol ) ;
1330 tcalRF.define( subtcal.row( ipol ) ) ;
1331
1332 // commit row
1333 tab.addRow() ;
1334 row.put( tab.nrow()-1 ) ;
1335
1336 newnr++ ;
1337 }
1338 idminmax[0] = oldnr ;
1339 idminmax[1] = newnr - 1 ;
1340 oldnr = newnr ;
1341
1342 String key = keyTcal( feedId, spwId, sTime ) ;
1343 tcalrec_.define( key, idminmax ) ;
1344 }
1345 delete tmpTcalCol ;
1346 iter1++ ;
1347 }
1348 iter0++ ;
1349 }
1350
1351 //tcalrec_.print( std::cout ) ;
1352// double endSec = gettimeofday_sec() ;
1353// os_ << "end MSFiller::fillTcal() endSec=" << endSec << " (" << endSec-startSec << "sec)" << LogIO::POST ;
1354}
1355
1356uInt MSFiller::getWeatherId( uInt idx, Double wtime )
1357{
1358// double startSec = gettimeofday_sec() ;
1359// os_ << "start MSFiller::getWeatherId() startSec=" << startSec << LogIO::POST ;
1360 uInt nrow = mwTime_.size() ;
1361 if ( nrow < 2 )
1362 return 0 ;
1363 uInt wid = nrow ;
1364 for ( uInt i = idx ; i < nrow-1 ; i++ ) {
1365 Double tStart = mwTime_[i]-0.5*mwInterval_[i] ;
1366 // use of INTERVAL column is problematic
1367 // since there are "blank" time of weather monitoring
1368 //Double tEnd = tStart + mwInterval_[i] ;
1369 Double tEnd = mwTime_[i+1]-0.5*mwInterval_[i+1] ;
1370 //os_ << "tStart = " << tStart << " dtEnd = " << tEnd-tStart << " dwtime = " << wtime-tStart << LogIO::POST ;
1371 if ( wtime >= tStart && wtime <= tEnd ) {
1372 wid = i ;
1373 break ;
1374 }
1375 }
1376 if ( wid == nrow ) {
1377 uInt i = nrow - 1 ;
1378 Double tStart = mwTime_[i-1]+0.5*mwInterval_[i-1] ;
1379 Double tEnd = mwTime_[i]+0.5*mwInterval_[i] ;
1380 //os_ << "tStart = " << tStart << " dtEnd = " << tEnd-tStart << " dwtime = " << wtime-tStart << LogIO::POST ;
1381 if ( wtime >= tStart && wtime <= tEnd )
1382 wid = i-1 ;
1383 else
1384 wid = i ;
1385 }
1386
1387 //if ( wid == nrow )
1388 //os_ << LogIO::WARN << "Couldn't find correct WEATHER_ID for time " << wtime << LogIO::POST ;
1389
1390// double endSec = gettimeofday_sec() ;
1391// os_ << "end MSFiller::getWeatherId() endSec=" << endSec << " (" << endSec-startSec << "sec)" << LogIO::POST ;
1392 return wid ;
1393}
1394
1395void MSFiller::getSysCalTime( Vector<MEpoch> &scTime, Vector<Double> &scInterval, Block<MEpoch> &tcol, Block<Int> &tidx )
1396{
1397// double startSec = gettimeofday_sec() ;
1398// os_ << "start MSFiller::getSysCalTime() startSec=" << startSec << LogIO::POST ;
1399
1400 if ( !isSysCal_ )
1401 return ;
1402
1403 uInt nrow = tidx.nelements() ;
1404 if ( scTime.nelements() == 0 )
1405 return ;
1406 else if ( scTime.nelements() == 1 ) {
1407 tidx[0] = 0 ;
1408 return ;
1409 }
1410 uInt scnrow = scTime.nelements() ;
1411 uInt idx = 0 ;
1412 const Double half = 0.5e0 ;
1413 // execute binary search
1414 idx = binarySearch( scTime, tcol[0].get( "s" ).getValue() ) ;
1415 if ( idx != 0 )
1416 idx -= 1 ;
1417 for ( uInt i = 0 ; i < nrow ; i++ ) {
1418 Double t = tcol[i].get( "s" ).getValue() ;
1419 Double tsc = scTime[0].get( "s" ).getValue() ;
1420 if ( t < tsc ) {
1421 tidx[i] = 0 ;
1422 continue ;
1423 }
1424 for ( uInt j = idx ; j < scnrow-1 ; j++ ) {
1425 Double tsc1 = scTime[j].get( "s" ).getValue() ;
1426 Double dt1 = scInterval[j] ;
1427 Double tsc2 = scTime[j+1].get( "s" ).getValue() ;
1428 Double dt2 = scInterval[j+1] ;
1429 if ( t > tsc1-half*dt1 && t <= tsc2-half*dt2 ) {
1430 tidx[i] = j ;
1431 idx = j ;
1432 break ;
1433 }
1434 }
1435 if ( tidx[i] == -1 ) {
1436// Double tsc = scTime[scnrow-1].get( "s" ).getValue() ;
1437// Double dt = scInterval[scnrow-1] ;
1438// if ( t <= tsc+0.5*dt ) {
1439// tidx[i] = scnrow-1 ;
1440// }
1441 tidx[i] = scnrow-1 ;
1442 }
1443 }
1444// double endSec = gettimeofday_sec() ;
1445// os_ << "end MSFiller::getSysCalTime() endSec=" << endSec << " (" << endSec-startSec << "sec) scnrow = " << scnrow << " tcol.nelements = " << tcol.nelements() << LogIO::POST ;
1446 return ;
1447}
1448
1449Block<uInt> MSFiller::getTcalId( Int fid, Int spwid, MEpoch &t )
1450{
1451// double startSec = gettimeofday_sec() ;
1452// os_ << "start MSFiller::getTcalId() startSec=" << startSec << LogIO::POST ;
1453 //if ( table_->tcal().table().nrow() == 0 ) {
1454 if ( !isSysCal_ ) {
1455 os_ << "No TCAL rows" << LogIO::POST ;
1456 Block<uInt> tcalids( 0 ) ;
1457 return tcalids ;
1458 }
1459 //String sctime = MVTime( Quantum<Double>(t,"s") ).string(MVTime::YMD) ;
1460 String sctime = MVTime( t.getValue() ).string(MVTime::YMD) ;
1461 String key = keyTcal( fid, spwid, sctime ) ;
1462 if ( !tcalrec_.isDefined( key ) ) {
1463 os_ << "No TCAL rows" << LogIO::POST ;
1464 Block<uInt> tcalids( 0 ) ;
1465 return tcalids ;
1466 }
1467 Vector<uInt> ids = tcalrec_.asArrayuInt( key ) ;
1468 uInt npol = ids[1] - ids[0] + 1 ;
1469 Block<uInt> tcalids( npol ) ;
1470 tcalids[0] = ids[0] ;
1471 tcalids[1] = ids[1] ;
1472 for ( uInt ipol = 2 ; ipol < npol ; ipol++ )
1473 tcalids[ipol] = ids[0] + ipol - 1 ;
1474
1475// double endSec = gettimeofday_sec() ;
1476// os_ << "end MSFiller::getTcalId() endSec=" << endSec << " (" << endSec-startSec << "sec)" << LogIO::POST ;
1477 return tcalids ;
1478}
1479
1480uInt MSFiller::getDirection( uInt idx, Vector<Double> &dir, Vector<Double> &srate, String &ref, MSPointing &tab, Double t )
1481{
1482// double startSec = gettimeofday_sec() ;
1483// os_ << "start MSFiller::getDirection() startSec=" << startSec << LogIO::POST ;
1484 // assume that cols is sorted by TIME
1485 Bool doInterp = False ;
1486 //uInt nrow = cols.nrow() ;
1487 uInt nrow = tab.nrow() ;
1488 if ( nrow == 0 )
1489 return 0 ;
1490 ROScalarMeasColumn<MEpoch> tcol( tab, "TIME" ) ;
1491 ROArrayMeasColumn<MDirection> dmcol( tab, "DIRECTION" ) ;
1492 ROArrayColumn<Double> dcol( tab, "DIRECTION" ) ;
1493 // binary search if idx == 0
1494 if ( idx == 0 ) {
1495 uInt nrowb = 75000 ;
1496 if ( nrow > nrowb ) {
1497 uInt nblock = nrow / nrowb + 1 ;
1498 for ( uInt iblock = 0 ; iblock < nblock ; iblock++ ) {
1499 uInt high = min( nrowb, nrow-iblock*nrowb ) ;
1500
1501 if ( tcol( high-1 ).get( "s" ).getValue() < t ) {
1502 idx = iblock * nrowb ;
1503 continue ;
1504 }
1505
1506 Vector<MEpoch> tarr( high ) ;
1507 for ( uInt irow = 0 ; irow < high ; irow++ ) {
1508 tarr[irow] = tcol( iblock*nrowb+irow ) ;
1509 }
1510
1511 uInt bidx = binarySearch( tarr, t ) ;
1512
1513 idx = iblock * nrowb + bidx ;
1514 break ;
1515 }
1516 }
1517 else {
1518 Vector<MEpoch> tarr( nrow ) ;
1519 for ( uInt irow = 0 ; irow < nrow ; irow++ ) {
1520 tarr[irow] = tcol( irow ) ;
1521 }
1522 idx = binarySearch( tarr, t ) ;
1523 }
1524 }
1525 // ensure that tcol(idx) < t
1526 //os_ << "tcol(idx) = " << tcol(idx).get("s").getValue() << " t = " << t << " diff = " << tcol(idx).get("s").getValue()-t << endl ;
1527 while ( tcol(idx).get("s").getValue() > t && idx > 0 )
1528 idx-- ;
1529 //os_ << "idx = " << idx << LogIO::POST ;
1530
1531 // index search
1532 for ( uInt i = idx ; i < nrow ; i++ ) {
1533 Double tref = tcol( i ).get( "s" ).getValue() ;
1534 if ( tref == t ) {
1535 idx = i ;
1536 break ;
1537 }
1538 else if ( tref > t ) {
1539 if ( i == 0 ) {
1540 idx = i ;
1541 }
1542 else {
1543 idx = i-1 ;
1544 doInterp = True ;
1545 }
1546 break ;
1547 }
1548 else {
1549 idx = nrow - 1 ;
1550 }
1551 }
1552 //os_ << "searched idx = " << idx << LogIO::POST ;
1553
1554 //os_ << "dmcol(idx).shape() = " << dmcol(idx).shape() << LogIO::POST ;
1555 IPosition ip( dmcol(idx).shape().nelements(), 0 ) ;
1556 //os_ << "ip = " << ip << LogIO::POST ;
1557 ref = dmcol(idx)(ip).getRefString() ;
1558 //os_ << "ref = " << ref << LogIO::POST ;
1559 if ( doInterp ) {
1560 //os_ << "do interpolation" << LogIO::POST ;
1561 //os_ << "dcol(idx).shape() = " << dcol(idx).shape() << LogIO::POST ;
1562 Double tref0 = tcol(idx).get("s").getValue() ;
1563 Double tref1 = tcol(idx+1).get("s").getValue() ;
1564 Matrix<Double> mdir0 = dcol( idx ) ;
1565 Matrix<Double> mdir1 = dcol( idx+1 ) ;
1566 Vector<Double> dir0 = mdir0.column( 0 ) ;
1567 //os_ << "dir0 = " << dir0 << LogIO::POST ;
1568 Vector<Double> dir1 = mdir1.column( 0 ) ;
1569 //os_ << "dir1 = " << dir1 << LogIO::POST ;
1570 Double dt0 = t - tref0 ;
1571 Double dt1 = tref1 - t ;
1572 dir.reference( (dt0*dir1+dt1*dir0)/(dt0+dt1) ) ;
1573 if ( mdir0.ncolumn() > 1 ) {
1574 if ( dt0 >= dt1 )
1575 srate.reference( mdir0.column( 1 ) ) ;
1576 else
1577 srate.reference( mdir1.column( 1 ) ) ;
1578 }
1579 //os_ << "dir = " << dir << LogIO::POST ;
1580 }
1581 else {
1582 //os_ << "no interpolation" << LogIO::POST ;
1583 Matrix<Double> mdir0 = dcol( idx ) ;
1584 dir.reference( mdir0.column( 0 ) ) ;
1585 if ( mdir0.ncolumn() > 1 )
1586 srate.reference( mdir0.column( 1 ) ) ;
1587 }
1588
1589// double endSec = gettimeofday_sec() ;
1590// os_ << "end MSFiller::getDirection() endSec=" << endSec << " (" << endSec-startSec << "sec)" << LogIO::POST ;
1591 return idx ;
1592}
1593
1594String MSFiller::keyTcal( Int feedid, Int spwid, String stime )
1595{
1596 String sfeed = "FEED" + String::toString( feedid ) ;
1597 String sspw = "SPW" + String::toString( spwid ) ;
1598 return sfeed+":"+sspw+":"+stime ;
1599}
1600
1601uInt MSFiller::binarySearch( Vector<MEpoch> &timeList, Double target )
1602{
1603 Int low = 0 ;
1604 Int high = timeList.nelements() ;
1605 uInt idx = 0 ;
1606
1607 while ( low <= high ) {
1608 idx = (Int)( 0.5 * ( low + high ) ) ;
1609 Double t = timeList[idx].get( "s" ).getValue() ;
1610 if ( t < target )
1611 low = idx + 1 ;
1612 else if ( t > target )
1613 high = idx - 1 ;
1614 else
1615 return idx ;
1616 }
1617
1618 idx = max( 0, min( low, high ) ) ;
1619
1620 return idx ;
1621
1622}
1623
1624} ;
1625
Note: See TracBrowser for help on using the repository browser.