The Binding of Asymmetric Ligands to an
Infinite Anisotropic Linear Lattice by Alan R. Wolfe

This Mathematica  notebook calculates and plots the Scatchard plot, neighbor-effect parameters, q, conditional probabilities, and length distribution of clusters of bound ligands for the anisotropic lattice, asymmetric ligand case with two binding modes (n1 need not equal n2).  It also permits comparison of an experimental Scatchard plot with the calculated theoretical data.  It can only be used after the appropriate initialization notebook has been evaluated.  To perform the calculations, simply set the input variables to the desired values and execute the "Kernel-> Evaluation-> Evaluate Notebook" command.  This may be repeated with different values for the input variables.  

The notebook may also be executed in sections.  To operate in this manner, the input parameters cell (as well as the experimental data cell, if desired) must be executed first.  Then, the cell immediately below the first "Calculate…" heading must be executed.  The Scatchard plot or any of the neighbor-effect parameters or conditional probabilities can then be displayed in any order.  It's easiest to start by simply selecting the right-most cell grouping bracket and executing everything from the input parameters to the Scatchard plot.  After executing the first calculation cell, any of the 3-D cluster length plots can be displayed by first executing the cell immediately below the second "Calculate…" heading, followed by the desired 3-D plot.  After executing the first calculation cell, any of the 2-D cluster length plots can be displayed by first executing the cell immediately below the third "Calculate…" heading, followed by the desired 2-D plot.  

The initial value of experimentalrLf (= experimental r/[free ligand]) must be positive, and experimentalData must be True, in order to perform the experimental vs. theoretical comparison.  If experimentalData is False, only theoretical data will be generated (over n = points equal intervals on the r axis).  If experimentalData is True, and the initial value of experimentalrLf is negative, again only theoretical data will be generated, but this time using the list of experimental r values provided (rExpArray).

INPUT VARIABLES:

points = 10; k1 = 1; k2 = 2; n1 = 1; n2 = 1; w11 = 1; 
w22 = 2; w12 = 0.1; w21 = 4; experimentalData = True; 
(* variables for cluster length plots: *) 
rCluster2D = 0.9; maxLength2D = 6; 
points3D = 10; maxLength3D = 5;

rCluster2D*rSat is the r value for which 2D cluster length distribution data will be displayed.  
points3D is the number of equally spaced r values greater than zero for which the cluster length distribution will be displayed in the 3D plots.  
(note - execution will be more efficient if points3D = points).  
maxLength is the maximum cluster length that will be considered.

Experimental Data (* disregarded if experimentalData is False *)

(* experimental r values - x values of most plots *) 
rExpArray = {0.04, 0.05, 0.06, 0.15, 0.25, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 0.95, 0.96} ;

(* The number of points in the two arrays must be equal.  Also, neither array should have values corresponding to an empty or saturated lattice. *)

(* experimental r/[free ligand] values - y values of Scatchard plot.  These will be disregarded if the first value is negative *) 
experimentalrLf = {1.35, 1.49, 1.36, 1.43, 1.28, 1.22, 1.27, 1.15, 1.0, 0.75, 0.39, 0.3, 0.25} ;

(* Choose definitions *) If [ n1==n2, Def1, Def2 ] ; 
Print [ "initial slope = ", initialSlope //N, "   deltaA (dimensionless version) = ", deltaA //N ] ;

(* Calculate the NE parameters, q, and Scatchard plot *) scroll = 1

referencePlot = True ; 

(* Choose definitions *) 
If [ n1==n2, Def1, Def2 ] ; 

(* Initialize loop parameters and output arrays *) 
rSatDetermine ; 
neChoose ; 
If [ experimentalrLf[[1]]<0, useData=False, useData=True ] ; 
If [ experimentalData==False, 
     points2 = points ; 
     xAxisInterval = rSat/(points2) ; 
     abscissa = Range [1, points2-1] ; abscissa2 = {} ; 
     points4 = points2 ; 
     AppendTo [ abscissa2, points4 - 1/2] ; points2 = points2+1 ; 
     AppendTo [ abscissa2, points4 - 1/4] ; points2 = points2+1 ; 
     abscissa = xAxisInterval Join [ abscissa, abscissa2 ] ] ; 
If [ experimentalData==True, 
     abscissa = rExpArray ; 
     points2 = Length [ abscissa ] +1 ; 
     Do [  
          If [ abscissa[[i]] >= rSat, abscissa = Drop [ abscissa, {i,i} ] ], 
          {i, points2-1, 1, -1} ] ; 
     points2 = Length [ abscissa ] +1 ; 
     experimentalrLf = Take [ experimentalrLf, points2-1 ] ] ; 
E1L = E1R = E2L = E2R = 1 ; 
Q = k1/(k1 + k2) ; 

(* Evaluate neighbor-effect parameters and q for r < rSat *) 
startPrint ; 
dropPoints = 0 ; 
ordinate = Map [ Function [ zz, r = zz ; X = r/F ; 
     If [ needCheck, 
          If [ flag==True, {E1L,E1R,E2L,E2R,Q} = {1,1,1,1,0.5} ] ; 
          If [ flag==False, ne ; checkLimits ] ; 
          If [ flag==True, dropPoints = dropPoints + 1 ] , 
          ne ] ; 
     If [ flag==False, Print [ r//N, "    ", rLf//N ] ] ; 
     {rLf,E1L,E1R,E2L,E2R,Q,X,ff} ], abscissa ] ; 
makeReference ; 

(* Evaluate neighbor-effect parameters for r = rSat *) 
PrependTo [ ordinate, {(k1 + k2)/2,1,1,1,1,k1/(k1 + k2),0,1} ] ; 
chooseNEandCP ; 
AppendTo [ ordinate, {0,E1L,E1R,E2L,E2R,Q,0,0} ] ;

(* Indicate which equations were used *) scroll = 1

Print [ "ne = ", neChoice, "; NE = ", NEchoice, "; CP = ", CPchoice ] ;

(* Display the Scatchard plot *) scroll = 1

If [ experimentalData && useData, makePlot2 ] ; 
If [ experimentalData && useData, 
     theoreticalrLf = Table [ ordinate[[i,1]], {i,2,points2} ] ; 
     Print [ "correlation coefficient (R) = ", 
          corrCoeff [ experimentalrLf, theoreticalrLf ] ] ; 
     makeResidualsPlot [ experimentalrLf, theoreticalrLf ] ]

If [ experimentalData && useData, 
     makeResidualsPlot2 [ experimentalrLf, theoreticalrLf ]  ] ;

If [ (n1==n2 || k1==0 || k2==0) && referencePlot, 
     makePlot3, 
     If [ !experimentalData || !useData, 
          makePlot [ 1, 0, "r/Lf", "Scatchard plot" ] ] ] ;

(* Plot q and the neighbor-effect parameters *) scroll = 1

(* q *)

qPlot

(* E1L *)

If [ k1>0, makePlot [ 2, 1, "E1L", "left NE for free b1L sites" ]  ]

(* E1R *)

If [ k2>0, makePlot [ 3, 1, "E1R", "right NE for free b2L sites" ]  ]

(* E2L *)

If [ k2>0, makePlot [ 4, 1, "E2L", "left NE for free b2L sites" ]  ]

(* E2R *)

If [ k1>0, makePlot [ 5, 1, "E2R", "right NE for free b1L sites" ]  ]

(* lattice coverage (if n1≠n2) *)

If [ k1>0 && k2>0 && !n1==n2, latticeCoveragePlot]

(* Plot the conditional probabilities *) scroll = 1

(* ff *)

makePlot [ 8, 0, "ff", "" ]

(* b1Lf *)

If [ k1>0, makeCPplot [ b1Lf, "      b1Lf" ] ]

(* b1Rf *)

If [ k2>0, makeCPplot [ b1Rf, "      b1Rf" ] ]

(* b2Lf *)

If [ k2>0, makeCPplot [ b2Lf, "      b2Lf" ] ]

(* b2Rf *)

If [ k1>0, makeCPplot [ b2Rf, "      b2Rf" ] ]

(* fb1L *)

makeCPplot [ fb1L, "     fb1L" ]

(* fb1R *)

makeCPplot [ fb1R, "     fb1R" ]

(* fb2L *)

makeCPplot [ fb2L, "     fb2L" ]

(* fb2R *)

makeCPplot [ fb2R, "     fb2R" ]

(* b1Lb1R *)

If [ k1>0, makeCPplot [ b1Lb1R, "          b1Lb1R" ] ]

(* b1Rb1L *)

If [ k2>0, makeCPplot [ b1Rb1L, "          b1Rb1L" ] ]

(* b2Lb2R *)

If [ k2>0, makeCPplot [ b2Lb2R, "          b2Lb2R" ] ]

(* b2Rb2L *)

If [ k1>0, makeCPplot [ b2Rb2L, "          b2Rb2L" ] ]

(* b1Lb2R *)

If [ k1>0, makeCPplot [ b1Lb2R, "b1Lb2R  (b2Rb1L) " ] ]

(* b1Rb2L *)

If [ k2>0, makeCPplot [ b1Rb2L, "b1Rb2L  (b2Lb1R) " ] ]

(* Calculate, print and plot 3D cluster length data *) scroll = 1

clusterArray = Table [ 0, {maxLength3D} ] ; 
ligandArray = clusterArray ; 
clusterArray3D = Table [ clusterArray, {points3D+1} ] ; 
ligandArray3D = clusterArray3D ; 
maxLength = maxLength3D ; 
printHeadings ; 
Do [ rCluster = (ij/points3D) ; clusterDistribution ; 
     clusterArray3D[[ij+1]] = clusterArray ; 
     ligandArray3D[[ij+1]] = ligandArray , 
{ ij, 0, points3D} ] ; 
chooseTicks ;

(* plot fraction of clusters, left view *)

threeDplot [ 2.2, -2.4, 1.0, "length         ", "          r/rSat", 
     "f clus.", clusterArray3D, tickArray1 ] ;

(* plot fraction of clusters, right view *)

threeDplot [ 2.2, 2.4, 1.0, "         length", "r/rSat          ", 
     "f clus.", clusterArray3D, tickArray0 ] ;

(* plot fraction of clusters, center view *)

threeDplot [ 2.2, -0.001, 1.0, "     length", "r/rSat", 
     "f clus.", clusterArray3D, tickArray ] ;

(* plot fraction of ligands, left view *)

threeDplot [ 2.2, -2.4, 1.0, "length         ", "          r/rSat", 
     "f lig.", ligandArray3D, tickArray1 ] ;

(* plot fraction of ligands, right view *)

threeDplot [ 2.2, 2.4, 1.0, "         length", "r/rSat          ", 
     "f lig.", ligandArray3D, tickArray0 ] ;

(* plot fraction of ligands, center view *)

threeDplot [ 2.2, -0.001, 1.0, "     length", "r/rSat", 
     "f lig.", ligandArray3D, tickArray ] ;

(* Calculate, print and plot 2D cluster length data *) scroll = 1

If [ (flag==False) || (rCluster2D rSat < rError) || (rCluster2D==1), 
     rCluster = rCluster2D ; maxLength = maxLength2D ; 
     clusterArray = Table [ 0, {maxLength} ] ; 
     ligandArray = clusterArray ; 
     printHeadings ; clusterDistribution ] ; 
Print [ " " ] ; 
If [ (flag==False) || (rCluster2D rSat < rError) || (rCluster2D==1), 
     Print [ "r = ", rCluster2D rSat, "; average cluster length = ", 
          averageClusterLength ] ] ; 
If [ flag && (rCluster2D rSat >= rError) && (rCluster2D < 1), 
     Print [ "r = ", rCluster2D rSat ] ; 
     Print [ "The average cluster length could not be calculated due to a" ] ; 
     Print [ "computational error." ] ] ; 
Print [ "rCluster2D = ", rCluster2D,  
     "; maxLength2D = ", maxLength2D ] ;

(* Plot 2D cluster length data *) scroll = 1

twoDplot [ "fraction clusters", maxClusters, clusterArray ] ;

twoDplot [ "fraction ligands", maxLigands, ligandArray ] ;

rCluster2D = 0.99; maxLength2D = 6;

Note - if the values of rCluster2D (= r/rSat) and/or maxLength2D are changed and the cell assigning these values is executed, the cluster length distribution can be recalculated for the new value(s) by selecting and executing the group of cells above this group.  (The selection is executed by hitting the "shift-return" keys or the "enter" key.)