// Ignore Spelling: Uut

using NLog;
using Raytheon.Instruments;
using Raytheon.Units;
using System;
using System.Windows;
using System.Collections.Generic;
using System.Drawing;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

namespace MeasurementManagerLib
{
   public class SpaceChamberLspsMeasurementManager
   {
      private INetCdfData netCdfData_ = null;
      private readonly ILspsChamber lspsChamber_;
      private readonly ILogger _logger;

      /// <summary>
      /// TODO: add video recorder instrument name as parameter
      /// constructor that uses instrument manager for creating an instrument
      /// </summary>
      /// <param name="instrumentManager"></param>
      /// <param name="deviceName"></param>
      public SpaceChamberLspsMeasurementManager(IInstrumentManager instrumentManager, string lspsChamber, string netCdfData)
      {
         _logger = LogManager.GetCurrentClassLogger();
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         lspsChamber_ = instrumentManager.GetInstrument<ILspsChamber>(lspsChamber);
         if (lspsChamber_ == null)
         {
            throw new Exception($"Instrument manager failed to create LSPS Chamber Device {lspsChamber}. Check your settings.");
         }
         lspsChamber_.Initialize();

         netCdfData_ = instrumentManager.GetInstrument<INetCdfData>(netCdfData);
         if (netCdfData_ == null)
         {
            throw new Exception($"Instrument manager failed to create NetCdfData Device {netCdfData}. Check your settings.");
         }
      }

      /// <summary>
      /// shuts down LSPS manager, clears resources
      /// </summary>
      public void Shutdown()
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");
         lspsChamber_?.Shutdown();
      }

      #region Autofill functions
      /// <summary>
      /// Auto Fill Cool Down
      /// </summary>
      public void AutoFillCoolDown(int pollingRateInMs = 1000, int timeOutInMs = 120000)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            lspsChamber_.AutoFillCoolDown();

            Raytheon.Instruments.LSPS.AutoFillState state;
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();

            do
            {
               if (stopwatch.ElapsedMilliseconds > timeOutInMs)
               {
                  throw new Exception($"Timed out waiting for Autofill to transition to cooling. Timeout value: {timeOutInMs} ms");
               }

               Thread.Sleep(pollingRateInMs);
               state = lspsChamber_.GetAutoFillState();
            } while (state != Raytheon.Instruments.LSPS.AutoFillState.COOLING);

            stopwatch.Stop();
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }

      /// <summary>
      /// Auto Fill Warm Up
      /// </summary>
      public void AutoFillWarmUp(int pollingRateInMs = 1000, int timeOutInMs = 10000)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            lspsChamber_.AutoFillWarmUp();

            Raytheon.Instruments.LSPS.AutoFillState state;
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();

            do
            {
               if (stopwatch.ElapsedMilliseconds > timeOutInMs)
               {
                  throw new Exception($"Timed out waiting for Autofill to transition to cooling. Timeout value: {timeOutInMs} ms");
               }

               Thread.Sleep(pollingRateInMs);
               state = lspsChamber_.GetAutoFillState();
            } while (state != Raytheon.Instruments.LSPS.AutoFillState.WARMING);

            stopwatch.Stop();
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }

      /// <summary>
      /// Auto Fill Force
      /// </summary>
      public void AutoFillForce()
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            lspsChamber_?.AutoFillForce();
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }

      /// <summary>
      /// Auto Fill Turn Off
      /// </summary>
      public void AutoFillTurnOff(int pollingRateInMs = 1000, int timeOutInMs = 60000)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            lspsChamber_.AutoFillTurnOff();

            Raytheon.Instruments.LSPS.AutoFillState state;
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();

            do
            {
               if (stopwatch.ElapsedMilliseconds > timeOutInMs)
               {
                  throw new Exception($"Timed out waiting for Autofill to transition to cooling. Timeout value: {timeOutInMs} ms");
               }

               Thread.Sleep(pollingRateInMs);
               state = lspsChamber_.GetAutoFillState();
            } while (state != Raytheon.Instruments.LSPS.AutoFillState.OFF);

            stopwatch.Stop();
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }
      #endregion

      #region NIF Functions
      /// <summary>
      /// Close Gate Valve
      /// </summary>
      public void CloseLspsGateValve(int pollingRateInMs = 1000, int timeOutInMs = 120000)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            lspsChamber_?.CloseLspsGateValve();
            WaitForLspsGateValveOperation(Raytheon.Instruments.LSPS.GateValvePosition.CLOSE, pollingRateInMs, timeOutInMs);
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }

      /// <summary>
      /// Open Gate Valve
      /// </summary>
      public void OpenLspsGateValve(int pollingRateInMs = 1000, int timeOutInMs = 120000)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            lspsChamber_?.OpenLspsGateValve();
            WaitForLspsGateValveOperation(Raytheon.Instruments.LSPS.GateValvePosition.OPEN, pollingRateInMs, timeOutInMs);
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }

      /// <summary>
      /// Wait for UUT Gate Valve to be in position
      /// </summary>
      private void WaitForLspsGateValveOperation(Raytheon.Instruments.LSPS.GateValvePosition gateValvePosition, int pollingRateInMs, int timeOutInMs)
      {
         int val = 0;
         Stopwatch stopwatch = new Stopwatch();
         stopwatch.Start();
         do
         {
            if (stopwatch.ElapsedMilliseconds > timeOutInMs)
            {
               throw new Exception($"Timed out waiting for LSPS Gate Valve to {gateValvePosition.ToString()}. Timeout value: {timeOutInMs} ms");
            }

            Thread.Sleep(pollingRateInMs);
            val = lspsChamber_.GetInputIndex((int)gateValvePosition);
         } while (val == 0);

         stopwatch.Stop();
      }

      /// <summary>
      /// Get UUT Gate Valve Position
      /// </summary>
      public double GetTemperature(Raytheon.Instruments.LSPS.TemperatureIndex tempIndex)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            return lspsChamber_.GetTemperature(tempIndex);
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }
      #endregion

      #region RIO Functions
      /// <summary>
      /// Close Gate Valve
      /// </summary>
      public void CloseVhfGateValve(int pollingRateInMs = 1000, int timeOutInMs = 120000)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            lspsChamber_?.CloseVhfGateValve();

            WaitForVhfGateValveOperation(Raytheon.Instruments.LSPS.GateValvePosition.CLOSE, pollingRateInMs, timeOutInMs);
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }

      /// <summary>
      /// Open Gate Valve
      /// </summary>
      public void OpenVhfGateValve(int pollingRateInMs = 1000, int timeOutInMs = 120000)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            lspsChamber_?.OpenVhfGateValve();

            WaitForVhfGateValveOperation(Raytheon.Instruments.LSPS.GateValvePosition.OPEN, pollingRateInMs, timeOutInMs);
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }

      /// <summary>
      /// Wait for VHF Gate Valve to be in position
      /// </summary>
      private void WaitForVhfGateValveOperation(Raytheon.Instruments.LSPS.GateValvePosition gateValvePosition, int pollingRateInMs, int timeOutInMs)
      {
         int val = 0;
         Stopwatch stopwatch = new Stopwatch();
         stopwatch.Start();
         do
         {
            if (stopwatch.ElapsedMilliseconds > timeOutInMs)
            {
               throw new Exception($"Timed out waiting for VHF Gate Valve to {gateValvePosition.ToString()}. Timeout value: {timeOutInMs} ms");
            }

            Thread.Sleep(pollingRateInMs);

            if (gateValvePosition == Raytheon.Instruments.LSPS.GateValvePosition.OPEN)
               val = lspsChamber_.GetVhfGateValveOpenInput();
            else
               val = lspsChamber_.GetVhfGateValveClosedInput();
         } while (val == 0);

         stopwatch.Stop();
      }

      /// <summary>
      /// Verify Gate Valve Chamber Pressure
      /// </summary>
      public void VerifyGateValveChamberPressure(double minLimit, double maxLimit)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            double val = lspsChamber_.GetVhfGateValveChamberPressure();

            if (val < minLimit || val > maxLimit)
            {
               throw new Exception($"Gate valve chamber pressure is out of range. Measured: {val}. Limits: [{minLimit}, {maxLimit}]");
            }
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }

      /// <summary>
      /// Verify Gate Valve Canister Pressure
      /// </summary>
      public void VerifyGateValveCanisterPressure(double minLimit, double maxLimit)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            double val = lspsChamber_.GetVhfGateValveUutPressure();

            if (val < minLimit || val > maxLimit)
            {
               throw new Exception($"Gate valve canister pressure is out of range. Measured: {val}. Limits: [{minLimit}, {maxLimit}]");
            }
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }
      #endregion

      #region Chamber Vacuum Functions
      /// <summary>
      /// Verify Chamber Pressure (CVAC)
      /// </summary>
      public void VerifyLspsChamberPressure(double minLimit, double maxLimit)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            double val = lspsChamber_.GetLspsChamberPressure();

            if (val < minLimit || val > maxLimit)
            {
               throw new Exception($"PLC Chamber pressure is out of range. Measured: {val}. Limits: [{minLimit}, {maxLimit}]");
            }
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }

      /// <summary>
      /// Verify Sensor Pressure (SVAC)
      /// </summary>
      public void VerifyLspsUutPressure(double minLimit, double maxLimit)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            double val = lspsChamber_.GetLspsUutPressure();

            if (val < minLimit || val > maxLimit)
            {
               throw new Exception($"PLC Chamber pressure is out of range. Measured: {val}. Limits: [{minLimit}, {maxLimit}]");
            }
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }
      #endregion

      #region GALIL Functions
      public void FilterWheelHome(int pollingRateInMs = 2000, int timeOutInMs = 120000)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            lspsChamber_.FilterWheelHome();

            Raytheon.Instruments.LSPS.TargetAndFilterWheelStatus status;
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            do
            {
               if (stopwatch.ElapsedMilliseconds > timeOutInMs)
               {
                  throw new Exception($"Timed out waiting for FilterWheel to home. Timeout value: {timeOutInMs} ms");
               }

               Thread.Sleep(pollingRateInMs);
               status = lspsChamber_.GetFilterWheelStatus();
            } while (status != Raytheon.Instruments.LSPS.TargetAndFilterWheelStatus.IN_POSITION);

            stopwatch.Stop();
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }

      /// <summary>
      /// Set Filter Wheel position
      /// </summary>
      /// <param name="position"></param>
      public void SetFilterWheelPosition(int position, int pollingRateInMs = 2000, int timeOutInMs = 120000)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");
         
         try
         {
            lspsChamber_.SetFilterWheelPosition(position);

            Raytheon.Instruments.LSPS.TargetAndFilterWheelStatus status;
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            do
            {
               if (stopwatch.ElapsedMilliseconds > timeOutInMs)
               {
                  throw new Exception($"Timed out waiting for FilterWheel to move. Timeout value: {timeOutInMs} ms");
               }

               Thread.Sleep(pollingRateInMs);
               status = lspsChamber_.GetFilterWheelStatus();
            } while (status != Raytheon.Instruments.LSPS.TargetAndFilterWheelStatus.IN_POSITION);

            stopwatch.Stop();
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }

      /// <summary>
      /// Get Filter Wheel position
      /// </summary>
      /// <param name="position"></param>
      public int GetFilterWheelPosition()
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            return lspsChamber_.GetFilterWheelPosition();
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }

      public void TargetWheelHome(int pollingRateInMs = 2000, int timeOutInMs = 120000)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            lspsChamber_.TargetWheelHome();

            Raytheon.Instruments.LSPS.TargetAndFilterWheelStatus status;
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            do
            {
               if (stopwatch.ElapsedMilliseconds > timeOutInMs)
               {
                  throw new Exception($"Timed out waiting for TargetWheel to home. Timeout value: {timeOutInMs} ms");
               }

               Thread.Sleep(pollingRateInMs);
               status = lspsChamber_.GetTargetWheelStatus();
            } while (status != Raytheon.Instruments.LSPS.TargetAndFilterWheelStatus.IN_POSITION);

            stopwatch.Stop();
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }

      /// <summary>
      /// Sets target wheel position
      /// </summary>
      /// <param name="position"></param>
      public void SetTargetWheelPosition(int position, int pollingRateInMs = 2000, int timeOutInMs = 120000)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            lspsChamber_.SetTargetWheelPosition(position);

            Raytheon.Instruments.LSPS.TargetAndFilterWheelStatus status;
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            do
            {
               if (stopwatch.ElapsedMilliseconds > timeOutInMs)
               {
                  throw new Exception($"Timed out waiting for TargetWheel to move. Timeout value: {timeOutInMs} ms");
               }

               Thread.Sleep(pollingRateInMs);
               status = lspsChamber_.GetTargetWheelStatus();
            } while (status != Raytheon.Instruments.LSPS.TargetAndFilterWheelStatus.IN_POSITION);

            stopwatch.Stop();
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }

      public void SteeringMirrorHome(int pollingRateInMs = 2000, int timeOutInMs = 120000)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            lspsChamber_.SteeringMirrorHome();

            Tuple<Raytheon.Instruments.LSPS.SteeringMirrorStatus, Raytheon.Instruments.LSPS.SteeringMirrorStatus> steeringMirrorStatus;
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            do
            {
               if (stopwatch.ElapsedMilliseconds > timeOutInMs)
               {
                  throw new Exception($"Timed out waiting for Steering Mirror to home. Timeout value: {timeOutInMs} ms");
               }

               Thread.Sleep(pollingRateInMs);
               steeringMirrorStatus = lspsChamber_.GetSteeringMirrorStatus();
            } while (steeringMirrorStatus.Item1 != Raytheon.Instruments.LSPS.SteeringMirrorStatus.IN_POSITION || steeringMirrorStatus.Item2 != Raytheon.Instruments.LSPS.SteeringMirrorStatus.IN_POSITION);

            stopwatch.Stop();
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }

      /// <summary>
      /// Get target wheel position
      /// </summary>
      /// <param name="position"></param>
      public int GetTargetWheelPosition()
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            return lspsChamber_.GetTargetWheelPosition();
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }

      public void SteeringMirrorStop(int pollingRateInMs = 2000, int timeOutInMs = 10000)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            lspsChamber_.SteeringMirrorStop();

            Tuple<Raytheon.Instruments.LSPS.SteeringMirrorStatus, Raytheon.Instruments.LSPS.SteeringMirrorStatus> steeringMirrorStatus;
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            do
            {
               if (stopwatch.ElapsedMilliseconds > timeOutInMs)
               {
                  throw new Exception($"Timed out waiting for Steering Mirror to stop. Timeout value: {timeOutInMs} ms");
               }

               Thread.Sleep(pollingRateInMs);
               steeringMirrorStatus = lspsChamber_.GetSteeringMirrorStatus();
            } while (steeringMirrorStatus.Item1 != Raytheon.Instruments.LSPS.SteeringMirrorStatus.IN_POSITION || steeringMirrorStatus.Item2 != Raytheon.Instruments.LSPS.SteeringMirrorStatus.IN_POSITION);

            stopwatch.Stop();
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }

      public void SteeringMirrorMove(double az, double el, double speed, Raytheon.Instruments.LSPS.WaitOption waitOption = Raytheon.Instruments.LSPS.WaitOption.WAIT, int pollingRateInMs = 2000, int timeOutInMs = 120000)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            lspsChamber_.SteeringMirrorMove(az, el, speed);

            if (waitOption == Raytheon.Instruments.LSPS.WaitOption.WAIT)
            {
               Tuple<Raytheon.Instruments.LSPS.SteeringMirrorStatus, Raytheon.Instruments.LSPS.SteeringMirrorStatus> steeringMirrorStatus;
               Stopwatch stopwatch = new Stopwatch();
               stopwatch.Start();
               do
               {
                  if (stopwatch.ElapsedMilliseconds > timeOutInMs)
                  {
                     throw new Exception($"Timed out waiting for Steering Mirror to move. Timeout value: {timeOutInMs} ms");
                  }

                  Thread.Sleep(pollingRateInMs);
                  steeringMirrorStatus = lspsChamber_.GetSteeringMirrorStatus();
               } while (steeringMirrorStatus.Item1 != Raytheon.Instruments.LSPS.SteeringMirrorStatus.IN_POSITION || steeringMirrorStatus.Item2 != Raytheon.Instruments.LSPS.SteeringMirrorStatus.IN_POSITION);
               stopwatch.Stop();
            }
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }

      public Tuple<double, double> SteeringMirrorGetBeamAngles()
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            return lspsChamber_.SteeringMirrorGetBeamAngles();
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }

      public void SteeringMirrorSetBeamSpeed(double speed)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            lspsChamber_?.SteeringMirrorSetBeamSpeed(speed);
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }

      public void SteeringMirrorSetRightLeftArrowAngle(double angle)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            lspsChamber_?.SteeringMirrorSetRightLeftArrowAngle(angle);
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }

      public void SteeringMirrorSetUpDownArrowAngle(double angle)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");
         
         try
         {
            lspsChamber_?.SteeringMirrorSetUpDownArrowAngle(angle);
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }

      public void SteeringMirrorLoadProfile(string profileFilePath)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            lspsChamber_?.SteeringMirrorLoadProfileFromFile(profileFilePath);
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }

      public void SteeringMirrorResetProfile()
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");
         
         try
         {
            lspsChamber_?.SteeringMirrorResetProfile();
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }

      public void SteeringMirrorRunProfile(Raytheon.Instruments.LSPS.SteeringMirrorProfileMode profileMode = Raytheon.Instruments.LSPS.SteeringMirrorProfileMode.LEARNED,
         Raytheon.Instruments.LSPS.SteeringMirrorMovementMode movementMode = Raytheon.Instruments.LSPS.SteeringMirrorMovementMode.ABSOLUTE,
         Raytheon.Instruments.LSPS.WaitOption waitOption = Raytheon.Instruments.LSPS.WaitOption.NO_WAIT,
         int pollingRateInMs = 2000, int timeOutInMs = 360000
         )
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            lspsChamber_.SteeringMirrorSetBeamSpeed(12000);
            lspsChamber_.SteeringMirrorRunProfile(profileMode, movementMode);

            if (waitOption == Raytheon.Instruments.LSPS.WaitOption.WAIT)
            {
               Tuple<Raytheon.Instruments.LSPS.SteeringMirrorStatus, Raytheon.Instruments.LSPS.SteeringMirrorStatus> steeringMirrorStatus;
               Stopwatch stopwatch = new Stopwatch();
               stopwatch.Start();
               do
               {
                  if (stopwatch.ElapsedMilliseconds > timeOutInMs)
                  {
                     throw new Exception($"Timed out waiting for Steering Mirror to complete profile move. Timeout value: {timeOutInMs} ms");
                  }

                  Thread.Sleep(pollingRateInMs);
                  steeringMirrorStatus = lspsChamber_.GetSteeringMirrorStatus();
               } while (steeringMirrorStatus.Item1 != Raytheon.Instruments.LSPS.SteeringMirrorStatus.IN_POSITION || steeringMirrorStatus.Item2 != Raytheon.Instruments.LSPS.SteeringMirrorStatus.IN_POSITION);
               stopwatch.Stop();
            }
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }

      public void SteeringMirrorMoveToBeginningOfProfile(Raytheon.Instruments.LSPS.WaitOption waitOption = Raytheon.Instruments.LSPS.WaitOption.WAIT, int pollingRateInMs = 2000, int timeOutInMs = 240000)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            lspsChamber_.SteeringMirrorMoveToBeginningOfProfile();

            if (waitOption == Raytheon.Instruments.LSPS.WaitOption.WAIT)
            {
               Tuple<Raytheon.Instruments.LSPS.SteeringMirrorStatus, Raytheon.Instruments.LSPS.SteeringMirrorStatus> steeringMirrorStatus;
               Stopwatch stopwatch = new Stopwatch();
               stopwatch.Start();
               do
               {
                  if (stopwatch.ElapsedMilliseconds > timeOutInMs)
                  {
                     throw new Exception($"Timed out waiting for Steering Mirror to move. Timeout value: {timeOutInMs} ms");
                  }

                  Thread.Sleep(pollingRateInMs);
                  steeringMirrorStatus = lspsChamber_.GetSteeringMirrorStatus();
               } while (steeringMirrorStatus.Item1 != Raytheon.Instruments.LSPS.SteeringMirrorStatus.IN_POSITION || steeringMirrorStatus.Item2 != Raytheon.Instruments.LSPS.SteeringMirrorStatus.IN_POSITION);
               stopwatch.Stop();
            }
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }

      public void SteeringMirrorRunNextStepInProfile(Raytheon.Instruments.LSPS.WaitOption waitOption = Raytheon.Instruments.LSPS.WaitOption.WAIT, int pollingRateInMs = 2000, int timeOutInMs = 30000)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            lspsChamber_.SteeringMirrorRunNextStepInProfile();

            if (waitOption == Raytheon.Instruments.LSPS.WaitOption.WAIT)
            {
               Tuple<Raytheon.Instruments.LSPS.SteeringMirrorStatus, Raytheon.Instruments.LSPS.SteeringMirrorStatus> steeringMirrorStatus;
               Stopwatch stopwatch = new Stopwatch();
               stopwatch.Start();
               do
               {
                  if (stopwatch.ElapsedMilliseconds > timeOutInMs)
                  {
                     throw new Exception($"Timed out waiting for Steering Mirror to move. Timeout value: {timeOutInMs} ms");
                  }

                  Thread.Sleep(pollingRateInMs);
                  steeringMirrorStatus = lspsChamber_.GetSteeringMirrorStatus();
               } while (steeringMirrorStatus.Item1 != Raytheon.Instruments.LSPS.SteeringMirrorStatus.IN_POSITION || steeringMirrorStatus.Item2 != Raytheon.Instruments.LSPS.SteeringMirrorStatus.IN_POSITION);
               stopwatch.Stop();
            }
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
           throw;
         }
      }
      #endregion

      #region BlackBody Functions
      /// <summary>
      /// Set BlackBody Setpoint Temperature
      /// </summary>
      /// <param name="temperature"></param>
      /// <param name="pollingRateInMs"></param>
      /// <param name="timeOutInMs"></param>
      public void SetBlackBodySetpointTemperature(double temperature, Raytheon.Instruments.LSPS.WaitOption waitOption = Raytheon.Instruments.LSPS.WaitOption.NO_WAIT, int pollingRateInMs = 2000, int timeOutInMs = 600000)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            lspsChamber_.SetBlackBodySetpointTemperature(temperature);

            if (waitOption == Raytheon.Instruments.LSPS.WaitOption.WAIT)
            {
               ConfirmBlackBodySetpointTemperature(temperature, pollingRateInMs, timeOutInMs);
            }
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }

      /// <summary>
      /// Confirm BlackBody Setpoint Temperature
      /// </summary>
      /// <param name="temperature"></param>
      /// <param name="pollingRateInMs"></param>
      /// <param name="timeOutInMs"></param>
      public void ConfirmBlackBodySetpointTemperature(double temperature, int pollingRateInMs = 2000, int timeOutInMs = 600000)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            const double TEMP_DELTA_ALLOWED = 0.1;

            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();

            Tuple<double, double> temp;
            do
            {
               if (stopwatch.ElapsedMilliseconds > timeOutInMs)
               {
                  throw new Exception($"Timed out waiting for blackbody to reach temperature setpoint. Timeout value: {timeOutInMs} ms");
               }

               Thread.Sleep(pollingRateInMs);
               temp = lspsChamber_.GetBlackbodyTemperature();
            } while (Math.Abs(temp.Item1 - temperature) >= TEMP_DELTA_ALLOWED);

            Tuple<Raytheon.Instruments.LSPS.Stability, Raytheon.Instruments.LSPS.Stability> stability;
            do
            {
               if (stopwatch.ElapsedMilliseconds > timeOutInMs)
               {
                  throw new Exception($"Timed out waiting for blackbody's temperature to stabilize. Timeout value: {timeOutInMs} ms");
               }

               Thread.Sleep(pollingRateInMs);
               stability = lspsChamber_.GetBlackbodyStability();
            } while (stability.Item1 != Raytheon.Instruments.LSPS.Stability.STABLE);

            stopwatch.Stop();
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }
      #endregion

      #region Chopper Functions
      /// <summary>
      /// Set Chopper Frequency
      /// </summary>
      /// <param name="frequency"></param>
      public void SetChopperFrequency(double frequency, int pollingRateInMs = 1000, int timeOutInMs = 600000)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            lspsChamber_.SetChopperFrequency(frequency);

            const double FREQ_DELTA_ALLOWED = 0.0001;
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();

            do
            {
               if (stopwatch.ElapsedMilliseconds > timeOutInMs)
               {
                  throw new Exception($"Timed out waiting for Chopper to reach frequency setpoint. Timeout value: {timeOutInMs} ms");
               }

               Thread.Sleep(pollingRateInMs);
            } while (Math.Abs(lspsChamber_.GetChopperFrequency() - frequency) >= FREQ_DELTA_ALLOWED);

            do
            {
               if (stopwatch.ElapsedMilliseconds > timeOutInMs)
               {
                  throw new Exception($"Timed out waiting for Chopper to stabilize. Timeout value: {timeOutInMs} ms");
               }

               Thread.Sleep(pollingRateInMs);
            } while (lspsChamber_.GetChopperStability() != Raytheon.Instruments.LSPS.Stability.STABLE);

            stopwatch.Stop();
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }

      /// <summary>
      /// Turn off Chopper wheel
      /// </summary>
      public void TurnOffChopperWheel(int pollingRateInMs = 1000, int timeOutInMs = 120000)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            lspsChamber_.TurnOffChopperWheel();

            Raytheon.Instruments.LSPS.ChopperState state;
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();

            do
            {
               if (stopwatch.ElapsedMilliseconds > timeOutInMs)
               {
                  throw new Exception($"Timed out waiting for Chopper Wheel to turn off. Timeout value: {timeOutInMs} ms");
               }

               Thread.Sleep(pollingRateInMs);
               state = lspsChamber_.GetChopperState();
            } while (state != Raytheon.Instruments.LSPS.ChopperState.OFF);

            stopwatch.Stop();
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }

      /// <summary>
      /// Stop chopper wheel at open position
      /// </summary>
      public void SetStopOpen(int pollingRateInMs = 1000, int timeOutInMs = 120000)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            lspsChamber_.SetStopOpen();

            Raytheon.Instruments.LSPS.ChopperState state;
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();

            do
            {
               if (stopwatch.ElapsedMilliseconds > timeOutInMs)
               {
                  throw new Exception($"Timed out waiting for Chopper Wheel to stop in Open position. Timeout value: {timeOutInMs} ms");
               }

               Thread.Sleep(pollingRateInMs);
               state = lspsChamber_.GetChopperState();
            } while (state != Raytheon.Instruments.LSPS.ChopperState.STOP_OPEN);

            do
            {
               if (stopwatch.ElapsedMilliseconds > timeOutInMs)
               {
                  throw new Exception($"Timed out waiting for Chopper Wheel to stabilize. Timeout value: {timeOutInMs} ms");
               }

               Thread.Sleep(pollingRateInMs);
            } while (lspsChamber_.GetChopperStability() != Raytheon.Instruments.LSPS.Stability.STABLE);

            stopwatch.Stop();
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }

      /// <summary>
      /// Stop chopper wheel at closed position
      /// </summary>
      public void SetStopClosed(int pollingRateInMs = 1000, int timeOutInMs = 120000)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            lspsChamber_.SetStopClosed();

            Raytheon.Instruments.LSPS.ChopperState state;
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();

            do
            {
               if (stopwatch.ElapsedMilliseconds > timeOutInMs)
               {
                  throw new Exception($"Timed out waiting for Chopper Wheel to stop in Closed position. Timeout value: {timeOutInMs} ms");
               }

               Thread.Sleep(pollingRateInMs);
               state = lspsChamber_.GetChopperState();
            } while (state != Raytheon.Instruments.LSPS.ChopperState.STOP_CLOSE);

            do
            {
               if (stopwatch.ElapsedMilliseconds > timeOutInMs)
               {
                  throw new Exception($"Timed out waiting for Chopper Wheel to stabilize. Timeout value: {timeOutInMs} ms");
               }

               Thread.Sleep(pollingRateInMs);
            } while (lspsChamber_.GetChopperStability() != Raytheon.Instruments.LSPS.Stability.STABLE);

            stopwatch.Stop();
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }
      #endregion

      #region Misc Functions
      /// <summary>
      /// Send A Command. Only for SET commands.
      /// DO NOT use for GET Commands as they require processing of returned data
      /// </summary>
      /// <param name="command"></param>
      public void SendACommand(string command)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            lspsChamber_.SendACommand(command);
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }

      public void ProcessNcdfData(string prefix, string suffix, string testDataPath)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");

         try
         {
            netCdfData_.ProcessNcdfData(prefix, suffix, testDataPath);
         }
         catch (Exception ex)
         {
            _logger.Error(ex.Message);
            throw;
         }
      }

      public void AddNcdfAttributes()
      {
         //-----------------------------Autofill------------------------------------

         netCdfData_.SetValue(Raytheon.Instruments.NCDF.Names.RADCAL_AUTOFILL_TIMETOFILL, lspsChamber_.GetTimeToFill(), Raytheon.Instruments.NCDF.AttrPosition.GLOBAL);

         netCdfData_.SetValue(Raytheon.Instruments.NCDF.Names.RADCAL_AUTOFILL_STATE, lspsChamber_.GetAutoFillState().ToString(), Raytheon.Instruments.NCDF.AttrPosition.GLOBAL);

         //-----------------------------Blackbody------------------------------------

         netCdfData_.SetValue(Raytheon.Instruments.NCDF.Names.MEASURED_BLACK_BODY_TEMPERATURE, lspsChamber_.GetBlackbodyTemperature().Item1, Raytheon.Instruments.NCDF.AttrPosition.GLOBAL);

         netCdfData_.SetValue(Raytheon.Instruments.NCDF.Names.RADCAL_BB_RATE_O_CHANGE, lspsChamber_.GetBlackbodyRateOfChange(), Raytheon.Instruments.NCDF.AttrPosition.GLOBAL);

         netCdfData_.SetValue(Raytheon.Instruments.NCDF.Names.RADCAL_BB_CTRL_STATE, lspsChamber_.GetBlackbodyControlState().ToString(), Raytheon.Instruments.NCDF.AttrPosition.GLOBAL);

         netCdfData_.SetValue(Raytheon.Instruments.NCDF.Names.RADCAL_BB_HEATER, lspsChamber_.GetBlackbodyHeaterPercent(), Raytheon.Instruments.NCDF.AttrPosition.GLOBAL);

         netCdfData_.SetValue(Raytheon.Instruments.NCDF.Names.RADCAL_BB_SETPOINT, lspsChamber_.GetBlackbodySetpoint(), Raytheon.Instruments.NCDF.AttrPosition.GLOBAL);

         netCdfData_.SetValue(Raytheon.Instruments.NCDF.Names.RADCAL_BB_STABILITY_A, lspsChamber_.GetBlackbodyStability().Item1.ToString(), Raytheon.Instruments.NCDF.AttrPosition.GLOBAL);

         netCdfData_.SetValue(Raytheon.Instruments.NCDF.Names.RADCAL_BB_STABILITY_B, lspsChamber_.GetBlackbodyStability().Item2.ToString(), Raytheon.Instruments.NCDF.AttrPosition.GLOBAL);

         netCdfData_.SetValue(Raytheon.Instruments.NCDF.Names.RADCAL_BB_BIT, lspsChamber_.GetBlackbodyBIT(), Raytheon.Instruments.NCDF.AttrPosition.GLOBAL);

         //-----------------------------CVAC------------------------------------

         netCdfData_.SetValue(Raytheon.Instruments.NCDF.Names.RADCAL_C_VAC, lspsChamber_.GetLspsChamberPressure(), Raytheon.Instruments.NCDF.AttrPosition.GLOBAL);

         netCdfData_.SetValue(Raytheon.Instruments.NCDF.Names.RADCAL_S_VAC, lspsChamber_.GetLspsUutPressure(), Raytheon.Instruments.NCDF.AttrPosition.GLOBAL);

         //-----------------------------Chopper------------------------------------

         netCdfData_.SetValue(Raytheon.Instruments.NCDF.Names.RADCAL_CHOPPER_FREQ, lspsChamber_.GetChopperFrequency(), Raytheon.Instruments.NCDF.AttrPosition.GLOBAL);

         netCdfData_.SetValue(Raytheon.Instruments.NCDF.Names.RADCAL_CHOPPER_STABILITY, lspsChamber_.GetChopperStability().ToString(), Raytheon.Instruments.NCDF.AttrPosition.GLOBAL);

         netCdfData_.SetValue(Raytheon.Instruments.NCDF.Names.RADCAL_CHOPPER_STATE, lspsChamber_.GetChopperState().ToString(), Raytheon.Instruments.NCDF.AttrPosition.GLOBAL);

         //-----------------------------Galil------------------------------------

         netCdfData_.SetValue(Raytheon.Instruments.NCDF.Names.TARGET_WHEEL_POSITION, lspsChamber_.GetTargetWheelPosition(), Raytheon.Instruments.NCDF.AttrPosition.GLOBAL);

         netCdfData_.SetValue(Raytheon.Instruments.NCDF.Names.MEASURED_APERTURE_POSITION, lspsChamber_.GetTargetWheelPosition(), Raytheon.Instruments.NCDF.AttrPosition.GLOBAL);

         netCdfData_.SetValue(Raytheon.Instruments.NCDF.Names.MEASURED_AZ_POSITION, lspsChamber_.SteeringMirrorGetBeamAngles().Item1, Raytheon.Instruments.NCDF.AttrPosition.GLOBAL);

         netCdfData_.SetValue(Raytheon.Instruments.NCDF.Names.MEASURED_EL_POSITION, lspsChamber_.SteeringMirrorGetBeamAngles().Item2, Raytheon.Instruments.NCDF.AttrPosition.GLOBAL);

         netCdfData_.SetValue(Raytheon.Instruments.NCDF.Names.MEASURED_FILTER_POSITION, lspsChamber_.GetFilterWheelPosition(), Raytheon.Instruments.NCDF.AttrPosition.GLOBAL);

         netCdfData_.SetValue(Raytheon.Instruments.NCDF.Names.SCAN_PATTERN, "oscillate", Raytheon.Instruments.NCDF.AttrPosition.GLOBAL);

         //-----------------------------NIF------------------------------------

         netCdfData_.SetValue(Raytheon.Instruments.NCDF.Names.RADCAL_NIF_TEMP_TANK_TOP, lspsChamber_.GetTemperature(Raytheon.Instruments.LSPS.TemperatureIndex.TANK_TOP), Raytheon.Instruments.NCDF.AttrPosition.GLOBAL);

         netCdfData_.SetValue(Raytheon.Instruments.NCDF.Names.RADCAL_NIF_TEMP_TANK_BOTTOM, lspsChamber_.GetTemperature(Raytheon.Instruments.LSPS.TemperatureIndex.TANK_BOTTOM), Raytheon.Instruments.NCDF.AttrPosition.GLOBAL);

         netCdfData_.SetValue(Raytheon.Instruments.NCDF.Names.RADCAL_GATE_VALVE, lspsChamber_.GetLspsGateValvePosition().ToString(), Raytheon.Instruments.NCDF.AttrPosition.GLOBAL);

         netCdfData_.SetValue(Raytheon.Instruments.NCDF.Names.L_S_P_S_GATE_VALVE_STATUS, lspsChamber_.GetLspsGateValvePosition().ToString(), Raytheon.Instruments.NCDF.AttrPosition.GLOBAL);

         //-----------------------------RIO------------------------------------

         netCdfData_.SetValue(Raytheon.Instruments.NCDF.Names.VHF_GV_CHAMBER_VAC, lspsChamber_.GetVhfGateValveChamberPressure(), Raytheon.Instruments.NCDF.AttrPosition.GLOBAL);

         netCdfData_.SetValue(Raytheon.Instruments.NCDF.Names.VHF_GV_UUT_VAC, lspsChamber_.GetVhfGateValveUutPressure(), Raytheon.Instruments.NCDF.AttrPosition.GLOBAL);
      }

      /// <summary>
      /// Balance On Pixel Location
      /// </summary>
      /// <param name="pixelX"></param>
      /// <param name="pixelY"></param>
      /// <param name="chopperRate"></param>
      /// <param name="minAmp"></param>
      /// <param name="maxOE"></param>
      public void BalanceOnPixelLocation(int pixelX, int pixelY, double chopperRate, double minAmp, double maxOE)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");
         //_lspsVideo?.BalanceOnPixelLocation(pixelX, pixelY, chopperRate, minAmp, maxOE);
      }

      /// <summary>
      /// Center Target On Pixel
      /// </summary>
      /// <param name="curTargetX"></param>
      /// <param name="curTargetY"></param>
      /// <param name="endPt"></param>
      //public void CenterTargetOnPixel(int curTargetX, int curTargetY, Point endPt)
      //{
      //   logger_?.Trace($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");
      //   //_lspsVideo?.CenterTargetOnPixel(curTargetX, curTargetY, endPt);
      //}

      /// <summary>
      /// Moves to pixel location for the Seeker
      /// </summary>
      /// <param name="pixelX"></param>
      /// <param name="pixelY"></param>
      /// <param name="chopperRate"></param>
      /// <param name="minAmp"></param>
      /// <param name="maxOE"></param>
      /// <exception cref="Exception"></exception>
      public void MoveToPixelLocationSeeker(int pixelX, int pixelY, double chopperRate, double minAmp, double maxOE)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");
         //_lspsVideo?.MoveToPixelLocationSeeker(pixelX, pixelY, chopperRate, minAmp, maxOE);
      }

      /// <summary>
      /// Moves to pixel location for the Sensor
      /// </summary>
      /// <param name="pixelX"></param>
      /// <param name="pixelY"></param>
      /// <param name="chopperRate"></param>
      /// <param name="minAmp"></param>
      /// <param name="maxOE"></param>
      /// <exception cref="Exception"></exception>
      public void MoveToPixelLocationSensor(int pixelX, int pixelY, double chopperRate, double minAmp, double maxOE)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");
         //_lspsVideo?.MoveToPixelLocationSensor(pixelX, pixelY, chopperRate, minAmp, maxOE);
      }

      /// <summary>
      /// Move UUT Rel
      /// </summary>
      /// <param name="az"></param>
      /// <param name="el"></param>
      public void MoveUutRel(double az, double el)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");
         //_lspsChamber?.MoveUutRel(az, el);
      }

      /// <summary>
		/// Seeker Find Target No Move
		/// </summary>
		/// <param name="targetX"></param>
		/// <param name="targetY"></param>
		/// <param name="chopperRate"></param>
		/// <param name="minAmp"></param>
		/// <param name="maxOE"></param>
		public void SeekerFindTargetNoMove(int targetX, int targetY, double chopperRate, double minAmp, double maxOE)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");
         //_lspsVideo?.SeekerFindTargetNoMove(targetX, targetY, chopperRate, minAmp, maxOE);
      }

      /// <summary>
      /// Sensor Find Target No Move
      /// </summary>
      /// <param name="targetX"></param>
      /// <param name="targetY"></param>
      /// <param name="chopperRate"></param>
      /// <param name="minAmp"></param>
      /// <param name="maxOE"></param>
      public void SensorFindTargetNoMove(int targetX, int targetY, double chopperRate, double minAmp, double maxOE)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");
         //_lspsVideo?.SensorFindTargetNoMove(targetX, targetY, chopperRate, minAmp, maxOE);
      }

      /// <summary>
		/// Center Target On Pixel
		/// </summary>
		/// <param name="pixelX"></param>
		/// <param name="pixelY"></param>
		/// <param name="chopperRate"></param>
		/// <param name="minAmp"></param>
		/// <param name="maxOE"></param>
		public void CenterTargetOnPixel(int pixelX, int pixelY, double chopperRate, double minAmp, double maxOE)
      {
         _logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");
         //Point endPt = new Point(pixelX, pixelY);
         // Interface signature is different
         //_lspsVideo?.CenterTargetOnPixel(0, 0, endPt);
      }
      #endregion
   }
}