microsoft / Qcodes

Modular data acquisition framework
http://microsoft.github.io/Qcodes/
MIT License
323 stars 309 forks source link

checking for number-ness in StandardParameter._sweep_steps #426

Open damazter opened 7 years ago

damazter commented 7 years ago

@giulioungaretti

Steps to reproduce

use a=np.arange(0, 1000, 1) to create an array of sweep values for, say the ivvi.dac1. use ivvi.dac1(a[0]) to change the dac value

Expected behaviour

this should work without warnings

Actual behaviour

a warning is spit out:

WARNING:root:cannot sweep dac1 from 998 to 999 - jumping.

This is because the following code gives an error (copied from StandardParameter):

 def _sweep_steps(self, value):
        oldest_ok_val = datetime.now() - timedelta(seconds=self._max_val_age)
        state = self._latest()
        if state['ts'] is None or state['ts'] < oldest_ok_val:
            start_value = self.get()
        else:
            start_value = state['value']

        self.validate(start_value)

        if not (isinstance(start_value, (int, float)) and
                isinstance(value, (int, float))):
            # something weird... parameter is numeric but one of the ends
            # isn't, even though it's valid.
            # probably a MultiType with a mix of numeric and non-numeric types
            # just set the endpoint and move on
            logging.warning('cannot sweep {} from {} to {} - jumping.'.format(
                self.name, start_value, value))
            return []

        # drop the initial value, we're already there
        return permissive_range(start_value, value, self._step)[1:]

the isinstance is probably not the correct way to check if something is a number, (np.arange yields an array of int32's instead of int64's which is the root cause of the problem)

System

windows 7 (64 bit) master branch 9602616bb924b540d56880b4f3437980271fcd9e

jenshnielsen commented 7 years ago

The simplest solution is probably to check against the numbers abstract base class http://stackoverflow.com/questions/3441358/python-most-pythonic-way-to-check-if-an-object-is-a-number alternatively we can add the relevant numpy types to the tuple (np.int32, np.int64 ...)

I think the return type of np.arange is platform acitecture dependent. At least I see

In [17]: a=np.arange(0, 1000, 1)

In [18]: isinstance(a[0], np.int32)
Out[18]: False

In [19]: isinstance(a[0], np.int64)
Out[19]: True

In [20]: isinstance(a[0], int)
Out[20]: False