sonusai 1.0.16__cp311-abi3-macosx_10_12_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sonusai/__init__.py +170 -0
- sonusai/aawscd_probwrite.py +148 -0
- sonusai/audiofe.py +481 -0
- sonusai/calc_metric_spenh.py +1136 -0
- sonusai/config/__init__.py +0 -0
- sonusai/config/asr.py +21 -0
- sonusai/config/config.py +65 -0
- sonusai/config/config.yml +49 -0
- sonusai/config/constants.py +53 -0
- sonusai/config/ir.py +124 -0
- sonusai/config/ir_delay.py +62 -0
- sonusai/config/source.py +275 -0
- sonusai/config/spectral_masks.py +15 -0
- sonusai/config/truth.py +64 -0
- sonusai/constants.py +14 -0
- sonusai/data/__init__.py +0 -0
- sonusai/data/silero_vad_v5.1.jit +0 -0
- sonusai/data/silero_vad_v5.1.onnx +0 -0
- sonusai/data/speech_ma01_01.wav +0 -0
- sonusai/data/whitenoise.wav +0 -0
- sonusai/datatypes.py +383 -0
- sonusai/deprecated/gentcst.py +632 -0
- sonusai/deprecated/plot.py +519 -0
- sonusai/deprecated/tplot.py +365 -0
- sonusai/doc.py +52 -0
- sonusai/doc_strings/__init__.py +1 -0
- sonusai/doc_strings/doc_strings.py +531 -0
- sonusai/genft.py +196 -0
- sonusai/genmetrics.py +183 -0
- sonusai/genmix.py +199 -0
- sonusai/genmixdb.py +235 -0
- sonusai/ir_metric.py +551 -0
- sonusai/lsdb.py +141 -0
- sonusai/main.py +134 -0
- sonusai/metrics/__init__.py +43 -0
- sonusai/metrics/calc_audio_stats.py +42 -0
- sonusai/metrics/calc_class_weights.py +90 -0
- sonusai/metrics/calc_optimal_thresholds.py +73 -0
- sonusai/metrics/calc_pcm.py +45 -0
- sonusai/metrics/calc_pesq.py +36 -0
- sonusai/metrics/calc_phase_distance.py +43 -0
- sonusai/metrics/calc_sa_sdr.py +64 -0
- sonusai/metrics/calc_sample_weights.py +25 -0
- sonusai/metrics/calc_segsnr_f.py +82 -0
- sonusai/metrics/calc_speech.py +382 -0
- sonusai/metrics/calc_wer.py +71 -0
- sonusai/metrics/calc_wsdr.py +57 -0
- sonusai/metrics/calculate_metrics.py +395 -0
- sonusai/metrics/class_summary.py +74 -0
- sonusai/metrics/confusion_matrix_summary.py +75 -0
- sonusai/metrics/one_hot.py +283 -0
- sonusai/metrics/snr_summary.py +128 -0
- sonusai/metrics_summary.py +314 -0
- sonusai/mixture/__init__.py +15 -0
- sonusai/mixture/audio.py +187 -0
- sonusai/mixture/class_balancing.py +103 -0
- sonusai/mixture/constants.py +3 -0
- sonusai/mixture/data_io.py +173 -0
- sonusai/mixture/db.py +169 -0
- sonusai/mixture/db_datatypes.py +92 -0
- sonusai/mixture/effects.py +344 -0
- sonusai/mixture/feature.py +78 -0
- sonusai/mixture/generation.py +1116 -0
- sonusai/mixture/helpers.py +351 -0
- sonusai/mixture/ir_effects.py +77 -0
- sonusai/mixture/log_duration_and_sizes.py +23 -0
- sonusai/mixture/mixdb.py +1857 -0
- sonusai/mixture/pad_audio.py +35 -0
- sonusai/mixture/resample.py +7 -0
- sonusai/mixture/sox_effects.py +195 -0
- sonusai/mixture/sox_help.py +650 -0
- sonusai/mixture/spectral_mask.py +51 -0
- sonusai/mixture/truth.py +61 -0
- sonusai/mixture/truth_functions/__init__.py +45 -0
- sonusai/mixture/truth_functions/crm.py +105 -0
- sonusai/mixture/truth_functions/energy.py +222 -0
- sonusai/mixture/truth_functions/file.py +48 -0
- sonusai/mixture/truth_functions/metadata.py +24 -0
- sonusai/mixture/truth_functions/metrics.py +28 -0
- sonusai/mixture/truth_functions/phoneme.py +18 -0
- sonusai/mixture/truth_functions/sed.py +98 -0
- sonusai/mixture/truth_functions/target.py +142 -0
- sonusai/mkwav.py +135 -0
- sonusai/onnx_predict.py +363 -0
- sonusai/parse/__init__.py +0 -0
- sonusai/parse/expand.py +156 -0
- sonusai/parse/parse_source_directive.py +129 -0
- sonusai/parse/rand.py +214 -0
- sonusai/py.typed +0 -0
- sonusai/queries/__init__.py +0 -0
- sonusai/queries/queries.py +239 -0
- sonusai/rs.abi3.so +0 -0
- sonusai/rs.pyi +1 -0
- sonusai/rust/__init__.py +0 -0
- sonusai/speech/__init__.py +0 -0
- sonusai/speech/l2arctic.py +121 -0
- sonusai/speech/librispeech.py +102 -0
- sonusai/speech/mcgill.py +71 -0
- sonusai/speech/textgrid.py +89 -0
- sonusai/speech/timit.py +138 -0
- sonusai/speech/types.py +12 -0
- sonusai/speech/vctk.py +53 -0
- sonusai/speech/voxceleb.py +108 -0
- sonusai/utils/__init__.py +3 -0
- sonusai/utils/asl_p56.py +130 -0
- sonusai/utils/asr.py +91 -0
- sonusai/utils/asr_functions/__init__.py +3 -0
- sonusai/utils/asr_functions/aaware_whisper.py +69 -0
- sonusai/utils/audio_devices.py +50 -0
- sonusai/utils/braced_glob.py +50 -0
- sonusai/utils/calculate_input_shape.py +26 -0
- sonusai/utils/choice.py +51 -0
- sonusai/utils/compress.py +25 -0
- sonusai/utils/convert_string_to_number.py +6 -0
- sonusai/utils/create_timestamp.py +5 -0
- sonusai/utils/create_ts_name.py +14 -0
- sonusai/utils/dataclass_from_dict.py +27 -0
- sonusai/utils/db.py +16 -0
- sonusai/utils/docstring.py +53 -0
- sonusai/utils/energy_f.py +44 -0
- sonusai/utils/engineering_number.py +166 -0
- sonusai/utils/evaluate_random_rule.py +15 -0
- sonusai/utils/get_frames_per_batch.py +2 -0
- sonusai/utils/get_label_names.py +20 -0
- sonusai/utils/grouper.py +6 -0
- sonusai/utils/human_readable_size.py +7 -0
- sonusai/utils/keyboard_interrupt.py +12 -0
- sonusai/utils/load_object.py +21 -0
- sonusai/utils/max_text_width.py +9 -0
- sonusai/utils/model_utils.py +28 -0
- sonusai/utils/numeric_conversion.py +11 -0
- sonusai/utils/onnx_utils.py +155 -0
- sonusai/utils/parallel.py +162 -0
- sonusai/utils/path_info.py +7 -0
- sonusai/utils/print_mixture_details.py +60 -0
- sonusai/utils/rand.py +13 -0
- sonusai/utils/ranges.py +43 -0
- sonusai/utils/read_predict_data.py +32 -0
- sonusai/utils/reshape.py +154 -0
- sonusai/utils/seconds_to_hms.py +7 -0
- sonusai/utils/stacked_complex.py +82 -0
- sonusai/utils/stratified_shuffle_split.py +170 -0
- sonusai/utils/tokenized_shell_vars.py +143 -0
- sonusai/utils/write_audio.py +26 -0
- sonusai/utils/yes_or_no.py +8 -0
- sonusai/vars.py +47 -0
- sonusai-1.0.16.dist-info/METADATA +56 -0
- sonusai-1.0.16.dist-info/RECORD +150 -0
- sonusai-1.0.16.dist-info/WHEEL +4 -0
- sonusai-1.0.16.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,365 @@
|
|
1
|
+
# mypy: ignore-errors
|
2
|
+
"""sonusai tplot
|
3
|
+
|
4
|
+
usage: tplot [-hv] [-r ROOT] [-c CONFIG] [-t TARGET] [-m MODEL] [-f FEATURE] [--sedthr SEDTHR]
|
5
|
+
|
6
|
+
options:
|
7
|
+
-h, --help
|
8
|
+
-v, --verbose Be verbose.
|
9
|
+
-r, --root ROOT Root of a gentcst tree.
|
10
|
+
-c, --config CONFIG YAML config file.
|
11
|
+
-t, --target TARGET Target .wav or .txt, else use target section in CONFIG.
|
12
|
+
-m, --model MODEL Aaware ONNX model file.
|
13
|
+
-f, --feature FEATURE Feature override, e.g., gfh64to128.
|
14
|
+
--sedthr SEDTHR SED thresholds override, e.g., '[-24, -27, -30]'.
|
15
|
+
|
16
|
+
CONFIG is used to override the default configuration, thus it does not need to be a complete
|
17
|
+
genmixdb config parameter set, only desired overrides like truth function and truth config.
|
18
|
+
|
19
|
+
A TARGET .txt file supports the same format as SonusAI genmixdb which is a list of regexes
|
20
|
+
for finding sound files.
|
21
|
+
|
22
|
+
ROOT, CONFIG, and TARGET are optional, but at least one of them must be specified.
|
23
|
+
Behavior is as follows in order of precedence:
|
24
|
+
|
25
|
+
1) If ROOT is provided, use the given directory as the root directory of
|
26
|
+
a gentcst tree. The config will be generated from the top down to the current leaf.
|
27
|
+
2) If CONFIG is provided, use the given YAML file to override the config.
|
28
|
+
3) If TARGET is provided, use the given .wav or .txt file to override the target
|
29
|
+
section of the config.
|
30
|
+
4) If FEATURE and/or SEDTHR are provided, use them to override the config.
|
31
|
+
|
32
|
+
If TARGET is given without a CONFIG, look for a corresponding YAML file to use as a
|
33
|
+
config. For example,
|
34
|
+
|
35
|
+
sonusai tplot -t 4-esc50-dogbark.txt
|
36
|
+
|
37
|
+
will first look for '4-esc50-dogbark.yml' and then for 'config.yml'. If neither
|
38
|
+
candidate was found and ROOT was also not specified then give an error. If
|
39
|
+
ROOT was specified then use the hierarchical config.
|
40
|
+
|
41
|
+
A multi-page plot TARGET-tplot.pdf or CONFIG-tplot.pdf is generated.
|
42
|
+
|
43
|
+
"""
|
44
|
+
|
45
|
+
import signal
|
46
|
+
|
47
|
+
|
48
|
+
def signal_handler(_sig, _frame):
|
49
|
+
import sys
|
50
|
+
|
51
|
+
from sonusai import logger
|
52
|
+
|
53
|
+
logger.info("Canceled due to keyboard interrupt")
|
54
|
+
sys.exit(1)
|
55
|
+
|
56
|
+
|
57
|
+
signal.signal(signal.SIGINT, signal_handler)
|
58
|
+
|
59
|
+
|
60
|
+
# TODO: re-work for modern mixdb API
|
61
|
+
def tplot(
|
62
|
+
root: str | None = None,
|
63
|
+
config_file: str | None = None,
|
64
|
+
target_file: str | None = None,
|
65
|
+
model_file: str | None = None,
|
66
|
+
feature: str | None = None,
|
67
|
+
thresholds: str | None = None,
|
68
|
+
verbose: bool = False,
|
69
|
+
) -> None:
|
70
|
+
import json
|
71
|
+
import os
|
72
|
+
|
73
|
+
import matplotlib.pyplot as plt
|
74
|
+
import numpy as np
|
75
|
+
import yaml
|
76
|
+
from matplotlib.backends.backend_pdf import PdfPages
|
77
|
+
from pyaaware import Predict
|
78
|
+
|
79
|
+
import sonusai
|
80
|
+
from sonusai import SonusAIError
|
81
|
+
from sonusai import logger
|
82
|
+
from sonusai.genft import genft
|
83
|
+
from sonusai.genmix import genmix
|
84
|
+
from sonusai.genmixdb import genmixdb
|
85
|
+
from sonusai.mixture import get_default_config
|
86
|
+
from sonusai.mixture import update_config_from_file
|
87
|
+
from sonusai.mixture import update_config_from_hierarchy
|
88
|
+
|
89
|
+
figsize = (11, 8.5)
|
90
|
+
|
91
|
+
if config_file is None and target_file is None and root is None:
|
92
|
+
raise SonusAIError("Error: No config provided.")
|
93
|
+
|
94
|
+
target_path = ""
|
95
|
+
config = get_default_config()
|
96
|
+
|
97
|
+
if root is not None:
|
98
|
+
leaf = os.getcwd()
|
99
|
+
target_path = os.path.basename(leaf)
|
100
|
+
config = update_config_from_hierarchy(root=root, leaf=leaf, config=config)
|
101
|
+
logger.debug(f"Hierarchical config for {leaf} using {root} as the root")
|
102
|
+
|
103
|
+
if config_file is not None:
|
104
|
+
target_path = config_file
|
105
|
+
config = update_config_from_file(config_file, config)
|
106
|
+
logger.debug(f"Config from {config_file}")
|
107
|
+
|
108
|
+
if target_file is not None:
|
109
|
+
target_path = target_file
|
110
|
+
if not os.path.exists(target_file):
|
111
|
+
raise SonusAIError(f"{target_file} does not exist.")
|
112
|
+
|
113
|
+
config["targets"] = [{"name": target_file}]
|
114
|
+
logger.debug(f"Targets from {target_file}")
|
115
|
+
|
116
|
+
if config_file is None:
|
117
|
+
target_config = f"{os.path.splitext(target_file)[0]}.yml"
|
118
|
+
if os.path.exists(target_config):
|
119
|
+
config = update_config_from_file(target_config, config)
|
120
|
+
logger.debug(f"Config from {target_config}")
|
121
|
+
else:
|
122
|
+
target_config = "config.yml"
|
123
|
+
if os.path.exists(target_config):
|
124
|
+
config = update_config_from_file(target_config, config)
|
125
|
+
logger.debug(f"Config from {target_config}")
|
126
|
+
elif root is None:
|
127
|
+
raise SonusAIError(f"Error: Could not determine config for {target_file}.")
|
128
|
+
|
129
|
+
file_base = os.path.splitext(target_path)[0]
|
130
|
+
file_name = os.path.split(file_base)[1]
|
131
|
+
output = f"./{file_name}-tplot.pdf"
|
132
|
+
|
133
|
+
if len(config["truth_settings"]) > 1:
|
134
|
+
raise SonusAIError("Number of truth_settings is more than one. This is not supported yet.")
|
135
|
+
|
136
|
+
if thresholds is not None:
|
137
|
+
thresholds = json.loads(thresholds)
|
138
|
+
if thresholds != config["truth_settings"][0]["config"]["thresholds"]:
|
139
|
+
config["truth_settings"][0]["config"]["thresholds"] = thresholds
|
140
|
+
logger.debug(f"Override SED thresholds with {thresholds}")
|
141
|
+
|
142
|
+
if feature is not None and feature != config["feature"]:
|
143
|
+
config["feature"] = feature
|
144
|
+
logger.debug(f"Override feature with {feature}")
|
145
|
+
|
146
|
+
logger.debug("")
|
147
|
+
|
148
|
+
# Run genmixdb, genmix, and genft
|
149
|
+
mixdb = genmixdb(config=config, logging=verbose)
|
150
|
+
num_mixtures = mixdb.num_mixtures # Number of mixtures
|
151
|
+
logger.info(f"Generating data for {num_mixtures} mixture plots")
|
152
|
+
audio_data = genmix(
|
153
|
+
mixdb=mixdb,
|
154
|
+
compute_segsnr=False,
|
155
|
+
compute_truth=False,
|
156
|
+
)
|
157
|
+
feature_data = genft(mixdb=mixdb, compute_segsnr=False)
|
158
|
+
|
159
|
+
# If model provided, read and check it
|
160
|
+
predict_data = np.zeros(0)
|
161
|
+
if model_file is not None:
|
162
|
+
import onnx
|
163
|
+
|
164
|
+
# model is an in-memory ModelProto
|
165
|
+
model = onnx.load(model_file)
|
166
|
+
if len(model.metadata_props) < 5:
|
167
|
+
logger.warn("Model metadata indicates this is not an Aaware model, ignoring.")
|
168
|
+
else:
|
169
|
+
if model.metadata_props[4].key != "feature":
|
170
|
+
logger.warn("Model metadata does not have Aaware feature, ignoring.")
|
171
|
+
else:
|
172
|
+
model_feature = model.metadata_props[4].value
|
173
|
+
logger.debug(f"Model feature is {model_feature}")
|
174
|
+
# TODO Check and read other params, flatten, addch, etc.
|
175
|
+
logger.info(f"Running prediction with {model_file}")
|
176
|
+
predict = Predict(model_file)
|
177
|
+
predict_data = predict.execute(feature_data.feature)
|
178
|
+
|
179
|
+
num_samples = audio_data.mixture.shape[0] # Total number of samples over all mixtures
|
180
|
+
num_features = feature_data.feature.shape[0] # Total number of feature frames over all mixtures
|
181
|
+
|
182
|
+
logger.info(f"Plotting {num_mixtures} target-truth results to {output}")
|
183
|
+
pdf = PdfPages(f"{output}")
|
184
|
+
for m in range(num_mixtures):
|
185
|
+
mixture_begin = mixdb["mixtures"][m]["i_sample_offset"]
|
186
|
+
feature_begin = mixdb["mixtures"][m]["o_frame_offset"]
|
187
|
+
# For each target/mixture, get index endpoint (mix,noise,target sample,...)
|
188
|
+
if m == num_mixtures - 1:
|
189
|
+
mixture_end = num_samples
|
190
|
+
feature_end = num_features
|
191
|
+
else:
|
192
|
+
mixture_end = mixdb["mixtures"][m + 1]["i_sample_offset"]
|
193
|
+
# out frames are possibly decimated/stride-combined
|
194
|
+
feature_end = mixdb["mixtures"][m + 1]["o_frame_offset"]
|
195
|
+
|
196
|
+
# Trim waveform data
|
197
|
+
mixture_trimmed = audio_data.mixture[mixture_begin:mixture_end]
|
198
|
+
target_trimmed = sum(audio_data.targets)[mixture_begin:mixture_end]
|
199
|
+
|
200
|
+
# Provide subset defined by mixture using truth_index array of indices (multichannel truth)
|
201
|
+
target_record = mixdb["targets"][mixdb["mixtures"][m]["target_id"]]
|
202
|
+
truth_settings = target_record["truth_settings"]
|
203
|
+
if len(truth_settings) > 1:
|
204
|
+
raise SonusAIError("Number of truth_settings is more than one. This is not supported yet.")
|
205
|
+
|
206
|
+
truth_index = np.array(truth_settings[0]["index"]) - 1
|
207
|
+
truth_f_trimmed = feature_data.truth_f[feature_begin:feature_end, truth_index]
|
208
|
+
|
209
|
+
if predict_data.shape[0] > 0:
|
210
|
+
predict_data_trimmed = predict_data[feature_begin:feature_end, :]
|
211
|
+
# Prediction Activity analysis to select top prediction class
|
212
|
+
# true if active in any frame
|
213
|
+
predict_activity = np.any(predict_data_trimmed >= mixdb["class_weights_threshold"], axis=0)
|
214
|
+
predict_activity_index = np.array([i for i, x in enumerate(predict_activity) if x]) + 1
|
215
|
+
logger.info(
|
216
|
+
f'Prediction active in classes based on threshold {mixdb["class_weights_threshold"]}:\n'
|
217
|
+
f'{predict_activity_index}'
|
218
|
+
)
|
219
|
+
predict_mean = np.mean(predict_data_trimmed, axis=0)
|
220
|
+
top_active_classes = np.argsort(predict_mean)[::-1] + 1
|
221
|
+
logger.info(f"Top 10 active prediction classes by mean:\n{top_active_classes[0:10]}")
|
222
|
+
# plot most active prediction
|
223
|
+
predict_data_trimmed = predict_data_trimmed[:, top_active_classes[0] - 1]
|
224
|
+
logger.info(f"Plotting prediction class {top_active_classes[0]}")
|
225
|
+
|
226
|
+
# Setup plot of target waveform with truth on top
|
227
|
+
# TODO
|
228
|
+
# Make a function w/args mixture_trimmed, target_trimmed, truth_f, pr, mixdat, m, truth_index, target_path
|
229
|
+
# calculate number of samples per frame for plotting
|
230
|
+
num_plot_features = truth_f_trimmed.shape[0]
|
231
|
+
num_plot_samples_per_feature = len(target_trimmed) // num_plot_features
|
232
|
+
# number of plot samples multiple of frames
|
233
|
+
num_plot_samples = num_plot_samples_per_feature * num_plot_features
|
234
|
+
# x-axis in sec
|
235
|
+
x_seconds = np.arange(num_plot_samples, dtype=np.float32) / sonusai.mixture.SAMPLE_RATE
|
236
|
+
# Reshape/extend truth to #samples in waveform
|
237
|
+
num_plot_classes = truth_f_trimmed.shape[1] # Number of plot truth classes
|
238
|
+
y_truth_f = np.reshape(
|
239
|
+
np.tile(np.expand_dims(truth_f_trimmed, 1), [1, num_plot_samples_per_feature, 1]),
|
240
|
+
[num_plot_samples, num_plot_classes],
|
241
|
+
)
|
242
|
+
|
243
|
+
fig, ax0 = plt.subplots(1, 1, constrained_layout=True, figsize=figsize)
|
244
|
+
ax = np.array([ax0], dtype=object)
|
245
|
+
plots = []
|
246
|
+
|
247
|
+
# Plot the time-domain waveforms then truth/prediction on second axis
|
248
|
+
if mixture_trimmed.shape[0] > 0:
|
249
|
+
color = "mistyrose"
|
250
|
+
(mix_plot,) = ax[0].plot(x_seconds, mixture_trimmed[0:num_plot_samples], color=color, label="MIX")
|
251
|
+
ax[0].tick_params(axis="y", labelcolor="red")
|
252
|
+
plots.append(mix_plot)
|
253
|
+
|
254
|
+
if target_trimmed.shape[0] > 0:
|
255
|
+
color = "tab:blue"
|
256
|
+
(tt_plot,) = ax[0].plot(x_seconds, target_trimmed[0:num_plot_samples], color=color, label="TAR")
|
257
|
+
ax[0].set_ylabel("ampl", color=color)
|
258
|
+
ax[0].tick_params(axis="y", labelcolor=color)
|
259
|
+
plots.append(tt_plot)
|
260
|
+
|
261
|
+
ax2 = ax[0].twinx() # instantiate 2nd y-axis that shares the same x-axis
|
262
|
+
|
263
|
+
# Plot first truth
|
264
|
+
# TODO Support multi-channel
|
265
|
+
if truth_f_trimmed.shape[0] > 0:
|
266
|
+
color = "tab:green"
|
267
|
+
label2 = f"truth{truth_index[0] + 1}"
|
268
|
+
# we already handled the x-label with ax1
|
269
|
+
ax2.set_ylabel(label2, color=color)
|
270
|
+
# logger.info(f'Mixture num {m}, truth_index={truth_index}')
|
271
|
+
(tr_plot,) = ax2.plot(x_seconds, y_truth_f[:, 0], color=color, label=label2)
|
272
|
+
ax2.set_ylim([-0.05, 1.05])
|
273
|
+
ax2.tick_params(axis="y", labelcolor=color)
|
274
|
+
plots.append(tr_plot)
|
275
|
+
|
276
|
+
if predict_data.shape[0] > 0:
|
277
|
+
color = "tab:brown"
|
278
|
+
label2 = f"prcl{top_active_classes[0]}"
|
279
|
+
# we already handled the x-label with ax1
|
280
|
+
ax2.set_ylabel(label2, color=color)
|
281
|
+
predict_extended = np.reshape(
|
282
|
+
np.tile(
|
283
|
+
np.expand_dims(predict_data_trimmed, 1),
|
284
|
+
[1, num_plot_samples_per_feature, 1],
|
285
|
+
),
|
286
|
+
[num_plot_samples, num_plot_classes],
|
287
|
+
)
|
288
|
+
(pr_plot,) = ax2.plot(x_seconds, predict_extended, color=color, label=label2)
|
289
|
+
ax2.set_ylim([-0.05, 1.05])
|
290
|
+
ax2.tick_params(axis="y", labelcolor=color)
|
291
|
+
plots.append(pr_plot)
|
292
|
+
|
293
|
+
ax[0].set_xlabel("time (s)") # set only on last/bottom plot
|
294
|
+
|
295
|
+
# Get actual mixture target config parameters
|
296
|
+
target_augmentations = mixdb["target_augmentations"][mixdb["mixtures"][m]["target_augmentation_index"]]
|
297
|
+
fig.suptitle(
|
298
|
+
f'{m + 1} of {num_mixtures}: {target_path}\n'
|
299
|
+
f'{target_record["name"]}\n'
|
300
|
+
f'Target augmentations: {target_augmentations}\n'
|
301
|
+
f'Truth indices: {truth_settings[0]["index"]}\n'
|
302
|
+
f'Global Truth Function:Config {truth_settings[0]["function"]} : {truth_settings[0]["config"]}',
|
303
|
+
fontsize=10,
|
304
|
+
)
|
305
|
+
pdf.savefig(fig)
|
306
|
+
plt.close(fig)
|
307
|
+
|
308
|
+
# open config file read in as text, then print to last page
|
309
|
+
last_page = plt.figure(figsize=figsize)
|
310
|
+
last_page.clf()
|
311
|
+
|
312
|
+
option_text = (
|
313
|
+
f"Function parameters:\n"
|
314
|
+
f" root {root}\n"
|
315
|
+
f" config {config_file}\n"
|
316
|
+
f" target {target_file}\n"
|
317
|
+
f" model {model_file}\n"
|
318
|
+
f" feature {feature}\n"
|
319
|
+
f" sedthr {thresholds}\n\n"
|
320
|
+
f"----------------------------------------\n\n"
|
321
|
+
)
|
322
|
+
last_page.text(
|
323
|
+
0.05,
|
324
|
+
0.95,
|
325
|
+
option_text + yaml.dump(config),
|
326
|
+
transform=last_page.transFigure,
|
327
|
+
family="monospace",
|
328
|
+
size=10,
|
329
|
+
ha="left",
|
330
|
+
va="top",
|
331
|
+
)
|
332
|
+
pdf.savefig()
|
333
|
+
plt.close()
|
334
|
+
pdf.close()
|
335
|
+
|
336
|
+
|
337
|
+
def main() -> None:
|
338
|
+
from docopt import docopt
|
339
|
+
|
340
|
+
import sonusai
|
341
|
+
from sonusai import create_file_handler
|
342
|
+
from sonusai import initial_log_messages
|
343
|
+
from sonusai import update_console_handler
|
344
|
+
from sonusai.utils.docstring import trim_docstring
|
345
|
+
|
346
|
+
args = docopt(trim_docstring(__doc__), version=sonusai.__version__, options_first=True)
|
347
|
+
|
348
|
+
verbose = args["--verbose"]
|
349
|
+
create_file_handler("tplot.log")
|
350
|
+
update_console_handler(verbose)
|
351
|
+
initial_log_messages("tplot")
|
352
|
+
|
353
|
+
tplot(
|
354
|
+
root=args["--root"],
|
355
|
+
config_file=args["--config"],
|
356
|
+
target_file=args["--target"],
|
357
|
+
model_file=args["--model"],
|
358
|
+
feature=args["--feature"],
|
359
|
+
thresholds=args["--sedthr"],
|
360
|
+
verbose=verbose,
|
361
|
+
)
|
362
|
+
|
363
|
+
|
364
|
+
if __name__ == "__main__":
|
365
|
+
main()
|
sonusai/doc.py
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
"""sonusai doc
|
2
|
+
|
3
|
+
usage: doc [-h] [TOPIC]
|
4
|
+
|
5
|
+
options:
|
6
|
+
-h, --help Display this help.
|
7
|
+
|
8
|
+
Show SonusAI documentation.
|
9
|
+
|
10
|
+
"""
|
11
|
+
|
12
|
+
|
13
|
+
def main() -> None:
|
14
|
+
from docopt import docopt
|
15
|
+
|
16
|
+
from sonusai import __version__ as sai_version
|
17
|
+
from sonusai.utils.docstring import trim_docstring
|
18
|
+
|
19
|
+
args = docopt(trim_docstring(__doc__), version=sai_version, options_first=True)
|
20
|
+
|
21
|
+
from sonusai import doc_strings
|
22
|
+
|
23
|
+
topic = args["TOPIC"]
|
24
|
+
|
25
|
+
print(f"SonusAI {sai_version} Documentation")
|
26
|
+
print("")
|
27
|
+
|
28
|
+
topics = sorted([item[4:] for item in dir(doc_strings) if item.startswith("doc_")])
|
29
|
+
|
30
|
+
if topic not in topics:
|
31
|
+
if topic is not None:
|
32
|
+
print(f"Unknown topic: {topic}")
|
33
|
+
print("")
|
34
|
+
|
35
|
+
print("Available topics:")
|
36
|
+
for item in topics:
|
37
|
+
print(f" {item}")
|
38
|
+
return
|
39
|
+
|
40
|
+
text = getattr(doc_strings, "doc_" + topic)()
|
41
|
+
print(text[1:])
|
42
|
+
|
43
|
+
|
44
|
+
if __name__ == "__main__":
|
45
|
+
from sonusai import exception_handler
|
46
|
+
from sonusai.utils.keyboard_interrupt import register_keyboard_interrupt
|
47
|
+
|
48
|
+
register_keyboard_interrupt()
|
49
|
+
try:
|
50
|
+
main()
|
51
|
+
except Exception as e:
|
52
|
+
exception_handler(e)
|
@@ -0,0 +1 @@
|
|
1
|
+
from .doc_strings import * # noqa: F403
|