def generate_code(self, hdf5_file):
        IntermediateDevice.generate_code(self, hdf5_file)
        group = self.init_device_group(hdf5_file)

        clockline = self.parent_device
        pseudoclock = clockline.parent_device
        times = pseudoclock.times[clockline]

        # out_table = np.empty((len(times),len(self.child_devices)), dtype=np.float32)
        # determine dtypes
        dtypes = []
        for device in self.child_devices:
            if isinstance(device, DigitalOut):
                device_dtype = np.int8
            elif isinstance(device, AnalogOut):
                device_dtype = np.float64
            dtypes.append((device.name, device_dtype))

        # create dataset
        out_table = np.zeros(len(times), dtype=dtypes)
        for device in self.child_devices:
            out_table[device.name][:] = device.raw_output

        group.create_dataset('OUTPUTS',
                             compression=config.compression,
                             data=out_table)
示例#2
0
 def generate_code(self, hdf5_file):
     IntermediateDevice.generate_code(self, hdf5_file)
     analogs = {}
     digitals = {}
     inputs = {}
     for device in self.child_devices:
         if isinstance(device,AnalogOut):
             analogs[device.connection] = device
         elif isinstance(device,DigitalOut):
             digitals[device.connection] = device
         elif isinstance(device,AnalogIn):
             inputs[device.connection] = device
         else:
             raise Exception('Got unexpected device.')
     analog_out_table = np.empty((len(self.parent_device.times[self.clock_type]),len(analogs)), dtype=np.float32)
     analog_connections = analogs.keys()
     analog_connections.sort()
     analog_out_attrs = []
     for i, connection in enumerate(analog_connections):
         output = analogs[connection]
         if any(output.raw_output > 10 )  or any(output.raw_output < -10 ):
             # Bounds checking:
             raise LabscriptError('%s %s '%(output.description, output.name) +
                               'can only have values between -10 and 10 Volts, ' + 
                               'the limit imposed by %s.'%self.name)
         analog_out_table[:,i] = output.raw_output
         analog_out_attrs.append(self.MAX_name +'/'+connection)
     input_connections = inputs.keys()
     input_connections.sort()
     input_attrs = []
     acquisitions = []
     for connection in input_connections:
         input_attrs.append(self.MAX_name+'/'+connection)
         for acq in inputs[connection].acquisitions:
             acquisitions.append((connection,acq['label'],acq['start_time'],acq['end_time'],acq['wait_label'],acq['scale_factor'],acq['units']))
     # The 'a256' dtype below limits the string fields to 256
     # characters. Can't imagine this would be an issue, but to not
     # specify the string length (using dtype=str) causes the strings
     # to all come out empty.
     acquisitions_table_dtypes = [('connection','a256'), ('label','a256'), ('start',float),
                                  ('stop',float), ('wait label','a256'),('scale factor',float), ('units','a256')]
     acquisition_table= np.empty(len(acquisitions), dtype=acquisitions_table_dtypes)
     for i, acq in enumerate(acquisitions):
         acquisition_table[i] = acq
     digital_out_table = []
     if digitals:
         digital_out_table = self.convert_bools_to_bytes(digitals.values())
     grp = hdf5_file.create_group('/devices/'+self.name)
     if all(analog_out_table.shape): # Both dimensions must be nonzero
         analog_dataset = grp.create_dataset('ANALOG_OUTS',compression=config.compression,data=analog_out_table)
         grp.attrs['analog_out_channels'] = ', '.join(analog_out_attrs)
     if len(digital_out_table): # Table must be non empty
         digital_dataset = grp.create_dataset('DIGITAL_OUTS',compression=config.compression,data=digital_out_table)
         grp.attrs['digital_lines'] = '/'.join((self.MAX_name,'port0','line0:%d'%(self.n_digitals-1)))
     if len(acquisition_table): # Table must be non empty
         input_dataset = grp.create_dataset('ACQUISITIONS',compression=config.compression,data=acquisition_table)
         grp.attrs['analog_in_channels'] = ', '.join(input_attrs)
         grp.attrs['acquisition_rate'] = self.acquisition_rate
     grp.attrs['clock_terminal'] = self.clock_terminal
示例#3
0
    def generate_code(self, hdf5_file):
        """Generates the hardware code from the script and saves it to the
        shot h5 file.

        This is called automatically when a shot is compiled.

        Args:
            hdf5_file (str): Path to shot's hdf5 file to save the instructions to.
        """
        IntermediateDevice.generate_code(self, hdf5_file)
        analogs = {}
        digitals = {}
        inputs = {}
        for device in self.child_devices:
            if isinstance(device, (AnalogOut, StaticAnalogOut)):
                analogs[device.connection] = device
            elif isinstance(device, (DigitalOut, StaticDigitalOut)):
                digitals[device.connection] = device
            elif isinstance(device, AnalogIn):
                inputs[device.connection] = device
            else:
                raise TypeError(device)

        clockline = self.parent_device
        if clockline is None:
            # No pseudoclock to call expand_timeseries() on our children.
            # Call it ourselves:
            for device in self.child_devices:
                if isinstance(device, (StaticDigitalOut, StaticAnalogOut)):
                    device.expand_timeseries()
            times = None
        else:
            times = clockline.parent_device.times[clockline]

        self._check_even_children(analogs, digitals)
        self._check_bounds(analogs)

        AO_table = self._make_analog_out_table(analogs, times)
        DO_table = self._make_digital_out_table(digitals, times)
        AI_table = self._make_analog_input_table(inputs)

        self._check_AI_not_too_fast(AI_table)
        self._check_wait_monitor_timeout_device_config()

        grp = self.init_device_group(hdf5_file)
        if AO_table is not None:
            grp.create_dataset('AO',
                               data=AO_table,
                               compression=config.compression)
        if DO_table is not None:
            grp.create_dataset('DO',
                               data=DO_table,
                               compression=config.compression)
        if AI_table is not None:
            grp.create_dataset('AI',
                               data=AI_table,
                               compression=config.compression)
示例#4
0
 def generate_code(self, hdf5_file):
     IntermediateDevice.generate_code(self, hdf5_file)
     stages = {stage.connection: stage for stage in self.child_devices}
     connections = sorted(stages, key=get_device_number)
     dtypes = [(connection, int) for connection in connections]
     static_value_table = np.empty(1, dtype=dtypes)
     for connection, stage in stages.items():
         static_value_table[connection][0] = stage.static_value
     grp = self.init_device_group(hdf5_file)
     grp.create_dataset('static_values', data=static_value_table)
    def generate_code(self, hdf5_file):

        IntermediateDevice.generate_code(self, hdf5_file)

        if len(self.child_devices) != 3:
            raise LabscriptError(
                "Wrong number of child_devices. This device expects exactly 3 children"
            )

        grp = hdf5_file.create_group('/devices/' + self.name)

        profile_dtypes = [
            ('freq', np.float),
            ('phase', np.float),
            ('amp', np.float),
            ('ext_in', bool),  #EE
            ('freq_dev', np.float)
        ]  #EE

        profile_table = np.zeros(1, dtype=profile_dtypes)

        profile_table['freq'] = self.RFSettings['freq']
        profile_table['amp'] = self.RFSettings['amp']
        profile_table['phase'] = self.RFSettings['phase']
        profile_table['ext_in'] = 0  ##EE
        profile_table['freq_dev'] = 0  #EE

        ## Emily edit
        if self.ext_in:
            profile_table['ext_in'] = 1
            profile_table['freq_dev'] = self.RFSettings['freq_dev']

        grp.create_dataset('RF_DATA',
                           compression=config.compression,
                           data=profile_table)

        if self.sweep:
            sweep_dtypes = [('sweep_low', np.float), ('sweep_high', np.float),
                            ('sweep_duration', np.float),
                            ('sweep_samplerate', np.float)]

            sweep_table = np.empty(1, dtype=sweep_dtypes)

            #            sweep_table['sweep_type'] = sweep_types[output.sweep_params['type']]
            sweep_table['sweep_low'] = self.sweep_params['low']
            sweep_table['sweep_high'] = self.sweep_params['high']
            sweep_table['sweep_duration'] = self.sweep_params['duration']
            #            sweep_table['sweep_falltime'] = output.sweep_params['falltime']
            sweep_table['sweep_samplerate'] = self.sweep_params['sample_rate']

            grp.create_dataset('SWEEP_DATA',
                               compression=config.compression,
                               data=sweep_table)
示例#6
0
    def generate_code(self, hdf5_file):
        IntermediateDevice.generate_code(self, hdf5_file)
        analogs = {}
        digitals = {}
        inputs = {}
        for device in self.child_devices:
            if isinstance(device, (AnalogOut, StaticAnalogOut)):
                analogs[device.connection] = device
            elif isinstance(device, (DigitalOut, StaticDigitalOut)):
                digitals[device.connection] = device
            elif isinstance(device, AnalogIn):
                inputs[device.connection] = device
            else:
                raise TypeError(device)

        clockline = self.parent_device
        if clockline is None:
            # No pseudoclock to call expand_timeseries() on our children.
            # Call it ourselves:
            for device in self.child_devices:
                if isinstance(device, (StaticDigitalOut, StaticAnalogOut)):
                    device.expand_timeseries()
            times = None
        else:
            times = clockline.parent_device.times[clockline]

        self._check_even_children(analogs, digitals)
        self._check_bounds(analogs)

        AO_table = self._make_analog_out_table(analogs, times)
        DO_table = self._make_digital_out_table(digitals, times)
        AI_table = self._make_analog_input_table(inputs)

        self._check_AI_not_too_fast(AI_table)

        grp = self.init_device_group(hdf5_file)
        if AO_table is not None:
            grp.create_dataset('AO',
                               data=AO_table,
                               compression=config.compression)
        if DO_table is not None:
            grp.create_dataset('DO',
                               data=DO_table,
                               compression=config.compression)
        if AI_table is not None:
            grp.create_dataset('AI',
                               data=AI_table,
                               compression=config.compression)
示例#7
0
    def _generate_code(self, hdf5_file):
        IntermediateDevice.generate_code(self, hdf5_file)
        analogs = {}
        digitals = {}
        inputs = {}
        for device in self.child_devices:
            if isinstance(device, AnalogOut):
                analogs[device.connection] = device
            elif isinstance(device, DigitalOut):
                digitals[device.connection] = device
            elif isinstance(device, AnalogIn):
                inputs[device.connection] = device
            else:
                raise Exception('Got unexpected device.')

        clockline = self.parent_device
        pseudoclock = clockline.parent_device
        times = pseudoclock.times[clockline]

        analog_connections = analogs.keys()
        analog_connections.sort()
        analog_out_attrs = []
        #KLUGGEEEE
        #get lenth of one output connection
        output_length = len(analogs[analog_connections[0]].raw_output)
        analog_out_table = np.empty((output_length, len(analogs)),
                                    dtype=np.float32)
        #analog_out_table = np.empty((len(times),len(analogs)), dtype=np.float32)
        for i, connection in enumerate(analog_connections):
            output = analogs[connection]
            if any(output.raw_output > 10) or any(output.raw_output < -10):
                # Bounds checking:
                raise LabscriptError(
                    '%s %s ' % (output.description, output.name) +
                    'can only have values between -10 and 10 Volts, ' +
                    'the limit imposed by %s.' % self.name)
            analog_out_table[:, i] = output.raw_output
            analog_out_attrs.append(self.MAX_name + '/' + connection)
        """
        if self.name == 'ni_card_B':
            #kluge to double every cell
            new_out_table = np.empty((output_length*2, len(analogs)), dtype=np.float32)
            for i, row in enumerate(analog_out_table):
                new_out_table[2*i] = row
                new_out_table[2*i+1] = row
            analog_out_table = new_out_table
        """
        #now we know that the last column should be randomized for one of the
        #CHOOSE CHANNEL HERE
        if self.name == 'ni_card_B':
            random_column = 0  #randint(0,6)
        else:
            # CHANGE THIS FOR CARD A
            random_column = 1

        #analog_out_table[:,-1] = analog_out_table[:,random_column]
        input_connections = inputs.keys()
        input_connections.sort()
        input_attrs = []
        acquisitions = []
        for connection in input_connections:
            input_attrs.append(self.MAX_name + '/' + connection)
            for acq in inputs[connection].acquisitions:
                acquisitions.append(
                    (connection, acq['label'], acq['start_time'],
                     acq['end_time'], acq['wait_label'], acq['scale_factor'],
                     acq['units']))
        # The 'a256' dtype below limits the string fields to 256
        # characters. Can't imagine this would be an issue, but to not
        # specify the string length (using dtype=str) causes the strings
        # to all come out empty.
        acquisitions_table_dtypes = [('connection', 'a256'), ('label', 'a256'),
                                     ('start', float), ('stop', float),
                                     ('wait label', 'a256'),
                                     ('scale factor', float),
                                     ('units', 'a256')]
        acquisition_table = np.empty(len(acquisitions),
                                     dtype=acquisitions_table_dtypes)
        for i, acq in enumerate(acquisitions):
            acquisition_table[i] = acq
        digital_out_table = []
        if digitals:
            digital_out_table = self.convert_bools_to_bytes(digitals.values())
        grp = self.init_device_group(hdf5_file)
        if all(analog_out_table.shape):  # Both dimensions must be nonzero
            grp.create_dataset('ANALOG_OUTS',
                               compression=config.compression,
                               data=analog_out_table)
            self.set_property('analog_out_channels',
                              ', '.join(analog_out_attrs),
                              location='device_properties')
        if len(digital_out_table):  # Table must be non empty
            grp.create_dataset('DIGITAL_OUTS',
                               compression=config.compression,
                               data=digital_out_table)
            self.set_property('digital_lines',
                              '/'.join((self.MAX_name, 'port0',
                                        'line0:%d' % (self.n_digitals - 1))),
                              location='device_properties')
        if len(acquisition_table):  # Table must be non empty
            grp.create_dataset('ACQUISITIONS',
                               compression=config.compression,
                               data=acquisition_table)
            self.set_property('analog_in_channels',
                              ', '.join(input_attrs),
                              location='device_properties')
        # TODO: move this to decorator (requires ability to set positional args with @set_passed_properties)
        self.set_property('clock_terminal',
                          self.clock_terminal,
                          location='connection_table_properties')
示例#8
0
    def generate_code(self, hdf5_file):

        IntermediateDevice.generate_code(self, hdf5_file)

        DDSProfs = {}

        if len(self.child_devices) > 1:
            raise LabscriptError(
                "Too many child_devices. This device expects exactly 1 AD_DDS child output."
            )

        output = self.child_devices[0]

        if isinstance(output, AD_DDS):
            prefix = output.connection[0]
            channel = int(output.connection[1])
        else:
            raise Exception('Got unexpected device.')

        numDDSProfs = len(output.profiles)

        grp = hdf5_file.create_group('/devices/' + self.name)

        if numDDSProfs:
            profile_dtypes = [('freq%d'%i,np.float) for i in range(numDDSProfs)] + \
                            [('phase%d'%i,np.float) for i in range(numDDSProfs)] + \
                            [('amp%d'%i,np.float) for i in range(numDDSProfs)]

            profile_table = np.zeros(1, dtype=profile_dtypes)

            for profile in output.profiles:
                profile_table['freq' +
                              profile[-1:]] = output.profiles[profile]['freq']
                profile_table['amp' +
                              profile[-1:]] = output.profiles[profile]['amp']
                profile_table['phase' +
                              profile[-1:]] = output.profiles[profile]['phase']

            grp.create_dataset('PROFILE_DATA',
                               compression=config.compression,
                               data=profile_table)

        if output.sweep:
            sweep_dtypes = [('sweep_type', np.int), ('sweep_low', np.float),
                            ('sweep_high', np.float),
                            ('sweep_risetime', np.float),
                            ('sweep_falltime', np.float),
                            ('sweep_dt', np.float)]

            sweep_table = np.empty(1, dtype=sweep_dtypes)

            sweep_types = {'freq': 0, 'phase': 1, 'amp': 2}

            sweep_table['sweep_type'] = sweep_types[
                output.sweep_params['type']]
            sweep_table['sweep_low'] = output.sweep_params['low']
            sweep_table['sweep_high'] = output.sweep_params['high']
            sweep_table['sweep_risetime'] = output.sweep_params['risetime']
            sweep_table['sweep_falltime'] = output.sweep_params['falltime']
            sweep_table['sweep_dt'] = output.sweep_params['sweep_dt']

            grp.create_dataset('SWEEP_DATA',
                               compression=config.compression,
                               data=sweep_table)
    def generate_code(self, hdf5_file):
        IntermediateDevice.generate_code(self, hdf5_file)
        analogs = {}
        digitals = {}
        inputs = {}
        for device in self.child_devices:
            if isinstance(device, AnalogOut):
                analogs[device.connection] = device
            elif isinstance(device, DigitalOut):
                digitals[device.connection] = device
            elif isinstance(device, AnalogIn):
                inputs[device.connection] = device
            else:
                raise Exception('Got unexpected device.')

        clockline = self.parent_device
        pseudoclock = clockline.parent_device
        times = pseudoclock.times[clockline]

        analog_out_table = np.empty((len(times), len(analogs)),
                                    dtype=np.float32)
        analog_connections = analogs.keys()
        analog_connections.sort()
        analog_out_attrs = []
        for i, connection in enumerate(analog_connections):
            output = analogs[connection]
            if any(output.raw_output > 10) or any(output.raw_output < -10):
                # Bounds checking:
                raise LabscriptError(
                    '%s %s ' % (output.description, output.name) +
                    'can only have values between -10 and 10 Volts, ' +
                    'the limit imposed by %s.' % self.name)
            analog_out_table[:, i] = output.raw_output
            analog_out_attrs.append(self.MAX_name + '/' + connection)
        input_connections = inputs.keys()
        input_connections.sort()
        input_attrs = []
        acquisitions = []
        for connection in input_connections:
            input_attrs.append(self.MAX_name + '/' + connection)
            for acq in inputs[connection].acquisitions:
                acquisitions.append(
                    (connection, acq['label'], acq['start_time'],
                     acq['end_time'], acq['wait_label'], acq['scale_factor'],
                     acq['units']))
        # The 'a256' dtype below limits the string fields to 256
        # characters. Can't imagine this would be an issue, but to not
        # specify the string length (using dtype=str) causes the strings
        # to all come out empty.
        acquisitions_table_dtypes = [('connection', 'a256'), ('label', 'a256'),
                                     ('start', float), ('stop', float),
                                     ('wait label', 'a256'),
                                     ('scale factor', float),
                                     ('units', 'a256')]
        acquisition_table = np.empty(len(acquisitions),
                                     dtype=acquisitions_table_dtypes)
        for i, acq in enumerate(acquisitions):
            acquisition_table[i] = acq
        digital_out_table = []
        if digitals:
            digital_out_table = self.convert_bools_to_bytes(digitals.values())
        grp = self.init_device_group(hdf5_file)
        if all(analog_out_table.shape):  # Both dimensions must be nonzero
            grp.create_dataset('ANALOG_OUTS',
                               compression=config.compression,
                               data=analog_out_table)
            self.set_property('analog_out_channels',
                              ', '.join(analog_out_attrs),
                              location='device_properties')
        if len(digital_out_table):  # Table must be non empty
            grp.create_dataset('DIGITAL_OUTS',
                               compression=config.compression,
                               data=digital_out_table)
            # construct a single string that has each port and line distribution separated by commas
            # this should coincide with the convention used by the create/write functions in the DAQmx library
            ports_str = ""
            for i in range(self.n_ports):
                ports_str = ports_str + self.MAX_name + '/port%d' % (
                    i) + '/line0:%d' % (self.n_lines - 1) + ','
            ports_str = ports_str[:-1]  # delete final comma in string
            self.set_property('digital_lines', (ports_str),
                              location='device_properties')
        if len(acquisition_table):  # Table must be non empty
            grp.create_dataset('ACQUISITIONS',
                               compression=config.compression,
                               data=acquisition_table)
            self.set_property('analog_in_channels',
                              ', '.join(input_attrs),
                              location='device_properties')
        # TODO: move this to decorator (requires ability to set positional args with @set_passed_properties)
        self.set_property('clock_terminal',
                          self.clock_terminal,
                          location='connection_table_properties')