{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "b6d8016c-6a09-4717-891b-6f091c5a944e",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from tensorflow.keras import layers, models\n",
    "\n",
    "import scipy\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "import pandas as pd\n",
    "from obspy import read\n",
    "from datetime import datetime, timedelta\n",
    "import matplotlib.pyplot as plt\n",
    "import os\n",
    "\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "7eabca9a-7e3d-49c8-b0b4-4d360dfc51a9",
   "metadata": {},
   "outputs": [],
   "source": [
    "# This section is to test the autoencoder - it generates data that is somewhat similar to the real data\n",
    "\n",
    "# Test signal generator\n",
    "\n",
    "# def signal(A, t):\n",
    "#     return A * np.sin(30*t) * np.exp(-t) + np.random.randn(t.shape[0])/2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "ea8f0359-e795-4ab3-aa8a-b8fc2a8d153b",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A1 = 3\n",
    "# t1 = np.linspace(0, 5, 40000)\n",
    "# s1 = signal(A1, t1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "6681ea57-27e9-480a-ad1f-ece1749ce3dc",
   "metadata": {},
   "outputs": [],
   "source": [
    "# def data_generator(n_samples):\n",
    "#     data = np.empty([n_samples, 40000])\n",
    "#     for i in range(n_samples):\n",
    "#         data[i] = signal(A1, t1)\n",
    "\n",
    "#     return data\n",
    "\n",
    "# data = data_generator(200)\n",
    "\n",
    "# # normalise\n",
    "# data = data / np.max(data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "92594999-3a15-4e0f-aff6-8b7b31860c71",
   "metadata": {},
   "outputs": [],
   "source": [
    "# convenience plot function\n",
    "def plot(x, y, title):\n",
    "    plt.figure()\n",
    "    plt.plot(x, y, linewidth=0.7, c='blue')\n",
    "    plt.title(title)\n",
    "    plt.savefig(title + '.png')\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "c0e83f5b-9b4e-4bfd-8de4-5b45231a709f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(46376,)\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 27892 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# test_filename = 'xa.s12.00.mhz.1970-03-25HR00_evid00003_trimmed_7000_sec'\n",
    "\n",
    "data_directory = './'\n",
    "mseed_file = f'{data_directory}{test_filename}.mseed'\n",
    "st = read(mseed_file)\n",
    "st\n",
    "\n",
    "tr = st.traces[0].copy()\n",
    "tr_times = tr.times()\n",
    "tr_data = tr.data\n",
    "\n",
    "# plot(tr_times, tr_data, 'Mseed Example')\n",
    "\n",
    "print(tr_times.shape)\n",
    "\n",
    "def read_all_mseed_files(data_directory, target_length=None):\n",
    "    # List all files in the directory with \".mseed\" extension\n",
    "    mseed_files = [f for f in os.listdir(data_directory) if f.endswith('.mseed')]\n",
    "    \n",
    "    data_matrix = []\n",
    "    \n",
    "    # Loop through all the mseed files and extract time and data series\n",
    "    for filename in mseed_files:\n",
    "        st = read(os.path.join(data_directory, filename))\n",
    "        tr = st.traces[0].copy()  \n",
    "        tr_data = tr.data  \n",
    "        \n",
    "        if target_length is None:\n",
    "            target_length = len(tr_data)  # Set target length to the first trace's length\n",
    "        \n",
    "        # Pad or trim the data to the target length\n",
    "        if len(tr_data) < target_length:\n",
    "            # Pad with zeros if shorter\n",
    "            tr_data = np.pad(tr_data, (0, target_length - len(tr_data)), mode='constant')\n",
    "        else:\n",
    "            # Trim if longer\n",
    "            tr_data = tr_data[:target_length]\n",
    "        \n",
    "        data_matrix.append(tr_data)\n",
    "    \n",
    "    # Convert the list to a numpy matrix\n",
    "    data_matrix = np.array(data_matrix)\n",
    "    \n",
    "    return data_matrix\n",
    "\n",
    "data = read_all_mseed_files(data_directory, 46376)\n",
    "\n",
    "plot(tr_times, data[3], 'Example 3')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "8d5233d0-cf1a-4a93-9f90-979160f1a7ee",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">Model: \"functional_6\"</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[1mModel: \"functional_6\"\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
       "┃<span style=\"font-weight: bold\"> Layer (type)                    </span>┃<span style=\"font-weight: bold\"> Output Shape           </span>┃<span style=\"font-weight: bold\">       Param # </span>┃\n",
       "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
       "│ input_layer_7 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">InputLayer</span>)      │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">46376</span>)          │             <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │\n",
       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
       "│ functional_4 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Functional</span>)       │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">128</span>)            │    <span style=\"color: #00af00; text-decoration-color: #00af00\">48,080,512</span> │\n",
       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
       "│ functional_5 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Functional</span>)       │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">46376</span>)          │    <span style=\"color: #00af00; text-decoration-color: #00af00\">48,126,760</span> │\n",
       "└─────────────────────────────────┴────────────────────────┴───────────────┘\n",
       "</pre>\n"
      ],
      "text/plain": [
       "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
       "┃\u001b[1m \u001b[0m\u001b[1mLayer (type)                   \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape          \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m      Param #\u001b[0m\u001b[1m \u001b[0m┃\n",
       "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
       "│ input_layer_7 (\u001b[38;5;33mInputLayer\u001b[0m)      │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m46376\u001b[0m)          │             \u001b[38;5;34m0\u001b[0m │\n",
       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
       "│ functional_4 (\u001b[38;5;33mFunctional\u001b[0m)       │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m128\u001b[0m)            │    \u001b[38;5;34m48,080,512\u001b[0m │\n",
       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
       "│ functional_5 (\u001b[38;5;33mFunctional\u001b[0m)       │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m46376\u001b[0m)          │    \u001b[38;5;34m48,126,760\u001b[0m │\n",
       "└─────────────────────────────────┴────────────────────────┴───────────────┘\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Total params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">96,207,272</span> (367.00 MB)\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[1m Total params: \u001b[0m\u001b[38;5;34m96,207,272\u001b[0m (367.00 MB)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">96,207,272</span> (367.00 MB)\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m96,207,272\u001b[0m (367.00 MB)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Non-trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> (0.00 B)\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m0\u001b[0m (0.00 B)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Define the input shape\n",
    "input_shape = (46376,)\n",
    "\n",
    "# Build the encoder\n",
    "def build_encoder(input_shape):\n",
    "    inputs = layers.Input(shape=input_shape)\n",
    "    encoded = layers.Dense(1024, activation='relu')(inputs)  \n",
    "    encoded = layers.Dense(512, activation='relu')(encoded)  \n",
    "    encoded = layers.Dense(128, activation='relu')(encoded)  \n",
    "    return models.Model(inputs, encoded)\n",
    "\n",
    "# Build the decoder\n",
    "def build_decoder():\n",
    "    encoded_inputs = layers.Input(shape=(128,))\n",
    "    decoded = layers.Dense(512, activation='relu')(encoded_inputs)\n",
    "    decoded = layers.Dense(1024, activation='relu')(decoded)\n",
    "    decoded = layers.Dense(46376, activation='linear')(decoded) \n",
    "    return models.Model(encoded_inputs, decoded)\n",
    "\n",
    "# Build the autoencoder\n",
    "def build_autoencoder(input_shape):\n",
    "    encoder = build_encoder(input_shape)\n",
    "    decoder = build_decoder()\n",
    "    \n",
    "    autoencoder_input = layers.Input(shape=input_shape)\n",
    "    encoded = encoder(autoencoder_input)\n",
    "    reconstructed = decoder(encoded)\n",
    "    \n",
    "    autoencoder = models.Model(autoencoder_input, reconstructed)\n",
    "    return autoencoder\n",
    "\n",
    "# Create the autoencoder\n",
    "autoencoder = build_autoencoder(input_shape)\n",
    "\n",
    "# Compile the autoencoder\n",
    "autoencoder.compile(optimizer='adam', loss='mse')\n",
    "\n",
    "# Display architecture\n",
    "autoencoder.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "1e032edc-7aa6-4606-a9ae-10755b729c44",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/10\n",
      "\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 638ms/step - loss: 1.7035e-17 - val_loss: 2.1754e-17\n",
      "Epoch 2/10\n",
      "\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 609ms/step - loss: 2.0816e-17 - val_loss: 2.1793e-17\n",
      "Epoch 3/10\n",
      "\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 607ms/step - loss: 1.4756e-17 - val_loss: 2.1855e-17\n",
      "Epoch 4/10\n",
      "\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 610ms/step - loss: 9.2580e-18 - val_loss: 2.1905e-17\n",
      "Epoch 5/10\n",
      "\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 611ms/step - loss: 2.1401e-17 - val_loss: 2.1988e-17\n",
      "Epoch 6/10\n",
      "\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 634ms/step - loss: 1.5923e-17 - val_loss: 2.2044e-17\n",
      "Epoch 7/10\n",
      "\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 621ms/step - loss: 1.0468e-17 - val_loss: 2.2061e-17\n",
      "Epoch 8/10\n",
      "\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 631ms/step - loss: 1.0075e-17 - val_loss: 2.2054e-17\n",
      "Epoch 9/10\n",
      "\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 606ms/step - loss: 1.5476e-17 - val_loss: 2.2053e-17\n",
      "Epoch 10/10\n",
      "\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 625ms/step - loss: 1.9096e-17 - val_loss: 2.2073e-17\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<keras.src.callbacks.history.History at 0x1f87f14b620>"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "autoencoder.fit(data, data, epochs=10, batch_size=10, validation_split=0.2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "fc11a70e-b56e-4595-8b2c-0de8d56b9838",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[1m3/3\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 53ms/step\n"
     ]
    }
   ],
   "source": [
    "reconstructed = autoencoder.predict(data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "9dccc169-5d08-420a-a962-c654cf129efd",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 47896 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure()\n",
    "plt.plot(tr_times, data[0], c='blue', label='Original signal', linewidth=0.7)\n",
    "plt.plot(tr_times, reconstructed[0], c='red', label='Reconstructed signal', linewidth=0.7)\n",
    "plt.legend(loc='best')\n",
    "plt.title('Reconstruction example')\n",
    "plt.savefig('Reconstruction_ex.png')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5ece85ed-eb24-4a24-b1c4-f0d3e16d95ca",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "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.12.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
