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

Last change on this file since 2768 was 2766, checked in by Takeshi Nakazato, 12 years ago

New Development: No

JIRA Issue: No

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

Use CountedPtr for NRODataRecord object instead of raw C pointer.


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