Line data Source code
1 : //# AntennaResponses.h: AntennaResponses provides access to antenna response data
2 : //# Copyright (C) 1995-1999,2000-2004
3 : //# Associated Universities, Inc. Washington DC, USA
4 : //# Copyright by ESO (in the framework of the ALMA collaboration)
5 : //#
6 : //# This library is free software; you can redistribute it and/or modify it
7 : //# under the terms of the GNU Library General Public License as published by
8 : //# the Free Software Foundation; either version 2 of the License, or (at your
9 : //# option) any later version.
10 : //#
11 : //# This library is distributed in the hope that it will be useful, but WITHOUT
12 : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
14 : //# License for more details.
15 : //#
16 : //# You should have received a copy of the GNU Library General Public License
17 : //# along with this library; if not, write to the Free Software Foundation,
18 : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
19 : //#
20 : //# Correspondence concerning CASA should be addressed as follows:
21 : //# Internet email: casa-feedback@nrao.edu.
22 : //# Postal address: CASA Project Office
23 : //# National Radio Astronomy Observatory
24 : //# 520 Edgemont Road
25 : //# Charlottesville, VA 22903-2475 USA
26 : //#
27 : //#
28 : //# $Id: $
29 :
30 : #ifndef IMAGES_ANTENNARESPONSES_H
31 : #define IMAGES_ANTENNARESPONSES_H
32 :
33 : //# Includes
34 : #include <casacore/casa/aips.h>
35 : #include <casacore/casa/Arrays/Vector.h>
36 : #include <casacore/casa/Exceptions/Error.h>
37 : #include <casacore/measures/Measures/MPosition.h>
38 : #include <casacore/measures/Measures/MDirection.h>
39 : #include <casacore/measures/Measures/MEpoch.h>
40 : #include <casacore/measures/Measures/MFrequency.h>
41 : #include <casacore/measures/Measures/MeasFrame.h>
42 : #include <casacore/measures/Measures/MeasRef.h>
43 : #include <casacore/measures/Measures/MeasTable.h>
44 : #include <casacore/images/Images/TempImage.h>
45 : #include <casacore/casa/OS/Time.h>
46 : #include <casacore/casa/Quanta/MVAngle.h>
47 : #include <casacore/casa/System/AipsrcValue.h>
48 : #include <casacore/casa/BasicSL/String.h>
49 : #include <casacore/casa/ostream.h>
50 :
51 : namespace casa { //# NAMESPACE CASA - BEGIN
52 :
53 :
54 : // <summary>
55 : // AntennaResponses provides access to antenna response data
56 : // </summary>
57 :
58 : // <use visibility=local>
59 :
60 : // <reviewed reviewer="Ger van Diepen, Max Voronkov, Dirk Petry, Remy Indebetouw" date="Jan 2011" tests="tAntennaResponses" demos="">
61 : // </reviewed>
62 :
63 : // <prerequisite>
64 : // <li> <linkto class=casacore::Measure>Measure</linkto> class
65 : // </prerequisite>
66 : //
67 : // <etymology>
68 : //
69 : // </etymology>
70 : //
71 : // <synopsis>
72 : // The location of the AntennaResponses table for a given observatory is set
73 : // in the column casacore::String ANTENNA_RESPONSES in the "Observatories" table (accessed
74 : // via the casacore::MeasTable class).
75 : //
76 : // The detailed rules of how the location and name of the table is derived
77 : // from the string found in ANTENNA_RESPONSES is described further down
78 : // in the comment to the initAntennaResponses() method.
79 : //
80 : // E.g., for ALMA, the location of the table would be
81 : //
82 : // data/alma/AntennaResponses
83 : //
84 : // and the entry in the Observatories table would be simply "alma/AntennaResponses".
85 : //
86 : // "AntennaResponses" is the recommended name of the table but in principle any
87 : // name can be used. That name will then have to be given in the Observatories table.
88 : //
89 : // Contents of the AntennaResponses table:
90 : //
91 : // column 0: casacore::Int BEAM_ID (a unique number in the table for the given observatory name)
92 : // column 1: casacore::String NAME (name of the observatory as in the observatory table)
93 : // column 2: casacore::Int BEAM_NUMBER (for observataories which support several simultaneous beams, zero-based)
94 : // column 3: casacore::Double START_TIME (a casacore::Measure, the time from which onwards this table row is valid)
95 : // column 4: casacore::String ANTENNA_TYPE (for ALMA: "DV", "DA", "PM", or "CM")
96 : // column 5: casacore::String RECEIVER_TYPE (for ALMA this will not be filled, at least for the moment)
97 : // column 6: casacore::Int NUM_SUBBANDS (number of response frequency sub-bands)
98 : // column 7: casacore::Array casacore::String (size set by NUM_SUBBANDS) BAND_NAME (for ALMA: "1", "2" etc.)
99 : // (if there is more than one sub-band per band, the band name repeats)
100 : // column 8: casacore::Array casacore::Double (a casacore::Quantum, size set by NUM_SUBBANDS) SUBBAND_MIN_FREQ
101 : // column 9: casacore::Array casacore::Double (a casacore::Quantum, size set by NUM_SUBBANDS) SUBBAND_MAX_FREQ
102 : // column 10: casacore::MDirection CENTER (the nominal center sky position where this row is valid, default (0.,90.) AZEL)
103 : // column 11: casacore::MDirection VALID_CENTER_MIN (sky position validity range min values, default (0.,0.) AZEL)
104 : // column 12: casacore::MDirection VALID_CENTER_MAX (sky position validity range max values, default (360.,90.) AZEL)
105 : // column 13: casacore::Array casacore::Int (size set by NUM_SUBBANDS) FUNCTION_TYPE
106 : // (uses enum FuncTypes defined below:
107 : // EFP = complex electric field pattern image,
108 : // VP = voltage pattern image,
109 : // AIF = complex aperture illumination function image,
110 : // NA = the function is not yet available,
111 : // here other codes can be easily added, e.g.
112 : // VPMAN = the function is available in casa via the vp manager (details t.b.d.),
113 : // INTERNAL = the function is generated on the fly internally
114 : // using ray-tracing as for the EVLA)
115 : // column 14: casacore::Array casacore::String (size set by NUM_SUBBANDS) FUNCTION_NAME
116 : // (names of the images as paths relative to the directory
117 : // where this table is located,
118 : // empty string if no image is available for the band, e.g.
119 : // "ticra_efield_patterns/melco12m_band6_efp.im")
120 : // column 15: casacore::Array casacore::uInt (size set by NUM_SUBBANDS) FUNCTION_CHANNEL
121 : // (the spectral image channel to use, can be different from 0 in the case
122 : // that several antenna responses are stored in one image file)
123 : // column 16: casacore::Array casacore::Double (a casacore::Quantum, size set by NUM_SUBBANDS) NOMINAL_FREQ
124 : // (the nominal frequency of the channel given by FUNCTION_CHANNEL)
125 : // column 17: casacore::Array casacore::Double (a casacore::Quantum, size set by NUM_SUBBANDS) RESPONSE_ROTATION_OFFSET
126 : // (the angle of an additional constant rotation of the response image)
127 : // project-dependent implementation)
128 : //
129 : // It is assured by the table filling code that columns 10, 11, and 12 use the same casacore::MDirection type.
130 : // </synopsis>
131 : //
132 : // <example>
133 : //
134 : // </example>
135 : //
136 : // <motivation>
137 : // Information on receiver bands and corresponding primary beams
138 : // (in whatever form) for different antenna types needs to be made
139 : // available to the CASA code in a place where imaging code
140 : // can pick it up.
141 : // </motivation>
142 : //
143 : // <todo asof="2001/01/17">
144 : // <li>
145 : // </todo>
146 :
147 : class AntennaResponses {
148 :
149 : public:
150 :
151 : enum FuncTypes{
152 : NA, // not available
153 : AIF, // complex aperture illumination function
154 : EFP, // complex electric field pattern
155 : VP, // real voltage pattern
156 : VPMAN, // the function is available in casa via the vp manager (details t.b.d.)
157 : INTERNAL, // the function is generated on the fly internally
158 : N_FuncTypes,
159 : ANY, // used in requests
160 : INVALID
161 : };
162 : // this can of course be extended for additional types if necessary
163 :
164 : // Constructor, does not call init()
165 1 : AntennaResponses(){};
166 :
167 : // Constructor, calls init()
168 : AntennaResponses(const casacore::String& path);
169 :
170 : // Takes the path (as taken from the new ANTENNA_RESPONSES column of the Observatories table)
171 : // and uses it as the name and location of the AntennaResponses table, and then initializes
172 : // the member vectors;
173 : // can be called repeatedly with different paths;
174 : // each call will overwrite the vectors.
175 : // If the path is an empty string, the member vectors will be reset to empty, i.e.
176 : // this is interpreted to mean that there is no AntennaResponses table on disk.
177 : // Returns true unless for some reason the initialisation fails (other than path=="").
178 : casacore::Bool init(const casacore::String& path="");
179 :
180 : // As init but does not overwrite the table (member vectors) in memory.
181 : // Instead it appends to the vectors.
182 : // Returns false if the path was already read before.
183 : casacore::Bool append(const casacore::String& path);
184 :
185 : // returns true if paths_p has at least one member
186 : casacore::Bool isInit();
187 :
188 : // returns true if path is a member element of paths_p, i.e. the contents of path was read
189 : casacore::Bool isInit(const casacore::String& path);
190 :
191 : // find the row containing the information pertinent to the given parameters
192 : // (this is also the index in the member vectors)
193 : // and the index (subband) to the frequency channel of the response
194 : // return false if no matching row could be found
195 : casacore::Bool getRowAndIndex(casacore::uInt& row, casacore::uInt& subBand,
196 : const casacore::String& obsName,
197 : const casacore::MEpoch& obsTime,
198 : const casacore::MFrequency& freq, // if requFType==INTERNAL, a frequency value of 0 (zero) will return the first row and band found
199 : const FuncTypes& requFType = ANY, // the requested function type
200 : const casacore::String& antennaType = "",
201 : const casacore::MDirection& center = casacore::MDirection(casacore::Quantity( 0., "deg"), // the center to be matched with the CENTER column,
202 : casacore::Quantity(90., "deg"), // default is the Zenith
203 : casacore::MDirection::AZEL), // the center to be matched with the CENTER column
204 : const casacore::String& receiverType = "",
205 : const casacore::Int& beamNumber = 0);
206 :
207 : // overloaded method: as previous method but using beamId
208 : // (instead of obs. time, ant. type, rec. type, center, and beam number)
209 : casacore::Bool getRowAndIndex(casacore::uInt& row, casacore::uInt& subBand,
210 : const casacore::String& obsName,
211 : const casacore::Int& beamId,
212 : const casacore::MFrequency& freq);
213 :
214 : // getRowAndIndex is then used by the following methods
215 :
216 : // Access methods for the response images: takes an observatory name,
217 : // an observation time, the antenna type (e.g. "DV"), the receiverType,
218 : // a frequency, a function type (enum FuncTypes, can be ANY, i.e. take the first available),
219 : // a direction, and a beam number and finds the appropriate image in the AntennaResponses table
220 : // which contains the image of the requested type and returns
221 : // the path, the channel to use, the frequency of that channel, and the FuncType of the image.
222 : // The image will contain a spectral axis even if degenerate.
223 : // The direction axis pair of the stored images is set as follows:
224 : // The axes are parallel to the ones given by the coordinate system type of the CENTER column
225 : // of the AntennaReponses table. The center of the image is that given by the CENTER column.
226 : // Furthermore, the images contain a casacore::Stokes axis (even if degenerate) to express the
227 : // beams for the different polarizations or polarization products.
228 : // Returns false if no appropriate image could be found.
229 : casacore::Bool getImageName(casacore::String& functionImageName, // the path to the image
230 : casacore::uInt& funcChannel, // the channel to use in the image
231 : casacore::MFrequency& nomFreq, // nominal frequency of the image (in the given channel)
232 : FuncTypes& fType, // the function type of the image
233 : casacore::MVAngle& rotAngOffset, // the response rotation angle offset
234 : const casacore::String& obsName, // (the observatory name, e.g. "ALMA" or "ACA")
235 : const casacore::MEpoch& obsTime,
236 : const casacore::MFrequency& freq,
237 : const FuncTypes& requFType = ANY, // the requested function type
238 : const casacore::String& antennaType = "",
239 0 : const casacore::MDirection& center = casacore::MDirection(casacore::Quantity( 0., "deg"), // the center to be matched with the CENTER column,
240 0 : casacore::Quantity(90., "deg"), // default is the Zenith
241 : casacore::MDirection::AZEL),
242 : const casacore::String& receiverType = "",
243 0 : const casacore::Int& beamNumber=0);
244 :
245 : // Overloaded method: returning the validity range
246 : casacore::Bool getImageName(casacore::String& functionImageName, // the path to the image
247 : casacore::uInt& funcChannel, // the channel to use in the image
248 : casacore::MFrequency& nomFreq, // nominal frequency of the image (in the given channel)
249 : casacore::MFrequency& loFreq, // lower end of the frequency validity range
250 : casacore::MFrequency& hiFreq, // upper end of the frequency validity range
251 : FuncTypes& fType, // the function type of the image
252 : casacore::MVAngle& rotAngOffset, // the response rotation angle offset
253 : const casacore::String& obsName, // (the observatory name, e.g. "ALMA" or "ACA")
254 : const casacore::MEpoch& obsTime,
255 : const casacore::MFrequency& freq,
256 : const FuncTypes& requFType = ANY, // the requested function type
257 : const casacore::String& antennaType = "",
258 : const casacore::MDirection& center = casacore::MDirection(casacore::Quantity( 0., "deg"), // the center to be matched with the CENTER column,
259 : casacore::Quantity(90., "deg"), // default is the Zenith
260 : casacore::MDirection::AZEL),
261 : const casacore::String& receiverType = "",
262 0 : const casacore::Int& beamNumber=0);
263 :
264 : // Overloaded method: as previous method but using beamId
265 : // (instead of obs. time, ant. type, rec. type, center, and functype)
266 : casacore::Bool getImageName(casacore::String& functionImageName,
267 : casacore::uInt& funcChannel, // the channel to use in the image
268 : casacore::MFrequency& nomFreq, // nominal frequency of the image (at the given channel)
269 : FuncTypes& fType, // the function type of the image
270 : casacore::MVAngle& rotAngOffset, // the response rotation angle offset
271 : const casacore::String& obsName, // (the observatory name, e.g. "ALMA" or "ACA")
272 : const casacore::Int& beamId,
273 : const casacore::MFrequency& freq);
274 :
275 :
276 : // Get a vector containing all unique antenna type strings for the given constraints
277 : casacore::Bool getAntennaTypes(casacore::Vector<casacore::String>& antTypes,
278 : const casacore::String& obsName, // (the observatory name, e.g. "ALMA" or "ACA")
279 : const casacore::MEpoch& obsTime,
280 : const casacore::MFrequency& freq,
281 : const FuncTypes& requFType = ANY, // the requested function type
282 : const casacore::MDirection& center = casacore::MDirection(casacore::Quantity( 0., "deg"), // the center to be matched with the CENTER column,
283 : casacore::Quantity(90., "deg"), // default is the Zenith
284 : casacore::MDirection::AZEL),
285 : const casacore::String& receiverType = "",
286 0 : const casacore::Int& beamNumber=0);
287 :
288 :
289 : // Put the given row into the present antenna reponses table (in memory).
290 : // If the row exists at the position given by casacore::uInt row, it is overwritten.
291 : // If it doesn't exist, the table is resized by one in memory and the new
292 : // row is added at the last position. The variable "row" then contains the
293 : // actual row that was filled.
294 : // Returns false, if the table was not initialised or the given data was
295 : // not consistent.
296 : // Consistency checks:
297 : // - all vectors have same dimension which is then used to set numSubbands
298 : // - beamId is unique for the given observatory
299 : // - center, validCenterMin, and validCenterMax have the same casacore::MDirection type
300 : casacore::Bool putRow(casacore::uInt& row,
301 : const casacore::String& obsName,
302 : const casacore::Int& beamId,
303 : const casacore::Vector<casacore::String>& bandName,
304 : const casacore::Vector<casacore::MVFrequency>& subbandMinFreq,
305 : const casacore::Vector<casacore::MVFrequency>& subbandMaxFreq,
306 : const casacore::Vector<FuncTypes>& funcType,
307 : const casacore::Vector<casacore::String>& funcName,
308 : const casacore::Vector<casacore::uInt>& funcChannel,
309 : const casacore::Vector<casacore::MVFrequency>& nomFreq,
310 : const casacore::Vector<casacore::MVAngle>& rotAngOffset,
311 : const casacore::String& antennaType = "",
312 : const casacore::MEpoch& startTime = casacore::MEpoch(casacore::MVEpoch(casacore::Quantity(40588., "d")), casacore::MEpoch::UTC), // beginning of 1970
313 : const casacore::MDirection& center = casacore::MDirection(casacore::Quantity( 0., "deg"), // the center to be matched with the CENTER column,
314 : casacore::Quantity(90., "deg"), // default is the Zenith
315 : casacore::MDirection::AZEL),
316 : const casacore::MDirection& validCenterMin = casacore::MDirection(casacore::Quantity( 0., "deg"),
317 : casacore::Quantity( 0., "deg"),
318 : casacore::MDirection::AZEL),
319 : const casacore::MDirection& validCenterMax = casacore::MDirection(casacore::Quantity( 360., "deg"),
320 : casacore::Quantity( 90., "deg"),
321 : casacore::MDirection::AZEL),
322 : const casacore::String& receiverType = "",
323 : const casacore::Int& beamNumber = 0);
324 :
325 : // Create an new AntennaReponses table on disk at the given path
326 : // and fill it with the table contents presently in memory.
327 : // Throw exceptions if there are problems writing the table.
328 : void create(const casacore::String& path);
329 :
330 : // Convert from casacore::Int to FuncType
331 : FuncTypes FuncType(casacore::Int i);
332 :
333 : // Convert from casacore::String to FuncType
334 : static FuncTypes FuncType(const casacore::String& sftyp);
335 :
336 : // get the name of the band corresponding to the frequency (in the rest frame of the observatory)
337 : casacore::Bool getBandName(casacore::String& bandName,
338 : const casacore::String& obsName,
339 : const casacore::MVFrequency& freq);
340 :
341 : private:
342 :
343 : // after initialization, this contains the name of the path where the
344 : // AntennaResponses table was read from;
345 : // if append was used to read additional tables in the memory table,
346 : // then this vector has several elements representing the different tables
347 : casacore::Vector<casacore::String> paths_p;
348 :
349 : // here a complete copy of the AntennaResponses table is stored
350 : casacore::uInt numRows_p;
351 : casacore::Vector<casacore::String> ObsName_p;
352 : casacore::Vector<casacore::MEpoch> StartTime_p;
353 : casacore::Vector<casacore::String> AntennaType_p;
354 : casacore::Vector<casacore::String> ReceiverType_p;
355 : casacore::Vector<casacore::Int> BeamId_p;
356 : casacore::Vector<casacore::Int> BeamNumber_p;
357 : casacore::Vector<casacore::MDirection> ValidCenter_p;
358 : casacore::Vector<casacore::MDirection> ValidCenterMin_p;
359 : casacore::Vector<casacore::MDirection> ValidCenterMax_p;
360 : casacore::Vector<casacore::uInt> NumSubbands_p;
361 : casacore::Vector<casacore::Vector<casacore::String> > BandName_p;
362 : casacore::Vector<casacore::Vector<casacore::MVFrequency> > SubbandMinFreq_p;
363 : casacore::Vector<casacore::Vector<casacore::MVFrequency> > SubbandMaxFreq_p;
364 : casacore::Vector<casacore::Vector<FuncTypes> > FuncType_p;
365 : casacore::Vector<casacore::Vector<casacore::String> > FuncName_p;
366 : casacore::Vector<casacore::Vector<casacore::uInt> > FuncChannel_p;
367 : casacore::Vector<casacore::Vector<casacore::MVFrequency> > NomFreq_p;
368 : casacore::Vector<casacore::Vector<casacore::MVAngle> > RotAngOffset_p;
369 :
370 : // not part of the table but same number of elements:
371 : // memory of the path from which the row was read (index to paths_p)
372 : casacore::Vector<casacore::uInt> pathIndex_p;
373 :
374 : };
375 :
376 :
377 : } //# NAMESPACE CASA - END
378 :
379 : #endif
|