08-25-2015 10:58 AM
Hello,
I'm attempting to use RFmx through Python.NET. The code works up until I try to grab the spectrum using FetchSpectrum():
# create variable name before passing it to .NET method spectrum = RFmxSpecAnMXSpectrum # This doesn't work! specAn.Spectrum.Results.FetchSpectrum('', timeout, spectrum)
Here's the full code:
import clr import sys # location of assemblies assy_path = r'C:\Program Files (x86)\National Instruments\MeasurementStudioVS2010\DotNET\Assemblies\Current' sys.path.append(assy_path) clr.AddReference("NationalInstruments.RFmx.SpecAnMX.Fx40") clr.AddReference("NationalInstruments.RFmx.InstrMX.Fx40") from NationalInstruments import * from NationalInstruments.RFmx.InstrMX import * from NationalInstruments.RFmx.SpecAnMX import * # VSA Settings resourceName = '5606_slave' centerFrequency = 10.0e9 # Hz referenceLevel = -10 # dBm externalAttenuation = 0.00 # dB timeout = 10 # seconds span = 1.0e+6 # Hz rbw = 100e3 averagingCount = 10 instrSession = RFmxInstrMX(resourceName, '') # configure VSA rbwAuto = RFmxSpecAnMXSpectrumRbwAutoBandwidth.True rbwFilterType = RFmxSpecAnMXSpectrumRbwFilterType.Gaussian averagingEnabled = RFmxSpecAnMXSpectrumAveragingEnabled.False averagingType = RFmxSpecAnMXSpectrumAveragingType.Rms #specAn = instrSession.GetSpecAnSignalConfiguration(); specAn = RFmxSpecAnMXExtension.GetSpecAnSignalConfiguration(instrSession) specAn.ConfigureRF('',centerFrequency,referenceLevel,externalAttenuation) specAn.Spectrum.Configuration.ConfigureSpan('', span) specAn.Spectrum.Configuration.ConfigureRbwFilter('', rbwAuto,rbw,rbwFilterType) specAn.Spectrum.Configuration.ConfigureAveraging('', averagingEnabled,averagingCount,averagingType) specAn.SelectMeasurements('',RFmxSpecAnMXMeasurementTypes.Spectrum,bool()) specAn.Commit('') # execute acquisition specAn.Initiate('','') # find peak power in the spectrum _,pkAmp,pkFreq,freqRes = specAn.Spectrum.Results.FetchMeasurement('',timeout,float(),float(),float()) print 'Peak Power: {:0.2f} dBm at {:0.6f} GHz'.format(pkAmp,pkFreq*1e-9) """ A .NET method may require the user to pass the variable name it wishes to modify as an argument. Python does not support "pass by reference" but the variable name must exist in python before it can be handed to the .NET method. The .NET method will simply point to the new instance. http://nbviewer.ipython.org/github/jonnojohnson/Agilent/blob/master/Python_Automation/Python_Automation.ipynb """ # create variable name before passing it to .NET method spectrum = RFmxSpecAnMXSpectrum # This doesn't work! specAn.Spectrum.Results.FetchSpectrum('', timeout, spectrum) instrSession.Close()
Here is the error:
Traceback (most recent call last):
File "<ipython-input-172-79fb463146f0>", line 3, in <module>
specAn.Spectrum.Results.FetchSpectrum("", timeout, spectrum)
ArgumentException: Object of type 'System.RuntimeType' cannot be converted to type 'NationalInstruments.Spectrum`1[System.Single]&'.
at System.RuntimeType.TryChangeType(Object value, Binder binder, CultureInfo culture, Boolean needsSpecialCast)
at System.Reflection.MethodBase.CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig)
at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at Python.Runtime.MethodBinder.Invoke(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info, MethodInfo[] methodinfo)
Any ideas?
Solved! Go to Solution.
08-25-2015 11:56 AM
See below for a reponse from a colleague that saw this post and is well-versed in the RFmx .NET API:
"I am not able to reply to it due to network issues. Can you please reply to the query and indicate that the spectrum type he/she is using is wrong.
# create variable name before passing it to .NET method
spectrum = RFmxSpecAnMXSpectrum
Should actually be
# create variable name before passing it to .NET method
spectrum = NationalInstruments.Spectrum<float> #Present in NationalInstruments.Common assembly"
Hope this takes care of the issue.
08-25-2015 12:40 PM
Hi JMota,
Thanks for the reply. I gave that a try, and I received the same error.
# import the "NationalInstruments.Common assembly" import NationalInstruments # create variable name before passing it to .NET method spectrum = NationalInstruments.Spectrum[float]
print spectrum
<class 'NationalInstruments.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]'
For reference, if I eliminate the [float]:
# create variable name before passing it to .NET method spectrum = NationalInstruments.Spectrum print spectrum <class 'NationalInstruments.Spectrum`1'>
08-25-2015 10:34 PM
Got some more info from another colleague. Just passing it along:
"Thats not how you call ref/out parameters from iron python. There are two ways
A. Implicit: you just don't pass ref and out params. And the python will return all ref and out parameters as a tuple.
B. Explicit: use clr.Reference[T] and then pass that."
Hope that sheds some light.
08-26-2015 03:34 AM - edited 08-26-2015 03:41 AM
Here is a minimal example that shows how to call FetchSpectrum:
import clr
import sys
# location of assemblies
assy_path = r'C:\Program Files (x86)\National Instruments\MeasurementStudioVS2010\DotNET\Assemblies\Current'
sys.path.append(assy_path)
clr.AddReference("NationalInstruments.RFmx.SpecAnMX.Fx40")
clr.AddReference("NationalInstruments.RFmx.InstrMX.Fx40")
clr.AddReference("NationalInstruments.Common")
from NationalInstruments import *
from NationalInstruments.RFmx.InstrMX import *
from NationalInstruments.RFmx.SpecAnMX import *
from System import *
# VSA Settings
resourceName = '5606_slave'
instrSession = RFmxInstrMX(resourceName, '')
specAn = RFmxSpecAnMXExtension.GetSpecAnSignalConfiguration(instrSession)
specAn.SelectMeasurements('',RFmxSpecAnMXMeasurementTypes.Spectrum,bool())
specAn.Commit('')
# execute acquisition
specAn.Initiate('','')
# create variable name before passing it to .NET method
spectrumDataRef=clr.Reference[Spectrum[Single]]();
result=specAn.Spectrum.Results.FetchSpectrum('',10.0,spectrumDataRef);
spectrumData=spectrumDataRef.Value;
print 'Spectrum size: {0}'.format(spectrumData.SampleCount)
instrSession.Close()
08-26-2015 10:52 AM
I gave that a try, but the clr module doesn't appear to have a "Reference()" method. Perhaps this is an IronPython implimentation, rather than Python.NET?
In[11]: dir(clr) Out[11]: ['AddReference', 'FindAssembly', 'ListAssemblies', 'NationalInstruments', 'System', '_AtExit', '__class__', '__doc__', '__file__', '__name__', '_extras', 'clrmethod', 'clrproperty', 'getPreload', 'setPreload']
08-26-2015 12:45 PM
Yes this is the IronPython implementation. I wrongly assimed that you were using IronPython.
You implmented this fix.
# import the "NationalInstruments.Common assembly" import NationalInstruments # create variable name before passing it to .NET method spectrum = NationalInstruments.Spectrum[float]
Instead of
spectrum = NationalInstruments.Spectrum[float]
can you please try
spectrum = NationalInstruments.Spectrum[float](0)
08-26-2015 04:11 PM
Ah! That was just about it. Here's what worked:
spectrum = NationalInstruments.Spectrum[System.Single](0) _,spectrum = specAn.Spectrum.Results.FetchSpectrum('',timeout,spectrum)
Here is the result and the final code for future reference:
import clr import sys import os import matplotlib.pyplot as plt import numpy as np # Windows environmental variable for Program Files program_files = os.environ['ProgramFiles(x86)'] assy_path = os.path.join(program_files, 'National Instruments', 'MeasurementStudioVS2010', 'DotNET', 'Assemblies', 'Current') sys.path.append(assy_path) clr.AddReference("NationalInstruments.Common") clr.AddReference("NationalInstruments.RFmx.SpecAnMX.Fx40") clr.AddReference("NationalInstruments.RFmx.InstrMX.Fx40") from NationalInstruments.RFmx.InstrMX import * from NationalInstruments.RFmx.SpecAnMX import * import NationalInstruments import System # VSA Settings resourceName = '5606_slave' centerFrequency = 25.0e9 # Hz referenceLevel = -10 # dBm externalAttenuation = 0.00 # dB timeout = 10 # seconds span = 1.0e+6 # Hz rbw = 100e3 # Hz averagingCount = 10 instrSession = RFmxInstrMX(resourceName, '') # Get model number _,model=instrSession.GetInstrumentModel('',str()) # configure VSA rbwAuto = RFmxSpecAnMXSpectrumRbwAutoBandwidth.True rbwFilterType = RFmxSpecAnMXSpectrumRbwFilterType.Gaussian averagingEnabled = RFmxSpecAnMXSpectrumAveragingEnabled.False averagingType = RFmxSpecAnMXSpectrumAveragingType.Rms specAn = RFmxSpecAnMXExtension.GetSpecAnSignalConfiguration(instrSession) specAn.ConfigureRF('',centerFrequency,referenceLevel,externalAttenuation) specAn.Spectrum.Configuration.ConfigureSpan('', span) specAn.Spectrum.Configuration.ConfigureRbwFilter('', rbwAuto,rbw,rbwFilterType) specAn.Spectrum.Configuration.ConfigureAveraging('', averagingEnabled,averagingCount,averagingType) specAn.SelectMeasurements('',RFmxSpecAnMXMeasurementTypes.Spectrum,bool()) specAn.Commit('') # execute acquisition specAn.Initiate('','') # get x data spectrum = NationalInstruments.Spectrum[System.Single](0) _,spectrum = specAn.Spectrum.Results.FetchSpectrum('',timeout,spectrum) # get y data analogwaveform = NationalInstruments.AnalogWaveform[System.Single](0) _,analogwaveform = specAn.Spectrum.Results.FetchPowerTrace('',timeout,analogwaveform) # close session instrSession.Close() # compute frequency and power startFrequency = spectrum.StartFrequency frequencyIncrement = spectrum.FrequencyIncrement sampleCount = spectrum.SampleCount stopFrequency = startFrequency + frequencyIncrement*(sampleCount+1) freqArray = np.linspace(startFrequency,stopFrequency,sampleCount) power = list(analogwaveform.GetRawData()) # plot results xscale = 1e-3 plt.plot((freqArray-centerFrequency)*xscale,power,linewidth=2.0) #plt.ylim(referenceLevel-100.,referenceLevel) plt.yticks(np.linspace(referenceLevel-100.,referenceLevel,11)) plt.xticks(np.linspace(-span,span,11)/2*xscale) plt.xlim(-span/2*xscale,span/2*xscale) plt.grid(True) plt.xlabel('Relative to Center Frequency (kHz)') plt.ylabel('Power (dBm)') plt.title("{} Spectrum at {:0.6f} GHz".format(model,centerFrequency*1e-9),fontsize='medium') plt.show()
08-26-2015 10:19 PM
Very nice. Glad to see you got it to work.
08-26-2015 10:33 PM
thank you for the help!