def run(self): """ Starts writing a waveform continuously to the patchclamp. While reading the buffer periodically """ self.patchVoltOutChan = self.configs["VpPatch"] self.patchCurOutChan = self.configs["Ip"] self.patchVoltInChan = self.configs["patchAO"] # DAQ with nidaqmx.Task() as writeTask, nidaqmx.Task() as readTask: writeTask.ao_channels.add_ao_voltage_chan(self.patchVoltInChan) readTask.ai_channels.add_ai_voltage_chan(self.patchVoltOutChan) readTask.ai_channels.add_ai_voltage_chan(self.patchCurOutChan) self.setTiming(writeTask, readTask) reader = AnalogMultiChannelReader(readTask.in_stream) writer = AnalogSingleChannelWriter(writeTask.out_stream) writer.write_many_sample(self.wave) """Reading data from the buffer in a loop. The idea is to let the task read more than could be loaded in the buffer for each iteration. This way the task will have to wait slightly longer for incoming samples. And leaves the buffer entirely clean. This way we always know the correct numpy size and are always left with an empty buffer (and the buffer will not slowly fill up).""" # output = np.zeros([2, self.readNumber]) writeTask.start() # Will wait for the readtask to start so it can use its clock readTask.start()
def test_one_sample(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) # Select a random loopback channel pair on the device. loopback_channel_pairs = self._get_analog_loopback_channels( x_series_device) loopback_channel_pair = random.choice(loopback_channel_pairs) with nidaqmx.Task() as write_task, nidaqmx.Task() as read_task: write_task.ao_channels.add_ao_voltage_chan( loopback_channel_pair.output_channel, max_val=10, min_val=-10) read_task.ai_channels.add_ai_voltage_chan( loopback_channel_pair.input_channel, max_val=10, min_val=-10) writer = AnalogSingleChannelWriter(write_task.out_stream) reader = AnalogSingleChannelReader(read_task.in_stream) # Generate random values to test. values_to_test = [random.uniform(-10, 10) for _ in range(10)] values_read = [] for value_to_test in values_to_test: writer.write_one_sample(value_to_test) time.sleep(0.001) value_read = reader.read_one_sample() assert isinstance(value_read, float) values_read.append(value_read) numpy.testing.assert_allclose( values_read, values_to_test, rtol=0.05, atol=0.005)
def dcoutDelayed(taskName, devNum, channelName, voltage, bTrig=0, trigChan="PFI0"): try: daq = initDAQ(devNum) except IndexError: print("No NI DAQ device connected") raise SystemExit except Exception: print("Unknown Error") raise SystemExit with nidaqmx.Task() as task: channelAddr = "Dev%d/%s" % (devNum + 1, channelName) fileName = fileName + str(devNum + 1) + channelName + ".pkl" task.ao_channels.add_ao_voltage_chan(channelAddr) task.timing.cfg_samp_clk_timing(rate=2, sample_mode=AcquisitionType.FINITE, samps_per_chan=2) if bTrig: task.triggers.start_trigger.cfg_dig_edge_start_trig( trigChan, Edge.RISING) writer = AnalogSingleChannelWriter(task.out_stream, auto_start=False) samples = np.ones(2) * voltage writer.write_many_sample(samples) task.start() task.save(save_as=taskName, overwrite_existing_task=True)
def test_many_sample(self, x_series_device, seed): # Reset the pseudorandom number generator with seed. random.seed(seed) number_of_samples = random.randint(20, 100) sample_rate = random.uniform(1000, 5000) # Select a random loopback channel pair on the device. loopback_channel_pairs = self._get_analog_loopback_channels( x_series_device) loopback_channel_pair = random.choice(loopback_channel_pairs) with nidaqmx.Task() as write_task, nidaqmx.Task() as read_task, \ nidaqmx.Task() as sample_clk_task: # Use a counter output pulse train task as the sample clock source # for both the AI and AO tasks. sample_clk_task.co_channels.add_co_pulse_chan_freq( '{0}/ctr0'.format(x_series_device.name), freq=sample_rate) sample_clk_task.timing.cfg_implicit_timing( samps_per_chan=number_of_samples) samp_clk_terminal = '/{0}/Ctr0InternalOutput'.format( x_series_device.name) write_task.ao_channels.add_ao_voltage_chan( loopback_channel_pair.output_channel, max_val=10, min_val=-10) write_task.timing.cfg_samp_clk_timing( sample_rate, source=samp_clk_terminal, active_edge=Edge.RISING, samps_per_chan=number_of_samples) read_task.ai_channels.add_ai_voltage_chan( loopback_channel_pair.input_channel, max_val=10, min_val=-10) read_task.timing.cfg_samp_clk_timing( sample_rate, source=samp_clk_terminal, active_edge=Edge.FALLING, samps_per_chan=number_of_samples) writer = AnalogSingleChannelWriter(write_task.out_stream) reader = AnalogSingleChannelReader(read_task.in_stream) # Generate random values to test. values_to_test = numpy.array( [random.uniform(-10, 10) for _ in range(number_of_samples)], dtype=numpy.float64) writer.write_many_sample(values_to_test) # Start the read and write tasks before starting the sample clock # source task. read_task.start() write_task.start() sample_clk_task.start() values_read = numpy.zeros(number_of_samples, dtype=numpy.float64) reader.read_many_sample( values_read, number_of_samples_per_channel=number_of_samples, timeout=2) numpy.testing.assert_allclose( values_read, values_to_test, rtol=0.05, atol=0.005)
def measure(self): """ Starts writing a waveform continuously to the patchclamp. While reading the buffer periodically. """ self.patchVoltOutChan = self.configs["Vp"] self.patchCurOutChan = self.configs["Ip"] self.patchVoltInChan = self.configs["patchAO"] # DAQ with nidaqmx.Task() as writeTask, nidaqmx.Task() as readTask: writeTask.ao_channels.add_ao_voltage_chan(self.patchVoltInChan) readTask.ai_channels.add_ai_voltage_chan(self.patchVoltOutChan) readTask.ai_channels.add_ai_voltage_chan(self.patchCurOutChan) self.setTiming(writeTask, readTask) reader = AnalogMultiChannelReader(readTask.in_stream) writer = AnalogSingleChannelWriter(writeTask.out_stream) writer.write_many_sample(self.wave) """Reading data from the buffer in a loop. The idea is to let the task read more than could be loaded in the buffer for each iteration. This way the task will have to wait slightly longer for incoming samples. And leaves the buffer entirely clean. This way we always know the correct numpy size and are always left with an empty buffer (and the buffer will not slowly fill up).""" if self.mode == 'voltageclamp': output = np.zeros([2, self.readNumber]) writeTask.start() # Will wait for the readtask to start so it can use its clock readTask.start() self.isRunning = True while self.isRunning: reader.read_many_sample(data=output, number_of_samples_per_channel=self.readNumber) # Emiting the data just received as a signal self.measurement.emit(output[0,:], output[1,:]) elif self.mode == 'zap': writeTask.start() # Will wait for the readtask to start so it can use its clock readTask.start() else: pass print('sealtest thread stopped')
def setup_DAQmx(self): self.read_task = nidaqmx.Task() self.write_task = nidaqmx.Task() self.sample_clk_task = nidaqmx.Task() # Use a counter output pulse train task as the sample clock source # for both the AI and AO tasks. self.sample_clk_task.co_channels.add_co_pulse_chan_freq('Dev1/ctr0', freq=self.sample_rate, idle_state=Level.LOW) self.sample_clk_task.timing.cfg_implicit_timing(sample_mode=AcquisitionType.CONTINUOUS,samps_per_chan=self.number_of_samples) self.sample_clk_task.control(TaskMode.TASK_COMMIT) samp_clk_terminal = '/Dev1/Ctr0InternalOutput' self.read_task.ai_channels.add_ai_voltage_chan(self.input_channel, max_val=10, min_val=-10) self.read_task.timing.cfg_samp_clk_timing(self.sample_rate, source=samp_clk_terminal, active_edge=Edge.FALLING,sample_mode=AcquisitionType.CONTINUOUS, samps_per_chan=self.number_of_samples) self.write_task.ao_channels.add_ao_voltage_chan(self.output_channel, max_val=10, min_val=-10) self.write_task.timing.cfg_samp_clk_timing(self.sample_rate, source=samp_clk_terminal, active_edge=Edge.FALLING,sample_mode=AcquisitionType.CONTINUOUS, samps_per_chan=self.number_of_samples) self.write_task.out_stream.regen_mode = RegenerationMode.DONT_ALLOW_REGENERATION self.write_task.out_stream.auto_start = False self.writer = AnalogSingleChannelWriter(self.write_task.out_stream) self.reader = AnalogMultiChannelReader(self.read_task.in_stream)
def dcoutNow(devNum, channelName, voltage, bTrig=0, trigChan="PFI0", fileName="MostRecentOutputVoltageOn"): bTrig = int(bTrig) devNum = int(devNum) try: daq = initDAQ(devNum) except IndexError: print("No NI DAQ device connected") raise SystemExit except Exception: print("Unknown Error") raise SystemExit with nidaqmx.Task() as task: channelAddr = "Dev%d/%s" % (devNum + 1, channelName) fileName = fileName + str(devNum + 1) + channelName + ".pkl" task.ao_channels.add_ao_voltage_chan(channelAddr) task.timing.cfg_samp_clk_timing(rate=2, sample_mode=AcquisitionType.FINITE, samps_per_chan=2) if bTrig: task.triggers.start_trigger.cfg_dig_edge_start_trig( trigChan, Edge.RISING) writer = AnalogSingleChannelWriter(task.out_stream, auto_start=False) samples = np.ones(2) * voltage writer.write_many_sample(samples) task.start() if bTrig: task.wait_until_done() saveVariable(voltage, fileName, "Most Recent Output Voltage on " + channelAddr) return 0
def arbitraryoutDelayed(taskName, devNum, channelName, voltagelist, outputRate, outputTime, bTrig=0, trigChan="PFI0"): devNum = int(devNum) outputRate = int(outputRate) bTrig = int(bTrig) assert len(voltagelist) == int(outputRate * outputTime) try: daq = initDAQ(devNum) except IndexError: print("No NI DAQ device connected") raise SystemExit except Exception: print("Unknown Error") raise SystemExit with nidaqmx.Task() as task: channelAddr = "Dev%d/%s" % (devNum + 1, channelName) task.ao_channels.add_ao_voltage_chan(channelAddr) nsamples = int(outputRate * outputTime) task.timing.cfg_samp_clk_timing(rate=outputRate, sample_mode=AcquisitionType.FINITE, samps_per_chan=nsamples) if bTrig: task.triggers.start_trigger.cfg_dig_edge_start_trig( trigChan, Edge.RISING) writer = AnalogSingleChannelWriter(task.out_stream, auto_start=False) writer.write_many_sample(voltagelist) task.start() task.save(save_as=taskName, overwrite_existing_save=True)
def run(self): """ Starts writing a waveform continuously to the patchclamp. While reading the buffer periodically """ self.patchVoltOutChan = self.configs.patchVoltOutChannel self.patchCurOutChan = self.configs.patchCurOutChannel self.patchVoltInChan = self.configs.patchVoltInChannel #DAQ with nidaqmx.Task() as writeTask, nidaqmx.Task() as readTask: writeTask.ao_channels.add_ao_voltage_chan(self.patchVoltInChan) readTask.ai_channels.add_ai_voltage_chan(self.patchVoltOutChan) readTask.ai_channels.add_ai_voltage_chan(self.patchCurOutChan) self.setTiming(writeTask, readTask) reader = AnalogMultiChannelReader(readTask.in_stream) writer = AnalogSingleChannelWriter(writeTask.out_stream) writer.write_many_sample(self.wave) """Reading data from the buffer in a loop. The idea is to let the task read more than could be loaded in the buffer for each iteration. This way the task will have to wait slightly longer for incoming samples. And leaves the buffer entirely clean. This way we always know the correct numpy size and are always left with an empty buffer (and the buffer will not slowly fill up).""" output = np.zeros([2, self.readNumber]) writeTask.start( ) #Will wait for the readtask to start so it can use its clock readTask.start() while not self.isInterruptionRequested(): reader.read_many_sample( data=output, number_of_samples_per_channel=self.readNumber) #Emiting the data just received as a signal #output = np.around(output, 7) #Round all values self.measurement.emit(output[0, :], output[1, :])
def calibrate(sRate, aiChan, aoChan, xValues): writingRate = sRate readingRate = writingRate outputData = xValues inputData = np.zeros(outputData.size + 1) with nidaqmx.Task() as writeTask, nidaqmx.Task() as readTask: writeTask.ao_channels.add_ao_voltage_chan(aoChan) readTask.ai_channels.add_ai_voltage_chan(aiChan) #In the USB6001 DAQ there seems to be no SampleClock, therefore we cannot sync the signals without an external trigger/clock #sample_clock = '/Dev2/ai/SampleClock' writeTask.timing.cfg_samp_clk_timing( rate=writingRate, sample_mode=nidaqmx.constants.AcquisitionType.CONTINUOUS, samps_per_chan=outputData.size) readTask.timing.cfg_samp_clk_timing( rate=readingRate, sample_mode=nidaqmx.constants.AcquisitionType.FINITE, samps_per_chan=inputData.size) #writeTask.triggers.start_trigger.cfg_dig_edge_start_trig(trigger_source = '/Dev2/ai/StartTrigger') #Setting the trigger on the analog input #readTask.triggers.start_trigger.cfg_dig_edge_start_trig(trigger_source = '/Dev2/ao/StartTrigger') reader = AnalogSingleChannelReader(readTask.in_stream) writer = AnalogSingleChannelWriter(writeTask.out_stream) writer.write_many_sample(outputData) writeTask.start() reader.read_many_sample(inputData, timeout=outputData.size / readingRate + 4) #The ai/StartTrigger 'takes' one sample from writing so the actual writing starts one sample later, therefore the inputData starts one sample later inputData = inputData[1::] return outputData, inputData
def openall(aoi=0, aof=3, aii=0, aif=31, read=True, write=False, clock=False, sample_rate=500000, initial_delay=0, duty_cycle=0.5, samps_per_chan=1): ''' 4 output channels, 32 input channels duty cycle = pulse width / pulse period clock must involve read and write ''' ad = address() rs = ad.lookup(mdlname) # Instrument's Address print(type(rs)) read_task, write_task, clock_task, max_samp_rate, writer, reader = None, None, None, None, None, None if read: read_task = nidaqmx.Task() read_task.ai_channels.add_ai_voltage_chan("%s/ai%s:%s" %(rs,aii,aif), terminal_config=TerminalConfiguration.RSE, min_val=-10, max_val=10) if write: write_task = nidaqmx.Task() write_task.ao_channels.add_ao_voltage_chan("%s/ao%s:%s" %(rs,aoi,aof)) # write_task.ao_channels.add_ao_func_gen_chan if clock and write and read: # one-shot data streaming # Use a counter output pulse train task as the sample clock source for both the AI and AO tasks. max_samp_rate = read_task.timing.samp_clk_max_rate print("Max reading rate: %s" %max_samp_rate) sample_rate = floor(min(sample_rate, max_samp_rate)) clock_task = nidaqmx.Task() clock_task.co_channels.add_co_pulse_chan_freq('{0}/ctr0'.format(rs), freq=sample_rate, initial_delay=initial_delay, duty_cycle=duty_cycle) clock_task.timing.cfg_implicit_timing(sample_mode=AcquisitionType.FINITE, samps_per_chan=samps_per_chan) samp_clk_terminal = '/{0}/Ctr0InternalOutput'.format(rs) write_task.timing.cfg_samp_clk_timing(sample_rate, source=samp_clk_terminal, active_edge=Edge.RISING, samps_per_chan=samps_per_chan) read_task.timing.cfg_samp_clk_timing(sample_rate, source=samp_clk_terminal, active_edge=Edge.FALLING, samps_per_chan=samps_per_chan) # Single Channel: writer = AnalogSingleChannelWriter(write_task.out_stream) # reader = AnalogSingleChannelReader(read_task.in_stream) # Multi Channel: # writer = AnalogMultiChannelWriter(write_task.out_stream) reader = AnalogMultiChannelReader(read_task.in_stream) pack = dict(write_task=write_task, read_task=read_task, clock_task=clock_task, max_samp_rate=max_samp_rate, writer=writer, reader=reader) return pack
class ExpFlowSeparation(): def __init__(self, simlator_args): self.get_setting(simlator_args) def get_setting(self, arg): # analog input self.sample_rate = arg["sample_rate"] self.number_of_samples = arg["number_of_samples"] self.dynamic_pressre = arg["dynamic_pressure"] self.reward_indicator = arg["reward_indicator"] self.input_channel = arg["input_channels"] sens_coff = np.array( arg["sens_cofficients"]) / arg["unit_change"] * arg["gain"] self.sens_coff = sens_coff.reshape(sens_coff.shape[0], 1) self.num_i = len(self.sens_coff) self.nb_actions = arg["nb_actions"] # state channels for nueral network self.state_channel = arg["state_channels"] self.num_s = len(self.state_channel) self.loc_100 = arg["reward_channel"] # analog output self.output_channel = arg["output_channel"] # another parameters self.timeout = arg["timeout"] self.dt = 1 / self.sample_rate self.total_time = arg["total_time"] self.n_loop = int(self.sample_rate * self.total_time / self.number_of_samples) # plama actuator self.burst_wave = self.get_burst_wave(arg["plasma_actuator_csv"]) def get_burst_wave(self, filename): PA = np.zeros((self.nb_actions + 1, self.number_of_samples)) print(filename) with open(filename, "r") as f: reader = csv.reader(f) for i, row in enumerate(reader): PA[i, :] = row return PA * 5 def load_args(self, filename): with open(filename, "r") as f: args = json.load(f) return args def setup_DAQmx(self): self.read_task = nidaqmx.Task() self.write_task = nidaqmx.Task() self.sample_clk_task = nidaqmx.Task() # Use a counter output pulse train task as the sample clock source # for both the AI and AO tasks. self.sample_clk_task.co_channels.add_co_pulse_chan_freq( 'Dev1/ctr0', freq=self.sample_rate, idle_state=Level.LOW) self.sample_clk_task.timing.cfg_implicit_timing( sample_mode=AcquisitionType.CONTINUOUS, samps_per_chan=self.number_of_samples) self.sample_clk_task.control(TaskMode.TASK_COMMIT) samp_clk_terminal = '/Dev1/Ctr0InternalOutput' self.read_task.ai_channels.add_ai_voltage_chan(self.input_channel, max_val=10, min_val=-10) self.read_task.timing.cfg_samp_clk_timing( self.sample_rate, source=samp_clk_terminal, active_edge=Edge.FALLING, sample_mode=AcquisitionType.CONTINUOUS, samps_per_chan=self.number_of_samples) self.write_task.ao_channels.add_ao_voltage_chan(self.output_channel, max_val=10, min_val=-10) self.write_task.timing.cfg_samp_clk_timing( self.sample_rate, source=samp_clk_terminal, active_edge=Edge.FALLING, sample_mode=AcquisitionType.CONTINUOUS, samps_per_chan=self.number_of_samples) self.write_task.out_stream.regen_mode = RegenerationMode.DONT_ALLOW_REGENERATION self.write_task.out_stream.auto_start = False self.writer = AnalogSingleChannelWriter(self.write_task.out_stream) self.reader = AnalogMultiChannelReader(self.read_task.in_stream) def reset(self): self.env_memory = np.zeros((0, self.num_i)) self.buffer_memory = np.zeros((0, 4 + self.nb_actions)) self.step_count = 0 self.setup_DAQmx() # start read analog self._start_reading() self._start_writing() return self._reading() def step(self, action): self._writing(action) observation = self._reading() reward = np.average(observation[:, self.loc_100]) if action != self.nb_actions: self.step_count += 1 if self.step_count < self.n_loop: return observation, reward, False else: return observation, reward, True def _start_reading(self): # start read analog self.read_task.start() self.sample_clk_task.start() def _start_writing(self): self._writing(0) self.write_task.start() for _ in range(3): self._writing(0) def stop_DAQmx(self): self.read_task.close() self.write_task.close() self.sample_clk_task.close() def _reading(self): values_read = np.zeros((self.num_i, self.number_of_samples), dtype=np.float64) self.reader.read_many_sample( values_read, number_of_samples_per_channel=self.number_of_samples, timeout=2) return (((values_read / self.sens_coff) + self.dynamic_pressre) / self.dynamic_pressre).T def _writing(self, action): print(self.burst_wave[action].shape) print(self.burst_wave[action]) self.writer.write_many_sample(self.burst_wave[action])
class Simulator(): def __init__(self, args, Property): self.property = Property self.dynamic_pressre = 57 self.reward_indicator = -0.55 self.sample_rate, self.number_of_samples = self.property.rate() self.input_channel, self.sens_coff = self.property.i_channels() self.output_channel = self.property.output() self.state_channel, self.loc_100 = self.property.s_channels() self.total_time, self.n_loop = self.property.control() self.burst_wave_file_name = self.property.get_burst_wave_file() self.num_i = len(self.sens_coff) self.num_s = len(self.state_channel) self.frame_width = args.frame_width self.frame_height = args.frame_height self.state_length = args.state_length self.num_actions = args.n_actions # 10 moving averege self.num_mave = 10 self.b = np.ones(self.num_mave) / self.num_mave self.burst_wave = self.get_burst_wave() self.before_reward = 0 self.attachment_count = 0 def get_burst_wave(self): PA = np.zeros((self.num_actions, self.number_of_samples)) with open(self.burst_wave_file_name, 'r') as f: reader = csv.reader(f) for i, row in enumerate(reader): PA[i, :] = row return PA def setup_DAQmx(self): self.read_task = nidaqmx.Task() self.write_task = nidaqmx.Task() self.sample_clk_task = nidaqmx.Task() # Use a counter output pulse train task as the sample clock source # for both the AI and AO tasks. self.sample_clk_task.co_channels.add_co_pulse_chan_freq( 'Dev1/ctr0', freq=self.sample_rate, idle_state=Level.LOW) self.sample_clk_task.timing.cfg_implicit_timing( sample_mode=AcquisitionType.CONTINUOUS, samps_per_chan=self.number_of_samples) self.sample_clk_task.control(TaskMode.TASK_COMMIT) samp_clk_terminal = '/Dev1/Ctr0InternalOutput' self.read_task.ai_channels.add_ai_voltage_chan(self.input_channel, max_val=10, min_val=-10) self.read_task.timing.cfg_samp_clk_timing( self.sample_rate, source=samp_clk_terminal, active_edge=Edge.FALLING, sample_mode=AcquisitionType.CONTINUOUS, samps_per_chan=self.number_of_samples) self.write_task.ao_channels.add_ao_voltage_chan(self.output_channel, max_val=10, min_val=-10) self.write_task.timing.cfg_samp_clk_timing( self.sample_rate, source=samp_clk_terminal, active_edge=Edge.FALLING, sample_mode=AcquisitionType.CONTINUOUS, samps_per_chan=self.number_of_samples) self.write_task.out_stream.regen_mode = RegenerationMode.DONT_ALLOW_REGENERATION self.write_task.out_stream.auto_start = False self.writer = AnalogSingleChannelWriter(self.write_task.out_stream) self.reader = AnalogMultiChannelReader(self.read_task.in_stream) def start_reading(self): # start read analog self.read_task.start() time.sleep(0.1) self.sample_clk_task.start() def stop_DAQmx(self): self.read_task.close() self.write_task.close() self.sample_clk_task.close() def get_observation(self): values_read = np.zeros((self.num_i, self.number_of_samples), dtype=np.float64) self.reader.read_many_sample( values_read, number_of_samples_per_channel=self.number_of_samples, timeout=2) return (((values_read / self.sens_coff) + self.dynamic_pressre) / self.dynamic_pressre).T def get_initial_state(self): return np.zeros( (self.state_length * self.frame_height, self.frame_width)) def preprocess(self, observation): state_t = np.array([ np.convolve(observation[:, self.state_channel[i]], self.b, mode='same') for i in range(self.num_s) ]).T return np.round( (np.average(np.split(state_t, self.frame_height, 0), axis=1)), 2).reshape(self.frame_height, self.frame_width) def write_daqmx_zero(self): values_zero = np.zeros(self.number_of_samples) self.writer.write_many_sample(values_zero) def write_daqmx(self, action): self.writer.write_many_sample(self.burst_wave[action] * 5) def get_reward(self, reward_ori): reward = self.reward_indicator < reward_ori return reward.astype(np.int) def get_reward_with_punish(self, reward_ori, action): reward = self.reward_indicator < reward_ori if reward: return reward.astype(np.int) * 0.7 - (action - 1) * 0.3 else: return reward.astype(np.int) * 0.7 def get_reward_with_keep_attachment(self, reward_ori, action): reward = self.reward_indicator < reward_ori if (reward.astype(np.int) - self.before_reward) >= 0 and reward: self.attachment_count += 0.01 else: self.attachment_count = 0.0 if reward: return self.attachment_count - (action - 1) * 0.1 else: return self.attachment_count
class Simulator(): def __init__(self, statenum, num_actions, Actor, QN, memory, gamma, batch_num, sample_rate, number_of_samples, input_channel, state_channel, loc_100, sensor_coff, output_channel, nloops, PA, current_id): self.actor = Actor self.num_actions = num_actions self.QN = QN self.memory = memory self.gamma = gamma self.batch_num = batch_num self.sample_rate = sample_rate self.number_of_samples = number_of_samples self.input_channel = input_channel # input cahnnels self.state_channel = state_channel self.output_channel = output_channel self.number_of_channels = sensor_coff.shape[0] self.state_length = statenum self.state_width = len(state_channel) # number of input cahnnels self.CH100 = loc_100 self.nloops = nloops self.burst_wave = PA self.loss = 0 self.dynamic_pressre = 60 self.sensor_coff = sensor_coff self.intispn = 0.1 # input time span self.tilen = int(self.intispn / 0.01) self.state_height = int(self.state_length / self.tilen) self.id = current_id # 10 moving averege self.num_mave = 10 self.b = np.ones(self.num_mave) / self.num_mave # inital action of DNN self.init_model_action() self.total_reward = 0 self.total_q_max = 0 self.reward_indicator = -0.55 self.a_buffer = [0] * self.num_actions def init_model_action(self): # first call of keras needs 0.22s seq = np.zeros(self.state_length * self.state_width).reshape( -1, self.state_length, self.state_width) #seq = np.zeros(self.state_length*self.state_width).reshape(-1,self.state_length) # keras needs to drive in 0.001s for _ in range(5): start = time.time() self.actor.get_action(seq, self.QN, train=False) end = time.time() print(start - end) def save_csv_3Dto2D(self, filename, data3d): #get absolute path name = os.path.dirname(os.path.abspath(__name__)) #conbine absolute and relative path joined_path = os.path.join(name, '../data/', self.id, filename) # change to absolute path data_path = os.path.normpath(joined_path) data2d = np.zeros( (self.nloops * 3, self.state_length * self.state_width)) for i in range(len(data3d)): data2d[i] = data3d[i].T.reshape(self.state_length * self.state_width) df = pd.DataFrame(data2d) df.to_csv(data_path) def save_csv(self, filename, data): #get absolute path name = os.path.dirname(os.path.abspath(__name__)) #conbine absolute and relative path joined_path = os.path.join(name, '../data/', self.id, filename) # change to absolute path data_path = os.path.normpath(joined_path) df = pd.DataFrame(data) df.to_csv(data_path) def save(self, read, i): #save data to csv file localdata = "runs/state/s%d.csv" % (i) self.save_csv_3Dto2D( localdata, self.memory.episode_local[:, 0:self.state_length, :]) localdata = "runs/state_/s_%d.csv" % (i) self.save_csv_3Dto2D( localdata, self.memory.episode_local[:, self.state_length + 2:self.state_length * 2 + 2, :]) localdata = "runs/action/a%d.csv" % (i) self.save_csv(localdata, self.memory.episode_local[:, self.state_length, 0]) localdata = "runs/reward/r%d.csv" % (i) self.save_csv(localdata, self.memory.episode_local[:, self.state_length + 1, 0]) localdata = "runs/cpte/cp%d.csv" % (i) self.save_csv( localdata, self.memory.episode_local[:, self.state_length * 2 + 2, 0]) localdata = "runs/punish/p%d.csv" % (i) self.save_csv( localdata, self.memory.episode_local[:, self.state_length * 2 + 3, 0]) localdata = "runs/result/run%d.csv" % (i) self.save_csv(localdata, self.buffer_memory) readdata = "origin/data%d.csv" % (i) self.save_csv(readdata, read) def setup_DAQmx(self): self.read_task = nidaqmx.Task() self.write_task = nidaqmx.Task() self.sample_clk_task = nidaqmx.Task() # Use a counter output pulse train task as the sample clock source # for both the AI and AO tasks. self.sample_clk_task.co_channels.add_co_pulse_chan_freq( 'Dev1/ctr0', freq=self.sample_rate, idle_state=Level.LOW) self.sample_clk_task.timing.cfg_implicit_timing( sample_mode=AcquisitionType.CONTINUOUS, samps_per_chan=self.number_of_samples) self.sample_clk_task.control(TaskMode.TASK_COMMIT) samp_clk_terminal = '/Dev1/Ctr0InternalOutput' self.read_task.ai_channels.add_ai_voltage_chan(self.input_channel, max_val=10, min_val=-10) self.read_task.timing.cfg_samp_clk_timing( self.sample_rate, source=samp_clk_terminal, active_edge=Edge.FALLING, sample_mode=AcquisitionType.CONTINUOUS, samps_per_chan=self.number_of_samples) self.write_task.ao_channels.add_ao_voltage_chan(self.output_channel, max_val=10, min_val=-10) self.write_task.timing.cfg_samp_clk_timing( self.sample_rate, source=samp_clk_terminal, active_edge=Edge.FALLING, sample_mode=AcquisitionType.CONTINUOUS, samps_per_chan=self.number_of_samples) self.write_task.out_stream.regen_mode = RegenerationMode.DONT_ALLOW_REGENERATION self.write_task.out_stream.auto_start = True self.writer = AnalogSingleChannelWriter(self.write_task.out_stream) self.reader = AnalogMultiChannelReader(self.read_task.in_stream) def start_reading(self): # start read analog self.read_task.start() time.sleep(0.1) self.sample_clk_task.start() def read_daqmx(self): values_read = np.zeros( (self.number_of_channels, self.number_of_samples), dtype=np.float64) self.reader.read_many_sample( values_read, number_of_samples_per_channel=self.number_of_samples, timeout=2) return (((values_read.T / self.sensor_coff) + self.dynamic_pressre) / self.dynamic_pressre) def write_daqmx_zero(self): values_zero = np.zeros(self.number_of_samples) self.writer.write_many_sample(values_zero) def write_daqmx(self, action): self.writer.write_many_sample(self.burst_wave[action] * 5) def stop_DAQmx(self): self.read_task.close() self.write_task.close() self.sample_clk_task.close() def preprocess(self, observation): # moving average filter state_t = np.zeros((self.number_of_samples, self.state_width)) for ich in range(self.state_width): state_t[:, ich] = np.convolve(observation[:, self.state_channel[ich]], self.b, mode='same') processed_observation = np.round( (np.average(np.split(state_t, self.state_height, 0), axis=1)), 2) return processed_observation.reshape(self.state_height, self.state_width) def get_initial_state(self): return np.zeros((self.state_length, self.state_width)) def get_reward(self, reward_ori): reward = self.reward_indicator < reward_ori return reward.astype(np.int) def run(self, Nepisode, targetQN, train=True): self.setup_DAQmx() # Parameters for plotting # initiate read = np.zeros((0, self.number_of_channels)) state = self.get_initial_state() self.buffer_memory = np.zeros((0, 4 + self.num_actions)) self.total_q_max = 0 # start read analog self.start_reading() # first loop # you read # you do not act # this loop is for caliburation of reward # you need to satrt writeanalog in first loop # 'cause the function takes time to start self.write_daqmx_zero() self.write_task.start() self.write_daqmx_zero() self.write_daqmx_zero() for n in range(int(self.nloops)): # adopt output timing and action zero self.write_daqmx_zero() observation = self.read_daqmx() processed_observation = self.preprocess(observation) next_state = np.append(state[self.state_height:, :], processed_observation, axis=0) # reward cpte = np.average(observation[:, self.CH100]) reward = self.get_reward(cpte) read = np.append(read, observation, axis=0) memory = [0, cpte, 0, 0] memory.extend(self.a_buffer) self.memory.add_local(state, 0, next_state, cpte, 0, 0) self.buffer_memory = np.append(self.buffer_memory, [memory], axis=0) state = next_state # calibulatkoe self.memory.calc_calibulation() # second loop # you read # you act for n in range(self.nloops): # action action, q, q_max = self.actor.get_action( state.reshape(-1, self.state_length, self.state_width), self.QN, train) #action, q, q_max = self.actor.get_action(state.reshape(-1,self.state_length), self.QN,train) # adopt output timing and action zero self.write_daqmx(action) observation = self.read_daqmx() processed_observation = self.preprocess(observation) next_state = np.append(state[self.state_height:, :], processed_observation, axis=0) # reward cpte = np.average(observation[:, self.CH100]) reward = self.get_reward(cpte) read = np.append(read, observation, axis=0) memory = [action, cpte, reward, np.argmax(q)] memory.extend(q) self.memory.add_local(state, action, next_state, cpte, reward, 0) self.buffer_memory = np.append(self.buffer_memory, [memory], axis=0) self.total_q_max += q_max state = next_state # third loop # you read # you do not act # make sure PA turn off for n in range(int(self.nloops)): # adopt output timing and action zero self.write_daqmx_zero() self.write_daqmx_zero() observation = self.read_daqmx() processed_observation = self.preprocess(observation) next_state = np.append(state[self.state_height:, :], processed_observation, axis=0) # reward cpte = np.average(observation[:, self.CH100]) reward = self.get_reward(cpte) read = np.append(read, observation, axis=0) memory = [0, cpte, reward, 0] memory.extend(self.a_buffer) self.memory.add_local(state, 0, next_state, cpte, 0, 0) self.buffer_memory = np.append(self.buffer_memory, [memory], axis=0) state = next_state # stop DAQmx self.stop_DAQmx() # edit experience in buffer self.memory.edit_experience_local() self.save(read, Nepisode) self.total_reward = self.memory.totalreward() # move current experience to global buffer self.memory.add_global(self.total_reward) if (self.memory.len() > self.batch_num) and train: self.loss = self.QN.replay(self.memory, self.batch_num, self.gamma, targetQN) self.actor.reduce_epsilon() return self.total_reward, self.loss, self.total_q_max / self.nloops
import numpy as np import nidaqmx from nidaqmx.constants import * from nidaqmx.stream_writers import AnalogSingleChannelWriter ttime = 10 # Total time (s) sigRate = 1 # Frequency (Hz) nsamples = 100 # Number of samples per cycle writingRate = nsamples * sigRate # Signal generation frequency Ax = 10 # Amplitude (V) nv = int(ttime * sigRate) output = np.tile(np.linspace(-Ax, Ax, int(nsamples)), nv) with nidaqmx.Task() as writeTask: writeTask.ao_channels.add_ao_voltage_chan("Dev1/ao0") writeTask.timing.cfg_samp_clk_timing( rate=writingRate, sample_mode=nidaqmx.constants.AcquisitionType.FINITE, samps_per_chan=int(nsamples * nv)) writer = AnalogSingleChannelWriter(writeTask.out_stream) writer.write_many_sample(output, timeout=ttime + 5) writeTask.start() print("Start writing") writeTask.wait_until_done(timeout=ttime + 5) print("Done with data")
class ExpFlowSeparation(): def __init__(self, simlator_args): self.get_setting(simlator_args) def get_setting(self, arg): # analog input self.sample_rate = arg["sample_rate"] self.number_of_samples = arg["number_of_samples"] self.dynamic_pressre = arg["dynamic_pressure"] self.reward_indicator = arg["reward_indicator"] self.input_channel = arg["input_channels"] sens_coff = np.array(arg["sens_cofficients"])/arg["unit_change"]*arg["gain"] self.sens_coff = sens_coff.reshape(sens_coff.shape[0],1) self.num_i = len(self.sens_coff) # state channels for nueral network self.state_channel = arg["state_channels"] self.num_s = len(self.state_channel) self.loc_100 = arg["reward_channel"] # analog output self.output_channel = arg["output_channel"] # another parameters self.timeout = arg["timeout"] self.dt = 1/self.sample_rate*self.number_of_samples self.total_time = arg["total_time"] self.n_loop = int(self.sample_rate*self.total_time/self.number_of_samples) # plama actuator self.burst_wave = self.get_burst_wave(arg) self.nb_actions = self.burst_wave.shape[0] - 1 def get_burst_wave(self,arg): if arg["mode"]=="gate": wave = self.get_gate_wave(arg["gate_mode"]["plasma_actuator_csv"]) elif arg["mode"]=="sin": wave = self.create_burst_wave(**arg["sin_mode"]) print("MODE: " + arg["mode"]) zero_wave = np.zeros((1,self.number_of_samples)) wave = np.append(zero_wave,wave,axis=0) return wave def get_gate_wave(self, filename): df_wave = pd.read_csv(filename, header=None).values np_wave = np.array([ i_wave for i_wave in df_wave ]) return np_wave def create_burst_wave(self,base_frequency, burst_frequency, burst_ratio, voltage): ### example -> burst_freq=600[Hz], burst_ratio=0.1[-], voltage=3[kV] time = np.linspace(0.0, self.dt, self.number_of_samples) tmp_sin = np.sin(2*np.pi*int(base_frequency)*time) tmp_sq = [(signal.square(2 * np.pi * bf_i * time, duty=br_i)+1)/2 for br_i in burst_ratio for bf_i in burst_frequency] wave = [(tmp_sin * tmp_sq_i) * vi for tmp_sq_i in tmp_sq for vi in voltage] zero_wave = np.zeros((1,self.number_of_samples)) wave = np.append(wave,zero_wave,axis=0)# plus off at last array return wave def load_args(self, filename): with open(filename,"r") as f: args = json.load(f) return args def setup_DAQmx(self): self.read_task = nidaqmx.Task() self.write_task = nidaqmx.Task() self.sample_clk_task = nidaqmx.Task() # Use a counter output pulse train task as the sample clock source # for both the AI and AO tasks. self.sample_clk_task.co_channels.add_co_pulse_chan_freq('Dev1/ctr0', freq=self.sample_rate, idle_state=Level.LOW) self.sample_clk_task.timing.cfg_implicit_timing(sample_mode=AcquisitionType.CONTINUOUS,samps_per_chan=self.number_of_samples) self.sample_clk_task.control(TaskMode.TASK_COMMIT) samp_clk_terminal = '/Dev1/Ctr0InternalOutput' self.read_task.ai_channels.add_ai_voltage_chan(self.input_channel, max_val=10, min_val=-10) self.read_task.timing.cfg_samp_clk_timing(self.sample_rate, source=samp_clk_terminal, active_edge=Edge.FALLING,sample_mode=AcquisitionType.CONTINUOUS, samps_per_chan=self.number_of_samples) self.write_task.ao_channels.add_ao_voltage_chan(self.output_channel, max_val=10, min_val=-10) self.write_task.timing.cfg_samp_clk_timing(self.sample_rate, source=samp_clk_terminal, active_edge=Edge.FALLING,sample_mode=AcquisitionType.CONTINUOUS, samps_per_chan=self.number_of_samples) self.write_task.out_stream.regen_mode = RegenerationMode.DONT_ALLOW_REGENERATION self.write_task.out_stream.auto_start = False self.writer = AnalogSingleChannelWriter(self.write_task.out_stream) self.reader = AnalogMultiChannelReader(self.read_task.in_stream) def reset(self): self.env_memory = np.zeros((0,self.num_i)) self.buffer_memory = np.zeros((0,4+self.nb_actions)) self.step_count = 0 self.setup_DAQmx() # start read analog self._start_reading() self._start_writing() return self._reading() def step(self, action): self._writing(action) observation = self._reading() reward = np.average(observation[:,self.loc_100]) if action != self.nb_actions : self.step_count += 1 if self.step_count < self.n_loop: return observation, reward, False else: return observation, reward, True def _start_reading(self): # start read analog self.read_task.start() self.sample_clk_task.start() def _start_writing(self): self._writing(0) self.write_task.start() for _ in range(3): self._writing(0) def stop_DAQmx(self): self.read_task.close() self.write_task.close() self.sample_clk_task.close() def _reading(self): values_read = np.zeros((self.num_i,self.number_of_samples), dtype=np.float64) self.reader.read_many_sample(values_read, number_of_samples_per_channel=self.number_of_samples,timeout=2) return (((values_read / self.sens_coff) + self.dynamic_pressre ) / self.dynamic_pressre).T def _writing(self,action): self.writer.write_many_sample(self.burst_wave[action])