From ea7ba628c32a367719c80ec3c1b5cb0b5ca5a003 Mon Sep 17 00:00:00 2001 From: Chris Maffeo <cmaffeo2@illinois.edu> Date: Thu, 20 Sep 2018 09:34:30 -0500 Subject: [PATCH] Improved fit for non-bonded potential to all-atom data --- mrdna/model/nbPot.py | 104 ++++++++++++++++++++++++++++++++++++------- setup.py | 1 + 2 files changed, 90 insertions(+), 15 deletions(-) diff --git a/mrdna/model/nbPot.py b/mrdna/model/nbPot.py index 56e46b9..b93bcee 100644 --- a/mrdna/model/nbPot.py +++ b/mrdna/model/nbPot.py @@ -8,10 +8,11 @@ from mrdna import get_resource_path dxParam = -1 -def maxForce(x,u,maxForce=40): +def maxForce(x,u0,maxForce=40): maxForce = maxForce * 0.014393265 # convert pN to kcal_mol/AA dx = np.diff(x) - f = -np.diff(u)/dx + f = -np.diff(u0)/dx + f[ np.isnan(f) ] = 0 ids = np.where(f > maxForce)[0] f[ids] = maxForce @@ -23,6 +24,7 @@ def maxForce(x,u,maxForce=40): ids = np.where(x > 40)[0] u = u - np.mean(u[ids]) + assert( np.isnan(u).sum() == 0 ) return u # d = np.loadtxt("resources/jj-nar-dna-pmf-20Mg-200Na.dat") @@ -41,21 +43,48 @@ def parametric_potential(x,*parms): u[x>np.max(x0)] = 0 return u -def integrated_potential(potfn,x,numBp,*parms): +def integrate_potential(potfn,x,y,*parms): u = np.zeros(np.shape(x)) - for h in range(-numBp,numBp+1): - r = np.sqrt(x**2 + (3.4*h)**2) + for h in y: + r = np.sqrt(x**2 + h**2) r[r<1] = 1 u = u + potfn(r,*parms) # * x/r return u + +# def integrated_potential(potfn,x,numBp,*parms): +# u = np.zeros(np.shape(x)) +# for h in range(-numBp,numBp+1): +# r = np.sqrt(x**2 + (3.4*h)**2) +# r[r<1] = 1 +# u = u + potfn(r,*parms) # * x/r +# return u + def fitFun(x,*parms): ## 1-turn iteracting with 4 turns (more is not needed) - return 10 * integrated_potential(parametric_potential,x,20,*parms) + y = np.arange(-20,21)*3.4 + return 10 * integrate_potential(parametric_potential,x,y,*parms) + +def fitFun5(x,*parms): + ## 1-turn iteracting with 4 turns (more is not needed) + y = np.arange(-20,21)*(5*3.4) + return 5 * 5 * integrate_potential(parametric_potential,x,y,*parms) + xinterp = np.linspace(np.min(x0),np.max(x0),1000) # interpolate potentialb yinterp = interp1d(x0,y0)(xinterp) -popt, pcov = opt.curve_fit(fitFun, xinterp, yinterp, p0=y0/10**2 ) # find fit to interpolated potential + +def fit_potential(bp1,bp2): + assert(bp2 >= bp1) + + def fitFun(x,*parms): + ## 1-turn iteracting with at least 4 turns (more is not needed) + y = np.arange(-20,21)*(bp2*3.4) + return (10.0/bp1) * integrate_potential(parametric_potential,x,y,*parms) + + popt, pcov = opt.curve_fit(fitFun, xinterp, yinterp, p0=y0/10**2 ) # find fit to interpolated potential + return lambda x: parametric_potential(x,*popt) + def nbPot(x,bps1,bps2): larger = np.max([bps1,bps2]) @@ -63,12 +92,31 @@ def nbPot(x,bps1,bps2): if larger >= 2: largerInt = int(0.5*larger) smaller *= larger/(2*largerInt) - y = smaller * integrated_potential(parametric_potential,x,largerInt,*popt) + y = np.arange(-largerInt,largerInt+1)*3.4 + u = smaller * integrate_potential(parametric_potential,x,y,*popt) else: - y = smaller * larger * parametric_potential(x,*popt) - y = maxForce(x,y, 100) - y = savgol(y, int(5.0/(x0[1]-x0[0])), 3) - return y + u = smaller * larger * parametric_potential(x,*popt) + u1 = maxForce(x,u, 100) + # u2 = savgol(u1, int(5.0/(x0[1]-x0[0])), 3) + u2 = u + assert(np.sum(np.isnan(u2)) == 0) + return u2 + +_pot_dict = {} + +def nbPot(x,bps1,bps2): + larger = np.max([bps1,bps2]) + smaller = np.min([bps1,bps2]) + key = (smaller,larger) + if key not in _pot_dict: + _pot_dict[key] = fit_potential(*key) + u = _pot_dict[key](x) + + u1 = maxForce(x,u, 100) + # u2 = savgol(u1, int(5.0/(x0[1]-x0[0])), 3) + u2 = u + assert(np.sum(np.isnan(u2)) == 0) + return u2 x = np.linspace(0,100,1001) @@ -104,6 +152,32 @@ nbDnaScheme = nbDnaScheme() if __name__ == "__main__": ## run some tests np.savetxt("jj-filtered.dat", np.array((x0,y0)).T) - y = fitFun(x,*popt) - np.savetxt("1-bp-fit.dat", np.array((x,y)).T), - + + # y = single_bp_pot = fitFun(x,*popt) + # np.savetxt("1-bp-fit.dat", np.array((x,y)).T), + + # y = fitFun5(x,*popt5) + # np.savetxt("5-bp-fit.dat", np.array((x,y)).T), + + + # tmp = nbPot(np.linspace(20,45,100), 1,1) + # import pdb + # pdb.set_trace() + y = 10*integrate_potential(nbPot, x, np.arange(-20,20)*3.4 , 1, 1) + np.savetxt("nb-1-1.dat", np.array((x,y)).T), + + y = 10*integrate_potential(nbPot, x, np.arange(-20,20)*(3.4*2) , 1, 2) + np.savetxt("nb-1-2.dat", np.array((x,y)).T), + + y = 10*integrate_potential(nbPot, x, np.arange(-20,20)*(3.4*5) , 1, 5) + np.savetxt("nb-1-5.dat", np.array((x,y)).T), + + y = 5*integrate_potential(nbPot, x, np.arange(-20,20)*(3.4*2) , 2, 2) + np.savetxt("nb-2-2.dat", np.array((x,y)).T), + + y = 2*integrate_potential(nbPot, x, np.arange(-20,20)*(3.4*5) , 5, 5) + np.savetxt("nb-5-5.dat", np.array((x,y)).T), + + # y = 10*5*integrate_potential(parametric_potential, x, np.arange(-20,20)*(3.4*5) , *popt) + # np.savetxt("scale-5-5.dat", np.array((x,y)).T), + diff --git a/setup.py b/setup.py index e339ebf..2d104e7 100644 --- a/setup.py +++ b/setup.py @@ -25,6 +25,7 @@ setuptools.setup( 'scipy>=1.1', 'mdanalysis>=0.18', 'cadnano>=2.5.2.1', + 'appdirs>=1.4' ), classifiers=( "Programming Language :: Python :: 3", -- GitLab