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 19 : ImageTransposer::ImageTransposer(
22 : const SPCIIF image, const String& order, const String& outputImage
23 19 : )
24 : : ImageTask<Float>(
25 : image, "", 0, "", "", "",
26 : "", outputImage, false
27 : ),
28 19 : _order(Vector<Int>(0)), _reverse(IPosition(0)) {
29 38 : LogOrigin origin(_class, String(__FUNCTION__) + "_1");
30 19 : *_getLog() << origin;
31 : //_construct();
32 19 : *_getLog() << origin;
33 19 : Regex intRegex("^(-?[0-9])+$");
34 19 : if (order.matches(intRegex)) {
35 19 : _order = _getOrder(order);
36 : }
37 : else {
38 0 : *_getLog() << "Incorrect order specification " << order
39 0 : << ". All characters must be digits." << LogIO::EXCEPTION;
40 : }
41 31 : }
42 :
43 9 : ImageTransposer::ImageTransposer(
44 : const SPCIIF image, const Vector<String> order,
45 : const String& outputImage
46 9 : )
47 : : ImageTask<Float>(
48 : image, "", 0, "", "", "",
49 : "", outputImage, false
50 9 : ), _order(Vector<Int>()), _reverse(IPosition(0)) {
51 18 : LogOrigin origin(_class, String(__FUNCTION__) + "_2");
52 9 : *_getLog() << origin;
53 : //_construct();
54 9 : *_getLog() << origin;
55 9 : Vector<String> orderCopy = order;
56 9 : std::vector<Bool> rev(orderCopy.size());
57 9 : uInt nRev = 0;
58 :
59 37 : for (uInt i=0; i<orderCopy.size(); i++) {
60 28 : if (orderCopy[i].startsWith("-")) {
61 0 : orderCopy[i] = orderCopy[i].substr(1);
62 0 : rev[i] = true;
63 0 : nRev++;
64 : }
65 : else {
66 28 : rev[i] = false;
67 : }
68 : }
69 13 : _order = _getImage()->coordinates().getWorldAxesOrder(orderCopy, true);
70 5 : uInt n = 0;
71 5 : 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 5 : *_getLog() << "Old to new axis mapping is " << _order << LogIO::NORMAL;
81 29 : }
82 :
83 5 : ImageTransposer::ImageTransposer(
84 : const SPCIIF image, uInt order,
85 : const String& outputImage
86 5 : )
87 : : ImageTask<Float>(
88 : image, "", 0, "", "", "",
89 : "", outputImage, false
90 5 : ), _order(Vector<Int>()), _reverse(IPosition(0)) {
91 10 : LogOrigin origin(_class, String(__FUNCTION__) + "_3");
92 5 : *_getLog() << origin;
93 : //_construct();
94 5 : *_getLog() << origin;
95 5 : _order = _getOrder(order);
96 14 : }
97 :
98 23 : SPIIF ImageTransposer::transpose() const {
99 23 : *_getLog() << LogOrigin(_class, __FUNCTION__);
100 : // get the image data
101 23 : Array<Float> dataCopy = _getImage()->get();
102 23 : CoordinateSystem newCsys = _getImage()->coordinates();
103 23 : IPosition shape = _getImage()->shape();
104 23 : 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 0 : }
117 23 : newCsys.transpose(_order, _order);
118 23 : IPosition newShape(_order.size());
119 106 : for (uInt i=0; i<newShape.size(); ++i) {
120 83 : newShape[i] = shape[_order[i]];
121 : }
122 : SPIIF output(
123 23 : new TempImage<Float>(TiledShape(newShape), newCsys)
124 23 : );
125 23 : if (_reverse.size() > 0) {
126 0 : dataCopy = reverseArray(dataCopy, _reverse);
127 : }
128 23 : output->put(reorderArray(dataCopy, _order));
129 23 : if (_getImage()->hasPixelMask()) {
130 : std::unique_ptr<Lattice<Bool> > maskLattice(
131 12 : _getImage()->pixelMask().clone()
132 12 : );
133 12 : Array<Bool> maskCopy = maskLattice->get();
134 12 : if (_reverse.size() > 0) {
135 0 : maskCopy = reverseArray(maskCopy, _reverse);
136 : }
137 24 : dynamic_cast<TempImage<Float> *>(output.get())->attachMask(
138 24 : ArrayLattice<Bool>(reorderArray(maskCopy, _order))
139 : );
140 12 : }
141 23 : ImageUtilities::copyMiscellaneous(*output, *this->_getImage());
142 46 : return this->_prepareOutputImage(*output);
143 23 : }
144 :
145 46 : ImageTransposer::~ImageTransposer() {}
146 :
147 24 : Vector<Int> ImageTransposer::_getOrder(uInt order) const {
148 24 : *_getLog() << LogOrigin(_class, String(__func__));
149 24 : uInt naxes = _getImage()->ndim();
150 24 : uInt raxes = uInt(log10(order)) + 1;
151 24 : if (naxes != raxes) {
152 7 : istringstream is;
153 7 : is >> order;
154 7 : if (! String(is.str()).contains("0")) {
155 7 : raxes++;
156 : }
157 7 : }
158 24 : if (raxes != naxes) {
159 6 : *_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 2 : << LogIO::EXCEPTION;
162 : }
163 22 : 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 22 : Vector<Int> myorder(naxes);
168 22 : uInt mag = 1;
169 79 : for (uInt i=1; i<myorder.size(); i++) {
170 57 : mag *= 10;
171 : }
172 22 : uInt scratchOrder = order;
173 97 : for (uInt i=0; i<myorder.size(); i++) {
174 79 : uInt index = scratchOrder/mag;
175 79 : if (index >= naxes) {
176 9 : *_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 3 : << LogIO::EXCEPTION;
181 : }
182 173 : for (uInt j=0; j<i; j++) {
183 98 : if ((Int)index == myorder[j]) {
184 3 : *_getLog() << "Axis number " << index
185 : << " specified multiple times in order parameter "
186 : << order << " . It can only be specified once."
187 1 : << LogIO::EXCEPTION;
188 : }
189 : }
190 75 : myorder[i] = index;
191 75 : scratchOrder -= index*mag;
192 75 : mag /= 10;
193 : }
194 18 : return myorder;
195 4 : }
196 :
197 19 : Vector<Int> ImageTransposer::_getOrder(const String& order) {
198 19 : String orderCopy = order;
199 19 : 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 35 : return _getOrder(String::toInt(orderCopy));
214 19 : }
215 :
216 : }
|