Commit 19e6a8cd authored by Jim King's avatar Jim King Committed by Jørgen Lind
Browse files

supporting changes for offset sorted

parent 4b104c5b
......@@ -54,6 +54,12 @@ SEGYFileInfo::Is2D() const
return m_segyType == SEGYType::Poststack2D || m_segyType == SEGYType::Prestack2D;
}
bool
SEGYFileInfo::IsOffsetSorted() const
{
return m_segyType == SEGYType::PrestackOffsetSorted;
}
SEGYBinInfo
SEGYFileInfo::readBinInfoFromHeader(const char *header, SEGYBinInfoHeaderFields const &headerFields, Endianness endianness, int segmentTraceIndex) const
{
......@@ -99,8 +105,15 @@ SEGYFileInfo::StaticGetUniqueID()
}
bool
SEGYFileInfo::Scan(const std::vector<DataProvider>& dataProviders, OpenVDS::Error &error, HeaderField const &primaryKeyHeaderField, HeaderField const &secondaryKeyHeaderField, SEGY::HeaderField const &startTimeHeaderField, SEGYBinInfoHeaderFields const &binInfoHeaderFields)
SEGYFileInfo::Scan(const std::vector<DataProvider>& dataProviders, OpenVDS::Error &error, HeaderField const &primaryKeyHeaderField, HeaderField const &secondaryKeyHeaderField, SEGY::HeaderField const &startTimeHeaderField, SEGY::HeaderField const& offsetHeaderField, SEGYBinInfoHeaderFields const &binInfoHeaderFields)
{
std::function<int(const char*)>
readOffset = [](const char* traceHeader) { return -1; };
if (IsOffsetSorted())
{
readOffset = [offsetHeaderField, this](const char* traceHeader) { return ReadFieldFromHeader(traceHeader, offsetHeaderField, m_headerEndianness); };
}
char textualFileHeader[TextualFileHeaderSize];
char binaryFileHeader[BinaryFileHeaderSize];
char traceHeader[TraceHeaderSize];
......@@ -148,14 +161,6 @@ SEGYFileInfo::Scan(const std::vector<DataProvider>& dataProviders, OpenVDS::Erro
for (const auto& dataProvider : dataProviders)
{
m_segmentInfoLists.emplace_back();
m_traceCounts.emplace_back();
auto&
segmentInfos = m_segmentInfoLists.back();
auto&
traceCount = m_traceCounts.back();
int64_t fileSize = dataProvider.Size(error);
if (error.code != 0)
......@@ -176,6 +181,32 @@ SEGYFileInfo::Scan(const std::vector<DataProvider>& dataProviders, OpenVDS::Erro
return false;
}
int
currentOffset = readOffset(traceHeader);
std::function<void(int, const SEGYSegmentInfo&)>
pushSegmentInfo;
if (IsOffsetSorted())
{
m_segmentInfoListsByOffset.emplace_back();
auto&
offsetMap = m_segmentInfoListsByOffset.back();
offsetMap.emplace(currentOffset, std::vector<SEGYSegmentInfo>());
pushSegmentInfo = [this](int offset, const SEGYSegmentInfo& segmentInfo) { m_segmentInfoListsByOffset.back()[offset].push_back(segmentInfo); };
}
else
{
m_segmentInfoLists.emplace_back();
pushSegmentInfo = [this](int offset, const SEGYSegmentInfo& segmentInfo) { m_segmentInfoLists.back().push_back(segmentInfo); };
}
m_traceCounts.emplace_back();
auto&
traceCount = m_traceCounts.back();
// If the sample count is not set in the binary header we try to find it from the first trace header
if (m_sampleCount == 0)
{
......@@ -188,7 +219,7 @@ SEGYFileInfo::Scan(const std::vector<DataProvider>& dataProviders, OpenVDS::Erro
m_sampleIntervalMilliseconds = ReadFieldFromHeader(traceHeader, TraceHeader::SampleIntervalHeaderField, m_headerEndianness) / 1000.0;
}
int64_t traceDataSize = (fileSize - TextualFileHeaderSize - BinaryFileHeaderSize);
const int64_t traceDataSize = (fileSize - TextualFileHeaderSize - BinaryFileHeaderSize);
traceCount = traceDataSize / TraceByteSize();
......@@ -217,6 +248,10 @@ SEGYFileInfo::Scan(const std::vector<DataProvider>& dataProviders, OpenVDS::Erro
int readCount = 1;
int
testOffset,
nextOffset;
while (segmentInfo.m_traceStop != lastTrace)
{
dataProvider.Read(traceHeader, TextualFileHeaderSize + BinaryFileHeaderSize + trace * TraceByteSize(), TraceHeaderSize, error);
......@@ -227,9 +262,10 @@ SEGYFileInfo::Scan(const std::vector<DataProvider>& dataProviders, OpenVDS::Erro
}
readCount++;
int primaryKey = ReadFieldFromHeader(traceHeader, primaryKeyHeaderField, m_headerEndianness);
primaryKey = ReadFieldFromHeader(traceHeader, primaryKeyHeaderField, m_headerEndianness);
testOffset = readOffset(traceHeader);
if (primaryKey == segmentInfo.m_primaryKey) // expand current segment if the primary key matches
if (primaryKey == segmentInfo.m_primaryKey && (!IsOffsetSorted() || testOffset == currentOffset)) // expand current segment if the primary key matches
{
assert(trace > segmentInfo.m_traceStop);
segmentInfo.m_traceStop = trace;
......@@ -241,17 +277,21 @@ SEGYFileInfo::Scan(const std::vector<DataProvider>& dataProviders, OpenVDS::Erro
outsideTrace = trace;
outsideBinInfo = readBinInfoFromHeader(traceHeader, binInfoHeaderFields, m_headerEndianness, 1);
nextPrimaryKey = primaryKey;
nextOffset = testOffset;
}
if (outsideTrace == segmentInfo.m_traceStop + 1) // current segment is finished
{
segmentInfos.push_back(segmentInfo);
int64_t segmentLength = segmentInfo.m_traceStop - segmentInfo.m_traceStart + 1;
pushSegmentInfo(currentOffset, segmentInfo);
const int64_t
segmentLength = segmentInfo.m_traceStop - segmentInfo.m_traceStart + 1;
// start a new segment
segmentInfo = SEGYSegmentInfo(nextPrimaryKey, outsideTrace, outsideBinInfo);
trace = std::min(lastTrace, outsideTrace + segmentLength);
outsideTrace = 0, jump = 1;
currentOffset = nextOffset;
}
else if (outsideTrace == 0) // looking for a trace outside the current segment
{
......@@ -270,7 +310,7 @@ SEGYFileInfo::Scan(const std::vector<DataProvider>& dataProviders, OpenVDS::Erro
}
// final segment in this file is finished
segmentInfos.push_back(segmentInfo);
pushSegmentInfo(testOffset, segmentInfo);
}
return true;
......
......@@ -327,6 +327,7 @@ enum class SEGYType
CDPGathers = 4,
ShotGathers = 5,
ReceiverGathers = 6,
PrestackOffsetSorted = 7
};
OPENVDS_EXPORT bool IsSEGYTypeUnbinned(SEGYType segyType);
......
......@@ -93,6 +93,11 @@ struct SEGYFileInfo
std::vector<std::vector<SEGYSegmentInfo>>
m_segmentInfoLists;
// vector of per-file offset-vector maps for SEGYType::PrestackOffsetSorted
std::vector<std::map<int, std::vector<SEGYSegmentInfo>>>
m_segmentInfoListsByOffset;
SEGY::HeaderField
m_primaryKey,
m_secondaryKey;
......@@ -108,7 +113,7 @@ struct SEGYFileInfo
OPENVDS_EXPORT int TraceByteSize() const;
OPENVDS_EXPORT bool Scan(const std::vector<DataProvider>& dataProviders, OpenVDS::Error &error, SEGY::HeaderField const &primaryKeyHeaderField, SEGY::HeaderField const &secondaryKeyHeaderField = SEGY::HeaderField(), SEGY::HeaderField const &startTimeHeaderField = SEGY::TraceHeader::StartTimeHeaderField, SEGYBinInfoHeaderFields const &binInfoHeaderFields = SEGYBinInfoHeaderFields::StandardHeaderFields());
OPENVDS_EXPORT bool Scan(const std::vector<DataProvider>& dataProviders, OpenVDS::Error &error, SEGY::HeaderField const &primaryKeyHeaderField, SEGY::HeaderField const &secondaryKeyHeaderField = SEGY::HeaderField(), SEGY::HeaderField const &startTimeHeaderField = SEGY::TraceHeader::StartTimeHeaderField, SEGY::HeaderField const& offsetHeaderField = SEGY::TraceHeader::OffsetHeaderField, SEGYBinInfoHeaderFields const &binInfoHeaderFields = SEGYBinInfoHeaderFields::StandardHeaderFields());
OPENVDS_EXPORT SEGYBinInfo readBinInfoFromHeader(const char* header, SEGYBinInfoHeaderFields const& headerFields, SEGY::Endianness endianness, int segmentTraceIndex) const;
......@@ -119,6 +124,8 @@ struct SEGYFileInfo
OPENVDS_EXPORT bool HasGatherOffset() const;
OPENVDS_EXPORT bool Is2D() const;
OPENVDS_EXPORT bool IsOffsetSorted() const;
};
#endif // SEGY_FILE_INFO_H
......@@ -218,15 +218,38 @@ SerializeSEGYFileInfo(SEGYFileInfo const& fileInfo, const int fileIndex)
jsonFileInfo["primaryKey"] = SerializeSEGYHeaderField(fileInfo.m_primaryKey);
jsonFileInfo["secondaryKey"] = SerializeSEGYHeaderField(fileInfo.m_secondaryKey);
Json::Value
jsonSegmentInfoArray(Json::ValueType::arrayValue);
for (auto const& segmentInfo : fileInfo.m_segmentInfoLists[fileIndex])
if (fileInfo.m_segyType == SEGY::SEGYType::PrestackOffsetSorted)
{
jsonSegmentInfoArray.append(SerializeSEGYSegmentInfo(segmentInfo));
Json::Value
jsonOffsetMap;
for (const auto& entry : fileInfo.m_segmentInfoListsByOffset[fileIndex])
{
Json::Value
jsonSegmentInfoArray(Json::ValueType::arrayValue);
for (auto const& segmentInfo : entry.second)
{
jsonSegmentInfoArray.append(SerializeSEGYSegmentInfo(segmentInfo));
}
jsonOffsetMap[std::to_string(entry.first)] = jsonSegmentInfoArray;
}
jsonFileInfo["segmentInfo"] = jsonOffsetMap;
}
else
{
Json::Value
jsonSegmentInfoArray(Json::ValueType::arrayValue);
jsonFileInfo["segmentInfo"] = jsonSegmentInfoArray;
for (auto const& segmentInfo : fileInfo.m_segmentInfoLists[fileIndex])
{
jsonSegmentInfoArray.append(SerializeSEGYSegmentInfo(segmentInfo));
}
jsonFileInfo["segmentInfo"] = jsonSegmentInfoArray;
}
return jsonFileInfo;
}
......@@ -1257,16 +1280,42 @@ parseSEGYFileInfoFile(const DataProvider& dataProvider, SEGYFileInfo& fileInfo,
}
fileInfo.m_traceCounts[fileIndex] = jsonFileInfo["traceCount"].asInt64();
if (fileInfo.m_segmentInfoLists.size() <= fileIndex)
if (fileInfo.m_segyType == SEGY::SEGYType::PrestackOffsetSorted)
{
fileInfo.m_segmentInfoLists.resize(fileIndex + 1);
if (fileInfo.m_segmentInfoListsByOffset.size() <= fileIndex)
{
fileInfo.m_segmentInfoListsByOffset.resize(fileIndex + 1);
}
auto&
offsetMap = fileInfo.m_segmentInfoListsByOffset[fileIndex];
offsetMap.clear();
const auto&
jsonSegmentInfo = jsonFileInfo["segmentInfo"];
for (Json::ValueConstIterator iter = jsonSegmentInfo.begin(); iter != jsonSegmentInfo.end(); ++iter)
{
const auto
offsetValue = std::stoi(iter.key().asString());
auto&
segmentInfoList = offsetMap[offsetValue];
for (const auto& jsonSegmentInfo : *iter)
{
segmentInfoList.push_back(segmentInfoFromJson(jsonSegmentInfo));
}
}
}
auto&
segmentInfo = fileInfo.m_segmentInfoLists[fileIndex];
segmentInfo.clear();
for (const auto& jsonSegmentInfo : jsonFileInfo["segmentInfo"])
else
{
segmentInfo.push_back(segmentInfoFromJson(jsonSegmentInfo));
if (fileInfo.m_segmentInfoLists.size() <= fileIndex)
{
fileInfo.m_segmentInfoLists.resize(fileIndex + 1);
}
auto&
segmentInfo = fileInfo.m_segmentInfoLists[fileIndex];
for (Json::Value jsonSegmentInfo : jsonFileInfo["segmentInfo"])
{
segmentInfo.push_back(segmentInfoFromJson(jsonSegmentInfo));
}
}
}
catch (Json::Exception &e)
......@@ -1666,6 +1715,7 @@ main(int argc, char* argv[])
bool disablePersistentID = false;
bool prestack = false;
bool is2D = false;
bool isOffsetSorted = false;
bool traceOrderByOffset = true;
bool jsonOutput = false;
bool help = false;
......@@ -1719,6 +1769,7 @@ main(int argc, char* argv[])
options.add_option("", "", "attribute-name", "The name of the primary VDS channel. The name may be Amplitude (default), Attribute, Depth, Probability, Time, Vavg, Vint, or Vrms", cxxopts::value<std::string>(attributeName)->default_value(AMPLITUDE_ATTRIBUTE_NAME), "<string>");
options.add_option("", "", "attribute-unit", "The units of the primary VDS channel. The unit name may be blank (default), ft, ft/s, Hz, m, m/s, ms, or s", cxxopts::value<std::string>(attributeUnit), "<string>");
options.add_option("", "", "2d", "Import 2D data.", cxxopts::value<bool>(is2D), "");
options.add_option("", "", "offset-sorted", "Import prestack data sorted by trace header Offset value.", cxxopts::value<bool>(isOffsetSorted), "");
// TODO add option for turning off traceOrderByOffset
options.add_option("", "h", "help", "Print this help information", cxxopts::value<bool>(help), "");
......@@ -1827,6 +1878,10 @@ main(int argc, char* argv[])
SEGY::SEGYType segyType = SEGY::SEGYType::Poststack;
if (isOffsetSorted)
{
segyType = SEGY::SEGYType::PrestackOffsetSorted;
}
if (is2D)
{
if (prestack)
......@@ -1947,7 +2002,8 @@ main(int argc, char* argv[])
}
SEGY::HeaderField
startTimeHeaderField = g_traceHeaderFields["starttime"];
startTimeHeaderField = g_traceHeaderFields["starttime"],
offsetHeaderField = g_traceHeaderFields["offset"];
OpenVDS::Error
error;
......@@ -1987,7 +2043,7 @@ main(int argc, char* argv[])
fileInfo.m_persistentID = OpenVDS::HashCombiner(hash);
}
bool success = fileInfo.Scan(dataProviders, error, primaryKeyHeaderField, secondaryKeyHeaderField, startTimeHeaderField, binInfoHeaderFields);
bool success = fileInfo.Scan(dataProviders, error, primaryKeyHeaderField, secondaryKeyHeaderField, startTimeHeaderField, offsetHeaderField, binInfoHeaderFields);
if (!success)
{
......
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