1414and :func:`~exatomic.molecule.Molecule.classify`.
1515"""
1616import numpy as np
17- from exatomic .container import Universe
17+ import pandas as pd
18+ from exatomic .algorithms .distance import _compute
1819
1920
2021def nearest_molecules (universe , n , sources , restrictions = None , how = 'atom' ,
@@ -46,13 +47,17 @@ def nearest_molecules(universe, n, sources, restrictions=None, how='atom',
4647 Returns:
4748 unis (dict): Dictionary of number of neighbors keys, universe values
4849 """
49- source_atoms , other_atoms , source_molecules , other_molecules , n = _slice_atoms_molecules (universe , sources , restrictions , how )
50+ source_atoms , other_atoms , source_molecules , other_molecules , n = _slice_atoms_molecules (universe , sources , restrictions , n )
5051 ordered_molecules , ordered_twos = _compute_neighbors_by_atom (universe , source_atoms , other_atoms , source_molecules )
51- unis = {nn : _build_universe (universe , ordered_molecules , ordered_twos , nn ) for nn in n }
52-
53-
54-
55-
52+ unis = {}
53+ if free_boundary == True :
54+ for nn in n :
55+ unis [nn ] = _build_free_universe (universe , ordered_molecules ,
56+ ordered_twos , nn , source_atoms ,
57+ source_molecules )
58+ else :
59+ raise NotImplementedError ()
60+ return unis
5661
5762
5863def _slice_atoms_molecules (universe , sources , restrictions , n ):
@@ -66,7 +71,7 @@ def _slice_atoms_molecules(universe, sources, restrictions, n):
6671 sources = [sources ]
6772 if not isinstance (restrictions , list ) and restrictions is not None :
6873 restrictions = [restrictions ]
69- if not isinstance (n , list ):
74+ if isinstance (n , ( int , np . int32 , np . int64 ) ):
7075 n = [n ]
7176 symbols = universe .atom ['symbol' ].unique ()
7277 classification = universe .molecule ['classification' ].unique ()
@@ -135,12 +140,68 @@ def _compute_neighbors_by_com(universe, source_molecules, other_molecules):
135140 raise NotImplementedError ()
136141
137142
143+ def _build_free_universe (universe , ordered_molecules , ordered_twos , n ,
144+ source_atoms , source_molecules ):
145+ """
146+ """
147+ molecule = np .concatenate ([mcules [:n ] for mcules in ordered_molecules ])
148+ molecule = np .concatenate ((molecule , source_molecules .index .tolist ()))
149+ molecule = universe .molecule [universe .molecule .index .isin (molecule )].copy ()
150+ atom = universe .atom [universe .atom ['molecule' ].isin (molecule .index )].copy ()
151+ atom_two = universe .atom_two [(universe .atom_two ['atom0' ].isin (atom .index ) &
152+ universe .atom_two ['atom1' ].isin (atom .index ))].copy ()
153+ frame = universe .frame [universe .frame .index .isin (atom ['frame' ])].copy ()
154+ frame ['periodic' ] = False
155+ uni = universe .__class__ (atom = atom , molecule = molecule , frame = frame , atom_two = atom_two )
156+ if universe .frame .is_periodic ():
157+ uni .atom .update (universe .visual_atom )
158+ if 'cx' not in uni .molecule .columns :
159+ uni .compute_molecule_com ()
160+ uni .atom ._revert_categories ()
161+ mapper = uni .atom .drop_duplicates ('molecule' ).set_index ('molecule' )['frame' ]
162+ uni .atom ._set_categories ()
163+ uni .molecule ['frame' ] = uni .molecule .index .map (lambda x : mapper [x ])
164+ sources = source_atoms .groupby ('frame' )
165+ groups = uni .molecule .groupby ('frame' )
166+ n = groups .ngroups
167+ dx = np .empty ((n , ), dtype = np .ndarray )
168+ dy = np .empty ((n , ), dtype = np .ndarray )
169+ dz = np .empty ((n , ), dtype = np .ndarray )
170+ index = np .empty ((n , ), dtype = np .ndarray )
171+ for i , (frame , group ) in enumerate (groups ):
172+ cx = group ['cx' ].values
173+ cy = group ['cy' ].values
174+ cz = group ['cz' ].values
175+ ccx , ccy , ccz = sources .get_group (frame )[['x' , 'y' , 'z' ]].mean ().values
176+ # ccx, ccy, ccz = mcules.ix[mcules['classification'] == 'solute', ['cx', 'cy', 'cz']].values[0]
177+ rx , ry , rz = uni .frame .ix [frame , ['rx' , 'ry' , 'rz' ]].values
178+ dxf , dyf , dzf = _compute (cx , cy , cz , rx , ry , rz , ccx , ccy , ccz )
179+ dx [i ] = dxf
180+ dy [i ] = dyf
181+ dz [i ] = dzf
182+ index [i ] = group .index .values
183+ del uni .molecule ['frame' ]
184+ dx = np .concatenate (dx )
185+ dy = np .concatenate (dy )
186+ dz = np .concatenate (dz )
187+ index = np .concatenate (index )
188+ df = pd .DataFrame .from_dict ({'x' : dx , 'y' : dy , 'z' : dz , 'molecule' : index })
189+ df .set_index ('molecule' , inplace = True )
190+ for molecule in df .index :
191+ dx , dy , dz = df .ix [molecule ].values
192+ uni .atom .ix [uni .atom ['molecule' ] == molecule , 'x' ] += dx
193+ uni .atom .ix [uni .atom ['molecule' ] == molecule , 'y' ] += dy
194+ uni .atom .ix [uni .atom ['molecule' ] == molecule , 'z' ] += dz
195+ return uni
196+
197+
138198def _build_universe (universe , ordered_molecules , ordered_twos , n ):
139199 """
140200 """
201+ raise NotImplementedError ()
141202 # TODO CONVERT TO A GENERIC AND COMPLETE SLICER
142- molecules = np .concatenate ([m [:n ] for m in ordered_molecules . values ])
143- twos = np .concatenate ([t [:n ] for t in ordered_twos . values ])
203+ molecules = np .concatenate ([m [:n ] for m in ordered_molecules ])
204+ twos = np .concatenate ([t [:n ] for t in ordered_twos ])
144205 atom = universe .atom [universe .atom ['molecule' ].isin (molecules )].copy ().sort_index ()
145206 two = universe .atom_two [universe .atom_two ['atom0' ].isin (atom .index ) &
146207 universe .atom_two ['atom1' ].isin (atom .index )].copy ().sort_index ()
0 commit comments