OpenZGY/C++ API and Internals (ALPHA)
Access seismic data stored in ZGY format.
databuffer.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 "../declspec.h"
18 #include "enum.h"
19 #include "types.h"
20 
21 #include <cstdint>
22 #include <array>
23 #include <memory>
24 #include <string>
25 
26 namespace InternalZGY {
27 #if 0
28 }
29 #endif
30 
185 class OPENZGY_TEST_API DataBuffer
186 {
187 public:
188  enum flags_t {C_ORDERING=1, CONTIGUOUS=2, POSITIVE_STRIDE=4, DEGENERATE=8};
189 public:
190  //** No copy or assign in the abstract base class.
191  DataBuffer(const DataBuffer&) = delete;
192  //** No copy or assign in the abstract base class.
193  DataBuffer& operator=(const DataBuffer&) = delete;
194  DataBuffer() = default;
195  virtual ~DataBuffer();
196  virtual std::string toString() const = 0;
197  virtual std::shared_ptr<void> voidData() = 0;
198  virtual std::shared_ptr<const void> voidData() const = 0;
199  //** True if there are no holes and the internal buffer can be treated as 1d.
200  virtual bool contiguous() const = 0;
201  //** Number of elements including holes. Computed from size() and stride().
202  virtual std::int64_t allocsize() const = 0;
203  //** Number of elements. Computed as the product of size() in each dimension.
204  virtual std::int64_t totalsize() const = 0;
205  //** Size in bytes of one element.
206  virtual std::int64_t itemsize() const = 0;
207  //** Number of elements as an unsafe (unchecked length) pointer.
208  virtual const std::int64_t* sizeptr() const = 0;
209  //** Buffer layout as an unsafe (unchecked length) pointer.
210  virtual const std::int64_t* strideptr() const = 0;
211  //** Number of elements in each of the (assumed) 3 dimensions
212  virtual std::array<std::int64_t,3> size3d() const = 0;
213  //** Buffer layout in each of the (assumed) 3 dimensions
214  virtual std::array<std::int64_t,3> stride3d() const = 0;
215  //** True if data() has proper reference counting. TODO-Medium: Rename, or yagni.
216  virtual bool ownsdata() const = 0;
217  //** True if buffer represents a constant value. data() will be length 1.
218  virtual bool isScalar() const = 0;
219  //** True if buffer is not scalar but samples are all the same.
220  virtual bool isAllSame(const std::int64_t *used_in) const = 0;
221  //** The constant value, if any, as a double. Unspecified if !isScalar().
222  virtual double scalarAsDouble() const = 0;
223  //** Convert the templated Type argument of the leaf class to an enum.
224  virtual RawDataType datatype() const = 0;
225  //** Set all samples to the same value.
226  virtual void fill(double value) = 0;
227  //** Make the instance unusable. May be needed if data is not ref counted.
228  virtual void clear() = 0;
229  //** Value range excluding infinites and nan.
230  virtual std::pair<double, double> range() const = 0;
234  virtual void copyFrom(
235  const DataBuffer* src,
236  const std::int64_t *srcorig,const std::int64_t *dstorig,
237  const std::int64_t *cpyorig,const std::int64_t *cpysize) = 0;
238  //std::int64_t ni() const { return size()[0]; }
239  //std::int64_t nj() const { return size()[1]; }
240  //std::int64_t nk() const { return size()[2]; }
242  virtual std::shared_ptr<DataBuffer> clone() const = 0;
244  virtual std::shared_ptr<DataBuffer> scaleToFloat(const std::array<double,2>&) = 0;
246  virtual std::shared_ptr<DataBuffer> scaleToStorage(const std::array<double,2>&, RawDataType) = 0;
247  virtual std::uint32_t layout() const = 0;
248  virtual bool is_cstride() const = 0;
249  virtual void check_cstride() const = 0;
250  virtual std::shared_ptr<DataBuffer> slice1(int dim, std::int64_t start, std::int64_t size) const = 0;
251  static std::shared_ptr<DataBuffer> makeDataBuffer3d(void *raw, std::int64_t nbytes, const std::array<std::int64_t,3>& size, RawDataType dtype);
252 };
253 
254 template <typename T, int NDim>
255 class DataBufferNd : public DataBuffer
256 {
257 public:
258  typedef T value_type;
260  typedef std::array<std::int64_t,NDim> ndsize_t;
261  enum { ndim = NDim };
262 
263  // TODO-Low: Group functions better.
264 public: // These are only available in the templated class.
265  //** Default copy/assign would work, but don't offer it if I don't need it.
266  DataBufferNd(const self_type&) = delete;
267  //** Default copy/assign would work, but don't offer it if I don't need it.
268  self_type& operator=(const self_type&) = delete;
269  //** Buffer represents a constant value. No allocated data.
270  DataBufferNd(T scalar, const std::array<std::int64_t,NDim>& size);
271  //** Allocate a new buffer and take ownership of it.
272  DataBufferNd(const std::array<std::int64_t,NDim>& size);
273  //** Allocate a new buffer and take ownership of it, with non-standard stride.
274  DataBufferNd(const std::array<std::int64_t,NDim>& size, const std::array<std::int64_t,NDim>& stride);
275  //** External buffer, shared ownership. Beware we might get a "fake" smartptr.
276  DataBufferNd(const std::shared_ptr<T>& data, const std::array<std::int64_t,NDim>& size);
277  //** External buffer, shared ownership. Beware we might get a "fake" smartptr.
278  DataBufferNd(const std::shared_ptr<T>& data, const std::array<std::int64_t,NDim>& size, const std::array<std::int64_t,NDim>& stride);
279  //** Plain, strongly typed pointer to data.
280  T* data() { return _data.get(); }
281  //** Plain, strongly typed pointer to data.
282  const T* data() const { return _data.get(); }
283  //** The constant value, if any. Return first value if !isScalar().
284  T scalarValue() const { return data()[0]; }
285  //** True if we know data() has proper reference counting because we allocated it.
286  virtual bool ownsdata() const {return _ownsdata; }
287  //** True if buffer represents a constant value.
288  bool isScalar() const override { return _is_scalar; }
289  //** True if buffer is not scalar but samples are all the same.
290  bool isAllSame(const std::int64_t *used_in) const override;
291  //** The constant value, if any, as a double.
292  double scalarAsDouble() const override { return (double)scalarValue(); }
293  RawDataType datatype() const override { return RawDataTypeTraits<T>::datatype; }
294  void fill(double value) override;
295  void clear() override;
296  std::pair<double, double> range() const override;
297  std::uint32_t layout() const override;
298  bool is_cstride() const override;
299  void check_cstride() const override;
300 
301 private:
302  ndsize_t _size;
303  ndsize_t _stride;
304  bool _is_scalar;
305  std::shared_ptr<T> _data;
306  bool _ownsdata;
307 
308  static std::uint32_t check_stride(const ndsize_t& size, const ndsize_t& stride);
309  static ndsize_t cstride(const ndsize_t& size);
310  static ndsize_t make_array(const std::int64_t *in);
311  static std::int64_t make_product(const ndsize_t& size);
312  static std::int64_t make_allocsize(const ndsize_t& size, const ndsize_t& stride);
313 
314 public:
315  std::string toString() const override;
316  std::shared_ptr<void> voidData() override { return _data; }
317  std::shared_ptr<const void> voidData() const override { return _data; }
318  bool contiguous() const override;
319  std::int64_t allocsize() const override;
320  std::int64_t totalsize() const override;
321  std::int64_t itemsize() const override;
322  const std::int64_t* sizeptr() const override;
323  const std::int64_t* strideptr() const override;
324  std::array<std::int64_t,3> size3d() const override;
325  std::array<std::int64_t,3> stride3d() const override;
326  const ndsize_t& safesize() const {return _size;}
327  const ndsize_t& safestride() const {return _stride;}
328  std::shared_ptr<DataBuffer> clone() const;
329  std::shared_ptr<DataBuffer> scaleToFloat(const std::array<double,2>&) override;
330  std::shared_ptr<DataBuffer> scaleToStorage(const std::array<double,2>&, RawDataType) override;
331  std::shared_ptr<DataBuffer> slice1(int dim, std::int64_t start, std::int64_t size) const override;
332 
333  std::shared_ptr<self_type> slice(const ndsize_t& neworig,
334  const ndsize_t& newsize) const;
335 
336  void copyFrom(const DataBuffer* src,
337  const std::int64_t *srcorig,const std::int64_t *dstorig,
338  const std::int64_t *cpyorig,const std::int64_t *cpysize);
339 
340  static void copySubset(const ndsize_t& srcorig, const self_type& src,
341  const ndsize_t& dstorig, self_type& dst,
342  const ndsize_t& cpyorig, const ndsize_t& cpysize);
343 
344  static void copySubset(const ndsize_t& srcorig, const self_type& src,
345  const ndsize_t& dstorig, self_type& dst);
346 
347 public:
348  // Logically private, but needs to be available from a DteBufferNd with different template arguments. Easier to make them public.
349  static std::shared_ptr<DataBuffer> s_scaleToFloat(const DataBuffer*, const std::array<double,2>&);
350  static std::shared_ptr<DataBuffer> s_scaleFromFloat(const DataBuffer*, const std::array<double,2>&);
351 };
352 
353 // Explicit template instanciation.
354 OPENZGY_DECLARE_EXPLICIT_TEMPLATE(DataBufferNd<std::int8_t, 3>)
355 OPENZGY_DECLARE_EXPLICIT_TEMPLATE(DataBufferNd<std::uint8_t, 3>)
356 OPENZGY_DECLARE_EXPLICIT_TEMPLATE(DataBufferNd<std::int16_t, 3>)
357 OPENZGY_DECLARE_EXPLICIT_TEMPLATE(DataBufferNd<std::uint16_t, 3>)
358 OPENZGY_DECLARE_EXPLICIT_TEMPLATE(DataBufferNd<std::int32_t, 3>)
359 OPENZGY_DECLARE_EXPLICIT_TEMPLATE(DataBufferNd<std::uint32_t, 3>)
360 OPENZGY_DECLARE_EXPLICIT_TEMPLATE(DataBufferNd<float, 3>)
361 
362 } // namespace
enum.h
enums and type aliases not visible to the public API.
types.h
Types and enums only used internally.
InternalZGY::RawDataType
RawDataType
Definition: enum.h:95
InternalZGY::DataBufferNd
Definition: databuffer.h:255
InternalZGY::RawDataTypeTraits
Definition: types.h:34
InternalZGY
Implementation not visible to clients.
InternalZGY::DataBuffer
Each DataBuffer instance represents some in memory data.
Definition: databuffer.h:185