Line data Source code
1 : //# MSMetaInfoForCal.cc: Definition of MSMetaInfoForCal
2 : //# Copyright (C) 2016
3 : //# Associated Universities, Inc. Washington DC, USA.
4 : //#
5 : //# This library is free software; you can redistribute it and/or modify it
6 : //# under the terms of the GNU Library General Public License as published by
7 : //# the Free Software Foundation; either version 2 of the License, or (at your
8 : //# option) any later version.
9 : //#
10 : //# This library is distributed in the hope that it will be useful, but WITHOUT
11 : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 : //# License for more details.
14 : //#
15 : //# You should have received a copy of the GNU Library General Public License
16 : //# along with this library; if not, write to the Free Software Foundation,
17 : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18 : //#
19 : //# Correspondence concerning AIPS++ should be adressed as follows:
20 : //# Internet email: casa-feedback@nrao.edu.
21 : //# Postal address: AIPS++ Project Office
22 : //# National Radio Astronomy Observatory
23 : //# 520 Edgemont Road
24 : //# Charlottesville, VA 22903-2475 USA
25 : //#
26 : //#
27 :
28 :
29 : #include <casacore/ms/MSOper/MSMetaData.h>
30 : #include <casacore/ms/MeasurementSets/MeasurementSet.h>
31 : #include <casacore/tables/Tables/TableUtil.h>
32 : #include <synthesis/MeasurementComponents/MSMetaInfoForCal.h>
33 : #include <msvis/MSVis/SimpleSimVi2.h>
34 : #include <casacore/casa/aips.h>
35 : #include <iostream>
36 :
37 : using namespace casacore;
38 :
39 : namespace casa { //# NAMESPACE CASA - BEGIN
40 :
41 : using namespace vi;
42 :
43 : // Constructor
44 0 : MSMetaInfoForCal::MSMetaInfoForCal(String msname) :
45 0 : msname_(msname),
46 0 : msOk_(False),
47 0 : nAnt_(4),
48 0 : nSpw_(1),
49 0 : nFld_(1),
50 0 : centerFreqs_(0),
51 0 : ms_(NULL),
52 0 : msmd_(NULL),
53 0 : ssp_(NULL)
54 : {
55 :
56 : // If the specified MS is available, make non-trivial meta-info accessors
57 0 : if (Table::isReadable(msname_) &&
58 0 : TableUtil::tableInfo(msname_).type()=="Measurement Set") {
59 :
60 0 : ms_ = new MeasurementSet(msname_);
61 :
62 : // 95% of the size of an Int column, or 50 MB (whichever smaller)
63 : // This ensures that smallish time-to-Id maps will get cached
64 : // (instead of one-off column info needed to calculate them)
65 : // This is appropriate for the the calibration context
66 0 : Float msmdcache=0.95*4.0f*Float(ms_->nrow())/1e6;
67 0 : msmdcache=min(msmdcache,50.0);
68 0 : msmd_ = new MSMetaData(ms_,msmdcache);
69 :
70 : // MS seems to be available
71 0 : msOk_=True;
72 :
73 : // Fill from msmd
74 0 : nAnt_=msmd_->nAntennas();
75 0 : nSpw_=msmd_->nSpw(True);
76 0 : nFld_=msmd_->nFields();
77 :
78 : }
79 : // else, String output will be spoofed
80 :
81 0 : }
82 :
83 : // Construct from a supplied MS object
84 3 : MSMetaInfoForCal::MSMetaInfoForCal(const MeasurementSet& ms) :
85 3 : msname_(ms.tableName()),
86 3 : msOk_(True), // A good MS was supplied, presumably...
87 3 : nAnt_(0),
88 3 : nSpw_(0),
89 3 : nFld_(0),
90 3 : centerFreqs_(0),
91 3 : ms_(NULL), // ... but we won't have our own MS pointer
92 0 : msmd_(new MSMetaData(&ms, // Form MSMetaData directly (not more than 50MB)
93 3 : min(50.0,0.95f*4.0f*Float(ms.nrow())/1e6))),
94 3 : ssp_(NULL)
95 : {
96 : // Fill counters from msmd
97 3 : nAnt_=msmd_->nAntennas();
98 3 : nSpw_=msmd_->nSpw(True);
99 3 : nFld_=msmd_->nFields();
100 3 : }
101 :
102 0 : MSMetaInfoForCal::MSMetaInfoForCal(const MeasurementSet& ms, String msname) :
103 0 : msname_(msname),
104 0 : msOk_(True), // A good MS was supplied, presumably...
105 0 : nAnt_(0),
106 0 : nSpw_(0),
107 0 : nFld_(0),
108 0 : centerFreqs_(0),
109 0 : ms_(NULL), // ... but we won't have our own MS pointer
110 0 : msmd_(new MSMetaData(&ms, // Form MSMetaData directly (not more than 50MB)
111 0 : min(50.0,0.95f*4.0f*Float(ms.nrow())/1e6))),
112 0 : ssp_(NULL)
113 : {
114 : // Fill counters from msmd
115 0 : nAnt_=msmd_->nAntennas();
116 0 : nSpw_=msmd_->nSpw(True);
117 0 : nFld_=msmd_->nFields();
118 0 : }
119 :
120 0 : MSMetaInfoForCal::MSMetaInfoForCal(uInt nAnt,uInt nSpw,uInt nFld) :
121 0 : msname_("<noms>"),
122 0 : msOk_(False),
123 0 : nAnt_(nAnt),
124 0 : nSpw_(nSpw),
125 0 : nFld_(nFld),
126 0 : centerFreqs_(0),
127 0 : ms_(NULL),
128 0 : msmd_(NULL),
129 0 : ssp_(NULL)
130 : {
131 : // Nothing to do
132 0 : }
133 :
134 :
135 : // Construct from SimpleSimVi2Paremeters
136 : // (useful for testing w/ actual (spoofed) data iteration
137 0 : MSMetaInfoForCal::MSMetaInfoForCal(const vi::SimpleSimVi2Parameters& sspar) :
138 0 : msname_("<noms>"),
139 0 : msOk_(False),
140 0 : nAnt_(sspar.nAnt_),
141 0 : nSpw_(sspar.nSpw_),
142 0 : nFld_(sspar.nField_),
143 0 : centerFreqs_(0),
144 0 : ms_(NULL),
145 0 : msmd_(NULL),
146 0 : ssp_(new SimpleSimVi2Parameters(sspar)) // a copy
147 : {
148 : // Nothing to do
149 0 : }
150 :
151 :
152 :
153 : // Destructor
154 3 : MSMetaInfoForCal::~MSMetaInfoForCal()
155 : {
156 3 : if (msmd_)
157 3 : delete msmd_;
158 3 : if (ms_)
159 0 : delete ms_;
160 3 : if (ssp_)
161 0 : delete ssp_;
162 3 : }
163 :
164 : // Return access to MSMetaData object (if avail)
165 0 : MSMetaData& MSMetaInfoForCal::msmd() const {
166 :
167 0 : if (msOk_ && msmd_)
168 0 : return *msmd_;
169 : else
170 0 : throw(AipsError("MSMetaDataForCal::msmd(): No MSMetaData object available!"));
171 : }
172 :
173 0 : const SimpleSimVi2Parameters& MSMetaInfoForCal::ssp() const {
174 0 : if (ssp_)
175 0 : return *ssp_;
176 : else
177 0 : throw(AipsError("MSMetaDataForCal::ssp(): No SimpleSimVi2Parameters object available!"));
178 : }
179 :
180 : // Antenna name, by index
181 0 : String MSMetaInfoForCal::antennaName(uInt iant) const {
182 0 : if (msOk_ && msmd_) {
183 0 : std::map<String, uInt> mymap;
184 0 : vector<uInt> ids(1);
185 0 : ids[0]=iant;
186 0 : uInt nAnt=msmd_->nAntennas();
187 0 : if (iant < nAnt)
188 0 : return msmd_->getAntennaNames(mymap,ids)[0];
189 : else {
190 0 : throw(AipsError(
191 0 : "Specified iant="+
192 0 : String::toString(iant)+
193 0 : " > nAnt="+
194 0 : String::toString(nAnt)));
195 : }
196 0 : }
197 : else {
198 0 : if (iant < nAnt_)
199 0 : return "AntennaId"+String::toString(iant);
200 : else {
201 0 : throw(AipsError(
202 0 : "Specified iant="+
203 0 : String::toString(iant)+
204 0 : " > nAnt="+
205 0 : String::toString(nAnt_)));
206 : }
207 : }
208 : }
209 :
210 : // Antenna names list, by index
211 0 : void MSMetaInfoForCal::antennaNames(Vector<String>& antnames) const {
212 0 : if (msOk_ && msmd_) {
213 0 : std::map<String, uInt> mymap;
214 0 : Vector<String> asV(msmd_->getAntennaNames(mymap));
215 0 : antnames.reference(asV);
216 0 : }
217 : else {
218 0 : antnames.resize(nAnt_);
219 0 : for (uInt iant=0;iant<nAnt_;++iant)
220 0 : antnames[iant]="AntennaId"+String::toString(iant);
221 : }
222 0 : }
223 :
224 : // Field name, by index
225 0 : String MSMetaInfoForCal::spwName(uInt ispw) const {
226 :
227 0 : if (msOk_ && msmd_) {
228 0 : uInt nSpw=msmd_->nSpw(True);
229 0 : if (ispw<nSpw)
230 0 : return msmd_->getSpwNames()[ispw];
231 : else {
232 0 : throw(AipsError(
233 0 : "Specified ispw="+
234 0 : String::toString(ispw)+
235 0 : " > nSpw="+
236 0 : String::toString(nSpw)));
237 : }
238 : }
239 : else
240 0 : if (ispw<nSpw_)
241 0 : return "SpwId"+String::toString(ispw);
242 : else {
243 0 : throw(AipsError(
244 0 : "Specified ispw="+
245 0 : String::toString(ispw)+
246 0 : " > nSpw="+
247 0 : String::toString(nSpw_)));
248 : }
249 :
250 : }
251 :
252 : // Field name, by index
253 0 : String MSMetaInfoForCal::fieldName(uInt ifld) const {
254 :
255 0 : if (msOk_ && msmd_) {
256 0 : vector<uInt> ids(1);
257 0 : ids[0]=ifld;
258 0 : uInt nFld=msmd_->nFields();
259 0 : if (ifld<nFld)
260 0 : return msmd_->getFieldNamesForFieldIDs(ids)[0];
261 : else {
262 0 : throw(AipsError(
263 0 : "Specified ifld="+
264 0 : String::toString(ifld)+
265 0 : " > nFld="+
266 0 : String::toString(nFld)));
267 : }
268 0 : }
269 : else
270 0 : if (ifld<nFld_)
271 0 : return "FieldId"+String::toString(ifld);
272 : else {
273 0 : throw(AipsError(
274 0 : "Specified ifld="+
275 0 : String::toString(ifld)+
276 0 : " > nFld="+
277 0 : String::toString(nFld_)));
278 : }
279 :
280 : }
281 :
282 0 : void MSMetaInfoForCal::fieldNames(Vector<String>& fldnames) const {
283 0 : if (msOk_ && msmd_) {
284 0 : Vector<String> asV(msmd_->getFieldNames());
285 0 : fldnames.reference(asV);
286 0 : }
287 : else {
288 0 : fldnames.resize(nFld_);
289 0 : for (uInt ifld=0;ifld<nFld_;++ifld)
290 0 : fldnames[ifld]="FieldId"+String::toString(ifld);
291 : }
292 0 : }
293 :
294 : // Field id at time
295 0 : Int MSMetaInfoForCal::fieldIdAtTime(Double time) const {
296 0 : if (msOk_ && msmd_) {
297 : // Assume 0.1s is adequate time resolution (may need to revisit?)
298 0 : return *(msmd_->getFieldsForTimes(time,0.1).begin());
299 : }
300 : else
301 0 : return -1; // no information, essentially
302 : }
303 :
304 : // Scan number at time
305 0 : Int MSMetaInfoForCal::scanNumberAtTime(Double time) const {
306 0 : if (msOk_ && msmd_) {
307 : // Assume 0.1s is adequate time resolution (may need to revisit?)
308 0 : return *(msmd_->getScansForTimes(time,0.1,-1,-1).begin());
309 : }
310 : else
311 0 : return -1; // no information, essentially
312 :
313 : }
314 :
315 0 : Double MSMetaInfoForCal::centerFreq(uInt ispw) const {
316 :
317 : // If centerFreqs_ not yet filled, do it
318 0 : if (centerFreqs_.nelements()==0) {
319 0 : if (msOk_ && msmd_) {
320 0 : centerFreqs_.resize(nSpw());
321 0 : vector<Quantity> centerFreqQ=msmd_->getCenterFreqs();
322 0 : for (uInt ispw=0;ispw<nSpw();++ispw) {
323 0 : centerFreqs_[ispw]=centerFreqQ[ispw].getValue("GHz");
324 : }
325 0 : }
326 : }
327 :
328 : // Return value for requested spw, if available
329 0 : if ( ispw<centerFreqs_.nelements() ) {
330 0 : return centerFreqs_[ispw];
331 : }
332 : else {
333 0 : return 0.0f;
334 :
335 : }
336 : }
337 :
338 :
339 : } //# NAMESPACE CASA - END
|