source: trunk/src/SDContainer.cc @ 757

Last change on this file since 757 was 685, checked in by mar637, 19 years ago

forgot to change some hardcoded axes. Now using asap::AxisNo? everywhere.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 15.0 KB
RevLine 
[2]1//#---------------------------------------------------------------------------
2//# SDContainer.cc: A container class for single dish integrations
3//#---------------------------------------------------------------------------
4//# Copyright (C) 2004
[125]5//# ATNF
[2]6//#
7//# This program is free software; you can redistribute it and/or modify it
8//# under the terms of the GNU General Public License as published by the Free
9//# Software Foundation; either version 2 of the License, or (at your option)
10//# any later version.
11//#
12//# This program is distributed in the hope that it will be useful, but
13//# WITHOUT ANY WARRANTY; without even the implied warranty of
14//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
15//# Public License for more details.
16//#
17//# You should have received a copy of the GNU General Public License along
18//# with this program; if not, write to the Free Software Foundation, Inc.,
19//# 675 Massachusetts Ave, Cambridge, MA 02139, USA.
20//#
21//# Correspondence concerning this software should be addressed as follows:
22//#        Internet email: Malte.Marquarding@csiro.au
23//#        Postal address: Malte Marquarding,
24//#                        Australia Telescope National Facility,
25//#                        P.O. Box 76,
26//#                        Epping, NSW, 2121,
27//#                        AUSTRALIA
28//#
29//# $Id:
30//#---------------------------------------------------------------------------
[349]31
[125]32#include <casa/aips.h>
[327]33#include <casa/iostream.h>
34#include <casa/iomanip.h>
[104]35#include <casa/Exceptions.h>
[349]36#include <casa/Utilities/Assert.h>
[81]37#include <tables/Tables/Table.h>
38#include <casa/Arrays/IPosition.h>
[125]39#include <casa/Arrays/Matrix.h>
[349]40#include <casa/Arrays/VectorIter.h>
[417]41#include <casa/Arrays/ArrayMath.h>
[308]42#include <casa/BasicMath/Math.h>
[81]43#include <casa/Quanta/MVTime.h>
[2]44
[308]45
[349]46
[215]47#include "SDDefs.h"
[2]48#include "SDContainer.h"
49
[125]50using namespace casa;
[83]51using namespace asap;
[2]52
[18]53void SDHeader::print() const {
54  MVTime mvt(this->utc);
[47]55  mvt.setFormat(MVTime::YMD);
[18]56  cout << "Observer: " << this->observer << endl
57       << "Project: " << this->project << endl
58       << "Obstype: " << this->obstype << endl
59       << "Antenna: " << this->antennaname << endl
60       << "Ant. Position: " << this->antennaposition << endl
61       << "Equinox: " << this->equinox << endl
62       << "Freq. ref.: " << this->freqref << endl
63       << "Ref. frequency: " << this->reffreq << endl
64       << "Bandwidth: "  << this->bandwidth << endl
65       << "Time (utc): "
[47]66       << mvt
[18]67       << endl;
68  //setprecision(10) << this->utc << endl;
69}
70
71
[16]72SDContainer::SDContainer(uInt nBeam, uInt nIF, uInt nPol, uInt nChan)
[2]73  : nBeam_(nBeam),
[16]74    nIF_(nIF),
75    nPol_(nPol),
76    nChan_(nChan),
77    spectrum_(IPosition(4,nBeam,nIF,nPol,nChan)),
78    flags_(IPosition(4,nBeam,nIF,nPol,nChan)),
[34]79    tsys_(IPosition(4,nBeam,nIF,nPol,nChan)),
[79]80    freqidx_(nIF),
[388]81    restfreqidx_(nIF),
[79]82    direction_(IPosition(2,nBeam,2)) {
[2]83  uChar x = 0;
84  flags_ = ~x;
[104]85  tcal.resize(2);
[2]86}
87
[16]88SDContainer::SDContainer(IPosition shp)
[685]89  : nBeam_(shp(asap::BeamAxis)),
90    nIF_(shp(asap::IFAxis)),
91    nPol_(shp(asap::PolAxis)),
92    nChan_(shp(asap::ChanAxis)),
[16]93    spectrum_(shp),
94    flags_(shp),
[34]95    tsys_(shp),
[685]96    freqidx_(shp(asap::IFAxis)),
97    restfreqidx_(shp(asap::IFAxis)) {
98  IPosition ip(2,shp(asap::BeamAxis),2);
[79]99  direction_.resize(ip);
[16]100  uChar x = 0;
101  flags_ = ~x;
[104]102  tcal.resize(2);
[16]103}
104
[2]105SDContainer::~SDContainer() {
106}
107
[47]108Bool SDContainer::resize(IPosition shp) {
[685]109  nBeam_ = shp(asap::BeamAxis);
110  nIF_ = shp(asap::IFAxis);
111  nPol_ = shp(asap::PolAxis);
112  nChan_ = shp(asap::ChanAxis);
[47]113  spectrum_.resize(shp);
114  flags_.resize(shp);
115  tsys_.resize(shp);
[685]116  freqidx_.resize(shp(asap::IFAxis));
117  restfreqidx_.resize(shp(asap::IFAxis));
118  IPosition ip(2,shp(asap::BeamAxis),2);
[79]119  direction_.resize(ip);
[47]120}
121
[2]122Bool SDContainer::putSpectrum(const Array<Float>& spec) {
123  spectrum_ = spec;
124}
[7]125Bool SDContainer::putFlags(const Array<uChar>& flag) {
126  flags_ = flag;
[2]127}
[7]128Bool SDContainer::putTsys(const Array<Float>& tsys) {
129  tsys_ = tsys;
[2]130}
131
132Bool SDContainer::setSpectrum(const Matrix<Float>& spec,
[417]133                              const Vector<Complex>& cSpec,
[349]134                              uInt whichBeam, uInt whichIF)
135//
136// spec is [nChan,nPol]
[417]137// cspec is [nChan]
[349]138// spectrum_ is [,,,nChan]
139//
[417]140// nPOl_ = 4  - xx, yy, real(xy), imag(xy)
141//
[349]142{
[417]143  AlwaysAssert(nPol_==4,AipsError);
[2]144
[417]145// Get slice  and check dim
146
147  Bool tSys = False;
148  Bool xPol = True;
149  IPosition start, end;
[685]150  setSlice(start, end, spec.shape(), spectrum_.shape(),
[417]151            whichBeam, whichIF, tSys, xPol);
152
153// Get a reference to the Pol/Chan slice we are interested in
154
155  Array<Float> subArr = spectrum_(start,end);
156
157// Iterate through pol-chan plane and fill
158
159  ReadOnlyVectorIterator<Float> inIt(spec,0);
160  VectorIterator<Float> outIt(subArr,asap::ChanAxis);
161  while (!outIt.pastEnd()) {
162     const IPosition& pos = outIt.pos();
163     if (pos(asap::PolAxis)<2) {
164        outIt.vector() = inIt.vector();
165        inIt.next();
166     } else if (pos(asap::PolAxis)==2) {
167        outIt.vector() = real(cSpec);
168     } else if (pos(asap::PolAxis)==3) {
169        outIt.vector() = imag(cSpec);
170     }
171//
172     outIt.next();
173  }
174
175  // unset flags for this spectrum, they might be set again by the
176  // setFlags method
177
178  Array<uChar> arr(flags_(start,end));
179  arr = uChar(0);
180//
181  return True;
182}
183
184
185Bool SDContainer::setSpectrum(const Matrix<Float>& spec,
186                              uInt whichBeam, uInt whichIF)
187//
188// spec is [nChan,nPol]
189// spectrum_ is [,,,nChan]
190// How annoying.
191{
192
[349]193// Get slice and check dim
194
195  IPosition start, end;
[685]196  setSlice(start, end, spec.shape(), spectrum_.shape(),
[417]197            whichBeam, whichIF, False, False);
[349]198
199// Get a reference to the Pol/Chan slice we are interested in
200
201  Array<Float> subArr = spectrum_(start,end);
202
203// Iterate through it and fill
204
205  ReadOnlyVectorIterator<Float> inIt(spec,0);
206  VectorIterator<Float> outIt(subArr,asap::ChanAxis);
[417]207  while (!outIt.pastEnd()) {
[349]208     outIt.vector() = inIt.vector();
209//
210     inIt.next();
211     outIt.next();
[14]212  }
[349]213
[2]214  // unset flags for this spectrum, they might be set again by the
215  // setFlags method
[14]216
[2]217  Array<uChar> arr(flags_(start,end));
218  arr = uChar(0);
[336]219//
220  return True;
[2]221}
222
[453]223Bool SDContainer::setFlags(const Matrix<uChar>& flags,
224                           uInt whichBeam, uInt whichIF,
225                           Bool hasXPol)
[349]226//
227// flags is [nChan,nPol]
[473]228// flags_ is [nBeam,nIF,nPol,nChan]
[349]229//
[473]230// Note that there are no separate flags for the XY cross polarization so we make
231// them up from the X and Y which is all the silly code below.  This means
232// that nPol==2 on input but 4 on output
233//
[349]234{
[417]235  if (hasXPol) AlwaysAssert(nPol_==4,AipsError);
236
[349]237// Get slice and check dim
[14]238
[349]239  IPosition start, end;
[685]240  setSlice(start, end, flags.shape(), flags_.shape(),
[417]241            whichBeam, whichIF, False, hasXPol);
[349]242
243// Get a reference to the Pol/Chan slice we are interested in
244
245  Array<uChar> subArr = flags_(start,end);
246
[417]247// Iterate through pol/chan plane  and fill
[349]248
249  ReadOnlyVectorIterator<uChar> inIt(flags,0);
250  VectorIterator<uChar> outIt(subArr,asap::ChanAxis);
251//
[417]252  Vector<uChar> maskPol0;
253  Vector<uChar> maskPol1;
254  Vector<uChar> maskPol01;
255  while (!outIt.pastEnd()) {
256     const IPosition& pos = outIt.pos();
257     if (pos(asap::PolAxis)<2) {
258        outIt.vector() = inIt.vector();
259//
260        if (hasXPol) {
261           if (pos(asap::PolAxis)==0) {
262              maskPol0 = inIt.vector();
263           } else if (pos(asap::PolAxis)==1) {
264              maskPol1 = inIt.vector();
265//
266              maskPol01.resize(maskPol0.nelements());
267              for (uInt i=0; i<maskPol01.nelements(); i++) maskPol01[i] = maskPol0[i]&maskPol1[i];
268           }
269        }
270        inIt.next();
271     } else if (pos(asap::PolAxis)==2) {
[473]272        if (hasXPol) {
273           outIt.vector() = maskPol01;
274        } else {
275           outIt.vector() = inIt.vector();
276           inIt.next();
277        }
278
[417]279     } else if (pos(asap::PolAxis)==3) {
[473]280        if (hasXPol) {
281           outIt.vector() = maskPol01;
282        } else {
283           outIt.vector() = inIt.vector();
284           inIt.next();
285        }
[417]286     }
[349]287     outIt.next();
[2]288  }
[349]289//
[16]290  return True;
[2]291}
292
[349]293
[2]294Bool SDContainer::setTsys(const Vector<Float>& tsys,
[417]295                          uInt whichBeam, uInt whichIF,
296                          Bool hasXpol)
[349]297//
[473]298// TSys shape is [nPol]
[349]299// Tsys does not depend upon channel but is replicated
[417]300// for simplicity of use.
301// There is no Tsys measurement for the cross polarization
302// so I have set TSys for XY to sqrt(Tx*Ty)
[349]303//
304{
305
306// Get slice and check dim
307
308  IPosition start, end;
[685]309  setSlice(start, end, tsys.shape(), tsys_.shape(),
[417]310            whichBeam, whichIF, True, hasXpol);
[349]311
312// Get a reference to the Pol/Chan slice we are interested in
313
314  Array<Float> subArr = tsys_(start,end);
315
316// Iterate through it and fill
317
318  VectorIterator<Float> outIt(subArr,asap::ChanAxis);
319  uInt i=0;
320  while (!outIt.pastEnd()) {
[417]321     const IPosition& pos = outIt.pos();
322//
323     if (pos(asap::PolAxis)<2) {
324       outIt.vector() = tsys(i++);
325     } else {
[473]326       if (hasXpol) {
327          outIt.vector() = sqrt(tsys[0]*tsys[1]);
328       } else {
329          outIt.vector() = tsys(i++);
330       }
[417]331     }
332//
[349]333     outIt.next();
[7]334  }
[2]335}
[27]336
[449]337Array<Float> SDContainer::getSpectrum(uInt whichBeam, uInt whichIF)
338//
339// non-const function because of Array(start,end) slicer
340//
341// Input  [nBeam,nIF,nPol,nChan]
342// Output [nChan,nPol]
343//
[125]344{
[27]345
[449]346// Get reference to slice and check dim
[27]347
[449]348  IPosition start, end;
[685]349  setSlice(start, end, spectrum_.shape(), whichBeam, whichIF);
[449]350//
351  Array<Float> dataIn = spectrum_(start,end);
352  Array<Float> dataOut(IPosition(2, nChan_, nPol_));
353//
354  ReadOnlyVectorIterator<Float> itIn(dataIn, asap::ChanAxis);
355  VectorIterator<Float> itOut(dataOut, 0);
356  while (!itOut.pastEnd()) {
357     itOut.vector() = itIn.vector();
358//
359     itIn.next();
360     itOut.next();
[27]361  }
[449]362//
363  return dataOut.copy();
[27]364}
365
[449]366Array<uChar> SDContainer::getFlags(uInt whichBeam, uInt whichIF)
367//
368// non-const function because of Array(start,end) slicer
369//
370// Input  [nBeam,nIF,nPol,nChan]
371// Output [nChan,nPol]
372//
[27]373{
374
[449]375// Get reference to slice and check dim
[27]376
[449]377  IPosition start, end;
[685]378  setSlice(start, end, flags_.shape(), whichBeam, whichIF);
[449]379//
380  Array<uChar> dataIn = flags_(start,end);
381  Array<uChar> dataOut(IPosition(2, nChan_, nPol_));
382//
383  ReadOnlyVectorIterator<uChar> itIn(dataIn, asap::ChanAxis);
384  VectorIterator<uChar> itOut(dataOut, 0);
385  while (!itOut.pastEnd()) {
386     itOut.vector() = itIn.vector();
387//
388     itIn.next();
389     itOut.next();
[27]390  }
[449]391//
392  return dataOut.copy();
[27]393}
394
[449]395Array<Float> SDContainer::getTsys(uInt whichBeam, uInt whichIF)
396//
397// Input  [nBeam,nIF,nPol,nChan]
[473]398// Output [nPol]   (drop channel dependency and select first value only)
[449]399//
[27]400{
[449]401// Get reference to slice and check dim
[27]402
[449]403  IPosition start, end;
[685]404  setSlice(start, end, spectrum_.shape(), whichBeam, whichIF);
[449]405//
406  Array<Float> dataIn = tsys_(start,end);
407  Vector<Float> dataOut(nPol_);
408//
409  ReadOnlyVectorIterator<Float> itIn(dataIn, asap::ChanAxis);
410  VectorIterator<Float> itOut(dataOut, 0);
411  uInt i = 0;
412  while (!itIn.pastEnd()) {
413    dataOut[i++] = itIn.vector()[0];
414    itIn.next();
415  }
416//
417  return dataOut.copy();
418}
[27]419
420
421
[449]422Array<Double> SDContainer::getDirection(uInt whichBeam) const
423//
424// Input [nBeam,2]
425// Output [nBeam]
426//
427{
428  Vector<Double> dataOut(2);
429  dataOut(0) = direction_(IPosition(2,whichBeam,0));
430  dataOut(1) = direction_(IPosition(2,whichBeam,1));
431  return dataOut.copy();
[27]432}
[34]433
[79]434
[388]435Bool SDContainer::setFrequencyMap(uInt freqID, uInt whichIF) {
436  freqidx_[whichIF] = freqID;
[34]437  return True;
438}
439
440Bool SDContainer::putFreqMap(const Vector<uInt>& freqs) {
441  freqidx_.resize();
442  freqidx_ = freqs;
443  return True;
444}
445
[388]446Bool SDContainer::setRestFrequencyMap(uInt freqID, uInt whichIF) {
447  restfreqidx_[whichIF] = freqID;
448  return True;
449}
450
451Bool SDContainer::putRestFreqMap(const Vector<uInt>& freqs) {
452  restfreqidx_.resize();
453  restfreqidx_ = freqs;
454  return True;
455}
456
[449]457Bool SDContainer::setDirection(const Vector<Double>& point, uInt whichBeam)
458//
459// Input [2]
460// Output [nBeam,2]
461//
462{
[79]463  if (point.nelements() != 2) return False;
[449]464//
465  Vector<Double> dataOut(2);
466  direction_(IPosition(2,whichBeam,0)) = point[0];
467  direction_(IPosition(2,whichBeam,1)) = point[1];
[79]468  return True;
469}
470
[449]471
[79]472Bool SDContainer::putDirection(const Array<Double>& dir) {
473  direction_.resize();
474  direction_ = dir;
475  return True;
476}
477
[453]478Bool SDContainer::putFitMap(const Array<Int>& arr) {
479  fitIDMap_.resize();
480  fitIDMap_ = arr;
481  return True;
482}
483
484void SDContainer::setSlice(IPosition& start, IPosition& end,
485                           const IPosition& shpIn, const IPosition& shpOut,
486                           uInt whichBeam, uInt whichIF, Bool tSys,
487                           Bool xPol) const
[349]488//
489// tSYs
490//   shpIn [nPol]
491// else
492//   shpIn [nCHan,nPol]
493//
[417]494// if xPol present, the output nPol = 4 but
495// the input spectra are nPol=2 (tSys) or nPol=2 (spectra)
496//
[349]497{
498  AlwaysAssert(asap::nAxes==4,AipsError);
[417]499  uInt pOff = 0;
500  if (xPol) pOff += 2;
[349]501  if (tSys) {
[417]502     AlwaysAssert(shpOut(asap::PolAxis)==shpIn(0)+pOff,AipsError);     // pol
[349]503  } else {
[417]504     AlwaysAssert(shpOut(asap::ChanAxis)==shpIn(0),AipsError);       // chan
505     AlwaysAssert(shpOut(asap::PolAxis)==shpIn(1)+pOff,AipsError);   // pol
[349]506  }
507//
[453]508  setSlice(start, end, shpOut, whichBeam, whichIF);
[449]509}
510
511
[453]512void SDContainer::setSlice(IPosition& start, IPosition& end,
513                           const IPosition& shape,
514                           uInt whichBeam, uInt whichIF) const
[449]515{
516  AlwaysAssert(asap::nAxes==4,AipsError);
[453]517  //
[349]518  start.resize(asap::nAxes);
519  start = 0;
520  start(asap::BeamAxis) = whichBeam;
521  start(asap::IFAxis) = whichIF;
522//
523  end.resize(asap::nAxes);
[449]524  end = shape-1;
[349]525  end(asap::BeamAxis) = whichBeam;
526  end(asap::IFAxis) = whichIF;
527}
528
529
[388]530uInt SDFrequencyTable::addFrequency(Double refPix, Double refVal, Double inc)
531{
[34]532  if (length() > 0) {
[388]533    for (uInt i=0; i< length();i++) {
534      if (near(refVal,refVal_[i]) &&
535          near(refPix,refPix_[i]) &&
536          near(inc,increment_[i])) {
537         return i;
[34]538      }
539    }
540  }
[388]541
542// Not found - add it
543
[34]544  nFreq_ += 1;
545  refPix_.resize(nFreq_,True);
546  refVal_.resize(nFreq_,True);
547  increment_.resize(nFreq_,True);
548  refPix_[nFreq_-1] = refPix;
549  refVal_[nFreq_-1] = refVal;
550  increment_[nFreq_-1] = inc;
[388]551  return nFreq_-1;
[34]552}
553
[388]554uInt SDFrequencyTable::addRestFrequency(Double val)
[204]555{
[388]556  uInt nFreq = restFreqs_.nelements();
557  if (nFreq>0) {
558    for (uInt i=0; i<nFreq;i++) {
559      if (near(restFreqs_[i],val)) {
560         return i;
[204]561      }
562    }
563  }
[388]564
565// Not found - add it
566
567  nFreq += 1;
568  restFreqs_.resize(nFreq,True);
569  restFreqs_[nFreq-1] = val;
570  return nFreq-1;
[204]571}
[388]572
573
[204]574void SDFrequencyTable::restFrequencies(Vector<Double>& rfs,
575                                       String& rfunit ) const
576{
577  rfs.resize(restFreqs_.nelements());
578  rfs = restFreqs_;
579  rfunit = restFreqUnit_;
580}
[326]581
[349]582// SDDataDesc
583
[453]584uInt SDDataDesc::addEntry(const String& source, uInt ID,
585                          const MDirection& dir, uInt secID)
[326]586{
587
588// See if already exists
589
590  if (n_ > 0) {
591    for (uInt i=0; i<n_; i++) {
[396]592      if (source==source_[i] && ID==ID_[i]) {
[326]593         return i;
594      }
595    }
596  }
597
598// Not found - add it
599
600  n_ += 1;
601  source_.resize(n_,True);
[396]602  ID_.resize(n_,True);
603  secID_.resize(n_,True);
604  secDir_.resize(n_,True,True);
[326]605//
606  source_[n_-1] = source;
[396]607  ID_[n_-1] = ID;
608  secID_[n_-1] = secID;
609  secDir_[n_-1] = dir;
[326]610//
611  return n_-1;
612}
613
614void SDDataDesc::summary() const
615{
[396]616   if (n_>0) {
617      cerr << "Source    ID" << endl;   
618      for (uInt i=0; i<n_; i++) {
[414]619         cout << setw(11) << source_(i) << ID_(i) << endl;
[396]620      }
[326]621   }
622}
[453]623
Note: See TracBrowser for help on using the repository browser.