public void TestGetCollisionEnergy(string rawFileName)
        {
            // Keys in this Dictionary are filename, values are Collision Energies by scan
            var expectedData = new Dictionary<string, Dictionary<int, List<double>>>();

            var ce30 = new List<double> { 30.00 };
            var ce45 = new List<double> { 45.00 };
            var ce20_120 = new List<double> { 20.00, 120.550003 };
            var ce120 = new List<double> { 120.550003 };
            var ms1Scan = new List<double>();

            // Keys in this dictionary are scan number and values are collision energies
            var file1Data = new Dictionary<int, List<double>>
            {
                {2250, ce45},
                {2251, ce45},
                {2252, ce45},
                {2253, ms1Scan},
                {2254, ce45},
                {2255, ce45},
                {2256, ce45},
                {2257, ms1Scan},
                {2258, ce45},
                {2259, ce45},
                {2260, ce45}
            };
            expectedData.Add("Shew_246a_LCQa_15Oct04_Andro_0904-2_4-20", file1Data);

            var file2Data = new Dictionary<int, List<double>>
            {
                {39000, ce30},
                {39001, ce30},
                {39002, ms1Scan},
                {39003, ce30},
                {39004, ce30},
                {39005, ce30},
                {39006, ce120},
                {39007, ce20_120},
                {39008, ce20_120},
                {39009, ce30},
                {39010, ce30}
            };
            expectedData.Add("HCC-38_ETciD_EThcD_4xdil_20uL_3hr_3_08Jan16_Pippin_15-08-53", file2Data);

            var file3Data = new Dictionary<int, List<double>>
            {
                {19000, ce120},
                {19001, ce20_120},
                {19002, ce20_120},
                {19003, ms1Scan},
                {19004, ce30},
                {19005, ce30},
                {19006, ce30},
                {19007, ce120},
                {19008, ce20_120},
                {19009, ce20_120},
                {19010, ce30}
            };
            expectedData.Add("HCC-38_ETciD_EThcD_07Jan16_Pippin_15-08-53", file3Data);

            var file4Data = new Dictionary<int, List<double>>
            {
                {1, ce30},
                {2, ce30}

            };
            expectedData.Add("MZ0210MnxEF889ETD", file4Data);

            var dataFile = GetRawDataFile(rawFileName);

            Dictionary<int, List<double>> collisionEnergiesThisFile;
            if (!expectedData.TryGetValue(Path.GetFileNameWithoutExtension(dataFile.Name), out collisionEnergiesThisFile))
            {
                Assert.Fail("Dataset {0} not found in dictionary expectedData", dataFile.Name);
            }

            // Keys are scan number, values are the list of collision energies
            var collisionEnergiesActual = new Dictionary<int, List<double>>();

            // Keys are scan number, values are msLevel
            var msLevelsActual = new Dictionary<int, int>();

            // Keys are scan number, values are the ActivationType, for example cid, etd, hcd
            var activationTypesActual = new Dictionary<int, string>();
            using (var reader = new XRawFileIO(dataFile.FullName))
            {
                foreach (var scanNumber in collisionEnergiesThisFile.Keys)
                {
                    clsScanInfo scanInfo;
                    var success = reader.GetScanInfo(scanNumber, out scanInfo);

                    Assert.IsTrue(success, "GetScanInfo returned false for scan {0}", scanNumber);

                    var collisionEnergiesThisScan = reader.GetCollisionEnergy(scanNumber);
                    collisionEnergiesActual.Add(scanNumber, collisionEnergiesThisScan);

                    msLevelsActual.Add(scanNumber, scanInfo.MSLevel);

                    activationTypesActual.Add(scanNumber, scanInfo.ActivationType.ToString());
                }

                Console.WriteLine("{0,-5} {1,-5} {2}", "Valid", "Scan", "Collision Energy");

                foreach (var actualEnergiesOneScan in (from item in collisionEnergiesActual orderby item.Key select item))
                {
                    var scanNumber = actualEnergiesOneScan.Key;

                    var expectedEnergies = collisionEnergiesThisFile[scanNumber];

                    var activationTypes = string.Join(", ", activationTypesActual[scanNumber]);

                    if (actualEnergiesOneScan.Value.Count == 0)
                    {
                        var msLevel = msLevelsActual[scanNumber];

                        if (msLevel != 1)
                        {
                            var msg = string.Format(
                                "Scan {0} has no collision energies, which should only be true for spectra with msLevel=1. This scan has msLevel={1} and activationType={2}",
                                scanNumber, msLevel, activationTypes);
                            Console.WriteLine(msg);

                            Assert.Fail(msg);
                        }
                        else
                        {
                            Console.WriteLine("{0,-5} {1,-5} {2}", true, scanNumber, "MS1 scan");
                        }
                    }
                    else
                    {
                        foreach (var actualEnergy in actualEnergiesOneScan.Value)
                        {
                            var isValid = expectedEnergies.Any(expectedEnergy => Math.Abs(actualEnergy - expectedEnergy) < 0.00001);

                            Console.WriteLine("{0,-5} {1,-5} {2}", isValid, scanNumber, actualEnergy.ToString("0.00"));

                            Assert.IsTrue(isValid, "Unexpected collision energy {0} for scan {1}", actualEnergy.ToString("0.00"), scanNumber);
                        }
                    }

                    if (expectedEnergies.Count != actualEnergiesOneScan.Value.Count)
                    {
                        var msg = string.Format("Collision energy count mismatch for scan {0}", scanNumber);
                        Console.WriteLine(msg);
                        Assert.AreEqual(expectedEnergies.Count, actualEnergiesOneScan.Value.Count, msg);
                    }

                }

            }
        }
        private static void TestReader(string rawFilePath, bool centroid = false, bool testSumming = false, int scanStart = 0, int scanEnd = 0)
        {
            try {
                if (!File.Exists(rawFilePath)) {
                    Console.WriteLine("File not found, skipping: " + rawFilePath);
                    return;
                }

                using (var oReader = new XRawFileIO(rawFilePath))
                {

                    foreach(var method in oReader.FileInfo.InstMethods) {
                        Console.WriteLine(method);
                    }

                    var iNumScans = oReader.GetNumScans();

                    var strCollisionEnergies = string.Empty;

                    ShowMethod(oReader);

                    var scanStep = 1;

                    if (scanStart < 1)
                        scanStart = 1;
                    if (scanEnd < 1) {
                        scanEnd = iNumScans;
                        scanStep = 21;
                    } else {
                        if (scanEnd < scanStart) {
                            scanEnd = scanStart;
                        }
                    }

                    for (var iScanNum = scanStart; iScanNum <= scanEnd; iScanNum += scanStep) {
                        clsScanInfo oScanInfo;

                        var bSuccess = oReader.GetScanInfo(iScanNum, out oScanInfo);
                        if (bSuccess) {
                            Console.Write("Scan " + iScanNum + " at " + oScanInfo.RetentionTime.ToString("0.00") + " minutes: " + oScanInfo.FilterText);
                            var lstCollisionEnergies = oReader.GetCollisionEnergy(iScanNum);

                            if (lstCollisionEnergies.Count == 0) {
                                strCollisionEnergies = string.Empty;
                            } else if (lstCollisionEnergies.Count >= 1) {
                                strCollisionEnergies = lstCollisionEnergies[0].ToString("0.0");

                                if (lstCollisionEnergies.Count > 1) {
                                    for (var intIndex = 1; intIndex <= lstCollisionEnergies.Count - 1; intIndex++) {
                                        strCollisionEnergies += ", " + lstCollisionEnergies[intIndex].ToString("0.0");
                                    }
                                }
                            }

                            if (string.IsNullOrEmpty(strCollisionEnergies)) {
                                Console.WriteLine();
                            } else {
                                Console.WriteLine("; CE " + strCollisionEnergies);
                            }

                            string monoMZ;
                            string chargeState;
                            string isolationWidth;

                            if (oScanInfo.TryGetScanEvent("Monoisotopic M/Z:", out monoMZ, false)) {
                                Console.WriteLine("Monoisotopic M/Z: " + monoMZ);
                            }

                            if (oScanInfo.TryGetScanEvent("Charge State", out chargeState, true))
                            {
                                Console.WriteLine("Charge State: " + chargeState);
                            }

                            if (oScanInfo.TryGetScanEvent("MS2 Isolation Width", out isolationWidth, true))
                            {
                                Console.WriteLine("MS2 Isolation Width: " + isolationWidth);
                            }

                            if (iScanNum % 50 == 0 || scanEnd - scanStart <= 50) {
                                // Get the data for scan iScanNum

                                Console.WriteLine();
                                Console.WriteLine("Spectrum for scan " + iScanNum);

                                double[] dblMzList;
                                double[] dblIntensityList;
                                var intDataCount = oReader.GetScanData(iScanNum, out dblMzList, out dblIntensityList, 0, centroid);

                                var mzDisplayStepSize = 50;
                                if (centroid) {
                                    mzDisplayStepSize = 1;
                                }

                                for (var iDataPoint = 0; iDataPoint <= dblMzList.Length - 1; iDataPoint += mzDisplayStepSize) {
                                    Console.WriteLine("  " + dblMzList[iDataPoint].ToString("0.000") + " mz   " + dblIntensityList[iDataPoint].ToString("0"));
                                }
                                Console.WriteLine();

                                const int scansToSum = 15;

                                if (iScanNum + scansToSum < iNumScans & testSumming) {
                                    // Get the data for scan iScanNum through iScanNum + 15

                                    double[,] dblMassIntensityPairs;
                                    var dataCount = oReader.GetScanDataSumScans(iScanNum, iScanNum + scansToSum, out dblMassIntensityPairs, 0, centroid);

                                    Console.WriteLine("Summed spectrum, scans " + iScanNum + " through " + (iScanNum + scansToSum));

                                    for (var iDataPoint = 0; iDataPoint <= dblMassIntensityPairs.GetLength(1) - 1; iDataPoint += 50) {
                                        Console.WriteLine("  " + dblMassIntensityPairs[0, iDataPoint].ToString("0.000") + " mz   " + dblMassIntensityPairs[1, iDataPoint].ToString("0"));
                                    }

                                    Console.WriteLine();
                                }

                                if (oScanInfo.IsFTMS) {
                                    udtFTLabelInfoType[] ftLabelData;

                                    var dataCount = oReader.GetScanLabelData(iScanNum, out ftLabelData);

                                    Console.WriteLine();
                                    Console.WriteLine("{0,12}{1,12}{2,12}{3,12}{4,12}{5,12}", "Mass", "Intensity", "Resolution", "Baseline", "Noise", "Charge");

                                    for (var iDataPoint = 0; iDataPoint <= dataCount - 1; iDataPoint += 50) {
                                        Console.WriteLine("{0,12}{1,12}{2,12}{3,12}{4,12}{5,12}", ftLabelData[iDataPoint].Mass.ToString("0.000"), ftLabelData[iDataPoint].Intensity.ToString("0"), ftLabelData[iDataPoint].Resolution.ToString("0"), ftLabelData[iDataPoint].Baseline.ToString("0.0"), ftLabelData[iDataPoint].Noise.ToString("0"), ftLabelData[iDataPoint].Charge.ToString("0"));
                                    }

                                    udtMassPrecisionInfoType[] ftPrecisionData;

                                    dataCount = oReader.GetScanPrecisionData(iScanNum, out ftPrecisionData);

                                    Console.WriteLine();
                                    Console.WriteLine("{0,12}{1,12}{2,12}{3,12}{4,12}", "Mass", "Intensity", "AccuracyMMU", "AccuracyPPM", "Resolution");

                                    for (var iDataPoint = 0; iDataPoint <= dataCount - 1; iDataPoint += 50) {
                                        Console.WriteLine("{0,12}{1,12}{2,12}{3,12}{4,12}", ftPrecisionData[iDataPoint].Mass.ToString("0.000"), ftPrecisionData[iDataPoint].Intensity.ToString("0"), ftPrecisionData[iDataPoint].AccuracyMMU.ToString("0.000"), ftPrecisionData[iDataPoint].AccuracyPPM.ToString("0.000"), ftPrecisionData[iDataPoint].Resolution.ToString("0"));
                                    }
                                }

                            }

                        }
                    }

                }

            } catch (Exception ex) {
                Console.WriteLine("Error in sub TestReader: " + ex.Message);
            }
        }