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/EnvVar.h>
31 : #include <casacore/casa/System/AppState.h>
32 : #include <casacore/images/Images/ImageFITSConverter.h>
33 : #include <casacore/images/Images/ImageUtilities.h>
34 : #include <casacore/images/Images/ImageOpener.h>
35 :
36 : #include <imageanalysis/ImageAnalysis/PixelValueManipulator.h>
37 : #include <imageanalysis/ImageAnalysis/SubImageFactory.h>
38 :
39 : using namespace std;
40 :
41 : using namespace casacore;
42 : namespace casa {
43 :
44 :
45 0 : std::shared_ptr<ComponentListImage> ImageFactory::createComponentListImage(
46 : const String& outfile, const Record& cl, const Vector<Int>& shape,
47 : const Record& csys, Bool overwrite, Bool log, Bool cache
48 : ) {
49 0 : _checkOutfile(outfile, overwrite);
50 0 : ComponentList mycl;
51 0 : String err;
52 0 : ThrowIf(! mycl.fromRecord(err, cl), err);
53 0 : CoordinateSystem mycsys;
54 0 : std::unique_ptr<CoordinateSystem> csysPtr;
55 0 : if (csys.empty()) {
56 0 : mycsys = CoordinateUtil::makeCoordinateSystem(shape, False);
57 0 : _centerRefPix(mycsys, shape);
58 : }
59 : else {
60 0 : csysPtr.reset(
61 : _makeCoordinateSystem(csys, shape)
62 : );
63 0 : mycsys = *csysPtr;
64 : }
65 :
66 : std::shared_ptr<ComponentListImage> image(
67 0 : outfile.empty()
68 0 : ? new ComponentListImage(mycl, mycsys, IPosition(shape), cache)
69 0 : : new ComponentListImage(mycl, mycsys, IPosition(shape), outfile, cache)
70 0 : );
71 0 : ostringstream os;
72 0 : os << "Created ComponentListImage " << outfile
73 0 : << " of shape " << shape << ".";
74 0 : ImageHistory<Float> hist(image);
75 0 : LogOrigin lor("ImageFactory", __func__);
76 0 : hist.addHistory(lor, os.str());
77 0 : if (log) {
78 0 : casacore::LogIO mylog;
79 0 : mylog << casacore::LogIO::NORMAL << os.str() << casacore::LogIO::POST;
80 0 : }
81 0 : return image;
82 0 : }
83 :
84 51 : SPIIF ImageFactory::floatImageFromShape(
85 : const String& outfile, const Vector<Int>& shape,
86 : const Record& csys, Bool linear,
87 : Bool overwrite, Bool verbose,
88 : const vector<std::pair<LogOrigin, String> > *const &msgs
89 : ) {
90 : return fromShape<Float>(
91 : outfile, shape, csys, linear,
92 : overwrite, verbose, msgs
93 51 : );
94 : }
95 :
96 0 : SPIIC ImageFactory::complexImageFromShape(
97 : const String& outfile, const Vector<Int>& shape,
98 : const Record& csys, Bool linear,
99 : Bool overwrite, Bool verbose,
100 : const vector<std::pair<LogOrigin, String> > *const &msgs
101 : ) {
102 : return fromShape<Complex>(
103 : outfile, shape, csys, linear,
104 : overwrite, verbose, msgs
105 0 : );
106 : }
107 :
108 0 : SPIID ImageFactory::doubleImageFromShape(
109 : const String& outfile, const Vector<casacore::Int>& shape,
110 : const Record& csys, Bool linear,
111 : Bool overwrite, Bool verbose,
112 : const std::vector<std::pair<LogOrigin, String> > *const &msgs
113 : ) {
114 : return fromShape<Double>(
115 : outfile, shape, csys, linear,
116 : overwrite, verbose, msgs
117 0 : );
118 : }
119 :
120 0 : SPIIDC ImageFactory::complexDoubleImageFromShape(
121 : const String& outfile, const Vector<Int>& shape,
122 : const Record& csys, casacore::Bool linear,
123 : Bool overwrite, casacore::Bool verbose,
124 : const std::vector<std::pair<LogOrigin, String> > *const &msgs
125 : ) {
126 : return fromShape<DComplex>(
127 : outfile, shape, csys, linear, overwrite, verbose, msgs
128 0 : );
129 : }
130 : /*
131 : SPIIF ImageFactory::fromASCII(
132 : const String& outfile, const String& infile,
133 : const IPosition& shape, const String& sep, const Record& csys,
134 : const Bool linear, const Bool overwrite
135 : ) {
136 : Path filePath(infile);
137 : auto fileName = filePath.expandedName();
138 : ifstream inFile(fileName.c_str());
139 : ThrowIf(!inFile, "Cannot open " + infile);
140 : auto n = shape.product();
141 : auto nx = shape[0];
142 : Vector<Float> a(n, 0.0);
143 : int idx = 0;
144 : string line;
145 : unique_ptr<string[]> managed(new string[2 * nx]);
146 : auto line2 = managed.get();
147 : uInt iline = 0;
148 : uInt nl = 1;
149 : while (nl > 0) {
150 : getline(inFile, line, '\n');
151 : nl = split(line, line2, 2 * nx, sep);
152 : if (nl > 0) {
153 : ThrowIf(
154 : nl != nx,
155 : "Length of line " + String::toString(iline)
156 : + " is " + String::toString(nl) + " but should be "
157 : + String::toString(nx)
158 : );
159 : for (uInt i = 0; i < nx; i++) {
160 : a[idx + i] = atof(line2[i].c_str());
161 : }
162 : idx += nx;
163 : iline += 1;
164 : }
165 : }
166 : Vector<Float> vec(n);
167 : for (uInt i = 0; i < n; ++i) {
168 : vec[i] = a[i];
169 : }
170 : Array<Float> pixels(vec.reform(IPosition(shape)));
171 : return imageFromArray(outfile, pixels, csys, linear, overwrite);
172 : }
173 : */
174 51 : ITUPLE ImageFactory::fromImage(
175 : const String& outfile, const String& infile,
176 : const Record& region, const String& mask, Bool dropdeg,
177 : Bool overwrite
178 : ) {
179 51 : auto imagePtrs = fromFile(infile, False);
180 51 : auto imageF = std::get<0>(imagePtrs);
181 51 : auto imageC = std::get<1>(imagePtrs);
182 51 : auto imageD = std::get<2>(imagePtrs);
183 51 : auto imageDC = std::get<3>(imagePtrs);
184 51 : if (imageF) {
185 102 : imageF = SubImageFactory<Float>::createImage(
186 51 : *imageF, outfile, region,
187 : mask, dropdeg, overwrite, false, false
188 51 : );
189 51 : ThrowIf(! imageF, "Failed to create image");
190 : }
191 0 : else if (imageC) {
192 0 : imageC = SubImageFactory<Complex>::createImage(
193 0 : *imageC, outfile, region,
194 : mask, dropdeg, overwrite, false, false
195 0 : );
196 0 : ThrowIf(! imageC, "Failed to create image");
197 : }
198 0 : else if (imageD) {
199 0 : imageD = SubImageFactory<Double>::createImage(
200 0 : *imageD, outfile, region,
201 : mask, dropdeg, overwrite, false, false
202 0 : );
203 0 : ThrowIf(! imageD, "Failed to create image");
204 : }
205 : else {
206 0 : imageDC = SubImageFactory<DComplex>::createImage(
207 0 : *imageDC, outfile, region,
208 : mask, dropdeg, overwrite, false, false
209 0 : );
210 0 : ThrowIf(! imageDC, "Failed to create image");
211 : }
212 51 : LogIO mylog;
213 51 : mylog << LogOrigin("ImageFactory", __func__);
214 51 : ITUPLE ret(imageF, imageC, imageD, imageDC);
215 51 : mylog << LogIO::NORMAL << _imageCreationMessage(outfile, ret)
216 51 : << LogIO::POST;
217 102 : return ret;
218 51 : }
219 :
220 0 : pair<SPIIF, SPIIC> ImageFactory::fromRecord(
221 : const RecordInterface& rec, const String& name
222 : ) {
223 0 : auto mytype = rec.type(rec.fieldNumber("imagearray"));
224 0 : pair<SPIIF, SPIIC> imagePair;
225 0 : if (isReal(mytype)) {
226 0 : imagePair.first = _fromRecord<Float>(rec, name);
227 : }
228 : else {
229 0 : imagePair.second = _fromRecord<Complex>(rec, name);
230 : }
231 0 : return imagePair;
232 0 : }
233 :
234 51 : void ImageFactory::_centerRefPix(
235 : CoordinateSystem& csys, const IPosition& shape
236 : ) {
237 51 : Int after = -1;
238 51 : Int iS = csys.findCoordinate(Coordinate::STOKES, after);
239 51 : Int sP = -1;
240 51 : if (iS >= 0) {
241 51 : Vector<Int> pixelAxes = csys.pixelAxes(iS);
242 51 : sP = pixelAxes(0);
243 51 : }
244 51 : Vector<Double> refPix = csys.referencePixel();
245 255 : for (Int i = 0; i < Int(refPix.nelements()); i++) {
246 204 : if (i != sP)
247 153 : refPix(i) = Double(shape(i) / 2);
248 : }
249 51 : csys.setReferencePixel(refPix);
250 51 : }
251 :
252 16 : CoordinateSystem* ImageFactory::_makeCoordinateSystem(
253 : const Record& coordinates, const IPosition& shape
254 : ) {
255 16 : std::unique_ptr<CoordinateSystem> csys;
256 16 : if (coordinates.nfields() == 1) {
257 : // must be a record as an element
258 16 : Record tmp(coordinates.asRecord(RecordFieldId(0)));
259 16 : csys.reset(CoordinateSystem::restore(tmp, ""));
260 16 : }
261 : else {
262 0 : csys.reset(CoordinateSystem::restore(coordinates, ""));
263 : }
264 : // Fix up any body longitude ranges...
265 16 : String errMsg;
266 16 : if (csys->hasDirectionCoordinate()) {
267 16 : auto axes = csys->directionAxesNumbers();
268 16 : if (min(axes) >= 0) {
269 16 : ThrowIf(
270 : ! CoordinateUtil::cylindricalFix(*csys, errMsg, shape),
271 : errMsg
272 : );
273 : }
274 : else {
275 0 : LogIO log(LogOrigin("ImageFactory", __func__));
276 : log << LogIO::WARN << "Direction coordinate has at least one "
277 : << "axis that has been removed, skipping cylindrical fix "
278 : << "which is normally only important for imported image formats "
279 0 : << "such as FITS" << LogIO::POST;
280 0 : }
281 16 : }
282 32 : return csys.release();
283 16 : }
284 :
285 364 : ITUPLE ImageFactory::fromFile(const String& infile, Bool cache) {
286 364 : _checkInfile(infile);
287 364 : ComponentListImage::registerOpenFunction();
288 364 : unique_ptr<LatticeBase> latt(ImageOpener::openImage(infile));
289 365 : ThrowIf (! latt, "Unable to open image " + infile);
290 363 : auto imagePtrs = _fromLatticeBase(latt);
291 363 : auto imageF = std::get<0>(imagePtrs);
292 363 : if (
293 : imageF
294 363 : && imageF->imageType().contains(ComponentListImage::IMAGE_TYPE)
295 : ) {
296 0 : std::dynamic_pointer_cast<ComponentListImage>(imageF)->setCache(cache);
297 : }
298 726 : return imagePtrs;
299 364 : }
300 :
301 0 : SPIIF ImageFactory::fromFile(
302 : const casacore::String& filename, casacore::Float, casacore::Bool cache
303 : ) {
304 0 : auto t = fromFile(filename, cache);
305 0 : return std::get<0>(t);
306 0 : }
307 :
308 0 : SPIIC ImageFactory::fromFile(
309 : const casacore::String& filename, casacore::Complex, casacore::Bool cache
310 : ) {
311 0 : auto t = fromFile(filename, cache);
312 0 : return std::get<1>(t);
313 0 : }
314 :
315 0 : SPIID ImageFactory::fromFile(
316 : const casacore::String& filename, casacore::Double, casacore::Bool cache
317 : ) {
318 0 : auto t = fromFile(filename, cache);
319 0 : return std::get<2>(t);
320 0 : }
321 :
322 0 : SPIIDC ImageFactory::fromFile(
323 : const casacore::String& filename, casacore::DComplex, casacore::Bool cache
324 : ) {
325 0 : auto t = fromFile(filename, cache);
326 0 : return std::get<3>(t);
327 0 : }
328 :
329 363 : ITUPLE ImageFactory::_fromLatticeBase(
330 : unique_ptr<LatticeBase>& latt
331 : ) {
332 363 : DataType dataType = latt->dataType();
333 363 : tuple<SPIIF, SPIIC, SPIID, SPIIDC> ret(nullptr, nullptr, nullptr, nullptr);
334 363 : if (dataType == TpFloat) {
335 : auto f = SPIIF(
336 726 : dynamic_cast<ImageInterface<Float> *>(latt.release())
337 726 : );
338 363 : ThrowIf(! f, "Could not cast LatticeBase to ImageInterface<Float>");
339 363 : std::get<0>(ret) = f;
340 363 : }
341 0 : else if (dataType == TpComplex) {
342 : auto c = SPIIC(
343 0 : dynamic_cast<ImageInterface<Complex> *>(latt.release())
344 0 : );
345 0 : ThrowIf(! c, "Could not cast LatticeBase to ImageInterface<Complex>");
346 0 : std::get<1>(ret) = c;
347 0 : }
348 0 : else if (dataType == TpDouble) {
349 : auto d = SPIID(
350 0 : dynamic_cast<ImageInterface<Double> *>(latt.release())
351 0 : );
352 0 : ThrowIf(! d, "Could not cast LatticeBase to ImageInterface<Double>");
353 0 : std::get<2>(ret) = d;
354 0 : }
355 0 : else if (dataType == TpDComplex) {
356 : auto dc = SPIIDC(
357 0 : dynamic_cast<ImageInterface<DComplex> *>(latt.release())
358 0 : );
359 0 : ThrowIf(! dc, "Could not cast LatticeBase to ImageInterface<DComplex>");
360 0 : std::get<3>(ret) = dc;
361 0 : }
362 : else {
363 0 : ostringstream os;
364 0 : os << dataType;
365 0 : throw AipsError("unsupported image data type " + os.str());
366 0 : }
367 363 : return ret;
368 0 : }
369 :
370 364 : void ImageFactory::_checkInfile(const String& infile) {
371 364 : ThrowIf(
372 : infile.empty(), "File name is empty"
373 : );
374 364 : File thefile(infile);
375 364 : ThrowIf(
376 : ! thefile.exists(),
377 : "File " + infile + " does not exist."
378 : );
379 364 : }
380 :
381 0 : SPIIF ImageFactory::fromFITS(
382 : const String& outfile, const String& fitsfile,
383 : const Int whichrep, const Int whichhdu,
384 : const Bool zeroBlanks, const Bool overwrite
385 : ) {
386 0 : _checkOutfile(outfile, overwrite);
387 0 : ThrowIf(
388 : whichrep < 0,
389 : "The Coordinate Representation index must be non-negative"
390 : );
391 0 : ImageInterface<Float> *x = nullptr;
392 0 : String error;
393 0 : Bool rval = ImageFITSConverter::FITSToImage(
394 : x, error, outfile, fitsfile, whichrep, whichhdu,
395 0 : HostInfo::memoryFree() / 1024, overwrite, zeroBlanks
396 : );
397 0 : SPIIF pOut(x);
398 0 : ThrowIf(! rval || ! pOut, error);
399 0 : return pOut;
400 0 : }
401 :
402 0 : void ImageFactory::rename(
403 : SPIIF& image, const String& name, const Bool overwrite
404 : ) {
405 0 : image = std::get<0>(_rename(image, name, overwrite));
406 0 : }
407 :
408 0 : void ImageFactory::rename(
409 : SPIIC& image, const String& name, const Bool overwrite
410 : ) {
411 0 : image = std::get<1>(_rename(image, name, overwrite));
412 0 : }
413 : /*
414 : void ImageFactory::toASCII(
415 : SPCIIF image, const String& outfile, Record& region,
416 : const String& mask, const String& sep,
417 : const String& format, Double maskvalue,
418 : Bool overwrite, Bool extendMask
419 : ) {
420 : String outFileStr(outfile);
421 : // Check output file name
422 :
423 : if (outFileStr.empty()) {
424 : Bool strippath(true);
425 : outFileStr = image->name(strippath);
426 : outFileStr = outFileStr + ".ascii";
427 : }
428 : _checkOutfile(outFileStr, overwrite);
429 :
430 : Path filePath(outFileStr);
431 : String fileName = filePath.expandedName();
432 :
433 : ofstream outFile(fileName.c_str());
434 : ThrowIf(! outFile, "Cannot open file " + outfile);
435 :
436 : PixelValueManipulator<Float> pvm(
437 : image, ®ion, mask
438 : );
439 : pvm.setVerbosity(ImageTask<Float>::QUIET);
440 : pvm.setStretch(extendMask);
441 : auto ret = pvm.get();
442 :
443 : auto pixels = ret.asArrayFloat("values");
444 : auto pixmask = ret.asArrayBool("mask");
445 : auto shape = pixels.shape();
446 : auto vshp = pixmask.shape();
447 : uInt nx = shape(0);
448 : uInt n = pixels.size();
449 : uInt nlines = 0;
450 : if (nx > 0) {
451 : nlines = n / nx;
452 : }
453 : IPosition vShape(1, n);
454 : Vector<Float> vpixels(pixels.reform(vShape));
455 : if (pixmask.size() > 0) {
456 : Vector<Bool> vmask(pixmask.reform(vShape));
457 : for (uInt i = 0; i<n; ++i) {
458 : if (! vmask[i]) {
459 : vpixels[i] = (float) maskvalue;
460 : }
461 : }
462 : }
463 : int idx = 0;
464 : uInt nline = 0;
465 : char nextentry[128];
466 : while (nline < nlines) {
467 : string line;
468 : for (uInt i = 0; i < nx - 1; ++i) {
469 : sprintf(
470 : nextentry, (format + "%s").c_str(), vpixels[idx + i],
471 : sep.c_str()
472 : );
473 : line += nextentry;
474 : }
475 : sprintf(nextentry, format.c_str(), vpixels[idx + nx - 1]);
476 : line += nextentry;
477 : outFile << line.c_str() << endl;
478 : idx += nx;
479 : nline += 1;
480 : }
481 : }
482 : */
483 0 : void ImageFactory::toFITS(
484 : SPCIIF image, const String& outfile, Bool velocity, Bool optical,
485 : Int bitpix, Double minpix, Double maxpix,
486 : const Record& region, const String& mask,
487 : Bool overwrite, Bool dropdeg, Bool deglast,
488 : Bool dropStokes, Bool stokeslast,
489 : Bool wavelength, Bool airWavelength,
490 : const String& origin, Bool stretch, Bool history
491 : ) {
492 0 : LogIO log;
493 0 : log << LogOrigin("ImageFactory", __func__);
494 0 : _checkOutfile(outfile, overwrite);
495 : // The SubImage that goes to the FITSCOnverter no longer will know
496 : // the name of the parent mask, so spit it out here
497 0 : if (image->isMasked()) {
498 : log << LogIO::NORMAL << "Applying mask of name '"
499 0 : << image->getDefaultMask() << "'" << LogIO::POST;
500 : }
501 0 : IPosition keepAxes;
502 0 : if (! dropdeg) {
503 0 : if (dropStokes) {
504 0 : const auto& cSys = image->coordinates();
505 0 : if (
506 0 : cSys.hasPolarizationCoordinate()
507 0 : && cSys.nCoordinates() > 1
508 : ) {
509 : // Stokes axis exists and its not the only one
510 0 : auto cNames = cSys.worldAxisNames();
511 0 : keepAxes = IPosition(cNames.size() - 1);
512 0 : uInt j = 0;
513 0 : for (uInt i = 0; i < cNames.size(); ++i) {
514 0 : if (cNames(i) != "Stokes") { // not Stokes?
515 0 : keepAxes(j) = i; // keep it
516 0 : j++;
517 : }
518 : }
519 0 : }
520 : }
521 : }
522 0 : AxesSpecifier axesSpecifier;
523 0 : if (dropdeg) {
524 0 : axesSpecifier = AxesSpecifier(false);
525 : }
526 0 : else if (! keepAxes.empty()) {
527 0 : axesSpecifier = AxesSpecifier(keepAxes);
528 : }
529 : auto subImage = SubImageFactory<Float>::createSubImageRO(
530 0 : *image, region, mask, &log, axesSpecifier, stretch
531 0 : );
532 : // FIXME remove when the casacore interface has been updated to const
533 0 : SPIIF myclone(subImage->cloneII());
534 0 : String error;
535 0 : ThrowIf (
536 : ! ImageFITSConverter::ImageToFITS(
537 : error, *myclone, outfile,
538 : HostInfo::memoryFree() / 1024,
539 : velocity, optical, bitpix, minpix,
540 : maxpix, overwrite, deglast,
541 : false, // verbose default
542 : stokeslast, wavelength,
543 : airWavelength, // for airWavelength=true
544 : origin, history
545 : ), error
546 : );
547 0 : }
548 :
549 0 : SPIIF ImageFactory::testImage(
550 : const String& outfile, const Bool overwrite,
551 : const String& imagetype
552 : ) {
553 : // setup image name relative to the data root...
554 0 : String testname;
555 0 : if (imagetype.contains("cube")) {
556 0 : testname = "demo/Images/test_imageFloat.fits";
557 : }
558 0 : else if (imagetype.contains("2d")) {
559 0 : testname = "demo/Images/imagetestimage.fits";
560 : }
561 : else {
562 0 : ThrowCc("imageType must be either \"cube\" or \"2d\"");
563 : }
564 :
565 0 : String fitsfile;
566 :
567 0 : const casacore::AppState &state = casacore::AppStateSource::fetch( );
568 0 : if ( state.initialized( ) )
569 0 : fitsfile = state.resolve(testname);
570 :
571 : else {
572 0 : String var = EnvironmentVariable::get("CASAPATH");
573 0 : if (var.empty()) {
574 0 : var = EnvironmentVariable::get("AIPSPATH");
575 : }
576 0 : ThrowIf( var.empty(),
577 : "Neither CASAPATH nor AIPSPATH is set, so cannot locate data directory" );
578 0 : String fields[4];
579 0 : Int num = split(var, fields, 4, String(" "));
580 0 : ThrowIf (num <= 0, "Bad CASAPATH/AIPSPATH value: " + var);
581 :
582 0 : fitsfile = fields[0] + "/data/" + testname;
583 0 : }
584 :
585 : return fromFITS(
586 : outfile, fitsfile, 0, 0, false, overwrite
587 0 : );
588 0 : }
589 :
590 67 : void ImageFactory::_checkOutfile(const String& outfile, Bool overwrite) {
591 67 : if (! overwrite && ! outfile.empty()) {
592 9 : NewFile validfile;
593 9 : String errmsg;
594 9 : ThrowIf(
595 : ! validfile.valueOK(outfile, errmsg), errmsg
596 : );
597 9 : }
598 67 : }
599 :
600 118 : String ImageFactory::_imageCreationMessage(
601 : const String& outfile, const IPosition& shape,
602 : DataType dataType
603 : ) {
604 118 : auto blank = outfile.empty();
605 118 : ostringstream os;
606 : os << "Created "
607 118 : << (blank ? "Temp" : "Paged") << " image "
608 236 : << (blank ? "" : "'" + outfile + "'")
609 118 : << " of shape " << shape << " with "
610 118 : << dataType << " valued pixels.";
611 354 : return os.str();
612 118 : }
613 :
614 51 : String ImageFactory::_imageCreationMessage(
615 : const String& outfile, const ITUPLE& imagePtrs
616 : ) {
617 51 : if (auto x = std::get<0>(imagePtrs)) {
618 : return _imageCreationMessage(
619 102 : outfile, x->shape(), TpFloat
620 51 : );
621 : }
622 0 : else if (auto x = std::get<1>(imagePtrs)) {
623 : return _imageCreationMessage(
624 0 : outfile, x->shape(), TpComplex
625 0 : );
626 : }
627 0 : else if (auto x = std::get<2>(imagePtrs)) {
628 : return _imageCreationMessage(
629 0 : outfile, x->shape(), TpDouble
630 0 : );
631 : }
632 0 : else if (auto x = std::get<3>(imagePtrs)) {
633 : return _imageCreationMessage(
634 0 : outfile, x->shape(), TpDComplex
635 0 : );
636 : }
637 : else {
638 0 : ThrowCc("Logic Error");
639 51 : }
640 : }
641 :
642 :
643 : }
644 :
|