Instruction:
Can you generate a brief explanation for the following Python 3 code
def handle_data(self, data, new_file=False, flush=True):
        '''Handling of the data.

        Parameters
        ----------
        data : list, tuple
            Data tuple of the format (data (np.array), last_time (float), curr_time (float), status (int))
        '''
        for i, module_id in enumerate(self._selected_modules):
            if data[i] is None:
                continue
            self._raw_data_files[module_id].append(data_iterable=data[i], scan_parameters=self._scan_parameters[module_id]._asdict(), new_file=new_file, flush=flush)

Response: Handling of the data.


Instruction:
Make a summary of the following Python 3 code
def handle_err(self, exc):
        '''Handling of Exceptions.

        Parameters
        ----------
        exc : list, tuple
            Information of the exception of the format (type, value, traceback).
            Uses the return value of sys.exc_info().
        '''
        if self.reset_rx_on_error and isinstance(exc[1], (RxSyncError, EightbTenbError)):
            self.fifo_readout.print_readout_status()
            self.fifo_readout.reset_rx()
        else:
            # print just the first error massage
            if not self.abort_run.is_set():
                self.abort(msg=exc[1].__class__.__name__ + ": " + str(exc[1]))
            self.err_queue.put(exc)

Response:
Handling of Exceptions.

        Parameters
        ----------
        exc : list, tuple
            Information of the exception of the format (type, value, traceback).
            Uses the return value of sys.exc_info().


Instruction:
Write a Python 3 script for
returning the configuration file for a given module ID and run number.

Response:
def get_configuration(self, module_id, run_number=None):
        ''' Returns the configuration for a given module ID.

        The working directory is searched for a file matching the module_id with the
        given run number. If no run number is defined the last successfull run defines
        the run number.
        '''
        def find_file(run_number):
            module_path = self.get_module_path(module_id)
            for root, _, files in os.walk(module_path):
                for cfgfile in files:
                    cfg_root, cfg_ext = os.path.splitext(cfgfile)
                    if cfg_root.startswith(''.join([str(run_number), '_', module_id])) and cfg_ext.endswith(".cfg"):
                        return os.path.join(root, cfgfile)

        if not run_number:
            run_numbers = sorted(self._get_run_numbers(status='FINISHED').keys(), reverse=True)
            found_fin_run_cfg = True
            if not run_numbers:
                return None
            last_fin_run = run_numbers[0]
            for run_number in run_numbers:
                cfg_file = find_file(run_number)
                if cfg_file:
                    if not found_fin_run_cfg:
                        logging.warning("Module '%s' has no configuration for run %d, use config of run %d", module_id, last_fin_run, run_number)
                    return cfg_file
                else:
                    found_fin_run_cfg = False
        else:
            cfg_file = find_file(run_number)
            if cfg_file:
                return cfg_file
            else:
                raise ValueError('Found no configuration with run number %s' % run_number)


Instruction:
How would you code a function in Python 3 to
select module and give access to the module.

Response:
def select_module(self, module_id):
        ''' Select module and give access to the module.
        '''
        if not isinstance(module_id, basestring) and isinstance(module_id, Iterable) and set(module_id) - set(self._modules):
            raise ValueError('Module IDs invalid:' % ", ".join(set(module_id) - set(self._modules)))
        if isinstance(module_id, basestring) and module_id not in self._module_cfgs:
            raise ValueError('Module ID "%s" is not valid' % module_id)
        if self._current_module_handle is not None:
            raise RuntimeError('Module handle "%s" cannot be set because another module is active' % module_id)

        if module_id is None:
            self._selected_modules = self._modules.keys()
        elif not isinstance(module_id, basestring) and isinstance(module_id, Iterable):
            self._selected_modules = module_id
        elif module_id in self._modules:
            self._selected_modules = [module_id]
        elif module_id in self._tx_module_groups:
            self._selected_modules = self._tx_module_groups[module_id]
        else:
            RuntimeError('Cannot open files. Module handle "%s" is not valid.' % self.current_module_handle)

        # FIFO readout
        self._selected_fifos = list(set([module_cfg['FIFO'] for (name, module_cfg) in self._module_cfgs.items() if name in self._selected_modules]))

        # Module filter functions dict for quick lookup
        self._readout_fifos = []
        self._filter = []
        self._converter = []
        for selected_module_id in self._selected_modules:
            module_cfg = self._module_cfgs[selected_module_id]
            self._readout_fifos.append(module_cfg['FIFO'])
            if 'tdc_channel' not in module_cfg:
                tdc_filter = false
                self._converter.append(None)
            elif module_cfg['tdc_channel'] is None:
                tdc_filter = is_tdc_word
                self._converter.append(convert_tdc_to_channel(channel=module_cfg['tdc_channel']))  # for the raw data analyzer
            else:
                tdc_filter = logical_and(is_tdc_word, is_tdc_from_channel(module_cfg['tdc_channel']))
                self._converter.append(convert_tdc_to_channel(channel=module_cfg['tdc_channel']))  # for the raw data analyzer
            if 'rx_channel' not in module_cfg:
                self._filter.append(logical_or(is_trigger_word, tdc_filter))
            elif module_cfg['rx_channel'] is None:
                self._filter.append(logical_or(is_trigger_word, logical_or(tdc_filter, is_fe_word)))
            else:
                self._filter.append(logical_or(is_trigger_word, logical_or(tdc_filter, logical_and(is_fe_word, is_data_from_channel(module_cfg['rx_channel'])))))

        # select readout channels and report sync status only from actively selected modules
        self._enabled_fe_channels = list(set([config['RX'] for (name, config) in self._module_cfgs.items() if name in self._selected_modules]))

        # enabling specific TX channels
        tx_channels = list(set([1 << config['tx_channel'] for (name, config) in self._module_cfgs.items() if name in self._selected_modules]))
        if tx_channels:
            self.dut['TX']['OUTPUT_ENABLE'] = reduce(lambda x, y: x | y, tx_channels)
        else:
            self.dut['TX']['OUTPUT_ENABLE'] = 0

        if not isinstance(module_id, basestring) and isinstance(module_id, Iterable):
            self._current_module_handle = None
        else:
            self._current_module_handle = module_id

        if module_id is not None and isinstance(module_id, basestring):
            current_thread().name = module_id


Instruction:
Can you generate a brief explanation for the following Python 3 code
def deselect_module(self):
        ''' Deselect module and cleanup.
        '''
        self._enabled_fe_channels = []  # ignore any RX sync errors
        self._readout_fifos = []
        self._filter = []
        self._converter = []
        self.dut['TX']['OUTPUT_ENABLE'] = 0
        self._current_module_handle = None
        if isinstance(current_thread(), _MainThread):
            current_thread().name = "MainThread"

Response: Deselect module and cleanup.


Instruction:
How would you explain what the following Python 3 function does
def enter_sync(self):
        ''' Waiting for all threads to appear, then continue.
        '''
        if self._scan_threads and self.current_module_handle not in [t.name for t in self._scan_threads]:
            raise RuntimeError('Thread name "%s" is not valid.')
        if self._scan_threads and self.current_module_handle in self._curr_sync_threads:
            raise RuntimeError('Thread "%s" is already actively reading FIFO.')
        with self._sync_lock:
            self._curr_sync_threads.append(self.current_module_handle)
        self._enter_sync_event.clear()
        while not self._enter_sync_event.wait(0.01):
            if self.abort_run.is_set():
                break
            with self._sync_lock:
                if len(set(self._curr_sync_threads) & set([t.name for t in self._scan_threads if t.is_alive()])) == len(set([t.name for t in self._scan_threads if t.is_alive()])) or not self._scan_threads:
                    self._enter_sync_event.set()

Response: Wait for all threads to appear then continue.


Instruction:
Here you have a function in Python 3, explain what it does
def exit_sync(self):
        ''' Waiting for all threads to appear, then continue.
        '''
        if self._scan_threads and self.current_module_handle not in [t.name for t in self._scan_threads]:
            raise RuntimeError('Thread name "%s" is not valid.')
        if self._scan_threads and self.current_module_handle not in self._curr_sync_threads:
            raise RuntimeError('Thread "%s" is not reading FIFO.')
        with self._sync_lock:
            self._curr_sync_threads.remove(self.current_module_handle)
        self._exit_sync_event.clear()
        while not self._exit_sync_event.wait(0.01):
            if self.abort_run.is_set():
                break
            with self._sync_lock:
                if len(set(self._curr_sync_threads) & set([t.name for t in self._scan_threads if t.is_alive()])) == 0 or not self._scan_threads:
                    self._exit_sync_event.set()

Response: Waiting for all threads to appear, then continue.


Instruction:
Make a summary of the following Python 3 code
def readout(self, *args, **kwargs):
        ''' Running the FIFO readout while executing other statements.

        Starting and stopping of the FIFO readout is synchronized between the threads.
        '''
        timeout = kwargs.pop('timeout', 10.0)
        self.start_readout(*args, **kwargs)
        try:
            yield
        finally:
            try:
                self.stop_readout(timeout=timeout)
            except Exception:
                # in case something fails, call this on last resort
                # if run was aborted, immediately stop readout
                if self.abort_run.is_set():
                    with self._readout_lock:
                        if self.fifo_readout.is_running:
                            self.fifo_readout.stop(timeout=0.0)

Response: A context manager that starts the FIFO readout while executing other statements.


Instruction:
Explain what the following Python 3 code does
def start_readout(self, *args, **kwargs):
        ''' Starting the FIFO readout.

        Starting of the FIFO readout is executed only once by a random thread.
        Starting of the FIFO readout is synchronized between all threads reading out the FIFO.
        '''
        # Pop parameters for fifo_readout.start
        callback = kwargs.pop('callback', self.handle_data)
        errback = kwargs.pop('errback', self.handle_err)
        reset_rx = kwargs.pop('reset_rx', True)
        reset_fifo = kwargs.pop('reset_fifo', True)
        fill_buffer = kwargs.pop('fill_buffer', False)
        no_data_timeout = kwargs.pop('no_data_timeout', None)
        enabled_fe_channels = kwargs.pop('enabled_fe_channels', self._enabled_fe_channels)
        if args or kwargs:
            self.set_scan_parameters(*args, **kwargs)
        if self._scan_threads and self.current_module_handle not in [t.name for t in self._scan_threads]:
            raise RuntimeError('Thread name "%s" is not valid.' % t.name)
        if self._scan_threads and self.current_module_handle in self._curr_readout_threads:
            raise RuntimeError('Thread "%s" is already actively reading FIFO.')
        with self._readout_lock:
            self._curr_readout_threads.append(self.current_module_handle)
        self._starting_readout_event.clear()
        while not self._starting_readout_event.wait(0.01):
            if self.abort_run.is_set():
                break
            with self._readout_lock:
                if len(set(self._curr_readout_threads) & set([t.name for t in self._scan_threads if t.is_alive()])) == len(set([t.name for t in self._scan_threads if t.is_alive()])) or not self._scan_threads:
                    if not self.fifo_readout.is_running:
                        self.fifo_readout.start(fifos=self._selected_fifos, callback=callback, errback=errback, reset_rx=reset_rx, reset_fifo=reset_fifo, fill_buffer=fill_buffer, no_data_timeout=no_data_timeout, filter_func=self._filter, converter_func=self._converter, fifo_select=self._readout_fifos, enabled_fe_channels=enabled_fe_channels)
                        self._starting_readout_event.set()

Response: Start the FIFO readout.


Instruction:
Can you tell what is the following Python 3 function doing
def stop_readout(self, timeout=10.0):
        ''' Stopping the FIFO readout.

        Stopping of the FIFO readout is executed only once by a random thread.
        Stopping of the FIFO readout is synchronized between all threads reading out the FIFO.
        '''
        if self._scan_threads and self.current_module_handle not in [t.name for t in self._scan_threads]:
            raise RuntimeError('Thread name "%s" is not valid.')
        if self._scan_threads and self.current_module_handle not in self._curr_readout_threads:
            raise RuntimeError('Thread "%s" is not reading FIFO.')
        with self._readout_lock:
            self._curr_readout_threads.remove(self.current_module_handle)
        self._stopping_readout_event.clear()
        while not self._stopping_readout_event.wait(0.01):
            with self._readout_lock:
                if len(set(self._curr_readout_threads) & set([t.name for t in self._scan_threads if t.is_alive()])) == 0 or not self._scan_threads or self.abort_run.is_set():
                    if self.fifo_readout.is_running:
                        self.fifo_readout.stop(timeout=timeout)
                    self._stopping_readout_event.set()

Response: Stops the FIFO readout.


Instruction:
Write a Python 3 script for
opening the hit or calibration file and return the calibration per pixel

Response:
def get_charge_calibration(calibation_file, max_tdc):
    ''' Open the hit or calibration file and return the calibration per pixel'''
    with tb.open_file(calibation_file, mode="r") as in_file_calibration_h5:
        tdc_calibration = in_file_calibration_h5.root.HitOrCalibration[:, :, :, 1]
        tdc_calibration_values = in_file_calibration_h5.root.HitOrCalibration.attrs.scan_parameter_values[:]
    return get_charge(max_tdc, tdc_calibration_values, tdc_calibration)


Instruction:
Write a Python 3 script to
add the Plot pyBAR data. entry to Dataset menu.

Response:
def addEntry(self):
        """Add the `Plot pyBAR data`. entry to `Dataset` menu.
        """
        export_icon = QtGui.QIcon()
        pixmap = QtGui.QPixmap(os.path.join(PLUGINSDIR,
                                            'csv/icons/document-export.png'))
        export_icon.addPixmap(pixmap, QtGui.QIcon.Normal, QtGui.QIcon.On)

        self.plot_action = QtGui.QAction(
            translate('PlotpyBARdata',
                      "Plot data with pyBAR plugin",
                      "Plot data with pyBAR plugin"),
            self,
            shortcut=QtGui.QKeySequence.UnknownKey, triggered=self.plot,
            icon=export_icon,
            statusTip=translate('PlotpyBARdata',
                                "Plotting of selected data with pyBAR",
                                "Status bar text for the Dataset -> Plot pyBAR data... action"))

        # Add the action to the Dataset menu
        menu = self.vtgui.dataset_menu
        menu.addSeparator()
        menu.addAction(self.plot_action)

        # Add the action to the leaf context menu
        cmenu = self.vtgui.leaf_node_cm
        cmenu.addSeparator()
        cmenu.addAction(self.plot_action)


Instruction:
Write a Python 3 function for
updating the export QAction when the Dataset menu is pulled down.

Response:
def updateDatasetMenu(self):
        """Update the `export` QAction when the Dataset menu is pulled down.

        This method is a slot. See class ctor for details.
        """
        enabled = True
        current = self.vtgui.dbs_tree_view.currentIndex()
        if current:
            leaf = self.vtgui.dbs_tree_model.nodeFromIndex(current)
            if leaf.node_kind in (u'group', u'root group'):
                enabled = False

        self.plot_action.setEnabled(enabled)


Instruction:
Can you generate the documentation for the following Python 3 function
def plot(self):
        # The PyTables node tied to the current leaf of the databases tree
        current = self.vtgui.dbs_tree_view.currentIndex()
        leaf = self.vtgui.dbs_tree_model.nodeFromIndex(current).node

        data_name = leaf.name

        hists_1d = ['HistRelBcid', 'HistErrorCounter', 'HistTriggerErrorCounter', 'HistServiceRecord', 'HistTot', 'HistTdc', 'HistClusterTot', 'HistClusterSize']
        hists_2d = ['HistOcc', 'Enable', 'Imon', 'C_High', 'EnableDigInj', 'C_Low', 'FDAC', 'TDAC', 'HistTdcPixel', 'HistTotPixel', 'HistThreshold', 'HistNoise', 'HistThresholdFitted', 'HistNoiseFitted', 'HistThresholdFittedCalib', 'HistNoiseFittedCalib']

        if data_name in hists_1d:
            plot_1d_hist(hist=leaf[:], title=data_name)
        elif data_name in hists_2d:
            if data_name == 'HistOcc':
                leaf = np.sum(leaf[:], axis=2)
            plot_2d_hist(hist=leaf[:], title=data_name)
        elif 'Table' in str(type(leaf)) and len(leaf[:].dtype.names) <= 3:  # detect tables with less than 4 columns
            plot_table(leaf[:], title=data_name)
        elif data_name == 'HitOrCalibration':
            print 'Comming soon'
        else:
            print 'Plotting', data_name, '(%s) is not supported!' % type(leaf)

Response: This method exports a given dataset to a CSV file.


Instruction:
Can you generate the documentation for the following Python 3 function
def helpAbout(self):

        # Text to be displayed
        about_text = translate('pyBarPlugin',
                               """<qt>
            <p>Data plotting plug-in for pyBAR.
            </qt>""",
                               'About')

        descr = dict(module_name='pyBarPlugin',
                     folder=PLUGINSDIR,
                     version=__version__,
                     plugin_name='pyBarPlugin',
                     author='David-Leon Pohl <david-leon.pohl@rub.de>, Jens Janssen <janssen@physik.uni-bonn.de>',
                     descr=about_text)

        return descr

Response: Help text for the object.


Instruction:
Implement a Python 3 function for
sending the config via ZeroMQ to a specified socket.

Response:
def send_meta_data(socket, conf, name):
    '''Sends the config via ZeroMQ to a specified socket. Is called at the beginning of a run and when the config changes. Conf can be any config dictionary.
    '''
    meta_data = dict(
        name=name,
        conf=conf
    )
    try:
        socket.send_json(meta_data, flags=zmq.NOBLOCK)
    except zmq.Again:
        pass


Instruction:
Here you have a function in Python 3, explain what it does
def send_data(socket, data, scan_parameters={}, name='ReadoutData'):
    '''Sends the data of every read out (raw data and meta data) via ZeroMQ to a specified socket
    '''
    if not scan_parameters:
        scan_parameters = {}
    data_meta_data = dict(
        name=name,
        dtype=str(data[0].dtype),
        shape=data[0].shape,
        timestamp_start=data[1],  # float
        timestamp_stop=data[2],  # float
        readout_error=data[3],  # int
        scan_parameters=scan_parameters  # dict
    )
    try:
        socket.send_json(data_meta_data, flags=zmq.SNDMORE | zmq.NOBLOCK)
        socket.send(data[0], flags=zmq.NOBLOCK)  # PyZMQ supports sending numpy arrays without copying any data
    except zmq.Again:
        pass

Response: Sends the data of every read out to a specified socket


Instruction:
Write a Python 3 script to
write raw data from data queue to file

Response:
def save_raw_data_from_data_queue(data_queue, filename, mode='a', title='', scan_parameters=None):  # mode="r+" to append data, raw_data_file_h5 must exist, "w" to overwrite raw_data_file_h5, "a" to append data, if raw_data_file_h5 does not exist it is created
    '''Writing raw data file from data queue

    If you need to write raw data once in a while this function may make it easy for you.
    '''
    if not scan_parameters:
        scan_parameters = {}
    with open_raw_data_file(filename, mode='a', title='', scan_parameters=list(dict.iterkeys(scan_parameters))) as raw_data_file:
        raw_data_file.append(data_queue, scan_parameters=scan_parameters)


Instruction:
How would you explain what the following Python 3 function does
def plot_linear_relation(x, y, x_err=None, y_err=None, title=None, point_label=None, legend=None, plot_range=None, plot_range_y=None, x_label=None, y_label=None, y_2_label=None, log_x=False, log_y=False, size=None, filename=None):
    ''' Takes point data (x,y) with errors(x,y) and fits a straight line. The deviation to this line is also plotted, showing the offset.

     Parameters
    ----------
    x, y, x_err, y_err: iterable

    filename: string, PdfPages object or None
        PdfPages file object: plot is appended to the pdf
        string: new plot file with the given filename is created
        None: the plot is printed to screen
    '''
    fig = Figure()
    FigureCanvas(fig)
    ax = fig.add_subplot(111)
    if x_err is not None:
        x_err = [x_err, x_err]
    if y_err is not None:
        y_err = [y_err, y_err]
    ax.set_title(title)
    if y_label is not None:
        ax.set_ylabel(y_label)
    if log_x:
        ax.set_xscale('log')
    if log_y:
        ax.set_yscale('log')
    if plot_range:
        ax.set_xlim((min(plot_range), max(plot_range)))
    if plot_range_y:
        ax.set_ylim((min(plot_range_y), max(plot_range_y)))
    if legend:
        fig.legend(legend, 0)
    ax.grid(True)
    ax.errorbar(x, y, xerr=x_err, yerr=y_err, fmt='o', color='black')  # plot points
    # label points if needed
    if point_label is not None:
        for X, Y, Z in zip(x, y, point_label):
            ax.annotate('{}'.format(Z), xy=(X, Y), xytext=(-5, 5), ha='right', textcoords='offset points')
    line_fit, _ = np.polyfit(x, y, 1, full=False, cov=True)
    fit_fn = np.poly1d(line_fit)
    ax.plot(x, fit_fn(x), '-', lw=2, color='gray')
    setp(ax.get_xticklabels(), visible=False)  # remove ticks at common border of both plots

    divider = make_axes_locatable(ax)
    ax_bottom_plot = divider.append_axes("bottom", 2.0, pad=0.0, sharex=ax)

    ax_bottom_plot.bar(x, y - fit_fn(x), align='center', width=np.amin(np.diff(x)) / 2, color='gray')
#     plot(x, y - fit_fn(x))
    ax_bottom_plot.grid(True)
    if x_label is not None:
        ax.set_xlabel(x_label)
    if y_2_label is not None:
        ax.set_ylabel(y_2_label)

    ax.set_ylim((-np.amax(np.abs(y - fit_fn(x)))), (np.amax(np.abs(y - fit_fn(x)))))

    ax.plot(ax.set_xlim(), [0, 0], '-', color='black')
    setp(ax_bottom_plot.get_yticklabels()[-2:-1], visible=False)

    if size is not None:
        fig.set_size_inches(size)

    if not filename:
        fig.show()
    elif isinstance(filename, PdfPages):
        filename.savefig(fig)
    elif filename:
        fig.savefig(filename, bbox_inches='tight')

    return fig

Response: Plots a linear relation between two data sets.


Instruction:
Create a Python 3 function to
plot a 2D histogram of x and y.

Response:
def plot_profile_histogram(x, y, n_bins=100, title=None, x_label=None, y_label=None, log_y=False, filename=None):
    '''Takes 2D point data (x,y) and creates a profile histogram similar to the TProfile in ROOT. It calculates
    the y mean for every bin at the bin center and gives the y mean error as error bars.

    Parameters
    ----------
    x : array like
        data x positions
    y : array like
        data y positions
    n_bins : int
        the number of bins used to create the histogram
    '''
    if len(x) != len(y):
        raise ValueError('x and y dimensions have to be the same')
    n, bin_edges = np.histogram(x, bins=n_bins)  # needed to calculate the number of points per bin
    sy = np.histogram(x, bins=n_bins, weights=y)[0]  # the sum of the bin values
    sy2 = np.histogram(x, bins=n_bins, weights=y * y)[0]  # the quadratic sum of the bin values
    bin_centers = (bin_edges[1:] + bin_edges[:-1]) / 2  # calculate the bin center for all bins
    mean = sy / n  # calculate the mean of all bins
    std = np.sqrt((sy2 / n - mean * mean))  # TODO: not understood, need check if this is really the standard deviation
    #     std_mean = np.sqrt((sy2 - 2 * mean * sy + mean * mean) / (1*(n - 1)))  # this should be the formular ?!
    std_mean = std / np.sqrt((n - 1))
    mean[np.isnan(mean)] = 0.0
    std_mean[np.isnan(std_mean)] = 0.0

    fig = Figure()
    FigureCanvas(fig)
    ax = fig.add_subplot(111)
    ax.errorbar(bin_centers, mean, yerr=std_mean, fmt='o')
    ax.set_title(title)
    if x_label is not None:
        ax.set_xlabel(x_label)
    if y_label is not None:
        ax.set_ylabel(y_label)
    if log_y:
        ax.yscale('log')
    ax.grid(True)
    if not filename:
        fig.show()
    elif isinstance(filename, PdfPages):
        filename.savefig(fig)
    else:
        fig.savefig(filename)


Instruction:
Explain what the following Python 3 code does
def round_to_multiple(number, multiple):
    '''Rounding up to the nearest multiple of any positive integer

    Parameters
    ----------
    number : int, float
        Input number.
    multiple : int
        Round up to multiple of multiple. Will be converted to int. Must not be equal zero.
    Returns
    -------
    ceil_mod_number : int
        Rounded up number.

    Example
    -------
    round_to_multiple(maximum, math.floor(math.log10(maximum)))
    '''
    multiple = int(multiple)
    if multiple == 0:
        multiple = 1
    ceil_mod_number = number - number % (-multiple)
    return int(ceil_mod_number)

Response: Round up to the nearest multiple of any positive integer.


Instruction:
Write a Python 3 script to
calculate quantiles from histograms cuts off hist below and above given quantile.

Response:
def hist_quantiles(hist, prob=(0.05, 0.95), return_indices=False, copy=True):
    '''Calculate quantiles from histograms, cuts off hist below and above given quantile. This function will not cut off more than the given values.

    Parameters
    ----------
    hist : array_like, iterable
        Input histogram with dimension at most 1.
    prob : float, list, tuple
        List of quantiles to compute. Upper and lower limit. From 0 to 1. Default is 0.05 and 0.95.
    return_indices : bool, optional
        If true, return the indices of the hist.
    copy : bool, optional
        Whether to copy the input data (True), or to use a reference instead. Default is False.

    Returns
    -------
    masked_hist : masked_array
       Hist with masked elements.
    masked_hist : masked_array, tuple
        Hist with masked elements and indices.
    '''
    # make np array
    hist_t = np.array(hist)
    # calculate cumulative distribution
    cdf = np.cumsum(hist_t)
    # copy, convert and normalize
    if cdf[-1] == 0:
        normcdf = cdf.astype('float')
    else:
        normcdf = cdf.astype('float') / cdf[-1]
    # calculate unique values from cumulative distribution and their indices
    unormcdf, indices = np.unique(normcdf, return_index=True)
    # calculate limits
    try:
        hp = np.where(unormcdf > prob[1])[0][0]
        lp = np.where(unormcdf >= prob[0])[0][0]
    except IndexError:
        hp_index = hist_t.shape[0]
        lp_index = 0
    else:
        hp_index = indices[hp]
        lp_index = indices[lp]
    # copy and create ma
    masked_hist = np.ma.array(hist, copy=copy, mask=True)
    masked_hist.mask[lp_index:hp_index + 1] = False
    if return_indices:
        return masked_hist, (lp_index, hp_index)
    else:
        return masked_hist


Instruction:
Create a Python 3 function to
return the last nonzero entry in a histogram.

Response:
def hist_last_nonzero(hist, return_index=False, copy=True):
    '''Find the last nonzero index and mask the remaining entries.

    Parameters
    ----------
    hist : array_like, iterable
        Input histogram with dimension at most 1.
    return_index : bool, optional
        If true, return the index.
    copy : bool, optional
        Whether to copy the input data (True), or to use a reference instead. Default is False.

    Returns
    -------
    masked_hist : masked_array
       Hist with masked elements.
    masked_hist : masked_array, tuple
        Hist with masked elements and index of the element after the last nonzero value.
    '''
    # make np array
    hist_t = np.array(hist)
    index = (np.where(hist_t)[-1][-1] + 1) if np.sum(hist_t) > 1 else hist_t.shape[0]
    # copy and create ma
    masked_hist = np.ma.array(hist, copy=copy, mask=True)
    masked_hist.mask[index:] = False
    if return_index:
        return masked_hist, index
    else:
        return masked_hist


Instruction:
Can you generate the documentation for the following Python 3 function
def readout(self, fifo, no_data_timeout=None):
        '''Readout thread continuously reading FIFO.

        Readout thread, which uses read_raw_data_from_fifo() and appends data to self._fifo_data_deque (collection.deque).
        '''
        logging.info('Starting readout thread for %s', fifo)
        time_last_data = time()
        time_wait = 0.0
        empty_reads = 0
        while not self.force_stop[fifo].wait(time_wait if time_wait >= 0.0 else 0.0):
            time_read = time()
            try:
                if no_data_timeout and time_last_data + no_data_timeout < get_float_time():
                    raise NoDataTimeout('Received no data for %0.1f second(s) from %s' % (no_data_timeout, fifo))
                raw_data = self.read_raw_data_from_fifo(fifo)
            except NoDataTimeout:
                no_data_timeout = None  # raise exception only once
                if self.errback:
                    self.errback(sys.exc_info())
                else:
                    raise
            except Exception:
                if self.errback:
                    self.errback(sys.exc_info())
                else:
                    raise
                if self.stop_readout.is_set():  # in case of a exception, break immediately
                    break
            else:
                n_data_words = raw_data.shape[0]
                if n_data_words > 0:
                    time_last_data = time()
                    empty_reads = 0
                    time_start_read, time_stop_read = self.update_timestamp(fifo)
                    status = 0
                    self._fifo_data_deque[fifo].append((raw_data, time_start_read, time_stop_read, status))
                    with self._fifo_conditions[fifo]:
                        self._fifo_conditions[fifo].notify_all()
                elif self.stop_readout.is_set():
                    if empty_reads == self._n_empty_reads:
                        break
                    else:
                        empty_reads += 1
            finally:
                # ensure that the readout interval does not depend on the processing time of the data
                # and stays more or less constant over time
                time_wait = self.readout_interval - (time() - time_read)
        self._fifo_data_deque[fifo].append(None)  # last item, None will stop worker
        with self._fifo_conditions[fifo]:
            self._fifo_conditions[fifo].notify_all()
        logging.info('Stopping readout thread for %s', fifo)

Response: Readout thread continuously reading FIFO.


Instruction:
Given the following Python 3 function, write the documentation
def worker(self, fifo):
        '''Worker thread continuously filtering and converting data when data becomes available.
        '''
        logging.debug('Starting worker thread for %s', fifo)
        self._fifo_conditions[fifo].acquire()
        while True:
            try:
                data_tuple = self._fifo_data_deque[fifo].popleft()
            except IndexError:
                self._fifo_conditions[fifo].wait(self.readout_interval)  # sleep a little bit, reducing CPU usage
            else:
                if data_tuple is None:  # if None then exit
                    break
                else:
                    for index, (filter_func, converter_func, fifo_select) in enumerate(izip(self.filter_func, self.converter_func, self.fifo_select)):
                        if fifo_select is None or fifo_select == fifo:
                            # filter and do the conversion
                            converted_data_tuple = convert_data_iterable((data_tuple,), filter_func=filter_func, converter_func=converter_func)[0]
                            n_data_words = converted_data_tuple[0].shape[0]
                            with self.data_words_per_second_lock:
                                self._words_per_read[index].append((n_data_words, converted_data_tuple[1], converted_data_tuple[2]))
                            self._data_deque[index].append(converted_data_tuple)
                            with self._data_conditions[index]:
                                self._data_conditions[index].notify_all()
        for index, fifo_select in enumerate(self.fifo_select):
            if fifo_select is None or fifo_select == fifo:
                self._data_deque[index].append(None)
                with self._data_conditions[index]:
                    self._data_conditions[index].notify_all()
        self._fifo_conditions[fifo].release()
        logging.debug('Stopping worker thread for %s', fifo)

Response: This method is a thread that continuously filters and converts data when data becomes available.


Instruction:
Write a Python 3 function that can
thread continuously calling callback function for writing data when data becomes available.

Response:
def writer(self, index, no_data_timeout=None):
        '''Writer thread continuously calling callback function for writing data when data becomes available.
        '''
        is_fe_data_header = logical_and(is_fe_word, is_data_header)
        logging.debug('Starting writer thread with index %d', index)
        self._data_conditions[index].acquire()
        time_last_data = time()
        time_write = time()
        converted_data_tuple_list = [None] * len(self.filter_func)  # callback function gets a list of lists of tuples
        while True:
            try:
                if no_data_timeout and time_last_data + no_data_timeout < time():
                    raise NoDataTimeout('Received no data for %0.1f second(s) for writer thread with index %d' % (no_data_timeout, index))
                converted_data_tuple = self._data_deque[index].popleft()
            except NoDataTimeout:  # no data timeout
                no_data_timeout = None  # raise exception only once
                if self.errback:
                    self.errback(sys.exc_info())
                else:
                    raise
            except IndexError:  # no data in queue
                self._data_conditions[index].wait(self.readout_interval)  # sleep a little bit, reducing CPU usage
            else:
                if converted_data_tuple is None:  # if None then write and exit
                    if self.callback and any(converted_data_tuple_list):
                        try:
                            self.callback(converted_data_tuple_list)
                        except Exception:
                            self.errback(sys.exc_info())
                    break
                else:
                    if no_data_timeout and np.any(is_fe_data_header(converted_data_tuple[0])):  # check for FEI4 data words
                        time_last_data = time()
                    if converted_data_tuple_list[index]:
                        converted_data_tuple_list[index].append(converted_data_tuple)
                    else:
                        converted_data_tuple_list[index] = [converted_data_tuple]  # adding iterable
                    if self.fill_buffer:
                        self._data_buffer[index].append(converted_data_tuple)
            # check if calling the callback function is about time
            if self.callback and any(converted_data_tuple_list) and ((self.write_interval and time() - time_write >= self.write_interval) or not self.write_interval):
                try:
                    self.callback(converted_data_tuple_list)  # callback function gets a list of lists of tuples
                except Exception:
                    self.errback(sys.exc_info())
                else:
                    converted_data_tuple_list = [None] * len(self.filter_func)
                    time_write = time()  # update last write timestamp
        self._data_conditions[index].release()
        logging.debug('Stopping writer thread with index %d', index)


Instruction:
Here you have a function in Python 3, explain what it does
def get_data_from_buffer(self, filter_func=None, converter_func=None):
        '''Reads local data buffer and returns data and meta data list.

        Returns
        -------
        data : list
            List of data and meta data dicts.
        '''
        if self._is_running:
            raise RuntimeError('Readout thread running')
        if not self.fill_buffer:
            logging.warning('Data buffer is not activated')
        return [convert_data_iterable(data_iterable, filter_func=filter_func, converter_func=converter_func) for data_iterable in self._data_buffer]

Response: Reads local data buffer and returns data and meta data dicts.


Instruction:
Write a Python 3 script for
reading local data buffer and returns raw data array.

Response:
def get_raw_data_from_buffer(self, filter_func=None, converter_func=None):
        '''Reads local data buffer and returns raw data array.

        Returns
        -------
        data : np.array
            An array containing data words from the local data buffer.
        '''
        if self._is_running:
            raise RuntimeError('Readout thread running')
        if not self.fill_buffer:
            logging.warning('Data buffer is not activated')
        return [convert_data_array(data_array_from_data_iterable(data_iterable), filter_func=filter_func, converter_func=converter_func) for data_iterable in self._data_buffer]


Instruction:
Explain what the following Python 3 code does
def read_raw_data_from_fifo(self, fifo, filter_func=None, converter_func=None):
        '''Reads FIFO data and returns raw data array.

        Returns
        -------
        data : np.array
            An array containing FIFO data words.
        '''
        return convert_data_array(self.dut[fifo].get_data(), filter_func=filter_func, converter_func=converter_func)

Response: Reads FIFO data and returns raw data array.


Instruction:
Write a Python 3 function for
getting an item from the queue Q.

Response:
def get_item_from_queue(Q, timeout=0.01):
    """ Attempts to retrieve an item from the queue Q. If Q is
        empty, None is returned.

        Blocks for 'timeout' seconds in case the queue is empty,
        so don't use this method for speedy retrieval of multiple
        items (use get_all_from_queue for that).
    """
    try:
        item = Q.get(True, 0.01)
    except Queue.Empty:
        return None

    return item


Instruction:
Explain what the following Python 3 code does
def argmin_list(seq, func):
    best_score, best = func(seq[0]), []
    for x in seq:
        x_score = func(x)
        if x_score < best_score:
            best, best_score = [x], x_score
        elif x_score == best_score:
            best.append(x)
    return best

Response: Returns a list of elements of seq with the lowest scores.


Instruction:
Implement a function in Python 3 to
flatten iterable but leaves out strings

Response:
def flatten_iterable(iterable):
    """flatten iterable, but leaves out strings

    [[[1, 2, 3], [4, 5]], 6] -> [1, 2, 3, 4, 5, 6]

    """
    for item in iterable:
        if isinstance(item, collections.Iterable) and not isinstance(item, basestring):
            for sub in flatten_iterable(item):
                yield sub
        else:
            yield item


Instruction:
Can you write a function in Python 3 where it
generates iterable from item but leaves out strings

Response:
def iterable(item):
    """generate iterable from item, but leaves out strings

    """
    if isinstance(item, collections.Iterable) and not isinstance(item, basestring):
        return item
    else:
        return [item]


Instruction:
Given the following Python 3 function, write the documentation
def natsorted(seq, cmp=natcmp):
    "Returns a copy of seq, sorted by natural string sort."
    import copy
    temp = copy.copy(seq)
    natsort(temp, cmp)
    return temp

Response: Returns a copy of seq sorted by natural string sort.


Instruction:
Can you generate the documentation for the following Python 3 function
def get_iso_time():
    '''returns time as ISO string, mapping to and from datetime in ugly way

    convert to string with str()
    '''
    t1 = time.time()
    t2 = datetime.datetime.fromtimestamp(t1)
    t4 = t2.__str__()
    try:
        t4a, t4b = t4.split(".", 1)
    except ValueError:
        t4a = t4
        t4b = '000000'
    t5 = datetime.datetime.strptime(t4a, "%Y-%m-%d %H:%M:%S")
    ms = int(t4b.ljust(6, '0')[:6])
    return t5.replace(microsecond=ms)

Response: returns time as ISO string mapping to and from datetime in ugly way


Instruction:
Can you generate the documentation for the following Python 3 function
def get_float_time():
    '''returns time as double precision floats - Time64 in pytables - mapping to and from python datetime's

    '''
    t1 = time.time()
    t2 = datetime.datetime.fromtimestamp(t1)
    return time.mktime(t2.timetuple()) + 1e-6 * t2.microsecond

Response: returns time as double precision floats - Time64 in pytables - mapping to and from python datetime s


Instruction:
Explain what the following Python 3 code does
def groupby_dict(dictionary, key):
    ''' Group dict of dicts by key.
    '''
    return dict((k, list(g)) for k, g in itertools.groupby(sorted(dictionary.keys(), key=lambda name: dictionary[name][key]), key=lambda name: dictionary[name][key]))

Response: Group dict of dicts by key.


Instruction:
Write a Python 3 script for
returning a new iterable with fillvalue removed from the first iterable.

Response:
def zip_nofill(*iterables):
    '''Zipping iterables without fillvalue.

    Note: https://stackoverflow.com/questions/38054593/zip-longest-without-fillvalue
    '''
    return (tuple([entry for entry in iterable if entry is not None]) for iterable in itertools.izip_longest(*iterables, fillvalue=None))


Instruction:
Write a Python 3 function for
finding a file in a directory upwards.

Response:
def find_file_dir_up(filename, path=None, n=None):
    '''Finding file in directory upwards.
    '''
    if path is None:
        path = os.getcwd()
    i = 0
    while True:
        current_path = path
        for _ in range(i):
            current_path = os.path.split(current_path)[0]
        if os.path.isfile(os.path.join(current_path, filename)):  # found file and return
            return os.path.join(current_path, filename)
        elif os.path.dirname(current_path) == current_path:  # root of filesystem
            return
        elif n is not None and i == n:
            return
        else:  # file not found
            i += 1
            continue


Instruction:
Write a Python 3 function that can
load configuration from a text file into a single object.

Response:
def load_configuration_from_text_file(register, configuration_file):
    '''Loading configuration from text files to register object

    Parameters
    ----------
    register : pybar.fei4.register object
    configuration_file : string
        Full path (directory and filename) of the configuration file. If name is not given, reload configuration from file.
    '''
    logging.info("Loading configuration: %s" % configuration_file)
    register.configuration_file = configuration_file

    config_dict = parse_global_config(register.configuration_file)

    if 'Flavor' in config_dict:
        flavor = config_dict.pop('Flavor').lower()
        if register.flavor:
            pass
        else:
            register.init_fe_type(flavor)
    else:
        if register.flavor:
            pass
        else:
            raise ValueError('Flavor not specified')
    if 'Chip_ID' in config_dict:
        chip_id = config_dict.pop('Chip_ID')
        if register.chip_address:
            pass
        else:
            register.set_chip_address(chip_address=chip_id & 0x7, broadcast=True if chip_id & 0x8 else False)
    elif 'Chip_Address' in config_dict:
        chip_address = config_dict.pop('Chip_Address')
        if register.chip_address:
            pass
        else:
            register.set_chip_address(chip_address)
    else:
        if register.chip_id_initialized:
            pass
        else:
            raise ValueError('Chip address not specified')
    global_registers_configured = []
    pixel_registers_configured = []
    for key in config_dict.keys():
        value = config_dict.pop(key)
        if key in register.global_registers:
            register.set_global_register_value(key, value)
            global_registers_configured.append(key)
        elif key in register.pixel_registers:
            register.set_pixel_register_value(key, value)
            pixel_registers_configured.append(key)
        elif key in register.calibration_parameters:
            register.calibration_parameters[key] = value
        else:
            register.miscellaneous[key] = value

    global_registers = register.get_global_register_attributes('name', readonly=False)
    pixel_registers = register.pixel_registers.keys()
    global_registers_not_configured = set(global_registers).difference(global_registers_configured)
    pixel_registers_not_configured = set(pixel_registers).difference(pixel_registers_configured)
    if global_registers_not_configured:
        logging.warning("Following global register(s) not configured: {}".format(', '.join('\'' + reg + '\'' for reg in global_registers_not_configured)))
    if pixel_registers_not_configured:
        logging.warning("Following pixel register(s) not configured: {}".format(', '.join('\'' + reg + '\'' for reg in pixel_registers_not_configured)))
    if register.miscellaneous:
        logging.warning("Found following unknown parameter(s): {}".format(', '.join('\'' + parameter + '\'' for parameter in register.miscellaneous.iterkeys())))


Instruction:
Can you implement a function in Python 3 that
loads a configuration from a HDF5 file to a register object.

Response:
def load_configuration_from_hdf5(register, configuration_file, node=''):
    '''Loading configuration from HDF5 file to register object

    Parameters
    ----------
    register : pybar.fei4.register object
    configuration_file : string, file
        Filename of the HDF5 configuration file or file object.
    node : string
        Additional identifier (subgroup). Useful when more than one configuration is stored inside a HDF5 file.
    '''
    def load_conf():
        logging.info("Loading configuration: %s" % h5_file.filename)
        register.configuration_file = h5_file.filename
        if node:
            configuration_group = h5_file.root.configuration.node
        else:
            configuration_group = h5_file.root.configuration

        # miscellaneous
        for row in configuration_group.miscellaneous:
            name = row['name']
            try:
                value = literal_eval(row['value'])
            except ValueError:
                value = row['value']
            if name == 'Flavor':
                if register.flavor:
                    pass
                else:
                    register.init_fe_type(value)
            elif name == 'Chip_ID':
                if register.chip_address:
                    pass
                else:
                    register.set_chip_address(chip_address=value & 0x7, broadcast=True if value & 0x8 else False)
            elif name == 'Chip_Address':
                if register.chip_address:
                    pass
                else:
                    register.set_chip_address(chip_address=value, broadcast=False)
            else:
                register.miscellaneous[name] = value

        if register.flavor:
            pass
        else:
            raise ValueError('Flavor not specified')

        if register.chip_id_initialized:
            pass
        else:
            raise ValueError('Chip address not specified')

        # calibration parameters
        for row in configuration_group.calibration_parameters:
            name = row['name']
            value = row['value']
            register.calibration_parameters[name] = literal_eval(value)

        # global
        for row in configuration_group.global_register:
            name = row['name']
            value = row['value']
            register.set_global_register_value(name, literal_eval(value))

        # pixels
        for pixel_reg in h5_file.iter_nodes(configuration_group, 'CArray'):  # ['Enable', 'TDAC', 'C_High', 'C_Low', 'Imon', 'FDAC', 'EnableDigInj']:
            if pixel_reg.name in register.pixel_registers:
                register.set_pixel_register_value(pixel_reg.name, np.asarray(pixel_reg).T)  # np.asarray(h5_file.get_node(configuration_group, name=pixel_reg)).T

    if isinstance(configuration_file, tb.file.File):
        h5_file = configuration_file
        load_conf()
    else:
        with tb.open_file(configuration_file, mode="r", title='') as h5_file:
            load_conf()


Instruction:
Write a Python 3 script to
save the configuration to text files from the given register object.

Response:
def save_configuration_to_text_file(register, configuration_file):
    '''Saving configuration to text files from register object

    Parameters
    ----------
    register : pybar.fei4.register object
    configuration_file : string
        Filename of the configuration file.
    '''
    configuration_path, filename = os.path.split(configuration_file)
    if os.path.split(configuration_path)[1] == 'configs':
        configuration_path = os.path.split(configuration_path)[0]
    filename = os.path.splitext(filename)[0].strip()
    register.configuration_file = os.path.join(os.path.join(configuration_path, 'configs'), filename + ".cfg")
    if os.path.isfile(register.configuration_file):
        logging.warning("Overwriting configuration: %s", register.configuration_file)
    else:
        logging.info("Saving configuration: %s" % register.configuration_file)
    pixel_reg_dict = {}
    for path in ["tdacs", "fdacs", "masks", "configs"]:
        configuration_file_path = os.path.join(configuration_path, path)
        if not os.path.exists(configuration_file_path):
            os.makedirs(configuration_file_path)
        if path == "tdacs":
            dac = register.get_pixel_register_objects(name="TDAC")[0]
            dac_config_path = os.path.join(configuration_file_path, "_".join([dac['name'].lower(), filename]) + ".dat")
            write_pixel_dac_config(dac_config_path, dac['value'])
            pixel_reg_dict[dac['name']] = os.path.relpath(dac_config_path, os.path.dirname(register.configuration_file))
        elif path == "fdacs":
            dac = register.get_pixel_register_objects(name="FDAC")[0]
            dac_config_path = os.path.join(configuration_file_path, "_".join([dac['name'].lower(), filename]) + ".dat")
            write_pixel_dac_config(dac_config_path, dac['value'])
            pixel_reg_dict[dac['name']] = os.path.relpath(dac_config_path, os.path.dirname(register.configuration_file))
        elif path == "masks":
            masks = register.get_pixel_register_objects(bitlength=1)
            for mask in masks:
                dac_config_path = os.path.join(configuration_file_path, "_".join([mask['name'].lower(), filename]) + ".dat")
                write_pixel_mask_config(dac_config_path, mask['value'])
                pixel_reg_dict[mask['name']] = os.path.relpath(dac_config_path, os.path.dirname(register.configuration_file))
        elif path == "configs":
            with open(register.configuration_file, 'w') as f:
                lines = []
                lines.append("# FEI4 Flavor\n")
                lines.append('%s %s\n' % ('Flavor', register.flavor))
                lines.append("\n# FEI4 Chip ID\n")
                lines.append('%s %d\n' % ('Chip_ID', register.chip_id))
                lines.append("\n# FEI4 Global Registers\n")
                global_regs = register.get_global_register_objects(readonly=False)
                for global_reg in sorted(global_regs, key=itemgetter('name')):
                    lines.append('%s %d\n' % (global_reg['name'], global_reg['value']))
                lines.append("\n# FEI4 Pixel Registers\n")
                for key in sorted(pixel_reg_dict):
                    lines.append('%s %s\n' % (key, pixel_reg_dict[key]))
                lines.append("\n# FEI4 Calibration Parameters\n")
                for key in register.calibration_parameters:
                    if register.calibration_parameters[key] is None:
                        lines.append('%s %s\n' % (key, register.calibration_parameters[key]))
                    elif isinstance(register.calibration_parameters[key], (float, int, long)):
                        lines.append('%s %s\n' % (key, round(register.calibration_parameters[key], 4)))
                    elif isinstance(register.calibration_parameters[key], list):
                        lines.append('%s %s\n' % (key, [round(elem, 2) for elem in register.calibration_parameters[key]]))
                    else:
                        raise ValueError('type %s not supported' % type(register.calibration_parameters[key]))
                if register.miscellaneous:
                    lines.append("\n# Miscellaneous\n")
                    for key, value in register.miscellaneous.iteritems():
                        lines.append('%s %s\n' % (key, value))
                f.writelines(lines)


Instruction:
Write a Python 3 script for
saving a configuration to HDF5 file from register object.

Response:
def save_configuration_to_hdf5(register, configuration_file, name=''):
    '''Saving configuration to HDF5 file from register object

    Parameters
    ----------
    register : pybar.fei4.register object
    configuration_file : string, file
        Filename of the HDF5 configuration file or file object.
    name : string
        Additional identifier (subgroup). Useful when storing more than one configuration inside a HDF5 file.
    '''
    def save_conf():
        logging.info("Saving configuration: %s" % h5_file.filename)
        register.configuration_file = h5_file.filename
        try:
            configuration_group = h5_file.create_group(h5_file.root, "configuration")
        except tb.NodeError:
            configuration_group = h5_file.root.configuration
        if name:
            try:
                configuration_group = h5_file.create_group(configuration_group, name)
            except tb.NodeError:
                configuration_group = h5_file.root.configuration.name

        # calibration_parameters
        try:
            h5_file.remove_node(configuration_group, name='calibration_parameters')
        except tb.NodeError:
            pass
        calibration_data_table = h5_file.create_table(configuration_group, name='calibration_parameters', description=NameValue, title='calibration_parameters')
        calibration_data_row = calibration_data_table.row
        for key, value in register.calibration_parameters.iteritems():
            calibration_data_row['name'] = key
            calibration_data_row['value'] = str(value)
            calibration_data_row.append()
        calibration_data_table.flush()

        # miscellaneous
        try:
            h5_file.remove_node(configuration_group, name='miscellaneous')
        except tb.NodeError:
            pass
        miscellaneous_data_table = h5_file.create_table(configuration_group, name='miscellaneous', description=NameValue, title='miscellaneous')
        miscellaneous_data_row = miscellaneous_data_table.row
        miscellaneous_data_row['name'] = 'Flavor'
        miscellaneous_data_row['value'] = register.flavor
        miscellaneous_data_row.append()
        miscellaneous_data_row['name'] = 'Chip_ID'
        miscellaneous_data_row['value'] = register.chip_id
        miscellaneous_data_row.append()
        for key, value in register.miscellaneous.iteritems():
            miscellaneous_data_row['name'] = key
            miscellaneous_data_row['value'] = value
            miscellaneous_data_row.append()
        miscellaneous_data_table.flush()

        # global
        try:
            h5_file.remove_node(configuration_group, name='global_register')
        except tb.NodeError:
            pass
        global_data_table = h5_file.create_table(configuration_group, name='global_register', description=NameValue, title='global_register')
        global_data_table_row = global_data_table.row
        global_regs = register.get_global_register_objects(readonly=False)
        for global_reg in sorted(global_regs, key=itemgetter('name')):
            global_data_table_row['name'] = global_reg['name']
            global_data_table_row['value'] = global_reg['value']  # TODO: some function that converts to bin, hex
            global_data_table_row.append()
        global_data_table.flush()

        # pixel
        for pixel_reg in register.pixel_registers.itervalues():
            try:
                h5_file.remove_node(configuration_group, name=pixel_reg['name'])
            except tb.NodeError:
                pass
            data = pixel_reg['value'].T
            atom = tb.Atom.from_dtype(data.dtype)
            ds = h5_file.create_carray(configuration_group, name=pixel_reg['name'], atom=atom, shape=data.shape, title=pixel_reg['name'])
            ds[:] = data

    if isinstance(configuration_file, tb.file.File):
        h5_file = configuration_file
        save_conf()
    else:
        with tb.open_file(configuration_file, mode="a", title='') as h5_file:
            save_conf()


Instruction:
Given the following Python 3 function, write the documentation
def load_configuration(self, configuration_file):
        '''Loading configuration

        Parameters
        ----------
        configuration_file : string
            Path to the configuration file (text or HDF5 file).
        '''
        if os.path.isfile(configuration_file):
            if not isinstance(configuration_file, tb.file.File) and os.path.splitext(configuration_file)[1].strip().lower() != ".h5":
                load_configuration_from_text_file(self, configuration_file)
            else:
                load_configuration_from_hdf5(self, configuration_file)
        else:
            raise ValueError('Cannot find configuration file specified: %s' % configuration_file)

Response: Load the configuration file.


Instruction:
Make a summary of the following Python 3 code
def save_configuration(self, configuration_file):
        '''Saving configuration

        Parameters
        ----------
        configuration_file : string
            Filename of the configuration file.
        '''
        if not isinstance(configuration_file, tb.file.File) and os.path.splitext(configuration_file)[1].strip().lower() != ".h5":
            return save_configuration_to_text_file(self, configuration_file)
        else:
            return save_configuration_to_hdf5(self, configuration_file)

Response: Save the configuration file.


Instruction:
Write a Python 3 script to
get fe_command from command name and keyword arguments return list of fe_command

Response:
def get_commands(self, command_name, **kwargs):
        """get fe_command from command name and keyword arguments

        wrapper for build_commands()
        implements FEI4 specific behavior

        """
        chip_id = kwargs.pop("ChipID", self.chip_id_bitarray)
        commands = []
        if command_name == "zeros":
            bv = bitarray(endian='little')
            if "length" in kwargs:
                bv += bitarray(kwargs["length"], endian='little')  # initialized from int, bits may be random
            elif kwargs:
                raise ValueError("Unknown parameter(s): %s" % ", ".join(kwargs.iterkeys()))
            bv.setall(0)  # all bits to zero
            commands.append(bv)
        elif command_name == "ones":
            bv = bitarray(endian='little')
            if "length" in kwargs:
                bv += bitarray(kwargs["length"], endian='little')  # initialized from int, bits may be random
            elif kwargs:
                raise ValueError("Unknown parameter(s): %s" % ", ".join(kwargs.iterkeys()))
            bv.setall(1)  # all bits to one
            commands.append(bv)
        elif command_name == "WrRegister":
            register_addresses = self.get_global_register_attributes("addresses", **kwargs)
            register_bitsets = self.get_global_register_bitsets(register_addresses)
            commands.extend([self.build_command(command_name, Address=register_address, GlobalData=register_bitset, ChipID=chip_id, **kwargs) for register_address, register_bitset in zip(register_addresses, register_bitsets)])
        elif command_name == "RdRegister":
            register_addresses = self.get_global_register_attributes('addresses', **kwargs)
            commands.extend([self.build_command(command_name, Address=register_address, ChipID=chip_id) for register_address in register_addresses])
        elif command_name == "WrFrontEnd":
            registers = ["S0", "S1", "SR_Clr", "CalEn", "DIGHITIN_SEL", "GateHitOr", "ReadErrorReq", "StopClkPulse", "SR_Clock", "Efuse_Sense", "HITLD_IN", "Colpr_Mode", "Colpr_Addr"]
            if self.fei4a:
                registers.append("ReadSkipped")
            elif self.fei4b:
                registers.append("SR_Read")
            self.create_restore_point()
            dcs = kwargs.pop("dcs", range(40))  # set the double columns to latch
            # in case of empty list
            if not dcs:
                dcs = range(40)
            joint_write = kwargs.pop("joint_write", False)
            same_mask_for_all_dc = kwargs.pop("same_mask_for_all_dc", False)
            register_objects = self.get_pixel_register_objects(do_sort=['pxstrobe'], **kwargs)
            # prepare for writing pixel registers
            if not self.broadcast:
                self.set_global_register_value("Colpr_Mode", 0)  # write only to the addressed double-column
                self.set_global_register_value("Colpr_Addr", 40)  # ivalid address, grounded
                # Broadcasting ConfMode not necessary, writing registers is also possible in RunMode
#                 commands.extend(self.get_commands("ConfMode", ChipID=8))  # set all chips to conf mode to receive commands#
                # set all other chips to invalid addresses, to make broadcasting of WrRegister command possible
                commands.extend(self.get_commands("WrRegister", name=["Colpr_Mode", "Colpr_Addr"], ChipID=8))  # braodcast
            self.set_global_register_value("S0", 0)
            self.set_global_register_value("S1", 0)
            self.set_global_register_value("SR_Clr", 0)
            self.set_global_register_value("CalEn", 0)
            self.set_global_register_value("DIGHITIN_SEL", 0)
            self.set_global_register_value("GateHitOr", 0)
            self.set_global_register_value("ReadErrorReq", 0)
            self.set_global_register_value("StopClkPulse", 0)
            self.set_global_register_value("SR_Clock", 0)
            self.set_global_register_value("Efuse_Sense", 0)
            self.set_global_register_value("HITLD_IN", 0)
            self.set_global_register_value("Colpr_Mode", 3 if same_mask_for_all_dc else 0)  # write only the addressed double-column
            self.set_global_register_value("Colpr_Addr", 0)
            if self.fei4a:
                self.set_global_register_value("ReadSkipped", 0)
            elif self.fei4b:
                self.set_global_register_value("SR_Read", 0)
            commands.extend(self.get_commands("WrRegister", name=registers))

            if joint_write:
                pxstrobes = 0
                first_read = True
                do_latch = False
                for register_object in register_objects:
                    if register_object['bitlength'] != 1:
                        raise ValueError('Pixel register %s: joint write not supported for pixel DACs' % register_object['name'])
                    pxstrobe = register_object['pxstrobe']
                    if not isinstance(pxstrobe, basestring):
                        do_latch = True
                        pxstrobes += 2 ** register_object['pxstrobe']
                    if first_read:
                        pixel_reg_value = register_object['value']
                        first_read = False
                    else:
                        if np.array_equal(pixel_reg_value, register_object['value']):
                            pixel_reg_value = register_object['value']
                        else:
                            raise ValueError('Pixel register %s: joint write not supported, pixel register values must be equal' % register_object['name'])
                if do_latch:
                    self.set_global_register_value("Latch_En", 1)
                else:
                    self.set_global_register_value("Latch_En", 0)
                self.set_global_register_value("Pixel_Strobes", pxstrobes)
                commands.extend(self.get_commands("WrRegister", name=["Pixel_Strobes", "Latch_En"]))
                for dc_no in (dcs[:1] if same_mask_for_all_dc else dcs):
                    self.set_global_register_value("Colpr_Addr", dc_no)
                    commands.extend(self.get_commands("WrRegister", name=["Colpr_Addr"]))
                    register_bitset = self.get_pixel_register_bitset(register_objects[0], 0, dc_no)
                    commands.extend([self.build_command(command_name, PixelData=register_bitset, ChipID=8, **kwargs)])  # broadcast
                    if do_latch:
                        commands.extend(self.get_commands("GlobalPulse", Width=0))
            else:
                for register_object in register_objects:
                    pxstrobe = register_object['pxstrobe']
                    if isinstance(pxstrobe, basestring):
                        do_latch = False
                        self.set_global_register_value("Pixel_Strobes", 0)  # no latch
                        self.set_global_register_value("Latch_En", 0)
                        commands.extend(self.get_commands("WrRegister", name=["Pixel_Strobes", "Latch_En"]))
                    else:
                        do_latch = True
                        self.set_global_register_value("Latch_En", 1)
                        commands.extend(self.get_commands("WrRegister", name=["Latch_En"]))
                    bitlength = register_object['bitlength']
                    for bit_no, pxstrobe_bit_no in (enumerate(range(bitlength)) if (register_object['littleendian'] is False) else enumerate(reversed(range(bitlength)))):
                        if do_latch:
                            self.set_global_register_value("Pixel_Strobes", 2 ** (pxstrobe + bit_no))
                            commands.extend(self.get_commands("WrRegister", name=["Pixel_Strobes"]))
                        for dc_no in (dcs[:1] if same_mask_for_all_dc else dcs):
                            self.set_global_register_value("Colpr_Addr", dc_no)
                            commands.extend(self.get_commands("WrRegister", name=["Colpr_Addr"]))
                            register_bitset = self.get_pixel_register_bitset(register_object, pxstrobe_bit_no, dc_no)
                            commands.extend([self.build_command(command_name, PixelData=register_bitset, ChipID=8, **kwargs)])  # broadcast
                            if do_latch:
                                commands.extend(self.get_commands("GlobalPulse", Width=0))
            self.restore(pixel_register=False)
            commands.extend(self.get_commands("WrRegister", name=registers))
        elif command_name == "RdFrontEnd":
            registers = ["Conf_AddrEnable", "S0", "S1", "SR_Clr", "CalEn", "DIGHITIN_SEL", "GateHitOr", "ReadErrorReq", "StopClkPulse", "SR_Clock", "Efuse_Sense", "HITLD_IN", "Colpr_Mode", "Colpr_Addr", "Pixel_Strobes", "Latch_En"]
            if self.fei4a:
                registers.append("ReadSkipped")
            elif self.fei4b:
                registers.append("SR_Read")
            self.create_restore_point()
            dcs = kwargs.pop("dcs", range(40))  # set the double columns to latch
            # in case of empty list
            if not dcs:
                dcs = range(40)
            register_objects = self.get_pixel_register_objects(**kwargs)
            self.set_global_register_value('Conf_AddrEnable', 1)
            self.set_global_register_value("S0", 0)
            self.set_global_register_value("S1", 0)
            self.set_global_register_value("SR_Clr", 0)
            if self.fei4b:
                self.set_global_register_value("SR_Read", 0)
            self.set_global_register_value("CalEn", 0)
            self.set_global_register_value("DIGHITIN_SEL", 0)
            self.set_global_register_value("GateHitOr", 0)
            if self.fei4a:
                self.set_global_register_value("ReadSkipped", 0)
            self.set_global_register_value("ReadErrorReq", 0)
            self.set_global_register_value("StopClkPulse", 0)
            self.set_global_register_value("SR_Clock", 0)
            self.set_global_register_value("Efuse_Sense", 0)
            self.set_global_register_value("HITLD_IN", 0)
            self.set_global_register_value("Colpr_Mode", 0)  # write only the addressed double-column
            self.set_global_register_value("Colpr_Addr", 0)
            self.set_global_register_value("Latch_En", 0)
            self.set_global_register_value("Pixel_Strobes", 0)
            commands.extend(self.get_commands("WrRegister", name=registers))
            for index, register_object in enumerate(register_objects):  # make sure that EnableDigInj is first read back, because it is not latched
                if register_object['name'] == 'EnableDigInj':
                    register_objects[0], register_objects[index] = register_objects[index], register_objects[0]
                    break
            for register_object in register_objects:
                pxstrobe = register_object['pxstrobe']
                bitlength = register_object['bitlength']
                for pxstrobe_bit_no in range(bitlength):
                    logging.debug('Pixel Register %s Bit %d', register_object['name'], pxstrobe_bit_no)
                    do_latch = True
                    try:
                        self.set_global_register_value("Pixel_Strobes", 2 ** (pxstrobe + pxstrobe_bit_no))
                    except TypeError:  # thrown for not latched digInjection
                        self.set_global_register_value("Pixel_Strobes", 0)  # do not latch
                        do_latch = False
                    commands.extend(self.get_commands("WrRegister", name=["Pixel_Strobes"]))
                    for dc_no in dcs:
                        self.set_global_register_value("Colpr_Addr", dc_no)
                        commands.extend(self.get_commands("WrRegister", name=["Colpr_Addr"]))
                        if do_latch is True:
                            self.set_global_register_value("S0", 1)
                            self.set_global_register_value("S1", 1)
                            self.set_global_register_value("SR_Clock", 1)
                            commands.extend(self.get_commands("WrRegister", name=["S0", "S1", "SR_Clock"]))
                            commands.extend(self.get_commands("GlobalPulse", Width=0))
                        self.set_global_register_value("S0", 0)
                        self.set_global_register_value("S1", 0)
                        self.set_global_register_value("SR_Clock", 0)
                        commands.extend(self.get_commands("WrRegister", name=["S0", "S1", "SR_Clock"]))
                        register_bitset = self.get_pixel_register_bitset(register_object, pxstrobe_bit_no if (register_object['littleendian'] is False) else register_object['bitlength'] - pxstrobe_bit_no - 1, dc_no)
                        if self.fei4b:
                            self.set_global_register_value("SR_Read", 1)
                            commands.extend(self.get_commands("WrRegister", name=["SR_Read"]))
                        commands.extend([self.build_command("WrFrontEnd", PixelData=register_bitset, ChipID=chip_id)])
                        if self.fei4b:
                            self.set_global_register_value("SR_Read", 0)
                            commands.extend(self.get_commands("WrRegister", name=["SR_Read"]))
            self.restore(pixel_register=False)
            commands.extend(self.get_commands("WrRegister", name=registers))
        else:
            commands.append(self.build_command(command_name, ChipID=chip_id, **kwargs))
        return commands


Instruction:
Create a Python 3 function for
building command from command_name and keyword values Returns list of bitarrays.

Response:
def build_command(self, command_name, **kwargs):
        """build command from command_name and keyword values

        Returns
        -------
        command_bitvector : list
            List of bitarrays.

        Usage
        -----
        Receives: command name as defined inside xml file, key-value-pairs as defined inside bit stream filed for each command
        """
#         command_name = command_name.lower()
        command_bitvector = bitarray(0, endian='little')
        if command_name not in self.commands:
            raise ValueError('Unknown command %s' % command_name)
        command_object = self.commands[command_name]
        command_parts = re.split(r'\s*[+]\s*', command_object['bitstream'])
        # for index, part in enumerate(command_parts, start = 1): # loop over command parts
        for part in command_parts:  # loop over command parts
            try:
                command_part_object = self.commands[part]
            except KeyError:
                command_part_object = None
            if command_part_object and 'bitstream'in command_part_object:  # command parts of defined content and length, e.g. Slow, ...
                if string_is_binary(command_part_object['bitstream']):
                    command_bitvector += bitarray(command_part_object['bitstream'], endian='little')
                else:
                    command_bitvector += self.build_command(part, **kwargs)
            elif command_part_object:  # Command parts with any content of defined length, e.g. ChipID, Address, ...
                if part in kwargs:
                    value = kwargs[part]
                else:
                    raise ValueError('Value of command part %s not given' % part)
                try:
                    command_bitvector += value
                except TypeError:  # value is no bitarray
                    if string_is_binary(value):
                        value = int(value, 2)
                    try:
                        command_bitvector += bitarray_from_value(value=int(value), size=command_part_object['bitlength'], fmt='I')
                    except Exception:
                        raise TypeError("Type of value not supported")
            elif string_is_binary(part):
                command_bitvector += bitarray(part, endian='little')
            # elif part in kwargs.keys():
            #    command_bitvector += kwargs[command_name]
            else:
                raise ValueError("Cannot process command part %s" % part)
        if command_bitvector.length() != command_object['bitlength']:
            raise ValueError("Command has unexpected length")
        if command_bitvector.length() == 0:
            raise ValueError("Command has length 0")
        return command_bitvector


Instruction:
How would you code a function in Python 3 to
return a list of attributes that are not in the global register.

Response:
def get_global_register_attributes(self, register_attribute, do_sort=True, **kwargs):
        """Calculating register numbers from register names.

        Usage: get_global_register_attributes("attribute_name", name = [regname_1, regname_2, ...], addresses = 2)
        Receives: attribute name to be returned, dictionaries (kwargs) of register attributes and values for making cuts
        Returns: list of attribute values that matches dictionaries of attributes

        """
        # speed up of the most often used keyword name
        try:
            names = iterable(kwargs.pop('name'))
        except KeyError:
            register_attribute_list = []
        else:
            register_attribute_list = [self.global_registers[reg][register_attribute] for reg in names]
        for keyword in kwargs.keys():
            allowed_values = iterable(kwargs[keyword])
            try:
                register_attribute_list.extend(map(itemgetter(register_attribute), filter(lambda global_register: set(iterable(global_register[keyword])).intersection(allowed_values), self.global_registers.itervalues())))
            except AttributeError:
                pass
        if not register_attribute_list and filter(None, kwargs.itervalues()):
            raise ValueError('Global register attribute %s empty' % register_attribute)
        if do_sort:
            return sorted(set(flatten_iterable(register_attribute_list)))
        else:
            return flatten_iterable(register_attribute_list)


Instruction:
Write a Python 3 function for
generating register objects from register names list

Response:
def get_global_register_objects(self, do_sort=None, reverse=False, **kwargs):
        """Generate register objects (list) from register name list

        Usage: get_global_register_objects(name = ["Amp2Vbn", "GateHitOr", "DisableColumnCnfg"], address = [2, 3])
        Receives: keyword lists of register names, addresses,... for making cuts
        Returns: list of register objects

        """
        # speed up of the most often used keyword name
        try:
            names = iterable(kwargs.pop('name'))
        except KeyError:
            register_objects = []
        else:
            register_objects = [self.global_registers[reg] for reg in names]
        for keyword in kwargs.iterkeys():
            allowed_values = iterable(kwargs[keyword])
            register_objects.extend(filter(lambda global_register: set(iterable(global_register[keyword])).intersection(allowed_values), self.global_registers.itervalues()))
        if not register_objects and filter(None, kwargs.itervalues()):
            raise ValueError('Global register objects empty')
        if do_sort:
            return sorted(register_objects, key=itemgetter(*do_sort), reverse=reverse)
        else:
            return register_objects


Instruction:
Can you tell what is the following Python 3 function doing
def get_global_register_bitsets(self, register_addresses):  # TOTO: add sorting
        register_bitsets = []
        for register_address in register_addresses:
            register_objects = self.get_global_register_objects(addresses=register_address)
            register_bitset = bitarray(16, endian='little')  # TODO remove hardcoded register size, see also below
            register_bitset.setall(0)
            register_littleendian = False
            for register_object in register_objects:
                if register_object['register_littleendian']:  # check for register endianness
                    register_littleendian = True
                if (16 * register_object['address'] + register_object['offset'] < 16 * (register_address + 1) and 16 * register_object['address'] + register_object['offset'] + register_object['bitlength'] > 16 * register_address):
                    reg = bitarray_from_value(value=register_object['value'], size=register_object['bitlength'])
                    if register_object['littleendian']:
                        reg.reverse()
# register_bitset[max(0, 16 * (register_object['address'] - register_address) + register_object['offset']):min(16, 16 * (register_object['address'] - register_address) + register_object['offset'] + register_object['bitlength'])] |= reg[max(0, 16 * (register_address - register_object['address']) - register_object['offset']):min(register_object['bitlength'], 16 * (register_address - register_object['address'] + 1) - register_object['offset'])]  # [ bit(n) bit(n-1)... bit(0) ]
                    register_bitset[max(0, 16 - 16 * (register_object['address'] - register_address) - register_object['offset'] - register_object['bitlength']):min(16, 16 - 16 * (register_object['address'] - register_address) - register_object['offset'])] |= reg[max(0, register_object['bitlength'] - 16 - 16 * (register_address - register_object['address']) + register_object['offset']):min(register_object['bitlength'], register_object['bitlength'] + 16 - 16 * (register_address - register_object['address'] + 1) + register_object['offset'])]  # [ bit(0)... bit(n-1) bit(n) ]
                else:
                    raise Exception("wrong register object")
            if register_littleendian:
                register_bitset.reverse()
            register_bitsets.append(register_bitset)
        return register_bitsets

Response: This function returns a list of register bitsets that are in the global register table.


Instruction:
Given the following Python 3 function, write the documentation
def get_pixel_register_objects(self, do_sort=None, reverse=False, **kwargs):
        # speed up of the most often used keyword name
        try:
            names = iterable(kwargs.pop('name'))
        except KeyError:
            register_objects = []
        else:
            register_objects = [self.pixel_registers[reg] for reg in names]
        for keyword in kwargs.iterkeys():
            allowed_values = iterable(kwargs[keyword])
            register_objects.extend(filter(lambda pixel_register: pixel_register[keyword] in allowed_values, self.pixel_registers.itervalues()))
        if not register_objects and filter(None, kwargs.itervalues()):
            raise ValueError('Pixel register objects empty')
        if do_sort:
            return sorted(register_objects, key=itemgetter(*do_sort), reverse=reverse)
        else:
            return register_objects

Response: Generate register objects from register name list


Instruction:
Can you tell what is the following Python 3 function doing
def get_pixel_register_bitset(self, register_object, bit_no, dc_no):
        if not 0 <= dc_no < 40:
            raise ValueError("Pixel register %s: DC out of range" % register_object['name'])
        if not 0 <= bit_no < register_object['bitlength']:
            raise ValueError("Pixel register %s: bit number out of range" % register_object['name'])
        col0 = register_object['value'][dc_no * 2, :]
        sel0 = (2 ** bit_no == (col0 & 2 ** bit_no))
        bv0 = bitarray(sel0.tolist(), endian='little')
        col1 = register_object['value'][dc_no * 2 + 1, :]
        sel1 = (2 ** bit_no == (col1 & 2 ** bit_no))
        # sel1 = sel1.astype(numpy.uint8) # copy of array
        # sel1 = sel1.view(dtype=np.uint8) # in-place type conversion
        bv1 = bitarray(sel1.tolist(), endian='little')
        bv1.reverse()  # shifted first
        # bv = bv1+bv0
        return bv1 + bv0

Response: This function calculates the bitset of the specified register bit number from the given double column number.


Instruction:
Make a summary of the following Python 3 code
def create_restore_point(self, name=None):
        '''Creating a configuration restore point.

        Parameters
        ----------
        name : str
            Name of the restore point. If not given, a md5 hash will be generated.
        '''
        if name is None:
            for i in iter(int, 1):
                name = datetime.datetime.utcnow().strftime('%Y%m%d%H%M%S%f') + '_' + str(i)
                try:
                    self.config_state[name]
                except KeyError:
                    break
                else:
                    pass
        if name in self.config_state:
            raise ValueError('Restore point %s already exists' % name)
        self.config_state[name] = (copy.deepcopy(self.global_registers), copy.deepcopy(self.pixel_registers))
        return name

Response: Creates a new configuration restore point.


Instruction:
Make a summary of the following Python 3 code
def restore(self, name=None, keep=False, last=True, global_register=True, pixel_register=True):
        '''Restoring a configuration restore point.

        Parameters
        ----------
        name : str
            Name of the restore point. If not given, a md5 hash will be generated.
        keep : bool
            Keeping restore point for later use.
        last : bool
            If name is not given, the latest restore point will be taken.
        global_register : bool
            Restore global register.
        pixel_register : bool
            Restore pixel register.
        '''
        if name is None:
            if keep:
                name = next(reversed(self.config_state)) if last else next(iter(self.config_state))
                value = self.config_state[name]
            else:
                name, value = self.config_state.popitem(last=last)
        else:
            value = self.config_state[name]
            if not keep:
                value = copy.deepcopy(value)  # make a copy before deleting object
                del self.config_state[name]

        if global_register:
            self.global_registers = copy.deepcopy(value[0])
        if pixel_register:
            self.pixel_registers = copy.deepcopy(value[1])

Response: Restores a configuration restore point.


Instruction:
Write a Python 3 function for
clearing all configuration restore points and point.

Response:
def clear_restore_points(self, name=None):
        '''Deleting all/a configuration restore points/point.

        Parameters
        ----------
        name : str
            Name of the restore point to be deleted. If not given, all restore points will be deleted.
        '''
        if name is None:
            self.config_state.clear()
        else:
            del self.config_state[name]


Instruction:
Here you have a function in Python 3, explain what it does
def save_configuration_dict(h5_file, configuation_name, configuration, **kwargs):
    '''Stores any configuration dictionary to HDF5 file.

    Parameters
    ----------
    h5_file : string, file
        Filename of the HDF5 configuration file or file object.
    configuation_name : str
        Configuration name. Will be used for table name.
    configuration : dict
        Configuration dictionary.
    '''
    def save_conf():
        try:
            h5_file.remove_node(h5_file.root.configuration, name=configuation_name)
        except tb.NodeError:
            pass
        try:
            configuration_group = h5_file.create_group(h5_file.root, "configuration")
        except tb.NodeError:
            configuration_group = h5_file.root.configuration

        scan_param_table = h5_file.create_table(configuration_group, name=configuation_name, description=NameValue, title=configuation_name)
        row_scan_param = scan_param_table.row
        for key, value in dict.iteritems(configuration):
            row_scan_param['name'] = key
            row_scan_param['value'] = str(value)
            row_scan_param.append()
        scan_param_table.flush()

    if isinstance(h5_file, tb.file.File):
        save_conf()
    else:
        if os.path.splitext(h5_file)[1].strip().lower() != ".h5":
            h5_file = os.path.splitext(h5_file)[0] + ".h5"
        with tb.open_file(h5_file, mode="a", title='', **kwargs) as h5_file:
            save_conf()

Response: Stores any configuration dictionary to HDF5 file.


Instruction:
Write a Python 3 function that can
filter and convert raw data numpy array.

Response:
def convert_data_array(array, filter_func=None, converter_func=None):  # TODO: add copy parameter, otherwise in-place
    '''Filter and convert raw data numpy array (numpy.ndarray).

    Parameters
    ----------
    array : numpy.array
        Raw data array.
    filter_func : function
        Function that takes array and returns true or false for each item in array.
    converter_func : function
        Function that takes array and returns an array or tuple of arrays.

    Returns
    -------
    data_array : numpy.array
        Data numpy array of specified dimension (converter_func) and content (filter_func)
    '''
#     if filter_func != None:
#         if not hasattr(filter_func, '__call__'):
#             raise ValueError('Filter is not callable')
    if filter_func:
        array = array[filter_func(array)]
#     if converter_func != None:
#         if not hasattr(converter_func, '__call__'):
#             raise ValueError('Converter is not callable')
    if converter_func:
        array = converter_func(array)
    return array


Instruction:
Create a Python 3 function to
convert raw data in data iterable.

Response:
def convert_data_iterable(data_iterable, filter_func=None, converter_func=None):  # TODO: add concatenate parameter
    '''Convert raw data in data iterable.

    Parameters
    ----------
    data_iterable : iterable
        Iterable where each element is a tuple with following content: (raw data, timestamp_start, timestamp_stop, status).
    filter_func : function
        Function that takes array and returns true or false for each item in array.
    converter_func : function
        Function that takes array and returns an array or tuple of arrays.

    Returns
    -------
    data_list : list
        Data list of the form [(converted data, timestamp_start, timestamp_stop, status), (...), ...]
    '''
    data_list = []
    for item in data_iterable:
        data_list.append((convert_data_array(item[0], filter_func=filter_func, converter_func=converter_func), item[1], item[2], item[3]))
    return data_list


Instruction:
Explain what the following Python 3 code does
def data_array_from_data_iterable(data_iterable):
    '''Convert data iterable to raw data numpy array.

    Parameters
    ----------
    data_iterable : iterable
        Iterable where each element is a tuple with following content: (raw data, timestamp_start, timestamp_stop, status).

    Returns
    -------
    data_array : numpy.array
        concatenated data array
    '''
    try:
        data_array = np.concatenate([item[0] for item in data_iterable])
    except ValueError:  # length is 0
        data_array = np.empty(0, dtype=np.uint32)
    return data_array

Response: Convert data iterable to raw data numpy array.


Instruction:
Write a Python 3 script for
converting TDC words at a given channel to common TDC header ( 0x4.

Response:
def convert_tdc_to_channel(channel):
    ''' Converts TDC words at a given channel to common TDC header (0x4).
    '''
    def f(value):
        filter_func = logical_and(is_tdc_word, is_tdc_from_channel(channel))
        select = filter_func(value)
        value[select] = np.bitwise_and(value[select], 0x0FFFFFFF)
        value[select] = np.bitwise_or(value[select], 0x40000000)
        f.__name__ = "convert_tdc_to_channel_" + str(channel)
        return value
    return f


Instruction:
Write a Python 3 function for
returning a function that returns True if the FE data is from the given channel.

Response:
def is_data_from_channel(channel=4):  # function factory
    '''Selecting FE data from given channel.

    Parameters
    ----------
    channel : int
        Channel number (4 is default channel on Single Chip Card).

    Returns
    -------
    Function.

    Usage:
    1 Selecting FE data from channel 4 (combine with is_fe_word):
        filter_fe_data_from_channel_4 = logical_and(is_fe_word, is_data_from_channel(4))
        fe_data_from_channel_4 = data_array[filter_fe_data_from_channel_4(data_array)]
    2 Sleceting data from channel 4:
        filter_data_from_channel_4 = is_data_from_channel(4)
        data_from_channel_4 = data_array[filter_data_from_channel_4(fe_data_array)]
    3 Sleceting data from channel 4:
        data_from_channel_4 = is_data_from_channel(4)(fe_raw_data)

    Other usage:
    f_ch4 = functoools.partial(is_data_from_channel, channel=4)
    l_ch4 = lambda x: is_data_from_channel(x, channel=4)
    '''
    if channel >= 0 and channel < 16:
        def f(value):
            return np.equal(np.right_shift(np.bitwise_and(value, 0x0F000000), 24), channel)
        f.__name__ = "is_data_from_channel_" + str(channel)  # or use inspect module: inspect.stack()[0][3]
        return f
    else:
        raise ValueError('Invalid channel number')


Instruction:
How would you explain what the following Python 3 function does
def logical_and(f1, f2):  # function factory
    '''Logical and from functions.

    Parameters
    ----------
    f1, f2 : function
        Function that takes array and returns true or false for each item in array.

    Returns
    -------
    Function.

    Usage:
    filter_func=logical_and(is_data_record, is_data_from_channel(4))  # new filter function
    filter_func(array) # array that has Data Records from channel 4
    '''
    def f(value):
        return np.logical_and(f1(value), f2(value))
    f.__name__ = "(" + f1.__name__ + "_and_" + f2.__name__ + ")"
    return f

Response: Logical and from functions.


Instruction:
Implement a Python 3 function for
returning a function that returns true or false for each item in array f1 and f2.

Response:
def logical_or(f1, f2):  # function factory
    '''Logical or from functions.

    Parameters
    ----------
    f1, f2 : function
        Function that takes array and returns true or false for each item in array.

    Returns
    -------
    Function.
    '''
    def f(value):
        return np.logical_or(f1(value), f2(value))
    f.__name__ = "(" + f1.__name__ + "_or_" + f2.__name__ + ")"
    return f


Instruction:
Here you have a function in Python 3, explain what it does
def logical_not(f):  # function factory
    '''Logical not from functions.

    Parameters
    ----------
    f1, f2 : function
        Function that takes array and returns true or false for each item in array.

    Returns
    -------
    Function.
    '''
    def f(value):
        return np.logical_not(f(value))
    f.__name__ = "not_" + f.__name__
    return f

Response: Returns a function that returns true or false for each item in array f1 and f2.


Instruction:
Here you have a function in Python 3, explain what it does
def logical_xor(f1, f2):  # function factory
    '''Logical xor from functions.

    Parameters
    ----------
    f1, f2 : function
        Function that takes array and returns true or false for each item in array.

    Returns
    -------
    Function.
    '''
    def f(value):
        return np.logical_xor(f1(value), f2(value))
    f.__name__ = "(" + f1.__name__ + "_xor_" + f2.__name__ + ")"
    return f

Response:
Logical xor from functions.

    Parameters
    ----------
    f1, f2 : function
        Function that takes array and returns true or false for each item in array.

    Returns
    -------
    Function.


Instruction:
Can you write a function in Python 3 where it
returns 31bit timestamp and 16bit trigger counter

Response:
def get_trigger_data(value, mode=0):
    '''Returns 31bit trigger counter (mode=0), 31bit timestamp (mode=1), 15bit timestamp and 16bit trigger counter (mode=2)
    '''
    if mode == 2:
        return np.right_shift(np.bitwise_and(value, 0x7FFF0000), 16), np.bitwise_and(value, 0x0000FFFF)
    else:
        return np.bitwise_and(value, 0x7FFFFFFF)


Instruction:
Can you tell what is the following Python 3 function doing
def get_col_row_tot_array_from_data_record_array(array):  # TODO: max ToT
    '''Convert raw data array to column, row, and ToT array.

    Parameters
    ----------
    array : numpy.array
        Raw data array.

    Returns
    -------
    Tuple of arrays.
    '''
    def get_col_row_tot_1_array_from_data_record_array(value):
        return np.right_shift(np.bitwise_and(value, 0x00FE0000), 17), np.right_shift(np.bitwise_and(value, 0x0001FF00), 8), np.right_shift(np.bitwise_and(value, 0x000000F0), 4)

    def get_col_row_tot_2_array_from_data_record_array(value):
        return np.right_shift(np.bitwise_and(value, 0x00FE0000), 17), np.add(np.right_shift(np.bitwise_and(value, 0x0001FF00), 8), 1), np.bitwise_and(value, 0x0000000F)

    col_row_tot_1_array = np.column_stack(get_col_row_tot_1_array_from_data_record_array(array))
    col_row_tot_2_array = np.column_stack(get_col_row_tot_2_array_from_data_record_array(array))
    # interweave array here
    col_row_tot_array = np.vstack((col_row_tot_1_array.T, col_row_tot_2_array.T)).reshape((3, -1), order='F').T  # http://stackoverflow.com/questions/5347065/interweaving-two-numpy-arrays
    # remove ToT > 14 (late hit, no hit) from array, remove row > 336 in case we saw hit in row 336 (no double hit possible)
    try:
        col_row_tot_array_filtered = col_row_tot_array[col_row_tot_array[:, 2] < 14]  # [np.logical_and(col_row_tot_array[:,2]<14, col_row_tot_array[:,1]<=336)]
    except IndexError:
        # logging.warning('Array is empty')
        return np.array([], dtype=np.dtype('>u4')), np.array([], dtype=np.dtype('>u4')), np.array([], dtype=np.dtype('>u4'))
    return col_row_tot_array_filtered[:, 0], col_row_tot_array_filtered[:, 1], col_row_tot_array_filtered[:, 2]

Response: Convert raw data array to column row and ToT array.