UnityMol  0.9.6-875
UnityMol viewer / In developement
AtomTree.cs
Go to the documentation of this file.
1 using UnityEngine;
2 using System.Collections;
3 using System.Collections.Generic;
4 using Molecule.Model;
5 
6 public class AtomTree {
7  private List<string> types;
8  private List<Vector3> positions;
9  private List<Color> colors;
10  private Vector3 bound0, bound1, split;
11  private AtomTree[] children;
12  private bool isLeaf = true;
13  private static int MAX_ATOMS = 8;
14  //private static Vector3 candidatePos;
15  private static Color candidateCol;
16  private static float candidateDist;
17 
18  public AtomTree(Vector3 b0, Vector3 b1) {
19  split = 0.5f * (b0 + b1); // Middle of the cube
20  bound0 = b0;
21  bound1 = b1;
22  positions = new List<Vector3>();
23  types = new List<string>();
24  colors = new List<Color>();
25  children = new AtomTree[8];
26  }
27 
28  private int GetChildIndex(Vector3 p) {
29  int childIndex = 0;
30 
31  if(p.x > split.x)
32  childIndex |= 1;
33  if(p.y > split.y)
34  childIndex |= 2;
35  if(p.z > split.z)
36  childIndex |= 4;
37 
38  return childIndex;
39  }
40 
41  private Vector3 GetOffset(Vector3 b0, Vector3 b1, int i) {
42  Vector3 result;
43  switch(i) {
44  case 0:
45  result = Vector3.zero;
46  break;
47  case 1:
48  result = new Vector3(b1.x, 0, 0);
49  break;
50  case 2:
51  result = new Vector3(0, b1.y, 0);
52  break;
53  case 3:
54  result = new Vector3(b1.x, b1.y, 0);
55  break;
56  case 4:
57  result = new Vector3(0, 0, b1.z);
58  break;
59  case 5:
60  result = new Vector3(b1.x, 0, b1.z);
61  break;
62  case 6:
63  result = new Vector3(0, b1.y, b1.z);
64  break;
65  case 7:
66  result = b1;
67  break;
68  default:
69  Debug.Log("VertexTree::Offset() > Something is very, very wrong here.");
70  result = Vector3.zero;
71  break;
72  }
73  return 0.5f * result;
74  }
75 
76  private void AddAtomToLeaf(Vector3 pos, string type, Color col) {
77  positions.Add(pos);
78  types.Add(type);
79  colors.Add(col);
80 
81  // If the addition brings the cube to the limit of atoms
82  if(positions.Count >= MAX_ATOMS)
83  Subdivide();
84  }
85 
86  private void Subdivide() {
87  Vector3 oppositeBound = bound1 - bound0;
88  Vector3 offset;
89 
90  // Creating the sub-cubes.
91  for(int i=0; i<8; i++) {
92  offset = GetOffset(bound0, oppositeBound, i);
93  children[i] = new AtomTree(bound0+offset, split+offset);
94  }
95 
96  // Sending the atoms (and corresponding types) to the correct sub-cubes.
97  int childIndex;
98  for(int i=0; i<MAX_ATOMS; i++) {
99  childIndex = GetChildIndex(positions[i]);
100  children[childIndex].AddAtomToLeaf(positions[i], types[i], colors[i]);
101  }
102 
103  // Now this cube is not a leaf anymore, but a node.
104  // It must be cleared, and no more atoms should be added to it.
105  positions.Clear();
106  types.Clear();
107  colors.Clear();
108 
109  isLeaf = false;
110  }
111 
112  private void AddAtom(Vector3 pos, string type, Color col) {
113  if(isLeaf) {
114  positions.Add(pos);
115  types.Add(type);
116  colors.Add(col);
117 
118  // If the addition brings the cube to the limit of atoms
119  if(positions.Count >= MAX_ATOMS)
120  Subdivide();
121  return;
122  }
123 
124  // If the function has not returned yet, then this is a node, not a leaf.
125  // So we just find the correct sub-cube for the recursive call.
126  int childIndex = GetChildIndex(pos);
127  children[childIndex].AddAtom(pos, type, col);
128  }
129 
130  private bool IsEmpty() {
131  return(isLeaf && positions.Count == 0);
132  }
133 
134  private AtomTree GetOptimalChild(Vector3 pos) {
135  AtomTree optimal = null;
136  float minDist = float.MaxValue;
137  float dist;
138  foreach(AtomTree child in children) {
139  if(!child.IsEmpty()) {
140  dist = Vector3.SqrMagnitude(child.split - pos);
141  //dist = Vector3.Distance(child.split, pos);
142  if(dist < minDist) {
143  minDist = dist;
144  optimal = child;
145  }
146  }
147  }
148  return optimal;
149  }
150 
151  public string GetClosestAtomType(Vector3 pos) {
152  string type=""; // it should not remain empty
153  if(isLeaf) {
154  float lowestDistance = float.MaxValue;
155  float dist;
156  for(int i=0; i<positions.Count; i++) {
157  dist = Vector3.SqrMagnitude(pos - positions[i]);
158  //dist = Vector3.Distance(pos, positions[i]);
159  if(dist < lowestDistance) {
160  lowestDistance = dist;
161  type = types[i];
162  }
163  }
164  return type;
165  }
166 
167  // If the function has not returned yet, then this is a node, not a leaf.
168  // So we just find the correct sub-cube for the recursive call.
169  int childIndex = GetChildIndex(pos);
170  type = children[childIndex].GetClosestAtomType(pos);
171  if (type != "")
172  return type;
173  else
174  return GetOptimalChild(pos).GetClosestAtomType(pos);
175  }
176 
177  public Color GetClosestAtomColor(Vector3 pos) {
178  candidateCol = Color.magenta;
179  // candidatePos = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
180  candidateDist = float.MaxValue;
182  return candidateCol;
183  //return SubGetClosestAtomColor(pos);
184  }
185 
186  public void SubGetClosestAtomColor(Vector3 pos) {
187  Debug.Log ("isLeaf " + isLeaf);
188  Debug.Log ("Taille colors " + colors.Count);
189  Debug.Log ("Positions " + positions.Count);
190  if(isLeaf) {
191  float dist;
192  for(int i=0; i<positions.Count; i++) {
193  dist = Vector3.SqrMagnitude(pos - positions[i]);
194  if(dist < candidateDist) {
195  candidateDist = dist;
196  candidateCol = colors[i];
197  // candidatePos = positions[i];
198  }
199  }
200  }
201  return;
202 
203  // If the function has not returned yet, then this is a node, not a leaf.
204  // So we just find the correct sub-cube for the recursive call.
205  int childIndex = GetChildIndex(pos);
206  AtomTree optChild = children[childIndex];
207  if(optChild.isLeaf) {
208  foreach(AtomTree child in children) {
209  child.SubGetClosestAtomColor(pos);
210  }
211  } else {
212  optChild.SubGetClosestAtomColor(pos);
213  }
214  }
215 
216  public void Print() {
217  if(isLeaf) {
218  for(int i=0; i<positions.Count; i++) {
219  Debug.Log("Type: " + types[i] + " and position: " + positions[i].ToString());
220  }
221  return;
222  }
223 
224  // If the function has not returned yet, then this is a node, not a leaf.
225  // So we just call the function on ALL children.
226  foreach(AtomTree atomTree in children)
227  if(atomTree != null)
228  atomTree.Print();
229  }
230 
231  public static AtomTree Build() {
232  //List<string> typeList = new List<string>();
233  //List<Vector3> posList = new List<Vector3>();
235  List<AtomModel> atomModels = MoleculeModel.atomsTypelist;
236  List<string> atomChain = MoleculeModel.atomsChainList;
237  List<float[]> atomLocations = MoleculeModel.atomsLocationlist;
238  List<string> atomResname = MoleculeModel.atomsResnamelist;
239  List<float> BfactorList = MoleculeModel.BFactorList;
240  List<int> atomsNumberList = MoleculeModel.atomsNumberList;
241  int nbres = 0;
242  string type;
243 
244  System.Diagnostics.Debug.Assert(atomModels.Count == atomLocations.Count);
245  //System.Diagnostics.Debug.Assert(atomChain.Count == atomLocations.Count);
246  for(int i=0; i<atomModels.Count; i++) {
247  //for(int i=0; i<atomChain.Count; i++) {
248  //string type = atomModels[i].type;
250  if(i > 0 && atomResname[i] != atomResname[i-1])
251  nbres++;
252  if(i>0 && atomChain[i] != atomChain[i-1])
253  nbres = 1;
254  // Coloration by domains (only for GLIC)
255  if(nbres > 182 && UI.UIData.isGLIC)
256  type = atomChain[i] + "L";
257  else
258  type = atomChain[i];
259  }
261  type = atomResname[i];
262  else if (UI.UIData.surfColBF)
263  type = BfactorList[i].ToString();
264  else if (UI.UIData.spread_tree) // For Spreading when camera near the structure
265  type = atomsNumberList[i].ToString();
266  else
267  type = atomModels[i].type;
268  Vector3 pos = new Vector3(atomLocations[i][0], atomLocations[i][1], atomLocations[i][2]);
269  //typeList.Add(type);
270  //posList.Add(pos);
271  Color col = MoleculeModel.atomsColorList[i];
272  atomTree.AddAtom(pos, type, col);
273  }
274  return atomTree;
275  }
276 
277 }
bool isLeaf
Definition: AtomTree.cs:12
void AddAtomToLeaf(Vector3 pos, string type, Color col)
Definition: AtomTree.cs:76
static bool surfColBF
Definition: UIData.cs:188
static bool surfColChain
Definition: UIData.cs:181
static Color candidateCol
Definition: AtomTree.cs:15
List< string > types
Definition: AtomTree.cs:7
static AtomTree Build()
Definition: AtomTree.cs:231
bool IsEmpty()
Definition: AtomTree.cs:130
static List< string > atomsChainList
The chain of each atom.
void Subdivide()
Definition: AtomTree.cs:86
static List< AtomModel > atomsTypelist
The type of each atom.
static int MAX_ATOMS
Definition: AtomTree.cs:13
Vector3 GetOffset(Vector3 b0, Vector3 b1, int i)
Definition: AtomTree.cs:41
static bool surfColPChim
Definition: UIData.cs:187
Vector3 bound1
Definition: AtomTree.cs:10
static bool surfColHydroKD
Definition: UIData.cs:182
void Print()
Definition: AtomTree.cs:216
void AddAtom(Vector3 pos, string type, Color col)
Definition: AtomTree.cs:112
static float candidateDist
Definition: AtomTree.cs:16
static List< float > BFactorList
Bfactor of each atom.
static bool surfColHydroEng
Definition: UIData.cs:183
string GetClosestAtomType(Vector3 pos)
Definition: AtomTree.cs:151
AtomTree GetOptimalChild(Vector3 pos)
Definition: AtomTree.cs:134
List< Vector3 > positions
Definition: AtomTree.cs:8
!WiP Includes FLAGS of GUI.
Definition: UIData.cs:78
void SubGetClosestAtomColor(Vector3 pos)
Definition: AtomTree.cs:186
static bool isGLIC
Definition: UIData.cs:189
List< Color > colors
Definition: AtomTree.cs:9
static Vector3 MaxValue
The "biggest" corner of the bounding box that encloses the molecule.
static List< Color > atomsColorList
The color of each atom.
int GetChildIndex(Vector3 p)
Definition: AtomTree.cs:28
AtomTree[] children
Definition: AtomTree.cs:11
static Vector3 MinValue
The "smallest" corner of the bounding box that encloses the molecule.
Vector3 bound0
Definition: AtomTree.cs:10
Color GetClosestAtomColor(Vector3 pos)
Definition: AtomTree.cs:177
AtomTree(Vector3 b0, Vector3 b1)
Definition: AtomTree.cs:18
static List< int > atomsNumberList
The number of each atoms (in the PDB file)
static List< string > atomsResnamelist
The name of the residue to which each atom belongs.
Vector3 split
Definition: AtomTree.cs:10
static bool spread_tree
Definition: UIData.cs:190
static bool surfColHydroWO
Definition: UIData.cs:184
Definition: GUIDisplay.cs:66
static bool surfColHydroEis
Definition: UIData.cs:185
static List< float[]> atomsLocationlist
The coordinates of each atom.