wenjun99 commited on
Commit
54f693c
·
verified ·
1 Parent(s): 04c0614

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +64 -135
app.py CHANGED
@@ -4,7 +4,7 @@ import numpy as np
4
  import pandas as pd
5
  from streamlit_cropper import st_cropper
6
 
7
- # Predefined headers for the 32 mutation sites
8
  mutation_site_headers = [
9
  3244, 3297, 3350, 3399, 3455, 3509, 3562, 3614,
10
  3665, 3720, 3773, 3824, 3879, 3933, 3985, 4039,
@@ -12,45 +12,19 @@ mutation_site_headers = [
12
  4510, 4561, 4615, 4668, 4720, 4773, 4828, 4882
13
  ]
14
 
15
- # Load thresholds from file
16
  thresholds = pd.Series({
17
- 3244: 1.094293328,
18
- 3297: 0.924916122,
19
- 3350: 0.664586629,
20
- 3399: 0.91573613,
21
- 3455: 1.300869714,
22
- 3509: 1.821975901,
23
- 3562: 1.178862418,
24
- 3614: 0.091557752,
25
- 3665: 0.298697327,
26
- 3720: 0.58379781,
27
- 3773: 0.891088481,
28
- 3824: 1.145509641,
29
- 3879: 0.81833191,
30
- 3933: 2.93084335,
31
- 3985: 1.593758847,
32
- 4039: 0.966055013,
33
- 4089: 1.465671338,
34
- 4145: 0.30309335,
35
- 4190: 1.321615138,
36
- 4245: 1.709752495,
37
- 4298: 0.868534701,
38
- 4349: 1.222907645,
39
- 4402: 0.58873557,
40
- 4455: 1.185522985,
41
- 4510: 1.266797682,
42
- 4561: 1.109913024,
43
- 4615: 1.181106084,
44
- 4668: 1.408533949,
45
- 4720: 0.714151142,
46
- 4773: 1.471959437,
47
- 4828: 0.95879943,
48
- 4882: 1.464503885
49
  })
50
 
51
- # -----------------------------------------
52
- # Utility functions
53
- # -----------------------------------------
54
 
55
  def string_to_binary_labels(s: str) -> list[int]:
56
  bits = []
@@ -105,19 +79,14 @@ def binary_labels_to_rgb_image(binary_labels: list[int], width: int = None, heig
105
  img = Image.fromarray(array, mode='RGB')
106
  return img
107
 
108
- # -----------------------------------------
109
- # Streamlit App
110
- # -----------------------------------------
111
 
112
  st.title("ASCII & Binary Label Converter")
113
-
114
  tab1, tab2, tab3 = st.tabs(["Text to Binary Labels", "Image to Binary Labels", "EF → Binary"])
115
 
116
- # ================= Tab 1 ===================
117
  with tab1:
118
- st.write("Enter text to see its ASCII codes and corresponding binary labels:")
119
- user_input = st.text_input("Text Input", value="DNA")
120
-
121
  if user_input:
122
  ascii_codes = [ord(c) for c in user_input]
123
  binary_labels = string_to_binary_labels(user_input)
@@ -126,118 +95,78 @@ with tab1:
126
  st.write(ascii_codes)
127
 
128
  st.subheader("Binary Labels per Character")
129
- grouped_chars = [binary_labels[i:i+8] for i in range(0, len(binary_labels), 8)]
130
- for idx, bits in enumerate(grouped_chars):
131
- st.write(f"'{user_input[idx]}' → {bits}")
132
 
133
  st.subheader("Binary Labels (32-bit groups)")
134
- num_groups = (len(binary_labels) + 31) // 32
135
- table_data = []
136
- for grp_idx in range(num_groups):
137
- start = grp_idx * 32
138
- end = start + 32
139
- group = binary_labels[start:end]
140
- if len(group) < 32:
141
- group += [0] * (32 - len(group))
142
- edited_sites = sum(group)
143
- row = group + [edited_sites]
144
- table_data.append(row)
145
-
146
- df = pd.DataFrame(table_data, columns=[str(h) for h in mutation_site_headers] + ["Edited Sites"])
147
- st.dataframe(df)
148
 
149
- st.download_button(
150
- label="Download Binary Labels Table as CSV",
151
- data=df.to_csv(index=False),
152
- file_name="binary_labels_table.csv",
153
- mime="text/csv"
154
- )
155
 
156
- # ================= Tab 2 ===================
157
  with tab2:
158
- st.write("Upload an image (JPG or PNG) to convert it into binary labels:")
159
- uploaded_file = st.file_uploader("Choose an image file", type=["jpg", "jpeg", "png"])
160
-
161
- if uploaded_file is not None:
162
- img = Image.open(uploaded_file)
163
- st.image(img, caption="Uploaded Image", use_column_width=True)
164
-
165
- st.subheader("Crop the image with drag and select (Free aspect ratio)")
166
- cropped_img = st_cropper(img, realtime_update=True, box_color='blue', aspect_ratio=None)
167
 
168
- st.image(cropped_img, caption="Cropped Image", use_column_width=True)
169
-
170
- max_pixels = st.slider("Max number of pixels to encode", min_value=32, max_value=1024, value=256, step=32)
171
-
172
- binary_labels = image_to_binary_labels_rgb(cropped_img, max_pixels=max_pixels)
173
 
174
  st.subheader("Binary Labels from Image")
175
- num_groups = (len(binary_labels) + 31) // 32
176
- table_data = []
177
- for grp_idx in range(num_groups):
178
- start = grp_idx * 32
179
- end = start + 32
180
- group = binary_labels[start:end]
181
- if len(group) < 32:
182
- group += [0] * (32 - len(group))
183
- edited_sites = sum(group)
184
- row = group + [edited_sites]
185
- table_data.append(row)
186
-
187
- df = pd.DataFrame(table_data, columns=[str(h) for h in mutation_site_headers] + ["Edited Sites"])
188
  st.dataframe(df)
189
 
190
- st.subheader("Reconstructed RGB Image")
191
- reconstructed_img = binary_labels_to_rgb_image(binary_labels)
192
- st.image(reconstructed_img, caption="Reconstructed Image", use_column_width=True)
193
-
194
- st.download_button(
195
- label="Download Image Binary Labels Table as CSV",
196
- data=df.to_csv(index=False),
197
- file_name="image_binary_labels_table.csv",
198
- mime="text/csv"
199
- )
200
 
201
- # ================= Tab 3 ===================
202
  with tab3:
203
- st.write("Upload an Editing Frequency CSV or fill in manually:")
204
- ef_file = st.file_uploader("Upload Editing Frequency CSV", type=["csv"], key="ef")
205
 
206
  if ef_file:
207
  ef_df = pd.read_csv(ef_file)
208
  ef_df = ef_df.loc[:, ~ef_df.columns.str.contains('^Unnamed')]
209
  else:
210
- ef_df = pd.DataFrame(columns=thresholds.index)
211
 
212
  edited_df = st.data_editor(ef_df, num_rows="dynamic")
213
 
214
  if st.button("Convert to Binary Labels"):
215
- common_cols = list(set(map(int, edited_df.columns)) & set(thresholds.index))
216
- common_cols = list(map(str, common_cols)) # Convert back to string for use as column names
217
 
218
- numeric_cols = edited_df[common_cols].select_dtypes(include=[np.number]).columns.tolist()
219
-
220
- binary_part = edited_df[numeric_cols].ge(thresholds[numeric_cols]).astype(int)
221
- non_binary_part = edited_df.drop(columns=numeric_cols, errors='ignore')
 
 
222
  binary_df = pd.concat([non_binary_part, binary_part], axis=1)
223
-
224
- def highlight_binary(val):
225
- if val == 1:
226
- return 'background-color: lightgreen'
227
- elif val == 0:
228
- return 'background-color: lightcoral'
229
- else:
230
- return ''
231
-
232
- styled_binary_df = binary_df.style.applymap(highlight_binary, subset=numeric_cols)
233
-
234
- st.subheader("Binary Labels")
235
- st.dataframe(styled_binary_df) # ✅ Display thresholded binary table
236
 
237
- st.download_button(
238
- label="Download Binary Labels Table as CSV",
239
- data=binary_df.to_csv(index=False),
240
- file_name="ef_binary_labels_table.csv",
241
- mime="text/csv"
242
- )
243
 
 
 
 
 
 
4
  import pandas as pd
5
  from streamlit_cropper import st_cropper
6
 
7
+ # Mutation site headers
8
  mutation_site_headers = [
9
  3244, 3297, 3350, 3399, 3455, 3509, 3562, 3614,
10
  3665, 3720, 3773, 3824, 3879, 3933, 3985, 4039,
 
12
  4510, 4561, 4615, 4668, 4720, 4773, 4828, 4882
13
  ]
14
 
15
+ # Thresholds for each mutation site
16
  thresholds = pd.Series({
17
+ 3244: 1.094293328, 3297: 0.924916122, 3350: 0.664586629, 3399: 0.91573613,
18
+ 3455: 1.300869714, 3509: 1.821975901, 3562: 1.178862418, 3614: 0.091557752,
19
+ 3665: 0.298697327, 3720: 0.58379781, 3773: 0.891088481, 3824: 1.145509641,
20
+ 3879: 0.81833191, 3933: 2.93084335, 3985: 1.593758847, 4039: 0.966055013,
21
+ 4089: 1.465671338, 4145: 0.30309335, 4190: 1.321615138, 4245: 1.709752495,
22
+ 4298: 0.868534701, 4349: 1.222907645, 4402: 0.58873557, 4455: 1.185522985,
23
+ 4510: 1.266797682, 4561: 1.109913024, 4615: 1.181106084, 4668: 1.408533949,
24
+ 4720: 0.714151142, 4773: 1.471959437, 4828: 0.95879943, 4882: 1.464503885
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  })
26
 
27
+ # === Utility functions ===
 
 
28
 
29
  def string_to_binary_labels(s: str) -> list[int]:
30
  bits = []
 
79
  img = Image.fromarray(array, mode='RGB')
80
  return img
81
 
82
+ # === Streamlit App ===
 
 
83
 
84
  st.title("ASCII & Binary Label Converter")
 
85
  tab1, tab2, tab3 = st.tabs(["Text to Binary Labels", "Image to Binary Labels", "EF → Binary"])
86
 
87
+ # Tab 1: Text to Binary
88
  with tab1:
89
+ user_input = st.text_input("Enter text", value="DNA")
 
 
90
  if user_input:
91
  ascii_codes = [ord(c) for c in user_input]
92
  binary_labels = string_to_binary_labels(user_input)
 
95
  st.write(ascii_codes)
96
 
97
  st.subheader("Binary Labels per Character")
98
+ grouped = [binary_labels[i:i+8] for i in range(0, len(binary_labels), 8)]
99
+ for i, bits in enumerate(grouped):
100
+ st.write(f"'{user_input[i]}' → {bits}")
101
 
102
  st.subheader("Binary Labels (32-bit groups)")
103
+ groups = []
104
+ for i in range(0, len(binary_labels), 32):
105
+ group = binary_labels[i:i+32]
106
+ group += [0] * (32 - len(group))
107
+ groups.append(group + [sum(group)])
 
 
 
 
 
 
 
 
 
108
 
109
+ df = pd.DataFrame(groups, columns=[str(h) for h in mutation_site_headers] + ["Edited Sites"])
110
+ st.dataframe(df)
111
+ st.download_button("Download as CSV", df.to_csv(index=False), "text_binary_labels.csv")
 
 
 
112
 
113
+ # Tab 2: Image to Binary
114
  with tab2:
115
+ uploaded = st.file_uploader("Upload an image (jpg/png)", type=["jpg", "jpeg", "png"])
116
+ if uploaded:
117
+ img = Image.open(uploaded)
118
+ st.image(img, caption="Original", use_column_width=True)
119
+ cropped = st_cropper(img, realtime_update=True, box_color="blue", aspect_ratio=None)
120
+ st.image(cropped, caption="Cropped", use_column_width=True)
 
 
 
121
 
122
+ max_pixels = st.slider("Max pixels to encode", 32, 1024, 256, 32)
123
+ binary_labels = image_to_binary_labels_rgb(cropped, max_pixels=max_pixels)
 
 
 
124
 
125
  st.subheader("Binary Labels from Image")
126
+ groups = []
127
+ for i in range(0, len(binary_labels), 32):
128
+ group = binary_labels[i:i+32]
129
+ group += [0] * (32 - len(group))
130
+ groups.append(group + [sum(group)])
131
+ df = pd.DataFrame(groups, columns=[str(h) for h in mutation_site_headers] + ["Edited Sites"])
 
 
 
 
 
 
 
132
  st.dataframe(df)
133
 
134
+ st.subheader("Reconstructed Image")
135
+ recon = binary_labels_to_rgb_image(binary_labels)
136
+ st.image(recon, caption="Reconstructed", use_column_width=True)
137
+ st.download_button("Download CSV", df.to_csv(index=False), "image_binary_labels.csv")
 
 
 
 
 
 
138
 
139
+ # Tab 3: EF → Binary
140
  with tab3:
141
+ st.write("Upload an Editing Frequency CSV or enter manually:")
142
+ ef_file = st.file_uploader("Upload EF CSV", type=["csv"], key="ef")
143
 
144
  if ef_file:
145
  ef_df = pd.read_csv(ef_file)
146
  ef_df = ef_df.loc[:, ~ef_df.columns.str.contains('^Unnamed')]
147
  else:
148
+ ef_df = pd.DataFrame(columns=[str(k) for k in thresholds.index])
149
 
150
  edited_df = st.data_editor(ef_df, num_rows="dynamic")
151
 
152
  if st.button("Convert to Binary Labels"):
153
+ int_map = {str(k): k for k in thresholds.index}
154
+ matching_cols = [col for col in edited_df.columns if col in int_map]
155
 
156
+ binary_part = pd.DataFrame()
157
+ for col in matching_cols:
158
+ col_threshold = thresholds[int_map[col]]
159
+ binary_part[col] = (edited_df[col].astype(float) >= col_threshold).astype(int)
160
+
161
+ non_binary_part = edited_df.drop(columns=matching_cols, errors='ignore')
162
  binary_df = pd.concat([non_binary_part, binary_part], axis=1)
 
 
 
 
 
 
 
 
 
 
 
 
 
163
 
164
+ def color_binary(val):
165
+ if val == 1: return "background-color: lightgreen"
166
+ if val == 0: return "background-color: lightcoral"
167
+ return ""
 
 
168
 
169
+ st.subheader("Binary Labels")
170
+ styled = binary_df.style.applymap(color_binary, subset=matching_cols)
171
+ st.dataframe(styled)
172
+ st.download_button("Download CSV", binary_df.to_csv(index=False), "ef_binary_labels.csv")