123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448 |
- #!/usr/bin/env python3
- # -*- coding: utf-8 -*-
- """
- pyTREMOR - Python /Seismoacoustics/ Squeezer - 2023-2024 - by Kräken.LABS (https://krakenslab.com)
- ----------
- Seismoacoustics — the combined study of vibrations in the Earth and sound waves in the atmosphere
- to characterize non-earthquake geohazards, such as avalanches, landslides, and volcanic eruptions.
- https://code.03c8.net/krakenslab/pytremor
- ----------
- You should have received a copy of the GNU General Public License along
- with PyTREMOR; if not, write to the Free Software Foundation, Inc., 51
- Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- """
- VERSION = str(0.5)
- import datetime
- from datetime import timedelta
- import os, sys
- import shutil
- from os import environ
- environ['PYGAME_HIDE_SUPPORT_PROMPT'] = '1'
- import pygame
- import subprocess
- from obspy import UTCDateTime
- import warnings
- def custom_filter(message, category, filename, lineno, *args, **kwargs):
- return not ('Font family' in str(message) and 'cursive' in str(message))
- warnings.simplefilter('ignore', custom_filter)
- def banner():
- print(r''' __ _______ __ __
- _ _\ \ / /_ _| __ ___| \/ | ___ _ __
- | '_ \ V / | || '__/ _ \ |\/| |/ _ \| '__|
- | |_) | | | || | | __/ | | | (_) | |
- | .__/|_| |_||_| \___|_| |_|\___/|_|
- |_| pyTREMOR (v'''+VERSION+''') by Kräken.LABS | (2023/2024)
- ''')
- import os
- import shutil
- import datetime
- from obspy import UTCDateTime
- def sonify(network_conf, station_conf, channel_conf, starttime_conf, endtime_conf, freqmax_conf, freqmin_conf, speed_up_factor_conf, fps_conf, spec_win_dur_conf, db_lim_conf):
- db_lim_conf = db_lim_conf.replace("\n", "")
- db_lim_conf_1 = int(db_lim_conf.split(",")[0])
- db_lim_conf_2 = int(db_lim_conf.split(",")[1])
- from sonify.sonify.sonify import sonify
- try:
- print(f"\nSonifying data for: {station_conf}...")
- result = sonify(
- network=network_conf.replace("\n", ""),
- station=station_conf.replace("\n", ""),
- channel=channel_conf.replace("\n", ""),
- starttime=UTCDateTime(starttime_conf),
- endtime=UTCDateTime(endtime_conf),
- freqmax=int(freqmax_conf.replace("\n", "")),
- freqmin=int(freqmin_conf.replace("\n", "")),
- speed_up_factor=int(speed_up_factor_conf.replace("\n", "")),
- fps=int(fps_conf.replace("\n", "")),
- spec_win_dur=int(spec_win_dur_conf.replace("\n", "")),
- db_lim=(db_lim_conf_1, db_lim_conf_2),
- )
- print("Sonification completed successfully.")
- now = datetime.datetime.now()
- filename = now.strftime("%Y-%m-%d-%H-%M-") + station_conf.replace("\n", "") + ".mp4"
- dataset_folder = "dataset"
- if not os.path.exists(dataset_folder):
- os.makedirs(dataset_folder)
- new_filepath = os.path.join(dataset_folder, filename)
- mp4_files = [file for file in os.listdir(".") if file.endswith(".mp4")]
- if mp4_files:
- mp4_file = mp4_files[0]
- shutil.move(mp4_file, new_filepath)
- print(f"Video moved and renamed to: {new_filepath}")
- if "--autorun" in sys.argv:
- pass
- else:
- menu()
- return True
- else:
- print("No .mp4 file found in the directory.")
- return False
- except Exception as e:
- print(f"An error occurred during sonification: {str(e)}")
- return False
- def menu():
- main_menu = {
- "(h)elp ":"show this message",
- "(v)ersion ":"current version",
- "(c)lear ":"clear screen",
- "(q)uit ":"quit program"
- }
- sonification_menu = {
- "(setup) ":"setup template",
- "(view) ":"view template",
- "(run) ":"run template",
- "(play) ":"play sonification"
- }
- clear()
- while 1:
- cmd = input("pyTREMOR@GSN% ")
- if cmd == "h" or cmd == "help":
- print()
- for n in main_menu:
- print(" "+ n + ": " + main_menu[n])
- print()
- for n in sonification_menu:
- print(" "+ n + ": " + sonification_menu[n])
- print()
- elif cmd == "v" or cmd == "version":
- banner()
- elif cmd == "c" or cmd == "clear":
- clear()
- elif cmd == "setup":
- setup()
- elif cmd == "view":
- view()
- elif cmd == "run":
- run_from_config_file()
- elif cmd == "play":
- play_sonification()
- elif cmd == "q" or cmd == "quit" or cmd == "exit":
- quit()
- def clear():
- os.system('clear')
- def quit():
- sys.exit()
-
- def read_config(file):
- if file == "config":
- f = open("config","r")
- else:
- f = open("autoconfig","r")
- lines = f.readlines()
- f.close()
- return lines
-
- import subprocess
- def play_sonification():
- dataset_folder = "dataset"
- if not os.path.exists(dataset_folder):
- print("No sonification files found.")
- return
-
- mp4_files = [file for file in os.listdir(dataset_folder) if file.endswith(".mp4")]
- wav_files = [file for file in os.listdir(dataset_folder) if file.endswith(".wav")]
- files = []
- for mp4_file in mp4_files:
- base_name = os.path.splitext(mp4_file)[0]
- if f"{base_name}.wav" in wav_files:
- files.append(mp4_file)
- else:
- files.append(mp4_file)
- if not files:
- print("No sonification files found.")
- return
- print("Available sonification files:")
- for i, filename in enumerate(files):
- print(f"{i+1}. {filename}")
-
- selection = input("Choose a file to play (enter number): ")
- try:
- selection = int(selection)
- if selection < 1 or selection > len(files):
- print("Invalid selection.")
- return
- selected_file = files[selection - 1]
- mp4_file = os.path.join(dataset_folder, selected_file)
- wav_file = os.path.splitext(selected_file)[0] + ".wav"
- wav_path = os.path.join(dataset_folder, wav_file)
- if not os.path.exists(wav_path):
- subprocess.run(["ffmpeg", "-i", mp4_file, wav_path])
- pygame.init()
- pygame.mixer.init()
- pygame.mixer.music.load(wav_path)
- pygame.mixer.music.play()
- while pygame.mixer.music.get_busy():
- pygame.time.Clock().tick(10)
- pygame.mixer.quit()
- except ValueError:
- print("Invalid input. Please enter a number.")
- def setup():
- network = input("\n set network (str) (ex: AV): ")
- station = input(" set station (str) (ex: ILSW): ")
- channel = input(" set channel (str) (ex: BHZ): ")
- starttime = input(" set starttime (ex: 2019, 6, 20, 23, 10): ")
- endtime = input(" set endtime (ex: 2019, 6, 21, 0, 30): ")
- freqmin = input(" set freqmin (int or float) (ex: 1): ")
- freqmax = input(" set freqmax (int or float) (ex: 23): ")
- speed_up_factor = input(" set speed_up_factor (int) (ex: 200): ")
- fps = input(" fps (int) (ex: 1): ")
- spec_win_dur = input(" set spec_win_dur (int or float) (ex: 8): ")
- db_lim = input(" set db_lim (tuple or str) (ex: -180,-130): ")
-
- with open("config", mode='w') as config:
- config.write("network="+network+"\n")
- config.write("station="+station+"\n")
- config.write("channel="+channel+"\n")
- config.write("starttime="+starttime+"\n")
- config.write("endtime="+endtime+"\n")
- config.write("freqmin="+freqmin+"\n")
- config.write("freqmax="+freqmax+"\n")
- config.write("speed_up_factor="+speed_up_factor+"\n")
- config.write("fps="+fps+"\n")
- config.write("spec_win_dur="+spec_win_dur+"\n")
- config.write("db_lim="+db_lim)
- config.close()
- def view():
- if os.path.isfile("config"):
- lines = read_config("config")
- else:
- with open("config", mode='w') as config:
- config.write("network=\n")
- config.write("station=\n")
- config.write("channel=\n")
- config.write("starttime=\n")
- config.write("endtime=\n")
- config.write("freqmin=\n")
- config.write("freqmax=\n")
- config.write("speed_up_factor=\n")
- config.write("fps=\n")
- config.write("spec_win_dur=\n")
- config.write("db_lim=")
- config.close()
- lines = read_config("config")
- print("\n", "sonify(")
- for line in lines:
- line = line.replace("\n","")
- print(" ",line)
- print(" )\n")
- def run(network_conf, station_conf, channel_conf, starttime_conf, endtime_conf, freqmax_conf, freqmin_conf, speed_up_factor_conf, fps_conf, spec_win_dur_conf, db_lim_conf):
- print("\n[+] Generating -sonify- setup from LOCAL config...")
- if os.path.isfile("config"):
- lines = read_config("config")
- else:
- print("\n[Error] not 'config' file generated... Exiting!\n")
- sys.exit(2)
- for line in lines:
- if "network" in line:
- network_conf = line.split("=")[1]
- if "station" in line:
- station_conf = line.split("=")[1]
- if "channel" in line:
- channel_conf = line.split("=")[1]
- if "starttime" in line:
- starttime_conf = line.split("=")[1]
- if "endtime" in line:
- endtime_conf = line.split("=")[1]
- if "freqmax" in line:
- freqmax_conf = line.split("=")[1]
- if "freqmin" in line:
- freqmin_conf = line.split("=")[1]
- if "speed_up_factor" in line:
- speed_up_factor_conf = line.split("=")[1]
- if "fps" in line:
- fps_conf = line.split("=")[1]
- if "spec_win_dur" in line:
- spec_win_dur_conf = line.split("=")[1]
- if "db_lim" in line:
- db_lim_conf = line.split("=")[1]
- success = sonify(network_conf, station_conf, channel_conf, starttime_conf, endtime_conf, freqmax_conf, freqmin_conf, speed_up_factor_conf, fps_conf, spec_win_dur_conf, db_lim_conf)
- if not success:
- return False
- return True
- def run_from_config_file():
- lines = read_config("config")
- network_conf = ""
- station_conf = ""
- channel_conf = ""
- starttime_conf = ""
- endtime_conf = ""
- freqmax_conf = ""
- freqmin_conf = ""
- speed_up_factor_conf = ""
- fps_conf = ""
- spec_win_dur_conf = ""
- db_lim_conf = ""
- for line in lines:
- if "network" in line:
- network_conf = line.split("=")[1]
- if "station" in line:
- station_conf = line.split("=")[1]
- if "channel" in line:
- channel_conf = line.split("=")[1]
- if "starttime" in line:
- starttime_conf = line.split("=")[1]
- if "endtime" in line:
- endtime_conf = line.split("=")[1]
- if "freqmax" in line:
- freqmax_conf = line.split("=")[1]
- if "freqmin" in line:
- freqmin_conf = line.split("=")[1]
- if "speed_up_factor" in line:
- speed_up_factor_conf = line.split("=")[1]
- if "fps" in line:
- fps_conf = line.split("=")[1]
- if "spec_win_dur" in line:
- spec_win_dur_conf = line.split("=")[1]
- if "db_lim" in line:
- db_lim_conf = line.split("=")[1]
- success = run(network_conf, station_conf, channel_conf, starttime_conf, endtime_conf, freqmax_conf, freqmin_conf, speed_up_factor_conf, fps_conf, spec_win_dur_conf, db_lim_conf)
- if success:
- menu()
- def init():
- if "--cmd" in sys.argv:
- try:
- network_conf = sys.argv[2]+"\n"
- station_conf = sys.argv[3]+"\n"
- channel_conf = sys.argv[4]+"\n"
- starttime_conf = sys.argv[5].replace(",",", ")+"\n"
- endtime_conf = sys.argv[6].replace(",",", ")+"\n"
- freqmax_conf = sys.argv[7]+"\n"
- freqmin_conf = sys.argv[8]+"\n"
- speed_up_factor_conf = sys.argv[9]+"\n"
- fps_conf = sys.argv[10]+"\n"
- spec_win_dur_conf = sys.argv[11]+"\n"
- db_lim_conf = sys.argv[12]+"\n"
- print("\n[+] Generating -sonify- setup from CMD config...")
- print("\n", "sonify(")
- print(" network="+network_conf.replace("\n",""))
- print(" station="+station_conf.replace("\n",""))
- print(" channel="+channel_conf.replace("\n",""))
- print(" starttime="+starttime_conf.replace("\n",""))
- print(" endtime="+endtime_conf.replace("\n",""))
- print(" freqmax="+freqmax_conf.replace("\n",""))
- print(" freqmin="+freqmin_conf.replace("\n",""))
- print(" speed_up_factor="+speed_up_factor_conf.replace("\n",""))
- print(" fps="+fps_conf.replace("\n",""))
- print(" spec_win_dur="+spec_win_dur_conf.replace("\n",""))
- print(" db_lim="+db_lim_conf)
- print(" )")
- success = sonify(network_conf, station_conf, channel_conf, starttime_conf, endtime_conf, freqmax_conf, freqmin_conf, speed_up_factor_conf, fps_conf, spec_win_dur_conf, db_lim_conf)
- if success:
- menu()
- except:
- print("\n[Error] Executing parameters are wrong... Please review your command line!")
- print("\n +SYNTAX:\n python3 pyTREMOR.py --cmd <network> <station> <channel> <starttime> <endtime> <freqmax> <freqmin> <speed_up_factor> <fps> <spec_win_dur> <db_lim>")
- print("\n +EXAMPLE:\n python3 pyTREMOR.py --cmd AV ILSW BHZ 2019,6,20,23,10 2019,6,21,0,30 23 1 200 1 8 -180,-130\n")
-
- elif "--autorun" in sys.argv:
- print("\n[+] Generating -sonify- setup from LOCAL auto-config...")
- if os.path.isfile("autoconfig"):
- lines = read_config("autoconfig")
- else:
- print("\n[Error] not 'autoconfig' file found... Exiting!\n")
- sys.exit(2)
- datetime_format = "%Y, %m, %d, %H, %M"
- endtime_conf = datetime.datetime.now()
- endtime_conf_format = endtime_conf.strftime(datetime_format)
- print("\n"+"-"*24)
- for line in lines:
- if "LASTHOURS" in line:
- lasthours = line.split("=")[1]
- print ("[Info] LAST HOURS: ["+ str(lasthours).replace("\n","")+"]")
- starttime_conf = endtime_conf - timedelta(hours=int(lasthours))
- starttime_conf_format = starttime_conf.strftime(datetime_format)
- print ("[Info] Starttime: "+str(starttime_conf_format))
- print ("[Info] Endtime: "+ str(endtime_conf_format))
- print("-"*24+"\n")
- stations_list=[]
- for line in lines:
- if "#" in line:
- location = line.split("{")[0]
- print (location)
- location_conf = line.split("{")[1]
- location_conf = location_conf.replace("{", "")
- location_conf = location_conf.replace("}", "")
- location_conf = location_conf.replace("\n", "")
- location_list = list(location_conf.split(","))
- location_list.append("starttime="+starttime_conf_format)
- location_list.append("endtime="+endtime_conf_format)
- print(" "+ str(location_list)+"\n")
- stations_list.append(location_list)
- print("-"*24+"\n")
- for station in stations_list:
- for value in station:
- if "network" in value:
- network_conf = value.split("=")[1]
- if "station" in value:
- station_conf = value.split("=")[1]
- if "channel" in value:
- channel_conf = value.split("=")[1]
- if "starttime" in value:
- starttime_conf = value.split("=")[1]
- if "endtime" in value:
- endtime_conf = value.split("=")[1]
- if "freqmax" in value:
- freqmax_conf = value.split("=")[1]
- if "freqmin" in value:
- freqmin_conf = value.split("=")[1]
- if "speed_up_factor" in value:
- speed_up_factor_conf = value.split("=")[1]
- if "fps" in value:
- fps_conf = value.split("=")[1]
- if "spec_win_dur" in value:
- spec_win_dur_conf = value.split("=")[1]
- if "db_lim" in value:
- db_lim_conf_1 = value.split("|")[0]
- db_lim_conf_1 = db_lim_conf_1.split("=")[1]
- db_lim_conf_2 = value.split("|")[1]
- db_lim_conf=(db_lim_conf_1+","+db_lim_conf_2)
- success = sonify(network_conf, station_conf, channel_conf, starttime_conf, endtime_conf, freqmax_conf, freqmin_conf, speed_up_factor_conf, fps_conf, spec_win_dur_conf, db_lim_conf)
- if not success:
- return False
- if "--help" in sys.argv:
- print("="*50)
- banner()
- print(" Seismoacoustics — the combined study of vibrations in the Earth and sound waves in the atmosphere\n to characterize non-earthquake geohazards, such as avalanches, landslides, and volcanic eruptions.\n")
- print("="*50)
- print(" +HELP:\n python3 pyTREMOR.py --help")
- print("-"*50)
- print("\n +SHELL:\n python3 pyTREMOR.py")
- print("\n +AUTORUN:\n python3 pyTREMOR.py --autorun")
- print("\n +CMD:\n python3 pyTREMOR.py --cmd <network> <station> <channel> <starttime> <endtime> <freqmax> <freqmin> <speed_up_factor> <fps> <spec_win_dur> <db_lim>\n")
- else:
- menu()
- init()
|