source: trunk/src/STFiller.cpp @ 1391

Last change on this file since 1391 was 1391, checked in by Malte Marquarding, 17 years ago

merge from alma branch to get alma/GBT support. Commented out fluxUnit changes as they are using a chnaged interface to PKSreader/writer. Also commented out progress meter related code.

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