source: trunk/external-alma/atnf/PKSIO/NRODataset.cc@ 2175

Last change on this file since 2175 was 2156, checked in by Takeshi Nakazato, 14 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:

Put in Release Notes: Yes/No

Module(s): Module Names change impacts.

Description: Describe your changes here...

Bug fix on TIME value: changed from start time to mid point of integration.


File size: 23.8 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
604double NRODataset::getScanTime( int i )
605{
606 double startTime = getStartIntTime( i ) ;
607 double interval = getIPTIM() / 86400.0 ; // [sec]->[day]
608 return startTime+0.5*interval ;
609}
610
611vector<bool> NRODataset::getIFs()
612{
613 vector<bool> v ;
614 vector< vector<double> > fref ;
615 vector< vector<double> > chcal = CHCAL ;
616 vector<double> f0cal = F0CAL ;
617 vector<double> beres = BERES ;
618 for ( int i = 0 ; i < rowNum_ ; i++ ) {
619 vector<double> f( 4, 0 ) ;
620 uInt index = getIndex( i ) ;
621 f[0] = chcal[index][0] ;
622 f[1] = f0cal[index] ;
623 f[2] = beres[index] ;
624 if ( f[0] != 0. ) {
625 f[1] = f[1] - f[0] * f[2] ;
626 }
627 NRODataRecord *record = getRecord( i ) ;
628 f[3] = record->FREQ0 ;
629 if ( v.size() == 0 ) {
630 v.push_back( True ) ;
631 fref.push_back( f ) ;
632 }
633 else {
634 bool b = true ;
635 int fsize = fref.size() ;
636 for ( int j = 0 ; j < fsize ; j++ ) {
637 if ( fref[j][1] == f[1] && fref[j][2] == f[2] && fref[j][3] == f[3] ) {
638 b = false ;
639 }
640 }
641 if ( b ) {
642 v.push_back( True ) ;
643 fref.push_back( f ) ;
644 }
645 }
646 }
647
648
649 // DEBUG
650 //cout << "NRODataset::getIFs() number of IF is " << v.size() << endl ;
651 //
652
653 return v ;
654}
655
656vector<double> NRODataset::getFrequencies( int i )
657{
658 // return value
659 // v[0] reference channel
660 // v[1] reference frequency
661 // v[2] frequency increment
662 vector<double> v( 3, 0.0 ) ;
663
664 NRODataRecord *record = getRecord( i ) ;
665 string arryt = string( record->ARRYT ) ;
666 //string sbeamno = arryt.substr( 1, arryt.size()-1 ) ;
667 //uInt ib = atoi( sbeamno.c_str() ) - 1 ;
668 uInt ib = getArrayId( arryt ) ;
669
670 int ia = -1 ;
671 bool isAOS = false ;
672 //cout << "NRODataset::getFrequencies() record->ARRYT=" << record->ARRYT << endl ;
673 //cout << "NRODataset::getFrequencies() ib = " << ib << endl ;
674
675 if ( strncmp( record->ARRYT, "X", 1 ) == 0 ) {
676 // FX
677 if ( strncmp( (record->ARRYT)+1, "1", 1 ) == 0
678 || strncmp( (record->ARRYT)+1, "3", 1 ) ) {
679 // FX1, 3
680 ia = 2 ;
681 }
682 else {
683 // FX2, 4
684 ia = 1 ;
685 }
686 }
687 else if ( strncmp( record->ARRYT, "A", 1 ) == 0 )
688 ia = 2 ; // AC
689 else if ( strncmp( record->ARRYT, "W", 1 ) == 0 ) {
690 // AOS-W
691 ia = 2 ;
692 isAOS = true ;
693 }
694 else if ( strncmp( record->ARRYT, "U", 1 ) == 0 ) {
695 // AOS-U
696 ia = 2 ;
697 isAOS = true ;
698 }
699 else if ( strncmp( record->ARRYT, "H", 1 ) == 0 ) {
700 // AOS-H
701 isAOS = true ;
702 //cout << record->ARRYT << " " << strlen(record->ARRYT) << endl ;
703 //cout << (record->ARRYT)+1 << endl ;
704 if ( strncmp( (record->ARRYT)+2, " ", 1 ) == 0 ) {
705 // H1-9
706 if ( strncmp( (record->ARRYT)+1, "9", 1 ) == 0 ) {
707 // H9
708 ia = 2 ;
709 }
710 else {
711 // H1-8
712 ia = 1 ;
713 }
714 }
715 else {
716 // H10-16
717 ia = 2 ;
718 }
719 }
720
721 int iu ;
722 if ( record->FQIF1 > 0 )
723 iu = 1 ; // USB
724 else
725 iu = 2 ; // LSB
726
727 int ivdef = -1 ;
728 //if ( strncmp( (dataset_->getVDEF()).c_str(), "RAD", 3 ) == 0 )
729 if ( (getVDEF()).compare( 0, 3, "RAD" ) == 0 )
730 ivdef = 0 ;
731 //else if ( strncmp( dataset_->getVDEF(), "OPT", 3 ) == 0 )
732 else if ( (getVDEF()).compare( 0, 3, "OPT" ) == 0 )
733 ivdef = 1 ;
734 // DEBUG
735 //cout << "NRODataset::getFrequencies() ivdef = " << ivdef << endl ;
736 //
737 double vel = getURVEL() + record->VRAD ;
738 double cvel = 2.99792458e8 ; // speed of light [m/s]
739 double fq0 = record->FREQ0 ;
740 //double fq0 = record->FQTRK ;
741
742 int ncal = getNFCAL()[ib] ;
743 vector<double> freqs( ncal ) ;
744 double cw = 0.0 ;
745 vector<double> fqcal = getFQCAL()[ib] ;
746 vector<double> chcal = getCHCAL()[ib] ;
747
748 for ( int ii = 0 ; ii < ncal ; ii++ ) {
749 freqs[ii] = fqcal[ii] ;
750 freqs[ii] -= getF0CAL()[ib] ;
751 if ( ia == 1 ) {
752 if ( iu == 1 ) {
753 freqs[ii] = fq0 + freqs[ii] ;
754 }
755 else if ( iu == 2 ) {
756 freqs[ii] = fq0 - freqs[ii] ;
757 }
758 }
759 else if ( ia == 2 ) {
760 if ( iu == 1 ) {
761 freqs[ii] = fq0 - freqs[ii] ;
762 }
763 else if ( iu == 2 ) {
764 freqs[ii] = fq0 + freqs[ii] ;
765 }
766 }
767// if ( ivdef == 0 ) {
768// double factor = 1.0 / ( 1.0 - vel / cvel ) ;
769// freqs[ii] = freqs[ii] * factor - record->FQTRK * ( factor - 1.0 ) ;
770// }
771// else if ( ivdef == 1 ) {
772// double factor = vel / cvel ;
773// freqs[ii] = freqs[ii] * ( 1.0 + factor ) - record->FQTRK * factor ;
774// }
775 }
776
777 if ( isAOS ) {
778 // regridding
779 while ( ncal < (int)chcal.size() ) {
780 chcal.pop_back() ;
781 }
782 Vector<Double> xin( chcal ) ;
783 Vector<Double> yin( freqs ) ;
784 int nchan = getNUMCH() ;
785 Vector<Double> xout( nchan ) ;
786 indgen( xout ) ;
787 Vector<Double> yout ;
788 InterpolateArray1D<Double, Double>::interpolate( yout, xout, xin, yin, InterpolateArray1D<Double,Double>::cubic ) ;
789 Double bw = abs( yout[nchan-1] - yout[0] ) ;
790 bw += 0.5 * abs( yout[nchan-1] - yout[nchan-2] + yout[1] - yout[0] ) ;
791 Double dz = bw / (Double) nchan ;
792 if ( yout[0] > yout[1] )
793 dz = - dz ;
794 v[0] = 0 ;
795 v[1] = yout[0] ;
796 v[2] = dz ;
797 }
798 else {
799 cw = getBERES()[ib] ;
800
801 if ( iu == 2 )
802 cw *= -1.0 ;
803
804 if ( cw == 0.0 ) {
805 cw = ( freqs[1] - freqs[0] )
806 / ( chcal[1] - chcal[0] ) ;
807// if ( cw < 0.0 )
808// cw = - cw ;
809 }
810 v[0] = chcal[0] - 1 ; // 0-base
811 v[1] = freqs[0] ;
812 v[2] = cw ;
813 }
814
815 // conversion from TOPO to LSRK
816 v[1] = toLSR( v[1], getStartIntTime( i ), record_->SCX, record_->SCY ) ;
817
818 if ( refFreq_[ib] != 0.0 ) {
819 v[1] = refFreq_[ib] ;
820 }
821 else {
822 refFreq_[ib] = v[1] ;
823 }
824
825 return v ;
826}
827
828uInt NRODataset::getArrayId( string type )
829{
830 string sbeamno = type.substr( 1, type.size()-1 ) ;
831 uInt ib = atoi( sbeamno.c_str() ) - 1 ;
832 return ib ;
833}
834
835void NRODataset::show()
836{
837 LogIO os( LogOrigin( "NRODataset", "show()", WHERE ) ) ;
838
839 os << LogIO::NORMAL << "------------------------------------------------------------" << endl ;
840 os << LogIO::NORMAL << "Number of scan = " << scanNum_ << endl ;
841 os << LogIO::NORMAL << "Number of data record = " << rowNum_ << endl ;
842 os << LogIO::NORMAL << "Length of data record = " << scanLen_ << " bytes" << endl ;
843 os << LogIO::NORMAL << "Allocated memory for spectral data = " << dataLen_ << " bytes" << endl ;
844 os << LogIO::NORMAL << "Max number of channel = " << chmax_ << endl ;
845 os << LogIO::NORMAL << "------------------------------------------------------------" << endl ;
846 os.post() ;
847
848}
849
850double NRODataset::toLSR( double v, double t, double x, double y )
851{
852 double vlsr ;
853
854 // get epoch
855 double tcent = t + 0.5*getIPTIM()/86400.0 ;
856 MEpoch me( Quantity( tcent, "d" ), MEpoch::UTC ) ;
857
858 // get antenna position
859 MPosition mp ;
860 if ( SITE.find( "45" ) != string::npos ) {
861 // 45m telescope
862 Double posx = -3.8710235e6 ;
863 Double posy = 3.4281068e6 ;
864 Double posz = 3.7240395e6 ;
865 mp = MPosition( MVPosition( posx, posy, posz ),
866 MPosition::ITRF ) ;
867 }
868 else {
869 // ASTE
870 Vector<Double> pos( 2 ) ;
871 pos[0] = -67.7031 ;
872 pos[1] = -22.9717 ;
873 Double sitealt = 4800.0 ;
874 mp = MPosition( MVPosition( Quantity( sitealt, "m" ),
875 Quantum< Vector<Double> >( pos, "deg" ) ),
876 MPosition::WGS84 ) ;
877 }
878
879 // get direction
880 MDirection md ;
881 if ( SCNCD == 0 ) {
882 // RADEC
883 if ( EPOCH == "B1950" ) {
884 md = MDirection( Quantity( Double(x), "rad" ), Quantity( Double(y), "rad" ),
885 MDirection::B1950 ) ;
886 }
887 else {
888 md = MDirection( Quantity( Double(x), "rad" ), Quantity( Double(y), "rad" ),
889 MDirection::J2000 ) ;
890 }
891 }
892 else if ( SCNCD == 1 ) {
893 // LB
894 md = MDirection( Quantity( Double(x), "rad" ), Quantity( Double(y), "rad" ),
895 MDirection::GALACTIC ) ;
896 }
897 else {
898 // AZEL
899 md = MDirection( Quantity( Double(x), "rad" ), Quantity( Double(y), "rad" ),
900 MDirection::AZEL ) ;
901 }
902
903 // to LSR
904 MeasFrame mf( me, mp, md ) ;
905 MFrequency::Convert tolsr( MFrequency::TOPO, MFrequency::Ref( MFrequency::LSRK, mf ) ) ;
906 vlsr = (double)(tolsr( Double(v) ).get( "Hz" ).getValue()) ;
907
908 return vlsr ;
909}
Note: See TracBrowser for help on using the repository browser.