/// <summary>
        /// Chi1v atomic valence connectivity index (order 0)
        /// </summary>
        /// <param name="mol"></param>
        /// <returns></returns>
        public static double Chi1v(this OBMol mol)
        {
            var deltas = mol.HkDeltas(false);

            return(mol.Bonds().Where(b => deltas[b.GetBeginAtomIdx() - 1] * deltas[b.GetEndAtomIdx() - 1] > 0)
                   .Select(b => Math.Sqrt(1 / (double)(deltas[b.GetBeginAtomIdx() - 1] * deltas[b.GetEndAtomIdx() - 1]))).Sum());
        }
        /// <summary>
        /// Calculates the approximate surface area contributions for each atom
        /// </summary>
        /// <param name="mol"></param>
        /// <param name="includeHydrogens">Include hydrogens in calculation</param>
        /// <returns></returns>
        public static double[] LabuteASAContributions(this OBMol mol, bool includeHydrogens = true)
        {
            var numAtoms = mol.NumAtoms();
            var Vi       = new double[numAtoms + 1].Zero().ToArray();
            var rads     = new double[numAtoms + 1].Zero().ToArray();

            rads[0] = AtomicConstants.GetRBO(1);
            double Ri, Rj, Bij, Dij;


            // OpenBabel atom numbering is 1-based
            for (var i = 1; i <= numAtoms; i++)
            {
                rads[i] = AtomicConstants.GetRBO(mol.GetAtom(i).GetAtomicNum());
            }

            foreach (var bond in mol.Bonds())
            {
                var beginAtom = bond.GetBeginAtomIdx();
                var endAtom   = bond.GetEndAtomIdx();
                Ri = rads[beginAtom];
                Rj = rads[endAtom];
                var bondOrder = bond.GetBondOrder();
                Bij = !bond.IsAromatic() ? Ri + Rj - BondConstants.BondScaleFactors[bondOrder] : Ri + Rj - BondConstants.BondScaleFactors[0];

                Dij            = Math.Min(Math.Max(Math.Abs(Ri - Rj), Bij), Ri + Rj);
                Vi[beginAtom] += Rj * Rj - Math.Pow((Ri - Dij), 2) / Dij;
                Vi[endAtom]   += Ri * Ri - Math.Pow((Rj - Dij), 2) / Dij;
            }

            if (includeHydrogens)
            {
                Rj = rads[0];
                for (var i = 1; i <= numAtoms; i++)
                {
                    Ri     = rads[i];
                    Bij    = Ri + Rj;
                    Dij    = Math.Min(Math.Max(Math.Abs(Ri - Rj), Bij), Ri + Rj);
                    Vi[i] += Rj * Rj - Math.Pow((Ri - Dij), 2) / Dij;
                    Vi[0] += Ri * Ri - Math.Pow((Rj - Dij), 2) / Dij;
                }
            }
            for (var i = 0; i <= numAtoms; i++)
            {
                Ri    = rads[i];
                Vi[i] = 4 * Math.PI * Math.Pow(Ri, 2) - Math.PI * Ri * Vi[i];
            }
            return(Vi);
        }
        public static OBMol addmol2(OBMol source, OBMol dest)
        {
            //combines two OBMols into one molecule
            // this is designed to do the same thing as the += operator in mol.cpp, in other words this implements functionality present in openbabel, but not in the C# api
            //modifies atom and bond indices in the process
            //dest.BeginModify();
            uint prevatms = dest.NumAtoms();
            uint nextatms = source.NumAtoms();
            uint acount   = prevatms;
            uint bcount   = dest.NumBonds();

            // First, handle atoms and bonds
            foreach (OBAtom atom in source.Atoms())
            {
                atom.SetId(acount); ////Need to remove ID which relates to source mol rather than this mol// But in the C++ it had a NoId thing I couldn't figure out
                dest.AddAtom(atom);
                acount++;
                //var foooo = dest.Atoms ();
            }
            //writeatominfotoscreen (dest);
            foreach (OBBond bond in source.Bonds())
            {
                bond.SetId(bcount);
                OBBond b = new OBBond();
                //b.SetBegin(dest.GetAtom((int)(bond.GetBeginAtomIdx() + prevatms)));
                //b.SetEnd(dest.GetAtom((int)(bond.GetEndAtomIdx() + prevatms)));
                b.Set(0, dest.GetAtom((int)(bond.GetBeginAtomIdx() + prevatms)),
                      dest.GetAtom((int)(bond.GetEndAtomIdx() + prevatms)), (int)bond.GetBO(), (int)bond.GetFlags());
                if (bond.HasData("trueBO"))
                {
                    b.CloneData(bond.GetData("trueBO")); //clone true bond order so we can eventually do MOF-UFF
                }
                dest.AddBond(b);
                //dest.AddBond( (int)bond.GetBO(), (int)bond.GetFlags());

                bcount++;
            }

            //don't really understand what they mean by residues
            //I think it's an amino acid or nucleotide so you can build up proteins and stuff?
            //don't think I'm going to use them either, but it might be useful


            //dest.EndModify(); this tends to mangle up all the atom ids, which is bad

            return(dest);
        }
        public static OBMol addmol(OBMol source, OBMol dest)
        {
            //combines two OBMols into one molecule
            // this is designed to do the same thing as the += operator in mol.cpp, in other words this implements functionality present in openbabel, but not in the C# api
            dest.BeginModify();
            uint prevatms = dest.NumAtoms();
            uint nextatms = source.NumAtoms();

            // First, handle atoms and bonds
            foreach (OBAtom atom in source.Atoms())
            {
                atom.SetId(0); ////Need to remove ID which relates to source mol rather than this mol// But in the C++ it had a NoId thing I couldn't figure out
                dest.AddAtom(atom);
                //var foooo = dest.Atoms ();
            }
            //writeatominfotoscreen (dest);
            foreach (OBBond bond in source.Bonds())
            {
                bond.SetId(0);

                dest.AddBond((int)(bond.GetBeginAtomIdx() + prevatms), (int)(bond.GetEndAtomIdx() + prevatms),
                             (int)bond.GetBO(), (int)bond.GetFlags());
            }

            //don't really understand what they mean by residues
            //I think it's an amino acid or nucleotide so you can build up proteins and stuff?
            //don't think I'm going to use them either, but it might be useful

            foreach (OBResidue residue in source.Residues())
            {
                OBResidue newres = new OBResidue();
                dest.AddResidue(newres);

                OBResidueAtomIter ai = new OBResidueAtomIter(residue);
                //dammit why didn't they implement a residue.atoms sort of thing? I don't want to play with enumerators
                ////#define FOR_ATOMS_OF_RESIDUE(a,r) for( OBResidueAtomIter a(r); a; ++a )
                while (ai.MoveNext())
                {
                    OBAtom resatom = new OBAtom();
                    resatom = ai.Current;
                    // This is the equivalent atom in our combined molecule
                    OBAtom atom = dest.GetAtom((int)(resatom.GetIdx() + prevatms));
                    // So we add this to the last-added residue
                    // (i.e., what we just copied)
                    //[dest.NumResidues () - 1]

                    var res = dest.Residues().GetEnumerator();
                    while (!res.MoveNext())
                    {
                    }                           //move to the last residue
                    res.Current.AddAtom(atom);

                    //var item = dest.Cast<RMSRequestProcessor.RMSMedia> ().ElementAt (1);
                }


                //for(OBAtom resatom in )
            }
            dest.EndModify();

            return(dest);
        }
 /// <summary>
 /// Chi1n atomic valence number connectivity index (order 1)
 /// </summary>
 /// <param name="mol"></param>
 /// <returns></returns>
 public static double Chi1n(this OBMol mol)
 {
     return(mol.Bonds().Where(b => b.GetBeginAtom().ValenceNumber() * b.GetEndAtom().ValenceNumber() > 0)
            .Select(b => Math.Sqrt(1 / (double)(b.GetBeginAtom().ValenceNumber() * b.GetEndAtom().ValenceNumber()))).Sum());
 }
        public designGraph moltoDesignGraph(OBMol mol)
        {
            //OBConversion obconv = new OBConversion ();
            designGraph  host   = new designGraph();
            OBConversion obconv = new OBConversion();

            Dictionary <uint, int> atomid2nodeid = new Dictionary <uint, int>();



            //obconv.SetInFormat("smi");
            //var format =obconv.GetInFormat();
            //uint d=mol.NumAtoms();
            OBElementTable ptable = new OBElementTable();

            //mol.FindTorsions ();
            int nodecount = 0;

            //loop through all atoms in the file and make them into nodes in the graph
            foreach (OBAtom a in mol.Atoms())
            {
                node n = new node();
                n.name = "n" + nodecount;


                var atype = a.GetAtomType();
                n.X = a.GetX() * (1 / scale);
                n.Y = a.GetY() * (1 / scale);
                n.Z = a.GetZ() * (1 / scale);

                uint   anum = a.GetAtomicNum();
                string sym  = ptable.GetSymbol((int)anum);
                //double test =ptable.GetIonization ((int)anum);
                int  maxbonds = ptable.GetMaxBonds((int)anum);
                uint val      = a.GetImplicitValence();
                n.localLabels.Add(sym);
                n.localLabels.Add(atype);
                n.localVariables.Add((double)maxbonds);
                n.localVariables.Add((double)val);
                host.addNode(n);
                atomid2nodeid.Add(a.GetId(), nodecount);
                //Console.WriteLine (x);
                nodecount++;
            }
            int arccount = 0;

            foreach (OBBond b in mol.Bonds())
            {
                arc ac = new arc();
                ac.directed = false;
                ac.name     = "a" + arccount;
                //uint bondorder = b.GetBondOrder ();

                if (b.IsSingle())
                {
                    ac.localLabels.Add("s");
                }
                if (b.IsTriple())
                {
                    ac.localLabels.Add("t");
                }
                if (b.IsDouble())
                {
                    ac.localLabels.Add("d");
                }
                uint toid   = b.GetEndAtomIdx();
                uint fromid = b.GetBeginAtomIdx();
                ac.To   = host.nodes[atomid2nodeid[toid - 1]];
                ac.From = host.nodes[atomid2nodeid[fromid - 1]];
                host.arcs.Add(ac);
                arccount++;
            }
            return(host);
        }