1065 lines
31 KiB
C#
1065 lines
31 KiB
C#
// UNCLASSIFIED
|
|
/*-------------------------------------------------------------------------
|
|
RAYTHEON PROPRIETARY: THIS DOCUMENT CONTAINS DATA OR INFORMATION
|
|
PROPRIETARY TO RAYTHEON COMPANY AND IS RESTRICTED TO USE ONLY BY PERSONS
|
|
AUTHORIZED BY RAYTHEON COMPANY IN WRITING TO USE IT. DISCLOSURE TO
|
|
UNAUTHORIZED PERSONS WOULD LIKELY CAUSE SUBSTANTIAL COMPETITIVE HARM TO
|
|
RAYTHEON COMPANY'S BUSINESS POSITION. NEITHER SAID DOCUMENT NOR ITS
|
|
CONTENTS SHALL BE FURNISHED OR DISCLOSED TO OR COPIED OR USED BY PERSONS
|
|
OUTSIDE RAYTHEON COMPANY WITHOUT THE EXPRESS WRITTEN APPROVAL OF RAYTHEON
|
|
COMPANY.
|
|
|
|
THIS PROPRIETARY NOTICE IS NOT APPLICABLE IF DELIVERED TO THE U.S.
|
|
GOVERNMENT.
|
|
|
|
UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
|
-------------------------------------------------------------------------*/
|
|
|
|
using NLog;
|
|
using Raytheon.Common;
|
|
using Raytheon.Instruments;
|
|
using Raytheon.Units;
|
|
using Raytheon.Framework;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
|
|
namespace MeasurementManagerLib
|
|
{
|
|
/// <summary>
|
|
/// This class manages RF instruments and provides an abstraction
|
|
/// </summary>
|
|
public class RfMeasurementManager : IDisposable
|
|
{
|
|
#region PrivateClassMembers
|
|
private struct SpecAnMeasurementFields
|
|
{
|
|
public List<string> _relays;
|
|
public SpecAnAveragingType _avgType;
|
|
public int _numAverages;
|
|
public int _rbw;
|
|
public int _vbw;
|
|
public int _centerFreq;
|
|
public int _span;
|
|
//public int _referanceLevel;
|
|
public int _attenuation;
|
|
public int _delay;
|
|
|
|
public SpecAnMeasurementFields(List<string> relays, SpecAnAveragingType avgType, int numAverages, int rbw, int vbw, int centerFreq, int span, /*int referanceLevel,*/ int attenuation, int delay)
|
|
{
|
|
_relays = relays;
|
|
_avgType = avgType;
|
|
_numAverages = numAverages;
|
|
_rbw = rbw;
|
|
_vbw = vbw;
|
|
_centerFreq = centerFreq;
|
|
_span = span;
|
|
//_referanceLevel = referanceLevel;
|
|
_attenuation = attenuation;
|
|
_delay = delay;
|
|
}
|
|
}
|
|
|
|
private struct PowerMeterPowerMeasurementFields
|
|
{
|
|
public List<string> _relays;
|
|
public readonly int _channel;
|
|
public readonly int _freq;
|
|
public readonly int _delay;
|
|
|
|
public PowerMeterPowerMeasurementFields(List<string> relays, int channel, int frequency, int delay)
|
|
{
|
|
_relays = relays;
|
|
_channel = channel;
|
|
_freq = frequency;
|
|
_delay = delay;
|
|
}
|
|
}
|
|
|
|
private struct SignalGeneratorMeasurementFields
|
|
{
|
|
public List<string> _relays;
|
|
public readonly int _powerLevel;
|
|
public readonly int _freq;
|
|
public readonly int _delay;
|
|
|
|
public SignalGeneratorMeasurementFields(List<string> relays, int powerLevel, int frequency, int delay)
|
|
{
|
|
_relays = relays;
|
|
_powerLevel = powerLevel;
|
|
_freq = frequency;
|
|
_delay = delay;
|
|
}
|
|
}
|
|
|
|
private static object _syncObj = new Object();
|
|
private Dictionary<string, Raytheon.Instruments.ISwitch> _switchCards;
|
|
private IPowerMeter _powerMeter;
|
|
private ISignalGenerator _sigGen;
|
|
private ISpecAnalyzer _specAn;
|
|
private Dictionary<string, PowerMeterPowerMeasurementFields> _powerMeterPowerMeasurements;
|
|
private Dictionary<string, SignalGeneratorMeasurementFields> _signalGeneratorMeasurements;
|
|
private Dictionary<string, SpecAnMeasurementFields> _specAnMeasurements;
|
|
|
|
private static NLog.ILogger _logger;
|
|
#endregion
|
|
|
|
#region PrivateClassFunctions
|
|
|
|
/// <summary>
|
|
/// The Finalizer
|
|
/// </summary>
|
|
~RfMeasurementManager()
|
|
{
|
|
Dispose(false);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Confirm each relay entry in the measurement file refers back to a card in the instrument file
|
|
/// </summary>
|
|
private void CheckForValidRelayFormat()
|
|
{
|
|
foreach (KeyValuePair<string, PowerMeterPowerMeasurementFields> entry in _powerMeterPowerMeasurements)
|
|
{
|
|
List<string> relays = entry.Value._relays;
|
|
|
|
foreach (string relayDef in relays)
|
|
{
|
|
string[] relayInfo = relayDef.Split('-');
|
|
if (relayInfo.Length != 2)
|
|
{
|
|
throw new Exception("Power Meter measurement relay format is not correct: " + relayDef);
|
|
}
|
|
|
|
if (_switchCards.ContainsKey(relayInfo[0].ToUpper()) == false)
|
|
{
|
|
throw new Exception("Power Meter measurement relay card field does not exist: " + relayInfo[0]);
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach (KeyValuePair<string, SignalGeneratorMeasurementFields> entry in _signalGeneratorMeasurements)
|
|
{
|
|
List<string> relays = entry.Value._relays;
|
|
|
|
foreach (string relayDef in relays)
|
|
{
|
|
string[] relayInfo = relayDef.Split('-');
|
|
if (relayInfo.Length != 2)
|
|
{
|
|
throw new Exception("Sig Gen measurement relay format is not correct: " + relayDef);
|
|
}
|
|
|
|
if (_switchCards.ContainsKey(relayInfo[0].ToUpper()) == false)
|
|
{
|
|
throw new Exception("Sig Gen measurement relay card field does not exist: " + relayInfo[0]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="disposing"></param>
|
|
protected virtual void Dispose(bool disposing)
|
|
{
|
|
if (disposing)
|
|
{
|
|
if (_powerMeter != null)
|
|
{
|
|
try
|
|
{
|
|
_powerMeter.Shutdown();
|
|
}
|
|
catch (Exception err)
|
|
{
|
|
_logger?.Error(err.Message + "\r\n" + err.StackTrace);
|
|
}
|
|
}
|
|
|
|
if (_sigGen != null)
|
|
{
|
|
try
|
|
{
|
|
_sigGen.Shutdown();
|
|
}
|
|
catch (Exception err)
|
|
{
|
|
_logger?.Error(err.Message + "\r\n" + err.StackTrace);
|
|
}
|
|
}
|
|
|
|
if (_specAn != null)
|
|
{
|
|
try
|
|
{
|
|
_specAn.Shutdown();
|
|
}
|
|
catch (Exception err)
|
|
{
|
|
_logger?.Error(err.Message + "\r\n" + err.StackTrace);
|
|
}
|
|
}
|
|
|
|
foreach (KeyValuePair<string, ISwitch> switchCard in _switchCards)
|
|
{
|
|
if (_switchCards[switchCard.Key] != null)
|
|
{
|
|
try
|
|
{
|
|
_switchCards[switchCard.Key].Shutdown();
|
|
}
|
|
catch (Exception err)
|
|
{
|
|
_logger?.Error(err.Message + "\r\n" + err.StackTrace);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Parses the ini file for measurement definitions
|
|
/// Populates the Dictionaries with the enum names and ini file data
|
|
/// </summary>
|
|
private void ParseMeasurementDef(ConfigurationFile configurationFile)
|
|
{
|
|
const string POWER_METER_MEASUREMENT = "PowerMeterReadPower";
|
|
const string SIG_GEN_MEASUREMENT = "SignalGeneratorEnable";
|
|
const string SPEC_AN_PEAK_AMP_MEASUREMENT = "SpecAnMeasurePeakAmplitude";
|
|
const string SPEC_AN_PEAK_FREQ_MEASUREMENT = "SpecAnMeasurePeakFrequency";
|
|
|
|
const char COMMA_DELIM = ',';
|
|
|
|
const int INI_POWER_METER_RELAY_INDEX = 0;
|
|
const int INI_POWER_METER_CHANNEL_NUM_INDEX = 1;
|
|
const int INI_POWER_METER_FREQ_INDEX = 2;
|
|
const int INI_POWER_METER_DELAY_INDEX = 3;
|
|
|
|
const int INI_SIG_GEN_RELAY_INDEX = 0;
|
|
const int INI_SIG_GEN_POWER_LEVEL_INDEX = 1;
|
|
const int INI_SIG_GEN_FREQ_INDEX = 2;
|
|
const int INI_SIG_GEN_DELAY_INDEX = 3;
|
|
|
|
const int INI_SPEC_AN_RELAY_INDEX = 0;
|
|
const int INI_SPEC_AN_AVG_TYPE_INDEX = 1;
|
|
const int INI_SPEC_AN_NUM_AVG_TYPE_INDEX = 2;
|
|
const int INI_SPEC_AN_RBW_INDEX = 3;
|
|
const int INI_SPEC_AN_VBW_INDEX = 4;
|
|
const int INI_SPEC_AN_CENTER_FREQ_INDEX = 5;
|
|
const int INI_SPEC_AN_SPAN_INDEX = 6;
|
|
//const int INI_SPEC_AN_REF_POWER_INDEX = 7;
|
|
const int INI_SPEC_AN_ATTENUATION_INDEX = 7;
|
|
const int INI_SPEC_AN_DELAY_INDEX = 8;
|
|
|
|
// read in all of the sections
|
|
List<string> sections = configurationFile.ReadAllSections();
|
|
|
|
foreach (string section in sections)
|
|
{
|
|
if (section.ToUpper().Contains(POWER_METER_MEASUREMENT.ToUpper()))
|
|
{
|
|
List<string> keys = configurationFile.ReadAllKeys(section);
|
|
foreach (string key in keys)
|
|
{
|
|
List<string> valueList = configurationFile.ReadList<string>(section, key);
|
|
|
|
// support for no relays (direct connect to scope)
|
|
List<string> relayList = new List<string>();
|
|
if (valueList[INI_POWER_METER_RELAY_INDEX].Trim() == "")
|
|
{
|
|
// no relays, nothing to do
|
|
}
|
|
else
|
|
{
|
|
relayList = valueList[INI_POWER_METER_RELAY_INDEX].Split(COMMA_DELIM).ToList();
|
|
}
|
|
|
|
for (int i = 0; i < relayList.Count; ++i)
|
|
{
|
|
relayList[i] = relayList[i].Trim();
|
|
}
|
|
int channel = Convert.ToInt32(valueList[INI_POWER_METER_CHANNEL_NUM_INDEX]);
|
|
int freq = Convert.ToInt32(valueList[INI_POWER_METER_FREQ_INDEX]);
|
|
int delay = Convert.ToInt32(valueList[INI_POWER_METER_DELAY_INDEX]);
|
|
_powerMeterPowerMeasurements.Add(key.ToUpper(), new PowerMeterPowerMeasurementFields(relayList, channel, freq, delay));
|
|
}
|
|
}
|
|
else if (section.ToUpper().Contains(SIG_GEN_MEASUREMENT.ToUpper()))
|
|
{
|
|
List<string> keys = configurationFile.ReadAllKeys(section);
|
|
foreach (string key in keys)
|
|
{
|
|
List<string> valueList = configurationFile.ReadList<string>(section, key);
|
|
|
|
// support for no relays (direct connect to scope)
|
|
List<string> relayList = new List<string>();
|
|
if (valueList[INI_SIG_GEN_RELAY_INDEX].Trim() == "")
|
|
{
|
|
// no relays, nothing to do
|
|
}
|
|
else
|
|
{
|
|
relayList = valueList[INI_SIG_GEN_RELAY_INDEX].Split(COMMA_DELIM).ToList();
|
|
}
|
|
|
|
for (int i = 0; i < relayList.Count; ++i)
|
|
{
|
|
relayList[i] = relayList[i].Trim();
|
|
}
|
|
int powLevel = Convert.ToInt32(valueList[INI_SIG_GEN_POWER_LEVEL_INDEX]);
|
|
int freq = Convert.ToInt32(valueList[INI_SIG_GEN_FREQ_INDEX]);
|
|
int delay = Convert.ToInt32(valueList[INI_SIG_GEN_DELAY_INDEX]);
|
|
_signalGeneratorMeasurements.Add(key.ToUpper(), new SignalGeneratorMeasurementFields(relayList, powLevel, freq, delay));
|
|
}
|
|
}
|
|
else if (section.ToUpper().Contains(SPEC_AN_PEAK_AMP_MEASUREMENT.ToUpper()))
|
|
{
|
|
List<string> keys = configurationFile.ReadAllKeys(section);
|
|
foreach (string key in keys)
|
|
{
|
|
List<string> valueList = configurationFile.ReadList<string>(section, key);
|
|
|
|
// support for no relays (direct connect to scope)
|
|
List<string> relayList = new List<string>();
|
|
if (valueList[INI_SPEC_AN_RELAY_INDEX].Trim() == "")
|
|
{
|
|
// no relays, nothing to do
|
|
}
|
|
else
|
|
{
|
|
relayList = valueList[INI_SPEC_AN_RELAY_INDEX].Split(COMMA_DELIM).ToList();
|
|
}
|
|
|
|
for (int i = 0; i < relayList.Count; ++i)
|
|
{
|
|
relayList[i] = relayList[i].Trim();
|
|
}
|
|
|
|
SpecAnAveragingType avgType = (SpecAnAveragingType)Enum.Parse(typeof(SpecAnAveragingType), valueList[INI_SPEC_AN_AVG_TYPE_INDEX], true);
|
|
int numAverages = Convert.ToInt32(valueList[INI_SPEC_AN_NUM_AVG_TYPE_INDEX]);
|
|
int rbw = Convert.ToInt32(valueList[INI_SPEC_AN_RBW_INDEX]);
|
|
int vbw = Convert.ToInt32(valueList[INI_SPEC_AN_VBW_INDEX]);
|
|
int centerFreq = Convert.ToInt32(valueList[INI_SPEC_AN_CENTER_FREQ_INDEX]);
|
|
int span = Convert.ToInt32(valueList[INI_SPEC_AN_SPAN_INDEX]);
|
|
//int refPower = Convert.ToInt32(valueList[INI_SPEC_AN_REF_POWER_INDEX]);
|
|
int attenuation = Convert.ToInt32(valueList[INI_SPEC_AN_ATTENUATION_INDEX]);
|
|
int delay = Convert.ToInt32(valueList[INI_SPEC_AN_DELAY_INDEX]);
|
|
_specAnMeasurements.Add(key.ToUpper(), new SpecAnMeasurementFields(relayList, avgType, numAverages, rbw, vbw, centerFreq, span, /*refPower,*/ attenuation, delay));
|
|
}
|
|
}
|
|
else if (section.ToUpper().Contains(SPEC_AN_PEAK_FREQ_MEASUREMENT.ToUpper()))
|
|
{
|
|
List<string> keys = configurationFile.ReadAllKeys(section);
|
|
foreach (string key in keys)
|
|
{
|
|
List<string> valueList = configurationFile.ReadList<string>(section, key);
|
|
|
|
// support for no relays (direct connect to scope)
|
|
List<string> relayList = new List<string>();
|
|
if (valueList[INI_SPEC_AN_RELAY_INDEX].Trim() == "")
|
|
{
|
|
// no relays, nothing to do
|
|
}
|
|
else
|
|
{
|
|
relayList = valueList[INI_SPEC_AN_RELAY_INDEX].Split(COMMA_DELIM).ToList();
|
|
}
|
|
|
|
for (int i = 0; i < relayList.Count; ++i)
|
|
{
|
|
relayList[i] = relayList[i].Trim();
|
|
}
|
|
|
|
SpecAnAveragingType avgType = (SpecAnAveragingType)Enum.Parse(typeof(SpecAnAveragingType), valueList[INI_SPEC_AN_AVG_TYPE_INDEX], true);
|
|
int numAverages = Convert.ToInt32(valueList[INI_SPEC_AN_NUM_AVG_TYPE_INDEX]);
|
|
int rbw = Convert.ToInt32(valueList[INI_SPEC_AN_RBW_INDEX]);
|
|
int vbw = Convert.ToInt32(valueList[INI_SPEC_AN_VBW_INDEX]);
|
|
int centerFreq = Convert.ToInt32(valueList[INI_SPEC_AN_CENTER_FREQ_INDEX]);
|
|
int span = Convert.ToInt32(valueList[INI_SPEC_AN_SPAN_INDEX]);
|
|
//int refPower = Convert.ToInt32(valueList[INI_SPEC_AN_REF_POWER_INDEX]);
|
|
int attenuation = Convert.ToInt32(valueList[INI_SPEC_AN_ATTENUATION_INDEX]);
|
|
int delay = Convert.ToInt32(valueList[INI_SPEC_AN_DELAY_INDEX]);
|
|
_specAnMeasurements.Add(key.ToUpper(), new SpecAnMeasurementFields(relayList, avgType, numAverages, rbw, vbw, centerFreq, span, /*refPower,*/ attenuation, delay));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Parses the ini file for measurement definitions
|
|
/// Populates the Dictionaries with the enum names and ini file data
|
|
/// </summary>
|
|
private void ParseMeasurementDef(string defFile)
|
|
{
|
|
const string POWER_METER_MEASUREMENT = "PowerMeterReadPower";
|
|
const string SIG_GEN_MEASUREMENT = "SignalGeneratorEnable";
|
|
const string SPEC_AN_PEAK_AMP_MEASUREMENT = "SpecAnMeasurePeakAmplitude";
|
|
const string SPEC_AN_PEAK_FREQ_MEASUREMENT = "SpecAnMeasurePeakFrequency";
|
|
|
|
const char BAR_DELIM = '|';
|
|
const char COMMA_DELIM = ',';
|
|
|
|
const int INI_POWER_METER_RELAY_INDEX = 0;
|
|
const int INI_POWER_METER_CHANNEL_NUM_INDEX = 1;
|
|
const int INI_POWER_METER_FREQ_INDEX = 2;
|
|
const int INI_POWER_METER_DELAY_INDEX = 3;
|
|
|
|
const int INI_SIG_GEN_RELAY_INDEX = 0;
|
|
const int INI_SIG_GEN_POWER_LEVEL_INDEX = 1;
|
|
const int INI_SIG_GEN_FREQ_INDEX = 2;
|
|
const int INI_SIG_GEN_DELAY_INDEX = 3;
|
|
|
|
const int INI_SPEC_AN_RELAY_INDEX = 0;
|
|
const int INI_SPEC_AN_AVG_TYPE_INDEX = 1;
|
|
const int INI_SPEC_AN_NUM_AVG_TYPE_INDEX = 2;
|
|
const int INI_SPEC_AN_RBW_INDEX = 3;
|
|
const int INI_SPEC_AN_VBW_INDEX = 4;
|
|
const int INI_SPEC_AN_CENTER_FREQ_INDEX = 5;
|
|
const int INI_SPEC_AN_SPAN_INDEX = 6;
|
|
//const int INI_SPEC_AN_REF_POWER_INDEX = 7;
|
|
const int INI_SPEC_AN_ATTENUATION_INDEX = 7;
|
|
const int INI_SPEC_AN_DELAY_INDEX = 8;
|
|
|
|
IniFile iniReader = new IniFile(defFile);
|
|
|
|
// read in all of the sections
|
|
List<string> sections = iniReader.ReadAllSections();
|
|
|
|
foreach (string section in sections)
|
|
{
|
|
if (section.ToUpper().Contains(POWER_METER_MEASUREMENT.ToUpper()))
|
|
{
|
|
List<string> keys = iniReader.ReadAllKeys(section);
|
|
foreach (string key in keys)
|
|
{
|
|
string value = iniReader.ReadValue(section, key);
|
|
string[] valueList = value.Split(BAR_DELIM);
|
|
|
|
// support for no relays (direct connect to scope)
|
|
List<string> relayList = new List<string>();
|
|
if (valueList[INI_POWER_METER_RELAY_INDEX].Trim() == "")
|
|
{
|
|
// no relays, nothing to do
|
|
}
|
|
else
|
|
{
|
|
relayList = valueList[INI_POWER_METER_RELAY_INDEX].Split(COMMA_DELIM).ToList();
|
|
}
|
|
|
|
for (int i = 0; i < relayList.Count; ++i)
|
|
{
|
|
relayList[i] = relayList[i].Trim();
|
|
}
|
|
int channel = Convert.ToInt32(valueList[INI_POWER_METER_CHANNEL_NUM_INDEX]);
|
|
int freq = Convert.ToInt32(valueList[INI_POWER_METER_FREQ_INDEX]);
|
|
int delay = Convert.ToInt32(valueList[INI_POWER_METER_DELAY_INDEX]);
|
|
_powerMeterPowerMeasurements.Add(key.ToUpper(), new PowerMeterPowerMeasurementFields(relayList, channel, freq, delay));
|
|
}
|
|
}
|
|
else if (section.ToUpper().Contains(SIG_GEN_MEASUREMENT.ToUpper()))
|
|
{
|
|
List<string> keys = iniReader.ReadAllKeys(section);
|
|
foreach (string key in keys)
|
|
{
|
|
string value = iniReader.ReadValue(section, key);
|
|
string[] valueList = value.Split(BAR_DELIM);
|
|
|
|
// support for no relays (direct connect to scope)
|
|
List<string> relayList = new List<string>();
|
|
if (valueList[INI_SIG_GEN_RELAY_INDEX].Trim() == "")
|
|
{
|
|
// no relays, nothing to do
|
|
}
|
|
else
|
|
{
|
|
relayList = valueList[INI_SIG_GEN_RELAY_INDEX].Split(COMMA_DELIM).ToList();
|
|
}
|
|
|
|
for (int i = 0; i < relayList.Count; ++i)
|
|
{
|
|
relayList[i] = relayList[i].Trim();
|
|
}
|
|
int powLevel = Convert.ToInt32(valueList[INI_SIG_GEN_POWER_LEVEL_INDEX]);
|
|
int freq = Convert.ToInt32(valueList[INI_SIG_GEN_FREQ_INDEX]);
|
|
int delay = Convert.ToInt32(valueList[INI_SIG_GEN_DELAY_INDEX]);
|
|
_signalGeneratorMeasurements.Add(key.ToUpper(), new SignalGeneratorMeasurementFields(relayList, powLevel, freq, delay));
|
|
}
|
|
}
|
|
else if (section.ToUpper().Contains(SPEC_AN_PEAK_AMP_MEASUREMENT.ToUpper()))
|
|
{
|
|
List<string> keys = iniReader.ReadAllKeys(section);
|
|
foreach (string key in keys)
|
|
{
|
|
string value = iniReader.ReadValue(section, key);
|
|
string[] valueList = value.Split(BAR_DELIM);
|
|
|
|
// support for no relays (direct connect to scope)
|
|
List<string> relayList = new List<string>();
|
|
if (valueList[INI_SPEC_AN_RELAY_INDEX].Trim() == "")
|
|
{
|
|
// no relays, nothing to do
|
|
}
|
|
else
|
|
{
|
|
relayList = valueList[INI_SPEC_AN_RELAY_INDEX].Split(COMMA_DELIM).ToList();
|
|
}
|
|
|
|
for (int i = 0; i < relayList.Count; ++i)
|
|
{
|
|
relayList[i] = relayList[i].Trim();
|
|
}
|
|
|
|
SpecAnAveragingType avgType = (SpecAnAveragingType)Enum.Parse(typeof(SpecAnAveragingType), valueList[INI_SPEC_AN_AVG_TYPE_INDEX], true);
|
|
int numAverages = Convert.ToInt32(valueList[INI_SPEC_AN_NUM_AVG_TYPE_INDEX]);
|
|
int rbw = Convert.ToInt32(valueList[INI_SPEC_AN_RBW_INDEX]);
|
|
int vbw = Convert.ToInt32(valueList[INI_SPEC_AN_VBW_INDEX]);
|
|
int centerFreq = Convert.ToInt32(valueList[INI_SPEC_AN_CENTER_FREQ_INDEX]);
|
|
int span = Convert.ToInt32(valueList[INI_SPEC_AN_SPAN_INDEX]);
|
|
//int refPower = Convert.ToInt32(valueList[INI_SPEC_AN_REF_POWER_INDEX]);
|
|
int attenuation = Convert.ToInt32(valueList[INI_SPEC_AN_ATTENUATION_INDEX]);
|
|
int delay = Convert.ToInt32(valueList[INI_SPEC_AN_DELAY_INDEX]);
|
|
_specAnMeasurements.Add(key.ToUpper(), new SpecAnMeasurementFields(relayList, avgType, numAverages, rbw, vbw, centerFreq, span, /*refPower,*/ attenuation, delay));
|
|
}
|
|
}
|
|
else if (section.ToUpper().Contains(SPEC_AN_PEAK_FREQ_MEASUREMENT.ToUpper()))
|
|
{
|
|
List<string> keys = iniReader.ReadAllKeys(section);
|
|
foreach (string key in keys)
|
|
{
|
|
string value = iniReader.ReadValue(section, key);
|
|
string[] valueList = value.Split(BAR_DELIM);
|
|
|
|
// support for no relays (direct connect to scope)
|
|
List<string> relayList = new List<string>();
|
|
if (valueList[INI_SPEC_AN_RELAY_INDEX].Trim() == "")
|
|
{
|
|
// no relays, nothing to do
|
|
}
|
|
else
|
|
{
|
|
relayList = valueList[INI_SPEC_AN_RELAY_INDEX].Split(COMMA_DELIM).ToList();
|
|
}
|
|
|
|
for (int i = 0; i < relayList.Count; ++i)
|
|
{
|
|
relayList[i] = relayList[i].Trim();
|
|
}
|
|
|
|
SpecAnAveragingType avgType = (SpecAnAveragingType)Enum.Parse(typeof(SpecAnAveragingType), valueList[INI_SPEC_AN_AVG_TYPE_INDEX], true);
|
|
int numAverages = Convert.ToInt32(valueList[INI_SPEC_AN_NUM_AVG_TYPE_INDEX]);
|
|
int rbw = Convert.ToInt32(valueList[INI_SPEC_AN_RBW_INDEX]);
|
|
int vbw = Convert.ToInt32(valueList[INI_SPEC_AN_VBW_INDEX]);
|
|
int centerFreq = Convert.ToInt32(valueList[INI_SPEC_AN_CENTER_FREQ_INDEX]);
|
|
int span = Convert.ToInt32(valueList[INI_SPEC_AN_SPAN_INDEX]);
|
|
//int refPower = Convert.ToInt32(valueList[INI_SPEC_AN_REF_POWER_INDEX]);
|
|
int attenuation = Convert.ToInt32(valueList[INI_SPEC_AN_ATTENUATION_INDEX]);
|
|
int delay = Convert.ToInt32(valueList[INI_SPEC_AN_DELAY_INDEX]);
|
|
_specAnMeasurements.Add(key.ToUpper(), new SpecAnMeasurementFields(relayList, avgType, numAverages, rbw, vbw, centerFreq, span, /*refPower,*/ attenuation, delay));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Will command the switch cards close a specified list of relays
|
|
/// </summary>
|
|
/// <param name="relayList"></param>
|
|
private void SwitchRelayClose(List<string> relayList)
|
|
{
|
|
foreach (string combo in relayList)
|
|
{
|
|
//break out the card and relay
|
|
string[] cardRelay = combo.Split('-');
|
|
string cardObject = cardRelay[0].Trim();
|
|
string relay = cardRelay[1].Trim();
|
|
|
|
//open the relays
|
|
_switchCards[cardObject.ToUpper()].Connect(relay);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Will command the switch card open all relays or the specified list of relays
|
|
/// </summary>
|
|
/// <param name="relayList">Optional list of relays to open</param>
|
|
private void SwitchRelayOpen(List<string> relayList)
|
|
{
|
|
foreach (string combo in relayList)
|
|
{
|
|
//break out the card and relay
|
|
string[] cardRelay = combo.Split('-');
|
|
string cardObject = cardRelay[0].Trim();
|
|
string relay = cardRelay[1].Trim();
|
|
|
|
//open the relays
|
|
_switchCards[cardObject.ToUpper()].Disconnect(relay);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region PublicClassFunctions
|
|
|
|
public RfMeasurementManager(IInstrumentManager instrumentManager,
|
|
List<string> switchInstrumentNames,
|
|
string powerMeeterName,
|
|
string signalGeneratorName,
|
|
string specAnalyzerName,
|
|
string configFileName = "")
|
|
{
|
|
|
|
_logger = LogManager.GetCurrentClassLogger();
|
|
|
|
// initialize class members
|
|
_powerMeterPowerMeasurements = new Dictionary<string, PowerMeterPowerMeasurementFields>(StringComparer.InvariantCultureIgnoreCase);
|
|
_signalGeneratorMeasurements = new Dictionary<string, SignalGeneratorMeasurementFields>(StringComparer.InvariantCultureIgnoreCase);
|
|
_specAnMeasurements = new Dictionary<string, SpecAnMeasurementFields>(StringComparer.InvariantCultureIgnoreCase);
|
|
_switchCards = new Dictionary<string, ISwitch>();
|
|
|
|
if(string.IsNullOrEmpty(configFileName))
|
|
{
|
|
configFileName = "RfMeasurementManager.xml";
|
|
}
|
|
|
|
ParseMeasurementDef(new ConfigurationFile(configFileName));
|
|
|
|
foreach (string name in switchInstrumentNames)
|
|
{
|
|
_switchCards[name] = instrumentManager.GetInstrument<ISwitch>(name);
|
|
_switchCards[name]?.Initialize();
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(powerMeeterName))
|
|
{
|
|
_powerMeter = instrumentManager.GetInstrument<IPowerMeter>(powerMeeterName);
|
|
_powerMeter?.Initialize();
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(signalGeneratorName))
|
|
{
|
|
_sigGen = instrumentManager.GetInstrument<ISignalGenerator>(signalGeneratorName);
|
|
_sigGen?.Initialize();
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(specAnalyzerName))
|
|
{
|
|
_specAn = instrumentManager.GetInstrument<ISpecAnalyzer>(specAnalyzerName);
|
|
_specAn?.Initialize();
|
|
}
|
|
|
|
CheckForValidRelayFormat();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Dispose of this objects resources
|
|
/// </summary>
|
|
public void Dispose()
|
|
{
|
|
try
|
|
{
|
|
Dispose(true);
|
|
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
catch (Exception err)
|
|
{
|
|
try
|
|
{
|
|
_logger?.Error(err.Message + "\r\n" + err.StackTrace);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
//Do not rethrow. Exception from error logger that has already been garbage collected
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// A getter for the list of power measurements (as defined in the input def file)
|
|
/// </summary>
|
|
/// <returns>A list of power measurements</returns>
|
|
public List<string> PowerMeterGetPowerMeasurementList()
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
List<string> measurements = new List<string>();
|
|
|
|
foreach (KeyValuePair<string, PowerMeterPowerMeasurementFields> entry in _powerMeterPowerMeasurements)
|
|
{
|
|
measurements.Add(entry.Key);
|
|
}
|
|
|
|
return measurements;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="measurementName"></param>
|
|
/// <returns></returns>
|
|
public double PowerMeterReadPower(string measurementName)
|
|
{
|
|
// hold onto the relays for the catch
|
|
List<string> measurementRelays = null;
|
|
|
|
try
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
if (_powerMeterPowerMeasurements.ContainsKey(measurementName.ToUpper()) == false)
|
|
{
|
|
throw new Exception("could not find measurement: " + measurementName);
|
|
}
|
|
|
|
// grab the measurement params
|
|
PowerMeterPowerMeasurementFields measurement = _powerMeterPowerMeasurements[measurementName.ToUpper()];
|
|
|
|
measurementRelays = measurement._relays;
|
|
|
|
// close the relays
|
|
SwitchRelayClose(measurementRelays);
|
|
|
|
bool ret = _powerMeter.SetFrequency(measurement._channel, Frequency.FromHertz(measurement._freq));
|
|
|
|
if (ret == false)
|
|
{
|
|
throw new Exception("set frequency failed for measurement: " + measurementName);
|
|
}
|
|
|
|
// wait a bit
|
|
Thread.Sleep(measurement._delay);
|
|
|
|
// make the measurement
|
|
double returnValue = _powerMeter.GetMeasurement(measurement._channel).Watts;
|
|
|
|
return returnValue;
|
|
}
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw;
|
|
}
|
|
finally
|
|
{
|
|
// open the relays
|
|
if (measurementRelays != null)
|
|
{
|
|
SwitchRelayOpen(measurementRelays);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public void PowerMeterSelfTest()
|
|
{
|
|
|
|
lock (_syncObj)
|
|
{
|
|
SelfTestResult res = _powerMeter.PerformSelfTest();
|
|
|
|
if (res != SelfTestResult.Pass)
|
|
{
|
|
throw new Exception("did not pass, the result was: " + res.ToString());
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="measurementName"></param>
|
|
/// <returns></returns>
|
|
public void SignalGeneratorDisable(string measurementName)
|
|
{
|
|
try
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
if (_signalGeneratorMeasurements.ContainsKey(measurementName.ToUpper()) == false)
|
|
{
|
|
throw new Exception("could not find measurement: " + measurementName);
|
|
}
|
|
|
|
// grab the measurement params
|
|
SignalGeneratorMeasurementFields measurement = _signalGeneratorMeasurements[measurementName.ToUpper()];
|
|
|
|
List<string> measurementRelays = measurement._relays;
|
|
|
|
_sigGen.Enable(false);
|
|
|
|
// wait a bit
|
|
Thread.Sleep(measurement._delay);
|
|
|
|
// close the relays
|
|
SwitchRelayOpen(measurementRelays);
|
|
}
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="measurementName"></param>
|
|
/// <returns></returns>
|
|
public void SignalGeneratorEnable(string measurementName)
|
|
{
|
|
try
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
if (_signalGeneratorMeasurements.ContainsKey(measurementName.ToUpper()) == false)
|
|
{
|
|
throw new Exception("could not find measurement: " + measurementName);
|
|
}
|
|
|
|
// grab the measurement params
|
|
SignalGeneratorMeasurementFields measurement = _signalGeneratorMeasurements[measurementName.ToUpper()];
|
|
|
|
List<string> measurementRelays = measurement._relays;
|
|
|
|
// close the relays
|
|
SwitchRelayClose(measurementRelays);
|
|
|
|
_sigGen.SetFrequency(new UnitizedValue(measurement._freq));
|
|
|
|
_sigGen.SetPowerLevel(new UnitizedValue(measurement._powerLevel));
|
|
|
|
// wait a bit
|
|
Thread.Sleep(measurement._delay);
|
|
|
|
_sigGen.Enable(true);
|
|
}
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw;
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Sends a SCPI command to the Sig Gen and reads the response
|
|
/// </summary>
|
|
/// <param name="command">The SCPI command to send</param>
|
|
/// <returns></returns>
|
|
public string SignalGeneratorIOQuery(string command)
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
return _sigGen.IOQuery(command);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sends a SCPI command to the Sig Gen
|
|
/// </summary>
|
|
/// <param name="command">The SCPI command to send</param>
|
|
public void SignalGeneratorIOWrite(string command)
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
_sigGen.IOWrite(command);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public void SignalGeneratorSelfTest()
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
SelfTestResult res = _sigGen.PerformSelfTest();
|
|
|
|
if (res != SelfTestResult.Pass)
|
|
{
|
|
throw new Exception("did not pass, the result was: " + res.ToString());
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sends a SCPI command to the Spec An and reads the response
|
|
/// </summary>
|
|
/// <param name="command">The SCPI command to send</param>
|
|
/// <returns></returns>
|
|
public string SpecAnIOQuery(string command, int timeout = 10000)
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
return _specAn.IOQuery(command, timeout);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sends a SCPI command to the Spec An
|
|
/// </summary>
|
|
/// <param name="command">The SCPI command to send</param>
|
|
public void SpecAnIOWrite(string command)
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
_specAn.IOWrite(command);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="measurementName"></param>
|
|
/// <returns></returns>
|
|
public double SpecAnMeasurePeakAmplitude(string measurementName)
|
|
{
|
|
// hold onto the relays for the catch
|
|
List<string> measurementRelays = null;
|
|
|
|
try
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
if (_specAnMeasurements.ContainsKey(measurementName.ToUpper()) == false)
|
|
{
|
|
throw new Exception("could not find measurement: " + measurementName);
|
|
}
|
|
|
|
// grab the measurement params
|
|
SpecAnMeasurementFields measurement = _specAnMeasurements[measurementName.ToUpper()];
|
|
|
|
measurementRelays = measurement._relays;
|
|
|
|
// close the relays
|
|
SwitchRelayClose(measurementRelays);
|
|
|
|
_specAn.ConfigureAveraging(measurement._avgType, measurement._numAverages);
|
|
|
|
_specAn.ConfigureBandwidth(measurement._rbw, measurement._vbw);
|
|
|
|
_specAn.ConfigureFrequency(measurement._centerFreq, measurement._span);
|
|
|
|
_specAn.ConfigurePowerLevel(/*measurement._referanceLevel,*/ measurement._attenuation);
|
|
|
|
// wait a bit
|
|
Thread.Sleep(measurement._delay);
|
|
|
|
double amp = _specAn.MeasurePeakAmplitude();
|
|
|
|
return amp;
|
|
}
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw;
|
|
}
|
|
finally
|
|
{
|
|
// open the relays
|
|
if (measurementRelays != null)
|
|
{
|
|
SwitchRelayOpen(measurementRelays);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="measurementName"></param>
|
|
/// <returns></returns>
|
|
public double SpecAnMeasurePeakFrequency(string measurementName)
|
|
{
|
|
// hold onto the relays for the catch
|
|
List<string> measurementRelays = null;
|
|
|
|
try
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
if (_specAnMeasurements.ContainsKey(measurementName.ToUpper()) == false)
|
|
{
|
|
throw new Exception("could not find measurement: " + measurementName);
|
|
}
|
|
|
|
// grab the measurement params
|
|
SpecAnMeasurementFields measurement = _specAnMeasurements[measurementName.ToUpper()];
|
|
|
|
measurementRelays = measurement._relays;
|
|
|
|
// close the relays
|
|
SwitchRelayClose(measurementRelays);
|
|
|
|
_specAn.ConfigureAveraging(measurement._avgType, measurement._numAverages);
|
|
|
|
_specAn.ConfigureBandwidth(measurement._rbw, measurement._vbw);
|
|
|
|
_specAn.ConfigureFrequency(measurement._centerFreq, measurement._span);
|
|
|
|
_specAn.ConfigurePowerLevel(/*measurement._referanceLevel,*/ measurement._attenuation);
|
|
|
|
// wait a bit
|
|
Thread.Sleep(measurement._delay);
|
|
|
|
double freq = _specAn.MeasurePeakFrequency();
|
|
|
|
return freq;
|
|
}
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw;
|
|
}
|
|
finally
|
|
{
|
|
// open the relays
|
|
if (measurementRelays != null)
|
|
{
|
|
SwitchRelayOpen(measurementRelays);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public void SpecAnSelfTest()
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
SelfTestResult res = _specAn.PerformSelfTest();
|
|
|
|
if (res != SelfTestResult.Pass)
|
|
{
|
|
throw new Exception("did not pass, the result was: " + res.ToString());
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|