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

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

Disabled debug messages to stdout.


File size: 23.9 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 <casa/Utilities/Regex.h>
36#include <scimath/Mathematics/InterpolateArray1D.h>
37
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
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
72 // endian matches
73 same_ = -1 ;
74
75 // Record for frequency setting
76 frec_ = Record() ;
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
189void NRODataset::convertEndian( NRODataRecord &r )
190{
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 ) ;
211 for ( int i = 0 ; i < 4 ; i++ )
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 ) ;
218 for ( int i = 0 ; i < 2 ; i++ )
219 for ( int j = 0 ; j < 2 ; j++ )
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 ) ;
226}
227
228void NRODataset::releaseRecord()
229{
230 if ( !record_.null() ) {
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_ ) {
243 LogIO os( LogOrigin( "NRODataset", "getRecord()", WHERE ) ) ;
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_ ) {
250 return &(*record_) ;
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 {
262 LogIO os( LogOrigin( "NRODataset", "getRecord()", WHERE ) ) ;
263 //cerr << "NRODataset::getRecord() error while reading data " << i << endl ;
264 os << LogIO::SEVERE << "error while reading data " << i << ". return NULL." << LogIO::EXCEPTION ;
265 dataid_ = -1 ;
266 return NULL ;
267 }
268
269 return &(*record_) ;
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 ) ;
287 if ( (int)fread( &(*record_), 1, SCAN_HEADER_SIZE, fp_ ) != SCAN_HEADER_SIZE ) {
288 //cerr << "Failed to read scan header: " << i << endl ;
289 LogIO os( LogOrigin( "NRODataset", "fillRecord()", WHERE ) ) ;
290 os << LogIO::SEVERE << "Failed to read scan header for " << i << "th row." << LogIO::POST ;
291 return -1 ;
292 }
293 if ( (int)fread( &(*record_->LDATA), 1, dataLen_, fp_ ) != dataLen_ ) {
294 //cerr << "Failed to read spectral data: " << i << endl ;
295 LogIO os( LogOrigin( "NRODataset", "fillRecord()", WHERE ) ) ;
296 os << LogIO::SEVERE << "Failed to read spectral data for " << i << "th row." << LogIO::POST ;
297 return -1 ;
298 }
299
300 if ( same_ == 0 ) {
301 convertEndian( *record_ ) ;
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{
339 vector< vector<double> > spec(rowNum_);
340
341 for ( int i = 0 ; i < rowNum_ ; i++ ) {
342 spec[i] = getSpectrum( i ) ;
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
354 const int nchan = NUMCH ;
355 vector<double> spec( chmax_ ) ; // spectrum "before" binding
356 // DEBUG
357 //cout << "NRODataset::getSpectrum() nchan = " << nchan << " chmax_ = " << chmax_ << endl ;
358 //
359
360 const NRODataRecord *record = getRecord( i ) ;
361
362 const int bit = IBIT ; // fixed to 12 bit
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 ;
373 LogIO os( LogOrigin("NRODataset","getSpectrum",WHERE) ) ;
374 os << LogIO::WARN << "zero spectrum for row " << i << LogIO::POST ;
375 if ( spec.size() != (unsigned int)nchan )
376 spec.resize( nchan ) ;
377 for ( vector<double>::iterator i = spec.begin() ;
378 i != spec.end() ; i++ )
379 *i = 0.0 ;
380 return spec ;
381 }
382 unsigned char *cdata = (unsigned char *)&(*record->LDATA) ;
383 vector<double> mscale = MLTSCF ;
384 double dscale = mscale[getIndex( i )] ;
385 int cbind = CHBIND ;
386 int chmin = CHMIN ;
387
388 // char -> int -> double
389 vector<double>::iterator iter = spec.begin() ;
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 };
400 int j = 0 ;
401 for ( int i = 0 ; i < chmax_ ; i++ ) {
402 // char -> int
403 int ivalue = 0 ;
404 if ( bit == 12 ) { // 12 bit qunatization
405 const int ialt = i & 1 ;
406 const int idx = j + start_pos[ialt];
407 const unsigned tmp = unsigned(cdata[idx]) << 8 | cdata[idx + 1];
408 ivalue = int((tmp >> shift_right[ialt]) & 0xFFF);
409 j += incr[ialt];
410 }
411
412 if ( ( ivalue < 0 ) || ( ivalue > 4096 ) ) {
413 //cerr << "NRODataset::getSpectrum() ispec[" << i << "] is out of range" << endl ;
414 LogIO os( LogOrigin( "NRODataset", "getSpectrum", WHERE ) ) ;
415 os << LogIO::SEVERE << "ivalue for row " << i << " is out of range" << LogIO::EXCEPTION ;
416 if ( spec.size() != (unsigned int)nchan )
417 spec.resize( nchan ) ;
418 for ( vector<double>::iterator i = spec.begin() ;
419 i != spec.end() ; i++ )
420 *i = 0.0 ;
421 return spec ;
422 }
423 // DEBUG
424 //cout << "NRODataset::getSpectrum() ispec[" << i << "] = " << ispec[i] << endl ;
425 //
426
427 // int -> double
428 *iter = (double)( ivalue * scale + offset ) * dscale ;
429 // DEBUG
430 //cout << "NRODataset::getSpectrum() spec[" << i << "] = " << *iter << endl ;
431 //
432 iter++ ;
433 }
434
435 // channel binding if necessary
436 if ( cbind != 1 ) {
437 iter = spec.begin() ;
438 advance( iter, chmin ) ;
439 vector<double>::iterator iter2 = spec.begin() ;
440 for ( int i = 0 ; i < nchan ; i++ ) {
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++ ;
447 }
448 *iter2 = sum0 / sum1 ;
449 iter2++ ;
450 // DEBUG
451 //cout << "NRODataset::getSpectrum() bspec[" << i << "] = " << bspec[i] << endl ;
452 //
453 }
454 spec.resize( nchan ) ;
455 }
456
457 // DEBUG
458 //cout << "NRODataset::getSpectrum() end process" << endl ;
459 //
460
461 return spec ;
462}
463
464int NRODataset::getIndex( int irow )
465{
466 // DEBUG
467 //cout << "NRODataset::getIndex() start" << endl ;
468 //
469 const NRODataRecord *record = getRecord( irow ) ;
470
471 const string str = record->ARRYT ;
472 // DEBUG
473 //cout << "NRODataset::getIndex() str = " << str << endl ;
474 //
475 int index = (int)getArrayId(str);
476 // DEBUG
477 //cout << "NRODataset::getIndex() irow = " << irow << "str = " << str << " 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 = 1;
492 Regex reRx2("(.*V|H20ch2)$");
493 Regex reRx1("(.*H|H20ch1)$");
494 Bool match1 = false;
495 Bool match2 = false;
496 for (int i = 0; i < arrayMax(); i++) {
497 //cout << "RX[" << i << "]=" << RX[i] << endl;
498 if (!match1) {
499 match1 = (reRx1.match(RX[i].c_str(), RX[i].size()) != String::npos);
500 }
501 if (!match2) {
502 match2 = (reRx2.match(RX[i].c_str(), RX[i].size()) != String::npos);
503 }
504 }
505
506 if (match1 && match2)
507 npol = 2;
508
509 //cout << "npol = " << npol << endl;
510
511 // DEBUG
512 //cout << "NRODataset::getPolarizationNum() end process" << endl ;
513 //
514
515 return npol ;
516}
517
518vector<double> NRODataset::getStartIntTime()
519{
520 vector<double> times ;
521 for ( int i = 0 ; i < rowNum_ ; i++ ) {
522 times.push_back( getStartIntTime( i ) ) ;
523 }
524 return times ;
525}
526
527double NRODataset::getStartIntTime( int i )
528{
529 const NRODataRecord *record = getRecord( i ) ;
530
531 const char *t = record->LAVST ;
532 return getMJD( t ) ;
533}
534
535double NRODataset::getMJD( const char *time )
536{
537 // TODO: should be checked which time zone the time depends on
538 // 2008/11/14 Takeshi Nakazato
539 string strStartTime( time ) ;
540 string strYear = strStartTime.substr( 0, 4 ) ;
541 string strMonth = strStartTime.substr( 4, 2 ) ;
542 string strDay = strStartTime.substr( 6, 2 ) ;
543 string strHour = strStartTime.substr( 8, 2 ) ;
544 string strMinute = strStartTime.substr( 10, 2 ) ;
545 string strSecond = strStartTime.substr( 12, strStartTime.size() - 12 ) ;
546 unsigned int year = atoi( strYear.c_str() ) ;
547 unsigned int month = atoi( strMonth.c_str() ) ;
548 unsigned int day = atoi( strDay.c_str() ) ;
549 unsigned int hour = atoi( strHour.c_str() ) ;
550 unsigned int minute = atoi( strMinute.c_str() ) ;
551 double second = atof( strSecond.c_str() ) ;
552 Time t( year, month, day, hour, minute, second ) ;
553
554 return t.modifiedJulianDay() ;
555}
556
557double NRODataset::getScanTime( int i )
558{
559 double startTime = getStartIntTime( i ) ;
560 double interval = getIPTIM() / 86400.0 ; // [sec]->[day]
561 return startTime+0.5*interval ;
562}
563
564vector<bool> NRODataset::getIFs()
565{
566 vector<bool> v ;
567 vector< vector<double> > fref ;
568 vector< vector<double> > chcal = CHCAL ;
569 vector<double> f0cal = F0CAL ;
570 vector<double> beres = BERES ;
571 for ( int i = 0 ; i < rowNum_ ; i++ ) {
572 vector<double> f( 4, 0 ) ;
573 uInt index = getIndex( i ) ;
574 f[0] = chcal[index][0] ;
575 f[1] = f0cal[index] ;
576 f[2] = beres[index] ;
577 if ( f[0] != 0. ) {
578 f[1] = f[1] - f[0] * f[2] ;
579 }
580 const NRODataRecord *record = getRecord( i ) ;
581 f[3] = record->FREQ0 ;
582 if ( v.size() == 0 ) {
583 v.push_back( True ) ;
584 fref.push_back( f ) ;
585 }
586 else {
587 bool b = true ;
588 int fsize = fref.size() ;
589 for ( int j = 0 ; j < fsize ; j++ ) {
590 if ( fref[j][1] == f[1] && fref[j][2] == f[2] && fref[j][3] == f[3] ) {
591 b = false ;
592 }
593 }
594 if ( b ) {
595 v.push_back( True ) ;
596 fref.push_back( f ) ;
597 }
598 }
599 }
600
601
602 // DEBUG
603 //cout << "NRODataset::getIFs() number of IF is " << v.size() << endl ;
604 //
605
606 return v ;
607}
608
609vector<double> NRODataset::getFrequencies( int i )
610{
611 // return value
612 // v[0] reference channel
613 // v[1] reference frequency
614 // v[2] frequency increment
615 vector<double> v( 3, 0.0 ) ;
616
617 const NRODataRecord *record = getRecord( i ) ;
618 string arryt = string( record->ARRYT ) ;
619 uInt ib = getArrayId( arryt ) ;
620 string rxname = getRX()[0] ;
621 string key = arryt ;
622 if ( rxname.find("MULT2") != string::npos )
623 key = "BEARS" ;
624
625 if ( frec_.isDefined( key ) ) {
626 // frequency for the array is already calculated
627 Vector<Double> f = frec_.asArrayDouble( key ) ;
628 Double *f_p = f.data() ;
629 for ( int i = 0 ; i < 3 ; i++ )
630 v[i] = (double)(f_p[i]) ;
631 return v ;
632 }
633
634 //int ia = -1 ;
635 bool isAOS = false ;
636 //cout << "NRODataset::getFrequencies() record->ARRYT=" << record->ARRYT << endl ;
637 //cout << "NRODataset::getFrequencies() ib = " << ib << endl ;
638
639 if ( arryt[0] == 'W' || arryt[0] == 'U' || arryt[0] == 'H' )
640 isAOS = true ;
641
642 Bool isUSB ;
643 if ( record->FQIF1 > 0 )
644 isUSB = True ; // USB
645 else
646 isUSB = False ; // LSB
647
648 int ivdef = -1 ;
649 if ( (getVDEF()).compare( 0, 3, "RAD" ) == 0 )
650 ivdef = 0 ;
651 else if ( (getVDEF()).compare( 0, 3, "OPT" ) == 0 )
652 ivdef = 1 ;
653 // DEBUG
654 //cout << "NRODataset::getFrequencies() ivdef = " << ivdef << endl ;
655 //
656 double vel = getURVEL() + record->VRAD ;
657 double cvel = 2.99792458e8 ; // speed of light [m/s]
658 double fq0 = record->FREQ0 ;
659 //double fq0 = record->FQTRK ;
660
661 int ncal = getNFCAL()[ib] ;
662 double cw = 0.0 ;
663 vector<double> fqcal = getFQCAL()[ib] ;
664 vector<double> chcal = getCHCAL()[ib] ;
665 double f0cal = getF0CAL()[ib] ;
666 Vector<Double> freqs( ncal, fq0-f0cal ) ;
667
668 double factor = vel / cvel ;
669 if ( ivdef == 0 )
670 factor = 1.0 / ( 1.0 - factor ) ;
671 for ( int ii = 0 ; ii < ncal ; ii++ ) {
672 freqs[ii] += fqcal[ii] ;
673 if ( ivdef == 0 ) {
674 freqs[ii] = freqs[ii] * factor + record->FQTRK * ( 1.0 - factor ) ;
675 }
676 else if ( ivdef == 1 ) {
677 freqs[ii] = freqs[ii] * ( 1.0 + factor ) - record->FQTRK * factor ;
678 }
679
680 //ofstream ofs("freqs.txt",ios::out|ios::app) ;
681 //ofs << setprecision(16) ;
682 //ofs << i << " " << record->ARRYT << " " << chcal[ii] << " " << freqs[ii] << " " << record->ISCAN << " " << fqcal[ii] << " " << f0cal << " " << record->FQTRK << " " << vel << endl ;
683 //ofs.close() ;
684
685 }
686
687 if ( isAOS ) {
688 // regridding
689 while ( ncal < (int)chcal.size() ) {
690 chcal.pop_back() ;
691 }
692 Vector<Double> xin( chcal ) ;
693 Vector<Double> yin( freqs ) ;
694 int nchan = getNUMCH() ;
695 Vector<Double> xout( nchan ) ;
696 indgen( xout ) ;
697 Vector<Double> yout ;
698 InterpolateArray1D<Double, Double>::interpolate( yout, xout, xin, yin, InterpolateArray1D<Double,Double>::cubic ) ;
699 Double bw = abs( yout[nchan-1] - yout[0] ) ;
700 bw += 0.5 * abs( yout[nchan-1] - yout[nchan-2] + yout[1] - yout[0] ) ;
701 Double dz = bw / (Double) nchan ;
702 if ( yout[0] > yout[1] )
703 dz = - dz ;
704 v[0] = 0 ;
705 v[1] = yout[0] ;
706 v[2] = dz ;
707 }
708 else {
709
710 cw = ( freqs[1] - freqs[0] )
711 / ( chcal[1] - chcal[0] ) ;
712
713 if ( isUSB ) {
714 // channel frequency inversion
715 cw *= -1.0 ;
716 Double tmp = freqs[1] ;
717 freqs[1] = freqs[0] ;
718 freqs[0] = tmp ;
719 }
720
721 v[0] = chcal[0] - 1 ; // 0-base
722 v[1] = freqs[0] ;
723 v[2] = cw ;
724 }
725
726 if ( refFreq_[ib] == 0.0 )
727 refFreq_[ib] = v[1] ;
728
729 // register frequency setting to Record
730 Vector<Double> f( v ) ;
731 frec_.define( key, f ) ;
732
733 return v ;
734}
735
736uInt NRODataset::getArrayId( string type )
737{
738 string sbeamno = type.substr( 1, type.size()-1 ) ;
739 uInt ib = atoi( sbeamno.c_str() ) - 1 ;
740 return ib ;
741}
742
743uInt NRODataset::getSortedArrayId( string type )
744{
745 uInt index = 0;
746 while (arrayNames_[index] != type && index < (uInt)ARYNM)
747 ++index;
748 return index;
749}
750
751void NRODataset::show()
752{
753 LogIO os( LogOrigin( "NRODataset", "show()", WHERE ) ) ;
754
755 os << LogIO::NORMAL << "------------------------------------------------------------" << endl ;
756 os << LogIO::NORMAL << "Number of scan = " << scanNum_ << endl ;
757 os << LogIO::NORMAL << "Number of data record = " << rowNum_ << endl ;
758 os << LogIO::NORMAL << "Length of data record = " << scanLen_ << " bytes" << endl ;
759 os << LogIO::NORMAL << "Allocated memory for spectral data = " << dataLen_ << " bytes" << endl ;
760 os << LogIO::NORMAL << "Max number of channel = " << chmax_ << endl ;
761 os << LogIO::NORMAL << "------------------------------------------------------------" << endl ;
762 os.post() ;
763
764}
765
766double NRODataset::toLSR( double v, double t, double x, double y )
767{
768 double vlsr ;
769
770 // get epoch
771 double tcent = t + 0.5*getIPTIM()/86400.0 ;
772 MEpoch me( Quantity( tcent, "d" ), MEpoch::UTC ) ;
773
774 // get antenna position
775 MPosition mp ;
776 if ( SITE.find( "45" ) != string::npos ) {
777 // 45m telescope
778 Double posx = -3.8710235e6 ;
779 Double posy = 3.4281068e6 ;
780 Double posz = 3.7240395e6 ;
781 mp = MPosition( MVPosition( posx, posy, posz ),
782 MPosition::ITRF ) ;
783 }
784 else {
785 // ASTE
786 Vector<Double> pos( 2 ) ;
787 pos[0] = -67.7031 ;
788 pos[1] = -22.9717 ;
789 Double sitealt = 4800.0 ;
790 mp = MPosition( MVPosition( Quantity( sitealt, "m" ),
791 Quantum< Vector<Double> >( pos, "deg" ) ),
792 MPosition::WGS84 ) ;
793 }
794
795 // get direction
796 MDirection md ;
797 if ( SCNCD == 0 ) {
798 // RADEC
799 if ( EPOCH == "B1950" ) {
800 md = MDirection( Quantity( Double(x), "rad" ), Quantity( Double(y), "rad" ),
801 MDirection::B1950 ) ;
802 }
803 else {
804 md = MDirection( Quantity( Double(x), "rad" ), Quantity( Double(y), "rad" ),
805 MDirection::J2000 ) ;
806 }
807 }
808 else if ( SCNCD == 1 ) {
809 // LB
810 md = MDirection( Quantity( Double(x), "rad" ), Quantity( Double(y), "rad" ),
811 MDirection::GALACTIC ) ;
812 }
813 else {
814 // AZEL
815 md = MDirection( Quantity( Double(x), "rad" ), Quantity( Double(y), "rad" ),
816 MDirection::AZEL ) ;
817 }
818
819 // to LSR
820 MeasFrame mf( me, mp, md ) ;
821 MFrequency::Convert tolsr( MFrequency::TOPO, MFrequency::Ref( MFrequency::LSRK, mf ) ) ;
822 vlsr = (double)(tolsr( Double(v) ).get( "Hz" ).getValue()) ;
823
824 return vlsr ;
825}
826
827uInt NRODataset::getPolNo( int i )
828{
829 int idx = getIndex( i ) ;
830// cout << "HORN[" << idx << "]=" << HORN[idx]
831// << ", RX[" << idx << "]=" << RX[idx] << endl ;
832 return polNoFromRX( RX[idx] ) ;
833}
834
835uInt NRODataset::polNoFromRX( const string &rx )
836{
837 uInt polno = 0 ;
838 // 2013/01/23 TN
839 // In NRO 45m telescope, naming convension for dual-polarization
840 // receiver is as follows:
841 //
842 // xxxH for horizontal component,
843 // xxxV for vertical component.
844 //
845 // Exception is H20ch1/ch2.
846 // Here, POLNO is assigned as follows:
847 //
848 // POLNO=0: xxxH or H20ch1
849 // 1: xxxV or H20ch2
850 //
851 // For others, POLNO is always 0.
852 String rxString(rx);
853 rxString.trim();
854 //cout << "rx='" << rxString << "' (size " << rxString.size() << ")" << endl;
855 Regex reRx("(.*V|H20ch2)$");
856 if (reRx.match(rxString.c_str(), rxString.size()) != String::npos) {
857 //cout << "match!" << endl;
858 polno = 1;
859 }
860 return polno ;
861}
862
863void NRODataset::initArray()
864{
865 if (ARYNM <= 0)
866 throw AipsError("ARYNM must be greater than zero.");
867
868 int numArray = 0;
869 arrayNames_.resize(ARYNM);
870 for (int irow = 0; numArray < ARYNM && irow < rowNum_; irow++) {
871 //cout << "irow " << irow << endl;
872 const NRODataRecord *record = getRecord( irow ) ;
873 const string str = record->ARRYT ;
874 if (find(arrayNames_.begin(), arrayNames_.end(), str) == arrayNames_.end()) {
875 arrayNames_[numArray] = str;
876 //cout << "arrayNames_[" << numArray << "]=" << str << endl;
877 ++numArray;
878 }
879 }
880 //cout << "numArray=" << numArray << endl;
881}
Note: See TracBrowser for help on using the repository browser.