OpenZGY/C++ Public API (ALPHA)
Access seismic data stored in ZGY format.
api.h
Go to the documentation of this file.
1 // Copyright 2017-2020, Schlumberger
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #pragma once
16 
17 #include <cstdint>
18 #include <vector>
19 #include <array>
20 #include <ostream>
21 #include <iostream>
22 #include <functional>
23 #include <memory>
24 #include <ostream>
25 #include <iostream>
26 #include <string>
27 
28 #include "declspec.h"
29 
30 #ifdef _MSC_VER
31 #pragma warning(push)
32 // The warning is due to me using pure virtual classes as "real" interfaces,
33 // having a similar inheritance scheme for interfaces and implementation.
34 // I believe this is safe as long as the interfaces are truly pure.
35 #pragma warning(disable:4250) // inherits via dominance
36 #endif
37 
38 namespace OpenZGY {
117 }
118 
119 namespace Test {
120  class ZgyWriterMock;
121 }
122 
123 namespace OpenZGY {
124 #if 0
125 }
126 #endif
127 
128 class IOContext;
129 class IZgyReader;
130 
131 namespace Impl {
132  class ZgyWriter;
133  class EnumMapper;
134 }
135 
208 enum class OPENZGY_API SampleDataType
209 {
210  unknown = 1000,
211  int8 = 1001,
212  int16 = 1002,
213  float32 = 1003, // Note, cannot call it just "float".
214 };
215 
216 namespace Formatters {
217  extern OPENZGY_API std::ostream& operator<<(std::ostream& os, SampleDataType value);
218 }
219 
229 enum class OPENZGY_API UnitDimension
230 {
231  unknown = 2000,
232  time = 2001,
233  length = 2002,
234  arcangle = 2003,
235 };
236 
237 namespace Formatters {
238  extern OPENZGY_API std::ostream& operator<<(std::ostream& os, UnitDimension value);
239 }
240 
249 enum class OPENZGY_API DecimationType
250 {
251  LowPass = 100,
266 };
267 
268 namespace Formatters {
269  extern OPENZGY_API std::ostream& operator<<(std::ostream& os, DecimationType value);
270 }
271 
275 class OPENZGY_API SampleStatistics
276 {
277 public:
278  std::int64_t cnt;
279  double sum;
280  double ssq;
281  double min;
282  double max;
284  : cnt(0), sum(0), ssq(0), min(0), max(0)
285  {
286  }
287 
289  SampleStatistics(std::int64_t cnt_in,
290  double sum_in, double ssq_in,
291  double min_in, double max_in)
292  : cnt(cnt_in), sum(sum_in), ssq(ssq_in), min(min_in), max(max_in)
293  {
294  }
295 };
296 
331 class OPENZGY_API SampleHistogram
332 {
333 public:
334  std::int64_t samplecount;
335  double minvalue;
336  double maxvalue;
337  std::vector<std::int64_t> bins;
339  : samplecount(0), minvalue(0), maxvalue(0), bins()
340  {
341  }
342 
344  SampleHistogram(std::int64_t samplecount_in,
345  double minvalue_in, double maxvalue_in,
346  const std::vector<std::int64_t>& bins_in)
347  : samplecount(samplecount_in)
348  , minvalue(minvalue_in)
349  , maxvalue(maxvalue_in)
350  , bins(bins_in)
351  {
352  }
353 };
354 
388 class OPENZGY_API ZgyWriterArgs
389 {
390 public:
391  typedef double float64_t;
392  typedef std::array<std::array<float64_t,2>,4> corners_t;
393  // Type aliases duplicated from the InternalZGY layer.
394  typedef std::pair<std::shared_ptr<const void>, std::int64_t> rawdata_t;
395  typedef std::function<rawdata_t(const rawdata_t&,const std::array<int64_t,3>&)> compressor_t;
396 
397 private:
398  friend class Impl::ZgyWriter; // Processing the high level parts.
399  friend class ::Test::ZgyWriterMock;
400  friend class Impl::EnumMapper; // Mapping the rest to the internal struct.
401  std::string _filename;
402  const IOContext *_iocontext; // TODO-Worry: Sure instance is short lived?
403  compressor_t _compressor;
404  compressor_t _lodcompressor;
405  std::array<std::int64_t,3> _size;
406  std::array<std::int64_t,3> _bricksize;
407  SampleDataType _datatype;
408  std::array<float,2> _datarange;
409  UnitDimension _zunitdim, _hunitdim;
410  std::string _zunitname, _hunitname;
411  double _zunitfactor, _hunitfactor;
412  float _zstart, _zinc;
413  std::array<float,2> _annotstart, _annotinc;
414  corners_t _corners;
415 
416 public:
417  ZgyWriterArgs()
418  : _filename("")
419  , _iocontext(nullptr)
420  , _compressor()
421  , _lodcompressor()
422  , _size{0,0,0}
423  , _bricksize{64,64,64}
424  , _datatype(SampleDataType::float32)
425  , _datarange{0, -1}
426  , _zunitdim(UnitDimension::unknown)
427  , _hunitdim(UnitDimension::unknown)
428  , _zunitname("")
429  , _hunitname("")
430  , _zunitfactor(1.0)
431  , _hunitfactor(1.0)
432  , _zstart(0)
433  , _zinc(0)
434  , _annotstart{0,0}
435  , _annotinc{0,0}
436  , _corners{0,0,0,0,0,0,0,0}
437  {
438  }
439 
443  void dump(std::ostream& out)
444  {
445  out << "ZgyWriterArgs\n"
446  << " filename: \"" << _filename << "\"\n"
447  << " iocontext: " << (_iocontext ? "*" : "(null)") << "\n"
448  << " compressor: " << (_compressor ? "*" : "(null)") << "\n"
449  << " lodcompress: " << (_lodcompressor ? "*" : "(null)") << "\n"
450  << " size: (" << _size[0] << "," << _size[1] << "," << _size[2] << ")\n"
451  << " bricksize: (" << _bricksize[0] << "," << _bricksize[1] << "," << _bricksize[2] << ")\n"
452  << " datatype: " << int(_datatype) << "\n"
453  << " datarange: " << _datarange[0] << " to " << _datarange[1] << "\n"
454  << " zunit: " << int(_zunitdim) << " \"" << _zunitname << "\" " << _zunitfactor << "\n"
455  << " hunit: " << int(_hunitdim) << " \"" << _hunitname << "\" " << _hunitfactor << "\n"
456  << " ilstart/inc: " << _annotstart[0] << " / " << _annotinc[0] << "\n"
457  << " xlstart/inc: " << _annotstart[1] << " / " << _annotinc[1] << "\n"
458  << " zstart/inc: " << _zstart << " / " << _zinc << "\n"
459  << " corner0: " << _corners[0][0] << ", " << _corners[0][1] << "\n"
460  << " corner1: " << _corners[1][0] << ", " << _corners[1][1] << "\n"
461  << " corner2: " << _corners[2][0] << ", " << _corners[2][1] << "\n"
462  << " corner3: " << _corners[3][0] << ", " << _corners[3][1] << "\n";
463  }
464 
471  ZgyWriterArgs& filename(const std::string& value) { _filename = value; return *this; }
477  ZgyWriterArgs& iocontext(const IOContext *value) { _iocontext = value; return *this; }
481  ZgyWriterArgs& compressor(const compressor_t& value) { _compressor = value; return *this; }
486  ZgyWriterArgs& compressor(const std::string& name, const std::vector<std::string>& args);
492  ZgyWriterArgs& zfp_compressor(float snr);
496  ZgyWriterArgs& lodcompressor(const compressor_t& value) { _lodcompressor = value; return *this; }
501  ZgyWriterArgs& lodcompressor(const std::string& name, const std::vector<std::string>& args);
507  ZgyWriterArgs& zfp_lodcompressor(float snr);
514  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; }
519  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; }
523  ZgyWriterArgs& datatype(SampleDataType value) { _datatype = value; return *this; }
531 ZgyWriterArgs& datarange(float lo, float hi) { _datarange[0] = lo; _datarange[1] = hi; return *this; }
538  ZgyWriterArgs& zunit(UnitDimension dimension, const std::string& name, double factor) {
539  _zunitdim = dimension;
540  _zunitname = name;
541  _zunitfactor = factor;
542  return *this;
543  }
550  ZgyWriterArgs& hunit(UnitDimension dimension, const std::string& name, double factor) {
551  _hunitdim = dimension;
552  _hunitname = name;
553  _hunitfactor = factor;
554  return *this;
555  }
560  ZgyWriterArgs& ilstart(float value) { _annotstart[0] = value; return *this; }
563  ZgyWriterArgs& ilinc(float value) { _annotinc[0] = value; return *this; }
566  ZgyWriterArgs& xlstart(float value) { _annotstart[1] = value; return *this; }
569  ZgyWriterArgs& xlinc(float value) { _annotinc[1] = value; return *this; }
572  ZgyWriterArgs& zstart(float value) { _zstart = value; return *this; }
575  ZgyWriterArgs& zinc(float value) { _zinc = value; return *this; }
579  ZgyWriterArgs& corners(const corners_t& value) { _corners = value; return *this; }
588  ZgyWriterArgs& metafrom(const std::shared_ptr<OpenZGY::IZgyReader>&);
589 
590  // TODO-Low: Add accessors as well. But these are only for internal
591  // use so the ugliness of accessing data members isn't that bad.
592 };
593 
597 class OPENZGY_API IZgyMeta
598 {
599 public:
600  typedef std::int8_t int8_t;
601  typedef std::int16_t int16_t;
602  typedef std::int32_t int32_t;
603  typedef std::int64_t int64_t;
604  typedef float float32_t;
605  typedef double float64_t;
606  typedef std::array<int64_t,3> size3i_t;
607  typedef std::array<std::array<float64_t,2>,4> corners_t;
608  // Type aliases duplicated from the InternalZGY layer.
609  typedef std::pair<std::shared_ptr<const void>, std::int64_t> rawdata_t;
610  typedef std::function<rawdata_t(const rawdata_t&,const std::array<int64_t,3>&)> compressor_t;
611 
612 public:
613  virtual ~IZgyMeta();
614  virtual size3i_t size() const = 0;
615  virtual SampleDataType datatype() const = 0;
616  virtual std::array<float32_t,2> datarange() const = 0;
617  virtual UnitDimension zunitdim() const = 0;
618  virtual UnitDimension hunitdim() const = 0;
619  virtual std::string zunitname() const = 0;
620  virtual std::string hunitname() const = 0;
621  virtual float64_t zunitfactor() const = 0;
622  virtual float64_t hunitfactor() const = 0;
623  virtual float32_t zstart() const = 0;
624  virtual float32_t zinc() const = 0;
625  virtual std::array<float32_t,2> annotstart() const = 0;
626  virtual std::array<float32_t,2> annotinc() const = 0;
627  virtual const corners_t& corners() const = 0;
628  virtual const corners_t& indexcorners() const = 0;
629  virtual const corners_t& annotcorners() const = 0;
630  virtual size3i_t bricksize() const = 0;
631  virtual std::vector<size3i_t> brickcount() const = 0;
632  virtual int32_t nlods() const = 0;
633  virtual void meta() const = 0;
634  virtual int32_t numthreads() const = 0;
635  virtual void set_numthreads(int32_t) = 0;
636  virtual void dump(std::ostream&) const = 0;
637  virtual SampleStatistics statistics() const = 0;
638  virtual SampleHistogram histogram() const = 0;
639 };
640 
644 class OPENZGY_API IZgyTools : virtual public IZgyMeta
645 {
646 public:
647  virtual ~IZgyTools();
666  virtual void transform(const corners_t& from, const corners_t& to, std::vector<std::array<float64_t,2>>&) const = 0;
671  virtual std::array<float64_t,2> transform1(const corners_t& from, const corners_t& to, const std::array<float64_t,2>&) const = 0;
672  virtual std::array<float64_t,2> annotToIndex(const std::array<float64_t,2>&) const = 0;
673  virtual std::array<float64_t,2> annotToWorld(const std::array<float64_t,2>&) const = 0;
674  virtual std::array<float64_t,2> indexToAnnot(const std::array<float64_t,2>&) const = 0;
675  virtual std::array<float64_t,2> indexToWorld(const std::array<float64_t,2>&) const = 0;
676  virtual std::array<float64_t,2> worldToAnnot(const std::array<float64_t,2>&) const = 0;
677  virtual std::array<float64_t,2> worldToIndex(const std::array<float64_t,2>&) const = 0;
678 };
679 
691 class OPENZGY_API IZgyReader : virtual public IZgyTools
692 {
693 public:
694  virtual ~IZgyReader();
696  virtual void read(const size3i_t& start, const size3i_t& size, float* data, int lod = 0) const = 0;
698  virtual void read(const size3i_t& start, const size3i_t& size, std::int16_t* data, int lod = 0) const = 0;
700  virtual void read(const size3i_t& start, const size3i_t& size, std::int8_t* data, int lod = 0) const = 0;
702  virtual std::pair<bool,double> readconst(const size3i_t& start, const size3i_t& size, int lod = 0, bool as_float = true) const = 0;
704  virtual void close() = 0;
706  static std::shared_ptr<IZgyReader> open(const std::string& filename, const IOContext* iocontext = nullptr);
707 };
708 
727 class OPENZGY_API IZgyWriter : virtual public IZgyTools
728 {
729 public:
730  virtual ~IZgyWriter();
731  virtual void write(const size3i_t& start, const size3i_t& size, const float* data) const = 0;
732  virtual void write(const size3i_t& start, const size3i_t& size, const std::int16_t *data) const = 0;
733  virtual void write(const size3i_t& start, const size3i_t& size, const std::int8_t* data) const = 0;
734  virtual void writeconst(const size3i_t& start, const size3i_t& size, const float* data) const = 0;
736  virtual void writeconst(const size3i_t& start, const size3i_t& size, const std::int16_t * data) const = 0;
737  virtual void writeconst(const size3i_t& start, const size3i_t& size, const std::int8_t* data) const = 0;
738  virtual void finalize(
740  const std::vector<DecimationType>& decimation = std::vector<DecimationType>(),
741  const std::function<bool(std::int64_t,std::int64_t)>& progress = nullptr,
742  bool force = false) = 0;
744  virtual void close_incomplete() = 0;
746  virtual void close() = 0;
748  virtual bool errorflag() const = 0;
749  virtual void set_errorflag(bool) = 0;
752  static std::shared_ptr<IZgyWriter> open(const ZgyWriterArgs& args);
753 };
754 
762 class OPENZGY_API IZgyUtils
763 {
764 public:
765  virtual ~IZgyUtils();
771  virtual void deletefile(const std::string& filename, bool missing_ok=true) = 0;
793  static std::shared_ptr<IZgyUtils> utils(const std::string& prefix, const IOContext* iocontext);
794 };
795 
814 class OPENZGY_API ProgressWithDots
815 {
816 private:
817  int _dots_printed;
818  int _length;
819  std::ostream& _outfile;
820 
821 public:
828  ProgressWithDots(int length=51, std::ostream& outfile = std::cerr);
843  bool operator()(std::int64_t done, std::int64_t total);
844 };
845 
846 } // namespace
847 
848 #ifdef _MSC_VER
849 #pragma warning(pop)
850 #endif
AverageNon0
AverageNon0
Average value, but treat 0 as NaN.
Definition: api.h:265
OpenZGY::ZgyWriterArgs::zunit
ZgyWriterArgs & zunit(UnitDimension dimension, const std::string &name, double factor)
Set vertical unit.
Definition: api.h:538
OpenZGY::SampleStatistics::cnt
std::int64_t cnt
Number of added samples.
Definition: api.h:278
MostFrequentNon0
MostFrequentNon0
The non-zero value that occurs most frequently.
Definition: api.h:264
AllZero
AllZero
Just fill the LOD brick with zeroes.
Definition: api.h:261
Decimate
Decimate
Simple decimation, use first sample.
Definition: api.h:258
OpenZGY::ZgyWriterArgs::ilinc
ZgyWriterArgs & ilinc(float value)
Set inline number increment between two adjacent ordinal values.
Definition: api.h:563
OpenZGY::IZgyTools
Base class of IZgyReader and IZgyWriter.
Definition: api.h:644
OpenZGY::ZgyWriterArgs::compressor
ZgyWriterArgs & compressor(const compressor_t &value)
Set functor for compressing full resolution data.
Definition: api.h:481
OpenZGY::SampleHistogram::minvalue
double minvalue
Center value of data in first bin.
Definition: api.h:335
OpenZGY::ZgyWriterArgs::iocontext
ZgyWriterArgs & iocontext(const IOContext *value)
Set credentials and other configuration.
Definition: api.h:477
OpenZGY::ProgressWithDots
Simple progress bar.
Definition: api.h:814
OpenZGY::Formatters::operator<<
OPENZGY_API std::ostream & operator<<(std::ostream &os, DecimationType value)
Output the string representation of the input enum type.
Definition: api.cpp:1308
OpenZGY::ZgyWriterArgs::hunit
ZgyWriterArgs & hunit(UnitDimension dimension, const std::string &name, double factor)
Set horizontal unit.
Definition: api.h:550
OpenZGY::IZgyWriter
Main API for creating ZGY files.
Definition: api.h:727
OpenZGY::IZgyMeta
Base class of IZgyReader and IZgyWriter.
Definition: api.h:597
OpenZGY::SampleHistogram::SampleHistogram
SampleHistogram(std::int64_t samplecount_in, double minvalue_in, double maxvalue_in, const std::vector< std::int64_t > &bins_in)
Create a new instance with all contents filled in.
Definition: api.h:344
OpenZGY::ZgyWriterArgs::datatype
ZgyWriterArgs & datatype(SampleDataType value)
Set type of samples in each brick.
Definition: api.h:523
OpenZGY::ZgyWriterArgs::zinc
ZgyWriterArgs & zinc(float value)
Set increment (distance between samples) in vertical direction.
Definition: api.h:575
OpenZGY::ZgyWriterArgs::size
ZgyWriterArgs & size(std::int64_t ni, std::int64_t nj, std::int64_t nk)
Set size of the survey.
Definition: api.h:514
Median
Median
Somewhat more expensive averaging.
Definition: api.h:254
OpenZGY::ZgyWriterArgs::datarange
ZgyWriterArgs & datarange(float lo, float hi)
Set scaling factors.
Definition: api.h:531
OpenZGY::SampleStatistics::SampleStatistics
SampleStatistics(std::int64_t cnt_in, double sum_in, double ssq_in, double min_in, double max_in)
Create a new instance with all contents filled in.
Definition: api.h:289
OpenZGY::SampleStatistics::max
double max
Maximum added sample value.
Definition: api.h:282
OpenZGY::ZgyWriterArgs::zstart
ZgyWriterArgs & zstart(float value)
Set first time/depth.
Definition: api.h:572
Average
Average
Simple averaging.
Definition: api.h:253
MinMax
MinMax
Checkerboard of minimum and maximum values.
Definition: api.h:257
Maximum
Maximum
Maximum value.
Definition: api.h:256
OpenZGY::ZgyWriterArgs::bricksize
ZgyWriterArgs & bricksize(std::int64_t ni, std::int64_t nj, std::int64_t nk)
Set size of one brick.
Definition: api.h:519
DecimateSkipNaN
DecimateSkipNaN
Use first sample that is not NaN.
Definition: api.h:259
OpenZGY::SampleHistogram::maxvalue
double maxvalue
Center value of data in last bin.
Definition: api.h:336
OpenZGY::ZgyWriterArgs::ilstart
ZgyWriterArgs & ilstart(float value)
Set first (ordinal 0) inline number.
Definition: api.h:560
OpenZGY::ZgyWriterArgs::corners
ZgyWriterArgs & corners(const corners_t &value)
Set survey corner points in world coordinates.
Definition: api.h:579
OpenZGY::SampleHistogram::bins
std::vector< std::int64_t > bins
array of counts by bin
Definition: api.h:337
LowPass
LowPass
Lowpass Z / decimate XY.
Definition: api.h:251
OpenZGY::IOContext
Base class for backend specific context.
Definition: iocontext.h:49
OpenZGY::SampleHistogram
Histogram of all sample values on the file.
Definition: api.h:331
DecimateRandom
DecimateRandom
Random decimation using a fixed seed.
Definition: api.h:260
WhiteNoise
WhiteNoise
Fill with white noise, hope nobody notices.
Definition: api.h:262
OpenZGY::IZgyReader
Main API for reading ZGY files.
Definition: api.h:691
OpenZGY::ZgyWriterArgs::lodcompressor
ZgyWriterArgs & lodcompressor(const compressor_t &value)
Set functor for compressing low resolution data.
Definition: api.h:496
OpenZGY::SampleHistogram::samplecount
std::int64_t samplecount
Sum of counts of all bins.
Definition: api.h:334
OpenZGY::ZgyWriterArgs::dump
void dump(std::ostream &out)
Output in human readable form for debugging.
Definition: api.h:443
OpenZGY::Impl::ZgyWriter
Concrete implementation of IZgyWriter.
Definition: api.cpp:508
WeightedAverage
WeightedAverage
Weighted averaging (depends on global stats).
Definition: api.h:252
OpenZGY::SampleStatistics::min
double min
Minimum added sample value.
Definition: api.h:281
OpenZGY::SampleStatistics
Statistics of all sample values on the file.
Definition: api.h:275
OpenZGY::SampleStatistics::ssq
double ssq
Sum-of-squares of added samples.
Definition: api.h:280
OpenZGY::IZgyUtils
Operations other than read and write.
Definition: api.h:762
OpenZGY::ZgyWriterArgs::xlstart
ZgyWriterArgs & xlstart(float value)
Set first (ordinal 0) crossline number.
Definition: api.h:566
OpenZGY::SampleStatistics::sum
double sum
Sum of added samples.
Definition: api.h:279
OpenZGY::ZgyWriterArgs::xlinc
ZgyWriterArgs & xlinc(float value)
Set crossline number increment between two adjacent ordinal values.
Definition: api.h:569
OpenZGY
The entire public API is in this namespace.
Definition: api.h:38
Minimum
Minimum
Minimum value.
Definition: api.h:255
MostFrequent
MostFrequent
The value that occurs most frequently.
Definition: api.h:263
OpenZGY::ZgyWriterArgs
Argument package for creating a ZGY file.
Definition: api.h:388
OpenZGY::ZgyWriterArgs::filename
ZgyWriterArgs & filename(const std::string &value)
Set file to open.
Definition: api.h:471