From c3ee9aa1ccb8e48689fed07efc8c3db985e316c8 Mon Sep 17 00:00:00 2001 From: samuel-amidon Date: Wed, 18 Dec 2024 13:16:45 -0800 Subject: [PATCH] move affinity initialization to optimization function --- bicytok/figures/figure1.py | 4 ---- bicytok/figures/figure4.py | 3 --- bicytok/figures/figure5.py | 3 --- bicytok/selectivityFuncs.py | 22 +++++++++++++++------- 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/bicytok/figures/figure1.py b/bicytok/figures/figure1.py index 057e381..7d59729 100644 --- a/bicytok/figures/figure1.py +++ b/bicytok/figures/figure1.py @@ -63,7 +63,6 @@ def makeFigure(): ) targCell = "Treg" offTargCells = cells[cells != targCell] - startingAff = 8.0 epitopesList = pd.read_csv( path_here / "bicytok" / "data" / "epitopeList.csv" @@ -76,12 +75,10 @@ def makeFigure(): for targetPairs in allTargets: print(targetPairs) - prevOptAffs = [startingAff] valencies = [signal[1]] targets = [] naming = [] for target, valency in targetPairs: - prevOptAffs.append(8.0) targets.append(target) valencies.append(valency) naming.append(f"{target} ({valency})") @@ -99,7 +96,6 @@ def makeFigure(): for dose in doseVec: optSelec, optParams = optimizeSelectivityAffs( - initialAffs = prevOptAffs, targRecs = targRecs.to_numpy(), offTargRecs = offTargRecs.to_numpy(), dose = dose, diff --git a/bicytok/figures/figure4.py b/bicytok/figures/figure4.py index aab8155..a5981ea 100644 --- a/bicytok/figures/figure4.py +++ b/bicytok/figures/figure4.py @@ -60,11 +60,9 @@ def makeFigure(): # targeting SIGNAL and 2 subunits corresponding to target1? # Right now it's just 1 subunit for target1. targetsBoth = [target1] - optAffs = [8.0, 8.0] valenciesBoth = np.array([[signal[1], valencies[i]]]) else: targetsBoth = [target1, target2] - optAffs = [8.0, 8.0, 8.0] valenciesBoth = np.array([[signal[1], valencies[i], valencies[j]]]) dfTargCell = epitopesDF.loc[ @@ -77,7 +75,6 @@ def makeFigure(): offTargRecs = dfOffTargCell[[signal[0]] + targetsBoth] optSelec, optParams = optimizeSelectivityAffs( - initialAffs = optAffs, targRecs = targRecs.to_numpy(), offTargRecs = offTargRecs.to_numpy(), dose = dose, diff --git a/bicytok/figures/figure5.py b/bicytok/figures/figure5.py index c33e772..298e9b5 100644 --- a/bicytok/figures/figure5.py +++ b/bicytok/figures/figure5.py @@ -93,7 +93,6 @@ def makeFigure(): ) for valency in valencies: - prevOptAffs = [8.0, 8.0, 8.0] for targets in allTargets: modelValencies = np.array([[signal_valency, valency, valency]]) @@ -107,13 +106,11 @@ def makeFigure(): offTargRecs = dfOffTargCell[[signal_receptor] + targets] optSelec, optParams = optimizeSelectivityAffs( - initialAffs = prevOptAffs, targRecs = targRecs, offTargRecs = offTargRecs, dose = dose, valencies = modelValencies ) - prevOptAffs = optParams select = (1 / optSelec,) non_marker_columns = ["CellType1", "CellType2", "CellType3", "Cell"] diff --git a/bicytok/selectivityFuncs.py b/bicytok/selectivityFuncs.py index e7860ae..7731d03 100644 --- a/bicytok/selectivityFuncs.py +++ b/bicytok/selectivityFuncs.py @@ -59,6 +59,7 @@ def minOffTargSelec( """ # Reformat input affinities to 10^aff and diagonalize + # Sam: shouldn't this be done before the optimization? modelAffs = restructureAffs(monomerAffs) # Use the binding model to calculate bound receptors for target and off-target cell types @@ -85,7 +86,6 @@ def minOffTargSelec( # Called in Figure1, Figure4, and Figure5 def optimizeSelectivityAffs( - initialAffs: list, targRecs: np.ndarray, offTargRecs: np.ndarray, dose: float, @@ -108,20 +108,29 @@ def optimizeSelectivityAffs( """ # Relabel initial affinities to a variable that will be altered during optimization - X0 = initialAffs + - # Set bounds for optimization + # Choose initial affinities and set bounds for optimization # minAffs and maxAffs chosen based on biologically realistic affinities for engineered ligands # Sam: affinities are maxing and bottoming out before optimization is complete... - # for fig1, target 1, final affinities are 1e7 and ~1e9 (9.997e8) + # for fig1, target 1, final affinities are 1e7 and ~1e9 (9.997e8) (with bounds 7 and 9) minAffs = [7.0] * (targRecs.shape[1]) maxAffs = [9.0] * (targRecs.shape[1]) - optBnds = Bounds(np.full_like(X0, minAffs), np.full_like(X0, maxAffs)) + initAffs = np.full_like( + valencies[0], # Correct this if sizes of initial affinities and valencies are not always the same + minAffs[0] + (maxAffs[0] - minAffs[0]) / 2 # Start at midpoint between min and max bounds + ) + optBnds = Bounds( + np.full_like(initAffs, minAffs), + np.full_like(initAffs, maxAffs) + ) + print(initAffs) + print(optBnds) # Run optimization to minimize off-target selectivity by changing affinities optimizer = minimize( minOffTargSelec, - X0, + initAffs, bounds=optBnds, args=( targRecs, @@ -137,7 +146,6 @@ def optimizeSelectivityAffs( return optSelect, optAffs -# Called in sampleReceptorAbundances # Sam: reimplement this function when we have a clearer idea # of how to calculate conversion factors def calcCITEConvFacts(CITE_DF: pd.DataFrame) -> pd.DataFrame: