class difference(Function): """Adds two nd arrays together""" def __init__(self): super().__init__("Addition") # inputs self.A = StreamInput(self, "a_p_norm") self.B = StreamInput(self, "a_a_norm") # outputs self.added = ArrayOutput(self, "added", self.read_added) # port declaration self.inputs = [ self.Reverse, self.A, self.B, ] self.outputs = [ self.added, ] def getpath(self, name): return_path = str(self) + "/" + name return return_path def evaluate(self): a = np.array(self.A.read()["data"][1]) b = np.array(self.B.read()["data"][1]) if a.ndim and b.ndim == 1: add = a + b elif a.ndim and b.ndim == 2: add_list = [] for i in range(a.shape[0]): add_i = a[i] + b[i] add_list.append(add_i) add = np.array(add_list) self.add_calc = np.array(add) self.lines = None def read_added(self): return { "data": [self.A.read()["data"][0], self.add_calc, self.lines], "label": self.A.read()["label"], }
class difference(Function): """takes the subtracts on spectra from another""" def __init__(self): super().__init__("Difference") # inputs self.A = StreamInput(self, "a_p_norm") self.B = StreamInput(self, "a_a_norm") self.Reverse = choice_input(self, "A-B", "A-B", ["A-B", "B-A"]) # outputs self.diff = ArrayOutput(self, "diff", self.read_diff) def evaluate(self): a = np.array(self.A.read()["data"][1]) b = np.array(self.B.read()["data"][1]) if a.ndim and b.ndim == 1: if self.Reverse.default == "A-B": diff = a - b else: diff = b - a elif a.ndim and b.ndim == 2: diff_list = [] for i in range(a.shape[0]): if self.Reverse.default == "A-B": diff_i = a[i] - b[i] diff_list.append(diff_i) else: diff_i = b[i] - a[i] diff_list.append(diff_i) diff = np.array(diff_list) self.diffs = diff self.lines = None def read_diff(self): return { "data": [self.A.read()["data"][0], self.diffs, self.lines], "label": self.A.read()["label"], }
class FindValue(Function): def __init__(self, name): super().__init__(name) # input ports self.inputarray = StreamInput(self, "inputarray") self.lookup = int_input(self, "lookup", self.inputarray, None) # output ports self.value = TextOutput(self, "value", self.read_value) self.graph = ArrayOutput(self, "graph", self.read_graph) def evaluate(self): x = np.array(self.inputarray.read()["data"][0]) y = np.array(self.inputarray.read()["data"][1]) if self.lookup.default: if x.ndim and y.ndim == 1: value = [y[find_array_equivalent(x, self.lookup.default)]] elif x.ndim and y.ndim == 2: value = [] for i in range(x.shape[0]): value_i = y[i][find_array_equivalent( x[i], self.lookup.default)] value.append(value_i) else: value = None self.value = value self.lines = [self.lookup.default] def read_value(self): return { "data": [self.inputarray.read()["data"][0], self.value], "label": self.inputarray.read()["label"], } # return self.value def read_graph(self): return { "data": [ self.inputarray.read()["data"][0], self.inputarray.read()["data"][1], self.lines, ], "label": self.inputarray.read()["label"], }
class Integrate(Function): def __init__(self): super().__init__("integrate") # input ports self.input = StreamInput(self, "inputarray") self.integral = ArrayOutput(self, "integral", self.read_integral) def evaluate(self): x = self.input.read()["data"][0] y = self.input.read()["data"][1] if x.ndim and y.ndim == 1: intgrl = integrate.cumtrapz( y[:], x[:], initial=0, ) elif x.ndim and y.ndim == 2: int_list = [] for i in range(x.shape[0]): integral_calc_ind_i = integrate.cumtrapz( y[i][:], x[i][:], initial=0, ) int_list.append(integral_calc_ind_i) intgrl = np.array(int_list) self.integral_calc = intgrl self.lines = None def read_integral(self): return { "data": [self.input.read()["data"][0], self.integral_calc, self.lines], "label": self.input.read()["label"], }
class scale(Function): """takes the subtracts on spectra from another""" def __init__(self): super().__init__("Scale") # inputs self.input = StreamInput(self, "input") # params self.scale_value = num_input(self, "scale_value", self.input, 1) # outputs self.scaled = ArrayOutput(self, "scaled", self.read_scaled) def evaluate(self): a = np.array(self.input.read()["data"][1]) if a.ndim == 1: ab = a * self.scale_value.default elif a.ndim == 2: scale_list = [] for i in range(a.shape[0]): scale_i = a[i] * self.scale_value.default scale_list.append(scale_i) ab = np.array(scale_list) self.scaled_calc = np.array(ab) self.lines = None def read_scaled(self): return { "data": [self.input.read()["data"][0], self.scaled_calc, self.lines], "label": self.input.read()["label"], }
class addition(Function): """Adds two nd arrays together""" def __init__(self): super().__init__("Addition") # inputs self.A = StreamInput(self, "A") self.B = StreamInput(self, "B") # outputs self.added = ArrayOutput(self, "added", self.read_added) def evaluate(self): a = np.array(self.A.read()["data"][1]) b = np.array(self.B.read()["data"][1]) if a.ndim and b.ndim == 1: add = a + b elif a.ndim and b.ndim == 2: add_list = [] for i in range(a.shape[0]): add_i = a[i] + b[i] add_list.append(add_i) add = np.array(add_list) self.add_calc = np.array(add) self.lines = None def read_added(self): return { "data": [self.A.read()["data"][0], self.add_calc, self.lines], "label": self.A.read()["label"], }
class single_step_subtraction(Function): """TODO: Centre the step function on the peaks energy!""" def __init__(self): super().__init__("step_subtraction") # Input Ports self.input_array = StreamInput(self, "input_array") self.apply_step = choice_input(self, "Apply", "on", ["on", "off"]) self.fit_function = choice_input(self, "fit_function", "Voight", ["Voight", "Arctan"]) self.step_start = int_input(self, "step_start", self.input_array, None) self.step_stop = int_input(self, "step_stop", self.input_array, None) self.edge = int_input(self, "edge", self.input_array, None) # output ports self.stepfunction = ArrayOutput(self, "stepfunction", self.read_stepfunction) self.subtracted_step = ArrayOutput(self, "post_step_a", self.read_subtracted_step) # evaluate method def evaluate(self): local_arguments = args_step(self) self.stepfunction_calc, self.subtracted_step_calc = single_step( energy=self.input_array.read()["data"][0], absorption=self.input_array.read()["data"][1], args=local_arguments, ) self.lines = [self.step_start.default, self.step_stop.default] def read_stepfunction(self): return { "data": [ self.input_array.read()["data"][0], self.stepfunction_calc, self.lines, ], "label": self.input_array.read()["label"], } # return self.stepfunction_a def read_subtracted_step(self): return { "data": [ self.input_array.read()["data"][0], self.subtracted_step_calc, self.lines, ], "label": self.input_array.read()["label"], }
class Transpose(Function): def __init__(self): super().__init__("Transpose") # streamed inputs self.spectra = StreamInput(self, "spectra") # parameter inputs self.action = choice_input(self, "Action", "on", ["off", "on"]) self.x_value_for_transpose = int_input(self, "x_value_for_transpose", self.spectra, 771) # output ports self.transposed_data = ArrayOutput(self, "transposed_data", self.read_transposed_data) def evaluate(self): local_arguments = args_transpose(self) self.transposed = Transpose_spectra( energy=self.spectra.read()["data"][0], absorption=self.spectra.read()["data"][1], args=local_arguments, ) self.lines = [self.x_value_for_transpose.default] def read_transposed_data(self): return { "data": [self.spectra.read()["data"][0], self.transposed, self.lines], "label": self.spectra.read()["label"], }
class convolve(Function): """ This create a sin function where the user can alter the frequency and amplitude """ def __init__(self): super().__init__("Convolve") # ports self.A = StreamInput(self, "A") self.B = StreamInput(self, "B") self.convolution = ArrayOutput(self, "convolution", self.read_convolution) def evaluate(self): self.conv_calc = self.A.read()["data"][1] + self.B.read()["data"][1] def read_convolution(self): return { "data": [self.A.read()["data"][0], self.conv_calc, None], "label": "s" }
class background_subtraction2(Function): def __init__(self): super().__init__("background_subtraction") # streamed inputs # self.e = StreamInput(self, "e") self.input_data = StreamInput(self, "input_data") # input.changed += self.on_data # parameter inputs self.fit = choice_input( fn=self, name="fit", default="No fit", choices=[ "No fit", "Polynomial fit inside limits", "Polynomial fit outside limits", "exp decay (fits for all e < 'Background_start' and e > ' Background_end')", "2 point linear (straight line between 2 points)", ], ) self.apply_offset = choice_input( fn=self, name="apply_offset", default="off", choices=[ "off", "on (shifts post 'Background_end' by amount equal to e = 'Background_end' to e = 'Background_start' )", ], ) # self.apply_offset = int_input(self, "apply_offset", 1, 1, 3) self.p_start = int_input(self, "Background_start", self.input_data, None) self.p_end = int_input(self, "Background_end", self.input_data, None) self.power = free_int_input(self, "power", 1, 1, 3) # output ports self.background = ArrayOutput(self, "background", self.read_background) self.subtracted_background = ArrayOutput( self, "subtracted_background", self.read_subtracted_background) # evaluate method def evaluate(self): local_arguments = args_background(self) x = self.input_data.read()["data"][0] y = self.input_data.read()["data"][1] ( self.x, self.calculated_subtracted_background, self.calculated_background, ) = calculate_background( x, y, local_arguments.p_start, local_arguments.p_end, local_arguments.power, local_arguments.fit, local_arguments.apply_offset, ) self.lines = [self.p_start.default, self.p_end.default] def read_background(self): return { "data": [ self.x, self.calculated_background, self.lines, ], "label": self.input_data.read()["label"], } def read_subtracted_background(self): return { "data": [ self.x, self.calculated_subtracted_background, self.lines, ], "label": self.input_data.read()["label"], }
class background_subtraction(Function): def __init__(self): super().__init__("background_subtraction") # streamed inputs # self.e = StreamInput(self, "e") self.t_p_all = StreamInput(self, "t_p_all") self.t_a_all = StreamInput(self, "t_a_all") # parameter inputs self.fit = choice_input( self, "fit", "No fit", [ "No fit", "Polynomial fit inside limits", "Polynomial fit outside limits", "exp decay (fits for all e < 'Background_start' and e > ' Background_end')", "2 point linear (straight line between 2 points)", ], ) self.apply_offset = choice_input( self, "apply_offset", "off", [ "off", "on (shifts post 'Background_end' by amount equal to e = 'Background_end' to e = 'Background_start' )", ], ) # self.apply_offset = int_input(self, "apply_offset", 1, 1, 3) self.p_start = int_input(self, "Background_start", self.t_p_all, None) self.p_end = int_input(self, "Background_end", self.t_p_all, None) self.power = free_int_input(self, "power", 1, 1, 4) # output ports self.a_p_background_subtraction = ArrayOutput( self, "a_p_background_subtraction", self.read_a_p_background_subtraction) self.a_a_background_subtraction = ArrayOutput( self, "a_a_background_subtraction", self.read_a_a_background_subtraction) self.a_p_background_subtracted = ArrayOutput( self, "a_p_background_subtracted", self.read_ia_p_background_subtracted) self.a_a_background_subtracted = ArrayOutput( self, "a_a_background_subtracted", self.read_ia_a_background_subtracted) # self.e_out= ArrayOutput(self, "e_out", self.read_e_out) # publish ports self.inputs = [ # self.e, self.t_p_all, self.t_a_all, self.fit, self.apply_offset, self.p_start, self.p_end, self.power, ] self.outputs = [ self.a_p_background_subtraction, self.a_a_background_subtraction, self.a_p_background_subtracted, self.a_a_background_subtracted, # self.e_out, ] # evaluate method def evaluate(self): local_arguments = args_background(self) x1 = self.t_p_all.read()["data"][0] y1 = self.t_p_all.read()["data"][1] x2 = self.t_a_all.read()["data"][0] y2 = self.t_a_all.read()["data"][1] ( self.x1, self.calculated_subtracted_background1, self.calculated_background1, ) = calculate_background( x1, y1, local_arguments.p_start, local_arguments.p_end, local_arguments.power, local_arguments.fit, local_arguments.apply_offset, ) ( self.x2, self.calculated_subtracted_background2, self.calculated_background2, ) = calculate_background( x2, y2, local_arguments.p_start, local_arguments.p_end, local_arguments.power, local_arguments.fit, local_arguments.apply_offset, ) self.lines = [self.p_start.default, self.p_end.default] def read_a_p_background_subtraction(self): return { "data": [self.x1, self.calculated_background1, self.lines], "label": self.t_p_all.read()["label"], } def read_a_a_background_subtraction(self): return { "data": [self.x2, self.calculated_background2, self.lines], "label": self.t_p_all.read()["label"], } def read_ia_p_background_subtracted(self): return { "data": [self.x1, self.calculated_subtracted_background1, self.lines], "label": self.t_p_all.read()["label"], } def read_ia_a_background_subtracted(self): return { "data": [self.x2, self.calculated_subtracted_background2, self.lines], "label": self.t_p_all.read()["label"], }
class SumRules(Function): def __init__(self): super().__init__("SumRules") self.p = StreamInput(self, "p") self.q = StreamInput(self, "q") self.r = StreamInput(self, "r") self.shell_occupation = num_input(self, "shell_occupation", self.p, 7.51) self.ratio = TextOutput(self, r"ratio = \frac{2q} {9p - 6p}", self.read_ratio) self.orbitalmoment = TextOutput( self, "orbital moment \frac{4 q} {3 r} * (10 - n3d) ", self.read_orbitalmoment, ) self.spinmoment = TextOutput(self, "spin moment \frac{2q} {9p - 6p}", self.read_spinmoment) def evaluate(self): n3d = self.shell_occupation.default valuep = self.p.read()["data"][1] valueq = self.q.read()["data"][1] valuer = self.r.read()["data"][1] if valuep and valuep and valuep != None: if len(valuep) == 1: p = float(valuep[0]) q = float(valueq[0]) r = float(valuer[0]) # sum rules ratio = [2 * q / ((9 * p) - (6 * q))] orbital = [-((4 * q) * (10 - n3d)) / (3 * r)] spin = [-((6 * p - 4 * q) * (10 - n3d)) / r] else: ratio = [] spin = [] orbital = [] for i in range(np.array(valuep).shape[0]): # local variables p = float(valuep[i]) q = float(valueq[i]) r = float(valuer[i]) # sum rules ratio_i = 2 * q / ((9 * p) - (6 * q)) orbital_i = -((4 * q) * (10 - n3d)) / (3 * r) spin_i = -((6 * p - 4 * q) * (10 - n3d)) / r # append ratio.append(ratio_i) orbital.append(orbital_i) spin.append(spin_i) else: ratio = None spin = None orbital = None self.ratio = ratio self.spin = spin self.orbital = orbital self.lines = None def read_ratio(self): return { "data": [self.p.read()["data"][0], self.ratio, self.lines], "label": self.p.read()["label"], } # return self.ratio def read_orbitalmoment(self): return { "data": [self.p.read()["data"][0], self.orbital, self.lines], "label": self.p.read()["label"], } # return self.orbital def read_spinmoment(self): return { "data": [self.p.read()["data"][0], self.spin, self.lines], "label": self.p.read()["label"], }
class IdentifyPeaks(Function): """TODO: Centre the step function on the peaks energy!""" def __init__(self): super().__init__("Identify Peaks") # Input Ports self.input_array = StreamInput(self, "input_array") self.number_of_peaks = free_int_input(self, "number_of_peaks", 1, 2, 10) self.center_of_peaks = int_input( self, "center_of_peaks", self.input_array, 5990 ) self.sigma_of_peaks = int_input(self, "sigma_of_peaks", self.input_array, 30) self.height_of_peaks = int_input( self, "height_of_peaks", self.input_array, 0.12 ) self.type_of_peaks = choice_input( self, "GaussianModel", "GaussianModel", ["GaussianModel", "LorentzianModel"] ) # output ports self.fitted_peaks = ArrayOutput(self, "fitted_peaks", self.read_fitted_peaks) # evaluate method def evaluate(self): # argument cantains peak information in default values (updated from GUI) local_arguments = args(self) # we set up a list with information to givew to Model. Looks like; # { # 'type': 'GaussianModel', # 'params': {'center': 652, 'height': 82, 'sigma': 60}, # }, fit = [] for i in range(self.number_of_peaks.default): model_type = str(self.type_of_peaks.default) params = { "center": self.center_of_peaks.default, "height": self.height_of_peaks.default, "sigma": self.sigma_of_peaks.default, } model_params = { "type": model_type, "params": params, } fit.append(model_params) print(fit) fitting_params = fit # perform fit (returns a list of arrays of each peak.) self.fitted_energy_scale_calc, self.fitted_peaks_calc = fit_peaks_to_data( energy=self.input_array.read()["data"][0], intensity=self.input_array.read()["data"][1], args=local_arguments, fitting_params=fit, ) # self.fitted_peaks = self.input_array.read()["data"][1] # lines representing the peak positions. self.lines = None def read_input_array(self): return { "data": [ self.input_array.read()["data"][0], self.input_array.read()["data"][1], self.lines, ], "label": self.input_array.read()["label"], } # return self.stepfunction_a def read_fitted_peaks(self): return { "data": [self.fitted_energy_scale_calc, self.fitted_peaks_calc, self.lines], "label": self.input_array.read()["label"], }
class single_step_subtraction_xanes(Function): """TODO: Centre the step function on the peaks energy!""" def __init__(self): super().__init__("step_subtraction") # Input Ports self.input_array = StreamInput(self, "input_array") self.apply_step = choice_input(self, "Apply", "off", ["off", "on"]) self.fit_function = choice_input(self, "fit_function", "Voight", ["Voight", "Arctan"]) self.pre_feature_min = int_input(self, "pre_feature_min", self.input_array, None) self.pre_feature_max = int_input(self, "pre_feature_max", self.input_array, None) self.post_feature_min = int_input(self, "post_feature_min", self.input_array, None) self.post_feature_max = int_input(self, "post_feature_max", self.input_array, None) # output ports self.stepfunction = ArrayOutput(self, "stepfunction", self.read_stepfunction) self.subtracted_step = ArrayOutput(self, "subtracted_step", self.read_subtracted_step) # evaluate method def evaluate(self): local_arguments = args_step(self) x = self.input_array.read()["data"][0] y = self.input_array.read()["data"][1] pre_feature_min = local_arguments.pre_feature_min pre_feature_max = local_arguments.pre_feature_max post_feature_min = local_arguments.post_feature_min post_feature_max = local_arguments.post_feature_max if local_arguments.apply_step == "off": x = x background = make_zero_array(x) y = y - background else: x, y, background = pre_edge_fit( x, y, pre_feature_min, pre_feature_max, post_feature_min, post_feature_max, ) self.x = x self.y = y self.background = background self.lines = [ pre_feature_min, pre_feature_max, post_feature_min, post_feature_max, ] def read_stepfunction(self): return { "data": [self.x, self.background, self.lines], "label": self.input_array.read()["label"], } # return self.stepfunction_a def read_subtracted_step(self): return { "data": [self.x, self.y, self.lines], "label": self.input_array.read()["label"], } # return self.post_step_p def calculate_fit(self, x, y, argument): pass
class EXAFSStreamParser(Function): def __init__(self): super().__init__("EXAFSStreamParser") # input ports self.input = StreamInput(self, "in") self.average_data = choice_input(self, "Average data", "off", ["off", "on"]) # output ports self.e = ArrayOutput(self, "e", self.read_e) self.intensity = ArrayOutput(self, "intensity", self.read_intensity) self.e_data = None self.intensity_data = None def evaluate(self): # e = None # Common energy scale extracted from first sample set intensity_all = [] e_all = [] names = [] for file in self.input.read(): name = os.path.basename(os.path.normpath(file)) # parse_data_file is a defined function at top (it extracts columns) f = open(file) data = f.read() samples = parse_xanes_data_file(data) energy = [sample.energy for sample in samples] intensity = [sample.intensity for sample in samples] # Sanity check # if len(t_p) != len(t_a): # raise Exception(" - Check SELECT_COL is selecting the correct columns from data file Number of parallel (%d) and anti-parallel (%d) samples differ" % (len(t_p), len(t_a))) # Add to array for averaging intensity_all.append(intensity) e_all.append(energy) # uncomment for XMLD # t_p_all.append(t_a[0:int(len(t_a)/2 -1)]) # t_a_all.append(t_a[int(len(t_a)/2):-1]) # e_all.append(e[0:int(len(t_a)/2 -1)]) names.append(name) # write data to ports if self.average_data.default == "on": self.intensity_all_data = [ np.mean(np.array(intensity_all), axis=0) ] self.e_all_data = [np.mean(np.array(e_all), axis=0)] self.label = "Averaged" else: self.intensity_all_data = np.array(intensity_all) self.e_all_data = np.array(e_all) self.label = names self.lines = None def read_intensity(self): return { "data": [self.e_all_data, self.intensity_all_data, self.lines], "label": self.label, } # return self.t_a_all_data def read_e(self): return { "data": [self.e_all_data, self.e_all_data, self.lines], "label": self.label, }
class XMCDStreamParser(Function): def __init__(self): super().__init__("XMCDStreamParser") # input ports self.input = StreamInput(self, "in") self.average_data = choice_input(self, "Average data", "off", ["off", "on"]) # output ports self.t_a_all = ArrayOutput(self, "t_a_all", self.read_t_a) self.t_p_all = ArrayOutput(self, "t_p_all", self.read_t_p) self.e = ArrayOutput(self, "e", self.read_e) # declare self.inputs = [ self.input, self.average_data, ] self.outputs = [ self.t_a_all, self.t_p_all, self.e, ] self.t_a_all_data = None self.t_p_all_data = None self.e_data = None self.parent = Function '''def getpath(self, name): # pass instance of class as path return_path = str(self) + "/" + str(name) # return_path = self.parent.getpath(self, str(self.__class__) + "/" + str(name)) # return_path = self.parent.getpath(self, str(self.__class__.__name__) + "/" + str(name)) return return_path''' def evaluate(self): # e = None # Common energy scale extracted from first sample set t_p_all = [] # Array of Parallel transmission series from each file t_a_all = [] e_all = [] names = [] for file in self.input.read(): name = os.path.basename(os.path.normpath(file)) # parse_data_file is a defined function at top (it extracts columns) f = open(file) data = f.read() samples = parse_xmcd_data_file(data) # Sanity checks angle = [sample.angle for sample in samples] ioes = [sample.ioes for sample in samples] # change if len(samples) % 2: raise Exception( " - Expected even number of samples, found odd number (%d) of samples" % len(samples)) # ------------------------------------------------------------------------ # Extract Energy series from 1st file only. Assume same in the rest. # ------------------------------------------------------------------------ # if not e: # Assume parallel and anti-parallel samples have same energy sequence # and extract from one set or other. e = [sample.e for sample in samples if sample.mag < 0] # ------------------------------------------------------------------------ # Parallel & Anti-parallel Transmission # ----------------------------------------------------------------------- t_p = [ sample.transmission for sample in samples if sample.mag >= 0 ] t_a = [sample.transmission for sample in samples if sample.mag < 0] # uncomment for XMLD """print(len(t_a)) if len(t_p) == 0: t_p = t_a[0:500] t_a = t_a[501: 1001] e = e[0:500] if len(t_p) == 0: t_p = t_p[0:len(t_p)/2 -1] t_a = t_p[len(t_p)/2: len(t_p)] e=e[0:len(t_a)/2] print(len(t_p))""" # Sanity check if len(t_p) != len(t_a): raise Exception( " - Check SELECT_COL is selecting the correct columns from data file. Number of parallel (%d) and anti-parallel (%d) samples differ" % (len(t_p), len(t_a))) # Add to array for averaging t_p_all.append(t_p) t_a_all.append(t_a) e_all.append(e) # uncomment for XMLD # t_p_all.append(t_a[0:int(len(t_a)/2 -1)]) # t_a_all.append(t_a[int(len(t_a)/2):-1]) # e_all.append(e[0:int(len(t_a)/2 -1)]) names.append(name) # write data to ports if self.average_data.default == "on": self.t_a_all_data = np.mean(np.array(t_a_all), axis=0) self.t_p_all_data = np.mean(np.array(t_p_all), axis=0) self.e_data = np.mean(np.array(e_all), axis=0) self.label = "Average" else: self.t_a_all_data = np.array(t_a_all) self.t_p_all_data = np.array(t_p_all) self.e_data = np.array(e_all) self.label = names self.lines = None def read_t_a(self): return { "data": [self.e_data, self.t_a_all_data, self.lines], "label": self.label, } # return self.t_a_all_data def read_t_p(self): return { "data": [self.e_data, self.t_p_all_data, self.lines], "label": self.label, } # return self.t_p_all_data def read_e(self): return { "data": [self.e_data, self.e_data, self.lines], "label": self.label }
class Xas(Function): def __init__(self): super().__init__("XAS spectra") # inputs self.a_p_norm = StreamInput(self, "a_p_norm") self.a_a_norm = StreamInput(self, "a_a_norm") # parameter inputs self.fit = choice_input( self, "fit", "Do Nothing!!", [ "linear", "polynomial", "exp decay", "2 point linear", "Do Nothing!!" ], ) self.background_start = int_input(self, "p_start_xas", self.a_p_norm, 770) self.background_stop = int_input(self, "p_stop_xas", self.a_p_norm, 805) # outputs self.xas = ArrayOutput(self, "xas", self.read_xas) self.xas_bg = ArrayOutput(self, "xas_bg", self.read_xas_bg) self.xas_integral = ArrayOutput(self, "xas_integral", self.read_xas_integral) def evaluate(self): local_arguments = args_xas(self) ax = np.array(self.a_p_norm.read()["data"][0]) bx = np.array(self.a_a_norm.read()["data"][0]) ay = np.array(self.a_p_norm.read()["data"][1]) by = np.array(self.a_a_norm.read()["data"][1]) if ax.ndim and bx.ndim == 1: add = by + ay integral_start = find_array_equivalent( ax, local_arguments.background_start) integral_end = find_array_equivalent( ax, local_arguments.background_stop) xas_bg_i, xas_i = background_xmcd( energy=np.array(ax), xmcd=add, args=local_arguments, ) xas_integral_i = integrate.cumtrapz( xas_i[integral_start:integral_end], ax[integral_start:integral_end], ) # self.xas_integral = np.append(xas_integral[0], xas_integral[0][-1]) xas_integral1 = np.concatenate([ zerolistmaker(len(ax[0:integral_start] + 1)), xas_integral_i, (zerolistmaker(len(ax[integral_end:]) + 1) + xas_integral_i[-1]), ]) xas_integral = np.array(xas_integral1) xas_bg = np.array(xas_bg_i) xas = np.array(xas_i) elif ax.ndim and bx.ndim == 2: xas_bg = [] xas = [] xas_integral = [] for i in range(ax.shape[0]): add = (np.array(self.a_p_norm.read()["data"][1])[i] + np.array(self.a_a_norm.read()["data"][1])[i]) integral_start = find_array_equivalent( self.a_a_norm.read()["data"][0][i], local_arguments.background_start) integral_end = find_array_equivalent( self.a_a_norm.read()["data"][0][i], local_arguments.background_stop) xas_bg_i, xas_i = background_xmcd( energy=np.array(self.a_a_norm.read()["data"][0])[i], xmcd=add, args=local_arguments, ) xas_integral_i = integrate.cumtrapz( xas_i[integral_start:integral_end], self.a_a_norm.read()["data"][0][i] [integral_start:integral_end], ) # self.xas_integral = np.append(xas_integral[0], xas_integral[0][-1]) xas_integral1 = np.concatenate([ zerolistmaker( len(self.a_a_norm.read()["data"][0][0] [0:integral_start] + 1)), xas_integral_i, (zerolistmaker( len(self.a_a_norm.read()["data"][0][0][integral_end:]) + 1) + xas_integral_i[-1]), ]) xas_integral_i = list(xas_integral1) xas_integral.append(xas_integral_i) xas.append(xas_i) xas_bg.append(xas_bg_i) xas_bg = np.array(xas_bg) xas = np.array(xas) xas_integral = np.array(xas_integral) self.xas_calc = xas self.xas_bg_calc = xas_bg self.xas_integral_calc = xas_integral self.lines = [ self.background_start.default, self.background_stop.default ] def read_xas(self): return { "data": [self.a_a_norm.read()["data"][0], self.xas_calc, self.lines], "label": self.a_p_norm.read()["label"], } # return self.xas def read_xas_bg(self): return { "data": [self.a_a_norm.read()["data"][0], self.xas_bg_calc, self.lines], "label": self.a_p_norm.read()["label"], } # return self.xas_bg def read_xas_integral(self): return { "data": [ self.a_a_norm.read()["data"][0], self.xas_integral_calc, self.lines, ], "label": self.a_p_norm.read()["label"], }
class step_subtraction(Function): """TODO: Centre the step function on the peaks energy!""" def __init__(self): super().__init__("step_subtraction") # Input Ports self.a_p_norm = StreamInput(self, "a_p_norm") self.a_a_norm = StreamInput(self, "a_a_norm") self.apply_step = choice_input(self, "Apply", "off", ["off", "on"]) self.fit_type = choice_input(self, "fit_type", "Alpha", ["Alpha", "Beta"]) self.fit_function = choice_input(self, "fit_function", "Voight", ["Voight", "Arctan"]) self.step_start = int_input(self, "step_start", self.a_p_norm, None) self.step_intermediate = int_input(self, "step_intermediate", self.a_p_norm, None) self.step_stop = int_input(self, "step_stop", self.a_p_norm, None) # output ports self.a_a_stepfunction = ArrayOutput(self, "a_a_stepfunction", self.read_a_a_stepfunction) self.a_p_stepfunction = ArrayOutput(self, "a_p_stepfunction", self.read_a_p_stepfunction) self.a_a_step_subtracted = ArrayOutput(self, "a_a_step_subtracted", self.read_a_a_step_subtracted) self.a_p_step_subtracted = ArrayOutput(self, "a_p_step_subtracted", self.read_a_p_step_subtracted) # evaluate method def evaluate(self): local_arguments = args_step(self) x1 = self.a_a_norm.read()["data"][0] y1 = self.a_a_norm.read()["data"][1] x2 = self.a_p_norm.read()["data"][0] y2 = self.a_p_norm.read()["data"][1] self.x1, self.post_step1, self.stepfunction1 = self.invoke_step_function( x1, y1, local_arguments) self.x2, self.post_step2, self.stepfunction2 = self.invoke_step_function( x2, y2, local_arguments) self.lines = [ self.step_start.default, self.step_intermediate.default, self.step_stop.default, ] def read_a_a_stepfunction(self): return { "data": [self.x1, self.stepfunction1, self.lines], "label": self.a_p_norm.read()["label"], } # return self.stepfunction_a def read_a_p_stepfunction(self): return { "data": [self.x2, self.stepfunction2, self.lines], "label": self.a_p_norm.read()["label"], } # return self.stepfunction_p def read_a_a_step_subtracted(self): return { "data": [self.x1, self.post_step1, self.lines], "label": self.a_p_norm.read()["label"], } # return self.post_step_a def read_a_p_step_subtracted(self): return { "data": [self.x2, self.post_step2, self.lines], "label": self.a_p_norm.read()["label"], } # return self.post_step_p def invoke_step_function(self, x: np.ndarray, y: np.ndarray, arguments): # arguments to relay start = arguments.step_start intermediate = arguments.step_intermediate stop = arguments.step_stop function = arguments.fit_function fittype = arguments.fit_type if arguments.apply_step == "off": x_return = x y_return = y step_return = make_zero_array(x) elif arguments.apply_step == "on": if np.array(y).ndim and np.array(x).ndim == 1: x_return, y_return, step_return = step3( x, y, start, intermediate, stop, function, fittype) elif np.array(y).ndim and np.array(x).ndim == 2: xlist = [] ylist = [] steplist = [] for i in range(np.array(y).shape[0]): xi, yi, stepi = step3(x[i], y[i], start, intermediate, stop, function, fittype) xlist.append(xi) ylist.append(yi) steplist.append(stepi) x_return = np.array(xlist) y_return = np.array(ylist) step_return = np.array(steplist) else: print("not 1 or 2 dimensions") x_return = x y_return = y step_return = make_zero_array(x) else: print("else, what") x_return = x y_return = y step_return = make_zero_array(x) return x_return, y_return, step_return
class Area(Function): def __init__(self): super().__init__("area") # input ports self.input = StreamInput(self, "inputarray") # int_input takes arguments (fn, name, input_stream) # The input_stream allows for limits to be calculated for GUI sliders. self.start = int_input(self, "start", self.input, 770) self.mid = int_input(self, "mid", self.input, 790) self.end = int_input(self, "end", self.input, 800) # self.value = TextOutput(self, "value", self.read_value) self.graph = ArrayOutput(self, "graph", self.read_graph) def evaluate(self): x = np.array(self.input.read()["data"][0]) y = np.array(self.input.read()["data"][1]) if x.ndim and y.ndim == 1: start = find_array_equivalent(x, self.start.default) mid = find_array_equivalent(x, self.mid.default) end = find_array_equivalent(x, self.end.default) a_l3 = integrate.cumtrapz( y[start:mid], x[start:mid], initial=0, ) a_l2 = integrate.cumtrapz( y[mid:end], x[mid:end], initial=0, ) b_ratio = [a_l3[-1] / (a_l2[-1] + a_l3[-1])] elif x.ndim and y.ndim == 2: bratio_list = [] for i in range(x.shape[0]): start = find_array_equivalent(x[i], self.start.default) mid = find_array_equivalent(x[i], self.mid.default) end = find_array_equivalent(x[i], self.end.default) a_l3 = integrate.cumtrapz( y[i][start:mid], x[i][start:mid], initial=0, ) a_l2 = integrate.cumtrapz( y[i][mid:end], x[i][mid:end], initial=0, ) b_ratio = a_l3[-1] / (a_l2[-1] + a_l3[-1]) bratio_list.append(b_ratio) b_ratio = list(bratio_list) self.value_calc = b_ratio self.lines = [self.start.default, self.mid.default, self.end.default] def read_value(self): return { "data": [self.input.read()["data"][0], self.value_calc], "label": self.input.read()["label"], } # return self.value def read_graph(self): return { "data": [ self.input.read()["data"][0], self.input.read()["data"][1], self.lines, ], "label": self.input.read()["label"], }
class Normalise(Function): def __init__(self): super().__init__("Normalise") # streamed inputs self.t_p_all = StreamInput(self, "t_p_all") self.t_a_all = StreamInput(self, "t_a_all") # parameter inputs self.action = choice_input( self, "Action", "Do not Apply", ["Do not Apply", "Apply"] ) self.normalise_point_1 = int_input( self, "normalise_point_1", self.t_p_all, None ) self.normalise_point_2 = int_input( self, "normalise_point_2", self.t_p_all, None ) # output ports self.a_p_norm = ArrayOutput(self, "a_p_norm", self.read_a_p_norm) self.a_a_norm = ArrayOutput(self, "a_a_norm", self.read_a_a_norm) def evaluate(self): local_arguments = args_normalise(self) x1 = self.t_p_all.read()["data"][0] y1 = self.t_p_all.read()["data"][1] x2 = self.t_a_all.read()["data"][0] y2 = self.t_a_all.read()["data"][1] self.x1, self.a_p_normalised1 = self.invoke_normalise_function( x1, y1, local_arguments ) self.x2, self.a_p_normalised2 = self.invoke_normalise_function( x2, y2, local_arguments ) self.lines = [self.normalise_point_1.default, self.normalise_point_2.default] def read_a_p_norm(self): return { "data": [self.x1, self.a_p_normalised1, self.lines], "label": self.t_p_all.read()["label"], } # return self.ia_p_norm def read_a_a_norm(self): return { "data": [self.x2, self.a_p_normalised2, self.lines], "label": self.t_p_all.read()["label"], } # return self.ia_a_norm def invoke_normalise_function(self, x, y, arguments): p1 = arguments.normalise_point_1 p2 = arguments.normalise_point_2 if arguments.action == "Do not Apply": x = x y = y elif arguments.action == "Apply": if np.array(x).ndim and np.array(y).ndim == 1: x, y = Normalise_spectra(x, y, p1, p2) elif np.array(x).ndim and np.array(y).ndim == 2: x_list = [] y_list = [] for i in range(x.shape[0]): xi, yi = Normalise_spectra(x[i], y[i], p1, p2) x_list.append(xi) y_list.append(yi) x = np.array(x_list) y = np.array(y_list) return x, y