-
Notifications
You must be signed in to change notification settings - Fork 0
/
Atom.java
178 lines (157 loc) · 5.64 KB
/
Atom.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
import org.apache.commons.math3.geometry.euclidean.threed.*;
import java.io.*;
import java.util.*;
import com.google.common.collect.*;
/**
* Represents an atom. This class is immutable.
*/
public class Atom implements Immutable, Serializable, Comparable<Atom>
{
/** For serialization. */
public static final long serialVersionUID = 1L;
/** Atomic element. */
public final Element element;
/** Location of the atom. */
public final Vector3D position;
/** AMOEBA atom type. */
public final int type1;
/** OPLS atom type. */
public final int type2;
/** The surface tension of this atom in kcal/angstroms^2. */
public final double surfaceTension;
/**
* Constructs a new atom.
* @param symbol the atomic symbol
* @param position the location of the atom
* @param type1 the AMOEBA atom type
* @param type2 the OPLS atom type
* @param surfaceTension the surface tension of this atom in kcal/angstroms^2
*/
public Atom(String symbol, Vector3D position, int type1, int type2, double surfaceTension)
{
this(Element.getElement(symbol), position, type1, type2, surfaceTension);
}
/** Constructs a new Atom. */
public Atom(Element element, Vector3D position, int type1, int type2, double surfaceTension)
{
this.element = element;
this.position = position;
if ( type1 < 0 || type2 < 0 )
throw new IllegalArgumentException("negative atom type");
this.type1 = type1;
this.type2 = type2;
this.surfaceTension = surfaceTension;
}
/**
* Compares the location of one atom to another using a comparison chart.
* @param a the atom being compared to this atom
* @return an int representing the result of the comparison (1 - same, 0 - different location)
*/
@Override
public int compareTo(Atom a)
{
double x1 = position.getX();
double x2 = a.position.getX();
double y1 = position.getY();
double y2 = a.position.getY();
double z1 = position.getZ();
double z2 = a.position.getZ();
return ComparisonChain.start().compare(x1, x2).compare(y1, y2).compare(z1, z2).result();
}
/**
* Returns a copy of this atom with a new atom type.
* @param newType1 the AMOEBA atom type for the new atom
* @param newType2 the OPLS atom type for the new atom
* @return a new atom with updated atom types
*/
public Atom setAtomType(int newType1, int newType2)
{
return new Atom(element, position, newType1, newType2, surfaceTension);
}
public Atom changeTypes(Atom anotherAtom)
{
return new Atom(element, position, anotherAtom.type1, anotherAtom.type2, anotherAtom.surfaceTension);
}
/**
* Returns a copy of this atom with a new position.
* @param newPosition the new position
* @return the new atom
*/
public Atom moveAtom(Vector3D newPosition)
{
return new Atom(element.symbol, newPosition, type1, type2, surfaceTension);
}
/**
* Rotates and translates this atom. The rotation is applied before the translation.
* @param rot a three-dimensional rotation.
* @param shift a vector that we add to the position of this after it has been rotated.
* @return the new atom
*/
public Atom transform(Rotation rot, Vector3D shift)
{
return new Atom(element.symbol, rot.applyTo(position).add(shift), type1, type2, surfaceTension);
}
/**
* Convenience method for moving an atom based on a map of old atoms and new atoms.
* @param atomMap a map from old atoms to new atoms
* @return the new atom if applicable
*/
public Atom moveAtom(Map<Atom,Atom> atomMap)
{
if (atomMap.containsKey(this))
return atomMap.get(this);
else
return this;
}
@Override
public String toString()
{
return String.format("%-2s %10.6f %10.6f %10.6f", element.symbol, position.getX(), position.getY(), position.getZ());
}
public String toFullString()
{
return String.format("%-2s %10.6f %10.6f %10.6f %3d %3d %7.4f", element.symbol, position.getX(), position.getY(), position.getZ(), type1, type2, surfaceTension);
}
@Override
public int hashCode()
{
return Objects.hash(element, position, type1, type2, surfaceTension);
}
@Override
public boolean equals(Object obj)
{
if ( obj == null )
return false;
else if ( obj == this )
return true;
else if ( !(obj instanceof Atom) )
return false;
Atom a = (Atom)obj;
if ( element == a.element &&
position.equals(a.position) &&
type1 == a.type1 &&
type2 == a.type2 &&
surfaceTension == a.surfaceTension )
return true;
return false;
}
/** For testing. */
public static void main(String[] args)
{
Atom atom1 = new Atom("C", new Vector3D(1.0, 2.0, 3.0), 103, 10, 0.0);
Atom atom2 = new Atom("C", new Vector3D(2.0, 2.0, 3.0), 103, 10, 0.0);
Atom atom3 = new Atom("C", new Vector3D(3.0, 3.0, 3.0), 103, 10, 0.0);
Atom atom4 = new Atom("C", new Vector3D(3.0, 2.0, 3.0), 103, 10, 0.0);
Atom atom5 = new Atom("C", new Vector3D(3.0, 2.0, 4.0), 103, 10, 0.0);
List<Atom> list = new LinkedList<>();
list.add(atom2);
list.add(atom1);
list.add(atom3);
list.add(atom4);
list.add(atom5);
Collections.shuffle(list);
Collections.sort(list);
for (Atom a : list)
System.out.println(a);
}
} // end of class Atom