def test_metrics(self): f = _segyio.open(self.filename, "r") binary_header = _segyio.read_binaryheader(f) ilb = 189 xlb = 193 with self.assertRaises(TypeError): metrics = _segyio.init_metrics("?", binary_header, ilb, xlb) with self.assertRaises(TypeError): metrics = _segyio.init_metrics(f, "?", ilb, xlb) with self.assertRaises(IndexError): metrics = _segyio.init_metrics(f, binary_header, ilb + 1, xlb) metrics = _segyio.init_metrics(f, binary_header, ilb, xlb) self.assertEqual(metrics['iline_field'], ilb) self.assertEqual(metrics['xline_field'], xlb) self.assertEqual(metrics['trace0'], _segyio.textheader_size() + _segyio.binheader_size()) self.assertEqual(metrics['sample_count'], 50) self.assertEqual(metrics['format'], 1) self.assertEqual(metrics['trace_bsize'], 200) self.assertEqual(metrics['sorting'], 2) # inline sorting = 2, crossline sorting = 1 self.assertEqual(metrics['trace_count'], 25) self.assertEqual(metrics['offset_count'], 1) self.assertEqual(metrics['iline_count'], 5) self.assertEqual(metrics['xline_count'], 5) _segyio.close(f) with self.assertRaises(IOError): metrics = _segyio.init_metrics(f, binary_header, ilb, xlb)
def create(filename, spec): """Create a new segy file. Since v1.1 Unstructured file creation since v1.4 Create a new segy file with the geometry and properties given by `spec`. This enables creating SEGY files from your data. The created file supports all segyio modes, but has an emphasis on writing. The spec must be complete, otherwise an exception will be raised. A default, empty spec can be created with `segyio.spec()`. Very little data is written to the file, so just calling create is not sufficient to re-read the file with segyio. Rather, every trace header and trace must be written to for the file to be considered complete. Create should be used together with python's `with` statement. This ensure the data is written. Please refer to the examples. The `spec` is any object that has the following attributes: Mandatory: iline (int/segyio.BinField) xline (int/segyio.BinField) samples (array-like of int) format (int), 1 = IBM float, 5 = IEEE float Exclusive: ilines (array-like of int) xlines (array-like of int) offsets (array-like of int) sorting (int/segyio.TraceSortingFormat) OR tracecount (int) Optional: ext_headers (int) The `segyio.spec()` function will default offsets and everything in the mandatory group, except format and samples, and requires the caller to fill in *all* the fields in either of the exclusive groups. If any field is missing from the first exclusive group, and the tracecount is set, the resulting file will be considered unstructured. If the tracecount is set, and all fields of the first exclusive group are specified, the file is considered structured and the tracecount is inferred from the xlines/ilines/offsets. The offsets are defaulted to [1] by `segyio.spec()`. Args: filename (str): Path to file to open. spec (:obj: `spec`): Structure of the segy file. Examples: Create a file:: >>> spec = segyio.spec() >>> spec.ilines = [1, 2, 3, 4] >>> spec.xlines = [11, 12, 13] >>> spec.samples = list(range(50)) >>> spec.sorting = 2 >>> spec.format = 1 >>> with segyio.create(path, spec) as f: ... ## fill the file with data ... Copy a file, but shorten all traces by 50 samples:: >>> with segyio.open(srcpath) as src: ... spec = segyio.spec() ... spec.sorting = src.sorting ... spec.format = src.format ... spec.samples = src.samples[:len(src.samples) - 50] ... spec.ilines = src.ilines ... spec.xline = src.xlines ... with segyio.create(dstpath, spec) as dst: ... dst.text[0] = src.text[0] ... dst.bin = src.bin ... dst.header = src.header ... dst.trace = src.trace Copy a file, but shorten all traces by 50 samples (since v1.4):: >>> with segyio.open(srcpath) as src: ... spec = segyio.tools.metadata(src) ... spec.samples = spec.samples[:len(spec.samples) - 50] ... with segyio.create(dstpath, spec) as dst: ... dst.text[0] = src.text[0] ... dst.bin = src.bin ... dst.header = src.header ... dst.trace = src.trace :rtype: segyio.SegyFile """ f = segyio.SegyFile(filename, "w+") f._samples = numpy.asarray(spec.samples, dtype=numpy.single) f._ext_headers = spec.ext_headers if hasattr(spec, 'ext_headers') else 0 f._bsz = _segyio.trace_bsize(len(f.samples)) txt_hdr_sz = _segyio.textheader_size() bin_hdr_sz = _segyio.binheader_size() f._tr0 = txt_hdr_sz + bin_hdr_sz + (f.ext_headers * txt_hdr_sz) f._fmt = int(spec.format) f._il = int(spec.iline) f._xl = int(spec.xline) if not structured(spec): f._tracecount = spec.tracecount else: f._sorting = spec.sorting f._offsets = numpy.copy(numpy.asarray(spec.offsets, dtype=numpy.intc)) f._tracecount = len(spec.ilines) * len(spec.xlines) * len(spec.offsets) f._ilines = numpy.copy(numpy.asarray(spec.ilines, dtype=numpy.intc)) f._xlines = numpy.copy(numpy.asarray(spec.xlines, dtype=numpy.intc)) line_metrics = _segyio.init_line_metrics(f.sorting, f.tracecount, len(f.ilines), len(f.xlines), len(f.offsets)) f._iline_length = line_metrics['iline_length'] f._iline_stride = line_metrics['iline_stride'] f._xline_length = line_metrics['xline_length'] f._xline_stride = line_metrics['xline_stride'] f.text[0] = default_text_header(f._il, f._xl, segyio.TraceField.offset) f.bin = { 3213: f.tracecount, 3217: 4000, 3221: len(f.samples), 3225: f.format, 3505: f.ext_headers, } return f
def create(filename, spec): """Create a new segy file. Since v1.1 Create a new segy file with the geometry and properties given by `spec`. This enables creating SEGY files from your data. The created file supports all segyio modes, but has an emphasis on writing. The spec must be complete, otherwise an exception will be raised. A default, empty spec can be created with `segyio.spec()`. Very little data is written to the file, so just calling create is not sufficient to re-read the file with segyio. Rather, every trace header and trace must be written to for the file to be considered complete. Create should be used together with python's `with` statement. This ensure the data is written. Please refer to the examples. Args: filename (str): Path to file to open. spec (:obj: `spec`): Structure of the segy file. Examples: Create a file:: >>> spec = segyio.spec() >>> spec.ilines = [1, 2, 3, 4] >>> spec.xlines = [11, 12, 13] >>> spec.samples = list(range(50)) >>> spec.sorting = 2 >>> spec.format = 1 >>> with segyio.create(path, spec) as f: ... ## fill the file with data ... Copy a file, but shorten all traces by 50 samples:: >>> with segyio.open(srcpath) as src: ... spec = segyio.spec() ... spec.sorting = src.sorting ... spec.format = src.format ... spec.samples = src.samples[:len(src.samples) - 50] ... spec.ilines = src.ilines ... spec.xline = src.xlines ... with segyio.create(dstpath, spec) as dst: ... dst.text[0] = src.text[0] ... dst.bin = src.bin ... dst.header = src.header ... dst.trace = src.trace :rtype: segyio.SegyFile """ f = segyio.SegyFile(filename, "w+") f._samples = numpy.asarray(spec.samples, dtype=numpy.single) f._ext_headers = spec.ext_headers f._bsz = _segyio.trace_bsize(len(f.samples)) txt_hdr_sz = _segyio.textheader_size() bin_hdr_sz = _segyio.binheader_size() f._tr0 = txt_hdr_sz + bin_hdr_sz + (spec.ext_headers * txt_hdr_sz) f._sorting = spec.sorting f._fmt = int(spec.format) f._offsets = numpy.copy(numpy.asarray(spec.offsets, dtype=numpy.intc)) f._tracecount = len(spec.ilines) * len(spec.xlines) * len(spec.offsets) f._il = int(spec.iline) f._ilines = numpy.copy(numpy.asarray(spec.ilines, dtype=numpy.intc)) f._xl = int(spec.xline) f._xlines = numpy.copy(numpy.asarray(spec.xlines, dtype=numpy.intc)) line_metrics = _segyio.init_line_metrics(f.sorting, f.tracecount, len(f.ilines), len(f.xlines), len(f.offsets)) f._iline_length = line_metrics['iline_length'] f._iline_stride = line_metrics['iline_stride'] f._xline_length = line_metrics['xline_length'] f._xline_stride = line_metrics['xline_stride'] f.text[0] = default_text_header(f._il, f._xl, segyio.TraceField.offset) f.bin = { 3213: f.tracecount, 3217: 4000, 3221: len(f.samples), 3225: f.format, 3505: f.ext_headers, } return f
def test_binary_header_size(self): self.assertEqual(400, _segyio.binheader_size())