source: tags/casa3.2.0asap/external-alma/atnf/PKSIO/NRODataset.cc@ 3010

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

New Development: No

JIRA Issue: Yes CAS-2819

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

Probably fixed an issue that sign of frequency increment is opposite for LSB.


File size: 23.6 KB
Line 
1//#---------------------------------------------------------------------------
2//# NRODataset.cc: Base class for NRO dataset.
3//#---------------------------------------------------------------------------
4//# Copyright (C) 2000-2006
5//# Associated Universities, Inc. Washington DC, USA.
6//#
7//# This library is free software; you can redistribute it and/or modify it
8//# under the terms of the GNU Library General Public License as published by
9//# the Free Software Foundation; either version 2 of the License, or (at your
10//# option) any later version.
11//#
12//# This library is distributed in the hope that it will be useful, but WITHOUT
13//# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14//# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
15//# License for more details.
16//#
17//# You should have received a copy of the GNU Library General Public License
18//# along with this library; if not, write to the Free Software Foundation,
19//# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
20//#
21//# Correspondence concerning AIPS++ should be addressed as follows:
22//# Internet email: aips2-request@nrao.edu.
23//# Postal address: AIPS++ Project Office
24//# National Radio Astronomy Observatory
25//# 520 Edgemont Road
26//# Charlottesville, VA 22903-2475 USA
27//#
28//# $Id$
29//#---------------------------------------------------------------------------
30//# Original: 2009/02/27, Takeshi Nakazato, NAOJ
31//#---------------------------------------------------------------------------
32
33#include <atnf/PKSIO/NRODataset.h>
34#include <casa/OS/Time.h>
35#include <scimath/Mathematics/InterpolateArray1D.h>
36
37#include <measures/Measures/MeasConvert.h>
38#include <measures/Measures/MCFrequency.h>
39#include <measures/Measures/MFrequency.h>
40#include <measures/Measures/MPosition.h>
41#include <measures/Measures/MEpoch.h>
42#include <measures/Measures/MDirection.h>
43
44#include <math.h>
45#include <fstream>
46
47//#include <casa/namespace.h>
48
49using namespace std ;
50
51//
52// NRODataset
53//
54// Base class for NRO dataset.
55//
56
57// constructor
58NRODataset::NRODataset( string name )
59{
60 LogIO os( LogOrigin( "NRODataset", "NRODataset()", WHERE ) ) ;
61
62 // memory allocation
63 initialize() ;
64
65 filename_ = name ;
66 fp_ = NULL ;
67 scanNum_ = 0 ;
68 rowNum_ = 0 ;
69 scanLen_ = 0 ;
70 dataLen_ = 0 ;
71 dataid_ = -1 ;
72
73 // OS endian
74 int i = 1 ;
75 endian_ = -1 ;
76 if ( *reinterpret_cast<char *>(&i) == 1 ) {
77 endian_ = LITTLE_ENDIAN ;
78 os << LogIO::NORMAL << "LITTLE_ENDIAN " << LogIO::POST ;
79 }
80 else {
81 endian_ = BIG_ENDIAN ;
82 os << LogIO::NORMAL << "BIG_ENDIAN " << LogIO::POST ;
83 }
84 same_ = -1 ;
85}
86
87// destructor
88NRODataset::~NRODataset()
89{
90 // release memory
91 releaseRecord() ;
92
93 // close file
94 close() ;
95}
96
97// data initialization
98void NRODataset::initialize()
99{
100 datasize_ = sizeof( char ) * 8 // LOFIL
101 + sizeof( char ) * 8 // VER
102 + sizeof( char ) * 16 // GROUP
103 + sizeof( char ) * 16 // PROJ
104 + sizeof( char ) * 24 // SCHED
105 + sizeof( char ) * 40 // OBSVR
106 + sizeof( char ) * 16 // LOSTM
107 + sizeof( char ) * 16 // LOETM
108 + sizeof( int ) * 2 // ARYNM, NSCAN
109 + sizeof( char ) * 120 // TITLE
110 + sizeof( char ) * 16 // OBJ
111 + sizeof( char ) * 8 // EPOCH
112 + sizeof( double ) * 4 // RA0, DEC0, GLNG0, GLAT0
113 + sizeof( int ) * 2 // NCALB, SCNCD
114 + sizeof( char ) * 120 // SCMOD
115 + sizeof( double ) // URVEL
116 + sizeof( char ) * 4 // VREF
117 + sizeof( char ) * 4 // VDEF
118 + sizeof( char ) * 8 // SWMOD
119 + sizeof( double ) * 8 // FRQSW, DBEAM, MLTOF, CMTQ, CMTE, CMTSOM, CMTNODE, CMTI
120 + sizeof( char ) * 24 // CMTTM
121 + sizeof( double ) * 6 // SBDX, SBDY, SBDZ1, SBDZ2, DAZP, DELP
122 + sizeof( int ) * 4 // CHBIND, NUMCH, CHMIN, CHMAX
123 + sizeof( double ) * 3 // ALCTM, IPTIM, PA
124 + sizeof( int ) * 3 // SCNLEN, SBIND, IBIT
125 + sizeof( char ) * 8 ; // SITE
126
127 // NRODataRecord
128 record_ = new NRODataRecord() ;
129 record_->LDATA = NULL ;
130}
131
132void NRODataset::convertEndian( int &value )
133{
134 char volatile *first = reinterpret_cast<char volatile *>( &value ) ;
135 char volatile *last = first + sizeof( int ) ;
136 std::reverse( first, last ) ;
137}
138
139void NRODataset::convertEndian( float &value )
140{
141 char volatile *first = reinterpret_cast<char volatile *>( &value ) ;
142 char volatile *last = first + sizeof( float ) ;
143 std::reverse( first, last ) ;
144}
145
146void NRODataset::convertEndian( double &value )
147{
148 char volatile *first = reinterpret_cast<char volatile *>( &value ) ;
149 char volatile *last = first + sizeof( double ) ;
150 std::reverse( first, last ) ;
151}
152
153int NRODataset::readHeader( char *v, int size )
154{
155 if ( (int)( fread( v, 1, size, fp_ ) ) != size ) {
156 return -1 ;
157 }
158 return 0 ;
159}
160
161int NRODataset::readHeader( int &v, int b )
162{
163 if ( fread( &v, 1, sizeof(int), fp_ ) != sizeof(int) ) {
164 return -1 ;
165 }
166
167 if ( b == 0 )
168 convertEndian( v ) ;
169
170 return 0 ;
171}
172
173int NRODataset::readHeader( float &v, int b )
174{
175 if ( fread( &v, 1, sizeof(float), fp_ ) != sizeof(float) ) {
176 return -1 ;
177 }
178
179 if ( b == 0 )
180 convertEndian( v ) ;
181
182 return 0 ;
183}
184
185int NRODataset::readHeader( double &v, int b )
186{
187 if ( fread( &v, 1, sizeof(double), fp_ ) != sizeof(double) ) {
188 return -1 ;
189 }
190
191 if ( b == 0 )
192 convertEndian( v ) ;
193
194 return 0 ;
195}
196
197void NRODataset::convertEndian( NRODataRecord *r )
198{
199 convertEndian( r->ISCAN ) ;
200 convertEndian( r->DSCX ) ;
201 convertEndian( r->DSCY ) ;
202 convertEndian( r->SCX ) ;
203 convertEndian( r->SCY ) ;
204 convertEndian( r->PAZ ) ;
205 convertEndian( r->PEL ) ;
206 convertEndian( r->RAZ ) ;
207 convertEndian( r->REL ) ;
208 convertEndian( r->XX ) ;
209 convertEndian( r->YY ) ;
210 convertEndian( r->TEMP ) ;
211 convertEndian( r->PATM ) ;
212 convertEndian( r->PH2O ) ;
213 convertEndian( r->VWIND ) ;
214 convertEndian( r->DWIND ) ;
215 convertEndian( r->TAU ) ;
216 convertEndian( r->TSYS ) ;
217 convertEndian( r->BATM ) ;
218 convertEndian( r->LINE ) ;
219 for ( int i = 0 ; i < 4 ; i++ )
220 convertEndian( r->IDMY1[i] ) ;
221 convertEndian( r->VRAD ) ;
222 convertEndian( r->FREQ0 ) ;
223 convertEndian( r->FQTRK ) ;
224 convertEndian( r->FQIF1 ) ;
225 convertEndian( r->ALCV ) ;
226 for ( int i = 0 ; i < 2 ; i++ )
227 for ( int j = 0 ; j < 2 ; j++ )
228 convertEndian( r->OFFCD[i][j] ) ;
229 convertEndian( r->IDMY0 ) ;
230 convertEndian( r->IDMY2 ) ;
231 convertEndian( r->DPFRQ ) ;
232 convertEndian( r->SFCTR ) ;
233 convertEndian( r->ADOFF ) ;
234}
235
236void NRODataset::releaseRecord()
237{
238 if ( record_ ) {
239 if ( record_->LDATA != NULL ) {
240 delete record_->LDATA ;
241 record_->LDATA = NULL ;
242 }
243 delete record_ ;
244 record_ = NULL ;
245 }
246 dataid_ = -1 ;
247}
248
249// Get specified scan
250NRODataRecord *NRODataset::getRecord( int i )
251{
252 LogIO os( LogOrigin( "NRODataset", "getRecord()", WHERE ) ) ;
253
254 // DEBUG
255 //cout << "NRODataset::getRecord() Start " << i << endl ;
256 //
257 if ( i < 0 || i >= rowNum_ ) {
258 //cerr << "NRODataset::getRecord() data index out of range." << endl ;
259 os << LogIO::SEVERE << "data index " << i << " out of range. return NULL." << LogIO::POST ;
260 return NULL ;
261 }
262
263 if ( i == dataid_ ) {
264 return record_ ;
265 }
266
267 // DEBUG
268 //cout << "NRODataset::getData() Get new dataset" << endl ;
269 //
270 // read data
271 int status = fillRecord( i ) ;
272 if ( status == 0 ) {
273 dataid_ = i ;
274 }
275 else {
276 //cerr << "NRODataset::getRecord() error while reading data " << i << endl ;
277 os << LogIO::SEVERE << "error while reading data " << i << ". return NULL." << LogIO::POST ;
278 dataid_ = -1 ;
279 return NULL ;
280 }
281
282 return record_ ;
283}
284
285int NRODataset::fillRecord( int i )
286{
287 LogIO os( LogOrigin( "NRODataset", "fillRecord()", WHERE ) ) ;
288
289 int status = 0 ;
290
291 status = open() ;
292 if ( status != 0 )
293 return status ;
294
295
296 // fill NRODataset
297 int offset = getDataSize() + scanLen_ * i ;
298 // DEBUG
299 //cout << "NRODataset::fillRecord() offset (header) = " << offset << endl ;
300 //cout << "NRODataset::fillRecord() sizeof(NRODataRecord) = " << sizeof( NRODataRecord ) << " byte" << endl ;
301 fseek( fp_, offset, SEEK_SET ) ;
302 if ( (int)fread( record_, 1, SCAN_HEADER_SIZE, fp_ ) != SCAN_HEADER_SIZE ) {
303 //cerr << "Failed to read scan header: " << i << endl ;
304 os << LogIO::SEVERE << "Failed to read scan header for " << i << "th row." << LogIO::POST ;
305 return -1 ;
306 }
307 if ( (int)fread( record_->LDATA, 1, dataLen_, fp_ ) != dataLen_ ) {
308 //cerr << "Failed to read spectral data: " << i << endl ;
309 os << LogIO::SEVERE << "Failed to read spectral data for " << i << "th row." << LogIO::POST ;
310 return -1 ;
311 }
312
313 if ( same_ == 0 ) {
314 convertEndian( record_ ) ;
315 }
316
317 // DWIND unit conversion (deg -> rad)
318 record_->DWIND = record_->DWIND * M_PI / 180.0 ;
319
320 return status ;
321}
322
323// open
324int NRODataset::open()
325{
326 int status = 0 ;
327
328 if ( fp_ == NULL ) {
329 if ( (fp_ = fopen( filename_.c_str(), "rb" )) == NULL )
330 status = -1 ;
331 else
332 status = 0 ;
333 }
334
335 return status ;
336}
337
338// close
339void NRODataset::close()
340{
341 // DEBUG
342 //cout << "NRODataset::close() close file" << endl ;
343 //
344 if ( fp_ != NULL )
345 fclose( fp_ ) ;
346 fp_ = NULL ;
347}
348
349// get spectrum
350vector< vector<double> > NRODataset::getSpectrum()
351{
352 vector< vector<double> > spec;
353
354 for ( int i = 0 ; i < rowNum_ ; i++ ) {
355 spec.push_back( getSpectrum( i ) ) ;
356 }
357
358 return spec ;
359}
360
361vector<double> NRODataset::getSpectrum( int i )
362{
363 LogIO os( LogOrigin( "NRODataset", "getSpectrum", WHERE ) ) ;
364
365 // DEBUG
366 //cout << "NRODataset::getSpectrum() start process (" << i << ")" << endl ;
367 //
368 // size of spectrum is not chmax_ but dataset_->getNCH() after binding
369 int nchan = NUMCH ;
370 vector<double> spec( chmax_, 0.0 ) ; // spectrum "before" binding
371 vector<double> bspec( nchan, 0.0 ) ; // spectrum "after" binding
372 // DEBUG
373 //cout << "NRODataset::getSpectrum() nchan = " << nchan << " chmax_ = " << chmax_ << endl ;
374 //
375
376 NRODataRecord *record = getRecord( i ) ;
377
378 int bit = IBIT ; // fixed to 12 bit
379 double scale = record->SFCTR ;
380 // DEBUG
381 //cout << "NRODataset::getSpectrum() scale = " << scale << endl ;
382 //
383 double offset = record->ADOFF ;
384 // DEBUG
385 //cout << "NRODataset::getSpectrum() offset = " << offset << endl ;
386 //
387 if ( ( scale == 0.0 ) && ( offset == 0.0 ) ) {
388 //cerr << "NRODataset::getSpectrum() zero spectrum (" << i << ")" << endl ;
389 return bspec ;
390 }
391 char *cdata = record->LDATA ;
392 vector<double> mscale = MLTSCF ;
393 double dscale = mscale[getIndex( i )] ;
394 int cbind = CHBIND ;
395 int chmin = CHMIN ;
396
397 // char -> int
398 vector<int> ispec( chmax_, 0 ) ;
399 union SharedMemory {
400 int ivalue ;
401 unsigned char cbuf[4] ;
402 } ;
403 SharedMemory u ;
404 int j = 0 ;
405 char ctmp = 0x00 ;
406 int sw = 0 ;
407 for ( int i = 0 ; i < chmax_ ; i++ ) {
408 if ( bit == 12 ) { // 12 bit qunatization
409 u.ivalue = 0 ;
410
411 if ( endian_ == BIG_ENDIAN ) {
412 // big endian
413 if ( sw == 0 ) {
414 char c0 = (cdata[j] >> 4) & 0x0f ;
415 char c1 = ((cdata[j] << 4) & 0xf0) | ((cdata[j+1] >> 4) & 0x0f) ;
416 ctmp = cdata[j+1] & 0x0f ;
417 u.cbuf[2] = c0 ;
418 u.cbuf[3] = c1 ;
419 j += 2 ;
420 sw = 1 ;
421 }
422 else if ( sw == 1 ) {
423 u.cbuf[2] = ctmp ;
424 u.cbuf[3] = cdata[j] ;
425 j++ ;
426 sw = 0 ;
427 }
428 }
429 else if ( endian_ == LITTLE_ENDIAN ) {
430 // little endian
431 if ( sw == 0 ) {
432 char c0 = (cdata[j] >> 4) & 0x0f ;
433 char c1 = ((cdata[j] << 4) & 0xf0) | ((cdata[j+1] >> 4) & 0x0f) ;
434 ctmp = cdata[j+1] & 0x0f ;
435 u.cbuf[1] = c0 ;
436 u.cbuf[0] = c1 ;
437 j += 2 ;
438 sw = 1 ;
439 }
440 else if ( sw == 1 ) {
441 u.cbuf[1] = ctmp ;
442 u.cbuf[0] = cdata[j] ;
443 j++ ;
444 sw = 0 ;
445 }
446 }
447 }
448
449 ispec[i] = u.ivalue ;
450 if ( ( ispec[i] < 0 ) || ( ispec[i] > 4096 ) ) {
451 //cerr << "NRODataset::getSpectrum() ispec[" << i << "] is out of range" << endl ;
452 os << LogIO::SEVERE << "ispec[" << i << "] is out of range" << LogIO::EXCEPTION ;
453 return bspec ;
454 }
455 // DEBUG
456 //cout << "NRODataset::getSpectrum() ispec[" << i << "] = " << ispec[i] << endl ;
457 //
458 }
459
460 // int -> double
461 for ( int i = 0 ; i < chmax_ ; i++ ) {
462 spec[i] = (double)( ispec[i] * scale + offset ) * dscale ;
463 // DEBUG
464 //cout << "NRODataset::getSpectrum() spec[" << i << "] = " << spec[i] << endl ;
465 //
466 }
467
468 // channel binding
469 if ( cbind != 1 ) {
470 int k = chmin ;
471 double sum0 = 0 ;
472 double sum1 = 0 ;
473 for ( int i = 0 ; i < nchan ; i++ ) {
474 for ( int j = k ; j < k + cbind ; j++ ) {
475 sum0 += spec[k] ;
476 sum1++ ;
477 }
478 bspec[i] = sum0 / sum1 ;
479 k += cbind ;
480 // DEBUG
481 //cout << "NRODataset::getSpectrum() bspec[" << i << "] = " << bspec[i] << endl ;
482 //
483 }
484 }
485 else {
486 for ( int i = 0 ; i < nchan ; i++ )
487 bspec[i] = spec[i] ;
488 }
489
490 // DEBUG
491 //cout << "NRODataset::getSpectrum() end process" << endl ;
492 //
493
494 return bspec ;
495}
496
497int NRODataset::getIndex( int irow )
498{
499 // DEBUG
500 //cout << "NRODataset::getIndex() start" << endl ;
501 //
502 NRODataRecord *record = getRecord( irow ) ;
503 string str = record->ARRYT ;
504 // DEBUG
505 //cout << "NRODataset::getIndex() str = " << str << endl ;
506 //
507 string substr = str.substr( 1, 2 ) ;
508 unsigned int index = (unsigned int)(atoi( substr.c_str() ) - 1) ;
509 // DEBUG
510 //cout << "NRODataset::getIndex() irow = " << irow << " index = " << index << endl ;
511 //
512
513 // DEBUG
514 //cout << "NRODataset::getIndex() end" << endl ;
515 //
516 return index ;
517}
518
519int NRODataset::getPolarizationNum()
520{
521 // DEBUG
522 //cout << "NRODataset::getPolarizationNum() start process" << endl ;
523 //
524 int npol = 0 ;
525
526 vector<string> type( 2 ) ;
527 type[0] = "CIRC" ;
528 type[1] = "LINR" ;
529 vector<double> crot ;
530 vector<double> lagl ;
531 //vector<int> ntype( 2, 0 ) ;
532
533 unsigned int imax = rowNum_ ;
534 for ( unsigned int i = 0 ; i < imax ; i++ ) {
535 int index = getIndex( i ) ;
536 // DEBUG
537 //cout <<"NRODataset::getPolarizationNum() index = " << index << endl ;
538 //
539 if ( POLTP[index] == type[0] ) {
540 if( count( crot.begin(), crot.end(), POLDR[index] ) != 0 ) {
541 crot.push_back( POLDR[index] ) ;
542 npol++ ;
543 }
544 //ntype[0] = 1 ;
545 }
546 else if ( POLTP[index] == type[1] ) {
547 if ( count( lagl.begin(), lagl.end(), POLAN[index] ) != 0 ) {
548 lagl.push_back( POLAN[index] ) ;
549 npol++ ;
550 }
551 //ntype[1] = 1 ;
552 }
553 }
554
555 if ( npol == 0 )
556 npol = 1 ;
557
558 // DEBUG
559 //cout << "NRODataset::getPolarizationNum() end process" << endl ;
560 //
561
562 return npol ;
563}
564
565vector<double> NRODataset::getStartIntTime()
566{
567 vector<double> times ;
568 for ( int i = 0 ; i < rowNum_ ; i++ ) {
569 times.push_back( getStartIntTime( i ) ) ;
570 }
571 return times ;
572}
573
574double NRODataset::getStartIntTime( int i )
575{
576 NRODataRecord *record = getRecord( i ) ;
577
578 char *t = record->LAVST ;
579 return getMJD( t ) ;
580}
581
582double NRODataset::getMJD( char *time )
583{
584 // TODO: should be checked which time zone the time depends on
585 // 2008/11/14 Takeshi Nakazato
586 string strStartTime( time ) ;
587 string strYear = strStartTime.substr( 0, 4 ) ;
588 string strMonth = strStartTime.substr( 4, 2 ) ;
589 string strDay = strStartTime.substr( 6, 2 ) ;
590 string strHour = strStartTime.substr( 8, 2 ) ;
591 string strMinute = strStartTime.substr( 10, 2 ) ;
592 string strSecond = strStartTime.substr( 12, strStartTime.size() - 12 ) ;
593 unsigned int year = atoi( strYear.c_str() ) ;
594 unsigned int month = atoi( strMonth.c_str() ) ;
595 unsigned int day = atoi( strDay.c_str() ) ;
596 unsigned int hour = atoi( strHour.c_str() ) ;
597 unsigned int minute = atoi( strMinute.c_str() ) ;
598 double second = atof( strSecond.c_str() ) ;
599 Time t( year, month, day, hour, minute, second ) ;
600
601 return t.modifiedJulianDay() ;
602}
603
604vector<bool> NRODataset::getIFs()
605{
606 vector<bool> v ;
607 vector< vector<double> > fref ;
608 vector< vector<double> > chcal = CHCAL ;
609 vector<double> f0cal = F0CAL ;
610 vector<double> beres = BERES ;
611 for ( int i = 0 ; i < rowNum_ ; i++ ) {
612 vector<double> f( 4, 0 ) ;
613 uInt index = getIndex( i ) ;
614 f[0] = chcal[index][0] ;
615 f[1] = f0cal[index] ;
616 f[2] = beres[index] ;
617 if ( f[0] != 0. ) {
618 f[1] = f[1] - f[0] * f[2] ;
619 }
620 NRODataRecord *record = getRecord( i ) ;
621 f[3] = record->FREQ0 ;
622 if ( v.size() == 0 ) {
623 v.push_back( True ) ;
624 fref.push_back( f ) ;
625 }
626 else {
627 bool b = true ;
628 int fsize = fref.size() ;
629 for ( int j = 0 ; j < fsize ; j++ ) {
630 if ( fref[j][1] == f[1] && fref[j][2] == f[2] && fref[j][3] == f[3] ) {
631 b = false ;
632 }
633 }
634 if ( b ) {
635 v.push_back( True ) ;
636 fref.push_back( f ) ;
637 }
638 }
639 }
640
641
642 // DEBUG
643 //cout << "NRODataset::getIFs() number of IF is " << v.size() << endl ;
644 //
645
646 return v ;
647}
648
649vector<double> NRODataset::getFrequencies( int i )
650{
651 // return value
652 // v[0] reference channel
653 // v[1] reference frequency
654 // v[2] frequency increment
655 vector<double> v( 3, 0.0 ) ;
656
657 NRODataRecord *record = getRecord( i ) ;
658 string arryt = string( record->ARRYT ) ;
659 //string sbeamno = arryt.substr( 1, arryt.size()-1 ) ;
660 //uInt ib = atoi( sbeamno.c_str() ) - 1 ;
661 uInt ib = getArrayId( arryt ) ;
662
663 int ia = -1 ;
664 bool isAOS = false ;
665 //cout << "NRODataset::getFrequencies() record->ARRYT=" << record->ARRYT << endl ;
666 //cout << "NRODataset::getFrequencies() ib = " << ib << endl ;
667
668 if ( strncmp( record->ARRYT, "X", 1 ) == 0 ) {
669 // FX
670 if ( strncmp( (record->ARRYT)+1, "1", 1 ) == 0
671 || strncmp( (record->ARRYT)+1, "3", 1 ) ) {
672 // FX1, 3
673 ia = 2 ;
674 }
675 else {
676 // FX2, 4
677 ia = 1 ;
678 }
679 }
680 else if ( strncmp( record->ARRYT, "A", 1 ) == 0 )
681 ia = 2 ; // AC
682 else if ( strncmp( record->ARRYT, "W", 1 ) == 0 ) {
683 // AOS-W
684 ia = 2 ;
685 isAOS = true ;
686 }
687 else if ( strncmp( record->ARRYT, "U", 1 ) == 0 ) {
688 // AOS-U
689 ia = 2 ;
690 isAOS = true ;
691 }
692 else if ( strncmp( record->ARRYT, "H", 1 ) == 0 ) {
693 // AOS-H
694 isAOS = true ;
695 //cout << record->ARRYT << " " << strlen(record->ARRYT) << endl ;
696 //cout << (record->ARRYT)+1 << endl ;
697 if ( strncmp( (record->ARRYT)+2, " ", 1 ) == 0 ) {
698 // H1-9
699 if ( strncmp( (record->ARRYT)+1, "9", 1 ) == 0 ) {
700 // H9
701 ia = 2 ;
702 }
703 else {
704 // H1-8
705 ia = 1 ;
706 }
707 }
708 else {
709 // H10-16
710 ia = 2 ;
711 }
712 }
713
714 int iu ;
715 if ( record->FQIF1 > 0 )
716 iu = 1 ; // USB
717 else
718 iu = 2 ; // LSB
719
720 int ivdef = -1 ;
721 //if ( strncmp( (dataset_->getVDEF()).c_str(), "RAD", 3 ) == 0 )
722 if ( (getVDEF()).compare( 0, 3, "RAD" ) == 0 )
723 ivdef = 0 ;
724 //else if ( strncmp( dataset_->getVDEF(), "OPT", 3 ) == 0 )
725 else if ( (getVDEF()).compare( 0, 3, "OPT" ) == 0 )
726 ivdef = 1 ;
727 // DEBUG
728 //cout << "NRODataset::getFrequencies() ivdef = " << ivdef << endl ;
729 //
730 double vel = getURVEL() + record->VRAD ;
731 double cvel = 2.99792458e8 ; // speed of light [m/s]
732 double fq0 = record->FREQ0 ;
733 //double fq0 = record->FQTRK ;
734
735 int ncal = getNFCAL()[ib] ;
736 vector<double> freqs( ncal ) ;
737 double cw = 0.0 ;
738 vector<double> fqcal = getFQCAL()[ib] ;
739 vector<double> chcal = getCHCAL()[ib] ;
740
741 for ( int ii = 0 ; ii < ncal ; ii++ ) {
742 freqs[ii] = fqcal[ii] ;
743 freqs[ii] -= getF0CAL()[ib] ;
744 if ( ia == 1 ) {
745 if ( iu == 1 ) {
746 freqs[ii] = fq0 + freqs[ii] ;
747 }
748 else if ( iu == 2 ) {
749 freqs[ii] = fq0 - freqs[ii] ;
750 }
751 }
752 else if ( ia == 2 ) {
753 if ( iu == 1 ) {
754 freqs[ii] = fq0 - freqs[ii] ;
755 }
756 else if ( iu == 2 ) {
757 freqs[ii] = fq0 + freqs[ii] ;
758 }
759 }
760// if ( ivdef == 0 ) {
761// double factor = 1.0 / ( 1.0 - vel / cvel ) ;
762// freqs[ii] = freqs[ii] * factor - record->FQTRK * ( factor - 1.0 ) ;
763// }
764// else if ( ivdef == 1 ) {
765// double factor = vel / cvel ;
766// freqs[ii] = freqs[ii] * ( 1.0 + factor ) - record->FQTRK * factor ;
767// }
768 }
769
770 if ( isAOS ) {
771 // regridding
772 while ( ncal < (int)chcal.size() ) {
773 chcal.pop_back() ;
774 }
775 Vector<Double> xin( chcal ) ;
776 Vector<Double> yin( freqs ) ;
777 int nchan = getNUMCH() ;
778 Vector<Double> xout( nchan ) ;
779 indgen( xout ) ;
780 Vector<Double> yout ;
781 InterpolateArray1D<Double, Double>::interpolate( yout, xout, xin, yin, InterpolateArray1D<Double,Double>::cubic ) ;
782 Double bw = abs( yout[nchan-1] - yout[0] ) ;
783 bw += 0.5 * abs( yout[nchan-1] - yout[nchan-2] + yout[1] - yout[0] ) ;
784 Double dz = bw / (Double) nchan ;
785 if ( yout[0] > yout[1] )
786 dz = - dz ;
787 v[0] = 0 ;
788 v[1] = yout[0] ;
789 v[2] = dz ;
790 }
791 else {
792 cw = getBERES()[ib] ;
793
794 if ( iu == 2 )
795 cw *= -1.0 ;
796
797 if ( cw == 0.0 ) {
798 cw = ( freqs[1] - freqs[0] )
799 / ( chcal[1] - chcal[0] ) ;
800// if ( cw < 0.0 )
801// cw = - cw ;
802 }
803 v[0] = chcal[0] - 1 ; // 0-base
804 v[1] = freqs[0] ;
805 v[2] = cw ;
806 }
807
808 // conversion from TOPO to LSRK
809 v[1] = toLSR( v[1], getStartIntTime( i ), record_->SCX, record_->SCY ) ;
810
811 if ( refFreq_[ib] != 0.0 ) {
812 v[1] = refFreq_[ib] ;
813 }
814 else {
815 refFreq_[ib] = v[1] ;
816 }
817
818 return v ;
819}
820
821uInt NRODataset::getArrayId( string type )
822{
823 string sbeamno = type.substr( 1, type.size()-1 ) ;
824 uInt ib = atoi( sbeamno.c_str() ) - 1 ;
825 return ib ;
826}
827
828void NRODataset::show()
829{
830 LogIO os( LogOrigin( "NRODataset", "show()", WHERE ) ) ;
831
832 os << LogIO::NORMAL << "------------------------------------------------------------" << endl ;
833 os << LogIO::NORMAL << "Number of scan = " << scanNum_ << endl ;
834 os << LogIO::NORMAL << "Number of data record = " << rowNum_ << endl ;
835 os << LogIO::NORMAL << "Length of data record = " << scanLen_ << " bytes" << endl ;
836 os << LogIO::NORMAL << "Allocated memory for spectral data = " << dataLen_ << " bytes" << endl ;
837 os << LogIO::NORMAL << "Max number of channel = " << chmax_ << endl ;
838 os << LogIO::NORMAL << "------------------------------------------------------------" << endl ;
839 os.post() ;
840
841}
842
843double NRODataset::toLSR( double v, double t, double x, double y )
844{
845 double vlsr ;
846
847 // get epoch
848 double tcent = t + 0.5*getIPTIM()/86400.0 ;
849 MEpoch me( Quantity( tcent, "d" ), MEpoch::UTC ) ;
850
851 // get antenna position
852 MPosition mp ;
853 if ( SITE.find( "45" ) != string::npos ) {
854 // 45m telescope
855 Double posx = -3.8710235e6 ;
856 Double posy = 3.4281068e6 ;
857 Double posz = 3.7240395e6 ;
858 mp = MPosition( MVPosition( posx, posy, posz ),
859 MPosition::ITRF ) ;
860 }
861 else {
862 // ASTE
863 Vector<Double> pos( 2 ) ;
864 pos[0] = -67.7031 ;
865 pos[1] = -22.9717 ;
866 Double sitealt = 4800.0 ;
867 mp = MPosition( MVPosition( Quantity( sitealt, "m" ),
868 Quantum< Vector<Double> >( pos, "deg" ) ),
869 MPosition::WGS84 ) ;
870 }
871
872 // get direction
873 MDirection md ;
874 if ( SCNCD == 0 ) {
875 // RADEC
876 if ( EPOCH == "B1950" ) {
877 md = MDirection( Quantity( Double(x), "rad" ), Quantity( Double(y), "rad" ),
878 MDirection::B1950 ) ;
879 }
880 else {
881 md = MDirection( Quantity( Double(x), "rad" ), Quantity( Double(y), "rad" ),
882 MDirection::J2000 ) ;
883 }
884 }
885 else if ( SCNCD == 1 ) {
886 // LB
887 md = MDirection( Quantity( Double(x), "rad" ), Quantity( Double(y), "rad" ),
888 MDirection::GALACTIC ) ;
889 }
890 else {
891 // AZEL
892 md = MDirection( Quantity( Double(x), "rad" ), Quantity( Double(y), "rad" ),
893 MDirection::AZEL ) ;
894 }
895
896 // to LSR
897 MeasFrame mf( me, mp, md ) ;
898 MFrequency::Convert tolsr( MFrequency::TOPO, MFrequency::Ref( MFrequency::LSRK, mf ) ) ;
899 vlsr = (double)(tolsr( Double(v) ).get( "Hz" ).getValue()) ;
900
901 return vlsr ;
902}
Note: See TracBrowser for help on using the repository browser.