-
Notifications
You must be signed in to change notification settings - Fork 122
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Re #6151 Add lightweight API v2 reducer code
- Loading branch information
Showing
13 changed files
with
829 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
Reduction Workflow | ||
================== | ||
|
||
This is the new reduction scripting interface. It uses the new python API | ||
and is built on the DataProcessor algorithms and the property manager | ||
data service. |
Empty file.
102 changes: 102 additions & 0 deletions
102
Code/Mantid/scripts/reduction_workflow/command_interface.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
""" | ||
List of user commands. | ||
""" | ||
|
||
from reducer import Reducer | ||
|
||
class ReductionSingleton: | ||
""" Singleton reduction class """ | ||
|
||
## storage for the instance reference | ||
__instance = None | ||
|
||
def __init__(self): | ||
""" Create singleton instance """ | ||
# Check whether we already have an instance | ||
if ReductionSingleton.__instance is None: | ||
# Create and remember instance | ||
ReductionSingleton.__instance = Reducer() | ||
|
||
# Store instance reference as the only member in the handle | ||
self.__dict__['_ReductionSingleton__instance'] = ReductionSingleton.__instance | ||
|
||
@classmethod | ||
def clean(cls, reducer_cls=None): | ||
if reducer_cls==None: | ||
ReductionSingleton.__instance = Reducer() | ||
else: | ||
ReductionSingleton.__instance = reducer_cls() | ||
|
||
@classmethod | ||
def replace(cls, red): | ||
""" | ||
Set the object pointed to by the singleton with | ||
the one passed | ||
@param red: reducer object | ||
""" | ||
if issubclass(red.__class__, Reducer): | ||
ReductionSingleton.__instance = red | ||
else: | ||
raise RuntimeError, 'The object passed to ReductionSingleton.replace() must be of type Reducer' | ||
|
||
|
||
@classmethod | ||
def run(cls): | ||
""" | ||
Execute the reducer and then clean it (regardless of | ||
if it throws) to ensure that a partially run reducer is | ||
not left behind | ||
""" | ||
try: | ||
if ReductionSingleton.__instance is not None: | ||
return ReductionSingleton.__instance._reduce() | ||
finally: | ||
ReductionSingleton.clean(ReductionSingleton.__instance.__class__) | ||
|
||
def __getattr__(self, attr): | ||
""" Delegate access to implementation """ | ||
return getattr(self.__instance, attr) | ||
|
||
def __setattr__(self, attr, value): | ||
""" Delegate access to implementation """ | ||
return setattr(self.__instance, attr, value) | ||
|
||
## Utilities | ||
def get_property_manager(name): | ||
prop_mng = PropertyManagerDataService.retrieve(name) | ||
|
||
## List of user commands ###################################################### | ||
def Clear(reducer_cls=None): | ||
""" | ||
Clears the Reducer of changes applied by all previous commands | ||
""" | ||
ReductionSingleton.clean(reducer_cls) | ||
|
||
def DataPath(path): | ||
ReductionSingleton().set_data_path(path) | ||
|
||
def OutputPath(path): | ||
ReductionSingleton().set_output_path(path) | ||
|
||
def Reduce1D(): | ||
return ReductionSingleton().reduce() | ||
|
||
def Reduce(): | ||
return ReductionSingleton().reduce() | ||
|
||
def AppendDataFile(datafile, workspace=None): | ||
""" | ||
Append a data file in the list of files to be processed. | ||
@param datafile: data file to be processed | ||
@param workspace: optional workspace name for this data file | ||
[Default will be the name of the file] | ||
""" | ||
ReductionSingleton().append_data_file(datafile, workspace) | ||
|
||
def ClearDataFiles(): | ||
""" | ||
Empty the list of data files to be processed while keeping | ||
all other reduction options. | ||
""" | ||
ReductionSingleton().clear_data_files() | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
import os | ||
from mantid.kernel import ConfigService, Logger | ||
from mantid.api import FileFinder | ||
|
||
def find_file(filename=None, startswith=None, data_dir=None): | ||
""" | ||
Returns a list of file paths for the search criteria. | ||
@param filename: exact name of a file. The first file found will be returned. | ||
@param startswith: string that files should start with. | ||
@param data_dir: additional directory to search | ||
""" | ||
raise RuntimeError, "find_file is no longer in use" | ||
# Files found | ||
files_found = [] | ||
filename = str(filename).strip() | ||
|
||
# List of directory to look into | ||
# The preferred way to operate is to have a symbolic link in a work directory, | ||
# so look in the current working directory first | ||
search_dirs = [os.getcwd()] | ||
# The second best location would be with the data itself | ||
if data_dir is not None: | ||
search_dirs.append(data_dir) | ||
# The standard place would be the location of the configuration files on the SNS mount | ||
search_dirs.append("/SNS/EQSANS/shared/instrument_configuration/") | ||
search_dirs.extend(ConfigService.Instance().getDataSearchDirs()) | ||
|
||
# Look for specific file | ||
if filename is not None: | ||
for d in search_dirs: | ||
if not os.path.isdir(d): | ||
continue | ||
file_path = os.path.join(os.path.normcase(d), filename) | ||
if os.path.isfile(file_path): | ||
files_found.append(file_path) | ||
# If we are looking for a specific file, return right after we find the first | ||
if startswith is None: | ||
return files_found | ||
|
||
# Look for files that starts with a specific string | ||
if startswith is not None: | ||
for d in search_dirs: | ||
if not os.path.isdir(d): | ||
continue | ||
files = os.listdir(d) | ||
for file in files: | ||
if file.startswith(startswith): | ||
file_path = os.path.join(os.path.normcase(d), file) | ||
files_found.append(file_path) | ||
|
||
return files_found | ||
|
||
def find_data(file, instrument='', allow_multiple=False): | ||
""" | ||
Finds a file path for the specified data set, which can either be: | ||
- a run number | ||
- an absolute path | ||
- a file name | ||
@param file: file name or part of a file name | ||
@param instrument: if supplied, FindNeXus will be tried as a last resort | ||
""" | ||
# First, assume a file name | ||
file = str(file).strip() | ||
|
||
# If we allow multiple files, users may use ; as a separator, | ||
# which is incompatible with the FileFinder | ||
n_files = 1 | ||
if allow_multiple: | ||
file=file.replace(';',',') | ||
toks = file.split(',') | ||
n_files = len(toks) | ||
|
||
instrument = str(instrument) | ||
file_path = FileFinder.getFullPath(file) | ||
if os.path.isfile(file_path): | ||
return file_path | ||
|
||
# Second, assume a run number and pass the instrument name as a hint | ||
try: | ||
# FileFinder doesn't like dashes... | ||
instrument=instrument.replace('-','') | ||
f = FileFinder.findRuns(instrument+file) | ||
if os.path.isfile(f[0]): | ||
if allow_multiple: | ||
# Mantid returns its own list object type, so make a real list out if it | ||
if len(f)==n_files: | ||
return [i for i in f] | ||
else: return f[0] | ||
except: | ||
# FileFinder couldn't make sense of the the supplied information | ||
pass | ||
|
||
# Third, assume a run number, without instrument name to take care of list of full paths | ||
try: | ||
f = FileFinder.findRuns(file) | ||
if os.path.isfile(f[0]): | ||
if allow_multiple: | ||
# Mantid returns its own list object type, so make a real list out if it | ||
if len(f)==n_files: | ||
return [i for i in f] | ||
else: return f[0] | ||
except: | ||
# FileFinder couldn't make sense of the the supplied information | ||
pass | ||
|
||
# If we didn't find anything, raise an exception | ||
Logger.get('find_data').error("\n\nCould not find a file for %s: check your reduction parameters\n\n" % str(file)) | ||
raise RuntimeError, "Could not find a file for %s" % str(file) |
Empty file.
Empty file.
Oops, something went wrong.