Commit bdecb3b2 authored by Paal Kvamme's avatar Paal Kvamme
Browse files

Finish the reopen() code, now updating annotation etc. only if explicitly set.

parent 0da767c0
......@@ -1353,12 +1353,6 @@ IZgyWriter::open(const ZgyWriterArgs& args)
* discard the original once we know that the new file is good.
* But, (a) rename on the cloud is difficult and (b) once this code
* gets implemented properly that trick isn't possible anyway.
*
* \li The current implementation is incomplete in the sense that it
* requires the caller to re-specify the unit, annotation, and world
* coordinate information. If not specified they will revert to the
* default value instead of being left unchanged. That particular
* problem is fairly easy to fix. Stay tuned.
*/
std::shared_ptr<IZgyWriter>
IZgyWriter::reopen(const ZgyWriterArgs& args)
......@@ -1388,18 +1382,12 @@ IZgyWriter::reopen(const ZgyWriterArgs& args)
// (usually zero) value. This should not make any difference because
// OpenZGY hides that distinction anyway.
newargs
// .merge(update_args) // Not implemented yet!
// TODO: Should only be merged if explicitly set.
.merge(args)
.filename(args._filename)
.iocontext(args._iocontext)
.compressor(args._compressor)
.lodcompressor(args._lodcompressor)
.ilstart(args._annotstart[0]).ilinc(args._annotinc[0])
.xlstart(args._annotstart[1]).xlinc(args._annotinc[1])
.zstart(args._zstart).zinc(args._zinc)
.corners(args._corners)
.hunit(args._hunitdim, args._hunitname, args._hunitfactor)
.zunit(args._zunitdim, args._zunitname, args._zunitfactor);
.lodcompressor(args._lodcompressor);
std::shared_ptr<IZgyWriter> writer = IZgyWriter::open(newargs);
// Cast is ok because all supported data types (int8, int16, float)
// can be cast to a single precision float without loss of accuracy.
......@@ -1436,6 +1424,38 @@ ZgyWriterArgs::metafrom(const std::shared_ptr<OpenZGY::IZgyReader>& reader)
return *this;
}
ZgyWriterArgs&
ZgyWriterArgs::merge(const ZgyWriterArgs& other)
{
if (other._have_size)
size(other._size[0], other._size[1], other._size[2]);
if (other._have_bricksize)
bricksize(other._bricksize[0], other._bricksize[1], other._bricksize[2]);
if (other._have_datatype)
datatype(other._datatype);
if (other._have_datarange)
datarange(other._datarange[0], other._datarange[1]);
if (other._have_zunit)
zunit(other._zunitdim, other._zunitname, other._zunitfactor);
if (other._have_hunit)
hunit(other._hunitdim, other._hunitname, other._hunitfactor);
if (other._have_ilstart)
ilstart(other._annotstart[0]);
if (other._have_ilinc)
ilinc(other._annotinc[0]);
if (other._have_xlstart)
xlstart(other._annotstart[1]);
if (other._have_xlinc)
xlinc(other._annotinc[1]);
if (other._have_zstart)
zstart(other._zstart);
if (other._have_zinc)
zinc(other._zinc);
if (other._have_corners)
corners(other._corners);
return *this;
}
ZgyWriterArgs&
ZgyWriterArgs::compressor(const std::string& name, const std::vector<std::string>& args)
{
......
......@@ -439,6 +439,23 @@ private:
float _zstart, _zinc;
std::array<float,2> _annotstart, _annotinc;
corners_t _corners;
// Keeps track of what information has been changed from the default.
// Currently metafrom() will set all to true. That might change.
// The information is only used by merge(). Transient information
// such as iocontext is ignored.
bool _have_size;
bool _have_bricksize;
bool _have_datatype;
bool _have_datarange;
bool _have_zunit;
bool _have_hunit;
bool _have_ilstart;
bool _have_ilinc;
bool _have_xlstart;
bool _have_xlinc;
bool _have_zstart;
bool _have_zinc;
bool _have_corners;
public:
ZgyWriterArgs()
......@@ -461,6 +478,19 @@ public:
, _annotstart{0,0}
, _annotinc{0,0}
, _corners{0,0,0,0,0,0,0,0}
, _have_size(false)
, _have_bricksize(false)
, _have_datatype(false)
, _have_datarange(false)
, _have_zunit(false)
, _have_hunit(false)
, _have_ilstart(false)
, _have_ilinc(false)
, _have_xlstart(false)
, _have_xlinc(false)
, _have_zstart(false)
, _have_zinc(false)
, _have_corners(false)
{
}
......@@ -538,16 +568,16 @@ public:
* \param nj number of crosslines.
* \param nk number of samples per trace (fastest).
*/
ZgyWriterArgs& size(std::int64_t ni, std::int64_t nj, std::int64_t nk) { _size[0]=ni; _size[1]=nj; _size[2]=nk; return *this; }
ZgyWriterArgs& size(std::int64_t ni, std::int64_t nj, std::int64_t nk) { _size[0]=ni; _size[1]=nj; _size[2]=nk; _have_size = true; return *this; }
/**
* \brief Set size of one brick.
* \details Almost always (64,64,64). Change at your own peril.
*/
ZgyWriterArgs& bricksize(std::int64_t ni, std::int64_t nj, std::int64_t nk) { _bricksize[0]=ni; _bricksize[1]=nj; _bricksize[2]=nk; return *this; }
ZgyWriterArgs& bricksize(std::int64_t ni, std::int64_t nj, std::int64_t nk) { _bricksize[0]=ni; _bricksize[1]=nj; _bricksize[2]=nk; _have_bricksize = true; return *this; }
/**
* \brief Set type of samples in each brick.
*/
ZgyWriterArgs& datatype(SampleDataType value) { _datatype = value; return *this; }
ZgyWriterArgs& datatype(SampleDataType value) { _datatype = value; _have_datatype = true; return *this; }
/**
* \brief Set scaling factors.
* \details For integral storage this specifies the two floating
......@@ -558,7 +588,7 @@ public:
* ZGY files require that min<max. This is not enforced here,
* but is checked when the file is actually created.
*/
ZgyWriterArgs& datarange(float lo, float hi) { _datarange[0] = lo; _datarange[1] = hi; return *this; }
ZgyWriterArgs& datarange(float lo, float hi) { _datarange[0] = lo; _datarange[1] = hi; _have_datarange = true; return *this; }
/**
* \brief Set vertical unit.
* \param dimension time or depth (a.k.a. length).
......@@ -569,6 +599,7 @@ ZgyWriterArgs& datarange(float lo, float hi) { _datarange[0] = lo; _datarange[1]
_zunitdim = dimension;
_zunitname = name;
_zunitfactor = factor;
_have_zunit = true;
return *this;
}
/**
......@@ -581,32 +612,33 @@ ZgyWriterArgs& datarange(float lo, float hi) { _datarange[0] = lo; _datarange[1]
_hunitdim = dimension;
_hunitname = name;
_hunitfactor = factor;
_have_hunit = true;
return *this;
}
/// \brief Set first (ordinal 0) inline number.
/// \details For maximum portability the inline and crossline start
/// and increment should be integral numbers. Some applications
/// might choose to convert them to int.
ZgyWriterArgs& ilstart(float value) { _annotstart[0] = value; return *this; }
ZgyWriterArgs& ilstart(float value) { _annotstart[0] = value; _have_ilstart = true; return *this; }
/// \brief Set inline number increment between two adjacent ordinal values.
/// \copydetails ilstart
ZgyWriterArgs& ilinc(float value) { _annotinc[0] = value; return *this; }
ZgyWriterArgs& ilinc(float value) { _annotinc[0] = value; _have_ilinc = true; return *this; }
/// \brief Set first (ordinal 0) crossline number.
/// \copydetails ilstart
ZgyWriterArgs& xlstart(float value) { _annotstart[1] = value; return *this; }
ZgyWriterArgs& xlstart(float value) { _annotstart[1] = value; _have_xlstart = true; return *this; }
/// \brief Set crossline number increment between two adjacent ordinal values.
/// \copydetails ilstart
ZgyWriterArgs& xlinc(float value) { _annotinc[1] = value; return *this; }
ZgyWriterArgs& xlinc(float value) { _annotinc[1] = value; _have_xlinc = true; return *this; }
/// \brief Set first time/depth.
/// \details Vertical annotation is generally safe to have non-integral.
ZgyWriterArgs& zstart(float value) { _zstart = value; return *this; }
ZgyWriterArgs& zstart(float value) { _zstart = value; _have_zstart = true; return *this; }
/// \brief Set increment (distance between samples) in vertical direction.
/// \copydetails zstart
ZgyWriterArgs& zinc(float value) { _zinc = value; return *this; }
ZgyWriterArgs& zinc(float value) { _zinc = value; _have_zinc = true; return *this; }
/// \brief Set survey corner points in world coordinates.
/// \details The corners are ordered origin, last inline (i.e. i=last, j=0),
/// last crossline, diagonal.
ZgyWriterArgs& corners(const corners_t& value) { _corners = value; return *this; }
ZgyWriterArgs& corners(const corners_t& value) { _corners = value; _have_corners = true; return *this; }
/**
* \brief Copy metadata from existing file.
*
......@@ -617,6 +649,15 @@ ZgyWriterArgs& datarange(float lo, float hi) { _datarange[0] = lo; _datarange[1]
*/
ZgyWriterArgs& metafrom(const std::shared_ptr<OpenZGY::IZgyReader>&);
/**
* \brief Copy metadata from another ZgyWriterArgs.
*
* Copy only those settings that have been explicitly changed in the
* supplied "other" ZgyWriterArgs into *this. If other.metafrom()
* has been called it is unspecified what gets copied.
*/
ZgyWriterArgs& merge(const ZgyWriterArgs&);
// TODO-Low: Add accessors as well. But these are only for internal
// use so the ugliness of accessing data members isn't that bad.
};
......
......@@ -718,6 +718,12 @@ static void do_write_twice(const std::string& filename, const IOContext* context
// Try to re-open it. Should work since there are no data blocks.
writer = IZgyWriter::reopen(secondargs);
// Re-open again, re-specifying the basic info (no error unless it changes)
// and not re-specifying the mutable part (should then be retained).
writer->close();
writer.reset();
writer = IZgyWriter::reopen(firstargs);
// Continue as in test_write(). Probably should have refactored to share code.
std::vector<float> data(2*3*4, -1000);
const OpenZGY::IZgyWriter::size3i_t origin{0,0,0};
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment