Commit 285791a6 authored by Jørgen Lind's avatar Jørgen Lind
Browse files

Merge branch feature/jorgen.lind/sample_formats with refs/heads/master into...

Merge branch feature/jorgen.lind/sample_formats with refs/heads/master into refs/merge-requests/531/train
parents 04f0a0a9 6ac6147a
Pipeline #86122 passed with stages
in 26 minutes and 28 seconds
/****************************************************************************
** Copyright 2021 The Open Group
** Copyright 2021 Bluware, Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
****************************************************************************/
#ifndef VALUERANGEESTIMATOR_H
#define VALUERANGEESTIMATOR_H
namespace OpenVDS
{
template<class T>
class HeapBasedValueRangeEstimator
{
private:
std::vector<T> m_minHeap,
m_maxHeap;
const int m_heapSizeMax;
int m_nanCount;
public:
HeapBasedValueRangeEstimator(float percentile, uint64_t sampleCount)
: m_heapSizeMax(int(((100.0f - percentile) / 100.0f) * sampleCount / 2) + 1)
, m_nanCount(0)
{
m_minHeap.reserve(m_heapSizeMax);
m_maxHeap.reserve(m_heapSizeMax);
}
template<typename InputIt, typename IsNan>
void UpdateValueRange(InputIt first, InputIt last, IsNan isNan)
{
std::for_each(first, last, [this, isNan](const T& element)
{
if (isNan(element))
{
++m_nanCount;
return;
}
if (int(m_minHeap.size()) < m_heapSizeMax)
{
m_minHeap.push_back(element);
std::push_heap(m_minHeap.begin(), m_minHeap.end(), std::less<T>());
}
else if (element < m_minHeap[0])
{
std::pop_heap(m_minHeap.begin(), m_minHeap.end(), std::less<T>());
m_minHeap.back() = element;
std::push_heap(m_minHeap.begin(), m_minHeap.end(), std::less<T>());
}
if (int(m_maxHeap.size()) < m_heapSizeMax)
{
m_maxHeap.push_back(element);
std::push_heap(m_maxHeap.begin(), m_maxHeap.end(), std::greater<T>());
}
else if (element > m_maxHeap[0])
{
std::pop_heap(m_maxHeap.begin(), m_maxHeap.end(), std::greater<T>());
m_maxHeap.back() = element;
std::push_heap(m_maxHeap.begin(), m_maxHeap.end(), std::greater<T>());
}
});
}
template<typename InputIt>
void UpdateValueRange(InputIt first, InputIt last)
{
UpdateValueRange(first, last, [](T) {return false; });
}
void GetValueRange(float& valueRangeMin, float& valueRangeMax)
{
if (!m_minHeap.empty())
{
if (m_minHeap[0] != m_maxHeap[0])
{
valueRangeMin = m_minHeap[0];
valueRangeMax = m_maxHeap[0];
}
else
{
valueRangeMin = m_minHeap[0];
valueRangeMax = valueRangeMin + 1.0f;
}
}
else
{
valueRangeMin = 0.0f;
valueRangeMax = 1.0f;
}
}
int NaNCount() const
{
return m_nanCount;
}
};
}
#endif
......@@ -305,6 +305,73 @@ int FormatSize(BinaryHeader::DataSampleFormatCode dataSampleFormatCode)
return 0;
}
const char* DataSampleFormatCodeToString(BinaryHeader::DataSampleFormatCode dataSampleFormatCode)
{
switch (dataSampleFormatCode)
{
case BinaryHeader::DataSampleFormatCode::Unknown: return "Unknown";
case BinaryHeader::DataSampleFormatCode::IBMFloat: return "IBMFloat";
case BinaryHeader::DataSampleFormatCode::Int32: return "Int32";
case BinaryHeader::DataSampleFormatCode::Int16: return "Int16";
case BinaryHeader::DataSampleFormatCode::FixedPoint: return "FixedPoint";
case BinaryHeader::DataSampleFormatCode::IEEEFloat: return "IEEEFloat";
case BinaryHeader::DataSampleFormatCode::IEEEDouble: return "IEEEDouble";
case BinaryHeader::DataSampleFormatCode::Int24: return "Int24";
case BinaryHeader::DataSampleFormatCode::Int8: return "Int8";
case BinaryHeader::DataSampleFormatCode::Int64: return "Int64";
case BinaryHeader::DataSampleFormatCode::UInt32: return "UInt32";
case BinaryHeader::DataSampleFormatCode::UInt16: return "UInt16";
case BinaryHeader::DataSampleFormatCode::UInt64: return "UInt64";
case BinaryHeader::DataSampleFormatCode::UInt24: return "UInt24";
case BinaryHeader::DataSampleFormatCode::UInt8: return "UInt8";
}
return "";
}
bool DataSampleFormatCodeFromString(const char *codeString, BinaryHeader::DataSampleFormatCode& code)
{
std::string lowercase = codeString;
std::transform(lowercase.begin(), lowercase.end(), lowercase.begin(), [](char in) {
if (in <= 'Z' && in >= 'A')
return char(in - ('Z' - 'z'));
return in;
});
if (lowercase == "unknown")
code = BinaryHeader::DataSampleFormatCode::Unknown;
else if (lowercase == "ibmfloat")
code = BinaryHeader::DataSampleFormatCode::IBMFloat;
else if (lowercase == "int32")
code = BinaryHeader::DataSampleFormatCode::Int32;
else if (lowercase == "int16")
code = BinaryHeader::DataSampleFormatCode::Int16;
else if (lowercase == "fixedpoint")
code = BinaryHeader::DataSampleFormatCode::FixedPoint;
else if (lowercase == "ieeefloat")
code = BinaryHeader::DataSampleFormatCode::IEEEFloat;
else if (lowercase == "ieeedouble")
code = BinaryHeader::DataSampleFormatCode::IEEEDouble;
else if (lowercase == "int24")
code = BinaryHeader::DataSampleFormatCode::Int24;
else if (lowercase == "int8")
code = BinaryHeader::DataSampleFormatCode::Int8;
else if (lowercase == "int64")
code = BinaryHeader::DataSampleFormatCode::Int64;
else if (lowercase == "uint32")
code = BinaryHeader::DataSampleFormatCode::UInt32;
else if (lowercase == "uint16")
code = BinaryHeader::DataSampleFormatCode::UInt16;
else if (lowercase == "uint64")
code = BinaryHeader::DataSampleFormatCode::UInt64;
else if (lowercase == "uint24")
code = BinaryHeader::DataSampleFormatCode::UInt24;
else if (lowercase == "uint8")
code = BinaryHeader::DataSampleFormatCode::UInt8;
else
return false;
return true;
}
bool
IsSEGYTypeUnbinned(SEGYType segyType)
{
......
......@@ -88,6 +88,8 @@ enum class DataSampleFormatCode
UInt8 = 16 // 1-byte, unsigned integer
};
const char* DataSampleFormatCodeToString(DataSampleFormatCode code);
enum class SortCode
{
Other = -1, // Other (should be explained in a user Extended Textual File Header stanza)
......@@ -315,6 +317,8 @@ OPENVDS_EXPORT int ReadFieldFromHeader(const void *header, HeaderField const &he
// Byte size of sample, returns 0 for invalid format
OPENVDS_EXPORT int FormatSize(BinaryHeader::DataSampleFormatCode dataSampleFormatCode);
OPENVDS_EXPORT const char* DataSampleFormatCodeToString(BinaryHeader::DataSampleFormatCode dataSampleFormatCode);
OPENVDS_EXPORT bool DataSampleFormatCodeFromString(const char *codeString, BinaryHeader::DataSampleFormatCode& code);
enum class SampleUnits
{
......
......@@ -17,6 +17,7 @@ SEGYImport [OPTION...] <input file>
| --scale \<value> | If a scale override (floating point) is given, it is used to scale the coordinates in the header instead of determining the scale factor from the coordinate scale trace header field. |
| --sample-unit \<string> | A sample unit of 'ms' is used for datasets in the time domain (default), while a sample unit of 'm' or 'ft' is used for datasets in the depth domain. |
| --sample-start \<value> | The start time/depth/frequency (depending on the domain) of the sampling. |
| --sample-format \<string> | Override the data format used when reading sample data from SEGY file. Possible values are: IBMFloat, IEEEFloat, UInt32, Int32, UInt16, Int16, UInt8, Int8. |
| --crs-wkt \<string> | A coordinate reference system in well-known text format can optionally be provided. |
| -l, --little-endian | Force little-endian trace headers. |
| --scan | Generate a JSON file containing information about the input SEG-Y file. |
......
This diff is collapsed.
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