Line data Source code
1 : /*
2 : * ImageReorderer.cc
3 : *
4 : * Created on: May 7, 2010
5 : * Author: dmehring
6 : */
7 :
8 : #include <imageanalysis/ImageAnalysis/ImageTransposer.h>
9 :
10 : #include <casacore/images/Images/ImageUtilities.h>
11 : #include <casacore/images/Images/PagedImage.h>
12 : #include <casacore/images/Images/TempImage.h>
13 :
14 : #include <imageanalysis/ImageAnalysis/SubImageFactory.h>
15 :
16 : using namespace casacore;
17 : namespace casa {
18 :
19 : const String ImageTransposer::_class = "ImageTransposer";
20 :
21 0 : ImageTransposer::ImageTransposer(
22 : const SPCIIF image, const String& order, const String& outputImage
23 0 : )
24 : : ImageTask<Float>(
25 : image, "", 0, "", "", "",
26 : "", outputImage, false
27 : ),
28 0 : _order(Vector<Int>(0)), _reverse(IPosition(0)) {
29 0 : LogOrigin origin(_class, String(__FUNCTION__) + "_1");
30 0 : *_getLog() << origin;
31 : //_construct();
32 0 : *_getLog() << origin;
33 0 : Regex intRegex("^(-?[0-9])+$");
34 0 : if (order.matches(intRegex)) {
35 0 : _order = _getOrder(order);
36 : }
37 : else {
38 0 : *_getLog() << "Incorrect order specification " << order
39 0 : << ". All characters must be digits." << LogIO::EXCEPTION;
40 : }
41 0 : }
42 :
43 0 : ImageTransposer::ImageTransposer(
44 : const SPCIIF image, const Vector<String> order,
45 : const String& outputImage
46 0 : )
47 : : ImageTask<Float>(
48 : image, "", 0, "", "", "",
49 : "", outputImage, false
50 0 : ), _order(Vector<Int>()), _reverse(IPosition(0)) {
51 0 : LogOrigin origin(_class, String(__FUNCTION__) + "_2");
52 0 : *_getLog() << origin;
53 : //_construct();
54 0 : *_getLog() << origin;
55 0 : Vector<String> orderCopy = order;
56 0 : std::vector<Bool> rev(orderCopy.size());
57 0 : uInt nRev = 0;
58 :
59 0 : for (uInt i=0; i<orderCopy.size(); i++) {
60 0 : if (orderCopy[i].startsWith("-")) {
61 0 : orderCopy[i] = orderCopy[i].substr(1);
62 0 : rev[i] = true;
63 0 : nRev++;
64 : }
65 : else {
66 0 : rev[i] = false;
67 : }
68 : }
69 0 : _order = _getImage()->coordinates().getWorldAxesOrder(orderCopy, true);
70 0 : uInt n = 0;
71 0 : if (nRev > 0) {
72 0 : _reverse.resize(nRev);
73 0 : for (uInt i=0; i<orderCopy.size(); i++) {
74 0 : if (rev[i]) {
75 0 : _reverse[n] = _order[i];
76 0 : n++;
77 : }
78 : }
79 : }
80 0 : *_getLog() << "Old to new axis mapping is " << _order << LogIO::NORMAL;
81 0 : }
82 :
83 0 : ImageTransposer::ImageTransposer(
84 : const SPCIIF image, uInt order,
85 : const String& outputImage
86 0 : )
87 : : ImageTask<Float>(
88 : image, "", 0, "", "", "",
89 : "", outputImage, false
90 0 : ), _order(Vector<Int>()), _reverse(IPosition(0)) {
91 0 : LogOrigin origin(_class, String(__FUNCTION__) + "_3");
92 0 : *_getLog() << origin;
93 : //_construct();
94 0 : *_getLog() << origin;
95 0 : _order = _getOrder(order);
96 0 : }
97 :
98 0 : SPIIF ImageTransposer::transpose() const {
99 0 : *_getLog() << LogOrigin(_class, __FUNCTION__);
100 : // get the image data
101 0 : Array<Float> dataCopy = _getImage()->get();
102 0 : CoordinateSystem newCsys = _getImage()->coordinates();
103 0 : IPosition shape = _getImage()->shape();
104 0 : if (_reverse.size() > 0) {
105 0 : Vector<Double> refPix = newCsys.referencePixel();
106 0 : Vector<Double> inc = newCsys.increment();
107 0 : for (
108 0 : IPosition::const_iterator iter=_reverse.begin();
109 0 : iter!=_reverse.end(); iter++
110 : ) {
111 0 : refPix[*iter] = shape[*iter] - 1 - refPix[*iter];
112 0 : inc[*iter] *= -1;
113 : }
114 0 : newCsys.setReferencePixel(refPix);
115 0 : newCsys.setIncrement(inc);
116 : }
117 0 : newCsys.transpose(_order, _order);
118 0 : IPosition newShape(_order.size());
119 0 : for (uInt i=0; i<newShape.size(); ++i) {
120 0 : newShape[i] = shape[_order[i]];
121 : }
122 : SPIIF output(
123 0 : new TempImage<Float>(TiledShape(newShape), newCsys)
124 0 : );
125 0 : if (_reverse.size() > 0) {
126 0 : dataCopy = reverseArray(dataCopy, _reverse);
127 : }
128 0 : output->put(reorderArray(dataCopy, _order));
129 0 : if (_getImage()->hasPixelMask()) {
130 : std::unique_ptr<Lattice<Bool> > maskLattice(
131 0 : _getImage()->pixelMask().clone()
132 0 : );
133 0 : Array<Bool> maskCopy = maskLattice->get();
134 0 : if (_reverse.size() > 0) {
135 0 : maskCopy = reverseArray(maskCopy, _reverse);
136 : }
137 0 : dynamic_cast<TempImage<Float> *>(output.get())->attachMask(
138 0 : ArrayLattice<Bool>(reorderArray(maskCopy, _order))
139 0 : );
140 : }
141 0 : ImageUtilities::copyMiscellaneous(*output, *this->_getImage());
142 0 : return this->_prepareOutputImage(*output);
143 : }
144 :
145 0 : ImageTransposer::~ImageTransposer() {}
146 :
147 0 : Vector<Int> ImageTransposer::_getOrder(uInt order) const {
148 0 : *_getLog() << LogOrigin(_class, String(__func__));
149 0 : uInt naxes = _getImage()->ndim();
150 0 : uInt raxes = uInt(log10(order)) + 1;
151 0 : if (naxes != raxes) {
152 0 : istringstream is;
153 0 : is >> order;
154 0 : if (! String(is.str()).contains("0")) {
155 0 : raxes++;
156 : }
157 : }
158 0 : if (raxes != naxes) {
159 0 : *_getLog() << "Image has " << naxes << " axes but " << raxes
160 : << " were given for reordering. Number of axes to reorder must match the number of image axes"
161 0 : << LogIO::EXCEPTION;
162 : }
163 0 : if (raxes > 10) {
164 0 : *_getLog() << "Only images with less than 10 axes can currently be reordered. This image has "
165 0 : << naxes << " axes" << LogIO::EXCEPTION;
166 : }
167 0 : Vector<Int> myorder(naxes);
168 0 : uInt mag = 1;
169 0 : for (uInt i=1; i<myorder.size(); i++) {
170 0 : mag *= 10;
171 : }
172 0 : uInt scratchOrder = order;
173 0 : for (uInt i=0; i<myorder.size(); i++) {
174 0 : uInt index = scratchOrder/mag;
175 0 : if (index >= naxes) {
176 0 : *_getLog() << "Image does not contain zero-based axis number " << index
177 : << " but this was incorrectly specified in order parameter. "
178 : << order << " All digits in the order parameter must be greater "
179 : << "than or equal to zero and less than the number of image axes."
180 0 : << LogIO::EXCEPTION;
181 : }
182 0 : for (uInt j=0; j<i; j++) {
183 0 : if ((Int)index == myorder[j]) {
184 0 : *_getLog() << "Axis number " << index
185 : << " specified multiple times in order parameter "
186 : << order << " . It can only be specified once."
187 0 : << LogIO::EXCEPTION;
188 : }
189 : }
190 0 : myorder[i] = index;
191 0 : scratchOrder -= index*mag;
192 0 : mag /= 10;
193 : }
194 0 : return myorder;
195 : }
196 :
197 0 : Vector<Int> ImageTransposer::_getOrder(const String& order) {
198 0 : String orderCopy = order;
199 0 : if (orderCopy.contains('-', 0)) {
200 0 : uInt maxn = orderCopy.freq('-') + 1;
201 0 : String *parts = new String[maxn];
202 0 : split(order, parts, maxn, '-');
203 : // disregard the first element because that won't have a -
204 0 : _reverse.resize(maxn - 1);
205 0 : orderCopy = parts[0];
206 0 : for (uInt i=1; i<maxn; i++) {
207 0 : _reverse[i-1] = String::toInt(parts[i].substr(0, 1));
208 0 : orderCopy += parts[i];
209 : }
210 0 : delete [] parts;
211 :
212 : }
213 0 : return _getOrder(String::toInt(orderCopy));
214 : }
215 :
216 : }
|