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
[File format] Moltemplate export capability #35
Comments
Coupling with moltemplateIf you check out the latest commits on testing, you'll see that a python terminal is now available in the GUI, which is enabled as soon as both the PYTHON and DESKTOP variables are enabled in cmake. I'll happily include moltemplate in future builds. I had a look at your dependencies, but couldn't find anything besides the python standard library, is this correct? Implementation-wise, i would include your repository as a git submodule as i have done for my other dependencies, this way it's easy to stay up to date with upstream. File supportThere are a few things to consider with file-support. Also, there needs to be a way to read in |
Yes! Moltemplate currently has no external dependencies. In the future, some optional features of moltemplate might depend on numpy, but I'll make sure that moltemplate can be installed without numpy (and ltemplify.py will never depend on numpy). (Actually, I just discovered that one of the executable scripts that is bundled with moltemplate, interpolate_mt.py, already depends on numpy, but this script is not included when you run "import moltemplate" in python. That script is a stand-alone executable script which is run from the terminal. It is not needed by ltemplify.py or any other python file in moltemplate. I would not worry that it depends on numpy. I don't think anybody besides myself has ever used it.)
Sounds great to me.
I'm working on changing ltemplify.py and moltemplate/init.py in order to make it possible to load ltemplify as a module from within python. (Currently "import moltemplate" works, but "ltemplify" is not visible. I'm working on this now.)
Are you thinking about including moltemplate import capability to VIPSTER? That would be cool. I wish I had thought about that. Importing moltemplate filesTo import data from moltemplate files, I the easiest way would be to ask moltemplate to generate a LAMMPS data file that VIPSTER can read. Moltemplate generate DATA files already include comments in the "Masses" section that contain the atom type strings. (If you like, I can also add comments following the "N bond types", "N angle types", "N dihedral types", and "N improper types" containing the type strings for these objects as well. We can worry about that later.) ** Does that sound reasonable? ** Current plansFor now, I will just focus on export capability. In the next day or two, I will figure out how to interact with moltemplate by accessing the main() functions for the various stand-alone executable scripts (like ltemplify.py) This will enable you to run ltemplify.py from within python without interacting with the shell. You just have to supply main with an argv argument (a python list) containing a single string which is the name of the DATA file VIPSTER has created:
(where LAMMPS_DATA_FILE is the name of the file created by VIPSTER) Does this sound reasonable to you? (If you really want to avoid using the file-system entirely, perhaps we can consider allowing non-string entries in the argv list and use StringIO perhaps. But I wasn't planning to do this unless you want me to. I'm open to other ideas too.) Details (long, feel free to skip)I hate to admit this embarrassing fact, but moltemplate was never intended be run from within python. This was an oversight on my part, because moltemplate (ttree.py) is nearly my first python program. I only intended it to be used from the command line to generate files for LAMMPS to read. I did this because, (as far as I know) the LAMMPS MD program has no way to interact with python other than by reading DATA files. Unlike hoomd-blu or OpenMM, a python user within LAMMPS cannot send the atom coordinates, topology information, and force field parameters to LAMMPS directly from within its python environment, without writing this to a data file (and using the LAMMPS' "read_data" command). That's also why part of moltemplate was writtin in BASH. To really make moltemplate python scriptable would require rewriting significant portions of it. Actually, this is something I am thinking of doing some time next year, because we also need this. (This may also augment the moltemplate syntax.) But this is not yet a high priority for us now. Making system calls in windowsIt's true. In linux you can either run "ltemplify.py LAMMPS_FILE.data > MOLTEMPLATE_FILE" in the terminal, or use os.system() or the subprocess() module. The tricky part is to handle the ">" stdout redirection to a file. Although this is irrelevant to us, for my own records, the way you would do this in python is:
...but, as you say, this will not work in a windows environment unless the user has already installed python. In the process of writing this reply, I realized how unreasonable it would be to make this a requirement. (I thought windows 10 now includes python by default, but I was wrong.) To get around this, we should load moltemplate.ltemplify as a module, which is what you suggested. I'm working on making all of the scripts in moltemplate available as modules. This might take a day, as I am inexperienced with python packaging. |
Don't limit yourself too much :) It would be useful to ship a useful scientific base-system anyways, Numpy would be the first candidate for this.
This sounds easiest, yes. I'm not sure if this can reasonably integrated with vipster, if the preparation process is taking for too long (going from the hours you mention for your vesicle example) that's quite unreasonable for simply "loading a file". Maybe this is better left for the user to execute explicitely? I'll have to learn more about them, maybe i get an idea how to reasonably treat a subset of your language.
That sounds great!
I'd really prefer avoiding the filesystem, yes. IIRC, StringIO can be used as a drop-in replacement for file objects in python, so hopefully the only change necessary is to encapsulate the parts of the current
JFYI, since some time ago there's the PyLammps interface. It exposes much of lammps in a pythonic way. |
Hi Sebastian To invoke ltemplify.py from within python use:
(I tested this recently, but please let me know if any of this fails to work.) Incidentally, I finally converted the There are also some examples. (Keep in mind that most of the examples use the "-mol" or "-id" arguments, this is because I was assuming that ltemplify.py users are extracting the molecule from a big LAMMPS data file that contains many molecules. In that case they need to specify which atoms we want in the final output file. I assume VIPSTER users would be drawing only one molecule, so we don't have to bother with this.) |
My apologies. Oh dear. I just noticed this. Unfortunately, in my previous post, I suggested writing the VIPSTER output to a DATA file, and then invoking ltemplify.Ltemplify.init() with an argument list which includes the name of this data file. However if you like, I can generalize it so that it can accept arguments that are file streams instead of file names. Would that be helpful? Something like this perhaps?
Or do you have a different way of doing this in mind? |
Yes, that would be exactly it! Regarding properties, what would you suggest to export? |
where NEW_FILE and DATA_FILE can either be a string (filename) or a file object (eg io.StringIO), and DATA_FILE contains the contents of the file created by VIPSTER.
Moltemplate is sort of like a (dumb) object-oriented programming language for building simulations.
and use a command like this:
...to make 40 copies of the "Styrene" monomer. They can then link them together with bonds to create a polystyrene polymer (from within moltemplate). In summary, in this example, "styrene.lt" is the file defining the object, and "Styrene" is the MOLECULE_NAME, which is the way moltemplate users will refer to this object inside their code (when using moltemplate later). I realize this example is confusing in because the MOLECULE_NAME is actually the name of a monomer ("Styrene"), not the molecule (polystyrene). The MOLECULE_NAME is the name of the object that moltemplate users will refer to later. (Again, alternatively users could build the entire polymer in VIPSTER, and save the entire thing as a moltemplate-object. That is fine too. We can give users the freedom they want.)
Just as you currently do with LAMMPS DATA files, leave it up to the user. Both kinds of molcules are allowed in moltemplate. Sometimes the user will want to include this information, and sometimes they won't. (See discussion below.) Details (TL;DR Feel free to skip)Molecule-Objects in moltemplate may or may not include force field information. a) Here's an example of a molecule-object which does include angle topology and force-field information (including force-field styles and force-field parameters) b) And here's an example which uses an external 3rd-party force-field (OPLSAA) instead. In this example, the user only needs to specify the atom coordinates, types, charges, and a list of pairs of bonds. They can leave out the angles, dihedrals, impropers and force-field parameters. Consequently, the definition of the "Ethylene" molecule below is much more compact:
Great questions! I propose that users should be free to select the atom_style they want, just as they normally do when saving LAMMPS data files. If that atom_style supports charge, then you can add a column to the data file for charges (and leave it 0.0 by default). (For moltemplate users, at least, however, I think the default atom_style should be "full". I think it is currently "atom" by default.) Similarly users can select whether or not they want to include angles, dihedrals, and impropers in the moltemplate file VIPSTER creates (just as they can select whether or not to include this information in the DATA file). Let users choose whether or not they want to include this information in their files. This way the burden of choice is on them, not you. Future features:DON'T WORRY ABOUT THIS NOW. WE CAN WORRY ABOUT THIS LATER!In addition to letting the user choose the atom style, and whether to include angles, dihedrals, or impropers, it would be nice if users could :
Implementation: If the user types any text into this box, then append the following string to the end of the MOLECULE_NAME variable:
Implementation If the user clicks on this box, then add '-ignore-bond-types' to the list of args, which will tell ltemplify.py to use a different type of Bonds list which omits bond types.
(Why? Bond types are typically determined by the force-field, so theirs no need to specify these types. Adding '-ignore-bond-types' to the list of argunents will tell ltemplify.py and moltemplate to choose their own bond types when creating the final DATA file which LAMMPS will read, according to the force-field rules. I would not have this box checked by default, unless the user has typed a non-empty string into the FORCE_FIELD_NAME text-box.) My apologies for writing such long, tedious replies. Thank you for reading them. |
I think I have all of this working now in version 2.12.4 (Uploaded a few minutes ago.) Note: Since I posted my comment 24 hours ago, I made some small changes to the Ltemplify API.
(where NEW_FILE and DATA_FILE can be file names or StringIO objects) Let me know if there is anything else you need. (Don't worry about the "Future Features" I mentioned above. Let's see if we can just get basic moltemplate file export working using the commands above.) |
Thanks for your work. I'm busy this week, so I won't be able to implement it for now, but it looks good so far. |
Hi Sebastian. I was re-reading this conversation, and I found it long and confusing. In your case, you can probably just use simple arguments, like: '-name', 'Ethylene'. (Somebody else wanted to write a program that would export moltemplate files, so this pushed me to finally cleaned up the documentation.) Thank you very much again for your recent bug fix. |
Hi Andrew, sorry for letting this issue sit dormant for so long. The good news: An example implementation of a moltemplate plugin may look like this (saved as `~/.config/vipster/plugins/moltemplate.py): from moltemplate.ltemplify import Ltemplify
import vipster as vp
from io import StringIO
name = "moltemplate" # display-name
extension = "lt" # default extension
command = "mol" # to specify plugin explicitely on CLI or in python
# parameters may hold the coeffs
# dict-value must be a 2-tuple with a `str`/`[str]`/`{str:str}` as the real value
# and a `str` as documentation
parameters = {"test_str": ("default_str", "doc_str"),
"test_vec": (["v1", 'v2', 3], "doc_vec"),
"test_map": ({'a': 5, 'b': 'c'}, "doc_map")
}
# preset may control output, i.e. toggle bond inclusion
# dict-value must be a 2-tuple with a `bool` or a named-enum-shim as the real value
# (int as default value, tuple of strings to give allowed values with their names)
# and a `str` as documentation
preset = {"test_bool": (True, "doc_bool"),
"test_enum": ((0, ('a', 'b', 'c')), 'doc_enum')
}
def writer(mol, p, c, idx):
# enforce fitting preset for lmp-Plugin intermediate
lmp_preset = vp.Presets[vp.Plugins.lmp]['default']
lmp_preset['style'] = "full"
# TODO: fill from own preset
lmp_preset['bonds'] = False
lmp_preset['angles'] = False
lmp_preset['dihedrals'] = False
lmp_preset['impropers'] = False
lmp_preset['coeff'] = True
# setup parameters
lmp_param = vp.Parameters[vp.Plugins.lmp]['default']
# TODO: fill from own parameters
lmp_param['Pair Coeff']['C'] = 'Null'
# write lmp datafile
tmp = vp.writeString(vp.Plugins.lmp, mol, param=lmp_param,
config=lmp_preset, index=idx)
tmp = StringIO(tmp)
# convert intermediate via ltemplify
res = StringIO()
ltemp = Ltemplify([])
ltemp.Convert(out_file=res, input_data_file=tmp)
res.seek(0)
return res.read() Please note the param/preset sections that need to be designed still, The bad news is that I'm still unsure on how to include this. |
I had forgotten that VIPSTER can also generate angle, dihedral, and improper interactions, as well as Lennard-Jones parameters for the atomic elements. (Moltemplate users have other ways of generating that information automatically, but I like that they can specify it manually in VIPSTER as well.) Anyway, thank you for remembering this feature Sebastian. For what it's worth, I spent a few minutes discussing VIPSTER when I gave a workshop on moltemplate last year at the LAMMPS conference. Even if your software still has bugs or issues, I think you should apply to go to the next conference in 2021. I remember two talks that presented in previous conferences (in 2013 and 2017 on "fix bond/react" and "Molecular Dynamics Studio") that described software whose development was still in progress. |
Regarding dependencies: I don't know if this helps, but moltemplate is maintained on pypi. That means that "pip install moltemplate" works reliably now. If this were a pure python project, you could include the 'moltemplate' dependency in the "install_requires" section of your "setup.py" file:
... I think this means that this would install moltemplate any time people use pip to install your software. However, vipster cannot be installed using "pip", so I suppose this suggestion is not very helpful. But perhaps there is a way to put "pip install moltemplate" in your cmake files? (I haven't learned how to use cmake yet.) Suggestion: Enclose the import Ltemplify command in a try block:
This way VIPSTER will exit gracefully if people did not install moltemplate correctly. I don't feel like it should be your responsibility to install moltemplate on their computers. Cheers |
It would be great to get your opinion on the parameter and io-preset templates.
See above, this is imho the most urgent part of the IO-preset/Plugin design.
Sorry for the confusion, i was being imprecise in my last comment. The current plan on including moltemplate:
|
Hi Sebastian. -Andrew |
Hi Sebastian
I'm sorry. I realize there was no way for you to proceed until I provided you more information how to handle molecules that use force-fields. So I have listed all of the possible ways that VIPSTER users may want to export to moltemplate, along with the corresponding python code below. Currently, the Ltemplify constructor currently accepts a list of string arguments that control its behavior. (Instead of a dictionary of name:value pairs.) These strings are the same command-line arguments which are normally passed to the "ltemplify.py" program when invoked from the shell. (I was lazy.) Currently, you will have to convert the information in the preset and parameters variables into this format. (...a list of strings. If you don't like the API I am using for the Ltemplify constructor, I am open to suggestions.) I will now tell you exactly what this list of strings should be for each of the force-fields that moltemplate supports:
ltemp = Ltemplify(args=['-atomstyle', atom_style, '-name', name]) where ltemp = Ltemplify(args=['-atomstyle', atom_style,
'-name', name+' inherits COMPASS',
'-preamble', 'import "compass_published.lt"',
'-ignore-angles', '-ignore-bond-types', '-ignore-masses', '-ignore-coeffs'])
ltemp = Ltemplify(args=['-atomstyle', atom_style,
'-name', name+' inherits OPLSAA',
'-preamble', 'import "oplsaa.lt"',
'-ignore-angles', '-ignore-bond-types', '-ignore-masses', '-ignore-coeffs'])
ltemp = Ltemplify(args=['-atomstyle', atom_style,
'-name', name+' inherits OPLSAA',
'-preamble', 'import "oplsaa.lt"',
'-preamble', 'import "loplsaa.lt"',
'-ignore-angles', '-ignore-bond-types', '-ignore-masses', '-ignore-coeffs'])
ltemp = Ltemplify(args=['-atomstyle', atom_style,
'-name', name+' inherits GAFF',
'-preamble', 'import "gaff.lt"',
'-ignore-angles', '-ignore-bond-types', '-ignore-masses', '-ignore-coeffs'])
ltemp = Ltemplify(args=['-atomstyle', atom_style,
'-name', name+' inherits GAFF2',
'-preamble', 'import "gaff2.lt"',
'-ignore-angles', '-ignore-bond-types', '-ignore-masses', '-ignore-coeffs'])
ltemp = Ltemplify(args=['-atomstyle', atom_style,
'-name', name+' inherits TraPPE',
'-preamble', 'import "trappe1998.lt"',
'-ignore-angles', '-ignore-bond-types', '-ignore-masses', '-ignore-coeffs']) Other force fields might be added in the future, but if they are, I will issue a pull request. (Alternatively if you want to just let the user specify the correct arguments to Ltemplify manually, I suppose that's okay with me also. If you are curious, there are several other ltemplify.py arguments which are explained here, but I don't think you need to worry about them.) I don't know how you want to encode this information in the preset and parameters variables for the moltemplate plugin. Again, if you don't like the API for the Ltemplify constructor, I am open to suggestions how to make it better.
Sounds good to me. Thanks for your patience for my slow replies. Andrew |
Commits 49d519a and 0cdaaa0 implement a writer and parser, respectively. The writer uses
Especially the last aspect is a bit hacky, and i'm not sure if this is production ready. |
Is your feature request related to a problem? Please describe.
Currently moltemplate users have to run ltemplify.py on the files created by VIPSTER, by typing this into the terminal/shell:
Describe the solution you'd like
Can we add a new entry ("Moltemplate LT") to the list of file formats that users can select from when saving (exporting) a molecule? It would behave identically to the "LAMMPS Data File" format, with the same list of options. However when VIPSTER saves the file, it runs the ltemplify.py script on this file to automatically convert the result into moltemplate format (using the syntax above).
This will either require users to have also installed moltemplate (since "ltemplify.py" is distributed with moltemplate), OR we could copy the current version of the "ltemplify.py" code into VIPSTER. (This would require adding "ltemplify.py", "ttree_lex.py", and "lttree_styles.py" to VIPSTER. This is 6785 lines of code, but this code is currently relatively stable. These files do not change very often these days.) I am happy either way.
Describe alternatives you've considered
Alternatively, you could instead add a new "IO-Config Preset" for the existing LAMMPS file format (instead of creating a new entry in the list of available file formats). That's okay too. However, if you do that, perhaps we could change the name of the entry from "LAMMPS Data File" to "LAMMPS File", or something vague like that (because moltemplate files have a different format from LAMMPS data files).
It's possible I may add one or two additional options that are specific to moltemplate (to allow the user to specify the force field they want, for example). But we can worry about this later.
Please let me if there is anything I can do to make this easier for you.
The text was updated successfully, but these errors were encountered: