source: branches/alma/src/STFiller.cpp @ 1446

Last change on this file since 1446 was 1446, checked in by TakTsutsumi, 16 years ago

Merged recent updates (since 2007) from nrao-asap

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.8 KB
RevLine 
[805]1//
2// C++ Implementation: STFiller
3//
4// Description:
5//
6//
7// Author: Malte Marquarding <asap@atnf.csiro.au>, (C) 2006
8//
9// Copyright: See COPYING file that comes with this distribution
10//
11//
[404]12#include <casa/iostream.h>
13#include <casa/iomanip.h>
14
[125]15#include <casa/Exceptions.h>
[284]16#include <casa/OS/Path.h>
[290]17#include <casa/OS/File.h>
[338]18#include <casa/Quanta/Unit.h>
[805]19#include <casa/Arrays/ArrayMath.h>
[1060]20#include <casa/Arrays/ArrayLogical.h>
[805]21#include <casa/Utilities/Regex.h>
22
23#include <casa/Containers/RecordField.h>
24
25#include <tables/Tables/TableRow.h>
26
[2]27#include <atnf/PKSIO/PKSreader.h>
[1387]28#include <casa/System/ProgressMeter.h>
[125]29
[1387]30
[835]31#include "STDefs.h"
[878]32#include "STAttr.h"
[2]33
[805]34#include "STFiller.h"
[901]35#include "STHeader.h"
[805]36
[125]37using namespace casa;
[2]38
[805]39namespace asap {
40
41STFiller::STFiller() :
[2]42  reader_(0),
[405]43  header_(0),
[805]44  table_(0)
[420]45{
[2]46}
[805]47
48STFiller::STFiller( CountedPtr< Scantable > stbl ) :
[46]49  reader_(0),
[405]50  header_(0),
[805]51  table_(stbl)
[420]52{
[46]53}
[2]54
[855]55STFiller::STFiller(const std::string& filename, int whichIF, int whichBeam ) :
[2]56  reader_(0),
[405]57  header_(0),
[805]58  table_(0)
[420]59{
[805]60  open(filename, whichIF, whichBeam);
[2]61}
62
[805]63STFiller::~STFiller()
64{
65  close();
[2]66}
67
[855]68void STFiller::open( const std::string& filename, int whichIF, int whichBeam )
[805]69{
[846]70  if (table_.null())  {
71    table_ = new Scantable();
72  }
[805]73  if (reader_)  { delete reader_; reader_ = 0; }
74  Bool haveBase, haveSpectra;
[2]75
76  String inName(filename);
[284]77  Path path(inName);
78  inName = path.expandedName();
[405]79
[290]80  File file(inName);
[805]81  if ( !file.exists() ) {
[290]82     throw(AipsError("File does not exist"));
83  }
[87]84  filename_ = inName;
[332]85
[405]86  // Create reader and fill in values for arguments
[2]87  String format;
[1060]88  Vector<Bool> beams, ifs;
89  Vector<uInt> nchans,npols;
90  if ( (reader_ = getPKSreader(inName, 0, 0, format, beams, ifs,
91                              nchans, npols, haveXPol_,haveBase, haveSpectra
92                              )) == 0 )  {
[405]93    throw(AipsError("Creation of PKSreader failed"));
[2]94  }
95  if (!haveSpectra) {
96    delete reader_;
97    reader_ = 0;
[87]98    throw(AipsError("No spectral data in file."));
[2]99    return;
100  }
101  nBeam_ = beams.nelements();
[1060]102  nIF_ = ifs.nelements();
[2]103  // Get basic parameters.
[1060]104  if ( anyEQ(haveXPol_, True) ) {
[717]105    pushLog("Cross polarization present");
[1060]106    for (uInt i=0; i< npols.nelements();++i) {
107      if (npols[i] < 3) npols[i] += 2;// Convert Complex -> 2 Floats
108    }
[110]109  }
[405]110  if (header_) delete header_;
[901]111  header_ = new STHeader();
[1060]112  header_->nchan = max(nchans);
113  header_->npol = max(npols);
[405]114  header_->nbeam = nBeam_;
115
116  Int status = reader_->getHeader(header_->observer, header_->project,
117                                  header_->antennaname, header_->antennaposition,
118                                  header_->obstype,header_->equinox,
119                                  header_->freqref,
120                                  header_->utc, header_->reffreq,
[1387]121                                  header_->bandwidth,
122                                  header_->fluxunit);
[405]123
[2]124  if (status) {
125    delete reader_;
126    reader_ = 0;
[805]127    delete header_;
128    header_ = 0;
[87]129    throw(AipsError("Failed to get header."));
[2]130  }
[405]131  if ((header_->obstype).matches("*SW*")) {
[2]132    // need robust way here - probably read ahead of next timestamp
[717]133    pushLog("Header indicates frequency switched observation.\n"
[754]134               "setting # of IFs = 1 ");
[2]135    nIF_ = 1;
[805]136    header_->obstype = String("fswitch");
[2]137  }
[405]138  // Determine Telescope and set brightness unit
[342]139
[1387]140
[342]141  Bool throwIt = False;
[878]142  Instrument inst = STAttr::convertInstrument(header_->antennaname, throwIt);
[1387]143  //header_->fluxunit = "Jy";
[342]144  if (inst==ATMOPRA || inst==TIDBINBILLA) {
[405]145     header_->fluxunit = "K";
[342]146  }
[1188]147  STAttr stattr;
148  header_->poltype = stattr.feedPolType(inst);
[405]149  header_->nif = nIF_;
150  header_->epoch = "UTC";
[805]151  // *** header_->frequnit = "Hz"
[2]152  // Apply selection criteria.
153  Vector<Int> ref;
[332]154  ifOffset_ = 0;
155  if (whichIF>=0) {
156    if (whichIF>=0 && whichIF<nIF_) {
[1060]157      ifs = False;
158      ifs(whichIF) = True;
[805]159      header_->nif = 1;
160      nIF_ = 1;
161      ifOffset_ = whichIF;
[332]162    } else {
[805]163      delete reader_;
164      reader_ = 0;
165      delete header_;
166      header_ = 0;
167      throw(AipsError("Illegal IF selection"));
[332]168    }
169  }
170  beamOffset_ = 0;
171  if (whichBeam>=0) {
[805]172    if (whichBeam>=0 && whichBeam<nBeam_) {
[1060]173      beams = False;
174      beams(whichBeam) = True;
[805]175      header_->nbeam = 1;
176      nBeam_ = 1;
177      beamOffset_ = whichBeam;
178    } else {
179      delete reader_;
180      reader_ = 0;
181      delete header_;
182      header_ = 0;
183      throw(AipsError("Illegal Beam selection"));
184    }
[332]185  }
186  Vector<Int> start(nIF_, 1);
187  Vector<Int> end(nIF_, 0);
[1060]188  reader_->select(beams, ifs, start, end, ref, True, haveXPol_[0], False);
[846]189  table_->setHeader(*header_);
[1387]190  //For MS, add the location of POINTING of the input MS so one get
191  //pointing data from there, if necessary.
192  //Also find nrow in MS
193  nInDataRow = 0;
194  if (format == "MS2") {
195    Path datapath(inName);
196    String ptTabPath = datapath.absoluteName();
197    Table inMS(ptTabPath);
198    nInDataRow = inMS.nrow();
199    ptTabPath.append("/POINTING");
200    table_->table().rwKeywordSet().define("POINTING", ptTabPath);
201    if ((header_->antennaname).matches("GBT")) {
202      String GOTabPath = datapath.absoluteName();
203      GOTabPath.append("/GBT_GO");
204      table_->table().rwKeywordSet().define("GBT_GO", GOTabPath);
205    }
206  }
[1446]207  String freqFrame = header_->freqref;
208  //translate frequency reference frame back to
209  //MS style (as PKSMS2reader converts the original frame
210  //in FITS standard style)
211  if (freqFrame == "TOPOCENT") {
212    freqFrame = "TOPO";
213  } else if (freqFrame == "GEOCENER") {
214    freqFrame = "GEO";
215  } else if (freqFrame == "BARYCENT") {
216    freqFrame = "BARY";
217  } else if (freqFrame == "GALACTOC") {
218    freqFrame = "GALACTO";
219  } else if (freqFrame == "LOCALGRP") {
220    freqFrame = "LGROUP";
221  } else if (freqFrame == "CMBDIPOL") {
222    freqFrame = "CMB";
223  } else if (freqFrame == "SOURCE") {
224    freqFrame = "REST";
225  }
226  table_->frequencies().setFrame(freqFrame);
[1387]227     
[805]228}
[405]229
[805]230void STFiller::close( )
231{
232  delete reader_;reader_=0;
233  delete header_;header_=0;
234  table_ = 0;
[2]235}
236
[805]237int asap::STFiller::read( )
238{
[87]239  int status = 0;
240
[17]241  Int    beamNo, IFno, refBeam, scanNo, cycleNo;
[87]242  Float  azimuth, elevation, focusAxi, focusRot, focusTan,
[2]243    humidity, parAngle, pressure, temperature, windAz, windSpeed;
[1446]244  Double bandwidth, freqInc, interval, mjd, refFreq, srcVel;
[1072]245  String          fieldName, srcName, tcalTime, obsType;
[2]246  Vector<Float>   calFctr, sigma, tcal, tsys;
247  Matrix<Float>   baseLin, baseSub;
[1446]248  Vector<Double>  direction(2), scanRate(2), srcDir(2), srcPM(2), restFreq;
[2]249  Matrix<Float>   spectra;
250  Matrix<uChar>   flagtra;
251  Complex         xCalFctr;
252  Vector<Complex> xPol;
[1387]253  Double min = 0.0;
254  Double max = nInDataRow;
255  ProgressMeter fillpm(min, max, "Data importing progress");
256  int n = 0;
[805]257  while ( status == 0 ) {
258    status = reader_->read(scanNo, cycleNo, mjd, interval, fieldName,
[1072]259                          srcName, srcDir, srcPM, srcVel, obsType, IFno,
260                          refFreq, bandwidth, freqInc, restFreq, tcal, tcalTime,
[805]261                          azimuth, elevation, parAngle, focusAxi,
262                          focusTan, focusRot, temperature, pressure,
263                          humidity, windSpeed, windAz, refBeam,
264                          beamNo, direction, scanRate,
265                          tsys, sigma, calFctr, baseLin, baseSub,
266                          spectra, flagtra, xCalFctr, xPol);
267    if ( status != 0 ) break;
[1387]268    n += 1;
269   
[1081]270    Regex filterrx(".*[SL|PA]$");
[1110]271    Regex obsrx("^AT.+");
272    if ( header_->antennaname.matches(obsrx) && obsType.matches(filterrx)) {
273        //cerr << "ignoring paddle scan" << endl;
[1081]274        continue;
275    }
[805]276    TableRow row(table_->table());
277    TableRecord& rec = row.record();
[999]278    // fields that don't get used and are just passed through asap
279    RecordFieldPtr<Array<Double> > srateCol(rec, "SCANRATE");
280    *srateCol = scanRate;
281    RecordFieldPtr<Array<Double> > spmCol(rec, "SRCPROPERMOTION");
282    *spmCol = srcPM;
283    RecordFieldPtr<Array<Double> > sdirCol(rec, "SRCDIRECTION");
284    *sdirCol = srcDir;
285    RecordFieldPtr<Double> svelCol(rec, "SRCVELOCITY");
286    *svelCol = srcVel;
287    // the real stuff
[972]288    RecordFieldPtr<Int> fitCol(rec, "FIT_ID");
289    *fitCol = -1;
[805]290    RecordFieldPtr<uInt> scanoCol(rec, "SCANNO");
291    *scanoCol = scanNo-1;
292    RecordFieldPtr<uInt> cyclenoCol(rec, "CYCLENO");
293    *cyclenoCol = cycleNo-1;
294    RecordFieldPtr<Double> mjdCol(rec, "TIME");
295    *mjdCol = mjd;
296    RecordFieldPtr<Double> intCol(rec, "INTERVAL");
297    *intCol = interval;
298    RecordFieldPtr<String> srcnCol(rec, "SRCNAME");
299    RecordFieldPtr<Int> srctCol(rec, "SRCTYPE");
[1387]300    RecordFieldPtr<String> fieldnCol(rec, "FIELDNAME");
301    *fieldnCol = fieldName;
[805]302    // try to auto-identify if it is on or off.
[922]303    Regex rx(".*[e|w|_R]$");
[942]304    Regex rx2("_S$");
[805]305    Int match = srcName.matches(rx);
306    if (match) {
307      *srcnCol = srcName;
308    } else {
309      *srcnCol = srcName.before(rx2);
310    }
311    //*srcnCol = srcName;//.before(rx2);
312    *srctCol = match;
313    RecordFieldPtr<uInt> beamCol(rec, "BEAMNO");
314    *beamCol = beamNo-beamOffset_-1;
315    RecordFieldPtr<Int> rbCol(rec, "REFBEAMNO");
316    Int rb = -1;
317    if (nBeam_ > 1 ) rb = refBeam-1;
318    *rbCol = rb;
319    RecordFieldPtr<uInt> ifCol(rec, "IFNO");
320    *ifCol = IFno-ifOffset_- 1;
321    uInt id;
322    /// @todo this has to change when nchan isn't global anymore
323    id = table_->frequencies().addEntry(Double(header_->nchan/2),
324                                            refFreq, freqInc);
325    RecordFieldPtr<uInt> mfreqidCol(rec, "FREQ_ID");
326    *mfreqidCol = id;
[25]327
[805]328    id = table_->molecules().addEntry(restFreq);
329    RecordFieldPtr<uInt> molidCol(rec, "MOLECULE_ID");
330    *molidCol = id;
[414]331
[805]332    id = table_->tcal().addEntry(tcalTime, tcal);
333    RecordFieldPtr<uInt> mcalidCol(rec, "TCAL_ID");
334    *mcalidCol = id;
335    id = table_->weather().addEntry(temperature, pressure, humidity,
336                                    windSpeed, windAz);
337    RecordFieldPtr<uInt> mweatheridCol(rec, "WEATHER_ID");
338    *mweatheridCol = id;
339    RecordFieldPtr<uInt> mfocusidCol(rec, "FOCUS_ID");
340    id = table_->focus().addEntry(focusAxi, focusTan, focusRot);
341    *mfocusidCol = id;
342    RecordFieldPtr<Array<Double> > dirCol(rec, "DIRECTION");
343    *dirCol = direction;
[922]344    RecordFieldPtr<Float> azCol(rec, "AZIMUTH");
[805]345    *azCol = azimuth;
[922]346    RecordFieldPtr<Float> elCol(rec, "ELEVATION");
[805]347    *elCol = elevation;
[405]348
[805]349    RecordFieldPtr<Float> parCol(rec, "PARANGLE");
350    *parCol = parAngle;
[332]351
[805]352    RecordFieldPtr< Array<Float> > specCol(rec, "SPECTRA");
353    RecordFieldPtr< Array<uChar> > flagCol(rec, "FLAGTRA");
354    RecordFieldPtr< uInt > polnoCol(rec, "POLNO");
[405]355
[805]356    RecordFieldPtr< Array<Float> > tsysCol(rec, "TSYS");
357    // Turn the (nchan,npol) matrix and possible complex xPol vector
358    // into 2-4 rows in the scantable
359    Vector<Float> tsysvec(1);
360    // Why is spectra.ncolumn() == 3 for haveXPol_ == True
361    uInt npol = (spectra.ncolumn()==1 ? 1: 2);
362    for ( uInt i=0; i< npol; ++i ) {
363      tsysvec = tsys(i);
364      *tsysCol = tsysvec;
365      *polnoCol = i;
[405]366
[805]367      *specCol = spectra.column(i);
368      *flagCol = flagtra.column(i);
369      table_->table().addRow();
370      row.put(table_->table().nrow()-1, rec);
[2]371    }
[1060]372    if ( haveXPol_[0] ) {
[805]373      // no tsys given for xpol, so emulate it
374      tsysvec = sqrt(tsys[0]*tsys[1]);
375      *tsysCol = tsysvec;
376      // add real part of cross pol
377      *polnoCol = 2;
378      Vector<Float> r(real(xPol));
379      *specCol = r;
380      // make up flags from linears
381      /// @fixme this has to be a bitwise or of both pols
382      *flagCol = flagtra.column(0);// | flagtra.column(1);
383      table_->table().addRow();
384      row.put(table_->table().nrow()-1, rec);
385      // ad imaginary part of cross pol
386      *polnoCol = 3;
387      Vector<Float> im(imag(xPol));
388      *specCol = im;
389      table_->table().addRow();
390      row.put(table_->table().nrow()-1, rec);
[2]391    }
[1387]392    fillpm._update(n);
[805]393  }
394  if (status > 0) {
395    close();
396    throw(AipsError("Reading error occured, data possibly corrupted."));
397  }
[1387]398  fillpm.done();
[2]399  return status;
400}
[805]401
402}//namespace asap
Note: See TracBrowser for help on using the repository browser.