Monod-Wyman-Changeux Analysis of Ligand-Gated Ion Channel Mutants Supporting Information

The following code reproduces the plots in the main text. Made on Mathematica version 10.4.1 for Windows. Sections can be opened by mouse click.

Raw data can be found here

Figures

Figure 3: nAChR Dose-Response and Data Collapse

Since all (Subscript[K, D]) parameters are necessarily positive, we fit their logarithms. In other words, we do not fit (Subscript[K, D]) but rather (Subscript[K, D]^log) defined as (Subscript[K, D])=(e^(Subscript[K, D]^log)).

(* Fitting the nAChR data sets. Note that due to the degeneracy in the parameters, the energy of the fully mutated nAChR ion channel, βϵ[1], can take on any value and still yield a good fit. Here, we arbitrarily set this parameter to βϵ[1]=-4, but see the sloppiness figure for more details on the possible degenerate parameter sets *)
fit=NonlinearModelFit[Flatten[nAChRdata,1],{nAChRFitFunction,βϵ[1]==-4.},{{KOlog,-22.76},{KClog,-11.7486},{βϵ[1],-4.},{βϵ[2],-9.},{βϵ[3],-14.},{βϵ[4],-19.},{βϵ[5],-24.}},{χ1,χ2,χ3,χ4,χ5,c}];
(*Echo[fit[{"RSquared","BestFitParameters"}]];*)

(* Plotting the fits *)
leg=PointLegend[colors,nAChRlabels,LegendMarkers->({Graphics[{EdgeForm[{Thickness[Medium],White}],{White,Thin,Circle[{0,0},0.1]},Disk[{0,0},0.1]}],0.03}&/@Range@4),Spacings->{0.1,0.4}];
plotA=Labeled[With[{opts=opts},Show[LogLinearPlot[Evaluate[nAChRFitFunction/.fit["BestFitParameters"]/.#&/@mutantsList],{c,(10^(-11)),(10^(-2))},PlotRange->{{(10^(-10)),(10^(-2.7))},{-0.01,1.07}},PlotLegends->Placed[leg,{Scaled[{0.78,0.33}], {0, 0.5}}],FrameLabel->frameLabel1,PlotStyle->colors[[5;;1;;-1]],opts],ListLogLinearPlot[data,PlotMarkers->{Graphics[{EdgeForm[{Thickness[Tiny],White}],Disk[{0,0},0.1]}],0.03},PlotStyle->colors[[5;;1;;-1]]]]
],aLabel,{{Top,Left}}];

(* === Begin Data Collapse Plot === *)
(* The Bohr parameter 'F' enables us to collapse all of the data sets *)
F=-Log[(1/nAChRpBound)-1]/.nAChRreplace;
(* We convert the data from normalized current to (Subscript[p, open])=(normalized current)(dynamic range)+(leakiness) where (dynamic range)=(Subscript[p, open]^max)-(Subscript[p, open]^min) and (leakiness)=(Subscript[p, open]^min) *)
dataCollapse=Map[{F,val*((nAChRpMax-nAChRpMin)/.nAChRreplace)+(nAChRpMin/.nAChRreplace)}/.Thread[{χ1,χ2,χ3,χ4,χ5,c,val}->#]&,nAChRdata,{2}]/.fit["BestFitParameters"];

(* Plotting *)
plotB=Labeled[Show[Plot[(1/(1+(E^(-x)))),{x,-6.2,6.16},PlotStyle->Black,PlotRange->{{-6.2,6.2},{-0.01,1.07}},FrameLabel->frameLabel2,Evaluate@opts],ListPlot[dataCollapse,PlotMarkers->{Graphics[{EdgeForm[{Thickness[Tiny],White}],Disk[{0,0},0.1]}],0.03},PlotStyle->colors[[5;;1;;-1]]]],bLabel,{{Top,Left}}];

grid=Grid[{{plotA,plotB}}]

Figure 4: nAChR Leakiness, Dynamic Range, [(Subscript[EC, 50])], Effective Hill Coefficient

Compute the leakiness ((Subscript[p, open]^min)), dynamic range ((Subscript[p, open]^max)-(Subscript[p, open]^min)), [(Subscript[EC, 50])] (concentration at which (Subscript[p, open])(c)=(((Subscript[p, open]^max)+(Subscript[p, open]^min))/2)), and effective Hill coefficient (log-slope at c=[(Subscript[EC, 50])]) for the nAChR mutant class.

(* Get the nAChR fit parameters from Figure 2 *)
fit=NonlinearModelFit[Flatten[nAChRdata,1],{nAChRFitFunction,βϵ[1]==-4.},{{KOlog,-22.76},{KClog,-11.7486},{βϵ[1],-4.},{βϵ[2],-9.},{βϵ[3],-14.},{βϵ[4],-19.},{βϵ[5],-24.}},{χ1,χ2,χ3,χ4,χ5,c}];
nAChRValues=fit["BestFitParameters"];

(* Analytic form of [(Subscript[EC, 50])] and effective Hill coefficient *)
EC50Exact=c/.Last@FullSimplify@Solve[((((1+(c/KO)))^2)/((((1+(c/KO)))^2)+(E^(-βϵ))(((1+(c/KC)))^2)))==(1/2) ((1/((E^(-βϵ))+1))+((KC^2)/((E^(-βϵ))(KO^2)+(KC^2)))),c];
hExact=FullSimplify[2*c*D[Log[nAChRpNormalized],c]/.c->EC50Exact];
(* Fit values *)
fitValues=fit["BestFitParameters"];
(* Identify the leakiness and dynamic range for the n=0,1,2,3,4 cases from Figure 2 *)
pointsLeak=Transpose@{Table[βϵ[j],{j,5}]/.fitValues,nAChRpMin/.nAChRreplace/.fitValues/.#&/@mutantsList};
pointsDyn=Transpose@{Table[βϵ[j],{j,5}]/.fitValues,nAChRpMax-nAChRpMin/.nAChRreplace/.fitValues/.#&/@mutantsList};

(* Plotting *)
{βϵMin,βϵMax}={-30,3}; (* Plot range *)
xBounds={βϵMin-0.7,βϵMax+0.5}; (* Plot range windowd *)
(* Plot legends *)
leg=PointLegend[colors,nAChRlabels,LegendMarkers->({marker,0.03}&/@Range@4),Spacings->{0.1,0.4}];
plotA=Labeled[
With[{opts=opts},Show[LogPlot[nAChRpMin,{βϵ,βϵMin,βϵMax},PlotStyle->ColorData[95][4],FrameLabel->frameLabel3,Axes->False,PlotRange->{xBounds,{(10^(-12.5)),2}},PlotLegends->Placed[leg,{Scaled[{0.75,0.4}], {0, 0.5}}],opts],ListLogPlot[List/@pointsLeak,PlotMarkers->{marker,markerSize},PlotStyle->colors[[5;;1;;-1]]]]
],aLabel,{{Top,Left}}];
plotB=Labeled[
With[{opts=opts},Show[Plot[nAChRpMax-nAChRpMin/.nAChRreplace/.fitValues,{βϵ,βϵMin,βϵMax},PlotStyle->ColorData[95][4],FrameLabel->frameLabel4,Axes->False,PlotRange->{xBounds,{-0.01,1.07}},opts],ListPlot[List/@pointsDyn,PlotMarkers->{marker,markerSize},PlotStyle->colors[[5;;1;;-1]]]]
],bLabel,{{Top,Left}}];

(* === Begin [(Subscript[EC, 50])] === *)
(* [(Subscript[EC, 50])] curve for the nAChR family of mutants *)
curvesEC50={EC50Exact/.{KO->(E^KOlog),KC->(E^KClog)}/.fitValues};
(* [(Subscript[EC, 50])] of the 5 dose response curves n=0,1,2,3,4 *)
pointsEC50=Transpose@Join[{Table[βϵ[j],{j,5}]/.fitValues},{Flatten[curvesEC50/.nAChRreplace/.fitValues/.mutantsList]}];

(* We next compute the [(Subscript[EC, 50])] and the effective Hill coefficients (h) from the data. To do this, we fit each data set separately to the MWC model, thereby guaranteeing that the theory curve will closely match the exact shape of the data. Then, we extract the [(Subscript[EC, 50])] and effective Hill coefficient from the resulting curve *)
{EC50Values,hValues}=Transpose[(
newDataIndividualFits=nAChRdata[[#]];
fit=Quiet[NonlinearModelFit[newDataIndividualFits,{nAChRFitFunction},List@@@nAChRValues,{χ1,χ2,χ3,χ4,χ5,c}],NonlinearModelFit::lstol];
bestFit=Normal@fit/.mutantsList[[#]];
{#,2c D[Log[bestFit],c]/.c->#}&@(c/.FindRoot[bestFit-0.5,{c,pointsEC50[[#,2]]}])
)&/@Range@5];

(* Plotting *)
leg=PointLegend[{ColorData[95][4],},characteristicsLabels,LegendMarkers->{{markerColor[],0.03},{Graphics[{EdgeForm[{Thickness[Medium],White}],{White,Thin,Circle[{0,0},0.1]},Disk[{0,0},0.1]}],0.03}},Joined->{True,False},Spacings->{0.1,0.5}];
plotC=Labeled[
With[{opts=opts},Show[LogPlot[curvesEC50,{βϵ,βϵMin,βϵMax},PlotStyle->{{ColorData[95][4],Automatic},{ColorData[95][3],Dashing[Small]}},PlotRange->{xBounds,{(10^(-10.5)),(10^(-3.5))}},FrameLabel->frameLabel5,Axes->False,PlotLegends->Placed[leg,{Scaled[{0.5,0.75}], {0, 0.5}}],Evaluate@opts],ListLogPlot[List/@pointsEC50,PlotMarkers->{marker,markerSize},PlotStyle->colors[[5;;1;;-1]]],ListLogPlot[List/@Transpose@{Table[βϵ[j],{j,5}]/.fitValues,EC50Values},PlotMarkers->{Graphics[{EdgeForm[{Thickness[Tiny],White}],Disk[{0,0},0.1]}],0.03},PlotStyle->colors[[5;;1;;-1]]]]
],cLabel,{{Top,Left}}];

(* === Begin Effective Hill Coefficient (h) === *)
(* Effective Hill coefficient curve for the nAChR family of mutants *)
curvesH={hExact/.{KO->(E^KOlog),KC->(E^KClog)}/.fitValues};
(* Effective Hill coefficient for the 5 dose response curves n=0,1,2,3,4 *)
pointsH=Transpose@Join[{Table[βϵ[j],{j,5}]/.fitValues},{Flatten[curvesH/.nAChRreplace/.fitValues/.mutantsList]}];

(* Plotting *)
plotD=Labeled[
With[{opts=opts},Show[Plot[curvesH,{βϵ,βϵMin,βϵMax},PlotStyle->{{ColorData[95][4],Automatic},{ColorData[95][3],Dashing[Small]}},FrameLabel->frameLabel6,PlotRange->{xBounds,{-0.01,2.1}},opts],ListPlot[List/@pointsH,PlotMarkers->{marker,markerSize},PlotStyle->colors[[5;;1;;-1]]],ListPlot[List/@Transpose@{Table[βϵ[j],{j,5}]/.fitValues,hValues},PlotMarkers->{Graphics[{EdgeForm[{Thickness[Tiny],White}],Disk[{0,0},0.1]}],0.03},PlotStyle->colors[[5;;1;;-1]]]]
],dLabel,{{Top,Left}}];

grid=Grid[{{plotA,plotB},{plotC,plotD}}]

Figure 6: CNGA2 Dose-Response and Data Collapse

As in the case of nAChR, we fit the logarithms of all (Subscript[K, D]) parameters, which are necessarily positive. In other words, we do not fit (Subscript[K, D]) but rather (Subscript[K, D]^log) defined as (Subscript[K, D])=(e^(Subscript[K, D]^log)).

(* Fitting the CNGA2 data sets. Note that due to the degeneracy in the parameters, the closed, inactive state's affinity to ligand (KCmutLog in the code or (Subscript[K, C]^( * )) in the text) can take on any value and still yield a good fit. Here, we arbitrarily set this parameter to KCmutLog=-2, but see the sloppiness figure for more details on the possible degenerate parameter sets *)
fit=NonlinearModelFit[Flatten[CNGA2data,1],{CNGA2FitFunction,KCmutLog==-2.},{{KOwtLog,Log[1.2 (10^(-6))]},{KOmutLog,Log[510 (10^(-6))]},{KCwtLog,Log[22 (10^(-6))]},{KCmutLog,Log[140 (10^(-3))]},{βϵ,-3.4}},{nMut,c}];
(*Echo[fit[{"RSquared","BestFitParameters"}]];*)

(* Plotting the fits *)
leg=PointLegend[colors,CNGA2labels,LegendMarkers->({Graphics[{EdgeForm[{Thickness[Medium],White}],{White,Thin,Circle[{0,0},0.1]},Disk[{0,0},0.1]}],0.03}&/@Range@4),Spacings->{0.1,0.4}];
plots=Table[CNGA2FitFunction/.nMut->jj,{jj,0,4}]/.fit["BestFitParameters"];
plotA=Labeled[With[{opts=opts},
Show[LogLinearPlot[plots,{c,(10^(-7)),(10^(-2))},FrameLabel->frameLabel7,opts],ListLogLinearPlot[CNGA2data[[All,All,{2,3}]],PlotMarkers->{Graphics[{EdgeForm[{Thickness[Tiny],White}],Disk[{0,0},0.1]}],0.03},PlotLegends->Placed[leg,{Scaled[{0.78,0.32}], {0, 0.5}}]]]
],aLabel,{{Top,Left}}];

(* === Begin Data Collapse Plot === *)
(* The Bohr parameter 'F' enables us to collapse all of the data sets *)
F=-Log[(1/CNGA2pBound)-1]/.CNGA2replace;
(* We convert the data from normalized current to (Subscript[p, open])=(normalized current)(dynamic range)+(leakiness) where (dynamic range)=(Subscript[p, open]^max)-(Subscript[p, open]^min) and (leakiness)=(Subscript[p, open]^min) *)
dataCollapse=Map[{F,val*((CNGA2pMax-CNGA2pMin)/.CNGA2replace)+(CNGA2pMin/.CNGA2replace)}/.Thread[{nMut,c,val}->#]&,CNGA2data,{2}]/.fit["BestFitParameters"];
(* Plotting *)
plotB=Labeled[Show[Plot[(1/(1+(E^(-x)))),{x,-6.2,6.16},PlotStyle->Black,PlotRange->{{-6.2,6.2},{-0.03,1.07}},FrameLabel->frameLabel8,Evaluate@opts],ListPlot[dataCollapse,PlotMarkers->{Graphics[{EdgeForm[{Thickness[Tiny],White}],Disk[{0,0},0.1]}],0.03},PlotStyle->colors]],bLabel,{{Top,Left}}];

grid=Grid[{{plotA,plotB}}]

Figure 7: CNGA2 States and Weights

Individual state probabilities for all 10 ion channel states for the wild type (n=0) CNGA2 ion channel and the ion channel with all four subunits mutated (n=4).

(* Start with the same CNGA2 fits from Figure 6 *)
fit=NonlinearModelFit[Flatten[CNGA2data,1],{CNGA2FitFunction,KCmutLog==-2.},{{KOwtLog,Log[1.2 (10^(-6))]},{KOmutLog,Log[510 (10^(-6))]},{KCwtLog,Log[22 (10^(-6))]},{KCmutLog,Log[140 (10^(-3))]},{βϵ,-3.4}},{nMut,c}];
(* State probabilities of the 10 wild type (n=0) ion channel states *)
probabilityWT=Join[Table[(c^jj)SeriesCoefficient[(((1+(c/KOwt)))^4),{c,0,jj}],{jj,0,4}],Table[(E^(-βϵ))(c^jj)SeriesCoefficient[(((1+(c/KCwt)))^4),{c,0,jj}],{jj,0,4}]]/((((1+(c/KOwt)))^4)+(E^(-βϵ)) (((1+(c/KCwt)))^4))/.CNGA2replace/.fit["BestFitParameters"];
(* State probabilities of the 10 fully mutated (n=4) ion channel states *)probabilityMut=Join[Table[(c^jj)SeriesCoefficient[(((1+(c/KOmut)))^4),{c,0,jj}],{jj,0,4}],Table[(E^(-βϵ))(c^jj)SeriesCoefficient[(((1+(c/KCmut)))^4),{c,0,jj}],{jj,0,4}]]/((((1+(c/KOmut)))^4)+(E^(-βϵ)) (((1+(c/KCmut)))^4))/.CNGA2replace/.fit["BestFitParameters"];
(* Re-order plots to show {0, open}, {0, closed}, {1, open}, {1, closed}... *)
probabilityWT=Flatten@Transpose@Partition[probabilityWT,5];
probabilityMut=Flatten@Transpose@Partition[probabilityMut,5];

(* Plotting *)
labels=font[#,10]&/@Flatten@Transpose@{font[#,10]&/@Table[Subscript[Style["O",Italic],ToString@jj],{jj,0,4}],font[#,10]&/@Table[Subscript[Style["C",Italic],ToString@jj],{jj,0,4}]};
leg=LineLegend[Flatten@Transpose@Partition[colors3,2],Flatten@Transpose@Partition[labels,2],LegendMarkerSize->14,Spacings->{0.2,0.0}];
plotA=Labeled[With[{opts=opts},
LogLogPlot[Evaluate@probabilityWT,{c,(10^(-7.18)),(10^(-1.82))},FrameLabel->frameLabel9,PlotLegends->Placed[leg,{Scaled[{0.365,0.28}], {0.5, 0.5}}],PlotRange->{{(10^(-7.2)),(10^(-1.8))},{(10^(-12.5)),(10^0.3)}},PlotStyle->colors3,PlotRange->All,opts]
],aLabel,{{Top,Left}}];
plotB=Labeled[With[{opts=opts},
LogLogPlot[Evaluate@probabilityMut,{c,(10^(-6.18)),(10^(-0.82))},FrameLabel->frameLabel10,PlotRange->{{(10^(-6.2)),(10^(-0.8))},{(10^(-12.5)),(10^0.3)}},PlotRange->All,PlotStyle->colors3,opts]
],bLabel,{{Top,Left}}];
grid=Grid[{{plotA,plotB}}]

Figure 8: CNGA2 Leakiness, Dynamic Range, [(Subscript[EC, 50])], Effective Hill Coefficient

Compute the leakiness ((Subscript[p, open]^min)), dynamic range ((Subscript[p, open]^max)-(Subscript[p, open]^min)), [(Subscript[EC, 50])] (concentration at which (Subscript[p, open])(c)=(((Subscript[p, open]^max)+(Subscript[p, open]^min))/2)), and effective Hill coefficient (log-slope at c=[(Subscript[EC, 50])]) for the CNGA2 mutant class.

(* Get the nAChR fit parameters from Figure 8 *)
fit=NonlinearModelFit[Flatten[CNGA2data,1],{CNGA2FitFunction,KCmutLog==-2.},{{KOwtLog,Log[1.2 (10^(-6))]},{KOmutLog,Log[510 (10^(-6))]},{KCwtLog,Log[22 (10^(-6))]},{KCmutLog,Log[140 (10^(-3))]},{βϵ,-3.4}},{nMut,c}];

(* Identify the leakiness and dynamic range for the nMut=0,1,2,3,4 cases from Figure 8 *)
pointsLeak={#,CNGA2pMin/.CNGA2replace/.fit["BestFitParameters"]/.nMut->#}&/@Range[0,4];
pointsDyn={#,CNGA2pMax-CNGA2pMin/.CNGA2replace/.fit["BestFitParameters"]/.nMut->#}&/@Range[0,4];

(* Plotting *)
leg=PointLegend[colors,CNGA2labels,LegendMarkers->({marker,0.03}&/@Range@4),Spacings->{0.45,0.4}];
(* Plot Range *)
xRange={-0.2,4.2};
(* Leakiness *)
plotA=Labeled[
With[{opts=opts},Show[Plot[CNGA2pMin/.CNGA2replace/.fit["BestFitParameters"],{nMut,0,4},PlotStyle->ColorData[95][4],FrameLabel->frameLabel11,PlotRange->{xRange,{0,0.2}},PlotLegends->Placed[leg,{Scaled[{0.24,0.65}],{0.5, 0.5}}],opts],ListPlot[List/@pointsLeak,PlotMarkers->{marker,markerSize}]]
],aLabel,{{Top,Left}}];
(* Dynamic Range *)
plotB=Labeled[
With[{opts=opts},Show[Plot[CNGA2pMax-CNGA2pMin/.CNGA2replace/.fit["BestFitParameters"],{nMut,0,4},PlotStyle->ColorData[95][4],PlotRange->{xRange,{0,1.05}},FrameLabel->frameLabel12,opts],ListPlot[List/@pointsDyn,PlotMarkers->{marker,markerSize}]]
],bLabel,{{Top,Left}}];

(* === Begin [(Subscript[EC, 50])] === *)
(* Find the [(Subscript[EC, 50])] numerically (since the (4^th) power of c makes it hard to find a clean analytic form) *)
EC50Equation=CNGA2pBound-(1/2)(CNGA2pMin+CNGA2pMax)/.CNGA2replace/.fit["BestFitParameters"];
(* Compute the [(Subscript[EC, 50])] for all values of nMut on the x-axis *)
pointsEC50=Join[Table[{nMut,c/.FindRoot[EC50Equation,{c,(10^(-3.))}]},{nMut,4.,3.8,-0.1}],Table[{nMut,c/.FindRoot[EC50Equation,{c,(10^(-6.))}]},{nMut,3.7,0,-0.1}]];
(* Identify the [(Subscript[EC, 50])] for the nMut=0,1,2,3,4 cases from Figure 8 *)
mutantPointsEC50=Cases[pointsEC50,{#,_}]&/@Range[0.,4.,1.];

(* We next compute the [(Subscript[EC, 50])] and the effective Hill coefficients (h) from the data. To do this, we fit each data set separately to the MWC model, thereby guaranteeing that the theory curve will closely match the exact shape of the data. Then, we extract the [(Subscript[EC, 50])] and effective Hill coefficient from the resulting curve *)
{EC50Values,hValues}=Transpose[(
fitIndividual=Quiet@NonlinearModelFit[CNGA2data[[#]],{CNGA2FitFunction,KCmutLog==-2.},List@@@fit["BestFitParameters"],{nMut,c}];
fitNormal=Normal@fitIndividual/.{nMut->CNGA2data[[#,1,1]]};
{c/.#,2c D[Log[fitNormal],c]/.#}&@(FindRoot[fitNormal-0.5,{c,Flatten[mutantPointsEC50,1][[#,2]]}])
)&/@Range@5];
EC50DataPoints=List/@Transpose@{Range[0,4],EC50Values};
hDataPoints=List/@Transpose@{Range[0,4],hValues};

(* Plotting [(Subscript[EC, 50])] *)
labels=font[#,10]&/@{"prediction","dose\[Hyphen]response data"};
leg=PointLegend[{ColorData[95][4],},labels,LegendMarkers->{{markerColor[],0.03},{Graphics[{EdgeForm[{Thickness[Medium],White}],{White,Thin,Circle[{0,0},0.1]},Disk[{0,0},0.1]}],0.03}},Joined->{True,False},Spacings->{0.1,0.7}];
plotC=Labeled[
Show[ListLogPlot[pointsEC50,Joined->True,PlotStyle->ColorData[95][4],FrameLabel->frameLabel13,PlotLegends->Placed[leg,{Scaled[{0.35,0.7}], {0.5, 0.5}}],PlotRange->{xRange,{1 (10^(-6.2)),(10^(-2.8))}},opts],ListLogPlot[mutantPointsEC50,PlotStyle->colors,PlotMarkers->{marker,markerSize}],ListLogPlot[EC50DataPoints,PlotMarkers->{Graphics[{EdgeForm[{Thickness[Tiny],White}],Disk[{0,0},0.1]}],0.03}]],cLabel,{{Top,Left}}];

(* === Begin Effective Hill Coefficient (h) === *)
hEquation=FullSimplify[2*c*D[Log[CNGA2pNormalized],c]]/.CNGA2replace/.fit["BestFitParameters"];
pointsH={nMut,hEquation}/.{nMut->#[[1]],c->#[[2]]}&/@pointsEC50;
mutantPointsH=Cases[pointsH,{#,_}]&/@Range[0.,4.,1.];
(* Plotting *)
plotD=Labeled[
Show[ListPlot[pointsH,Joined->True,PlotStyle->ColorData[95][4],FrameLabel->frameLabel14,PlotRange->{xRange,{-0.1,2.65}},opts],ListPlot[mutantPointsH,PlotStyle->colors,PlotMarkers->{marker,markerSize}],ListPlot[hDataPoints,PlotMarkers->{Graphics[{EdgeForm[{Thickness[Tiny],White}],Disk[{0,0},0.1]}],0.03}]],dLabel,{{Top,Left}}];

(* Plot the full grid *)
grid=Grid[{{plotA,plotB},{plotC,plotD}}]

Figure 9: nAChR and CNGA2 Prediction Curves using only n=0 and n=4 Data

nAChR Predictions: Demonstrate how only two data sets (in this case the wild type n=0 data set and the ion channel with n=4 mutated subunits) can be used to fully characterize the MWC parameters ((Subscript[K, O]), (Subscript[K, C]), and βϵ). With these parameters in hand, we can then predict (without any further fitting) the behavior of the remaining mutants, assuming that each mutation changes βϵ by a fixed amount.

(* Grab only the n=0 and n=4 data sets *)
newData15=Flatten[nAChRdata[[{1,5}]],1];
(* Fit the two data sets to obtain the thermodynamic parameters for the class of nAChR mutants *)
fit15=NonlinearModelFit[newData15,{nAChRFitFunction},{{KOlog,-22.76},{KClog,-11.7486},{βϵ[1],-4.},{βϵ[5],-24.}},{χ1,χ2,χ3,χ4,χ5,c}];
(* Interpolate the energies to find the remaining βϵ values assuming that each mutation shifts βϵ by a constant amount *)
otherβϵValues=Thread[{βϵ[2],βϵ[3],βϵ[4]}->(Table[βϵ[1]+(jj/4)(βϵ[5]-βϵ[1]),{jj,1,3}]/.fit15["BestFitParameters"])];

(* Plotting *)
leg=PointLegend[colors,nAChRlabels,LegendMarkers->({Graphics[{EdgeForm[{Thickness[Medium],White}],{White,Thin,Circle[{0,0},0.1]},Disk[{0,0},0.1]}],0.03}&/@Range@4),Spacings->{0.1,0.4}];
plotA=Labeled[With[{opts=opts},Show[LogLinearPlot[Evaluate[nAChRFitFunction/.fit15["BestFitParameters"]/.otherβϵValues/.#&/@mutantsList],{c,(10^(-11)),(10^(-2))},PlotRange->{{(10^(-10)),(10^(-2.7))},{-0.01,Automatic}},PlotLegends->Placed[leg,{Scaled[{0.79,0.35}], {0, 0.5}}],FrameLabel->frameLabel1,PlotStyle->Transpose@{{Automatic,Dashed,Dashed,Dashed,Automatic},colors[[5;;1;;-1]]},opts],ListLogLinearPlot[data,PlotMarkers->{Graphics[{EdgeForm[{Thickness[Tiny],White}],Disk[{0,0},0.1]}],0.03},PlotStyle->colors[[5;;1;;-1]]]]
],aLabel,{{Top,Left}}]

CNGA2 Predictions: Demonstrate how only two data sets (in this case the ion channels with (Subscript[n, Mut])=3 and (Subscript[n, Mut])=4 mutated subunits) can be used to fully characterize the MWC parameters ((Subscript[K, O]), (Subscript[K, C]), (Subscript[K, O]^( * )), (Subscript[K, C]^( * )), and βϵ). With these parameters in hand, we can then predict (without any further fitting) the behavior of the remaining mutants, assuming that each mutation changes βϵ by a fixed amount.

(* Grab only the nMut=3 and nMut=4 data sets. Note that these have indices 4 and 5 in 'CNGA2data *)
fit=NonlinearModelFit[Flatten[CNGA2data[[{4,5}]],1],{CNGA2FitFunction,KCmutLog==-2.},{{KOwtLog,Log[1.2 (10^(-6))]},{KOmutLog,Log[510 (10^(-6))]},{KCwtLog,Log[22 (10^(-6))]},{KCmutLog,Log[140 (10^(-3))]},{βϵ,-3.4}},{nMut,c}];
(* Plotting *)
leg=PointLegend[colors,CNGA2labels,LegendMarkers->({Graphics[{EdgeForm[{Thickness[Medium],White}],{White,Thin,Circle[{0,0},0.1]},Disk[{0,0},0.1]}],0.03}&/@Range@4),Spacings->{0.1,0.4}];
plotB=Labeled[With[{opts=opts},
Show[LogLinearPlot[Evaluate[Table[CNGA2FitFunction/.nMut->jj,{jj,0,4}]/.fit["BestFitParameters"]],{c,(10^(-7)),(10^(-2))},FrameLabel->frameLabel7,PlotStyle->{Dashed,Dashed,Dashed,Automatic,Automatic},opts],ListLogLinearPlot[CNGA2data[[All,All,{2,3}]],PlotMarkers->{Graphics[{EdgeForm[{Thickness[Tiny],White}],Disk[{0,0},0.1]}],0.03},PlotLegends->Placed[leg,{Scaled[{0.79,0.34}], {0, 0.5}}]]]
],bLabel,{{Top,Left}}]

Compare the nAChR and CNGA2 results

Grid[{{plotA,plotB}}]

Figure 10: nAChR and CNGA2 Sloppiness

nAChR Sloppiness: Compute the best-fit parameters given the constraint (Subscript[K, O])=value where value varies in the range [(10^(-13)),(10^(-9))]M. We start with the (Subscript[K, O]) value found in Figure 2 above. After that, the initial guess for each (Subscript[K, O]) will be the parameters found for the closest (Subscript[K, O]) computed thus far.

(* Initial guess to next starting value is determined by the closest (Subscript[K, O]) run computed thus far *)
Clear[nAChRFit,fitParametersList,initialGuess]
nAChRFit[KOlogVal_]:=(
(* Initial guesses for each parameter will be given by the closest results for a previous run *)
closestPreviousKO=First@Nearest[KOlog/.fitParametersList,KOlogVal];
initialGuess=#[[Position[#,closestPreviousKO][[1,1]]]]&@fitParametersList;
(* Fit to the new (Subscript[K, O]) value *)
fitnAChR=
Quiet[NonlinearModelFit[Flatten[nAChRdata,1],{nAChRFitFunction,KOlog==KOlogVal},List@@@Most@initialGuess,{χ1,χ2,χ3,χ4,χ5,c}],NonlinearModelFit::eit];
Join[fitnAChR["BestFitParameters"],{RSquared->fitnAChR["RSquared"]}]
)

(* Begin with the same initial guesses as in Figure 2 *)
fitnAChR=
Quiet[NonlinearModelFit[Flatten[nAChRdata,1],{nAChRFitFunction,KOlog==Log[3. (10^(-12))]},{KOlog,{KClog,-9.74},{βϵ[1],-11.13},{βϵ[2],-16.29},{βϵ[3],-21.45},{βϵ[4],-26.61},{βϵ[5],-31.77}},{χ1,χ2,χ3,χ4,χ5,c}],NonlinearModelFit::eit];
fitParametersList={Join[fitnAChR["BestFitParameters"],{RSquared->fitnAChR["RSquared"]}]};

(* Search through (Subscript[K, O])>3\[Cross](10^(-12)) *)
{minKO,maxKO}={4. (10^(-12)),6. (10^(-10))};
Do[
AppendTo[fitParametersList,nAChRFit[jj]]
,{jj,Subdivide[Log[minKO],Log[maxKO],10]}];
{minKO,maxKO}={1. (10^(-9)),4. (10^(-9))};
Do[
AppendTo[fitParametersList,nAChRFit[jj]]
,{jj,Subdivide[Log[minKO],Log[maxKO],20]}];

(* Search through (Subscript[K, O])<3\[Cross](10^(-12)) *)
{minKO,maxKO}={4. (10^(-14)),2. (10^(-12))};
Do[
AppendTo[fitParametersList,nAChRFit[jj]]
,{jj,Reverse@Subdivide[Log[minKO],Log[maxKO],10]}];

(* Plotting *)
leg=Row[{LineLegend[colors2[[1;;3]],nAChRlabels2[[1;;3]],Spacings->{0.1,0.0},LegendMarkerSize->15],LineLegend[colors2[[4;;6]],nAChRlabels2[[4;;6]],Spacings->{0.1,0.0},LegendMarkerSize->15]}];
plotA=Labeled[ListLogLinearPlot[Sort/@Transpose[Join[Table[{(E^KOlog),βϵ[jj]},{jj,5,1,-1}],{{(E^KOlog),Log[10,(E^KClog)]}}]/.fitParametersList,{2,1}],Joined->True,PlotLegends->Placed[leg,{Scaled[{0.1,0.77}], {0, 0.5}}],PlotRange->{{(10^(-13.6)),(10^(-8.5))},{-42,29}},FrameLabel->frameLabel15,PlotStyle->colors2,Evaluate@opts],aLabel,{{Top,Left}}]

CNGA2 Sloppiness: Compute the best-fit parameters given the constraint (Subscript[K, O])=value where value varies in the range [(10^(-7)),(10^(-5))]M. Outside of this range, no MWC parameters yield satisfactory fits of the entire CNGA2 data set. We start with the (Subscript[K, O]) value found in Figure 8 above. After that, the initial guess for each (Subscript[K, O]) will be the parameters found for the closest (Subscript[K, O]) computed thus far.

Clear[CNGA2Fit,fitParametersList,initialGuess]
CNGA2Fit[KOlogVal_]:=(
(* Initial guesses for each parameter will be given by the closest results for a previous run *)
closestPreviousKO=First@Nearest[KOwtLog/.fitParametersList,KOlogVal];
initialGuess=#[[Position[#,closestPreviousKO][[1,1]]]]&@fitParametersList;
(* Fit to the new (Subscript[K, A]) value *)
fitCNGA2=
Quiet[NonlinearModelFit[Flatten[CNGA2data,1],{CNGA2FitFunction,KCmutLog==-2.,KOwtLog==KOlogVal},List@@@Most@initialGuess,{nMut,c}],NonlinearModelFit::eit];
Join[fitCNGA2["BestFitParameters"],{RSquared->fitCNGA2["RSquared"]}]
)
(* Initiate the first parameter value from which to search through parameter space *)
fit=NonlinearModelFit[Flatten[CNGA2data,1],{CNGA2FitFunction,KCmutLog==-2.},{{KOwtLog,Log[1.2 (10^(-6))]},{KOmutLog,Log[510 (10^(-6))]},{KCwtLog,Log[22 (10^(-6))]},{KCmutLog,Log[140 (10^(-3))]},{βϵ,-3.4}},{nMut,c}];
fitParametersList={Join[fit["BestFitParameters"],{RSquared->fit["RSquared"]}]};
(* Search for other (Subscript[K, O]^WT)>-13.65 *)
{minKOLog,maxKOLog}={-13.0,-11.575};
Do[
AppendTo[fitParametersList,CNGA2Fit[jj]]
,{jj,Subdivide[minKOLog,maxKOLog,20]}];
{minKOLog,maxKOLog}={-11.575,-11.5};
Do[
AppendTo[fitParametersList,CNGA2Fit[jj]]
,{jj,Subdivide[minKOLog,maxKOLog,10]}];
(* Search for other (Subscript[K, O]^WT)<-13.65 *)
{minKOLog,maxKOLog}={-16.0,-14.0};
Do[
AppendTo[fitParametersList,CNGA2Fit[jj]]
,{jj,Reverse@Subdivide[minKOLog,maxKOLog,40]}];

(* Plotting *)
leg=Row[{LineLegend[colors2[[1;;2]],CNGA2labels2[[1;;2]],Spacings->{0.1,0.0},LegendMarkerSize->15],LineLegend[colors2[[3;;4]],CNGA2labels2[[3;;4]],Spacings->{0.1,0.0},LegendMarkerSize->15]}];
plotB=Labeled[ListLogLinearPlot[Sort/@Transpose[Table[{(E^KOwtLog),jj},{jj,{Log[10,(E^KOmutLog)],Log[10,(E^KCwtLog)],Log[10,(E^KCmutLog)],βϵ}}]/.fitParametersList,{2,1}],Joined->True,PlotRange->{{(10^(-7.05)),(10^(-4.9))},{-10,Automatic}},PlotLegends->Placed[leg,{Scaled[{0.05,0.85}], {0, 0.5}}],FrameLabel->frameLabel15,PlotStyle->colors2,Evaluate@opts],bLabel,{{Top,Left}}]

Compare the nAChR and CNGA2 results

Grid[{{plotA,plotB}}]

SI Figures

Figure S2: Dynamics Towards Equilibrium

The cycle condition must be fulfilled: ((Subscript[k, +]^e)/(Subscript[k, -]^e))=(((Subscript[k, +]^o)(Subscript[k, off]^((O))))/((Subscript[k, -]^o)(Subscript[k, off]^((C)))))

(* Construct the transition rate matrix K from the main text *)
newMat={{-kpe-kon LL,koffC,kme,0},{kon LL,-koffC-kpo,0,kmo},{kpe,0,-kme-kon LL,koffO},{0,kpo,kon LL,-kmo-koffO}};
(* Let the concentrations of all ion channel conformations evolve in time based on chemical kinetics *)
time=(10^(-2.));
vec={CC[t],CCLL[t],OO[t],OOLL[t]};
initialConditions={0.45,0.005,0.005,0.54};
res=First@Block[{kon=((10^3.)/LL),koffO=(10^(-2.)),koffC=(10^4.),kpo=(10^5.),kmo=(10^1.),kpe=(10^1.),kme=(10^3.)},
Echo[timeScale=Max@Most[-1/Eigenvalues[newMat]],"Exact time scale:"];
Echo[Max[-(1/{-koffO-kon LL,-koffC-kmo-kpo,-kon LL-kme-kpe})],"Approximate time scale:"];
NDSolve[Join[Thread[D[vec,t]==newMat.vec],Thread[(vec/.t->0)==initialConditions]],{CC,CCLL,OO,OOLL},{t,0,time}]
];
(* Plot the results *)
timeScaleLabels=font/@{"O","C","OL","CL"};
leg=LineLegend[ColorData[95]/@{3,1,4,2},timeScaleLabels,Spacings->{0.1,0.1},LegendMarkerSize->15];
plot=LogPlot[Evaluate[#[t]&/@({CC,CCLL,OO,OOLL}/.res)],{t,0,time},Epilog->{Dashed,Line[{{#,Log@(10^(-5))},{#,Log@10}}&@timeScale]},PlotStyle->ColorData[95],PlotRange->{{Automatic,0.0102},{0.9 (10^(-5.)),Automatic}},PlotLegends->Placed[leg,{Scaled[{0.75,0.64}], {0, 0.5}}],FrameLabel->frameLabel16,Evaluate@opts]

Figure S3: Other nAChR Mutants

(* Using the (Subscript[K, A]) and (Subscript[K, I]) values for the nAChR class, and given the [(Subscript[EC, 50])] data for the other nAChR mutants from Labarca (1995), fit the βϵ values of the other mutants *)
fit=NonlinearModelFit[Flatten[nAChRdata,1],{nAChRFitFunction,βϵ[1]==-4.},{{KOlog,-22.76},{KClog,-11.7486},{βϵ[1],-4.},{βϵ[2],-9.},{βϵ[3],-14.},{βϵ[4],-19.},{βϵ[5],-24.}},{χ1,χ2,χ3,χ4,χ5,c}];
(* Analytic form of [(Subscript[EC, 50])] and effective Hill coefficient *)
EC50Exact=c/.Last@FullSimplify@Solve[nAChRpBound==(1/2) (nAChRpMin+nAChRpMax),c];
βϵfunction=EC50Exact/.{KO->(E^KOlog),KC->(E^KClog)}/.fit["BestFitParameters"];
(* Data taken from Labarca (1995) Table S1. Curves are plotted from left-to-right, starting with the most mutated subunits and ending with wild type *)
measuredEC50Values={24010,1290,531,1910,486,202,49.7,208,42.7,10.3,15.1,8.4,9.8,2.3,2.0};
(* Ordering the data from highest to lowest WITHIN EACH CLASS so that the coloring will go from darkest to lightest (left to right) *)
sortedData=Reverse@Sort@measuredEC50Values;
ECvalues=Reverse@sortedData*(10^(-9.));
results=FindRoot[βϵfunction-#,{βϵ,-5.}]&/@ECvalues;
(* Plotting the results *)
curves=nAChRpNormalized/.#/.{KC->(E^KClog),KO->(E^KOlog)}/.fit["BestFitParameters"]&/@results;
colorsShades=Flatten@{{#,Darker@#}&@ColorData[97][5],{Lighter@Lighter@#,#,Darker@#,Darker@Darker@#}&@ColorData[97][4],{Lighter@Lighter@#,Lighter@#,#,Darker@#}&@ColorData[97][3],{Lighter@Lighter@Lighter@#,Lighter@Lighter@#,Lighter@#,#}&@ColorData[97][2],{#}&@ColorData[97][1]};
leg=PointLegend[colors,nAChRlabels,LegendMarkers->({Graphics[{EdgeForm[{Thickness[Medium],White}],{White,Thin,Circle[{0,0},0.1]},Disk[{0,0},0.1]}],0.03}&/@Range@4),Spacings->{0.1,0.4}];
plotA=With[{opts=opts},Show[LogLinearPlot[Evaluate@curves,{c,(10^(-11)),(10^(-2))},PlotStyle->colorsShades,PlotRange->{{(10^(-10)),(10^(-2.7))},{-0.01,1.07}},FrameLabel->frameLabel1,opts],ListLogLinearPlot[data,PlotStyle->colors[[5;;1;;-1]],PlotMarkers->{Graphics[{EdgeForm[{Thickness[Tiny],White}],Disk[{0,0},0.1]}],0.03},PlotLegends->Placed[leg,{Scaled[{0.78,0.33}], {0, 0.5}}]]]
]

Figure S4: Individual nAChR Subunit Contributions to ϵ

Fitting the [(Subscript[EC, 50])] values in Table S1 assuming that the α, β, γ, and δ subunits in nAChR all increase ϵ by a different amount upon mutation

(* Using the (Subscript[K, A]) and (Subscript[K, I]) values for the nAChR class, and given the [(Subscript[EC, 50])] data for the other nAChR mutants from Labarca (1995), fit the βϵ values of the other mutants *)
fit=NonlinearModelFit[Flatten[nAChRdata,1],{nAChRFitFunction,βϵ[1]==-4.},{{KOlog,-22.76},{KClog,-11.7486},{βϵ[1],-4.},{βϵ[2],-9.},{βϵ[3],-14.},{βϵ[4],-19.},{βϵ[5],-24.}},{χ1,χ2,χ3,χ4,χ5,c}];
(* Analytic form of [(Subscript[EC, 50])] and effective Hill coefficient *)
EC50Exact=c/.Last@FullSimplify@Solve[nAChRpBound==(1/2) (nAChRpMin+nAChRpMax),c];
βϵfunction=EC50Exact/.{KO->(E^KOlog),KC->(E^KClog)}/.fit["BestFitParameters"];

(* Data taken from Labarca (1995) Table S1 *)
measuredEC50Values={24010,1290,531,1910,486,202,49.7,208,42.7,10.3,15.1,8.4,9.8,2.3,2.0};
ECvalues=measuredEC50Values*(10^(-9.));
results=FindRoot[βϵfunction-#,{βϵ,-5.}]&/@ECvalues;
(* Number of mutated subunits from Table S1: {(Subscript[n, (SuperStar[α])]),(Subscript[n, (SuperStar[β])]),(Subscript[n, (SuperStar[γ])]),(Subscript[n, (SuperStar[δ])])} *)
numberMutatedSubunits={{0,0,0,0},{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1},{2,0,0,0},{0,1,1,0},{0,1,0,1},{0,0,1,1},{2,1,0,0},{2,0,1,0},{2,0,0,1},{0,1,1,1},{2,1,0,1},{2,0,1,1}};
(* Best-fit values of βϵ *)
bestFitϵValues=(βϵ/.results);
(* Modify values so that they are all energy differences from the wild type gating energy *)
bestFitϵDifferences=bestFitϵValues-First@bestFitϵValues;
(* {(Subscript[n, (SuperStar[α])]),(Subscript[n, (SuperStar[β])]),(Subscript[n, (SuperStar[γ])]),(Subscript[n, (SuperStar[δ])]),Δϵ between wild type and mutant} *)
mutantϵData=Append[numberMutatedSubunits[[#]],bestFitϵDifferences[[#]]]&/@Range@Length@bestFitϵDifferences;

(* Fit the (Subscript[Δϵ, j]^( * ))'s *)
ϵFit=LinearModelFit[mutantϵData,{ϵα,ϵβ,ϵγ,ϵδ},{ϵα,ϵβ,ϵγ,ϵδ},IncludeConstantBasis->False];
(* Best-fit unified prediction of the ϵ's for the mutants *)
bestFitMutantϵ=First@bestFitϵValues+(Normal@ϵFit/.Thread[{ϵα,ϵβ,ϵγ,ϵδ}->#])&/@numberMutatedSubunits;
(* Compute the predicted [(Subscript[EC, 50])] values for the mutants in Table S1 *)
predictedEC50Values=(10^9)EC50Exact/.#/.{KO->(E^KOlog),KC->(E^KClog)}/.fit["BestFitParameters"]&/@(List/@Thread[βϵ->bestFitMutantϵ]);

(* Plotting *)
With[{opts=opts},Show[LogLogPlot[x,{x,0.5,50000},PlotStyle->{Black,Dashed},AspectRatio->1,PlotRange->{{0.4,50000},{0.4,50000}},FrameLabel->frameLabel28,ImageSize->(295/GoldenRatio),opts],ListLogLogPlot[Transpose@{predictedEC50Values,measuredEC50Values},PlotStyle->First@colors3,PlotMarkers->{Graphics[{EdgeForm[{Thickness[Tiny],White}],Disk[{0,0},0.1]}],0.03}]]]

Figure S5: nAChR Normalized Current and (Subscript[p, open])

(* Plot A - Normalized current curves as in Figure 2A *)
fit=NonlinearModelFit[Flatten[nAChRdata,1],{nAChRFitFunction,βϵ[1]==-4.},{{KOlog,-22.76},{KClog,-11.7486},{βϵ[1],-4.},{βϵ[2],-9.},{βϵ[3],-14.},{βϵ[4],-19.},{βϵ[5],-24.}},{χ1,χ2,χ3,χ4,χ5,c}];
leg=PointLegend[colors,nAChRlabels,LegendMarkers->({Graphics[{EdgeForm[{Thickness[Medium],White}],{White,Thin,Circle[{0,0},0.1]},Disk[{0,0},0.1]}],0.03}&/@Range@4),Spacings->{0.1,0.4}];
plotA=Labeled[With[{opts=opts},Show[LogLinearPlot[Evaluate[nAChRFitFunction/.fit["BestFitParameters"]/.#&/@mutantsList],{c,(10^(-10.)),(10^(-2.72))},PlotRange->{{(10^(-10)),(10^(-2.7))},{-0.01,1.07}},PlotLegends->Placed[leg,{Scaled[{0.78,0.33}], {0, 0.5}}],FrameLabel->frameLabel1,PlotStyle->colors[[5;;1;;-1]],opts],ListLogLinearPlot[data,PlotMarkers->{Graphics[{EdgeForm[{Thickness[Tiny],White}],Disk[{0,0},0.1]}],0.03},PlotStyle->colors[[5;;1;;-1]]]]
],aLabel,{{Top,Left}}];

(* Plot B - (Subscript[p, bound]) (i.e. the un-normalized dose-response curves) *)
plotB=Labeled[With[{opts=opts},Show[LogLinearPlot[Evaluate[nAChRpBound/.nAChRreplace/.fit["BestFitParameters"]/.#&/@mutantsList],{c,(10^(-10.)),(10^(-2.72))},PlotRange->{{(10^(-10)),(10^(-2.7))},{-0.01,1.07}},FrameLabel->frameLabel17,PlotStyle->colors[[5;;1;;-1]],opts]]
],bLabel,{{Top,Left}}];
grid=Grid[{{plotA,plotB}}]

Figure S6: CNGA2 Normalized Current and (Subscript[p, open])

(* Plot A - Normalized current curves as in Figure 6A *)
fit=NonlinearModelFit[Flatten[CNGA2data,1],{CNGA2FitFunction,KCmutLog==-2.},{{KOwtLog,Log[1.2 (10^(-6))]},{KOmutLog,Log[510 (10^(-6))]},{KCwtLog,Log[22 (10^(-6))]},{KCmutLog,Log[140 (10^(-3))]},{βϵ,-3.4}},{nMut,c}];
(* Plotting the fits *)
leg=PointLegend[colors,CNGA2labels,LegendMarkers->({Graphics[{EdgeForm[{Thickness[Medium],White}],{White,Thin,Circle[{0,0},0.1]},Disk[{0,0},0.1]}],0.03}&/@Range@4),Spacings->{0.1,0.4}];
plots=Table[CNGA2FitFunction/.nMut->jj,{jj,0,4}]/.fit["BestFitParameters"];
plotA=Labeled[With[{opts=opts},
Show[LogLinearPlot[plots,{c,(10^(-7)),(10^(-2))},FrameLabel->frameLabel7,opts],ListLogLinearPlot[CNGA2data[[All,All,{2,3}]],PlotMarkers->{Graphics[{EdgeForm[{Thickness[Tiny],White}],Disk[{0,0},0.1]}],0.03},PlotLegends->Placed[leg,{Scaled[{0.78,0.32}], {0, 0.5}}]]]
],aLabel,{{Top,Left}}];
(* Plot B - (Subscript[p, bound]) (i.e. the un-normalized dose-response curves) *)
plotB=Labeled[With[{opts=opts},
LogLinearPlot[Evaluate[Table[CNGA2pBound/.nMut->jj,{jj,0,4}]/.CNGA2replace/.fit["BestFitParameters"]],{c,(10^(-7)),(10^(-2))},FrameLabel->frameLabel18,opts]
],bLabel,{{Top,Left}}];
grid=Grid[{{plotA,plotB}}]

Figure S7: Leu 9’Thr Mutations

(* Plot A - The [(Subscript[EC, 50])] values of the Leu 9'Thr mutants should be linear with the number of mutated subunits. Fit with a linear function going through the wild type value at n=0 *)
fit=LinearModelFit[leu9ThrData,x,x,IncludeConstantBasis->False];
(* Wild type value [(Subscript[EC, 50])]=2.4\[Cross](10^(-5)) *)
wtEC50=0.000024786;
(* Change to absolute [(Subscript[EC, 50])] rather than a ratio with wt values *)
leu9ThrDataEC50=leu9ThrData;
leu9ThrDataEC50[[All,2]]=wtEC50*(10^(leu9ThrData[[All,2]]));

plotA=Labeled[With[{opts=opts},Show[LogPlot[wtEC50*(10^(fit[x])),{x,0,5},PlotStyle->ColorData[95][1],FrameLabel->frameLabel19,PlotRange->{{-0.3,5.3},{0.9 (10^(-8)),3.1 (10^(-5))}},opts],ListLogPlot[leu9ThrDataEC50,PlotMarkers->{Graphics[{EdgeForm[{Thickness[Tiny],White}],Disk[{0,0},0.1]}],0.03},PlotStyle->ColorData[95][1]]
]
],aLabel,{{Top,Left}}];


(* Plot B - Predict the dose-response curves of the entire class of mutants *)

(* Shift data from μM to M *)
leu9ThrData3=Map[{#[[1]]*(10^(-6)),#[[2]]}&,leu9ThrData2,{2}];
fit=NonlinearModelFit[Flatten[nAChRdata,1],{nAChRFitFunction,βϵ[1]==-4.},{{KOlog,-22.76},{KClog,-11.7486},{βϵ[1],-4.},{βϵ[2],-9.},{βϵ[3],-14.},{βϵ[4],-19.},{βϵ[5],-24.}},{χ1,χ2,χ3,χ4,χ5,c}];
(* Predicted Δ,ϵ increment with each Leu 9'Thr mutation based on Filatov [(Subscript[EC, 50])] data *)
Δϵ=2*1.8208698759049284`;
βϵValues=βϵ[5]+Range[0,4]Δϵ/.fit["BestFitParameters"];
functions=nAChRFitFunction/.(List/@Thread[βϵ[5]->βϵValues])/.fit["BestFitParameters"]/.Last@mutantsList;
leg=Row[{LineLegend[colors,nAChRlabels,LegendMarkerSize->10,Spacings->{0.1,0.4}],PointLegend[{ColorData[97][1],Darker[ColorData[97][2],0.2],Lighter[ColorData[97][2],0.3],Darker@ColorData[97][3]},nAChRlabels3,LegendMarkers->({Graphics[{EdgeForm[{Thickness[Medium],White}],{White,Thin,Circle[{0,0},0.1]},Disk[{0,0},0.1]}],0.03}&/@Range@4),Spacings->{0.1,0.3}]}];
plotB=Labeled[With[{opts=opts},Show[LogLinearPlot[Evaluate@functions,{c,(10^(-9)),(10^(-1))},PlotRange->{{(10^(-9)),(10^(-1.7))},{-0.01,1.07}},PlotLegends->Placed[leg,{Scaled[{0.62,0.33}], {0, 0.5}}],FrameLabel->frameLabel1,PlotStyle->colors,opts],ListLogLinearPlot[leu9ThrData3,PlotMarkers->{Graphics[{EdgeForm[{Thickness[Tiny],White}],Disk[{0,0},0.1]}],0.03},PlotStyle->{ColorData[97][1],Darker[ColorData[97][2],0.2],Lighter[ColorData[97][2],0.3],Darker@ColorData[97][3]}]]
],bLabel,{{Top,Left}}];
grid=Grid[{{plotA,plotB}}]

Figure S8: CNGA2 Combinations of Ion Channels

Measuring the normalized current data from 1:1 combinations of n=0 and n=4 CNGA2 ion channels. Data from Figure 1B of Wongsamitkul 2016.

(* Start with the same CNGA2 fits from Figure 6 *)
fit=NonlinearModelFit[Flatten[CNGA2data,1],{CNGA2FitFunction,KCmutLog==-2.},{{KOwtLog,Log[1.2 (10^(-6))]},{KOmutLog,Log[510 (10^(-6))]},{KCwtLog,Log[22 (10^(-6))]},{KCmutLog,Log[140 (10^(-3))]},{βϵ,-3.4}},{nMut,c}];

(* Predict the response from two equal quantities of the n=0 and n=4 channels. See Equation (42) in the SI, which shows that this will be the average of the two channel responses *)
plots=Table[CNGA2FitFunction/.nMut->jj,{jj,{0,4}}]/.fit["BestFitParameters"];
(* Shifting data to Molar instead of μMolar *)
newData3=Map[{#[[1]]*(10^(-6)),#[[2]]}&,data3,{2}];
(* Create legend *)
labels=font[#,10]&/@{Row[{Style["n",FontSlant->Italic],"=4"}],Row[{Style["n",FontSlant->Italic],"=0,4 (1:1)"}],Row[{Style["n",FontSlant->Italic],"=0"}]};
leg=PointLegend[colors[[{1,6,5}]],labels,Spacings->{0.1,0.4}];
plotA=With[{opts=opts},
Show[LogLinearPlot[Evaluate@{plots[[1]],((plots[[1]]+plots[[-1]])/2),plots[[-1]]},{c,(10^(-7.08)),(10^(-1.92))},PlotStyle->{ColorData[97][1],ColorData[97][6],ColorData[97][5]},FrameLabel->frameLabel7,PlotRange->{{(10^(-7.1)),(10^(-1.9))},{-0.01,1.07}},opts],ListLogLinearPlot[newData3,PlotStyle->colors[[{1,6,5}]],PlotMarkers->{Graphics[{EdgeForm[{Thickness[Tiny],White}],Disk[{0,0},0.1]}],0.03},PlotLegends->Placed[leg,{Scaled[{0.73,0.22}], {0, 0.5}}]]]
]

Figure S9: nAChR Properties Analytic Approximations

Plot the four characteristics - the leakiness, dynamic range, [(Subscript[EC, 50])], and effective Hill coefficient - for the nAChR family of mutants. This figure is very similar to Figure 5, except that we compare the exact relations (purple) to the analytic approximations shown to 1st order (dashed, teal).

fit=NonlinearModelFit[Flatten[nAChRdata,1],{nAChRFitFunction,βϵ[1]==-4.},{{KOlog,-22.76},{KClog,-11.7486},{βϵ[1],-4.},{βϵ[2],-9.},{βϵ[3],-14.},{βϵ[4],-19.},{βϵ[5],-24.}},{χ1,χ2,χ3,χ4,χ5,c}];
nAChRValues=fit["BestFitParameters"];
(* Analytic form of [(Subscript[EC, 50])] and effective Hill coefficient *)
EC50Exact=c/.Last@FullSimplify@Solve[nAChRpBound==(1/2) (nAChRpMin+nAChRpMax),c];
hExact=Simplify[2*c*D[Log[nAChRpNormalized],c]/.c->EC50Exact];
(* Fit values *)
fitValues=fit["BestFitParameters"];
(* Plot range along βϵ axis *)
{βϵMin,βϵMax}={-30,3};
xBounds={βϵMin-0.7,βϵMax+0.5};

(* Plot legend *)
labels=font[#,11]&/@{"Exact expression","Approximate form"};
leg=LineLegend[{ColorData[95][4],{ColorData[95][3],Dashing[Small]}},labels,Spacings->{0.4,0.3},LegendMarkerSize->18];

(* Plot the leakiness and dynamic range *)
plotAcurves={nAChRpMin,(E^(βϵ))};
plotA=Labeled[
With[{opts=opts},Show[LogPlot[plotAcurves,{βϵ,βϵMin,βϵMax},PlotStyle->{{ColorData[95][4],Automatic},{ColorData[95][3],Dashing[Small]}},FrameLabel->frameLabel3,Axes->False,PlotLegends->Placed[leg,{Scaled[{0.06,0.75}], {0, 0.5}}],PlotRange->{xBounds,{(10^(-12.5)),2}},opts]]
],aLabel,{{Top,Left}}];
plotBcurves={nAChRpMax-nAChRpMin,1-(E^(-βϵ))((((KO/KC)))^2)-(E^(βϵ))}/.{KO->(E^KOlog),KC->(E^KClog)}/.fitValues;
plotB=Labeled[
With[{opts=opts},Show[Plot[plotBcurves,{βϵ,βϵMin,βϵMax},PlotStyle->{{ColorData[95][4],Automatic},{ColorData[95][3],Dashing[Small]}},FrameLabel->frameLabel4,Axes->False,PlotRange->{xBounds,{-0.01,1.05}},opts]]
],bLabel,{{Top,Left}}];

(* === Compute the exact [(Subscript[EC, 50])] and effective Hill coefficients from the data. Do this by fitting each curve individually to the best parameter combination possible, and then extracting the [(Subscript[EC, 50])] and effective Hill coefficient from that fit === *)

(* Plot the [(Subscript[EC, 50])] and effecitve Hill coefficient *)
plotCcurves={EC50Exact,KO (E^(-βϵ/2))}/.{KO->(E^KOlog),KC->(E^KClog)}/.fitValues;
plotC=Labeled[
With[{opts=opts},Show[LogPlot[plotCcurves,{βϵ,βϵMin,βϵMax},PlotStyle->{{ColorData[95][4],Automatic},{ColorData[95][3],Dashing[Small]}},PlotRange->{xBounds,{(10^(-10.5)),(10^(-3.5))}},FrameLabel->frameLabel5,Axes->False,opts]]
],cLabel,{{Top,Left}}];
plotDcurves={hExact,2-2(KO/KC)(E^(-βϵ/2))-2(E^(βϵ/2))}/.{KO->(E^KOlog),KC->(E^KClog)}/.fitValues;
plotD=Labeled[
With[{opts=opts},Show[Plot[plotDcurves,{βϵ,βϵMin,βϵMax},PlotStyle->{{ColorData[95][4],Automatic},{ColorData[95][3],Dashing[Small]}},FrameLabel->frameLabel6,PlotRange->{xBounds,{-0.01,2.1}},opts]]
],dLabel,{{Top,Left}}];
grid=Grid[{{plotA,plotB},{plotC,plotD}}]

Figure S10: CNGA2 Properties Analytic Approximations ((Subscript[K, O]) and (Subscript[K, C]) mutations)

What happens if you take the wild type CNGA2 molecule and tune the (Subscript[K, O]) and (Subscript[K, C])? Note that this is different from the CNGA2 data considered in the text. We consider how the four characteristics - the leakiness, dynamic range, [(Subscript[EC, 50])], and effective Hill coefficient - vary within this family of mutants.

(* Minimum and maximum (Subscript[p, open]) values for the general MWC model with m ligand binding sites, (Subscript[p, open])=((((1+(c/(Subscript[K, O]))))^m)/((((1+(c/(Subscript[K, O]))))^m)+(E^(-βϵ))(((1+(c/(Subscript[K, C]))))^m))) *)
pMin=(1/(1+(E^(-βϵ))));
pMax=(1/(1+(E^(-βϵ))(((KOoverKC))^n)));
(* Exact formulas for the leakiness, dynamic range, [(Subscript[EC, 50])], and effective Hill coefficient. All analytic forms can be found in Martins and Swain 2011 or Marzen, Garcia, Phillips 2013 *)
{leakiness,dynamicRange,EC50,h}=Block[{βϵ=-3.4,n=4},{
(* Leakiness *)
pMin,
(* Dynamic Range *)
pMax-pMin,
(* [(Subscript[EC, 50])] *)
((1-(λ^(1/n)))/((λ^(1/n))-KOoverKC))/.λ->((1+(((KOoverKC))^n)+2(E^(-βϵ))(((KOoverKC))^n))/((E^(-βϵ))(1+(((KOoverKC))^n))+2)),
(* Effective Hill Coefficient *)
((n KOoverKC c (1-KOoverKC)((1/(1+(E^(-βϵ))))+(1/(1+(E^(-βϵ))(((KOoverKC))^n))))(2-((1/(1+(E^(-βϵ))))+(1/(1+(E^(-βϵ))(((KOoverKC))^n))))))/(((1/(1+(E^(-βϵ))(((KOoverKC))^n)))-(1/(1+(E^(-βϵ)))))KOoverKC(c+1)(KOoverKC c+1)))/.c->((1-(λ^(1/n)))/((λ^(1/n))-KOoverKC))/.λ->((2-((1/(1+(E^(-βϵ))))+(1/(1+(E^(-βϵ))(((KOoverKC))^n)))))/((E^(-βϵ))((1/(1+(E^(-βϵ))))+(1/(1+(E^(-βϵ))(((KOoverKC))^n))))))}];

(* Plotting *)
{rangeMin,rangeMax}={(10^(-4.1)),(10^0.08)};
xRange={(10^(-4.1)),(10^0.1)};
(* Leakiness *)
plotA=Labeled[
With[{opts=opts},Show[LogLinearPlot[leakiness,{KOoverKC,rangeMin,rangeMax},PlotStyle->ColorData[95][4],FrameLabel->frameLabel20,PlotRange->{xRange,{0,0.1}},opts]]
],aLabel,{{Top,Left}}];
(* Dynamic Range *)
plotB=Labeled[
With[{opts=opts},Show[LogLinearPlot[dynamicRange,{KOoverKC,rangeMin,rangeMax},PlotStyle->ColorData[95][4],PlotRange->{xRange,{0,1}},FrameLabel->frameLabel21,opts]]
],bLabel,{{Top,Left}}];
(* [(Subscript[EC, 50])] *)
plotC=Labeled[
With[{opts=opts},Show[LogLinearPlot[EC50,{KOoverKC,rangeMin,rangeMax},PlotStyle->ColorData[95][4],PlotRange->{xRange,{0,4}},FrameLabel->frameLabel22,opts]]
],cLabel,{{Top,Left}}];
(* Effective Hill Coefficient *)
plotD=Labeled[
With[{opts=opts},Show[LogLinearPlot[h,{KOoverKC,rangeMin,rangeMax},PlotStyle->ColorData[95][4],PlotRange->{xRange,{0,2.5}},FrameLabel->frameLabel23,opts]]
],dLabel,{{Top,Left}}];
grid=Grid[{{plotA,plotB},{plotC,plotD}}]

Figure S11: CNGA2 Properties Analytic Approximations (subunit mutations)

Plot the four characteristics - the leakiness, dynamic range, [(Subscript[EC, 50])], and effective Hill coefficient - for the CNGA2 family of mutants considered in the text. This figure is very similar to Figure 8, except that we compare the exact relations (purple) of the [(Subscript[EC, 50])] and h to the analytic approximations shown to 1st order (dashed, teal).

(* Get the nAChR fit parameters from Figure 8 *)
fit=NonlinearModelFit[Flatten[CNGA2data,1],{CNGA2FitFunction,KCmutLog==-2.},{{KOwtLog,Log[1.2 (10^(-6))]},{KOmutLog,Log[510 (10^(-6))]},{KCwtLog,Log[22 (10^(-6))]},{KCmutLog,Log[140 (10^(-3))]},{βϵ,-3.4}},{nMut,c}];

(* Plot Range *)
xRange={-0.2,4.2};
(* Leakiness *)
plotA=Labeled[
With[{opts=opts},Plot[CNGA2pMin/.CNGA2replace/.fit["BestFitParameters"],{nMut,0,4},PlotStyle->ColorData[95][4],FrameLabel->frameLabel11,PlotRange->{xRange,{0,0.2}},opts]
],aLabel,{{Top,Left}}];
(* Dynamic Range *)
plotB=Labeled[
With[{opts=opts},Plot[CNGA2pMax-CNGA2pMin/.CNGA2replace/.fit["BestFitParameters"],{nMut,0,4},PlotStyle->ColorData[95][4],PlotRange->{xRange,{0,1.05}},FrameLabel->frameLabel12,opts]
],bLabel,{{Top,Left}}];

(* === Begin [(Subscript[EC, 50])] === *)
(* Find the [(Subscript[EC, 50])] numerically (since the (4^th) power of c makes it hard to find a clean analytic form) *)
EC50Equation=CNGA2pBound-(1/2)(CNGA2pMin+CNGA2pMax)/.CNGA2replace/.fit["BestFitParameters"];
(* Compute the [(Subscript[EC, 50])] for all values of nMut on the x-axis *)
pointsEC50=Join[Table[{nMut,c/.FindRoot[EC50Equation,{c,(10^(-3.))}]},{nMut,4.,3.8,-0.1}],Table[{nMut,c/.FindRoot[EC50Equation,{c,(10^(-6.))}]},{nMut,3.7,0,-0.1}]];
(* Identify the [(Subscript[EC, 50])] for the nMut=0,1,2,3,4 cases from Figure 8 *)
mutantPointsEC50=Cases[pointsEC50,{#,_}]&/@Range[0.,4.,1.];

(* Plotting [(Subscript[EC, 50])] *)
labels=font[#,11]&/@{"Exact expression","Approximate form"};
leg=PointLegend[{ColorData[95][4],{ColorData[95][3]}},labels,Joined->{True,False},Spacings->{0.4,0.3},LegendMarkerSize->18,LegendMarkers->{None,"◆"}];
(* Approximation for [(Subscript[EC, 50])] at n=0,2,4 *)
approximationsEC50={{{0,(E^(-βϵ/4))KOwt}},{{2,(((E^(-βϵ/2))KOmut KOwt)/((KOmut+KOwt)))}},{{4,(E^(-βϵ/4))KOmut}}}/.CNGA2replace/.fit["BestFitParameters"];
plotC=Labeled[
Show[ListLogPlot[pointsEC50,Joined->True,PlotStyle->ColorData[95][4],FrameLabel->frameLabel13,PlotLegends->Placed[leg,{Scaled[{0.1,0.7}], {0, 0.5}}],PlotRange->{xRange,{1 (10^(-6.2)),(10^(-2.8))}},opts],ListLogPlot[First/@approximationsEC50,PlotStyle->{ColorData[95][3],PointSize[Medium]},PlotMarkers->"◆"]],cLabel,{{Top,Left}}];

(* === Begin Effective Hill Coefficient (h) === *)
hEquation=FullSimplify[2*c*D[Log[CNGA2pNormalized],c]]/.CNGA2replace/.fit["BestFitParameters"];
pointsH={nMut,hEquation}/.{nMut->#[[1]],c->#[[2]]}&/@pointsEC50;
(* Approximation for [(Subscript[EC, 50])] at n=0,2,4 *)
approximationsH={{{0,4-4 (E^(βϵ/4))-((4 (E^(-βϵ/4)) KOwt)/KCwt)}},{{2,2-4 (E^(βϵ/2))}},{{4,4-4 (E^(βϵ/4))-((4 (E^(-βϵ/4)) KOmut)/KCmut)}}}/.CNGA2replace/.fit["BestFitParameters"];
plotD=Labeled[
Show[ListPlot[pointsH,Joined->True,PlotStyle->ColorData[95][4],FrameLabel->frameLabel14,PlotRange->{xRange,{-0.1,2.65}},opts],ListPlot[First/@approximationsH,PlotStyle->{ColorData[95][3],PointSize[Medium]},Mesh->All,PlotMarkers->"◆"]],dLabel,{{Top,Left}}];

(* Plot the full grid *)
grid=Grid[{{plotA,plotB},{plotC,plotD}}]

Figure S12: Comparing Experimental Measurements of ϵ in nAChR

(* Plot A - Force wild type energy βϵ[5]=-18 *)
KOguess[βϵVal_]:=-10.885+0.5 βϵVal
KCguess[βϵVal_]:=-9.7
βϵVal=-18.;
fit=NonlinearModelFit[Flatten[nAChRdata,1],{nAChRFitFunction,βϵ[5]==βϵVal},{{KOlog,-22.76},{KClog,-11.7486},{βϵ[1],βϵVal+20},{βϵ[2],βϵVal+15},{βϵ[3],βϵVal+10},{βϵ[4],βϵVal+5},{βϵ[5],βϵVal}},{χ1,χ2,χ3,χ4,χ5,c}];
leg=PointLegend[colors,nAChRlabels,LegendMarkers->({Graphics[{EdgeForm[{Thickness[Medium],White}],{White,Thin,Circle[{0,0},0.1]},Disk[{0,0},0.1]}],0.03}&/@Range@4),Spacings->{0.1,0.4}];
plotA=Labeled[With[{opts=opts},Show[LogLinearPlot[Evaluate[nAChRFitFunction/.fit["BestFitParameters"]/.#&/@mutantsList],{c,(10^(-11)),(10^(-2))},PlotRange->{{(10^(-10)),(10^(-2.7))},{-0.01,1.07}},PlotLegends->Placed[leg,{Scaled[{0.78,0.33}], {0, 0.5}}],FrameLabel->frameLabel1,PlotStyle->colors[[5;;1;;-1]],opts],ListLogLinearPlot[data,PlotMarkers->{Graphics[{EdgeForm[{Thickness[Tiny],White}],Disk[{0,0},0.1]}],0.03},PlotStyle->colors[[5;;1;;-1]]]]
],aLabel,{{Top,Left}}];

(* Plot B - Force wild type energy βϵ[5]=-16 *)
βϵVal=-16.;
fit2=NonlinearModelFit[Flatten[nAChRdata,1],{nAChRFitFunction,βϵ[5]==βϵVal},{{KOlog,-22.76},{KClog,-11.7486},{βϵ[1],βϵVal+20},{βϵ[2],βϵVal+15},{βϵ[3],βϵVal+10},{βϵ[4],βϵVal+5},{βϵ[5],βϵVal}},{χ1,χ2,χ3,χ4,χ5,c}];
plotB=Labeled[With[{opts=opts},Show[LogLinearPlot[Evaluate[nAChRFitFunction/.fit2["BestFitParameters"]/.#&/@mutantsList],{c,(10^(-11)),(10^(-2))},PlotRange->{{(10^(-10)),(10^(-2.7))},{-0.01,1.07}},PlotLegends->Placed[leg,{Scaled[{0.78,0.33}], {0, 0.5}}],FrameLabel->frameLabel1,PlotStyle->colors[[5;;1;;-1]],opts],ListLogLinearPlot[data,PlotMarkers->{Graphics[{EdgeForm[{Thickness[Tiny],White}],Disk[{0,0},0.1]}],0.03},PlotStyle->colors[[5;;1;;-1]]]]
],bLabel,{{Top,Left}}];
grid=Grid[{{plotA,plotB}}]

Figure S13: Comparing Experimental Measurements of ϵ in CNGA2

(* ==== Plot A ==== *)
(* The same fit as in Figure 6, but now forcing βϵ=-5 *)
fit=NonlinearModelFit[Flatten[CNGA2data,1],{CNGA2FitFunction,βϵ==-5.},{{KOwtLog,-14.4},{KOmutLog,-3.6},{KCwtLog,-4.5},{KCmutLog,-0.9},{βϵ,-9.0}},{nMut,c}];

(* Plotting the fits *)
leg=PointLegend[colors,CNGA2labels,LegendMarkers->({Graphics[{EdgeForm[{Thickness[Medium],White}],{White,Thin,Circle[{0,0},0.1]},Disk[{0,0},0.1]}],0.03}&/@Range@4),Spacings->{0.1,0.4}];
plots=Table[CNGA2FitFunction/.nMut->jj,{jj,0,4}]/.fit["BestFitParameters"];
plotA=Labeled[With[{opts=opts},
Show[LogLinearPlot[plots,{c,(10^(-7)),(10^(-2))},PlotStyle->colors,FrameLabel->frameLabel7,opts],ListLogLinearPlot[CNGA2data[[All,All,{2,3}]],PlotStyle->colors,PlotMarkers->{Graphics[{EdgeForm[{Thickness[Tiny],White}],Disk[{0,0},0.1]}],0.03},PlotLegends->Placed[leg,{Scaled[{0.78,0.32}], {0, 0.5}}]]]
],aLabel,{{Top,Left}}];

(* ==== Plot B ==== *)
(* The same fit as in Figure 6, but now forcing βϵ=-8 *)
fit=NonlinearModelFit[Flatten[CNGA2data,1],{CNGA2FitFunction,βϵ==-8.},{{KOwtLog,-15.5},{KOmutLog,-4.0},{KCwtLog,-4.2},{KCmutLog,-0.9},{βϵ,-9.0}},{nMut,c}];

(* Plotting the fits *)
leg=PointLegend[colors,CNGA2labels,LegendMarkers->({Graphics[{EdgeForm[{Thickness[Medium],White}],{White,Thin,Circle[{0,0},0.1]},Disk[{0,0},0.1]}],0.03}&/@Range@4),Spacings->{0.1,0.4}];
plots=Table[CNGA2FitFunction/.nMut->jj,{jj,0,4}]/.fit["BestFitParameters"];
plotB=Labeled[With[{opts=opts},
Show[LogLinearPlot[plots,{c,(10^(-7)),(10^(-2))},PlotStyle->colors,FrameLabel->frameLabel7,opts],ListLogLinearPlot[CNGA2data[[All,All,{2,3}]],PlotStyle->colors,PlotMarkers->{Graphics[{EdgeForm[{Thickness[Tiny],White}],Disk[{0,0},0.1]}],0.03},PlotLegends->Placed[leg,{Scaled[{0.78,0.32}], {0, 0.5}}]]]
],bLabel,{{Top,Left}}];

Grid[{{plotA,plotB}}]

Figure S14: Individual nAChR Fits for [(Subscript[EC, 50])] and effective Hill coefficients

(* Begin with the fit from Figure 3 *)
fit=NonlinearModelFit[Flatten[nAChRdata,1],{nAChRFitFunction,βϵ[1]==-4.},{{KOlog,-22.76},{KClog,-11.7486},{βϵ[1],-4.},{βϵ[2],-9.},{βϵ[3],-14.},{βϵ[4],-19.},{βϵ[5],-24.}},{χ1,χ2,χ3,χ4,χ5,c}];
(* Individually fit each data set, using the Figure 3 parameters as starting guesses *)
Do[
individualFits[jj]=NonlinearModelFit[nAChRdata[[jj]],nAChRFitFunction,{{KOlog,(KOlog/.fit["BestFitParameters"])},{KClog,(KClog/.fit["BestFitParameters"])},{βϵ[jj],(βϵ[jj]/.fit["BestFitParameters"])}},{χ1,χ2,χ3,χ4,χ5,c}]
,{jj,1,5}];
plots=Normal@(individualFits/@Range@5)/.(E^(βϵ[_])):>0/.{χ1->1,χ2->1,χ3->1,χ4->1,χ5->1};

(* Plotting the fits *)
leg=PointLegend[colors,nAChRlabels,LegendMarkers->({Graphics[{EdgeForm[{Thickness[Medium],White}],{White,Thin,Circle[{0,0},0.1]},Disk[{0,0},0.1]}],0.03}&/@Range@4),Spacings->{0.1,0.4}];
plotA=With[{opts=opts},Show[LogLinearPlot[plots,{c,(10^(-11)),(10^(-2))},PlotRange->{{(10^(-10)),(10^(-2.7))},{-0.01,1.07}},PlotLegends->Placed[leg,{Scaled[{0.78,0.33}], {0, 0.5}}],FrameLabel->frameLabel1,PlotStyle->colors[[5;;1;;-1]],opts],ListLogLinearPlot[data,PlotMarkers->{Graphics[{EdgeForm[{Thickness[Tiny],White}],Disk[{0,0},0.1]}],0.03},PlotStyle->colors[[5;;1;;-1]]]]
]

Figure S15: Sloppiness discussion of nAChR Curves

(* Plot A - Force wild type βϵ (listed as ((βϵ)^((0))) in the text, and as βϵ[5] in the code) to equal -20 *)
fit=NonlinearModelFit[Flatten[nAChRdata,1],{nAChRFitFunction,βϵ[5]==-20.},{{KOlog,-22.76},{KClog,-11.7486},{βϵ[1],0.},{βϵ[2],-5.},{βϵ[3],-10.},{βϵ[4],-15.},{βϵ[5],-20.}},{χ1,χ2,χ3,χ4,χ5,c}];
leg=PointLegend[colors,nAChRlabels,LegendMarkers->({Graphics[{EdgeForm[{Thickness[Medium],White}],{White,Thin,Circle[{0,0},0.1]},Disk[{0,0},0.1]}],0.03}&/@Range@4),Spacings->{0.1,0.4}];
plotA=Labeled[With[{opts=opts},Show[LogLinearPlot[Evaluate[nAChRFitFunction/.fit["BestFitParameters"]/.#&/@mutantsList],{c,(10^(-11)),(10^(-2))},PlotRange->{{(10^(-10)),(10^(-2.7))},{-0.01,1.07}},PlotLegends->Placed[leg,{Scaled[{0.78,0.33}], {0, 0.5}}],FrameLabel->frameLabel1,PlotStyle->colors[[5;;1;;-1]],opts],ListLogLinearPlot[data,PlotMarkers->{Graphics[{EdgeForm[{Thickness[Tiny],White}],Disk[{0,0},0.1]}],0.03},PlotStyle->colors[[5;;1;;-1]]]]
],aLabel,{{Top,Left}}];
(* Plot B - Force wild type βϵ to equal -100 *)
fit2=NonlinearModelFit[Flatten[nAChRdata,1],{nAChRFitFunction,βϵ[5]==-100.},{{KOlog,-60.885},{KClog,-9.7},{βϵ[1],-80.},{βϵ[2],-85.},{βϵ[3],-90.},{βϵ[4],-95.},{βϵ[5],-100.}},{χ1,χ2,χ3,χ4,χ5,c}];
plotB=Labeled[With[{opts=opts},Show[LogLinearPlot[Evaluate[nAChRFitFunction/.fit2["BestFitParameters"]/.#&/@mutantsList],{c,(10^(-11)),(10^(-2))},PlotRange->{{(10^(-10)),(10^(-2.7))},{-0.01,1.07}},FrameLabel->frameLabel1,PlotStyle->colors[[5;;1;;-1]],opts],ListLogLinearPlot[data,PlotMarkers->{Graphics[{EdgeForm[{Thickness[Tiny],White}],Disk[{0,0},0.1]}],0.03},PlotStyle->colors[[5;;1;;-1]]]]
],bLabel,{{Top,Left}}];
grid=Grid[{{plotA,plotB}}]

Figure S16: Sloppiness approximation of nAChR Curves

(* Plot A - Difference between exact gene expression ((((1+(c/KO)))^2)/((((1+(c/KO)))^2)+(E^(-βϵ)) (((1+(c/KC)))^2))) and the approximate form (((((c/KO)))^2)/(((((c/KO)))^2)+(E^(-βϵ)) (((1+(c/KC)))^2))) which has no sloppiness *)
fit=NonlinearModelFit[Flatten[nAChRdata,1],{nAChRFitFunction,βϵ[5]==-24.},{{KOlog,-22.76},{KClog,-11.7486},{βϵ[1],-4.},{βϵ[2],-9.},{βϵ[3],-14.},{βϵ[4],-19.},{βϵ[5],-24.}},{χ1,χ2,χ3,χ4,χ5,c}];
plots={((((1+(c/KO)))^2)/((((1+(c/KO)))^2)+(E^(-βϵ)) (((1+(c/KC)))^2))),(((((c/KO)))^2)/(((((c/KO)))^2)+(E^(-βϵ)) (((1+(c/KC)))^2)))}/.{KC->(E^KClog),KO->(E^KOlog),βϵ->βϵ[5]}/.fit["BestFitParameters"];
leg=LineLegend[{ColorData[97][1],{ColorData[95][2],Dashed}},nAChRlabels4,Spacings->{0.1,0.4},LegendMarkerSize->20];
plotA=Labeled[LogLinearPlot[plots,{c,(10^(-7)),(10^(-3))},PlotRange->{Automatic,{-0.01,0.95}},PlotLegends->Placed[leg,{Scaled[{0.13,0.56}], {0, 0.5}}],FrameLabel->frameLabel24,PlotStyle->{ColorData[97][1],{ColorData[95][2],Dashed}},Evaluate@opts],aLabel,{{Top,Left}}];

(* Plot B - Maximum difference between exact and approximate forms over all [ACh] concentrations for each βϵ[5] value. For every βϵ[5] value, we find the corresponding (Subscript[K, C]) and (Subscript[K, O]) values through non-linear fitting, and then find the minimum value between the exact and approximate forms *)

(* Initial guesses for the non-linear fitting at each βϵ[5] value *)
KOguess[βϵVal_]:=-10.885+0.5 βϵVal
KCguess[βϵVal_]:=-9.7
(* Find the maximum difference for βϵ[5]=0 *)
approximationDiffs=List@With[{βϵVal=0.},diff=((((1+(c/KO)))^2)/((((1+(c/KO)))^2)+(E^(-βϵ)) (((1+(c/KC)))^2)))-(((((c/KO)))^2)/(((((c/KO)))^2)+(E^(-βϵ)) (((1+(c/KC)))^2)))/.{KC->(E^KClog),KO->(E^KOlog),βϵ->βϵVal}/.NonlinearModelFit[Last@data,{nAChRFitFunction/.Last@mutantsList/.βϵ[5]->βϵVal},{{KOlog,KOguess[βϵVal]},{KClog,KCguess[βϵVal]}},c]["BestFitParameters"];
{βϵVal,#,diff/.c->#}&@Min[c/.NSolve[{D[diff,c]==0,c>0},c]]];
(* Working our way down in βϵ[5] values, using the previous value as the starting guess for the maximum difference location *)
Quiet@Do[
diff=((((1+(c/KO)))^2)/((((1+(c/KO)))^2)+(E^(-βϵ)) (((1+(c/KC)))^2)))-(((((c/KO)))^2)/(((((c/KO)))^2)+(E^(-βϵ)) (((1+(c/KC)))^2)))/.{KC->(E^KClog),KO->(E^KOlog),βϵ->βϵVal}/.NonlinearModelFit[Last@data,{nAChRFitFunction/.Last@mutantsList/.βϵ[5]->βϵVal},{{KOlog,KOguess[βϵVal]},{KClog,KCguess[βϵVal]}},c]["BestFitParameters"];
AppendTo[approximationDiffs,{βϵVal,#,diff/.c->#}&@(c/.FindRoot[D[diff,c],{c,approximationDiffs[[-1,2]]}])
]
,{βϵVal,-0.1,-20,-0.1}];
(* Plot the results *)
plotB=Labeled[ListPlot[approximationDiffs[[All,{1,3}]],Joined->True,PlotStyle->ColorData[95][5],PlotRange->{{-20.1,0.1},{-0.004,0.35}},PlotRange->All,FrameLabel->frameLabel25,Evaluate@opts],bLabel,{{Top,Left}}];
grid=Grid[{{plotA,plotB}}]

Figure S17: All nAChR Predictions

We first consider all possible predictions using 2 of the 5 nAChR mutants to characterize the MWC parameters ((Subscript[K, O]), (Subscript[K, C]), and βϵ) and then fit the remaining mutant data. Then we consider using 3 data sets and then 4 data sets to characterize the MWC parameters.

fit=NonlinearModelFit[Flatten[nAChRdata,1],{nAChRFitFunction,βϵ[1]==-4.},{{KOlog,-22.76},{KClog,-11.7486},{βϵ[1],-4.},{βϵ[2],-9.},{βϵ[3],-14.},{βϵ[4],-19.},{βϵ[5],-24.}},{χ1,χ2,χ3,χ4,χ5,c}];

(* 'listInput' is a subset of the list {0,1,2,3,4}. Every element in this list is used to characterize the (Subscript[K, O]), (Subscript[K, C]), and βϵ parameters, with the remaining data sets being predicted by these parameters
'legendQ' = True implies that a plot legend will be shown *)
Clear[model,list,listInput,KAlog,KIlog]
model[listInput_,legendQ_:False]:=
(
(* In the text I specify wild type as 0 and fully mutated as 5, but in the code these are indexed as 1 through 5 *)
list=5-listInput;
startingGuess=fit["BestFitParameters"];
(* Fit to data for the 'listInput' elements *)
newDataTrainingSet=Flatten[nAChRdata[[list]],1];
(* Fit using the physical constraint (Subscript[K, O])≥(10^(-10))M, since smaller dissociation constants are unphysical *)
fitnAChR=NonlinearModelFit[newDataTrainingSet,{nAChRFitFunction,Log[(10^(-10.))]≤KOlog},Cases[List@@@startingGuess,f_/;MatchQ[f[[1]],KOlog|KClog|βϵ[Alternatives@@list]],{1}],{χ1,χ2,χ3,χ4,χ5,c}];
(* Make a linear approximation to the 'listInput' βϵ values and use that to predict the remaining βϵ values. When 'listInput' has exactly two elements, this amounts to taking the straight line between both energies and extrapolating it to the remaining energy values *)
linearModel=LinearModelFit[Transpose@{list,Thread[βϵ[list]]}/.fitnAChR["BestFitParameters"],x,x];
otherβϵValues=βϵ[#]->linearModel[#]&/@DeleteCases[Range@5,Alternatives@@list];
(*Echo[otherβϵValues];*)

labels=nAChRlabels;
leg=PointLegend[colors,labels,LegendMarkers->({Graphics[{EdgeForm[{Thickness[Medium],White}],{White,Thin,Circle[{0,0},0.1]},Disk[{0,0},0.1]}],0.03}&/@Range@4),Spacings->{0.1,0.4}];
plot=With[{opts=opts},Show[LogLinearPlot[Evaluate[nAChRFitFunction/.fitnAChR["BestFitParameters"]/.otherβϵValues/.#&/@mutantsList],{c,(10^(-11)),(10^(-2))},PlotRange->{{(10^(-10)),(10^(-2.7))},Automatic},PlotLegends->If[legendQ,Placed[leg,{Scaled[{0.78,0.33}], {0, 0.5}}],None],FrameLabel->frameLabel1,PlotStyle->Transpose@{ColorData[97]/@Range[5,1,-1],(Range[5]/.{Alternatives@@list->Automatic,_Integer->Dashed})},opts],ListLogLinearPlot[data,PlotMarkers->{Graphics[{EdgeForm[{Thickness[Tiny],White}],Disk[{0,0},0.1]}],0.03},PlotStyle->ColorData[97]/@Range[5,1,-1]]]
];

(* Compute (R^2) for the data sets not represented by 'listInput' *)
finalFit=NonlinearModelFit[Flatten[nAChRdata[[Complement[Range@5,list]]],1],Join[{nAChRFitFunction},Equal@@@Cases[fitnAChR["BestFitParameters"],f_/;MatchQ[f,KOlog|KClog->_],{1}],Equal@@@otherβϵValues],Cases[List@@@startingGuess,f_/;MatchQ[f[[1]],KOlog|KClog|βϵ[Alternatives@@Complement[Range@5,list]]],{1}],{χ1,χ2,χ3,χ4,χ5,c}];
(*Echo[Row[{listInput,": (R^2)=",finalFit["RSquared"]}]];*)

(* Return a plot of the resulting predictiosn *)
plot
)

(* All possible predictions using 2 data sets to characterize the MWC parameters and predict the remaining data sets *)
indices=Subsets[Range[0,4],{2}];
letters=Style[#,FontFamily->"Times",14]&/@ToUpperCase@Alphabet[][[;;Length@indices]];
grid=Grid[Partition[Labeled[model[indices[[#]],If[#==1,True,False]],letters[[#]],{{Top,Left}}]&/@Range@Length@indices,2]]

(* All possible predictions using 3 data sets to characterize the MWC parameters and predict the remaining data sets *)
indices=Subsets[Range[0,4],{3}];
letters=Style[#,FontFamily->"Times",14]&/@ToUpperCase@Alphabet[][[;;Length@indices]];
grid=Grid[Partition[Labeled[model[indices[[#]],If[#==1,True,False]],letters[[#]],{{Top,Left}}]&/@Range@Length@indices,2]]

(* All possible predictions using 4 data sets to characterize the MWC parameters and predict the remaining data sets *)
indices=Subsets[Range[0,4],{4}];
letters=Style[#,FontFamily->"Times",14]&/@ToUpperCase@Alphabet[][[;;Length@indices]];
grid=Grid[Partition[Append[Labeled[model[indices[[#]],If[#==1,True,False]],letters[[#]],{{Top,Left}}]&/@Range@Length@indices,""],2]]

Figure S18: All CNGA2 Predictions

We first consider all possible predictions using 2 of the 5 nAChR mutants to characterize the MWC parameters ((Subscript[K, O]), (Subscript[K, C]), and βϵ) and then fit the remaining mutant data. Then we consider using 1 data set (for the n=1,2,or 3 mutants) as well as 3 or 4 data sets to characterize the MWC parameters.

(* 'listInput' is a subset of the list {0,1,2,3,4}. Every element in this list is used to characterize the (Subscript[K, O]), (Subscript[K, C]), and βϵ parameters, with the remaining data sets being predicted by these parameters
'legendQ' = True implies that a plot legend will be shown *)
Clear[model,list,listInput,KAlog,KIlog]
model[listInput_,legendQ_:False]:=
(
(* Fit just the data sets provided in 'listInput'. The remaining mutant data sets will be pure predictions *)
fit=NonlinearModelFit[Flatten[CNGA2data[[listInput+1]],1],{CNGA2FitFunction,KCmutLog==-2.},{{KOwtLog,Log[1.2 (10^(-6))]},{KOmutLog,Log[510 (10^(-6))]},{KCwtLog,Log[22 (10^(-6))]},{KCmutLog,Log[140 (10^(-3))]},{βϵ,-3.4}},{nMut,c}];

labels=CNGA2labels;
leg=PointLegend[colors,labels,LegendMarkers->({Graphics[{EdgeForm[{Thickness[Medium],White}],{White,Thin,Circle[{0,0},0.1]},Disk[{0,0},0.1]}],0.03}&/@Range@4),Spacings->{0.1,0.4}];
plots=Table[CNGA2FitFunction/.nMut->jj,{jj,0,4}]/.fit["BestFitParameters"];
plotStyle=Range[0,4]/.{Alternatives@@listInput->Automatic,_Integer->Dashed};
With[{opts=opts},
Show[LogLinearPlot[Evaluate@plots,{c,(10^(-7)),(10^(-2))},FrameLabel->frameLabel7,PlotRange->{{(10^(-7.1)),(10^(-2))},{-0.01,1.05}},PlotStyle->plotStyle,opts],ListLogLinearPlot[newData3,PlotMarkers->{Graphics[{EdgeForm[{Thickness[Tiny],White}],Disk[{0,0},0.1]}],0.03},PlotLegends->If[legendQ,Placed[leg,{Scaled[{0.78,0.33}], {0, 0.5}}],None]]]
]
)

(* All possible predictions using 2 data sets to characterize the MWC parameters and predict the remaining data sets *)
indices=Reverse(* Reverse for consistency with SI Figure 27 *)@Subsets[Range[0,4],{2}];
letters=Style[#,FontFamily->"Times",14]&/@ToUpperCase@Alphabet[][[;;Length@indices]];
grid=Grid[Partition[Labeled[model[indices[[#]],If[#==1,True,False]],letters[[#]],{{Top,Left}}]&/@Range@Length@indices,2]]

(* All possible predictions using 3 data sets to characterize the MWC parameters and predict the remaining data sets *)
indices=Subsets[Range[0,4],{3}];
letters=Style[#,FontFamily->"Times",14]&/@ToUpperCase@Alphabet[][[;;Length@indices]];
grid=Grid[Partition[Labeled[model[indices[[#]],If[#==1,True,False]],letters[[#]],{{Top,Left}}]&/@Range@Length@indices,2]]

(* All possible predictions using 4 data sets to characterize the MWC parameters and predict the remaining data sets *)
indices=Subsets[Range[0,4],{4}];
letters=Style[#,FontFamily->"Times",14]&/@ToUpperCase@Alphabet[][[;;Length@indices]];
grid=Grid[Partition[Append[Labeled[model[indices[[#]],If[#==1,True,False]],letters[[#]],{{Top,Left}}]&/@Range@Length@indices,""],2]]

(* For CNGA2, you can in fact theoretically predict the behavior of the entire class of mutants using only the n=2, n=3, or n=4 data sets, since these dose-response curves already contain information about both the wild type and mutant subunits, and hence can be used to characterize all five MWC parameters. However, these fits (as expected) are not as good as the ones that utilize more data sets as input, as they are highly susceptible to the details of a specific channel response (i.e. this is a case of over-fitting) *)
indices=List/@Range[1,3];
letters=Style[#,FontFamily->"Times",14]&/@ToUpperCase@Alphabet[][[;;Length@indices]];
grid=Grid[Partition[Append[Labeled[model[indices[[#]],If[#==1,True,False]],letters[[#]],{{Top,Left}}]&/@Range@Length@indices,""],2]]

Initialization

Fitting

nAChR Fitting

(* Original function *)
nAChRpBound=((((1+(c/KO)))^2)/((((1+(c/KO)))^2)+(E^(-βϵ))(((1+(c/KC)))^2)));
(* Find the minima and maxima in order to normalize *)
nAChRpMin=Limit[nAChRpBound,c->0];
nAChRpMax=Limit[nAChRpBound,c->∞];
nAChRpNormalized=FullSimplify[((nAChRpBound-nAChRpMin)/(nAChRpMax-nAChRpMin))];

nAChRreplace={KC->(E^KClog),KO->(E^KOlog),βϵ->Log[χ1 (E^(βϵ[1]))+χ2 (E^(βϵ[2]))+χ3 (E^(βϵ[3]))+χ4 (E^(βϵ[4]))+χ5 (E^(βϵ[5]))],KAeff->(χ1 (E^(KAeffLog[1]))+χ2 (E^(KAeffLog[2]))+χ3 (E^(KAeffLog[3]))+χ4 (E^(KAeffLog[4]))+χ5 (E^(KAeffLog[5])))};
nAChRFitFunction=nAChRpNormalized/.nAChRreplace;

CNGA2 Fitting

(* Original function *)
CNGA2pBound=(((((1+(c/KOwt)))^(4-nMut))(((1+(c/KOmut)))^nMut))/((((1+(c/KOwt)))^(4-nMut))(((1+(c/KOmut)))^nMut)+(E^(-βϵ))(((1+(c/KCwt)))^(4-nMut))(((1+(c/KCmut)))^nMut)));
(* Find the minima and maxima in order to normalize *)
CNGA2pMin=Limit[CNGA2pBound,c->0];
CNGA2pMax=Limit[CNGA2pBound,c->∞];
CNGA2pNormalized=FullSimplify[((CNGA2pBound-CNGA2pMin)/(CNGA2pMax-CNGA2pMin))];

CNGA2replace={KOwt->(E^KOwtLog),KOmut->(E^KOmutLog),KCwt->(E^KCwtLog),KCmut->(E^KCmutLog)};
CNGA2FitFunction=CNGA2pNormalized/.CNGA2replace;

Figure Labels

(* PlotLegend labels *)
nAChRlabels={"n=0Text","n=1Text","n=2Text","n=3Text","n=4Text"};
nAChRlabels2={"((βϵ)^((0)))Text","((βϵ)^((1)))Text","((βϵ)^((2)))Text","((βϵ)^((3)))Text","((βϵ)^((4)))Text","\!\(\*Cell[TextData[Cell[BoxData[
FormBox[
RowBox[{
RowBox[{
SubscriptBox[
StyleBox["log",
FontSize->10], "10"], 
StyleBox["(",
FontSize->10], 
StyleBox[
SubscriptBox["K", "C"],
FontSize->10], 
StyleBox[")",
FontSize->10]}], 
StyleBox[" ",
FontSize->10], 
StyleBox[
RowBox[{"(", 
StyleBox["M",
FontSlant->"Plain"], ")"}],
FontSize->10]}], TraditionalForm]]]], "Text",
CellChangeTimes->{{3.6818905989851923`*^9, 3.681890603120429*^9}}]\)"};
nAChRlabels3={"\!\(\*Cell[TextData[Cell[BoxData[
FormBox[
StyleBox[
RowBox[{
SubscriptBox["α", "2"], "βγδ"}],
FontSize->10], TraditionalForm]]]], "Text",
CellChangeTimes->{{3.6810994294725723`*^9, 3.681099430285576*^9}}]\)","\!\(\*Cell[TextData[Cell[BoxData[
FormBox[
StyleBox[
RowBox[{
SubscriptBox["α", "2"], 
SuperscriptBox["βγ", "*"], "δ"}],
FontSize->10], TraditionalForm]]]], "Text",
CellChangeTimes->{{3.6810994294725723`*^9, 3.681099430285576*^9}}]\)","\!\(\*Cell[TextData[Cell[BoxData[
FormBox[
StyleBox[
RowBox[{
SubscriptBox["α", "2"], 
SuperscriptBox["βγδ", "*"]}],
FontSize->10], TraditionalForm]]]], "Text",
CellChangeTimes->{{3.6810994294725723`*^9, 3.681099430285576*^9}}]\)","\!\(\*Cell[TextData[Cell[BoxData[
FormBox[
StyleBox[
RowBox[{
SubscriptBox["α", "2"], 
SuperscriptBox["βγ", "*"], 
SuperscriptBox["δ", "*"]}],
FontSize->10], TraditionalForm]]]], "Text",
CellChangeTimes->{{3.6810994294725723`*^9, 3.681099430285576*^9}}]\)"};
nAChRlabels4={"\!\(\*Cell[TextData[Cell[BoxData[
FormBox[
StyleBox[
RowBox[{
SubscriptBox["p", "open"], "(", "c", ")"}],
FontSize->12], TraditionalForm]]]], "Text",
CellChangeTimes->{{3.6810994294725723`*^9, 3.681099430285576*^9}}]\)","\!\(\*Cell[TextData[Cell[BoxData[
FormBox[
StyleBox[
RowBox[{
SubsuperscriptBox["p", "open", 
AdjustmentBox["approx",
BoxBaselineShift->-0.2857142857142857,
BoxMargins->{{0., 0.}, {0.2857142857142857, -0.2857142857142857}}]], "(", "c", ")"}],
FontSize->12], TraditionalForm]]]], "Text",
CellChangeTimes->{{3.6810994294725723`*^9, 3.681099430285576*^9}}]\)"};
CNGA2labels={"n=0Text","n=1Text","n=2Text","n=3Text","n=4Text"};
CNGA2labels2={"\!\(\*Cell[TextData[Cell[BoxData[
FormBox[
StyleBox[
RowBox[{
RowBox[{
SubscriptBox[
StyleBox["log",
FontSize->10], "10"], "(", 
SubsuperscriptBox["K", "O", "*"], ")"}], " ", 
RowBox[{"(", 
StyleBox["M",
FontSlant->"Plain"], ")"}]}],
FontSize->10], TraditionalForm]]]], "Text",
CellChangeTimes->{{3.6818905989851923`*^9, 3.681890603120429*^9}}]\)","\!\(\*Cell[TextData[Cell[BoxData[
FormBox[
StyleBox[
RowBox[{
RowBox[{
SubscriptBox[
StyleBox["log",
FontSize->10], "10"], "(", 
SubscriptBox["K", "C"], ")"}], " ", 
RowBox[{"(", 
StyleBox["M",
FontSlant->"Plain"], ")"}]}],
FontSize->10], TraditionalForm]]]], "Text",
CellChangeTimes->{{3.6818905989851923`*^9, 3.681890603120429*^9}}]\)","\!\(\*Cell[TextData[Cell[BoxData[
FormBox[
StyleBox[
RowBox[{
RowBox[{
SubscriptBox[
StyleBox["log",
FontSize->10], "10"], "(", 
SubsuperscriptBox["K", "C", "*"], ")"}], " ", 
RowBox[{"(", 
StyleBox["M",
FontSlant->"Plain"], ")"}]}],
FontSize->10], TraditionalForm]]]], "Text",
CellChangeTimes->{{3.6818905989851923`*^9, 3.681890603120429*^9}}]\)","βϵText"};

(* FrameLabel for plots *)
frameLabel1=font[#,10]&/@{"\!\(\*Cell[TextData[Cell[BoxData[
FormBox[
RowBox[{
RowBox[{"[", "ACh", "]"}], " ", 
RowBox[{"(", 
StyleBox["M",
FontSlant->"Plain"], ")"}]}], TraditionalForm]],
FontSize->10]], "Text",
CellChangeTimes->{3.6541908437503166`*^9}]\)","normalized currentText"};
frameLabel2=font[#,10]&/@{"\!\(\*Cell[TextData[Cell[BoxData[
FormBox[
RowBox[{
RowBox[{"Bohr", " ", "parameter"}], ",", " ", 
RowBox[{
SubscriptBox["F", "nAChR"], " ", 
RowBox[{"(", 
RowBox[{
SubscriptBox["k", "B"], "T", " ", "units"}], ")"}]}]}], TraditionalForm]],
FontSize->10]], "Text",
CellChangeTimes->{3.6541908437503166`*^9}]\)","(Subscript[p, open])Text"};
frameLabel3=font[#,10]&/@{"βϵText","leakinessText"};
frameLabel4=font[#,10]&/@{"βϵText","dynamic rangeText"};
frameLabel5=font[#,10]&/@{"βϵText","\!\(\*Cell[TextData[Cell[BoxData[
FormBox[
RowBox[{
RowBox[{"[", 
SubscriptBox["EC", "50"], "]"}], " ", 
RowBox[{"(", 
StyleBox["M",
FontSlant->"Plain"], ")"}]}], TraditionalForm]]]], "Text",
CellChangeTimes->{{3.6541943215768204`*^9, 3.654194322649226*^9}},
FontSize->10]\)"};
frameLabel6=font[#,10]&/@{"βϵText","hText"};
frameLabel7=font[#,10]&/@{"\!\(\*Cell[TextData[Cell[BoxData[
FormBox[
RowBox[{
RowBox[{"[", "cGMP", "]"}], " ", 
RowBox[{"(", 
StyleBox["M",
FontSlant->"Plain"], ")"}]}], TraditionalForm]],
FontSize->10]], "Text",
CellChangeTimes->{3.6541908437503166`*^9}]\)","normalized currentText"};
frameLabel8=font[#,10]&/@{"\!\(\*Cell[TextData[Cell[BoxData[
FormBox[
RowBox[{
RowBox[{"Bohr", " ", "parameter"}], ",", " ", 
RowBox[{
SubscriptBox["F", "CNGA2"], " ", 
RowBox[{"(", 
RowBox[{
SubscriptBox["k", "B"], "T", " ", "units"}], ")"}]}]}], TraditionalForm]],
FontSize->10]], "Text",
CellChangeTimes->{3.6541908437503166`*^9}]\)","(Subscript[p, open])Text"};
frameLabel9=font[#,10]&/@{"\!\(\*Cell[TextData[Cell[BoxData[
FormBox[
RowBox[{
RowBox[{"[", "cGMP", "]"}], " ", 
RowBox[{"(", 
StyleBox["M",
FontSlant->"Plain"], ")"}]}], TraditionalForm]],
FontSize->10]], "Text",
CellChangeTimes->{3.6541908437503166`*^9}]\)","\!\(\*Cell[TextData[Cell[BoxData[
FormBox[
RowBox[{"n", "=", 
RowBox[{"0", " ", "state", " ", "probabilities"}]}], TraditionalForm]]]], "Text",
CellChangeTimes->{{3.6541943215768204`*^9, 3.654194322649226*^9}},
FontSize->10]\)"};
frameLabel10=font[#,10]&/@{"\!\(\*Cell[TextData[Cell[BoxData[
FormBox[
RowBox[{
RowBox[{"[", "cGMP", "]"}], " ", 
RowBox[{"(", 
StyleBox["M",
FontSlant->"Plain"], ")"}]}], TraditionalForm]],
FontSize->10]], "Text",
CellChangeTimes->{3.6541908437503166`*^9}]\)","\!\(\*Cell[TextData[Cell[BoxData[
FormBox[
RowBox[{"n", "=", 
RowBox[{"4", " ", "state", " ", "probabilities"}]}], TraditionalForm]]]], "Text",
CellChangeTimes->{{3.6541943215768204`*^9, 3.654194322649226*^9}},
FontSize->10]\)"};
frameLabel11=font[#,10]&/@{"nText","leakinessText"};
frameLabel12=font[#,10]&/@{"nText","dynamic rangeText"};
frameLabel13=font[#,10]&/@{"nText","\!\(\*Cell[TextData[Cell[BoxData[
FormBox[
RowBox[{
RowBox[{"[", 
SubscriptBox["EC", "50"], "]"}], " ", 
RowBox[{"(", 
StyleBox["M",
FontSlant->"Plain"], ")"}]}], TraditionalForm]]]], "Text",
CellChangeTimes->{{3.6541943215768204`*^9, 3.654194322649226*^9}},
FontSize->10]\)"};
frameLabel14=font[#,10]&/@{"nText","hText"};
frameLabel15=font[#,10]&/@{"\!\(\*Cell[TextData[Cell[BoxData[
FormBox[
RowBox[{
SubscriptBox["K", "O"], " ", 
RowBox[{"(", 
StyleBox["M",
FontSlant->"Plain"], ")"}]}], TraditionalForm]],
FontSize->10]], "Text",
CellChangeTimes->{3.6541908437503166`*^9}]\)","model parametersText"};
frameLabel16=font[#,10]&/@{"time (sec)","probability"};
frameLabel17=font[#,10]&/@{"\!\(\*Cell[TextData[Cell[BoxData[
FormBox[
RowBox[{
RowBox[{"[", "ACh", "]"}], " ", 
RowBox[{"(", 
StyleBox["M",
FontSlant->"Plain"], ")"}]}], TraditionalForm]],
FontSize->10]], "Text",
CellChangeTimes->{3.6541908437503166`*^9}]\)","(Subscript[p, open])Text"};
frameLabel18=font[#,10]&/@{"\!\(\*Cell[TextData[Cell[BoxData[
FormBox[
RowBox[{
RowBox[{"[", "cGMP", "]"}], " ", 
RowBox[{"(", 
StyleBox["M",
FontSlant->"Plain"], ")"}]}], TraditionalForm]],
FontSize->10]], "Text",
CellChangeTimes->{3.6541908437503166`*^9}]\)","(Subscript[p, open])Text"};
frameLabel19=font[#,10]&/@{"nText","\!\(\*Cell[TextData[Cell[BoxData[
FormBox[
RowBox[{
RowBox[{"[", 
SubscriptBox["EC", "50"], "]"}], " ", 
RowBox[{"(", 
StyleBox["M",
FontSlant->"Plain"], ")"}]}], TraditionalForm]]]], "Text",
CellChangeTimes->{{3.6541943215768204`*^9, 3.654194322649226*^9}},
FontSize->10]\)"};
frameLabel20=font[#,10]&/@{"(Subscript[K, O])/(Subscript[K, C])Text","leakinessText"};
frameLabel21=font[#,10]&/@{"(Subscript[K, O])/(Subscript[K, C])Text","dynamic rangeText"};
frameLabel22=font[#,10]&/@{"(Subscript[K, O])/(Subscript[K, C])Text","\!\(\*Cell[TextData[Cell[BoxData[
FormBox[
RowBox[{
RowBox[{"[", 
SubscriptBox["EC", "50"], "]"}], "/", 
SubscriptBox["K", "O"]}], TraditionalForm]]]], "Text",
CellChangeTimes->{{3.6541943215768204`*^9, 3.654194322649226*^9}},
FontSize->10]\)"};
frameLabel23=font[#,10]&/@{"(Subscript[K, O])/(Subscript[K, C])Text","hText"};
frameLabel24=font[#,10]&/@{"\!\(\*Cell[TextData[Cell[BoxData[
FormBox[
RowBox[{
RowBox[{"[", "ACh", "]"}], " ", 
RowBox[{"(", 
StyleBox["M",
FontSlant->"Plain"], ")"}]}], TraditionalForm]],
FontSize->10]], "Text",
CellChangeTimes->{3.6541908437503166`*^9}]\)","(Subscript[p, open])Text"};
frameLabel25=font[#,10]&/@{"((βϵ)^((0)))Text","\!\(\*Cell[TextData[Cell[BoxData[
FormBox[
RowBox[{
SubscriptBox["max", "c"], 
RowBox[{"\[LeftBracketingBar]", 
RowBox[{
SubscriptBox["p", "open"], "-", 
SubsuperscriptBox["p", "open", "approx"]}], "\[RightBracketingBar]"}]}], TraditionalForm]]]], "Text",
CellChangeTimes->{{3.6541943215768204`*^9, 3.654194322649226*^9}},
FontSize->10]\)"};
frameLabel26=font[#,10]&/@{"nText","\!\(\*Cell[TextData[Cell[BoxData[
FormBox[
RowBox[{"log", "(", 
FractionBox[
RowBox[{"[", 
SubsuperscriptBox["EC", "50", "mut"], "]"}], 
RowBox[{"[", 
SubsuperscriptBox["EC", "50", "wt"], "]"}]], ")"}], TraditionalForm]]]], "Text",
CellChangeTimes->{{3.6541943215768204`*^9, 3.654194322649226*^9}},
FontSize->10]\)"};
frameLabel27=font[#,10]&/@{"\!\(\*Cell[TextData[Cell[BoxData[
FormBox[
RowBox[{
RowBox[{"[", "ACh", "]"}], " ", 
RowBox[{"(", "μM", ")"}]}], TraditionalForm]],
FontSize->10]], "Text",
CellChangeTimes->{3.6541908437503166`*^9}]\)","normalized currentText"};
frameLabel28=font[#,10]&/@{"predicted [(Subscript[EC, 50])]Text","measured [(Subscript[EC, 50])]Text"};

Figure Colors/Format

(* Color scheme *)
colors={,,,,,,,,,,};
colors2={,,,,,,};
colors3=Flatten[{#,Directive[#,Dashed]}&/@colors2[[;;5]],1];

(* Use Times New Roman font *)
font[text_,size_:12,opts___]:=Style[text,FontFamily->"Times",size,opts];

Note: I used the CustomTicks package to precisely control the size, location, and labels of the FrameTicks in all of the figures. I do not include that code here, since that is an optional package, but I highly recommend the package.

(* Image Size for all plots *)
size=295;

(* Plot markers, which I use when showing data from best-fit curves (i.e. not direct experimental data but best-fit data) *)
marker=Graphics[{Thickness[0.2],Line[{{-0.5,-0.5},{0.5,-0.5},{0.5,0.5},{-0.5,0.5},{-0.5,-0.5}}]}];
markerColor[color_]:=Graphics[{color,Thickness[0.2],Line[{{-0.5,-0.5},{0.5,-0.5},{0.5,0.5},{-0.5,0.5},{-0.5,-0.5}}]}];
markerSize=0.04;

opts={Frame->{True,True,False,False}(*,PlotRangeClipping->False*),Axes->False,ImageSize->{size,size/GoldenRatio},PlotRangePadding->{{Automatic,0},{0,Automatic}},
(* Make plots have similar look to Rob's 'Physical Biology of the Cell' *)
Prolog->{,Rectangle[Scaled[{0,0}],Scaled[{1,1}]]},FrameTicksStyle->Directive[,Thickness[Small],FontColor->],FrameStyle->Directive[,Thick,FontColor->]};

(* Labels for multiple plots *)
aLabel=Style["A",FontFamily->"Times",14];
bLabel=Style["B",FontFamily->"Times",14];
cLabel=Style["C",FontFamily->"Times",14];
dLabel=Style["D",FontFamily->"Times",14];

Raw Dose-Response Data

Data shown in the form
{ligand concentration (Molar units), normalized current}
where the normalized current ranges from 0 to 1.

Within each section, we demonstrate how to plot the data

nAChR Data

Data digitized from Figure 1B of Labarca 1995, Nature: Channel gating governed symmetrically by conserved leucine residues in the M2 domain of nicotinic receptors

(* The 5 data sets are in order: 
n=4 ((Subscript[α, 2])(SuperStar[β])(SuperStar[γ])(SuperStar[δ])), 
n=3 ((Subscript[α, 2]^( * ))(SuperStar[βγ])(SuperStar[δ])), 
n=2 ((Subscript[α, 2]^( * ))βγδ), 
n=1 ((Subscript[α, 2])(SuperStar[βγ])δ), 
n=0 (wild type) 
where n represents the number of mutated subunits in (Subscript[α, 2])βγδ nAChR, and the mutated subunits are also indicated by an asterisk supscript *)
data={{{2.48709936107592`*^-10,0.0899541554508751`},{5.0885598345785`*^-10,0.320509652590848`},{1.04111004149363`*^-9,0.594033899730821`},{2.53377767955113`*^-9,0.863672926480484`},{5.07281460538333`*^-9,0.955553919919246`}},{{1.01876817597469`*^-9,0.01395314602961`},{1.99588075012716`*^-9,0.0980190107671603`},{4.0835355348698`*^-9,0.266074507907133`},{6.0341918190285`*^-9,0.381356199528936`},{1.01561586197055`*^-8,0.531809913358008`},{1.98970501457948`*^-8,0.701813278095558`},{3.98353996872819`*^-8,0.82885052153432`},{6.01552057681328`*^-8,0.910931716857335`},{9.90745971104424`*^-8,0.981304676985195`}},{{1.01561586197055`*^-8,0.00251303835800831`},{2.47173180499458`*^-8,0.0201989401076716`},{4.94859407049017`*^-8,0.0788768085464335`},{9.90745971104424`*^-8,0.235210926985195`},{2.46408367172235`*^-7,0.59274320743607`},{4.93328192906576`*^-7,0.836967950874831`},{9.87680364548479`*^-7,0.979630194313593`},{2.45645920361575`*^-6,0.993412474764468`}},{{9.90745971104424`*^-8,0.0203671769851954`},{2.46408367172235`*^-7,0.0282900824360701`},{4.93328192906576`*^-7,0.086967950874832`},{1.00934046583632`*^-6,0.231585948014805`},{2.45645920361575`*^-6,0.639896849764468`},{5.02587063244321`*^-6,0.786467971904441`},{0.0000100621732343706`,0.938895840343203`},{0.0000250256246222384`,0.993693745794078`}},{{9.87680364548479`*^-7,0.00306769431359366`},{2.45645920361575`*^-6,0.0227093497644685`},{4.91801716709331`*^-6,0.0696684682032302`},{9.84624243717257`*^-6,0.192799461641992`},{0.0000250256246222384`,0.503459370794078`},{0.0000490279963796938`,0.755493985531628`},{0.000100310384479228`,0.872768232671601`},{0.000249481893147569`,1.01545676312247`}}};

The following plots the above data

leg=PointLegend[ColorData[97]/@Range@5,Table[font["n="<>ToString@j,10],{j,4,0,-1}],Spacings->{0.1,0.4}];
ListLogLinearPlot[data,PlotRange->{{(10^(-10)),(10^(-2.7))},{-0.01,1.07}},PlotLegends->Placed[leg,{Scaled[{0.8,0.33}], {0, 0.5}}],FrameLabel->frameLabel1,opts]

Data digitized from Figure 2 of Filatov 1995, Molecular Pharmacology: The role of conserved leucines in the M2 domain of the acetylcholine receptor in channel gating

(* Data is in the form: {# of Leu 9'Thr mutations, Log[((Subscript[EC, 50]^mut)/(Subscript[EC, 50]^wt))]} *)
leu9ThrData={{0,0},{1,-1.353942125`},{1,-1.278606075`},{2,-1.529315282`},{2,-1.844112347`},{2,-2.266543218`},{2,-2.465645635`},{3,-2.180985166`},{3,-2.280536374`},{3,-2.727171526`},{3,-2.859020491`},{4,-2.762667511`},{4,-2.916030184`},{5,-3.215278491`}};

Data digitized from Figure 1B of Filatov 1995, Molecular Pharmacology: The role of conserved leucines in the M2 domain of the acetylcholine receptor in channel gating

leu9ThrData2={{{0.020645131301201856`,-0.0024627954619258485`},{0.208129897715007`,-0.004782132938133676`},{0.5216545096850084`,-0.0022088928344836667`},{1.0376519058880074`,0.00460866282151251`},{5.221500607562624`,0.10555806657050781`},{20.766957882923226`,0.46589811601849473`},{212.11921128940364`,0.9841475924568711`}},{{0.05174644876003773`,-0.0019471870530067825`},{0.10073952375332833`,0.006940005150081641`},{0.20689434749964825`,0.03122942293274944`},{0.5175782157338285`,0.1510876696360669`},{2.052955160134082`,0.6791247022046312`},{5.157551457698662`,0.8699682411630782`},{20.704710152856222`,0.9854471177249845`}},{{0.10295734058164789`,-0.010561869107493349`},{0.2069389606159097`,0.017854816916997862`},{1.023414728595668`,0.528278930343645`},{5.124468643771598`,0.9358154566075608`},{20.502415544922158`,0.927839432698697`},{209.02152944092924`,0.8967072490700743`}},{{0.020198736888554725`,0.020183158032476722`},{0.05088938690774035`,0.034070371244056874`},{0.2026660489662376`,0.3121051529028033`},{0.30655983204664305`,0.6400633135913536`},{1.0065977478498467`,0.889399295195118`},{5.093456183431155`,0.9790287234100024`}}};

The following plots the above data

plotA=Labeled[ListPlot[leu9ThrData,FrameLabel->frameLabel26,opts],aLabel,{{Top,Left}}];
leg=Row[{LineLegend[colors,nAChRlabels,LegendMarkerSize->10,Spacings->{0.1,0.4}],PointLegend[{ColorData[97][1],Darker[ColorData[97][2],0.2],Lighter[ColorData[97][2],0.3],Darker@ColorData[97][3]},nAChRlabels3,Spacings->{0.1,0.3}]}];
plotB=Labeled[ListLogLinearPlot[leu9ThrData2,PlotRange->{{(10^(-3)),(10^4.3)},{-0.01,1.07}},FrameLabel->frameLabel27,PlotLegends->Placed[leg,{Scaled[{0.62,0.33}], {0, 0.5}}],opts],bLabel,{{Top,Left}}];
grid=Grid[{{plotA,plotB}}]

CNGA2 Data

Data digitized from Figure 1A of Wongsamitkul 2016, Nature. Quantifying the cooperative subunit action in a multimeric membrane receptor

(* The 5 data sets are in order: 
n=0 (wt-wt-wt-wt), 
n=1 (mut-wt-wt-wt), 
n=2 (mut-mut-wt-wt), 
n=3 (mut-mut-mut-wt), 
n=4 (mut-mut-mut-mut) 
where n represents the number of mutated subunits in homotetrameric CNGA2 *)
data2={{{0.2`,0.00683`},{0.5`,0.03775`},{1.`,0.15281`},{2.`,0.53379`},{3.`,0.71316`},{5.`,0.89002`},{10.`,0.94341`},{20.`,0.96179`},{30.`,0.99278`},{100.`,1.`}},{{0.2`,0.00432`},{0.5`,0.03961`},{1.`,0.16605`},{2.`,0.41177`},{3.`,0.50117`},{5.`,0.71641`},{10.`,0.7942`},{20.`,0.96225`},{100.`,1.`}},{{0.2`,0.00245`},{1.`,0.05557`},{2.`,0.15192`},{5.`,0.42783`},{10.`,0.62345`},{20.`,0.79161`},{100.`,0.9444`},{1000.`,1.`}},{{2.`,0.02692`},{5.`,0.06311`},{10.`,0.10938`},{20.`,0.20388`},{50.`,0.31558`},{100.`,0.46621`},{200.`,0.58361`},{300.`,0.69209`},{500.`,0.83734`},{1000.`,0.92867`},{3000.`,0.98903`},{5000.`,1.`}},{{50.`,0.00707`},{100.`,0.01598`},{200.`,0.0699`},{300.`,0.12687`},{500.`,0.30558`},{1000.`,0.7195`},{3000.`,0.95091`},{5000.`,1.`}}};

Data digitized from Figure 1B of Wongsamitkul 2016, Nature. Quantifying the cooperative subunit action in a multimeric membrane receptor

(* The 3 data sets are in order: 
n=0 (wt-wt-wt-wt), 
n=0 and n=4 (wt-wt-wt-wt + mut-mut-mut-mut in a 1:1 ratio), 
n=4 (mut-mut-mut-mut) 
where n represents the number of mutated subunits in homotetrameric CNGA2 *)data3={{{0.1998082871892`,0.00443676457017971`},{0.498128641146003`,0.0366044239647795`},{1.`,0.151707283676099`},{1.98869648971878`,0.534639804966913`},{3.00973048624308`,0.713744593576886`},{5.00479741890331`,0.888497453437041`},{9.95302305872666`,0.945374661772979`},{19.98082871892`,0.962952048412974`},{29.95591693013`,0.993583732954697`},{100.`,1.00250786591772`}},{{0.502841939516576`,0.0875520549617048`},{1.`,0.14297365922195`},{2.00751355653708`,0.327945514566458`},{5.0047974189033`,0.462005459259457`},{100.`,0.493046439425735`},{200.751355653708`,0.517901846444187`},{598.544045299122`,0.670912922727962`},{1004.71986661702`,0.836933646481694`},{5028.41939516573`,1.0031270185716`}},{{49.8128641146002`,0.00530893633741413`},{99.9999999999996`,0.0141526985232607`},{200.751355653708`,0.069575791131233`},{298.151931950884`,0.126406860687675`},{500.479741890329`,0.30552802112263`},{995.302305872664`,0.721939436154347`},{2995.59169301299`,0.952099016797492`},{5028.41939516574`,1.0031270185716`}}};

The following plots the above data

(* Shifting data to Molar instead of μMolar *)
newData2=Map[{#[[1]]*(10^(-6)),#[[2]]}&,data2,{2}];
(* Create legend *)
leg=PointLegend[ColorData[97]/@Range@5,Table[font["n="<>ToString@j,10],{j,0,4}],Spacings->{0.1,0.4}];
ListLogLinearPlot[newData2,PlotRange->{{(10^(-7)),(10^(-1.8))},{-0.01,1.07}},PlotLegends->Placed[leg,{Scaled[{0.8,0.33}], {0, 0.5}}],FrameLabel->frameLabel7,opts]

(* Shifting data to Molar instead of μMolar *)
newData3=Map[{#[[1]]*(10^(-6)),#[[2]]}&,data3,{2}];
(* Create legend *)
labels=font[#,10]&/@{Row[{Style["n",FontSlant->Italic],"="<>ToString@4}],Row[{Style["n",FontSlant->Italic],"=0,4 (1:1)"}],Row[{Style["n",FontSlant->Italic],"="<>ToString@0}]};
leg=PointLegend[ColorData[97]/@Range@5,labels,Spacings->{0.1,0.4}];
ListLogLinearPlot[newData3,PlotRange->{{(10^(-7)),(10^(-1.5))},{-0.01,1.07}},PlotLegends->Placed[leg,{Scaled[{0.73,0.33}], {0, 0.5}}],FrameLabel->frameLabel7,opts]

Modifying Data for Fitting

(* Helper function for modifying nAChR data *)
identifierList=FoldList[RotateRight,{1,0,0,0,0},{1,1,1,1}];
mutantsList=Rule@@@Transpose@{{χ1,χ2,χ3,χ4,χ5},#}&/@identifierList;

(* Data from the 5 nAChR dose-response curves is fit simultaneously. To do this, we transform each data point from the form 
{ligand concentration, normalized current} 
into 
{(Subscript[Q, n=0]),(Subscript[Q, n=1]),(Subscript[Q, n=2]),(Subscript[Q, n=3]),(Subscript[Q, n=4]),ligand concentration, normalized current}
where the (Subscript[Q, jj])=1 if the data point belongs in the 'jj' data set and 0 otherwise
 *)
nAChRdata=(len=Length@data[[#]];
Transpose@Join[{Table[identifierList[[#,1]],{len}],Table[identifierList[[#,2]],{len}],Table[identifierList[[#,3]],{len}],Table[identifierList[[#,4]],{len}],Table[identifierList[[#,5]],{len}]},Transpose@data[[#]]])&/@Range@5;

(* Data from the 5 CNGA2 dose-response curves is fit simultaneously. To do this, we transform each data point from the form 
{ligand concentration, normalized current} 
into 
{(Subscript[n, mut]),ligand concentration, normalized current}
where the (Subscript[n, mut]) is the number of mutated subunits ((Subscript[n, mut])=0 for the wild type channel and (Subscript[n, mut])=4 for the fully mutated ion channel)
 *)
(* Shifting data to Molar instead of μMolar *)
newData3=Map[{#[[1]]*(10^(-6)),#[[2]]}&,data2,{2}];
(* Format is {nMut,[cGMP],normalized current} *)
CNGA2data=Table[Transpose@Join[{Table[jj,{Length@#}]},Transpose@#]&@newData3[[jj+1]],{jj,0,Length@newData3-1}];