{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "7ecb5319-8e20-4416-90a6-1551e1ca9355",
   "metadata": {
    "lines_to_next_cell": 0
   },
   "source": [
    "This tutorial deals with __creating a SEG-Y file (rev. 2) from scratch__. \n",
    "\n",
    "Let's start by importing some packages (including the seisio package itself) and setting up the logging config."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "100ed10e-d1ed-4d5a-ab62-a25999717503",
   "metadata": {},
   "outputs": [],
   "source": [
    "import logging\n",
    "import numpy as np\n",
    "\n",
    "import sys\n",
    "sys.path.insert(1, '../')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "b342cb54",
   "metadata": {},
   "outputs": [],
   "source": [
    "import seisio"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "e5eee723",
   "metadata": {},
   "outputs": [],
   "source": [
    "logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s', force=True)\n",
    "log = logging.getLogger(\"main\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e36474ac-a90e-4374-ad52-476976ef16fa",
   "metadata": {},
   "source": [
    "The following defines a Ricker function that simply creates a (possibly shifted) Ricker wavelet. We use that function to simulate our data set later on."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "b9657166",
   "metadata": {},
   "outputs": [],
   "source": [
    "def ricker(t, t0=0.0, fm=30.0):\n",
    "    \"\"\"\n",
    "    Zero-phase Ricker wavelet, possibly shifted in time.\n",
    "\n",
    "    Parameters\n",
    "    ----------\n",
    "    t: 1D numerical array\n",
    "        Time vector containing times in seconds.\n",
    "    t0: numerical scalar\n",
    "        Time shift in seconds. Peak of Ricker wavelet is positioned at t0.\n",
    "    fm: numerical scalar\n",
    "        Main frequency in Hertz.\n",
    "\n",
    "    Returns\n",
    "    -------\n",
    "    1D numerical array\n",
    "        The amplitude values of the Ricker wavelet corresponding to t.\n",
    "    \"\"\"\n",
    "    return (1-2*np.pi**2*fm**2*(t-t0)**2)*np.exp(-np.pi**2*fm**2*(t-t0)**2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "997e055e",
   "metadata": {},
   "source": [
    "Let's assume we have some high-resolution data with a large number of samples per trace that won't comply with SEGY rev. 0 or 1. We simulate\n",
    "the data by 10 traces, each trace containing a shifted Ricker wavelet of 5000 Hz):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "a1c2f0e7-a3e2-4be7-9a22-89276642c9eb",
   "metadata": {},
   "outputs": [],
   "source": [
    "nt = 10                                # number of traces\n",
    "ns = 80001                             # number of samples\n",
    "dt_micro = 0.1                         # sampling interval 0.1 microsec\n",
    "dt = dt_micro*1e-6                     # sampling interval in sec\n",
    "t = np.arange(0, (ns-1)*dt+dt/2, dt)   # time vector (for plotting only)\n",
    "fm = 5000                              # Ricker main frequency in Hertz\n",
    "\n",
    "data = np.zeros((nt, ns), dtype=np.float32)\n",
    "for i in np.arange(nt):\n",
    "    data[i, :] = ricker(t, t0=(i+1)*7000*dt, fm=fm)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cd54bb51",
   "metadata": {},
   "source": [
    "In each of the 10 traces, the ricker wavelet is shifted a little bit further in time.\n",
    "\n",
    "Now we create a SEG-Y output file follwing SEG-Y revision 2 standard, using IEEE floats as data format, and big-endian byte order. We encode the textual file header as 'EBCDIC', and for good measures we throw in two additional textual header records."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "2e782f25-1bf5-4532-b887-9a37455263e8",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO: Output file: data/SEGYrev2.sgy\n",
      "INFO: Output number of samples per data trace: 80001.\n",
      "INFO: Output data sample format: 4-byte IEEE floating-point.\n",
      "INFO: Output file endianess set to '>'.\n",
      "INFO: Number of additional textual header records: 2.\n",
      "INFO: Byte offset of first trace relative to start of file: 10000 bytes.\n",
      "INFO: Number of trailer stanza records: 0.\n",
      "INFO: SEG-Y trace header extension 1 is not present.\n",
      "INFO: Number of user-defined trace headers: 0\n",
      "INFO: Creating file according to SEG-Y rev. 2.0.\n"
     ]
    }
   ],
   "source": [
    "file = \"data/SEGYrev2.sgy\"\n",
    "\n",
    "out = seisio.output(file, ns=ns, vsi=dt_micro, endian=\">\", format=5, txtenc=\"ebcdic\", segymaj=2, ntxtrec=2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4a47ded4-6e3e-4996-96b1-c01b4c55dcec",
   "metadata": {},
   "source": [
    "Now we get a template for a primary SEG-Y textual file header and fill in the first line with some text. We pretty-print the textual header by simply logging it:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "100bf9bd",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO: Primary textual file header:\n",
      "INFO: -------- BEGIN --------\n",
      "C01 This is an exemplary textual file header.                                   \n",
      "C02                                                                             \n",
      "C03                                                                             \n",
      "C04                                                                             \n",
      "C05                                                                             \n",
      "C06                                                                             \n",
      "C07                                                                             \n",
      "C08                                                                             \n",
      "C09                                                                             \n",
      "C10                                                                             \n",
      "C11                                                                             \n",
      "C12                                                                             \n",
      "C13                                                                             \n",
      "C14                                                                             \n",
      "C15                                                                             \n",
      "C16                                                                             \n",
      "C17                                                                             \n",
      "C18                                                                             \n",
      "C19                                                                             \n",
      "C20                                                                             \n",
      "C21                                                                             \n",
      "C22                                                                             \n",
      "C23                                                                             \n",
      "C24                                                                             \n",
      "C25                                                                             \n",
      "C26                                                                             \n",
      "C27                                                                             \n",
      "C28                                                                             \n",
      "C29                                                                             \n",
      "C30                                                                             \n",
      "C31                                                                             \n",
      "C32                                                                             \n",
      "C33                                                                             \n",
      "C34                                                                             \n",
      "C35                                                                             \n",
      "C36                                                                             \n",
      "C37                                                                             \n",
      "C38                                                                             \n",
      "C39 SEG-Y_REV2.0                                                                \n",
      "C40 END TEXTUAL HEADER                                                          \n",
      "INFO: --------- END ---------\n"
     ]
    }
   ],
   "source": [
    "txthead = out.txthead_template\n",
    "txthead[0] = \"C01 This is an exemplary textual file header.\"\n",
    "out.log_txthead(txthead=txthead, info=\"Primary textual file header\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cd9e3fc1-ac16-4055-8a62-13e32e6d7a20",
   "metadata": {},
   "source": [
    "In a similar way, we can get a template for the SEG-Y binary file header, fill in some information, and pretty-print the header by simply logging it:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "f3c7c7b3",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO: SEG-Y binary file header:\n",
      "+----------+-----------------+----------------------------------------------------------+\n",
      "|          |           value | description                                              |\n",
      "|----------+-----------------+----------------------------------------------------------|\n",
      "| job      |     1           | Job identification number                                |\n",
      "| line     |    42           | Line number                                              |\n",
      "| nt       |    10           | Number of traces per ensemble                            |\n",
      "| format   |     5           | Data sample format code                                  |\n",
      "| ens      | 80001           | Extended number of samples per data trace                |\n",
      "| edt      |     0.1         | Extended sample interval (IEEE)                          |\n",
      "| iconst   |     1.69091e+07 | The integer constant 16909060_10 (01020304_16)           |\n",
      "| segymaj  |     2           | SEG-Y major format revision number                       |\n",
      "| fixed    |     1           | Fixed length trace flag                                  |\n",
      "| ntxthead |     2           | Number of 3200-byte extended textual file header records |\n",
      "| byteoff  | 10000           | Byte offset of first trace relative to start of file     |\n",
      "+----------+-----------------+----------------------------------------------------------+\n"
     ]
    }
   ],
   "source": [
    "binhead = out.binhead_template\n",
    "binhead[\"job\"] = 1\n",
    "binhead[\"line\"] = 42\n",
    "binhead[\"nt\"] = nt\n",
    "out.log_binhead(binhead=binhead)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "274a007a-ab09-4582-97b9-e21f7414d2c5",
   "metadata": {},
   "source": [
    "As can be seen, the `ns` entry is 0 (therefore not shown) and only the `ens` entry is set - that's because the number of samples is larger than what the `ns` binary header slot could store. The same holds, in principle, for the `dt` entry (only `edt` is present), as a sampling interval of 0.1 microseconds could not be stored in a previous SEG-Y revision.\n",
    "\n",
    "Let's create two additional SEG-Y header records which follow the binary file header; this is just an example. We could keep it short as seisio will pad the textual header to the required 3200 bytes as required, but we can also get a template and fill in some exemplary data that simulates typical data stored in such additional header records. We again pretty-print the header records by simplye logging them."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "0bd937da",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO: Additional textual header #1:\n",
      "INFO: -------- BEGIN --------\n",
      "(( OGP: P1/11 Data Geographic Extent ))                                         \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "...                                                                             \n",
      "INFO: --------- END ---------\n",
      "INFO: Additional textual header #2:\n",
      "INFO: -------- BEGIN --------\n",
      "(( Company XYZ: User-defined textual header ))                                  \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "                                                                                \n",
      "INFO: --------- END ---------\n"
     ]
    }
   ],
   "source": [
    "txtrec1 = out.txtrec_template\n",
    "txtrec1[0] = \"(( OGP: P1/11 Data Geographic Extent ))\"\n",
    "for i in range(1, len(txtrec1), 1):\n",
    "    txtrec1[i] = \"...\"  # fill in some \"...\" in each line\n",
    "out.log_txthead(txthead=txtrec1, info=\"Additional textual header #1\")\n",
    "# the second records is a single string which will automatically be padded\n",
    "txtrec2 = \"(( Company XYZ: User-defined textual header ))\"  \n",
    "out.log_txthead(txthead=txtrec2, info=\"Additional textual header #2\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "624072c9-ef7a-4d94-85be-e0354fa657a0",
   "metadata": {},
   "source": [
    "Obviously, we also need some trace headers for our data. So let's get a template for the trace headers and fill in some useful information:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "6bb460db",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create some trace headers for our data\n",
    "trchead = out.headers_template(nt=nt)\n",
    "trchead[\"tracl\"] = np.arange(1, nt+1/2, 1)\n",
    "trchead[\"cdp\"] = np.arange(1, nt+1/2, 1)\n",
    "trchead[\"trid\"] = 1\n",
    "trchead[\"duse\"] = 2\n",
    "dx = 0.01\n",
    "trchead[\"scalco\"] = -100\n",
    "trchead[\"sx\"] = trchead[\"gx\"] = 100*np.arange(0, (nt-1)*dx+dx/2, dx)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5440041f-da29-417e-a061-83bd9aea3514",
   "metadata": {},
   "source": [
    "The header mnemonics `ns` and `dt` cannot be set as the values would overflow but the flag indicating fixed trace lengths is set and the correct values are stored in the SEG-Y binary file header - these values then hold for all traces according to the SEG-Y standard. \n",
    "\n",
    "Let's log some statistics for our trace header table we have just created:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "07de63bf",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO: Summary of trace header statistics (zeros excluded):\n",
      "+--------+-------+-------+--------+---------+---------+---------+\n",
      "|        |   min |   max |   mean |     std |     25% |     75% |\n",
      "|--------+-------+-------+--------+---------+---------+---------|\n",
      "| tracl  |     1 |    10 |    5.5 | 3.02765 |    3.25 |    7.75 |\n",
      "| cdp    |     1 |    10 |    5.5 | 3.02765 |    3.25 |    7.75 |\n",
      "| trid   |     1 |     1 |    1   | 0       |    1    |    1    |\n",
      "| duse   |     2 |     2 |    2   | 0       |    2    |    2    |\n",
      "| scalco |  -100 |  -100 | -100   | 0       | -100    | -100    |\n",
      "| sx     |     0 |     9 |    4.5 | 3.02765 |    2.25 |    6.75 |\n",
      "| gx     |     0 |     9 |    4.5 | 3.02765 |    2.25 |    6.75 |\n",
      "+--------+-------+-------+--------+---------+---------+---------+\n"
     ]
    }
   ],
   "source": [
    "thstat = seisio.log_thstat(trchead)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dd96a35d-e601-450a-a664-5b76d441bdfc",
   "metadata": {},
   "source": [
    "Now let's write everything we have to disk in our output SEG-Y file:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "0ae0a764",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO: SEG-Y textual file header encoding set to 'EBCDIC'.\n",
      "INFO: SEG-Y ext. textual record 1 encoding set to 'EBCDIC'.\n",
      "INFO: SEG-Y ext. textual record 2 encoding set to 'EBCDIC'.\n",
      "INFO: Wrote textual and binary file headers and 2 add. header record(s).\n",
      "INFO: Swapping bytes of output data.\n",
      "INFO: Writing 10 trace(s) to disk...\n",
      "INFO: Finalizing output file and re-writing updated binary header.\n",
      "INFO: Wrote a total of 10 trace(s), file size: 3212440 bytes.\n"
     ]
    }
   ],
   "source": [
    "out.init(textual=txthead, binary=binhead, records=[txtrec1, txtrec2])\n",
    "out.write_traces(data=data, headers=trchead)\n",
    "out.finalize()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c3adb119-a265-4e05-a007-745e65939896",
   "metadata": {},
   "source": [
    "At this point, we have created a SEG-Y rev. 2 data file with 10 traces."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e9178fe3-c1e9-49ad-8570-d2439baac499",
   "metadata": {},
   "source": [
    "As a cross-check, let's try to use the __segyio__ package (if installed) to read the file back. We then plot the original data and the data read back by segyio to see whether they match. We also log the trace headers read by segyio:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "4a13b818-b59c-4ee7-93a5-10e749f8a85e",
   "metadata": {},
   "outputs": [],
   "source": [
    "try:\n",
    "    import pandas as pd\n",
    "    import segyio\n",
    "    from tabulate import tabulate\n",
    "    import matplotlib.pyplot as plt\n",
    "except ImportError:\n",
    "    log.warning(\"Cannot run consistency check.\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "65051d2e-8c8f-4196-96e3-88512ae69558",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO: SEGYIO textual file header:\n",
      "C01 This is an exemplary textual file header.\n",
      "C02\n",
      "C03\n",
      "C04\n",
      "C05\n",
      "C06\n",
      "C07\n",
      "C08\n",
      "C09\n",
      "C10\n",
      "C11\n",
      "C12\n",
      "C13\n",
      "C14\n",
      "C15\n",
      "C16\n",
      "C17\n",
      "C18\n",
      "C19\n",
      "C20\n",
      "C21\n",
      "C22\n",
      "C23\n",
      "C24\n",
      "C25\n",
      "C26\n",
      "C27\n",
      "C28\n",
      "C29\n",
      "C30\n",
      "C31\n",
      "C32\n",
      "C33\n",
      "C34\n",
      "C35\n",
      "C36\n",
      "C37\n",
      "C38\n",
      "C39 SEG-Y_REV2.0\n",
      "C40 END TEXTUAL HEADER\n",
      "INFO: SEGYIO number of extended headers: 2\n",
      "INFO: SEGYIO add. textual file header #1:\n",
      "(( OGP: P1/11 Data Geographic Extent ))\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "...\n",
      "INFO: SEGYIO add. textual file header #2:\n",
      "(( Company XYZ: User-defined textual header ))\n",
      "INFO: SEGYIO binary header:\n",
      "{JobID: 1, LineNumber: 42, ReelNumber: 0, Traces: 10, AuxTraces: 0, Interval: 0, IntervalOriginal: 0, Samples: 0, SamplesOriginal: 0, Format: 5, EnsembleFold: 0, SortingCode: 0, VerticalSum: 0, SweepFrequencyStart: 0, SweepFrequencyEnd: 0, SweepLength: 0, Sweep: 0, SweepChannel: 0, SweepTaperStart: 0, SweepTaperEnd: 0, Taper: 0, CorrelatedTraces: 0, BinaryGainRecovery: 0, AmplitudeRecovery: 0, MeasurementSystem: 0, ImpulseSignalPolarity: 0, VibratoryPolarity: 0, ExtAuxTraces: 0, ExtSamples: 80001, ExtSamplesOriginal: 0, ExtEnsembleFold: 0, SEGYRevision: 2, SEGYRevisionMinor: 0, TraceFlag: 1, ExtendedHeaders: 2}\n",
      "INFO: SEGYIO number of traces: 10\n",
      "INFO: SEGYIO number of samples: 80001\n",
      "INFO: SEGYIO trace headers:\n",
      "+----------------------------------------+------+------+------+------+------+------+------+------+------+------+\n",
      "|                                        |    1 |    2 |    3 |    4 |    5 |    6 |    7 |    8 |    9 |   10 |\n",
      "|----------------------------------------+------+------+------+------+------+------+------+------+------+------|\n",
      "| TRACE_SEQUENCE_LINE                    |    1 |    2 |    3 |    4 |    5 |    6 |    7 |    8 |    9 |   10 |\n",
      "| TRACE_SEQUENCE_FILE                    |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| FieldRecord                            |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| TraceNumber                            |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| EnergySourcePoint                      |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| CDP                                    |    1 |    2 |    3 |    4 |    5 |    6 |    7 |    8 |    9 |   10 |\n",
      "| CDP_TRACE                              |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| TraceIdentificationCode                |    1 |    1 |    1 |    1 |    1 |    1 |    1 |    1 |    1 |    1 |\n",
      "| NSummedTraces                          |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| NStackedTraces                         |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| DataUse                                |    2 |    2 |    2 |    2 |    2 |    2 |    2 |    2 |    2 |    2 |\n",
      "| offset                                 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| ReceiverGroupElevation                 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| SourceSurfaceElevation                 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| SourceDepth                            |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| ReceiverDatumElevation                 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| SourceDatumElevation                   |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| SourceWaterDepth                       |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| GroupWaterDepth                        |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| ElevationScalar                        |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| SourceGroupScalar                      | -100 | -100 | -100 | -100 | -100 | -100 | -100 | -100 | -100 | -100 |\n",
      "| SourceX                                |    0 |    1 |    2 |    3 |    4 |    5 |    6 |    7 |    8 |    9 |\n",
      "| SourceY                                |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| GroupX                                 |    0 |    1 |    2 |    3 |    4 |    5 |    6 |    7 |    8 |    9 |\n",
      "| GroupY                                 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| CoordinateUnits                        |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| WeatheringVelocity                     |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| SubWeatheringVelocity                  |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| SourceUpholeTime                       |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| GroupUpholeTime                        |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| SourceStaticCorrection                 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| GroupStaticCorrection                  |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| TotalStaticApplied                     |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| LagTimeA                               |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| LagTimeB                               |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| DelayRecordingTime                     |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| MuteTimeStart                          |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| MuteTimeEND                            |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| TRACE_SAMPLE_COUNT                     |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| TRACE_SAMPLE_INTERVAL                  |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| GainType                               |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| InstrumentGainConstant                 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| InstrumentInitialGain                  |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| Correlated                             |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| SweepFrequencyStart                    |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| SweepFrequencyEnd                      |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| SweepLength                            |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| SweepType                              |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| SweepTraceTaperLengthStart             |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| SweepTraceTaperLengthEnd               |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| TaperType                              |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| AliasFilterFrequency                   |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| AliasFilterSlope                       |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| NotchFilterFrequency                   |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| NotchFilterSlope                       |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| LowCutFrequency                        |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| HighCutFrequency                       |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| LowCutSlope                            |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| HighCutSlope                           |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| YearDataRecorded                       |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| DayOfYear                              |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| HourOfDay                              |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| MinuteOfHour                           |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| SecondOfMinute                         |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| TimeBaseCode                           |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| TraceWeightingFactor                   |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| GeophoneGroupNumberRoll1               |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| GeophoneGroupNumberFirstTraceOrigField |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| GeophoneGroupNumberLastTraceOrigField  |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| GapSize                                |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| OverTravel                             |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| CDP_X                                  |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| CDP_Y                                  |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| INLINE_3D                              |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| CROSSLINE_3D                           |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| ShotPoint                              |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| ShotPointScalar                        |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| TraceValueMeasurementUnit              |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| TransductionConstantMantissa           |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| TransductionConstantPower              |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| TransductionUnit                       |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| TraceIdentifier                        |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| ScalarTraceHeader                      |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| SourceType                             |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| SourceEnergyDirectionMantissa          |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| SourceEnergyDirectionExponent          |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| SourceMeasurementMantissa              |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| SourceMeasurementExponent              |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| SourceMeasurementUnit                  |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| UnassignedInt1                         |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "| UnassignedInt2                         |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |\n",
      "+----------------------------------------+------+------+------+------+------+------+------+------+------+------+\n"
     ]
    }
   ],
   "source": [
    "with segyio.open(file, strict=False) as segyfile:\n",
    "    log.info(\"SEGYIO textual file header:\\n%s\",\n",
    "             segyio.tools.wrap(segyfile.text[0].decode('ascii'), 80))\n",
    "    log.info(\"SEGYIO number of extended headers: %d\", segyfile.ext_headers)\n",
    "    for i in range(segyfile.ext_headers):\n",
    "        log.info(\"SEGYIO add. textual file header #%d:\\n%s\", i+1,\n",
    "                 segyio.tools.wrap(segyfile.text[i+1].decode('ascii'), 80))\n",
    "    log.info(\"SEGYIO binary header:\\n%s\", segyfile.bin)\n",
    "    log.info(\"SEGYIO number of traces: %d\", len(segyfile.trace))\n",
    "    log.info(\"SEGYIO number of samples: %d\", segyfile.samples.size)\n",
    "\n",
    "    header_keys = segyio.tracefield.keys\n",
    "    trace_headers = pd.DataFrame(index=range(1, segyfile.tracecount+1), columns=header_keys.keys())\n",
    "    for k, v in header_keys.items():\n",
    "        trace_headers[k] = segyfile.attributes(v)[:]\n",
    "\n",
    "    log.info(\"%s\\n%s\", \"SEGYIO trace headers:\", tabulate(trace_headers.T, headers=\"keys\", tablefmt=\"psql\"))\n",
    "\n",
    "    segydata = segyfile.trace.raw[:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "b6143bd9-cb86-4f5b-adec-5ad74e820a0b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 70696 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots(1, 1)\n",
    "\n",
    "for i in range(segyfile.tracecount):\n",
    "    msg = \"Original data\" if i == 0 else \"_ignored\"\n",
    "    ax.plot(i+data[i, :], np.arange(0, (ns-1)*dt+dt/2, dt), 'k-', label=msg)\n",
    "    msg = \"Written by seisio, read by segyio\" if i == 0 else \"_ignored\"\n",
    "    ax.plot(i+segydata[i, :], np.arange(0, (ns-1)*dt+dt/2, dt), 'r--', label=msg)\n",
    "\n",
    "ax.invert_yaxis()\n",
    "ax.legend()\n",
    "ax.set_title(\"Data comparison\")\n",
    "ax.set_xlabel(\"Trace number\")\n",
    "ax.set_ylabel(\"Time in s\")\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "01da9f0b-8486-4490-a43e-9dedd2976269",
   "metadata": {},
   "source": [
    "Note: We provide another Python package called __seisplot__ for displaying seismic data in a convenient way."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a128204f-087d-4574-af8d-21025f88b0b8",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "jupytext": {
   "cell_metadata_filter": "-all",
   "executable": "/usr/bin/env python3",
   "main_language": "python",
   "notebook_metadata_filter": "-all"
  },
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.19"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
