Open xiaowei-xie2 opened 2 months ago
Is this specific to TorchForce? What if you change
force = TorchForce('model.pt')
to
force = CustomBondForce('r')
leaving everything else the same, including the calls to addGlobalParameter()
? Do you get the same error? If so, the problem isn't related to TorchForce, and you should probably ask at https://github.com/choderalab/openmmtools. On the other hand, if that works and the problem really is related to TorchForce, can you post a complete example with all the files needed to reproduce it?
Thank you for the reply! I went ahead and tried your suggestion and it seems the problem is specific to TorchForce. I created a simple example to reproduce this behavior below. Also I think I might have found a workaround (inspired by the openmmml package) by adding the following lines.
cv = openmm.CustomCVForce("")
cv.addGlobalParameter("param_a", 1)
cv.addGlobalParameter("param_b", 1)
tempSystem = openmm.System()
tempSystem.addForce(force)
interactingVarNames = []
for idx, force in enumerate(tempSystem.getForces()):
name = f"allForce{idx+1}"
cv.addCollectiveVariable(name, copy.deepcopy(force))
interactingVarNames.append(name)
assert len(interactingVarNames) > 0
interactingSum = "+".join(interactingVarNames)
cv.setEnergyFunction(
f"({interactingSum})"
)
system.addForce(cv)
In this openmm_files.tar.gz
I have 3 files mmforce.py
, torchforce.py
and torchforce_workaround.py
and their corresponding outputs. You can see that only the force object is changed between the files.
Please let me know if my workaround is correct?
@mikemhenry @ijpulidos can you take a look at this? This error is happening because of an interaction between SWIG and openmmtools.
_get_system_controlled_parameters()
tries to find the list of global parameters by looping over all forces and looking for methods called getNumGlobalParameters()
and getGlobalParameterName()
.
for force_index in range(system.getNumForces()):
force = system.getForce(force_index)
try:
n_global_parameters = force.getNumGlobalParameters()
except AttributeError:
continue
for parameter_id in range(n_global_parameters):
parameter_name = force.getGlobalParameterName(parameter_id)
if parameter_name in searched_parameters:
yield force, parameter_name, parameter_id
The problem is that SWIG can only return the correct Python Force subclass from getForce()
for built in classes. If the force was defined by a plugin, it just returns an instance of the abstract Force class. That's just referring to the Python wrapper, of course. The C++ object it wraps has the correct class. The TorchForce Python wrapper provides static isinstance()
and cast()
methods for checking whether something is a wrapped TorchForce and casting it to the correct Python class.
The robust way of getting a list of all global parameters is to call getParameters()
on a Context.
Hi,
I would like to do a Hamiltonian REMD with custom defined states, with each state specified by a torchForce object with a different global parameter. But I am having trouble creating a CompoundThermodynamicState to be used with ReplicaExchangeSampler. I can create a GlobalParameterState, but when I use that to create CompoundThermodynamicState, it complains there is no global parameter in the system. I have no trouble doing the same thing with a MM force field. Any idea what might be going wrong?
Thank you!
Here is the structure of the code I was using:
And I am getting the following error: