コード例 #1
0
	def read(self):
		"""
		Take measurements.
		"""
		measurements = [None] * len(self.measurement_resources)

		thrs = []
		for i, (name, resource) in enumerate(self.measurement_resources):
			if resource is not None:
				def save_callback(value, i=i):
					measurements[i] = value
					if self.read_callback is not None:
						self.read_callback(i, value)

				thr = Thread(target=self.read_resource, args=(name, resource, save_callback))
				thrs.append(thr)
				thr.daemon = True
				thr.start()
		
		for thr in thrs:
			thr.join()

		if self.data_callback is not None:
			if self.first_time_point is None:
				cur_time = 0
				self.first_time_point = time()
			else:
				cur_time = time() - self.first_time_point

			self.data_callback(cur_time, tuple(flatten(self.current_values)), tuple(measurements))
			

		return self.condition
コード例 #2
0
    def read(self):
        """
		Take measurements.
		"""
        measurements = [None] * len(self.measurement_resources)

        thrs = []
        for i, (name, resource) in enumerate(self.measurement_resources):
            if resource is not None:

                def save_callback(value, i=i):
                    measurements[i] = value
                    if self.read_callback is not None:
                        self.read_callback(i, value)

                thr = Thread(target=self.read_resource,
                             args=(name, resource, save_callback))
                thrs.append(thr)
                thr.daemon = True
                thr.start()

        for thr in thrs:
            thr.join()

        if self.data_callback is not None:
            if self.first_time_point is None:
                cur_time = 0
                self.first_time_point = time()
            else:
                cur_time = time() - self.first_time_point

            self.data_callback(cur_time, tuple(flatten(self.current_values)),
                               tuple(measurements))

        return self.condition
コード例 #3
0
    def __init__(self,
                 resources,
                 variables,
                 num_items,
                 measurement_resources,
                 measurement_variables,
                 condition_resources=[],
                 condition_variables=[],
                 pulse_config=None,
                 continuous=False):
        self.resources = resources
        self.variables = variables
        self.num_items = num_items
        self.measurement_resources = measurement_resources
        self.measurement_variables = measurement_variables
        #TODO: Instead of flattening, make use of the group ordering for quicker access
        self.condition_resources = [
            cond_tuple for cond_tuple in flatten(condition_resources)
        ]
        self.condition_variables = condition_variables
        self.pulse_config = pulse_config
        self.continuous = continuous

        # The callbacks should be set before calling run(), if necessary.
        self.data_callback, self.close_callback, self.write_callback, self.read_callback = [
            None
        ] * 4
        self.general_exception_handler = None
        self.resource_exception_handler = None

        self.devices_configured = False

        self.current_f = None

        self.item = -1

        self.paused = False
        self.pause_lock = Condition()

        self.last_continuous = False
        self.done = False
        self.aborting = False
        self.abort_fatal = False

        self.sweep_start_time = time()
        self.first_time_point = None

        self.orders = [vars[0].order for vars in self.variables]
        self.orders.reverse()
        self.condition_orders = [
            group[0].order for group in self.condition_variables
        ]
        self.conditional_wait = 0
        self.order_periods = None
コード例 #4
0
def load_values(f):
    """
	Load data points from a file.

	The values in the file must either be comma separated, line-wise, or a combination of the two.
	For example:
		1.0,2.0,3.0
		4.0,5.0
		6.0
	would be interpreted as [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
	"""

    reader = csv.reader(f)

    # Ignore blank lines.
    return [float(x) for x in flatten(reader) if not x.isspace()]
コード例 #5
0
ファイル: box.py プロジェクト: 0/SpanishAcquisition
def load_values(f):
	"""
	Load data points from a file.

	The values in the file must either be comma separated, line-wise, or a combination of the two.
	For example:
		1.0,2.0,3.0
		4.0,5.0
		6.0
	would be interpreted as [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
	"""

	reader = csv.reader(f)

	# Ignore blank lines.
	return [float(x) for x in flatten(reader) if not x.isspace()]
コード例 #6
0
	def __init__(self, resources, variables, num_items, measurement_resources, measurement_variables,
			condition_resources=[], condition_variables=[], pulse_config=None, continuous=False):
		self.resources = resources
		self.variables = variables 
		self.num_items = num_items 
		self.measurement_resources = measurement_resources
		self.measurement_variables = measurement_variables
		#TODO: Instead of flattening, make use of the group ordering for quicker access
		self.condition_resources = [cond_tuple for cond_tuple in flatten(condition_resources)] 
		self.condition_variables = condition_variables
		self.pulse_config = pulse_config
		self.continuous = continuous

		# The callbacks should be set before calling run(), if necessary.
		self.data_callback, self.close_callback, self.write_callback, self.read_callback = [None] * 4
		self.general_exception_handler = None
		self.resource_exception_handler = None

		self.devices_configured = False

		self.current_f = None

		self.item = -1

		self.paused = False
		self.pause_lock = Condition()

		self.last_continuous = False
		self.done = False
		self.aborting = False
		self.abort_fatal = False

		self.sweep_start_time = time()
		self.first_time_point = None
		
		self.orders = [vars[0].order for vars in self.variables]
		self.orders.reverse()
		self.condition_orders = [group[0].order for group in self.condition_variables]
		self.conditional_wait = 0
		self.order_periods = None
コード例 #7
0
	def OnBeginCapture(self, evt=None):
		# Prevent accidental double-clicking.
		self.start_button.Disable()
		def enable_button():
			sleep(1)
			wx.CallAfter(self.start_button.Enable)
		thr = Thread(target=enable_button)
		thr.daemon = True
		thr.start()

		all_variables = [var for var in list(self.global_store.variables.values()) if var.enabled]
		output_variables = sift(all_variables, OutputVariable)
		input_variables = [var for var in sift(all_variables, InputVariable) if var.resource_name != '']
		condition_variables =  sift(all_variables, ConditionVariable)

		if not output_variables:
			output_variables.append(OutputVariable(order=0, name='<Dummy>', enabled=True))

		output_variables, num_items = sort_output_variables(output_variables)
		condition_variables = sort_condition_variables(condition_variables)

		resource_names = [tuple(var.resource_name for var in group) for group in output_variables]
		measurement_resource_names = [var.resource_name for var in input_variables]
		condition_resource_names = [tuple(set(flatten([var.resource_names for var in group]))) for group in condition_variables]


		continuous = self.continuous_checkbox.Value

		missing_resources = set()
		unreadable_resources = set()
		unwritable_resources = set()
		missing_devices = set()

		pulse_program = self.global_store.pulse_program

		if pulse_program is not None:
			pulse_program = pulse_program.with_resources

			try:
				pulse_program.generate_waveforms(dry_run=True)
			except PulseError as e:
				MessageDialog(self, '\n'.join(e[0]), 'Pulse program error', monospace=True).Show()
				return
			except Exception as e:
				MessageDialog(self, str(e), 'Pulse program error').Show()
				return

			pulse_awg, pulse_oscilloscope = None, None
			pulse_channels = {}

			try:
				pulse_awg = self.global_store.devices[pulse_program.awg].device
				if pulse_awg is None:
					raise KeyError
			except KeyError:
				missing_devices.add(pulse_program.awg)
			else:
				# Gather used channel numbers.
				pulse_channels = dict((k, v) for k, v in list(pulse_program.output_channels.items()) if v is not None)

				actual_channels = list(range(1, len(pulse_awg.channels)))
				invalid_channels = [k for k, v in list(pulse_channels.items()) if v not in actual_channels]

				if invalid_channels:
					MessageDialog(self, 'Invalid channels for: {0}'.format(', '.join(invalid_channels)), 'Invalid channels').Show()
					return

			try:
				pulse_oscilloscope = self.global_store.devices[pulse_program.oscilloscope].device
				if pulse_oscilloscope is None:
					raise KeyError
			except KeyError:
				missing_devices.add(pulse_program.oscilloscope)

			try:
				pulse_config = PulseConfiguration(pulse_program, pulse_channels, pulse_awg, pulse_oscilloscope)
			except TypeError as e:
				MessageDialog(self, str(e), 'Device configuration error').Show()
				return
		else:
			pulse_config = None

		resources = []
		for group in resource_names:
			group_resources = []

			for name in group:
				if name == '':
					group_resources.append((str(len(resources)), None))
				elif name not in self.global_store.resources:
					missing_resources.add(name)
				else:
					resource = self.global_store.resources[name]

					if resource.writable:
						group_resources.append((name, resource))
					else:
						unwritable_resources.add(name)

			resources.append(tuple(group_resources))
			
		measurement_resources = []
		measurement_units = []
		for name in measurement_resource_names:
			if name not in self.global_store.resources:
				missing_resources.add(name)
			else:
				resource = self.global_store.resources[name]

				if resource.readable:
					measurement_resources.append((name, resource))
					measurement_units.append(resource.display_units)
				else:
					unreadable_resources.add(name)
				
		condition_resources = []
		for group in condition_resource_names:
			group_resources = []
			
			for name in group:
				if name not in self.global_store.resources:
					missing_resources.add(name)
				else:
					resource = self.global_store.resources[name]

					if resource.readable:
						group_resources.append((name, resource))
					else:
						#the name may already have been put here by the loop assigning
						#to measurement_resources
						if name not in unreadable_resources:
							unreadable_resources.add(name)

			condition_resources.append(tuple(group_resources))

		mismatched_resources = []
		for (res_name, resource), var in zip(flatten(resources), flatten(output_variables)):
			if resource is None:
				continue

			if resource.units is not None:
				if not (var.type == 'quantity' and
						resource.verify_dimensions(var.units, exception=False, from_string=True)):
					mismatched_resources.append((res_name, var.name))
			else:
				if var.type not in ['float', 'integer']:
					mismatched_resources.append((res_name, var.name))

		for items, msg in [
			(missing_resources, 'Missing resources'),
			(unreadable_resources, 'Unreadable resources'),
			(unwritable_resources, 'Unwritable resources'),
			(missing_devices, 'Missing devices')]:

			if items:
				MessageDialog(self, ', '.join('"{0}"'.format(x) for x in sorted(items)), msg).Show()

		if mismatched_resources:
			MessageDialog(self, ', '.join('Mismatched resource type for resource name {0} with variable name {1}'.format(x[0], x[1]) for x in mismatched_resources),
					'Mismatched resources').Show()

		if (missing_resources or unreadable_resources or unwritable_resources or
				missing_devices or mismatched_resources):
			return
		
		# Check that all the condition arguments are compatible with one another.
		
		for cvar in flatten(condition_variables):
			
			# Get a condition.
			for cond in cvar.conditions:
								
				value1 = cond.arg1
				value2 = cond.arg2
				resource1 = None
				resource2 = None
				
				# If working with resources, use their values as the values, and make the resource available
				
				if cond.type1 == 'resource name':
					resource1 = [resource for (name, resource) in flatten(condition_resources) if name == cond.arg1][0]
					value1 = resource1.value
				if cond.type2 == 'resource name':
					resource2 = [resource for (name, resource) in flatten(condition_resources) if name == cond.arg2][0]
					value2 = resource2.value
				
				# Check if the other argument is in the allowed values
				
				if hasattr(resource1,'allowed_values') and resource1.allowed_values is not None:
					if value2 not in resource1.allowed_values:
						MessageDialog(self, 'In the condition {0}, {1} is not in allowed_values of {2}.'.format(cond, value2, cond.arg1),'Condition error').Show()
						return
				if hasattr(resource2,'allowed_values') and resource2.allowed_values is not None:
					if value1 not in resource2.allowed_values:
						MessageDialog(self, 'In the condition {0}, {1} is not in allowed_values of {2}.'.format(cond, value1, cond.arg2),'Condition error').Show()
						return

				# Check if units agree.
				
				if resource1 is not None and resource1.units is not None:
					try:
						value1.assert_dimensions(value2)
					except ValueError:
						MessageDialog(self, 'In the condition {0}, {1} does not have a dimension.'.format(cond, value2),'Condition error').Show()
						return
					except IncompatibleDimensions:
						MessageDialog(self, 'In the condition {0}, {1} and {2} do not have matching dimensions.'.format(cond, value1, value2),'Condition error').Show()
						return
				if resource2 is not None and resource2.units is not None:
					try:
						value2.assert_dimensions(value1)
					except ValueError:
						MessageDialog(self, 'In the condition {0}, {1} does not have a dimension.'.format(cond, value1),'Condition error').Show()
						return
					except IncompatibleDimensions:
						MessageDialog(self, 'In the condition {0}, {1} and {2} do not have matching dimensions.'.format(cond, value1, value2),'Condition error').Show()
						return


		exporting = False
		if self.export_enabled.Value:
			dir = self.directory_browse_button.GetValue()
			# YYYY-MM-DD_HH-MM-SS.csv
			name = '{0:04}-{1:02}-{2:02}_{3:02}-{4:02}-{5:02}.csv'.format(*localtime())

			if not dir:
				MessageDialog(self, 'No directory selected.', 'Export path').Show()
				return

			if not os.path.isdir(dir):
				MessageDialog(self, 'Invalid directory selected', 'Export path').Show()
				return

			file_path = os.path.join(dir, name)
			if os.path.exists(file_path):
				MessageDialog(self, file_path, 'File exists').Show()
				return

			# Everything looks alright, so open the file.
			export_file = open(file_path, 'w')
			export_csv = csv.writer(export_file)
			exporting = True

			# Show the path in the GUI.
			self.last_file_name.Value = file_path

			# Write the header.
			export_csv.writerow(['Time (s)'] +
					['{0.name} ({0.units})'.format(var) if var.units is not None else var.name
							for var in flatten(output_variables)] +
					['{0.name} ({1})'.format(var, units) if units is not None else var.name
						for var, units in zip(input_variables, measurement_units)])

		self.capture_dialogs += 1

		dlg = DataCaptureDialog(self, resources, output_variables, num_items, measurement_resources,
				input_variables, condition_resources, condition_variables, pulse_config, continuous=continuous)
		dlg.SetMinSize((500, -1))

		for name in measurement_resource_names:
			wx.CallAfter(pub.sendMessage, 'data_capture.start', name=name)

		# Export buffer.
		max_buf_size = 10
		buf = []
		buf_lock = Lock()

		def flush():
			export_csv.writerows(buf)
			export_file.flush()

			while buf:
				buf.pop()

		def data_callback(cur_time, values, measurement_values):
			for name, value in zip(measurement_resource_names, measurement_values):
				wx.CallAfter(pub.sendMessage, 'data_capture.data', name=name, value=value)

			# Extract values out of quantities, since the units have already been taken care of in the header.
			values = [x.original_value if hasattr(x, 'original_value') else x for x in values]
			measurement_values = [x.original_value if hasattr(x, 'original_value') else x for x in measurement_values]

			if exporting:
				with buf_lock:
					buf.append([cur_time] + values + measurement_values)

					if len(buf) >= max_buf_size:
						flush()

		def close_callback():
			self.capture_dialogs -= 1

			if exporting:
				with buf_lock:
					flush()
					export_file.close()

			for name in measurement_resource_names:
				wx.CallAfter(pub.sendMessage, 'data_capture.stop', name=name)

		dlg.data_callback = data_callback
		dlg.close_callback = close_callback
		dlg.Show()
		dlg.start()
コード例 #8
0
	def testProper(self):
		"""
		Testing everything that there is to test along the happy path:
			nested and parallel variables
			measurements
			dwell time
		"""

		res_bufs = [[], [], [], []]
		measurement_counts = [0] * 2

		def setter(i, value):
			res_bufs[i].append(value)

		def getter(i):
			measurement_counts[i] += (-1) ** i

			return measurement_counts[i]

		dwell_time = Quantity(50, 'ms')

		# Output.
		res0 = Resource(setter=partial(setter, 0))
		res0.units = 'cm-1'
		res1 = Resource(setter=partial(setter, 1))
		res2 = Resource(setter=partial(setter, 2))
		res3 = Resource(setter=partial(setter, 3))

		var0 = OutputVariable(name='Var 0', order=2, enabled=True, const=0.0)
		var0.config = LinSpaceConfig(-1.0, -2.0, 2)
		var0.smooth_steps = 2
		var0.smooth_from, var0.smooth_to, var0.smooth_transition = [True] * 3
		var0.type = 'quantity'
		var0.units = 'cm-1'

		var1 = OutputVariable(name='Var 1', order=1, enabled=True, const=-1.0)
		var1.config = LinSpaceConfig(1.0, 4.0, 4)
		var1.smooth_steps = 3
		var1.smooth_from, var1.smooth_to, var1.smooth_transition = [True] * 3

		var2 = OutputVariable(name='Var 2', order=1, enabled=True, const=1.23, use_const=True)

		var3 = OutputVariable(name='Var 3', order=1, enabled=True, const=-9.0, wait=str(dwell_time))
		var3.config = LinSpaceConfig(-1.0, 2.0, 4)
		var3.smooth_steps = 2
		var3.smooth_from, var3.smooth_to, var3.smooth_transition = True, True, False

		var4 = OutputVariable(name='Var 4', order=3, enabled=True, const=-20.0)
		var4.config = LinSpaceConfig(-10.0, 20, 1)
		var4.smooth_steps = 2
		var4.smooth_from = True

		# Input.
		meas_res0 = Resource(getter=partial(getter, 0))
		meas_res1 = Resource(getter=partial(getter, 1))

		meas0 = InputVariable(name='Meas 0')
		meas1 = InputVariable(name='Meas 1')

		vars, num_items = sort_output_variables([var0, var1, var2, var3, var4])
		ctrl = sweep.SweepController([(('Res 2', res2),), (('Something', None),), (('Res 0', res0),),
				(('Res 1', res1), ('Res 3', res3))], vars, num_items,
				[('Meas res 0', meas_res0), ('Meas res 1', meas_res1)], [meas0, meas1])

		# Callback verification buffers.
		actual_values = []
		actual_measurement_values = []
		actual_writes = []
		actual_reads = []
		closed = [0]

		# Callbacks.
		def data_callback(cur_time, values, measurement_values):
			actual_values.append(values)
			actual_measurement_values.append(measurement_values)
		ctrl.data_callback = data_callback

		def close_callback():
			closed[0] += 1
		ctrl.close_callback = close_callback

		def write_callback(pos, i, value):
			actual_writes.append((pos, i, value))
		ctrl.write_callback = write_callback

		def read_callback(i, value):
			actual_reads.append((i, value))
		ctrl.read_callback = read_callback

		# Let it run.
		start_time = time()
		ctrl.run()
		elapsed_time = time() - start_time

		expected_time = num_items * dwell_time.value
		assert expected_time < elapsed_time, 'Took {0} s, expected at least {1} s.'.format(elapsed_time, expected_time)

		expected_res1 = [1.0, 2.0, 3.0, 4.0]
		expected_res2 = [-1.0, 0.0, 1.0, 2.0]

		expected_inner_writes = list(flatten(((3, 0, x), (3, 1, x - 2.0)) for x in [1.0, 2.0, 3.0, 4.0]))
		expected_writes = [(0, 0, 1.23), (1, 0, -10.0)] + list(flatten([(2, 0, x)] + expected_inner_writes
				for x in [Quantity(x, 'cm-1') for x in [-1.0, -2.0]]))

		eq_(res_bufs, [
			[Quantity(x, 'cm-1') for x in [0.0, -1.0, -1.0, -2.0, -2.0, 0.0]],
			[-1.0, 0.0, 1.0] + expected_res1 + [4.0, 2.5, 1.0] + expected_res1 + [4.0, 1.5, -1.0],
			[1.23],
			[-9.0, -1.0] + expected_res2 + expected_res2 + [2.0, -9.0],
		])
		eq_(measurement_counts, [8, -8])
		eq_(actual_values, [(1.23, -10.0, x, y, y - 2.0)
				for x in [Quantity(x, 'cm-1') for x in [-1.0, -2.0]]
				for y in [1.0, 2.0, 3.0, 4.0]])
		eq_(actual_measurement_values, [(x, -x) for x in xrange(1, 9)])
		eq_(actual_writes, expected_writes)
		eq_(actual_reads, list(flatten(((0, x), (1, -x)) for x in xrange(1, 9))))
		eq_(closed, [1])
コード例 #9
0
	def testConditionsSweep(self):
		"""
		Tests a setup with condition variables and output variables.  Similar to testProper, but with
		conditions mixed in.
		"""

		res_bufs = [[], [], [], []]
		measurement_counts = [0] * 2

		def setter(i, value):
			res_bufs[i].append(value)

		def getter(i):
			measurement_counts[i] += (-1) ** i

			return measurement_counts[i]

		dwell_time = Quantity(50, 'ms')

		# Output.
		res0 = Resource(setter=partial(setter, 0))
		res0.units = 'cm-1'
		res1 = Resource(setter=partial(setter, 1))
		res2 = Resource(setter=partial(setter, 2))
		res3 = Resource(setter=partial(setter, 3))

		var0 = OutputVariable(name='Var 0', order=2, enabled=True, const=0.0)
		var0.config = LinSpaceConfig(-1.0, -2.0, 2)
		var0.smooth_steps = 2
		var0.smooth_from, var0.smooth_to, var0.smooth_transition = [True] * 3
		var0.type = 'quantity'
		var0.units = 'cm-1'

		var1 = OutputVariable(name='Var 1', order=1, enabled=True, const=-1.0)
		var1.config = LinSpaceConfig(1.0, 4.0, 4)
		var1.smooth_steps = 3
		var1.smooth_from, var1.smooth_to, var1.smooth_transition = [True] * 3

		var2 = OutputVariable(name='Var 2', order=1, enabled=True, const=1.23, use_const=True)

		var3 = OutputVariable(name='Var 3', order=1, enabled=True, const=-9.0, wait=str(dwell_time))
		var3.config = LinSpaceConfig(-1.0, 2.0, 4)
		var3.smooth_steps = 2
		var3.smooth_from, var3.smooth_to, var3.smooth_transition = True, True, False

		var4 = OutputVariable(name='Var 4', order=3, enabled=True, const=-20.0)
		var4.config = LinSpaceConfig(-10.0, 20, 1)
		var4.smooth_steps = 2
		var4.smooth_from = True
		
		# Condition variables.
		
		## Resources used for checking the conditions.
		
		iters = [cycle([0,1]), cycle([0,1,2]), cycle([0,-1,-2])]
		def cres_getter(i):
			return iters[i].next()
				
		cres0 = Resource('cres0', getter=partial(cres_getter,0))
		cres1 = Resource('cres1', getter=partial(cres_getter,1))
		cres2 = Resource('cres2', getter=partial(cres_getter,2))
		
		condition_resources = [(('cres0',cres0),),(('cres1',cres1),('cres2',cres2),)]
		
		
		cond0 = Condition('resource name','integer','cres0','==',1)
		cond1 = Condition('resource name','integer','cres1','==',2)
		cond2 = Condition('resource name','integer','cres2','==',-2)

		cvar0 = ConditionVariable(name='cvar0',order=0,enabled=True,wait=str(dwell_time),
								resource_names=['cres0',],conditions=[cond0])
		cvar1 = ConditionVariable(name='cvar1',order=1,enabled=True,wait=str(dwell_time),
								resource_names=['cres1',],conditions=[cond1])
		cvar2 = ConditionVariable(name='cvar2',order=1,enabled=True,wait=str(dwell_time),
								resource_names=['cres2',],conditions=[cond2])

		# Input.
		meas_res0 = Resource(getter=partial(getter, 0))
		meas_res1 = Resource(getter=partial(getter, 1))

		meas0 = InputVariable(name='Meas 0')
		meas1 = InputVariable(name='Meas 1')

		vars, num_items = sort_output_variables([var0, var1, var2, var3, var4])
		cvars = sort_condition_variables([cvar0,cvar1,cvar2])
		ctrl = sweep.SweepController([(('Res 2', res2),), (('Something', None),), (('Res 0', res0),),
				(('Res 1', res1), ('Res 3', res3))], vars, num_items,
				[('Meas res 0', meas_res0), ('Meas res 1', meas_res1)], [meas0, meas1],
				condition_resources, cvars)

		# Callback verification buffers.
		actual_values = []
		actual_measurement_values = []
		actual_writes = []
		actual_reads = []
		closed = [0]

		# Callbacks.
		def data_callback(cur_time, values, measurement_values):
			actual_values.append(values)
			actual_measurement_values.append(measurement_values)
		ctrl.data_callback = data_callback

		def close_callback():
			closed[0] += 1
		ctrl.close_callback = close_callback

		def write_callback(pos, i, value):
			actual_writes.append((pos, i, value))
		ctrl.write_callback = write_callback

		def read_callback(i, value):
			actual_reads.append((i, value))
		ctrl.read_callback = read_callback

		# Let it run.
		start_time = time()
		ctrl.run()
		elapsed_time = time() - start_time

		expected_time = num_items * dwell_time.value
		assert expected_time < elapsed_time, 'Took {0} s, expected at least {1} s.'.format(elapsed_time, expected_time)

		expected_res1 = [1.0, 2.0, 3.0, 4.0]
		expected_res2 = [-1.0, 0.0, 1.0, 2.0]

		expected_inner_writes = list(flatten(((3, 0, x), (3, 1, x - 2.0)) for x in [1.0, 2.0, 3.0, 4.0]))
		expected_writes = [(0, 0, 1.23), (1, 0, -10.0)] + list(flatten([(2, 0, x)] + expected_inner_writes
				for x in [Quantity(x, 'cm-1') for x in [-1.0, -2.0]]))

		eq_(res_bufs, [
			[Quantity(x, 'cm-1') for x in [0.0, -1.0, -1.0, -2.0, -2.0, 0.0]],
			[-1.0, 0.0, 1.0] + expected_res1 + [4.0, 2.5, 1.0] + expected_res1 + [4.0, 1.5, -1.0],
			[1.23],
			[-9.0, -1.0] + expected_res2 + expected_res2 + [2.0, -9.0],
		])
		
		eq_(measurement_counts, [24, -24])
		
	
		# Construct predicted actual values. 
		expected_actual_values = []
		for x in [Quantity(x, 'cm-1') for x in [-1.0, -2.0]]:
			for y in [1.0, 2.0, 3.0, 4.0]:
				
				# We append twice since the 0th order condition will create an extra measurement
				# for every non_conditionally based measurement
				expected_actual_values.append((1.23, -10.0, x, y, y - 2.0))
				expected_actual_values.append((1.23, -10.0, x, y, y - 2.0))
				
				# If were at the end of order 1, we append 4 more times to have a total of 6
				# This is because in the condition checking stage, we require the 0th order condition
				# and the 1st order conditions to all be true. So, cycling through entries in [0,1]
				# and [0,1,2], it will take a total of 6 condition checks to get 1 in [0,1], and 2 in
				# [0,1,2].
				if y == 4:
					expected_actual_values.append((1.23, -10.0, x, y, y - 2.0))
					expected_actual_values.append((1.23, -10.0, x, y, y - 2.0))
					expected_actual_values.append((1.23, -10.0, x, y, y - 2.0))
					expected_actual_values.append((1.23, -10.0, x, y, y - 2.0))
				

		eq_(actual_values, expected_actual_values)

		eq_(actual_measurement_values, [(x, -x) for x in xrange(1, 25)])
		eq_(actual_writes, expected_writes)
		eq_(actual_reads, list(flatten(((0, x), (1, -x)) for x in xrange(1, 25))))
		eq_(closed, [1])
コード例 #10
0
ファイル: data_capture.py プロジェクト: 0/SpanishAcquisition
	def OnBeginCapture(self, evt=None):
		# Prevent accidental double-clicking.
		self.start_button.Disable()
		def enable_button():
			sleep(1)
			wx.CallAfter(self.start_button.Enable)
		thr = Thread(target=enable_button)
		thr.daemon = True
		thr.start()

		all_variables = [var for var in self.global_store.variables.values() if var.enabled]
		output_variables = sift(all_variables, OutputVariable)
		input_variables = [var for var in sift(all_variables, InputVariable) if var.resource_name != '']

		if not output_variables:
			output_variables.append(OutputVariable(order=0, name='<Dummy>', enabled=True))

		output_variables, num_items = sort_variables(output_variables)

		resource_names = [tuple(var.resource_name for var in group) for group in output_variables]
		measurement_resource_names = [var.resource_name for var in input_variables]

		continuous = self.continuous_checkbox.Value

		missing_resources = set()
		unreadable_resources = set()
		unwritable_resources = set()
		missing_devices = set()

		pulse_program = self.global_store.pulse_program

		if pulse_program is not None:
			pulse_program = pulse_program.with_resources

			try:
				pulse_program.generate_waveforms(dry_run=True)
			except PulseError as e:
				MessageDialog(self, '\n'.join(e[0]), 'Pulse program error', monospace=True).Show()
				return
			except Exception as e:
				MessageDialog(self, str(e), 'Pulse program error').Show()
				return

			pulse_awg, pulse_oscilloscope = None, None
			pulse_channels = {}

			try:
				pulse_awg = self.global_store.devices[pulse_program.awg].device
				if pulse_awg is None:
					raise KeyError
			except KeyError:
				missing_devices.add(pulse_program.awg)
			else:
				# Gather used channel numbers.
				pulse_channels = dict((k, v) for k, v in pulse_program.output_channels.items() if v is not None)

				actual_channels = range(1, len(pulse_awg.channels))
				invalid_channels = [k for k, v in pulse_channels.items() if v not in actual_channels]

				if invalid_channels:
					MessageDialog(self, 'Invalid channels for: {0}'.format(', '.join(invalid_channels)), 'Invalid channels').Show()
					return

			try:
				pulse_oscilloscope = self.global_store.devices[pulse_program.oscilloscope].device
				if pulse_oscilloscope is None:
					raise KeyError
			except KeyError:
				missing_devices.add(pulse_program.oscilloscope)

			try:
				pulse_config = PulseConfiguration(pulse_program, pulse_channels, pulse_awg, pulse_oscilloscope)
			except TypeError as e:
				MessageDialog(self, str(e), 'Device configuration error').Show()
				return
		else:
			pulse_config = None

		resources = []
		for group in resource_names:
			group_resources = []

			for name in group:
				if name == '':
					group_resources.append((str(len(resources)), None))
				elif name not in self.global_store.resources:
					missing_resources.add(name)
				else:
					resource = self.global_store.resources[name]

					if resource.writable:
						group_resources.append((name, resource))
					else:
						unwritable_resources.add(name)

			resources.append(tuple(group_resources))

		measurement_resources = []
		measurement_units = []
		for name in measurement_resource_names:
			if name not in self.global_store.resources:
				missing_resources.add(name)
			else:
				resource = self.global_store.resources[name]

				if resource.readable:
					measurement_resources.append((name, resource))
					measurement_units.append(resource.display_units)
				else:
					unreadable_resources.add(name)

		mismatched_resources = []
		for (res_name, resource), var in zip(flatten(resources), flatten(output_variables)):
			if resource is None:
				continue

			if resource.units is not None:
				if not (var.type == 'quantity' and
						resource.verify_dimensions(var.units, exception=False, from_string=True)):
					mismatched_resources.append((res_name, var.name))
			else:
				if var.type not in ['float', 'integer']:
					mismatched_resources.append((res_name, var.name))

		for items, msg in [
			(missing_resources, 'Missing resources'),
			(unreadable_resources, 'Unreadable resources'),
			(unwritable_resources, 'Unwritable resources'),
			(missing_devices, 'Missing devices')]:

			if items:
				MessageDialog(self, ', '.join('"{0}"'.format(x) for x in sorted(items)), msg).Show()

		if mismatched_resources:
			MessageDialog(self, ', '.join('{0}/{1}'.format(x[0], x[1]) for x in mismatched_resources),
					'Mismatched resources').Show()

		if (missing_resources or unreadable_resources or unwritable_resources or
				missing_devices or mismatched_resources):
			return

		exporting = False
		if self.export_enabled.Value:
			dir = self.directory_browse_button.GetValue()
			# YYYY-MM-DD_HH-MM-SS.csv
			name = '{0:04}-{1:02}-{2:02}_{3:02}-{4:02}-{5:02}.csv'.format(*localtime())

			if not dir:
				MessageDialog(self, 'No directory selected.', 'Export path').Show()
				return

			if not os.path.isdir(dir):
				MessageDialog(self, 'Invalid directory selected', 'Export path').Show()
				return

			file_path = os.path.join(dir, name)
			if os.path.exists(file_path):
				MessageDialog(self, file_path, 'File exists').Show()
				return

			# Everything looks alright, so open the file.
			export_file = open(file_path, 'w')
			export_csv = csv.writer(export_file)
			exporting = True

			# Show the path in the GUI.
			self.last_file_name.Value = file_path

			# Write the header.
			export_csv.writerow(['Time (s)'] +
					['{0.name} ({0.units})'.format(var) if var.units is not None else var.name
							for var in flatten(output_variables)] +
					['{0.name} ({1})'.format(var, units) if units is not None else var.name
						for var, units in zip(input_variables, measurement_units)])

		self.capture_dialogs += 1

		dlg = DataCaptureDialog(self, resources, output_variables, num_items, measurement_resources,
				input_variables, pulse_config, continuous=continuous)
		dlg.SetMinSize((500, -1))

		for name in measurement_resource_names:
			wx.CallAfter(pub.sendMessage, 'data_capture.start', name=name)

		# Export buffer.
		max_buf_size = 10
		buf = []
		buf_lock = Lock()

		def flush():
			export_csv.writerows(buf)
			export_file.flush()

			while buf:
				buf.pop()

		def data_callback(cur_time, values, measurement_values):
			for name, value in zip(measurement_resource_names, measurement_values):
				wx.CallAfter(pub.sendMessage, 'data_capture.data', name=name, value=value)

			# Extract values out of quantities, since the units have already been taken care of in the header.
			values = [x.original_value if hasattr(x, 'original_value') else x for x in values]
			measurement_values = [x.original_value if hasattr(x, 'original_value') else x for x in measurement_values]

			if exporting:
				with buf_lock:
					buf.append([cur_time] + values + measurement_values)

					if len(buf) >= max_buf_size:
						flush()

		def close_callback():
			self.capture_dialogs -= 1

			if exporting:
				with buf_lock:
					flush()
					export_file.close()

			for name in measurement_resource_names:
				wx.CallAfter(pub.sendMessage, 'data_capture.stop', name=name)

		dlg.data_callback = data_callback
		dlg.close_callback = close_callback
		dlg.Show()
		dlg.start()
コード例 #11
0
    def testProper(self):
        """
		Testing everything that there is to test along the happy path:
			nested and parallel variables
			measurements
			dwell time
		"""

        res_bufs = [[], [], [], []]
        measurement_counts = [0] * 2

        def setter(i, value):
            res_bufs[i].append(value)

        def getter(i):
            measurement_counts[i] += (-1)**i

            return measurement_counts[i]

        dwell_time = Quantity(50, 'ms')

        # Output.
        res0 = Resource(setter=partial(setter, 0))
        res0.units = 'cm-1'
        res1 = Resource(setter=partial(setter, 1))
        res2 = Resource(setter=partial(setter, 2))
        res3 = Resource(setter=partial(setter, 3))

        var0 = OutputVariable(name='Var 0', order=2, enabled=True, const=0.0)
        var0.config = LinSpaceConfig(-1.0, -2.0, 2)
        var0.smooth_steps = 2
        var0.smooth_from, var0.smooth_to, var0.smooth_transition = [True] * 3
        var0.type = 'quantity'
        var0.units = 'cm-1'

        var1 = OutputVariable(name='Var 1', order=1, enabled=True, const=-1.0)
        var1.config = LinSpaceConfig(1.0, 4.0, 4)
        var1.smooth_steps = 3
        var1.smooth_from, var1.smooth_to, var1.smooth_transition = [True] * 3

        var2 = OutputVariable(name='Var 2',
                              order=1,
                              enabled=True,
                              const=1.23,
                              use_const=True)

        var3 = OutputVariable(name='Var 3',
                              order=1,
                              enabled=True,
                              const=-9.0,
                              wait=str(dwell_time))
        var3.config = LinSpaceConfig(-1.0, 2.0, 4)
        var3.smooth_steps = 2
        var3.smooth_from, var3.smooth_to, var3.smooth_transition = True, True, False

        var4 = OutputVariable(name='Var 4', order=3, enabled=True, const=-20.0)
        var4.config = LinSpaceConfig(-10.0, 20, 1)
        var4.smooth_steps = 2
        var4.smooth_from = True

        # Input.
        meas_res0 = Resource(getter=partial(getter, 0))
        meas_res1 = Resource(getter=partial(getter, 1))

        meas0 = InputVariable(name='Meas 0')
        meas1 = InputVariable(name='Meas 1')

        vars, num_items = sort_output_variables([var0, var1, var2, var3, var4])
        ctrl = sweep.SweepController([(('Res 2', res2), ),
                                      (('Something', None), ),
                                      (('Res 0', res0), ),
                                      (('Res 1', res1), ('Res 3', res3))],
                                     vars, num_items,
                                     [('Meas res 0', meas_res0),
                                      ('Meas res 1', meas_res1)],
                                     [meas0, meas1])

        # Callback verification buffers.
        actual_values = []
        actual_measurement_values = []
        actual_writes = []
        actual_reads = []
        closed = [0]

        # Callbacks.
        def data_callback(cur_time, values, measurement_values):
            actual_values.append(values)
            actual_measurement_values.append(measurement_values)

        ctrl.data_callback = data_callback

        def close_callback():
            closed[0] += 1

        ctrl.close_callback = close_callback

        def write_callback(pos, i, value):
            actual_writes.append((pos, i, value))

        ctrl.write_callback = write_callback

        def read_callback(i, value):
            actual_reads.append((i, value))

        ctrl.read_callback = read_callback

        # Let it run.
        start_time = time()
        ctrl.run()
        elapsed_time = time() - start_time

        expected_time = num_items * dwell_time.value
        assert expected_time < elapsed_time, 'Took {0} s, expected at least {1} s.'.format(
            elapsed_time, expected_time)

        expected_res1 = [1.0, 2.0, 3.0, 4.0]
        expected_res2 = [-1.0, 0.0, 1.0, 2.0]

        expected_inner_writes = list(
            flatten(
                ((3, 0, x), (3, 1, x - 2.0)) for x in [1.0, 2.0, 3.0, 4.0]))
        expected_writes = [(0, 0, 1.23), (1, 0, -10.0)] + list(
            flatten([(2, 0, x)] + expected_inner_writes
                    for x in [Quantity(x, 'cm-1') for x in [-1.0, -2.0]]))

        eq_(res_bufs, [
            [Quantity(x, 'cm-1') for x in [0.0, -1.0, -1.0, -2.0, -2.0, 0.0]],
            [-1.0, 0.0, 1.0] + expected_res1 + [4.0, 2.5, 1.0] +
            expected_res1 + [4.0, 1.5, -1.0],
            [1.23],
            [-9.0, -1.0] + expected_res2 + expected_res2 + [2.0, -9.0],
        ])
        eq_(measurement_counts, [8, -8])
        eq_(actual_values,
            [(1.23, -10.0, x, y, y - 2.0)
             for x in [Quantity(x, 'cm-1') for x in [-1.0, -2.0]]
             for y in [1.0, 2.0, 3.0, 4.0]])
        eq_(actual_measurement_values, [(x, -x) for x in xrange(1, 9)])
        eq_(actual_writes, expected_writes)
        eq_(actual_reads, list(flatten(
            ((0, x), (1, -x)) for x in xrange(1, 9))))
        eq_(closed, [1])
コード例 #12
0
    def testConditionsSweep(self):
        """
		Tests a setup with condition variables and output variables.  Similar to testProper, but with
		conditions mixed in.
		"""

        res_bufs = [[], [], [], []]
        measurement_counts = [0] * 2

        def setter(i, value):
            res_bufs[i].append(value)

        def getter(i):
            measurement_counts[i] += (-1)**i

            return measurement_counts[i]

        dwell_time = Quantity(50, 'ms')

        # Output.
        res0 = Resource(setter=partial(setter, 0))
        res0.units = 'cm-1'
        res1 = Resource(setter=partial(setter, 1))
        res2 = Resource(setter=partial(setter, 2))
        res3 = Resource(setter=partial(setter, 3))

        var0 = OutputVariable(name='Var 0', order=2, enabled=True, const=0.0)
        var0.config = LinSpaceConfig(-1.0, -2.0, 2)
        var0.smooth_steps = 2
        var0.smooth_from, var0.smooth_to, var0.smooth_transition = [True] * 3
        var0.type = 'quantity'
        var0.units = 'cm-1'

        var1 = OutputVariable(name='Var 1', order=1, enabled=True, const=-1.0)
        var1.config = LinSpaceConfig(1.0, 4.0, 4)
        var1.smooth_steps = 3
        var1.smooth_from, var1.smooth_to, var1.smooth_transition = [True] * 3

        var2 = OutputVariable(name='Var 2',
                              order=1,
                              enabled=True,
                              const=1.23,
                              use_const=True)

        var3 = OutputVariable(name='Var 3',
                              order=1,
                              enabled=True,
                              const=-9.0,
                              wait=str(dwell_time))
        var3.config = LinSpaceConfig(-1.0, 2.0, 4)
        var3.smooth_steps = 2
        var3.smooth_from, var3.smooth_to, var3.smooth_transition = True, True, False

        var4 = OutputVariable(name='Var 4', order=3, enabled=True, const=-20.0)
        var4.config = LinSpaceConfig(-10.0, 20, 1)
        var4.smooth_steps = 2
        var4.smooth_from = True

        # Condition variables.

        ## Resources used for checking the conditions.

        iters = [cycle([0, 1]), cycle([0, 1, 2]), cycle([0, -1, -2])]

        def cres_getter(i):
            return iters[i].next()

        cres0 = Resource('cres0', getter=partial(cres_getter, 0))
        cres1 = Resource('cres1', getter=partial(cres_getter, 1))
        cres2 = Resource('cres2', getter=partial(cres_getter, 2))

        condition_resources = [(('cres0', cres0), ),
                               (
                                   ('cres1', cres1),
                                   ('cres2', cres2),
                               )]

        cond0 = Condition('resource name', 'integer', 'cres0', '==', 1)
        cond1 = Condition('resource name', 'integer', 'cres1', '==', 2)
        cond2 = Condition('resource name', 'integer', 'cres2', '==', -2)

        cvar0 = ConditionVariable(name='cvar0',
                                  order=0,
                                  enabled=True,
                                  wait=str(dwell_time),
                                  resource_names=[
                                      'cres0',
                                  ],
                                  conditions=[cond0])
        cvar1 = ConditionVariable(name='cvar1',
                                  order=1,
                                  enabled=True,
                                  wait=str(dwell_time),
                                  resource_names=[
                                      'cres1',
                                  ],
                                  conditions=[cond1])
        cvar2 = ConditionVariable(name='cvar2',
                                  order=1,
                                  enabled=True,
                                  wait=str(dwell_time),
                                  resource_names=[
                                      'cres2',
                                  ],
                                  conditions=[cond2])

        # Input.
        meas_res0 = Resource(getter=partial(getter, 0))
        meas_res1 = Resource(getter=partial(getter, 1))

        meas0 = InputVariable(name='Meas 0')
        meas1 = InputVariable(name='Meas 1')

        vars, num_items = sort_output_variables([var0, var1, var2, var3, var4])
        cvars = sort_condition_variables([cvar0, cvar1, cvar2])
        ctrl = sweep.SweepController([(('Res 2', res2), ),
                                      (('Something', None), ),
                                      (('Res 0', res0), ),
                                      (('Res 1', res1), ('Res 3', res3))],
                                     vars, num_items,
                                     [('Meas res 0', meas_res0),
                                      ('Meas res 1', meas_res1)],
                                     [meas0, meas1], condition_resources,
                                     cvars)

        # Callback verification buffers.
        actual_values = []
        actual_measurement_values = []
        actual_writes = []
        actual_reads = []
        closed = [0]

        # Callbacks.
        def data_callback(cur_time, values, measurement_values):
            actual_values.append(values)
            actual_measurement_values.append(measurement_values)

        ctrl.data_callback = data_callback

        def close_callback():
            closed[0] += 1

        ctrl.close_callback = close_callback

        def write_callback(pos, i, value):
            actual_writes.append((pos, i, value))

        ctrl.write_callback = write_callback

        def read_callback(i, value):
            actual_reads.append((i, value))

        ctrl.read_callback = read_callback

        # Let it run.
        start_time = time()
        ctrl.run()
        elapsed_time = time() - start_time

        expected_time = num_items * dwell_time.value
        assert expected_time < elapsed_time, 'Took {0} s, expected at least {1} s.'.format(
            elapsed_time, expected_time)

        expected_res1 = [1.0, 2.0, 3.0, 4.0]
        expected_res2 = [-1.0, 0.0, 1.0, 2.0]

        expected_inner_writes = list(
            flatten(
                ((3, 0, x), (3, 1, x - 2.0)) for x in [1.0, 2.0, 3.0, 4.0]))
        expected_writes = [(0, 0, 1.23), (1, 0, -10.0)] + list(
            flatten([(2, 0, x)] + expected_inner_writes
                    for x in [Quantity(x, 'cm-1') for x in [-1.0, -2.0]]))

        eq_(res_bufs, [
            [Quantity(x, 'cm-1') for x in [0.0, -1.0, -1.0, -2.0, -2.0, 0.0]],
            [-1.0, 0.0, 1.0] + expected_res1 + [4.0, 2.5, 1.0] +
            expected_res1 + [4.0, 1.5, -1.0],
            [1.23],
            [-9.0, -1.0] + expected_res2 + expected_res2 + [2.0, -9.0],
        ])

        eq_(measurement_counts, [24, -24])

        # Construct predicted actual values.
        expected_actual_values = []
        for x in [Quantity(x, 'cm-1') for x in [-1.0, -2.0]]:
            for y in [1.0, 2.0, 3.0, 4.0]:

                # We append twice since the 0th order condition will create an extra measurement
                # for every non_conditionally based measurement
                expected_actual_values.append((1.23, -10.0, x, y, y - 2.0))
                expected_actual_values.append((1.23, -10.0, x, y, y - 2.0))

                # If were at the end of order 1, we append 4 more times to have a total of 6
                # This is because in the condition checking stage, we require the 0th order condition
                # and the 1st order conditions to all be true. So, cycling through entries in [0,1]
                # and [0,1,2], it will take a total of 6 condition checks to get 1 in [0,1], and 2 in
                # [0,1,2].
                if y == 4:
                    expected_actual_values.append((1.23, -10.0, x, y, y - 2.0))
                    expected_actual_values.append((1.23, -10.0, x, y, y - 2.0))
                    expected_actual_values.append((1.23, -10.0, x, y, y - 2.0))
                    expected_actual_values.append((1.23, -10.0, x, y, y - 2.0))

        eq_(actual_values, expected_actual_values)

        eq_(actual_measurement_values, [(x, -x) for x in xrange(1, 25)])
        eq_(actual_writes, expected_writes)
        eq_(actual_reads,
            list(flatten(((0, x), (1, -x)) for x in xrange(1, 25))))
        eq_(closed, [1])