diff --git a/clients/python/test/PredFull/__init__.py b/clients/python/test/PredFull/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/clients/python/test/PredFull/numpy_arrays/AA1intsCID20.npy b/clients/python/test/PredFull/numpy_arrays/AA1intsCID20.npy new file mode 100644 index 00000000..2cddabe9 Binary files /dev/null and b/clients/python/test/PredFull/numpy_arrays/AA1intsCID20.npy differ diff --git a/clients/python/test/PredFull/numpy_arrays/AA1mzsCID20.npy b/clients/python/test/PredFull/numpy_arrays/AA1mzsCID20.npy new file mode 100644 index 00000000..91282ae6 Binary files /dev/null and b/clients/python/test/PredFull/numpy_arrays/AA1mzsCID20.npy differ diff --git a/clients/python/test/PredFull/numpy_arrays/HIISVMoxR2CID30_intensities.npy b/clients/python/test/PredFull/numpy_arrays/HIISVMoxR2CID30_intensities.npy new file mode 100644 index 00000000..a676e4ee Binary files /dev/null and b/clients/python/test/PredFull/numpy_arrays/HIISVMoxR2CID30_intensities.npy differ diff --git a/clients/python/test/PredFull/numpy_arrays/HIISVMoxR2CID30_mzs.npy b/clients/python/test/PredFull/numpy_arrays/HIISVMoxR2CID30_mzs.npy new file mode 100644 index 00000000..ccb1e004 Binary files /dev/null and b/clients/python/test/PredFull/numpy_arrays/HIISVMoxR2CID30_mzs.npy differ diff --git a/clients/python/test/PredFull/numpy_arrays/HIISVMoxR2CID30_rawspectrum.npy b/clients/python/test/PredFull/numpy_arrays/HIISVMoxR2CID30_rawspectrum.npy new file mode 100644 index 00000000..242e2331 Binary files /dev/null and b/clients/python/test/PredFull/numpy_arrays/HIISVMoxR2CID30_rawspectrum.npy differ diff --git a/clients/python/test/PredFull/numpy_arrays/PEPTIPEPTIPEPTIPEPTIPEPTIPEPT2intsHCD21.npy b/clients/python/test/PredFull/numpy_arrays/PEPTIPEPTIPEPTIPEPTIPEPTIPEPT2intsHCD21.npy new file mode 100644 index 00000000..ac1597b4 Binary files /dev/null and b/clients/python/test/PredFull/numpy_arrays/PEPTIPEPTIPEPTIPEPTIPEPTIPEPT2intsHCD21.npy differ diff --git a/clients/python/test/PredFull/numpy_arrays/PEPTIPEPTIPEPTIPEPTIPEPTIPEPT2mzsHCD21.npy b/clients/python/test/PredFull/numpy_arrays/PEPTIPEPTIPEPTIPEPTIPEPTIPEPT2mzsHCD21.npy new file mode 100644 index 00000000..8bf97cd7 Binary files /dev/null and b/clients/python/test/PredFull/numpy_arrays/PEPTIPEPTIPEPTIPEPTIPEPTIPEPT2mzsHCD21.npy differ diff --git a/clients/python/test/PredFull/numpy_arrays/RHKDESTNQCGPAVILM(ox)FYW4intsHCD23.npy b/clients/python/test/PredFull/numpy_arrays/RHKDESTNQCGPAVILM(ox)FYW4intsHCD23.npy new file mode 100644 index 00000000..6bcfd515 Binary files /dev/null and b/clients/python/test/PredFull/numpy_arrays/RHKDESTNQCGPAVILM(ox)FYW4intsHCD23.npy differ diff --git a/clients/python/test/PredFull/numpy_arrays/RHKDESTNQCGPAVILM(ox)FYW4mzsHCD23.npy b/clients/python/test/PredFull/numpy_arrays/RHKDESTNQCGPAVILM(ox)FYW4mzsHCD23.npy new file mode 100644 index 00000000..adf3a883 Binary files /dev/null and b/clients/python/test/PredFull/numpy_arrays/RHKDESTNQCGPAVILM(ox)FYW4mzsHCD23.npy differ diff --git a/clients/python/test/PredFull/numpy_arrays/RHKDESTNQCGPAVILMFYW3intsCID22.npy b/clients/python/test/PredFull/numpy_arrays/RHKDESTNQCGPAVILMFYW3intsCID22.npy new file mode 100644 index 00000000..0d64d27a Binary files /dev/null and b/clients/python/test/PredFull/numpy_arrays/RHKDESTNQCGPAVILMFYW3intsCID22.npy differ diff --git a/clients/python/test/PredFull/numpy_arrays/RHKDESTNQCGPAVILMFYW3mzsCID22.npy b/clients/python/test/PredFull/numpy_arrays/RHKDESTNQCGPAVILMFYW3mzsCID22.npy new file mode 100644 index 00000000..da2cb6ac Binary files /dev/null and b/clients/python/test/PredFull/numpy_arrays/RHKDESTNQCGPAVILMFYW3mzsCID22.npy differ diff --git a/clients/python/test/PredFull/test_PredFull.py b/clients/python/test/PredFull/test_PredFull.py new file mode 100644 index 00000000..c75a9a3f --- /dev/null +++ b/clients/python/test/PredFull/test_PredFull.py @@ -0,0 +1,117 @@ +from test.server_config import SERVER_GRPC, SERVER_HTTP +import tritonclient.grpc as grpcclient +import numpy as np +from pathlib import Path +import requests +import time + +# To ensure MODEL_NAME == test_.py +MODEL_NAME = Path(__file__).stem.replace("test_", "") + + +def test_available_http(): + req = requests.get(f"{SERVER_HTTP}/v2/models/{MODEL_NAME}", timeout=1) + assert req.status_code == 200 + + +def test_available_grpc(): + triton_client = grpcclient.InferenceServerClient(url=SERVER_GRPC) + assert triton_client.is_model_ready(MODEL_NAME) + + +def test_inference(): + SEQUENCES = np.array( + [ + ["AA"], + ["PEPTIPEPTIPEPTIPEPTIPEPTIPEPT"], + ["RHKDESTNQCGPAVILMFYW"], + ["RHKDESTNQCGPAVILM[UNIMOD:35]FYW"], + ], + dtype=np.object_, + ) + SEQUENCES_copy = SEQUENCES + for i in range(249): + for seq in SEQUENCES_copy: + SEQUENCES = np.append(SEQUENCES, [seq], axis=0) + len_s = len(SEQUENCES) + + charge = np.array([[i % 6 + 1] for i in range(len_s)], dtype=np.int32) + nce = np.array([[(19 + i) % 40 + 1] for i in range(len_s)], dtype=np.float32) + fragmentation_type = np.array( + [["HCD" if i % 2 != 0 else "CID"] for i in range(len_s)], dtype=np.object_ + ) + + start = time.time() + triton_client = grpcclient.InferenceServerClient(url=SERVER_GRPC) + + in_pep_seq = grpcclient.InferInput("peptide_sequences", [len_s, 1], "BYTES") + in_pep_seq.set_data_from_numpy(SEQUENCES) + + in_charge = grpcclient.InferInput("precursor_charges", [len_s, 1], "INT32") + in_charge.set_data_from_numpy(charge) + + in_nce = grpcclient.InferInput("collision_energies", [len_s, 1], "FP32") + in_nce.set_data_from_numpy(nce) + + in_frag = grpcclient.InferInput("fragmentation_types", [len_s, 1], "BYTES") + in_frag.set_data_from_numpy(fragmentation_type) + + result = triton_client.infer( + MODEL_NAME, + inputs=[in_pep_seq, in_charge, in_nce, in_frag], + outputs=[ + grpcclient.InferRequestedOutput("mzs"), + grpcclient.InferRequestedOutput("intensities"), + ], + ) + + fragmentmz = result.as_numpy("mzs") + intensities = result.as_numpy("intensities") + end = time.time() + print(fragmentmz[0:5, :]) + print(intensities[0:5, :]) + print(end - start) + + for i, (test_mzs, test_ints) in enumerate( + zip( + [ + "AA1mzsCID20.npy", + "PEPTIPEPTIPEPTIPEPTIPEPTIPEPT2mzsHCD21.npy", + "RHKDESTNQCGPAVILMFYW3mzsCID22.npy", + "RHKDESTNQCGPAVILM(ox)FYW4mzsHCD23.npy", + ], + [ + "AA1intsCID20.npy", + "PEPTIPEPTIPEPTIPEPTIPEPTIPEPT2intsHCD21.npy", + "RHKDESTNQCGPAVILMFYW3intsCID22.npy", + "RHKDESTNQCGPAVILM(ox)FYW4intsHCD23.npy", + ], + ) + ): + # get predicted arrays + pred_mzs = fragmentmz[i, :] + pred_ints = intensities[i, :] + pred_mzs = pred_mzs[pred_mzs != -1] + pred_ints = pred_ints[pred_ints != -1] + pred_ints /= 1000 + + # get elements in test loaded array + ground_truth_mzs = np.load("test/PredFull/numpy_arrays/" + test_mzs) + p_indices = np.where(np.isin(pred_mzs, ground_truth_mzs))[0] + gt_indices = np.where(np.isin(ground_truth_mzs, pred_mzs))[0] + + print( + np.max( + abs( + pred_ints[p_indices] + - np.load("test/PredFull/numpy_arrays/" + test_ints)[gt_indices] + ) + ) + ) + assert np.allclose( + pred_ints[p_indices], + np.load("test/PredFull/numpy_arrays/" + test_ints)[gt_indices], + rtol=0, + atol=1e-1, + equal_nan=True, + ) diff --git a/clients/python/test/PredFull/test_PredFull_Postprocess.py b/clients/python/test/PredFull/test_PredFull_Postprocess.py new file mode 100644 index 00000000..811619a4 --- /dev/null +++ b/clients/python/test/PredFull/test_PredFull_Postprocess.py @@ -0,0 +1,68 @@ +from test.server_config import SERVER_GRPC, SERVER_HTTP +from pathlib import Path +from test.lib import lib_test_available_grpc, lib_test_available_http +import numpy as np +import tritonclient.grpc as grpcclient + + +# To ensure MODEL_NAME == test_.py +MODEL_NAME = Path(__file__).stem.replace("test_", "") + + +def test_available_http(): + lib_test_available_http(MODEL_NAME, SERVER_HTTP) + + +def test_available_grpc(): + lib_test_available_grpc(MODEL_NAME, SERVER_GRPC) + + +def test_inference(): + triton_client = grpcclient.InferenceServerClient(url=SERVER_GRPC) + + spectrum = np.load("test/PredFull/numpy_arrays/HIISVMoxR2CID30_rawspectrum.npy") + in_spectrum = grpcclient.InferInput("spectrum", spectrum.shape, "FP32") + in_spectrum.set_data_from_numpy(spectrum) + + mass = np.array([[871.4]], dtype=np.float32) + in_mass = grpcclient.InferInput("precursor_mass_with_oxM", [1, 1], "FP32") + in_mass.set_data_from_numpy(mass) + + result = triton_client.infer( + MODEL_NAME, + inputs=[in_spectrum, in_mass], + outputs=[ + grpcclient.InferRequestedOutput("mzs"), + grpcclient.InferRequestedOutput("intensities"), + ], + ) + + mzs = result.as_numpy("mzs") + intensities = result.as_numpy("intensities") + print(mzs) + print(intensities) + print(mzs.shape) + + assert intensities.shape == mzs.shape + + ground_truth_intensities = np.load( + "test/PredFull/numpy_arrays/HIISVMoxR2CID30_intensities.npy" + ) + ground_truth_mzs = np.load("test/PredFull/numpy_arrays/HIISVMoxR2CID30_mzs.npy") + + ground_truth_mzs = ground_truth_mzs[ground_truth_intensities > 1] + ground_truth_intensities = ground_truth_intensities[ground_truth_intensities > 1] + + assert np.allclose( + intensities, + ground_truth_intensities, + rtol=0, + atol=1e-4, + ) + + assert np.allclose( + mzs, + ground_truth_mzs, + rtol=0, + atol=1e-4, + ) diff --git a/clients/python/test/PredFull/test_PredFull_Preprocess_charge.py b/clients/python/test/PredFull/test_PredFull_Preprocess_charge.py new file mode 100644 index 00000000..7482d0c2 --- /dev/null +++ b/clients/python/test/PredFull/test_PredFull_Preprocess_charge.py @@ -0,0 +1,73 @@ +from test.server_config import SERVER_GRPC, SERVER_HTTP +from pathlib import Path +from test.lib import lib_test_available_grpc, lib_test_available_http +import numpy as np +import tritonclient.grpc as grpcclient + +# To ensure MODEL_NAME == test_.py +MODEL_NAME = Path(__file__).stem.replace("test_", "") + + +def test_available_http(): + lib_test_available_http(MODEL_NAME, SERVER_HTTP) + + +def test_available_grpc(): + lib_test_available_grpc(MODEL_NAME, SERVER_GRPC) + + +def test_inference(): + + triton_client = grpcclient.InferenceServerClient(url=SERVER_GRPC) + + charge = np.array([[3], [1]], dtype=np.int32) + in_charge = grpcclient.InferInput("precursor_charges", [len(charge), 1], "INT32") + in_charge.set_data_from_numpy(charge) + + result = triton_client.infer( + MODEL_NAME, + inputs=[in_charge], + outputs=[ + grpcclient.InferRequestedOutput("precursor_charges_in:0"), + ], + ) + + one_hot_charge = result.as_numpy("precursor_charges_in:0") + + ground_truth = np.array( + [ + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ] + ) + + print(one_hot_charge[1]) + assert np.array_equal(one_hot_charge[0], ground_truth) diff --git a/clients/python/test/PredFull/test_PredFull_Preprocess_collision_energy.py b/clients/python/test/PredFull/test_PredFull_Preprocess_collision_energy.py new file mode 100644 index 00000000..7680da63 --- /dev/null +++ b/clients/python/test/PredFull/test_PredFull_Preprocess_collision_energy.py @@ -0,0 +1,39 @@ +from test.server_config import SERVER_GRPC, SERVER_HTTP +from pathlib import Path +from test.lib import lib_test_available_grpc, lib_test_available_http +import numpy as np +import tritonclient.grpc as grpcclient + +# To ensure MODEL_NAME == test_.py +MODEL_NAME = Path(__file__).stem.replace("test_", "") + + +def test_available_http(): + lib_test_available_http(MODEL_NAME, SERVER_HTTP) + + +def test_available_grpc(): + lib_test_available_grpc(MODEL_NAME, SERVER_GRPC) + + +def test_inference(): + + triton_client = grpcclient.InferenceServerClient(url=SERVER_GRPC) + + ces = np.array([[30]], dtype=np.float32) + in_ces = grpcclient.InferInput("collision_energies", [1, 1], "FP32") + in_ces.set_data_from_numpy(ces) + + result = triton_client.infer( + MODEL_NAME, + inputs=[in_ces], + outputs=[ + grpcclient.InferRequestedOutput("norm_collision_energy"), + ], + ) + + normce = result.as_numpy("norm_collision_energy") + + ground_truth = np.array([0.30]) + + assert np.allclose(normce[0], ground_truth, atol=1e-4) diff --git a/clients/python/test/PredFull/test_PredFull_Preprocess_combine_meta.py b/clients/python/test/PredFull/test_PredFull_Preprocess_combine_meta.py new file mode 100644 index 00000000..765bc7a8 --- /dev/null +++ b/clients/python/test/PredFull/test_PredFull_Preprocess_combine_meta.py @@ -0,0 +1,123 @@ +from test.server_config import SERVER_GRPC, SERVER_HTTP +from pathlib import Path +from test.lib import lib_test_available_grpc, lib_test_available_http +import numpy as np +import tritonclient.grpc as grpcclient + +# To ensure MODEL_NAME == test_.py +MODEL_NAME = Path(__file__).stem.replace("test_", "") + + +def test_available_http(): + lib_test_available_http(MODEL_NAME, SERVER_HTTP) + + +def test_available_grpc(): + lib_test_available_grpc(MODEL_NAME, SERVER_GRPC) + + +def test_inference(): + triton_client = grpcclient.InferenceServerClient(url=SERVER_GRPC) + + charge = np.array( + [ + [ + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ] + ], + dtype=np.float32, + ) + + fragmentation = np.array( + [ + [ + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ] + ], + dtype=np.float32, + ) + + mass = np.array([[0.042774]], dtype=np.float32) + nce = np.array([[0.30]], dtype=np.float32) + + in_charge = grpcclient.InferInput("precursor_charges_in:0", [1, 30], "FP32") + in_charge.set_data_from_numpy(charge) + + in_frag = grpcclient.InferInput("fragmentation_types_encoding", [1, 30], "FP32") + in_frag.set_data_from_numpy(fragmentation) + + in_mass = grpcclient.InferInput("precursor_mass", [1, 1], "FP32") + in_mass.set_data_from_numpy(mass) + + in_nce = grpcclient.InferInput("norm_collision_energy", [1, 1], "FP32") + in_nce.set_data_from_numpy(nce) + + result = triton_client.infer( + MODEL_NAME, + inputs=[in_charge, in_frag, in_mass, in_nce], + outputs=[ + grpcclient.InferRequestedOutput("meta_input"), + ], + ) + + meta = result.as_numpy("meta_input") + print(meta.shape) + assert meta.shape == (1, 3, 30) diff --git a/clients/python/test/PredFull/test_PredFull_Preprocess_fragmentation_types.py b/clients/python/test/PredFull/test_PredFull_Preprocess_fragmentation_types.py new file mode 100644 index 00000000..6fabc904 --- /dev/null +++ b/clients/python/test/PredFull/test_PredFull_Preprocess_fragmentation_types.py @@ -0,0 +1,111 @@ +from test.server_config import SERVER_GRPC, SERVER_HTTP +from pathlib import Path +from test.lib import lib_test_available_grpc, lib_test_available_http +import numpy as np +import tritonclient.grpc as grpcclient + +# To ensure MODEL_NAME == test_.py +MODEL_NAME = Path(__file__).stem.replace("test_", "") + + +def test_available_http(): + lib_test_available_http(MODEL_NAME, SERVER_HTTP) + + +def test_available_grpc(): + lib_test_available_grpc(MODEL_NAME, SERVER_GRPC) + + +def test_inference(): + + triton_client = grpcclient.InferenceServerClient(url=SERVER_GRPC) + + fragmentation = np.array([["HCD"], ["CID"]], dtype=np.object_) + in_fragmentation = grpcclient.InferInput( + "fragmentation_types", fragmentation.shape, "BYTES" + ) + in_fragmentation.set_data_from_numpy(fragmentation) + + result = triton_client.infer( + MODEL_NAME, + inputs=[in_fragmentation], + outputs=[ + grpcclient.InferRequestedOutput("fragmentation_types_encoding"), + ], + ) + + one_fragmentation = result.as_numpy("fragmentation_types_encoding") + + ground_truth = np.array( + [ + [ + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + ] + ) + + print(one_fragmentation) + print(ground_truth) + + assert np.array_equal(one_fragmentation, ground_truth) diff --git a/clients/python/test/PredFull/test_PredFull_Preprocess_mass.py b/clients/python/test/PredFull/test_PredFull_Preprocess_mass.py new file mode 100644 index 00000000..68367f32 --- /dev/null +++ b/clients/python/test/PredFull/test_PredFull_Preprocess_mass.py @@ -0,0 +1,53 @@ +from test.server_config import SERVER_GRPC, SERVER_HTTP +from pathlib import Path +from test.lib import lib_test_available_grpc, lib_test_available_http +import numpy as np +import tritonclient.grpc as grpcclient + +# To ensure MODEL_NAME == test_.py +MODEL_NAME = Path(__file__).stem.replace("test_", "") + + +def test_available_http(): + lib_test_available_http(MODEL_NAME, SERVER_HTTP) + + +def test_available_grpc(): + lib_test_available_grpc(MODEL_NAME, SERVER_GRPC) + + +def test_inference(): + + SEQUENCES = np.array( + [["HIISVM[UNIMOD:35]R"]], + dtype=np.object_, + ) + + triton_client = grpcclient.InferenceServerClient(url=SERVER_GRPC) + + in_pep_seq = grpcclient.InferInput("peptide_sequences", [1, 1], "BYTES") + in_pep_seq.set_data_from_numpy(SEQUENCES) + + result = triton_client.infer( + MODEL_NAME, + inputs=[in_pep_seq], + outputs=[ + grpcclient.InferRequestedOutput("precursor_mass"), + ], + ) + + mass = result.as_numpy("precursor_mass") + ground_truth = 0.0427743459608515 + + result = triton_client.infer( + MODEL_NAME, + inputs=[in_pep_seq], + outputs=[ + grpcclient.InferRequestedOutput("precursor_mass_with_oxM"), + ], + ) + + mass = result.as_numpy("precursor_mass_with_oxM") + ground_truth = 871.481819 + print(mass) + assert np.allclose(mass[0], ground_truth, atol=1e-4) diff --git a/clients/python/test/PredFull/test_PredFull_Preprocess_peptide.py b/clients/python/test/PredFull/test_PredFull_Preprocess_peptide.py new file mode 100644 index 00000000..4f396fb7 --- /dev/null +++ b/clients/python/test/PredFull/test_PredFull_Preprocess_peptide.py @@ -0,0 +1,325 @@ +from test.server_config import SERVER_GRPC, SERVER_HTTP +from pathlib import Path +from test.lib import lib_test_available_grpc, lib_test_available_http +import numpy as np +import tritonclient.grpc as grpcclient + +# To ensure MODEL_NAME == test_.py +MODEL_NAME = Path(__file__).stem.replace("test_", "") + + +def test_available_http(): + lib_test_available_http(MODEL_NAME, SERVER_HTTP) + + +def test_available_grpc(): + lib_test_available_grpc(MODEL_NAME, SERVER_GRPC) + + +def test_inference(): + + ground_truth = np.array( + [ + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.68529457, + 0.0, + 1.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.5654203, + 0.001, + 1.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.5654203, + 0.002, + 1.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.43516013, + 0.003, + 1.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.49534208, + 0.004, + 1.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.6552024, + 0.005, + 0.0, + 1.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.78050554, + 0.006, + 1.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + ] + ) + + SEQUENCES = np.array( + [["HIISVM[UNIMOD:35]R"], ["HIISVMR"]], + dtype=np.object_, + ) + + triton_client = grpcclient.InferenceServerClient(url=SERVER_GRPC) + + in_pep_seq = grpcclient.InferInput("peptide_sequences", [2, 1], "BYTES") + in_pep_seq.set_data_from_numpy(SEQUENCES) + + result = triton_client.infer( + MODEL_NAME, + inputs=[in_pep_seq], + outputs=[ + grpcclient.InferRequestedOutput("input"), + ], + ) + + peptide_embedding = result.as_numpy("input") + + assert np.allclose(peptide_embedding[0, 0:9, :], ground_truth, atol=1e-4) diff --git a/clients/python/test/PredFull/test_PredFull_core.py b/clients/python/test/PredFull/test_PredFull_core.py new file mode 100644 index 00000000..bdae68fb --- /dev/null +++ b/clients/python/test/PredFull/test_PredFull_core.py @@ -0,0 +1,439 @@ +from test.server_config import SERVER_GRPC, SERVER_HTTP +from pathlib import Path +from test.lib import lib_test_available_grpc, lib_test_available_http +import numpy as np +import tritonclient.grpc as grpcclient + + +# To ensure MODEL_NAME == test_.py +MODEL_NAME = Path(__file__).stem.replace("test_", "") + + +def test_available_http(): + lib_test_available_http(MODEL_NAME, SERVER_HTTP) + + +def test_available_grpc(): + lib_test_available_grpc(MODEL_NAME, SERVER_GRPC) + + +def test_inference(): + peptide_embedding = np.array( + [ + [ + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.68529457, + 0.0, + 1.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.5654203, + 0.001, + 1.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.5654203, + 0.002, + 1.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.43516013, + 0.003, + 1.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.49534208, + 0.004, + 1.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.6552024, + 0.005, + 0.0, + 1.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.78050554, + 0.006, + 1.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + ] + ], + dtype=np.float32, + ) + meta = np.array( + [ + [ + [ + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.04277435, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.3, + ], + ] + ], + dtype=np.float32, + ) + + triton_client = grpcclient.InferenceServerClient(url=SERVER_GRPC) + + in_peptide_embedding = grpcclient.InferInput( + "input", peptide_embedding.shape, "FP32" + ) + in_peptide_embedding.set_data_from_numpy(peptide_embedding) + + in_meta = grpcclient.InferInput("meta_input", meta.shape, "FP32") + in_meta.set_data_from_numpy(meta) + + result = triton_client.infer( + MODEL_NAME, + inputs=[in_peptide_embedding, in_meta], + outputs=[ + grpcclient.InferRequestedOutput("spectrum"), + ], + ) + + intensities = result.as_numpy("spectrum") + print(intensities) + + assert intensities.shape == (1, 20000) + + assert np.allclose( + intensities, + np.load("test/PredFull/numpy_arrays/HIISVMoxR2CID30_rawspectrum.npy"), + rtol=0, + atol=1e-4, + ) diff --git a/models/PredFull/PredFull/config.pbtxt b/models/PredFull/PredFull/config.pbtxt new file mode 100644 index 00000000..210ce5fb --- /dev/null +++ b/models/PredFull/PredFull/config.pbtxt @@ -0,0 +1,165 @@ +max_batch_size: 1000 +platform: "ensemble" +input [ + { + name: "peptide_sequences", + data_type: TYPE_STRING, + dims: [-1] + }, + { + name: "precursor_charges", + data_type: TYPE_INT32, + dims: [1] + }, + { + name: "collision_energies", + data_type: TYPE_FP32, + dims: [1] + }, + { + name: "fragmentation_types", + data_type: TYPE_STRING, + dims: [1] + } +] +output [ + { + name: "mzs", + data_type: TYPE_FP32, + dims: [-1] + }, + { + name: "intensities", + data_type: TYPE_FP32, + dims: [-1] + } +] + +ensemble_scheduling { + step [ + { + model_name: "PredFull_Preprocess_charge" + model_version: 1 + input_map { + key: "precursor_charges" + value: "precursor_charges" + }, + output_map { + key: "precursor_charges_in:0" + value: "precursor_charges_in:0" + } + }, + { + model_name: "PredFull_Preprocess_peptide" + model_version: 1 + input_map { + key: "peptide_sequences" + value: "peptide_sequences" + }, + output_map { + key: "input" + value: "input" + } + }, + { + model_name: "PredFull_Preprocess_collision_energy" + model_version: 1 + input_map { + key: "collision_energies" + value: "collision_energies" + }, + output_map { + key: "norm_collision_energy" + value: "norm_collision_energy" + } + }, + { + model_name: "PredFull_Preprocess_fragmentation_types" + model_version: 1 + input_map { + key: "fragmentation_types" + value: "fragmentation_types" + }, + output_map { + key: "fragmentation_types_encoding" + value: "fragmentation_types_encoding" + } + }, + { + model_name: "PredFull_Preprocess_mass" + model_version: 1 + input_map { + key: "peptide_sequences" + value: "peptide_sequences" + }, + output_map { + key: "precursor_mass" + value: "precursor_mass" + }, + output_map { + key: "precursor_mass_with_oxM" + value: "precursor_mass_with_oxM" + } + }, + { + model_name: "PredFull_Preprocess_combine_meta" + model_version: 1 + input_map { + key: "precursor_charges_in:0" + value: "precursor_charges_in:0" + }, + input_map { + key: "fragmentation_types_encoding" + value: "fragmentation_types_encoding" + }, + input_map { + key: "precursor_mass" + value: "precursor_mass" + }, + input_map { + key: "norm_collision_energy" + value: "norm_collision_energy" + } + output_map { + key: "meta_input" + value: "meta_input" + } + }, + { + model_name: "PredFull_core" + model_version: 1 + input_map { + key: "input" + value: "input" + }, + input_map { + key: "meta_input" + value: "meta_input" + }, + output_map { + key: "spectrum" + value: "spectrum" + } + }, + { + model_name: "PredFull_Postprocess" + model_version: 1 + input_map { + key: "spectrum" + value: "spectrum" + }, + input_map { + key: "precursor_mass_with_oxM" + value: "precursor_mass_with_oxM" + }, + output_map { + key: "mzs" + value: "mzs" + }, + output_map { + key: "intensities" + value: "intensities" + } + } + ] +} diff --git a/models/PredFull/PredFull_Postprocess/1/model.py b/models/PredFull/PredFull_Postprocess/1/model.py new file mode 100644 index 00000000..b94c65d0 --- /dev/null +++ b/models/PredFull/PredFull_Postprocess/1/model.py @@ -0,0 +1,75 @@ +import json +import numpy as np +import triton_python_backend_utils as pb_utils +import math + + +def sparse( + x, y, th=0.001 +): # original python version had th = 0.0002. That feel s abit unnecessary + x = np.asarray(x, dtype="float32") + y = np.asarray(y, dtype="float32") + + y /= np.max(y) + + return x[y > th], y[y > th] + + +class TritonPythonModel: + def __init__(self): + super().__init__() + self.output_dtype = None + + def initialize(self, args): + model_config = json.loads(args["model_config"]) + output0_config = pb_utils.get_output_config_by_name(model_config, "intensities") + self.output_dtype = pb_utils.triton_string_to_numpy(output0_config["data_type"]) + + def execute(self, requests): + responses = [] + all_mzs = [] + all_ints = [] + for request in requests: + # mtx = pb_utils.get_input_tensor_by_name(request, "spectrum").as_numpy() + # np.save("mtx.npy", mtx) + spectra = pb_utils.get_input_tensor_by_name(request, "spectrum").as_numpy() + precursor_mass_with_oxm = pb_utils.get_input_tensor_by_name( + request, "precursor_mass_with_oxM" + ).as_numpy() + + # format this for whole batch. May require not prematurely cutting spectra short based on precursor mass + for i, mass in enumerate(precursor_mass_with_oxm): + spectra[i, min(math.ceil(mass / 0.1), spectra.shape[1]) :] = 0 + spectra = np.square(spectra) + + final_shape1 = 0 + for i in range(spectra.shape[0]): + spectrum = spectra[i, :] + imz = np.arange(0, spectra.shape[1], dtype="int32") * 0.1 + mzs, its = sparse(imz, spectrum) + all_mzs.append(mzs) + all_ints.append(its) + if its.size > final_shape1: + final_shape1 = its.size + + for i, (mzs, ints) in enumerate(zip(all_mzs, all_ints)): + minus_int_array = np.full(final_shape1 - mzs.size, -0.001) + minus_mz_array = np.full(final_shape1 - mzs.size, -1) + all_mzs[i] = np.append(mzs, minus_mz_array) + all_ints[i] = np.append(ints, minus_int_array) + + all_mzs = np.array(all_mzs) + all_ints = np.array(all_ints) + + all_ints *= 1000 + all_mzs = np.round(all_mzs, 2) + all_ints = np.round(all_ints, 4) + + output_tensors = [ + pb_utils.Tensor("mzs", all_mzs.astype(self.output_dtype)), + pb_utils.Tensor("intensities", all_ints.astype(self.output_dtype)), + ] + + responses.append(pb_utils.InferenceResponse(output_tensors=output_tensors)) + + return responses diff --git a/models/PredFull/PredFull_Postprocess/config.pbtxt b/models/PredFull/PredFull_Postprocess/config.pbtxt new file mode 100644 index 00000000..8e911112 --- /dev/null +++ b/models/PredFull/PredFull_Postprocess/config.pbtxt @@ -0,0 +1,26 @@ +max_batch_size: 1000 + +input[ + { + name: 'spectrum', + data_type: TYPE_FP32, + dims: [20000] + }, + { + name: 'precursor_mass_with_oxM', + data_type: TYPE_FP32, + dims: [1] + } +] +output [ + { + name: 'mzs', + data_type: TYPE_FP32, + dims: [-1] + }, + { + name: 'intensities', + data_type: TYPE_FP32, + dims: [-1] + } +] diff --git a/models/PredFull/PredFull_Preprocess_charge/1/model.py b/models/PredFull/PredFull_Preprocess_charge/1/model.py new file mode 100644 index 00000000..225e937b --- /dev/null +++ b/models/PredFull/PredFull_Preprocess_charge/1/model.py @@ -0,0 +1,48 @@ +import json +import triton_python_backend_utils as pb_utils +import numpy as np + +MAX_CHARGE = 30 + + +def indices_to_one_hot(data, nb_classes): + """ + Convert an iterable of indices to one-hot encoded labels. + :param data: charge, int between 1 and 30 + """ + if data > nb_classes or data < 1: + raise RuntimeError("Charge out of range") + targets = np.array([data - 1]) # -1 for 0 indexing + return np.int_((np.eye(nb_classes)[targets])).tolist()[0] + + +def to_one_hot(numeric): + array = [indices_to_one_hot(x, MAX_CHARGE) for x in numeric] + return np.array(array, dtype=float) + + +class TritonPythonModel: + def initialize(self, args): + self.model_config = model_config = json.loads(args["model_config"]) + output0_config = pb_utils.get_output_config_by_name( + self.model_config, "precursor_charges_in:0" + ) + self.output_dtype = pb_utils.triton_string_to_numpy(output0_config["data_type"]) + + def execute(self, requests): # throw error if charge less than 1 or greater than 30 + responses = [] + for request in requests: + # at earliest sign of charge exceeding max, can append TritonError instead + charge_in_raw = pb_utils.get_input_tensor_by_name( + request, "precursor_charges" + ) + charge_in_flat = sum(charge_in_raw.as_numpy().tolist(), []) + charge_in = to_one_hot(charge_in_flat) + t = pb_utils.Tensor( + "precursor_charges_in:0", charge_in.astype(self.output_dtype) + ) + responses.append(pb_utils.InferenceResponse(output_tensors=[t])) + return responses + + def finalize(self): + pass diff --git a/models/PredFull/PredFull_Preprocess_charge/config.pbtxt b/models/PredFull/PredFull_Preprocess_charge/config.pbtxt new file mode 100644 index 00000000..468fe52d --- /dev/null +++ b/models/PredFull/PredFull_Preprocess_charge/config.pbtxt @@ -0,0 +1,15 @@ +max_batch_size: 1000 +input[ + { + name: 'precursor_charges', + data_type: TYPE_INT32, + dims: [1] + } +] +output [ + { + name: 'precursor_charges_in:0', + data_type: TYPE_FP32, + dims: [30] + } +] \ No newline at end of file diff --git a/models/PredFull/PredFull_Preprocess_collision_energy/1/model.py b/models/PredFull/PredFull_Preprocess_collision_energy/1/model.py new file mode 100644 index 00000000..240861e5 --- /dev/null +++ b/models/PredFull/PredFull_Preprocess_collision_energy/1/model.py @@ -0,0 +1,33 @@ +import triton_python_backend_utils as pb_utils +import numpy as np +import json + + +class TritonPythonModel: + def initialize(self, args): + self.model_config = json.loads(args["model_config"]) + output0_config = pb_utils.get_output_config_by_name( + self.model_config, "norm_collision_energy" + ) + self.output_dtype = pb_utils.triton_string_to_numpy(output0_config["data_type"]) + + def execute(self, requests): + responses = [] + for request in requests: + raw_ce = pb_utils.get_input_tensor_by_name( + request, "collision_energies" + ).as_numpy() + + for i in range(raw_ce.shape[0]): + if raw_ce[i] == 0: + raw_ce[i] = 25 + + t = pb_utils.Tensor( + "norm_collision_energy", (raw_ce / 100).astype(self.output_dtype) + ) + # will need to eventually cast to vector of length 30 + responses.append(pb_utils.InferenceResponse(output_tensors=[t])) + return responses + + def finalize(self): + pass diff --git a/models/PredFull/PredFull_Preprocess_collision_energy/config.pbtxt b/models/PredFull/PredFull_Preprocess_collision_energy/config.pbtxt new file mode 100644 index 00000000..32ed3baf --- /dev/null +++ b/models/PredFull/PredFull_Preprocess_collision_energy/config.pbtxt @@ -0,0 +1,15 @@ +max_batch_size: 1000 +input[ + { + name: 'collision_energies', + data_type: TYPE_FP32, + dims: [1] + } +] +output [ + { + name: 'norm_collision_energy', + data_type: TYPE_FP32, + dims: [1] + } +] \ No newline at end of file diff --git a/models/PredFull/PredFull_Preprocess_combine_meta/1/model.py b/models/PredFull/PredFull_Preprocess_combine_meta/1/model.py new file mode 100644 index 00000000..e037cfb6 --- /dev/null +++ b/models/PredFull/PredFull_Preprocess_combine_meta/1/model.py @@ -0,0 +1,42 @@ +import json +import triton_python_backend_utils as pb_utils +import numpy as np + + +class TritonPythonModel: + def initialize(self, args): + self.model_config = model_config = json.loads(args["model_config"]) + output0_config = pb_utils.get_output_config_by_name( + self.model_config, "meta_input" + ) + self.output_dtype = pb_utils.triton_string_to_numpy(output0_config["data_type"]) + + def execute(self, requests): + responses = [] + for request in requests: + charge = pb_utils.get_input_tensor_by_name( + request, "precursor_charges_in:0" + ).as_numpy() + fragmentation = pb_utils.get_input_tensor_by_name( + request, "fragmentation_types_encoding" + ).as_numpy() + mass = pb_utils.get_input_tensor_by_name( + request, "precursor_mass" + ).as_numpy() + nce = pb_utils.get_input_tensor_by_name( + request, "norm_collision_energy" + ).as_numpy() + + meta = np.zeros((charge.shape[0], 3, 30)) # testing + for i in range(charge.shape[0]): + meta[i, 0, :] = charge[i, :] + meta[i, 1, :] = fragmentation[i, :] + meta[i, 2, 0] = mass[i] + meta[i, 2, -1] = nce[i] + + t = pb_utils.Tensor("meta_input", meta.astype(self.output_dtype)) + responses.append(pb_utils.InferenceResponse(output_tensors=[t])) + return responses + + def finalize(self): + pass diff --git a/models/PredFull/PredFull_Preprocess_combine_meta/config.pbtxt b/models/PredFull/PredFull_Preprocess_combine_meta/config.pbtxt new file mode 100644 index 00000000..8bed89d3 --- /dev/null +++ b/models/PredFull/PredFull_Preprocess_combine_meta/config.pbtxt @@ -0,0 +1,30 @@ +max_batch_size: 1000 +input [ + { + name: 'precursor_charges_in:0', + data_type: TYPE_FP32, + dims: [30] + }, + { + name: 'fragmentation_types_encoding', + data_type: TYPE_FP32, + dims: [30], + }, + { + name: 'precursor_mass', + data_type: TYPE_FP32, + dims: [1] + }, + { + name: 'norm_collision_energy', + data_type: TYPE_FP32, + dims: [1] + } +] +output [ + { + name: 'meta_input', + data_type: TYPE_FP32, + dims: [3, 30] + } +] \ No newline at end of file diff --git a/models/PredFull/PredFull_Preprocess_fragmentation_types/1/model.py b/models/PredFull/PredFull_Preprocess_fragmentation_types/1/model.py new file mode 100644 index 00000000..f38bf1c6 --- /dev/null +++ b/models/PredFull/PredFull_Preprocess_fragmentation_types/1/model.py @@ -0,0 +1,50 @@ +import triton_python_backend_utils as pb_utils +import numpy as np +import json + +ftypes = {"UN": 0, "CID": 1, "ETD": 2, "HCD": 3, "ETHCD": 4, "ETCID": 5} + + +def map_fragtypes(data): + datanum = ftypes[data] + targets = np.array([datanum]) + return np.int_((np.eye(30)[targets])).tolist()[0] + + +def to_one_hot(fragtypes): + array = [map_fragtypes(x) for x in fragtypes] + return np.array(array, dtype=float) + + +class TritonPythonModel: + def __init__(self): + super().__init__() + self.output_dtype = None + + def initialize(self, args): + model_config = json.loads(args["model_config"]) + output0_config = pb_utils.get_output_config_by_name( + model_config, "fragmentation_types_encoding" + ) + self.output_dtype = pb_utils.triton_string_to_numpy(output0_config["data_type"]) + + def execute(self, requests): + responses = [] + for request in requests: + fragmentation_types = pb_utils.get_input_tensor_by_name( + request, "fragmentation_types" + ) + fragmentation_types = sum( + np.char.upper(fragmentation_types.as_numpy().astype(str)).tolist(), [] + ) + fragmentation_types_encoding = to_one_hot(fragmentation_types) + + t = pb_utils.Tensor( + "fragmentation_types_encoding", + fragmentation_types_encoding.astype(self.output_dtype), + ) + responses.append(pb_utils.InferenceResponse(output_tensors=[t])) + return responses + + def finalize(self): + pass diff --git a/models/PredFull/PredFull_Preprocess_fragmentation_types/config.pbtxt b/models/PredFull/PredFull_Preprocess_fragmentation_types/config.pbtxt new file mode 100644 index 00000000..c7a168cb --- /dev/null +++ b/models/PredFull/PredFull_Preprocess_fragmentation_types/config.pbtxt @@ -0,0 +1,15 @@ +max_batch_size: 1000 +input[ + { + name: 'fragmentation_types', + data_type: TYPE_STRING, + dims: [1] + } +] +output [ +{ + name: 'fragmentation_types_encoding', + data_type: TYPE_FP32, + dims: [30] + } +] \ No newline at end of file diff --git a/models/PredFull/PredFull_Preprocess_mass/1/model.py b/models/PredFull/PredFull_Preprocess_mass/1/model.py new file mode 100644 index 00000000..96ac8cb1 --- /dev/null +++ b/models/PredFull/PredFull_Preprocess_mass/1/model.py @@ -0,0 +1,81 @@ +import triton_python_backend_utils as pb_utils +import numpy as np +import json +from pyteomics import mass + + +def getmod(pep): + mod = np.zeros(len(pep)) + + if pep.isalpha(): + return pep, mod + + seq = [] + + i = -1 + while len(pep) > 0: + if pep[0] == "[": + if pep[8:11] == "35]": + mod[i] = 1 + pep = pep[11:] + else: # not oxM + mod[i] = -1 + return pep, mod + else: + seq += pep[0] + pep = pep[1:] + i = len(seq) - 1 + + return "".join(seq), mod[: len(seq)] + + +class TritonPythonModel: + def __init__(self): + super().__init__() + self.output_dtype = None + + def initialize(self, args): + model_config = json.loads(args["model_config"]) + output0_config = pb_utils.get_output_config_by_name( + model_config, "precursor_mass" + ) + self.output_dtype = pb_utils.triton_string_to_numpy(output0_config["data_type"]) + + def execute(self, requests): + responses = [] + for request in requests: + peptide_in = pb_utils.get_input_tensor_by_name(request, "peptide_sequences") + peptides_ = peptide_in.as_numpy().tolist() + peptide_in_list = [x[0].decode("utf-8") for x in peptides_] + masses = [] + masses_with_oxm = [] # for postprocessing + + for seq in peptide_in_list: + seq, mod = getmod(seq) # move getmod as separate python file + if np.any(mod == -1): + raise RuntimeError("Only Oxidation modification is supported") + + base = mass.fast_mass(seq, ion_type="M", charge=1) + base += 57.021 * seq.count("C") + base_with_oxm = base + 15.9949 * sum(mod) + base /= 20000.0 + masses.append(base) + masses_with_oxm.append(base_with_oxm) + + masses = np.array(masses) + # masses = np.reshape(masses, (1, 1)) # testing + masses_with_oxm = np.array(masses_with_oxm) + # masses_with_oxm = np.reshape(masses_with_oxm, (1, 1)) # testing + t = pb_utils.Tensor( + "precursor_mass", + masses.astype(self.output_dtype), + ) + t2 = pb_utils.Tensor( + "precursor_mass_with_oxM", + masses_with_oxm.astype(self.output_dtype), + ) + responses.append(pb_utils.InferenceResponse(output_tensors=[t, t2])) + return responses + + def finalize(self): + pass diff --git a/models/PredFull/PredFull_Preprocess_mass/config.pbtxt b/models/PredFull/PredFull_Preprocess_mass/config.pbtxt new file mode 100644 index 00000000..a45a37bf --- /dev/null +++ b/models/PredFull/PredFull_Preprocess_mass/config.pbtxt @@ -0,0 +1,22 @@ +max_batch_size: 1000 +input[ + { + name: 'peptide_sequences', + data_type: TYPE_STRING, + dims: [-1] + } +] +output [ + { + name: 'precursor_mass', + data_type: TYPE_FP32, + dims: [1] + reshape: {shape: []} + }, + { + name: 'precursor_mass_with_oxM', + data_type: TYPE_FP32, + dims: [1] + reshape: {shape: []} + } +] \ No newline at end of file diff --git a/models/PredFull/PredFull_Preprocess_peptide/1/model.py b/models/PredFull/PredFull_Preprocess_peptide/1/model.py new file mode 100644 index 00000000..0bcbda9c --- /dev/null +++ b/models/PredFull/PredFull_Preprocess_peptide/1/model.py @@ -0,0 +1,121 @@ +import json +import numpy as np +import triton_python_backend_utils as pb_utils + +Alist = list("ACDEFGHIKLMNPQRSTVWYZ") +charMap = {"*": 0, "]": len(Alist) + 1, "[": len(Alist) + 2} +for i, a in enumerate(Alist): + charMap[a] = i + 1 + +ENCODING_DIMENSION = 24 + +mono = { + "G": 57.021464, + "A": 71.037114, + "S": 87.032029, + "P": 97.052764, + "V": 99.068414, + "T": 101.04768, + "C": 160.03019, + "L": 113.08406, + "I": 113.08406, + "D": 115.02694, + "Q": 128.05858, + "K": 128.09496, + "E": 129.04259, + "M": 131.04048, + "m": 147.0354, + "H": 137.05891, + "F": 147.06441, + "R": 156.10111, + "Y": 163.06333, + "N": 114.04293, + "W": 186.07931, + "O": 147.03538, +} + + +def getmod(pep): + mod = np.zeros(len(pep)) + + if pep.isalpha(): + return pep, mod + + seq = [] + + i = -1 + while len(pep) > 0: + if pep[0] == "[": + if pep[8:11] == "35]": + mod[i] = 1 + pep = pep[11:] + else: # not oxM + mod[i] = -1 + return pep, mod + else: + seq += pep[0] + pep = pep[1:] + i = len(seq) - 1 + + return "".join(seq), mod[: len(seq)] + + +class TritonPythonModel: + def initialize(self, args): + self.model_config = model_config = json.loads(args["model_config"]) + output0_config = pb_utils.get_output_config_by_name(self.model_config, "input") + self.output_dtype = pb_utils.triton_string_to_numpy(output0_config["data_type"]) + + def execute(self, requests): + responses = [] + + for request in requests: + sequences = [] + peptide_in = pb_utils.get_input_tensor_by_name(request, "peptide_sequences") + peptides_ = peptide_in.as_numpy().tolist() + peptide_in_list = [x[0].decode("utf-8") for x in peptides_] + + pep_dimension = 30 + for seq in peptide_in_list: # can make this more efficient + seq, mod = getmod(seq) + + if len(seq) + 2 > pep_dimension: + pep_dimension = len(seq) + 2 + + for seq in peptide_in_list: + # check for modifications + seq, mod = getmod(seq) + + embedding = np.zeros([pep_dimension, 29], dtype="float32") + + if np.any(mod == -1): + raise RuntimeError("Only Oxidation modification is supported") + + # process base peptide sequence + seq = seq.replace("L", "I") + embedding[len(seq)][ENCODING_DIMENSION - 1] = 1 # ending pos + for i, aa in enumerate(seq): + embedding[i][charMap[aa]] = 1 + embedding[i][ENCODING_DIMENSION] = ( + mono[aa] / 200 + ) # mass of AA divided by 200 + embedding[: len(seq), ENCODING_DIMENSION + 1] = ( + np.arange(len(seq)) / 1000 + ) # position info #position divided by 1000 + embedding[len(seq) + 1, 0] = 1 # padding info + + # still need to encode mod + for i, modi in enumerate(mod): + embedding[i][ENCODING_DIMENSION + 2 + int(modi)] = 1 + + sequences.append(embedding) + + sequences = np.array(sequences) + + t = pb_utils.Tensor("input", sequences.astype(self.output_dtype)) + + responses.append(pb_utils.InferenceResponse(output_tensors=[t])) + return responses + + def finalize(self): + pass diff --git a/models/PredFull/PredFull_Preprocess_peptide/config.pbtxt b/models/PredFull/PredFull_Preprocess_peptide/config.pbtxt new file mode 100644 index 00000000..16177d5f --- /dev/null +++ b/models/PredFull/PredFull_Preprocess_peptide/config.pbtxt @@ -0,0 +1,15 @@ +max_batch_size: 1000 +input[ + { + name: 'peptide_sequences', + data_type: TYPE_STRING, + dims: [-1] + } +] +output [ + { + name: 'input', + data_type: TYPE_FP32, + dims: [-1, 29] + } +] \ No newline at end of file diff --git a/models/PredFull/PredFull_core/1/.zenodo b/models/PredFull/PredFull_core/1/.zenodo new file mode 100644 index 00000000..ac748a53 --- /dev/null +++ b/models/PredFull/PredFull_core/1/.zenodo @@ -0,0 +1,2 @@ +https://zenodo.org/records/14675474/files/model.savedmodel.zip?download=1 +md5:803d8fc9cde2c0407f84f10064883726 diff --git a/models/PredFull/PredFull_core/config.pbtxt b/models/PredFull/PredFull_core/config.pbtxt new file mode 100644 index 00000000..9a8715bc --- /dev/null +++ b/models/PredFull/PredFull_core/config.pbtxt @@ -0,0 +1 @@ +max_batch_size: 1000