{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"This notebook shows how Constant Wavelet Transform can be performed with usage of cmorlet-tensorflow package fork provided by [Fractal Feelings](https://www.kaggle.com/kevinmcisaac) (https://github.com/Kevin-McIsaac/cmorlet-tensorflow/tree/Performance).\n\nHave any questions or suggestions? Please comment below.\n\n**<font color='red'>And if you liked this notebook, please upvote it!</font>**\n\n**Changelog**\n* v2 - changed normalization\n* v1 - initial version","metadata":{}},{"cell_type":"markdown","source":"## Import packages","metadata":{}},{"cell_type":"code","source":"!pip install -q git+https://github.com//Kevin-McIsaac/cmorlet-tensorflow@Performance --no-deps","metadata":{"execution":{"iopub.status.busy":"2021-09-02T14:11:49.697726Z","iopub.execute_input":"2021-09-02T14:11:49.698167Z","iopub.status.idle":"2021-09-02T14:11:56.835204Z","shell.execute_reply.started":"2021-09-02T14:11:49.698075Z","shell.execute_reply":"2021-09-02T14:11:56.834080Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport os\nfrom glob import glob\nimport matplotlib.pyplot as plt\nfrom scipy import signal\nimport tensorflow as tf\nfrom CWT.cwt import ComplexMorletCWT\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\n%matplotlib inline","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-09-02T14:11:56.837118Z","iopub.execute_input":"2021-09-02T14:11:56.837518Z","iopub.status.idle":"2021-09-02T14:12:03.449626Z","shell.execute_reply.started":"2021-09-02T14:11:56.837469Z","shell.execute_reply":"2021-09-02T14:12:03.448876Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"num_samples = 4 # first N samples to process\nimage_size = [256, 256]","metadata":{"execution":{"iopub.status.busy":"2021-09-02T14:12:03.450919Z","iopub.execute_input":"2021-09-02T14:12:03.451281Z","iopub.status.idle":"2021-09-02T14:12:03.454197Z","shell.execute_reply.started":"2021-09-02T14:12:03.451254Z","shell.execute_reply":"2021-09-02T14:12:03.453491Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Read training labels","metadata":{}},{"cell_type":"markdown","source":"Now we read training labels data, and get npy paths.","metadata":{}},{"cell_type":"code","source":"ROOT_DIR = '../input/g2net-gravitational-wave-detection'\ndf = pd.read_csv(os.path.join(ROOT_DIR, 'training_labels.csv'))\ndf['path'] = df['id'].apply(lambda x: f'{ROOT_DIR}/train/{x[0]}/{x[1]}/{x[2]}/{x}.npy')","metadata":{"execution":{"iopub.status.busy":"2021-09-02T14:12:03.455304Z","iopub.execute_input":"2021-09-02T14:12:03.455680Z","iopub.status.idle":"2021-09-02T14:12:04.141404Z","shell.execute_reply.started":"2021-09-02T14:12:03.455655Z","shell.execute_reply":"2021-09-02T14:12:04.140628Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Demonstrate CWT usage","metadata":{}},{"cell_type":"markdown","source":"Let's calculate CWT for 4 first signals with and without usage of a bandpass filter (20-500Hz), and plot results!","metadata":{}},{"cell_type":"code","source":"train_files = df['path'].values[:num_samples]\nbHP, aHP = signal.butter(8, (20, 500), btype='bandpass', fs=2048)\ncwt_transform = ComplexMorletCWT(wavelet_width=8, fs=2048, lower_freq=20, upper_freq=500, n_scales=image_size[0],\n                    stride=int(np.ceil(4096/image_size[0])), output='magnitude', data_format='channels_first')\nwaves = []\ncwts = []\nwaves_f = []\ncwts_f = []\nfor i in range(num_samples):\n    wave = np.load(train_files[i])\n    wave = wave[0, :]  # for demonstration we will use only signal from one detector\n    wave /= tf.math.reduce_max(wave, axis=0, keepdims=True) # normalization\n    waves.append(np.squeeze(wave))\n    \n    # Without a filter\n    wave_t = tf.convert_to_tensor(wave[np.newaxis, np.newaxis, :])\n    cwt = cwt_transform(wave_t)\n    cwts.append(np.squeeze(cwt.numpy()))\n    \n    # With a filter\n    wave_f = wave*signal.tukey(4096, 0.2)\n    wave_f = signal.filtfilt(bHP, aHP, wave_f)\n    waves_f.append(wave_f)\n    wave_t_f = tf.convert_to_tensor(wave_f[np.newaxis, np.newaxis, :])\n    cwt_f = cwt_transform(wave_t_f)\n    cwts_f.append(np.squeeze(cwt_f.numpy()))","metadata":{"execution":{"iopub.status.busy":"2021-09-02T14:12:35.556231Z","iopub.execute_input":"2021-09-02T14:12:35.556579Z","iopub.status.idle":"2021-09-02T14:12:36.220799Z","shell.execute_reply.started":"2021-09-02T14:12:35.556549Z","shell.execute_reply":"2021-09-02T14:12:36.219693Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Without a filter","metadata":{}},{"cell_type":"code","source":"fig, axs = plt.subplots(num_samples)\nfig.set_figheight(15)\nfig.set_figwidth(15)\nfor i in range(num_samples):\n    nid = df['id'][i]\n    ntarget = df['target'][i]\n    axs[i].title.set_text(f'{nid}.npy, target: {ntarget}')\n    axs[i].plot(waves[i])","metadata":{"execution":{"iopub.status.busy":"2021-09-02T14:12:36.222147Z","iopub.execute_input":"2021-09-02T14:12:36.222400Z","iopub.status.idle":"2021-09-02T14:12:36.702023Z","shell.execute_reply.started":"2021-09-02T14:12:36.222375Z","shell.execute_reply":"2021-09-02T14:12:36.701242Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, axs = plt.subplots(num_samples)\nfig.set_figheight(20)\nfig.set_figwidth(5)\nfor i in range(num_samples):\n    nid = df['id'][i]\n    ntarget = df['target'][i]\n    axs[i].title.set_text(f'{nid}.npy, target: {ntarget}')\n    axs[i].pcolormesh(cwts[i])","metadata":{"execution":{"iopub.status.busy":"2021-09-02T14:12:36.703271Z","iopub.execute_input":"2021-09-02T14:12:36.703633Z","iopub.status.idle":"2021-09-02T14:12:37.345220Z","shell.execute_reply.started":"2021-09-02T14:12:36.703605Z","shell.execute_reply":"2021-09-02T14:12:37.344271Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## With a filter","metadata":{}},{"cell_type":"code","source":"fig, axs = plt.subplots(num_samples)\nfig.set_figheight(15)\nfig.set_figwidth(15)\nfor i in range(num_samples):\n    nid = df['id'][i]\n    ntarget = df['target'][i]\n    axs[i].title.set_text(f'{nid}.npy, target: {ntarget}')\n    axs[i].plot(waves_f[i])","metadata":{"execution":{"iopub.status.busy":"2021-09-02T14:12:37.346470Z","iopub.execute_input":"2021-09-02T14:12:37.346765Z","iopub.status.idle":"2021-09-02T14:12:37.855748Z","shell.execute_reply.started":"2021-09-02T14:12:37.346735Z","shell.execute_reply":"2021-09-02T14:12:37.854641Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, axs = plt.subplots(num_samples)\nfig.set_figheight(20)\nfig.set_figwidth(5)\nfor i in range(num_samples):\n    nid = df['id'][i]\n    ntarget = df['target'][i]\n    axs[i].title.set_text(f'{nid}.npy, target: {ntarget}')\n    axs[i].pcolormesh(cwts_f[i])","metadata":{"execution":{"iopub.status.busy":"2021-09-02T14:12:37.857022Z","iopub.execute_input":"2021-09-02T14:12:37.857321Z","iopub.status.idle":"2021-09-02T14:12:38.554496Z","shell.execute_reply.started":"2021-09-02T14:12:37.857291Z","shell.execute_reply":"2021-09-02T14:12:38.553701Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"You can use ComplexMorletCWT() as your model block to convert waves to CWT on-the-fly in TensorFlow models.","metadata":{"execution":{"iopub.status.busy":"2021-07-03T14:29:22.62631Z","iopub.execute_input":"2021-07-03T14:29:22.626623Z","iopub.status.idle":"2021-07-03T14:29:22.632544Z","shell.execute_reply.started":"2021-07-03T14:29:22.626594Z","shell.execute_reply":"2021-07-03T14:29:22.63147Z"}}}]}