diff --git a/scripts/acoustics.py b/scripts/acoustics.py
new file mode 100644
index 0000000000000000000000000000000000000000..58d56f6647fe77dffaca920694be34314d7d4c17
--- /dev/null
+++ b/scripts/acoustics.py
@@ -0,0 +1,229 @@
+#!/usr/bin/env python
+# coding=utf-8
+"""
+Online Acoustic Monitoring
+
+Usage:
+    acoustics.py [options]
+    acoustics.py (-h | --help)
+
+Options:
+    -d DET_ID       Detector ID
+    -n N_DUS        Number of DUs
+    -o PLOT_DIR     The directory to save the plot 
+    -h --help       Show this screen.
+
+"""
+import numpy as np
+import matplotlib.pyplot as plt
+import time
+import os
+import matplotlib
+from matplotlib import colors
+from datetime import datetime
+from docopt import docopt
+import km3pipe as kp
+
+
+def diff(first, second):
+    second = set(second)
+    return [item for item in first if item not in second]
+
+
+args = docopt(__doc__)
+
+detid = args['-d']
+directory = args['-o']
+N_DUS = args['-n']
+N_DUS = int(N_DUS)
+
+db = kp.db.DBManager()
+sds = kp.db.StreamDS()
+
+ACOUSTIC_BEACONS = [12, 14, 16]
+N_DOMS = 18
+N_ABS=3
+DOMS = range(N_DOMS + 1)
+DUS = range(1, N_DUS + 1)
+
+TIT = 600 # Time Interval between Trains of acoustic pulses)
+SSW = 160 # Signal Security Window (Window size with signal)
+
+check = True
+while check:
+    
+    table = db.run_table(detid)
+    minrun = table["RUN"][len(table["RUN"]) - 1]	
+    ind, = np.where((table["RUN"] == minrun))
+    mintime1 = table['UNIXSTARTTIME'][ind]
+    mintime = mintime1.values
+    maxrun = table["RUN"][len(table["RUN"]) - 1]
+    now = time.time()
+    if (now - mintime/1000) < TIT:
+        minrun = table["RUN"][len(table["RUN"]) - 1] - 1 
+    print(now)
+
+    N_Pulses_Indicator = [] # Matrix indicating how many pulses each piezo reveals
+    for du in DUS:
+        N_Pulses_Indicator_DU = [] # Array indicating for each DU how many pulses each piezo reveals.
+        for ab in ACOUSTIC_BEACONS:
+            for dom in DOMS:
+                try:
+                    domID = db.doms.via_omkey((du, dom), detid).dom_id
+                    toas_all = sds.toashort(detid = detid, minrun = minrun, maxrun = maxrun, domid = domID, emitterid = ab) 
+                
+                    QF_abdom = toas_all["QUALITYFACTOR"]
+                    UTB_abdom = toas_all["UNIXTIMEBASE"]
+                    TOAS_abdom = toas_all["TOA_S"]
+                    UTB_abdom = UTB_abdom.values
+                    up = np.where(UTB_abdom>(now-TIT))
+                    down = np.where(UTB_abdom<(now))
+                    intr = np.intersect1d(up,down)
+                    UTB_abdom = UTB_abdom[intr]
+                    QF_abdom = QF_abdom[intr]                
+                    QF_abdom = QF_abdom.values
+                    QFlist = QF_abdom.tolist()
+                    QFlist.sort(reverse = True)
+                    QF_max = max(QF_abdom)
+                    QF_max_index = np.where(QF_abdom == QF_max)
+                    UTB_signal_min = UTB_abdom[QF_max_index] - SSW/2
+                    UTB_signal_max = UTB_abdom[QF_max_index] + SSW/2
+                    temp1 = np.where(UTB_abdom > (UTB_signal_min[0]))
+                    temp2 = np.where(UTB_abdom < (UTB_signal_max[0]))
+                    inter = np.intersect1d(temp1, temp2)
+                    inter = inter.tolist()
+                    signal_index = inter
+                    QF_abdom_index = np.where(QF_abdom)
+                    all_data_index = QF_abdom_index[0].tolist()
+                    noise_index = diff(all_data_index, signal_index)
+                    SIGNAL = QF_abdom[signal_index] 
+                    UTB_SIGNAL = UTB_abdom[signal_index]
+                    NOISE = QF_abdom[noise_index] 
+                    NOISElist = NOISE.tolist()
+                    NOISElist.sort(reverse = True)
+                    noise_threshold = max(NOISE) 
+                    
+                    # First filter: 22 greatest
+                    Security_Number = 22 # To be sure to take all the pulses
+                        
+                    SIGNAL = SIGNAL.tolist()
+                    SIGNAL_OLD = np.array(SIGNAL)
+                    SIGNAL.sort(reverse = True)
+                    QF_first = SIGNAL[0:Security_Number]
+                    
+                    # Second filter: delete duplicates
+                    
+                    QF_second = np.unique(QF_first)
+                    QF_second = QF_second.tolist()
+                    QF_second.sort(reverse = True)
+                    
+                    # Third filter: If there are more than 11 elements I will eliminate the worst
+                    
+                    if len(QF_second) > 11:
+                        QF_second = np.array(QF_second)
+                        QF_third = [k for k in QF_second if (np.where(QF_second == k)[0][0] < 11)]
+                    else:
+                        QF_third = QF_second
+                    
+                    # Fourth filter: I remove the data if it is below the maximum noise
+                    
+                    QF_fourth = [k for k in QF_third if k > (noise_threshold + (5*np.std(NOISE)))]
+                    
+                    # Fifth filter: Check if the clicks are interspersed in the right way
+                    
+                    Q = []
+                    for q in np.arange(len(QF_fourth)):
+                        Q.append(np.where(SIGNAL_OLD == QF_fourth[q])[0][0])
+                    UTB_fourth = np.array(UTB_SIGNAL.tolist())[Q]
+                    UTB_fourth_l = UTB_fourth.tolist()
+                    D = []
+                    for g in np.arange(len(UTB_fourth_l)):
+                        if ((np.mod((UTB_fourth_l[g] - UTB_fourth_l[0]), 5) > 0.5 and np.mod((UTB_fourth_l[g] - UTB_fourth_l[0]), 5) < 4.5) or (np.mod((UTB_fourth_l[g] - UTB_fourth_l[0]), 5)>5)):
+                           D.append(g)
+                    for d in sorted(D, reverse = True):
+                        del QF_fourth[d]  
+                    QF_fifth = QF_fourth
+                    QF_OK = QF_fifth
+                    NUM = len(QF_OK) # Number of pulses
+                    print(NUM)
+                    
+                    if (NUM > 7):
+                        N_Pulses_Indicator_DU.append(1.5)
+                    elif (NUM < 8 and NUM > 3):
+                        N_Pulses_Indicator_DU.append(0.5)
+                    elif (NUM < 4 and NUM > 0):
+                        N_Pulses_Indicator_DU.append(-0.5)
+                    elif (NUM == 0):
+                        N_Pulses_Indicator_DU.append(-1.5)
+
+                        
+                except (TypeError, ValueError): # TypeError if no data found for a certain piezo, ValueError if there are zero data for a certain piezo
+                    N_Pulses_Indicator_DU.append(-1.5)
+                    
+        N_Pulses_Indicator.append(N_Pulses_Indicator_DU)
+        
+       
+    fig = plt.figure()
+    ax = fig.add_subplot(111)
+    N_doms = 18
+    doms = range(N_doms + 1)
+    L = len(doms)
+    
+    duab = []
+    DUs = []
+    for du in range(N_DUS):
+        duabdu = []
+        duab1 = (du+0.9)*np.ones(L)
+        duab2 = (du+1)*np.ones(L)
+        duab3 = (du+1.1)*np.ones(L)
+        duabdu.append(duab1)
+        duabdu.append(duab2)
+        duabdu.append(duab3)
+        duab.append(duabdu)
+        DUs.append(np.array(N_Pulses_Indicator[du]))
+            
+    ind = np.where(DUs[1] < 1000)
+    iAB1 = np.where(ind[0] < L)
+    iAB2_up = np.where(ind[0] > (L - 1))
+    iAB2_down = np.where(ind[0] < 2*L)
+    iAB2 = np.intersect1d(iAB2_up, iAB2_down)
+    iAB3 = np.where(ind[0] > (2*L - 1))
+    
+    colorsList = [(0, 0, 0), (1, 0.3, 0), (1, 1, 0), (0.2, 0.9, 0)]
+    CustomCmap = matplotlib.colors.ListedColormap(colorsList)
+    bounds = [-2, -1, 0, 1, 2]
+    norma = colors.BoundaryNorm(bounds, CustomCmap.N)
+    for du in range(N_DUS):
+        for ab in range(N_ABS):
+            color = ax.scatter(duab[du][ab], doms, s = 20, c = DUs[du][iAB1], norm=norma, marker = 's', cmap = CustomCmap);
+            color = ax.scatter(duab[du][ab], doms, s = 20, c = DUs[du][iAB2], norm=norma, marker = 's', cmap = CustomCmap);
+            color = ax.scatter(duab[du][ab], doms, s = 20, c = DUs[du][iAB3], norm=norma, marker = 's', cmap = CustomCmap);
+    
+    cbar = plt.colorbar(color)
+    cbar.ax.get_yaxis().set_ticks([])
+    for j, lab in enumerate(['$0. pings$', '$1-3 pings$', '$4-7 pings$', '$>7. pings$']):
+        cbar.ax.text(3.5, (2*j + 1)/8.0, lab, ha = 'center', va = 'center')
+    cbar.ax.get_yaxis().labelpad = 18
+    
+    matplotlib.pyplot.xticks(np.arange(1, N_DUS + 1, step = 1))
+    matplotlib.pyplot.yticks(np.arange(0, 19, step = 1))
+    matplotlib.pyplot.grid(color = 'k', linestyle = '-', linewidth = 0.2)
+    ax.set_xlabel('DUs', fontsize = 18)
+    ax.set_ylabel('Floors', fontsize = 18)
+    ts = now + 3600
+    DATE = datetime.utcfromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')
+    ax.set_title(r' %.16s Detection of the pings emitted by autonomous beacons' %DATE, fontsize = 10)                  
+        
+    my_path = os.path.abspath(directory) 
+    my_file = 'Online_Acoustic_Monitoring.png'
+    
+    fig.savefig(os.path.join(my_path, my_file))    
+                                        
+    print(time.time())
+                               
+    check = False
+    check_time = time.time() - now
+    print(check_time)
+       
+    time.sleep(abs(TIT - check_time))
+    check = True