/// <summary>
        /// The Thermo decon result filename is assumed to be the same as the spectra file name
        /// </summary>
        private static AnnotatedSpecies GetThermoDeconSpecies(string line, StreamReader reader, string fileName)
        {
            string[]   items      = line.Split(ItemDelimiter);
            int        numCharges = int.Parse(items[3]); // TODO: get this from header, not hardcoded
            List <int> chargeList = new List <int>();

            double mass        = double.Parse(items[MonoisotopicMassColumn]);
            string speciesName = items[SpeciesNameColumn] + " (" + mass.ToString("F1") + ")";
            double apexRt      = double.Parse(items[RetentionTimeColumn]);
            string rtRange     = items[FeatureRtStartColumn];
            double rtStart     = double.Parse(rtRange.Split('-')[0].Trim());
            double rtEnd       = double.Parse(rtRange.Split('-')[1].Trim());

            for (int i = 0; i < numCharges + 1; i++)
            {
                var nextLine        = reader.ReadLine();
                var chargeLineSplit = nextLine.Split(ItemDelimiter);

                if (chargeLineSplit[1].Trim().Equals("Charge State", StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }

                chargeList.Add(int.Parse(chargeLineSplit[1]));
            }

            var deconFeature = new DeconvolutionFeature(mass, apexRt, rtStart, rtEnd, chargeList, fileName);
            var species      = new AnnotatedSpecies(deconFeature);

            species.DeconvolutionFeature = deconFeature;

            return(species);
        }
        private static AnnotatedSpecies GetTdPortalSpecies(string line)
        {
            string[] items = line.Split(ItemDelimiter);

            string baseSequence = items[SpeciesNameColumn];
            string modSequence  = items[SpeciesNameColumn];
            double mass         = double.Parse(items[MonoisotopicMassColumn]);
            // TD portal does not report precursor charge

            var id = new Identification(baseSequence, modSequence, mass, -1);

            var species = new AnnotatedSpecies(id);

            return(species);
        }
        private static AnnotatedSpecies GetMetaMorpheusSpecies(string line)
        {
            string[] items = line.Split(ItemDelimiter);

            string baseSequence = items[SpeciesNameColumn];
            string modSequence  = items[SpeciesNameColumn];
            double mass         = double.Parse(items[MonoisotopicMassColumn]);
            int    charge       = int.Parse(items[ChargeColumn]);

            var id = new Identification(baseSequence, modSequence, mass, charge);

            var species = new AnnotatedSpecies(id);

            species.Identification = id;

            return(species);
        }
        private static AnnotatedSpecies GetFlashDeconvSpecies(string line)
        {
            string[] items = line.Split(ItemDelimiter);

            string identifier = items[SpeciesNameColumn];
            double mass       = double.Parse(items[MonoisotopicMassColumn]);

            int    minChargeState = int.Parse(items[MinChargeColumn]);
            int    maxChargeState = int.Parse(items[MaxChargeColumn]);
            var    chargeList     = Enumerable.Range(minChargeState, maxChargeState - minChargeState + 1).ToList();
            double apexRt         = double.Parse(items[RetentionTimeColumn]) / 60;
            double rtStart        = double.Parse(items[FeatureRtStartColumn]) / 60;
            double rtEnd          = double.Parse(items[FeatureRtEndColumn]) / 60;
            string fileName       = items[SpectraFileNameColumn];
            var    deconFeature   = new DeconvolutionFeature(mass, apexRt, rtStart, rtEnd, chargeList, fileName);
            var    species        = new AnnotatedSpecies(deconFeature);

            species.DeconvolutionFeature = deconFeature;

            return(species);
        }
        public static List <AnnotatedSpecies> ReadSpeciesFromFile(string filePath, out List <string> errors)
        {
            var fileType = InputSourceType.Unknown;

            errors = new List <string>();
            var listOfSpecies = new List <AnnotatedSpecies>();

            // open the file to read
            StreamReader reader;

            try
            {
                reader = new StreamReader(filePath);
            }
            catch (Exception e)
            {
                errors.Add("Error reading file " + filePath + "\n" + e.Message);
                return(listOfSpecies);
            }

            // read the file
            int lineNum = 0;

            while (reader.Peek() > 0)
            {
                string line = reader.ReadLine();
                lineNum++;

                // determine file type from the header
                if (lineNum == 1)
                {
                    fileType = GetFileTypeFromHeader(line);

                    if (fileType == InputSourceType.Unknown)
                    {
                        errors.Add("Could not interpret header labels from file: " + filePath);
                        return(listOfSpecies);
                    }

                    continue;
                }

                // read the line + create the species object
                AnnotatedSpecies species = null;
                switch (fileType)
                {
                case InputSourceType.MetaMorpheus:
                    species = GetMetaMorpheusSpecies(line);
                    break;

                case InputSourceType.FlashDeconv:
                    species = GetFlashDeconvSpecies(line);
                    break;

                case InputSourceType.TDPortal:
                    species = GetTdPortalSpecies(line);
                    break;

                case InputSourceType.ThermoDecon:
                    species = GetThermoDeconSpecies(line, reader, filePath);
                    break;
                }

                // add the item to the list
                if (species != null)
                {
                    listOfSpecies.Add(species);
                }
            }

            return(listOfSpecies);
        }