Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 21 additions & 6 deletions src/mvesuvio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,20 +39,35 @@ def set_ipfolder(self):


class RunArgInputs(ArgInputs):
def __init__(self, yes):
def __init__(self, back_workspace, front_workspace, minimal_output, outputs_dir):
super().__init__("run")
self.__yes = yes
self.__back_workspace = back_workspace
self.__front_workspace = front_workspace
self.__minimal_output = minimal_output
self.__outputs_dir = outputs_dir

@property
def yes(self):
return self.__yes
def back_workspace(self):
return self.__back_workspace

@property
def front_workspace(self):
return self.__front_workspace

@property
def minimal_output(self):
return self.__minimal_output

@property
def outputs_dir(self):
return self.__outputs_dir


def set_config(inputs_file="", ip_folder=""):
config_args = ConfigArgInputs(inputs_file, ip_folder)
main(config_args)


def run(yes_to_all=False):
run_args = RunArgInputs(yes_to_all)
def run(back_workspace="", front_workspace="", minimal_output=False, outputs_dir=""):
run_args = RunArgInputs(back_workspace, front_workspace, minimal_output, outputs_dir)
main(run_args)
41 changes: 29 additions & 12 deletions src/mvesuvio/analysis_fitting.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,27 @@

repoPath = Path(__file__).absolute().parent # Path to the repository

PLOTS_PROJECTION = "mantid"


class FitInYSpace:
def __init__(self, fi, ws_to_fit, ws_to_fit_ncp, ws_res):
self.fitting_inputs = fi
def __init__(self, fi, ws_to_fit, ws_to_fit_ncp, ws_res, outputs_dir):
self.ws_to_fit = ws_to_fit
self.ws_to_fit_ncp = ws_to_fit_ncp
self.ws_resolution = ws_res

fi.figSavePath = fi.save_path / "figures"
fi.outputs_dir = outputs_dir
fi.figSavePath = fi.outputs_dir / "figures"
fi.figSavePath.mkdir(exist_ok=True, parents=True)

# TODO: Look into fixing this
# If errors are zero, don't run minos or global fit
if np.max(ws_to_fit.extractE()) == 0:
fi.run_minos = False
fi.do_global_fit = False

self.fitting_inputs = fi

def run(self):
wsResSum = SumSpectra(InputWorkspace=self.ws_resolution, OutputWorkspace=self.ws_resolution.name() + "_Sum")
normalise_workspace(wsResSum)
Expand Down Expand Up @@ -772,7 +782,7 @@ def saveMinuitPlot(yFitIC, wsMinuitFit, mObj):
for p, v, e in zip(mObj.parameters, mObj.values, mObj.errors):
leg += f"${p}={v:.2f} \\pm {e:.2f}$\n"

fig, ax = plt.subplots(subplot_kw={"projection": "mantid"})
fig, ax = plt.subplots(subplot_kw={"projection": PLOTS_PROJECTION})
ax.errorbar(wsMinuitFit, "k.", wkspIndex=0, label="Weighted Avg")
ax.errorbar(wsMinuitFit, "r-", wkspIndex=1, label=leg)
ax.plot(wsMinuitFit, "b.", wkspIndex=2, label="Residuals")
Expand Down Expand Up @@ -845,6 +855,9 @@ def runMinos(mObj, yFitIC, constrFunc, wsName):

if yFitIC.show_plots:
fig.show()
else:
plt.close(fig)
del fig

return parameters, values, errors, minosAutoErr, minosManErr

Expand All @@ -868,8 +881,8 @@ def runAndPlotManualMinos(minuitObj, constrFunc, bestFitVals, bestFitErrs, showP
width,
tight_layout=True,
figsize=figsize,
subplot_kw={"projection": "mantid"},
) # subplot_kw={'projection':'mantid'}
subplot_kw={"projection": PLOTS_PROJECTION},
)
fig.canvas.manager.set_window_title(wsName + "_minos")

merrors = {}
Expand Down Expand Up @@ -996,7 +1009,7 @@ def plotAutoMinos(minuitObj, wsName, yFitIC):
width,
tight_layout=True,
figsize=figsize,
subplot_kw={"projection": "mantid"},
subplot_kw={"projection": PLOTS_PROJECTION},
)
fig.canvas.manager.set_window_title(wsName + "_autominos")

Expand All @@ -1020,7 +1033,11 @@ def plotAutoMinos(minuitObj, wsName, yFitIC):
fig.legend(handle, label, loc="lower right")
savePath = yFitIC.figSavePath / fig.canvas.manager.get_window_title()
plt.savefig(savePath, bbox_inches="tight")
fig.show()
if yFitIC.show_plots:
fig.show()
else:
plt.close(fig)
del fig, axs


def plotProfile(ax, var, varSpace, fValsMigrad, lerr, uerr, fValsMin, varVal, varErr):
Expand Down Expand Up @@ -1318,7 +1335,7 @@ def groupDetectors(ipData, yFitIC):
idxList = formIdxList(clusters)

if yFitIC.show_plots:
fig, ax = plt.subplots(tight_layout=True, subplot_kw={"projection": "mantid"})
fig, ax = plt.subplots(tight_layout=True, subplot_kw={"projection": PLOTS_PROJECTION})
fig.canvas.manager.set_window_title("Grouping of detectors")
plotFinalGroups(ax, ipData, idxList)
fig.show()
Expand Down Expand Up @@ -1424,7 +1441,7 @@ def formIdxList(clusters):

def plotDetsAndInitialCenters(L1, theta, centers):
"""Used in debugging."""
fig, ax = plt.subplots(tight_layout=True, subplot_kw={"projection": "mantid"})
fig, ax = plt.subplots(tight_layout=True, subplot_kw={"projection": PLOTS_PROJECTION})
fig.canvas.manager.set_window_title("Starting centroids for groupings")
ax.scatter(L1, theta, alpha=0.3, color="r", label="Detectors")
ax.scatter(centers[:, 0], centers[:, 1], color="k", label="Starting centroids")
Expand Down Expand Up @@ -1613,7 +1630,7 @@ def plotGlobalFit(dataX, dataY, dataE, mObj, totCost, wsName, yFitIC):
int(np.ceil(len(dataY) / rows)),
figsize=(15, 8),
tight_layout=True,
subplot_kw={"projection": "mantid"},
subplot_kw={"projection": PLOTS_PROJECTION},
)
fig.canvas.manager.set_window_title(wsName + "_fitglobal")

Expand Down Expand Up @@ -1647,7 +1664,7 @@ def plotGlobalFit(dataX, dataY, dataE, mObj, totCost, wsName, yFitIC):

def save_workspaces(yFitIC):
for ws_name in mtd.getObjectNames():
save_path = yFitIC.save_path / f"{yFitIC.fitting_model}_fit" / ws_name
save_path = yFitIC.outputs_dir / f"{yFitIC.fitting_model}_fit" / ws_name
if ws_name.endswith("Parameters") or ws_name.endswith("CovarianceMatrix"):
save_path.parent.mkdir(exist_ok=True, parents=True)
SaveAscii(ws_name, str(save_path))
Expand Down
23 changes: 19 additions & 4 deletions src/mvesuvio/analysis_reduction.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
CreateWorkspace,
GroupWorkspaces,
SaveAscii,
SaveNexus,
AppendSpectra,
)

Expand Down Expand Up @@ -118,6 +119,7 @@ def PyInit(self):
self.declareProperty(name="MultipleScatteringOrder", defaultValue=-1, validator=IntBoundedValidator(lower=0))
self.declareProperty(name="NumberOfEvents", defaultValue=-1, validator=IntBoundedValidator(lower=0))
self.declareProperty(name="ResultsPath", defaultValue="", doc="Directory to store results, to be deleted later.")
self.declareProperty(name="MinimalOutputFiles", defaultValue=False, doc="Flag to set number of output files to minimum.")
# Outputs
self.declareProperty(
TableWorkspaceProperty(name="OutputMeansTable", defaultValue="", direction=Direction.Output),
Expand Down Expand Up @@ -153,6 +155,7 @@ def _setup(self):
self._h_ratio = self.getProperty("HRatioToChosenMass").value
self._constraints = dill.loads(eval(self.getProperty("Constraints").value))
self._profiles_table = self.getProperty("InputProfiles").value
self._minimal_output = self.getProperty("MinimalOutputFiles").value

self._instrument_params = load_instrument_params(self._ip_file, self.getProperty("InputWorkspace").value.getSpectrumNumbers())
self._resolution_params = load_resolution(self._instrument_params)
Expand Down Expand Up @@ -342,7 +345,7 @@ def _set_y_space_arrays(self):
return

def _save_plots(self):
if not self._save_figures_path.exists():
if self._minimal_output or not self._save_figures_path.exists():
return

lw = 2
Expand Down Expand Up @@ -726,6 +729,18 @@ def create_gamma_workspaces(self):
return mtd[ws_corrections_name + "_gamma_backgr"]

def _save_results(self):
for ws_name in mtd.getObjectNames():
if ws_name.endswith(("ncp", "fse", "fit_results", "means", "initial_parameters") + tuple([str(i) for i in range(10)])):
SaveAscii(ws_name, str(self._save_results_path / ws_name))
all_workspaces = mtd.getObjectNames()
if self._minimal_output:
last_iteration = max([ws.replace("_total_ncp", "")[-1] for ws in all_workspaces if ws.endswith("_total_ncp")])
for ws_name in all_workspaces:
if ws_name.endswith((f"{last_iteration}_total_ncp", f"{last_iteration}_total_fse")):
SaveAscii(ws_name, str(self._save_results_path.absolute() / ws_name) + ".txt")
if ws_name.endswith((f"{last_iteration}_fit_results", f"{last_iteration}_means")):
SaveAscii(ws_name, str(self._save_results_path.absolute() / ws_name) + ".txt")
return

for ws_name in all_workspaces:
if ws_name.endswith(("ncp", "fse", "initial_parameters", "means", "fit_results")):
SaveAscii(ws_name, str(self._save_results_path.absolute() / ws_name) + ".txt")
if ws_name.endswith(tuple([str(i) for i in range(10)])):
SaveNexus(ws_name, str(self._save_results_path.absolute() / ws_name) + ".nxs")
2 changes: 2 additions & 0 deletions src/mvesuvio/globals.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
BACKWARD_TAG = "bckwd"
FORWARD_TAG = "fwd"
74 changes: 60 additions & 14 deletions src/mvesuvio/main/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import argparse
from os import path
from pathlib import Path
from mvesuvio.util import handle_config


Expand All @@ -13,7 +14,12 @@ def main(manual_args=None):
if args.command == "run":
if not handle_config.config_set():
__setup_config(None)
__run_analysis()
__run_analysis(args)

if args.command == "bootstrap":
if not handle_config.config_set():
__setup_config(None)
__run_bootstrap(args)


def __setup_and_parse_args():
Expand All @@ -35,27 +41,51 @@ def __set_up_parser():
type=str,
)

subparsers.add_parser("run", help="run mvesuvio analysis")
run_parser = subparsers.add_parser("run", help="run mvesuvio analysis")
run_parser.add_argument(
"--back-workspace",
"-b",
help="input workspace for vesuvio backward analysis, bypasses loading (and subtracting) raw and empty.",
default="",
type=str,
)
run_parser.add_argument(
"--front-workspace",
"-f",
help="input workspace for vesuvio forward analysis, bypasses loading (and subtracting) raw and empty.",
default="",
type=str,
)
run_parser.add_argument("--minimal-output", action="store_true", help="Flag to set output files to minimum.")
run_parser.add_argument("--outputs-dir", "-o", help="Directory for populating with output files.")
boot_parser = subparsers.add_parser("bootstrap", help="Run bootstrap of vesuvio analysis (without y-space fitting)")
boot_parser.add_argument(
"--inputs-dir",
"-d",
help="Directory containing input bootstrap replicas. Replicas should be inside sparate backaward and forward subdirectories.",
default="",
type=str,
)
return parser


def __setup_config(args):
__set_logging_properties()
handle_config.setup_config_dir()
handle_config.setup_default_inputs()
handle_config.setup_default_ipfile_dir()

config_dir = handle_config.VESUVIO_CONFIG_PATH
handle_config.setup_config_dir(config_dir)
ipfolder_dir = handle_config.VESUVIO_IPFOLDER_PATH
inputs = handle_config.VESUVIO_INPUTS_PATH
ipfolder_dir = handle_config.VESUVIO_IPFOLDER_PATH

if handle_config.config_set():
inputs = handle_config.read_config_var("caching.inputs") if not args or not args.set_inputs else args.set_inputs
ipfolder_dir = handle_config.read_config_var("caching.ipfolder") if not args or not args.set_ipfolder else args.set_ipfolder
else:
inputs = inputs if not args or not args.set_inputs else args.set_inputs
ipfolder_dir = ipfolder_dir if not args or not args.set_ipfolder else args.set_ipfolder
inputs = handle_config.read_config_var("caching.inputs")
ipfolder_dir = handle_config.read_config_var("caching.ipfolder")

handle_config.setup_default_ipfile_dir()
handle_config.setup_default_inputs()
if args and args.set_inputs:
inputs = str(Path(args.set_inputs).absolute())
if args and args.set_ipfolder:
ipfolder_dir = str(Path(args.set_ipfolder).absolute())

handle_config.set_config_vars(
{
Expand Down Expand Up @@ -84,10 +114,26 @@ def __set_logging_properties():
return


def __run_analysis():
def __run_analysis(args):
from mvesuvio.main.run_routine import Runner

if not args:
Runner().run()
return
Runner(
override_back_workspace=args.back_workspace,
override_front_workspace=args.front_workspace,
minimal_output=args.minimal_output,
output_directory=args.outputs_dir,
).run()


def __run_bootstrap(args):
from mvesuvio.main.run_routine import Runner

Runner().run()
if not args:
return
Runner(bootstrap_inputs_directory=args.inputs_dir, minimal_output=True).run_bootstrap()


if __name__ == "__main__":
Expand Down
Loading
Loading