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

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

more refactoring on NRO filler.


File size: 45.7 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  : scanNum_(0),
61    rowNum_(0),
62    scanLen_(0),
63    dataLen_(0),
64    dataid_(-1),
65    filename_(name),
66    fp_(NULL),
67    same_(-1),
68    frec_()
69{
70  // size for common part of data
71  datasize_ = sizeof( char ) * 8   // LOFIL
72    + sizeof( char ) * 8           // VER
73    + sizeof( char ) * 16          // GROUP
74    + sizeof( char ) * 16          // PROJ
75    + sizeof( char ) * 24          // SCHED
76    + sizeof( char ) * 40          // OBSVR
77    + sizeof( char ) * 16          // LOSTM
78    + sizeof( char ) * 16          // LOETM
79    + sizeof( int ) * 2            // ARYNM, NSCAN
80    + sizeof( char ) * 120         // TITLE
81    + sizeof( char ) * 16          // OBJ
82    + sizeof( char ) * 8           // EPOCH
83    + sizeof( double ) * 4         // RA0, DEC0, GLNG0, GLAT0
84    + sizeof( int ) * 2            // NCALB, SCNCD
85    + sizeof( char ) * 120         // SCMOD
86    + sizeof( double )             // URVEL
87    + sizeof( char ) * 4           // VREF
88    + sizeof( char ) * 4           // VDEF
89    + sizeof( char ) * 8           // SWMOD
90    + sizeof( double ) * 8         // FRQSW, DBEAM, MLTOF, CMTQ, CMTE, CMTSOM, CMTNODE, CMTI
91    + sizeof( char ) * 24          // CMTTM
92    + sizeof( double ) * 6         // SBDX, SBDY, SBDZ1, SBDZ2, DAZP, DELP
93    + sizeof( int ) * 4            // CHBIND, NUMCH, CHMIN, CHMAX
94    + sizeof( double ) * 3         // ALCTM, IPTIM, PA
95    + sizeof( int ) * 3            // SCNLEN, SBIND, IBIT
96    + sizeof( char ) * 8 ;         // SITE
97}
98
99// destructor
100NRODataset::~NRODataset()
101{
102  // release memory
103  releaseRecord() ;
104
105  // close file
106  close() ;
107}
108
109// data initialization
110void NRODataset::initializeCommon()
111{
112  LogIO os( LogOrigin( "NRODataset", "initialize()", WHERE ) ) ;
113
114  int arymax = arrayMax() ;
115
116  // check endian
117  open() ;
118  fseek( fp_, 144, SEEK_SET ) ;
119  int tmp ;
120  if( fread( &tmp, 1, sizeof(int), fp_ ) != sizeof(int) ) {
121    os << LogIO::SEVERE << "Error while checking endian of the file. " << LogIO::EXCEPTION ;
122    return ;
123  }
124  if ( ( 0 < tmp ) && ( tmp <= arymax ) ) {
125    same_ = 1 ;
126    os << LogIO::NORMAL << "same endian " << LogIO::POST ;
127  }
128  else {
129    same_ = 0 ;
130    os << LogIO::NORMAL << "different endian " << LogIO::POST ;
131  }
132  fseek( fp_, 0, SEEK_SET ) ;
133
134  // common part of calculation of data size and memory allocation
135  RX.resize( arymax ) ;
136  HPBW.resize( arymax ) ;
137  EFFA.resize( arymax ) ;
138  EFFB.resize( arymax ) ;
139  EFFL.resize( arymax ) ;
140  EFSS.resize( arymax ) ;
141  GAIN.resize( arymax ) ;
142  HORN.resize( arymax ) ;
143  POLTP.resize( arymax ) ;
144  POLDR.resize( arymax ) ;
145  POLAN.resize( arymax ) ;
146  DFRQ.resize( arymax ) ;
147  SIDBD.resize( arymax ) ;
148  REFN.resize( arymax ) ;
149  IPINT.resize( arymax ) ;
150  MULTN.resize( arymax ) ;
151  MLTSCF.resize( arymax ) ;
152  LAGWIND.resize( arymax ) ;
153  BEBW.resize( arymax ) ;
154  BERES.resize( arymax ) ;
155  CHWID.resize( arymax ) ;
156  ARRY.resize( arymax ) ;
157  NFCAL.resize( arymax ) ;
158  F0CAL.resize( arymax ) ;
159  FQCAL.resize( arymax ) ;
160  CHCAL.resize( arymax ) ;
161  CWCAL.resize( arymax ) ;
162  DSBFC.resize( arymax ) ;
163
164  for ( int i = 0 ; i < arymax ; i++ ) {
165    FQCAL[i].resize( 10 ) ;
166    CHCAL[i].resize( 10 ) ;
167    CWCAL[i].resize( 10 ) ;
168  }
169
170  // NRODataRecord
171  record_ = new NRODataRecord() ;
172  record_->LDATA = NULL ;
173
174  // reference frequency
175  refFreq_.resize( arymax, 0.0 ) ;
176}
177
178// fill data header
179int NRODataset::fillHeader()
180{
181  LogIO os( LogOrigin( "NRODataset", "fillHeader()", WHERE ) ) ;
182
183  // open file
184  if ( open() ) {
185    os << LogIO::SEVERE << "Error opening file " << filename_ << "." << LogIO::EXCEPTION ;
186    return -1 ;
187  }
188
189  // fill
190  int status = fillHeader( same_ ) ;
191
192  if ( status != 0 ) {
193    os << LogIO::SEVERE << "Error while reading header " << filename_ << "." << LogIO::EXCEPTION ;
194    return status ;
195  }
196
197//   //scanNum_ = NSCAN + 1 ; // includes ZERO scan
198//   scanLen_ = SCNLEN ;
199//   dataLen_ = scanLen_ - SCAN_HEADER_SIZE ;
200//   scanNum_ = getScanNum();
201//   rowNum_ = scanNum_ * ARYNM ;
202//   chmax_ = (int) ( dataLen_ * 8 / IBIT ) ;
203//   record_->LDATA = new char[dataLen_] ;
204
205  initArray();
206
207  show() ;
208
209  return status ;
210}
211
212int NRODataset::fillHeaderCommon( int sameEndian )
213{
214  LogIO os( LogOrigin( "NRODataset", "fillHeader()", WHERE ) ) ;
215
216  int arymax = arrayMax() ;
217
218  string str4( 4, ' ' ) ;
219  string str8( 8, ' ' ) ;
220  string str16( 16, ' ' ) ;
221  string str18( 18, ' ' ) ;
222  string str24( 24, ' ' ) ;
223  string str40( 40, ' ' ) ;
224  string str120( 120, ' ' ) ;
225  char c4[4] ;
226  char c8[8] ;
227  char c16[16] ;
228  char c18[18] ;
229  char c24[24] ;
230  char c40[40] ;
231  char c120[120] ;
232
233  // make sure file pointer points a beginning of the file
234  fseek( fp_, 0, SEEK_SET ) ;
235
236  // read data header
237  strcpy( c8, str8.c_str() ) ;
238  if ( readHeader( c8, 8 ) == -1 ) {
239    os << LogIO::WARN << "Error while reading data LOFIL." << LogIO::POST ;
240    return -1 ;
241  }
242  LOFIL = string( c8 ) ;
243  // DEBUG
244  //cout << "LOFIL = " << LOFIL << endl ;
245  //
246  strcpy( c8, str8.c_str() ) ;
247  if ( readHeader( c8, 8 ) == -1 ) {
248    os << LogIO::WARN << "Error while reading data VER." << LogIO::POST ;
249    return -1 ;
250  }
251  VER = string( c8 ) ;
252  // DEBUG
253  //cout << "VER = " << VER << endl ;
254  //
255  strcpy( c16, str16.c_str() ) ;
256  if ( readHeader( c16, 16 ) == -1 ) {
257    os << LogIO::WARN << "Error while reading data GROUP." << LogIO::POST ;
258    return -1 ;
259  }
260  GROUP = string( c16 ) ;
261  // DEBUG
262  //cout << "GROUP = " << GROUP << endl ;
263  //
264  strcpy( c16, str16.c_str() ) ;
265  if ( readHeader( c16, 16 ) == -1 ) {
266    os << LogIO::WARN << "Error while reading data PROJ." << LogIO::POST ;
267    return -1 ;
268  }
269  PROJ = string( c16 ) ;
270  // DEBUG
271  //cout << "PROJ = " << PROJ << endl ;
272  //
273  strcpy( c24, str24.c_str() ) ;
274  if ( readHeader( c24, 24 ) == -1 ) {
275    os << LogIO::WARN << "Error while reading data SCHED." << LogIO::POST ;
276    return -1 ;
277  }
278  SCHED = string( c24 ) ;
279  // DEBUG
280  //cout << "SCHED = " << SCHED << endl ;
281  //
282  strcpy( c40, str40.c_str() ) ;
283  if ( readHeader( c40, 40 ) == -1 ) {
284    os << LogIO::WARN << "Error while reading data OBSVR." << LogIO::POST ;
285    return -1 ;
286  } 
287  OBSVR = string( c40 ) ;
288  // DEBUG
289  //cout << "OBSVR = " << OBSVR << endl ;
290  //
291  strcpy( c16, str16.c_str() ) ;
292  if ( readHeader( c16, 16 ) == -1 ) {
293    os << LogIO::WARN << "Error while reading data LOSTM." << LogIO::POST ;
294    return -1 ;
295  }
296  LOSTM = string( c16 ) ;
297  // DEBUG
298  //cout << "LOSTM = " << LOSTM << endl ;
299  //
300  strcpy( c16, str16.c_str() ) ;
301  if ( readHeader( c16, 16 ) == -1 ) {
302    os << LogIO::WARN << "Error while reading data LOETM." << LogIO::POST ;
303    return -1 ;
304  }
305  LOETM = string( c16 ) ;
306  // DEBUG
307  //cout << "LOETM = " << LOETM << endl ;
308  //
309  if ( readHeader( ARYNM, sameEndian ) == -1 ) {
310    os << LogIO::WARN << "Error while reading data ARYNM." << LogIO::POST ;
311    return -1 ;
312  }
313  // DEBUG
314  //cout << "ARYNM = " << ARYNM << endl ;
315  //
316  if ( readHeader( NSCAN, sameEndian ) == -1 ) {
317    os << LogIO::WARN << "Error while reading data NSCAN." << LogIO::POST ;
318    return -1 ;
319  }
320  // DEBUG
321  //cout << "NSCAN = " << NSCAN << endl ;
322  //
323  strcpy( c120, str120.c_str() ) ;
324  if ( readHeader( c120, 120 ) == -1 ) {
325    os << LogIO::WARN << "Error while reading data TITLE." << LogIO::POST ;
326    return -1 ;
327  }
328  TITLE = string( c120 ) ;
329  // DEBUG
330  //cout << "TITLE = " << TITLE << endl ;
331  //
332  strcpy( c16, str16.c_str() ) ;
333  if ( readHeader( c16, 16 ) == -1 ) {
334    os << LogIO::WARN << "Error while reading data OBJ." << LogIO::POST ;
335    return -1 ;
336  }
337  OBJ = string( c16 ) ;
338  // DEBUG
339  //cout << "OBJ = " << OBJ << endl ;
340  //
341  strcpy( c8, str8.c_str() ) ;
342  if ( readHeader( c8, 8 ) == -1 ) {
343    os << LogIO::WARN << "Error while reading data EPOCH." << LogIO::POST ;
344    return -1 ;
345  }
346  EPOCH = string( c8 ) ;
347  // DEBUG
348  //cout << "EPOCH = " << EPOCH << endl ;
349  //
350  if ( readHeader( RA0, sameEndian ) == -1 ) {
351    os << LogIO::WARN << "Error while reading data RA0." << LogIO::POST ;
352    return -1 ;
353  }
354  // DEBUG
355  //cout << "RA0 = " << RA0 << endl ;
356  //
357  if ( readHeader( DEC0, sameEndian ) == -1 ) {
358    os << LogIO::WARN << "Error while reading data DEC0." << LogIO::POST ;
359    return -1 ;
360  }
361  // DEBUG
362  //cout << "DEC0 = " << DEC0 << endl ;
363  //
364  if ( readHeader( GLNG0, sameEndian ) == -1 ) {
365    os << LogIO::WARN << "Error while reading data GLNG0." << LogIO::POST ;
366    return -1 ;
367  }
368  // DEBUG
369  //cout << "GLNG0 = " << GLNG0 << endl ;
370  //
371  if ( readHeader( GLAT0, sameEndian ) == -1 ) {
372    os << LogIO::WARN << "Error while reading data GLAT0." << LogIO::POST ;
373    return -1 ;
374  }
375  // DEBUG
376  //cout << "GLAT0 = " << GLAT0 << endl ;
377  //
378  if ( readHeader( NCALB, sameEndian ) == -1 ) {
379    os << LogIO::WARN << "Error while reading data NCALB." << LogIO::POST ;
380    return -1 ;
381  }
382  // DEBUG
383  //cout << "NCALB = " << NCALB << endl ;
384  //
385  if ( readHeader( SCNCD, sameEndian ) == -1 ) {
386    os << LogIO::WARN << "Error while reading data SCNCD." << LogIO::POST ;
387    return -1 ;
388  }
389  // DEBUG
390  //cout << "SCNCD = " << SCNCD << endl ;
391  //
392  strcpy( c120, str120.c_str() ) ;
393  if ( readHeader( c120, 120 ) == -1 ) {
394    os << LogIO::WARN << "Error while reading data SCMOD." << LogIO::POST ;
395    return -1 ;
396  }
397  SCMOD = string( c120 ) ;
398  // DEBUG
399  //cout << "SCMOD = " << SCMOD << endl ;
400  //
401  if ( readHeader( URVEL, sameEndian ) == -1 ) {
402    os << LogIO::WARN << "Error while reading data URVEL." << LogIO::POST ;
403    return -1 ;
404  }
405  // DEBUG
406  //cout << "URVEL = " << URVEL << endl ;
407  //
408  strcpy( c4, str4.c_str() ) ;
409  if ( readHeader( c4, 4 ) == -1 ) {
410    os << LogIO::WARN << "Error while reading data VREF." << LogIO::POST ;
411    return -1 ;
412  }
413  VREF = string( c4 ) ;
414  // DEBUG
415  //cout << "VREF = " << VREF << endl ;
416  //
417  strcpy( c4, str4.c_str() ) ;
418  if ( readHeader( c4, 4 ) == -1 ) {
419    os << LogIO::WARN << "Error while reading data VDEF." << LogIO::POST ;
420    return -1 ;
421  }
422  VDEF = string( c4 ) ;
423  // DEBUG
424  //cout << "VDEF = " << VDEF << endl ;
425  //
426  strcpy( c8, str8.c_str() ) ;
427  if ( readHeader( c8, 8 ) == -1 ) {
428    os << LogIO::WARN << "Error while reading data SWMOD." << LogIO::POST ;
429    return -1 ;
430  }
431  SWMOD = string( c8 ) + "::OTF" ;
432  // DEBUG
433  //cout << "SWMOD = " << SWMOD << endl ;
434  //
435  if ( readHeader( FRQSW, sameEndian ) == -1 ) {
436    os << LogIO::WARN << "Error while reading data FRQSW." << LogIO::POST ;
437    return -1 ;
438  }
439  // DEBUG
440  //cout << "FRQSW = " << FRQSW << endl ;
441  //
442  if ( readHeader( DBEAM, sameEndian ) == -1 ) {
443    os << LogIO::WARN << "Error while reading data DBEAM." << LogIO::POST ;
444    return -1 ;
445  }
446  // DEBUG
447  //cout << "DBEAM = " << DBEAM << endl ;
448  //
449  if ( readHeader( MLTOF, sameEndian ) == -1 ) {
450    os << LogIO::WARN << "Error while reading data MLTOF." << LogIO::POST ;
451    return -1 ;
452  }
453  // DEBUG
454  //cout << "MLTOF = " << MLTOF << endl ;
455  //
456  if ( readHeader( CMTQ, sameEndian ) == -1 ) {
457    os << LogIO::WARN << "Error while reading data CMTQ." << LogIO::POST ;
458    return -1 ;
459  }
460  // DEBUG
461  //cout << "CMTQ = " << CMTQ << endl ;
462  //
463  if ( readHeader( CMTE, sameEndian ) == -1 ) {
464    os << LogIO::WARN << "Error while reading data CMTE." << LogIO::POST ;
465    return -1 ;
466  }
467  // DEBUG
468  //cout << "CMTE = " << CMTE << endl ;
469  //
470  if ( readHeader( CMTSOM, sameEndian ) == -1 ) {
471    os << LogIO::WARN << "Error while reading data CMTSOM." << LogIO::POST ;
472    return -1 ;
473  }
474  // DEBUG
475  //cout << "CMTSOM = " << CMTSOM << endl ;
476  //
477  if ( readHeader( CMTNODE, sameEndian ) == -1 ) {
478    os << LogIO::WARN << "Error while reading data CMTNODE." << LogIO::POST ;
479    return -1 ;
480  }
481  // DEBUG
482  //cout << "CMTNODE = " << CMTNODE << endl ;
483  //
484  if ( readHeader( CMTI, sameEndian ) == -1 ) {
485    os << LogIO::WARN << "Error while reading data CMTI." << LogIO::POST ;
486    return -1 ;
487  }
488  // DEBUG
489  //cout << "CMTI = " << CMTI << endl ;
490  //
491  strcpy( c24, str24.c_str() ) ;
492  if ( readHeader( c24, 24 ) == -1 ) {
493    os << LogIO::WARN << "Error while reading data CMTTM." << LogIO::POST ;
494    return -1 ;
495  }
496  CMTTM = string( c24 ) ;
497  // DEBUG
498  //cout << "CMTTM = " << CMTTM << endl ;
499  //
500  if ( readHeader( SBDX, sameEndian ) == -1 ) {
501    os << LogIO::WARN << "Error while reading data SBDX." << LogIO::POST ;
502    return -1 ;
503  }
504  // DEBUG
505  //cout << "SBDX = " << SBDX << endl ;
506  //
507  if ( readHeader( SBDY, sameEndian ) == -1 ) {
508    os << LogIO::WARN << "Error while reading data SBDY." << LogIO::POST ;
509    return -1 ;
510  }
511  // DEBUG
512  //cout << "SBDY = " << SBDY << endl ;
513  //
514  if ( readHeader( SBDZ1, sameEndian ) == -1 ) {
515    os << LogIO::WARN << "Error while reading data SBDZ1." << LogIO::POST ;
516    return -1 ;
517  }
518  // DEBUG
519  //cout << "SBDZ1 = " << SBDZ1 << endl ;
520  //
521  if ( readHeader( SBDZ2, sameEndian ) == -1 ) {
522    os << LogIO::WARN << "Error while reading data SBDZ2." << LogIO::POST ;
523    return -1 ;
524  }
525  // DEBUG
526  //cout << "SBDZ2 = " << SBDZ2 << endl ;
527  //
528  if ( readHeader( DAZP, sameEndian ) == -1 ) {
529    os << LogIO::WARN << "Error while reading data DAZP." << LogIO::POST ;
530    return -1 ;
531  }
532  // DEBUG
533  //cout << "DAZP = " << DAZP << endl ;
534  //
535  if ( readHeader( DELP, sameEndian ) == -1 ) {
536    os << LogIO::WARN << "Error while reading data DELP." << LogIO::POST ;
537    return -1 ;
538  }
539  // DEBUG
540  //cout << "DELP = " << DELP << endl ;
541  //
542  if ( readHeader( CHBIND, sameEndian ) == -1 ) {
543    os << LogIO::WARN << "Error while reading data CHBIND." << LogIO::POST ;
544    return -1 ;
545  }
546  // DEBUG
547  //cout << "CHBIND = " << CHBIND << endl ;
548  //
549  if ( readHeader( NUMCH, sameEndian ) == -1 ) {
550    os << LogIO::WARN << "Error while reading data NUMCH." << LogIO::POST ;
551    return -1 ;
552  }
553  // DEBUG
554  //cout << "NUMCH = " << NUMCH << endl ;
555  //
556  if ( readHeader( CHMIN, sameEndian ) == -1 ) {
557    os << LogIO::WARN << "Error while reading data CHMIN." << LogIO::POST ;
558    return -1 ;
559  }
560  // DEBUG
561  //cout << "CHMIN = " << CHMIN << endl ;
562  //
563  if ( readHeader( CHMAX, sameEndian ) == -1 ) {
564    os << LogIO::WARN << "Error while reading data CHMAX." << LogIO::POST ;
565    return -1 ;
566  }
567  // DEBUG
568  //cout << "CHMAX = " << CHMAX << endl ;
569  //
570  if ( readHeader( ALCTM, sameEndian ) == -1 ) {
571    os << LogIO::WARN << "Error while reading data ALCTM." << LogIO::POST ;
572    return -1 ;
573  }
574  // DEBUG
575  //cout << "ALCTM = " << ALCTM << endl ;
576  //
577  if ( readHeader( IPTIM, sameEndian ) == -1 ) {
578    os << LogIO::WARN << "Error while reading data IPTIM." << LogIO::POST ;
579    return -1 ;
580  }
581  // DEBUG
582  //cout << "IPTIM = " << IPTIM << endl ;
583  //
584  if ( readHeader( PA, sameEndian ) == -1 ) {
585    os << LogIO::WARN << "Error while reading data PA." << LogIO::POST ;
586    return -1 ;
587  }
588  // DEBUG
589  //cout << "PA = " << PA << endl ;
590  //
591  for ( int i = 0 ; i < arymax ; i++ ) {
592    strcpy( c18, str18.c_str() ) ;
593    if ( readHeader( c18, 16 ) == -1 ) {
594      os << LogIO::WARN << "Error while reading data RX[" << i << "]." << LogIO::POST ;
595      return -1 ;
596    }
597    c18[16] = '\0' ;
598    RX[i] = string( c18 ) ;
599  }
600  // DEBUG
601//   nro_debug_output( "RX", arymax, RX ) ;
602  //
603  for ( int i = 0 ; i < arymax ; i++ ) {
604    if ( readHeader( HPBW[i], sameEndian ) == -1 ) {
605      os << LogIO::WARN << "Error while reading data HPBW[" << i << "]." << LogIO::POST ;
606      return -1 ;
607    }
608  }
609  // DEBUG
610//   nro_debug_output( "HPBW", arymax, HPBW ) ;
611  //
612  for ( int i = 0 ; i < arymax ; i++ ) {
613    if ( readHeader( EFFA[i], sameEndian ) == -1 ) {
614      os << LogIO::WARN << "Error while reading data EFFA[" << i << "]." << LogIO::POST ;
615      return -1 ;
616    }
617  }
618  // DEBUG
619//   nro_debug_output( "EFFA", arymax, EFFA ) ;
620  //
621  for ( int i = 0 ; i < arymax ; i++ ) {
622    if ( readHeader( EFFB[i], sameEndian ) == -1 ) {
623      os << LogIO::WARN << "Error while reading data EFFB[" << i << "]." << LogIO::POST ;
624      return -1 ;
625    }
626  }
627  // DEBUG
628//   nro_debug_output( "EFFB", arymax, EFFB ) ;
629  //
630  for ( int i = 0 ; i < arymax ; i++ ) {
631    if ( readHeader( EFFL[i], sameEndian ) == -1 ) {
632      os << LogIO::WARN << "Error while reading data EFFL[" << i << "]." << LogIO::POST ;
633      return -1 ;
634    }
635  }
636  // DEBUG
637//   nro_debug_output( "EFFL", arymax, EFFL ) ;
638  //
639  for ( int i = 0 ; i < arymax ; i++ ) {
640    if ( readHeader( EFSS[i], sameEndian ) == -1 ) {
641      os << LogIO::WARN << "Error while reading data EFSS[" << i << "]." << LogIO::POST ;
642      return -1 ;
643    }
644  }
645  // DEBUG
646//   nro_debug_output( "EFSS", arymax, EFSS ) ;
647  //
648  for ( int i = 0 ; i < arymax ; i++) {
649    if ( readHeader( GAIN[i], sameEndian ) == -1 ) {
650      os << LogIO::WARN << "Error while reading data GAIN[" << i << "]." << LogIO::POST ;
651      return -1 ;
652    }
653  }
654  // DEBUG
655//   nro_debug_output( "GAIN", arymax, GAIN ) ;
656  //
657  for ( int i = 0 ; i < arymax ; i++) {
658    strcpy( c4, str4.c_str() ) ;
659    if ( readHeader( c4, 4 ) == -1 ) {
660      os << LogIO::WARN << "Error while reading data HORN[" << i << "]." << LogIO::POST ;
661      return -1 ;
662    }
663    HORN[i] = string( c4 ) ;
664  }
665  // DEBUG
666//   nro_debug_output( "HORN", arymax, HORN ) ;
667  //
668  for ( int i = 0 ; i < arymax ; i++) {
669    strcpy( c4, str4.c_str() ) ;
670    if ( readHeader( c4, 4 ) == -1 ) {
671      os << LogIO::WARN << "Error while reading data POLTP[" << i << "]." << LogIO::POST ;
672      return -1 ;
673    }
674    POLTP[i] = string( c4 ) ;
675  }
676  // DEBUG
677//   nro_debug_output( "POLTP", arymax, POLTP ) ;
678  //
679  for ( int i = 0 ; i < arymax ; i++) {
680    if ( readHeader( POLDR[i], sameEndian ) == -1 ) {
681      os << LogIO::WARN << "Error while reading data POLDR[" << i << "]." << LogIO::POST ;
682      return -1 ;
683    }
684  }
685  // DEBUG
686//   nro_debug_output( "POLDR", arymax, POLDR ) ;
687  //
688  for ( int i = 0 ; i < arymax ; i++) {
689    if ( readHeader( POLAN[i], sameEndian ) == -1 ) {
690      os << LogIO::WARN << "Error while reading data POLAN[" << i << "]." << LogIO::POST ;
691      return -1 ;
692    }
693  }
694  // DEBUG
695//   nro_debug_output( "POLAN", arymax, POLAN ) ;
696  //
697  for ( int i = 0 ; i < arymax ; i++) {
698    if ( readHeader( DFRQ[i], sameEndian ) == -1 ) {
699      os << LogIO::WARN << "Error while reading data DFRQ[" << i << "]." << LogIO::POST ;
700      return -1 ;
701    }
702  }
703  // DEBUG
704//   nro_debug_output( "DFRQ", arymax, DFRQ ) ;
705  //
706  for ( int i = 0 ; i < arymax ; i++) {
707    strcpy( c4, str4.c_str() ) ;
708    if ( readHeader( c4, 4 ) == -1 ) {
709      os << LogIO::WARN << "Error while reading data SIDBD[" << i << "]." << LogIO::POST ;
710      return -1 ;
711    }
712    SIDBD[i] = string( c4 ) ;
713  }
714  // DEBUG
715//   nro_debug_output( "SIDBD", arymax, SIDBD ) ;
716  //
717  for ( int i = 0 ; i < arymax ; i++) {
718    if ( readHeader( REFN[i], sameEndian ) == -1 ) {
719      os << LogIO::WARN << "Error while reading data REFN[" << i << "]." << LogIO::POST ;
720      return -1 ;
721    }
722  }
723  // DEBUG
724//   nro_debug_output( "REFN", arymax, REFN ) ;
725  //
726  for ( int i = 0 ; i < arymax ; i++) {
727    if ( readHeader( IPINT[i], sameEndian ) == -1 ) {
728      os << LogIO::WARN << "Error while reading data IPINT[" << i << "]." << LogIO::POST ;
729      return -1 ;
730    }
731  }
732  // DEBUG
733//   nro_debug_output( "IPINT", arymax, IPINT ) ;
734  //
735  for ( int i = 0 ; i < arymax ; i++) {
736    if ( readHeader( MULTN[i], sameEndian ) == -1 ) {
737      os << LogIO::WARN << "Error while reading data MULTN[" << i << "]." << LogIO::POST ;
738      return -1 ;
739    }
740  }
741  // DEBUG
742//   nro_debug_output( "MULTN", arymax, MULTN ) ;
743  //
744  for ( int i = 0 ; i < arymax ; i++) {
745    if ( readHeader( MLTSCF[i], sameEndian ) == -1 ) {
746      os << LogIO::WARN << "Error while reading data MLTSCF[" << i << "]." << LogIO::POST ;
747      return -1 ;
748    }
749  }
750  // DEBUG
751//   nro_debug_output( "MLTSCF", arymax, MLTSCF ) ;
752  //
753  for ( int i = 0 ; i < arymax ; i++) {
754    strcpy( c8, str8.c_str() ) ;
755    if ( readHeader( c8, 8 ) == -1 ) {
756      os << LogIO::WARN << "Error while reading data LAGWIND[" << i << "]." << LogIO::POST ;
757      return -1 ;
758    }
759    LAGWIND[i] = string( c8 ) ;
760  }
761  // DEBUG
762//   nro_debug_output( "LAGWIND", arymax, LAGWIND ) ;
763  //
764  for ( int i = 0 ; i < arymax ; i++) {
765    if ( readHeader( BEBW[i], sameEndian ) == -1 ) {
766      os << LogIO::WARN << "Error while reading data BEBW[" << i << "]." << LogIO::POST ;
767      return -1 ;
768    }
769  }
770  // DEBUG
771//   nro_debug_output( "BEBW", arymax, BEBW ) ;
772  //
773  for ( int i = 0 ; i < arymax ; i++) {
774    if ( readHeader( BERES[i], sameEndian ) == -1 ) {
775      os << LogIO::WARN << "Error while reading data BERES[" << i << "]." << LogIO::POST ;
776      return -1 ;
777    }
778  }
779  // DEBUG
780//   nro_debug_output( "BERES", arymax, BERES ) ;
781  //
782  for ( int i = 0 ; i < arymax ; i++) {
783    if ( readHeader( CHWID[i], sameEndian ) == -1 ) {
784      os << LogIO::WARN << "Error while reading data CHWID[" << i << "]." << LogIO::POST ;
785      return -1 ;
786    }
787  }
788  // DEBUG
789//   nro_debug_output( "CHWID", arymax, CHWID ) ;
790  //
791  for ( int i = 0 ; i < arymax ; i++) {
792    if ( readHeader( ARRY[i], sameEndian ) == -1 ) {
793      os << LogIO::WARN << "Error while reading data ARRY[" << i << "]." << LogIO::POST ;
794      return -1 ;
795    }
796  }
797  // DEBUG
798//   nro_debug_output( "ARRY", arymax, ARRY ) ;
799  //
800  for ( int i = 0 ; i < arymax ; i++) {
801    if ( readHeader( NFCAL[i], sameEndian ) == -1 ) {
802      os << LogIO::WARN << "Error while reading data NFCAL[" << i << "]." << LogIO::POST ;
803      return -1 ;
804    }
805  }
806  // DEBUG
807//   nro_debug_output( "NFCAL", arymax, NFCAL ) ;
808  //
809  for ( int i = 0 ; i < arymax ; i++) {
810    if ( readHeader( F0CAL[i], sameEndian ) == -1 ) {
811      os << LogIO::WARN << "Error while reading data F0CAL[" << i << "]." << LogIO::POST ;
812      return -1 ;
813    }
814  }
815  // DEBUG
816//   nro_debug_output( "F0CAL", arymax, F0CAL ) ;
817  //
818  for ( int i = 0 ; i < arymax ; i++) {
819    for ( int j = 0 ; j < 10 ; j++ ) {
820      if ( readHeader( FQCAL[i][j], sameEndian ) == -1 ) {
821        os << LogIO::WARN << "Error while reading data FQCAL[" << i << "][" << j << "]." << LogIO::POST ;
822        return -1 ;
823      }
824    }
825  }
826  // DEBUG
827//   nro_debug_output( "FQCAL", arymax, 10, FQCAL ) ;
828  // 
829  for ( int i = 0 ; i < arymax ; i++) {
830    for ( int j = 0 ; j < 10 ; j++ ) {
831      if ( readHeader( CHCAL[i][j], sameEndian ) == -1 ) {
832        os << LogIO::WARN << "Error while reading data CHCAL[" << i << "][" << j << "]." << LogIO::POST ;
833        return -1 ;
834      }
835    }
836  }
837  // DEBUG
838//   nro_debug_output( "CHCAL", arymax, 10, CHCAL ) ;
839  // 
840  for ( int i = 0 ; i < arymax ; i++) {
841    for ( int j = 0 ; j < 10 ; j++ ) {
842      if ( readHeader( CWCAL[i][j], sameEndian ) == -1 ) {
843        os << LogIO::WARN << "Error while reading data CWCAL[" << i << "][" << j << "]." << LogIO::POST ;
844        return -1 ;
845      }
846    }
847  }
848  // DEBUG
849//   nro_debug_output( "CWCAL", arymax, 10, CWCAL ) ;
850  // 
851  if ( readHeader( SCNLEN, sameEndian ) == -1 ) {
852    os << LogIO::WARN << "Error while reading data SCNLEN." << LogIO::POST ;
853    return -1 ;
854  }
855  // DEBUG
856  //cout << "SCNLEN = " << SCNLEN << endl ;
857  //
858  if ( readHeader( SBIND, sameEndian ) == -1 ) {
859    os << LogIO::WARN << "Error while reading data SBIND." << LogIO::POST ;
860    return -1 ;
861  }
862  // DEBUG
863  //cout << "SBIND = " << SBIND << endl ;
864  //
865  if ( readHeader( IBIT, sameEndian ) == -1 ) {
866    os << LogIO::WARN << "Error while reading data IBIT." << LogIO::POST ;
867    return -1 ;
868  }
869  // DEBUG
870  //cout << "IBIT = " << IBIT << endl ;
871  //
872  strcpy( c8, str8.c_str() ) ;
873  if ( readHeader( c8, 8 ) == -1 ) {
874    os << LogIO::WARN << "Error while reading data SITE." << LogIO::POST ;
875    return -1 ;
876  }
877  SITE = string( c8 ) ;
878  // DEBUG
879  //cout << "SITE = " << SITE << endl ;
880  //
881
882  //scanNum_ = NSCAN + 1 ; // includes ZERO scan
883  scanLen_ = SCNLEN ;
884  dataLen_ = scanLen_ - SCAN_HEADER_SIZE ;
885  scanNum_ = getScanNum();
886  rowNum_ = scanNum_ * ARYNM ;
887  chmax_ = (int) ( dataLen_ * 8 / IBIT ) ;
888  record_->LDATA = new char[dataLen_] ;
889
890  return 0 ;
891}
892
893void NRODataset::convertEndian( int &value )
894{
895  char volatile *first = reinterpret_cast<char volatile *>( &value ) ;
896  char volatile *last = first + sizeof( int ) ;
897  std::reverse( first, last ) ;
898}
899
900void NRODataset::convertEndian( float &value )
901{
902  char volatile *first = reinterpret_cast<char volatile *>( &value ) ;
903  char volatile *last = first + sizeof( float ) ;
904  std::reverse( first, last ) ;
905}
906
907void NRODataset::convertEndian( double &value )
908{
909  char volatile *first = reinterpret_cast<char volatile *>( &value ) ;
910  char volatile *last = first + sizeof( double ) ;
911  std::reverse( first, last ) ;
912}
913
914int NRODataset::readHeader( char *v, int size )
915{
916  if ( (int)( fread( v, 1, size, fp_ ) ) != size ) {
917    return -1 ;
918  }
919  return 0 ;
920}
921
922int NRODataset::readHeader( int &v, int b )
923{
924  if ( fread( &v, 1, sizeof(int), fp_ ) != sizeof(int) ) {
925    return -1 ;
926  }
927
928  if ( b == 0 )
929    convertEndian( v ) ;
930
931  return 0 ;
932}
933
934int NRODataset::readHeader( float &v, int b )
935{
936  if ( fread( &v, 1, sizeof(float), fp_ ) != sizeof(float) ) {
937    return -1 ;
938  }
939
940  if ( b == 0 )
941    convertEndian( v ) ;
942
943  return 0 ;
944}
945
946int NRODataset::readHeader( double &v, int b )
947{
948  if ( fread( &v, 1, sizeof(double), fp_ ) != sizeof(double) ) {
949    return -1 ;
950  }
951
952  if ( b == 0 )
953    convertEndian( v ) ;
954
955  return 0 ;
956}
957
958void NRODataset::convertEndian( NRODataRecord &r )
959{
960  convertEndian( r.ISCAN ) ;
961  convertEndian( r.DSCX ) ;
962  convertEndian( r.DSCY ) ;
963  convertEndian( r.SCX ) ;
964  convertEndian( r.SCY ) ;
965  convertEndian( r.PAZ ) ;
966  convertEndian( r.PEL ) ;
967  convertEndian( r.RAZ ) ;
968  convertEndian( r.REL ) ;
969  convertEndian( r.XX ) ;
970  convertEndian( r.YY ) ;
971  convertEndian( r.TEMP ) ;
972  convertEndian( r.PATM ) ;
973  convertEndian( r.PH2O ) ;
974  convertEndian( r.VWIND ) ;
975  convertEndian( r.DWIND ) ;
976  convertEndian( r.TAU ) ; 
977  convertEndian( r.TSYS ) ;
978  convertEndian( r.BATM ) ;
979  convertEndian( r.LINE ) ;
980  for ( int i = 0 ; i < 4 ; i++ )
981    convertEndian( r.IDMY1[i] ) ;
982  convertEndian( r.VRAD ) ;
983  convertEndian( r.FREQ0 ) ;
984  convertEndian( r.FQTRK ) ;
985  convertEndian( r.FQIF1 ) ;
986  convertEndian( r.ALCV ) ;
987  for ( int i = 0 ; i < 2 ; i++ )
988    for ( int j = 0 ; j < 2 ; j++ )
989      convertEndian( r.OFFCD[i][j] ) ;
990  convertEndian( r.IDMY0 ) ;
991  convertEndian( r.IDMY2 ) ;
992  convertEndian( r.DPFRQ ) ;
993  convertEndian( r.SFCTR ) ;
994  convertEndian( r.ADOFF ) ;
995}
996
997void NRODataset::releaseRecord()
998{
999  if ( !record_.null() ) {
1000    record_ = NULL ;
1001  }
1002  dataid_ = -1 ;
1003}
1004
1005// Get specified scan
1006NRODataRecord *NRODataset::getRecord( int i )
1007{
1008  // DEBUG
1009  //cout << "NRODataset::getRecord()  Start " << i << endl ;
1010  //
1011  if ( i < 0 || i >= rowNum_ ) {
1012    LogIO os( LogOrigin( "NRODataset", "getRecord()", WHERE ) ) ;
1013    //cerr << "NRODataset::getRecord()  data index out of range." << endl ;
1014    os << LogIO::SEVERE << "data index " << i << " out of range. return NULL." << LogIO::POST ;
1015    return NULL ;
1016  }
1017
1018  if ( i == dataid_ ) {
1019    return &(*record_) ;
1020  }
1021
1022  // DEBUG
1023  //cout << "NRODataset::getData()  Get new dataset" << endl ;
1024  //
1025  // read data
1026  int status = fillRecord( i ) ;
1027  if ( status == 0 ) {
1028    dataid_ = i ;
1029  }
1030  else {
1031    LogIO os( LogOrigin( "NRODataset", "getRecord()", WHERE ) ) ;
1032    //cerr << "NRODataset::getRecord()  error while reading data " << i << endl ;
1033    os << LogIO::SEVERE << "error while reading data " << i << ". return NULL." << LogIO::EXCEPTION ;
1034    dataid_ = -1 ;
1035    return NULL ;
1036  }
1037
1038  return &(*record_) ;
1039}
1040
1041int NRODataset::fillRecord( int i )
1042{
1043  int status = 0 ;
1044
1045  status = open() ;
1046  if ( status != 0 )
1047    return status ;
1048   
1049
1050  // fill NRODataset
1051  long offset = getDataSize() + scanLen_ * i ;
1052  // DEBUG
1053  //cout << "NRODataset::fillRecord()  offset (header) = " << offset << endl ;
1054  //cout << "NRODataset::fillRecord()  sizeof(NRODataRecord) = " << sizeof( NRODataRecord ) << " byte" << endl ;
1055  fseek( fp_, offset, SEEK_SET ) ;
1056  if ( (int)fread( &(*record_), 1, SCAN_HEADER_SIZE, fp_ ) != SCAN_HEADER_SIZE ) {
1057    //cerr << "Failed to read scan header: " << i << endl ;
1058    LogIO os( LogOrigin( "NRODataset", "fillRecord()", WHERE ) ) ;
1059    os << LogIO::SEVERE << "Failed to read scan header for " << i << "th row." << LogIO::POST ;
1060    return -1 ;
1061  }
1062  if ( (int)fread( &(*record_->LDATA), 1, dataLen_, fp_ ) != dataLen_ ) {
1063    //cerr << "Failed to read spectral data: " << i << endl ;
1064    LogIO os( LogOrigin( "NRODataset", "fillRecord()", WHERE ) ) ;
1065    os << LogIO::SEVERE << "Failed to read spectral data for " << i << "th row." << LogIO::POST ;
1066    return -1 ;
1067  }
1068
1069  if ( same_ == 0 ) {
1070    convertEndian( *record_ ) ;
1071  }
1072
1073  // DWIND unit conversion (deg -> rad)
1074  record_->DWIND = record_->DWIND * M_PI / 180.0 ;
1075
1076  return status ;
1077}
1078
1079// open
1080int NRODataset::open()
1081{
1082  int status = 0 ;
1083
1084  if ( fp_ == NULL ) {
1085    if ( (fp_ = fopen( filename_.c_str(), "rb" )) == NULL )
1086      status = -1 ;
1087    else
1088      status = 0 ;
1089  }
1090
1091  return status ;
1092}
1093
1094// close
1095void NRODataset::close()
1096{
1097  // DEBUG
1098  //cout << "NRODataset::close()  close file" << endl ;
1099  //
1100  if ( fp_ != NULL )
1101    fclose( fp_ ) ;
1102  fp_ = NULL ;
1103}
1104
1105// get spectrum
1106vector< vector<double> > NRODataset::getSpectrum()
1107{
1108  vector< vector<double> > spec(rowNum_);
1109
1110  for ( int i = 0 ; i < rowNum_ ; i++ ) {
1111    spec[i] = getSpectrum( i ) ;
1112  }
1113
1114  return spec ;
1115}
1116
1117vector<double> NRODataset::getSpectrum( int i )
1118{
1119  // DEBUG
1120  //cout << "NRODataset::getSpectrum() start process (" << i << ")" << endl ;
1121  //
1122  // size of spectrum is not chmax_ but dataset_->getNCH() after binding
1123  const int nchan = NUMCH ;
1124  vector<double> spec( chmax_ ) ;  // spectrum "before" binding
1125  // DEBUG
1126  //cout << "NRODataset::getSpectrum()  nchan = " << nchan << " chmax_ = " << chmax_ << endl ;
1127  //
1128
1129  const NRODataRecord *record = getRecord( i ) ;
1130
1131  const int bit = IBIT ;   // fixed to 12 bit
1132  double scale = record->SFCTR ;
1133  // DEBUG
1134  //cout << "NRODataset::getSpectrum()  scale = " << scale << endl ;
1135  //
1136  double offset = record->ADOFF ;
1137  // DEBUG
1138  //cout << "NRODataset::getSpectrum()  offset = " << offset << endl ;
1139  //
1140  if ( ( scale == 0.0 ) && ( offset == 0.0 ) ) {
1141    //cerr << "NRODataset::getSpectrum()  zero spectrum (" << i << ")" << endl ;
1142    LogIO os( LogOrigin("NRODataset","getSpectrum",WHERE) ) ;
1143    os << LogIO::WARN << "zero spectrum for row " << i << LogIO::POST ;
1144    if ( spec.size() != (unsigned int)nchan )
1145      spec.resize( nchan ) ;
1146    for ( vector<double>::iterator i = spec.begin() ;
1147          i != spec.end() ; i++ )
1148      *i = 0.0 ;
1149    return spec ;
1150  }
1151  unsigned char *cdata = (unsigned char *)&(*record->LDATA) ;
1152  vector<double> mscale = MLTSCF ;
1153  double dscale = mscale[getIndex( i )] ;
1154  int cbind = CHBIND ;
1155  int chmin = CHMIN ;
1156
1157  // char -> int -> double
1158  vector<double>::iterator iter = spec.begin() ;
1159
1160  static const int shift_right[] = {
1161    4, 0
1162  };
1163  static const int start_pos[] = {
1164    0, 1
1165  };
1166  static const int incr[] = {
1167    0, 3
1168  };
1169  int j = 0 ;
1170  for ( int i = 0 ; i < chmax_ ; i++ ) {
1171    // char -> int
1172    int ivalue = 0 ;
1173    if ( bit == 12 ) {  // 12 bit qunatization
1174      const int ialt = i & 1 ;
1175      const int idx = j + start_pos[ialt];
1176      const unsigned tmp = unsigned(cdata[idx]) << 8 | cdata[idx + 1];
1177      ivalue = int((tmp >> shift_right[ialt]) & 0xFFF);
1178      j += incr[ialt];
1179    }
1180
1181    if ( ( ivalue < 0 ) || ( ivalue > 4096 ) ) {
1182      //cerr << "NRODataset::getSpectrum()  ispec[" << i << "] is out of range" << endl ;
1183      LogIO os( LogOrigin( "NRODataset", "getSpectrum", WHERE ) ) ;
1184      os << LogIO::SEVERE << "ivalue for row " << i << " is out of range" << LogIO::EXCEPTION ;
1185      if ( spec.size() != (unsigned int)nchan )
1186        spec.resize( nchan ) ;
1187      for ( vector<double>::iterator i = spec.begin() ;
1188            i != spec.end() ; i++ )
1189        *i = 0.0 ;
1190      return spec ;
1191    }
1192    // DEBUG
1193    //cout << "NRODataset::getSpectrum()  ispec[" << i << "] = " << ispec[i] << endl ;
1194    //
1195
1196    // int -> double
1197    *iter = (double)( ivalue * scale + offset ) * dscale ;
1198    // DEBUG
1199    //cout << "NRODataset::getSpectrum()  spec[" << i << "] = " << *iter << endl ;
1200    //
1201    iter++ ;
1202  }
1203
1204  // channel binding if necessary
1205  if ( cbind != 1 ) {
1206    iter = spec.begin() ;
1207    advance( iter, chmin ) ;
1208    vector<double>::iterator iter2 = spec.begin() ;
1209    for ( int i = 0 ; i < nchan ; i++ ) {
1210      double sum0 = 0 ;
1211      double sum1 = 0 ;
1212      for ( int j = 0 ; j < cbind ; j++ ) {
1213        sum0 += *iter ;
1214        sum1 += 1.0 ;
1215        iter++ ;
1216      }
1217      *iter2 = sum0 / sum1 ;
1218      iter2++ ;
1219      // DEBUG
1220      //cout << "NRODataset::getSpectrum()  bspec[" << i << "] = " << bspec[i] << endl ;
1221      //
1222    }
1223    spec.resize( nchan ) ;
1224  }
1225
1226  // DEBUG
1227  //cout << "NRODataset::getSpectrum() end process" << endl ;
1228  //
1229
1230  return spec ;
1231}
1232
1233int NRODataset::getIndex( int irow )
1234{
1235  // DEBUG
1236  //cout << "NRODataset::getIndex()  start" << endl ;
1237  //
1238  const NRODataRecord *record = getRecord( irow ) ;
1239
1240  const string str = record->ARRYT ;
1241  // DEBUG
1242  //cout << "NRODataset::getIndex()  str = " << str << endl ;
1243  //
1244  int index = (int)getArrayId(str);
1245  // DEBUG
1246  //cout << "NRODataset::getIndex()  irow = " << irow << "str = " << str << " index = " << index << endl ;
1247  //
1248
1249  // DEBUG
1250  //cout << "NRODataset::getIndex()  end" << endl ;
1251  //
1252  return index ;
1253}
1254
1255int NRODataset::getPolarizationNum()
1256{
1257  // DEBUG
1258  //cout << "NRODataset::getPolarizationNum()  start process" << endl ;
1259  //
1260  int npol = 1;
1261  Regex reRx2("(.*V|H20ch2)$");
1262  Regex reRx1("(.*H|H20ch1)$");
1263  Bool match1 = false;
1264  Bool match2 = false;
1265  for (int i = 0; i < arrayMax(); i++) {
1266    //cout << "RX[" << i << "]=" << RX[i] << endl;
1267    if (!match1) {
1268      match1 = (reRx1.match(RX[i].c_str(), RX[i].size()) != String::npos);
1269    }
1270    if (!match2) {
1271      match2 = (reRx2.match(RX[i].c_str(), RX[i].size()) != String::npos);
1272    }
1273  }
1274
1275  if (match1 && match2)
1276    npol = 2; 
1277
1278  //cout << "npol = " << npol << endl;
1279
1280  // DEBUG
1281  //cout << "NRODataset::getPolarizationNum()  end process" << endl ;
1282  //
1283
1284  return npol ;
1285}
1286
1287vector<double> NRODataset::getStartIntTime()
1288{
1289  vector<double> times ;
1290  for ( int i = 0 ; i < rowNum_ ; i++ ) {
1291    times.push_back( getStartIntTime( i ) ) ;
1292  }
1293  return times ;
1294}
1295
1296double NRODataset::getStartIntTime( int i )
1297{
1298  const NRODataRecord *record = getRecord( i ) ;
1299
1300  const char *t = record->LAVST ;
1301  return getMJD( t ) ;
1302}
1303
1304double NRODataset::getMJD( const char *time )
1305{
1306  // TODO: should be checked which time zone the time depends on
1307  // 2008/11/14 Takeshi Nakazato
1308  string strStartTime( time ) ;
1309  string strYear = strStartTime.substr( 0, 4 ) ;
1310  string strMonth = strStartTime.substr( 4, 2 ) ;
1311  string strDay = strStartTime.substr( 6, 2 ) ;
1312  string strHour = strStartTime.substr( 8, 2 ) ;
1313  string strMinute = strStartTime.substr( 10, 2 ) ;
1314  string strSecond = strStartTime.substr( 12, strStartTime.size() - 12 ) ;
1315  unsigned int year = atoi( strYear.c_str() ) ;
1316  unsigned int month = atoi( strMonth.c_str() ) ;
1317  unsigned int day = atoi( strDay.c_str() ) ;
1318  unsigned int hour = atoi( strHour.c_str() ) ;
1319  unsigned int minute = atoi( strMinute.c_str() ) ;
1320  double second = atof( strSecond.c_str() ) ;
1321  Time t( year, month, day, hour, minute, second ) ;
1322
1323  return t.modifiedJulianDay() ;
1324}
1325
1326double NRODataset::getScanTime( int i )
1327{
1328  double startTime = getStartIntTime( i ) ;
1329  double interval = getIPTIM() / 86400.0 ; // [sec]->[day]
1330  return startTime+0.5*interval ;
1331}
1332
1333vector<bool> NRODataset::getIFs()
1334{
1335  vector<bool> v ;
1336  vector< vector<double> > fref ;
1337  vector< vector<double> > chcal = CHCAL ;
1338  vector<double> f0cal = F0CAL ;
1339  vector<double> beres = BERES ;
1340  for ( int i = 0 ; i < rowNum_ ; i++ ) {
1341    vector<double> f( 4, 0 ) ;
1342    uInt index = getIndex( i ) ;
1343    f[0] = chcal[index][0] ;
1344    f[1] = f0cal[index] ;
1345    f[2] = beres[index] ;
1346    if ( f[0] != 0. ) {
1347      f[1] = f[1] - f[0] * f[2] ;
1348    }
1349    const NRODataRecord *record = getRecord( i ) ;
1350    f[3] = record->FREQ0 ;
1351    if ( v.size() == 0 ) {
1352      v.push_back( True ) ;
1353      fref.push_back( f ) ;
1354    }
1355    else {
1356      bool b = true ;
1357      int fsize = fref.size() ;
1358      for ( int j = 0 ; j < fsize ; j++ ) {
1359        if ( fref[j][1] == f[1] && fref[j][2] == f[2] && fref[j][3] == f[3] ) {
1360          b = false ;
1361        }
1362      }
1363      if ( b ) {
1364        v.push_back( True ) ;
1365        fref.push_back( f ) ;
1366      }
1367    }
1368  }
1369
1370
1371  // DEBUG
1372  //cout << "NRODataset::getIFs()   number of IF is " << v.size() << endl ;
1373  //
1374
1375  return v ;
1376}
1377
1378vector<double> NRODataset::getFrequencies( int i )
1379{
1380  // return value
1381  // v[0]  reference channel
1382  // v[1]  reference frequency
1383  // v[2]  frequency increment
1384  vector<double> v( 3, 0.0 ) ;
1385
1386  const NRODataRecord *record = getRecord( i ) ;
1387  string arryt = string( record->ARRYT ) ;
1388  uInt ib = getArrayId( arryt ) ;
1389  string rxname = getRX()[0] ;
1390  string key = arryt ;
1391  if ( rxname.find("MULT2") != string::npos )
1392    key = "BEARS" ;
1393
1394  if ( frec_.isDefined( key ) ) {
1395    // frequency for the array is already calculated
1396    Vector<Double> f =  frec_.asArrayDouble( key ) ;
1397    Double *f_p = f.data() ;
1398    for ( int i = 0 ; i < 3 ; i++ )
1399      v[i] = (double)(f_p[i]) ;
1400    return v ;
1401  }
1402
1403  //int ia = -1 ;
1404  bool isAOS = false ;
1405  //cout << "NRODataset::getFrequencies()  record->ARRYT=" << record->ARRYT << endl ;
1406  //cout << "NRODataset::getFrequencies()  ib = " << ib << endl ;
1407
1408  if ( arryt[0] == 'W' || arryt[0] == 'U' || arryt[0] == 'H' )
1409    isAOS = true ;
1410
1411  Bool isUSB ;
1412  if ( record->FQIF1 > 0 )
1413    isUSB = True ;  // USB
1414  else
1415    isUSB = False ;  // LSB
1416
1417  int ivdef = -1 ;
1418  if ( (getVDEF()).compare( 0, 3, "RAD" ) == 0 )
1419    ivdef = 0 ;
1420  else if ( (getVDEF()).compare( 0, 3, "OPT" ) == 0 )
1421    ivdef = 1 ;
1422  // DEBUG
1423  //cout << "NRODataset::getFrequencies() ivdef = " << ivdef << endl ;
1424  //
1425  double vel = getURVEL() + record->VRAD ;
1426  double cvel = 2.99792458e8 ; // speed of light [m/s]
1427  double fq0 = record->FREQ0 ;
1428  //double fq0 = record->FQTRK ;
1429
1430  int ncal = getNFCAL()[ib] ;
1431  double cw = 0.0 ;
1432  vector<double> fqcal = getFQCAL()[ib] ;
1433  vector<double> chcal = getCHCAL()[ib] ;
1434  double f0cal = getF0CAL()[ib] ;
1435  Vector<Double> freqs( ncal, fq0-f0cal ) ;
1436
1437  double factor = vel / cvel ;
1438  if ( ivdef == 0 )
1439    factor = 1.0 / ( 1.0 - factor ) ;
1440  for ( int ii = 0 ; ii < ncal ; ii++ ) {
1441    freqs[ii] += fqcal[ii] ;
1442    if ( ivdef == 0 ) {
1443      freqs[ii] = freqs[ii] * factor + record->FQTRK * ( 1.0 - factor ) ;
1444    }
1445    else if ( ivdef == 1 ) {
1446      freqs[ii] = freqs[ii] * ( 1.0 + factor ) - record->FQTRK * factor ;
1447    }
1448
1449    //ofstream ofs("freqs.txt",ios::out|ios::app) ;
1450    //ofs << setprecision(16) ;
1451    //ofs << i << " " << record->ARRYT << " " << chcal[ii] << " " << freqs[ii] << " " << record->ISCAN << " " << fqcal[ii] << " " << f0cal << " " << record->FQTRK << " " << vel << endl ;
1452    //ofs.close() ;
1453
1454  }
1455
1456  if ( isAOS ) {
1457    // regridding
1458    while ( ncal < (int)chcal.size() ) {
1459      chcal.pop_back() ;
1460    }
1461    Vector<Double> xin( chcal ) ;
1462    Vector<Double> yin( freqs ) ;
1463    int nchan = getNUMCH() ;
1464    Vector<Double> xout( nchan ) ;
1465    indgen( xout ) ;
1466    Vector<Double> yout ;
1467    InterpolateArray1D<Double, Double>::interpolate( yout, xout, xin, yin, InterpolateArray1D<Double,Double>::cubic ) ;
1468    Double bw = abs( yout[nchan-1] - yout[0] ) ;
1469    bw += 0.5 * abs( yout[nchan-1] - yout[nchan-2] + yout[1] - yout[0] ) ;
1470    Double dz = bw / (Double) nchan ;
1471    if ( yout[0] > yout[1] )
1472      dz = - dz ;
1473    v[0] = 0 ;
1474    v[1] = yout[0] ;
1475    v[2] = dz ;
1476  }
1477  else {
1478
1479    cw = ( freqs[1] - freqs[0] )
1480      / ( chcal[1] - chcal[0] ) ;   
1481
1482    if ( isUSB ) {
1483      // channel frequency inversion
1484      cw *= -1.0 ;
1485      Double tmp = freqs[1] ;
1486      freqs[1] = freqs[0] ;
1487      freqs[0] = tmp ;
1488    }
1489   
1490    v[0] = chcal[0] - 1 ; // 0-base
1491    v[1] = freqs[0] ;
1492    v[2] = cw ;
1493  }
1494
1495  if ( refFreq_[ib] == 0.0 )
1496    refFreq_[ib] = v[1] ;
1497
1498  // register frequency setting to Record
1499  Vector<Double> f( v ) ;
1500  frec_.define( key, f ) ;
1501
1502  return v ;
1503}
1504
1505uInt NRODataset::getArrayId( string type )
1506{
1507  string sbeamno = type.substr( 1, type.size()-1 ) ;
1508  uInt ib = atoi( sbeamno.c_str() ) - 1 ;
1509  return ib ;
1510}
1511
1512uInt NRODataset::getSortedArrayId( string type )
1513{
1514  uInt index = 0;
1515  while (arrayNames_[index] != type && index < (uInt)ARYNM)
1516    ++index;
1517  return index;
1518}
1519
1520void NRODataset::show()
1521{
1522  LogIO os( LogOrigin( "NRODataset", "show()", WHERE ) ) ;
1523
1524  os << LogIO::NORMAL << "------------------------------------------------------------" << endl ;
1525  os << LogIO::NORMAL << "Number of scan = " << scanNum_ << endl ;
1526  os << LogIO::NORMAL << "Number of data record = " << rowNum_ << endl ;
1527  os << LogIO::NORMAL << "Length of data record = " << scanLen_ << " bytes" << endl ;
1528  os << LogIO::NORMAL << "Allocated memory for spectral data = " << dataLen_ << " bytes" << endl ;
1529  os << LogIO::NORMAL << "Max number of channel = " << chmax_ << endl ;
1530  os << LogIO::NORMAL << "------------------------------------------------------------" << endl ;
1531  os.post() ;
1532
1533}
1534
1535double NRODataset::toLSR( double v, double t, double x, double y )
1536{
1537  double vlsr ;
1538
1539  // get epoch
1540  double tcent = t + 0.5*getIPTIM()/86400.0 ;
1541  MEpoch me( Quantity( tcent, "d" ), MEpoch::UTC ) ;
1542
1543  // get antenna position
1544  MPosition mp ;
1545  if ( SITE.find( "45" ) != string::npos ) {
1546    // 45m telescope
1547    Double posx = -3.8710235e6 ;
1548    Double posy = 3.4281068e6 ;
1549    Double posz = 3.7240395e6 ;
1550    mp = MPosition( MVPosition( posx, posy, posz ),
1551                    MPosition::ITRF ) ;
1552  }
1553  else {
1554    // ASTE
1555    Vector<Double> pos( 2 ) ;
1556    pos[0] = -67.7031 ;
1557    pos[1] = -22.9717 ;
1558    Double sitealt = 4800.0 ;
1559    mp = MPosition( MVPosition( Quantity( sitealt, "m" ),
1560                                Quantum< Vector<Double> >( pos, "deg" ) ),
1561                    MPosition::WGS84 ) ;
1562  }
1563
1564  // get direction
1565  MDirection md ;
1566  if ( SCNCD == 0 ) {
1567    // RADEC
1568    if ( EPOCH == "B1950" ) {
1569      md = MDirection( Quantity( Double(x), "rad" ), Quantity( Double(y), "rad" ),
1570                       MDirection::B1950 ) ;
1571    }
1572    else {
1573      md = MDirection( Quantity( Double(x), "rad" ), Quantity( Double(y), "rad" ),
1574                       MDirection::J2000 ) ;
1575    }
1576  }
1577  else if ( SCNCD == 1 ) {
1578    // LB
1579    md = MDirection( Quantity( Double(x), "rad" ), Quantity( Double(y), "rad" ),
1580                     MDirection::GALACTIC ) ;
1581  }
1582  else {
1583    // AZEL
1584    md = MDirection( Quantity( Double(x), "rad" ), Quantity( Double(y), "rad" ),
1585                     MDirection::AZEL ) ;
1586  }
1587   
1588  // to LSR
1589  MeasFrame mf( me, mp, md ) ;
1590  MFrequency::Convert tolsr( MFrequency::TOPO, MFrequency::Ref( MFrequency::LSRK, mf ) ) ;
1591  vlsr = (double)(tolsr( Double(v) ).get( "Hz" ).getValue()) ;
1592
1593  return vlsr ;
1594}
1595
1596uInt NRODataset::getPolNo( int i )
1597{
1598  int idx = getIndex( i ) ;
1599//   cout << "HORN[" << idx << "]=" << HORN[idx]
1600//        << ", RX[" << idx << "]=" << RX[idx] << endl ;
1601  return polNoFromRX( RX[idx] ) ;
1602}
1603
1604uInt NRODataset::polNoFromRX( const string &rx )
1605{
1606  uInt polno = 0 ;
1607  // 2013/01/23 TN
1608  // In NRO 45m telescope, naming convension for dual-polarization
1609  // receiver is as follows:
1610  //
1611  //    xxxH for horizontal component,
1612  //    xxxV for vertical component.
1613  //
1614  // Exception is H20ch1/ch2.
1615  // Here, POLNO is assigned as follows:
1616  //
1617  //    POLNO=0: xxxH or H20ch1
1618  //          1: xxxV or H20ch2
1619  //
1620  // For others, POLNO is always 0.
1621  String rxString(rx);
1622  rxString.trim();
1623  //cout << "rx='" << rxString << "' (size " << rxString.size() << ")" << endl;
1624  Regex reRx("(.*V|H20ch2)$");
1625  if (reRx.match(rxString.c_str(), rxString.size()) != String::npos) {
1626    //cout << "match!" << endl;
1627    polno = 1;
1628  }
1629  return polno ;
1630}
1631
1632void NRODataset::initArray()
1633{
1634  if (ARYNM <= 0)
1635    throw AipsError("ARYNM must be greater than zero.");
1636
1637  int numArray = 0;
1638  arrayNames_.resize(ARYNM);
1639  for (int irow = 0; numArray < ARYNM && irow < rowNum_; irow++) {
1640    //cout << "irow " << irow << endl;
1641    const NRODataRecord *record = getRecord( irow ) ;
1642    const string str = record->ARRYT ;
1643    if (find(arrayNames_.begin(), arrayNames_.end(), str) == arrayNames_.end()) {
1644      arrayNames_[numArray] = str;
1645      //cout << "arrayNames_[" << numArray << "]=" << str << endl;
1646      ++numArray;
1647    }
1648  }
1649  //cout << "numArray=" << numArray << endl;
1650}
1651
1652int NRODataset::getScanNum()
1653{
1654  long offset = getDataSize() + scanLen_ * NSCAN * ARYNM ;
1655  fseek( fp_, offset, SEEK_SET ) ;
1656  // try to read data
1657  fgetc( fp_ ) ;
1658  int eof = feof( fp_ ) ;
1659  //cout << "eof=" << eof << endl;
1660  // reset file pointer
1661  fseek( fp_, 0, SEEK_SET ) ;
1662  return NSCAN + (eof > 0 ? 0 : 1) ;
1663}
Note: See TracBrowser for help on using the repository browser.