public void ContractChains()
        {
            HasseNodeCollection VisitedNodes = new HasseNodeCollection();
            // identify vertices with one edge in and one edge out, put them on remove list
            List <HasseNode> ToBeRemoved = new List <HasseNode>();

            foreach (HasseNode Node in HasseDiagramNodes.Values)
            {
                if (!VisitedNodes.ContainsKey(Node.KeyString))
                {
                    if (Node.EdgesToCovered.Count == 1 && Node.EdgesToCovering.Count == 1)
                    {
                        ToBeRemoved.Add(Node);
                    }
                    VisitedNodes.Add(Node.KeyString, Node);
                }
            }

            //now contract nodes A-B-C to form A-C, then throw away B
            foreach (HasseNode Node in ToBeRemoved)
            {
                HasseNode Node1 = Node.EdgesToCovered[0].LowerNode;
                HasseNode Node2 = Node.EdgesToCovering[0].UpperNode;
                this.MakeEdge(Node1, Node2);
                this.RemoveEdge(Node.EdgesToCovered[0]);
                this.RemoveEdge(Node.EdgesToCovering[0]);
                HasseDiagramNodes.Remove(Node.KeyString);
            }
        }
        public void FindLUBAndGLB(HasseNode newNode, ref HasseNodeCollection lub, ref HasseNodeCollection glb)
        {
            bool dbgTimings     = Convert.ToBoolean(DEBUGLEVEL & LOG_ALL_TIMINGS);
            bool dbgComparisons = Convert.ToBoolean(DEBUGLEVEL & LOG_ALL_COMPARISON_COUNTS);

            //glb = BruteForceFindGlb(newNode, HasseDiagramNodes);
            //lub = BruteForceFindLub(newNode, HasseDiagramNodes);
            glb = FindGlb(newNode, HasseDiagramNodes);
            lub = FindLub(newNode, HasseDiagramNodes);
        }
        public static HasseNodeCollection FindLub(HasseNode ReferenceNode, HasseNodeCollection AllNodes)
        {
            bool dbg = Convert.ToBoolean(DEBUGLEVEL & LOG_DEBUG_MAKE_LUB);
            HasseNodeCollection lub = new HasseNodeCollection();
            //List<string> ToBeRemoved = new List<string>();
            HashSet <string> ToBeRemoved = new HashSet <string>();

            foreach (HasseNode Node in AllNodes.Values)
            {
                if (!ToBeRemoved.Contains(Node.KeyString))
                {
                    System.Diagnostics.Debug.WriteLineIf(dbg, "test if " + Node.KeyString + " is larger than " + ReferenceNode.KeyString);


                    // debug:
                    //HasseNode[] subobj = ReferenceNode.getElementarySubobjects().Values.ToArray();
                    //if (!Node.HasElements(subobj) &&
                    //    (Node.IsLargerThan(ReferenceNode)))
                    //{
                    //    System.Diagnostics.Debugger.Break();
                    //}


                    if (Node.IsLargerThan(ReferenceNode))
                    {
                        System.Diagnostics.Debug.WriteLineIf(dbg, " yes - is lub candidate, delete above...");
                        lub.Add(Node.KeyString, Node);
                        FindNodesAbove(Node, ToBeRemoved, 0);
                    }

                    /*
                     * else if (ReferenceNode.IsLargerThan(Node))
                     * {
                     *  DeleteNodesBelow(Node, ToBeRemoved, 0);
                     * }
                     */
                    else
                    {
                        ToBeRemoved.Add(Node.KeyString);
                    }
                }
            }

            foreach (string key in ToBeRemoved)
            {
                lub.Remove(key);
            }

            return(lub);
        }
        private List <HasseEdge> InsertNodeBetweenGlbAndLub(
            HasseNode newNode,
            HasseNodeCollection collectionLUB,
            HasseNodeCollection collectionGLB, bool debug)
        {
            bool             dbg        = Convert.ToBoolean(DEBUGLEVEL & LOG_INSERTIONS);
            List <HasseEdge> AddedEdges = new List <HasseEdge>();
            // break any existing relations between LUBs and GLBs
            // first make list of edges to delete
            List <HasseEdge> EdgesToBeDeleted = new List <HasseEdge>();

            foreach (HasseNode v_low in collectionGLB.Values)
            {
                foreach (HasseNode v_high in collectionLUB.Values)
                {
                    System.Diagnostics.Debug.WriteLineIf(dbg, "cut " + v_low.KeyString + " - " + v_high.KeyString);
                    foreach (HasseEdge E in v_low.EdgesToCovering)
                    {
                        if (E.UpperNode == v_high)
                        {
                            EdgesToBeDeleted.Add(E);
                        }
                    }
                }
            }

            foreach (HasseEdge E in EdgesToBeDeleted)
            {
                RemoveEdge(E);
            }



            //make differences between elements and new
            foreach (HasseNode v_low in collectionGLB.Values)
            {
                System.Diagnostics.Debug.WriteLineIf(dbg, "cover (I)  " + v_low.KeyString + " with " + newNode.KeyString);
                HasseEdge NewEdge = MakeEdge(v_low, newNode);
                AddedEdges.Add(NewEdge);
            }

            //make relations between new and LUBs
            foreach (HasseNode v_high in collectionLUB.Values)
            {
                System.Diagnostics.Debug.WriteLineIf(dbg, "cover (II) " + newNode.KeyString + " with " + v_high.KeyString);
                MakeEdge(newNode, v_high);
            }

            return(AddedEdges);
        }
        public void ContractChains2()
        {
            // identify vertices with one edge out, put them on remove list
            HasseNodeCollection VisitedNodes = new HasseNodeCollection();
            List <HasseNode>    ToBeRemoved  = new List <HasseNode>();

            foreach (HasseNode Node in HasseDiagramNodes.Values)
            {
                if (!VisitedNodes.ContainsKey(Node.KeyString))
                {
                    if (Node.EdgesToCovering.Count == 1)
                    {
                        foreach (HasseEdge TheCoveringEdge in Node.EdgesToCovering)
                        {
                            if (TheCoveringEdge.UpperNode.EdgesToCovered.Count == 1)
                            {
                                ToBeRemoved.Add(Node);
                            }
                        }
                    }
                    VisitedNodes.Add(Node.KeyString, Node);
                }
            }

            //now contract nodes A-B to form B
            // B must inherit innodes as into A, then throw away A
            foreach (HasseNode Node in ToBeRemoved)
            {
                HasseEdge EdgeUpToCovering = Node.EdgesToCovering[0];
                HasseNode NodeCovering     = EdgeUpToCovering.UpperNode;
                //HasseNode Node2 = null;

                System.Diagnostics.Debug.WriteLine("contract  [" + Node.KeyString + "]-[" + NodeCovering.KeyString + "]");
                RemoveEdge(EdgeUpToCovering);

                // make list of edges to covered
                HasseEdge[] EdgesToCovered = Node.EdgesToCovered.ToArray();

                foreach (HasseEdge E2 in EdgesToCovered)
                {
                    HasseNode Node2 = E2.LowerNode;
                    // inherit edges from those that Node covers
                    this.MakeEdge(Node2, NodeCovering);
                    this.RemoveEdge(E2);
                }
                HasseDiagramNodes.Remove(Node.KeyString);
            }
        }
Example #6
0
 public static void CheckCollectionsHaveSameObjects(HasseNodeCollection correctLub, HasseNodeCollection c2)
 {
     foreach (HasseNode elm1 in correctLub.Values)
     {
         if (!c2.ContainsKey(elm1.KeyString))
         {
             throw new Exception("CheckCompareCollections: missing element: " + elm1.KeyString);
         }
     }
     foreach (HasseNode elm2 in c2.Values)
     {
         if (!correctLub.ContainsKey(elm2.KeyString))
         {
             throw new Exception("CheckCompareCollections: extra element" + elm2.KeyString);
         }
     }
 }
        // ==========================================


        public HasseDiagram(HasseNodeFactory.NodeType t)
        {
            // construct new HasseDiagram
            HasseDiagramNodes = new HasseNodeCollection();  //collection nodes in diagram
            DifferenceNodes   = new HasseNodeCollection();  //collection of objects expressing difference
            //ElementaryHasseNodes = new HasseNodeCollection(); // collection of elements

            // factory for nodes, set its nodetype and let it have access to global elements collection
            diagramNodeFactory    = new HasseNodeFactory(t);
            differenceNodeFactory = new HasseNodeFactory(t);

            // a queue for nodes to be created after current node is fully processed
            FragmentInsertionQueue = new HasseFragmentInsertionQueue(HasseDiagramNodes);

            // create the root node as part of construction
            RootNode = diagramNodeFactory.NewNode("", HasseNode.HasseNodeTypes.ROOT, "");
            HasseDiagramNodes.Add("{}", RootNode);
        }
Example #8
0
        public void test6()
        {
            HasseDiagram        HDM      = new HasseDiagram(HasseNodeFactory.NodeType.STRING);
            HasseNodeCollection elements = new HasseNodeCollection();

            HDM.AddNode("XA0");
            HDM.AddNode("XA1");
            HDM.AddNode("XB0");
            HDM.AddNode("XB1");

            HDM.AddNode("YA0");
            HDM.AddNode("YA1");
            HDM.AddNode("YB0");
            HDM.AddNode("YB1");
            // HDM.DeleteNodesWithOneCover();
            DotFileWriter DW = new DotFileWriter(HDM.HasseDiagramNodes, "C:\\temp\\testdotfile.dot");

            DW.WriteDotFile();
            //TopologicalSort.topsort(HDM.AllHasseNodes, true);
            HDM.Draw();
        }
        public static HasseNodeCollection BruteForceFindGlb(HasseNode @ref, HasseNodeCollection AllNodes)
        {
            if (@ref.KeyString.Equals("x"))
            {
                System.Diagnostics.Debugger.Break();
            }

            HasseNodeCollection glb         = new HasseNodeCollection();
            List <string>       ToBeRemoved = new List <string>();

            foreach (HasseNode Node in AllNodes.Values)
            {
                if (@ref.IsLargerThan(Node))
                {
                    glb.Add(Node.KeyString, Node);
                }
            }


            foreach (HasseNode Node in glb.Values)
            {
                foreach (HasseNode Node2 in glb.Values)
                {
                    if (Node != Node2)
                    {
                        if (Node.IsLargerThan(Node2))
                        {
                            ToBeRemoved.Add(Node2.KeyString);
                        }
                        //           break;
                    }
                }
            }
            foreach (string key in ToBeRemoved)
            {
                glb.Remove(key);
            }

            return(glb);
        }
        public static HasseNodeCollection FindGlb(HasseNode ReferenceNode, HasseNodeCollection AllNodes)
        {
            bool dbg = Convert.ToBoolean(DEBUGLEVEL & LOG_DEBUG_MAKE_GLB);
            HasseNodeCollection glb = new HasseNodeCollection();
            //List<string> ToBeRemoved = new List<string>();
            HashSet <string> ToBeRemoved = new HashSet <string>();

            foreach (HasseNode Node in AllNodes.Values)
            {
                if (!ToBeRemoved.Contains(Node.KeyString))
                {
                    System.Diagnostics.Debug.WriteLineIf(dbg, "test if " + ReferenceNode.KeyString + " is larger than " + Node.KeyString);
                    if (ReferenceNode.IsLargerThan(Node))
                    {
                        System.Diagnostics.Debug.WriteLineIf(dbg, " yes - is glb candidate, delete below...");
                        glb.Add(Node.KeyString, Node);
                        FindNodesBelow(Node, ToBeRemoved, 0);
                    }

                    /*   else if (Node.IsLargerThan(ReferenceNode))
                     * {
                     *     DeleteNodesAbove(Node, ToBeRemoved, 0);
                     * }
                     */
                    else
                    {
                        ToBeRemoved.Add(Node.KeyString);
                    }
                }
            }

            foreach (string key in ToBeRemoved)
            {
                glb.Remove(key);
            }

            return(glb);
        }
Example #11
0
        public void test5()
        {
            HasseDiagram HDM = new HasseDiagram(HasseNodeFactory.NodeType.STRING);

            System.Random       rnd      = new System.Random(1);
            HasseNodeCollection elements = new HasseNodeCollection();

            for (int i = 1; i <= 500; i++)
            {
                string buf    = "";
                int    strLen = Convert.ToInt32(rnd.Next(1, 500));
                //8
                //random string length
                for (int j = 1; j <= strLen; j++)
                {
                    buf += "A";
                }
                HDM.AddNode(buf);
            }
            //HDM.BFGTopOrder.DebugReport()
            //TopologicalSort.topsort(HDM.AllHasseNodes ,true);
            HDM.Draw();
        }
        public static HasseNodeCollection BruteForceFindLub(HasseNode @ref, HasseNodeCollection AllNodes)
        {
#if DEBUG
            // if (@ref.UniqueString.Equals("*B*")) {
            //    System.Diagnostics.Debugger.Break();
            // }
#endif

            HasseNodeCollection lub         = new HasseNodeCollection();
            List <string>       ToBeRemoved = new List <string>();
            foreach (HasseNode Node in AllNodes.Values)
            {
                if (Node.IsLargerThan(@ref))
                {
                    lub.Add(Node.KeyString, Node);
                }
            }

            foreach (HasseNode Node in lub.Values)
            {
                foreach (HasseNode Node2 in lub.Values)
                {
                    if (Node2.IsLargerThan(Node))
                    {
                        ToBeRemoved.Add(Node2.KeyString);
                        //break;
                    }
                }
            }
            foreach (string key in ToBeRemoved)
            {
                lub.Remove(key);
            }

            return(lub);
        }
Example #13
0
        public static void test4(string filename)
        {
            HasseDiagram        HDM      = new HasseDiagram(HasseNodeFactory.NodeType.STRING);
            HasseNodeCollection elements = new HasseNodeCollection();

            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
            sw.Start();

            System.IO.FileStream fs = new System.IO.FileStream(filename, System.IO.FileMode.Open, System.IO.FileAccess.Read);

            System.IO.TextReader rdr = new System.IO.StreamReader(fs);
            int maxCount             = 200000;
            int count = 0;

            List <string> Words = new List <string>();


            do
            {
                //if (count >= maxCount)   break;

                char[] delim = { ' ', ',', '.' };
                string line  = rdr.ReadLine();
                if (line == null)
                {
                    break;
                }
                string[] words = line.Split(delim);
                for (int i = 0; i < words.Length; i++)
                {
                    count += 1;
                    string w = words[i];
                    w = w.Trim();
                    w = w.ToLower();
                    w = w.Replace("*", "");
                    w = w.Replace("(", "");
                    w = w.Replace(")", "");
                    w = w.Replace("]", "");
                    w = w.Replace("[", "");
                    w = w.Replace("„", "");
                    w = w.Replace(":", "");
                    w = w.Replace("\"", "");
                    if (!string.IsNullOrEmpty(w))
                    {
                        Words.Add(w); // Add to list for insertion below
                    }
                }
            } while (true);

            // 'randomise' order
            StringHashComparer shc = new StringHashComparer();

            Words.Sort(shc);

            //65533
            count = 0;
            foreach (string Word in Words)
            {
                count += 1;

                System.Diagnostics.Debug.WriteLine(Word);
                foreach (char c in Word.ToCharArray())
                {
                    //    System.Diagnostics.Debug.WriteLine(((int)c).ToString ());
                }

                HDM.AddNode(Word);
                if (count >= maxCount)
                {
                    break;
                }
            }

            fs.Close();
            sw.Stop();

            System.Diagnostics.Debug.WriteLine("Total time: " + ((double)sw.ElapsedMilliseconds / 1000).ToString() + " seconds");
            System.Diagnostics.Debug.WriteLine("Total time: " + ((double)sw.ElapsedTicks / System.Diagnostics.Stopwatch.Frequency).ToString() + " seconds");

            HDM.ContractChains2();

            HDM.HasseDiagramNodes.Sort();
            foreach (HasseNode n in HDM.HasseDiagramNodes.Values)
            {
                System.Diagnostics.Debug.WriteLine(n.KeyString);
            }

            DotFileWriter DW = new DotFileWriter(HDM.HasseDiagramNodes, "C:\\Users\\ssampath\\Documents\\HasseDiagramOutput\\testdotfile.dot");

            DW.LabelMode = labelMode.USE_NODE_KEY;
            DW.WriteDotFile();
            System.Diagnostics.Debug.WriteLine(HDM.RootNode.HashString());
            System.Diagnostics.Debug.WriteLine(HDM.HasseDiagramNodes.Count.ToString() + " Diagram objects");
            System.Diagnostics.Debug.WriteLine(HDM.DifferenceNodes.Count.ToString() + " Difference objects");
            //System.Diagnostics.Debug.WriteLine(HasseDiagramStats.Report(HDM.HasseDiagramNodes));
        }
        private bool addNode(HasseNode newNode, HasseNode[] AboveTheseNodes, HasseNode[] BelowTheseNodes)
        {
            // should return true if node was inserted
            // or false if corresponding node already exist

            bool debug      = Convert.ToBoolean(DEBUGLEVEL & LOG_INSERTIONS);
            bool dbgTimings = Convert.ToBoolean(DEBUGLEVEL & LOG_ALL_TIMINGS);

            sw.Reset();
            sw.Start();

            if (newNode.Size() < MINIMUM_FRAGMENT_SIZE)
            {
                return(false);
            }

            // do not add identical objects
            if (HasseDiagramNodes.ContainsKey(newNode.KeyString))
            {
                // is already there - we will update type, set name, redraw image, then return.
                HasseDiagramNodes[newNode.KeyString].AddNodeType(newNode.NodeType);
                if (newNode.HasNodeType(HasseNode.HasseNodeTypes.REAL))
                {
                    string n = newNode.GetName();
                    HasseDiagramNodes[newNode.KeyString].SetName(n);
                    //if (CREATE_NODE_IMAGE) HasseDiagramNodes[newNode.KeyString].CreateImage();
                    System.Diagnostics.Debug.WriteLineIf(debug, " Skipping add of " + newNode.KeyString);
                }
                return(false);
            }
            //if (CREATE_NODE_IMAGE) newNode.CreateImage();
            CountAdditions += 1;

            if (DEBUGLEVEL > 0)
            {
                System.Diagnostics.Debug.WriteLine("Add Node " + newNode.KeyString + " " + CountAdditions.ToString());
            }


            // loop elements of new object

            /*
             * foreach (HasseNode Element in newNode.getElementarySubobjects().Values)
             *   {
             *       if (USE_ELEMENTS)
             *       {
             *           // add to diagram nodes list if not already there
             *           if (!HasseDiagramNodes.ContainsKey(Element.KeyString))
             *           {
             *               HasseDiagramNodes.Add(Element.KeyString, Element);
             *               //Element.CreateImage();
             *               this.MakeEdge(RootNode, Element);
             *           }
             *       }
             *       // add to elements collection if not there already
             *       if (!ElementaryHasseNodes.ContainsKey(Element.KeyString))
             *           ElementaryHasseNodes.Add(Element.KeyString, Element);
             *   }
             */


            System.Diagnostics.Debug.WriteLineIf(dbgTimings, " ticks add 1 (init) " + sw.ElapsedTicks.ToString());
            sw.Reset();
            sw.Start();

            System.Diagnostics.Debug.WriteLineIf(debug, "=== Start LUB and GLB for " + newNode.KeyString + " ===");

            if (CountAdditions == -1)
            {
                System.Diagnostics.Debugger.Break();
            }

            HasseNodeCollection NodesInGreatestLowerBound = null;
            HasseNodeCollection NodesInLeastUpperBound    = null;

            FindLUBAndGLB(newNode, ref NodesInLeastUpperBound, ref NodesInGreatestLowerBound);


            System.Diagnostics.Debug.WriteLineIf(dbgTimings, " ticks 2 (got lub and glb) " + sw.ElapsedTicks.ToString());
            sw.Reset();
            sw.Start();
            System.Diagnostics.Debug.WriteLineIf(debug, "=== Done LUB and GLB =======");

            List <HasseEdge> NewlyFormedEdges = InsertNodeBetweenGlbAndLub(
                newNode, NodesInLeastUpperBound, NodesInGreatestLowerBound, debug);

            System.Diagnostics.Debug.WriteLineIf(dbgTimings, " ticks 3 (inserted new) " + sw.ElapsedTicks.ToString());
            sw.Reset();
            sw.Start();

            if (Convert.ToBoolean(CHECK_LEVEL & CHECK_ALL))
            {
                newNode.validate();
            }

            if (MAKE_MCS_AT_ONCE)
            {
                FindCommonFragments(newNode);
            }


            System.Diagnostics.Debug.WriteLineIf(dbgTimings, " ticks 4 (made MCS)" + sw.ElapsedTicks.ToString());
            // The node may be there already, just added, as element if it is both element and real
            // if (!newNode.HasNodeType(HasseNode.HasseNodeTypes.ELEMENT))
            HasseDiagramNodes.Add(newNode.KeyString, newNode);
            return(true);
        }
 public DotFileWriter(HasseNodeCollection col, List <HasseNode> _subset, string path)
 {
     NodeCollection  = col;
     FilenameAndPath = path;
     subset          = _subset;
 }
 public DotFileWriter(HasseNodeCollection col, string path)
 {
     NodeCollection  = col;
     FilenameAndPath = path;
 }
        public static String Report(HasseNodeCollection nodes, HasseNode rootNode)
        {
            int countLeaves = 0;
            int countReals  = 0;

            foreach (HasseNode node in nodes.Values)
            {
                if (node.IsLeafNode())
                {
                    countLeaves++;
                }
                if (node.HasNodeType(HasseNode.HasseNodeTypes.REAL))
                {
                    countReals++;
                }
            }

            StringBuilder sb = new StringBuilder();

            sb.AppendLine("Leaf count: " + countLeaves.ToString());
            sb.AppendLine("REAL count: " + countReals.ToString());

            // how selective are the root nodes?
            // the average root node, how many parents, of all?


            List <HasseNodeCollection> NodesInLevel = new List <HasseNodeCollection>();
            int CountUpwardEdges = 0;
            int CountLeafNodes   = 0;
            int countAllLeaves   = 0;
            HasseNodeCollection NodesOnThisLevel = new HasseNodeCollection();

            NodesOnThisLevel.Add(rootNode.KeyString, rootNode);

            HasseNodeCollection NodesOnThisLevelPlusOne = new HasseNodeCollection();

            for (int level = 1; ; level++)
            {
                CountUpwardEdges = 0;
                CountLeafNodes   = 0;
                foreach (HasseNode node in NodesOnThisLevel.Values)
                {
                    node.LevelFromRoot = level;
                    foreach (HasseEdge EdgeUpToParent in node.EdgesToCovering)
                    {
                        HasseNode Parent = EdgeUpToParent.UpperNode;
                        CountUpwardEdges++;
                        if (!NodesOnThisLevelPlusOne.ContainsKey(Parent.KeyString))
                        {
                            NodesOnThisLevelPlusOne.Add(Parent.KeyString, Parent);
                        }
                    }
                    if (node.EdgesToCovering.Count == 0)
                    {
                        CountLeafNodes++; countAllLeaves++;
                    }
                }

                sb.AppendLine("at level " + level.ToString() + ";\tnodes: " + NodesOnThisLevel.Count.ToString() + "\tsum upward edges: " + CountUpwardEdges.ToString() + "\t count leaf nodes: " + CountLeafNodes.ToString());

                NodesInLevel.Add(NodesOnThisLevel);
                if (NodesOnThisLevelPlusOne.Count == 0)
                {
                    break;
                }
                NodesOnThisLevel        = NodesOnThisLevelPlusOne;
                NodesOnThisLevelPlusOne = new  HasseNodeCollection();
            }
            sb.AppendLine("total node count: " + nodes.Count.ToString());
            sb.AppendLine("total leaves count: " + countAllLeaves.ToString());

            return(sb.ToString());
        }
Example #18
0
 public HasseFragmentInsertionQueue(HasseNodeCollection _nodesInDiagram)
 {
     nodesInDiagram = _nodesInDiagram;
 }
Example #19
0
        public static void chemtest()
        {
            //IndigoTests T = new IndigoTests();
            //T.test1();


            Indigo indigo = new Indigo();

            /*
             * ChemHasseNode L_ALA = new ChemHasseNode("N[C@@H](C)C(=O)O", HasseNode.HasseNodeTypes.REAL, allNodes);
             * ChemHasseNode D_ALA = new ChemHasseNode("N[C@H](C)C(=O)O", HasseNode.HasseNodeTypes.REAL, allNodes);
             * d=L_ALA.GetDifferenceString (D_ALA);
             * d = D_ALA.GetDifferenceString(L_ALA);
             */
//            HasseDiagram HDM = new HasseDiagram(HasseNodeFactory.NodeType.CHEM );
            HasseDiagram        HDM      = new HasseDiagram(HasseNodeFactory.NodeType.FINGERPRINTCHEM);
            HasseNodeCollection elements = new HasseNodeCollection();

            //ChemHasseNode A = (ChemHasseNode)HDM.AddNode("c1ccccccc[nH]1"); // azonine
            //ChemHasseNode B = (ChemHasseNode)HDM.AddNode("C12=C(C=NC=C1)NC1=C2C=CC=C1");  // pyrido indol
            //ChemHasseNode C = (ChemHasseNode)HDM.AddNode("c1cccc2[nH]ccc21"); // indol

            //FingerprintChemHasseNode A = (FingerprintChemHasseNode)HDM.AddNode("C"); //
            //FingerprintChemHasseNode B = (FingerprintChemHasseNode)HDM.AddNode("CC");  //
            //FingerprintChemHasseNode C = (FingerprintChemHasseNode)HDM.AddNode("CN"); //


            // ChemHasseNode A = (ChemHasseNode)HDM.AddNode(@"[NH3+]C");
            //ChemHasseNode B = (ChemHasseNode)HDM.AddNode(@"[NH2]CC");

            //bool tst = A.IsLargerThan(B);
            //tst = B.IsLargerThan(A);
            //A.GetMaxCommonFragments(A, B);
            //tst = A.IsLargerThan(C);
            //tst = C.IsLargerThan(A);

            // pyridoindol larger than azonine

            System.Threading.Thread.CurrentThread.Priority = System.Threading.ThreadPriority.BelowNormal;
            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
            sw.Start();

            int count = 0;

            //foreach (IndigoObject item in indigo.iterateSDFile(@"C:\temp\benzodiazepines.sdf"))
            //foreach (IndigoObject item in indigo.iterateSDFile(@"C:\temp\monoamtrain_x.sdf"))
            //foreach (IndigoObject item in indigo.iterateSDFile(@"C:\HassePub\Datasets\Jorissen\compounds_1st.sdf"))
            //foreach (IndigoObject item in indigo.iterateSDFile(@"C:\HassePub\Datasets\benzodiazepines_v4.sdf"))
            //    foreach (IndigoObject item in indigo.iterateSDFile(@"C:\HassePub\Datasets\small_set.sdf"))
            // foreach (IndigoObject item in indigo.iterateSDFile(@"C:\HassePub\Datasets\chembl_pyridines.sdf"))
            //foreach (IndigoObject item in indigo.iterateSDFile(@"C:\HassePub\Datasets\ChEBI_anilines_480-500.sdf"))
            //foreach (IndigoObject item in indigo.iterateSDFile(@"C:\HassePub\Datasets\ChEBI_valines.sdf"))
            foreach (IndigoObject item in indigo.iterateSDFile(@"C:\HassePub\Datasets\ChEBI_valines_v21.sdf")) // in pub
            {
                if (item.isChiral() == false)
                {
                    continue;
                }
                count++;
                //System.Diagnostics.Debugger.Break();
                if (count > 24)
                {
                    break;            //24 for valines in pub
                }
                //         HasseNode N = HDM.CreateNewNode(item);
                //if (N.IsValid())
                //{
                System.Diagnostics.Stopwatch sw2 = new System.Diagnostics.Stopwatch();
                sw2.Start();
                try
                {
                    HasseNode N = HDM.CreateNewNode(item.molfile());
                    if (item.hasProperty("CHEMBL ID"))
                    {
                        string ChemblID = item.getProperty("CHEMBL ID");
                        N.SetName(ChemblID);
                    }
                    else if (item.hasProperty("ChEBI ID"))
                    {
                        string ChebiID = item.getProperty("ChEBI ID");
                        N.SetName(ChebiID);
                    }
                    else
                    {
                        N.SetName(count.ToString());
                    }

                    HDM.AddNode(N);
                    System.Diagnostics.Debug.WriteLine("---   " + N.KeyString);
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine("WARNING: could not add node: " + ex.ToString());
                }
            }

            List <HasseNode> subset = new List <HasseNode>();

            /*
             * foreach (HasseNode N in HDM.HasseDiagramNodes.Values)
             * {
             * if (N.NodeType != HasseNode.HasseNodeTypes.ROOT)
             * {
             *  float weight = N.Weight();
             *  N.SetName("w=" + weight.ToString());
             *  float w = 5F * weight / 29F;
             *  if (w < 1) w = 1F;
             *  if (w > 3.5) w = 3.5F;
             * //       N.CreateImage(w);
             *  N.CreateImage();
             *  //if (weight > 20) subset.Add(N);
             * }
             *
             * }
             */
            //DotFileWriter DW = new DotFileWriter(HDM.HasseDiagramNodes, subset, "C:\\temp\\testdotfile.dot");
            DotFileWriter DW = new DotFileWriter(HDM.HasseDiagramNodes, "C:\\temp\\testdotfile.dot");

            int cnt = 0;


            foreach (HasseNode N in HDM.HasseDiagramNodes.Values)
            {
                if ((N.GetType() == typeof(ChemHasseNode) || N.GetType() == typeof(FingerprintChemHasseNode)) && N.NodeType != HasseNode.HasseNodeTypes.ROOT)
                {
                    cnt++;
                    N.SetName(cnt.ToString());
                    if (N.GetType() == typeof(ChemHasseNode))
                    {
                        ((ChemHasseNode )N).CreateImage();
                    }
                    if (N.GetType() == typeof(FingerprintChemHasseNode))
                    {
                        ((FingerprintChemHasseNode)N).CreateImage();
                    }
                }
            }

            DW.SetLabelsToNumericSequence();
            DW.SetDrawingColors();
            DW.LabelMode     = labelMode.NO_LABELS; // for figure 5
            DW.directionMode = graphDirection.RIGHT;

            //DW.LabelMode = labelMode.USE_NODE_LABEL;
            //DW.LabelMode = labelMode.USE_NODE_ID;

            DW.UseImage        = true;
            DW.WriteEdgeLabels = false;

            sw.Stop();
            System.Diagnostics.Debug.WriteLine(sw.ElapsedMilliseconds.ToString());

            DW.WriteDotFile();

            System.Diagnostics.Debug.WriteLine("Nodes: " + HDM.HasseDiagramNodes.Count());
            System.Diagnostics.Debug.WriteLine("Diffs: " + HDM.DifferenceNodes.Count());
            System.Diagnostics.Debug.WriteLine("Hash: " + HDM.RootNode.HashString());

            foreach (HasseNode N in HDM.HasseDiagramNodes.Values)
            {
                if (N.HasNodeType(HasseNode.HasseNodeTypes.FRAGMENT))
                {
                    ;
                }
                //  System.Diagnostics.Debug.WriteLine(N.KeyString + " " + N.Weight().ToString() );
            }
            System.Diagnostics.Debug.WriteLine(HasseDiagramStats.Report(HDM.HasseDiagramNodes, HDM.RootNode));
        }