public override void ArmAndWait()
 {
     lock (this)
     {
         if (!Environs.Debug)
         {
             inputTask.Start();
             latestData = reader.ReadSingleSample();
             inputTask.Stop();
             //check that photodiode is not saturating
             if (latestData[lockCavityChannel] > 4.7)
             {
                 hardwareControl.diodeSaturationError();
             }
             else
             {
                 hardwareControl.diodeSaturation();
             }
             // send the new lock cavity data to the hardware controller
             normalized_Data = latestData[lockCavityChannel] / latestData[refCavityChannel];
             hardwareControl.UpdateLockCavityData(normalized_Data);
         }
         else
         {
             // do nothing
         }
     }
 }
        /// <summary>
        /// Locks the laser to a reference cavity. This method runs continuously until the laser is unlocked.
        /// When this method is called, the reference cavity is read in order to establish the lock point.
        /// The reference cavity is then read continuously and adjustments fed-back to the laser.
        /// </summary>
        public void Lock()
        {
            double   singleValue;
            double   singlerefValue;
            double   averageValue   = 0;
            int      reads          = 0;
            bool     firstTime      = true;
            DateTime oldCavityStamp = new DateTime();
            DateTime newCavityStamp = new DateTime();

            newCavityStamp = DateTime.Now;

            status = ControllerState.busy;
            ui.ControlVoltageEditorEnabledState(false);
            hardwareControl.LaserLocked = true;
            hardwareControl.SetAnalogOutputBlockedStatus("laser", true);

            while (status == ControllerState.busy)
            {
                if (!Environs.Debug)
                {
                    oldCavityStamp = newCavityStamp;
                    // read the cavity
                    if (hardwareControl.AnalogInputsAvailable)//scanmaster not running
                    {
                        singleValue = 0;
                        inputTask.Start();
                        latestData = cavityReader.ReadMultiSample(SAMPLES_PER_READ);
                        inputTask.Stop();

                        singlerefValue = 0;
                        inputrefTask.Start();
                        latestrefData = cavityrefReader.ReadMultiSample(SAMPLES_PER_READ);
                        inputrefTask.Stop();

                        foreach (double d in latestData)
                        {
                            singleValue += d;
                        }
                        foreach (double e in latestrefData)
                        {
                            singlerefValue += e;
                        }
                        singleValue    = singleValue / SAMPLES_PER_READ;
                        singlerefValue = singlerefValue / SAMPLES_PER_READ;
                        if (singleValue > 4.7)
                        {
                            hardwareControl.diodeSaturationError();
                        }
                        else
                        {
                            hardwareControl.diodeSaturation();
                        }
                        singleValue    = singleValue / singlerefValue;
                        newCavityStamp = DateTime.Now;
                        hardwareControl.UpdateLockCavityData(singleValue);
                        //hardwareControl.UpdateLockCavityData(singleValue / singlerefValue);
                    }
                    else
                    {
                        singleValue    = hardwareControl.LastCavityData;
                        newCavityStamp = hardwareControl.LastCavityTimeStamp;
                    }

                    // provided the last cavity read is recent, do something with it
                    if (hardwareControl.TimeSinceLastCavityRead < LATENCY && newCavityStamp.CompareTo(oldCavityStamp) != 0)
                    {
                        // if this is the first read since throwing the lock, the result defines the set-point
                        if (firstTime)
                        {
                            integratedDeviation = 0;
                            // make sure we don't have a value that's out of range
                            if (singleValue > UPPER_SETPOINT_LIMIT)
                            {
                                singleValue = UPPER_SETPOINT_LIMIT;
                            }
                            if (singleValue < LOWER_SETPOINT_LIMIT)
                            {
                                singleValue = LOWER_SETPOINT_LIMIT;
                            }
                            setPoint = singleValue;
                            ui.SetSetPointNumericEditorValue(setPoint);
                            firstTime = false;
                        }
                        // otherwise, use the last read to update the running average
                        else
                        {
                            averageValue += singleValue;
                            reads++;
                            deviation           = averageValue / reads - setPoint;
                            integratedDeviation = integratedDeviation + deviation * hardwareControl.TimeSinceLastCavityRead;
                        }
                        // is it time to feed-back to the laser
                        if (reads != 0 && (reads >= READS_PER_FEEDBACK || ui.SpeedSwitchState))
                        {
                            averageValue = averageValue / reads;
                            deviation    = averageValue - setPoint;
                            LaserVoltage = LaserVoltage + SignOfFeedback * proportionalGain * deviation +
                                           integralGain * integratedDeviation; //other terms to go here
                            // update the deviation plot
                            ui.DeviationPlotXYAppend(deviation);
                            // reset the variables
                            averageValue = 0;
                            reads        = 0;
                        }
                    }
                }
                else
                {
                    // Debug mode
                    ui.DeviationPlotXYAppend(hardwareControl.LaserFrequencyControlVoltage - setPoint);
                }
                Thread.Sleep(SLEEPING_TIME);
            }
            // we're out of the while loop - revert to the unlocked state
            status = ControllerState.free;
            hardwareControl.LaserLocked = false;
            ui.ControlVoltageEditorEnabledState(true);
            hardwareControl.SetAnalogOutputBlockedStatus("laser", false);
        }