From eccffe039ecd97fd304b952d3c565dbd91286e7f Mon Sep 17 00:00:00 2001 From: GuiMacielPereira Date: Tue, 7 Jan 2025 14:39:26 +0000 Subject: [PATCH] Replace old notices with print tables Previous notices were not very clear and made the code more confusing, replaced them with printing tables that are already bring created anyway. Log output is much easier to follow this way --- src/mvesuvio/analysis_fitting.py | 64 +++++++-------------------- src/mvesuvio/analysis_reduction.py | 5 +-- src/mvesuvio/util/analysis_helpers.py | 14 ++++-- 3 files changed, 29 insertions(+), 54 deletions(-) diff --git a/src/mvesuvio/analysis_fitting.py b/src/mvesuvio/analysis_fitting.py index 5c91c13..ca2cf61 100644 --- a/src/mvesuvio/analysis_fitting.py +++ b/src/mvesuvio/analysis_fitting.py @@ -10,8 +10,10 @@ import time import re from mantid.kernel import logger +from mantid.simpleapi import AnalysisDataService from mvesuvio.util import handle_config +from mvesuvio.util.analysis_helpers import print_table_workspace, passDataIntoWS repoPath = Path(__file__).absolute().parent # Path to the repository @@ -40,7 +42,7 @@ def fitInYSpaceProcedure(yFitIC, IC, wsTOF): fitProfileMinuit(yFitIC, wsJoYAvg, wsResSum) fitProfileMantidFit(yFitIC, wsJoYAvg, wsResSum) - printYSpaceFitResults(wsJoYAvg.name()) + printYSpaceFitResults() yfitResults = ResultsYFitObject(IC, yFitIC, wsTOF.name(), wsJoYAvg.name()) yfitResults.save() @@ -105,7 +107,10 @@ def subtract_profiles_except_lightest(ic, ws): if len(ic.masses) == 1: return - ws_name_lightest_mass = ic.name + '_' + str(ic.number_of_iterations_for_corrections) + '_' + str(min(ic.masses)) + '_ncp' + # TODO: Make the fetching of these workspaces more robust, prone to error + profiles_table = mtd[ic.name + '_initial_parameters'] + lightest_mass_str = profiles_table.column('label')[np.argmin(profiles_table.column('mass'))] + ws_name_lightest_mass = ic.name + '_' + str(ic.number_of_iterations_for_corrections) + '_' + lightest_mass_str + '_ncp' ws_name_profiles = ic.name + '_' + str(ic.number_of_iterations_for_corrections) + '_total_ncp' wsNcpExceptFirst = Minus(mtd[ws_name_profiles], mtd[ws_name_lightest_mass], @@ -128,7 +133,9 @@ def switchFirstTwoAxis(A): def ySpaceReduction(wsTOF, mass0, yFitIC, ic): """Seperate procedures depending on masking specified.""" - ws_name_lightest_mass = ic.name + '_' + str(ic.number_of_iterations_for_corrections) + '_' + str(min(ic.masses)) + '_ncp' + profiles_table = mtd[ic.name + '_initial_parameters'] + lightest_mass_str = profiles_table.column('label')[np.argmin(profiles_table.column('mass'))] + ws_name_lightest_mass = ic.name + '_' + str(ic.number_of_iterations_for_corrections) + '_' + lightest_mass_str + '_ncp' ncp = mtd[ws_name_lightest_mass].extractY() rebinPars = yFitIC.range_for_rebinning_in_y_space @@ -415,15 +422,6 @@ def extractWS(ws): return ws.extractX(), ws.extractY(), ws.extractE() -def passDataIntoWS(dataX, dataY, dataE, ws): - "Modifies ws data to input data" - for i in range(ws.getNumberHistograms()): - ws.dataX(i)[:] = dataX[i, :] - ws.dataY(i)[:] = dataY[i, :] - ws.dataE(i)[:] = dataE[i, :] - return ws - - def symmetrizeWs(avgYSpace): """ Symmetrizes workspace after weighted average. @@ -904,6 +902,8 @@ def createCorrelationTableWorkspace(wsYSpaceSym, parameters, corrMatrix): tableWS.addColumn(type="float", name=p) for p, arr in zip(parameters, corrMatrix): tableWS.addRow([p] + list(arr)) + print_table_workspace(tableWS) + def runMinos(mObj, yFitIC, constrFunc, wsName): @@ -1283,39 +1283,10 @@ def fitProfileMantidFit(yFitIC, wsYSpaceSym, wsRes): return -def printYSpaceFitResults(wsJoYName): - logger.notice("\nFit in Y Space results:") - foundWS = [] - try: - wsFitLM = mtd[wsJoYName + "_lm_Parameters"] - foundWS.append(wsFitLM) - except KeyError: - pass - try: - wsFitSimplex = mtd[wsJoYName + "_simplex_Parameters"] - foundWS.append(wsFitSimplex) - except KeyError: - pass - try: - wsFitMinuit = mtd[wsJoYName + "_minuit_Parameters"] - foundWS.append(wsFitMinuit) - except KeyError: - pass - - for tableWS in foundWS: - logger.notice("\n" + " ".join(tableWS.getName().split("_")[-3:]) + ":") - for key in tableWS.keys(): - if key == "Name": - logger.notice( - f"{key:>20s}: " - + " ".join([f"{elem:7.8s}" for elem in tableWS.column(key)]) - ) - else: - logger.notice( - f"{key:>20s}: " - + " ".join([f"{elem:7.4f}" for elem in tableWS.column(key)]) - ) - logger.notice("\n") +def printYSpaceFitResults(): + for ws_name in mtd.getObjectNames(): + if ws_name.endswith('Parameters'): + print_table_workspace(mtd[ws_name]) class ResultsYFitObject: @@ -1858,12 +1829,11 @@ def create_table_for_global_fit_parameters(wsName, m, chi2): logger.notice(f"Value of Chi2/ndof: {chi2:.2f}") logger.notice(f"Migrad Minimum valid: {m.valid}") - logger.notice("\nResults of Global Fit:\n") for p, v, e in zip(m.parameters, m.values, m.errors): - logger.notice(f"{p:>7s} = {v:>8.4f} \u00B1 {e:<8.4f}") t.addRow([p, v, e]) t.addRow(["Cost function", chi2, 0]) + print_table_workspace(t) def plotGlobalFit(dataX, dataY, dataE, mObj, totCost, wsName, yFitIC): diff --git a/src/mvesuvio/analysis_reduction.py b/src/mvesuvio/analysis_reduction.py index b00c762..04c52b0 100644 --- a/src/mvesuvio/analysis_reduction.py +++ b/src/mvesuvio/analysis_reduction.py @@ -324,7 +324,6 @@ def _fit_neutron_compton_profiles(self): self._row_being_fit = 0 while self._row_being_fit != len(self._dataY): self._fit_neutron_compton_profiles_to_row() - self.log().notice('') self._row_being_fit += 1 assert np.any(self._fit_parameters), "Fitting parameters cannot be zero for all spectra!" @@ -466,7 +465,6 @@ def _create_means_table(self): table.addColumn(type="float", name="mean_intensity") table.addColumn(type="float", name="std_intensity") - self.log().notice("\nmass mean widths mean intensities\n") for label, mass, mean_width, std_width, mean_intensity, std_intensity in zip( self._profiles_table.column("label"), self._masses, @@ -477,10 +475,9 @@ def _create_means_table(self): ): # Explicit conversion to float required to match profiles table table.addRow([label, float(mass), float(mean_width), float(std_width), float(mean_intensity), float(std_intensity)]) - self.log().notice(f"{label:6s} {mean_width:10.5f} \u00B1 {std_width:7.5f}" + \ - f"{mean_intensity:10.5f} \u00B1 {std_intensity:7.5f}\n") self.setPropertyValue("OutputMeansTable", table.name()) + print_table_workspace(table, precision=5) return table diff --git a/src/mvesuvio/util/analysis_helpers.py b/src/mvesuvio/util/analysis_helpers.py index b73c6a1..fc0bfaa 100644 --- a/src/mvesuvio/util/analysis_helpers.py +++ b/src/mvesuvio/util/analysis_helpers.py @@ -6,18 +6,26 @@ import numpy as np import numbers -from mvesuvio.analysis_fitting import passDataIntoWS from mvesuvio.util import handle_config import ntpath -def print_table_workspace(table): +def passDataIntoWS(dataX, dataY, dataE, ws): + "Modifies ws data to input data" + for i in range(ws.getNumberHistograms()): + ws.dataX(i)[:] = dataX[i, :] + ws.dataY(i)[:] = dataY[i, :] + ws.dataE(i)[:] = dataE[i, :] + return ws + + +def print_table_workspace(table, precision=3): table_dict = table.toDict() # Convert floats into strings for key, values in table_dict.items(): new_column = [int(item) if (not isinstance(item, str) and item.is_integer()) else item for item in values] - table_dict[key] = [f"{item:.3f}" if isinstance(item, float) else str(item) for item in new_column] + table_dict[key] = [f"{item:.{precision}f}" if isinstance(item, float) else str(item) for item in new_column] max_spacing = [max([len(item) for item in values] + [len(key)]) for key, values in table_dict.items()] header = "|" + "|".join(f"{item}{' '*(spacing-len(item))}" for item, spacing in zip(table.keys(), max_spacing)) + "|"