From c3984abdadc2058951d8ed878e74247e779f59be Mon Sep 17 00:00:00 2001 From: Isaac Gresham Date: Thu, 3 Oct 2024 22:38:43 +0200 Subject: [PATCH] black Linted with black. --- refellips/dataSE.py | 318 ++++++++++++++++++++++----------------- refellips/objectiveSE.py | 16 +- refellips/structureSE.py | 38 ++--- 3 files changed, 192 insertions(+), 180 deletions(-) diff --git a/refellips/dataSE.py b/refellips/dataSE.py index daab4b7..bc7f069 100644 --- a/refellips/dataSE.py +++ b/refellips/dataSE.py @@ -72,11 +72,7 @@ def __init__( self.name = name # If a file, then open and load the file. - if ( - hasattr(data, "read") - or type(data) is str - or isinstance(data, PurePath) - ): + if hasattr(data, "read") or type(data) is str or isinstance(data, PurePath): self.load(data) self.filename = data @@ -212,9 +208,7 @@ def save(self, f): header = "wavelength\tAOI\tPsi\tDelta" np.savetxt( f, - np.column_stack( - (self._wavelength, self._aoi, self._psi, self._delta) - ), + np.column_stack((self._wavelength, self._aoi, self._psi, self._delta)), delimiter="\t", header=header, ) @@ -312,9 +306,7 @@ def open_EP4file(fname, reflect_delta=False): del op["psi"] del op["delta"] name = _make_EP4dname(fname, op) - datasets.append( - DataSE(data, name=name, reflect_delta=reflect_delta, **op) - ) + datasets.append(DataSE(data, name=name, reflect_delta=reflect_delta, **op)) if len(datasets) == 1: return datasets[0] @@ -400,8 +392,7 @@ def _loadEP4(df): loc_data = False if loc_data and ( - len(df["X_pos"].drop_duplicates()) > 1 - or len(df["Y_pos"].drop_duplicates()) > 1 + len(df["X_pos"].drop_duplicates()) > 1 or len(df["Y_pos"].drop_duplicates()) > 1 ): xpos = np.nan ypos = np.nan @@ -460,9 +451,7 @@ def _loadEP4(df): return output -def open_HORIBAfile( - fname, reflect_delta=False, lambda_cutoffs=[-np.inf, np.inf] -): +def open_HORIBAfile(fname, reflect_delta=False, lambda_cutoffs=[-np.inf, np.inf]): """ Opening and loading in a data file created by a Horiba ellipsometer. Data file loaded should be of the Horiba file format .spe. @@ -511,9 +500,7 @@ def open_HORIBAfile( else: if not len(line): MDingest = False - if not len( - metadata[MDlabel] - ): # there is no metadata for entry + if not len(metadata[MDlabel]): # there is no metadata for entry metadata[MDlabel] = None # Set metadata to none elif len(metadata[MDlabel]) == 1: # there is only one entry metadata[MDlabel] = metadata[MDlabel][ @@ -521,9 +508,7 @@ def open_HORIBAfile( ] # remove data from list else: # there is metadata in the line - metadata[MDlabel].append( - line - ) # append line to metadata entry + metadata[MDlabel].append(line) # append line to metadata entry data_df = pd.read_csv( fname, @@ -543,6 +528,7 @@ def open_HORIBAfile( return DataSE(data, name=name, reflect_delta=reflect_delta, **metadata) + def open_M2000file(fname, dropdatapoints=1): """ Open and load in an Accurion EP4 formmated data file. @@ -569,182 +555,230 @@ def open_M2000file(fname, dropdatapoints=1): data = [] - with open(fname, mode ='r') as file: + with open(fname, mode="r") as file: __ = file.readline() meas_info = file.readline() __ = file.readline() - + count = 0 while True: data_row = [] - + count += 1 # print (count) - + # Get next line from file - line = file.readline().split('\t') + line = file.readline().split("\t") if not line: break if len(line) == 1: break - data_row.append(float(line[0])) # Wavelength - data_row.append(float(line[1])) # Angle - data_row.append(float(line[2])) # Psi - data_row.append(float(line[3])) # Delta - data_row.append(float(line[4])) # Psi Error - data_row.append(float(line[5])) # Delta Error - - line = file.readline().split('\t') - data_row.append(float(line[2])) # Unknown - data_row.append(float(line[3])) # Depolarization % - data_row.append(float(line[4])) # Unknown - - line = file.readline().split('\t') - data_row.append(float(line[2])) # Unknown - data_row.append(float(line[3])) # Intensity - data_row.append(float(line[4])) # Unknown - + data_row.append(float(line[0])) # Wavelength + data_row.append(float(line[1])) # Angle + data_row.append(float(line[2])) # Psi + data_row.append(float(line[3])) # Delta + data_row.append(float(line[4])) # Psi Error + data_row.append(float(line[5])) # Delta Error + + line = file.readline().split("\t") + data_row.append(float(line[2])) # Unknown + data_row.append(float(line[3])) # Depolarization % + data_row.append(float(line[4])) # Unknown + + line = file.readline().split("\t") + data_row.append(float(line[2])) # Unknown + data_row.append(float(line[3])) # Intensity + data_row.append(float(line[4])) # Unknown + data.append(data_row) - + data = np.array(data) data = data[::dropdatapoints] - return DataSE(data[:,[0,1,2,3]].T) + return DataSE(data[:, [0, 1, 2, 3]].T) def open_woolam_time_series(fname, take_every=1): - df = pd.read_csv(fname, skiprows=4, sep='\t', - names=['Wavelength, nm', 'Angle of incidence, ˚', 'Psi', 'Delta', 'Psi error', 'Delta error', 'None', 'Time, min']) + df = pd.read_csv( + fname, + skiprows=4, + sep="\t", + names=[ + "Wavelength, nm", + "Angle of incidence, ˚", + "Psi", + "Delta", + "Psi error", + "Delta error", + "None", + "Time, min", + ], + ) time_dict = {} - for idx, (time, subdf) in enumerate(df.groupby('Time, min')): - if idx%take_every == 0: - time_dict[np.round(time*60,1)] = DataSE(np.array([subdf['Wavelength, nm'],subdf['Angle of incidence, ˚'],subdf['Psi'],subdf['Delta']])[:,::5]) - + for idx, (time, subdf) in enumerate(df.groupby("Time, min")): + if idx % take_every == 0: + time_dict[np.round(time * 60, 1)] = DataSE( + np.array( + [ + subdf["Wavelength, nm"], + subdf["Angle of incidence, ˚"], + subdf["Psi"], + subdf["Delta"], + ] + )[:, ::5] + ) + return time_dict def open_FilmSenseFile(fname): with open(fname, "r") as f: header = f.readline() - if header == 'Film_Sense_Data\n': - return _open_FilmSenseFile_standard (f) - elif header == 'Film_Sense_Dyn_Data\n': - return _open_FilmSenseFile_dynamic (f) + if header == "Film_Sense_Data\n": + return _open_FilmSenseFile_standard(f) + elif header == "Film_Sense_Dyn_Data\n": + return _open_FilmSenseFile_dynamic(f) else: - assert False, 'Filetype not recognized' - - -def _parse_FilmSenseFileHeader(firstline, mode='standard'): - - firstline = firstline[:-1] #remove newline char - firstline = firstline.split('\t') - - metadata = {'numwvls' : int(firstline[0]), - 'numdatasets' : int(firstline[1]), - 'nomAOI' : float(firstline[2])} - - if mode == 'standard': - metadata['AlignX'] = float(firstline[3]) - metadata['AlignY'] = float(firstline[4]) - metadata['AvInten'] = float(firstline[5]) - elif mode == 'dynamic': - metadata['?'] = float(firstline[3]) + assert False, "Filetype not recognized" + + +def _parse_FilmSenseFileHeader(firstline, mode="standard"): + firstline = firstline[:-1] # remove newline char + firstline = firstline.split("\t") + + metadata = { + "numwvls": int(firstline[0]), + "numdatasets": int(firstline[1]), + "nomAOI": float(firstline[2]), + } + + if mode == "standard": + metadata["AlignX"] = float(firstline[3]) + metadata["AlignY"] = float(firstline[4]) + metadata["AvInten"] = float(firstline[5]) + elif mode == "dynamic": + metadata["?"] = float(firstline[3]) else: - assert False, 'mode not recognized' + assert False, "mode not recognized" return metadata - - -def _open_FilmSenseFile_standard (f): + +def _open_FilmSenseFile_standard(f): metadata = _parse_FilmSenseFileHeader(f.readline()) # Note - in the documentation the first numwvls lines are only supposed # have 4 columns. In these data files they have 8. - df = pd.DataFrame(columns=['Wavelength', 'led_Br', 'led_ExpL', 'led_ExpR', 'N', 'C', 'S', 'P', 'Intensity', 'Delta', 'Psi'], - index=np.linspace(1,metadata['numwvls'],metadata['numwvls'], dtype=int)) + df = pd.DataFrame( + columns=[ + "Wavelength", + "led_Br", + "led_ExpL", + "led_ExpR", + "N", + "C", + "S", + "P", + "Intensity", + "Delta", + "Psi", + ], + index=np.linspace(1, metadata["numwvls"], metadata["numwvls"], dtype=int), + ) - for i in range(metadata['numwvls']): - line = f.readline().split('\t') - df.iloc[i]['Wavelength'] = float(line[0]) - df.iloc[i]['led_Br'] = float(line[1]) - df.iloc[i]['led_ExpL'] = float(line[2]) - df.iloc[i]['led_ExpR'] = float(line[3]) + for i in range(metadata["numwvls"]): + line = f.readline().split("\t") + df.iloc[i]["Wavelength"] = float(line[0]) + df.iloc[i]["led_Br"] = float(line[1]) + df.iloc[i]["led_ExpL"] = float(line[2]) + df.iloc[i]["led_ExpR"] = float(line[3]) - for i in range(metadata['numwvls']): - line = f.readline().split('\t') - df.iloc[i]['N'] = float(line[0]) - df.iloc[i]['C'] = float(line[1]) - df.iloc[i]['S'] = float(line[2]) - df.iloc[i]['P'] = float(line[3]) - df.iloc[i]['Intensity'] = float(line[4]) + for i in range(metadata["numwvls"]): + line = f.readline().split("\t") + df.iloc[i]["N"] = float(line[0]) + df.iloc[i]["C"] = float(line[1]) + df.iloc[i]["S"] = float(line[2]) + df.iloc[i]["P"] = float(line[3]) + df.iloc[i]["Intensity"] = float(line[4]) - S = np.array(df['S'], dtype=np.float32) - N = np.array(df['N'], dtype=np.float32) - C = np.array(df['C'], dtype=np.float32) - df['Psi'] = np.rad2deg(np.arccos(N)/2) - #Delta1 = 180+np.rad2deg(np.arctan(np.array(df['S'], dtype=np.float32)/np.array(df['C'], dtype=np.float32))) + S = np.array(df["S"], dtype=np.float32) + N = np.array(df["N"], dtype=np.float32) + C = np.array(df["C"], dtype=np.float32) + df["Psi"] = np.rad2deg(np.arccos(N) / 2) + # Delta1 = 180+np.rad2deg(np.arctan(np.array(df['S'], dtype=np.float32)/np.array(df['C'], dtype=np.float32))) - df['Delta'] = np.rad2deg(np.angle((C+1j*S)/(1+N))) + df["Delta"] = np.rad2deg(np.angle((C + 1j * S) / (1 + N))) - Psi = np.array(df['Psi']).astype(np.float64) - Delta = np.array(df['Delta']).astype(np.float64) + Psi = np.array(df["Psi"]).astype(np.float64) + Delta = np.array(df["Delta"]).astype(np.float64) Deltamask = Delta < 0 - Delta[Deltamask] = 360 + Delta[Deltamask] + Delta[Deltamask] = 360 + Delta[Deltamask] - AOI = np.ones_like(Psi)*metadata['nomAOI'] - Wvl = np.array(df['Wavelength']).astype(np.float64) + AOI = np.ones_like(Psi) * metadata["nomAOI"] + Wvl = np.array(df["Wavelength"]).astype(np.float64) return DataSE(data=[Wvl, AOI, Psi, Delta], reflect_delta=False) - -def _open_FilmSenseFile_dynamic (f): - metadata = _parse_FilmSenseFileHeader(f.readline(), mode='dynamic') - base_df = pd.DataFrame(columns=['Wavelength', 'led_Br', 'led_ExpL', 'led_ExpR', 'N', 'C', 'S', 'P', 'Intensity', 'Delta', 'Psi'], - index=np.linspace(1,metadata['numwvls'],metadata['numwvls'], dtype=int)) +def _open_FilmSenseFile_dynamic(f): + metadata = _parse_FilmSenseFileHeader(f.readline(), mode="dynamic") + + base_df = pd.DataFrame( + columns=[ + "Wavelength", + "led_Br", + "led_ExpL", + "led_ExpR", + "N", + "C", + "S", + "P", + "Intensity", + "Delta", + "Psi", + ], + index=np.linspace(1, metadata["numwvls"], metadata["numwvls"], dtype=int), + ) + + for i in range(metadata["numwvls"]): + line = f.readline().split("\t") + base_df.iloc[i]["Wavelength"] = float(line[0]) + base_df.iloc[i]["led_Br"] = float(line[1]) + base_df.iloc[i]["led_ExpL"] = float(line[2]) + base_df.iloc[i]["led_ExpR"] = float(line[3]) - for i in range(metadata['numwvls']): - line = f.readline().split('\t') - base_df.iloc[i]['Wavelength'] = float(line[0]) - base_df.iloc[i]['led_Br'] = float(line[1]) - base_df.iloc[i]['led_ExpL'] = float(line[2]) - base_df.iloc[i]['led_ExpR'] = float(line[3]) - - + dataheader = f.readline().split("\t") - dataheader = f.readline().split('\t') - time_series = {} - for i in range(metadata['numdatasets']): + for i in range(metadata["numdatasets"]): line = f.readline()[:-2] - line = line.split('\t') + line = line.split("\t") time = float(line[0]) df = copy.deepcopy(base_df) - for j in range(metadata['numwvls']): - J = j*5 - df.iloc[j]['N'] = float(line[J+1]) - df.iloc[j]['C'] = float(line[J+2]) - df.iloc[j]['S'] = float(line[J+3]) - df.iloc[j]['P'] = float(line[J+4]) - df.iloc[j]['Intensity'] = float(line[J+5]) - - S = np.array(df['S'], dtype=np.float32) - N = np.array(df['N'], dtype=np.float32) - C = np.array(df['C'], dtype=np.float32) - df['Psi'] = np.rad2deg(np.arccos(N)/2) - df['Delta'] = np.rad2deg(np.angle((C+1j*S)/(1+N))) - - Psi = np.array(df['Psi']).astype(np.float64) - Delta = np.array(df['Delta']).astype(np.float64) + for j in range(metadata["numwvls"]): + J = j * 5 + df.iloc[j]["N"] = float(line[J + 1]) + df.iloc[j]["C"] = float(line[J + 2]) + df.iloc[j]["S"] = float(line[J + 3]) + df.iloc[j]["P"] = float(line[J + 4]) + df.iloc[j]["Intensity"] = float(line[J + 5]) + + S = np.array(df["S"], dtype=np.float32) + N = np.array(df["N"], dtype=np.float32) + C = np.array(df["C"], dtype=np.float32) + df["Psi"] = np.rad2deg(np.arccos(N) / 2) + df["Delta"] = np.rad2deg(np.angle((C + 1j * S) / (1 + N))) + + Psi = np.array(df["Psi"]).astype(np.float64) + Delta = np.array(df["Delta"]).astype(np.float64) Deltamask = Delta < 0 - Delta[Deltamask] = 360 + Delta[Deltamask] - AOI = np.ones_like(Psi)*metadata['nomAOI'] - Wvl = np.array(df['Wavelength']).astype(np.float64) + Delta[Deltamask] = 360 + Delta[Deltamask] + AOI = np.ones_like(Psi) * metadata["nomAOI"] + Wvl = np.array(df["Wavelength"]).astype(np.float64) time_series[time] = DataSE(data=[Wvl, AOI, Psi, Delta], reflect_delta=False) - - return time_series \ No newline at end of file + + return time_series diff --git a/refellips/objectiveSE.py b/refellips/objectiveSE.py index dcd5208..677061b 100644 --- a/refellips/objectiveSE.py +++ b/refellips/objectiveSE.py @@ -179,7 +179,9 @@ def residuals(self, pvals=None): wavelength, aoi, psi_d, delta_d = self.data.data wavelength_aoi = np.c_[wavelength, aoi] psi, delta = self.model(wavelength_aoi) - delta_err = 2*np.rad2deg(np.arcsin(np.sin(np.deg2rad(delta/2)) - np.sin(np.deg2rad(delta_d/2)))) + delta_err = 2 * np.rad2deg( + np.arcsin(np.sin(np.deg2rad(delta / 2)) - np.sin(np.deg2rad(delta_d / 2))) + ) return np.r_[psi - psi_d, delta_err] def chisqr(self, pvals=None): @@ -317,9 +319,7 @@ def logp(self, pvals=None): logp = np.sum( [ param.logp() - for param in f_unique( - p for p in flatten(self.parameters) if p.vary - ) + for param in f_unique(p for p in flatten(self.parameters) if p.vary) ] ) @@ -375,9 +375,7 @@ def logl(self, pvals=None): # here just set it to unity y_err = 1 if self.lnsigma is not None: - var_y = ( - y_err * y_err + np.exp(2 * float(self.lnsigma)) * model * model - ) + var_y = y_err * y_err + np.exp(2 * float(self.lnsigma)) * model * model else: var_y = y_err**2 @@ -494,9 +492,7 @@ def residuals_scaler(vals): scale = 1.0 # scale by reduced chi2 if experimental uncertainties weren't used. if not (self.weighted): - scale = self.chisqr() / ( - n_datapoints - len(self.varying_parameters()) - ) + scale = self.chisqr() / (n_datapoints - len(self.varying_parameters())) return covar * scale diff --git a/refellips/structureSE.py b/refellips/structureSE.py index 25c69fc..eda1b0b 100644 --- a/refellips/structureSE.py +++ b/refellips/structureSE.py @@ -111,9 +111,7 @@ def complex(self, wavelength): dispersion = self.epsilon(energies) return np.sqrt(dispersion) else: - raise NotImplementedError( - "epsilon or complex not defined for this object" - ) + raise NotImplementedError("epsilon or complex not defined for this object") def __call__(self, thick=0, rough=0, vfsolv=0): """ @@ -229,16 +227,12 @@ class SlabSE(ComponentSE): def __init__(self, thick, ri, rough, name="", vfsolv=0, interface=None): self.name = name self._interfaces = None - self.thick = possibly_create_parameter( - thick, name=f"{name} - thick", units="Å" - ) + self.thick = possibly_create_parameter(thick, name=f"{name} - thick", units="Å") if not isinstance(ri, ScattererSE): raise ValueError("ri should be a ScattererSE object") self.ri = ri - self.rough = possibly_create_parameter( - rough, name=f"{name} - rough", units="Å" - ) + self.rough = possibly_create_parameter(rough, name=f"{name} - rough", units="Å") self.vfsolv = possibly_create_parameter( vfsolv, name=f"{name} - volfrac solvent", bounds=(0.0, 1.0) ) @@ -328,18 +322,14 @@ def __init__( interface=None, ): super().__init__(name=name) - self.thick = possibly_create_parameter( - thick, name=f"{name} - thick", units="Å" - ) + self.thick = possibly_create_parameter(thick, name=f"{name} - thick", units="Å") self.ri_A = ri_A self.ri_B = ri_B self.vf_B = possibly_create_parameter( vf_B, name=f"{name} - vf_B", bounds=(0, 1) ) - self.rough = possibly_create_parameter( - rough, name=f"{name} - rough", units="Å" - ) + self.rough = possibly_create_parameter(rough, name=f"{name} - rough", units="Å") p = Parameters(name=self.name) p.append(self.thick) @@ -503,9 +493,7 @@ def depolarisation_factor(self, value): if 0 <= float(value) <= 1: self._depolarisation_factor = float(value) else: - raise ValueError( - "Depolarisation factor needs to be a float in [0, 1]." - ) + raise ValueError("Depolarisation factor needs to be a float in [0, 1].") def append(self, item): """ @@ -521,15 +509,12 @@ def append(self, item): return if not isinstance(item, ComponentSE): - raise ValueError( - "You can only add ComponentSE objects to a structure" - ) + raise ValueError("You can only add ComponentSE objects to a structure") super().append(item) def reflectivity(self): raise NotImplementedError( - "Use refellips.ReflectModelSE to calculate ellipsometric" - " parameters" + "Use refellips.ReflectModelSE to calculate ellipsometric" " parameters" ) def slabs(self, **kwds): @@ -592,8 +577,7 @@ def slabs(self, **kwds): return None if not ( - isinstance(self.data[-1], (SlabSE)) - and isinstance(self.data[0], (SlabSE)) + isinstance(self.data[-1], (SlabSE)) and isinstance(self.data[0], (SlabSE)) ): raise ValueError( "The first and last Components in a StructureSE need to be SlabsSE" @@ -695,9 +679,7 @@ def ri_profile(self, z=None, align=0, max_delta_z=None): if align != 0: align = int(align) if align >= len(slabs) - 1 or align < -1 * len(slabs): - raise RuntimeError( - "abs(align) has to be less than " "len(slabs) - 1" - ) + raise RuntimeError("abs(align) has to be less than " "len(slabs) - 1") # to figure out the offset you need to know the cumulative distance # to the interface slabs[0, 0] = slabs[-1, 0] = 0.0