//functions for making openbabel easier to work with, adding functionality that isn't in the api(also adding functionality that is in the regular api, but isn't in the C# api), and functions that make debugging less of a pain //this is in a partial class for now, but it would be pretty useful as a library #region functions for converting double arrays to their openbabel counterparts and vice versa public static double[] obvec2dubs(OBVector3 a) { //turns a horrible obvector into a very nice double array double[] b = { a.GetX(), a.GetY(), a.GetZ() }; return(b); }
// public static bool isInCone(OBVector3 x, OBVector3 apex, OBVector3 axis, double aperture ) // { // //got it from here:http://stackoverflow.com/questions/10768142/verify-if-point-is-inside-a-cone-in-3d-space // //test if point x is inside an infinite cone defined by apex point with normal vector axis and aperture angle(in radians) // double halfAperture=aperture/2; // OBVector3 apexToXVect = OBVector3(apex,x); // OBVector3. // bool insideCone = StarMath.dotProduct(apex,axis)/StarMath.norm2(apexToXVect)/StarMath.norm2(axis) > Math.Cos(aperture); // return insideCone; // } public static bool atomsInCarboxylateCone(OBAtom a, OBAtom carba, OBMol mol) { //angle should probably not be hardcoded double aperture = 120 * Math.PI / 180; double[] axis = obvec2dubs(OBVector3.Sub(carba.GetVector(), a.GetVector())); //axis = StarMath.divide (axis, StarMath.norm2 (axis)); double[] apex = obvec2dubs(carba.GetVector()); List <uint> exclude = new List <uint>(); exclude.Add(carba.GetIdx()); foreach (OBBond b in carba.Bonds()) { OBAtom other = b.GetNbrAtom(carba); if (other != a) { exclude.Add(other.GetIdx()); } } foreach (OBAtom n in mol.Atoms()) { if (!exclude.Contains(n.GetIdx())) { double[] x = obvec2dubs(n.GetVector()); //if any point is found to be in the carboxylate's cone, return true if (isInCone(x, apex, axis, aperture)) { return(true); } } } return(false); }
public static double radial_weight(OBMol mol, OBAtom carbon1, OBAtom a1) { OBVector3 compos = mol_com(mol); OBVector3 v2 = carbon1.GetVector(); OBVector3 v3 = a1.GetVector(); return(openbabel_csharp.Point2Line(compos, v2, v3)); }
public static double atomdist(OBAtom a0, OBAtom a1) { OBVector3 disp = OBVector3.Sub(a0.GetVector(), a1.GetVector()); double x = disp.GetX(); double y = disp.GetY(); double z = disp.GetZ(); double dist = Math.Sqrt(x * x + y * y + z * z); return(dist); }
public static double atom2linedistance(OBAtom x0, OBAtom a1, OBAtom a2) { //a1 and a2 are atoms that define the axis in question, x0 is the atom that we want to know the distance from the axis OBVector3 v0 = x0.GetVector(); OBVector3 v1 = a1.GetVector(); OBVector3 v2 = a2.GetVector(); return(openbabel_csharp.Point2Line(v0, v1, v2)); }
public static double pairwiseangle(OBAtom carbon1, OBAtom a1, OBAtom carbon2, OBAtom a2) { //carbon1 and carbon2 are carbon atoms connected to oxygen //a1 and a2 connect to carbon1 and carbon2 respectively OBVector3 vec1 = OBVector3.Sub(carbon1.GetVector(), a1.GetVector()); OBVector3 vec2 = OBVector3.Sub(carbon2.GetVector(), a2.GetVector()); double angle = angle_between_vectors(vec1, vec2); return(angle); }
public static OBVector3 mol_com(OBMol mol) { //center of mass of molecule OBVector3 sum = OBVector3.VZero; double molw = 0; foreach (OBAtom a in mol.Atoms()) { double m = a.GetAtomicMass(); sum = OBVector3.Add(sum, OBVector3.Mul(m, a.GetVector())); molw = molw + m; } return(OBVector3.Mul(1 / molw, sum)); }
public static double angle_between_vectors(OBVector3 a, OBVector3 b) { a = a.Normalize(); b = b.Normalize(); double dot = StarMath.dotProduct(obvec2dubs(a), obvec2dubs(b)); double angle = Math.Acos(dot) * 180 / Math.PI; if (double.IsNaN(angle)) { angle = Math.Acos(Convert.ToInt32(dot)) * 180 / Math.PI; } return(angle); }
public static double greatest_radial_distance(OBMol mol, OBAtom carbon1, OBAtom a1) { OBVector3 v2 = carbon1.GetVector(); OBVector3 v3 = a1.GetVector(); double maxd = 0; foreach (OBAtom a in mol.Atoms()) { OBVector3 v1 = a.GetVector(); double d = openbabel_csharp.Point2Line(v1, v2, v3); if (d > maxd) { maxd = d; } } return(maxd); }
public static OBMol connect_within_radius(OBMol mol, OBAtom n, double radius) { foreach (OBAtom a in mol.Atoms()) { if (a.GetIdx() == n.GetIdx()) { continue; } else { double len = Math.Round(StarMath.norm2(obvec2dubs(OBVector3.Sub(a.GetVector(), n.GetVector()))), 7); //gets length if (len <= radius) { mol.AddBond((int)a.GetIdx(), (int)n.GetIdx(), 1); } } } return(mol); }
public static OBMol merge_atoms_at_same_location(OBMol mol) { double radius = 0.1; //when we make a unit_cell by copy and pasting base cases we end up with atoms at the same location that need to be merged //assumes only two atoms overlap at a time Dictionary <int, int> tomerge = new Dictionary <int, int>(); foreach (OBAtom a in mol.Atoms()) { if (!tomerge.ContainsKey((int)a.GetIdx())) { foreach (OBAtom b in mol.Atoms()) { if (a.GetIdx() == b.GetIdx()) { continue; } else { double len = Math.Round(StarMath.norm2(obvec2dubs(OBVector3.Sub(a.GetVector(), b.GetVector()))), 7); //gets length if (len <= radius) { tomerge.Add((int)b.GetIdx(), (int)a.GetIdx()); } } } } } int atomsdeleted = 0; foreach (int key in tomerge.Keys) { mol = molecule_merge(mol, mol.GetAtom(key - atomsdeleted), mol.GetAtom(tomerge[key] - atomsdeleted)); atomsdeleted++; } return(mol); }
public static double greatest_axial_distance(OBMol mol, OBAtom carbon1, OBAtom a1) { //finds the distance of the most distant atom along the axis defined by the carboxyl defined by carbon 1 and a1 double[] vec = obvec2dubs(OBVector3.Sub(carbon1.GetVector(), a1.GetVector())); vec = StarMath.normalize(vec); double maxd = 0; foreach (OBAtom a in mol.Atoms()) { if (a == carbon1) { continue; } double d = StarMath.dotProduct(vec, obvec2dubs(OBVector3.Sub(carbon1.GetVector(), a.GetVector()))); // get pairwise axial distance by taking the scalar projection of the carbon's position to atom A if (d > maxd) { maxd = d; } } return(maxd); }
public static void trajectoryFrameToCIF(string frame, string outFile, List <int> esequence, OBConversion obconv) { //converts a frame from the above function into a CIF file //lammps trajectory files have unit cell dimension data for every frame //requires an element sequence for identifying element type from lammps atom types OBUnitCell uc = new OBUnitCell(); OBMol mol = new OBMol(); OBMatrix3x3 mat = new OBMatrix3x3(); using (StringReader reader = new StringReader(frame)) { string line = ""; bool foundMatrix = false; do { line = reader.ReadLine(); if (line.Contains("BOX BOUNDS")) { //data from lammps is in this format //ITEM: BOX BOUNDS xy xz yz //xlo_bound xhi_bound xy //ylo_bound yhi_bound xz //zlo_bound zhi_bound yz string row0 = reader.ReadLine(); double[] row0d = OBFunctions.spacedStringToDoubleArray(row0); double xlo = row0d[0]; double xhi = row0d[1]; double xy = row0d[2]; string row1 = reader.ReadLine(); double[] row1d = OBFunctions.spacedStringToDoubleArray(row1); double ylo = row1d[0]; double yhi = row1d[1]; double xz = row1d[2]; string row2 = reader.ReadLine(); double[] row2d = OBFunctions.spacedStringToDoubleArray(row2); double zlo = row2d[0]; double zhi = row2d[1]; double yz = row2d[2]; //adjust box bounds, taken from VMD's source for reading lammps files double xdelta = Math.Min(0, xy); xdelta = Math.Min(xdelta, xz); xdelta = Math.Min(xdelta, xy + xz); xlo = xlo - xdelta; xdelta = Math.Max(0, xy); xdelta = Math.Max(xdelta, xz); xdelta = Math.Max(xdelta, xy + xz); xhi = xhi - xdelta; ylo = ylo - Math.Min(0, yz); yhi = yhi - Math.Max(0, yz); OBVector3 A = new OBVector3(xhi - xlo, 0, 0); OBVector3 B = new OBVector3(xy, yhi - ylo, 0); OBVector3 C = new OBVector3(xz, yz, zhi - zlo); //OBVector3 A = new OBVector3 (xhi-xlo, xy, xz); //OBVector3 B = new OBVector3 (0, yhi-ylo, yz); //OBVector3 C= new OBVector3 (0, 0, zhi-zlo); mat = new OBMatrix3x3(A, B, C); uc.SetData(A, B, C); foundMatrix = true; } } while (!foundMatrix); //uc.SetData (mat); bool foundAtoms = false; do { line = reader.ReadLine(); if (line.Contains("ITEM: ATOMS")) { foundAtoms = true; } } while (!foundAtoms); while ((line = reader.ReadLine()) != null) { string[] splitline = line.Split((char[])null, StringSplitOptions.RemoveEmptyEntries); int lammpstype = Convert.ToInt32(splitline[1]) - 1; int atype = esequence[lammpstype]; OBAtom a = new OBAtom(); a.SetAtomicNum(atype); //position in fraction coordinates OBVector3 fvec = new OBVector3(Convert.ToDouble(splitline[3]), Convert.ToDouble(splitline[4]), Convert.ToDouble(splitline[5])); //OBVector3 fvec = new OBVector3 (Convert.ToDouble (splitline [2]), Convert.ToDouble (splitline [3]), Convert.ToDouble (splitline [4])); //convert to cartesian. OBVector3 cvec = uc.FractionalToCartesian(fvec); a.SetVector(cvec); mol.AddAtom(a); } mol.CloneData(uc); obconv.SetOutFormat("cif"); obconv.AddOption("b"); obconv.WriteFile(mol, outFile); } }
public static OBVector3 dubs2obvec(double[] a) { OBVector3 b = new OBVector3(a[0], a[1], a[2]); return(b); }