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: aips2-request@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 : }
81 0 : return image;
82 : }
83 :
84 248 : 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 248 : );
94 : }
95 :
96 6 : 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 6 : );
106 : }
107 :
108 2 : 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 2 : );
118 : }
119 :
120 2 : 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 2 : );
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 703 : ITUPLE ImageFactory::fromImage(
175 : const String& outfile, const String& infile,
176 : const Record& region, const String& mask, Bool dropdeg,
177 : Bool overwrite
178 : ) {
179 1406 : auto imagePtrs = fromFile(infile, False);
180 1406 : auto imageF = std::get<0>(imagePtrs);
181 1406 : auto imageC = std::get<1>(imagePtrs);
182 1406 : auto imageD = std::get<2>(imagePtrs);
183 1406 : auto imageDC = std::get<3>(imagePtrs);
184 703 : if (imageF) {
185 1405 : imageF = SubImageFactory<Float>::createImage(
186 703 : *imageF, outfile, region,
187 : mask, dropdeg, overwrite, false, false
188 702 : );
189 702 : 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 1404 : LogIO mylog;
213 702 : mylog << LogOrigin("ImageFactory", __func__);
214 702 : ITUPLE ret(imageF, imageC, imageD, imageDC);
215 702 : mylog << LogIO::NORMAL << _imageCreationMessage(outfile, ret)
216 702 : << LogIO::POST;
217 1404 : return ret;
218 : }
219 :
220 21 : pair<SPIIF, SPIIC> ImageFactory::fromRecord(
221 : const RecordInterface& rec, const String& name
222 : ) {
223 21 : auto mytype = rec.type(rec.fieldNumber("imagearray"));
224 21 : pair<SPIIF, SPIIC> imagePair;
225 21 : if (isReal(mytype)) {
226 21 : imagePair.first = _fromRecord<Float>(rec, name);
227 : }
228 : else {
229 0 : imagePair.second = _fromRecord<Complex>(rec, name);
230 : }
231 20 : return imagePair;
232 : }
233 :
234 321 : void ImageFactory::_centerRefPix(
235 : CoordinateSystem& csys, const IPosition& shape
236 : ) {
237 321 : Int after = -1;
238 321 : Int iS = csys.findCoordinate(Coordinate::STOKES, after);
239 321 : Int sP = -1;
240 321 : if (iS >= 0) {
241 228 : Vector<Int> pixelAxes = csys.pixelAxes(iS);
242 228 : sP = pixelAxes(0);
243 : }
244 642 : Vector<Double> refPix = csys.referencePixel();
245 1448 : for (Int i = 0; i < Int(refPix.nelements()); i++) {
246 1127 : if (i != sP)
247 899 : refPix(i) = Double(shape(i) / 2);
248 : }
249 321 : csys.setReferencePixel(refPix);
250 321 : }
251 :
252 428 : CoordinateSystem* ImageFactory::_makeCoordinateSystem(
253 : const Record& coordinates, const IPosition& shape
254 : ) {
255 428 : std::unique_ptr<CoordinateSystem> csys;
256 428 : if (coordinates.nfields() == 1) {
257 : // must be a record as an element
258 387 : Record tmp(coordinates.asRecord(RecordFieldId(0)));
259 387 : csys.reset(CoordinateSystem::restore(tmp, ""));
260 : }
261 : else {
262 41 : csys.reset(CoordinateSystem::restore(coordinates, ""));
263 : }
264 : // Fix up any body longitude ranges...
265 856 : String errMsg;
266 428 : if (csys->hasDirectionCoordinate()) {
267 820 : auto axes = csys->directionAxesNumbers();
268 410 : if (min(axes) >= 0) {
269 410 : 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 : }
281 : }
282 856 : return csys.release();
283 : }
284 :
285 22692 : ITUPLE ImageFactory::fromFile(const String& infile, Bool cache) {
286 22692 : _checkInfile(infile);
287 22692 : ComponentListImage::registerOpenFunction();
288 45384 : unique_ptr<LatticeBase> latt(ImageOpener::openImage(infile));
289 22695 : ThrowIf (! latt, "Unable to open image " + infile);
290 22689 : auto imagePtrs = _fromLatticeBase(latt);
291 45378 : auto imageF = std::get<0>(imagePtrs);
292 22689 : if (
293 : imageF
294 22689 : && imageF->imageType().contains(ComponentListImage::IMAGE_TYPE)
295 : ) {
296 0 : std::dynamic_pointer_cast<ComponentListImage>(imageF)->setCache(cache);
297 : }
298 45378 : return imagePtrs;
299 : }
300 :
301 106 : SPIIF ImageFactory::fromFile(
302 : const casacore::String& filename, casacore::Float, casacore::Bool cache
303 : ) {
304 212 : auto t = fromFile(filename, cache);
305 212 : return std::get<0>(t);
306 : }
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 : }
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 : }
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 : }
328 :
329 22689 : ITUPLE ImageFactory::_fromLatticeBase(
330 : unique_ptr<LatticeBase>& latt
331 : ) {
332 22689 : DataType dataType = latt->dataType();
333 22689 : tuple<SPIIF, SPIIC, SPIID, SPIIDC> ret(nullptr, nullptr, nullptr, nullptr);
334 22689 : if (dataType == TpFloat) {
335 : auto f = SPIIF(
336 45376 : dynamic_cast<ImageInterface<Float> *>(latt.release())
337 68064 : );
338 22688 : ThrowIf(! f, "Could not cast LatticeBase to ImageInterface<Float>");
339 22688 : std::get<0>(ret) = f;
340 : }
341 1 : else if (dataType == TpComplex) {
342 : auto c = SPIIC(
343 2 : dynamic_cast<ImageInterface<Complex> *>(latt.release())
344 3 : );
345 1 : ThrowIf(! c, "Could not cast LatticeBase to ImageInterface<Complex>");
346 1 : std::get<1>(ret) = c;
347 : }
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 : }
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 : }
362 : else {
363 0 : ostringstream os;
364 0 : os << dataType;
365 0 : throw AipsError("unsupported image data type " + os.str());
366 : }
367 22689 : return ret;
368 : }
369 :
370 22692 : void ImageFactory::_checkInfile(const String& infile) {
371 22692 : ThrowIf(
372 : infile.empty(), "File name is empty"
373 : );
374 45384 : File thefile(infile);
375 22692 : ThrowIf(
376 : ! thefile.exists(),
377 : "File " + infile + " does not exist."
378 : );
379 22692 : }
380 :
381 12 : 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 12 : _checkOutfile(outfile, overwrite);
387 12 : ThrowIf(
388 : whichrep < 0,
389 : "The Coordinate Representation index must be non-negative"
390 : );
391 12 : ImageInterface<Float> *x = nullptr;
392 24 : String error;
393 36 : Bool rval = ImageFITSConverter::FITSToImage(
394 : x, error, outfile, fitsfile, whichrep, whichhdu,
395 12 : HostInfo::memoryFree() / 1024, overwrite, zeroBlanks
396 : );
397 12 : SPIIF pOut(x);
398 12 : ThrowIf(! rval || ! pOut, error);
399 24 : return pOut;
400 : }
401 :
402 19 : void ImageFactory::rename(
403 : SPIIF& image, const String& name, const Bool overwrite
404 : ) {
405 19 : image = std::get<0>(_rename(image, name, overwrite));
406 19 : }
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 3 : 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 6 : LogIO log;
493 3 : log << LogOrigin("ImageFactory", __func__);
494 3 : _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 3 : if (image->isMasked()) {
498 : log << LogIO::NORMAL << "Applying mask of name '"
499 1 : << image->getDefaultMask() << "'" << LogIO::POST;
500 : }
501 6 : IPosition keepAxes;
502 3 : if (! dropdeg) {
503 3 : 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 : }
520 : }
521 : }
522 6 : AxesSpecifier axesSpecifier;
523 3 : if (dropdeg) {
524 0 : axesSpecifier = AxesSpecifier(false);
525 : }
526 3 : 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 6 : );
532 : // FIXME remove when the casacore interface has been updated to const
533 6 : SPIIF myclone(subImage->cloneII());
534 6 : String error;
535 3 : 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 3 : }
548 :
549 1 : 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 2 : String testname;
555 1 : if (imagetype.contains("cube")) {
556 0 : testname = "demo/Images/test_imageFloat.fits";
557 : }
558 1 : else if (imagetype.contains("2d")) {
559 1 : testname = "demo/Images/imagetestimage.fits";
560 : }
561 : else {
562 0 : ThrowCc("imageType must be either \"cube\" or \"2d\"");
563 : }
564 :
565 2 : String fitsfile;
566 :
567 1 : const casacore::AppState &state = casacore::AppStateSource::fetch( );
568 1 : if ( state.initialized( ) )
569 1 : 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 : }
584 :
585 : return fromFITS(
586 : outfile, fitsfile, 0, 0, false, overwrite
587 2 : );
588 : }
589 :
590 804 : void ImageFactory::_checkOutfile(const String& outfile, Bool overwrite) {
591 804 : if (! overwrite && ! outfile.empty()) {
592 458 : NewFile validfile;
593 458 : String errmsg;
594 229 : ThrowIf(
595 : ! validfile.valueOK(outfile, errmsg), errmsg
596 : );
597 : }
598 804 : }
599 :
600 1472 : String ImageFactory::_imageCreationMessage(
601 : const String& outfile, const IPosition& shape,
602 : DataType dataType
603 : ) {
604 1472 : auto blank = outfile.empty();
605 1472 : ostringstream os;
606 : os << "Created "
607 1472 : << (blank ? "Temp" : "Paged") << " image "
608 3348 : << (blank ? "" : "'" + outfile + "'")
609 1472 : << " of shape " << shape << " with "
610 1472 : << dataType << " valued pixels.";
611 2944 : return os.str();
612 : }
613 :
614 702 : String ImageFactory::_imageCreationMessage(
615 : const String& outfile, const ITUPLE& imagePtrs
616 : ) {
617 1404 : if (auto x = std::get<0>(imagePtrs)) {
618 : return _imageCreationMessage(
619 1404 : outfile, x->shape(), TpFloat
620 702 : );
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 : }
640 : }
641 :
642 :
643 : }
644 :
|