Exemplo n.º 1
0
    def run(self):
        """Runs the script"""

        # Convert the units to the desired ones
        self.original_data = deepcopy(self.data)  # Is needed for gradin

        # Plot deltas of each measurement
        abs_diff = self.data["All"][["C11R11", "C127R127",
                                     "C255R257"]].diff(axis=0)
        rel_diff = (
            abs_diff /
            self.data["All"][["C11R11", "C127R127", "C255R257"]]).rename(
                columns={
                    "C11R11": "C11R11_reldiff",
                    "C127R127": "C127R127_reldiff",
                    "C255R257": "C255R257_reldiff"
                })
        abs_diff = abs_diff.rename(
            columns={
                "C11R11": "C11R11_absdiff",
                "C127R127": "C127R127_absdiff",
                "C255R257": "C255R257_absdiff"
            })

        temp = rel_diff.join(abs_diff)
        self.data["All"] = self.data["All"].join(temp)
        self.data["columns"].extend([
            "C11R11_absdiff", "C127R127_absdiff", "C255R257_absdiff",
            "C11R11_reldiff", "C127R127_reldiff", "C255R257_reldiff"
        ])

        for file in self.data["keys"]:
            self.data[file]["measurements"].extend([
                "C11R11_absdiff", "C127R127_absdiff", "C255R257_absdiff",
                "C11R11_reldiff", "C127R127_reldiff", "C255R257_reldiff"
            ])
            self.data[file]["data"] = self.data["All"]
            self.data[file]["units"].extend(
                ["None", "urad", "urad", "urad", "%", "%", "%"])

        # Plot all Measurements
        self.basePlots = plot_all_measurements(self.data,
                                               self.config,
                                               self.xaxis,
                                               self.analysisName,
                                               do_not_plot=self.donts,
                                               ErrorBars=self.errors)

        # self.basePlots = applyPlotOptions(self.basePlots, {'Curve': {'color': "hv.Cycle('PiYG')"}})
        self.PlotDict["BasePlots"] = self.basePlots
        self.PlotDict["All"] = self.basePlots

        return self.PlotDict
Exemplo n.º 2
0
    def run(self):
        """Runs the script"""

        # Plot all Measurements
        self.basePlots = plot_all_measurements(self.data,
                                               self.config,
                                               self.xrow,
                                               self.analysisName,
                                               do_not_plot=self.donts)
        self.PlotDict["BasePlots"] = self.basePlots
        self.PlotDict["All"] = self.basePlots

        # Plot all special Plots:
        # Histogram Plot
        self.Histogram = dospecialPlots(
            self.data, self.config, self.analysisName, "concatHistogram",
            self.measurements, **self.config[self.analysisName].get(
                "AuxOptions", {}).get("concatHistogram", {}))
        if self.Histogram:
            self.PlotDict["Histogram"] = self.Histogram
            self.PlotDict["All"] = self.PlotDict["All"] + self.Histogram

        # Whiskers Plot
        self.WhiskerPlots = dospecialPlots(self.data, self.config,
                                           self.analysisName, "BoxWhisker",
                                           self.measurements)
        if self.WhiskerPlots:
            self.PlotDict["Whiskers"] = self.WhiskerPlots
            self.PlotDict["All"] = self.PlotDict["All"] + self.WhiskerPlots

        # Violin Plot
        self.Violin = dospecialPlots(self.data, self.config, self.analysisName,
                                     "Violin", self.measurements)
        if self.Violin:
            self.PlotDict["Violin"] = self.Violin
            self.PlotDict["All"] = self.PlotDict["All"] + self.Violin

        # singleHist Plot
        self.singleHist = dospecialPlots(
            self.data, self.config, self.analysisName, "Histogram",
            self.measurements, **self.config[self.analysisName].get(
                "AuxOptions", {}).get("singleHistogram", {}))
        if self.singleHist:
            self.PlotDict["singleHistogram"] = self.singleHist
            self.PlotDict["All"] = self.PlotDict["All"] + self.singleHist

        # Reconfig the plots to be sure
        self.PlotDict["All"] = config_layout(
            self.PlotDict["All"],
            **self.config[self.analysisName].get("Layout", {}))
        return self.PlotDict
Exemplo n.º 3
0
    def run(self):
        """Runs the script"""

        # Convert the units to the desired ones
        for meas in self.measurements:
            unit = (self.config[self.analysisname].get(meas, {}).get(
                "UnitConversion", None))
            if unit:
                self.data = convert_to_EngUnits(self.data, meas, unit)

        # Plot all Measurements
        self.basePlots = plot_all_measurements(
            self.data,
            self.config,
            self.measurements[0],
            self.analysisname,
            do_not_plot=[self.measurements[0]],
        )
        self.PlotDict["All"] = self.basePlots

        # Plot all special Plots:
        # Histogram Plot
        self.Histogram = dospecialPlots(
            self.data, self.config, self.analysisname, "concatHistogram",
            self.measurements, **self.config[self.analysisname].get(
                "AuxOptions", {}).get("concatHistogram", {}))
        if self.Histogram:
            self.PlotDict["Histogram"] = self.Histogram
            self.PlotDict["All"] = self.PlotDict["All"] + self.Histogram

        # Whiskers Plot
        self.WhiskerPlots = dospecialPlots(self.data, self.config,
                                           self.analysisname, "BoxWhisker",
                                           self.measurements)
        if self.WhiskerPlots:
            self.PlotDict["Whiskers"] = self.WhiskerPlots
            self.PlotDict["All"] = self.PlotDict["All"] + self.WhiskerPlots

        # Violin Plot
        self.Violin = dospecialPlots(self.data, self.config, self.analysisname,
                                     "Violin", self.measurements)
        if self.Violin:
            self.PlotDict["Violin"] = self.Violin
            self.PlotDict["All"] = self.PlotDict["All"] + self.Violin

        # Reconfig the plots to be sure
        self.PlotDict["All"] = config_layout(
            self.PlotDict["All"],
            **self.config.get(self.analysisname, {}).get("Layout", {}))
        return self.PlotDict
Exemplo n.º 4
0
    def analysis_gate(self, df):
        # global curr_savgol_plot, maxsavgol
        gate_files.append(df)  # append to a list containing all the gate diode files

        # Remove initial kink from the data
        start_value = np.mean(self.data[df]["data"]["Current"][10:20])
        CurrentCopy = self.data[df]["data"]["Current"].copy()
        for x in range(int(len(self.data[df]["data"]["Current"]) / 2)):
            if CurrentCopy[x] < start_value:
                CurrentCopy[x] = start_value

        # Generate curve
        plot_not_kink = self.add_single_plots(
            self.data[df]["data"][self.xaxis], CurrentCopy, "Current"
        )

        # Try savgol filter
        ##try:
        ##    i = 0
        ##    while i < 2:
        ##        curr_savgol = scipy.signal.savgol_filter(self.data[df]['data']['Current'], 31, 3)  # window size 51, polynomial order 3
        ##        i += 1
        ##    maxsavgol = max(curr_savgol)
        ##    curr_savgol_plot = self.add_single_plots(self.data[df]['data']['Voltage'], curr_savgol, "SavgolCurrent")
        ##except Exception:
        ##    self.log.warning("No savgol plot possible... Error: {}")

        # Interpolation current curve
        xnew, ynew = self.interpolated_axis(
            df, self.data[df]["data"][self.xaxis], CurrentCopy
        )
        curr_interp_plot = self.add_single_plots(xnew, ynew, "InterpolatedCurrent")

        # Build the first derivatives
        firstderi_interp = self.build_first_derivative(xnew, ynew)
        dif_intep_plot = self.add_single_plots(
            xnew, firstderi_interp, "FirstDerivativeCurrent"
        )

        # Second derivative
        second_deriv_interp = self.build_second_derivative(xnew, ynew)
        dif2_intep_plot = self.add_single_plots(
            xnew, second_deriv_interp, "SecondDerivativeCurrent"
        )

        # Not interpolated first derivative
        firstdev_not_interp = self.build_first_derivative(
            self.data[df]["data"]["Current"], self.data[df]["data"]["Voltage"]
        )
        self.insert_in_df(df, 3, "firstderivative_gate", firstdev_not_interp)

        # Try to find the start and ending indices of the points where you want to average, used to handle the problematic files
        max1_index = list(firstderi_interp).index(max(firstderi_interp))
        min1_index = list(firstderi_interp).index(min(firstderi_interp))
        if min1_index < max1_index:
            min1_index = max1_index + 1
            max1_index = min1_index - 2
        median_index = int(len(xnew) / 2)
        if median_index < max1_index:
            median_index = max1_index + 1
        if min1_index < median_index:
            min1_index = median_index + 1
            max1_index = median_index - 1

        # Find the segment where you want to average using the second derivative
        interesting_section = sorted(
            list(second_deriv_interp[max1_index:median_index]), reverse=True
        )
        firstminimum = interesting_section[0]
        interesting_section2 = sorted(
            list(second_deriv_interp[median_index:min1_index]), reverse=True
        )
        second_minimum = interesting_section2[0]

        # Find average
        start_average = list(second_deriv_interp).index(firstminimum)
        end_average = list(second_deriv_interp).index(second_minimum)
        I_surf_maxima_average = np.mean(list(ynew[start_average:end_average]))

        # Compute the surface current with the average method
        mxx = max(ynew)  # find maximum value of the current-voltage curve
        miny = np.mean(
            list(ynew[-1000:])
        )  # find the minimum of the current-voltage curve by averaging 20 points values in the curve tail
        I_surf_average = (
            I_surf_maxima_average - miny
        )  # compute the surface current by computing the difference between the maximum and minimum value
        I_surf_average_table = "{:.2e}".format(I_surf_average)
        Surface_current_average.append(I_surf_average_table)

        # Compute surface current with the maximum method
        Isurf_max = (
            mxx - miny
        )  # compute the surface current by computing the difference between the maximum and minimum value
        Isurf_table = "{:.2e}".format(Isurf_max)
        Surface_current.append(Isurf_table)

        # Compute Surface_recombination_velocity with the maximum method
        S_null_max = Isurf_max / (
            self.config["IV_PQC_parameter"]["q"]
            * self.config["IV_PQC_parameter"]["n_i_intrinsic_carrier_concentration"]
            * (float(self.data[df]["header"][0].split(":")[1]) * (1e-8))
        )
        Surface_recombination_velocity.append(S_null_max)

        # Compute Surface_recombination_velocity with the average method
        S_null_average = I_surf_average / (
            self.config["IV_PQC_parameter"]["q"]
            * self.config["IV_PQC_parameter"]["n_i_intrinsic_carrier_concentration"]
            * (float(self.data[df]["header"][0].split(":")[1]) * (1e-8))
        )
        Surface_recombination_velocity_average.append(S_null_average)

        # Add text to the plot
        text = hv.Text(
            3,
            9 * (1e-11),
            "Isurf_max: {} A\n"
            "Isurf_average: {} A\n"
            "Surface recombination velocity_max: {} cm/s\n"
            "Surface recombination velocity_average: {} cm/s".format(
                np.round(Isurf_max, 15),
                np.round(I_surf_average, 15),
                np.round(S_null_max, 4),
                np.round(S_null_average, 4),
            ),
        ).opts(style=dict(text_font_size="20pt"))

        # Do this if the analysis is of just one file.
        if len(gate_files) == 1:
            # Add overlaid lines on the plot
            Path_min = hv.Path([(-2, miny), (6, miny)]).opts(line_width=2.0)
            Path_mxx = hv.Path([(-2, mxx), (6, mxx)]).opts(line_width=2.0)
            ##Path_savgolmax = hv.Path([(-2, maxsavgol), (6, maxsavgol)]).opts(line_width=2.0)
            Path_average = hv.Path(
                [(-2, I_surf_maxima_average), (6, I_surf_maxima_average)]
            ).opts(line_width=2.0)
            Path_Isurf = hv.Arrow(-1, mxx, "max", "^")
            Path_Isurf_average = hv.Arrow(0, I_surf_maxima_average, "average", "^")
            # Plot all Measurements
            self.donts_gatediode = [
                "timestamp",
                "voltage",
                "Voltage",
                "Current",
                "Stepsize",
                "Wait",
                "Stepsize",
                "Frequency",
                "x",
                "N",
            ]  # don't plot these.
            self.PlotDict["BasePlots_gate"] = plot_not_kink
            self.PlotDict["BasePlots_gate"] += dif_intep_plot
            self.PlotDict["BasePlots_gate"] += dif2_intep_plot
            self.PlotDict["BasePlots_gate"] += curr_interp_plot
            try:
                self.PlotDict["BasePlots_gate"] += curr_savgol_plot
                self.PlotDict["BasePlots_gate"] += curr_savgol_plot * plot_not_kink
            except Exception:
                self.log.warning("No savgol plot possible... Error: {}")
            self.PlotDict["BasePlots_gate"] += (
                text
                * plot_not_kink
                * Path_min
                * Path_mxx
                * Path_average
                * Path_Isurf
                * Path_Isurf_average
            )  # * Path_savgolmax
            self.PlotDict["BasePlots_gate"] += (
                curr_interp_plot * dif_intep_plot * dif2_intep_plot * plot_not_kink
            )

            # Add table that shows resulting parameters of the analysis
            df4 = pd.DataFrame(
                {
                    "Name": gate_files,
                    "Surface current_max (A)": Surface_current,
                    "Surface current_average (A)": Surface_current_average,
                    "Surface recombination velocity_max (cm/s)": Surface_recombination_velocity,
                    "Surface recombination velocity_average (cm/s)": Surface_recombination_velocity_average,
                }
            )
            table3 = hv.Table((df4), label="Gate analysis")
            table3.opts(width=1300, height=800)
            self.PlotDict["BasePlots_gate"] += table3

        # Do this if the analysis is of more than one file
        elif len(gate_files) > 1:
            self.donts = [
                "timestamp",
                "voltage",
                "Voltage",
                "Stepsize",
                "Wait",
                "Stepsize",
                "Frequency",
                "firstderivative_gate",
                "x",
                "N",
            ]  # do not plot this data
            self.basePlots3 = plot_all_measurements(
                self.data,
                self.config,
                self.xaxis,
                self.name,
                do_not_plot=self.donts,
                keys=gate_files,
            )
            self.PlotDict["BasePlots_gate"] = self.basePlots3

            # Add table that shows resulting parameters of the analysis
            df4 = pd.DataFrame(
                {
                    "Name": gate_files,
                    "Surface current_max (A)": Surface_current,
                    "Surface current_average (A)": Surface_current_average,
                    "Surface recombination velocity_max (cm/s)": Surface_recombination_velocity,
                    "Surface recombination velocity_average (cm/s)": Surface_recombination_velocity_average,
                }
            )
            table3 = hv.Table((df4), label="Gate analysis")
            table3.opts(width=1300, height=800)
            self.PlotDict["BasePlots_gate"] += table3

        return self.PlotDict["BasePlots_gate"]
Exemplo n.º 5
0
    def analysis_diode(self, df):
        # global fdestimation
        diode_files.append(df)  # Append to a list containing all the diode files
        self.data[df]["data"]["Voltage"] = list(
            map(abs, self.data[df]["data"]["Voltage"])
        )  # take absolute value of Voltage

        # Try interpolation + filtered savitzy-golay derivative plot
        (
            capacity_curve,
            derivative_onec2_curve,
            deronec2_savgol_plot,
        ) = self.interp_derivative_diode(
            df, self.data[df]["data"][self.xaxis], self.data[df]["data"]["Capacity"]
        )
        self.insert_in_df(df, 3, "1C2", 1 / self.data[df]["data"]["Capacity"].pow(2))

        # Compute first derivative of 1/C2
        firstdev_invers_C2 = self.build_first_derivative(
            self.data[df]["data"][self.xaxis], self.data[df]["data"]["1C2"]
        )
        self.insert_in_df(df, 4, "derivative1C2", firstdev_invers_C2)

        # Calculate deep x
        x = (
            self.config["IV_PQC_parameter"]["epsilonNull"]
            * (1e-6)
            * float(self.data[df]["header"][0].split(":")[1])
            * self.config["IV_PQC_parameter"]["epsilonSiliconOxide"]
        ) / self.data[df]["data"]["Capacity"][:42]
        self.insert_in_df(df, 5, "x", x)

        # Calculate doping profile
        N = (2) / (
            self.config["IV_PQC_parameter"]["epsilonNull"]
            * (1e-2)
            * self.config["IV_PQC_parameter"]["q"]
            * self.config["IV_PQC_parameter"]["epsilonSiliconOxide"]
            * self.data[df]["data"]["derivative1C2"][:42]
            * (float(self.data[df]["header"][0].split(":")[1]) * (1e-8))
            * (float(self.data[df]["header"][0].split(":")[1]) * (1e-8))
        )
        self.insert_in_df(df, 6, "N", N)

        # Plot all Measurements
        self.donts_diode = [
            "timestamp",
            "voltage",
            "Voltage",
            "Stepsize",
            "Wait",
            "Stepsize",
            "Frequency",
            "x",
            "N",
            "Capacity",
            "Current",
        ]  # do not plot capacity voltage plot
        self.basePlots4 = plot_all_measurements(
            self.data,
            self.config,
            self.xaxis,
            self.name,
            do_not_plot=self.donts_diode,
            keys=diode_files,
        )
        self.PlotDict["BasePlots_diode"] = self.basePlots4

        # Add a plot with a different x axis
        self.basePlots_2 = plot_all_measurements(
            self.data,
            self.config,
            "x",
            self.name,
            do_not_plot=["Voltage", "Current", "Capacity", "1C2", "derivative1C2", "x"],
            keys=diode_files,
        )  # diode is the list containing all the diode files
        self.PlotDict["BasePlots_diode"] += self.basePlots_2

        # Add full depletion point to 1/c^2 curve
        if (
            self.config["IV_PQC"]
            .get("1C2", {})
            .get("DoFullDepletionCalculation", False)
        ):
            try:
                if self.basePlots4.Overlay.A_1C2.children:
                    c2plot = self.basePlots4.Overlay.A_1C2.opts(clone=True)
                else:
                    c2plot = self.basePlots4.Curve.A_1C2.opts(clone=True)
                fdestimation = self.find_full_depletion_c2(
                    c2plot,
                    self.data,
                    self.config,
                    diode_files,
                    PlotLabel="Full depletion estimation",
                )
            except Exception as err:
                self.log.warning(
                    "No full depletion calculation possible... Error: {}".format(err)
                )

        # Find resistivity
        C_min = np.mean(self.data[df]["data"]["Capacity"][-20:])
        d_active = (
            self.config["IV_PQC_parameter"]["epsilonNull"]
            * self.config["IV_PQC_parameter"]["epsilonSiliconOxide"]
            * (float(self.data[df]["header"][0].split(":")[1]) * (1e-8))
            * (1e-2)
            / C_min
        )  # in cm
        T_n = 295 / 300
        u_holes_mobility = 54.3 * pow(T_n, -0.57) + 1.36 * (1e8) * pow(295, -2.23) / (
            1 + ((5e12) / (2.35 * (1e17) * pow(T_n, 2.4))) * 0.88 * pow(T_n, -0.146)
        )  # in cm^2/(V*s)
        rho = (
            d_active
            * d_active
            / (
                2
                * self.config["IV_PQC_parameter"]["epsilonNull"]
                * (1e-2)
                * self.config["IV_PQC_parameter"]["epsilonSiliconOxide"]
                * fdestimation[1]
                * u_holes_mobility
            )
        )  # in Ohm * cm
        rho_table = "{:.2e}".format(
            rho
        )  # value to show later on in the table showing the results of the analysis
        resistivity.append(rho_table)

        # Add a table that show the results of the analysis
        if len(diode_files) == 1:
            self.PlotDict["BasePlots_diode"] += fdestimation[0]
            # Add trial plots
            self.PlotDict["BasePlots_diode"] += capacity_curve
            ##self.PlotDict["BasePlots_diode"] += derivative_onec2_curve * deronec2_savgol_plot
            ##self.PlotDict["BasePlots_diode"] += deronec2_savgol_plot
            # Add table
            df3 = pd.DataFrame(
                {
                    "Name": diode_files,
                    "full depletion voltage (V)": fdepvoltage,
                    " Bulk resistivity (Ohm * cm)": resistivity,
                }
            )
            table2 = hv.Table(df3, label="Diode analysis")
            table2.opts(width=1300, height=800)
            self.PlotDict["BasePlots_diode"] += table2

        else:
            df3 = pd.DataFrame(
                {
                    "Name": diode_files,
                    "full depletion voltage (V)": fdepvoltage,
                    "Bulk resistivity (Ohm * cm)": resistivity,
                }
            )
            table2 = hv.Table(df3, label="Diode analysis")
            table2.opts(width=1300, height=800)
            self.PlotDict["BasePlots_diode"] += table2

        return self.PlotDict["BasePlots_diode"]
Exemplo n.º 6
0
    def analysis_mos(self, df):
        # global fBestimation
        cv_files.append(
            df
        )  # Append data-frame to a list containing all the cv mos files that you want to analyze.

        # Double check that the voltage values have increasing order.
        if (
            "Voltage" in self.data[df]["data"]
            and self.data[df]["data"]["Voltage"][0] > 0
        ):  # If the first element is positive signifies that the voltage values have been stored in decreasing order
            self.data[df]["data"]["Voltage"] = list(
                reversed(self.data[df]["data"]["Voltage"])
            )  # If voltage values have decreasing order, reverse them.
            self.data[df]["data"]["Capacity"] = list(
                reversed(self.data[df]["data"]["Capacity"])
            )

        # Normalize capacity by the Area and set to cm^2
        self.data[df]["data"]["Capacity"] = self.data[df]["data"]["Capacity"] / (
            float(self.data[df]["header"][0].split(":")[1]) * (1e-8)
        )

        # Generate a capacity copy without the small kink at the begging of the curve
        CapacityCopy = self.data[df]["data"]["Capacity"].copy()
        capMin = np.max(
            self.data[df]["data"]["Capacity"][:20]
        )  # Find the Maximum among the first 20 values of the Capacity and set it as the minimum Capacity value
        for x in range(len(self.data[df]["data"]["Capacity"])):
            if CapacityCopy[x] < capMin:
                CapacityCopy[x] = capMin
        # Insert into the data frame
        self.insert_in_df(df, 3, "CapacityCopy", CapacityCopy)

        # Build second derivative
        seconddev = self.build_second_derivative(
            self.data[df]["data"][self.xaxis], self.data[df]["data"]["CapacityCopy"]
        )
        self.insert_in_df(df, 4, "derivative2", seconddev)

        # Build interpolated plot and interpolated derivatives
        (
            capa_interp_plot,
            derivative_interpolation_plot,
            secondderivative_interp_plot,
            max_firstder_plot,
            voltage_value_of_max_firstder,
        ) = self.interpol(
            df, self.data[df]["data"][self.xaxis], self.data[df]["data"]["CapacityCopy"]
        )

        # Find the index of the row which contains the maximum value of the second derivative
        indexMax = self.data[df]["data"].index.get_loc(
            self.data[df]["data"]["derivative2"].values.argmax()
        )

        # Find the index of the row which contains the minimum value of the second derivative
        indexMin = self.data[df]["data"].index.get_loc(
            self.data[df]["data"]["derivative2"].values.argmin()
        )

        # Plot all Measurements
        self.donts_mos = [
            "timestamp",
            "voltage",
            "Voltage",
            "Stepsize",
            "Wait",
            "Stepsize",
            "Frequency",
            "x",
            "N",
            "Current",
        ]  # don't plot these.
        self.basePlots5 = plot_all_measurements(
            self.data,
            self.config,
            self.xaxis,
            self.name,
            do_not_plot=self.donts_mos,
            keys=cv_files,
        )
        self.PlotDict["BasePlots_MOS"] = self.basePlots5

        # Add flat bandage voltage point to the Capacity curve
        if (
            self.config["IV_PQC"]
            .get("CapacityCopy", {})
            .get("findFlatBandVoltage", False)
        ):
            try:
                if self.basePlots5.Overlay.MOS_CV_CURVES.children:
                    clone_plot = self.basePlots5.Overlay.MOS_CV_CURVES.opts(clone=True)
                else:
                    clone_plot = self.basePlots5.Curve.MOS_CV_CURVES.opts(clone=True)
                fBestimation = self.find_flatBand_voltage(
                    clone_plot,
                    self.data,
                    self.config,
                    indexMax,
                    indexMin,
                    df,
                    cv_files,
                    voltage_value_of_max_firstder,
                    PlotLabel="Flat band voltage estimation",
                )
            except Exception as err:
                self.log.warning(
                    "No flat band voltage calculation possible... Error: {}".format(err)
                )

        # Do these plots for the analysis of one single cv mos file
        if len(cv_files) == 1:
            self.PlotDict["BasePlots_MOS"] += fBestimation[0]
            self.PlotDict["BasePlots_MOS"] += derivative_interpolation_plot
            self.PlotDict["BasePlots_MOS"] += secondderivative_interp_plot
            self.PlotDict["BasePlots_MOS"] += capa_interp_plot
            self.PlotDict["BasePlots_MOS"] += (
                capa_interp_plot
                * max_firstder_plot
                * derivative_interpolation_plot
                * secondderivative_interp_plot
            )
            self.PlotDict["BasePlots_MOS"] += (
                fBestimation[6] * max_firstder_plot * derivative_interpolation_plot
            )

        # Add a Table that shows the differents analysis parameters values
        df2 = pd.DataFrame(
            {
                "Name": cv_files,
                "Flatband Voltage second_derivative (V)": fbvoltage,
                "Flatband Voltage first_derivative (V)": fbvoltage_firstderivative,
                "Accumulation capacitance (F)": Accum_capacitance_list,
                "Accumulation capacitance normalized (F/cm^2)": Accum_capacitance_normalized_list,
                "Tox (nm)": Tox_list,
                "Nox (cm^-2)": Nox_list,
            }
        )
        table1 = hv.Table(df2, label="Mos analysis")
        table1.opts(width=1300, height=800)
        # Do plots
        self.PlotDict["BasePlots_MOS"] += table1

        return self.PlotDict["BasePlots_MOS"]
Exemplo n.º 7
0
    def run(self):
        """Runs the script"""

        # Add the 1/c^2 data to the dataframes
        for df in self.data["keys"]:
            if "CV" in self.data[df]["data"]:
                self.data[df]["data"].insert(
                    3, "1C2", 1 / self.data[df]["data"]["CV"].pow(2))
                self.data[df]["units"].append("arb. units")
                self.data[df]["measurements"].append("1C2")
            elif "capacitance" in self.data[df]["data"]:
                self.data[df]["data"].insert(
                    3, "1C2", 1 / self.data[df]["data"]["capacitance"].pow(2))
                self.data[df]["units"].append("arb. units")
                self.data[df]["measurements"].append("1C2")

        # Add the measurement to the list

        # Plot all Measurements
        self.basePlots = plot_all_measurements(self.data,
                                               self.config,
                                               self.xaxis,
                                               self.analysisName,
                                               do_not_plot=self.donts)
        #self.basePlots = applyPlotOptions(self.basePlots, {'Curve': {'color': "hv.Cycle('PiYG')"}})
        self.PlotDict["BasePlots"] = self.basePlots
        self.PlotDict["All"] = self.basePlots

        # Add full depletion point to 1/c^2 curve
        if self.config[self.analysisName].get("1C2", {}).get(
                "DoFullDepletionCalculation", False):
            try:
                if self.basePlots.Overlay.CV_CURVES_hyphen_minus_Full_depletion.children:
                    c2plot = self.basePlots.Overlay.CV_CURVES_hyphen_minus_Full_depletion.opts(
                        clone=True)
                else:
                    c2plot = self.basePlots.Curve.CV_CURVES_hyphen_minus_Full_depletion.opts(
                        clone=True)
                fdestimation = self.find_full_depletion(
                    c2plot,
                    self.data,
                    self.config,
                    PlotLabel="Full depletion estimation")
                self.PlotDict["All"] += fdestimation
                self.PlotDict["BasePlots"] += fdestimation
            except Exception as err:
                self.log.warning(
                    "No full depletion calculation possible... Error: {}".
                    format(err))

        # Whiskers Plot
        self.WhiskerPlots = dospecialPlots(self.data, self.config,
                                           self.analysisName, "BoxWhisker",
                                           self.measurements)
        if self.WhiskerPlots:
            self.PlotDict["Whiskers"] = self.WhiskerPlots
            self.PlotDict["All"] = self.PlotDict["All"] + self.WhiskerPlots

        # Histogram Plot
        self.HistogramPlots = dospecialPlots(self.data, self.config,
                                             self.analysisName, "Histogram",
                                             self.measurements)
        if self.HistogramPlots:
            self.PlotDict["Histogram"] = self.HistogramPlots
            self.PlotDict["All"] = self.PlotDict["All"] + self.HistogramPlots

        # Reconfig the plots to be sure
        self.PlotDict["All"] = config_layout(
            self.PlotDict["All"],
            **self.config[self.analysisName].get("Layout", {}))

        return self.PlotDict
Exemplo n.º 8
0
    def run(self):
        """Runs the script"""

        # Convert the units to the desired ones
        self.original_data = deepcopy(self.data)  # Is needed for grading
        for meas in self.measurements:
            unit = (self.config[self.analysisName].get(meas, {}).get(
                "UnitConversion", None))
            if unit:
                self.data = convert_to_EngUnits(self.data, meas, unit)

        # Add the 1/c^2 data to the dataframes
        for df in self.data["keys"]:
            if "CV" in self.data[df]["data"]:
                self.data[df]["data"].insert(
                    3, "1C2", 1 / self.data[df]["data"]["CV"].pow(2))
                self.data[df]["units"].append("arb. units")
                self.data[df]["measurements"].append("1C2")
            elif "capacitance" in self.data[df]["data"]:
                self.data[df]["data"].insert(
                    3, "1C2", 1 / self.data[df]["data"]["capacitance"].pow(2))
                self.data[df]["units"].append("arb. units")
                self.data[df]["measurements"].append("1C2")

        # Add the measurement to the list

        # Plot all Measurements
        self.basePlots = plot_all_measurements(
            self.data,
            self.config,
            self.xaxis,
            self.analysisName,
            do_not_plot=self.donts,
        )
        # self.basePlots = applyPlotOptions(self.basePlots, {'Curve': {'color': "hv.Cycle('PiYG')"}})
        self.PlotDict["BasePlots"] = self.basePlots
        self.PlotDict["All"] = self.basePlots

        # Add full depletion point to 1/c^2 curve
        if (self.config[self.analysisName].get("1C2", {}).get(
                "DoFullDepletionCalculation", False)):
            try:
                if (self.basePlots.Overlay.
                        CV_CURVES_hyphen_minus_Full_depletion.children):
                    c2plot = self.basePlots.Overlay.CV_CURVES_hyphen_minus_Full_depletion.opts(
                        clone=True)
                else:
                    c2plot = self.basePlots.Curve.CV_CURVES_hyphen_minus_Full_depletion.opts(
                        clone=True)
                fdestimation = self.find_full_depletion(
                    c2plot,
                    self.data,
                    self.config,
                    PlotLabel="Full depletion estimation",
                )
                self.PlotDict["All"] += fdestimation
                self.PlotDict["BasePlots"] += fdestimation
            except Exception as err:
                self.log.warning(
                    "No full depletion calculation possible... Error: {}".
                    format(err))

        # Whiskers Plot
        self.WhiskerPlots = dospecialPlots(self.data, self.config,
                                           self.analysisName, "BoxWhisker",
                                           self.measurements)
        if self.WhiskerPlots:
            self.PlotDict["Whiskers"] = self.WhiskerPlots
            self.PlotDict["All"] = self.PlotDict["All"] + self.WhiskerPlots

        # Histogram Plot
        self.HistogramPlots = dospecialPlots(self.data, self.config,
                                             self.analysisName, "Histogram",
                                             self.measurements)
        if self.HistogramPlots:
            self.PlotDict["Histogram"] = self.HistogramPlots
            self.PlotDict["All"] = self.PlotDict["All"] + self.HistogramPlots

        # Reconfig the plots to be sure
        self.PlotDict["All"] = config_layout(
            self.PlotDict["All"],
            **self.config[self.analysisName].get("Layout", {}))
        self.PlotDict["data"] = self.data

        # Grade the sensor
        try:
            self.grade_Sensor()
        except:
            self.log.critical(
                "Some error happend while evaluating grade of sensor. This can happen!",
                exc_info=True)

        return self.PlotDict
Exemplo n.º 9
0
    def run(self):
        """Runs the script"""
        from forge.tools import plainPlot  # some elusive error in debugger it works while running it does not, but only here
        # Do some grouping and sanatizing
        groupedcountries = self.data["All"].groupby(
            self.data["All"]["Country/Region"])  # Data grouped by country
        self.countries = list(groupedcountries.groups)

        self.PlotDict["All"] = None
        prekeys = self.data["keys"]
        for items in self.config["COVID19"]["Countries"]:
            countryName = list(items.keys())[0]
            inhabitants = list(items.values())[0]
            countrycasegrouped = groupedcountries.get_group(
                countryName).groupby(
                    "Name")  # Grouped for death, confirmed, recovered

            seldata = {
            }  # a dict containing all data from one country grouped by death, confirmed, recovered
            for i, key in enumerate(
                    prekeys):  # The three groups: death, confirmed, recovered
                rawdata = countrycasegrouped.get_group(key).sum(
                )  # Some countries have region information (I combine them to a single one)
                seldata[self.keys_basenames[i]] = rawdata[
                    self.measurements].reindex(self.measurements)

            # Now do the anlysis
            growth = {}
            relgrowth = {}
            for key, dat in seldata.items():
                growth[key] = dat.diff()
                # Calculate the relative growth
                gr = growth[key].reindex(self.measurements)
                absc = dat.reindex(self.measurements)
                relgrowth[key] = gr.shift(
                    periods=-1, fill_value=np.nan).divide(
                        absc.replace(0, np.nan)).shift(
                            periods=1, fill_value=np.nan
                        ) * self.config["COVID19"]["GrowingRateMulti"]

            # Replace the data in the data structure
            newkeys = [
                "Accumulated", "Growth", "RelativeGrowth*{}".format(
                    self.config["COVID19"]["GrowingRateMulti"])
            ]
            self.data["keys"] = newkeys
            self.data["columns"] = self.keys_basenames
            units = ["#" for i in self.keys_basenames]
            for key, dat in zip(newkeys, [seldata, growth, relgrowth]):
                self.data[key] = {
                    "analysed": False,
                    "plots": False,
                    "header": ""
                }
                self.data[key]["measurements"] = self.keys_basenames
                self.data[key]["units"] = units
                #self.data[key]["units"][-2] = "%" # The last one is percent
                dat["Date"] = pd.to_datetime(pd.Series(self.measurements,
                                                       name="Date",
                                                       index=pd.Index(
                                                           self.measurements)),
                                             infer_datetime_format=True)
                dat["Date"] = dat["Date"].dt.to_period('d')
                dat["Name"] = pd.Series([key for i in self.measurements],
                                        name="Name",
                                        index=pd.Index(self.measurements))
                self.data[key]["measurements"].append("Date")
                self.data[key]["units"].append("")
                self.data[key]["data"] = pd.DataFrame(dat)

            # Start plotting
            # All individual
            donts = ["Date"]
            individual = plot_all_measurements(
                self.data,
                self.config,
                "Date",
                "COVID19",
                keys=[
                    "Accumulated", "Growth", "RelativeGrowth*{}".format(
                        self.config["COVID19"]["GrowingRateMulti"])
                ],
                do_not_plot=donts,
                PlotLabel="{}".format(countryName))

            if self.Plots:
                self.Plots += individual
            else:
                self.Plots = individual

            self.relgrowth_all_countries(countryName)
            if self.config["COVID19"]["Normalize"] == True:
                self.accumulated_all_countries_normalizes(
                    countryName, inhabitants)
            elif self.config["COVID19"]["Normalize"] == False:
                self.accumulated_all_countries(countryName)

            # Cases vs growth
            if not self.GrowthvsCases:
                self.GrowthvsCases = plainPlot(
                    "Curve",
                    self.data["Accumulated"]["data"]["confirmed"],
                    self.data["Growth"]["data"]["confirmed"],
                    label=countryName,
                    ylabel="New Cases",
                    **self.config['COVID19']['General'],
                    **self.config['COVID19']['GvC']["PlotOptions"])
            else:
                self.GrowthvsCases *= plainPlot(
                    "Curve",
                    self.data["Accumulated"]["data"]["confirmed"],
                    self.data["Growth"]["data"]["confirmed"],
                    label=countryName,
                    ylabel="New Cases",
                    **self.config['COVID19']['General'],
                    **self.config['COVID19']['GvC']["PlotOptions"])

            # Death vs growth
            if not self.DeathvsCases:
                self.DeathvsCases = plainPlot(
                    "Curve",
                    self.data["Accumulated"]["data"]["confirmed"],
                    self.data["Accumulated"]["data"]["deaths"],
                    label=countryName,
                    ylabel="Total Deaths",
                    **self.config['COVID19']['General'],
                    **self.config['COVID19']['GvC']["PlotOptions"])
            else:
                self.DeathvsCases *= plainPlot(
                    "Curve",
                    self.data["Accumulated"]["data"]["confirmed"],
                    self.data["Accumulated"]["data"]["deaths"],
                    label=countryName,
                    ylabel="Total Deaths",
                    **self.config['COVID19']['General'],
                    **self.config['COVID19']['GvC']["PlotOptions"])

        # Relabel the plots
        self.GrowthvsCases = relabelPlot(
            self.GrowthvsCases.opts(xlim=(1, None), ylim=(1, None)),
            "New Cases vs. Total Cases")
        self.DeathvsCases = relabelPlot(
            self.DeathvsCases.opts(xlim=(1, None), ylim=(1, None)),
            "Total Death vs. Total Cases")
        if not self.config["COVID19"]["Normalize"]:
            self.cases = relabelPlot(self.cases,
                                     "Confirmed Cases not normalized")
            self.recovered = relabelPlot(self.recovered,
                                         "Recovered Cases not normalized")
            self.deaths = relabelPlot(self.deaths, "Deaths not normalized")
        self.casesrelgrowth = relabelPlot(self.casesrelgrowth,
                                          "Confirmed Cases relative growth")
        self.recoveredrelgrowth = relabelPlot(
            self.recoveredrelgrowth, "Recovered Cases relative growth")
        self.deathsrelgrowth = relabelPlot(self.deathsrelgrowth,
                                           "Deaths relative growth")
        if self.config["COVID19"]["Normalize"]:
            self.casesNorm = relabelPlot(self.casesNorm,
                                         "Confirmed Cases normalized")
            self.recoveredNorm = relabelPlot(self.recoveredNorm,
                                             "Recovered Cases normalized")
            self.deathsNorm = relabelPlot(self.deathsNorm, "Deaths normalized")

        # Define Plotting order
        self.plottingOrder = [
            self.GrowthvsCases, self.DeathvsCases, self.casesNorm,
            self.recoveredNorm, self.deathsNorm, self.casesrelgrowth,
            self.recoveredrelgrowth, self.deathsrelgrowth, self.cases,
            self.recovered, self.deaths, self.Plots
        ]
        for plot in self.plottingOrder:
            if plot:
                if self.PlotDict["All"]:
                    self.PlotDict["All"] += plot
                else:
                    self.PlotDict["All"] = plot

        # Reconfig the plots to be sure
        self.PlotDict["All"].opts(opts.Bars(stacked=True))
        self.PlotDict["All"] = config_layout(
            self.PlotDict["All"],
            **self.config.get(self.analysisname, {}).get("Layout", {}))
        return self.PlotDict