The Python scripts for the manuscript were executed with Python V3.10.12.
The following package versions are recommended for reproducing the results:
When using Conda, the suggested versions can be installed with:
conda create -n xarpes python=3.10.12
conda activate xarpes
pip install abipy==0.9.8
pip install blochpesto==1.1.1
pip install igor2==0.5.12
pip install lmfit==1.3.1
pip install matplotlib==3.8.4
pip install mpmath==1.3.0
pip install numba==0.60.0
pip install numpy==1.26.4
pip install pandas==2.2.2
pip install pymatgen==2024.10.29
pip install scipy==1.13.0
Supp_Fig_4_data folder can be copied inside Figures_and_tables/Supp_Fig_4/ to post-process the ABINIT calculations.generate_figure_n.py ( script to generate the $n^{\text{th}}$ figure. For all of the figure folders, one can either copy-paste everything from Data/Figure_n_data (or Data/Supp_Fig_n_data) into Figures_and_tables/Figure_n/Figure_n_data (Figures_and_tables/Supp_Fig_n/Supp_Fig_n_data) or copy-paste the minimum required files (specified in each case), after which the figure can be generated with generate_fig_n.py (generate_figure_sn.py).mrel times the default value (1.5875 $m_{\mathrm{e}}$), $k_{\mathrm{R}}^{\mathrm{F}}$ is equal to krel times the default value (0.25 Å$^{-1}$), $\Gamma_{\mathrm{R}}^{\mathrm{imp}}$ is equal to dive, $\lambda_{\mathrm{R}}^{\mathrm{el}}$ is equal to lmbe, and $h_{\mathrm{R}}$ is equal to $m_0$.fig1v1.svg figure as a .pdf file.fig_1a.asy, which is subsequently imported as a .png into fig1v1.svg.Figure 2 can be generated by executing the .tex file with pdflatex in $\LaTeX$.
Figure_3_data is initially empty, but can be populated by executing test_loop_se.py and analyse_mock.py. Alternatively, they can be copy-pasted from Data/Figure_3_data.generate_figure_3.py, which generates an artificial band map, and performs the desired tests on it.test_loop_se.py, which performs the self-energy extraction for different Fermi energies and energy resolutions.Figure_4_data is initially empty, but it can be populated by executing analyse_mock.py to generate results for panel $\textbf{a}$. This script generates an artificial band maps, followed by extracting from it the self-energy and Eliashberg function.analyse_ideal.py for panel $\textbf{b}$, which does the same thing as analyse_mock.py, except now with ideal data.test_loop_a2f_fast.py for panel $\textbf{c}$, which simulates data with noise for rpts cases, and may take several minutes to complete. If it is desired to quickly test the entire workflow, the variable rpts in test_loop_a2f_fast.py can be set to a lower number of iterations (say, 5). This variable represents the number of data pairs $N_{J}$ in the text.Data/Figure_4_data.analyse_mock.py under the header # Optimized right can be obtained by executing mock_optimisation.right.py. After an optimisation that might take a minute or so, the optimised parameters can be copied from the script artificial_einstein_right.txt created in Figure_4_data.Figure_5_data is initially empty. Copy the experimental bandmap from Data/Figure_5_data/STO_2_0010STO_2_.txt into Figures_and_tables/Figure_5/Figure_5_data to execute the scripts described below.tio2_2023_single.py and tio2_2023_nomec.py. These scripts need to be executed first. Afterwards, the Bayesian loop scripts can be executed, which may take a minute or two to complete.default_inner_left.py and default_inner_right.py write to STO_2_0010STO_2__inner_left.txt and STO_2_0010STO_2__inner_right.txt for the parameters in tio2_2023_single.py. The scripts default_right.py and nomec_right.py write to STO_2_0010STO_2__right.txt and STO_2_0010STO_2__mec_pars_right.txt for the parameters in tio2_2023_nomec.pyFigure_6_data is initially empty. Copy the experimental bandmap from Data/Figure_6_data/graphene_raw_cut_2.txt into Figures_and_tables/Figure_6/graphene_raw_cut_2.txt to execute the scripts described below.graphene_linearised.py. Afterwards, the Bayesian loop scripts left_linear_optimisation.py and right_linear_optimisation.py can be executed. Especially the former script can take longer than the other optimization scripts to complete -- say 5 to 10 minutes on a workstation -- as the cost function for these data is somewhat flat near the minimum.Figure 7 shows the Fermi edge from Li-doped graphene. The results are obtained by executing graphene_cut2.py.
Supp_Fig_1_data can be replaced by the version inside Data to obtain all optimized results.analyse_mock.py, followed by optimising them with mock_optimisation_right.py. This optimisation may take several minutes to complete, and is very sensitive to the Python, NumPy, and SciPy versions. Therefore, the latter output is postprocessed by local_s1.py, which should plot the optimised parameters in local_supfig1v2.pdf in agreement with the values reported in Supplemental Table 2, taking into consideration the reported significant figures.local_supfig1v2.pdf with supfig1v2.pdf gives an impression of how the parameters might differ during the optimization for slightly different package versions, while still arriving at the optimised results.Supp_Fig_2_data is initially empty. For the current analyses, STO_2_0010STO_2_.txt must be copied (also available in Data/Supp_Fig_2_data), while the latter folder now also contains C10239BM47fine_a2f.txt, the Eliashberg function from the publication described in the main text, for panel $\textbf{d}$.STO_2_0010STO_2_.txt must be copied (also available in Data/Supp_Fig_2_data), while the latter folder now also contains C10239BM47fine_a2f.txt, the Eliashberg function from the publication described in the main text, for panel $\textbf{d}$.tio2_2023_single_complete.py, since in top of the analyses of Figure_5/tio2_2023_single.py, it contains the analysis for the MEM-aided result shown in panel $\textbf{d}$.Figure_5 folder.STO_2_0010STO_2__inner_right_mem.txt used for panel $\textbf{d}$ here, is generated with mem_inner_right.py.Supp_Fig_3_data is initially empty. For the current analyses, once again the input file graphene_raw_cut_2.txt is necessary, while for panel $\textbf{c}$ the data from Usachov et al. (2018) are necessary, found in file graphene_kink_selfs_2.csv. Copy both of them inside the Figures_and_tables/Supp_Fig_3/Supp_Fig_3_data folder.graphene_edge.py.graphene_linearised.py.graphene_cut2_reproduce.py.graphene_linearised_uncorrected.py. These are based on new optimizations with left_linear_uncorrected.py and right_linear_uncorrected.py, writing to the respective Supp_Fig_3_data/graphene_raw_cut_2_uncl_left.csv and Supp_Fig_3_data/graphene_raw_cut_2_uncl_right.csv.graphene_linearised.py. The optimised parameters are based on Figure_6/left_linear_optimisation.py.graphene_linearised_confined.py.Supp_Fig_4_data needs to be replaced by the version from Data to run some postprocessing steps.Al_pbesol_ncsr_0.4.1.psp8 is described in the supplemental section of the manuscript.fcc_relax.abi.vacuum_8.abi. Files with $n$ layers of vacuum can be generated by running with Bash:create_vacuum.sh vacuum_n.abi n
work_function.py.layer_41.abi and path_m.abi. Files with $n$ where $n$ is odd can be generated by running from the terminal:create_layer.sh layer_n.abi n
bulk_bands.abi, while the bands were projected onto $k_z$ with 100_bands.abi.postproc_bands.py. The extrema determination of the 100 projected bands inside the Supp_Fig_4_data folder may take a minute or so to complete.analyse_aluminium.py. The optimized parameters under the header Right-hand side can be obtained by executing optimise_all.py and fix_mb.py. After optimisations that may take a few minutes, the optimised parameters are found at the bottom of Supp_Fig_4_data/raw201004071530_calib_right.txt and Supp_Fig_4_data/raw201004071530_calib_right_fixed.txt, respectively..abi file, there is a corresponding .abo file in Data/Supp_Fig_4_data that can be inspected for the anticipated calculations being performed, their output values, and runtime.mock_optimisation_right.py and retrieving the output parameters at the bottom of the newly created artificial_einstein_right.txt. The script may take several minutes to run.postproc_mock.py, which already contains the optimized parameters right after the brnc header.postproc_mock.py the parameters right after the branch name variable brnc, with the table listing rounded deviations for which the extraction will fail. For example, multiplying $m_{\text{R}}^{\text{b}}$ by 1.2 will result in failure, while the code should still complete if it is multiplied by 1.15.postproc_mock.py.mock_optimisation_right.py to execute the Bayesian loop. The loop may take seconds to minutes to either fail or complete, especially for large allowed $h_0$. The table lists rounded ranges for which the code terminates successfully.artificial_einstein_right.txt, and upon success, should result in a minus log-probability below -474, with -487 being the best possible result. In case of success, the absolute values are also printed by the bottom lines of code in mock_optimisation_right.py.Optimized right header in postproc_mock.py, followed by multiplying the parameters by the allowed deviations in the table. The absolute values are also printed by the bottom of the code.Supp_Fig_4. The bold KS $m_{\mathrm{R}}^{\mathrm{b}}$ value is printed with postproc_shortened.py, which fits the Kohn-Sham eigenvalues.analyse_aluminium.py. The 5 parameters optimised by the Bayesian loop for the xARPES case and KS case are generated by following up with optimise_all.py and fix_mb.py, respectively.