Source code for xarpes.functions

# Copyright (C) 2024 xARPES Developers
# This program is free software under the terms of the GNU GPLv3 license.

"""Separate functions mostly used in conjunction with various classes."""

[docs] def download_examples(): """Downloads the examples folder from the xARPES code only if it does not already exist. Prints executed steps and a final cleanup/failure message. Returns ------- 0, 1 : int Returns 0 if the execution succeeds, 1 if it fails. """ import requests import zipfile import os import shutil import io repo_url = 'https://github.com/xARPES/xARPES_examples' output_dir = '.' # Directory from which the function is called # Check if 'examples' directory already exists final_examples_path = os.path.join(output_dir, 'examples') if os.path.exists(final_examples_path): print("Warning: 'examples' folder already exists. No download will be performed.") return 1 # Exit the function if 'examples' directory exists # Proceed with download if 'examples' directory does not exist repo_parts = repo_url.replace("https://github.com/", "").rstrip('/') zip_url = f"https://github.com/{repo_parts}/archive/refs/heads/main.zip" # Make the HTTP request to download the zip file print(f"Downloading {zip_url}") response = requests.get(zip_url) if response.status_code == 200: zip_file_bytes = io.BytesIO(response.content) with zipfile.ZipFile(zip_file_bytes, 'r') as zip_ref: zip_ref.extractall(output_dir) # Path to the extracted main folder main_folder_path = os.path.join(output_dir, repo_parts.split('/')[-1] + '-main') examples_path = os.path.join(main_folder_path, 'examples') # Move the 'examples' directory to the target location if it was extracted if os.path.exists(examples_path): shutil.move(examples_path, final_examples_path) print(f"'examples' subdirectory moved to {final_examples_path}") else: print("'examples' subdirectory not found in the repository.") # Remove the rest of the extracted content shutil.rmtree(main_folder_path) print(f"Cleaned up temporary files in {main_folder_path}") return 0 else: print(f"Failed to download the repository. Status code: {response.status_code}") return 1
[docs] def error_function(p, xdata, ydata, function, extra_args): r"""The error function used inside the fit_leastsq function. Parameters ---------- p : ndarray Array of parameters during the optimization xdata : ndarray Array of abscissa values the function is evaluated on ydata : ndarray Outcomes on ordinate the evaluated function is compared to function : function Function or class with call method to be evaluated extra_args : Arguments provided to function that should not be optimized Returns ------- residual : Residual between evaluated function and ydata """ residual = function(xdata, *p, extra_args) - ydata return residual
[docs] def fit_leastsq(p0, xdata, ydata, function, extra_args): r"""Wrapper arround scipy.optimize.leastsq. Parameters ---------- p0 : ndarray Initial guess for parameters to be optimized xdata : ndarray Array of abscissa values the function is evaluated on ydata : ndarray Outcomes on ordinate the evaluated function is compared to function : function Function or class with call method to be evaluated extra_args : Arguments provided to function that should not be optimized Returns ------- pfit_leastsq : ndarray Array containing the optimized parameters perr_leastsq : ndarray Covariance matrix of the optimized parameters """ import numpy as np from scipy.optimize import leastsq pfit, pcov, infodict, errmsg, success = leastsq( error_function, p0, args=(xdata, ydata, function, extra_args), full_output=1) if (len(ydata) > len(p0)) and pcov is not None: s_sq = (error_function(pfit, xdata, ydata, function, extra_args) ** 2).sum() / (len(ydata) - len(p0)) pcov = pcov * s_sq else: pcov = np.inf error = [] for i in range(len(pfit)): try: error.append(np.absolute(pcov[i][i]) ** 0.5) except: error.append(0.00) pfit_leastsq = pfit perr_leastsq = np.array(error) return pfit_leastsq, perr_leastsq