[docs]defshrink_ghost_atoms(mols,length=None,map=None):""" Update all of the molecules (or single molecule) in 'mols' so that the bond lengths involving ghost atoms at one or other end state (but not both) are shrunk to `length`. This is 0.6 A by default (this seems to be a value that causes fewest NaNs). """from..baseimportcreate_mapfrom..casimportSymbolfrom..mmimportAmberBondmols=mols.clone()iflengthisNone:length=0.6else:from..unitsimportangstrom,ulength=u(length).to(angstrom)map=create_map(map)perturbable_mols=mols.molecules("property is_perturbable")props=["LJ","bond","charge",]map0=map.add_suffix("0",props)map1=map.add_suffix("1",props)# identify all of the ghost atomsfrom_ghosts=[]to_ghosts=[]formolinperturbable_mols:foratominmol.atoms():chg0=atom.property(map0["charge"])chg1=atom.property(map1["charge"])lj0=atom.property(map0["LJ0"])lj1=atom.property(map1["LJ1"])is_ghost0=chg0.is_zero()andlj0.is_dummy()is_ghost1=chg1.is_zero()andlj1.is_dummy()ifis_ghost0andnotis_ghost1:from_ghosts.append(atom.index())elifis_ghost1:to_ghosts.append(atom.index())r=Symbol("r")bonds0=mol.property(map0["bond"])bonds1=mol.property(map1["bond"])changed0=Falsechanged1=Falseforbondinmol.bonds():# are either of the atoms in the bond in from_ghosts or to_ghostsis_from_ghost=(bond[0].index()infrom_ghostsorbond[1].index()infrom_ghosts)is_to_ghost=bond[0].index()into_ghostsorbond[1].index()into_ghostsifis_from_ghostandnotis_to_ghost:# this is a bond that is turning into a ghostr0_0=lengthpot0=AmberBond(bond.potential(map0),r)ifr0_0<pot0.r0():# only change it if the bond is not already shorterbonds0.set(bond.id(),AmberBond(pot0.k(),r0_0).to_expression(r),)changed0=Trueelifis_to_ghost:r0_1=lengthpot1=AmberBond(bond.potential(map1),r)ifr0_1<pot1.r0():# only change it if the bond is not already shorterbonds1.set(bond.id(),AmberBond(pot1.k(),r0_1).to_expression(r),)changed1=Trueifchanged0:mol=mol.edit().set_property(map0["bond"].source(),bonds0).commit()ifchanged1:mol=mol.edit().set_property(map1["bond"].source(),bonds1).commit()ifchanged0orchanged1:mols.update(mol)returnmols