Skip to content

Commit e46bb1b

Browse files
committed
Use extension 1 in rotation calculations
1 parent c59003f commit e46bb1b

5 files changed

Lines changed: 144 additions & 17 deletions

File tree

lib/src/segy.c

Lines changed: 64 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3257,7 +3257,7 @@ static int scaled_standard_header_cdp(
32573257
const segy_entry_definition* map,
32583258
int cdp_offset,
32593259
int scalar_offset,
3260-
float* cdp
3260+
double* cdp
32613261
) {
32623262

32633263
segy_field_data fd = {0};
@@ -3294,39 +3294,86 @@ static int scaled_standard_header_cdp(
32943294
return SEGY_OK;
32953295
}
32963296

3297-
static int scaled_cdp(
3297+
static int scaled_ext1_header_cdp(
3298+
const char* header,
3299+
const segy_entry_definition* map,
3300+
int cdp_offset,
3301+
double* cdp
3302+
) {
3303+
3304+
segy_field_data fd = { 0 };
3305+
int err = segy_get_tracefield( header, map, cdp_offset, &fd );
3306+
if( err != SEGY_OK ) return err;
3307+
3308+
switch( fd.entry_type ) {
3309+
case SEGY_ENTRY_TYPE_IEEE64:
3310+
*cdp = fd.value.f64;
3311+
return SEGY_OK;
3312+
break;
3313+
default:
3314+
return SEGY_INVALID_FIELD_DATATYPE;
3315+
}
3316+
}
3317+
3318+
static int scaled_cdp_in_dimension(
32983319
segy_datasource* ds,
32993320
int traceno,
3300-
float* cdpx,
3301-
float* cdpy
3321+
int dimension_standard_name,
3322+
int dimension_ext1_name,
3323+
double* cdp
33023324
) {
33033325

33043326
char trheader[SEGY_TRACE_HEADER_SIZE];
33053327

3306-
int err = segy_read_standard_traceheader( ds, traceno, trheader );
3307-
if( err != 0 ) return err;
3328+
const segy_entry_definition* ext1_map =
3329+
ds->traceheader_mapping_extension1.offset_to_entry_definition;
3330+
const int cdp_ext1_offset =
3331+
ds->traceheader_mapping_extension1.name_to_offset[dimension_ext1_name];
3332+
3333+
if( ext1_map[cdp_ext1_offset - 1].entry_type != SEGY_ENTRY_TYPE_UNDEFINED ) {
3334+
int err = segy_read_traceheader( ds, traceno, 1, ext1_map, trheader );
3335+
if( err != SEGY_OK ) return err;
3336+
3337+
err = scaled_ext1_header_cdp(
3338+
trheader, ext1_map, cdp_ext1_offset, cdp
3339+
);
3340+
if( err != SEGY_OK ) return err;
3341+
if( *cdp != 0 || !ext1_map[cdp_ext1_offset - 1].requires_nonzero_value ) {
3342+
return SEGY_OK;
3343+
}
3344+
}
33083345

33093346
const segy_entry_definition* standard_map =
33103347
ds->traceheader_mapping_standard.offset_to_entry_definition;
33113348

3312-
const int cdp_x_offset =
3313-
ds->traceheader_mapping_standard.name_to_offset[SEGY_TR_CDP_X];
3314-
const int cdp_y_offset =
3315-
ds->traceheader_mapping_standard.name_to_offset[SEGY_TR_CDP_Y];
3349+
const int cdp_standard_offset =
3350+
ds->traceheader_mapping_standard.name_to_offset[dimension_standard_name];
33163351
const int scalar_offset =
33173352
ds->traceheader_mapping_standard.name_to_offset[SEGY_TR_SOURCE_GROUP_SCALAR];
33183353

3319-
err = scaled_standard_header_cdp(
3320-
trheader, standard_map, cdp_x_offset, scalar_offset, cdpx
3321-
);
3354+
int err = segy_read_standard_traceheader( ds, traceno, trheader );
33223355
if( err != SEGY_OK ) return err;
33233356

33243357
err = scaled_standard_header_cdp(
3325-
trheader, standard_map, cdp_y_offset, scalar_offset, cdpy
3358+
trheader, standard_map, cdp_standard_offset, scalar_offset, cdp
33263359
);
33273360
return err;
33283361
}
33293362

3363+
static int scaled_cdp(
3364+
segy_datasource* ds,
3365+
int traceno,
3366+
double* cdpx,
3367+
double* cdpy
3368+
) {
3369+
int err;
3370+
err = scaled_cdp_in_dimension( ds, traceno, SEGY_TR_CDP_X, SEGY_EXT1_CDP_X, cdpx );
3371+
if( err != SEGY_OK ) return err;
3372+
3373+
err = scaled_cdp_in_dimension( ds, traceno, SEGY_TR_CDP_Y, SEGY_EXT1_CDP_Y, cdpy );
3374+
return err;
3375+
}
3376+
33303377
int segy_rotation_cw( segy_datasource* ds,
33313378
int line_length,
33323379
int stride,
@@ -3335,7 +3382,7 @@ int segy_rotation_cw( segy_datasource* ds,
33353382
int linenos_sz,
33363383
float* rotation) {
33373384

3338-
struct coord { float x, y; } nw, sw;
3385+
struct coord { double x, y; } nw, sw;
33393386

33403387
int err;
33413388
int traceno;
@@ -3355,8 +3402,8 @@ int segy_rotation_cw( segy_datasource* ds,
33553402
err = scaled_cdp( ds, traceno, &nw.x, &nw.y );
33563403
if( err != 0 ) return err;
33573404

3358-
float x = nw.x - sw.x;
3359-
float y = nw.y - sw.y;
3405+
double x = nw.x - sw.x;
3406+
double y = nw.y - sw.y;
33603407
double radians = x || y ? atan2( x, y ) : 0;
33613408
if( radians < 0 ) radians += 2 * acos(-1);
33623409

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import sys
2+
import itertools as itr
3+
import segyio
4+
import segyio.su as su
5+
6+
7+
def product(f):
8+
return itr.product(range(len(f.ilines)), range(len(f.xlines)))
9+
10+
# this program turns the rev1 file into rev2 file with CDP values set to
11+
# different set of cdp-x and cdp-y coordinates in standard and ext1 headers.
12+
# The formulas are taken from make-rotated-copies.py script
13+
14+
def main():
15+
if len(sys.argv) != 3:
16+
sys.exit(
17+
"Usage: {} [source-file] [destination-file]".format(sys.argv[0]))
18+
19+
srcfile = sys.argv[1]
20+
dstfile = sys.argv[2] if len(sys.argv) > 2 else srcfile
21+
22+
with segyio.open(srcfile) as src:
23+
spec = segyio.spec()
24+
spec.format = int(src.format)
25+
spec.sorting = int(src.sorting)
26+
spec.samples = src.samples
27+
spec.ilines = src.ilines
28+
spec.xlines = src.xlines
29+
spec.traceheader_count = 2
30+
spec.tracecount = src.tracecount
31+
32+
with segyio.create(dstfile, spec) as dst:
33+
for i in range(1 + src.ext_headers):
34+
dst.text[i] = src.text[i]
35+
dst.bin = src.bin
36+
dst.trace = src.trace
37+
dst.traceheader = src.traceheader
38+
39+
dst.bin[segyio.BinField.SEGYRevision] = 2
40+
dst.bin[segyio.BinField.MaxAdditionalTraceHeaders] = 1
41+
42+
for i in range(src.tracecount):
43+
dst.traceheader[i][1].header_name = bytes("SEG00001", "ascii")
44+
45+
with segyio.open(dstfile, 'r+') as dst:
46+
for i, (x, y) in enumerate(product(src)):
47+
trh = dst.traceheader[i][0]
48+
# "right" rotation formula
49+
trh.cdp_x = y
50+
trh.cdp_y = 100 - x
51+
trh.co_scal = 1
52+
53+
trh = dst.traceheader[i][1]
54+
# "left" rotation formula
55+
trh.cdp_x = (100 - y) * 21
56+
trh.cdp_y = x * 21
57+
58+
59+
if __name__ == '__main__':
60+
main()

python/test/tools.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,20 @@ def test_rotation_lsb():
174174
assert rotation(msb, line = 'fast') == rotation(lsb, line = 'fast')
175175
assert rotation(msb, line = 'slow') == rotation(lsb, line = 'slow')
176176

177+
def test_rotation_ext1():
178+
# note that in the test file ext1 values are taken from "left" and standard
179+
# header values are taken from "right", yet the result does not correspond
180+
# to "left" results. This happens because some of the values in the ext1
181+
# header are 0 and 'use-if-non-zero' flag is set for ext1 header. So these
182+
# values fall down to 'right' standard header instead.
183+
#
184+
# While in reality it is likely that standard header would be 0-ed, for us
185+
# it is good opportunity to test 'use-if-non-zero' flag. It was checked that
186+
# test result values correspond with the mixed left-right picked data.
187+
with segyio.open(testdata / 'rotated-small-rev2.sgy') as f:
188+
assert 4.712 == approx(segyio.tools.rotation(f, line = 'fast')[0], abs = 1e-3)
189+
assert 3.142 == approx(segyio.tools.rotation(f, line = 'slow')[0], abs = 1e-3)
190+
177191
def test_metadata():
178192
spec = segyio.spec()
179193
spec.ilines = [1, 2, 3, 4, 5]

test-data/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@ To recreate:
5757
| left-small.sgy | 270° |
5858
| inv-acute-small.sgy | 315° |
5959

60+
File below is used to test revision 2 features and is created with:
61+
`python python/examples/make-rotated-rev2.py test-data/small.sgy test-data/rotated-small-rev2.sgy`
62+
63+
| File | Purpose |
64+
|------------------------|--------------------------------------------------------------------------- |
65+
| rotated-small-rev2.sgy | Revision 2 file with different values on standard and extension 1 headers. |
6066

6167
## Dimensions sorting test files
6268

test-data/rotated-small-rev2.sgy

20.1 KB
Binary file not shown.

0 commit comments

Comments
 (0)