source: trunk/src/SDContainer.cc@ 456

Last change on this file since 456 was 453, checked in by mar637, 20 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
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// SDFitTable
585
586
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
635// SDDataDesc
636
637uInt SDDataDesc::addEntry(const String& source, uInt ID,
638 const MDirection& dir, uInt secID)
639{
640
641// See if already exists
642
643 if (n_ > 0) {
644 for (uInt i=0; i<n_; i++) {
645 if (source==source_[i] && ID==ID_[i]) {
646 return i;
647 }
648 }
649 }
650
651// Not found - add it
652
653 n_ += 1;
654 source_.resize(n_,True);
655 ID_.resize(n_,True);
656 secID_.resize(n_,True);
657 secDir_.resize(n_,True,True);
658//
659 source_[n_-1] = source;
660 ID_[n_-1] = ID;
661 secID_[n_-1] = secID;
662 secDir_[n_-1] = dir;
663//
664 return n_-1;
665}
666
667void SDDataDesc::summary() const
668{
669 if (n_>0) {
670 cerr << "Source ID" << endl;
671 for (uInt i=0; i<n_; i++) {
672 cout << setw(11) << source_(i) << ID_(i) << endl;
673 }
674 }
675}
676
Note: See TracBrowser for help on using the repository browser.