22#ifndef NRLIB_SURFACEIO_HPP
23#define NRLIB_SURFACEIO_HPP
30 template <
class A>
class RegularSurface;
31 template <
class A>
class RegularSurfaceRotated;
32 template <
class A>
class Grid2D;
71 const std::vector<std::string> & labels);
98 namespace NRLibPrivate {
112#include "../exception/exception.hpp"
113#include "../math/constants.hpp"
114#include "../iotools/fileio.hpp"
115#include "../iotools/stringtools.hpp"
123 OpenRead(file, filename.c_str(), std::ios::in | std::ios::binary);
129 std::string token = ReadNext<std::string>(file, line);
130 if (token !=
"STORMGRID_BINARY") {
132 "in STORM binary format.");
135 int ni = ReadNext<int>(file, line);
136 int nj = ReadNext<int>(file, line);
137 double dx = ReadNext<double>(file, line);
138 double dy = ReadNext<double>(file, line);
139 double x_min = ReadNext<double>(file, line);
140 double x_max = ReadNext<double>(file, line);
141 double y_min = ReadNext<double>(file, line);
142 double y_max = ReadNext<double>(file, line);
144 double lx = x_max - x_min;
145 double ly = y_max - y_min;
170 " \"" + filename +
"\"");
174 "STORM surface file at line " +
ToString(line) +
":" +
e.what() +
"\n");
190 ReadNext<int>(file, line);
191 int nj = ReadNext<int>(file, line);
192 double dx = ReadNext<double>(file, line);
193 double dy = ReadNext<double>(file, line);
195 double x_min = ReadNext<double>(file, line);
196 double x_max = ReadNext<double>(file, line);
197 double y_min = ReadNext<double>(file, line);
198 double y_max = ReadNext<double>(file, line);
200 int ni = ReadNext<int>(file, line);
201 angle = ReadNext<double>(file, line);
202 angle = NRLib::Degree*angle;
203 ReadNext<double>(file, line);
204 ReadNext<double>(file, line);
206 ReadNext<int>(file, line);
207 ReadNext<int>(file, line);
208 ReadNext<int>(file, line);
209 ReadNext<int>(file, line);
210 ReadNext<int>(file, line);
211 ReadNext<int>(file, line);
212 ReadNext<int>(file, line);
215 double lx = (x_max - x_min)*cos(angle);
216 double ly = (y_max - y_min)*cos(angle);
220 std::string text =
"Inconsistent data in file. dx != lx/(nx-1).\n";
228 std::string text =
"Inconsistent data in file. dy != ly/(ny-1).\n";
252 " \"" + filename +
"\"");
256 "IRAP ASCII surface file at line " +
ToString(line) +
":" +
e.what() +
"\n");
266 std::ifstream header_file;
267 OpenRead(header_file, filename.c_str(), std::ios::in | std::ios::binary);
273 getline(header_file, tmp_str);
277 throw Exception(
"Wrong dimension of Sgri file. We expect a surface, dimension should be 2.\n");
279 getline(header_file, tmp_str);
281 std::vector<std::string> axis_labels(dim);
282 for (i=0; i<dim; i++)
283 getline(header_file, axis_labels[i]);
284 if (((axis_labels[0].find(
"X") == std::string::npos) && (axis_labels[0].find(
"x") == std::string::npos)) ||
285 ((axis_labels[1].find(
"Y") == std::string::npos) && (axis_labels[1].find(
"y") == std::string::npos)))
286 throw Exception(
"Wrong axis labels. First axis should be x-axis, second axis should be y-axis.\n");
289 getline(header_file, tmp_str);
294 header_file >> n_grid;
296 throw Exception(
"Error: Number of grids read from sgri file must be >0");
298 getline(header_file, tmp_str);
301 for (i=0; i<n_grid; i++)
302 getline(header_file, tmp_str);
304 std::vector<float> d_values1(dim);
305 std::vector<float> d_values2(dim);
306 std::vector<int> i_values(dim);
308 for (i=0; i<dim; i++)
309 header_file >> d_values1[i];
310 getline(header_file,tmp_str);
312 for (i=0; i<dim; i++)
313 header_file >> i_values[i];
314 getline(header_file,tmp_str);
316 for (i=0; i<dim; i++) {
317 header_file >> d_values2[i];
319 getline(header_file,tmp_str);
321 std::vector<float> min_values(dim);
322 for (i=0; i<dim; i++)
324 header_file >> min_values[i];
336 throw Exception(
"Error: Number of samples in X-dir must be >= 1.\n");
339 throw Exception(
"Error: Number of samples in Y-dir must be >= 1.\n");
343 throw Exception(
"Error: Grid sampling in X-dir must be > 0.0.\n");
347 throw Exception(
"Error: Grid sampling in Y-dir must be > 0.0.\n");
353 double x_min = min_values[0]-0.5*dx;
354 double y_min = min_values[1]-0.5*dy;
356 header_file >> angle;
358 surface.
Resize(nx, ny, 0.0);
361 getline(header_file, tmp_str);
364 header_file >> missing_code;
366 getline(header_file, tmp_str);
369 getline(header_file, tmp_str);
370 if (!tmp_str.empty()) {
374 while (!std::isspace(c,loc)) {
378 tmp_str.erase(tmp_str.begin()+i, tmp_str.end());
384 bin_file_name = path +
"/" + tmp_str;
388 header_file >> has_complex;
389 if (has_complex != 0 ) {
390 throw Exception(
"Error: Can not read Sgri binary file. Complex values?");
395 std::ifstream bin_file;
396 OpenRead(bin_file, bin_file_name, std::ios::in | std::ios::binary);
401 "Sgri surface file " +
e.what() +
"\n");
421 int header_start_line;
422 bool is_multicolumn_ascii =
false;
425 if (is_multicolumn_ascii ==
false)
426 throw Exception(
"Error: Did not recognize file as a multicolumns ascii file.\n");
432 for (
int i = 0; i < header_start_line; i++) {
437 std::vector<std::string> variable_names(5);
438 variable_names[0] = NRLib::ReadNext<std::string>(file, line);
439 variable_names[1] = NRLib::ReadNext<std::string>(file, line);
440 variable_names[2] = NRLib::ReadNext<std::string>(file, line);
441 variable_names[3] = NRLib::ReadNext<std::string>(file, line);
442 variable_names[4] = NRLib::ReadNext<std::string>(file, line);
444 std::vector<std::vector<double> >
data(5);
447 for (
int i = 0; i < 5; i++) {
448 data[i].push_back(NRLib::ReadNext<double>(file, line));
457 for (
int i = 0; i < 5; i++) {
458 if (variable_names[i] ==
"Inline" || variable_names[i] ==
"IL")
460 if (variable_names[i] ==
"Crossline" || variable_names[i] ==
"XL")
462 if (variable_names[i] ==
"X" || variable_names[i] ==
"UTMX")
464 if (variable_names[i] ==
"Y" || variable_names[i] ==
"UTMY")
466 if (variable_names[i] ==
"Attribute" || variable_names[i] ==
"Z" || variable_names[i] ==
"TWT")
472 err_txt +=
"Could not find variable name for Inline in file " + filename +
". (Tried Inline, IL).\n";
474 err_txt +=
"Could not find variable name for Crossline in file " + filename +
". (Tried Crossline, XL).\n";
476 err_txt +=
"Could not find variable name for X in file " + filename +
". (Tried X, UTMX).\n";
478 err_txt +=
"Could not find variable name for Y in file " + filename +
". (Tried Y, UTMY).\n";
480 err_txt +=
"Could not find variable name for Attribute in file " + filename +
". (Tried Attribute, Z, TWT).\n";
483 throw Exception(
"Error when finding header information in " + filename +
" :" + err_txt +
"\n");
485 std::vector<double> il_vec =
data[il_index];
486 std::vector<double> xl_vec =
data[xl_index];
487 std::vector<double> x_vec =
data[x_index];
488 std::vector<double> y_vec =
data[y_index];
489 std::vector<double> z_vec =
data[z_index];
492 std::vector<double> il_vec_sorted = il_vec;
493 std::sort(il_vec_sorted.begin(), il_vec_sorted.end());
494 il_vec_sorted.erase(std::unique(il_vec_sorted.begin(), il_vec_sorted.end()), il_vec_sorted.end());
496 std::vector<double> xl_vec_sorted = xl_vec;
497 std::sort(xl_vec_sorted.begin(), xl_vec_sorted.end());
498 xl_vec_sorted.erase(std::unique(xl_vec_sorted.begin(), xl_vec_sorted.end()), xl_vec_sorted.end());
500 int ni_file =
static_cast<int>(il_vec_sorted.size());
501 int nj_file =
static_cast<int>(xl_vec_sorted.size());
503 int il_min_file =
static_cast<int>(il_vec_sorted[0]);
504 int il_max_file =
static_cast<int>(il_vec_sorted[ni_file-1]);
506 int xl_min_file =
static_cast<int>(xl_vec_sorted[0]);
507 int xl_max_file =
static_cast<int>(xl_vec_sorted[nj_file-1]);
509 int n =
static_cast<int>(
data[0].size());
514 int d_il_file =
static_cast<int>((il_max_file - il_min_file) / (ni_file - 1));
515 int d_xl_file =
static_cast<int>((xl_max_file - xl_min_file) / (nj_file - 1));
517 for (
int k = 0; k < n; k++) {
519 int il_loc = (
static_cast<int>(
data[il_index][k]) - il_min_file)/d_il_file;
520 int xl_loc = (
static_cast<int>(
data[xl_index][k]) - xl_min_file)/d_xl_file;
522 ilxl_grid_file(il_loc, xl_loc) =
static_cast<A
>(
data[z_index][k]);
528 for (
int i = 0; i < ni_file; i++) {
529 if (ilxl_grid_file(i,nj_file/2) != missing) {
531 for (
int k = t1+1; k < ni_file; k++) {
532 if (ilxl_grid_file(k,nj_file/2) != missing) {
540 int diff_il = (t2 - t1)*d_il_file;
543 for (
int j = 0; j < nj_file; j++) {
544 if (ilxl_grid_file(ni_file/2,j) != missing) {
546 for (
int k = t1+1; k < nj_file; k++) {
547 if (ilxl_grid_file(ni_file/2,k) != missing) {
555 int diff_xl = (t2 - t1)*d_xl_file;
557 if (diff_il != d_il_file) {
558 err_txt +=
"Found sampling of IL-values to be " +
NRLib::ToString(d_il_file) +
559 ", but grid values are given with a IL-sampling of " +
NRLib::ToString(diff_il) +
".\n";
561 if (diff_xl != d_xl_file) {
562 err_txt +=
"Found sampling of XL-values to be " +
NRLib::ToString(d_xl_file) +
563 ", but grid values are given with a XL-sampling of " +
NRLib::ToString(diff_xl) +
".\n";
569 int il_min_segy = ilxl_area[0];
570 int il_max_segy = ilxl_area[1];
571 int xl_min_segy = ilxl_area[2];
572 int xl_max_segy = ilxl_area[3];
573 int il_step_segy = ilxl_area[4];
574 int xl_step_segy = ilxl_area[5];
577 int n_il = (il_max_segy - il_min_segy)/d_il_file + 1;
578 int n_xl = (xl_max_segy - xl_min_segy)/d_xl_file + 1;
581 int il0_segy =
static_cast<int>(il0_ref+0.5);
582 int xl0_segy =
static_cast<int>(xl0_ref+0.5);
585 if (il0_segy < il_min_segy)
586 il0_segy -= (il0_segy - il_min_segy) % il_step_segy;
587 else if (il0_segy > il_max_segy)
588 il0_segy += (il_max_segy - il0_segy) % il_step_segy;
590 if (xl0_segy < xl_min_segy)
591 xl0_segy -= (xl0_segy - xl_min_segy) % xl_step_segy;
592 else if (xl0_segy > xl_max_segy)
593 xl0_segy += (xl_max_segy - xl0_segy) % xl_step_segy;
597 for (
int i = 0; i < n_il; i++) {
598 for (
int j = 0; j < n_xl; j++) {
601 int il_glob = il_min_segy + i*d_il_file;
602 int xl_glob = xl_min_segy + j*d_xl_file;
605 int il_loc_file = (il_glob - il_min_file)/d_il_file;
606 int xl_loc_file = (xl_glob - xl_min_file)/d_xl_file;
610 if (il_loc_file < 0 || il_loc_file > ni_file-1 || xl_loc_file < 0 || xl_loc_file > nj_file-1)
613 z = ilxl_grid_file(il_loc_file, xl_loc_file);
616 if (il0_segy == il_min_segy && xl0_segy == xl_min_segy) {
620 else if (il0_segy == il_max_segy && xl0_segy == xl_max_segy) {
621 grid_i = n_il - i - 1;
622 grid_j = n_xl - j - 1;
624 else if (il0_segy == il_min_segy && xl0_segy == xl_max_segy) {
626 grid_j = n_xl - j - 1;
629 grid_i = n_il - i - 1;
633 surface_grid(grid_i, grid_j) =
z;
643 "Multicolumn ASCII file: \n" +
e.what() +
"\n");
658 << std::setprecision(6)
660 << surf.
GetNJ() <<
" "
661 << surf.
GetDX() <<
" "
662 << surf.
GetDY() <<
"\n"
663 << std::setprecision(2)
668 << surf.
GetNI() <<
" "
669 << std::setprecision(6)
670 << angle*180/NRLib::Pi <<
" "
671 << std::setprecision(2)
674 <<
" 0 0 0 0 0 0 0\n";
679 for (
size_t i = 0; i < surf.
GetN(); i++) {
680 file << surf(i) <<
" ";
686 for (
size_t i = 0; i < surf.
GetN(); i++) {
690 file << surf(i) <<
" ";
704 OpenWrite(file, filename.c_str(), std::ios::out | std::ios::binary);
708 file <<
"STORMGRID_BINARY\n\n"
710 << surf.
GetDX() <<
" " << surf.
GetDY() <<
"\n"
719 std::vector<double>
data(surf.
GetN());
const cJSON *const b
Definition: cJSON.h:251
char const int const cJSON_bool format
Definition: cJSON.h:161
const char *const string
Definition: cJSON.h:170
Definition: exception.hpp:80
Definition: exception.hpp:34
Definition: grid2d.hpp:32
size_t GetN() const
Definition: grid2d.hpp:63
iterator end()
Definition: grid2d.hpp:56
size_t GetNI() const
Definition: grid2d.hpp:61
iterator begin()
Definition: grid2d.hpp:55
size_t GetNJ() const
Definition: grid2d.hpp:62
Definition: regularsurface.hpp:39
bool IsMissing(A val) const
Check if grid value is missing.
Definition: regularsurface.hpp:203
double GetDX() const
Definition: regularsurface.hpp:191
void SetDimensions(double x_min, double y_min, double lx, double ly)
Definition: regularsurface.hpp:774
double GetXMin() const
Definition: regularsurface.hpp:187
double GetYMin() const
Definition: regularsurface.hpp:188
double GetDY() const
Definition: regularsurface.hpp:192
A GetMissingValue() const
Definition: regularsurface.hpp:222
void SetMissingValue(A missing_val)
Definition: regularsurface.hpp:223
double GetXMax() const
Definition: regularsurface.hpp:189
void Resize(size_t ni, size_t nj, const A &val=A())
Resize grid. Overrides Grid2D's resize.
Definition: regularsurface.hpp:789
double GetYMax() const
Definition: regularsurface.hpp:190
void SetName(const std::string &name)
Definition: regularsurface.hpp:226
bool Equal(double a, double b)
Definition: exception.hpp:31
std::string GetPath(const std::string &filename)
Get the path from a full file name.
I ReadBinaryFloatArray(std::istream &stream, I begin, size_t n, Endianess number_representation=END_BIG_ENDIAN)
Read an array of 4-byte floats on standard IEEE format.
Definition: fileio.hpp:688
void WriteIrapClassicAsciiSurf(const RegularSurface< A > &surf, double angle, const std::string &filename)
Definition: surfaceio.hpp:650
I ReadAsciiArrayFast(std::istream &stream, I begin, size_t n)
Gets sequence with elements of type T from input stream. Does no type checking, and does not count li...
Definition: fileio.hpp:481
const double STORM_MISSING
Definition: surfaceio.hpp:36
std::vector< RegularSurfaceRotated< float > > ReadMultipleSgriSurf(const std::string &filename, const std::vector< std::string > &labels)
void ReadIrapClassicAsciiSurf(const std::string &filename, RegularSurface< A > &surface, double &angle)
Definition: surfaceio.hpp:180
void ReadSgriSurf(const std::string &filename, RegularSurface< A > &surface, double &angle)
Definition: surfaceio.hpp:262
SurfaceFileFormat FindSurfaceFileType(const std::string &filename)
Find type of file.
std::string GetStem(const std::string &filename)
Get the stem of the filename (filename without path and extension)
void WriteStormBinarySurf(const RegularSurface< A > &surf, const std::string &filename)
Definition: surfaceio.hpp:700
I ReadBinaryDoubleArray(std::istream &stream, I begin, size_t n, Endianess number_representation=END_BIG_ENDIAN)
Read an array of 8-byte floats on standard IEEE format.
Definition: fileio.hpp:758
const double MULT_IRAP_MISSING
Definition: surfaceio.hpp:34
SurfaceFileFormat
Definition: surfaceio.hpp:38
@ SURF_STORM_BINARY
Definition: surfaceio.hpp:41
@ SURF_SGRI
Definition: surfaceio.hpp:42
@ SURF_RMS_POINTS_ASCII
Definition: surfaceio.hpp:43
@ SURF_UNKNOWN
Definition: surfaceio.hpp:39
@ SURF_IRAP_CLASSIC_ASCII
Definition: surfaceio.hpp:40
@ SURF_MULT_ASCII
Definition: surfaceio.hpp:44
void DiscardRestOfLine(std::istream &stream, int &line_num, bool throw_if_non_whitespace)
Reads and discard all characters until and including next newline.
bool FindMulticolumnAsciiLine(const std::string &filename, int &header_start_line)
void ReadMulticolumnAsciiSurf(std::string filename, RegularSurface< A > &surface, double x_ref, double y_ref, double lx, double ly, int *ilxl_area, double il0_ref, double xl0_ref)
Definition: surfaceio.hpp:406
std::string GetSurfFormatString(SurfaceFileFormat format)
String describing file format.
std::string ReplaceExtension(const std::string &filename, const std::string &extension)
Replace file extension.
bool CheckEndOfFile(std::istream &stream)
Check if end of file is reached. Discards all whitespace before end of file or next token.
void WriteBinaryDoubleArray(std::ostream &stream, I begin, I end, Endianess number_representation=END_BIG_ENDIAN)
Write an array of 8-byte floats on standard IEEE format.
Definition: fileio.hpp:726
void OpenWrite(std::ofstream &stream, const std::string &filename, std::ios_base::openmode mode=std::ios_base::out, bool create_dir=true)
Open file for writing.
const double IRAP_MISSING
Definition: surfaceio.hpp:35
void OpenRead(std::ifstream &stream, const std::string &filename, std::ios_base::openmode mode=std::ios_base::in)
Open file for reading.
std::string ToString(const T obj, int precision=-99999)
Definition: stringtools.hpp:177
void ReadStormBinarySurf(const std::string &filename, RegularSurface< A > &surface)
Definition: surfaceio.hpp:119
static const double e
Definition: exprtk.hpp:758
x y * z
Definition: exprtk.hpp:9663