Skip to content

Commit 744f4e8

Browse files
authored
Merge pull request #16 from mwang87/speed-optimization
Binary search for zooming
2 parents f62af3c + 05b04b4 commit 744f4e8

File tree

1 file changed

+104
-17
lines changed

1 file changed

+104
-17
lines changed

app.py

Lines changed: 104 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -582,23 +582,41 @@ def determine_xic_target(search, clickData, existing_xic):
582582
return ""
583583

584584

585-
def create_map_fig(filename, map_selection=None, show_ms2_markers=True):
586-
min_rt = 0
587-
max_rt = 1000000
588-
min_mz = 0
589-
max_mz = 2000
585+
# Binary Search
586+
def _find_lcms_rt(filename, rt_query):
587+
run = pymzml.run.Reader(filename, MS_precisions=MS_precisions)
590588

591-
if map_selection is not None:
592-
if "xaxis.range[0]" in map_selection:
593-
min_rt = float(map_selection["xaxis.range[0]"])
594-
if "xaxis.range[1]" in map_selection:
595-
max_rt = float(map_selection["xaxis.range[1]"])
589+
s = 0
590+
e = run.get_spectrum_count()
596591

597-
if "yaxis.range[0]" in map_selection:
598-
min_mz = float(map_selection["yaxis.range[0]"])
599-
if "yaxis.range[1]" in map_selection:
600-
max_mz = float(map_selection["yaxis.range[1]"])
592+
while True:
593+
jump_point = int((e + s) / 2)
594+
595+
# Jump out early
596+
if jump_point == 0:
597+
break
598+
599+
if jump_point == run.get_spectrum_count():
600+
break
601+
602+
if s == e:
603+
break
604+
605+
if e - s == 1:
606+
break
607+
608+
spec = run[ jump_point ]
609+
610+
if spec.scan_time_in_minutes() < rt_query:
611+
s = jump_point
612+
elif spec.scan_time_in_minutes() > rt_query:
613+
e = jump_point
614+
else:
615+
break
616+
617+
return e
601618

619+
def _gather_lcms_data(filename, min_rt, max_rt, min_mz, max_mz):
602620
all_mz = []
603621
all_rt = []
604622
all_i = []
@@ -615,9 +633,14 @@ def create_map_fig(filename, map_selection=None, show_ms2_markers=True):
615633
all_ms3_rt = []
616634
all_ms3_scan = []
617635

636+
# Performing Binary Search for bounds of RT
637+
min_rt_index = _find_lcms_rt(filename, min_rt) # These are inclusive on left
638+
max_rt_index = _find_lcms_rt(filename, max_rt) + 1 # Exclusive on the right
639+
618640
# Understand parameters
619641
run = pymzml.run.Reader(filename, MS_precisions=MS_precisions)
620-
for spec in tqdm(run):
642+
for spec_index in tqdm(range(min_rt_index, max_rt_index)):
643+
spec = run[spec_index]
621644
try:
622645
# Still waiting for the window
623646
if spec.scan_time_in_minutes() < min_rt:
@@ -672,8 +695,66 @@ def create_map_fig(filename, map_selection=None, show_ms2_markers=True):
672695
all_ms3_scan.append(spec.ID)
673696
except:
674697
pass
675-
676-
698+
699+
ms1_results = {}
700+
ms1_results["mz"] = all_mz
701+
ms1_results["rt"] = all_rt
702+
ms1_results["i"] = all_i
703+
ms1_results["scan"] = all_scan
704+
ms1_results["index"] = all_index
705+
ms1_results["number_spectra"] = number_spectra
706+
707+
ms2_results = {}
708+
ms2_results["all_ms2_mz"] = all_ms2_mz
709+
ms2_results["all_ms2_rt"] = all_ms2_rt
710+
ms2_results["all_ms2_scan"] = all_ms2_scan
711+
712+
ms3_results = {}
713+
ms3_results["all_ms3_mz"] = all_ms3_mz
714+
ms3_results["all_ms3_rt"] = all_ms3_rt
715+
ms3_results["all_ms3_scan"] = all_ms3_scan
716+
717+
return ms1_results, ms2_results, ms3_results
718+
719+
def create_map_fig(filename, map_selection=None, show_ms2_markers=True):
720+
min_rt = 0
721+
max_rt = 1000000
722+
min_mz = 0
723+
max_mz = 2000
724+
725+
if map_selection is not None:
726+
if "xaxis.range[0]" in map_selection:
727+
min_rt = float(map_selection["xaxis.range[0]"])
728+
if "xaxis.range[1]" in map_selection:
729+
max_rt = float(map_selection["xaxis.range[1]"])
730+
731+
if "yaxis.range[0]" in map_selection:
732+
min_mz = float(map_selection["yaxis.range[0]"])
733+
if "yaxis.range[1]" in map_selection:
734+
max_mz = float(map_selection["yaxis.range[1]"])
735+
736+
import time
737+
start_time = time.time()
738+
ms1_results, ms2_results, ms3_results = _gather_lcms_data(filename, min_rt, max_rt, min_mz, max_mz)
739+
end_time = time.time()
740+
print("READ FILE", end_time - start_time)
741+
742+
start_time = time.time()
743+
744+
all_mz = ms1_results["mz"]
745+
all_rt = ms1_results["rt"]
746+
all_i = ms1_results["i"]
747+
all_scan = ms1_results["scan"]
748+
all_index = ms1_results["index"]
749+
number_spectra = ms1_results["number_spectra"]
750+
751+
all_ms2_mz = ms2_results["all_ms2_mz"]
752+
all_ms2_rt = ms2_results["all_ms2_rt"]
753+
all_ms2_scan = ms2_results["all_ms2_scan"]
754+
755+
all_ms3_mz = ms3_results["all_ms3_mz"]
756+
all_ms3_rt = ms3_results["all_ms3_rt"]
757+
all_ms3_scan = ms3_results["all_ms3_scan"]
677758

678759
df = pd.DataFrame()
679760
df["mz"] = all_mz
@@ -688,6 +769,10 @@ def create_map_fig(filename, map_selection=None, show_ms2_markers=True):
688769

689770
cvs = ds.Canvas(plot_width=width, plot_height=height)
690771
agg = cvs.points(df,'rt','mz', agg=ds.sum("i"))
772+
773+
end_time = time.time()
774+
print("Datashader Agg", end_time - start_time)
775+
691776
zero_mask = agg.values == 0
692777
agg.values = np.log10(agg.values, where=np.logical_not(zero_mask))
693778
fig = px.imshow(agg, origin='lower', labels={'color':'Log10(abundance)'}, color_continuous_scale="Hot_r", height=600, template="plotly_white")
@@ -709,6 +794,8 @@ def create_map_fig(filename, map_selection=None, show_ms2_markers=True):
709794
scatter_ms3_fig = go.Scatter(x=all_ms3_rt, y=all_ms3_mz, mode='markers', customdata=all_ms3_scan, marker=dict(color='green', size=5, symbol="x"), name="MS3s")
710795
fig.add_trace(scatter_ms3_fig)
711796

797+
798+
712799
return fig
713800

714801
# Creating TIC plot

0 commit comments

Comments
 (0)