ni / nimi-python

Python bindings for NI Modular Instrument drivers.
Other
110 stars 85 forks source link

Delete arbitrary waveform from memory raises AttributeError: '_SessionBase' object has no attribute '_clear_arb_waveform' #960

Open ihouses opened 5 years ago

ihouses commented 5 years ago

When deleting a arbitrary waveform the driver crashes with the error: AttributeError: '_SessionBase' object has no attribute '_clear_arb_waveform'

My code is:

options = {'simulate': False, 'driver_setup': {'Model': '5433 (2CH)', 'BoardType': 'PXIe', }, } self.session = nifgen.Session(resource_name=name, options=options)

def start_generation(self, delete_waveform=True):

    self.session._initiate_generation()

    if delete_waveform is True:
        self.session.channels[self.channel].delete_waveform(self.waveform_handle)

self.waveform_handle = 0

If I dont't delete the waveform I get an error:

nifgen.errors.DriverError: -1074118634: You must specify which waveform to generate.

But since : self.session._initiate_generation() doesn't have arguments to select the waveform that I want to initiate... I don't know how to do it.

I load my waveform with:

self.session.channels[channel].arb_sample_rate = self.sample_rate self.session.channels[channel].output_mode = nifgen.OutputMode.ARB self.session.channels[channel].trigger_mode = enums.TriggerMode.SINGLE self.waveform_handle = self.session.create_waveform(waveform_data_array=waveform)

    self.session.streaming_waveform_handle = self.waveform_handle
    self.session.channels[channel].configure_arb_waveform(waveform_handle=self.waveform_handle, gain=1, offset=0)

I don't know how to overwrite and previous handler.

marcoskirsch commented 5 years ago
    self.session._initiate_generation()

You shouldn't use anything that starts with an underscore. Those methods are considered "private" and may change. Only use the methods and properties publicly documented. See this example.

If I dont't delete the waveform I get an error:

nifgen.errors.DriverError: -1074118634: You must specify which waveform to generate.

But since : self.session._initiate_generation() doesn't have arguments to select the waveform that I want to initiate... I don't know how to do it.

Set property arb_waveform_handle

This should be enough to get you unstuck. Regardless, this is a legitimate bug and we will fix it. Thanks for reporting!

ihouses commented 5 years ago

set arb_waveform_handle prevents to get the error. Now I need to be able to delete waveforms from memory, I guess this is the fix that you are talking about.

marcoskirsch commented 4 years ago

nifgen.Session.delete_waveform() is a hand-coded method that calls either of the codegenerated methods _delete_named_waveform or _clear_arb_waveform. They eventually call the NI-FGEN functions on the DLL:

ViStatus _VI_FUNC  niFgen_ClearArbWaveform (
   ViSession vi,
   ViInt32 wfmHandle);

or

ViStatus _VI_FUNC niFgen_DeleteNamedWaveform(
   ViSession vi,
   ViConstString channelName,
   ViConstString wfmName);

Notice that niFgen_ClearArbWaveform doesn't take in a channel. So this cannot be made to work without adding new functionality to the driver runtime.

All this said, the error you get AttributeError: '_SessionBase' object has no attribute '_clear_arb_waveform' is terrible.

If instead of

        self.session.channels[self.channel].delete_waveform(self.waveform_handle)

you called the method directly on the session:

        self.session.delete_waveform(self.waveform_handle)

then it would work.

marcoskirsch commented 4 years ago

1288 is related but broader in scope. Note that if that issue is fixed, then this issue doesn't necessarilly go away, as the error could reference private method

Note that if we fix this, then #960 is a bit improved but still the error would possibly reference a private method _clear_arb_waveform which is not ideal.