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

Last change on this file since 2218 was 2218, 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...

Get frequency reference frame from the data.


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