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

Last change on this file since 1387 was 1387, checked in by TakTsutsumi, 17 years ago

merged from NRAO version of ASAP 2.1 with ALMA specific modifications

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.2 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                                  header_->fluxunit);
123
124  if (status) {
125    delete reader_;
126    reader_ = 0;
127    delete header_;
128    header_ = 0;
129    throw(AipsError("Failed to get header."));
130  }
131  if ((header_->obstype).matches("*SW*")) {
132    // need robust way here - probably read ahead of next timestamp
133    pushLog("Header indicates frequency switched observation.\n"
134               "setting # of IFs = 1 ");
135    nIF_ = 1;
136    header_->obstype = String("fswitch");
137  }
138  // Determine Telescope and set brightness unit
139
140
141  Bool throwIt = False;
142  Instrument inst = STAttr::convertInstrument(header_->antennaname, throwIt);
143  //header_->fluxunit = "Jy";
144  if (inst==ATMOPRA || inst==TIDBINBILLA) {
145     header_->fluxunit = "K";
146  }
147  STAttr stattr;
148  header_->poltype = stattr.feedPolType(inst);
149  header_->nif = nIF_;
150  header_->epoch = "UTC";
151  // *** header_->frequnit = "Hz"
152  // Apply selection criteria.
153  Vector<Int> ref;
154  ifOffset_ = 0;
155  if (whichIF>=0) {
156    if (whichIF>=0 && whichIF<nIF_) {
157      ifs = False;
158      ifs(whichIF) = True;
159      header_->nif = 1;
160      nIF_ = 1;
161      ifOffset_ = whichIF;
162    } else {
163      delete reader_;
164      reader_ = 0;
165      delete header_;
166      header_ = 0;
167      throw(AipsError("Illegal IF selection"));
168    }
169  }
170  beamOffset_ = 0;
171  if (whichBeam>=0) {
172    if (whichBeam>=0 && whichBeam<nBeam_) {
173      beams = False;
174      beams(whichBeam) = True;
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    }
185  }
186  Vector<Int> start(nIF_, 1);
187  Vector<Int> end(nIF_, 0);
188  reader_->select(beams, ifs, start, end, ref, True, haveXPol_[0], False);
189  table_->setHeader(*header_);
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  }
207     
208}
209
210void STFiller::close( )
211{
212  delete reader_;reader_=0;
213  delete header_;header_=0;
214  table_ = 0;
215}
216
217int asap::STFiller::read( )
218{
219  int status = 0;
220
221  Int    beamNo, IFno, refBeam, scanNo, cycleNo;
222  Float  azimuth, elevation, focusAxi, focusRot, focusTan,
223    humidity, parAngle, pressure, temperature, windAz, windSpeed;
224  Double bandwidth, freqInc, interval, mjd, refFreq, restFreq, srcVel;
225  String          fieldName, srcName, tcalTime, obsType;
226  Vector<Float>   calFctr, sigma, tcal, tsys;
227  Matrix<Float>   baseLin, baseSub;
228  Vector<Double>  direction(2), scanRate(2), srcDir(2), srcPM(2);
229  Matrix<Float>   spectra;
230  Matrix<uChar>   flagtra;
231  Complex         xCalFctr;
232  Vector<Complex> xPol;
233  Double min = 0.0;
234  Double max = nInDataRow;
235  ProgressMeter fillpm(min, max, "Data importing progress");
236  int n = 0;
237  while ( status == 0 ) {
238    status = reader_->read(scanNo, cycleNo, mjd, interval, fieldName,
239                          srcName, srcDir, srcPM, srcVel, obsType, IFno,
240                          refFreq, bandwidth, freqInc, restFreq, tcal, tcalTime,
241                          azimuth, elevation, parAngle, focusAxi,
242                          focusTan, focusRot, temperature, pressure,
243                          humidity, windSpeed, windAz, refBeam,
244                          beamNo, direction, scanRate,
245                          tsys, sigma, calFctr, baseLin, baseSub,
246                          spectra, flagtra, xCalFctr, xPol);
247    if ( status != 0 ) break;
248    n += 1;
249   
250    Regex filterrx(".*[SL|PA]$");
251    Regex obsrx("^AT.+");
252    if ( header_->antennaname.matches(obsrx) && obsType.matches(filterrx)) {
253        //cerr << "ignoring paddle scan" << endl;
254        continue;
255    }
256    TableRow row(table_->table());
257    TableRecord& rec = row.record();
258    // fields that don't get used and are just passed through asap
259    RecordFieldPtr<Array<Double> > srateCol(rec, "SCANRATE");
260    *srateCol = scanRate;
261    RecordFieldPtr<Array<Double> > spmCol(rec, "SRCPROPERMOTION");
262    *spmCol = srcPM;
263    RecordFieldPtr<Array<Double> > sdirCol(rec, "SRCDIRECTION");
264    *sdirCol = srcDir;
265    RecordFieldPtr<Double> svelCol(rec, "SRCVELOCITY");
266    *svelCol = srcVel;
267    // the real stuff
268    RecordFieldPtr<Int> fitCol(rec, "FIT_ID");
269    *fitCol = -1;
270    RecordFieldPtr<uInt> scanoCol(rec, "SCANNO");
271    *scanoCol = scanNo-1;
272    RecordFieldPtr<uInt> cyclenoCol(rec, "CYCLENO");
273    *cyclenoCol = cycleNo-1;
274    RecordFieldPtr<Double> mjdCol(rec, "TIME");
275    *mjdCol = mjd;
276    RecordFieldPtr<Double> intCol(rec, "INTERVAL");
277    *intCol = interval;
278    RecordFieldPtr<String> srcnCol(rec, "SRCNAME");
279    RecordFieldPtr<Int> srctCol(rec, "SRCTYPE");
280    RecordFieldPtr<String> fieldnCol(rec, "FIELDNAME");
281    *fieldnCol = fieldName;
282    // try to auto-identify if it is on or off.
283    Regex rx(".*[e|w|_R]$");
284    Regex rx2("_S$");
285    Int match = srcName.matches(rx);
286    if (match) {
287      *srcnCol = srcName;
288    } else {
289      *srcnCol = srcName.before(rx2);
290    }
291    //*srcnCol = srcName;//.before(rx2);
292    *srctCol = match;
293    RecordFieldPtr<uInt> beamCol(rec, "BEAMNO");
294    *beamCol = beamNo-beamOffset_-1;
295    RecordFieldPtr<Int> rbCol(rec, "REFBEAMNO");
296    Int rb = -1;
297    if (nBeam_ > 1 ) rb = refBeam-1;
298    *rbCol = rb;
299    RecordFieldPtr<uInt> ifCol(rec, "IFNO");
300    *ifCol = IFno-ifOffset_- 1;
301    uInt id;
302    /// @todo this has to change when nchan isn't global anymore
303    id = table_->frequencies().addEntry(Double(header_->nchan/2),
304                                            refFreq, freqInc);
305    RecordFieldPtr<uInt> mfreqidCol(rec, "FREQ_ID");
306    *mfreqidCol = id;
307
308    id = table_->molecules().addEntry(restFreq);
309    RecordFieldPtr<uInt> molidCol(rec, "MOLECULE_ID");
310    *molidCol = id;
311
312    id = table_->tcal().addEntry(tcalTime, tcal);
313    RecordFieldPtr<uInt> mcalidCol(rec, "TCAL_ID");
314    *mcalidCol = id;
315    id = table_->weather().addEntry(temperature, pressure, humidity,
316                                    windSpeed, windAz);
317    RecordFieldPtr<uInt> mweatheridCol(rec, "WEATHER_ID");
318    *mweatheridCol = id;
319    RecordFieldPtr<uInt> mfocusidCol(rec, "FOCUS_ID");
320    id = table_->focus().addEntry(focusAxi, focusTan, focusRot);
321    *mfocusidCol = id;
322    RecordFieldPtr<Array<Double> > dirCol(rec, "DIRECTION");
323    *dirCol = direction;
324    RecordFieldPtr<Float> azCol(rec, "AZIMUTH");
325    *azCol = azimuth;
326    RecordFieldPtr<Float> elCol(rec, "ELEVATION");
327    *elCol = elevation;
328
329    RecordFieldPtr<Float> parCol(rec, "PARANGLE");
330    *parCol = parAngle;
331
332    RecordFieldPtr< Array<Float> > specCol(rec, "SPECTRA");
333    RecordFieldPtr< Array<uChar> > flagCol(rec, "FLAGTRA");
334    RecordFieldPtr< uInt > polnoCol(rec, "POLNO");
335
336    RecordFieldPtr< Array<Float> > tsysCol(rec, "TSYS");
337    // Turn the (nchan,npol) matrix and possible complex xPol vector
338    // into 2-4 rows in the scantable
339    Vector<Float> tsysvec(1);
340    // Why is spectra.ncolumn() == 3 for haveXPol_ == True
341    uInt npol = (spectra.ncolumn()==1 ? 1: 2);
342    for ( uInt i=0; i< npol; ++i ) {
343      tsysvec = tsys(i);
344      *tsysCol = tsysvec;
345      *polnoCol = i;
346
347      *specCol = spectra.column(i);
348      *flagCol = flagtra.column(i);
349      table_->table().addRow();
350      row.put(table_->table().nrow()-1, rec);
351    }
352    if ( haveXPol_[0] ) {
353      // no tsys given for xpol, so emulate it
354      tsysvec = sqrt(tsys[0]*tsys[1]);
355      *tsysCol = tsysvec;
356      // add real part of cross pol
357      *polnoCol = 2;
358      Vector<Float> r(real(xPol));
359      *specCol = r;
360      // make up flags from linears
361      /// @fixme this has to be a bitwise or of both pols
362      *flagCol = flagtra.column(0);// | flagtra.column(1);
363      table_->table().addRow();
364      row.put(table_->table().nrow()-1, rec);
365      // ad imaginary part of cross pol
366      *polnoCol = 3;
367      Vector<Float> im(imag(xPol));
368      *specCol = im;
369      table_->table().addRow();
370      row.put(table_->table().nrow()-1, rec);
371    }
372    fillpm._update(n);
373  }
374  if (status > 0) {
375    close();
376    throw(AipsError("Reading error occured, data possibly corrupted."));
377  }
378  fillpm.done();
379  return status;
380}
381
382}//namespace asap
Note: See TracBrowser for help on using the repository browser.