Skip to content
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

Added custom box passing when saving #330

Merged
merged 14 commits into from
Mar 23, 2017
Merged

Conversation

justinGilmer
Copy link
Contributor

Modified to_parmed() function to accept custom box sizes.

Modified saver() to accept custom box sizes

Modified test_compound to accept custom boxes.

I need to add more tests to ensure that the data is properly saved and converted to Angstroms.

Made box a required argument for to_parmed().

Modified `to_parmed()` function to accept custom box sizes.

Modified `saver()` to accept custom box sizes

Modified test_compound to accept custom boxes.
@ctk3b
Copy link
Member

ctk3b commented Mar 10, 2017

Looks good, thanks! Will merge once you've got some appropriate unit tests in there to make sure the info makes it all the way through to parmed and the saved files.

Ran into a few limitations when trying to save/load for my unit tests.

1. Cannot load `.lammps` data files.
	- Seems not an issue, contains a lot of information not really needed
2. HOOMDXML unit conversion on loading
	- Writing out `.hoomdxml` files converts box parameters to Angstroms
	- when loading back in, units stay in Angstroms
	- Unsure how to correct, since we are delegating the loading to mdtraj
2.1 HOOMDXML box custom issues
	- possibly incorrectly moving to origin?
	- just a padded box has correct lengths, but angstroms
	- custom box has wildly incorrect lengths
		- unsure what is causing it
		- custom box parameters are affecting bounding box upon loading
			- still a mystery at the moment
3. Hard to test every file that parmed and mbuild can save to
	- Not every file type we write out can be loaded back in: (`.lammps`, `.gsd`, etc.)
	- Unsure how to check using tests within mBuild to ensure data we write out is correct
	- havent really tested using unit tests if the data we write out in the mBuild supported savers are correct (at least in the tests region).
4. Box seems pretty rudimentary
	- Possible issue to convert to a triclinic system?
	- lots of assumptions about the boxes in the savers (angles = 90, etc.)
	- might be a pretty hefty overhaul of the `Box` class
5. Units conversions everywhere
	- no real method to the madness in terms of when the units are converted from nm to Angstroms
	- Since `save()` is the way to output files, all unit conversions there?
	- Assuming using save is the only way to output files
		- would make sense to enforce this?

Things to Note
1. Lots of print statements in here now
	- Still very much a WIP
	- want to get some feedback and discussion
2. WIP
	- I have my tests failing on purpose at the moment to observe outputs.
3. For `parmed` supported structures and `mdtraj` supported loadable files
	- Seem to work properly
	- unsure even angstrom to nm conversion is correct?
	- maybe `.hoomdxml` just a fluke in the loading using `mdtraj`?
@justinGilmer
Copy link
Contributor Author

Since commit message is a bit hard to read, posting it here, since it will also be useful for the questions I have.

Ran into a few limitations when trying to save/load for my unit tests.

  1. Cannot load .lammps data files.

    • Seems not an issue, contains a lot of information not really needed
  2. HOOMDXML unit conversion on loading

    • Writing out .hoomdxml files converts box parameters to Angstroms
    • when loading back in, units stay in Angstroms
    • Unsure how to correct, since we are delegating the loading to mdtraj

2.1 HOOMDXML box custom issues
- possibly incorrectly moving to origin?
- just a padded box has correct lengths, but angstroms
- custom box has wildly incorrect lengths
- unsure what is causing it
- custom box parameters are affecting bounding box upon loading
- still a mystery at the moment

  1. Hard to test every file that parmed and mbuild can save to

    • Not every file type we write out can be loaded back in: (.lammps, .gsd, etc.)
    • Unsure how to check using tests within mBuild to ensure data we write out is correct
    • havent really tested using unit tests if the data we write out in the mBuild supported savers are correct (at least in the tests region).
  2. Box seems pretty rudimentary

    • Possible issue to convert to a triclinic system?
    • lots of assumptions about the boxes in the savers (angles = 90, etc.)
    • might be a pretty hefty overhaul of the Box class
  3. Units conversions everywhere

    • no real method to the madness in terms of when the units are converted from nm to Angstroms
    • Since save() is the way to output files, all unit conversions there?
    • Assuming using save is the only way to output files
      • would make sense to enforce this?

Things to Note

  1. Lots of print statements in here now

    • Still very much a WIP
    • want to get some feedback and discussion
  2. WIP

    • I have my tests failing on purpose at the moment to observe outputs.
  3. For parmed supported structures and mdtraj supported loadable files

    • Seem to work properly
    • unsure even angstrom to nm conversion is correct?
    • maybe .hoomdxml just a fluke in the loading using mdtraj?

Removed wrapping issue from hoomdxml.

Bounding box preserves proper length of box based on
particle positions.

Custom box support to allow smaller or larger boxes to write to data files.
Had extraneous arguments in the load function.

**kwargs handles this.
@ctk3b
Copy link
Member

ctk3b commented Mar 18, 2017

Can you resolve the merge conflicts here? Need to get this fix in sooner rather than later.

@ctk3b
Copy link
Member

ctk3b commented Mar 22, 2017

@justinGilmer will you have time to fix this up today?

Error where box was not being properly set, causing DIV0 errors.

Maxs and mins of `Box` class was not being set correctly, not updating lengths,
which was essential for `to_parmed()` to function properly.
@justinGilmer
Copy link
Contributor Author

I think all the issues have been ironed out. Just waiting for the CI's to finish.

@@ -1304,16 +1304,18 @@ def save(self, filename, show_ports=False, forcefield_name=None,
# pad non periodic faces with .25nm buffers
if box is None:
box = self.boundingbox
box_vec_max = box.maxs.tolist()
box_vec_min = box.maxs.tolist()
Copy link
Member

@ctk3b ctk3b Mar 22, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should definitely be box.mins but could you explain why the list cast is necessary here?

Copy link
Contributor Author

@justinGilmer justinGilmer Mar 22, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue was when we were just changing these values, the setter was not being called it seemed. box.lengths was not being updated. At least with the 2 single residue test case. The best way I could see would be to just unwrap that numpy array and perform the operations on it. Then pass it back as one numpy array which seemed to update box.lengths as well.

EDIT:
TLDR, it seemed that changing in place the numpy array values would not force the box setter to update the lengths. By converting to a list so it could be operated on and then passing that back in as a numpy array, that seemed to alleviate this issue.

Copy link
Contributor Author

@justinGilmer justinGilmer Mar 22, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it was just that the residue case was very different. It had no bounding box essentially. It was a [0,0,0] box. Which seemed to affect the setters.

EDIT:
I see what you mean about the two max calls. Fixing now.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah that makes sense. The setters don't work for elements of the array getting changed. Probably not worth tackling until the box rewrite.

box mins list was assigned the maxs of the box.
Copy link
Member

@ctk3b ctk3b left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, thanks! Just some final tidying up and it's good to go.

for attr in box_attributes:
pad_attr = getattr(padded_ch3.boundingbox, attr)
custom_attr = getattr(custom_ch3.boundingbox, attr)
assert(np.array_equal(pad_attr, custom_attr))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assert is a statement so parentheses should be removed.

**kwargs : keyword arguments
Arbitrary keyword arguments.

Args:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These args belong in the save function where I believe they already are.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, load is it's own separate function, outside of Compound. Since save and its **kwargs are passed to other savers and such, would it be reasonable to have both defined?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you asking if both *args and **kwargs should be defined here? *args gets a bit tricky because it cares about order. **kwargs could have a bit more description like "arguments passed down to mdtraj".

That being said, my original comment was about the content of the Args: section that I tagged. ref_distance/mass/energy are not arguments relevant to any of the loaders. They only apply to the hoomd saver so they shouldnt be in the docstring for the load function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah gotcha, that makes sense. And youre correct, I was recalling the source code for mdTraj incorrectly. Just looked it up and I understand it now.

@@ -393,10 +407,10 @@ def test_intermol_conversion2(self, ethane, h2o):
def test_parmed_conversion(self, ethane, h2o):
compound = mb.Compound([ethane, h2o])

structure = compound.to_parmed()
structure = compound.to_parmed(box=compound.boundingbox)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default right now will be the boundingbox plus a buffer is nothing specified, correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is if they call save(). If they just call to_parmed, that is not currently happening.

Unsure how we would want to handle this actually. Since we were wanting the padding to be handled by the saver. I guess I could check if the box passed in is None, if so, pad and move on. That would handle use cases when just calling this function. Since save() does the padding before passing that box to to_parmed()

Incorrect description of arguments that could be passed to load function.
@ctk3b
Copy link
Member

ctk3b commented Mar 23, 2017

Almost done! Just gotta remove the parentheses around that assert statement.

to_parmed now supports generation of padded boxes without calling save().

Can also pass in custom box as well.

If no box passed in, will default to a .25nm buffer on all sides of box.
box_vec_max[dim] += 0.25
box_vec_min[dim] -= 0.25
box.mins = np.asarray(box_vec_min)
box.maxs = np.asarray(box_vec_max)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is duplicated now. I think you can re-organize this so it only exists in to_parmed

1. Modified to_parmed() to handle the box padding.

2. save() no longer handles box padding

3. Modified the 3 mbuild data file writers (hoomd, lammps, gsd)
	to also use the parmed structure for box information.
Changed mBuild file writers to instantiate the box in 1 line.
forcefield = True
if structure[0].type == '':
forcefield = False
xyz = np.array([[atom.xx, atom.xy, atom.xz] for atom in structure.atoms])

box.lengths = np.array([structure.box[0], structure.box[1], structure.box[2]])
box.maxs *= 10.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean to delete this?

Deleted angstroms conversion of the box maxs member.
Looped over 3 dimensions instead of enumerating the periodicity.
@ctk3b ctk3b merged commit 5012262 into mosdef-hub:master Mar 23, 2017
@justinGilmer justinGilmer deleted the boxSaver branch May 18, 2017 16:05
@summeraz summeraz mentioned this pull request Aug 21, 2018
umesh-timalsina referenced this pull request in GOMC-WSU/MoSDeF-GOMC Mar 22, 2022
Added custom box passing when saving
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants