//This function is used by generateHypo to get the mass of a composition in the composition table.
 public Double getcompMass(GlycanCompositionTable CT, List<string> elementIDs)
 {
     Double Mass = 0;
     PeriodicTable PT = new PeriodicTable();
     for (int i = 0; i < CT.elementAmount.Count(); i++)
     {
         Mass = Mass + CT.elementAmount[i] * PT.getMass(elementIDs[i]);
     }
     return Mass;
 }
        //This function reads the generate composition page and save it to a variable of class "generator".
        public GlycanHypothesisCombinatorialGenerator getGenerator()
        {
            //compotable is used to store the data from the composition table before they are used.
            List<GlycanCompositionTable> compotable = new List<GlycanCompositionTable>();
            //arTable is used to store the data from additional rules table before they're used.
            List<Boundary> arTable = new List<Boundary>();
            //GD is used to store all the data that will be returned.
            GlycanHypothesisCombinatorialGenerator GD = new GlycanHypothesisCombinatorialGenerator();

            String currentpath = Application.StartupPath + "\\compositionsCurrent.cpos";
            try
            {
                FileStream reading = new FileStream(currentpath, FileMode.Open, FileAccess.Read);
                StreamReader readcompo = new StreamReader(reading);
                //Read the first line to skip the column names:
                String Line1 = readcompo.ReadLine();
                String[] headers = Line1.Split(',');
                List<string> elementIDs = new List<string>();
                bool moreElements = true;
                int sh= 2;
                while (moreElements)
                {
                    if (headers[sh] != "Lower Bound")
                    {
                        elementIDs.Add(headers[sh]);
                        sh++;
                    }
                    else
                        moreElements = false;
                }

                bool firstrow = true;
                //Read the other lines for compTable data.
                while (readcompo.Peek() >= 0)
                {
                    GlycanCompositionTable compTable = new GlycanCompositionTable();
                    if (firstrow)
                    {
                        compTable.elementIDs = elementIDs;
                        firstrow = false;
                    }
                    String Line = readcompo.ReadLine();
                    String[] eachentry = Line.Split(',');
                    //When next line is the Modification line, it breaks.
                    if (eachentry[0] == "Modification%^&!@#*()iop")
                        break;
                    compTable.Letter = eachentry[0];
                    compTable.Molecule = eachentry[1];
                    for (int i = 2; i < elementIDs.Count + 2; i++)
                    {
                        compTable.elementAmount.Add(Convert.ToInt32(eachentry[i]));
                    }
                    List<String> bounds = new List<String>();
                    bounds.Add(eachentry[elementIDs.Count + 2]);
                    bounds.Add(eachentry[elementIDs.Count + 3]);
                    compTable.Bound = bounds;
                    compotable.Add(compTable);
                }
                //Send compotable data to GD
                GD.comTable = compotable;
                //Populate the Modification Table
                String modiLine = readcompo.ReadLine();
                //Send Modification data to GD
                GD.Modification = modiLine.Split(',');

                //Populate the additional rules table
                while (readcompo.Peek() >= 0)
                {
                    String Line = readcompo.ReadLine();
                    String[] eachentry = Line.Split(',');
                    if (eachentry[0] != "" && eachentry[2] != "")
                    {
                        Boundary areTable = new Boundary();
                        areTable.Formula = eachentry[0];
                        areTable.Relationship = eachentry[1];
                        areTable.Constraint = Convert.ToString(eachentry[2]);
                        arTable.Add(areTable);
                    }
                }
                //Send arTable data to GD.
                GD.aTable = arTable;

                readcompo.Close();
                reading.Close();
            }
            catch (Exception compoex)
            {
                MessageBox.Show("Error in loading GlycanCompositions Table. Error:" + compoex);
            }
            return GD;
        }
        //This function is used to read the cpos file and translate it to generatorData format.
        private GlycanHypothesisCombinatorialGenerator extractFile(String path)
        {
            //table is used to store the data before the calculation
            GlycanHypothesisCombinatorialGenerator DATA = new GlycanHypothesisCombinatorialGenerator();
            List<GlycanCompositionTable> GD = new List<GlycanCompositionTable>();
            try
            {
                FileStream reading = new FileStream(path, FileMode.Open, FileAccess.Read);
                StreamReader readcompo = new StreamReader(reading);
                //Read the first line to throw the column names:
                String Line1 = readcompo.ReadLine();
                String[] headers = Line1.Split(',');
                int sh = 2;
                bool moreElements = true;
                List<string> elementIDs = new List<string>();
                while (moreElements)
                {
                    if (headers[sh] != "Lower Bound")
                    {
                        elementIDs.Add(headers[sh]);
                        sh++;
                    }
                    else
                    {
                        moreElements = false;
                    }

                }
                bool firstRow = true;
                while (readcompo.Peek() >= 0)
                {
                    String Line = readcompo.ReadLine();
                    String[] eachentry = Line.Split(',');
                    if (eachentry[0] == "Modification%^&!@#*()iop")
                        break;
                    GlycanCompositionTable CT = new GlycanCompositionTable();
                    CT.Letter = eachentry[0];
                    CT.Molecule = eachentry[1];
                    if (firstRow)
                    {
                        CT.elementIDs = elementIDs;
                        firstRow = false;
                    }
                    for (int i = 0; i < elementIDs.Count(); i++)
                    {
                        CT.elementAmount.Add(Convert.ToInt32(eachentry[2 + i]));
                    }
                        //Random the lower bound and upper bound to get random composition hypothesis
                    CT.Bound = new List<String>();
                    CT.Bound.Add(eachentry[2 + elementIDs.Count()]);
                    CT.Bound.Add(eachentry[2 + elementIDs.Count() + 1]);
                    GD.Add(CT);
                }
                String Line2 = readcompo.ReadLine();
                String[] eachentry2 = Line2.Split(',');
                DATA.comTable = GD;
                DATA.Modification = eachentry2;
                readcompo.Close();
                reading.Close();
            }
            catch (Exception compoex)
            {
                MessageBox.Show("Error in loading GlycanCompositions Table (cpos). Error:" + compoex);
            }

            DATA.aTable = new List<Boundary>();
            DATA.comTable = GD;
            return DATA;
        }