Amber-MD / pytraj

Python interface of cpptraj
https://amber-md.github.io/pytraj
168 stars 38 forks source link

Iteration and selecting by distance #1564

Closed jyosa closed 3 years ago

jyosa commented 3 years ago

Hi, I'm trying to select by distance in each frame (every frame change the residues to select by distance), but I could not do this task. The system consist of a solute surrounded by solvent (methanol), it is possible do that with pytraj, because I tried with iteraframe but looks that is not possible. The thing is that for each molecule less than, for example 5 A , I want to perform some calculation for each frame.

Thank you in advance

hainm commented 3 years ago

hi @jyosa

How's about just precaculate the distance array to find the frame_indices that satisfy your criteria?

dist = pt.distance(...)
print(dist < 5) #
jyosa commented 3 years ago

Did not work, but for example for a frame 0

top = traj.top
top.set_reference(traj[0])
selection = traj[':ACE<:5.0|:ACE, NME'][0]

here select all residues less than 5 A and also the solute, but when I used the iteration id doesn't work

hainm commented 3 years ago

ok, so I misunderstood your original idea.

May be trying:

top = traj.top
for frame in traj:
    top.set_reference_frame(frame)
    atom_indices = top.select(<your mask>)
    print(frame.xyz[atom_indices].shape) # You can tell that you will likely get different shape 

PS1: What are you trying to solve? To get stripped trajectory from the selection? (that won't work because different frame might have different number of atoms, due to the distance-selection).

jyosa commented 3 years ago

Hi thank you for your answer, from the selection it is possible also to select each residue? because with this loop I get index for all atoms in the selection, but I got stuck selecting each residue. I want to compute instantaneous dipole moment for each residue in the selection that's my goal. Again thank you!

hainm commented 3 years ago

hi @jyosa, here is my very naive approach: using the atom indices to get new topology and get the residue information?

In [23]: t = pt.datafiles.load_tz2_ortho()

In [24]: top = t.top

In [25]: top.set_reference(t[1])

In [26]: indices = t.top.select(':1<:5.0')

In [27]: [res.original_resid for res in top[indices].residues] 
# `original_resid` is 1-based index and is the "original" resid in the `top` above.
jyosa commented 3 years ago

goo thank you is getting better, but when I try to compute center of mass I got this: TypeError: Argument 'atmask' has incorrect type (expected pytraj.core.c_core.AtomMask, got str)

ini = 0 top = traj.top for frame in traj: top.set_reference(traj[ini]) indices = traj.top.select(':ACE<:5.0|:ACE, NME') residues = [res.original_resid for res in top[indices].residues] for l in residues: res_id = "\':" + str(l) + "\'" atom_indices = top.select(':225')

com = frame.center_of_mass(':225') <---- here ask me for pytraj.core.c_core.AtomMask

    coor = frame.xyz[atom_indices]
    #print(com)
ini = ini+1
hainm commented 3 years ago

com = frame.center_of_mass(':225') <---- here ask me for pytraj.core.c_core.AtomMask

It's low level code:

vec = frame.center_of_mass(pt.AtomMask(':225'))
print(vec.values)

Or use the API

pt.center_of_mass(traj, mask= ..., fram_indices=[your_index])

https://github.com/Amber-MD/pytraj/blob/8d4f3a759befeca94de6df76d789276e8263b650/pytraj/all_actions.py#L1552

PS: It might be a good idea for pytraj to accept string. Cheers.

jyosa commented 3 years ago

Excellent thank you now it is working

hainm commented 3 years ago

Great. Happy to close this issue.