def __init__(self, data, configs): '''removes wrong data''' for file in list(data.keys()): if "contact chain" not in data[file]["header"][3].lower(): data.pop(file) self.log = logging.getLogger(__name__) self.data = convert_to_df(data, abs=False) self.config = configs self.df = [] self.basePlots = None self.analysisname = "Contact_Chain" self.PlotDict = {"Name": self.analysisname} self.measurements = self.data["columns"] self.sort_parameter = self.config["Contact_Chain"]["Bar_chart"][ "CreateBarChart"] self.Substrate_Type = ["Polysilicon", "N+", "P+"] self.filename_df = pd.DataFrame(columns=[ "Filename", "Substrate Type", "_", "Batch", "Wafer No.", "_", "HM location", "Test structure", "Resistance", "Standard deviation" ]) self.PlotDict["All"] = None self.limits = {"Polysilicon": 4 * 10**7, "N+": 10**5, "P+": 8 * 10**4} self.files_to_fit = self.config["files_to_fit"] hvtext = hv.Text(0, 0, self.analysisname, fontsize=20).opts(color="black", xlabel='', ylabel='') box = hv.Polygons(hv.Box(0, 0, 1).opts(color="black")).opts(color="white") self.PlotDict["All"] = box * hvtext
def __init__(self, data, configs): self.log = logging.getLogger(__name__) self.config = configs self.analysisName = "Stripscan" self.data = convert_to_df(data, abs=self.config.get("abs_value_only", False)) self.data = rename_columns( self.data, self.config.get(self.analysisName, {}).get("Measurement_aliases", {}), ) self.finalPlot = None self.df = [] self.measurements = self.data["columns"] self.donts = () if "Pad" in self.measurements: padidx = self.measurements.index("Pad") self.xrow = "Pad" else: self.log.error("No 'Pad' column found in data. Analysis cannot be done!") return self.PlotDict = {"Name": self.analysisName} self.donts = ["Pad", "Name"] # 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)
def __init__(self, data, configs): self.log = logging.getLogger(__name__) self.config = configs self.analysisName = "IVCV_HPK" self.data = convert_to_df(data, abs=True) self.data = rename_columns( self.data, self.config[self.analysisName].get("Measurement_aliases", {})) self.basePlots = None self.PlotDict = { "Name": "IVCV" } # Name of analysis and cnavas for all plots generated during this analysis self.capincluded = False self.measurements = self.data["columns"] self.measurements.remove("VR") self.measurements.remove("Name") # Find CV measurement for file in self.data["keys"]: if "CV" in file: self.data["keys"].append("1C2") self.data["1C2"] = self.data[file].copy() self.data["1C2"]["data"] = 1 / ( self.data[file]["data"][self.measurements] * self.data[file]["data"][self.measurements]) self.data["1C2"]["data"]["VR"] = self.data[file]["data"]["VR"] self.data["1C2"]["data"]["Name"] = ( self.data[file]["data"]["Name"] + "1c2") self.capincluded = True self.xaxis = "VR" # The do not plot list, you can extend this list as you like self.donts = ("Name", "VR")
def __init__(self, data, configs): # Do the analysis of the gate diode files as the last one. if not all( analysis_type[0:6] == "IV_GCD" for analysis_type in data[list(data.keys())[0]]["header"][2] ): data = self.file_order(data) self.log = logging.getLogger(__name__) self.data = convert_to_df(data, abs=False, keys="all") self.config = configs self.df = [] self.basePlots = None self.basePlots_2 = None self.name = "IV_PQC" self.PlotDict = {"Name": "IV"} self.capincluded = False # Add different columns to the data frame; self.data["columns"].insert(3, "CapacityCopy") self.data["columns"].insert(4, "derivative") self.data["columns"].insert(5, "derivative2") self.data["columns"].insert(6, "1C2") self.data["columns"].insert(7, "derivative1C2") self.data["columns"].insert(8, "x") self.data["columns"].insert(9, "N") self.data["columns"].insert(10, "firstderivative_gate") self.capincluded = True self.measurements = self.data["columns"] self.xaxis = self.measurements[0] # Select your x axis, normally voltage. # Convert the units to the desired ones for meas in self.measurements: unit = self.config[self.name].get(meas, {}).get("UnitConversion", None) if unit: self.data = convert_to_EngUnits(self.data, meas, unit)
def __init__(self, data, configs): self.log = logging.getLogger(__name__) self.config = configs self.analysisName = "MemoryEffect_IMS" self.data = convert_to_df(data, abs=self.config.get("abs_value_only", False)) self.data = rename_columns( self.data, self.config[self.analysisName].get("Measurement_aliases", {})) self.basePlots = None self.PlotDict = { "Name": "MemoryEffect_IMS" } # Name of analysis and cnavas for all plots generated during this analysis self.measurements = self.data["columns"] self.xaxis = self.measurements[7] # The do not plot list, you can extend this list as you like self.donts = [ "stdC11R11", "stdC127R127", "stdC255R257", "step", "Name" ] self.errors = { "C11R11": self.data["All"]["stdC11R11"], "C127R127": self.data["All"]["stdC127R127"], "C255R257": self.data["All"]["stdC255R257"] }
def __init__(self, data, configs): self.log = logging.getLogger(__name__) self.data = convert_to_df(data, abs=False) self.config = configs self.df = [] self.basePlots = None self.analysisname = "COVID19" self.PlotDict = {"Name": self.analysisname} self.measurements = self.data["columns"][ 4:] # Cut the non measurement lines #hv.renderer('bokeh') self.keys_basenames = [ name.split("_")[-2] for name in self.data["keys"] ] self.countries = [] # Plot canvas: self.Plots = None self.cases = None self.recovered = None self.deaths = None self.casesrelgrowth = None self.recoveredrelgrowth = None self.deathsrelgrowth = None self.casesNorm = None self.recoveredNorm = None self.deathsNorm = None self.GrowthvsCases = None self.DeathvsCases = None
def analysis(self): """Does the analysis""" average_len = 1 # Manipulate data for entry in self.data: self.data[entry]["data"]["measurement"] = np.array( range(0, 1000 - (average_len - 1))) self.data[entry]["measurements"].insert(0, "measurement") self.data[entry]["units"].insert(0, "#") # Do moving average over all data arrays for col in self.data[entry]["data"]: if col != "measurement": self.data[entry]["data"][col] = moving_average( self.data[entry]["data"][col], average_len) # Do rpoly conversion rpolyvoltage = -1 for file in self.data: self.data[file]["data"][ "R1"] = rpolyvoltage / self.data[file]["data"]["R1"] indx = self.data[file]["measurements"].index("R1") self.data[file]["units"][indx] = "Ohm" # Convert to df self.data = convert_to_df(self.data, abs=False) self.measurements = self.data["columns"] self.xaxis = "measurement"
def __init__(self, data, configs): for file in list(data.keys()): if "FET" not in data[file]["header"][3]: data.pop(file) self.log = logging.getLogger(__name__) self.data = convert_to_df(data, abs=False) self.config = configs self.basePlots = None self.analysisname = "FET" self.PlotDict = {"Name": self.analysisname} self.measurements = self.data["columns"] self.PlotDict["All"] = None self.do_analysis_1 = True self.do_analysis_2 = True self.do_analysis_3 = True self.df = pd.DataFrame(columns=["Name", "_", "Batch", "Wafer No.", "_", "_", "HM location", "Test structure", "ELR Method", "Second Derivative", "Second Derivative log"]) self.sort_parameter = self.config["FET"]["Bar_chart"]["CreateBarChart"] '''turns all headers into dictionaries and creates entries in self.data ''' for file in self.data["keys"]: self.data[file]["Ana 1"] = "_" self.data[file]["Ana 2"] = "_" self.data[file]["Ana 3"] = "_" self.data[file]["header"] = self.list_to_dict(self.data[file]["header"])
def __init__(self, data, configs): self.log = logging.getLogger(__name__) self.data = convert_to_df(data, abs=False) self.config = configs self.df = [] self.basePlots = None self.PlotDict = {"Name": "Curve_plots"} self.measurements = self.data["columns"]
def __init__(self, data, configs): self.log = logging.getLogger(__name__) self.data = convert_to_df(data, abs=True) self.config = configs self.df = [] self.Plots = [] self.allPlots = None self.individual = None self.PlotDict = {"Name": "Relaxation time"} self.measurements = self.data["columns"]
def __init__(self, data, configs): self.log = logging.getLogger(__name__) self.config = configs self.analysisName = "IVCV_QTC" self.data = convert_to_df(data, abs=self.config.get("abs_value_only", False)) self.data = rename_columns( self.data, self.config[self.analysisName].get("Measurement_aliases", {}) ) self.basePlots = None self.PlotDict = { "Name": "IVCV" } # Name of analysis and cnavas for all plots generated during this analysis self.capincluded = False if ( "capacitance" in self.data[self.data["keys"][0]]["data"] or "CV" in self.data[self.data["keys"][0]]["data"] ): self.data["columns"].insert(3, "1C2") # because we are adding it later on self.capincluded = True self.measurements = self.data["columns"] self.xaxis = self.measurements[0] # The do not plot list, you can extend this list as you like self.donts = [ "Name", "voltage_1", "Idark", "Idiel", "Rpoly", "Cac", "Cint", "Rint", "Pad", "Istrip", ] if "voltage" in self.measurements: self.xaxis = "voltage" padidx = self.measurements.index("voltage") del self.measurements[padidx] else: self.log.error( "No 'voltage' entry found in data, cannot do IVC analysis. Maybe you have to set an alias for your measurement." ) # 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)
def __init__(self, data, configs): self.log = logging.getLogger(__name__) self.config = configs self.analysisName = "Alibava" self.data = convert_to_df(data, abs=self.config.get("abs_value_only", False)) self.data = rename_columns( self.data, self.config[self.analysisName].get("Measurement_aliases", {}) ) self.basePlots = None self.PlotDict = { "Name": "IVCV" } # Name of analysis and cnavas for all plots generated during this analysis self.xaxis = "Temperature" self.donts = []
def __init__(self, data, configs): self.log = logging.getLogger(__name__) self.data = convert_to_df(data, abs=False) self.config = configs self.df = [] self.basePlots = None self.analysisname = "TCAD" self.PlotDict = {"Name": self.analysisname} self.measurements = self.data["columns"] # hv.renderer('bokeh') self.areafactors = self.config["AreaFactors"] self.scalefactors = self.config["ScalingFactors"] self.to_plot = [ ( "IV", "IV_1", self.areafactors.get("IV", 1), self.scalefactors.get("IV", 1), ), ( "CV", "CV_1", self.areafactors.get("CV", 1), self.scalefactors.get("CV", 1), ), ( "1c2", "1c2_1", self.areafactors.get("1c2", 1), self.scalefactors.get("1c2", 1), ), ( "oxide_charges", "interstrip_resistance", self.areafactors.get("interstrip_resistance", 1), self.scalefactors.get("interstrip_resistance", 1), ), ( "pstop_depth", "interstrip_resistance", self.areafactors.get("interstrip_resistance", 1), self.scalefactors.get("interstrip_resistance", 1), ), ]
def __init__(self, data, configs): '''removes wrong data''' for file in list(data.keys()): if "Linewidth".lower() not in data[file]["header"][3].lower(): data.pop(file) self.log = logging.getLogger(__name__) self.data = convert_to_df(data, abs=False) self.config = configs self.df = [] self.basePlots = None self.analysisname = "Linewidth" self.PlotDict = {"Name": self.analysisname} self.measurements = self.data["columns"] self.PlotDict["All"] = None self.sort_parameter = self.config["Linewidth"]["Bar_chart"][ "CreateBarChart"] self.Substrate_Type = ["P+", "N+", "P-stop"] self.filename_df = pd.DataFrame(columns=[ "Filename", "Substrate Type", "_", "Batch", "Wafer No.", "_", "HM location", "Test structure", "Linewidth [um]", "Standard deviation" ]) self.limits = {"P+": 0.05, "N+": 0.00001, "P-stop": 0.0005} self.files_to_fit = self.config["files_to_fit"] self.sheet_dic = { "P+": self.config["Linewidth"]["parameter"]["sheet_r_p+"], "N+": self.config["Linewidth"]["parameter"]["sheet_r_N+"], "P-stop": self.config["Linewidth"]["parameter"]["sheet_r_ps"] } self.std_dic = { "P+": self.config["Linewidth"]["parameter"]["std_p+"], "N+": self.config["Linewidth"]["parameter"]["std_N+"], "P-stop": self.config["Linewidth"]["parameter"]["std_ps"] } hvtext = hv.Text(0, 0, self.analysisname, fontsize=25).opts(color="black", xlabel='', ylabel='') box = hv.Polygons(hv.Box(0, 0, 300).opts(color="black")).opts(color="white") self.PlotDict["All"] = box * hvtext
def __init__(self, data, configs): '''removes wrong data''' for file in list(data.keys()): if "van-der-pauw" not in data[file]["header"][3].lower( ) and "bulk cross" not in data[file]["header"][3].lower(): data.pop(file) self.log = logging.getLogger(__name__) self.data = convert_to_df(data, abs=False) self.config = configs self.df = [] self.basePlots = None self.analysisname = "Van_der_Pauw" self.PlotDict = {"Name": self.analysisname} self.measurements = self.data["columns"] self.PlotDict["All"] = None self.sort_parameter = self.config["Van_der_Pauw"]["Bar_chart"][ "CreateBarChart"] self.Substrate_Type = [ "P-stop", "Polysilicon", "N+", "P+", "Metal", "bulk" ] '''columns have to be fitted according to sample_name + sample_type layout''' self.filename_df = pd.DataFrame(columns=[ "Filename", "Substrate Type", "_", "Batch", "Wafer No.", "_", "HM location", "Test structure", "_", "Sheet Resistance [Ohm/sq]", "Standard deviation" ]) self.limits = { "P-stop": 25000, "Polysilicon": 3000, "N+": 50, "P+": 1300, "Metal": 0.03, "bulk": 70000 } self.files_to_fit = self.config["files_to_fit"] hvtext = hv.Text(0, 0, self.analysisname, fontsize=13).opts(color="black", xlabel='', ylabel='') box = hv.Polygons(hv.Box(0, 0, 2).opts(color="black")).opts(color="white") self.PlotDict["All"] = box * hvtext
def __init__(self, data, configs): '''removes wrong data''' for file in list(data.keys()): if "meander" not in data[file]["header"][3]: data.pop(file) self.log = logging.getLogger(__name__) self.data = convert_to_df( data, abs=False ) ## funktioniert nicht komplet da metal und poly andere messungen haben self.complete_df(data) self.config = configs self.df = [] self.basePlots = None self.analysisname = "Meander" self.PlotDict = {"Name": self.analysisname} self.measurements = self.data["columns"] self.sort_parameter = self.config["Meander"]["Bar_chart"][ "CreateBarChart"] self.Substrate_Type = ["Polysilicon", "Metal"] self.filename_df = pd.DataFrame(columns=[ "Filename", "Substrate Type", "_", "Batch", "Wafer No.", "_", "HM location", "Test structure", "_", "Resistivity", "Standard deviation", "specific Resistivity [Ohm/sq]" ]) self.PlotDict["All"] = None self.limits = {"Polysilicon": 2 * 10**6, "Metal": 450} self.files_to_fit = self.config["files_to_fit"] self.squares = { "Polysilicon": self.config["Meander"]["parameter"]["squares_poly"], "Metal": self.config["Meander"]["parameter"]["squares_m"] } hvtext = hv.Text(0, 0, self.analysisname, fontsize=13).opts(color="black", xlabel='', ylabel='') box = hv.Polygons(hv.Box(0, 0, 2).opts(color="black")).opts(color="white") self.PlotDict["All"] = box * hvtext
def __init__(self, data, configs): self.log = logging.getLogger(__name__) self.data = convert_to_df(data, abs=False, keys="all") self.config = configs self.df = [] self.basePlots = None self.name = "IV_PQC" self.PlotDict = {"Name": "IV"} self.measurements = self.data["columns"] self.xaxis = "voltage" self.donts = ["timestamp", "voltage"] #hv.renderer('bokeh') c2 = 1 / (self.data['ChuckLeakage-Default_HME_S-PQC_Flute_1-Diode_IV']['data']["current"] * self.data['ChuckLeakage-Default_HME_S-PQC_Flute_1-Diode_IV']['data']["current"]) # Convert the units to the desired ones for meas in self.measurements: unit = self.config[self.name].get(meas, {}).get("UnitConversion", None) if unit: self.data = convert_to_EngUnits(self.data, meas, unit)
def __init__(self, data, configs): '''removes wrong data''' for file in list(data.keys()): if "MOS capacitor" not in data[file]["header"][0]: data.pop(file) self.log = logging.getLogger(__name__) self.data = convert_to_df(data, abs=False) self.config = configs self.basePlots = None self.analysisname = "MOS_CV" self.PlotDict = {"Name": self.analysisname} self.measurements = self.data["columns"] self.interpolation_der = self.config[ self.analysisname]["Derivative"]["interpolate"] self.do_derivative = self.config[self.analysisname]["Derivative"]["do"] self.plot_der = self.config[self.analysisname]["Derivative"]["plot"] self.interpolation_fit = self.config[ self.analysisname]["Fit"]["interpolate"] self.do_fit = self.config[self.analysisname]["Fit"]["do"] self.PlotDict["All"] = None