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.