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

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

New Development: No

JIRA Issue: Yes CAS-2819

Ready for Test: Yes

Interface Changes: No

What Interface Changed: Please list interface changes

Test Programs: List test programs

Put in Release Notes: Yes/No?

Module(s): Module Names change impacts.

Description: Describe your changes here...

IFNO is taken from ARRAY number.
Bug fix on checking if spectrometer is AOS or not.


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