asigalov61 commited on
Commit
f2fd65a
·
verified ·
1 Parent(s): 705a89e

Upload 2 files

Browse files
Files changed (2) hide show
  1. TMIDIX.py +195 -15
  2. TPLOTS.py +168 -15
TMIDIX.py CHANGED
@@ -8,7 +8,7 @@ r'''############################################################################
8
  # Tegridy MIDI X Module (TMIDI X / tee-midi eks)
9
  # Version 1.0
10
  #
11
- # NOTE: TMIDI X Module starts after the partial MIDI.py module @ line 1342
12
  #
13
  # Based upon MIDI.py module v.6.7. by Peter Billam / pjb.com.au
14
  #
@@ -21,19 +21,19 @@ r'''############################################################################
21
  #
22
  ###################################################################################
23
  ###################################################################################
24
- # Copyright 2025 Project Los Angeles / Tegridy Code
25
  #
26
- # Licensed under the Apache License, Version 2.0 (the "License");
27
- # you may not use this file except in compliance with the License.
28
- # You may obtain a copy of the License at
29
  #
30
- # http://www.apache.org/licenses/LICENSE-2.0
31
  #
32
- # Unless required by applicable law or agreed to in writing, software
33
- # distributed under the License is distributed on an "AS IS" BASIS,
34
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
35
- # See the License for the specific language governing permissions and
36
- # limitations under the License.
37
  ###################################################################################
38
  ###################################################################################
39
  #
@@ -1446,8 +1446,9 @@ def _encode(events_lol, unknown_callback=None, never_add_eot=False,
1446
  # pjb.com.au
1447
  #
1448
  # Project Los Angeles
1449
- # Tegridy Code 2021
1450
- # https://github.com/Tegridy-Code/Project-Los-Angeles
 
1451
  #
1452
  ###################################################################################
1453
  ###################################################################################
@@ -1490,6 +1491,10 @@ import math
1490
 
1491
  import matplotlib.pyplot as plt
1492
 
 
 
 
 
1493
  ###################################################################################
1494
  #
1495
  # Original TMIDI Tegridy helper functions
@@ -11182,7 +11187,182 @@ def rle_decode_ones(encoding, size=(128, 128)):
11182
  return matrix
11183
 
11184
  ###################################################################################
11185
- #
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11186
  # This is the end of the TMIDI X Python module
11187
- #
11188
  ###################################################################################
 
8
  # Tegridy MIDI X Module (TMIDI X / tee-midi eks)
9
  # Version 1.0
10
  #
11
+ # NOTE: TMIDI X Module starts after the partial MIDI.py module @ line 1438
12
  #
13
  # Based upon MIDI.py module v.6.7. by Peter Billam / pjb.com.au
14
  #
 
21
  #
22
  ###################################################################################
23
  ###################################################################################
24
+ # Copyright 2025 Project Los Angeles / Tegridy Code
25
  #
26
+ # Licensed under the Apache License, Version 2.0 (the "License");
27
+ # you may not use this file except in compliance with the License.
28
+ # You may obtain a copy of the License at
29
  #
30
+ # http://www.apache.org/licenses/LICENSE-2.0
31
  #
32
+ # Unless required by applicable law or agreed to in writing, software
33
+ # distributed under the License is distributed on an "AS IS" BASIS,
34
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
35
+ # See the License for the specific language governing permissions and
36
+ # limitations under the License.
37
  ###################################################################################
38
  ###################################################################################
39
  #
 
1446
  # pjb.com.au
1447
  #
1448
  # Project Los Angeles
1449
+ # Tegridy Code 2025
1450
+ #
1451
+ # https://github.com/Tegridy-Code/Project-Los-Angeles
1452
  #
1453
  ###################################################################################
1454
  ###################################################################################
 
1491
 
1492
  import matplotlib.pyplot as plt
1493
 
1494
+ import psutil
1495
+
1496
+ from collections import defaultdict
1497
+
1498
  ###################################################################################
1499
  #
1500
  # Original TMIDI Tegridy helper functions
 
11187
  return matrix
11188
 
11189
  ###################################################################################
11190
+
11191
+ def vertical_list_search(list_of_lists, trg_list):
11192
+
11193
+ src_list = list_of_lists
11194
+
11195
+ if not src_list or not trg_list:
11196
+ return []
11197
+
11198
+ num_rows = len(src_list)
11199
+ k = len(trg_list)
11200
+
11201
+ row_sets = [set(row) for row in src_list]
11202
+
11203
+ results = []
11204
+
11205
+ for start in range(num_rows - k + 1):
11206
+ valid = True
11207
+
11208
+ for offset, target in enumerate(trg_list):
11209
+
11210
+ if target not in row_sets[start + offset]:
11211
+ valid = False
11212
+ break
11213
+
11214
+ if valid:
11215
+ results.append(list(range(start, start + k)))
11216
+
11217
+ return results
11218
+
11219
+ ###################################################################################
11220
+
11221
+ def smooth_values(values, window_size=3):
11222
+
11223
+ smoothed = []
11224
+
11225
+ for i in range(len(values)):
11226
+
11227
+ start = max(0, i - window_size // 2)
11228
+ end = min(len(values), i + window_size // 2 + 1)
11229
+
11230
+ window = values[start:end]
11231
+
11232
+ smoothed.append(int(sum(window) / len(window)))
11233
+
11234
+ return smoothed
11235
+
11236
+ ###################################################################################
11237
+
11238
+ def is_mostly_wide_peaks_and_valleys(values,
11239
+ min_range=32,
11240
+ threshold=0.7,
11241
+ smoothing_window=5
11242
+ ):
11243
+
11244
+ if not values:
11245
+ return False
11246
+
11247
+ smoothed_values = smooth_values(values, smoothing_window)
11248
+
11249
+ value_range = max(smoothed_values) - min(smoothed_values)
11250
+
11251
+ if value_range < min_range:
11252
+ return False
11253
+
11254
+ if all(v == smoothed_values[0] for v in smoothed_values):
11255
+ return False
11256
+
11257
+ trend_types = []
11258
+
11259
+ for i in range(1, len(smoothed_values)):
11260
+ if smoothed_values[i] > smoothed_values[i - 1]:
11261
+ trend_types.append(1)
11262
+
11263
+ elif smoothed_values[i] < smoothed_values[i - 1]:
11264
+ trend_types.append(-1)
11265
+
11266
+ else:
11267
+ trend_types.append(0)
11268
+
11269
+ trend_count = trend_types.count(1) + trend_types.count(-1)
11270
+
11271
+ proportion = trend_count / len(trend_types)
11272
+
11273
+ return proportion >= threshold
11274
+
11275
+ ###################################################################################
11276
+
11277
+ def system_memory_utilization(return_dict=False):
11278
+
11279
+ if return_dict:
11280
+ return dict(psutil.virtual_memory()._asdict())
11281
+
11282
+ else:
11283
+ print('RAM memory % used:', psutil.virtual_memory()[2])
11284
+ print('RAM Used (GB):', psutil.virtual_memory()[3]/(1024**3))
11285
+
11286
+ ###################################################################################
11287
+
11288
+ def create_files_list(datasets_paths=['./'],
11289
+ files_exts=['.mid', '.midi', '.kar', '.MID', '.MIDI', '.KAR'],
11290
+ randomize_files_list=True,
11291
+ verbose=True
11292
+ ):
11293
+ if verbose:
11294
+ print('=' * 70)
11295
+ print('Searching for files...')
11296
+ print('This may take a while on a large dataset in particular...')
11297
+ print('=' * 70)
11298
+
11299
+ filez_set = defaultdict(None)
11300
+
11301
+ files_exts = tuple(files_exts)
11302
+
11303
+ for dataset_addr in tqdm.tqdm(datasets_paths):
11304
+ for dirpath, dirnames, filenames in os.walk(dataset_addr):
11305
+ for file in filenames:
11306
+ if file not in filez_set and file.endswith(files_exts):
11307
+ filez_set[os.path.join(dirpath, file)] = None
11308
+
11309
+ filez = list(filez_set.keys())
11310
+
11311
+ if verbose:
11312
+ print('Done!')
11313
+ print('=' * 70)
11314
+
11315
+ if filez:
11316
+ if randomize_files_list:
11317
+
11318
+ if verbose:
11319
+ print('Randomizing file list...')
11320
+
11321
+ random.shuffle(filez)
11322
+
11323
+ if verbose:
11324
+ print('Done!')
11325
+ print('=' * 70)
11326
+
11327
+ if verbose:
11328
+ print('Found', len(filez), 'files.')
11329
+ print('=' * 70)
11330
+
11331
+ else:
11332
+ if verbose:
11333
+ print('Could not find any files...')
11334
+ print('Please check dataset dirs and files extensions...')
11335
+ print('=' * 70)
11336
+
11337
+ return filez
11338
+
11339
+ ###################################################################################
11340
+
11341
+ def has_consecutive_trend(nums, count):
11342
+
11343
+ if len(nums) < count:
11344
+ return False
11345
+
11346
+ increasing_streak = 1
11347
+ decreasing_streak = 1
11348
+
11349
+ for i in range(1, len(nums)):
11350
+ if nums[i] > nums[i - 1]:
11351
+ increasing_streak += 1
11352
+ decreasing_streak = 1
11353
+
11354
+ elif nums[i] < nums[i - 1]:
11355
+ decreasing_streak += 1
11356
+ increasing_streak = 1
11357
+
11358
+ else:
11359
+ increasing_streak = decreasing_streak = 1
11360
+
11361
+ if increasing_streak == count or decreasing_streak == count:
11362
+ return True
11363
+
11364
+ return False
11365
+
11366
+ ###################################################################################
11367
  # This is the end of the TMIDI X Python module
 
11368
  ###################################################################################
TPLOTS.py CHANGED
@@ -4,12 +4,12 @@ r'''############################################################################
4
  ################################################################################
5
  #
6
  #
7
- # Tegridy Plots Python Module (TPLOTS)
8
- # Version 1.0
9
  #
10
- # Project Los Angeles
11
  #
12
- # Tegridy Code 2024
13
  #
14
  # https://github.com/asigalov61/tegridy-tools
15
  #
@@ -33,20 +33,20 @@ r'''############################################################################
33
  ################################################################################
34
  ################################################################################
35
  #
36
- # Critical dependencies
37
  #
38
- # !pip install numpy
39
- # !pip install scipy
40
- # !pip install matplotlib
41
- # !pip install networkx
42
- # !pip3 install scikit-learn
43
  #
44
  ################################################################################
45
  #
46
- # Future critical dependencies
47
  #
48
- # !pip install umap-learn
49
- # !pip install alphashape
50
  #
51
  ################################################################################
52
  '''
@@ -1254,6 +1254,113 @@ def plot_parsons_code(parsons_code,
1254
 
1255
  plt.close()
1256
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1257
  ################################################################################
1258
  # [WIP] Future dev functions
1259
  ################################################################################
@@ -1363,7 +1470,53 @@ plt.show()
1363
  '''
1364
 
1365
  ################################################################################
1366
- #
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1367
  # This is the end of TPLOTS Python modules
1368
- #
1369
  ################################################################################
 
4
  ################################################################################
5
  #
6
  #
7
+ # Tegridy Plots Python Module (TPLOTS)
8
+ # Version 1.0
9
  #
10
+ # Project Los Angeles
11
  #
12
+ # Tegridy Code 2025
13
  #
14
  # https://github.com/asigalov61/tegridy-tools
15
  #
 
33
  ################################################################################
34
  ################################################################################
35
  #
36
+ # Critical dependencies
37
  #
38
+ # !pip install numpy==1.24.4
39
+ # !pip install scipy
40
+ # !pip install matplotlib
41
+ # !pip install networkx
42
+ # !pip3 install scikit-learn
43
  #
44
  ################################################################################
45
  #
46
+ # Future critical dependencies
47
  #
48
+ # !pip install umap-learn
49
+ # !pip install alphashape
50
  #
51
  ################################################################################
52
  '''
 
1254
 
1255
  plt.close()
1256
 
1257
+ ################################################################################
1258
+
1259
+ def plot_tokens_embeddings_constellation(tokens_embeddings,
1260
+ start_token,
1261
+ end_token,
1262
+ plot_size=(10, 10),
1263
+ labels_size=12,
1264
+ show_grid=False,
1265
+ save_plot=''):
1266
+
1267
+ """
1268
+ Plots token embeddings constellation using MST and graph layout
1269
+ without dimensionality reduction.
1270
+ """
1271
+
1272
+ distance_matrix = metrics.pairwise_distances(tokens_embeddings[start_token:end_token], metric='cosine')
1273
+
1274
+ token_labels = [str(i) for i in range(start_token, end_token)]
1275
+
1276
+ mst = minimum_spanning_tree(distance_matrix).toarray()
1277
+
1278
+ n = distance_matrix.shape[0]
1279
+ G = nx.Graph()
1280
+
1281
+ for i in range(n):
1282
+ for j in range(n):
1283
+ if mst[i, j] > 0:
1284
+ weight = 1 / (distance_matrix[i, j] + 1e-8)
1285
+ G.add_edge(i, j, weight=weight)
1286
+
1287
+ pos = nx.kamada_kawai_layout(G, weight='weight')
1288
+
1289
+ points = np.array([pos[i] for i in range(n)])
1290
+
1291
+ plt.figure(figsize=plot_size)
1292
+ plt.scatter(points[:, 0], points[:, 1], color='blue')
1293
+
1294
+ for i, label in enumerate(token_labels):
1295
+ plt.annotate(label, (points[i, 0], points[i, 1]),
1296
+ textcoords="offset points",
1297
+ xytext=(0, 10),
1298
+ ha='center',
1299
+ fontsize=labels_size)
1300
+
1301
+ for i in range(n):
1302
+ for j in range(n):
1303
+ if mst[i, j] > 0:
1304
+ plt.plot([points[i, 0], points[j, 0]],
1305
+ [points[i, 1], points[j, 1]],
1306
+ 'k--', alpha=0.5)
1307
+
1308
+ plt.title('Token Embeddings Constellation with MST', fontsize=labels_size)
1309
+ plt.grid(show_grid)
1310
+
1311
+ if save_plot:
1312
+ plt.savefig(save_plot, bbox_inches="tight")
1313
+ plt.close()
1314
+
1315
+ else:
1316
+ plt.show()
1317
+
1318
+ plt.close()
1319
+
1320
+ ################################################################################
1321
+
1322
+ def find_token_path(tokens_embeddings,
1323
+ start_token,
1324
+ end_token,
1325
+ verbose=False
1326
+ ):
1327
+
1328
+ """
1329
+ Finds the path of tokens between start_token and end_token using
1330
+ the Minimum Spanning Tree (MST) derived from the distance matrix.
1331
+ """
1332
+
1333
+ distance_matrix = metrics.pairwise_distances(tokens_embeddings, metric='cosine')
1334
+
1335
+ token_labels = [str(i) for i in range(len(distance_matrix))]
1336
+
1337
+ if verbose:
1338
+ print('Total number of tokens:', len(distance_matrix))
1339
+
1340
+ mst = minimum_spanning_tree(distance_matrix).toarray()
1341
+
1342
+ n = distance_matrix.shape[0]
1343
+ G = nx.Graph()
1344
+
1345
+ for i in range(n):
1346
+ for j in range(n):
1347
+ if mst[i, j] > 0:
1348
+ weight = 1 / (distance_matrix[i, j] + 1e-8)
1349
+ G.add_edge(i, j, weight=weight)
1350
+
1351
+ try:
1352
+ start_idx = token_labels.index(str(start_token))
1353
+ end_idx = token_labels.index(str(end_token))
1354
+
1355
+ except ValueError:
1356
+ raise ValueError("Start or end token not found in the provided token labels.")
1357
+
1358
+ path_indices = nx.shortest_path(G, source=start_idx, target=end_idx)
1359
+
1360
+ token_path = [int(token_labels[idx]) for idx in path_indices]
1361
+
1362
+ return token_path
1363
+
1364
  ################################################################################
1365
  # [WIP] Future dev functions
1366
  ################################################################################
 
1470
  '''
1471
 
1472
  ################################################################################
1473
+
1474
+ def plot_tree_horizontal(data):
1475
+
1476
+ """
1477
+ Given data as a list of levels (each level is a tuple or list of
1478
+ displacements for each branch), this function computes the cumulative
1479
+ value per branch (starting from 0) and plots each branch
1480
+ with the tree level mapped to the x-axis and the cumulative value mapped
1481
+ to the y-axis. This gives a left-to-right tree with branches spanning up
1482
+ (positive) and down (negative).
1483
+
1484
+ Parameters:
1485
+ data (list of tuple/list): Each element represents a tree level.
1486
+ It is assumed every level has the same length.
1487
+ """
1488
+
1489
+ # Convert data to a NumPy array with shape (n_levels, n_branches)
1490
+ data = np.array(data)
1491
+ n_levels, n_branches = data.shape
1492
+
1493
+ # Compute cumulative sums along each branch.
1494
+ # Each branch starts at 0 at level 0.
1495
+ cum = np.zeros((n_levels + 1, n_branches))
1496
+ for i in range(n_levels):
1497
+ cum[i + 1, :] = cum[i, :] + data[i, :]
1498
+
1499
+ plt.figure(figsize=(12, 8))
1500
+
1501
+ # Plot each branch as a line. For branch j:
1502
+ # - x coordinates are the tree levels (0 to n_levels)
1503
+ # - y coordinates are the corresponding cumulative values.
1504
+ for j in range(n_branches):
1505
+ x = np.arange(n_levels + 1)
1506
+ y = cum[:, j]
1507
+ plt.plot(x, y, marker='o', label=f'Branch {j}')
1508
+
1509
+ plt.title("Horizontal Tree Visualization: Branches Spanning Up and Down", fontsize=14)
1510
+ plt.xlabel("Tree Level (Left = Root)")
1511
+ plt.ylabel("Cumulative Value (Up = Positive, Down = Negative)")
1512
+
1513
+ # Add a horizontal line at y=0 to emphasize the center.
1514
+ plt.axhline(0, color="gray", linestyle="--")
1515
+
1516
+ #plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left')
1517
+ plt.tight_layout()
1518
+ plt.show()
1519
+
1520
+ ################################################################################
1521
  # This is the end of TPLOTS Python modules
 
1522
  ################################################################################