Commit 323261c2 authored by Jim King's avatar Jim King Committed by Jørgen Lind
Browse files

update analyzeSegment and analyzePrimaryKey

parent 79f1cac1
...@@ -66,6 +66,13 @@ ...@@ -66,6 +66,13 @@
constexpr double METERS_PER_FOOT = 0.3048; constexpr double METERS_PER_FOOT = 0.3048;
enum class TraceSpacingByOffset
{
Off = 0,
On = 1,
Auto = 2
};
int64_t GetTotalSystemMemory() int64_t GetTotalSystemMemory()
{ {
MEMORYSTATUSEX status; MEMORYSTATUSEX status;
...@@ -893,7 +900,7 @@ updateValueRangeHeaps(const SEGYFileInfo& fileInfo, const int heapSizeMax, std:: ...@@ -893,7 +900,7 @@ updateValueRangeHeaps(const SEGYFileInfo& fileInfo, const int heapSizeMax, std::
} }
bool bool
analyzeSegment(DataProvider &dataProvider, SEGYFileInfo const& fileInfo, SEGYSegmentInfo const& segmentInfo, float valueRangePercentile, OpenVDS::FloatRange& valueRange, int& fold, int& secondaryStep, const SEGY::SEGYType segyType, int& offsetStart, int& offsetEnd, int& offsetStep, TraceInfo2DManager * pTraceInfo2DManager, bool isTraceOrderByOffset, bool jsonOutput, OpenVDS::Error& error) analyzeSegment(DataProvider &dataProvider, SEGYFileInfo const& fileInfo, SEGYSegmentInfo const& segmentInfo, float valueRangePercentile, OpenVDS::FloatRange& valueRange, int& fold, int& secondaryStep, const SEGY::SEGYType segyType, TraceInfo2DManager * pTraceInfo2DManager, TraceSpacingByOffset& traceSpacingByOffset, std::vector<int>& offsetValues, bool jsonOutput, OpenVDS::Error& error)
{ {
assert(segmentInfo.m_traceStop >= segmentInfo.m_traceStart && "A valid segment info should always have a stop trace greater or equal to the start trace"); assert(segmentInfo.m_traceStop >= segmentInfo.m_traceStart && "A valid segment info should always have a stop trace greater or equal to the start trace");
assert(pTraceInfo2DManager != nullptr); assert(pTraceInfo2DManager != nullptr);
...@@ -905,9 +912,7 @@ analyzeSegment(DataProvider &dataProvider, SEGYFileInfo const& fileInfo, SEGYSeg ...@@ -905,9 +912,7 @@ analyzeSegment(DataProvider &dataProvider, SEGYFileInfo const& fileInfo, SEGYSeg
valueRange = OpenVDS::FloatRange(0.0f, 1.0f); valueRange = OpenVDS::FloatRange(0.0f, 1.0f);
secondaryStep = 0; secondaryStep = 0;
fold = 1; fold = 1;
offsetStart = 0; offsetValues.clear();
offsetEnd = 0;
offsetStep = 0;
const int traceByteSize = fileInfo.TraceByteSize(); const int traceByteSize = fileInfo.TraceByteSize();
...@@ -929,8 +934,7 @@ analyzeSegment(DataProvider &dataProvider, SEGYFileInfo const& fileInfo, SEGYSeg ...@@ -929,8 +934,7 @@ analyzeSegment(DataProvider &dataProvider, SEGYFileInfo const& fileInfo, SEGYSeg
// Determine fold and secondary step // Determine fold and secondary step
int gatherSecondaryKey = 0, gatherFold = 0, gatherSecondaryStep = 0; int gatherSecondaryKey = 0, gatherFold = 0, gatherSecondaryStep = 0;
std::set<int> std::map<int, std::vector<int>> gatherOffsetValues;
offsetValues;
for (int64_t trace = segmentInfo.m_traceStart; trace <= segmentInfo.m_traceStop; trace++) for (int64_t trace = segmentInfo.m_traceStart; trace <= segmentInfo.m_traceStop; trace++)
{ {
...@@ -988,56 +992,84 @@ analyzeSegment(DataProvider &dataProvider, SEGYFileInfo const& fileInfo, SEGYSeg ...@@ -988,56 +992,84 @@ analyzeSegment(DataProvider &dataProvider, SEGYFileInfo const& fileInfo, SEGYSeg
{ {
const auto const auto
thisOffset = SEGY::ReadFieldFromHeader(header, g_traceHeaderFields["offset"], fileInfo.m_headerEndianness); thisOffset = SEGY::ReadFieldFromHeader(header, g_traceHeaderFields["offset"], fileInfo.m_headerEndianness);
offsetValues.insert(thisOffset); gatherOffsetValues[gatherSecondaryKey].push_back(thisOffset);
} }
// Update value range // Update value range
updateValueRangeHeaps(fileInfo, heapSizeMax, minHeap, maxHeap, data, sampleBuffer); updateValueRangeHeaps(fileInfo, heapSizeMax, minHeap, maxHeap, data, sampleBuffer);
} }
if (fileInfo.HasGatherOffset() && !fileInfo.IsUnbinned()) if (fileInfo.HasGatherOffset() && !fileInfo.IsUnbinned() && !gatherOffsetValues.empty())
{ {
offsetStart = *offsetValues.begin(); // use the longest gather in the segment to populate the list of offset values
offsetEnd = *offsetValues.rbegin();
// iterate over offsetValues to get offset step // find the longest gather
if (offsetValues.size() > 1) int
longestSecondaryKey = (*gatherOffsetValues.begin()).first;
for (const auto& entry : gatherOffsetValues)
{ {
auto if (entry.second.size() > gatherOffsetValues[longestSecondaryKey].size())
iter = offsetValues.begin();
auto
previousOffset = *iter;
offsetStep = INT32_MAX;
while (++iter != offsetValues.end())
{ {
const auto longestSecondaryKey = entry.first;
thisOffset = *iter;
offsetStep = std::min(offsetStep, thisOffset - previousOffset);
previousOffset = thisOffset;
} }
} }
else
{
offsetStep = 1;
}
if (isTraceOrderByOffset) // copy the longest gather's offset values to the method arg
const auto
& longestGatherValues = gatherOffsetValues[longestSecondaryKey];
offsetValues.assign(longestGatherValues.begin(), longestGatherValues.end());
if (traceSpacingByOffset != TraceSpacingByOffset::Off)
{ {
// 'fold' calculated by counting traces in a gather may be incorrect if there are duplicate-key // Determine if offset values are suitable for computed respacing: Values are monotonically increasing
// traces, so we'll ignore it and use the count of unique offset values bool
fold = static_cast<int>(offsetValues.size()); isSane = false;
size_t
numSorted = 0;
// check that offset start/end/step is consistent // check each gather to see if offsets are ordered within every gather
if (offsetStart + (fold - 1) * offsetStep != offsetEnd) for (const auto& entry : gatherOffsetValues)
{ {
const auto const auto
msgFormat = "The detected gather offset start/end/step of '{0}/{1}/{2}' is not consistent with the detected fold of '{3}'. This may indicate an incorrect header format for Offset trace header."; & offsets = entry.second;
const auto if (std::is_sorted(offsets.begin(), offsets.end()))
msg = fmt::format(msgFormat, offsetStart, offsetEnd, offsetStep, fold); {
++numSorted;
}
else
{
// if a gather is unordered then we're done
break;
}
}
if (numSorted == gatherOffsetValues.size())
{
// we can do respacing
if (traceSpacingByOffset == TraceSpacingByOffset::Auto)
{
// change the parameter to On to indicate that respacing is in effect
traceSpacingByOffset = TraceSpacingByOffset::On;
}
}
else if (traceSpacingByOffset == TraceSpacingByOffset::Auto)
{
// the offset spacing doesn't conform to our needs for respacing, so force the setting from Auto to Off
traceSpacingByOffset = TraceSpacingByOffset::Off;
}
else
{
// traceSpacingByOffset is set to On, but detected offset values aren't compatible with the respacing scheme
auto msg = "The detected gather offset values are not monotonically increasing. This may indicate an incorrect header format for the trace header Offset field and/or an incorrect option value for --respace-gathers.";
OpenVDS::printError(jsonOutput, "analyzeSegment", msg); OpenVDS::printError(jsonOutput, "analyzeSegment", msg);
return false; return false;
return false;
} }
} }
} }
// If the secondary step couldn't be determined, set it to the last step or 1 // If the secondary step couldn't be determined, set it to the last step or 1
...@@ -2293,13 +2325,6 @@ main(int argc, char* argv[]) ...@@ -2293,13 +2325,6 @@ main(int argc, char* argv[])
std::string azimuthTypeString; std::string azimuthTypeString;
std::string azimuthUnitString; std::string azimuthUnitString;
enum class TraceSpacingByOffset
{
Off = 0,
On = 1,
Auto = 2
};
TraceSpacingByOffset traceSpacingByOffset = TraceSpacingByOffset::Auto; TraceSpacingByOffset traceSpacingByOffset = TraceSpacingByOffset::Auto;
std::string traceSpacingByOffsetString; std::string traceSpacingByOffsetString;
......
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