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

add options for attribute name and unit

parent 3a27324e
"""
Global configuration information for SEGYImport pytests
"""
import os
import subprocess
from typing import List
test_output_dir = "c:\\temp\\SEGY\\t"
test_data_dir = "c:\\temp\\SEGY\\RegressionTestData"
class ImportExecutor:
def __init__(self):
import_exe = os.getenv("SEGYIMPORT_EXECUTABLE")
if not import_exe:
raise EnvironmentError("SEGYIMPORT_EXECUTABLE environment variable is not set")
self.args = [import_exe]
self.run_result = None
def add_arg(self, more_arg: str):
self.args.append(more_arg)
def add_args(self, more_args: List[str]):
self.args.extend(more_args)
def run(self) -> int:
self.run_result = subprocess.run(self.args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
return self.run_result.returncode
def output(self) -> str:
if self.run_result:
return str(self.run_result.stdout)
return ""
def command_line(self) -> str:
"""Convenience method to return a string showing the command and arguments"""
return " ".join(self.args)
pass
\ No newline at end of file
import os
from pathlib import Path
import pytest
import openvds
from segyimport_test_config import test_data_dir, test_output_dir, ImportExecutor
@pytest.fixture
def poststack_segy() -> str:
return os.path.join(test_data_dir, "HeadwavePlatform", "PlatformIntegration", "Teleport", "Teleport_Trim",
"3D_Stack", "ST0202R08_TIME.segy")
@pytest.fixture
def output_vds() -> str:
vds_filename = os.path.join(test_output_dir, "import_test.vds")
if Path(vds_filename).exists():
os.remove(vds_filename)
return vds_filename
def test_default_attribute_and_unit(poststack_segy, output_vds):
ex = ImportExecutor()
ex.add_args(["--vdsfile", output_vds])
ex.add_arg(poststack_segy)
result = ex.run()
assert result == 0, ex.output()
assert Path(output_vds).exists()
with openvds.open(output_vds, "") as handle:
layout = openvds.getLayout(handle)
descriptor = layout.getChannelDescriptor(0)
assert descriptor.name == "Amplitude"
assert descriptor.unit == ""
def test_custom_attribute_name(poststack_segy, output_vds):
custom_attribute_name = "Vrms"
ex = ImportExecutor()
ex.add_args(["--vdsfile", output_vds])
ex.add_args(["--attribute-name", custom_attribute_name])
ex.add_arg(poststack_segy)
result = ex.run()
assert result == 0, ex.output()
assert Path(output_vds).exists()
with openvds.open(output_vds, "") as handle:
layout = openvds.getLayout(handle)
descriptor = layout.getChannelDescriptor(0)
assert descriptor.name == custom_attribute_name
assert descriptor.unit == ""
def test_custom_attribute_unit(poststack_segy, output_vds):
custom_attribute_unit = "Hz"
ex = ImportExecutor()
ex.add_args(["--vdsfile", output_vds])
ex.add_args(["--attribute-unit", custom_attribute_unit])
ex.add_arg(poststack_segy)
result = ex.run()
assert result == 0, ex.output()
assert Path(output_vds).exists()
with openvds.open(output_vds, "") as handle:
layout = openvds.getLayout(handle)
descriptor = layout.getChannelDescriptor(0)
assert descriptor.name == "Amplitude"
assert descriptor.unit == custom_attribute_unit
def test_invalid_attribute_name(poststack_segy, output_vds):
custom_attribute_name = "JulesVerne"
ex = ImportExecutor()
ex.add_args(["--vdsfile", output_vds])
ex.add_args(["--attribute-name", custom_attribute_name])
ex.add_arg(poststack_segy)
result = ex.run()
assert result > 0, ex.output()
assert not Path(output_vds).exists()
def test_invalid_attribute_unit(poststack_segy, output_vds):
custom_attribute_unit = "furlong/fortnight"
ex = ImportExecutor()
ex.add_args(["--vdsfile", output_vds])
ex.add_args(["--attribute-unit", custom_attribute_unit])
ex.add_arg(poststack_segy)
result = ex.run()
assert result > 0, ex.output()
assert not Path(output_vds).exists()
import os
import subprocess
from pathlib import Path
from typing import List
import pytest
import openvds
from segyimport_test_config import test_data_dir, test_output_dir
from segyimport_test_config import test_data_dir, test_output_dir, ImportExecutor
@pytest.fixture
......@@ -59,35 +58,6 @@ def multi_file_input_file_info_files(multi_file_input_parts_count, multi_file_in
return filenames
class ImportExecutor:
def __init__(self):
import_exe = os.getenv("SEGYIMPORT_EXECUTABLE")
if not import_exe:
raise EnvironmentError("SEGYIMPORT_EXECUTABLE environment variable is not set")
self.args = [import_exe]
self.run_result = None
def add_arg(self, more_arg: str):
self.args.append(more_arg)
def add_args(self, more_args: List[str]):
self.args.extend(more_args)
def run(self) -> int:
self.run_result = subprocess.run(self.args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
return self.run_result.returncode
def output(self) -> str:
if self.run_result:
return str(self.run_result.stdout)
return ""
def command_line(self) -> str:
"""Convenience method to return a string showing the command and arguments"""
return " ".join(self.args)
pass
def test_multi_file_scan_one_file_info(multi_file_input_glob):
"""
Tests --scan with multiple input SEGY files, but only one file info file specified.
......
......@@ -1306,13 +1306,13 @@ struct OffsetChannelInfo
};
std::vector<OpenVDS::VolumeDataChannelDescriptor>
createChannelDescriptors(SEGYFileInfo const& fileInfo, OpenVDS::FloatRange const& valueRange, const OffsetChannelInfo& offsetInfo)
createChannelDescriptors(SEGYFileInfo const& fileInfo, OpenVDS::FloatRange const& valueRange, const OffsetChannelInfo& offsetInfo, const std::string& attributeName, const std::string& attributeUnit)
{
std::vector<OpenVDS::VolumeDataChannelDescriptor>
channelDescriptors;
// Primary channel
channelDescriptors.emplace_back(OpenVDS::VolumeDataChannelDescriptor::Format_R32, OpenVDS::VolumeDataChannelDescriptor::Components_1, AMPLITUDE_ATTRIBUTE_NAME, "", valueRange.Min, valueRange.Max);
channelDescriptors.emplace_back(OpenVDS::VolumeDataChannelDescriptor::Format_R32, OpenVDS::VolumeDataChannelDescriptor::Components_1, attributeName.c_str(), attributeUnit.c_str(), valueRange.Min, valueRange.Max);
// Trace defined flag
channelDescriptors.emplace_back(OpenVDS::VolumeDataChannelDescriptor::Format_U8, OpenVDS::VolumeDataChannelDescriptor::Components_1, "Trace", "", 0.0f, 1.0f, OpenVDS::VolumeDataMapping::PerTrace, OpenVDS::VolumeDataChannelDescriptor::DiscreteData);
......@@ -1507,14 +1507,16 @@ main(int argc, char* argv[])
bool help = false;
bool helpConnection = false;
bool version = false;
std::string attributeName = AMPLITUDE_ATTRIBUTE_NAME;
std::string attributeUnit;
std::string supportedCompressionMethods = "None";
if(OpenVDS::IsCompressionMethodSupported(OpenVDS::CompressionMethod::Wavelet)) supportedCompressionMethods += ", Wavelet";
if(OpenVDS::IsCompressionMethodSupported(OpenVDS::CompressionMethod::RLE)) supportedCompressionMethods += ", RLE";
if(OpenVDS::IsCompressionMethodSupported(OpenVDS::CompressionMethod::Zip)) supportedCompressionMethods += ", Zip";
if(OpenVDS::IsCompressionMethodSupported(OpenVDS::CompressionMethod::WaveletNormalizeBlock)) supportedCompressionMethods += ", WaveletNormalizeBlock";
if(OpenVDS::IsCompressionMethodSupported(OpenVDS::CompressionMethod::WaveletLossless)) supportedCompressionMethods += ", WaveletLossless";
if(OpenVDS::IsCompressionMethodSupported(OpenVDS::CompressionMethod::WaveletNormalizeBlockLossless)) supportedCompressionMethods += ", WaveletNormalizeBlockLossless";
if (OpenVDS::IsCompressionMethodSupported(OpenVDS::CompressionMethod::Wavelet)) supportedCompressionMethods += ", Wavelet";
if (OpenVDS::IsCompressionMethodSupported(OpenVDS::CompressionMethod::RLE)) supportedCompressionMethods += ", RLE";
if (OpenVDS::IsCompressionMethodSupported(OpenVDS::CompressionMethod::Zip)) supportedCompressionMethods += ", Zip";
if (OpenVDS::IsCompressionMethodSupported(OpenVDS::CompressionMethod::WaveletNormalizeBlock)) supportedCompressionMethods += ", WaveletNormalizeBlock";
if (OpenVDS::IsCompressionMethodSupported(OpenVDS::CompressionMethod::WaveletLossless)) supportedCompressionMethods += ", WaveletLossless";
if (OpenVDS::IsCompressionMethodSupported(OpenVDS::CompressionMethod::WaveletNormalizeBlockLossless)) supportedCompressionMethods += ", WaveletNormalizeBlockLossless";
std::vector<std::string> fileNames;
......@@ -1531,7 +1533,7 @@ main(int argc, char* argv[])
options.add_option("", "", "scan", "Generate a JSON file containing information about the input SEG-Y file.", cxxopts::value<bool>(scan), "");
options.add_option("", "i", "file-info", "A JSON file (generated by the --scan option) containing information about an input SEG-Y file.", cxxopts::value<std::vector<std::string>>(fileInfoFileNames), "<file>");
options.add_option("", "b", "brick-size", "The brick size for the volume data store.", cxxopts::value<int>(brickSize), "<value>");
options.add_option("", "", "margin", "The margin size (overlap) of the bricks.", cxxopts::value<int>(margin), "<value>");
options.add_option("", "", "margin", "The margin size (overlap) of the bricks.", cxxopts::value<int>(margin), "<value>");
options.add_option("", "f", "force", "Continue on upload error.", cxxopts::value<bool>(force), "");
options.add_option("", "", "ignore-warnings", "Ignore warnings about import parameters.", cxxopts::value<bool>(ignoreWarnings), "");
options.add_option("", "", "compression-method", std::string("Compression method. Supported compression methods are: ") + supportedCompressionMethods + ".", cxxopts::value<std::string>(compressionMethodString), "<string>");
......@@ -1545,6 +1547,8 @@ main(int argc, char* argv[])
options.add_option("", "", "uniqueID", "Generate a new globally unique ID when scanning the input SEG-Y file.", cxxopts::value<bool>(uniqueID), "");
options.add_option("", "", "disable-persistentID", "Disable the persistentID usage, placing the VDS directly into the url location.", cxxopts::value<bool>(disablePersistentID), "");
options.add_option("", "", "json-output", "Enable json output.", cxxopts::value<bool>(jsonOutput), "");
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>");
// TODO add option for turning off traceOrderByOffset
options.add_option("", "h", "help", "Print this help information", cxxopts::value<bool>(help), "");
......@@ -1567,7 +1571,7 @@ main(int argc, char* argv[])
overrideBrickSize = result.count("brick-size") != 0;
overrideMargin = result.count("margin") != 0;
}
catch (cxxopts::OptionParseException &e)
catch (cxxopts::OptionParseException& e)
{
OpenVDS::printError(jsonOutput, "Args", e.what());
return EXIT_FAILURE;
......@@ -1601,33 +1605,33 @@ main(int argc, char* argv[])
std::transform(compressionMethodString.begin(), compressionMethodString.end(), compressionMethodString.begin(), asciitolower);
if(compressionMethodString.empty()) compressionMethod = OpenVDS::CompressionMethod::None;
else if(compressionMethodString == "none") compressionMethod = OpenVDS::CompressionMethod::None;
else if(compressionMethodString == "wavelet") compressionMethod = OpenVDS::CompressionMethod::Wavelet;
else if(compressionMethodString == "rle") compressionMethod = OpenVDS::CompressionMethod::RLE;
else if(compressionMethodString == "zip") compressionMethod = OpenVDS::CompressionMethod::Zip;
else if(compressionMethodString == "waveletnormalizeblock") compressionMethod = OpenVDS::CompressionMethod::WaveletNormalizeBlock;
else if(compressionMethodString == "waveletlossless") compressionMethod = OpenVDS::CompressionMethod::WaveletLossless;
else if(compressionMethodString == "waveletnormalizeblocklossless") compressionMethod = OpenVDS::CompressionMethod::WaveletNormalizeBlockLossless;
if (compressionMethodString.empty()) compressionMethod = OpenVDS::CompressionMethod::None;
else if (compressionMethodString == "none") compressionMethod = OpenVDS::CompressionMethod::None;
else if (compressionMethodString == "wavelet") compressionMethod = OpenVDS::CompressionMethod::Wavelet;
else if (compressionMethodString == "rle") compressionMethod = OpenVDS::CompressionMethod::RLE;
else if (compressionMethodString == "zip") compressionMethod = OpenVDS::CompressionMethod::Zip;
else if (compressionMethodString == "waveletnormalizeblock") compressionMethod = OpenVDS::CompressionMethod::WaveletNormalizeBlock;
else if (compressionMethodString == "waveletlossless") compressionMethod = OpenVDS::CompressionMethod::WaveletLossless;
else if (compressionMethodString == "waveletnormalizeblocklossless") compressionMethod = OpenVDS::CompressionMethod::WaveletNormalizeBlockLossless;
else
{
OpenVDS::printError(jsonOutput, "CompressionMethod", "Unknown compression method", compressionMethodString);
return EXIT_FAILURE;
}
if(!OpenVDS::IsCompressionMethodSupported(compressionMethod))
if (!OpenVDS::IsCompressionMethodSupported(compressionMethod))
{
OpenVDS::printError(jsonOutput, "CompressionMethod", "Unsupported compression method", compressionMethodString);
return EXIT_FAILURE;
}
if(compressionMethod == OpenVDS::CompressionMethod::Wavelet || compressionMethod == OpenVDS::CompressionMethod::WaveletNormalizeBlock || compressionMethod == OpenVDS::CompressionMethod::WaveletLossless || compressionMethod == OpenVDS::CompressionMethod::WaveletNormalizeBlockLossless)
if (compressionMethod == OpenVDS::CompressionMethod::Wavelet || compressionMethod == OpenVDS::CompressionMethod::WaveletNormalizeBlock || compressionMethod == OpenVDS::CompressionMethod::WaveletLossless || compressionMethod == OpenVDS::CompressionMethod::WaveletNormalizeBlockLossless)
{
if(!overrideBrickSize)
if (!overrideBrickSize)
{
brickSize = 128;
}
if(!overrideMargin)
if (!overrideMargin)
{
margin = 4;
}
......@@ -1639,9 +1643,9 @@ main(int argc, char* argv[])
SEGY::SEGYType segyType = SEGY::SEGYType::Poststack;
if (primaryKey == "inlinenumber" || primaryKey == "crosslinenumber" )
if (primaryKey == "inlinenumber" || primaryKey == "crosslinenumber")
{
if(prestack)
if (prestack)
{
segyType = SEGY::SEGYType::Prestack;
}
......@@ -1684,13 +1688,13 @@ main(int argc, char* argv[])
if (singleConnection)
inputConnection = urlConnection;
if(uniqueID && !persistentID.empty())
if (uniqueID && !persistentID.empty())
{
OpenVDS::printError(jsonOutput, "Args", "--uniqueID does not make sense when the persistentID is specified");
return EXIT_FAILURE;
}
if(disablePersistentID && !persistentID.empty())
if (disablePersistentID && !persistentID.empty())
{
OpenVDS::printError(jsonOutput, "Args", "--disable-PersistentID does not make sense when the persistentID is specified");
return EXIT_FAILURE;
......@@ -1769,14 +1773,14 @@ main(int argc, char* argv[])
fileInfo.m_segyType = segyType;
// Scan the file if '--scan' was passed or we're uploading but no fileInfo file was specified
if(scan || fileInfoFileNames.empty())
if (scan || fileInfoFileNames.empty())
{
if(!uniqueID)
if (!uniqueID)
{
OpenVDS::HashCombiner
hash;
for(std::string const &fileName : fileNames)
for (std::string const& fileName : fileNames)
{
hash.Add(fileName);
}
......@@ -1792,13 +1796,13 @@ main(int argc, char* argv[])
return EXIT_FAILURE;
}
if(overrideSampleStart)
if (overrideSampleStart)
{
fileInfo.m_startTimeMilliseconds = sampleStart;
}
// If we are in scan mode we serialize the result of the file scan either to a fileInfo file (if specified) or to stdout and exit
if(scan)
if (scan)
{
for (int fileIndex = 0; fileIndex < fileNames.size(); ++fileIndex)
{
......@@ -1918,7 +1922,7 @@ main(int argc, char* argv[])
// Check for only a single segment
if(fileInfo.m_segmentInfoLists.size() == 1 && fileInfo.m_segmentInfoLists[0].size() == 1)
if (fileInfo.m_segmentInfoLists.size() == 1 && fileInfo.m_segmentInfoLists[0].size() == 1)
{
OpenVDS::printWarning_with_condition_fatal(jsonOutput, !ignoreWarnings, "SegmentInfoList", "Warning: There is only one segment, either this is (as of now unsupported) 2D data or this usually indicates using the wrong header format for the input dataset.", "Use --ignore-warnings to force the import to go ahead.");
}
......@@ -1949,7 +1953,7 @@ main(int argc, char* argv[])
}
else if (segyType == SEGY::SEGYType::Poststack || segyType == SEGY::SEGYType::Poststack2D)
{
if(fold > 1)
if (fold > 1)
{
OpenVDS::printError(jsonOutput, "SEGY", fmt::format("Detected a fold of '{0}', this usually indicates using the wrong header format or primary key for the input dataset or that the input data is binned prestack data (PSTM/PSDM gathers) in which case the --prestack option should be used.", fold));
return EXIT_FAILURE;
......@@ -1991,15 +1995,15 @@ main(int argc, char* argv[])
SEGY::SampleUnits
sampleUnits;
if(sampleUnit.empty() || sampleUnit == "ms" || sampleUnit == "millisecond" || sampleUnit == "milliseconds")
if (sampleUnit.empty() || sampleUnit == "ms" || sampleUnit == "millisecond" || sampleUnit == "milliseconds")
{
sampleUnits = SEGY::SampleUnits::Milliseconds;
}
else if(sampleUnit == "m" || sampleUnit == "meter" || sampleUnit == "meters")
else if (sampleUnit == "m" || sampleUnit == "meter" || sampleUnit == "meters")
{
sampleUnits = SEGY::SampleUnits::Meters;
}
else if(sampleUnit == "ft" || sampleUnit == "foot" || sampleUnit == "feet")
else if (sampleUnit == "ft" || sampleUnit == "foot" || sampleUnit == "feet")
{
sampleUnits = SEGY::SampleUnits::Feet;
}
......@@ -2009,6 +2013,28 @@ main(int argc, char* argv[])
return EXIT_FAILURE;
}
if (!(attributeName == DEFAULT_ATTRIBUTE_NAME || attributeName == AMPLITUDE_ATTRIBUTE_NAME || attributeName == DEPTH_ATTRIBUTE_NAME
|| attributeName == PROBABILITY_ATTRIBUTE_NAME || attributeName == TIME_ATTRIBUTE_NAME || attributeName == AVERAGE_VELOCITY_ATTRIBUTE_NAME
|| attributeName == INTERVAL_VELOCITY_ATTRIBUTE_NAME || attributeName == RMS_VELOCITY_ATTRIBUTE_NAME))
{
const auto msg = fmt::format("Unknown attribute name: {}, legal names are '{}', '{}', '{}', '{}', '{}', '{}', '{}', or '{}'\n",
attributeName, DEFAULT_ATTRIBUTE_NAME, AMPLITUDE_ATTRIBUTE_NAME, DEPTH_ATTRIBUTE_NAME, PROBABILITY_ATTRIBUTE_NAME, TIME_ATTRIBUTE_NAME, AVERAGE_VELOCITY_ATTRIBUTE_NAME,
INTERVAL_VELOCITY_ATTRIBUTE_NAME, RMS_VELOCITY_ATTRIBUTE_NAME);
OpenVDS::printError(jsonOutput, "Args", msg);
return EXIT_FAILURE;
}
if (!(attributeUnit.empty() || attributeUnit == KNOWNMETADATA_UNIT_FOOT || attributeUnit == KNOWNMETADATA_UNIT_FEET_PER_SECOND
|| attributeUnit == "Hz" || attributeUnit == KNOWNMETADATA_UNIT_METER || attributeUnit == KNOWNMETADATA_UNIT_METERS_PER_SECOND
|| attributeUnit == KNOWNMETADATA_UNIT_MILLISECOND || attributeUnit == KNOWNMETADATA_UNIT_SECOND))
{
const auto msg = fmt::format("Unknown attribute unit: {}, legal units are blank (no units), '{}', '{}', '{}', '{}', '{}', '{}', or '{}'\n",
attributeUnit, KNOWNMETADATA_UNIT_FOOT, KNOWNMETADATA_UNIT_FEET_PER_SECOND, "Hz", KNOWNMETADATA_UNIT_METER, KNOWNMETADATA_UNIT_METERS_PER_SECOND,
KNOWNMETADATA_UNIT_MILLISECOND, KNOWNMETADATA_UNIT_SECOND);
OpenVDS::printError(jsonOutput, "Args", msg);
return EXIT_FAILURE;
}
// Create axis descriptors
std::vector<OpenVDS::VolumeDataAxisDescriptor> axisDescriptors = createAxisDescriptors(fileInfo, sampleUnits, fold, primaryStep, secondaryStep);
......@@ -2033,7 +2059,7 @@ main(int argc, char* argv[])
}
// Create channel descriptors
std::vector<OpenVDS::VolumeDataChannelDescriptor> channelDescriptors = createChannelDescriptors(fileInfo, valueRange, OffsetChannelInfo(fileInfo.HasGatherOffset(), offsetStart, offsetEnd, offsetStep));
std::vector<OpenVDS::VolumeDataChannelDescriptor> channelDescriptors = createChannelDescriptors(fileInfo, valueRange, OffsetChannelInfo(fileInfo.HasGatherOffset(), offsetStart, offsetEnd, offsetStep), attributeName, attributeUnit);
// Create metadata
OpenVDS::MetadataContainer
......
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