source: trunk/src/SDContainer.cc @ 453

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

Added SDFitTable

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 15.7 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)
89  : nBeam_(shp(0)),
90    nIF_(shp(1)),
91    nPol_(shp(2)),
92    nChan_(shp(3)),
93    spectrum_(shp),
94    flags_(shp),
[34]95    tsys_(shp),
[388]96    freqidx_(shp(1)),
97    restfreqidx_(shp(1)) {
[79]98  IPosition ip(2,shp(0),2);
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) {
109  nBeam_ = shp(0);
110  nIF_ = shp(1);
111  nPol_ = shp(2);
112  nChan_ = shp(3);
113  spectrum_.resize(shp);
114  flags_.resize(shp);
115  tsys_.resize(shp);
116  freqidx_.resize(shp(1));
[388]117  restfreqidx_.resize(shp(1));
[79]118  IPosition ip(2,shp(0),2);
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;
150  setSlice (start, end, spec.shape(), spectrum_.shape(),
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// nPol==2
192{
193
[349]194// Get slice and check dim
195
196  IPosition start, end;
197  setSlice (start, end, spec.shape(), spectrum_.shape(),
[417]198            whichBeam, whichIF, False, False);
[349]199
200// Get a reference to the Pol/Chan slice we are interested in
201
202  Array<Float> subArr = spectrum_(start,end);
203
204// Iterate through it and fill
205
206  ReadOnlyVectorIterator<Float> inIt(spec,0);
207  VectorIterator<Float> outIt(subArr,asap::ChanAxis);
[417]208  while (!outIt.pastEnd()) {
[349]209     outIt.vector() = inIt.vector();
210//
211     inIt.next();
212     outIt.next();
[14]213  }
[349]214
[2]215  // unset flags for this spectrum, they might be set again by the
216  // setFlags method
[14]217
[2]218  Array<uChar> arr(flags_(start,end));
219  arr = uChar(0);
[336]220//
221  return True;
[2]222}
223
224
[417]225
226
[453]227Bool SDContainer::setFlags(const Matrix<uChar>& flags,
228                           uInt whichBeam, uInt whichIF,
229                           Bool hasXPol)
[349]230//
231// flags is [nChan,nPol]
232// flags_ is [,,,nChan]
233// How annoying.
[417]234// there are no separate flags for XY so make
235// them up from X and Y
[349]236//
237{
[417]238  if (hasXPol) AlwaysAssert(nPol_==4,AipsError);
239
[349]240// Get slice and check dim
[14]241
[349]242  IPosition start, end;
243  setSlice (start, end, flags.shape(), flags_.shape(),
[417]244            whichBeam, whichIF, False, hasXPol);
[349]245
246// Get a reference to the Pol/Chan slice we are interested in
247
248  Array<uChar> subArr = flags_(start,end);
249
[417]250// Iterate through pol/chan plane  and fill
[349]251
252  ReadOnlyVectorIterator<uChar> inIt(flags,0);
253  VectorIterator<uChar> outIt(subArr,asap::ChanAxis);
254//
[417]255  Vector<uChar> maskPol0;
256  Vector<uChar> maskPol1;
257  Vector<uChar> maskPol01;
258  while (!outIt.pastEnd()) {
259     const IPosition& pos = outIt.pos();
260     if (pos(asap::PolAxis)<2) {
261        outIt.vector() = inIt.vector();
262//
263        if (hasXPol) {
264           if (pos(asap::PolAxis)==0) {
265              maskPol0 = inIt.vector();
266           } else if (pos(asap::PolAxis)==1) {
267              maskPol1 = inIt.vector();
268//
269              maskPol01.resize(maskPol0.nelements());
270              for (uInt i=0; i<maskPol01.nelements(); i++) maskPol01[i] = maskPol0[i]&maskPol1[i];
271           }
272        }
273//
274        inIt.next();
275     } else if (pos(asap::PolAxis)==2) {
276        outIt.vector() = maskPol01;
277     } else if (pos(asap::PolAxis)==3) {
278        outIt.vector() = maskPol01;
279     }
280//
[349]281     outIt.next();
[2]282  }
[349]283//
[16]284  return True;
[2]285}
286
[349]287
[2]288Bool SDContainer::setTsys(const Vector<Float>& tsys,
[417]289                          uInt whichBeam, uInt whichIF,
290                          Bool hasXpol)
[349]291//
292// Tsys does not depend upon channel but is replicated
[417]293// for simplicity of use.
294// There is no Tsys measurement for the cross polarization
295// so I have set TSys for XY to sqrt(Tx*Ty)
[349]296//
297{
298
299// Get slice and check dim
300
301  IPosition start, end;
302  setSlice (start, end, tsys.shape(), tsys_.shape(),
[417]303            whichBeam, whichIF, True, hasXpol);
[349]304
305// Get a reference to the Pol/Chan slice we are interested in
306
307  Array<Float> subArr = tsys_(start,end);
308
309// Iterate through it and fill
310
311  VectorIterator<Float> outIt(subArr,asap::ChanAxis);
312  uInt i=0;
313  while (!outIt.pastEnd()) {
[417]314     const IPosition& pos = outIt.pos();
315//
316     if (pos(asap::PolAxis)<2) {
317       outIt.vector() = tsys(i++);
318     } else {
319       outIt.vector() = sqrt(tsys[0]*tsys[1]);
320     }
321//
[349]322     outIt.next();
[7]323  }
[2]324}
[27]325
[449]326Array<Float> SDContainer::getSpectrum(uInt whichBeam, uInt whichIF)
327//
328// non-const function because of Array(start,end) slicer
329//
330// Input  [nBeam,nIF,nPol,nChan]
331// Output [nChan,nPol]
332//
[125]333{
[27]334
[449]335// Get reference to slice and check dim
[27]336
[449]337  IPosition start, end;
338  setSlice (start, end, spectrum_.shape(), whichBeam, whichIF);
339//
340  Array<Float> dataIn = spectrum_(start,end);
341  Array<Float> dataOut(IPosition(2, nChan_, nPol_));
342//
343  ReadOnlyVectorIterator<Float> itIn(dataIn, asap::ChanAxis);
344  VectorIterator<Float> itOut(dataOut, 0);
345  while (!itOut.pastEnd()) {
346     itOut.vector() = itIn.vector();
347//
348     itIn.next();
349     itOut.next();
[27]350  }
[449]351//
352  return dataOut.copy();
[27]353}
354
[449]355Array<uChar> SDContainer::getFlags(uInt whichBeam, uInt whichIF)
356//
357// non-const function because of Array(start,end) slicer
358//
359// Input  [nBeam,nIF,nPol,nChan]
360// Output [nChan,nPol]
361//
[27]362{
363
[449]364// Get reference to slice and check dim
[27]365
[449]366  IPosition start, end;
367  setSlice (start, end, flags_.shape(), whichBeam, whichIF);
368//
369  Array<uChar> dataIn = flags_(start,end);
370  Array<uChar> dataOut(IPosition(2, nChan_, nPol_));
371//
372  ReadOnlyVectorIterator<uChar> itIn(dataIn, asap::ChanAxis);
373  VectorIterator<uChar> itOut(dataOut, 0);
374  while (!itOut.pastEnd()) {
375     itOut.vector() = itIn.vector();
376//
377     itIn.next();
378     itOut.next();
[27]379  }
[449]380//
381  return dataOut.copy();
[27]382}
383
[449]384Array<Float> SDContainer::getTsys(uInt whichBeam, uInt whichIF)
385//
386// Input  [nBeam,nIF,nPol,nChan]
387// Output [nPol]   (drop channel dependency and select first value)
388//
[27]389{
[449]390// Get reference to slice and check dim
[27]391
[449]392  IPosition start, end;
393  setSlice (start, end, spectrum_.shape(), whichBeam, whichIF);
394//
395  Array<Float> dataIn = tsys_(start,end);
396  Vector<Float> dataOut(nPol_);
397//
398  ReadOnlyVectorIterator<Float> itIn(dataIn, asap::ChanAxis);
399  VectorIterator<Float> itOut(dataOut, 0);
400  uInt i = 0;
401  while (!itIn.pastEnd()) {
402    dataOut[i++] = itIn.vector()[0];
403    itIn.next();
404  }
405//
406  return dataOut.copy();
407}
[27]408
409
410
[449]411Array<Double> SDContainer::getDirection(uInt whichBeam) const
412//
413// Input [nBeam,2]
414// Output [nBeam]
415//
416{
417  Vector<Double> dataOut(2);
418  dataOut(0) = direction_(IPosition(2,whichBeam,0));
419  dataOut(1) = direction_(IPosition(2,whichBeam,1));
420  return dataOut.copy();
[27]421}
[34]422
[79]423
[388]424Bool SDContainer::setFrequencyMap(uInt freqID, uInt whichIF) {
425  freqidx_[whichIF] = freqID;
[34]426  return True;
427}
428
429Bool SDContainer::putFreqMap(const Vector<uInt>& freqs) {
430  freqidx_.resize();
431  freqidx_ = freqs;
432  return True;
433}
434
[388]435Bool SDContainer::setRestFrequencyMap(uInt freqID, uInt whichIF) {
436  restfreqidx_[whichIF] = freqID;
437  return True;
438}
439
440Bool SDContainer::putRestFreqMap(const Vector<uInt>& freqs) {
441  restfreqidx_.resize();
442  restfreqidx_ = freqs;
443  return True;
444}
445
[449]446Bool SDContainer::setDirection(const Vector<Double>& point, uInt whichBeam)
447//
448// Input [2]
449// Output [nBeam,2]
450//
451{
[79]452  if (point.nelements() != 2) return False;
[449]453//
454  Vector<Double> dataOut(2);
455  direction_(IPosition(2,whichBeam,0)) = point[0];
456  direction_(IPosition(2,whichBeam,1)) = point[1];
[79]457  return True;
458}
459
[449]460
[79]461Bool SDContainer::putDirection(const Array<Double>& dir) {
462  direction_.resize();
463  direction_ = dir;
464  return True;
465}
466
[204]467Bool SDContainer::appendHistory(const String& hist)
468{
469  history_.resize(history_.nelements()+1,True);
470  history_[history_.nelements()-1] = hist;
471  return True;
472}
473Bool SDContainer::putHistory(const Vector<String>& hist)
474{
475  history_.resize();
476  history_ = hist;
477  return True;
478}
479
[453]480Bool SDContainer::putFitMap(const Array<Int>& arr) {
481  fitIDMap_.resize();
482  fitIDMap_ = arr;
483  return True;
484}
485
486void SDContainer::setSlice(IPosition& start, IPosition& end,
487                           const IPosition& shpIn, const IPosition& shpOut,
488                           uInt whichBeam, uInt whichIF, Bool tSys,
489                           Bool xPol) const
[349]490//
491// tSYs
492//   shpIn [nPol]
493// else
494//   shpIn [nCHan,nPol]
495//
[417]496// if xPol present, the output nPol = 4 but
497// the input spectra are nPol=2 (tSys) or nPol=2 (spectra)
498//
[349]499{
500  AlwaysAssert(asap::nAxes==4,AipsError);
[417]501  uInt pOff = 0;
502  if (xPol) pOff += 2;
[349]503  if (tSys) {
[417]504     AlwaysAssert(shpOut(asap::PolAxis)==shpIn(0)+pOff,AipsError);     // pol
[349]505  } else {
[417]506     AlwaysAssert(shpOut(asap::ChanAxis)==shpIn(0),AipsError);       // chan
507     AlwaysAssert(shpOut(asap::PolAxis)==shpIn(1)+pOff,AipsError);   // pol
[349]508  }
509//
[453]510  setSlice(start, end, shpOut, whichBeam, whichIF);
[449]511}
512
513
[453]514void SDContainer::setSlice(IPosition& start, IPosition& end,
515                           const IPosition& shape,
516                           uInt whichBeam, uInt whichIF) const
[449]517{
518  AlwaysAssert(asap::nAxes==4,AipsError);
[453]519  //
[349]520  start.resize(asap::nAxes);
521  start = 0;
522  start(asap::BeamAxis) = whichBeam;
523  start(asap::IFAxis) = whichIF;
524//
525  end.resize(asap::nAxes);
[449]526  end = shape-1;
[349]527  end(asap::BeamAxis) = whichBeam;
528  end(asap::IFAxis) = whichIF;
529}
530
531
[388]532uInt SDFrequencyTable::addFrequency(Double refPix, Double refVal, Double inc)
533{
[34]534  if (length() > 0) {
[388]535    for (uInt i=0; i< length();i++) {
536      if (near(refVal,refVal_[i]) &&
537          near(refPix,refPix_[i]) &&
538          near(inc,increment_[i])) {
539         return i;
[34]540      }
541    }
542  }
[388]543
544// Not found - add it
545
[34]546  nFreq_ += 1;
547  refPix_.resize(nFreq_,True);
548  refVal_.resize(nFreq_,True);
549  increment_.resize(nFreq_,True);
550  refPix_[nFreq_-1] = refPix;
551  refVal_[nFreq_-1] = refVal;
552  increment_[nFreq_-1] = inc;
[388]553  return nFreq_-1;
[34]554}
555
[388]556uInt SDFrequencyTable::addRestFrequency(Double val)
[204]557{
[388]558  uInt nFreq = restFreqs_.nelements();
559  if (nFreq>0) {
560    for (uInt i=0; i<nFreq;i++) {
561      if (near(restFreqs_[i],val)) {
562         return i;
[204]563      }
564    }
565  }
[388]566
567// Not found - add it
568
569  nFreq += 1;
570  restFreqs_.resize(nFreq,True);
571  restFreqs_[nFreq-1] = val;
572  return nFreq-1;
[204]573}
[388]574
575
[204]576void SDFrequencyTable::restFrequencies(Vector<Double>& rfs,
577                                       String& rfunit ) const
578{
579  rfs.resize(restFreqs_.nelements());
580  rfs = restFreqs_;
581  rfunit = restFreqUnit_;
582}
[326]583
[453]584// SDFitTable
[326]585
[349]586
[453]587const Vector<Double>& SDFitTable::getFitParameters(uInt whichRow) const
588{
589  if (whichRow <= n_)
590    return fitParms_[whichRow];
591}
592
593const Vector<Bool>& SDFitTable::getFitParameterMask(uInt whichRow) const
594{
595  if (whichRow <= n_)
596    return parMask_[whichRow];
597}
598
599const Vector<Int>& SDFitTable::getFitComponents(uInt whichRow) const
600{
601  if (whichRow <= n_)
602    return fitComps_[whichRow];
603}
604
605const Vector<String>& SDFitTable::getFitFunctions(uInt whichRow) const
606{
607  if (whichRow <= n_)
608    return fitFuncs_[whichRow];
609}
610
611void SDFitTable::putFitParameters(uInt whichRow, const Vector<Double>& arr)
612{
613  if (whichRow <= n_)
614    fitParms_[whichRow] = arr;
615}
616
617void SDFitTable::putFitParameterMask(uInt whichRow, const Vector<Bool>& arr)
618{
619  if (whichRow <= n_)
620    parMask_[whichRow] = arr;
621}
622
623void SDFitTable::putFitComponents(uInt whichRow, const Vector<Int>& arr)
624{
625  if (whichRow <= n_)
626    fitComps_[whichRow] = arr;
627}
628void SDFitTable::putFitFunctions(uInt whichRow, const Vector<String>& arr)
629{
630  if (whichRow <= n_)
631    fitFuncs_[whichRow] = arr;
632}
633
634
[349]635// SDDataDesc
636
[453]637uInt SDDataDesc::addEntry(const String& source, uInt ID,
638                          const MDirection& dir, uInt secID)
[326]639{
640
641// See if already exists
642
643  if (n_ > 0) {
644    for (uInt i=0; i<n_; i++) {
[396]645      if (source==source_[i] && ID==ID_[i]) {
[326]646         return i;
647      }
648    }
649  }
650
651// Not found - add it
652
653  n_ += 1;
654  source_.resize(n_,True);
[396]655  ID_.resize(n_,True);
656  secID_.resize(n_,True);
657  secDir_.resize(n_,True,True);
[326]658//
659  source_[n_-1] = source;
[396]660  ID_[n_-1] = ID;
661  secID_[n_-1] = secID;
662  secDir_[n_-1] = dir;
[326]663//
664  return n_-1;
665}
666
667void SDDataDesc::summary() const
668{
[396]669   if (n_>0) {
670      cerr << "Source    ID" << endl;   
671      for (uInt i=0; i<n_; i++) {
[414]672         cout << setw(11) << source_(i) << ID_(i) << endl;
[396]673      }
[326]674   }
675}
[453]676
Note: See TracBrowser for help on using the repository browser.