Beispiel #1
0
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)
Beispiel #2
0
    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_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)
Beispiel #4
0
    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')
Beispiel #5
0
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
Beispiel #6
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)
Beispiel #7
0
    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, :])
Beispiel #8
0
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
Beispiel #9
0
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])
Beispiel #10
0
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
Beispiel #11
0
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
Beispiel #12
0
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")
Beispiel #13
0
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])