{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "c8cb71ee-5811-4189-b675-d013ffe31365",
   "metadata": {
    "lines_to_next_cell": 0
   },
   "source": [
    "This tutorial deals with __reading a SEG2 file__. \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": "6ddae925-e467-4a99-8917-3db6ef66c9c1",
   "metadata": {},
   "outputs": [],
   "source": [
    "import logging\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "\n",
    "import sys\n",
    "sys.path.insert(1, '../')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "8887b5b3",
   "metadata": {},
   "outputs": [],
   "source": [
    "import seisio"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "ef33d394",
   "metadata": {},
   "outputs": [],
   "source": [
    "logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s', force=True)\n",
    "log = logging.getLogger(\"main\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "68f98349-8d42-432b-a88b-ab5608d9a7cf",
   "metadata": {},
   "source": [
    "Let's create the seisio object. Under ideal circumstances, the module can determine all relevant parameters automatically to read the file correctly:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "c06a7da3-4583-4170-a763-a9e5d9811cd3",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO: Input file: data/shot1.seg2\n",
      "INFO: Valid SEG2 file descriptor found. File endianess: '<'.\n",
      "INFO: File standard is SEG2 rev. 1.\n",
      "INFO: Number of data traces in file: 48.\n",
      "WARNING: Unknown string 'SERIAL_STRING' found in free format section.\n",
      "WARNING: Value associated with this key: .\n",
      "INFO: Valid SEG2 trace descriptor found on first trace.\n",
      "INFO: Number of samples on first data trace: 1000.\n",
      "INFO: Data sample format: 4-byte IEEE floating-point.\n"
     ]
    }
   ],
   "source": [
    "file = \"data/shot1.seg2\"\n",
    "\n",
    "sio = seisio.input(file)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "9a999cad",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO: nt=48, ns=1000, dt on first trace=2.500000e-04\n"
     ]
    }
   ],
   "source": [
    "nt = sio.ntraces\n",
    "ns = sio.nsamples\n",
    "dt = sio.vsi\n",
    "log.info(\"nt=%d, ns=%d, dt on first trace=%e\", nt, ns, dt)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8dfeaddb-65b3-478c-a45d-34d39b11a119",
   "metadata": {},
   "source": [
    "Let's get the strings from the SEG2 file header block:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "83b3d982-53d7-49db-8916-224e69298a28",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO: File header: string='ACQUISITION_DATE', value='04/May/2023'\n",
      "INFO: File header: string='ACQUISITION_TIME', value='13:24:32'\n",
      "INFO: File header: string='COMPANY', value='Geometrics'\n",
      "INFO: File header: string='INSTRUMENT', value='GEOMETRICS SEISMODULES CONTROLLER 0000'\n",
      "INFO: File header: string='JOB_ID', value='0000'\n",
      "INFO: File header: string='OBSERVER', value='Observer'\n",
      "INFO: File header: string='SERIAL_STRING', value=''\n",
      "INFO: File header: string='TRACE_SORT', value='AS_ACQUIRED'\n",
      "INFO: File header: string='UNITS', value='METERS'\n",
      "INFO: File header 'NOTE' entry #0: BASE_INTERVAL 1.00\n",
      "INFO: File header 'NOTE' entry #1: SHOT_INCREMENT 0.00\n",
      "INFO: File header 'NOTE' entry #2: PHONE_INCREMENT 0.00\n",
      "INFO: File header 'NOTE' entry #3: AGC_WINDOW 0\n",
      "INFO: File header 'NOTE' entry #4: DISPLAY_FILTERS 0 0\n"
     ]
    }
   ],
   "source": [
    "fheader = sio.fheader\n",
    "for key in fheader:\n",
    "    if key == \"NOTE\":\n",
    "        for i, k in enumerate(fheader[key]):\n",
    "            log.info(\"File header 'NOTE' entry #%d: %s\", i, k)\n",
    "    else:\n",
    "        log.info(\"File header: string='%s', value='%s'\", key, fheader[key])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1003e324-c8d9-4767-9079-4056072f4e86",
   "metadata": {},
   "source": [
    "This SEG2 file was recorded as part of a little near-surface field experiment, using a Geometrics Geode (48 channel recording system) and the corresponding recording software.\n",
    "\n",
    "Let's log the trace header strings found in the data file:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "f5940393-0482-4b49-8e78-9f09ceb5a534",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO: Trace header definition:\n",
      "+----------------------------+-------+--------+------------------------------------------------+\n",
      "|                            |   no. | type   | description                                    |\n",
      "|----------------------------+-------+--------+------------------------------------------------|\n",
      "| ALIAS_FILTER               |     0 | str    | Anti-aliasing filter specs                     |\n",
      "| AMPLITUDE_RECOVERY         |     1 | str    | Amplitude recovery method                      |\n",
      "| BAND_REJECT_FILTER         |     2 | str    | Acquisition band-rejection filter specs        |\n",
      "| CDP_NUMBER                 |     3 | str    | CDP number                                     |\n",
      "| CDP_TRACE                  |     4 | str    | Trace number within CDP                        |\n",
      "| CHANNEL_NUMBER             |     5 | str    | Channel number                                 |\n",
      "| DATUM                      |     6 | str    | Datum (elevation)                              |\n",
      "| DELAY                      |     7 | str    | Delay recording time                           |\n",
      "| DESCALING_FACTOR           |     8 | str    | Descaling factor                               |\n",
      "| DIGITAL_BAND_REJECT_FILTER |     9 | str    | Processing digital band-rejection filter specs |\n",
      "| DIGITAL_HIGH_CUT_FILTER    |    10 | str    | Processing digital high-cut filter specs       |\n",
      "| DIGITAL_LOW_CUT_FILTER     |    11 | str    | Processing digital low-cut filter specs        |\n",
      "| END_OF_GROUP               |    12 | str    | Last trace of group flag                       |\n",
      "| FIXED_GAIN                 |    13 | str    | Recording instrument fixed gain (dB)           |\n",
      "| HIGH_CUT_FILTER            |    14 | str    | Acquisition high-cut filter specs              |\n",
      "| LINE_ID                    |    15 | str    | Line identification                            |\n",
      "| LOW_CUT_FILTER             |    16 | str    | Acquisition low-cut filter specs               |\n",
      "| NOTCH_FREQUENCY            |    17 | str    | Notch filter frequency                         |\n",
      "| POLARITY                   |    18 | str    | Polarity                                       |\n",
      "| RAW_RECORD                 |    19 | str    | File name of raw record                        |\n",
      "| RECEIVER                   |    20 | str    | Type of receiver (and number of rec. in group) |\n",
      "| RECEIVER_GEOMETRY          |    21 | str    | Receiver group geometry                        |\n",
      "| RECEIVER_LOCATION          |    22 | str    | Receiver (group) location (x, y, z)            |\n",
      "| RECEIVER_SPECS             |    23 | str    | Receiver specs                                 |\n",
      "| RECEIVER_STATION_NUMBER    |    24 | str    | Receiver station number                        |\n",
      "| SAMPLE_INTERVAL            |    25 | str    | Sampling interval (s)                          |\n",
      "| SHOT_SEQUENCE_NUMBER       |    26 | str    | Shot sequence number                           |\n",
      "| SKEW                       |    27 | str    | Skew value                                     |\n",
      "| SOURCE                     |    28 | str    | Type of source                                 |\n",
      "| SOURCE_GEOMETRY            |    29 | str    | Source (array) geometry                        |\n",
      "| SOURCE_LOCATION            |    30 | str    | Source (array) location (x, y, z)              |\n",
      "| SOURCE_STATION_NUMBER      |    31 | str    | Source station number                          |\n",
      "| STACK                      |    32 | str    | Stack (no. of summed shots)                    |\n",
      "| STATIC_CORRECTIONS         |    33 | str    | Static correction (src, rec, total)            |\n",
      "| TRACE_TYPE                 |    34 | str    | Trace type                                     |\n",
      "| NOTE                       |    35 | str    | Further comments                               |\n",
      "| NSAMPLES                   |    36 | str    | Number of samples                              |\n",
      "+----------------------------+-------+--------+------------------------------------------------+\n"
     ]
    }
   ],
   "source": [
    "sio.log_thdef()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8616a27f-557c-4ff4-88a6-0fd6fbbed484",
   "metadata": {},
   "source": [
    "Now read the data set. For SEG2 data, because there is no strict value type encoding enforced, and due to the fact that many companies have non-standard strings in the descriptor blocks, the trace headers are returned as a Pandas dataframe:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "bfd8647e-7e32-4735-bb25-3dba1daf7d73",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO: Reading entire data set (48 traces) from disk...\n",
      "INFO: Reading all traces took 0.041 seconds.\n"
     ]
    }
   ],
   "source": [
    "data, headers = sio.read_dataset()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "12c578f1-457a-4a9d-bdc3-b622b4107ce8",
   "metadata": {},
   "outputs": [],
   "source": [
    "delay = np.float32(headers[\"DELAY\"][0])\n",
    "channel = np.array(headers[\"CHANNEL_NUMBER\"], dtype=int)\n",
    "t = np.arange(delay, delay+(ns-1)*dt+dt/2, dt, dtype=np.float32)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ed5ed76f-69b3-4425-b60a-ecfca16f600d",
   "metadata": {},
   "source": [
    "Finally, plot the normalized traces starting at channel 2 (trace 1) and ending at channel 32 (trace 31), as all larger channels contain no data (apart from noise):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "e0224eac-91e8-4815-9287-5781283741f6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 158256 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(1, 32):\n",
    "    dmax = np.max(np.abs(data[i, :]))\n",
    "    amp = channel[i] + data[i, :]/dmax\n",
    "    ax.plot(amp, t, 'k-')\n",
    "    ax.fill_betweenx(t, amp, channel[i], where=amp > channel[i], lw=0, facecolor=\"black\")\n",
    "\n",
    "ax.set_xlabel(\"Channel number\")\n",
    "ax.set_ylabel(\"Time in s\")\n",
    "ax.set_xlim(1, 33)\n",
    "ax.set_ylim(t[-1], t[0])\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3d3c74f4-ded4-4581-8a2b-7ea77e9884b3",
   "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": "84079133-557c-4f39-a284-b55d1bdb6f58",
   "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
}
