public void ChangeParent(Node parent) { if (Parent.Parent != null) { Parent.ChangeParent(this); } Parent.Children.Remove(this); parent.AddChild(this); }
public static SuperCell ReadMol2_complex(string fileName, int atomsPerCell) { SuperCell superCell = new SuperCell(); superCell.isError = false; superCell.isParent = true; superCell.errorType = SuperCellError.NoError; superCell.filePath = fileName; #region RawDataReader Queue<string> atomLines = new Queue<string>(); List<string> bondLines = new List<string>(); StreamReader reader = File.OpenText(fileName); string line; bool startReading = false; bool bondsPresent = false; bool latticePresent = false; while (true) { if (startReading) { while ((line = reader.ReadLine()) != null) { if (line == "@<TRIPOS>BOND") { bondsPresent = true; break; } else { atomLines.Enqueue(line); } } break; } else { line = reader.ReadLine(); if (line == "@<TRIPOS>ATOM") startReading = true; } } if (bondsPresent) { while ((line = reader.ReadLine()) != null) { if (line == "@<TRIPOS>CRYSIN") { latticePresent = true; break; } else { bondLines.Add(line); } } } else { superCell.isError = true; superCell.errorType = SuperCellError.Base_NoBonds; return superCell; } string latticeLine; if (!latticePresent) { superCell.isError = true; superCell.errorType = SuperCellError.Base_NoLattice; return superCell; } else { latticeLine = reader.ReadLine(); } #endregion #region OrderFinder Queue<int[]> bondsQueue = new Queue<int[]>(); Queue<int> bondTypesQueue = new Queue<int>(); int[] tempBond; int numBonds = 0; while (true) { string[] items = bondLines[bondsQueue.Count].Split(' '); tempBond = new int[2] { int.Parse(items[1]), int.Parse(items[2]) }; if (tempBond[0] > atomsPerCell || tempBond[1] > atomsPerCell) { break; } else { bondsQueue.Enqueue(tempBond); bondTypesQueue.Enqueue(int.Parse(items[3])); numBonds++; } } Node headNode = new Node(); Node thisAtom; superCell.bonds = new int[bondsQueue.Count, 2]; superCell.bondTypes = new int[bondsQueue.Count]; int count = 0; while (bondsQueue.Count > 0) { tempBond = bondsQueue.Dequeue(); superCell.bonds[count, 0] = tempBond[0]; superCell.bonds[count, 1] = tempBond[1]; superCell.bondTypes[count] = bondTypesQueue.Dequeue(); thisAtom = headNode.SearchChildren(tempBond[0]); if (thisAtom != null) { Node otherAtom = headNode.SearchChildren(tempBond[1]); if (otherAtom != null) { otherAtom.ChangeParent(thisAtom); } else { thisAtom.AddChild(new Node(tempBond[1])); } } else { Node otherAtom = headNode.SearchChildren(tempBond[1]); if (otherAtom != null) { otherAtom.AddChild(new Node(tempBond[0])); } else { Node tempNode = new Node(tempBond[0]); headNode.AddChild(tempNode); tempNode.AddChild(new Node(tempBond[1])); } } count++; } if (headNode.Children.Count > 0) { superCell.order = headNode.FindOrder(); } else { superCell.isError = true; superCell.errorType = SuperCellError.Base_CouldntFindOrder; return superCell; } #endregion #region RawDataProcessor int numAtoms = atomLines.Count; int molsPerCell = superCell.order.GetLength(0); int atomsPerMol = superCell.order.GetLength(1); int numCells = numAtoms / atomsPerCell; int numMols = molsPerCell*numCells; superCell.types = new string[atomsPerCell]; superCell.mols = new List<Molecule>(); for (int cell = 0; cell < numCells; cell++) { double[,] atomsBuffer = new double[atomsPerCell, 3]; for (int atom = 0; atom < atomsPerCell; atom++) { string[] items = atomLines.Dequeue().Split(' '); if (cell == 0) { if (items[5].Length > 2) { superCell.types[atom] = items[5].Remove(items[5].Length - 2); } else { superCell.types[atom] = items[5]; } } atomsBuffer[atom, 0] = double.Parse(items[2]); atomsBuffer[atom, 1] = double.Parse(items[3]); atomsBuffer[atom, 2] = double.Parse(items[4]); } for (int mol = 0; mol < molsPerCell; mol++) { double[,] thisMol = new double[atomsPerMol, 3]; for (int atom = 0; atom < atomsPerMol; atom++) { thisMol[atom, 0] = atomsBuffer[superCell.order[mol, atom], 0]; thisMol[atom, 1] = atomsBuffer[superCell.order[mol, atom], 1]; thisMol[atom, 2] = atomsBuffer[superCell.order[mol, atom], 2]; } superCell.mols.Add(new Molecule(thisMol, true)); } } superCell.centroids = DenseMatrix.Create(numMols, 3, 0); superCell.directions = DenseMatrix.Create(numMols, 3, 0); count = 0; foreach (Molecule mol in superCell.mols) { superCell.centroids.SetRow(count, mol.centroid); superCell.directions.SetRow(count, mol.direction); count++; } #endregion #region LatticeFinder string[] latticeItems = latticeLine.Split(' '); double[,] incompleteLattice = new double[2, 3] { { double.Parse(latticeItems[0]), double.Parse(latticeItems[1]), double.Parse(latticeItems[2]) }, { double.Parse(latticeItems[3]), double.Parse(latticeItems[4]), double.Parse(latticeItems[5]) } }; superCell.latticeParams = new double[2, 3] { { 0.0, 0.0, 0.0 }, { incompleteLattice[1, 0], incompleteLattice[1, 1], incompleteLattice[1, 2] } }; superCell.superCellSize = new int[3] { 0, 0, 0 }; superCell.latticeVectors = DenseMatrix.OfArray(new double[,] { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }); bool[] cellDone = new bool[3] { false, false, false }; double tempA; double tempB; double tempC; int cellA=0; int cellB=0; int cellC=0; if (numMols > 1) { for (int i = 0; i < 3; i++) { tempA = (superCell.mols[molsPerCell].centroid - superCell.mols[0].centroid).L2Norm(); double tempLatticeRatio = incompleteLattice[0, i] / tempA; if (Math.Abs(tempLatticeRatio - Math.Round(tempLatticeRatio)) < 0.001) { cellA = (int)Math.Round(tempLatticeRatio); superCell.superCellSize[i] = cellA; superCell.latticeParams[0, i] = tempA; cellDone[i] = true; superCell.latticeVectors.SetColumn(i, superCell.mols[molsPerCell].centroid - superCell.mols[0].centroid); break; } } } else { superCell.isError = true; superCell.errorType = SuperCellError.Base_SingleMol; return superCell; } if (numMols > cellA) { for (int i = 0; i < 3; i++) { if (cellDone[i] == true) continue; tempB = (superCell.mols[cellA*molsPerCell].centroid - superCell.mols[0].centroid).L2Norm(); double tempLatticeRatio = incompleteLattice[0, i] / tempB; if (Math.Abs(tempLatticeRatio - Math.Round(tempLatticeRatio)) < 0.001) { cellB = (int)Math.Round(tempLatticeRatio); superCell.superCellSize[i] = cellB; superCell.latticeParams[0, i] = tempB; cellDone[i] = true; superCell.latticeVectors.SetColumn(i, superCell.mols[cellA*molsPerCell].centroid - superCell.mols[0].centroid); break; } } } else { superCell.isError = true; superCell.errorType = SuperCellError.Base_LineCell; return superCell; } if (numMols > cellA * cellB) { for (int i = 0; i < 3; i++) { if (cellDone[i] == true) continue; tempC = (superCell.mols[cellA * cellB * molsPerCell].centroid - superCell.mols[0].centroid).L2Norm(); double tempLatticeRatio = incompleteLattice[0, i] / tempC; if (Math.Abs(tempLatticeRatio - Math.Round(tempLatticeRatio)) < 0.001) { cellC = (int)Math.Round(tempLatticeRatio); superCell.superCellSize[i] = cellC; superCell.latticeParams[0, i] = tempC; cellDone[i] = true; superCell.latticeVectors.SetColumn(i, superCell.mols[cellA*cellB*molsPerCell].centroid - superCell.mols[0].centroid); break; } } } else { int cIndex = 3; for (int i = 0; i < 3; i++) { if (cellDone[i] == false) cIndex = i; } superCell.superCellSize[cIndex] = 1; superCell.latticeParams[0,cIndex] = incompleteLattice[0, cIndex]; superCell.latticeVectors.SetColumn(cIndex, FindCVect(superCell.latticeVectors.Column((cIndex + 1) % 3), superCell.latticeVectors.Column((cIndex + 2) % 3), superCell.latticeParams[1, (cIndex + 1) % 3], superCell.latticeParams[1, (cIndex + 2) % 3], superCell.latticeParams[0, cIndex])); } #endregion superCell.CalculateDirectionDerivatives(); return superCell; }
public Node(int mol, Node parent) { AtomNumber = mol; parent.AddChild(this); Children = new List<Node>(); }