source: trunk/external-alma/asdm2ASAP/ASDMFiller.cc @ 2220

Last change on this file since 2220 was 2220, checked in by Takeshi Nakazato, 13 years ago

New Development: No

JIRA Issue: Yes CAS-1913

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...

Number of IFs is not a number of rows of SpectralWindow? table,
but a number of frequency groups.
When freqGroup is not defined, number of IFs is set to number
of non-WVR spectral windows plus 1 (WVR spectral window).


File size: 17.8 KB
Line 
1#include<iostream>
2
3#include <STHeader.h>
4
5#include <measures/Measures/MEpoch.h>
6#include <measures/Measures/MPosition.h>
7#include <measures/Measures/MDirection.h>
8#include <measures/Measures/MCDirection.h>
9#include <measures/Measures/MeasFrame.h>
10#include <measures/Measures/MeasConvert.h>
11#include <casa/Arrays/Vector.h>
12#include <casa/Arrays/Matrix.h>
13#include <casa/Quanta/MVTime.h>
14#include <casa/Logging/LogMessage.h>
15
16#include "ASDMFiller.h"
17
18using namespace std ;
19using namespace casa ;
20using namespace asap ;
21
22ASDMFiller::ASDMFiller( CountedPtr<Scantable> stable )
23  : FillerBase( stable ),
24    antennaId_( -1 ),
25    antennaName_( "" ),
26    className_("ASDMFiller")
27{
28  reader_ = new ASDMReader() ;
29}
30
31ASDMFiller::~ASDMFiller()
32{
33  // nothing to do?
34  logsink_ = 0 ;
35}
36
37void ASDMFiller::setLogger( CountedPtr<LogSinkInterface> &logsink )
38{
39  logsink_ = logsink ;
40  if ( !(reader_.null()) ) {
41    reader_->setLogger( logsink ) ;
42  }
43}
44
45bool ASDMFiller::open( const string &filename, const Record &rec )
46{
47  String funcName = "open" ;
48  bool status = reader_->open( filename, rec ) ;
49
50  antennaId_ = reader_->getAntennaId() ;
51  antennaName_ = reader_->getAntennaName() ;
52
53  //logsink->postLocally( LogMessage("antennaId_ = "+String::toString(antennaId_),LogOrigin(className_,funcName,WHERE)) ) ;
54  //logsink->postLocally( LogMessage("antennaName_ = "+antennaName_,LogOrigin(className_,funcName,WHERE)) ) ;
55
56  return status ;
57}
58
59void ASDMFiller::fill()
60{
61  String funcName = "fill" ;
62
63  // header
64  fillHeader() ;
65
66  // set Frame for FREQUENCIES table
67  string sFreqFrame = reader_->getFrame() ;
68  MFrequency::Types freqFrame = toFrameType( sFreqFrame ) ;
69  table_->frequencies().setFrame( freqFrame, false ) ;
70  table_->frequencies().setFrame( freqFrame, true ) ;
71  //logsink_->postLocally( LogMessage("sFreqFrame = "+sFreqFrame,LogOrigin(className_,funcName,WHERE)) ) ;
72 
73  Vector<casa::Double> antpos = table_->getHeader().antennaposition ;
74
75  //STHeader hdr = table_->getHeader() ;
76 
77  // data selection
78  reader_->select() ;
79
80  // pick up valid configDescriptionId
81  Vector<uInt> configDescIdList = reader_->getConfigDescriptionIdList() ;
82  uInt numConfigDescId = configDescIdList.size() ;
83
84  //logsink->postLocally( LogMessage("configDescIdList = "+String::toString(configDescIdList),LogOrigin(className_,funcName,WHERE)) ) ;
85
86  // get field list
87  Vector<uInt> fieldIdList = reader_->getFieldIdList() ;
88  uInt numFieldId = fieldIdList.size() ;
89
90  //logsink->postLocally( LogMessage("fieldIdList = "+String::toString(fieldIdList),LogOrigin(className_,funcName,WHERE)) ) ;
91
92  // BEAMNO is always 0 since ALMA antenna is single beam
93  uInt beamno = 0 ;
94
95  // REFBEAMNO is -1
96  setReferenceBeam() ;
97
98  // fill FOCUS_ID and add FOCUS row if necessary
99  setFocus() ;
100
101  for ( uInt icon = 0 ; icon < numConfigDescId ; icon++ ) {
102    for ( unsigned int ifield = 0 ; ifield < numFieldId ; ifield++ ) {
103      //logsink_->postLocally( LogMessage("start configDescId "+String::toString(configDescIdList[icon])+" fieldId "+String::toString(fieldIdList[ifield]),LogOrigin(className_,funcName,WHERE)) ) ;
104
105      //Bool status = reader_->setMainRow( configDescIdList[icon], fieldIdList[ifield] ) ;
106      if ( !(reader_->setMainRow( configDescIdList[icon], fieldIdList[ifield] )) ) {
107        //logsink_->postLocally( LogMessage("skip configDescId "+String::toString(configDescIdList[icon])+" fieldId "+String::toString(fieldIdList[ifield]),LogOrigin(className_,funcName,WHERE)) ) ;
108        continue ;
109      }
110
111      // number of rows
112      uInt nrow = reader_->getNumMainRow() ;
113
114      //logsink_->postLocally( LogMessage("There are "+String::toString(nrow)+" rows in Main table corresponding to configDescId "+String::toString(configDescIdList[icon])+" fieldId "+String::toString(fieldIdList[ifield]),LogOrigin(className_,funcName,WHERE)) ) ;
115     
116      // CYCLENO
117      unsigned int cycleno = 0 ;
118
119      for ( uInt irow = 0 ; irow < nrow ; irow++ ) {
120
121        // set main row
122        if ( !(reader_->setMainRow( irow )) ) {
123          // skip row since the row doesn't have valid configDescId
124          //logsink_->postLocally( LogMessage("skip "+String::toString(irow),LogOrigin(className_,funcName,WHERE)) ) ;
125          continue ;
126        }
127
128        // scan and subscan
129        unsigned int scanno = reader_->getScanNo() ;
130        //uInt subscanno = reader_->getSubscanNo() ;
131
132        // set data
133        if ( !(reader_->setData()) ) {
134          // skip row since reader failed to retrieve data
135          //logsink_->postLocally( LogMessage("skip "+String::toString(irow),LogOrigin(className_,funcName,WHERE)) ) ;
136          continue ;
137        }
138
139        unsigned int numData = reader_->getNumData() ;
140        double refpix = 0.0 ;
141        double refval = 0.0 ;
142        double incr = 0.0 ;
143
144        for ( unsigned int idata = 0 ; idata < numData ; idata++ ) {
145
146          // subscan number
147          unsigned int subscanno = reader_->getSubscanNo( idata ) ;
148
149          // IFNO
150          uInt ifno = reader_->getIFNo( idata ) ;
151
152
153          // REFPIX, REFVAL, INCREMENT
154          String ifkey = getIFKey( ifno ) ;
155          if ( ifrec_.isDefined( ifkey ) ) {
156            getFrequencyRec( ifkey, refpix, refval, incr ) ;
157          }
158          else {
159            reader_->getFrequency( idata, refpix, refval, incr ) ;
160            setFrequencyRec( ifkey, refpix, refval, incr ) ;
161          }
162
163          // fill FREQ_ID and add FREQUENCIES row if necessary
164          setFrequency( (casa::Double)refpix, (casa::Double)refval, (casa::Double)incr ) ;
165
166
167          // rest frequency
168          vector<double> rf = reader_->getRestFrequency( idata ) ;
169         
170          // fill MOLECULE_ID and add MOLECULES row if necessary
171          Vector<casa::Double> restFreqs( rf.size() ) ;
172          for ( uInt i = 0 ; i < rf.size() ; i++ )
173            restFreqs[i] = (casa::Double)(rf[i]) ;
174          setMolecule( restFreqs ) ;
175         
176
177          // time and interval
178          casa::Double mjd = (casa::Double)(reader_->getTime( idata )) ;
179          casa::Double interval = (casa::Double)(reader_->getInterval( idata )) ;
180
181          // fill TIME and INTERVAL
182          setTime( mjd, interval ) ;
183
184
185          // source spec
186          string srcname = reader_->getSourceName( idata ) ;
187          string fieldname = reader_->getFieldName( idata ) ;
188          int srctype = reader_->getSrcType( scanno, subscanno ) ;
189          vector<double> srcDirection = reader_->getSourceDirection( idata ) ;
190          vector<double> srcProperMotion = reader_->getSourceProperMotion( idata ) ;
191          double sysVel = reader_->getSysVel( idata ) ;
192         
193          // fill SRCNAME, SRCTYPE, FIELDNAME, SRCDIRECTION, SRCPROPERMOTION, and SRCVELOCITY
194          Vector<casa::Double> srcDir( 2 ) ;
195          srcDir[0] = (casa::Double)(srcDirection[0]) ;
196          srcDir[1] = (casa::Double)(srcDirection[1]) ;
197          Vector<casa::Double> srcPM( 2 ) ;
198          srcPM[0] = (casa::Double)(srcProperMotion[0]) ;
199          srcPM[1] = (casa::Double)(srcProperMotion[1]) ;
200          setSource( srcname, srctype, fieldname, srcDir, srcPM, (casa::Double)sysVel ) ;
201
202          // fill FLAGROW
203          unsigned int flagrow = reader_->getFlagRow( idata ) ;
204          setFlagrow( (uInt)flagrow ) ;
205
206          // fill WEATHER_ID and add WEATHER row if necessary
207          float temperature ;
208          float pressure ;
209          float humidity ;
210          float windspeed ;
211          float windaz ;
212          reader_->getWeatherInfo( idata,
213                                   temperature,
214                                   pressure,
215                                   humidity,
216                                   windspeed,
217                                   windaz ) ;
218          setWeather2( (casa::Float)temperature,
219                       (casa::Float)pressure,
220                       (casa::Float)humidity,
221                       (casa::Float)windspeed,
222                       (casa::Float)windaz ) ;
223
224          // fill AZIMUTH, ELEVATION, DIRECTION and SCANRATE
225          vector<double> dir ;
226          double az ;
227          double el ;
228          vector<double> srate ;
229          reader_->getPointingInfo( idata,
230                                    dir,
231                                    az,
232                                    el,
233                                    srate ) ;
234          Vector<casa::Double> scanRate( 2, 0.0 ) ;
235          Vector<casa::Double> direction( 2, 0.0 ) ;
236          if ( srate.size() > 0 ) {
237            scanRate[0] = (casa::Double)(srate[0]) ;
238            scanRate[1] = (casa::Double)(srate[1]) ;
239          }
240          setScanRate( scanRate ) ;
241          if ( dir.size() > 0 ) {
242            direction[0] = (casa::Double)(dir[0]) ;
243            direction[1] = (casa::Double)(dir[1]) ;
244          }
245          else {
246            toJ2000( direction, az, el, mjd, antpos ) ;
247          }
248          //logsink_->postLocally( LogMessage("direction = "+String::toString(direction),LogOrigin(className_,funcName,WHERE)) ) ;
249          setDirection( direction, (casa::Float)az, (casa::Float)el ) ;
250
251          // loop on polarization
252          vector<unsigned int> dataShape = reader_->getDataShape( idata ) ;
253//           ostringstream oss ;
254//           for ( unsigned int i = 0 ; i < dataShape.size() ; i++ ) {
255//             if ( i == 0 )
256//               oss << "dataShape=[" << dataShape[i] << ", " ;
257//             else if ( i == dataShape.size()-1 )
258//               oss << dataShape[i] << "]"  ;
259//             else
260//               oss << dataShape[i] << ", " ;
261//           }
262//           logsink_->postLocally( LogMessage(oss.str(),LogOrigin(className_,funcName,WHERE)) ) ;
263                                     
264          //int numPol = reader_->getNumPol( idata ) ;
265          unsigned int numPol = dataShape[0] ;
266          unsigned int numChan = dataShape[1] ;
267
268          //logsink_->postLocally( LogMessage("numPol = "+String::toString(numPol),LogOrigin(className_,funcName,WHERE)) ) ;
269
270          // OPACITY
271          vector<float> tau = reader_->getOpacity( idata ) ;
272          Vector<casa::Float> opacity = toVector( tau, numPol ) ;
273
274          // SPECTRA, FLAGTRA, TSYS, TCAL
275          float *sp = reader_->getSpectrum( idata ) ;
276          vector< vector<float> > ts = reader_->getTsys( idata ) ;
277          vector< vector<float> > tc = reader_->getTcal( idata ) ;
278          Matrix<casa::Float> spectra = toMatrix( sp, numPol, numChan ) ;
279          Vector<uChar> flagtra( numChan, 0 ) ;
280          Matrix<casa::Float> tsys = toMatrix( ts, numPol, numChan ) ;
281          Matrix<casa::Float> tcal = toMatrix( tc, numPol, numChan ) ;
282//           String caltime = "" ;
283//           if ( anyNE( tcal, (casa::Float)1.0 ) )
284//             caltime = toTcalTime( mjd ) ;
285          String caltime = toTcalTime( mjd ) ;
286
287          for ( unsigned int ipol = 0 ; ipol < numPol ; ipol++ ) {
288
289            // fill SCANNO, CYCLENO, IFNO, POLNO, and BEAMNO
290            setIndex( (uInt)scanno-1, (uInt)cycleno, ifno, ipol, beamno ) ;
291
292            // fill SPECTRA, FLAGTRA, TSYS
293            setSpectrum( spectra.row(ipol), flagtra, tsys.row(ipol) ) ;
294
295            // fill TCAL_ID and add TCAL row if necessary
296            setTcal2( caltime, tcal.row(ipol) ) ;
297
298            // fill OPACITY
299            setOpacity( opacity[ipol] ) ;
300           
301            // commit row
302            commitRow() ;
303          }
304
305          // increment CYCLENO
306          cycleno++ ;
307        }
308      }
309    }
310  }
311
312  return ;
313}
314
315void ASDMFiller::close()
316{
317  reader_->close() ;
318  reader_ = 0 ;
319
320  return ;
321}
322
323void ASDMFiller::fillHeader()
324{
325  STHeader hdr ;
326
327  reader_->fillHeader( hdr.nchan,
328                       hdr.npol,
329                       hdr.nif,
330                       hdr.nbeam,
331                       hdr.observer,
332                       hdr.project,
333                       hdr.obstype,
334                       hdr.antennaname,
335                       hdr.antennaposition,
336                       hdr.equinox,
337                       hdr.freqref,
338                       hdr.reffreq,
339                       hdr.bandwidth,
340                       hdr.utc,
341                       hdr.fluxunit,
342                       hdr.epoch,
343                       hdr.poltype ) ;
344
345  setHeader( hdr ) ;
346}
347
348String ASDMFiller::getIFKey( uInt ifno )
349{
350  return "IFNO"+String::toString( ifno ) ;
351}
352
353void ASDMFiller::getFrequencyRec( String key,
354                                       double &refpix,
355                                       double &refval,
356                                       double &incr )
357{
358  Record frec = ifrec_.asRecord( key ) ;
359  refpix = frec.asdouble( "REFPIX" ) ;
360  refval = frec.asdouble( "REFVAL" ) ;
361  incr = frec.asdouble( "INCREMENT" ) ;
362}
363
364void ASDMFiller::setFrequencyRec( String key,
365                                       double refpix,
366                                       double refval,
367                                       double incr )
368{
369  Record frec ;
370  frec.define( "REFPIX", refpix ) ;
371  frec.define( "REFVAL", refval ) ;
372  frec.define( "INCREMENT", incr ) ;
373  ifrec_.defineRecord( key, frec ) ;
374}
375
376Matrix<casa::Float> ASDMFiller::toMatrix( float *sp,
377                                         unsigned int npol,
378                                         unsigned int nchan )
379{
380  Matrix<casa::Float> mSp( npol, nchan ) ;
381  if ( npol <= 2 ) {
382    // 1 or 2 polarization case
383    for ( unsigned int ich = 0 ; ich < nchan ; ich++ ) {
384      for ( unsigned int ipol = 0 ; ipol < npol ; ipol++ ) {
385        mSp(ipol,ich) = (casa::Float)(sp[npol*ich+ipol]) ;
386      }
387    }
388  }
389  else {
390    // 4 polarization case
391    for ( unsigned int ich = 0 ; ich < nchan ; ich++ ) {
392      mSp(0,ich) = (casa::Float)(sp[4*ich]) ;   // Re(XX)
393      mSp(1,ich) = (casa::Float)(sp[4*ich+4]) ; // Re(YY)
394      mSp(2,ich) = (casa::Float)(sp[4*ich+2]) ; // Re(XY)
395      mSp(3,ich) = (casa::Float)(sp[4*ich+3]) ; // Im(XY)
396    }
397  }
398  return mSp ;
399}
400
401Matrix<casa::Float> ASDMFiller::toMatrix( vector< vector<float> > &tsys,
402                                               unsigned int npol,
403                                               unsigned int nchan )
404{
405  unsigned int numRec = tsys.size() ;
406  unsigned int numChan = tsys[0].size() ;
407  Matrix<casa::Float> ret ;
408  if ( npol == numRec && nchan == numChan ) {
409    ret.resize( npol, nchan ) ;
410    for ( unsigned int ip = 0 ; ip < npol ; ip++ )
411      for ( unsigned int ic = 0 ; ic < nchan ; ic++ )
412        ret( ip, ic ) = (casa::Float)(tsys[ip][ic]) ;
413  }
414  else if ( npol == numRec && numChan == 1 ) {
415    ret.resize( npol, 1 ) ;
416    for ( unsigned int ip = 0 ; ip < npol ; ip++ )
417      ret( ip, 0 ) = (casa::Float)(tsys[0][0]) ;
418  }
419  else if ( numRec == 1 && nchan == numChan ) {
420    ret.resize( npol, nchan ) ;
421    for ( unsigned int ip = 0 ; ip < npol ; ip++ )
422      for ( unsigned int ic = 0 ; ic < nchan ; ic++ )
423        ret( ip, ic ) = (casa::Float)(tsys[0][ic]) ;
424  }
425  else if ( numRec == 1 && numChan == 1 ) {
426    ret.resize( npol, 1 ) ;
427    for ( unsigned int ip = 0 ; ip < npol ; ip++ )
428      ret( ip, 0 ) = (casa::Float)(tsys[0][0]) ;
429  }
430  else if ( numRec == 2 && npol == 4 && numChan == nchan ) {
431    // TODO: How to determine Tsys for XY?
432    //       at the moment Tsys[XY] = 0.5*(Tsys[X]+Tsys[Y])
433    ret.resize( npol, nchan ) ;
434    for ( unsigned int ic = 0 ; ic < nchan ; ic++ ) {
435      casa::Float tsysxy = (casa::Float)(0.5*(tsys[0][ic]+tsys[1][ic])) ;
436      ret( 0, ic ) = (casa::Float)(tsys[0][ic]) ;
437      ret( 1, ic ) = (casa::Float)(tsys[1][ic]) ;
438      ret( 2, ic ) = tsysxy ;
439      ret( 3, ic ) = tsysxy ;
440    }
441  }
442  else if ( numRec == 2 && npol == 4 && numChan == 1 ) {
443    // TODO: How to determine Tsys for XY?
444    //       at the moment Tsys[XY] = 0.5*(Tsys[X]+Tsys[Y])
445    ret.resize( npol, 1 ) ;
446    casa::Float tsysxy = (casa::Float)(0.5*(tsys[0][0]+tsys[1][0])) ;
447    ret( 0, 0 ) = (casa::Float)(tsys[0][0]) ;
448    ret( 1, 0 ) = (casa::Float)(tsys[1][0]) ;
449    ret( 2, 0 ) = tsysxy ;
450    ret( 3, 0 ) = tsysxy ;
451  }
452  else {
453    // I don't know how to handle ...
454    for ( unsigned int ip = 0 ; ip < npol ; ip++ )
455      for ( unsigned int ic = 0 ; ic < nchan ; ic++ )
456        ret( ip, ic ) = (casa::Float)(tsys[0][ic]) ;   
457  }
458  return ret ;
459}
460
461Vector<casa::Float> ASDMFiller::toVector( vector<float> &tau,
462                                               unsigned int npol )
463{
464  Vector<casa::Float> ret( npol ) ;
465
466  if ( npol == 4 ) {
467    ret[0] = (casa::Float)tau[0] ;
468    ret[1] = (casa::Float)tau[1] ;
469    ret[2] = 0.5 * ( ret[0] + ret[1] ) ;
470    ret[3] = ret[2] ;
471  }
472  else if ( npol == tau.size() ) {
473    for ( unsigned int ipol = 0 ; ipol < npol ; ipol++ )
474      ret[ipol] = (casa::Float)tau[ipol] ;
475  }
476  else {
477    // I don't know how to handle...
478    for ( unsigned int ipol = 0 ; ipol < npol ; ipol++ )
479      ret[ipol] = (casa::Float)tau[0] ;
480  }
481  return ret ;
482}
483
484String ASDMFiller::toTcalTime( casa::Double mjd )
485{
486  return MVTime( mjd ).string( MVTime::YMD ) ;
487}
488
489void ASDMFiller::toJ2000( Vector<casa::Double> &dir,
490                               double az,
491                               double el,
492                               casa::Double mjd,
493                               Vector<casa::Double> antpos )
494{
495  String funcName = "toJ2000" ;
496
497  Vector<casa::Double> azel( 2 ) ;
498  azel[0] = az ;
499  azel[1] = el ;
500  MEpoch me( Quantity( mjd, "d" ), MEpoch::UTC ) ;
501  Vector<Quantity> qantpos( 3 ) ;
502  qantpos[0] = Quantity( antpos[0], "m" ) ;
503  qantpos[1] = Quantity( antpos[1], "m" ) ;
504  qantpos[2] = Quantity( antpos[2], "m" ) ;
505  MPosition mp( MVPosition( qantpos ),
506                MPosition::ITRF ) ;
507//   mp.print( os_.output() ) ;
508  MeasFrame mf( me, mp ) ;
509  MDirection::Convert toj2000( MDirection::AZELGEO,
510                               MDirection::Ref( MDirection::J2000, mf ) ) ;
511  dir = toj2000( azel ).getAngle( "rad" ).getValue() ;
512  //logsink->postLocally( LogMessage("dir = "+String::toString(dir),LogOrigin(className_,funcName,WHERE)) ) ;
513}
514
515MFrequency::Types ASDMFiller::toFrameType( string &s )
516{
517  MFrequency::Types ftype = MFrequency::DEFAULT ;
518  if ( s == "LABREST" )
519    ftype = MFrequency::REST ;
520  else {
521    Bool b = MFrequency::getType( ftype, String(s) ) ;
522    if (!b)
523      ftype = MFrequency::DEFAULT ;
524  }
525  return ftype ;
526}
Note: See TracBrowser for help on using the repository browser.