Line data Source code
1 : //# tSubImage.cc: Test program for class SubImage
2 : //# Copyright (C) 1998,1999,2000,2001,2003
3 : //# Associated Universities, Inc. Washington DC, USA.
4 : //#
5 : //# This program is free software; you can redistribute it and/or modify it
6 : //# under the terms of the GNU General Public License as published by the Free
7 : //# Software Foundation; either version 2 of the License, or (at your option)
8 : //# any later version.
9 : //#
10 : //# This program is distributed in the hope that it will be useful, but WITHOUT
11 : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 : //# more details.
14 : //#
15 : //# You should have received a copy of the GNU General Public License along
16 : //# with this program; if not, write to the Free Software Foundation, Inc.,
17 : //# 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18 : //#
19 : //# Correspondence concerning AIPS++ should be addressed as follows:
20 : //# Internet email: casa-feedback@nrao.edu.
21 : //# Postal address: AIPS++ Project Office
22 : //# National Radio Astronomy Observatory
23 : //# 520 Edgemont Road
24 : //# Charlottesville, VA 22903-2475 USA
25 : //#
26 : //# $Id: $
27 :
28 : #include <imageanalysis/ImageAnalysis/ImageFactory.h>
29 :
30 : #include <casacore/casa/OS/Directory.h>
31 : #include <casacore/casa/OS/RegularFile.h>
32 : #include <casacore/casa/OS/SymLink.h>
33 : #include <casacore/coordinates/Coordinates/CoordinateUtil.h>
34 : #include <casacore/images/Images/PagedImage.h>
35 : #include <casacore/images/Images/TempImage.h>
36 : #include <casacore/tables/LogTables/NewFile.h>
37 : #include <casacore/tables/Tables/TableUtil.h>
38 :
39 : #include <imageanalysis/ImageAnalysis/ImageHistory.h>
40 : #include <imageanalysis/ImageAnalysis/SubImageFactory.h>
41 :
42 : namespace casa {
43 :
44 : template <class T> void ImageFactory::remove(SPIIT& image, casacore::Bool verbose) {
45 : ThrowIf(
46 : ! image, "Image cannot be null"
47 : );
48 : ThrowIf(
49 : ! image->isPersistent(),
50 : "This image tool is not associated with a "
51 : "persistent disk file. It cannot be deleted"
52 : );
53 : auto fileName = image->name(false);
54 : ThrowIf(
55 : fileName.empty(),
56 : "Filename is empty or does not exist."
57 : );
58 : casacore::File f(fileName);
59 : ThrowIf(
60 : ! f.exists(),
61 : fileName + " does not exist."
62 : );
63 :
64 : // Destroy object before deleting image. This is why a reference
65 : // needs to be passed in.
66 : image.reset();
67 :
68 : // Now try and blow it away. If it's open, tabledelete won't delete it.
69 : casacore::String message;
70 : casacore::LogIO log;
71 : if (casacore::TableUtil::canDeleteTable(message, fileName, true)) {
72 : try {
73 : casacore::TableUtil::deleteTable(fileName, true);
74 : log << (verbose ? casacore::LogIO::NORMAL : casacore::LogIO::DEBUG1)
75 : << "deleted table " << fileName << casacore::LogIO::POST;
76 : }
77 : catch (const casacore::AipsError& x) {
78 : ThrowCc(
79 : "Failed to delete file " + fileName
80 : + " because " + x.getMesg()
81 : );
82 : };
83 : }
84 : else {
85 : ThrowCc(
86 : "Cannot delete file " + fileName
87 : + " because " + message
88 : );
89 : }
90 : }
91 :
92 : template<class T>
93 : std::shared_ptr<TempImage<std::complex<T>>> ImageFactory::makeComplexImage(
94 : SPCIIT realPart, SPCIIT imagPart
95 : ) {
96 : auto shape = realPart->shape();
97 : ThrowIf(
98 : shape != imagPart->shape(),
99 : "Real and imaginary parts have different shapes"
100 : );
101 : std::shared_ptr<TempImage<std::complex<T>>> newImage(
102 : new TempImage<std::complex<T>>(shape, realPart->coordinates())
103 : );
104 : LatticeExpr<std::complex<T>> expr(
105 : casacore::formComplex(*realPart, *imagPart)
106 : );
107 : if (ImageMask::isAllMaskTrue(expr)) {
108 : newImage->copyData(expr);
109 : }
110 : else {
111 : newImage->attachMask(casacore::ArrayLattice<Bool>(shape));
112 : LogIO os;
113 : casacore::LatticeUtilities::copyDataAndMask(os, *newImage, expr, False);
114 : }
115 : ImageUtilities::copyMiscellaneous(*newImage, *realPart);
116 : return newImage;
117 : }
118 :
119 : template <class T>
120 : std::shared_ptr<casacore::ImageInterface<std::complex<T>>> ImageFactory::makeComplex(
121 : SPCIIT realPart, SPCIIT imagPart, const String& outfile,
122 : const Record& region, Bool overwrite
123 : ) {
124 : _checkOutfile(outfile, overwrite);
125 : const IPosition realShape = realPart->shape();
126 : const IPosition imagShape = imagPart->shape();
127 : ThrowIf(! realShape.isEqual(imagShape), "Image shapes are not identical");
128 : const auto& cSysReal = realPart->coordinates();
129 : const auto& cSysImag = imagPart->coordinates();
130 : ThrowIf(
131 : !cSysReal.near(cSysImag), "Image Coordinate systems are not conformant"
132 : );
133 : String mask;
134 : auto subRealImage = SubImageFactory<T>::createSubImageRO(
135 : *realPart, region, mask, nullptr
136 : );
137 : auto subImagImage = SubImageFactory<T>::createSubImageRO(
138 : *imagPart, region, mask, nullptr
139 : );
140 : auto complexImage = makeComplexImage(
141 : std::dynamic_pointer_cast<const casacore::ImageInterface<T>>(subRealImage),
142 : std::dynamic_pointer_cast<const casacore::ImageInterface<T>>(subImagImage)
143 : );
144 : return SubImageFactory<std::complex<T>>::createImage(
145 : *complexImage, outfile, Record(), "", AxesSpecifier(),
146 : overwrite, false, false
147 : );
148 : }
149 :
150 0 : template <class T> SPIIT ImageFactory::createImage(
151 : const casacore::String& outfile,
152 : const casacore::CoordinateSystem& cSys, const casacore::IPosition& shape,
153 : casacore::Bool log, casacore::Bool overwrite,
154 : const vector<std::pair<casacore::LogOrigin, casacore::String> > *const &msgs
155 : ) {
156 0 : _checkOutfile(outfile, overwrite);
157 0 : ThrowIf(
158 : shape.nelements() != cSys.nPixelAxes(),
159 : "Supplied CoordinateSystem and image shape are inconsistent"
160 : );
161 0 : SPIIT image;
162 0 : if (outfile.empty()) {
163 0 : image.reset(new casacore::TempImage<T>(shape, cSys));
164 0 : ThrowIf(! image, "Failed to create TempImage");
165 : }
166 : else {
167 0 : image.reset(new casacore::PagedImage<T>(shape, cSys, outfile));
168 0 : ThrowIf(
169 : ! image,
170 : "Failed to create PagedImage"
171 : );
172 : }
173 0 : auto creationMsg = _imageCreationMessage(outfile, shape, whatType<T>());
174 0 : ImageHistory<T> hist(image);
175 0 : if (msgs) {
176 0 : hist.addHistory(*msgs);
177 : }
178 0 : LogOrigin lor("ImageFactory", __func__);
179 0 : hist.addHistory(lor, creationMsg);
180 0 : image->set(0.0);
181 0 : if (log) {
182 0 : LogIO mylog;
183 0 : mylog << LogOrigin("ImageFactory", __func__)
184 0 : << LogIO::NORMAL << creationMsg << LogIO::POST;
185 0 : }
186 0 : return image;
187 0 : }
188 :
189 : template<class T>
190 : std::shared_ptr<casacore::TempImage<T>> ImageFactory::floatFromComplex(
191 : std::shared_ptr<const casacore::ImageInterface<std::complex<T>>> complexImage,
192 : ComplexToFloatFunction function
193 : ) {
194 : std::shared_ptr<TempImage<T>> newImage(
195 : new TempImage<T>(
196 : TiledShape(complexImage->shape()),
197 : complexImage->coordinates()
198 : )
199 : );
200 : {
201 : // FIXME use lattice copies
202 : auto mymask = complexImage->getMask();
203 : if (complexImage->hasPixelMask()) {
204 : mymask = mymask && complexImage->pixelMask().get();
205 : }
206 : if (! allTrue(mymask)) {
207 : newImage->attachMask(ArrayLattice<Bool>(mymask));
208 : }
209 : }
210 : ImageUtilities::copyMiscellaneous(*newImage, *complexImage);
211 : switch (function) {
212 : case REAL:
213 : // FIXME use lattice copies
214 : newImage->put(real(complexImage->get()));
215 : break;
216 : case IMAG:
217 : // FIXME use lattice copies
218 : newImage->put(imag(complexImage->get()));
219 : break;
220 : default:
221 : ThrowCc("Logic Error: Unhandled function");
222 : }
223 : return newImage;
224 : }
225 :
226 0 : template <class T> SPIIT ImageFactory::fromShape(
227 : const casacore::String& outfile,
228 : const casacore::Vector<casacore::Int>& shapeV,
229 : const casacore::Record& coordinates, casacore::Bool linear,
230 : casacore::Bool overwrite, casacore::Bool verbose,
231 : const vector<std::pair<casacore::LogOrigin, casacore::String> > *const &msgs
232 : ) {
233 0 : ThrowIf(
234 : shapeV.nelements() == 0, "The shape must have more than zero elements"
235 : );
236 0 : ThrowIf(anyTrue(shapeV <= 0), "All elements of shape must be positive");
237 0 : casacore::CoordinateSystem mycsys;
238 0 : std::unique_ptr<casacore::CoordinateSystem> csysPtr;
239 0 : if (coordinates.empty()) {
240 0 : mycsys = casacore::CoordinateUtil::makeCoordinateSystem(shapeV, linear);
241 0 : _centerRefPix(mycsys, shapeV);
242 : }
243 : else {
244 0 : csysPtr.reset(_makeCoordinateSystem(coordinates, shapeV));
245 0 : mycsys = *csysPtr;
246 : }
247 0 : return createImage<T>(outfile, mycsys, shapeV, verbose, overwrite, msgs);
248 0 : }
249 :
250 : template <class T> SPIIT ImageFactory::imageFromArray(
251 : const casacore::String& outfile, const casacore::Array<T>& pixels,
252 : const casacore::Record& csys, casacore::Bool linear,
253 : casacore::Bool overwrite, casacore::Bool verbose,
254 : const vector<std::pair<casacore::LogOrigin, casacore::String> > *const &msgs
255 : ) {
256 : SPIIT myim = fromShape<T>(
257 : outfile, pixels.shape().asVector(),
258 : csys, linear, overwrite, verbose, msgs
259 : );
260 : myim->put(pixels);
261 : return myim;
262 : }
263 :
264 0 : template <class T> SPIIT ImageFactory::_fromRecord(
265 : const casacore::RecordInterface& rec, const casacore::String& name
266 : ) {
267 0 : SPIIT image;
268 0 : casacore::String err;
269 0 : image.reset(new casacore::TempImage<T>());
270 0 : ThrowIf(
271 : ! image->fromRecord(err, rec),
272 : "Error converting image from record: " + err
273 : );
274 0 : if (! name.empty()) {
275 0 : image = SubImageFactory<T>::createImage(
276 0 : *image, name, casacore::Record(), "", false,
277 : true, false, false
278 : );
279 : }
280 0 : return image;
281 0 : }
282 :
283 0 : template <class T> ITUPLE ImageFactory::_rename(
284 : SPIIT& image, const casacore::String& name,
285 : const casacore::Bool overwrite
286 : ) {
287 0 : casacore::LogIO mylog;
288 0 : mylog << casacore::LogOrigin(className(), __func__);
289 0 : ThrowIf (! image, "Image pointer cannot be null");
290 0 : ThrowIf(
291 : ! image->isPersistent(),
292 : "This image tool is not associated with a "
293 : "persistent disk file. It cannot be renamed"
294 : );
295 0 : ThrowIf(
296 : name.empty(), "new file name must be specified"
297 : );
298 0 : casacore::String oldName = image->name(false);
299 0 : ThrowIf(
300 : oldName.empty(),
301 : "Current file name is empty, cannot rename"
302 : );
303 0 : ThrowIf(
304 : oldName == name,
305 : "Specified output name is the same as the current image name"
306 : );
307 : // Let's see if it exists. If it doesn't, then the user has deleted it
308 0 : casacore::File file(oldName);
309 0 : if (file.isSymLink()) {
310 0 : file = casacore::File(casacore::SymLink(file).followSymLink());
311 : }
312 0 : ThrowIf(
313 : ! file.exists(), "The image to be renamed no longer exists"
314 : );
315 0 : _checkOutfile(name, overwrite);
316 : // close image before renaming
317 0 : image.reset();
318 : // Now try and move it
319 0 : casacore::Bool follow(true);
320 0 : if (file.isRegular(follow)) {
321 0 : casacore::RegularFile(file).move(name, overwrite);
322 : }
323 0 : else if (file.isDirectory(follow)) {
324 0 : casacore::Directory(file).move(name, overwrite);
325 : }
326 0 : else if (file.isSymLink()) {
327 0 : casacore::SymLink(file).copy(name, overwrite);
328 : }
329 : else {
330 0 : ThrowCc("Failed to rename file " + oldName + " to " + name);
331 : }
332 : mylog << casacore::LogIO::NORMAL << "Successfully renamed file " << oldName
333 0 : << " to " << name << casacore::LogIO::POST;
334 0 : return fromFile(name);
335 :
336 0 : }
337 :
338 :
339 : }
340 :
|