Пример #1
0
 def depth(self, depth):
     "data of a depth slice"
     depth_idx = int((depth - self.startDepth) // self.stepDepth)
     with segyio.open(self.segy_file, 'r') as segyfile:
         segyfile.mmap()
         data = segyfile.depth_slice[depth_idx]
     return data
Пример #2
0
 def cdp(self, cdp):
     "data of a cdp"
     with segyio.open(self.segy_file, 'r') as segyfile:
         segyfile.mmap()
         data = segyfile.gather[cdp]
         data = data.reshape((data.shape[-1],))
     return data
Пример #3
0
    def _parse_segy(self):
        with segyio.open(self.segy_file, 'r') as segyfile:
            segyfile.mmap()
            self.startInline = segyfile.ilines[0]
            self.endInline = segyfile.ilines[-1]
            self.nEast = len(segyfile.ilines)
            self.stepInline = (self.endInline - self.startInline) // \
                (self.nEast - 1)
            self.startCrline = segyfile.xlines[0]
            self.endCrline = segyfile.xlines[-1]
            self.nNorth = len(segyfile.xlines)
            self.stepCrline = (self.endCrline - self.startCrline) // \
                (self.nNorth - 1)
            self.startDepth = segyfile.samples[0]
            self.endDepth = segyfile.samples[-1]
            self.nDepth = len(segyfile.samples)
            self.stepDepth = (self.endDepth - self.startDepth) // \
                (self.nDepth - 1)

            inline_A = self.startInline
            crline_A = self.startCrline
            index_A = 0
            x_A = segyfile.header[index_A][segyio.su.cdpx]
            y_A = segyfile.header[index_A][segyio.su.cdpy]

            inline_B = inline_A
            crline_B = self.startCrline + 2 * self.stepCrline
            index_B = 2
            x_B = segyfile.header[index_B][segyio.su.cdpx]
            y_B = segyfile.header[index_B][segyio.su.cdpy]

            inline_C = self.startInline + 2 * self.stepInline
            crline_C = crline_B
            index_C = 2 * self.nNorth + 2
            x_C = segyfile.header[index_C][segyio.su.cdpx]
            y_C = segyfile.header[index_C][segyio.su.cdpy]

            setting_dict = {
                "inline_range": [
                    self.startInline, self.endInline, self.stepInline],
                "crline_range": [
                    self.startCrline, self.endCrline, self.stepCrline],
                "z_range": [
                    self.startDepth, self.endDepth, self.stepDepth, "unknown"],
                "point_A": [inline_A, crline_A, x_A, y_A],
                "point_B": [inline_B, crline_B, x_B, y_B],
                "point_C": [inline_C, crline_C, x_C, y_C]
            }
            self.survey_setting = SurveySetting(ThreePoints(setting_dict))
Пример #4
0
    def test_header_dict_methods(self):
        with segyio.open(self.filename, "r") as f:
            self.assertEqual(89, len(list(f.header[0].keys())))
            self.assertEqual(89, len(list(f.header[1].values())))
            self.assertEqual(89, len(list(f.header[2].items())))
            self.assertEqual(89, len(list(f.header[3])))
            self.assertTrue(0 not in f.header[0])
            self.assertTrue(1 in f.header[0])
            self.assertTrue(segyio.su.cdpx in f.header[0])
            iter(f.header[0])

            self.assertEqual(30, len(f.bin.keys()))
            self.assertEqual(30, len(list(f.bin.values())))
            self.assertEqual(30, len(list(f.bin.items())))
            self.assertEqual(30, len(f.bin))
            iter(f.bin)
Пример #5
0
    def set_source_filename(self, filename, **kwargs):
        if filename:
            try:
                source = segyio.open(filename, "r", **kwargs)
            except:
                raise
            else:
                self._close_current_file()
                self._source = source
                self._source.mmap()
                samples = self._source.samples
        else:
            self._close_current_file()
            self._source = EmptyDataSource()

        self.slice_data_source_changed.emit()
Пример #6
0
def test_header_dict_methods():
    with segyio.open("test-data/small.sgy") as f:
        assert 89 == len(list(f.header[0].keys()))
        assert 89 == len(list(f.header[1].values()))
        assert 89 == len(list(f.header[2].items()))
        assert 89 == len(list(f.header[3]))
        assert 0 not in f.header[0]
        assert 1 in f.header[0]
        assert segyio.su.cdpx in f.header[0]
        iter(f.header[0])

        assert 30 == len(f.bin.keys())
        assert 30 == len(list(f.bin.values()))
        assert 30 == len(list(f.bin.items()))
        assert 30 == len(f.bin)
        iter(f.bin)
Пример #7
0
def test_traces_slicing():
    with segyio.open("test-data/small.sgy") as f:
        traces = list(map(np.copy, f.trace[0:6:2]))
        assert len(traces) == 3
        assert traces[0][49] == f.trace[0][49]
        assert traces[1][49] == f.trace[2][49]
        assert traces[2][49] == f.trace[4][49]

        rev_traces = list(map(np.copy, f.trace[4::-2]))
        assert rev_traces[0][49] == f.trace[4][49]
        assert rev_traces[1][49] == f.trace[2][49]
        assert rev_traces[2][49] == f.trace[0][49]

        # make sure buffers can be reused
        for i, trace in enumerate(f.trace[0:6:2]):
            assert np.array_equal(trace, traces[i])
Пример #8
0
def resample(segy, sample_rate=4, outpath=pathlib.Path.cwd()):
    '''Create a resample segy file (increase sampling rate)

    Creates a resampled segy file from an original segy. Note that the new
    sampling rate has to be a strict multiple of the original one.

    Parameters
    ----------
    segy : vmlib.seis.segy.io.Segy()
        instance of the source segyfile as loaded by vmlib.seis.segy.io
    sample_rate : float, optional
        destination sampling rate in milliseconds (defaults to 4 [ms])
    outpath : pathlib.Path, optional
        path to destination folder (defaults is pathlib.Path.cwd())

    Returns
    -------
    pathlib.Path
        path to the created, resampled, segy file

    Raises
    ------
    ValueError
        if the desired sample rate is not a strict multiple of the original one
    '''
    # Resolve destination file
    filename, extension = segy.info['filename'].split('.')
    destination = outpath.joinpath(f'{filename}_resample.{extension}')
    # Check new sampling rate
    if (sample_rate % segy.info['sample_rate']) == 0:
        ratio = int(sample_rate / segy.info['sample_rate'])
        # Process file
        with segyio.open(segy.info['file'], ignore_geometry=True) as src:
            spec = segyio.tools.metadata(src)
            spec.samples = spec.samples[:int(src.samples.size / ratio) - 1]
            with segyio.create(destination, spec) as dst:
                dst.text[0] = src.text[0]
                dst.bin = src.bin
                for ix, trace in enumerate(src.trace):
                    dst.trace[ix] = sps.resample(trace,
                                                 int(len(trace) / ratio))
                dst.bin.update(hdt=sample_rate * 1000)
                dst.bin.update(hns=len(spec.samples))
                dst.header = src.header
        return destination
    else:
        raise ValueError('Check sample rate to be multiple of the original')
Пример #9
0
def put_segy_texthead(segyfile,
                      ebcidc,
                      ext_headers=False,
                      line_counter=True,
                      **segyio_kwargs):

    header = ""
    if isinstance(ebcidc, dict):
        for key in ebcidc:
            if not isinstance(key, int):
                warn(
                    "ebcidc dict contains not integer keys that will be ignored",
                    UserWarning,
                )
        for line in range(1, 41):
            if line_counter:
                lc = f"C{line:02d} "
                n = 75
                content = "{:<76}"
            else:
                lc = ""
                n = 79
                content = "{:<80}"
            try:
                test = ebcidc[line]
                if len(test) > 75:
                    warn(f"EBCIDC line {line} is too long - truncating",
                         UserWarning)
                header = header + lc + content.format(ebcidc[line][:n])
            except KeyError:
                # line not specified in dictionary
                header = header + lc + " " * n
        header = bytes(header, "utf8")
    elif isinstance(ebcidc, bytes):
        if len(ebcidc) > 3200:
            warn("Byte EBCIDC is too large - truncating", UserWarning)
        header = ebcidc[:3200]
    elif isinstance(ebcidc, str):
        if len(ebcidc) > 3200:
            warn("String EBCIDC is too large - truncating", UserWarning)
        header = bytes(ebcidc[:3200], "utf8")
    else:
        raise ValueError("Unknown ebcidc type")

    segyio_kwargs["ignore_geometry"] = True
    with segyio.open(segyfile, "r+", **segyio_kwargs) as segyf:
        segyf.text[0] = header
Пример #10
0
def get_segy_texthead(segyfile,
                      ext_headers=False,
                      no_richstr=False,
                      **segyio_kwargs):
    """Return the ebcidc

    Args:
        segyfile (str): Segy File Path
        ext_headers (bool): Return EBCIDC and extended headers in list.
            Defaults to False
        no_richstr (bool, optional): Defaults to False. If true the returned string
            will not be updated for pretty HTML printing.
        segyio_kwargs: Key word arguments to pass to segyio.open
    Returns:
        str: Returns the EBCIDC text as a formatted paragraph.
    """

    with open(segyfile, mode="rb") as f:
        f.seek(0, 0)  # Locate our position to first byte of file
        data = f.read(3200)  # Read the first 3200 byte from our position

    if _isascii(data) and ext_headers == False:
        text = data.decode("ascii")  # EBCDIC encoding
        text = _text_fixes(text)
        text = segyio.tools.wrap(text)
    elif ext_headers == False:
        text = data.decode("cp500")  # text is ebcidc
        text = _text_fixes(text)
        text = segyio.tools.wrap(text)
    else:
        segyio_kwargs["ignore_geometry"] = True
        try:  # pray that the encoding is ebcidc
            with segyio.open(segyfile, "r", **segyio_kwargs) as segyf:
                text = segyf.text[0].decode("ascii", "replace")
                text = _text_fixes(text)
                text = segyio.tools.wrap(text)
                if segyf.ext_headers and ext_headers:
                    text2 = segyf.text[1].decode("ascii", "replace")
                    text = [text, text2]
        except UnicodeDecodeError as err:
            print(err)
            print("The segy text header could not be decoded.")

    if no_richstr:
        return text
    else:
        return _upgrade_txt_richstr(text)
Пример #11
0
def metadata(f):
    """Get survey structural properties and metadata

    Create a description object that, when passed to ``segyio.create()``, would
    create a new file with the same structure, dimensions, and metadata as
    ``f``.

    Takes an open segy file (created with segyio.open) or a file name.

    Parameters
    ----------

    f : str or segyio.SegyFile

    Returns
    -------
    spec : segyio.spec

    Notes
    -----

    .. versionadded:: 1.4

    """

    if not isinstance(f, segyio.SegyFile):
        with segyio.open(f) as fl:
            return metadata(fl)

    spec = segyio.spec()

    spec.iline = f._il
    spec.xline = f._xl
    spec.samples = f.samples
    spec.format = f.format

    spec.ilines = f.ilines
    spec.xlines = f.xlines
    spec.offsets = f.offsets
    spec.sorting = f.sorting

    spec.tracecount = f.tracecount

    spec.ext_headers = f.ext_headers
    spec.endian = f.endian

    return spec
Пример #12
0
    def test_create_from_naught_prestack(self):
        with TestContext("create_from_naught_prestack"):
            fname = "mk-ps.sgy"
            spec = segyio.spec()
            spec.format = 5
            spec.sorting = 2
            spec.samples = range(7)
            spec.ilines = range(1, 4)
            spec.xlines = range(1, 3)
            spec.offsets = range(1, 6)

            with segyio.create(fname, spec) as dst:
                arr = np.arange(start=0.000,
                                stop=0.007,
                                step=0.001,
                                dtype=np.single)

                arr = np.concatenate([[arr + 0.01], [arr + 0.02]], axis=0)
                lines = [arr + i for i in spec.ilines]
                cube = [(off * 100) + line for line in lines
                        for off in spec.offsets]

                dst.iline[:, :] = cube

                for of in spec.offsets:
                    for il in spec.ilines:
                        dst.header.iline[il, of] = {
                            TraceField.INLINE_3D: il,
                            TraceField.offset: of
                        }
                    for xl in spec.xlines:
                        dst.header.xline[xl, of] = {
                            TraceField.CROSSLINE_3D: xl
                        }

            with segyio.open(fname, "r") as f:
                self.assertAlmostEqual(101.010, f.trace[0][0], places=4)
                self.assertAlmostEqual(101.011, f.trace[0][1], places=4)
                self.assertAlmostEqual(101.016, f.trace[0][-1], places=4)
                self.assertAlmostEqual(503.025, f.trace[-1][5], places=4)
                self.assertNotEqual(f.header[0][TraceField.offset],
                                    f.header[1][TraceField.offset])
                self.assertEqual(1, f.header[0][TraceField.offset])
                self.assertEqual(2, f.header[1][TraceField.offset])

                for x, y in zip(f.iline[:, :], cube):
                    self.assertListEqual(list(x.flatten()), list(y.flatten()))
Пример #13
0
def test_attributes():
    with segyio.open("test-data/small.sgy") as f:
        il = TraceField.INLINE_3D
        xl = TraceField.CROSSLINE_3D

        assert 1 == f.attributes(il)[0]
        assert 20 == f.attributes(xl)[0]

        assert f.tracecount == len(f.attributes(il))
        assert iter(f.attributes(il))

        ils = [(i // 5) + 1 for i in range(25)]
        attrils = list(map(int, f.attributes(il)[:]))
        assert ils == attrils

        xls = [(i % 5) + 20 for i in range(25)]
        attrxls = list(map(int, f.attributes(xl)[:]))
        assert xls == attrxls

        ils = [(i // 5) + 1 for i in range(25)][::-1]
        attrils = list(map(int, f.attributes(il)[::-1]))
        assert ils == attrils

        xls = [(i % 5) + 20 for i in range(25)][::-1]
        attrxls = list(map(int, f.attributes(xl)[::-1]))
        assert xls == attrxls

        assert f.header[0][il] == f.attributes(il)[0]
        f.mmap()
        assert f.header[0][il] == f.attributes(il)[0]

        ils = [(i // 5) + 1 for i in range(25)][1:21:3]
        attrils = list(map(int, f.attributes(il)[1:21:3]))
        assert ils == attrils

        xls = [(i % 5) + 20 for i in range(25)][2:17:5]
        attrxls = list(map(int, f.attributes(xl)[2:17:5]))
        assert xls == attrxls

        ils = [1, 2, 3, 4, 5]
        attrils = list(map(int, f.attributes(il)[[0, 5, 11, 17, 23]]))
        assert ils == attrils

        ils = [1, 2, 3, 4, 5]
        indices = np.asarray([0, 5, 11, 17, 23])
        attrils = list(map(int, f.attributes(il)[indices]))
        assert ils == attrils
Пример #14
0
def _segy2d_xr(
    segyfile,
    ds,
    segyio_kwargs,
    n0,
    ns,
    head_df,
    head_loc,
    vert_domain="TWT",
    silent=False,
):
    """Helper function to load 2d data into an xarray with the seisnc form."""

    if vert_domain == "TWT":
        dims = DimensionKeyField.twod_twt
    elif vert_domain == "DEPTH":
        dims = DimensionKeyField.twod_depth
    else:
        raise ValueError(f"Unknown vert_domain: {vert_domain}")

    with segyio.open(segyfile, "r", **segyio_kwargs) as segyf:

        segyf.mmap()

        pb = tqdm(total=segyf.tracecount,
                  desc="Converting SEGY",
                  disable=silent,
                  **TQDM_ARGS)
        shape = [ds.dims[d] for d in dims]
        volume = np.zeros(shape, dtype=np.float32)
        percentiles = np.zeros_like(PERCENTILES)

        # this can probably be done as a block - leaving for now just incase sorting becomes an issue
        for trc, val in head_df.iterrows():
            volume[int(val.cdp_index), :] = segyf.trace[trc][n0:ns + 1]
            pb.update()
            percentiles = (np.percentile(segyf.trace[trc][n0:ns + 1],
                                         PERCENTILES) + percentiles) / 2.0
        pb.close()

    ds[VariableKeyField.data] = (
        dims,
        volume[:, n0:ns + 1],
    )
    ds.attrs[AttrKeyField.percentiles] = list(percentiles)

    return ds
Пример #15
0
def test_fopen_error():
    # non-existent file
    with pytest.raises(IOError):
        segyio.open("no_dir/no_file")

    # non-existant mode
    with pytest.raises(ValueError):
        segyio.open("test-data/small.sgy", "foo")

    with pytest.raises(ValueError):
        segyio.open("test-data/small.sgy", "r+b+toolong")
Пример #16
0
    def test_fopen_error(self):
        # non-existent file
        with self.assertRaises(IOError):
            segyio.open("no_dir/no_file", "r")

        # non-existant mode
        with self.assertRaises(ValueError):
            segyio.open(self.filename, "foo")

        with self.assertRaises(ValueError):
            segyio.open(self.filename, "r+b+toolong")
Пример #17
0
def learn5():
    path2 = 'E:/Research/data/F3_entire.segy'
    path3 = 'E:/Research/data/test1.segy'
    with segyio.open(path2) as src:
        spec = segyio.spec()
        spec.sorting = src.sorting
        spec.format = src.format
        spec.samples = src.samples
        spec.ilines = src.ilines
        spec.xlines = src.xlines
        spec.tracecount = src.tracecount
        print(len(src.samples))
        with segyio.create(path3, spec) as dst:
            dst.text[0] = src.text[0]
            dst.bin = src.bin
            dst.header = src.header
            dst.trace = src.trace
Пример #18
0
    def test_dt_fallback(self):
        with TestContext("dt_fallback") as context:
            context.copy_file(self.filename)
            with segyio.open("small.sgy", "r+") as f:
                # Both zero
                f.bin[BinField.Interval] = 0
                f.header[0][TraceField.TRACE_SAMPLE_INTERVAL] = 0
                f.flush()
                fallback_dt = 4
                np.testing.assert_almost_equal(segyio.dt(f, fallback_dt), fallback_dt)

                # dt in bin header different from first trace
                f.bin[BinField.Interval] = 6000
                f.header[0][TraceField.TRACE_SAMPLE_INTERVAL] = 1000
                f.flush()
                fallback_dt = 4
                np.testing.assert_almost_equal(segyio.dt(f, fallback_dt), fallback_dt)
Пример #19
0
def load_segy(fn_sgy, *args, **kwargs):
    """Load segy data.

    This is very generic for now, need to do work if there are particular
    types of segy files that need to be read. We cannot yet support a
    generic SEGY file, even if complies to some standard set.
    """
    if not SEGY:
        raise ImportError('Need segyio to load SGY files')
    segy_data = RadarData(None)
    segy_data.fn = fn_sgy
    f = segyio.open(fn_sgy, ignore_geometry=True)

    segy_data.data = segyio.tools.collect(f.trace).transpose()
    segy_data.snum = f.bin[segyio.BinField.Samples]
    segy_data.tnum = segy_data.data.shape[1]
    segy_data.dt = f.bin[segyio.BinField.Interval] * 1.0e-12
    segy_data.travel_time = np.arange(segy_data.snum) * segy_data.dt * 1.0e6
    segy_data.trace_num = np.arange(segy_data.data.shape[1]) + 1
    segy_data.flags = RadarFlags()
    # segy_data.travel_time = np.atleast_2d(np.arange(0,
    # segy_data.dt * segy_data.snum, segy_data.dt)).transpose()
    # + segy_data.dt

    # TODO  these next ones are filler
    # right now, they are selected so that they read in the delores data
    segy_data.trace_int = 1
    segy_data.chan = 1
    segy_data.trig = np.zeros((segy_data.tnum, ))
    segy_data.decday = np.zeros((segy_data.tnum, ))
    segy_data.x_coord = f.attributes(segyio.TraceField.CDP_X)[:] / 10.0
    segy_data.y_coord = f.attributes(segyio.TraceField.CDP_Y)[:] / 10.0
    segy_data.dist = np.hstack(
        ([0],
         np.cumsum(
             np.sqrt(
                 np.diff(segy_data.x_coord)**2.0 +
                 np.diff(segy_data.y_coord)**2.0)))) / 1000.
    segy_data.long = np.zeros((segy_data.tnum, ))
    segy_data.lat = np.zeros((segy_data.tnum, ))
    segy_data.elev = np.zeros((segy_data.tnum, ))
    segy_data.trig_level = np.zeros((segy_data.tnum, ))
    segy_data.pressure = np.zeros((segy_data.tnum, ))

    segy_data.check_attrs()
    return segy_data
Пример #20
0
def getFileInfo(dirName):
    """
    This function will read all of the *.segy or & *.sgy files in a given 
    directory. It returns a list with the file name and the shot location.
    This information will be passed to the GUI to display the file names. At
    a latter time it might be worth extracting other things from the headers
    and storing them in this list.
    
    DEPENDENCIES:
        GLOB - this is used to get the file names in the directory
        segyio - this is used to read the segy files and extract header info
    INPUTS:
        dirName (str) = this is a string to the directory that contains all of 
        the segy files from the survey.
    OUTPUTS:
        fileInfo is a list that is total Files by 2.
        Column 1 (str) = file name
        Column 2 (float) = shot location (units assumed to be m)
        
    NOTES:
        At this stage I use two if statemetns to check for segy files. If there
        are no segy files fileInfo will be an empty list and the user will get 
        an error. Though I am not sure where error goes in a GUI?
         - It depends, but we will be able to use try-except blocks for them
        
        It might be worth adding columns to this list if we need more info from
        the files later on
    """
    files = glb.glob(os.path.join(dirName, "*.sgy"))
    if files == []:
        files = glb.glob(os.path.join(dirName, "*.segy"))

    if files == []:
        print("No files with *.sgy or *.segy exist in this directory")
    # Column 1: File Name (str)
    # Column 2: SX (float)
    fileInfo = []

    for file in files:
        filename = os.path.basename(file)
        # print(filename)
        with segyio.open(file, strict=False) as f:
            shotLoc = f.header[0][segyio.TraceField.SourceX]
            # print(shotLoc)
        fileInfo.append([filename, shotLoc])
    return fileInfo
Пример #21
0
def test_depth_slice_writing(tmpdir):

    buf = np.empty(shape=(5, 5), dtype=np.single)

    def value(x, y):
        return x + (1.0 // 5) * y

    for x, y in itertools.product(range(5), range(5)):
        buf[x][y] = value(x, y)

    with segyio.open(tmpdir / "small.sgy", "r+") as f:
        f.depth_slice[7] = buf * 3.14  # assign to depth 7
        assert np.allclose(f.depth_slice[7], buf * 3.14)

        f.depth_slice = [buf * i for i in range(len(f.depth_slice))]  # assign to all depths
        for index, depth_slice in enumerate(f.depth_slice):
            assert np.allclose(depth_slice, buf * index)
Пример #22
0
 def btnArquivoPressed(self):
     options = QFileDialog.Options()
     #options |= QFileDialog.FileType("*.segy")
     fileName, _ = QFileDialog.getOpenFileName(
         self,
         "QFileDialog.getOpenFileName()",
         "",
         "Seg-Y (*.segy);; Seg-Y (*.sgy)",
         options=options)
     if fileName:
         self.txtArquivo.setText(fileName)
         sgy = segyio.open(self.txtArquivo.text(), ignore_geometry=True)
         Dx = np.array(sgy.trace)
         self.dado = Dx
         [self.nt, self.nr] = self.dado.shape
         self.txtNt.setText(str(self.nt))
         self.txtNr.setText(str(self.nr))
Пример #23
0
 def location(self):
     if self._data_type[0][-3: ] == 'bin':
         self._location['inline_start'] = self._data_type[2][0]
         self._location['xline_start'] = self._data_type[2][1]
         self._location['time_start'] = self._data_type[2][2]
         self._location['sample_interval'] = self._data_type[2][3]
         self.location_out = self._location
         pass
     elif self._data_type[0][-3: ] == 'sgy':
         with segyio.open(self._data_type[0]) as f:
             self._location['inline_start'] = f.ilines[0]
             self._location['xline_start'] = f.xlines[0]
             self._location['time_start'] = int(f.samples[0])
             self._location['sample_interval'] = int(f.samples[1] - f.samples[0])
             self.location_out = self._location
         pass
     return
Пример #24
0
def openSegy3D(filename):
  """
  Open 3D seismic volume in SEGY or SGY format 
  """
  import segyio

  try:
    with segyio.open(filename) as f:

      data = segyio.tools.cube(f)

      inlines = f.ilines
      crosslines = f.xlines
      twt = f.samples
      sample_rate = segyio.tools.dt(f) / 1000

      print('Successfully read \n')
      print('Inline range from', inlines[0], 'to', inlines[-1])
      print('Crossline range from', crosslines[0], 'to', crosslines[-1])
      print('TWT from', twt[0], 'to', twt[-1])   
      print('Sample rate:', sample_rate, 'ms')  

      try:
        rot, cdpx, cdpy = segyio.tools.rotation(f, line="fast")
        print('Survey rotation: {:.2f} deg'.format(rot))      
      except:
        print("Survey rotation not recognized")  

      cube = dict({"data": data,
                   "inlines": inlines,
                   "crosslines": crosslines,
                   "twt": twt,
                   "sample_rate": sample_rate})
      
      # See Stackoverflow: https://stackoverflow.com/questions/4984647/accessing-dict-keys-like-an-attribute
      class AttrDict(dict):
          def __init__(self, *args, **kwargs):
              super(AttrDict, self).__init__(*args, **kwargs)
              self.__dict__ = self  

      cube = AttrDict(cube)

  except:
    print("openSegy cannot read your data")  

  return cube 
Пример #25
0
def make_segy_index(filename, extra_headers=None, limits=None):
    """Index traces in a single SEGY file.

    Parameters
    ----------
    filename : str
        Path to SEGY file.
    extra_headers : array-like or str
        Additional headers to put unto DataFrme. If 'all', all headers are included.
    limits : slice or int, default to None
        If int, index only first ```limits``` traces. If slice, index only traces
        within given range. If None, index all traces.

    Returns
    -------
    df : pandas.DataFrame
        DataFrame with trace indexing.
    """
    if not isinstance(limits, slice):
        limits = slice(limits)

    with segyio.open(filename, strict=False) as segyfile:
        segyfile.mmap()
        if extra_headers == 'all':
            headers = [h.__str__() for h in segyio.TraceField.enums()]
        elif extra_headers is None:
            headers = DEFAULT_SEGY_HEADERS + SUPPORT_SEGY_HEADERS
        else:
            extra_headers = [extra_headers] if isinstance(
                extra_headers, str) else list(extra_headers)
            headers = set(DEFAULT_SEGY_HEADERS + extra_headers +
                          SUPPORT_SEGY_HEADERS)

        meta = dict()

        for k in headers:
            meta[k] = segyfile.attributes(getattr(segyio.TraceField,
                                                  k))[limits]

        meta['file_id'] = np.repeat(filename, segyfile.tracecount)[limits]
        meta['RecieverID'] = np.array(
            [hash(pair) for pair in zip(meta['GroupX'], meta['GroupY'])])

    df = pd.DataFrame(meta)
    return df
Пример #26
0
    def convert_segy_stream(self, bits_per_voxel, blockshape, reduce_iops=False):
        """Memory-efficient method of compressing SEG-Y file larger than machine memory.
        Requires at least n_crosslines x n_samples x blockshape[2] x 4 bytes of available memory"""
        t0 = time.time()

        if not os.path.exists(self.in_filename):
            msg = "With searching comes loss,  and the presence of absence:  'My Segy' not found."
            raise FileNotFoundError(msg)

        with segyio.open(self.in_filename, mode='r', strict=False) as segyfile:

            if self.geom is None:
                if segyfile.unstructured:
                    print("SEG-Y file is unstructured and no geometry provided. Determining this may take some time...")
                    traces_ref = {(h[189], h[193]): i for i, h in enumerate(segyfile.header)}
                    self.geom = InferredGeometry(traces_ref)
                    print("... inferred geometry is:", self.geom)
                else:
                    self.geom = Geometry(0, len(segyfile.ilines), 0, len(segyfile.xlines))
            n_traces = len(self.geom.ilines) * len(self.geom.xlines)
            inline_set_bytes = blockshape[0] * (len(self.geom.xlines) * len(segyfile.samples)) * 4

            headers_to_store = get_unique_headerwords(segyfile)
            numpy_headers_arrays = [np.zeros(n_traces, dtype=np.int32) for _ in range(len(headers_to_store))]

        if inline_set_bytes > virtual_memory().total // 2:
            print("One inline set is {} bytes, machine memory is {} bytes".format(inline_set_bytes, virtual_memory().total))
            print("Try using fewer inlines in the blockshape, or compressing a subcube")
            raise RuntimeError("ABORTED effort: Close all that you have. You ask way too much.")

        max_queue_length = min(16, (virtual_memory().total // 2) // inline_set_bytes)
        print("VirtualMemory={}MB, InlineSet={}MB : Using queue of length {}".format(virtual_memory().total/(1024*1024),
                                                                                     inline_set_bytes/(1024*1024),
                                                                                     max_queue_length))

        run_conversion_loop(self.in_filename, self.out_filename, bits_per_voxel, blockshape,
                            headers_to_store, numpy_headers_arrays, self.geom,
                            queuesize=max_queue_length, reduce_iops=reduce_iops)

        with open(self.out_filename, 'ab') as f:
            for header_array in numpy_headers_arrays:
                f.write(header_array.tobytes())

        t3 = time.time()
        print("Total conversion time: {}                     ".format(t3-t0))
Пример #27
0
    def _read_velocity(self, vcube, cell_corners):
        """
        Read velocity from segy file. Upscale.
        :param vcube:
        :param cell_corners:
        :return:
        """

        with segyio.open(vcube) as f:
            x = np.empty(f.tracecount, dtype=np.float64)
            y = np.empty(f.tracecount, dtype=np.float64)
            dt = segyio.dt(f) / 1e6
            nt = len(f.samples)

            for i, h in enumerate(f.header):
                scalar = h[TraceField.SourceGroupScalar]
                if scalar < 0:
                    scalar = -1.0 / scalar
                x[i] = h[TraceField.CDP_X] * scalar
                y[i] = h[TraceField.CDP_Y] * scalar

            ny = len(f.xlines)
            nx = len(f.ilines)

            # memory issue might happen if volume becomes too large
            traces = f.trace.raw[:]

            if f.sorting == segyio.TraceSortingFormat.INLINE_SORTING:
                x = x.reshape(ny, nx)
                y = y.reshape(ny, nx)
                traces = traces.reshape(ny, nx, nt)
                x = np.transpose(x)
                y = np.transpose(y)
                traces = np.transpose(traces, (1, 0, 2))
            elif f.sorting == segyio.TraceSortingFormat.CROSSLINE_SORTING:
                x = x.reshape(nx, ny)
                y = y.reshape(nx, ny)
                traces = traces.reshape(nx, ny, nt)
            else:
                raise RuntimeError

        x, y, traces, nt, dt = self._upscale_velocity(cell_corners, x, y,
                                                      traces, nt, dt)

        return x, y, traces, nt, dt
Пример #28
0
    def read_2Dmodel(self, path):
        """
        Build a 2D velocity model from a SEG-Y format.
        It uses the 'segyio' from https://github.com/equinor/segyio
        """
        with segyio.open(path, ignore_geometry=True) as f:
            n_samples = len(f.samples)
            n_traces = len(f.trace)
            data = np.zeros(shape=(n_samples, n_traces), dtype=np.float32)
            index = 0
            for trace in f.trace:
                data[:, index] = trace
                index += 1

            # data = 2d data
            # n_samples = height
            # n_traces = length
            self.model = data
Пример #29
0
    def test_open_fails_unstructured(self):
        with segyio.open(self.filename, "r", 37, strict=False) as f:
            with self.assertRaises(ValueError):
                f.iline[10]

            with self.assertRaises(ValueError):
                f.iline[:, :]

            with self.assertRaises(ValueError):
                f.xline[:, :]

            with self.assertRaises(ValueError):
                f.depth_slice[2]

            # operations that don't rely on geometry still works
            self.assertEqual(f.header[2][189], 1)
            self.assertListEqual(list(f.attributes(189)[:]),
                                 [(i // 5) + 1 for i in range(len(f.trace))])
Пример #30
0
    def test_traces_slicing(self):
        with segyio.open(self.filename, "r") as f:

            traces = list(map(np.copy, f.trace[0:6:2]))
            self.assertEqual(len(traces), 3)
            self.assertEqual(traces[0][49], f.trace[0][49])
            self.assertEqual(traces[1][49], f.trace[2][49])
            self.assertEqual(traces[2][49], f.trace[4][49])

            rev_traces = list(map(np.copy, f.trace[4::-2]))
            self.assertEqual(rev_traces[0][49], f.trace[4][49])
            self.assertEqual(rev_traces[1][49], f.trace[2][49])
            self.assertEqual(rev_traces[2][49], f.trace[0][49])

            # make sure buffers can be reused
            buf = None
            for i, trace in enumerate(f.trace[0:6:2, buf]):
                self.assertTrue(np.array_equal(trace, traces[i]))
Пример #31
0
def compress_and_compare_zgy(zgy_file, sgy_file, tmp_path, bits_per_voxel,
                             rtol):
    out_sgz = os.path.join(
        str(tmp_path), 'test_{}_{}_.sgz'.format(
            os.path.splitext(os.path.basename(zgy_file))[0], bits_per_voxel))

    with ZgyConverter(zgy_file) as converter:
        converter.run(out_sgz, bits_per_voxel=bits_per_voxel)

    with SgzReader(out_sgz) as reader:
        sgz_data = reader.read_volume()
        sgz_ilines = reader.ilines

    with segyio.open(sgy_file) as f:
        ref_ilines = f.ilines

    assert np.allclose(sgz_data, segyio.tools.cube(sgy_file), rtol=rtol)
    assert all([a == b for a, b in zip(sgz_ilines, ref_ilines)])
Пример #32
0
def main():
    if len(sys.argv) < 2:
        sys.exit("Usage: trace_headers_to_dataframe.py [file]")

    filename = sys.argv[1]

    # Open file
    with segyio.open(filename, ignore_geometry=True) as f:
        # Get all header keys:
        header_keys = segyio.tracefield.keys
        # Initialize df with trace id as index and headers as columns
        trace_headers = pd.DataFrame(index=range(1, f.tracecount + 1),
                                     columns=header_keys.keys())
        # Fill dataframe with all trace headers values
        for k, v in header_keys.items():
            trace_headers[k] = f.attributes(v)[:]

    print(trace_headers.head())
Пример #33
0
def test_open_fails_unstructured():
    with segyio.open("test-data/small.sgy", "r", 37, strict=False) as f:
        with pytest.raises(ValueError):
            _ = f.iline[10]

        with pytest.raises(ValueError):
            _ = f.iline[:, :]

        with pytest.raises(ValueError):
            _ = f.xline[:, :]

        with pytest.raises(ValueError):
            _ = f.depth_slice[2]

        # operations that don't rely on geometry still works
        assert f.header[2][189] == 1
        assert (list(f.attributes(189)[:]) ==
                [(i // 5) + 1 for i in range(len(f.trace))])
Пример #34
0
    def update(self, index, data):
        """
        Update data with ndarray

        Parameters
        ----------
        index : InlineIndex
        data : 2-d ndarray
            data for updating Inline
        """
        try:
            if not isinstance(index, InlineIndex):
                raise TypeError("has to be InlineIndex")
            if data.shape != (self.nNorth, self.nDepth):
                raise ValueError
            with segyio.open(self.segy_file, 'r+') as segyfile:
                segyfile.mmap()
                segyfile.iline[index.value] = data
        except Exception as er:
            print(er.message)
Пример #35
0
 def inline(self, inline):
     "data of a inline section"
     with segyio.open(self.segy_file, 'r') as segyfile:
         segyfile.mmap()
         data = segyfile.iline[inline]
     return data
Пример #36
0
 def crline(self, crline):
     "data of a crossline section"
     with segyio.open(self.segy_file, 'r') as segyfile:
         segyfile.mmap()
         data = segyfile.xline[crline]
     return data