Re: [PyMOL] Delete atoms out of unit cell box

I have tweaked a script by Tsjerk Wassenaar that can remove atoms out of a unit cell. I have encountered 2 problems. First is even though i knew the Atom i wanted to remove from the model i had no easy way to do it because i didn't found any unique identifier for an Atom in the atom class.
```So what i did was to treat each object separately. This seems to work.
```
The other problem is that pymol segfaults with big selections. I think the problem is the number of
`logical operations in the selection and not the string size.`
```
Here is the script:

from pymol import cmd
import math

```
## Determining the determinant of matrix a ##
```
def det(a):
```
return a[0][0]*(a[1][1]*a[2][2]-a[2][1]*a[1][2])-a[1][0]*(a[0][1]*a[2][2]-a[2][1]*a[0][2])+a[2][0]*(a[0][1]*a[1][2]-
```
a[1][1]*a[0][2])

```
## Basic inversion of a 3x3-matrix a ##
```def minv(a):
c = 1/det(a)
return [[ c*(a[1][1]*a[2][2]-a[2][1]*a[1][2]),
-c*(a[0][1]*a[2][2]-a[2][1]*a[0][2]),
c*(a[0][1]*a[1][2]-a[1][1]*a[0][2]) ],
[ -c*(a[1][0]*a[2][2]-a[2][0]*a[1][2]),
c*(a[0][0]*a[2][2]-a[2][0]*a[0][2]),
-c*(a[0][0]*a[1][2]-a[1][0]*a[0][2]) ],
[ c*(a[1][0]*a[2][1]-a[2][0]*a[1][1]),
-c*(a[0][0]*a[2][1]-a[2][0]*a[0][1]),
c*(a[0][0]*a[1][1]-a[1][0]*a[0][1]) ]]

```
## Multiplying a vector b by matrix a ##
```def mvmult(a, b):
return [ a[0][0]*b[0]+a[0][1]*b[1]+a[0][2]*b[2],
a[1][0]*b[0]+a[1][1]*b[1]+a[1][2]*b[2],
a[2][0]*b[0]+a[2][1]*b[1]+a[2][2]*b[2] ]

##############################################
```
## Protein / image operations ################
```##############################################
```
# p should be the pdb molecule from which the # unit cell information will be derived
```
def rmoutside(p = None):
if p == None:
print '# Error: No box specified! #'
return
objects = cmd.get_names("objects")
cmd.select("out_of_box","none")
for j in range(len(objects)):
print objects[j]
if(cmd.get_type(objects[j]) == "object:molecule"):
sel = "("+str(objects[j])+")"
sel = cmd.get_model(sel)
par = cmd.get_symmetry(p)
par[3] = par[3]/360*2*math.pi
par[4] = par[4]/360*2*math.pi
par[5] = par[5]/360*2*math.pi

v_a = [par[0],0,0]
v_b = [math.cos(par[5])*par[1],math.sin(par[5])*par[1],0]
v_c = [par[2]*math.cos(par[4]),

par[1]*par[2]*math.cos(par[3])-par[2]*math.cos(par[4])*v_b[0],

math.sqrt(par[2]*par[2]-par[2]*math.cos(par[4])*par[2]*math.cos(par[4])-

par[1]*par[2]*math.cos(par[3])-par[2]*math.cos(par[4])*v_b[0]*par[1]*par[2]*math.cos(par[3])-par[2]*math.cos(par[4])*v_b[0])]
b = [ v_a,v_b,v_c ]

```
# b should now be a box-matrix: [ [ x1, y1, z1 ], [ x2, y2, z2 ], [ x3, y3, z3 ] ]
```            S = [ [b[0][0], b[1][0], b[2][0]],
[b[0][1], b[1][1], b[2][1]],
[b[0][2], b[1][2], b[2][2]] ]
T = minv(S)
list = "out_of_box";
for i in range(len(sel.atom)):
sel.atom[i].coord = mvmult(T, sel.atom[i].coord)
```
if sel.atom[i].coord[0] < 0 or sel.atom[i].coord[0] > 1 or sel.atom[i].coord[1] < 0 or sel.atom[i].coord[1] > 1 or sel.atom[i].coord[2] < 0 or se\
```l.atom[i].coord[2] > 1:
```
list = "(index "+str(sel.atom[i].index)+" and "+str(objects[j])+") or " + list
```
```
# this is to try to make sure pymol doesn't seg fault # so when we already have a big list for selection make the selection and empty the list
```                    if(len(list) > 2000):
cmd.select("out_of_box", list)
list = "out_of_box"
else:
sel.atom[i].coord = mvmult(S, sel.atom[i].coord)
cmd.select("out_of_box", list)

```