source: branches/newfiller/src/PKSFiller.cpp @ 1795

Last change on this file since 1795 was 1795, checked in by Malte Marquarding, 14 years ago

First Working version of the PKSFiller

File size: 10.0 KB
Line 
1//
2// C++ Implementation: PKSFiller
3//
4// Description:
5//
6//
7// Author: Malte Marquarding <asap@atnf.csiro.au>, (C) 2010
8//
9// Copyright: See COPYING file that comes with this distribution
10//
11//
12#include <casa/iostream.h>
13#include <casa/iomanip.h>
14
15#include <casa/Exceptions.h>
16#include <casa/OS/Path.h>
17#include <casa/OS/File.h>
18#include <casa/Quanta/Unit.h>
19#include <casa/Arrays/ArrayMath.h>
20#include <casa/Arrays/ArrayLogical.h>
21#include <casa/Utilities/Regex.h>
22
23
24#include <measures/Measures/MDirection.h>
25#include <measures/Measures/MeasConvert.h>
26
27#include <atnf/PKSIO/PKSrecord.h>
28#include <atnf/PKSIO/PKSreader.h>
29
30#ifdef HAS_ALMA
31 #include <casa/System/ProgressMeter.h>
32#endif
33#include <casa/Logging/LogIO.h>
34
35#include <time.h>
36
37#include "STDefs.h"
38#include "STAttr.h"
39
40#include "PKSFiller.h"
41#include "STHeader.h"
42
43using namespace casa;
44
45namespace asap {
46
47
48PKSFiller::PKSFiller( CountedPtr< Scantable > stbl ) :
49  FillerBase(stbl),
50  reader_(0),
51  header_(0)
52{
53  setReferenceRegex(".*(e|w|_R)$");
54}
55
56PKSFiller::~PKSFiller()
57{
58  close();
59}
60
61bool PKSFiller::open( const std::string& filename)
62{
63  /*
64  if (table_.null())  {
65    table_ = new Scantable();
66  }
67  */
68  if (reader_)  { delete reader_; reader_ = 0; }
69  Bool haveBase, haveSpectra;
70
71  String inName(filename);
72  Path path(inName);
73  inName = path.expandedName();
74
75  File file(inName);
76  filename_ = inName;
77
78  // Create reader and fill in values for arguments
79  String format;
80  Vector<Bool> beams, ifs;
81  Vector<uInt> nchans,npols;
82
83  String antenna("");
84  if ( (reader_ = getPKSreader(inName, antenna, 0, 0, format, beams, ifs,
85                              nchans, npols, haveXPol_,haveBase, haveSpectra
86                              )) == 0 )  {
87    return False;
88  }
89
90  if (!haveSpectra) {
91    delete reader_;
92    reader_ = 0;
93    throw(AipsError("No spectral data in file."));
94  }
95  LogIO os;
96  nBeam_ = beams.nelements();
97  nIF_ = ifs.nelements();
98  // Get basic parameters.
99  if ( anyEQ(haveXPol_, True) ) {
100    os <<  "Cross polarization present" << LogIO::POST;
101    for (uInt i=0; i< npols.nelements();++i) {
102      if (npols[i] < 3) npols[i] += 2;// Convert Complex -> 2 Floats
103    }
104  }
105  if (header_) delete header_;
106  header_ = new STHeader();
107  header_->nchan = max(nchans);
108  header_->npol = max(npols);
109  header_->nbeam = nBeam_;
110
111  Int status = reader_->getHeader(header_->observer, header_->project,
112                                  header_->antennaname, header_->antennaposition,
113                                  header_->obstype,
114                                  header_->fluxunit,
115                                  header_->equinox,
116                                  header_->freqref,
117                                  header_->utc, header_->reffreq,
118                                  header_->bandwidth);
119
120  if (status) {
121    delete reader_;
122    reader_ = 0;
123    delete header_;
124    header_ = 0;
125    throw(AipsError("Failed to get header."));
126  }
127  if ((header_->obstype).matches("*SW*")) {
128    // need robust way here - probably read ahead of next timestamp
129    os << "Header indicates frequency switched observation.\n"
130       << "setting # of IFs = 1 " << LogIO::POST;
131
132    nIF_ = 1;
133    header_->obstype = String("fswitch");
134  }
135  // Determine Telescope and set brightness unit
136
137  Bool throwIt = False;
138  Instrument inst = STAttr::convertInstrument(header_->antennaname, throwIt);
139
140  if (inst==ATMOPRA || inst==TIDBINBILLA) {
141    header_->fluxunit = "K";
142  } else {
143    // downcase for use with Quanta
144    if (header_->fluxunit == "JY") {
145      header_->fluxunit = "Jy";
146    }
147  }
148  STAttr stattr;
149  header_->poltype = stattr.feedPolType(inst);
150  header_->nif = nIF_;
151  header_->epoch = "UTC";
152  // *** header_->frequnit = "Hz"
153  // Apply selection criteria.
154  Vector<Int> ref;
155
156  Vector<Int> start(nIF_, 1);
157  Vector<Int> end(nIF_, 0);
158  Bool getPt = False;
159  reader_->select(beams, ifs, start, end, ref, True, haveXPol_[0], False, getPt);
160  setHeader(*header_);
161  //For MS, add the location of POINTING of the input MS so one get
162  //pointing data from there, if necessary.
163  //Also find nrow in MS
164  nInDataRow = 0;
165  if (format == "MS2") {
166    Path datapath(inName);
167    String ptTabPath = datapath.absoluteName();
168    Table inMS(ptTabPath);
169    nInDataRow = inMS.nrow();
170    ptTabPath.append("/POINTING");
171    table_->table().rwKeywordSet().define("POINTING", ptTabPath);
172    if ((header_->antennaname).matches("GBT")) {
173      String GOTabPath = datapath.absoluteName();
174      GOTabPath.append("/GBT_GO");
175      table_->table().rwKeywordSet().define("GBT_GO", GOTabPath);
176    }
177  }
178  String freqFrame = header_->freqref;
179  //translate frequency reference frame back to
180  //MS style (as PKSMS2reader converts the original frame
181  //in FITS standard style)
182  if (freqFrame == "TOPOCENT") {
183    freqFrame = "TOPO";
184  } else if (freqFrame == "GEOCENER") {
185    freqFrame = "GEO";
186  } else if (freqFrame == "BARYCENT") {
187    freqFrame = "BARY";
188  } else if (freqFrame == "GALACTOC") {
189    freqFrame = "GALACTO";
190  } else if (freqFrame == "LOCALGRP") {
191    freqFrame = "LGROUP";
192  } else if (freqFrame == "CMBDIPOL") {
193    freqFrame = "CMB";
194  } else if (freqFrame == "SOURCE") {
195    freqFrame = "REST";
196  }
197  // set both "FRAME" and "BASEFRAME"
198  table_->frequencies().setFrame(freqFrame, false);
199  table_->frequencies().setFrame(freqFrame,true);
200  //table_->focus().setParallactify(true);
201
202  return true;
203}
204
205void PKSFiller::close( )
206{
207  if (reader_ != 0) {
208    delete reader_;
209    reader_=0;
210  }
211
212  if (header_ != 0) {
213    delete header_;
214    header_=0;
215  }
216  table_ = 0;
217}
218
219void PKSFiller::fill( )
220{
221  int status = 0;
222
223/**
224  Int    beamNo, IFno, refBeam, scanNo, cycleNo;
225  Float  azimuth, elevation, focusAxi, focusRot, focusTan,
226    humidity, parAngle, pressure, temperature, windAz, windSpeed;
227  Double bandwidth, freqInc, interval, mjd, refFreq, srcVel;
228  String          fieldName, srcName, tcalTime, obsType;
229  Vector<Float>   calFctr, sigma, tcal, tsys;
230  Matrix<Float>   baseLin, baseSub;
231  Vector<Double>  direction(2), scanRate(2), srcDir(2), srcPM(2), restFreq(1);
232  Matrix<Float>   spectra;
233  Matrix<uChar>   flagtra;
234  Complex         xCalFctr;
235  Vector<Complex> xPol;
236**/
237
238  Double min = 0.0;
239  Double max = nInDataRow;
240#ifdef HAS_ALMA
241  ProgressMeter fillpm(min, max, "Data importing progress");
242#endif
243  PKSrecord pksrec;
244  pksrec.srcType=-1;
245  int n = 0;
246  bool isGBTFITS = false ;
247  if ((header_->antennaname.find( "GBT" ) != String::npos)
248       && File(filename_).isRegular()) {
249    FILE *fp = fopen( filename_.c_str(), "r" ) ;
250    fseek( fp, 640, SEEK_SET ) ;
251    char buf[81] ;
252    fread( buf, 80, 1, fp ) ;
253    buf[80] = '\0' ;
254    if ( strstr( buf, "NRAO_GBT" ) != NULL ) {
255      isGBTFITS = true ;
256    }
257    fclose( fp ) ;
258  }
259
260  while ( status == 0 ) {
261
262    status = reader_->read(pksrec);
263    if ( status != 0 ) break;
264    n += 1;
265    Regex filterrx(".*[SL|PA]$");
266    Regex obsrx("^AT.+");
267    if ( header_->antennaname.matches(obsrx) &&
268         pksrec.obsType.matches(filterrx)) {
269        //cerr << "ignoring paddle scan" << endl;
270        continue;
271    }
272
273    Vector<Double> sratedbl(pksrec.scanRate.nelements());
274    convertArray(sratedbl, pksrec.scanRate);
275    //setScanRate(sratedbl);
276
277    Regex rx(getReferenceRegex());
278    Regex rx2("_S$");
279    Int match = pksrec.srcName.matches(rx);
280    std::string srcname;
281    if (match) {
282      srcname = pksrec.srcName;
283    } else {
284      srcname = pksrec.srcName.before(rx2);
285    }
286    Int srctype = match;
287    if ( pksrec.srcType != -1 ) {
288      srctype = pksrec.srcType ;
289    }
290    setTime(pksrec.mjd, pksrec.interval);
291    setSource(srcname, srctype, pksrec.fieldName,
292              pksrec.srcDir, pksrec.srcPM, pksrec.srcVel);
293
294    if (nBeam_ > 1 ) {
295      setReferenceBeam(pksrec.refBeam-1);
296    }
297    setFrequency(Double(header_->nchan/2), pksrec.refFreq, pksrec.freqInc);
298    /*
299    if ( pksrec.nchan == 1 ) {
300       setFrequency(0.0, pksrec.refFreq, pksrec.freqInc)
301    }
302    else {
303      setFrequency(Double(pksrec.nchan/2), pksrec.refFreq, pksrec.freqInc);
304    }
305    */
306    setMolecule(pksrec.restFreq);
307    setTcal(pksrec.tcalTime, pksrec.tcal);
308    setWeather(pksrec.temperature, pksrec.pressure,
309                                    pksrec.humidity, pksrec.windSpeed,
310                                    pksrec.windAz);
311    setFocus(pksrec.parAngle, pksrec.focusAxi, pksrec.focusTan,
312             pksrec.focusRot);
313    setDirection(pksrec.direction, pksrec.azimuth, pksrec.elevation);
314
315    // Turn the (nchan,npol) matrix and possible complex xPol vector
316    // into 2-4 rows in the scantable
317    Vector<Float> tsysvec(1);
318    // Why is spectra.ncolumn() == 3 for haveXPol_ == True
319    uInt npol = (pksrec.spectra.ncolumn()==1 ? 1: 2);
320    uInt polno =0;
321    for ( uInt i=0; i< npol; ++i ) {
322      tsysvec = pksrec.tsys(i);
323      if (isGBTFITS) {
324        polno = pksrec.polNo ;
325      } else {
326        polno = i;
327      }
328      setIndex(pksrec.scanNo-1, pksrec.cycleNo-1, pksrec.IFno-1,
329               pksrec.beamNo-1, polno);
330      setSpectrum(pksrec.spectra.column(i), pksrec.flagged.column(i), tsysvec);
331      commitRow();
332    }
333    /*
334    RecordFieldPtr< uInt > flagrowCol(rec, "FLAGROW");
335    *flagrowCol = pksrec.flagrow;
336    */
337    if ( haveXPol_[0] ) {
338      // no tsys given for xpol, so emulate it
339      tsysvec = sqrt(pksrec.tsys[0]*pksrec.tsys[1]);
340      // add real part of cross pol
341      polno = 2;
342      Vector<Float> r(real(pksrec.xPol));
343      // make up flags from linears
344      /// @fixme this has to be a bitwise or of both pols
345      /// pksrec.flagged.column(0) | pksrec.flagged.column(1);
346
347      setIndex(pksrec.scanNo-1, pksrec.cycleNo-1, pksrec.IFno-1,
348               pksrec.beamNo-1, polno);
349      setSpectrum(r, pksrec.flagged.column(0), tsysvec);
350      commitRow();
351
352      // ad imaginary part of cross pol
353      polno = 3;
354      Vector<Float> im(imag(pksrec.xPol));
355      setIndex(pksrec.scanNo-1, pksrec.cycleNo-1, pksrec.IFno-1,
356               pksrec.beamNo-1, polno);
357      setSpectrum(im, pksrec.flagged.column(0), tsysvec);
358      commitRow();
359    }
360#ifdef HAS_ALMA
361    fillpm._update(n);
362#endif
363  }
364  if (status > 0) {
365    close();
366    throw(AipsError("Reading error occured, data possibly corrupted."));
367  }
368#ifdef HAS_ALMA
369  fillpm.done();
370#endif
371}
372
373}//namespace asap
Note: See TracBrowser for help on using the repository browser.