-
Notifications
You must be signed in to change notification settings - Fork 75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow tinkerio to read TINKERPATH variable from environment #206
base: master
Are you sure you want to change the base?
Changes from all commits
9cc0613
9739cdd
29cb1e5
bfee909
6467d43
d733a7d
a721335
8fe477b
923fb74
8e84119
1479bdc
c592fd3
5f97997
b27a8ab
856a7e5
894eb48
65aa071
840bb50
1af843d
3824a07
4e32677
d2af798
4225594
be69727
3c41916
82be78a
178f3e0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -314,14 +314,18 @@ def __init__(self, name="tinker", **kwargs): | |
self.warn_vn = False | ||
super(TINKER,self).__init__(name=name, **kwargs) | ||
|
||
def CheckEnvironmentTinker(self): | ||
tinkerpath = os.getenv("TINKERPATH", default="") | ||
return tinkerpath | ||
|
||
def setopts(self, **kwargs): | ||
|
||
""" Called by __init__ ; Set TINKER-specific options. """ | ||
|
||
## The directory containing TINKER executables (e.g. dynamic) | ||
if 'tinkerpath' in kwargs: | ||
self.tinkerpath = kwargs['tinkerpath'] | ||
if not os.path.exists(os.path.join(self.tinkerpath,"dynamic")): | ||
if not os.path.exists(os.path.join(self.tinkerpath,"dynamic")) and 'dynamic' not in os.environ.keys(): | ||
warn_press_key("The 'dynamic' executable indicated by %s doesn't exist! (Check tinkerpath)" \ | ||
% os.path.join(self.tinkerpath,"dynamic")) | ||
else: | ||
|
@@ -350,8 +354,24 @@ def calltinker(self, command, stdin=None, print_to_screen=False, print_command=F | |
# Sometimes the engine changes dirs and the key goes missing, so we link it. | ||
if "%s.key" % self.name in csplit and not os.path.exists("%s.key" % self.name): | ||
LinkFile(self.abskey, "%s.key" % self.name) | ||
prog = os.path.join(self.tinkerpath, csplit[0]) | ||
csplit[0] = prog | ||
tinkpath=self.CheckEnvironmentTinker() | ||
if tinkpath!=None: # need to override input masterhost tinkerpath, otherwise if worker node has different )S/ libraries then will crash | ||
tinkerpath=tinkpath | ||
else: | ||
tinkerpath=self.tinkerpath | ||
|
||
if 'analyze' in command: | ||
gpuvergood=False | ||
if stdin=='E,M': | ||
gpuvergood=True | ||
if command[-1]=='E' or command[-1]=='M': | ||
gpuvergood=True | ||
csplit[0]='analyze' | ||
command=' '.join(csplit) | ||
if '_gpu' not in command: | ||
prog = os.path.join(tinkerpath, csplit[0]) | ||
csplit[0] = prog | ||
|
||
o = _exec(' '.join(csplit), stdin=stdin, print_to_screen=print_to_screen, print_command=print_command, rbytes=1024, **kwargs) | ||
# Determine the TINKER version number. | ||
for line in o[:10]: | ||
|
@@ -360,12 +380,33 @@ def calltinker(self, command, stdin=None, print_to_screen=False, print_command=F | |
if len(vw.split('.')) <= 2: | ||
vn = float(vw) | ||
else: | ||
ls = vw.split('.') | ||
last = ls[1:] | ||
first = ls[0] | ||
vn = first+'.'+''.join(last) | ||
ls=vw.split('.') | ||
last=ls[1:] | ||
first=ls[0] | ||
vn=first+'.'+''.join(last) | ||
versionstr='' | ||
for e in vn: | ||
if e.isdigit() or e=='.': | ||
versionstr+=e | ||
count=versionstr.count('.') | ||
if count==2: | ||
newversionstr='' | ||
for eidx in range(len(versionstr)): | ||
e=versionstr[eidx] | ||
if eidx>1: | ||
if e!='.': | ||
newversionstr+=e | ||
else: | ||
newversionstr+=e | ||
versionstr=newversionstr | ||
vn=versionstr | ||
vn = float(vn) | ||
if '_gpu' in command: # then tinker 9 version | ||
vn_need=1 | ||
else: | ||
vn_need = 6.3 | ||
|
||
vn = float(vn) | ||
vn_need = 6.3 | ||
try: | ||
if vn < vn_need: | ||
if self.warn_vn: | ||
|
@@ -643,7 +684,7 @@ def evaluate_(self, xyzin, force=False, dipole=False): | |
Result = OrderedDict() | ||
# If we want the dipoles (or just energies), analyze is the way to go. | ||
if dipole or (not force): | ||
oanl = self.calltinker("analyze %s -k %s" % (xyzin, self.name), stdin="G,E,M", print_to_screen=False) | ||
oanl = self.calltinker("analyze %s -k %s" % (xyzin, self.name), stdin="E,M", print_to_screen=False) | ||
# Read potential energy and dipole from file. | ||
eanl = [] | ||
dip = [] | ||
|
@@ -729,6 +770,9 @@ def energy_dipole(self): | |
x = "%s.xyz" % self.name | ||
self.mol.write(x, ftype="tinker") | ||
Result = self.evaluate_(x, dipole=True) | ||
print('Result',Result,flush=True) | ||
print('Result["Energy"]',Result["Energy"],flush=True) | ||
print('Result["Dipole"]',Result["Dipole"],flush=True) | ||
return np.hstack((Result["Energy"].reshape(-1,1), Result["Dipole"])) | ||
|
||
def normal_modes(self, shot=0, optimize=True): | ||
|
@@ -910,13 +954,13 @@ def molecular_dynamics(self, nsteps, timestep, temperature=None, pressure=None, | |
if temperature is not None: | ||
md_defs["integrator"] = "stochastic" | ||
else: | ||
md_defs["integrator"] = "beeman" | ||
md_defs["integrator"] = "respa" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The default parameters are what's used if the user doesn't specify the option in the key file, so it doesn't need to be the most efficient, it only needs to be fail-safe. Does the use of respa require any additional options in the key file, i.e. specifying the long and short timestep, or the subdivision of the long timestep to make the short timestep? |
||
md_opts["thermostat"] = None | ||
# Periodic boundary conditions. | ||
if self.pbc: | ||
md_opts["vdw-correction"] = '' | ||
if temperature is not None and pressure is not None: | ||
md_defs["integrator"] = "beeman" | ||
md_defs["integrator"] = "respa" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See above comment. |
||
md_defs["thermostat"] = "bussi" | ||
md_defs["barostat"] = "montecarlo" | ||
if anisotropic: | ||
|
@@ -933,7 +977,7 @@ def molecular_dynamics(self, nsteps, timestep, temperature=None, pressure=None, | |
|
||
eq_opts = deepcopy(md_opts) | ||
if self.pbc and temperature is not None and pressure is not None: | ||
eq_opts["integrator"] = "beeman" | ||
eq_opts["integrator"] = "respa" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See above comment. |
||
eq_opts["thermostat"] = "bussi" | ||
eq_opts["barostat"] = "berendsen" | ||
|
||
|
@@ -942,27 +986,31 @@ def molecular_dynamics(self, nsteps, timestep, temperature=None, pressure=None, | |
self.optimize(0, method="bfgs", crit=1) | ||
os.system("mv %s.xyz_2 %s.xyz" % (self.name, self.name)) | ||
if verbose: logger.info("Done\n") | ||
if 'GPUDYNAMICS' in os.environ.keys() and 'gas' not in self.name: | ||
dynamickeyword='dynamic_gpu' | ||
suffix='' | ||
else: | ||
dynamickeyword='dynamic' | ||
suffix='' | ||
|
||
# Run equilibration. | ||
if nequil > 0: | ||
write_key("%s-eq.key" % self.name, eq_opts, "%s.key" % self.name, md_defs) | ||
if verbose: printcool("Running equilibration dynamics", color=0) | ||
if self.pbc and pressure is not None: | ||
self.calltinker("dynamic %s -k %s-eq %i %f %f 4 %f %f" % (self.name, self.name, nequil, timestep, float(nsave*timestep)/1000, | ||
temperature, pressure), print_to_screen=verbose) | ||
self.calltinker(dynamickeyword+" %s -k %s-eq %i %f %f 4 %f %f%s" % (self.name, self.name, nequil, timestep, float(nsave*timestep)/1000,temperature, pressure,suffix), print_to_screen=verbose) | ||
else: | ||
self.calltinker("dynamic %s -k %s-eq %i %f %f 2 %f" % (self.name, self.name, nequil, timestep, float(nsave*timestep)/1000, | ||
temperature), print_to_screen=verbose) | ||
self.calltinker(dynamickeyword+" %s -k %s-eq %i %f %f 2 %f" % (self.name, self.name, nequil, timestep, float(nsave*timestep)/1000,temperature), print_to_screen=verbose) | ||
os.system("rm -f %s.arc" % (self.name)) | ||
|
||
# Run production. | ||
if verbose: printcool("Running production dynamics", color=0) | ||
write_key("%s-md.key" % self.name, md_opts, "%s.key" % self.name, md_defs) | ||
|
||
if self.pbc and pressure is not None: | ||
odyn = self.calltinker("dynamic %s -k %s-md %i %f %f 4 %f %f" % (self.name, self.name, nsteps, timestep, float(nsave*timestep/1000), | ||
temperature, pressure), print_to_screen=verbose) | ||
odyn = self.calltinker(dynamickeyword+" %s -k %s-md %i %f %f 4 %f %f%s" % (self.name, self.name, nsteps, timestep, float(nsave*timestep/1000),temperature, pressure,suffix), print_to_screen=verbose) | ||
else: | ||
odyn = self.calltinker("dynamic %s -k %s-md %i %f %f 2 %f" % (self.name, self.name, nsteps, timestep, float(nsave*timestep/1000), | ||
odyn = self.calltinker(dynamickeyword+" %s -k %s-md %i %f %f 2 %f" % (self.name, self.name, nsteps, timestep, float(nsave*timestep/1000), | ||
temperature), print_to_screen=verbose) | ||
|
||
# Gather information. | ||
|
@@ -977,25 +1025,39 @@ def molecular_dynamics(self, nsteps, timestep, temperature=None, pressure=None, | |
edyn.append(float(s[2])) | ||
if 'Current Kinetic' in line: | ||
kdyn.append(float(s[2])) | ||
if len(s) > 0 and s[0] == 'Temperature' and s[2] == 'Kelvin': | ||
temps.append(float(s[1])) | ||
temps.append(temperature) # GPU version does not print out Temperature (or just new dynamic doesnt) | ||
|
||
# Potential and kinetic energies converted to kJ/mol. | ||
edyn = np.array(edyn) * 4.184 | ||
kdyn = np.array(kdyn) * 4.184 | ||
temps = np.array(temps) | ||
|
||
mass = 0.0 | ||
if verbose: logger.info("Post-processing to get the dipole moments\n") | ||
oanl = self.calltinker("analyze %s-md.arc" % self.name, stdin="G,E,M", print_to_screen=False) | ||
oanl = self.calltinker("analyze %s " % self.name, stdin="G,E,M", print_to_screen=False) | ||
for ln, line in enumerate(oanl): | ||
if 'Polarization' in line: | ||
if 'MUTUAL' in line or 'THOLE' in line: | ||
continue | ||
|
||
strip = line.strip() | ||
s = line.split() | ||
if 'Total System Mass' in line: | ||
mass = float(s[-1]) | ||
|
||
oanl = self.calltinker("analyze %s-md.arc" % self.name, stdin="E,M", print_to_screen=False) | ||
|
||
# Read potential energy and dipole from file. | ||
eanl = [] | ||
dip = [] | ||
mass = 0.0 | ||
ecomp = OrderedDict() | ||
havekeys = set() | ||
first_shot = True | ||
for ln, line in enumerate(oanl): | ||
if 'Polarization' in line: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you please comment on why you want to skip parsing these lines out of analyze? |
||
if 'MUTUAL' in line or 'THOLE' in line: | ||
continue | ||
|
||
strip = line.strip() | ||
s = line.split() | ||
if 'Total System Mass' in line: | ||
|
@@ -1007,10 +1069,13 @@ def molecular_dynamics(self, nsteps, timestep, temperature=None, pressure=None, | |
if first_shot: | ||
for key in eckeys: | ||
if strip.startswith(key): | ||
|
||
|
||
value=float(s[-2])*4.184 | ||
if key in ecomp: | ||
ecomp[key].append(float(s[-2])*4.184) | ||
ecomp[key].append(value) | ||
else: | ||
ecomp[key] = [float(s[-2])*4.184] | ||
ecomp[key] = [value] | ||
if key in havekeys: | ||
first_shot = False | ||
havekeys.add(key) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you comment on this? Is "dynamic" supposed to be an environment variable too?