diff --git a/CMakeLists.txt b/CMakeLists.txt index 6baf8ea..a253fe4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,6 +9,22 @@ set (CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) +# Is casacore built with ADIOS 2 support ? default is NO +option(HAVE_ADIOS2 "casacore is built with ADIOS2 support" OFF) +if (HAVE_ADIOS2) + message(STATUS "Casacore is built with ADIOS2 support") + add_definitions(-DCASACORE_HAS_ADIOS2) +else() + message(STATUUS "Casacore is NOT built with ADIOS2 support") +endif() + +option(HAVE_MPI "casacore is built with MPI support" OFF) +if (HAVE_MPI) + message(STATUS "Casacore is built with MPI support") + add_definitions(-DHAVE_MPI) +else() + message(STATUUS "Casacore is NOT built with MPI support") +endif() # rpath setup for libraries diff --git a/synthesis/CMakeLists.txt b/synthesis/CMakeLists.txt index f388d94..d557c7a 100644 --- a/synthesis/CMakeLists.txt +++ b/synthesis/CMakeLists.txt @@ -158,6 +158,7 @@ set(synthesis_LIB_SRCS set(synthesis_PROGRAMS lwimager + tAdiosImage ) @@ -389,6 +390,8 @@ install (FILES Images/ImageFFT.h Images/ImageMetaData.h Images/ImagePolarimetry.h +Images/ADIOSImage.h +Images/ADIOSImage.tcc DESTINATION include/casarest/synthesis/Images COMPONENT casa_synthesis ) diff --git a/synthesis/Images/ADIOSImage.h b/synthesis/Images/ADIOSImage.h new file mode 100644 index 0000000..73181e5 --- /dev/null +++ b/synthesis/Images/ADIOSImage.h @@ -0,0 +1,195 @@ +#ifndef IMAGES_ADIOSIMAGE_H +#define IMAGES_ADIOSIMAGE_H + +//#ifdef CASACORE_HAS_ADIOS2 + +//# Includes +#include +#include +#include +#include +#include +#include +#include +#include + +//# Forward Declarations +#include + +// we need to be able to compile without MPI (although this class is not expected to be +// useful in such circumstances) +#ifdef HAVE_MPI + +#include + +#else + +#ifdef MPI_COMM_SELF + #error "MPI_COMM_SELF appears to be defined without MPI available - this shouldn't have happened!" +#endif +typedef int MPI_Comm; +// the following can be any number +#define MPI_COMM_SELF ((MPI_Comm)0x44000001) +#endif + +namespace casacore { + +/// @details this class is a subclass of the casacore ImageInterface. It uses +/// casacore adios2 to read and write image cube from/to file. The +/// class utilises the Adios2StMan as a Data Manager and it has two +/// columns named (1) "map" which stores the pixel value of the image cube +/// and (2) "mask" that keeps the mask of the image. These column names are +/// used as ADIOS variables. Also, this class does not support the retrival +/// of the mask of the image cube because this operation can cause excessive +/// memory usage on a compute node. However, the mask get/put operation per +/// image plane is supported. +template class ADIOSImage : public casacore::ImageInterface +{ +public: + + /// @brief create adios image accessor + /// @param[in] mapShape of the image + /// @param[in] coordinateInfo coordinate of the image + /// @param[in] nameOfNewFile filenamee + /// @param[in] tolerance used for compression + /// @param[in] configname name of configuration file + /// @param[in] rowNumber number of rows + ADIOSImage(const casacore::TiledShape& mapShape, + const casacore::CoordinateSystem& coordinateInfo, + const casacore::String& nameOfNewFile, + float tolerance = 0.0, + casacore::String configname = "", + casacore::uInt rowNumber = 0); + + /// @brief create adios image accessor + /// @param[in] comms MPI communicator + /// @param[in] mapShape of the image + /// @param[in] coordinateInfo coordinate of the image + /// @param[in] nameOfNewFile filenamee + /// @param[in] tolerance used for compression + /// @param[in] configname name of configuration file + /// @param[in] rowNumber number of rows + ADIOSImage(MPI_Comm comms, + const casacore::TiledShape& mapShape, + const casacore::CoordinateSystem& coordinateInfo, + const casacore::String& nameOfNewFile, + float tolerance = 0.0, + casacore::String configname = "", + casacore::uInt rowNumber = 0); + + /// @brief create adios image accessor + /// @param[in] filename name of the file to be created + /// @param[in] tolerance used for compression + /// @param[in] configname name of configuration file + /// @param[in] spec mask value + /// @param[in] rowNumber number of rows + explicit ADIOSImage(const casacore::String &filename, + float tolerance = 0.0, + casacore::String configname = "", + casacore::uInt rowNumber = 0); + + /// @brief create adios image accessor + /// @param[in] comms MPI communicator + /// @param[in] filename name of the file to be created + /// @param[in] tolerance used for compression + /// @param[in] configname name of configuration file + /// @param[in] spec mask value + /// @param[in] rowNumber number of rows + ADIOSImage(MPI_Comm comms, + const casacore::String &filename, + float tolerance = 0.0, + casacore::String configname = "", + casacore::uInt rowNumber = 0); + + /// @brief copy constructor + /// @param[in] other an instance to copy from + ADIOSImage (const ADIOSImage& other); + + casacore::Table& table() { return itsTable; } + + static casacore::String className() + { return "ADIOSImage"; } + + /// @brief Create a table that contains an array of columns to be managed by Adios2StMan + /// @param[in] shape shape of the array/data + /// @param[in] rowNumber number of rows + /// @param[in] filename name of the file + void makeNewTable (const casacore::TiledShape& shape, casacore::uInt rowNumber, casacore::String filename); + + ///@brief override base abstract methods + casacore::ImageInterface* cloneII() const override; + casacore::String imageType() const override; + void resize (const casacore::TiledShape& newShape) override; + const casacore::LatticeRegion* getRegionPtr() const override; + casacore::Bool setImageInfo(const casacore::ImageInfo& info) override; + casacore::Bool setCoordinateInfo (const casacore::CoordinateSystem& coords); + casacore::IPosition shape() const; + ///@brief get a slice of the image cube + casacore::Bool doGetSlice (casacore::Array& buffer, const casacore::Slicer& theSlice); + ///@brief get a slice of the mask. + casacore::Bool doGetMaskSlice (casacore::Array& buffer, const casacore::Slicer& theSlice); + ///@brief put a slice of data into the image cube + void doPutSlice (const casacore::Array& sourceBuffer, const casacore::IPosition& where, + const casacore::IPosition& stride); + void doPutMaskSlice(const casacore::Array &mask, const casacore::IPosition& where, + const casacore::IPosition& stride); + casacore::Bool setUnits (const casacore::Unit& newUnits) override; + casacore::String name(casacore::Bool stripPath=casacore::False) const override; + + ///@brief override base virtual methods + casacore::Bool ok() const; + casacore::Bool setMiscInfo (const casacore::RecordInterface& newInfo) override; + casacore::Bool isPaged() const; + + ///@brief reopen the table column + void reopenColumn(); + + // masking operation on the whole image cube is not supported + bool isMasked() const override { return false; } + bool hasPixelMask() const override { return false; } + virtual const Lattice& pixelMask() const override; + virtual Lattice& pixelMask() override; + + static casacore::Table& getTable(void* imagePtr, casacore::Bool writable); +// MV: the code seems to build file with the following methods declared private (as they were in the +// PagedImage interface where it presumably was copied from). Unless there is a good reason not to, it +// would be better to keep them private. I won't insist on further design improvements for code which +// goes into casarest/casacore. +private: + //rewritten PagedImage private functions + // @see casacore documentation for more details + void attach_logtable(); + void setTableType(); + void restoreAll (const casacore::TableRecord& rec); + void restoreImageInfo (const casacore::TableRecord& rec); + void restoreUnits (const casacore::TableRecord& rec); + void restoreMiscInfo (const casacore::TableRecord& rec); + + void reopenRW(); + + ///@brief tolerance used for compression + float itsTolerance; + casacore::ArrayColumn itsDataColumn; + casacore::ArrayColumn itsMaskColumn; + casacore::Table itsTable; + + const casacore::uInt itsRow; + casacore::String itsConfig; + // @brief MPI communicator the default MPI_COMM_SELF is assigned in the constructor (unless proper communicator is provided) + MPI_Comm itsIOComms; + int rank() const; + void setup(const casacore::TiledShape& shape, casacore::uInt rowNumber, + const casacore::String& filename, const casacore::CoordinateSystem& coordinateInfo); + void setup(const casacore::String& filename); +}; +// The tcc include must be here and not after the namespace +// otherwise the template definition in the tcc file must have +// askap::imageaccess::ADIOSImage::blah(...) instead of +// ADIOSImage::blah(...) +#include +} +//#else +//#error "Using ADIOSImage requires building casacore with ADIOS2 support. It also requires building casarest with -DHAVE_ADIOS2=YES" +//#endif // CASACORE_HAS_ADIOS2 + +#endif // IMAGES_ADIOSIMAGE_H diff --git a/synthesis/Images/ADIOSImage.tcc b/synthesis/Images/ADIOSImage.tcc new file mode 100644 index 0000000..b829bd1 --- /dev/null +++ b/synthesis/Images/ADIOSImage.tcc @@ -0,0 +1,601 @@ +#ifndef IMAGES_ADIOSIMAGE_TCC +#define IMAGES_ADIOSIMAGE_TCC + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +template +ADIOSImage::ADIOSImage ( + const casacore::TiledShape& shape, + const casacore::CoordinateSystem& coordinateInfo, + const casacore::String& filename, + float tolerance, + casacore::String configname, + casacore::uInt rowNumber) +: /* casacore::ImageInterface(casacore::RegionHandlerTable(getTable, this)), */ + itsTolerance(tolerance), itsConfig(configname), itsRow(rowNumber), + itsIOComms(MPI_COMM_SELF) +{ +#ifdef CASACORE_HAS_ADIOS2 + this->setup(shape,rowNumber,filename, coordinateInfo); +#else + throw casacore::AipsError("Casacore is not built with ADIOS2 support"); +#endif +} + +template +ADIOSImage::ADIOSImage ( + MPI_Comm comms, + const casacore::TiledShape& shape, + const casacore::CoordinateSystem& coordinateInfo, + const casacore::String& filename, + float tolerance, + casacore::String configname, + casacore::uInt rowNumber) +: /* casacore::ImageInterface(casacore::RegionHandlerTable(getTable, this)), */ + itsTolerance(tolerance),itsConfig(configname),itsRow(rowNumber), + itsIOComms(comms) +{ +#if defined CASACORE_HAS_ADIOS2 + this->setup(shape,rowNumber,filename,coordinateInfo); +#else + throw casacore::AipsError("Casacore is not built with ADIOS2 support"); +#endif +} + +template +ADIOSImage::ADIOSImage ( + const casacore::String& filename, + float tolerance, + casacore::String configname, + casacore::uInt rowNumber) +: /* casacore::ImageInterface(casacore::RegionHandlerTable(getTable, this)), */ + itsTolerance(tolerance), itsConfig(configname),itsRow(rowNumber), + itsIOComms(MPI_COMM_SELF) +{ +#ifdef CASACORE_HAS_ADIOS2 + this->setup(filename); +#else + throw casacore::AipsError("Casacore is not built with ADIOS2 support"); +#endif +} + +template +ADIOSImage::ADIOSImage ( + MPI_Comm comms, + const casacore::String& filename, + float tolerance, + casacore::String configname, + casacore::uInt rowNumber) +: /* casacore::ImageInterface(casacore::RegionHandlerTable(getTable, this)), */ + itsTolerance(tolerance), itsConfig(configname),itsRow(rowNumber), + itsIOComms(comms) +{ +#ifdef CASACORE_HAS_ADIOS2 + this->setup(filename); +#else + throw casacore::AipsError("casacore and/or casarest are not built with ADIOS2 support"); +#endif +} + +template +ADIOSImage::ADIOSImage (const ADIOSImage& other) +: casacore::ImageInterface(other), + itsDataColumn(other.itsDataColumn), + itsMaskColumn(other.itsMaskColumn), + itsRow(other.itsRow) +{ +} + +template +void ADIOSImage::makeNewTable(const casacore::TiledShape& shape, casacore::uInt rowNumber, casacore::String filename) +{ + const casacore::IPosition latShape = shape.shape(); + + const casacore::uInt ndim = latShape.nelements(); + + casacore::TableDesc description; + description.addColumn(casacore::ArrayColumnDesc("map", + casacore::String("version 4.0"), + latShape, casacore::ColumnDesc::FixedShape)); + description.addColumn(casacore::ArrayColumnDesc("mask", + casacore::String("version 4.0"), + latShape, casacore::ColumnDesc::FixedShape)); + + casacore::SetupNewTable newtab(filename, description, casacore::Table::New); + + + std::shared_ptr adios2StMan; + if (itsConfig == "") { + std::string engineType = ""; + std::map engineParams; + std::vector> transportParams; + std::map m; + std::map m2; + std::vector> v; + if ( itsTolerance > 0.000001 ) { + std::string accuracy = std::to_string(itsTolerance); + m["Variable"] = "map"; + m["Operator"] = "mgard"; + m["accuracy"] = accuracy; + m["s"] = "0.0"; + m["mode"] = "ABS"; + + m2["Variable"] = "mask"; + m2["Operator"] = "mgard"; + m["accuracy"] = accuracy; + m["s"] = "0.0"; + m["mode"] = "ABS"; + + v.push_back(m); + v.push_back(m2); + if ( itsIOComms != MPI_COMM_SELF ) { +#ifdef CASACORE_HAS_ADIOS2 + adios2StMan.reset(new casacore::Adios2StMan(itsIOComms,engineType, + engineParams,transportParams,v)); +#else +#warning "Warning ! CASACORE is not built with ADIOS2 support. But use with MPI" +#endif + } else { + adios2StMan.reset(new casacore::Adios2StMan(engineType, engineParams,transportParams,v)); + } + newtab.bindColumn("map", *adios2StMan); + newtab.bindColumn("mask", *adios2StMan); + } else { + m["Variable"] = "map"; + m2["Variable"] = "mask"; + v.push_back(m); + v.push_back(m2); + if ( itsIOComms != MPI_COMM_SELF ) { +#ifdef CASACORE_HAS_ADIOS2 + adios2StMan.reset(new casacore::Adios2StMan(itsIOComms,engineType, + engineParams,transportParams,v)); +#else +#warning "Warning !CASACORE is not built with ADIOS2 support. But use with MPI" +#endif + } else { + adios2StMan.reset(new casacore::Adios2StMan(engineType, engineParams, + transportParams,v)); + } + + newtab.bindColumn("map", *adios2StMan); + newtab.bindColumn("mask", *adios2StMan); + } + } else { + // invoke itsConfiguration based call + casacore::Adios2StMan::from_config_t from_config {}; + if ( itsIOComms != MPI_COMM_SELF ) { +#ifdef CASACORE_HAS_ADIOS2 + adios2StMan.reset(new casacore::Adios2StMan(itsIOComms,itsConfig, from_config)); +#else +#warning "!Warning! CASACORE is not built with ADIOS2 support. But use with MPI" +#endif + } else { + adios2StMan.reset(new casacore::Adios2StMan(itsConfig, from_config)); + } + newtab.bindColumn("map", *adios2StMan); + newtab.bindColumn("mask", *adios2StMan); + } + + itsTable = casacore::Table(itsIOComms, newtab); + itsDataColumn = casacore::ArrayColumn(itsTable,"map"); + itsMaskColumn = casacore::ArrayColumn(itsTable,"mask"); + const casacore::uInt rows = itsTable.nrow(); + if ((rowNumber + 1) > rows) { + itsTable.addRow(rowNumber - rows + 1); + for (casacore::rownr_t row = rows; row <= rowNumber - rows; row++){ + itsDataColumn.setShape(row, latShape); + itsMaskColumn.setShape(row, latShape); + } + } +} + +template +casacore::Bool ADIOSImage::setUnits(const casacore::Unit& newUnits) +{ + this->setUnitMember (newUnits); + casacore::Table& tab = table(); + if (tab.keywordSet().isDefined("units")) { + tab.rwKeywordSet().removeField("units"); + } + if (!tab.isWritable()){ + tab.reopenRW(); + } + tab.rwKeywordSet().define("units", newUnits.getName()); + return casacore::True; +} + +template +casacore::Bool ADIOSImage::setImageInfo(const casacore::ImageInfo& info) +{ + // Set imageinfo in base class. + casacore::Bool ok = casacore::ImageInterface::setImageInfo(info); + if (ok) { + // Make persistent in table keywords. + casacore::Table& tab = table(); + // Delete existing one if there. + if (tab.keywordSet().isDefined("imageinfo")) { + tab.rwKeywordSet().removeField("imageinfo"); + } + // Convert info to a record and save as keyword. + casacore::TableRecord rec; + casacore::String error; + if (this->imageInfo().toRecord(error, rec)) { + tab.rwKeywordSet().defineRecord("imageinfo", rec); + } else { + // Could not convert to record. + casacore::LogIO os; + os << casacore::LogIO::SEVERE << "Error saving ImageInfo in image " << name() + << "; " << error << casacore::LogIO::POST; + ok = casacore::False; + } + } + return ok; +} + +template +casacore::Bool ADIOSImage::setMiscInfo (const casacore::RecordInterface& newInfo) +{ + this->setMiscInfoMember(newInfo); + casacore::Table& tab = table(); + if (tab.keywordSet().isDefined("miscinfo")) { + tab.rwKeywordSet().removeField("miscinfo"); + } + tab.rwKeywordSet().defineRecord("miscinfo", newInfo); + return casacore::True; +} + +template +void ADIOSImage::attach_logtable() +{ + // Open logtable as readonly if main table is not writable. + casacore::Table& tab = table(); + this->setLogMember(casacore::LoggerHolder (name() + "/logtable", tab.isWritable())); + // Insert the keyword if possible and if it does not exist yet. + if (tab.isWritable() && ! tab.keywordSet().isDefined ("logtable")) { + tab.rwKeywordSet().defineTable("logtable", casacore::Table(name() + "/logtable")); + } +} + +template +void ADIOSImage::setTableType() +{ + casacore::TableInfo& info(table().tableInfo()); + const casacore::String reqdType = info.type(casacore::TableInfo::PAGEDIMAGE); + if (info.type() != reqdType) { + info.setType(reqdType); + } + const casacore::String reqdSubType = info.subType(casacore::TableInfo::PAGEDIMAGE); + if (info.subType() != reqdSubType) { + info.setSubType(reqdSubType); + } +} + +template +void ADIOSImage::restoreAll (const casacore::TableRecord& rec) +{ + // Restore the coordinate system from the record + // MV: I am not sure whether we're supposed to take the ownership of the returned raw pointer, but the original code + // written with raw pointers did the equivalent thing + //std::unique_ptr restoredCoords(casacore::CoordinateSystem::restore(rec, "coords")); + casacore::CoordinateSystem* restoredCoords(casacore::CoordinateSystem::restore(rec, "coords")); + AlwaysAssert(restoredCoords, casacore::AipsError); + this->setCoordsMember(*restoredCoords); + // Restore the image info. + restoreImageInfo (rec); + // Restore the units. + restoreUnits (rec); + // Restore the miscinfo. + restoreMiscInfo (rec); +} + +template +void ADIOSImage::restoreImageInfo (const casacore::TableRecord& rec) +{ + if (rec.isDefined("imageinfo")) { + casacore::String error; + casacore::ImageInfo info; + casacore::Bool ok = info.fromRecord (error, rec.asRecord("imageinfo")); + if (ok) { + this->setImageInfoMember(info); + } else { + casacore::LogIO os; + os << casacore::LogIO::WARN << "Failed to restore the ImageInfo in image " << name() + << "; " << error << casacore::LogIO::POST; + } + } +} + +template +void ADIOSImage::restoreUnits (const casacore::TableRecord& rec) +{ + casacore::Unit retval; + casacore::String unitName; + if (rec.isDefined("units")) { + if (rec.dataType("units") != casacore::TpString) { + casacore::LogIO os; + os << casacore::LogOrigin("ADIOSImage", "units()", WHERE) + << "'units' keyword in image table is not a string! Units not restored." + << casacore::LogIO::SEVERE << casacore::LogIO::POST; + } else { + rec.get("units", unitName); + } + } + if (! unitName.empty()) { + // OK, non-empty unit, see if it's valid, if not try some known things to + // make a valid unit out of it. + if (! casacore::UnitVal::check(unitName)) { + // Beam and Pixel are the most common undefined units + casacore::UnitMap::putUser("Pixel",casacore::UnitVal(1.0),"Pixel unit"); + casacore::UnitMap::putUser("Beam",casacore::UnitVal(1.0),"Beam area"); + } + if (! casacore::UnitVal::check(unitName)) { + // OK, maybe we need FITS + casacore::UnitMap::addFITS(); + } + if (!casacore::UnitVal::check(unitName)) { + // I give up! + casacore::LogIO os; + casacore::UnitMap::putUser(unitName, casacore::UnitVal(1.0, casacore::UnitDim::Dnon), unitName); + os << casacore::LogIO::WARN << "FITS unit \"" << unitName + << "\" unknown to CASA - will treat it as non-dimensional." + << casacore::LogIO::POST; + retval.setName(unitName); + retval.setValue(casacore::UnitVal(1.0, casacore::UnitDim::Dnon)); + } else { + retval = casacore::Unit(unitName); + } + } + this->setUnitMember(retval); +} + +template +void ADIOSImage::restoreMiscInfo (const casacore::TableRecord& rec) +{ + if (rec.isDefined("miscinfo") && + rec.dataType("miscinfo") == casacore::TpRecord) { + this->setMiscInfoMember (rec.asRecord ("miscinfo")); + } +} + +template +casacore::Table& ADIOSImage::getTable (void* imagePtr, casacore::Bool writable) +{ + ADIOSImage* im = static_cast*>(imagePtr); + AlwaysAssert(im != NULL, casacore::AipsError); + return im->itsTable; +} + +template +casacore::Bool ADIOSImage::setCoordinateInfo (const casacore::CoordinateSystem& coords) +{ + casacore::Bool ok = casacore::ImageInterface::setCoordinateInfo(coords); + if (ok) { + casacore::Table& tab = table(); + // Update the coordinates + if (tab.keywordSet().isDefined("coords")) { + tab.rwKeywordSet().removeField("coords"); + } + if (!(this->coordinates().save(tab.rwKeywordSet(), "coords"))) { + casacore::LogIO os; +os << casacore::LogIO::SEVERE << "Error saving coordinates in image " << name() + << casacore::LogIO::POST; +ok = casacore::False; + } + } + return ok; +} + +template +casacore::IPosition ADIOSImage::shape() const +{ + return itsDataColumn.shape(itsRow); +} + +template +casacore::String ADIOSImage::name(casacore::Bool stripPath) const +{ + return itsTable.tableName(); +} + +template +casacore::Bool ADIOSImage::ok() const +{ + return (itsDataColumn.ndim(itsRow) == this->coordinates().nPixelAxes()); +} + +template +casacore::Bool ADIOSImage::doGetSlice(casacore::Array& buffer, const casacore::Slicer& theSlice) +{ + itsDataColumn.getSlice(itsRow, theSlice, buffer, casacore::True); + return casacore::False; +} + +template +casacore::Bool ADIOSImage::doGetMaskSlice(casacore::Array& mask, const casacore::Slicer& theSlice) +{ + itsMaskColumn.getSlice(itsRow, theSlice, mask, casacore::True); + return casacore::False; +} + +template +void ADIOSImage::doPutSlice(const casacore::Array& sourceBuffer, const casacore::IPosition& where, const casacore::IPosition& stride) +{ + casacore::Array maskArr = ! casacore::isNaN(sourceBuffer); + + const casacore::uInt arrDim = sourceBuffer.ndim(); + const casacore::uInt latDim = this->ndim(); + AlwaysAssert(arrDim <= latDim, casacore::AipsError); + if (arrDim == latDim) { + casacore::Slicer section(where, sourceBuffer.shape(), stride, casacore::Slicer::endIsLength); + itsDataColumn.putSlice (itsRow, section, sourceBuffer); + itsMaskColumn.putSlice (itsRow, section, maskArr); + } else { + casacore::Array degenerateArr(sourceBuffer.addDegenerate(latDim-arrDim)); + casacore::Slicer section(where, degenerateArr.shape(), stride, casacore::Slicer::endIsLength); + itsDataColumn.putSlice (itsRow, section, degenerateArr); + casacore::Array degenerateMaskArr(maskArr.addDegenerate(latDim-arrDim)); + itsMaskColumn.putSlice (itsRow, section, degenerateMaskArr); + } +} + +template +void ADIOSImage::doPutMaskSlice(const casacore::Array &mask, const casacore::IPosition& where, const casacore::IPosition& stride) +{ + const casacore::uInt arrDim = mask.ndim(); + const casacore::uInt latDim = this->ndim(); + AlwaysAssert(arrDim <= latDim, casacore::AipsError); + if (arrDim == latDim) { + casacore::Slicer section(where, mask.shape(), stride, casacore::Slicer::endIsLength); + itsMaskColumn.putSlice (itsRow, section, mask); + } else { + casacore::Array degenerateArr(mask.addDegenerate(latDim-arrDim)); + casacore::Slicer section(where, degenerateArr.shape(), stride, casacore::Slicer::endIsLength); + itsMaskColumn.putSlice (itsRow, section, degenerateArr); + } +} + +template +const casacore::LatticeRegion* ADIOSImage::getRegionPtr() const +{ + return nullptr; + throw (AipsError ("ADIOSImage::getRegionPtr - not implemented")); +} + +template +casacore::ImageInterface* ADIOSImage::cloneII() const +{ + return new ADIOSImage (*this); +} + +template +void ADIOSImage::resize (const casacore::TiledShape& newShape) +{ + if (newShape.shape().nelements() != this->coordinates().nPixelAxes()) { + throw(casacore::AipsError("ADIOSImage::resize: coordinate info is " + "the incorrect shape.")); + } + casacore::IPosition tileShape = newShape.tileShape(); + itsDataColumn.setShape (itsRow, newShape.shape(), tileShape); + itsMaskColumn.setShape (itsRow, newShape.shape(), tileShape); +} + +template +casacore::String ADIOSImage::imageType() const +{ + return className(); +} + +template +void ADIOSImage::reopenRW() +{ + if (!itsTable.isWritable()) { + itsTable.reopenRW(); + itsDataColumn = casacore::ArrayColumn(itsTable, "map"); + itsMaskColumn = casacore::ArrayColumn(itsTable, "mask"); + } +} + +template +void ADIOSImage::reopenColumn() +{ + itsDataColumn = casacore::ArrayColumn(itsTable, "map"); + itsMaskColumn = casacore::ArrayColumn(itsTable, "mask"); +} + +template +casacore::Bool ADIOSImage::isPaged() const +{ + return casacore::True; +} +template +casacore::Lattice& ADIOSImage::pixelMask() +{ + throw (AipsError ("ADIOSImage::pixelMask - not implemented")); +} + +template +const casacore::Lattice& ADIOSImage::pixelMask() const +{ + throw (AipsError ("ADIOSImage::pixelMask - not implemented")); +} + +template +int ADIOSImage::rank() const +{ +#ifdef HAVE_MPI + int size; + int result = MPI_Comm_size(itsIOComms, &size); + DebugAssert(result == MPI_SUCCESS, casacore::AipsError); + int rank; + result = MPI_Comm_rank(itsIOComms, &rank); + DebugAssert(result == MPI_SUCCESS, casacore::AipsError); + + return rank; +#else + return 0; +#endif +} + +template +void ADIOSImage::setup(const casacore::TiledShape& shape, + casacore::uInt rowNumber, + const casacore::String& filename, + const casacore::CoordinateSystem& coordinateInfo) +{ + makeNewTable(shape, rowNumber, filename); + const int r = rank(); + if ( itsIOComms == MPI_COMM_SELF || r == 0 ) { + attach_logtable(); + setTableType(); + } + AlwaysAssert(setCoordinateInfo(coordinateInfo), casacore::AipsError); +} + +template +void ADIOSImage::setup(const casacore::String& filename) +{ + itsTable = casacore::Table(filename,casacore::Table::TableOption::Old); + itsDataColumn = casacore::ArrayColumn(itsTable, "map"); + itsMaskColumn = casacore::ArrayColumn(itsTable, "mask"); + if ( itsIOComms == MPI_COMM_SELF ) { + attach_logtable(); + } + restoreAll (itsTable.keywordSet()); +} +#endif diff --git a/synthesis/apps/tAdiosImage.cc b/synthesis/apps/tAdiosImage.cc new file mode 100644 index 0000000..6cae2a3 --- /dev/null +++ b/synthesis/apps/tAdiosImage.cc @@ -0,0 +1,9 @@ + +#include + + +int main(int argc, char** argv) +{ + casacore::ADIOSImage adios("test"); + return 0; +}