|
| 1 | +// Copyright 2025 TGS |
| 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 | +#include "main.hh" |
| 16 | + |
| 17 | +int main() { |
| 18 | + const std::string path = "s3://tgs-opendata-poseidon/full_stack_agc.mdio"; |
| 19 | + const uint64_t cache_size_bytes = 1024ULL * 1024ULL * 1024ULL * 5ULL; // Use a 5GiB cache. |
| 20 | + mdio::Future<mdio::Dataset> dsFut = OpenDataset(path, cache_size_bytes); |
| 21 | + |
| 22 | + if (!dsFut.status().ok()) { |
| 23 | + std::cerr << "Failed to open dataset: " << dsFut.status().message() << std::endl; |
| 24 | + return 1; |
| 25 | + } |
| 26 | + |
| 27 | + mdio::Dataset ds = dsFut.value(); |
| 28 | + std::cout << "Dataset opened successfully" << std::endl; |
| 29 | + std::cout << ds << std::endl; |
| 30 | + |
| 31 | + auto cdpsFut = GetUTMCoords(ds); |
| 32 | + if (!cdpsFut.status().ok()) { |
| 33 | + std::cerr << "Failed to get UTM coordinates: " << cdpsFut.status().message() << std::endl; |
| 34 | + return 1; |
| 35 | + } |
| 36 | + |
| 37 | + auto cdps = cdpsFut.value(); |
| 38 | + auto cdp_x = cdps.first.value(); |
| 39 | + auto cdp_y = cdps.second.value(); |
| 40 | + |
| 41 | + auto cdp_x_extents = GetExtents<mdio::dtypes::float64_t>(cdp_x); |
| 42 | + auto cdp_y_extents = GetExtents<mdio::dtypes::float64_t>(cdp_y); |
| 43 | + |
| 44 | + std::cout << "========CDP Coordinates=========" << std::endl; |
| 45 | + std::cout << "CDP X extents: " << cdp_x_extents << std::endl; |
| 46 | + std::cout << "CDP Y extents: " << cdp_y_extents << std::endl; |
| 47 | + utm::print_corners(cdp_x_extents, cdp_y_extents); |
| 48 | + std::cout << std::endl; |
| 49 | + // This displays the maximum area of the extents on a web map. |
| 50 | + // The surveys actual polygon is not computed in this example. |
| 51 | + utm::web_display(cdp_x_extents, cdp_y_extents); |
| 52 | + std::cout << std::endl; |
| 53 | + std::cout << "=================================" << std::endl << std::endl; |
| 54 | + |
| 55 | + auto linesFut = GetInlineCrossline(ds); |
| 56 | + if (!linesFut.status().ok()) { |
| 57 | + std::cerr << "Failed to get inline and crossline coordinates: " << linesFut.status().message() << std::endl; |
| 58 | + return 1; |
| 59 | + } |
| 60 | + |
| 61 | + auto lines = linesFut.value(); |
| 62 | + auto il = lines.first.value(); |
| 63 | + auto xl = lines.second.value(); |
| 64 | + |
| 65 | + auto il_extents = GetExtents<mdio::dtypes::uint16_t>(il); |
| 66 | + auto xl_extents = GetExtents<mdio::dtypes::uint16_t>(xl); |
| 67 | + |
| 68 | + std::cout << "Inline extents: " << il_extents << std::endl; |
| 69 | + std::cout << "Crossline extents: " << xl_extents << std::endl; |
| 70 | + |
| 71 | + auto statsResult = stats::CalculateVolumeStatistics<mdio::dtypes::float32_t, mdio::dtypes::uint16_t>(ds); |
| 72 | + if (!statsResult.status().ok()) { |
| 73 | + std::cerr << "Failed to get volume statistics: " << statsResult.status().message() << std::endl; |
| 74 | + return 1; |
| 75 | + } |
| 76 | + |
| 77 | + auto stats = statsResult.value(); |
| 78 | + std::cout << stats << std::endl; |
| 79 | + |
| 80 | + // Now that we have the statistics, lets pinpoint where our peak and trough amplitudes are located on the world. |
| 81 | + mdio::ValueDescriptor<mdio::dtypes::uint16_t> il_peak = {"inline", stats.peak_amplitude_inline}; |
| 82 | + mdio::ValueDescriptor<mdio::dtypes::uint16_t> xl_peak = {"crossline", stats.peak_amplitude_crossline}; |
| 83 | + mdio::ValueDescriptor<mdio::dtypes::uint16_t> il_trough = {"inline", stats.trough_amplitude_inline}; |
| 84 | + mdio::ValueDescriptor<mdio::dtypes::uint16_t> xl_trough = {"crossline", stats.trough_amplitude_crossline}; |
| 85 | + |
| 86 | + auto peakSlicedDatasetRes = ds.sel(il_peak, xl_peak); |
| 87 | + if (!peakSlicedDatasetRes.status().ok()) { |
| 88 | + std::cerr << "Failed to slice dataset: " << peakSlicedDatasetRes.status().message() << std::endl; |
| 89 | + return 1; |
| 90 | + } |
| 91 | + |
| 92 | + auto peakSlicedDataset = peakSlicedDatasetRes.value(); |
| 93 | + // We can print the dataset and see that the inline and crossline indices are not the same as their values. |
| 94 | + // std::cout << "Peak sliced dataset: " << peakSlicedDataset << std::endl; |
| 95 | + |
| 96 | + // We can re-use the same function (and variable) to get the cdp coordinates of the peak amplitude now. |
| 97 | + cdpsFut = GetUTMCoords(peakSlicedDataset); |
| 98 | + if (!cdpsFut.status().ok()) { |
| 99 | + std::cerr << "Failed to get UTM coordinates of peak amplitude: " << cdpsFut.status().message() << std::endl; |
| 100 | + return 1; |
| 101 | + } |
| 102 | + |
| 103 | + cdps = cdpsFut.value(); |
| 104 | + cdp_x = cdps.first.value(); |
| 105 | + cdp_y = cdps.second.value(); |
| 106 | + cdp_x_extents = GetExtents<mdio::dtypes::float64_t>(cdp_x); |
| 107 | + cdp_y_extents = GetExtents<mdio::dtypes::float64_t>(cdp_y); |
| 108 | + |
| 109 | + std::cout << "========Peak Amplitude=========" << std::endl; |
| 110 | + utm::print_corners(cdp_x_extents, cdp_y_extents); |
| 111 | + utm::web_display(cdp_x_extents, cdp_y_extents); |
| 112 | + std::cout << std::endl; |
| 113 | + std::cout << "=================================" << std::endl << std::endl; |
| 114 | + |
| 115 | + auto troughSlicedDatasetRes = ds.sel(il_trough, xl_trough); |
| 116 | + if (!troughSlicedDatasetRes.status().ok()) { |
| 117 | + std::cerr << "Failed to slice dataset: " << troughSlicedDatasetRes.status().message() << std::endl; |
| 118 | + return 1; |
| 119 | + } |
| 120 | + |
| 121 | + auto troughSlicedDataset = troughSlicedDatasetRes.value(); |
| 122 | + // The trough sliced dataset should show a different inline/crossline index pair than the peak sliced dataset. |
| 123 | + // std::cout << "Trough sliced dataset: " << troughSlicedDataset << std::endl; |
| 124 | + |
| 125 | + cdpsFut = GetUTMCoords(troughSlicedDataset); |
| 126 | + if (!cdpsFut.status().ok()) { |
| 127 | + std::cerr << "Failed to get UTM coordinates of trough amplitude: " << cdpsFut.status().message() << std::endl; |
| 128 | + return 1; |
| 129 | + } |
| 130 | + |
| 131 | + cdps = cdpsFut.value(); |
| 132 | + cdp_x = cdps.first.value(); |
| 133 | + cdp_y = cdps.second.value(); |
| 134 | + cdp_x_extents = GetExtents<mdio::dtypes::float64_t>(cdp_x); |
| 135 | + cdp_y_extents = GetExtents<mdio::dtypes::float64_t>(cdp_y); |
| 136 | + |
| 137 | + std::cout << "========Trough Amplitude=========" << std::endl; |
| 138 | + utm::print_corners(cdp_x_extents, cdp_y_extents); |
| 139 | + std::cout << std::endl; |
| 140 | + utm::web_display(cdp_x_extents, cdp_y_extents); |
| 141 | + std::cout << std::endl; |
| 142 | + std::cout << "=================================" << std::endl << std::endl; |
| 143 | + return 0; |
| 144 | +} |
| 145 | + |
| 146 | + |
| 147 | +mdio::Future<mdio::Dataset> OpenDataset(const std::string& path, uint64_t cache_size_bytes) { |
| 148 | + auto cacheJson = nlohmann::json::parse(R"({"cache_pool": {"total_bytes_limit": 1073741824}})"); // 1GiB default cache size. |
| 149 | + cacheJson["cache_pool"]["total_bytes_limit"] = cache_size_bytes; |
| 150 | + auto spec = mdio::Context::Spec::FromJson(cacheJson); |
| 151 | + auto ctx = mdio::Context(spec.value()); |
| 152 | + return mdio::Dataset::Open(path, mdio::constants::kOpen, ctx); |
| 153 | +} |
| 154 | + |
| 155 | +mdio::Result<std::pair<mdio::Future<mdio::VariableData<mdio::dtypes::float64_t>>, mdio::Future<mdio::VariableData<mdio::dtypes::float64_t>>>> GetUTMCoords(mdio::Dataset& ds) { |
| 156 | + MDIO_ASSIGN_OR_RETURN(auto cdp_x, ds.variables.get<mdio::dtypes::float64_t>("cdp-x")); |
| 157 | + MDIO_ASSIGN_OR_RETURN(auto cdp_y, ds.variables.get<mdio::dtypes::float64_t>("cdp-y")); |
| 158 | + |
| 159 | + auto cdp_x_fut = cdp_x.Read(); |
| 160 | + auto cdp_y_fut = cdp_y.Read(); |
| 161 | + |
| 162 | + return std::make_pair(cdp_x_fut, cdp_y_fut); |
| 163 | +} |
| 164 | + |
| 165 | +mdio::Result<std::pair<mdio::Future<mdio::VariableData<mdio::dtypes::uint16_t>>, mdio::Future<mdio::VariableData<mdio::dtypes::uint16_t>>>> GetInlineCrossline(mdio::Dataset& ds) { |
| 166 | + MDIO_ASSIGN_OR_RETURN(auto il, ds.variables.get<mdio::dtypes::uint16_t>("inline")); |
| 167 | + MDIO_ASSIGN_OR_RETURN(auto xl, ds.variables.get<mdio::dtypes::uint16_t>("crossline")); |
| 168 | + |
| 169 | + auto il_fut = il.Read(); |
| 170 | + auto xl_fut = xl.Read(); |
| 171 | + |
| 172 | + return std::make_pair(il_fut, xl_fut); |
| 173 | +} |
0 commit comments