Biochemical log sensor

Functions for initialization

(* 
n is number of Hill eqs in sum;
base is used as c = (base^i);
*)
HillEq[x_,k_,c_]:=(x/c)^k/(1+(x/c)^k);

popts={AspectRatio->1/GoldenRatio,Axes->False,Frame->True,PlotRange->{{-1-0.5,12+0.5},{-0.03*(6+1),1.03*(6+1)}},FrameTicks->{{Range[0,6+1],None},{Select[Range[-1,12],EvenQ],None}}};

FitHillToLog[n_,k_,base_,log2xmin_,log2xmax_]:= Module[
{tbl,fit,step,pl},
Clear[x];
step=2^((log2xmax-log2xmin)/100);
tbl=Table[{x,N[Sum[HillEq[x,k,base^i],{i,0,n}]]},{x,2^log2xmin,2^log2xmax,step}];
fit=FindFormula[tbl,x,TargetFunctions->{Log}];
Print[fit];
pl=ParametricPlot[{{Log[2,x],N[Sum[HillEq[x,k,base^i],{i,0,n}]]},{Log[2,x],fit}},{x,2^log2xmin,2^log2xmax},AspectRatio->1/GoldenRatio,Axes->False,Frame->True,PlotRange->{{log2xmin-0.5,log2xmax+0.5},{-0.03*(n+1),1.03*(n+1)}},FrameTicks->{{Range[0,n+1],None},{Select[Range[log2xmin,log2xmax],EvenQ],None}},PlotStyle->{Dashing[{0.1,0}],Dashing[{0.03,0.03}]}];
Show[pl]
]

FitHillToLogN[n_,k_,base_,log2xmin_,log2xmax_]:= Module[
{tbl,fit,step,pl},
Clear[x];
step=2^((log2xmax-log2xmin)/100);
tbl=Table[{x,N[Sum[HillEq[x,k,base^i],{i,0,n}]]},{x,2^log2xmin,2^log2xmax,step}];
pl=ParametricPlot[{{Log[2,x],N[Sum[HillEq[x,k,base^i],{i,0,n}]]}},{x,2^log2xmin,2^log2xmax},AspectRatio->1/GoldenRatio,Axes->False,Frame->True,PlotRange->{{log2xmin-0.5,log2xmax+0.5},{-0.03*(n+1),1.03*(n+1)}},FrameTicks->{{Range[0,n+1],None},{Select[Range[log2xmin,log2xmax],EvenQ],None}}];
Show[pl]
]

(* cv is sd/mean for Normal, => sd = mean*cv *)
FitHillToLogR[n_,k_,base_,log2xmin_,log2xmax_,cv_]:= Module[
{tbl,fit,step,pl,kR,baseR},
Clear[x];
kR=Table[RandomVariate[NormalDistribution[k,k*cv]],{i,0,n}];
baseR=Table[RandomVariate[NormalDistribution[base^i,base^i*cv]],{i,0,n}];
step=2^((log2xmax-log2xmin)/100);
tbl=Table[{x,N[Sum[HillEq[x,k,base^i],{i,0,n}]]},{x,2^log2xmin,2^log2xmax,step}];
fit=FindFormula[tbl,x,TargetFunctions->{Log}];
Print[fit];
pl=ParametricPlot[{{Log[2,x],N[Sum[HillEq[x,kR[[i+1]],baseR[[i+1]]],{i,0,n}]]},{Log[2,x],fit}},{x,2^log2xmin,2^log2xmax},AspectRatio->1/GoldenRatio,Axes->False,Frame->True,PlotRange->{{log2xmin-0.5,log2xmax+0.5},{-0.03*(n+1),1.03*(n+1)}},FrameTicks->{{Range[0,n+1],None},{Select[Range[log2xmin,log2xmax],EvenQ],None}},PlotStyle->{Dashing[{0.1,0}],Dashing[{0.03,0.03}]}];
Show[pl]
]

Plots: Figure 1

plA=ParametricPlot[{{Log[2,x],HillEq[x,1,2]}},{x,2^-1,2^12},Evaluate@popts]

n=6;
k={1,2};
base={4,8};
xmin=-1;
xmax=12;
pl=Table[Null,{Length[k]*Length[base]}];
For[i=1,i≤Length[k],i++,
For[j=1,j≤Length[base],j++,
pl[[j+2(i-1)]]=FitHillToLog[n,k[[i]],base[[j]],xmin,xmax];
]
]
Clear[n,k,base,xmin,xmax];
GraphicsColumn[pl,ImageSize->Large]

n=6;
k={1,2};
base={4,8};
xmin=-1;
xmax=12;
plR=Table[Null,{Length[k]*Length[base]}];
For[i=1,i≤Length[k],i++,
For[j=1,j≤Length[base],j++,
plR[[j+2(i-1)]]=FitHillToLogR[n,k[[i]],base[[j]],xmin,xmax,0.25];
]
]
Clear[n,k,base,xmin,xmax];
GraphicsColumn[plR,ImageSize->Large]

final=Labeled[GraphicsGrid[{{plA,pl[[1]],pl[[3]]},{pl[[2]],pl[[4]],plR[[3]]}},ImageSize->Full,Epilog->{
Inset[Text["A"],ImageScaled[{0.048,0.95}]],Inset[Text["B"],ImageScaled[{0.389,0.95}]],
Inset[Text["C"],ImageScaled[{0.728,0.95}]],Inset[Text["D"],ImageScaled[{0.048,0.435}]],
Inset[Text["E"],ImageScaled[{0.389,0.435}]],
Inset[Text["F"],ImageScaled[{0.728,0.435}]]
}],{Text[Style["Log2 input",FontSize->15]],Rotate[Text[Style["Sensor output",FontSize->15]],90Degree]},{Bottom,Left}]
Export["~/Desktop/logSensor.pdf",final];

Plots : Figures 2 and 3

Use k = 1 to generate Figure 2, and k = 2 to generate Figure 3

n={1,2,3,4,5,6};
k=2; (* 1 => Figure 2; 2 => Figure 3 *)
base={2,4,8,16};
xmin=-1;
xmax=14;
pl=Table[{Null,Null},Length[n],Length[base]];
For[i=1,i≤Length[n],i++,
For[j=1,j≤Length[base],j++,
pl[[i,j]]=FitHillToLogN[n[[i]],k,base[[j]],xmin,xmax];
]
]
Clear[n,k,base,xmin,xmax];
gout=GraphicsGrid[pl,ImageSize->Full]
Export["Desktop/plotNk.pdf",gout,ImageSize->560];