Line data Source code
1 : //# Copyright (C) 2009
2 : //# Associated Universities, Inc. Washington DC, USA.
3 : //#
4 : //# This library is free software; you can redistribute it and/or modify it
5 : //# under the terms of the GNU Library General Public License as published by
6 : //# the Free Software Foundation; either version 2 of the License, or (at your
7 : //# option) any later version.
8 : //#
9 : //# This library is distributed in the hope that it will be useful, but WITHOUT
10 : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 : //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12 : //# License for more details.
13 : //#
14 : //# You should have received a copy of the GNU Library General Public License
15 : //# along with this library; if not, write to the Free Software Foundation,
16 : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
17 : //#
18 : //# Correspondence concerning AIPS++ should be addressed as follows:
19 : //# Internet email: casa-feedback@nrao.edu.
20 : //# Postal address: AIPS++ Project Office
21 : //# National Radio Astronomy Observatory
22 : //# 520 Edgemont Road
23 : //# Charlottesville, VA 22903-2475 USA
24 : //#
25 :
26 : #include <imageanalysis/ImageAnalysis/ImageMetaData.h>
27 :
28 : #include <casacore/casa/Logging/LogFilter.h>
29 :
30 : #include <casacore/casa/aips.h>
31 :
32 : #include <casacore/images/Images/ImageSummary.h>
33 :
34 :
35 : #ifndef IMAGEANALYSIS_IMAGEMETADATA_TCC
36 : #define IMAGEANALYSIS_IMAGEMETADATA_TCC
37 :
38 : using namespace casacore;
39 :
40 : namespace casa {
41 :
42 0 : template <class T> ImageMetaData<T>::ImageMetaData(
43 : SPCIIT image
44 0 : ) : ImageMetaDataBase<T>(image), _image(image), _info(image->imageInfo()),
45 0 : _csys(image->coordinates()) {}
46 :
47 0 : template<class T> String ImageMetaData<T>::_getBrightnessUnit() const {
48 0 : return _image->units().getName();
49 : }
50 :
51 : template<class T> casacore::Record ImageMetaData<T>::summary(
52 : const casacore::String& doppler, const casacore::Bool list,
53 : const casacore::Bool pixelorder, const casacore::Bool verbose
54 : ) {
55 : auto log = this->_getLog();
56 : log << casacore::LogOrigin("ImageMetaData", __func__);
57 : casacore::Vector<casacore::String> messages;
58 : casacore::Record retval;
59 : casacore::ImageSummary<T> s(*_image);
60 : casacore::MDoppler::Types velType;
61 : if (!casacore::MDoppler::getType(velType, doppler)) {
62 : log << casacore::LogIO::WARN << "Illegal velocity type, using RADIO"
63 : << casacore::LogIO::POST;
64 : velType = casacore::MDoppler::RADIO;
65 : }
66 :
67 : if (list) {
68 : messages = s.list(log, velType, false, verbose);
69 : }
70 : else {
71 : // Write messages to local sink only so we can fish them out again
72 : casacore::LogFilter filter;
73 : casacore::LogSink sink(filter, false);
74 : casacore::LogIO osl(sink);
75 : messages = s.list(osl, velType, true);
76 : }
77 : retval.define("messages", messages);
78 : auto axes = s.axisNames(pixelorder);
79 : auto crpix = s.referencePixels(false); // 0-rel
80 : auto crval = s.referenceValues(pixelorder);
81 : auto cdelt = s.axisIncrements(pixelorder);
82 : auto axisunits = s.axisUnits(pixelorder);
83 :
84 : auto shape = this->_getShape();
85 : retval.define("ndim", (casacore::Int)shape.size());
86 : retval.define("shape", shape.asVector());
87 : retval.define("tileshape", s.tileShape().asVector());
88 : retval.define("axisnames", axes);
89 : retval.define("refpix", crpix);
90 : retval.define("refval", crval);
91 : retval.define("incr", cdelt);
92 : retval.define("axisunits", axisunits);
93 : retval.define("unit", _getBrightnessUnit());
94 : retval.define("hasmask", s.hasAMask());
95 : retval.define("defaultmask", s.defaultMaskName());
96 : retval.define("masks", s.maskNames());
97 : retval.define("imagetype", _getImType());
98 :
99 : const auto& info = _image->imageInfo();
100 : casacore::Record iRec;
101 : casacore::String error;
102 : using casacore::AipsError;
103 : ThrowIf(
104 : ! info.toRecord(error, iRec),
105 : "Failed to convert ImageInfo to a record because "
106 : );
107 : if (iRec.isDefined("restoringbeam")) {
108 : retval.defineRecord("restoringbeam", iRec.asRecord("restoringbeam"));
109 : }
110 : else if (iRec.isDefined("perplanebeams")) {
111 : retval.defineRecord("perplanebeams", info.beamToRecord(-1, -1));
112 : }
113 : return retval;
114 : }
115 :
116 0 : template <class T> Record ImageMetaData<T>::toRecord(Bool verbose) const {
117 0 : if (_header.empty()) {
118 0 : _header = this->_makeHeader();
119 : }
120 0 : if (verbose) {
121 0 : this->_toLog(_header);
122 : }
123 0 : return _header;
124 : }
125 :
126 0 : template <class T> Vector<String> ImageMetaData<T>::_getAxisNames() const {
127 0 : if (_axisNames.empty()) {
128 0 : _axisNames = _getCoords().worldAxisNames();
129 : }
130 0 : return _axisNames;
131 : }
132 :
133 0 : template <class T> Vector<String> ImageMetaData<T>::_getAxisUnits() const {
134 0 : if (_axisUnits.empty()) {
135 0 : _axisUnits = _getCoords().worldAxisUnits();
136 : }
137 0 : return _axisUnits;
138 : }
139 :
140 0 : template <class T> GaussianBeam ImageMetaData<T>::_getBeam() const {
141 0 : const ImageInfo& info = _getInfo();
142 0 : if (info.hasSingleBeam()) {
143 0 : if (_beam == GaussianBeam::NULL_BEAM) {
144 0 : _beam = info.restoringBeam(-1, -1);
145 : }
146 0 : return _beam;
147 : }
148 0 : else if (info.hasMultipleBeams()) {
149 0 : throw AipsError("This image has multiple beams.");
150 : }
151 : else {
152 0 : throw AipsError("This image has no beam(s).");
153 : }
154 : }
155 :
156 0 : template <class T> String ImageMetaData<T>::_getEquinox() const {
157 0 : if (_equinox.empty()) {
158 0 : if (_getCoords().hasDirectionCoordinate()) {
159 0 : _equinox = MDirection::showType(
160 0 : _getCoords().directionCoordinate().directionType()
161 : );
162 : }
163 : }
164 0 : return _equinox;
165 : }
166 :
167 0 : template <class T> String ImageMetaData<T>::_getImType() const {
168 0 : if (_imtype.empty()) {
169 0 : _imtype = ImageInfo::imageType(_getInfo().imageType());
170 : }
171 0 : return _imtype;
172 : }
173 :
174 0 : template <class T> vector<Quantity> ImageMetaData<T>::_getIncrements() const {
175 0 : if (_increment.size() == 0) {
176 0 : Vector<Double> incs = _getCoords().increment();
177 0 : Vector<String> units = _getAxisUnits();
178 0 : for (uInt i=0; i<incs.size(); i++) {
179 0 : _increment.push_back(Quantity(incs[i], units[i]));
180 : }
181 0 : }
182 0 : return _increment;
183 : }
184 :
185 0 : template <class T> String ImageMetaData<T>::_getObject() const {
186 0 : if (_object.empty()) {
187 0 : _object = _getInfo().objectName();
188 : }
189 0 : return _object;
190 : }
191 :
192 0 : template <class T> Vector<String> ImageMetaData<T>::_getMasks() const {
193 0 : if (_masks.empty()) {
194 0 : _masks = _image->regionNames(RegionHandler::Masks);
195 : }
196 0 : return _masks;
197 : }
198 :
199 0 : template <class T> MEpoch ImageMetaData<T>::_getObsDate() const {
200 0 : if (_obsdate.get("s") == 0) {
201 0 : _obsdate = _getCoords().obsInfo().obsDate();
202 : }
203 0 : return _obsdate;
204 : }
205 :
206 0 : template <class T> String ImageMetaData<T>::_getObserver() const {
207 0 : if (_observer.empty()) {
208 0 : _observer = _getCoords().obsInfo().observer();
209 : }
210 0 : return _observer;
211 : }
212 :
213 0 : template <class T> String ImageMetaData<T>::_getProjection() const {
214 0 : if (_projection.empty()) {
215 0 : _projection = ImageMetaDataBase<T>::_getProjection();
216 : }
217 0 : return _projection;
218 : }
219 :
220 0 : template <class T> Vector<Double> ImageMetaData<T>::_getRefPixel() const {
221 0 : if (_refPixel.size() == 0) {
222 0 : _refPixel = _getCoords().referencePixel();
223 : }
224 0 : return _refPixel;
225 : }
226 :
227 0 : template <class T> Vector<String> ImageMetaData<T>::_getStokes() const {
228 0 : const CoordinateSystem csys = _getCoords();
229 0 : ThrowIf(
230 : ! csys.hasPolarizationCoordinate(),
231 : "Logic Error: coordinate system does not have a polarization coordinate"
232 : );
233 0 : if (_stokes.empty()) {
234 0 : _stokes = csys.stokesCoordinate().stokesStrings();
235 : }
236 0 : return _stokes;
237 0 : }
238 :
239 0 : template <class T> Vector<Quantity> ImageMetaData<T>::_getRefValue() const {
240 0 : if (_refVal.size() == 0) {
241 0 : Vector<Double> vals = _getCoords().referenceValue();
242 0 : Vector<String> units = _getAxisUnits();
243 0 : for (uInt i=0; i<vals.size(); i++) {
244 0 : _refVal.push_back(Quantity(vals[i], units[i]));
245 : }
246 0 : }
247 0 : return Vector<Quantity>(_refVal);
248 : }
249 :
250 0 : template <class T> String ImageMetaData<T>::_getRefFreqType() const {
251 0 : if (_reffreqtype.empty() && _getCoords().hasSpectralAxis()) {
252 0 : _reffreqtype = MFrequency::showType(
253 0 : _getCoords().spectralCoordinate().frequencySystem(false)
254 : );
255 : }
256 0 : return _reffreqtype;
257 : }
258 :
259 0 : template <class T> Quantity ImageMetaData<T>::_getRestFrequency() const {
260 0 : const CoordinateSystem& csys = _getCoords();
261 0 : ThrowIf(
262 : ! csys.hasSpectralAxis(),
263 : "Image has no spectral axis so there is no rest frequency"
264 : );
265 0 : if (_restFreq.getValue() == 0) {
266 0 : _restFreq = Quantity(
267 0 : csys.spectralCoordinate().restFrequency(),
268 0 : csys.spectralCoordinate().worldAxisUnits()[0]
269 : );
270 : }
271 0 : return _restFreq;
272 : }
273 :
274 0 : template <class T> Record ImageMetaData<T>::_getStatistics() const {
275 0 : if (_stats.empty() && isReal(_image->dataType())) {
276 0 : _stats = this->_calcStats();
277 : }
278 0 : return _stats;
279 : }
280 :
281 0 : template <class T> String ImageMetaData<T>::_getTelescope() const {
282 0 : if (_telescope.empty()) {
283 0 : _telescope = _getCoords().obsInfo().telescope();
284 : }
285 0 : return _telescope;
286 : }
287 :
288 : }
289 :
290 : #endif
|