예제 #1
0
        void NextListItem()
        {
            if (CurrentListItem < CamResList.Count)
            {
                CurrentListItem++;

                _phosImages         = CamResList[(int)CurrentListItem - 1].Images;
                _phosFilteredImages = CamResList[(int)CurrentListItem - 1].FilteredImages;
                _phosSpectra        = SpecResList[(int)CurrentListItem - 1].Spectra;
                DiamondResult       = DiamondResList[(int)CurrentListItem - 1];
                PeakInfoList        = PeakInfoListList[(int)CurrentListItem - 1];

                NumSpectraItems         = _phosSpectra.Count.ToString();
                SpectrumIntegrationTime = _phosSpectra[0].IntegrationTime.ToString();

                CurrentPhosItem         = 1;
                CurrentSpectraItem      = 1;
                _startTimeStamp         = CamResList[(int)CurrentListItem - 1].StartTimeStamp;
                _spectrumStartTimeStamp = SpecResList[(int)CurrentListItem - 1].StartTimeStamp;

                //Analyzing();
                //if (PeakInfoList.Count >= 2)
                //{
                //    DiamondResult = SpectrumAnalyzer.TestAggregate(PeakInfoList);
                //}
                AnalyzingResult = ResultString((int)DiamondResult);
                UpdateMarker();
            }
        }
예제 #2
0
        public PhosResultsViewModel(List <CamPhosResults> camResList, List <SpectrometerPhosResults> specResList, List <List <List <PeakDetectInfo> > > peakInfoListList, List <ANALYZER_RESULT> diamondResList, List <Tuple <System.Windows.Shapes.Ellipse, TextBlock, Point> > markerList, CamPhosResults camResultsPre, bool mappingMeasure = false, System.Windows.Shapes.Rectangle rect = null)
        {
            base.DisplayName    = "PhosResultsViewModelBatchMeasurement";
            ShowListItemControl = false;
            CamResList          = camResList;
            SpecResList         = specResList;
            PeakInfoListList    = peakInfoListList;
            DiamondResList      = diamondResList;
            MarkerList          = markerList;
            CamResultsPre       = camResultsPre.Images;
            this.mappingMeasure = mappingMeasure;
            RectMark            = rect;

            Width  = CamResultsPre[0].Image.Width;
            Height = CamResultsPre[0].Image.Height;

            _phosImages         = CamResList[0].Images;
            _phosFilteredImages = CamResList[0].FilteredImages;
            _phosSpectra        = SpecResList[0].Spectra;
            DiamondResult       = DiamondResList[0];
            PeakInfoList        = peakInfoListList[0];

            CurrentListItem         = 1;
            CurrentPhosItem         = 1;
            CurrentSpectraItem      = 1;
            SaveFolderPath          = Properties.Settings.Default.SaveFolderPath;
            _startTimeStamp         = CamResList[0].StartTimeStamp;
            _spectrumStartTimeStamp = SpecResList[0].StartTimeStamp;
            SpectrumIntegrationTime = _phosSpectra[0].IntegrationTime.ToString();

            CommandSetFolder           = new RelayCommand(param => SetFolder(), cc => _busy == false);
            CommandPreviousPhosItem    = new RelayCommand(param => PreviousPhosItem(), cc => _busy == false);
            CommandNextPhosItem        = new RelayCommand(param => NextPhosItem(), cc => _busy == false);
            CommandPreviousSpectraItem = new RelayCommand(param => PreviousSpectraItem(), cc => _busy == false);
            CommandNextSpectraItem     = new RelayCommand(param => NextSpectraItem(), cc => _busy == false);
            CommandSave    = new RelayCommand(param => Save(), cc => _busy == false);
            CommandSaveAll = new RelayCommand(param => Save(true), cc => _busy == false);

            CommandPreviousListItem = new RelayCommand(param => PreviousListItem(), cc => _busy == false);
            CommandNextListItem     = new RelayCommand(param => NextListItem(), cc => _busy == false);

            CommandCalibrate = new RelayCommand(param => Calibrate(), cc => mappingMeasure == false);

            SpectrumData       = new ObservableDataSource <Point>();
            SmoothSpectrumData = new ObservableDataSource <Point>();

            InitializeColorLegend();
        }
예제 #3
0
        public PhosResultsViewModel(CamPhosResults camResults, SpectrometerPhosResults spectroResults, List <List <PeakDetectInfo> > peakInfoList, ANALYZER_RESULT diamondResult, List <Tuple <System.Windows.Shapes.Ellipse, TextBlock, Point> > markerList, CamPhosResults camResultsPre)
        {
            base.DisplayName        = "PhosResultsViewModel";
            ShowListItemControl     = false;
            _phosImages             = camResults.Images;
            _phosFilteredImages     = camResults.FilteredImages;
            _phosSpectra            = spectroResults.Spectra;
            NumSpectraItems         = _phosSpectra.Count.ToString();
            CurrentListItem         = 0;
            CurrentPhosItem         = 1;
            CurrentSpectraItem      = 1;
            SaveFolderPath          = Properties.Settings.Default.SaveFolderPath;
            _startTimeStamp         = camResults.StartTimeStamp;
            _spectrumStartTimeStamp = spectroResults.StartTimeStamp;
            PeakInfoList            = peakInfoList;
            DiamondResult           = diamondResult;
            SpectrumIntegrationTime = _phosSpectra[0].IntegrationTime.ToString();
            MarkerList    = markerList;
            CamResultsPre = camResultsPre.Images;

            Width  = CamResultsPre[0].Image.Width;
            Height = CamResultsPre[0].Image.Height;

            CommandSetFolder           = new RelayCommand(param => SetFolder(), cc => _busy == false);
            CommandPreviousPhosItem    = new RelayCommand(param => PreviousPhosItem(), cc => _busy == false);
            CommandNextPhosItem        = new RelayCommand(param => NextPhosItem(), cc => _busy == false);
            CommandPreviousSpectraItem = new RelayCommand(param => PreviousSpectraItem(), cc => _busy == false);
            CommandNextSpectraItem     = new RelayCommand(param => NextSpectraItem(), cc => _busy == false);
            CommandSave    = new RelayCommand(param => Save(), cc => _busy == false);
            CommandSaveAll = new RelayCommand(param => Save(true), cc => _busy == false);

            CommandCalibrate = new RelayCommand(param => Calibrate());

            SpectrumData       = new ObservableDataSource <Point>();
            SmoothSpectrumData = new ObservableDataSource <Point>();

            InitializeColorLegend();
        }
예제 #4
0
        static ANALYZER_RESULT Analysis(List <List <double> > wlList, List <List <double> > countsList, bool skipSaturated = false,
                                        bool skipNone = false, bool skipRefer = false, TEST_PARM_TYPE test_type = TEST_PARM_TYPE.SKIP, List <double> checks = null)
        {
            bool result = false;

            try
            {
                dtAllPeaks.Rows.Clear();
                dtSigPeaks.Rows.Clear();
                dtSmoothPeaks.Rows.Clear();
                dtPeakInfo.Rows.Clear();

                List <Peak> allPeaks;
                List <Peak> sigPeaks;
                List <List <PeakDetectInfo> > debugPeakInfoList = new List <List <PeakDetectInfo> >();
                ANALYZER_RESULT testResult     = ANALYZER_RESULT.ERROR;
                List <Point>    spectrum       = new List <Point>();
                List <Point>    smoothSpectrum = new List <Point>();

                if (wlList.Count == 1)
                {
                    var wl     = wlList[0];
                    var counts = countsList[0];
                    SpectrumAnalyzer analyzer = new SpectrumAnalyzer(wl, counts);

                    spectrum = analyzer.SpectrumData.SpectrumData;
                    var debugPeakInfo = new List <PeakDetectInfo>();
                    var debugInfo     = new DebugInfo();
                    testResult = analyzer.Test(out allPeaks, out sigPeaks, out debugPeakInfo, out debugInfo);
                    debugPeakInfoList.Add(debugPeakInfo);

                    for (int i = 0; i < allPeaks.Count; i++)
                    {
                        DataRow row    = dtAllPeaks.NewRow();
                        var     top    = Math.Round(allPeaks[i].Top.X, 1);
                        var     height = Math.Round(allPeaks[i].Height, 1);
                        var     width  = Math.Round(allPeaks[i].Width, 1);
                        var     fwhm   = Math.Round(allPeaks[i].FullWidthHalfMax, 1);
                        row[0] = Math.Round(allPeaks[i].Top.X, 1);
                        row[1] = Math.Round(allPeaks[i].Height, 1);
                        row[2] = Math.Round(allPeaks[i].Width, 1);
                        row[3] = Math.Round(allPeaks[i].FullWidthHalfMax, 1);
                        //if ( (top>=414&&top<=416))
                        //    File.AppendAllText(@"P:\Projects\405\temp\sudhin.csv",
                        //        top+","+height+","+width+","+fwhm+"\r\n");
                        dtAllPeaks.Rows.Add(row);
                    }
                    for (int i = 0; i < sigPeaks.Count; i++)
                    {
                        DataRow row = dtSigPeaks.NewRow();
                        row[0] = Math.Round(sigPeaks[i].Top.X, 1);
                        row[1] = Math.Round(sigPeaks[i].Height, 1);
                        row[2] = Math.Round(sigPeaks[i].Width, 1);
                        row[3] = Math.Round(sigPeaks[i].FullWidthHalfMax, 1);
                        dtSigPeaks.Rows.Add(row);
                    }
                }
                //else
                //{
                //    for (int i = 0; i < wlList.Count; i++)
                //    {
                //        var wl = wlList[i];
                //        var counts = countsList[i];
                //        List<PeakDetectInfo> peakInfo = new List<PeakDetectInfo>();
                //        var debugInfo = new DebugInfo();
                //        SpectrumAnalyzer analyzer = new SpectrumAnalyzer(wl, counts);
                //        var s = analyzer.SpectrumData.SpectrumData;
                //        if (i % 2 != 0)
                //            s.Reverse();
                //        spectrum.AddMany(s);
                //        analyzer.Test(out peakInfo, out debugInfo);
                //        if (chkPossibleCz.IsChecked == false && chkPossibleCzPeak.IsChecked == false)
                //        {
                //            chkPossibleCz.IsChecked = debugInfo.IsDetectedStraightLine;
                //            chkPossibleCzPeak.IsChecked = debugInfo.IsDetectedPeak;
                //        }
                //        if (chkN3Side2.IsChecked == false)
                //            chkN3Side2.IsChecked = debugInfo.IsDetectedN3Side2;

                //        debugPeakInfoList.Add(peakInfo);
                //    }

                //    testResult = SpectrumAnalyzer.TestAggregate(debugPeakInfoList);
                //}

                for (int i = 0; i < debugPeakInfoList.Count; i++)
                {
                    var debugPeakInfo = debugPeakInfoList[i];
                    for (int j = 0; j < debugPeakInfo.Count; j++)
                    {
                        var     key       = Math.Round(debugPeakInfo[j].StartPosition);
                        DataRow row       = null;
                        string  search    = "Location = " + key;
                        var     foundRows = dtPeakInfo.Select(search);
                        if (foundRows.Length == 0)
                        {
                            row    = dtPeakInfo.NewRow();
                            row[0] = key;
                            row[1] = debugPeakInfo[j].IsSaturated;
                            row[2] = debugPeakInfo[j].IsDetected;
                            dtPeakInfo.Rows.Add(row);
                        }
                        else
                        {
                            row = foundRows[0];
                            if (!debugPeakInfo[j].IsSaturated)
                            {
                                row[1] = false;
                            }

                            if ((bool)row[2] == false)
                            {
                                row[2] = debugPeakInfo[j].IsDetected;
                            }
                        }
                    }
                }

                if (test_type != TEST_PARM_TYPE.SKIP)
                {
                    if (skipSaturated && testResult == ANALYZER_RESULT.SATURATED)
                    {
                        result = true;
                    }
                    else if (skipNone && testResult == ANALYZER_RESULT.NONE)
                    {
                        result = true;
                    }
                    else if (skipRefer && testResult == ANALYZER_RESULT.REFER)
                    {
                        result = true;
                    }
                    else
                    {
                        if (test_type == TEST_PARM_TYPE.NATURAL)//natural
                        {
                            result = testResult == ANALYZER_RESULT.NATURAL_DIAMOND;
                        }
                        else if (test_type == TEST_PARM_TYPE.SYNTHETIC)//synthetic
                        {
                            result = (testResult == ANALYZER_RESULT.HPHT_SYNTHETIC_DIAMOND ||
                                      testResult == ANALYZER_RESULT.CVD_SYNTHETIC_DIAMOND);
                        }
                        else if (test_type == TEST_PARM_TYPE.SIMULANT)//simulant
                        {
                            result = testResult == ANALYZER_RESULT.NON_DIAMOND;
                        }
                        else if (test_type == TEST_PARM_TYPE.INDIVIDUAL)//individual
                        {
                            result = checks != null && checks.Count > 0;
                            foreach (var pos in checks)
                            {
                                var debugPeakInfo = debugPeakInfoList[0];
                                if (debugPeakInfo.Where(p => Math.Abs(p.StartPosition - pos) <= 3 && p.IsDetected).ToList().Count == 0)
                                {
                                    result = false;
                                    break;
                                }
                            }
                        }
                    }
                }

                return(testResult);

                //if (result == false)
                //{
                //update gui
                //return ResultString((int)testResult);

                //if (comboShowSmooth.SelectedIndex < 1)
                //{
                //    SpectrumData = new ObservableDataSource<Point>(spectrum);
                //    lgSmoothSpectrum.Visibility = Visibility.Collapsed;
                //    lgMainSpectrum.Visibility = Visibility.Visible;
                //}
                //else
                //{
                //    double pos = Convert.ToDouble(comboShowSmooth.Text);
                //    var debugPeakInfo = debugPeakInfoList[0];
                //    var dpi = debugPeakInfo.Where(p => Math.Abs(p.StartPosition - pos) <= 3).FirstOrDefault();
                //    if (dpi != null)
                //    {
                //        SmoothSpectrumData.Collection.AddMany(dpi.SmoothSpectrumData);
                //        lgSmoothSpectrum.Visibility = Visibility.Visible;
                //        lgMainSpectrum.Visibility = Visibility.Collapsed;

                //        for (int i = 0; i < dpi.SmoothPeaks.Count; i++)
                //        {
                //            DataRow row = dtSmoothPeaks.NewRow();
                //            row[0] = Math.Round(dpi.SmoothPeaks[i].Top.X, 1);
                //            row[1] = Math.Round(dpi.SmoothPeaks[i].Height, 1);
                //            row[2] = Math.Round(dpi.SmoothPeaks[i].Width, 1);
                //            row[3] = Math.Round(dpi.SmoothPeaks[i].FullWidthHalfMax, 1);
                //            dtSmoothPeaks.Rows.Add(row);

                //        }
                //    }
                //    else
                //    {
                //        SpectrumData = new ObservableDataSource<Point>(spectrum);
                //        lgSmoothSpectrum.Visibility = Visibility.Collapsed;
                //        lgMainSpectrum.Visibility = Visibility.Visible;
                //    }

                //}

                //}
            }
            catch (Exception ex)
            {
                //MessageBox.Show(ex.Message, "Error processing data");

                //SpectrumData.Collection.Clear();
                //SmoothSpectrumData.Collection.Clear();

                //PeakHeightThreshold = 0;
                //PeakWidthThreshold = 0;
                //mainWindow.Title = "Bad data";
                return(ANALYZER_RESULT.ERROR);
            }
        }
예제 #5
0
        void BwBatchMeasure(object sender, DoWorkEventArgs e)
        {
            List <Point> posiList = (List <Point>)e.Argument;

            if (posiList.Count <= 1)
            {
                e.Result = new Result(ResultStatus.ERROR, "No stones selected for measurement");
                Debug.WriteLine("no selected positions");
            }
            else
            {
                try
                {
                    BackgroundWorker bw = sender as BackgroundWorker;
                    int progress        = 0;
                    int step            = (int)(100.0 / (posiList.Count - 1) + 0.99);
                    bw.ReportProgress(step / 2);
                    _statusVM.IsBusy = true;

                    _measurementType = MeasurementType.MEASURE;
                    // 0. capture image before measurement
                    _cameraVM.StartEnqueue();
                    if (!_whMeasureControl.WaitOne(2000))
                    {
                        // todo: error in capture image
                        e.Result = new Result(ResultStatus.ERROR, "Failed to enqueue image");
                        return;
                    }
                    // camera reset to continue mode for display
                    _cameraVM.StopEnqueue();
                    ulong timeStamp = (ulong)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalMilliseconds;
                    _camResultsPre = new CamPhosResults(timeStamp, _cameraVM.GetImageQueue().ToList());
                    Thread.Sleep(200);

                    // loop through the positionlist to do each measurement
                    for (int i = 1; i < posiList.Count; i++)
                    {
                        // 1. move to ref position (EndPoint)
                        double deltaX = -(posiList[i].X - posiList[i - 1].X);
                        double deltaY = posiList[i].Y - posiList[i - 1].Y;

                        if (!_xyzAxesVM.MoveTo(deltaX, deltaY, false))
                        {
                            e.Result = new Result(ResultStatus.ERROR, "Failed to move stone to the reference position");
                            Debug.WriteLine("batchmeasure: MoveTo({0}, {1}) failed", deltaX, deltaY);
                            return;
                        }
                        Thread.Sleep(300);

                        // 2. turn on laser
                        if (!_xyzAxesVM.SetLaserOnOff(true))
                        {
                            e.Result = new Result(ResultStatus.ERROR, "Failed to turn on laser");
                            Debug.WriteLine("batchmeasure: SetLaserOnOff(true) failed");
                            return;
                        }
                        Thread.Sleep(1000);

                        // 3. capture image
                        _cameraVM.StartEnqueue();
                        if (!_whMeasureControl.WaitOne(2000))
                        {
                            // todo: error in capture image
                            e.Result = new Result(ResultStatus.ERROR, "Failed to enqueue image");
                            Debug.WriteLine("batchmeasure: StartEnqueue failed");
                            return;
                        }
                        // camera reset to continue mode for display
                        _cameraVM.StopEnqueue();
                        timeStamp       = (ulong)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalMilliseconds;
                        _camPhosResults = new CamPhosResults(timeStamp, _cameraVM.GetImageQueue().ToList());
                        Thread.Sleep(300);

                        // 4. spectrometer measure
                        if (mappingMeasure)
                        {
                            ResetSpectroResults();

                            double integrationTime = GlobalVariables.spectrometerSettings.IntegrationTime;
                            uint   numAverages     = GlobalVariables.spectrometerSettings.NumAverages;

                            Callback MeasurementEnd = MeasurementCompleteCallback;
                            if (!_spectrometerVM.StartPhosphorescenceMeasurement(GlobalVariables.spectrometerSettings.Delay, GlobalVariables.spectrometerSettings.Counts, integrationTime, numAverages, MeasurementEnd, out string error))
                            {
                                e.Result = new Result(ResultStatus.ERROR, "Failed in start phosphorescence measurement");
                                return;
                            }
                            if (!_whMeasureControl.WaitOne(15000))
                            {
                                // todo: error in getting spectrometer data
                                e.Result = new Result(ResultStatus.ERROR, "Failed in phosphorescence measurement");
                                return;
                            }

                            // save spectrum data to _spectroResults
                            for (int m = 0; m < _spectrometerPhosResults.Spectra.Count; m++)
                            {
                                _spectroResults.Spectra.Add(_spectrometerPhosResults.Spectra[m]);
                            }
                        }
                        else
                        {
                            Stopwatch watch  = Stopwatch.StartNew();
                            int       factor = 0;
                            int       index  = 2;
                            _peakInfoList.Clear();
                            ResetSpectroResults();
                            while (index >= 0 && index <= 4)
                            {
                                Console.WriteLine("spectrum parameter index: {0}", index);
                                double integrationTime = SpectrumParameters[index].Item1;
                                uint   numAverages     = SpectrumParameters[index].Item2;

                                Callback MeasurementEnd = MeasurementCompleteCallback;
                                if (!_spectrometerVM.StartPhosphorescenceMeasurement(GlobalVariables.spectrometerSettings.Delay, GlobalVariables.spectrometerSettings.Counts, integrationTime, numAverages, MeasurementEnd, out string error))
                                {
                                    e.Result = new Result(ResultStatus.ERROR, "Failed in start phosphorescence measurement");
                                    return;
                                }
                                if (!_whMeasureControl.WaitOne(15000))
                                {
                                    // todo: error in getting spectrometer data
                                    e.Result = new Result(ResultStatus.ERROR, "Failed in phosphorescence measurement");
                                    return;
                                }

                                // save spectrum data to _spectroResults
                                for (int m = 0; m < _spectrometerPhosResults.Spectra.Count; m++)
                                {
                                    _spectroResults.Spectra.Add(_spectrometerPhosResults.Spectra[m]);
                                }

                                // analyze spectrum data
                                List <double>         wl       = _spectrometerPhosResults.Spectra[0].Spectrum.Select(p => p.X).ToList();
                                List <double>         counts   = _spectrometerPhosResults.Spectra[0].Spectrum.Select(p => p.Y).ToList();
                                List <PeakDetectInfo> peakInfo = new List <PeakDetectInfo>();
                                _diamondResult = RamanAnalyzer.Analysis(wl, counts, out peakInfo);

                                if (_diamondResult == ANALYZER_RESULT.ERROR || _diamondResult == ANALYZER_RESULT.ERROR_SPIKE)
                                {
                                    break;
                                }

                                if (_diamondResult == ANALYZER_RESULT.NONE)
                                {
                                    _peakInfoList.Add(peakInfo);
                                    if (factor == 0 || factor == 1)
                                    {
                                        index++;
                                        factor = 1;
                                        continue;
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                                else if (_diamondResult == ANALYZER_RESULT.SATURATED)
                                {
                                    _peakInfoList.Add(peakInfo);
                                    if (factor == 0 || factor == -1)
                                    {
                                        index--;
                                        factor = -1;
                                        continue;
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                                else if (_diamondResult == ANALYZER_RESULT.NON_DIAMOND)
                                {
                                    if (index >= 2)
                                    {
                                        _peakInfoList.Clear();
                                    }
                                    _peakInfoList.Add(peakInfo);
                                    break;
                                }
                                else
                                {
                                    _peakInfoList.Clear();
                                    break;
                                }
                            }

                            watch.Stop();
                            long ms = watch.ElapsedMilliseconds;
                            Console.WriteLine("spectrum measurement spend: {0}", ms);

                            if (_peakInfoList.Count >= 2)
                            {
                                _diamondResult = SpectrumAnalyzer.TestAggregate(_peakInfoList);
                            }
                        }
                        Thread.Sleep(300);

                        // 5. turn off laser
                        if (!_xyzAxesVM.SetLaserOnOff(false))
                        {
                            e.Result = new Result(ResultStatus.ERROR, "Failed to turn off laser");
                            Debug.WriteLine("batchmeasure: SetLaserOnOff(false) failed");
                            return;
                        }
                        Thread.Sleep(300);

                        CamResList.Add(_camPhosResults);
                        SpeResList.Add(_spectroResults);
                        DiamondResList.Add(_diamondResult);
                        PeakInfoListList.Add(_peakInfoList);

                        bw.ReportProgress(progress += step);
                    }
                    e.Result = new Result(ResultStatus.SUCCESS, null);
                } catch (Exception ex)
                {
                    e.Result = new Result(ResultStatus.ERROR, ex.Message);
                    Debug.WriteLine(ex.Message);
                }
            }
        }
예제 #6
0
        void BwMeasure(object sender, DoWorkEventArgs e)
        {
            try
            {
                BackgroundWorker bw = sender as BackgroundWorker;
                int progress        = 0;
                int step            = 25;
                bw.ReportProgress(step / 2);
                _statusVM.IsBusy = true;

                _measurementType = MeasurementType.MEASURE;
                // 0. capture image before measurement
                _cameraVM.StartEnqueue();
                if (!_whMeasureControl.WaitOne(2000))
                {
                    // todo: error in capture image
                    e.Result = new Result(ResultStatus.ERROR, "Failed to enqueue image");
                    return;
                }
                // camera reset to continue mode for display
                _cameraVM.StopEnqueue();
                ulong timeStamp = (ulong)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalMilliseconds;
                _camResultsPre = new CamPhosResults(timeStamp, _cameraVM.GetImageQueue().ToList());
                Thread.Sleep(200);

                // 1. turn on laser
                if (!_xyzAxesVM.SetLaserOnOff(true))
                {
                    e.Result = new Result(ResultStatus.ERROR, "Failed to turn on the laser");
                    return;
                }
                bw.ReportProgress(progress += step);
                Thread.Sleep(1000);

                // 1.5 capture image
                _cameraVM.StartEnqueue();
                if (!_whMeasureControl.WaitOne(2000))
                {
                    // todo: error in capture image
                    e.Result = new Result(ResultStatus.ERROR, "Failed to enqueue image");
                    return;
                }
                // camera reset to continue mode for display
                _cameraVM.StopEnqueue();
                timeStamp       = (ulong)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalMilliseconds;
                _camPhosResults = new CamPhosResults(timeStamp, _cameraVM.GetImageQueue().ToList());
                Thread.Sleep(200);

                bw.ReportProgress(progress += step);
                // 2. spectrometer measure
                Stopwatch watch  = Stopwatch.StartNew();
                int       factor = 0;
                int       index  = 2;
                _peakInfoList.Clear();
                ResetSpectroResults();
                while (index >= 0 && index <= 4)
                {
                    Console.WriteLine("spectrum parameter index: {0}", index);
                    double integrationTime = SpectrumParameters[index].Item1;
                    uint   numAverages     = SpectrumParameters[index].Item2;

                    Callback MeasurementEnd = MeasurementCompleteCallback;
                    if (!_spectrometerVM.StartPhosphorescenceMeasurement(GlobalVariables.spectrometerSettings.Delay, GlobalVariables.spectrometerSettings.Counts, integrationTime, numAverages, MeasurementEnd, out string error))
                    {
                        e.Result = new Result(ResultStatus.ERROR, "Failed in start phosphorescence measurement");
                        return;
                    }
                    if (!_whMeasureControl.WaitOne(15000))
                    {
                        // todo: error in getting spectrometer data
                        e.Result = new Result(ResultStatus.ERROR, "Failed in phosphorescence measurement");
                        return;
                    }

                    // save spectrum data to _spectroResults
                    for (int i = 0; i < _spectrometerPhosResults.Spectra.Count; i++)
                    {
                        _spectroResults.Spectra.Add(_spectrometerPhosResults.Spectra[i]);
                    }

                    // analyze spectrum data
                    List <double>         wl       = _spectrometerPhosResults.Spectra[0].Spectrum.Select(p => p.X).ToList();
                    List <double>         counts   = _spectrometerPhosResults.Spectra[0].Spectrum.Select(p => p.Y).ToList();
                    List <PeakDetectInfo> peakInfo = new List <PeakDetectInfo>();
                    _diamondResult = RamanAnalyzer.Analysis(wl, counts, out peakInfo);

                    if (_diamondResult == ANALYZER_RESULT.ERROR || _diamondResult == ANALYZER_RESULT.ERROR_SPIKE)
                    {
                        break;
                    }

                    if (_diamondResult == ANALYZER_RESULT.NONE)
                    {
                        _peakInfoList.Add(peakInfo);
                        if (factor == 0 || factor == 1)
                        {
                            index++;
                            factor = 1;
                            continue;
                        }
                        else
                        {
                            break;
                        }
                    }
                    else if (_diamondResult == ANALYZER_RESULT.SATURATED)
                    {
                        _peakInfoList.Add(peakInfo);
                        if (factor == 0 || factor == -1)
                        {
                            index--;
                            factor = -1;
                            continue;
                        }
                        else
                        {
                            break;
                        }
                    }
                    else if (_diamondResult == ANALYZER_RESULT.NON_DIAMOND)
                    {
                        if (index >= 2)
                        {
                            _peakInfoList.Clear();
                        }
                        _peakInfoList.Add(peakInfo);
                        break;
                    }
                    else
                    {
                        _peakInfoList.Clear();
                        break;
                    }
                }

                if (_peakInfoList.Count >= 2)
                {
                    _diamondResult = SpectrumAnalyzer.TestAggregate(_peakInfoList);
                }
                _spectrometerPhosResults = _spectroResults;

                watch.Stop();
                long ms = watch.ElapsedMilliseconds;
                Console.WriteLine("spectrum measurement spend: {0}", ms);
                Thread.Sleep(200);

                bw.ReportProgress(progress += step);
                // 3. turn off laser
                if (!_xyzAxesVM.SetLaserOnOff(false))
                {
                    e.Result = new Result(ResultStatus.ERROR, "Failed to turn off the laser");
                    return;
                }

                bw.ReportProgress(progress += step);
                e.Result = new Result(ResultStatus.SUCCESS, null);
            } catch (Exception ex)
            {
                Console.WriteLine("measurementvm exception: " + ex.Message);
                e.Result = new Result(ResultStatus.ERROR, ex.Message);
            }
        }