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,67 @@ 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+ uni .compute_molecule_com ()
159+ uni .atom ._revert_categories ()
160+ mapper = uni .atom .drop_duplicates ('molecule' ).set_index ('molecule' )['frame' ]
161+ uni .atom ._set_categories ()
162+ uni .molecule ['frame' ] = uni .molecule .index .map (lambda x : mapper [x ])
163+ sources = source_atoms .groupby ('frame' )
164+ groups = uni .molecule .groupby ('frame' )
165+ n = groups .ngroups
166+ dx = np .empty ((n , ), dtype = np .ndarray )
167+ dy = np .empty ((n , ), dtype = np .ndarray )
168+ dz = np .empty ((n , ), dtype = np .ndarray )
169+ index = np .empty ((n , ), dtype = np .ndarray )
170+ for i , (frame , group ) in enumerate (groups ):
171+ cx = group ['cx' ].values
172+ cy = group ['cy' ].values
173+ cz = group ['cz' ].values
174+ ccx , ccy , ccz = sources .get_group (frame )[['x' , 'y' , 'z' ]].mean ().values
175+ # ccx, ccy, ccz = mcules.ix[mcules['classification'] == 'solute', ['cx', 'cy', 'cz']].values[0]
176+ rx , ry , rz = uni .frame .ix [frame , ['rx' , 'ry' , 'rz' ]].values
177+ dxf , dyf , dzf = _compute (cx , cy , cz , rx , ry , rz , ccx , ccy , ccz )
178+ dx [i ] = dxf
179+ dy [i ] = dyf
180+ dz [i ] = dzf
181+ index [i ] = group .index .values
182+ del uni .molecule ['frame' ]
183+ dx = np .concatenate (dx )
184+ dy = np .concatenate (dy )
185+ dz = np .concatenate (dz )
186+ index = np .concatenate (index )
187+ df = pd .DataFrame .from_dict ({'x' : dx , 'y' : dy , 'z' : dz , 'molecule' : index })
188+ df .set_index ('molecule' , inplace = True )
189+ for molecule in df .index :
190+ dx , dy , dz = df .ix [molecule ].values
191+ uni .atom .ix [uni .atom ['molecule' ] == molecule , 'x' ] += dx
192+ uni .atom .ix [uni .atom ['molecule' ] == molecule , 'y' ] += dy
193+ uni .atom .ix [uni .atom ['molecule' ] == molecule , 'z' ] += dz
194+ return uni
195+
196+
138197def _build_universe (universe , ordered_molecules , ordered_twos , n ):
139198 """
140199 """
200+ raise NotImplementedError ()
141201 # 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 ])
202+ molecules = np .concatenate ([m [:n ] for m in ordered_molecules ])
203+ twos = np .concatenate ([t [:n ] for t in ordered_twos ])
144204 atom = universe .atom [universe .atom ['molecule' ].isin (molecules )].copy ().sort_index ()
145205 two = universe .atom_two [universe .atom_two ['atom0' ].isin (atom .index ) &
146206 universe .atom_two ['atom1' ].isin (atom .index )].copy ().sort_index ()
0 commit comments