source: trunk/src/SDContainer.cc@ 467

Last change on this file since 467 was 465, checked in by mar637, 20 years ago

Added SDFitTable to handle fits and expose them to python vi the sdfit class.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.6 KB
Line 
1//#---------------------------------------------------------------------------
2//# SDContainer.cc: A container class for single dish integrations
3//#---------------------------------------------------------------------------
4//# Copyright (C) 2004
5//# ATNF
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//#---------------------------------------------------------------------------
31
32#include <casa/aips.h>
33#include <casa/iostream.h>
34#include <casa/iomanip.h>
35#include <casa/Exceptions.h>
36#include <casa/Utilities/Assert.h>
37#include <tables/Tables/Table.h>
38#include <casa/Arrays/IPosition.h>
39#include <casa/Arrays/Matrix.h>
40#include <casa/Arrays/VectorIter.h>
41#include <casa/Arrays/ArrayMath.h>
42#include <casa/BasicMath/Math.h>
43#include <casa/Quanta/MVTime.h>
44
45
46
47#include "SDDefs.h"
48#include "SDContainer.h"
49
50using namespace casa;
51using namespace asap;
52
53void SDHeader::print() const {
54 MVTime mvt(this->utc);
55 mvt.setFormat(MVTime::YMD);
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): "
66 << mvt
67 << endl;
68 //setprecision(10) << this->utc << endl;
69}
70
71
72SDContainer::SDContainer(uInt nBeam, uInt nIF, uInt nPol, uInt nChan)
73 : nBeam_(nBeam),
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)),
79 tsys_(IPosition(4,nBeam,nIF,nPol,nChan)),
80 freqidx_(nIF),
81 restfreqidx_(nIF),
82 direction_(IPosition(2,nBeam,2)) {
83 uChar x = 0;
84 flags_ = ~x;
85 tcal.resize(2);
86}
87
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),
95 tsys_(shp),
96 freqidx_(shp(1)),
97 restfreqidx_(shp(1)) {
98 IPosition ip(2,shp(0),2);
99 direction_.resize(ip);
100 uChar x = 0;
101 flags_ = ~x;
102 tcal.resize(2);
103}
104
105SDContainer::~SDContainer() {
106}
107
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));
117 restfreqidx_.resize(shp(1));
118 IPosition ip(2,shp(0),2);
119 direction_.resize(ip);
120}
121
122Bool SDContainer::putSpectrum(const Array<Float>& spec) {
123 spectrum_ = spec;
124}
125Bool SDContainer::putFlags(const Array<uChar>& flag) {
126 flags_ = flag;
127}
128Bool SDContainer::putTsys(const Array<Float>& tsys) {
129 tsys_ = tsys;
130}
131
132Bool SDContainer::setSpectrum(const Matrix<Float>& spec,
133 const Vector<Complex>& cSpec,
134 uInt whichBeam, uInt whichIF)
135//
136// spec is [nChan,nPol]
137// cspec is [nChan]
138// spectrum_ is [,,,nChan]
139//
140// nPOl_ = 4 - xx, yy, real(xy), imag(xy)
141//
142{
143 AlwaysAssert(nPol_==4,AipsError);
144
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
194// Get slice and check dim
195
196 IPosition start, end;
197 setSlice (start, end, spec.shape(), spectrum_.shape(),
198 whichBeam, whichIF, False, False);
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);
208 while (!outIt.pastEnd()) {
209 outIt.vector() = inIt.vector();
210//
211 inIt.next();
212 outIt.next();
213 }
214
215 // unset flags for this spectrum, they might be set again by the
216 // setFlags method
217
218 Array<uChar> arr(flags_(start,end));
219 arr = uChar(0);
220//
221 return True;
222}
223
224
225
226
227Bool SDContainer::setFlags(const Matrix<uChar>& flags,
228 uInt whichBeam, uInt whichIF,
229 Bool hasXPol)
230//
231// flags is [nChan,nPol]
232// flags_ is [,,,nChan]
233// How annoying.
234// there are no separate flags for XY so make
235// them up from X and Y
236//
237{
238 if (hasXPol) AlwaysAssert(nPol_==4,AipsError);
239
240// Get slice and check dim
241
242 IPosition start, end;
243 setSlice (start, end, flags.shape(), flags_.shape(),
244 whichBeam, whichIF, False, hasXPol);
245
246// Get a reference to the Pol/Chan slice we are interested in
247
248 Array<uChar> subArr = flags_(start,end);
249
250// Iterate through pol/chan plane and fill
251
252 ReadOnlyVectorIterator<uChar> inIt(flags,0);
253 VectorIterator<uChar> outIt(subArr,asap::ChanAxis);
254//
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//
281 outIt.next();
282 }
283//
284 return True;
285}
286
287
288Bool SDContainer::setTsys(const Vector<Float>& tsys,
289 uInt whichBeam, uInt whichIF,
290 Bool hasXpol)
291//
292// Tsys does not depend upon channel but is replicated
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)
296//
297{
298
299// Get slice and check dim
300
301 IPosition start, end;
302 setSlice (start, end, tsys.shape(), tsys_.shape(),
303 whichBeam, whichIF, True, hasXpol);
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()) {
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//
322 outIt.next();
323 }
324}
325
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//
333{
334
335// Get reference to slice and check dim
336
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();
350 }
351//
352 return dataOut.copy();
353}
354
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//
362{
363
364// Get reference to slice and check dim
365
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();
379 }
380//
381 return dataOut.copy();
382}
383
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//
389{
390// Get reference to slice and check dim
391
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}
408
409
410
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();
421}
422
423
424Bool SDContainer::setFrequencyMap(uInt freqID, uInt whichIF) {
425 freqidx_[whichIF] = freqID;
426 return True;
427}
428
429Bool SDContainer::putFreqMap(const Vector<uInt>& freqs) {
430 freqidx_.resize();
431 freqidx_ = freqs;
432 return True;
433}
434
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
446Bool SDContainer::setDirection(const Vector<Double>& point, uInt whichBeam)
447//
448// Input [2]
449// Output [nBeam,2]
450//
451{
452 if (point.nelements() != 2) return False;
453//
454 Vector<Double> dataOut(2);
455 direction_(IPosition(2,whichBeam,0)) = point[0];
456 direction_(IPosition(2,whichBeam,1)) = point[1];
457 return True;
458}
459
460
461Bool SDContainer::putDirection(const Array<Double>& dir) {
462 direction_.resize();
463 direction_ = dir;
464 return True;
465}
466
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
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
490//
491// tSYs
492// shpIn [nPol]
493// else
494// shpIn [nCHan,nPol]
495//
496// if xPol present, the output nPol = 4 but
497// the input spectra are nPol=2 (tSys) or nPol=2 (spectra)
498//
499{
500 AlwaysAssert(asap::nAxes==4,AipsError);
501 uInt pOff = 0;
502 if (xPol) pOff += 2;
503 if (tSys) {
504 AlwaysAssert(shpOut(asap::PolAxis)==shpIn(0)+pOff,AipsError); // pol
505 } else {
506 AlwaysAssert(shpOut(asap::ChanAxis)==shpIn(0),AipsError); // chan
507 AlwaysAssert(shpOut(asap::PolAxis)==shpIn(1)+pOff,AipsError); // pol
508 }
509//
510 setSlice(start, end, shpOut, whichBeam, whichIF);
511}
512
513
514void SDContainer::setSlice(IPosition& start, IPosition& end,
515 const IPosition& shape,
516 uInt whichBeam, uInt whichIF) const
517{
518 AlwaysAssert(asap::nAxes==4,AipsError);
519 //
520 start.resize(asap::nAxes);
521 start = 0;
522 start(asap::BeamAxis) = whichBeam;
523 start(asap::IFAxis) = whichIF;
524//
525 end.resize(asap::nAxes);
526 end = shape-1;
527 end(asap::BeamAxis) = whichBeam;
528 end(asap::IFAxis) = whichIF;
529}
530
531
532uInt SDFrequencyTable::addFrequency(Double refPix, Double refVal, Double inc)
533{
534 if (length() > 0) {
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;
540 }
541 }
542 }
543
544// Not found - add it
545
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;
553 return nFreq_-1;
554}
555
556uInt SDFrequencyTable::addRestFrequency(Double val)
557{
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;
563 }
564 }
565 }
566
567// Not found - add it
568
569 nFreq += 1;
570 restFreqs_.resize(nFreq,True);
571 restFreqs_[nFreq-1] = val;
572 return nFreq-1;
573}
574
575
576void SDFrequencyTable::restFrequencies(Vector<Double>& rfs,
577 String& rfunit ) const
578{
579 rfs.resize(restFreqs_.nelements());
580 rfs = restFreqs_;
581 rfunit = restFreqUnit_;
582}
583
584// SDDataDesc
585
586uInt SDDataDesc::addEntry(const String& source, uInt ID,
587 const MDirection& dir, uInt secID)
588{
589
590// See if already exists
591
592 if (n_ > 0) {
593 for (uInt i=0; i<n_; i++) {
594 if (source==source_[i] && ID==ID_[i]) {
595 return i;
596 }
597 }
598 }
599
600// Not found - add it
601
602 n_ += 1;
603 source_.resize(n_,True);
604 ID_.resize(n_,True);
605 secID_.resize(n_,True);
606 secDir_.resize(n_,True,True);
607//
608 source_[n_-1] = source;
609 ID_[n_-1] = ID;
610 secID_[n_-1] = secID;
611 secDir_[n_-1] = dir;
612//
613 return n_-1;
614}
615
616void SDDataDesc::summary() const
617{
618 if (n_>0) {
619 cerr << "Source ID" << endl;
620 for (uInt i=0; i<n_; i++) {
621 cout << setw(11) << source_(i) << ID_(i) << endl;
622 }
623 }
624}
625
Note: See TracBrowser for help on using the repository browser.