diff --git a/src/View/Results/Window.py b/src/View/Results/Window.py index ccac22ef..a0687705 100644 --- a/src/View/Results/Window.py +++ b/src/View/Results/Window.py @@ -31,14 +31,23 @@ except Exception as e: print(f"Module 'rasterio' is not available: {e}") _rasterio_loaded = False +try: + import pyaudio + import wave + _audio_loaded = True +except Exception as e: + print(f"Either 'pyaudio' or 'wave' is not available: {e}") + _audio_loaded = False + from functools import reduce -from numpy import sqrt +import numpy as np from datetime import datetime from tools import trace, timer, logger_exception from View.Tools.PamhyrWindow import PamhyrWindow +from View.WaitingDialog import WaitingDialog from PyQt5.QtGui import ( QKeySequence, QIcon, QPixmap, @@ -349,7 +358,8 @@ class ResultsWindow(PamhyrWindow): "action_add": self._add_custom_plot, "action_export": self._export, # "action_export": self.export_current, - "action_import_data": self.import_data + "action_import_data": self.import_data, + "action_play_sound": self.play_sound } if _rasterio_loaded: actions["action_Geo_tiff"] = self.import_geotiff @@ -357,6 +367,12 @@ class ResultsWindow(PamhyrWindow): self.find(QAction, "action_Geo_tiff")\ .setEnabled(False) + if _audio_loaded: + actions["action_play_sound"] = self.play_sound + else: + self.find(QAction, "action_play_sound")\ + .setVisible(False) + if len(self._results) > 1: self.find(QAction, "action_reload").setEnabled(False) @@ -959,7 +975,7 @@ class ResultsWindow(PamhyrWindow): map( lambda p: p.get_ts_key(timestamp, "V") / - sqrt(9.81 * ( + np.sqrt(9.81 * ( p.geometry.wet_area( p.get_ts_key(timestamp, "Z")) / p.geometry.wet_width( @@ -973,7 +989,7 @@ class ResultsWindow(PamhyrWindow): map( lambda p: p.get_ts_key(timestamp, "V") / - sqrt(9.81 * ( + np.sqrt(9.81 * ( p.geometry.wet_area( p.get_ts_key(timestamp, "Z")) / p.geometry.wet_width( @@ -986,7 +1002,7 @@ class ResultsWindow(PamhyrWindow): map( lambda p: p.get_ts_key(timestamp, "V") / - sqrt(9.81 * ( + np.sqrt(9.81 * ( p.geometry.wet_area( p.get_ts_key(timestamp, "Z")) / p.geometry.wet_width( @@ -1122,7 +1138,7 @@ class ResultsWindow(PamhyrWindow): if self._current_results != 2: fr = my_dict[dict_y["froude"]] = list( map(lambda z, v: - v / sqrt(9.81 * ( + v / np.sqrt(9.81 * ( profile.geometry.wet_area(z) / profile.geometry.wet_width(z)) ), z, v) @@ -1131,7 +1147,7 @@ class ResultsWindow(PamhyrWindow): fr1 = list( map(lambda z, v: v / - sqrt(9.81 * ( + np.sqrt(9.81 * ( profile1.geometry.wet_area(z) / profile1.geometry.wet_width(z)) ), z1, v1) @@ -1139,7 +1155,7 @@ class ResultsWindow(PamhyrWindow): fr2 = list( map(lambda z, v: v / - sqrt(9.81 * ( + np.sqrt(9.81 * ( profile2.geometry.wet_area(z) / profile2.geometry.wet_width(z)) ), z2, v2) @@ -1313,3 +1329,84 @@ class ResultsWindow(PamhyrWindow): for p in self._additional_plot: self._additional_plot[p].add_imported_plot(data) + + def play_sound(self): + def get_sine_wave(frequency, duration, + sample_rate=44100, amplitude=4096): + t = np.linspace(0, duration, int(sample_rate*duration)) + return amplitude*np.sin(2*np.pi*frequency*t) + + if not _audio_loaded: + return + + # results + results=self._results[self._current_results[0]] + if results is None: + return + + # reach + reach = results.river.reachs[self._get_current_reach()] + profile_id = self._get_current_profile() + profile = reach.profile(profile_id) + + t = self._timestamps + q = profile.get_key("Q") + + scale=[] + low = 30; high = 84 + for k in range(low, high): + note=440*2**((k-49)/12) + scale.append(note) # add musical note + n_notes = len(scale) # number of musical notes + # rescale + # we start at low to high + tmax = max(t); tmin = min(t); + qmax = max(q); qmin = min(q); qfact = (n_notes) / (qmax - qmin + 1) + for i in range(len(q)): + q[i] = int((q[i] - qmin) * qfact) + nq = [q[0]] # (notes) + dq = [0.1] # durée + for i in range(len(t)-1): + if q[i] == q[i+1]: + dq[-1] += 0.1 + else: + nq.append(q[i+1]) + dq.append(0.1) + wq=[] + for i in range(len(dq)): # loop over dataset observations, create one note per observation + volume = 2048 + new_w = get_sine_wave(frequency = scale[nq[i]], duration = dq[i], amplitude = volume) + wq = np.concatenate((wq,new_w)) + p = pyaudio.PyAudio() + chunk = 1048 + stream = p.open(format = + p.get_format_from_width(2), + channels = 1, + rate = 44100, + output = True) + + + + def fn(): + i = 0 + while i < len(wq): + stream.write( + wq[i:min(i+chunk,len(wq))].astype(np.int16).tobytes() + ) + i += chunk + + title = self._trad["playing_sound"] + dlg = WaitingDialog( + payload_fn=fn, + title=title, + parent=self + ) + dlg.exec_() + + #stop stream + stream.stop_stream() + stream.close() + + #close PyAudio + p.terminate() + diff --git a/src/View/Results/translate.py b/src/View/Results/translate.py index 7a1e7e9b..bea42fe9 100644 --- a/src/View/Results/translate.py +++ b/src/View/Results/translate.py @@ -61,6 +61,9 @@ class ResultsTranslate(MainTranslate): self._dict["ImageCoordinates"] = _translate( "Results", "Image coordinates" ) + self._dict["playing_sound"] = _translate( + "Results", "Playing sound..." + ) self._sub_dict["table_headers_reach"] = { "name": _translate("Results", "Reach name"), diff --git a/src/View/ui/Results.ui b/src/View/ui/Results.ui index 4e33b042..0be79a36 100644 --- a/src/View/ui/Results.ui +++ b/src/View/ui/Results.ui @@ -240,6 +240,7 @@ + @@ -301,6 +302,18 @@ Import data from SCV file + + + + ressources/multimedia-volume-control-symbolic.symbolic.pngressources/multimedia-volume-control-symbolic.symbolic.png + + + play_sound + + + Play discharge as sound + + diff --git a/src/View/ui/ressources/multimedia-volume-control-symbolic.symbolic.png b/src/View/ui/ressources/multimedia-volume-control-symbolic.symbolic.png new file mode 100644 index 00000000..c6eccca6 Binary files /dev/null and b/src/View/ui/ressources/multimedia-volume-control-symbolic.symbolic.png differ diff --git a/src/lang/fr.ts b/src/lang/fr.ts index b25cab15..4f391c23 100644 --- a/src/lang/fr.ts +++ b/src/lang/fr.ts @@ -427,90 +427,100 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie. CommonWord - + Name Nom - + Type Type - + Value Valeur - + Comment Commentaire - + Description Description - + Time Temps - + Date Date - + Reach Bief - + Reaches Biefs - + Main channel Lit mineur - + Floodway Lit moyen - + Not defined Non défini - + Not associated Non associé - + Cross-section Section en travers - + Title Titre - + Method Méthode - + Select reach Sélectionner un bief + + + ID + + + + + Pamhyr2 ID + + Configure @@ -538,10 +548,15 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.Sélection des graphiques personnalisés - + Elevation (m) Cote (m) + + + user_imported + + D90AdisTS @@ -632,10 +647,10 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie. Read results: - Lecture des résultats : + Lecture des résultats : - + . . @@ -750,32 +765,32 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.Débit - + First cross-section Première section en travers - + Last cross-section Dernière section en travers First guideline - Première ligne directrice + Première ligne directrice Guideline used for distance computation - Lignes directrices pour le calcul des distances + Lignes directrices pour le calcul des distances - + Spline Spline - + Linear Linéaire @@ -805,7 +820,7 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.Ligne - + Limits Limites @@ -815,12 +830,12 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.Options - + Space step (m) Pas d'espace (m) - + Type of interpolation: Type d'interpolation : @@ -855,7 +870,7 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.Valeur à l'origine - + Parameters Paramètres @@ -867,7 +882,7 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie. Second guideline - Seconde ligne directrice + Seconde ligne directrice @@ -1308,12 +1323,12 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie. Frictions - + Start (m) PK de départ (m) - + End (m) PK de fin (m) @@ -1333,10 +1348,20 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.Strickler ($m^{1/3}/s$) - + Coefficient Coefficient + + + Mage initial frictions file (*.RUG *.rug) + + + + + All files (*) + Tous les fichiers (*) + GeoTIFF @@ -1434,12 +1459,12 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.Géométrie des sections en travers - + upstream amont - + downstream aval @@ -1581,12 +1606,12 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.Évaporation - + Start (m) PK de départ (m) - + End (m) PK de fin (m) @@ -1605,6 +1630,16 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.End rk (m) Pk fin + + + Shapefile (*.LAT *.lat) + + + + + All files (*) + Tous les fichiers (*) + LateralContributionAdisTS @@ -1627,17 +1662,17 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie. MainWindow - + Open debug window Ouvrir la fenêtre de débogage - + Open SQLite debuging tool ('sqlitebrowser') Ouvrir l'outil de débogage SQLite ('sqlitebrowser') - + Enable this window Activer cette fenêtre @@ -1702,7 +1737,7 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.Éditer la couche sédimentaire - + Ctrl+E Ctrl+E @@ -1767,7 +1802,7 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.&Fenêtres - + New study Nouvelle étude @@ -1777,82 +1812,82 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.Ctrl+N - + Open a study Ouvrir une étude - + Ctrl+O Ctrl+O - + Close Fermer - + Close current study Fermer l'étude en cours - + Save Sauvegarder - + Save study Sauvegarder l'étude - + Ctrl+S Ctrl+S - + Save as ... Sauvegarder sous ... - + Save study as ... Sauvegarder l'étude sous ... - + Ctrl+Shift+S Ctrl+Shift+S - + Pamhyr2 configuration Configuration de Pamhyr2 - + Quit Quitter - + Quit application Quitter l'application - + Ctrl+F4 Ctrl+F4 - + Edit river network Éditer le réseau - + Edit geometry Éditer la géométrie @@ -1867,37 +1902,37 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.Exporter la géométrie - + Numerical parameters of solvers Paramètres numériques des solveurs - + Boundary conditions and point sources Conditions aux limites et apports ponctuels - + Initial conditions Conditions initiales - + Edit friction Éditer les frottements - + Edit lateral sources Éditer les contributions latérales - + Run solver Lancer le solveur - + F5 F5 @@ -1907,137 +1942,137 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.Ouvrir - + Visualize last results Visualisation des derniers résultats - + Visualize the last results Visualisation des derniers résultats - + About À propos - + Save current study Sauvegarder l'étude - + Save the study (Ctrl+S) Sauvegarde de l'étude (Ctrl+S) - + Close the study (Ctrl+F) Fermeture de l'étude (Ctrl+F) - + Ctrl+F Ctrl+F - + Run a solver Lancer un solveur - + River network Réseau - + Geometry Géometrie - + Edit reach geometry Éditer la géométrie du bief actuel - + Boundary conditions Conditions aux limites - + Edit boundary conditions and point sources Éditer les conditions aux limites et les apports ponctuels - + Lateral sources Contributions latérales - + Friction Frottements - + Edit study Éditer l'étude - + Define initial conditions Définir les conditions initiales - + Sediment layers Couches sédimentaires - + Define sediment layers Définition des couches sédimentaires - + Edit reach sediment layers Éditer les couches sédimentaires - + Mage Mage - + Open Mage documentation Ouvrir la documentation de Mage - + Users (wiki) Utilisateurs (wiki) - + Developers (pdf) Développeurs (pdf) - + Developers (html) Développeurs (html) - + Reservoirs Casiers - + Edit reservoirs Éditer les casiers @@ -2047,12 +2082,12 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.Ouvrages hydrauliques - + Edit hydraulic structures Éditer les ouvrages hydrauliques - + Open results from file Ouvrir des résultats depuis un fichier @@ -2117,7 +2152,7 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.Suspension - + Add a new boundary condition or lateral source Ajouter une condition aux limites ou un apport latéral @@ -2127,7 +2162,7 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.Supprimer les lignes selectionnées - + Edit boundary condition or lateral source Éditer une condition aux limites ou un apport latéral @@ -2192,17 +2227,17 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.Hydrogramme - + Add customized visualization Ajouter une visualisation personnalisée - + Reload Recharger - + Export Exporter @@ -2212,7 +2247,7 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.supprimer - + Edit Strickler coefficients Éditer les coefficients de Strickler @@ -2482,12 +2517,12 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.Maillage - + Summary Résumé - + Checks Vérifications @@ -2497,12 +2532,12 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.&Avancé - + &Additional files Fichiers &supplémentaires - + REP additional lines Lignes REP supplémentaires @@ -2577,7 +2612,7 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.Éditer fichier - + Edit the study information Éditer les informations de l'étude @@ -2587,12 +2622,12 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.toolBar - + toolBar_2 toolBar_2 - + Edit frictions Éditer les frottements @@ -2642,7 +2677,7 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.Trier les points - + Export data as CSV Exporter les données au format CSV @@ -2707,47 +2742,47 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.Données - + Please select a reach Veuillez sélectionner un bief - + Last open study Dernière étude ouverte - + Do you want to open again the last open study? Voulez-vous rouvrir la dernière étude ? - + This edition window need a reach selected into the river network to work on it Cette fenêtre d'édition a besoin d'un bief sélectionné dans le réseau pour travailler dessus - + Close without saving study Fermer sans sauvegarder l'étude - + Do you want to save current study before closing it? Souhaitez-vous sauvegarder l'étude en cours avant de la fermer ? - + Warning Avertissement - + X (m) X (m) - + Y (m) Y (m) @@ -2777,37 +2812,37 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.Apports Latéraux - + AdisTS AdisTS - + Output RK Pk de sortie - + Run AdisTS Lancer AdisTS - + Pollutants Polluants - + D90 D90 - + DIF DIF - + Open results AdisTS Ouvrir des résultats AdisTS @@ -2922,27 +2957,27 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.Export données brutes - + Yes Oui - + No Non - + Compare results Comparaison de résultats - + Geo tiff Geo tiff - + Import background image Importer une image de fond @@ -2956,6 +2991,81 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.Change current reach Changer le bief courrant + + + Loading file ... + + + + + Reading results ... + + + + + Open backup file + + + + + A more recent backup file as found for this study, do you want to open the backup file? + + + + + Results + Résultats + + + + The version of the results does not match the version of the study. One or more data has been modified after the last simulation Do you still want to open those results? + + + + + Results compare + + + + + Results comparison parameters is invalid + + + + + Results comparison with two incompatible study version + + + + + Scenarios + + + + + Edit scenarios tree + + + + + Import data + + + + + Import data from SCV file + + + + + play_sound + + + + + Play discharge as sound + + MainWindow_reach @@ -3013,27 +3123,27 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.Supprimer l'arrête - + Enable the reach Activer l'arête - + Disable the reach Désactiver l'arête - + Reverse the reach orientation Inverser l'orientation de l'arête - + Source node Nœud source - + Destination node Nœud destination @@ -3053,10 +3163,20 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.Bief - + Index Index + + + Split the reach + + + + + Select profile + + OutputRKAdisTS @@ -3176,7 +3296,7 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.Lecture des résultats - + Water elevation Cote de l'eau @@ -3186,12 +3306,12 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.Cote maximum de l'eau - + Reach name Nom du bief - + Profile Profil @@ -3246,12 +3366,12 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.Masse min - + Variables names Noms des variables - + Pollutant name Nom des polluants @@ -3261,7 +3381,7 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.enveloppe - + Profile name Nom du profil @@ -3281,7 +3401,7 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.Fichiers GeoTIFF (*.tiff *.tif) - + Image coordinates Coordonnées de l'image @@ -3290,11 +3410,89 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.All files (*) Tous les fichiers (*) + + + CSV file (*.csv) + + + + + Playing sound... + + + + + Scenarios + + + Scenarios + + + + + Select this scenario + + + + + Create new scenario from current scenario + + + + + Delete this scenario + + + + + Duplicate this scenario + + + + + Parent + + + + + Create new scenario + + + + + Delete scenario + + + + + Select scenario + + + + + Undo ... + + + + + Redo ... + + + + + Save scenarios before scenarios switching + + + + + Save scenarios before scenarios switching ? + + SedimentLayers - + (no name) (sans nom) @@ -3319,7 +3517,7 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.Contrainte critique - + (no name - @rk) (sans nom - @rk) @@ -3382,7 +3580,7 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.Sélection des logs - + Compare solvers Comparaison de solveurs @@ -3682,87 +3880,87 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie. Unit - + Width (m) Largeur (m) - + Depth (m) Profondeur (m) - + Diameter (m) Diamètre (m) - + Thickness (m) Épaisseur (m) - + Elevation (m) Cote (m) - + Area (hectare) Aire (hectare) - + Time (sec) Temps (s) - + Time (JJJ:HH:MM:SS) Temps (JJJ:HH:MM:SS) - + Date (sec) Date (s) - + Date (ISO format) Date (format ISO) - + River Kilometer (m) Point Kilométrique (m) - + Max Depth (m) Profondeur max (m) - + Mean Depth (m) Profondeur moyenne (m) - + Velocity (m/s) Vitesse (m/s) - + Wet Perimeter (m) Périmètre mouillé (m) - + Hydraulic Radius (m) Rayon hydraulique (m) - + Froude number Nombre de Froude @@ -3805,132 +4003,132 @@ moyen droit (m) D90 - + Width Envelop (m) Enveloppe de la argeur (m) - + Max Width (m) Largeur max (m) - + Min Width (m) Largeur min (m) - + Min Depth (m) Profondeur min (m) - + Depth Envelop (m) Enveloppe de la profondeur (m) - + Bed Elevation (m) Cote du fond (m) - + Bed Elevation Envelop (m) Enveloppe de la cote du fond (m) - + Max Bed Elevation (m) Cote du fond max (m) - + Min Bed Elevation (m) Cote du fond min (m) - + Water Elevation (m) Cote de l'eau (m) - + Water Elevation Envelop (m) Enveloppe de la cote de l'eau (m) - + Max Water Elevation (m) Cote de l'eau max (m) - + Min Water Elevation (m) Cote de l'eau min (m) - + Velocity Envelop (m/s) Enveloppe de la vitesse (m/s) - + Max Velocity (m/s) Vitesse max (m/s) - + Min Velocity (m/s) Vitesse min (m/s) - + Area Aire - + Rho Rho - + Porosity Porosité - + CDC_RIV CDC_RIV - + CDC_CAS CDC_CAS - + APD APD - + AC AC - + BC BC - + Concentration (g/l) Concentration (g/l) - + Mass (kg) Masse @@ -3950,32 +4148,32 @@ moyen droit (m) Coeff c - + Discharge Débit - + Discharge Envelop Enveloppe du débit - + Max Discharge Débit max - + Min Discharge Débit min - + Concentration Concentration - + Wet Area Aire mouillée