From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

FetchSpectrum Using Python and RFmx

Solved!
Go to solution

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?

 

0 Kudos
Message 1 of 10
(6,435 Views)

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.

0 Kudos
Message 2 of 10
(6,426 Views)

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'>

 

0 Kudos
Message 3 of 10
(6,416 Views)

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.

0 Kudos
Message 4 of 10
(6,393 Views)

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()

0 Kudos
Message 5 of 10
(6,374 Views)

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']
0 Kudos
Message 6 of 10
(6,360 Views)

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)
Message 7 of 10
(6,354 Views)
Solution
Accepted by topic author jmagers

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:

 

spectrum.png

 

 

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()
0 Kudos
Message 8 of 10
(6,333 Views)

Very nice. Glad to see you got it to work.

0 Kudos
Message 9 of 10
(6,322 Views)

thank you for the help!

 

0 Kudos
Message 10 of 10
(6,319 Views)