Example #1
0
    def experiment_get_template(self, experiment_id=None):
        """Retrieve the template for an experiment.

        Can be used to duplicate the experiment on another machine.
        """

        util.check_par('experiment id', experiment_id, _type=int, _min=0)

        exp = self._rest_session.get(self._rest_prefix + '/experiments/%d'%experiment_id)

        try:
            exp = exp.json()
            exp['experiment']['id']
        except:
            raise Exception('Failed to get template for experiment id %d'%experiment_id)

       
        # build the template protocol
        ret_proto = {}
        ret_proto['lid_temperature'] = exp['experiment']['protocol']['lid_temperature']
        for stage in exp['experiment']['protocol']['stages']:
            stage['stage'].pop('id')
            for step in stage['stage']['steps']:
                step['step'].pop('id')
        ret_proto['stages'] = exp['experiment']['protocol']['stages']

        ret = {'experiment':{'name':exp['experiment']['name'], 'protocol':ret_proto}}

        return ret
Example #2
0
    def experiment_delete(self, experiment_id=None):

        util.check_par('experiment id', experiment_id, _type=int, _min=0)

        ret = self._rest_session.delete(self._rest_prefix + '/experiments/%d'%experiment_id)

        if 'experiment' in ret.json() and not ret.json()['experiment']:
            return True
        else:
            raise Exception('Failed to delete experiment id %d'%experiment_id)
Example #3
0
    def experiment_info(self, experiment_id=None):
        """Get status of an experiment."""

        util.check_par('experiment id', experiment_id, _type=int, _min=0)

        ret = self._rest_session.get(self._rest_prefix + '/experiments/%d'%experiment_id)
        try:
            return ret.json()
        except:
            raise Exception('Failed to get experiment id %d'%experiment_id)
Example #4
0
    def experiment_info(self, experiment_id=None):
        """Get status of an experiment."""

        util.check_par('experiment id', experiment_id, _type=int, _min=0)

        ret = self._rest_session.get(self._rest_prefix +
                                     '/experiments/%d' % experiment_id)
        try:
            return ret.json()
        except:
            raise Exception('Failed to get experiment id %d' % experiment_id)
Example #5
0
    def set_heat_block_temp(self, temp, tol=0.5):
        
        util.check_par('temperature', temp, _type=float, _min=0, _max=100)
        util.check_par('tolerance', tol, _type=float, _min=0, _max=5)

        self.test_control('heat_block_target_temp','%d'%temp)

        while True:
            time.sleep(1)
            if abs(temp - float(self.status()['heat_block']['temperature'])) <= tol:
                break
Example #6
0
    def set_heat_block_temp(self, temp, tol=0.5):

        util.check_par('temperature', temp, _type=float, _min=0, _max=100)
        util.check_par('tolerance', tol, _type=float, _min=0, _max=5)

        self.test_control('heat_block_target_temp', '%d' % temp)

        while True:
            time.sleep(1)
            if abs(temp -
                   float(self.status()['heat_block']['temperature'])) <= tol:
                break
Example #7
0
    def experiment_delete(self, experiment_id=None):

        util.check_par('experiment id', experiment_id, _type=int, _min=0)

        ret = self._rest_session.delete(self._rest_prefix +
                                        '/experiments/%d' % experiment_id)

        if 'experiment' in ret.json() and not ret.json()['experiment']:
            return True
        else:
            raise Exception('Failed to delete experiment id %d' %
                            experiment_id)
Example #8
0
    def experiment_start(self, experiment_id=None):
        
        util.check_par('experiment id', experiment_id, _type=int, _min=0)

        ret = self._rest_session.post(self._rest_prefix + ':8000/control/start', data='{"experiment_id":"%d"}'%experiment_id)
        status = True
        try:
            if ret.json()['status']['status'] == 'true':
                return True
            else:
                raise Exception('Failed to start experiment %d. (%s)'%(experiment_id, ret.json()['status']['error']))
        except KeyError:
            raise Exception('Invalid reply from instrument')
Example #9
0
    def experiment_start(self, experiment_id=None):

        util.check_par('experiment id', experiment_id, _type=int, _min=0)

        ret = self._rest_session.post(
            self._rest_prefix + ':8000/control/start',
            data='{"experiment_id":"%d"}' % experiment_id)
        status = True
        try:
            if ret.json()['status']['status'] == 'true':
                return True
            else:
                raise Exception('Failed to start experiment %d. (%s)' %
                                (experiment_id, ret.json()['status']['error']))
        except KeyError:
            raise Exception('Invalid reply from instrument')
Example #10
0
    def data_logger_start(self, cnt_pre, cnt_post):
        """Setup and start the data logger"""

        util.check_par('pre-trigger sample count', cnt_pre, int, _min = 0)
        util.check_par('post-trigger sample count', cnt_post, int, _min = 0)

        ret = self._rest_session.post(
                self._rest_prefix + ':8000/test/data_logger/start', 
                headers={'Content-Type':'application/json'}, 
                data=json.dumps({'pre_samples':'%d'%cnt_pre, 'post_samples':'%d'%cnt_post,})
                )

        try:
            if ret.json()['status']['status'] == 'true':
                return True
            else:
                raise Exception('Failed to start data logger (%s)'%ret.json()['status']['error'])
        except KeyError:
            raise Exception('Invalid reply from instrument')
Example #11
0
    def data_logger_trigger(self, timeout_s=None):
        """Wait for logger data and retrieve it"""

        if timeout_s != None:
            util.check_par('timeout (seconds)', timeout_s, int, _min=1)

        remote_output_file = '/tmp/data_logger.csv'
        local_output_file = 'data.csv.%s' % self._config['host']
        self.ssh_command('rm -f ' + remote_output_file)

        ret = self._rest_session.post(
            self._rest_prefix + ':8000/test/data_logger/trigger',
            headers={'Content-Type': 'application/json'})
        try:
            if ret.json()['status']['status'] != 'true':
                raise Exception('Failed to trigger data logger (%s)' %
                                ret.json()['status']['error'])
        except KeyError:
            raise Exception('Invalid reply from instrument')

        ret = []

        while True:
            if timeout_s != None:
                if timeout_s < 0:
                    return False
                else:
                    timeout_s -= 10

            time.sleep(10)
            ret = self.ssh_command('stat ' + remote_output_file)
            if ret[0] == 0:
                # file exists
                time.sleep(1)
                break

        self.sftp_get(remote_output_file, local_output_file)

        ret = pd.read_csv(local_output_file, header=0)
        ret = ret.set_index(['time_offset'])

        return ret
Example #12
0
    def data_logger_trigger(self, timeout_s=None):
        """Wait for logger data and retrieve it"""

        if timeout_s != None:
            util.check_par('timeout (seconds)', timeout_s, int, _min=1)

        remote_output_file = '/tmp/data_logger.csv'
        local_output_file = 'data.csv.%s'%self._config['host']
        self.ssh_command('rm -f ' + remote_output_file)

        ret = self._rest_session.post(
                self._rest_prefix + ':8000/test/data_logger/trigger', 
                headers={'Content-Type':'application/json'} 
                )
        try:
            if ret.json()['status']['status'] != 'true':
                raise Exception('Failed to trigger data logger (%s)'%ret.json()['status']['error'])
        except KeyError:
            raise Exception('Invalid reply from instrument')

        ret = []

        while True:
            if timeout_s != None:
                if timeout_s < 0:
                    return False
                else:
                    timeout_s -= 10

            time.sleep(10)
            ret = self.ssh_command('stat ' + remote_output_file)
            if ret[0] == 0:
                # file exists
                time.sleep(1)
                break

        self.sftp_get(remote_output_file, local_output_file)

        ret = pd.read_csv(local_output_file, header=0)
        ret = ret.set_index(['time_offset'])

        return ret
Example #13
0
    def experiment_copy(self, experiment_id=None, name=None):
        """Copy an existing experiment.

        Returns the id of the new experiment.
        """
        util.check_par('experiment id', experiment_id, _type=int, _min=0)

        ret = self._rest_session.post(self._rest_prefix + '/experiments/%d/copy'%experiment_id)
        new_experiment_id = -1
        try:
            new_experiment_id = int(ret.json()['experiment']['id'])
        except:
            raise Exception('Failed to copy experiment id %d'%experiment_id)

        if name:
            ret = self._rest_session.put(
                    self._rest_prefix + '/experiments/%d'%new_experiment_id,
                    headers={'Content-Type':'application/json'}, 
                    data=json.dumps({'experiment':{'name':name}})
                    )

        return new_experiment_id
Example #14
0
    def data_logger_start(self, cnt_pre, cnt_post):
        """Setup and start the data logger"""

        util.check_par('pre-trigger sample count', cnt_pre, int, _min=0)
        util.check_par('post-trigger sample count', cnt_post, int, _min=0)

        ret = self._rest_session.post(
            self._rest_prefix + ':8000/test/data_logger/start',
            headers={'Content-Type': 'application/json'},
            data=json.dumps({
                'pre_samples': '%d' % cnt_pre,
                'post_samples': '%d' % cnt_post,
            }))

        try:
            if ret.json()['status']['status'] == 'true':
                return True
            else:
                raise Exception('Failed to start data logger (%s)' %
                                ret.json()['status']['error'])
        except KeyError:
            raise Exception('Invalid reply from instrument')
Example #15
0
    def experiment_copy(self, experiment_id=None, name=None):
        """Copy an existing experiment.

        Returns the id of the new experiment.
        """
        util.check_par('experiment id', experiment_id, _type=int, _min=0)

        ret = self._rest_session.post(self._rest_prefix +
                                      '/experiments/%d/copy' % experiment_id)
        new_experiment_id = -1
        try:
            new_experiment_id = int(ret.json()['experiment']['id'])
        except:
            raise Exception('Failed to copy experiment id %d' % experiment_id)

        if name:
            ret = self._rest_session.put(
                self._rest_prefix + '/experiments/%d' % new_experiment_id,
                headers={'Content-Type': 'application/json'},
                data=json.dumps({'experiment': {
                    'name': name
                }}))

        return new_experiment_id
Example #16
0
    def experiment_get_template(self, experiment_id=None):
        """Retrieve the template for an experiment.

        Can be used to duplicate the experiment on another machine.
        """

        util.check_par('experiment id', experiment_id, _type=int, _min=0)

        exp = self._rest_session.get(self._rest_prefix +
                                     '/experiments/%d' % experiment_id)

        try:
            exp = exp.json()
            exp['experiment']['id']
        except:
            raise Exception('Failed to get template for experiment id %d' %
                            experiment_id)

        # build the template protocol
        ret_proto = {}
        ret_proto['lid_temperature'] = exp['experiment']['protocol'][
            'lid_temperature']
        for stage in exp['experiment']['protocol']['stages']:
            stage['stage'].pop('id')
            for step in stage['stage']['steps']:
                step['step'].pop('id')
        ret_proto['stages'] = exp['experiment']['protocol']['stages']

        ret = {
            'experiment': {
                'name': exp['experiment']['name'],
                'protocol': ret_proto
            }
        }

        return ret
Example #17
0
    def read_well(self, well, cnt, mode='status', source_on=True):
        """Get optical readings from the status page or from the csv dump"""

        util.check_par('well', well, int, 0, 15)
        util.check_par('sample count', cnt, int, 0)
        util.check_par('mode', mode, str, _list=['status', 'dump'])
        util.check_par('source on', source_on, bool, _list=[True, False])

        self.test_control("photodiode_mux_channel", '%d' % well)

        if source_on:
            self.test_control("activate_led", '%d' % well)
        else:
            self.test_control("disable_leds", '')

        time.sleep(0.5)

        ret = []
        if mode == 'status':
            for i in range(cnt):
                ret.append([
                    int(i) for i in self.status()['optics']['photodiode_value']
                ])

            ret = pd.DataFrame(ret)
            ret.columns = [
                'optics_%d' % (i + 1) for i in range(ret.columns.size)
            ]

            self.test_control("disable_leds", '')

        elif mode == 'dump':
            self.data_logger_start(10, cnt - 10)
            ret = self.data_logger_trigger()

            self.test_control("disable_leds", '')

            ret = ret[[c for c in list(ret.columns) if c.startswith('optics')]]
        else:
            raise Exception('Unknown mode: %s' % mode)

        return ret
Example #18
0
    def read_well(self, well, cnt, mode='status', source_on=True):
        """Get optical readings from the status page or from the csv dump"""

        
        util.check_par('well', well, int, 0, 15)
        util.check_par('sample count', cnt, int, 0)
        util.check_par('mode', mode, str, _list=['status', 'dump'])
        util.check_par('source on', source_on, bool, _list=[True, False])

        self.test_control("photodiode_mux_channel",'%d'%well)

        if source_on:
            self.test_control("activate_led",'%d'%well)
        else:
            self.test_control("disable_leds",'')

        time.sleep(0.5)

        ret = []
        if mode == 'status':
            for i in range(cnt):
                ret.append([int(i) for i in self.status()['optics']['photodiode_value']])
            
            ret = pd.DataFrame(ret)
            ret.columns = ['optics_%d'%(i+1) for i in range(ret.columns.size)]

            self.test_control("disable_leds",'')

        elif mode == 'dump':
            self.data_logger_start(10, cnt-10)
            ret = self.data_logger_trigger()

            self.test_control("disable_leds",'')

            ret = ret[[c for c in list(ret.columns) if c.startswith('optics')]]
        else:
            raise Exception('Unknown mode: %s'%mode)

        return ret
Example #19
0
    def __init__(self,
                 wells=range(16),
                 temperatures_C=[10, 60, 80],
                 loops=300,
                 settle_s=300,
                 leds_on=True,
                 lid_temp_C=None):

        self.wells = wells
        self.temperatures_C = temperatures_C
        self.loops = loops
        self.settle_s = settle_s
        self.leds_on = leds_on
        self.lid_temp_C = lid_temp_C

        super(ChaiNoiseTest, self).__init__()

        [
            util.check_par('well', well, _type=int, _min=0, _max=15)
            for well in self.wells
        ]
        [
            util.check_par('temperature (degC)',
                           temp,
                           _type=int,
                           _min=0,
                           _max=90) for temp in [
                               temp_number
                               for temp_number in self.temperatures_C
                               if temp_number != None
                           ]
        ]
        util.check_par('loops', self.loops, _type=int, _min=0)
        util.check_par('settle time (s)',
                       self.settle_s,
                       _type=int,
                       _min=0,
                       _max=3600)

        self.logger_data = {}
        self.parsed_data = None
        self.results = None
        self.meas_values = {
            'avg_p2p': [None, None, 300, 500],
            'avg_diff': [None, None, 100, 200],
            'step_p2p': [None, None, 300, 500]
        }
        self.step_data_slice = slice(9, 16)
Example #20
0
    def sql_get_data(self, table, experiment_id, channel=None, well=None):
        """Get data for a specific experiment."""

        util.check_par('experiment id', experiment_id, _type=int, _min=0)

        channel_string = ''
        if channel is not None:
            util.check_par('channel', channel, _type=int, _min=1, _max=2)
            channel_string = 'and channel = %d'%(int(channel))

        well_string = ''
        if well is not None:
            util.check_par('well number', well, _type=int, _min=0, _max=15)
            well_string = 'and well_num = %d'%(int(well))

        data = self.sql_command(
                "select * from %s where experiment_id = %d %s %s"%(table, experiment_id, channel_string, well_string)
               )
        return data
Example #21
0
    def sql_get_data(self, table, experiment_id, channel=None, well=None):
        """Get data for a specific experiment."""

        util.check_par('experiment id', experiment_id, _type=int, _min=0)

        channel_string = ''
        if channel is not None:
            util.check_par('channel', channel, _type=int, _min=1, _max=2)
            channel_string = 'and channel = %d' % (int(channel))

        well_string = ''
        if well is not None:
            util.check_par('well number', well, _type=int, _min=0, _max=15)
            well_string = 'and well_num = %d' % (int(well))

        data = self.sql_command(
            "select * from %s where experiment_id = %d %s %s" %
            (table, experiment_id, channel_string, well_string))
        return data
Example #22
0
    def __init__(
            self,
            wells = range(16),
            temperatures_C = [10, 60, 80],
            loops = 300,
            settle_s = 300,
            leds_on = True,
            lid_temp_C = None
            ):

        self.wells = wells
        self.temperatures_C = temperatures_C
        self.loops = loops
        self.settle_s = settle_s
        self.leds_on = leds_on
        self.lid_temp_C = lid_temp_C
        

        super(ChaiNoiseTest, self).__init__()
        
        [util.check_par('well', well, _type=int, _min=0, _max=15) for well in self.wells] 
        [util.check_par('temperature (degC)', temp, _type=int, _min=0, _max=90) for temp in 
                [temp_number for temp_number in self.temperatures_C if temp_number != None]
                ] 
        util.check_par('loops', self.loops, _type=int, _min=0) 
        util.check_par('settle time (s)', self.settle_s, _type=int, _min=0, _max=3600) 

        self.logger_data = {}
        self.parsed_data = None
        self.results = None
        self.meas_values = {
                'avg_p2p' : [None, None, 300, 500], 
                'avg_diff': [None, None, 100, 200],
                'step_p2p': [None, None, 300, 500]
                }
        self.step_data_slice = slice(9,16)
Example #23
0
    def experiment_loop(self,
                        experiment_id=None,
                        loop_cnt=100,
                        data_log=False,
                        data_log_duration_s=None,
                        poll_seconds=60,
                        gap_minutes=1,
                        stop_on_error=True,
                        delete_loop_experiments=False):
        """Run the same experiment in a loop.

        Copies of the experiments are created, run and optionally deleted.
        """

        if self.state() != 'idle':
            raise Exception('Device is running an experiment')

        util.check_par('experiment id', experiment_id, _type=int, _min=0)
        util.check_par('loop count', loop_cnt, _type=int, _min=1, _max=1000)
        util.check_par('poll seconds',
                       poll_seconds,
                       _type=int,
                       _min=1,
                       _max=3600)
        util.check_par('gap minutes',
                       gap_minutes,
                       _type=int,
                       _min=0,
                       _max=1440)

        exp_info = self.experiment_info(experiment_id)
        if data_log:
            if data_log_duration_s != None:
                util.check_par('data log duration (seconds)',
                               data_log_duration_s,
                               _type=int,
                               _min=1)
            else:
                if exp_info['experiment']['completion_status'] != 'success':
                    raise Exception(
                        "Template experiment did not complete successfully. Please specify the data_log_duration_s parameter"
                    )
                try:
                    start_time = datetime.strptime(
                        exp_info['experiment']['started_at'],
                        '%Y-%m-%dT%H:%M:%S.000Z')
                    end_time = datetime.strptime(
                        exp_info['experiment']['completed_at'],
                        '%Y-%m-%dT%H:%M:%S.000Z')
                except:
                    raise Exception("Failed to detect experiment duration.")

                duration = end_time - start_time
                if duration.days != 0:
                    raise Exception(
                        "Detected invalid experiment duration (days): %d" %
                        duration.days)
                if duration.seconds < 0 or duration.seconds > 12 * 3600:
                    raise Exception(
                        "Detected invalid experiment duration (seconds): %d" %
                        duration.seconds)
                data_log_duration_s = duration.seconds + 60

        data = {}

        for loop in range(1, loop_cnt + 1):

            new_id = self.experiment_copy(experiment_id,
                                          name=exp_info['experiment']['name'] +
                                          '_loop_%d' % loop)
            print("Starting loop %d with experiment id %d" % (loop, new_id))

            if data_log:
                self.data_logger_start(
                    int(1.2 * data_log_duration_s) *
                    self.data_logger_samplerate, 10)

            self.experiment_start(new_id)
            time.sleep(10)
            if self.state() == 'idle':
                raise Exception(
                    'Failed to start loop %d for experiment id %d' %
                    (loop, new_id))

            while True:
                time.sleep(poll_seconds)
                if self.state() == 'idle':
                    break

            if data_log:
                data[new_id] = self.data_logger_trigger(timeout_s=60)
                self.data_logger_stop()
                pickle.dump(data, open('data_%s' % self._config['host'], 'wb'))

            if stop_on_error and self.experiment_info(
                    new_id)['experiment']['completion_status'] != 'success':
                raise Exception('Loop %d for experiment id %d failed' %
                                (loop, new_id))

            time.sleep(gap_minutes * 60)

            if delete_loop_experiments:
                try:
                    self.experiment_delete(new_id)
                except:
                    print('Failed to delete experiment id %d' % new_id)

            time.sleep(10)

            # renew connection authorization
            self.connect_rest()

        print("Finished %d loops for experiment id %d" % (loop, experiment_id))

        return data
Example #24
0
    def experiment_loop(
                   self, 
                   experiment_id=None, 
                   loop_cnt=100, 
                   data_log=False, data_log_duration_s=None, 
                   poll_seconds=60, gap_minutes=1, 
                   stop_on_error=True, 
                   delete_loop_experiments=False
                   ):
        """Run the same experiment in a loop.

        Copies of the experiments are created, run and optionally deleted.
        """

        if self.state() != 'idle':
            raise Exception('Device is running an experiment')

        util.check_par('experiment id', experiment_id, _type=int, _min=0)
        util.check_par('loop count', loop_cnt, _type=int, _min=1, _max=1000)
        util.check_par('poll seconds', poll_seconds, _type=int, _min=1, _max=3600)
        util.check_par('gap minutes', gap_minutes, _type=int, _min=0, _max=1440)

        exp_info = self.experiment_info(experiment_id)
        if data_log:
            if data_log_duration_s != None:
                util.check_par('data log duration (seconds)', data_log_duration_s, _type=int, _min=1)
            else:
                if exp_info['experiment']['completion_status'] != 'success':
                    raise Exception("Template experiment did not complete successfully. Please specify the data_log_duration_s parameter")
                try:
                    start_time = datetime.strptime(exp_info['experiment']['started_at'], '%Y-%m-%dT%H:%M:%S.000Z')
                    end_time = datetime.strptime(exp_info['experiment']['completed_at'], '%Y-%m-%dT%H:%M:%S.000Z')
                except:
                    raise Exception("Failed to detect experiment duration.")

                duration = end_time - start_time
                if duration.days != 0:
                    raise Exception("Detected invalid experiment duration (days): %d"%duration.days)
                if duration.seconds < 0 or duration.seconds > 12*3600:
                    raise Exception("Detected invalid experiment duration (seconds): %d"%duration.seconds)
                data_log_duration_s = duration.seconds + 60

        data={}

        for loop in range(1, loop_cnt+1):

            new_id = self.experiment_copy(experiment_id, name = exp_info['experiment']['name'] + '_loop_%d'%loop)
            print("Starting loop %d with experiment id %d"%(loop, new_id))

            if data_log:
                self.data_logger_start(int(1.2 * data_log_duration_s) * self.data_logger_samplerate, 10)

            self.experiment_start(new_id)
            time.sleep(10)
            if self.state() == 'idle':
                raise Exception('Failed to start loop %d for experiment id %d'%(loop, new_id))

            while True:
                time.sleep(poll_seconds)
                if self.state() == 'idle':
                    break;

            if data_log:
                data[new_id] = self.data_logger_trigger(timeout_s = 60)
                self.data_logger_stop()
                pickle.dump(data, open('data_%s'%self._config['host'], 'wb'))
            
            if stop_on_error and self.experiment_info(new_id)['experiment']['completion_status'] != 'success':
                raise Exception('Loop %d for experiment id %d failed'%(loop, new_id))

            time.sleep(gap_minutes * 60)

            if delete_loop_experiments:
                try:
                    self.experiment_delete(new_id)
                except:
                    print('Failed to delete experiment id %d'%new_id)

            time.sleep(10)

            # renew connection authorization
            self.connect_rest()

        print("Finished %d loops for experiment id %d"%(loop, experiment_id))

        return data