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

Last change on this file since 2748 was 2748, checked in by Takeshi Nakazato, 11 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...

POLNO is properly set according to RX name. When RX name ends with 'V'
or is 'H20ch2', POLNO will be set to 1. Otherwise, POLNO is 0.


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