Пример #1
0
    def test_plotting(self):
        # create a basic plot, request the layout and data, then create a plotly figure
        test = BasicPlot(x_label='Test', y_label='Test Y', graph_height=400, graph_width=400, marker_size=6.0,
                         layout={'plot_bgcolor': '#fff'}, figure_border=1, x_min=0, x_max=2.0, y_min=0, y_max=2.0)

        # now add some data
        test.add_data(x_data=[0.1, 0.2], y_data=[0.5, 0.6], error_x={'type': 'data', 'array': [0.05, 0.05], 'visible': True},
                      mode='markers+lines', name='testing', text='testing_text')

        test_plot = test.get_plot(as_figure=True)

        # fig = go.Figure(
        #     data=[go.Bar(y=[2, 1, 3])],
        #     layout_title_text="A Figure Displayed with the 'png' Renderer"
        # )
        # fig.show(renderer="png")

        # fig = go.Figure(data=test_plot['data'], layout=test_plot['layout'])

        test_plot.write_image('test.svg')

        # plot(fig)
        # fig.show(renderer='png')

        a = 5
Пример #2
0
    def init_plot(self, x_label, y_label, x_scale, y_scale):

        self.plot = BasicPlot(x_label=x_label,
                              y_label=y_label,
                              x_scale=x_scale,
                              y_scale=y_scale,
                              graph_height=self.graph_height,
                              graph_width=self.graph_width)
Пример #3
0
    def init_plot(self, x_label, y_label, x_scale, y_scale):

        self.plot = BasicPlot(x_label=x_label, y_label=y_label, x_scale=x_scale, y_scale=y_scale,
                              graph_height=self.graph_height, graph_width=self.graph_width, marker_shapes=('circle',))

        # make the plot only have circles
        self.plot.marker['size'] = 8
Пример #4
0
    def save_tlm_plots(self):
        """
        Saves TLM plots for this TLM instance at all Vd values. This includes R vs. Length, Rc vs. n, Rsheet vs. n

        """
        for i, vd in enumerate(self.vd_values):

            new_dataset = self.tlm_datasets[vd]

            # now we can start computing TLM properties
            n_full = new_dataset.get_column('n')

            # get the column with the lowest max min
            min_max_n_col = np.argmin(np.max(n_full, axis=1))
            # get the min_max n value
            min_max_n = np.min(np.max(n_full, axis=1))
            # now get the min n value from the column with the min_max_n.  This is important to ensure we get a rectangular n array
            max_min_n = np.partition(
                n_full[min_max_n_col][np.where(
                    n_full[min_max_n_col, :] >= 1.0)[0]], 2)[2]
            # value = 989429999999.9993 = 9.89e+11

            # expr: np.where((n_full[1]>max_min_n) & (n_full[1]<min_max_n))
            # looks like for n_full[1] range is 29-122 with gap 68-83 for total of 78 values
            # n_full[0]: 37-114, missing 75-76 for total 76 values
            # n_full[2]: 31-120, missing 68-83 for total 76 values
            n = new_dataset.get_column('n',
                                       master_independent_value_range=[
                                           max_min_n, min_max_n.magnitude
                                       ])

            # check to make sure the n values are close enough.  If the Vg step is not fine enough and the device Vts are hihgly varied, the n values may not be close enough
            # to extract TLM data at a specific n
            max_n_varience = np.max(n[:, 1]) - np.min(n[:, 1])
            assert max_n_varience < self.maximum_n_varience, 'Varience in carrier density between the devices is {0}, which is greater than {1}.  As such,' \
                                                             'accurate TLM extraction is not possible.  This could be the result of too small a gate' \
                                                             'voltage step and high varience between device threshold voltages.  You can try to remove ' \
                                                             'device data with high varience, or lower the maximum_n_varience value in the' \
                                                             'TLMExtractor object.'.format(max_n_varience, self.maximum_n_varience)

            n_r = np.round(np.array(n, dtype=float) * 1e-12)
            r = new_dataset.get_column('r',
                                       master_independent_value_range=[
                                           max_min_n, min_max_n.magnitude
                                       ])
            l = new_dataset.get_column('l',
                                       master_independent_value_range=[
                                           max_min_n, min_max_n.magnitude
                                       ])

            n_units = '10<sup>12</sup> cm<sup>-2</sup>'
            r_units = '\u03A9\u2022\u03BCm'  # ;&times;&mu;m'
            l_units = '\u03BCm'
            # create_scatter_plot(l[:, 0], r[:, 0], scale='lin', show=True, autoscale=True)

            r_sheet, r_sheet_error, rc, rc_error = self.linear_regression(l, r)

            # now add r_sheet and rc to the dataset
            # new_dataset.add_column()
            max_l = float(max(l[:, 0]))

            r_plot = BasicPlot(x_label='length {0}'.format(l_units),
                               y_label='total resistance {0}'.format(r_units),
                               marker_size=8.0,
                               x_min=0.0,
                               x_max=max_l * 1.2)

            for i in range(0, len(n[0]), round(len(n[0]) / 5)):
                r_plot.add_data(x_data=l[:, i],
                                y_data=r[:, i],
                                mode='markers',
                                name='n = {0} {1}'.format(n_r[0][i], n_units),
                                text='n')
                r_plot.add_line(x_data=[0.0, max_l],
                                y_data=[float(rc[i]),
                                        float(r[-1, i])],
                                name=None)

            r_plot.save_plot(name='r_at_vd_{0}'.format(vd))

            rc_plot = BasicPlot(
                x_label='carrier density {0}'.format(n_units),
                y_label='contact resistance {0}'.format(r_units),
                marker_size=8.0)

            rc_plot.add_data(x_data=n[0] * 1e-12,
                             y_data=rc,
                             error_y={
                                 'type': 'data',
                                 'array': np.array(rc_error, dtype=float),
                                 'visible': True
                             },
                             mode='markers',
                             name='n',
                             text='n')

            rc_plot.save_plot(name='rc_at_vd_{0}'.format(vd))

            rsheet_plot = BasicPlot(
                x_label='carrier density {0}'.format(n_units),
                y_label='sheet resistance',
                marker_size=8.0)

            rsheet_plot.add_data(x_data=n[0] * 1e-12,
                                 y_data=r_sheet,
                                 error_y={
                                     'type': 'data',
                                     'array': np.array(r_sheet_error,
                                                       dtype=float),
                                     'visible': True
                                 },
                                 mode='markers',
                                 name='n',
                                 text='n')

            rsheet_plot.save_plot(name='rsheet_at_vd_{0}'.format(vd))
Пример #5
0
    def save_tlm_plots(self):
        """
        Saves TLM plots for this TLM instance at all Vd values. This includes R vs. Length, Rc vs. n, Rsheet vs. n

        """
        for i, vd in enumerate(self.vd_values):

            new_dataset = self.tlm_datasets[vd]

            # now we can start computing TLM properties
            n_full = new_dataset.get_column('n')
            # grab the min max of n and the max min of n
            min_max_n = np.min(np.max(n_full, axis=1))
            max_min_n = np.max([
                np.min(n_full[i][np.where(n_full[i, :] >= 1.0)[0]])
                for i in range(n_full.shape[0])
            ])
            n = new_dataset.get_column(
                'n',
                master_independent_value_range=[max_min_n, min_max_n.value])
            n_r = np.round(np.array(n, dtype=float) * 1e-12)
            r = new_dataset.get_column(
                'r',
                master_independent_value_range=[max_min_n, min_max_n.value])
            l = new_dataset.get_column(
                'l',
                master_independent_value_range=[max_min_n, min_max_n.value])

            n_units = '10<sup>12</sup> cm<sup>-2</sup>'
            r_units = '\u03A9\u2022\u03BCm'  # ;&times;&mu;m'
            l_units = '\u03BCm'
            # create_scatter_plot(l[:, 0], r[:, 0], scale='lin', show=True, autoscale=True)

            r_sheet, r_sheet_error, rc, rc_error = self.linear_regression(l, r)

            # now add r_sheet and rc to the dataset
            # new_dataset.add_column()
            max_l = float(max(l[:, 0]))

            r_plot = BasicPlot(x_label='length {0}'.format(l_units),
                               y_label='total resistance {0}'.format(r_units),
                               marker_size=8.0,
                               x_min=0.0,
                               x_max=max_l * 1.2)

            for i in range(0, len(n[0]), round(len(n[0]) / 5)):
                r_plot.add_data(x_data=l[:, i],
                                y_data=r[:, i],
                                mode='markers',
                                name='n = {0} {1}'.format(n_r[0][i], n_units),
                                text='n')
                r_plot.add_line(x_data=[0.0, max_l],
                                y_data=[float(rc[i]),
                                        float(r[-1, i])],
                                name=None)

            r_plot.save_plot(name='r_at_vd_{0}'.format(vd))

            rc_plot = BasicPlot(
                x_label='carrier density {0}'.format(n_units),
                y_label='contact resistance {0}'.format(r_units),
                marker_size=8.0)

            rc_plot.add_data(x_data=n[0] * 1e-12,
                             y_data=rc,
                             error_y={
                                 'type': 'data',
                                 'array': np.array(rc_error, dtype=float),
                                 'visible': True
                             },
                             mode='markers',
                             name='n',
                             text='n')

            rc_plot.save_plot(name='rc_at_vd_{0}'.format(vd))

            rsheet_plot = BasicPlot(
                x_label='carrier density {0}'.format(n_units),
                y_label='sheet resistance',
                marker_size=8.0)

            rsheet_plot.add_data(x_data=n[0] * 1e-12,
                                 y_data=r_sheet,
                                 error_y={
                                     'type': 'data',
                                     'array': np.array(r_sheet_error,
                                                       dtype=float),
                                     'visible': True
                                 },
                                 mode='markers',
                                 name='n',
                                 text='n')

            rsheet_plot.save_plot(name='rsheet_at_vd_{0}'.format(vd))
Пример #6
0
    def save_plots(self):

        I_units = '\u03BCA/\u03BCm'
        if self.idvg is not None:
            vg = self.idvg.get_column('vg')[0]
            # first save the IdVg and IdVd plots
            rc_plot = BasicPlot(x_label='Vg (V)',
                                y_label='Id ({0})'.format(I_units),
                                marker_size=8.0)

            for vd, id in self.idvg.get_set_indexed_columns('id').items():
                rc_plot.add_data(x_data=vg,
                                 y_data=id * 1e6,
                                 mode='markers',
                                 name='Vd = {0}'.format(vd),
                                 text='n')

            rc_plot.save_plot(name='IdVg_plot')

        if self.idvd is not None:
            vd = self.idvd.get_column('vd')[0]
            # first save the IdVg and IdVd plots
            rc_plot = BasicPlot(x_label='Vd (V)',
                                y_label='Id ({0})'.format(I_units),
                                marker_size=8.0)

            for vg, id in self.idvd.get_set_indexed_columns('id').items():
                rc_plot.add_data(x_data=vd,
                                 y_data=id * 1e6,
                                 mode='markers',
                                 name='Vg = {0}'.format(vg),
                                 text='n')

            rc_plot.save_plot(name='IdVd_plot')

        # now save a CSV file of the FET properties
        self.FET.publish_csv('.')
Пример #7
0
class BasicApp(BaseApp):

    # external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

    # app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

    def __init__(self,
                 x_label,
                 y_label,
                 x_scale='linear',
                 y_scale='linear',
                 hidden_update=True,
                 graph_height=None,
                 graph_width=None,
                 upload_input=False,
                 *args,
                 **kwargs):

        super(BasicApp, self).__init__(*args, **kwargs)

        self.graph_height = graph_height
        self.graph_width = graph_width

        self.upload_input = upload_input

        self.init_plot(x_label=x_label,
                       y_label=y_label,
                       x_scale=x_scale,
                       y_scale=y_scale)

        self.update_function = None

        # the callback options
        self.callback_inputs = []
        self.callback_states = []
        self.callback_outputs = []

        # app layout
        self.app_layout = html.Div(
            style={'margin': '0 auto'},
            children=[
                dcc.Graph(self.name),
                html.Div(className='col-sm',
                         style={'display': 'none'} if hidden_update else {},
                         children=[
                             html.Button('Update',
                                         name='update_' + self.name,
                                         id='update_' + self.name,
                                         className='alert')
                         ])
            ],
        )

    def add_div(self, div, top=False, bottom=False):
        # assert not top or not bottom, 'You must choose to add to the top or the bottom'
        assert top or bottom, 'You must choose to add to the top or the bottom'
        assert isinstance(div, html.Div), 'The input must be of type Div'
        if top:
            self.app_layout.children = [div] + self.app_layout.children
        elif bottom:
            self.app_layout.children.append(div)

    def init_plot(self, x_label, y_label, x_scale, y_scale):

        self.plot = BasicPlot(x_label=x_label,
                              y_label=y_label,
                              x_scale=x_scale,
                              y_scale=y_scale,
                              graph_height=self.graph_height,
                              graph_width=self.graph_width)

    def build_app(self):

        self.app.layout = self.app_layout

        self._update_graph_function()

        # if there is an upload data module, run the callback creator
        if self.upload_input:
            self._upload_input_callback()

        # @self.app.callback(Output(self.name, 'figure'),
        #               [Input('blank', 'value'), Input('update_' + self.name, 'n_clicks')])
        # def update_graph(x_value, update):
        #     if self.update_function is not None:
        #         new_data = self.update_function(update)
        #         # print(new_data)
        #         if new_data is not None:
        #             return self.plot.get_plot(new_data=new_data)
        #     else:
        #         return self.plot.get_plot()

    def _update_graph_function(self):
        @self.app.callback(
            [Output(self.name, 'figure')] + self.callback_outputs,
            [Input('update_' + self.name, 'n_clicks')] + self.callback_inputs,
            self.callback_states)
        def update_graph(update_n, *args):
            # create the kwargs
            output_callbacks = tuple([None for i in self.callback_outputs])
            callbacks = self.callback_inputs + self.callback_states
            kwargs = {
                callback.component_id: _input
                for _input, callback in zip(args, callbacks)
            }
            # if data was uploaded to through an upload module, then convert the json to a dataframe
            if self.upload_input:
                kwargs['uploaded-data'] = self._read_df_from_json(
                    kwargs['uploaded-data'])

            if self.update_function is not None:
                new_data = self.update_function(update_n, **kwargs)
                # print(new_data)
                if new_data is not None:
                    # if new data is a dict, then extract the plot and callback data
                    if isinstance(new_data, dict):
                        callback_data = new_data['callback_data']
                        new_data = new_data['plot_data']
                        # look through the new data for any outputs that match the callback_outputs
                        callback_outputs = [
                            callback_data.get(callback.component_id, None)
                            for callback in self.callback_outputs
                        ]
                    else:
                        callback_outputs = output_callbacks

                    return (self.plot.get_plot(
                        new_data=new_data), ) + tuple(callback_outputs)

            return (self.plot.get_plot(), ) + output_callbacks

        return update_graph

    def add_data(self, x, y, text, name, mode='markers'):
        self.plot.add_data(x, y, text, name, mode=mode)

    def _upload_input_callback(self):
        """
        Create the callback for uploading data
        Returns:

        """
        @self.app.callback(Output('uploaded-data', 'children'),
                           [Input('upload-data', 'contents')],
                           [State('upload-data', 'filename')])
        def process_uploaded_data(contents, names):

            if contents is None:
                return None
            else:
                cleaned_data = load_csv_or_xls(contents, names)

            # now return the data as json
            return cleaned_data.to_json(orient='split')

        return process_uploaded_data

    @staticmethod
    def _read_df_from_json(json_data):
        """
        Simply read read json data and output a pandas dataframe
        Args:
            json_data (str): Json string of data to be read

        Returns:
            pd.DataFrame or None if json_data was None
        """
        if json_data is None:
            return json_data
        return pd.read_json(json_data, orient='split')

    def add_update_graph(self, update_function):
        """
        Add a function that will be run for updating the graph
        Args:
            update_function: Function to run

        Returns:

        """
        self.update_function = update_function