From c43e28a5e5e609b415a826883a5c122f46e2fd75 Mon Sep 17 00:00:00 2001 From: Chris Date: Wed, 13 May 2020 18:55:46 -0600 Subject: [PATCH 01/19] added new function packmol_constrain to allow contraints about each axis individually --- mbuild/packing.py | 45 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/mbuild/packing.py b/mbuild/packing.py index 7c14be1b5..96f6ef277 100755 --- a/mbuild/packing.py +++ b/mbuild/packing.py @@ -44,16 +44,45 @@ end structure """ -PACKMOL_CONSTRAIN = """ -constrain_rotation x 0. 0. -constrain_rotation y 0. 0. -constrain_rotation z 0. 0. -""" +def packmol_constrain(fix_orientation): + + constraints = ['constrain_rotation x 0. 0.', + 'constrain_rotation y 0. 0.', + 'constrain_rotation z 0. 0.'] + + CONSTRAIN = """ + {} + {} + {} + """ + if not any(fix_orientation): # No directions fixed + return None + if all(fix_orientation): # All directions fixed + PACKMOL_CONSTRAIN = CONSTRAIN.format(constraints[0], constraints[1], constraints[2]) + elif fix_orientation.count(True) == 1: # Only 1 direction fixed + PACKMOL_CONSTRAIN = CONSTRAIN.format(constraints[fix_orientation.index(True)],"","") + else: # 2 directions are fixed + if fix_orientation[0] and fix_orientation[1]: # Only x and y are fixed + PACKMOL_CONSTRAIN = CONSTRAIN.format(constraints[0], constraints[1], "") + if fix_orientation[0] and fix_orientation[2]: # Only x and z are fixed + PACKMOL_CONSTRAIN = CONSTRAIN.format(constraints[0], "", constraints[2]) + if fix_orientation[1] and fix_orientation[2]: # Only y and z are fixed + PACKMOL_CONSTRAIN = CONSTRAIN.format("", constraints[1], constraints[2]) + return PACKMOL_CONSTRAIN + +# Original value for PACKMOL_CONSTRAIN +#PACKMOL_CONSTRAIN = """ +#constrain_rotation x 0. 0. +#constrain_rotation y 0. 0. +#constrain_rotation z 0. 0. +#""" + + def fill_box(compound, n_compounds=None, box=None, density=None, overlap=0.2, seed=12345, edge=0.2, compound_ratio=None, - aspect_ratio=None, fix_orientation=False, temp_file=None, + aspect_ratio=None, fix_orientation=(False, False, False), temp_file=None, update_port_locations=False): """Fill a box with a `mbuild.compound` or `Compound`s using PACKMOL. @@ -120,6 +149,7 @@ def fill_box(compound, n_compounds=None, box=None, density=None, overlap=0.2, """ # check that the user has the PACKMOL binary on their PATH _check_packmol(PACKMOL) + print(fix_orientation) arg_count = 3 - [n_compounds, box, density].count(None) if arg_count != 2: @@ -205,11 +235,12 @@ def fill_box(compound, n_compounds=None, box=None, density=None, overlap=0.2, compound_xyz_list.append(compound_xyz) comp.save(compound_xyz.name, overwrite=True) + PACKMOL_CONSTRAIN = packmol_constrain(rotate) input_text += PACKMOL_BOX.format(compound_xyz.name, m_compounds, box_mins[0], box_mins[1], box_mins[2], box_maxs[0], box_maxs[1], box_maxs[2], - PACKMOL_CONSTRAIN if rotate else "") + PACKMOL_CONSTRAIN if PACKMOL_CONSTRAIN else "") _run_packmol(input_text, filled_xyz, temp_file) # Create the topology and update the coordinates. From 74fcdf8ef415c49b85860d018d798e1ec4bbbe1b Mon Sep 17 00:00:00 2001 From: Chris Date: Wed, 13 May 2020 20:03:24 -0600 Subject: [PATCH 02/19] added doc strings to packmol_constraints function --- mbuild/packing.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/mbuild/packing.py b/mbuild/packing.py index 96f6ef277..ec1711d28 100755 --- a/mbuild/packing.py +++ b/mbuild/packing.py @@ -45,6 +45,17 @@ """ def packmol_constrain(fix_orientation): + """ + Provides information to PACKMOL of which axes to constrain rotation about. + fix_orientation is generated within the `fill_box` function + + fix_orientation : tuple of booleans + + Returns + -------- + None if fix_orientation = (False, False, False) + str to be added to PACKMOL input text if fix_orientation contains True + """ constraints = ['constrain_rotation x 0. 0.', 'constrain_rotation y 0. 0.', @@ -65,20 +76,11 @@ def packmol_constrain(fix_orientation): if fix_orientation[0] and fix_orientation[1]: # Only x and y are fixed PACKMOL_CONSTRAIN = CONSTRAIN.format(constraints[0], constraints[1], "") if fix_orientation[0] and fix_orientation[2]: # Only x and z are fixed - PACKMOL_CONSTRAIN = CONSTRAIN.format(constraints[0], "", constraints[2]) + PACKMOL_CONSTRAIN = CONSTRAIN.format(constraints[0], constraints[2], "") if fix_orientation[1] and fix_orientation[2]: # Only y and z are fixed - PACKMOL_CONSTRAIN = CONSTRAIN.format("", constraints[1], constraints[2]) + PACKMOL_CONSTRAIN = CONSTRAIN.format(constraints[1], constraints[2], "") return PACKMOL_CONSTRAIN -# Original value for PACKMOL_CONSTRAIN -#PACKMOL_CONSTRAIN = """ -#constrain_rotation x 0. 0. -#constrain_rotation y 0. 0. -#constrain_rotation z 0. 0. -#""" - - - def fill_box(compound, n_compounds=None, box=None, density=None, overlap=0.2, seed=12345, edge=0.2, compound_ratio=None, @@ -149,8 +151,6 @@ def fill_box(compound, n_compounds=None, box=None, density=None, overlap=0.2, """ # check that the user has the PACKMOL binary on their PATH _check_packmol(PACKMOL) - print(fix_orientation) - arg_count = 3 - [n_compounds, box, density].count(None) if arg_count != 2: msg = ("Exactly 2 of `n_compounds`, `box`, and `density` " From 7ee47df8311102b22e3bbba388b03cf04c239fba Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 18 May 2020 10:51:38 -0600 Subject: [PATCH 03/19] updated the doc strings in the packmol_constrain function --- mbuild/packing.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/mbuild/packing.py b/mbuild/packing.py index ec1711d28..70589ead7 100755 --- a/mbuild/packing.py +++ b/mbuild/packing.py @@ -46,15 +46,18 @@ def packmol_constrain(fix_orientation): """ - Provides information to PACKMOL of which axes to constrain rotation about. + Provides information to PACKMOL about which axes to constrain rotation. fix_orientation is generated within the `fill_box` function - - fix_orientation : tuple of booleans - + Parameters + ---------- + fix_orientation : iterable of booleans, directions (x, y, z) about + which to constrain rotation. If True, no rotation + in that direction Returns - -------- + ------- None if fix_orientation = (False, False, False) - str to be added to PACKMOL input text if fix_orientation contains True + string + rotation constraints to be added to PACKMOL input text """ constraints = ['constrain_rotation x 0. 0.', From dc3d98316ef301aed37217496fbe0540e6dc81bc Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 26 May 2020 10:49:05 -0600 Subject: [PATCH 04/19] updated packmol_constraints using Justin's suggestion for string formatting; lowers the amount of if/else statements --- mbuild/packing.py | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/mbuild/packing.py b/mbuild/packing.py index 70589ead7..5ec752952 100755 --- a/mbuild/packing.py +++ b/mbuild/packing.py @@ -59,30 +59,23 @@ def packmol_constrain(fix_orientation): string rotation constraints to be added to PACKMOL input text """ - constraints = ['constrain_rotation x 0. 0.', 'constrain_rotation y 0. 0.', 'constrain_rotation z 0. 0.'] - CONSTRAIN = """ {} {} {} """ - if not any(fix_orientation): # No directions fixed + if not any(fix_orientation): return None - if all(fix_orientation): # All directions fixed - PACKMOL_CONSTRAIN = CONSTRAIN.format(constraints[0], constraints[1], constraints[2]) - elif fix_orientation.count(True) == 1: # Only 1 direction fixed - PACKMOL_CONSTRAIN = CONSTRAIN.format(constraints[fix_orientation.index(True)],"","") - else: # 2 directions are fixed - if fix_orientation[0] and fix_orientation[1]: # Only x and y are fixed - PACKMOL_CONSTRAIN = CONSTRAIN.format(constraints[0], constraints[1], "") - if fix_orientation[0] and fix_orientation[2]: # Only x and z are fixed - PACKMOL_CONSTRAIN = CONSTRAIN.format(constraints[0], constraints[2], "") - if fix_orientation[1] and fix_orientation[2]: # Only y and z are fixed - PACKMOL_CONSTRAIN = CONSTRAIN.format(constraints[1], constraints[2], "") - return PACKMOL_CONSTRAIN + final_constraints = list() + for i, val in enumerate(fix_orientation): + if val: + final_constraints.append(constraints[i]) + else: + final_constraints.append("") + return CONSTRAIN.format(*final_constraints) def fill_box(compound, n_compounds=None, box=None, density=None, overlap=0.2, @@ -138,9 +131,10 @@ def fill_box(compound, n_compounds=None, box=None, density=None, overlap=0.2, aspect_ratio : list of float If a non-cubic box is desired, the ratio of box lengths in the x, y, and z directions. - fix_orientation : bool or list of bools + fix_orientation : iterable of booleans or list of iterables Specify that compounds should not be rotated when filling the box, - default=False. + Rotation contraints are specified for each individual axis (x, y, z) + default=(False, False, False) temp_file : str, default=None File name to write PACKMOL's raw output to. update_port_locations : bool, default=False @@ -168,7 +162,6 @@ def fill_box(compound, n_compounds=None, box=None, density=None, overlap=0.2, n_compounds = [n_compounds] if not isinstance(fix_orientation, (list, set)): fix_orientation = [fix_orientation]*len(compound) - if compound is not None and n_compounds is not None: if len(compound) != len(n_compounds): msg = ("`compound` and `n_compounds` must be of equal length.") From 7f068d86489d134c8ac499e9e8cd1443543e594b Mon Sep 17 00:00:00 2001 From: chrisjones4 Date: Tue, 26 May 2020 11:35:52 -0600 Subject: [PATCH 05/19] added warning message and behavior to handle non-iterable fix_orientation value --- mbuild/packing.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/mbuild/packing.py b/mbuild/packing.py index 5ec752952..375a2793d 100755 --- a/mbuild/packing.py +++ b/mbuild/packing.py @@ -67,6 +67,12 @@ def packmol_constrain(fix_orientation): {} {} """ + # Handles instances that are not iterable; defaults to True/Fales for all axes + if fix_orientation == True: + fix_orientation=(True, True, True) + if fix_orientation == False: + fix_orientation=(False, False, False) + if not any(fix_orientation): return None final_constraints = list() @@ -160,8 +166,17 @@ def fill_box(compound, n_compounds=None, box=None, density=None, overlap=0.2, compound = [compound] if n_compounds is not None and not isinstance(n_compounds, (list, set)): n_compounds = [n_compounds] + if not isinstance(fix_orientation, (list, set)): fix_orientation = [fix_orientation]*len(compound) + try: + iter(fix_orientation[0]) + except: + warn('fix_orientation can be given as an iterable of True/False values + for each compound to fix rotations about each x,y,z axis individually. + Using a single instance of True/False defaults to (True,True,True) + and (Fale,False,False) respectively') + if compound is not None and n_compounds is not None: if len(compound) != len(n_compounds): msg = ("`compound` and `n_compounds` must be of equal length.") From 41669bce0b3877ec5a3956f331b1631602cf3d76 Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 26 May 2020 11:55:01 -0600 Subject: [PATCH 06/19] fixed quotations in warning message --- mbuild/packing.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mbuild/packing.py b/mbuild/packing.py index 375a2793d..5660ec2f4 100755 --- a/mbuild/packing.py +++ b/mbuild/packing.py @@ -172,10 +172,10 @@ def fill_box(compound, n_compounds=None, box=None, density=None, overlap=0.2, try: iter(fix_orientation[0]) except: - warn('fix_orientation can be given as an iterable of True/False values - for each compound to fix rotations about each x,y,z axis individually. - Using a single instance of True/False defaults to (True,True,True) - and (Fale,False,False) respectively') + warnings.warn("fix_orientation can be given as an iterable of True/False values " + "for each compound to fix rotations about each x,y,z axis individually. " + "Using a single instance of True/False defaults to (True,True,True) " + "and (Fale,False,False) respectively") if compound is not None and n_compounds is not None: if len(compound) != len(n_compounds): From 033b576a448bc575cebe59d8aab36b965b4190b3 Mon Sep 17 00:00:00 2001 From: Chris Date: Sun, 7 Jun 2020 18:14:27 -0600 Subject: [PATCH 07/19] added new unit test for new fix_orientation functionality --- mbuild/tests/test_packing.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/mbuild/tests/test_packing.py b/mbuild/tests/test_packing.py index 944872f5f..4b4d5e2fa 100755 --- a/mbuild/tests/test_packing.py +++ b/mbuild/tests/test_packing.py @@ -216,6 +216,16 @@ def test_no_rotate(self, h2o): w0 -= w0.sum(0) / len(w0) w1 -= w1.sum(0) / len(w1) assert np.isclose(w0, w1).all() is not True + + def specify_axis(self): + arguments = [(True, False, False), (False, True, True), + (False, True, False), (False, False, True)] + constraints = ["constrain_rotation x", + "constrain_rotation y" and "constrain_rotation z", + "constrain_rotation y", + "constrain_rotation z"] + for i, arg in enumerate(arguments): + assert constraints[i] in mb.packing.packmol_constrain(arg) def test_remove_port(self): from mbuild.lib.recipes import Alkane From 3ba2b8016b4040161b293cdf1f72dc1085cf4e5a Mon Sep 17 00:00:00 2001 From: Chris Date: Sun, 7 Jun 2020 20:16:00 -0600 Subject: [PATCH 08/19] fixed unit test for specify_axis; now tests for all 6 remaining possible fix_orientation inputs --- mbuild/tests/test_packing.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/mbuild/tests/test_packing.py b/mbuild/tests/test_packing.py index 4b4d5e2fa..6f2bc2dc1 100755 --- a/mbuild/tests/test_packing.py +++ b/mbuild/tests/test_packing.py @@ -218,14 +218,20 @@ def test_no_rotate(self, h2o): assert np.isclose(w0, w1).all() is not True def specify_axis(self): - arguments = [(True, False, False), (False, True, True), - (False, True, False), (False, False, True)] - constraints = ["constrain_rotation x", - "constrain_rotation y" and "constrain_rotation z", - "constrain_rotation y", - "constrain_rotation z"] + arguments = [(True, False, False), + (False, True, False), + (False, False, True), + (True, True, False), + (False, True, True), + (True, False, True)] + constraints = [["constrain_rotation x"], + ["constrain_rotation y"], + ["constrain_rotation z"], + ["constrain_rotation x", "constrain_rotation y"], + ["constrain_rotation y", "constrain_rotation z"], + ["constrain_rotation x", "constrain_rotation z"]] for i, arg in enumerate(arguments): - assert constraints[i] in mb.packing.packmol_constrain(arg) + assert all(c in mb.packing.packmol_constrain(arg) for c in constraints[i]) def test_remove_port(self): from mbuild.lib.recipes import Alkane From cf4ba73a8846caf5d305106a3652fd3caab096f4 Mon Sep 17 00:00:00 2001 From: Chris Date: Wed, 10 Jun 2020 12:37:25 -0600 Subject: [PATCH 09/19] fixes to unit test per notes from Ray --- mbuild/tests/test_packing.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/mbuild/tests/test_packing.py b/mbuild/tests/test_packing.py index 6f2bc2dc1..4ae381f2f 100755 --- a/mbuild/tests/test_packing.py +++ b/mbuild/tests/test_packing.py @@ -216,8 +216,23 @@ def test_no_rotate(self, h2o): w0 -= w0.sum(0) / len(w0) w1 -= w1.sum(0) / len(w1) assert np.isclose(w0, w1).all() is not True + + @pytest.mark.parametrize('orientations,constraints', + [((True, False, False),["constrain_rotation x"]), + ((False, True, False),["constrain_rotation y"]), + ((False, False, True),["constrain_rotation z"]), + ((True, True, False),["constrain_rotation x", + "constrain_rotation y"]), + ((False, True, True),["constrain_rotation y", + "constrain_rotation z"]), + ((True, False, True),["constrain_rotation x", + "constrain_rotation z"])]) + def test_specify_axis(self, orientations, constraints): + for i in constraints: + assert i in mb.packing.packmol_constrain(orientations) - def specify_axis(self): + @pytest.mark.parametrize + def test_specify_axis(self): arguments = [(True, False, False), (False, True, False), (False, False, True), From 561101021b2216b0ea32ec6f372256ea590cfbec Mon Sep 17 00:00:00 2001 From: Chris Date: Wed, 10 Jun 2020 12:38:29 -0600 Subject: [PATCH 10/19] removed my old specify_axis unit test --- mbuild/tests/test_packing.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/mbuild/tests/test_packing.py b/mbuild/tests/test_packing.py index 4ae381f2f..172d4ccd1 100755 --- a/mbuild/tests/test_packing.py +++ b/mbuild/tests/test_packing.py @@ -230,23 +230,6 @@ def test_no_rotate(self, h2o): def test_specify_axis(self, orientations, constraints): for i in constraints: assert i in mb.packing.packmol_constrain(orientations) - - @pytest.mark.parametrize - def test_specify_axis(self): - arguments = [(True, False, False), - (False, True, False), - (False, False, True), - (True, True, False), - (False, True, True), - (True, False, True)] - constraints = [["constrain_rotation x"], - ["constrain_rotation y"], - ["constrain_rotation z"], - ["constrain_rotation x", "constrain_rotation y"], - ["constrain_rotation y", "constrain_rotation z"], - ["constrain_rotation x", "constrain_rotation z"]] - for i, arg in enumerate(arguments): - assert all(c in mb.packing.packmol_constrain(arg) for c in constraints[i]) def test_remove_port(self): from mbuild.lib.recipes import Alkane From 3a394b0a0be3dce2c068d601bec4105dff19f740 Mon Sep 17 00:00:00 2001 From: Chris Date: Wed, 17 Jun 2020 09:49:15 -0600 Subject: [PATCH 11/19] added new packmol_constrain functionality to all packing functions --- mbuild/packing.py | 69 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 21 deletions(-) diff --git a/mbuild/packing.py b/mbuild/packing.py index 5660ec2f4..9247a5187 100755 --- a/mbuild/packing.py +++ b/mbuild/packing.py @@ -271,8 +271,8 @@ def fill_box(compound, n_compounds=None, box=None, density=None, overlap=0.2, def fill_region(compound, n_compounds, region, overlap=0.2, - seed=12345, edge=0.2, fix_orientation=False, temp_file=None, - update_port_locations=False): + seed=12345, edge=0.2, fix_orientation=(False,False,False), + temp_file=None, update_port_locations=False): """Fill a region of a box with `mbuild.Compound`(s) using PACKMOL. Parameters @@ -291,9 +291,10 @@ def fill_region(compound, n_compounds, region, overlap=0.2, Buffer at the edge of the region to not place molecules. This is necessary in some systems because PACKMOL does not account for periodic boundary conditions in its optimization. - fix_orientation : bool or list of bools + fix_orientation : iterable of booleans or list of iterables Specify that compounds should not be rotated when filling the box, - default=False. + Rotation contraints are specified for each individual axis (x, y, z) + default=(False, False, False) temp_file : str, default=None File name to write PACKMOL's raw output to. update_port_locations : bool, default=False @@ -318,7 +319,13 @@ def fill_region(compound, n_compounds, region, overlap=0.2, n_compounds = [n_compounds] if not isinstance(fix_orientation, (list, set)): fix_orientation = [fix_orientation]*len(compound) - + try: + iter(fix_orientation[0]) + except: + warnings.warn("fix_orientation can now be passed as a tuple or list with True/False " + "values specified for each x,y,z axis individually. " + "Using a single instance of True/False defaults to (True,True,True) " + "and (Fale,False,False) respectively") if compound is not None and n_compounds is not None: if len(compound) != len(n_compounds): msg = ("`compound` and `n_compounds` must be of equal length.") @@ -353,6 +360,7 @@ def fill_region(compound, n_compounds, region, overlap=0.2, compound_xyz_list.append(compound_xyz) comp.save(compound_xyz.name, overwrite=True) + PACKMOL_CONSTRAIN = packmol_constrain(rotate) reg_mins = reg.mins * 10 reg_maxs = reg.maxs * 10 reg_maxs -= edge * 10 # Apply edge buffer @@ -360,7 +368,7 @@ def fill_region(compound, n_compounds, region, overlap=0.2, reg_mins[0], reg_mins[1], reg_mins[2], reg_maxs[0], reg_maxs[1], reg_maxs[2], - PACKMOL_CONSTRAIN if rotate else "") + PACKMOL_CONSTRAIN if PACKMOL_CONSTRAIN else "") _run_packmol(input_text, filled_xyz, temp_file) @@ -379,7 +387,8 @@ def fill_region(compound, n_compounds, region, overlap=0.2, def fill_sphere(compound, sphere, n_compounds=None, density=None, overlap=0.2, seed=12345, edge=0.2, compound_ratio=None, - fix_orientation=False, temp_file=None, update_port_locations=False): + fix_orientation=(False,False,False), temp_file=None, + update_port_locations=False): """Fill a sphere with a compound using packmol. One argument of `n_compounds and density` must be specified. @@ -412,9 +421,10 @@ def fill_sphere(compound, sphere, n_compounds=None, density=None, overlap=0.2, Ratio of number of each compound to be put in sphere. Only used in the case of `density` having been specified, `n_compounds` not specified, and more than one `compound`. - fix_orientation : bool or list of bools - Specify that compounds should not be rotated when filling the sphere, - default=False. + fix_orientation : iterable of booleans or list of iterables + Specify that compounds should not be rotated when filling the box, + Rotation contraints are specified for each individual axis (x, y, z) + default=(False, False, False) temp_file : str, default=None File name to write PACKMOL's raw output to. update_port_locations : bool, default=False @@ -447,6 +457,13 @@ def fill_sphere(compound, sphere, n_compounds=None, density=None, overlap=0.2, n_compounds = [n_compounds] if not isinstance(fix_orientation, (list, set)): fix_orientation = [fix_orientation]*len(compound) + try: + iter(fix_orientation[0]) + except: + warnings.warn("fix_orientation can now be passed as a tuple or list with True/False " + "values specified for each x,y,z axis individually. " + "Using a single instance of True/False defaults to (True,True,True) " + "and (Fale,False,False) respectively") if compound is not None and n_compounds is not None: if len(compound) != len(n_compounds): @@ -508,15 +525,16 @@ def fill_sphere(compound, sphere, n_compounds=None, density=None, overlap=0.2, compound_xyz = _new_xyz_file() compound_xyz_list.append(compound_xyz) - + PACKMOL_CONSTRAIN = packmol_constrain(rotate) comp.save(compound_xyz.name, overwrite=True) + input_text += PACKMOL_SPHERE.format(compound_xyz.name, m_compounds, sphere[0], sphere[1], sphere[2], radius, - PACKMOL_CONSTRAIN if rotate else "") - print(input_text) + PACKMOL_CONSTRAIN if PACKMOL_CONSTRAIN else "") + _run_packmol(input_text, filled_xyz, temp_file) - + # Create the topology and update the coordinates. filled = Compound() filled = _create_topology(filled, compound, n_compounds) @@ -531,8 +549,8 @@ def fill_sphere(compound, sphere, n_compounds=None, density=None, overlap=0.2, def solvate(solute, solvent, n_solvent, box, overlap=0.2, - seed=12345, edge=0.2, fix_orientation=False, temp_file=None, - update_port_locations=False): + seed=12345, edge=0.2, fix_orientation=(False,False,False), + temp_file=None, update_port_locations=False): """Solvate a compound in a box of solvent using packmol. Parameters @@ -553,9 +571,10 @@ def solvate(solute, solvent, n_solvent, box, overlap=0.2, Buffer at the edge of the box to not place molecules. This is necessary in some systems because PACKMOL does not account for periodic boundary conditions in its optimization. - fix_orientation : bool - Specify if solvent should not be rotated when filling box, - default=False. + fix_orientation : iterable of booleans or list of iterables + Specify that compounds should not be rotated when filling the box, + Rotation contraints are specified for each individual axis (x, y, z) + default=(False, False, False) temp_file : str, default=None File name to write PACKMOL's raw output to. update_port_locations : bool, default=False @@ -577,6 +596,13 @@ def solvate(solute, solvent, n_solvent, box, overlap=0.2, n_solvent = [n_solvent] if not isinstance(fix_orientation, (list, set)): fix_orientation = [fix_orientation] * len(solvent) + try: + iter(fix_orientation[0]) + except: + warnings.warn("fix_orientation can now be passed as a tuple or list with True/False " + "values specified for each x,y,z axes individually. " + "Using a single instance of True/False defaults to (True,True,True) " + "and (Fale,False,False) respectively") if len(solvent) != len(n_solvent): msg = ("`n_solvent` and `n_solvent` must be of equal length.") @@ -607,13 +633,14 @@ def solvate(solute, solvent, n_solvent, box, overlap=0.2, solvent_xyz = _new_xyz_file() solvent_xyz_list.append(solvent_xyz) - + solv.save(solvent_xyz.name, overwrite=True) + PACKMOL_CONSTRAIN = packmol_constrain(rotate) input_text += PACKMOL_BOX.format(solvent_xyz.name, m_solvent, box_mins[0], box_mins[1], box_mins[2], box_maxs[0], box_maxs[1], box_maxs[2], - PACKMOL_CONSTRAIN if rotate else "") + PACKMOL_CONSTRAIN if PACKMOL_CONSTRAIN else "") _run_packmol(input_text, solvated_xyz, temp_file) # Create the topology and update the coordinates. From d5641a11dc81e0ae2600a947b3e24d9e33ef3dcd Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 18 Jun 2020 17:46:05 -0600 Subject: [PATCH 12/19] fixed inconsistencies in doc strings for fix_orientation --- mbuild/packing.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mbuild/packing.py b/mbuild/packing.py index 9247a5187..a431b5e48 100755 --- a/mbuild/packing.py +++ b/mbuild/packing.py @@ -138,7 +138,7 @@ def fill_box(compound, n_compounds=None, box=None, density=None, overlap=0.2, If a non-cubic box is desired, the ratio of box lengths in the x, y, and z directions. fix_orientation : iterable of booleans or list of iterables - Specify that compounds should not be rotated when filling the box, + If True, specifies that compounds should not be rotated when filling the box. Rotation contraints are specified for each individual axis (x, y, z) default=(False, False, False) temp_file : str, default=None @@ -292,7 +292,7 @@ def fill_region(compound, n_compounds, region, overlap=0.2, necessary in some systems because PACKMOL does not account for periodic boundary conditions in its optimization. fix_orientation : iterable of booleans or list of iterables - Specify that compounds should not be rotated when filling the box, + If True, specifies that compounds should not be rotated when filling the box. Rotation contraints are specified for each individual axis (x, y, z) default=(False, False, False) temp_file : str, default=None @@ -422,7 +422,7 @@ def fill_sphere(compound, sphere, n_compounds=None, density=None, overlap=0.2, case of `density` having been specified, `n_compounds` not specified, and more than one `compound`. fix_orientation : iterable of booleans or list of iterables - Specify that compounds should not be rotated when filling the box, + If True, specifies that compounds should not be rotated when filling the sphere. Rotation contraints are specified for each individual axis (x, y, z) default=(False, False, False) temp_file : str, default=None @@ -572,7 +572,7 @@ def solvate(solute, solvent, n_solvent, box, overlap=0.2, in some systems because PACKMOL does not account for periodic boundary conditions in its optimization. fix_orientation : iterable of booleans or list of iterables - Specify that compounds should not be rotated when filling the box, + If True, specifies that compounds should not be rotated when filling the box. Rotation contraints are specified for each individual axis (x, y, z) default=(False, False, False) temp_file : str, default=None From 475d17f6818f6f00007b0dcc0defa8f37fb1a381 Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 18 Jun 2020 17:56:03 -0600 Subject: [PATCH 13/19] made warning messages consistent for each packing function --- mbuild/packing.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mbuild/packing.py b/mbuild/packing.py index a431b5e48..7f85ec769 100755 --- a/mbuild/packing.py +++ b/mbuild/packing.py @@ -172,8 +172,8 @@ def fill_box(compound, n_compounds=None, box=None, density=None, overlap=0.2, try: iter(fix_orientation[0]) except: - warnings.warn("fix_orientation can be given as an iterable of True/False values " - "for each compound to fix rotations about each x,y,z axis individually. " + warnings.warn("fix_orientation can now be passed as a tuple or list with True/False " + "values specified for each x,y,z axis individually. " "Using a single instance of True/False defaults to (True,True,True) " "and (Fale,False,False) respectively") From 2e55f88ca97845e14182395e2f5c092c9aaa31a5 Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 30 Jun 2020 09:13:11 -0600 Subject: [PATCH 14/19] added a leading underscore to the packmol_constrain function, and moved it below the various packing functions. Made slight change to description of fix_orientation in doc strings --- mbuild/packing.py | 96 +++++++++++++++++++++++------------------------ 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/mbuild/packing.py b/mbuild/packing.py index 7f85ec769..75df03875 100755 --- a/mbuild/packing.py +++ b/mbuild/packing.py @@ -44,46 +44,6 @@ end structure """ -def packmol_constrain(fix_orientation): - """ - Provides information to PACKMOL about which axes to constrain rotation. - fix_orientation is generated within the `fill_box` function - Parameters - ---------- - fix_orientation : iterable of booleans, directions (x, y, z) about - which to constrain rotation. If True, no rotation - in that direction - Returns - ------- - None if fix_orientation = (False, False, False) - string - rotation constraints to be added to PACKMOL input text - """ - constraints = ['constrain_rotation x 0. 0.', - 'constrain_rotation y 0. 0.', - 'constrain_rotation z 0. 0.'] - CONSTRAIN = """ - {} - {} - {} - """ - # Handles instances that are not iterable; defaults to True/Fales for all axes - if fix_orientation == True: - fix_orientation=(True, True, True) - if fix_orientation == False: - fix_orientation=(False, False, False) - - if not any(fix_orientation): - return None - final_constraints = list() - for i, val in enumerate(fix_orientation): - if val: - final_constraints.append(constraints[i]) - else: - final_constraints.append("") - return CONSTRAIN.format(*final_constraints) - - def fill_box(compound, n_compounds=None, box=None, density=None, overlap=0.2, seed=12345, edge=0.2, compound_ratio=None, aspect_ratio=None, fix_orientation=(False, False, False), temp_file=None, @@ -137,7 +97,7 @@ def fill_box(compound, n_compounds=None, box=None, density=None, overlap=0.2, aspect_ratio : list of float If a non-cubic box is desired, the ratio of box lengths in the x, y, and z directions. - fix_orientation : iterable of booleans or list of iterables + fix_orientation : tuple of booleans or list of tuples If True, specifies that compounds should not be rotated when filling the box. Rotation contraints are specified for each individual axis (x, y, z) default=(False, False, False) @@ -246,7 +206,7 @@ def fill_box(compound, n_compounds=None, box=None, density=None, overlap=0.2, compound_xyz_list.append(compound_xyz) comp.save(compound_xyz.name, overwrite=True) - PACKMOL_CONSTRAIN = packmol_constrain(rotate) + PACKMOL_CONSTRAIN = _packmol_constrain(rotate) input_text += PACKMOL_BOX.format(compound_xyz.name, m_compounds, box_mins[0], box_mins[1], box_mins[2], box_maxs[0], @@ -291,7 +251,7 @@ def fill_region(compound, n_compounds, region, overlap=0.2, Buffer at the edge of the region to not place molecules. This is necessary in some systems because PACKMOL does not account for periodic boundary conditions in its optimization. - fix_orientation : iterable of booleans or list of iterables + fix_orientation : tuple of booleans or list of tuples If True, specifies that compounds should not be rotated when filling the box. Rotation contraints are specified for each individual axis (x, y, z) default=(False, False, False) @@ -360,7 +320,7 @@ def fill_region(compound, n_compounds, region, overlap=0.2, compound_xyz_list.append(compound_xyz) comp.save(compound_xyz.name, overwrite=True) - PACKMOL_CONSTRAIN = packmol_constrain(rotate) + PACKMOL_CONSTRAIN = _packmol_constrain(rotate) reg_mins = reg.mins * 10 reg_maxs = reg.maxs * 10 reg_maxs -= edge * 10 # Apply edge buffer @@ -421,7 +381,7 @@ def fill_sphere(compound, sphere, n_compounds=None, density=None, overlap=0.2, Ratio of number of each compound to be put in sphere. Only used in the case of `density` having been specified, `n_compounds` not specified, and more than one `compound`. - fix_orientation : iterable of booleans or list of iterables + fix_orientation : tuple of booleans or list of tuples If True, specifies that compounds should not be rotated when filling the sphere. Rotation contraints are specified for each individual axis (x, y, z) default=(False, False, False) @@ -525,7 +485,7 @@ def fill_sphere(compound, sphere, n_compounds=None, density=None, overlap=0.2, compound_xyz = _new_xyz_file() compound_xyz_list.append(compound_xyz) - PACKMOL_CONSTRAIN = packmol_constrain(rotate) + PACKMOL_CONSTRAIN = _packmol_constrain(rotate) comp.save(compound_xyz.name, overwrite=True) input_text += PACKMOL_SPHERE.format(compound_xyz.name, m_compounds, @@ -571,7 +531,7 @@ def solvate(solute, solvent, n_solvent, box, overlap=0.2, Buffer at the edge of the box to not place molecules. This is necessary in some systems because PACKMOL does not account for periodic boundary conditions in its optimization. - fix_orientation : iterable of booleans or list of iterables + fix_orientation : tuple of booleans or list of tuples If True, specifies that compounds should not be rotated when filling the box. Rotation contraints are specified for each individual axis (x, y, z) default=(False, False, False) @@ -635,7 +595,7 @@ def solvate(solute, solvent, n_solvent, box, overlap=0.2, solvent_xyz_list.append(solvent_xyz) solv.save(solvent_xyz.name, overwrite=True) - PACKMOL_CONSTRAIN = packmol_constrain(rotate) + PACKMOL_CONSTRAIN = _packmol_constrain(rotate) input_text += PACKMOL_BOX.format(solvent_xyz.name, m_solvent, box_mins[0], box_mins[1], box_mins[2], box_maxs[0], @@ -685,6 +645,46 @@ def _validate_box(box): return box +def _packmol_constrain(fix_orientation): + """ + Provides information to PACKMOL about which axes to constrain rotation. + fix_orientation is generated within the `fill_box` function + Parameters + ---------- + fix_orientation : tuple of booleans or single boolean, directions (x, y, z) about + which to constrain rotation. If True, no rotation + in that direction + Returns + ------- + None if fix_orientation = (False, False, False) + string + rotation constraints to be added to PACKMOL input text + """ + constraints = ['constrain_rotation x 0. 0.', + 'constrain_rotation y 0. 0.', + 'constrain_rotation z 0. 0.'] + CONSTRAIN = """ + {} + {} + {} + """ + # Handles instances that are not iterable; defaults to True/Fales for all axes + if fix_orientation == True: + fix_orientation=(True, True, True) + if fix_orientation == False: + fix_orientation=(False, False, False) + + if not any(fix_orientation): + return None + final_constraints = list() + for i, val in enumerate(fix_orientation): + if val: + final_constraints.append(constraints[i]) + else: + final_constraints.append("") + return CONSTRAIN.format(*final_constraints) + + def _new_xyz_file(): """Generate PDB file using tempfile.NamedTemporaryFile. From 3b6f19a7f8304190360896e81c37c3cf8a2d1b61 Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 30 Jun 2020 09:14:14 -0600 Subject: [PATCH 15/19] added the leadering underscore to the packmol_constrain function call in the unit test --- mbuild/tests/test_packing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mbuild/tests/test_packing.py b/mbuild/tests/test_packing.py index 172d4ccd1..b6c4c5622 100755 --- a/mbuild/tests/test_packing.py +++ b/mbuild/tests/test_packing.py @@ -229,7 +229,7 @@ def test_no_rotate(self, h2o): "constrain_rotation z"])]) def test_specify_axis(self, orientations, constraints): for i in constraints: - assert i in mb.packing.packmol_constrain(orientations) + assert i in mb.packing._packmol_constrain(orientations) def test_remove_port(self): from mbuild.lib.recipes import Alkane From 85cf398bc3ff86e44fd9c792d3068792c1c84a0a Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 16 Jul 2020 08:43:10 -0600 Subject: [PATCH 16/19] fixed typos, more robust check of fix_orientation in the _packmol_constrain function --- mbuild/packing.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/mbuild/packing.py b/mbuild/packing.py index 75df03875..4bcea37db 100755 --- a/mbuild/packing.py +++ b/mbuild/packing.py @@ -135,7 +135,7 @@ def fill_box(compound, n_compounds=None, box=None, density=None, overlap=0.2, warnings.warn("fix_orientation can now be passed as a tuple or list with True/False " "values specified for each x,y,z axis individually. " "Using a single instance of True/False defaults to (True,True,True) " - "and (Fale,False,False) respectively") + "and (False,False,False) respectively") if compound is not None and n_compounds is not None: if len(compound) != len(n_compounds): @@ -285,7 +285,7 @@ def fill_region(compound, n_compounds, region, overlap=0.2, warnings.warn("fix_orientation can now be passed as a tuple or list with True/False " "values specified for each x,y,z axis individually. " "Using a single instance of True/False defaults to (True,True,True) " - "and (Fale,False,False) respectively") + "and (False,False,False) respectively") if compound is not None and n_compounds is not None: if len(compound) != len(n_compounds): msg = ("`compound` and `n_compounds` must be of equal length.") @@ -423,7 +423,7 @@ def fill_sphere(compound, sphere, n_compounds=None, density=None, overlap=0.2, warnings.warn("fix_orientation can now be passed as a tuple or list with True/False " "values specified for each x,y,z axis individually. " "Using a single instance of True/False defaults to (True,True,True) " - "and (Fale,False,False) respectively") + "and (False,False,False) respectively") if compound is not None and n_compounds is not None: if len(compound) != len(n_compounds): @@ -562,7 +562,7 @@ def solvate(solute, solvent, n_solvent, box, overlap=0.2, warnings.warn("fix_orientation can now be passed as a tuple or list with True/False " "values specified for each x,y,z axes individually. " "Using a single instance of True/False defaults to (True,True,True) " - "and (Fale,False,False) respectively") + "and (False,False,False) respectively") if len(solvent) != len(n_solvent): msg = ("`n_solvent` and `n_solvent` must be of equal length.") @@ -668,11 +668,11 @@ def _packmol_constrain(fix_orientation): {} {} """ - # Handles instances that are not iterable; defaults to True/Fales for all axes - if fix_orientation == True: - fix_orientation=(True, True, True) - if fix_orientation == False: - fix_orientation=(False, False, False) + # Handles instances that are not iterable; defaults to True/False for all axes + if fix_orientation is True: + fix_orientation = [fix_orientation] * 3 + if fix_orientation is False: + fix_orientation= [fix_orientation] * 3 if not any(fix_orientation): return None @@ -756,7 +756,7 @@ def _run_packmol(input_text, filled_xyz, temp_file): "the .xyz_FORCED file instead. This may not be a " "sufficient packing result.") warnings.warn(msg) - os.system('cp {0}_forced {0}'.format(filled_xyz.name)) + os.system('cp {0}_FORCED {0}'.format(filled_xyz.name)) if 'ERROR' in out or proc.returncode != 0: _packmol_error(out, err) From d63f96757cb5aeb88be3d00e05dd02514ffff44f Mon Sep 17 00:00:00 2001 From: Chris Date: Sun, 26 Jul 2020 23:24:41 -0600 Subject: [PATCH 17/19] made changes to the checking and handling of lists of bools for the fix_orientation parameter. Updated doc strings --- mbuild/packing.py | 85 +++++++++++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 36 deletions(-) diff --git a/mbuild/packing.py b/mbuild/packing.py index 4bcea37db..279f43b49 100755 --- a/mbuild/packing.py +++ b/mbuild/packing.py @@ -46,7 +46,7 @@ def fill_box(compound, n_compounds=None, box=None, density=None, overlap=0.2, seed=12345, edge=0.2, compound_ratio=None, - aspect_ratio=None, fix_orientation=(False, False, False), temp_file=None, + aspect_ratio=None, fix_orientation=[False, False, False], temp_file=None, update_port_locations=False): """Fill a box with a `mbuild.compound` or `Compound`s using PACKMOL. @@ -97,10 +97,11 @@ def fill_box(compound, n_compounds=None, box=None, density=None, overlap=0.2, aspect_ratio : list of float If a non-cubic box is desired, the ratio of box lengths in the x, y, and z directions. - fix_orientation : tuple of booleans or list of tuples + fix_orientation : boolean, list of booleans or list of lists of booleans If True, specifies that compounds should not be rotated when filling the box. Rotation contraints are specified for each individual axis (x, y, z) - default=(False, False, False) + default=[False, False, False]. If a single instance of True or False is passed + then defaults to True or False for all axes. temp_file : str, default=None File name to write PACKMOL's raw output to. update_port_locations : bool, default=False @@ -129,13 +130,15 @@ def fill_box(compound, n_compounds=None, box=None, density=None, overlap=0.2, if not isinstance(fix_orientation, (list, set)): fix_orientation = [fix_orientation]*len(compound) - try: - iter(fix_orientation[0]) - except: - warnings.warn("fix_orientation can now be passed as a tuple or list with True/False " + try: + iter(fix_orientation[0]) + except: + warnings.warn("fix_orientation can now be passed as a list with True/False " "values specified for each x,y,z axis individually. " - "Using a single instance of True/False defaults to (True,True,True) " - "and (False,False,False) respectively") + "Using a single instance of True/False defaults to [True,True,True] " + "and [False,False,False] respectively") + if isinstance(fix_orientation, (list, set)) and len(fix_orientation) == 3: + fix_orientation = [fix_orientation]*len(compound) if compound is not None and n_compounds is not None: if len(compound) != len(n_compounds): @@ -231,7 +234,7 @@ def fill_box(compound, n_compounds=None, box=None, density=None, overlap=0.2, def fill_region(compound, n_compounds, region, overlap=0.2, - seed=12345, edge=0.2, fix_orientation=(False,False,False), + seed=12345, edge=0.2, fix_orientation=[False,False,False], temp_file=None, update_port_locations=False): """Fill a region of a box with `mbuild.Compound`(s) using PACKMOL. @@ -251,10 +254,11 @@ def fill_region(compound, n_compounds, region, overlap=0.2, Buffer at the edge of the region to not place molecules. This is necessary in some systems because PACKMOL does not account for periodic boundary conditions in its optimization. - fix_orientation : tuple of booleans or list of tuples + fix_orientation : list of booleans or list of lists of booleans If True, specifies that compounds should not be rotated when filling the box. Rotation contraints are specified for each individual axis (x, y, z) - default=(False, False, False) + default=[False, False, False]. If a single instance of True or False is passed + then defaults to True or False for all axes. temp_file : str, default=None File name to write PACKMOL's raw output to. update_port_locations : bool, default=False @@ -279,13 +283,16 @@ def fill_region(compound, n_compounds, region, overlap=0.2, n_compounds = [n_compounds] if not isinstance(fix_orientation, (list, set)): fix_orientation = [fix_orientation]*len(compound) - try: - iter(fix_orientation[0]) - except: - warnings.warn("fix_orientation can now be passed as a tuple or list with True/False " + try: + iter(fix_orientation[0]) + except: + warnings.warn("fix_orientation can now be passed as a list with True/False " "values specified for each x,y,z axis individually. " "Using a single instance of True/False defaults to (True,True,True) " "and (False,False,False) respectively") + if isinstance(fix_orientation, (list, set)) and len(fix_orientation) == 3: + fix_orientation = [fix_orientation]*len(compound) + if compound is not None and n_compounds is not None: if len(compound) != len(n_compounds): msg = ("`compound` and `n_compounds` must be of equal length.") @@ -347,7 +354,7 @@ def fill_region(compound, n_compounds, region, overlap=0.2, def fill_sphere(compound, sphere, n_compounds=None, density=None, overlap=0.2, seed=12345, edge=0.2, compound_ratio=None, - fix_orientation=(False,False,False), temp_file=None, + fix_orientation=[False,False,False], temp_file=None, update_port_locations=False): """Fill a sphere with a compound using packmol. @@ -381,10 +388,11 @@ def fill_sphere(compound, sphere, n_compounds=None, density=None, overlap=0.2, Ratio of number of each compound to be put in sphere. Only used in the case of `density` having been specified, `n_compounds` not specified, and more than one `compound`. - fix_orientation : tuple of booleans or list of tuples - If True, specifies that compounds should not be rotated when filling the sphere. + fix_orientation : boolean, list of booleans or list of lists of booleans + If True, specifies that compounds should not be rotated when filling the box. Rotation contraints are specified for each individual axis (x, y, z) - default=(False, False, False) + default=[False, False, False]. If a single instance of True or False is passed + then defaults to True or False for all axes. temp_file : str, default=None File name to write PACKMOL's raw output to. update_port_locations : bool, default=False @@ -417,13 +425,15 @@ def fill_sphere(compound, sphere, n_compounds=None, density=None, overlap=0.2, n_compounds = [n_compounds] if not isinstance(fix_orientation, (list, set)): fix_orientation = [fix_orientation]*len(compound) - try: - iter(fix_orientation[0]) - except: - warnings.warn("fix_orientation can now be passed as a tuple or list with True/False " + try: + iter(fix_orientation[0]) + except: + warnings.warn("fix_orientation can now be passed as a list with True/False " "values specified for each x,y,z axis individually. " - "Using a single instance of True/False defaults to (True,True,True) " - "and (False,False,False) respectively") + "Using a single instance of True/False defaults to [True,True,True] " + "and [False,False,False] respectively") + if isinstance(fix_orientation, (list, set)) and len(fix_orientation) == 3: + fix_orientation = [fix_orientation]*len(compound) if compound is not None and n_compounds is not None: if len(compound) != len(n_compounds): @@ -509,7 +519,7 @@ def fill_sphere(compound, sphere, n_compounds=None, density=None, overlap=0.2, def solvate(solute, solvent, n_solvent, box, overlap=0.2, - seed=12345, edge=0.2, fix_orientation=(False,False,False), + seed=12345, edge=0.2, fix_orientation=[False,False,False], temp_file=None, update_port_locations=False): """Solvate a compound in a box of solvent using packmol. @@ -531,10 +541,11 @@ def solvate(solute, solvent, n_solvent, box, overlap=0.2, Buffer at the edge of the box to not place molecules. This is necessary in some systems because PACKMOL does not account for periodic boundary conditions in its optimization. - fix_orientation : tuple of booleans or list of tuples + fix_orientation : boolean, list of booleans or list of lists of booleans If True, specifies that compounds should not be rotated when filling the box. Rotation contraints are specified for each individual axis (x, y, z) - default=(False, False, False) + default=[False, False, False]. If a single instance of True or False is passed + then defaults to True or False for all axes. temp_file : str, default=None File name to write PACKMOL's raw output to. update_port_locations : bool, default=False @@ -556,13 +567,15 @@ def solvate(solute, solvent, n_solvent, box, overlap=0.2, n_solvent = [n_solvent] if not isinstance(fix_orientation, (list, set)): fix_orientation = [fix_orientation] * len(solvent) - try: - iter(fix_orientation[0]) - except: - warnings.warn("fix_orientation can now be passed as a tuple or list with True/False " + try: + iter(fix_orientation[0]) + except: + warnings.warn("fix_orientation can now be passed as a list with True/False " "values specified for each x,y,z axes individually. " - "Using a single instance of True/False defaults to (True,True,True) " - "and (False,False,False) respectively") + "Using a single instance of True/False defaults to [True,True,True] " + "and [False,False,False] respectively") + if isinstance(fix_orientation, (list, set)) and len(fix_orientation) == 3: + fix_orientation = [fix_orientation]*len(compound) if len(solvent) != len(n_solvent): msg = ("`n_solvent` and `n_solvent` must be of equal length.") @@ -651,7 +664,7 @@ def _packmol_constrain(fix_orientation): fix_orientation is generated within the `fill_box` function Parameters ---------- - fix_orientation : tuple of booleans or single boolean, directions (x, y, z) about + fix_orientation : list of booleans or single boolean, directions (x, y, z) about which to constrain rotation. If True, no rotation in that direction Returns From 052be47cdb26fbabc89bf33e07bae3590d035ee2 Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 6 Aug 2020 10:14:45 -0600 Subject: [PATCH 18/19] change compound to solvent in def solvate(); fixed failing solvate test in previous commit --- mbuild/packing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mbuild/packing.py b/mbuild/packing.py index 279f43b49..285e73acb 100755 --- a/mbuild/packing.py +++ b/mbuild/packing.py @@ -575,7 +575,7 @@ def solvate(solute, solvent, n_solvent, box, overlap=0.2, "Using a single instance of True/False defaults to [True,True,True] " "and [False,False,False] respectively") if isinstance(fix_orientation, (list, set)) and len(fix_orientation) == 3: - fix_orientation = [fix_orientation]*len(compound) + fix_orientation = [fix_orientation]*len(solvent) if len(solvent) != len(n_solvent): msg = ("`n_solvent` and `n_solvent` must be of equal length.") From 2d90190c92253f0287e32f08943d0c4488a474d9 Mon Sep 17 00:00:00 2001 From: Chris Date: Wed, 14 Apr 2021 12:09:26 -0600 Subject: [PATCH 19/19] fixed a lot of little errors --- mbuild/packing.py | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/mbuild/packing.py b/mbuild/packing.py index d3425cb3a..7d623c241 100755 --- a/mbuild/packing.py +++ b/mbuild/packing.py @@ -63,7 +63,7 @@ def fill_box( edge=0.2, compound_ratio=None, aspect_ratio=None, - fix_orientation=[False, False, False] + fix_orientation=[False, False, False], temp_file=None, update_port_locations=False, ): @@ -157,7 +157,7 @@ def fill_box( fix_orientation = [fix_orientation]*len(compound) try: iter(fix_orientation[0]) - except: + except TypeError: warnings.warn("fix_orientation can now be passed as a list with True/False " "values specified for each x,y,z axis individually. " "Using a single instance of True/False defaults to [True,True,True] " @@ -297,7 +297,7 @@ def fill_region( seed=12345, sidemax=100.0, edge=0.2, - fix_orientation=[False, False, False] + fix_orientation=[False, False, False], temp_file=None, update_port_locations=False, ): @@ -354,7 +354,7 @@ def fill_region( fix_orientation = [fix_orientation]*len(compound) try: iter(fix_orientation[0]) - except: + except TypeError: warnings.warn("fix_orientation can now be passed as a list with True/False " "values specified for each x,y,z axis individually. " "Using a single instance of True/False defaults to (True,True,True) " @@ -443,7 +443,7 @@ def fill_sphere( sidemax=100.0, edge=0.2, compound_ratio=None, - fix_orientation=[False, False, False] + fix_orientation=[False, False, False], temp_file=None, update_port_locations=False, ): @@ -524,7 +524,7 @@ def fill_sphere( fix_orientation = [fix_orientation]*len(compound) try: iter(fix_orientation[0]) - except: + except TypeError: warnings.warn("fix_orientation can now be passed as a list with True/False " "values specified for each x,y,z axis individually. " "Using a single instance of True/False defaults to [True,True,True] " @@ -653,7 +653,7 @@ def solvate( seed=12345, sidemax=100.0, edge=0.2, - fix_orientation=[False, False, False] + fix_orientation=[False, False, False], temp_file=None, update_port_locations=False, ): @@ -709,7 +709,7 @@ def solvate( fix_orientation = [fix_orientation] * len(solvent) try: iter(fix_orientation[0]) - except: + except TypeError: warnings.warn("fix_orientation can now be passed as a list with True/False " "values specified for each x,y,z axes individually. " "Using a single instance of True/False defaults to [True,True,True] " @@ -833,7 +833,7 @@ def _packmol_constrain(fix_orientation): {} """ # Handles instances that are not iterable; defaults to True/False for all axes - if fix_orientation is True or is False: + if fix_orientation is True or fix_orientation is False: fix_orientation = [fix_orientation] * 3 if not any(fix_orientation): @@ -926,11 +926,7 @@ def _run_packmol(input_text, filled_xyz, temp_file): "sufficient packing result." ) warnings.warn(msg) -<<<<<<< HEAD os.system('cp {0}_FORCED {0}'.format(filled_xyz.name)) -======= - os.system("cp {0}_FORCED {0}".format(filled_xyz.name)) ->>>>>>> 636f9b15f796614c616f807c652486010fa9e43e if "ERROR" in out or proc.returncode != 0: _packmol_error(out, err)