arcan3 commited on
Commit
7d492c9
·
1 Parent(s): b37ce89

added alternative#

Browse files
Files changed (2) hide show
  1. app.py +54 -4
  2. funcs/som.py +40 -0
app.py CHANGED
@@ -4,9 +4,12 @@ import csv
4
  import json
5
  import torch
6
  import numpy as np
 
7
  import gradio as gr
8
 
9
  from phate import PHATEAE
 
 
10
  from funcs.som import ClusterSOM
11
  from funcs.tools import numpy_to_native
12
 
@@ -14,6 +17,7 @@ from funcs.processor import process_data
14
  from funcs.plot_func import plot_sensor_data_from_json
15
  from funcs.dataloader import BaseDataset2, read_json_files
16
 
 
17
  DEVICE = torch.device("cpu")
18
  reducer10d = PHATEAE(epochs=30, n_components=10, lr=.0001, batch_size=128, t='auto', knn=8, relax=True, metric='euclidean')
19
  reducer10d.load('models/r10d_6.pth')
@@ -133,6 +137,43 @@ def process_som_data(data, prediction):
133
 
134
  return processed_data
135
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  def get_som_mp4_v2(csv_file_box, slice_size_slider, sample_rate, window_size_slider, reducer=reducer10d, cluster=cluster_som):
137
  processed_file_box, json_file_box, slices_per_leg, plot_box_leg, plot_box_overlay, slice_slider, plot_slice_leg, get_all_slice, slice_json_box = process_data(csv_file_box, slice_size_slider, sample_rate, window_size_slider)
138
 
@@ -161,8 +202,17 @@ def get_som_mp4_v2(csv_file_box, slice_size_slider, sample_rate, window_size_sli
161
  prediction = cluster_som.predict(embedding10d)
162
  processed_data = process_som_data(data,prediction)
163
 
 
 
 
 
 
 
164
  # Write the processed data to a CSV file
165
- header = ['Gait', 'TS', 'State', 'Condition', 'Shape1', 'Shape2', 'Shape3', 'Shape4', 'Color1', 'Color2', 'Color3', 'Color4', 'Danger1', 'Danger2', 'Danger3', 'Danger4']
 
 
 
166
  with open('animation_table.csv', 'w', newline='') as csvfile:
167
  csv_writer = csv.writer(csvfile)
168
  csv_writer.writerow(header)
@@ -174,7 +224,7 @@ def get_som_mp4_v2(csv_file_box, slice_size_slider, sample_rate, window_size_sli
174
  som_video = cluster.plot_activation(embedding10d)
175
  som_video.write_videofile('som_sequence.mp4')
176
 
177
- return processed_file_box, json_file_box, slices_per_leg, plot_box_leg, plot_box_overlay, slice_slider, plot_slice_leg, get_all_slice, slice_json_box, 'som_sequence.mp4', 'animation.mp4'
178
  return processed_file_box, json_file_box, slices_per_leg, plot_box_leg, plot_box_overlay, slice_slider, plot_slice_leg, get_all_slice, slice_json_box, 'som_sequence.mp4', None
179
 
180
  # ml inference
@@ -232,7 +282,7 @@ with gr.Blocks(title='Cabasus') as cabasus_sensor:
232
 
233
  with gr.Row():
234
  real_video = gr.Video(label='real video')
235
- trend_graph = gr.Video(label='trend graph')
236
 
237
  plot_box_leg = gr.Plot(label="Filtered Signal Plot")
238
  slice_slider = gr.Slider(minimum=1, maximum=300, label='Slice select', step=1)
@@ -282,7 +332,7 @@ with gr.Blocks(title='Cabasus') as cabasus_sensor:
282
  #redoing the whole calculation with the file loading
283
  csv_file_box.change(get_som_mp4_v2, inputs=[csv_file_box, slice_size_slider, sample_rate, window_size_slider],
284
  outputs=[processed_file_box, json_file_box, slices_per_leg, plot_box_leg, plot_box_overlay, slice_slider, plot_slice_leg, get_all_slice, slice_json_box,
285
- activation_video, animation])
286
 
287
  button_label_Add.click(attach_label_to_json, inputs=[slice_json_box, label_name], outputs=[slice_json_label_box])
288
 
 
4
  import json
5
  import torch
6
  import numpy as np
7
+ import pandas as pd
8
  import gradio as gr
9
 
10
  from phate import PHATEAE
11
+ from pytvlwcharts import *
12
+ from pandas import Timestamp
13
  from funcs.som import ClusterSOM
14
  from funcs.tools import numpy_to_native
15
 
 
17
  from funcs.plot_func import plot_sensor_data_from_json
18
  from funcs.dataloader import BaseDataset2, read_json_files
19
 
20
+
21
  DEVICE = torch.device("cpu")
22
  reducer10d = PHATEAE(epochs=30, n_components=10, lr=.0001, batch_size=128, t='auto', knn=8, relax=True, metric='euclidean')
23
  reducer10d.load('models/r10d_6.pth')
 
137
 
138
  return processed_data
139
 
140
+ def scores_to_dataframe(scores, start_time='2022-07-01 09:15:00+05:30', start_score=100, none_replacement=-0):
141
+ # Create a timestamp for every score in the list
142
+ timestamps = [pd.Timestamp(start_time) + pd.Timedelta(seconds=i) for i in range(len(scores))]
143
+
144
+ # Convert timestamps to unix timestamps
145
+ unix_timestamps = [int(ts.value // 10**9) for ts in timestamps]
146
+
147
+ # Initialize open prices list
148
+ open_prices = [start_score]
149
+
150
+ # Calculate open and close prices
151
+ for i in range(1, len(scores)):
152
+ if scores[i-1] is not None:
153
+ open_prices.append(open_prices[i-1] + scores[i-1])
154
+ else:
155
+ open_prices.append(open_prices[i-1])
156
+
157
+ close_prices = [open + (score if score is not None else none_replacement) for open, score in zip(open_prices, scores)]
158
+
159
+ # Create high and low prices
160
+ high_prices = [max(open, close) for open, close in zip(open_prices, close_prices)]
161
+ low_prices = [min(open, close) for open, close in zip(open_prices, close_prices)]
162
+
163
+ # Create a dataframe
164
+ df = pd.DataFrame({
165
+ 'time': unix_timestamps,
166
+ 'open': open_prices,
167
+ 'high': high_prices,
168
+ 'low': low_prices,
169
+ 'close': close_prices
170
+ })
171
+
172
+ # Start index from 1
173
+ df.index += 1
174
+
175
+ return df
176
+
177
  def get_som_mp4_v2(csv_file_box, slice_size_slider, sample_rate, window_size_slider, reducer=reducer10d, cluster=cluster_som):
178
  processed_file_box, json_file_box, slices_per_leg, plot_box_leg, plot_box_overlay, slice_slider, plot_slice_leg, get_all_slice, slice_json_box = process_data(csv_file_box, slice_size_slider, sample_rate, window_size_slider)
179
 
 
202
  prediction = cluster_som.predict(embedding10d)
203
  processed_data = process_som_data(data,prediction)
204
 
205
+ scores = cluster_som.score(embedding10d, threshold_radius=8.5)
206
+ scores_df = scores_to_dataframe(scores)
207
+ DailyChart = Chart(data=scores_df, width = 1360, height = 500,
208
+ time_scale=TimeScaleOptions(seconds_visible=True,
209
+ time_visible=True)).mark_candlestick()
210
+
211
  # Write the processed data to a CSV file
212
+ header = ['Gait', 'TS', 'State', 'Condition',
213
+ 'Shape1', 'Shape2', 'Shape3', 'Shape4',
214
+ 'Color1', 'Color2', 'Color3', 'Color4',
215
+ 'Danger1', 'Danger2', 'Danger3', 'Danger4']
216
  with open('animation_table.csv', 'w', newline='') as csvfile:
217
  csv_writer = csv.writer(csvfile)
218
  csv_writer.writerow(header)
 
224
  som_video = cluster.plot_activation(embedding10d)
225
  som_video.write_videofile('som_sequence.mp4')
226
 
227
+ return processed_file_box, json_file_box, slices_per_leg, plot_box_leg, plot_box_overlay, slice_slider, plot_slice_leg, get_all_slice, slice_json_box, 'som_sequence.mp4', 'animation.mp4', DailyChart
228
  return processed_file_box, json_file_box, slices_per_leg, plot_box_leg, plot_box_overlay, slice_slider, plot_slice_leg, get_all_slice, slice_json_box, 'som_sequence.mp4', None
229
 
230
  # ml inference
 
282
 
283
  with gr.Row():
284
  real_video = gr.Video(label='real video')
285
+ trend_graph = gr.Plot(label='trend graph')
286
 
287
  plot_box_leg = gr.Plot(label="Filtered Signal Plot")
288
  slice_slider = gr.Slider(minimum=1, maximum=300, label='Slice select', step=1)
 
332
  #redoing the whole calculation with the file loading
333
  csv_file_box.change(get_som_mp4_v2, inputs=[csv_file_box, slice_size_slider, sample_rate, window_size_slider],
334
  outputs=[processed_file_box, json_file_box, slices_per_leg, plot_box_leg, plot_box_overlay, slice_slider, plot_slice_leg, get_all_slice, slice_json_box,
335
+ activation_video, animation, trend_graph])
336
 
337
  button_label_Add.click(attach_label_to_json, inputs=[slice_json_box, label_name], outputs=[slice_json_label_box])
338
 
funcs/som.py CHANGED
@@ -65,6 +65,46 @@ class ClusterSOM:
65
  results.append((-1, None)) # Noise
66
 
67
  return results
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
 
69
  # rearranging the subplots in the closest square format
70
  def rearrange_subplots(self, num_subplots):
 
65
  results.append((-1, None)) # Noise
66
 
67
  return results
68
+
69
+ def score(self, data, midpoints=None, threshold_radius=4):
70
+ """
71
+ Compute the score for each sample in the data based on the distance of the BMU node to the closest midpoint of the SOM grid.
72
+
73
+ :param data: The input data.
74
+ :param midpoints: A dictionary with keys as the indices of the SOMs and values as lists of midpoints on the grid for the corresponding SOMs.
75
+ :param threshold_radius: The threshold radius for score calculation.
76
+ """
77
+ scores = []
78
+
79
+ for sample in data:
80
+ # Predict the cluster and BMU SOM coordinate for each sample in the data
81
+ result = self.predict([sample])[0]
82
+
83
+ # Check if it is not a noise
84
+ if result[0] != -1:
85
+ # The activated SOM's index and its corresponding BMU
86
+ activated_som_index, bmu = result[0], result[1]
87
+
88
+ # Get the corresponding SOM for the data point
89
+ som = self.som_models[activated_som_index]
90
+
91
+ # If specific midpoints are provided for SOMs, use them; else compute the midpoint of the SOM grid
92
+ if midpoints is not None and activated_som_index in midpoints:
93
+ specified_midpoints = midpoints[activated_som_index]
94
+ else:
95
+ specified_midpoints = [tuple((dim-1)/2 for dim in som.get_weights().shape[:2])]
96
+
97
+ # Compute the grid distances from the BMU to each midpoint and find the minimum distance
98
+ min_distance = min(np.sqrt((midpoint[0] - bmu[0])**2 + (midpoint[1] - bmu[1])**2) for midpoint in specified_midpoints)
99
+
100
+ # Compute the score as the minimum grid distance minus the threshold radius
101
+ score = min_distance - threshold_radius
102
+
103
+ scores.append(score)
104
+ else:
105
+ scores.append(None) # Noise
106
+
107
+ return scores
108
 
109
  # rearranging the subplots in the closest square format
110
  def rearrange_subplots(self, num_subplots):