wenjun99 commited on
Commit
2dd1657
·
verified ·
1 Parent(s): d4ed224

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +103 -9
app.py CHANGED
@@ -392,12 +392,87 @@ def get_well_position(sample_index):
392
  with tab5:
393
  st.header("Decode Binary Labels to String")
394
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
395
  # ========== 32-BIT DECODING ==========
396
  st.subheader("32-bit Binary per Row")
397
  st.write("Upload CSV with 32 columns (0 or 1), no headers, from EF Binary format or enter manually below.")
398
 
399
  binary32_file = st.file_uploader("Upload 32-bit Binary CSV", type=["csv"], key="binary_32")
400
 
 
 
 
 
 
 
401
  if binary32_file:
402
  df_32 = pd.read_csv(binary32_file, header=None)
403
  df_32.columns = [str(h) for h in mutation_site_headers_actual_3614]
@@ -429,10 +504,7 @@ with tab5:
429
  st.write(decoded_asc)
430
  st.download_button("Download Concatenated Output", decoded_asc, "decoded_32bit_string_ascending.txt", key="download_txt_tab5_32_asc")
431
 
432
- # === Robot Preparation Script from 32-bit Binary ===
433
  st.subheader("Robot Preparation Script from 32-bit Binary")
434
- robot_template_32 = pd.read_csv("/home/user/app/Robot2.csv", skiprows=3)
435
- robot_template_32.columns = ['Labware', 'Source', 'Labware_2', 'Destination', 'Volume', 'Tool', 'Name']
436
 
437
  df_32_robot = df_32.copy()
438
  df_32_robot.insert(0, 'Sample', range(1, len(df_32_robot)+1))
@@ -440,23 +512,45 @@ with tab5:
440
  df_32_robot['volume donors (µl)'] = 64 / df_32_robot['# donors']
441
 
442
  robot_script_32 = []
443
- source_wells_32 = robot_template_32['Source'].unique().tolist()
444
- if len(source_wells_32) < df_32.shape[1]:
445
- source_wells_32 += [f"Fake{i}" for i in range(df_32.shape[1] - len(source_wells_32))]
446
- source_wells_32 = source_wells_32[:df_32.shape[1]]
447
 
448
  for i, col in enumerate(df_32.columns):
449
  for row_idx, sample in df_32_robot.iterrows():
450
  if int(sample[col]) == 1:
451
  source = source_wells_32[i]
452
  dest = get_well_position(int(sample['Sample']))
 
453
  vol = round(sample['volume donors (µl)'], 2)
454
- robot_script_32.append({'Source': source, 'Destination': dest, 'Volume': vol})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
455
 
456
- robot_script_32_df = pd.DataFrame(robot_script_32)
457
  st.dataframe(robot_script_32_df)
458
  st.download_button("Download Robot Script (32-bit)", robot_script_32_df.to_csv(index=False), "robot_script_32bit.csv", key="download_robot_32")
459
 
 
 
 
 
 
 
460
  st.markdown("---")
461
 
462
  # ========== 31-BIT DECODING ==========
 
392
  with tab5:
393
  st.header("Decode Binary Labels to String")
394
 
395
+ # Utility: Track source volumes and update if exceeds limit
396
+ def track_and_replace_source(source_list, robot_script, volume_limit=170):
397
+ source_volumes = {}
398
+ adjusted_sources = []
399
+
400
+ for entry in robot_script:
401
+ src = entry['Source']
402
+ vol = entry['Volume']
403
+
404
+ if src not in source_volumes:
405
+ source_volumes[src] = 0
406
+
407
+ source_volumes[src] += vol
408
+
409
+ if source_volumes[src] > volume_limit:
410
+ row_letter = src[0]
411
+ col_number = src[1:]
412
+ new_row_letter = chr(ord(row_letter) + 4)
413
+ new_src = f"{new_row_letter}{col_number}"
414
+ entry['Source'] = new_src
415
+
416
+ if new_src not in source_volumes:
417
+ source_volumes[new_src] = 0
418
+ source_volumes[new_src] += vol
419
+ source_volumes[src] -= vol
420
+
421
+ adjusted_sources.append(entry)
422
+
423
+ return adjusted_sources, source_volumes
424
+
425
+ # Utility: Generate fixed-volume D source to all sample wells
426
+ def generate_fixed_d_source_instructions_to_all_samples(n_samples, fixed_volume=16, volume_limit=170):
427
+ d_source_volumes = {}
428
+ d_source_script = []
429
+ current_d_index = 1
430
+
431
+ for i in range(n_samples):
432
+ dest = get_well_position(i + 1)
433
+ current_d_well = f"D{current_d_index}"
434
+
435
+ if current_d_well not in d_source_volumes:
436
+ d_source_volumes[current_d_well] = 0
437
+
438
+ if d_source_volumes[current_d_well] + fixed_volume > volume_limit:
439
+ current_d_index += 1
440
+ current_d_well = f"D{current_d_index}"
441
+ d_source_volumes[current_d_well] = 0
442
+
443
+ d_source_volumes[current_d_well] += fixed_volume
444
+ tool = 'TS_10' if fixed_volume < 10 else 'TS_50'
445
+
446
+ d_source_script.append({
447
+ 'Source': current_d_well,
448
+ 'Destination': dest,
449
+ 'Volume': fixed_volume,
450
+ 'Tool': tool
451
+ })
452
+
453
+ return d_source_script, d_source_volumes
454
+
455
+ def generate_source_wells(n):
456
+ wells = []
457
+ rows = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
458
+ for i in range(n):
459
+ row = rows[i // 12] # cycle through A, B, C...
460
+ col = (i % 12) + 1 # 1 to 12
461
+ wells.append(f"{row}{col}")
462
+ return wells
463
+
464
  # ========== 32-BIT DECODING ==========
465
  st.subheader("32-bit Binary per Row")
466
  st.write("Upload CSV with 32 columns (0 or 1), no headers, from EF Binary format or enter manually below.")
467
 
468
  binary32_file = st.file_uploader("Upload 32-bit Binary CSV", type=["csv"], key="binary_32")
469
 
470
+ st.subheader("Optional Metadata (Optional)")
471
+ barcode_id_input = st.text_input("Barcode ID (applied to all rows, optional)", value="")
472
+ labware_source_input = st.text_input("Labware for Source (optional, default = 1)", value="1")
473
+ labware_dest_input = st.text_input("Labware for Destination (optional, default = 1)", value="1")
474
+ name_input = st.text_input("Name field (optional, default = blank)", value="")
475
+
476
  if binary32_file:
477
  df_32 = pd.read_csv(binary32_file, header=None)
478
  df_32.columns = [str(h) for h in mutation_site_headers_actual_3614]
 
504
  st.write(decoded_asc)
505
  st.download_button("Download Concatenated Output", decoded_asc, "decoded_32bit_string_ascending.txt", key="download_txt_tab5_32_asc")
506
 
 
507
  st.subheader("Robot Preparation Script from 32-bit Binary")
 
 
508
 
509
  df_32_robot = df_32.copy()
510
  df_32_robot.insert(0, 'Sample', range(1, len(df_32_robot)+1))
 
512
  df_32_robot['volume donors (µl)'] = 64 / df_32_robot['# donors']
513
 
514
  robot_script_32 = []
515
+ source_wells_32 = generate_source_wells(df_32.shape[1])
516
+ used_destinations = set()
 
 
517
 
518
  for i, col in enumerate(df_32.columns):
519
  for row_idx, sample in df_32_robot.iterrows():
520
  if int(sample[col]) == 1:
521
  source = source_wells_32[i]
522
  dest = get_well_position(int(sample['Sample']))
523
+ used_destinations.add(dest)
524
  vol = round(sample['volume donors (µl)'], 2)
525
+ tool = 'TS_10' if vol < 10 else 'TS_50'
526
+ robot_script_32.append({
527
+ 'Source': source,
528
+ 'Destination': dest,
529
+ 'Volume': vol,
530
+ 'Tool': tool
531
+ })
532
+
533
+ robot_script_32, source_volumes_32 = track_and_replace_source(source_wells_32, robot_script_32)
534
+
535
+ d_script, d_volumes = generate_fixed_d_source_instructions_to_all_samples(len(df_32_robot))
536
+ full_robot_script = robot_script_32 + d_script
537
+
538
+ robot_script_32_df = pd.DataFrame(full_robot_script)
539
+ robot_script_32_df.insert(0, 'Barcode ID', barcode_id_input)
540
+ robot_script_32_df.insert(1, 'Labware_Source', labware_source_input)
541
+ robot_script_32_df.insert(3, 'Labware_Destination', labware_dest_input)
542
+ robot_script_32_df['Name'] = name_input
543
+ robot_script_32_df = robot_script_32_df[['Barcode ID', 'Labware_Source', 'Source', 'Labware_Destination', 'Destination', 'Volume', 'Tool', 'Name']]
544
 
 
545
  st.dataframe(robot_script_32_df)
546
  st.download_button("Download Robot Script (32-bit)", robot_script_32_df.to_csv(index=False), "robot_script_32bit.csv", key="download_robot_32")
547
 
548
+ st.subheader("Total Volume Used Per Source")
549
+ combined_volumes = {**source_volumes_32, **d_volumes}
550
+ source_volume_df = pd.DataFrame(list(combined_volumes.items()), columns=['Source', 'Total Volume (µl)'])
551
+ st.dataframe(source_volume_df)
552
+ st.download_button("Download Source Volumes", source_volume_df.to_csv(index=False), "source_total_volumes.csv", key="download_volume_32")
553
+
554
  st.markdown("---")
555
 
556
  # ========== 31-BIT DECODING ==========