private MassSpectrum GetSpectrumByScanNum(int scanNum)
        {
            //if (scanNum >= 24021 && scanNum <= 24021)
            //{
            //    return null;
            //}
            string scanFilter = null;

            _rawReader.GetFilterForScanNum(scanNum, ref scanFilter);

            // get scan type;
            int nScanType = 0;

            _rawReader.GetScanTypeForScanNum(scanNum, ref nScanType);

            // get scan header information of the spectrum;
            int    numPackets = 0, numChannels = 0, uniformTime = 0;
            double startTime = 0, lowMass = 0, highMass = 0, tic = 0, basePeakMass = 0, basePeakIntensity = 0, frequency = 0;

            _rawReader.GetScanHeaderInfoForScanNum(scanNum, ref numPackets, ref startTime, ref lowMass, ref highMass,
                                                   ref tic, ref basePeakMass, ref basePeakIntensity, ref numChannels, ref uniformTime, ref frequency);

            // get the instrument type;
            InstrumentType instrumentType = InstrumentType.ELSE;

            if (scanFilter.StartsWith("FTMS"))
            {
                instrumentType = InstrumentType.FTMS;
            }
            else if (scanFilter.StartsWith("ITMS"))
            {
                instrumentType = InstrumentType.ITMS;
            }

            // get MS spectrum list;
            string spectrumId = "controllerType=0 controllerNumber=1 scan=" + scanNum.ToString();

            // get the retention time;
            double retentionTime = double.NaN;

            _rawReader.RTFromScanNum(scanNum, ref retentionTime);

            // get the ion injection time and the precursor information;
            object trailerLabelsObj   = null;
            object trailerValuesObj   = null;
            int    trailer_array_size = -1;

            _rawReader.GetTrailerExtraForScanNum(scanNum, ref trailerLabelsObj, ref trailerValuesObj, ref trailer_array_size);
            string[] trailerLabels = (string[])trailerLabelsObj;
            string[] trailerValues = (string[])trailerValuesObj;

            double ionInjectionTime    = 0;
            double precMz              = 0;
            int    precZ               = 0;
            int    precScanNum         = 0;
            double isolationWindowSize = 0;

            for (int trailerIdx = trailerLabels.GetLowerBound(0); trailerIdx <= trailerLabels.GetUpperBound(0); trailerIdx++)
            {
                if (trailerLabels[trailerIdx].StartsWith("Ion Injection Time"))
                {
                    ionInjectionTime = double.Parse(trailerValues[trailerIdx]);
                }
                if (trailerLabels[trailerIdx].StartsWith("Monoisotopic M/Z"))
                {
                    precMz = double.Parse(trailerValues[trailerIdx]);
                }
                if (trailerLabels[trailerIdx].StartsWith("Charge State"))
                {
                    precZ = int.Parse(trailerValues[trailerIdx]);
                }
                if (trailerLabels[trailerIdx].StartsWith("Master Scan Number"))
                {
                    precScanNum = int.Parse(trailerValues[trailerIdx]);
                }
                if (trailerLabels[trailerIdx].StartsWith("MS2 Isolation Width"))
                {
                    isolationWindowSize = double.Parse(trailerValues[trailerIdx]);
                }
            }

            // get the analyzer temperature from the status log;
            object logLabelsObj = null;
            object logValuesObj = null;
            int    pnArraySize  = 0;

            _rawReader.GetStatusLogForScanNum(scanNum, 1.0, ref logLabelsObj, ref logValuesObj, ref pnArraySize);
            double analyzerTemperature = -1.0;

            if (logLabelsObj != null && logValuesObj != null)
            {
                string[] logLabels = (string[])logLabelsObj;
                string[] logValues = (string[])logValuesObj;

                for (int idx = logLabels.GetLowerBound(0); idx <= logLabels.GetUpperBound(0); idx++)
                {
                    if (logLabels[idx].Contains("FT Analyzer Temp"))
                    {
                        analyzerTemperature = double.Parse(logValues[idx]);
                    }

                    if (logLabels[idx].Contains("Analyzer Temperature"))
                    {
                        analyzerTemperature = double.Parse(logValues[idx]);
                    }
                }
            }

            // create an instance of MassSpectrum;
            List <Ion>   peaks    = null;
            MassSpectrum spectrum = new MassSpectrum(
                (int)scanNum,
                spectrumId,
                retentionTime,
                peaks,
                ionInjectionTime,
                instrumentType,
                scanFilter,
                analyzerTemperature,
                correctPrecMz);

            // check the MS level;
            if (scanFilter.Contains(" ms "))
            {
                spectrum.MsLevel = 1;

                // do not filter peaks for MS1 as all peaks may be needed for later masss/charge correction;
                spectrum.Peaks = GetPeaks(scanNum, scanFilter, false);
            }
            else if (scanFilter.Contains(" ms2 "))
            {
                spectrum.MsLevel = 2;
                int activationType = 0;
                //int pnNumMSOrders = 0;
                _rawReader.GetActivationTypeForScanNum(scanNum, spectrum.MsLevel, ref activationType);
                //_rawReader.GetNumberOfMSOrdersFromScanNum(scanNum, ref pnNumMSOrders);
                //_rawReader.GetIsolationWidthForScanNum(scanNum, pnNumMSOrders, ref isolationWindowSize);
                spectrum.IsolationWindowSize = isolationWindowSize;
                spectrum.ActivationMethod    = (Activation)activationType;
                spectrum.Peaks               = GetPeaks(scanNum, scanFilter, false);
                spectrum.Precursors          = new List <Tuple <double, int> >();
                spectrum.PrecursorIntensity  = 0;
                spectrum.PrecursorScanNumber = precScanNum;

                // get the precMz from the filter;
                int begin = scanFilter.IndexOf(" ms2 ") + 5;
                int end = begin + 1, len = 1;
                while (end < scanFilter.Count() && (scanFilter[end] >= '0' && scanFilter[end] <= '9') || scanFilter[end] == '.')
                {
                    end++;
                    len++;
                }
                spectrum.PrecMzFromFilter = double.Parse(scanFilter.Substring(begin, len));

                //Console.Write(bypassThermoAlgorithm);
                //Console.Write(precMz);
                if (precMz == 0 || bypassThermoAlgorithm)
                {
                    precMz = spectrum.PrecMzFromFilter;
                }

                if (precZ == 0 && ALWAYS_USE_PRECURSOR_CHARGE_STATE_RANGE)
                {
                    foreach (int z in MS2_PRECURSOR_CHARGES)
                    {
                        spectrum.Precursors.Add(new Tuple <double, int>(precMz, z));
                    }
                }
                else
                {
                    spectrum.Precursors.Add(new Tuple <double, int>(precMz, precZ));
                }
            }
            else if (scanFilter.Contains(" ms3 "))
            {
                spectrum.MsLevel = 3;
                if (precMz == 0)
                {
                    int end = scanFilter.Count() - 1;
                    while (end >= 0 && scanFilter[end] != '@')
                    {
                        end--;
                    }
                    int begin = end - 1, len = 1;
                    while (begin >= 0 && (scanFilter[begin] >= '0' && scanFilter[begin] <= '9') || scanFilter[begin] == '.')
                    {
                        begin--;
                        len++;
                    }
                    begin++;
                    len--;
                    precMz = double.Parse(scanFilter.Substring(begin, len));
                }

                // TODO: MS3 spectrum mass/charge correction need to be taken care;
                spectrum.Precursors = new List <Tuple <double, int> >();
                spectrum.Precursors.Add(new Tuple <double, int>(precMz, precZ));

                spectrum.Peaks = GetPeaks(scanNum, scanFilter, false);
                if (precMz < 0.01)
                {
                    for (int trailerIdx = trailerLabels.GetLowerBound(0); trailerIdx <= trailerLabels.GetUpperBound(0); trailerIdx++)
                    {
                        if (trailerLabels[trailerIdx].StartsWith("SPS Mass 1"))
                        {
                            precMz = double.Parse(trailerValues[trailerIdx]);
                            break;
                        }
                    }
                }
                spectrum.Precursors          = new List <Tuple <double, int> >();
                spectrum.PrecursorIntensity  = double.NaN;
                spectrum.PrecursorScanNumber = precScanNum;
                int activationType = 0;
                _rawReader.GetActivationTypeForScanNum(scanNum, spectrum.MsLevel, ref activationType);
                spectrum.ActivationMethod = (Activation)activationType;

                if (precZ == 0 && ALWAYS_USE_PRECURSOR_CHARGE_STATE_RANGE)
                {
                    int maxCharge = 0;
                    foreach (int z in MS2_PRECURSOR_CHARGES)
                    {
                        if (maxCharge < z)
                        {
                            maxCharge = z;
                        }
                    }
                    for (int z = 0; z <= maxCharge; z++)
                    {
                        spectrum.Precursors.Add(new Tuple <double, int>(precMz, z));
                    }
                }
                else
                {
                    spectrum.Precursors.Add(new Tuple <double, int>(precMz, precZ));
                }
            }

            // get the isolation window size;
            //double isoWinSize = 0;
            //int numMSOrders = 0;
            //_rawReader.GetNumberOfMSOrdersFromScanNum(scanNum, ref numMSOrders);
            //for (int i = 0; i <= 10; i++)
            //{
            //    _rawReader.GetIsolationWidthForScanNum(scanNum, i, ref isoWinSize);
            //    Console.WriteLine(i + "\t" + isoWinSize);
            //}
            //spectrum.IsolationWindowSize = isoWinSize;
            //_rawReader.GetIsolationWidthForScanNum(scanNum, spectrum.MsLevel, ref isoWinSize);
            //Console.WriteLine(spectrum.MsLevel + "\t" + isoWinSize);

            // set the scan header information;
            spectrum.TotIonCurrent     = tic;
            spectrum.LowMz             = lowMass;
            spectrum.HighMz            = highMass;
            spectrum.BasePeakMz        = basePeakMass;
            spectrum.BasePeakIntensity = basePeakIntensity;

            return(spectrum);
        }