Line data Source code
1 : //# Copyright (C) 1998,1999,2000,2001,2003
2 : //# Associated Universities, Inc. Washington DC, USA.
3 : //#
4 : //# This program is free software; you can redistribute it and/or modify it
5 : //# under the terms of the GNU General Public License as published by the Free
6 : //# Software Foundation; either version 2 of the License, or (at your option)
7 : //# any later version.
8 : //#
9 : //# This program 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 General Public License for
12 : //# more details.
13 : //#
14 : //# You should have received a copy of the GNU General Public License along
15 : //# with this program; if not, write to the Free Software Foundation, Inc.,
16 : //# 675 Massachusetts Ave, Cambridge, MA 02139, USA.
17 : //#
18 : //# Correspondence concerning AIPS++ should be addressed as follows:
19 : //# Internet email: aips2-request@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 : //# $Id: $
26 :
27 : #include <imageanalysis/ImageAnalysis/ImageRegridderBase.h>
28 :
29 : namespace casa {
30 :
31 0 : template <class T> ImageRegridderBase<T>::ImageRegridderBase(
32 : const SPCIIT image, const casacore::Record *const regionRec,
33 : const casacore::String& maskInp, const casacore::String& outname,
34 : casacore::Bool overwrite, const casacore::CoordinateSystem& csys,
35 : const casacore::IPosition& axes, const casacore::IPosition& shape
36 : ) : ImageTask<T>(
37 : image, "", regionRec, "", "", "", maskInp, outname, overwrite
38 : ), _csysTo(csys), _axes(axes), _shape(shape),
39 : _specAsVelocity(false), _doRefChange(false),
40 : _replicate(false), _forceRegrid(false), _decimate(10),
41 : _method(casacore::Interpolate2D::LINEAR), _outputStokes(),
42 0 : _nReplicatedChans(0) {
43 0 : ThrowIf(
44 : this->_isPVImage(),
45 : "PV images are not supported. Please first regrid the image from which "
46 : "the PV image was generated, and then create the PV image from that "
47 : "regridded image"
48 : );
49 0 : this->_construct();
50 0 : _finishConstruction();
51 0 : }
52 :
53 0 : template <class T> ImageRegridderBase<T>::~ImageRegridderBase() {}
54 :
55 : template <class T>
56 0 : casacore::Bool ImageRegridderBase<T>::_regriddingDirectionAxes() const {
57 0 : auto dirAxesNumbers = _csysTo.directionAxesNumbers();
58 0 : if (! dirAxesNumbers.empty()) {
59 0 : auto v = dirAxesNumbers.tovector();
60 0 : for (casacore::Int i=0; i<(casacore::Int)_axes.size(); ++i) {
61 0 : if (std::find(v.begin(), v.end(), _axes[i]) != v.end()) {
62 0 : return true;
63 : }
64 : }
65 : }
66 0 : return false;
67 : }
68 :
69 0 : template <class T> void ImageRegridderBase<T>::setDecimate(casacore::Int d) {
70 0 : if (d > 1 && _regriddingDirectionAxes()) {
71 0 : auto dirAxesNumbers = _csysTo.directionAxesNumbers();
72 0 : auto v = dirAxesNumbers.tovector();
73 0 : for (casacore::Int i=0; i<(casacore::Int)_axes.size(); i++) {
74 0 : casacore::Int axis = _axes[i];
75 0 : ThrowIf(
76 : (casacore::Int)_shape[axis] < 3*d
77 : && std::find(v.begin(), v.end(), axis) != v.end(),
78 : "The output image has only "
79 : + casacore::String::toString(_shape[axis])
80 : + " pixels along axis " + casacore::String::toString(axis)
81 : + ", so the maximum value of decimate should "
82 : "be " + casacore::String::toString(_shape[axis]/3)
83 : );
84 : }
85 : }
86 0 : _decimate = d;
87 0 : }
88 :
89 0 : template <class T> void ImageRegridderBase<T>::_finishConstruction() {
90 0 : casacore::Bool shapeSpecified = ! _shape.empty() && _shape[0] >= 0;
91 0 : if (! shapeSpecified) {
92 0 : casacore::IPosition imShape = this->_getImage()->shape();
93 0 : _shape.resize(imShape.size());
94 0 : _shape = imShape;
95 0 : if (this->_getDropDegen()) {
96 0 : casacore::IPosition tmp = _shape.nonDegenerate();
97 0 : _shape.resize(tmp.size());
98 0 : _shape = tmp;
99 : }
100 : }
101 0 : _kludgedShape = _shape;
102 0 : const auto& csysFrom = this->_getImage()->coordinates();
103 : // enforce stokes rules CAS-4960
104 0 : if (
105 : csysFrom.hasPolarizationCoordinate()
106 0 : && _csysTo.hasPolarizationCoordinate()
107 : ) {
108 0 : auto templateStokes = _csysTo.stokesCoordinate().stokes();
109 0 : auto inputStokes = csysFrom.stokesCoordinate().stokes();
110 0 : auto inputPolAxisNumber = csysFrom.polarizationAxisNumber();
111 0 : if (
112 : (
113 0 : _axes.empty()
114 0 : || inputPolAxisNumber < (casacore::Int)_axes.size()
115 0 : ) && templateStokes.size() > 1
116 : ) {
117 0 : if (
118 : (
119 0 : _axes.empty() && inputStokes.size() > 1
120 : )
121 0 : || _axes[inputPolAxisNumber] > 0
122 : ) {
123 0 : auto stokesFrom = csysFrom.stokesCoordinate();
124 0 : auto stokesTo = _csysTo.stokesCoordinate();
125 : casacore::Stokes::StokesTypes valFrom, valTo;
126 0 : for (casacore::uInt i=0; i<inputStokes.size(); i++) {
127 0 : stokesFrom.toWorld(valFrom, i);
128 0 : for (casacore::uInt j=0; j<templateStokes.size(); j++) {
129 0 : stokesTo.toWorld(valTo, j);
130 0 : if (valFrom == valTo) {
131 0 : _outputStokes.push_back(
132 : casacore::Stokes::name(valFrom)
133 : );
134 0 : break;
135 : }
136 : }
137 : }
138 0 : ThrowIf(
139 : _outputStokes.empty(),
140 : "Input image and template coordinate "
141 : "system have no common stokes."
142 : );
143 0 : ThrowIf(
144 : shapeSpecified && (
145 : (casacore::Int)_outputStokes.size()
146 : != _shape[inputPolAxisNumber]
147 : ),
148 : "Specified output stokes axis length ("
149 : + casacore::String::toString(_shape[inputPolAxisNumber])
150 : + ") does not match the number of common stokes ("
151 : + casacore::String::toString(_outputStokes.size())
152 : + ") in the input image and template coordinate system."
153 : );
154 : // This is a kludge to fool the underlying casacore::ImageRegrid
155 : // constructor that the shape is acceptable to it. We copy just
156 : // the stokes we from the output of ImageRegrid.
157 0 : ImageMetaData<T> md(this->_getImage());
158 0 : _kludgedShape[csysFrom.polarizationAxisNumber(false)]
159 0 : = md.nStokes();
160 : }
161 : }
162 : }
163 0 : casacore::Int spectralAxisNumber = csysFrom.spectralAxisNumber(false);
164 0 : if (
165 0 : csysFrom.hasSpectralAxis() && _csysTo.hasSpectralAxis()
166 0 : && this->_getImage()->shape()[spectralAxisNumber] == 1
167 0 : && ! _axes.empty()
168 : ) {
169 0 : casacore::uInt count = 0;
170 0 : for( casacore::Int axis: _axes ) {
171 0 : if (axis == spectralAxisNumber) {
172 0 : *this->_getLog() << casacore::LogIO::NORMAL << "You've "
173 : << "specified explicitly that the spectral axis should be "
174 : << "regridded. However, the input image has a "
175 : << "degenerate spectral axis and so it cannot be "
176 : << "regridded. Instead, the resulting single output "
177 0 : << "channel will be replicated " << _shape[axis]
178 0 : << " times in the output image." << casacore::LogIO::POST;
179 0 : casacore::IPosition newAxes(_axes.size() - 1, 0);
180 0 : casacore::IPosition toRemove(1, count);
181 0 : newAxes = _axes.removeAxes(toRemove);
182 0 : _axes.resize(newAxes.size());
183 0 : _axes = newAxes;
184 0 : _nReplicatedChans = _shape[axis];
185 0 : _kludgedShape[axis] = 1;
186 :
187 0 : break;
188 : }
189 0 : count++;
190 : }
191 : }
192 0 : }
193 :
194 : template <class T> template <class U>
195 0 : void ImageRegridderBase<T>::setConfiguration(
196 : const ImageRegridderBase<U>& that
197 : ) {
198 0 : _method = that._method;
199 0 : _decimate = that._getDecimate();
200 0 : _replicate = that._getReplicate();
201 0 : _doRefChange = that._getDoRefChange();
202 0 : _forceRegrid = that._getForceRegrid();
203 0 : this->setStretch(that._getStretch());
204 0 : _specAsVelocity = that._specAsVelocity;
205 0 : this->setDropDegen(that._getDropDegen());
206 0 : }
207 :
208 : }
|