source: trunk/src/MSFiller.cpp @ 1990

Last change on this file since 1990 was 1990, checked in by Takeshi Nakazato, 13 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...

Test version of MSFiller that contains benchmark codes.


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